MINI MINI MANI MO

Path : /opt/oracle/product/18c/dbhomeXE/rdbms/admin/
File Upload :
Current File : //opt/oracle/product/18c/dbhomeXE/rdbms/admin/recover.bsq

# Copyright (c) 1996, 2018, Oracle and/or its affiliates. All rights reserved.
#
## ****************************************************************************
## * RECOVER.BSQ is now a DERIVED OBJECT.  If you are editing                 *
## * .../rdbms/admin/recover.bsq, STOP and edit                               *
## * .../rdbms/src/client/tools/rcvman/recover.txt instead.  recover.bsq is   *
## * derived from recover.txt, and any changes made directly to recover.bsq   *
## * will be lost.                                                            *
## ****************************************************************************
#
# If you don't want comments to be removed i.e, lines starting with # or --
# enclose them within <hash>STOP_SED and <hash>START_SED (where <hash> is #) 
# as is done for this line in recover.txt. Also make sure they are not on the 
# same line. To keep memory scripts as such use this facility.
 
 
library '18.04.00.00'
raschemaversion 0
 
define 'x$rman_constant'
<<<
package rman_constant is
   &const&
end;
>>>
 
define 'x$debl'
<<<
procedure debl(func varchar2, str varchar2, dtype number , level number) is
   chid          varchar2(2000) := krmicd.getChid;
begin
   if (chid is null) then
      krmicd.writeTrc(func, rman_constant.TRACE_MSG, str, dtype, level);
   else
      krmicd.writeTrc(func, rman_constant.TRACE_MSG,
                      'channel '||chid||': '||str, dtype, level);
   end if;
end;
>>>
 
define 'x$deb'
<<<
procedure deb(func  varchar2,
              str   varchar2,
              dtype number    DEFAULT rman_constant.DEBUG_PLSQL,
              level number    DEFAULT rman_constant.LEVEL_DEFAULT) is
begin
   debl(func, str, dtype, level);
end;
>>>
 
define 'x$beginBackupJobStep'
<<<
function beginBackupJobStep return boolean is
  dur_usr_endtime   binary_integer;
  dur_softendtime   binary_integer;
  dur_est_secs      binary_integer;
  partial           boolean;
  backup_cancelled  exception;
  pragma exception_init(backup_cancelled, -19591);
begin
--
  if (NOT krmicd.beginJobStep(dur_usr_endtime, dur_softendtime,
                              dur_est_secs, partial)) then
    if (NOT partial) then
      raise backup_cancelled;
    end if;
    return FALSE;
  end if;
  
  sys.dbms_backup_restore.setLimit(sys.dbms_backup_restore.dur_endtime,
                                   dur_usr_endtime);
  sys.dbms_backup_restore.setLimit(sys.dbms_backup_restore.dur_est_secs,
                                   dur_est_secs);
  sys.dbms_backup_restore.setLimit(sys.dbms_backup_restore.dur_softendtime,
                                   dur_softendtime);
 
  return TRUE;
end;
>>>
 
define 'x$endBackupJobStep'
<<<
function endBackupJobStep (failed IN boolean, errcode IN binary_integer)  
   return boolean is
   ignore_errs boolean;
   sleep_secs   number;
begin
     ignore_errs := krmicd.endJobStep(failed, errcode);
 
     sys.dbms_backup_restore.getlimit
       (sys.dbms_backup_restore.sleep_secs, sleep_secs);
 
--
--
     if (sleep_secs > 0) then
        krmicd.writeMsg(8599, krmicd.getChid,
                        to_char(floor(sleep_secs/3600)) || ':' ||
                        to_char(floor(mod(sleep_secs, 3600)/60),
                                'FM09') || ':' ||
                        to_char(mod(sleep_secs,60), 'FM09'));
     end if;
 
--
     if (failed and ignore_errs) then
        krmicd.clearErrors;
        return TRUE;
     end if;
 
--
     if (not failed) then
        return TRUE;
     end if;
 
     return FALSE;
end;
>>>
 
define 'x$setBackupParams'
<<<
procedure setBackupParams(docopy in boolean) is
  p1 number;
  p2 number;
  p3 number;
  p4 number;
  t1 varchar2(1025);
  t2 varchar2(1);
  t3 varchar2(1);
 
begin
  if (not docopy and krmicd.getParams(1, p1, p2, p3, p4, t1, t2, t3)) then
     sys.dbms_backup_restore.setparms(p0=>1, p1=>1, p2=>p1, p3=>p2, p5=>t1);
  end if;
  return;
end;
>>>
 
define 'x$setRestoreParams'
<<<
procedure setRestoreParams is
  p1 number;
  p2 number;
  p3 number;
  p4 number;
  t1 varchar2(1025);
  t2 varchar2(1);
  t3 varchar2(1);
begin
  if (krmicd.getParams(2, p1, p2, p3, p4, t1, t2, t3)) then
     sys.dbms_backup_restore.setparms(p0=>2, p5=>t1);
     loop 
       exit when not krmicd.getParams(3, p1, p2, p3, p4, t1, t2, t3);
       sys.dbms_backup_restore.setparms(p0=>2, p5=>t1);
     end loop;
  end if;
 
  return;
end;
>>>
 
define 'x$setNetworkRestoreParams'
<<<
function setNetworkRestoreParams return boolean is 
  p1 number;
  p2 number;
  p3 number;
  p4 number; 
  t1 varchar2(1025);
  t2 varchar2(1);
  t3 varchar2(1);
  docompress boolean := FALSE;
begin
  setRestoreParams;
 
--
  if (krmicd.getParams(1, p1, p2, p3, p4, t1, t2, t3)) then
     sys.dbms_backup_restore.setParms(
              p0  => 10,
              p1  => 1,   -- encrypt
              p2  => p1,  -- algorithm
              p3  => p2,  -- transparent
              p5  => t1); -- password
--
     sys.dbms_backup_restore.setparms(p0=>2, p5=>t1);
  end if;
 
--
  if (krmicd.getParams(4, p1, p2, p3, p4, t1, t2, t3)) then
     if (p2 = 1) then
        p2 := sys.dbms_backup_restore.lopt_false;
     elsif (p2 = 2) then
        p2 := sys.dbms_backup_restore.lopt_true;
     end if;
 
     sys.dbms_backup_restore.setParms(
              p0   => 11,
              p1   => 1,   -- compress
              p2   => p1,  -- asofrel
              p3   => p2,  -- loadopt
              p5   => t1); -- schema
     docompress := TRUE;
  end if;
 
  return docompress;
end;
>>>
 
define 'v$controlfile_record_section'
<<<
define table v$controlfile_record_section
(
TYPE                                    VARCHAR2(128),
RECORD_SIZE                             NUMBER,
RECORDS_TOTAL                           NUMBER,
RECORDS_USED                            NUMBER,
FIRST_INDEX                             NUMBER,
LAST_INDEX                              NUMBER,
LAST_RECID                              NUMBER
);
>>>
 
define 'v$controlfile'
<<<
define table v$controlfile
(
STATUS                                  VARCHAR2(7),
NAME                                    VARCHAR2(513),
IS_RECOVERY_DEST_FILE                   VARCHAR2(3),
BLOCK_SIZE                              NUMBER,
FILE_SIZE_BLKS                          NUMBER
);
>>>
 
define 'v$database'
<<<
define table v$database
(
DBID                                    NUMBER,
NAME                                    VARCHAR2(9),
CREATED                                 DATE,
RESETLOGS_CHANGE#                       NUMBER,
RESETLOGS_TIME                          DATE,
PRIOR_RESETLOGS_CHANGE#                 NUMBER,
PRIOR_RESETLOGS_TIME                    DATE,
LOG_MODE                                VARCHAR2(12),
CHECKPOINT_CHANGE#                      NUMBER,
ARCHIVE_CHANGE#                         NUMBER,
CONTROLFILE_TYPE                        VARCHAR2(7),
CONTROLFILE_CREATED                     DATE,
CONTROLFILE_SEQUENCE#                   NUMBER,
CONTROLFILE_CHANGE#                     NUMBER,
CONTROLFILE_TIME                        DATE,
OPEN_RESETLOGS                          VARCHAR2(11),
VERSION_TIME                            DATE,
RECOVERY_TARGET_INCARNATION#            NUMBER,
LAST_OPEN_INCARNATION#                  NUMBER,
FLASHBACK_ON                            VARCHAR2(3),
DB_UNIQUE_NAME                          VARCHAR2(30),
DATABASE_ROLE                           VARCHAR2(16),
CONTROLFILE_CONVERTED                   VARCHAR2(3),
PRIMARY_DB_UNIQUE_NAME                  VARCHAR2(30),
CDB                                     VARCHAR2(3)
);
>>>
 
define 'v$tablespace'
<<<
define table v$tablespace
(
TS#                                     NUMBER,
CON_ID                                  NUMBER,
NAME                                    VARCHAR2(30),
INCLUDED_IN_DATABASE_BACKUP             VARCHAR2(3),
BIGFILE                                 VARCHAR2(3),
ENCRYPT_IN_BACKUP                       VARCHAR2(3)
);
>>>
 
define 'v$datafile'
<<<
define table v$datafile
(
BLABLA                                   NUMBER
);
>>>
 
define 'v$tempfile'
<<<
define table v$tempfile
(
 CON_ID                                 NUMBER,
 FILE#                                  NUMBER,
 CREATION_CHANGE#                       NUMBER,
 NAME                                   VARCHAR2(513)
);
>>>
 
define 'x$kccrt'
<<<
define table x$kccrt
(
INST_ID                                 NUMBER,
CON_ID                                  NUMBER,
RTNUM                                   NUMBER,
RTSTA                                   NUMBER,
RTNLF                                   NUMBER,
RTSEQ                                   NUMBER,
RTENB                                   VARCHAR2(20),
RTETS                                   VARCHAR2(20),
RTDIS                                   VARCHAR2(20),
RTDIT                                   VARCHAR2(20)
);
>>>
 
define 'x$kcctir'
<<<
define table x$kcctir
(
INST_ID                                 NUMBER,
CON_ID                                  NUMBER,
TIRNUM                                  NUMBER
);
>>>
 
define 'v$log'
<<<
define table v$log
(
CON_ID                                  NUMBER,
GROUP#                                  NUMBER,
THREAD#                                 NUMBER,
SEQUENCE#                               NUMBER,
BYTES                                   NUMBER,
MEMBERS                                 NUMBER,
ARCHIVED                                VARCHAR2(3),
STATUS                                  VARCHAR2(16),
FIRST_CHANGE#                           NUMBER,
FIRST_TIME                              DATE
);
>>>
 
define 'v$standby_log'
<<<
define table v$standby_log
(
CON_ID                                  NUMBER,
GROUP#                                  NUMBER,
THREAD#                                 NUMBER,
SEQUENCE#                               NUMBER,
BYTES                                   NUMBER,
MEMBERS                                 NUMBER,
ARCHIVED                                VARCHAR2(3),
STATUS                                  VARCHAR2(16),
FIRST_CHANGE#                           NUMBER,
FIRST_TIME                              DATE
);
>>>
 
define 'v$logfile'
<<<
define table v$logfile
(
CON_ID                                  NUMBER,
GROUP#                                  NUMBER,
STATUS                                  VARCHAR2(7),
MEMBER                                  VARCHAR2(513),
STATUS                                  VARCHAR2(7)
);
>>>
 
define 'v$rman_configuration'
<<<
DEFINE TABLE v$rman_configuration
(
CON_ID              NUMBER,
CONF#               NUMBER,
NAME                VARCHAR2(65),
VALUE               VARCHAR2(1025)
);
>>>
 
define 'v$log_history'
<<<
define table v$log_history
(
CON_ID                                  NUMBER,
RECID                                   NUMBER,
STAMP                                   NUMBER,
THREAD#                                 NUMBER,
SEQUENCE#                               NUMBER,
FIRST_CHANGE#                           NUMBER,
FIRST_TIME                              DATE,
NEXT_CHANGE#                            NUMBER,
RESETLOGS_CHANGE#                       NUMBER,
RESETLOGS_TIME                          DATE
);
>>>
 
define 'v$archived_log'
<<<
define table v$archived_log
(
CON_ID                                  NUMBER,
RECID                                   NUMBER,
STAMP                                   NUMBER,
NAME                                    VARCHAR2(513),
DEST_ID                                 NUMBER,
THREAD#                                 NUMBER,
SEQUENCE#                               NUMBER,
RESETLOGS_CHANGE#                       NUMBER,
RESETLOGS_TIME                          DATE,
FIRST_CHANGE#                           NUMBER,
FIRST_TIME                              DATE,
NEXT_CHANGE#                            NUMBER,
NEXT_TIME                               DATE,
BLOCKS                                  NUMBER,
BLOCK_SIZE                              NUMBER,
CREATOR                                 VARCHAR2(7),
REGISTRAR                               VARCHAR2(7),
STANDBY_DEST                            VARCHAR2(3),
ARCHIVED                                VARCHAR2(3),
APPLIED                                 VARCHAR2(3),
DELETED                                 VARCHAR2(3),
STATUS                                  VARCHAR2(1),
COMPLETION_TIME                         DATE,
DICTIONARY_BEGIN                        VARCHAR2(3),
DICTIONARY_END                          VARCHAR2(3),
IS_RECOVERY_DEST_FILE                   VARCHAR2(3),
COMPRESSED                              VARCHAR2(3),
END_OF_REDO_TYPE                        VARCHAR2(10)
);
>>>
 
define 'v$recovery_status'
<<<
define table v$recovery_status
(
CON_ID                                 NUMBER,
RECOVERY_CHECKPOINT                    DATE,
THREAD                                 NUMBER,
SEQUENCE_NEEDED                        NUMBER,
SCN_NEEDED                             VARCHAR2(20),
TIME_NEEDED                            DATE,
PREVIOUS_LOG_NAME                      VARCHAR2(513),
PREVIOUS_LOG_STATUS                    VARCHAR2(13),
REASON                                 VARCHAR2(13)
);
>>>
 
define 'v$offline_range'
<<<
define table v$offline_range
(
CON_ID                                  NUMBER,
RECID                                   NUMBER,
STAMP                                   NUMBER,
FILE#                                   NUMBER,
OFFLINE_CHANGE#                         NUMBER,
ONLINE_CHANGE#                          NUMBER,
ONLINE_TIME                             DATE,
RESETLOGS_CHANGE#                       NUMBER,
RESETLOGS_TIME                          DATE
);
>>>
 
define 'v$backup_set'
<<<
define table v$backup_set
(
CON_ID                                  NUMBER,
RECID                                   NUMBER,
STAMP                                   NUMBER,
SET_STAMP                               NUMBER,
SET_COUNT                               NUMBER,
BACKUP_TYPE                             VARCHAR2(1),
CONTROLFILE_INCLUDED                    VARCHAR2(3),
INCREMENTAL_LEVEL                       NUMBER,
PIECES                                  NUMBER,
START_TIME                              DATE,
COMPLETION_TIME                         DATE,
ELAPSED_SECONDS                         NUMBER,
BLOCK_SIZE                              NUMBER,
STATUS                                  VARCHAR2(1),
INPUT_FILE_SCAN_ONLY                    VARCHAR2(3),
KEEP                                    VARCHAR2(3),
KEEP_UNTIL                              DATE,
KEEP_OPTIONS                            VARCHAR2(13),
MULTI_SECTION                           VARCHAR2(3),
FOR_XTTS                                VARCHAR2(3),
GUID                                    RAW(16)
);
>>>
 
define 'v$backup_piece'
<<<
define table v$backup_piece
(
CON_ID                                  NUMBER,
RECID                                   NUMBER,
STAMP                                   NUMBER,
SET_STAMP                               NUMBER,
SET_COUNT                               NUMBER,
PIECE#                                  NUMBER,
COPY#                                   NUMBER,
DEVICE_TYPE                             VARCHAR2(17),
HANDLE                                  VARCHAR2(513),
COMMENTS                                VARCHAR2(81),
MEDIA                                   VARCHAR2(65),
MEDIA_POOL                              NUMBER,
CONCUR                                  VARCHAR2(3),
TAG                                     VARCHAR2(32),
STATUS                                  VARCHAR2(1),
START_TIME                              DATE,
COMPLETION_TIME                         DATE,
ELAPSED_SECONDS                         NUMBER,
DELETED                                 VARCHAR2(3),
BYTES                                   NUMBER,
IS_RECOVERY_DEST_FILE                   VARCHAR2(3),
RMAN_STATUS_RECID                       NUMBER,
RMAN_STATUS_STAMP                       NUMBER,
COMPRESSED                              VARCHAR2(3),
ENCRYPTED                               VARCHAR2(3),
BACKED_BY_OSB                           VARCHAR2(3),
FOR_XTTS                                VARCHAR2(3),
GUID                                    RAW(16)
);
>>>
 
define 'v$backup_datafile'
<<<
define table v$backup_datafile
(
 CON_ID                                 NUMBER,
 RECID                                  NUMBER,
 STAMP                                  NUMBER,
 SET_STAMP                              NUMBER,
 SET_COUNT                              NUMBER,
 FILE#                                  NUMBER,
 CREATION_CHANGE#                       NUMBER,
 CREATION_TIME                          DATE,
 RESETLOGS_CHANGE#                      NUMBER,
 RESETLOGS_TIME                         DATE,
 INCREMENTAL_LEVEL                      NUMBER,
 INCREMENTAL_CHANGE#                    NUMBER,
 CHECKPOINT_CHANGE#                     NUMBER,
 CHECKPOINT_TIME                        DATE,
 ABSOLUTE_FUZZY_CHANGE#                 NUMBER,
 MARKED_CORRUPT                         NUMBER,
 MEDIA_CORRUPT                          NUMBER,
 LOGICALLY_CORRUPT                      NUMBER,
 DATAFILE_BLOCKS                        NUMBER,
 BLOCKS                                 NUMBER,
 BLOCK_SIZE                             NUMBER,
 OLDEST_OFFLINE_RANGE                   NUMBER,
 COMPLETION_TIME                        DATE,
 CONTROLFILE_TYPE                       VARCHAR2(1),
 USED_CHANGE_TRACKING                   VARCHAR2(3),
 BLOCKS_READ                            NUMBER,
 USED_OPTIMIZATION                      VARCHAR2(3),
 FOREIGN_DBID                           NUMBER,
 PLUGGED_READONLY                       VARCHAR2(3),
 PLUGIN_CHANGE#                         NUMBER,
 PLUGIN_RESETLOGS_CHANGE#               NUMBER,
 PLUGIN_RESETLOGS_TIME                  DATE,
 SECTION_SIZE                           NUMBER,
 SPARSE_BACKUP                          VARCHAR2(3),
 GUID                                   RAW(16)
);
>>>
 
define 'v$backup_corruption'
<<<
define table v$backup_corruption
(
CON_ID                                  NUMBER,
RECID                                   NUMBER,
STAMP                                   NUMBER,
SET_STAMP                               NUMBER,
SET_COUNT                               NUMBER,
PIECE#                                  NUMBER,
FILE#                                   NUMBER,
BLOCK#                                  NUMBER,
BLOCKS                                  NUMBER,
CORRUPTION_CHANGE#                      NUMBER,
MARKED_CORRUPT                          VARCHAR2(3),
CORRUPTION_TYPE                         VARCHAR2(9)
);
>>>
 
define 'v$backup_redolog'
<<<
define table v$backup_redolog
(
CON_ID                                  NUMBER,
RECID                                   NUMBER,
STAMP                                   NUMBER,
SET_STAMP                               NUMBER,
SET_COUNT                               NUMBER,
THREAD#                                 NUMBER,
SEQUENCE#                               NUMBER,
RESETLOGS_CHANGE#                       NUMBER,
RESETLOGS_TIME                          DATE,
FIRST_CHANGE#                           NUMBER,
FIRST_TIME                              DATE,
NEXT_CHANGE#                            NUMBER,
NEXT_TIME                               DATE,
BLOCKS                                  NUMBER,
BLOCK_SIZE                              NUMBER,
TERMINAL                                VARCHAR2(3)
);
>>>
 
define 'v$datafile_copy'
<<<
define table v$datafile_copy
(
CON_ID                                  NUMBER,
RECID                                   NUMBER,
STAMP                                   NUMBER,
NAME                                    VARCHAR2(513),
TAG                                     VARCHAR2(32),
FILE#                                   NUMBER,
RFILE#                                  NUMBER,
CREATION_CHANGE#                        NUMBER,
CREATION_TIME                           DATE,
RESETLOGS_CHANGE#                       NUMBER,
RESETLOGS_TIME                          DATE,
INCREMENTAL_LEVEL                       NUMBER,
CHECKPOINT_CHANGE#                      NUMBER,
CHECKPOINT_TIME                         DATE,
ABSOLUTE_FUZZY_CHANGE#                  NUMBER,
RECOVERY_FUZZY_CHANGE#                  NUMBER,
RECOVERY_FUZZY_TIME                     DATE,
ONLINE_FUZZY                            VARCHAR2(3),
BACKUP_FUZZY                            VARCHAR2(3),
MARKED_CORRUPT                          NUMBER,
MEDIA_CORRUPT                           NUMBER,
LOGICALLY_CORRUPT                       NUMBER,
BLOCKS                                  NUMBER,
BLOCK_SIZE                              NUMBER,
OLDEST_OFFLINE_RANGE                    NUMBER,
DELETED                                 VARCHAR2(3),
STATUS                                  VARCHAR2(1),
COMPLETION_TIME                         DATE,
CONTROLFILE_TYPE                        VARCHAR2(1),
KEEP                                    VARCHAR2(3),
KEEP_UNTIL                              DATE,
KEEP_OPTIONS                            VARCHAR2(13),
SCANNED                                 VARCHAR2(3),
IS_RECOVERY_DEST_FILE                   VARCHAR2(3),
RMAN_STATUS_RECID                       NUMBER,
RMAN_STATUS_STAMP                       NUMBER,
FOREIGN_DBID                            NUMBER,
PLUGGED_READONLY                        VARCHAR2(3),
PLUGIN_CHANGE#                          NUMBER,
PLUGIN_RESETLOGS_CHANGE#                NUMBER,
PLUGIN_RESETLOGS_TIME                   DATE,
CONVERTED_FILE                          VARCHAR2(3),
SPARSE_BACKUP                           VARCHAR2(3),
GUID                                    RAW(16)
);
>>>
 
define 'v$copy_corruption'
<<<
define table v$copy_corruption
(
CON_ID                                  NUMBER,
RECID                                   NUMBER,
STAMP                                   NUMBER,
COPY_RECID                              NUMBER,
COPY_STAMP                              NUMBER,
FILE#                                   NUMBER,
BLOCK#                                  NUMBER,
BLOCKS                                  NUMBER,
CORRUPTION_CHANGE#                      NUMBER,
MARKED_CORRUPT                          VARCHAR2(3),
CORRUPTION_TYPE                         VARCHAR2(9)
);
>>>
 
define 'x$kccblkcor'
<<<
define table x$kccblkcor
(
CON_ID                                  NUMBER,
BLKRID                                  NUMBER,
BLKSTM                                  NUMBER,
BLKTYPE                                 NUMBER,
BLKFNO                                  NUMBER,
BLKCRS                                  NUMBER,
BLKCRT                                  DATE,
BLKTOT                                  NUMBER,
BLKSBLK                                 NUMBER,
BLKSCN                                  NUMBER
);
>>>
 
define 'v$deleted_object'
<<<
define table v$deleted_object
(
CON_ID                                  NUMBER,
RECID                                   NUMBER,
STAMP                                   NUMBER,
TYPE                                    VARCHAR2(30),
OBJECT_RECID                            NUMBER,
OBJECT_STAMP                            NUMBER,
OBJECT_DATA                             NUMBER,
SET_STAMP                               NUMBER,
SET_COUNT                               NUMBER
);
>>>
 
define 'v$backup_spfile'
<<<
define table v$backup_spfile
(
CON_ID                                  NUMBER,
RECID                                   NUMBER,
STAMP                                   NUMBER,
SET_STAMP                               NUMBER,
SET_COUNT                               NUMBER,
MODIFICATION_TIME                       DATE,
BYTES                                   NUMBER,
COMPLETION_TIME                         DATE,
DB_UNIQUE_NAME                          VARCHAR2(30),
GUID                                    RAW(16)
);
>>>
 
define 'v$transportable_platform'
<<<
define table v$transportable_platform
(
CON_ID                                  NUMBER,
PLATFORM_ID                             NUMBER,
PLATFORM_NAME                           VARCHAR2(101)
);
>>>
 
define 'x$kccdi'
<<<
define table x$kccdi
(
ADDR                                    RAW(4),
INDX                                    NUMBER,
INST_ID                                 NUMBER,
CON_ID                                  NUMBER,
DIDFV                                   NUMBER,
DIDFC                                   NUMBER,
DICTS                                   VARCHAR2(20),
DIDBN                                   VARCHAR2(9),
DIRDB                                   NUMBER,
DICCT                                   VARCHAR2(20),
DIFLG                                   NUMBER,
DIIRS                                   VARCHAR2(20),
DIRLS                                   VARCHAR2(20),
DIRLC                                   VARCHAR2(20),
DIRLC_I                                 NUMBER,
DIPRS                                   VARCHAR2(20),
DIPRC                                   VARCHAR2(20),
DIPRC_I                                 NUMBER,
DIRDV                                   NUMBER,
DIRDC                                   NUMBER,
DINDF                                   NUMBER,
DINOF                                   NUMBER,
DICPT                                   NUMBER,
DISCN                                   VARCHAR2(20),
DINET                                   NUMBER,
DINOT                                   NUMBER,
DIOTH                                   NUMBER,
DIOTT                                   NUMBER,
DIETB                                   RAW(8),
DIMLM                                   NUMBER,
DIMDM                                   NUMBER,
DIARH                                   NUMBER,
DIART                                   NUMBER,
DIFAS                                   VARCHAR2(20),
DICKP_SCN                               VARCHAR2(20),
DICKP_TIM                               VARCHAR2(20),
DICSQ                                   NUMBER,
DIDBI                                   NUMBER,
DISSC_SCN                               VARCHAR2(20),
DISSC_TIM                               VARCHAR2(20),
DISFP                                   NUMBER,
DIBSC                                   NUMBER,
DIPOFB                                  NUMBER,
DIPNFB                                  NUMBER,
DICOFB                                  NUMBER,
DICNFB                                  NUMBER,
DIFL2                                   NUMBER
);
>>>
 
define 'x$kccdi2'
<<<
define table x$kccdi2
(
CON_ID                                  NUMBER,
DI2IRT                                  VARCHAR2(20),
DI2FBRET                                NUMBER
);
>>>
 
define 'x$kccfe'
<<<
define table x$kccfe
(
ADDR                                    RAW(4),
INDX                                    NUMBER,
INST_ID                                 NUMBER,
CON_ID                                  NUMBER,
FENUM                                   NUMBER,
FECSZ                                   NUMBER,
FEBSZ                                   NUMBER,
FESTA                                   NUMBER,
FECRC_SCN                               VARCHAR2(20),
FECRC_TIM                               VARCHAR2(20),
FECRC_THR                               NUMBER,
FECRC_RBA_SEQ                           NUMBER,
FECRC_RBA_BNO                           NUMBER,
FECRC_RBA_BOF                           NUMBER,
FECRC_ETB                               RAW(8),
FECPS                                   VARCHAR2(20),
FECPT                                   VARCHAR2(20),
FECPC                                   NUMBER,
FESTS                                   VARCHAR2(20),
FESTT                                   VARCHAR2(20),
FEBSC                                   VARCHAR2(20),
FEFNH                                   NUMBER,
FEFNT                                   NUMBER,
FEDUP                                   NUMBER,
FEURS                                   VARCHAR2(20),
FEURT                                   VARCHAR2(20),
FEOFS                                   VARCHAR2(20),
FEONC_SCN                               VARCHAR2(20),
FEONC_TIM                               VARCHAR2(20),
FEONC_THR                               NUMBER,
FEONC_RBA_SEQ                           NUMBER,
FEONC_RBA_BNO                           NUMBER,
FEONC_RBA_BOF                           NUMBER,
FEONC_ETB                               RAW(8),
FEPOR                                   NUMBER,
FETSN                                   NUMBER,
FETSI                                   NUMBER,
FERFN                                   NUMBER,
FEPFT                                   NUMBER,
FEDOR                                   NUMBER,
FEPDI                                   NUMBER,
FEFDB                                   NUMBER,
FEPLG_SCN                               VARCHAR2(20),
FEPAX                                   NUMBER,
FEPLUS                                  NUMBER,
FEPRLS                                  NUMBER,
FEPRLT                                  DATE,
FEFCRS                                  NUMBER,
FEFCRT                                  DATE,
FEFCPS                                  NUMBER,
FEFCPT                                  DATE,
FEPFDI                                  NUMBER,
FEPFCPS                                 NUMBER,
FEPFAFN                                 NUMBER
);
>>>
 
define 'x$kcctf'
<<<
define table x$kcctf
(
ADDR                                    RAW(4),
INDX                                    NUMBER,
INST_ID                                 NUMBER,
CON_ID                                  NUMBER,
TFNUM                                   NUMBER,
TFAFN                                   NUMBER,
TFCSZ                                   NUMBER,
TFBSZ                                   NUMBER,
TFSTA                                   NUMBER,
TFCRC_SCN                               VARCHAR2(20),
TFCRC_TIM                               VARCHAR2(20),
TFFNH                                   NUMBER,
TFFNT                                   NUMBER,
TFDUP                                   NUMBER,
TFTSN                                   NUMBER,
TFTSI                                   NUMBER,
TFRFN                                   NUMBER,
TFPFT                                   NUMBER,
TFMSZ                                   NUMBER,
TFNSZ                                   NUMBER
);
>>>
 
 
define 'x$kccfle'
<<<
define table x$kccfle
(
ADDR                                    RAW(4),
INDX                                    NUMBER,
INST_ID                                 NUMBER,
CON_ID                                  NUMBER,
FLELTIM                                 VARCHAR2(20)
);
>>>
 
define 'x$kccfn'
<<<
define table x$kccfn
(
ADDR                                    RAW(4),
INDX                                    NUMBER,
INST_ID                                 NUMBER,
CON_ID                                  NUMBER,
FNNUM                                   NUMBER,
FNTYP                                   NUMBER,
FNFNO                                   NUMBER,
FNFWD                                   NUMBER,
FNBWD                                   NUMBER,
FNFLG                                   NUMBER,
FNNAM                                   VARCHAR2(513),
FNONM                                   VARCHAR2(513),
FNUNN                                   NUMBER
);
>>>
 
define 'v$mystat'
<<<
define table v$mystat
(
CON_ID                                  NUMBER,
SID                                     NUMBER,
STATISTIC#                              NUMBER,
VALUE                                   NUMBER
);
>>>
 
define 'v$instance'
<<<
define table v$instance
(
CON_ID                                  NUMBER,
INSTANCE_NUMBER                         NUMBER,
INSTANCE_NAME                           VARCHAR2(16),
HOST_NAME                               VARCHAR2(64),
VERSION                                 VARCHAR2(17),
STARTUP_TIME                            DATE,
STATUS                                  VARCHAR2(7),
PARALLEL                                VARCHAR2(3),
THREAD#                                 NUMBER,
ARCHIVER                                VARCHAR2(7),
LOG_SWITCH_WAIT                         VARCHAR2(11),
LOGINS                                  VARCHAR2(10),
SHUTDOWN_PENDING                        VARCHAR2(3)
);
>>>
 
define 'gv$instance'
<<<
define table gv$instance
(
INST_ID                                 NUMBER,
CON_ID                                  NUMBER,
INSTANCE_NUMBER                         NUMBER,
INSTANCE_NAME                           VARCHAR2(16),
HOST_NAME                               VARCHAR2(64),
VERSION                                 VARCHAR2(17),
STARTUP_TIME                            DATE,
STATUS                                  VARCHAR2(7),
PARALLEL                                VARCHAR2(3),
THREAD#                                 NUMBER,
ARCHIVER                                VARCHAR2(7),
LOG_SWITCH_WAIT                         VARCHAR2(11),
LOGINS                                  VARCHAR2(10),
SHUTDOWN_PENDING                        VARCHAR2(3)
);
>>>
 
define 'v$parameter'
<<<
define table v$parameter
(
CON_ID                                  NUMBER,
NUM                                     NUMBER,
NAME                                    VARCHAR2(64),
TYPE                                    NUMBER,
VALUE                                   VARCHAR2(512),
ISDEFAULT                               VARCHAR2(9),
ISSES_MODIFIABLE                        VARCHAR2(5),
ISSYS_MODIFIABLE                        VARCHAR2(9),
ISMODIFIED                              VARCHAR2(10),
ISADJUSTED                              VARCHAR2(5),
DESCRIPTION                             VARCHAR2(64)
);
>>>
 
define 'v$parameter2'
<<<
define table v$parameter2
(
CON_ID                                  NUMBER,
NUM                                     NUMBER,
NAME                                    VARCHAR2(80),
TYPE                                    NUMBER,
VALUE                                   VARCHAR2(512),
DISPLAY_VALUE                           VARCHAR2(512),
ISDEFAULT                               VARCHAR2(6),
ISSES_MODIFIABLE                        VARCHAR2(5),
ISSYS_MODIFIABLE                        VARCHAR2(9),
ISINSTANCE_MODIFIABLE                   VARCHAR2(5),
ISMODIFIED                              VARCHAR2(10),
ISADJUSTED                              VARCHAR2(5),
ISDEPRECATED                            VARCHAR2(5),
DESCRIPTION                             VARCHAR2(255),
ORDINAL                                 NUMBER,
UPDATE_COMMENT                          VARCHAR2(255)
);
>>>
 
define 'v$memory_dynamic_components'
<<<
define table v$memory_dynamic_components
(
 CON_ID                                 NUMBER,
 COMPONENT                              VARCHAR2(64),
 CURRENT_SIZE                           NUMBER,
 MIN_SIZE                               NUMBER,
 MAX_SIZE                               NUMBER,
 USER_SPECIFIED_SIZE                    NUMBER,
 OPER_COUNT                             NUMBER,
 LAST_OPER_TYPE                         VARCHAR2(13),
 LAST_OPER_MODE                         VARCHAR2(9),
 LAST_OPER_TIME                         DATE,
 GRANULE_SIZE                           NUMBER
);
>>>
 
define 'x$kcrmx'
<<<
define table x$kcrmx
(
ADDR                                    RAW(4),
INDX                                    NUMBER,
INST_ID                                 NUMBER,
CON_ID                                  NUMBER,
BCF                                     NUMBER,
CBR                                     NUMBER,
TBR                                     NUMBER,
SBR                                     NUMBER,
IRS                                     VARCHAR2(20),
INS                                     VARCHAR2(20),
STM                                     VARCHAR2(20),
CKPSCN                                  VARCHAR2(20),
CKPTIM                                  VARCHAR2(20),
CKPETB                                  RAW(8),
EOK                                     NUMBER,
NAM                                     VARCHAR2(513),
THR                                     NUMBER,
SCN                                     VARCHAR2(20),
TIM                                     VARCHAR2(20),
SEQ                                     NUMBER,
LOS                                     VARCHAR2(20),
FAM                                     NUMBER,
UIS                                     NUMBER,
ORT                                     VARCHAR2(20),
NRT                                     VARCHAR2(20),
FLG                                     NUMBER,
MRS                                     NUMBER,
NTX                                     NUMBER,
CTC                                     NUMBER,
RLS                                     NUMBER,
RLC                                     NUMBER
);
>>>
 
define 'x$undo$'
<<<
define table undo$
(
US#                                     NUMBER,
NAME                                    VARCHAR2(30),
USER#                                   NUMBER,
FILE#                                   NUMBER,
BLOCK#                                  NUMBER,
SCNBAS                                  NUMBER,
SCNWRP                                  NUMBER,
XACTSQN                                 NUMBER,
UNDOSQN                                 NUMBER,
INST#                                   NUMBER,
STATUS$                                 NUMBER,
TS#                                     NUMBER,
UGRP#                                   NUMBER,
KEEP                                    NUMBER,
OPTIMAL                                 NUMBER,
FLAGS                                   NUMBER,
SPARE1                                  NUMBER,
SPARE2                                  NUMBER,
SPARE3                                  NUMBER,
SPARE4                                  VARCHAR2(1000),
SPARE5                                  VARCHAR2(1000),
SPARE6                                  DATE
);
>>>
 
define 'x$cdb_rollback_segs'
<<<
define table cdb_rollback_segs
(
SEGMENT_NAME                            VARCHAR2(30),
OWNER                                   VARCHAR2(6),
TABLESPACE_NAME                         VARCHAR2(30),
SEGMENT_ID                              NUMBER,
FILE_ID                                 NUMBER,
BLOCK_ID                                NUMBER,
INITIAL_EXTENT                          NUMBER,
NEXT_EXTENT                             NUMBER,
MIN_EXTENTS                             NUMBER,
MAX_EXTENTS                             NUMBER,
PCT_INCREASE                            NUMBER,
STATUS                                  VARCHAR2(16),
INSTANCE_NUM                            VARCHAR2(40),
RELATIVE_FNO                            NUMBER,
CON_ID                                  NUMBER
);
>>>
 
define 'v$database_incarnation'
<<<
define table v$database_incarnation
(
CON_ID                                             NUMBER,
INCARNATION#                                       NUMBER,
RESETLOGS_CHANGE#                                  NUMBER,
RESETLOGS_TIME                                     DATE,
PRIOR_RESETLOGS_CHANGE#                            NUMBER,
PRIOR_RESETLOGS_TIME                               DATE,
STATUS                                             VARCHAR2(7),
RESETLOGS_ID                                       NUMBER,
PRIOR_INCARNATION#                                 NUMBER
);
>>>
 
define 'x$kcpdbinc'
<<<
define table x$kcpdbinc
(
ADDR                                               RAW(8),
INDX                                               NUMBER,
INST_ID                                            NUMBER,
CON_ID                                             NUMBER,
DBINC                                              NUMBER,
DBRLS                                              NUMBER,
DBRLC                                              DATE,
PDBINC                                             NUMBER,
STATUS                                             NUMBER,
INCSCN                                             NUMBER,
BRSCN                                              NUMBER,
BRTIME                                             DATE,
ERSCN                                              NUMBER,
PR_DBINC                                           NUMBER,
PR_DBRLS                                           NUMBER,
PR_DBRLC                                           DATE,
PR_PDBINC                                          NUMBER,
PR_PDBINC_NULL                                     NUMBER,
PR_INCSCN                                          NUMBER,
PR_ERSCN                                           NUMBER,
FB_ALLOWED                                         NUMBER
);
>>>
 
define 'v$rman_status'
<<<
define table v$rman_status
(
CON_ID             NUMBER,
SID                NUMBER,
RECID              NUMBER,
STAMP              NUMBER,
PARENT_RECID       NUMBER,
PARENT_STAMP       NUMBER,
SESSION_RECID      NUMBER,
SESSION_STAMP      NUMBER,
ROW_LEVEL          NUMBER,
ROW_TYPE           VARCHAR2(20),
COMMAND_ID         VARCHAR2(33),
OPERATION          VARCHAR2(33),
STATUS             VARCHAR2(23),
MBYTES_PROCESSED   NUMBER,
START_TIME         DATE,
END_TIME           DATE,
INPUT_BYTES        NUMBER,
OUTPUT_BYTES       NUMBER,
OPTIMIZED          VARCHAR2(3),
OBJECT_TYPE        VARCHAR2(80),
OUTPUT_DEVICE_TYPE VARCHAR2(17),
OSB_ALLOCATED      VARCHAR2(3)
 
);
>>>
 
define 'v$rman_output'
<<<
define table v$rman_output
(
CON_ID             NUMBER,
SID                NUMBER,
RECID              NUMBER,
STAMP              NUMBER,
RMAN_STATUS_RECID  NUMBER,
RMAN_STATUS_STAMP  NUMBER,
SESSION_RECID      NUMBER,
SESSION_STAMP      NUMBER,
OUTPUT             VARCHAR2(129)
);
>>>
 
define 'x$kccrdi'
<<<
define table x$kccrdi
(
ADDR                                    RAW(4),
INDX                                    NUMBER,
INST_ID                                 NUMBER,
CON_ID                                  NUMBER,
LOCATION                                VARCHAR2(513),
SLIMIT                                  NUMBER,
SUSED                                   NUMBER,
SDATAFILE                               NUMBER,
FCNT                                    NUMBER,
SRECL                                   NUMBER,
SYSAVAIL                                NUMBER,
OMRTIME                                 DATE,
FLAGS                                   NUMBER
);
>>>
 
define 'x$kccrsp'
<<<
define table x$kccrsp
(
ADDR                                    RAW(4),
INDX                                    NUMBER,
INST_ID                                 NUMBER,
CON_ID                                  NUMBER,
RSPNAME                                 VARCHAR2(128),
RSPINCARN                               NUMBER,
RSPSCN                                  VARCHAR2(20),
RSPTIME                                 VARCHAR2(20),
RSPRSPTIME                              VARCHAR2(20),
RSPLGSZ                                 VARCHAR2(23),
RSPFLAGS                                NUMBER,
RSPFSCN                                 VARCHAR2(20),
RSPCLEAN                                NUMBER
);
>>>
 
define 'x$kccnrs'
<<<
define table x$kccnrs
(
ADDR                                    RAW(4),
INDX                                    NUMBER,
INST_ID                                 NUMBER,
CON_ID                                  NUMBER,
NRSNAME                                 VARCHAR2(128),
NRSINCARN                               NUMBER,
NRSSCN                                  VARCHAR2(20),
NRSTIME                                 VARCHAR2(20),
NRSFLAGS                                NUMBER,
NRSRSPTIME                              VARCHAR2(20),
NRSRID                                  NUMBER,
NRSSTM                                  NUMBER,
RSPCLEAN                                NUMBER
);
>>>
 
define 'v$containers'
<<<
define table v$containers
(
CON_ID                                  NUMBER,
DBID                                    NUMBER,
NAME                                    VARCHAR2(128),
OPEN_MODE                               VARCHAR2(10),
CREATE_SCN                              NUMBER,
GUID                                    RAW(16),
LOCAL_UNDO                              NUMBER
);
>>>
 
define 'x$kccpdb'
<<<
define table x$kccpdb
(
CON_ID                                  NUMBER,
PDBRNO                                  NUMBER,
PDBDBID                                 NUMBER,
PDBDBN                                  VARCHAR2(128),
PDBNLN                                  NUMBER,
PDBINC                                  NUMBER,
PDBSTA                                  NUMBER,
PDBFLG                                  NUMBER,
PDBINS                                  VARCHAR2(20),
PDBRDI                                  NUMBER,
PDBCCKP_SCN                             VARCHAR2(20),
PDBCCKP_TIME                            VARCHAR2(20),
PDBADCNE                                NUMBER,
PDBADCNR                                NUMBER,
PDBDFP                                  NUMBER,
PDBTFP                                  NUMBER,
PDBNDF                                  NUMBER,
PDBNTF                                  NUMBER,
PDBCRS                                  VARCHAR2(20),
PDBOTB                                  RAW(132),
PDBCSS                                  VARCHAR2(20),
PDBMKID                                 RAW(16),
PDBUID                                  NUMBER,
PDBGUID                                 RAW(16)
);
>>>
 
define 'x$delete_logs'
<<<
procedure delete_logs(keep_for_rcv     IN boolean,
                      del_all          IN boolean,
                      del_target       IN boolean,
                      preplugin        IN boolean) IS
   alfrec           v$archived_log%ROWTYPE;
   scn_needed_num   number;
   pdbid            number;
   pplcdbdbid       number;
   ppltrans         number;
begin
 
--
   if (keep_for_rcv)
   then
      select to_number(scn_needed) into scn_needed_num
               from v$recovery_status;
   else
      scn_needed_num := 9e125;
   end if;
   
   if (preplugin) then
      krmicd.getPrePluginTranslation(pdbid, pplcdbdbid);
      ppltrans := sys.dbms_backup_restore.beginPrePluginTranslation(
                     pdbid => pdbid, pplcdbdbid => pplcdbdbid);
   end if;
 
--
--
   loop
<<getnext>>
--
--
--
      alfrec.name := krmicd.getLog(scn_needed_num,
                                   alfrec.thread#,
                                   alfrec.sequence#,
                                   alfrec.recid,
                                   alfrec.stamp,
                                   alfrec.resetlogs_change#,
                                   alfrec.first_change#,
                                   alfrec.next_change#,
                                   alfrec.block_size,
                                   alfrec.is_recovery_dest_file,
                                   preplugin);
      exit when (alfrec.name is NULL);
      
      if (not del_all and alfrec.is_recovery_dest_file != 'YES') then
         goto getnext;
      end if;
      
      begin
         if del_target then
            krmicd.deleteArchivedLog(
                                use_target       => 1,
                                recid            => alfrec.recid,
                                stamp            => alfrec.stamp,
                                fname            => alfrec.name,
                                thread           => alfrec.thread#,
                                sequence         => alfrec.sequence#,
                                resetlogs_change => alfrec.resetlogs_change#,
                                first_change     => alfrec.first_change#,
                                blksize          => alfrec.block_size,
                                preplugin        => preplugin);
         else
            sys.dbms_backup_restore.deleteArchivedLog(
                                recid            => alfrec.recid,
                                stamp            => alfrec.stamp,
                                fname            => alfrec.name,
                                thread           => alfrec.thread#,
                                sequence         => alfrec.sequence#,
                                resetlogs_change => alfrec.resetlogs_change#,
                                first_change     => alfrec.first_change#,
                                blksize          => alfrec.block_size);
         end if;
      exception
         when others then
             krmicd.writeMsg(8510, to_char(alfrec.thread#),
                                   to_char(alfrec.sequence#));
             raise;
      end;
      krmicd.writeMsg(8071, krmicd.getChid);
      krmicd.writeMsg(8514, alfrec.name, to_char(alfrec.recid),
                                         to_char(alfrec.stamp));
   end loop;
 
   if (ppltrans > 0) then
      sys.dbms_backup_restore.endPrePluginTranslation;
   end if;
end;
>>>
 
define 'x$name_log'
<<<
procedure name_log(memnum      IN number
                  ,arch_recid  IN number
                  ,arch_stamp  IN number
                  ,thread      IN number
                  ,sequence    IN number
                  ,fname       IN varchar2
                  ,blocks      IN number
                  ,blksize     IN number
                  ,files       IN OUT binary_integer
                  ,first_time  IN OUT boolean
                  ,docopies    IN boolean
                  ,validatecmd IN boolean) IS
  duplicate       boolean;
  in_use          exception;
  del_for_space   exception;
  pragma exception_init(in_use, -19584);
  pragma exception_init(del_for_space, -19805);
begin
   sys.dbms_backup_restore.backupArchivedLog(arch_recid => arch_recid,
                                             arch_stamp => arch_stamp,
                                             duplicate => duplicate);
   if first_time then
      if validatecmd then
         krmicd.writeMsg(8146, krmicd.getChid);
      elsif not docopies then
         krmicd.writeMsg(8014, krmicd.getChid);
      end if;
      first_time := FALSE;
   end if;
 
   if not duplicate then
     files := files + 1;
     krmicd.writeMsg(8504, to_char(thread), to_char(sequence),
                     to_char(arch_recid), to_char(arch_stamp));
   end if;
   deb('name_log', 'blocks=' || blocks || ' block_size=' || blksize,
       rman_constant.DEBUG_IO, rman_constant.LEVEL_MIN);
exception
   when in_use then
      krmicd.writeMsg(8603, fname);
      krmicd.clearErrors;
   when del_for_space then
      krmicd.writeMsg(8604, fname);
      krmicd.clearErrors;
end;
>>>
 
define 'x$name_datafilecopy'
<<<
procedure name_datafilecopy(memnum       IN     number
                           ,copy_recid   IN     number
                           ,copy_stamp   IN     number
                           ,fname        IN     varchar2
                           ,dfnumber     IN     number
                           ,blocks       IN     number
                           ,blksize      IN     number
                           ,tsname       IN OUT varchar2
                           ,files        IN OUT binary_integer
                           ,docopies     IN     boolean
                           ,max_corrupt  IN     number default 0
                           ,since_change IN     number default 0) IS
  in_use           exception; 
  del_for_space    exception;
  dropped_pdb_file exception;
  pragma exception_init(in_use, -19584);
  pragma exception_init(del_for_space, -19805);
  pragma exception_init(dropped_pdb_file, -45913);
begin
  if files < memnum then
    sys.dbms_backup_restore.backupDataFileCopy(
       copy_recid   => copy_recid,
       copy_stamp   => copy_stamp,
       max_corrupt  => max_corrupt,
       since_change => since_change);
 
    if docopies and dfnumber != 0 then
       tsname := sys.dbms_backup_restore.getTsNameFromDataFileCopy(fname,
                                                                   dfnumber);
    end if;
 
    files := files + 1;
 
    if not docopies then
       krmicd.writeMsg(8033, krmicd.getChid, to_char(dfnumber, 'FM09999'));
       krmicd.writeMsg(8506, fname);
    else
       krmicd.writeMsg(8587, to_char(dfnumber, 'FM09999'), fname);
    end if;
 
    deb('budc_name', 'blocks=' || blocks || ' block_size=' || blksize,
        rman_constant.DEBUG_IO, rman_constant.LEVEL_MIN);
  end if;
exception
   when in_use then
      krmicd.writeMsg(8603, fname);
      krmicd.clearErrors;
   when del_for_space then
      krmicd.writeMsg(8604, fname);
      krmicd.clearErrors;
   when dropped_pdb_file then
      krmicd.writeMsg(6825, fname);
      krmicd.clearErrors;
end;
>>>
 
define 'x$getFileRestored'
<<<
procedure getFileRestored(proxy IN boolean) IS
   firstcall  boolean := TRUE;
   ftype      binary_integer;
   thread     binary_integer;
   sequence   number;
   resetscn   number;
   resetstamp number;
   fno        binary_integer;
   callagain  binary_integer;
   fname      varchar2(1024);
begin
   loop
      callagain := sys.dbms_backup_restore.fetchFileRestored(
                                           firstcall  => firstcall,
                                           proxy      => proxy,
                                           ftype      => ftype,
                                           fno        => fno,
                                           thread     => thread,
                                           sequence   => sequence,
                                           resetscn   => resetscn,
                                           resetstamp => resetstamp,
                                           fname      => fname
                                           );
      exit when callagain = 0;
      firstcall := FALSE;
      krmicd.fileRestored(ftype      => ftype,
                          fno        => fno,
                          thread     => thread,
                          sequence   => sequence,
                          resetscn   => resetscn,
                          resetstamp => resetstamp,
                          fname      => fname);
   end loop;
end;
>>>
 
define 'x$stamp2date'
<<<
function stamp2date(stamp IN number) return date IS
x number;
dt varchar2(19);
begin
   x := stamp;
 
   dt := to_char(mod(x,60), 'FM09'); -- seconds
   x := floor(x/60);
 
   dt := to_char(mod(x,60), 'FM09') || ':' || dt; -- minutes
   x := floor(x/60);
 
   dt := to_char(mod(x,24), 'FM09') || ':' || dt; -- hours
   x := floor(x/24);
 
   dt := to_char(mod(x,31)+1, 'FM09') || ' ' || dt; -- days
   x := floor(x/31);
 
   dt := to_char(mod(x,12)+1, 'FM09') || '/' || dt; -- months
 
   dt := to_char(floor(x/12)+1988)   || '/' || dt;
 
   return to_date(dt, 'YYYY/MM/DD HH24:MI:SS');
end;
>>>
 
define 'x$date2stamp'
<<<
function date2stamp(dt IN date) return number is
  stamp number;
begin
  stamp := (((((to_number(to_char(dt, 'YYYY'))-1988)*12
         +     (to_number(to_char(dt, 'MM'))-1))*31
         +     (to_number(to_char(dt, 'DD'))-1))*24
         +     (to_number(to_char(dt, 'HH24'))))*60
         +     (to_number(to_char(dt, 'MI'))))*60
         +     (to_number(to_char(dt, 'SS')));
  return stamp;
end;
>>>
 
define 'x$dur2time'
<<<
procedure dur2time(dur   IN OUT number,
                   hours IN OUT number,
                   mins  IN OUT number,
                   secs  IN OUT number) is
begin
   hours := floor(dur*24);
   dur := dur - hours/24;
 
   mins := floor(dur*24*60);
   dur := dur - mins/(24*60);
 
   secs := dur*24*60*60;
end;
>>>
 
define 'x$currentTime'
<<<
function currentTime return date is
begin
    return CAST(SYS_EXTRACT_UTC(SYSTIMESTAMP) AS DATE);
end;
>>>
 
define 'x$entered'
<<<
procedure entered(func varchar2) is
begin
   krmicd.writeTrc(func, rman_constant.TRACE_ENTER, '',
                   rman_constant.DEBUG_PLSQL, 1);
end;
>>>
 
define 'x$exited'
<<<
procedure exited(func varchar2, str varchar2) is
begin
   krmicd.writeTrc(func, rman_constant.TRACE_EXIT, str,
                   rman_constant.DEBUG_PLSQL, 1);
end;
>>>
 
define 'x$bool2char'
<<<
function bool2char(b boolean) return varchar2 is
begin
   if (b) then return 'TRUE'; else return 'FALSE'; end if;
end;
>>>
 
define 'x$kcvfh'
<<<
DEFINE TABLE x$kcvfh
(
ADDR                                    RAW(4),
INDX                                    NUMBER,
INST_ID                                 NUMBER,
HXFIL                                   NUMBER,
HXONS                                   NUMBER,
HXSTS                                   VARCHAR2(20),
HXERR                                   NUMBER,
HXVER                                   NUMBER,
FHSWV                                   NUMBER,
FHCVN                                   NUMBER,
FHDBI                                   NUMBER,
FHDBN                                   VARCHAR2(9),
FHCSQ                                   NUMBER,
FHFSZ                                   NUMBER,
FHBSZ                                   NUMBER,
FHFNO                                   NUMBER,
FHTYP                                   NUMBER,
FHRDB                                   NUMBER,
FHCRS                                   VARCHAR2(20),
FHCRT                                   VARCHAR2(20),
FHRLC                                   VARCHAR2(20),
FHRLC_I                                 NUMBER,
FHRLS                                   VARCHAR2(20),
FHPRC                                   VARCHAR2(20),
FHPRC_I                                 NUMBER,
FHPRS                                   VARCHAR2(20),
FHBTI                                   VARCHAR2(20),
FHBSC                                   VARCHAR2(20),
FHBTH                                   NUMBER,
FHSTA                                   NUMBER,
FHSCN                                   VARCHAR2(20),
FHTIM                                   VARCHAR2(20),
FHTHR                                   NUMBER,
FHRBA_SEQ                               NUMBER,
FHRBA_BNO                               NUMBER,
FHRBA_BOF                               NUMBER,
FHETB                                   RAW(8),
FHCPC                                   NUMBER,
FHRTS                                   VARCHAR2(20),
FHCCC                                   NUMBER,
FHBCP_SCN                               VARCHAR2(20),
FHBCP_TIM                               VARCHAR2(20),
FHBCP_THR                               NUMBER,
FHBCP_RBA_SEQ                           NUMBER,
FHBCP_RBA_BNO                           NUMBER,
FHBCP_RBA_BOF                           NUMBER,
FHBCP_ETB                               RAW(8),
FHBHZ                                   NUMBER,
FHXCD                                   RAW(16),
FHTSN                                   NUMBER,
FHTNM                                   VARCHAR2(30),
FHRFN                                   NUMBER,
FHAFS                                   VARCHAR2(20),
FHRFS                                   VARCHAR2(20),
FHRFT                                   VARCHAR2(20),
HXIFZ                                   NUMBER,
HXNRCV                                  NUMBER,
HXFNM                                   VARCHAR2(513),
FHPOFB                                  NUMBER,
FHPNFB                                  NUMBER
);
>>>
 
define 'x$kcvfhtmp'
<<<
define table x$kcvfhtmp
(
ADDR                                    RAW(4),
INDX                                    NUMBER,
INST_ID                                 NUMBER,
HTMPXFIL                                NUMBER,
HTMPXONS                                NUMBER,
HTMPXERR                                NUMBER,
HTMPXVER                                NUMBER,
FHTMPSWV                                NUMBER,
FHTMPCVN                                NUMBER,
FHTMPDBI                                NUMBER,
FHTMPDBN                                VARCHAR2(9),
FHTMPCSQ                                NUMBER,
FHTMPFSZ                                NUMBER,
FHTMPBSZ                                NUMBER,
FHTMPFNO                                NUMBER,
FHTMPTYP                                NUMBER,
FHTMPCRS                                VARCHAR2(20),
FHTMPCRT                                VARCHAR2(20),
FHTMPSTA                                NUMBER,
FHTMPCCC                                NUMBER,
FHTMPXCD                                RAW(16),
FHTMPTSN                                NUMBER,
FHTMPTNM                                VARCHAR2(30),
FHTMPRFN                                NUMBER,
HTMPXFNM                                VARCHAR2(513)
);
>>>
 
define 'x$dual'
<<<
DEFINE TABLE x$dual
(
ADDR                                    RAW(4),
INDX                                    NUMBER,
INST_ID                                 NUMBER,
DUMMY                                   VARCHAR2(1)
);
>>>
 
define 'v$proxy_datafile'
<<<
DEFINE TABLE v$proxy_datafile
(
CON_ID                                  NUMBER,
RECID                                   NUMBER,
STAMP                                   NUMBER,
DEVICE_TYPE                             VARCHAR2(17),
HANDLE                                  VARCHAR2(513),
COMMENTS                                VARCHAR2(81),
MEDIA                                   VARCHAR2(65),
MEDIA_POOL                              NUMBER,
TAG                                     VARCHAR2(32),
STATUS                                  VARCHAR2(1),
DELETED                                 VARCHAR2(3),
FILE#                                   NUMBER,
CREATION_CHANGE#                        NUMBER,
CREATION_TIME                           DATE,
RESETLOGS_CHANGE#                       NUMBER,
RESETLOGS_TIME                          DATE,
CHECKPOINT_CHANGE#                      NUMBER,
CHECKPOINT_TIME                         DATE,
ABSOLUTE_FUZZY_CHANGE#                  NUMBER,
RECOVERY_FUZZY_CHANGE#                  NUMBER,
RECOVERY_FUZZY_TIME                     DATE,
INCREMENTAL_LEVEL                       NUMBER,
ONLINE_FUZZY                            VARCHAR2(3),
BACKUP_FUZZY                            VARCHAR2(3),
BLOCKS                                  NUMBER,
BLOCK_SIZE                              NUMBER,
OLDEST_OFFLINE_RANGE                    NUMBER,
START_TIME                              DATE,
COMPLETION_TIME                         DATE,
ELAPSED_SECONDS                         NUMBER,
CONTROLFILE_TYPE                        VARCHAR2(1),
KEEP                                    VARCHAR2(3),
KEEP_UNTIL                              DATE,
KEEP_OPTIONS                            VARCHAR2(13),
RMAN_STATUS_RECID                       NUMBER,
RMAN_STATUS_STAMP                       NUMBER,
FOREIGN_DBID                            NUMBER,
PLUGGED_READONLY                        VARCHAR2(3),
PLUGIN_CHANGE#                          NUMBER,
PLUGIN_RESETLOGS_CHANGE#                NUMBER,
PLUGIN_RESETLOGS_TIME                   DATE,
GUID                                    RAW(16)
);
>>>
 
define 'v$proxy_archivedlog'
<<<
DEFINE TABLE v$proxy_archivedlog
(
RECID                                   NUMBER,
STAMP                                   NUMBER,
DEVICE_TYPE                             VARCHAR2(17),
HANDLE                                  VARCHAR2(513),
COMMENTS                                VARCHAR2(81),
MEDIA                                   VARCHAR2(65),
MEDIA_POOL                              NUMBER,
TAG                                     VARCHAR2(32),
STATUS                                  VARCHAR2(1),
DELETED                                 VARCHAR2(3),
THREAD#                                 NUMBER,
SEQUENCE#                               NUMBER,
RESETLOGS_CHANGE#                       NUMBER,
RESETLOGS_TIME                          DATE,
FIRST_CHANGE#                           NUMBER,
FIRST_TIME                              DATE,
NEXT_CHANGE#                            NUMBER,
NEXT_TIME                               DATE,
BLOCKS                                  NUMBER,
BLOCK_SIZE                              NUMBER,
START_TIME                              DATE,
COMPLETION_TIME                         DATE,
ELAPSED_SECONDS                         NUMBER,
RMAN_STATUS_RECID                       NUMBER,
RMAN_STATUS_STAMP                       NUMBER,
TERMINAL                                VARCHAR2(3),
KEEP                                    VARCHAR2(3),
KEEP_UNTIL                              DATE,
KEEP_OPTIONS                            VARCHAR2(13)
);
>>>
 
define 'x$is_recovery_area_enabled'
<<<
function is_recovery_area_enabled return boolean IS
   dbstate        number := 0;
begin
  select   count(*)
    into   dbstate
    from   x$kccrdi
   where   location is not null;
   
  if (dbstate = 0) then
     return FALSE;
  end if;
 
  return TRUE;
end;
>>>
 
define 'x$aged_files'
<<<
procedure refreshAgedFiles is
  busy_retries  number := 0;             -- retry counter for ss enqueue busy
  err_msg       varchar2(2048);
begin
   if (NOT krmicd.valRedoLogDeletionPolicy) then
      krmicd.writeMsg(8591);
   end if;
 
   if (NOT is_recovery_area_enabled()) then
      deb('refreshAgedFiles', 'recovery area is not enabled');
      return;
   end if;
 
   deb('refreshAgedFiles', 'Starting refreshAgedFiles at ' || to_char(sysdate));
 
 
 
<<retry>>
   begin
      sys.dbms_backup_restore.refreshAgedFiles;
   exception
     when others then
        err_msg := sqlerrm;
        krmicd.writeErrMsg(6764, err_msg);
        krmicd.writeMsg(8132);          -- unable to refresh aged files
        krmicd.clearErrors;
   end;
 
   deb('refreshAgedFiles', 'Finished refreshAgedFiles at ' || to_char(sysdate));
end;
>>>
 
define 'x$applied_al'
<<<
function isalnotapplied(recid            IN number,
                        stamp            IN number,
                        next_change      IN number,
                        resetlogs_change IN number,
                        resetlogs_time   IN varchar2)
return boolean IS
   applied_change number;
   isnotapplied   binary_integer := 1;
begin
--
   select decode(al.applied, 'YES', 0, 1)
     into isnotapplied
     from v$archived_log al
    where al.recid = isalnotapplied.recid
      and al.stamp = isalnotapplied.stamp
      and al.resetlogs_change# = isalnotapplied.resetlogs_change
      and al.resetlogs_time = to_date(isalnotapplied.resetlogs_time,
                                      'YYYY-MM-DD HH24:MI:SS',
                                      'NLS_CALENDAR=Gregorian');
   if (isnotapplied = 1) then
--
--
      select nvl(max(al.first_change#), 0)
         into applied_change
         from v$archived_log al
        where al.applied = 'YES'
          and al.standby_dest = 'NO'
          and al.resetlogs_change# = isalnotapplied.resetlogs_change
          and al.resetlogs_time = to_date(isalnotapplied.resetlogs_time,
                                          'YYYY-MM-DD HH24:MI:SS',
                                          'NLS_CALENDAR=Gregorian');
      if (next_change <= applied_change) then
         isnotapplied := 0;
      end if;
  end if;
 
  if (isnotapplied > 0) then
     return TRUE;
  else
     return FALSE;
  end if;
end;
>>>
 
define 'x$isalforgrsp'
<<<
function isalforgrsp(first_change     IN number,
                     next_change      IN number,
                     resetlogs_change IN number,
                     resetlogs_time   IN varchar2)
return boolean is
   count_grsp  number;
begin
   select count(*)
     into count_grsp
     from x$kccrsp grsp,
          v$database_incarnation dbinc
    where grsp.rspincarn = dbinc.incarnation#
      and bitand(grsp.rspflags, 2) != 0
      and bitand(grsp.rspflags, 1) = 1  -- Guaranteed
      and grsp.rspfscn <= grsp.rspscn -- filter archived log for clean grsp
      and grsp.rspfscn != 0
      and dbinc.resetlogs_change# = isalforgrsp.resetlogs_change
      and dbinc.resetlogs_time = to_date(isalforgrsp.resetlogs_time,
                                         'YYYY-MM-DD HH24:MI:SS',
                                         'NLS_CALENDAR=Gregorian')
--
      and isalforgrsp.first_change  <= (grsp.rspscn + 1)
      and isalforgrsp.next_change >= grsp.rspfscn;
 
   if (count_grsp > 0) then
      return TRUE;
   end if;
   return FALSE;
end;
>>>
 
define 'x$del_copy'
<<<
procedure del_copy(copy_recid         IN  number
                  ,copy_stamp         IN  number
                  ,fname              IN  varchar2
                  ,dfnumber           IN  binary_integer
                  ,resetlogs_change   IN  number
                  ,creation_change    IN  number
                  ,checkpoint_change  IN  number
                  ,blksize            IN  number
                  ,no_delete          IN  binary_integer) IS
begin 
   sys.dbms_backup_restore.deleteDataFileCopy(
                          recid             => copy_recid,
                          stamp             => copy_stamp,
                          fname             => fname,
                          dfnumber          => dfnumber,
                          resetlogs_change  => resetlogs_change,
                          creation_change   => creation_change,
                          checkpoint_change => checkpoint_change,
                          blksize           => blksize,
                          no_delete         => no_delete);
   if (dfnumber = 0) then
      krmicd.writeMsg(8072);
      krmicd.writeMsg(8516, fname, to_char(copy_recid), to_char(copy_stamp));
   else
      krmicd.writeMsg(8070);
      krmicd.writeMsg(8513, fname, to_char(copy_recid), to_char(copy_stamp));
  end if;
end;
>>>
 
define 'x$del_log'
<<<
procedure del_log(cfisstby            IN     boolean
                 ,arch_recid          IN     number
                 ,arch_stamp          IN     number
                 ,fname               IN     varchar2
                 ,thread              IN     number
                 ,sequence            IN     number
                 ,resetlogs_change    IN     number
                 ,resetlogs_time      IN     varchar2
                 ,first_change        IN     number
                 ,blksize             IN     number
                 ,next_change         IN     number
                 ,first_time          IN OUT boolean
                 ,docopies            IN     boolean
                 ,reqscn              IN OUT number     -- required scn
                 ,rlgscn              IN OUT number
                 ,appscn              IN OUT number     -- applied scn
                 ,apprlgscn           IN OUT number
                 ,alldest             IN     number
                 ,reqbackups          IN     number
                 ,nbackups            IN     number) IS
   skiparch_lal  boolean := FALSE; -- TRUE if log is required locally
   skiparch_ral  boolean := FALSE; -- TRUE is log is required remotely
   skiparch_nbck boolean := FALSE; -- TRUE if log is required for backups
   skiparch_grsp boolean := FALSE;
   err_msg       varchar2(2048);
begin
--
--
   if (not docopies) then
 
--
--
--
--
      if (first_time) then
         krmicd.getArchiveLogDeletionSCN(alldest, reqscn, rlgscn, 
                                         appscn, apprlgscn);
         deb('del_log', 'reqscn='||reqscn||',rlgscn='||rlgscn);
         deb('del_log', 'appscn='||appscn||',apprlgscn='||apprlgscn);
      end if;
 
      if ((next_change > appscn and resetlogs_change = apprlgscn) OR
          (resetlogs_change > apprlgscn)) then
         skiparch_lal := TRUE;
         deb('del_log', 'next_change='||next_change||
                        ',rlgscn='||resetlogs_change);
--
--
--
--
      elsif ((next_change > reqscn and resetlogs_change = rlgscn) OR
             (resetlogs_change > reqscn)) then
         skiparch_ral := TRUE;
         deb('del_log', 'next_change='||next_change||
                        ',rlgscn='||resetlogs_change);
      elsif (reqbackups > nbackups) then
--
         skiparch_nbck := TRUE;
      else
         skiparch_grsp :=
            isalforgrsp(first_change, next_change, resetlogs_change,
                        resetlogs_time);
      end if;
 
   end if;
 
--
--
   if (first_time) then
      krmicd.writeMsg(8071, krmicd.getChid);
   end if;
   first_time := FALSE;
 
   if skiparch_lal then
      krmicd.writeMsg(8120);
      krmicd.writeMsg(8515, fname, to_char(thread), to_char(sequence));
   elsif skiparch_ral then
      krmicd.writeMsg(8137);
      krmicd.writeMsg(8515, fname, to_char(thread), to_char(sequence));
   elsif skiparch_nbck then
      krmicd.writeMsg(8138);
      krmicd.writeMsg(8515, fname, to_char(thread), to_char(sequence));
   elsif skiparch_grsp then
      krmicd.writeMsg(8139);
      krmicd.writeMsg(8515, fname, to_char(thread), to_char(sequence));
   else
--
--
      krmicd.writeMsg(8514, fname, to_char(arch_recid), to_char(arch_stamp));
      begin
         sys.dbms_backup_restore.deleteArchivedLog(
                                  recid            => arch_recid,
                                  stamp            => arch_stamp,
                                  fname            => fname,
                                  thread           => thread,
                                  sequence         => sequence,
                                  resetlogs_change => resetlogs_change,
                                  first_change     => first_change,
                                  blksize          => blksize);
--
--
      exception
         when others then
           err_msg := sqlerrm;
           krmicd.writeMsg(8118);
           krmicd.writeMsg(8515, fname, to_char(thread), to_char(sequence));
           krmicd.writeErrMsg(4005, err_msg);
           krmicd.clearErrors;
      end;
   end if;
end;
>>>
 
define 'x$is_db_in_noarchivelog'
<<<
function is_db_in_noarchivelog return boolean is
   noarchivelog binary_integer;
begin
  select count(*)
    into noarchivelog
    from v$database
   where log_mode = 'NOARCHIVELOG';
  if (noarchivelog = 0) then
     return FALSE;
  else
     return TRUE;
  end if;
end;
>>>
 
define 'x$listNbrBlockStat'
<<<
procedure listNbrBlockStat(blkstat IN sys.dbms_backup_restore.blockStatTable_t)
                          IS
   firstcall    boolean := TRUE;
   lastcall     boolean := FALSE;      
begin
   for i in 1..blkstat.count loop
        if (i = blkstat.count) then
           lastcall := TRUE;
        end if;
 
        if firstcall then
           krmicd.writeMsg(7225);
           krmicd.writeMsg(7226);
           krmicd.writeMsg(7267);
           krmicd.writeMsg(7268);
        end if;
 
        if blkstat(i).status then
           krmicd.writeMsg(7269,
                           to_char(blkstat(i).dfnumber),
                           to_char(blkstat(i).corrupt),
                           to_char(blkstat(i).examined),
                           to_char(blkstat(i).empty));
        else
           krmicd.writeMsg(7270, to_char(blkstat(i).dfnumber));
        end if;
 
        if lastcall then
           krmicd.writeMsg(0);
           krmicd.writeMsg(7271);
           krmicd.writeMsg(0);
        end if;
 
        firstcall := FALSE;
   end loop;
          
end;
>>>
 
define regdb
<<<
--
declare
  db_name     varchar2(8);
  reg_dbuname varchar2(30);
  reset_scn   number;
  reset_time  date;
  db_id       number;
  cf_type     binary_integer;
  cf_sequence binary_integer;
  l_con_id    number := sys_context('userenv', 'con_id');
  l_guid      v$containers.guid%type;
begin
    select dbid, name, resetlogs_change#, resetlogs_time,
           db_unique_name
    into   db_id, db_name, reset_scn, reset_time, reg_dbuname
    from v$database;
 
    select c.guid into l_guid from v$containers c
     where c.con_id = l_con_id;
 
    dbms_rcvcat.registerDatabase
      (db_id, db_name, reset_scn, reset_time, reg_dbuname, l_con_id, l_guid);
    krmicd.writeMsg(8006, db_name);
end;
>>>
 
define resetdb
<<<
--
declare
  db_name     varchar2(8);
  reset_scn   number;
  reset_time  date;
  parent_reset_scn number;
  parent_reset_time  date;
  db_id       number;
  cf_type     binary_integer;
  cf_sequence binary_integer;
  dbinc_key   number;
  cfdbinc_key number;
  db_not_mounted EXCEPTION;
  PRAGMA EXCEPTION_INIT(db_not_mounted, -1507);
  incarnation_key_missing EXCEPTION;
  PRAGMA EXCEPTION_INIT(incarnation_key_missing, -20008);
  incarnation_already_registered EXCEPTION;
  PRAGMA EXCEPTION_INIT(incarnation_already_registered, -20009);
 
begin
  &object&
 
%IF% target
  if (dbinc_key is not NULL) then
    sys.dbms_backup_restore.resetdatabase(dbinc_key);
    krmicd.writeMsg(8066, dbinc_key);
  else
    raise incarnation_key_missing;
  end if;
%ENDIF% target
 
%IF% catalog
  if (dbinc_key is NULL) then
    select dbid, name, resetlogs_change#, resetlogs_time
    into   db_id, db_name, reset_scn, reset_time
    from v$database;
 
    select diprs, to_date(diprc, 'MM/DD/RR HH24:MI:SS',
                          'NLS_CALENDAR=Gregorian')
    into parent_reset_scn, parent_reset_time
    from x$kccdi;
 
    begin
      dbms_rcvcat.resetDatabase(db_id             => db_id,
                                db_name           => db_name,
                                reset_scn         => reset_scn,
                                reset_time        => reset_time,
                                parent_reset_scn  => parent_reset_scn,
                                parent_reset_time => parent_reset_time);
      dbms_rcvcat.setReason(dbms_rcvcat.RESYNC_REASON_RESET);
      krmicd.writeMsg(8005, db_name);
    exception
      when incarnation_already_registered then
        krmicd.writeMsg(20009);
      when others then
        raise;
    end;
  else
    select upper(value) into db_name
    from v$parameter
    where name = 'db_name';
    dbms_rcvcat.resetDatabase(dbinc_key, db_name, reset_scn, reset_time, db_id);
    krmicd.writeMsg(8066, dbinc_key);
 
    begin
      select incarnation# into cfdbinc_key from v$database_incarnation
        where resetlogs_change#=reset_scn and
           resetlogs_time =reset_time;
       sys.dbms_backup_restore.resetDatabase(cfdbinc_key);
--
    exception
      when db_not_mounted then
        krmicd.clearErrors;
      when no_data_found then
        krmicd.writeMsg(6566);
      when others then
        krmicd.writeErrMsg(1005, sqlerrm);
    end;
  end if;
%ENDIF% catalog
end;
>>>
 
define 'resync'
<<<
--
declare
 
&constants&
 
  CONFIGRESYNC_NO         CONSTANT number := 0;
  CONFIGRESYNC_TORC       CONSTANT number := 1;
  CONFIGRESYNC_TOCF       CONSTANT number := 2;
  CONFIGRESYNC_TORC_TOCF  CONSTANT number := 3;
 
  mount_status varchar2(7);
  cf_type      varchar2(7) := NULL;
  tmzone            varchar2(256);    -- timezone of primary
  db_id             number;
  db_name           varchar2(8);
  ldb_unique_name   varchar2(30);       -- parameter db_unique_name
  reset_scn         number;             -- db current reset scn
  reset_time        date;               -- db current reset time
  err_msg           varchar2(2048);
  parent_reset_scn  number;
  parent_reset_time date;
 
 
 
--
  flashback_time date      := to_date(NULL);
 
  prior_reset_scn   number;             -- db prior reset scn
  prior_reset_time  date;               -- db prior reset time
 
  snapcf      varchar2(512);            -- snapshot controlfile name
  name        varchar2(512);            -- default snapshot cf name
  cfname      varchar2(512) := NULL;    -- backup cf name
 
  ckp_scn     number;
  ckp_time    date;
  ckp_cf_seq  number;
  cf_create_time date;
  getckptscn  number;
  cf_version  date;                     -- v$database.version_time
  kccdivts    number;                   -- date2stamp(cf_version)
 
  recid number;
  high_cp_recid  number; -- 1
  high_rt_recid  number; -- 2
  high_le_recid  number; -- 3
  high_fe_recid  number; -- 4
  high_fn_recid  number; -- 5
  high_ts_recid  number; -- 6
  high_r1_recid  number; -- 7
  high_rm_recid  number; -- 8
  high_lh_recid  number; -- 9
  high_or_recid  number; -- 10
  high_al_recid  number; -- 11
  high_bs_recid  number; -- 12
  high_bp_recid  number; -- 13
  high_bf_recid  number; -- 14
  high_bl_recid  number; -- 15
  high_dc_recid  number; -- 16
  high_fc_recid  number; -- 17
  high_cc_recid  number; -- 18
  high_dl_recid  number; -- 19
  high_pc_recid  number; -- 20
  high_bi_recid  number; -- 21
 
--
--
--
  high_ic_recid   number;  -- 22 'DATABASE INCARNATION'
  high_rsr_recid  number;  -- 24 'RMAN STATUS RECORDS'
  high_tf_recid   number;
  high_grsp_recid number := 0;
  high_nrsp_recid number := 0;
  shigh_rsr_recid number;
  high_rout_stamp number;  -- in-memory 'RMAN OUTPUT records' high record stamp
  inst_startup_time DATE;
  inst_startup_stamp number;
  high_bcr_recid number;  -- 'DATABASE BLOCK CORRUPTION'
  low_bcr_recid  number;
  high_pdb_recid number;
  high_pic_recid number;
 
  doRoutMining boolean;
  full_resync boolean;  -- set by rman compiler
  implicit    boolean;  -- set by rman compiler
  debug_resync boolean; -- set by rman compiler
  converted_cf boolean; -- set by rman compiler
 
  read_retries number := 0;             -- retry counter for inconsistant_read
  busy_retries number := 0;             -- retry counter for ss enqueue busy
  sort_retries number := 0;             -- retry counter for sort_area_size
  sync_retries number := 0;             -- retry counter for automatic resync
 
  conf_toCF    boolean := FALSE;        -- flags that tells how resync conf
  first        boolean;
  force        boolean;                 -- flag that tells do we force resync
  rc_aux_fname varchar2(1025);          -- aux_name from recovery catalog
 
  rbs_count    number := NULL;
  b            boolean;
  read_only    number;
  ret          number;
 
  sort_area_size   number;    -- sort_area_size from v$parameter
  sort_area_size_init CONSTANT number := 10485760;
  sort_area_size_incr CONSTANT number := 10485760;
  rec_size         number;    -- record_size from v$controlfile_record_section
  total_recs       number;
  high_recno       number;
  rec_per_chunk    integer;
  high             number;
  low              number;
  found            number;
  releasecf        boolean := FALSE;    -- flag tells to release cfile enqueue
  parent_dbinc_key number;
  low_bs_recid     number;
  low_bdf_recid    number;
  low_bsf_recid    number;
  low_brl_recid    number;
  local_low        number;
  local_high       number;
  dbtype           number := rman_constant.DEBUG_RESYNC;
  low_run_recid    number := 0;        -- Lowest remote runnig rman row
  running_found    boolean;            -- flag used in resync of V$RMAN_STATUS
 
  resyncstamp      number := 0;        -- resync above this timestamp
  min_stamp        number;             -- minimum timestamp
  max_stamp        number;             -- maximum timestamp
  high_stamp       number;             -- to move high timestamp
  new_min_stamp    number;             -- retry using this minimum timestamp
  until_stamp      number;             -- check until this timestamp
  wasresyncstamp   number;             -- was resynced timestamp
  middle           number;             -- for binary search
  no_units         number;             -- number of units between min-max stamp
  maxdups          number := 16;       -- look for these many duplicates
  lh_lowscn        number;             -- low_scn of log history resynced
 
--
--
--
--
--
--
--
  unit             number := 2;        -- 12 hours granularity
  least_stamp      CONSTANT number := 0;
  greatest_stamp   CONSTANT number := 2**32;
 
  resync_reason           number;
  fullResyncBaseMsg       number;
  resync_active           boolean;
  resync_valid            boolean;
  resync_added            number;
  resync_dropped          number;
  resync_changed          number;
  resync_recreated        number;
  resync_renamed          number;
  resync_resized          number;
 
  type rspname_t is table of x$kccrsp.rspname%type index by binary_integer;
  type numTab_t  is table of number index by binary_integer;
  type timeTab_t is table of date index by binary_integer;
  type boolTab_t is table of varchar2(3) index by binary_integer;
  for_dbuname             varchar2(30);
  curr_dbuname            varchar2(30);
  source_cs               varchar2(512);
  dest_cs                 varchar2(512);
  for_db_id               number;
  ub4_cf_type             binary_integer := 0;
  null_retVal             varchar2(1);
  auto_prim_resync        boolean := FALSE;
  callSetDatabase         boolean := FALSE;
  pdb_dict_check          numTab_t;
  pdb_dict_check_sby      numTab_t;
  ignore_resync_err       boolean := FALSE;
  lrecid                  number;
  lstamp                  number;
  lrec_type               number;
  lfname                  varchar2(1024);
  oam_tst_level           number;
  resync_2_AMSchema       number := 0;
  rsid                    number;
  rsts                    number;
  curr_set_stamp          number := 0;
  curr_set_count          number := 0;
  invalid_pdbid           number := sys.dbms_backup_restore.getParm(16);
 
  need_primary_resync exception;
  pragma exception_init(need_primary_resync, -20079);
 
  db_id_mismatch exception;
  pragma exception_init(db_id_mismatch, -20109);
 
  sort_area_too_small EXCEPTION;
  PRAGMA EXCEPTION_INIT(sort_area_too_small, -1220);
 
  resync_not_needed exception;
  pragma exception_init(resync_not_needed, -20034);
 
  DATABASE_INCARNATION_NOT_FOUND exception;
  pragma exception_init(DATABASE_INCARNATION_NOT_FOUND, -20003);
 
  change_record_stamp exception;
  pragma exception_init(change_record_stamp, -20081);
 
  dbuname_mismatch exception;
  pragma exception_init(dbuname_mismatch, -20223);
  
  setstamp_setcount_conflict  exception;
  pragma exception_init(setstamp_setcount_conflict, -20110);
 
  invalid_setstamp_setcount_conf  exception;
  pragma exception_init(invalid_setstamp_setcount_conf, -20111);
  
  incarnation_already_registered exception;
  pragma exception_init(incarnation_already_registered, -20009);
 
--
--
--
--
--
--
--
--
--
--
 
  cursor rs is
    select type, last_recid from v$controlfile_record_section;
 
  cursor pdb is
    select name, con_id, dbid, create_scn, guid, 'N' noBackup
      from v$containers
     where con_id = 0            -- applicable only for non-cdb
   union all
    select substr(pdb.pdbdbn, 1, pdb.pdbnln) name, pdb.con_id, pdb.pdbdbid dbid,
       to_number(pdb.pdbcrs) create_scn, pdb.pdbguid guid,
       decode(bitand(pdb.pdbflg, 4096), 4096, 'Y', 'N') noBackup
      from x$kccpdb pdb
     where (pdb.pdbcrs > 0 or con_id  = 1) 
--
--
       and (pdb.pdbsta != 3 OR bitand(pdb.pdbflg, 8192)=8192)
       and pdb.con_id > 0
   order by guid;
 
  cursor pdb_dict_check_c is
    select con_id, pdbdbn name
      from x$kccpdb pdb
     where pdb.con_id > 1
       and (pdb.pdbsta != 3 OR bitand(pdb.pdbflg, 8192)=8192)
       and bitand(pdb.pdbflg, 8192) !=8192  -- skip refresh PDBs
       and bitand(pdb.pdbflg, 1) = 1;
     
 
--
--
--
--
--
 
--
--
--
--
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
 
--
--
--
--
--
--
--
--
 
  cursor ts is
    select ts2.ts#,
           ts2.name,
           ts2.included_in_database_backup,
           to_number(fe2.fecrc_scn) create_scn,
           to_date(fe2.fecrc_tim,'MM/DD/RR HH24:MI:SS',
                                 'NLS_CALENDAR=Gregorian') create_time,
           ts2.bigfile bigfile,
           'NO'        temporary,
           ts2.encrypt_in_backup,
           fe2.feplus plugin_scn,
           ts2.con_id con_id
    from x$kccfe fe2,
         (select ts1.ts#,
                 ts1.name,
                 ts1.included_in_database_backup,
                 min(fe1.fenum) fenum,
                 ts1.bigfile bigfile,
                 ts1.encrypt_in_backup,
                 ts1.con_id
          from x$kccfe fe1,
               (select ts.ts#,
                       ts.name,
                       ts.included_in_database_backup,
                       min(to_number(fe.fecrc_scn)) create_scn,
                       ts.bigfile bigfile,
                       ts.encrypt_in_backup,
                       ts.con_id
                from x$kccfe fe, v$tablespace ts
                where fe.fetsn=ts.ts#
                  and fe.con_id = ts.con_id
                  and fe.fedup<>0
                group by ts.con_id,
                         ts.ts#,
                         ts.name,
                         ts.included_in_database_backup,
                         ts.bigfile,
                         ts.encrypt_in_backup
               ) ts1
          where ts1.ts#=fe1.fetsn and
                ts1.con_id= fe1.con_id and
                to_number(fe1.fecrc_scn) = ts1.create_scn
          group by ts1.con_id,
                   ts1.ts#,
                   ts1.name,
                   ts1.included_in_database_backup,
                   ts1.bigfile,
                   ts1.encrypt_in_backup
         ) ts2
    where ts2.fenum=fe2.fenum and (fe2.fefdb = 0 or fe2.feplus != 0)
    union all
    select ts2.ts#,
           ts2.name,
           ts2.included_in_database_backup,
           to_number(tf2.tfcrc_scn) create_scn,
           to_date(tf2.tfcrc_tim,'MM/DD/RR HH24:MI:SS',
                                 'NLS_CALENDAR=Gregorian') create_time,
           ts2.bigfile bigfile,
           'YES'       temporary,
           ts2.encrypt_in_backup,
           0 plugin_scn,
           ts2.con_id con_id
    from x$kcctf tf2,
         (select ts1.ts#,
                 ts1.name,
                 ts1.included_in_database_backup,
                 min(tf1.tfnum) tfnum,
                 ts1.bigfile bigfile,
                 ts1.encrypt_in_backup,
                 ts1.con_id
          from x$kcctf tf1,
               (select ts.ts#,
                       ts.name,
                       ts.included_in_database_backup,
                       min(to_number(tf.tfcrc_scn)) create_scn,
                       ts.bigfile bigfile,
                       ts.encrypt_in_backup,
                       ts.con_id
                from x$kcctf tf, v$tablespace ts
                where tf.tftsn = ts.ts#
                  and tf.con_id = ts.con_id
                  and tf.tfdup != 0
                  and bitand(tf.tfsta, 32) != 32
                group by ts.con_id,
                         ts.ts#,
                         ts.name,
                         ts.included_in_database_backup,
                         ts.bigfile,
                         ts.encrypt_in_backup
               ) ts1
          where ts1.ts#=tf1.tftsn and
                ts1.con_id = tf1.con_id and
                to_number(tf1.tfcrc_scn) = ts1.create_scn
          group by ts1.con_id,
                   ts1.ts#,
                   ts1.name,
                   ts1.included_in_database_backup,
                   ts1.bigfile,
                   ts1.encrypt_in_backup
         ) ts2
    where ts2.tfnum=tf2.tfnum
    order by 10, 1; -- con_id, ts#
 
--
--
--
--
--
--
--
--
--
--
--
--
--
  cursor df(low_fno number, high_fno number) IS
    SELECT fenum fileno,
      to_number(fe.fecrc_scn) create_scn,
      to_date(fe.fecrc_tim,'MM/DD/RR HH24:MI:SS',
              'NLS_CALENDAR=Gregorian') create_time,
      fe.fecrc_thr create_thread,
      fe.fecsz     create_size,
      fe.fetsn tsnum,
      fn.fnnam fname,
      fh.fhfsz fsize,
      fe.febsz block_size,
      to_number(fe.feofs) offline_scn,
      to_number(fe.feonc_scn) online_scn,
      to_date(fe.feonc_tim,'MM/DD/RR HH24:MI:SS',
              'NLS_CALENDAR=Gregorian') online_time,
      to_number(fe.fecps) stop_scn,
      to_date(fe.festt, 'MM/DD/RR HH24:MI:SS',
              'NLS_CALENDAR=Gregorian') stop_time,
      to_number(bitand(fe.festa, 4096+128)) clean_flag, -- This WCC or SOR
      to_number(bitand(fe.festa, 4)) read_enabled_flag,
      to_number(bitand(fe.festa, 64)) missing_file_flag, -- this is KCCFECKD
      fe.ferfn rfileno,                      -- this is relative file number
      decode(fe.fepax, 0    , 'UNKNOWN'
                     , 65535, 'NONE'
                            , fnaux.fnnam) aux_fname,
      fe.fepdi foreign_dbid,
      fe.fefcrs foreign_create_scn,
      fe.fefcrt foreign_create_time,
      decode(fe.fefdb, 1, 'YES', 'NO') plugged_readonly,
      fe.feplus plugin_scn,
      fe.feprls plugin_reset_scn,
      fe.feprlt plugin_reset_time,
      fe.con_id con_id,
      CASE WHEN fe.con_id > 1 THEN
         decode(bitand(fe.festa, (4096+128)), 0, 0,
                decode(fe.fecps, fe1.pdbStopScn, 1, 0))
      ELSE 0 END pdb_closed,
      fe.fepfdi  pdb_foreign_dbid,
      fe.fepfcps pdb_foreign_ckp_scn,
      fe.fepfafn pdb_foreign_afn
      FROM x$kccfe fe, x$kccfn fn, x$kccfn fnaux, x$kcvfh fh,
          (SELECT fe.con_id,
                  MIN(decode(bitand(fe.festa, (4096+128)), 0, 0, fe.fecps))
                     pdbStopScn
             FROM x$kccfe fe
            WHERE fe.fetsn = 0
              AND fe.fedup != 0
              AND (fe.fefdb = 0 OR fe.feprls != 0)
            GROUP BY fe.con_id) fe1
      WHERE fe.fepax = fnaux.fnnum(+)
      AND   fn.fnfno=fe.fenum
      AND   fn.fnfno=fh.hxfil
      AND   fe.fefnh=fn.fnnum
      AND   fe.fedup<>0
      AND   fnaux.fntyp(+)=22
      AND   fn.fntyp=4
      AND   fn.fnnam IS NOT NULL
      AND   fe.fenum between low_fno and high_fno
      AND   fe.con_id = fe1.con_id
      ORDER BY fe.fenum;
 
  cursor tf(low_fno number, high_fno number) IS
    SELECT tfnum fileno,
      to_number(tf.tfcrc_scn) create_scn,
      to_date(tf.tfcrc_tim,'MM/DD/RR HH24:MI:SS',
              'NLS_CALENDAR=Gregorian') create_time,
      tf.tftsn tsnum,
      fn.fnnam fname,
      decode(nvl(fh.fhtmpfsz, 0), 0, tf.tfcsz, fh.fhtmpfsz) fsize,
      tf.tfbsz block_size,
      tf.tfrfn rfileno,                      -- this is relative file number
      decode(bitand(tf.tfsta, 16), 0, 'OFF', 'ON') autoextend,
      tf.tfmsz max_size,
      tf.tfnsz next_size,
      tf.con_id con_id
      FROM x$kcctf tf, x$kccfn fn, x$kcvfhtmp fh
      WHERE fn.fnfno=tf.tfnum
      AND   fn.fnfno=fh.htmpxfil
      AND   tf.tffnh=fn.fnnum
      AND   tf.tfdup!=0
      AND   fn.fntyp=7
      AND   bitand(tf.tfsta, 32)!=32
      AND   fn.fnnam IS NOT NULL
      AND   tf.tfnum between low_fno and high_fno
      ORDER BY tf.tfnum;
 
  cursor rt is
    select rtnum thread#, rtseq last_sequence#, to_number(rtenb) enable_scn,
           to_date(rtets,'MM/DD/RR HH24:MI:SS',
                         'NLS_CALENDAR=Gregorian') enable_time,
           to_number(rtdis) disable_scn,
           to_date(rtdit,'MM/DD/RR HH24:MI:SS',
                         'NLS_CALENDAR=Gregorian') disable_time,
           decode(bitand(rtsta,67), 0, 'D', 2, 'E', 3, 'E', 66, 'I') status
    from x$kccrt rt, x$kcctir tr
   where rtnlf      != 0                    -- groups is not zero
     and tr.inst_id  = rt.inst_id           -- join with x$kcctir
     and tirnum      = rtnum
     and rt.inst_id  = USERENV('Instance')  -- belongs to this instance
   order by rtnum;
 
--
--
--
--
  cursor orl is
    select thread#, group#, member fname, bytes, type
      from (select l.thread#, lf.group#, lf.member, l.bytes, 'ONLINE' type
              from v$log l, v$logfile lf
              where l.group# = lf.group#
                and l.thread# != 0          -- skip unassigned threads
                and nvl(lf.status, 'FOO') not in 
                    ('INVALID', 'DELETED', 'UNKNOWN')
              union all
              select l.thread#, lf.group#, lf.member, l.bytes, 'STANDBY' type
              from v$standby_log l, v$logfile lf
              where l.group# = lf.group#
                and l.thread# != 0          -- skip unassigned threads
                and nvl(lf.status, 'FOO') not in 
                    ('INVALID', 'DELETED', 'UNKNOWN'))
    order by nlssort(member, 'NLS_COMP=ANSI NLS_SORT=ASCII7');   -- bug 2107554
 
--
  cursor grsp is
    select rspname, rspfscn from_scn, rspscn to_scn, 
           to_date(rsprsptime, 'MM/DD/YYYY HH24:MI:SS', 
                               'NLS_CALENDAR=Gregorian') rsprsptime,
           to_date(rsptime, 'MM/DD/YYYY HH24:MI:SS', 
                            'NLS_CALENDAR=Gregorian') rsptime,
           decode(bitand(rspflags, 1), 1, 'YES', 'NO') guaranteed,
           resetlogs_change#, resetlogs_time, r.con_id con_id,
           decode(bitand(rspflags, 16), 16, 'YES', 'NO') clean
      from x$kccrsp r, v$database_incarnation
     where rspincarn = incarnation#
       and bitand(rspflags, 2) != 0
     order by r.con_id, nlssort(rspname, 'NLS_COMP=ANSI NLS_SORT=ASCII7');
 
  cursor nrsp(low number, high number) is
    select nrsname, nrsrid recid, nrsstm stamp, nrsincarn, nrsscn,
           to_date(nrsrsptime, 'MM/DD/YYYY HH24:MI:SS', 
                               'NLS_CALENDAR=Gregorian') nrsrsptime,
           to_date(nrstime, 'MM/DD/YYYY HH24:MI:SS', 
                            'NLS_CALENDAR=Gregorian') nrstime,
           decode(bitand(nrsflags, 2), 2, 0, 1) deleted,
           resetlogs_change# reset_scn,
           resetlogs_time reset_time,
           r.con_id con_id, 
           decode(bitand(nrsflags, 16), 16, 'YES', 'NO') clean
      from x$kccnrs r, v$database_incarnation d
     where r.nrsincarn = d.incarnation#
       and nrsrid between low and high
       and (nrsstm >= kccdivts OR nrsrid = high)
       and nrsstm >= resyncstamp
     order by nrsrid;
 
--
--
--
--
  cursor rlh(low_recid number, high_recid number) is
    select recid, stamp, thread#, sequence#, first_change# low_scn,
           first_time low_time, next_change# next_scn, resetlogs_change#,
           resetlogs_time
    from v$log_history
    where recid between low_recid and high_recid
          and resetlogs_time is not null                     -- bug 3125145 
          and stamp >= resyncstamp
    order by recid;
 
--
--
--
--
--
--
 
  cursor al(low_recid number, high_recid number, cf_type varchar2) is
    select recid, stamp, name, thread#, sequence#, resetlogs_change#,
           resetlogs_time, first_change#, first_time,
           next_change#, next_time, blocks, block_size,
           decode(archived, 'YES', 'Y', 'NO', 'N', 'UNKNOWN') archived,
           status, completion_time,
           decode(registrar, 'RFS', 'Y', 'SRMN', 'Y',
                             'RMAN', 'N', 'N') is_standby,
           dictionary_begin, dictionary_end,
           is_recovery_dest_file, compressed, creator, 
           decode(end_of_redo_type, 'TERMINAL', 'YES', 'NO') terminal
    from v$archived_log
    where recid between low_recid and high_recid
      and (stamp >= kccdivts OR recid = high_recid)
      and standby_dest = 'NO'
      and stamp >= resyncstamp
    order by recid;
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
  cursor offr(low_recid number, high_recid number) is
    select /*+ first_rows */ offr.recid, offr.stamp, offr.file#,
           to_number(fe.fecrc_scn) creation_change#,
           offr.offline_change#,offr.online_change#,offr.online_time, 
           offr.resetlogs_change#, offr.resetlogs_time
    from v$offline_range offr, x$kccfe fe
    where offr.file# = fe.fenum(+)
    and   offr.online_change# > to_number(fe.fecrc_scn(+))
    and   (offr.recid between low_recid and high_recid 
     or    fe.fecrc_scn is null)                               -- bug 3408643
    and   offr.resetlogs_time is not null                      -- bug 3125145
    and   fe.fedup != 0             -- we are not interested in dropped files
    and   stamp >= resyncstamp
    order by offr.recid;
 
  cursor bs(low_recid number, high_recid number) is
    select bs.recid, bs.stamp, bs.set_stamp, bs.set_count, bs.backup_type,
           bs.incremental_level,
           bs.pieces, start_time, completion_time, controlfile_included,
           bs.input_file_scan_only, keep_until,
           decode (bs.keep_options, 'LOGS'      , KEEP_LOGS
                               , 'NOLOGS'       , KEEP_NOLOGS
                               , 'BACKUP_LOGS'  , KEEP_CONSIST
                                                , 0) keep_options,
           bs.block_size, bs.multi_section, bs.guid,
           decode(bs.con_id, invalid_pdbid, 1, 0) dropped_pdb
    from v$backup_set bs
    where bs.recid between low_recid and high_recid
      and (bs.stamp >= kccdivts OR bs.recid = high_recid)
      and bs.stamp >= resyncstamp
      and bs.for_xtts != 'YES'
    order by bs.recid;
 
  cursor bp(low_recid number, high_recid number) is
    select bp.recid, bp.stamp, bp.set_stamp, bp.set_count, bp.piece#,
           bp.copy#, bp.tag,
           bp.device_type, bp.handle,
           bp.comments, bp.media, bp.media_pool, bp.concur,
           bp.start_time, bp.completion_time, bp.status, 
           bp.bytes, bp.is_recovery_dest_file, bp.rman_status_recid,
           bp.rman_status_stamp,
           bp.compressed, bp.encrypted, bp.backed_by_osb, bp.guid,
           decode(bp.con_id, invalid_pdbid, 1, 0) dropped_pdb
    from v$backup_piece bp
    where bp.recid between low_recid and high_recid
      and (bp.stamp >= kccdivts OR bp.recid = high_recid)
      and bp.stamp >= resyncstamp
      and bp.for_xtts != 'YES'
    order by bp.recid;
 
  cursor bdf(low_recid number, high_recid number) is
    select bdf.recid, bdf.stamp, bdf.set_stamp, bdf.set_count, bdf.file#,
           bdf.creation_change#, bdf.creation_time,
           bdf.resetlogs_change#, bdf.resetlogs_time, bdf.incremental_level,
           bdf.incremental_change#, bdf.checkpoint_change#,
           bdf.checkpoint_time, bdf.absolute_fuzzy_change#,
           bdf.datafile_blocks, bdf.blocks, bdf.block_size,
           bdf.oldest_offline_range, bdf.completion_time,
           bdf.controlfile_type, bdf.marked_corrupt, bdf.media_corrupt,
           bdf.logically_corrupt, bdf.blocks_read,
           bdf.used_change_tracking, bdf.used_optimization, bdf.foreign_dbid,
           bdf.plugged_readonly, bdf.plugin_change#,
           bdf.plugin_resetlogs_change#, bdf.plugin_resetlogs_time,
           bdf.section_size, bdf.guid, bdf.sparse_backup,
           decode(bdf.con_id, invalid_pdbid, 1, 0) dropped_pdb
    from v$backup_datafile bdf
    where bdf.recid between low_recid and high_recid
      and (bdf.stamp >= kccdivts OR bdf.recid = high_recid)
      and bdf.stamp >= resyncstamp
    order by bdf.recid;
 
--
  cursor bdfbs(low_recid number, high_recid number,
               low_bs_recid number, high_bs_recid number) is
    select bdf.recid, bdf.stamp, bdf.set_stamp, bdf.set_count, bdf.file#, 
           bdf.creation_change#, bdf.creation_time,
           bdf.resetlogs_change#, bdf.resetlogs_time, bdf.incremental_level, 
           bdf.incremental_change#, bdf.checkpoint_change#,
           bdf.checkpoint_time, bdf.absolute_fuzzy_change#,
           bdf.datafile_blocks, bdf.blocks, bdf.block_size,
           bdf.oldest_offline_range, bdf.completion_time, bdf.controlfile_type,
           bdf.marked_corrupt, bdf.media_corrupt, bdf.logically_corrupt,
           bdf.blocks_read, bdf.used_change_tracking, bdf.used_optimization,
           bdf.foreign_dbid, bdf.plugged_readonly, bdf.plugin_change#,
           bdf.plugin_resetlogs_change#, bdf.plugin_resetlogs_time,
           bdf.section_size, bdf.guid, bdf.sparse_backup,
           decode(bdf.con_id, invalid_pdbid, 1, 0) dropped_pdb
    from v$backup_datafile bdf, v$backup_set bs
    where bs.recid between low_bs_recid and high_bs_recid
          and (bs.stamp >= kccdivts OR bs.recid = high_bs_recid)
          and bs.stamp >= resyncstamp
          and bdf.set_stamp = bs.set_stamp
          and bdf.set_count = bs.set_count
          and bs.backup_type != 'L'  -- ignore archivelog backups
          and bdf.recid between low_recid and high_recid
    order by bdf.recid;
 
  cursor bsf(low_recid number, high_recid number) is
    select bsf.recid, bsf.stamp, bsf.set_stamp, bsf.set_count,
           bsf.modification_time, bsf.bytes, bsf.completion_time,
           bsf.db_unique_name, bsf.guid,
           decode(bsf.con_id, invalid_pdbid, 1, 0) dropped_pdb
    from v$backup_spfile bsf
    where bsf.recid between low_recid and high_recid
      and (bsf.stamp >= kccdivts OR bsf.recid = high_recid)
      and bsf.stamp >= resyncstamp
      and bsf.modification_time is not null
      and bsf.completion_time is not null
      and bsf.bytes is not null
    order by bsf.recid;
 
--
  cursor bsfbs(low_recid number, high_recid number,
               low_bs_recid number, high_bs_recid number) is
    select bsf.recid, bsf.stamp, bsf.set_stamp, bsf.set_count,
           bsf.modification_time, bsf.bytes,
           bsf.completion_time, bsf.db_unique_name, bsf.guid,
           decode(bsf.con_id, invalid_pdbid, 1, 0) dropped_pdb
    from v$backup_spfile bsf, v$backup_set bs
    where bs.recid between low_bs_recid and high_bs_recid
          and (bs.stamp >= kccdivts OR bs.recid = high_bs_recid)
          and bs.stamp >= resyncstamp
          and bsf.set_stamp = bs.set_stamp
          and bsf.set_count = bs.set_count
          and bsf.modification_time is not null
          and bsf.completion_time is not null
          and bsf.bytes is not null
          and bs.backup_type != 'L'  -- ignore archivelog backups
          and bsf.recid between low_recid and high_recid
    order by bsf.recid;
 
  cursor bcb(low_recid number, high_recid number) is
    select recid, stamp, set_stamp, set_count, piece#, file#, block#, blocks,
           corruption_change#, marked_corrupt, corruption_type
    from v$backup_corruption
    where recid between low_recid and high_recid
      and (stamp >= kccdivts OR recid = high_recid)
      and stamp >= resyncstamp
    order by recid;
 
  cursor brl(low_recid number, high_recid number) is
    select recid, stamp, set_stamp, set_count, thread#, sequence#,
           resetlogs_change#, resetlogs_time, first_change#, first_time,
           next_change#, next_time, blocks, block_size, terminal
    from v$backup_redolog
    where recid between low_recid and high_recid
      and (stamp >= kccdivts OR recid = high_recid)
      and stamp >= resyncstamp
    order by recid;
 
--
  cursor brlbs(low_recid number, high_recid number,
               low_bs_recid number, high_bs_recid number) is
    select brl.recid, brl.stamp, brl.set_stamp, brl.set_count,
           brl.thread#, brl.sequence#, brl.resetlogs_change#,
           brl.resetlogs_time, brl.first_change#, brl.first_time, 
           brl.next_change#, brl.next_time, brl.blocks, brl.block_size,
           brl.terminal
    from v$backup_redolog brl, v$backup_set bs
    where bs.recid between low_bs_recid and high_bs_recid
          and (bs.stamp >= kccdivts OR bs.recid = high_bs_recid)
          and bs.stamp >= resyncstamp
          and brl.set_stamp = bs.set_stamp
          and brl.set_count = bs.set_count
          and bs.backup_type = 'L'  -- only archivelog backups
          and brl.recid between low_recid and high_recid
    order by brl.recid;
 
  cursor cdf(low_recid number, high_recid number) is
    select dc.recid, dc.stamp, dc.name fname, dc.tag, dc.file#,
           dc.creation_change# create_scn,
           dc.creation_time create_time, dc.resetlogs_change# reset_scn,
           dc.resetlogs_time reset_time, dc.incremental_level incr_level,
           dc.checkpoint_change# ckp_scn,
           dc.checkpoint_time ckp_time,
           dc.absolute_fuzzy_change# abs_fuzzy_scn,
           dc.online_fuzzy,
           dc.backup_fuzzy,
           dc.recovery_fuzzy_change# rcv_fuzzy_scn,
           dc.recovery_fuzzy_time rcv_fuzzy_time,
           dc.blocks, dc.block_size, dc.oldest_offline_range,
           dc.status, dc.completion_time, dc.controlfile_type,
           dc.keep_until,
           decode (dc.keep_options, 'LOGS'         , KEEP_LOGS
                                  , 'NOLOGS'       , KEEP_NOLOGS
                                  , 'BACKUP_LOGS'  , KEEP_CONSIST
                                                   , 0) keep_options,
           dc.scanned,
           dc.is_recovery_dest_file, dc.rman_status_recid,
           dc.rman_status_stamp, dc.marked_corrupt, dc.foreign_dbid,
           dc.plugged_readonly, dc.plugin_change#,
           dc.plugin_resetlogs_change#, dc.plugin_resetlogs_time,
           dc.guid, dc.sparse_backup,
           decode(dc.con_id, invalid_pdbid, 1, 0) dropped_pdb
    from v$datafile_copy dc
    where dc.recid between low_recid and high_recid
      and (dc.stamp >= kccdivts OR dc.recid = high_recid)
      and dc.stamp >= resyncstamp
      and dc.converted_file != 'YES'
    order by dc.recid;
 
  cursor xdf(low_recid number, high_recid number) is
    select pdf.recid, pdf.stamp, pdf.tag, pdf.file#,
           pdf.creation_change# create_scn,
           pdf.creation_time create_time, pdf.resetlogs_change# reset_scn,
           pdf.resetlogs_time reset_time, pdf.incremental_level incr_level,
           pdf.checkpoint_change# ckp_scn,
           pdf.checkpoint_time ckp_time,
           pdf.absolute_fuzzy_change# abs_fuzzy_scn,
           pdf.online_fuzzy,
           pdf.backup_fuzzy,
           pdf.recovery_fuzzy_change# rcv_fuzzy_scn,
           pdf.recovery_fuzzy_time rcv_fuzzy_time,
           pdf.blocks, pdf.block_size, pdf.oldest_offline_range,
           pdf.device_type, pdf.handle, pdf.comments, pdf.media,
           pdf.media_pool, pdf.status, pdf.start_time,
           pdf.completion_time, pdf.controlfile_type,
           pdf.keep_until,
           decode (pdf.keep_options, 'LOGS'         , KEEP_LOGS
                                   , 'NOLOGS'       , KEEP_NOLOGS
                                   , 'BACKUP_LOGS'  , KEEP_CONSIST
                                                    , 0) keep_options,
           pdf.rman_status_recid, pdf.rman_status_stamp, pdf.foreign_dbid,
           pdf.plugged_readonly, pdf.plugin_change#,
           pdf.plugin_resetlogs_change#,
           pdf.plugin_resetlogs_time, pdf.guid,
           decode(pdf.con_id, invalid_pdbid, 1, 0) dropped_pdb
    from v$proxy_datafile pdf
    where pdf.recid between low_recid and high_recid
      and (pdf.stamp >= kccdivts OR pdf.recid = high_recid)
      and pdf.stamp >= resyncstamp
    order by pdf.recid;
 
  cursor xal(low_recid number, high_recid number) is
    select recid, stamp, tag, thread#, sequence#, resetlogs_change#,
           resetlogs_time, first_change#, first_time, next_change#,
           next_time, blocks, block_size, device_type, handle,
           comments, media, media_pool, status, start_time, completion_time,
           rman_status_recid, rman_status_stamp, terminal,
           keep_until,
           decode (keep_options, 'LOGS'         , KEEP_LOGS
                               , 'NOLOGS'       , KEEP_NOLOGS
                               , 'BACKUP_LOGS'  , KEEP_CONSIST
                                                , 0) keep_options
    from v$proxy_archivedlog
    where recid between low_recid and high_recid
      and (stamp >= kccdivts OR recid = high_recid)
      and stamp >= resyncstamp
    order by recid;
 
  cursor ccb(low_recid number, high_recid number) is
    select recid, stamp, copy_recid, copy_stamp, file#, block#, blocks,
           corruption_change#, marked_corrupt, corruption_type
    from v$copy_corruption
    where recid between low_recid and high_recid
      and (stamp >= kccdivts OR recid = high_recid)
      and stamp >= resyncstamp
    order by recid;
 
  cursor bcr(low_recid number, high_recid number) is
    select blkrid recid, blkstm stamp, blkfno file#, blkcrs create_scn,
           blkcrt create_time, blksblk block#, blktot blocks,
           blkscn corrupt_scn,
           decode(bitand(blktype, 255), 2, 'ALL ZERO', 3, 'FRACTURED',
                  4, 'CHECKSUM', 5, 'CORRUPT',
                  6, 'NOLOGGING', 7, 'LOGICAL', 'UNKNOWN') corruption_type
    from x$kccblkcor
    where blkrid between low_recid and high_recid
      and blkstm >= resyncstamp
      and bitand(blktype, 255) != 1 -- skip deleted records
      and bitand(blktype, 255) != 6 -- skip nologging records
    order by blkrid;
 
--
--
--
--
  cursor dl(low_recid number, high_recid number) is
    select /*+
             LEADING(x$kccdl@sel$3 df tf)
             USE_HASH(df)
             USE_HASH(tf)
             FULL(x$kccdl@sel$3)
             NO_SWAP_JOIN_INPUTS(df)
             NO_SWAP_JOIN_INPUTS(tf)
           */
           recid, stamp, type object_type, object_recid, object_stamp,
           object_data, type,
           (case when type = 'DATAFILE RENAME ON RESTORE' OR
                      type = 'PLUGGED READONLY RENAME' then
                      df.name
                 when type = 'TEMPFILE RENAME' then tf.name
            else to_char(null) end) object_fname,
           (case when type = 'DATAFILE RENAME ON RESTORE' then
                      df.creation_change#
                 when type = 'PLUGGED READONLY RENAME' then df.plugin_change#
                 when type = 'TEMPFILE RENAME' then tf.creation_change#
            else to_number(null) end) object_create_scn,
           set_stamp,
           set_count
    from v$deleted_object,
         (select /*+
                   LEADING(fe)
                   FULL(fe)
                   FULL(fn)
                   USE_HASH(fn)
                 */
                 fe.fenum                file#, 
                 to_number(fe.fecrc_scn) creation_change#,
                 fe.feplus               plugin_change#,
                 fn.fnnam                name
            from x$kccfe fe, x$kccfn fn
           where fe.fenum = fn.fnfno
             and fe.fefnh = fn.fnnum 
             and fe.fedup != 0
             and fn.fntyp = 4
             and fn.fnnam is not null
             and bitand(fn.fnflg, 4) != 4) df,
         (select /*+
                   LEADING(tf)
                   FULL(tf)
                   FULL(fn)
                   USE_HASH(fn)
                 */
                 tf.tfnum                file#,
                 to_number(tf.tfcrc_scn) creation_change#,
                 fn.fnnam                name
            from x$kcctf tf, x$kccfn fn
           where tf.tfnum = fn.fnfno
             and tf.tffnh = fn.fnnum
             and tf.tfdup != 0
             and bitand(tf.tfsta, 32) != 32 
             and fn.fntyp = 7
             and fn.fnnam is not null) tf
    where object_data = df.file#(+)
      and object_data = tf.file#(+)
      and recid between low_recid and high_recid
      and (stamp >= kccdivts OR recid = high_recid)
      and stamp >= resyncstamp
      and type != 'BACKUP RECORD CLEANUP'
      and type != 'PREVIOUS PIECE BACKUP SET'
    order by recid;
 
  cursor ic(low_recid number, high_recid number) is
     select resetlogs_change#, resetlogs_time,
            prior_resetlogs_change#, prior_resetlogs_time
     from v$database_incarnation
     where incarnation# between low_recid and high_recid
     order by resetlogs_change#;   -- resync parent first
 
  cursor pic(low_recid number, high_recid number, special_rec number) is
    select substr(pdb.pdbdbn, 1, pdb.pdbnln) name,
           pdb.pdbguid guid,
           pdb.con_id,
           to_number(pdb.pdbcrs) create_scn,
           pdbinc.pdbinc recid,
           decode(pdbinc.status, 1, 'YES', 'NO') curr_pdbinc,
           pdbinc.incscn inc_scn,
           pdbinc.brscn begin_reset_scn,
           pdbinc.brtime begin_reset_time,
           pdbinc.erscn end_reset_scn,
           pdbinc.dbrls db_reset_scn,
           pdbinc.dbrlc db_reset_time,
           pdbinc.pr_incscn pr_inc_scn,
           pdbinc.pr_erscn pr_end_reset_scn,
           pdbinc.pr_dbrls pr_db_reset_scn,
           pdbinc.pr_dbrlc pr_db_reset_time
      from x$kcpdbinc pdbinc,
           x$kccpdb pdb
     where pdbinc.con_id = pdb.con_id
       and (pdb.pdbsta != 3 OR bitand(pdb.pdbflg, 8192)=8192)
       and pdb.pdbcrs > 0
       and pdb.con_id > 1
       and ((pdbinc.pdbinc between low_recid and high_recid) OR
            (special_rec = 1 AND pdbinc.pdbinc = pdb.pdbinc))
   order by guid, begin_reset_scn, begin_reset_time,
            end_reset_scn, recid;
--
 
--
  cursor rsr(low_recid number, high_recid number) is
    select /*+ rule */ recid, stamp, parent_recid, parent_stamp, 
           session_recid, session_stamp, 
           row_level, row_type, command_id, operation, status, 
           mbytes_processed,
           start_time, end_time,
           input_bytes, output_bytes, optimized, object_type, 
           output_device_type,
           osb_allocated
    from v$rman_status
    where recid between low_recid and high_recid
      and (stamp >= kccdivts OR recid = high_recid)
      and (stamp >= resyncstamp OR stamp >= rsts)
--
--
      and ((resync_2_AMSchema = 0) or
           (resync_2_AMSchema = 1 and oam_tst_level = 0) or
           (resync_2_AMSchema = 1 and oam_tst_level >= 1 and 
            session_recid = rsid and session_stamp = rsts))
    order by recid;
 
  cursor rout(low_stamp number) is
    select recid, stamp, session_recid, session_stamp, 
           rman_status_recid, rman_status_stamp, output
    from v$rman_output
    where stamp >= low_stamp
      and stamp >= resyncstamp
--
--
      and ((resync_2_AMSchema = 0) or
           (resync_2_AMSchema = 1 and oam_tst_level = 0) or
           (resync_2_AMSchema = 1 and oam_tst_level >= 1 and 
            session_recid = rsid and session_stamp = rsts))
    order by session_recid, rman_status_recid;
 
--
  cursor duprec_c(low_stamp number, high_stamp number) is
    select recid, stamp, 'AL' type
      from v$archived_log
     where status != 'D'
       and standby_dest = 'NO'
       and archived = 'YES'
       and stamp > low_stamp
       and stamp <= high_stamp
    union all
    select recid, stamp, 'BP' type
      from v$backup_piece
     where status != 'D'
       and stamp > low_stamp
       and stamp <= high_stamp
    union all
    select recid, stamp, 'DC' type
      from v$datafile_copy
     where status != 'D'
       and stamp > low_stamp
       and stamp <= high_stamp
    order by stamp desc;
 
  cursor duprout_c(low_stamp number, high_stamp number) is
    select recid, stamp, session_recid, session_stamp, rman_status_recid, 
           rman_status_stamp
      from v$rman_output
       where stamp > low_stamp
         and stamp <= high_stamp
    order by stamp desc;
 
   procedure deb_sort_area(max_high IN number) is
   begin
--
      if debug_resync then
         deb('resync', 'sort_area_size='||sort_area_size, dbtype,
             rman_constant.LEVEL_HI);
         deb('resync', 'rec_size='||rec_size, dbtype,
             rman_constant.LEVEL_HI);
         deb('resync', 'rec_per_chunk='||rec_per_chunk, dbtype,
             rman_constant.LEVEL_HI);
         deb('resync', 'low= '||low||'    max_high='||max_high, dbtype,
             rman_constant.LEVEL_HI);
         deb('resync', 'total_recs='||total_recs, dbtype,
             rman_constant.LEVEL_HI);
      end if;
   end;
 
   function set_sort_area_size(newsize in number) return number is
      s          number;
      memmgmt    number;
      maxrecsize number;
      inststatus varchar2(12);
   begin
      select count(*) into memmgmt from v$parameter
       where name='workarea_size_policy' and upper(value)='AUTO';      
      krmicd.clearErrors;
      if memmgmt = 0 then    -- manual memory management
         deb('resync', 'manual memory management', dbtype);
         if newsize is not null then
            krmicd.execSql('alter session set sort_area_size=' ||
                           to_char(newsize));
            krmicd.clearErrors;
         end if;
         select to_number(value) into s from v$parameter
           where name='sort_area_size';
         if s < newsize then
            krmicd.writeMsg(1005, 'could not set sort_area_size to '||
              to_char(newsize) || ', using ' || to_char(s) || ' instead.');
         end if;
      else            -- automatic memory management
--
--
         select current_size into s from v$memory_dynamic_components
          where component='PGA Target' AND
          (CON_ID = 0 OR CON_ID = sys_context('userenv', 'con_id'));
         deb('resync', 
             'Instance using automatic memory management, PGA Target size ' ||
             s, dbtype);
--
--
         select status into inststatus from v$instance;
         if inststatus in ('MOUNTED', 'OPEN') then
            select max(record_size) into maxrecsize 
              from v$controlfile_record_section;
         else
--
            maxrecsize := 12288;
         end if;
         if s < maxrecsize then
            krmicd.writeMsg(1005, 
               'Cannot use PGA Target dynamic memory current_size ' || 
               to_char(s) || ', using ' || to_char(maxrecsize) || ' instead.');
            s := maxrecsize;
         end if;
      end if;
      return s;
   end set_sort_area_size;
   
   procedure display_uncatalog_bp(set_stamp IN number, set_count IN number) is
      
   cursor gethandle(setstamp number, setcount number)  is
       select bp.handle
         from v$backup_piece bp
        where bp.set_stamp = setstamp 
          and bp.set_count = setcount 
          and bp.status = 'A';
   begin
      for hdle in gethandle(set_stamp, set_count) loop
        krmicd.writeMsg(8192, hdle.handle);
      end loop;	  
   end display_uncatalog_bp;
 
--
--
   procedure resyncConf2Catalog(cf_type       IN varchar2,
                                current_cf    IN boolean) IS
 
--
   cursor conf_c is
       select conf#, name, value, value pvalue, instr(value, 'CONNECT') pos
       from v$rman_configuration;
 
   begin
 
      high_rm_recid := null;
      if current_cf then
         sys.dbms_backup_restore.getCkpt(getckptscn
                                 ,high_cp_recid
                                 ,high_rt_recid
                                 ,high_le_recid
                                 ,high_fe_recid
                                 ,high_fn_recid
                                 ,high_ts_recid
                                 ,high_r1_recid
                                 ,high_rm_recid
                                 ,high_lh_recid
                                 ,high_or_recid
                                 ,high_al_recid
                                 ,high_bs_recid
                                 ,high_bp_recid
                                 ,high_bf_recid
                                 ,high_bl_recid
                                 ,high_dc_recid
                                 ,high_fc_recid
                                 ,high_cc_recid
                                 ,high_dl_recid
                                 ,high_pc_recid
                                 ,high_bi_recid
                                 );
      end if;
 
--
--
      dbms_rcvcat.resetConfig2(TRUE, high_rm_recid);   -- wipe out nodespecific
      if cf_type in ('CURRENT', 'CREATED') then
         dbms_rcvcat.resetConfig2(FALSE);                   -- wipe out generic
      end if;
      
--
      for confrec in conf_c loop
        deb('resync', 'Resyncing configuration cf_type '|| cf_type, dbtype);
        deb('resync', 'Resyncing configuration '|| confrec.conf#, dbtype);
        if confrec.pos > 0 then
           confrec.pvalue :=
              substr(confrec.pvalue, 1, confrec.pos - 1) || 'CONNECT *******';
        end if;
        deb('resync', ' Name: ' || confrec.name ||
                      ' Value: '|| confrec.pvalue, dbtype);
--
        if krmicd.isNodeSpecific(confrec.name, confrec.value) then
            dbms_rcvcat.setConfig2(confrec.conf#, confrec.name, confrec.value, 
                                   TRUE);                     -- node specific
        elsif cf_type in ('CURRENT', 'CREATED') then
            dbms_rcvcat.setConfig2(confrec.conf#, confrec.name, confrec.value, 
                                   FALSE);                          -- generic
 
--
--
--
--
            if confrec.name = 'DB_UNIQUE_NAME' then
              dbms_rcvcat.resyncAddDBUname(confrec.value);
            end if;
        end if;
      end loop;
   end resyncConf2Catalog;
 
--
--
  procedure resyncConf2ControlFile(for_dbuname    in varchar2,
                                   source_cs      in varchar2) IS
     first boolean;
     conf_name    varchar2(65);
     conf_value   varchar2(1025);
     recid        number;
     null_retVal  varchar2(1);
  begin
 
--
     if for_dbuname is not null then
         null_retVal := 
           sys.dbms_backup_restore.remoteSQLExecute(
              source_dbuname => for_dbuname, 
              source_cs      => source_cs,
              stmt           => 
                 'begin ' ||
                 ' sys.dbms_backup_restore.resetConfig;' ||
                 'end;');
     else
        sys.dbms_backup_restore.resetConfig;
     end if;
     
     first := TRUE;
 
     deb('resync', 'Pushing configuration to controlfile');
 
--
     loop
        begin
           conf_name := NULL;
           conf_value := NULL;
           dbms_rcvcat.getConfig(recid, conf_name, conf_value, first);
 
           if for_dbuname is not null then
              null_retVal := 
                 sys.dbms_backup_restore.remoteSQLExecute(
                    source_dbuname => for_dbuname, 
                    source_cs      => source_cs,
                    stmt           => 
                      'declare ' ||
                      ' recid number; ' ||
                      'begin ' ||
                      ' recid := sys.dbms_backup_restore.setConfig (' ||
                        '''' || replace(conf_name,'''','''''') || ''',''' ||
                        replace(conf_value,'''','''''') || '''); '||
                      'end;');
           else
              recid := sys.dbms_backup_restore.setConfig (conf_name, 
                                                          conf_value);
           end if;
           deb('resync', 'Pushing conf name=' || conf_name ||
                         ';value=' || conf_value);
           first := FALSE;
        exception
           when no_data_found then
              krmicd.clearErrors;
              exit;
        end;
      end loop;
  end resyncConf2ControlFile;
 
  function getFlashbackTime(cftype varchar2) return date is
     flashback_on         number;
     fb_retention_target  number;
     fb_until_time        date := to_date(null);
     recovery_time        date;
  begin 
--
     select decode(flashback_on, 'YES', 1, 0)
       into flashback_on
       from v$database;
 
     if (flashback_on = 0) then
        return to_date(null);   -- flashback off
     end if;
 
--
     select di2fbret
       into fb_retention_target
       from x$kccdi2;
 
     if (nvl(fb_retention_target, 0) = 0) then
        return to_date(null);   -- no retention target set
     end if;
 
     deb('resync', 'fb_retention_target= ' || to_char(fb_retention_target),
         dbtype);
 
--
--
     if (fb_retention_target > 14 * 60 * 24) then
        select min(to_date(fleltim, 'MM DD YYYY HH24:MI:SS',
                           'NLS_CALENDAR=Gregorian'))
          into fb_until_time
          from x$kccfle;
 
          deb('resync', 'fb_until_time= ' ||
              nvl(to_char(fb_until_time), 'NULL'), dbtype);
 
--
--
--
--
          fb_retention_target := 14 * 60 * 24;
     end if;
 
--
     if (fb_until_time IS NULL) then
--
        select decode(cftype, 'STANDBY',
                      nvl(to_date(di2irt, 'MM DD YYYY HH24:MI:SS',
                          'NLS_CALENDAR=Gregorian'), sysdate), sysdate)
          into recovery_time
          from x$kccdi2;
 
        deb('resync', 'recovery_time= ' || to_char(recovery_time),
            dbtype);
 
--
        fb_until_time := recovery_time - fb_retention_target/(60 * 24);
 
        deb('resync', 'fb_until_time= ' || nvl(to_char(fb_until_time), 'NULL'),
            dbtype);
     end if;
 
     return fb_until_time;
  exception
     when no_data_found then
        return to_date(null);
     when others then
        raise;
  end;
 
--
  function is19871set return boolean is
     isset number;
  begin
     select count(*)
       into isset
       from v$parameter2
      where name = 'event'
        and lower(value) = '19871 trace name context forever, level 1';
     if isset > 0 then
        return true;
     else
        return false;
     end if;
  exception
     when others then
        return false;
  end;
 
--
  function is_19871_L0_set return boolean is
     isset number;
  begin
     select count(*)
       into isset
       from v$parameter2
      where name = 'event'
        and lower(value) = '19871 trace name context forever, level 0';
     if isset > 0 then
        return true;
     else
        return false;
     end if;
  exception
     when others then
        return false;
  end;
 
 
--
--
--
--
--
--
--
  function wasresynced(until_stamp  IN  number
                      ,high_stamp   IN  number) return number is
     nodups      number;                   -- number of duplicates
     high        number;
     low         number;
     resyncstamp number;
  begin
     high   := high_stamp;
     low    := until_stamp;
     nodups := 0;
     resyncstamp := 0;
     deb('resync', 'wasresynced high_stamp=' || high_stamp ||
         ' high_date=' || stamp2date(high_stamp), dbtype);
 
     for duprec in duprec_c(low, high) loop
        if (dbms_rcvcat.isDuplicateRecord(recid    => duprec.recid
                                         ,stamp    => duprec.stamp
                                         ,type     => duprec.type)) then
           if (resyncstamp = 0) then
              resyncstamp := duprec.stamp;
           end if;
 
           nodups := nodups + 1;
           if (nodups >= maxdups) then
              deb('resync', 'wasresynced resyncstamp=' || resyncstamp ||
                  ' resyncdate=' || stamp2date(resyncstamp), dbtype);
              return resyncstamp;
           end if;
        else             -- couldn't find 16 consecutive duplicate records.
           deb('resync', 'wasresynced could not find record recid=' ||
               duprec.recid || ' stamp=' || duprec.stamp || ' type=' ||
               duprec.type || ' maxdups=' || nodups, dbtype);
           return 0;
        end if;
     end loop;
 
--
--
      deb('resync', 'timestamp range not enough - nodups=' || nodups, dbtype);
      return -1;
   end;
 
   function routresynced(until_stamp  IN  number
                        ,high_stamp   IN  number) return number is
     nodups      number;                   -- number of duplicates
     high        number;
     low         number;
     resyncstamp number;
   begin
     high   := high_stamp;
     low    := until_stamp;
     nodups := 0;
     resyncstamp := 0;
     deb('resync', 'routresynced high_stamp=' || high_stamp ||
         ' high_date=' || stamp2date(high_stamp), dbtype);
 
     for duprec in duprout_c(low, high) loop
        if (dbms_rcvcat.isRoutDuplicateRecord(
               recid             => duprec.recid
              ,stamp             => duprec.stamp
              ,session_recid     => duprec.session_recid
              ,session_stamp     => duprec.session_stamp
              ,rman_status_recid => duprec.rman_status_recid
              ,rman_status_stamp => duprec.rman_status_stamp)) then
 
           if (resyncstamp = 0) then
              resyncstamp := duprec.stamp;
           end if;
 
           nodups := nodups + 1;
           if (nodups >= maxdups) then
              deb('resync', 'routresynced resyncstamp=' || resyncstamp ||
                  ' resyncdate=' || stamp2date(resyncstamp), dbtype);
              return resyncstamp;
           end if;
        else             -- couldn't find 16 consecutive duplicate records.
           deb('resync', 'routresynced could not find record recid=' ||
               duprec.recid || ' stamp=' || duprec.stamp || 
               ' maxdups=' || nodups, dbtype);
           return 0;
        end if;
     end loop;
 
--
--
      deb('resync', 'timestamp range not enough - nodups=' || nodups, dbtype);
      return -1;
   end;
 
   procedure resyncTempfiles is
   begin
 
     select record_size, last_recid into rec_size, high_tf_recid
       from v$controlfile_record_section
      where type = 'TEMPORARY FILENAME';
 
     deb('resync', 'high_tf_recid= '|| high_tf_recid, dbtype);
 
     if dbms_rcvcat.beginTempFileResync(high_tf_recid) THEN
        rec_size := 1024 + rec_size;  -- kccfn + kcctf
        rec_per_chunk := floor(sort_area_size / rec_size);
 
--
        select nvl(max(tfnum), 0)
          into high_recno
          from x$kcctf
         where tfdup != 0;
 
        found := 0;
        low := 1;
        deb_sort_area(0);
        loop
           high := low + rec_per_chunk - 1;
           for tfrec in tf(low, high) LOOP
              deb('resync', 'Resyncing tempfile '|| tfrec.fname, dbtype);
              IF tfrec.fsize = 0 THEN
--
--
                 tfrec.fsize := NULL;
              END IF;
 
              deb('resync', 'Calling checkTempFile for fileno '||
                  tfrec.fileno||' size '||tfrec.fsize, dbtype);
              dbms_rcvcat.checkTempFile(
                  tfrec.fileno, tfrec.fname, tfrec.create_scn,
                  tfrec.create_time, tfrec.fsize, tfrec.block_size,
                  tfrec.tsnum, tfrec.rfileno, tfrec.autoextend,
                  tfrec.max_size, tfrec.next_size, tfrec.con_id,
                  pdb_dict_check.exists(tfrec.con_id));
              found := found + 1;
           end loop;
 
           IF (high >= high_recno) THEN
              deb('resync', 'Processed '||found|| ' tempfiles.  Done', dbtype);
              goto all_tf_found;
           ELSE
              low := high + 1;
           END IF;
        end loop;
 
        <<all_tf_found>>
 
        dbms_rcvcat.endTempFileResync;
     end if;
   end;
 
   procedure resyncPdbInc is
      is_cdb  number; -- is a CDB?
   begin
      select decode(cdb, 'YES', 1, 0) into is_cdb from v$database;
      if (is_cdb = 0) then
         return;
      end if;
 
      recid := dbms_rcvcat.beginPluggableDbincResync; 
 
--
      for picrec in pic(0, 0, 1) loop
         deb('resync', 'Calling checkPluggableDbinc for fab/special record'||
             ' pdbname= ' || picrec.name ||
             ' guid=' || picrec.guid ||
             ' con_id=' || picrec.con_id||
             ' recid=' || picrec.recid ||
             ' curr=' || picrec.curr_pdbinc ||
             ' inc_scn=' || picrec.inc_scn ||
             ' end_reset_scn=' || picrec.end_reset_scn ||
             ' db_reset_scn=' || picrec.db_reset_scn ||
             ' pr_inc_scn=' || nvl(picrec.pr_inc_scn, '') ||
             ' pr_end_reset_scn=' || nvl(picrec.pr_end_reset_scn, '') ||
             ' pr_db_reset_scn=' || picrec.pr_db_reset_scn, dbtype);
         dbms_rcvcat.checkPluggableDbinc(
            picrec.recid, picrec.guid,
            picrec.curr_pdbinc, picrec.inc_scn,
            picrec.begin_reset_scn, picrec.begin_reset_time,
            picrec.end_reset_scn, picrec.db_reset_scn, picrec.db_reset_time,
            picrec.pr_inc_scn, picrec.pr_end_reset_scn,
            picrec.pr_db_reset_scn, picrec.pr_db_reset_time, FALSE);
      end loop;
 
      select record_size, last_recid into rec_size, high_pic_recid
        from v$controlfile_record_section
        where type='PDBINC RECORD';
 
      deb('resync', 'Plugggable inc last recid ' || recid || '; high ' ||
          high_pic_recid);
--
      recid := dbms_rcvcat.beginPluggableDbincResync; 
      if (high_pic_recid > recid) then
         high := recid;
         low := recid + 1;
         rec_per_chunk := floor(sort_area_size / rec_size);
         total_recs := high_pic_recid - low + 1;
         deb_sort_area(high_pic_recid);
         while (high < high_pic_recid) loop
            high := least(low + rec_per_chunk - 1, high_pic_recid);
            for picrec in pic(low, high, 0) loop
               deb('resync', 'Calling checkPluggableDbinc for' ||
                   ' pdbname= ' || picrec.name ||
                   ' guid=' || picrec.guid ||
                   ' con_id=' || picrec.con_id ||
                   ' recid=' || picrec.recid ||
                   ' curr=' || picrec.curr_pdbinc ||
                   ' inc_scn=' || picrec.inc_scn ||
                   ' end_reset_scn=' || picrec.end_reset_scn ||
                   ' db_reset_scn=' || picrec.db_reset_scn ||
                   ' pr_inc_scn=' || nvl(picrec.pr_inc_scn, '') ||
                   ' pr_end_reset_scn=' || nvl(picrec.pr_end_reset_scn, '') ||
                   ' pr_db_reset_scn=' || picrec.pr_db_reset_scn, dbtype);
               dbms_rcvcat.checkPluggableDbinc(
                  picrec.recid, picrec.guid,
                  picrec.curr_pdbinc, picrec.inc_scn,
                  picrec.begin_reset_scn, picrec.begin_reset_time,
                  picrec.end_reset_scn, picrec.db_reset_scn,
                  picrec.db_reset_time, picrec.pr_inc_scn,
                  picrec.pr_end_reset_scn, picrec.pr_db_reset_scn,
                  picrec.pr_db_reset_time, TRUE);
            end loop;
            low := high + 1;
         end loop;
      end if;
 
      dbms_rcvcat.endPluggableDbincResync(high_pic_recid);
   end;
begin
  entered('resync');
 
  debug_resync := FALSE;
 
  &resync_flag&
 
  deb('resync', 'resyncing to AM is =' || resync_2_AMSchema, dbtype);
 
--
--
--
--
--
--
  if not implicit then
     dbms_rcvcat.lockForCkpt;
  end if;
 
  <<restart_resync>> -- come back here for automatic resync from primary
 
--
--
  if (releasecf) then
    deb('resync', 'Release earlier held snapshot enqueue', dbtype);
    sys.dbms_backup_restore.cfileUseCurrent;
    releasecf := FALSE;
  end if;
 
  if auto_prim_resync then
     select primary_db_unique_name into for_dbuname from v$database;
  end if;
 
  if callSetDatabase then
     select dbid, name, dbinc.resetlogs_change#, dbinc.resetlogs_time,
            controlfile_type, upper(db_unique_name)
       into for_db_id, db_name, reset_scn, reset_time,
            cf_type, curr_dbuname
     from v$database, v$database_incarnation dbinc
     where dbinc.status = 'CURRENT';
 
     if cf_type = 'BACKUP' then
        deb('resync', 'remote site is primary', dbtype);
        cf_type := 'CURRENT';
--
--
        ub4_cf_type := 1;
     else
        deb('resync', 'remote site is standby', dbtype);
--
--
        ub4_cf_type := 4;
     end if;
 
   <<resync_after_incarnation>> -- come here after registering new incarnation
   begin
     dbms_rcvcat.setDatabase(db_name        => db_name,
                       reset_scn      => reset_scn,
                       reset_time     => reset_time,
                       db_id          => db_id,
                       db_unique_name => curr_dbuname,
                       dummy_instance => FALSE,
                       cf_type        => ub4_cf_type,
                       site_aware     => TRUE);
 
--
--
--
     krmicd.checksetDatabase;
     callSetDatabase :=  FALSE;
 
   exception
--
--
     when DATABASE_INCARNATION_NOT_FOUND then
       select dbid, name, resetlogs_change#, resetlogs_time
         into   db_id, db_name, reset_scn, reset_time
         from v$database;
       select diprs, to_date(diprc, 'MM/DD/RR HH24:MI:SS', 
				    'NLS_CALENDAR=Gregorian')
         into parent_reset_scn, parent_reset_time
         from x$kccdi;
       begin
         dbms_rcvcat.resetDatabase(db_id             => db_id,
                                   db_name           => db_name,
                                   reset_scn         => reset_scn,
                                   reset_time        => reset_time,
                                   parent_reset_scn  => parent_reset_scn,
                                   parent_reset_time => parent_reset_time);
        krmicd.writeMsg(8005);
        goto resync_after_incarnation;
 
       exception
        when incarnation_already_registered then
          deb('resync', 'database incarnation already known',dbtype);
          goto resync_after_incarnation;
       end;
     when others then
       raise;
   end;
  end if;
 
 
 
  sort_area_size := set_sort_area_size(null);
  if sort_area_size < sort_area_size_init then
    sort_area_size := set_sort_area_size(sort_area_size_init);
  end if;
 
  deb('resync', 'Starting resync', dbtype);
  
--
  if for_dbuname is not null then
     krmicd.writeMsg(6615, for_dbuname);
  end if;
 
  deb('resync', 'cfname is '|| cfname, dbtype);
 
  if cfname is null then
    select status into mount_status from v$instance;
    if mount_status not in ('MOUNTED', 'OPEN') then
      if full_resync then
        krmicd.writeMsg(8034);
      else
        krmicd.writeMsg(8035);
      end if;
      return;
    end if;
  else
    mount_status := 'BACKUP';                   -- resync from backup cf
  end if;
 
--
--
--
  if for_dbuname is null then
     select startup_time into inst_startup_time from v$instance;
     inst_startup_stamp := date2stamp(inst_startup_time);
  end if;
 
  <<snapshot>>  -- retry on makeAndUseSnapshot failure
 
  begin
--
--
 
    if (full_resync) then
      deb('resync', 'full_resync value is true', dbtype);
    else
      deb('resync', 'full_resync value is false', dbtype);
    end if;
 
    if (full_resync or for_dbuname is not null) then
      if (cfname is null) then
 
--
--
        select controlfile_type, dbid into cf_type, db_id from v$database;
 
--
--
--
--
--
 
--
        if for_dbuname is null then
           sys.dbms_backup_restore.cfileMakeAndUseSnapshot(
                   isstby    => FALSE, 
                   source_dbuname => NULL,
                   source_cs  => NULL, 
                   dest_cs => NULL,
                   for_resync => TRUE);
 
        else
--
--
           deb('resync', 'creating remote cf snapshot for '|| 
               for_dbuname,dbtype);
           deb('resync', 'source connid '|| source_cs, dbtype);
           deb('resync', 'dest connid '|| dest_cs, dbtype);
 
--
--
--
--
           low_run_recid := sys.dbms_backup_restore.remoteSQLExecute(
                               source_dbuname => for_dbuname,
                               source_cs      => source_cs,
                               stmt           =>
                                'select nvl(min(recid), -1) '   ||
                                'from gv$rman_status_current '  ||
                                'where status like ''%RUNNING%''');
 
           deb('resync', 'lowest recid for running job at primary ' || 
               low_run_recid, dbtype );
 
           if source_cs is null then
              source_cs := 
                 sys.dbms_backup_restore.get_connect_identifier
                    (dbuname => for_dbuname);
              if source_cs is null then
                 krmicd.SignalErrMsg(6613, for_dbuname);
                 return;
              end if;
              deb('resync', 'got source connid '|| source_cs, dbtype);
           end if;
           if dest_cs is null then
              select db_unique_name into ldb_unique_name from v$database;
--
--
              null_retVal := sys.dbms_backup_restore.remoteSQLExecute(
                     source_dbuname => for_dbuname, 
                     source_cs      => source_cs,
                     stmt           => 
                            'declare ' ||
                            '   n varchar2(200);' ||
                            'begin ' ||
                            ' n := sys.dbms_backup_restore.getCkptSCN;' ||
                            'end;');
 
              dest_cs := sys.dbms_backup_restore.remoteSQLExecute(
                         source_dbuname => for_dbuname,
                         source_cs      => source_cs,
                         stmt           =>
                          'select ' ||
                          '  sys.dbms_backup_restore.get_connect_identifier('||
                          '     dbuname=>''' || ldb_unique_name || ''')' ||
                          ' from dual');
              
              if dest_cs is null then
                 krmicd.SignalErrMsg(6613, ldb_unique_name);
                 return;
              end if;
              deb('resync', 'got dest connid '|| dest_cs, dbtype);
           end if;
 
           sys.dbms_backup_restore.cfileMakeAndUseSnapshot(
                   isstby    => FALSE, 
                   source_dbuname => for_dbuname,
                   source_cs  => source_cs, 
                   dest_cs => dest_cs,
                   for_resync => TRUE);
 
--
--
           select dbid, name, dbinc.resetlogs_change#, dbinc.resetlogs_time,
                  controlfile_type, upper(db_unique_name)
              into  for_db_id, db_name, reset_scn, reset_time,
                  cf_type, ldb_unique_name
           from v$database db, v$database_incarnation dbinc
           where dbinc.status = 'CURRENT';
 
--
           if db_id <> for_db_id then
              raise db_id_mismatch;
           end if;
 
--
--
--
--
--
--
--
           if lower(ldb_unique_name) <> lower(for_dbuname) then
             krmicd.writeMsg(6538, for_dbuname, ldb_unique_name);
             raise dbuname_mismatch;
           end if;
 
           mount_status := sys.dbms_backup_restore.remoteSQLExecute(
                               source_dbuname => for_dbuname, 
                               source_cs      => source_cs,
                               stmt           => 
                                    'select status from v$instance');
           deb('resync', 'remote site mount_status=' || mount_status, dbtype);
 
--
--
           if cf_type = 'BACKUP' then
              deb('resync', 'remote site is primary', dbtype);
              cf_type := 'CURRENT';
--
--
              ub4_cf_type := 1;
           else
              deb('resync', 'remote site is standby', dbtype);
--
--
              ub4_cf_type := 4;
           end if;
 
--
--
           begin
              dbms_rcvcat.setDatabase(db_name        => db_name,
                                      reset_scn      => reset_scn,
                                      reset_time     => reset_time,
                                      db_id          => db_id,
                                      db_unique_name => for_dbuname,
                                      dummy_instance => FALSE,
                                      cf_type        => ub4_cf_type,
                                      site_aware     => TRUE);
--
--
--
              krmicd.checksetDatabase;
           exception
--
--
              when others then
                 raise;
           end;
        end if;
      else
--
        sys.dbms_backup_restore.cfileUseCopy(cfname);
      end if;
      releasecf := TRUE;
    end if;
  exception
 
    when sys.dbms_backup_restore.snapshot_enqueue_busy then
--
--
--
--
      if busy_retries = 180 then
         krmicd.writeMsg(20029, 'cannot make a snapshot controlfile');
         raise;
      end if;
 
      busy_retries := busy_retries + 1;
--
      if (mod(busy_retries, 15) = 0) then
         krmicd.writeMsg(8512);
      end if;
      krmicd.sleep(20);
      krmicd.clearErrors;
      goto snapshot;
 
  end;  -- snapshot controlfile stuff
 
--
--
--
  pdb_dict_check.delete;
  for pdbrec in pdb_dict_check_c loop
     if full_resync or auto_prim_resync then
        pdb_dict_check(pdbrec.con_id) := 1;
        if auto_prim_resync then
           pdb_dict_check_sby(pdbrec.con_id) := 1;
           krmicd.writeMsg(20073, pdbrec.name);
        end if;
        deb('resync', 'con_id=' || pdbrec.con_id || 
            ' needs dictionary check', dbtype);
     end if;
  end loop;
 
--
--
--
 
  if (cf_type is null) then                  -- cf_type not filled up yet
    select controlfile_type into cf_type from v$database;
    deb('resync', 'set cf_type to '|| cf_type);
  end if;
 
  if cf_type = 'STANDBY' then
--
--
--
--
    deb('resync', 'Resyncing from a standby controlfile', dbtype);
    full_resync := FALSE;
  elsif cf_type = 'CURRENT' then
    deb('resync', 'Resyncing from a current controlfile', dbtype);
  elsif cf_type = 'BACKUP' then
    deb('resync', 'Resyncing from a backup controlfile', dbtype);
    full_resync := FALSE;
  elsif cf_type = 'FARSYNC' then
    deb('resync', 'Resyncing from a farsync controlfile', dbtype);
    full_resync := FALSE;
  elsif cf_type = 'CREATED' then
    deb('resync', 'Resyncing from a created controlfile', dbtype);
    full_resync := FALSE;
  else
    if full_resync then
      krmicd.writeMsg(8040);
    else
      krmicd.writeMsg(8041);
    end if;
    ignore_resync_err := TRUE;
    raise resync_not_needed;
  end if;
 
  <<retry>>  -- retry on inconsistent read or sort_area_size overflow
 
begin
 
--
--
--
--
--
  if (sort_retries = 0 AND read_retries = 0) then
    select dbid, name, dbinc.resetlogs_change#, dbinc.prior_resetlogs_change#,
         dbinc.resetlogs_time, dbinc.prior_resetlogs_time, controlfile_created,
         controlfile_sequence#, controlfile_change#, controlfile_time,
         version_time
    into   db_id, db_name, reset_scn, prior_reset_scn, reset_time,
         prior_reset_time, cf_create_time, ckp_cf_seq,
         ckp_scn, ckp_time, cf_version
    from v$database db, v$database_incarnation dbinc 
    where dbinc.incarnation# = db.recovery_target_incarnation#;
 
--
    select db_unique_name into ldb_unique_name from v$database;
 
    kccdivts := date2stamp(cf_version);   -- used by circular record queries
 
    deb('resync', 'kccdivts= '||to_char(kccdivts), dbtype);
    if for_dbuname is not null then
--
--
       null_retVal := sys.dbms_backup_restore.remoteSQLExecute(
              source_dbuname => for_dbuname, 
              source_cs      => source_cs,
              stmt           => 
                     'declare ' ||
                     '   n varchar2(200);' ||
                     'begin ' ||
                     ' n := sys.dbms_backup_restore.getCkptSCN;' ||
                     'end;');
       getckptscn := to_number(
              sys.dbms_backup_restore.remoteSQLExecute(
              source_dbuname => for_dbuname, 
              source_cs      => source_cs,
              stmt           => 
                  'select sys.dbms_backup_restore.getCkptSCN from dual'));
    else
       getckptscn := sys.dbms_backup_restore.getCkptSCN;
    end if;
 
--
--
    select last_recid into high_cp_recid
       from v$controlfile_record_section
      where type = 'CKPT PROGRESS';
    select last_recid into high_rt_recid
       from v$controlfile_record_section
      where type = 'REDO THREAD';
    select last_recid into high_le_recid
       from v$controlfile_record_section
      where type = 'REDO LOG';
    select last_recid into high_fe_recid
       from v$controlfile_record_section
      where type = 'DATAFILE';
    select last_recid into high_fn_recid
       from v$controlfile_record_section
      where type = 'FILENAME';
    select last_recid into high_ts_recid
       from v$controlfile_record_section
      where type = 'TABLESPACE';
    select last_recid into high_r1_recid
       from v$controlfile_record_section
      where type = 'TEMPORARY FILENAME';
    select last_recid into high_rm_recid
       from v$controlfile_record_section
      where type = 'RMAN CONFIGURATION';
    select last_recid into high_lh_recid
       from v$controlfile_record_section
      where type = 'LOG HISTORY';
    select last_recid into high_or_recid
       from v$controlfile_record_section
      where type = 'OFFLINE RANGE';
    select last_recid into high_al_recid
       from v$controlfile_record_section
      where type = 'ARCHIVED LOG';
    select last_recid into high_bs_recid
       from v$controlfile_record_section
      where type = 'BACKUP SET';
    select last_recid into high_bp_recid
       from v$controlfile_record_section
      where type = 'BACKUP PIECE';
    select last_recid into high_bf_recid
       from v$controlfile_record_section
      where type = 'BACKUP DATAFILE';
    select last_recid into high_bl_recid
       from v$controlfile_record_section
      where type = 'BACKUP REDOLOG';
    select last_recid into high_dc_recid
       from v$controlfile_record_section
      where type = 'DATAFILE COPY';
    select last_recid into high_fc_recid
       from v$controlfile_record_section
      where type = 'BACKUP CORRUPTION';
    select last_recid into high_cc_recid
       from v$controlfile_record_section
      where type = 'COPY CORRUPTION';
    select last_recid into high_dl_recid
       from v$controlfile_record_section
      where type = 'DELETED OBJECT';
    select last_recid into high_pc_recid
       from v$controlfile_record_section
      where type = 'PROXY COPY';
    select last_recid into high_bi_recid
       from v$controlfile_record_section
      where type = 'BACKUP SPFILE';
 
    if debug_resync then
       deb('resync', 'high_cp_recid= '||high_cp_recid, dbtype);
       deb('resync', 'high_rt_recid= '||high_rt_recid, dbtype);
       deb('resync', 'high_le_recid= '||high_le_recid, dbtype);
       deb('resync', 'high_fe_recid= '||high_fe_recid, dbtype);
       deb('resync', 'high_fn_recid= '||high_fn_recid, dbtype);
       deb('resync', 'high_ts_recid= '||high_ts_recid, dbtype);
       deb('resync', 'high_r1_recid= '||high_r1_recid, dbtype);
       deb('resync', 'high_rm_recid= '||high_rm_recid, dbtype);
       deb('resync', 'high_lh_recid= '||high_lh_recid, dbtype);
       deb('resync', 'high_or_recid= '||high_or_recid, dbtype);
       deb('resync', 'high_al_recid= '||high_al_recid, dbtype);
       deb('resync', 'high_bs_recid= '||high_bs_recid, dbtype);
       deb('resync', 'high_bp_recid= '||high_bp_recid, dbtype);
       deb('resync', 'high_bf_recid= '||high_bf_recid, dbtype);
       deb('resync', 'high_bl_recid= '||high_bl_recid, dbtype);
       deb('resync', 'high_dc_recid= '||high_dc_recid, dbtype);
       deb('resync', 'high_fc_recid= '||high_fc_recid, dbtype);
       deb('resync', 'high_cc_recid= '||high_cc_recid, dbtype);
       deb('resync', 'high_dl_recid= '||high_dl_recid, dbtype);
       deb('resync', 'high_pc_recid= '||high_pc_recid, dbtype);
       deb('resync', 'high_bi_recid= '||high_bi_recid, dbtype);
    end if;
 
    if (not full_resync) then
      ckp_scn := getckptscn;
      ckp_time := NULL;
    end if;
 
    begin
      if (full_resync or auto_prim_resync) then
        dbms_rcvcat.beginCkpt
        (ckp_scn, ckp_cf_seq, cf_version, ckp_time, 'FULL', mount_status,
         high_fe_recid, cf_type);
      else
        dbms_rcvcat.beginCkpt
          (ckp_scn, ckp_cf_seq, cf_version, ckp_time, 'PARTIAL',
           mount_status, high_fe_recid, cf_type);
      end if;
    exception
      when resync_not_needed then
         ignore_resync_err := implicit;
         raise;
    end;
 
--
--
--
--
--
    if (dbms_rcvcat.lastFullCkpt is null) then
       deb('resync', 'first resync after open resetlogs of root', dbtype);
       deb('resync', 'ignore pdb dictionary check bit', dbtype);
       pdb_dict_check.delete;
    end if;
 
    if (full_resync) then
       if implicit then
          resync_reason := dbms_rcvcat.getReason;
          if resync_reason = dbms_rcvcat.RESYNC_REASON_NOACTION then
             fullResyncBaseMsg := 8002;
          elsif resync_reason = dbms_rcvcat.RESYNC_REASON_TS then
             fullResyncBaseMsg := 8200;
          elsif resync_reason = dbms_rcvcat.RESYNC_REASON_DF then
             fullResyncBaseMsg := 8205;
          elsif resync_reason = dbms_rcvcat.RESYNC_REASON_TF then
             fullResyncBaseMsg := 8210;
          elsif resync_reason = dbms_rcvcat.RESYNC_REASON_THR then
             fullResyncBaseMsg := 8215;
          elsif resync_reason = dbms_rcvcat.RESYNC_REASON_ORL then
             fullResyncBaseMsg := 8220;
          elsif resync_reason = dbms_rcvcat.RESYNC_REASON_RESET then
             fullResyncBaseMsg := 8224;
          elsif resync_reason = dbms_rcvcat.RESYNC_REASON_CONF then
             fullResyncBaseMsg := 8225;
          elsif resync_reason = dbms_rcvcat.RESYNC_REASON_RSL then
             fullResyncBaseMsg := 8226;
          elsif resync_reason = dbms_rcvcat.RESYNC_REASON_CF then
             fullResyncBaseMsg := 8227;
          elsif resync_reason = dbms_rcvcat.RESYNC_REASON_INC then
             fullResyncBaseMsg := 8228;
          elsif resync_reason = dbms_rcvcat.RESYNC_REASON_PDB then
             fullResyncBaseMsg := 8237;
          else
             fullResyncBaseMsg := 8229;
          end if;
          if not auto_prim_resync then
             krmicd.writeMsg(fullResyncBaseMsg);
          end if;
       else
          if not auto_prim_resync then
             krmicd.writeMsg(8002);      -- full resync
          end if;
       end if;
    else
       if not implicit and not auto_prim_resync then
          krmicd.writeMsg(8243);
       end if;
    end if;
  end if;
 
--
  if (for_dbuname IS NOT NULL) then
     tmzone := sys.dbms_backup_restore.remoteSQLExecute(
                  source_dbuname => for_dbuname, 
                  source_cs      => source_cs,
                  stmt           => 
                       'select TO_CHAR(systimestamp, ''TZR'') from dual');
  else
     select TO_CHAR(systimestamp, 'TZR') into tmzone from x$dual;
  end if;
  select db_unique_name into ldb_unique_name from v$database;
  deb('resync','Instance '||ldb_unique_name|| 
                          ' has timezone' || tmzone, dbtype);
  dbms_rcvcat.addTimeZone(ldb_unique_name, tmzone, 'R');
 
  if (full_resync or auto_prim_resync) then
     select last_recid into high_pdb_recid
       from v$controlfile_record_section
       where type = 'PDB RECORD';
 
     deb('resync', 'high_pdb_recid = ' || high_pdb_recid, dbtype);
     if dbms_rcvcat.beginPluggableDBResync(high_pdb_recid) then
        for pdbrec in pdb loop
           deb('resync', 'Calling checkPluggableDB name=' ||
               pdbrec.name || ' dbid=' || pdbrec.dbid ||
               ' con_id=' || pdbrec.con_id, dbtype);
           dbms_rcvcat.checkPluggableDB(
              pdbrec.name, pdbrec.con_id, pdbrec.dbid, pdbrec.create_scn,
              pdbrec.guid, pdbrec.noBackup);
        end loop;
        dbms_rcvcat.endPluggableDBResync;
     end if;
 
--
--
--
--
     resyncPdbInc;
 
     select last_recid into high_tf_recid
       from v$controlfile_record_section
      where type = 'TEMPORARY FILENAME';
 
--
--
--
--
--
--
--
--
--
     if (mount_status = 'OPEN' OR
         dbms_rcvcat.tempFileToResync(high_tf_recid)) then
        force := TRUE;                    -- force tablespace resync
        deb('resync', 'Forcing tablespace resync, for '||
            nvl(high_ts_recid, 0)||' tablespaces', dbtype);
     else
        force := FALSE;
        deb('resync', 'Checking if tablespace resync is needed, have '||
            nvl(high_ts_recid, 0)||' tablespaces', dbtype);
     end if;
     krmicd.clearErrors;
 
     if dbms_rcvcat.beginTableSpaceResync(high_ts_recid, force) then
        for tsrec in ts loop
           if (mount_status = 'OPEN') then
           begin
	      rbs_count := 0;
	      if tsrec.con_id = 0 then -- non-cdb
                 if for_dbuname is not null then
                    rbs_count := to_number(
                                   sys.dbms_backup_restore.remoteSQLExecute(
                                      source_dbuname => for_dbuname, 
                                      source_cs      => source_cs,
                                      stmt           => 
                                         'select count(us#) from undo$ u ' ||
                                         ' where u.ts# = ' || tsrec.ts# ||
                                         '   and u.status$ != 1'));
                 else
                    select count(us#) into rbs_count
                      from undo$ u
                     where u.ts# = tsrec.ts#
                       and u.status$ != 1;
                 end if;
              else -- cdb
                 if for_dbuname is not null then
                    rbs_count := to_number(
                                   sys.dbms_backup_restore.remoteSQLExecute(
                                      source_dbuname => for_dbuname,
                                      source_cs      => source_cs,
                                      stmt           =>
                              'select count(*) from cdb_rollback_segs u ' ||
                              ' where u.tablespace_name = ''' || tsrec.name ||
                              '''   and u.con_id = ' || tsrec.con_id ||
                              '   and (u.con_id = 1 or ' ||
                              '        exists ( ' ||
                              '           select 1 from v$containers ' ||
                              '            where con_id = ' || tsrec.con_id || 
                              '              and local_undo = 1 ' ||
                              '               ) ' ||
                              '       )'));
                 else
                    select count(*) into rbs_count
                      from cdb_rollback_segs u
                     where tsrec.name = u.tablespace_name
                       and tsrec.con_id = u.con_id
                       and (u.con_id = 1 or
                            exists (select 1 from v$containers
                                     where con_id = tsrec.con_id
                                      and local_undo = 1));
                 end if;
              end if;
           exception
              when others then
                err_msg := sqlerrm;
                krmicd.writeErrMsg(4005, err_msg);
                rbs_count := 0;
                raise;
           end;
           end if;
           deb('resync', 'Calling checkTableSpace', dbtype);
           deb('resync', '  for ts: '||tsrec.name||' ('||to_char(tsrec.ts#)||
               '), cscn: '||to_char(tsrec.create_scn)||
               ', plugin_scn: '||to_char(tsrec.plugin_scn)||' with '||
               rbs_count||' rollback segments', dbtype);
           dbms_rcvcat.checkTableSpace
              (tsrec.name, tsrec.ts#, tsrec.create_scn, tsrec.create_time,
               rbs_count, tsrec.included_in_database_backup, tsrec.bigfile,
               tsrec.temporary, tsrec.encrypt_in_backup, tsrec.plugin_scn,
               tsrec.con_id, pdb_dict_check.exists(tsrec.con_id));
        end loop;
 
        deb('resync', 'Calling endTableSpaceResync', dbtype);
        dbms_rcvcat.endTableSpaceResync;
     end if;
 
     IF dbms_rcvcat.beginDataFileResync(high_fe_recid) THEN
        select record_size into rec_size
          from v$controlfile_record_section
        where type='DATAFILE';
 
        rec_size := 1024 + rec_size;  -- kccfn + kccfe
        rec_per_chunk := floor(sort_area_size / rec_size);
 
        select max(fenum) into high_recno
          from x$kccfe fe
         where fe.fedup != 0;
 
        deb('resync', 'total files= '|| total_recs, dbtype);
 
        found := 0;
        low := 1;
        deb_sort_area(0);
        loop
           high := low + rec_per_chunk - 1;
           for dfrec in df(low, high) LOOP
              deb('resync', 'Resyncing datafile '|| dfrec.fname, dbtype);
              IF (dfrec.plugged_readonly = 'NO' OR
                  dfrec.plugin_scn != 0) THEN
                 IF (dfrec.clean_flag <> 0 OR -- the clean bit is on
                     dfrec.plugged_readonly = 'YES') THEN
                    IF (dfrec.read_enabled_flag <> 0 AND
                        dfrec.pdb_closed = 0) THEN
                       read_only := 1;
                    ELSE
                       read_only := 0;         -- offline clean or pdb_closed
                    END IF;
                 ELSE -- the file is not clean
                    dfrec.stop_scn   := NULL;
                    dfrec.stop_time  := NULL;
                    dfrec.pdb_closed := 0;
                    read_only := 0;
                 END IF;
 
                 IF dfrec.fsize = 0 THEN
--
--
                    dfrec.fsize := NULL;
                 END IF;
 
                 IF dfrec.missing_file_flag <> 0 THEN
--
--
--
                    dfrec.fname := NULL;
                 END IF;
 
                 deb('resync', 'Calling checkDataFile for fileno '||
                     dfrec.fileno||' size '||dfrec.fsize, dbtype);
                 dbms_rcvcat.checkDataFile(
                    dfrec.fileno, dfrec.fname, dfrec.create_scn,
                    dfrec.create_time, dfrec.fsize, dfrec.block_size,
                    dfrec.tsnum, dfrec.stop_scn, read_only, dfrec.stop_time,
                    dfrec.rfileno, dfrec.aux_fname, dfrec.foreign_dbid,
                    dfrec.foreign_create_scn, dfrec.foreign_create_time,
                    dfrec.plugged_readonly, dfrec.plugin_scn,
                    dfrec.plugin_reset_scn, dfrec.plugin_reset_time,
                    dfrec.create_thread, dfrec.create_size,
                    dfrec.con_id, dfrec.pdb_closed,
                    pdb_dict_check.exists(dfrec.con_id),
                    dfrec.pdb_foreign_dbid, dfrec.pdb_foreign_ckp_scn,
                    dfrec.pdb_foreign_afn);
 
--
--
--
 
                 IF (dfrec.aux_fname = 'UNKNOWN') THEN
                    IF debug_resync THEN
                       deb('resync', 'Calling getCloneName', dbtype);
                    END IF;
                    rc_aux_fname := dbms_rcvcat.getCloneName(dfrec.fileno,
                                                             dfrec.create_scn,
                                                             dfrec.plugin_scn);
 
                    IF for_dbuname is not null THEN
                       null_retVal := 
                          sys.dbms_backup_restore.remoteSQLExecute(
                             source_dbuname => for_dbuname, 
                             source_cs      => source_cs,
                             stmt           => 
                               'begin ' ||
                               ' sys.dbms_backup_restore.setDatafileAux(' ||
                                 dfrec.fileno || ',''' ||
                                 replace(rc_aux_fname,'''','''''') || '''); '||
                               'end;');
                    ELSE
                       sys.dbms_backup_restore.setDatafileAux(dfrec.fileno,
                                                              rc_aux_fname);
                    END IF;
                 END IF;
 
                 IF dfrec.offline_scn <> 0 then
                    deb('resync', 'Calling checkOfflineRange: offline '||
                        dfrec.offline_scn||' online '|| dfrec.online_scn,
                        dbtype);
                    dbms_rcvcat.checkOfflineRange(
                       null, null, dfrec.fileno, dfrec.create_scn,
                       dfrec.offline_scn, dfrec.online_scn, dfrec.online_time,
                       cf_create_time);
                 END IF;
              END IF;
              found := found + 1;
           end loop;
           IF (high >= high_recno) THEN
              deb('resync', 'Processed '||found|| ' datafiles.  Done', dbtype);
              goto all_df_found;
           END IF;
           low := high + 1;
        end loop;
 
        <<all_df_found>>
 
        dbms_rcvcat.endDataFileResync;
     end if;
 
 
     resyncTempfiles;
 
     deb('resync', 'high_rt_recid= '|| high_rt_recid, dbtype);
 
     if dbms_rcvcat.beginThreadResync(high_rt_recid) then
        for rtrec in rt loop
           deb('resync', 'Calling checkThread for thread '||
               rtrec.thread#||' with sequence '|| rtrec.last_sequence#,
               dbtype);
           dbms_rcvcat.checkThread
              (rtrec.thread#, rtrec.last_sequence#, rtrec.enable_scn,
              rtrec.enable_time, rtrec.disable_scn, rtrec.disable_time,
              rtrec.status);
        end loop;
 
        dbms_rcvcat.endThreadResync;
     end if;
 
     deb('resync', 'high_le_recid= '|| high_le_recid, dbtype);
 
     if dbms_rcvcat.beginOnlineRedoLogResync(high_le_recid) then
        for orlrec in orl loop
           deb('resync','Calling checkOnlineRedoLog '|| orlrec.fname, dbtype);
           dbms_rcvcat.checkOnlineRedoLog
              (orlrec.thread#, orlrec.group#, orlrec.fname,
               orlrec.bytes, orlrec.type);
        end loop;
        dbms_rcvcat.endOnlineRedoLogResync;
     end if;
 
     if resync_reason != dbms_rcvcat.RESYNC_REASON_NOACTION then
        deb('resync', 'Checking for fullResyncAction', dbtype);
        dbms_rcvcat.getResyncActions(resync_valid, 
                                     resync_added,
                                     resync_dropped, 
                                     resync_changed,
                                     resync_recreated,
                                     resync_renamed,
                                     resync_resized);
        deb('resync', 'fullResyncAction.added:     '||nvl(resync_added, -1), 
            dbtype);
        deb('resync', 'fullResyncAction.dropped:   '||nvl(resync_dropped, -1), 
            dbtype);
        deb('resync', 'fullResyncAction.changed:   '||nvl(resync_changed, -1), 
            dbtype);
        deb('resync', 'fullResyncAction.recreated: '||nvl(resync_recreated, -1), 
            dbtype);
        deb('resync', 'fullResyncAction.renamed:   '||nvl(resync_renamed, -1), 
            dbtype);
        deb('resync', 'fullResyncAction.resized:   '||nvl(resync_resized, -1), 
            dbtype);
 
        if resync_valid then
           deb('resync', 'Got a valid fullResyncAction', dbtype);
           krmicd.msgResyncActions(fullResyncBaseMsg,
                                   resync_added,
                                   resync_dropped, 
                                   resync_changed,
                                   resync_recreated,
                                   resync_renamed,
                                   resync_resized);
        end if;
     end if;
     dbms_rcvcat.setReason(dbms_rcvcat.RESYNC_REASON_NONE, TRUE);
  end if; -- full_resync or auto_prim_resync
 
  IF not auto_prim_resync AND cf_type = 'STANDBY' AND not converted_cf THEN
    IF dbms_rcvcat.beginOnlineRedoLogResync(high_le_recid) THEN
       for orlrec in orl loop
          deb('resync','Calling checkOnlineRedoLog '|| orlrec.fname, dbtype);
          dbms_rcvcat.checkOnlineRedoLog
             (orlrec.thread#, orlrec.group#, orlrec.fname,
              orlrec.bytes, orlrec.type);
       end loop;                    
       dbms_rcvcat.endOnlineRedoLogResync;
    END IF;
 
    IF dbms_rcvcat.beginDataFileResyncForStandby(high_fe_recid) THEN
        rec_size := 758 + 75;
        rec_per_chunk := floor(sort_area_size / rec_size);
 
        select max(fenum) into high_recno
          from x$kccfe fe
         where fe.fedup != 0;
 
        found := 0;
        low := 1;
        deb_sort_area(0);
        loop
           high := low + rec_per_chunk - 1;
           for dfrec in df(low, high) LOOP
              deb('resync', 'Resyncing datafile for standby '|| dfrec.fname);
              IF (dfrec.plugged_readonly = 'NO' OR
                  dfrec.plugin_scn != 0) THEN
 
                 deb('resync', 'plugin_scn = ' || dfrec.plugin_scn ||
                      ' plugged_readonly = ' || dfRec.plugged_readonly ||
                      ' clean_flag = ' || dfRec.clean_flag ||
                      ' read_enabled_flag = ' || dfRec.read_enabled_flag);
 
                 IF (dfrec.clean_flag <> 0 OR -- the clean bit is on
                     dfrec.plugged_readonly = 'YES') THEN
                    IF (dfrec.read_enabled_flag <> 0 AND
                        dfrec.pdb_closed = 0) THEN
                       deb('resync', 'the file is clean');
                       read_only := 1;
                    ELSE
                       deb('resync', 'the file is offline clean');
                       read_only := 0;         -- offline clean
                    END IF;
                 ELSE -- the file is not clean
                    deb('resync', 'the file is not clean');
                    dfrec.stop_scn := NULL;
                    dfrec.stop_time := NULL;
                    read_only := 0;
                 END IF;
 
                 IF dfrec.fsize = 0 THEN
--
--
                    dfrec.fsize := NULL;
                 END IF;
 
                 IF dfrec.missing_file_flag <> 0 THEN
--
--
--
                    dfrec.fname := NULL;
                 END IF;
 
                 deb('resync', 'Calling checkDataFileForStandby for fileno '||
                     dfrec.fileno||' size '||dfrec.fsize ||
                     ' create_scn = ' || dfRec.create_scn ||
                     ' plugin_scn = ' || dfRec.plugin_scn ||
                     ' stop_scn = ' || dfRec.stop_scn ||
                     ' read_only = ' || read_only);
 
                 dbms_rcvcat.checkDataFileForStandby(
                    dfrec.fileno, dfrec.fname, dfrec.create_scn,
                    dfrec.create_time, dfrec.fsize, dfrec.block_size,
                    dfrec.tsnum, dfrec.rfileno, dfrec.stop_scn, read_only, 
                    dfrec.foreign_dbid, dfrec.plugin_scn, sync_retries > 0,
                    pdb_dict_check_sby.exists(dfrec.con_id));
              END IF;
              found := found + 1;
           end loop;
           IF (high >= high_recno) THEN
              deb('resync', 'Processed '||found|| ' datafiles.  Done');
              goto all_df_found_for_standby;
           END IF;
           low := high + 1;
        end loop;
 
        <<all_df_found_for_standby>>
 
        dbms_rcvcat.endDataFileResyncForStandby;
     end if;
 
     select record_size, last_recid into rec_size, high_tf_recid
       from v$controlfile_record_section
      where type = 'TEMPORARY FILENAME';
 
     if dbms_rcvcat.beginTempFileResyncForStandby(high_tf_recid) THEN
        rec_size := 1024 + rec_size;  -- kccfn + kcctf
        rec_per_chunk := floor(sort_area_size / rec_size);
 
--
        select nvl(max(tfnum), 0)
          into high_recno
          from x$kcctf
         where tfdup != 0;
 
        found := 0;
        low := 1;
        deb_sort_area(0);
        loop
           high := low + rec_per_chunk - 1;
           for tfrec in tf(low, high) LOOP
              deb('resync', 'Resyncing tempfile '|| tfrec.fname, dbtype);
              IF tfrec.fsize = 0 THEN
--
--
                 tfrec.fsize := NULL;
              END IF;
 
              deb('resync', 'Calling checkTempFile for fileno '||
                  tfrec.fileno||' size '||tfrec.fsize, dbtype);
              dbms_rcvcat.checkTempFileForStandby(
                  tfrec.fileno, tfrec.fname, tfrec.create_scn,
                  tfrec.create_time, tfrec.fsize, tfrec.block_size,
                  tfrec.tsnum, tfrec.rfileno, tfrec.autoextend,
                  tfrec.max_size, tfrec.next_size, tfrec.con_id);
              found := found + 1;
           end loop;
 
           IF (high >= high_recno) THEN
              deb('resync', 'Processed '||found|| ' tempfiles.  Done', dbtype);
              goto all_stby_tf_found;
           ELSE
              low := high + 1;
           END IF;
        end loop;
 
        <<all_stby_tf_found>>
 
        dbms_rcvcat.endTempFileResyncForStandby;
     end if;
  END IF;
 
 
  if (not auto_prim_resync and dbms_rcvcat.doDuplicateMining) then
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
     
     deb('resync', 'Begin mining previous resyncstamp', dbtype);
 
     select max(stamp1), min(stamp2)
       into max_stamp, until_stamp
       from (select nvl(max(al.stamp), least_stamp)    stamp1,
                    nvl(min(al.stamp), greatest_stamp) stamp2
               from v$archived_log  al
              where standby_dest = 'NO'
                and status != 'D'
                and archived = 'YES'
                and al.stamp >= kccdivts
             union all
             select nvl(max(bp.stamp), least_stamp)    stamp1,
                    nvl(min(bp.stamp), greatest_stamp) stamp2
               from v$backup_piece  bp
              where status != 'D'
                and bp.stamp >= kccdivts
             union all
             select nvl(max(dc.stamp), least_stamp)    stamp1,
                    nvl(min(dc.stamp), greatest_stamp) stamp2
               from v$datafile_copy dc
              where status != 'D'
                and dc.stamp >= kccdivts);
 
     deb('resync', '(until_stamp, max_stamp)=(' ||
         until_stamp || ',' || max_stamp || ')', dbtype);
 
     if (max_stamp >= until_stamp) then
        if is19871set then           -- testing binary search
           unit    := 24 * 60 * 60;  -- second granularity
           maxdups := 2;             -- look for two duplicates
        end if;
        min_stamp := until_stamp;
 
        <<retry_mining>>
        no_units := stamp2date(max_stamp) - stamp2date(min_stamp);
        deb('resync', 'number of days apart=' || no_units ||
            ' unit=' || unit, dbtype);
        no_units := ceil(no_units * unit);
        deb('resync', 'number of units apart=' || no_units, dbtype);
        high := no_units;
        low  := 0;
        middle := 0;
 
--
        while (low <= high) loop
           middle := floor((low + high) / 2);
           deb('resync', 'high=' || high || ' low=' || low, dbtype);
           high_stamp := date2stamp(stamp2date(min_stamp) + middle/unit);
           wasresyncstamp := wasresynced(until_stamp, high_stamp);
           if (wasresyncstamp != 0) then
              resyncstamp := wasresyncstamp;
              low  := middle + 1;
              if (wasresyncstamp = -1) then
                 new_min_stamp := high_stamp;
              end if;
           else
              high := middle - 1;
           end if;
        end loop;
 
--
--
        if (resyncstamp = -1 and unit < 1440 and new_min_stamp > 0) then
           deb('resync', 'retry using new min_stamp ' || new_min_stamp,
               dbtype);
           unit := 1440;               -- minute granularity
           min_stamp := new_min_stamp;
           goto retry_mining;
        end if;
        deb('resync', 'previous resyncstamp=' || resyncstamp, dbtype);
     end if;
        
     deb('resync', 'End mining previous resyncstamp', dbtype);
  end if;
 
--
--
--
  select record_size, last_recid into rec_size, high_ic_recid
     from v$controlfile_record_section
     where type='DATABASE INCARNATION';
  recid := dbms_rcvcat.beginIncarnationResync(return_Recid=>TRUE);
  deb('resync', 'Incarnation last recid ' ||recid||'; high '||high_ic_recid,
      dbtype);
  if (high_ic_recid > recid) then
     high := recid;
     low  := recid+1;
     rec_per_chunk := floor(sort_area_size / rec_size);
     total_recs := high_ic_recid - low + 1;
     deb_sort_area(high_ic_recid);
     while (high < high_ic_recid) loop
        high := least(low + rec_per_chunk -1, high_ic_recid);
        for icrec in ic(low, high) loop
           deb('resync', 'Calling checkIncarnation with reset_scn: '||
               icrec.resetlogs_change#||' reset_time: ' ||
               icrec.prior_resetlogs_time, dbtype);
           parent_dbinc_key :=
             dbms_rcvcat.checkIncarnation(icrec.resetlogs_change#,
                                          icrec.resetlogs_time,
                                          icrec.prior_resetlogs_change#,
                                          icrec.prior_resetlogs_time, 
                                          db_name);
        end loop;
        low := high + 1;
     end loop;
 
--
     deb('resync', 'Calling checkIncarnation for current reset_scn: '||
         reset_scn||' reset_time: '||reset_time, dbtype);
     parent_dbinc_key :=
        dbms_rcvcat.checkIncarnation(reset_scn, reset_time, prior_reset_scn,
                                     prior_reset_time, db_name);
  end if;
  dbms_rcvcat.endIncarnationResync(kccdivts, high_ic_recid);
 
--
--
--
  ret := dbms_rcvcat.beginConfigResync2(high_conf_recid => high_rm_recid);
  deb('resync', 'Configuration last recid '||high_rm_recid|| '; ret '|| ret,
      dbtype);
 
--
--
--
--
  if (ret = CONFIGRESYNC_TORC OR ret = CONFIGRESYNC_TORC_TOCF) then
      resyncConf2Catalog(cf_type, FALSE);
  end if;
 
  if auto_prim_resync then
     goto skip_circular_section_resync;
  end if;
 
  if (cfname is null  and        -- not a resync from controlfile copy
      cf_type != 'BACKUP') then  -- not a backup controlfile
 
    flashback_time := getFlashbackTime(cf_type);
 
    select last_recid into high_grsp_recid
      from v$controlfile_record_section
      where type = 'GUARANTEED RESTORE POINT';
 
    dbms_rcvcat.updateOldestFlashbackSCN(
       oldest_flashback_scn     => NULL,       -- obsolete argument
       oldest_flashback_time    => flashback_time);
 
    deb('resync', 'high_grsp_recid = ' || high_grsp_recid, dbtype);
    if dbms_rcvcat.beginGuaranteedRPResync(high_grsp_recid) then
       for grsprec in grsp loop
          deb('resync', 'Calling checkGuaranteedRP ' ||
              grsprec.rspname, dbtype);
          dbms_rcvcat.checkGuaranteedRP
             (grsprec.rspname, grsprec.from_scn, grsprec.to_scn,
              grsprec.resetlogs_change#, grsprec.resetlogs_time,
              grsprec.rsptime, grsprec.rsprsptime, grsprec.guaranteed,
              grsprec.con_id, grsprec.clean);
       end loop;
       dbms_rcvcat.endGuaranteedRPResync;
    end if;
  end if;
 
--
--
--
--
  
--
--
--
--
--
--
--
--
 
  recid := dbms_rcvcat.beginRmanStatusResync;
--
--
--
--
  select record_size, last_recid into rec_size, high_rsr_recid
       from v$controlfile_record_section
       where type='RMAN STATUS';
  running_found := FALSE;
  deb('resync', 'RmanStatusResync last recid '||recid|| 
      '; high '||high_rsr_recid, dbtype);
 
--
  if (low_run_recid > 0 and
      low_run_recid < high_rsr_recid) then
     deb('resync', 'using low_run_recid ' || low_run_recid, dbtype);
     shigh_rsr_recid := low_run_recid - 1;
  else
     shigh_rsr_recid := high_rsr_recid;
  end if;
 
  if (high_rsr_recid > recid) then
     high := recid;
     low := recid + 1;
     rec_per_chunk := floor(sort_area_size / rec_size);
     total_recs := high_rsr_recid - low + 1;
     deb_sort_area(high_rsr_recid);
     while (high < high_rsr_recid) loop
        high := least(low + rec_per_chunk - 1, high_rsr_recid);
        deb('resync', 'Calling rsr cursor from: '|| low||' to: '||high, 
            dbtype);
 
        for rsrrec in rsr(low, high) loop
--
--
--
--
--
--
           if (rsrrec.status like '%RUNNING%' and
               sysdate - rsrrec.start_time < 4 and
               not running_found ) then
              deb('resync', 'row '||low||' belongs to job still running: ' ||
                  rsrrec.status, dbtype);
              shigh_rsr_recid := rsrrec.recid - 1;
              running_found := TRUE;
           else
              deb('resync', 'row '||low||' belongs to finished job: ' ||
                  rsrrec.status, dbtype, rman_constant.LEVEL_HI);
           end if;
 
           deb('resync', 'Calling checkRmanStatus for '|| rsrrec.recid ||
               ' with status '||rsrrec.status, dbtype);
           dbms_rcvcat.checkRmanStatus(rsrrec.recid,  
                                       rsrrec.stamp,  
                                       rsrrec.parent_recid, 
                                       rsrrec.parent_stamp,
                                       rsrrec.row_level,
                                       rsrrec.row_type, 
                                       rsrrec.command_id,
                                       rsrrec.operation,  
                                       rsrrec.status,  
                                       rsrrec.mbytes_processed, 
                                       rsrrec.start_time,  
                                       rsrrec.end_time,
                                       rsrrec.input_bytes,
                                       rsrrec.output_bytes,
                                       rsrrec.optimized,
                                       rsrrec.object_type,
                                       rsrrec.session_recid,
                                       rsrrec.session_stamp,
                                       rsrrec.output_device_type,
                                       rsrrec.osb_allocated);
        end loop;
        low := high + 1;
     end loop;
  end if;
 
  dbms_rcvcat.endRmanStatusResync(shigh_rsr_recid);
 
  if for_dbuname is not null then
--
--
--
--
     deb('resync', 'we can not resync rman output for remote instance');
  else
     low := dbms_rcvcat.beginRmanOutputResync(inst_startup_stamp, 
                                              doRoutMining);
 
--
--
--
--
     if (doRoutMining = true) then
        deb('resync', 'Begin duplicate rout mining');
 
        select max(stamp1), min(stamp2)
          into max_stamp, until_stamp
          from (select nvl(max(rout.stamp), least_stamp)    stamp1,
                       nvl(min(rout.stamp), greatest_stamp) stamp2
                  from v$rman_output  rout);
 
        deb('resync', '(until_stamp, max_stamp)=(' ||
            until_stamp || ',' || max_stamp || ')', dbtype);
 
        if (max_stamp >= until_stamp) then
           unit    := 24 * 60 * 60;   -- second granularity
           maxdups := 16;             -- look for 16 duplicates
           min_stamp := until_stamp;
 
           <<retry_rout_mining>>
           no_units := stamp2date(max_stamp) - stamp2date(min_stamp);
           deb('resync', 'number of days apart=' || no_units ||
               ' unit=' || unit, dbtype);
           no_units := ceil(no_units * unit);
           deb('resync', 'number of units apart=' || no_units, dbtype);
           high := no_units;
           low  := 0;
           middle := 0;
 
--
           while (low <= high) loop
              middle := floor((low + high) / 2);
              deb('resync', 'high=' || high || ' low=' || low, dbtype);
              high_stamp := date2stamp(stamp2date(min_stamp) + middle/unit);
              wasresyncstamp := routresynced(until_stamp, high_stamp);
              if (wasresyncstamp != 0) then
                 resyncstamp := wasresyncstamp;
                 low  := middle + 1;
                 if (wasresyncstamp = -1) then
                    new_min_stamp := high_stamp;
                 end if;
              else
                 high := middle - 1;
              end if;
           end loop;
 
           deb('resync', 'previous resyncstamp=' || resyncstamp, dbtype);
        end if;
 
        deb('resync', 'End mining previous resyncstamp', dbtype);
 
        if (resyncstamp > 0) then
           low := resyncstamp;
        end if;
     end if;
 
     if low = (greatest_stamp - 1) then
        deb('resync', 'RMAN output disabled');
     else   
        deb('resync', 'RMAN output last RMAN output '||low);
 
        for routrec in rout(low) loop
            deb('resync', 'Calling checkRmanOutput with recid '||routrec.recid
                ||' stamp '|| routrec.stamp||' session '||
                routrec.session_recid ||' session stamp '||
                routrec.session_stamp, dbtype, rman_constant.LEVEL_HI);
            deb('resync', 'rman_status_recid '||routrec.rman_status_recid ||
                ' rman_status_stamp '|| routrec.rman_status_stamp, dbtype,
                rman_constant.LEVEL_HI);
            deb('resync', 'Calling checkRmanOutput with output '||
                 routrec.output, dbtype, rman_constant.LEVEL_HI);
            dbms_rcvcat.checkRmanOutput(routrec.recid,
                                        routrec.stamp, 
                                        routrec.session_recid,
                                        routrec.session_stamp, 
                                        routrec.rman_status_recid,
                                        routrec.rman_status_stamp,
                                        routrec.output);
        end loop;
        dbms_rcvcat.endRmanOutputResync;
     end if; 
  end if;
 
  recid := dbms_rcvcat.beginLogHistoryResync;
  if (recid = 0) then
     lh_lowscn := dbms_rcvcat.getLogHistoryLowSCN;
     if (lh_lowscn > 0) then
        select nvl(max(recid), 0) into recid
          from v$log_history
         where first_change# <= lh_lowscn;
     end if;
  end if;
  deb('resync', 'Log History last recid '||recid|| '; high '||high_lh_recid,
      dbtype);
  if (high_lh_recid > recid) then
     select record_size into rec_size
       from v$controlfile_record_section
      where type='LOG HISTORY';
 
     high := recid;
     low := recid + 1;
     rec_per_chunk := floor(sort_area_size / rec_size);
     total_recs := high_lh_recid - low + 1;
     deb_sort_area(high_lh_recid);
     while (high < high_lh_recid) loop
        high := least(low + rec_per_chunk -1, high_lh_recid);
        for rlhrec in rlh(low, high) loop
           deb('resync', 'Calling checkLogHistory with recid '||rlhrec.recid ||
               ' thread '|| rlhrec.thread#||' sequence '||rlhrec.sequence# ||
               ' reset_scn '|| rlhrec.resetlogs_change#, dbtype);
           dbms_rcvcat.checkLogHistory(
              rlhrec.recid, rlhrec.stamp, rlhrec.thread#,
              rlhrec.sequence#, rlhrec.low_scn, rlhrec.low_time,
              rlhrec.next_scn, rlhrec.resetlogs_change#, 
              rlhrec.resetlogs_time);
        end loop;
        low := high + 1;
     end loop;
  end if;
  dbms_rcvcat.endLogHistoryResync;
 
  recid := dbms_rcvcat.beginArchivedLogResync;
  deb('resync', 'Archive log last recid '||recid|| '; high '||high_al_recid,
      dbtype);
  if (high_al_recid > recid) then
     select record_size into rec_size
       from v$controlfile_record_section
      where type='ARCHIVED LOG';
 
     high := recid;
     low := recid + 1;
     rec_per_chunk := floor(sort_area_size / rec_size);
     total_recs := high_al_recid - low + 1;
     deb_sort_area(high_al_recid);
 
     while (high < high_al_recid) loop
        high := least(low + rec_per_chunk -1, high_al_recid);
        for alrec in al(low, high, cf_type) loop
          <<al_resync_again>>
          begin
           deb('resync', 'Calling checkArchivedLog for '|| alrec.name, dbtype);
           deb('resync', '  with sequence '||alrec.sequence#||
               ' archived '||alrec.archived||
               ' status '||alrec.status||
               ' recid '||alrec.recid||
               ' is_standby '||alrec.is_standby, dbtype);
           dbms_rcvcat.checkArchivedLog(
              alrec.recid, alrec.stamp, alrec.thread#,
              alrec.sequence#, alrec.resetlogs_change#, alrec.resetlogs_time,
              alrec.first_change#, alrec.first_time, alrec.next_change#,
              alrec.next_time, alrec.blocks, alrec.block_size, alrec.name,
              alrec.archived, alrec.completion_time, alrec.status,
              alrec.is_standby, alrec.dictionary_begin, alrec.dictionary_end,
              alrec.is_recovery_dest_file, alrec.compressed, alrec.creator,
              alrec.terminal);
          exception
            when change_record_stamp then
              deb('resync', 'got exception: Changing stamp for this record');
              if for_dbuname is not null then
                 null_retVal := 
                    sys.dbms_backup_restore.remoteSQLExecute(
                       source_dbuname => for_dbuname, 
                       source_cs      => source_cs,
                       stmt           => 
                         'begin ' ||
                         ' sys.dbms_backup_restore.IncrementRecordStamp(' ||
                         '    rectype => ' || 
                         '     sys.dbms_backup_restore.RTYP_ARCHIVED_LOG ' ||
                         '  , recid   => ' || alrec.recid ||
                         '  , stamp   => ' || alrec.stamp ||
                         '    ); ' ||
                         'end;');
              else
                 sys.dbms_backup_restore.IncrementRecordStamp(
                      rectype    => sys.dbms_backup_restore.RTYP_ARCHIVED_LOG,
                      recid      => alrec.recid, 
                      stamp      => alrec.stamp);
              end if;
              alrec.stamp := alrec.stamp + 1;
              krmicd.clearErrors;
              goto al_resync_again;
          end;
        end loop;
        low := high + 1;
     end loop;
  end if;
  dbms_rcvcat.endArchivedLogResync;
 
  recid := dbms_rcvcat.beginOfflineRangeResync;
  deb('resync', 'Offline range last recid '||recid|| '; high '||high_or_recid,
      dbtype);
  if (high_or_recid > recid) then
     select record_size into rec_size
       from v$controlfile_record_section
      where type='OFFLINE RANGE';
 
     high := recid;
     low := recid + 1;
     rec_per_chunk := floor(sort_area_size / rec_size);
     total_recs := high_or_recid - low + 1;
     deb_sort_area(high_or_recid);
     while (high < high_or_recid) loop
        high := least(low + rec_per_chunk -1, high_or_recid);
        for offrrec in offr(low, high) LOOP
           deb('resync', 'Calling checkOfflineRange'||
               ' recid: '||nvl(offrrec.recid,-1)||
               ' file#: '||offrrec.file#||
               ' creation_scn: '||nvl(offrrec.creation_change#, -1)||
               ' offline_scn: '||offrrec.offline_change#|| 
               ' online_scn: '||offrrec.online_change#,
               dbtype);
           dbms_rcvcat.checkOfflineRange(
              offrrec.recid, offrrec.stamp, offrrec.file#,
              offrrec.creation_change#,
              offrrec.offline_change#, offrrec.online_change#,
              offrrec.online_time, cf_create_time, 
              offrrec.resetlogs_change#, offrrec.resetlogs_time);
        end loop;
        low := high + 1;
     end loop;
  end if;
  dbms_rcvcat.endOfflineRangeResync;
 
 
--
--
--
 
--
  select last_recid, record_size into high_nrsp_recid, rec_size
    from v$controlfile_record_section
    where type = 'RESTORE POINT';
  deb('resync', 'high_nrsp_recid= '||high_nrsp_recid, dbtype);
 
--
--
  recid := dbms_rcvcat.beginRestorePointResync;
  deb('resync', 'Restore Point last recid '||recid|| '; high '||
      high_nrsp_recid,dbtype);
  if (high_nrsp_recid > recid) then
     high := recid;
     low := recid + 1;
     rec_per_chunk := floor(sort_area_size / rec_size);
     total_recs := high_nrsp_recid - low + 1;
     deb_sort_area(high_nrsp_recid);
 
     while (high < high_nrsp_recid) loop
        high := least(low + rec_per_chunk -1, high_nrsp_recid);
        for nrsprec in nrsp(low, high) loop
           deb('resync', 'Calling checkRestorePoint for recid '||
               nrsprec.recid||' name '||nrsprec.nrsname ||
               ' con_id ' || nrsprec.con_id,
               dbtype);
           dbms_rcvcat.checkRestorePoint(
               nrsprec.recid, nrsprec.stamp, nrsprec.nrsname,
               nrsprec.reset_scn, nrsprec.reset_time, nrsprec.nrsscn,
               nrsprec.nrsrsptime, nrsprec.nrstime, nrsprec.deleted,
               nrsprec.con_id, nrsprec.clean);
        end loop;
        low := high + 1;
     end loop;
  end if;
 
  select min(nrsrid) into low from x$kccnrs;  -- Purge catalog below cf recid
  dbms_rcvcat.endRestorePointResync(low);
 
  deb('resync', 'oam_tst_level = ' || oam_tst_level, dbtype);
  deb('resync', 'resync_2_AMSchema = ' || resync_2_AMSchema, dbtype);
  if resync_2_AMSchema = 1 and oam_tst_level >= 2 then
     deb('resync', 'oam_tst_level:Skipping resync of all backup set records', 
         dbtype);
     goto skip_all_backupset_resync;
  end if;
 
  recid := dbms_rcvcat.beginBackupSetResync;
  low_bs_recid := recid;     -- store this recid for bdf, brl resync
  deb('resync', 'Backup set last recid '||recid|| '; high '||high_bs_recid,
      dbtype);
  if (high_bs_recid > recid) then
     select record_size into rec_size
       from v$controlfile_record_section
      where type='BACKUP SET';
 
     high := recid;
     low := recid + 1;
     rec_per_chunk := floor(sort_area_size / rec_size);
     total_recs := high_bs_recid - low + 1;
     deb_sort_area(high_bs_recid);
     while (high < high_bs_recid) loop
        high := least(low + rec_per_chunk -1, high_bs_recid);
        for bsrec in bs(low, high) loop
           deb('resync', 'Calling checkBackupSet for set_stamp '||
               bsrec.set_stamp||' set_count '||bsrec.set_count||
               ' pieces: '||bsrec.pieces||' recid: '||bsrec.recid,
               dbtype);
           dbms_rcvcat.checkBackupSet(
              bsrec.recid, bsrec.stamp, bsrec.set_stamp, bsrec.set_count,
              bsrec.backup_type, bsrec.incremental_level, bsrec.pieces,
              bsrec.start_time, bsrec.completion_time,
              bsrec.controlfile_included, bsrec.input_file_scan_only,
              bsrec.keep_options, bsrec.keep_until, bsrec.block_size,
              bsrec.multi_section, TRUE, bsrec.guid, bsrec.dropped_pdb);
        end loop;
        low := high + 1;
     end loop;
 
     deb('resync', 'Backupset -> Backup DataFile', dbtype);
     low_bdf_recid := dbms_rcvcat.beginBackupDataFileResync;
     select nvl(min(bdf.recid) - 1, 0), nvl(max(bdf.recid), 0)
     into local_low, local_high
     from v$backup_set bs, v$backup_datafile bdf
     where ((bdf.recid <= low_bdf_recid and low_bdf_recid != 0) OR
            (bdf.stamp <= kccdivts and low_bdf_recid = 0))
       and bs.recid between low_bs_recid and high_bs_recid
       and (bs.stamp >= kccdivts OR bs.recid = high_bs_recid)
       and bs.stamp >= resyncstamp
       and bs.set_stamp = bdf.set_stamp
       and bs.set_count = bdf.set_count
       and bs.backup_type != 'L';  -- ignore archivelog backups
 
     select record_size into rec_size
       from v$controlfile_record_section
      where type='BACKUP DATAFILE';
 
     high := local_low;
     low := local_low + 1;
     rec_per_chunk := floor(sort_area_size / rec_size);
     total_recs := local_high - low + 1;
     deb_sort_area(local_high);
     while (high < local_high) loop
        high := least(low + rec_per_chunk -1, local_high);
        for bdfbsrec in bdfbs(low, high, low_bs_recid, high_bs_recid) loop
           curr_set_stamp := bdfbsrec.set_stamp;
           curr_set_count := bdfbsrec.set_count;
           deb('resync', 'Calling checkBackupDataFile for set_stamp '||
               bdfbsrec.set_stamp||' set_count '||bdfbsrec.set_count,
               dbtype);
           deb('resync', ' file# '||bdfbsrec.file#||' recid '||bdfbsrec.recid,
               dbtype);
           dbms_rcvcat.checkBackupDataFile(
              bdfbsrec.recid, bdfbsrec.stamp, bdfbsrec.set_stamp,
              bdfbsrec.set_count, bdfbsrec.file#, bdfbsrec.creation_change#,
              bdfbsrec.creation_time, bdfbsrec.resetlogs_change#,
              bdfbsrec.resetlogs_time, bdfbsrec.incremental_level,
              bdfbsrec.incremental_change#, bdfbsrec.checkpoint_change#,
              bdfbsrec.checkpoint_time, bdfbsrec.absolute_fuzzy_change#,
              bdfbsrec.datafile_blocks, bdfbsrec.blocks, bdfbsrec.block_size,
              bdfbsrec.oldest_offline_range, bdfbsrec.completion_time,
              bdfbsrec.controlfile_type, bdfbsrec.marked_corrupt,
              bdfbsrec.media_corrupt, bdfbsrec.logically_corrupt,
              FALSE, bdfbsrec.blocks_read, bdfbsrec.used_change_tracking,
              bdfbsrec.used_optimization, bdfbsrec.foreign_dbid,
              bdfbsrec.plugged_readonly, bdfbsrec.plugin_change#,
              bdfbsrec.plugin_resetlogs_change#,
              bdfbsrec.plugin_resetlogs_time,
              bdfbsrec.section_size, bdfbsrec.guid, bdfbsrec.sparse_backup,
              TRUE, FALSE, bdfbsrec.dropped_pdb);
           curr_set_stamp := 0;
           curr_set_count := 0;
        end loop;
        low := high + 1;
     end loop;
     dbms_rcvcat.endBackupDataFileResync;
 
     deb('resync', 'Backupset -> Backup Spfile', dbtype);
     low_bsf_recid := dbms_rcvcat.beginBackupSpFileResync;
     select nvl(min(bsf.recid) - 1, 0), nvl(max(bsf.recid), 0)
     into local_low, local_high
     from v$backup_set bs, v$backup_spfile bsf
     where ((bsf.recid <= low_bsf_recid and low_bsf_recid != 0) OR
            (bsf.stamp <= kccdivts and low_bsf_recid = 0))
       and bs.recid between low_bs_recid and high_bs_recid
       and (bs.stamp >= kccdivts OR bs.recid = high_bs_recid)
       and bs.stamp >= resyncstamp
       and bs.set_stamp = bsf.set_stamp
       and bs.set_count = bsf.set_count
       and bs.backup_type != 'L';  -- ignore archivelog backups
 
     select record_size into rec_size
       from v$controlfile_record_section
      where type='BACKUP SPFILE';
 
     high := local_low;
     low := local_low + 1;
     rec_per_chunk := floor(sort_area_size / rec_size);
     total_recs := local_high - low + 1;
     deb_sort_area(local_high);
     while (high < local_high) loop
        high := least(low + rec_per_chunk -1, local_high);
        for bsfbsrec in bsfbs(low, high, low_bs_recid, high_bs_recid) loop
           curr_set_stamp := bsfbsrec.set_stamp;
           curr_set_count := bsfbsrec.set_count;
           deb('resync', 'Calling checkBackupSpFile for set_stamp '||
               bsfbsrec.set_stamp||' set_count '||bsfbsrec.set_count
               ||' recid '||bsfbsrec.recid, dbtype);
           dbms_rcvcat.checkBackupSpFile(
              bsfbsrec.recid, bsfbsrec.stamp, bsfbsrec.set_stamp,
              bsfbsrec.set_count, bsfbsrec.modification_time,
              bsfbsrec.bytes, FALSE, bsfbsrec.db_unique_name,
              bsfbsrec.guid, bsfbsrec.dropped_pdb);
           curr_set_stamp := 0;
           curr_set_count := 0;
        end loop;
        low := high + 1;
     end loop;
     dbms_rcvcat.endBackupSpFileResync;
 
     deb('resync', 'Backupset -> Backup RedoLog', dbtype);
     low_brl_recid := dbms_rcvcat.beginBackupRedoLogResync;
     select nvl(min(brl.recid) - 1, 0), nvl(max(brl.recid), 0)
     into local_low, local_high
     from v$backup_set bs, v$backup_redolog brl
     where ((brl.recid <= low_brl_recid and low_brl_recid != 0) OR
            (brl.stamp <= kccdivts and low_brl_recid = 0))
       and bs.recid between low_bs_recid and high_bs_recid
       and (bs.stamp >= kccdivts OR bs.recid = high_bs_recid)
       and bs.stamp >= resyncstamp
       and bs.set_stamp = brl.set_stamp
       and bs.set_count = brl.set_count
       and bs.backup_type = 'L';  -- only archivelog backups
 
     select record_size into rec_size
       from v$controlfile_record_section
      where type='BACKUP REDOLOG';
 
     high := local_low;
     low := local_low + 1;
     rec_per_chunk := floor(sort_area_size / rec_size);
     total_recs := local_high - low + 1;
     deb_sort_area(local_high);
     while (high < local_high) loop
        high := least(low + rec_per_chunk -1, local_high);
        for brlbsrec in brlbs(low, high, low_bs_recid, high_bs_recid) loop
           curr_set_stamp := brlbsrec.set_stamp;
           curr_set_count := brlbsrec.set_count;
           deb('resync', 'Calling checkBackupRedoLog for set_stamp '||
               brlbsrec.set_stamp||' set_count '||brlbsrec.set_count||
               ' recid '||brlbsrec.recid, dbtype);
           deb('resync', '  sequence '||brlbsrec.sequence#||
               ' first change '||brlbsrec.first_change#||
               ' next change '||brlbsrec.next_change#, dbtype);
           dbms_rcvcat.checkBackupRedoLog(
              brlbsrec.recid, brlbsrec.stamp, brlbsrec.set_stamp,
              brlbsrec.set_count, brlbsrec.thread#, brlbsrec.sequence#,
              brlbsrec.resetlogs_change#, brlbsrec.resetlogs_time,
              brlbsrec.first_change#, brlbsrec.first_time,
              brlbsrec.next_change#, brlbsrec.next_time, brlbsrec.blocks,
              brlbsrec.block_size, FALSE, brlbsrec.terminal);
           curr_set_stamp := 0;
           curr_set_count := 0;
        end loop;
        low := high + 1;
     end loop;
     dbms_rcvcat.endBackupRedoLogResync;
  end if;
  dbms_rcvcat.endBackupSetResync;
 
  recid := dbms_rcvcat.beginBackupPieceResync;
  deb('resync', 'Backup piece last recid '||recid|| '; high '||high_bp_recid,
      dbtype);
  if (high_bp_recid > recid) then
     select record_size into rec_size
       from v$controlfile_record_section
      where type='BACKUP PIECE';
 
     high := recid;
     low := recid + 1;
     rec_per_chunk := floor(sort_area_size / rec_size);
     total_recs := high_bp_recid - low + 1;
     deb_sort_area(high_bp_recid);
     while (high < high_bp_recid) loop
        high := least(low + rec_per_chunk -1, high_bp_recid);
        for bprec in bp(low, high) loop
          << bp_resync_again>>
          begin
           deb('resync', 'Calling checkBackupPiece for stamp '||
               bprec.stamp||' recid '||bprec.recid, dbtype);
           deb('resync', '  Handle '||bprec.handle||' status '||
               bprec.status||' piece# '||bprec.piece#, dbtype);
           deb('resync', 'set_stamp '||bprec.set_stamp||
               ' set_count '||bprec.set_count, dbtype);
 
           if resync_2_AMSchema = 1 and
              (oam_tst_level >= 1 and bprec.device_type = 'SBT_TAPE') then
                 deb('resync', 'oam_tst_level:' ||
                      'Skipping resync of all tape backup piece recs', dbtype);
             continue;
           end if;
 
           dbms_rcvcat.checkBackupPiece(
              bprec.recid, bprec.stamp, bprec.set_stamp, bprec.set_count,
              bprec.piece#, bprec.tag, bprec.device_type, bprec.handle,
              bprec.comments, bprec.media, bprec.concur,
              bprec.start_time, bprec.completion_time, bprec.status,
              bprec.copy#, bprec.media_pool, bprec.bytes,
              bprec.is_recovery_dest_file, 
              bprec.rman_status_recid, bprec.rman_status_stamp,
              bprec.compressed, bprec.encrypted, bprec.backed_by_osb, 'U',
              NULL, TRUE, NULL, bprec.guid, NULL, bprec.dropped_pdb);
          exception
            when change_record_stamp then
              deb('resync', 'got exception: Changing stamp for this record');
              if for_dbuname is not null then
                 null_retVal := 
                    sys.dbms_backup_restore.remoteSQLExecute(
                       source_dbuname => for_dbuname, 
                       source_cs      => source_cs,
                       stmt           => 
                         'begin ' ||
                         ' sys.dbms_backup_restore.IncrementRecordStamp(' ||
                         '    rectype => ' || 
                         '     sys.dbms_backup_restore.RTYP_BACKUP_PIECE ' ||
                         '  , recid   => ' || bprec.recid ||
                         '  , stamp   => ' || bprec.stamp ||
                         '    ); ' ||
                         'end;');
              else
                 sys.dbms_backup_restore.IncrementRecordStamp(
                      rectype    => sys.dbms_backup_restore.RTYP_BACKUP_PIECE,
                      recid      => bprec.recid, 
                      stamp      => bprec.stamp);
              end if;
              bprec.stamp := bprec.stamp + 1;
              krmicd.clearErrors;
              goto bp_resync_again;
          end;
        end loop;
        low := high + 1;
     end loop;
  end if;
  dbms_rcvcat.endBackupPieceResync;
 
  recid := dbms_rcvcat.beginBackupDataFileResync;
  deb('resync', 'Backup DataFile last recid '||recid||
      '; high '||high_bf_recid, dbtype);
  if (high_bf_recid > recid) then
     select record_size into rec_size
       from v$controlfile_record_section
      where type='BACKUP DATAFILE';
 
     high := recid;
     low := recid + 1;
     rec_per_chunk := floor(sort_area_size / rec_size);
     total_recs := high_bf_recid - low + 1;
     deb_sort_area(high_bf_recid);
     while (high < high_bf_recid) loop
        high := least(low + rec_per_chunk -1, high_bf_recid);
        for bdfrec in bdf(low, high) loop
           curr_set_stamp := bdfrec.set_stamp;
           curr_set_count := bdfrec.set_count;
           deb('resync', 'Calling checkBackupDataFile for set_stamp '||
               bdfrec.set_stamp||' set_count '||bdfrec.set_count ||
               ' recid '||bdfrec.recid, dbtype);
           deb('resync', '  file# '||bdfrec.file#, dbtype);
           dbms_rcvcat.checkBackupDataFile(
              bdfrec.recid, bdfrec.stamp, bdfrec.set_stamp, bdfrec.set_count,
              bdfrec.file#, bdfrec.creation_change#, bdfrec.creation_time,
              bdfrec.resetlogs_change#, bdfrec.resetlogs_time,
              bdfrec.incremental_level, bdfrec.incremental_change#,
              bdfrec.checkpoint_change#, bdfrec.checkpoint_time,
              bdfrec.absolute_fuzzy_change#, bdfrec.datafile_blocks,
              bdfrec.blocks, bdfrec.block_size, bdfrec.oldest_offline_range,
              bdfrec.completion_time, bdfrec.controlfile_type,
              bdfrec.marked_corrupt, bdfrec.media_corrupt,
              bdfrec.logically_corrupt, TRUE, bdfrec.blocks_read,
              bdfrec.used_change_tracking, bdfrec.used_optimization,
              bdfrec.foreign_dbid, bdfrec.plugged_readonly,
              bdfrec.plugin_change#, bdfrec.plugin_resetlogs_change#,
              bdfrec.plugin_resetlogs_time,
              bdfrec.section_size, bdfrec.guid, bdfrec.sparse_backup,
              TRUE, FALSE, bdfrec.dropped_pdb);
           curr_set_stamp := 0;
           curr_set_count := 0;
        end loop;
        low := high + 1;
     end loop;
  end if;
  dbms_rcvcat.endBackupDataFileResync;
 
  recid := dbms_rcvcat.beginBackupSpFileResync;
  deb('resync', 'Backup SPFILE last recid '||recid||
      '; high '||high_bi_recid, dbtype);
  if (high_bi_recid > recid) then
     select record_size into rec_size
       from v$controlfile_record_section
      where type='BACKUP SPFILE';
 
     high := recid;
     low := recid + 1;
     rec_per_chunk := floor(sort_area_size / rec_size);
     total_recs := high_bi_recid - low + 1;
     deb_sort_area(high_bi_recid);
     while (high < high_bi_recid) loop
        high := least(low + rec_per_chunk - 1, high_bi_recid);
        for bsfrec in bsf(low, high) loop
           curr_set_stamp := bsfrec.set_stamp;
           curr_set_count := bsfrec.set_count;
           deb('resync', 'Calling checkBackupSpFile for set_stamp '||
               bsfrec.set_stamp||' set_count '||bsfrec.set_count ||
               ' recid '||bsfrec.recid, dbtype);
           dbms_rcvcat.checkBackupSpFile(
              bsfrec.recid, bsfrec.stamp, bsfrec.set_stamp, bsfrec.set_count,
              bsfrec.modification_time, bsfrec.bytes, TRUE, 
              bsfrec.db_unique_name, bsfrec.guid, bsfrec.dropped_pdb);
           curr_set_stamp := 0;
           curr_set_count := 0;
        end loop;
        low := high + 1;
     end loop;
  end if;
  dbms_rcvcat.endBackupSpFileResync;
 
  recid := dbms_rcvcat.beginBackupCorruptionResync;
  deb('resync', 'Backup Corruption last recid '||recid||
      '; high '||high_fc_recid, dbtype);
  if (high_fc_recid > recid) then
     select record_size into rec_size
       from v$controlfile_record_section
      where type='BACKUP CORRUPTION';
 
     high := recid;
     low := recid + 1;
     rec_per_chunk := floor(sort_area_size / rec_size);
     total_recs := high_fc_recid - low + 1;
     deb_sort_area(high_fc_recid);
     while (high < high_fc_recid) loop
        high := least(low + rec_per_chunk -1, high_fc_recid);
        for bcbrec in bcb(low, high) loop
           deb('resync', 'Calling checkBackupCorruption for set_stamp '||
               bcbrec.set_stamp||' set_count '||bcbrec.set_count, dbtype);
           deb('resync', '  file# '||bcbrec.file# ||' recid '||bcbrec.recid,
               dbtype);
           dbms_rcvcat.checkBackupCorruption(
              bcbrec.recid, bcbrec.stamp, bcbrec.set_stamp, bcbrec.set_count,
              bcbrec.piece#, bcbrec.file#, bcbrec.block#, bcbrec.blocks,
              bcbrec.corruption_change#, bcbrec.marked_corrupt,
              bcbrec.corruption_type);
        end loop;
        low := high + 1;
     end loop;
  end if;
  dbms_rcvcat.endBackupCorruptionResync;
 
  recid := dbms_rcvcat.beginBackupRedoLogResync;
  deb('resync', 'Backup RedoLog last recid '||recid||
      '; high '||high_bl_recid, dbtype);
  if (high_bl_recid > recid) then
     select record_size into rec_size
       from v$controlfile_record_section
      where type='BACKUP REDOLOG';
 
     high := recid;
     low := recid + 1;
     rec_per_chunk := floor(sort_area_size / rec_size);
     total_recs := high_bl_recid - low + 1;
     deb_sort_area(high_bl_recid);
     while (high < high_bl_recid) loop
        high := least(low + rec_per_chunk -1, high_bl_recid);
        for brlrec in brl(low, high) loop
           curr_set_stamp := brlrec.set_stamp;
           curr_set_count := brlrec.set_count; 
           deb('resync', 'Calling checkBackupRedoLog for set_stamp '||
               brlrec.set_stamp||' set_count '||brlrec.set_count||
               ' recid '||brlrec.recid, dbtype);
           deb('resync', '  sequence '||brlrec.sequence#||
               ' first change '||brlrec.first_change#||
               ' next change '||brlrec.next_change#, dbtype);
           dbms_rcvcat.checkBackupRedoLog(
              brlrec.recid, brlrec.stamp, brlrec.set_stamp, brlrec.set_count,
              brlrec.thread#, brlrec.sequence#, brlrec.resetlogs_change#,
              brlrec.resetlogs_time, brlrec.first_change#, brlrec.first_time,
              brlrec.next_change#, brlrec.next_time, brlrec.blocks,
              brlrec.block_size, TRUE, brlrec.terminal);
           curr_set_stamp := 0;
           curr_set_count := 0;
        end loop;
        low := high + 1;
     end loop;
  end if;
  dbms_rcvcat.endBackupRedoLogResync;
 
<< skip_all_backupset_resync >>
 
  if resync_2_AMSchema = 1 and oam_tst_level >= 2 then
     deb('resync', 
         'oam_tst_level:Skipping resync of datafile image copy recs', dbtype);
     goto skip_all_dfcopy_resync;
  end if;
 
  recid := dbms_rcvcat.beginDataFileCopyResync;
  deb('resync', 'DataFIleCopy last recid '||recid|| '; high '||high_dc_recid,
      dbtype);
  if (high_dc_recid > recid) then
     select record_size into rec_size
       from v$controlfile_record_section
      where type='DATAFILE COPY';
 
     high := recid;
     low := recid + 1;
     rec_per_chunk := floor(sort_area_size / rec_size);
     total_recs := high_dc_recid - low + 1;
     deb_sort_area(high_dc_recid);
     while (high < high_dc_recid) loop
        high := least(low + rec_per_chunk -1, high_dc_recid);
        for cdfrec in cdf(low, high) loop
          << cdf_resync_again >>
          begin
           deb('resync', 'Calling checkDataFileCopy for '|| cdfrec.fname, 
               dbtype);
           deb('resync', '  file# '||cdfrec.file#|| ' status '||cdfrec.status||
                         ' recid '||cdfrec.recid, dbtype);
           dbms_rcvcat.checkDataFileCopy(
              cdfrec.recid, cdfrec.stamp, cdfrec.fname, cdfrec.tag,
              cdfrec.file#, cdfrec.create_scn, cdfrec.create_time,
              cdfrec.reset_scn, cdfrec.reset_time, cdfrec.incr_level,
              cdfrec.ckp_scn, cdfrec.ckp_time, cdfrec.online_fuzzy,
              cdfrec.backup_fuzzy, cdfrec.abs_fuzzy_scn, cdfrec.rcv_fuzzy_scn,
              cdfrec.rcv_fuzzy_time, cdfrec.blocks, cdfrec.block_size,
              cdfrec.oldest_offline_range, cdfrec.completion_time,
              cdfrec.status, cdfrec.controlfile_type,
              cdfrec.keep_options, cdfrec.keep_until, cdfrec.scanned,
              cdfrec.is_recovery_dest_file, cdfrec.rman_status_recid, 
              cdfrec.rman_status_stamp, cdfrec.marked_corrupt,
              cdfrec.foreign_dbid, cdfrec.plugged_readonly,
              cdfrec.plugin_change#, cdfrec.plugin_resetlogs_change#,
              cdfrec.plugin_resetlogs_time, cdfrec.guid, cdfrec.sparse_backup,
              cdfrec.dropped_pdb);
          exception
            when change_record_stamp then
              deb('resync', 'got exception: Changing stamp for this record');
              if for_dbuname is not null then
                 null_retVal := 
                    sys.dbms_backup_restore.remoteSQLExecute(
                       source_dbuname => for_dbuname, 
                       source_cs      => source_cs,
                       stmt           => 
                         'begin ' ||
                         ' sys.dbms_backup_restore.IncrementRecordStamp(' ||
                         '    rectype => ' || 
                         '     sys.dbms_backup_restore.RTYP_DFILE_COPY ' ||
                         '  , recid   => ' || cdfrec.recid ||
                         '  , stamp   => ' || cdfrec.stamp ||
                         '    ); ' ||
                         'end;');
              else
                 sys.dbms_backup_restore.IncrementRecordStamp(
                      rectype    => sys.dbms_backup_restore.RTYP_DFILE_COPY,
                      recid      => cdfrec.recid, 
                      stamp      => cdfrec.stamp);
              end if;
 
              cdfrec.stamp := cdfrec.stamp + 1;
              krmicd.clearErrors;
              goto cdf_resync_again;
          end;
        end loop;
        low := high + 1;
     end loop;
  end if;
  dbms_rcvcat.endDataFileCopyResync;
 
  << skip_all_dfcopy_resync >>
 
  recid := dbms_rcvcat.beginCopyCorruptionResync;
  deb('resync', 'Copy Corruption last recid '||recid||
      '; high '||high_cc_recid, dbtype);
  if (high_cc_recid > recid) then
     select record_size into rec_size
       from v$controlfile_record_section
      where type='COPY CORRUPTION';
 
     high := recid;
     low := recid + 1;
     rec_per_chunk := floor(sort_area_size / rec_size);
     total_recs := high_cc_recid - low + 1;
     deb_sort_area(high_cc_recid);
     while (high < high_cc_recid) loop
        high := least(low + rec_per_chunk -1, high_cc_recid);
        for ccbrec in ccb(low, high) loop
           deb('resync', 'Calling checkCopyCorruption for file '||ccbrec.file#
                         ||' recid '||ccbrec.copy_recid, dbtype);
           dbms_rcvcat.checkCopyCorruption(ccbrec.recid, ccbrec.stamp,
              ccbrec.copy_recid, ccbrec.copy_stamp,
              ccbrec.file#, ccbrec.block#, ccbrec.blocks,
              ccbrec.corruption_change#, ccbrec.marked_corrupt,
              ccbrec.corruption_type);
        end loop;
        low := high + 1;
     end loop;
  end if;
  dbms_rcvcat.endCopyCorruptionResync;
 
  select record_size,
         decode(records_used, 0, 0, last_recid + 1 - records_used) old_recid,
         last_recid
    into rec_size, low_bcr_recid, high_bcr_recid
   from v$controlfile_record_section
  where type='DATABASE BLOCK CORRUPTION';
  recid := dbms_rcvcat.beginBlockCorruptionResync(low_bcr_recid);
  deb('resync', 'Block Corruption last recid '||recid||
      '; low ' ||low_bcr_recid || ';high '||high_bcr_recid, dbtype);
  if (high_bcr_recid > recid) then
     high := recid;
     low := recid + 1;
     rec_per_chunk := floor(sort_area_size / rec_size);
     total_recs := high_bcr_recid - low + 1;
     deb_sort_area(high_bcr_recid);
     while (high < high_bcr_recid) loop
        high := least(low + rec_per_chunk -1, high_bcr_recid);
        for bcrrec in bcr(low, high) loop
           deb('resync', 'Calling checkBlockCorruption for'
                         ||' recid '           || bcrrec.recid 
                         ||' stamp '           || bcrrec.stamp
                         ||' file# '           || bcrrec.file#
                         ||' block# '          || bcrrec.block#
                         ||' blocks '          || bcrrec.blocks,
                         dbtype);
           dbms_rcvcat.checkBlockCorruption(bcrrec.recid, bcrrec.stamp,
              bcrrec.file#, bcrrec.create_scn, bcrrec.create_time,
              bcrrec.block#, bcrrec.blocks, bcrrec.corrupt_scn,
              bcrrec.corruption_type);
        end loop;
        low := high + 1;
     end loop;
  end if;
  dbms_rcvcat.endBlockCorruptionResync;
 
  recid := dbms_rcvcat.beginDeletedObjectResync;
  deb('resync', 'DeletedObject last recid '||recid|| '; high '||high_dl_recid,
      dbtype);
  if (high_dl_recid > recid) then
     select record_size into rec_size
       from v$controlfile_record_section
      where type='DELETED OBJECT';
 
     high := recid;
     low := recid + 1;
     rec_per_chunk := floor(sort_area_size / rec_size);
     total_recs := high_dl_recid - low + 1;
     deb_sort_area(high_dl_recid);
     while (high < high_dl_recid) loop
        high := least(low + rec_per_chunk -1, high_dl_recid);
        for dlrec in dl(low, high) loop
           if (dlrec.object_type = 'INSTANT RESTORE') then
              dlrec.object_fname :=
                           sys.dbms_backup_restore.getParm(
                                      sys.dbms_backup_restore.BACKING_FILENAME,
                                      dlrec.object_data);
           end if;
           deb('resync', 'Calling checkDeletedObject for recid '||
               dlrec.recid                 ||' object type '    ||
               dlrec.object_type           ||' with count '     ||
               dlrec.object_recid          ||' and stamp '      ||
               dlrec.object_stamp          ||' and data '       ||
               dlrec.object_data           ||' and set_stamp '  ||
               nvl(to_char(dlrec.set_stamp), 'NULL') ||' and set_count '  ||
               nvl(to_char(dlrec.set_count), 'NULL') ||' and create_scn ' ||
               nvl(to_char(dlrec.object_create_scn), 'NULL'), dbtype);
           dbms_rcvcat.checkDeletedObject(
              dlrec.recid, dlrec.stamp,
              dlrec.object_type, dlrec.object_recid, dlrec.object_stamp,
              dlrec.object_data,
              dlrec.object_fname,
              dlrec.object_create_scn,
              dlrec.set_stamp,
              dlrec.set_count);
        end loop;
        low := high + 1;
     end loop;
  end if;
  dbms_rcvcat.endDeletedObjectResync;
 
  if resync_2_AMSchema = 1 and oam_tst_level >= 1 then
     deb('resync', 'oam_tst_level:Skipping resync of all proxy backup records',
         dbtype);
     goto skip_all_proxy_resync;
  end if;
 
  recid := dbms_rcvcat.beginProxyResync;
  deb('resync', 'ProxyResync last recid '||recid|| '; high '||high_pc_recid,
      dbtype);
 
  if (high_pc_recid > recid) then
     select record_size into rec_size
       from v$controlfile_record_section
      where type='PROXY COPY';
 
     high := recid;
     low := recid + 1;
     rec_per_chunk := floor(sort_area_size / rec_size);
     total_recs := high_pc_recid - low + 1;
     deb_sort_area(high_pc_recid);
     while (high < high_pc_recid) loop
        high := least(low + rec_per_chunk - 1, high_pc_recid);
        for xdfrec in xdf(low, high) loop
          << xdf_resync_again >>
          begin
           deb('resync', 'Calling checkProxyDataFile for '|| xdfrec.handle ||
                         ' recid ' || xdfrec.recid, dbtype);
           deb('resync', '  file# '||xdfrec.file#|| ' status '||xdfrec.status,
               dbtype);
           dbms_rcvcat.checkProxyDataFile(xdfrec.recid,
                                          xdfrec.stamp,
                                          xdfrec.tag,
                                          xdfrec.file#,
                                          xdfrec.create_scn,
                                          xdfrec.create_time,
                                          xdfrec.reset_scn,
                                          xdfrec.reset_time,
                                          xdfrec.incr_level,
                                          xdfrec.ckp_scn,
                                          xdfrec.ckp_time,
                                          xdfrec.online_fuzzy,
                                          xdfrec.backup_fuzzy,
                                          xdfrec.abs_fuzzy_scn,
                                          xdfrec.rcv_fuzzy_scn,
                                          xdfrec.rcv_fuzzy_time,
                                          xdfrec.blocks,
                                          xdfrec.block_size,
                                          xdfrec.oldest_offline_range,
                                          xdfrec.device_type,
                                          xdfrec.handle,
                                          xdfrec.comments,
                                          xdfrec.media,
                                          xdfrec.media_pool,
                                          xdfrec.start_time,
                                          xdfrec.completion_time,
                                          xdfrec.status,
                                          xdfrec.controlfile_type,
                                          xdfrec.keep_options,
                                          xdfrec.keep_until,
                                          xdfrec.rman_status_recid,
                                          xdfrec.rman_status_stamp,
                                          xdfrec.foreign_dbid,
                                          xdfrec.plugged_readonly,
                                          xdfrec.plugin_change#,
                                          xdfrec.plugin_resetlogs_change#,
                                          xdfrec.plugin_resetlogs_time,
                                          xdfrec.guid,
                                          xdfrec.dropped_pdb);
          exception
            when change_record_stamp then
              deb('resync', 'got exception: Changing stamp for this record');
              if for_dbuname is not null then
                 null_retVal := 
                    sys.dbms_backup_restore.remoteSQLExecute(
                       source_dbuname => for_dbuname, 
                       source_cs      => source_cs,
                       stmt           => 
                         'begin ' ||
                         ' sys.dbms_backup_restore.IncrementRecordStamp(' ||
                         '    rectype => ' || 
                         '     sys.dbms_backup_restore.RTYP_PROXY ' ||
                         '  , recid   => ' || xdfrec.recid ||
                         '  , stamp   => ' || xdfrec.stamp ||
                         '    ); ' ||
                         'end;');
              else
                 sys.dbms_backup_restore.IncrementRecordStamp(
                      rectype    => sys.dbms_backup_restore.RTYP_PROXY,
                      recid      => xdfrec.recid, 
                      stamp      => xdfrec.stamp);
              end if;
 
              xdfrec.stamp := xdfrec.stamp + 1;
              krmicd.clearErrors;
              goto xdf_resync_again;
          end;
        end loop;
 
        for xalrec in xal(low, high) loop
          << xal_resync_again >>
          begin
           deb('resync', 'Calling checkProxyArchivedLog for '|| xalrec.handle,
               dbtype);
           deb('resync', '  thread# ' || xalrec.thread# ||
               ' sequence# ' || xalrec.sequence# || ' status ' ||
               xalrec.status || '  recid ' || xalrec.recid, dbtype);
           dbms_rcvcat.checkProxyArchivedLog(xalrec.recid,
                                             xalrec.stamp,
                                             xalrec.tag,
                                             xalrec.thread#,
                                             xalrec.sequence#,
                                             xalrec.resetlogs_change#,
                                             xalrec.resetlogs_time,
                                             xalrec.first_change#,
                                             xalrec.first_time,
                                             xalrec.next_change#,
                                             xalrec.next_time,
                                             xalrec.blocks,
                                             xalrec.block_size,
                                             xalrec.device_type,
                                             xalrec.handle,
                                             xalrec.comments,
                                             xalrec.media,
                                             xalrec.media_pool,
                                             xalrec.start_time,
                                             xalrec.completion_time,
                                             xalrec.status,
                                             xalrec.rman_status_recid,
                                             xalrec.rman_status_stamp,
                                             xalrec.terminal,
                                             xalrec.keep_until,
                                             xalrec.keep_options);
          exception
            when change_record_stamp then
              deb('resync', 'got exception: Changing stamp for this record');
              if for_dbuname is not null then
                 null_retVal := 
                    sys.dbms_backup_restore.remoteSQLExecute(
                       source_dbuname => for_dbuname, 
                       source_cs      => source_cs,
                       stmt           => 
                         'begin ' ||
                         ' sys.dbms_backup_restore.IncrementRecordStamp(' ||
                         '    rectype => ' || 
                         '     sys.dbms_backup_restore.RTYP_PROXY ' ||
                         '  , recid   => ' || xalrec.recid ||
                         '  , stamp   => ' || xalrec.stamp ||
                         '    ); ' ||
                         'end;');
              else
                 sys.dbms_backup_restore.IncrementRecordStamp(
                      rectype    => sys.dbms_backup_restore.RTYP_PROXY,
                      recid      => xalrec.recid, 
                      stamp      => xalrec.stamp);
              end if;
 
              xalrec.stamp := xalrec.stamp + 1;
              krmicd.clearErrors;
              goto xal_resync_again;
          end;
        end loop;
 
        low := high + 1;
     end loop;
  end if;
  dbms_rcvcat.endProxyResync;
 
  << skip_all_proxy_resync >>
  << skip_circular_section_resync >>
 
--
--
  if (releasecf) then
    sys.dbms_backup_restore.cfileUseCurrent;
    releasecf := FALSE;
  end if;
 
--
  if (ret = CONFIGRESYNC_TOCF OR ret = CONFIGRESYNC_TORC_TOCF) then
      resyncConf2ControlFile(for_dbuname, source_cs);
  end if;
 
--
--
--
--
--
--
--
  if for_dbuname is null and 
     (ret = CONFIGRESYNC_TOCF OR ret = CONFIGRESYNC_TORC_TOCF) then
       resyncConf2Catalog(cf_type, TRUE);
  end if;
  dbms_rcvcat.endConfigResync2;
 
  deb('resync', 'Calling getPolledRec', dbtype);
  while (dbms_rcvcat.getPolledRec(lrec_type, lrecid, lstamp, lfname)) loop
     deb('resync', 'BA Polled ' || lfname, dbtype);
     sys.dbms_backup_restore.OAMPolledRecord(
          rectype    => lrec_type,
          recid      => lrecid, 
          stamp      => lstamp);
  end loop;
 
 
  deb('resync', 'Calling sanityCheck', dbtype);
  dbms_rcvcat.sanityCheck;
 
  deb('resync', 'Calling endCkpt', dbtype);
  dbms_rcvcat.endCkpt;
 
  if (auto_prim_resync) then
     krmicd.writeMsg(8244);
     auto_prim_resync := FALSE;
     for_dbuname := null;
     cf_type := null;
--
     read_retries := 0;
     busy_retries := 0;
     sort_retries := 0;
     callSetDatabase := TRUE;
     if (sync_retries < 2 and is_19871_L0_set) then
        null_retVal := sys.dbms_backup_restore.remoteSQLExecute(
              source_dbuname => for_dbuname,
              source_cs      => source_cs,
              stmt           => 'alter system archive log current');
        sys.dbms_backup_restore.sleep(10);
     end if;
     goto restart_resync;
  elsif (full_resync) then
     krmicd.writeMsg(8004);
  else
     if not implicit then
        krmicd.writeMsg(8245);
     end if;
  end if;
 
  exited('resync', 'OK');
exception
  when need_primary_resync then
    if sync_retries < 5 then
      krmicd.writeErrMsg(1005, sqlerrm);
      krmicd.writeMsg(8246);
      sync_retries := sync_retries + 1;
      dbms_rcvcat.cancelCkpt;
      auto_prim_resync := TRUE;
      cf_type := null;
--
      read_retries := 0;
      busy_retries := 0;
      sort_retries := 0;
      pdb_dict_check_sby.delete;
      krmicd.clearErrors;
      goto restart_resync;
    else
      dbms_rcvcat.cancelCkpt;
      raise;
    end if;
  when sort_area_too_small then
    if (sort_retries < 5) then
      sort_retries := sort_retries + 1;
      krmicd.writeMsg(1005,
        'resync got ORA'||to_char(sqlcode)||
        ', retrying with sort_area_size = '||
        to_char((sort_area_size + sort_area_size_incr) / 1048576)||
        'MB');
      sort_area_size := set_sort_area_size(sort_area_size +
                                           sort_area_size_incr);
      goto retry;
    else
      dbms_rcvcat.cancelCkpt;
      krmicd.writeMsg(1005, 'resync got ORA-'||to_char(sqlcode)||
                          ', giving up');
      exited('resync', 'sort_area_too_small');
      raise;
    end if;
--
--
--
  when sys.dbms_backup_restore.inconsistant_read then
--
    if (read_retries < 5) then
      read_retries := read_retries + 1;
      krmicd.writeMsg(1005,
                      'resync got ORA-235, retry '||to_char(read_retries));
      krmicd.clearErrors;
      krmicd.sleep(10*read_retries);
      goto retry;
    else
      dbms_rcvcat.cancelCkpt;
      krmicd.writeMsg(1005, 'resync got ORA-235, giving up');
      exited('resync', 'inconsistant_read');
      raise;
    end if;
  when resync_not_needed then
    dbms_rcvcat.cancelCkpt;
    if (releasecf) then
      sys.dbms_backup_restore.cfileUseCurrent;
      releasecf := FALSE;
    end if;
    if ignore_resync_err then
      deb('resync', 'Ignoring resync error RMAN-20034');
      krmicd.clearErrors;
    else
      raise;
    end if;
  when setstamp_setcount_conflict then
    dbms_rcvcat.cancelCkpt;
    if (releasecf) then
      sys.dbms_backup_restore.cfileUseCurrent;
      releasecf := FALSE;
    end if;
    if (curr_set_stamp = 0 AND curr_set_count = 0) then
      exited('resync', 'invalid_set_stamp set_count conflict');
      krmicd.SignalErrMsg(20111);
    else
      display_uncatalog_bp(curr_set_stamp, curr_set_count);
      exited('resync', 'set_stamp set_count conflict');
      raise;
    end if;
  when others then
    dbms_rcvcat.cancelCkpt;
    if (releasecf) then
      sys.dbms_backup_restore.cfileUseCurrent;
      releasecf := FALSE;
    end if;
    exited('resync', 'ORA-'||to_char(sqlcode));
    raise;
end;
end;
>>>
 
define devalloc
<<<
--
declare
  devtype       varchar2(255);
  chid          varchar2(255);
  debug         varchar2(10) := null;
  options       number := null;
  node          varchar2(255);
  maxsize       number;
  kbytes        number := null;
  parallel      binary_integer := null;
  readrate      number := null;
  rate          number := null;
  sendcmd       varchar2(256);
  vendor        varchar2(256);
  israc         boolean;
  instname      varchar2(17);
  isfirst       boolean;
  wait          boolean;
  wait_msg_dis  boolean := false;
  num_sbt_chns  number;
  error_str     varchar2(256);
  oam_job_id    varchar2(256);
  request_time  date;
  oam_tst_level number;
  vendortype    number := 0;
begin
  &object&
  if debug is not null then
    krmicd.execSql(
           'alter session set events ''trace[krb.*] disk='
           ||debug|| ', memory=' ||debug||'''');
  end if;
  if options is not null then
    krmicd.execSql(
           'alter session set events ''immediate trace name krb_options level '
           ||options||'''');
  end if;
  devtype := sys.dbms_backup_restore.deviceAllocate( ident => chid,
       node => node, &args& );
  if kbytes is null then
     maxsize := sys.dbms_backup_restore.deviceQuery
       (sys.dbms_backup_restore.DEVICEQUERY_MAXSIZE);
  else
     maxsize := kbytes;
  end if;
  if maxsize > 0 then
     sys.dbms_backup_restore.setlimit
       (sys.dbms_backup_restore.kbytes, maxsize);
  end if;
  if devtype = 'SBT_TAPE' then
     vendortype := to_number(sys.dbms_backup_restore.deviceQuery
       (sys.dbms_backup_restore.DEVICEQUERY_VENDORTYPE));
  end if; 
  krmicd.setChannelInfo
    (devtype,
     node,
     maxsize,
     sys.dbms_backup_restore.deviceQuery
       (sys.dbms_backup_restore.DEVICEQUERY_PROXY),
     sys.dbms_backup_restore.deviceQuery
       (sys.dbms_backup_restore.DEVICEQUERY_MAXPROXY), vendortype);
  if parallel is not null then
     sys.dbms_backup_restore.setlimit
       (sys.dbms_backup_restore.parallel, parallel);
  end if;
  if readrate is not null then
     sys.dbms_backup_restore.setlimit
       (sys.dbms_backup_restore.readrate, readrate);
  end if;
  if rate is not null then
     sys.dbms_backup_restore.setlimit
       (sys.dbms_backup_restore.max_read_kbytes, rate);
  end if;
  if sendcmd is not null then
     sys.dbms_backup_restore.devicecommand(sendcmd, NULL);
  end if;
  krmicd.writeMsg(8030, chid);
  krmicd.getInstance(instname, israc);
  if (israc) then
     krmicd.writeMsg(8605, chid, to_char(krmicd.getSid),
                     to_char(instname), devtype);
  else
     krmicd.writeMsg(8500, chid, to_char(krmicd.getSid), devtype);
  end if;
  vendor := sys.dbms_backup_restore.deviceQuery
    (sys.dbms_backup_restore.DEVICEQUERY_VENDOR);
  if vendor is not null then
     krmicd.writemsg(8526, chid, vendor);
  end if;
  if (oam_tst_level > 0 and
      (vendortype = sys.dbms_backup_restore.DEVICEQUERY_BA) ) then
--
    sys.dbms_backup_restore.setParms(p0 => 14,
                                     p1 => 1);
  end if;
 
%IF% catalog
  if (vendortype = sys.dbms_backup_restore.DEVICEQUERY_BA) then
     krmicd.getChannelInfo(chid, isfirst);
     if isfirst then
        request_time := sysdate;
        oam_job_id   := to_char(krmicd.getSid) ||
                        to_char(sysdate, 'hh24mmssddmmyyyy');
 
        wait    := true;
        num_sbt_chns := krmicd.getSBTParallelism;
        while wait loop
           dbms_rcvcat.throttle_me(oam_job_id, num_sbt_chns,
                                   request_time, wait, error_str);
           if error_str is not null then
              krmicd.SignalErrMsg(1004, error_str);
           elsif wait then
              krmicd.writeMsg(8629, to_char(num_sbt_chns));
              wait_msg_dis := true;
              krmicd.sleep(60);
           else
              if wait_msg_dis then
                 krmicd.writeMsg(8630);
              end if;
           end if;
        end loop;
     end if;
  end if;
%ENDIF% catalog
 
%IF% target
--
--
  if (vendortype = sys.dbms_backup_restore.DEVICEQUERY_BA) then
     krmicd.writeMsg(6918);
  end if;
%ENDIF% target
 
end;
>>>
 
define devrel
<<<
--
begin
  sys.dbms_backup_restore.deviceDeallocate;
  sys.dbms_backup_restore.set_client_info('');
  krmicd.writeMsg(8031, krmicd.getChid);
  krmicd.clearChannelInfo;                      -- tell krmq no device here now
end;
>>>
 
define setlm
<<<
begin
>>>
 
define 'kbytes'
<<<
  sys.dbms_backup_restore.setLimit(
    sys.dbms_backup_restore.kbytes,&args&);
>>>
 
define 'rate'
<<<
  sys.dbms_backup_restore.setLimit(
    sys.dbms_backup_restore.max_read_kbytes,&args&);
>>>
 
define 'readrate'
<<<
  sys.dbms_backup_restore.setLimit(
    sys.dbms_backup_restore.readrate,&args&);
>>>
 
define 'parallel'
<<<
  sys.dbms_backup_restore.setLimit(
    sys.dbms_backup_restore.parallel,&args&);
>>>
 
define setlmend
<<<
end;
>>>
 
define 'change'
<<<
--
declare
   found       boolean;
   mismatch    boolean;
   anymiss     boolean := FALSE;
   runatsite   boolean := FALSE;
   ocount      number := 0;
   mcount      number := 0;
   rscount     number := 0;
   rc          number;
   rc_in_use   number;
   msg         number;
 
   /* about the object */
   new_status  varchar2(1);
   old_status  varchar2(1);
   ba_access   varchar2(1);
   objectType  number;
   handle      varchar2(512);
   recid       number;
   stamp       number;
   obj_key1    number;
   obj_key2    number;
   pieceno     number;
   blksize     number;
   rlscn       number;
   rlstime     date;
   crescn      number;
   ckpscn      number;
   new_fname   varchar2(512);
   cmdmsg      number;
   cmdtxt      varchar2(32);
   new_recid   number;
   new_stamp   number;
   obj_typen   varchar2(20);
   devtype     varchar2(20);
   devicetype  varchar2(20);
   writeflag   binary_integer;
   dummy       binary_integer;
   keep_until_d date := NULL;
   force       binary_integer;
   hdl_isdisk  binary_integer;
   site_key    number;
   this_site_key number := 0;
   nsite_key number := 0;
   source_dbid number;
   vbkey       number := 0;
   foreignal   binary_integer;
   to_db_unique_name varchar2(30);
   pdbid       number;
   pplcdbdbid  number;
   ppltrans    number;
 
--
--
&constants&
--
   dexpired_exists       exception;
   internal_error        exception;
   pragma exception_init(dexpired_exists,       -20502);
   pragma exception_init(internal_error,        -600);
begin
   &1&
   entered('change');
   deb('change', 'started, command:'||cmd);
   select decode(cmd,
                    krmiAVAIL,    6200,
                    krmiDELETE,   6201,
                    krmiDEXPIRED, 6202,
                    krmiKEEP,     6203,
                    krmiUAVAIL,   6204,
                    krmiUNCAT,    6205,
                    krmiXCHECK,   6206)
     into cmdmsg
     from x$dual;
 
   select decode(cmd,
                    krmiAVAIL,    'CHANGE AVAILABLE',
                    krmiDELETE,   'DELETE',
                    krmiDEXPIRED, 'DELETE',
                    krmiXCHECK,   'CROSSCHECK',
                                  'UNKNOWN')
     into cmdtxt
     from x$dual; 
 
   devicetype := NULL;
 
%IF% catalog
   this_site_key := dbms_rcvcat.getThisSiteKey;
   nsite_key     := dbms_rcvcat.getThisSiteKey(to_db_unique_name);
   deb('change', 'this_site_key=' || this_site_key);
   deb('change', 'nsite_key=' || nsite_key);
%ENDIF% catalog
 
   loop
      found := FALSE;
      mismatch := FALSE;
      rc_in_use := 0;
      vbkey := 0;
 
--
      krmicd.changeGetNext(objectType, handle, recid, stamp,
                           obj_key1, obj_key2, pieceno, blksize,
                           ckpscn, rlscn, rlstime, crescn, old_status, 
                           devtype, site_key, source_dbid, vbkey, ba_access,
                           pdbid, pplcdbdbid);
 
      deb('change', 'File  '|| handle || ' belongs to ' ||site_key);
      deb('change', 'File  '|| handle || ' virtual key '||vbkey);
      deb('change', 'File  '|| handle || ' ba_access '  ||ba_access);
      deb('change', 'Pdbid '|| pdbid  || ' pplcdbdbid ' || pplcdbdbid);
 
%IF% catalog
--
--
--
--
--
      if site_key = 0 and this_site_key <> 0 then
         site_key := this_site_key;
         deb('change', 'updated site_key to '|| site_key);
      end if;
%ENDIF% catalog
      exit when objectType = 0;
 
      if old_status != 'X' and cmd = krmiDEXPIRED then
         krmicd.writeMsg(1005, 'INTERNAL ERROR: Available object during '||
                               'DELETE EXPIRED');
         raise internal_error;
      end if;
 
      if nforce = 1 or (old_status = 'U' and cmd = krmiDELETE) then
         force := 1;
      else
         force := 0;
      end if;
 
      if devtype = 'DISK' then
        hdl_isdisk := 1;
      else
        hdl_isdisk := 0;
      end if;
 
      if devicetype is NULL and devtype is not NULL then
         devicetype := devtype;
      end if;
 
      deb('change', ' processing (file/handle='||handle||','||
          'recid='||to_char(recid)||', old_status='||old_status||
          ', hdl_isdisk=' || hdl_isdisk || ', devicetype=' ||
           nvl(devicetype, 'NULL') ||  ', source_dbid=' ||
           source_dbid || ')');
      deb('change',' force: '||force);
 
      if objectType = krmiBPIECEX then
         obj_typen := 'Backup Piece';
      elsif objectType = krmiPC then
         obj_typen := 'Proxy Copy';
      elsif objectType = krmiDC then
         if (obj_key1 = 0) then
            obj_typen := 'Control File Copy';
         else
            obj_typen := 'Datafile Copy';
         end if;
      elsif objectType = krmiRAL then
         if (source_dbid = 0) then
            obj_typen := 'Archivelog';
            foreignal  := 0;
         else
            obj_typen := 'Foreign Archivelog';
            foreignal  := 1;
         end if;
      elsif objectType = krmiBS then
         obj_typen := 'Backup Set';
      else
         krmicd.writeMsg(1005, 'INTERNAL ERROR: unexpected objectType='||
                         to_char(objectType));
         raise internal_error;
      end if;
 
      if cmd in (krmiUAVAIL, krmiUNCAT, krmiKEEP, krmiRESETDBUN) then
--
--
--
--
--
--
--
         found := TRUE;
      else
--
--
         begin
            ppltrans := sys.dbms_backup_restore.beginPrePluginTranslation(
                           pdbid => pdbid, pplcdbdbid => pplcdbdbid);
            if objectType = krmiBPIECEX then
               deb('change', 'Calling ValidateBackupPiece for '||handle);
               rc := sys.dbms_backup_restore.validateBackupPiece(
                  recid      => recid,
                  stamp      => stamp,
                  handle     => handle,
                  set_stamp  => obj_key2,
                  set_count  => obj_key1,
                  pieceno    => pieceno,
                  hdl_isdisk => hdl_isdisk);
            elsif objectType = krmiPC then
               deb('change', 'Calling proxyValOnly for '||handle);
               rc := sys.dbms_backup_restore.proxyValOnly(
                  recid  => recid,
                  stamp  => stamp,
                  handle => handle);
            elsif objectType = krmiDC then
               deb('change', 'Calling ValidateDataFileCopy for '||handle);
               rc := sys.dbms_backup_restore.validateDataFileCopy(
                  recid             => recid,
                  stamp             => stamp,
                  fname             => handle,
                  dfnumber          => obj_key1,
                  resetlogs_change  => rlscn,
                  creation_change   => crescn,
                  checkpoint_change => ckpscn,
                  blksize           => blksize,
                  signal            => 0);
            elsif objectType = krmiRAL then
               deb('change', 'Calling ValidateArchivedLog for '||handle);
               rc := sys.dbms_backup_restore.validateArchivedLog(
                  recid             => recid,
                  stamp             => stamp,
                  fname             => handle,
                  thread            => obj_key1,
                  sequence          => obj_key2,
                  resetlogs_change  => rlscn,
                  first_change      => crescn,
                  blksize           => blksize,
                  signal            => 0,
                  terminal          => 0,
                  foreignal         => foreignal);
            end if;
            if (ppltrans > 0) then
               sys.dbms_backup_restore.endPrePluginTranslation;
            end if;
         exception
            when others then
               if implicit != 0 then
--
--
                  rc := sys.dbms_backup_restore.validate_file_different;
                  krmicd.writeErrMsg(1005, sqlerrm);
                  krmicd.clearErrors;
               elsif force = 0 then
                  raise;
               else     
                  krmicd.clearErrors;
               end if;
         end;
         deb('change', 'file '||handle||', rc='||rc);
         rc_in_use := bitand(rc, sys.dbms_backup_restore.validate_in_use);
         rc := bitand(rc, sys.dbms_backup_restore.validate_file_different);
         deb('change', 'file '||handle||', Modified rc='||rc||
             ' rc_in_use='||rc_in_use);
         if rc = 0 and rc_in_use = 0 then
            found := TRUE;
         end if;
      end if;
 
      deb('change', 'file '||handle||', found='||bool2char(found));
 
      if krmicd.changeSetFound(found) then 
         if found then
            deb('change', 'file '||handle||' in found');
            if cmd in (krmiDELETE, krmiDEXPIRED) and old_status = 'X' then
               deb('change', 'file '||handle||'mismatched due to X');
               mismatch := TRUE;
--
--
            end if;
         else
            if rc_in_use != 0 then
               deb('change', 'cannot validate file:'||handle||
                             ', in use by another process');
               if force = 0 then
                  krmicd.writeMsg(8167, cmdtxt);
                  krmicd.writeMsg(8517, handle, to_char(recid), to_char(stamp));
                  goto next_object;
               end if;
            end if;
            if cmd = krmiAVAIL then
               deb('change', 'file '||handle||' not found in AVAIL');
               if objectType = krmiBPIECEX then
                  krmicd.writeMsg(6481, handle);
               elsif objectType = krmiPC then
                  krmicd.writeMsg(6482, handle);
               elsif objectType = krmiDC then
                  if obj_key1 = 0 then
                     krmicd.writeMsg(6479, handle);
                  else
                     krmicd.writeMsg(6478, handle);
                  end if;
               elsif objectType = krmiRAL then
                  krmicd.writeMsg(6480, handle);
               end if;
--
--
               ocount := ocount - 1;
            elsif cmd = krmiDELETE then
               deb('change', 'file '||handle||' not found in DELETE');
               if old_status = 'A' then
                  mismatch := TRUE;
               end if;
            else
               deb('change', 'file '||handle||' not found for cmd '||cmd);
            end if;
         end if;
 
         deb('change', 'file '||handle||' mismatch: '||bool2char(mismatch)||
                       ' force: '||force|| ' rc_in_use: '||rc_in_use );
         if mismatch and force = 0 then
--
            krmicd.mismatchObj(obj_typen, handle, site_key);
            anymiss := TRUE;
            mcount := mcount + 1;
            goto next_object;
         end if;
 
--
         if cmd in (krmiXCHECK, krmiAVAIL) then
            if found then
               new_status := 'A';
            else
               new_status := 'X';
            end if;
         elsif cmd in (krmiDEXPIRED, krmiDELETE) then
            new_status := 'D';
         elsif cmd = krmiUNCAT then
            new_status := 'R';
         elsif cmd = krmiUAVAIL then
            new_status := 'U';
         elsif cmd = krmiRESETDBUN then
            new_status := old_status;
         elsif cmd = krmiKEEP then
--
            new_status := 'K';
            keep_until_d := stamp2date(keep_until);
         else
            krmicd.writeMsg(1005,'INTERNAL ERROR: unknown cmd='||to_char(cmd));
            raise internal_error;
         end if;
 
--
--
--
         if cmd in (krmiXCHECK, krmiAVAIL) then
            if not found and site_key <> this_site_key then
               deb('change','file ' || handle || 
                            ' must be crosschecked at site ' || site_key);
               krmicd.runAtSiteObj(obj_typen, handle, site_key);
               runatsite := TRUE;
               rscount := rscount + 1;
               goto next_object;
            end if;
         end if;
 
--
--
--
         if cmd in (krmiDEXPIRED, krmiDELETE) then
            if not found and site_key <> this_site_key then
               deb('change','file ' || handle || 
                            ' must be deleted at site ' || site_key);
               krmicd.runAtSiteObj(obj_typen, handle, site_key);
               runatsite := TRUE;
               rscount := rscount + 1;
               goto next_object;
            end if;
         end if;
 
--
--
--
         if objectType = krmiBS and cmd = krmiKEEP and vbkey != 0 then
            krmicd.writeMsg(1005, 'Not Supported on Recovery Appliance ');
            krmicd.writeMsg(1005, 'Cannot do KEEP on virtual backups');
            goto next_object;
         elsif objectType = krmiBS then
%IF% catalog
            if (cmd = krmiRESETDBUN AND
                (site_key is null or site_key <> nsite_key)) then
               dbms_rcvcat.changeBackupSet(
                  recid          => recid,
                  stamp          => stamp,
                  keep_options   => keep_options,
                  keep_until     => keep_until_d,
                  osite_key      => site_key,
                  nsite_key      => nsite_key);
            end if;
%ENDIF% catalog
            if dbnomount = 0 then
               ppltrans := sys.dbms_backup_restore.beginPrePluginTranslation(
                              pdbid => pdbid, pplcdbdbid => pplcdbdbid);
               sys.dbms_backup_restore.changeBackupSet(
                  recid         => recid,
                  stamp         => stamp,
                  set_count     => obj_key1,
                  keep_options  => keep_options,
                  keep_until    => keep_until);
               if (ppltrans > 0) then
                  sys.dbms_backup_restore.endPrePluginTranslation;
               end if;
%IF% catalog
            else
               dbms_rcvcat.changeBackupSet(
                  recid          => recid,
                  stamp          => stamp,
                  keep_options   => keep_options,
                  keep_until     => keep_until_d);
%ENDIF% catalog
            end if;
            if cmd = krmiKEEP then
                if keep_options = 0 then
--
                   krmicd.writeMsg(8121);
                else
--
                   krmicd.writeMsg(8122);
                   if keep_until > 0 then
                      krmicd.writeMsg(6518, to_char(keep_until_d));
                   else
                      krmicd.writeMsg(6519);
                   end if;
 
                   if (keep_options = KEEP_LOGS) then
--
--
                      krmicd.writeMsg(6521);
                   elsif (keep_options = KEEP_NOLOGS) then
--
--
                      krmicd.writeMsg(6520);
                   elsif (keep_options != KEEP_CONSIST) then
--
                      krmicd.writeMsg(1005,
                             'INTERNAL ERROR: ' ||
                             'unexpected keep option for Backup Set');
                      raise internal_error;
                   end if;
                end if;
            else
               krmicd.writeMsg(1005,
                      'INTERNAL ERROR: unexpected cmd='||
                      to_char(cmd)||' for Backup Set');
               raise internal_error;
            end if;
            krmicd.writeMsg(8539, to_char(obj_key2),  -- set key
                                  to_char(recid),     -- set recid
                                  to_char(stamp));    -- set stamp
         elsif objectType = krmiBPIECEX then
%IF% catalog
            if (cmd = krmiRESETDBUN AND
                (site_key is null or site_key <> nsite_key)) then
              dbms_rcvcat.changeBackupPiece(
                 bp_recid  => recid,
                 bp_stamp  => stamp,
                 status    => new_status,
                 set_stamp => obj_key2,
                 set_count => obj_key1,
                 osite_key => site_key,
                 nsite_key => nsite_key);
            end if;
%ENDIF% catalog
            if  (old_status != new_status ) then
               if (vbkey != 0 or ba_access = 'L')
                   and (cmd = krmiAVAIL  or 
                        cmd = krmiUAVAIL or
                        cmd = krmiUNCAT) then
                  krmicd.writeMsg(1005, 'Not Supported on ' || 
                                  'Recovery Appliance ');
                  krmicd.writeMsg(1005, 'Cannot change availability ' || 
                                  'or uncatalog backup ' || handle);
                  goto next_object;
               elsif dbnomount = 0 then
                  ppltrans :=
                     sys.dbms_backup_restore.beginPrePluginTranslation(
                        pdbid => pdbid, pplcdbdbid => pplcdbdbid);
                  sys.dbms_backup_restore.changeBackupPiece(
                     recid     => recid,
                     stamp     => stamp,
                     handle    => handle,
                     set_stamp => obj_key2,
                     set_count => obj_key1,
                     pieceno   => pieceno,
                     status    => new_status,
                     force     => force);
                  if (ppltrans > 0) then
                     sys.dbms_backup_restore.endPrePluginTranslation;
                  end if;
%IF% catalog
               else
--
                  if dbnomount != 0 and new_status = 'D' and force = 0 then
                     ppltrans :=
                        sys.dbms_backup_restore.beginPrePluginTranslation(
                           pdbid => pdbid, pplcdbdbid => pplcdbdbid);
                     sys.dbms_backup_restore.changeBackupPiece(
                        recid     => recid,
                        stamp     => stamp,
                        handle    => handle,
                        set_stamp => obj_key2,
                        set_count => obj_key1,
                        pieceno   => pieceno,
                        status    => new_status,
                        force     => 1);
                     if (ppltrans > 0) then
                        sys.dbms_backup_restore.endPrePluginTranslation;
                     end if;
                  end if;
 
                  dbms_rcvcat.changeBackupPiece(
                     bp_recid  => recid,
                     bp_stamp  => stamp,
                     status    => new_status,
                     set_stamp => obj_key2,
                     set_count => obj_key1);
%ENDIF% catalog
               end if;
            else
               deb('change', 'file '||handle||
                   ' not updated on repository, old_status:'||old_status||
                   ' same as new_status:'||new_status||',site_key:'||site_key);
            end if;
            if cmd = krmiXCHECK then
               if found then
                  krmicd.writeMsg(8074, 'AVAILABLE');
               else
                  krmicd.writeMsg(8074, 'EXPIRED');
               end if;
            elsif cmd in (krmiDEXPIRED, krmiDELETE) then
               if (rc_in_use = 0 or (rc_in_use != 0 and force != 0)) then
                  krmicd.writeMsg(8073);
               end if;
            elsif cmd = krmiAVAIL then
               if found then
                  krmicd.writeMsg(6115);
               else
                  krmicd.writeMsg(6486);
               end if;
            elsif cmd = krmiUAVAIL then
               krmicd.writeMsg(6111);
            elsif cmd = krmiRESETDBUN then
               if (site_key is null or site_key <> nsite_key) then
                  krmicd.writeMsg(1005, 'change backup piece db_unique_name');
               end if;
            elsif cmd = krmiUNCAT then
               krmicd.writeMsg(8128);
            end if;
            if (rc_in_use = 0 or (rc_in_use != 0 and force != 0)) then
               krmicd.writeMsg(8517, handle, to_char(recid), to_char(stamp));
               ocount := ocount + 1;
            end if;
         elsif objectType = krmiPC then
%IF% catalog
            if (cmd = krmiRESETDBUN AND
                (site_key is null or site_key <> nsite_key)) then
               dbms_rcvcat.changeProxyCopy(
                  pc_recid      => recid,
                  pc_stamp      => stamp,
                  status        => new_status,
                  keep_options  => keep_options,
                  keep_until    => keep_until_d,
                  osite_key     => site_key,
                  nsite_key     => nsite_key);
            end if;
%ENDIF% catalog
            if (old_status != new_status) then
               if dbnomount = 0 then
                  ppltrans :=
                     sys.dbms_backup_restore.beginPrePluginTranslation(
                        pdbid => pdbid, pplcdbdbid => pplcdbdbid);
                  sys.dbms_backup_restore.proxyChange(
                     recid         => recid,
                     stamp         => stamp,
                     handle        => handle,
                     status        => new_status,
                     keep_options  => keep_options,
                     keep_until    => keep_until,
                     force         => force);
                  if (ppltrans > 0) then
                     sys.dbms_backup_restore.endPrePluginTranslation;
                  end if;
%IF% catalog
               else
                  dbms_rcvcat.changeProxyCopy(
                     pc_recid      => recid,
                     pc_stamp      => stamp,
                     status        => new_status,
                     keep_options  => keep_options,
                     keep_until    => keep_until_d);
%ENDIF% catalog
               end if;
            else
               deb('change', 'file '||handle||
                   ' not updated on repository, old_status:'||old_status||
                   'same as new_status:'||new_status||',site_key:'||site_key);
            end if;
            if cmd = krmiXCHECK then
               if found then
                  krmicd.writeMsg(6450, 'AVAILABLE');
               else
                  krmicd.writeMsg(6450, 'EXPIRED');
               end if;
            elsif cmd in (krmiDEXPIRED, krmiDELETE) then
               krmicd.writeMsg(6449);
            elsif cmd = krmiAVAIL then
               if found then
                  krmicd.writeMsg(6447);
               else
                  krmicd.writeMsg(6487);
               end if;
            elsif cmd = krmiUAVAIL then
               krmicd.writeMsg(6446);
            elsif cmd = krmiRESETDBUN then
               if (site_key is null or site_key <> nsite_key) then
                  krmicd.writeMsg(1005, 'change proxy copy db_unique_name');
               end if;
            elsif cmd = krmiUNCAT then
               krmicd.writeMsg(6448);
            elsif cmd = krmiKEEP then
                if keep_options = 0 then
--
                   krmicd.writeMsg(8125);
                else
--
                   krmicd.writeMsg(8126);
                   if keep_until > 0 then
                      krmicd.writeMsg(6518, to_char(keep_until_d));
                   else
                      krmicd.writeMsg(6519);
                   end if;
                   if keep_options = KEEP_LOGS then
--
--
                      krmicd.writeMsg(6521);
                   elsif keep_options = KEEP_NOLOGS then
--
--
                      krmicd.writeMsg(6520);
                   elsif keep_options = KEEP_CONSIST then
                      krmicd.writeMsg(1005,
                             'INTERNAL ERROR: ' ||
                             'unexpected keep option for Proxy Copy');
                      raise internal_error;
                   end if;
                end if;
            else
               krmicd.writeMsg(1005,
                      'INTERNAL ERROR: unexpected cmd='||
                      to_char(cmd)||' for Proxy Copy');
               raise internal_error;
            end if;
            krmicd.writeMsg(6451, handle, to_char(recid), to_char(stamp));
            ocount := ocount + 1;
         elsif objectType = krmiDC then
%IF% catalog
            if (cmd = krmiRESETDBUN AND
                (site_key is null or site_key <> nsite_key)) then
               dbms_rcvcat.changeDataFileCopy(
                  cdf_recid         => recid,
                  cdf_stamp         => stamp,
                  status            => new_status,
                  keep_options      => keep_options,
                  keep_until        => keep_until_d,
                  osite_key         => site_key,
                  nsite_key         => nsite_key);
            end if;
%ENDIF% catalog
            if (old_status != new_status) then
               if dbnomount = 0 then
                  ppltrans :=
                     sys.dbms_backup_restore.beginPrePluginTranslation(
                        pdbid => pdbid, pplcdbdbid => pplcdbdbid);
                  sys.dbms_backup_restore.changeDataFileCopy(
                     recid             => recid,
                     stamp             => stamp,
                     fname             => handle,
                     dfnumber          => obj_key1,
                     resetlogs_change  => rlscn,
                     creation_change   => crescn,
                     checkpoint_change => ckpscn,
                     blksize           => blksize,
                     new_status        => new_status,
                     keep_options      => keep_options,
                     keep_until        => keep_until,
                     force             => force);
                  if (ppltrans > 0) then
                     sys.dbms_backup_restore.endPrePluginTranslation;
                  end if;
%IF% catalog
               else
                  dbms_rcvcat.changeDataFileCopy(
                     cdf_recid         => recid,
                     cdf_stamp         => stamp,
                     status            => new_status,
                     keep_options      => keep_options,
                     keep_until        => keep_until_d);
%ENDIF% catalog
               end if;
            else
               deb('change', 'file '||handle||
                   ' not updated on repository, old_status:'||old_status||
                   'same as new_status:'||new_status||',site_key:'||site_key);
            end if;
            if cmd = krmiXCHECK then
               if found then
                  if obj_key1 = 0 then
                     krmicd.writeMsg(6156);
                  else
                     krmicd.writeMsg(6154);
                  end if;
               else
                  if obj_key1 = 0 then
                     krmicd.writeMsg(6155);
                  else
                     krmicd.writeMsg(6153);
                  end if;
               end if;
            elsif cmd in (krmiDEXPIRED, krmiDELETE) then
               if obj_key1 = 0 then
                  krmicd.writeMsg(8072);
               else
                  krmicd.writeMsg(8070);
               end if;
            elsif cmd = krmiAVAIL then
               if obj_key1 = 0 then
                  if found then
                     krmicd.writeMsg(6114);
                  else
                     krmicd.writeMsg(6484);
                  end if;
               else
                  if found then
                     krmicd.writeMsg(6112);
                  else
                     krmicd.writeMsg(6483);
                  end if;
               end if;
            elsif cmd = krmiUAVAIL then
               if obj_key1 = 0 then
                  krmicd.writeMsg(6110);
               else
                  krmicd.writeMsg(6108);
               end if;
            elsif cmd = krmiRESETDBUN then
               if (site_key is null or site_key <> nsite_key) then
                  if obj_key1 = 0 then
                     krmicd.writeMsg(1005, 
                        'change control file copy db_unique_name');
                  else
                     krmicd.writeMsg(1005, 
                        'change datafile copy db_unique_name');
                  end if;
               end if;
            elsif cmd = krmiUNCAT then
               if obj_key1 = 0 then
                  krmicd.writeMsg(6121);
               else
                  krmicd.writeMsg(6119);
               end if;
            elsif cmd = krmiKEEP then
                if keep_options = 0 then
--
                   krmicd.writeMsg(8123);
                else
--
                   krmicd.writeMsg(8124);
                   if keep_until > 0 then
                      krmicd.writeMsg(6512, to_char(keep_until_d));
                   else
                      krmicd.writeMsg(6513);
                   end if;
                   if keep_options = KEEP_LOGS then
--
--
                      krmicd.writeMsg(6515);
                   elsif keep_options = KEEP_NOLOGS then
--
--
                      krmicd.writeMsg(6514);
                   elsif keep_options != KEEP_CONSIST then
--
                      krmicd.writeMsg(1005,
                             'INTERNAL ERROR: ' ||
                             'unexpected keep option for Copy');
                      raise internal_error;
                   end if;
                end if;
            else
               krmicd.writeMsg(1005,
                      'INTERNAL ERROR: unexpected cmd='||
                      to_char(cmd)||' for Copy');
               raise internal_error;
            end if;
            if obj_key1 = 0 then
               krmicd.writeMsg(8516, handle, to_char(recid), to_char(stamp));
            else
               krmicd.writeMsg(8513, handle, to_char(recid), to_char(stamp));
            end if;
            ocount := ocount + 1;
         elsif objectType = krmiRAL then
%IF% catalog
            if (cmd = krmiRESETDBUN AND
                (site_key is null or site_key <> nsite_key)) then
               dbms_rcvcat.changeArchivedLog(
                  al_recid          => recid,
                  al_stamp          => stamp,
                  status            => new_status,
                  osite_key         => site_key,
                  nsite_key         => nsite_key);
            end if;
%ENDIF% catalog
            if (old_status != new_status) then
               if dbnomount = 0 then
                  ppltrans :=
                     sys.dbms_backup_restore.beginPrePluginTranslation(
                        pdbid => pdbid, pplcdbdbid => pplcdbdbid);
                  sys.dbms_backup_restore.changeArchivedLog(
                     recid             => recid,
                     stamp             => stamp,
                     fname             => handle,
                     thread            => obj_key1,
                     sequence          => obj_key2,
                     resetlogs_change  => rlscn,
                     first_change      => crescn,
                     blksize           => blksize,
                     new_status        => new_status,
                     force             => force,
                     foreignal         => foreignal);
                  if (ppltrans > 0) then
                     sys.dbms_backup_restore.endPrePluginTranslation;
                  end if;
%IF% catalog
               else
                  if (foreignal != 0) then
                     krmicd.writeMsg(1005,
                         'INTERNAL ERROR: unexpected database status'||
                         ' for Foreign Archivelog');
                     raise internal_error;
                  end if;
                  dbms_rcvcat.changeArchivedLog(
                     al_recid          => recid,
                     al_stamp          => stamp,
                     osite_key         => site_key,
                     status            => new_status);
%ENDIF% catalog
               end if;
            else
               deb('change', 'file '||handle||
                   ' not updated on repository, old_status:'||old_status||
                   ',same as new_status:'||new_status||',site_key:'||site_key);
            end if;
            if (foreignal = 0) then
               if cmd = krmiXCHECK then
                  if found then
                     krmicd.writeMsg(6158);
                  else
                     krmicd.writeMsg(6157);
                  end if;
               elsif cmd in (krmiDEXPIRED, krmiDELETE) then
                  krmicd.writeMsg(6406);
               elsif cmd = krmiAVAIL then
                  if found then
                     krmicd.writeMsg(6113);
                  else
                     krmicd.writeMsg(6485);
                  end if;
               elsif cmd = krmiUAVAIL then
                  krmicd.writeMsg(6109);
               elsif cmd = krmiRESETDBUN then
                  if (site_key is null or site_key <> nsite_key) then
                     krmicd.writeMsg(1005, 
                        'change archived log db_unique_name');
                  end if;
               elsif cmd = krmiUNCAT then
                  krmicd.writeMsg(6120);
               end if;
               krmicd.writeMsg(8514, handle, to_char(recid), to_char(stamp));
            else  -- foreign archived log
               if cmd = krmiXCHECK then
                  if found then
                     krmicd.writeMsg(8618);
                  else
                     krmicd.writeMsg(8617);
                  end if;
               elsif cmd in (krmiDEXPIRED, krmiDELETE) then
                  krmicd.writeMsg(8621);
               elsif cmd = krmiAVAIL then
                  if found then
                     krmicd.writeMsg(8622);
                  else
                     krmicd.writeMsg(8623);
                  end if;
               elsif cmd in (krmiUAVAIL, krmiRESETDBUN) then
                  krmicd.writeMsg(1005,
                          'INTERNAL ERROR: unexpected cmd='||
                          to_char(cmd)||' for Foreign Archivelog');
                   raise internal_error;
               elsif cmd = krmiUNCAT then
                  krmicd.writeMsg(8620);
               end if;
               krmicd.writeMsg(8619, handle, to_char(recid), to_char(stamp));
            end if;
            ocount := ocount + 1;
         else
            krmicd.writeMsg(1005, 'INTERNAL ERROR: unexpected objectType='||
                                  to_char(objectType));
            raise internal_error;
         end if;
      end if;
<<next_object>>
      null;
   end loop;
   if ocount > 0 then
      if cmd = krmiRESETDBUN then
         krmicd.writeMsg(1005, 
           'Changed ' || to_char(ocount) || ' objects db_unique_name');
      else
         krmicd.writeMsg(cmdmsg, to_char(ocount));
      end if;
      if ((not anymiss) and implicit = 0)then
         krmicd.writeMsg(0);
      end if;
      if (cmd in (krmiDELETE, krmiDEXPIRED, krmiUNCAT)) then
         sys.dbms_backup_restore.cleanupBackupRecords;
      end if;
   end if;
   if anymiss then
--
      krmicd.writeMsg(0);
      krmicd.writeMsg(6207, mcount, nvl(devicetype, ' '));
      krmicd.writeMsg(6208);
      krmicd.listMismatch;
      krmicd.writeMsg(0);
   end if;
 
   if runatsite then
--
      krmicd.writeMsg(0);
      krmicd.writeMsg(6216, rscount);
      krmicd.listRunAtSite;
      krmicd.writeMsg(0);
   end if;
 
   if (vbkey != 0) then
      exited('change', 'OK');
   else
      exited('change', 'NOTOK');
   end if;
end;
>>>
 
define change_failure 
<<<
--
declare
   failureList      sys.dbms_ir.ir_failure_list_type;
   errorList        sys.dbms_ir.ir_error_list_type;
   cmdmsg           number; 
   failureId        number;
   firstcall        binary_integer;
   &constants&
   internal_error   exception;
   pragma exception_init(internal_error, -600);
begin
   entered('change_failure');
   deb('change_failure', 'started, command: '|| cmd);
 
   select decode(cmd,
                 krmiHIGH,     7207,
                 krmiLOW,      7208,
                 krmiCLOSED,   7209)
     into cmdmsg
     from x$dual;
 
   firstcall := 1;
   loop
      exit when not krmicd.failureGetNext(firstcall, failureId);
      firstcall := 0;
      failureList(failureList.count + 1) := failureId;
      deb('change_failure', 'added failureId = ' || failureId);
   end loop;
 
   if (failureList.count = 0) then
      raise internal_error;
   end if;
 
   if (cmd = krmiCLOSED) then
      sys.dbms_ir.closeFailures(
         failureList => failureList
        ,errorList   => errorList);
   elsif (cmd = krmiHIGH) then
      sys.dbms_ir.changePriority(
         failureList => failureList
        ,newPriority => sys.dbms_ir.IR_FAILURE_HIGH
        ,errorList   => errorList);
   elsif (cmd = krmiLOW) then
      sys.dbms_ir.changePriority(
         failureList => failureList
        ,newPriority => sys.dbms_ir.IR_FAILURE_LOW
        ,errorList   => errorList);
   else
      raise internal_error;
   end if;
 
   for i in 1..errorList.count loop
      if (abs(errorList(i).errorCode) = 51102) then
         krmicd.writeMsg(8062, to_char(errorList(i).failureID));
      else
         krmicd.writeMsg(8061,
                         to_char(errorList(i).failureID),
                         abs(errorList(i).errorCode));
      end if;
   end loop;
 
   krmicd.writeMsg(cmdmsg, to_char(failureList.count - errorList.count));
   exited('change_failure', 'OK');
end;
>>>
 
define catdfc
<<<
--
declare
  fname       varchar2(512);
  full_name   varchar2(512);
  recid       number;
  stamp       number;
  rsid        number;
  rsts        number;
  preplugin   boolean;
  pdbid       number;
  pplcdbdbid  number;
  ppltrans    number;
begin
  &object&
  if (preplugin) then
     krmicd.getPrePluginTranslation(pdbid, pplcdbdbid);
     ppltrans := sys.dbms_backup_restore.beginPrePluginTranslation(
                    pdbid => pdbid, pplcdbdbid => pplcdbdbid);
  end if;
  sys.dbms_backup_restore.setRmanStatusRowId(rsid=>rsid, rsts=>rsts);
  sys.dbms_backup_restore.inspectDataFileCopy(fname => fname,
    full_name => full_name, recid => recid, stamp => stamp, 
    &args&);
  krmicd.writeMsg(8050);
  krmicd.writeMsg(8513, full_name, to_char(recid), to_char(stamp));
  sys.dbms_backup_restore.setRmanStatusRowId(rsid=>0, rsts=>0);
  if (ppltrans > 0) then
     sys.dbms_backup_restore.endPrePluginTranslation;
  end if;
end;
>>>
 
define catalc
<<<
--
declare
  fname       varchar2(512);
  full_name   varchar2(512);
  recid       number;
  stamp       number;
  rsid        number;
  rsts        number;
  preplugin   boolean;
  pdbid       number;
  pplcdbdbid  number;
  ppltrans    number;
begin
  &object&
  if (preplugin) then
     krmicd.getPrePluginTranslation(pdbid, pplcdbdbid);
     ppltrans := sys.dbms_backup_restore.beginPrePluginTranslation(
                    pdbid => pdbid, pplcdbdbid => pplcdbdbid);
  end if;
  sys.dbms_backup_restore.setRmanStatusRowId(rsid=>rsid, rsts=>rsts);
  sys.dbms_backup_restore.inspectArchivedLog(fname => fname,
    full_name => full_name, recid => recid, stamp => stamp,
    change_rdi => TRUE, preplugin => preplugin);
  krmicd.writeMsg(8051);
  krmicd.writeMsg(8514, full_name, to_char(recid), to_char(stamp));
  sys.dbms_backup_restore.setRmanStatusRowId(rsid=>0, rsts=>0);
  if (ppltrans > 0) then
     sys.dbms_backup_restore.endPrePluginTranslation;
  end if;
end;
>>>
 
define catbcf
<<<
--
declare
  fname       varchar2(512);
  full_name   varchar2(512);
  recid       number;
  stamp       number;
  rsid        number;
  rsts        number;
  preplugin   boolean;
  pdbid       number;
  pplcdbdbid  number;
  ppltrans    number;
begin
  &object&
  if (preplugin) then
     krmicd.getPrePluginTranslation(pdbid, pplcdbdbid);
     ppltrans := sys.dbms_backup_restore.beginPrePluginTranslation(
                    pdbid => pdbid, pplcdbdbid => pplcdbdbid);
  end if;
  sys.dbms_backup_restore.setRmanStatusRowId(rsid=>rsid, rsts=>rsts);
  sys.dbms_backup_restore.inspectControlFile(fname => fname,
    full_name => full_name, recid => recid, stamp => stamp);
  krmicd.writeMsg(8052);
  krmicd.writeMsg(8516, full_name, to_char(recid), to_char(stamp));
  sys.dbms_backup_restore.setRmanStatusRowId(rsid=>0, rsts=>0);
  if (ppltrans > 0) then
     sys.dbms_backup_restore.endPrePluginTranslation;
  end if;
end;
>>>
 
define catbp
<<<
--
declare
  handle      varchar2(512);
  full_handle varchar2(512);
  recid       number;
  stamp       number;
  err_num     number := 0;
  err_msg     varchar2(2048);
  rsid        number;
  rsts        number;
  preplugin   boolean;
  pdbid       number;
  pplcdbdbid  number;
  ppltrans    number;
  db_not_mounted exception;
  pragma exception_init(db_not_mounted, -1507);
begin
  &object& 
 
  if (preplugin) then
     krmicd.getPrePluginTranslation(pdbid, pplcdbdbid);
     ppltrans := sys.dbms_backup_restore.beginPrePluginTranslation(
                    pdbid => pdbid, pplcdbdbid => pplcdbdbid);
  end if;
 
  begin
     sys.dbms_backup_restore.setRmanStatusRowId(rsid=>rsid, rsts=>rsts);
     sys.dbms_backup_restore.inspectBackupPiece(
                          handle        => handle, 
                          full_handle   => full_handle,
                          recid         => recid,
                          stamp         => stamp);
  exception
     when db_not_mounted then
        raise;
--
--
     when others then
--
        err_num := sqlcode;
        err_msg := sqlerrm;
  end;
 
  if (err_num = 0) then
     krmicd.writeMsg(8127);
     krmicd.writeMsg(8517, full_handle, to_char(recid), to_char(stamp));
  else
     krmicd.writeErrMsg(1005, err_msg);
--
     krmicd.mismatchObj('Backup Piece', handle, 0);
     krmicd.setDeferError;
  end if;
  sys.dbms_backup_restore.setRmanStatusRowId(rsid=>0, rsts=>0);
  if (ppltrans > 0) then
     sys.dbms_backup_restore.endPrePluginTranslation;
  end if;
end;
>>>
 
define clean
<<<
--
declare
  /* device status variables */
  state       binary_integer;
  devtype     varchar2(512);
  name        varchar2(512);
  bufsz       binary_integer;
  bufcnt      binary_integer;
  kbytes      number;
  readrate    binary_integer;
  parallel    binary_integer;
  thread      number;
  kcrmx_recs  number;
  autochn     number := 0;
 
  mr_not_started exception;
  pragma exception_init(mr_not_started, -1112);
  db_not_mounted exception;
  pragma exception_init(db_not_mounted, -1507);
begin
  &object&
  begin
    krmicd.execSql('select count(*) from x$dual');
  exception
    when others then
      krmicd.clearErrors;
  end;
  sys.dbms_backup_restore.backupCancel;
  sys.dbms_backup_restore.restoreCancel(FALSE);
  begin
    sys.dbms_backup_restore.proxyCancel;
  exception
     when others then
        krmicd.clearErrors;
  end;
  sys.dbms_backup_restore.cfileUseCurrent;              -- release enqueue
  sys.dbms_backup_restore.deviceStatus(state, devtype, name, bufsz, bufcnt,
                                         kbytes, readrate, parallel);
  begin
     sys.dbms_backup_restore.bmrCancel;
  exception
     when others then
        krmicd.clearErrors;
  end;
  begin
     sys.dbms_backup_restore.flashbackCancel;
  exception
     when others then
        krmicd.clearErrors;
  end;
  begin
     sys.dbms_backup_restore.nbrCancel;
  exception
     when others then
        krmicd.clearErrors;
  end;
  begin
     sys.dbms_backup_restore.prePluginRecoveryCancel;
  exception
     when others then
        krmicd.clearErrors;
  end;
  begin
     sys.dbms_backup_restore.endPrePluginTranslation;
  exception
     when others then
        krmicd.clearErrors;
  end;
  begin
     sys.dbms_backup_restore.recoverCancel;
  exception
     when others then
        krmicd.clearErrors;
  end;
  begin
    if krmicd.mrCheck > 0 then
      krmicd.execSql('alter database recover cancel');
    end if;
  exception
    when others then
      krmicd.clearErrors;
  end;
  begin
     sys.dbms_backup_restore.cleanupPgaContext;
  exception
     when others then
        krmicd.clearErrors;
  end;
 
--
--
--
--
--
--
  if (autochn = 0) then
    if (state > sys.dbms_backup_restore.NO_DEVICE) then
       sys.dbms_backup_restore.deviceDeallocate;        
       krmicd.writeMsg(8031, krmicd.getChid);
--
--
--
       sys.dbms_backup_restore.set_client_info('');
    end if;
    krmicd.clearChannelInfo;                    -- tell krmq no device here now
  end if;
  sys.dbms_backup_restore.setRmanStatusRowId(rsid=>0, rsts=>0);
end;
>>>
 
 
define del_start
<<<
--
declare
   first_time           boolean := TRUE;
   arch_recid           number;
   arch_stamp           number;
   fname                varchar2(512);
   thread               number;
   sequence             number;
   resetlogs_change     number;
   resetlogs_time       varchar2(512);
   first_change         number;
   next_change          number;
   blksize              number;
   handle               varchar2(512);
   recid                number;
   stamp                number;
   cfisstby             boolean := FALSE;
   chtype               varchar2(16);
   cfauto               boolean       := FALSE;
   skipped              boolean       := FALSE;
   dfnumber             number;
   copy_recid           number;
   copy_stamp           number;
   creation_change      number;
   checkpoint_change    number;
   no_delete            binary_integer;
   reqscn               number;     -- streams/standby required scn
   rlgscn               number;     -- streams/standby resetlogs scn
   appscn               number;
   apprlgscn            number;
   alldest              number := 0;
   docopies             boolean := FALSE;
   reqbackups           number;
   nbackups             number;
begin
   first_time := TRUE;  -- make sure atleast one statement
--
   chtype     := krmicd.getDevType;
   
>>>
 
define budf_start
<<<
--
/* This must be retriable, which means a backup conversation may already
 * be in progress when this step (re)executes.
 */
declare
  /* backup conversation status variables: budf_start */
  state       binary_integer;
  setid       number;
  stamp       number;
  pieceno     binary_integer;
  files       binary_integer;
  datafiles   boolean;
  incremental boolean;
  nochecksum  boolean;
  device      boolean;
  hdrupd      boolean  := TRUE;
  sparse_option
              binary_integer := 0; /* default backup type of sparse datafile */
  /* piece creation variables */
  done        boolean;
  concur      boolean;
  chg_tracking_err number;
  /* Miscellaneous */
  memnum      number;
  dfnumber    number;
  cfname      varchar2(512);
  copy_recid  number;
  copy_stamp  number;
  busy_retries number := 0;
  resetlogs_change  number;
  creation_change   number;
  checkpoint_change number;
  blksize           number;
  blocks            number;
  fname             varchar2(1024);
  dpfname           varchar2(1024);
  no_delete         binary_integer;
  copy         number;
  nformat      number := 1;
  handle       varchar2(512);
  comment      varchar2(80);
  media        varchar2(80);
  wrong_format      exception;
  pragma exception_init(wrong_format, -20039);
  first_time        boolean := TRUE;
  backup_level      number;
  elapsed           number;
  starttime         date;
  hours             number;
  mins              number;
  secs              number;
  ncopies           number := 0;
  docompress        boolean := FALSE;
  compressalg       varchar2(80);
  compressasof      number;
  compresslopt      binary_integer;
  nonlogblk         boolean := FALSE;
 
  /* backup_type is used to indicate what type of backup is done. This is used
   * to get configured copies, look at krmkgbac for more comments. */
  backup_type       number := 2;
  isstby            boolean;
  larchlog_failover boolean;
  failoverdone      boolean := FALSE;
  docopies          boolean := FALSE;
  cnvrtto           boolean := FALSE;
  cnvrtfr           boolean := FALSE;
  sameen            boolean := FALSE;
  reusefile         boolean := FALSE;
  tsname            varchar2(30) := NULL;
  thread            number := NULL;
  sequence          number := NULL;
  m                 number := 8581;
  cprecid           number;
  cpstamp           number;
  rsid              number;
  rsts              number;
  cptag             varchar2(31) := NULL;
  noct              boolean := FALSE;
  nooptim           boolean := FALSE;
  dontcare          varchar2(1);
  pltfrmto          number := NULL;
  pltfrmfr          number := NULL;
  foreign_dbname    varchar2(8) := NULL;
  foreign_dbid      number := NULL;
  doconvert         boolean := FALSE;
  savepiecename     boolean := FALSE;
  transontarget     boolean := FALSE;
  transonlyundo     boolean := FALSE;
  convertdb         boolean := FALSE;
  bckconvertdb      boolean := FALSE;
  processfile       boolean := TRUE;
  isomf             boolean;
  istmplt           boolean;
  isasm             boolean;
  validatecmd       boolean;
  validateopt       boolean;
  newcorrupt        boolean;   -- TRUE if new corruption is found
  updateok          boolean;
  snapshot_cf       boolean;
  file_exists       number;
  crescn            number;
  isfarsync         boolean := FALSE;
 
  /* Multi-section backup fields */
  msb_secbytes      number := 0;
  msb_file_size     number;
  msb_set_stamp     number;
  msb_set_count     number;
  msb_section_size  number;
  msb_first_section number;
  msb_section_count number;
  msb_piece_number  number;
  msb_piece_count   number;
  msb_section_copy_fname varchar2(1025);
  msb_is_first_section boolean := FALSE;
  dpscn             number;
  mirror_num        number := 0;          /* 0: do not use a specific mirror */
  cnvrt_need_format exception;
  bkp_need_format   exception;
  /* Transportable tablespace encryption */
  jobname           varchar2(512) := null;
  passphrase        varchar2(128) := null;
  pragma exception_init(cnvrt_need_format, -20038);
  pragma exception_init(bkp_need_format, -20045);
begin
  &1&
--
  &2&
--
  &3&
--
  &4&
--
  &5&
--
  &6&
--
  &7&
--
  &msb_secbytes&
--
  &comp_alg&
--
  &sparse_option&
 
  if pltfrmto is not null or pltfrmfr is not null then
     doconvert := true;
  end if;
 
--
  if (NOT beginBackupJobStep()) then
    return;
  end if;
 
  sys.dbms_backup_restore.backupStatus(state, setid, stamp, pieceno, files,
                                       datafiles, incremental, nochecksum,
                                       device);
  if state = sys.dbms_backup_restore.BACKUP_NO_CONVERSATION then
    goto start_convo;
  elsif state = sys.dbms_backup_restore.BACKUP_NAMING_FILES then
    goto name_files;
  else
    goto create_piece;
  end if;
 
<<start_convo>>
  sys.dbms_backup_restore.setRmanStatusRowId(rsid=>rsid, rsts=>rsts);
  sys.dbms_backup_restore.backupSetDatafile(stamp, setid,
                                            &args_start&,
                                            &args_tag&,
                                            backup_level => backup_level,
                                            imagcp    => docopies,
                                            convertto => cnvrtto,
                                            convertfr => cnvrtfr,
                                            pltfrmto  => pltfrmto,
                                            pltfrmfr  => pltfrmfr,
                                            sameen    => sameen,
                                            convertdb => convertdb or
                                                         bckconvertdb,
                                            validate  => validateopt,
                                            hdrupd    => hdrupd,
                                            sparse_option => sparse_option,
                                            mirror_num => mirror_num);
  if hdrupd then
     krmicd.writeMsg(6782);
     krmicd.writeMsg(6785);
     updateok := sys.dbms_backup_restore.UpdateHeaders();
     if not updateok then
        krmicd.writeMsg(6784);
        krmicd.writeMsg(8191, 
                        sys.dbms_backup_restore.getParm(
                                   sys.dbms_backup_restore.TRACE_FILENAME));
     end if;
     krmicd.writeMsg(6783);
  end if;
 
  if (noct) then
    dontcare :=
      sys.dbms_backup_restore.getParm(sys.dbms_backup_restore.incr_noct);
  end if;
 
  if (nooptim) then
    dontcare :=
      sys.dbms_backup_restore.getParm(sys.dbms_backup_restore.full_nooptim);
  end if;
 
--
  if docopies then
--
     if not convertdb then
        if doconvert then
           krmicd.writeMsg(8589, krmicd.getChid);
        else
           krmicd.writeMsg(8580, krmicd.getChid);
        end if;
     end if;
  else
     if backup_level is not null then
        if (docompress) then
           krmicd.writeMsg(8047, krmicd.getChid, to_char(backup_level));
        else
           krmicd.writeMsg(8048, krmicd.getChid, to_char(backup_level));
        end if;  
     else
        if (docompress) then
           krmicd.writeMsg(8046, krmicd.getChid); 
        elsif (validatecmd) then
           krmicd.writeMsg(8140, krmicd.getChid);
        else
           krmicd.writeMsg(8008, krmicd.getChid);
        end if;
     end if;
  end if;
 
  if pltfrmto is not null and not docopies then
     krmicd.getExportJobName(jobname, passphrase);
--
--
 
     if (jobname is not null) then
        passphrase := null;
        sys.dbms_backup_restore.setExportJobName(jobname, passphrase);
     end if;
  end if;
 
  setBackupParams(docopies);
<<name_files>>
  deb('budf_start', 'set_stamp=' || stamp || ' set_count=' || setid,
      rman_constant.DEBUG_IO, rman_constant.LEVEL_MIN);
>>>
 
define bual_start
<<<
--
/* This must be retriable, which means a backup conversation may already
 * be in progress when this step (re)executes.
 */
declare
  /* backup conversation status variables: bual_start */
  state             binary_integer;
  setid             number;
  stamp             number;
  pieceno           binary_integer;
  files             binary_integer;
  datafiles         boolean;
  incremental       boolean;
  backup_level      number;
  nochecksum        boolean;
  device            boolean;
  /* piece creation variables */
  done              boolean;
  concur            boolean;
  chg_tracking_err  number;
  /* Miscellaneous */
  memnum            number;
  arch_recid        number;
  arch_stamp        number;
  fname             varchar2(512);
  dpfname           varchar2(512);
  thread            number;
  sequence          number;
  resetlogs_change  number;
  resetlogs_time    varchar2(512);
  first_change      number;
  next_change       number;
  blksize           number;
  blocks            number;
  copy              number;
  nformat           number := 1;
  handle            varchar2(512);
  comment           varchar2(80);
  media             varchar2(80);
  wrong_format      exception;
  pragma exception_init(wrong_format, -20039);
  first_time        boolean := TRUE;
  cfisstby          boolean := FALSE;
  elapsed           number;
  starttime         date;
  hours             number;
  mins              number;
  secs              number;
  ncopies           number := 0;
--
--
  backup_type       number := 1;
  larchlog_failover boolean;
  failoverdone      boolean := FALSE;
  docopies          boolean := FALSE;
  reusefile         boolean := FALSE;
  dfnumber          number := NULL;
  tsname            varchar2(30) := NULL;
  m                 number := 8583;
  cprecid           number;
  cpstamp           number;
  foreign_dbname    varchar2(8) := NULL;
  foreign_dbid      number := NULL;
  rsid              number;
  rsts              number;
  cptag             varchar2(31) := NULL;
  doconvert         boolean := FALSE;
  docompress        boolean := FALSE;
  compressalg       varchar2(80);
  compressasof      number;
  compresslopt      binary_integer;
  savepiecename     boolean := FALSE;
  transontarget     boolean := FALSE;
  transonlyundo     boolean := FALSE;
  convertdb         boolean := FALSE;
  bckconvertdb      boolean := FALSE;
  processfile       boolean := TRUE;
  reqscn            number;     -- streams/standby required scn
  rlgscn            number;     -- streams/standby resetlogs scn
  appscn            number;
  alldest           number := 0;
  apprlgscn         number;
  reqbackups        number;
  nbackups          number;
  isomf             boolean;
  istmplt           boolean;
  isasm             boolean;
  validatecmd       boolean;
  validateopt       boolean;
  newcorrupt        boolean;   -- TRUE if new corruption is found
  msb_secbytes      number := 0;
  msb_is_first_section boolean := FALSE;
  nonlogblk         boolean := FALSE;
  cnvrt_need_format exception;
  bkp_need_format   exception;
  pragma exception_init(cnvrt_need_format, -20038);
  pragma exception_init(bkp_need_format, -20045);
begin
--
  &2&
--
  &3&
--
  &4&
--
  &5&
--
  &6&
--
  &7&
--
  &msb_secbytes&
--
  &comp_alg&
 
--
  if (NOT beginBackupJobStep()) then
    return;
  end if;
  
  sys.dbms_backup_restore.backupStatus(state, setid, stamp, pieceno, files,
                                         datafiles, incremental, nochecksum,
                                         device);
 
  if state = sys.dbms_backup_restore.BACKUP_NO_CONVERSATION then
    goto start_convo;
  elsif state = sys.dbms_backup_restore.BACKUP_NAMING_FILES then
    goto name_files;
  else
    goto create_piece;
  end if;
 
<<start_convo>>
  sys.dbms_backup_restore.setRmanStatusRowId(rsid=>rsid, rsts=>rsts);
  sys.dbms_backup_restore.backupSetArchivedLog(set_stamp => stamp,
                                               set_count => setid,
                                               &args_start&,
                                               &args_tag&,
                                               imagcp => docopies,
                                               validate => validateopt);
  if not docopies then
     if (validatecmd) then
        krmicd.writeMsg(8145, krmicd.getChid);
     elsif (docompress) then
        krmicd.writeMsg(8049, krmicd.getChid);
     else
        krmicd.writeMsg(8009, krmicd.getChid);
     end if;
  else
     krmicd.writeMsg(8582, krmicd.getChid);
  end if;
  setBackupParams(docopies);
<<name_files>>
>>>
 
define bubs_start
<<<
--
declare
  set_count         number;
  set_stamp         number;
  recid             number;
  stamp             number;
  copy_recid        number;
  copy_stamp        number;
  isrdf             boolean;
  pieceno           number := 0;              -- piece number for this step
  piececnt          binary_integer := 0;      -- count of distinct piece copies
  npieces           binary_integer := 0;      -- number pieces in backup set
  type names is table of varchar2(512) index by binary_integer;
  type ctlid is table of number index by binary_integer;
  type isrdf_tab is table of boolean index by binary_integer;
  pnames            names;
  precid            ctlid;
  pstamp            ctlid;
  pisrdf            isrdf_tab;
  /* piece creation variables */
  concur            boolean;
  /* Miscellaneous */
  fname             varchar2(1024);
  copy              number;
  max_copy          binary_integer;
  ncopies           number := 0;             -- number of output copies to make
  docompress        boolean := FALSE;
  compressalg       varchar2(80);
  compressasof      number;
  compresslopt      binary_integer;
  nformat           number := 1;
  handle            varchar2(512);
  comment           varchar2(80);
  media             varchar2(80);
  elapsed           number;
  stampd            date;
  hours             number;
  mins              number;
  secs              number;
  cfauto            boolean       := FALSE;
  skipped           boolean       := FALSE;     -- skipped this backuppiece
  chtype            varchar2(16);
  start_time        date;
  savepiecename     boolean := FALSE;
  transontarget     boolean := FALSE;
  transonlyundo     boolean := FALSE;
  convertdb         boolean := FALSE;
  bckconvertdb      boolean := FALSE;
  processfile       boolean := TRUE;
  rsid              number;
  rsts              number;
  wrong_format      exception;
  in_use            exception; 
  del_for_space     exception;
  dropped_pdb_file  exception;
  isomf             boolean;
  istmplt           boolean;
  isasm             boolean;
  skip_inaccessible boolean;
  firstscan         boolean;
  pltfrmfr          number := NULL;
  nofrpltfrm        boolean  := FALSE;
  cnvrtfr           boolean := FALSE;
  pragma exception_init(wrong_format, -20039);
  pragma exception_init(in_use, -19584);
  pragma exception_init(del_for_space, -19805);
  pragma exception_init(dropped_pdb_file, -45913);
begin
--
  &object&
--
  &3&
--
  &4&
--
  &7&
--
  &comp_alg&
 
  if (skip_inaccessible and krmicd.isBsInaccessible(firstscan)) then
     if (firstscan) then
        krmicd.writeMsg(8107, to_char(set_count), to_char(set_stamp));
     end if;
     return;
  end if;
 
  if pltfrmfr is NULL then
     krmicd.writeMsg(8104, krmicd.getChid, to_char(set_count),
                     to_char(set_stamp), to_char(pieceno));
  end if;
 
--
  if (NOT beginBackupJobStep()) then
    return;
  end if;
 
  sys.dbms_backup_restore.setRmanStatusRowId(rsid=>rsid, rsts=>rsts);
>>>
 
define copyfil_start
<<<
--
declare
  cpfil_unsupported exception;
  pragma exception_init(cpfil_unsupported, -16524);
 
  type names is table of varchar2(512) index by binary_integer;
  src_name          varchar2(512);
  lformat           names;
  nformat           number := 1;
  netalias          varchar2(1000) := NULL;
  worked            boolean;
  memnum            number;
  ispwdfile         boolean := false;
begin
--
  if (NOT beginBackupJobStep()) then
    return;
  end if;
>>>
 
define budf_name
<<<
--
  &memnum&
  &object&
  if (first_time) then
     if validatecmd then
        if (nonlogblk = FALSE) then
           krmicd.writeMsg(8141, krmicd.getChid);
        end if;
     elsif not docopies then
        krmicd.writeMsg(8010, krmicd.getChid);
     end if;
     first_time := FALSE;
  end if;
  if files < memnum then
    begin
       sys.dbms_backup_restore.backupDataFile(dfnumber => dfnumber, &args&);
       if convertdb then
          if transonlyundo then
             processfile := krmicd.isFileUndo(dfnumber);
          end if;
 
          if processfile then
             if transontarget then
                krmicd.writeMsg(8305, krmicd.getChid);
             else
                krmicd.writeMsg(8589, krmicd.getChid);
             end if;
          end if;
          
       end if;
 
       if (processfile and nonlogblk = FALSE) then
          krmicd.writeMsg(8522, to_char(dfnumber, 'FM09999'), fname);
 
          deb('budf_name', 'blocks=' || blocks || ' block_size=' || blksize,
              rman_constant.DEBUG_IO, rman_constant.LEVEL_MIN);
       end if;
    exception
       when sys.dbms_backup_restore.inc_scn_matches_df_scn then
          krmicd.writeMsg(8522, to_char(dfnumber, 'FM09999'), fname);
          krmicd.writeMsg(8056, to_char(dfnumber, 'FM09999'));
          krmicd.clearErrors;
--
       when others then
          select count(*) into file_exists
             from x$kccfe fe
            where fe.fenum = dfnumber               and
                  to_number(fe.fecrc_scn) = crescn and
                  fe.fedup != 0;
 
--
          if file_exists > 0 then
             raise;
          else
--
             krmicd.writeMsg(8193, to_char(dfnumber, 'FM09999'), fname);
             deb('budf_fname', sqlerrm);
             krmicd.clearErrors;
          end if;
    end;
    files := files + 1;
  end if;
>>>
 
define budc_name
<<<
--
  &memnum&
  &object&
  name_datafilecopy(memnum, copy_recid, copy_stamp, fname, dfnumber, blocks,
                    blksize, tsname, files, docopies, &args&);
>>>
 
define bucv_name
<<<
--
  &memnum&
  &object&
  if files < memnum then
    sys.dbms_backup_restore.convertDataFileCopy(fname, &args&);
    files := files + 1;
    krmicd.writeMsg(8506, fname);
  end if;
>>>
 
define busp_name
<<<
--
  &memnum&
  &object&
  if (first_time) then
     if validatecmd then
        krmicd.writeMsg(8141, krmicd.getChid);
     elsif not docopies then
        krmicd.writeMsg(8010, krmicd.getChid);
     end if;
     first_time := FALSE;
  end if;
  sys.dbms_backup_restore.backupSpFile;
  krmicd.writeMsg(8113);
>>>
 
define bucf_name
<<<
--
  isstby := FALSE;
  isfarsync := FALSE;
  dfnumber := 0;
  &memnum&
  &object&
  if (first_time) then
     if validatecmd then
        krmicd.writeMsg(8141, krmicd.getChid);
     elsif not docopies then
        krmicd.writeMsg(8010, krmicd.getChid);
     end if;
     first_time := FALSE;
  end if;
 
  if (cfname is null and not validateopt and not docopies) then
     snapshot_cf := TRUE;
  else
     snapshot_cf := FALSE;
--
--
--
--
     for r in (select 1 from v$instance where parallel = 'YES') loop
        snapshot_cf := TRUE;
        exit;
     end loop;
  end if;
 
  if files < memnum then
--
--
--
--
      <<snapshot>>  -- retry on failure to get snapshot enqueue
 
      begin
--
        if snapshot_cf then
           sys.dbms_backup_restore.cfileMakeAndUseSnapshot(isstby);
           sys.dbms_backup_restore.cfileUseCurrent;
        end if;
        sys.dbms_backup_restore.backupControlFile(cfname      => cfname,
                                                  isstby      => isstby,
                                                  snapshot_cf => snapshot_cf,
                                                  isfarsync   => isfarsync);
      exception
        when sys.dbms_backup_restore.snapshot_enqueue_busy then
--
--
--
--
          if busy_retries = 180 then
             krmicd.writeMsg(20029, 'cannot make a snapshot controlfile');
             raise;
          end if;
 
          busy_retries := busy_retries + 1;
--
          if (mod(busy_retries, 15) = 0) then
             krmicd.writeMsg(8512);
          end if;
          krmicd.sleep(20);
          krmicd.clearErrors;
          goto snapshot;
      end;      -- snapshot controlfile stuff
 
    files := files + 1;
    if cfname is null then
      if validatecmd then
         if isstby then 
            krmicd.writeMsg(8142);
         else
            krmicd.writeMsg(8143);
         end if;
      elsif not docopies then
         if isstby then 
            krmicd.writeMsg(8020);
         else
            krmicd.writeMsg(8011);
         end if;
      else
         if isstby then 
            krmicd.writeMsg(8585);
         else
            krmicd.writeMsg(8584);
         end if;
      end if;
    else
      krmicd.writeMsg(8524, cfname);
      deb('bucf_name', 'blocks=' || blocks || ' block_size=' || blksize,
          rman_constant.DEBUG_IO, rman_constant.LEVEL_MIN);
    end if;
  end if;
>>>
 
define bual_name
<<<
--
  name_log(&memnum&, &object&, files=>files, first_time => first_time,
           docopies => docopies, validatecmd => validatecmd);
  &1&
>>>
 
define bubp_name
<<<
--
  &object&
--
  pnames(piececnt) := fname;
  precid(piececnt) := copy_recid;
  pstamp(piececnt) := copy_stamp;
  pisrdf(piececnt) := isrdf;
  piececnt := piececnt + 1;
>>>
 
define budp_name
<<<
--
  declare
     dpckpscn             number;
     dpckptime            number;
     dprlgscn             number;
     dprlgtime            number;
     dpfno                number;
     dpdeflt              boolean;
  begin
     &memnum&
     &object&
 
     if files < memnum then
        sys.dbms_backup_restore.backupDmpfile(dmpfile => fname,
                                              blksize => blksize,
                                              dpckpscn => dpckpscn,
                                              dpckptime => dpckptime,
                                              dprlgscn => dprlgscn,
                                              dprlgtime => dprlgtime,
                                              dpfno => dpfno,
                                              dbid => foreign_dbid);
        krmicd.writeMsg(8557, fname);
 
        if dpdeflt then
           dpfname := fname;
        end if;
 
        deb('budp_name', 'dmpfile='    || fname || 
                         ' blocksize=' || blksize ||
                         ' dprlgtime=' || dprlgtime ||
                         ' dprlgscn= ' || dprlgscn ||
                         ' dpckpscn= ' || dpckpscn ||
                         ' dpckptime= '|| dpckptime ||
                         ' dpfno='     || dpfno ||
                         ' dbid='      || foreign_dbid);
        files := files + 1;
     end if;
  end;
>>>
 
define copyfil_name
<<<
--
  &memnum&
  &object&
 
  if ispwdfile then 
     src_name := sys.dbms_backup_restore.getParm(12);
  end if;
>>>
 
define msb
<<<
--
 
  sys.dbms_backup_restore.backupStatus(state, setid, stamp, pieceno, files,
                                         datafiles, incremental, nochecksum,
                                         device);
  if (files = 0 ) then
     if krmicd.firstMSB then     
        krmicd.exitMSB;
        goto create_piece;
     end if;
  else
     if krmicd.firstMSB then     
        sys.dbms_backup_restore.initMSB(dfnumber, msb_file_size,
                                        msb_set_stamp, msb_set_count);
        if docopies then
           msb_is_first_section := TRUE; 
        end if;
 
        krmicd.initMSB(msb_file_size, blksize, msb_secbytes,
                       msb_set_stamp, msb_set_count);
     end if;
 
--
--
--
     if (not msb_is_first_section and docopies and not validateopt) then
        krmicd.getMSC(handle);   
 
        sys.dbms_backup_restore.setMSC(handle);
 
        deb('msb', 'Nextsection: '||handle);
     end if;   
 
     krmicd.getMSB(msb_section_size, msb_first_section, msb_section_count,
                   msb_set_stamp, msb_set_count, msb_piece_number,
                   msb_piece_count);
 
     sys.dbms_backup_restore.setMSB(dfnumber, msb_section_size,
                                    msb_first_section, msb_section_count,
                                    msb_set_stamp, msb_set_count,
                                    msb_piece_number, msb_piece_count);
 
     if (validatecmd) then
        krmicd.writeMsg(8616, msb_section_size * msb_first_section + 1,
                        least(blocks,
                        (msb_section_size * msb_first_section) +
                        (msb_section_size * msb_section_count)));
     else
        krmicd.writeMsg(8525, msb_section_size * msb_first_section + 1,
                        least(blocks,
                        (msb_section_size * msb_first_section) +
                        (msb_section_size * msb_section_count)));
     end if;
  end if;
>>>
 
define bu_create
<<<
--
<<create_piece>>
  sys.dbms_backup_restore.backupStatus(state, setid, stamp, pieceno, files,
                                         datafiles, incremental, nochecksum,
                                         device);
 
  starttime := currentTime();
 
--
--
 
  if (files = 0) then
      sys.dbms_backup_restore.backupCancel;
      krmicd.writeMsg(8057, krmicd.getChid);
  else
--
      &ncopies&
 
      if (ncopies = 0) then
         ncopies := krmicd.getBackupCopies(backup_type, krmicd.getDevType);
      end if;
 
      sys.dbms_backup_restore.setLimit(sys.dbms_backup_restore.dupcnt,
                                       ncopies);
 
      loop
          if not docopies then
             krmicd.writeMsg(8038, krmicd.getChid, to_char(pieceno+1),
                             to_char(sysdate));
          end if;
 
          declare
              type names is table of varchar2(512) index by binary_integer;
              fnames             names;
              lformat            names;
              lyear              varchar2(4);
              lday               varchar2(2);
              lmonth             varchar2(2);
              copyaux            number;
              chtype             varchar2(16);
              busy_retries       number := 0;
              piecefmt           varchar2(512);
              orig_fname         varchar2(512);
              set_stamp          number;
              set_count          number;
              deffmt             binary_integer;
              dest               binary_integer := 0;
              netalias           varchar2(1000) := NULL;
              new_reusefile      boolean := reusefile ;
          begin
          <<snapshot>>
              begin
              select to_char(sysdate, 'YYYY',
                             'NLS_CALENDAR=Gregorian'),
                     to_char(sysdate, 'MM',
                             'NLS_CALENDAR=Gregorian'),
                     to_char(sysdate, 'DD',
                             'NLS_CALENDAR=Gregorian')
                into lyear, lmonth, lday
                from x$dual;
 
--
              lformat(0) := NULL;
 
--
 
--
--
--
              &lformat&
 
--
--
--
              copy := 0;
              while copy < ncopies loop
                  begin
--
                  piecefmt := lformat(mod(copy, nformat));
                  krmicd.getFormat(format  => piecefmt,
                                   copy    => copy+1,
                                   deffmt  => deffmt,
                                   dest    => dest);
 
--
--
--
                  chtype := krmicd.getDevType;
                  if chtype is null then
                     chtype := 'N/A';
                  elsif (docopies and chtype != 'DISK') then
                     chtype := 'DISK';
                  end if;
 
                  &savepiecename&
 
                  if docopies then
                     orig_fname := fname;
                  else
                     orig_fname := NULL;
                  end if;
 
                  deb('bu_create_genpiece',
                   'pieceno: '        || nvl(to_char(pieceno),'-NULL-')        ||
                   ' setid: '         || nvl(to_char(setid),'-NULL-')          ||
                   ' stamp: '         || nvl(to_char(stamp),'-NULL-')          ||
                   ' format: '        || nvl(piecefmt,'-NULL-')                ||
                   ' copy: '          || nvl(to_char(copy),'-NULL-')           ||
                   ' chtype: '        || nvl(chtype,'-NULL-')                  ||
                   ' lyear: '         || nvl(lyear,'-NULL-')                   ||
                   ' lmonth: '        || nvl(lmonth,'-NULL-')                  ||
                   ' lday: '          || nvl(lday,'-NULL-')                    ||
                   ' foreign_dbid: '  || nvl(to_char(foreign_dbid),'-NULL-')   ||
                   ' ndbname: '       || nvl(foreign_dbname,'-NULL-')          ||
                   ' dfnumber: '      || nvl(to_char(dfnumber),'-NULL-')       ||
                   ' tsname: '        || nvl(tsname,'-NULL-')                  ||
                   ' logseq: '        || nvl(to_char(sequence),'-NULL-')       ||
                   ' logthr: '        || nvl(to_char(thread),'-NULL-')
                   );
 
                  fnames(copy) :=
                      sys.dbms_backup_restore.genPieceName(
                         pno => pieceno+1,
                         set_count => setid,
                         set_stamp => stamp,
                         format => piecefmt,
                         copyno => copy+1,
                         devtype => chtype,
                         year => lyear,
                         month => lmonth,
                         day => lday,
                         dbid => foreign_dbid,
                         ndbname => foreign_dbname,
                         cfseq => NULL,     -- not used
                         fileno => dfnumber,
                         tsname => tsname,
                         logseq => to_char(sequence),
                         logthr => thread,
                         imagcp => docopies,
                         savepname => savepiecename,
                         fname => orig_fname,
                         forcnvrt => processfile);
 
--
                  istmplt := FALSE;
                  if (chtype = 'DISK') then
                     sys.dbms_backup_restore.isfileNameOMF(
                                              fname   => fnames(copy),
                                              isomf   => isomf,
                                              isasm   => isasm,
                                              istmplt => istmplt);
                     if deffmt != 0 then
                        if (doconvert and docopies) then
                           raise cnvrt_need_format;
                        elsif (incremental and backup_level is null) then
                           raise bkp_need_format;
                        end if;
                     end if;
                  end if;
 
--
--
                  copyaux := 0;
                  while (not istmplt and dest = 0 and copyaux < copy) loop
                      if fnames(copy) = fnames(copyaux) then
                          raise wrong_format;
                      end if;
                      copyaux := copyaux + 1;
                  end loop;
--
                  if (copy > 0) then
                      sys.dbms_backup_restore.backupPieceCrtDupSet(copy,
                                                                fnames(copy));
                  end if;
                  end;
                  copy := copy + 1;
              end loop;
--
--
              copy := 0;
 
--
--
--
              if docopies and msb_is_first_section and not validateopt then
                 deb('bu_create ','Msc: Front Loader');
 
                 sys.dbms_backup_restore.initMSC(fname  => fnames(copy),
                                                 deffmt => deffmt, 
                                                 dest   => dest, 
                                                 handle => handle);
 
                 deb('bu_create ', 'HANDLE:'||handle);
 
--
--
--
--
                 krmicd.setMSC(handle);
              end if;
 
--
--
--
              if processfile and not transontarget then
                 if krmicd.checkFailedBP(fnames(copy), pieceno) then
                    new_reusefile := TRUE;
                    deb('bu_create ', 'reusefile ');
                 else
                    deb('bu_create ', 'save file name');
--
--
                    new_reusefile := reusefile;
                    krmicd.saveBpName(fnames(copy), pieceno); 
                 end if;
                 sys.dbms_backup_restore.backupPieceCreate(
                     fname            => fnames(copy),
                     pieceno          => pieceno,
                     done             => done,
                     handle           => handle,
                     comment          => comment,
                     media            => media,
                     concur           => concur,
                     &args_create&,
                     reuse            => new_reusefile,
                     archlog_failover => larchlog_failover,
                     deffmt           => deffmt,
                     recid            => cprecid,
                     stamp            => cpstamp,
                     tag              => cptag,
                     dest             => dest,
                     post10_2         => TRUE,
                     netalias         => netalias,
                     docompress       => docompress,
                     compressalg      => compressalg,
                     compressasof     => compressasof,
                     compresslopt     => compresslopt);
 
--
                krmicd.fileRestored(ftype      => rman_constant.DATAFILE,
                                    fno        => nvl(dfnumber, 0),
                                    thread     => 0,
                                    sequence   => 0,
                                    resetscn   => 0,
                                    resetstamp => 0,
                                    fname      => handle);
 
--
--
--
                sys.dbms_backup_restore.pieceContextGetNumber(
                          sys.dbms_backup_restore.signal_change_tracking_error,
                          chg_tracking_err);
                if chg_tracking_err = 1 then
                   krmicd.writeMsg(8606);
                end if;
              else
                done := TRUE;
              end if;
 
              if larchlog_failover then
                 failoverdone := TRUE;
              end if;
 
              if concur then
                 krmicd.writeMsg(8135, fname);
              end if;
 
              if done then
                 sys.dbms_backup_restore.backupCancel();
              end if;
 
              exception
                  when sys.dbms_backup_restore.snapshot_enqueue_busy then
--
--
--
--
--
--
                     if busy_retries = 180 then
                        krmicd.writeMsg(20029, 
                                        'cannot make a snapshot controlfile');
                        sys.dbms_backup_restore.backupCancel();         
                        raise;
                     end if;
 
                     busy_retries := busy_retries + 1;
--
                     if (mod(busy_retries, 15) = 0) then
                        krmicd.writeMsg(8512);
                     end if;
                     krmicd.sleep(20);
                     krmicd.clearErrors;
                     goto snapshot;
              end;    
              krmicd.writeIOs(stamp, setid);
          end; -- snapshot controlfile stuff
          if not docopies then
              if ncopies = 1 then
                  krmicd.writeMsg(8044, krmicd.getChid, to_char(pieceno),
                                  to_char(sysdate));
              else
--
--
                  if cptag is not null then
                     krmicd.writeMsg(8053, krmicd.getChid, to_char(pieceno),
                                     to_char(sysdate), to_char(ncopies),
                                     cptag);
                  else
                     krmicd.writeMsg(8045, krmicd.getChid, to_char(pieceno),
                                     to_char(sysdate), to_char(ncopies));
                  end if;
              end if;
          end if;
          copy := 0;
 
--
--
--
          if processfile and not transontarget then
            while copy < ncopies loop
                if (copy > 0) then
--
                    sys.dbms_backup_restore.backupPieceCrtDupGet(copy,
                                                                 handle,
                                                                 comment,
                                                                 media);
                end if;
                if not docopies then
                    if comment is null then comment := 'NONE'; end if;
 
--
--
--
--
                    if ncopies = 1 and cptag is not null then
                       krmicd.writeMsg(8530, handle, cptag, comment);
                    else
                       krmicd.writeMsg(8503, handle, comment);
                    end if;
                else
                    if doconvert then
                       krmicd.writeMsg(8588, handle);
                    else
                       if cptag is NOT NULL then
                          if cprecid = 0 and cpstamp = 0 then
                             krmicd.writeMsg(8592, handle, cptag);
                          else
                             krmicd.writeMsg(8586, handle, cptag, 
                                             to_char(cprecid),
                                             to_char(cpstamp));
                          end if;
                       else
                          krmicd.writeMsg(8501, handle, to_char(cprecid),
                                          to_char(cpstamp));
                       end if;
                    end if;
                end if;
                copy := copy + 1;
            end loop;
          end if;
          if done then
             elapsed := currentTime() - starttime;
             dur2time(elapsed, hours, mins, secs);
 
             if failoverdone then
                krmicd.writemsg(8112, krmicd.getChid);
             end if;
 
             if not docopies then
                m := 8540;
             elsif processfile then
                if transontarget then
                   m := 8306;
                elsif doconvert then
                   m := 8590;
                end if;
             end if;
 
             if processfile then
                krmicd.writemsg(m, krmicd.getChid,
                                to_char(hours, 'FM09') || ':' ||
                                to_char(mins,  'FM09') || ':' ||
                                to_char(secs,  'FM09'));
             end if;
             if dpfname is not null then
                sys.dbms_backup_restore.deleteFile(dpfname);
             end if;
             exit;
          end if;
      end loop;
  end if;
  first_time := TRUE;  -- in case we will be deleting what we backed up
>>>
 
define bu_validate
<<<
--
<<create_piece>>
  sys.dbms_backup_restore.backupStatus(state, setid, stamp, pieceno, files,
                                         datafiles, incremental, nochecksum,
                                         device);
 
  starttime := currentTime();
 
--
--
 
  if (files = 0) then
      sys.dbms_backup_restore.backupCancel;
      krmicd.writeMsg(8057, krmicd.getChid);
  else
      declare
          busy_retries  number := 0;
          m             number;
          blkstat       sys.dbms_backup_restore.blockStatTable_t;
          blkRangeTable sys.dbms_backup_restore.blockRangeTable_t;
          blkRange      sys.dbms_backup_restore.blockRange_t;
          firstcall     boolean := TRUE;
      begin 
         loop
            exit when not krmicd.validateBlockGetNext(
                             firstcall     => firstcall,
                             dfnumber      => blkRange.dfnumber,
                             blknumber     => blkRange.blknumber,
                             range         => blkRange.range);
            blkRangeTable(blkRangeTable.count + 1) := blkRange;
            firstcall := FALSE;
            deb('bu_validate', 'dfnumber = ' || blkRange.dfnumber  ||
                             ' blknumber = ' || blkRange.blknumber ||
                             ' count = '     || blkRange.range);
         end loop;
         sys.dbms_backup_restore.validateBlock(blkRangeTable);
 
      <<snapshot>>
          newcorrupt := FALSE;
          begin
              sys.dbms_backup_restore.backupValidate(
                              archlog_failover  => larchlog_failover,
                              nocleanup         => TRUE,
                              compress_set      => docompress,
                              nbr_option        => nonlogblk);
              if larchlog_failover then
                 failoverdone := TRUE;
              end if;
              sys.dbms_backup_restore.getBlockStat(blkstat);
              for i in 1..blkstat.count loop
                 krmicd.copyBlockStat(
                    filetype     => blkstat(i).filetype
                   ,dfnumber     => blkstat(i).dfnumber
                   ,thread       => blkstat(i).thread
                   ,sequence     => blkstat(i).sequence
                   ,highscn      => blkstat(i).highscn
                   ,examined     => blkstat(i).examined
                   ,corrupt      => blkstat(i).corrupt
                   ,empty        => blkstat(i).empty
                   ,data_proc    => blkstat(i).data_proc
                   ,data_fail    => blkstat(i).data_fail
                   ,index_proc   => blkstat(i).index_proc
                   ,index_fail   => blkstat(i).index_fail
                   ,other_proc   => blkstat(i).other_proc
                   ,other_fail   => blkstat(i).other_fail
                   ,nonlogblk    => blkstat(i).nonlogblk
                   ,mirrornum    => blkstat(i).mirrornum
                   ,status       => blkstat(i).status);
 
                 if (blkstat(i).data_fail  > 0 or
                     blkstat(i).index_fail > 0 or
                     blkstat(i).other_fail > 0) then
                    newcorrupt := TRUE;
                 end if;
              end loop;
              sys.dbms_backup_restore.backupCancel();
          exception
              when sys.dbms_backup_restore.snapshot_enqueue_busy then
--
--
--
--
                 if busy_retries = 180 then
                    krmicd.writeMsg(20029, 'cannot make a snapshot controlfile');
                    raise;
                 end if;
 
                 busy_retries := busy_retries + 1;
--
                 if (mod(busy_retries, 15) = 0) then
                    krmicd.writeMsg(8512);
                 end if;
                 krmicd.sleep(20);
                 krmicd.clearErrors;
                 goto snapshot;
          end;
      end; -- <<snapshot>>
      elapsed := currentTime() - starttime;
      dur2time(elapsed, hours, mins, secs);
      if failoverdone then
         krmicd.writemsg(8112, krmicd.getChid);
      end if;
      if validatecmd then
         m := 8144;
      elsif not docopies then
         m := 8540;
      else
         if doconvert then
            m := 8590;
         else
            m := 8581;
         end if;
      end if;
      krmicd.writemsg(m, krmicd.getChid,
                      to_char(hours, 'FM09') || ':' ||
                      to_char(mins,  'FM09') || ':' ||
                      to_char(secs,  'FM09'));
      krmicd.listBlockStat;
      if (newcorrupt) then
         krmicd.setErrState;
         krmicd.writeMsg(8190);
         krmicd.writeMsg(8191, sys.dbms_backup_restore.getParm(
                                   sys.dbms_backup_restore.TRACE_FILENAME));
      end if;
  end if;
>>>
 
define bu_copy
<<<
--
   start_time := currentTime();
 
   max_copy := krmicd.getmaxcopyno(set_stamp => set_stamp,
                                   set_count => set_count);
   if piececnt = 0 then
      krmicd.writeMsg(8105, krmicd.getChid);
   else
      if pltfrmfr is NOT NULL then
         cnvrtfr := TRUE;
         declare
            pname   varchar2(101);
         begin
            if nofrpltfrm THEN
               krmicd.writeMsg(8559, krmicd.getChid);
            else
               select platform_name
                 into pname
                 from v$transportable_platform
                where platform_id = pltfrmfr;
               krmicd.writeMsg(8558, krmicd.getChid, pname);
            end if;
         end;
      else
         if docompress then
            krmicd.writeMsg(8631, krmicd.getChid, to_char(pieceno),
                            to_char(sysdate));
         else
            krmicd.writeMsg(8038, krmicd.getChid, to_char(pieceno),
                            to_char(sysdate));
         end if;
      end if;
 
      declare
         type names is table of varchar2(512) index by binary_integer;
         copyaux            number;
         fnames             names;
         busy_retries       number := 0;
         lyear              varchar2(4);
         lday               varchar2(2);
         lmonth             varchar2(2);
         lformat            names;
         piecefmt           varchar2(512);
         piececopy          number;
         lcfaudate          varchar2(512);
         cfaudate           date;
         lsequence          number;
         deffmt             binary_integer;
         dest               binary_integer := 0;
         rc                 binary_integer;
         rcva_enabled       boolean;              
         dummy_bool         boolean;
         dummy_num          number;
         outtag             varchar2(31);
      begin
         lformat(0) := NULL;                     -- initalize  the format
 
--
--
--
--
--
         &lcfaudate&
         &lsequence&
         &ncopies&
         &lformat&
         cfaudate := to_date(lcfaudate, 'YYYY-MM-DD HH24:MI:SS',
                             'NLS_CALENDAR=Gregorian');
 
         select to_char(nvl(cfaudate, sysdate), 'YYYY',
                        'NLS_CALENDAR=Gregorian'),
                to_char(nvl(cfaudate, sysdate), 'MM',
                        'NLS_CALENDAR=Gregorian'),
                to_char(nvl(cfaudate, sysdate), 'DD',
                        'NLS_CALENDAR=Gregorian')
           into lyear, lmonth, lday
           from x$dual;
 
         if lsequence is not NULL and
            lsequence >=0 and lsequence <=255 and
            ncopies = 1 then
            cfauto := TRUE;        -- controlfile autobackup piece
         end if;
 
         chtype        := krmicd.getDevType;
 
         if chtype is null then
            chtype := 'N/A';
         end if;
 
         sys.dbms_backup_restore.setLimit(sys.dbms_backup_restore.dupcnt,
                                          ncopies);
 
 
--
--
--
 
         copy := 0;
         while copy < ncopies loop
            begin
--
               piecefmt := lformat(mod(copy, nformat));
                  
               skipped  := FALSE;
 
               if cfauto then
                  krmicd.getFormat(format => piecefmt,
                                   copy   => copy+1,
                                   cfauto => TRUE,
                                   deffmt => deffmt,
                                   dest   => dest);
               else
                  krmicd.getFormat(format => piecefmt,
                                   copy   => copy+1,
                                   deffmt => deffmt,
                                   dest   => dest);
               end if;
 
               fnames(copy) :=
                  sys.dbms_backup_restore.genPieceName(
                           pno => pieceno,
                           set_count => set_count,
                           set_stamp => set_stamp,
                           format => piecefmt,
                           copyno => copy+max_copy+1,
                           devtype => chtype,
                           year => lyear,
                           month => lmonth,
                           day => lday,
                           dbid => null,     -- computed in server if required
                           ndbname => null,  -- computed in server if required
                           pdbname => null,  -- computed in server if required
                           cfseq => lsequence);
 
--
               istmplt := FALSE;
               if (chtype = 'DISK') then
                  sys.dbms_backup_restore.isfileNameOMF(
                           fname   => fnames(copy),
                           isomf   => isomf,
                           isasm   => isasm,
                           istmplt => istmplt);
               end if;
 
--
               copyaux := 0;
               while (not istmplt and dest = 0 and copyaux < copy) loop
                  if fnames(copy) = fnames(copyaux) then
                     raise wrong_format;
                  end if;
                  copyaux := copyaux + 1;
               end loop;
 
--
               if (copy > 0) then
                  sys.dbms_backup_restore.backupPieceCrtDupSet(copy,
                                                               fnames(copy));
               end if;
            end;
            copy := copy + 1;
         end loop;
 
--
         piececopy := 0;      -- start with first copy;
 
         <<failover>>
         begin
--
--
--
--
--
--
            if cfauto then
               rcva_enabled := is_recovery_area_enabled();
               if chtype != 'DISK' or not rcva_enabled or deffmt = 0 then
                  rc := sys.dbms_backup_restore.validateBackupPiece(
                                 recid      => 0,
                                 stamp      => 0,
                                 handle     => fnames(0),
                                 set_stamp  => set_stamp,
                                 set_count  => set_count,
                                 pieceno    => 0,
                                 params     => NULL,
                                 hdl_isdisk => 0);
                  if bitand(rc, 
                       sys.dbms_backup_restore.validate_file_different) = 0
                  then
                     skipped := TRUE;
                  end if;
               elsif rcva_enabled and deffmt != 0 then
--
--
                  if pisrdf(piececopy) then
                     skipped := TRUE;
                  end if;
               end if;
            end if;
 
            if (not skipped) then
               krmicd.writeMsg(8013, krmicd.getChid, pnames(piececopy));
 
               sys.dbms_backup_restore.backupSetPiece(
                  &args_tag&,
                  &args_start&,
                  convertfr => cnvrtfr,
                  pltfrmfr  => pltfrmfr,
                  orsbck    => FALSE); 
 
               setBackupParams(FALSE);
 
               sys.dbms_backup_restore.backupPieceBackup(
                  bpname       => pnames(piececopy),
                  copyno       => max_copy,
                  copy_recid   => precid(piececopy),
                  copy_stamp   => pstamp(piececopy),
                  npieces      => npieces);
  
               sys.dbms_backup_restore.backupPieceCreate(
                        fname            => fnames(0),
                        pieceno          => dummy_num,
                        done             => dummy_bool,
                        handle           => handle,
                        comment          => comment,
                        media            => media,
                        concur           => concur,
                        &args_create&,
                        &args_reuse&,
                        archlog_failover => dummy_bool,
                        deffmt           => deffmt,
                        recid            => recid,
                        stamp            => stamp,
                        tag              => outtag,
                        docompress       => docompress,
                        dest             => dest,
                        post10_2         => TRUE,
                        netalias         => NULL,
                        compressalg      => compressalg,
                        compressasof     => compressasof,
                        compresslopt     => compresslopt);
 
               sys.dbms_backup_restore.backupCancel();
 
--
               copy := 0;
               while (copy < ncopies) loop
                  if (copy > 0) then
--
                     sys.dbms_backup_restore.backupPieceCrtDupGet(
                        copy, handle, comment, media);
                  end if;
                                                                   
                  if comment is null then
                     comment := 'NONE';
                  end if;
                  krmicd.writeMsg(8503, handle, comment);
                  copy := copy + 1;
               end loop;
            else
               krmicd.writeMsg(8119, pnames(piececopy));
            end if;
         exception
           when sys.dbms_backup_restore.retryable_error_exp then
               sys.dbms_backup_restore.backupCancel();
               piececopy := piececopy + 1;
               if (piececopy >= piececnt) then
                  raise;
               end if;
               krmicd.writeMsg(8110);
               krmicd.clearErrors;  -- clear failover errors
               goto failover;
            when in_use then
               sys.dbms_backup_restore.backupCancel();
               krmicd.writeMsg(8603, pnames(piececopy));
               piececopy := piececopy + 1;
               if (piececopy < piececnt) then
                  krmicd.writeMsg(8110);
                  krmicd.clearErrors;  -- clear failover errors
                  goto failover;
               else
                  krmicd.clearErrors;
               end if;
             when del_for_space then
               sys.dbms_backup_restore.backupCancel();
                krmicd.writeMsg(8604, pnames(piececopy));
                piececopy := piececopy + 1;
                if (piececopy < piececnt) then
                   krmicd.writeMsg(8110);
                   krmicd.clearErrors;  -- clear failover errors
                   goto failover;
                else
                   krmicd.clearErrors;
                end if;
             when dropped_pdb_file then
               sys.dbms_backup_restore.backupCancel();
                krmicd.writeMsg(6826,  pnames(piececopy));
                piececopy := piececopy + 1;
                krmicd.clearErrors;
             when others then
               sys.dbms_backup_restore.backupCancel();
               raise;
         end;
 
         if ncopies = 1 then
            krmicd.writeMsg(8044, krmicd.getChid, to_char(pieceno),
                            to_char(sysdate));
         else
            krmicd.writeMsg(8045, krmicd.getChid, to_char(pieceno),
                            to_char(sysdate), to_char(ncopies));
         end if;
 
         elapsed := currentTime() - start_time;
         dur2time(elapsed, hours, mins, secs);
         krmicd.writemsg(8556, krmicd.getChid,
                         to_char(hours, 'FM09') || ':' ||
                         to_char(mins,  'FM09') || ':' ||
                         to_char(secs,  'FM09'));
 
      end;
   end if;
>>>
 
define copyfil_xfer
<<<
--
  lformat(0) := NULL;
 
--
--
--
  &lformat&
 
--
--
  if (lformat(0) is null) then
    raise cpfil_unsupported;
  end if;
 
  worked := sys.dbms_backup_restore.networkFileTransfer(
                  dbname      => netalias,
                  username    => null,
                  passwd      => null,
                  srcfile     => src_name,
                  destfile    => lformat(0),
                  operation   => 'read');
>>>
 
define budc_begin_del
<<<
--
declare
  copy_recid        number;
  copy_stamp        number;
  fname             varchar2(1024);
  dfnumber          number;
  resetlogs_change  number;
  creation_change   number;
  checkpoint_change number;
  blksize           number;
  no_delete         binary_integer;
begin
>>>
 
define budc_del
<<<
--
  &object&
  del_copy(copy_recid, copy_stamp, fname, dfnumber, resetlogs_change,
           creation_change, checkpoint_change, blksize, no_delete);
>>>
 
define budc_end_del
<<<
--
end;
>>>
 
 
define bual_begin_del
<<<
--
declare
  cfisstby          boolean := FALSE;
  arch_recid        number;
  arch_stamp        number;
  fname             varchar2(512);
  thread            number;
  sequence          number;
  resetlogs_change  number;
  resetlogs_time    varchar2(512);
  first_change      number;
  blksize           number;
  next_change       number;
  first_time        boolean := TRUE;
  docopies          boolean := FALSE;
  reqscn            number;     -- streams/standby required scn
  rlgscn            number;     -- streams/standby resetlogs scn
  appscn            number;
  apprlgscn         number;
  alldest           number := 0;
  reqbackups        number;
  nbackups          number;
begin
>>>
 
 
define bual_del
<<<
--
  &object&
  del_log(cfisstby, arch_recid, arch_stamp, fname, thread, sequence,
          resetlogs_change, resetlogs_time, first_change, blksize,
          next_change, first_time, docopies, reqscn, rlgscn, appscn,
          apprlgscn, alldest, reqbackups, nbackups);
>>>
 
define bual_end_del
<<<
--
end;
>>>
 
 
define bubp_begin_del
<<<
--
declare
  skipped           boolean       := FALSE;     -- skipped this backuppiece
  handle            varchar2(1024);
  recid             number;
  stamp             number;
begin
>>>
 
define bubp_del
<<<
--
  &object&
--
--
--
--
--
--
  if ((not skipped) or (krmicd.getDevType != 'DISK')) then
     sys.dbms_backup_restore.changeBackupPiece(
                  handle    => handle,
                  recid     => recid,
                  stamp     => stamp,
                  status    => 'S',
                  &args&
               );
     krmicd.writeMsg(8073);
     krmicd.writeMsg(8517, handle, to_char(recid), to_char(stamp));
  end if;
>>>
 
define bubp_end_del
<<<
--
end;
>>>
 
 
define bu_end
<<<
--
  if (endBackupJobStep(FALSE, 0)) then null; end if;
  sys.dbms_backup_restore.setRmanStatusRowId(rsid=>0, rsts=>0);
exception
  when others then
     if (not endBackupJobStep(TRUE, sqlcode)) then
        raise;
     end if;
     sys.dbms_backup_restore.setRmanStatusRowId(rsid=>0, rsts=>0);
end;
>>>
 
define switch_prim_bct
<<<
begin
   sys.dbms_backup_restore.switch_primary_bct();
end;
>>>
 
define restoredfc
<<<
--
declare
  recid             number;
  stamp             number;
  copy_recid        number;
  copy_stamp        number;
  dfnumber          number;
  old_dfnumber      number;
  fname             varchar2(512) := null;      -- restore dest
  max_corrupt       number := 0;
  full_name         varchar2(512);              -- output filename
  copy              varchar2(512);              -- input filename
  check_logical     boolean := false;
  byduplicate       boolean := false;
  preplugin         boolean := false;
  pdbid             number;
  pplcdbdbid        number;
  blksize           number := 0;
  blocks            number := 0;
  rfno              number := 0;
  lowscn            varchar2(41) := null;
  identical         boolean := FALSE;
  force             boolean := FALSE;
  rsid              number;
  rsts              number;
  tsname            varchar2(512) := null;
  found             boolean;
  inst_restore      number  := 0;
  sparse_restore    number  := 0;
  hours             number;
  mins              number;
  secs              number;
  starttime         date;
  elapsed           number;
begin
  &object&
 
  found := krmicd.valGetFound(copy_recid, copy_stamp);
 
  sys.dbms_backup_restore.setRmanStatusRowId(rsid=>rsid, rsts=>rsts);
 
  krmicd.writeMsg(8019, krmicd.getChid, to_char(dfnumber, 'FM09999'));
  krmicd.writeMsg(8507, to_char(copy_recid), to_char(copy_stamp), copy);
 
  if fname is not null then
    krmicd.writeMsg(8509, to_char(dfnumber, 'FM09999'), fname);
    if (identical and force) then
--
--
--
        krmicd.writeMsg(8552, fname);
        return;
    end if;
  end if;
 
  begin 
    starttime := currentTime();
 
    if byduplicate and copy is not null and fname is not null then
       sys.dbms_backup_restore.resDataFileCopy(
                             cname           => copy,
                             fname           => fname,
                             full_name       => full_name,
                             max_corrupt     => max_corrupt,
                             check_logical   => check_logical,
                             blksize         => blksize,
                             blocks          => blocks,
                             fno             => dfnumber,
                             scnstr          => lowscn,
                             rfno            => rfno,
                             tsname          => tsname,
                             sparse_restore  => sparse_restore);
    elsif preplugin then
       sys.dbms_backup_restore.copyDataFileCopy(
                             full_name        => full_name,
                             cname            => copy,
                             fno              => dfnumber,
                             oldfno           => old_dfnumber,
                             rfno             => rfno,
                             blksize          => blksize,
                             blocks           => blocks,
                             fname            => fname,
                             max_corrupt      => max_corrupt,
                             check_logical    => check_logical,
                             inst_restore     => inst_restore,
                             preplugin        => true,
                             sparse_restore  => sparse_restore);
    else
       sys.dbms_backup_restore.copyDataFileCopy(
                             full_name        => full_name,
                             recid            => recid,
                             stamp            => stamp,
                             fname            => fname,
                             copy_recid       => copy_recid,
                             copy_stamp       => copy_stamp,
                             max_corrupt      => max_corrupt,
                             check_logical    => check_logical,
                             inst_restore     => inst_restore,
                             sparse_restore   => sparse_restore);
    end if;
 
    elapsed := currentTime() - starttime;
    dur2time(elapsed, hours, mins, secs);
    krmicd.writeMsg(8007, krmicd.getChid, to_char(dfnumber, 'FM09999'),
                          to_char(hours, 'FM09') || ':' ||
                          to_char(mins,  'FM09') || ':' ||
                          to_char(secs,  'FM09'));
 
    if byduplicate and copy is not null and fname is not null then
       krmicd.writeMsg(8505, full_name);
    elsif preplugin then
       krmicd.writeMsg(8505, full_name);
    else
       krmicd.writeMsg(8501, full_name, to_char(recid),to_char(stamp));
    end if;
 
    krmicd.fileRestored(ftype      => rman_constant.DATAFILE,
                        fno        => dfnumber,
                        thread     => 0,
                        sequence   => 0,
                        resetscn   => 0,
                        resetstamp => 0,
                        fname      => full_name);
  exception
    when sys.dbms_backup_restore.retryable_error_exp then
       if not krmicd.doRestoreFailover(rman_constant.DATAFILE) then
          raise;
       end if;
--
       krmicd.writeErrMsg(1005, sqlerrm);
       krmicd.clearErrors;
    when others then
       raise;
  end;
end;
>>>
 
define restorecfc
<<<
--
declare
  src_name   varchar2(512);
  dest_name  varchar2(512);
  full_name  varchar2(512);
  recid      number;
  stamp      number;
  currcf     boolean;
  identical  boolean := FALSE;
  force      boolean := FALSE;
  rsid       number;
  rsts       number;
  isstby     boolean := FALSE;
  nocfconv   boolean := FALSE;
  isfarsync  boolean := FALSE;
begin
  &object&
 
  sys.dbms_backup_restore.setRmanStatusRowId(rsid=>rsid, rsts=>rsts);
  krmicd.writeMsg(8021, krmicd.getChid);
  if (not currcf) then
     krmicd.writeMsg(8505, dest_name);
  end if;
 
  if (identical and force) then
--
--
--
     krmicd.writeMsg(8552, dest_name);
     return;
  end if;
 
  begin
     sys.dbms_backup_restore.copyControlFile(full_name => full_name,
       recid => recid, stamp => stamp, src_name => src_name,
       dest_name => dest_name);
     krmicd.writeMsg(8025, krmicd.getChid);
     krmicd.writeMsg(8506, src_name);
     if (currcf) then
        print_controlfile;
     else
        krmicd.writeMsg(8501, full_name, to_char(recid), to_char(stamp));
     end if;
 
     krmicd.fileRestored(ftype      => rman_constant.CONTROLFILE,
                         fno        => 0,
                         thread     => 0,
                         sequence   => 0,
                         resetscn   => 0,
                         resetstamp => 0);
  exception
    when sys.dbms_backup_restore.retryable_error_exp then
       if not krmicd.doRestoreFailover(rman_constant.CONTROLFILE) then
          raise;
       end if;
--
       krmicd.writeErrMsg(1005, sqlerrm);
       krmicd.clearErrors;
    when others then
       raise;
  end;
  sys.dbms_backup_restore.setRmanStatusRowId(rsid=>0, rsts=>0);
end;
>>>
 
define rsdf_start
<<<
--
declare
  /* restoreStatus: rsdf_start */
  state            binary_integer;
  pieces_done      binary_integer;
  files            binary_integer;
  datafiles        boolean;
  incremental      boolean;
  device           boolean;
  /* restorebackuppiece */
  done             boolean;
  currcf           boolean;
  fhandle          varchar2(512);
  handle           varchar2(512);
  outhandle        varchar2(512);
  params           varchar2(512);
  fromdisk         boolean;              -- TRUE => backupset on disk
  /* Miscellaneous */
  memnum           number;
  piecenum         number;
  dfnumber         number;
  thread           number := null;
  sequence         number := null;
  toname           varchar2(512);
  orgname          varchar2(512);
  tsname           varchar2(512);
  cfname           varchar2(512);
  pfname           varchar2(512);
  sfname           varchar2(512);
  set_count        number;
  set_stamp        number;
  first_time       boolean := TRUE;
  validate         boolean := FALSE;   -- TRUE => only validate
  val_bs_only      boolean := FALSE;   -- TRUE => only bs validation
--
  max_corrupt      binary_integer := 0;
  check_logical    boolean := FALSE;
  tag              varchar2(31);
  outtag           varchar2(31);
  bmr              boolean := FALSE;
  blocks           number;
  blksize          number;
  failover         boolean := FALSE;
  devtype          varchar2(512);
  rsid             number;
  rsts             number;
  err_msg          varchar2(2048);
  start_time       date;
  recid            number;
  stamp            number;
  preview          boolean := FALSE;
  recall           boolean := FALSE;
  isstby           boolean := FALSE;
  nocfconv         boolean := FALSE;
  msrpno           number := 0;
  msrpct           number := 0;
  isfarsync        boolean := FALSE;
  networkfdf       boolean := FALSE;     
  sameend          boolean := TRUE;
  preplugin        boolean := FALSE;
  pdbid            number;
  pplcdbdbid       number;
  ppltrans         number;
  old_dfnumber     number;
  sparse_restore   number := 0;
  encdec_restore   number := 0;
  restore_not_complete exception;
 
begin
  &1&
 
--
  if preview then
     deb('rsdf_start', 'preview');
     return;
  end if;
 
  if (preplugin) then
     ppltrans := sys.dbms_backup_restore.beginPrePluginTranslation(
                    pdbid => pdbid, pplcdbdbid => pplcdbdbid);
  end if;
 
  sys.dbms_backup_restore.restoreStatus(state, pieces_done, files, datafiles,
                       incremental, device);
  if (msrpno > 1) then
--
--
--
--
    pieces_done := msrpno - 1;
  end if;
  start_time := currentTime();
  if state = sys.dbms_backup_restore.restore_no_conversation then
    goto start_convo;
  elsif state = sys.dbms_backup_restore.restore_naming_files then
    goto name_files;
  else
    goto restore_piece;
  end if;
 
<<start_convo>>
  sys.dbms_backup_restore.setRmanStatusRowId(rsid=>rsid, rsts=>rsts);
  sys.dbms_backup_restore.restoreSetDataFile(
      check_logical    => check_logical
     ,cleanup          => FALSE
     ,service          => NULL
     ,chunksize        => 0
     ,rs_flags         => 0
     ,preplugin        => preplugin
     ,sparse_restore   => sparse_restore
     ,encdec_restore   => encdec_restore);
  incremental := FALSE;
  if bmr then
    krmicd.writeMsg(8106, krmicd.getChid);
  elsif validate then
    krmicd.writeMsg(8096, krmicd.getChid);
  else
    krmicd.writeMsg(8016, krmicd.getChid);
  end if;
 
  setRestoreParams;
<<name_files>>
  deb('rsdf_start', 'set_stamp=' || set_stamp || ' set_count=' || set_count,
      rman_constant.DEBUG_IO, rman_constant.LEVEL_MIN);
>>>
 
define ridf_start
<<<
--
declare
  /* restoreStatus: ridf_start */
  state       binary_integer;
  pieces_done binary_integer;
  files       binary_integer;
  datafiles   boolean;
  incremental boolean;
  device      boolean;
  /* restorebackuppiece */
  done        boolean;
  currcf      boolean;
  fhandle     varchar2(512);
  handle      varchar2(512);
  outhandle   varchar2(512);
  params      varchar2(512);
  fromdisk    boolean;              -- TRUE => backupset on disk
  /* Miscellaneous */
  memnum      number;
  piecenum    number;
  dfnumber    number;
  thread      number := null;
  sequence    number := null;
  toname      varchar2(512);
  orgname     varchar2(512);
  cfname      varchar2(512);
  fuzzy_hint  number;
  set_count   number;
  set_stamp   number;
  first_time       boolean := TRUE;
  validate         boolean := FALSE;
  val_bs_only      boolean := FALSE;   -- TRUE => only bs validation
--
  max_corrupt      binary_integer := 0;
  check_logical    boolean := FALSE;
  tag              varchar2(31);
  outtag           varchar2(31);
  bmr              boolean := FALSE;
  blocks           number;
  blksize          number;
  failover         boolean := FALSE;
  devtype          varchar2(512);
  rcvcopy          boolean := FALSE;
  islevel0         binary_integer := 0;
  rsid             number;
  rsts             number;
  err_msg          varchar2(2048);
  start_time       date;
  recid            number;
  stamp            number;
  preview          boolean := FALSE;
  recall           boolean := FALSE;
  isstby           boolean := FALSE;
  nocfconv         boolean := FALSE;
  msrpno           number  := 0;
  msrpct           number  := 0;
  isfarsync        boolean := FALSE;
  preplugin        boolean := FALSE;
  pdbid            number  := 0;
  pplcdbdbid       number  := 0;
  ppltrans         number;
  old_dfnumber     number;
  restore_not_complete exception;
 
begin
  &1&
 
--
  if preview then
     deb('ridf_start', 'preview');
     return;
  end if;
 
  if (preplugin) then
     ppltrans := sys.dbms_backup_restore.beginPrePluginTranslation(
                    pdbid => pdbid, pplcdbdbid => pplcdbdbid);
  end if;
 
  sys.dbms_backup_restore.restoreStatus(state, pieces_done, files, datafiles,
                       incremental, device);
  if (msrpno > 1) then
--
--
--
--
    pieces_done := msrpno - 1;
  end if;
 
  start_time := currentTime();
  if state = sys.dbms_backup_restore.restore_no_conversation then
    goto start_convo;
  elsif state = sys.dbms_backup_restore.restore_naming_files then
    goto name_files;
  else
    goto restore_piece;
  end if;
 
<<start_convo>>
  sys.dbms_backup_restore.setRmanStatusRowId(rsid=>rsid, rsts=>rsts);
  sys.dbms_backup_restore.applySetDatafile(
      check_logical    => check_logical
     ,cleanup          => FALSE
     ,service          => NULL
     ,chunksize        => 0
     ,rs_flags         => 0
     ,preplugin        => preplugin);
  incremental := TRUE;
  krmicd.writeMsg(8039, krmicd.getChid);
 
  setRestoreParams;
<<name_files>>
  deb('ridf_start', 'set_stamp=' || set_stamp || ' set_count=' || set_count,
      rman_constant.DEBUG_IO, rman_constant.LEVEL_MIN);
>>>
 
define rsdf_name
<<<
--
  toname := null;
  max_corrupt := 0;
  &memnum&
  &object&
  if msrpno > 1 and not bmr then
    declare
      tempfno number;
    begin
      krmicd.getMSR(tempfno, toname);
    end;
  end if;
  if files < memnum then
    sys.dbms_backup_restore.restoreDataFileTo(
                        dfnumber     => dfnumber,
                        toname       => toname,
                        max_corrupt  => max_corrupt,
                        tsname       => tsname,
                        old_dfnumber => old_dfnumber);
 
    if msrpno = 1 and not bmr then
      sys.dbms_backup_restore.initMSR(dfnumber, toname);
    end if;
 
    if msrpno > 0 then
      krmicd.setMSR(dfnumber, toname, orgname);
    end if;
 
    if first_time then
       if bmr then
          krmicd.writeMsg(8108, krmicd.getChid);
       else
          krmicd.writeMsg(8089, krmicd.getChid);
       end if;
       first_time := FALSE;
    end if;
    if bmr then
      krmicd.writeMsg(8533, to_char(dfnumber, 'FM09999'));
    else
      if toname is not null then
        krmicd.writeMsg(8610, krmicd.getChid, to_char(dfnumber, 'FM09999'), 
                        toname);
      else
        krmicd.writeMsg(8610, krmicd.getChid, to_char(dfnumber, 'FM09999'),
                        'default location');
      end if;
      deb('rsdf_name', 'blocks=' || blocks || ' block_size=' || blksize,
          rman_constant.DEBUG_IO, rman_constant.LEVEL_MIN);
    end if;
    if (msrpno > 0) then
      krmicd.writeMsg(8555, krmicd.getChid, to_char(msrpno), to_char(msrpct));
    end if;
  end if;
>>>
 
define ridf_name
<<<
--
  toname := null;
  max_corrupt := 0;
  &memnum&
  &object&
  if msrpno > 1 and not bmr then
    declare
      tempfno number;
    begin
      krmicd.getMSR(tempfno, toname);
    end;
  end if;
  if files < memnum then
    sys.dbms_backup_restore.applyDataFileTo(
        dfnumber       => dfnumber,
        toname         => toname,
        fuzziness_hint => fuzzy_hint,
        max_corrupt    => max_corrupt,
        islevel0       => islevel0,
        recid          => recid,
        stamp          => stamp,
        old_dfnumber   => old_dfnumber);
 
    if msrpno = 1 and not bmr then
      sys.dbms_backup_restore.initMSR(dfnumber, toname);
    end if;
 
    if msrpno > 0 then
      krmicd.setMSR(dfnumber, toname, orgname);
    end if;
 
    if first_time then
       if bmr then
          krmicd.writeMsg(8108, krmicd.getChid);
       elsif rcvcopy then
          krmicd.writeMsg(8131, krmicd.getChid);
       else
          krmicd.writeMsg(8089, krmicd.getChid);
       end if;
       first_time := FALSE;
    end if;
 
    if bmr then
      krmicd.writeMsg(8533, to_char(dfnumber, 'FM09999'));
    elsif toname is not null then
      if rcvcopy then
         krmicd.writeMsg(8551, to_char(dfnumber, 'FM09999'), toname);
      else
         krmicd.writeMsg(8509, to_char(dfnumber, 'FM09999'), toname);
      end if;
      deb('ridf_name', 'blocks=' || blocks || ' block_size=' || blksize,
          rman_constant.DEBUG_IO, rman_constant.LEVEL_MIN);
    end if;
    if (msrpno > 0) then
      krmicd.writeMsg(8555, krmicd.getChid, to_char(msrpno), to_char(msrpct));
    end if;
  end if;
>>>
 
define rscf_name
<<<
--
  &object&
  &memnum&
  if files < memnum then
    sys.dbms_backup_restore.restoreControlfileTo(cfname    => cfname,
                                                 isstby    => isstby,
                                                 nocfconv  => nocfconv,
                                                 isfarsync => isfarsync);
    krmicd.writeMsg(8021, krmicd.getChid);
    if (not currcf) then
       krmicd.writeMsg(8505, cfname);
    end if;
  end if;
>>>
 
define rssf_name
<<<
--
  &object&
  &memnum&
  if files < memnum then
    sys.dbms_backup_restore.restoreSpfileTo(pfname => pfname,
                                            sfname => sfname);
    if pfname is not null then
       krmicd.writeMsg(8114, krmicd.getChid);
       krmicd.writeMsg(8505, pfname);
    elsif sfname is not null then
       krmicd.writeMsg(8115, krmicd.getChid);
       krmicd.writeMsg(8505, sfname);
    else
       krmicd.writeMsg(8115, krmicd.getChid);
       krmicd.writeMsg(8116);
    end if;
  end if;
>>>
 
define restore_piece_label
<<<
--
<<restore_piece>>
>>>
 
define rspiece_init
<<<
--
  fhandle := NULL;
  &piecenum&
>>>
 
define rspiece_name
<<<
--
  &object&  -- handle, tag, fromdisk, recid, stamp
  if (pieces_done+1) = piecenum then
    sys.dbms_backup_restore.restoreSetPiece(handle   => handle,
                                            tag      => tag,
                                            fromdisk => fromdisk,
                                            recid    => recid,
                                            stamp    => stamp);
    if fhandle is NULL then
       fhandle := handle;
    end if;
  end if;
>>>
 
define 'x$print_controlfile'
<<<
procedure print_controlfile is
  src_name   varchar2(512);
  dest_name  varchar2(512);
begin
  for i in 1..9999 loop
    dest_name := sys.dbms_backup_restore.getparm(
                 sys.dbms_backup_restore.control_file, i);
    exit when dest_name is null;
    krmicd.writeMsg(8505, dest_name);
  end loop;
end;
>>>
 
define 'x$restore_piece'
<<<
function restore_piece_int(pieces_done IN OUT binary_integer
                          ,piecenum    IN     number
                          ,fhandle     IN     varchar2
                          ,done        OUT    boolean
                          ,params      IN     varchar2
                          ,outhandle   OUT    varchar2
                          ,outtag      OUT    varchar2
                          ,failover    OUT    boolean
                          ,err_msg     OUT    varchar2
                          ,val_bs_only IN     boolean
                          ,validate    IN     boolean
                          ,devtype     OUT    varchar2
                          ,bmr         IN     boolean
                          ,set_stamp   IN     number
                          ,set_count   IN     number
                          ,start_time  IN     date
                          ,incremental IN     boolean
                          ,currcf      IN     boolean
                          ,ppltrans    IN     number) return boolean is
   elapsed number;
   hours   number;
   mins    number;
   secs    number;
begin
--
  if (pieces_done+1) = piecenum then
    begin 
       if (fhandle is not NULL) then
          krmicd.writeMsg(8003, krmicd.getChid, fhandle);
       end if;
       sys.dbms_backup_restore.restoreBackupPiece(done      => done,
                                                  params    => params,
                                                  outhandle => outhandle,
                                                  outtag    => outtag,
                                                  failover  => failover);
    exception
       when sys.dbms_backup_restore.retryable_error_exp then
          err_msg := sqlerrm;
 
          if not krmicd.doRestoreFailover(rman_constant.BACKUPPIECE) then
             raise;
          end if;
 
--
--
--
          if (val_bs_only) then
              raise;
	  end if;
	  if (not validate) then
             getFileRestored(FALSE);
          end if;
          devtype := krmicd.checkBsFailover;
          if (incremental and devtype is null) then
             raise;
          end if;
--
          krmicd.writeErrMsg(8615, krmicd.getChid||': '||err_msg);
          krmicd.clearErrors;
          if (devtype is not null) then
             krmicd.writeMsg(8612, krmicd.getChid, devtype);
          end if;
          return true;
       when others then
          raise;
    end;
    if failover then
       krmicd.writeMsg(8614, krmicd.getChid, fhandle);
       krmicd.writeMsg(8613, krmicd.getChid, outhandle, nvl(outtag, 'NULL'));
    else
       krmicd.writeMsg(8611, krmicd.getChid, outhandle, nvl(outtag, 'NULL'));
    end if;
    if bmr then
      krmicd.writeMsg(8109, krmicd.getChid, to_char(piecenum));
    else
      krmicd.writeMsg(8023, krmicd.getChid, to_char(piecenum));
      krmicd.writeIOs(set_stamp, set_count);
    end if;
    if done then
      elapsed := currentTime() - start_time;
      dur2time(elapsed, hours, mins, secs);
      if (bmr) then
        krmicd.writeMsg(8183, krmicd.getChid,
                              to_char(hours, 'FM09') || ':' ||
                              to_char(mins,  'FM09') || ':' ||
                              to_char(secs,  'FM09'));
      elsif (validate) then
        krmicd.writeMsg(8182, krmicd.getChid,
                              to_char(hours, 'FM09') || ':' ||
                              to_char(mins,  'FM09') || ':' ||
                              to_char(secs,  'FM09'));
      else
        krmicd.writeMsg(8180, krmicd.getChid,
                              to_char(hours, 'FM09') || ':' ||
                              to_char(mins,  'FM09') || ':' ||
                              to_char(secs,  'FM09'));
      end if;
--
      if currcf then
         print_controlfile;
      end if;
      if validate then            -- validate backupset, restore validate cmds
         krmicd.fileRestored(ftype      => rman_constant.BACKUPPIECE,
                             fno        => 0,
                             thread     => 0,
                             sequence   => 0,
                             resetscn   => 0,
                             resetstamp => 0);
      else
         getFileRestored(FALSE);
      end if;
      if (ppltrans > 0) then
         sys.dbms_backup_restore.endPrePluginTranslation;
      end if;
      sys.dbms_backup_restore.restoreCancel(TRUE);
      return false;
    end if;
    pieces_done := pieces_done + 1;
  end if;
    return false;
end;
>>>
 
define restore_piece
<<<
  if (restore_piece_int(pieces_done, piecenum, fhandle, done, params,
         outhandle, outtag, failover, err_msg, val_bs_only, validate,
         devtype, bmr, set_stamp, set_count, start_time, incremental, 
         currcf, ppltrans)) then
     goto restore_failover;
  end if;
 
  if done then
     if (ppltrans > 0) then
        sys.dbms_backup_restore.endPrePluginTranslation;
     end if;
     return;
  end if; 
>>>
 
define restore_end
<<<
--
  krmicd.writeMsg(8001);
 
  if not krmicd.doRestoreFailover(rman_constant.BACKUPPIECE) then
     begin
        sys.dbms_backup_restore.restoreCancel(FALSE);
     exception
        when others then
           krmicd.writeMsg(1005, 
                           'a. dbms_backup_restore.restoreCancel() failed');
     end; 
 
     if (ppltrans > 0) then
        sys.dbms_backup_restore.endPrePluginTranslation;
     end if;
     raise restore_not_complete;
  end if;
 
--
--
--
--
  if (not validate) then
     getFileRestored(FALSE);
  end if;
  
  devtype := krmicd.checkBsFailover;
 
  if (incremental and devtype is null) then
     begin
        sys.dbms_backup_restore.restoreCancel(TRUE);
     exception 
        when others then
           krmicd.writeMsg(1005, 
                           'b. dbms_backup_restore.restoreCancel() failed');
     end;
  end if;
 
  if (dfnumber is not null) then
     krmicd.writeMsg(1005, 'Restore did not complete for some' ||
                     ' files from backup piece ' ||
                     outhandle || ' (piecenum=' || to_char(piecenum) ||
                     ', pieces_done=' || to_char(pieces_done) ||
                     ', done=' || bool2char(done) ||
                     ', failover=' || bool2char(failover) || ')');
  else
     krmicd.writeMsg(1005, 'Restore did not complete for some' ||
                     ' archived logs from backup piece ' || outhandle ||
                     ' (piecenum=' || to_char(piecenum) ||
                     ', pieces_done=' || to_char(pieces_done) ||
                     ', done=' || bool2char(done) ||
                     ', failover=' || bool2char(failover) || ')');
  end if;
 
  krmicd.writeMsg(1005, 'Please check alert log for ' ||
                        'additional information.');
 
  if (devtype is not null) then
     krmicd.writeMsg(8612, krmicd.getChid, devtype);
  end if;
 
--
<<restore_failover>>
  begin
     sys.dbms_backup_restore.restoreCancel(FALSE);
  exception
     when others then
        krmicd.writeMsg(1005, 
                        'c. dbms_backup_restore.restoreCancel() failed');
  end; 
 
  if (ppltrans > 0) then
     sys.dbms_backup_restore.endPrePluginTranslation;
  end if;
 
  sys.dbms_backup_restore.setRmanStatusRowId(rsid=>0, rsts=>0);
end;
>>>
 
define msr_finish
<<<
--
declare
  dfnumber number;
  msrfname varchar2(1024);
  err_msg  varchar2(2048);
begin
  krmicd.getMSR(dfnumber, msrfname);
  sys.dbms_backup_restore.setParms(p0 => 5,
                                   p1 => dfnumber,
                                   p5 => msrfname);
exception
  when sys.dbms_backup_restore.retryable_error_exp then
     err_msg := sqlerrm;
 
     if not krmicd.doRestoreFailover(rman_constant.BACKUPPIECE) then
        raise;
     end if;
 
--
     krmicd.writeErrMsg(8615, krmicd.getChid||': '||err_msg);
     krmicd.clearErrors;
end;
>>>
 
define msr_error_clean
<<<
--
declare
  dfnumber number;
  msrfname varchar2(1024);
begin
  krmicd.getMSRError(dfnumber, msrfname);
 
  if (msrfname is not null) then
     sys.dbms_backup_restore.deleteFile(msrfname);
  end if;
end;
>>>
 
define msc_finish
<<<
--
declare
  mscfname varchar2(1024);
begin
  krmicd.getMSC(mscfname);
  sys.dbms_backup_restore.setParms(p0 => 9,
                                   p5 => mscfname);
end;
>>>
 
define rsal_start
<<<
--
declare
  /* restoreStatus: rsal_start */
  state       binary_integer;
  pieces_done binary_integer;
  files       binary_integer;
  datafiles   boolean;
  incremental boolean;
  device      boolean;
  /* restorebackuppiece */
  done        boolean;
  currcf      boolean;      -- unused here
  cfname      varchar2(512);
  fhandle     varchar2(512);
  handle      varchar2(512);
  outhandle   varchar2(512);
  params      varchar2(512);
  fromdisk    boolean;              -- TRUE => backupset on disk
  /* Miscellaneous */
  memnum      number;
  piecenum    number;
  dfnumber    number := null;
  thread      number;
  sequence    number;
  destination varchar2(512) := null;
  validate    boolean := FALSE;
  val_bs_only   boolean := FALSE;   -- TRUE => only bs validation
--
 
  tag         varchar2(31);
  outtag      varchar2(31);
  bmr         boolean := FALSE;
  set_count   number;
  set_stamp   number;
  failover    boolean := FALSE;
  devtype     varchar2(512);
  rsid        number;
  rsts        number;
  err_msg     varchar2(2048);
  start_time    date;
  recid       number;
  stamp       number;
  savepiecename       boolean := FALSE;
  transontarget       boolean := FALSE;
  preview             boolean := FALSE;
  recall              boolean := FALSE;
  isstby              boolean := FALSE;
  nocfconv            boolean := FALSE;
  preplugin           boolean := FALSE;
  pdbid               number  := 0;
  pplcdbdbid          number  := 0;
  ppltrans            number;
  isfarsync           boolean := FALSE;
  restore_not_complete exception;
  log_included         exception;
  pragma exception_init(log_included, -19636);
begin
  &1&
 
--
  if preview then
     deb('rsal_start', 'preview');
     return;
  end if;
 
  if (preplugin) then
     ppltrans := sys.dbms_backup_restore.beginPrePluginTranslation(
                    pdbid => pdbid, pplcdbdbid => pplcdbdbid);
  end if;
 
  sys.dbms_backup_restore.restoreStatus(state, pieces_done, files, datafiles,
                       incremental, device);
  start_time := currentTime();
  if state = sys.dbms_backup_restore.restore_no_conversation then
    goto start_convo;
  elsif state = sys.dbms_backup_restore.restore_naming_files then
    goto name_files;
  else
    goto restore_piece;
  end if;
 
<<start_convo>>
  &object&
  sys.dbms_backup_restore.setRmanStatusRowId(rsid=>rsid, rsts=>rsts);
  sys.dbms_backup_restore.restoreSetArchivedLog(
      destination      => destination
     ,cleanup          => FALSE
     ,service          => NULL
     ,preplugin        => preplugin);
  incremental := FALSE;
  if validate then
    krmicd.writeMsg(8097, krmicd.getChid);
  elsif destination is null then
    krmicd.writeMsg(8017, krmicd.getChid);
  else
    krmicd.writeMsg(8018, krmicd.getChid);
    krmicd.writeMsg(8508, destination);
  end if;
 
  setRestoreParams;
<<name_files>>
  deb('rsal_start', 'set_stamp=' || set_stamp || ' set_count=' || set_count,
      rman_constant.DEBUG_IO, rman_constant.LEVEL_MIN);
>>>
 
define rsal_name
<<<
--
  &memnum&
  &object&
  if files < memnum then
    begin
      sys.dbms_backup_restore.restoreArchivedLog(thread => thread,
                                                 sequence => sequence);
      krmicd.writeMsg(8022, krmicd.getChid);
      krmicd.writeMsg(8510, to_char(thread), to_char(sequence));
%IF% target
    exception
--
--
--
      when log_included then
        null;
%ENDIF% target
    end;
  end if;
>>>
 
define 'switch'
<<<
--
declare
  copy_recid number;
  copy_stamp number;
  catalog    boolean;
  dfnumber   number;
  fname      varchar2(512);
begin
  &object&
  sys.dbms_backup_restore.switchToCopy(copy_recid => copy_recid
                                      ,copy_stamp => copy_stamp
                                      ,catalog    => catalog
                                      ,newfno     => dfnumber);
  krmicd.writeMsg(8015, to_char(dfnumber));
  krmicd.writeMsg(8507, to_char(copy_recid), to_char(copy_stamp), fname);
end;
>>>
 
 
define tdb_gtsc
<<<
--
/* This is to generate the transport script */
declare
  tscname      varchar2(512);
  pfformat     varchar2(512);
  rmtscname    varchar2(512);
  pfname       varchar2(512);
  newtscname   varchar2(512);
  newrmtscname varchar2(512);
begin
  &tscname&
  &pfformat&
  &rmtscname&
  sys.dbms_backup_restore.genTransportScript(tscname, pfformat, rmtscname,
                                             pfname, newtscname, newrmtscname,
                                             &args&);
  krmicd.writeMsg(8301, pfname);
  if rmtscname is not null then
    krmicd.writeMsg(8302, newrmtscname);
  end if;
  if tscname is not null then 
    krmicd.writeMsg(8300, newtscname);
  end if;
end;
>>>
 
define tdb_lock
<<<
/* This is to lock transportable db context */
declare
  newdbname varchar2(10);
begin
  &newdbname&
  sys.dbms_backup_restore.TransportDBLock(newdbname);
end;
>>>  
 
define tdb_unlock
<<<
/* This is to unlock transportable db context */
begin  
  sys.dbms_backup_restore.TransportDBUnlock;
  krmicd.writeMsg(8303);
  krmicd.writeMsg(8304);
end;
>>>
 
define 'sql'
<<<
--
begin
  krmicd.execSql(&args&);
end;
>>>
define testkrm
<<<
begin
  krmicd.writeMsg(1005, null);
end;
>>>
 
define 'smr1'
<<<
--
declare
   mr_cancelled exception;
   pragma exception_init(mr_cancelled, -283);
 
   mr_need_log  exception;
   pragma exception_init(mr_need_log, -279);
 
   mr_not_needed  exception;
   pragma exception_init(mr_not_needed, -264);
 
   bmr_block_errors exception;
   pragma exception_init(bmr_block_errors, -19680);
 
   thread           number;
   sequence         number;
   scn              number;
   dellog           binary_integer;
   recid            binary_integer;
   stamp            binary_integer;
   seq              binary_integer;
   resetlogs_change number;
   first_change     number;
   blksize          binary_integer;
   logname          varchar2(512);
   stopthd          number;
   stopseq          number;
   toclause         boolean;   -- TRUE = TO CLAUSE; FALSE = TO BEFORE CLAUSE
   bmr              boolean := FALSE;
   rls              number;          -- resetlogs scn for required log
   rlc              number;          -- resetlogs count for required log
   flash            boolean := FALSE;
   pdbpitr          boolean := FALSE;
   stoprcv          boolean;
   start_time       date;
   elapsed          number;
   hours            number;
   mins             number;
   secs             number;
   nonlogblk        boolean     := FALSE;
   con_id           number      := sys_context('userenv', 'con_id');
   app_root         varchar2(3) :=
                                sys_context('userenv', 'is_application_root');
   internal_error   exception;
   preplugin        boolean := FALSE;
   pdbid            number;
   pplpdbid         number;
   pplcdbdbid       number;
   unplugSCN        number;
   file#            number;
   old_file#        number;
   firstcall        binary_integer;
   pragma exception_init(internal_error, -600);
begin
   begin
      &object&
      start_time := currentTime();
      if (nonlogblk) then
         krmicd.writeMsg(8241);                  -- starting NBR recovery
      else
         krmicd.writeMsg(8054);                  -- starting media recovery
      end if;
      if preplugin then
         sys.dbms_backup_restore.prePluginRecoveryStart(
                                pdbid       => pdbid
                               ,pplpdbid    => pplpdbid
                               ,pplcdbdbid  => pplcdbdbid
                               ,unplugSCN   => unplugSCN);
         firstcall := 1;
         loop
            exit when not
               krmicd.recoverFileGetNext
                 (firstcall, preplugin, file#, old_file#);
            firstcall := 0;
            deb('smr1', 'file# = ' || file# || ' ,old_file# = ' || old_file#);
            sys.dbms_backup_restore.prePluginRecoveryAddFile(file#, old_file#);
         end loop;
      elsif (not bmr and not flash) then
          if (con_id <= 1) then
             krmicd.execSQL('alter database recover datafile list clear');
          elsif (app_root = 'YES') then
             krmicd.execSQL('alter database recover datafile root');
          end if;
      end if;
>>>
 
 
define 'smr2'
<<<
--
      if (con_id > 1) then
         raise internal_error;
      end if;
      krmicd.execSql('alter database recover datafile list' ||
                     '&args&');
>>>
 
define 'smr3'
<<<
--
      if bmr then
         sys.dbms_backup_restore.bmrDoMediaRecovery(NULL);
         begin
            sys.dbms_backup_restore.bmrCancel;
         exception
            when bmr_block_errors then
               krmicd.writeMsg(8111);
         end;
      elsif flash then
         begin
            sys.dbms_backup_restore.flashbackFiles(NULL);
            krmicd.checkSetDatabase;
         exception
            when others then
               krmicd.checkSetDatabase;
               raise;
         end;
         sys.dbms_backup_restore.flashbackCancel;
         krmicd.checkSetDatabase;
      elsif pdbpitr then
         sys.dbms_backup_restore.recoverDo(NULL);
         sys.dbms_backup_restore.recoverCancel;
      elsif nonlogblk then
         declare
            blkstat    sys.dbms_backup_restore.blockStatTable_t;
            firstcall  boolean := TRUE;
            lastcall   boolean := FALSE;
            files      binary_integer;
         begin
            sys.dbms_backup_restore.NbrFileStatus(files);
            if (files = 0) then
                sys.dbms_backup_restore.nbrCancel;
                krmicd.writeMsg(8057, krmicd.getChid);
            else
                sys.dbms_backup_restore.nbrDoMediaRecovery(NULL);
                sys.dbms_backup_restore.getNbrBlockStat(blkstat);
                listNbrBlockStat(blkstat);
            end if;
         end;
      elsif preplugin then
         sys.dbms_backup_restore.prePluginDoMediaRecovery(NULL);
         sys.dbms_backup_restore.prePluginRecoveryCancel;
      else
         krmicd.execSql('alter database recover' || '&args&');
      end if;
      elapsed := currentTime() - start_time;
      dur2time(elapsed, hours, mins, secs);
--
      if (nonlogblk) then 
         krmicd.writeMsg(8242, to_char(hours, 'FM09') || ':' ||
                               to_char(mins,  'FM09') || ':' ||
                               to_char(secs,  'FM09'));
--
      else
         krmicd.writeMsg(8181, to_char(hours, 'FM09') || ':' ||
                               to_char(mins,  'FM09') || ':' ||
                               to_char(secs,  'FM09')); 
      end if;
      return;
   exception
      when mr_cancelled then
        krmicd.writeMsg(8059);
        raise;
      when mr_need_log then
        krmicd.clearErrors;
      when mr_not_needed then
        krmicd.clearErrors;
        elapsed := currentTime() - start_time;
        dur2time(elapsed, hours, mins, secs);
--
        if (nonlogblk) then 
           krmicd.writeMsg(8242, to_char(hours, 'FM09') || ':' ||
                                 to_char(mins,  'FM09') || ':' ||
                                 to_char(secs,  'FM09'));
--
        else
           krmicd.writeMsg(8181, to_char(hours, 'FM09') || ':' ||
                                 to_char(mins,  'FM09') || ':' ||
                                 to_char(secs,  'FM09')); 
        end if;
        return;
      when others then
        krmicd.writeMsg(8059);
        raise;
   end;
 
   toclause := krmicd.checkUntil(stopthd, stopseq);
 
   select resetlogs_change# into resetlogs_change from v$database_incarnation 
     where status='CURRENT';
 
   select thr, seq, scn, rls, rlc 
      into thread, sequence, scn, rls, rlc from x$kcrmx;
  
   if (resetlogs_change = rls and 
       stopthd = thread       and
       ((sequence >= stopseq and toclause = FALSE) OR
        (sequence > stopseq and toclause = TRUE))) then
      if bmr then
         begin
            sys.dbms_backup_restore.bmrCancel;
         exception
            when bmr_block_errors then
               krmicd.writeMsg(8111);
         end;
      elsif flash then
         sys.dbms_backup_restore.flashbackCancel;
         krmicd.checkSetDatabase;
      elsif pdbpitr then
         sys.dbms_backup_restore.recoverCancel;
      elsif nonlogblk then
         sys.dbms_backup_restore.nbrCancel;
      elsif preplugin then
         sys.dbms_backup_restore.prePluginRecoveryCancel;
      else
         krmicd.execSql('alter database recover cancel');
      end if;
 
      elapsed := currentTime() - start_time;
      dur2time(elapsed, hours, mins, secs);
--
      if (nonlogblk) then 
         krmicd.writeMsg(8242, to_char(hours, 'FM09') || ':' ||
                               to_char(mins,  'FM09') || ':' ||
                               to_char(secs,  'FM09'));
--
      else
         krmicd.writeMsg(8181, to_char(hours, 'FM09') || ':' ||
                               to_char(mins,  'FM09') || ':' ||
                               to_char(secs,  'FM09')); 
      end if;
      return;
   end if;
end;
>>>
 
define 'log_apply1'
<<<
--
declare
 
  mr_cancelled exception;
  pragma exception_init(mr_cancelled, -283);
 
--
  mr_cont_rcv  exception;
  pragma exception_init(mr_cont_rcv, -288);
 
  mr_need_log  exception;
  pragma exception_init(mr_need_log, -279);
 
  mr_aborted   exception;
  pragma exception_init(mr_aborted, -20500);
 
  bmr_block_errors exception;
  pragma exception_init(bmr_block_errors, -19680);
 
  mr_createdf  exception;
  pragma exception_init(mr_createdf, -20505);
 
  archivelog_missing_exception      exception;
  pragma exception_init(archivelog_missing_exception, -20515);
 
  archivelog_backup_not_found      exception;
  pragma exception_init(archivelog_backup_not_found, -20506);
 
  cant_open_log exception;
  pragma exception_init(cant_open_log, -308);
 
  alfrec           v$archived_log%ROWTYPE;
  dellog           boolean := FALSE; -- set by rman compiler
  deltarget        boolean := FALSE; -- set by rman compiler
  bmr              boolean := FALSE; -- set by rman compiler
  flash            boolean := FALSE; -- set by rman compiler
  pdbpitr          boolean := FALSE; -- set by rman compiler
  untilcancel      boolean := FALSE; -- set by rman compiler
  preplugin        boolean := FALSE; -- set by rman compiler
 
  scn              number;
  stopthd          number;
  stopseq          number;
  stoprcv          boolean;
  rlc              number;      -- resetlogs count
  resetlogs_change number;      -- resetlogs SCN used when untilLog is set
  start_time    date;
  elapsed       number;
  hours         number;
  mins          number;
  secs          number;
  pstandby      number;
 
--
  unnamed          varchar2(1024);
  dfname           varchar2(1024);
  newdfname        varchar2(1024);
  fileno           number := 0;
  recovdf          boolean := false;
  filelist         varchar2(512):=NULL;
  tmp              number:=0;
  toclause         boolean;
  tsnum            number;
  tsname           varchar2(32);
  pdbname          varchar2(128);
  bnewomf          boolean;
  dropf            boolean;
  createdf         boolean := false;
  type numTab_t is table of number index by binary_integer;
  df_offln_list    numTab_t;
  con_id           number  := sys_context('userenv', 'con_id');
  internal_error   exception;
  pragma exception_init(internal_error, -600);
 
  function continue_rcv(createdf OUT boolean) return boolean is
  begin
    createdf := false;
  <<do_cont_again>>
      begin
        krmicd.clearErrors;
        krmicd.execSql('alter database recover continue');
      exception
        when mr_cont_rcv then
           goto do_cont_again;
        when mr_need_log then
           return true;
        when mr_createdf then
           createdf := true;
           return true;
      end;
    return false;
  end;
 
begin
 
  &object&
 
  toclause := krmicd.checkUntil(stopthd, stopseq);
 
  select count(*) into pstandby from V$DATABASE
         where database_role='PHYSICAL STANDBY';
 
  <<restart_recovery>> -- recovery is never restarted for bmr
 
   begin 
     start_time := currentTime();
--
--
--
--
--
     if not bmr and not flash and not pdbpitr and recovdf then
        deb('apply_log', 're-start recovery');
 
        krmicd.execSQL('alter database recover datafile list clear');
        if filelist is not null then
           krmicd.execSql('alter database recover datafile list ' || filelist);
        end if;
>>>
 
define 'log_apply3'
<<<
        krmicd.execSql('alter database recover' || '&args&');
        fileno := 0;
        recovdf := false;
      end if;
    exception 
        when mr_need_log then
           krmicd.clearErrors;
    end;
 
--
<<get_log>>
 
  if createdf then
     createdf := false;
     raise mr_createdf;
  end if;
 
  begin
    select thr, seq, scn, rls, rlc into
           alfrec.thread#, alfrec.sequence#, scn, alfrec.resetlogs_change#,
           rlc from x$kcrmx;
 
  exception
    when no_data_found then
       if bmr then
          begin
             sys.dbms_backup_restore.bmrCancel;
          exception
             when bmr_block_errors then
                krmicd.writeMsg(8111);
          end;
       elsif flash then
          sys.dbms_backup_restore.flashbackCancel;
          krmicd.checkSetDatabase;
       elsif pdbpitr then
          sys.dbms_backup_restore.recoverCancel;
       elsif preplugin then
          sys.dbms_backup_restore.prePluginRecoveryCancel;
       end if;
--
--
--
--
--
--
--
--
 
--
       delete_logs(FALSE, dellog, deltarget, preplugin);
 
       return;
  end;
 
  select resetlogs_change# into resetlogs_change from v$database_incarnation
      where status='CURRENT';
 
  if (resetlogs_change=alfrec.resetlogs_change# and
      stopthd = alfrec.thread# and
      alfrec.sequence# >= stopseq)
  then
    stoprcv := FALSE;
    if bmr then
       begin
          sys.dbms_backup_restore.bmrCancel;
       exception
          when bmr_block_errors then
             krmicd.writeMsg(8111);
       end;
       stoprcv := TRUE;
    elsif flash then
--
--
       if alfrec.sequence# > stopseq then
          sys.dbms_backup_restore.flashbackCancel;
          krmicd.checkSetDatabase;
          stoprcv := TRUE;
       end if;
    elsif pdbpitr then
       sys.dbms_backup_restore.recoverCancel;
       stoprcv := TRUE;
    elsif preplugin then
       sys.dbms_backup_restore.prePluginRecoveryCancel;
       stoprcv := TRUE;
    else
       krmicd.execSql('alter database recover cancel');
       stoprcv := TRUE;
    end if;
 
    if stoprcv then
--
--
--
--
--
 
--
       delete_logs(FALSE, dellog, deltarget, preplugin);
       elapsed := currentTime() - start_time;
       dur2time(elapsed, hours, mins, secs);
--
       krmicd.writeMsg(8181, to_char(hours, 'FM09') || ':' ||
                             to_char(mins,  'FM09') || ':' ||
                             to_char(secs,  'FM09'));       
       return;
    end if;
  end if;
 
  begin
    deb('log_apply', 'looking for log with scn ' ||scn||' thread='||
         alfrec.thread#||' sequence='||alfrec.sequence# ||' resetlogs scn '||
         alfrec.resetlogs_change#||' resetlogs time='||
         to_char(stamp2date(rlc)));
 
    begin
--
       alfrec.name := krmicd.checkLog(scn,
                                   alfrec.thread#,
                                   alfrec.sequence#,
                                   alfrec.recid,
                                   alfrec.stamp,
                                   alfrec.resetlogs_change#,
                                   stamp2date(rlc),
                                   alfrec.first_change#,
                                   alfrec.next_change#,
                                   alfrec.block_size,
                                   preplugin);
 
    exception
       when archivelog_backup_not_found or archivelog_missing_exception then
          if (untilcancel) then
--
--
--
             alfrec.name := NULL;
             krmicd.writeMsg(8194, to_char(alfrec.thread#),
                              to_char(alfrec.sequence#));
          else
--
--
--
             raise;
          end if;
    end;
  exception
    when archivelog_backup_not_found then
      raise;
    when others then
       if (is_db_in_noarchivelog) then
          krmicd.writeMsg(8187, to_char(scn));
       else
          if pstandby = 1 then
             krmicd.clearErrors;
--
             delete_logs(FALSE, dellog, deltarget, preplugin);
             elapsed := currentTime() - start_time;
             dur2time(elapsed, hours, mins, secs);
--
             krmicd.writeMsg(8181, to_char(hours, 'FM09') || ':' ||
                                   to_char(mins,  'FM09') || ':' ||
                                   to_char(secs,  'FM09'));
             return;
          else
             krmicd.writeMsg(8060);          -- unable to find log
             krmicd.writeMsg(8510, to_char(alfrec.thread#),
                                   to_char(alfrec.sequence#));
             raise;
          end if;
       end if;
  end;
 
  deb('log_apply', 'log file name returned is ' || alfrec.name );
 
  begin
 
    if alfrec.name is not NULL then
      if bmr then
         sys.dbms_backup_restore.bmrDoMediaRecovery(alfrec.name);
      elsif flash then
         sys.dbms_backup_restore.flashbackFiles(alfrec.name);
      elsif pdbpitr then
         sys.dbms_backup_restore.recoverDo(alfrec.name);
      elsif preplugin then
         sys.dbms_backup_restore.prePluginDoMediaRecovery(alfrec.name);
      else
         krmicd.writeMsg(8515, alfrec.name,
                         to_char(alfrec.thread#),
                         to_char(alfrec.sequence#));
--
         krmicd.execSql( 'alter database recover logfile ''' ||
                          replace(alfrec.name,'''','''''') || '''');
      end if;
 
--
--
--
--
--
 
--
      delete_logs(FALSE, dellog, deltarget, preplugin);
 
      if bmr then
         begin
            sys.dbms_backup_restore.bmrCancel;
         exception
            when bmr_block_errors then
               krmicd.writeMsg(8111);
         end;
      elsif flash then
         sys.dbms_backup_restore.flashbackCancel;
         krmicd.checkSetDatabase;
      elsif pdbpitr then
         sys.dbms_backup_restore.recoverCancel;
      elsif preplugin then
         sys.dbms_backup_restore.prePluginRecoveryCancel;
      end if;
      elapsed := currentTime() - start_time;
      dur2time(elapsed, hours, mins, secs);
--
      krmicd.writeMsg(8181, to_char(hours, 'FM09') || ':' ||
                            to_char(mins,  'FM09') || ':' ||
                            to_char(secs,  'FM09'));      
      return;
    else
      return;
    end if;
  exception
    when mr_cont_rcv then
      if continue_rcv(createdf) then
         goto get_log;
      end if;
    when mr_need_log or cant_open_log then
--
--
      krmicd.clearErrors;
 
--
--
--
--
--
      delete_logs(TRUE, dellog, deltarget, preplugin);
 
      goto get_log;
    when mr_createdf then
       if (bmr or flash or pdbpitr) then
         raise;
       end if;
 
--
       for df_rec in (select fnfno, fnnam, fnonm, ts.ts#, ts.name,
                      fepfdi, fepdi,
                      (case when pdb.con_id > 1 then
                       pdb.name else null end) pdbname
       from x$kccfn fn, x$kccfe fe, v$tablespace ts, v$containers pdb
       where fn.fnunn = 1
         and fn.fnfno=fe.fenum
         and fe.fefnh=fnnum
         and fe.fetsn=ts.ts#
         and fe.con_id = ts.con_id
         and fe.con_id = pdb.con_id) loop
 
--
--
         if (df_rec.fepdi > 0 or df_rec.fepfdi > 0) then
           raise;
         end if;
 
         fileno := df_rec.fnfno;
         unnamed := df_rec.fnnam;
         dfname := df_rec.fnonm;
         tsnum  := df_rec.ts#;
         tsname := df_rec.name;
         pdbname := df_rec.pdbname;
 
         deb('apply_log', 'tsnum ' || tsnum);
         deb('apply_log', 'tsname ' || tsname);
         deb('apply_log', 'fileno ' || fileno);
         deb('apply_log', 'dfname ' || dfname);
         deb('apply_log', 'pdbname' || nvl(pdbname, 'NULL'));
 
         deb('apply_log', 'file old name is ' || dfname);
 
         recovdf := true;
         if krmicd.getDfInfo(fileno, tsnum, tsname, pdbname,
                             newdfname, bnewomf, dropf)
         then
            if (newdfname is not null) then
               dfname := newdfname;
               deb('apply_log', 'file new name is ' || newdfname);
            else
               deb('apply_log', 'using name at creation ' || dfname);
            end if;
 
            krmicd.writeMsg(6064, fileno, dfname);
            sys.dbms_backup_restore.createDatafile(fno => fileno,
                                                   newomf => bnewomf,
                                                   recovery => TRUE,
                                                   fname => dfname);
 
--
            if filelist is not null then
               filelist := filelist || ', ' || fileno;
            else
               filelist := fileno;
            end if;
 
         else
           dfname := null;
           deb('apply_log', 'no filename - ignore creation of file# '
                            || fileno);
           deb('apply_log', 'This is recover database skip tablespace cmd');
 
           if (df_offln_list.exists(fileno)) then
             deb('apply_log', 'file is already offlined ' || fileno);
 
           else
 
             df_offln_list(fileno) := 1;
 
             if (dropf = true) then
               krmicd.writeMsg(6958, 'alter database datafile ' || fileno ||
                                     ' offline drop');
               krmicd.execSql('alter database datafile ' || fileno ||
                              ' offline drop', 0, pdbname);
             else
               krmicd.writeMsg(6958, 'alter database datafile ' || fileno ||
                                     ' offline');
               krmicd.execSql('alter database datafile ' || fileno ||
                              ' offline', 0, pdbname);
             end if;
           end if;
         end if;
       end loop;
--
--
       krmicd.clearErrors;
       goto restart_recovery;
  end;
end;
>>>
 
define 'scr_cre_rep'
<<<
--
declare
  creat  boolean;
  line   varchar2(1024);
  name   varchar2(100);
  scr_com varchar2(255);
  global boolean;
begin
  &args&
 
  if creat then
    dbms_rcvcat.createScript(name, scr_com, global);
  else
    dbms_rcvcat.replaceScript(name, scr_com, global);
  end if;
 
  loop
    line := krmicd.getLine;
    if line is null then
      exit;
    end if;
    dbms_rcvcat.putLine(line);
  end loop;
 
  dbms_rcvcat.commitChanges;
  if creat then
    if global then
       krmicd.writeMsg(8150, name);
    else
       krmicd.writeMsg(8085, name);
    end if;
  else
    if global then
       krmicd.writeMsg(8151, name);
    else
       krmicd.writeMsg(8086, name);
    end if;
  end if;
end;
>>>
 
define replicate_controlfile
<<<
declare
  cfname      varchar2(512);
begin
  &object&
  replicate_controlfile(cfname => cfname);
end;
>>>
 
define 'x$replicate_controlfile'
<<<
procedure replicate_controlfile(cfname IN varchar2) IS
  src_name   varchar2(512);
  dest_name  varchar2(512);
  full_name  varchar2(512);
  recid      number;
  stamp      number;
  firstcall  boolean := TRUE;
begin
  src_name := sys.dbms_backup_restore.normalizefilename(cfname);
  for i in 1..9999 loop
    dest_name := sys.dbms_backup_restore.getparm(
              sys.dbms_backup_restore.control_file, i);
    if dest_name is null then exit; end if;
    if src_name <> dest_name then
      if firstcall then
         krmicd.writeMsg(8058);
         krmicd.writeMsg(8506, src_name);
         firstcall := FALSE;
      end if;
      krmicd.writeMsg(8505, dest_name);
      sys.dbms_backup_restore.copyControlFile(src_name  => src_name,
                                              dest_name => dest_name,
                                              recid     => recid,
                                              stamp     => stamp,
                                              full_name => full_name);
    end if;
  end loop;
end;
>>>
 
define "rpctest"
<<<
--
begin
   sys.dbms_backup_restore.sleep(60);            -- 1 minute
end;
>>>
 
define tspitr_rescf
<<<
# restore the controlfile
restore clone controlfile;
 
# mount the controlfile
sql clone 'alter database mount clone database';
 
# archive current online log 
sql 'alter system archive log current';
>>>
 
define tspitr_noauto
<<<
# avoid unnecessary autobackups for structural changes during TSPITR
sql 'begin dbms_backup_restore.AutoBackupFlag(FALSE); end;';
>>>
 
define tspitr_resync
<<<
# resync catalog
resync catalog;
>>>
 
define tspitr_until
<<<
{
# set requested point in time
set until &1&;
>>>
 
define tspitr_offrecset
<<<
plsql
&begin&
--
declare
  sqlstatement       varchar2(512);
  pdbname            varchar2(128);
  offline_not_needed exception;
  pragma exception_init(offline_not_needed, -01539);
begin
  &object& -- pdbname
  sqlstatement := 'alter tablespace '|| &1& ||' offline immediate';
  krmicd.writeMsg(6162, sqlstatement);
  krmicd.execSql(sqlstatement, 0, pdbname);
exception
  when offline_not_needed then
    null;
end;
&end&
;
>>>
 
define tspitr_flipcom
<<<
# switch to valid datafilecopies
>>>
 
define tspitr_flip
<<<
switch clone datafile &1& to datafilecopy &2&;
>>>
 
define tspitr_newcom
<<<
# set destinations for recovery set and auxiliary set datafiles
>>>
define tspitr_newdf
<<<
set newname for datafile &1& to &2&;
>>>
 
define tspitr_newomfaux
<<<
set newname for clone datafile &1& to new;
>>>
 
define tspitr_newomfrec
<<<
set newname for datafile &1& to new;
>>>
 
define tspitr_newtemp
<<<
set newname for tempfile &1& to &2&;
>>>
 
define tspitr_newomftemp
<<<
set newname for clone tempfile &1& to new;
>>>
 
define tspitr_switchtemp
<<<
# switch all tempfiles
switch clone tempfile all;
>>>
 
define tspitr_restore
<<<
# restore the tablespaces in the recovery set and the auxiliary set
restore clone datafile &1&;
 
>>>
 
 
define tspitr_restore_sparse
<<<
# sparse restore the tablespaces in the recovery set and the auxiliary set
restore clone from &1& datafile &2& ;
 
>>>
 
define tspitr_restore_close
<<<
switch clone datafile all;
}
>>>
 
define tspitr_onlinecom
<<<
# online the datafiles restored or switched
>>>
 
define tspitr_onlinedf
<<<
sql clone&1& "alter database datafile &2& online";
>>>
 
define tspitr_recover_reset
<<<
# recover and open resetlogs
recover clone database tablespace &1& delete archivelog;
alter clone database open resetlogs;
}
>>>
 
define tspitr_open_pdb
<<<
{
sql clone 'alter pluggable database &1& open';
}
>>>
 
define tspitr_recover_ro
<<<
# recover and open database read only
recover clone database tablespace &1&;
sql clone 'alter database open read only';
}
>>>
 
define tspitr_open_pdb_ro
<<<
{
sql clone 'alter pluggable database &1& open read only';
}
>>>
 
define tspitr_onlinetscom
<<<
# online the tablespaces that will be exported
>>>
 
define tspitr_onts
<<<
sql clone&1& 'alter tablespace &2& online';
>>>
 
define tspitr_readonlycom
<<<
# make read only the tablespace that will be exported
>>>
 
define tspitr_rots
<<<
sql clone&1& 'alter tablespace &2& read only';
>>>
 
define tspitr_mkclonedir
<<<
# create directory for datapump export
sql clone&1& "create or replace directory &2& as ''&3&''";
>>>
 
define tspitr_mktargetdir
<<<
# create directory for datapump import
sql&1& "create or replace directory &2& as ''&3&''";
>>>
 
define tspitr_uncatcom
<<<
# uncatalog used datafilecopies
>>>
 
define tspitr_uncatcopy
<<<
change datafilecopy &1& uncatalog;
>>>
 
define tspitr_dropcom
<<<
# drop target tablespaces before importing them back
>>>
 
define tspitr_dropkeepts
<<<
sql&1& 'drop tablespace &2& including contents keep datafiles cascade constraints';
>>>
 
define tspitr_dropts
<<<
sql&1& 'drop tablespace &2& including contents cascade constraints';
>>>
 
define tspitr_shutclone
<<<
# shutdown clone before import
shutdown clone abort
>>>
 
define tspitr_readwritecom
<<<
# make read write and offline the imported tablespaces
>>>
 
define tspitr_rwts
<<<
sql&1& 'alter tablespace &2& read write';
sql&3& 'alter tablespace &4& offline';
>>>
 
 
define tspitr_yesauto
<<<
# enable autobackups after TSPITR is finished
sql 'begin dbms_backup_restore.AutoBackupFlag(TRUE); end;';
>>>
 
define tspitr_mount_cl
<<<
# mount database
sql clone 'alter database mount clone database';
>>>
 
define impscrpt_0
<<<
/*
   The following command may be used to import the tablespaces.
   Substitute values for <logon> and <directory>.
 
   impdp <logon> directory=<directory> dumpfile=&1& transport_datafiles=&2& 
*/
 
--
--
--
--
>>>
 
define impscrpt_1
<<<
CREATE DIRECTORY &1& AS &2&;
>>>
 
define impscrpt_2
<<<
/* PL/SQL Script to import the exported tablespaces */
DECLARE
--
  tbs_files     dbms_streams_tablespace_adm.file_set;
  cvt_files     dbms_streams_tablespace_adm.file_set;
 
--
  dump_file     dbms_streams_tablespace_adm.file;
  dp_job_name   VARCHAR2(30) := NULL;
 
--
  ts_names       dbms_streams_tablespace_adm.tablespace_set;
BEGIN
--
  dump_file.file_name := &1&;
  dump_file.directory_object := '&2&';
 
--
>>>
 
define impscrpt_3
<<<
  tbs_files(&1&).file_name := &2&;
  tbs_files(&3&).directory_object := &4&;
 
>>>
 
define impscrpt_4
<<<
--
  dbms_streams_tablespace_adm.attach_tablespaces(
    datapump_job_name      => dp_job_name,
    dump_file              => dump_file,
    tablespace_files       => tbs_files,
    converted_files        => cvt_files,
    tablespace_names       => ts_names);
 
--
  IF ts_names IS NOT NULL AND ts_names.first IS NOT NULL THEN
    FOR i IN ts_names.first .. ts_names.last LOOP
      dbms_output.put_line('imported tablespace '|| ts_names(i));
    END LOOP;
  END IF;
END;
/
 
--
>>>
 
define impscrpt_5
<<<
DROP DIRECTORY &1&;
>>>
 
 
define impscrpt_6
<<<
--------------------------------------------------------------
-- End of sample PL/SQL script
--------------------------------------------------------------
>>>
 
define pdbpitr_rescf
<<<
# restore the controlfile
restore clone controlfile;
 
# mount the controlfile
sql clone 'alter database mount clone database';
>>>
 
define pdbpitr_recover1
<<<
# recover pdb
recover clone database tablespace &1& pluggable database &2&
   delete archivelog;
sql clone 'alter database open read only';
>>>
 
define pdbpitr_recover2
<<<
# recover pdb
recover clone database tablespace &1& datafile &3&
   pluggable database &2& delete archivelog;
sql clone 'alter database open read only';
>>>
 
define pdbpitr_recover3
<<<
#recover pdb
recover clone database tablespace &1& pluggable database &2&
  delete archivelog;
#open in read write mode
sql clone 'alter database open resetlogs';
#unplug dropped pdb into temp file
sql clone "alter pluggable database &5& unplug into ''&3&''";
#create pdb using temp file of recovered pdb
sql "create pluggable database &6& using ''&4&'' nocopy tempfile reuse";
alter pluggable database &7& open;
}
>>>
 
 
define 'x$save_pdb_clean_scn'
<<<
procedure save_pdb_clean_scn is
  clnscnwrp   number;
  clnscnbas   number;
begin
   krmicd.pdbCleanScn(clnscnwrp => clnscnwrp,
                      clnscnbas => clnscnbas);
   deb('save_pdb_clean_scn', 'clnscnwrp=' || clnscnwrp ||
       ' clnscnbas=' || clnscnbas);
end;
>>>
 
define save_pdb_clean_scn
<<<
plsql
&begin&
begin
   save_pdb_clean_scn;
end;
&end&
;
>>>
 
define 'x$add_dropped_ts'
<<<
procedure add_dropped_ts is
   firstcall  binary_integer := 1;
   fname      varchar2(512);
   full_name  varchar2(512);
   recid      number;
   stamp      number;
   cant_inspect_curr_file exception;
   pragma exception_init(cant_inspect_curr_file, -19657);
begin
   loop
      exit when not krmicd.droppedFileGetNext(
                       firstcall => firstcall,
                       fname     => fname);
      firstcall := 0;
      deb('add_dropped_ts', 'fname=' || fname);
 
      begin
         sys.dbms_backup_restore.inspectDataFileCopy(
                           fname      => fname,
                           full_name  => full_name,
                           recid      => recid,
                           stamp      => stamp,
                           change_rdi => FALSE);
         sys.dbms_backup_restore.switchToCopy(
                           copy_recid => recid,
                           copy_stamp => stamp,
                           catalog    => TRUE);
      exception
         when cant_inspect_curr_file then
            deb('add_dropped_ts ', 'already exists');
            krmicd.clearErrors;
      end;
   end loop;
end;
>>>
 
define add_dropped_ts
<<<
plsql
&begin&
begin
   add_dropped_ts;
end;
&end&
;
>>>
 
 
define 'x$pdbpitr_inspect'
<<< 
procedure pdbpitr_inspect(pdbname in varchar2) is
  firstcall   binary_integer := 1;
  auxdfcList  sys.dbms_backup_restore.register_auxdfc_list;
  auxdfc      sys.dbms_backup_restore.register_auxdfc;
  i           binary_integer := 0;
  clnscnwrp   number;
  clnscnbas   number;
begin
   krmicd.pdbCleanScn(clnscnwrp => clnscnwrp,
                      clnscnbas => clnscnbas);
   deb('pdbpitr_inspect', 'clnscnwrp=' || clnscnwrp ||
       ' clnscnbas=' || clnscnbas);
   loop
      exit when not krmicd.auxFileGetNext(
                       firstcall => firstcall,
                       fname     => auxdfc.fname,
                       dfnumber  => auxdfc.dfnumber,
                       tsnum     => auxdfc.tsnum,
                       blksize   => auxdfc.blksize);
      deb('pdbpitr_inspect', 'fname=' || auxdfc.fname ||
           ' dfnumber=' || auxdfc.dfnumber || ' tsnum=' || auxdfc.tsnum ||
           ' blksize='  || auxdfc.blksize);
      auxdfcList(i) := auxdfc;
      i := i+ 1;
      firstcall := 0;
   end loop;
   sys.dbms_backup_restore.registerAuxDfCopy(
                          pdbname    => pdbname,
                          auxdfcList => auxdfcList,
                          clnscnwrp  => clnscnwrp,
                          clnscnbas  => clnscnbas);
end;
>>>
 
define pdbpitr_inspect
<<<
plsql
&begin&
begin
   pdbpitr_inspect(pdbname => &1&);
end;
&end&
;
}
>>>
 
define validateset
<<<
--
  sys.dbms_backup_restore.restorevalidate;
>>>
 
 
define scandfc
<<<
--
declare
  recid            number;
  stamp            number;
  fname            varchar2(512);
  dfnumber         number;
  old_dfnumber     number;
  rfno             number;
  blksize          number;
  blocks           number;
  scn              number;
  check_logical    boolean := false;
  found            boolean;
  preplugin        boolean := false;
  pdbid            number;
  pplcdbdbid       number;
begin
  &object&
  found := krmicd.valGetFound(recid, stamp);
  if dfnumber = 0 then
    krmicd.writeMsg(8518, krmicd.getChid, fname);
  else
    krmicd.writeMsg(8519, krmicd.getChid, fname);
  end if;
 
  if (not preplugin) then
     scn := sys.dbms_backup_restore.scandatafilecopy(
                              recid            => recid,
                              stamp            => stamp,
                              update_fuzziness => false,
                              check_logical    => check_logical);
  else
     scn := sys.dbms_backup_restore.scandatafilecopy(
                              update_fuzziness => false,
                              check_logical    => check_logical,
                              fname            => fname, 
                              fno              => dfnumber,
                              oldfno           => old_dfnumber,
                              rfno             => rfno,
                              blksize          => blksize,
                              blocks           => blocks,
                              preplugin        => true);
  end if;
 
  if dfnumber = 0 then
     krmicd.fileRestored(ftype => rman_constant.CONTROLFILE,
                         fno        => 0,
                         thread     => 0,
                         sequence   => 0,
                         resetscn   => 0,
                         resetstamp => 0);
  else
     krmicd.fileRestored(ftype => rman_constant.DATAFILE,
                         fno        => dfnumber,
                         thread     => 0,
                         sequence   => 0,
                         resetscn   => 0,
                         resetstamp => 0,
                         fname      => fname);
  end if;
 
exception
  when sys.dbms_backup_restore.retryable_error_exp then
     if not krmicd.doRestoreFailover(rman_constant.DATAFILE) then
        raise;
     end if;
--
     krmicd.writeErrMsg(1005, sqlerrm);
     krmicd.clearErrors;
  when others then
     raise;
end;
>>>
 
define bscandfc
<<<
--
declare
  recid    number;
  stamp    number;
  found    boolean;
  fname    varchar2(512);
begin
  &object&
  found := krmicd.valGetFound(recid, stamp);
  krmicd.writeMsg(8532, krmicd.getChid, fname);
  sys.dbms_backup_restore.bmrscandatafilecopy(recid, stamp);
 
exception
  when sys.dbms_backup_restore.retryable_error_exp then
     if not krmicd.doRestoreFailover(rman_constant.DATAFILE) then
        raise;
     end if;
--
     krmicd.writeErrMsg(1005, sqlerrm);
     krmicd.clearErrors;
  when others then
     raise;
end;
>>>
 
define scanal
<<<
--
declare
  record_not_found exception;
  pragma exception_init(record_not_found, -19571);
  recid      number;
  stamp      number;
  fname      varchar2(512);
  full_name  varchar2(512);
  rsid       number;
  rsts       number;
  isstby     boolean := FALSE;
  nocfconv   boolean := FALSE;
  isfarsync  boolean := FALSE;
begin
  &object&
  krmicd.writeMsg(8520, krmicd.getChid, fname);
  sys.dbms_backup_restore.setRmanStatusRowId(rsid=>rsid, rsts=>rsts);
 
<<scan_log>>  -- retry on non-cataloged archived log
  begin
     sys.dbms_backup_restore.scanarchivedlog(recid => recid, stamp => stamp);
  exception
     when record_not_found then
        sys.dbms_backup_restore.inspectArchivedLog(fname => fname,
           full_name => full_name, recid => recid, stamp => stamp);
        deb('scanal', 'cataloged archive log recid=' || recid ||
            ' stamp=' || stamp);
        krmicd.clearErrors;
        goto scan_log;
  end;
  sys.dbms_backup_restore.setRmanStatusRowId(rsid=>0, rsts=>0);
end;
>>>
 
define setcmdid
<<<
--
declare
  cmdid  varchar2(512);
begin
  &object&
  if krmicd.getDevType is null then
    return;
  end if;
  sys.dbms_backup_restore.set_client_info(
    'id='||cmdid||',rman channel='||krmicd.getchid);
end;
>>>
 
define aor
<<<
--
declare
  cfname      varchar2(512) := null;
  recid       number;
  stamp       number;
  copy_recid  number := 0;
  copy_stamp  number := 0;
  fname       varchar2(512) := null;
  dfnumber    binary_integer := null;
  blksize     number := null;
begin
  &1&                   -- set variables
 
  sys.dbms_backup_restore.applyOfflineRange(cfname  => cfname,
                                            dfname  => fname,
                                            blksize => blksize,
                                            recid   => recid,
                                            stamp   => stamp,
                                            fno     => dfnumber,
                                            dfrecid => copy_recid,
                                            dfstamp => copy_stamp);
 
  if (fname is not null) then
    krmicd.writeMsg(8088, fname);
  else
    krmicd.writeMsg(8088, to_char(dfnumber, 'FM09999'));
  end if;
  krmicd.writeMsg(8521, to_char(recid), to_char(stamp));
end;
>>>
 
define net_rsdf_start
<<<
--
declare
  done             boolean;
  tsname           varchar2(512);
  toname           varchar2(512);
  orgname          varchar2(512);
  service          varchar2(256);
  piecenum         number;
  dfnumber         number;
  max_corrupt      binary_integer := 0;
  check_logical    boolean := FALSE;
  err_msg          varchar2(2048);
  start_time       date;
  elapsed          number;
  hours            number;
  mins             number;
  secs             number;
  outhandle        varchar2(512);
  failover         boolean := FALSE;
  outtag           varchar2(31);
  rcvcopy          boolean := FALSE;
  rsid             number;
  rsts             number;
  preview          boolean := FALSE;
  validate         boolean := FALSE;
  isstby           boolean;
  nocfconv         boolean;
  cfname           varchar2(512);
  currcf           boolean;
  pfname           varchar2(512);
  sfname           varchar2(512);
  msrpno           number := 0;
  msrpct           number := 0;
  first_time       boolean := TRUE;
  msb_section_size number;
  docompress       boolean;
  isfarsync        boolean := FALSE;
  networkfdf       boolean := FALSE;     
  sameend          boolean := TRUE;
  transname        boolean := FALSE;
  xfno             number := 0;
  fileckpt_scn     number := 0;
  restore_not_complete exception;
  sparse_restore   number := 0;
  encdec_restore   number := 0;
begin
  &1& -- set conversation variables
 
--
  if preview then
     deb('net_rsdf_start', 'preview');
     return;
  end if;
 
  start_time := currentTime();
  sys.dbms_backup_restore.setRmanStatusRowId(rsid=>rsid, rsts=>rsts);
 
--
  if networkfdf then
     sys.dbms_backup_restore.restoreSetForeignDF(
                               check_logical => check_logical
                              ,cleanup       => FALSE
                              ,service       => service
                              ,dfincr        => FALSE
                              ,sameend       => sameend);
  else
     sys.dbms_backup_restore.restoreSetDataFile(
                               check_logical  => check_logical
                              ,cleanup        => FALSE
                              ,service        => service
                              ,sparse_restore => sparse_restore
                              ,encdec_restore => encdec_restore);
  end if;
  docompress := setNetworkRestoreParams;
 
  if validate then
     krmicd.writeMsg(8096, krmicd.getChid);
  else
     krmicd.writeMsg(8016, krmicd.getChid);
  end if;
 
  if docompress then
     krmicd.writeMsg(8168, krmicd.getChid, service);
  else
     krmicd.writeMsg(8169, krmicd.getChid, service);
  end if;
>>>
 
define net_ridf_start
<<<
--
declare
  done             boolean;
  toname           varchar2(512);
  orgname          varchar2(512);
  service          varchar2(256);
  piecenum         number;
  dfnumber         number;
  max_corrupt      binary_integer := 0;
  check_logical    boolean := FALSE;
  err_msg          varchar2(2048);
  start_time       date;
  elapsed          number;
  hours            number;
  mins             number;
  secs             number;
  outhandle        varchar2(512);
  failover         boolean := FALSE;
  outtag           varchar2(31);
  recid            number;
  stamp            number;
  fuzzy_hint       number;
  islevel0         binary_integer;
  rcvcopy          boolean := FALSE;
  rsid             number;
  rsts             number;
  preview          boolean := FALSE;
  validate         boolean := FALSE;
  isstby           boolean;
  nocfconv         boolean;
  msrpno           number := 0;
  msrpct           number := 0;
  first_time       boolean := TRUE;
  msb_section_size number;
  docompress       boolean;
  currcf           boolean;
  isfarsync        boolean := FALSE;
  networkfdf       boolean := FALSE;     
  sameend          boolean := TRUE;
  transname        boolean := FALSE;
  xfno             number := 0;
  fileckpt_scn     number := 0;
  restore_not_complete exception;
begin
  &1& -- set conversation variables
 
--
  if preview then
     deb('net_ridf_start', 'preview');
     return;
  end if;
 
  start_time := currentTime();
  sys.dbms_backup_restore.setRmanStatusRowId(rsid=>rsid, rsts=>rsts);
  if networkfdf then
     sys.dbms_backup_restore.restoreSetForeignDF(
                               check_logical => check_logical
                              ,cleanup       => FALSE
                              ,service       => service
                              ,dfincr        => TRUE
                              ,sameend       => sameend);
  else
     sys.dbms_backup_restore.applySetDatafile(
                               check_logical => check_logical
                              ,cleanup       => FALSE
                              ,service       => service);
  end if;
  docompress := setNetworkRestoreParams;
 
  krmicd.writeMsg(8039, krmicd.getChid);
  if docompress then
     krmicd.writeMsg(8168, krmicd.getChid, service);
  else
     krmicd.writeMsg(8169, krmicd.getChid, service);
  end if;
>>>
 
define net_rsal_start
<<<
--
declare
  done             boolean;
  toname           varchar2(512);
  orgname          varchar2(512);
  service          varchar2(256);
  piecenum         number;
  thread           number;
  sequence         number;
  arch_recid       number;
  arch_stamp       number;
  destination      varchar2(512) := null;
  err_msg          varchar2(2048);
  start_time       date;
  elapsed          number;
  hours            number;
  mins             number;
  secs             number;
  outhandle        varchar2(512);
  failover         boolean := FALSE;
  outtag           varchar2(31);
  rsid             number;
  rsts             number;
  preview          boolean := FALSE;
  validate         boolean := FALSE;
  currcf           boolean;
  docompress       boolean;
  msrpno           number;
  dfnumber         number;
  networkfdf       boolean := FALSE;     
  sameend          boolean := TRUE;
  transname        boolean := FALSE;
  xfno             number := 0;
  fileckpt_scn     number := 0;
  networkfal       boolean := FALSE;     
  restore_not_complete exception;
begin
  &1&
 
--
  if preview then
     deb('net_rsal_start', 'preview');
     return;
  end if;
 
  start_time := currentTime();
  sys.dbms_backup_restore.setRmanStatusRowId(rsid=>rsid, rsts=>rsts);
 
--
  if networkfal then
     sys.dbms_backup_restore.restoreSetForeignAL(
                               destination   => destination
                              ,cleanup       => FALSE
                              ,service       => service);
  else
     sys.dbms_backup_restore.restoreSetArchivedLog(
                               destination   => destination
                              ,cleanup       => FALSE
                              ,service       => service);
  end if;
  docompress := setNetworkRestoreParams;
 
  if validate then
    krmicd.writeMsg(8097, krmicd.getChid);
  elsif destination is null then
    krmicd.writeMsg(8017, krmicd.getChid);
  else
    krmicd.writeMsg(8018, krmicd.getChid);
    krmicd.writeMsg(8508, destination);
  end if;
 
  if docompress then
     krmicd.writeMsg(8168, krmicd.getChid, service);
  else
     krmicd.writeMsg(8169, krmicd.getChid, service);
  end if;
>>>
 
define net_rsdf_name
<<<
--
  toname := null;
  orgname := null;
  max_corrupt := 0;
  &object& -- dfnumber, toname, max_corrupt, tsname, orgname
 
  sys.dbms_backup_restore.networkBackupDatafile(dfnumber => dfnumber);
 
  if msrpno > 0 then
    sys.dbms_backup_restore.networkSetMSB(
                    dfnumber      => dfnumber,
                    section_size  => msb_section_size, 
                    first_section => piecenum - 1,
                    section_count => 1,
                    pieceno       => piecenum,
                    piececnt      => msrpct);
  end if;
 
  if msrpno > 1 then
    declare
      tempfno number;
    begin
      krmicd.getMSR(tempfno, toname);
    end;
  end if;
 
  if (not validate) then
    sys.dbms_backup_restore.restoreDataFileTo(dfnumber => dfnumber,
                                              toname => toname,
                                              max_corrupt => max_corrupt,
                                              tsname => tsname);
   
    if msrpno = 1 then
      sys.dbms_backup_restore.initMSR(dfnumber, toname);
    end if;
 
--
--
 
    if first_time then
       krmicd.writeMsg(8089, krmicd.getChid);
       first_time := FALSE;
    end if;
 
--
    if (not networkfdf) then
       if toname is not null then
          krmicd.writeMsg(8610, krmicd.getChid, to_char(dfnumber, 'FM09999'),
                          toname);
       else
          krmicd.writeMsg(8610, krmicd.getChid, to_char(dfnumber, 'FM09999'),
                          'default location');
       end if;
    end if;
 
    if (msrpno > 0) then
      krmicd.writeMsg(8555, krmicd.getChid, to_char(msrpno), to_char(msrpct));
    end if;
  end if;
>>>
 
define net_ridf_name
<<<
--
  toname := null;
  max_corrupt := 0;
--
  &object&
 
  sys.dbms_backup_restore.networkBackupDatafile(dfnumber => dfnumber);
 
  if msrpno > 0 then
    sys.dbms_backup_restore.networkSetMSB(
                    dfnumber      => dfnumber,
                    section_size  => msb_section_size,
                    first_section => piecenum - 1,
                    section_count => 1,
                    pieceno       => piecenum,
                    piececnt      => msrpct);
  end if;
 
  if msrpno > 1 then
    declare
      tempfno number;
    begin
      krmicd.getMSR(tempfno, toname);
    end;
  end if;
 
  if (not validate) then
     sys.dbms_backup_restore.applyDataFileTo(
                                     dfnumber       => dfnumber
                                    ,toname         => toname
                                    ,fuzziness_hint => fuzzy_hint
                                    ,max_corrupt    => max_corrupt
                                    ,islevel0       => islevel0
                                    ,recid          => recid
                                    ,stamp          => stamp);
     if msrpno = 1 then
       sys.dbms_backup_restore.initMSR(dfnumber, toname);
     end if;
    
--
--
 
     if toname is not null then
        if rcvcopy then
           krmicd.writeMsg(8551, to_char(dfnumber, 'FM09999'), toname);
        elsif (networkfdf) then
          krmicd.writeMsg(8626, krmicd.getChid, to_char(dfnumber, 'FM09999'), 
                          toname);
        else
           krmicd.writeMsg(8509, to_char(dfnumber, 'FM09999'), toname);
        end if;
     end if;
 
     if (msrpno > 0) then
       krmicd.writeMsg(8555, krmicd.getChid, to_char(msrpno), to_char(msrpct));
     end if;
  end if;
>>>
 
define net_rsal_name
<<<
--
  &object&
  sys.dbms_backup_restore.networkBackupArchivedLog(
                         arch_recid => arch_recid,
                         arch_stamp => arch_stamp);
  if (not validate) then
     sys.dbms_backup_restore.restoreArchivedLog(thread   => thread,
                                                sequence => sequence);
     krmicd.writeMsg(8022, krmicd.getChid);
     krmicd.writeMsg(8510, to_char(thread), to_char(sequence));
  end if;
>>>
 
define net_rscf_name
<<<
--
  &object&      
 
  sys.dbms_backup_restore.networkBackupDatafile(dfnumber => 0);
 
  if (not validate) then
     sys.dbms_backup_restore.restoreControlfileTo(cfname    => cfname,
                                                  isstby    => isstby,
                                                  nocfconv  => nocfconv,
                                                  isfarsync => isfarsync);
     krmicd.writeMsg(8021, krmicd.getChid);
     if (not currcf) then
        krmicd.writeMsg(8505, cfname);
     end if;
  end if;
>>>  
 
define net_rssf_name
<<<
--
  &object&
 
  sys.dbms_backup_restore.networkBackupSpfile;
 
  if (not validate) then
    sys.dbms_backup_restore.restoreSpfileTo(pfname => pfname,
                                            sfname => sfname);
    if pfname is not null then
       krmicd.writeMsg(8114, krmicd.getChid);
       krmicd.writeMsg(8505, pfname);
    elsif sfname is not null then
       krmicd.writeMsg(8115, krmicd.getChid);
       krmicd.writeMsg(8505, sfname);
    else
       krmicd.writeMsg(8115, krmicd.getChid);
       krmicd.writeMsg(8116);
    end if;
  end if;
>>>
 
define net_restore_piece
<<<
--
  sys.dbms_backup_restore.restoreSetPiece(handle   => 'network'
                                         ,tag      => null
                                         ,fromdisk => false
                                         ,recid    => 0
                                         ,stamp    => 0);
--
--
  if msrpno > 0 then
     krmicd.setMSR(dfnumber, nvl(toname, 'dummy'), orgname);
  end if;
 
  sys.dbms_backup_restore.restoreBackupPiece(done      => done 
                                            ,params    => null
                                            ,outhandle => outhandle 
                                            ,outtag    => outtag 
                                            ,failover  => failover);
  if (not done) then
     krmicd.writeMsg(8001);
     raise restore_not_complete;
  end if;
 
  elapsed := currentTime() - start_time;
  dur2time(elapsed, hours, mins, secs);
 
--
--
  if (transname) then
    xfno := sys.dbms_backup_restore.getXttsName(toname);
    krmicd.writeMsg(8626, krmicd.getChid, xfno, toname);
    if orgname is not null then
      krmicd.isRestorePlugin(true);
      krmicd.addxttfile(xfno, orgname);
      krmicd.isRestorePlugin(false);
      krmicd.addxttfile(xfno, toname);
    end if;
  end if;
 
  if (validate) then
     krmicd.writeMsg(8182, krmicd.getChid,
                           to_char(hours, 'FM09') || ':' ||
                           to_char(mins,  'FM09') || ':' ||
                           to_char(secs,  'FM09'));
  else
     krmicd.writeMsg(8180, krmicd.getChid,
                           to_char(hours, 'FM09') || ':' ||
                           to_char(mins,  'FM09') || ':' ||
                           to_char(secs,  'FM09'));
  end if;
 
  if validate then            -- validate backupset, restore validate cmds
     krmicd.fileRestored(ftype      => rman_constant.BACKUPPIECE,
                         fno        => 0,
                         thread     => 0,
                         sequence   => 0,
                         resetscn   => 0,
                         resetstamp => 0);
  else
--
     if currcf then
        print_controlfile;
     end if;
     getFileRestored(FALSE);
  end if;
 
  sys.dbms_backup_restore.restoreCancel(TRUE);
exception
  when sys.dbms_backup_restore.retryable_error_exp then
     err_msg := sqlerrm;
     if not krmicd.doRestoreFailover(rman_constant.DATAFILE) then
        raise;
     end if;
 
--
     if (not validate) then
        getFileRestored(FALSE);
     end if;
     begin
        sys.dbms_backup_restore.restoreCancel(TRUE);
     exception
        when others then
           krmicd.writeMsg(1005,
                           'dbms_backup_restore.restoreCancel() failed');
     end;
 
--
     raise;
  when others then
     sys.dbms_backup_restore.restoreCancel(TRUE);
     raise;
end;
>>>
 
define proxy_backup_start
<<<
--
declare
  dfnumber          number;
  copy_recid        number;
  copy_stamp        number;
  busy_retries      number;
  resetlogs_change  number;
  resetlogs_time    varchar2(512);
  creation_change   number;
  checkpoint_change number;
  blksize           number;
  fname             varchar2(1024);
  fmt               varchar2(1024);
  no_delete         binary_integer;
  first_time        boolean := TRUE;
  cfisstby          boolean := FALSE;
  incremental       boolean := FALSE;
  media_pool        binary_integer := 0;
  set_type          varchar2(30);
  tag               varchar2(32) := NULL;
  elapsed           number;
  start_time        date;
  hours             number;
  mins              number;
  secs              number;
  pieceno           number := 0;
  set_stamp         number;
  set_count         number;
  cfname            varchar2(1);      -- not used for backup
  currcf            boolean := FALSE; -- not used for backup
  validate          boolean := FALSE; -- not used for backup
  val_bs_only   boolean := FALSE;   -- TRUE => only bs validation
--
  keep_options      binary_integer := 0;
  keep_until        number := 0;
  lyear             varchar2(4);
  lmonth            varchar2(2);
  lday              varchar2(2);
  chtype            varchar2(16);
  isstby            boolean;
  handle            varchar2(512);
  arch_recid        number;
  arch_stamp        number;
  thread            number;
  sequence          number;
  first_change      number;
  next_change       number;
  deffmt            binary_integer;
  dest              binary_integer := 0;
  isrestore         boolean := FALSE;  -- not a proxy restore
  rsid              number;
  rsts              number;
  reqscn            number;     -- streams/standby required scn
  rlgscn            number;     -- streams/standby resetlogs scn
  appscn            number;
  apprlgscn         number;
  reqbackups        number;
  nbackups          number;
  alldest           number := 0;
  docopies          boolean := FALSE;
  in_use            exception; 
  del_for_space     exception;
  no_files          exception;
  dropped_pdb_file  exception;
  isfarsync         boolean := FALSE;
  ppltrans          number;
  pragma exception_init(in_use, -19584);
  pragma exception_init(del_for_space, -19805);
  pragma exception_init(no_files, -19581);
  pragma exception_init(dropped_pdb_file, -45913);
begin
  &1&
 
  if incremental then
     set_type := 'incremental level 0';
  else
     set_type := 'full';
  end if;
  select to_char(sysdate, 'YYYY',
                 'NLS_CALENDAR=Gregorian'),
         to_char(sysdate, 'MM',
                 'NLS_CALENDAR=Gregorian'),
         to_char(sysdate, 'DD',
                 'NLS_CALENDAR=Gregorian')
    into lyear, lmonth, lday
    from x$dual;
  sys.dbms_backup_restore.setRmanStatusRowId(rsid=>rsid, rsts=>rsts);
  sys.dbms_backup_restore.proxyBeginBackup(tag          => tag,
                                           incremental  => incremental,
                                           media_pool   => media_pool,
                                           set_stamp    => set_stamp,
                                           set_count    => set_count,
                                           keep_options => keep_options,
                                           keep_until   => keep_until);
  start_time := stamp2date(set_stamp);
>>>
 
define proxy_budf
<<<
--
  fmt := NULL;
  &1& -- fmt
  chtype := krmicd.getDevType;
  krmicd.getFormat(format => fmt,
                   copy   => 1,
                   deffmt => deffmt,
                   dest   => dest);
  if chtype is null then
     chtype := 'N/A';
  end if;
 
  loop
     exit when not krmicd.proxyBackupDataFile(dfnumber, fname);
 
     pieceno := pieceno + 1;
     if (first_time) then
        krmicd.writeMsg(8527, krmicd.getChid, set_type,
                        to_char(stamp2date(set_stamp)));
        krmicd.writeMsg(8091, krmicd.getChid);
        first_time := FALSE;
     end if;
     handle := sys.dbms_backup_restore.genPieceName(
                               pno => pieceno,
                               set_count => set_count,
                               set_stamp => set_stamp,
                               format => fmt,
                               copyno => 1,
                               devtype => chtype,
                               year => lyear,
                               month => lmonth,
                               day => lday,
                               dbid => null,     -- computed in server
                               ndbname => null,  -- computed in server
                               pdbname => null,  -- computed in server
                               cfseq => NULL);   -- not used
 
     sys.dbms_backup_restore.proxyBackupDataFile(file#  => dfnumber,
                                                 handle => handle);
     krmicd.writeMsg(8522, to_char(dfnumber, 'FM09999'), fname);
     krmicd.writeMsg(8529, handle);
  end loop;
>>>
 
define proxy_budc
<<<
--
  fmt := NULL;
  &1& -- fmt
  chtype := krmicd.getDevType;
  krmicd.getFormat(format => fmt,
                   copy   => 1,
                   deffmt => deffmt,
                   dest   => dest);
  if chtype is null then
     chtype := 'N/A';
  end if;
 
  loop
     exit when not
       krmicd.proxyBackupDataFileCopy(dfnumber, fname, copy_recid, copy_stamp);
 
     pieceno := pieceno + 1;
     if (first_time) then
        krmicd.writeMsg(8527, krmicd.getChid, set_type,
                        to_char(stamp2date(set_stamp)));
        krmicd.writeMsg(8091, krmicd.getChid);
        first_time := FALSE;
     end if;
     handle := sys.dbms_backup_restore.genPieceName(
                                pno => pieceno,
                                set_count => set_count,
                                set_stamp => set_stamp,
                                format => fmt,
                                copyno => 1,
                                devtype => chtype,
                                year => lyear,
                                month => lmonth,
                                day => lday,
                                dbid => null,    -- computed in server
                                ndbname => null, -- computed in server
                                pdbname => null, -- computed in server
                                cfseq => NULL);  -- not used
 
     begin
        sys.dbms_backup_restore.proxyBackupDataFileCopy(
                              copy_recid => copy_recid,
                              copy_stamp => copy_stamp,
                              handle     => handle);
        krmicd.writeMsg(8033, krmicd.getChid, to_char(dfnumber, 'FM09999'));
        krmicd.writeMsg(8506, fname);
        krmicd.writeMsg(8529, handle);
     exception
        when in_use then
           krmicd.writeMsg(8603, fname);
           krmicd.clearErrors;
        when del_for_space then
           krmicd.writeMsg(8604, fname);
           krmicd.clearErrors;
        when dropped_pdb_file then
           krmicd.writeMsg(6825, fname);
           krmicd.clearErrors;
     end;
  end loop;
>>>
 
define proxy_bucf
<<<
--
  fmt := NULL;
  &1& -- fmt
  chtype := krmicd.getDevType;
  krmicd.getFormat(format => fmt,
                   copy   => 1,
                   deffmt => deffmt,
                   dest   => dest);
  if chtype is null then
     chtype := 'N/A';
  end if;
 
  loop
     fname := NULL;
     exit when not krmicd.proxyBackupControlfile(fname);
 
     pieceno := pieceno + 1;
     if (first_time) then
        krmicd.writeMsg(8527, krmicd.getChid, set_type,
                        to_char(stamp2date(set_stamp)));
        krmicd.writeMsg(8091, krmicd.getChid);
        first_time := FALSE;
     end if;
--
--
--
--
     busy_retries := 0;
     <<snapshot>>  -- retry on failure to get snapshot enqueue
 
     begin
       if fname is null then -- backup current controlfile
          sys.dbms_backup_restore.cfileMakeAndUseSnapshot(isstby);
          sys.dbms_backup_restore.cfileUseCurrent;
       end if;
 
       handle := sys.dbms_backup_restore.genPieceName(
                                pno => pieceno,
                                set_count => set_count,
                                set_stamp => set_stamp,
                                format => fmt,
                                copyno => 1,
                                devtype => chtype,
                                year => lyear,
                                month => lmonth,
                                day => lday,
                                dbid => null,    -- computed in server
                                ndbname => null, -- computed in server
                                pdbname => null, -- computed in server
                                cfseq => NULL);  -- not used
 
       sys.dbms_backup_restore.proxyBackupControlFile(name   => fname,
                                                      handle => handle);
     exception
        when sys.dbms_backup_restore.snapshot_enqueue_busy then
--
--
--
--
           if busy_retries = 180 then
              krmicd.writeMsg(20029, 'cannot make a snapshot controlfile');
              raise;
           end if;
 
           busy_retries := busy_retries + 1;
--
           if (mod(busy_retries, 15) = 0) then
              krmicd.writeMsg(8512);
           end if;
           krmicd.sleep(20);
           krmicd.clearErrors;
           goto snapshot;
       end;      -- snapshot controlfile stuff
 
     if fname is null then
        if isstby then
           krmicd.writeMsg(8099);
        else
           krmicd.writeMsg(8093);
        end if;
     else
        krmicd.writeMsg(8524, fname);
     end if;
     krmicd.writeMsg(8529, handle);
  end loop;
>>>
 
define proxy_bual
<<<
--
  fmt := NULL;
  &1& -- fmt
  chtype := krmicd.getDevType;
  krmicd.getFormat(format => fmt,
                   copy   => 1,
                   deffmt => deffmt,
                   dest   => dest);
  if chtype is null then
     chtype := 'N/A';
  end if;
 
  loop
     fname := NULL;
     exit when not
       krmicd.proxyBackupArchivedLog(thread, sequence, fname, arch_recid,
                                     arch_stamp);
 
     pieceno := pieceno + 1;
     if (first_time) then
        krmicd.writeMsg(8542, krmicd.getChid, to_char(stamp2date(set_stamp)));
        krmicd.writeMsg(8543, krmicd.getChid);
        first_time := FALSE;
     end if;
     handle := sys.dbms_backup_restore.genPieceName(
                                pno => pieceno,
                                set_count => set_count,
                                set_stamp => set_stamp,
                                format => fmt,
                                copyno => 1,
                                devtype => chtype,
                                year => lyear,
                                month => lmonth,
                                day => lday,
                                dbid => null,    -- computed in server
                                ndbname => null, -- computed in server
                                pdbname => null, -- computed in server
                                cfseq => NULL);  -- not used
     begin
        sys.dbms_backup_restore.proxyBackupArchivedlog(
                                 arch_recid => arch_recid,
                                 arch_stamp => arch_stamp,
                                 handle     => handle);
        krmicd.writeMsg(8504, to_char(thread), to_char(sequence),
                        to_char(arch_recid), to_char(arch_stamp));
        krmicd.writeMsg(8529, handle);
     exception
        when in_use then
           krmicd.writeMsg(8603, fname);
           krmicd.clearErrors;
        when del_for_space then
           krmicd.writeMsg(8604, fname);
           krmicd.clearErrors;
     end;
  end loop;
>>>
 
 
define proxy_restore_start
<<<
--
declare
  currcf             boolean;
  handle             varchar2(512);
  dfnumber           number;
  toname             varchar2(512);
  orgname            varchar2(512);
  cfname             varchar2(512);
  destination        varchar2(512) := null;
  first_time         boolean := TRUE;
  start_time         date;
  elapsed            number;
  hours              number;
  mins               number;
  secs               number;
  recid              number;
  stamp              number;
  validate           boolean;
  val_bs_only        boolean := FALSE;   -- TRUE => only bs validation
--
  vrc                binary_integer;
  validation_failure exception;
  thread             number;
  sequence           number;
  resetlogs_id       number; -- ub4 value of resetlogs timestamp, used
--
--
  isrestore          boolean := TRUE;  -- is a proxy restore
  rsid               number;
  rsts               number;
  tsname             varchar2(512);
  blksize            number;
  blocks             number;
  no_files           exception;
  preplugin          boolean := FALSE;
  pdbid              number := 0;
  pplcdbdbid         number := 0;
  ppltrans           number;
  old_dfnumber       number;
  pragma exception_init(no_files, -19581);
 
begin
  &1&
 
  if (preplugin) then
     ppltrans := sys.dbms_backup_restore.beginPrePluginTranslation(
                    pdbid => pdbid, pplcdbdbid => pplcdbdbid);
  end if;
 
  sys.dbms_backup_restore.setRmanStatusRowId(rsid=>rsid, rsts=>rsts);
  if not validate then
     sys.dbms_backup_restore.proxyBeginRestore(
                                 destination      => destination
                                ,cleanup          => FALSE
                                ,preplugin        => preplugin);
  end if;
  start_time := currentTime();
  if (validate) then
    krmicd.writeMsg(8100, krmicd.getChid);
  else
    krmicd.writeMsg(8090, krmicd.getChid);
  end if;
>>>
 
define proxy_rsdf
<<<
--
  loop
     exit when not krmicd.proxyRestoreDatafile(
        handle, dfnumber, toname, blocks, blksize, tsname, old_dfnumber);
 
     sys.dbms_backup_restore.proxyRestoreDatafile(
                                        handle    => handle,
                                        file#     => dfnumber,
                                        toname    => toname,
                                        tsname    => tsname,
                                        blksize   => blksize,
                                        blocks    => blocks,
                                        old_file# => old_dfnumber);
     if first_time then
        krmicd.writeMsg(8094, krmicd.getChid);
        first_time := FALSE;
     end if;
     krmicd.writeMsg(8610, krmicd.getChid, to_char(dfnumber, 'FM09999'),
                     toname);
     krmicd.writeMsg(8529, handle);
  end loop;
>>>
 
define proxy_rscf
<<<
--
  loop
     exit when not krmicd.proxyRestoreControlfile(handle, cfname, currcf,
                                                  blocks, blksize);
 
     sys.dbms_backup_restore.proxyRestoreControlfile(handle => handle,
                                                     toname  => cfname,
                                                     blksize => blksize,
                                                     blocks  => blocks);
     if first_time then
        krmicd.writeMsg(8094, krmicd.getChid);
        first_time := FALSE;
     end if;
     krmicd.writeMsg(8021, krmicd.getChid);
     if (cfname is not null) then
        krmicd.writeMsg(8505, cfname);
     end if;
     krmicd.writeMsg(8529, handle);
  end loop;
>>>
 
define proxy_rsal
<<<
--
  loop
     exit when not
        krmicd.proxyRestoreArchivedLog(handle, thread, sequence, resetlogs_id,
                                       blocks, blksize);
 
     sys.dbms_backup_restore.proxyRestoreArchivedLog(
                                             handle => handle,
                                             thread => thread,
                                             sequence => sequence,
                                             resetlogs_id =>resetlogs_id,
                                             blksize => blksize,
                                             blocks => blocks);
     if first_time then
        krmicd.writeMsg(8544, krmicd.getChid);
        first_time := FALSE;
     end if;
     krmicd.writeMsg(8529, handle);
     krmicd.writeMsg(8022, krmicd.getChid);
     krmicd.writeMsg(8510, to_char(thread), to_char(sequence));
  end loop;
>>>
 
define proxy_val
<<<
--
  loop
     exit when not krmicd.proxyValOnly(handle, recid, stamp);
     vrc := sys.dbms_backup_restore.proxyValOnly(recid, stamp, handle);
     if vrc < sys.dbms_backup_restore.validate_file_different then
       krmicd.writeMsg(8531, krmicd.getChid, handle, 'FOUND');
       krmicd.fileRestored(ftype      => rman_constant.PROXYFILE,
                           fno        => 0,
                           thread     => 0,
                           sequence   => 0,
                           resetscn   => 0,
                           resetstamp => 0);
     else
       krmicd.writeMsg(8531, krmicd.getChid, handle, 'NOT FOUND');
     end if;
  end loop;
>>>
 
define proxy_go
<<<
--
  if not validate then
    begin
       sys.dbms_backup_restore.proxyGo;
       if isrestore then
          getFileRestored(TRUE);
       end if;
       sys.dbms_backup_restore.proxyCancel;  -- this could also signal error
    exception
       when sys.dbms_backup_restore.retryable_error_exp then
          if (isrestore and
              krmicd.doRestoreFailover(rman_constant.PROXYFILE)) then
--
             krmicd.writeErrMsg(1005, sqlerrm);
             krmicd.clearErrors;
          else
             raise;
          end if;
       when no_files then
          if (not isrestore) then
             krmicd.writeMsg(8057, krmicd.getChid);
             krmicd.clearErrors;
          else
             raise;
          end if;
       when others then
          raise;
    end;
 
    if (ppltrans > 0) then
       sys.dbms_backup_restore.endPrePluginTranslation;
    end if;
 
--
    if currcf then
       print_controlfile;
    end if;
    elapsed := currentTime() - start_time;
    dur2time(elapsed, hours, mins, secs);
    krmicd.writemsg(8528, krmicd.getChid,
                    to_char(hours, 'FM09') || ':' ||
                    to_char(mins,  'FM09') || ':' ||
                    to_char(secs,  'FM09'));
  end if;
  first_time := TRUE;          -- just in case we delete the backed archivelog
>>>
 
define proxy_end
<<<
  if validate then
    krmicd.writeMsg(8101, krmicd.getChid);
  end if;
  sys.dbms_backup_restore.setRmanStatusRowId(rsid=>0, rsts=>0);
end;
>>>
 
 
define cl_beg
<<<
{
>>>
 
define cl_unt1
<<<
   set until scn &1&;
>>>
 
define cl_unt2
<<<
   set until time &1&;
>>>
 
define cl_unt3
<<<
   set to restore point &1&;
>>>
 
define cl_catb
<<<
   catalog clone datafilecopy 
&1&
>>>
 
define cl_cat
<<<
, &1&
>>>
 
define cl_cate
<<<
;
>>>
 
define cl_cend
<<<
   ;
>>>
 
define cl_end
<<<
}
>>>
 
 
define res_cl_res
<<<
   restore
>>>
 
define res_cl_spf
<<<
   restore clone spfile to &1&;
>>>
 
define res_cl_spffb
<<<
   restore clone spfile to &1& from &2&;
>>>
 
define res_cl_spffs
<<<
   restore clone from service &2& spfile to &1&;
>>>
 
define res_cl_spffs_uscomp
<<<
   restore clone from service &2& using compressed backupset
   spfile to &1&;
>>>
 
define cop_cl_file
<<<
   targetfile &1& auxiliary format &2&
>>>
 
define cop_cl_pwdfile
<<<
   passwordfile auxiliary format &1&
>>>
 
define cop_set_spf
<<<
   sql clone "alter system set spfile=&1&";
>>>
 
define set_cl_spfp
<<<
   sql clone "alter system set &1& = &2& comment=&3& scope=spfile";
>>>
 
define set_cl_spfr
<<<
   sql clone "alter system reset &1& scope=spfile";
>>>
 
define cspfile_cl
<<<
   sql clone "create spfile from memory";
>>>
 
define cpfile_cl
<<<
   sql clone "create pfile=&1& from spfile";
>>>
 
define cl_skp
<<<
   skip forever tablespace &1&
>>>
 
define cl_skp_ro
<<<
   skip readonly
>>>
 
define cl_from_service
<<<
   from service &1&
>>>
 
define cl_from_sparse
<<<
   from &1&
>>>
 
define cl_section_size
<<<
   section size &1&
>>>
 
define cl_using_compress
<<<
   using compressed backupset
>>>
 
define cl_as_encrypted
<<<
   as encrypted 
>>>
 
define cl_as_decrypted
<<<
   as decrypted 
>>>
 
define cl_db
<<<
   clone database
>>>
 
define cl_xtt_pdb
<<<
   clone foreign pluggable database
   &1& 
>>>
 
define cl_df
<<<
   clone datafile
   &1&
>>>
 
define cl_stby
<<<
   standby
>>>
 
define cop_cl_bck
<<<
   backup as copy reuse
>>>
 
define cop_cl_df
<<<
   datafile &1& auxiliary format &2&
>>>
 
define copn_cl_df
<<<
   datafile &1& auxiliary format new
>>>
 
define cop_cl_al
<<<
   archivelog like &1& auxiliary format &2&
>>>
 
define res_cl_alfs
<<<
   restore clone force from service &1& 
           archivelog from scn &2&;
>>>
 
define res_cl_alfs_uscomp
<<<
   restore clone force from service &1& using compressed backupset
   archivelog from scn &2&;
>>>
 
define res_cl_falfs
<<<
   restore clone force from service &1& 
           foreign archivelog from scn &2&;
>>>
 
define res_cl_setaldest
<<<
   set archivelog destination to &1&;
>>>
 
define cl_add_srlg
<<<
   sql clone "alter database add standby logfile group &1& &2& size &3& &4&";
>>>
 
define cl_add_srl
<<<
  sql clone "alter database add standby logfile member &1& reuse to group &2&";
>>>
 
define cl_drop_srlg
<<<
   sql clone "alter database drop standby logfile group &1&";
>>>
 
define cat_cl_al1
<<<
   catalog clone archivelog &1&;
>>>
 
define cat_cl_al2
<<<
   catalog clone recovery area;
>>>
 
define cat_cl_al3
<<<
   catalog clone start with &1&;
>>>
 
define arc_cl_log
<<<
   sql 'alter system archive log current';
>>>
 
define res_cl_set
<<<
   set newname for datafile &1& to &2&;
>>>
 
define res_cl_setn
<<<
   set newname for clone datafile &1& to new;
>>>
 
define res_cl_swi
<<<
   switch clone datafile all;
>>>
 
define res_cl_sett
<<<
   set newname for tempfile &1& to &2&;
>>>
 
define res_cl_setnt
<<<
   set newname for clone tempfile &1& to new;
>>>
 
define res_cl_swit
<<<
   switch clone tempfile all;
>>>
 
define rec_cl_rec
<<<
   recover
>>>
 
define rec_cl_fdfs
<<<
   clone foreign datafilecopy
   &1& from service &2& 
>>>
 
define rec_cl_comma
<<<
   ,
>>>
 
define rec_cl_noredo
<<<
   noredo
>>>
 
define rec_cl_delinp
<<<
    delete archivelog
>>>
 
define opn_cl_shi
<<<
   shutdown clone immediate;
>>>
 
define opn_cl_stp
<<<
 
   startup clone nomount pfile=&1&;
>>>
 
define opn_cl_stsp
<<<
   startup clone nomount;
>>>
 
define opn_cl_swi
<<<
   switch clone datafile &1& to datafilecopy &2&;
>>>
 
define opn_cl_end
<<<
   Alter clone database open resetlogs;
>>>
 
define rec_cl_delarc
<<<
   delete clone force archivelog all;
>>>
 
define opn_cl_pdb_end
<<<
   sql clone "alter pluggable database all open";
>>>
 
define opn_cl_pdb_end_restrict
<<<
   sql clone "alter pluggable database all open restricted";
>>>
 
define en_rest_sess
<<<
   sql clone 'alter system enable restricted session';
>>>
 
define disable_system_trigger
<<<
   sql clone 'alter system set "_system_trig_enabled"=FALSE';
>>>
 
define reset_system_trigger
<<<
   sql clone 'alter system reset "_system_trig_enabled"';
>>>
 
define cl_onl_ts
<<<
   #online the readonly tablespace
   sql clone&1& "alter tablespace &2& online";
>>>
 
define cop_cl_cf
<<<
   shutdown clone immediate;
   startup clone force nomount
   backup as copy current controlfile auxiliary format &1&;
>>>
 
define cop_cl_scf
<<<
   backup as copy current controlfile for standby auxiliary format &1&;
>>>
 
define cop_cl_fcf
<<<
   backup as copy current controlfile for farsync auxiliary format &1&;
>>>
 
define cl_flash_off
<<<
   sql clone 'alter database flashback off';
>>>
 
define cop_cl_cf2
<<<
   restore clone primary controlfile to &1& from &2&;
>>>
 
define mnt_cl_cf
<<<
   alter clone database mount;
>>>
 
define mnt_cl_scf
<<<
   sql clone 'alter database mount standby database';
>>>
 
define res_cl_scf
<<<
   restore clone standby controlfile;
>>>
 
define res_cl_scffb
<<<
   restore clone standby controlfile from &1&;
>>>
 
define res_cl_scffs
<<<
   restore clone from service &1& standby controlfile;
>>>
 
define res_cl_scffs_uscomp
<<<
   restore clone from service &1& using compressed backupset
   standby controlfile;
>>>
 
define mnt_cl_fcf
<<<
   sql clone 'alter database mount';
>>>
 
define res_cl_fcf
<<<
   restore clone farsync controlfile;
>>>
 
define res_cl_fcffb
<<<
   restore clone farsync controlfile from &1&;
>>>
 
define res_cl_fcffs
<<<
   restore clone from service &1& farsync controlfile;
>>>
 
define res_cl_fcffs_uscomp
<<<
   restore clone from service &1& using compressed backupset
   farsync controlfile;
>>>
 
define res_cl_clcf
<<<
   restore clone controlfile;
   sql clone 'alter database mount clone database';
>>>
 
define res_cl_cf
<<<
   shutdown clone immediate;
   startup clone force nomount
   restore clone primary controlfile;
   alter clone database mount;
>>>
 
define res_cl_cffb
<<<
   shutdown clone immediate;
   startup clone force nomount
   restore clone primary controlfile from &1&;
   alter clone database mount;
>>>
 
define res_cl_cffs
<<<
   shutdown clone immediate;
   startup clone force nomount
   restore clone from service &1& primary controlfile;
>>>
 
define res_cl_cffs_uscomp
<<<
   shutdown clone immediate;
   startup clone force nomount
   restore clone from service &1& using compressed backupset
   primary controlfile;
>>>
 
define cl_onl_df
<<<
   sql clone&1& "alter database datafile &2& online";
>>>
 
define cl_uncat
<<<
change datafilecopy &1& uncatalog;
>>>
 
 
define val_pieces
<<<
--
declare
   pieceCnt     number := 0;
   retval       binary_integer;
   handle       varchar2(512);
   recid        number;
   stamp        number;
   setCount     number;
   setStamp     number;
   piece        number;
   valrc        binary_integer;
   hdl_isdisk   binary_integer := 0;
   m1           varchar2(128);
   m2           varchar2(128);
   m3           varchar2(128);
   m4           varchar2(128);
   m5           varchar2(128);
   m6           varchar2(128);
   m7           varchar2(128);
   m8           varchar2(128);
   m9           varchar2(128);
   m10          varchar2(128);
   m11          varchar2(128);
   m12          varchar2(128);
   m13          varchar2(128);
   m14          varchar2(128);
   m15          varchar2(128);
   m16          varchar2(128);
   m17          varchar2(128);
   m18          varchar2(128);
   m19          varchar2(128);
   m20          varchar2(128);
   returnCode   binary_integer;
   msca         binary_integer;
   attributes   binary_integer;
   preview      boolean := FALSE;
   recall       boolean := FALSE;
   imp_recall   boolean := FALSE;
   flags        binary_integer := 0;
   disp_hdr     boolean := TRUE;
   few_remote   boolean := FALSE;
   few_remote_e exception;
   pragma exception_init(few_remote_e, -20507);
 
   function addcomma(media in varchar2) return varchar2 is
      out_media varchar2(80) := null;
   begin
      if media is not null then
        out_media := ',' ||media;
      end if;
      return out_media;
   end; 
begin
  &1&
 
  if (recall = FALSE) then
     imp_recall :=
        krmicd.getVendorType = sys.dbms_backup_restore.DEVICEQUERY_OPC OR
        krmicd.getVendorType = sys.dbms_backup_restore.DEVICEQUERY_BA;
     recall := imp_recall;
  end if;
 
--
  sys.dbms_backup_restore.validationStart;
 
--
  loop
    retval := krmicd.getValidatePieceArgs(handle, recid, stamp, setCount,
                                          setStamp, piece, hdl_isdisk);
    deb('val_pieces', 'handle:'||handle||' is disk:'||hdl_isdisk);
    if (retval = 0) then
--
--
       sys.dbms_backup_restore.validationAddPiece(
                                           recid      => recid,
                                           stamp      => stamp,
                                           handle     => handle,
                                           set_stamp  => setStamp,
                                           set_count  => setCount,
                                           pieceno    => piece,
                                           params     => NULL,
                                           hdl_isdisk => hdl_isdisk);
--
        pieceCnt := pieceCnt + 1;
    else
--
       exit;
    end if;
  end loop;
 
  if (pieceCnt = 0) then
     sys.dbms_backup_restore.validationEnd;
     return;
  end if;
 
  if recall then
     flags := sys.dbms_backup_restore.vvflags_recall;
  end if;
 
--
  sys.dbms_backup_restore.validationValidate(flags => flags);
 
--
--
  loop
     sys.dbms_backup_restore.validationNextResult(handle     => handle,
                                                  recid      => recid,
                                                  set_stamp  => setStamp,
                                                  set_count  => setCount,
                                                  pieceno    => piece,
                                                  msca       => msca,
                                                  m1         => m1,
                                                  m2         => m2,
                                                  m3         => m3,
                                                  m4         => m4,
                                                  m5         => m5,
                                                  m6         => m6,
                                                  m7         => m7,
                                                  m8         => m8,
                                                  m9         => m9,
                                                  m10        => m10,
                                                  m11        => m11,
                                                  m12        => m12,
                                                  m13        => m13,
                                                  m14        => m14,
                                                  m15        => m15,
                                                  m16        => m16,
                                                  m17        => m17,
                                                  m18        => m18,
                                                  m19        => m19,
                                                  m20        => m20,
                                                  attributes => attributes);
     exit when handle is NULL;
 
     deb('val_pieces', 'validated handle:' || handle||' Media:'||m1||
         ' attributes='||attributes||' msca='||msca);
     if bitand(attributes, sys.dbms_backup_restore.attribute_remote) = 1 then
        if disp_hdr then
           if recall then
              krmicd.writeMsg(8608);
              krmicd.writeMsg(7524);
           else
              krmicd.writeMsg(8607);
              krmicd.writeMsg(6320);
           end if;
           disp_hdr := FALSE;
           few_remote := TRUE;
        end if;
        krmicd.writeMsg(6355, handle, m1 ||
                        addcomma(m2) || addcomma(m3) || addcomma(m4) ||
                        addcomma(m5) || addcomma(m6) || addcomma(m7) ||
                        addcomma(m8) || addcomma(m9) || addcomma(m10) ||
                        addcomma(m11) || addcomma(m12) || addcomma(m13) ||
                        addcomma(m14) || addcomma(m15) || addcomma(m16) ||
                        addcomma(m17) || addcomma(m18) || addcomma(m19) ||
                        addcomma(m20));
     end if;
     pieceCnt := pieceCnt - 1;
     krmicd.setValidateResult(handle, recid, setStamp, setCount, piece, msca,
                     m1 , m2 , m3 , m4 , m5 , m6 , m7 , m8 , m9 , m10,
                     m11, m12, m13, m14, m15, m16, m17, m18, m19, m20);
  end loop;
  krmicd.endPieceValidate;
  sys.dbms_backup_restore.validationEnd;
 
  if few_remote and not preview and not imp_recall then
     raise few_remote_e;
  end if;
end;
>>>
 
define backup_baut
<<<
declare
   ncopies      number;
   copyno       number;
   handle       varchar2(512);
   comment      varchar2(80);
   media        varchar2(80);
   lcfaudate    date;
   lsequence    binary_integer;
   lbautfmt     varchar2(512);
   rsid         number;
   rsts         number;
   p1           binary_integer    := 0;
   p2           binary_integer;
   p3           binary_integer;
   p4           binary_integer;
   p5           binary_integer;
   t1           varchar2(1025);
   t2           varchar2(1);
   t3           varchar2(1);
   busy_retries number            := 0;
begin
--
--
--
   &lsequence&
   &lcfaudate&
   &lbautfmt&
   &object&
   setBackupParams(FALSE);
   if (krmicd.getParams(1, p2, p3, p4, p5, t1, t2, t3)) then
      p1 := 1;
   end if;
   sys.dbms_backup_restore.setRmanStatusRowId(rsid=>rsid, rsts=>rsts);
 
   <<snapshot>>  -- retry on failure to get snapshot enqueue
   begin
      sys.dbms_backup_restore.DoAutobackup(ncopies => ncopies,
                                           cfaudate => lcfaudate,
                                           seq => lsequence,
                                           format => lbautfmt,
                                           p1 => p1,
                                           p2 => p2,
                                           p3 => p3,
                                           p4 => t1);
   exception
      when sys.dbms_backup_restore.snapshot_enqueue_busy then
--
--
--
--
         if busy_retries = 180 then
            krmicd.writeMsg(20029, 'cannot make a snapshot controlfile');
            raise;
         end if;
 
         busy_retries := busy_retries + 1;
--
         if (mod(busy_retries, 15) = 0) then
            krmicd.writeMsg(8512);
         end if;
         krmicd.sleep(20);
         krmicd.clearErrors;
         goto snapshot;
   end;      -- snapshot controlfile stuff
 
   copyno := 0;
   loop
       exit when copyno=ncopies;
       sys.dbms_backup_restore.backupPieceCrtDupGet(copyno,
                                                    handle,
                                                    comment,
                                                    media);
       if comment is null then comment := 'NONE'; end if;
       krmicd.writeMsg(8503, handle, comment);
       copyno := copyno + 1;
   end loop;
   sys.dbms_backup_restore.setRmanStatusRowId(rsid=>0, rsts=>0);
end;
>>>
 
define raut_search
<<<
--
declare
    ldbid      number := 0;
    trgt_date  date;
    lyear      varchar2(4);
    lmonth     varchar2(2);
    lday       varchar2(2);
    lmon_day   varchar2(4);
    year       binary_integer;
    month      binary_integer;
    day        binary_integer;
    ats        number;                   -- autobackup time stamp
    days       number;
    sft_seq    binary_integer;           -- search file table seq and date
    sft_date   number;
    aut_seq    binary_integer;           -- used autobackup seq and date
    aut_date   number;
    tempseq    binary_integer;           -- temp var 
    tempdate   number;
    old_seq    binary_integer := 1;
    cfname     varchar2(512);
    sfname     varchar2(512);
    pfname     varchar2(512);
    rc         number;
    status     number;
    lformat    varchar2(512)  := NULL;
    lsequence  binary_integer := 255;
    lmaxdays   number         := 7;
    handle     varchar2(512)  := NULL;
    outhandle  varchar2(512);
    sfthandle  varchar2(512);
    lhandle    varchar2(512);
    sdate      varchar2(512)  := NULL;
    currcf     boolean        := FALSE;
    set_ra     varchar2(512)  := NULL;       -- recovery area specified by user
    set_ns     varchar2(512)  := NULL;          -- name space specified by user
    uset_ns    varchar2(512)  := NULL;   -- upper case of db_name given by user
    done       boolean;
    found      boolean;
    mustspfile boolean;                 -- must we find autobackup with spfile?
    abort      boolean;
    dorestore  boolean;
    endstatus  boolean;
    fromcopy   boolean        := FALSE;
    begtime    date;
    endtime    date;
    seconds    number;
    retval     number;
    full_name  varchar2(512);
    recid      number;
    stamp      number;
    isstby     boolean        := FALSE;   -- restore standby controlfile?
    nocfconv   boolean        := FALSE;
    csf_retries number        := 0;       -- retry counter for spfile_not_in_bs
--
    rsid       number;
    rsts       number;
    start_time date;                      -- begin_time of restore
    elapsed    number;                    -- elapsed time for restore
    hours      number;
    mins       number;
    secs       number;
    dummyscn   number;
    isomf      boolean;
    isasm      boolean;
    istmplt    boolean;
    validate   boolean := FALSE;
    preview    boolean := FALSE;
    vheader    boolean := FALSE;
    isfarsync  boolean := FALSE;          -- restore farsync controlfile?
 
--
--
    dummy_error exception;
    pragma exception_init(dummy_error, -6512);
 
begin
--
--
   &1&
 
   old_seq   := lsequence;
   aut_seq   := lsequence;
 
   select decode(sdate, NULL, sysdate,
                        to_date(sdate, 'MON DD YYYY HH24:MI:SS', 
                        'NLS_CALENDAR=Gregorian'))
     into trgt_date
     from x$dual;
 
   start_time := currentTime();
 
   done       := FALSE;
   abort      := FALSE;
   dorestore  := FALSE;
   endstatus  := FALSE;
   isasm      := FALSE;
   isomf      := FALSE;
   istmplt    := FALSE;
   aut_seq    := 0;
   aut_date   := 0;
   sft_date   := 0;
   sft_seq    := 0;
   sfthandle  := to_char(NULL);
   outhandle  := to_char(NULL);
 
--
   if handle is not null 
   then
--
--
--
--
--
--
--
--
      status := sys.dbms_backup_restore.validateBackupPiece(
                                               recid             => 0,
                                               stamp             => 0,
                                               handle            => handle,
                                               set_stamp         => 0,
                                               set_count         => 0,
                                               pieceno           => 0,
                                               params            => NULL,
                                               hdl_isdisk        => 0);
      rc := bitand(status, sys.dbms_backup_restore.validate_file_different);
      if (rc = 0) 
      then
         outhandle := handle;
         fromcopy  := FALSE;
      else
         status := sys.dbms_backup_restore.validateDatafileCopy(
                                               recid             => 0,
                                               stamp             => 0,
                                               fname             => handle,
                                               dfnumber          => 0,
                                               resetlogs_change  => 0,
                                               creation_change   => 0,
                                               checkpoint_change => 0,
                                               blksize           => 0,
                                               signal            => 0);
         rc := bitand(status,
                      sys.dbms_backup_restore.validate_file_different);
         if (rc = 0) 
         then
            outhandle := handle;
            fromcopy  := TRUE;
         end if;
      end if;
   elsif (krmicd.getDevType = 'DISK') then
      if (lformat is not NULL and instr(lformat, '%') = 0)
      then 
--
         sys.dbms_backup_restore.isfileNameOMF(fname   => lformat,
                                               isomf   => isomf,
                                               isasm   => isasm,
                                               istmplt => istmplt);
      end if;
 
--
      if (istmplt and isasm) 
      then
         deb('raut_search', 'Searching ASM diskgroup ' || lformat);
--
         sys.dbms_backup_restore.searchFiles(pattern => lformat, 
                                             ns      => set_ns,
                                             omf     => TRUE,
                                             ccf     => FALSE,
                                             ftype   => 'U');
         found := sys.dbms_backup_restore.findAutSearchFileTable(
                                          mustspfile => mustspfile,
                                          until      => date2stamp(trgt_date),
                                          fname      => lhandle, 
                                          year       => year, 
                                          month      => month, 
                                          day        => day,
                                          sequence   => tempseq,
                                          ats        => ats);
         krmicd.writeMsg(8600, lformat);       
         krmicd.writeMsg(8549, set_ns);
         if (found)
         then
            krmicd.writeMsg(8601, krmicd.getChid, lhandle, lformat);
            sft_date  := year*10000+month*100+day;
            sft_seq   := tempseq;
            sfthandle := lhandle;
            deb('raut_search', 'sft_date=' || sft_date ||
                ' sft_seq=' || sft_seq);
         else
            krmicd.writeMsg(8602, krmicd.getChid, lformat);
         end if;
      end if;
 
--
--
--
      begin
         deb('raut_search', 'Searching recovery area ' || set_ra);
         sys.dbms_backup_restore.searchFiles(pattern => set_ra, 
                                             ns      => set_ns,
                                             omf     => TRUE,
                                             ccf     => FALSE,
                                             ftype   => 'U');
         found := sys.dbms_backup_restore.findAutSearchFileTable(
                                        mustspfile => mustspfile,
                                        until      => date2stamp(trgt_date),
                                        fname      => lhandle, 
                                        year       => year, 
                                        month      => month, 
                                        day        => day,
                                        sequence   => tempseq,
                                        ats        => ats);
 
         krmicd.writeMsg(8548, set_ra);       
         krmicd.writeMsg(8549, set_ns);
         if (found)
         then
            krmicd.writeMsg(8546, krmicd.getChid, lhandle);
            tempdate := year*10000+month*100+day;
            if (sft_date < tempdate OR 
                (sft_date = tempdate AND sft_seq < tempseq))
            then
               if sfthandle is not null then
                  deb('raut_search', 'Skipping autobackup ' || sfthandle ||
                      ' ;older than ' || lhandle);
               end if;
               sft_date  := tempdate;
               sft_seq   := tempseq;
               sfthandle := lhandle;
               deb('raut_search', 'sft_date=' || sft_date ||
                   ' sft_seq=' || sft_seq);
            else 
               deb('raut_search', 'Skipping autobackup ' || lhandle ||
                   ' ;older than ' || sfthandle);
            end if;
         else
            krmicd.writeMsg(8547, krmicd.getChid);
         end if;  
      exception
            when sys.dbms_backup_restore.ra_not_set then
            krmicd.clearErrors;
      end;
   end if; -- if not handle
 
 <<retry>>  -- retry on *_not_in_bs errors from restoreBackupPiece
 
--
--
--
    if (sfthandle is not null)
    then
       outhandle := sfthandle;
    end if;
 
--
--
    if (istmplt and isasm) 
    then
       goto raut_search_end;
    end if;
 
--
--
    if (handle is not null) 
    then
        goto raut_search_end;
    end if;
 
--
    if (ldbid = 0)
    then
        krmicd.writeMsg(8550, lformat);
        goto raut_search_end;
    end if;
 
--
    begin
        deb('raut_search', 'Searching manually starting with day: ' ||
            trgt_date || ' and sequence: ' || old_seq);
        found := FALSE;
        for days in 1..lmaxdays loop
            select to_char(trgt_date, 'YYYY', 'NLS_CALENDAR=Gregorian'),
                   to_char(trgt_date,   'MM', 'NLS_CALENDAR=Gregorian'),
                   to_char(trgt_date,   'DD', 'NLS_CALENDAR=Gregorian'),
                   upper(set_ns)
                into lyear, lmonth, lday, uset_ns
                from x$dual;
            select sysdate into begtime from x$dual;
            deb('raut_search', 'Channel '||krmicd.getChid||
                          ' starting search for day '||lyear||lmonth||lday||
                          ' at '||begtime);
            tempdate := to_number(lyear||lmonth||lday);
            for tempseq in reverse 0..old_seq loop
--
--
                if (tempdate < sft_date OR
                    (tempdate = sft_date AND tempseq < sft_seq)) then
                   deb('raut_search', 'Skipping autobackup search; day '
                       || tempdate || ' older than ' || outhandle);
                   found := TRUE;
                   exit;
                end if;
 
                if krmicd.getAut(tempseq, lyear||lmonth||lday) = 1 then
                   if (tempseq = old_seq) then
                       krmicd.writeMsg(8535, krmicd.getChid, tempdate);
                   end if;
                else
                   abort := TRUE;
                   exit;
                end if;
 
                lhandle := sys.dbms_backup_restore.genPieceName
                  (pno       => 0,
                   set_count => 0,
                   set_stamp => 0,
                   format    => lformat,
                   copyno    => 1,
                   devtype   => 'N/A',
                   year      => lyear,
                   month     => lmonth,
                   day       => lday,
                   dbid      => ldbid,
                   ndbname   => uset_ns,
                   pdbname   => NULL,
                   cfseq     => tempseq);
                if (mod(tempseq,10) = 0) then
                    deb('raut_search', 'Channel '|| krmicd.getChid ||
                        ' looking for day: '|| lyear || lmonth || lday ||
                        ' sequence ' || tempseq || ' handle: '||lhandle);
                end if;
--
                status := sys.dbms_backup_restore.validateBackupPiece(
                    recid     => 0,  stamp     => 0,    handle    => lhandle,
                    set_stamp => 0,  set_count => 0,    pieceno   => 0,
                    params    => NULL, hdl_isdisk => 0);
 
                deb('raut_search', 'status=' || status);
                rc := bitand(status,
                             sys.dbms_backup_restore.validate_file_different);
                deb('raut_search', 'rc=' || rc);
                if (rc = 0) then
                    found := TRUE;
                    aut_date  := tempdate;
                    aut_seq   := tempseq;
                    outhandle := lhandle;
                    krmicd.writeMsg(8536, krmicd.getChid, lhandle);
                    if (sfthandle is not null) then
                       deb('raut_search', 'Skipping autobackup ' || sfthandle
                           || ' ;older than ' || outhandle);
                    end if;
                    exit;
                end if;
            end loop;
            exit when (found OR abort);
            select sysdate, (sysdate-begtime)*60*24*60
              into endtime, seconds
              from x$dual;
            deb('raut_search', 'Channel ' || krmicd.getChid ||
                ' ending search for day ' || lyear || lmonth || lday ||
                ' at ' || endtime ||' (elapsed: ' || seconds ||
                ' seconds)');
            old_seq := 255;
            trgt_date := trgt_date - 1;
        end loop;
    end;
 
    <<raut_search_end>>
 
    if outhandle is not null then
--
        if outhandle = sfthandle then
           aut_seq   := sft_seq;
           aut_date  := sft_date;
--
--
           sft_date  := 0;
           sft_seq   := 0;
           sfthandle := to_char(null);
        end if;
 
--
--
--
--
--
--
        if (krmicd.foundAut(aut_seq, aut_date) = 0) then
            abort := TRUE;
        else
            retval := krmicd.resAut(aut_seq, aut_date);
            while (retval = 2) loop
                sys.dbms_backup_restore.sleep(5);
                retval := krmicd.resAut(aut_seq, aut_date);
             end loop;
             if (retval = 0) then
                 abort := TRUE;
             end if;
             if (retval = 1) then
                 dorestore := TRUE;
             end if;
        end if;
    end if;
 
    if abort then
        krmicd.writeMsg(8537, krmicd.getChid);
    else
        if outhandle is null then
            if  ldbid <> 0 then
               krmicd.writeMsg(8538, krmicd.getChid, lmaxdays);
            end if;
            krmicd.setNotFeasible;
        end if;
    end if;
 
--
--
--
--
--
    endstatus := krmicd.endAut;
    if preview then
       if not endstatus then
          krmicd.writeMsg(6172);
          krmicd.clearErrors;
       end if;
       return;
    end if;
 
    if not endstatus then
--
--
--
        raise dummy_error;
    end if;
 
    if vheader then
       return;
    end if;
>>>
 
define raut_cf
<<<
--
--
--
    &1&
 
    sys.dbms_backup_restore.setRmanStatusRowId(rsid=>rsid, rsts=>rsts);
 
--
--
    if aut_seq = 0 then
       trgt_date := trgt_date - 1;
       old_seq   := 255;
    else
       old_seq := aut_seq - 1;
    end if;
 
    if dorestore then
        if not fromcopy then
--
--
           if validate then
              krmicd.writeMsg(8096, krmicd.getChid);
           elsif handle is null then
               krmicd.writeMsg(8553, krmicd.getChid, outhandle);
           else
               krmicd.writeMsg(8021, krmicd.getChid);
           end if;
           if (csf_retries = 0) then
               sys.dbms_backup_restore.restoreSetDataFile;
               setRestoreParams;
               if validate then
                  sys.dbms_backup_restore.restorevalidate;
               else
                  sys.dbms_backup_restore.restoreControlFileTo(cfname,
                                                               isstby,
                                                               nocfconv,
                                                               isfarsync);
               end if;
           end if;
           begin
               sys.dbms_backup_restore.restoreBackupPiece(done => done,
                                                          handle => outhandle,
                                                          params => NULL);
           exception
--
--
--
--
           when sys.dbms_backup_restore.scf_not_in_bs then
               if (csf_retries = 3) or (handle is not null) then
                   raise;
               end if;
               csf_retries := csf_retries + 1;
               krmicd.writeMsg(8133, krmicd.getChid);
               krmicd.writeMsg(8134, krmicd.getChid);
               krmicd.clearErrors;
 
--
--
               done      := FALSE;
               abort     := FALSE;
               dorestore := FALSE;
               endstatus := FALSE;
               outhandle := to_char(NULL);
               aut_seq   := 0;
               aut_date  := 0;
               goto retry;
           end;
           elapsed := currentTime() - start_time;
           dur2time(elapsed, hours, mins, secs);
           if validate then
               krmicd.writeMsg(8182, krmicd.getChid,
                               to_char(hours, 'FM09') || ':' ||
                               to_char(mins,  'FM09') || ':' ||
                               to_char(secs,  'FM09'));
           elsif handle is null then
               krmicd.writeMsg(8534, krmicd.getChid);
           else
               krmicd.writeMsg(8180, krmicd.getChid, 
                               to_char(hours, 'FM09') || ':' ||
                               to_char(mins,  'FM09') || ':' ||
                               to_char(secs,  'FM09'));
           end if;
--
           if currcf and not validate then
               print_controlfile;
           end if;
        else
--
--
           if validate then
              krmicd.writeMsg(8518, krmicd.getChid, outhandle);
              dummyscn := sys.dbms_backup_restore.scandatafilecopy(
                                         recid            => recid,
                                         stamp            => stamp,
                                         update_fuzziness => false,
                                         check_logical    => false);
           else   
              sys.dbms_backup_restore.copyControlFile(full_name => full_name,
                                                      recid     => recid,
                                                      stamp     => stamp,
                                                      src_name  => outhandle,
                                                      dest_name => cfname);
              krmicd.writeMsg(8025, krmicd.getChid);
           end if;
--
           if currcf then
               print_controlfile;
           end if;
        end if;
 
        krmicd.fileRestored(ftype      => rman_constant.CONTROLFILE,
                            fno        => 0,
                            thread     => 0,
                            sequence   => 0,
                            resetscn   => 0,
                            resetstamp => 0);
    end if;
    sys.dbms_backup_restore.setRmanStatusRowId(rsid=>0, rsts=>0);
end;
>>>
 
define raut_sf
<<<
--
--
    &1&
    sys.dbms_backup_restore.setRmanStatusRowId(rsid=>rsid, rsts=>rsts);
 
--
--
    if aut_seq = 0 then
       trgt_date := trgt_date - 1;
       old_seq := 255;
    else
       old_seq := aut_seq - 1;
    end if;
 
    if dorestore then
        if validate then
           krmicd.writeMsg(8096, krmicd.getChid);
        else
           krmicd.writeMsg(8554, krmicd.getChid, outhandle);
        end if;
--
        if (csf_retries = 0) then
            sys.dbms_backup_restore.restoreSetDataFile;
            setRestoreParams;
            if validate then
               sys.dbms_backup_restore.restorevalidate;
            else 
               sys.dbms_backup_restore.restoreSpFileTo(pfname => pfname,
                                                       sfname => sfname);
            end if;
        end if;
        begin
            sys.dbms_backup_restore.restoreBackupPiece(done   => done,
                                                       handle => outhandle,
                                                       params => NULL);
        exception
--
--
--
--
--
            when sys.dbms_backup_restore.spfile_not_in_bs then
               if (csf_retries = 3) or (handle is not null) then
                   raise;
               end if;
               csf_retries := csf_retries + 1;
               krmicd.writeMsg(8117, krmicd.getChid);
               krmicd.writeMsg(8134, krmicd.getChid);
               krmicd.clearErrors;
 
--
--
               done      := FALSE;
               abort     := FALSE;
               dorestore := FALSE;
               endstatus := FALSE;
               outhandle := to_char(NULL);
               aut_seq   := 0;
               aut_date  := 0;
               goto retry;
        end;
        krmicd.fileRestored(ftype      => rman_constant.SPFILE,
                            fno        => 0,
                            thread     => 0,
                            sequence   => 0,
                            resetscn   => 0,
                            resetstamp => 0);
        krmicd.writeMsg(8541, krmicd.getChid);
    end if;
    sys.dbms_backup_restore.setRmanStatusRowId(rsid=>0, rsts=>0);
end;
>>>
 
define refresh_agf
<<<
--
begin
   refreshAgedFiles;
end;
>>>
 
define switch_tf
<<<
declare
   tsnum        number;
   tsname       varchar2(32);
   tfnum        number;
   tfname       varchar2(1024);
   create_time  date;
   create_scn   number;
   blocks       number;
   blocksize    binary_integer;
   rfnum        number;
   exton        boolean;
   isSFT        boolean;
   maxsize      number;
   nextsize     number;
   missing      boolean;
   rename       boolean;
   pdbid        number;
begin
  loop
     exit when not
        krmicd.switchTempfile(tsnum, tsname, tfnum, tfname, create_time,
                              create_scn, blocks, blocksize, rfnum, exton,
                              isSFT, maxsize, nextsize, missing, rename,
                              pdbid);
     deb('switch_tf', 'channel: '|| krmicd.getChid ||
         ' tempfile= '|| tfname || ' tsname= ' || tsname ||
         ' blocks= ' || blocks || ' blocksize= ' || blocksize ||
         ' create_scn= ' || to_char(create_scn) ||
         ' maxsize= ' || maxsize || ' nextsize= ' || nextsize ||
         ' pdbid= ' || pdbid);
 
     sys.dbms_backup_restore.switchTempfile(
                            tsnum => tsnum,
                            tsname => tsname,
                            tfnum => tfnum,
                            tfname => tfname,
                            create_time => create_time,
                            create_scn => create_scn,
                            blocks => blocks,
                            blocksize => blocksize,
                            rfnum => rfnum,
                            exton => exton,
                            isSFT => isSFT,
                            maxsize => maxsize,
                            nextsize => nextsize,
                            pdbid => pdbid);
     if (missing) then
        krmicd.writeMsg(8184, tfname, tsname);
     elsif (rename) then
        krmicd.writeMsg(8185, to_char(tfnum), tfname);
     else
        krmicd.writeMsg(8186, tfname);
     end if;
   end loop;
end;
>>>
 
define val_copies
<<<
--
declare
   objecttype    number;
   handle        varchar2(512);
   newname       varchar2(512);
   recid         number;
   stamp         number;
   objkey1       number;
   objkey2       number;
   blksize       number;
   ckpscn        number;
   rlscn         number;
   crescn        number;
   rc            number; 
   found         boolean;
   dummy         boolean;
   &constants&
   internal_error  exception;
   db_not_mounted  exception;
   pragma exception_init(internal_error, -600);
   pragma exception_init(db_not_mounted, -1507);
begin
   &object&
   loop
      found := FALSE;
      exit when not krmicd.valCopyGetNext(
                       objecttype    => objecttype,
                       handle        => handle,
                       recid         => recid,
                       stamp         => stamp,
                       objkey1       => objkey1,
                       objkey2       => objkey2,
                       blksize       => blksize,
                       ckpscn        => ckpscn,
                       rlscn         => rlscn,
                       crescn        => crescn,
                       found         => dummy);
      begin
         if (objecttype = krmiDC) then
            rc := sys.dbms_backup_restore.validateDataFileCopy(
                     recid             => recid,
                     stamp             => stamp,
                     fname             => handle,
                     dfnumber          => objkey1,
                     resetlogs_change  => rlscn,
                     creation_change   => crescn,
                     checkpoint_change => ckpscn,
                     blksize           => blksize,
                     signal            => 0);
 
            if (bitand(rc, krmkvt_MISSING) != 0
                or bitand(rc, krmkvt_MISSOK) != 0) then
               if (bitand(rc, krmkvt_FILE_DIFF) = 0
                   and bitand(rc, krmkvt_IN_USE) = 0 
                   and bitand(rc, krmkvt_DEL_FOR_SPACE) = 0) then
                  if (objkey1 = 0) then
                        sys.dbms_backup_restore.inspectControlFile(
                              fname             => handle,
                              full_name         => newname,
                              recid             => recid,
                              stamp             => stamp);
                  else
                        sys.dbms_backup_restore.inspectDataFileCopy(
                              fname             => handle,
                              full_name         => newname,
                              recid             => recid,
                              stamp             => stamp);
                  end if;
                  deb('val_copies', 'new recid='||recid||' stamp='||stamp);
               end if;
            end if;
         elsif (objecttype = krmiPC) then
            rc := sys.dbms_backup_restore.proxyValOnly(
                     recid  => recid,
                     stamp  => stamp,
                     handle => handle);
         elsif (objecttype = krmiRAL) then
            rc := sys.dbms_backup_restore.validateArchivedLog(
                     recid             => recid,
                     stamp             => stamp,
                     fname             => handle,
                     thread            => objkey1,
                     sequence          => objkey2,
                     resetlogs_change  => rlscn,
                     first_change      => crescn,
                     blksize           => blksize,
                     signal            => 0);
         else
            raise internal_error;
         end if;
      exception
         when internal_error then
            raise;
         when db_not_mounted then
            rc := 0;  -- inspect should have failed but successfully validated
            krmicd.clearErrors;
         when others then
            rc := sys.dbms_backup_restore.validate_file_different;
            krmicd.writeErrMsg(1005, sqlerrm);
            krmicd.clearErrors;
      end;
      
      if (rc = 0 or rc = sys.dbms_backup_restore.validate_record_notfound) then
         found := TRUE;
      end if;
 
      if (krmicd.valCopySetFound(found, recid, stamp)) then
         deb('val_copies', 'chid: ' || krmicd.getChid || ' found ' || handle);
      end if;
   end loop;
end;
>>>
 
define valhdr_copies
<<<
--
declare
   objecttype    number;
   handle        varchar2(512);
   recid         number;
   stamp         number;
   objkey1       number;
   objkey2       number;
   blksize       number;
   ckpscn        number;
   rlscn         number;
   crescn        number;
   found         boolean;
   allfound      boolean := TRUE;
   &constants&
   internal_error  exception;
   pragma exception_init(internal_error, -600);
begin
   &object&
   loop
      found := FALSE;
      exit when not krmicd.valCopyGetNext(
                       objecttype    => objecttype,
                       handle        => handle,
                       recid         => recid,
                       stamp         => stamp,
                       objkey1       => objkey1,
                       objkey2       => objkey2,
                       blksize       => blksize,
                       ckpscn        => ckpscn,
                       rlscn         => rlscn,
                       crescn        => crescn,
                       found         => found);
      if (not found) then
         allfound := FALSE;
         if (objecttype = krmiDC) then
            if (objkey1 != 0) then
               krmicd.writeMsg(6727, handle);
            else
               krmicd.writeMsg(6728, handle);
            end if;
         elsif (objecttype = krmiPC) then
            krmicd.writeMsg(8165, handle);
         elsif (objecttype = krmiRAL) then
            krmicd.writeMsg(6726, handle);
         else
            raise internal_error;
         end if;
         krmicd.setNotFeasible;
      end if;
   end loop;
 
   if (allfound) then
      if (objecttype = krmiDC) then
         krmicd.writeMsg(8166);
      elsif (objecttype = krmiPC) then
         krmicd.writeMsg(8164);
      elsif (objecttype = krmiRAL) then
         krmicd.writeMsg(6158);
      else
         raise internal_error;
      end if;
   end if;
end;
>>>
 
define 'x$valhdr_pieces'
<<<
procedure valhdr_pieces(bskey in number) is
   recid number;
   stamp number;
begin
   if not krmicd.valGetFound(recid, stamp) then
      krmicd.writeMsg(12017, bskey);
      krmicd.setNotFeasible;
   elsif (krmicd.isValAllFound) then
      krmicd.writeMsg(8163);
   end if;
end;
>>>
 
define valhdr_pieces
<<<
begin
   valhdr_pieces(&object&);
end;
>>>
 
define create_working_set
<<<
--
declare
   failureList      sys.dbms_ir.ir_failure_list_type;
   firstcall        binary_integer;
   adviseid         number;
   failureId        number;
   start_time       date;
   elapsed          number;
   hours            number;
   mins             number;
   secs             number;
begin
   &object&
 
   start_time := currentTime();
 
   if (adviseid is null) then
      firstcall := 1;
      loop
         exit when not krmicd.failureGetNext(firstcall, failureId);
         firstcall := 0;
         failureList(failureList.count + 1) := failureId;
         deb('create_working_set', 'added failureId = ' || failureId);
      end loop;
      sys.dbms_ir.getAdviseId(failureList => failureList, 
                              adviseid    => adviseid);
      deb('create_working_set', 'adviseid = ' || adviseid);
   end if;
   krmicd.copyAdviseId(adviseid => adviseid);
   sys.dbms_ir.createWorkingRepairSet(adviseid => adviseid);
 
   elapsed := currentTime() - start_time;
   dur2time(elapsed, hours, mins, secs);
   deb('create_working_set', 'took ' ||
       to_char(hours, 'FM09') || ':' ||
       to_char(mins,  'FM09') || ':' ||
       to_char(secs,  'FM09'));
end;
>>>
 
define update_feasibility_check
<<<
--
declare
   firstcall        binary_integer;
   adviseid         number;
   feasible_int     binary_integer;
   repairFeasList   sys.dbms_ir.ir_repair_feasibility_list;
   repairFeasRec    sys.dbms_ir.ir_repair_feasibility;
   start_time       date;
   elapsed          number;
   hours            number;
   mins             number;
   secs             number;
begin
   &object&
 
   start_time := currentTime();
 
   firstcall := 1;
   loop
      exit when not krmicd.repairGetNext(
               firstcall   => firstcall,
               failureidx  => repairFeasRec.failureidx,
               repairidx   => repairFeasRec.repairidx,
               feasibility => repairFeasRec.feasibility);
 
      firstcall := 0;   -- no more first call
 
      repairFeasList(repairFeasList.count + 1) := repairFeasRec;
 
      if (repairFeasRec.feasibility) then
         feasible_int := 1;
      else
         feasible_int := 0;
      end if;
 
      deb('update_feasibility_check',
          'failureidx=' || repairFeasRec.failureidx ||
          ' repairidx=' || repairFeasRec.repairidx  ||
          ' feasible='  || feasible_int);
   end loop;
 
   if (repairFeasList.count > 0) then
      sys.dbms_ir.updateFeasibilityAndImpact(
                            adviseid        => adviseid
                           ,repairList      => repairFeasList);
   end if;
 
   sys.dbms_ir.consolidateRepair(adviseid => adviseid);
 
   elapsed := currentTime() - start_time;
   dur2time(elapsed, hours, mins, secs);
   deb('update_feasibility_check', 'took: ' ||
       to_char(hours, 'FM09') || ':' ||
       to_char(mins,  'FM09') || ':' ||
       to_char(secs,  'FM09'));
end;
>>>
 
define create_repair_script
<<<
--
declare
   firstcall        binary_integer;
   filename         varchar2(512);
   fileid           number;
   cmdline          varchar2(513);
   cmdscript        sys.dbms_ir.ir_script_file_type;
   start_time       date;
   elapsed          number;
   hours            number;
   mins             number;
   secs             number;
begin
   start_time := currentTime();
 
   firstcall := 1;
   loop
      exit when not krmicd.scriptLineGetNext(firstcall, cmdline);
      if (firstcall != 0) then
         sys.dbms_ir.createScriptFile(
                      fileid   => fileid
                     ,fileName => fileName);
      end if;
      deb('create_repair_script', 'cmdline=' || cmdline);
      firstcall := 0;
      cmdscript(cmdscript.count + 1) := cmdline;
   end loop;
 
   if (fileid is not null) then
      sys.dbms_ir.writeFile(fileid    => fileid
                           ,contents  => cmdscript);
      sys.dbms_ir.closeScriptFile(fileid => fileid);
      krmicd.copyRepairScriptName(filename);
   end if;
 
   elapsed := currentTime() - start_time;
   dur2time(elapsed, hours, mins, secs);
   deb('create_repair_script', 'took: ' ||
       to_char(hours, 'FM09') || ':' ||
       to_char(mins,  'FM09') || ':' ||
       to_char(secs,  'FM09'));
end;
>>>
 
define update_repair_option
<<<
--
declare
   adviseid         number;
   optionidx        number;
   filename         varchar2(512);
   start_time       date;
   elapsed          number;
   hours            number;
   mins             number;
   secs             number;
begin
   &object&
   start_time := currentTime();
 
   filename := krmicd.getRepairScriptName;
   deb('update_repair_option', 'script_name=' || filename);
   sys.dbms_ir.updateRepairOption(
                 adviseid    => adviseid
                ,optionidx   => optionidx
                ,scriptname  => filename);
 
   elapsed := currentTime() - start_time;
   dur2time(elapsed, hours, mins, secs);
   deb('update_repair_option', 'took: ' ||
       to_char(hours, 'FM09') || ':' ||
       to_char(mins,  'FM09') || ':' ||
       to_char(secs,  'FM09'));
end;
>>>
 
define advise_done
<<<
--
declare
   adviseid          number;
   repairOptionList  sys.dbms_ir.ir_repair_option_list;
   start_time        date;
   elapsed           number;
   hours             number;
   mins              number;
   secs              number;
begin
   &object&
   start_time := currentTime();
 
   sys.dbms_ir.advisedone(
               adviseid          => adviseid
              ,generatedRepairs  => repairOptionList);
   for i in 1..repairOptionList.count loop
      deb('advise_done', 'optionidx=' || repairOptionList(i).optionidx  ||
                         ' repairid=' || repairOptionList(i).repairid);
      krmicd.copyRepairId(
          optionidx  => repairOptionList(i).optionidx
         ,repairid   => repairOptionList(i).repairid);
   end loop;
 
   elapsed := currentTime() - start_time;
   dur2time(elapsed, hours, mins, secs);
   deb('advise_done', 'took: ' ||
       to_char(hours, 'FM09') || ':' ||
       to_char(mins,  'FM09') || ':' ||
       to_char(secs,  'FM09'));
end;
>>>
 
define get_repair_script
<<<
--
declare
   repairid    number;
   fileid      number;
   cmdscript   sys.dbms_ir.ir_script_file_type;
   start_time  date;
   elapsed     number;
   hours       number;
   mins        number;
   secs        number;
   opendb      boolean := TRUE;
begin
   &object&
   start_time := currentTime();
 
   sys.dbms_ir.openScriptFile(
                   repairid   => repairid
                  ,fileid     => fileid);
   sys.dbms_ir.getFile(
                   fileid     => fileid
                  ,contents   => cmdscript);
   sys.dbms_ir.closeScriptFile(fileid => fileid);
 
   for i in 1..cmdscript.count loop
      deb('get_repair_script', 'cmdline=' || cmdscript(i));
      if (not opendb and cmdscript(i) like '%alter database open resetlogs%')
      then
         deb('get_repair_script', 'skipping open resetlogs');
      else
         krmicd.scriptLineCopyNext(cmdscript(i));
      end if;
   end loop;
 
   elapsed := currentTime() - start_time;
   dur2time(elapsed, hours, mins, secs);
   deb('get_repair_script', 'took: ' ||
       to_char(hours, 'FM09') || ':' ||
       to_char(mins,  'FM09') || ':' ||
       to_char(secs,  'FM09'));
end;
>>>
 
define repair_desc
<<<
   #&^desc&
>>>
 
define repair_spec_end
<<<
   )
>>>
 
define repair_command_end
<<<
;
>>>
 
define repair_add_fservice
<<<
   from service &^1&
>>>
 
define repair_add_df
<<<
   datafile &^1&
>>>
 
define repair_add_df_spec
<<<
   ( datafile &^1&
>>>
 
define repair_add_block
<<<
   datafile &2& block &^1&
>>>
 
define repair_add_arg
<<<
   &^1&
>>>
 
define repair_fc_restore_df_only
<<<
   restore validate header
>>>
 
define repair_fc_restore_df
<<<
   restore validate header preview
>>>
 
define repair_rs_restore_df
<<<
   restore
>>>
 
define repair_fc_recover_df
<<<
   recover validate header preview
>>>
 
define repair_rs_recover_df
<<<
   recover
>>>
 
define repair_fc_offline_df
<<<
declare
   open_inst    binary_integer;
   mount_inst   binary_integer;
   total_inst   binary_integer;
   system_tbs   binary_integer;
   noarchivelog binary_integer;
   online_rw    binary_integer;
   feasibility  boolean := TRUE;
   type numTab_t is table of number index by binary_integer;
   dfnol        numTab_t;
begin
   &1&
   select count(case when status = 'OPEN' then 1 else 0 end),
          count(case when status = 'MOUNTED' then 1 else 0 end),
          count(*)
     into open_inst, mount_inst, total_inst
     from gv$instance;
 
   deb('fc_offline_df', 'open_inst='   || open_inst ||
                        ' mount_inst=' || mount_inst ||
                        ' total_inst=' || total_inst);
   if (open_inst != total_inst OR mount_inst != total_inst) then
      feasibility := FALSE;
   end if;
 
   select count(*)
     into noarchivelog
     from v$database
    where log_mode = 'NOARCHIVELOG';
 
   deb('fc_offline_df', 'noarchivelog=' || noarchivelog);
 
   for i in 1..dfnol.count loop
      exit when not feasibility;
      select count(*)
        into system_tbs
        from (select fe.fenum file#,
                     fe.fetsn ts#,
                     fe.con_id
                from x$kccfe fe
               where fe.fedup != 0) df,
             v$tablespace ts
       where ts.name = 'SYSTEM'
         and ts.ts# = df.ts#
         and df.con_id = ts.con_id
         and df.file# = dfnol(i);
      deb('fc_offline_df', 'dfno=' || dfnol(i));
      deb('fc_offline_df', 'system_tbs=' || system_tbs);
      if (system_tbs > 0) then
         feasibility := FALSE;
      else
         select count(*)
           into online_rw
           from (select fe.fenum file#,
                 decode(fe.fetsn,
                        0, decode(bitand(fe.festa,2), 0, 'SYSOFF', 'SYSTEM'),
                        decode(bitand(fe.festa,18), 0, 'OFFLINE',
                                                    2, 'ONLINE',
                                                       'RECOVER')) status,
                 decode(fe.fedor, 2,'READ ONLY',
                        decode(bitand(fe.festa, 12), 0, 'DISABLED',
                                                     4, 'READ ONLY',
                                                    12, 'READ WRITE',
                                                        'UNKNOWN')) enabled
                from x$kccfe fe
               where fe.fedup != 0) df
          where df.status = 'ONLINE'
            and df.enabled = 'READ WRITE'
            and df.file# = dfnol(i);
         deb('fc_offline_df', 'online_rw=' || online_rw);
         if (noarchivelog > 0 and online_rw > 0) then
            feasibility := FALSE;
         end if;
      end if;
   end loop;
   if (feasibility) then
      deb('fc_offline_df', 'feasibility=TRUE');
   else
      deb('fc_offline_df', 'feasibility=FALSE');
      krmicd.setNotFeasible;
   end if;
end;
>>>
 
define repair_rs_alter_df
<<<
   sql&2& 'alter database datafile &^1&
>>>
 
define repair_rs_offline_df
<<<
   offline';
>>>
 
define repair_rs_online_df
<<<
   online';
>>>
 
define repair_fc_restore_db_only
<<<
   restore database validate header;
>>>
 
define repair_fc_restore_db_only_fservice
<<<
   restore database validate header from service&^1&;
>>>
 
define repair_fc_restore_db
<<<
   restore database validate header preview;
>>>
 
define repair_fc_rstore_db_fservice
<<<
   restore database validate header preview from service&^1&;
>>>
 
define repair_fc_restore_dbpitr
<<<
   restore database validate header preview until scn &^untscn&;
>>>
 
define repair_rs_restore_db
<<<
   restore database;
>>>
 
define repair_rs_restore_db_fservice
<<<
   restore database from service&^1&;
>>>
 
define repair_rs_reset_incarnation
<<<
   reset database to incarnation &^1&;
>>>
 
define repair_rs_restore_dbpitr
<<<
   restore database until scn &^untscn&;
>>>
 
define repair_fc_recover_db
<<<
   recover validate header preview database;
>>>
 
define repair_fc_recover_dbpitr
<<<
   recover validate header preview database until scn &^untscn&;
>>>
 
define repair_rs_recover_db
<<<
   recover database;
>>>
 
define repair_rs_recover_dbpitr
<<<
   recover database until scn &^untscn&;
>>>
 
define repair_rs_open_resetlogs
<<<
   alter database open resetlogs;
>>>
 
define repair_fc_flashback_db
<<<
   flashback validate header preview database to before scn &^1&;
>>>
 
define repair_rs_flashback_db
<<<
   flashback database to before scn &^1&;
>>>
 
define repair_fc_bmr
<<<
   recover validate header preview
>>>
 
define repair_rs_bmr
<<<
   recover
>>>
 
define repair_fc_restore_ctl
<<<
   restore validate header preview controlfile&^1&;
>>>
 
define repair_fc_restore_ctl_fservice
<<<
   restore validate header preview from service&^1& controlfile;
>>>
 
define repair_rs_set_dbid
<<<
   set dbid&^1&;
>>>
 
define repair_rs_restore_ctl
<<<
   restore controlfile&^1&;
   sql 'alter database mount';
>>>
 
define repair_rs_restore_ctl_fservice
<<<
   restore controlfile from service&^1&;
   sql 'alter database mount';
>>>
 
define repair_rs_restart_db
<<<
   shutdown;
   startup nomount;
>>>
 
define repair_fc_replicate_ctl
<<<
declare
   feasibility boolean := FALSE;
   cfname      v$controlfile.name%type;
begin
   for i in 1..9999 loop
      cfname := sys.dbms_backup_restore.getparm(
                   sys.dbms_backup_restore.control_file, i);
      exit when cfname is null;
      feasibility := sys.dbms_ir.controlfilecheck(cfname => cfname);
      if (feasibility) then
         deb('repair_fc_replicate_ctl', cfname || ' feasible');
      else
         deb('repair_fc_replicate_ctl', cfname || ' not feasible');
      end if;
      exit when feasibility;
   end loop;
   if (feasibility) then
      krmicd.copyReplicateCtlFrom(cfname => cfname);
   else
      krmicd.setNotFeasible;
   end if;
end;
>>>
 
define repair_rs_replicate_ctl
<<<
   restore controlfile from&^1&;
   sql 'alter database mount';
>>>
 
define repair_fc_sqlscript
<<<
declare
   repairtype    number;
   feasibility   boolean;
   dataloss      number;
   repairtime    number;
   parameterlist varchar2(2048);
   impact        varchar2(256);
begin
--
   &1&
   sys.dbms_ir.getFeasibilityAndImpact(
               repairtype    => repairtype
              ,parameterlist => parameterlist
              ,feasibility   => feasibility
              ,dataloss      => dataloss
              ,repairtime    => repairtime
              ,impact        => impact);
   if (feasibility) then
      deb('fc_sqlscript', 'feasibility=TRUE');
   else
      deb('fc_sqlscript', 'feasibility=FALSE');
      krmicd.setNotFeasible;
   end if;
end;
>>>
 
define repair_rs_sqlscript
<<<
   sql "begin sys.dbms_ir.execsqlscript(filename =>&1&); end;";
>>>
 
define repair_fc_force_openreset
<<<
declare
   repairtype    number;
   feasibility   boolean;
   dataloss      number;
   repairtime    number;
   parameterlist varchar2(2048);
   impact        varchar2(256);
begin
--
   &1&
   sys.dbms_ir.getFeasibilityAndImpact(
               repairtype    => repairtype
              ,parameterlist => null
              ,feasibility   => feasibility
              ,dataloss      => dataloss
              ,repairtime    => repairtime
              ,impact        => impact);
   if (feasibility) then
      deb('fc_force_openreset', 'feasibility=TRUE');
   else
      deb('fc_force_openreset', 'feasibility=FALSE');
      krmicd.setNotFeasible;
   end if;
end;
>>>
 
define repair_rs_force_openreset
<<<
   sql 'alter database recover database until cancel';
   alter database open resetlogs;
>>>
 
define res_xtt_start
<<<
--
declare
  /* restoreStatus: res_xtt_start */
  state       binary_integer;
  pieces_done binary_integer;
  files       binary_integer;
  datafiles   boolean;
  incremental boolean;
  device      boolean;
  typefno     boolean    := FALSE;
  typets      boolean    := FALSE;
  typefall    boolean    := FALSE;
  typedfcopy  boolean    := FALSE;
 
  /* setRmanStatusRowId */
  rsid        number;
  rsts        number;
 
  /* restoreSetXttfile */
  pltfrmfr    number;
 
  /* restoreXttFileTo */
  xfno        number;
  xfname      varchar2(512)   := NULL;
  xtsname     varchar2(30);
 
  /* restoreXttSetPiece */
  handle      varchar2(512);
  xplugfile   varchar2(512)   := NULL;
  doxttplug   boolean         := FALSE;
 
  /* restoreDmpfile */
  fulldmpfile varchar2(512)   := NULL;
  dmpfile     varchar2(512)   := NULL;
  dpdest      varchar2(512)   := NULL;
 
  /* restoreXttBPiece */
  done        boolean;
 
  /* Statistical variables */
  start_time  date;
  elapsed     number;
  hours       number;
  mins        number;
  secs        number;
  
  piecenum    number;
  memnum      number;
  otag        varchar2(31);
  failo       boolean   := FALSE;
  chtype      varchar2(16);
  fromdisk    boolean   := FALSE;
  first_time  boolean   := TRUE;
  files_named boolean   := FALSE;
  doimport    boolean   := FALSE;
  remdmpfile  boolean   := TRUE;
  xttsincr    boolean   := FALSE;
  doplugfcnv  boolean   := FALSE;
  restore_not_complete exception;
  /* Transportable tablespace encryption */
  jobname     varchar2(512) := NULL;
  passphrase  varchar2(128) := NULL;
 
begin
  &1& -- rsid, rsts, platform
  sys.dbms_backup_restore.restoreStatus(state, pieces_done, files, datafiles,
                       incremental, device);
  start_time := currentTime();
 
--
--
  
  krmicd.getExportJobName(jobname, passphrase);
     
  if state = sys.dbms_backup_restore.restore_no_conversation then
    goto start_convo;
  elsif state = sys.dbms_backup_restore.restore_naming_files then
    goto name_files;
  else
    goto restore_piece;
  end if;
 
<<start_convo>>
  sys.dbms_backup_restore.setRmanStatusRowId(rsid=>rsid, rsts=>rsts);
  sys.dbms_backup_restore.restoreSetXttfile(pltfrmfr, xttsincr);
  setRestoreParams;
  krmicd.writeMsg(8016, krmicd.getChid);
 
  if (passphrase is not null) then
     sys.dbms_backup_restore.setExportJobName(jobname, passphrase);
     passphrase := null;
  end if;
 
<<name_files>>
>>>
 
define res_xtt_fname
<<<
--
  &1& -- xfno, xtsname, xfname, memnum
  if files < memnum then
     if first_time then
        krmicd.writeMsg(8089, krmicd.getChid);
        first_time := FALSE;
     end if;
 
     if typefall then
        sys.dbms_backup_restore.restoreXttFileTo(
                        sys.dbms_backup_restore.xtt_all, NULL, NULL, xfname);
        krmicd.writeMsg(8622, krmicd.getChid);
     elsif typets then
        sys.dbms_backup_restore.restoreXttFileTo(
                        sys.dbms_backup_restore.xtt_tablespace, NULL,
                        xtsname, xfname);
        krmicd.writeMsg(8623, krmicd.getChid, xtsname);
     elsif typefno then
        sys.dbms_backup_restore.restoreXttFileTo(
                        sys.dbms_backup_restore.xtt_fileno, xfno, NULL,
                        xfname);
        krmicd.writeMsg(8624, krmicd.getChid, to_char(xfno, 'FM09999')); 
     elsif typedfcopy then
        sys.dbms_backup_restore.applyDataFileTo(
                        dfnumber => 1, toname => xfname, 
                        fuzziness_hint => 0, max_corrupt => 0, islevel0 => 1,
                        recid => 0, stamp => 0);
        krmicd.writeMsg(8624, krmicd.getChid, xfname);         
     end if;
 
  end if;
>>>
 
define res_name_dmpfile
<<<
--
  &1& -- dmpfile, dpdest, fulldmpfile, memnum, doimport, remdmpfile
  if files < memnum then
     if first_time then
        krmicd.writeMsg(8089, krmicd.getChid);
        first_time := FALSE;
     end if;
 
     krmicd.writeMsg(8625, krmicd.getChid, fulldmpfile);
 
     sys.dbms_backup_restore.restoreDmpfile(dmpfile => fulldmpfile);
  end if;
>>>
 
define res_xtt_do
<<<
--
  &1& -- handle, piecenum, xplugfile, doplugfcnv
  if (pieces_done + 1) = piecenum then
     krmicd.writeMsg(8003, krmicd.getChid, handle);
     begin
        if xplugfile IS NOT NULL then
           sys.dbms_backup_restore.parsePlugXmlFile(xplugfile);
           doxttplug := TRUE;
        end if;
     end;
     loop
        begin
           if xttsincr then
              chtype := krmicd.getDevType;
              if chtype = 'DISK' then
                 fromdisk := TRUE;
              end if;
              sys.dbms_backup_restore.restoreSetPiece(
                       handle => handle, tag => null, fromdisk => fromdisk,
                       recid => null, stamp => null);
              sys.dbms_backup_restore.restoreBackupPiece(
                       done => done, params => null, outhandle => handle,
                       outtag => otag, failover => failo);
              files_named := TRUE;
           else
              sys.dbms_backup_restore.XttRestore(handle, done);
              files_named := TRUE;
           end if;
        exception
           when sys.dbms_backup_restore.xtts_name_files then
              krmicd.clearErrors;
              loop
                 xfno := sys.dbms_backup_restore.getXttsName(xfname);
                 exit when xfno = 0;
                 krmicd.writeMsg(8626, krmicd.getChid, xfno, xfname);
                 krmicd.addxttfile(xfno, xfname);
              end loop;
           when others then
              raise;
        end;
        exit when files_named;
     end loop;
 
     krmicd.writeMsg(8627, krmicd.getChid, handle);
     krmicd.writeMsg(8023, krmicd.getChid, to_char(piecenum));
      
     if done then
        elapsed := currentTime() - start_time;
        dur2time(elapsed, hours, mins, secs);
        krmicd.writeMsg(8180, krmicd.getChid,
                              to_char(hours, 'FM09') || ':' ||
                              to_char(mins,  'FM09') || ':' ||
                              to_char(secs,  'FM09'));
        if doimport then
           deb('xtt-restore', 'Calling doxttimport');
           krmicd.doxttimport(dpdest, dmpfile);
        end if;
        if doxttplug then
           krmicd.isRestorePlugin(true);
           loop
              xfno := sys.dbms_backup_restore.getXttsPlugName(xfname);
              exit when xfno = 0;
              krmicd.writeMsg(8430, krmicd.getChid, xfno, xfname);
              krmicd.addxttfile(xfno, xfname);
           end loop;
           deb('xtt-restore', 'Calling doxttplug');
           krmicd.doxttplug(xplugfile, doplugfcnv);
           krmicd.isRestorePlugin(false);
        end if;
        sys.dbms_backup_restore.restoreCancel(TRUE);
        deb('xtt-restore', 'Done');
        return;
     end if;
 
     pieces_done := pieces_done + 1;
  end if;     
>>>
 
define res_xtt_end
<<<
--
  krmicd.writeMsg(8001);
  begin
     sys.dbms_backup_restore.restoreCancel(FALSE);
  exception
     when others then
        krmicd.writeMsg(1005, 'a. dbms_backup_restore.restoreCancel() failed');
  end; 
  raise restore_not_complete;
end;
>>>
 
define stbysync_restore_ctl_fservice
<<<
   restore standby controlfile from service &1&;
   alter database mount standby database;
>>>
 
define stbysync_restore_ctl
<<<
   restore standby controlfile;
   alter database mount standby database;
>>>
 
define cl_tar_catb
<<<
   catalog datafilecopy 
&1&
>>>
 
define stbysync_cl_swi
<<<
   switch datafile all;
>>>
 
define stbysync_cl_setnt
<<<
   set newname for tempfile &1& to new;
>>>
 
define stbysync_cl_swit
<<<
   switch tempfile all;
>>>
 
define stbysync_cl_resetdb
<<<
   reset database to incarnation &1&;
>>>
 
define stbysync_cl_resdffs
<<<
   restore from service &1& datafile
   &2&;
>>>
 
define stbysync_cl_resdf
<<<
   restore datafile
   &2&;
>>>
 
define stbysync_cl_recfs
<<<
  recover database from service &1&;
>>>
 
define stbysync_cl_rec
<<<
  recover database noredo;
>>>
 
#STOPSTOP <--- This is where krmk.pc stops parsing during initialization
 
 
 
 
define db
<<<
CREATE TABLE db
(
db_key           NUMBER NOT NULL,          -- sequence generated primary key
db_id            NUMBER NOT NULL,          -- kccfhdbi from controlfile
reg_db_unique_name VARCHAR2(30),           -- primary db unique name given
--
--
curr_dbinc_key   NUMBER,                   -- current incarnation
storage_prov     VARCHAR(1) DEFAULT 'N',   -- 'Y' if storage is provisioned
--
CONSTRAINT db_p  PRIMARY KEY (db_key),     -- db_key is primary key
CONSTRAINT db_u1 UNIQUE(db_id)             -- ensure that db_id is unique
) &tablespace&
>>>
 
define db_i_curr_dbinc_key
<<<
CREATE INDEX fc$db_i_curr_dbinc_key on db(curr_dbinc_key) COMPRESS 1
&tablespace&
>>>
 
define db_insert_trigger
<<<
create or replace trigger db_insert_trigger before insert on db for each row
declare
  is_owner number;
  is_auth  number;
  can_add  number;
begin
 
--
--
--
--
 
  select count(*) into is_owner from user_users where username=user;
  if is_owner > 0 then return; end if;
 
  select count(*) into is_auth from vpc_databases
    where filter_uid = uid and db_id <> 0 and db_id = :new.db_id;
  if is_auth > 0 then return; end if;
 
  update vpc_databases set db_id = :new.db_id, reg_db_unique_name = null
    where filter_uid = uid 
      and db_id = 0
      and reg_db_unique_name = :new.reg_db_unique_name;
  if sql%rowcount = 1 then
    return; 
  end if;
 
  select count(*) into can_add from vpc_users
    where filter_uid = uid and add_new_db = 'Y';
 
  if can_add = 0 then
    raise_application_error(num => -20012,
                            msg => 'not authorized to add new database');
  end if;
 
--
--
--
--
--
 
  insert into vpc_databases(filter_user, filter_uid, db_id)
     values(user, uid, :new.db_id);
 
end;
>>>
 
define rman_seq
<<<
CREATE SEQUENCE rman_seq MAXVALUE 18446744073709551615 CACHE 100 ORDER NOCYCLE
>>>
 
 
define conf
<<<
CREATE TABLE conf
(
db_key         NUMBER NOT NULL,            -- db to which this configuration
--
conf#          NUMBER NOT NULL,            -- configuration number
--
name           VARCHAR2(65) NOT NULL,      -- configuration name
value          VARCHAR2(1025),             -- configuration value
 
--
--
--
--
db_unique_name VARCHAR2(512) DEFAULT NULL, 
site_key       NUMBER DEFAULT 0 NOT NULL,
--
--
--
--
--
--
cleanup        VARCHAR2(3) DEFAULT 'YES',  
CONSTRAINT conf_f1 FOREIGN KEY(db_key)
     REFERENCES db ON DELETE CASCADE
) &tablespace&
>>>
 
define conf_i_db <<< CREATE INDEX conf_i_db on conf(db_key) &tablespace& >>>
 
define 'node'
<<<
CREATE TABLE node
(
db_unique_name  VARCHAR2(512),                         -- Instance site name
db_key          NUMBER NOT NULL,
high_conf_recid NUMBER DEFAULT 0 NOT NULL,    -- last configuration recid seen
force_resync2cf VARCHAR2(3) DEFAULT 'NO' NOT NULL, 
--
high_rout_stamp NUMBER default 0,
inst_startup_stamp NUMBER default 0,
--
--
--
--
--
database_role   VARCHAR2(7) DEFAULT 'PRIMARY' NOT NULL,
site_key        NUMBER DEFAULT 0 NOT NULL,
last_kccdivts    NUMBER DEFAULT 0,         -- for incarnation resync
high_ic_recid    NUMBER DEFAULT 0,         -- recid based incarnation resync
cf_create_time  DATE,                      -- cf version_time at last resync
--
--
dbinc_key       NUMBER DEFAULT 0 NOT NULL, -- incarnation of ckp_scn
ckp_scn         NUMBER DEFAULT 0 NOT NULL, -- cf ckp scn at last full resync
full_ckp_cf_seq NUMBER DEFAULT 0 NOT NULL, -- cf seq at last full resync
job_ckp_cf_seq  NUMBER DEFAULT 0 NOT NULL, -- cf seq at last partial resync
high_ts_recid   NUMBER,                    -- tablespace recid
high_df_recid   NUMBER,                    -- datafile recid
high_rt_recid   NUMBER,                    -- redo thread recid
high_orl_recid  NUMBER,                    -- online redo log recid
high_offr_recid NUMBER DEFAULT 0 NOT NULL, -- offline range (kkor) recid
high_rlh_recid  NUMBER DEFAULT 0 NOT NULL, -- log history (kcclh) recid
high_al_recid   NUMBER DEFAULT 0 NOT NULL, -- archived log (kccal) recid
high_bs_recid   NUMBER DEFAULT 0 NOT NULL, -- backup set (kccbs) recid
high_bp_recid   NUMBER DEFAULT 0 NOT NULL, -- backup piece (kccbp) recid
high_bdf_recid  NUMBER DEFAULT 0 NOT NULL, -- backup datafile (kccbf) recid
high_cdf_recid  NUMBER DEFAULT 0 NOT NULL, -- datafile copy (kccdc) recid
high_brl_recid  NUMBER DEFAULT 0 NOT NULL, -- backup redo log (kccbl) recid
high_bcb_recid  NUMBER DEFAULT 0 NOT NULL, -- backup datafile corruption recid
high_ccb_recid  NUMBER DEFAULT 0 NOT NULL, -- datafile copy corruption recid
high_do_recid   NUMBER DEFAULT 0 NOT NULL, -- deleted object recid
high_pc_recid   NUMBER DEFAULT 0 NOT NULL, -- proxy copy (kccpc) recid
high_bsf_recid  NUMBER DEFAULT 0 NOT NULL, -- backup SPFILE (kccbi) recid
high_rsr_recid  NUMBER DEFAULT 0 NOT NULL, -- RMAN status (kccrsr) recid
high_tf_recid   NUMBER DEFAULT 0 NOT NULL, -- tempfile recid
high_grsp_recid NUMBER DEFAULT 0 NOT NULL, -- guaranteed restore point recid
high_nrsp_recid NUMBER DEFAULT 0 NOT NULL, -- normal restore point recid
high_bcr_recid  NUMBER DEFAULT 0 NOT NULL, -- high blk crpt (kccblkcor) recid
low_bcr_recid   NUMBER DEFAULT 0 NOT NULL, -- low  blk crpt (kccblkcor) recid
high_pdb_recid  NUMBER,                    -- pluggable database recid
high_pic_recid  NUMBER DEFAULT 0 NOT NULL, -- pluggable dbinc recid
bcr_in_use      VARCHAR2(3) DEFAULT 'NO' NOT NULL,
--
bp_key_poll     NUMBER DEFAULT 0 NOT NULL, -- Feedback given to control file
--
db_timezone     VARCHAR2(64),              -- Time Zone of database
timezone_src    VARCHAR2(1),               -- 'A' - from OAM admin
--
--
--
 
CONSTRAINT node_p  PRIMARY KEY (site_key),
CONSTRAINT check_site_key CHECK (site_key > 0),
CONSTRAINT node_f1 FOREIGN KEY(db_key)
  REFERENCES db ON DELETE CASCADE,
CONSTRAINT node_u1 UNIQUE (db_key, db_unique_name),
--
--
--
CONSTRAINT check_database_role_c2 CHECK 
  ((substr(db_unique_name,1,1) = '$' AND database_role = 'RA') OR
   (substr(nvl(db_unique_name, 'A'),1,1) <> '$' AND 
     database_role IN ('PRIMARY', 'STANDBY'))),
CONSTRAINT check_timezone_src CHECK (timezone_src IN ('A', 'P','R','S'))
)  &tablespace&
>>>
 
define node_i_db_key
<<<
CREATE INDEX fc$node_i_db_key on node(db_key) COMPRESS 1
&tablespace&
>>>
 
 
define dbinc
<<<
CREATE TABLE dbinc
(
dbinc_key       NUMBER NOT NULL,        -- sequence generated primary key
db_key          NUMBER NOT NULL,        -- database to which this incarnation
--
db_name         VARCHAR2(8) NOT NULL,   -- current db_name
reset_scn       NUMBER NOT NULL,        -- SCN of last resetlogs
reset_time      DATE NOT NULL,          -- timestamp of last resetlogs
parent_dbinc_key NUMBER,                -- parent incarnation
--
dbinc_status    VARCHAR2(8) DEFAULT 'ORPHAN' NOT NULL,
dbinc_timezone  VARCHAR2(64),           -- timezone of incarnation
--
--
 
CONSTRAINT dbinc_status CHECK(dbinc_status in ('CURRENT', 'PARENT', 'ORPHAN')),
CONSTRAINT dbinc_p  PRIMARY KEY(dbinc_key),
CONSTRAINT dbinc_u1 UNIQUE (db_key, reset_scn, reset_time),
CONSTRAINT dbinc_f1 FOREIGN KEY(db_key)
  REFERENCES db ON DELETE CASCADE
) &tablespace&
>>>
 
define dbinc_i_db_key
<<<
CREATE INDEX fc$dbinc_i_db_key on dbinc(db_key) COMPRESS 1
&tablespace&
>>>
 
define db_f1
<<<
ALTER TABLE db ADD
CONSTRAINT db_f1 FOREIGN KEY(curr_dbinc_key) REFERENCES dbinc
>>>
 
define pdb
<<<
CREATE TABLE pdb
(
pdb_key           NUMBER,
db_key            NUMBER NOT NULL,         -- db to which this pdb belongs
name              VARCHAR2(128),           -- PDB name
con_id            NUMBER NOT NULL,         -- container id
db_id             NUMBER NOT NULL,         -- database id of the PDB
create_scn        NUMBER NOT NULL,
guid              RAW(16) NOT NULL,        -- guid of PDB
nobackup          VARCHAR2(1) DEFAULT 'N' NOT NULL,
--
CONSTRAINT pdb_p  PRIMARY KEY (pdb_key),
CONSTRAINT pdb_u1 UNIQUE (db_key, guid),
CONSTRAINT pdb_f1 FOREIGN KEY(db_key)
   REFERENCES db ON DELETE CASCADE,
CONSTRAINT pdb_c1 CHECK (create_scn > 0),
CONSTRAINT pdb_c_nobackup CHECK (nobackup in ('Y','N'))
) &tablespace&
>>>
 
define pdb_i_1
<<<
CREATE INDEX pdb_i_1 on pdb(db_key) &tablespace&
>>>
 
define pdb_i_2
<<<
CREATE INDEX pdb_i_2 on pdb(db_key, guid, pdb_key) &tablespace&
>>>
 
 
define pdbinc
<<<
CREATE TABLE pdbinc
(
pdbinc_key        NUMBER NOT NULL,      -- sequence generated primary key
pdb_key           NUMBER NOT NULL,      -- pdb to which this inc belongs
born_dbinc_key    NUMBER NOT NULL,      -- dbinc at which this pdbinc is born
inc_scn           NUMBER NOT NULL,      -- incarnation scn
begin_reset_scn   NUMBER NOT NULL,      -- begin resetlogs scn
begin_reset_time  DATE NOT NULL,        -- timestamp of begin resetlogs
end_reset_scn     NUMBER NOT NULL,      -- end resetlogs scn
parent_pdbinc_key NUMBER,               -- parent incarnation
--
pdbinc_status    VARCHAR2(8) DEFAULT 'ORPHAN' NOT NULL,
CONSTRAINT pdbinc_status CHECK(
   pdbinc_status in ('CURRENT', 'PARENT', 'ORPHAN')),
CONSTRAINT pdbinc_p  PRIMARY KEY(pdbinc_key),
CONSTRAINT pdbinc_u1 UNIQUE (pdb_key, born_dbinc_key, end_reset_scn),
CONSTRAINT pdbinc_f1 FOREIGN KEY(pdb_key)
  REFERENCES pdb ON DELETE CASCADE,
CONSTRAINT pdbinc_f2 FOREIGN KEY(born_dbinc_key)
  REFERENCES dbinc ON DELETE CASCADE,
CONSTRAINT pdbinc_c1 CHECK (end_reset_scn >= inc_scn)
) &tablespace&
>>>
 
define pdbinc_i_1
<<<
CREATE INDEX pdbinc_i_1 on pdbinc(pdbinc_status, pdb_key) &tablespace&
>>>
 
define pdbinc_i_born_dbinc_key
<<<
CREATE INDEX fc$pdbinc_i_born_dbinc_key on pdbinc(born_dbinc_key) COMPRESS 1
&tablespace&
>>>
 
define pdb_dbinc
<<<
CREATE TABLE pdb_dbinc
(
dbinc_key         NUMBER NOT NULL,
pdb_key           NUMBER NOT NULL,
drop_scn          NUMBER,
drop_time         DATE,
--
curr_pdbinc_key   NUMBER,             -- current incarnation
CONSTRAINT pdb_dbinc_p  PRIMARY KEY (dbinc_key, pdb_key),
CONSTRAINT pdb_dbinc_f1 FOREIGN KEY(pdb_key)
   REFERENCES pdb ON DELETE CASCADE,
CONSTRAINT pdb_dbinc_f2 FOREIGN KEY(dbinc_key)
   REFERENCES dbinc ON DELETE CASCADE
) &tablespace&
>>>
 
define pdb_dbinc_i_pdb_key
<<<
CREATE INDEX fc$pdb_dbinc_i_pdb_key on pdb_dbinc(pdb_key) COMPRESS 1
&tablespace&
>>>
 
 
 
define ckp
<<<
CREATE TABLE ckp
(
ckp_key         NUMBER NOT NULL,        -- primary key
ckp_scn         NUMBER NOT NULL,        -- controlfile checkpoint scn
ckp_time        DATE,                   -- controlfile checkpoint timestamp
ckp_cf_seq      NUMBER NOT NULL,        -- controlfile sequence
cf_create_time  DATE NOT NULL,          -- controlfile version_time
--
--
dbinc_key       NUMBER NOT NULL,        -- database incarnation
ckp_type        VARCHAR2(7) NOT NULL,   -- resync type, 'FULL' or 'PARTIAL'
ckp_db_status   VARCHAR2(7),            -- 'OPEN' or 'MOUNTED' or NULL
resync_time     DATE NOT NULL,          -- resync time
site_key        NUMBER DEFAULT 0 NOT NULL,
CONSTRAINT ckp_p  PRIMARY KEY (ckp_key),
--
--
--
CONSTRAINT ckp_u1 UNIQUE (dbinc_key, ckp_scn, ckp_type, ckp_cf_seq,
                          cf_create_time),
CONSTRAINT ckp_f1 FOREIGN KEY (dbinc_key) -- checkpoint belongs to a dbinc
  REFERENCES dbinc ON DELETE CASCADE,
CONSTRAINT ckp_f3 FOREIGN KEY (site_key) -- checkpoint belongs to a site
  REFERENCES node ON DELETE CASCADE,
CONSTRAINT ckp_c_type CHECK (ckp_type in ('FULL', 'PARTIAL'))
) &tablespace&
>>>
 
define ckp_i_site_key
<<<
CREATE INDEX fc$ckp_i_site_key on ckp(site_key) COMPRESS 1
&tablespace&
>>>
 
 
 
 
define ts
<<<
CREATE TABLE ts
(
dbinc_key            NUMBER NOT NULL,       -- database incarnation
ts#                  NUMBER NOT NULL,       -- tablespace id in target db
ts_name              VARCHAR2(30) NOT NULL, -- tablespace name
create_scn           NUMBER NOT NULL,       -- creation SCN (from 1st datafile)
create_time          DATE,                  -- creation time
plugin_scn           NUMBER DEFAULT 0 NOT NULL, -- plugin SCN
bigfile              VARCHAR2(3) DEFAULT 'NO' NOT NULL,
--
--
--
temporary            VARCHAR2(3) DEFAULT 'NO' NOT NULL,
--
--
--
--
drop_scn             NUMBER,                -- drop SCN (as calculated)
--
drop_time            DATE,                  -- drop time
included_in_database_backup
                     VARCHAR2(3) DEFAULT 'YES' NOT NULL,
--
--
--
encrypt_in_backup
                     VARCHAR2(3),
--
--
--
--
pdbinc_key           NUMBER NOT NULL,
CONSTRAINT ts_p2 PRIMARY KEY
   (dbinc_key, pdbinc_key, ts#, create_scn, plugin_scn),
CONSTRAINT ts_u5 UNIQUE
   (dbinc_key, pdbinc_key, ts_name, create_scn, plugin_scn),
CONSTRAINT ts_u4 UNIQUE (dbinc_key, pdbinc_key, ts#, drop_scn),
CONSTRAINT ts_f1 FOREIGN KEY (dbinc_key)
  REFERENCES dbinc ON DELETE CASCADE,
CONSTRAINT ts_f2 FOREIGN KEY (pdbinc_key)
  REFERENCES pdbinc ON DELETE CASCADE
) &tablespace&
>>>
 
define ts_i_pdbinc_key
<<<
CREATE INDEX fc$ts_i_pdbinc_key on ts(pdbinc_key) COMPRESS 1
&tablespace&
>>>
 
define tsatt
<<<
CREATE TABLE tsatt
(
dbinc_key       NUMBER NOT NULL,        -- database incarnation
ts#             NUMBER NOT NULL,        -- tablespace id in target db
create_scn      NUMBER NOT NULL,        -- creation SCN
plugin_scn      NUMBER DEFAULT 0 NOT NULL, -- plugin SCN
start_ckp_key   NUMBER NOT NULL,        -- ckp when first observed
end_ckp_key     NUMBER,                 -- ckp when changed; NULL->current
rbs_count       NUMBER,                 -- number of rollback segs in this ts
--
pdbinc_key      NUMBER NOT NULL,
CONSTRAINT tsatt_u3 UNIQUE
  (dbinc_key, pdbinc_key, ts#, create_scn, plugin_scn, end_ckp_key),
CONSTRAINT tsatt_f2 FOREIGN KEY (start_ckp_key)
  REFERENCES ckp,
CONSTRAINT tsatt_f3 FOREIGN KEY (end_ckp_key)
  REFERENCES ckp,
CONSTRAINT tsatt_f5 FOREIGN KEY
  (dbinc_key, pdbinc_key, ts#, create_scn, plugin_scn)
  REFERENCES ts ON DELETE CASCADE INITIALLY DEFERRED,
CONSTRAINT tsatt_f6 FOREIGN KEY (pdbinc_key)
  REFERENCES pdbinc ON DELETE CASCADE
) &tablespace&
>>>
 
define tsatt_i_pdbinc_key
<<<
CREATE INDEX fc$tsatt_i_pdbinc_key on tsatt(pdbinc_key) COMPRESS 1
&tablespace&
>>>
 
 
 
define df
<<<
CREATE TABLE df
(
dbinc_key            NUMBER NOT NULL,  -- database incarnation
file#                NUMBER NOT NULL,  -- database file number
create_scn           NUMBER NOT NULL,  -- creation SCN
create_time          DATE,             -- creation timestamp
ts#                  NUMBER NOT NULL,  -- tablespace id in target db
ts_create_scn        NUMBER NOT NULL,  -- tablespace creation SCN
block_size           NUMBER NOT NULL,  -- blocksize
--
clone_fname          VARCHAR2(1024),   -- clone datafile name (alias aux_name)
drop_scn             NUMBER,           -- drop SCN (as calculated)
--
drop_time            DATE,             -- drop time
stop_scn             NUMBER,           -- offline clean or read only scn
stop_time            DATE,             -- timestamp for above SCN
read_only            NUMBER NOT NULL,  -- 1 if stop_scn is read only, else 0
rfile#               NUMBER,           -- tablespace relative file number
df_key               NUMBER NOT NULL,
blocks               NUMBER,           -- size of file
foreign_dbid         NUMBER     DEFAULT 0 NOT NULL,
foreign_create_scn   NUMBER     DEFAULT 0 NOT NULL,
foreign_create_time  DATE,
plugged_readonly     VARCHAR2(3) DEFAULT 'NO' NOT NULL,
plugin_scn           NUMBER     DEFAULT 0 NOT NULL,
plugin_reset_scn     NUMBER     DEFAULT 0 NOT NULL,
plugin_reset_time    DATE,
create_thread        NUMBER,           -- null means unknown, 0 not recreatable
create_size          NUMBER,           -- null means unknown, 0 not recreatable
pdbinc_key           NUMBER NOT NULL,
ts_pdbinc_key        NUMBER NOT NULL,
issft                NUMBER,           -- null means unknown
ts_plugin_scn        NUMBER     DEFAULT 0 NOT NULL,  -- tablespace plugin scn
pdb_closed           NUMBER     DEFAULT 0 NOT NULL,  -- 1 if pdb is closed, else 0
pdb_foreign_dbid     NUMBER     DEFAULT 0 NOT NULL,
pdb_foreign_ckp_scn  NUMBER     DEFAULT 0 NOT NULL,
--
--
--
pdb_foreign_afn      NUMBER     DEFAULT 0 NOT NULL,
--
CONSTRAINT df_p1 PRIMARY KEY
   (dbinc_key, pdbinc_key, file#, create_scn, plugin_scn),
CONSTRAINT df_u3 UNIQUE (dbinc_key, pdbinc_key, file#, drop_scn),
CONSTRAINT df_u4 UNIQUE (dbinc_key, pdbinc_key, df_key),
--
--
--
--
CONSTRAINT df_f6 FOREIGN KEY
  (dbinc_key, ts_pdbinc_key, ts#, ts_create_scn, ts_plugin_scn)
  REFERENCES ts ON DELETE CASCADE,
CONSTRAINT df_f7 FOREIGN KEY (pdbinc_key) REFERENCES pdbinc ON DELETE CASCADE
) &tablespace&
>>>
 
define df_i_1
<<<
CREATE INDEX df_i_1 on 
   df(dbinc_key, ts_pdbinc_key, ts#, ts_create_scn, ts_plugin_scn) &tablespace&
>>>
 
define df_i_pdbinc_key
<<<
CREATE INDEX fc$df_i_pdbinc_key on df(pdbinc_key) COMPRESS 1
&tablespace&
>>>
 
define site_dfatt
<<<
CREATE TABLE site_dfatt
(
fname           VARCHAR2(1024),         -- datafile name
df_key          NUMBER NOT NULL,
site_key        NUMBER NOT NULL,
CONSTRAINT site_dfatt_p PRIMARY KEY (df_key, site_key),
--
--
CONSTRAINT site_dfatt_f2 FOREIGN KEY (site_key)
  REFERENCES node ON DELETE CASCADE
) &tablespace&
>>>
 
define site_dfatt_i_site_key
<<<
CREATE INDEX fc$site_dfatt_i_site_key on site_dfatt(site_key) COMPRESS 1
&tablespace&
>>>
 
 
 
 
define offr
<<<
CREATE TABLE offr
(
offr_key        NUMBER NOT NULL,
dbinc_key       NUMBER NOT NULL,        -- database incarnation
offr_recid      NUMBER,                 -- offline range recid
offr_stamp      NUMBER,                 -- offline range stamp
file#           NUMBER NOT NULL,        -- datafile number
create_scn      NUMBER NOT NULL,        -- datafile creation scn
offline_scn     NUMBER NOT NULL,        -- scn at datafile was taken offline
online_scn      NUMBER NOT NULL,        -- online checkpoint SCN
online_time     DATE NOT NULL,          -- online checkpoint time
cf_create_time  DATE,                   -- controlfile creation time
CONSTRAINT offr_p  PRIMARY KEY (offr_key),
CONSTRAINT offr_u2 UNIQUE (dbinc_key, file#, create_scn, offline_scn,
                           cf_create_time),
CONSTRAINT offr_f1 FOREIGN KEY (dbinc_key)
  REFERENCES dbinc ON DELETE CASCADE
) &tablespace&
>>>
 
 
define tf
<<<
CREATE TABLE tf
(
dbinc_key       NUMBER NOT NULL,        -- database incarnation
file#           NUMBER NOT NULL,        -- tempfile number
create_scn      NUMBER NOT NULL,        -- creation SCN
create_time     DATE,                   -- creation timestamp
ts#             NUMBER NOT NULL,        -- tablespace id in target db
ts_create_scn   NUMBER NOT NULL,        -- tablespace creation SCN
plugin_scn      NUMBER DEFAULT 0 NOT NULL, -- always zero for temp files
--
block_size      NUMBER NOT NULL,        -- blocksize
rfile#          NUMBER,                 -- tablespace relative file number
tf_key          NUMBER NOT NULL,
pdb_key         NUMBER NOT NULL,
ts_pdbinc_key   NUMBER NOT NULL,
CONSTRAINT tf_p  PRIMARY KEY (dbinc_key, file#, create_scn),
--
--
--
--
--
--
--
--
--
--
CONSTRAINT tf_f4 FOREIGN KEY (pdb_key)
   REFERENCES pdb ON DELETE CASCADE
) &tablespace&
>>>
 
define tf_i_1
<<<
CREATE INDEX tf_i_1 on
   tf(dbinc_key, ts_pdbinc_key, ts#, ts_create_scn, plugin_scn) &tablespace&
>>>
 
define tf_i_pdb_key
<<<
CREATE INDEX fc$tf_i_pdb_key on tf(pdb_key) COMPRESS 1
&tablespace&
>>>
 
 
 
define site_tfatt
<<<
CREATE TABLE site_tfatt
(
fname           VARCHAR2(1024),         -- datafile name
tf_key          NUMBER NOT NULL,
site_key        NUMBER NOT NULL,
drop_scn        NUMBER,                 -- drop SCN (as calculated)
--
drop_time       DATE,                   -- drop time
blocks          NUMBER,                 -- size of file in blocks
autoextend      VARCHAR2(3),
max_size        NUMBER,
next_size       NUMBER,
CONSTRAINT site_tfatt_p PRIMARY KEY (tf_key, site_key),
--
--
CONSTRAINT site_tfatt_f2 FOREIGN KEY (site_key)
  REFERENCES node ON DELETE CASCADE
) &tablespace&
>>>
 
define site_tfatt_i_site_key
<<<
CREATE INDEX fc$site_tfatt_i_site_key on site_tfatt(site_key) COMPRESS 1
&tablespace&
>>>
 
 
define rr
<<<
CREATE TABLE rr
(
rr_key          NUMBER NOT NULL,
dbinc_key       NUMBER NOT NULL,        -- database incarnation
low_scn         NUMBER NOT NULL,        -- low SCN of the range
high_scn        NUMBER NOT NULL,        -- high SCN of the range
CONSTRAINT rr_p  PRIMARY KEY (rr_key),
CONSTRAINT rr_f1 FOREIGN KEY (dbinc_key)
  REFERENCES dbinc ON DELETE CASCADE
) &tablespace&
>>>
 
define rr_i_dbinc_key
<<<
CREATE INDEX fc$rr_i_dbinc_key on rr(dbinc_key) COMPRESS 1
&tablespace&
>>>
 
 
define rt
<<<
CREATE TABLE rt
(
dbinc_key       NUMBER NOT NULL,        -- database incarnation
thread#         NUMBER NOT NULL,        -- thread number
--
sequence#       NUMBER NOT NULL,        -- last log sequence number allocated
enable_scn      NUMBER,                 -- SCN of last enable
enable_time     DATE,                   -- timestamp of last enable
disable_scn     NUMBER,                 -- SCN of last disable
disable_time    DATE,                   -- timestamp of last disable
status          VARCHAR2(1) NOT NULL,   -- 'D' -> disabled
--
--
--
CONSTRAINT rt_p  PRIMARY KEY (dbinc_key, thread#),
CONSTRAINT rt_f1 FOREIGN KEY (dbinc_key)
  REFERENCES dbinc ON DELETE CASCADE,
CONSTRAINT rt_c1_status CHECK (status in ('D','E','O','I'))
) &tablespace&
>>>
 
define orl
<<<
CREATE TABLE orl
(
dbinc_key       NUMBER NOT NULL,              -- database incarnation
thread#         NUMBER NOT NULL,              -- thread number
group#          NUMBER NOT NULL,              -- group number
fname           VARCHAR2(1024) NOT NULL,      -- datafile name
bytes           NUMBER DEFAULT NULL,          -- size of redolog
type            VARCHAR2(7) DEFAULT 'ONLINE', -- ONLINE or STANDBY
site_key        NUMBER,
--
CONSTRAINT orl_f1 FOREIGN KEY (dbinc_key, thread#)
  REFERENCES rt ON DELETE CASCADE,
CONSTRAINT orl_f2 FOREIGN KEY (site_key)
  REFERENCES node ON DELETE CASCADE
) &tablespace&
>>>
 
define orl_i_1
<<<
CREATE INDEX orl_i_1 on orl(dbinc_key, thread#, group#) &tablespace&
>>>
 
define orl_i_site_key
<<<
CREATE INDEX fc$orl_i_site_key on orl(site_key) COMPRESS 1
&tablespace&
>>>
 
 
define rlh
<<<
CREATE TABLE rlh
(
rlh_key         NUMBER NOT NULL,
dbinc_key       NUMBER NOT NULL,        -- database incarnation
rlh_recid       NUMBER NOT NULL,        -- log history recid from control file
rlh_stamp       NUMBER NOT NULL,        -- log history stamp from control file
thread#         NUMBER NOT NULL,        -- thread number
sequence#       NUMBER NOT NULL,        -- log sequence number
low_scn         NUMBER NOT NULL,        -- scn generated when switching in
low_time        DATE NOT NULL,
next_scn        NUMBER NOT NULL,        -- scn generated when switching out
status          VARCHAR2(1),            -- 'C' -> cleared
CONSTRAINT rlh_p  PRIMARY KEY (rlh_key),
CONSTRAINT rlh_u1 UNIQUE (dbinc_key, thread#, sequence#, low_scn),
CONSTRAINT rlh_f1 FOREIGN KEY (dbinc_key) REFERENCES dbinc ON DELETE CASCADE,
CONSTRAINT rlh_c_status CHECK (status in ('C'))
) &tablespace&
>>>
 
 
 
define al
<<<
CREATE TABLE al
(
al_key          NUMBER NOT NULL,
dbinc_key       NUMBER NOT NULL,        -- database incarnation
al_recid        NUMBER NOT NULL,        -- archive log recid from control file
al_stamp        NUMBER NOT NULL,        -- archive log stamp from control file
thread#         NUMBER NOT NULL,        -- thread number
sequence#       NUMBER NOT NULL,        -- log sequence number
low_scn         NUMBER NOT NULL,        -- scn generated when switching in
low_time        DATE   NOT NULL,        -- time low SCN allocated
next_scn        NUMBER NOT NULL,        -- scn generated when switching out
next_time       DATE,                   -- time when next SCN allocated
fname           VARCHAR2(1024),         -- archive log file name,
--
fname_hashkey   VARCHAR2(20),           -- hashed fname for indexing
archived        VARCHAR2(1) NOT NULL,   -- 'Y' -> archived log
--
blocks          NUMBER NOT NULL,        -- number of blocks written
block_size      NUMBER NOT NULL,        -- size of a block in bytes
completion_time DATE NOT NULL,          -- time the log was archived or copied
is_standby      VARCHAR2(1),            -- 'Y' if standby, 'N' if primary
status          VARCHAR2(1) NOT NULL,
dictionary_begin VARCHAR2(3),           -- log contains start of logminer dict
dictionary_end   VARCHAR2(3),           -- log contains end of logminer dict
is_recovery_dest_file VARCHAR2(3) DEFAULT 'NO' NOT NULL,
--
compressed      VARCHAR2(3) DEFAULT 'NO',  -- compressed
creator         VARCHAR2(7) DEFAULT NULL,
terminal        VARCHAR2(3) DEFAULT 'NO',  -- 'YES' for terminal rcv log
site_key        NUMBER,                    -- Null when log owner is unknown
CONSTRAINT al_p  PRIMARY KEY (al_key),
CONSTRAINT al_u1 UNIQUE (dbinc_key, al_recid, al_stamp, is_standby),
CONSTRAINT al_f1 FOREIGN KEY (dbinc_key) REFERENCES dbinc ON DELETE CASCADE,
CONSTRAINT al_f2 FOREIGN KEY (site_key) REFERENCES node ON DELETE CASCADE,
CONSTRAINT al_c_archived CHECK (archived in ('Y','N')),
CONSTRAINT al_c_status CHECK (status in ('A','U','D','X')),
CONSTRAINT al_c_is_standby CHECK (is_standby in ('Y','N'))
) &tablespace&
>>>
 
define al_i_fname_status
<<<
CREATE INDEX al_i_fname_status on al(fname_hashkey, status) &tablespace&
>>>
 
define al_i_2
<<<
CREATE INDEX al_i_2 on al(dbinc_key, thread#, sequence#, low_scn) &tablespace&
>>>
 
define al_i_site_key
<<<
CREATE INDEX fc$al_i_site_key on al(site_key) COMPRESS 1
&tablespace&
>>>
 
 
define bs
<<<
CREATE TABLE bs
(
bs_key          NUMBER NOT NULL,        -- sequence generated primary key
db_key          NUMBER NOT NULL,        -- database
bs_recid        NUMBER,                 -- backup set recid from control file
bs_stamp        NUMBER,                 -- backup set stamp from control file
set_stamp       NUMBER NOT NULL,        -- set_stamp from control file
set_count       NUMBER NOT NULL,        -- set_count from control file
bck_type        VARCHAR2(1),            -- 'D' -> full datafile
--
--
incr_level      NUMBER,                 -- incremental backup level (0 - 4)
--
--
pieces          NUMBER NOT NULL,        -- number of backup pieces in the set
start_time      DATE,                   -- time when this backup started
completion_time DATE,                   -- time when this backup completed
status          VARCHAR2(1),            -- 'A' -> complete set of pieces avail
--
--
controlfile_included                    -- Indicates if this backup set has
                VARCHAR2(7),            -- a controlfile in it
--
--
--
--
input_file_scan_only VARCHAR2(3),       -- 'NO' -> this is a real backup
--
keep_options  NUMBER DEFAULT 0 NOT NULL,-- if backup is done with keep option
--
--
--
--
keep_until      DATE,                   -- valid only if keep_options != 0
--
block_size      NUMBER DEFAULT NULL,    -- block size for backup set
--
--
site_key        NUMBER,                 -- Null when set owner is unknown
--
multi_section   VARCHAR2(1),            -- 'Y' if backup is multi-section, else
--
pdb_key         NUMBER NOT NULL,
CONSTRAINT bs_p  PRIMARY KEY (bs_key),
CONSTRAINT bs_u2 UNIQUE (db_key, set_stamp, set_count),
CONSTRAINT bs_f1 FOREIGN KEY(db_key)    -- backup set belongs to a db
  REFERENCES db ON DELETE CASCADE,
CONSTRAINT bs_f2 FOREIGN KEY (site_key) REFERENCES node,
CONSTRAINT bs_f3 FOREIGN KEY (pdb_key)  REFERENCES pdb,
CONSTRAINT bs_c_bck_type CHECK (bck_type in ('D','I','L')),
CONSTRAINT bs_c_incr_level CHECK (incr_level in (0,1,2,3,4)),
--
CONSTRAINT bs_c_controlfile_included CHECK (controlfile_included in
                                            ('NONE','BACKUP','STANDBY'))
) &tablespace&
>>>
 
define bs_i_1
<<<
CREATE INDEX bs_i_1 on bs(db_key, bs_recid, bs_stamp)
&tablespace&
>>>
 
define bs_i_site_db_key
<<<
CREATE INDEX bs_i_site_db_key on bs(site_key,db_key)
&tablespace&
>>>
 
define bs_i_cleanupBV
<<<
CREATE INDEX bs_i_cleanupBV on bs
   (db_key, input_file_scan_only, completion_time, status)
&tablespace&
>>>
 
define bs_i_pdb_key
<<<
CREATE INDEX fc$bs_i_pdb_key on bs(pdb_key) COMPRESS 1
&tablespace&
>>>
 
 
define bp
<<<
CREATE TABLE bp
(
bp_key          NUMBER NOT NULL,        -- sequence generated primary key
bs_key          NUMBER NOT NULL,        -- backup set
db_key          NUMBER NOT NULL,
bp_recid        NUMBER NOT NULL,        -- backup piece recid from control file
bp_stamp        NUMBER NOT NULL,        -- backup piece stamp from control file
piece#          NUMBER NOT NULL,        -- first piece is 1
copy#           NUMBER NOT NULL,        -- copy number, 1 if no copies
tag             VARCHAR2(32),           -- user specified tag
device_type     VARCHAR2(255) NOT NULL, -- 'DISK' -> on disk rather than seq
handle          VARCHAR2(1024) NOT NULL, --backup piece handle
handle_hashkey  VARCHAR2(30) NOT NULL,  -- indexed hashkey on handle
comments        VARCHAR2(255),          --
 
 
media           VARCHAR2(80),           -- media handle
media_pool      NUMBER,                 -- media pool
concur          VARCHAR2(1) NOT NULL,   -- 'Y' media supports concurrent access
start_time      DATE NOT NULL,          -- time when this piece started
completion_time DATE NOT NULL,          -- time when this piece completed
--
status          VARCHAR2(1) NOT NULL,
bytes           NUMBER DEFAULT NULL,
is_recovery_dest_file VARCHAR2(3) DEFAULT 'NO' NOT NULL,
--
rsr_key         NUMBER,                 -- key of the row in the rsr table
compressed      VARCHAR2(3) DEFAULT 'NO',-- compressed
site_key        NUMBER,                 -- Null when piece owner is unknown
encrypted       VARCHAR(1) DEFAULT 'N', -- 'Y' means encrypted, otherwise not
backed_by_osb   VARCHAR(1) DEFAULT 'N', -- 'Y' means backed by OSB 
ct_key          NUMBER,                 -- sbt_catalog key
ba_access       VARCHAR(1) DEFAULT 'U', -- Unknown, Local, Tape, Disk,
--
--
--
vb_key          NUMBER,                 -- virtual backup ID
lib_key         NUMBER,                 -- lib_key  (used by ORS only)
purged          VARCHAR(1) DEFAULT 'U' NOT NULL,
--
--
--
pdb_key         NUMBER NOT NULL,
template_key    NUMBER,                 -- template_key
CONSTRAINT bp_p  PRIMARY KEY (bp_key),
CONSTRAINT bp_u1 UNIQUE (bs_key, bp_recid, bp_stamp),
CONSTRAINT bp_u2 UNIQUE (ct_key),
CONSTRAINT bp_f2 FOREIGN KEY (site_key) REFERENCES node,
CONSTRAINT bp_f3 FOREIGN KEY (bs_key) REFERENCES bs,
CONSTRAINT bp_f4 FOREIGN KEY (pdb_key) REFERENCES pdb,
CONSTRAINT bp_c_rs CHECK (ba_access IN ('U', 'D', 'L', 'T', 'R')),
CONSTRAINT bp_c_lib_key CHECK
   ((lib_key IS NOT NULL AND vb_key  IS NULL AND ba_access IN ('T', 'R')) OR
    (lib_key IS NULL     AND ba_access IN ('D', 'L', 'U'))),
CONSTRAINT bp_c_status CHECK (status in ('A','U','D','X')),
CONSTRAINT bp_c_concur CHECK (concur in ('Y','N')),
CONSTRAINT bp_c_purged CHECK
   ((purged in ('Y','N') AND status  = 'D' AND ba_access != 'U') OR
    (purged = 'N'        AND status != 'D' AND ba_access != 'U') OR
    (purged = 'U'        AND ba_access = 'U')),
CONSTRAINT bp_c_copyno CHECK (copy# > 0 AND copy# <= 256)
) &tablespace&
>>>
 
define bp_i_device_handle_status
<<<
CREATE INDEX bp_i_device_handle_status on bp(handle_hashkey, status)
&tablespace&
>>>
 
define bp_i_2
<<<
CREATE INDEX bp_i_2 on bp(db_key, bp_recid, bp_stamp)
&tablespace&
>>>
 
define bp_i_3
<<<
CREATE INDEX bp_i_3 on bp(db_key, bs_key)
&tablespace&
>>>
 
define bp_i_site_bs_key
<<<
CREATE INDEX bp_i_site_bs_key on bp(site_key,bs_key)
&tablespace&
>>>
 
define bp_i_pdb_key
<<<
CREATE INDEX fc$bp_i_pdb_key on bp(pdb_key) COMPRESS 1
&tablespace&
>>>
 
 
define bcf
<<<
CREATE TABLE bcf
(
bcf_key         NUMBER NOT NULL,
bs_key          NUMBER NOT NULL,        -- backup set
dbinc_key       NUMBER NOT NULL,        -- database incarnation
bcf_recid       NUMBER NOT NULL,        -- recid from control file
bcf_stamp       NUMBER NOT NULL,        -- stamp from control file
ckp_scn         NUMBER NOT NULL,        -- controlfile checkpoint SCN
ckp_time        DATE NOT NULL,          -- controlfile checkpoint time
create_time     DATE NOT NULL,          -- controlfile creation time
min_offr_recid  NUMBER NOT NULL,        -- recid of the oldest offline range
block_size      NUMBER NOT NULL,        -- blocksize
controlfile_type VARCHAR2(1),           -- 'B' -> backup controlfile
--
blocks          NUMBER,                 -- # blocks
autobackup_date DATE,                   -- controlfile autobackup date
autobackup_sequence NUMBER,             -- controlfile autobackup sequence
pdb_key         NUMBER NOT NULL,
CONSTRAINT bcf_p  PRIMARY KEY (bcf_key),
CONSTRAINT bcf_u2 UNIQUE (bs_key),
CONSTRAINT bcf_f1 FOREIGN KEY (bs_key)
  REFERENCES bs ON DELETE CASCADE,
CONSTRAINT bcf_f2 FOREIGN KEY (pdb_key)
  REFERENCES pdb,
CONSTRAINT bcf_f3 FOREIGN KEY (dbinc_key) 
  REFERENCES dbinc ON DELETE CASCADE,
CONSTRAINT bcf_c_cf_type CHECK (controlfile_type in ('S','B'))
) &tablespace&
>>>
 
define bcf_i_dbinc 
<<< 
CREATE INDEX bcf_i_dbinc on bcf(dbinc_key) &tablespace& 
>>>
 
define bcf_i_pdb_key
<<<
CREATE INDEX fc$bcf_i_pdb_key on bcf(pdb_key) COMPRESS 1
&tablespace&
>>>
 
 
define ccf
<<<
CREATE TABLE ccf
(
ccf_key         NUMBER NOT NULL,
dbinc_key       NUMBER NOT NULL,        -- database incarnation
ccf_recid       NUMBER NOT NULL,        -- recid from control file
ccf_stamp       NUMBER NOT NULL,        -- stamp from control file
fname           VARCHAR2(1024) NOT NULL, -- cf copy file name
fname_hashkey   VARCHAR2(20) NOT NULL,  -- hashed fname for indexing
tag             VARCHAR2(32),           -- cf copy tag
ckp_scn         NUMBER NOT NULL,        -- controlfile checkpoint SCN
ckp_time        DATE NOT NULL,          -- controlfile checkpoint time
create_time     DATE NOT NULL,          -- controlfile creation time
min_offr_recid  NUMBER NOT NULL,        -- recid of the oldest offline range
blocks          NUMBER DEFAULT NULL,    -- number of blocks
block_size      NUMBER NOT NULL,        -- blocksize
completion_time DATE NOT NULL,          -- time that the copy was taken
controlfile_type VARCHAR2(1),           -- 'B' -> backup controlfile
--
--
status          VARCHAR2(1) NOT NULL,
keep_options  NUMBER DEFAULT 0 NOT NULL,-- if backup is done with keep option
--
--
--
--
keep_until      DATE,                   -- valid only if keep_options != 0
--
is_recovery_dest_file VARCHAR2(3) DEFAULT 'NO' NOT NULL,
--
rsr_key         NUMBER,                 -- key of the row in the rsr table
site_key        NUMBER,                 -- Null when cfcopy owner is unknown
pdb_key         NUMBER NOT NULL,
CONSTRAINT ccf_p  PRIMARY KEY (ccf_key),
CONSTRAINT ccf_f1 FOREIGN KEY (dbinc_key) REFERENCES dbinc ON DELETE CASCADE,
CONSTRAINT ccf_f2 FOREIGN KEY (site_key) REFERENCES node,
CONSTRAINT ccf_f3 FOREIGN KEY (pdb_key)  REFERENCES pdb,
CONSTRAINT ccf_u1 UNIQUE (dbinc_key, ccf_recid, ccf_stamp),
CONSTRAINT ccf_c_status CHECK (status in ('A','U','D','X')),
CONSTRAINT ccf_c_cf_type CHECK (controlfile_type in ('S','B'))
) &tablespace&
>>>
 
define ccf_i_fname_status
<<<
CREATE INDEX ccf_i_fname_status on ccf(fname_hashkey, status) &tablespace&
>>>
 
define ccf_i_site_key
<<<
CREATE INDEX fc$ccf_i_site_key on ccf(site_key) COMPRESS 1
&tablespace&
>>>
 
define ccf_i_pdb_key
<<<
CREATE INDEX fc$ccf_i_pdb_key on ccf(pdb_key) COMPRESS 1
&tablespace&
>>>
 
 
define xcf
<<<
CREATE TABLE xcf
(
xcf_key         NUMBER NOT NULL,
dbinc_key       NUMBER NOT NULL,        -- database incarnation
xcf_recid       NUMBER NOT NULL,        -- recid from control file
xcf_stamp       NUMBER NOT NULL,        -- stamp from control file
tag             VARCHAR2(32),           -- cf copy tag
ckp_scn         NUMBER NOT NULL,        -- controlfile checkpoint SCN
ckp_time        DATE NOT NULL,          -- controlfile checkpoint time
create_time     DATE NOT NULL,          -- controlfile creation time
min_offr_recid  NUMBER NOT NULL,        -- recid of the oldest offline range
blocks          NUMBER DEFAULT NULL,    -- number of blocks in file
block_size      NUMBER NOT NULL,        -- blocksize
device_type     VARCHAR2(255) NOT NULL, -- 'DISK' -> on disk rather than seq
handle          VARCHAR2(1024) NOT NULL, -- backup piece handle
handle_hashkey  VARCHAR2(30) NOT NULL,  -- indexed hashkey on handle
comments        VARCHAR2(255),          --
media           VARCHAR2(80),           -- media handle
media_pool      NUMBER,                 -- media pool
start_time      DATE NOT NULL,          -- time when this piece started
completion_time DATE NOT NULL,          -- time when this piece completed
controlfile_type VARCHAR2(1),           -- 'B' -> backup controlfile
--
--
status          VARCHAR2(1) NOT NULL,
keep_options  NUMBER DEFAULT 0 NOT NULL,-- if backup is done with keep option
--
--
--
--
keep_until      DATE,                   -- valid only if keep_options != 0
--
rsr_key         NUMBER,                 -- key of the row in the rsr table
site_key        NUMBER,                 -- Null when proxycopy owner is unknown
pdb_key         NUMBER NOT NULL,
CONSTRAINT xcf_p  PRIMARY KEY (xcf_key),
CONSTRAINT xcf_f1 FOREIGN KEY (dbinc_key) REFERENCES dbinc ON DELETE CASCADE,
CONSTRAINT xcf_f2 FOREIGN KEY (site_key) REFERENCES node,
CONSTRAINT xcf_f3 FOREIGN KEY (pdb_key)  REFERENCES pdb,
CONSTRAINT xcf_u1 UNIQUE (dbinc_key, xcf_recid, xcf_stamp),
CONSTRAINT xcf_c_status CHECK (status in ('A','U','D','X')),
CONSTRAINT xcf_c_cf_type CHECK (controlfile_type in ('S','B'))
) &tablespace&
>>>
 
define xcf_i_handle_status
<<<
CREATE INDEX xcf_i_handle_status on xcf(handle_hashkey, status) &tablespace&
>>>
 
define xcf_i_pdb_key
<<<
CREATE INDEX fc$xcf_i_pdb_key on xcf(pdb_key) COMPRESS 1
&tablespace&
>>>
 
 
define bsf
<<<
CREATE TABLE bsf
(
bsf_key           NUMBER NOT NULL,
bs_key            NUMBER NOT NULL,        -- backup set
db_key            NUMBER NOT NULL,        -- database to which this SPFILE
--
db_unique_name    VARCHAR2(30),           -- Instance site name
--
bsf_recid         NUMBER NOT NULL,        -- recid from control file
bsf_stamp         NUMBER NOT NULL,        -- stamp from control file
modification_time DATE   NOT NULL,        -- SPFILE modification time
bytes             NUMBER NOT NULL,        -- size of SPFILE in bytes
pdb_key           NUMBER NOT NULL,
CONSTRAINT bsf_p  PRIMARY KEY (bsf_key),
CONSTRAINT bsf_u2 UNIQUE (bs_key),
CONSTRAINT bsf_f1 FOREIGN KEY (bs_key)
  REFERENCES bs ON DELETE CASCADE,
CONSTRAINT bsf_f2 FOREIGN KEY (pdb_key)
  REFERENCES pdb
) &tablespace&
>>>
 
define bsf_i_bs_key
<<<
CREATE INDEX bsf_i_bs_key on bsf(bs_key)
&tablespace&
>>>
 
define bsf_i_pdb_key
<<<
CREATE INDEX fc$bsf_i_pdb_key on bsf(pdb_key) COMPRESS 1
&tablespace&
>>>
 
 
define bdf
<<<
CREATE TABLE bdf
(
bdf_key              NUMBER NOT NULL,   -- primary key
dbinc_key            NUMBER NOT NULL,   -- database incarnation
bdf_recid            NUMBER NOT NULL,   -- bdf recid from control file
bdf_stamp            NUMBER NOT NULL,   -- bdf stamp from control file
bs_key               NUMBER NOT NULL,   -- backup set, null if copy
file#                NUMBER NOT NULL,   -- database file number
create_scn           NUMBER NOT NULL,   -- creation SCN
create_time          DATE  DEFAULT NULL,-- creation time
incr_level           NUMBER,            -- incremental backup level (null,0-4)
incr_scn             NUMBER NOT NULL,   -- scn since backup contains changes
ckp_scn              NUMBER NOT NULL,   -- scn of the last datafile ckpt
ckp_time             DATE NOT NULL,     -- time of the last datafile ckpt
abs_fuzzy_scn        NUMBER,            -- absolute fuzzy scn
rcv_fuzzy_scn        NUMBER,            -- media recovery fuzzy scn
rcv_fuzzy_time       DATE,              -- timestamp for media rcv fuzzy scn
datafile_blocks      NUMBER NOT NULL,   -- number of blocks in datafile
blocks               NUMBER NOT NULL,   -- number of blocks written to backup
block_size           NUMBER NOT NULL,   -- blocksize
completion_time      DATE,              -- completion time (null for 8.0.2)
blocks_read          NUMBER NOT NULL,   -- number of blocks read for backup
marked_corrupt       NUMBER DEFAULT NULL,
--
used_chg_track       VARCHAR2(1) DEFAULT 'N',
--
used_optim           VARCHAR2(1) DEFAULT 'N',
--
foreign_dbid         NUMBER      DEFAULT 0 NOT NULL,
plugged_readonly     VARCHAR2(3) DEFAULT 'NO' NOT NULL,
plugin_scn           NUMBER      DEFAULT 0 NOT NULL,
plugin_reset_scn     NUMBER      DEFAULT 0 NOT NULL,
plugin_reset_time    DATE,
section_size         NUMBER,
pdb_key              NUMBER NOT NULL,
sparse_backup        VARCHAR2(3) DEFAULT 'NO' NOT NULL,
CONSTRAINT bdf_p  PRIMARY KEY (bdf_key),
CONSTRAINT bdf_u2 UNIQUE (bs_key, file#),
CONSTRAINT bdf_f1 FOREIGN KEY (bs_key)
  REFERENCES bs ON DELETE CASCADE,
CONSTRAINT bdf_f2 FOREIGN KEY (pdb_key)
  REFERENCES pdb,
CONSTRAINT bdf_f3 FOREIGN KEY (dbinc_key)
  REFERENCES dbinc ON DELETE CASCADE,
CONSTRAINT bdf_c_sparse_backup CHECK (sparse_backup in ('YES', 'NO'))
) &tablespace&
>>>
 
define bdf_i_bs_key
<<<
CREATE INDEX bdf_i_bs_key on bdf(bs_key) &tablespace&
>>>
 
define bdf_i_df_key
<<<
CREATE INDEX bdf_i_df_key on bdf(dbinc_key, file#, create_scn) &tablespace&
>>>
 
define bdf_i_pdb_key
<<<
CREATE INDEX fc$bdf_i_pdb_key on bdf(pdb_key) COMPRESS 1
&tablespace&
>>>
 
 
define cdf
<<<
CREATE TABLE cdf
(
cdf_key               NUMBER NOT NULL,  -- primary key
dbinc_key             NUMBER NOT NULL,  -- database incarnation
cdf_recid             NUMBER NOT NULL,  -- df copy recid from control file
cdf_stamp             NUMBER NOT NULL,  -- df copy stamp from control file
file#                 NUMBER NOT NULL,  -- database file number
create_scn            NUMBER NOT NULL,  -- creation SCN
create_time           DATE DEFAULT NULL,-- timestamp when datafile was created
fname                 VARCHAR2(1024) NOT NULL,
--
fname_hashkey         VARCHAR2(20) NOT NULL,
--
tag                   VARCHAR2(32),     -- df copy tag
incr_level            NUMBER,           -- incremental backup level (null or 0)
ckp_scn               NUMBER NOT NULL,  -- scn of the last datafile ckpt
ckp_time              DATE NOT NULL,    -- time of the last datafile ckpt
onl_fuzzy             VARCHAR2(1) NOT NULL,
--
bck_fuzzy             VARCHAR2(1) NOT NULL,
--
abs_fuzzy_scn         NUMBER,          -- absolute fuzzy scn, if known.
--
rcv_fuzzy_scn         NUMBER,          -- media recovery fuzzy scn
rcv_fuzzy_time        DATE,            -- timestamp for media rcv fuzzy scn
blocks                NUMBER NOT NULL, -- number of blocks
block_size            NUMBER NOT NULL, -- blocksize
completion_time       DATE NOT NULL,   -- time when this copy completed
--
status                VARCHAR2(1) NOT NULL,
keep_options          NUMBER DEFAULT 0 NOT NULL,
--
--
--
--
--
keep_until            DATE,            -- valid only if keep_options != 0
--
scanned               VARCHAR2(1) DEFAULT 'N' NOT NULL,
--
is_recovery_dest_file VARCHAR2(3) DEFAULT 'NO' NOT NULL,
--
rsr_key               NUMBER,          -- key of the row in the rsr table
marked_corrupt        NUMBER DEFAULT NULL,
--
site_key              NUMBER,          -- Null when dfcopy owner is unknown
foreign_dbid          NUMBER      DEFAULT 0 NOT NULL,
plugged_readonly      VARCHAR2(3) DEFAULT 'NO' NOT NULL,
plugin_scn            NUMBER      DEFAULT 0 NOT NULL,
plugin_reset_scn      NUMBER      DEFAULT 0 NOT NULL,
plugin_reset_time     DATE,
pdb_key               NUMBER NOT NULL,
sparse_backup         VARCHAR2(3) DEFAULT 'NO' NOT NULL,
CONSTRAINT cdf_p  PRIMARY KEY (cdf_key),
CONSTRAINT cdf_u1 UNIQUE (dbinc_key, cdf_recid, cdf_stamp),
CONSTRAINT cdf_f1 FOREIGN KEY (dbinc_key) REFERENCES dbinc ON DELETE CASCADE,
--
--
--
--
CONSTRAINT cdf_f3 FOREIGN KEY (site_key) REFERENCES node,
CONSTRAINT cdf_f4 FOREIGN KEY (pdb_key)  REFERENCES pdb,
CONSTRAINT cdf_c_status CHECK (status in ('A','U','D','X','F')),
CONSTRAINT cdf_c_onl_fuzzy CHECK (onl_fuzzy in ('Y','N')),
CONSTRAINT cdf_c_bck_fuzzy CHECK (bck_fuzzy in ('Y','N')),
CONSTRAINT cdf_c_sparse_backup CHECK (sparse_backup in ('YES', 'NO'))
) &tablespace&
>>>
 
define cdf_i_df_key
<<<
CREATE INDEX cdf_i_df_key on cdf(dbinc_key, file#, create_scn) &tablespace&
>>>
 
define cdf_i_fname_status
<<<
CREATE INDEX cdf_i_fname_status on cdf(fname_hashkey, status) &tablespace&
>>>
 
define cdf_i_site_key
<<<
CREATE INDEX fc$cdf_i_site_key on cdf(site_key) COMPRESS 1
&tablespace&
>>>
 
define cdf_i_pdb_key
<<<
CREATE INDEX fc$cdf_i_pdb_key on cdf(pdb_key) COMPRESS 1
&tablespace&
>>>
 
 
define xdf
<<<
CREATE TABLE xdf
(
xdf_key              NUMBER NOT NULL,  -- primary key
dbinc_key            NUMBER NOT NULL,  -- database incarnation
xdf_recid            NUMBER NOT NULL,  -- x$kccpd recid from control file
xdf_stamp            NUMBER NOT NULL,  -- x$kccpd stamp from control file
file#                NUMBER NOT NULL,  -- database file number
create_scn           NUMBER NOT NULL,  -- creation SCN
create_time          DATE DEFAULT NULL,-- creation time
tag                  VARCHAR2(32),     -- df copy tag
incr_level           NUMBER,           -- incremental backup level (null or 0)
ckp_scn              NUMBER NOT NULL,  -- scn of the last datafile ckpt
ckp_time             DATE NOT NULL,    -- time of the last datafile ckpt
onl_fuzzy            VARCHAR2(1) NOT NULL,
--
bck_fuzzy            VARCHAR2(1) NOT NULL,
--
abs_fuzzy_scn        NUMBER,           -- absolute fuzzy scn, if known.
--
rcv_fuzzy_scn        NUMBER,           -- media recovery fuzzy scn
rcv_fuzzy_time       DATE,             -- timestamp for media rcv fuzzy scn
blocks               NUMBER NOT NULL,  -- number of blocks
block_size           NUMBER NOT NULL,  -- blocksize
device_type          VARCHAR2(255) NOT NULL, 
--
handle               VARCHAR2(1024) NOT NULL,
--
handle_hashkey       VARCHAR2(30) NOT NULL,
--
comments             VARCHAR2(255),    --
media                VARCHAR2(80),     -- media handle
media_pool           NUMBER,           -- media pool
start_time           DATE NOT NULL,    -- time when this piece started
completion_time      DATE NOT NULL,    -- time when this piece completed
--
status               VARCHAR2(1) NOT NULL,
keep_options         NUMBER DEFAULT 0 NOT NULL,
--
--
--
--
--
keep_until           DATE,             -- valid only if keep_options != 0
--
rsr_key              NUMBER,           -- key of the row in the rsr table
site_key             NUMBER,           -- Null when proxycopy owner is unknown
foreign_dbid         NUMBER      DEFAULT 0 NOT NULL,
plugged_readonly     VARCHAR2(3) DEFAULT 'NO' NOT NULL,
plugin_scn           NUMBER      DEFAULT 0 NOT NULL,
plugin_reset_scn     NUMBER      DEFAULT 0 NOT NULL,
plugin_reset_time    DATE,
pdb_key              NUMBER NOT NULL,
CONSTRAINT xdf_p  PRIMARY KEY (xdf_key),
CONSTRAINT xdf_u1 UNIQUE (dbinc_key, xdf_recid, xdf_stamp),
CONSTRAINT xdf_f1 FOREIGN KEY (dbinc_key) REFERENCES dbinc ON DELETE CASCADE,
--
--
--
--
CONSTRAINT xdf_f3 FOREIGN KEY (site_key) REFERENCES node,
CONSTRAINT xdf_f4 FOREIGN KEY (pdb_key)  REFERENCES pdb,
CONSTRAINT xdf_c_status CHECK (status in ('A','U','D','X')),
CONSTRAINT xdf_c_onl_fuzzy CHECK (onl_fuzzy in ('Y','N')),
CONSTRAINT xdf_c_bck_fuzzy CHECK (bck_fuzzy in ('Y','N'))
) &tablespace&
>>>
 
define xdf_i_df_key
<<<
CREATE INDEX xdf_i_df_key on xdf(dbinc_key, file#, create_scn) &tablespace&
>>>
 
define xdf_i_handle_status
<<<
CREATE INDEX xdf_i_handle_status on xdf(handle_hashkey, status) &tablespace&
>>>
 
define xdf_i_site_key
<<<
CREATE INDEX fc$xdf_i_site_key on xdf(site_key) COMPRESS 1
&tablespace&
>>>
 
define xdf_i_pdb_key
<<<
CREATE INDEX fc$xdf_i_pdb_key on xdf(pdb_key) COMPRESS 1
&tablespace&
>>>
 
 
define xal
<<<
CREATE TABLE xal
(
xal_key         NUMBER NOT NULL,        -- primary key
dbinc_key       NUMBER NOT NULL,        -- database incarnation
xal_recid       NUMBER NOT NULL,        -- x$kccpa recid from control file
xal_stamp       NUMBER NOT NULL,        -- x$kccpa stamp from control file
tag             VARCHAR2(32),           -- al copy tag
thread#         NUMBER NOT NULL,        -- thread number
sequence#       NUMBER NOT NULL,        -- log sequence number
low_scn         NUMBER NOT NULL,        -- scn generated when switching in
low_time        DATE   NOT NULL,        -- time low SCN allocated
next_scn        NUMBER NOT NULL,        -- scn generated when switching out
next_time       DATE NOT NULL,          -- time when next SCN allocated
blocks          NUMBER NOT NULL,        -- number of blocks written to backup
block_size      NUMBER NOT NULL,        -- size of a block in bytes
device_type     VARCHAR2(255) NOT NULL, -- 'DISK' -> on disk rather than seq
handle          VARCHAR2(1024) NOT NULL,-- backup piece handle
handle_hashkey  VARCHAR2(30) NOT NULL,  -- indexed hashkey on handle
comments        VARCHAR2(255),          --
media           VARCHAR2(80),           -- media handle
media_pool      NUMBER,                 -- media pool
start_time      DATE NOT NULL,          -- time when this piece started
completion_time DATE NOT NULL,          -- time when this piece completed
rsr_key         NUMBER,                 -- key of the row in the rsr table
terminal        VARCHAR2(3) DEFAULT 'NO',  -- 'YES' for terminal rcv log
keep_options    NUMBER DEFAULT 0 NOT NULL,
--
--
--
--
--
keep_until       DATE,                 -- valid only if keep_options != 0
--
--
status          VARCHAR2(1) NOT NULL,
site_key        NUMBER,                 -- Null when proxycopy owner is unknown
CONSTRAINT xal_p  PRIMARY KEY (xal_key),
CONSTRAINT xal_u1 UNIQUE (dbinc_key, xal_recid, xal_stamp),
CONSTRAINT xal_f1 FOREIGN KEY (dbinc_key) REFERENCES dbinc ON DELETE CASCADE,
CONSTRAINT xal_f2 FOREIGN KEY (site_key) REFERENCES node,
CONSTRAINT xal_c_status CHECK (status in ('A','U','D','X'))
) &tablespace&
>>>
 
define xal_i_al_key
<<<
CREATE INDEX xal_i_al_key on xal(dbinc_key, thread#, sequence#) &tablespace&
>>>
 
define xal_i_handle_status
<<<
CREATE INDEX xal_i_handle_status on xal(handle_hashkey, status) &tablespace&
>>>
 
define xal_i_site_key
<<<
CREATE INDEX fc$xal_i_site_key on xal(site_key) COMPRESS 1
&tablespace&
>>>
 
 
define brl
<<<
CREATE TABLE brl
(
brl_key         NUMBER NOT NULL,
dbinc_key       NUMBER NOT NULL,        -- database incarnation
brl_recid       NUMBER NOT NULL,        -- recid from control file
brl_stamp       NUMBER NOT NULL,        -- stamp from control file
bs_key          NUMBER NOT NULL,        -- backup set key
thread#         NUMBER NOT NULL,        -- thread number
sequence#       NUMBER NOT NULL,        -- log sequence number
low_scn         NUMBER NOT NULL,        -- scn generated when switching in
low_time        DATE   NOT NULL,        -- time low SCN allocated
next_scn        NUMBER NOT NULL,        -- scn generated when switching out
next_time       DATE NOT NULL,          -- time when next SCN allocated
blocks          NUMBER NOT NULL,        -- number of blocks written to backup
block_size      NUMBER NOT NULL,        -- size of a block in bytes
terminal        VARCHAR2(3) DEFAULT 'NO',  -- 'YES' for terminal rcv log
activation      VARCHAR2(1),            -- 'Y' for activation log, NULL = N
CONSTRAINT brl_p  PRIMARY KEY (brl_key),
CONSTRAINT brl_u2 UNIQUE (bs_key, thread#, sequence#),
CONSTRAINT brl_f1 FOREIGN KEY (bs_key)
  REFERENCES bs ON DELETE CASCADE
) &tablespace&
>>>
 
define brl_i_bs_key
<<<
CREATE INDEX brl_i_bs_key on brl(bs_key) &tablespace&
>>>
 
define brl_i_dts
<<<
CREATE INDEX brl_i_dts on brl(dbinc_key, thread#, sequence#) &tablespace&
>>>
 
define brl_i_act
<<<
CREATE INDEX brl_i_act
     ON brl (NVL2(activation, dbinc_key, NULL)) COMPRESS 1 &tablespace&
>>>
 
 
 
define bcb
<<<
CREATE TABLE bcb
(
bdf_key         NUMBER NOT NULL,        -- datafile backup or copy
bcb_recid       NUMBER NOT NULL,        -- recid from control file
bcb_stamp       NUMBER NOT NULL,        -- stamp from control file
piece#          NUMBER NOT NULL,        -- backup piece to which block belongs
block#          NUMBER NOT NULL,        -- starting block number in the file
blocks          NUMBER NOT NULL,        -- block count in corrupt range
corrupt_scn     NUMBER,                 -- scn at which corruption was detected
marked_corrupt  VARCHAR2(1) NOT NULL,   -- 'Y' -> could not read from disk
corruption_type VARCHAR2(9),
CONSTRAINT bcb_u1 UNIQUE (bdf_key, bcb_recid, bcb_stamp),
CONSTRAINT bcb_f1 FOREIGN KEY (bdf_key)
  REFERENCES bdf ON DELETE CASCADE
) &tablespace&
>>>
 
 
define ccb
<<<
CREATE TABLE ccb
(
cdf_key         NUMBER NOT NULL,        -- datafile copy
ccb_recid       NUMBER NOT NULL,        -- recid from control file
ccb_stamp       NUMBER NOT NULL,        -- stamp from control file
block#          NUMBER NOT NULL,        -- block number in the file
blocks          NUMBER NOT NULL,        -- block count in corrupt range
corrupt_scn     NUMBER,                 -- scn at which corruption was detected
marked_corrupt  VARCHAR2(1) NOT NULL,   -- 'Y' -> could not read from disk
corruption_type VARCHAR2(9),
CONSTRAINT ccb_u1 UNIQUE (cdf_key, ccb_recid, ccb_stamp),
CONSTRAINT ccb_f1 FOREIGN KEY (cdf_key)
  REFERENCES cdf ON DELETE CASCADE
) &tablespace&
>>>
 
 
define rsr
<<<
CREATE TABLE rsr
(
rsr_key         NUMBER NOT NULL,
dbinc_key       NUMBER NOT NULL,        -- database incarnation
rsr_recid       NUMBER NOT NULL,        -- recid from control file
rsr_stamp       NUMBER NOT NULL,        -- stamp from control file
rsr_pkey        NUMBER,                 -- key of the parent, NULL if no
rsr_l0key       NUMBER,                 -- key of the level 0, NULL if no
rsr_level       NUMBER,                 -- level
rsr_type        VARCHAR2(33),           -- row type
rsr_oper        VARCHAR2(33),           -- operation
rsr_cmdid       VARCHAR2(33),           -- command id
rsr_status      VARCHAR2(33),           -- status
rsr_mbytes      NUMBER NOT NULL,        -- megabytes
rsr_start       DATE NOT NULL,          -- start time
rsr_end         DATE,                   -- end time
rsr_ibytes      NUMBER,                 -- input megabytes processed
rsr_obytes      NUMBER,                 -- output megabytes produced
rsr_optimized   VARCHAR2(3),            -- was optimization applied
rsr_otype       VARCHAR2(80),           -- input object types involved in oper
rsr_srecid      NUMBER,                 -- session recid
rsr_sstamp      NUMBER,                 -- session stamp
rsr_odevtype    VARCHAR2(17),           -- output device type
site_key        NUMBER,                 -- Null when rman job owner is unknown
rsr_osb_allocated VARCHAR2(1),          -- 'Y' when OSB is allocated
CONSTRAINT rsr_key  PRIMARY KEY(rsr_key),
CONSTRAINT rsr_u2 UNIQUE (dbinc_key, rsr_recid, rsr_stamp, site_key),
CONSTRAINT rsr_f1 FOREIGN KEY(dbinc_key) REFERENCES dbinc ON DELETE CASCADE,
CONSTRAINT rsr_f2 FOREIGN KEY (site_key) REFERENCES node ON DELETE CASCADE
) &tablespace&
>>>
 
define rsr_i_site_key
<<<
CREATE INDEX fc$rsr_i_site_key on rsr(site_key) COMPRESS 1
&tablespace&
>>>
 
 
define scr
<<<
CREATE TABLE scr
(
scr_key         NUMBER NOT NULL,        -- sequence generated primary key
db_key          NUMBER,                 -- database that owns this script,
--
scr_name        VARCHAR2(100) NOT NULL, -- script name
scr_comment     VARCHAR2(255),          -- comment for script
CONSTRAINT scr_p  PRIMARY KEY(scr_key),
CONSTRAINT scr_f1 FOREIGN KEY(db_key)
  REFERENCES db ON DELETE CASCADE,
CONSTRAINT scr_u1 UNIQUE(db_key, scr_name)
) &tablespace&
>>>
 
define scr_trigger
<<<
create or replace trigger scr_trigger before insert or update or delete 
on scr for each row
declare
  global_script boolean;
begin
  if inserting then
    global_script := :new.db_key is null;
  elsif updating then
    global_script := :old.db_key is null or :new.db_key is null;
  elsif deleting then
    global_script := :old.db_key is null;
  end if;
 
  if not global_script or dbms_catowner = user then return; end if;
 
  raise_application_error(num=>-20016,
           msg=>'virtual private catalog user cannot modify global scripts');
end;
>>>
 
 
define scrl
<<<
CREATE TABLE scrl
(
scr_key         NUMBER NOT NULL,        -- script that owns this line
db_key          NUMBER,                 -- database that owns this script
linenum         NUMBER NOT NULL,        -- line number
text            VARCHAR2(1024) NOT NULL,-- text of the line
CONSTRAINT scrl_u1 UNIQUE(scr_key, linenum),
CONSTRAINT scrl_f1 FOREIGN KEY(scr_key)
  REFERENCES scr ON DELETE CASCADE
) &tablespace&
>>>
 
define scrl_trigger
<<<
create or replace trigger scrl_trigger before insert or update or delete 
on scrl for each row
declare
  dbkey number;
begin
  if inserting then
    select db_key into dbkey from scr where scr_key = :new.scr_key;
    :new.db_key := dbkey;
  end if;
 
  if dbms_catowner = user then return; end if;
 
  if updating then
    dbkey := :new.db_key;
    if :old.db_key <> :new.db_key then
      raise_application_error(num=>-20017,
                              msg=>'illegal script update operation');
    end if;
  elsif deleting then
    dbkey := :old.db_key;
  end if;
 
  if dbkey is not null then return; end if;
 
  raise_application_error(num=>-20016,
           msg=>'virtual private catalog user cannot modify global scripts');
end;
>>>
 
define rout
<<<
CREATE TABLE rout
(
db_key          NUMBER NOT NULL,        -- database output belongs to
rsr_key         NUMBER NOT NULL,        -- command that generated the output
rout_skey       NUMBER NOT NULL,        -- session that created the output
rout_recid      NUMBER NOT NULL,        -- record id from server
rout_stamp      NUMBER NOT NULL,        -- timestamp when row was added
site_key        NUMBER,                 -- sitekey
rout_text       VARCHAR2(130) NOT NULL, -- RMAN output
CONSTRAINT rout_u1 UNIQUE(db_key, rout_skey, rsr_key, rout_recid, rout_stamp),
CONSTRAINT rout_f1 FOREIGN KEY(db_key)
  REFERENCES db ON DELETE CASCADE,
CONSTRAINT rout_f2 FOREIGN KEY(rsr_key)
  REFERENCES rsr ON DELETE CASCADE,
CONSTRAINT rout_f3 FOREIGN KEY(site_key)
  REFERENCES node ON DELETE CASCADE
) &tablespace&
>>>
 
define config
<<<
CREATE TABLE config
(
name            VARCHAR2(30),           -- name of configuration option
value           VARCHAR2(100),          -- value of configuration option
CONSTRAINT config_p PRIMARY KEY (name)
)
ORGANIZATION INDEX
&tablespace&
>>>
 
define fb
<<<
CREATE TABLE fb
(
dbinc_key                NUMBER NOT NULL,
db_unique_name           VARCHAR2(512) NOT NULL,    -- Instance site name
oldest_flashback_scn     NUMBER,                    -- guaranteed flashback scn
oldest_flashback_time    DATE DEFAULT NULL,         -- flashback target time
CONSTRAINT fb_u1 UNIQUE(dbinc_key, db_unique_name),
CONSTRAINT fb_f1 FOREIGN KEY(dbinc_key)
  REFERENCES dbinc ON DELETE CASCADE
) &tablespace&
>>>
 
define grsp
<<<
CREATE TABLE grsp
(
dbinc_key                NUMBER NOT NULL,
site_key                 NUMBER,
rspname                  VARCHAR2(128) NOT NULL,
creation_time            DATE DEFAULT NULL,
rsptime                  DATE DEFAULT NULL,
from_scn                 NUMBER,
to_scn                   NUMBER,
guaranteed               VARCHAR2(3) DEFAULT 'YES',
pdb_key                  NUMBER NOT NULL,
clean                    VARCHAR2(3) DEFAULT 'NO',
CONSTRAINT grsp_u2 FOREIGN KEY(dbinc_key)
  REFERENCES dbinc ON DELETE CASCADE,
CONSTRAINT grsp_u3 FOREIGN KEY (site_key)
  REFERENCES node ON DELETE CASCADE,
CONSTRAINT grsp_u4 UNIQUE(site_key, rspname, pdb_key),
CONSTRAINT grsp_f1 FOREIGN KEY (pdb_key) REFERENCES pdb ON DELETE CASCADE,
CONSTRAINT grsp_c1 CHECK (clean IN ('YES','NO'))
) &tablespace&
>>>
 
define grsp_i_pdb_key
<<<
CREATE INDEX fc$grsp_i_pdb_key on grsp(pdb_key) COMPRESS 1
&tablespace&
>>>
 
define grsp_i_dbinc_key
<<<
CREATE INDEX fc$grsp_i_dbinc_key on grsp(dbinc_key) COMPRESS 1
&tablespace&
>>>
 
define nrsp
<<<
CREATE TABLE nrsp
(
nrsp_recid               NUMBER NOT NULL,
nrsp_stamp               NUMBER NOT NULL,
dbinc_key                NUMBER NOT NULL,
site_key                 NUMBER,
rspname                  VARCHAR2(128) NOT NULL,
creation_time            DATE DEFAULT NULL,
rsptime                  DATE DEFAULT NULL,
to_scn                   NUMBER,
long_term                VARCHAR2(3),
pdb_key                  NUMBER NOT NULL,
clean                    VARCHAR2(3) DEFAULT 'NO',
CONSTRAINT nrsp_u1 UNIQUE (dbinc_key, nrsp_recid, nrsp_stamp, site_key),
CONSTRAINT nrsp_f1 FOREIGN KEY(dbinc_key)
  REFERENCES dbinc ON DELETE CASCADE,
CONSTRAINT nrsp_f2 FOREIGN KEY (site_key)
  REFERENCES node ON DELETE CASCADE,
CONSTRAINT nrsp_u2 UNIQUE(site_key, rspname, pdb_key),
CONSTRAINT nrsp_f3 FOREIGN KEY (pdb_key) REFERENCES pdb ON DELETE CASCADE,
CONSTRAINT nrsp_c1 CHECK (clean IN ('YES','NO'))
) &tablespace&
>>>
 
define nrsp_i_pdb_key
<<<
CREATE INDEX fc$nrsp_i_pdb_key on nrsp(pdb_key) COMPRESS 1
&tablespace&
>>>
 
define bcr
<<<
CREATE TABLE bcr
(
bcr_recid       NUMBER NOT NULL,        -- recid from control file
bcr_stamp       NUMBER NOT NULL,        -- stamp from control file
df_key          NUMBER NOT NULL,        -- df_key in df table
site_key        NUMBER NOT NULL,        -- which db_unique_name it contains
block#          NUMBER NOT NULL,        -- block number in the file
blocks          NUMBER NOT NULL,        -- block count in corrupt range
corrupt_scn     NUMBER,                 -- scn at which corruption was
corruption_type VARCHAR2(9),
CONSTRAINT bcr_p  PRIMARY KEY (bcr_recid, bcr_stamp, site_key),
CONSTRAINT bcr_f1 FOREIGN KEY (site_key)
  REFERENCES node ON DELETE CASCADE,
CONSTRAINT bcr_f2 FOREIGN KEY (df_key, site_key)
  REFERENCES site_dfatt ON DELETE CASCADE,
CONSTRAINT bcr_c_blocks CHECK (blocks != 0)
) &tablespace&
>>>
 
define bcr_i_site_key
<<<
CREATE INDEX fc$bcr_i_site_key on bcr(site_key) COMPRESS 1
&tablespace&
>>>
 
define bcr_i_df_site_key
<<<
CREATE INDEX fc$bcr_i_df_site_key on bcr(df_key, site_key) COMPRESS 1
&tablespace&
>>>
 
define vpc_users
<<<
CREATE TABLE vpc_users
(
filter_user VARCHAR2(128) NOT NULL,  -- Name of user who has access
filter_uid  NUMBER constraint vpc_users_uid_nn NOT NULL, -- uid of above
add_new_db  CHAR(1),                 -- Y -> user can add new DBs to catalog
version     VARCHAR2(12),            -- Version this user is sync'ed to
CONSTRAINT vpc_users_p PRIMARY KEY(filter_user)
) &tablespace&
>>>
 
define vpc_databases
<<<
CREATE TABLE vpc_databases
(
filter_user VARCHAR2(128) NOT NULL,  -- Name of user who has access
filter_uid  NUMBER constraint vpc_databases_uid_nn NOT NULL, -- uid of above
db_id       NUMBER NOT NULL,         -- Database to which this user has access
reg_db_unique_name VARCHAR2(30),     -- Will become null, as soon as db_id is 
--
CONSTRAINT vpc_databases_f1 FOREIGN KEY(filter_user)
  REFERENCES vpc_users,
CONSTRAINT vpc_databases_u2 UNIQUE(filter_user, db_id, reg_db_unique_name),
CONSTRAINT vpc_databases_c1 CHECK 
  ((db_id > 0 and reg_db_unique_name is null) or 
   (db_id = 0 and reg_db_unique_name is not null))
) &tablespace&
>>>
 
define upgcat_vpc_users_add_uid
<<<
alter table vpc_users add (filter_uid number)
>>>
 
define upgcat_vpc_users_populate_uid
<<<
--
--
--
--
begin
   update vpc_users set filter_uid =
      (select user_id from all_users where username = filter_user)
      where filter_uid is null;
   commit;
end;
>>>
 
define upgcat_db_add_reg_db_unique_name
<<<
alter table db add (reg_db_unique_name varchar2(30))
>>>
 
define upgcat_vpc_databases_add_reg_db_unique_name
<<<
alter table vpc_databases add (reg_db_unique_name varchar2(30))
>>>
 
define upgcat_db_add_storage_prov
<<<
alter table db add (storage_prov VARCHAR(1) DEFAULT 'N')
>>>
 
define upgcat_vpc_databases_add_vpc_databases_c1
<<<
alter table vpc_databases add 
CONSTRAINT vpc_databases_c1 CHECK 
  ((db_id > 0 and reg_db_unique_name is null) or 
   (db_id = 0 and reg_db_unique_name is not null))
>>>
 
define upgcat_vpc_databases_add_vpc_databases_u2
<<<
alter table vpc_databases add
  CONSTRAINT vpc_databases_u2 UNIQUE(filter_user, db_id, reg_db_unique_name)
>>>
 
define upgcat_vpc_databases_drop_vpc_databases_u1
<<<
alter table vpc_databases drop constraint vpc_databases_u1
>>>
 
define upgcat_vpc_databases_add_uid
<<<
alter table vpc_databases add (filter_uid number)
>>>
 
define upgcat_vpc_databases_populate_uid
<<<
--
--
--
begin
   update vpc_databases set filter_uid =
      (select filter_uid from vpc_users where
          vpc_databases.filter_user = vpc_users.filter_user)
      where filter_uid is null;
   delete from vpc_databases where filter_uid is null;
   commit;
end;
>>>
 
define upgcat_vpc_users_delete_null_uids
<<<
begin
  delete from vpc_users where filter_uid is null;
  commit;
end;
>>>
 
define upgcat_vpc_users_uid_not_null
<<<
alter table vpc_users modify(filter_uid constraint vpc_users_uid_nn not null)
>>>
 
define upgcat_vpc_databases_uid_not_null
<<<
alter table vpc_databases
modify(filter_uid constraint vpc_databases_uid_nn not null)
>>>
 
define cfs
<<<
CREATE TABLE cfs
(
stmt_number NUMBER NOT NULL, -- statement number
stmt_type   CHAR(1),         -- statement type (C=create, D=drop)
stmt_sql    LONG             -- DDL statement to execute
) &tablespace&
>>>
 
define xmlstore
<<<
CREATE TABLE xmlstore
(
created_user      VARCHAR2(128)  NOT NULL,  -- User who has created
store_key         number         NOT NULL,
name              varchar2(1024) NOT NULL,
name_tag          varchar2(64),
version_num       number         DEFAULT 1 NOT NULL,
creation_time     timestamp      NOT NULL,
modified_time     timestamp      NOT NULL,
doctype           varchar2(32),
schema_ver        varchar2(32),
xml_comment       varchar2(1024),
xmldoc            sys.xmltype    NOT NULL,
constraint xmlstore_p  primary key(store_key),
constraint xmlstore_u1 unique(name, name_tag, version_num)
) &tablespace&
xmltype xmldoc store as clob
>>>
 
define xmlstore_insert_trigger
<<<
create or replace trigger xmlstore_insert_trigger 
  before insert or update on xmlstore for each row
declare
  can_add  number;
begin
  if dbms_catowner <> user then
    select count(*) into can_add from vpc_users
       where filter_user=user;
    if can_add = 0 then
       raise_application_error(num => -20012,
                           msg => 'not authorized to add new row to xmlstore');
    end if;
  end if;
  if inserting then
     :new.created_user := user;
     :new.creation_time := sys_extract_utc(systimestamp);
     :new.modified_time := :new.creation_time;
  else
     :new.created_user := :old.created_user;
     :new.modified_time := sys_extract_utc(systimestamp);
     :new.creation_time := :old.creation_time;
  end if;
end;
>>>
 
define rs_server
<<<
create table server
(
server_key       number NOT NULL,
filter_user      varchar2(128) NOT NULL,  -- User who has access to ORS
server_host      clob          NOT NULL,  -- comma separated list of host
server_port      number        NOT NULL,  -- http port
wallet_alias     varchar2(512)  NOT NULL,
wallet_path      varchar2(512),
proxy_url        varchar2(512),           -- http proxy host without port
proxy_port       number,                  -- port
timeout_secs     number,
rep_server_name  varchar2(128) NOT NULL,
CONSTRAINT server_p PRIMARY KEY (server_key),
CONSTRAINT server_u1 UNIQUE(filter_user, wallet_alias, wallet_path),
CONSTRAINT server_u2 UNIQUE(rep_server_name),
CONSTRAINT server_c1 CHECK (server_port > 0),
CONSTRAINT server_c2 CHECK (proxy_port  > 0)
) &tablespace&
>>>
 
define deleted_object
<<<
CREATE TABLE deleted_object
(
do_key     number NOT NULL,
db_key     number NOT NULL, 
create_time date  NOT NULL,
obj_typ    varchar(26) NOT NULL,
obj_key    number NOT NULL,
obj_stamp  number NOT NULL,
obj_data   number,
set_stamp  number,
set_count  number,
handle     varchar2(1024),
device_type varchar2(255),
CONSTRAINT deleted_object_p1 primary key(do_key, db_key),
CONSTRAINT deleted_object_c1 
              CHECK (obj_typ in 
                      ('BACKUP PIECE',
                       'BACKUP PIECE AVAILABLE',
                       'BACKUP PIECE UNAVAILABLE',
                       'BACKUP PIECE EXPIRED',
                       'BACKUP SET KEEP OPTIONS',
                       'BACKUP SET KEEP UNTIL')),
CONSTRAINT deleted_object_f1 FOREIGN KEY(db_key)
  REFERENCES DB ON DELETE CASCADE
) &tablespace&
>>>
 
define deleted_object_i_1
<<<
CREATE INDEX deleted_object_i_1 on deleted_object(db_key,create_time) compress
1
&tablespace&
>>>
 
define create_deleted_object_seq
<<<
DECLARE
  is_ra  VARCHAR2(128);
  invalid_identifier  exception;
  pragma exception_init(invalid_identifier, -904);
BEGIN
  BEGIN
    EXECUTE IMMEDIATE 'select sys.rai_schema from dual' INTO is_ra;
  EXCEPTION
    WHEN invalid_identifier THEN NULL;
  END;
  IF is_ra IS NULL THEN
    BEGIN
      FOR do_seq_rec IN
        (select table_name from user_tables
           where partitioned='YES'
             and table_name = 'DO_SEQ')
      LOOP
        EXECUTE IMMEDIATE 'drop table do_seq';
      END LOOP;
    END;
  END IF;
  EXECUTE IMMEDIATE q'{
CREATE TABLE do_seq
(
db_key     NUMBER NOT NULL,
curr_value NUMBER DEFAULT 0 NOT NULL,
CONSTRAINT do_seq_p1 PRIMARY KEY(db_key) USING INDEX (
  CREATE UNIQUE INDEX do_seq_p1 ON do_seq(db_key) }'
|| CASE WHEN is_ra IS NOT NULL THEN ' LOCAL' END
|| q'{),
CONSTRAINT do_seq_f1 FOREIGN KEY(db_key)
  REFERENCES DB ON DELETE CASCADE
)}'
|| CASE WHEN is_ra IS NOT NULL THEN 
     ' PARTITION BY HASH (db_key) PARTITIONS 16'
   END
|| ' &tablespace& ';
END;
>>>
 
define bp_update_trigger
<<<
create or replace trigger bp_update_trigger before update on bp for each row
   when (old.status <> new.status)
declare
   l_set_stamp number;
   l_set_count number;
   l_do_seq    number;
begin
   update do_seq set curr_value = curr_value + 1
      where db_key = :old.db_key
      returning curr_value into l_do_seq;
 
   select set_stamp, set_count into l_set_stamp, l_set_count
      from bs
      where bs_key = :old.bs_key;
   insert into deleted_object(do_key, db_key, create_time,
              obj_typ,
              obj_key, obj_stamp, obj_data,
              set_stamp, set_count, handle, device_type)
      values (l_do_seq, :old.db_key, sysdate,
              decode(:new.status, 'A', 'BACKUP PIECE AVAILABLE',
                                  'U', 'BACKUP PIECE UNAVAILABLE',
                                  'D', 'BACKUP PIECE',
                                  'X', 'BACKUP PIECE EXPIRED',
                                  'INVALID VALUE ' || :new.status),
              :old.bp_recid, :old.bp_stamp, null,
              l_set_stamp, l_set_count, :old.handle, :old.device_type);
end;
>>>
 
define watermarks
<<<
create table watermarks
(
db_key           number NOT NULL,
db_unique_name   varchar2(32) NOT NULL,
rs_version_stamp date   NOT NULL,
high_bp_recid    number DEFAULT 0 NOT NULL, -- backup piece recid
high_do_key      number DEFAULT 0 NOT NULL, -- delete object stamp
 
cf_version_stamp date,                      -- primary cf version time
high_df_recid    number DEFAULT 0 NOT NULL, -- df mark for last full resync
high_ts_recid    number DEFAULT 0 NOT NULL, -- ts mark for last full rsync
high_tf_recid    number DEFAULT 0 NOT NULL, -- tf mark for last full resync
high_offr_recid  number DEFAULT 0 NOT NULL, -- offline range mark
 
CONSTRAINT watermarks_f1 FOREIGN KEY(db_key)
  REFERENCES db ON DELETE CASCADE,
CONSTRAINT watermarks_u1 UNIQUE (db_key)
) &tablespace&
>>>
 
define rcfile
<<<
CREATE TABLE rcfile
(
rcfile_key        number,
creation_time     timestamp      NOT NULL,
name              varchar2(1024) NOT NULL,
xmldoc            sys.xmltype    NOT NULL,
constraint rcfile_p primary key(rcfile_key),
constraint rcfile_u1 unique(name)
) &tablespace&
xmltype xmldoc store as clob
>>>
 
define orsevent
<<<
CREATE TABLE orsevent
(
ospid           number,
stamp           number,
stat_start_time date,
event           varchar2(64)    NOT NULL,
param1          varchar2(512),
tag             varchar2(64),
total_waits     number    DEFAULT 0 NOT NULL,
time_waited     number,
minimum_elapsed number, 
minimum_time    date, 
maximum_elapsed number,
maximum_time    date,
start_time      timestamp,
last_start_time date, 
last_end_time   date, 
buf_size        number, 
buf_count       number,
event_type      number,
newstats        number,
constraint      orsevent_u1 unique (ospid, stamp, event, param1),
constraint      orsevent_c1_event_type CHECK (event_type in (1,2)),
constraint      orsevent_c2_newstats CHECK (newstats in (0,1))
) &tablespace&
>>>
 
define avm_restore_range_cache
<<<
CREATE TABLE rrcache
(
db_key         number,
low_time       date,
high_time      date,
low_scn        number,
high_scn       number,
low_dbinc_key  number,
high_dbinc_key number,
range_type     varchar2(32),
max_bp_key     number,
last_do_key    number,
last_updated   date,
constraint     restore_range_cache_u1 unique(db_key, range_type, low_scn)
) &tablespace&
>>>
 
define db_delete_trigger
<<<
create or replace trigger db_delete_trigger after delete on db for each row
declare
begin
   delete rcfile where name like '%_' || :old.db_id || '%';
end;
>>>
 
 
define rs_rc_get_object_list
<<<
create or replace view "_RS_RC_GET_OBJECT_LIST_" as 
   select y.rcfile_key, y.prefix, y.istruncated, substr(y.marker, 8) marker,
          y.maxkeys,
          substr(z.rcfile_name, 8) rcfile_name, z.lastmodified, z.bytes from 
          (select x.rcfile_key, t.prefix, t.istruncated, t.xmldoc, t.marker,
                  t.maxkeys
             from rcfile x, 
                  xmltable('/ListBucketResult' passing x.xmldoc 
                    columns prefix      varchar2(1024) path 'Prefix', 
                            istruncated varchar2(10) path 'IsTruncated', 
                            xmldoc      xmltype path 'Contents',
                            marker      varchar2(1024) path 'Marker', 
                            MaxKeys     number path 'MaxKeys') t 
             where name like 'prefix=%') y, 
          xmltable('/Contents' passing y.xmldoc 
             columns rcfile_name varchar2(1024) path 'Key', 
                     lastmodified timestamp with time zone path 'LastModified',
                     bytes number path 'Size')z
>>>
 
 
define rc_rcver
<<<
create or replace view rc_rcver as select version from rcver
>>>
 
define rc_deleted_object
<<<
create or replace view rc_deleted_object as
select deleted_object.db_key   db_key,
       deleted_object.do_key   do_key,
       deleted_object.obj_typ  object_type,
       deleted_object.obj_key  object_key,
       deleted_object.obj_stamp object_stamp,
       deleted_object.obj_data  object_data,
       deleted_object.set_stamp set_stamp,
       deleted_object.set_count set_count,
       deleted_object.handle    handle,
       deleted_object.device_type device_type
 from deleted_object
>>>
 
define rc_watermarks
<<<
create or replace view rc_watermarks as
select db_key, db_unique_name, rs_version_stamp, high_bp_recid, high_do_key,
       cf_version_stamp, high_df_recid, high_ts_recid, high_tf_recid,
       high_offr_recid from watermarks
>>>
 
define xml_table_names_views
<<<
DECLARE
   type table_name_type is table of user_tables.table_name%TYPE
             index by binary_integer;
   ltable_name table_name_type;
   PROCEDURE createView(name IN VARCHAR2) IS
      CURSOR column_c IS
         SELECT column_name, data_type, data_length FROM user_tab_columns
            WHERE TABLE_NAME = name
            ORDER BY column_name;
      first_row BOOLEAN := TRUE;
      row_data    column_c%ROWTYPE;
      column_list VARCHAR2(4000);
      column_defs VARCHAR2(4000);
      view_stmt VARCHAR2(4000);
      xml_col_name  VARCHAR2(4000);
--
--
   BEGIN
   OPEN column_c;
   LOOP
      FETCH column_c INTO row_data;
      EXIT WHEN column_c%NOTFOUND;
      xml_col_name := REPLACE(row_data.column_name, '#', '_x0023_');
 
      IF row_data.data_type = 'VARCHAR2' OR
         row_data.data_type = 'RAW' THEN
         column_defs := column_defs ||
                        to_char(case when first_row THEN '' ELSE ',' end) ||
                       '"' || row_data.column_name || '" ' ||
                       row_data.data_type ||
                       '(' || row_data.data_length || ')' ||
                       ' path ''' || xml_col_name || '''';
--
--
--
--
      ELSIF row_data.data_type = 'DATE' THEN
         column_defs := column_defs ||
                        to_char(case when first_row THEN '' ELSE ',' end) ||
                        '"' || row_data.column_name || '" CHAR(24) path ''' || 
                        xml_col_name || '''';
      ELSE
         column_defs := column_defs ||
                        to_char(case when first_row THEN '' ELSE ',' end) ||
                        '"' || row_data.column_name || '" ' ||
                        row_data.data_type ||
                        ' path ''' || xml_col_name || '''';
      END IF;
      column_list := column_list ||
                     to_char(case when first_row THEN '' ELSE ',' end) ||
                     't."' || row_data.column_name || '"';
 
      first_row := FALSE;
   END LOOP;
   IF first_row = FALSE THEN
      view_stmt := 'CREATE OR REPLACE VIEW "_RS_' || name || '_" AS ' ||
                    ' select x.rcfile_key rs_rcfile_key, x.creation_time ' ||
                    ' rs_rcfile_creation_time, x.name rs_rcfile_name,' || 
                    column_list ||
                    ' from rcfile x, xmltable(' ||
                    '''/ALL_TABLES/TABLE_' || name || '/ROW''' ||
                    ' passing x.xmldoc columns ' ||
                   column_defs || ') t';
   END IF;
   DBMS_OUTPUT.PUT_LINE(view_stmt);
   EXECUTE IMMEDIATE view_stmt;
   END;
BEGIN
 
--
--
   ltable_name(1)  := 'RC_DATABASE';
   ltable_name(2)  := 'RC_DATABASE_INCARNATION';
   ltable_name(3)  := 'RC_SITE';
   ltable_name(4)  := 'RC_RMAN_CONFIGURATION';
   ltable_name(5)  := 'RC_TABLESPACE';
   ltable_name(6)  := 'RC_REDO_THREAD';
   ltable_name(7)  := 'RCI_DATAFILE';
   ltable_name(8)  := 'RCI_TEMPFILE';
   ltable_name(9)  := 'RC_REDO_LOG';
   ltable_name(10) := 'RC_CHECKPOINT';
   ltable_name(11) := 'RC_OFFLINE_RANGE';
   ltable_name(12) := 'RCI_PDBS';
   ltable_name(13) := 'RC_PLUGGABLE_DATABASE_INC';
 
--
--
   ltable_name(14) := 'RC_RCVER';
   ltable_name(15) := 'RC_WATERMARKS';
   ltable_name(16) := 'RCI_BACKUP_SET';
   ltable_name(17) := 'RCI_BACKUP_PIECE';
   ltable_name(18) := 'RCI_BACKUP_CONTROLFILE';
   ltable_name(19) := 'RCI_BACKUP_DATAFILE';
   ltable_name(20) := 'RC_BACKUP_REDOLOG';
   ltable_name(21) := 'RCI_BACKUP_SPFILE';
   ltable_name(22) := 'RC_DELETED_OBJECT';
   ltable_name(23) := 'RCI_RA_UPSTREAM_DATABASE';
   FOR idx in 1..23 LOOP
      createView(ltable_name(idx));
   END LOOP;
END;
>>>
 
 
define dbms_catowner
<<<
CREATE OR REPLACE FUNCTION dbms_catowner RETURN VARCHAR2 AUTHID DEFINER IS
   u varchar2(128);
begin
   select username into u from user_users;
   return u;
end;
>>>
 
define grant_rman_seq
<<<
grant select on rman_seq to public
>>>
 
define grant_dbms_rcvman
<<<
grant execute on dbms_rcvman to public
>>>
 
define grant_dbms_rcvcat
<<<
grant execute on dbms_rcvcat to public
>>>
 
define grant_rc_listBackupPipe
<<<
grant execute on rc_listBackupPipe to public
>>>
 
define grant_rc_listRsRangePipe
<<<
grant execute on rc_listRsRangePipe to public
>>>
 
define grant_dbms_catowner
<<<
grant execute on dbms_catowner to public
>>>
 
define drop_al_v <<< drop view al_v >>>
define drop_bcf_v <<< drop view bcf_v >>>
define drop_bdf_v <<< drop view bdf_v >>>
define drop_brl_v <<< drop view brl_v >>>
define drop_ccf_v <<< drop view ccf_v >>>
define drop_cdf_v <<< drop view cdf_v >>>
define drop_ckp_v <<< drop view ckp_v >>>
define drop_site_dfatt_v <<< drop view site_dfatt_v >>>
define drop_df_v <<< drop view df_v >>>
define drop_fb_v <<< drop view fb_v >>>
define drop_grsp_v <<< drop view grsp_v >>>
define drop_nrsp_v <<< drop view nrsp_v >>>
define drop_offr_v <<< drop view offr_v >>>
define drop_orl_v <<< drop view orl_v >>>
define drop_rlh_v <<< drop view rlh_v >>>
define drop_rr_v <<< drop view rr_v >>>
define drop_rsr_v <<< drop view rsr_v >>>
define drop_rt_v <<< drop view rt_v >>>
define drop_site_tfatt_v <<< drop view site_tfatt_v >>>
define drop_tf_v <<< drop view tf_v >>>
define drop_tsatt_v <<< drop view tsatt_v >>>
define drop_ts_v <<< drop view ts_v >>>
define drop_xal_v <<< drop view xal_v >>>
define drop_xcf_v <<< drop view xcf_v >>>
define drop_xdf_v <<< drop view xdf_v >>>
define drop_bp_v <<< drop view bp_v >>>
define drop_bsf_v <<< drop view bsf_v >>>
define drop_bs_v <<< drop view bs_v >>>
define drop_conf_v <<< drop view conf_v >>>
define drop_dbinc_v <<< drop view dbinc_v >>>
define drop_db_v <<< drop view db_v >>>
define drop_pdb_v <<< drop view pdb_v >>>
define drop_pdbinc_v <<< drop view pdbinc_v >>>
define drop_pdb_dbinc_v <<< drop view pdb_dbinc_v >>>
define drop_node_v <<< drop view node_v >>>
define drop_rout_v <<< drop view rout_v >>>
define drop_scr_v <<< drop view scr_v >>>
define drop_bcb_v <<< drop view bcb_v >>>
define drop_ccb_v <<< drop view ccb_v >>>
define drop_scrl_v <<< drop view scrl_v >>>
define drop_config_v <<< drop view config_v >>>
define drop_rcver_v <<< drop view rcver_v >>>
define drop_vpc_users_v <<< drop view vpc_users_v >>>
define drop_vpc_databases_v <<< drop view vpc_databases_v >>>
define drop_cfs_v <<< drop view cfs_v >>>
define drop_xmlstore_v <<< drop view xmlstore_v >>>
define drop_bcr_v <<< drop view bcr_v >>>
define drop_server_v <<< drop view server_v >>>
define drop_deleted_object_v <<< drop view deleted_object_v >>>
define drop_watermarks_v <<< drop view watermarks_v >>>
define drop_rcfile_v <<< drop view rcfile_v >>>
define drop_orsevent_v <<< drop view orsevent_v >>>
define drop_dbms_catowner <<< drop function dbms_catowner >>>
 
define syn_drop_all
<<<
begin
   for s in (select * from all_synonyms
              where owner = sys_context('USERENV', 'CURRENT_SCHEMA')) loop
      execute immediate 'drop synonym ' || s.synonym_name;
   end loop;
end;
>>>
 
define config_update
<<<
begin
   insert into config select 'compatible','080004' from dual
     where not exists (select * from config);
   commit;
end;
>>>
 
define tempres
<<<
CREATE TABLE tempres
( 
name        VARCHAR2(1024) NOT NULL,      -- name of the temporary resource
data_type   VARCHAR2(32)   NOT NULL,      -- TABLE or DBLINK
CONSTRAINT tempres_u1 UNIQUE(name)
) &tablespace&
>>>
 
define idb
<<<
CREATE TABLE &1&
(
db_key            NUMBER NOT NULL,
db_id             NUMBER NOT NULL,
CONSTRAINT &2&_p  PRIMARY KEY (db_key),
CONSTRAINT &3&_u1 UNIQUE(db_id)
)
>>>
 
define idbinc
<<<
CREATE TABLE &1&
(
dbinc_key        NUMBER NOT NULL,
CONSTRAINT &2&_p PRIMARY KEY(dbinc_key)
)
>>>
 
define dblink
<<<
--
--
--
--
CREATE DATABASE LINK &1& CONNECT
   TO &2& IDENTIFIED BY &3& USING &4&
>>>
 
 
define rc_database
<<<
create or replace view rc_database as
select db.db_key,
       db.curr_dbinc_key dbinc_key,
       db.db_id dbid,
       dbinc.db_name name,
       dbinc.reset_scn resetlogs_change#,
       dbinc.reset_time resetlogs_time,
       (CAST(NULL AS NUMBER)) final_change#
from db, dbinc
where db.curr_dbinc_key = dbinc.dbinc_key
>>>
 
define rc_database_ors
<<<
create or replace view rc_database as
select db.db_key,
       db.curr_dbinc_key dbinc_key,
       db.db_id dbid,
       dbinc.db_name name,
       dbinc.reset_scn resetlogs_change#,
       dbinc.reset_time resetlogs_time,
       (case when (select count(*) from task 
                    where task_type in (120,130)
                      and state not in (3,8) 
                      and db_key = db.db_key
                      and rownum = 1) > 0
             then 0
             else (select min(max(next_scn)) 
                   from brl b1
                   where nvl2(activation, dbinc_key, null) = db.curr_dbinc_key
                   and db.storage_prov = 'Y'
                   and not exists (select 1 from brl b2
                                    where b1.dbinc_key = b2.dbinc_key
                                      and b1.thread# = b2.thread#
                                      and b1.sequence# < b2.sequence#)
                   group by thread#)
       end) as final_change#
from db, dbinc
where db.curr_dbinc_key = dbinc.dbinc_key
>>>
 
define rci_pdbs
<<<
create or replace view rci_pdbs as
select pdb.pdb_key,
       pdb.db_key,
       pdb.name,
       pdb.con_id,
       pdb.db_id dbid,
       pdb.create_scn creation_change#,
       pdb.guid guid,
       pdb.nobackup
  from pdb
>>>
 
define rc_pdbs
<<<
create or replace view rc_pdbs as
select pdb_key,
       db_key,
       name,
       con_id,
       dbid,
       creation_change#,
       guid
  from rci_pdbs
 where con_id > 1
>>>
 
define rc_rman_configuration
<<<
create or replace view rc_rman_configuration as
select conf.db_key,
       conf.conf# conf#,
       conf.name name,
       conf.value value,
       conf.db_unique_name db_unique_name,
       conf.site_key
from db, conf
where db.db_key = conf.db_key
>>>
 
define rc_database_incarnation
<<<
create or replace view rc_database_incarnation as
select db.db_key,
       db.db_id dbid,
       cur.dbinc_key,
       cur.db_name name,
       cur.reset_scn resetlogs_change#,
       cur.reset_time resetlogs_time,
       decode(cur.dbinc_key, db.curr_dbinc_key, 'YES', 'NO')
         current_incarnation, 
       cur.parent_dbinc_key,
       par.reset_scn prior_resetlogs_change#,
       par.reset_time prior_resetlogs_time,
       cur.dbinc_status  status,
       db.reg_db_unique_name,
       pdb.con_id,
       pdb.guid
from db, dbinc cur, dbinc par, pdb
where db.db_key = cur.db_key
  and (cur.parent_dbinc_key = par.dbinc_key)
  and db.db_key = pdb.db_key
  and pdb.con_id in (1, 0)
union all
select db.db_key,
       db.db_id dbid,
       dbinc.dbinc_key,
       dbinc.db_name name,
       dbinc.reset_scn resetlogs_change#,
       dbinc.reset_time resetlogs_time,
       decode(dbinc.dbinc_key, db.curr_dbinc_key, 'YES', 'NO')
         current_incarnation, 
       to_number(null),
       to_number(null),
       to_date(null),
       dbinc.dbinc_status status,
       db.reg_db_unique_name,
       pdb.con_id,
       pdb.guid
from db, dbinc, pdb
where db.db_key=dbinc.db_key
  and dbinc.parent_dbinc_key IS NULL          -- get last incarnation
  and db.db_key = pdb.db_key
  and pdb.con_id in (1, 0)
>>>
 
 
define rci_pdbinc_this_dbinc
<<<
create or replace view rci_pdbinc_this_dbinc as
select par.*,
       cur.inc_scn next_inc_scn,
       cur.end_reset_scn next_end_reset_scn,
       pdb.db_key,
       pdb_dbinc.dbinc_key,
       pdb.name,
       pdb.con_id,
       pdb.db_id,
       pdb.create_scn,
       pdb_dbinc.drop_scn,
       pdb_dbinc.curr_pdbinc_key,
       pdb.nobackup,
       pdb.guid
  from pdbinc cur, pdbinc par, pdb, pdb_dbinc
 where cur.parent_pdbinc_key = par.pdbinc_key
   and cur.pdbinc_status != 'ORPHAN'
   and cur.pdb_key = pdb.pdb_key
   and pdb.pdb_key = pdb_dbinc.pdb_key
union all
select pdbinc.*,
       18446744073709551615 next_inc_scn,
       18446744073709551615 next_end_reset_scn,
       pdb.db_key,
       pdb_dbinc.dbinc_key,
       pdb.name,
       pdb.con_id,
       pdb.db_id,
       pdb.create_scn,
       pdb_dbinc.drop_scn,
       pdb_dbinc.curr_pdbinc_key,
       pdb.nobackup,
       pdb.guid
  from pdbinc, pdb, pdb_dbinc
 where pdb_dbinc.curr_pdbinc_key = pdbinc.pdbinc_key
   and pdbinc.pdbinc_status = 'CURRENT'
   and pdbinc.pdb_key = pdb.pdb_key
>>>
 
define rc_pluggable_database_inc
<<<
create or replace view rc_pluggable_database_inc as
select rci_pdbs.pdb_key,
       rci_pdbs.name,
       rci_pdbs.con_id,
       rci_pdbs.dbid,
       rci_pdbs.guid,
       rci_pdbs.creation_change# create_scn,
       cur.pdbinc_key,
       rci_pdbs.db_key db_key,
       decode(cur.pdbinc_status, 'CURRENT', 'YES', 'NO') current_incarnation,
       cur.inc_scn incarnation_scn,
       cur.begin_reset_scn begin_resetlogs_scn,
       cur.begin_reset_time begin_resetlogs_time,
       cur.end_reset_scn end_resetlogs_scn,
       cur.born_dbinc_key dbinc_key,
       cur_dbinc.reset_scn db_resetlogs_scn,
       cur_dbinc.reset_time db_resetlogs_time,
       cur.parent_pdbinc_key prior_pdbinc_key,
       par.inc_scn prior_incarnation_scn,
       par.begin_reset_scn prior_begin_resetlogs_scn,
       par.begin_reset_time prior_begin_resetlogs_time,
       par.end_reset_scn prior_end_resetlogs_scn,
       par.born_dbinc_key prior_dbinc_key,
       par_dbinc.reset_scn prior_db_resetlogs_scn,
       par_dbinc.reset_time prior_db_resetlogs_time,
       cur.pdbinc_status status
from rci_pdbs, pdbinc cur, pdbinc par, dbinc cur_dbinc, dbinc par_dbinc
where rci_pdbs.pdb_key = cur.pdb_key and
      rci_pdbs.con_id > 1 and
      cur.parent_pdbinc_key = par.pdbinc_key(+) and
      cur_dbinc.dbinc_key = cur.born_dbinc_key and
      cur_dbinc.parent_dbinc_key = par_dbinc.dbinc_key(+)
>>>
 
 
 
define rc_resync
<<<
create or replace view rc_resync as
select dbinc.db_key,
       dbinc.dbinc_key,
       dbinc.db_name,
       ckp.ckp_key resync_key,
       ckp.ckp_scn controlfile_change#,
       ckp.ckp_time controlfile_time,
       ckp.ckp_cf_seq controlfile_sequence#,
       ckp.cf_create_time controlfile_version,
       ckp.ckp_type resync_type,
       ckp.ckp_db_status db_status,
       ckp.resync_time
from ckp, dbinc
where ckp.dbinc_key = dbinc.dbinc_key
>>>
 
 
 
define rc_checkpoint
<<<
create or replace view rc_checkpoint as
select dbinc.db_key,
       dbinc.dbinc_key,
       dbinc.db_name,
       ckp.ckp_key,
       ckp.ckp_scn,
       ckp.ckp_cf_seq,
       ckp.ckp_time,
       ckp.ckp_type,
       ckp.ckp_db_status,
       ckp.site_key
from ckp, dbinc
where ckp.dbinc_key = dbinc.dbinc_key
>>>
 
 
define rci_tablespace_this_dbinc
<<<
create or replace view rci_tablespace_this_dbinc as
select dbinc.db_key,
       dbinc.dbinc_key,
       dbinc.db_name,
       pdbinc.con_id,
       pdbinc.name pdb_name,
       pdbinc.pdb_key pdb_key,
       ts.pdbinc_key,
       ts.ts#,
       ts.ts_name name,
       ts.create_scn creation_change#,
       ts.create_time creation_time,
       ts.drop_scn drop_change#,
       ts.drop_time,
       ts.included_in_database_backup,
       ts.bigfile,
       ts.temporary,
       ts.encrypt_in_backup,
       ts.plugin_scn plugin_change#
from ts, dbinc, rci_pdbinc_this_dbinc pdbinc
where dbinc.dbinc_key = ts.dbinc_key
  and ts.pdbinc_key   = pdbinc.pdbinc_key
  and ts.dbinc_key    = pdbinc.dbinc_key
  and ts.create_scn   < pdbinc.next_inc_scn
  and ts.plugin_scn   < pdbinc.next_inc_scn
>>>
 
define rc_tablespace
<<<
create or replace view rc_tablespace as
select dbinc.db_key,
       dbinc.dbinc_key,
       dbinc.db_name,
       pdb.con_id,
       decode(pdb.con_id, 0, NULL, pdb.name) pdb_name,
       pdb.pdb_key pdb_key,
       ts.pdbinc_key,
       ts.ts#,
       ts.ts_name name,
       ts.create_scn creation_change#,
       ts.create_time creation_time,
       ts.drop_scn drop_change#,
       ts.drop_time,
       ts.included_in_database_backup,
       ts.bigfile,
       ts.temporary,
       ts.encrypt_in_backup,
       ts.plugin_scn plugin_change#
from ts, dbinc, pdbinc, pdb
where dbinc.dbinc_key = ts.dbinc_key
  and ts.pdbinc_key = pdbinc.pdbinc_key
  and pdbinc.pdb_key = pdb.pdb_key
>>>
 
 
define rci_tempfile
<<<
create or replace view rci_tempfile as
select dbinc.db_key,
       dbinc.dbinc_key,
       dbinc.db_name,
       pdb.con_id con_id,
       decode(pdb.con_id, 0, NULL, pdb.name) pdb_name,
       pdb.pdb_key pdb_key,
       ts.ts#,
       ts.ts_name tablespace_name,
       tf.file#,
       tf.create_scn creation_change#,
       tf.create_time creation_time,
       site_tfatt.drop_scn drop_change#,
       site_tfatt.drop_time,
       site_tfatt.blocks * tf.block_size bytes,
       site_tfatt.blocks,
       tf.block_size,
       site_tfatt.fname name,
       tf.rfile#,
       site_tfatt.autoextend,
       site_tfatt.max_size maxsize,
       site_tfatt.next_size nextsize,
       ts.bigfile,
       node.site_key,
       node.db_unique_name,
       ts.create_scn tablespace_creation_change#,
       ts.create_time tablespace_creation_time,
       ts.drop_scn tablespace_drop_change#,
       ts.drop_time tablespace_drop_time
from dbinc, ts, tf, node, site_tfatt, pdb
where dbinc.dbinc_key = ts.dbinc_key
and   ts.dbinc_key = tf.dbinc_key
and   ts.ts# = tf.ts#
and   ts.create_scn = tf.ts_create_scn
and   ts.pdbinc_key = tf.ts_pdbinc_key
and   node.db_key = dbinc.db_key
and   tf.tf_key = site_tfatt.tf_key
and   node.site_key = site_tfatt.site_key
and   tf.pdb_key = pdb.pdb_key
>>>
 
define rci_datafile
<<<
create or replace view rci_datafile as
select a.db_key,
       a.dbinc_key,
       a.db_name,
       a.con_id,
       a.pdb_name,
       a.pdb_key,
       a.pdb_closed,
       a.pdbinc_key,
       a.ts#,
       a.tablespace_name,
       a.file#,
       a.creation_change#,
       a.creation_time,
       a.drop_change#,
       a.drop_time,
       a.bytes,
       a.blocks,
       a.block_size,
       site_dfatt.fname name,
       a.stop_change#,
       a.stop_time,
       a.read_only,
       a.rfile#,
       a.included_in_database_backup,
       a.aux_name,
       a.encrypt_in_backup,
       a.site_key,
       a.db_unique_name,
       a.foreign_dbid,
       a.foreign_create_scn foreign_creation_change#,
       a.foreign_create_time foreign_creation_time,
       a.plugged_readonly,
       a.plugin_scn plugin_change#,
       a.plugin_reset_scn plugin_resetlogs_change#,
       a.plugin_reset_time plugin_resetlogs_time,
       a.creation_thread,
       a.creation_size,
       a.pdb_foreign_dbid,
       a.pdb_foreign_ckp_scn,
       a.pdb_nobackup,
       a.pdb_foreign_afn
  from 
    (select dbinc.db_key,
       dbinc.dbinc_key,
       dbinc.db_name,
       pdb.con_id con_id,
       pdb.name pdb_name,
       pdb.pdb_key pdb_key,
       df.pdbinc_key,
       df.pdb_closed,
       ts.ts#,
       ts.ts_name tablespace_name,
       df.file#,
       df.create_scn creation_change#,
       df.create_time creation_time,
       df.drop_scn drop_change#,
       df.drop_time,
       df.blocks*df.block_size bytes,
       df.blocks,
       df.block_size,
       df.stop_scn stop_change#,
       df.stop_time,
       df.read_only read_only,
       df.rfile#,
       ts.included_in_database_backup,
       df.clone_fname aux_name,
       ts.encrypt_in_backup,
       df.df_key,
       node.site_key,
       node.db_unique_name,
       df.foreign_dbid,
       df.foreign_create_scn,
       df.foreign_create_time,
       df.plugged_readonly,
       df.plugin_scn,
       df.plugin_reset_scn,
       df.plugin_reset_time,
       df.create_thread creation_thread,
       df.create_size creation_size,
       df.pdb_foreign_dbid,
       df.pdb_foreign_ckp_scn,
       pdb.nobackup pdb_nobackup,
       df.pdb_foreign_afn
    from dbinc, ts, df, node, pdbinc, pdb
    where dbinc.dbinc_key = ts.dbinc_key
    and   ts.dbinc_key = df.dbinc_key
    and   ts.ts# = df.ts#
    and   ts.create_scn = df.ts_create_scn
    and   ts.pdbinc_key = df.ts_pdbinc_key
    and   ts.plugin_scn = df.ts_plugin_scn
    and   node.db_key = dbinc.db_key
    and   df.pdbinc_key = pdbinc.pdbinc_key
    and   pdb.pdb_key = pdbinc.pdb_key) a, site_dfatt
where a.site_key = site_dfatt.site_key(+)
  and a.df_key = site_dfatt.df_key(+)
>>>
 
define rci_datafile_this_dbinc
<<<
create or replace view rci_datafile_this_dbinc as
select a.db_key,
       a.dbinc_key,
       a.db_name,
       a.con_id,
       a.pdb_name,
       a.pdb_key,
       a.pdb_closed,
       a.pdbinc_key,
       a.ts#,
       a.tablespace_name,
       a.file#,
       a.creation_change#,
       a.creation_time,
       a.drop_change#,
       a.drop_time,
       a.bytes,
       a.blocks,
       a.block_size,
       site_dfatt.fname name,
       a.stop_change#,
       a.stop_time,
       a.read_only,
       a.rfile#,
       a.included_in_database_backup,
       a.aux_name,
       a.encrypt_in_backup,
       a.site_key,
       a.db_unique_name,
       a.foreign_dbid,
       a.foreign_create_scn foreign_creation_change#,
       a.foreign_create_time foreign_creation_time,
       a.plugged_readonly,
       a.plugin_scn plugin_change#,
       a.plugin_reset_scn plugin_resetlogs_change#,
       a.plugin_reset_time plugin_resetlogs_time,
       a.creation_thread,
       a.creation_size,
       a.pdb_foreign_dbid,
       a.pdb_foreign_ckp_scn,
       a.pdb_nobackup,
       a.pdb_foreign_afn
  from 
    (select dbinc.db_key,
       dbinc.dbinc_key,
       dbinc.db_name,
       pdbinc.con_id con_id,
       pdbinc.name pdb_name,
       pdbinc.pdb_key pdb_key,
       df.pdbinc_key,
       df.pdb_closed,
       ts.ts#,
       ts.ts_name tablespace_name,
       df.file#,
       df.create_scn creation_change#,
       df.create_time creation_time,
       df.drop_scn drop_change#,
       df.drop_time,
       df.blocks*df.block_size bytes,
       df.blocks,
       df.block_size,
       df.stop_scn stop_change#,
       df.stop_time,
       df.read_only read_only,
       df.rfile#,
       ts.included_in_database_backup,
       df.clone_fname aux_name,
       ts.encrypt_in_backup,
       df.df_key,
       node.site_key,
       node.db_unique_name,
       df.foreign_dbid,
       df.foreign_create_scn,
       df.foreign_create_time,
       df.plugged_readonly,
       df.plugin_scn,
       df.plugin_reset_scn,
       df.plugin_reset_time,
       df.create_thread creation_thread,
       df.create_size creation_size,
       df.pdb_foreign_dbid,
       df.pdb_foreign_ckp_scn,
       pdbinc.nobackup pdb_nobackup,
       df.pdb_foreign_afn
    from dbinc, ts, df, node, rci_pdbinc_this_dbinc pdbinc
    where dbinc.dbinc_key = ts.dbinc_key
    and   ts.dbinc_key = df.dbinc_key
    and   ts.ts# = df.ts#
    and   ts.create_scn = df.ts_create_scn
    and   ts.pdbinc_key = df.ts_pdbinc_key
    and   ts.plugin_scn = df.ts_plugin_scn
    and   node.db_key = dbinc.db_key
    and   df.pdbinc_key = pdbinc.pdbinc_key
    and   df.dbinc_key = pdbinc.dbinc_key
    and   df.create_scn < pdbinc.next_inc_scn
    and   df.plugin_scn < pdbinc.next_inc_scn) a, site_dfatt
where a.site_key = site_dfatt.site_key(+)
  and a.df_key = site_dfatt.df_key(+)
>>>
 
define create_rci_avm_upstream_database
<<<
create or replace view rci_ra_upstream_database as 
   select to_number(null) dbid, 'NOT_RA_SCHEMA' name from dual
>>>
 
define create_rci_avm_upstream_database_ors
<<<
create or replace view rci_ra_upstream_database as 
   select dbid, name from v$database
>>>
 
define rc_datafile
<<<
create or replace view rc_datafile as
select db_key,
       dbinc_key,
       db_name,
       con_id,
       decode(con_id, 0, NULL, pdb_name) pdb_name,
       pdb_key,
       pdbinc_key,
       ts#,
       tablespace_name,
       file#,
       creation_change#,
       creation_time,
       drop_change#,
       drop_time,
       bytes,
       blocks,
       block_size,
       name,
       stop_change#,
       stop_time,
       read_only,
       rfile#,
       included_in_database_backup,
       aux_name,
       encrypt_in_backup,
       site_key,
       db_unique_name,
       foreign_dbid,
       foreign_creation_change#,
       foreign_creation_time,
       plugged_readonly,
       plugin_change#,
       plugin_resetlogs_change#,
       plugin_resetlogs_time,
       creation_thread,
       creation_size
  from rci_datafile
       where substr(nvl(db_unique_name, 'A'),1,1) <> '$'
   
>>>
 
define rc_tempfile
<<<
create or replace view rc_tempfile as
select * from rci_tempfile
       where substr(nvl(db_unique_name, 'A'),1,1) <> '$'
>>>
 
 
define rc_redo_thread
<<<
create or replace view rc_redo_thread as
select dbinc.db_key,
       dbinc.dbinc_key,
       dbinc.db_name,
       rt.thread#,
       rt.status,
       rt.sequence#,
       rt.enable_scn enable_change#,
       rt.enable_time,
       rt.disable_scn disable_change#,
       rt.disable_time
from dbinc, rt
where dbinc.dbinc_key = rt.dbinc_key
>>>
 
 
define rc_redo_log
<<<
create or replace view rc_redo_log as
select dbinc.db_key,
       dbinc.dbinc_key,
       dbinc.db_name,
       orl.thread#,
       orl.group#,
       orl.fname name,
       orl.site_key,
       orl.bytes bytes,
       orl.type type
from dbinc, orl
where dbinc.dbinc_key = orl.dbinc_key
>>>
 
define rc_log_history
<<<
create or replace view rc_log_history as
select dbinc.db_key,
       dbinc.dbinc_key,
       dbinc.db_name,
       rlh.rlh_recid recid,
       rlh.rlh_stamp stamp,
       rlh.thread#,
       rlh.sequence#,
       rlh.low_scn first_change#,
       rlh.low_time first_time,
       rlh.next_scn next_change#,
       decode(rlh.status, 'N', 'NO', 'Y', 'YES', NULL,  NULL, '?') cleared
--       rlh.next_time,
--       rlh.blocks
from dbinc, rlh
where dbinc.dbinc_key = rlh.dbinc_key
>>>
 
define rc_archived_log
<<<
create or replace view rc_archived_log as
select dbinc.db_key,
       dbinc.dbinc_key,
       dbinc.db_name,
       al.al_key,
       al.al_recid recid,
       al.al_stamp stamp,
       al.fname name,
       al.thread#,
       al.sequence#,
       dbinc.reset_scn resetlogs_change#,
       dbinc.reset_time resetlogs_time,
       al.low_scn first_change#,
       al.low_time first_time,
       al.next_scn next_change#,
       al.next_time,
       al.blocks,
       al.block_size,
       al.completion_time,
       decode(al.archived, 'N', 'NO', 'Y', 'YES', '?') archived,
       al.status,
       decode(al.is_standby, 'Y', 'YES', 'NO') is_standby,
       al.dictionary_begin,
       al.dictionary_end,
       al.is_recovery_dest_file,
       al.compressed,
       al.creator,
       al.terminal,
       al.site_key
from dbinc, al
where dbinc.dbinc_key = al.dbinc_key
>>>
 
 
define rci_backup_set
<<<
create or replace view rci_backup_set as
select db.db_key,
       db.db_id,
       bs.bs_key,
       bs.bs_recid recid,
       bs.bs_stamp stamp,
       bs.set_stamp,
       bs.set_count,
       bs.bck_type backup_type,
       bs.incr_level incremental_level,
       bs.pieces,
       bs.start_time,
       bs.completion_time,
       abs((bs.completion_time - bs.start_time) * 86400) elapsed_seconds,
       bs.status,
       bs.controlfile_included,
       bs.input_file_scan_only,
       decode(keep_options, 0, 'NO',
                               'YES') keep,
       keep_until,
       decode(keep_options, 256,  'LOGS',
                            512,  'NOLOGS',
                            1024, 'BACKUP_LOGS',
                                  NULL) keep_options,
       bs.block_size,
       bs.site_key,
       decode(bs.multi_section, 'Y', 'YES', 'NO') multi_section,
       pdb.guid,
       pdb.pdb_key
from db, bs, pdb
where db.db_key = bs.db_key
  and pdb.pdb_key = bs.pdb_key
>>>
 
define rc_backup_set
<<<
create or replace view rc_backup_set as
select db_key,
       db_id,
       pdb_key,
       bs_key,
       recid,
       stamp,
       set_stamp,
       set_count,
       backup_type,
       incremental_level,
       pieces,
       start_time,
       completion_time,
       elapsed_seconds,
       status,
       controlfile_included,
       input_file_scan_only,
       keep,
       keep_until,
       keep_options,
       block_size,
       site_key,
       multi_section
from rci_backup_set
>>>
 
 
 
define rci_backup_piece
<<<
create or replace view rci_backup_piece as
select db.db_key,
       db.db_id,
       bp.bp_key,
       bp.bp_recid recid,
       bp.bp_stamp stamp,
       bs.bs_key,
       bs.set_stamp,
       bs.set_count,
       bs.bck_type backup_type,
       bs.incr_level incremental_level,
       bp.piece#,
       bp.copy#,
       bp.device_type,
       bp.handle,
       bp.comments,
       bp.media,
       bp.media_pool,
       decode(bp.concur, 'N', 'NO', 'Y', 'YES', '?') concur,
       bp.tag,
       bp.start_time,
       bp.completion_time,
       abs((bp.completion_time - bp.start_time) * 86400) elapsed_seconds,
       bp.status,
       bp.bytes,
       bp.is_recovery_dest_file,
       bp.rsr_key,
       bp.compressed,
       bp.site_key,
       decode(bp.encrypted, 'N', 'NO', 'Y', 'YES', '?') encrypted,
       decode(bp.backed_by_osb, 'N', 'NO', 'Y', 'YES', '?') backed_by_osb,
       decode(bp.ba_access,
             'U', 'Unknown', 'T', 'Tape', 'L', 'Local', 'D', 'Disk',
             'R', 'Replication') ba_access,    -- any changes to this list
--
       bp.vb_key,
       decode(bp.vb_key, NULL, 'NO', 'YES') virtual,
       bp.lib_key,
       pdb.guid,
       pdb.pdb_key
from db, bs, bp, pdb
where db.db_key = bs.db_key
and   bs.bs_key = bp.bs_key
and   bp.status != 'D'
and   bp.pdb_key = pdb.pdb_key
>>>
 
define rc_backup_piece
<<<
create or replace view rc_backup_piece as
select db_key,
       db_id,
       pdb_key,
       bp_key,
       recid,
       stamp,
       bs_key,
       set_stamp,
       set_count,
       backup_type,
       incremental_level,
       piece#,
       copy#,
       device_type,
       handle,
       comments,
       media,
       media_pool,
       concur,
       tag,
       start_time,
       completion_time,
       elapsed_seconds,
       status,
       bytes,
       is_recovery_dest_file,
       rsr_key,
       compressed,
       site_key,
       encrypted,
       backed_by_osb,
       ba_access,
       vb_key,
       virtual,
       lib_key
from rci_backup_piece
>>>
 
 
define rci_backup_datafile
<<<
create or replace view rci_backup_datafile as
select dbinc.db_key,
       dbinc.dbinc_key,
       dbinc.db_name,
       bdf.bdf_key,
       bdf.bdf_recid recid,
       bdf.bdf_stamp stamp,
       bs.bs_key,
       bs.set_stamp,
       bs.set_count,
       bs.bs_recid,
       bs.bs_stamp,
       bs.bck_type backup_type,
       bdf.incr_level incremental_level,
       bdf.completion_time,
       bdf.file#,
       bdf.create_scn creation_change#,
       bdf.create_time creation_time,
       dbinc.reset_scn resetlogs_change#,
       dbinc.reset_time resetlogs_time,
       bdf.incr_scn incremental_change#,
       bdf.ckp_scn checkpoint_change#,
       bdf.ckp_time checkpoint_time,
       bdf.abs_fuzzy_scn absolute_fuzzy_change#,
       bdf.datafile_blocks,
       bdf.blocks,
       bdf.block_size,
       bs.status,
       bs.incr_level bs_level,
       bs.pieces,
       bdf.blocks_read,
       bdf.marked_corrupt,
       decode(bdf.used_chg_track, 'Y', 'YES', 'NO')  used_change_tracking,
       decode(bdf.used_optim, 'Y', 'YES', 'NO') used_optimization,
       decode(bdf.used_optim, 
              'Y',round((100 *(bdf.datafile_blocks - bdf.blocks_read)) / 
                        bdf.datafile_blocks),
              NULL) pct_notread,
       bdf.foreign_dbid,
       bdf.plugged_readonly,
       bdf.plugin_scn plugin_change#,
       bdf.plugin_reset_scn plugin_resetlogs_change#,
       bdf.plugin_reset_time plugin_resetlogs_time,
       bdf.section_size,
       pdb.guid,
       bdf.sparse_backup,
       pdb.pdb_key
from dbinc, bs, bdf, pdb
where dbinc.dbinc_key = bdf.dbinc_key
and   bs.bs_key = bdf.bs_key
and   bs.bck_type != 'L'
and   bdf.pdb_key = pdb.pdb_key
>>>
 
define rc_backup_datafile
<<<
create or replace view rc_backup_datafile as
select db_key,
       dbinc_key,
       db_name,
       pdb_key,
       bdf_key,
       recid,
       stamp,
       bs_key,
       set_stamp,
       set_count,
       bs_recid,
       bs_stamp,
       backup_type,
       incremental_level,
       completion_time,
       file#,
       creation_change#,
       creation_time,
       resetlogs_change#,
       resetlogs_time,
       incremental_change#,
       checkpoint_change#,
       checkpoint_time,
       absolute_fuzzy_change#,
       datafile_blocks,
       blocks,
       block_size,
       status,
       bs_level,
       pieces,
       blocks_read,
       marked_corrupt,
       used_change_tracking,
       used_optimization,
       pct_notread,
       foreign_dbid,
       plugged_readonly,
       plugin_change#,
       plugin_resetlogs_change#,
       plugin_resetlogs_time,
       section_size,
       sparse_backup
from rci_backup_datafile
>>>
 
 
define rci_backup_controlfile
<<<
create or replace view rci_backup_controlfile as
select dbinc.db_key,
       dbinc.dbinc_key,
       dbinc.db_name,
       bcf.bcf_key,
       bcf.bcf_recid recid,
       bcf.bcf_stamp stamp,
       bs.bs_key,
       bs.set_stamp,
       bs.set_count,
       dbinc.reset_scn resetlogs_change#,
       dbinc.reset_time resetlogs_time,
       bcf.ckp_scn checkpoint_change#,
       bcf.ckp_time checkpoint_time,
       bcf.create_time creation_time,
       bcf.block_size,
       bcf.min_offr_recid oldest_offline_range,
       bs.status,
       bs_recid,
       bs_stamp,
       bs.incr_level bs_level,
       bs.completion_time,
       bcf.controlfile_type,
       bcf.blocks,
       bcf.autobackup_date,
       bcf.autobackup_sequence,
       pdb.guid,
       pdb.pdb_key
from dbinc, bs, bcf, pdb
where dbinc.dbinc_key = bcf.dbinc_key
and   bs.bs_key = bcf.bs_key
and   bs.bck_type != 'L'
and   bcf.pdb_key = pdb.pdb_key
>>>
 
define rc_backup_controlfile
<<<
create or replace view rc_backup_controlfile as
select db_key,
       dbinc_key,
       db_name,
       bcf_key,
       recid,
       stamp,
       bs_key,
       set_stamp,
       set_count,
       resetlogs_change#,
       resetlogs_time,
       checkpoint_change#,
       checkpoint_time,
       creation_time,
       block_size,
       oldest_offline_range,
       status,
       bs_recid,
       bs_stamp,
       bs_level,
       completion_time,
       controlfile_type,
       blocks,
       autobackup_date,
       autobackup_sequence
from rci_backup_controlfile
>>>
 
 
define rci_backup_spfile
<<<
create or replace view rci_backup_spfile as
select db.db_key,
       bsf.bsf_key,
       bsf.bsf_recid recid,
       bsf.bsf_stamp stamp,
       bs.bs_key,
       bs.set_stamp,
       bs.set_count,
       bsf.modification_time,
       bs.status,
       bs_recid,
       bs_stamp,
       bs.completion_time,
       bsf.bytes,
       bsf.db_unique_name,
       pdb.guid
from db, bs, bsf, pdb
where db.db_key = bsf.db_key
and   bs.bs_key = bsf.bs_key
and   bs.bck_type != 'L'
and   bsf.pdb_key = pdb.pdb_key
>>>
 
define rc_backup_spfile
<<<
create or replace view rc_backup_spfile as
select db_key,
       bsf_key,
       recid,
       stamp,
       bs_key,
       set_stamp,
       set_count,
       modification_time,
       status,
       bs_recid,
       bs_stamp,
       completion_time,
       bytes,
       db_unique_name
from rci_backup_spfile
>>>
 
 
define rc_datafile_copy
<<<
create or replace view rc_datafile_copy as
select dbinc.db_key,
       dbinc.dbinc_key,
       dbinc.db_name,
       cdf.pdb_key,
       cdf.cdf_key,
       cdf.cdf_recid recid,
       cdf.cdf_stamp stamp,
       cdf.fname name,
       cdf.tag,
       cdf.file#,
       cdf.create_scn creation_change#,
       cdf.create_time creation_time,
       dbinc.reset_scn resetlogs_change#,
       dbinc.reset_time resetlogs_time,
       cdf.incr_level incremental_level,
       cdf.ckp_scn checkpoint_change#,
       cdf.ckp_time checkpoint_time,
       cdf.abs_fuzzy_scn absolute_fuzzy_change#,
       cdf.rcv_fuzzy_scn recovery_fuzzy_change#,
       cdf.rcv_fuzzy_time recovery_fuzzy_time,
       decode(cdf.onl_fuzzy,'N', 'NO', 'Y', 'YES', '?') online_fuzzy,
       decode(cdf.bck_fuzzy,'N', 'NO', 'Y', 'YES', '?') backup_fuzzy,
       cdf.blocks,
       cdf.block_size,
       cdf.completion_time,
       cdf.status,
       decode(keep_options, 0, 'NO',
                               'YES') keep,
       keep_until,
       decode(keep_options, 256,  'LOGS',
                            512,  'NOLOGS',
                            1024, 'BACKUP_LOGS',
                                  NULL) keep_options,
       decode(cdf.scanned,'N', 'NO', 'Y', 'YES', '?') scanned,
       cdf.is_recovery_dest_file,
       cdf.rsr_key,
       cdf.marked_corrupt,
       cdf.site_key,
       cdf.foreign_dbid,
       cdf.plugged_readonly,
       cdf.plugin_scn plugin_change#,
       cdf.plugin_reset_scn plugin_resetlogs_change#,
       cdf.plugin_reset_time plugin_resetlogs_time,
       cdf.sparse_backup
from dbinc, cdf
where dbinc.dbinc_key = cdf.dbinc_key
>>>
 
define rc_controlfile_copy
<<<
create or replace view rc_controlfile_copy as
select dbinc.db_key,
       dbinc.dbinc_key,
       dbinc.db_name,
       ccf.ccf_key,
       ccf.ccf_recid recid,
       ccf.ccf_stamp stamp,
       ccf.fname name,
       ccf.tag,
       dbinc.reset_scn resetlogs_change#,
       dbinc.reset_time resetlogs_time,
       ccf.ckp_scn checkpoint_change#,
       ccf.ckp_time checkpoint_time,
       ccf.create_time creation_time,
--
       ccf.blocks,
       ccf.block_size,
       ccf.min_offr_recid oldest_offline_range,
       ccf.completion_time,
       ccf.status,
       ccf.controlfile_type,
       decode(keep_options, 0, 'NO',
                               'YES') keep,
       keep_until,
       decode(keep_options, 256,  'LOGS',
                            512,  'NOLOGS',
                            1024, 'BACKUP_LOGS',
                                  NULL) keep_options,
       ccf.is_recovery_dest_file,
       ccf.rsr_key,
       ccf.site_key
from dbinc, ccf
where dbinc.dbinc_key = ccf.dbinc_key
>>>
 
 
define rc_backup_redolog
<<<
create or replace view rc_backup_redolog as
select dbinc.db_key,
       dbinc.dbinc_key,
       dbinc.db_name,
       brl.brl_key,
       brl.brl_recid recid,
       brl.brl_stamp stamp,
       bs.bs_key,
       bs.set_stamp,
       bs.set_count,
       bs.bck_type backup_type,
       bs.completion_time,
       brl.thread#,
       brl.sequence#,
       dbinc.reset_scn resetlogs_change#,
       dbinc.reset_time resetlogs_time,
       brl.low_scn first_change#,
       brl.low_time first_time,
       brl.next_scn next_change#,
       brl.next_time,
       brl.blocks,
       brl.block_size,
       bs.status,
       bs_recid,
       bs_stamp,
       bs.pieces,
       brl.terminal,
       decode(activation,'Y','YES','NO') partial 
from dbinc, bs, brl
where dbinc.dbinc_key = brl.dbinc_key
and   bs.bs_key = brl.bs_key
and   bs.bck_type = 'L'
>>>
 
 
define rc_backup_corruption
<<<
create or replace view rc_backup_corruption as
select dbinc.db_key,
       dbinc.dbinc_key,
       dbinc.db_name,
       bcb.bcb_recid recid,
       bcb.bcb_stamp stamp,
       bs.bs_key,
       bs.set_stamp,
       bs.set_count,
       bcb.piece#,
       bdf.bdf_key,
       bdf.bdf_recid,
       bdf.bdf_stamp,
       bdf.file#,
       bdf.create_scn creation_change#,
       bcb.block#,
       bcb.blocks,
       bcb.corrupt_scn corruption_change#,
       decode(bcb.marked_corrupt,'N', 'NO', 'Y', 'YES', '?') marked_corrupt,
       bcb.corruption_type
from dbinc, bs, bdf, bcb
where dbinc.dbinc_key = bdf.dbinc_key
and   bs.bs_key = bdf.bs_key
and   bdf.bdf_key = bcb.bdf_key
>>>
 
define rc_copy_corruption
<<<
create or replace view rc_copy_corruption as
select dbinc.db_key,
       dbinc.dbinc_key,
       dbinc.db_name,
       ccb.ccb_recid recid,
       ccb.ccb_stamp stamp,
       cdf.cdf_key,
       cdf.cdf_recid copy_recid,
       cdf.cdf_stamp copy_stamp,
       cdf.file#,
       cdf.create_scn creation_change#,
       ccb.block#,
       ccb.blocks,
       ccb.corrupt_scn corruption_change#,
       decode(ccb.marked_corrupt,'N', 'NO', 'Y', 'YES', '?') marked_corrupt,
       ccb.corruption_type
from  dbinc, cdf, ccb
where dbinc.dbinc_key = cdf.dbinc_key
and   cdf.cdf_key = ccb.cdf_key
and   cdf.status = 'A'
>>>
 
 
define rc_offline_range
<<<
create or replace view rc_offline_range as
select dbinc.db_key,
       dbinc.dbinc_key,
       dbinc.db_name,
       offr.offr_recid recid,
       offr.offr_stamp stamp,
       offr.file#,
       offr.create_scn creation_change#,
       offr.offline_scn offline_change#,
       offr.online_scn online_change#,
       offr.online_time,
       offr.cf_create_time,
       dbinc.reset_scn resetlogs_change#,
       dbinc.reset_time resetlogs_time,
       offr.offr_key
from dbinc, offr
where dbinc.dbinc_key = offr.dbinc_key
>>>
 
 
define rc_stored_script
<<<
create or replace view rc_stored_script as
select db.db_key,
       nvl(dbinc.db_name, 'GLOBAL') db_name,
       scr.scr_name script_name,
       scr.scr_comment script_comment
from db, dbinc, scr
where dbinc.dbinc_key(+) = db.curr_dbinc_key
and   db.db_key(+) = scr.db_key
>>>
 
define rc_stored_script_line
<<<
create or replace view rc_stored_script_line as
select db.db_key,
       scr.scr_name script_name,
       scrl.linenum line,
       scrl.text
from db, scr, scrl
where db.db_key(+) = scr.db_key
and   scr.scr_key = scrl.scr_key
>>>
 
 
define rc_proxy_datafile
<<<
create or replace view rc_proxy_datafile as
select dbinc.db_key,
       dbinc.dbinc_key,
       dbinc.db_name,
       xdf.pdb_key,
       xdf.xdf_key,
       xdf.xdf_recid recid,
       xdf.xdf_stamp stamp,
       xdf.tag,
       xdf.file#,
       xdf.create_scn creation_change#,
       xdf.create_time creation_time,
       dbinc.reset_scn resetlogs_change#,
       dbinc.reset_time resetlogs_time,
       xdf.incr_level incremental_level,
       xdf.ckp_scn checkpoint_change#,
       xdf.ckp_time checkpoint_time,
       xdf.abs_fuzzy_scn absolute_fuzzy_change#,
       xdf.rcv_fuzzy_scn recovery_fuzzy_change#,
       xdf.rcv_fuzzy_time recovery_fuzzy_time,
       decode(xdf.onl_fuzzy,'N', 'NO', 'Y', 'YES', '?') online_fuzzy,
       decode(xdf.bck_fuzzy,'N', 'NO', 'Y', 'YES', '?') backup_fuzzy,
       xdf.blocks,
       xdf.block_size,
       xdf.device_type,
       xdf.handle,
       xdf.comments,
       xdf.media,
       xdf.media_pool,
       xdf.start_time,
       xdf.completion_time,
       abs((xdf.completion_time - xdf.start_time) * 86400) elapsed_seconds,
       xdf.status,
       decode(keep_options, 0, 'NO',
                               'YES') keep,
       keep_until,
       decode(keep_options, 256,  'LOGS',
                            512,  'NOLOGS',
                            1024, 'BACKUP_LOGS',
                                  NULL) keep_options,
       xdf.rsr_key,
       xdf.site_key,
       xdf.foreign_dbid,
       xdf.plugged_readonly,
       xdf.plugin_scn plugin_change#,
       xdf.plugin_reset_scn plugin_resetlogs_change#,
       xdf.plugin_reset_time plugin_resetlogs_time
from dbinc, xdf
where dbinc.dbinc_key = xdf.dbinc_key
>>>
 
define rc_proxy_controlfile
<<<
create or replace view rc_proxy_controlfile as
select dbinc.db_key,
       dbinc.dbinc_key,
       dbinc.db_name,
       xcf.xcf_key,
       xcf.xcf_recid recid,
       xcf.xcf_stamp stamp,
       xcf.tag,
       dbinc.reset_scn resetlogs_change#,
       dbinc.reset_time resetlogs_time,
       xcf.ckp_scn checkpoint_change#,
       xcf.ckp_time checkpoint_time,
       xcf.create_time creation_time,
       xcf.block_size,
       xcf.blocks,
       xcf.min_offr_recid oldest_offline_range,
       xcf.device_type,
       xcf.handle,
       xcf.comments,
       xcf.media,
       xcf.media_pool,
       xcf.start_time,
       xcf.completion_time,
       abs((xcf.completion_time - xcf.start_time) * 86400) elapsed_seconds,
       xcf.status,
       xcf.controlfile_type,
       decode(keep_options, 0, 'NO',
                               'YES') keep,
       keep_until,
       decode(keep_options, 256,  'LOGS',
                            512,  'NOLOGS',
                            1024, 'BACKUP_LOGS',
                                  NULL) keep_options,
       xcf.rsr_key,
       xcf.site_key
from dbinc, xcf
where dbinc.dbinc_key = xcf.dbinc_key
>>>
 
define rc_proxy_archivedlog
<<<
create or replace view rc_proxy_archivedlog as
select dbinc.db_key,
       dbinc.dbinc_key,
       dbinc.db_name,
       xal.xal_key,
       xal.xal_recid recid,
       xal.xal_stamp stamp,
       xal.tag,
       xal.device_type,
       xal.handle,
       xal.comments,
       xal.media,
       xal.media_pool,
       xal.status,
       xal.thread#,
       xal.sequence#,
       dbinc.reset_scn resetlogs_change#,
       dbinc.reset_time resetlogs_time,
       xal.low_scn first_change#,
       xal.low_time first_time,
       xal.next_scn next_change#,
       xal.next_time,
       xal.blocks,
       xal.block_size,
       xal.start_time,
       xal.completion_time,
       abs((xal.completion_time - xal.start_time) * 86400) elapsed_seconds,
       xal.rsr_key,
       xal.terminal,
       decode(keep_options, 0, 'NO',
                               'YES') keep,
       keep_until,
       decode(keep_options, 256,  'LOGS',
                            512,  'NOLOGS',
                            1024, 'BACKUP_LOGS',
                                  NULL) keep_options,
       xal.site_key
from dbinc, xal
where dbinc.dbinc_key = xal.dbinc_key
>>>
 
 
define rc_database_block_corruption
<<<
create or replace view rc_database_block_corruption as
select node.db_key                 db_key,
       df.dbinc_key                dbinc_key,
       df.file#                    file#,
       bcr.block#                  block#,
       bcr.blocks                  blocks,
       bcr.corrupt_scn             corruption_change#,
       bcr.corruption_type         corruption_type
  from bcr, df,
       (select dbinc_key from dbinc where dbinc_status = 'CURRENT') dbinc,
       (select distinct db_key, site_key
          from node where bcr_in_use = 'YES') node
 where bcr.df_key = df.df_key
   and node.site_key = bcr.site_key
   and df.drop_scn is null
   and df.dbinc_key = dbinc.dbinc_key
 
union all
 
select distinct
       outer.db_key                db_key,
       outer.dbinc_key             dbinc_key,
       outer.file#                 file#,
       outer.block#                block#,
       outer.blocks                blocks,
       outer.corruption_change#    corruption_change#,
       outer.corruption_type       corruption_type
  from (select db_key, dbinc_key, file#, block#, blocks,
               corruption_change#, copy_stamp stamp, corruption_type
          from rc_copy_corruption
         union
        select bs.db_key, dbinc_key, file#, block#, blocks,
               corruption_change#, bs.stamp, corruption_type
          from rc_backup_corruption bc, rc_backup_set bs
         where bc.bs_key = bs.bs_key) outer, 
               (select distinct db_key from node where bcr_in_use = 'NO') node
       where outer.db_key = node.db_key
         and not exists (select 1
                           from rc_datafile_copy
                          where outer.db_key = db_key and
                                outer.dbinc_key = dbinc_key and
                                scanned = 'YES' and
                                outer.file# = file# and
                                outer.stamp < stamp
                          union
                         select 1
                           from rc_backup_datafile bdf, rc_backup_set bs
                          where bdf.bs_key = bs.bs_key and
                                outer.db_key = bdf.db_key and
                                outer.dbinc_key = bdf.dbinc_key and
                                outer.file# = file# and
                                outer.stamp < bs.stamp and
                                (datafile_blocks = blocks_read or 
                                 (nvl(bdf.incremental_level,0) = 0 and
                                 used_optimization='YES')))
>>>
 
define drop_rc_lbRecVar_t
<<< drop type rc_lbRecVar_t >>>
 
define drop_rc_lbRecSet_t
<<< drop type rc_lbRecSet_t >>>
 
define drop_rc_lbRec_t
<<< drop type rc_lbRec_t >>>
 
define rc_lbRec_t
<<<
   create or replace type rc_lbRec_t authid current_user as object
   (
      list_order1               NUMBER,
      list_order2               NUMBER,
      pkey                      NUMBER,
      backup_type               VARCHAR2(32),
      file_type                 VARCHAR2(32),
      keep                      VARCHAR2(3),
      keep_until                DATE,
      keep_options              VARCHAR2(13),
      status                    VARCHAR2(16),
      fname                     VARCHAR2(1024),
      tag                       VARCHAR2(32),
      media                     VARCHAR2(80),
      recid                     NUMBER,
      stamp                     NUMBER,
      device_type               VARCHAR2(255),
      block_size                NUMBER,
      completion_time           DATE,
      is_rdf                    VARCHAR2(3),
      compressed                VARCHAR2(3),
      obsolete                  VARCHAR2(3),
      bytes                     NUMBER,
 
      bs_key                    NUMBER,
      bs_count                  NUMBER,
      bs_stamp                  NUMBER,
      bs_type                   VARCHAR2(32),
      bs_incr_type              VARCHAR2(32),
      bs_pieces                 NUMBER,
      bs_copies                 NUMBER,
      bs_completion_time        DATE,
      bs_status                 VARCHAR2(16),
      bs_bytes                  NUMBER,
      bs_compressed             VARCHAR2(3),
      bs_tag                    VARCHAR2(1024),
      bs_device_type            VARCHAR2(255),
 
      bp_piece#                 NUMBER,
      bp_copy#                  NUMBER,
 
      df_file#                  NUMBER,
      df_ts#                    NUMBER,
      df_plugin_change#         NUMBER,
      df_foreign_dbid           NUMBER,
      df_tablespace             VARCHAR2(30),
      df_resetlogs_change#      NUMBER,
      df_creation_change#       NUMBER,
      df_checkpoint_change#     NUMBER,
      df_ckp_mod_time           DATE,
      df_incremental_change#    NUMBER,
 
      rl_thread#                NUMBER,
      rl_sequence#              NUMBER,
      rl_resetlogs_change#      NUMBER,
      rl_first_change#          NUMBER,
      rl_first_time             DATE,
      rl_next_change#           NUMBER,
      rl_next_time              DATE
   )
>>>
 
define rc_lbRecSet_t
<<<
   create or replace type rc_lbRecSet_t as table of rc_lbRec_t
>>>
 
define drop_rc_lbRecSetImpl_t
<<<
   drop type rc_lbRecSetImpl_t 
>>>
 
define rc_lbRecSetImpl_t
<<<
create or replace type rc_lbRecSetImpl_t authid current_user as object 
  (
  curval                number,   -- current rownum
  done                  number,   -- done with the query
  needobsolete          number,   -- user interested in obsolete col
 
  static function ODCITableStart(sctx   IN OUT rc_lbRecSetImpl_t)
    return number,
 
  member function ODCITableFetch(self   IN OUT rc_lbRecSetImpl_t, 
                                 nrows  IN     number, 
                                 objSet OUT    rc_lbRecSet_t) 
    return number,
 
  member function ODCITableClose(self   IN     rc_lbRecSetImpl_t) 
    return number
  )
>>>
 
define rc_lbRecSetImplbody_t
<<<
create or replace type body rc_lbRecSetImpl_t is
 
--
--
--
 
  static function ODCITableStart(sctx IN OUT rc_lbRecSetImpl_t) 
    return number is
  begin
--
    sctx:=rc_lbRecSetImpl_t(0, 0, 1);
    return SYS.ODCIConst.Success;
  end ODCITableStart;
 
--
--
--
--
  member function ODCITableFetch(self   IN OUT rc_lbRecSetImpl_t, 
                                 nrows  IN     number, 
                                 objSet OUT    rc_lbRecSet_t) 
    return number is
    n number := 0;
    firstCall       boolean := TRUE;
    ret             boolean := TRUE;
    redundancy      number;
    recovery_window number;
    untilTime       date;
    lbRec           dbms_rcvman.lbrec_t;
    lbCursor        dbms_rcvman.lbCursor_t;
    lbState         dbms_rcvman.lbState_t;
  begin
    objSet:=rc_lbRecSet_t();
 
--
    dbms_rcvman.resetAll;
 
    redundancy := 1;
    recovery_window := 0;
 
--
--
--
    dbms_rcvman.getRetentionPolicy(recovery_window, redundancy);
 
--
    dbms_rcvman.setAllIncarnations(TRUE);
 
--
    if (recovery_window > 0) then
      SELECT (sysdate-recovery_window) INTO untilTime from dual;
      dbms_rcvman.setUntilTime(untilTime);
    end if;
 
    dbms_rcvman.setDeviceTypeAny;
 
    if (recovery_window = 0 and redundancy = 0) then
--
       dbms_rcvman.setNeedObsoleteData(false);
    else
       if self.needobsolete = 1 then
          dbms_rcvman.setNeedObsoleteData(true);
       else
          dbms_rcvman.setNeedObsoleteData(false);
       end if;
    end if;
 
    while ret and self.done = 0 loop
      ret := dbms_rcvman.listBackup(lbRec, firstCall, FALSE, 
                                    redundancy, TRUE, lbCursor, lbState, null);
      if (lbRec.pkey is not null) then
        objSet.extend;
        n := n + 1;
        objSet(n):= rc_lbRec_t(
                            to_number(null),   -- list_order1
                            to_number(null),   -- list_order2
                            to_number(null),   -- pkey
                            to_char(null),     -- backup_type
                            to_char(null),     -- file_type
                            to_char(null),     -- keep
                            to_date(null),     -- keep_until
                            to_char(null),     -- keep_options
                            to_char(null),     -- status
                            to_char(null),     -- fname
                            to_char(null),     -- tag
                            to_char(null),     -- media
                            to_number(null),   -- recid
                            to_number(null),   -- stamp
                            to_char(null),     -- device_type
                            to_number(null),   -- block_size
                            to_date(null),     -- completion_time
                            to_char(null),     -- is_rdf
                            to_char(null),     -- compressed
                            to_char(null),     -- obsolete
                            to_number(null),   -- bytes
                            to_number(null),   -- bs_key
                            to_number(null),   -- bs_count
                            to_number(null),   -- bs_stamp
                            to_char(null),     -- bs_type
                            to_char(null),     -- bs_incr_type
                            to_number(null),   -- bs_pieces
                            to_number(null),   -- bs_copies
                            to_date(null),     -- bs_completion_time
                            to_char(null),     -- bs_status
                            to_number(null),   -- bs_bytes
                            to_char(null),     -- bs_compressed
                            to_char(null),     -- bs_tag
                            to_char(null),     -- bs_device_type
                            to_number(null),   -- bp_piece#
                            to_number(null),   -- bp_copy#
                            to_number(null),   -- df_file#
                            to_number(null),   -- df_ts#
                            to_number(null),   -- df_plugin_change#
                            to_number(null),   -- df_foreign_dbid
                            to_char(null),     -- df_tablespace
                            to_number(null),   -- df_resetlogs_change#
                            to_number(null),   -- df_creation_change#
                            to_number(null),   -- df_checkpoint_change#
                            to_date(null),     -- df_ckp_mod_time
                            to_number(null),   -- df_incremental_change#
                            to_number(null),   -- rl_thread#
                            to_number(null),   -- rl_sequence#
                            to_number(null),   -- rl_resetlogs_change#
                            to_number(null),   -- rl_first_change#
                            to_date(null),     -- rl_first_time
                            to_number(null),   -- rl_next_change#
                            to_date(null));    -- rl_next_time
        objSet(n).list_order1            := lbRec.list_order1;
        objSet(n).list_order2            := lbRec.list_order2;
        objSet(n).pkey                   := lbRec.pkey;
        objSet(n).backup_type            := lbRec.backup_type;
        objSet(n).file_type              := lbRec.file_type;
        objSet(n).keep                   := lbRec.keep;
        objSet(n).keep_until             := lbRec.keep_until;
        objSet(n).keep_options           := lbRec.keep_options;
        objSet(n).status                 := lbRec.status;
        objSet(n).fname                  := lbRec.fname;
        objSet(n).tag                    := lbRec.tag;
        objSet(n).media                  := lbRec.media;
        objSet(n).recid                  := lbRec.stamp;
        objSet(n).stamp                  := lbRec.stamp;
        objSet(n).device_type            := lbRec.device_type;
        objSet(n).block_size             := lbRec.block_size;
        objSet(n).completion_time        := lbRec.completion_time;
        objSet(n).is_rdf                 := lbRec.is_rdf;
        objSet(n).compressed             := lbRec.compressed;
        objSet(n).obsolete               := lbRec.obsolete;
        objSet(n).bytes                  := lbRec.bytes;
        objSet(n).bs_key                 := lbRec.bs_key;
        objSet(n).bs_count               := lbRec.bs_count;
        objSet(n).bs_stamp               := lbRec.bs_stamp;
        objSet(n).bs_type                := lbRec.bs_type;
        objSet(n).bs_incr_type           := lbRec.bs_incr_type;
        objSet(n).bs_pieces              := lbRec.bs_pieces;
        objSet(n).bs_copies              := lbRec.bs_copies;
        objSet(n).bs_completion_time     := lbRec.bs_completion_time;
        objSet(n).bs_status              := lbRec.bs_status;
        objSet(n).bs_bytes               := lbRec.bs_bytes;
        objSet(n).bs_compressed          := lbRec.bs_compressed;
        objSet(n).bs_tag                 := lbRec.bs_tag;
        objSet(n).bs_device_type         := lbRec.bs_device_type;
        objSet(n).bp_piece#              := lbRec.bp_piece#;
        objSet(n).bp_copy#               := lbRec.bp_copy#;
        objSet(n).df_file#               := lbRec.df_file#;
        objSet(n).df_ts#                 := lbRec.df_ts#;
        objSet(n).df_plugin_change#      := lbRec.df_plugin_change#;
        objSet(n).df_foreign_dbid        := lbRec.df_foreign_dbid;
        objSet(n).df_tablespace          := lbRec.df_tablespace;
        objSet(n).df_resetlogs_change#   := lbRec.df_resetlogs_change#;
        objSet(n).df_creation_change#    := lbRec.df_creation_change#;
        objSet(n).df_checkpoint_change#  := lbRec.df_checkpoint_change#;
        objSet(n).df_ckp_mod_time        := lbRec.df_ckp_mod_time;
        objSet(n).df_incremental_change# := lbRec.df_incremental_change#;
        objSet(n).rl_thread#             := lbRec.rl_thread#;
        objSet(n).rl_sequence#           := lbRec.rl_sequence#;
        objSet(n).rl_resetlogs_change#   := lbRec.rl_resetlogs_change#;
        objSet(n).rl_first_change#       := lbRec.rl_first_change#;
        objSet(n).rl_first_time          := lbRec.rl_first_time;
        objSet(n).rl_next_change#        := lbRec.rl_next_change#;
        objSet(n).rl_next_time           := lbRec.rl_next_time;
      end if;
      firstCall := false;
      self.curval:=self.curval+1;
      if not ret then
        self.done := 1;
      end if;
    end loop;
    return SYS.ODCIConst.Success;
  end ODCITableFetch;
 
  member function ODCITableClose(self IN rc_lbRecSetImpl_t) 
    return number is
  begin
    return SYS.ODCIConst.Success;
  end ODCITableClose;
end;
>>>
 
define drop_rc_listBackupPipe
<<< drop function rc_listBackupPipe >>>
 
define rc_listBackupPipe
<<<
  CREATE OR REPLACE FUNCTION rc_listBackupPipe 
   RETURN rc_lbRecSet_t AUTHID DEFINER PIPELINED using rc_lbRecSetImpl_t;
>>>
 
define rc_backup_files
<<<
  create or replace view rc_backup_files
       as select pkey,
                 backup_type,
                 file_type,
                 keep,
                 keep_until,
                 keep_options,
                 status,
                 fname,
                 tag,
                 media,
                 recid,
                 stamp,
                 device_type,
                 block_size,
                 completion_time,
                 compressed,
                 obsolete,
                 bytes,
                 bs_key,
                 bs_count,
                 bs_stamp,
                 bs_type,
                 bs_incr_type,
                 bs_pieces,
                 bs_copies,
                 bs_completion_time,
                 bs_status,
                 bs_bytes,
                 bs_compressed,
                 bs_tag,
                 bs_device_type,
                 bp_piece#,
                 bp_copy#,
                 df_file#,
                 df_tablespace,
                 df_resetlogs_change#,
                 df_creation_change#,
                 df_checkpoint_change#,
                 df_ckp_mod_time,
                 rl_thread#,
                 rl_sequence#,
                 rl_resetlogs_change#,
                 rl_first_change#,
                 rl_first_time,
                 rl_next_change#,
                 rl_next_time
                 from TABLE(rc_listBackupPipe)
>>>
 
 
define drop_rc_RangeRecVar_t
<<< drop type rc_RangeRecVar_t >>>
 
define drop_rc_RangeRecSet_t
<<< drop type rc_RangeRecSet_t >>>
 
define drop_rc_RangeRec_t
<<< drop type rc_RangeRec_t >>>
 
define rc_RangeRec_t
<<<
   create or replace type rc_RangeRec_t authid current_user as object
   (
      db_key            NUMBER,
      site_key          NUMBER,
      high_time         DATE,
      low_time          DATE,
      low_scn           NUMBER,
      high_scn          NUMBER,
      low_dbinc_key     NUMBER,
      high_dbinc_key    NUMBER
   )
>>>
 
define rc_RangeRecSet_t
<<<
    create or replace type rc_RangeRecSet_t as table of rc_RangeRec_t
>>>
 
define drop_rc_RangeRecSetImpl_t
<<<
   drop type rc_RangeRecSetImpl_t
>>>
 
define rc_RangeRecSetImpl_t
<<<
create or replace type rc_RangeRecSetImpl_t authid current_user as object
  (
  curval                number,        -- current rownum
  done                  number,        -- done with the query
  opCode                varchar2(20),  -- backup/log location
 
  static function ODCITableStart(sctx   IN OUT rc_RangeRecSetImpl_t,
                                 opCode IN     varchar2)
    return number,
 
  member function ODCITableFetch(self   IN OUT rc_RangeRecSetImpl_t,
                                 nrows  IN     number,
                                 objSet OUT    rc_RangeRecSet_t)
    return number,
 
  member function ODCITableClose(self   IN     rc_RangeRecSetImpl_t)
    return number
   )
>>>
 
define rc_RangeRecSetImplbody_t
<<<
create or replace type body rc_RangeRecSetImpl_t is
  
  static function ODCITableStart(sctx   IN OUT rc_RangeRecSetImpl_t,
                                 opCode IN varchar2)
    return number is
    PRAGMA AUTONOMOUS_TRANSACTION;
  begin
--
    sctx:=rc_RangeRecSetImpl_t(0, 0, opCode);   
    return SYS.ODCIConst.Success;
  end ODCITableStart;
  
  member function ODCITableFetch(self   IN OUT rc_RangeRecSetImpl_t,
                                 nrows  IN     number,
                                 objSet OUT    rc_RangeRecSet_t)
    return number is
    PRAGMA AUTONOMOUS_TRANSACTION;
 
    n                number := 0;
    i                number;
    indx             number := 0;
    ret              boolean;
    isOrs            number := 0;
    site_aware       boolean;
    dbid             number := 0;
    dbkey            number := 0;
    sitekey          number := 0;
    single_site      boolean := false;  -- true means we are interested in
--
    hashval_old      number;
    hashval_new      number;
    high_bp_key_new  number := 0;
    last_do_key_new  number := 0;
    valfound         boolean;
    no_of_entries    number := 0;
    no_of_db         number := 0;
    dev_type       varchar(32);
    high_bp_key_old  number;
    last_do_key_old  number;
    max_range_scn    number;
    maxScnExist      boolean;
    maxScn           number;
    maxTime          date;
    maxDbIncKey      number;
    maxRlgScn        number;
    maxRlgTime       date;
    logMissing       boolean;
    logBreakPointScn number;
    logBreakPointTime date;
    logBreakDbIncKey  number;
    logBreakRlgScn    number;
    logBreakRlgTime   date;
    restoreRangeTab  dbms_rcvman.restoreRangeTab_t;
 
    CURSOR getAllDb_c IS SELECT db_key, db_id FROM db;
    CURSOR getAllSite_c IS SELECT site_key, db.db_key, db_unique_name, db_id  
           FROM node, db WHERE node.db_key = db.db_key order by db_key;
    CURSOR restore_range_c ( dbkey_p IN number, dev_type_p IN varchar2)
           IS SELECT * FROM rrcache
             WHERE db_key = dbkey_p AND range_type=dev_type_p; 
 
    dbDetail         getAllDb_c%rowtype;
    siteDetail       getAllSite_c%rowtype;
    restore_range_r  restore_range_c%rowtype;
 
  begin
    dbkey := dbms_rcvman.getDbKey;
 
--
    if dbkey is null then
       single_site := false;
       open getAllDb_c;
       open getAllSite_c;
    else  -- user is interested for a particular db
       SELECT db_id INTO dbid from db where db_key = dbkey; 
       single_site := true;
    end if;
    
    objSet := rc_RangeRecSet_t();
 
    if (single_site = false) then
       dbms_rcvman.resetAll;
    end if;
 
    dbms_rcvman.setAllIncarnations(TRUE);
 
--
    if (substr(opCode,  1, 2) = 'RA') then
       isOrs := 1;
    else
       isOrs := 0;
    end if;
 
--
    dbms_rcvman.resetDeviceType;
 
--
    if (isOrs = 1) then
       dbms_rcvman.setDeviceType('SBT_TAPE');
       if (substr(opCode,  4, 3) = 'ANY') then
          dev_type := 'RA$ANY';
       elsif (substr(opCode,  4, 4) = 'DISK') then
          dev_type := 'RA$DISK';
       elsif (substr(opCode,  4, 3) = 'SBT') then
          dev_type := 'RA$SBT';
       end if;
    else
       if (substr(opCode,  4, 3) = 'ANY') then
          dbms_rcvman.setDeviceTypeAny;
          dev_type := 'RC$ANY';
       elsif (substr(opCode,  4, 4) = 'DISK') then
          dbms_rcvman.setDeviceType('DISK');
          dev_type := 'RC$DISK';
       elsif (substr(opCode,  4, 3) = 'SBT') then
          dbms_rcvman.setDeviceType('SBT_TAPE');
          dev_type := 'RC$SBT';
       end if;
    end if;
 
    if ((substr(opCode,  8, 10) = 'SITE_AWARE') or
        (substr(opCode,  9, 10) = 'SITE_AWARE')) then
       site_aware := TRUE;
    else
       site_aware := FALSE;
    end if;
 
--
    WHILE self.done = 0 LOOP
      n := n + 1;
 
      exit when n = 2 and single_site = true;
 
      IF (isOrs = 1) THEN
        if (single_site = false) then
           fetch getAllDb_c into dbDetail;
           exit when getAllDb_c%NOTFOUND;
           dbkey := dbDetail.db_key;
           dbid := dbDetail.db_id;
        end if;
      ELSE
        if (single_site = false) then
           fetch getAllSite_c into siteDetail;
           exit when getAllSite_c%NOTFOUND;
           dbkey := siteDetail.db_key;
           dbid := siteDetail.db_id;
           sitekey := siteDetail.site_key;
        end if;
      END IF;
 
--
      select max(max_bp_key) into high_bp_key_old from rrcache
         where db_key = dbkey and range_type = dev_type;
      select max(last_do_key) into last_do_key_old from rrcache
         where db_key = dbkey and range_type = dev_type;
 
--
      IF (isOrs = 1) THEN
        SELECT NVL(MAX(bp_key), 0) INTO  high_bp_key_new FROM 
          (SELECT bp_key FROM bp  
             WHERE db_key = dbkey
               ORDER BY 1 DESC)
          WHERE ROWNUM = 1;
      ELSE
        high_bp_key_new := 0;
      END IF;
  
      SELECT NVL(MAX(curr_value), 0) INTO last_do_key_new
        FROM do_seq
        WHERE db_key = dbkey;
 
      valfound := FALSE;
 
--
--
--
--
      IF (isOrs = 0) THEN
         valfound := FALSE;
--
--
--
      ELSIF (high_bp_key_old < high_bp_key_new 
          and last_do_key_new = last_do_key_old)
      THEN
         dbms_rcvman.setRestoreRangeDevTyp(dev_type);
         ret := dbms_rcvman.setLocalOrsSiteKey(dbid);
 
--
--
--
         IF ret = TRUE THEN 
            maxScnExist  := dbms_rcvman.getMaxRedoSCN(maxScn, maxTime, 
                                                      maxDbIncKey, maxRlgScn, 
                                                      maxRlgTime, isOrs);
            IF (maxScnExist) THEN
               SELECT nvl(max(high_scn), 0) INTO max_range_scn  
                 FROM rrcache
                 WHERE db_key = dbkey AND range_type = dev_type AND
                    high_scn < maxScn;
--
--
               logMissing := dbms_rcvman.findLogBreakPoint(logBreakPointScn,
                                                           logBreakPointTime,
                                                           logBreakDbIncKey, 
                                                           logBreakRlgScn,
                                                           logBreakRlgTime, 
                                                           max_range_scn, 
                                                           maxScn, isOrs); 
               IF (logMissing = FALSE and max_range_scn > 0) THEN
                  UPDATE rrcache SET high_scn = maxScn,
                      high_time = maxTime, high_dbinc_key = maxDbIncKey,
                      last_updated = sysdate 
                    WHERE db_key = dbkey and range_type = dev_type and 
                          high_scn = max_range_scn;
                  commit;
                  valfound := TRUE;
               END IF;
            END IF;
         END IF;
 
         dbms_rcvman.resetLocalOrsSiteKey;
         dbms_rcvman.resetRestoreRangeDevTyp;  
      ELSIF (high_bp_key_old = high_bp_key_new 
             and last_do_key_new = last_do_key_old) 
      THEN
         valfound := true;
      END IF;
 
      if valfound = false then
        if single_site = false then
           if (isOrs = 1) then
               dbms_rcvman.setdatabase(NULL, NULL, NULL, dbDetail.db_id);
           else
               dbms_rcvman.setdatabase(db_name        => NULL,
                                      reset_scn      => NULL,
                                      reset_time     => NULL,
                                      db_id          => siteDetail.db_id,
                                      db_unique_name =>
                                                    siteDetail.db_unique_name,
                                     site_aware     => site_aware,
                                     dummy_instance => FALSE,
                                     ors_instance   => FALSE);
 
           end if;
        end if;
 
        ret := dbms_rcvman.getRestoreRangeSet(restoreRangeTab,
                                              opCode,
                                              dbid);
      end if;
 
--
--
      IF (valfound = true) then
        OPEN restore_range_c(dbkey, dev_type);
        loop
          FETCH restore_range_c INTO restore_range_r;
          EXIT WHEN restore_range_c%NOTFOUND;
          objSet.extend;
          indx := indx + 1;
          objSet(indx) := rc_RangeRec_t(
                                  to_number(null),
                                  to_number(null),
                                  to_date(null),
                                  to_date(null),
                                  to_number(null),
                                  to_number(null),
                                  to_number(null),
                                  to_number(null));
          objSet(indx).db_key         := dbkey;
          objSet(indx).site_key       := sitekey;
          objSet(indx).low_time         := restore_range_r.low_time;
          objSet(indx).high_time        := restore_range_r.high_time;
          objSet(indx).low_scn          := restore_range_r.low_scn;
          objSet(indx).high_scn         := restore_range_r.high_scn;
          objSet(indx).low_dbinc_key    := restore_range_r.low_dbinc_key;
          objSet(indx).high_dbinc_key   := restore_range_r.high_dbInc_key;
        end loop;
        CLOSE restore_range_c;
 
--
--
      ELSE
        no_of_entries := 0;
        i := null;
--
        DELETE FROM rrcache where db_key = dbkey and
          range_type = dev_type;
        commit;
        loop
          if (i is null) then
             i := restoreRangeTab.first;
          else
             i := restoreRangeTab.next(i);
          end if;
          exit when i is NULL;
     
          if (restoreRangeTab(i).isValidRange = TRUE) then
            objSet.extend;
            indx := indx + 1;
            objSet(indx) := rc_RangeRec_t(
                                  to_number(null),
                                  to_number(null),
                                  to_date(null),
                                  to_date(null),
                                  to_number(null),
                                  to_number(null),
                                  to_number(null),
                                  to_number(null));
            if (ret = TRUE) then
              no_of_entries := no_of_entries + 1;
              objSet(indx).db_key         := dbkey;
              objSet(indx).site_key       := sitekey;
 
              objSet(indx).low_time         := restoreRangeTab(i).lowTime;
              objSet(indx).high_time        := restoreRangeTab(i).highTime;
              objSet(indx).low_scn          := restoreRangeTab(i).lowScn;
              objSet(indx).high_scn         := restoreRangeTab(i).highScn;
              objSet(indx).low_dbinc_key    := restoreRangeTab(i).lowDbIncKey;
              objSet(indx).high_dbinc_key   := restoreRangeTab(i).highDbIncKey;
            end if;
          end if;
 
--
          if restoreRangeTab(i).isValidRange = TRUE and ret = TRUE then
            INSERT INTO rrcache(
                          db_key,
                          low_time,
                          high_time,
                          low_scn,
                          high_scn,
                          low_dbinc_key,
                          high_dbinc_key,
                          range_type,
                          max_bp_key,
                          last_do_key,
                          last_updated) values
              (dbkey, restoreRangeTab(i).lowTime,
               restoreRangeTab(i).highTime, restoreRangeTab(i).lowScn,  
               restoreRangeTab(i).highScn, restoreRangeTab(i).lowDbIncKey,  
               restoreRangeTab(i).highDbIncKey, dev_type, high_bp_key_new,
               last_do_key_new, sysdate);
            commit;
          end if;
        end loop;  -- loop ends for each restore range of a database
 
      END IF;  -- end of if (valfound = true)
 
--
      if (single_site = false) then
         dbms_rcvman.resetdbkey;
      end if;
      self.curval := self.curval + 1;
    END LOOP;   -- loop ends for each database
 
--
    if (single_site = false) then
       dbms_rcvman.resetdbkey;
    end if;
    self.done := 1;
    if (single_site = false) then
      close getAllDb_c;
      close getAllSite_c;
    end if;
 
    return SYS.ODCIConst.Success;
 
    EXCEPTION
      WHEN others THEN
      dbms_rcvman.resetDeviceType;
      if getAllDb_c%ISOPEN then
         close getAllDb_c;
      end if;
      if getAllSite_c%ISOPEN then
         close getAllSite_c;
      end if;
      return SYS.ODCIConst.Error;
  end ODCITableFetch;
 
  member function ODCITableClose(self IN rc_RangeRecSetImpl_t)
    return number is
  begin
    return SYS.ODCIConst.Success;
  end ODCITableClose;
end;
>>>
 
 
define drop_rc_listRsRangePipe
<<< drop function rc_listRsRangePipe >>>
 
define rc_listRsRangePipe
<<<
  CREATE OR REPLACE FUNCTION rc_listRsRangePipe (opCode IN varchar2)
   RETURN rc_RangeRecSet_t AUTHID DEFINER PIPELINED using rc_RangeRecSetImpl_t;
>>>
 
define rc_restore_range
<<<
  create or replace view rc_restore_range
       as select db_key,
                 site_key,
                 low_time,
                 high_time,
                 low_scn,
                 high_scn,
                 low_dbinc_key,
                 high_dbinc_key
                 from TABLE(rc_listRsRangePipe('RC$ANY$SITE_AWARE'))
>>>
 
define rc_disk_restore_range
<<<
  create or replace view rc_disk_restore_range 
       as select db_key,
                 site_key,
                 low_time,
                 high_time,
                 low_scn,
                 high_scn,
                 low_dbinc_key,
                 high_dbinc_key
                 from TABLE(rc_listRsRangePipe('RC$DISK$SITE_AWARE'))
>>>
 
define rc_sbt_restore_range
<<<
  create or replace view rc_sbt_restore_range
       as select db_key,
                 site_key,
                 low_time,
                 high_time,
                 low_scn,
                 high_scn,
                 low_dbinc_key,
                 high_dbinc_key
                 from TABLE(rc_listRsRangePipe('RC$SBT$SITE_AWARE'))
>>>
 
define rc_rman_status
<<<
create or replace view rc_rman_status as
select dbinc.db_key,
       dbinc.dbinc_key,
       dbinc.db_name,
       rsr.rsr_recid  recid,
       rsr.rsr_stamp  stamp,
       rsr.rsr_key    rsr_key,
       rsr.rsr_pkey   parent_key,
       nvl(rsr.rsr_l0key, rsr.rsr_key) session_key,
       rsr.rsr_type   row_type,
       rsr.rsr_level  row_level,
       rsr.rsr_oper   operation,
       rsr.rsr_status status,
       rsr.rsr_cmdid  command_id,
       rsr.rsr_mbytes mbytes_processed,
       rsr.rsr_start  start_time,
       rsr.rsr_end    end_time,
       nvl(rsr.rsr_l0key, rsr.rsr_key) job_key,
       rsr.rsr_ibytes input_bytes,
       rsr.rsr_obytes output_bytes,
       rsr.rsr_optimized optimized,
       rsr.rsr_otype   object_type,
       rsr.rsr_srecid  session_recid,
       rsr.rsr_sstamp  session_stamp,
       rsr.rsr_odevtype output_device_type,
       rsr.site_key     site_key,
       decode(rsr.rsr_osb_allocated, 'Y', 'YES', 'NO') osb_allocated
from dbinc, rsr
where dbinc.dbinc_key = rsr.dbinc_key
>>>
 
define drop_rc_rout
<<< drop table rout >>>
 
define drop_rc_rman_output
<<< drop view rc_rman_output >>>
 
define rc_rman_output
<<<
create or replace view rc_rman_output as
select db_key,
       rsr_key,
       site_key,
       rout_skey      session_key,
       rout_recid     recid,
       rout_stamp     stamp,
       rout_text      output
from rout
>>>
 
define rc_rman_backup_subjob_details
<<<
create or replace view RC_RMAN_BACKUP_SUBJOB_DETAILS
as select a.*,
   decode(nvl(b.autocnt,0), 0, 'NO', 'YES') autobackup_done,
   decode(status_weight, 2000, 'FAILED',
                         1900, 'RUNNING WITH ERRORS',
                         1500, 'RUNNING WITH WARNINGS',
                         1001, 'RUNNING',
                          900, 'COMPLETED WITH ERRORS',
                          500, 'COMPLETED WITH WARNINGS',
                          001, 'COMPLETED',
                          'FAILED') status,
   decode(input_type_weight,9, 'DB FULL',
                             8, 'RECVR AREA',
                             7, 'DB INCR',
                             6, 'DATAFILE FULL',
                             5, 'DATAFILE INCR',
                             4, 'ARCHIVELOG',
                             3, 'CONTROLFILE',
                             2, 'SPFILE', 
                             1, 'BACKUPSET', null) input_type,
   decode(optimized_weight, 1, 'YES', 'NO') optimized,
   nvl(b.autocnt,0) autobackup_count,
   case when input_bytes/decode(output_bytes,0,null,output_bytes)>1
        then input_bytes/decode(output_bytes,0,null,output_bytes) else 1 end
        compression_ratio,   
   dbms_rcvman.Num2DisplaySize(input_bytes)  input_bytes_display,
   dbms_rcvman.Num2DisplaySize(output_bytes)  output_bytes_display 
from ( select unique db_key, db_name, session_key,
       session_recid, session_stamp, operation, command_id,
       min(start_time) over
          (partition by session_key, operation) start_time,
       max(end_time) over
           (partition by session_key, operation) end_time,
       sum(input_bytes) over
           (partition by session_key, operation) input_bytes,
       sum(output_bytes) over
           (partition by session_key, operation) output_bytes,
       max(status_weight) over
           (partition by session_key, operation)status_weight,
       max(optimized_weight) over
           (partition by session_key, operation)
           optimized_weight,
       max(input_type_weight) over
           (partition by session_key, operation)
           input_type_weight,
       decode(count(distinct output_device_type) over 
                  (partition by session_key, operation),1,
             first_value(output_device_type) over 
                  (partition by session_key, operation),0, 
             null, '*') output_device_type,
       decode(count(distinct osb_allocated) over 
                  (partition by session_key, operation),1,
             first_value(osb_allocated) over 
                  (partition by session_key, operation),0, 
             'NO', '*') backed_by_osb
    from (select  d.*,
                 decode(status, 'RUNNING', 1001,
                  'RUNNING WITH WARNINGS', 1500, 
                    'RUNNING WITH ERRORS', 1900, 
                              'COMPLETED', 0001, 
                'COMPLETED WITH WARNINGS', 500, 
                  'COMPLETED WITH ERRORS', 900, 
                                 'FAILED', 2000, 2000) status_weight,
             decode(optimized,'YES', 1, 0) optimized_weight,
             decode(object_type, 'DB FULL', 9,
                              'RECVR AREA', 8, 
                                 'DB INCR', 7, 
                           'DATAFILE FULL', 6, 
                           'DATAFILE INCR', 5, 
                              'ARCHIVELOG', 4, 
                             'CONTROLFILE', 3, 
                                  'SPFILE', 2, 
                               'BACKUPSET', 1, 0) input_type_weight
         from
         rc_rman_status d
         where operation like 'BACKUP%' and row_level=1)) a,
( select session_key, count(*) autocnt from rc_rman_status 
  where operation like '%AUTOBACKUP%' and row_level > 1 
  group by session_key ) b
where a.session_key=b.session_key (+)
>>>
 
define rc_rman_backup_job_details
<<<
create or replace view RC_RMAN_BACKUP_JOB_DETAILS as
select a.*,
   dbms_rcvman.Num2DisplaySize(input_bytes) input_bytes_display,
   dbms_rcvman.Num2DisplaySize(output_bytes) output_bytes_display,
   dbms_rcvman.Num2DisplaySize(input_bytes_per_sec) input_bytes_per_sec_display,
   dbms_rcvman.Num2DisplaySize(output_bytes_per_sec) output_bytes_per_sec_display,
   dbms_rcvman.Sec2DisplayTime(elapsed_seconds) time_taken_display
from
(select unique a.*,
   decode(autobackup_count, 0, 'NO', 'YES') autobackup_done,
   decode(status_weight, 2000, 'FAILED',
                         1900, 'RUNNING WITH ERRORS',
                         1500, 'RUNNING WITH WARNINGS',
                         1001, 'RUNNING',
                          900, 'COMPLETED WITH ERRORS',
                          500, 'COMPLETED WITH WARNINGS',
                          001, 'COMPLETED',
                          'FAILED') status,
   decode(input_type_weight,9, 'DB FULL',
                             8, 'RECVR AREA',
                             7, 'DB INCR',
                             6, 'DATAFILE FULL',
                             5, 'DATAFILE INCR',
                             4, 'ARCHIVELOG',
                             3, 'CONTROLFILE',
                             2, 'SPFILE', 
                             1, 'BACKUPSET', null) input_type,
   decode(optimized_weight, 1, 'YES', 'NO') optimized,
   abs(a.end_time-a.start_time)*86400 elapsed_seconds,
   case when 
     a.input_bytes/decode(a.output_bytes,0,null,a.output_bytes)>1
   then a.input_bytes/decode(a.output_bytes,0,null,a.output_bytes)
   else 1 end compression_ratio,
   a.input_bytes/(decode(a.end_time-a.start_time, 0, 1,
                     abs(a.end_time-a.start_time))*86400) input_bytes_per_sec,
   a.output_bytes/(decode(a.end_time-a.start_time, 0, 1,
                     abs(a.end_time-a.start_time))*86400) output_bytes_per_sec
       from
 (select db_key, db_name, session_key, session_recid, session_stamp, command_id,
       min(start_time) over
          (partition by session_key) start_time,
       max(end_time) over
           (partition by session_key) end_time,
       sum(input_bytes) over
           (partition by session_key) input_bytes,
       sum(output_bytes) over
           (partition by session_key) output_bytes,
       max(status_weight) over
           (partition by session_key)status_weight,
       max(optimized_weight) over
           (partition by session_key)
           optimized_weight,
       max(input_type_weight) over
           (partition by session_key)
           input_type_weight,
       decode(count(distinct output_device_type) over 
                  (partition by session_key),1,
             first_value(output_device_type) over 
                  (partition by session_key),0, 
             null, '*') output_device_type,
       sum(autobackup_count) over
           (partition by session_key) autobackup_count,
       backed_by_osb
  from RC_RMAN_BACKUP_SUBJOB_DETAILS) a) a
>>>
 
define rc_backup_set_details
<<<
create or replace view RC_BACKUP_SET_DETAILS as
select unique b.session_key,  b.session_recid, b.session_stamp, 
              a.db_key, f.db_name,
              a.bs_key, a.RECID, a.stamp,
              a.set_stamp, a.set_count, a.backup_type, a.controlfile_included,
              a.incremental_level, a.pieces, a.start_time, a.completion_time,
              a.elapsed_seconds, a.block_size, a.keep, a.keep_until,
              a.keep_options, a.device_type, a.compressed,
              a.num_copies, a.output_bytes,
              a.original_input_bytes, 
              case when a.compression_ratio>1 then
                a.compression_ratio else 1 end compression_ratio, 'A' status,
              a.original_inprate_bytes, a.output_rate_bytes,
   dbms_rcvman.Num2DisplaySize(original_input_bytes) 
      original_input_bytes_display,
   dbms_rcvman.Num2DisplaySize(output_bytes) output_bytes_display,
   dbms_rcvman.Num2DisplaySize(original_inprate_bytes) 
      original_inprate_bytes_display,
   dbms_rcvman.Num2DisplaySize(output_rate_bytes) output_rate_bytes_display,
   dbms_rcvman.Sec2DisplayTime(elapsed_seconds) time_taken_display,
   a.encrypted, a.backed_by_osb
   from 
   (
   select unique a.*,
       b.rsr_key,
       decode(b.devcnt, 1, first_value(b.device_type) over 
                                      (partition by b.bs_key), 
                            '*') device_type, b.compressed,
        count(distinct copy#)
             over (partition by b.bs_key) num_copies,
        b.output_bytes output_bytes, 
        c.original_input_bytes,
        c.original_input_bytes /
          (decode(b.output_bytes,0,c.original_input_bytes,
                  b.output_bytes)) compression_ratio,
        c.original_input_bytes/
                (decode(a.elapsed_seconds, 0, 1, a.elapsed_seconds))
                original_inprate_bytes,
        b.output_bytes/
                (decode(a.elapsed_seconds, 0, 1, a.elapsed_seconds))
                output_rate_bytes,
        b.encrypted, b.backed_by_osb
   from rc_backup_set a,
   (select bs_key, device_type, status,
    count(distinct device_type) over (partition by bs_key)devcnt,
    compressed,
    sum(bytes) over (partition by bs_key, copy#) output_bytes, 
    copy#, rsr_key, 
    count(piece#) over (partition by bs_key, copy#) npieces,
    encrypted, backed_by_osb
    from rc_backup_piece where status = 'A') b,
   (
    select bs_key,
      sum(original_input_bytes)  original_input_bytes
    from
    (
      select bs_key,
        sum((datafile_blocks+1)*block_size) 
           over (partition by bs_key) original_input_bytes
      from rc_backup_datafile
      union
      select bs_key,
        sum((blocks+1)*block_size) 
          over (partition by bs_key) original_input_bytes
      from rc_backup_controlfile
      union
      select bs_key,
        sum(bytes) over (partition by bs_key) original_input_bytes
      from rc_backup_spfile
    ) group by bs_key
    union
    select bs_key,
      sum((blocks+1)*block_size)
       over (partition by bs_key) original_input_bytes
    from rc_backup_redolog
    ) c
   where a.bs_key=b.bs_key and
         a.bs_key=c.bs_key and
         a.pieces=b.npieces
   ) a,
   (select session_key, session_recid, session_stamp, recid, stamp, rsr_key,
    start_time, end_time, db_key, db_name
    from rc_rman_status) b,
   (select db_key, name "DB_NAME" from rc_database) f,
   (select /*+ no_merge */ dbms_rcvman.sv_getsessionkey skey from dual) c,
   (select /*+ no_merge */ dbms_rcvman.sv_getsessionfromTimeRange fTime
        from dual) d,
   (select /*+ no_merge */ dbms_rcvman.sv_getsessionuntilTimeRange uTime
        from dual) e
    where  a.rsr_key = b.rsr_key (+) and 
           a.db_key = f.db_key and
           (c.skey is null or c.skey = b.session_key) and
           (d.fTime is null or d.fTime <= b.start_time) and
           (e.uTime is null or e.uTime >= b.end_time)
>>>
 
define rc_backup_piece_details
<<<
create or replace view RC_BACKUP_PIECE_DETAILS as
select unique b.session_key,b.session_recid,b.session_stamp,
              a.*,
   dbms_rcvman.Num2DisplaySize(bytes) size_bytes_display
   from 
   (select f.db_name, c.*
   from rc_backup_set a, 
   (select rc_backup_piece.*,
        count(piece#) over 
            (partition by bs_key, copy#) pieces_per_set
    from rc_backup_piece
    where status = 'A') c,
    (select db_key, name "DB_NAME" from rc_database) f
    where a.bs_key = c.bs_key and
          a.db_key = f.db_key and
          a.pieces = c.pieces_per_set) a, 
   (select session_key, session_recid, session_stamp, recid, stamp, rsr_key,
           start_time, end_time, db_key, db_name
    from rc_rman_status) b,
   (select /*+ no_merge */ dbms_rcvman.sv_getsessionkey skey from dual) c,
   (select /*+ no_merge */ dbms_rcvman.sv_getsessionfromTimeRange fTime
        from dual) d,
   (select /*+ no_merge */ dbms_rcvman.sv_getsessionuntilTimeRange uTime
        from dual) e
    where  a.status = 'A' and
           a.rsr_key = b.rsr_key (+) and 
           (c.skey is null or c.skey = b.session_key) and
           (d.fTime is null or d.fTime <= b.start_time) and
           (e.uTime is null or e.uTime >= b.end_time)
>>>
 
define rc_backup_copy_details
<<<
create or replace view RC_BACKUP_COPY_DETAILS as
select a.*,
   dbms_rcvman.Num2DisplaySize(output_bytes) output_bytes_display from
(select b.session_key, b.session_recid, b.session_stamp, 
        a.*
  from
   ((select db_key, db_name, rsr_key, cdf_key copy_key, file#, name, tag,
       creation_change#, 
       creation_time, checkpoint_change#, checkpoint_time,
       marked_corrupt, (blocks+1)*block_size output_bytes,
       completion_time, null controlfile_type, keep, keep_until,
       keep_options, is_recovery_dest_file, sparse_backup
  from rc_datafile_copy where status='A')
  union
   (select db_key, db_name, rsr_key, ccf_key copy_key, 0, name, tag,
       null creation_change#, 
       creation_time, checkpoint_change#, checkpoint_time, 
       null, (blocks +1)*block_size output_bytes,
       completion_time, controlfile_type, keep, keep_until,
       keep_options, is_recovery_dest_file, 'NO' sparse_backup
  from rc_controlfile_copy where status='A')) a, rc_rman_status b,
   (select /*+ no_merge */ dbms_rcvman.sv_getsessionkey skey from dual) c,
   (select /*+ no_merge */ dbms_rcvman.sv_getsessionfromTimeRange fTime
        from dual) d,
   (select /*+ no_merge */ dbms_rcvman.sv_getsessionuntilTimeRange uTime
        from dual) e
    where  a.rsr_key = b.rsr_key (+) and 
           (c.skey is null or c.skey = b.session_key) and
           (d.fTime is null or d.fTime <= b.start_time) and
           (e.uTime is null or e.uTime >= b.end_time))a
>>>
 
define rc_proxy_copy_details
<<<
create or replace view RC_PROXY_COPY_DETAILS as
select a.*,
   dbms_rcvman.Num2DisplaySize(output_bytes) output_bytes_display from
(select b.session_recid session_key, b.session_recid, b.session_stamp, 
        a.*
   from 
    (select db_key, db_name, rsr_key, xdf_key copy_key, file#, handle,comments, 
       media,media_pool,
       tag, creation_change#, 
       creation_time, checkpoint_change#, checkpoint_time,
       (blocks+1)*block_size output_bytes, 
       completion_time, null controlfile_type, keep, keep_until,
       keep_options
    from rc_proxy_datafile where status = 'A'
    union
    select db_key, db_name, rsr_key, xcf_key copy_key, 0, handle,comments, 
       media,media_pool,
       tag, null creation_change#, 
       creation_time, checkpoint_change#, checkpoint_time, 
       (blocks+1)*block_size output_bytes,
       completion_time, controlfile_type, keep, keep_until,
       keep_options
   from rc_proxy_controlfile where status='A') a, rc_rman_status b,
   (select /*+ no_merge */ dbms_rcvman.sv_getsessionkey skey from dual) c,
   (select /*+ no_merge */ dbms_rcvman.sv_getsessionfromTimeRange fTime
        from dual) d,
   (select /*+ no_merge */ dbms_rcvman.sv_getsessionuntilTimeRange uTime
        from dual) e
    where  a.rsr_key = b.rsr_key (+) and 
           (c.skey is null or c.skey = b.session_key) and
           (d.fTime is null or d.fTime <= b.start_time) and
           (e.uTime is null or e.uTime >= b.end_time))a
>>>
 
define rc_proxy_archivelog_details
<<<
create or replace view RC_PROXY_ARCHIVELOG_DETAILS as
select a.*,
   dbms_rcvman.Num2DisplaySize(output_bytes) output_bytes_display from
(select b.rsr_key session_key, b.session_recid, b.session_stamp, 
        a.db_key, a.db_name,
       a.recid copy_key, a.thread#, a.sequence#, a.resetlogs_change#,
       a.resetlogs_time, a.handle, a.media, a.media_pool,
       a.tag, a.first_change#, a.next_change#, a.first_time, a.next_time,
       (a.blocks+1)*a.block_size output_bytes, a.completion_time
  from rc_proxy_archivedlog a, rc_rman_status b,
   (select /*+ no_merge */ dbms_rcvman.sv_getsessionkey skey from dual) c,
   (select /*+ no_merge */ dbms_rcvman.sv_getsessionfromTimeRange fTime
        from dual) d,
   (select /*+ no_merge */ dbms_rcvman.sv_getsessionuntilTimeRange uTime
        from dual) e
    where  a.status = 'A' and
           a.rsr_key = b.rsr_key (+) and 
           (c.skey is null or c.skey = b.session_key) and
           (d.fTime is null or d.fTime <= b.start_time) and
           (e.uTime is null or e.uTime >= b.end_time))a
>>>
 
define rc_backup_datafile_details
<<<
CREATE OR REPLACE VIEW RC_BACKUP_DATAFILE_DETAILS AS
select a.*, b.con_id, b.pdb_name, b.pdb_key, b.ts#, b.name tsname,
   dbms_rcvman.Num2DisplaySize(filesize) filesize_display from
(select unique 'BACKUPSET' btype, b.bs_key btype_key, 
       b.session_key,
       b.session_recid,
       b.session_stamp,
       b.db_key, b.db_name,
       a.set_stamp id1, 
       b.set_count id2, file#, 
       creation_change#, creation_time,
       resetlogs_change#, resetlogs_time, a.incremental_level, 
       incremental_change#, checkpoint_change#, checkpoint_time,
       marked_corrupt,
       (datafile_blocks+1)*a.block_size filesize,
       (datafile_blocks+1)/(blocks+1) compression_ratio,
       a.sparse_backup
   from rc_backup_datafile a, rc_backup_set_details b where
        a.bs_key = b.bs_key
union
select unique 'IMAGECOPY' btype, a.cdf_key btype_key, 
       b.session_key,
       b.session_recid,
       b.session_stamp,
       a.db_key, a.db_name,
       a.recid, a.stamp, file#, 
       creation_change#, creation_time,
       resetlogs_change#, resetlogs_time, incremental_level, 
       0 incremental_change#, checkpoint_change#, checkpoint_time,
       marked_corrupt,
       (blocks+1)*block_size filesize,
       1 compression_ratio,
       a.sparse_backup
   from rc_datafile_copy a, rc_rman_status b,
   (select /*+ no_merge */ dbms_rcvman.sv_getsessionkey skey from dual) c,
   (select /*+ no_merge */ dbms_rcvman.sv_getsessionfromTimeRange fTime
        from dual) d,
   (select /*+ no_merge */ dbms_rcvman.sv_getsessionuntilTimeRange uTime
        from dual) e
    where  a.status = 'A' and
           a.rsr_key = b.rsr_key (+) and 
           (c.skey is null or c.skey = b.session_key) and
           (d.fTime is null or d.fTime <= b.start_time) and
           (e.uTime is null or e.uTime >= b.end_time)
union
select unique 'PROXYCOPY' btype, a.xdf_key btype_key, 
       b.session_key,
       b.session_recid,
       b.session_stamp,
       a.db_key, a.db_name,
       a.recid, a.stamp, file#,
       creation_change#, creation_time,
       resetlogs_change#, resetlogs_time, incremental_level, 
       0 incremental_change#, checkpoint_change#, checkpoint_time,
       null marked_corrupt, 
       (blocks+1)*block_size filesize,
       1 compression_ratio,
       'NO' sparse_backup
   from rc_proxy_datafile a, rc_rman_status b,
   (select /*+ no_merge */ dbms_rcvman.sv_getsessionkey skey from dual) c,
   (select /*+ no_merge */ dbms_rcvman.sv_getsessionfromTimeRange fTime
        from dual) d,
   (select /*+ no_merge */ dbms_rcvman.sv_getsessionuntilTimeRange uTime
        from dual) e
    where  a.status = 'A' and
           a.rsr_key = b.rsr_key (+) and 
           (c.skey is null or c.skey = b.session_key) and
           (d.fTime is null or d.fTime <= b.start_time) and
           (e.uTime is null or e.uTime >= b.end_time)) a,
(select distinct df.db_key, df.file#, df.ts#, df.con_id, df.pdb_name,
                 df.pdb_key, ts.name
   from rci_datafile df, rc_tablespace ts
 where ts.ts# = df.ts# and ts.pdb_key = df.pdb_key and df.db_key=ts.db_key) b
where a.file# = b.file#(+) and a.db_key=b.db_key(+)
>>>
 
define rc_backup_controlfile_details
<<<
CREATE Or REPLACE VIEW RC_BACKUP_CONTROLFILE_DETAILS AS
select a.*,
      dbms_rcvman.Num2DisplaySize(filesize) filesize_display 
from 
(select unique 'BACKUPSET' btype, b.bs_key btype_key, 
       b.session_key,
       b.session_recid,
       b.session_stamp,
       a.db_key, a.db_name,
       a.set_stamp id1, 
       b.set_count id2,
       creation_time,
       resetlogs_change#, resetlogs_time, checkpoint_change#, checkpoint_time,
       (a.blocks+1)*a.block_size filesize,
       1 compression_ratio
   from rc_backup_controlfile a, rc_backup_set_details b where
        a.bs_key = b.bs_key
union
select unique 'IMAGECOPY' btype, a.ccf_key btype_key, 
       b.session_key,
       b.session_recid,
       b.session_stamp,
       a.db_key, a.db_name,
       a.recid, a.stamp,
       creation_time,
       resetlogs_change#, resetlogs_time, checkpoint_change#, checkpoint_time,
       (blocks+1)*block_size filesize,
       1 compression_ratio
   from rc_controlfile_copy a, rc_rman_status b,
   (select /*+ no_merge */ dbms_rcvman.sv_getsessionkey skey from dual) c,
   (select /*+ no_merge */ dbms_rcvman.sv_getsessionfromTimeRange fTime
        from dual) d,
   (select /*+ no_merge */ dbms_rcvman.sv_getsessionuntilTimeRange uTime
        from dual) e
    where  a.status = 'A' and
           a.rsr_key = b.rsr_key (+) and 
           (c.skey is null or c.skey = b.session_key) and
           (d.fTime is null or d.fTime <= b.start_time) and
           (e.uTime is null or e.uTime >= b.end_time)
union
select unique 'PROXYCOPY' btype, a.xcf_key btype_key, 
       b.session_key,
       b.session_recid,
       b.session_stamp,
       a.db_key, a.db_name,
       a.recid, a.stamp,
       creation_time,
       resetlogs_change#, resetlogs_time, checkpoint_change#, checkpoint_time,
       (blocks+1)*block_size filesize,
       1 compression_ratio
   from rc_proxy_controlfile a, rc_rman_status b,
   (select /*+ no_merge */ dbms_rcvman.sv_getsessionkey skey from dual) c,
   (select /*+ no_merge */ dbms_rcvman.sv_getsessionfromTimeRange fTime
        from dual) d,
   (select /*+ no_merge */ dbms_rcvman.sv_getsessionuntilTimeRange uTime
        from dual) e
    where  a.status = 'A' and
           a.rsr_key = b.rsr_key (+) and
           (c.skey is null or c.skey = b.session_recid) and
           (d.fTime is null or d.fTime <= b.start_time) and
           (e.uTime is null or e.uTime >= b.end_time))a
>>>
 
define rc_backup_archivelog_details
<<<
CREATE Or REPLACE VIEW RC_BACKUP_ARCHIVELOG_DETAILS AS
select a.*,
   dbms_rcvman.Num2DisplaySize(filesize) filesize_display
from
(select unique 'BACKUPSET' btype, b.bs_key btype_key, 
       b.session_key,
       b.session_recid,
       b.session_stamp,
       a.db_key, a.db_name,
       a.set_stamp id1, b.set_count id2, 
       thread#, sequence#, resetlogs_change#, resetlogs_time,
       first_change#, 
       first_time,
       next_change#, 
       next_time,
       (blocks+1)*a.block_size filesize,
       b.compression_ratio
   from rc_backup_redolog a, rc_backup_set_details b where
        a.bs_key = b.bs_key
union
select unique 'PROXYCOPY', a.xal_key btype_key, 
       session_key,
       session_recid,
       session_stamp,
       a.db_key, a.db_name,
       a.recid, a.stamp, 
       thread#, sequence#, resetlogs_change#, resetlogs_time,
       first_change#, first_time,
       next_change#, next_time,
       (blocks+1)*block_size filesize,
       1
   from rc_proxy_archivedlog a, rc_rman_status b,
   (select /*+ no_merge */ dbms_rcvman.sv_getsessionkey skey from dual) c,
   (select /*+ no_merge */ dbms_rcvman.sv_getsessionfromTimeRange fTime
        from dual) d,
   (select /*+ no_merge */ dbms_rcvman.sv_getsessionuntilTimeRange uTime
        from dual) e
    where  a.status = 'A' and
           a.rsr_key = b.rsr_key (+) and 
           (c.skey is null or c.skey = b.session_key) and
           (d.fTime is null or d.fTime <= b.start_time) and
           (e.uTime is null or e.uTime >= b.end_time))a
>>>
 
define rc_backup_spfile_details
<<<
CREATE Or REPLACE VIEW RC_BACKUP_SPFILE_DETAILS AS
select unique b.session_recid session_key, b.session_recid,
       b.session_stamp, b.db_key, b.db_name,
       b.recid bs_key, a.set_stamp, b.set_count, 
       modification_time,
       a.bytes filesize,
       dbms_rcvman.Num2DisplaySize(a.bytes) filesize_display
   from rc_backup_spfile a, rc_backup_set_details b where
        a.bs_key = b.bs_key
>>>
 
define rc_backup_set_summary
<<<
CREATE Or REPLACE VIEW RC_BACKUP_SET_SUMMARY AS
select db.name db_name, a.*,
    case when 
      original_input_bytes/decode(output_bytes, 0, null, output_bytes) > 1
    then 
      original_input_bytes/decode(output_bytes, 0, null, output_bytes)
    else 1 end compression_ratio,
    dbms_rcvman.Num2DisplaySize(original_input_bytes) 
              original_input_bytes_display,
    dbms_rcvman.Num2DisplaySize(output_bytes) output_bytes_display ,
    dbms_rcvman.Num2DisplaySize(original_inprate_bytes) 
              original_inprate_bytes_display,
    dbms_rcvman.Num2DisplaySize(output_rate_bytes) output_rate_bytes_display
from 
(select db_key, count(*) num_backupsets,
       min(start_time) oldest_backup_time,
       max(start_time) newest_backup_time,
       sum(output_bytes) output_bytes,
       sum(original_input_bytes) original_input_bytes,
       avg(original_inprate_bytes) original_inprate_bytes,
       avg(output_rate_bytes) output_rate_bytes
from 
  (select unique db_key,
     set_stamp, set_count,
     start_time,
     output_bytes,
     original_input_bytes,
     original_inprate_bytes,
     output_rate_bytes,
     compression_ratio
   from
     rc_backup_set_details) group by db_key)a, rc_database db 
   where db.db_key = a.db_key
>>>
 
define rc_backup_datafile_summary
<<<
CREATE OR REPLACE VIEW RC_BACKUP_DATAFILE_SUMMARY AS
select db.name db_name, a.*,
    case when 
      input_bytes/decode(output_bytes, 0, null, output_bytes) > 1
    then 
      input_bytes/decode(output_bytes, 0, null, output_bytes)
    else 1 end compression_ratio,
       dbms_rcvman.Num2DisplaySize(input_bytes) input_bytes_display,
       dbms_rcvman.Num2DisplaySize(output_bytes) output_bytes_display 
from
(select db_key, sum(num_times_backed) num_files_backed, 
       sum(distinct_files_backed) num_distinct_files_backed,
       count(distinct ts# || '.' || pdb_key)  num_distinct_ts_backed,
       min(min_checkpoint_change#) min_checkpoint_change#,
       max(max_checkpoint_change#) max_checkpoint_change#,
       min(min_checkpoint_time) min_checkpoint_time,
       max(max_checkpoint_time) max_checkpoint_time, 
       sum(input_bytes) input_bytes,
       sum(output_bytes) output_bytes
   from
   ( select a.*, b.ts#, b.pdb_key, count(distinct a.file#) 
         over (partition by a.file#, a.creation_change#) distinct_files_backed
   from 
   (select unique a.db_key,
           a.file#, sum(a.num_times_backed) num_times_backed,
           min(min_checkpoint_change#) min_checkpoint_change#,
           max(max_checkpoint_change#) max_checkpoint_change#,
           min(min_checkpoint_time) min_checkpoint_time,
           max(max_checkpoint_time) max_checkpoint_time,
           sum(input_bytes) input_bytes,
           sum(output_bytes) output_bytes,
           creation_change#
    from
    ((select a.db_key,
            file#,count(*) over (partition by a.db_key,file#, creation_change#) 
            num_times_backed,
            min(checkpoint_change#) over
                          (partition by a.db_key,file#, creation_change#) 
                 min_checkpoint_change#,
            max(checkpoint_change#) over
                          (partition by a.db_key,file#, creation_change#) 
            max_checkpoint_change#,
            min(checkpoint_time) over 
                          (partition by a.db_key,file#, creation_change#) 
            min_checkpoint_time,
            max(checkpoint_time) over 
                          (partition by a.db_key,file#, creation_change#) 
            max_checkpoint_time,
            sum((datafile_blocks+1)*a.block_size) over
                  (partition by a.db_key,file#, creation_change#) input_bytes,
            sum((a.blocks+1)*a.block_size) over
                  (partition by a.db_key,file#, creation_change#) output_bytes,
       creation_change#
    from rc_backup_datafile a, 
         (select unique db_key, bs_key from rc_backup_set_details) b
    where a.bs_key = b.bs_key and
          a.db_key = b.db_key
    )
    union
    (select unique  a.db_key,
           file#, count(*) over (partition by a.db_key, file#, creation_change#)
           num_times_backed,
           min(checkpoint_change#) over
              (partition by a.db_key, file#, creation_change#) 
              min_checkpoint_change#,
           max(checkpoint_change#) over 
               (partition by a.db_key, file#, creation_change#) 
               max_checkpoint_change#,
           min(checkpoint_time) over
               (partition by a.db_key, file#, creation_change#) 
               min_checkpoint_time,
           max(checkpoint_time) over
                (partition by a.db_key,file#, creation_change#) 
                max_checkpoint_time,
           sum((blocks+1)*block_size) over
                (partition by a.db_key,file#, creation_change#)
                input_bytes,
           sum((blocks+1)*block_size) over
                 (partition by a.db_key,file#, creation_change#)
                 output_bytes,
           creation_change#
    from rc_datafile_copy a, rc_rman_status b,
   (select /*+ no_merge */ dbms_rcvman.sv_getsessionkey skey from dual) c,
   (select /*+ no_merge */ dbms_rcvman.sv_getsessionfromTimeRange fTime
        from dual) d,
   (select /*+ no_merge */ dbms_rcvman.sv_getsessionuntilTimeRange uTime
        from dual) e
    where  a.status = 'A' and
           a.rsr_key = b.rsr_key (+) and 
           (c.skey is null or c.skey = b.session_key) and
           (d.fTime is null or d.fTime <= b.start_time) and
           (e.uTime is null or e.uTime >= b.end_time) and
           a.db_key = b.db_key
    )
    union
    (select unique  a.db_key,
           file#, 
           count(*) over 
             (partition by a.db_key, file#, creation_change#) num_times_backed,
           min(checkpoint_change#) over 
               (partition by a.db_key, file#, creation_change#) 
               min_checkpoint_change#,
           max(checkpoint_change#) over
               (partition by a.db_key, file#, creation_change#) 
               max_checkpoint_change#,
           min(checkpoint_time) over
               (partition by a.db_key, file#, creation_change#) 
               min_checkpoint_time,
           max(checkpoint_time) over
               (partition by a.db_key, file#, creation_change#) 
               max_checkpoint_time,
           sum((blocks+1)*block_size) over
               (partition by a.db_key, file#, creation_change#)
               input_bytes,
           sum((blocks+1)*block_size) over
               (partition by a.db_key, file#, creation_change#)
               output_bytes,
           creation_change#
    from rc_proxy_datafile a, rc_rman_status b,
   (select /*+ no_merge */ dbms_rcvman.sv_getsessionkey skey from dual) c,
   (select /*+ no_merge */ dbms_rcvman.sv_getsessionfromTimeRange fTime
        from dual) d,
   (select /*+ no_merge */ dbms_rcvman.sv_getsessionuntilTimeRange uTime
        from dual) e
    where  a.status = 'A' and
           a.rsr_key = b.rsr_key (+) and 
           (c.skey is null or c.skey = b.session_key) and
           (d.fTime is null or d.fTime <= b.start_time) and
           (e.uTime is null or e.uTime >= b.end_time) and
           a.db_key = b.db_key
    )) a group by a.db_key, a.file#, creation_change#) a,
    (select  distinct df.db_key, df.file#, df.ts#, df.pdb_key, ts.name 
          from rci_datafile df, rc_tablespace ts 
      where ts.ts# = df.ts# and
            ts.pdb_key = df.pdb_key and
            ts.db_key = df.db_key) b
where a.db_key = b.db_key and a.file# = b.file#(+)) 
  group by db_key)a, rc_database db where a.db_key = db.db_key
>>>
 
define rc_backup_controlfile_summary
<<<
CREATE OR REPLACE VIEW RC_BACKUP_CONTROLFILE_SUMMARY AS
select b.name db_name, a.*, 
       case when 
         input_bytes/decode(output_bytes, 0, null, output_bytes) > 1
       then 
         input_bytes/decode(output_bytes, 0, null, output_bytes) 
       else 1 end compression_ratio,
       dbms_rcvman.Num2DisplaySize(input_bytes) input_bytes_display,
       dbms_rcvman.Num2DisplaySize(output_bytes) output_bytes_display 
from
(select db_key, 
       sum(num_times_backed) num_files_backed, 
       1 num_distinct_files_backed,
       min(min_checkpoint_change#) min_checkpoint_change#,
       max(max_checkpoint_change#) max_checkpoint_change#,
       min(min_checkpoint_time) min_checkpoint_time,
       max(max_checkpoint_time) max_checkpoint_time,
       sum(input_bytes) input_bytes,
       sum(output_bytes) output_bytes
   from
    ((select a.db_key,
       count(*) over (partition by creation_time) 
            num_times_backed,
       min(checkpoint_change#) over (partition by creation_time) 
                 min_checkpoint_change#,
       max(checkpoint_change#) over (partition by creation_time) 
                 max_checkpoint_change#,
       min(checkpoint_time) over (partition by creation_time) 
                 min_checkpoint_time,
       max(checkpoint_time) over (partition by creation_time) 
                 max_checkpoint_time,
       sum((blocks+1)*a.block_size)
                 over (partition by creation_time) input_bytes,
       sum((blocks+1)*a.block_size) over (partition by creation_time)
                 output_bytes,
       creation_time
    from rc_backup_controlfile a, 
         (select unique db_key, bs_key from
          rc_backup_set_details) b
    where a.bs_key = b.bs_key and
          a.db_key = b.db_key
    )
    union
    (select a.db_key,
       count(*) over (partition by creation_time)
              num_times_backed,
       min(checkpoint_change#) over (partition by creation_time) 
                 min_checkpoint_change#,
       max(checkpoint_change#) over (partition by creation_time) 
                 max_checkpoint_change#,
       min(checkpoint_time) over (partition by creation_time) 
                 min_checkpoint_time,
       max(checkpoint_time) over (partition by creation_time) 
                 max_checkpoint_time,
       sum((blocks+1)*block_size) over (partition by creation_time)
                 input_bytes,
       sum((blocks+1)*block_size) over (partition by creation_time)
                 output_bytes,
       creation_time
    from rc_controlfile_copy a, rc_rman_status b,
   (select /*+ no_merge */ dbms_rcvman.sv_getsessionkey skey from dual) c,
   (select /*+ no_merge */ dbms_rcvman.sv_getsessionfromTimeRange fTime
        from dual) d,
   (select /*+ no_merge */ dbms_rcvman.sv_getsessionuntilTimeRange uTime
        from dual) e
    where  a.status = 'A' and
           a.rsr_key = b.rsr_key (+) and 
           (c.skey is null or c.skey = b.session_key) and
           (d.fTime is null or d.fTime <= b.start_time) and
           (e.uTime is null or e.uTime >= b.end_time) and
           a.db_key = b.db_key
    )
    union
    (select a.db_key, 
       count(*) over (partition by creation_time)
              num_times_backed,
       min(checkpoint_change#) over (partition by creation_time) 
                 min_checkpoint_change#,
       max(checkpoint_change#) over (partition by creation_time) 
                 max_checkpoint_change#,
       min(checkpoint_time) over (partition by creation_time) 
                 min_checkpoint_time,
       max(checkpoint_time) over (partition by creation_time) 
                 max_checkpoint_time,
       sum((blocks+1)*block_size) over (partition by creation_time)
                 input_bytes,
       sum((blocks+1)*block_size) over (partition by creation_time)
                 output_bytes,
       creation_time
    from rc_proxy_controlfile a, rc_rman_status b,
   (select /*+ no_merge */ dbms_rcvman.sv_getsessionkey skey from dual) c,
   (select /*+ no_merge */ dbms_rcvman.sv_getsessionfromTimeRange fTime
        from dual) d,
   (select /*+ no_merge */ dbms_rcvman.sv_getsessionuntilTimeRange uTime
        from dual) e
    where  a.status = 'A' and
           a.rsr_key = b.rsr_key (+) and
           (c.skey is null or c.skey = b.session_key) and
           (d.fTime is null or d.fTime <= b.start_time) and
           (e.uTime is null or e.uTime >= b.end_time) and
           a.db_key = b.db_key
    ))group by db_key)a, rc_database b where a.db_key=b.db_key
>>>
 
define rc_backup_archivelog_summary
<<<
CREATE or REPLACE VIEW RC_BACKUP_ARCHIVELOG_SUMMARY AS
select db.name db_name, a.*,
       case when 
         input_bytes/decode(output_bytes, 0, null, output_bytes) > 1
       then 
         input_bytes/decode(output_bytes, 0, null, output_bytes)
       else 1 end compression_ratio,
       dbms_rcvman.Num2DisplaySize(input_bytes) input_bytes_display,
       dbms_rcvman.Num2DisplaySize(output_bytes) output_bytes_display 
from
  (select db_key,
       sum(num_files_backed) num_files_backed,
       sum(distinct_files_backed) num_distinct_files_backed,
       min(min_first_change#) min_first_change#,
       max(max_next_change#) max_next_change#,
       min(min_first_time) min_first_time,
       max(max_next_time) max_next_time,
       sum(original_input_bytes) input_bytes,
       sum(output_bytes) output_bytes
  from
    ((select a.db_key,
       num_files_backed,
       distinct_files_backed,
       min_first_change#,
       max_next_change#,
       min_first_time,
       max_next_time,
       original_input_bytes,
       output_bytes
     from
       (select a.db_key, count(*) num_files_backed,
         min(first_change#)min_first_change#,
         max(next_change#) max_next_change#,
         min(first_time)min_first_time,
         max(next_time) max_next_time
       from rc_backup_redolog a, rc_backup_set_details b
       where a.bs_key = b.bs_key and a.db_key = b.db_key group by a.db_key)a,
       (select db_key, count(*) distinct_files_backed
         from (select unique a.db_key,
                thread#, sequence#, resetlogs_change#, resetlogs_time
                from rc_backup_redolog a, rc_backup_set_details b
               where a.bs_key = b.bs_key and a.db_key = b.db_key) 
        group by db_key)b,
       (select db_key, nvl(sum(original_input_bytes),0) original_input_bytes,
         nvl(sum(output_bytes), 0) output_bytes
       from (select unique db_key, bs_key, original_input_bytes,
                      output_bytes from
             rc_backup_set_details where backup_type='L') 
       group by db_key)c
    where
       a.db_key = b.db_key and
       b.db_key = c.db_key)
    union
    (select a.db_key,
       num_files_backed,
       distinct_files_backed,
       min_first_change#,
       max_next_change#,
       min_first_time,
       max_next_time,
       original_input_bytes,
       output_bytes
     from
       (select a.db_key, 
         count(*) num_files_backed,
         min(first_change#)min_first_change#,
         max(next_change#) max_next_change#,
         min(first_time)min_first_time,
         max(next_time) max_next_time,
         nvl(sum((blocks+1)*block_size),0) original_input_bytes,
         nvl(sum((blocks+1)*block_size),0) output_bytes
         from rc_proxy_archivedlog a, rc_rman_status b,
       (select /*+ no_merge */ dbms_rcvman.sv_getsessionkey skey from dual) c,
       (select /*+ no_merge */ dbms_rcvman.sv_getsessionfromTimeRange fTime
        from dual) d,
       (select /*+ no_merge */ dbms_rcvman.sv_getsessionuntilTimeRange uTime
        from dual) e
        where  a.status = 'A' and
           a.rsr_key = b.rsr_key (+) and 
           (c.skey is null or c.skey = b.session_key) and
           (d.fTime is null or d.fTime <= b.start_time) and
           (e.uTime is null or e.uTime >= b.end_time) and
           a.db_key = b.db_key group by a.db_key) a,
           (select db_key, count(*) distinct_files_backed
             from (select unique a.db_key,
             thread#, sequence#, resetlogs_change#, resetlogs_time
             from rc_proxy_archivedlog a, rc_rman_status b,
      (select /*+ no_merge */ dbms_rcvman.sv_getsessionkey skey from dual) c,
      (select /*+ no_merge */ dbms_rcvman.sv_getsessionfromTimeRange fTime
        from dual) d,
      (select /*+ no_merge */ dbms_rcvman.sv_getsessionuntilTimeRange uTime
        from dual) e
         where  a.status = 'A' and
           a.rsr_key = b.rsr_key (+) and 
           (c.skey is null or c.skey = b.session_key) and
           (d.fTime is null or d.fTime <= b.start_time) and
           (e.uTime is null or e.uTime >= b.end_time) and
           a.db_key = b.db_key) group by db_key)b 
   where a.db_key=b.db_key))
   group by db_key)a, 
   rc_database db where a.db_key=db.db_key
>>>
 
define rc_backup_spfile_summary
<<<
create or replace view RC_BACKUP_SPFILE_SUMMARY as
select db.name db_name, a.*,
       dbms_rcvman.Num2DisplaySize(input_bytes) input_bytes_display
from
(select a.db_key, num_files_backed,
       num_distinct_files_backed,
       min_modification_time,
       max_modification_time,
       input_bytes
  from
  (select a.db_key, count(*) num_files_backed,
       min(modification_time)min_modification_time,
       max(modification_time) max_modification_time,
       sum(bytes) input_bytes
    from rc_backup_spfile a, rc_backup_set_details b
    where a.bs_key = b.bs_key and a.db_key=b.db_key
    group by a.db_key)a,
  (select db_key, count(*) num_distinct_files_backed
    from (select unique a.db_key, modification_time
          from rc_backup_spfile a, rc_backup_set_details b
          where a.bs_key = b.bs_key and a.db_key=b.db_key) group by db_key)b
   where a.db_key=b.db_key)a, rc_database db where a.db_key=db.db_key
>>>
 
define rc_backup_copy_summary
<<<
CREATE OR REPLACE VIEW RC_BACKUP_COPY_SUMMARY AS
select db.name db_name, a.*,
       dbms_rcvman.Num2DisplaySize(output_bytes) output_bytes_display
from
(select db_key, nvl(sum(num_times_backed),0) num_copies,
       sum(distinct_copies)  num_distinct_copies,
       min(min_checkpoint_change#) min_checkpoint_change#,
       max(max_checkpoint_change#) max_checkpoint_change#,
       min(min_checkpoint_time) min_checkpoint_time,
       max(max_checkpoint_time) max_checkpoint_time,
       sum(output_bytes) output_bytes
   from
    (select unique a.db_key,
       file#, count(*) over (partition by file#, creation_change#)
              num_times_backed,
       count(distinct file#) 
               over (partition by file#, creation_change#, checkpoint_change#)
                distinct_copies,
       min(checkpoint_change#) over (partition by file#, creation_change#) 
                 min_checkpoint_change#,
       max(checkpoint_change#) over (partition by file#, creation_change#) 
                 max_checkpoint_change#,
       min(checkpoint_time) over (partition by file#, creation_change#) 
                 min_checkpoint_time,
       max(checkpoint_time) over (partition by file#, creation_change#) 
                 max_checkpoint_time,
       sum((blocks+1)*block_size) over (partition by file#, creation_change#)
                 output_bytes
    from rc_datafile_copy a, rc_rman_status b,
   (select /*+ no_merge */ dbms_rcvman.sv_getsessionkey skey from dual) c,
   (select /*+ no_merge */ dbms_rcvman.sv_getsessionfromTimeRange fTime
        from dual) d,
   (select /*+ no_merge */ dbms_rcvman.sv_getsessionuntilTimeRange uTime
        from dual) e
    where  a.status = 'A' and
           a.rsr_key = b.rsr_key (+) and 
           (c.skey is null or c.skey = b.session_key) and
           (d.fTime is null or d.fTime <= b.start_time) and
           (e.uTime is null or e.uTime >= b.end_time) and
           a.db_key=b.db_key
   union
     select unique a.db_key, 
       0 file#, count(*) over (partition by creation_time)
              num_times_backed,
       1      distinct_copies,
       min(checkpoint_change#) over (partition by creation_time) 
                 min_checkpoint_change#,
       max(checkpoint_change#) over (partition by creation_time) 
                 max_checkpoint_change#,
       min(checkpoint_time) over (partition by creation_time) 
                 min_checkpoint_time,
       max(checkpoint_time) over (partition by creation_time) 
                 max_checkpoint_time,
       sum((blocks+1)*block_size) over (partition by creation_time)
                 output_bytes
    from rc_controlfile_copy a, rc_rman_status b,
   (select /*+ no_merge */ dbms_rcvman.sv_getsessionkey skey from dual) c,
   (select /*+ no_merge */ dbms_rcvman.sv_getsessionfromTimeRange fTime
        from dual) d,
   (select /*+ no_merge */ dbms_rcvman.sv_getsessionuntilTimeRange uTime
        from dual) e
    where  a.status = 'A' and
           a.rsr_key = b.rsr_key (+) and 
           (c.skey is null or c.skey = b.session_key) and
           (d.fTime is null or d.fTime <= b.start_time) and
           (e.uTime is null or e.uTime >= b.end_time) and
           a.db_key=b.db_key) group by db_key)a, rc_database db 
where a.db_key=db.db_key
>>>
 
define rc_proxy_copy_summary
<<<
CREATE OR REPLACE VIEW RC_PROXY_COPY_SUMMARY AS
select db.name db_name, a.*,
       dbms_rcvman.Num2DisplaySize(output_bytes) output_bytes_display
from
(select db_key, 
       nvl(sum(num_times_backed),0) num_copies,
       sum(distinct_copies)  num_distinct_copies,
       min(min_checkpoint_change#) min_checkpoint_change#,
       max(max_checkpoint_change#) max_checkpoint_change#,
       min(min_checkpoint_time) min_checkpoint_time,
       max(max_checkpoint_time) max_checkpoint_time,
       sum(output_bytes) output_bytes
   from
    (select unique a.db_key,
       file#, count(*) over (partition by file#, creation_change#)
              num_times_backed,
       count(distinct file#) 
                over (partition by file#, creation_change#, checkpoint_change#)
                distinct_copies,
       min(checkpoint_change#) over (partition by file#, creation_change#) 
                 min_checkpoint_change#,
       max(checkpoint_change#) over (partition by file#, creation_change#) 
                 max_checkpoint_change#,
       min(checkpoint_time) over (partition by file#, creation_change#) 
                 min_checkpoint_time,
       max(checkpoint_time) over (partition by file#, creation_change#) 
                 max_checkpoint_time,
       sum((blocks+1)*block_size) over (partition by file#, creation_change#)
                 output_bytes
    from rc_proxy_datafile a, rc_rman_status b,
   (select /*+ no_merge */ dbms_rcvman.sv_getsessionkey skey from dual) c,
   (select /*+ no_merge */ dbms_rcvman.sv_getsessionfromTimeRange fTime
        from dual) d,
   (select /*+ no_merge */ dbms_rcvman.sv_getsessionuntilTimeRange uTime
        from dual) e
    where  a.status = 'A' and
           a.rsr_key = b.rsr_key (+) and 
           (c.skey is null or c.skey = b.session_key) and
           (d.fTime is null or d.fTime <= b.start_time) and
           (e.uTime is null or e.uTime >= b.end_time) and
           a.db_key = b.db_key
    union
    select unique a.db_key,
       0 file#, count(*) over (partition by creation_time)
              num_times_backed,
       1      distinct_copies,
       min(checkpoint_change#) over (partition by creation_time) 
                 min_checkpoint_change#,
       max(checkpoint_change#) over (partition by creation_time) 
                 max_checkpoint_change#,
       min(checkpoint_time) over (partition by creation_time) 
                 min_checkpoint_time,
       max(checkpoint_time) over (partition by creation_time) 
                 max_checkpoint_time,
       sum((blocks+1)*block_size) over (partition by creation_time)
                 output_bytes
    from rc_proxy_controlfile a, rc_rman_status b,
   (select /*+ no_merge */ dbms_rcvman.sv_getsessionkey skey from dual) c,
   (select /*+ no_merge */ dbms_rcvman.sv_getsessionfromTimeRange fTime
        from dual) d,
   (select /*+ no_merge */ dbms_rcvman.sv_getsessionuntilTimeRange uTime
        from dual) e
    where  a.status = 'A' and
           a.rsr_key = b.rsr_key (+) and
           (c.skey is null or c.skey = b.session_key) and
           (d.fTime is null or d.fTime <= b.start_time) and
           (e.uTime is null or e.uTime >= b.end_time) and
           a.db_key = b.db_key) group by db_key) a, rc_database db
 where a.db_key = db.db_key
>>>
 
define rc_proxy_archivelog_summary
<<<
CREATE or REPLACE VIEW RC_PROXY_ARCHIVELOG_SUMMARY AS
select db.name db_name, a.*,
       dbms_rcvman.Num2DisplaySize(output_bytes) output_bytes_display
from
(select a.db_key,
       nvl(num_files_backed, 0) num_files_backed,
       num_distinct_files_backed,
       min_first_change#,
       max_next_change#,
       min_first_time,
       max_next_time,
       output_bytes
from
(select a.db_key, count(*) num_files_backed,
       min(first_change#)min_first_change#,
       max(next_change#) max_next_change#,
       min(first_time)min_first_time,
       max(next_time) max_next_time,
       sum((blocks+1)*block_size) output_bytes
    from rc_proxy_archivedlog a, rc_rman_status b,
   (select /*+ no_merge */ dbms_rcvman.sv_getsessionkey skey from dual) c,
   (select /*+ no_merge */ dbms_rcvman.sv_getsessionfromTimeRange fTime
        from dual) d,
   (select /*+ no_merge */ dbms_rcvman.sv_getsessionuntilTimeRange uTime
        from dual) e
    where  a.status = 'A' and
           a.rsr_key = b.rsr_key (+) and 
           (c.skey is null or c.skey = b.session_key) and
           (d.fTime is null or d.fTime <= b.start_time) and
           (e.uTime is null or e.uTime >= b.end_time) and
           a.db_key=b.db_key group by a.db_key)a,
(select db_key, count(*) num_distinct_files_backed
    from (select unique a.db_key, 
            thread#, sequence#, resetlogs_change#, resetlogs_time
          from rc_proxy_archivedlog a, rc_rman_status b,
          (select /*+ no_merge */ dbms_rcvman.sv_getsessionkey skey
              from dual) c,
          (select /*+ no_merge */ dbms_rcvman.sv_getsessionfromTimeRange fTime
              from dual) d,
          (select /*+ no_merge */ dbms_rcvman.sv_getsessionuntilTimeRange uTime
              from dual) e
          where  a.status = 'A' and
             a.rsr_key = b.rsr_key (+) and 
             (c.skey is null or c.skey = b.session_key) and
             (d.fTime is null or d.fTime <= b.start_time) and
             (e.uTime is null or e.uTime >= b.end_time) and
             a.db_key=b.db_key) group by db_key)b where a.db_key=b.db_key)a,
 rc_database db where a.db_key=db.db_key
>>>
 
define rc_unusable_backupfile_details
<<<
create or replace view RC_UNUSABLE_BACKUPFILE_DETAILS AS
select b.session_key, a.* from
  (select a.db_key, f.db_name, a.rsr_key,
       'BACKUPSET' btype, a.bs_key btype_key, a.set_stamp id1, a.set_count id2,
       'BACKUPPIECE' filetype, a.bp_key filetype_key, a.status, a.bytes filesize, 
        a.device_type, a.handle filename, a.media, a.media_pool 
     from rc_backup_piece a,
          (select db_key, name "DB_NAME" from rc_database) f
     where a.status <> 'A' and a.db_key = f.db_key
  union
  select db_key, db_name, rsr_key, 
        'IMAGECOPY', cdf_key, null, null, 'DATAFILECOPY', cdf_key, status,
        (blocks+1)*block_size, 'DISK', name, null, null 
     from rc_datafile_copy where status <> 'A'
  union
  select db_key, db_name, rsr_key, 
        'IMAGECOPY', ccf_key, null, null, 'CONTROLFILECOPY', ccf_key, status,
        (blocks+1)*block_size, 'DISK', name, null, null 
     from rc_controlfile_copy where status <> 'A'
  union
  select db_key, db_name, rsr_key, 
        'PROXYCOPY', xdf_key, null, null, 'DATAFILECOPY', xdf_key, status,
        (blocks+1)*block_size, device_type, handle, media, media_pool
     from rc_proxy_datafile where status <> 'A'
  union
  select db_key, db_name, rsr_key, 
        'PROXYCOPY', xcf_key, null, null, 'CONTROLFILECOPY', xcf_key, status,
        (blocks+1)*block_size, device_type, handle, media, media_pool
     from rc_proxy_controlfile where status <> 'A'
  union
  select db_key, db_name, rsr_key, 
        'PROXYCOPY', xal_key, null, null, 'ARCHIVELOGCOPY', xal_key, status,
        (blocks+1)*block_size, device_type, handle, media, media_pool
     from rc_proxy_archivedlog where status <> 'A') a, rc_rman_status b,
  (select /*+ no_merge */ dbms_rcvman.sv_getsessionkey skey from dual) c,
  (select /*+ no_merge */ dbms_rcvman.sv_getsessionfromTimeRange fTime
       from dual) d,
  (select /*+ no_merge */ dbms_rcvman.sv_getsessionuntilTimeRange uTime
       from dual) e
   where  a.rsr_key = b.rsr_key (+) and 
          (c.skey is null or c.skey = b.session_key) and
          (d.fTime is null or d.fTime <= b.start_time) and
          (e.uTime is null or e.uTime >= b.end_time)
>>>
 
define rc_rman_backup_type
<<<
create or replace view rc_rman_backup_type as
   select 9 weight, 'DB FULL' input_type  from dual union 
   select 8, 'RECVR AREA'    from dual union
   select 7, 'DB INCR'       from dual union
   select 6, 'DATAFILE FULL' from dual union
   select 5, 'DATAFILE INCR' from dual union
   select 4, 'ARCHIVELOG'    from dual union
   select 3, 'CONTROLFILE'   from dual union
   select 2, 'SPFILE'        from dual union
   select 1, 'BACKUPSET'     from dual
>>>
 
define rc_restore_point
<<<
create or replace view rc_restore_point as
   select dbinc_key,
          null recid,
          null stamp,
          site_key, 
          rspname name,
          rsptime restore_point_time,
          creation_time creation_time,
          to_scn scn,
          'NO' long_term,
          'YES' preserved,         /* All guaranteed are also preserved */
          guaranteed guarantee_flashback_database,
          pdb_key,
          clean
   from grsp
   union
   select dbinc_key,
          nrsp_recid recid,
          nrsp_stamp stamp,
          site_key, 
          rspname name,
          rsptime restore_point_time,
          creation_time creation_time,
          to_scn scn,
          long_term,
          'NO' preserved,
          'NO' guarantee_flashback_database,
          pdb_key,
          clean
   from nrsp
>>>
 
define rci_site
<<<
create or replace view rci_site as
   select site_key,
          db_key,
          database_role,
          cf_create_time,
          substr(db_unique_name, 1, 30) db_unique_name,
          high_conf_recid,
          force_resync2cf,
          high_rout_stamp,
          inst_startup_stamp,
          last_kccdivts,
          high_ic_recid,
          dbinc_key,
          ckp_scn,
          full_ckp_cf_seq,
          job_ckp_cf_seq,
          high_ts_recid,
          high_df_recid,
          high_rt_recid,
          high_orl_recid,
          high_offr_recid,
          high_rlh_recid,
          high_al_recid,
          high_bs_recid,
          high_bp_recid,
          high_bdf_recid,
          high_cdf_recid,
          high_brl_recid,
          high_bcb_recid,
          high_ccb_recid,
          high_do_recid,
          high_pc_recid,
          high_bsf_recid,
          high_rsr_recid,
          high_tf_recid,
          high_grsp_recid,
          high_nrsp_recid,
          high_bcr_recid,
          low_bcr_recid,
          bcr_in_use,
          high_pdb_recid,
          high_pic_recid
   from node
>>>
 
define rc_site
<<<
create or replace view rc_site as
   select * from
   rci_site
   where substr(nvl(db_unique_name, 'A'),1,1) <> '$'
>>>
 
define rc_current_xmlfiles
<<<
   create or replace view rc_current_xmlfile 
   as select name, name_tag, version_num, schema_ver, xml_comment,
             creation_time, modified_time  from
   (select name, name_tag, version_num,
    max(version_num) over (partition by name, name_tag) curr_version_num,
    creation_time,  
    last_value(modified_time) over (partition by name, name_tag, version_num) 
      modified_time,
    doctype,
    last_value(schema_ver) over (partition by name, name_tag, version_num) 
      schema_ver,
    last_value(xml_comment) over (partition by name, name_tag, version_num) 
      xml_comment
   from xmlstore) where version_num = curr_version_num
>>>
 
define drop_rc_rman_backup_subjob_details
<<<
  drop view rc_rman_backup_subjob_details
>>>
define drop_rc_rman_backup_job_details
<<<
  drop view rc_rman_backup_job_details
>>>
define drop_rc_backup_set_details
<<<
  drop view rc_backup_set_details
>>>
define drop_rc_backup_piece_details
<<<
  drop view rc_backup_piece_details
>>>
define drop_rc_backup_copy_details
<<<
  drop view rc_backup_copy_details
>>>
define drop_rc_proxy_copy_details
<<<
  drop view rc_proxy_copy_details
>>>
define drop_rc_proxy_archivelog_details
<<<
  drop view rc_proxy_archivelog_details
>>>
define drop_rc_backup_datafile_details
<<<
  drop view rc_backup_datafile_details
>>>
define drop_rc_backup_controlfile_details
<<<
  drop view rc_backup_controlfile_details
>>>
define drop_rc_backup_archivelog_details
<<<
  drop view rc_backup_archivelog_details
>>>
define drop_rc_backup_spfile_details
<<<
  drop view rc_backup_spfile_details
>>>
define drop_rc_backup_set_summary
<<<
  drop view rc_backup_set_summary
>>>
define drop_rc_backup_datafile_summary
<<<
  drop view rc_backup_datafile_summary
>>>
define drop_rc_backup_controlfile_summary
<<<
  drop view rc_backup_controlfile_summary
>>>
define drop_rc_backup_archivelog_summary
<<<
  drop view rc_backup_archivelog_summary
>>>
define drop_rc_backup_spfile_summary
<<<
  drop view rc_backup_spfile_summary
>>>
define drop_rc_backup_copy_summary
<<<
  drop view rc_backup_copy_summary
>>>
define drop_rc_proxy_copy_summary
<<<
  drop view rc_proxy_copy_summary
>>>
define drop_rc_proxy_archivelog_summary
<<<
  drop view rc_proxy_archivelog_summary
>>>
define drop_rc_unusable_backupfile_details
<<<
  drop view rc_unusable_backupfile_details
>>>
define drop_rc_rman_backup_type
<<<
  drop view rc_rman_backup_type
>>>
define drop_rc_restore_point
<<<
  drop view rc_restore_point
>>>
define drop_rc_site
<<<
  drop view rc_site
>>>
define drop_rci_site
<<<
  drop view rci_site
>>>
define drop_rc_current_xmlfiles
<<<
  drop view rc_current_xmlfile
>>>
define drop_rc_pdbs
<<<
  drop view rc_pdbs
>>>
define drop_rci_pdbs
<<<
  drop view rci_pdbs
>>>
define drop_rci_pdbinc_this_dbinc
<<<
  drop view rci_pdbinc_this_dbinc
>>>
define drop_rc_pluggable_database_inc
<<<
  drop view rc_pluggable_database_inc
>>>
define drop_rc_restore_range
<<<
  drop view rc_restore_range
>>>
define drop_rc_disk_restore_range
<<<
  drop view rc_disk_restore_range
>>>
define drop_rc_sbt_restore_range
<<<
  drop view rc_sbt_restore_range
>>>
 
 
 
 
 
 
 
 
 
 
 
 
define dbmsrvct_sql
<<<
create or replace package dbms_rcvcat authid current_user is
 
--
TRUE#  CONSTANT number := 1;
FALSE# CONSTANT number := 0;
 
--
UPGRADE_COMPLETED CONSTANT number := 1;
 
--
RESYNC_FULL    CONSTANT number := 1;
RESYNC_PARTIAL CONSTANT number := 2;
RESYNC_NONE    CONSTANT number := 3;
 
CONFIGRESYNC_NO        CONSTANT number := 0;
CONFIGRESYNC_TORC      CONSTANT number := 1;
CONFIGRESYNC_TOCF      CONSTANT number := 2;
CONFIGRESYNC_TORC_TOCF CONSTANT number := 3;
 
--
--
CF_CURRENT     CONSTANT number := 1;
CF_BACKUP      CONSTANT number := 2;
CF_CREATED     CONSTANT number := 3;
CF_STANDBY     CONSTANT number := 4;
CF_CLONE       CONSTANT number := 5;
CF_NOMOUNT     CONSTANT number := 6;
 
--
--
this_db_key      number := NULL;
this_dbinc_key   number := NULL;
 
type registerDbPending_t is record
(
   dbid        number  := null,
   con_id      number  := null,
   guid        raw(16) := null
);
registerDbPending registerDbPending_t;
 
RESYNC_REASON_NOACTION    CONSTANT number := 1;  -- do not display reasons
RESYNC_REASON_NONE        CONSTANT number := 2;  -- no reason is yet set
RESYNC_REASON_DF          CONSTANT number := 3; 
RESYNC_REASON_TF          CONSTANT number := 4;
RESYNC_REASON_TS          CONSTANT number := 5;
RESYNC_REASON_THR         CONSTANT number := 6;
RESYNC_REASON_ORL         CONSTANT number := 7;
RESYNC_REASON_CONF        CONSTANT number := 8;
RESYNC_REASON_CF          CONSTANT number := 9;
RESYNC_REASON_RSL         CONSTANT number := 10;
RESYNC_REASON_INC         CONSTANT number := 11;
RESYNC_REASON_RESET       CONSTANT number := 12;
RESYNC_REASON_PDB         CONSTANT number := 13;
resync_reason     number  := RESYNC_REASON_NONE;
doResyncReasons   boolean := FALSE;
 
RESYNC_ACTION_ADD         CONSTANT number := 1;
RESYNC_ACTION_DROP        CONSTANT number := 2;
RESYNC_ACTION_CHANGE      CONSTANT number := 3;
RESYNC_ACTION_RECREATE    CONSTANT number := 4;
RESYNC_ACTION_RENAME      CONSTANT number := 5;
RESYNC_ACTION_RESIZE      CONSTANT number := 6;
 
TYPE resyncActionNames_t    IS VARRAY(6) OF varchar2(12);
 
--
RESYNC_ACTION_NAMES         CONSTANT resyncActionNames_t := 
                            resyncActionNames_t('added',   'dropped',
                                                'changed', 'recreated',
                                                'renamed', 'resized');
 
TYPE resyncActionTaken_t    IS VARRAY(6) OF boolean;
 
TYPE resyncActionCounts_t   IS VARRAY(6) OF number;
 
RESYNC_OBJECT_TABLESPACE    CONSTANT number := 1;
RESYNC_OBJECT_DATAFILE      CONSTANT number := 2;
RESYNC_OBJECT_TEMPFILE      CONSTANT number := 3;
RESYNC_OBJECT_REDOTHREAD    CONSTANT number := 4;
RESYNC_OBJECT_ONLINELOG     CONSTANT number := 5;
RESYNC_OBJECT_PDB           CONSTANT number := 6;
 
TYPE resyncActionObjects_t  IS VARRAY(5) OF varchar2(16);
 
--
RESYNC_ACTION_OBJECTS       CONSTANT resyncActionObjects_t :=
                            resyncActionObjects_t('Tablespace', 'Datafile', 
                                                  'Tempfile',   'Redo thread', 
                                                  'Online redo log');
--
RCVCAT_LEVEL_ZERO           CONSTANT number := 0;  
RCVCAT_LEVEL_MIN            CONSTANT number := 1;
RCVCAT_LEVEL_LOW            CONSTANT number := 5;
RCVCAT_LEVEL_MID            CONSTANT number := 9;
RCVCAT_LEVEL_HI             CONSTANT number := 12;
RCVCAT_LEVEL_MAX            CONSTANT number := 15;
RCVCAT_LEVEL_DEFAULT        CONSTANT number := RCVCAT_LEVEL_MID; 
 
TYPE fullResyncActions_t IS RECORD
(
   active          boolean,
   valid           boolean,
   lastobjno       number,
   objtype         number,
   actTaken        resyncActionTaken_t,
   actCount        resyncActionCounts_t
);
 
fullResyncAction   fullResyncActions_t; -- :=
--
--
--
 
/*-----------------------*
 * Debugging functions   *
 *-----------------------*/
 
PROCEDURE setDebugOn(dbglevel IN NUMBER DEFAULT RCVCAT_LEVEL_DEFAULT);
 
PROCEDURE setDebugOff;
 
/*-----------------------*
 * Database Registration *
 *-----------------------*/
 
PROCEDURE registerDatabase(
   db_id          IN number
  ,db_name        IN varchar2
  ,reset_scn      IN number
  ,reset_time     IN date
  ,db_unique_name IN varchar2 default null
  ,con_id         IN number   default 0
  ,guid           IN raw      default null
);
 
--
--
--
--
--
--
--
--
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
 
 
procedure resetDatabase(
  db_id             IN number
 ,db_name           IN varchar2
 ,reset_scn         IN number
 ,reset_time        IN date
 ,parent_reset_scn  IN number
 ,parent_reset_time IN date
);
 
function resetDatabase(
  db_id             IN number
 ,db_name           IN varchar2
 ,reset_scn         IN number
 ,reset_time        IN date
 ,parent_reset_scn  IN number
 ,parent_reset_time IN date
) return number;
 
procedure resetDatabase(
  dbinc_key  IN number
 ,db_name    IN varchar2
);
 
procedure resetDatabase(
  dbinc_key  IN number
 ,db_name    IN varchar2
 ,reset_scn  OUT number
 ,reset_time OUT date
 ,db_id      IN number DEFAULT NULL
);
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
 
 
procedure unregisterDatabase(
  db_key     IN NUMBER DEFAULT NULL
 ,db_id      IN NUMBER
);
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
 
/*--------------------------*
 * Set Database Incarnation *
 *--------------------------*/
 
procedure setDatabase(
  db_name         IN varchar2
 ,reset_scn       IN number
 ,reset_time      IN date
 ,db_id           IN number
 ,db_unique_name  IN varchar2
 ,dummy_instance  IN boolean
 ,cf_type         IN number
 ,site_aware      IN boolean default FALSE
 ,ors_instance    IN boolean default FALSE
);
 
procedure setDatabase(
  db_name         IN varchar2
 ,reset_scn       IN number
 ,reset_time      IN date
 ,db_id           IN number
 ,db_unique_name  IN varchar2 default NULL);
 
procedure setDatabase(dbinc_key number);
 
procedure setDatabase;
 
--
--
--
--
--
--
--
--
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
 
/*-----------------------------*
 * Recovery Catalog Checkpoint *
 *-----------------------------*/
function ckptNeeded(
  ckp_scn          IN number
 ,ckp_cf_seq       IN number
 ,cf_version       IN date
 ,cf_type          IN number
 ,high_df_recid    IN number
 ,high_orl_recid   IN number
 ,high_cdf_recid   IN number
 ,high_al_recid    IN number
 ,high_bp_recid    IN number
 ,high_do_recid    IN number
 ,high_offr_recid  IN number
 ,high_pc_recid    IN number  DEFAULT NULL -- for compatibility
 ,high_conf_recid  IN number  DEFAULT NULL -- for compatibility
 ,rltime           IN DATE    DEFAULT NULL -- for compatibility
 ,high_ts_recid    IN number  DEFAULT NULL -- for compatibility
 ,high_bs_recid    IN number  DEFAULT NULL -- for compatibility
 ,lopen_reset_scn  IN number  DEFAULT NULL -- for compatibility
 ,lopen_reset_time IN DATE    DEFAULT NULL -- for compatibility
 ,high_ic_recid    IN number  DEFAULT NULL -- for compatibility
 ,high_tf_recid    IN number  DEFAULT NULL -- for compatibility
 ,high_rt_recid    IN number  DEFAULT NULL -- for compatibility
 ,high_grsp_recid  IN number  DEFAULT NULL -- for compatibility
 ,high_nrsp_recid  IN number  DEFAULT NULL -- for compatibility
 ,high_bcr_recid   IN number  DEFAULT NULL -- for compatibility
 ,high_pdb_recid   IN number  DEFAULT NULL -- for compatibility
 ,high_pic_recid   IN number  DEFAULT NULL -- for compatibility
) return number;
 
PROCEDURE lockForCkpt(ors_inspect IN boolean DEFAULT FALSE);
 
procedure beginCkpt(
  ckp_scn       IN number
 ,ckp_cf_seq    IN number
 ,cf_version    IN date
 ,ckp_time      IN date
 ,ckp_type      IN varchar2
 ,ckp_db_status IN varchar2
 ,high_df_recid IN number
 ,cf_type       IN varchar2 DEFAULT 'CURRENT'   -- for compatibility reasons
);
 
--
--
--
--
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
 
procedure endCkpt;
 
--
--
--
--
--
--
 
--
--
--
--
 
procedure cancelCkpt;
 
--
--
--
 
--
--
function lastFullCkpt return number;
 
--
--
FUNCTION getPolledRec(rec_type OUT NUMBER,
                      recid    OUT NUMBER,
                      stamp    OUT NUMBER,
                      fname    OUT VARCHAR2) RETURN BOOLEAN;
 
/*-------------------*
 * Resync            *
 *-------------------*/
 
--
--
--
--
--
--
--
--
--
--
--
--
--
 
--
--
--
--
--
--
--
--
--
--
--
 
--
--
 
/*---------------------*
 * Pluggable DB Resync *
 *---------------------*/
 
FUNCTION beginPluggableDBResync(
  high_pdb_recid IN NUMBER)
RETURN BOOLEAN;
 
--
--
--
 
PROCEDURE checkPluggableDB(
  name       IN VARCHAR2
 ,con_id     IN NUMBER
 ,db_id      IN NUMBER
 ,create_scn IN NUMBER
 ,guid       IN RAW
 ,noBackup   IN VARCHAR2 DEFAULT 'N'
);
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
 
PROCEDURE endPluggableDBResync;
 
--
--
 
/*-------------------*
 * Tablespace Resync *
 *-------------------*/
 
function beginTableSpaceResync(
  high_ts_recid IN NUMBER,
  force         IN BOOLEAN DEFAULT FALSE
) return boolean;
 
--
--
 
--
--
--
 
--
--
 
 
procedure checkTableSpace(
  ts_name                     IN varchar2
 ,ts#                         IN number
 ,create_scn                  IN number
 ,create_time                 IN date
 ,rbs_count                   IN number   DEFAULT NULL
 ,included_in_database_backup IN varchar2 DEFAULT NULL
 ,bigfile                     IN varchar2 DEFAULT NULL
 ,temporary                   IN varchar2 DEFAULT NULL
 ,encrypt_in_backup           IN varchar2 DEFAULT NULL
 ,plugin_scn                  IN number   DEFAULT 0
 ,con_id                      IN number   DEFAULT 0
 ,pdb_dict_check              IN boolean  DEFAULT FALSE
);
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
 
--
--
--
--
--
--
--
--
--
 
procedure endTableSpaceResync;
 
--
 
--
--
 
 
/*-----------------*
 * Datafile Resync *
 *-----------------*/
 
function beginDataFileResync(
  high_df_recid IN number
) return boolean;
 
 
--
--
--
 
--
--
 
procedure checkDataFile(file#               IN NUMBER,
                        fname               IN VARCHAR2,
                        create_scn          IN NUMBER,
                        create_time         IN DATE,
                        blocks              IN NUMBER,
                        block_size          IN NUMBER,
                        ts#                 IN NUMBER,
                        stop_scn            IN NUMBER,
                        read_only           IN NUMBER,
                        stop_time           IN DATE     DEFAULT NULL,
                        rfile#              IN NUMBER   DEFAULT NULL,
                        aux_fname           IN VARCHAR2 DEFAULT NULL,
                        foreign_dbid        IN NUMBER   DEFAULT 0,
                        foreign_create_scn  IN NUMBER   DEFAULT 0,
                        foreign_create_time IN DATE     DEFAULT NULL,
                        plugged_readonly    IN VARCHAR2 DEFAULT 'NO',
                        plugin_scn          IN NUMBER   DEFAULT 0,
                        plugin_reset_scn    IN NUMBER   DEFAULT 0,
                        plugin_reset_time   IN DATE     DEFAULT NULL,
                        create_thread       IN NUMBER   DEFAULT NULL,
                        create_size         IN NUMBER   DEFAULT NULL,
                        con_id              IN NUMBER   DEFAULT 0,
                        pdb_closed          IN NUMBER   DEFAULT 0,
                        pdb_dict_check      IN BOOLEAN  DEFAULT FALSE,
                        pdb_foreign_dbid    IN NUMBER   DEFAULT 0,
                        pdb_foreign_ckp_scn IN NUMBER   DEFAULT 0,
                        pdb_foreign_afn     IN NUMBER   DEFAULT 0);
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
 
--
--
 
procedure endDataFileResync;
 
--
 
--
--
 
--
--
 
function beginDataFileResyncForStandby(
  high_df_recid IN number
) return boolean;
 
procedure checkDataFileForStandby(
                        file#               IN NUMBER,
                        fname               IN VARCHAR2,
                        create_scn          IN NUMBER,
                        create_time         IN DATE,
                        blocks              IN NUMBER,
                        block_size          IN NUMBER,
                        ts#                 IN NUMBER,
                        rfile#              IN NUMBER,
                        stop_scn            IN NUMBER,
                        read_only           IN NUMBER,
                        foreign_dbid        IN NUMBER,
                        plugin_scn          IN NUMBER,
                        did_prim_resync     IN BOOLEAN  DEFAULT FALSE,
                        pdb_dict_check      IN BOOLEAN  DEFAULT FALSE);
 
--
--
--
--
--
--
 
procedure endDataFileResyncForStandby;
 
function beginTempFileResyncForStandby(
  high_tf_recid IN number
) return boolean;
 
procedure checkTempFileForStandby
                       (file#          IN NUMBER,
                        fname          IN VARCHAR2,
                        create_scn     IN NUMBER,
                        create_time    IN DATE,
                        blocks         IN NUMBER,
                        block_size     IN NUMBER,
                        ts#            IN NUMBER,
                        rfile#         IN NUMBER,
                        autoextend     IN VARCHAR2,
                        max_size       IN NUMBER,
                        next_size      IN NUMBER,
                        con_id         IN NUMBER DEFAULT 0);
 
procedure endTempFileResyncForStandby;
 
procedure setDatafileSize(
  file#       IN number
 ,create_scn  IN number
 ,blocks      IN number
 ,plugin_scn  IN number DEFAULT 0
);
 
/*-----------------*
 * TempFile Resync *
 *-----------------*/
 
function tempFileToResync(
  high_tf_recid IN number
) return boolean;
 
--
--
--
--
--
 
function beginTempFileResync(
  high_tf_recid IN number
) return boolean;
 
 
--
--
--
 
--
--
 
procedure checkTempFile(file#          IN NUMBER,
                        fname          IN VARCHAR2,
                        create_scn     IN NUMBER,
                        create_time    IN DATE,
                        blocks         IN NUMBER,
                        block_size     IN NUMBER,
                        ts#            IN NUMBER,
                        rfile#         IN NUMBER,
                        autoextend     IN VARCHAR2,
                        max_size       IN NUMBER,
                        next_size      IN NUMBER,
                        con_id         IN NUMBER  DEFAULT 0,
                        pdb_dict_check IN BOOLEAN DEFAULT FALSE);
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
 
--
--
 
procedure endTempFileResync;
 
--
 
--
--
 
/*---------------------*
 * Redo Thread resync  *
 *---------------------*/
 
function beginThreadResync(
  high_rt_recid IN number
) return boolean;
 
 
--
 
 
procedure checkThread(
  thread#        IN number
 ,last_sequence# IN number
 ,enable_scn     IN number
 ,enable_time    IN date
 ,disable_scn    IN number
 ,disable_time   IN date
 ,status         IN varchar2
);
 
--
--
--
 
--
--
--
--
--
--
--
--
--
--
--
 
--
--
--
 
 
procedure endThreadResync;
 
--
 
 
 
/*------------------------*
 * Online Redo Log resync *
 *------------------------*/
 
function beginOnlineRedoLogResync(
  high_orl_recid IN number
) return boolean;
 
--
 
procedure checkOnlineRedoLog(
  thread#        IN number
 ,group#         IN number
 ,fname          IN varchar2
 ,bytes          IN number   default null
 ,type           IN varchar2 default 'ONLINE'
);
 
--
--
--
 
procedure endOnlineRedoLogResync;
 
--
 
/*---------------------------------*
 * Guaranteed Restore Point Resync *
 *---------------------------------*/
 
function beginGuaranteedRPResync(
  high_grsp_recid IN number
) return boolean;
 
--
 
PROCEDURE checkGuaranteedRP(
  rspname            IN VARCHAR2
 ,from_scn           IN NUMBER
 ,to_scn             IN NUMBER
 ,resetlogs_change#  IN NUMBER
 ,resetlogs_time     IN DATE
 ,create_time        IN DATE DEFAULT NULL
 ,rsp_time           IN DATE DEFAULT NULL
 ,guaranteed         IN VARCHAR2 DEFAULT 'YES'
 ,con_id             IN NUMBER   DEFAULT NULL
 ,clean              IN VARCHAR2 DEFAULT 'NO'
);
 
--
--
--
 
procedure endGuaranteedRPResync;
 
--
--
 
 
/*----------------------------------*
 * RMAN Configration records resync *
 *----------------------------------*/
 
function beginConfigResync(
  high_conf_recid IN number
) return number;
 
function beginConfigResync2(
  high_conf_recid IN number
) return number;
 
--
--
 
procedure endConfigResync;
 
procedure endConfigResync2(sync_to_cf_pending IN boolean DEFAULT FALSE);
 
--
--
 
procedure getConfig(
   conf#          OUT    number
  ,name           IN OUT varchar2
  ,value          IN OUT varchar2
  ,first          IN     boolean);
 
--
--
 
PROCEDURE setKeepOutputForSession(days IN number);
--
 
/*-----------------------------*
 * Redo Log History resync     *
 *-----------------------------*/
 
function beginLogHistoryResync return number;
 
--
--
--
--
 
function getLogHistoryLowSCN return number;
 
--
--
--
--
 
procedure checkLogHistory(
  rlh_recid   IN number
 ,rlh_stamp   IN number
 ,thread#     IN number
 ,sequence#   IN number
 ,low_scn     IN number
 ,low_time    IN date
 ,next_scn    IN number
 ,reset_scn   IN number default NULL
 ,reset_time  IN date default NULL
);
 
--
--
--
--
 
--
--
--
--
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
 
 
procedure endLogHistoryResync;
 
--
--
 
 
 
/*-------------------------*
 * Archived Log resync     *
 *-------------------------*/
 
function beginArchivedLogResync return number;
 
--
 
 
procedure checkArchivedLog(
  al_recid    IN number
 ,al_stamp    IN number
 ,thread#     IN number
 ,sequence#   IN number
 ,reset_scn   IN number
 ,reset_time  IN date
 ,low_scn     IN number
 ,low_time    IN date
 ,next_scn    IN number
 ,next_time   IN date
 ,blocks      IN number
 ,block_size  IN number
 ,fname       IN varchar2
 ,archived    IN varchar2
 ,completion_time IN date
 ,status      IN varchar2
 ,is_standby  IN varchar2 DEFAULT NULL
 ,dictionary_begin IN varchar2 DEFAULT NULL
 ,dictionary_end   IN varchar2 DEFAULT NULL
 ,is_recovery_dest_file 
                   IN varchar2 default 'NO'
 ,compressed       IN varchar2 default 'NO'
 ,creator          IN varchar2 default NULL
 ,terminal         IN varchar2 default 'NO'
 ,chk_last_recid   IN boolean  DEFAULT TRUE
);
 
--
--
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
 
 
 
procedure endArchivedLogResync;
 
--
--
 
 
 
/*-------------------------*
 * Offline range resync    *
 *-------------------------*/
 
function beginOfflineRangeResync return number;
 
--
--
 
 
procedure checkOfflineRange(
  offr_recid     IN number
 ,offr_stamp     IN number
 ,file#          IN number
 ,create_scn     IN number
 ,offline_scn    IN number
 ,online_scn     IN number
 ,online_time    IN date
 ,cf_create_time IN date
 ,reset_scn   IN number default NULL
 ,reset_time  IN date default NULL
);
 
--
 
 
--
--
--
--
--
 
 
procedure endOfflineRangeResync;
 
--
 
 
 
/*-------------------------*
 * Backup Set resync       *
 *-------------------------*/
 
function beginBackupSetResync return number;
 
--
--
 
 
procedure checkBackupSet(
  bs_recid        IN number
 ,bs_stamp        IN number
 ,set_stamp       IN number
 ,set_count       IN number
 ,bck_type        IN varchar2
 ,incr_level      IN number         DEFAULT NULL
 ,pieces          IN number
 ,start_time      IN date
 ,completion_time IN date
 ,controlfile_included
                  IN VARCHAR2       DEFAULT NULL
 ,input_file_scan_only
                  IN VARCHAR2       DEFAULT NULL
 ,keep_options    IN number         DEFAULT 0
 ,keep_until      IN date           DEFAULT NULL
 ,block_size      IN number         DEFAULT NULL
 ,multi_section   IN varchar2       DEFAULT NULL
 ,chk_last_recid  IN boolean        DEFAULT TRUE
 ,guid            IN raw            DEFAULT NULL
 ,dropped_pdb     IN binary_integer DEFAULT 0 
);
 
--
--
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
 
procedure endBackupSetResync;
 
--
 
 
 
/*-------------------------*
 * Backup piece resync     *
 *-------------------------*/
 
function beginBackupPieceResync return number;
 
 
procedure checkBackupPiece(
  bp_recid                IN number
 ,bp_stamp                IN number
 ,set_stamp               IN number
 ,set_count               IN number
 ,piece#                  IN number
 ,tag                     IN varchar2
 ,device_type             IN varchar2
 ,handle                  IN varchar2
 ,comments                IN varchar2
 ,media                   IN varchar2
 ,concur                  IN varchar2
 ,start_time              IN date
 ,completion_time         IN date
 ,status                  IN varchar2
 ,copy#                   IN number         default 1
 ,media_pool              IN number         default 0
 ,bytes                   IN number         default NULL
 ,is_recovery_dest_file   IN varchar2       default 'NO'
 ,rsr_recid               IN number         default NULL
 ,rsr_stamp               IN number         default NULL
 ,compressed              IN varchar2       default 'NO'
 ,encrypted               IN varchar2       default 'NO'
 ,backed_by_osb           IN varchar2       default 'NO'
 ,ba_access               IN varchar2       default 'U'
 ,vbkey                   IN number         default NULL
 ,chk_last_recid          IN boolean        default TRUE
 ,lib_key                 IN number         default NULL
 ,guid                    IN raw            default NULL
 ,template_key            IN number         default NULL
 ,dropped_pdb             IN binary_integer default 0
);
 
function checkBackupPiece(
  bp_recid                IN number
 ,bp_stamp                IN number
 ,set_stamp               IN number
 ,set_count               IN number
 ,piece#                  IN number
 ,tag                     IN varchar2
 ,device_type             IN varchar2
 ,handle                  IN varchar2
 ,comments                IN varchar2
 ,media                   IN varchar2
 ,concur                  IN varchar2
 ,start_time              IN date
 ,completion_time         IN date
 ,status                  IN varchar2
 ,copy#                   IN number         default 1
 ,media_pool              IN number         default 0
 ,bytes                   IN number         default NULL
 ,is_recovery_dest_file   IN varchar2       default 'NO'
 ,rsr_recid               IN number         default NULL
 ,rsr_stamp               IN number         default NULL
 ,compressed              IN varchar2       default 'NO'
 ,encrypted               IN varchar2       default 'NO'
 ,backed_by_osb           IN varchar2       default 'NO'
 ,ba_access               IN varchar2       default 'U'
 ,vbkey                   IN number         default NULL
 ,chk_last_recid          IN boolean        default TRUE
 ,lib_key                 IN number         default NULL
 ,guid                    IN raw            default NULL
 ,template_key            IN number         default NULL
 ,dropped_pdb             IN binary_integer default 0
) return number;
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
 
procedure endBackupPieceResync;
 
 
 
/*-------------------------*
 * Backup Datafile resync  *
 *-------------------------*/
 
function beginBackupDataFileResync return number;
 
procedure checkBackupDataFile(
  bdf_recid           IN number
 ,bdf_stamp           IN number
 ,set_stamp           IN number
 ,set_count           IN number
 ,file#               IN number
 ,create_scn          IN number
 ,create_time         IN date
 ,reset_scn           IN number
 ,reset_time          IN date
 ,incr_level          IN number
 ,incr_scn            IN number
 ,ckp_scn             IN number
 ,ckp_time            IN date
 ,abs_fuzzy_scn       IN number
 ,datafile_blocks     IN number
 ,blocks              IN number
 ,block_size          IN number
 ,min_offr_recid      IN number
 ,completion_time     IN date
 ,controlfile_type    IN varchar2       DEFAULT NULL
 ,cfile_abck_year     IN number         DEFAULT NULL
 ,cfile_abck_mon_day  IN number         DEFAULT NULL
 ,cfile_abck_seq      IN number         DEFAULT NULL
 ,chk_last_recid      IN boolean        DEFAULT TRUE
 ,blocks_read         IN number         DEFAULT NULL
 ,used_chg_track      IN varchar2       DEFAULT 'NO'
 ,used_optim          IN varchar2       DEFAULT 'NO'
 ,foreign_dbid        IN number         DEFAULT 0
 ,plugged_readonly    IN varchar2       DEFAULT 'NO'
 ,plugin_scn          IN number         DEFAULT 0
 ,plugin_reset_scn    IN number         DEFAULT 0
 ,plugin_reset_time   IN date           DEFAULT NULL
 ,section_size        IN number         DEFAULT NULL
 ,guid                IN raw            DEFAULT NULL
 ,sparse_backup       IN varchar2       DEFAULT 'NO'
 ,isResync            IN boolean        DEFAULT TRUE
 ,isVirtual           IN boolean        DEFAULT FALSE
 ,dropped_pdb         IN binary_integer DEFAULT 0
);
 
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
 
procedure endBackupDataFileResync;
 
/*-------------------------*
 * Backup SPFILE resync  *
 *-------------------------*/
 
function beginBackupSpFileResync return number;
 
procedure checkBackupSpFile(
  bsf_recid         IN number
 ,bsf_stamp         IN number
 ,set_stamp         IN number
 ,set_count         IN number
 ,modification_time IN date
 ,bytes             IN number
 ,chk_last_recid    IN boolean        DEFAULT TRUE
 ,db_unique_name    IN varchar2       DEFAULT NULL
 ,guid              IN raw            DEFAULT NULL
 ,dropped_pdb       IN binary_integer DEFAULT 0
);
 
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
 
 
procedure endBackupSpFileResync;
 
/*-------------------------*
 * Backup Redo Log resync  *
 *-------------------------*/
 
function beginBackupRedoLogResync return number;
 
procedure checkBackupRedoLog(
  brl_recid      IN number
 ,brl_stamp      IN number
 ,set_stamp      IN number
 ,set_count      IN number
 ,thread#        IN number
 ,sequence#      IN number
 ,reset_scn      IN number
 ,reset_time     IN date
 ,low_scn        IN number
 ,low_time       IN date
 ,next_scn       IN number
 ,next_time      IN date
 ,blocks         IN number
 ,block_size     IN number
 ,chk_last_recid IN boolean  DEFAULT TRUE
 ,terminal       IN varchar2 DEFAULT 'NO'
 ,activation     IN varchar2 DEFAULT NULL
);
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
 
procedure endBackupRedoLogResync;
 
 
/*----------------------------*
 * Copy Datafile resync       *
 *----------------------------*/
 
function beginDataFileCopyResync return number;
 
procedure checkDataFileCopy(
  cdf_recid             IN number
 ,cdf_stamp             IN number
 ,fname                 IN varchar2
 ,tag                   IN varchar2
 ,file#                 IN number
 ,create_scn            IN number
 ,create_time           IN date
 ,reset_scn             IN number
 ,reset_time            IN date
 ,incr_level            IN number
 ,ckp_scn               IN number
 ,ckp_time              IN date
 ,onl_fuzzy             IN varchar2
 ,bck_fuzzy             IN varchar2
 ,abs_fuzzy_scn         IN number
 ,rcv_fuzzy_scn         IN number
 ,rcv_fuzzy_time        IN date
 ,blocks                IN number
 ,block_size            IN number
 ,min_offr_recid        IN number
 ,completion_time       IN date
 ,status                IN varchar2
 ,controlfile_type      IN varchar2       DEFAULT NULL
 ,keep_options          IN number         DEFAULT 0
 ,keep_until            IN date           DEFAULT NULL
 ,scanned               IN varchar2       DEFAULT 'NO'
 ,is_recovery_dest_file IN varchar2       DEFAULT 'NO'
 ,rsr_recid             IN number         DEFAULT NULL
 ,rsr_stamp             IN number         DEFAULT NULL
 ,marked_corrupt        IN number         DEFAULT NULL
 ,foreign_dbid          IN number         DEFAULT 0
 ,plugged_readonly      IN varchar2       DEFAULT 'NO'
 ,plugin_scn            IN number         DEFAULT 0
 ,plugin_reset_scn      IN number         DEFAULT 0
 ,plugin_reset_time     IN date           DEFAULT NULL
 ,guid                  IN raw            DEFAULT NULL
 ,sparse_backup         IN varchar2       DEFAULT 'NO'
 ,dropped_pdb           IN binary_integer DEFAULT 0
);
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
 
procedure endDataFileCopyResync;
 
 
/*----------------------------*
 * Corrupt Block resync       *
 *----------------------------*/
 
function beginBackupCorruptionResync return number;
 
procedure checkBackupCorruption(
  bcb_recid       IN number
 ,bcb_stamp       IN number
 ,set_stamp       IN number
 ,set_count       IN number
 ,piece#          IN number
 ,file#           IN number
 ,block#          IN number
 ,blocks          IN number
 ,corrupt_scn     IN number
 ,marked_corrupt  IN varchar2
 ,corruption_type IN varchar2 default NULL
);
 
procedure endBackupCorruptionResync;
 
 
function beginCopyCorruptionResync return number;
 
procedure checkCopyCorruption(
  ccb_recid       IN number
 ,ccb_stamp       IN number
 ,cdf_recid       IN number
 ,cdf_stamp       IN number
 ,file#           IN number
 ,block#          IN number
 ,blocks          IN number
 ,corrupt_scn     IN number
 ,marked_corrupt  IN varchar2
 ,corruption_type IN varchar2 default NULL
);
 
procedure endCopyCorruptionResync;
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
 
 
 
/*----------------------------*
 * Deleted Object resync      *
 *----------------------------*/
 
function beginDeletedObjectResync return number;
 
procedure checkDeletedObject(
  do_recid          IN number
 ,do_stamp          IN number
 ,object_type       IN varchar2
 ,object_recid      IN number
 ,object_stamp      IN number
 ,object_data       IN number   DEFAULT NULL
 ,object_fname      IN varchar2 DEFAULT NULL
 ,object_create_scn IN number   DEFAULT NULL
 ,set_stamp         IN number   DEFAULT NULL
 ,set_count         IN number   DEFAULT NULL
 ,handle            IN VARCHAR2 DEFAULT NULL
 ,device_type       IN VARCHAR2 DEFAULT NULL
);
 
procedure endDeletedObjectResync;
 
/*-------------------*
 * Proxy Copy resync *
 *-------------------*/
 
function beginProxyResync return number;
 
procedure checkProxyDataFile(
  xdf_recid         IN number
 ,xdf_stamp         IN number
 ,tag               IN varchar2
 ,file#             IN number
 ,create_scn        IN number
 ,create_time       IN date
 ,reset_scn         IN number
 ,reset_time        IN date
 ,incr_level        IN number
 ,ckp_scn           IN number
 ,ckp_time          IN date
 ,onl_fuzzy         IN varchar2
 ,bck_fuzzy         IN varchar2
 ,abs_fuzzy_scn     IN number
 ,rcv_fuzzy_scn     IN number
 ,rcv_fuzzy_time    IN date
 ,blocks            IN number
 ,block_size        IN number
 ,min_offr_recid    IN number
 ,device_type       IN varchar2
 ,handle            IN varchar2
 ,comments          IN varchar2
 ,media             IN varchar2
 ,media_pool        IN number
 ,start_time        IN date
 ,completion_time   IN date
 ,status            IN varchar2
 ,controlfile_type  IN varchar2       DEFAULT NULL
 ,keep_options      IN number         DEFAULT 0
 ,keep_until        IN date           DEFAULT NULL
 ,rsr_recid         IN number         DEFAULT NULL
 ,rsr_stamp         IN number         DEFAULT NULL
 ,foreign_dbid      IN number         DEFAULT 0
 ,plugged_readonly  IN varchar2       DEFAULT 'NO'
 ,plugin_scn        IN number         DEFAULT 0
 ,plugin_reset_scn  IN number         DEFAULT 0
 ,plugin_reset_time IN date           DEFAULT NULL
 ,guid              IN raw            DEFAULT NULL
 ,dropped_pdb       IN binary_integer DEFAULT 0
);
 
PROCEDURE checkProxyArchivedLog(
  xal_recid          IN NUMBER
 ,xal_stamp          IN NUMBER
 ,tag                IN VARCHAR2
 ,thread#            IN NUMBER
 ,sequence#          IN NUMBER
 ,resetlogs_change#  IN NUMBER
 ,resetlogs_time     IN DATE
 ,first_change#      IN NUMBER
 ,first_time         IN DATE
 ,next_change#       IN NUMBER
 ,next_time          IN DATE
 ,blocks             IN NUMBER
 ,block_size         IN NUMBER
 ,device_type        IN VARCHAR2
 ,handle             IN VARCHAR2
 ,comments           IN VARCHAR2
 ,media              IN VARCHAR2
 ,media_pool         IN NUMBER
 ,start_time         IN DATE
 ,completion_time    IN DATE
 ,status             IN VARCHAR2
 ,rsr_recid          IN NUMBER
 ,rsr_stamp          IN NUMBER
 ,terminal           IN VARCHAR2 default 'NO'
 ,keep_until         IN DATE     default NULL
 ,keep_options       IN NUMBER   default 0
);
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
 
procedure endProxyResync;
 
/*-------------------------*
 * Incarnation resync     *
 *-------------------------*/
 
FUNCTION beginIncarnationResync(return_Recid in boolean DEFAULT FALSE) 
                               return number;
--
--
--
--
 
function checkIncarnation(reset_scn         IN NUMBER,
                          reset_time        IN DATE,
                          prior_reset_scn   IN NUMBER DEFAULT NULL,
                          prior_reset_time  IN DATE DEFAULT NULL,
                          db_name           IN VARCHAR2 DEFAULT 'UNKNOWN')
                         return number;
--
--
--
 
procedure endIncarnationResync(high_kccdivts IN NUMBER, 
                               high_ic_recid IN NUMBER DEFAULT 0);
--
--
 
/*--------------------------------*
 * Pluggable DB Incaration Resync *
 *--------------------------------*/
FUNCTION beginPluggableDbincResync RETURN NUMBER;
 
--
--
--
 
PROCEDURE checkPluggableDbinc(
  recid               IN NUMBER
 ,guid                IN RAW
 ,curr_pdbinc         IN VARCHAR2
 ,inc_scn             IN NUMBER
 ,begin_reset_scn     IN NUMBER
 ,begin_reset_time    IN DATE
 ,end_reset_scn       IN NUMBER
 ,db_reset_scn        IN NUMBER
 ,db_reset_time       IN DATE
 ,pr_inc_scn          IN NUMBER
 ,pr_end_reset_scn    IN NUMBER
 ,pr_db_reset_scn     IN NUMBER
 ,pr_db_reset_time    IN DATE
 ,chk_last_recid      IN BOOLEAN
);
--
--
--
 
PROCEDURE endPluggableDbincResync(high_pic_recid IN NUMBER);
 
--
--
 
/*-----------------------------*
 * Normal restore point Resync *
 *-----------------------------*/
 
FUNCTION beginRestorePointResync RETURN NUMBER;
 
PROCEDURE checkRestorePoint(
  nrsp_recid    IN NUMBER
 ,nrsp_stamp    IN NUMBER
 ,nrsp_name     IN VARCHAR2
 ,reset_scn     IN NUMBER
 ,reset_time    IN DATE
 ,to_scn        IN NUMBER
 ,nrsp_time     IN DATE
 ,create_time   IN DATE
 ,deleted       IN NUMBER
 ,con_id        IN NUMBER   DEFAULT NULL
 ,clean         IN VARCHAR2 DEFAULT 'NO'
);
 
PROCEDURE endRestorePointResync(lowrecid IN number);
 
 
/*----------------------------*
 * RMAN Status resync         *
 *----------------------------*/
 
FUNCTION beginRmanStatusResync RETURN NUMBER;
--
--
 
 
PROCEDURE checkRmanStatus( recid            IN NUMBER
                          ,stamp            IN NUMBER
                          ,parent_recid     IN NUMBER
                          ,parent_stamp     IN NUMBER
                          ,row_level        IN NUMBER
                          ,row_type         IN VARCHAR2
                          ,command_id       IN VARCHAR2
                          ,operation        IN VARCHAR2
                          ,status           IN VARCHAR2
                          ,mbytes_processed IN NUMBER
                          ,start_time       IN DATE
                          ,end_time         IN DATE
                          ,ibytes           IN NUMBER default null
                          ,obytes           IN NUMBER default null
                          ,optimized        IN VARCHAR2 default null
                          ,otype            IN VARCHAR2 default null
                          ,session_recid    IN NUMBER default null
                          ,session_stamp    IN NUMBER default null
                          ,odevtype         IN VARCHAR2 default null
                          ,osb_allocated    IN VARCHAR2 default 'NO');
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
 
PROCEDURE endRmanStatusResync(recid number);
--
 
 
PROCEDURE updateRmanStatusRow( recid   IN number
                              ,stamp   IN number
                              ,mbytes  IN number
                              ,status  IN binary_integer);
--
 
/*----------------------------*
 * RMAN Output resync         *
 *----------------------------*/
 
FUNCTION beginRmanOutputResync(start_timestamp in NUMBER) RETURN NUMBER;
--
--
 
FUNCTION beginRmanOutputResync(start_timestamp IN  NUMBER
                              ,doRoutMining    OUT BOOLEAN) RETURN NUMBER;
 
PROCEDURE checkRmanOutput( recid             IN NUMBER
                          ,stamp             IN NUMBER
                          ,session_recid     IN NUMBER
                          ,session_stamp     IN NUMBER
                          ,rman_status_recid IN NUMBER
                          ,rman_status_stamp IN NUMBER
                          ,output       IN VARCHAR2);
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
 
PROCEDURE endRmanOutputResync;
--
 
/*----------------------------*
 * Block Corruption Resync    *
 *----------------------------*/
function beginBlockCorruptionResync(
  low_bcr_recid   IN number)
 return number;
 
procedure checkBlockCorruption(
  bcr_recid       IN number
 ,bcr_stamp       IN number
 ,file#           IN number
 ,create_scn      IN number
 ,create_time     IN date
 ,block#          IN number
 ,blocks          IN number
 ,corrupt_scn     IN number
 ,corruption_type IN varchar2
);
 
procedure endBlockCorruptionResync;
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
 
/*----------------------------*
 * Change Procedures          *
 *----------------------------*/
 
procedure changeDataFileCopy(
  cdf_recid    IN number
 ,cdf_stamp    IN number
 ,status       IN varchar2
 ,keep_options IN number DEFAULT NULL -- null means don't update
 ,keep_until   IN date   DEFAULT NULL
 ,osite_key    IN number DEFAULT NULL
 ,nsite_key    IN number DEFAULT NULL
 ,new_recid    IN number DEFAULT NULL
);
 
--
--
--
 
procedure changeControlfileCopy(
  cdf_recid    IN number
 ,cdf_stamp    IN number
 ,status       IN varchar2
 ,keep_options IN number DEFAULT NULL -- null means don't update
 ,keep_until   IN date   DEFAULT NULL
 ,osite_key    IN number DEFAULT NULL
 ,nsite_key    IN number DEFAULT NULL
 ,new_recid    IN number DEFAULT NULL
);
 
--
--
 
procedure changeArchivedLog(
  al_recid  IN number
 ,al_stamp  IN number
 ,status    IN varchar2
 ,osite_key IN number DEFAULT NULL
 ,nsite_key IN number DEFAULT NULL
 ,new_recid IN number DEFAULT NULL
);
 
--
--
 
 
procedure changeBackupSet(
  recid        IN number
 ,stamp        IN number
 ,keep_options IN number   -- null means don't update
 ,keep_until   IN date
 ,osite_key    IN number DEFAULT NULL
 ,nsite_key    IN number DEFAULT NULL
);
 
--
--
--
 
procedure changeBackupPiece(
  bp_recid  IN number
 ,bp_stamp  IN number
 ,status    IN varchar2
 ,set_stamp IN number DEFAULT NULL
 ,set_count IN number DEFAULT NULL
 ,osite_key IN number DEFAULT NULL
 ,nsite_key IN number DEFAULT NULL
 ,handle    IN VARCHAR2  DEFAULT NULL
 ,device_type IN VARCHAR2 DEFAULT NULL
);
 
--
--
 
procedure changeProxyCopy(
  pc_recid     IN number
 ,pc_stamp     IN number
 ,status       IN varchar2
 ,keep_options IN number  DEFAULT NULL -- null means don't update
 ,keep_until   IN date    DEFAULT NULL
 ,osite_key IN number DEFAULT NULL
 ,nsite_key    IN number DEFAULT NULL
);
 
--
--
 
 
/*----------------------------*
 * Reconcile for Replication  *
 *----------------------------*/
 
PROCEDURE doReplicationReconcile(p_db_key IN NUMBER, 
                                 p_lib_key IN NUMBER,
                                 p_server_key IN NUMBER);
 
 
--
 
 
/*----------------------------*
 * Stored Script Procedures   *
 *----------------------------*/
 
procedure createScript(name IN varchar2);
 
procedure createScript(name IN varchar2,
                       scr_com IN varchar2,
                       global  IN boolean);
 
procedure replaceScript(name IN varchar2);
 
procedure replaceScript(name IN varchar2,
                        scr_com IN varchar2,
                        global  IN boolean);
 
--
--
--
--
 
procedure putLine(line IN varchar2);
 
--
--
--
--
 
procedure deleteScript(name IN varchar2);
 
procedure deleteScript(name IN varchar2, glob IN number);
 
--
 
procedure getScript(name IN varchar2);
 
procedure getScript(name IN varchar2, glob IN number);
 
--
--
--
 
function getLine return varchar2;
 
--
--
 
procedure commitChanges(msg IN varchar2 default NULL);
 
--
 
/*---------------------------------------*
 * Procedures for EM xml store support   
 * The initial user of this API will be EM, however other client that intends 
 * to save XML data in RMAN's recovery catalog can also use the API.
 * The API provides the versioned file system functionality, i.e. the clients
 * can save multiple version of same XML file, with additional option to
 * overwrite the latest version.
 *---------------------------------------*/
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
procedure createXMLFile (name        IN varchar2 
                        ,name_tag    IN varchar2 default null
                        ,xmldoc      IN clob
                        ,doctype     IN varchar2 default null
                        ,xml_comment IN varchar2 default null
                        ,schema_ver  IN varchar2 default null);
 
--
--
--
--
--
--
--
--
--
--
--
--
--
procedure updateXMLFile (name        IN varchar2
                        ,name_tag    IN varchar2 default null
                        ,xmldoc      IN clob     default null
                        ,xml_comment IN varchar2 default null
                        ,schema_ver  IN varchar2 default null
                        ,new_name    IN varchar2 default null
                        ,new_name_tag IN varchar2 default null
                        ,new_version  IN BOOLEAN default FALSE);
 
--
procedure deleteXMLFile (name       IN varchar2
                        ,name_tag   IN varchar2 default null);
 
--
--
--
--
--
--
--
--
procedure readXMLFile   (name        IN varchar2
                        ,name_tag    IN varchar2 default null
                        ,version_num IN number default null
                        ,xmldoc      OUT clob);
 
--
--
--
--
--
--
--
--
--
procedure getXMLFileAttr (name        IN varchar2
                         ,name_tag    IN varchar2 default null
                         ,version_num IN number default null
                         ,doctype     OUT varchar2
                         ,file_size   OUT number
                         ,xml_comment OUT varchar2
                         ,schema_ver  OUT varchar2);
 
/*---------------------------------------*
 * Procedures for clone database support *
 *---------------------------------------*/
 
procedure setCloneName(file#            IN     number
                      ,creation_change# IN     number
                      ,new_clone_fname  IN     varchar2
                      ,old_clone_fname  IN     varchar2
                      ,changedauxname   OUT    boolean
                      ,plugin_change#   IN number   DEFAULT 0);
 
FUNCTION  getCloneName(file#            IN number
                      ,creation_change# IN number
                      ,plugin_change#   IN number  DEFAULT 0) RETURN VARCHAR2;
 
 
/*-----------------------------------*
 * Procedures for RMAN configuration *
 *-----------------------------------*/
 
PROCEDURE setConfig(conf#            IN NUMBER
                   ,name             IN VARCHAR2
                   ,value            IN VARCHAR2);
 
 
PROCEDURE resetConfig;
 
PROCEDURE setConfig2(conf#           IN NUMBER
                    ,name            IN VARCHAR2
                    ,value           IN VARCHAR2
                    ,nodespec        IN BOOLEAN);
 
PROCEDURE resetConfig2(nodespec      IN BOOLEAN, 
                       high_conf_recid IN NUMBER DEFAULT NULL);
 
PROCEDURE deleteConfig(conf#         IN NUMBER);
 
FUNCTION  setConfig3(name            IN VARCHAR2
                    ,value           IN VARCHAR2
                    ,db_unique_name  IN VARCHAR2) RETURN NUMBER;
 
PROCEDURE deleteConfig3(conf#        IN NUMBER
                    ,db_unique_name  IN VARCHAR2);
 
/*----------------------------*
 * Version info               *
 *----------------------------*/
 
function getPackageVersion return varchar2;
function getCatalogVersion return varchar2;
 
/*-------------------*
 * Utility functions *
 *-------------------*/
 
/*
 * NAME
 *   bsStstusRecalc
 * DESCRIPTION
 *   Recompute the backupset status for all backupset whose current
 *   status is a specified value.  This is intended to be used when
 *   new values are introduced for the bs.status column.
 */
 
PROCEDURE bsStatusRecalc(status IN varchar2);
 
--
--
--
 
--
--
--
--
--
--
 
PROCEDURE reNormalize(newname IN varchar2, oldname OUT varchar2);
 
--
--
--
 
PROCEDURE sanityCheck;
 
--
--
--
--
--
--
--
--
--
--
 
FUNCTION getDbid RETURN NUMBER;
 
PROCEDURE listScriptNames(glob IN number, 
                          allnames IN number);
 
--
--
--
--
--
--
 
PROCEDURE getScriptNames(dbname  OUT varchar2,
                         scnm    OUT varchar2,
                         sccom   OUT varchar2);
 
--
--
--
--
--
 
PROCEDURE updateOldestFlashbackSCN(
                oldest_flashback_scn     IN NUMBER,
                oldest_flashback_time    IN DATE   DEFAULT NULL);
 
--
--
 
FUNCTION getDbinc RETURN NUMBER;
 
--
 
FUNCTION isDuplicateRecord(recid    IN NUMBER
                          ,stamp    IN NUMBER
                          ,type     IN VARCHAR2) RETURN BOOLEAN;
--
--
--
--
--
--
 
FUNCTION doDuplicateMining RETURN BOOLEAN;
--
--
 
--
FUNCTION isRoutDuplicateRecord(recid             IN NUMBER
                              ,stamp             IN NUMBER
                              ,session_recid     IN NUMBER
                              ,session_stamp     IN NUMBER
                              ,rman_status_recid IN NUMBER
                              ,rman_status_stamp IN NUMBER)
RETURN BOOLEAN;
 
--
--
PROCEDURE unregisterSite(db_unique_name IN VARCHAR2, 
                         incbcks IN binary_integer);
 
--
--
PROCEDURE renameSite(from_db_unique_name IN VARCHAR2, 
                     to_db_unique_name IN VARCHAR2);
 
--
--
PROCEDURE resyncAddDBUname(cdbunstr IN varchar2);
 
--
--
FUNCTION  getThisSiteKey(db_unique_name in VARCHAR2 DEFAULT NULL) 
   return NUMBER;
 
--
FUNCTION  isAMSchema RETURN BOOLEAN;
 
--
FUNCTION  getAMTstlevel RETURN NUMBER;
 
PROCEDURE enableResyncActions;
 
PROCEDURE setReason(reason IN number, forceSet IN boolean default FALSE);
 
FUNCTION getReason RETURN number;
 
PROCEDURE incResyncActions(action      IN number,
                           objno       IN number,
                           objname     IN varchar2);
 
PROCEDURE getResyncActions(valid      OUT boolean
                           ,added     OUT number
                           ,dropped   OUT number
                           ,changed   OUT number
                           ,recreated OUT number
                           ,renamed   OUT number
                           ,resized   OUT number);
 
PROCEDURE clearResyncActions;
 
PROCEDURE dumpResyncActions;
 
FUNCTION debOK (level IN number DEFAULT RCVCAT_LEVEL_DEFAULT)  RETURN boolean;
 
--
--
--
--
--
PROCEDURE createTempResource(
   name       IN varchar2
  ,data_type  IN varchar2);
 
--
--
--
--
--
--
--
FUNCTION lockTempResource(
   name      IN varchar2
  ,data_type IN varchar2)
RETURN BOOLEAN;
 
--
--
--
--
--
--
--
PROCEDURE cleanupTempResource;
 
--
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE addDbidToImport(
   first    IN binary_integer
  ,idb      IN varchar2
  ,idbinc   IN varchar2
  ,dbid     IN number    DEFAULT NULL
  ,dbname   IN varchar2  DEFAULT NULL);
 
--
--
--
--
--
--
--
PROCEDURE lockDbidToImport(
   idb   IN varchar2);
 
--
--
--
--
--
--
--
--
PROCEDURE importSchema(
   dblink   IN varchar2
  ,idb      IN varchar2
  ,idbinc   IN varchar2);
 
--
--
--
--
--
PROCEDURE setArchiveFileScopeAttributes(logs_shared IN NUMBER);
 
--
PROCEDURE setBackupFileScopeAttributes(
                 disk_backups_shared IN NUMBER,
                 tape_backups_shared IN NUMBER);
 
 
--
--
--
--
--
--
PROCEDURE unregisterDatabase(
   idb      IN varchar2);
 
--
PROCEDURE clearUnarchivedLogs;
 
/*--------------------------------------*
 * Virtual Private Catalog Procedures   *
 *--------------------------------------*/
 
PROCEDURE grant_catalog(userid IN varchar2, dbname IN varchar2);
PROCEDURE grant_catalog(userid IN varchar2, 
                        dbid IN number,
                        reg_db_unique_name IN varchar2 default null);
PROCEDURE grant_register(userid IN varchar2);
PROCEDURE revoke_catalog(userid IN varchar2, dbname IN varchar2);
PROCEDURE revoke_catalog(userid IN varchar2, 
                         dbid IN number,
                         reg_db_unique_name IN varchar2 default null);
PROCEDURE revoke_register(userid IN varchar2);
PROCEDURE revoke_all(userid IN varchar2);
PROCEDURE create_virtual_catalog;
PROCEDURE drop_virtual_catalog;
PROCEDURE setupVPD(i_oper IN NUMBER);
 
PROCEDURE dumpPkgState (msg in varchar2 default NULL);
 
/*--------------------------------------*
 * Recovery Server Catalog Procedures   *
 *--------------------------------------*/
 
PROCEDURE put_bucket(bktname in varchar2);
FUNCTION get_bucket(bktname in varchar2) return CLOB;
PROCEDURE delete_bucket(bktname in varchar2);
--
--
--
 
PROCEDURE put_object(bktname in varchar2, objname in varchar2,
                     objtype in varchar2, objval in out CLOB);
FUNCTION get_object(bktname in varchar2, 
                    objname in varchar2,
                    parms   in varchar2 DEFAULT null) return CLOB;
PROCEDURE delete_object(bktname in varchar2, objname in varchar2);
 
PROCEDURE writeFixedSections(bktname IN VARCHAR2 DEFAULT NULL);
PROCEDURE readFixedSections(input_xml_filename  IN VARCHAR2,
                            bktname IN VARCHAR2 DEFAULT NULL);
PROCEDURE rsWriteWaterMarks (input_xml_filename  IN VARCHAR2,
                              bktname IN VARCHAR2 DEFAULT NULL);
PROCEDURE writeBackupSections(input_xml_filename  IN VARCHAR2,
                              bktname IN VARCHAR2 DEFAULT NULL);
PROCEDURE readBackupSections(bktname IN VARCHAR2 DEFAULT NULL);
 
PROCEDURE rsDeleteBackupPiece(bp_key IN number, purged IN varchar2);
 
PROCEDURE addTimeZone(
   db_unique_name IN VARCHAR2
  ,db_timezone    IN VARCHAR2
  ,tmz_src        IN VARCHAR2
  ,incarnations   IN VARCHAR2 default 'CURRENT'
);
--
--
--
--
--
--
--
--
--
--
--
--
--
 
FUNCTION getValueFromConfig(entry IN VARCHAR2) RETURN VARCHAR2;
--
--
 
PROCEDURE throttle_me(p_oam_job_id         IN VARCHAR2,
                      p_channels_reqd      IN NUMBER,
                      p_request_time       IN DATE,
                      p_wait               OUT BOOLEAN,
                      p_error_str          OUT VARCHAR2);
 
end dbms_rcvcat;
>>>
 
 
define dbmsrman_sql
<<<
create or replace package dbms_rcvman authid current_user is
 
--
 
--
--
--
 
TRUE#  CONSTANT number := 1;
FALSE# CONSTANT number := 0;
 
--
--
--
 
--
--
--
--
--
--
 
--
--
--
--
 
COPY                  CONSTANT NUMBER :=  1; -- any image copy of a file
FULL_DF_BACKUP        CONSTANT NUMBER :=  2; -- datafile in a full backup set
INCREMENTAL_DF_BACKUP CONSTANT NUMBER :=  3; -- datafile in an incr backup set
BACKUP                CONSTANT NUMBER :=  4; -- any file in a backup set
--
OFFLINE_RANGE         CONSTANT NUMBER :=  5; -- an offline range
CUMULATIVE            CONSTANT NUMBER :=  6; -- cumulative incremental
--
PROXY                 CONSTANT NUMBER :=  7; -- any proxy copy of a file
NONPROXY              CONSTANT NUMBER  := 9; -- any img, bs other than proxy
AVMCOPY               CONSTANT NUMBER := 10; -- only avm image copy of a file
SPARSE                CONSTANT NUMBER := 11; -- for sparse backup
NONSPARSE             CONSTANT NUMBER := 12; -- for nonsparse backup
 
--
 
implicitOfflRange CONSTANT NUMBER := 2**0;
cleanRange        CONSTANT NUMBER := 2**1;
applyOfflRange    CONSTANT NUMBER := 2**2;
dfCopy            CONSTANT NUMBER := 2**3;
proxyFull         CONSTANT NUMBER := 2**4;
buSet             CONSTANT NUMBER := 2**5;
applyIncremental  CONSTANT NUMBER := 2**6;
redo              CONSTANT NUMBER := 2**7;
 
--
maxKind           CONSTANT NUMBER := redo;            -- last real kind above
allKind           CONSTANT NUMBER := (maxKind*2) - 1; -- all real backup types
fullKind          CONSTANT NUMBER := dfCopy + proxyFull + buSet;
tagKind           CONSTANT NUMBER := fullKind + applyIncremental;
 
--
deletedKind       CONSTANT NUMBER := maxKind*2;      -- action deleted
 
--
--
--
 
BSavailable     CONSTANT BINARY_INTEGER := 2**0;
BSunavailable   CONSTANT BINARY_INTEGER := 2**1;
BSdeleted       CONSTANT BINARY_INTEGER := 2**2;
BSexpired       CONSTANT BINARY_INTEGER := 2**3;
--
--
--
--
BSpartial_avail CONSTANT BINARY_INTEGER := 2**4;
 
 
--
--
--
BSdatafile_full  CONSTANT BINARY_INTEGER := 2**0;
BSdatafile_incr  CONSTANT BINARY_INTEGER := 2**1;
BSarchivelog     CONSTANT BINARY_INTEGER := 2**2;
 
--
--
--
BScfile_all      CONSTANT BINARY_INTEGER := 2**0;      -- shouldn't be altered
BScfile_auto     CONSTANT BINARY_INTEGER := 2**1;
 
--
--
--
 
TYPE dfRec_t IS RECORD
(
   dfNumber             number,
   dfCreationSCN        number,
   dfCreationTime       date,
   fileName             varchar2(1024),
   tsName               varchar2(30),
   tsNumber             number,
   status               number,
   blocks               number,
   blockSize            number,
   kbytes               number,
   unrecovSCN           number,
   stopSCN              number,
   readOnly             number,
   rfNumber             number,
   inBackup             number,     -- if greater than 0 then
--
   auxName              varchar2(1024),
   dbincKey             number,
   dfOfflineSCN         number, 
   dfOnlineSCN          number, 
   dfOnlineTime         date,
   encrypt              number,     -- encrypt value 1=ON, 2=OFF, 3=CLEAR
   foreignDbid          number,         -- foreign database id
   pluggedRonly         binary_integer, -- 1 for read-only. Otherwise, 0
   pluginSCN            number,         -- plugin change#
   pluginRlgSCN         number,         -- plugin resetlogs_change#
   pluginRlgTime        date,           -- plugin resetlogs_time
   newDfCreationSCN     number,         -- plugin scn or creation scn
   creation_thread      number,         -- creation thread
   creation_size        number,         -- creation size
   pdbId                number,         -- pdbid
   pdbKey               number,         -- pdbKey
   pdbName              varchar2(128),  -- pdbname
   pdbClosed            number,         -- pdbclosed
   pdbForeignDbid       number, -- dbid of PDB from which this file came from
   pdbForeignCkpScn     number, -- foreign ckp scn of PDB datafile during plugin
   noBackupPdb          number,         -- this PDB is excluded from backup
   pdbForeignAfn        number  -- foreign PDB absolute datafile number
);
 
TYPE prePluginDfRec_t IS RECORD
(
   dfNumber             number,
   pdbId                number,
   prePluginDfNumber    number
);
   
--
--
--
 
TYPE tfRec_t IS RECORD
(
   tfNumber             number,
   tfCreationSCN        number,
   tfCreationTime       date,
   fileName             varchar2(1024),
   tsName               varchar2(30),
   tsNumber             number,
   status               number,
   isSFT                varchar2(3),
   blocks               number,
   blockSize            number,
   maxSize              number,
   nextSize             number,
   rfNumber             number,
   dbincKey             number,
   pdbId                number,
   pdbKey               number,
   pdbName              varchar2(128)
);
 
--
--
--
 
TYPE alRec_t IS RECORD
(
   key                  number,
   recid                number,
   stamp                number,
   thread               number,
   sequence             number,
   fileName             varchar2(1024),
   lowSCN               number,
   lowTime              date,
   nextSCN              number,
   nextTime             date,
   rlgSCN               number,
   rlgTime              date,
   blocks               number,
   blockSize            number,
   status               varchar2(1),
   compTime             date,
   duplicate            number,
   isrdf                varchar2(3),
   compressed           varchar2(3),
   stby                 varchar2(1),
   terminal             varchar2(3),
   site_key             number,
   site_key_order_col   number,
   source_dbid          number
);
 
--
--
--
--
--
--
 
--
--
--
--
--
--
 
--
--
--
--
 
--
 
--
--
--
 
TYPE rcvRec_t IS RECORD
(
--
 
   type_con             number,         -- recovery container type
   key_con              number,         -- primary key
   recid_con            number,         -- recid
   stamp_con            number,         -- stamp
   setStamp_con         number,         -- set count if backup set (null)
   setCount_con         number,         -- set stamp if backup set (null)
   bsRecid_con          number,         -- backup set recid (null)
   bsStamp_con          number,         -- backup set stamp (null)
   bsKey_con            number,         -- backup set key (null)
   bsLevel_con          number,         -- backup set level (null)
   bsType_con           varchar2(1),    -- backup set type
   elapseSecs_con       number,         -- backup set elapse seconds (null)
   pieceCount_con       number,         -- backup set piece count (null)
   fileName_con         varchar2(1024), -- filename if a copy (or) piece (null)
   tag_con              varchar2(32),   -- tag (null)
--
--
   copyNumber_con       number,         -- backup set copy# (null) maxlimit 256
--
   status_con           varchar2(1),    -- status (null)
   blocks_con           number,         -- size of file in blocks (null)
   blockSize_con        number,         -- block size (null)
   deviceType_con       varchar2(255),  -- device type required (null)
--
--
   compTime_con         date,           -- completion time
   cfCreationTime_con   date,           -- controlfile creation time if
--
   pieceNumber_con      number,
   bpCompTime_con       date,
   bpCompressed_con     varchar2(3),
 
   multi_section_con    varchar2(1),    -- multi-section backup piece
 
--
 
   type_act             number,         -- recovery action type
   fromSCN_act          number,
   toSCN_act            number,
   toTime_act           date,
   rlgSCN_act           number,
   rlgTime_act          date,
   dbincKey_act         number,
   level_act            number,
   section_size_act     number,
 
--
 
   dfNumber_obj         number,
   dfCreationSCN_obj    number,
   cfSequence_obj       number,        -- controlfile autobackup sequence
   cfDate_obj           date,          -- controlfile autobackup date
   logSequence_obj      number,
   logThread_obj        number,
   logRlgSCN_obj        number,
   logRlgTime_obj       date,
   logLowSCN_obj        number,
   logLowTime_obj       date,
   logNextSCN_obj       number,
   logNextTime_obj      date,
   logTerminal_obj      varchar2(3),
   cfType_obj           varchar2(1),   -- controlfile type ('B' or 'S')
   pdbKey_obj           number,
 
--
   keep_options         number,
   keep_until           date,
 
--
 
   afzSCN_act           number,
   rfzTime_act          date,
   rfzSCN_act           number,
 
--
   media_con            varchar2(80),    -- media volume name for backup piece
 
   isrdf_con            varchar2(3),
 
--
   site_key_con         number,
 
--
   foreignDbid_obj      number,         -- foreign database id
   pluggedRonly_obj     binary_integer, -- 1 for read-only. Otherwise, 0
   pluginSCN_obj        number,         -- plugin change#
   pluginRlgSCN_obj     number,         -- plugin resetlogs change#
   pluginRlgTime_obj    date,           -- plugin resetlogs time
 
--
   newDfCreationSCN_obj number,         -- plugin scn or creation scn
   newToSCN_act         number,         -- plugin scn or checkpoint scn
   newRlgSCN_act        number,         -- plugin rlgscn or rlgscn
   newRlgTime_act       date,           -- plugin rlgtime or rlgtime
 
--
   sfDbUniqueName_obj   varchar2(30),
 
--
   sparse_backup_con    varchar2(3),    -- whether sparse or nonsparse backup
   ppl_pdb_id_con       number,         -- preplugin pdb id
   ppl_cdb_dbid_con     number          -- preplugin cdb database id
);
 
--
--
--
 
--
--
--
--
--
--
--
--
 
--
 
offlineRangeRec_con_t   CONSTANT NUMBER := 2**0;
proxyCopy_con_t         CONSTANT NUMBER := 2**1;
imageCopy_con_t         CONSTANT NUMBER := 2**2;
backupSet_con_t         CONSTANT NUMBER := 2**3;
addredo_con_t           CONSTANT NUMBER := 2**4;
deleted_con_t           CONSTANT NUMBER := 2**8;
datafile_con_t          CONSTANT NUMBER := 2**9;
avmImageCopy_con_t      CONSTANT NUMBER := 2**10;
 
--
backupMask_con_t        CONSTANT NUMBER := proxyCopy_con_t + imageCopy_con_t +
                                           backupSet_con_t;
tagMask_con_t           CONSTANT NUMBER := proxyCopy_con_t + imageCopy_con_t +
                                           backupSet_con_t;
 
--
--
--
 
full_act_t              CONSTANT NUMBER := 2**0;
incremental_act_t       CONSTANT NUMBER := 2**1;
redo_act_t              CONSTANT NUMBER := 2**2;
offlineRange_act_t      CONSTANT NUMBER := 2**3;
cleanRange_act_t        CONSTANT NUMBER := 2**4;
implicitRange_act_t     CONSTANT NUMBER := 2**5;
spanningRange_act_t     CONSTANT NUMBER := 2**6;
createdatafile_act_t    CONSTANT NUMBER := 2**7;
 
--
--
--
 
--
--
--
 
getCfCopy               CONSTANT NUMBER := 0;
getDfCopy               CONSTANT NUMBER := 1;
getAnyProxy             CONSTANT NUMBER := 2;
getCfBackup             CONSTANT NUMBER := 3;
listCfCopy              CONSTANT NUMBER := 4;
listDfCopy              CONSTANT NUMBER := 5;
listCfBackup            CONSTANT NUMBER := 6;
listDfBackup            CONSTANT NUMBER := 7;
listAlBackup            CONSTANT NUMBER := 8;
listDfProxy             CONSTANT NUMBER := 9;
getRecovAction          CONSTANT NUMBER := 10;
getAlBackup             CONSTANT NUMBER := 11;
listAlCopy              CONSTANT NUMBER := 12;
listBSet                CONSTANT NUMBER := 13;
getSfBackup             CONSTANT NUMBER := 14;
listSfBackup            CONSTANT NUMBER := 15;
getAllBSet              CONSTANT NUMBER := 16;
listAlProxy             CONSTANT NUMBER := 17;
getRangeAlBackup        CONSTANT NUMBER := 18;
 
--
--
--
--
--
--
unknownCmd_t            CONSTANT BINARY_INTEGER := 0;
recoverCmd_t            CONSTANT BINARY_INTEGER := 1;
rcvCopyCmd_t            CONSTANT BINARY_INTEGER := 2;
obsoleteCmd_t           CONSTANT BINARY_INTEGER := 3;
restoreCmd_t            CONSTANT BINARY_INTEGER := 4;
blkRestoreCmd_t         CONSTANT BINARY_INTEGER := 5;
 
--
--
--
--
--
--
stuckMemorySize CONSTANT NUMBER := 50 * 1024 * 1024;
 
--
--
--
 
TYPE bsRec_t IS RECORD
(
   recid                number,
   stamp                number,
   key                  number,
   setStamp             number,
   setCount             number,
   bsType               varchar2(1),
   level                number,
   elapseSecs           number,
   compTime             date,
   status               varchar2(1),
   pieceCount           number,
   keep_options         number,
   keep_until           date,
   multi_section        varchar2(1),
   ppl_pdb_id           number,         -- preplugin pdb id
   ppl_cdb_dbid         number          -- preplugin cdb database id
);
 
--
--
--
 
TYPE bpRec_t IS RECORD
(
   recid                number,
   stamp                number,
   key                  number,
   bskey                number,
   setStamp             number,
   setCount             number,
   bsType               varchar2(1),
   pieceNumber          number,
   copyNumber           number,
   status               varchar2(1),
   compTime             date,
   handle               varchar2(1024),
   tag                  varchar2(32),
   deviceType           varchar2(255),
   media                varchar2(80),
   bytes                number,
   compressed           varchar2(3),
   site_key             number,
   vb_key               number,
   am_access            varchar2(1), -- need for 12.0 compatibility
   ba_access            varchar2(1),
   ppl_pdb_id           number,         -- preplugin pdb id
   ppl_cdb_dbid         number          -- preplugin cdb database id
);
 
--
--
--
 
TYPE validBackupSetRec_t IS RECORD
(
   deviceType   varchar2(255),
   tag          varchar2(32),                   -- may be null
   order1       number,                         -- preference hint
   copyNumber   number,                         -- null if code 2 or 3
   code         number                          -- 1 => same copy#
--
--
--
);
 
bsRecCacheEnabled   constant boolean := TRUE;  -- FALSE to use pre10i method
bsRecCacheLowLimit  constant number  := 2048;  -- minimum cache size
bsRecCacheHighLimit constant number  := 32768; -- maximum cache size
 
 
TYPE incarnation_t IS RECORD
(
INCARNATION#                                       NUMBER,
RESETLOGS_CHANGE#                                  NUMBER,
RESETLOGS_TIME                                     DATE,
PRIOR_RESETLOGS_CHANGE#                            NUMBER,
PRIOR_RESETLOGS_TIME                               DATE,
STATUS                                             VARCHAR2(7),
RESETLOGS_ID                                       NUMBER,
PRIOR_INCARNATION#                                 NUMBER
);
 
TYPE pdb_incarnation_t IS RECORD
(
CON_ID                                             NUMBER,
PDBINC_KEY                                         NUMBER,
INCSCN                                             NUMBER,
ERSCN                                              NUMBER,
STATUS                                             VARCHAR2(7)
);
 
--
--
--
TYPE bhistoryRec_t IS RECORD
(
   dfNumber        number,
   create_scn      number,
   reset_scn       number,
   reset_time      date,
   ckp_scn         number,
   ckp_time        date,
   stop_scn        number,
   logThread       number,
   logSequence     number,
   setStamp        number,
   setCount        number,
   compTime        date,
   nbackups        number,
   logTerminal     varchar2(3),
   next_scn        number,
   pluggedRonly    binary_integer, -- 1 for read-only. Otherwise, 0
   pluginSCN       number,
   pluginRlgSCN    number,
   pluginRlgTime   date,
   newcreate_scn   number,    -- create_scn or pluginSCN
   newreset_scn    number,    -- reset_scn  or pluginRlgSCN
   newreset_time   date       -- reset_time or pluginRlgTime
);
 
--
--
--
TYPE agedFileRec_t IS RECORD
(
   type           number,
   key            number,
   stamp          number,
   order_hint     number
);
 
--
--
--
 
--
--
--
backupset_txt      CONSTANT VARCHAR2(16) := 'BACKUP SET';
copy_txt           CONSTANT VARCHAR2(16) := 'COPY';
proxycopy_txt      CONSTANT VARCHAR2(16) := 'PROXY COPY';
datafile_txt       CONSTANT VARCHAR2(16) := 'DATAFILE';
spfile_txt         CONSTANT VARCHAR2(16) := 'SPFILE';
archivedlog_txt    CONSTANT VARCHAR2(16) := 'ARCHIVED LOG';
controlfile_txt    CONSTANT VARCHAR2(16) := 'CONTROLFILE';
piece_txt          CONSTANT VARCHAR2(16) := 'PIECE';
available_txt      CONSTANT VARCHAR2(16) := 'AVAILABLE';
unavailable_txt    CONSTANT VARCHAR2(16) := 'UNAVAILABLE';
expired_txt        CONSTANT VARCHAR2(16) := 'EXPIRED';
deleted_txt        CONSTANT VARCHAR2(16) := 'DELETED';
other_txt          CONSTANT VARCHAR2(16) := 'OTHER';
full_txt           CONSTANT VARCHAR2(16) := 'FULL';
incr1_txt          CONSTANT VARCHAR2(16) := 'INCR1';
incr2_txt          CONSTANT VARCHAR2(16) := 'INCR2';
incr3_txt          CONSTANT VARCHAR2(16) := 'INCR3';
incr4_txt          CONSTANT VARCHAR2(16) := 'INCR4';
incr_txt           CONSTANT VARCHAR2(16) := 'INCR';        -- level unknown
 
--
--
--
--
--
--
--
TYPE lbRec_t IS RECORD
(
   list_order1        NUMBER,       -- just hint to correctly order records
 
   list_order2        NUMBER,       -- just hint to correctly order records
 
   pkey               NUMBER,       -- primary key
--
--
--
   backup_type        VARCHAR2(32),  -- Type of the backup:
--
--
--
 
--
--
--
   file_type           VARCHAR2(32), -- Type of the file:
--
--
--
--
--
 
--
--
   keep               VARCHAR2(3),
   keep_until         DATE,
   keep_options       VARCHAR2(13),
   status             VARCHAR2(16),   -- Status of the piece/copy:
--
--
--
--
   fname              VARCHAR2(1024), -- piece or copy name
   tag                VARCHAR2(32),   -- piece or copy tag
   media              VARCHAR2(80),
   recid              NUMBER,
   stamp              NUMBER,
   device_type        VARCHAR2(255),
   block_size         NUMBER,
   completion_time    DATE,
   is_rdf             VARCHAR2(3),
   compressed         VARCHAR2(3),
   obsolete           VARCHAR2(3),
   keep_for_dbpitr    VARCHAR2(3),
   bytes              NUMBER,
 
--
--
   bs_key                NUMBER,        
   bs_count              NUMBER,        
   bs_stamp              NUMBER,        
   bs_type               VARCHAR2(32), -- Type of the backup set:
--
--
   bs_incr_type          VARCHAR2(32), 
   bs_pieces             NUMBER,
   bs_copies             NUMBER,
   bs_completion_time    DATE,
   bs_status             VARCHAR2(16),   -- Status of the backup set:
--
--
--
--
   bs_bytes              NUMBER,
   bs_compressed         VARCHAR2(3),    -- If backup set is compressed:
--
--
--
 
   bs_tag                VARCHAR2(1024), -- List of all tags of pieces.
--
--
 
   bs_device_type        VARCHAR2(255),  -- List of device types of pieces. 
--
 
--
--
   bp_piece#             NUMBER,
   bp_copy#              NUMBER,
   bp_vb_key             NUMBER,
   bp_ba_access          VARCHAR2(1),
   bp_lib_key            NUMBER,
 
--
--
   df_file#                  NUMBER,
   df_ts#                    NUMBER,
   df_plugin_change#         NUMBER,
   df_foreign_dbid           NUMBER,
   df_tablespace             VARCHAR2(30),
   df_resetlogs_change#      NUMBER,
   df_creation_change#       NUMBER,
   df_checkpoint_change#     NUMBER,
   df_ckp_mod_time           DATE, 
   df_incremental_change#    NUMBER,
   
--
--
   rl_thread#            NUMBER,
   rl_sequence#          NUMBER,
   rl_resetlogs_change#  NUMBER,
   rl_first_change#      NUMBER,
   rl_first_time         DATE,
   rl_next_change#       NUMBER,
   rl_next_time          DATE,
   rl_snapstandby        VARCHAR2(3),
 
--
   sf_db_unique_name     VARCHAR2(30),
 
--
   con_id                NUMBER
);
 
--
--
--
TYPE lbDfRec_t IS RECORD
(
   dfRec                dfRec_t,
--
--
--
--
--
   fullmin_scn           NUMBER,
   fullmin_rlgscn        NUMBER,
 
--
--
--
--
--
   incrmin_scn           NUMBER,
   incrmin_rlgscn        NUMBER,
 
--
--
--
--
--
   logmin_scn            NUMBER,
   logmin_rlgscn         NUMBER
);
 
TYPE lbDfRecTab_t  IS TABLE     OF lbDfRec_t      INDEX BY BINARY_INTEGER;
TYPE lbRecTab_t    IS TABLE     OF lbRec_t        INDEX BY BINARY_INTEGER;
TYPE lbRecVar_t    IS VARRAY(1) OF lbRec_t;
TYPE rcvRecTabI_t  IS TABLE     OF rcvRec_t       INDEX BY BINARY_INTEGER;
TYPE rcvRecTabII_t IS TABLE     OF rcvRecTabI_t   INDEX BY BINARY_INTEGER;
TYPE dfRecTab_t    IS TABLE     OF dfRec_t        INDEX BY BINARY_INTEGER;
TYPE numTab_t      IS TABLE     OF number         INDEX BY BINARY_INTEGER;
TYPE lbCursor_t    IS REF                         CURSOR;
 
--
--
--
--
--
TYPE lbState_t   IS RECORD
  (
--
--
--
   lbRecOutTab        lbRecTab_t,
   lbRecOutTab_count  binary_integer,
 
--
--
   lbRecTmpTab        lbRecTab_t,
 
--
   lbRecCmn           lbRec_t,
 
--
--
   lbDfRecTabUs       lbDfRecTab_t,
 
--
--
   lbDfRecTab         dfRecTab_t,
 
--
--
   lbMaxDfNumber      number,
 
--
   lbNowTime          date,
 
--
--
   lbPieceCountTab    numTab_t,
   lbCopyCount        binary_integer,
 
--
--
   lbMkTab            rcvRecTabII_t,
 
--
--
   lbMkITab           rcvRecTabII_t,
 
--
--
--
--
--
--
--
--
--
   lbMinGrsp         number,
 
--
--
--
--
--
   lbFbUntilTime     date,
 
--
--
--
--
   lbRlKeepRlgSCN     number,
 
--
--
--
--
--
--
   lbRlKeepSCN        number,
 
--
--
--
--
--
   lbObsoleteRetention boolean,
   lbKeepForDBPITR     boolean,
   lbObsoleteKeep      boolean,
 
   lbNeedObsoleteData  boolean
 );
 
--
--
--
lbStatePck   lbState_t;
 
--
--
--
 
--
--
--
--
--
--
--
--
 
TYPE restoreRange_t IS RECORD
(
   lowTime       DATE,
   highTime      DATE,
   startScn      NUMBER,
   lowScn        NUMBER,
   highScn       NUMBER,
   lowDbIncKey   NUMBER,
   highDbIncKey  NUMBER,
   lowRlgScn     NUMBER,
   highRlgScn    NUMBER,
   lowRlgTime    DATE,
   highRlgTime   DATE,
   rcvStartScn   NUMBER,
   rcvStartTime  DATE,
   isValidRange  BOOLEAN,
   cfBkupFound   BOOLEAN,
   con_id        NUMBER
);
 
TYPE restoreRangeTab_t IS TABLE OF restoreRange_t INDEX BY BINARY_INTEGER;
 
--
 
TYPE failureRec_t IS RECORD
(
   priority      VARCHAR2(8),
   failureId     NUMBER,
   parentId      NUMBER,
   childCount    NUMBER,
   description   VARCHAR2(1024),
   timeDetected  DATE,
   status        VARCHAR2(12),
   impacts       VARCHAR2(1024)
);
 
TYPE repairRec_t IS RECORD
(
   type          NUMBER,
   failureidx    NUMBER,
   repairidx     NUMBER,
   description   VARCHAR2(1024)
);
 
TYPE repairParmsRec_t IS RECORD
(
   type          NUMBER,
   failureidx    NUMBER,
   repairidx     NUMBER,
   name          VARCHAR2(256),
   value         VARCHAR2(512)
);
 
TYPE repairOptionRec_t IS RECORD
(
   optionidx     NUMBER,
   description   VARCHAR2(1024)
);
 
TYPE repairStepRec_t IS RECORD
(
   type           NUMBER,
   failureidx     NUMBER,
   repairidx      NUMBER,
   repairstepidx  NUMBER,
   workingrepair  NUMBER,
   description    VARCHAR2(1024),
   repairscript   VARCHAR2(1024)
);
    
--
--
--
TYPE pdbNameRec_t IS RECORD
(
   pdbId    NUMBER,
   name     VARCHAR2(128),
   pdbGuid  VARCHAR2(128)
);
 
TYPE pdbFileRec_t IS RECORD
(
   pdbId    NUMBER,
   file#    NUMBER,
   stopSCN  NUMBER
);
 
cdbRoot_txt  CONSTANT VARCHAR2(8) := 'CDB$ROOT';
 
--
--
--
 
--
--
--
 
FUNCTION dumpState(
   lineno IN number)
RETURN varchar2;
 
PROCEDURE dumpPkgState(msg in varchar2 default null);
 
PROCEDURE setDebugOn;
 
PROCEDURE setDebugOff;
 
--
--
--
--
--
--
--
 
PROCEDURE initialize(rman_vsn IN number);
 
--
--
--
 
PROCEDURE set_package_constants;
 
--
--
--
 
FUNCTION stamp2date(stamp IN number) RETURN date;
 
--
--
--
PROCEDURE getCurrentIncarnation(
   db_id          IN  number
  ,reset_scn      OUT number
  ,reset_time     OUT date);
 
--
--
--
 
--
--
--
--
--
--
--
--
 
--
--
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
 
PROCEDURE setDatabase(
   db_name    IN varchar2
  ,reset_scn  IN number
  ,reset_time IN date
  ,db_id      IN number
  ,db_unique_name IN varchar2 default NULL
  ,site_aware IN boolean default FALSE
  ,dummy_instance  IN boolean default FALSE
  ,ors_instance    IN boolean default FALSE);
 
--
--
--
FUNCTION getDbUniqueName(
   db_id      IN number)
RETURN varchar2;
 
--
FUNCTION getDbKey RETURN NUMBER;
 
--
FUNCTION getMinRcvStartScn RETURN NUMBER;
 
--
PROCEDURE resetDbKey;
 
--
--
FUNCTION DbUniqueNameIsStandby
RETURN NUMBER;
 
--
--
PROCEDURE setCanConvertCf(flag IN boolean);
 
--
--
PROCEDURE setDbincKey(
   key IN number);
 
--
--
--
 
FUNCTION getParentIncarnation(
   resetlogs_change# IN OUT number
  ,resetlogs_time    IN OUT date)
RETURN number;
 
--
--
--
--
 
PROCEDURE getCheckpoint(
   scn OUT number
  ,seq OUT number);
 
--
--
 
PROCEDURE getCheckpoint(
   scn       OUT number
  ,seq       OUT number
  ,ckp_key_1 OUT number
  ,ckp_key_2 OUT number);
 
--
--
--
PROCEDURE SetGetSinceLastBackedAL(ntimes  IN number DEFAULT 1,
                                  devtype IN varchar2 DEFAULT NULL,
                                  sbpscn  IN number);
 
--
--
--
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
 
PROCEDURE setCompletedRange(
   after  IN date
  ,before IN date);
 
PROCEDURE setLikePattern(
   pattern IN varchar2);
 
PROCEDURE setcanApplyAnyRedo(
   flag IN boolean);
 
--
PROCEDURE setBigScnAware;
 
--
PROCEDURE setAllFlag(
   flag IN boolean);
 
PROCEDURE setAllIncarnations(
   flag IN boolean);
 
PROCEDURE setUntilTime(
   unttime IN date);
 
--
--
--
--
--
--
PROCEDURE setUntilScn(
   scn     IN number
  ,rlgscn  IN number  DEFAULT NULL
  ,rlgtime IN date    DEFAULT NULL
  ,flbrp   IN boolean DEFAULT FALSE
  ,rpoint  IN boolean DEFAULT FALSE);
 
PROCEDURE setUntilLog(
   sequence# IN number
  ,thread#   IN number);
 
PROCEDURE setToLog(
   sequence# IN number
  ,thread#   IN number);
 
PROCEDURE setUntilResetlogs;
 
PROCEDURE setGuid(guid IN varchar2 DEFAULT NULL);
 
FUNCTION getUntilTime return date;
 
FUNCTION getUntilScn return number;
 
PROCEDURE resetUntil;
 
--
--
--
--
--
--
--
 
PROCEDURE setFrom(
   restorefrom IN number DEFAULT NULL);
 
--
--
--
--
--
--
PROCEDURE setSparseness(
   sparseness IN number DEFAULT NULL);
 
--
--
--
--
--
--
--
--
--
--
--
--
--
 
PROCEDURE setDeviceType(
   type IN varchar2);
 
--
--
 
PROCEDURE setStandby(
   stby IN boolean);
 
PROCEDURE setDeviceTypeAny;
 
--
 
PROCEDURE resetDeviceType;
 
--
--
--
--
--
--
--
--
 
PROCEDURE setTag(tag IN varchar2 DEFAULT NULL);
 
--
--
--
--
--
--
--
 
PROCEDURE setRecoveryDestFile(onlyrdf IN BOOLEAN);
 
--
--
--
--
--
--
--
--
--
PROCEDURE setOrsFile(localOnly IN BOOLEAN, libKey IN NUMBER);
 
--
--
--
--
--
PROCEDURE setSiteName(db_unique_name IN VARCHAR2, for_realfiles IN NUMBER);
 
--
PROCEDURE clrSiteName;
 
--
FUNCTION getSiteName(site_key IN NUMBER) RETURN VARCHAR2;
 
--
FUNCTION getSiteKey(db_unique_name IN VARCHAR2) RETURN NUMBER;
 
--
PROCEDURE setArchiveFileScopeAttributes(logs_shared IN NUMBER);
 
--
PROCEDURE setFirstFullBckScopeAttributes(baseline_cap IN NUMBER);
 
--
PROCEDURE setBackupFileScopeAttributes(
                 disk_backups_shared IN NUMBER,
                 tape_backups_shared IN NUMBER);
 
--
--
 
PROCEDURE resetAll(transclause IN BOOLEAN DEFAULT TRUE);
 
--
--
--
 
--
--
 
findValidBackupSetRcvRec rcvRec_t;              -- place to save a rcvRec_t
 
PROCEDURE findValidBackupSet(
   backupSetRec            IN     rcvRec_t
  ,deviceType              IN     varchar2       DEFAULT NULL
  ,tag                     IN     varchar2       DEFAULT NULL
  ,available               IN     number         DEFAULT TRUE#  -- for compat.
  ,unavailable             IN     number         DEFAULT FALSE# -- for compat.
  ,deleted                 IN     number         DEFAULT FALSE# -- for compat.
  ,expired                 IN     number         DEFAULT FALSE# -- for compat.
  ,availableMask           IN     binary_integer DEFAULT NULL); -- for compat.
 
findValidBackupSetBsRec  bsRec_t;               -- place to save a bsRec_t
 
--
PROCEDURE findValidBackupSet(
   backupSetRec            IN     bsRec_t
  ,deviceType              IN     varchar2       DEFAULT NULL
  ,tag                     IN     varchar2       DEFAULT NULL
  ,available               IN     number         DEFAULT TRUE#  -- for compat.
  ,unavailable             IN     number         DEFAULT FALSE# -- for compat.
  ,deleted                 IN     number         DEFAULT FALSE# -- for compat.
  ,expired                 IN     number         DEFAULT FALSE# -- for compat.
  ,availableMask           IN     binary_integer DEFAULT NULL); -- for compat.
 
FUNCTION getValidBackupSet(
   validBackupSetRec            OUT NOCOPY validBackupSetRec_t
  ,checkDeviceIsAllocated       IN  number DEFAULT FALSE#)
RETURN number;                                  -- TRUE# -> got a record
--
 
--
--
--
 
--
--
--
--
--
--
 
FUNCTION getRcvRec(
   funCode      IN number
  ,rcvRec       OUT NOCOPY rcvRec_t
  ,callAgain    OUT number)
RETURN number;
 
--
--
--
 
--
--
--
--
--
--
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
 
--
--
--
--
--
--
--
--
--
--
--
--
--
 
PROCEDURE translateDatabase(
   sinceUntilSCN IN number DEFAULT NULL);
 
PROCEDURE skipTableSpace(
   tsName  IN varchar2
  ,pdbId   IN number DEFAULT 0);
 
PROCEDURE translateTablespace(
   ts_name IN varchar2, pdb_id IN number DEFAULT 0);
 
--
--
--
--
--
--
--
--
--
--
--
 
--
--
--
--
--
--
--
--
--
--
--
 
PROCEDURE translateDataFile(
   fname IN varchar2);
 
PROCEDURE translateDatafile(
   fno   IN number);
 
PROCEDURE translateDatafile(
   fno    IN number
  ,ckpscn IN number);
 
--
--
 
PROCEDURE translateAllDatafile;
 
PROCEDURE translateCorruptList;
 
PROCEDURE getDatafile(
   dfRec     OUT NOCOPY dfRec_t
  ,oldClient IN  boolean DEFAULT FALSE);
 
--
PROCEDURE getDataFile(
   file#        OUT number
  ,crescn       OUT number
  ,creation_time OUT date
  ,fname        OUT varchar2
  ,ts_name      OUT varchar2
  ,status       OUT number
  ,blksize      OUT number
  ,kbytes       OUT number
  ,blocks       OUT number
  ,unrecoverable_change# OUT number
  ,stop_change# OUT number
  ,read_only    OUT number);
 
--
--
--
--
--
 
PROCEDURE translatePrePluginDf(con_id IN number);
 
FUNCTION getPrePluginDf(
   prePluginDfRec OUT NOCOPY prePluginDfRec_t)
RETURN NUMBER;
 
--
--
--
--
--
PROCEDURE translateTempfile;
 
PROCEDURE translateTempfile(fname IN varchar2);
 
PROCEDURE translateTempfile(fno IN number);
 
--
--
--
PROCEDURE getTempfile(tfRec OUT NOCOPY tfRec_t);
 
--
--
--
 
--
--
 
PROCEDURE translateOnlineLogs(srls IN number DEFAULT 0);
 
PROCEDURE getOnlineLog(
   fname        OUT varchar2
  ,thread#      OUT number
  ,group#       OUT number);
 
--
--
--
 
--
--
 
--
--
--
--
 
--
--
--
--
 
--
--
--
--
 
--
--
--
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
 
--
--
--
 
PROCEDURE getArchivedLog(
   alRec       OUT NOCOPY alRec_t
  ,closeCursor IN  boolean DEFAULT FALSE);
 
PROCEDURE translateArchivedLogKey(
   al_key       IN  number
  ,available    IN  number       DEFAULT 1 -- ignored (for compatability)
  ,unavailable  IN  number       DEFAULT 1 -- ignored (for compatability)
  ,deleted      IN  number       DEFAULT 1 -- ignored (for compatability)
  ,online       IN  number       DEFAULT 1 -- ignored (for compatability)
  ,recid        OUT number
  ,stamp        OUT number
  ,thread#      OUT number
  ,sequence#    OUT number
  ,low_scn      OUT number
  ,reset_scn    OUT number
  ,block_size   OUT number
  ,fname        OUT varchar2
  ,needstby     IN number        DEFAULT NULL);
 
PROCEDURE translateArchivedLogName(
   fname        IN varchar2
  ,available    IN number         DEFAULT NULL   -- for compatability
  ,unavailable  IN number         DEFAULT NULL   -- for compatability
  ,deleted      IN number         DEFAULT NULL   -- for compatability
  ,online       IN number                        -- ignored
  ,duplicates   IN number
  ,statusMask   IN binary_integer DEFAULT NULL   -- for compatability
  ,needstby     IN number         DEFAULT NULL); -- for compatability
 
--
--
--
--
--
 
PROCEDURE translateArchivedLogSeqRange(
   thread#      IN number
  ,fromseq#     IN number
  ,toseq#       IN number
  ,pattern      IN varchar2
  ,available    IN number         DEFAULT NULL     -- for compatability
  ,unavailable  IN number         DEFAULT NULL     -- for compatability
  ,deleted      IN number         DEFAULT NULL     -- for compatability
  ,online       IN number                          -- ignored
  ,duplicates   IN number
  ,statusMask   IN binary_integer DEFAULT NULL     -- for compatability
  ,needstby     IN number         DEFAULT NULL     -- for compatability
  ,foreignal    IN binary_integer DEFAULT 0        -- for compatability
  ,incarn       IN number         DEFAULT NULL);   -- for compatibility
 
PROCEDURE translateArchivedLogTimeRange(
   thread#      IN number
  ,fromTime     IN date
  ,toTime       IN date
  ,pattern      IN varchar2
  ,available    IN number         DEFAULT NULL     -- for compatability
  ,unavailable  IN number         DEFAULT NULL     -- for compatability
  ,deleted      IN number         DEFAULT NULL     -- for compatability
  ,online       IN number                          -- ignored
  ,duplicates   IN number
  ,statusMask   IN binary_integer DEFAULT NULL     -- for compatability
  ,needstby     IN number         DEFAULT NULL     -- for compatability
  ,foreignal    IN binary_integer DEFAULT 0        -- for compatability
  ,incarn       IN number         DEFAULT NULL);   -- for compatibility
 
PROCEDURE translateArchivedLogSCNRange(
   thread#      IN number
  ,fromSCN      IN number
  ,toSCN        IN number
  ,pattern      IN varchar2
  ,available    IN number         DEFAULT NULL     -- for compatability
  ,unavailable  IN number         DEFAULT NULL     -- for compatability
  ,deleted      IN number         DEFAULT NULL     -- for compatability
  ,online       IN number
  ,duplicates   IN number
  ,statusMask   IN binary_integer DEFAULT NULL     -- for compatability
  ,needstby     IN number         DEFAULT NULL
  ,doingRecovery IN  number DEFAULT FALSE#
  ,onlyrdf      IN binary_integer DEFAULT 0        -- for compatability
  ,reset_scn    IN number         DEFAULT NULL     -- for compatability
  ,reset_time   IN date           DEFAULT NULL     -- for compatability
  ,sequence#    IN number         DEFAULT NULL     -- for compatability
  ,foreignal    IN binary_integer DEFAULT 0        -- for compatability
  ,incarn       IN number         DEFAULT NULL);   -- for compatibility
 
PROCEDURE translateArchivedLogPattern(
   pattern      IN varchar2
  ,available    IN number         DEFAULT NULL     -- for compatability
  ,unavailable  IN number         DEFAULT NULL     -- for compatability
  ,deleted      IN number         DEFAULT NULL     -- for compatability
  ,online       IN number                          -- ignored
  ,duplicates   IN number
  ,statusMask   IN binary_integer DEFAULT NULL     -- for compatability
  ,needstby     IN number         DEFAULT NULL     -- for compatability
  ,foreignal    IN binary_integer DEFAULT 0);      -- for compatability
 
PROCEDURE translateArchivedLogCancel;
 
 
--
PROCEDURE sv_setSessionKey(skey IN NUMBER);
PROCEDURE sv_setSessionTimeRange(fromTime IN DATE, untilTime IN DATE);
 
FUNCTION sv_getSessionKey RETURN NUMBER;
FUNCTION sv_getSessionfromTimeRange RETURN DATE;
FUNCTION sv_getSessionUntilTimeRange RETURN DATE;
 
--
--
--
 
--
--
--
--
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
 
--
PROCEDURE getArchivedLog(
   recid        OUT number
  ,stamp        OUT number
  ,thread#      OUT number
  ,sequence#    OUT number
  ,low_scn      OUT number
  ,nxt_scn      OUT number
  ,fname        OUT varchar2
  ,reset_scn    OUT number
  ,block_size   OUT number
  ,blocks       OUT number);
 
--
--
--
 
--
--
--
--
--
--
--
--
--
 
PROCEDURE translateControlFileCopyName(
   fname        IN varchar2
  ,available    IN number         DEFAULT NULL -- for compatability
  ,unavailable  IN number         DEFAULT NULL -- for compatability
  ,duplicates   IN number
  ,statusMask   IN binary_integer DEFAULT NULL -- for compatability
  ,onlyone      IN number         DEFAULT 1);
 
PROCEDURE translateControlFileCopyTag(
   cftag        IN varchar2
  ,available    IN number         DEFAULT NULL -- for compatability
  ,unavailable  IN number         DEFAULT NULL -- for compatability
  ,duplicates   IN number
  ,statusMask   IN binary_integer DEFAULT NULL -- for compatability
  ,onlyone      IN number         DEFAULT 1);
 
PROCEDURE translateControlFileCopyKey(
   key          IN number
  ,available    IN number         DEFAULT NULL    -- for compatability
  ,unavailable  IN number         DEFAULT NULL    -- for compatability
  ,statusMask   IN binary_integer DEFAULT NULL);  -- for compatability
 
 
PROCEDURE getControlFileCopy(
   rcvRec       IN OUT NOCOPY rcvRec_t);
 
--
PROCEDURE getControlFileCopy(
   recid        OUT number
  ,stamp        OUT number
  ,reset_scn    OUT number
  ,ckp_scn      OUT number
  ,block_size   OUT number);
 
--
--
--
 
PROCEDURE getDataFileCopy(
   rcvRec       OUT NOCOPY rcvRec_t
  ,closeCursor  IN  boolean DEFAULT FALSE);
 
--
--
 
--
--
 
--
--
--
--
--
 
--
--
--
 
--
--
--
--
--
--
 
--
--
--
--
 
--
--
--
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
 
PROCEDURE translateDataFileCopyKey(
   cdf_key      IN number
  ,available    IN number         DEFAULT NULL   -- for compatability
  ,unavailable  IN number         DEFAULT NULL   -- for compatability
  ,statusMask   IN binary_integer DEFAULT NULL); -- for compatability
 
--
PROCEDURE translateDataFileCopyKey(
   cdf_key      IN number
  ,available    IN number
  ,unavailable  IN number
  ,recid        OUT number
  ,stamp        OUT number
  ,file#        OUT number
  ,fname        OUT varchar2
  ,reset_scn    OUT number
  ,create_scn   OUT number
  ,ckp_scn      OUT number
  ,block_size   OUT number
  ,blocks       OUT number);
 
PROCEDURE translateDataFileCopyName(
   fname        IN varchar2
  ,available    IN number         DEFAULT NULL   -- for compatability
  ,unavailable  IN number         DEFAULT NULL   -- for compatability
  ,duplicates   IN number
  ,statusMask   IN binary_integer DEFAULT NULL   -- for compatability
  ,onlyone      IN number         DEFAULT 1
  ,pluginSCN    IN number         DEFAULT 0);
 
PROCEDURE translateDataFileCopyTag(
   tag          IN varchar2
  ,available    IN number         DEFAULT NULL     -- for compatibility
  ,unavailable  IN number         DEFAULT NULL     -- for compatibility
  ,duplicates   IN number
  ,statusMask   IN binary_integer DEFAULT NULL     -- for compatibility
  ,pluginSCN    IN number         DEFAULT 0
  ,onlytc       IN binary_integer DEFAULT FALSE#); -- for compatibility
 
PROCEDURE translateDataFileCopyFno(
   fno          IN number
  ,available    IN number         DEFAULT NULL
  ,unavailable  IN number         DEFAULT NULL
  ,duplicates   IN number
  ,statusMask   IN binary_integer DEFAULT NULL
  ,pluginSCN    IN number         DEFAULT 0);
 
PROCEDURE translateDataFileCopy(
   duplicates   IN number
  ,statusMask   IN binary_integer
  ,onlyrdf      IN binary_integer
  ,pluginSCN    IN number         DEFAULT 0);
 
--
PROCEDURE translateDatafileCancel;
 
--
PROCEDURE getDataFileCopy(
   recid        OUT number
  ,stamp        OUT number
  ,file#        OUT number
  ,fname        OUT varchar2
  ,reset_scn    OUT number
  ,create_scn   OUT number
  ,ckp_scn      OUT number
  ,block_size   OUT number
  ,blocks       OUT number);
 
--
--
--
 
PROCEDURE getProxyCopy(
   rcvRec       OUT NOCOPY rcvRec_t
  ,closeCursor  IN  boolean DEFAULT FALSE);
 
PROCEDURE translateProxyCopyKey(
   pc_key       IN number
  ,deviceType   IN varchar2
  ,available    IN number           DEFAULT NULL   -- for compatability
  ,unavailable  IN number           DEFAULT NULL   -- for compatability
  ,deleted      IN number           DEFAULT NULL   -- for compatability
  ,expired      IN number           DEFAULT NULL   -- for compatability
  ,statusMask   IN binary_integer   DEFAULT NULL); -- for compatability
 
--
PROCEDURE translateProxyCopyKey(
   pc_key       IN number
  ,device_type  IN varchar2
  ,available    IN number
  ,unavailable  IN number
  ,deleted      IN number
  ,recid        OUT number
  ,stamp        OUT number
  ,handle       OUT varchar2);
 
PROCEDURE translateProxyCopyHandle(
   handle       IN varchar2
  ,deviceType   IN varchar2
  ,available    IN number           DEFAULT NULL   -- for compatability
  ,unavailable  IN number           DEFAULT NULL   -- for compatability
  ,deleted      IN number           DEFAULT NULL   -- for compatability
  ,expired      IN number           DEFAULT NULL   -- for compatability
  ,statusMask   IN binary_integer   DEFAULT NULL); -- for compatability
 
--
PROCEDURE translateProxyCopyHandle(
   handle       IN varchar2
  ,device_type  IN varchar2
  ,available    IN number
  ,unavailable  IN number
  ,deleted      IN number
  ,recid        OUT number
  ,stamp        OUT number);
 
PROCEDURE translateProxyCopyTag(
   tag          IN varchar2
  ,device_type  IN varchar2
  ,available    IN number           DEFAULT NULL   -- for compatability
  ,unavailable  IN number           DEFAULT NULL   -- for compatability
  ,deleted      IN number           DEFAULT NULL   -- for compatability
  ,statusMask   IN binary_integer   DEFAULT NULL); -- for compatability
 
PROCEDURE translateProxyCopyGuid(
   guid         IN varchar2
  ,device_type  IN varchar2
  ,statusMask   IN binary_integer);
 
--
--
--
--
 
--
--
 
--
--
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
 
--
PROCEDURE getProxyCopy(
   recid OUT number
  ,stamp OUT number
  ,handle OUT varchar2);
 
--
--
--
 
PROCEDURE getBackupPiece(
   bpRec        OUT NOCOPY bpRec_t
  ,closeCursor  IN  boolean DEFAULT FALSE);
 
PROCEDURE translateBackupPieceKey(
   key         IN  number
  ,available   IN  number            DEFAULT TRUE#
  ,unavailable IN  number            DEFAULT TRUE#
  ,expired     IN  number            DEFAULT TRUE#
  ,statusMask  IN  binary_integer    DEFAULT NULL);   -- for compatability
 
PROCEDURE translateBackupPieceKey(                        -- only used in 8.1.6
   bp_key       IN  number
  ,available    IN  number
  ,unavailable  IN  number
  ,recid        OUT number
  ,stamp        OUT number
  ,handle       OUT varchar2
  ,set_stamp    OUT number
  ,set_count    OUT number
  ,piece#       OUT number);
 
PROCEDURE translateBackupPieceHandle(
   handle      IN  varchar2
  ,deviceType  IN  varchar2
  ,available   IN  number            DEFAULT NULL     -- for compatability
  ,unavailable IN  number            DEFAULT NULL     -- for compatability
  ,expired     IN  number            DEFAULT NULL     -- for compatability
  ,statusMask  IN  binary_integer    DEFAULT NULL);   -- for compatability
 
PROCEDURE translateBackupPieceHandle(                     -- only used in 8.1.6
   handle       IN  varchar2
  ,device_type  IN  varchar2
  ,available    IN  number
  ,unavailable  IN  number
  ,recid        OUT number
  ,stamp        OUT number
  ,set_stamp    OUT number
  ,set_count    OUT number
  ,piece#       OUT number);
 
PROCEDURE translateBackupPieceTag(
   tag          IN varchar2
  ,available    IN number             DEFAULT NULL     -- for compatability
  ,unavailable  IN number             DEFAULT NULL     -- for compatability
  ,statusMask   IN binary_integer     DEFAULT NULL);   -- for compatability
 
PROCEDURE translateBackupPieceGuid(
   guid         IN varchar2
  ,statusMask   IN binary_integer);
 
PROCEDURE translateBackupPieceBSKey(
   key          IN number
  ,tag          IN varchar2           DEFAULT NULL
  ,deviceType   IN varchar2           DEFAULT NULL
  ,pieceCount   IN number
  ,duplicates   IN number             DEFAULT TRUE#
  ,copyNumber   IN number             DEFAULT NULL
  ,available    IN number             DEFAULT TRUE#
  ,unavailable  IN number             DEFAULT FALSE#
  ,deleted      IN number             DEFAULT FALSE#
  ,expired      IN number             DEFAULT FALSE#
  ,statusMask   IN binary_integer     DEFAULT NULL);   -- for compatability
 
PROCEDURE translateBackupPieceBsKey(
   startBsKey   IN number
  ,tag          IN varchar2        DEFAULT NULL
  ,statusMask   IN binary_integer  DEFAULT NULL);
--
--
   
PROCEDURE translateSeekBpBsKey(
   bsKey        IN number
  ,deviceType   IN varchar2
  ,pieceCount   IN number
  ,duplicates   IN number   DEFAULT TRUE#
  ,copyNumber   IN number   DEFAULT NULL);
--
--
--
--
--
--
--
--
--
 
PROCEDURE translateBpBsKeyCancel;
--
--
--
 
--
PROCEDURE translateBackupSetKey(
   bs_key          IN  number
  ,device_type     IN  varchar2
  ,available       IN  number
  ,unavailable     IN  number
  ,deleted         IN  number
  ,duplicates      IN  number
  ,backup_type     OUT varchar2
  ,recid           OUT number
  ,stamp           OUT number
  ,set_stamp       OUT number
  ,set_count       OUT number
  ,bslevel         OUT number
  ,completion_time OUT date);
 
--
PROCEDURE translateBackupSetKey(
   bs_key      IN  number
  ,device_type IN  varchar2
  ,available   IN  number
  ,unavailable IN  number
  ,deleted     IN  number
  ,duplicates  IN  number
  ,backup_type OUT varchar2
  ,recid       OUT number
  ,stamp       OUT number);
 
--
PROCEDURE translateBackupSetRecid(
   recid       IN  number
  ,stamp       IN  number
  ,device_type IN  varchar2
  ,bs_key      OUT number
  ,bslevel     OUT number
  ,completed   OUT date);
 
--
PROCEDURE translateBackupSetRecid(
   recid       IN  number
  ,stamp       IN  number
  ,device_type IN  varchar2);
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
 
--
PROCEDURE getBackupPiece(
   recid      OUT number
  ,stamp      OUT number
  ,bpkey      OUT number
  ,set_stamp  OUT number
  ,set_count  OUT number
  ,piece#     OUT number
  ,copy#      OUT number
  ,status     OUT varchar2
  ,completion OUT date
  ,handle     OUT varchar2);
 
--
PROCEDURE getBackupPiece(
   recid      OUT number
  ,stamp      OUT number
  ,set_stamp  OUT number
  ,set_count  OUT number
  ,piece#     OUT number
  ,handle     OUT varchar2);
 
--
--
--
 
PROCEDURE translateBackupSetKey(
   key        IN  number
  ,bsRec      OUT NOCOPY bsRec_t);
 
PROCEDURE translateAllBackupSet(
   backupType            IN  binary_integer
  ,tag                   IN  varchar2
  ,statusMask            IN  binary_integer
  ,completedAfter        IN  date
  ,completedBefore       IN  date
  ,onlyrdf               IN  binary_integer DEFAULT 0);
 
PROCEDURE getAllBackupSet(
   rcvRec OUT NOCOPY rcvRec_t);
 
--
--
--
 
FUNCTION translatePdb2Name(
   pdbId IN NUMBER)
RETURN VARCHAR2;
 
FUNCTION translatePdbGuid2Name(
   pdbGuid IN VARCHAR2,
   pdbId OUT NUMBER)
 RETURN VARCHAR2;
 
--
--
--
 
--
--
--
--
--
--
PROCEDURE findControlfileBackup(
   allCopies      IN boolean default FALSE,
   allBackups     IN boolean default FALSE,
   allIncarnation IN boolean default FALSE,
   fromSCN        IN number  default 0,
   pdbid          IN number  default 0);
 
--
--
FUNCTION getControlfileBackup(
   rcvRec     OUT NOCOPY rcvRec_t)
RETURN number;
 
--
FUNCTION getPrimaryDfName(fno IN NUMBER) RETURN VARCHAR2;
 
--
--
--
--
 
--
FUNCTION findControlFileBackup(
   type         OUT number
  ,recid        OUT number
  ,stamp        OUT number
  ,fname        OUT varchar2
  ,device_type  OUT varchar2
  ,ckp_scn      OUT number)
RETURN number;
 
--
FUNCTION findControlFileBackup(
   type         OUT number
  ,recid        OUT number
  ,stamp        OUT number
  ,fname        OUT varchar2
  ,device_type  OUT varchar2
  ,ckp_scn      OUT number
  ,rlg_scn      OUT number
  ,blksize      OUT number)
RETURN number;
 
--
--
--
 
PROCEDURE findRangeArchivedLogBackup(
   minthread    IN number
  ,minsequence  IN number
  ,minlowSCN    IN number
  ,maxthread    IN number
  ,maxsequence  IN number
  ,maxlowSCN    IN number
  ,allCopies    IN boolean default FALSE);
 
--
--
--
--
--
--
--
--
--
--
--
 
--
PROCEDURE findArchivedLogBackup(
   thread    IN number
  ,sequence  IN number
  ,lowSCN    IN number
  ,allCopies IN boolean default FALSE);
 
--
--
--
--
--
--
--
--
--
 
--
FUNCTION getArchivedLogBackup(
   rcvRec       OUT NOCOPY rcvRec_t)
RETURN binary_integer;
 
--
FUNCTION findArchivedLogBackup(
   thread#    IN  number
  ,sequence#  IN  number
  ,low_scn    IN  number
  ,type       OUT number
  ,recid      OUT number
  ,stamp      OUT number
  ,device_type OUT varchar2)
RETURN number;
 
--
--
--
 
--
--
--
--
PROCEDURE findSpfileBackup(
   allCopies  IN boolean default FALSE
  ,redundancy IN number  default NULL
  ,rmanCmd    IN number  default unknownCmd_t);
 
PROCEDURE findSpfileBackup(
   allCopies  IN boolean default FALSE
  ,redundancy IN number  default NULL
  ,rmanCmd    IN number  default unknownCmd_t
  ,scn_warn  OUT number);
 
--
--
FUNCTION getSpfileBackup(
   rcvRec       OUT NOCOPY rcvRec_t
  ,redundancy   IN         number default NULL
  ,rmanCmd      IN         number default unknownCmd_t)
RETURN number;
 
--
--
--
 
PROCEDURE listTranslateControlfileCopy(
   tag             IN  varchar2
  ,completedAfter  IN  date
  ,completedBefore IN  date
  ,statusMask      IN  binary_integer   DEFAULT
                       BSavailable+BSunavailable+BSexpired
  ,liststby        IN  binary_integer   DEFAULT NULL -- default for 8.1
  ,file_pattern    IN varchar2       DEFAULT NULL);
 
PROCEDURE listGetControlfileCopy(
   rcvRec OUT NOCOPY rcvRec_t);
 
--
FUNCTION listGetControlfileCopy(
   bcfkey     OUT number
  ,ckpscn     OUT number
  ,ckptime    OUT date
  ,status     OUT varchar2
  ,completion OUT date
  ,fname      OUT varchar2)
RETURN number;
 
PROCEDURE listTranslateDataFileCopy(
   file#             IN number
  ,creation_change#  IN number
  ,tag               IN varchar2        DEFAULT NULL
  ,file_name_pattern IN varchar2        DEFAULT NULL
  ,completedAfter    IN date            DEFAULT NULL
  ,completedBefore   IN date            DEFAULT NULL
  ,statusMask        IN binary_integer  DEFAULT BSavailable+BSunavailable
--
  ,pluginSCN         IN number          DEFAULT 0);
 
PROCEDURE listGetDataFileCopy(
   rcvRec OUT NOCOPY rcvRec_t);
 
--
FUNCTION listGetDataFileCopy(
   cdf_key            OUT number
  ,status             OUT varchar2
  ,fname              OUT varchar2
  ,completion_time    OUT date
  ,checkpoint_change# OUT number
  ,checkpoint_time    OUT date)
RETURN number;
 
PROCEDURE listTranslateArchivedLogCopy(
   thread#           IN number
  ,sequence#         IN number
  ,first_change#     IN number
  ,file_name_pattern IN varchar2        DEFAULT NULL
  ,completedAfter    IN date            DEFAULT NULL
  ,completedBefore   IN date            DEFAULT NULL
  ,statusMask        IN binary_integer  DEFAULT
                       BSavailable+BSunavailable+BSexpired  -- 8.0/8.1 defaults
  ,needstby          IN number          DEFAULT NULL);
 
PROCEDURE listGetArchivedLogCopy(
   rcvRec       OUT NOCOPY rcvRec_t);
 
--
FUNCTION listGetArchivedLogCopy(
   al_key          OUT number
  ,status          OUT varchar2
  ,fname           OUT varchar2
  ,completion_time OUT date)
RETURN number;
 
--
--
--
 
PROCEDURE listTranslateControlfileBackup(
   tag             IN  varchar2
  ,completedAfter  IN  date
  ,completedBefore IN  date
  ,statusMask      IN  binary_integer   DEFAULT
                      BSavailable+BSunavailable+BSexpired   -- 8.0/8.1 defaults
  ,autobackup      IN  binary_integer    DEFAULT BScfile_all
  ,liststby        IN  binary_integer    DEFAULT NULL);
 
PROCEDURE listGetControlfileBackup(
   rcvRec OUT NOCOPY rcvRec_t);
 
--
FUNCTION listGetControlfileBackup(
   bskey      OUT number,
   ckpscn     OUT number,
   ckptime    OUT date)
RETURN number;
 
PROCEDURE listTranslateSpfileBackup(
   completedAfter  IN  date
  ,completedBefore IN  date);
 
PROCEDURE listGetSpfileBackup(
   rcvRec OUT NOCOPY rcvRec_t);
 
PROCEDURE listTranslateDataFileBackup(
   file#             IN number
  ,creation_change#  IN number
  ,tag               IN varchar2        DEFAULT NULL
  ,completedAfter    IN date            DEFAULT NULL
  ,completedBefore   IN date            DEFAULT NULL
  ,statusMask        IN binary_integer  DEFAULT
                      BSavailable+BSunavailable+BSexpired   -- 8.0/8.1 defaults
  ,pluginSCN         IN number          DEFAULT 0);
 
PROCEDURE listGetDataFileBackup(
   rcvRec OUT NOCOPY rcvRec_t);
 
--
FUNCTION listGetDataFileBackup(
   bs_key             OUT number
  ,backup_type        OUT varchar2
  ,incremental_level  OUT number
  ,completion_time    OUT date
  ,checkpoint_change# OUT number
  ,checkpoint_time    OUT date)
RETURN number;
 
--
PROCEDURE translateBackupFile(
   bs_recid    IN  number
  ,bs_stamp    IN  number
  ,fno         IN  number
  ,bskey       OUT number
  ,inclevel    OUT number
  ,backup_type OUT varchar2
  ,completed   OUT date);
 
--
PROCEDURE listTranslateArchivedLogBackup(
   thread#           IN number
  ,sequence#         IN number
  ,first_change#     IN number
  ,completedAfter    IN date           DEFAULT NULL
  ,completedBefore   IN date           DEFAULT NULL
  ,statusMask        IN binary_integer DEFAULT
                      BSavailable+BSunavailable+BSexpired); -- 8.0/8.1 defaults
 
PROCEDURE listGetArchivedLogBackup(
   rcvRec OUT NOCOPY rcvRec_t);
 
--
FUNCTION listGetArchivedLogBackup(
   bs_key          OUT number
  ,completion_time OUT date)
RETURN number;
 
--
PROCEDURE listTranslateArchivedLogBackup(
   thread#      IN number   DEFAULT NULL
  ,lowseq       IN number   DEFAULT NULL
  ,highseq      IN number   DEFAULT NULL
  ,lowscn       IN number   DEFAULT NULL
  ,highscn      IN number   DEFAULT NULL
  ,from_time    IN date     DEFAULT NULL
  ,until_time   IN date     DEFAULT NULL
  ,pattern      IN varchar2 DEFAULT NULL);
 
--
FUNCTION listGetArchivedLogBackup(
   bs_key          OUT number
  ,thread#         OUT number
  ,sequence#       OUT number
  ,first_change#   OUT number
  ,next_change#    OUT number
  ,first_time      OUT date
  ,next_time       OUT date)
RETURN number;
 
--
--
--
 
PROCEDURE listTranslateBackupsetFiles(
   bs_key          IN  number);
 
PROCEDURE listGetBackupsetFiles(
   rcvRec          OUT NOCOPY rcvRec_t);
 
--
--
--
 
--
PROCEDURE listTranslateProxyDataFile(
   file#             IN number
  ,creation_change#  IN number
  ,tag               IN varchar2        DEFAULT NULL
  ,handle_pattern    IN varchar2        DEFAULT NULL
  ,completedAfter    IN date            DEFAULT NULL
  ,completedBefore   IN date            DEFAULT NULL 
  ,statusMask        IN binary_integer  DEFAULT
                       BSavailable+BSunavailable+BSexpired
  ,liststby          IN binary_integer  DEFAULT NULL -- default for 8.1
  ,pluginSCN         IN number          DEFAULT 0);
 
PROCEDURE listGetProxyDataFile(
   rcvRec OUT NOCOPY rcvRec_t);
 
--
FUNCTION listGetProxyDataFile(
   xdf_key            OUT number
  ,recid              OUT number
  ,stamp              OUT number
  ,status             OUT varchar2
  ,handle             OUT varchar2
  ,completion_time    OUT date
  ,checkpoint_change# OUT number
  ,checkpoint_time    OUT date)
RETURN number;
 
--
--
--
--
--
--
--
--
PROCEDURE listTranslateProxyDFRecid(
   recid              IN number
  ,stamp              IN number
  ,xdf_key            OUT number
  ,file#              OUT number
  ,status             OUT varchar2
  ,handle             OUT varchar2
  ,completion_time    OUT date
  ,checkpoint_change# OUT number
  ,checkpoint_time    OUT date);
 
PROCEDURE listTranslateProxyArchivedLog(
   thread#           IN number
  ,sequence#         IN number
  ,first_change#     IN number
  ,tag               IN varchar2        DEFAULT NULL
  ,handle_pattern    IN varchar2        DEFAULT NULL
  ,completedAfter    IN date            DEFAULT NULL
  ,completedBefore   IN date            DEFAULT NULL
  ,statusMask        IN binary_integer  DEFAULT
                                        BSavailable+BSunavailable+BSexpired);
 
PROCEDURE listGetProxyArchivedLog(
   rcvRec OUT NOCOPY rcvRec_t);
 
--
--
--
 
PROCEDURE listTranslateDBIncarnation(
   db_name       IN varchar2 DEFAULT NULL,
   all_databases IN number  DEFAULT 0);
 
FUNCTION listGetDBIncarnation(
   db_key            OUT number
  ,dbinc_key         OUT number
  ,db_name           OUT varchar2
  ,db_id             OUT number
  ,current_inc       OUT varchar2
  ,resetlogs_change# OUT number
  ,resetlogs_time    OUT date
  ,dbinc_status      OUT varchar2)
RETURN number;
 
FUNCTION listGetDBIncarnation(
   db_key            OUT number
  ,dbinc_key         OUT number
  ,db_name           OUT varchar2
  ,db_id             OUT number
  ,current_inc       OUT varchar2
  ,resetlogs_change# OUT number
  ,resetlogs_time    OUT date)
RETURN number;
 
--
--
--
 
PROCEDURE listTranslateDBSite(
   db_name      IN varchar2 DEFAULT NULL,
   alldbs       IN binary_integer DEFAULT 1);
 
FUNCTION listGetDBSite(
   db_key            OUT number
  ,db_id             OUT number
  ,db_name           OUT varchar2
  ,db_role           OUT varchar2
  ,db_unique_name    OUT varchar2)
RETURN number;
 
--
--
--
 
PROCEDURE listRollbackSegTableSpace;
 
FUNCTION listGetTableSpace(
   ts#               OUT number
  ,ts_name           OUT varchar2)
RETURN number;
 
FUNCTION listGetTableSpace(
   ts#               OUT number
  ,ts_name           OUT varchar2
  ,pdbname           OUT varchar2)
RETURN number;
 
--
--
--
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
 
--
--
--
--
 
FUNCTION getIncrementalScn(
   file#        IN number
  ,create_scn   IN number
  ,reset_scn    IN number
  ,reset_time   IN date
  ,incr_level   IN number
  ,cumulative   IN number
  ,sourcemask   IN number   DEFAULT NULL 
  ,tag          IN varchar2 DEFAULT NULL
  ,pluginSCN    IN number   DEFAULT 0)
RETURN number;
 
--
--
--
--
--
--
--
--
--
--
--
 
PROCEDURE getIncrementalScn(
   first        IN  boolean                  -- open the cursor if this is TRUE
  ,file#        IN  number
  ,create_scn   IN  number
  ,reset_scn    IN  number
  ,reset_time   IN  date
  ,incr_level   IN  number
  ,cumulative   IN  number
  ,rcvRec       OUT NOCOPY rcvRec_t
  ,sourcemask   IN  number    DEFAULT NULL
  ,tag          IN  varchar2  DEFAULT NULL 
  ,pluginSCN    IN  number    DEFAULT 0
  ,keep         IN  boolean   DEFAULT NULL);
 
 
--
--
--
 
PROCEDURE findOfflineRangeCopy(
   offr_recid   IN number
  ,offr_ckpscn  IN number
  ,cf_cretime   IN date
  ,dbinc_key    IN number);
 
PROCEDURE getOfflineRangeCopy(
   rcvRec       OUT  NOCOPY rcvRec_t);
 
--
FUNCTION getOfflineRangeCopy
RETURN varchar2;
 
--
--
--
--
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
 
--
--
 
--
--
--
 
--
--
--
 
PROCEDURE setComputeRecoveryActionMasks(
   containerMask        IN number
  ,actionMask           IN number
  ,allRecords           IN number
  ,availableMask        IN binary_integer
  ,fullBackups          IN number DEFAULT NULL);
--
--
--
--
--
--
--
--
--
--
--
--
--
 
--
PROCEDURE setComputeRecoveryActionMasks(
   containerMask        IN number
  ,actionMask           IN number
  ,allRecords           IN number);
 
--
PROCEDURE setRAflags(
   kindMask    IN number
  ,allRecords  IN boolean);
 
FUNCTION computeRecoveryActions(
fno        IN number,   -- Datafile number.
crescn     IN number,   -- Datafile creation SCN.
df_rlgscn  IN number    -- Datafile resetlogs SCN.  Null if this is a RESTORE
   default null,        -- command, else this is the value in the datafile
--
df_rlgtime IN date      -- Datafile resetlogs time.  Null if df_rlgscn is
   default null,        -- null, else value from datafile header.
df_ckpscn  IN number    -- Datafile checkpoint SCN.  Null if df_rlgscn is
   default null,        -- null, else value from datafile header.
offlscn    IN number    -- kccfeofs (may be null).
   default 0,
onlscn     IN number    -- kccfeonc (null if offlscn is null).
   default 0,
onltime    IN date      -- kccfeonc_time
   default null,
cleanscn   IN number    -- kccfecps if either SOR or WCC set, else null.
   default 0,
clean2scn  IN number    -- CF ckpt SCN if WCC set, infinity if SOR bit set
   default 0,           -- else null.
clean2time IN date      -- cf ckpt time if WCC, SYSDATE if SOR
   default null,
allowfuzzy IN boolean   -- TRUE if can be fuzzy at until SCN/time, FALSE if
  default FALSE,        -- not.  default is FALSE.
partial_rcv IN boolean  -- TRUE if can do partial recovery, FALSE if not
  default FALSE,
cf_scn     IN number    -- controlfile checkpoint SCN (NULL if none mounted)
  default NULL,
cf_cretime IN date      -- controlfile creation time (NULL if none mounted)
  default NULL,
cf_offrrid IN number    -- recid of oldest offline range in controlfile
  default NULL,         -- (NULL if none mounted)
allCopies  IN boolean   -- if TRUE, then stack all valid copies of a bu set
  default FALSE,
df_cretime IN date      -- datafile creation time
  default NULL,
rmanCmd    IN binary_integer
  default unknownCmd_t,
foreignDbid   IN number
  default 0,
pluggedRonly  IN binary_integer
  default 0,
pluginSCN     IN number
  default 0,
pluginRlgSCN  IN number
  default 0,
pluginRlgTime IN date 
  default NULL,
creation_thread IN number
  default NULL,
creation_size   IN number
  default NULL,
pdbId           IN number
  default 1,
pdbForeignDbid  IN number
  default 0
) return binary_integer;
 
--
--
--
 
--
 
SUCCESS     CONSTANT binary_integer := 0;
UNAVAILABLE CONSTANT binary_integer := 1;
AVAILABLE   CONSTANT binary_integer := 2;
RESTORABLE  CONSTANT binary_integer := 3;
NO_ACTION   CONSTANT binary_integer := 4;
 
--
--
--
--
--
--
--
--
--
--
--
--
--
 
FUNCTION getRecoveryAction(
   action OUT NOCOPY rcvRec_t)
RETURN binary_integer;
 
--
FUNCTION getRecoveryAction(
   kind       OUT number
  ,set_stamp  OUT number
  ,set_count  OUT number
  ,recid      OUT number
  ,stamp      OUT number
  ,fname      OUT varchar2
  ,blocksize  OUT number
  ,blocks     OUT number
  ,devtype    OUT varchar2
  ,from_scn   OUT number
  ,to_scn     OUT number
  ,to_time    OUT date
  ,rlgscn     OUT number
  ,rlgtime    OUT date
  ,cfcretime  OUT date
  ,dbinc_key  OUT number)
RETURN binary_integer;
 
PROCEDURE printRecoveryActions;
 
PROCEDURE trimRecoveryActions(
   maxActions           IN number
  ,containerMask        IN number
  ,actionMask           IN number);
 
--
--
--
--
--
--
--
--
--
--
--
 
--
--
--
 
PROCEDURE reportTranslateDFDel ;
 
--
FUNCTION reportGetDFDel(
   file#               OUT number
  ,filetype            OUT number
  ,checkpoint_change#  OUT number
  ,checkpoint_time     OUT date
  ,resetlogs_change#   OUT number
  ,resetlogs_time      OUT date
  ,incremental_change# OUT number
  ,fuzzy_change#       OUT number
  ,recid               OUT number
  ,stamp               OUT number
  ,fname               OUT varchar2
  ,restorable          OUT number)
RETURN number;
 
--
FUNCTION reportGetDFDel(
   file#               OUT number
  ,filetype            OUT number
  ,checkpoint_change#  OUT number
  ,checkpoint_time     OUT date
  ,resetlogs_change#   OUT number
  ,resetlogs_time      OUT date
  ,incremental_change# OUT number
  ,fuzzy_change#       OUT number
  ,recid               OUT number
  ,stamp               OUT number
  ,fname               OUT varchar2
  ,restorable          OUT number
  ,key                 OUT number
  ,completion_time     OUT date)
RETURN number;
 
--
--
--
 
FUNCTION getCloneName(
   fno    IN number
  ,crescn IN number
  ,pluscn IN number DEFAULT 0)
RETURN varchar2;
 
 
--
--
--
 
FUNCTION wasFileOffline(
   fno    IN number
  ,untilscn IN number)
RETURN number;
 
--
--
--
 
procedure getConfig(
   conf#          OUT    number
  ,name           IN OUT varchar2
  ,value          IN OUT varchar2
  ,first          IN     boolean);
 
--
--
--
 
FUNCTION getmaxcopyno(
   bsstamp         IN    number
  ,bscount         IN    number)
RETURN number;
 
--
--
--
 
PROCEDURE bmrAddCorruptTable(
   dfnumber    OUT number
  ,blknumber   OUT number
  ,range       OUT number
  ,first       IN  boolean);
 
--
--
--
 
PROCEDURE getDfBackupHistory(
   backedUpDev     IN   varchar2
  ,first           IN   boolean
  ,bhistoryRec     OUT  NOCOPY bhistoryRec_t
  ,recentbackup    IN   boolean DEFAULT FALSE  -- get no: recent backups
  ,doingCmd        IN   varchar2 DEFAULT NULL
  ,keepTag         IN   varchar2 DEFAULT NULL
  ,toDest1         IN   varchar2 DEFAULT NULL
  ,toDest2         IN   varchar2 DEFAULT NULL
  ,toDest3         IN   varchar2 DEFAULT NULL
  ,toDest4         IN   varchar2 DEFAULT NULL);
 
PROCEDURE getAlBackupHistory(
   backedUpDev     IN   varchar2
  ,first           IN   boolean
  ,bhistoryRec     OUT  NOCOPY bhistoryRec_t
  ,doingCmd        IN   varchar2 DEFAULT NULL
  ,keepTag         IN   varchar2 DEFAULT NULL
  ,toDest1         IN   varchar2 DEFAULT NULL
  ,toDest2         IN   varchar2 DEFAULT NULL
  ,toDest3         IN   varchar2 DEFAULT NULL
  ,toDest4         IN   varchar2 DEFAULT NULL);
 
PROCEDURE getBsBackupHistory(
   backedUpDev     IN   varchar2
  ,first           IN   boolean
  ,set_stamp       IN   number DEFAULT NULL
  ,set_count       IN   number DEFAULT NULL
  ,bhistoryRec     OUT  NOCOPY bhistoryRec_t
  ,doingCmd        IN   varchar2 DEFAULT NULL
  ,keepTag         IN   varchar2 DEFAULT NULL
  ,toDest1         IN   varchar2 DEFAULT NULL
  ,toDest2         IN   varchar2 DEFAULT NULL
  ,toDest3         IN   varchar2 DEFAULT NULL
  ,toDest4         IN   varchar2 DEFAULT NULL);
 
PROCEDURE getDcBackupHistory(
   backedUpDev     IN   varchar2
  ,first           IN   boolean
  ,bhistoryRec     OUT  NOCOPY bhistoryRec_t
  ,doingCmd        IN   varchar2 DEFAULT NULL
  ,keepTag         IN   varchar2 DEFAULT NULL
  ,toDest1         IN   varchar2 DEFAULT NULL
  ,toDest2         IN   varchar2 DEFAULT NULL
  ,toDest3         IN   varchar2 DEFAULT NULL
  ,toDest4         IN   varchar2 DEFAULT NULL
  ,atAnyScn        IN   boolean  DEFAULT FALSE);
 
--
PROCEDURE getBackupHistory(
   dfRec            IN  dfRec_t
  ,backedUpDev      IN  varchar2
  ,nbackupsFlag     IN  number
  ,bscompletionFlag IN  number
  ,nbackups         OUT number
  ,bscompletion     OUT date);
 
--
PROCEDURE getBackupHistory(
   alRec            IN  alRec_t
  ,backedUpDev      IN  varchar2
  ,nbackupsFlag     IN  number
  ,bscompletionFlag IN  number
  ,nbackups         OUT number
  ,bscompletion     OUT date);
 
PROCEDURE getBackupHistory(
   bpRec            IN  bpRec_t
  ,backedUpDev      IN  varchar2
  ,nbackupsFlag     IN  number
  ,bscompletionFlag IN  number
  ,nbackups         OUT number
  ,bscompletion     OUT date
  ,toDest1          IN  varchar2 DEFAULT NULL
  ,toDest2          IN  varchar2 DEFAULT NULL
  ,toDest3          IN  varchar2 DEFAULT NULL
  ,toDest4          IN  varchar2 DEFAULT NULL);
 
--
--
--
 
FUNCTION getPackageVersion
RETURN varchar2;
 
--
--
--
FUNCTION isStatusMatch(status      IN VARCHAR2,
                       mask        IN NUMBER) RETURN NUMBER;
FUNCTION isDeviceTypeAllocated(deviceType IN varchar2)
                      RETURN NUMBER;
FUNCTION isBackupTypeMatch(btype       IN VARCHAR2,
                           mask        IN binary_integer)
                                              RETURN NUMBER;
--
--
--
PROCEDURE setRcvRecBackupAge(age IN number);
 
--
--
--
PROCEDURE resetthisBackupAge;
 
--
--
--
 
PROCEDURE getRetentionPolicy(recovery_window OUT number
                            ,redundancy      OUT number);
--
--
--
--
 
FUNCTION listBackup(lbRecOut         OUT     NOCOPY lbRec_t
                   ,firstCall        IN      boolean
                   ,only_obsolete    IN      boolean
                   ,redundancy       IN      number
                   ,piped_call       IN      boolean
                   ,lbCursor         IN  OUT NOCOPY lbCursor_t
                   ,lbState          IN  OUT NOCOPY lbState_t
                   ,extRlKeepSCN     IN      number DEFAULT NULL)
  RETURN boolean;
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
 
 
--
 
FUNCTION getRestoreRangeSet(restoreRangeTab OUT restoreRangeTab_t
                           ,opCode  IN  varchar2
                           ,db_id   IN  number)
    
  RETURN boolean;
 
--
 
PROCEDURE setNeedObsoleteData(NeedObsoleteData IN boolean DEFAULT TRUE);
--
--
 
--
 
--
--
PROCEDURE getCopyofDatafile(
   first          IN      boolean     -- TRUE if this is the first time called
  ,itag           IN      varchar2    -- tag that the copy should have or NULL
  ,fno            OUT     number      -- datafile number
  ,crescn         OUT     number      -- creation scn of the datafile
  ,rlogscn        OUT     number      -- resetlogs scn of the datafile
  ,rlgtime        OUT     date        -- resetlogs time of the datafile
  ,recid          OUT     binary_integer -- recid of the latest datafilecopy
  ,stamp          OUT     binary_integer -- stamp of the latest datafilecopy
  ,name           OUT     varchar2    -- name of the datafilecopy
  ,otag           OUT     varchar2    -- tag of the datafilecopy
  ,status         OUT     varchar2    -- status of the datafilecopy
  ,nblocks        OUT     number      -- number of blocks of datafilecopy
  ,bsz            OUT     binary_integer -- blocksize of the datafilecopy
  ,ctime          OUT     date        -- creation time of the datafilecopy
  ,toscn          OUT     number      -- checkpoint scn of the datafilecopy
  ,totime         OUT     date        -- checkpoint time of the datafilecopy
  ,pluggedRonly   OUT     binary_integer -- 1 for read-only. Otherwise, 0
  ,pluginSCN      OUT     number      -- plugin scn
  ,pluginRlgSCN   OUT     number      -- resetlogs when datafile was plugged
  ,pluginRlgTime  OUT     date);      -- resetlog time when df was plugged
 
--
--
--
--
 
PROCEDURE getCopyofDatafile(
   dfnumber       IN      number      -- datafile number
  ,itag           IN      varchar2    -- tag that the copy should have or NULL
  ,crescn         IN  OUT number      -- creation scn of the datafile
  ,rlogscn        IN  OUT number      -- resetlogs scn of the datafile
  ,rlgtime        IN  OUT date        -- resetlogs time of the datafile
  ,recid          OUT     binary_integer -- recid of the latest datafilecopy
  ,stamp          OUT     binary_integer -- stamp of the latest datafilecopy
  ,name           OUT     varchar2    -- name of the datafilecopy
  ,otag           OUT     varchar2    -- tag of the datafilecopy
  ,status         OUT     varchar2    -- status of the datafilecopy
  ,nblocks        OUT     binary_integer -- number of blocks of datafilecopy
  ,bsz            OUT     binary_integer -- blocksize of the datafilecopy
  ,ctime          OUT     date        -- creation time of the datafilecopy
  ,toscn          OUT     number      -- checkpoint scn of the datafilecopy
  ,totime         OUT     date        -- checkpoint time of the datafilecopy
  ,pluggedRonly   OUT     binary_integer -- 1 for read-only. Otherwise, 0
  ,pluginSCN      IN      number);    -- plugin scn
 
--
--
--
--
 
PROCEDURE getCopyofDatafile(
   dfnumber    IN  number          -- datafile number
  ,itag        IN  varchar2        -- tag that the copy should have or NULL
  ,crescn      IN  number          -- creation scn of the datafile
  ,rlogscn     IN  number          -- resetlogs scn of the datafile
  ,rlgtime     IN  date            -- resetlogs time of the datafile
  ,recid       OUT binary_integer  -- recid of the latest datafilecopy
  ,stamp       OUT binary_integer  -- stamp of the latest datafilecopy
  ,name        OUT varchar2        -- name of the datafilecopy
  ,otag        OUT varchar2        -- tag of the datafilecopy
  ,status      OUT varchar2        -- status of the datafilecopy
  ,nblocks     OUT binary_integer  -- number of blocks of the datafilecopy
  ,bsz         OUT binary_integer  -- blocksize of the datafilecopy
  ,ctime       OUT date            -- creation time of the datafilecopy
  ,toscn       OUT number          -- checkpoint scn of the datafilecopy
  ,totime      OUT date);          -- checkpoint time of the datafilecopy
 
--
--
--
PROCEDURE getdropOSFiles(
   first         IN  boolean
  ,agedFileRec   OUT NOCOPY agedFileRec_t);
 
PROCEDURE getBackedUpFiles(
   first         IN  boolean
  ,agedFileRec   OUT NOCOPY agedFileRec_t);
 
--
--
PROCEDURE getRedoLogDeletionPolicy(
   policy        OUT varchar2);
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE setRedoLogDeletionPolicy(
   policy  IN  varchar2
  ,alldest IN  number);
 
--
--
--
--
--
FUNCTION validateStandbyConfig(
   policy  IN  varchar2
  ,alldest IN  number)
RETURN NUMBER;
 
--
--
--
--
--
--
--
--
--
--
PROCEDURE getSCNForAppliedPolicy(
   minscn    OUT  number
  ,rlgscn    OUT  number);
 
--
--
--
--
--
--
--
--
PROCEDURE getAppliedAl(
   first         IN  boolean
  ,agedFileRec   OUT NOCOPY agedFileRec_t);
 
--
--
--
--
--
PROCEDURE getRequiredSCN(
   reqscn   OUT  number
  ,rlgscn   OUT  number
  ,streams  IN   number DEFAULT 0
  ,alldest  IN   number DEFAULT 0);
 
--
--
PROCEDURE getAppliedSCN(
   appscn   OUT  number
  ,rlgscn   OUT  number
  ,alldest  IN   number);
 
--
--
FUNCTION isTranslatedFno(fno IN number) RETURN NUMBER;
 
--
--
FUNCTION isBsRecCacheMatch(
   key         IN   number
  ,deviceType  IN   varchar2
  ,tag         IN   varchar2
  ,status      IN   varchar2)
RETURN NUMBER;
 
--
PROCEDURE resetReclRecid;
 
--
PROCEDURE setReclRecid(
   rectype  IN  binary_integer
  ,recid    IN  number);
 
--
--
FUNCTION IsReclRecid(
   rectype  IN  binary_integer
  ,recid    IN  number)
RETURN NUMBER;
 
--
--
FUNCTION getSpaceRecl(ceilAsm IN binary_integer default 0) RETURN NUMBER;
 
--
PROCEDURE getRestorePoint(
   name         IN varchar2
  ,rlgscn       OUT number
  ,rlgtime      OUT date
  ,scn          OUT number
  ,guaranteed   OUT number);
 
--
PROCEDURE getRestorePoint(
   name         IN varchar2
  ,rlgscn       OUT number
  ,rlgtime      OUT date
  ,scn          OUT number
  ,guaranteed   OUT number
  ,con_id       IN number
  ,clean        OUT number
  ,out_con_id   OUT number);
 
--
PROCEDURE listTranslateRestorePoint(
  name          IN  varchar2);
 
--
PROCEDURE listGetRestorePoint(
   name         OUT varchar2
  ,scn          OUT number
  ,rsptime      OUT date
  ,cretime      OUT date
  ,rsptype      OUT varchar2);
 
PROCEDURE listGetRestorePoint(
   name         OUT varchar2
  ,scn          OUT number
  ,rsptime      OUT date
  ,cretime      OUT date
  ,rsptype      OUT varchar2
  ,pdbname      OUT varchar2);
 
--
--
--
FUNCTION Num2DisplaySize(input_size IN NUMBER) return VARCHAR2;
 
--
FUNCTION Sec2DisplayTime(input_secs IN NUMBER) return VARCHAR2;
 
FUNCTION getEncryptTSCount RETURN BINARY_INTEGER;
 
--
--
--
--
PROCEDURE setArchivedLogRecord(
   thread#   IN  number
  ,sequence# IN  number
  ,first     IN  boolean);
 
--
--
--
PROCEDURE setCanHandleTransportableTbs(
   flag IN boolean);
 
--
--
FUNCTION getArchivedNextSCN RETURN NUMBER;
 
--
--
FUNCTION isArchivedLogMissing(fromSCN IN NUMBER, untilSCN IN NUMBER)
  RETURN NUMBER;
 
--
--
FUNCTION getNextAvailableSCN(fromScn           IN  NUMBER, 
                             nextAvailableSCN  OUT  NUMBER,
                             isOrs             IN   NUMBER)
  RETURN BOOLEAN;
 
--
FUNCTION findLogBreakPoint(logBreakPointScn        OUT NUMBER,
                           logBreakPointTime       OUT DATE,
                           logBreakPointDbIncKey   OUT NUMBER,
                           logBreakPointRlgScn     OUT NUMBER,
                           logBreakPointRlgTime    OUT DATE,
                           fromSCN                 IN  NUMBER,
                           untilSCN                IN  NUMBER,
                           isOrs                   IN  NUMBER)
  RETURN boolean;
 
--
--
FUNCTION getMaxRedoSCN(maxScn      OUT NUMBER,
                       maxTime     OUT DATE,
                       maxDbIncKey OUT NUMBER,
                       maxRlgScn   OUT NUMBER,
                       maxRlgTime  OUT DATE,
                       isOrs       IN  NUMBER)
   RETURN boolean;
 
--
PROCEDURE setRestoreRangeDevTyp(typ IN VARCHAR2);
 
--
PROCEDURE resetRestoreRangeDevTyp;
 
PROCEDURE setSkipOfflineRangeAboveSCN(maxCheckpointSCN IN NUMBER);
 
--
--
--
 
--
--
FUNCTION getDropSCN(dfNum        IN NUMBER,
                    creScn       IN  NUMBER,
                    creTime      IN  DATE,
                    plugScn      IN  NUMBER,
                    foreignDbId  IN  NUMBER,
                    dropScn      OUT NUMBER,
                    dropTime     OUT DATE,
                    dropDbIncKey OUT NUMBER,
                    dropRlgScn   OUT NUMBER,
                    dropRlgTime  OUT DATE)
RETURN boolean;
 
--
--
--
FUNCTION getIncarnationKey(untilSCN IN NUMBER) RETURN NUMBER;
 
--
--
PROCEDURE setDbidTransClause(dbid IN number);
 
--
--
FUNCTION isTranslatedDbid(dbid IN number) RETURN NUMBER;
 
--
--
FUNCTION getMaxScn RETURN number;
 
FUNCTION getMaxScn(logmaxnt OUT date) RETURN NUMBER;
 
FUNCTION getActualDbinc RETURN number;
--
--
--
--
--
--
 
PROCEDURE setStdbyCtrlScn(ctrlSCN IN NUMBER);
--
--
 
FUNCTION translatePdbName(pdbName IN VARCHAR2)
RETURN NUMBER;
 
--
 
FUNCTION translatePdbName(pdbName IN VARCHAR2,
                          pdbGuid OUT VARCHAR2) 
RETURN NUMBER;
--
 
PROCEDURE resetPdbIdList;
--
 
PROCEDURE setPdbId(pdbId IN NUMBER, first IN BOOLEAN);
--
--
 
FUNCTION isTranslatedPdbId(pdbId IN NUMBER) RETURN NUMBER;
--
--
 
FUNCTION isPdbScnOrphan(untilSCN IN NUMBER, pdbId IN NUMBER) RETURN NUMBER;
--
--
 
FUNCTION setLocalOrsSiteKey(db_id IN NUMBER) RETURN boolean;
--
 
PROCEDURE resetLocalOrsSiteKey;
--
 
FUNCTION isNoBackupPdb(pdbname IN VARCHAR2) RETURN NUMBER;
--
 
--
--
--
 
PROCEDURE listApplicationPdbs(root_con_id IN  number);
--
 
FUNCTION listGetAppPdb(pdb_name OUT varchar2) RETURN NUMBER;
--
 
FUNCTION pdbHasDatafile(pdbId IN NUMBER) RETURN NUMBER;
--
 
--
 
pragma TIMESTAMP('2000-03-12:13:51:00');
 
END; -- dbms_rcvman or x$dbms_rcvman
 
>>>
 
define dbmsrvpc_sql
<<<
CREATE OR REPLACE PACKAGE dbms_rcvvpc
IS
 
  FUNCTION filter_pass_all (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2;
 
  FUNCTION f_vpc_databases (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2;
 
  FUNCTION f_db (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2;
 
  FUNCTION f_dbinc (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2;
 
  FUNCTION f_bp (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2;
 
  FUNCTION f_bsf (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2;
 
  FUNCTION f_bs (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2;
 
  FUNCTION f_conf (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2;
 
  FUNCTION f_deleted_object (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2;
 
  FUNCTION f_do_seq (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2;
 
  FUNCTION f_node (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2;
 
  FUNCTION f_pdb (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2;
 
  FUNCTION f_rout (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2;
 
  FUNCTION f_watermarks (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2;
 
  FUNCTION f_sbt_template_db (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2;
 
  FUNCTION f_pdbinc (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2;
 
  FUNCTION f_pdb_dbinc (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2;
 
  FUNCTION f_al (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2;
 
  FUNCTION f_bcf (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2;
 
  FUNCTION f_bdf (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2;
 
  FUNCTION f_brl (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2;
 
  FUNCTION f_ccf (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2;
 
  FUNCTION f_cdf (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2;
 
  FUNCTION f_ckp (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2;
 
  FUNCTION f_df (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2;
 
  FUNCTION f_fb (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2;
 
  FUNCTION f_grsp (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2;
 
  FUNCTION f_nrsp (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2;
 
  FUNCTION f_offr (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2;
 
  FUNCTION f_orl (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2;
 
  FUNCTION f_rlh (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2;
 
  FUNCTION f_rr (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2;
 
  FUNCTION f_rsr (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2;
 
  FUNCTION f_rt (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2;
 
  FUNCTION f_tf (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2;
 
  FUNCTION f_tsatt (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2;
 
  FUNCTION f_ts (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2;
 
  FUNCTION f_xal (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2;
 
  FUNCTION f_xcf (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2;
 
  FUNCTION f_xdf (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2;
 
  FUNCTION f_scr (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2;
 
  FUNCTION f_rrcache (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2;
 
  FUNCTION f_bcb (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2;
 
  FUNCTION f_ccb (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2;
 
  FUNCTION f_scrl (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2;
 
  FUNCTION f_cfs (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2;
 
  FUNCTION f_config (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2;
 
  FUNCTION f_orsevent (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2;
 
  FUNCTION f_rcfile (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2;
 
  FUNCTION f_xmlstore (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2;
 
  FUNCTION f_bcr (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2;
 
  FUNCTION f_server (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2;
 
  FUNCTION f_vpc_users (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2;
 
  FUNCTION f_site_dfatt (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2;
 
  FUNCTION f_site_tfatt (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2;
 
END dbms_rcvvpc;
>>>
 
define dbmsunsetvpc_sql
<<<
DECLARE
  e_policy_notexists               EXCEPTION;
  PRAGMA                           EXCEPTION_INIT(e_policy_notexists, -28102);
  e_insufficient_privs             EXCEPTION;
  PRAGMA                           EXCEPTION_INIT(e_insufficient_privs, -6550);
BEGIN
  FOR i IN (
    SELECT object_name
         , policy_name
      FROM user_policies
  )
  LOOP
    BEGIN
      EXECUTE IMMEDIATE '
      BEGIN
        dbms_rls.drop_policy (
          object_name => :1
        , policy_name => :2
        );
      END;' USING i.object_name
                , i.policy_name;
    EXCEPTION
      WHEN e_policy_notexists
      THEN NULL;
      WHEN e_insufficient_privs
      THEN
        RAISE_APPLICATION_ERROR (
          -20153
        ,  ' Unable to drop the VPD protection policies!'
        || CHR(10) || CHR(13)
        || 'This recovery catalog does not have VPD support enabled!'
        || ' Exit this RMAN session.'
        || CHR(10) || CHR(13)
        || 'Execute ''?/rdbms/admin/dbmsrmanvpc.sql -vpd '
        || USER || '''' || ' after connecting'
        || CHR(10) || CHR(13)
        || 'to a catalog database as SYS. Then perform the UPGRADE catalog.'
        );
    END;
  END LOOP;
END;
>>>
 
define dbmsrman2_sql
<<<
--
 
--
--
--
 
--
--
--
--
--
--
--
--
--
--
--
--
FUNCTION isInFailureList(
   parentId     IN number
  ,failureId    IN number
  ,for_exclude  IN binary_integer
  )
RETURN NUMBER;
 
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE createFailureList(
   first_call   IN boolean
  ,failureId    IN number
  ,for_exclude  IN boolean);
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE translateFailure(
   critical        IN  binary_integer
  ,high            IN  binary_integer
  ,low             IN  binary_integer
  ,unknown         IN  binary_integer default 0
  ,closed          IN  binary_integer
  ,adviseId        IN  number);
 
--
--
--
--
--
--
--
--
--
PROCEDURE getFailure(
   failureRec      OUT NOCOPY failureRec_t);
 
--
--
--
--
--
--
--
--
PROCEDURE translateRepair(
   adviseid        IN  number);
 
--
--
--
--
--
--
--
--
--
PROCEDURE getRepair(
   repairRec OUT NOCOPY repairRec_t);
 
--
--
--
--
--
--
--
--
PROCEDURE translateRepairParms(
   adviseid        IN  number);
 
--
--
--
--
--
--
--
--
--
--
PROCEDURE getRepairParms(
   repairParmsRec OUT NOCOPY repairParmsRec_t);
 
--
--
--
--
--
--
--
--
PROCEDURE translateRepairOption(
   adviseid        IN  number);
 
--
--
--
--
--
--
--
--
--
--
PROCEDURE getRepairOption(
   repairOptionRec OUT NOCOPY repairOptionRec_t);
 
--
--
--
--
--
--
--
--
PROCEDURE translateRepairStep(
   optionidx       IN  number); 
 
--
--
--
--
--
--
--
--
--
--
PROCEDURE getRepairStep(
   repairStepRec   OUT NOCOPY repairStepRec_t);
 
--
--
--
--
--
--
--
--
PROCEDURE translateManualRepair(
   adviseId        IN  number);
 
--
--
--
--
--
--
--
--
--
--
FUNCTION getManualRepair(
   mandatory OUT varchar2)
RETURN varchar2;
 
--
--
--
--
--
--
--
--
--
--
FUNCTION getRepairScriptName(
   repairId       IN  number,
   description    OUT varchar2)
RETURN varchar2;
 
pragma TIMESTAMP('2000-03-12:13:51:00');
 
END; -- dbms_rcvman or x$dbms_rcvman
 
--
>>>
 
define dbmsrman3_sql
<<<
 
--
 
@@?/rdbms/admin/dbmsrmansys.sql
 
drop public synonym v$backup_files;
drop view v_$backup_files;
drop function v_listBackupPipe;
drop type v_lbRecSetImpl_t;
drop type v_lbRecSet_t;
drop type v_lbRec_t;
--
--
--
--
create type v_lbRec_t as object
   (
      list_order1               NUMBER,
      list_order2               NUMBER,
      pkey                      NUMBER,
      backup_type               VARCHAR2(32),
      file_type                 VARCHAR2(32),
      keep                      VARCHAR2(3),
      keep_until                DATE,
      keep_options              VARCHAR2(13),
      status                    VARCHAR2(16),
      fname                     VARCHAR2(1024),
      tag                       VARCHAR2(32),
      media                     VARCHAR2(80),
      recid                     NUMBER,
      stamp                     NUMBER,
      device_type               VARCHAR2(255),
      block_size                NUMBER,
      completion_time           DATE,
      is_rdf                    VARCHAR2(3),
      compressed                VARCHAR2(3),
      obsolete                  VARCHAR2(3),
      bytes                     NUMBER,
 
      bs_key                    NUMBER,
      bs_count                  NUMBER,
      bs_stamp                  NUMBER,
      bs_type                   VARCHAR2(32),
      bs_incr_type              VARCHAR2(32),
      bs_pieces                 NUMBER,
      bs_copies                 NUMBER,
      bs_completion_time        DATE,
      bs_status                 VARCHAR2(16),
      bs_bytes                  NUMBER,
      bs_compressed             VARCHAR2(3),
      bs_tag                    VARCHAR2(1024),
      bs_device_type            VARCHAR2(255),
 
      bp_piece#                 NUMBER,
      bp_copy#                  NUMBER,
 
      df_file#                  NUMBER,
      df_ts#                    NUMBER,
      df_plugin_change#         NUMBER,
      df_foreign_dbid           NUMBER,
      df_tablespace             VARCHAR2(30),
      df_resetlogs_change#      NUMBER,
      df_creation_change#       NUMBER,
      df_checkpoint_change#     NUMBER,
      df_ckp_mod_time           DATE,
      df_incremental_change#    NUMBER,
 
      rl_thread#                NUMBER,
      rl_sequence#              NUMBER,
      rl_resetlogs_change#      NUMBER,
      rl_first_change#          NUMBER,
      rl_first_time             DATE,
      rl_next_change#           NUMBER,
      rl_next_time              DATE,
 
      con_id                    NUMBER
   );
/
create type v_lbRecSet_t as table of v_lbRec_t;
/
create type v_lbRecSetImpl_t as object 
(
   curval                number,  -- current rownum
   done                  number,  -- done with the query
   needobsolete          number,  -- user requested obsolete column
 
   static function ODCITablePrepare(sctx OUT    v_lbRecSetImpl_t, 
                                   ti    IN     SYS.ODCITabFuncInfo) 
      return number,
 
   static function ODCITableStart(sctx   IN OUT v_lbRecSetImpl_t)
      return number,
 
   member function ODCITableFetch(self   IN OUT v_lbRecSetImpl_t, 
                                  nrows  IN     number, 
                                  objSet OUT    v_lbRecSet_t) 
      return number,
 
   member function ODCITableClose(self   IN     v_lbRecSetImpl_t) 
      return number
);
/
create or replace type body v_lbRecSetImpl_t is
 
  static function ODCITablePrepare(sctx OUT v_lbRecSetImpl_t, 
                                   ti   IN  SYS.ODCITabFuncInfo) 
    return number is
  begin
--
    sctx:=v_lbRecSetImpl_t(0, 0, 0);
 
--
--
    for i in ti.Attrs.first .. ti.Attrs.last
    loop
      if (ti.Attrs(i) = 20) then
         sctx.needobsolete := 1;
         exit;
      end if;
    end loop;
 
    return SYS.ODCIConst.Success;
  end ODCITablePrepare;
 
  static function ODCITableStart(sctx IN OUT v_lbRecSetImpl_t) 
    return number is
  begin
    return SYS.ODCIConst.Success;
  end ODCITableStart;
 
--
--
--
--
  member function ODCITableFetch(self   IN OUT v_lbRecSetImpl_t, 
                                 nrows  IN     number, 
                                 objSet OUT    v_lbRecSet_t) 
    return number is
    n               number  := 0;
    firstCall       boolean := TRUE;
    ret             boolean := TRUE;
    redundancy      number;
    recovery_window number;
    untilTime       date;
    lbRec           sys.dbms_rcvman.lbrec_t;
    lbCursor        sys.dbms_rcvman.lbCursor_t;
    lbState         sys.dbms_rcvman.lbState_t;
  begin
    objSet:=v_lbRecSet_t();
 
--
    sys.dbms_rcvman.resetAll;
--
    sys.dbms_rcvman.setDatabase(NULL, NULL, NULL, NULL);
 
    redundancy := 1;
    recovery_window := 0;
 
--
--
--
    sys.dbms_rcvman.getRetentionPolicy(recovery_window, redundancy);
 
--
    sys.dbms_rcvman.setAllIncarnations(TRUE);
 
--
    if (recovery_window > 0)
    then
      select (sysdate-recovery_window) into untilTime from dual;
      sys.dbms_rcvman.setUntilTime(untilTime);
    end if;
 
    sys.dbms_rcvman.setDeviceTypeAny;
 
    if (recovery_window = 0 and redundancy = 0) then
--
       sys.dbms_rcvman.setNeedObsoleteData(false);
    else
       if self.needobsolete = 1 then
          sys.dbms_rcvman.setNeedObsoleteData(true);
       else
          sys.dbms_rcvman.setNeedObsoleteData(false);
       end if;
    end if;
 
    while ret and self.done = 0 loop
      ret := sys.dbms_rcvman.listBackup(lbRec, firstCall, FALSE, 
                                        redundancy,
                                        TRUE, lbCursor, lbState, null);
      if (lbRec.pkey is not null)
      then
        objSet.extend;
        n := n + 1;
        objSet(n):= v_lbRec_t(
                            to_number(null),   -- list_order1
                            to_number(null),   -- list_order2
                            to_number(null),   -- pkey
                            to_char(null),     -- backup_type
                            to_char(null),     -- file_type
                            to_char(null),     -- keep
                            to_date(null),     -- keep_until
                            to_char(null),     -- keep_options
                            to_char(null),     -- status
                            to_char(null),     -- fname
                            to_char(null),     -- tag
                            to_char(null),     -- media
                            to_number(null),   -- recid
                            to_number(null),   -- stamp
                            to_char(null),     -- device_type
                            to_number(null),   -- block_size
                            to_date(null),     -- completion_time
                            to_char(null),     -- is_rdf
                            to_char(null),     -- compressed
                            to_char(null),     -- obsolete
                            to_number(null),   -- bytes
                            to_number(null),   -- bs_key
                            to_number(null),   -- bs_count
                            to_number(null),   -- bs_stamp
                            to_char(null),     -- bs_type
                            to_char(null),     -- bs_incr_type
                            to_number(null),   -- bs_pieces
                            to_number(null),   -- bs_copies
                            to_date(null),     -- bs_completion_time
                            to_char(null),     -- bs_status
                            to_number(null),   -- bs_bytes
                            to_char(null),     -- bs_compressed
                            to_char(null),     -- bs_tag
                            to_char(null),     -- bs_device_type
                            to_number(null),   -- bp_piece#
                            to_number(null),   -- bp_copy#
                            to_number(null),   -- df_file#
                            to_number(null),   -- df_ts#
                            to_number(null),   -- df_plugin_change#
                            to_number(null),   -- df_foreign_dbid
                            to_char(null),     -- df_tablespace
                            to_number(null),   -- df_resetlogs_change#
                            to_number(null),   -- df_creation_change#
                            to_number(null),   -- df_checkpoint_change#
                            to_date(null),     -- df_ckp_mod_time
                            to_number(null),   -- df_incremental_change#
                            to_number(null),   -- rl_thread#
                            to_number(null),   -- rl_sequence#
                            to_number(null),   -- rl_resetlogs_change#
                            to_number(null),   -- rl_first_change#
                            to_date(null),     -- rl_first_time
                            to_number(null),   -- rl_next_change#
                            to_date(null),     -- rl_next_time
                            to_number(null));  -- con_id
        objSet(n).list_order1            := lbRec.list_order1;
        objSet(n).list_order2            := lbRec.list_order2;
        objSet(n).pkey                   := lbRec.pkey;
        objSet(n).backup_type            := lbRec.backup_type;
        objSet(n).file_type              := lbRec.file_type;
        objSet(n).keep                   := lbRec.keep;
        objSet(n).keep_until             := lbRec.keep_until;
        objSet(n).keep_options           := lbRec.keep_options;
        objSet(n).status                 := lbRec.status;
        objSet(n).fname                  := lbRec.fname;
        objSet(n).tag                    := lbRec.tag;
        objSet(n).media                  := lbRec.media;
        objSet(n).recid                  := lbRec.stamp;
        objSet(n).stamp                  := lbRec.stamp;
        objSet(n).device_type            := lbRec.device_type;
        objSet(n).block_size             := lbRec.block_size;
        objSet(n).completion_time        := lbRec.completion_time;
        objSet(n).is_rdf                 := lbRec.is_rdf;
        objSet(n).compressed             := lbRec.compressed;
        objSet(n).obsolete               := lbRec.obsolete;
        objSet(n).bytes                  := lbRec.bytes;
        objSet(n).bs_key                 := lbRec.bs_key;
        objSet(n).bs_count               := lbRec.bs_count;
        objSet(n).bs_stamp               := lbRec.bs_stamp;
        objSet(n).bs_type                := lbRec.bs_type;
        objSet(n).bs_incr_type           := lbRec.bs_incr_type;
        objSet(n).bs_pieces              := lbRec.bs_pieces;
        objSet(n).bs_copies              := lbRec.bs_copies;
        objSet(n).bs_completion_time     := lbRec.bs_completion_time;
        objSet(n).bs_status              := lbRec.bs_status;
        objSet(n).bs_bytes               := lbRec.bs_bytes;
        objSet(n).bs_compressed          := lbRec.bs_compressed;
        objSet(n).bs_tag                 := lbRec.bs_tag;
        objSet(n).bs_device_type         := lbRec.bs_device_type;
        objSet(n).bp_piece#              := lbRec.bp_piece#;
        objSet(n).bp_copy#               := lbRec.bp_copy#;
        objSet(n).df_file#               := lbRec.df_file#;
        objSet(n).df_ts#                 := lbRec.df_ts#;
        objSet(n).df_plugin_change#      := lbRec.df_plugin_change#;
        objSet(n).df_foreign_dbid        := lbRec.df_foreign_dbid;
        objSet(n).df_tablespace          := lbRec.df_tablespace;
        objSet(n).df_resetlogs_change#   := lbRec.df_resetlogs_change#;
        objSet(n).df_creation_change#    := lbRec.df_creation_change#;
        objSet(n).df_checkpoint_change#  := lbRec.df_checkpoint_change#;
        objSet(n).df_ckp_mod_time        := lbRec.df_ckp_mod_time;
        objSet(n).df_incremental_change# := lbRec.df_incremental_change#;
        objSet(n).rl_thread#             := lbRec.rl_thread#;
        objSet(n).rl_sequence#           := lbRec.rl_sequence#;
        objSet(n).rl_resetlogs_change#   := lbRec.rl_resetlogs_change#;
        objSet(n).rl_first_change#       := lbRec.rl_first_change#;
        objSet(n).rl_first_time          := lbRec.rl_first_time;
        objSet(n).rl_next_change#        := lbRec.rl_next_change#;
        objSet(n).rl_next_time           := lbRec.rl_next_time;
        objSet(n).con_id                 := lbRec.con_id;      
      end if;
      firstCall := false;
      self.curval:=self.curval+1;
      if not ret then
        self.done := 1;
      end if;
    end loop;
    return SYS.ODCIConst.Success;
  end ODCITableFetch;
 
  member function ODCITableClose(self IN v_lbRecSetImpl_t) 
    return number 
  is
  begin
    return SYS.ODCIConst.Success;
  end ODCITableClose;
end;
/
CREATE OR REPLACE FUNCTION v_listBackupPipe
   RETURN v_lbRecSet_t PIPELINED using v_lbRecSetImpl_t;
/
--
--
--
--
--
--
--
--
--
create or replace view v_$backup_files
       as select pkey,
                 backup_type,
                 file_type,
                 keep,
                 keep_until,
                 keep_options,
                 status,
                 fname,
                 tag,
                 media,
                 recid,
                 stamp,
                 device_type,
                 block_size,
                 completion_time,
                 compressed,
                 obsolete,
                 bytes,
                 bs_key,
                 bs_count,
                 bs_stamp,
                 bs_type,
                 bs_incr_type,
                 bs_pieces,
                 bs_copies,
                 bs_completion_time,
                 bs_status,
                 bs_bytes,
                 bs_compressed,
                 bs_tag,
                 bs_device_type,
                 bp_piece#,
                 bp_copy#,
                 df_file#,
                 df_tablespace,
                 df_resetlogs_change#,
                 df_creation_change#,
                 df_checkpoint_change#,
                 df_ckp_mod_time,
                 rl_thread#,
                 rl_sequence#,
                 rl_resetlogs_change#,
                 rl_first_change#,
                 rl_first_time,
                 rl_next_change#,
                 rl_next_time,
                 con_id
            from table(v_listBackupPipe);
create or replace public synonym v$backup_files
       for v_$backup_files;
/
 
grant select on v_$backup_files to select_catalog_role;
 
drop public synonym v$restore_range;
drop view v_$restore_range;
drop public synonym v$disk_restore_range;
drop view v_$disk_restore_range;
drop public synonym v$sbt_restore_range;
drop view v_$sbt_restore_range;
drop function v_listRsRangePipe;
drop type v_RangeRecSetImpl_t;
drop type v_RangeRecSet_t;
drop type v_RangeRec_t;
 
create type v_RangeRec_t as object
   (
      db_id                   NUMBER,
      high_time               DATE,
      low_time                DATE,
      low_change#             NUMBER,
      high_change#            NUMBER,
      low_resetlogs_change#   NUMBER,
      high_resetlogs_change#  NUMBER,
      low_resetlogs_time      DATE,
      high_resetlogs_time     DATE,
      con_id                  NUMBER
   );
/
create type v_RangeRecSet_t as table of v_RangeRec_t;
/
create type v_RangeRecSetImpl_t as object
(
  curval                number,   -- current rownum
  done                  number,   -- done with the query
  opCode                varchar2(10),
 
  static function ODCITableStart(sctx   IN OUT v_RangeRecSetImpl_t,
                                 opCode IN varchar2)
    return number,
 
  member function ODCITableFetch(self   IN OUT v_RangeRecSetImpl_t,
                                 nrows  IN     number,
                                 objSet OUT    v_RangeRecSet_t)
    return number,
 
  member function ODCITableClose(self   IN     v_RangeRecSetImpl_t)
    return number
);
/
create or replace type body v_RangeRecSetImpl_t is
 
  static function ODCITableStart(sctx   IN OUT v_RangeRecSetImpl_t,
                                 opCode IN varchar2)
    return number is
  begin
--
    sctx:=v_RangeRecSetImpl_t(0, 0, opCode);
    return SYS.ODCIConst.Success;
  end ODCITableStart;
 
  member function ODCITableFetch(self   IN OUT v_RangeRecSetImpl_t,
                                 nrows  IN     number,
                                 objSet OUT    v_RangeRecSet_t)
    return number is
 
    n                number := 0;
    i                number;
    indx             number := 0;
    dbcount          number;
    ret              boolean;
    restoreRangeTab  sys.dbms_rcvman.restoreRangeTab_t;
 
    CURSOR getAllDb_c IS SELECT  dbid FROM v$database;
    dbDetail getAllDb_c%rowtype;
 
  begin
    open getAllDb_c;
    objSet := v_RangeRecSet_t();
 
    select count(*) into dbcount from v$database;
 
    while n < dbcount and self.done = 0 loop
      n := n + 1;
 
      sys.dbms_rcvman.resetAll;
      sys.dbms_rcvman.resetDeviceType;
      sys.dbms_rcvman.setAllIncarnations(TRUE);
 
      if (opCode = 'V$ANY') then
        sys.dbms_rcvman.setDeviceTypeAny;
      elsif (opCode = 'V$DISK') then
        sys.dbms_rcvman.setDeviceType('DISK');
      elsif (opCode = 'V$SBT') then
        sys.dbms_rcvman.setDeviceType('SBT_TAPE');
      end if;
 
      fetch getAllDb_c into dbDetail;
      sys.dbms_rcvman.setdatabase(NULL, NULL, NULL, dbDetail.dbid);
 
      ret := sys.dbms_rcvman.getRestoreRangeSet(restoreRangeTab, 
                                                opCode,
                                                dbDetail.dbid);
      i := to_number(null);
      LOOP
        IF (i is null) THEN
           i := restoreRangeTab.first;
        ELSE
           i := restoreRangeTab.next(i);
        END IF;
        EXIT WHEN i IS NULL;
 
        if (restoreRangeTab(i).isValidRange = TRUE) then
          objSet.extend;
          indx := indx + 1;
          objSet(indx) := v_RangeRec_t(
                                    to_number(null),
                                    to_date(null),
                                    to_date(null),
                                    to_number(null),
                                    to_number(null),
                                    to_number(null),
                                    to_number(null),
                                    to_date(null),
                                    to_date(null),
                                    to_number(null));
          if (ret = TRUE) then
            objSet(indx).db_id            := dbDetail.dbid;
            objSet(indx).low_time         := restoreRangeTab(i).lowTime;
            objSet(indx).high_time        := restoreRangeTab(i).highTime;
            objSet(indx).low_change#      := restoreRangeTab(i).lowScn;
            objSet(indx).high_change#     := restoreRangeTab(i).highScn;
            objSet(indx).low_resetlogs_change# := restoreRangeTab(i).lowRlgScn;
            objSet(indx).high_resetlogs_change# := 
                                                restoreRangeTab(i).highRlgScn;
            objSet(indx).low_resetlogs_time  := restoreRangeTab(i).lowRlgTime;
            objSet(indx).high_resetlogs_time := restoreRangeTab(i).highRlgTime;
            objSet(indx).con_id              := restoreRangeTab(i).con_id;
          end if;
        end if;
      END LOOP;
      self.curval := self.curval + 1;
      if (self.curval = dbcount) then
        self.done := 1;
        close getAllDb_c;
      end if;
    end loop;
 
    return SYS.ODCIConst.Success;
  end ODCITableFetch;
 
  member function ODCITableClose(self IN v_RangeRecSetImpl_t)
    return number is
  begin
    return SYS.ODCIConst.Success;
  end ODCITableClose;
end;
/
CREATE OR REPLACE FUNCTION v_listRsRangePipe (opCode IN varchar2)
   RETURN v_RangeRecSet_t PIPELINED using v_RangeRecSetImpl_t;
/
create or replace view v_$restore_range
       as select db_id,
                 low_time,
                 high_time,
                 low_change#,
                 high_change#,
                 low_resetlogs_change#,
                 high_resetlogs_change#,
                 low_resetlogs_time,
                 high_resetlogs_time,
                 con_id
                 from TABLE(v_listRsRangePipe('V$ANY'));
/
create or replace public synonym v$restore_range
       for v_$restore_range;
/
create or replace view v_$disk_restore_range
       as select db_id,
                 low_time,
                 high_time,
                 low_change#,
                 high_change#,
                 low_resetlogs_change#,
                 high_resetlogs_change#,
                 low_resetlogs_time,
                 high_resetlogs_time,
                 con_id
                 from TABLE(v_listRsRangePipe('V$DISK'));
/
create or replace public synonym v$disk_restore_range
       for v_$disk_restore_range;
/
create or replace view v_$sbt_restore_range
       as select db_id,
                 low_time,
                 high_time,
                 low_change#,
                 high_change#,
                 low_resetlogs_change#,
                 high_resetlogs_change#,
                 low_resetlogs_time,
                 high_resetlogs_time,
                 con_id
                 from TABLE(v_listRsRangePipe('V$SBT'));
/
create or replace public synonym v$sbt_restore_range
       for v_$sbt_restore_range;
/
 
grant select on v_$restore_range to select_catalog_role;
 
grant select on v_$disk_restore_range to select_catalog_role;
 
grant select on v_$sbt_restore_range to select_catalog_role;
 
create or replace view v_$rman_backup_subjob_details as select * from v$rman_backup_subjob_details;
create or replace public synonym v$rman_backup_subjob_details for v_$rman_backup_subjob_details;
grant select on v_$rman_backup_subjob_details to select_catalog_role;
 
create or replace view v_$rman_backup_job_details as select * from v$rman_backup_job_details;
create or replace public synonym v$rman_backup_job_details for v_$rman_backup_job_details;
grant select on v_$rman_backup_job_details to select_catalog_role;
 
create or replace view v_$backup_set_details as select * from v$backup_set_details;
create or replace public synonym v$backup_set_details for v_$backup_set_details;
grant select on v_$backup_set_details to select_catalog_role;
 
create or replace view v_$backup_piece_details as select * from v$backup_piece_details;
create or replace public synonym v$backup_piece_details for v_$backup_piece_details;
grant select on v_$backup_piece_details to select_catalog_role;
 
create or replace view v_$backup_copy_details as select * from v$backup_copy_details;
create or replace public synonym v$backup_copy_details for v_$backup_copy_details;
grant select on v_$backup_copy_details to select_catalog_role;
 
create or replace view v_$proxy_copy_details as select * from v$proxy_copy_details;
create or replace public synonym v$proxy_copy_details for v_$proxy_copy_details;
grant select on v_$proxy_copy_details to select_catalog_role;
 
create or replace view v_$proxy_archivelog_details as select * from v$proxy_archivelog_details;
create or replace public synonym v$proxy_archivelog_details for v_$proxy_archivelog_details;
grant select on v_$proxy_archivelog_details to select_catalog_role;
 
create or replace view v_$backup_datafile_details as select * from v$backup_datafile_details;
create or replace public synonym v$backup_datafile_details for v_$backup_datafile_details;
grant select on v_$backup_datafile_details to select_catalog_role;
 
create or replace view v_$backup_controlfile_details as select * from v$backup_controlfile_details;
create or replace public synonym v$backup_controlfile_details for v_$backup_controlfile_details;
grant select on v_$backup_controlfile_details to select_catalog_role;
 
create or replace view v_$backup_archivelog_details as select * from v$backup_archivelog_details;
create or replace public synonym v$backup_archivelog_details for v_$backup_archivelog_details;
grant select on v_$backup_archivelog_details to select_catalog_role;
 
create or replace view v_$backup_spfile_details as select * from v$backup_spfile_details;
create or replace public synonym v$backup_spfile_details for v_$backup_spfile_details;
grant select on v_$backup_spfile_details to select_catalog_role;
 
create or replace view v_$backup_set_summary as select * from v$backup_set_summary;
create or replace public synonym v$backup_set_summary for v_$backup_set_summary;
grant select on v_$backup_set_summary to select_catalog_role;
 
create or replace view v_$backup_datafile_summary as select * from v$backup_datafile_summary;
create or replace public synonym v$backup_datafile_summary for v_$backup_datafile_summary;
grant select on v_$backup_datafile_summary to select_catalog_role;
 
create or replace view v_$backup_controlfile_summary as select * from v$backup_controlfile_summary;
create or replace public synonym v$backup_controlfile_summary for v_$backup_controlfile_summary;
grant select on v_$backup_controlfile_summary to select_catalog_role;
 
create or replace view v_$backup_archivelog_summary as select * from v$backup_archivelog_summary;
create or replace public synonym v$backup_archivelog_summary for v_$backup_archivelog_summary;
grant select on v_$backup_archivelog_summary to select_catalog_role;
 
create or replace view v_$backup_spfile_summary as select * from v$backup_spfile_summary;
create or replace public synonym v$backup_spfile_summary for v_$backup_spfile_summary;
grant select on v_$backup_spfile_summary to select_catalog_role;
 
create or replace view v_$backup_copy_summary as select * from v$backup_copy_summary;
create or replace public synonym v$backup_copy_summary for v_$backup_copy_summary;
grant select on v_$backup_copy_summary to select_catalog_role;
 
create or replace view v_$proxy_copy_summary as select * from v$proxy_copy_summary;
create or replace public synonym v$proxy_copy_summary for v_$proxy_copy_summary;
grant select on v_$proxy_copy_summary to select_catalog_role;
 
create or replace view v_$proxy_archivelog_summary as select * from v$proxy_archivelog_summary;
create or replace public synonym v$proxy_archivelog_summary for v_$proxy_archivelog_summary;
grant select on v_$proxy_archivelog_summary to select_catalog_role;
 
create or replace view v_$unusable_backupfile_details as select * from v$unusable_backupfile_details;
create or replace public synonym v$unusable_backupfile_details for v_$unusable_backupfile_details;
grant select on v_$unusable_backupfile_details to select_catalog_role;
 
create or replace view v_$rman_backup_type as select * from v$rman_backup_type;
create or replace public synonym v$rman_backup_type for v_$rman_backup_type;
grant select on v_$rman_backup_type to select_catalog_role;
 
create or replace view v_$rman_encryption_algorithms as select * from
v$rman_encryption_algorithms;
create or replace public synonym v$rman_encryption_algorithms for
v_$rman_encryption_algorithms;
grant select on v_$rman_encryption_algorithms to select_catalog_role;
 
--
>>>
 
define rcver_mod
<<<
 alter table rcver modify (version varchar2(15))
>>>
 
define rcver
<<<
CREATE TABLE rcver
(
version varchar2(15) NOT NULL,
constraint rcver_version_unique unique(version)
) &tablespace&
>>>
 
define raschemaver
<<<
CREATE TABLE raschemaver
(
version number,
CONSTRAINT raschemaver_p PRIMARY KEY (version),
CONSTRAINT check_version CHECK (version >= 0 and version < 100)
)
ORGANIZATION INDEX
&tablespace&
>>>
 
define enable_plsql_warn
<<<
begin
dbms_warning.set_warning_setting_string('enable:all', 'session');
dbms_warning.add_warning_setting_cat('performance','disable', 'session');
end;
>>>
 
define disable_plsql_warn
<<<
begin
dbms_warning.set_warning_setting_string('disable:all', 'session');
end;
>>>
 
define disable_plsql_warn_5005_5021
<<<
begin
dbms_warning.add_warning_setting_num(5005, 'disable', 'session');
dbms_warning.add_warning_setting_num(5021, 'disable', 'session');
end;
>>>
 
define disable_plsql_warn_5004_6002
<<<
begin
dbms_warning.add_warning_setting_num(5004, 'disable', 'session'); 
dbms_warning.add_warning_setting_num(6002, 'disable', 'session'); 
end;
>>>
 
define disable_plsql_warn_5018_6010
<<<
begin
dbms_warning.add_warning_setting_num(5018, 'disable', 'session');
dbms_warning.add_warning_setting_num(6010, 'disable', 'session');
end;
>>>
 
define disable_plsql_warn_6006_6010
<<<
begin
dbms_warning.add_warning_setting_num(6006, 'disable', 'session');
dbms_warning.add_warning_setting_num(6010, 'disable', 'session');
end;
>>>
 
define disable_plsql_warn_6009
<<<
begin
dbms_warning.add_warning_setting_num(6009, 'disable', 'session');
end;
>>>
 
define create_sbt_template_db
<<<
create table sbt_template_db
(
db_key         number not null,
template_key   number not null,
baseline_scn   number,
last_bp_key    number,           -- last bp_key queued so we can avoid
--
curr_dbinc_key number,
constraint sbt_template_db_p1 primary key (db_key, template_key)
) &tablespace&
>>>
 
define rcver_setvsn
<<<
begin
  delete from rcver;
  insert into rcver values(&vsnstr&);
  commit;
end;
>>>
 
define raschemaver_update
<<<
begin
  delete from raschemaver;
  insert into raschemaver values (0);
  commit;
end;
>>>
 
define set_reg_dbunqnm
<<<
declare
   cursor db_c is
      select reg_db_unique_name, db_key
        from db
       where reg_db_unique_name is null
       for update;   
   l_reg_dbunqnm node.db_unique_name%TYPE;
begin
   for dbrec in db_c loop
     select max(db_unique_name) into l_reg_dbunqnm
       from (select db_unique_name
               from node
              where dbrec.db_key = node.db_key and
                    db_unique_name not like '%$%'
                    order by database_role, db_unique_name)
      where rownum = 1;
     update db set reg_db_unique_name = l_reg_dbunqnm
      where current of db_c;
   end loop;
   commit;
end;
>>>
 
define prvtrvct_plb
<<<
CREATE OR replace PACKAGE BODY dbms_rcvcat IS
--
--
--
 
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
 
catalogVersion CONSTANT VARCHAR2(11) := '18.04.00.00'; -- @@VERSION_CHANGE@@ set
 
--
--
type version_list_type is table of varchar2(14);
version_list version_list_type := version_list_type(
               '08.00.04.00'
              ,'08.00.05.00'
              ,'08.01.03.00'
              ,'08.01.06.00'
              ,'08.01.07.00'
              ,'09.00.00.00'
              ,'09.02.00.00'
              ,'10.01.00.00'
              ,'10.02.00.00'
              ,'10.02.00.01'
              ,'11.01.00.00'
              ,'11.01.00.01'
              ,'11.01.00.02'
              ,'11.01.00.03'
              ,'11.01.00.04'
              ,'11.01.00.05'
              ,'11.01.00.06'
              ,'11.01.00.07'
              ,'11.02.00.00'
              ,'11.02.00.01'
              ,'11.02.00.02'
              ,'12.01.00.00'
              ,'12.01.00.01'
              ,'12.01.00.02'
              ,'12.02.00.00'
              ,'12.02.00.01'
              ,'12.02.00.02'
              ,catalogVersion -- @@VSN_CHANGE@@
             );
 
version_max_index binary_integer;
version_counter binary_integer := 1;
 
/*-----------*
 * Constants *
 *-----------*/
 
MAXNUMVAL      CONSTANT NUMBER := 2**32-1;
ZERO_GUID      CONSTANT RAW(16) := HEXTORAW(RPAD('0', 32, '0'));
 
/*-------------------------*
 * Package State Variables *
 *-------------------------*/
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
 
debug               BOOLEAN := FALSE;
this_ckp_key        NUMBER  := NULL;
this_ckp_scn        NUMBER  := NULL;
this_ckp_time       DATE    := NULL;
this_lib_key        NUMBER  := NULL;
last_full_ckp_scn   NUMBER  := NULL;
last_guid           PDB.GUID%TYPE := NULL;
last_con_id_ts#     NUMBER;
last_ts#            NUMBER;
last_file#          NUMBER;
last_thread#        NUMBER;
last_fname          site_dfatt.fname%type;
last_pdb_recid      NUMBER;
last_pic_recid      NUMBER;
last_ts_recid       NUMBER;
last_df_recid       NUMBER;
last_tf_recid       NUMBER;
last_rt_recid       NUMBER;
last_orl_recid      NUMBER;
last_conf_recid     NUMBER;
force_resync2cf     VARCHAR2(3) := 'NO';
last_rlh_recid      NUMBER;
last_al_recid       NUMBER;
last_offr_recid     NUMBER;
last_bs_recid       NUMBER;
last_bp_recid       NUMBER;
last_bdf_recid      NUMBER;
last_bsf_recid      NUMBER;
last_brl_recid      NUMBER;
last_cdf_recid      NUMBER;
last_bcb_recid      NUMBER;
last_ccb_recid      NUMBER;
last_do_recid       NUMBER;
last_xdf_recid      NUMBER := NULL;
last_xal_recid      NUMBER := NULL;
last_rsr_recid      NUMBER;
last_rout_stamp     NUMBER := NULL;
last_inst_startup_stamp NUMBER := NULL;
lrsr_key            NUMBER;
lrout_skey          NUMBER;
lsession_recid      NUMBER;
lsession_stamp      NUMBER;
lrman_status_recid  NUMBER;
lrman_status_stamp  NUMBER;
--
krbmror_llength_bytes NUMBER := 130;
--
--
type rout_list     is table of rout%ROWTYPE index by binary_integer;
lrout_table        rout_list;
lrout_curridx      binary_integer := 0;
 
--
--
last_ic_recid       NUMBER := NULL;
scr_key             NUMBER := NULL;
scr_line            NUMBER;
scr_glob            BOOLEAN;
kccdivts            NUMBER;
type bskeys_v       is table of number index by varchar2(128);
duplicatebs         bskeys_v;
type bskeys is table of number index by binary_integer;
cntbs               NUMBER := 0;
updatebs            bskeys;
last_reset_scn      NUMBER;
last_reset_time     DATE;
last_dbinc_key      NUMBER;
do_temp_ts_resync   BOOLEAN := FALSE;  -- indicates if temp_ts is resynced
last_cf_version_time DATE;
dbglvl              NUMBER := RCVCAT_LEVEL_DEFAULT;
low_nrsp_recid      NUMBER;
last_nrsp_recid     NUMBER;
last_grsp_recid     NUMBER;
last_rspname        grsp.rspname%type;
last_pdb_key        NUMBER;
last_bcr_recid      NUMBER;
last_resync_cksum   NUMBER;
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
this_cf_type    VARCHAR2(7) := NULL;
this_cf_version DATE := NULL;
this_ckp_type   VARCHAR2(10) := NULL;
 
--
this_db_unique_name    node.db_unique_name%TYPE;
this_site_key          NUMBER; -- Never NULL even for 9i RMAN client
client_site_aware      boolean := FALSE;
 
--
logs_shared           number := FALSE#; -- used only when client_site_aware
disk_backups_shared   number := TRUE#;  -- indicates shared accross all sites
tape_backups_shared   number := TRUE#;  -- indicates shared accross all sites
 
--
session_keep_output   number := NULL;
rman_keep_output      number := NULL;
 
reNorm_state binary_integer;
RENORM_DFATT CONSTANT binary_integer := 1;
RENORM_ORL   CONSTANT binary_integer := 2;
RENORM_AL    CONSTANT binary_integer := 3;
RENORM_BP    CONSTANT binary_integer := 4;
RENORM_CCF   CONSTANT binary_integer := 5;
RENORM_CDF   CONSTANT binary_integer := 6;
RENORM_TFATT CONSTANT binary_integer := 7;
 
--
--
--
--
--
--
type sessionWaterMarks_t is record
(
last_kccdivts      number := 0,            -- check if ctl version is diff 
high_rout_stamp    number := 0,            -- for rman_output resync
high_ic_recid      number := 0,            -- incarnation recid
high_offr_recid    number := 0,            -- offline range (kkor) recid
high_rlh_recid     number := 0,            -- log history (kcclh) recid
high_al_recid      number := 0,            -- archived log (kccal) recid
high_bs_recid      number := 0,            -- backup set (kccbs) recid
high_bp_recid      number := 0,            -- backup piece (kccbp) recid
high_bdf_recid     number := 0,            -- backup datafile (kccbf) recid
high_cdf_recid     number := 0,            -- datafile copy (kccdc) recid
high_brl_recid     number := 0,            -- backup redo log (kccbl) recid
high_bcb_recid     number := 0,            -- backup datafile corruption recid
high_ccb_recid     number := 0,            -- datafile copy corruption recid
high_do_recid      number := 0,            -- deleted object recid
high_pc_recid      number := 0,            -- proxy copy (kccpc) recid
high_bsf_recid     number := 0,            -- backup SPFILE (kccbi) recid
high_rsr_recid     number := 0,            -- RMAN status (kccrsr) recid
high_nrsp_recid    number := 0,            -- normal restore point recid
high_bcr_recid     number := 0,            -- high blk crpt (kccblkcor) recid
high_pic_recid     number := 0             -- high pdbinc recid
);
 
init_sessionWaterMarks sessionWaterMarks_t;
prev_sessionWaterMarks sessionWaterMarks_t;
sessionWaterMarks      sessionWaterMarks_t;
 
--
type ts_name_list     is table of ts.ts_name%type index by binary_integer;
type numTab_t         is table of number index by binary_integer; 
type key_columns_list is table of varchar2(30);
type sp_columns_list  is table of varchar2(1);
 
--
--
--
import_dbid numTab_t;
--
--
--
--
--
--
--
--
key_columns  CONSTANT key_columns_list := key_columns_list
   ('DB_KEY'          , 'DBINC_KEY'      , 'CURR_DBINC_KEY'    ,
    'PARENT_DBINC_KEY', 'CKP_KEY'        , 'START_CKP_KEY'     ,
    'END_CKP_KEY'     , 'OFFR_KEY'       , 'RR_KEY'            ,
    'RLH_KEY'         , 'AL_KEY'         , 'BS_KEY'            ,
    'BP_KEY'          , 'BCF_KEY'        , 'CCF_KEY'           ,
    'XCF_KEY'         , 'BSF_KEY'        , 'BDF_KEY'           ,
    'CDF_KEY'         , 'XDF_KEY'        , 'XAL_KEY'           ,
    'BRL_KEY'         , 'BDF_KEY'        , 'RSR_KEY'           ,
    'RSR_PKEY'        , 'RSR_L0KEY'      , 'SCR_KEY'           ,
    'ROUT_SKEY'       , 'SITE_KEY'       , 'DF_KEY'            ,
    'TF_KEY'          , 'PDB_KEY'        , 'LIB_KEY'           ,
    'VB_KEY'          , 'CT_KEY'         , 'PDBINC_KEY'        ,
    'CURR_PDBINC_KEY' , 'BORN_DBINC_KEY' , 'PARENT_PDBINC_KEY' ,
    'TS_PDBINC_KEY'   , 'TEMPLATE_KEY');
 
--
--
import_dblink tempres.name%type;
import_offset number;
 
/*---------------------------------------------------*
 * package variables used for recovery server        *
 *---------------------------------------------------*/
this_is_ors              BOOLEAN := FALSE;
this_is_ors_admin        BOOLEAN := FALSE;
orsadmin_user            ALL_USERS.USERNAME%TYPE := NULL;
this_server              SERVER%ROWTYPE;
this_amazon_server       BOOLEAN := FALSE;
this_server_uname        VARCHAR2(512):= NULL;
this_server_passw        VARCHAR2(512):= NULL;
this_server_url          VARCHAR2(512):= NULL;
this_xml_signature_beg   VARCHAR2(50) := '<?xml version="1.0"?> <ALL_TABLES> ';
this_xml_signature_end   VARCHAR2(50) := ' </ALL_TABLES> ';
this_forwatermarks       VARCHAR2(50) := 'forwatermarks_';
this_watermarks          VARCHAR2(50) := 'watermarks_';
this_backupsets          VARCHAR2(50) := 'backupsets_';
this_database            VARCHAR2(50) := 'database_';
this_url_db_unique_name  node.db_unique_name%TYPE;
this_lock_ors_inspect    BOOLEAN      := FALSE;
this_clr_ba_newinc_err   BOOLEAN      := FALSE;
this_upstream_site_key   NUMBER       := NULL;
this_enable_populate_rsr NUMBER       := NULL;
--
--
--
this_verrec                  RC_RCVER%ROWTYPE;
this_curr_inc                RC_DATABASE_INCARNATION%ROWTYPE;
this_wmrec                   RC_WATERMARKS%ROWTYPE;
this_upstream_dbrec          RCI_RA_UPSTREAM_DATABASE%ROWTYPE;
this_rsiterec                RC_SITE%ROWTYPE;
this_v_wmrec                 CLOB;
this_curr_bp_recid           NUMBER;
this_high_bp_recid           NUMBER;
this_bp_key_poll             NUMBER;
 
FUNCTION assert_schema (
  i_schema                   VARCHAR2
, i_enquote                  BOOLEAN DEFAULT FALSE
)
RETURN VARCHAR2;
 
PROCEDURE assert_schema (
  o_schema                   OUT NOCOPY VARCHAR2
, o_eschema                  OUT NOCOPY VARCHAR2
, i_schema                   IN VARCHAR2
);
 
g_catowner                   CONSTANT user_users.username%TYPE :=
  assert_schema(dbms_catowner);
g_ecatowner                  CONSTANT VARCHAR2(130) :=
  assert_schema(dbms_catowner, TRUE);
 
e_no_vpd_setup               CONSTANT NUMBER := -20153;
e_no_vpd_setup_m             CONSTANT VARCHAR2(64) :=
  'recovery catalog does not have VPD support enabled!';
 
--
--
--
--
--
TYPE vtr IS VARRAY(4) OF VARCHAR2(256);
TYPE vtr_t IS TABLE OF vtr;
vpd_table_list CONSTANT vtr_t :=
vtr_t
(
    vtr('VPC_DATABASES', 'SELECT', 'T', 'T')
  , vtr('DB',             NULL,    'T', 'F')
  , vtr('DBINC',          NULL,    'T', 'T')
  , vtr('BP',             NULL,    'T', 'T')
  , vtr('BSF',            NULL,    'T', 'T')
  , vtr('BS',             NULL,    'T', 'T')
  , vtr('CONF',           NULL,    'T', 'T')
  , vtr('DELETED_OBJECT', NULL,    'T', 'T')
  , vtr('DO_SEQ',         NULL,    'T', 'T')
  , vtr('NODE',           NULL,    'T', 'T')
  , vtr('PDB',            NULL,    'T', 'T')
  , vtr('ROUT',           NULL,    'T', 'T')
  , vtr('WATERMARKS',     NULL,    'T', 'T')
  , vtr('PDBINC',         NULL,    'T', 'T')
  , vtr('PDB_DBINC',      NULL,    'T', 'T')
  , vtr('AL',             NULL,    'T', 'T')
  , vtr('BCF',            NULL,    'T', 'T')
  , vtr('BDF',            NULL,    'T', 'T')
  , vtr('BRL',            NULL,    'T', 'T')
  , vtr('CCF',            NULL,    'T', 'T')
  , vtr('CDF',            NULL,    'T', 'T')
  , vtr('CKP',            NULL,    'T', 'T')
  , vtr('DF',             NULL,    'T', 'T')
  , vtr('FB',             NULL,    'T', 'T')
  , vtr('GRSP',           NULL,    'T', 'T')
  , vtr('NRSP',           NULL,    'T', 'T')
  , vtr('OFFR',           NULL,    'T', 'T')
  , vtr('ORL',            NULL,    'T', 'T')
  , vtr('RLH',            NULL,    'T', 'T')
  , vtr('RR',             NULL,    'T', 'T')
  , vtr('RSR',            NULL,    'T', 'T')
  , vtr('RT',             NULL,    'T', 'T')
  , vtr('TF',             NULL,    'T', 'T')
  , vtr('TSATT',          NULL,    'T', 'T')
  , vtr('TS',             NULL,    'T', 'T')
  , vtr('XAL',            NULL,    'T', 'T')
  , vtr('XCF',            NULL,    'T', 'T')
  , vtr('XDF',            NULL,    'T', 'T')
  , vtr('SCR',            NULL,    'T', 'T')
  , vtr('BCB',            NULL,    'T', 'T')
  , vtr('CCB',            NULL,    'T', 'T')
  , vtr('SCRL',           NULL,    'T', 'T')
  , vtr('CFS',           'SELECT', 'T', 'T')
  , vtr('CONFIG',        'SELECT', 'T', 'T')
  , vtr('ORSEVENT',       NULL,    'T', 'T')
  , vtr('RCFILE',         NULL,    'T', 'T')
  , vtr('XMLSTORE',      'SELECT', 'T', 'F')
  , vtr('BCR',            NULL,    'T', 'T')
  , vtr('SERVER',         NULL,    'T', 'F')
  , vtr('VPC_USERS',     'SELECT', 'T', 'T')
  , vtr('SITE_DFATT',     NULL,    'T', 'T')
  , vtr('SITE_TFATT',     NULL,    'T', 'T')
  , vtr('RCVER',         'SELECT', 'F', 'F')
  , vtr('RASCHEMAVER',   'SELECT', 'F', 'F')
  , vtr('RRCACHE',       'SELECT', 'T', 'T')  
  , vtr('SBT_TEMPLATE_DB',NULL,    'T', 'T')
);
--
--
g_vpd_required_policies      NUMBER := 0;
 
/*---------*
 * Cursors *
 *---------*/
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
 
--
cursor pdbQ IS
  SELECT pdb.pdb_key, pdb.name, pdb.con_id, pdb.guid,
         pdb.create_scn, pdb.nobackup
    FROM pdb
   WHERE pdb.db_key = this_db_key
     AND pdb.con_id > 1
   ORDER BY pdb.guid;
 
cursor picQ IS
   SELECT pdbinc.pdb_key, pdbinc.pdbinc_key, pdb.con_id,
          pdb.guid, pdb.create_scn, pdbinc.inc_scn, pdbinc.begin_reset_scn,
          pdbinc.begin_reset_time, pdbinc.end_reset_scn,
          dbinc.reset_scn db_reset_scn, dbinc.reset_time db_reset_time,
          pdbinc.parent_pdbinc_key
     FROM pdbinc, pdb, dbinc
    WHERE pdb.pdb_key     = pdbinc.pdb_key
      AND dbinc.dbinc_key = pdbinc.born_dbinc_key
      AND pdb.con_id      > 1
      AND pdb.db_key      = this_db_key
    ORDER BY guid, con_id, create_scn, begin_reset_scn, begin_reset_time,
             end_reset_scn;
--
 
--
cursor tsQ IS
  SELECT ts.ts_name, ts.ts#, ts.create_scn, ts.create_time, tsatt.rbs_count,
         ts.included_in_database_backup, ts.bigfile, ts.temporary,
         ts.encrypt_in_backup, ts.plugin_scn, ts.pdbinc_key, pdbinc.con_id,
         pdbinc.curr_pdbinc_key, pdbinc.pdb_key, pdbinc.drop_scn pdb_drop_scn
  FROM ts, tsatt, rci_pdbinc_this_dbinc pdbinc
  WHERE ts.dbinc_key     = tsatt.dbinc_key
    AND ts.ts#           = tsatt.ts#
    AND ts.pdbinc_key    = pdbinc.pdbinc_key
    AND tsatt.pdbinc_key = pdbinc.pdbinc_key
    AND ts.create_scn    = tsatt.create_scn
    AND ts.dbinc_key     = this_dbinc_key
    AND ts.plugin_scn    = tsatt.plugin_scn
    AND ts.drop_scn       IS NULL              --skip ones we know were dropped
    AND tsatt.end_ckp_key IS NULL
    AND pdbinc.dbinc_key = this_dbinc_key
    AND ts.create_scn    < pdbinc.next_inc_scn --skip ones in orphan scn
  ORDER BY pdbinc.con_id, ts.ts#; -- client passes rows to checkTs in
--
--
 
--
cursor dfQ IS
  SELECT df.file#, df.create_scn, df.create_time, df.plugin_scn, df.ts#,
         site_dfatt.fname, df.blocks, df.clone_fname, df.stop_scn,
         df.read_only, df.plugged_readonly, df.create_thread, df.create_size,
         df.foreign_dbid, df.pdb_closed, df.pdbinc_key,
         pdbinc.curr_pdbinc_key, pdbinc.pdb_key
  FROM df, site_dfatt, rci_pdbinc_this_dbinc pdbinc
  WHERE df.dbinc_key  = this_dbinc_key  -- our dbinc please
    AND df.drop_scn  IS NULL            -- df not dropped
    AND this_site_key = site_dfatt.site_key(+)  -- select names for the site
    AND df.df_key     = site_dfatt.df_key(+)    -- join site_dfatt to df
    AND df.pdbinc_key = pdbinc.pdbinc_key
    AND df.create_scn < pdbinc.next_inc_scn     -- skip ones in orphan scn
    AND df.plugin_scn < pdbinc.next_inc_scn
    AND pdbinc.dbinc_key = this_dbinc_key
  ORDER BY df.file#;                    -- client passes rows to checkDf in
--
--
 
--
cursor tfQ IS
  SELECT tf.file#, tf.create_scn, tf.create_time, tf.ts#,
         site_tfatt.fname, site_tfatt.blocks, site_tfatt.autoextend,
         site_tfatt.max_size, site_tfatt.next_size, tf.tf_key tf_key,
         tf.pdb_key, pdb.con_id
  FROM tf, site_tfatt, pdb
  WHERE tf.dbinc_key  = this_dbinc_key       -- our dbinc please
    AND this_site_key = site_tfatt.site_key  -- select names for the site
    AND tf.tf_key     = site_tfatt.tf_key    -- join site_tfatt to tf
    AND site_tfatt.drop_scn IS NULL          -- tf not dropped
    AND tf.pdb_key    = pdb.pdb_key
  ORDER BY tf.file#;                    -- client passes rows to checkTf in
--
--
 
--
cursor rtQ IS
  SELECT rt.thread#, rt.sequence#, rt.enable_scn,
         rt.enable_time, rt.status
  FROM rt
  WHERE rt.dbinc_key = this_dbinc_key
  ORDER BY rt.thread#;
 
 
--
cursor orlQ IS
  SELECT orl.thread#, orl.group#, orl.fname
  FROM orl
  WHERE orl.dbinc_key = this_dbinc_key
    AND orl.site_key  = this_site_key
  ORDER BY nlssort(orl.fname, 'NLS_COMP=ANSI NLS_SORT=ASCII7'); -- bug 2107554
 
--
cursor grspQ IS
  SELECT grsp.rspname, grsp.from_scn, grsp.to_scn, grsp.pdb_key
  FROM grsp, dbinc, pdb
  WHERE grsp.dbinc_key = dbinc.dbinc_key
    AND dbinc.db_key = this_db_key
    AND grsp.site_key = this_site_key
    AND grsp.pdb_key = pdb.pdb_key
  ORDER BY pdb.con_id, grsp.pdb_key,
           nlssort(grsp.rspname, 'NLS_COMP=ANSI NLS_SORT=ASCII7');
 
--
--
cursor bpq(device_type VARCHAR2, handle VARCHAR2,
           bp_recid VARCHAR2, bp_stamp VARCHAR2) IS
  SELECT bp_key, bs_key
  FROM bp
  WHERE db_key = this_db_key
  AND   status != 'D'
  AND   device_type = bpq.device_type
  AND   ((disk_backups_shared = TRUE# AND bp.device_type = 'DISK') OR
         (tape_backups_shared = TRUE# AND bp.device_type <> 'DISK') OR
         (this_site_key = nvl(bp.site_key, this_site_key)))
  AND   handle = bpq.handle
  AND   handle_hashkey = substr(bpq.device_type,1,10) ||
                         substr(bpq.handle,1,10) ||
                         substr(bpq.handle,-10)
  AND   NOT (bp_recid = bpq.bp_recid AND
             bp_stamp = bpq.bp_stamp);
 
 
--
cursor scrlQ(key NUMBER) IS
  SELECT text
  FROM scrl
  WHERE scr_key = key
  ORDER BY linenum;
 
--
cursor rcverQ IS
  SELECT version
  FROM rcver
  ORDER BY version;
 
cursor reNorm_dfatt_c IS
  SELECT fname
  FROM site_dfatt
  WHERE df_key in (select df_key from df, dbinc 
                    where df.dbinc_key = dbinc.dbinc_key 
                      and dbinc.db_key = this_db_key)
  FOR UPDATE OF site_dfatt.df_key;
 
cursor reNorm_orl_c IS
  SELECT fname
  FROM orl
  WHERE dbinc_key in (select dbinc_key from dbinc where db_key = this_db_key)
  FOR UPDATE OF orl.dbinc_key;
 
cursor reNorm_al_c IS
  SELECT fname
  FROM al
  where dbinc_key in (select dbinc_key from dbinc where db_key = this_db_key)
  FOR UPDATE OF al.al_key;
 
cursor reNorm_bp_c IS
  SELECT handle
  FROM bp
  WHERE device_type = 'DISK' and db_key = this_db_key
  FOR UPDATE OF bp.bp_key;
 
cursor reNorm_ccf_c IS
  SELECT fname
  FROM ccf
  WHERE dbinc_key in (select dbinc_key from dbinc where db_key = this_db_key)
  FOR UPDATE OF ccf.ccf_key;
 
cursor reNorm_cdf_c IS
  SELECT fname
  FROM cdf
  WHERE dbinc_key in (select dbinc_key from dbinc where db_key = this_db_key)
  FOR UPDATE OF cdf.dbinc_key;
 
cursor reNorm_tfatt_c IS
  SELECT fname
  FROM site_tfatt
  WHERE tf_key in (select tf_key from tf, dbinc 
                    where tf.dbinc_key = dbinc.dbinc_key 
                      and dbinc.db_key = this_db_key)
  FOR UPDATE OF site_tfatt.tf_key;
 
cursor lscrnames_c(glob number, allnames number) IS
    select 1 oby, rdbi.db_name dname, s.scr_name sname, s.scr_comment scomm
      from db rdb, dbinc rdbi, scr s
     where lscrnames_c.glob is null
       and lscrnames_c.allnames is null
       and rdbi.dbinc_key = rdb.curr_dbinc_key
       and rdb.db_key = s.db_key
       and s.db_key = this_db_key
       and s.db_key is not NULL
    UNION ALL
    select 2, 'ORA%GLOB', s.scr_name, s.scr_comment
      from scr s
     where s.db_key IS NULL
    UNION ALL
    select 3, rdbi.db_name, s.scr_name, s.scr_comment
      from db rdb, dbinc rdbi, scr s
     where lscrnames_c.glob is null
       and lscrnames_c.allnames is not null
       and rdbi.dbinc_key = rdb.curr_dbinc_key
       and rdb.db_key = s.db_key
       and s.db_key is not NULL
    order by 1 asc, 2 asc, 3 asc;
 
getPolled_AL BOOLEAN := FALSE;
getPolled_BP BOOLEAN := FALSE;
 
--
RTYP_ARCHIVED_LOG         CONSTANT number := 11;
RTYP_BACKUP_PIECE         CONSTANT number := 13;
RTYP_DFILE_COPY           CONSTANT number := 16;
 
CURSOR feedback_al(bp_key_poll NUMBER) IS
   SELECT al_recid recid, al_stamp stamp, fname
     FROM al, (SELECT distinct dbinc_key, thread#, sequence# 
                  FROM brl
                  WHERE bs_key IN 
                     (SELECT bs_key FROM bp 
                         WHERE db_key = this_db_key
                           AND bp_key > bp_key_poll 
                           AND purged = 'N'
                           AND device_type = 'SBT_TAPE' 
                           AND ba_access IN ('L', 'T')
                           AND site_key IN
                              (SELECT site_key FROM node WHERE
                                  db_unique_name like '$%' AND 
                                  db_key=this_db_key))) bal 
     WHERE al.site_key = this_site_key
       AND al.is_recovery_dest_file = 'YES'
       AND bal.dbinc_key=al.dbinc_key 
       AND bal.thread# = al.thread# 
       AND bal.sequence# = al.sequence#;
 
CURSOR feedback_bp(bp_key_poll NUMBER) IS
--
--
   SELECT bs_key, piece#, device_type, site_key,
          bp_recid recid, bp_stamp stamp, ba_access, handle
     FROM bp
     WHERE db_key = this_db_key
       AND ((site_key=this_site_key AND
             is_recovery_dest_file = 'YES') OR
            (device_type = 'SBT_TAPE' and ba_access in ('L', 'T', 'D')))
       AND bs_key in (SELECT bs_key FROM bp 
                         WHERE db_key = this_db_key
                           AND bp_key > bp_key_poll 
                           AND purged = 'N'
                           AND device_type = 'SBT_TAPE' 
                           AND ba_access IN ('L', 'T')
                           AND site_key IN
                              (SELECT site_key FROM node WHERE
                                  db_unique_name like '$%' AND 
                                  db_key=this_db_key))
   UNION
 
--
--
   SELECT bp.bs_key, piece#, device_type, site_key,
          bp_recid recid, bp_stamp stamp, ba_access, handle
      FROM bp,
            (SELECT distinct a.bs_key FROM bdf a,
                (SELECT bs_key, file#, create_scn, ckp_scn, dbinc_key
                    FROM bdf
                    WHERE bs_key IN 
                       (SELECT bs_key FROM bp
                           WHERE db_key = this_db_key
                             AND bp_key > bp_key_poll
                             AND purged = 'N'
                             AND device_type = 'SBT_TAPE'
                             AND ba_access IN ('L', 'T')
                             AND site_key IN
                                (SELECT site_key FROM node WHERE
                                    db_unique_name like '$%' AND
                                    db_key=this_db_key))) b
                 WHERE b.file#=a.file#
                   AND b.create_scn=a.create_scn
                   AND b.ckp_scn=a.ckp_scn
                   AND b.dbinc_key=a.dbinc_key
                   AND b.bs_key <> a.bs_key) c
     WHERE db_key = this_db_key
       AND site_key = this_site_key
       AND bp.bs_key = c.bs_key
       AND is_recovery_dest_file = 'YES'
 
     ORDER BY bs_key, piece#, device_type, ba_access desc;
 
disk_bp_rec  feedback_bp%ROWTYPE;
curr_bp_key_poll NUMBER;
 
 
/*----------------------*
 * Cursor Row Variables *
 *----------------------*/
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
 
pdbRec          pdbQ%rowtype;
picRec          picQ%rowtype;
tsRec           tsQ%rowtype;
dfRec           dfQ%rowtype;
tfRec           tfQ%rowtype;
rtRec           rtQ%rowtype;
orlRec          orlQ%rowtype;
grspRec         grspQ%rowtype;
 
/*---------------*
 * Private Types *
 *---------------*/
 
/*-------------------*
 * Private functions *
 *-------------------*/
 
FUNCTION vtr_tname(i IN number) RETURN VARCHAR2 IS
BEGIN
  RETURN vpd_table_list(i)(1);
END;
 
FUNCTION vtr_privs(i IN number) RETURN VARCHAR2 IS
BEGIN
  RETURN NVL(vpd_table_list(i)(2), 'SELECT,UPDATE,DELETE,INSERT');
END;
 
FUNCTION vtr_policy_required(i IN number) RETURN BOOLEAN IS
BEGIN
  RETURN vpd_table_list(i)(3) = 'T';
END;
 
FUNCTION vtr_update_check(i IN number) RETURN BOOLEAN IS
BEGIN
  RETURN vpd_table_list(i)(4) = 'T';
END;
 
PROCEDURE setDebugOn(dbglevel IN NUMBER DEFAULT RCVCAT_LEVEL_DEFAULT) IS
BEGIN
--
--
--
--
   dbms_output.enable(buffer_size => null);
   debug := TRUE;
   dbglvl := dbglevel;
END;
 
PROCEDURE setDebugOff IS
BEGIN
   dumpPkgState('Debug off');
   dbms_output.disable;  -- free memory
   debug := FALSE;
END;
 
PROCEDURE deb(line IN varchar2
              ,level IN number DEFAULT RCVCAT_LEVEL_DEFAULT) IS
BEGIN
   IF debOK(level) THEN
      IF this_is_ors_admin THEN
         EXECUTE IMMEDIATE 'BEGIN sys.kbrsi_icd.rsTrace(:1); END;' USING
            'RCVCAT: ' || line;
      END IF;
      dbms_output.put_line('DBGRCVCAT: '||line);
   END IF;
EXCEPTION
   WHEN others THEN
      dbms_output.put_line('(DO_NOT_IGNORE)caught exception during deb ' ||
                           substr(sqlerrm, 1, 512));
END deb;
 
PROCEDURE deb_put(line IN varchar2
              ,level IN number DEFAULT RCVCAT_LEVEL_DEFAULT) IS
BEGIN
   if debOK(level) then
      dbms_output.put('DBGRCVCAT: '||line);
   end if;
EXCEPTION
   WHEN others THEN
      dbms_output.put_line('(DO_NOT_IGNORE)caught exception during deb ' ||
                           substr(sqlerrm, 1, 512));
END deb_put;
 
FUNCTION debOK(level IN number DEFAULT RCVCAT_LEVEL_DEFAULT) RETURN boolean IS
BEGIN
  return (debug and dbglvl >= level);
END debOK;
 
PROCEDURE init_package_vars(p_server_key NUMBER DEFAULT NULL) IS
  proxy   varchar2(512);
  got_srvr_info  boolean := TRUE;
  no_ds_err         EXCEPTION;
  PRAGMA EXCEPTION_INIT(no_ds_err, -1034); -- Oracle not available
BEGIN
  BEGIN
    IF p_server_key IS NOT NULL THEN 
      SELECT * INTO this_server 
        FROM server 
        WHERE filter_user=user
          AND server_key = p_server_key;
    ELSE 
      SELECT * INTO this_server FROM server where filter_user=user;
    END IF;
         
--
--
    IF (INSTR(this_server.server_host, 'amazonaws.com') <> 0) THEN
      this_amazon_server := TRUE;
      this_server_url    := this_server.server_host;
      if (this_server.server_port is not null) then
         this_server_url := this_server_url || ':' || this_server.server_port;
      end if;
      this_server_uname  := NULL;
      this_server_passw  := NULL;
    ELSE
      this_amazon_server := FALSE;
      IF p_server_key IS NOT NULL THEN 
         BEGIN
           execute immediate 'begin dbms_rai_wallet2url(
                                wallet_loc   => :wallet_path,
                                cred_alias   => :wallet_alias,
                                username     => :username,
                                password     => :password,
                                url          => :url,
                                client       => ''REPLICATION''); end;'
                  using in this_server.wallet_path, in this_server.wallet_alias,
                        out this_server_uname, out this_server_passw,
                        out this_server_url;
         EXCEPTION
            WHEN no_ds_err THEN
               got_srvr_info := FALSE;
               deb('INIT_PKG_VARS:  Unable to communicate with downstream '||
                   'replication server');
         END;
      END IF;
    END IF;
    if got_srvr_info then
       if this_server.proxy_url is not null then
          proxy := this_server.proxy_url;
          if (this_server.proxy_port is not null) then
             proxy := proxy || ':' || this_server.proxy_port;
          end if;
          utl_http.set_proxy(proxy, null /* noproxy */);
       end if;
       utl_http.set_response_error_check(TRUE);
       utl_http.set_detailed_excp_support(TRUE);
       utl_http.set_wallet(path     => this_server.wallet_path,
                           password => null);
    end if;
  EXCEPTION
    WHEN NO_DATA_FOUND THEN
      deb('init_package_vars(no_data_found): ignore it');
    WHEN TOO_MANY_ROWS THEN
      deb('init_package_vars(too_many_rows): ignore it');
    WHEN OTHERS THEN
      deb('init_package_vars(fail): p_server_key=' || p_server_key ||
          ',error='|| sqlerrm);
      RAISE;
  END;
END init_package_vars;
 
--
--
PROCEDURE checkResync IS
BEGIN
 
  IF (this_ckp_key IS NULL) THEN
    raise_application_error(-20031, 'Resync not started');
  END IF;
  IF (this_db_key IS NULL) THEN
    raise_application_error(-20021, 'Database not set');
  END IF;
  IF (this_dbinc_key IS NULL) THEN
    raise_application_error(-20020, 'Database incarnation not set');
  END IF;
  IF (this_site_key IS NULL) THEN
    raise_application_error(-20199, 'Database site key not set');
  END IF;
 
END checkResync;
 
--
function date2stamp(dt IN date) return number is
  stamp number;
begin
  stamp := (((((to_number(to_char(dt, 'YYYY'))-1988)*12
         +     (to_number(to_char(dt, 'MM'))-1))*31
         +     (to_number(to_char(dt, 'DD'))-1))*24
         +     (to_number(to_char(dt, 'HH24'))))*60
         +     (to_number(to_char(dt, 'MI'))))*60
         +     (to_number(to_char(dt, 'SS')));
  return stamp;
end;
 
--
function stamp2date(stamp IN number) return date IS
x number;
dt varchar2(19);
begin
   if stamp is null then
       return null;
   end if;
 
   x := stamp;
 
   dt := to_char(mod(x,60), 'FM09'); -- seconds
   x := floor(x/60);
 
   dt := to_char(mod(x,60), 'FM09') || ':' || dt; -- minutes
   x := floor(x/60);
 
   dt := to_char(mod(x,24), 'FM09') || ':' || dt; -- hours
   x := floor(x/24);
 
   dt := to_char(mod(x,31)+1, 'FM09') || ' ' || dt; -- days
   x := floor(x/31);
 
   dt := to_char(mod(x,12)+1, 'FM09') || '/' || dt; -- months
 
   dt := to_char(floor(x/12)+1988)   || '/' || dt;
 
   return to_date(dt, 'YYYY/MM/DD HH24:MI:SS');
end;
 
--
FUNCTION maskConnectString(value IN VARCHAR2)
RETURN VARCHAR2 IS
   lpos  PLS_INTEGER;
BEGIN
   lpos := instr(value, 'CONNECT');
   IF lpos > 0
   THEN
      RETURN substr(value, 1, lpos - 1) || 'CONNECT *******';
   ELSE
      RETURN value;
   END IF;
END maskConnectString;
 
--
PROCEDURE recomputeDbincStatus(db_key IN NUMBER,
                               dbinc_key IN NUMBER) IS
--
 PROCEDURE updateDbincStatus(db_key IN NUMBER, dbinc_key IN NUMBER) IS
 parent_key NUMBER;
 BEGIN
  BEGIN
   deb('updateDbincStatus - for db_key='||db_key||' dbinc='||dbinc_key);
   update dbinc set dbinc_status='PARENT'
      where dbinc_key =  updateDbincStatus.dbinc_key and
            db_key = updateDbincStatus.db_key;
 
--
   select parent_dbinc_key into parent_key from dbinc
      where dbinc_key= updateDbincStatus.dbinc_key and
            db_key = updateDbincStatus.db_key;
 
   updateDbincStatus(db_key, parent_key);
   deb('updateDbincStatus - normal return for dbinc=' || dbinc_key);
 
  EXCEPTION
    WHEN no_data_found THEN
       deb('updateDbincStatus- Last parent is  ' || dbinc_key);
       IF (dbinc_key is NOT NULL) THEN -- set last incarnation in the chain
           update dbinc set dbinc_status='PARENT'
              where dbinc_key=updateDbincStatus.dbinc_key and
                    db_key = updateDbincStatus.db_key;
       END IF;
       return;  -- reached the last known parent
    WHEN OTHERS THEN
       deb('updateDbincStatus - rollback all, release locks');
       rollback;
       RAISE;
  END;
 END updateDbincStatus;
BEGIN
 
--
  UPDATE db SET curr_dbinc_key = recomputeDbincStatus.dbinc_key
    WHERE db_key = recomputeDbincStatus.db_key;
 
  UPDATE dbinc SET dbinc_status='ORPHAN'
     WHERE dbinc.db_key = recomputeDbincStatus.db_key;
  updateDbincStatus(db_key, dbinc_key);
  UPDATE dbinc SET dbinc_status='CURRENT'
    where dbinc_key=recomputeDbincStatus.dbinc_key and
          db_key = recomputeDbincStatus.db_key;
END recomputeDbincStatus;
 
--
--
FUNCTION isOrsMedia(media IN VARCHAR2) RETURN BOOLEAN IS
BEGIN
   IF (media LIKE '%Recovery Appliance%') THEN
      RETURN TRUE;
   ELSE
      RETURN FALSE;
   END IF;
END isOrsMedia;
 
--
PROCEDURE initOrsAdmin IS
BEGIN
   EXECUTE IMMEDIATE 'begin :owner := dbms_rai_owner; end;'
      USING OUT orsadmin_user;
EXCEPTION
   WHEN OTHERS THEN
      deb('initOrsAdmin(DO_NOT_IGNORE):' || substr(sqlerrm, 1, 132));
END initOrsAdmin;
 
--
PROCEDURE inheritPdbInc(
   db_key           IN NUMBER
  ,dbinc_key        IN NUMBER
  ,reset_scn        IN NUMBER
  ,parent_dbinc_key IN NUMBER) IS
BEGIN
   deb('inheritPdbInc - dbinc_key=' || dbinc_key ||
       ' parent_dbinc_key=' || parent_dbinc_key);
 
--
   FOR r IN (SELECT pdb.pdb_key, pdbinc.pdbinc_key
               FROM pdbinc, pdb
              WHERE pdb.pdb_key = pdbinc.pdb_key
                AND pdb.db_key  = inheritPdbInc.db_key
                AND pdb.con_id in (0, 1))
   LOOP
      deb('inheritPdbInc root');
      INSERT INTO pdb_dbinc
         (dbinc_key, pdb_key, drop_scn, drop_time, curr_pdbinc_key)
      VALUES
         (inheritPdbInc.dbinc_key, r.pdb_key, NULL, NULL, r.pdbinc_key);
   END LOOP;
 
   IF (parent_dbinc_key IS NULL) THEN
      RETURN;
   END IF;
 
--
   FOR r IN (SELECT pdb.pdb_key, pdb_dbinc.curr_pdbinc_key
               FROM pdb_dbinc, pdb
              WHERE pdb_dbinc.dbinc_key = inheritPdbInc.parent_dbinc_key
                AND pdb.pdb_key = pdb_dbinc.pdb_key
                AND pdb.create_scn < inheritPdbInc.reset_scn
                AND (pdb_dbinc.drop_scn IS NULL OR
                     pdb_dbinc.drop_scn > inheritPdbInc.reset_scn)
                AND pdb.con_id > 1)
   LOOP
      deb('inheritPdbInc - pdb_key=' || r.pdb_key ||
          ' curr_pdbinc_key=' || r.curr_pdbinc_key);
 
      INSERT INTO pdb_dbinc
         (dbinc_key, pdb_key, drop_scn, drop_time, curr_pdbinc_key)
      VALUES
         (inheritPdbInc.dbinc_key, r.pdb_key, NULL, NULL, r.curr_pdbinc_key);
   END LOOP;
END inheritPdbInc;
 
--
PROCEDURE recomputePluggableDbincStatus(dbinc_key IN NUMBER) IS
   CURSOR pdbincQ(dbinc_key NUMBER) IS
      SELECT curr_pdbinc_key, pdb_key
        FROM pdb_dbinc
       WHERE dbinc_key = pdbincQ.dbinc_key;
 
--
   PROCEDURE updatePluggableDbincStatus(pdbinc_key IN NUMBER) IS
      parent_key NUMBER;
   BEGIN
      UPDATE pdbinc SET pdbinc_status='PARENT'
       WHERE pdbinc_key = updatePluggableDbincStatus.pdbinc_key;
 
--
      SELECT parent_pdbinc_key INTO parent_key FROM pdbinc
       WHERE pdbinc_key= updatePluggableDbincStatus.pdbinc_key;
 
      updatePluggableDbincStatus(parent_key);
   EXCEPTION
      WHEN no_data_found THEN
         RETURN; -- reached the last known parent
   END updatePluggableDbincStatus;
BEGIN
   deb('recomputePluggableDbincStatus for dbinc_key ' || dbinc_key);
   FOR pdbincQrec in pdbincQ(recomputePluggableDbincStatus.dbinc_key) LOOP
--
      UPDATE pdbinc SET pdbinc_status = 'ORPHAN'
       WHERE pdbinc.pdb_key = pdbincQrec.pdb_key;
 
--
      updatePluggableDbincStatus(pdbincQrec.curr_pdbinc_key);
 
      UPDATE pdbinc SET pdbinc_status='CURRENT'
       WHERE pdbinc.pdbinc_key = pdbincQrec.curr_pdbinc_key;
   END LOOP;
END recomputePluggableDbincStatus;
 
FUNCTION getPdbInc(
   birth_scn      IN NUMBER
  ,con_id         IN NUMBER
  ,out_pdb_key   OUT NUMBER
) RETURN NUMBER IS
   local_pdbinc_key   NUMBER;
BEGIN
   IF (last_full_ckp_scn IS NULL) THEN
      deb('getPdbInc - full resync for first time');
      SELECT pdbinc_key, pdb_key
        INTO local_pdbinc_key, out_pdb_key
        FROM rci_pdbinc_this_dbinc pdbinc
       WHERE pdbinc.dbinc_key = this_dbinc_key
         AND pdbinc.drop_scn IS NULL
         AND pdbinc.con_id = getPdbInc.con_id
         AND pdbinc.pdbinc_status = 'CURRENT';
   ELSE
      deb('getPdbInc - last_full_ckp_scn ' || last_full_ckp_scn ||
                     ' birth_scn ' || birth_scn);
      FOR r IN (SELECT pdbinc.pdbinc_key, pdbinc.pdb_key, pdbinc.inc_scn,
                       pdbinc.next_inc_scn
                  FROM rci_pdbinc_this_dbinc pdbinc
                 WHERE pdbinc.dbinc_key = this_dbinc_key
                   AND pdbinc.drop_scn IS NULL
                   AND pdbinc.con_id  = getPdbInc.con_id
                   AND pdbinc.next_inc_scn > last_full_ckp_scn
                 ORDER BY pdbinc.inc_scn)
      LOOP
--
         IF (birth_scn >= r.inc_scn      AND
             birth_scn <= r.next_inc_scn AND
             birth_scn >= last_full_ckp_scn) THEN
            local_pdbinc_key := r.pdbinc_key;
            out_pdb_key      := r.pdb_key;
            EXIT;
         END IF;
 
         local_pdbinc_key := r.pdbinc_key;
         out_pdb_key      := r.pdb_key;
      END LOOP;
   END IF;
 
   IF (local_pdbinc_key IS NULL) THEN
      raise_application_error(-20999, 'getPdbInc - pdbinc not known');
   ELSE
      deb('getPdbInc - pdbinc ' || local_pdbinc_key);
   END IF;
   RETURN local_pdbinc_key;
END getPdbInc;
 
/* convert guid to pdb key */
FUNCTION guidToPdbKey(guid IN RAW, dropped_pdb IN binary_integer)
RETURN NUMBER IS
   l_pdb_key NUMBER;
BEGIN
   IF (guid IS NULL OR guid = ZERO_GUID) THEN
      SELECT pdb_key INTO l_pdb_key
        FROM pdb
       WHERE pdb.db_key = this_db_key
         AND pdb.con_id IN (1, 0);
   ELSE
      SELECT max(pdb_key) INTO l_pdb_key
        FROM pdb
       WHERE pdb.db_key = this_db_key
         AND pdb.guid   = guidToPdbKey.guid;
   END IF;
 
--
--
--
--
--
   IF (l_pdb_key IS NULL) THEN
      IF (dropped_pdb > 0) THEN
         SELECT pdb_key INTO l_pdb_key
           FROM pdb
          WHERE pdb.db_key = this_db_key
            AND pdb.con_id IN (1, 0);
      ELSE
         RAISE no_data_found;
      END IF;
   END IF;
 
   RETURN l_pdb_key;
EXCEPTION
   WHEN OTHERS THEN
      deb('guidToPdbKey translation failed for ' || guid);
      RAISE;
END guidToPdbKey;
 
/*-------------------*
 * Register Database *
 *-------------------*/
PROCEDURE registerDatabase(db_id          IN NUMBER
                          ,db_name        IN VARCHAR2
                          ,reset_scn      IN NUMBER
                          ,reset_time     IN DATE
                          ,db_unique_name IN VARCHAR2 default null
                          ,con_id         IN NUMBER   default 0
                          ,guid           IN RAW      default null
                          ) IS
 
  loc_dbinc_key number;
  loc_db_key    number;
  loc_pdb_key   number;
  p_dbun        node.db_unique_name%TYPE := upper(db_unique_name);
 
BEGIN
--
  BEGIN
    SELECT NULL INTO loc_dbinc_key
      FROM rcver
     WHERE version LIKE catalogVersion || '.%';
  EXCEPTION
    WHEN no_data_found THEN
      raise_application_error(-20298, 'Not compatible recovery catalog');
  END;
 
  IF (this_ckp_key IS NOT NULL) THEN
    raise_application_error(-20030 , 'Resync in progress');
  END IF;
 
  this_db_key := NULL;
  this_dbinc_key := NULL;
 
--
--
  IF p_dbun is NULL and registerDbPending.dbid is null THEN
     registerDbPending.dbid   := db_id;
     registerDbPending.con_id := con_id;
     registerDbPending.guid   := guid;
     deb('registerDatabase pushed to setDatabase stage for dbid = ' || db_id);
     RETURN;
  END IF;
 
  BEGIN
    INSERT INTO db(db_key, db_id, reg_db_unique_name) 
      VALUES(rman_seq.nextval, db_id, p_dbun)
    RETURNING db_key INTO loc_db_key;
  EXCEPTION
    WHEN dup_val_on_index THEN
      raise_application_error(-20002, 'Database already registered');
  END;
 
  INSERT INTO dbinc
    (dbinc_key, db_key, db_name, reset_scn, reset_time)
  VALUES
    (rman_seq.nextval, loc_db_key, upper(db_name), reset_scn, reset_time)
  RETURNING dbinc_key INTO loc_dbinc_key;
 
--
  recomputeDbincStatus(loc_db_key, loc_dbinc_key);
 
  deb('registerDatabase - ' ||
      'adding node row, db_unique_name value=' || p_dbun);
  INSERT INTO node(db_key, force_resync2cf, database_role, site_key,
                   db_unique_name)
     VALUES(loc_db_key, 'NO', 'PRIMARY', rman_seq.nextval,
            p_dbun);
 
  deb('registerDatabase - adding a row to pdb for rootdb, con_id=' ||
       con_id || ' guid=' || nvl(guid, ZERO_GUID));
  IF (con_id IS NULL OR con_id NOT IN (0, 1)) THEN
     raise_application_error(-20999, 
        'internal error: only con_id 0 or 1 can register database');
  END IF;
 
  INSERT INTO pdb
     (pdb_key, db_key, name, con_id, db_id, create_scn, guid)
  VALUES
     (rman_seq.nextval, loc_db_key, NULL, con_id, db_id, 1,
      nvl(guid, ZERO_GUID))
  RETURNING pdb_key INTO loc_pdb_key;
 
  INSERT INTO pdbinc
     (pdbinc_key, pdb_key, born_dbinc_key, inc_scn,
      begin_reset_scn, begin_reset_time, end_reset_scn,
      parent_pdbinc_key,  pdbinc_status)
  VALUES
     (rman_seq.nextval, loc_pdb_key, loc_dbinc_key, 1,
      reset_scn, reset_time, 1,
      NULL, 'CURRENT');
 
  INSERT INTO pdb_dbinc
     (dbinc_key, pdb_key, drop_scn, drop_time, curr_pdbinc_key)
  VALUES
     (loc_dbinc_key, loc_pdb_key, NULL, NULL, rman_seq.currval);
 
  setReason(RESYNC_REASON_NOACTION);
  commitChanges('registerDatabase');
 
--
  registerDbPending.dbid := null;
 
--
EXCEPTION
  WHEN OTHERS THEN
    deb('registerDatabase - rollback, release locks');
    rollback;
--
    registerDbPending.dbid := null;
    RAISE;
 
END registerDatabase;
 
--
--
 
PROCEDURE resetDatabase(db_id             IN NUMBER
                       ,db_name           IN VARCHAR2
                       ,reset_scn         IN NUMBER
                       ,reset_time        IN DATE
                       ,parent_reset_scn  IN NUMBER
                       ,parent_reset_time IN DATE
                       ) IS
 
local          dbinc%rowtype;                    -- local variables
BEGIN
--
  BEGIN
    SELECT NULL INTO local.db_key
      FROM rcver
     WHERE version LIKE catalogVersion || '.%';
  EXCEPTION
    WHEN no_data_found THEN
      raise_application_error(-20298, 'Not compatible with recovery catalog');
  END;
 
  IF (this_ckp_key IS NOT NULL) THEN
    raise_application_error(-20030, 'Resync in progress');
  END IF;
  IF (db_id IS NULL) THEN
    raise_application_error(-20007, 'db_id is null');
  END IF;
 
  this_db_key := NULL;
  this_dbinc_key := NULL;
 
  BEGIN
    SELECT db_key, curr_dbinc_key INTO local.db_key, local.dbinc_key
    FROM db
    WHERE db.db_id = resetDatabase.db_id               -- should return 1 row
    FOR UPDATE OF db.db_key;
  EXCEPTION
    WHEN no_data_found THEN
      raise_application_error(-20001, 'Database not found');
  END;
 
--
  BEGIN
    SELECT dbinc_key INTO local.parent_dbinc_key
    FROM dbinc
    WHERE dbinc.db_key = local.db_key
    AND   dbinc.reset_scn = resetDatabase.parent_reset_scn
    AND   dbinc.reset_time = resetDatabase.parent_reset_time;
  EXCEPTION
    WHEN no_data_found THEN
      local.parent_dbinc_key := NULL;
  END;
 
--
  BEGIN
    INSERT INTO dbinc
      (dbinc_key, db_key, db_name, reset_scn, reset_time, parent_dbinc_key)
    VALUES
      (rman_seq.nextval, local.db_key, upper(db_name), reset_scn,
       reset_time, local.parent_dbinc_key)
    RETURNING dbinc_key INTO local.dbinc_key;
  EXCEPTION
    WHEN dup_val_on_index THEN
      raise_application_error(-20009, 'Db incarnation already registered');
  END;
 
  inheritPdbInc(
     local.db_key, local.dbinc_key, reset_scn, local.parent_dbinc_key);
 
--
  recomputeDbincStatus(local.db_key, local.dbinc_key);
  recomputePluggableDbincStatus(local.dbinc_key);
  commitChanges('resetDatabase');
 
--
EXCEPTION
  WHEN OTHERS THEN
    deb('resetDatabase - rollback, release locks');
    rollback;
    RAISE;
 
END resetDatabase;
 
--
FUNCTION resetDatabase(db_id             IN NUMBER
                      ,db_name           IN VARCHAR2
                      ,reset_scn         IN NUMBER
                      ,reset_time        IN DATE
                      ,parent_reset_scn  IN NUMBER
                      ,parent_reset_time IN DATE
                       ) RETURN NUMBER IS
local    dbinc%rowtype;                    -- local variables
BEGIN
--
  BEGIN
    SELECT NULL INTO local.db_key
     FROM rcver
     WHERE version LIKE catalogVersion || '.%';
  EXCEPTION
    WHEN no_data_found THEN
      raise_application_error(-20298, 'Not compatible with recovery catalog');
  END;
 
  IF (this_ckp_key IS NOT NULL) THEN
    raise_application_error(-20030, 'Resync in progress');
  END IF;
  IF (db_id IS NULL) THEN
    raise_application_error(-20007, 'db_id is null');
  END IF;
 
  BEGIN
    SELECT db_key INTO local.db_key
      FROM db
     WHERE db.db_id = resetDatabase.db_id;              -- should return 1 row
  EXCEPTION
    WHEN no_data_found THEN
      raise_application_error(-20001, 'Database not found');
  END;
 
  SELECT dbinc_key INTO local.dbinc_key
    FROM dbinc
   WHERE dbinc.db_key = local.db_key
     AND dbinc.reset_scn = resetDatabase.reset_scn
     AND dbinc.reset_time = resetDatabase.reset_time;
 
  resetDatabase(local.dbinc_key, db_name);
 
  RETURN local.dbinc_key;
END resetDatabase;
 
--
 
PROCEDURE resetDatabase(
  dbinc_key  IN NUMBER
 ,db_name    IN VARCHAR2
) IS
 
local     dbinc%rowtype;                    -- local variables
BEGIN
--
  BEGIN
    SELECT NULL INTO local.db_key
      FROM rcver
     WHERE version LIKE catalogVersion || '.%';
  EXCEPTION
    WHEN no_data_found THEN
      raise_application_error(-20298, 'Not compatible with recovery catalog');
  END;
 
  IF (this_ckp_key IS NOT NULL) THEN
    raise_application_error(-20030, 'Resync in progress');
  END IF;
  IF (dbinc_key IS NULL) THEN
    raise_application_error(-20008, 'Database incarnation key is missing');
  END IF;
 
  this_db_key := NULL;
  this_dbinc_key := NULL;
 
  BEGIN
    SELECT db_key, db_name
    INTO local.db_key, local.db_name
    FROM dbinc
    WHERE dbinc.dbinc_key = resetDatabase.dbinc_key;
  EXCEPTION
    WHEN no_data_found THEN
      raise_application_error(-20010, 'Database incarnation not found');
  END;
 
--
  IF (upper(db_name) <> local.db_name) THEN
     IF (db_name != 'UNKNOWN') THEN
        UPDATE dbinc
           SET db_name = upper(resetDatabase.db_name)
         WHERE dbinc.dbinc_key = resetDatabase.dbinc_key;
     ELSE
        raise_application_error(-20004, 'Database name does not match');
     END IF;
  END IF;
 
--
  recomputeDbincStatus(local.db_key, resetDatabase.dbinc_key);
  recomputePluggableDbincStatus(resetDatabase.dbinc_key);
 
  commitChanges('resetDatabase');
 
--
EXCEPTION
  WHEN OTHERS THEN
    deb('resetDatabase - rollback, release locks');
    rollback;
    RAISE;
END resetDatabase;
 
procedure resetDatabase(
  dbinc_key  IN  number
 ,db_name    IN  varchar2
 ,reset_scn  OUT number
 ,reset_time OUT date
 ,db_id      IN  number DEFAULT NULL
) IS
  local_db_key dbinc.db_key%TYPE;
BEGIN
  IF db_id IS NOT NULL THEN
     BEGIN
       SELECT db_key INTO local_db_key
         FROM db
        WHERE db.db_id = resetDatabase.db_id;           -- should return 1 row
     EXCEPTION
       WHEN no_data_found THEN
         raise_application_error(-20001, 'Database not found');
     END;
  ELSE
     local_db_key := this_db_key;
  END IF;
 
  BEGIN
    SELECT reset_scn, reset_time
    INTO resetDatabase.reset_scn, resetDatabase.reset_time
    FROM dbinc
    WHERE dbinc.dbinc_key = resetDatabase.dbinc_key AND
          (db_id IS NULL OR dbinc.db_key = local_db_key);
 
  EXCEPTION
    WHEN no_data_found THEN
      raise_application_error(-20010, 'Database incarnation not found');
  END;
 
  resetDatabase(dbinc_key, db_name);
END resetDatabase;
 
PROCEDURE unRegisterDatabase(
  db_key     IN NUMBER DEFAULT NULL
 ,db_id      IN NUMBER
) IS
 
tmp         NUMBER;
cnt         NUMBER := 0;
 
BEGIN
  IF (this_ckp_key IS NOT NULL) THEN
    raise_application_error(-20030, 'Resync in progress');
  END IF;
 
--
  BEGIN
    SELECT 0 INTO tmp FROM db
    WHERE db.db_id = unRegisterDatabase.db_id;
  EXCEPTION
  WHEN no_data_found THEN
    raise_application_error(-20001, 'Database not found');
  END;
 
--
--
  SELECT count(*) INTO cnt FROM db
   WHERE storage_prov = 'Y'
     AND db.db_id = unRegisterDatabase.db_id;
 
  IF (cnt <> 0) THEN
    raise_application_error(-20301, 'Cannot unregister database');
  END IF;
 
--
--
  SELECT 0 INTO tmp FROM db
    WHERE db.db_id = unRegisterDatabase.db_id FOR UPDATE OF db.db_key;
 
  DELETE FROM bp 
    WHERE db_key = 
      (select db_key from db where db.db_id = unRegisterDatabase.db_id);
   
  DELETE FROM db WHERE db.db_id = unRegisterDatabase.db_id;
  commitChanges('unRegisterDatabase');
 
--
EXCEPTION
  WHEN OTHERS THEN
    deb('unregisterDatabase - rollback, release locks');
    rollback;
    RAISE;
 
END unRegisterDatabase;
 
--
PROCEDURE setArchiveFileScopeAttributes(logs_shared  IN NUMBER) IS
BEGIN
   deb('setArchiveFileScopeAttributes');
 
   IF logs_shared > 0 THEN
      dbms_rcvcat.logs_shared := TRUE#;
   ELSE
      dbms_rcvcat.logs_shared := FALSE#;
   END IF;
   deb('logs_shared = ' || dbms_rcvcat.logs_shared);
 
   dbms_rcvman.setArchiveFileScopeAttributes(logs_shared);
 
   deb('exiting setArchiveFileScopeAttributes');
END setArchiveFileScopeAttributes;
 
--
PROCEDURE setBackupFileScopeAttributes(
                 disk_backups_shared IN NUMBER,
                 tape_backups_shared IN NUMBER) IS
   lsite_key NUMBER;
BEGIN
   deb('setBackupFileScopeAttributes');
 
   IF disk_backups_shared IS NOT NULL THEN
      IF disk_backups_shared > 0 THEN
         dbms_rcvcat.disk_backups_shared := TRUE#;
      ELSE
         dbms_rcvcat.disk_backups_shared := FALSE#;
      END IF;
   END IF;
 
   IF tape_backups_shared IS NOT NULL THEN
      IF tape_backups_shared > 0 THEN
         dbms_rcvcat.tape_backups_shared := TRUE#;
      ELSE
         dbms_rcvcat.tape_backups_shared := FALSE#;
      END IF;
   END IF;
 
   deb('disk_backups_shared='||dbms_rcvcat.disk_backups_shared);
   deb('tape_backups_shared='||dbms_rcvcat.tape_backups_shared);
 
   dbms_rcvman.setBackupFileScopeAttributes(disk_backups_shared,
                                            tape_backups_shared);
 
   deb('exiting setBackupFileScopeAttributes');
END setBackupFileScopeAttributes;
 
/*--------------*
 * Set Database *
 *--------------*/
 
--
 
PROCEDURE setDatabase(db_name        IN VARCHAR2
                     ,reset_scn      IN NUMBER
                     ,reset_time     IN DATE
                     ,db_id          IN NUMBER
                     ,db_unique_name IN VARCHAR2
                     ,dummy_instance IN BOOLEAN
                     ,cf_type        IN NUMBER
                     ,site_aware     IN BOOLEAN default FALSE
                     ,ors_instance   IN BOOLEAN default FALSE) IS
 
   local             dbinc%rowtype;                    -- local variables
   current_inc       VARCHAR2(3);
   dbnm              dbinc.db_name%TYPE;
   dbnm_in           dbinc.db_name%TYPE;
   rid               varchar2(18);
   local_site_key    number;
   dbunqnm           node.db_unique_name%TYPE;
   db_role           node.database_role%type;
   dbunqnm_in        node.db_unique_name%TYPE;
   l_reg_dbunqnm     node.db_unique_name%TYPE;
   cat_version       varchar2(12);
   vpd_version       varchar2(12);
   prim_dbunqnm_in   node.db_unique_name%TYPE;
   db_id_in          number;
   tmp_dbunqnm_cnt   number;
   tmp_primary_cnt   number;
   cf_type_in        number;
   my_dbunqnm        watermarks.db_unique_name%TYPE;
BEGIN
--
  BEGIN
    SELECT NULL INTO local.db_key
      FROM rcver
     WHERE version LIKE catalogVersion || '.%';
  EXCEPTION
    WHEN no_data_found THEN
      raise_application_error(-20298, 'Not compatible with recovery catalog');
  END;
 
  IF (this_ckp_key IS NOT NULL) THEN
    raise_application_error(-20030, 'Resync in progress');
  END IF;
 
  this_db_key := NULL;                  -- clear in case exception raised
  this_dbinc_key := NULL;
  kccdivts := NULL;
  dbnm_in := upper(db_name);
  dbunqnm_in := upper(db_unique_name);
  db_id_in := db_id;
  cf_type_in := cf_type;
 
--
--
  IF registerDbPending.dbid = db_id AND NOT ors_instance THEN
     registerDatabase(db_id          => db_id,
                      db_name        => dbnm_in,
                      reset_scn      => reset_scn,
                      reset_time     => reset_time,
                      db_unique_name => dbunqnm_in,
                      con_id         => registerDbPending.con_id,
                      guid           => registerDbPending.guid);
  END IF;  
 
  deb('setDatabase(db_unique_name)='||db_unique_name);
 
--
  IF ors_instance THEN
    IF db_unique_name IS NULL OR substr(db_unique_name, 1, 1) = '$' THEN
      raise_application_error(-20999, 
         'internal error: db_unique_name value is invalid=' || db_unique_name);
    END IF;
    IF db_id IS NULL THEN
      raise_application_error(-20999, 
         'internal error: db_id must be specified for ORS instance');
    END IF;
    cf_type_in := CF_STANDBY;
 
--
--
--
    IF instr(dbunqnm_in, '$'|| db_id) = 0 THEN
       dbunqnm_in := dbunqnm_in || '$' || db_id;
    END IF;
    dbunqnm_in := '$' || dbunqnm_in;
  END IF;
 
<<now_try_with_dbid>>
 
--
--
--
--
 
  IF (db_id_in IS NOT NULL) THEN
    BEGIN
      SELECT db_key, curr_dbinc_key, db_name, reg_db_unique_name
        INTO local.db_key, local.dbinc_key, local.db_name, l_reg_dbunqnm
      FROM db
      WHERE db.db_id = db_id_in;                        -- should return 1 row
    EXCEPTION
      WHEN no_data_found THEN
        raise_application_error(-20001, 'Database not found');
    END;
 
--
    IF (dbnm_in is NOT NULL AND db_id is NOT NULL) THEN
--
--
--
--
 
       BEGIN
         SELECT decode(dbinc.dbinc_key, db.curr_dbinc_key, 'YES', 'NO'),
                dbinc.db_name, dbinc.rowid
         INTO   current_inc, dbnm, rid
         FROM db, dbinc
         WHERE db.db_key = dbinc.db_key
         AND   db.db_id = setDatabase.db_id
         AND   dbinc.reset_scn = setDatabase.reset_scn
         AND   dbinc.reset_time = setDatabase.reset_time;
       EXCEPTION
         WHEN no_data_found THEN
           raise_application_error(-20003, 'Database incarnation not found');
       END;
 
       IF (current_inc = 'NO') THEN
         raise_application_error(-20011, 'Database incarnation not current');
       END IF;
       IF (dbnm != dbnm_in) THEN
          UPDATE dbinc
             SET dbinc.db_name = dbnm_in
           WHERE rowid = rid;
          commitChanges('setDatabase');
       END IF;
    END IF;
 
    IF (NOT dummy_instance AND dbunqnm_in IS NOT NULL) THEN
       deb('setDatabase - check db_unique_name= ' || dbunqnm_in ||
           ' cf_type_in= ' || cf_type_in);
 
--
--
--
--
       IF l_reg_dbunqnm IS NULL THEN
          UPDATE db
             SET db.reg_db_unique_name = dbunqnm_in
           WHERE db.db_key = local.db_key
             AND db.db_id = setDatabase.db_id
             AND db.reg_db_unique_name IS NULL;
          deb('setDatabase: updating null db_unique_name in DB with  ' ||
              dbunqnm_in || 'number of rows updated ' || sql%rowcount);
          commitChanges('setDatabase1');
       END IF;
 
--
--
--
--
--
--
       SELECT count(*) into tmp_dbunqnm_cnt
          FROM node
          WHERE node.db_unique_name is NULL
            AND node.db_key = local.db_key;
       IF tmp_dbunqnm_cnt = 1 THEN
          SELECT count(*) into tmp_dbunqnm_cnt
             FROM node
             WHERE node.db_unique_name is not NULL
               AND node.db_key = local.db_key;
          IF tmp_dbunqnm_cnt > 0 THEN
             raise_application_error(-20999, 
                'internal error: found non-null and null site name');
          END IF;
          UPDATE NODE SET node.db_unique_name = dbunqnm_in
             WHERE node.db_unique_name is NULL
               AND node.db_key = local.db_key;
          deb('setDatabase: updating null db_unique_name with ' ||dbunqnm_in ||
              'number of rows updated ' || sql%rowcount);
       END IF;
 
       BEGIN
--
          SELECT node.database_role, site_key
            INTO db_role, local_site_key
            FROM node
           WHERE node.db_key = local.db_key
             AND node.db_unique_name = dbunqnm_in;
 
--
--
          SELECT count(*) into tmp_primary_cnt
            FROM node
           WHERE node.database_role = 'PRIMARY'
             AND site_key <> local_site_key
             AND node.db_key = local.db_key;
 
          deb('setDatabase - check database_role');
          IF (cf_type_in = CF_STANDBY AND db_role != 'STANDBY') THEN
--
             deb('setDatabase - database role not standby - updating');
             UPDATE node
                SET node.database_role = 
                       decode(substr(node.db_unique_name,1,1), '$',
                             'RA', 'STANDBY'),
                    node.high_conf_recid = 0
              WHERE site_key = local_site_key
                AND (node.database_role <>
                     decode(substr(node.db_unique_name,1,1), '$',
                            'RA', 'STANDBY'));
             commitChanges('setDatabase2');
          ELSIF ((cf_type_in = CF_CURRENT OR cf_type_in = CF_BACKUP) AND 
                 (db_role != 'PRIMARY' OR tmp_primary_cnt > 1)) THEN
--
             deb('setDatabase - not primary or primary_cnt='||tmp_primary_cnt);
--
             UPDATE node
                SET node.database_role =
                    decode(substr(node.db_unique_name,1,1), '$',
                          'RA', 'STANDBY'),
                    node.high_conf_recid = 0
              WHERE site_key <> local_site_key
                AND db_key = local.db_key;
 
--
--
--
--
             UPDATE node
                SET node.database_role = 'PRIMARY',
                    node.high_conf_recid = 0,
                    high_ic_recid = 0,  
                    high_ts_recid = NULL,
                    high_df_recid = NULL,
                    high_rt_recid = NULL,
                    high_orl_recid = NULL,
                    high_tf_recid = 0,
                    high_pdb_recid = NULL,
                    high_pic_recid = 0
              WHERE site_key = local_site_key
                AND db_key = local.db_key;
 
             sessionWaterMarks.high_ic_recid  := 0;
             sessionWaterMarks.high_pic_recid := 0;
 
             commitChanges('setDatabase3');
             prev_sessionWaterMarks := sessionWaterMarks;
          END IF;
       EXCEPTION
          WHEN no_data_found THEN
             IF (cf_type_in = CF_CURRENT OR cf_type_in = CF_BACKUP) THEN
                deb('setDatabase: adding node row, new primary database...');
--
                UPDATE node
                   SET node.database_role = 
                          decode(substr(node.db_unique_name,1,1),'$',
                                 'RA', 'STANDBY'),
                       node.high_conf_recid = 0
                   WHERE db_key = local.db_key;
                INSERT INTO node(db_unique_name, db_key, force_resync2cf,
                                 database_role, site_key)
                VALUES(dbunqnm_in, local.db_key, 'NO', 
                       'PRIMARY', rman_seq.nextval);
                commitChanges('setDatabase4');
             ELSIF cf_type_in = CF_STANDBY THEN
--
                deb('setDatabase: adding node row, new standby database...');
                BEGIN
                   INSERT INTO node(db_unique_name, db_key, force_resync2cf,
                                    database_role, 
                                    site_key)
                   VALUES(dbunqnm_in, local.db_key, 'NO', 
                          decode(substr(dbunqnm_in,1,1), '$',
                                 'RA', 'STANDBY'), 
                          rman_seq.nextval);
                   commitChanges('setDatabase5');
                EXCEPTION
                  WHEN dup_val_on_index THEN
                     deb('setDatabase - someone inserted same standby');
                END;
             ELSE
--
--
--
--
--
--
                BEGIN
                   deb('setDatabase - falking db_unique_name from'||
                       dbunqnm_in);
                   SELECT db_unique_name into prim_dbunqnm_in from node
                      WHERE db_key = local.db_key AND
                            database_role = 'PRIMARY';
                   dbunqnm_in := prim_dbunqnm_in;
                   deb('setDatabase - changing dbunqnm_in to ' || dbunqnm_in);
                EXCEPTION
                   WHEN no_data_found THEN
                      deb('setDatabase - unknown dbunqnm_in set to null');
                      dbunqnm_in := null;
                END;
             END IF;
       END;
    END IF;
--
  ELSIF (dbnm_in IS NOT NULL) THEN
 
    BEGIN
      SELECT db.db_key, db.curr_dbinc_key, db.db_id
        INTO local.db_key, local.dbinc_key, db_id_in
        FROM db, dbinc
       WHERE db.curr_dbinc_key = dbinc.dbinc_key
         AND dbinc.db_name   = dbnm_in;
    EXCEPTION
      WHEN no_data_found THEN
        raise_application_error(-20001, 'Database not found');
      WHEN too_many_rows THEN
        raise_application_error(-20005, 'Database name is ambiguous');
    END;
    GOTO now_try_with_dbid;
 
  ELSE
    raise_application_error(-20006, 'Database name is missing');
  END IF;
 
--
--
  this_db_unique_name := dbunqnm_in;
  this_db_key         := local.db_key;
  this_dbinc_key      := local.dbinc_key;
  deb('setDatabase - this_db_unique_name='||this_db_unique_name);
  deb('setDatabase - this_dbinc_key:'||to_char(this_dbinc_key));
  deb('setDatabase - this_db_key:'||to_char(this_db_key));
 
  BEGIN
    select site_key into this_site_key from node
        where db_unique_name=upper(dbunqnm_in)
          AND db_key = this_db_key;
    deb('setDatabase - this_site_key:'||this_site_key);
  EXCEPTION
    WHEN no_data_found THEN
      BEGIN
         select site_key, db_unique_name 
             into this_site_key, dbunqnm_in from node
             where database_role='PRIMARY'
               AND db_key = this_db_key;
         deb('setDatabase - this_site_key(primary):'||this_site_key);
      EXCEPTION
         WHEN no_data_found THEN
--
--
            deb('setDatabase - this_site_key is null');
            this_site_key := null;
      END;
  END;
 
  cntbs := 0;
 
--
--
  dbms_rcvman.setDatabase (dbnm_in, reset_scn, reset_time,
                           db_id, this_db_unique_name, site_aware,
                           dummy_instance, ors_instance);
 
  client_site_aware := site_aware;
 
  IF client_site_aware THEN
     setArchiveFileScopeAttributes(logs_shared => 0);
     setBackupFileScopeAttributes (disk_backups_shared => 0, 
                                   tape_backups_shared => 1);
  END IF;
 
  IF this_is_ors THEN
    BEGIN
      IF this_is_ors_admin THEN
         EXECUTE IMMEDIATE 'select rtrim(ltrim(value)) 
            from sys.v_$parameter where lower(name)=''db_unique_name'''
            into my_dbunqnm;
      ELSE
         my_dbunqnm := this_db_unique_name;
      END IF;
      INSERT INTO do_seq(db_key) VALUES (this_db_key);
      INSERT INTO watermarks(db_key, db_unique_name, rs_version_stamp)
        VALUES (this_db_key, my_dbunqnm, SYSDATE);
      commitChanges('setDatabase6 - added a row to watermarks,'||this_db_key);
    EXCEPTION
      WHEN dup_val_on_index THEN
        NULL;
    END;
  END IF;
END setDatabase;
 
--
PROCEDURE setDatabase(db_name        IN VARCHAR2
                     ,reset_scn      IN NUMBER
                     ,reset_time     IN DATE
                     ,db_id          IN NUMBER
                     ,db_unique_name IN VARCHAR2 DEFAULT NULL) IS
BEGIN
   setDatabase(db_name        => db_name,
               reset_scn      => reset_scn,
               reset_time     => reset_time,
               db_id          => db_id,
               db_unique_name => db_unique_name,
               dummy_instance => FALSE,
               cf_type        => CF_CURRENT);
END setDatabase;
 
--
--
--
--
 
PROCEDURE setDatabase(dbinc_key number) IS
  dbinc_row dbinc%ROWTYPE;
  db_row    db%ROWTYPE;
BEGIN
 
  select * into dbinc_row from dbinc where dbinc_key = setDatabase.dbinc_key;
  select * into db_row from db where db_key = dbinc_row.db_key;
  setDatabase(db_name        => dbinc_row.db_name,
              reset_scn      => dbinc_row.reset_scn,
              reset_time     => dbinc_row.reset_time,
              db_id          => db_row.db_id);
 
END setDatabase;
 
procedure setDatabase IS
  dbinckey number;
BEGIN
 
  select curr_dbinc_key into dbinckey from db;
  setDatabase(dbinckey);
 
END setDatabase;
 
 
--
--
--
--
--
--
--
--
--
PROCEDURE doReplicationReconcile(p_db_key           IN NUMBER, 
                                 p_lib_key          IN NUMBER, 
                                 p_server_key    IN NUMBER) IS
  dbinckey              NUMBER;
  dbinc_row             dbinc%ROWTYPE;
  db_row                db%ROWTYPE;
  l_dbun                VARCHAR2(512);
  l_save_this_server    SERVER%ROWTYPE;
  resync_done           NUMBER;
BEGIN
 
  deb('doReplicationReconcile: ' ||
      '( p_db_key=>' || p_db_key||
      ', p_lib_key=>' || p_lib_key||
      ', p_server_key=>' || p_server_key|| ')');
 
  select curr_dbinc_key into dbinckey from db WHERE db_key=p_db_key;
  select * into dbinc_row from dbinc where dbinc_key = dbinckey;
  select * into db_row from db where db_key = dbinc_row.db_key;
 
  execute immediate 'begin :url :=  dbms_ra_int.dbkey2name(:db_key); end;'
          using out this_url_db_unique_name, in dbinc_row.db_key;
 
  execute immediate 'select  rtrim(ltrim(value)) from sys.v_$parameter ' ||
                    'where lower(name)=''db_unique_name''' into l_dbun;
 
  deb('doReplicationReconcile: info for setDatabase ' ||
      '  db_name=>' || dbinc_row.db_name ||
      ', reset_scn=>' ||dbinc_row.reset_scn||
      ', reset_time=>' ||dbinc_row.reset_time||
      ', db_id=>' ||db_row.db_id||
      ', db_unique_name=>' ||l_dbun||
      ', this_url_db_unique_name=>' || this_url_db_unique_name);
 
--
  l_save_this_server  := this_server;
  
--
  this_lib_key := p_lib_key;
 
  init_package_vars(p_server_key);
   
  setDatabase(db_name        => dbinc_row.db_name,
              reset_scn      => dbinc_row.reset_scn,
              reset_time     => dbinc_row.reset_time,
              db_id          => db_row.db_id,
              db_unique_name => l_dbun,
              dummy_instance => FALSE,
              cf_type        => CF_STANDBY,
              site_aware     => TRUE,
              ors_instance   => TRUE);
  
--
  this_verrec := null;
  this_curr_inc := null;
  this_wmrec := null;
  this_v_wmrec := null;
  deb('clearing all variables used for reconcile');
  select nvl(count(*), 0) into resync_done 
     from ts where dbinc_key = this_dbinc_key;
  IF resync_done > 0 THEN
     writeFixedSections;
     readBackupSections;
  ELSE
     deb('doReplicationReconcile: resync not done, skipping reconcile');
  END IF;
  
  this_server  := l_save_this_server;
  this_lib_key := NULL;
  this_url_db_unique_name := NULL;
  this_verrec := null;
  this_curr_inc := null;
  this_wmrec := null;
  this_v_wmrec := null;
  deb('doReplicationReconcile: resync (suc)');
  
EXCEPTION
  WHEN OTHERS THEN
    deb('doReplicationReconcile: resync (fail):' || substr(sqlerrm, 1, 512));
    this_server := l_save_this_server;
    this_url_db_unique_name := NULL;
    this_verrec := null;
    this_curr_inc := null;
    this_wmrec := null;
    this_v_wmrec := null;
    RAISE;
    
END doReplicationReconcile;
 
 
/*-----------------------------*
 * Recovery Catalog Checkpoint *
 *-----------------------------*/
 
PROCEDURE lockForCkpt(ors_inspect IN boolean DEFAULT FALSE) IS
   local_dbid     NUMBER;
   local_dbkey    NUMBER;
   start_time     DATE := sysdate;
BEGIN
  IF (this_ckp_key IS NOT NULL) THEN
    raise_application_error(-20030, 'Resync in progress');
  END IF;
  IF (this_dbinc_key IS NULL) THEN
    raise_application_error(-20020, 'Database incarnation not set');
  END IF;
 
--
--
--
--
  SELECT db_id INTO local_dbid FROM db
  WHERE db_key = this_db_key FOR UPDATE OF db.db_key;
 
--
--
  IF this_is_ors THEN
    SELECT high_bp_recid INTO this_curr_bp_recid FROM watermarks
      WHERE db_key = this_db_key FOR UPDATE OF watermarks.high_bp_recid;
    this_high_bp_recid := this_curr_bp_recid;
  END IF;
 
  this_lock_ors_inspect := ors_inspect;
  deb('lockForCkpt - took ' || ((sysdate - start_time) * 86400) || ' seconds');
  deb('lockForCkpt - Obtained all locks for db ' || to_char(this_db_key));
 
--
--
--
--
END lockForCkpt;
 
FUNCTION ckptNeeded(
  ckp_scn          IN NUMBER
 ,ckp_cf_seq       IN NUMBER
 ,cf_version       IN DATE
 ,cf_type          IN NUMBER
 ,high_df_recid    IN NUMBER
 ,high_orl_recid   IN NUMBER
 ,high_cdf_recid   IN NUMBER
 ,high_al_recid    IN NUMBER
 ,high_bp_recid    IN NUMBER
 ,high_do_recid    IN NUMBER
 ,high_offr_recid  IN NUMBER
 ,high_pc_recid    IN NUMBER  DEFAULT NULL -- for compatibility
 ,high_conf_recid  IN NUMBER  DEFAULT NULL -- for compatibility
 ,rltime           IN DATE    DEFAULT NULL -- for compatibility
 ,high_ts_recid    IN NUMBER  DEFAULT NULL -- for compatibility
 ,high_bs_recid    IN NUMBER  DEFAULT NULL -- for compatibility
 ,lopen_reset_scn  IN number  DEFAULT NULL -- for compatibility
 ,lopen_reset_time IN DATE    DEFAULT NULL -- for compatibility
 ,high_ic_recid    IN NUMBER  DEFAULT NULL -- for compatibility
 ,high_tf_recid    IN NUMBER  DEFAULT NULL -- for compatibility
 ,high_rt_recid    IN NUMBER  DEFAULT NULL -- for compatibility
 ,high_grsp_recid  IN NUMBER  DEFAULT NULL -- for compatibility
 ,high_nrsp_recid  IN NUMBER  DEFAULT NULL -- for compatibility
 ,high_bcr_recid   IN NUMBER  DEFAULT NULL -- for compatibility
 ,high_pdb_recid   IN NUMBER  DEFAULT NULL -- for compatibility
 ,high_pic_recid   IN NUMBER  DEFAULT NULL -- for compatibility
) RETURN NUMBER IS
 
ckp_type              NUMBER;
local                 node%rowtype;
local_dbid            NUMBER := 0;
local_reset_time      DATE;
local_reset_scn       NUMBER := 0;
cksum                 NUMBER;
ckp_desc              VARCHAR2(30);
BEGIN
  IF (this_ckp_key IS NOT NULL) THEN
    raise_application_error(-20030, 'Resync in progress');
  END IF;
  IF (this_dbinc_key IS NULL) THEN
    raise_application_error(-20020, 'Database incarnation not set');
  END IF;
  IF (this_site_key IS NULL) THEN
    raise_application_error(-20199, 'Site key is not set');
  END IF;
 
  SELECT db_id
  INTO local_dbid
  FROM db
  WHERE db.db_key = this_db_key FOR UPDATE OF db.db_key;
 
  deb('ckptNeeded - Obtained all locks for database ' ||
      to_char(this_db_key));
 
--
  cksum := high_df_recid           + high_orl_recid          +
           high_cdf_recid          + high_al_recid           +
           high_bp_recid           + high_do_recid           +
           high_offr_recid         + nvl(high_pc_recid, 0)   +
           nvl(high_conf_recid, 0) + nvl(high_ts_recid, 0)   +
           nvl(high_bs_recid, 0)   + nvl(high_ic_recid, 0)   +
           nvl(high_tf_recid, 0)   + nvl(high_rt_recid, 0)   +
           nvl(high_grsp_recid, 0) + nvl(high_nrsp_recid, 0) +
           nvl(high_bcr_recid, 0)  + nvl(high_pdb_recid, 0)  +
           nvl(high_pic_recid, 0);
 
--
--
--
--
--
--
  SELECT cf_create_time, nvl(high_df_recid,0), nvl(high_ts_recid,0),
         nvl(high_orl_recid,0), nvl(high_cdf_recid,0), nvl(high_al_recid,0),
         nvl(high_bp_recid,0), nvl(high_do_recid,0), nvl(high_offr_recid,0),
         nvl(high_pc_recid,0), full_ckp_cf_seq, job_ckp_cf_seq,
         nvl(high_ic_recid,0), nvl(high_bs_recid,0), nvl(high_tf_recid, 0),
         nvl(high_rt_recid, 0), nvl(high_grsp_recid, 0),
         nvl(high_nrsp_recid, 0), nvl(high_bcr_recid, 0),
         high_conf_recid, force_resync2cf, nvl(high_pdb_recid, -1),
         nvl(high_pic_recid, 0)
    INTO   local.cf_create_time, local.high_df_recid, local.high_ts_recid,
         local.high_orl_recid, local.high_cdf_recid, local.high_al_recid,
         local.high_bp_recid,  local.high_do_recid, local.high_offr_recid,
         local.high_pc_recid,  local.full_ckp_cf_seq, local.job_ckp_cf_seq,
         local.high_ic_recid, local.high_bs_recid, local.high_tf_recid,
         local.high_rt_recid, local.high_grsp_recid, local.high_nrsp_recid,
         local.high_bcr_recid, local.high_conf_recid, local.force_resync2cf,
         local.high_pdb_recid, local.high_pic_recid
    FROM node
    WHERE site_key = this_site_key;
 
  SELECT reset_scn, reset_time into local_reset_scn, local_reset_time 
    FROM dbinc
    WHERE dbinc_key = this_dbinc_key;
 
  ckp_type := RESYNC_NONE;
  setReason(RESYNC_REASON_NONE);
 
  IF (rltime IS NOT NULL AND rltime != local_reset_time) THEN
--
--
--
--
--
--
    deb('ckptNeeded - rltime='||to_char(rltime)||
         ', local_reset_time='||to_char(local_reset_time));
    ckp_type := RESYNC_NONE;
    GOTO ret;
  ELSIF (cf_version = local.cf_create_time) THEN
    deb('ckptNeeded - local_reset_scn='||local_reset_scn||
                    ' lopen_reset_scn='||lopen_reset_scn);
    deb('ckptNeeded - local_reset_time='||local_reset_time||
                    ' lopen_reset_time='||lopen_reset_time);
--
--
--
--
    IF (cf_type = CF_CURRENT AND
        (lopen_reset_scn IS NULL or local_reset_scn = lopen_reset_scn) AND
        (lopen_reset_time IS NULL or local_reset_time = lopen_reset_time)) THEN
 
      deb('ckptNeeded - high_pdb_recid='||to_char(high_pdb_recid)||
               ', local.high_pdb_recid='||to_char(local.high_pdb_recid));
      IF (high_pdb_recid > local.high_pdb_recid) THEN
        ckp_type := RESYNC_FULL;
        IF local.high_pdb_recid <= 0 THEN
           setReason(RESYNC_REASON_NOACTION);
        ELSE
           setReason(RESYNC_REASON_PDB);
        END IF;
        GOTO ret;
      ELSIF (high_pdb_recid < local.high_pdb_recid) THEN
        raise_application_error(-20035, 'Invalid high recid');
      END IF;
 
      deb('ckptNeeded - high_ts_recid='||to_char(high_ts_recid)||
               ', local.high_ts_recid='||to_char(local.high_ts_recid));
 
      IF (high_ts_recid > local.high_ts_recid) THEN
        ckp_type := RESYNC_FULL;
        IF local.high_ts_recid = 0 THEN
           setReason(RESYNC_REASON_NOACTION);
        ELSE
           setReason(RESYNC_REASON_TS);
        END IF;
        GOTO ret;
      ELSIF (high_ts_recid < local.high_ts_recid) THEN
        raise_application_error(-20035, 'Invalid high recid');
      END IF;
 
      deb('ckptNeeded - high_df_recid='||to_char(high_df_recid)||
               ', local.high_df_recid='||to_char(local.high_df_recid));
      IF (high_df_recid > local.high_df_recid) THEN
        ckp_type := RESYNC_FULL;
        setReason(RESYNC_REASON_DF);
        GOTO ret;
      ELSIF (high_df_recid < local.high_df_recid) THEN
--
--
--
--
        raise_application_error(-20035, 'Invalid high recid');
      END IF;
 
      deb('ckptNeeded - high_tf_recid='||to_char(high_tf_recid)||
               ', local.high_tf_recid='||to_char(local.high_tf_recid));
      IF (high_tf_recid > local.high_tf_recid) THEN
        ckp_type := RESYNC_FULL;
        setReason(RESYNC_REASON_TF);
        GOTO ret;
      ELSIF (high_tf_recid < local.high_tf_recid) THEN
        raise_application_error(-20035, 'Invalid high recid');
      END IF;
 
      deb('ckptNeeded - high_rt_recid='||to_char(high_rt_recid)||
               ', local.high_rt_recid='||to_char(local.high_rt_recid));
      IF (high_rt_recid > local.high_rt_recid) THEN
        ckp_type := RESYNC_FULL;
        setReason(RESYNC_REASON_THR);
        GOTO ret;
      ELSIF (high_rt_recid < local.high_rt_recid) THEN
        raise_application_error(-20035, 'Invalid high recid');
      END IF;
 
      deb('ckptNeeded - high_orl_recid='||to_char(high_orl_recid)||
               ', local.high_orl_recid='||to_char(local.high_orl_recid));
      IF (high_orl_recid > local.high_orl_recid) THEN
        ckp_type := RESYNC_FULL;
        setReason(RESYNC_REASON_ORL);
        GOTO ret;
      ELSIF (high_orl_recid < local.high_orl_recid) THEN
        raise_application_error(-20035, 'Invalid high recid');
      END IF;
--
--
--
       deb('ckptNeeded - high_conf_recid='||high_conf_recid||
                     ', local.high_conf_recid='||local.high_conf_recid);
       deb('       local.force_resync2cf='||local.force_resync2cf);
      IF (high_conf_recid != local.high_conf_recid OR
          local.force_resync2cf = 'YES')
      THEN
         ckp_type := RESYNC_FULL;
         setReason(RESYNC_REASON_CONF);
         GOTO ret;
      END IF;
 
--
--
--
 
      deb('ckptNeeded - high_cdf_recid='||to_char(high_cdf_recid)||
               ', local.high_cdf_recid='||to_char(local.high_cdf_recid));
      IF (high_cdf_recid > local.high_cdf_recid) THEN
        ckp_type := RESYNC_PARTIAL;
        GOTO ret;
      ELSIF (high_cdf_recid < local.high_cdf_recid) THEN
        raise_application_error(-20035, 'Invalid high recid');
      END IF;
      deb('ckptNeeded - high_al_recid='||to_char(high_al_recid)||
               ', local.high_al_recid='||to_char(local.high_al_recid));
      IF (high_al_recid > local.high_al_recid) THEN
        ckp_type := RESYNC_PARTIAL;
        GOTO ret;
      ELSIF (high_al_recid < local.high_al_recid) THEN
        raise_application_error(-20035, 'Invalid high recid');
      END IF;
      deb('ckptNeeded - high_bp_recid='||to_char(high_bp_recid)||
               ', local.high_bp_recid='||to_char(local.high_bp_recid));
      IF (high_bp_recid > local.high_bp_recid) THEN
        ckp_type := RESYNC_PARTIAL;
        GOTO ret;
      ELSIF (high_bp_recid < local.high_bp_recid) THEN
        raise_application_error(-20035, 'Invalid high recid');
      END IF;
      deb('ckptNeeded - high_bs_recid='||to_char(high_bs_recid)||
               ', local.high_bs_recid='||to_char(local.high_bs_recid));
      IF (high_bs_recid > local.high_bs_recid) THEN
        ckp_type := RESYNC_PARTIAL;
        GOTO ret;
      ELSIF (high_bs_recid < local.high_bs_recid) THEN
        raise_application_error(-20035, 'Invalid high recid');
      END IF;
      deb('ckptNeeded - high_do_recid='||to_char(high_do_recid)||
               ', local.high_do_recid='||to_char(local.high_do_recid));
      IF (high_do_recid > local.high_do_recid) THEN
        ckp_type := RESYNC_PARTIAL;
        GOTO ret;
      ELSIF (high_do_recid < local.high_do_recid) THEN
        raise_application_error(-20035, 'Invalid high recid');
      END IF;
      deb('ckptNeeded - high_offr_recid='||to_char(high_offr_recid)||
               ', local.high_offr_recid='||to_char(local.high_offr_recid));
      IF (high_offr_recid > local.high_offr_recid) THEN
        ckp_type := RESYNC_PARTIAL;
        GOTO ret;
      ELSIF (high_offr_recid < local.high_offr_recid) THEN
        raise_application_error(-20035, 'Invalid high recid');
      END IF;
      deb('ckptNeeded - high_pc_recid='||to_char(high_pc_recid)||
               ', local.high_pc_recid='||to_char(local.high_pc_recid));
      IF (high_pc_recid > local.high_pc_recid) THEN
        ckp_type := RESYNC_PARTIAL;
        GOTO ret;
      ELSIF (high_pc_recid < local.high_pc_recid) THEN
        raise_application_error(-20035, 'Invalid high recid');
      END IF;
      deb('ckptNeeded - high_ic_recid='||to_char(high_ic_recid)||
               ', local.high_ic_recid='||to_char(local.high_ic_recid));
      IF (high_ic_recid > local.high_ic_recid) THEN
        ckp_type := RESYNC_PARTIAL;
        GOTO ret;
      ELSIF (high_ic_recid < local.high_ic_recid) THEN
        raise_application_error(-20035, 'Invalid high recid');
      END IF;
      deb('ckptNeeded: high_grsp_recid='||to_char(high_grsp_recid)||
                    ', local.high_grsp_recid='||to_char(local.high_grsp_recid));
      IF (high_grsp_recid > local.high_grsp_recid) THEN
        ckp_type := RESYNC_PARTIAL;
        GOTO ret;
      ELSIF (high_grsp_recid < local.high_grsp_recid) THEN
        raise_application_error(-20035, 'Invalid high recid');
      END IF;
      deb('ckptNeeded: high_bcr_recid='||to_char(high_bcr_recid)||
                    ', local.high_bcr_recid='||to_char(local.high_bcr_recid));
      IF (high_bcr_recid > local.high_bcr_recid) THEN
        ckp_type := RESYNC_PARTIAL;
        GOTO ret;
      ELSIF (high_bcr_recid < local.high_bcr_recid) THEN
        raise_application_error(-20035, 'Invalid high recid');
      END IF;
      deb('ckptNeeded: high_nrsp_recid='||to_char(high_nrsp_recid)||
                    ', local.high_nrsp_recid='||to_char(local.high_nrsp_recid));
      IF (high_nrsp_recid > local.high_nrsp_recid) THEN
        ckp_type := RESYNC_PARTIAL;
        GOTO ret;
      ELSIF (high_nrsp_recid < local.high_nrsp_recid) THEN
        raise_application_error(-20035, 'Invalid high recid');
      END IF;
      deb('ckptNeeded - high_pic_recid='||to_char(high_pic_recid)||
               ', local.high_pic_recid='||to_char(local.high_pic_recid));
      IF (high_pic_recid > local.high_pic_recid) THEN
        ckp_type := RESYNC_PARTIAL;
        GOTO ret;
      ELSIF (high_pic_recid < local.high_pic_recid) THEN
        raise_application_error(-20035, 'Invalid high recid');
      END IF;
    ELSE
--
      IF (cksum = last_resync_cksum AND kccdivts = date2stamp(cf_version)) THEN
         deb('ckptNeeded - resync checksum same as last checksum');
         ckp_type := RESYNC_NONE;
      ELSE
         ckp_type := RESYNC_PARTIAL;
         last_resync_cksum := cksum;
      END IF;
    END IF;
  ELSE
--
--
--
--
    IF (cf_type = CF_CURRENT) THEN
      deb('ckptNeeded - cf_type = CF_CURRENT');
      ckp_type := RESYNC_FULL;
      setReason(RESYNC_REASON_CF);
    ELSE
      deb('ckptNeeded - cf_type != CF_CURRENT');
      IF (cksum = last_resync_cksum AND kccdivts = date2stamp(cf_version)) THEN
         deb('ckptNeeded - resync checksum same as last checksum');
         ckp_type := RESYNC_NONE;
      ELSE
         ckp_type := RESYNC_PARTIAL;
         last_resync_cksum := cksum;
      END IF;
    END IF;
  END IF;
 
<<ret>>
--
--
--
--
--
--
  IF (ckp_type = RESYNC_PARTIAL AND
      cf_version = local.cf_create_time AND
      ckp_cf_seq = greatest(local.job_ckp_cf_seq, local.full_ckp_cf_seq)) THEN
     deb('ckptNeeded - cf_seq has not advanced - do not need a resync');
     deb('ckptNeeded - ' || ckp_cf_seq || ',' || local.job_ckp_cf_seq ||
                     ',' || local.full_ckp_cf_seq);
     ckp_type := RESYNC_NONE;
  END IF;
 
--
  IF (ckp_type = RESYNC_NONE) THEN
    deb('ckptNeeded - resync not needed, rollback, release locks');
    rollback;
  END IF;
 
  select decode(ckp_type, RESYNC_NONE, 'RESYNC_NONE',
                          RESYNC_PARTIAL, 'RESYNC_PARTIAL',
                          RESYNC_FULL, 'RESYNC_FULL',
                          'UNKNOWN') into ckp_desc from dual;
  deb('ckptNeeded - resync type is ' || ckp_desc);
  deb('ckptNeeded - returning ckp_type=' ||ckp_type);
  RETURN ckp_type;
 
--
EXCEPTION
  WHEN OTHERS THEN
    deb('ckptNeeded - error, rollback, release locks');
    rollback;
    RAISE;
END ckptNeeded;
 
PROCEDURE addTimeZone(
   db_unique_name IN VARCHAR2
  ,db_timezone    IN VARCHAR2
  ,tmz_src        IN VARCHAR2
  ,incarnations   IN VARCHAR2 default 'CURRENT'
)IS
prev_tmz        node.db_timezone%type;
prev_src        node.timezone_src%type;
l_db_key        NUMBER;
l_dbinc_key     NUMBER;
update_cur      NUMBER :=0;
comma_pos       NUMBER;
is_valid        NUMBER;
is_tmz_valid    VARCHAR2(7);
cur_dbinc       NUMBER;
tail_dbinc      VARCHAR2(256);
invalid_keys    VARCHAR2(256);
l_invalid_val   VARCHAR2(256);
l_err_no        CONSTANT NUMBER := -20244; -- modify in upate_db
--
tmz_err         EXCEPTION;
PRAGMA EXCEPTION_INIT(tmz_err, -20244);
BEGIN
--
--
--
  IF tmz_src = 'P' OR tmz_src = 'A'
  THEN
    BEGIN
      select tz_offset(db_timezone)
        into is_tmz_valid
      from dual;
   EXCEPTION
      when others THEN
        l_invalid_val := 'timezone - ' || db_timezone; 
        RAISE tmz_err;
   END;
  END IF;
 
--
  IF tmz_src = 'R'        -- db_key already available during resync
  THEN
    l_db_key := this_db_key;
    select db_timezone, timezone_src
      into prev_tmz, prev_src
      from node
    where node.db_unique_name = upper(addTimeZone.db_unique_name)
      AND db_key = l_db_key;
  ELSE                   -- need to fetch db_key
    select db_key, db_timezone, timezone_src
      into l_db_key, prev_tmz, prev_src
      from node
    where node.db_unique_name = upper(addTimeZone.db_unique_name);
  END IF;
 
--
  select dbinc_key 
    into l_dbinc_key
    from dbinc
   where db_key = l_db_key
     AND dbinc_status = 'CURRENT';
 
--
  IF incarnations != 'CURRENT'
  THEN
--
    is_valid := LENGTH(TRIM(TRANSLATE(incarnations, 
                                       ',0123456789', ' '))); 
    IF is_valid IS NOT NULL
    THEN
      l_invalid_val := 'incarnations - ' || incarnations;
      RAISE tmz_err;
    END IF;
 
    tail_dbinc := incarnations;
    IF LENGTH(TRIM(tail_dbinc)) > 0
    THEN
      LOOP
        comma_pos := instr(tail_dbinc, ',');
        IF comma_pos = 0
        THEN
          cur_dbinc := TO_NUMBER(TRIM(tail_dbinc));
          tail_dbinc := NULL;
        ELSE
          cur_dbinc := TO_NUMBER(TRIM(substr(tail_dbinc,1, comma_pos-1)));
          tail_dbinc := substr(tail_dbinc, comma_pos+1);
        END IF;
 
--
        IF l_dbinc_key = cur_dbinc
        THEN
          update_cur := 1;
        END IF;
 
        IF cur_dbinc IS NOT NULL
        THEN
          select count(*)
            into is_valid
            from dbinc
           where db_key = l_db_key
             AND dbinc_key = cur_dbinc;
 
          IF is_valid = 0
          THEN
            IF invalid_keys is NULL
            THEN
              invalid_keys := cur_dbinc;
            ELSE
              invalid_keys := invalid_keys || ',' || cur_dbinc;
            END IF;
          END IF;
        END IF;
        
        EXIT WHEN tail_dbinc IS NULL;
      END LOOP;
    END IF;
  END IF;
 
--
  IF invalid_keys IS NOT NULL
  THEN
      l_invalid_val := 'invalid keys in incarnations - '
                                          || invalid_keys;
      RAISE tmz_err;
  END IF;
 
--
--
  IF (prev_src IS NULL AND (update_cur = 1 OR 
                              incarnations = 'CURRENT')) OR
     (                         --no need to re-update
      NOT(prev_src = tmz_src AND prev_tmz = db_timezone)  AND 
      (
       (tmz_src = 'P') OR      -- update if coming from parameter file
--
       (tmz_src = 'A' AND prev_src IN ('A', 'S', 'R') AND (update_cur=1
                                         OR incarnations = 'CURRENT')) OR
--
--
--
       (tmz_src = 'S' AND prev_src IN ('S', 'P', 'R')) OR
--
--
       (tmz_src = 'R' AND prev_src = 'R')
       )
      )
  THEN
    UPDATE node
       SET node.db_timezone = addTimeZone.db_timezone,
           timezone_src = tmz_src
     WHERE node.db_unique_name
              = upper(addTimeZone.db_unique_name)
      AND db_key = l_db_key;      -- could be from resync
 
    UPDATE dbinc
       SET dbinc_timezone = db_timezone
     WHERE db_key = l_db_key
      AND dbinc_status = 'CURRENT';
 
--
    IF tmz_src = 'A'
    THEN
      update_cur := 2;
    END IF;
  END IF;
 
--
  IF incarnations != 'CURRENT'
  THEN
--
    IF update_cur = 1 AND      -- did not allow
--
       NOT(prev_src = tmz_src AND prev_tmz = db_timezone)
    THEN
      l_invalid_val := 'Current incarnation cannot be updated';
      RAISE tmz_err;
    ELSE
      tail_dbinc := incarnations;
      IF NVL(LENGTH(TRIM(tail_dbinc)),0) > 0
      THEN
        LOOP
          comma_pos := NVL(instr(tail_dbinc, ','),0);
          IF comma_pos = 0
          THEN
            cur_dbinc := TO_NUMBER(TRIM(tail_dbinc));
            tail_dbinc := NULL;
          ELSE
            cur_dbinc := TO_NUMBER(TRIM(substr(tail_dbinc,1, comma_pos-1)));
            tail_dbinc := substr(tail_dbinc, comma_pos+1);
          END IF; 
 
          IF cur_dbinc != l_dbinc_key   -- also checks cur_dbinc is null
          THEN
            UPDATE dbinc
               SET dbinc_timezone = db_timezone
             WHERE dbinc_key = cur_dbinc
               AND db_key = l_db_key;
          END IF;
        
          EXIT WHEN tail_dbinc IS NULL;
        END LOOP;
      END IF;
    END IF;
  END IF;
  commitChanges('addTimeZone');
EXCEPTION
  WHEN tmz_err THEN
       deb(l_invalid_val);
       raise_application_error(l_err_no, l_invalid_val);
  WHEN OTHERS THEN
       deb('Error in addTimeZone, release locks');
       ROLLBACK;
       RAISE;
END addTimeZone;
 
 
PROCEDURE beginCkpt(
  ckp_scn       IN NUMBER
 ,ckp_cf_seq    IN NUMBER
 ,cf_version    IN DATE
 ,ckp_time      IN DATE
 ,ckp_type      IN VARCHAR2
 ,ckp_db_status IN VARCHAR2
 ,high_df_recid IN NUMBER
 ,cf_type       IN VARCHAR2 DEFAULT 'CURRENT'   -- for compatibility reasons
) IS
 
local      ckp%rowtype;
node_count NUMBER;
db_role    node.database_role%type;
local_dbid NUMBER;
local_reset_noncir_watermarks boolean := TRUE;
local_reset_cir_watermarks    boolean := TRUE;
BEGIN
  IF (this_ckp_key IS NOT NULL) THEN
    raise_application_error(-20030, 'Resync in progress');
  END IF;
  IF (this_dbinc_key IS NULL) THEN
    raise_application_error(-20020, 'Database incarnation not set');
  END IF;
  IF (this_site_key IS NULL) THEN
    raise_application_error(-20199, 'Site key is not set');
  END IF;
  IF (cf_type != 'CURRENT' AND ckp_type = 'FULL') THEN
    raise_application_error(-20072, 'full resync from noncurrent controlfile');
  END IF;
 
 
  clearResyncActions;
 
  deb('beginCkpt - ckp_type = '||ckp_type||', cf_type ='||cf_type ||
      ', ckp_scn =' || ckp_scn || ', site_key = ' || this_site_key);
 
--
  SELECT db_id INTO local_dbid FROM db
  WHERE db_key = this_db_key FOR UPDATE OF db.db_key;
 
  deb('beginCkpt - Obtained all locks for db '|| to_char(this_db_key));
 
--
--
--
--
--
--
--
--
  kccdivts := date2stamp(cf_version);           -- save in pkg global
 
--
  SELECT ckp_scn, cf_create_time,
         decode(beginCkpt.ckp_type, 'FULL', full_ckp_cf_seq,
                greatest(job_ckp_cf_seq, full_ckp_cf_seq)), dbinc_key
  INTO local.ckp_scn, local.cf_create_time, local.ckp_cf_seq, local.dbinc_key
  FROM node
  WHERE site_key = this_site_key;
 
--
  last_cf_version_time := local.cf_create_time;
 
--
  SELECT max(ckp_key)
    INTO local.ckp_key
    FROM ckp
    WHERE dbinc_key = this_dbinc_key;
 
  IF (local.ckp_key IS NULL) THEN
    deb('beginCkpt - first checkpoint for this incarnation '|| this_dbinc_key);
    local_reset_noncir_watermarks := TRUE;
    IF (cf_version = local.cf_create_time) THEN
       local_reset_cir_watermarks := FALSE;
    ELSE 
       local_reset_cir_watermarks := TRUE;
    END IF;
  ELSIF (cf_type = 'CURRENT' OR
         (cf_type = 'STANDBY' AND this_db_unique_name is not null)) THEN
--
--
--
--
--
--
    IF (ckp_type = 'FULL' AND this_dbinc_key = local.dbinc_key) THEN
      IF  (ckp_scn < local.ckp_scn) THEN
        deb('beginCkpt - cf scn='||ckp_scn||',catalog cf scn='||local.ckp_scn);
        raise_application_error(-20032, 'Invalid checkpoint SCN');
      ELSIF (ckp_scn = local.ckp_scn AND ckp_cf_seq < local.ckp_cf_seq) THEN
        deb('beginCkpt - cf seq='||ckp_cf_seq||',catalog cf seq='||
            local.ckp_cf_seq);
        raise_application_error(-20033, 'Invalid checkpoint cf seq#');
      ELSIF (ckp_scn = local.ckp_scn AND ckp_cf_seq = local.ckp_cf_seq) THEN
        raise_application_error(-20034, 'Resync not needed');
      END IF;
    END IF;
 
    deb('beginCkpt:last_cf_version' || local.cf_create_time);
    deb('beginCkpt:cf_version' || cf_version);
 
    IF (cf_version = local.cf_create_time) THEN
      deb('beginCkpt - Resync from same last control file');
--
--
--
--
--
      IF (ckp_cf_seq < local.ckp_cf_seq AND
          this_dbinc_key = local.dbinc_key) THEN
        deb('beginCkpt - cf seq='||ckp_cf_seq||',catalog cf seq='||
            local.ckp_cf_seq);
        raise_application_error(-20033, 'Invalid checkpoint cf seq#');
      ELSIF (ckp_cf_seq = local.ckp_cf_seq AND
             this_dbinc_key = local.dbinc_key) THEN
        raise_application_error(-20034, 'Resync not needed');
      END IF;
 
      local_reset_noncir_watermarks := FALSE;
      local_reset_cir_watermarks    := FALSE;
    ELSE
      deb('beginCkpt - Resync from different control file');
      local_reset_noncir_watermarks := TRUE;
      local_reset_cir_watermarks    := TRUE;
    END IF;
  ELSE
--
--
    IF (ckp_db_status = 'BACKUP') THEN
       deb('beginCkpt - Resync from control file copy');
       local_reset_noncir_watermarks := TRUE;
       local_reset_cir_watermarks    := TRUE;
    ELSE
--
--
       IF (kccdivts = sessionWaterMarks.last_kccdivts) THEN
          deb('beginCkpt - Resync from same backup control file');
          local_reset_noncir_watermarks := FALSE;
          local_reset_cir_watermarks    := FALSE;
       ELSE
          deb('beginCkpt - Resync from different backup control file');
          local_reset_noncir_watermarks := TRUE;
          local_reset_cir_watermarks    := TRUE;
       END IF;
    END IF;
  END IF;
 
  IF (local_reset_cir_watermarks) THEN
     deb('beginCkpt - init session watermarks');
     sessionWaterMarks := init_sessionWaterMarks;
     sessionWaterMarks.last_kccdivts := kccdivts;
  END IF;
 
--
--
  IF (cf_type = 'CURRENT' OR cf_type = 'CREATED' OR 
      (cf_type = 'STANDBY' AND this_db_unique_name is not null)) THEN
    IF NOT local_reset_noncir_watermarks THEN
       deb('beginCkpt - update ckp_scn and use existing non cir water marks');
--
       UPDATE node SET
         ckp_scn =
           greatest(ckp_scn,
             decode(beginCkpt.ckp_type, 'FULL', beginCkpt.ckp_scn, 0)),
         full_ckp_cf_seq =
           greatest(full_ckp_cf_seq,
             decode(beginCkpt.ckp_type, 'FULL', beginCkpt.ckp_cf_seq, 0)),
         job_ckp_cf_seq =
           greatest(job_ckp_cf_seq,
             decode(beginCkpt.ckp_type, 'PARTIAL', beginCkpt.ckp_cf_seq, 0)),
         bcr_in_use = nvl2(high_bcr_recid, 'YES', 'NO')
       WHERE site_key = this_site_key;
    ELSE
--
--
--
--
--
--
--
--
--
--
--
       deb('beginCkpt - update ckp_scn and reset non cir water marks, ' ||
           'this_site_key '|| this_site_key);
       UPDATE node SET
         cf_create_time = beginCkpt.cf_version,
         dbinc_key = this_dbinc_key,
         ckp_scn =
           decode(beginCkpt.ckp_type, 'FULL', beginCkpt.ckp_scn, 0),
         full_ckp_cf_seq =
           decode(beginCkpt.ckp_type, 'FULL', beginCkpt.ckp_cf_seq, 0),
         job_ckp_cf_seq =
           decode(beginCkpt.ckp_type, 'PARTIAL', beginCkpt.ckp_cf_seq, 0),
         bcr_in_use = nvl2(high_bcr_recid, 'YES', 'NO'),
         high_ts_recid = NULL,
         high_df_recid = NULL,
         high_rt_recid = NULL,
         high_orl_recid = NULL,
         high_tf_recid = 0,
         high_grsp_recid = 0,
         high_pdb_recid = NULL
       WHERE site_key = this_site_key;
    END IF;
  ELSE
--
     UPDATE node SET
       cf_create_time = beginCkpt.cf_version,
       dbinc_key = this_dbinc_key,
       ckp_scn =
         decode(beginCkpt.ckp_type, 'FULL', beginCkpt.ckp_scn, 0),
       full_ckp_cf_seq =
         decode(beginCkpt.ckp_type, 'FULL', beginCkpt.ckp_cf_seq, 0),
       job_ckp_cf_seq =
         decode(beginCkpt.ckp_type, 'PARTIAL', beginCkpt.ckp_cf_seq, 0),
       bcr_in_use = nvl2(high_bcr_recid, 'YES', 'NO')
     WHERE site_key = this_site_key;
  END IF;
 
  IF (local_reset_cir_watermarks) THEN
--
--
--
     deb('beginCkpt - update reset circular water marks, this_site_key '||
         this_site_key);
     UPDATE node SET
       high_ic_recid = 0,
       high_offr_recid = 0,
       high_rlh_recid = 0,
       high_al_recid = 0,
       high_bs_recid = 0,
       high_bp_recid = 0,
       high_bdf_recid = 0,
       high_cdf_recid = 0,
       high_brl_recid = 0,
       high_bcb_recid = 0,
       high_ccb_recid = 0,
       high_do_recid = 0,
       high_pc_recid = 0,
       high_bsf_recid = 0,
       high_rsr_recid = 0,
       high_nrsp_recid = 0,
       high_bcr_recid = 0,
       bcr_in_use = nvl2(high_bcr_recid, 'YES', 'NO'),
       high_pic_recid = 0
     WHERE site_key = this_site_key;
  END IF;
 
  SELECT max(ckp_scn) INTO last_full_ckp_scn
    FROM ckp 
   WHERE ckp_type = 'FULL'
     AND dbinc_key = this_dbinc_key;
  deb('beginCkpt - last_full_ckp_scn ' || last_full_ckp_scn);
 
--
  BEGIN
    INSERT INTO ckp
       (ckp_key, ckp_scn, ckp_cf_seq, cf_create_time, ckp_time,
        dbinc_key, ckp_type, ckp_db_status, resync_time, site_key)
    VALUES
       (rman_seq.nextval, ckp_scn, ckp_cf_seq, cf_version, ckp_time,
        this_dbinc_key, beginCkpt.ckp_type, ckp_db_status, sysdate,
        this_site_key)
    RETURNING ckp_key INTO this_ckp_key;
  EXCEPTION
    WHEN dup_val_on_index THEN
      IF (cf_type = 'CURRENT' OR 
          (cf_type = 'STANDBY' AND this_db_unique_name IS NOT NULL)) THEN
        RAISE;
      ELSE
--
--
--
--
--
--
        raise_application_error(-20034, 'Resync not needed');
      END IF;
  END;
 
  SELECT count(*) INTO  node_count
  FROM   node
  WHERE  node.db_key = this_db_key AND
         node.db_unique_name = this_db_unique_name;
 
  IF (node_count = 0 AND this_db_unique_name IS NOT NULL) THEN
     IF substr(this_db_unique_name,1,1) = '$' THEN
        db_role := 'RA';
     ELSE
        IF (cf_type = 'STANDBY') THEN
           db_role := 'STANDBY';
        ELSE
           db_role := 'PRIMARY';
        END IF;
     END IF;
     deb('beginCkpt - adding node row with force_resync2cf=NO' ||
         ', db_unique_name = ' || this_db_unique_name ||
         ', db_role = ' || db_role);
     INSERT INTO node(db_unique_name,      db_key,      high_conf_recid,
                      force_resync2cf,     database_role, site_key)
               VALUES(this_db_unique_name, this_db_key, 0,
                      'NO',                db_role,       rman_seq.nextval);
  END IF;
  this_ckp_scn := ckp_scn;
  this_ckp_time := ckp_time;
  this_cf_type := cf_type;
  this_cf_version := cf_version;
  this_ckp_type := ckp_type;
  deb('beginCkpt:this_cf_type' || this_cf_type);
  deb('beginCkpt:this_cf_version' || this_cf_version);
  deb('beginCkpt: clearing watermark indexes');
 
--
--
  select rman_seq.currval into this_bp_key_poll from dual;
  getPolled_AL := TRUE;
  IF feedback_al%ISOPEN THEN CLOSE feedback_al; END IF;
  IF feedback_bp%ISOPEN THEN CLOSE feedback_bp; END IF;
  
  IF this_is_ors THEN
     this_enable_populate_rsr := getValueFromConfig('_enable_populate_rsr_key');
  END IF;
--
EXCEPTION
  WHEN OTHERS THEN
    deb('beginCkpt - error, rollback, release locks');
    rollback;
    RAISE;
 
END beginCkpt;
 
 
PROCEDURE clearCursorVariables IS
 
BEGIN
  pdbRec.guid := NULL;
  picRec.guid := NULL;
  tsRec.ts# := NULL;
  dfRec.file# := NULL;
  tfRec.file# := NULL;
  rtRec.thread# := NULL;
  orlRec.fname := NULL;
  grspRec.rspname := NULL;
 
END clearCursorVariables;
 
 
PROCEDURE endCkpt IS
 
BEGIN
 
  deb('endCkpt:Updating watermarks for backup related columns');
  deb('endCkpt:this_curr_bp_recid=' || this_curr_bp_recid);
  deb('endCkpt:this_high_bp_recid=' || this_high_bp_recid);
  IF this_curr_bp_recid <> this_high_bp_recid THEN
     UPDATE watermarks SET high_bp_recid  = this_high_bp_recid
     WHERE db_key = this_db_key;
  END IF;
--
  IF this_ckp_type = 'FULL' THEN
     deb('endCkpt:this_cf_version updated=' || this_cf_version);
     UPDATE watermarks SET cf_version_stamp = this_cf_version
     WHERE db_key = this_db_key;
  END IF;
 
--
--
  this_enable_populate_rsr := NULL;
  this_upstream_site_key := NULL;
--
  IF this_lock_ors_inspect THEN
    this_ckp_key := NULL;                 -- and update state variable
    this_ckp_scn := NULL;
    this_ckp_time := NULL;
    this_cf_type := NULL;
    this_cf_version := NULL;
    last_cf_version_time := NULL;
    this_ckp_type := NULL;
    commitChanges('endCkpt-1');
  ELSE
    checkResync;
 
    IF (tsRec.ts# IS NOT NULL) THEN
      raise_application_error(-20041, 'Tablespace resync not completed');
    END IF;
    IF (dfRec.file# IS NOT NULL) THEN
      raise_application_error(-20051, 'Datafile resync not completed');
    END IF;
 
    this_ckp_key := NULL;                 -- and update state variable
    this_ckp_scn := NULL;
    this_ckp_time := NULL;
    this_cf_type := NULL;
    this_cf_version := NULL;
    last_cf_version_time := NULL;
    this_ckp_type := NULL;
 
--
    clearCursorVariables;   
 
--
--
--
    IF this_clr_ba_newinc_err AND this_is_ors THEN
       deb('endckpt:fix_error for db_key = '||this_db_key);
--
--
--
       EXECUTE IMMEDIATE
        'BEGIN dbms_rai_fix_error(
          error_num => -64735);
         END;' ;
       this_clr_ba_newinc_err := FALSE;
    END IF;
    commitChanges('endCkpt-2');
 
    prev_sessionWaterMarks := sessionWaterMarks;
 
    /* Do not run cleanupTempResource when connected to a virtual catalog,
     * because we do not allow merging catalogs to be done by a virtual
     * catalog user. The cleanuopTempResource executes DDLs that will
     * automatically commit and release locks */
    if user = g_catowner then
      cleanupTempResource;
    end if;
  END IF;
 
END endCkpt;
 
 
PROCEDURE cancelCkpt IS
 
BEGIN
  deb('cancelCkpt - rollback, release locks');
  rollback;
 
--
--
  this_enable_populate_rsr := NULL;
  this_upstream_site_key := NULL;
--
--
  IF this_lock_ors_inspect THEN
     return;
  END IF;
 
  sessionWaterMarks := prev_sessionWaterMarks;
 
  IF (this_ckp_key IS NOT NULL) THEN
--
    this_ckp_key := NULL;
    this_ckp_scn := NULL;
    this_ckp_time := NULL;
  END IF;
  IF pdbQ%ISOPEN     THEN CLOSE pdbQ;   END IF;
  IF picQ%ISOPEN     THEN CLOSE picQ;   END IF;
  IF tsQ%ISOPEN      THEN CLOSE tsQ;    END IF;
  IF dfQ%ISOPEN      THEN CLOSE dfQ;    END IF;
  IF tfQ%ISOPEN      THEN CLOSE tfQ;    END IF;
  IF rtQ%ISOPEN      THEN CLOSE rtQ;    END IF;
  IF orlQ%ISOPEN     THEN CLOSE orlQ;   END IF;
  IF grspQ%ISOPEN    THEN CLOSE grspQ;  END IF;
  IF bpq%ISOPEN      THEN CLOSE bpq;    END IF;
  IF feedback_al%ISOPEN THEN CLOSE feedback_al; END IF;
  IF feedback_bp%ISOPEN THEN CLOSE feedback_bp; END IF;
  
--
  clearCursorVariables;   
 
--
  last_resync_cksum := NULL;
END cancelCkpt;
 
--
--
FUNCTION lastFullCkpt RETURN NUMBER IS
BEGIN
   RETURN last_full_ckp_scn;
END lastFullCkpt;
 
/* Feedback about files polled by OAM */
FUNCTION getPolledAl (rec_type OUT NUMBER,
                      recid    OUT NUMBER,
                      stamp    OUT NUMBER,
                      fname    OUT VARCHAR2) RETURN BOOLEAN IS
   al_rec       feedback_al%ROWTYPE;
BEGIN
 
   IF NOT feedback_al%ISOPEN THEN 
      deb('getPolledAl - open feedback_al, bp_key_poll=' || curr_bp_key_poll);
      OPEN feedback_al(curr_bp_key_poll);
   END IF;
 
   FETCH feedback_al INTO al_rec;
 
   IF feedback_al%NOTFOUND THEN
      CLOSE feedback_al;
      deb('getPolledAl - closing feedback_al');
      RETURN FALSE;
   ELSE
      deb('getPolledAl - recid='||al_rec.recid||',stamp='||al_rec.stamp);
      deb('getPolledAl - fname='||al_rec.fname);
      rec_type := RTYP_ARCHIVED_LOG;
      recid    := al_rec.recid;
      stamp    := al_rec.stamp;
      fname    := al_rec.fname;
      RETURN TRUE;
   END IF;
 
END getPolledAl;
 
FUNCTION haveProcessedBS (disk_bs_key IN NUMBER) RETURN BOOLEAN IS
   to_process NUMBER;
BEGIN
   deb('haveProcessedBS - disk_bs_key='||disk_bs_key);
 
--
--
   to_process := 0;
   FOR cur_rec IN
      (SELECT file#, create_scn, ckp_scn, dbinc_key 
          FROM bdf where bs_key=disk_bs_key
       MINUS 
       SELECT a.file#, a.create_scn, a.ckp_scn, a.dbinc_key
          FROM bdf a, 
              (SELECT bs_key, file#, create_scn, ckp_scn, dbinc_key
                  FROM bdf 
                  WHERE bs_key=disk_bs_key) b
          WHERE b.file#=a.file# 
            AND b.create_scn=a.create_scn 
            AND b.ckp_scn=a.ckp_scn 
            AND b.dbinc_key=a.dbinc_key 
            AND b.bs_key <> a.bs_key
            AND a.bs_key IN
                (SELECT bs_key FROM bp 
                    WHERE handle like 'VB$%' 
                      AND db_key = this_db_key 
                      AND bp_key > curr_bp_key_poll))
   LOOP
      to_process := to_process + 1;
      deb('haveProcessedBS - not processed file#='||cur_rec.file#||
          ',create_scn='||cur_rec.create_scn||
          ',ckp_scn='||cur_rec.ckp_scn||
          ',dbinc_key='||cur_rec.dbinc_key);
   END LOOP;
   IF to_process = 0 THEN
      deb('haveProcessedBS - Disk backupset processed by OAM');
      return TRUE;
   END IF;
 
   return FALSE;
END haveProcessedBS;
 
FUNCTION getPolledBP (rec_type OUT NUMBER,
                      recid    OUT NUMBER,
                      stamp    OUT NUMBER,
                      fname    OUT VARCHAR2) RETURN BOOLEAN IS
   to_process   NUMBER;
   bp_rec       feedback_bp%ROWTYPE;
 
BEGIN
 
   IF NOT feedback_bp%ISOPEN THEN 
      deb('getPolledBP - open feedback_bp, bp_key_poll=' || curr_bp_key_poll);
      OPEN feedback_bp(curr_bp_key_poll);
   END IF;
 
   IF disk_bp_rec.bs_key is NOT NULL THEN
      deb('getPolledBP - have cached disk piece = '||disk_bp_rec.handle);
      IF haveProcessedBS(disk_bp_rec.bs_key) THEN
         rec_type := RTYP_BACKUP_PIECE;
         recid    := disk_bp_rec.recid;
         stamp    := disk_bp_rec.stamp;
         fname    := disk_bp_rec.handle;
         disk_bp_rec := null;
         deb('getPolledBP - Purgable');
         RETURN TRUE;
      ELSE
         disk_bp_rec := null;
         deb('getPolledBP - Not purgable');
      END IF;
   END IF;
 
<<get_next_rec>>
 
   FETCH feedback_bp INTO bp_rec;
 
   IF feedback_bp%NOTFOUND THEN
      CLOSE feedback_bp;
      deb('getPolledBP - closing feedback_bp');
      RETURN FALSE;
   ELSE
 
      deb('getPolledBP - bs_key='||bp_rec.bs_key||',piece#='||bp_rec.piece#||
       ',device_type='||bp_rec.device_type||',ba_access='||bp_rec.ba_access);
      deb('getPolledBP - recid='||bp_rec.recid||',stamp='||bp_rec.stamp||
         ',site_key='||bp_rec.site_key);
      deb('getPolledBP - handle='||bp_rec.handle);
 
      IF disk_bp_rec.bs_key is NULL AND
         bp_rec.device_type = 'DISK' THEN
         disk_bp_rec := bp_rec;
         deb('getPolledBP - fetch next; Chk disk piece=' ||disk_bp_rec.handle);
         goto get_next_rec;
      END IF;
 
      IF disk_bp_rec.bs_key is NULL THEN
         deb('getPolledBP - fetch next; No disk piece to check');
         goto get_next_rec;
      END IF;
 
      IF bp_rec.device_type = 'SBT_TAPE' AND
         bp_rec.bs_key = disk_bp_rec.bs_key AND
         bp_rec.piece# = disk_bp_rec.piece#  THEN
 
--
--
         IF bp_rec.ba_access = 'L' OR bp_rec.ba_access = 'T' THEN
            rec_type := RTYP_BACKUP_PIECE;
            recid    := disk_bp_rec.recid;
            stamp    := disk_bp_rec.stamp;
            fname    := disk_bp_rec.handle;
            disk_bp_rec := null;
            deb('getPolledBP - Disk backuppiece copied by OAM');
            RETURN TRUE;
--
--
--
         ELSIF bp_rec.ba_access = 'D' AND
               haveProcessedBS(disk_bp_rec.bs_key) THEN
            rec_type := RTYP_BACKUP_PIECE;
            recid    := disk_bp_rec.recid;
            stamp    := disk_bp_rec.stamp;
            fname    := disk_bp_rec.handle;
            disk_bp_rec := null;
            deb('getPolledBP - Polled Disk backuppiece processed');
            RETURN TRUE;
         END IF;
      ELSE
--
--
         IF haveProcessedBS(disk_bp_rec.bs_key) THEN
            rec_type := RTYP_BACKUP_PIECE;
            recid    := disk_bp_rec.recid;
            stamp    := disk_bp_rec.stamp;
            fname    := disk_bp_rec.handle;
            IF bp_rec.device_type = 'DISK' THEN
               disk_bp_rec := bp_rec;    -- save for next call, to avoid fetch
            ELSE
               disk_bp_rec := null;
            END IF;
            return TRUE;
         ELSE
            deb('getPolledBP - Disk backuppiece not processed - check next');
            IF bp_rec.device_type = 'DISK' THEN
               disk_bp_rec := bp_rec;    -- save for next call, to avoid fetch
            ELSE
               disk_bp_rec := null;
            END IF;
         END IF;
      END IF;
      deb('getPolledBP - fetch next');
      goto get_next_rec;
   END IF;
 
 
END getPolledBP;
 
FUNCTION getPolledRec(rec_type OUT NUMBER,
                      recid    OUT NUMBER,
                      stamp    OUT NUMBER,
                      fname    OUT VARCHAR2) RETURN BOOLEAN IS
BEGIN
 
--
--
   IF NOT (this_is_ors AND
           (this_cf_type = 'CURRENT' OR
            (this_cf_type = 'STANDBY' and this_db_unique_name is not null)))
                                                                          THEN
      RETURN FALSE;
   END IF;
 
   SELECT bp_key_poll into curr_bp_key_poll 
      FROM node
      WHERE site_key = this_site_key;
 
   IF getPolled_AL THEN
      IF (getPolledAL(rec_type, recid, stamp, fname)) THEN
         RETURN TRUE;
      ELSE
         getPolled_BP := TRUE;
         getPolled_AL := FALSE;
      END IF;
   END IF;
 
   IF getPolled_BP THEN
      IF (getPolledBP(rec_type, recid, stamp, fname)) THEN
         RETURN TRUE;
      END IF;
   END IF;
 
--
--
   deb('getPolledRec - Polling bp_key='||this_bp_key_poll);
   getPolled_BP := FALSE;
   getPolled_AL := FALSE;
 
   RETURN FALSE;
 
END getPolledRec;
 
/*---------------------*
 * Pluggable DB Resync *
 *---------------------*/
PROCEDURE fetchPdb IS                   -- this is private to the pkg body
 
BEGIN
  FETCH pdbQ INTO pdbRec;               -- get next row
  IF pdbQ%NOTFOUND THEN
    pdbRec.guid := NULL;                -- indicate end of fetch
    CLOSE pdbQ;
  ELSE
    deb('fetchPdb - '||pdbRec.name||' ('||to_char(pdbRec.con_id)||') '||
        to_char(pdbRec.guid));
  END IF;
END fetchPdb;
 
PROCEDURE addPdb(
   name       IN VARCHAR2
  ,con_id     IN NUMBER
  ,db_id      IN NUMBER
  ,create_scn IN NUMBER
  ,guid       IN RAW
  ,nobackup   IN VARCHAR2) IS
  local pdb%rowtype;
BEGIN
  deb('addPdb - db_id '|| to_char(db_id));
 
  INSERT INTO pdb
    (pdb_key, db_key, name, con_id, db_id, create_scn, guid, nobackup)
  VALUES
    (rman_seq.nextval, this_db_key, name, con_id, db_id, create_scn, guid,
     nobackup);
END addPdb;
 
PROCEDURE dropPdb(                       -- private to package body
  pdb_key    IN NUMBER
 ,drop_scn   IN NUMBER
 ,drop_time  IN DATE
) IS
 
BEGIN
  deb('dropPdb - pdb_key ' || to_char(pdb_key));
 
  UPDATE pdb_dbinc SET
         drop_scn  = dropPdb.drop_scn,
         drop_time = dropPdb.drop_time
   WHERE pdb_dbinc.dbinc_key = this_dbinc_key
     AND pdb_dbinc.pdb_key   = dropPdb.pdb_key
     AND pdb_dbinc.drop_scn IS NULL;
END dropPdb;
 
FUNCTION beginPluggableDBResync(
  high_pdb_recid IN NUMBER)
RETURN BOOLEAN IS
 
BEGIN
 
  checkResync;
 
--
--
--
--
--
  
  SELECT high_pdb_recid INTO last_pdb_recid
  FROM node  
  WHERE site_key = this_site_key;
 
  IF (high_pdb_recid = last_pdb_recid) THEN
    deb('beginPluggableDBResync - Resync of PDBs not needed');
    RETURN FALSE;
  ELSIF (high_pdb_recid > last_pdb_recid OR last_pdb_recid IS NULL) THEN
    deb('beginPluggableDBResync - Catalog pdb_recid: '|| last_pdb_recid);
    deb('beginPluggableDBResync - High pdb_recid: '|| high_pdb_recid);
    last_pdb_recid := high_pdb_recid;
  
    OPEN pdbQ;                          -- just open that cursor please
    fetchPdb;                           -- do priming read
    last_guid := NULL;                  -- initialize for ordering assert
 
    if resync_reason = RESYNC_REASON_PDB then
      fullResyncAction.active  := TRUE;
      fullResyncAction.valid   := TRUE;
      fullResyncAction.objtype := RESYNC_OBJECT_PDB;
    else
      fullResyncAction.active  := FALSE;
    end if;
 
    RETURN TRUE;
  ELSE
    raise_application_error(-20035, 'Invalid high recid');
  END IF;
  
END beginPluggableDBResync;
 
PROCEDURE checkPluggableDB(
  name       IN VARCHAR2
 ,con_id     IN NUMBER
 ,db_id      IN NUMBER
 ,create_scn IN NUMBER
 ,guid       IN RAW
 ,nobackup   IN VARCHAR2 DEFAULT 'N'
) IS
   dbinc_key   number;
BEGIN
  IF (last_guid >= guid) THEN
    raise_application_error(-20036, 'Invalid record order');
  END IF;
 
  last_guid := guid;
 
  WHILE (guid > pdbRec.guid) LOOP
    dropPdb(pdbRec.pdb_key, this_ckp_scn, this_ckp_time);
    incResyncActions(RESYNC_ACTION_DROP, pdbRec.con_id, pdbRec.name);
    fetchPdb;
  END LOOP;
 
  IF (guid < pdbRec.guid OR pdbRec.guid IS NULL) THEN
    IF (con_id IN (1, 0)) THEN
       IF (guid != ZERO_GUID) THEN
          UPDATE pdb SET guid = checkPluggableDb.guid
           WHERE pdb.db_key = this_db_key
             AND pdb.con_id = checkPluggableDb.con_id;
       END IF;
    ELSE
--
       addPdb(name, con_id, db_id, create_scn, guid, nobackup);
       incResyncActions(RESYNC_ACTION_ADD, con_id, name);
    END IF;
  ELSE -- (guid = pdbRec.guid)
--
    IF (pdbRec.con_id != con_id OR pdbRec.create_scn != create_scn) THEN
       deb('checkPluggableDb - drop and add new pdb');
       dropPdb(pdbRec.pdb_key, this_ckp_scn, this_ckp_time);
       UPDATE pdb
          SET name       = checkPluggableDB.name,
              con_id     = checkPluggableDB.con_id,
              create_scn = checkPluggableDB.create_scn,
              db_id      = checkPluggableDB.db_id,
              nobackup   = checkPluggableDB.nobackup
        WHERE pdb.pdb_key = pdbRec.pdb_key;
       incResyncActions(RESYNC_ACTION_RENAME, con_id, name);
    ELSIF (pdbRec.name != name OR pdbRec.nobackup != nobackup) THEN
       deb('checkPluggableDb - update name/nobackup');
       UPDATE pdb
          SET name     = checkPluggableDB.name,
              nobackup = checkPluggableDB.nobackup
        WHERE pdb.pdb_key = pdbRec.pdb_key;
       incResyncActions(RESYNC_ACTION_RENAME, con_id, name);
    ELSE
       deb('checkPluggableDb - pdb already known');
    END IF;
    fetchPdb;
  END IF;
END checkPluggableDB;
 
PROCEDURE endPluggableDBResync IS
 
BEGIN
  checkResync;
  WHILE (pdbRec.guid IS NOT NULL) LOOP   -- while extra tablespaces in rcvcat
     dropPdb(pdbRec.pdb_key, this_ckp_scn, this_ckp_time);
     incResyncActions(RESYNC_ACTION_DROP, pdbRec.con_id, pdbRec.name);
     fetchPdb;
  END LOOP;
 
--
  pdbRec.guid := NULL;
 
--
  UPDATE node SET high_pdb_recid = nvl(last_pdb_recid, high_pdb_recid)
  WHERE site_key = this_site_key;
 
  last_pdb_recid := NULL;
END endPluggableDBResync;
 
/*-------------------*
 * Tablespace Resync *
 *-------------------*/
 
PROCEDURE fetchTs IS                    -- this is private to the pkg body
 
BEGIN
  FETCH tsQ INTO tsRec;                 -- get next row
  IF tsQ%NOTFOUND THEN
    tsRec.con_id       := MAXNUMVAL;          -- indicate end of fetch
    tsRec.ts#          := MAXNUMVAL;
    tsRec.pdb_drop_scn := NULL;
    CLOSE tsQ;
  ELSE
    deb('fetchTs - '||tsRec.ts_name||' ('||to_char(tsRec.ts#)||') '||
        to_char(tsRec.create_scn) || ';plugin_scn='||to_char(tsRec.plugin_scn));    
  END IF;
END fetchTs;
 
PROCEDURE addTs(
  ts_name                     IN VARCHAR2
 ,ts#                         IN NUMBER
 ,create_scn                  IN NUMBER
 ,create_time                 IN DATE
 ,rbs_count                   IN NUMBER
 ,included_in_database_backup IN VARCHAR2
 ,bigfile                     IN VARCHAR2
 ,temporary                   IN VARCHAR2
 ,encrypt_in_backup           IN VARCHAR2
 ,plugin_scn                  IN NUMBER
 ,pdbinc_key                  IN NUMBER
) IS
BEGIN
  deb('addTs - tablespace '||ts_name||' ('||to_char(ts#)||') '||
      to_char(create_scn) || ',plugin_scn=' || to_char(plugin_scn));
  INSERT INTO ts
    (dbinc_key, ts#, ts_name, create_scn,
     create_time, included_in_database_backup, bigfile, temporary, 
     encrypt_in_backup, plugin_scn, pdbinc_key)
  VALUES
    (this_dbinc_key, ts#, ts_name, create_scn, create_time,
     included_in_database_backup, bigfile, temporary, encrypt_in_backup,
     plugin_scn, pdbinc_key);
 
  INSERT INTO tsatt
    (dbinc_key, ts#, create_scn, start_ckp_key, rbs_count, plugin_scn,
     pdbinc_key)
  VALUES 
    (this_dbinc_key, ts#, create_scn, this_ckp_key, rbs_count, plugin_scn,
     pdbinc_key);
 
END addTs;
 
PROCEDURE dropTs(                       -- private to package body
  ts#        IN NUMBER
 ,create_scn IN NUMBER
 ,drop_scn   IN NUMBER
 ,drop_time  IN DATE
 ,plugin_scn IN NUMBER
 ,pdbinc_key IN NUMBER
) IS
 
BEGIN
  deb('dropTs - tablespace '||to_char(ts#)||' - '||to_char(create_scn) ||
      ',plugin_scn - ' || plugin_scn);
  UPDATE ts SET
    drop_scn     = dropTs.drop_scn,
    drop_time    = dropTs.drop_time
  WHERE ts.dbinc_key  = this_dbinc_key
  AND   ts.pdbinc_key = dropTs.pdbinc_key
  AND   ts.ts#        = dropTs.ts#
  AND   ts.create_scn = dropTs.create_scn
  AND   ts.plugin_scn = dropTs.plugin_scn;
  deb('dropTs - returning');
END dropTs;
 
PROCEDURE renameTs(
  ts_name    IN VARCHAR2
 ,dbinc_key  IN NUMBER
 ,ts#        IN NUMBER
 ,create_scn IN NUMBER
 ,plugin_scn IN NUMBER
 ,pdbinc_key IN NUMBER
) IS
 
BEGIN
  UPDATE ts SET
     ts.ts_name = renameTs.ts_name
  WHERE ts.dbinc_key  = renameTs.dbinc_key
  AND   ts.pdbinc_key = renameTs.pdbinc_key
  AND   ts.ts#        = renameTs.ts#
  AND   ts.create_scn = renameTs.create_scn
  AND   ts.plugin_scn = renameTs.plugin_scn;
END renameTs;
 
FUNCTION beginTableSpaceResync(
  high_ts_recid IN NUMBER,
  force         IN BOOLEAN DEFAULT FALSE)
RETURN BOOLEAN IS
 
BEGIN
 
  checkResync;
 
--
--
 
--
--
--
--
--
 
  SELECT high_ts_recid INTO last_ts_recid
  FROM node
  WHERE site_key = this_site_key;
 
 
  IF (high_ts_recid = last_ts_recid AND NOT force) THEN
    deb('beginTableSpaceResync - Resync of tablespaces not needed');
    RETURN FALSE;
  ELSIF (high_ts_recid > last_ts_recid OR last_ts_recid IS NULL OR
         high_ts_recid IS NULL OR force) THEN
 
    deb('beginTableSpaceResync - Catalog ts_recid: '||last_ts_recid);
    deb('beginTableSpaceResync - High ts_recid: '||high_ts_recid);
    last_ts_recid := high_ts_recid;
 
    OPEN tsQ;                           -- just open that cursor please
    fetchTs;                            -- do priming read
    last_con_id_ts# := -1;              -- initialize for ordering assert
    last_ts# := -1;                     -- initialize for ordering assert
 
    if resync_reason = RESYNC_REASON_TS then
      fullResyncAction.active  := TRUE;
      fullResyncAction.valid   := TRUE;
      fullResyncAction.objtype := RESYNC_OBJECT_TABLESPACE;
    else
      fullResyncAction.active  := FALSE;
    end if;
 
    RETURN TRUE;
  ELSE
    raise_application_error(-20035, 'Invalid high recid');
  END IF;
 
END beginTableSpaceResync;
 
 
PROCEDURE checkTableSpace(
  ts_name                     IN VARCHAR2
 ,ts#                         IN NUMBER
 ,create_scn                  IN NUMBER
 ,create_time                 IN DATE
 ,rbs_count                   IN NUMBER   DEFAULT NULL
 ,included_in_database_backup IN VARCHAR2 DEFAULT NULL
 ,bigfile                     IN VARCHAR2 DEFAULT NULL
 ,temporary                   IN VARCHAR2 DEFAULT NULL
 ,encrypt_in_backup           IN VARCHAR2 DEFAULT NULL
 ,plugin_scn                  IN NUMBER   DEFAULT 0
 ,con_id                      IN NUMBER   DEFAULT 0
 ,pdb_dict_check              IN BOOLEAN  DEFAULT FALSE
) IS
--
--
--
idb              varchar2(3) := nvl(included_in_database_backup, 'YES');
--
bf               varchar2(3) := nvl(bigfile, 'NO');   -- actual default value
tmp              varchar2(3) := nvl(temporary, 'NO'); -- actual default value
ts_changed       boolean     := FALSE;
local_pdbinc_key number;
local_pdb_key    number;
BEGIN
  IF (tsRec.ts# IS NULL) THEN   -- assert beginTableSpaceResync was called
    raise_application_error(-20040, 'Tablespace resync not started');
  END IF;
 
--
  IF (last_con_id_ts# > con_id) THEN
     raise_application_error(-20036, 'Invalid record order');
  END IF;
 
  IF (con_id > last_con_id_ts#) THEN
     last_ts# := -1;
  END IF;
 
  IF (last_ts# >= ts#) THEN 
    raise_application_error(-20036, 'Invalid record order');
  END IF;
 
--
--
--
--
  IF (temporary IS NOT NULL) THEN
     do_temp_ts_resync := TRUE;
  END IF;
 
--
  last_con_id_ts# := con_id;
  last_ts# := ts#;
 
--
--
--
  IF (create_scn > this_ckp_scn AND tmp = 'NO') THEN
    raise_application_error(-20042, 'Invalid tablespace create SCN');
  END IF;
 
--
--
--
--
--
--
--
  deb('checkTableSpace - ts#: ' || ts# || ' tsRec.ts#: ' || tsRec.ts# ||
      ' con_id ' || con_id || ' tsRec.con_id: ' || tsRec.con_id ||
      ' tsRec.pdb_drop_scn ' || tsRec.pdb_drop_scn);
  WHILE (con_id > tsRec.con_id OR
         (tsRec.con_id = con_id AND ts# > tsRec.ts#) OR
         tsRec.pdb_drop_scn IS NOT NULL) LOOP
    IF (tsRec.temporary = 'NO' OR -- is a permanent tablespace 
        do_temp_ts_resync) THEN   -- is a 10gR2 or later rman client
       deb('checkTableSpace - before calling dropTS');
       dropTs(tsRec.ts#, tsRec.create_scn, this_ckp_scn, this_ckp_time,
              tsRec.plugin_scn, tsRec.pdbinc_key);
       deb('checkTableSpace - before calling incResyncActions');
       begin
          incResyncActions(RESYNC_ACTION_DROP, tsRec.ts#, tsRec.ts_name);
       exception
          when others then
              deb('checkTableSpace - (DO_NOT_IGNORE)caught exception ' ||
                  substr(sqlerrm, 1, 132));
       end;
       deb('checkTableSpace - after calling incResyncActions');
    END IF;
    deb('checkTableSpace - before calling fetchTS');
    fetchTs;
    deb('checkTableSpace - after calling fetchTS');
  END LOOP;
 
  deb('checkTableSpace -out of loop, ts#: ' || ts# || ' tsRec.ts#: ' ||
       tsRec.ts# || ' con_id ' || con_id || ' tsRec.con_id: ' || tsRec.con_id);
 
  IF (con_id != tsRec.con_id OR ts# < tsRec.ts#) THEN
    IF (pdb_dict_check) THEN
        deb('checkTableSpace - skipping tablespace needs dictionary check');
    ELSE
--
       local_pdbinc_key := getPdbInc(greatest(create_scn, plugin_scn),
                                     con_id, local_pdb_key);
       addTs(ts_name, ts#, create_scn, create_time, rbs_count, idb, bf,
             tmp, encrypt_in_backup, plugin_scn, local_pdbinc_key);
    END IF;
    incResyncActions(RESYNC_ACTION_ADD, ts#, ts_name);
  ELSE -- (con_id = tsRec.con_id AND ts# = tsRec.ts#)
    IF (pdb_dict_check) THEN
       deb('checkTableSpace - skipping tablespace needs dictionary check');
       goto next_Ts;
    END IF;
 
    IF (create_scn = tsRec.create_scn) THEN
--
--
      IF (create_time <> tsRec.create_time) THEN
        raise_application_error(-20043, 'Invalid tablespace create time');
      END IF;
 
      IF (plugin_scn > 0) THEN
        IF (tsRec.plugin_scn < checkTableSpace.plugin_scn) THEN
          deb('checkTableSpace - plugin read only tbs dropped and replugged');
--
--
--
          dropTs(tsRec.ts#, tsRec.create_scn, this_ckp_scn, this_ckp_time,
                 tsRec.plugin_scn, tsRec.pdbinc_key);
          incResyncActions(RESYNC_ACTION_DROP, tsRec.ts#, tsRec.ts_name);
          addTs(ts_name, ts#, create_scn, create_time, rbs_count, idb, bf, tmp, 
                encrypt_in_backup, plugin_scn, tsRec.curr_pdbinc_key);
          incResyncActions(RESYNC_ACTION_ADD, ts#, ts_name);
          goto next_Ts;
        ELSIF (tsRec.plugin_scn > checkTableSpace.plugin_scn) THEN
--
          raise_application_error(-20055, 'Invalid tablespace plugin SCN');
        ELSE
--
--
          deb('checkTableSpace - known plugged in tablespace');
        END IF;
      END IF;
 
--
--
      IF (ts_name <> tsRec.ts_name) THEN
        renameTs(ts_name, this_dbinc_key, tsRec.ts#, tsRec.create_scn, 
                 tsRec.plugin_scn, tsRec.pdbinc_key);
        incResyncActions(RESYNC_ACTION_RENAME, tsRec.ts#, ts_name);
      END IF;
 
--
--
      IF (idb <> nvl(tsRec.included_in_database_backup,'XX')) THEN
        UPDATE ts SET ts.included_in_database_backup =
                                  checkTableSpace.included_in_database_backup
        WHERE  ts.dbinc_key  = this_dbinc_key
        AND    ts.ts#        = tsRec.ts#
        AND    ts.pdbinc_key = tsRec.pdbinc_key
        AND    ts.create_scn = tsRec.create_scn
        AND    ts.plugin_scn = tsRec.plugin_scn;
        ts_changed := TRUE;
      END IF;
 
--
--
      IF (tsRec.encrypt_in_backup is null and encrypt_in_backup is not null OR
          tsRec.encrypt_in_backup is not null and encrypt_in_backup is null OR
          tsRec.encrypt_in_backup <> encrypt_in_backup) THEN
        UPDATE ts SET ts.encrypt_in_backup = checkTableSpace.encrypt_in_backup
        WHERE  ts.dbinc_key  = this_dbinc_key
        AND    ts.ts#        = tsRec.ts#
        AND    ts.pdbinc_key = tsRec.pdbinc_key
        AND    ts.create_scn = tsRec.create_scn
        AND    ts.plugin_scn = tsRec.plugin_scn;
        ts_changed := TRUE;
      END IF;
 
--
--
      IF (rbs_count <> nvl(tsRec.rbs_count,-1)) THEN
        UPDATE tsatt SET end_ckp_key = this_ckp_key
        WHERE tsatt.dbinc_key = this_dbinc_key
        AND   tsatt.ts# = tsRec.ts#
        AND   tsatt.pdbinc_key = tsRec.pdbinc_key
        AND   tsatt.create_scn = tsRec.create_scn
        AND   tsatt.plugin_scn = tsRec.plugin_scn
        AND   tsatt.end_ckp_key IS NULL;
 
        INSERT INTO tsatt(dbinc_key, ts#, create_scn, start_ckp_key, rbs_count,
               plugin_scn, pdbinc_key)
        VALUES(this_dbinc_key, tsRec.ts#, tsRec.create_scn, this_ckp_key,
               rbs_count, tsRec.plugin_scn, tsRec.pdbinc_key);
        ts_changed := TRUE;
      END IF;
 
      if ts_changed then
        incResyncActions(RESYNC_ACTION_CHANGE, tsRec.ts#, tsRec.ts_name);
      end if;
    ELSIF (create_scn = 0 AND tmp = 'YES') THEN
--
--
--
       dropTs(tsRec.ts#, tsRec.create_scn, create_scn, create_time, 
              tsRec.plugin_scn, tsRec.pdbinc_key);
 
       DELETE FROM ts
        WHERE ts.dbinc_key = this_dbinc_key
          AND ts.ts# = checkTableSpace.ts#
          AND ts.pdbinc_key = tsRec.pdbinc_key
          AND ts.create_scn = 0
          AND ts.plugin_scn = 0;
 
       addTs(ts_name, ts#, create_scn, create_time, rbs_count, idb, bf, tmp,
             encrypt_in_backup, plugin_scn, tsRec.curr_pdbinc_key);
       incResyncActions(RESYNC_ACTION_CHANGE, tsRec.ts#, ts_name);
    ELSE
       IF (tmp = 'YES') THEN
--
--
          IF (tsRec.temporary = 'NO') THEN
             dropTs(tsRec.ts#, tsRec.create_scn, create_scn, create_time,
                    tsRec.plugin_scn, tsRec.pdbinc_key);
          END IF;
 
--
--
--
--
--
          DELETE FROM ts
            WHERE ts.dbinc_key = this_dbinc_key
              AND ts.ts# = checkTablespace.ts#
              AND ts.pdbinc_key = tsRec.pdbinc_key
              AND ts.temporary = 'YES';
          deb('Deleting tablespace entry for ts#=' || ts# ||
              ', ts_name=' || ts_name);
 
          addTs(ts_name, ts#, create_scn, create_time, rbs_count, idb,
                bf, tmp, encrypt_in_backup, plugin_scn, tsRec.curr_pdbinc_key);
          deb('Added tablespace entry for ts#=' || ts# || ', ts_name=' ||
              ts_name);
 
          incResyncActions(RESYNC_ACTION_RECREATE, ts#, ts_name);
       ELSE
          IF (create_scn > tsRec.create_scn) THEN
 
--
--
--
--
--
--
--
--
             dropTs(tsRec.ts#, tsRec.create_scn, create_scn, create_time,
                    tsRec.plugin_scn, tsRec.pdbinc_key);
 
             addTs(ts_name, ts#, create_scn, create_time, rbs_count, idb,
                   bf, tmp, encrypt_in_backup, plugin_scn,
                   tsRec.curr_pdbinc_key);
             incResyncActions(RESYNC_ACTION_RECREATE, tsRec.ts#, ts_name);
          ELSE -- (create_scn < tsRec.create_scn)
--
--
--
--
             raise_application_error(-20042,
                                     'Invalid tablespace creation change#');
          END IF;
       END IF;
    END IF;
 
<<next_Ts>>
    fetchTS;                            -- get next row from TS cursor
 
  END IF; -- (ts# < tsRec.ts)
 
END checkTableSpace;
 
 
PROCEDURE endTableSpaceResync IS
 
BEGIN
  checkResync;
 
  deb('endTableSpaceResync - tsRec.ts#: ' || tsRec.ts#);
 
--
--
--
  begin
     WHILE (tsRec.con_id < MAXNUMVAL) LOOP -- while extra tablespaces in rcvcat
       IF (tsRec.temporary = 'NO' OR -- is a permanent tablespace 
           do_temp_ts_resync) THEN   -- is a 10gR2 or later rman client
          deb('endTableSpaceResync - before calling dropTS');
          dropTs(tsRec.ts#, tsRec.create_scn, this_ckp_scn, this_ckp_time,
                 tsRec.plugin_scn, tsRec.pdbinc_key);
          deb('endTableSpaceResync - before calling incResyncActions');
          begin
             incResyncActions(RESYNC_ACTION_DROP, tsRec.ts#, tsRec.ts_name);
          exception
             when others then
                 deb('endTableSpaceResync (DO_NOT_IGNORE)-caught exception ' ||
                     substr(sqlerrm, 1, 132));
          end;
          deb('endTableSpaceResync - after calling incResyncActions');
       END IF;
       deb('endTableSpaceResync - before calling fetchTS');
       fetchTs;
       deb('endTableSpaceResync - after calling fetchTS');
     END LOOP;
  exception
     when others then
        deb('checkTableSpace(DO_NOT_IGNORE) - caugth exception ' ||
            substr(sqlerrm, 1, 132));
  end;
  deb('endTableSpaceResync -out of loop,  tsRec.ts#: ' || tsRec.ts#);
 
--
  tsRec.ts# := NULL;
 
--
  UPDATE node SET high_ts_recid = nvl(last_ts_recid, high_ts_recid)
  WHERE site_key = this_site_key;
 
--
  IF this_is_ors and this_ckp_type = 'FULL' THEN
     UPDATE watermarks SET high_ts_recid = nvl(last_ts_recid, high_ts_recid)
     WHERE db_key = this_db_key;
  END IF;
 
  last_ts_recid := NULL;
 
--
--
  IF (NOT do_temp_ts_resync) THEN
     UPDATE node SET high_tf_recid = 0
      WHERE site_key = this_site_key;
  END IF;
 
END endTableSpaceResync;
 
 
/*-----------------*
 * Datafile Resync *
 *-----------------*/
 
PROCEDURE fetchDF IS                    -- private to package body
BEGIN
  FETCH dfQ INTO dfRec;
  IF dfQ%NOTFOUND THEN
    dfRec.file# := MAXNUMVAL;           -- indicate end-of-fetch
    CLOSE dfQ;
  ELSE
    deb('fetchDF - file#' || dfRec.file#);
  END IF;
END fetchDF;
 
PROCEDURE addDF(file#               IN NUMBER,  -- private to package body
                fname               IN VARCHAR2,
                create_time         IN DATE,
                create_scn          IN NUMBER,
                blocks              IN NUMBER,
                block_size          IN NUMBER,
                ts#                 IN NUMBER,
                stop_scn            IN NUMBER,
                stop_time           IN DATE,
                read_only           IN NUMBER,
                rfile#              IN NUMBER,
                foreign_dbid        IN NUMBER,
                foreign_create_scn  IN NUMBER,
                foreign_create_time IN DATE,
                plugged_readonly    IN varchar2,
                plugin_scn          IN NUMBER,   
                plugin_reset_scn    IN NUMBER,   
                plugin_reset_time   IN DATE,
                create_thread       IN NUMBER,   
                create_size         IN NUMBER,
                pdbinc_key          IN NUMBER,
                pdb_key             IN NUMBER,
                pdb_closed          IN NUMBER,
                pdb_foreign_dbid    IN NUMBER,
                pdb_foreign_ckp_scn IN NUMBER,
                pdb_foreign_afn     IN NUMBER) IS
 
 
ts_create_scn NUMBER;
ts_plugin_scn NUMBER;
ts_pdbinc_key NUMBER;
ts_name       ts.ts_name%type;
local_df_key  NUMBER;
child_rec     exception;
pragma        exception_init(child_rec, -2292);
BEGIN
  SELECT ts.create_scn, ts.plugin_scn, ts.ts_name, ts.pdbinc_key
  INTO ts_create_scn, ts_plugin_scn, ts_name, ts_pdbinc_key
  FROM ts, rci_pdbinc_this_dbinc pdbinc
  WHERE ts.dbinc_key = this_dbinc_key
  AND   ts.ts# = addDF.ts#
  AND   ts.pdbinc_key = pdbinc.pdbinc_key
  AND   pdbinc.pdb_key = addDF.pdb_key
  AND   pdbinc.dbinc_key = this_dbinc_key
  AND   ts.create_scn  < pdbinc.next_inc_scn
  AND   ts.drop_scn IS NULL;            -- in case ts numbers are reused
 
--
--
--
--
--
  BEGIN
    select distinct df_key into local_df_key from df, dbinc 
      where  file#        = addDF.file#
        and  create_scn   = addDF.create_scn
        and  plugin_scn   = addDF.plugin_scn
        and  foreign_dbid = addDF.foreign_dbid
        and  ts#          = addDF.ts#
        and  df.dbinc_key = dbinc.dbinc_key
        and  dbinc.db_key = this_db_key;
 
  EXCEPTION
    WHEN no_data_found THEN
      select rman_seq.nextval into local_df_key from dual;
  END;
 
--
--
--
--
  INSERT INTO df(dbinc_key, file#, create_scn, create_time,
                 ts#, ts_create_scn, ts_plugin_scn, block_size,
                 stop_scn, stop_time, read_only, rfile#, df_key, blocks,
                 foreign_dbid, foreign_create_scn, foreign_create_time,
                 plugged_readonly, plugin_scn, plugin_reset_scn,
                 plugin_reset_time, create_thread, create_size, pdbinc_key,
                 ts_pdbinc_key, pdb_closed, pdb_foreign_dbid,
                 pdb_foreign_ckp_scn, pdb_foreign_afn)
  VALUES(this_dbinc_key, file#, create_scn, create_time, ts#, ts_create_scn,
         ts_plugin_scn, block_size, stop_scn, stop_time, read_only, rfile#, 
         local_df_key, nvl(blocks, 0), foreign_dbid, foreign_create_scn,
         foreign_create_time, plugged_readonly, plugin_scn, plugin_reset_scn,
         plugin_reset_time, create_thread, create_size, pdbinc_key,
         ts_pdbinc_key, pdb_closed, pdb_foreign_dbid,
         pdb_foreign_ckp_scn, pdb_foreign_afn);
 
--
--
--
  BEGIN
    INSERT INTO site_dfatt(df_key, fname, site_key)
    VALUES(local_df_key, fname, this_site_key);
  EXCEPTION
    WHEN dup_val_on_index THEN
--
      UPDATE site_dfatt SET
        fname = addDf.fname
      WHERE 
        site_key = this_site_key AND
        df_key   = local_df_key;      
  END;
END addDf;
 
PROCEDURE setDatafileSize(file#      IN number
                         ,create_scn IN number
                         ,blocks     IN number
                         ,plugin_scn IN number default 0) IS
BEGIN
  IF (this_dbinc_key is NULL) THEN
    raise_application_error(-20020, 'Database incarnation not set');
  END IF;
 
  update df
  set df.blocks = setDatafileSize.blocks
     where dbinc_key = this_dbinc_key
     and   df.file# = setDatafileSize.file#
     and   df.create_scn = setDatafileSize.create_scn
     and   df.plugin_scn = setDatafileSize.plugin_scn;
  commitChanges('setDatafileSize');
END setDatafileSize;
 
PROCEDURE dropDf(                       -- private to package body
  file# IN NUMBER
 ,create_scn IN NUMBER
 ,plugin_scn IN NUMBER
 ,drop_scn IN NUMBER
 ,drop_time IN DATE
 ,pdbinc_key IN NUMBER
) IS
 
BEGIN
--
--
--
--
--
--
--
--
 
  UPDATE df SET
    drop_scn     = dropDf.drop_scn,
    drop_time    = dropDf.drop_time
  WHERE df.dbinc_key  = this_dbinc_key
  AND   df.file#      = dropDf.file#
  AND   df.create_scn = dropDf.create_scn
  AND   df.plugin_scn = dropDf.plugin_scn
  AND   df.pdbinc_key = dropDf.pdbinc_key;
END dropDf;
 
FUNCTION beginDataFileResyncForStandby(
  high_df_recid IN number
) return boolean IS
BEGIN
  checkResync;
 
  SELECT high_df_recid INTO last_df_recid
  FROM node
  WHERE node.site_key = this_site_key;
 
  deb('high_df_recid='||high_df_recid||',last_df_recid='||last_df_recid);
 
  IF last_full_ckp_scn IS NULL THEN
     deb('beginDataFileResyncForStandby - no full resync');
     raise_application_error(-20079,
        'full resync from primary database is not done');
  END IF;
 
--
--
--
  IF (high_df_recid > last_df_recid OR last_df_recid IS NULL) THEN
     last_df_recid := high_df_recid;
     last_file# := -1;                   -- initialize for ordering assert
--
--
     IF this_ckp_scn > last_full_ckp_scn THEN
        OPEN dfQ;
        fetchDf;                            -- do priming read
     END IF;
     RETURN TRUE;
  END IF;
  deb('no need to resync datafile names for '||this_db_unique_name||
      ' standby site');
  RETURN FALSE;
END;
 
PROCEDURE checkDataFileForStandby(file#           IN NUMBER,
                                  fname           IN VARCHAR2,
                                  create_scn      IN NUMBER,
                                  create_time     IN DATE,
                                  blocks          IN NUMBER,
                                  block_size      IN NUMBER,
                                  ts#             IN NUMBER,
                                  rfile#          IN NUMBER,
                                  stop_scn        IN NUMBER,
                                  read_only       IN NUMBER,
                                  foreign_dbid    IN NUMBER,
                                  plugin_scn      IN NUMBER,
                                  did_prim_resync IN BOOLEAN  DEFAULT FALSE,
                                  pdb_dict_check  IN BOOLEAN  DEFAULT FALSE) IS
   local_df_key NUMBER;
BEGIN
   IF (last_file# >= file#) THEN        -- assert rows passed in ascending
      raise_application_error(-20036, 'Invalid record order');
   END IF;
 
   last_file# := file#;                 -- for checking next call
 
   IF pdb_dict_check THEN
      deb('checkDataFileForStandby - skipping df, needs dictionary check');
      RETURN;
   END IF;
 
 
--
--
   IF this_ckp_scn > last_full_ckp_scn THEN
      IF (file# != dfRec.file#) THEN
         IF (file# > dfRec.file#) THEN
            deb('checkDataFileForStandby - dropped file#=' || dfRec.file#);
         ELSE
--
            deb('checkDataFileForStandby - added file#=' || file#);
         END IF;
         raise_application_error(-20079, 
            'full resync from primary database is not done');
      ELSE
--
--
--
 
--
--
         IF (create_scn <> dfRec.create_scn OR
             plugin_scn <> dfRec.plugin_scn OR
             stop_scn <> dfRec.stop_scn OR
             stop_scn is null and dfRec.stop_scn is not null OR
             stop_scn is not null and dfRec.stop_scn is null OR
             read_only < dfRec.read_only OR
             read_only is null and dfRec.read_only is not null OR
             read_only is not null and dfRec.read_only is null) THEN
            deb('checkDataFileForStandby - change for file#= ' || file# ||
                ' create_scn = ' || create_scn ||
                ' dfRec.create_scn = ' || dfRec.create_scn ||
                ' plugin_scn = ' || plugin_scn ||
                ' dfRec.plugin_scn = ' || dfRec.plugin_scn ||
                ' stop_scn = ' || stop_scn ||
                ' dfRec.stop_scn = ' || dfRec.stop_scn ||
                ' read_only = ' || read_only ||
                ' dfRec.read_only = ' || dfRec.read_only);
            raise_application_error(-20079, 
               'full resync from primary database is not done');
         END IF;
      END IF;
      fetchDF;
   END IF;
 
   BEGIN
--
     select distinct df_key into local_df_key from df, dbinc 
       where  file#        = checkDataFileForStandby.file#
         and  create_scn   = checkDataFileForStandby.create_scn
         and  plugin_scn   = checkDataFileForStandby.plugin_scn
         and  decode(foreign_dbid, 0, checkDataFileForStandby.foreign_dbid,
                     foreign_dbid)  = checkDataFileForStandby.foreign_dbid
         and  ts#          = checkDataFileForStandby.ts#
         and  df.dbinc_key = dbinc.dbinc_key
         and  dbinc.db_key = this_db_key;
   EXCEPTION
      WHEN no_data_found THEN
         IF NOT did_prim_resync THEN
            raise_application_error(-20079,
               'full resync from primary database is not done');
         ELSE
--
--
            raise_application_error(-20999,
               'Internal error in checkDataFileForStandby - 1 ');
         END IF;
 
--
      WHEN too_many_rows THEN
         raise_application_error(-20999,
           'Internal error in checkDataFileForStandby - 2 ');
   END;
 
--
--
--
   BEGIN
     INSERT INTO site_dfatt(df_key, fname, site_key)
     VALUES(local_df_key, checkDataFileForStandby.fname, this_site_key);
   EXCEPTION
     WHEN dup_val_on_index THEN
--
       UPDATE site_dfatt SET
         fname = checkDataFileForStandby.fname
       WHERE
         site_key = this_site_key AND
         df_key   = local_df_key;      
   END;
END;
 
PROCEDURE endDataFileResyncForStandby IS
BEGIN
  checkResync;
 
--
  IF (this_ckp_scn > last_full_ckp_scn AND
      dfRec.file# < MAXNUMVAL) THEN
     deb('endDataFileResyncForStandby - dropped file# > ' || dfRec.file#);
     raise_application_error(-20079, 
        'full resync from primary database is not done');
     IF dfQ%ISOPEN THEN 
        CLOSE dfQ; 
     END IF;
  END IF;
 
--
  dfRec.file# := NULL;
 
--
  UPDATE node SET high_df_recid = last_df_recid
  WHERE node.site_key = this_site_key;
 
  last_df_recid := NULL;
END;
 
 
FUNCTION beginDataFileResync(
  high_df_recid IN NUMBER
) RETURN BOOLEAN IS
 
BEGIN
  checkResync;
 
  IF (tsRec.ts# IS NOT NULL) THEN
    raise_application_error(-20041, 'Tablespace resync not completed');
  END IF;
 
  SELECT high_df_recid INTO last_df_recid
  FROM node
  WHERE site_key = this_site_key;
 
  IF (high_df_recid = last_df_recid) THEN
    deb('beginDataFileResync - Resync of datafiles not needed');
    RETURN FALSE;
  ELSIF (high_df_recid > last_df_recid OR last_df_recid IS NULL) THEN
    deb('beginDataFileResync - Catalog df_recid: '||last_df_recid);
    deb('beginDataFileResync - High df_recid: '||high_df_recid);
    last_df_recid := high_df_recid;
 
    OPEN dfQ;
    fetchDf;                            -- do priming read
    last_file# := -1;                   -- initialize for ordering assert
 
    if resync_reason = RESYNC_REASON_DF then
      fullResyncAction.valid   := TRUE;
      fullResyncAction.active  := TRUE;
      fullResyncAction.objtype := RESYNC_OBJECT_DATAFILE;
    else
      fullResyncAction.active  := FALSE;
    end if;
 
    RETURN TRUE;
  ELSE
    raise_application_error(-20035, 'Invalid high recid');
  END IF;
 
END beginDataFileResync;
 
 
PROCEDURE checkDataFile(file#         IN  NUMBER,
                        fname         IN  VARCHAR2,
                        create_scn    IN  NUMBER,
                        create_time   IN  DATE,
                        blocks        IN  NUMBER,
                        block_size    IN  NUMBER,
                        ts#           IN  NUMBER,
                        stop_scn      IN  NUMBER,
                        read_only     IN  NUMBER,
                        stop_time     IN  DATE     DEFAULT NULL,
                        rfile#        IN  NUMBER   DEFAULT NULL,
                        aux_fname     IN  VARCHAR2 DEFAULT NULL,
                        foreign_dbid        IN NUMBER   DEFAULT 0,
                        foreign_create_scn  IN NUMBER   DEFAULT 0,
                        foreign_create_time IN DATE     DEFAULT NULL,
                        plugged_readonly    IN VARCHAR2 DEFAULT 'NO',
                        plugin_scn          IN NUMBER   DEFAULT 0,
                        plugin_reset_scn    IN NUMBER   DEFAULT 0,
                        plugin_reset_time   IN DATE     DEFAULT NULL,
                        create_thread       IN NUMBER   DEFAULT NULL,
                        create_size         IN NUMBER   DEFAULT NULL,
                        con_id              IN NUMBER   DEFAULT 0,
                        pdb_closed          IN NUMBER   DEFAULT 0,
                        pdb_dict_check      IN BOOLEAN  DEFAULT FALSE,
                        pdb_foreign_dbid    IN NUMBER   DEFAULT 0,
                        pdb_foreign_ckp_scn IN NUMBER   DEFAULT 0,
                        pdb_foreign_afn     IN NUMBER   DEFAULT 0)
IS
   local_df_key     NUMBER;
   changedauxname   BOOLEAN;
   local_pdbinc_key NUMBER;
   local_pdb_key    NUMBER;
   existing_file    BOOLEAN;
BEGIN
   IF (dfRec.file# IS NULL) THEN -- assert beginDataFileResync was called
      raise_application_error(-20050, 'Datafile resync not started');
   END IF;
   IF (last_file# >= file#) THEN        -- assert rows passed in ascending
      raise_application_error(-20036, 'Invalid record order');
   END IF;
   last_file# := file#;                 -- for checking next call
   
   IF (plugged_readonly = 'NO' AND create_scn > this_ckp_scn) THEN
      raise_application_error(-20052, 'Invalid datafile create SCN');
   ELSIF (plugged_readonly = 'YES' AND plugin_scn > this_ckp_scn) THEN
      raise_application_error(-20055, 'Invalid datafile plugin SCN');
   END IF;
 
--
--
--
--
--
   WHILE (file# > dfRec.file#) LOOP
      deb('checkDatafile - dropping file#: '||to_char(dfRec.file#));
      dropDf(dfRec.file#, dfRec.create_scn, dfRec.plugin_scn,
             this_ckp_scn, this_ckp_time, dfRec.pdbinc_key);
      incResyncActions(RESYNC_ACTION_DROP, dfRec.file#, dfRec.fname);
      fetchDf;
   END LOOP;
 
   IF (file# < dfRec.file#) THEN
      IF (pdb_dict_check) THEN
         deb('checkDataFile - skipping df needs dictionary check');
      ELSE
         local_pdbinc_key := getPdbInc(greatest(create_scn, plugin_scn),
                                       con_id, local_pdb_key);
--
         deb('checkDatafile - adding file#: '||to_char(file#));
         addDF(file#, fname, create_time, create_scn, blocks, block_size,
               ts#, stop_scn, stop_time, read_only, rfile#, foreign_dbid,
               foreign_create_scn, foreign_create_time, plugged_readonly,
               plugin_scn, plugin_reset_scn, plugin_reset_time,
               create_thread, create_size, local_pdbinc_key,
               local_pdb_key, pdb_closed, pdb_foreign_dbid,
               pdb_foreign_ckp_scn, pdb_foreign_afn);
--
--
--
         IF (aux_fname is not NULL) THEN
           setCloneName(file#, create_scn, aux_fname, NULL, changedauxname, 
                        plugin_scn);
         END IF;
      END IF;
      incResyncActions(RESYNC_ACTION_ADD, file#, fname);
   ELSE -- (file# = dfRec.file#)
      existing_file := FALSE;
 
      IF (create_scn = dfRec.create_scn AND
          plugin_scn = dfRec.plugin_scn) THEN
--
--
         IF (create_time IS NOT NULL AND 
             dfRec.create_time IS NOT NULL AND 
             create_time <> dfRec.create_time) THEN
            raise_application_error(-20053, 'Invalid datafile create time');
         END IF;
         IF (ts# <> dfRec.ts#) THEN
            raise_application_error(-20054, 'Invalid datafile ts#');
         END IF;
 
         existing_file := TRUE;
 
         SELECT DISTINCT df_key INTO local_df_key FROM df 
            WHERE file#        = checkDataFile.file#
              AND create_scn   = checkDataFile.create_scn
              AND plugin_scn   = checkDataFile.plugin_scn
              AND decode(foreign_dbid, 0, checkDataFile.foreign_dbid,
                         foreign_dbid)  = checkDataFile.foreign_dbid
              AND ts#          = checkDataFile.ts#
              AND dbinc_key    = this_dbinc_key;
 
--
--
--
--
         IF (dfRec.create_time IS NULL AND create_time IS NOT NULL) THEN
           UPDATE df
              SET create_time = checkDatafile.create_time 
            WHERE df_key = local_df_key;
            deb('checkDatafile - updated create_time which is NULL');
         END IF;
 
--
--
         IF (fname <> dfRec.fname OR dfRec.fname is NULL) THEN
--
--
--
--
--
           IF (fname = dfRec.clone_fname and dfRec.fname is not null) THEN
              deb('checkDatafile - new datafilename is old auxname');
              setCloneName(dfRec.file#, dfRec.create_scn, dfRec.fname,
                           dfRec.clone_fname, changedauxname,
                           dfRec.plugin_scn);
           END IF;
 
           incResyncActions(RESYNC_ACTION_RENAME, dfRec.file#, fname);
           UPDATE site_dfatt SET
              fname = checkDataFile.fname
           WHERE 
             site_key = this_site_key AND
             df_key   = local_df_key;
 
--
--
           IF sql%rowcount = 0 THEN
              INSERT INTO site_dfatt (df_key, fname, site_key)
              VALUES(local_df_key, checkDataFile.fname, this_site_key);
           END IF;
         END IF;
      END IF;
 
      IF (pdb_dict_check) THEN
         deb('checkDataFile - skipping df needs dictionary check');
      ELSIF (existing_file) THEN
--
--
         IF ((create_thread is not null AND dfRec.create_thread is null) OR
             (create_size is not null AND dfRec.create_size is null)) THEN
           UPDATE df SET
              create_thread    = checkDataFile.create_thread,
              create_size      = checkDataFile.create_size
              WHERE df.df_key  = local_df_key;
         END IF;
 
--
--
         IF foreign_dbid <> 0 AND dfrec.foreign_dbid = 0 THEN
            UPDATE df SET
              foreign_dbid    = checkDataFile.foreign_dbid
              WHERE df.df_key  = local_df_key;
            deb('checkDatafile - foreign_dbid for file#.df_key('||
                local_df_key || ') changed to ' || checkDataFile.foreign_dbid);
         END IF;
 
--
         IF ((blocks <> dfrec.blocks) OR
             (stop_scn <> dfrec.stop_scn) OR
             (stop_scn IS NULL AND dfrec.stop_scn IS NOT NULL) OR
             (stop_scn IS NOT NULL AND dfrec.stop_scn IS NULL) OR
             (pdb_closed <> dfrec.pdb_closed)) THEN
           IF blocks <> dfRec.blocks THEN
              deb('checkDatafile - size changed for file#: '||
                  to_char(file#)||' from '||to_char(dfRec.blocks)||' to '||
                  to_char(blocks));
              incResyncActions(RESYNC_ACTION_RESIZE, dfRec.file#, fname);
           ELSE
              deb('checkDatafile - stopSCN changed for file#: '||
                  to_char(file#)||' from '||
                  nvl(to_char(dfRec.stop_scn), 'NULL')||' to '||
                  nvl(to_char(checkDatafile.stop_scn), 'NULL'));
              incResyncActions(RESYNC_ACTION_CHANGE, dfRec.file#, fname);
           END IF;
 
           UPDATE df SET
              stop_scn     = checkDataFile.stop_scn,
              stop_time    = checkDataFile.stop_time,
              read_only    = checkDataFile.read_only,
              blocks       = checkDataFile.blocks,
              pdb_closed   = checkDataFile.pdb_closed
              WHERE df.dbinc_key  = this_dbinc_key
              AND   df.file#      = dfRec.file#
              AND   df.create_scn = dfRec.create_scn
              AND   df.plugin_scn = dfRec.plugin_scn
              AND   df.pdbinc_key = dfRec.pdbinc_key;
         ELSE
           deb('checkDatafile - stopSCN remains the same for file#: '||
               to_char(file#));
         END IF;
 
--
--
--
         IF (aux_fname is not NULL) THEN
            setCloneName(dfRec.file#, dfRec.create_scn, aux_fname, 
                         dfRec.clone_fname, changedauxname,
                         dfRec.plugin_scn);
            IF changedauxname THEN
               incResyncActions(RESYNC_ACTION_CHANGE, dfRec.file#, fname);
            END IF;
         END IF;
      ELSIF ((case when plugged_readonly = 'NO' then
              create_scn else plugin_scn end) >
             (case when dfRec.plugged_readonly = 'NO' then
              dfRec.create_scn else dfRec.plugin_scn end)) THEN
--
--
--
--
--
--
--
--
--
 
         deb('checkDatafile - file#: '||to_char(file#)||' recreated');
         dropDf(dfRec.file#, dfRec.create_scn, dfRec.plugin_scn,
                this_ckp_scn, this_ckp_time, dfRec.pdbinc_key);
         local_pdbinc_key := getPdbInc(greatest(create_scn, plugin_scn),
                                       con_id, local_pdb_key);
         addDf(file#, fname, create_time, create_scn, blocks, block_size, ts#,
               stop_scn, stop_time, read_only, rfile#, foreign_dbid,
               foreign_create_scn, foreign_create_time, plugged_readonly,
               plugin_scn, plugin_reset_scn, plugin_reset_time,
               create_thread, create_size, local_pdbinc_key,
               local_pdb_key, pdb_closed, pdb_foreign_dbid,
               pdb_foreign_ckp_scn, pdb_foreign_afn);
         incResyncActions(RESYNC_ACTION_RECREATE, dfRec.file#, fname);
      ELSE -- (create_scn < dfRec.create_scn)
--
--
--
--
--
         IF (plugged_readonly = 'NO') THEN
            raise_application_error(-20052, 'Invalid datafile create SCN');
         ELSE
            raise_application_error(-20055, 'Invalid datafile plugin SCN');
         END IF;
      END IF;
 
      fetchDF;                          -- get next row from DF cursor
 
   END IF; -- (file# < dfRec.file#)
END checkDataFile;
 
 
PROCEDURE endDataFileResync IS
 
BEGIN
  checkResync;
 
--
  WHILE (dfRec.file# < MAXNUMVAL) LOOP
--
    dropDf(dfRec.file#, dfRec.create_scn, dfRec.plugin_scn,
           this_ckp_scn, this_ckp_time, dfRec.pdbinc_key);
    begin
       incResyncActions(RESYNC_ACTION_DROP, dfRec.file#, dfRec.fname);
    exception
       when others then
           deb('endTableSpaceResync(DO_NOT_IGNORE) - caugth exception ' ||
               substr(sqlerrm, 1, 132));
    end;
    fetchDf;
  END LOOP;
 
--
  dfRec.file# := NULL;
 
--
  UPDATE node SET high_df_recid = last_df_recid
  WHERE site_key = this_site_key;
 
--
  IF this_is_ors and this_ckp_type = 'FULL' THEN
     UPDATE watermarks SET high_df_recid = last_df_recid
     WHERE db_key = this_db_key;
  END IF;
 
  last_df_recid := NULL;
END endDataFileResync;
 
/*-----------------*
 * Tempfile Resync *
 *-----------------*/
 
PROCEDURE fetchTf IS                    -- private to package body
BEGIN
--
  IF tfRec.file# = MAXNUMVAL THEN
     return;
  END IF;
 
  FETCH tfQ INTO tfRec;
  IF tfQ%NOTFOUND THEN
    tfRec.file# := MAXNUMVAL;           -- indicate end-of-fetch
    CLOSE tfQ;
  END IF;
END fetchTf;
 
PROCEDURE addTf(file#          IN NUMBER,  -- private to package body
                fname          IN VARCHAR2,
                create_time    IN DATE,
                create_scn     IN NUMBER,
                blocks         IN NUMBER,
                block_size     IN NUMBER,
                ts#            IN NUMBER,
                rfile#         IN NUMBER,
                autoextend     IN VARCHAR2,
                max_size       IN NUMBER,
                next_size      IN NUMBER,
                con_id         IN NUMBER) IS
   ts_create_scn NUMBER;
   ts_pdbinc_key NUMBER;
   local_tf_key  NUMBER;
   local_pdb_key NUMBER;
BEGIN
   SELECT pdb.pdb_key INTO local_pdb_key
     FROM pdb, pdb_dbinc
    WHERE pdb_dbinc.drop_scn IS NULL
      AND pdb.con_id          = addTf.con_id
      AND pdb.pdb_key         = pdb_dbinc.pdb_key
      AND pdb_dbinc.dbinc_key = this_dbinc_key;
 
   BEGIN
     SELECT ts.create_scn, ts.pdbinc_key
       INTO ts_create_scn, ts_pdbinc_key
     FROM ts, rci_pdbinc_this_dbinc pdbinc
     WHERE ts.dbinc_key = this_dbinc_key
       AND ts.ts# = addTf.ts#
       AND ts.pdbinc_key = pdbinc.pdbinc_key
       AND pdbinc.pdb_key = local_pdb_key
       AND pdbinc.dbinc_key = this_dbinc_key
       AND ts.create_scn  < pdbinc.next_inc_scn
       AND ts.drop_scn IS NULL;            -- in case ts numbers are reused
   EXCEPTION
     WHEN no_data_found THEN
--
--
--
       IF (this_cf_type = 'STANDBY' AND this_db_unique_name is not null) THEN
         RETURN;
       END IF;
   END;
   deb('ts_create_scn=' || ts_create_scn);
 
--
--
  BEGIN
    SELECT DISTINCT tf.tf_key INTO local_tf_key 
    FROM tf, dbinc
    WHERE tf.file#        = addTf.file#
      AND tf.create_scn   = addTf.create_scn
      AND (tf.create_time = addTf.create_time
           OR tf.create_time IS NULL AND addTf.create_time IS NULL)
      AND  tf.ts#         = addTf.ts#
      AND  tf.rfile#      = addTf.rfile#
      AND  tf.dbinc_key   = dbinc.dbinc_key
      AND  dbinc.db_key   = this_db_key;
   EXCEPTION
    WHEN no_data_found THEN
      SELECT rman_seq.nextval INTO local_tf_key FROM dual;
  END;
 
  BEGIN
    INSERT INTO tf(dbinc_key, file#, create_scn, create_time,
                   ts#, ts_create_scn, block_size, rfile#, tf_key, pdb_key,
                   ts_pdbinc_key)
    VALUES(this_dbinc_key, file#, create_scn, create_time, ts#, ts_create_scn,
           block_size, rfile#, local_tf_key, local_pdb_key, ts_pdbinc_key);
  EXCEPTION
    WHEN dup_val_on_index THEN
--
--
--
      IF create_scn = 0 THEN
        UPDATE tf SET 
           create_time   = addTf.create_time,
           ts#           = addTf.ts#,
           ts_create_scn = addTf.ts_create_scn,
           block_size    = addTf.block_size,
           rfile#        = addTf.rfile#,
           pdb_key       = local_pdb_key
        WHERE dbinc_key  = this_dbinc_key
          AND file#      = addTf.file#
          AND create_scn = addTf.create_scn;
      END IF;
 
--
--
--
--
--
--
--
--
--
--
--
  END;
 
--
--
--
  BEGIN
    INSERT INTO site_tfatt(tf_key, fname, site_key, blocks,
          autoextend, max_size, next_size)
    VALUES(local_tf_key, fname, this_site_key, nvl(addTf.blocks, 0),
           addTf.autoextend, addTf.max_size, addTf.next_size);
--
  EXCEPTION
    WHEN dup_val_on_index THEN
--
      UPDATE site_tfatt SET
        fname = addTf.fname,
        blocks     = nvl(addTf.blocks, 0),
        autoextend = addTf.autoextend,
        max_size   = addTf.max_size,
        next_size  = addTf.next_size,
        drop_scn   = NULL,
        drop_time  = NULL
      WHERE site_key = this_site_key
        AND tf_key   = local_tf_key;      
  END;
END addTf;
 
PROCEDURE dropTf(                       -- private to package body
  tf_key IN NUMBER
 ,drop_scn IN NUMBER
 ,drop_time IN DATE
) IS
 
BEGIN
  UPDATE site_tfatt SET
    drop_scn     = dropTf.drop_scn,
    drop_time    = dropTf.drop_time
  WHERE this_site_key = site_key
    AND tf_key = dropTf.tf_key;
END dropTf;
 
FUNCTION tempFileToResync(
   high_tf_recid IN NUMBER
) RETURN BOOLEAN IS
   tf_recid  number;
BEGIN
  checkResync;
 
  SELECT high_tf_recid INTO tf_recid
  FROM node
  WHERE site_key = this_site_key;
 
  IF (high_tf_recid = tf_recid) THEN
    RETURN FALSE;
  ELSIF (high_tf_recid > tf_recid OR tf_recid IS NULL) THEN
    RETURN TRUE;
  ELSE
    raise_application_error(-20035, 'Invalid high recid');
  END IF;
END tempFileToResync;
 
--
--
--
FUNCTION beginTempFileResyncForStandby(
  high_tf_recid IN NUMBER
) RETURN BOOLEAN IS
BEGIN
  RETURN beginTempFileResync (high_tf_recid);
END beginTempFileResyncForStandby;
 
--
--
--
--
--
--
--
--
PROCEDURE checkTempFileForStandby
                       (file#          IN  NUMBER,
                        fname          IN  VARCHAR2,
                        create_scn     IN  NUMBER,
                        create_time    IN  DATE,
                        blocks         IN  NUMBER,
                        block_size     IN  NUMBER,
                        ts#            IN  NUMBER,
                        rfile#         IN  NUMBER,
                        autoextend     IN  VARCHAR2,
                        max_size       IN  NUMBER,
                        next_size      IN  NUMBER,
                        con_id         IN  NUMBER DEFAULT 0)
IS
   local_tf_key NUMBER;
BEGIN
    checkTempFile(file#, fname, create_scn, create_time, blocks, block_size,
                  ts#, rfile#, autoextend, max_size, next_size, con_id, FALSE);
END checkTempFileForStandby;
 
PROCEDURE endTempFileResyncForStandby IS
BEGIN
  endTempFileResync;
END endTempFileResyncForStandby;
 
 
FUNCTION beginTempFileResync(
  high_tf_recid IN NUMBER
) RETURN BOOLEAN IS
 
BEGIN
  checkResync;
 
  IF (tsRec.ts# IS NOT NULL) THEN
    raise_application_error(-20041, 'Tablespace resync not completed');
  END IF;
 
  SELECT high_tf_recid INTO last_tf_recid
  FROM node
  WHERE site_key = this_site_key;
 
  IF (high_tf_recid = last_tf_recid) THEN
    deb('beginTempFileResync - Resync of tempfiles not needed');
    RETURN FALSE;
  ELSIF (high_tf_recid > last_tf_recid OR last_tf_recid IS NULL) THEN
    deb('beginTempFileResync - Catalog tf_recid: '||last_tf_recid);
    deb('beginTempFileResync - High tf_recid: '||high_tf_recid);
    last_tf_recid := high_tf_recid;
 
    OPEN tfQ;
    fetchTf;                            -- do priming read
    last_file# := -1;                   -- initialize for ordering assert
 
    if resync_reason = RESYNC_REASON_TF then
      fullResyncAction.active  := TRUE;
      fullResyncAction.valid   := TRUE;
      fullResyncAction.objtype := RESYNC_OBJECT_TEMPFILE;
    else
      fullResyncAction.active  := FALSE;
    end if;
 
    RETURN TRUE;
  ELSE
    raise_application_error(-20035, 'Invalid high recid');
  END IF;
 
END beginTempFileResync;
 
PROCEDURE checkTempFile(file#          IN  NUMBER,
                        fname          IN  VARCHAR2,
                        create_scn     IN  NUMBER,
                        create_time    IN  DATE,
                        blocks         IN  NUMBER,
                        block_size     IN  NUMBER,
                        ts#            IN  NUMBER,
                        rfile#         IN  NUMBER,
                        autoextend     IN  VARCHAR2,
                        max_size       IN  NUMBER,
                        next_size      IN  NUMBER,
                        con_id         IN  NUMBER  DEFAULT 0,
                        pdb_dict_check IN  BOOLEAN DEFAULT FALSE)
IS
   local_tf_key     NUMBER;
BEGIN
   IF (tfRec.file# IS NULL) THEN -- assert beginTempFileResync was called
      raise_application_error(-20050, 'Tempfile resync not started');
   END IF;
   IF (last_file# >= file#) THEN        -- assert rows passed in ascending
      raise_application_error(-20036, 'Invalid record order');
   END IF;
   last_file# := file#;                 -- for checking next call
 
--
--
--
--
 
--
--
--
--
--
   WHILE (file# > tfRec.file#) LOOP
      dropTf(tfRec.tf_key, this_ckp_scn, this_ckp_time);
      incResyncActions(RESYNC_ACTION_DROP, tfRec.file#, tfRec.fname);
      fetchTf;
   END LOOP;
 
   IF (file# < tfRec.file#) THEN
      IF (pdb_dict_check) THEN
         deb('checkTempFile - skipping tf needs dictionary check');
      ELSE 
         addTf(file#, fname, create_time, create_scn, blocks, block_size, ts#,
               rfile#, autoextend, max_size, next_size, con_id);
      END IF;
      incResyncActions(RESYNC_ACTION_ADD, tfRec.file#, fname);
   ELSE -- (file# = tfRec.file#)
      IF (pdb_dict_check) THEN
         deb('checkTempFile - skipping tf needs dictionary check');
      ELSIF (create_scn = 0) THEN
         addTf(file#, fname, create_time, create_scn, blocks, block_size, ts#,
               rfile#, autoextend, max_size, next_size, con_id);
         incResyncActions(RESYNC_ACTION_CHANGE, file#, fname);
      ELSIF (create_scn = tfRec.create_scn) THEN
--
--
         IF (create_time <> tfRec.create_time) THEN
            raise_application_error(-20053, 'Invalid tempfile create time');
         END IF;
         IF (ts# <> tfRec.ts#) THEN
            raise_application_error(-20054, 'Invalid tempfile ts#');
         END IF;
 
--
         addTf(file#, fname, create_time, create_scn, blocks, block_size, ts#,
               rfile#, autoextend, max_size, next_size, con_id);
 
         IF (fname <> tfRec.fname OR tfRec.fname is NULL) THEN
            incResyncActions(RESYNC_ACTION_RENAME, file#, fname);
         END IF;
 
--
--
         IF (blocks <> tfrec.blocks OR
             autoextend <> tfrec.autoextend OR
             max_size <> tfrec.max_size OR
             next_size <> tfrec.next_size ) THEN
           IF blocks <> tfrec.blocks THEN
              incResyncActions(RESYNC_ACTION_RESIZE, file#, fname);
           ELSE
              incResyncActions(RESYNC_ACTION_CHANGE, file#, fname);
           END IF;
         END IF;
      ELSE
--
--
--
--
--
--
         dropTf(tfRec.tf_key, create_scn, create_time);
         addTf(file#, fname, create_time, create_scn, blocks, block_size, ts#,
               rfile#, autoextend, max_size, next_size, con_id);
         incResyncActions(RESYNC_ACTION_RECREATE, file#, fname);
      END IF;
 
      fetchTf;                          -- get next row from Tf cursor
 
   END IF; -- (file# = tfRec.file#)
   
END checkTempFile;
 
 
PROCEDURE endTempFileResync IS
 
BEGIN
  checkResync;
 
--
  deb('endTempFileResync - entering with tempfile number'||tfRec.file#);
  WHILE (tfRec.file# < MAXNUMVAL) LOOP
    dropTf(tfRec.tf_key, this_ckp_scn, this_ckp_time);
    incResyncActions(RESYNC_ACTION_DROP, tfRec.file#, tfRec.fname);
    fetchTf;
    deb('endTempFileResync - dropping tempfile '||tfRec.file#);
  END LOOP;
 
--
  tfRec.file# := NULL;
 
--
  UPDATE node SET high_tf_recid = last_tf_recid
  WHERE site_key = this_site_key;
 
--
  IF this_is_ors and this_ckp_type = 'FULL' THEN
     UPDATE watermarks SET high_tf_recid = last_tf_recid
     WHERE db_key = this_db_key;
  END IF;
 
  last_tf_recid := NULL;
 
END endTempFileResync;
 
/*---------------------*
 * Redo Thread resync  *
 *---------------------*/
 
PROCEDURE fetchRt IS
 
BEGIN
  FETCH rtQ INTO rtRec;
  IF rtQ%NOTFOUND THEN
    rtRec.thread# := MAXNUMVAL;
    CLOSE rtQ;
  END IF;
END fetchRt;
 
PROCEDURE addRt(
  thread#        IN NUMBER
 ,last_sequence# IN NUMBER
 ,enable_scn     IN NUMBER
 ,enable_time    IN DATE
 ,disable_scn    IN NUMBER
 ,disable_time   IN DATE
 ,status         IN VARCHAR2
) IS
 
BEGIN
  INSERT INTO rt
    (dbinc_key, thread#, sequence#,
     enable_scn, enable_time, disable_scn, disable_time, status)
  VALUES
    (this_dbinc_key, thread#, last_sequence#,
     enable_scn, enable_time, disable_scn, disable_time, status);
END addRt;
 
PROCEDURE dropRt(thread# IN NUMBER) IS
BEGIN
--
  DELETE FROM rt
  WHERE rt.dbinc_key = this_dbinc_key
  AND   rt.thread#   = dropRt.thread#;
END dropRt;
 
FUNCTION beginThreadResync(
  high_rt_recid IN NUMBER
) RETURN BOOLEAN IS
 
BEGIN
  checkResync;
 
  SELECT high_rt_recid INTO last_rt_recid
  FROM node
  WHERE site_key = this_site_key;
 
  IF (high_rt_recid = last_rt_recid) THEN
    deb('beginThreadResync - Resync of redo threads not needed');
    RETURN FALSE;
  ELSIF (high_rt_recid > last_rt_recid OR last_rt_recid IS NULL) THEN
    deb('beginThreadResync - Catalog rt_recid: '||last_rt_recid);
    deb('beginThreadResync - High rt_recid: '||high_rt_recid);
    last_rt_recid := high_rt_recid;
 
    OPEN rtQ;
    fetchRt;                            -- do priming read
    last_thread# := -1;
 
    if resync_reason = RESYNC_REASON_THR then
      fullResyncAction.valid   := TRUE;
      fullResyncAction.active  := TRUE;
      fullResyncAction.objtype := RESYNC_OBJECT_REDOTHREAD;
    else
      fullResyncAction.active  := FALSE;
    end if;
 
    RETURN TRUE;
  ELSE
    raise_application_error(-20035, 'Invalid high recid');
  END IF;
 
END beginThreadResync;
 
PROCEDURE checkThread(
  thread#        IN NUMBER
 ,last_sequence# IN NUMBER
 ,enable_scn     IN NUMBER
 ,enable_time    IN DATE
 ,disable_scn    IN NUMBER
 ,disable_time   IN DATE
 ,status         IN VARCHAR2
) IS
 
BEGIN
  IF (rtRec.thread# IS NULL) THEN
    raise_application_error(-20061, 'Thread resync not started');
  END IF;
  IF (last_thread# >= thread#) THEN
    raise_application_error(-20036, 'Invalid record order');
  END IF;
  last_thread# := thread#;
 
  WHILE (thread# > rtRec.thread#) LOOP
--
--
--
    dropRt(rtRec.thread#);
    incResyncActions(RESYNC_ACTION_DROP, rtRec.thread#, to_char(NULL));
    fetchRt;
  END LOOP;
  IF (thread# < rtRec.thread#) THEN
--
    addRt(thread#, last_sequence#, enable_scn, enable_time,
          disable_scn, disable_time, status);
    incResyncActions(RESYNC_ACTION_ADD, thread#, to_char(NULL));
  ELSE -- (thread# = rtRec.thread#)
--
    UPDATE rt SET
      sequence# = checkThread.last_sequence#,
      enable_scn = checkThread.enable_scn,
      enable_time = checkThread.enable_time,
      disable_scn = checkThread.disable_scn,
      disable_time = checkThread.disable_time,
      status = checkThread.status
    WHERE rt.dbinc_key = this_dbinc_key
    AND   rt.thread# = checkThread.thread#;
    incResyncActions(RESYNC_ACTION_CHANGE, rtRec.thread#, to_char(NULL));
    fetchRt;
  END IF;
 
END checkThread;
 
PROCEDURE endThreadResync IS
BEGIN
  WHILE (rtRec.thread# < MAXNUMVAL) LOOP
--
--
--
    dropRt(rtRec.thread#);
    fetchRt;
  END LOOP;
 
  rtRec.thread# := NULL;
 
--
  UPDATE node SET high_rt_recid = last_rt_recid
  WHERE site_key = this_site_key;
 
  last_rt_recid := NULL;
END endThreadResync;
 
/*------------------------*
 * Online Redo Log resync *
 *------------------------*/
 
--
--
--
--
--
--
--
--
--
--
FUNCTION nlsnamecmp(n1 IN varchar2, n2 IN varchar2) RETURN NUMBER IS
  CURSOR nlsnamecmp_c(n1 varchar2, n2 varchar2) IS
     SELECT name
       FROM (SELECT n1 name FROM dual
             UNION ALL
             SELECT n2 name FROM dual)
      ORDER BY nlssort(name, 'NLS_COMP=ANSI NLS_SORT=ASCII7');
  ln1  varchar2(1024);
  ln2  varchar2(1024);
BEGIN
  if (n1 is null or n2 is null) then
     return null;
  elsif (n1 = n2) then
     return 0;
  elsif (n1 = chr(1) or n2 = chr(255)) then
     return -1;
  elsif (n2 = chr(1) or n1 = chr(255)) then
     return 1;
  end if;
 
  open nlsnamecmp_c(n1, n2);
  fetch nlsnamecmp_c into ln1;
  fetch nlsnamecmp_c into ln2;
  close nlsnamecmp_c;
  if (ln1 = n1) then
     return -1;
  end if;
  return 1;
END nlsnamecmp;
 
PROCEDURE fetchOrl IS
 
BEGIN
  FETCH orlQ INTO orlRec;
  IF orlQ%NOTFOUND THEN
    orlRec.fname := chr(255);      -- assume chr(255) is greater than any name
    CLOSE orlQ;
  END IF;
END fetchOrl;
 
PROCEDURE addOrl(
  thread#        IN NUMBER
 ,group#         IN NUMBER
 ,fname          IN VARCHAR2
 ,bytes          IN NUMBER
 ,type           IN VARCHAR2
) IS
  thread_not_found EXCEPTION;
  PRAGMA EXCEPTION_INIT(thread_not_found, -2291);
BEGIN
  INSERT INTO orl
    (dbinc_key, thread#, group#, fname, bytes, type, site_key)
  VALUES
    (this_dbinc_key, thread#, group#, fname, bytes, type, this_site_key);
EXCEPTION
  WHEN thread_not_found THEN
--
--
    IF type <> 'STANDBY' THEN
       raise_application_error(-20079,
             'full resync from primary database is not done');
    ELSE
       deb('ignored resync of standby redo log ' || fname);
    END IF;
END addOrl;
 
PROCEDURE dropOrl(fname IN VARCHAR2) IS
BEGIN
--
  DELETE FROM orl
  WHERE orl.dbinc_key = this_dbinc_key
  AND   orl.site_key  = this_site_key
  AND   orl.fname     = dropOrl.fname;
END dropOrl;
 
FUNCTION beginOnlineRedoLogResync(
  high_orl_recid IN NUMBER
) RETURN BOOLEAN IS
 
BEGIN
  checkResync;
 
  SELECT high_orl_recid INTO last_orl_recid
  FROM node
  WHERE site_key = this_site_key;
 
  IF (high_orl_recid = last_orl_recid) THEN
    deb('beginOnlineRedoLogResync - Resync of online logs not needed');
    RETURN FALSE;
  ELSIF (high_orl_recid > last_orl_recid OR last_orl_recid IS NULL) THEN
    deb('beginOnlineRedoLogResync - Catalog orl_recid: '||last_orl_recid);
    deb('beginOnlineRedoLogResync - High orl_recid: '||high_orl_recid);
    last_orl_recid := high_orl_recid;
 
    OPEN orlQ;
    fetchOrl;
    last_fname := chr(1);           -- assume chr(1) is less than any name
 
    if resync_reason = RESYNC_REASON_ORL then
      fullResyncAction.active  := TRUE;
      fullResyncAction.valid   := TRUE;
      fullResyncAction.objtype := RESYNC_OBJECT_ONLINELOG;
    else
      fullResyncAction.active := FALSE;
    end if;
 
    RETURN TRUE;
  ELSE
    raise_application_error(-20035, 'Invalid high recid');
  END IF;
END beginOnlineRedoLogResync;
 
PROCEDURE checkOnlineRedoLog(
  thread#        IN NUMBER
 ,group#         IN NUMBER
 ,fname          IN VARCHAR2
 ,bytes          IN NUMBER   DEFAULT NULL
 ,type           IN VARCHAR2 DEFAULT 'ONLINE'
) IS
BEGIN
  IF (orlRec.fname IS NULL) THEN
    raise_application_error(-20061, 'Redo resync not started');
  END IF;
  IF (nlsnamecmp(last_fname, fname) >= 0) THEN
    raise_application_error(-20036, 'Invalid record order');
  END IF;
  last_fname := fname;
 
  WHILE (nlsnamecmp(fname, orlRec.fname) > 0) LOOP
--
--
--
    dropOrl(orlRec.fname);
    incResyncActions(RESYNC_ACTION_DROP, to_number(NULL), orlRec.fname);
    fetchOrl;
  END LOOP;
  IF (nlsnamecmp(fname, orlRec.fname) < 0) THEN
--
    addOrl(thread#, group#, fname, bytes, type);
    incResyncActions(RESYNC_ACTION_ADD, to_number(NULL), fname);
  ELSE -- (fname = orlRec.fname)
    UPDATE orl SET
      thread# = checkOnlineRedoLog.thread#,
      group#  = checkOnlineRedoLog.group#,
      bytes   = checkOnlineRedoLog.bytes,
      type    = checkOnlineRedoLog.type
    WHERE orl.dbinc_key = this_dbinc_key
    AND   orl.fname = checkOnlineRedoLog.fname
    AND   orl.site_key = this_site_key;
    incResyncActions(RESYNC_ACTION_CHANGE, to_number(NULL), orlRec.fname);
    fetchOrl;
  END IF;
END checkOnlineRedoLog;
 
PROCEDURE endOnlineRedoLogResync IS
BEGIN
  WHILE (orlRec.fname != chr(255)) LOOP
--
--
--
    dropOrl(orlRec.fname);
    incResyncActions(RESYNC_ACTION_DROP, to_number(NULL), orlRec.fname);
    fetchOrl;
  END LOOP;
 
  orlRec.fname := NULL;
 
--
  UPDATE node SET high_orl_recid = last_orl_recid
  WHERE site_key = this_site_key;
 
  last_orl_recid := NULL;
END endOnlineRedoLogResync;
 
/*---------------------------------*
 * Guaranteed restore point Resync *
 *---------------------------------*/
 
PROCEDURE fetchGrsp IS
BEGIN
  FETCH grspQ INTO grspRec;
  IF grspQ%NOTFOUND THEN
    grspRec.rspname := chr(255);  -- assume chr(255) is greater than any name
    grspRec.pdb_key := null;
    CLOSE grspQ;
  END IF;
END fetchGrsp;
 
PROCEDURE addGrsp(
  rspname        IN VARCHAR2
 ,from_scn       IN NUMBER
 ,to_scn         IN NUMBER
 ,dbinc_key      IN NUMBER
 ,create_time    IN DATE
 ,rsp_time       IN DATE
 ,guaranteed     IN VARCHAR2
 ,pdb_key        IN NUMBER
 ,clean          IN VARCHAR2
) IS
 
BEGIN
  INSERT INTO grsp
    (dbinc_key, rspname, from_scn, to_scn, creation_time, rsptime, 
     guaranteed, site_key, pdb_key, clean)
  VALUES
    (dbinc_key, rspname, from_scn, to_scn, create_time, rsp_time,
     guaranteed, this_site_key, pdb_key, clean);
END addGrsp;
 
PROCEDURE dropGrsp(
  rspname   IN VARCHAR2
 ,pdb_key   IN NUMBER) IS
BEGIN
  DELETE FROM grsp
  WHERE grsp.rspname = dropGrsp.rspname
    AND grsp.site_key = this_site_key
    AND grsp.pdb_key = dropGrsp.pdb_key;
END dropGrsp;
 
FUNCTION beginGuaranteedRPResync(
  high_grsp_recid IN NUMBER
) RETURN BOOLEAN IS
BEGIN
  checkResync;
 
  SELECT node.high_grsp_recid INTO last_grsp_recid
  FROM node
  WHERE site_key = this_site_key;
 
  IF (high_grsp_recid = last_grsp_recid) THEN
    RETURN FALSE;
  ELSIF (high_grsp_recid > last_grsp_recid OR last_grsp_recid IS NULL) THEN
    last_grsp_recid := high_grsp_recid;
 
    OPEN grspQ;
    fetchGrsp;
    last_rspname := chr(1);           -- assume chr(1) is less than any name
    last_pdb_key := -1;
    RETURN TRUE;
  ELSE
    raise_application_error(-20035, 'Invalid high recid');
  END IF;
 
END beginGuaranteedRPResync;
 
PROCEDURE checkGuaranteedRP(
  rspname            IN VARCHAR2
 ,from_scn           IN NUMBER
 ,to_scn             IN NUMBER
 ,resetlogs_change#  IN NUMBER
 ,resetlogs_time     IN DATE
 ,create_time        IN DATE DEFAULT NULL
 ,rsp_time           IN DATE DEFAULT NULL
 ,guaranteed         IN VARCHAR2 DEFAULT 'YES'
 ,con_id             IN NUMBER   DEFAULT NULL
 ,clean              IN VARCHAR2 DEFAULT 'NO'
) IS
   my_dbinc_key  number;
   local_pdb_key number;
BEGIN
  IF (grspRec.rspname IS NULL) THEN
    raise_application_error(-20099, 'restore point resync not started');
  END IF;
 
  my_dbinc_key := checkIncarnation(resetlogs_change#, resetlogs_time);
 
--
--
  deb('checkGuaranteedRP - con_id=' || con_id);
  SELECT pdb.pdb_key INTO local_pdb_key
    FROM pdb, pdb_dbinc
   WHERE pdb_dbinc.drop_scn IS NULL
     AND pdb.con_id IN
         (checkGuaranteedRP.con_id,
          0, 
          decode(nvl(checkGuaranteedRP.con_id, 0), 0, 1))
     AND pdb.pdb_key         = pdb_dbinc.pdb_key
     AND pdb_dbinc.dbinc_key = my_dbinc_key;
  deb('checkGuaranteedRP - local_pdb_key=' || local_pdb_key);
 
  IF (nlsnamecmp(last_rspname, rspname) >= 0 AND
      (last_pdb_key = local_pdb_key)) THEN
    raise_application_error(-20036, 'Invalid record order');
  END IF;
  last_rspname := rspname;
  last_pdb_key := local_pdb_key;
 
  WHILE (grspRec.pdb_key != local_pdb_key) LOOP
--
--
--
    dropGrsp(grspRec.rspname, grspRec.pdb_key);
    fetchGrsp;
  END LOOP;
 
  WHILE (grspRec.pdb_key = local_pdb_key AND
         nlsnamecmp(rspname, grspRec.rspname) > 0) LOOP
--
--
--
    dropGrsp(grspRec.rspname, grspRec.pdb_key);
    fetchGrsp;
  END LOOP;
 
  IF (grspRec.pdb_key != local_pdb_key OR
      nlsnamecmp(rspname, grspRec.rspname) < 0) THEN
--
    addGrsp(rspname, from_scn, to_scn, my_dbinc_key, create_time, rsp_time,
            guaranteed, local_pdb_key, clean);
  ELSE -- (rspname = grspRec.rspname)
--
    UPDATE grsp SET
      from_scn = checkGuaranteedRP.from_scn,
      to_scn = checkGuaranteedRP.to_scn,
      rsptime = checkGuaranteedRP.rsp_time,
      guaranteed = checkGuaranteedRP.guaranteed,
      dbinc_key = my_dbinc_key
    WHERE grsp.rspname = checkGuaranteedRP.rspname
      AND grsp.site_key = this_site_key
      AND grsp.pdb_key = local_pdb_key;
 
    fetchGrsp;
  END IF;
END checkGuaranteedRP;
 
PROCEDURE endGuaranteedRPResync IS
BEGIN
  WHILE (grspRec.rspname != chr(255)) LOOP
--
--
    dropGrsp(grspRec.rspname, grspRec.pdb_key);
    fetchGrsp;
  END LOOP;
 
  grspRec.rspname := NULL;
   
--
  UPDATE node SET high_grsp_recid = last_grsp_recid
  WHERE site_key = this_site_key;
      
  last_grsp_recid := NULL;
END endGuaranteedRPResync;
 
 
/*-----------------------------------*
 * RMAN Configuration records resync *
 *-----------------------------------*/
 
FUNCTION beginConfigResync(
  high_conf_recid IN NUMBER
) RETURN NUMBER IS
 
BEGIN
  checkResync;
 
  SELECT high_conf_recid INTO last_conf_recid
  FROM   node
  WHERE  site_key = this_site_key;
 
  IF (high_conf_recid = last_conf_recid)
  THEN
    RETURN CONFIGRESYNC_NO;                                -- no resync needed
  ELSIF (last_conf_recid IS NULL OR high_conf_recid > last_conf_recid)
  THEN
    last_conf_recid := high_conf_recid;
    RETURN CONFIGRESYNC_TORC;                   -- we need resync from CF to RC
  ELSE
    last_conf_recid := high_conf_recid;
    RETURN CONFIGRESYNC_TOCF;                   -- we need resync from RC to CF
  END IF;
 
END beginConfigResync;
 
PROCEDURE endConfigResync IS
BEGIN
 
--
  UPDATE node SET high_conf_recid = last_conf_recid
  WHERE site_key = this_site_key;
 
  last_conf_recid := NULL;
 
END endConfigResync;
 
FUNCTION beginConfigResync2(
  high_conf_recid IN     NUMBER
) RETURN NUMBER IS
  to_CF                 boolean := FALSE;
  to_Catalog            boolean := FALSE;
  local_force_resync2cf VARCHAR2(3) := 'NO';
  curr_cf_version_time  DATE;
  conf_count            NUMBER;
BEGIN
 
  checkResync;
 
  SELECT node.high_conf_recid, node.force_resync2cf, cf_create_time
  INTO   last_conf_recid,      local_force_resync2cf, curr_cf_version_time
  FROM   node
  WHERE  site_key = this_site_key;
 
--
  IF (local_force_resync2cf = 'YES')
  THEN
     to_CF := TRUE;
  END IF;
 
--
--
  IF (last_cf_version_time is NULL) THEN
     SELECT COUNT(*) INTO conf_count FROM CONF
        WHERE site_key = this_site_key;
     IF conf_count = 0 THEN
        to_Catalog := TRUE;
     END IF;
  END IF;
 
--
--
--
--
  IF (last_cf_version_time <> curr_cf_version_time) THEN
     IF (this_cf_type = 'CURRENT') THEN
        IF high_conf_recid > last_conf_recid THEN
           to_Catalog := TRUE;
        ELSIF (high_conf_recid < last_conf_recid) THEN
           to_CF := TRUE;
        END IF;
     ELSE
        to_CF := TRUE;
     END IF;
  END IF;
 
--
--
--
--
--
  IF (last_cf_version_time = curr_cf_version_time) THEN
     IF (high_conf_recid > last_conf_recid) THEN
        to_Catalog := TRUE;
     ELSIF (high_conf_recid < last_conf_recid) THEN
        to_CF := TRUE;
     END IF;
  END IF;
 
--
--
  IF (NOT to_Catalog AND NOT to_CF)
  THEN
     RETURN CONFIGRESYNC_NO;
  END IF;
 
--
--
  last_conf_recid     := high_conf_recid;
 
--
  IF (NOT to_Catalog AND to_CF) THEN
     RETURN CONFIGRESYNC_TOCF;
  END IF;
 
--
  IF (to_Catalog AND NOT to_CF) THEN
     RETURN CONFIGRESYNC_TORC;
  END IF;
 
--
--
  IF (to_Catalog AND to_CF) THEN
     RETURN CONFIGRESYNC_TORC_TOCF;
  END IF;
 
END beginConfigResync2;
 
PROCEDURE endConfigResync2(sync_to_cf_pending IN boolean DEFAULT FALSE) IS
   cf_pending number := 0;
BEGIN
 
  IF sync_to_cf_pending THEN
    cf_pending := 1;
  END IF;
 
  IF (force_resync2cf = 'YES') THEN
    deb('endConfigResync2 - force_resync2cf = TRUE');
--
--
    UPDATE node SET node.force_resync2cf = 'YES'
      WHERE node.db_key = this_db_key
        AND site_key <> this_site_key;
  END IF;
 
--
--
--
--
--
  UPDATE node SET node.high_conf_recid = last_conf_recid,
                  node.force_resync2cf = decode(cf_pending, 1, 'YES', 'NO')
  WHERE site_key = this_site_key;
 
  deb('endConfigResync2 - last_conf_recid='||last_conf_recid);
 
  force_resync2cf := 'NO';
  last_conf_recid := NULL;
 
END endConfigResync2;
 
PROCEDURE getConfig(
   conf#          OUT    number
  ,name           IN OUT varchar2
  ,value          IN OUT varchar2
  ,first          IN     boolean)
IS
   eof          boolean := FALSE;
BEGIN
 
--
--
   dbms_rcvman.getConfig(conf#, name, value, first);
 
END getConfig;
 
PROCEDURE getRmanOutputLogging(days OUT number)
IS
  conf_value             varchar2(512);
  conf_name              varchar2(512) := 'RMAN OUTPUT';
  conf#                  binary_integer;
  len1                   binary_integer;
  len2                   binary_integer;
  len3                   binary_integer;
BEGIN
  deb('Entering getRmanOutputLogging');
  days := 0;
  dbms_rcvman.getConfig(conf#, conf_name, conf_value, TRUE);
 
  len1 := length('TO KEEP FOR ');
  len2 := length(' DAYS');
  len3 := length(conf_value);
  days := to_number(substr(conf_value, len1, len3-len2-len1+1));
  deb('getRmanOutputLogging - days = '||days);
 
EXCEPTION
  WHEN no_data_found THEN
    deb('getRmanOutputLogging - config not set, taking default');
    days := 7;
 
END getRmanOutputLogging;
 
PROCEDURE setKeepOutputForSession(days IN number)
IS
BEGIN
  deb('setKeepOutputForSession - session_keep_output = ' || days);
  session_keep_output := days;
END setKeepOutputForSession;
 
PROCEDURE updateRestorePoint(
  lowscn  IN NUMBER
 ,highscn IN NUMBER DEFAULT NULL -- next scn by another name
) IS
  nextscn number;
  refs number;
BEGIN
--
  IF (highscn is null) THEN
    nextscn := lowscn + 1;
  ELSE
    nextscn := highscn;
  END IF;
 
--
--
  UPDATE nrsp r SET LONG_TERM = NULL
  WHERE r.to_scn >= lowscn AND r.to_scn <= nextscn
    AND r.long_term IS NOT NULL
    AND r.site_key = this_site_key;
  deb('updateRestorePoint - (lowscn ' || lowscn || ' - highscn ' || nextscn ||
      ') rows updated ' || sql%rowcount);
END updateRestorePoint;
 
/*-------------------------*
 * Redo Log History resync *
 *-------------------------*/
 
FUNCTION beginLogHistoryResync RETURN NUMBER IS
 
BEGIN
  checkResync;
 
  IF (this_cf_type = 'CURRENT' OR
      (this_cf_type = 'STANDBY' AND this_db_unique_name is not null)) THEN
--
--
     SELECT high_rlh_recid INTO last_rlh_recid
     FROM node
     WHERE site_key = this_site_key;
  ELSE
     last_rlh_recid := sessionWaterMarks.high_rlh_recid;
  END IF;
 
  RETURN last_rlh_recid;
 
END beginLogHistoryResync;
 
FUNCTION getLogHistoryLowSCN RETURN NUMBER IS
   lowSCN  number;
BEGIN
   checkResync;
   SELECT nvl(max(low_scn), 0)
     INTO lowSCN
     FROM rlh
    WHERE rlh.dbinc_key = this_dbinc_key;
   RETURN lowSCN;
END getLogHistoryLowSCN;
 
PROCEDURE checkLogHistory(
  rlh_recid   IN NUMBER
 ,rlh_stamp   IN NUMBER
 ,thread#     IN NUMBER
 ,sequence#   IN NUMBER
 ,low_scn     IN NUMBER
 ,low_time    IN DATE
 ,next_scn    IN NUMBER
 ,reset_scn   IN number default NULL
 ,reset_time  IN date default NULL
) IS
 
local   rlh%rowtype;
 
BEGIN
  IF (last_rlh_recid IS NULL) THEN
    raise_application_error(-20037, 'Invalid last recid');
  END IF;
 
  IF (rlh_recid < last_rlh_recid) THEN
    raise_application_error(-20036, 'Invalid record order');
  END IF;
 
  IF (rlh_recid > last_rlh_recid + 1) THEN
--
--
    NULL;
  END IF;
  last_rlh_recid := rlh_recid;
 
  IF (last_dbinc_key is NULL or reset_scn is NULL) THEN
     deb('checkLogHistory - Init last_dbinc_key');
     last_dbinc_key := this_dbinc_key;
     select reset_scn, reset_time into last_reset_scn, last_reset_time
        from dbinc
        where dbinc_key = this_dbinc_key;
  END IF;
 
  IF (reset_scn IS NOT NULL and reset_time IS NOT NULL) THEN
    IF (reset_scn <> last_reset_scn or reset_time <> last_reset_time) THEN
      BEGIN
         deb('checkLogHistory - new last_dbinc_key');
         deb('checkLogHistory - for reset_time ' || checkLogHistory.reset_time
             || ' reset_scn ' || checkLogHistory.reset_scn
             || ' this_db_key ' || this_db_key);
         select dbinc_key into last_dbinc_key from dbinc
           where reset_time = checkLogHistory.reset_time and
                 reset_scn = checkLogHistory.reset_scn and
                 db_key = this_db_key;
         last_reset_scn := reset_scn;
         last_reset_time := reset_time;
      EXCEPTION
      WHEN others THEN
         raise_application_error(-29999, 'Unknown Incarnation');
      END;
    END IF;
  END IF;
 
  deb('checkLogHistory - last_dbinc_key='||last_dbinc_key||
      ' reset_scn '||reset_scn || ' reset_time '||reset_time);
 
  BEGIN
    INSERT INTO rlh(
       rlh_key, dbinc_key, rlh_recid, rlh_stamp, thread#, sequence#,
       low_scn, low_time, next_scn)
    VALUES(
       rman_seq.nextval, last_dbinc_key, rlh_recid, rlh_stamp,
       thread#, sequence#, low_scn, low_time, next_scn);
  EXCEPTION
    WHEN dup_val_on_index THEN
--
--
      RETURN;
  END;
END checkLogHistory;
 
PROCEDURE endLogHistoryResync IS
 
BEGIN
  IF (this_cf_type = 'CURRENT' OR
      (this_cf_type = 'STANDBY' AND this_db_unique_name is not null)) THEN
--
     UPDATE node SET high_rlh_recid = last_rlh_recid
     WHERE site_key = this_site_key;
  END IF;
 
  last_rlh_recid := NULL;
 
END endLogHistoryResync;
 
/*-------------------------*
 * Archived Log resync     *
 *-------------------------*/
 
FUNCTION beginArchivedLogResync RETURN NUMBER IS
BEGIN
  checkResync;
 
  IF (this_cf_type = 'CURRENT' OR
      (this_cf_type = 'STANDBY' AND this_db_unique_name is not null)) THEN
     SELECT high_al_recid INTO last_al_recid
     FROM node
     WHERE site_key = this_site_key;
  ELSE
     last_al_recid := sessionWaterMarks.high_al_recid;
  END IF;
 
  RETURN last_al_recid;
END beginArchivedLogResync;
 
PROCEDURE deleteDuplicateAL(recid IN NUMBER,
                            stamp IN NUMBER,
                            fname in VARCHAR2) IS
   lfname al.fname%TYPE;
BEGIN
   
   lfname := fname;
   IF lfname is null THEN
      BEGIN
         SELECT fname INTO lfname from AL 
         WHERE al_recid = recid
           AND al_stamp = stamp
           AND al.dbinc_key in 
               (select dbinc_key from dbinc where db_key = this_db_key);
      EXCEPTION
         WHEN no_data_found THEN
            RETURN;
         WHEN too_many_rows THEN -- unique key is dbinc_key, al_recid, al_stamp
            RETURN;
      END;
   END IF;
 
--
--
   DELETE al
   WHERE al.dbinc_key IN
            (SELECT dbinc_key FROM dbinc WHERE dbinc.db_key = this_db_key)
     AND al.fname    = lfname
     AND ((nvl(al.site_key, this_site_key) = this_site_key) OR
          (logs_shared = TRUE#))
     AND al.fname_hashkey = substr(lfname,1,10)||substr(lfname,-10)
     AND NOT  (al.al_recid = recid AND
               al.al_stamp = stamp );
 
END deleteDuplicateAL;
 
PROCEDURE checkArchivedLog(
  al_recid    IN NUMBER
 ,al_stamp    IN NUMBER
 ,thread#     IN NUMBER
 ,sequence#   IN NUMBER
 ,reset_scn   IN NUMBER
 ,reset_time  IN DATE
 ,low_scn     IN NUMBER
 ,low_time    IN DATE
 ,next_scn    IN NUMBER
 ,next_time   IN DATE
 ,blocks      IN NUMBER
 ,block_size  IN NUMBER
 ,fname       IN VARCHAR2
 ,archived    IN VARCHAR2
 ,completion_time IN DATE
 ,status      IN VARCHAR2
 ,is_standby  IN VARCHAR2
 ,dictionary_begin      IN VARCHAR2   default NULL
 ,dictionary_end        IN VARCHAR2   default NULL
 ,is_recovery_dest_file IN VARCHAR2   default 'NO'
 ,compressed            IN VARCHAR2   default 'NO'
 ,creator               IN VARCHAR2   default NULL
 ,terminal              IN VARCHAR2   default 'NO'
 ,chk_last_recid        IN boolean    default TRUE
) IS
 
local  al%rowtype;
my_dbinc_key NUMBER;
 
BEGIN
--
--
  IF chk_last_recid THEN
     IF (last_al_recid IS NULL) THEN
       raise_application_error(-20037, 'Invalid last recid');
     END IF;
 
     IF (al_recid < last_al_recid) THEN
       raise_application_error(-20036, 'Invalid record order');
     END IF;
 
     IF (al_recid > last_al_recid + 1) THEN
--
--
       NULL;
     END IF;
     last_al_recid := al_recid;
  END IF;
 
  IF (this_dbinc_key IS NULL) THEN
    raise_application_error(-20020, 'Database incarnation not set');
  END IF;
 
  IF (al_stamp > 0 and al_stamp < kccdivts) THEN
     deb('checkArchivedLog - ignoring record kccdivts='||kccdivts);
     RETURN;                    -- obsolete record from a backup controlfile
  END IF;
 
--
--
  IF (sequence# = 0) THEN
    RETURN;
  END IF;
 
--
--
--
  my_dbinc_key := checkIncarnation(reset_scn, reset_time);
 
  BEGIN
    IF (status = 'D') THEN
--
       NULL;
    ELSE
       INSERT INTO al
         (al_key, dbinc_key, al_recid, al_stamp, thread#, sequence#,
          low_scn, low_time, next_scn, next_time,
          fname, fname_hashkey, archived, blocks, block_size,
          completion_time, status, is_standby,
          dictionary_begin, dictionary_end, is_recovery_dest_file, 
          compressed, creator, terminal, site_key)
       VALUES
         (rman_seq.nextval, my_dbinc_key, al_recid, al_stamp, thread#,
          sequence#, low_scn, low_time, next_scn, next_time,
          fname, substr(fname,1,10)||substr(fname, -10),
          archived, blocks, checkArchivedLog.block_size, completion_time,
          status, is_standby, dictionary_begin, dictionary_end,
          is_recovery_dest_file, compressed, creator, terminal, this_site_key);
 
       deleteDuplicateAL(al_recid, al_stamp, fname);
    END IF;
 
--
--
--
--
    IF checkArchivedLog.archived = 'N' then
       UPDATE rlh SET
         status = decode(fname, NULL, 'C', status)
       WHERE rlh.dbinc_key = my_dbinc_key
       AND   rlh.thread#   = checkArchivedLog.thread#
       AND   rlh.sequence# = checkArchivedLog.sequence#
       AND   rlh.low_scn   = checkArchivedLog.low_scn;
    END IF;
 
  EXCEPTION
    WHEN dup_val_on_index THEN
      deb('checkArchivedLog - Inside dup_val_on_index exception');
--
--
      SELECT * INTO local
      FROM al
        WHERE al.dbinc_key = my_dbinc_key
        AND   (al.is_standby = checkArchivedLog.is_standby OR
                 (al.is_standby is NULL AND 
                  checkArchivedLog.is_standby is NULL))
        AND   al.al_recid = checkArchivedLog.al_recid
        AND   al.al_stamp = checkArchivedLog.al_stamp;
 
--
      IF client_site_aware AND this_site_key <> local.site_key THEN
          raise_application_error(-20081, 'change stamp for the record');
      END IF;
 
--
      IF (fname <> local.fname) THEN
        deb('checkArchivedLog - input fname ['||fname||']; local.fname ['|| 
            local.fname || ']');
        raise_application_error(-20080, 'Invalid archived log name');
       
      END IF;
  END;
 
END checkArchivedLog;
 
PROCEDURE endArchivedLogResync IS
BEGIN
  IF (this_cf_type = 'CURRENT' OR
      (this_cf_type = 'STANDBY' AND this_db_unique_name is not null)) THEN
     UPDATE node SET high_al_recid = last_al_recid
     WHERE site_key = this_site_key;
  END IF;
 
  sessionWaterMarks.high_al_recid := last_al_recid;
  last_al_recid := NULL;
 
END endArchivedLogResync;
 
/*-------------------------*
 * Offline range resync    *
 *-------------------------*/
 
FUNCTION beginOfflineRangeResync RETURN NUMBER IS
BEGIN
  checkResync;
 
  IF (this_cf_type = 'CURRENT' OR
      (this_cf_type = 'STANDBY' AND this_db_unique_name is not null)) THEN
     SELECT high_offr_recid INTO last_offr_recid
     FROM node
     WHERE site_key = this_site_key;
  ELSE
     last_offr_recid := sessionWaterMarks.high_offr_recid;
  END IF;
 
  RETURN last_offr_recid;
END beginOfflineRangeResync;
 
PROCEDURE checkOfflineRange(
  offr_recid     IN NUMBER
 ,offr_stamp     IN NUMBER
 ,file#          IN NUMBER
 ,create_scn     IN NUMBER
 ,offline_scn    IN NUMBER
 ,online_scn     IN NUMBER
 ,online_time    IN DATE
 ,cf_create_time IN DATE
 ,reset_scn      IN number default NULL
 ,reset_time     IN date default NULL
) IS
 
   local   offr%rowtype;
 
--
--
BEGIN
  IF (last_offr_recid IS NULL AND offr_recid IS NOT NULL) THEN
    raise_application_error(-20037, 'Invalid last recid');
  END IF;
 
  deb('Checkofflinerange - '||
      ' recid: '||           nvl(to_char(offr_recid), 'NULL')||
      ' stamp: '||           nvl(to_char(offr_stamp), 'NULL')||
      ' file#: '||           file#||
      ' create_scn: '||      nvl(to_char(create_scn), 'NULL')||
      ' offline_scn: '||     offline_scn ||
      ' online_scn: '||      online_scn||
      ' online_time: '||     online_time||
      ' cf_create_time: '||  cf_create_time||
      ' reset_scn:'||        nvl(reset_scn, -1));
 
  last_offr_recid := offr_recid;
 
  IF (last_dbinc_key is NULL OR reset_scn IS NULL) THEN
     deb('checkOfflineRange - Init dbinc_key: '||this_dbinc_key);
     last_dbinc_key := this_dbinc_key;
     SELECT reset_scn, reset_time
       INTO last_reset_scn, last_reset_time
       FROM dbinc
      WHERE dbinc_key = this_dbinc_key;
  END IF;
 
  IF (reset_scn IS NOT NULL and reset_time IS NOT NULL) THEN
    IF (reset_scn <> last_reset_scn or reset_time <> last_reset_time) THEN
      BEGIN
         deb('checkOfflineRange - new incarnation detected'||
             ' reset_scn: '||      reset_scn||
             ' last_reset_scn: '|| last_reset_scn);
         SELECT dbinc_key
           INTO last_dbinc_key
           FROM dbinc
          WHERE reset_time = checkOfflineRange.reset_time
            AND reset_scn  = checkOfflineRange.reset_scn
            AND db_key = this_db_key;
         last_reset_scn  := reset_scn;
         last_reset_time := reset_time;
      EXCEPTION
        WHEN others THEN
          raise_application_error(-20070, 'Unknown Incarnation');
      END;
    END IF;
  END IF;
 
  deb('checkOfflineRange - dbinc_key is: '||last_dbinc_key);
 
  deb('checkOfflineRange - Looking if offline range record already '||
      'exists in OFFR');
  BEGIN
--
    SELECT distinct file#, create_scn, offline_scn,
           online_scn, online_time
      INTO local.file#, local.create_scn, local.offline_scn,
           local.online_scn, local.online_time
      FROM offr
      WHERE dbinc_key      = last_dbinc_key
        AND file#          = checkOfflineRange.file#
        AND create_scn     = checkOfflineRange.create_scn
        AND offline_scn    = checkOfflineRange.offline_scn;
 
    IF local.online_scn <> checkOfflineRange.online_scn THEN
      deb('checkOfflineRange - Online_scn OK?'||
          ' online_scn: '       || online_scn ||
          ' local.online_scn: ' || local.online_scn);
--
    END IF;
 
    IF local.online_time <> checkOfflineRange.online_time THEN
      deb('checkOfflineRange - Online_time OK?'||
          ' online_time: '       || online_time ||
          ' local.online_time: ' || local.online_time);
--
    END IF;
 
  EXCEPTION
    WHEN no_data_found THEN
      NULL; -- offline range record not yet known to catalog, go to insert
 
    WHEN too_many_rows THEN
      RAISE;      -- there must not be more then on offline range with same
--
    WHEN others THEN
      RAISE;
  END;
 
  BEGIN
    INSERT INTO
      offr(offr_key, dbinc_key, offr_recid, offr_stamp,
           file#, create_scn, offline_scn, online_scn,
           online_time, cf_create_time)
      VALUES(rman_seq.nextval, last_dbinc_key, offr_recid, nvl(offr_stamp,0),
             file#, create_scn, offline_scn, online_scn,
             online_time, cf_create_time);
    incResyncActions(RESYNC_ACTION_CHANGE, file#, to_char(NULL));
    deb('checkOfflineRange - Succesfully inserted new OFFR.');
 
  EXCEPTION
    WHEN dup_val_on_index THEN
      deb('checkOfflineRange - record already exists');
      IF offr_recid > 0 AND offr_stamp > 0 THEN
        deb('checkOfflineRange - update new offr_recid, offr_stamp, '||
            'online_scn and online_time');
        UPDATE OFFR
            SET offr_recid = checkOfflineRange.offr_recid,
                offr_stamp = checkOfflineRange.offr_stamp,
                online_scn = checkOfflineRange.online_scn,
                online_time= checkOfflineRange.online_time
          WHERE dbinc_key      = last_dbinc_key
            AND file#          = checkOfflineRange.file#
            AND create_scn     = checkOfflineRange.create_scn
            AND offline_scn    = checkOfflineRange.offline_scn
            AND cf_create_time = checkOfflineRange.cf_create_time;
        incResyncActions(RESYNC_ACTION_CHANGE, file#, to_char(NULL));
      END IF;
  END;
 
  deb('checkOfflineRange - exiting');
END;
 
PROCEDURE endOfflineRangeResync IS
BEGIN
  IF (this_cf_type = 'CURRENT' OR
      (this_cf_type = 'STANDBY' AND this_db_unique_name is not null)) THEN
     UPDATE node SET high_offr_recid = last_offr_recid
     WHERE site_key = this_site_key;
  END IF;
 
--
  IF this_is_ors and this_ckp_type = 'FULL' THEN
     UPDATE watermarks SET high_offr_recid = last_offr_recid
     WHERE db_key = this_db_key;
  END IF;
 
  sessionWaterMarks.high_offr_recid := last_offr_recid;
  last_offr_recid := NULL;
 
END endOfflineRangeResync;
 
/*-------------------------*
 * Backup Set resync       *
 *-------------------------*/
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE updateBackupSetRec(bs_key IN NUMBER) IS
  total_pieces     NUMBER;
  backup_validate  VARCHAR2(3);
  available_pieces NUMBER;
  new_status       VARCHAR2(1);
  bskeep           NUMBER;
  bstype           VARCHAR2(1);
  low              NUMBER := NULL;
  high             NUMBER := NULL;
  bs_site_key      NUMBER := NULL;
  not_purged       NUMBER := 0;
  pieces_on_msite  NUMBER;
  new_site_key     NUMBER;
  need_resync      NUMBER := 0;
  dbkey            NUMBER;
  incr_lvl         NUMBER;
  ra_node_count    NUMBER;
BEGIN
  deb('updateBackupSetRec, bs_key=' || bs_key);
--
--
  BEGIN
    SELECT pieces,input_file_scan_only, keep_options, bck_type, site_key,
           incr_level, db_key
    INTO total_pieces,backup_validate, bskeep, bstype, bs_site_key,
         incr_lvl, dbkey
    FROM bs
    WHERE bs.bs_key = updateBackupSetRec.bs_key;
  EXCEPTION
    WHEN no_data_found THEN
       new_status := 'D'; -- all pieces are deleted or not there
  END;
 
  IF nvl(backup_validate,'NO') <> 'YES' THEN
    SELECT max(count(DISTINCT piece#)) INTO available_pieces
    FROM  bp
    WHERE bp.bs_key = updateBackupSetRec.bs_key
    AND   bp.status = 'A'
    GROUP BY device_type;
 
    SELECT count(*) INTO not_purged
      FROM bp
     WHERE bp.bs_key = updateBackupSetRec.bs_key
       AND bp.purged = 'N'
       AND bp.ba_access IN ('L', 'D');
  END IF;
 
--
  IF bs_site_key IS NULL OR bs_site_key <> this_site_key THEN
    SELECT count(distinct nvl(site_key, 0)) INTO pieces_on_msite
      FROM bp
      WHERE bs_key = updateBackupSetRec.bs_key;
    IF pieces_on_msite = 1 THEN
       SELECT distinct site_key  INTO new_site_key
       FROM BP
       WHERE bs_key = updateBackupSetRec.bs_key;
    END IF;
--
    UPDATE bs SET site_key = new_site_key
    WHERE bs.bs_key = updateBackupSetRec.bs_key;
  END IF;
 
  deb('updateBackupSetRec, total_piece='||total_pieces||
      ', available_pieces='||available_pieces||
      ', not_purged='||not_purged);
  IF (total_pieces = 0 or backup_validate = 'YES') THEN
--
    new_status := 'D';
  ELSIF (available_pieces = total_pieces) THEN
    new_status := 'A';
  ELSE
    BEGIN
--
       SELECT 'O' INTO new_status FROM bp
        WHERE bp.bs_key = updateBackupSetRec.bs_key
          AND bp.status != 'D'
          AND rownum < 2;
    EXCEPTION WHEN no_data_found THEN
       new_status := 'D'; -- all pieces are deleted or not there
    END;
  END IF;
 
  deb('updateBackupSetRec, new_status='||new_status||',val='||backup_validate);
  IF (new_status in ('O', 'A') OR
      backup_validate = 'YES'  OR
      not_purged != 0) THEN
     UPDATE bs SET status = new_status
      WHERE bs.bs_key = updateBackupSetRec.bs_key;
  ELSE
--
     IF (bskeep > 0 and bstype = 'L') THEN
       SELECT min(low_scn), max(next_scn) INTO low, high
       FROM brl
       WHERE bs_key = updateBackupSetRec.bs_key;
     END IF;
     IF (bskeep > 0 and bstype = 'D') THEN
        SELECT min(ckp_scn) INTO low
        FROM bdf
        WHERE bs_key = updateBackupSetRec.bs_key;
     END IF;
    
--
--
--
     IF (this_is_ors
         AND incr_lvl IS NOT NULL 
         AND this_enable_populate_rsr = 1) THEN
       BEGIN 
--
--
         IF this_upstream_site_key IS NULL THEN
           SELECT site_key INTO this_upstream_site_key
           FROM   node
           WHERE  node.db_key = dbkey AND
                  database_role = 'RA' AND
                  db_unique_name like '$%$%' AND
                  db_unique_name not like '$%$%$%';
          END IF;
 
          deb('updateBackupSetRec, this_upstream_site_key = ' || 
                                   this_upstream_site_key);
--
--
          SELECT count(*) INTO need_resync
          FROM   bp
          WHERE  bs_key     =  updateBackupSetRec.bs_key
          AND    ((ba_access = 'L' AND vb_key IS NULL 
                   AND substr(handle,1,6) != 'RA_SBT')
--
--
                  OR (ba_access = 'D' AND rsr_key IS NULL))
--
--
--
          AND    site_key = this_upstream_site_key;
       EXCEPTION
          WHEN no_data_found THEN
            deb('updateBackupSetRec, node table has no RA rows with db_key '
                                                             || dbkey);
       END;
     END IF;
 
     IF need_resync = 0 THEN
--
--
       deb('updateBackupSetRec, deleting rows from BP and BS for bs_key=' || 
                                updateBackupSetRec.bs_key); 
       DELETE from bp WHERE bp.bs_key = updateBackupSetRec.bs_key;
       deb('updateBackupSetRec, deleted rows from bp =' || SQL%ROWCOUNT);
       DELETE FROM bs WHERE bs.bs_key = updateBackupSetRec.bs_key;
       deb('updateBackupSetRec, deleted rows from bs =' || SQL%ROWCOUNT);
     ELSE
       deb('updateBackupSetRec, Skipping deletion of bs_key = ' || bs_key ||
            '. Waiting till resync happens to delete this.');
     END IF;
 
--
     IF (low IS NOT NULL) THEN
       updateRestorePoint(low, high);
     END IF;
  END IF;
END updateBackupSetRec;
 
FUNCTION beginBackupSetResync RETURN NUMBER IS
BEGIN
  checkResync;
 
  IF (this_cf_type = 'CURRENT' OR
      (this_cf_type = 'STANDBY' AND this_db_unique_name is not null)) THEN
     SELECT high_bs_recid INTO last_bs_recid
     FROM node
     WHERE site_key = this_site_key;
  ELSE
     last_bs_recid := sessionWaterMarks.high_bs_recid;
  END IF;
 
  RETURN last_bs_recid;
END beginBackupSetResync;
 
PROCEDURE checkBackupSet(
  bs_recid             IN NUMBER
 ,bs_stamp             IN NUMBER
 ,set_stamp            IN NUMBER
 ,set_count            IN NUMBER
 ,bck_type             IN VARCHAR2
 ,incr_level           IN NUMBER         DEFAULT NULL
 ,pieces               IN NUMBER
 ,start_time           IN DATE
 ,completion_time      IN DATE
 ,controlfile_included IN VARCHAR2       DEFAULT NULL
 ,input_file_scan_only IN VARCHAR2       DEFAULT NULL
 ,keep_options         IN NUMBER         DEFAULT 0
 ,keep_until           IN DATE           DEFAULT NULL
 ,block_size           IN NUMBER         DEFAULT NULL
 ,multi_section        IN VARCHAR2       DEFAULT NULL
 ,chk_last_recid       IN BOOLEAN        DEFAULT TRUE
 ,guid                 IN RAW            DEFAULT NULL
 ,dropped_pdb          IN BINARY_INTEGER DEFAULT 0
) IS
 
local      bs%rowtype;
newbskey   number;
l_pdb_key  number;
 
BEGIN
  IF (chk_last_recid) THEN
     IF (last_bs_recid IS NULL) THEN
       raise_application_error(-20037, 'Invalid last recid');
     END IF;
 
     IF (bs_recid < last_bs_recid) THEN
       raise_application_error(-20036, 'Invalid record order');
     END IF;
 
     IF (bs_recid > last_bs_recid + 1) THEN
--
       NULL;
     END IF;
     last_bs_recid := bs_recid;
  END IF;
 
  IF (bs_stamp > 0 and bs_stamp < kccdivts) THEN
     deb('checkBackupSet - ignoring record kccdivts='||kccdivts);
     RETURN;                    -- obsolete record from a backup controlfile
  END IF;
 
  IF (bck_type NOT IN ('D','I','L') OR bck_type IS NULL) THEN
    raise_application_error(-20090, 'Invalid backup set type');
  END IF;
 
  IF (incr_level NOT IN (0,1,2,3,4) OR
      (bck_type NOT IN ('D','I') AND incr_level <> 0)) THEN
    raise_application_error(-20091, 'Invalid backup set level');
  END IF;
 
  l_pdb_key := guidToPdbKey(guid, dropped_pdb);
 
  BEGIN
--
--
    INSERT INTO bs
      (bs_key, db_key, bs_recid, bs_stamp, set_stamp, set_count,
       bck_type, incr_level, pieces, start_time, completion_time, status,
       controlfile_included, input_file_scan_only, keep_options, keep_until,
       block_size, site_key, multi_section, pdb_key)
    VALUES
      (rman_seq.nextval, this_db_key, bs_recid, bs_stamp, set_stamp, set_count,
       bck_type, incr_level, pieces, start_time, completion_time, 'D',
       decode(controlfile_included, 'SBY','STANDBY','YES','BACKUP','NONE'),
       input_file_scan_only, keep_options, keep_until, block_size, 
       this_site_key, decode(multi_section,'YES','Y',null), l_pdb_key)
    RETURNING bs_key INTO newbskey;
 
    cntbs := cntbs + 1;
    updatebs(cntbs) := newbskey;
 
  EXCEPTION
    WHEN dup_val_on_index THEN
      deb('checkBackupSet - Inside dup_val_on_index exception');
--
      SELECT * INTO local
      FROM bs
      WHERE bs.db_key = this_db_key
        AND bs.set_stamp = checkBackupSet.set_stamp
        AND bs.set_count = checkBackupSet.set_count;
  
      duplicatebs(local.bs_key) := 1;
 
--
--
--
      IF (pieces > local.pieces) THEN
        UPDATE bs
           SET bs.pieces = checkBackupSet.pieces
        WHERE bs.db_key = this_db_key
        AND bs.bs_key = local.bs_key;
 
--
        cntbs:= cntbs + 1;
        updatebs(cntbs) := local.bs_key;
      END IF;
 
--
--
--
--
 
--
--
      IF local.site_key IS NULL AND cntbs > 0 AND
         updatebs(cntbs) <> local.bs_key THEN
         cntbs := cntbs + 1;
         updatebs(cntbs) := local.bs_key;
      END IF;
 
      IF (local.completion_time <> checkBackupSet.completion_time) THEN
        UPDATE bs
           SET completion_time = checkBackupSet.completion_time
         WHERE bs.db_key = this_db_key
           AND bs.bs_key = local.bs_key;
      END IF;
  END;
END checkBackupSet;
 
PROCEDURE endBackupSetResync IS
BEGIN
  IF (this_cf_type = 'CURRENT' OR
      (this_cf_type = 'STANDBY' AND this_db_unique_name is not null)) THEN
--
     UPDATE node SET high_bs_recid = last_bs_recid
     WHERE site_key = this_site_key;
  END IF;
 
  sessionWaterMarks.high_bs_recid := last_bs_recid;
  last_bs_recid := NULL;
 
END endBackupSetResync;
 
 /*-------------------------*
 * Backup piece resync     *
 *-------------------------*/
 
FUNCTION beginBackupPieceResync RETURN NUMBER IS
BEGIN
  checkResync;
 
  IF (this_cf_type = 'CURRENT' OR
      (this_cf_type = 'STANDBY' AND this_db_unique_name is not null)) THEN
     SELECT high_bp_recid INTO last_bp_recid
     FROM node
     WHERE site_key = this_site_key;
  ELSE
     last_bp_recid := sessionWaterMarks.high_bp_recid;
  END IF;
 
  RETURN last_bp_recid;
END beginBackupPieceResync;
 
PROCEDURE deleteDuplicateBP(recid IN NUMBER,
                            stamp IN NUMBER,
                            bs_key IN NUMBER,
                            device_type IN VARCHAR2,
                            handle      IN VARCHAR2) IS
   ldevice_type bp.device_type%TYPE;
   lhandle      bp.device_type%TYPE;
BEGIN
 
   ldevice_type := device_type;
   lhandle      := handle;
 
   IF ldevice_type IS NULL OR lhandle IS NULL THEN
      BEGIN
         SELECT device_type, handle INTO ldevice_type, lhandle FROM BP
         WHERE bp.db_key   = this_db_key
           AND bp_recid    = recid
           AND bp_stamp    = stamp
           AND ((disk_backups_shared = TRUE# AND bp.device_type = 'DISK') OR
                (tape_backups_shared = TRUE# AND bp.device_type <> 'DISK') OR
                (this_site_key = nvl(bp.site_key, this_site_key)))
           AND deleteDuplicateBP.bs_key = bp.bs_key;
      EXCEPTION
         WHEN no_data_found THEN
            RETURN;
         WHEN too_many_rows THEN -- unique key is bs_key, recid, stamp
            RETURN;
      END;
   END IF;
 
   IF this_is_ors AND this_ckp_key IS NULL THEN 
      this_enable_populate_rsr := 
                          getValueFromConfig('_enable_populate_rsr_key');
   END IF;
--
--
--
--
   FOR bprec IN bpq(ldevice_type, lhandle, recid, stamp) LOOP
      UPDATE bp SET bp.status = 'D' WHERE bp.bp_key = bprec.bp_key;
      updateBackupSetRec(bprec.bs_key);        -- update the backupset status
   END LOOP;
--
--
   IF this_is_ors AND this_ckp_key IS NULL THEN 
      this_enable_populate_rsr := NULL;
      this_upstream_site_key := NULL;
   END IF;
END deleteDuplicateBP;
 
PROCEDURE checkBackupPiece(
  bp_recid                IN NUMBER
 ,bp_stamp                IN NUMBER
 ,set_stamp               IN NUMBER
 ,set_count               IN NUMBER
 ,piece#                  IN NUMBER
 ,tag                     IN VARCHAR2
 ,device_type             IN VARCHAR2
 ,handle                  IN VARCHAR2
 ,comments                IN VARCHAR2
 ,media                   IN VARCHAR2
 ,concur                  IN VARCHAR2
 ,start_time              IN DATE
 ,completion_time         IN DATE
 ,status                  IN VARCHAR2
 ,copy#                   IN NUMBER         default 1
 ,media_pool              IN NUMBER         default 0
 ,bytes                   IN NUMBER         default NULL
 ,is_recovery_dest_file   IN VARCHAR2       default 'NO'
 ,rsr_recid               IN NUMBER         default NULL
 ,rsr_stamp               IN NUMBER         default NULL
 ,compressed              IN VARCHAR2       default 'NO'
 ,encrypted               IN VARCHAR2       default 'NO'
 ,backed_by_osb           IN VARCHAR2       default 'NO'
 ,ba_access               IN VARCHAR2       default 'U'
 ,vbkey                   IN NUMBER         default NULL
 ,chk_last_recid          IN BOOLEAN        default TRUE
 ,lib_key                 IN NUMBER         default NULL
 ,guid                    IN RAW            default NULL
 ,template_key            IN NUMBER         default NULL
 ,dropped_pdb             IN BINARY_INTEGER default 0
) IS
   bp_key NUMBER;
BEGIN
   bp_key := checkBackupPiece(
                bp_recid               => bp_recid
               ,bp_stamp               => bp_stamp
               ,set_stamp              => set_stamp
               ,set_count              => set_count
               ,piece#                 => piece#
               ,tag                    => tag
               ,device_type            => device_type
               ,handle                 => handle
               ,comments               => comments
               ,media                  => media
               ,concur                 => concur
               ,start_time             => start_time
               ,completion_time        => completion_time
               ,status                 => status
               ,copy#                  => copy#
               ,media_pool             => media_pool
               ,bytes                  => bytes
               ,is_recovery_dest_file  => is_recovery_dest_file
               ,rsr_recid              => rsr_recid
               ,rsr_stamp              => rsr_stamp
               ,compressed             => compressed
               ,encrypted              => encrypted
               ,backed_by_osb          => backed_by_osb
               ,ba_access              => ba_access
               ,vbkey                  => vbkey
               ,chk_last_recid         => chk_last_recid
               ,lib_key                => lib_key
               ,guid                   => guid
               ,template_key           => template_key
               ,dropped_pdb            => dropped_pdb);
END checkBackupPiece;
 
FUNCTION checkBackupPiece(
  bp_recid                IN NUMBER
 ,bp_stamp                IN NUMBER
 ,set_stamp               IN NUMBER
 ,set_count               IN NUMBER
 ,piece#                  IN NUMBER
 ,tag                     IN VARCHAR2
 ,device_type             IN VARCHAR2
 ,handle                  IN VARCHAR2
 ,comments                IN VARCHAR2
 ,media                   IN VARCHAR2
 ,concur                  IN VARCHAR2
 ,start_time              IN DATE
 ,completion_time         IN DATE
 ,status                  IN VARCHAR2
 ,copy#                   IN NUMBER         default 1   -- No longer in use
 ,media_pool              IN NUMBER         default 0
 ,bytes                   IN NUMBER         default NULL
 ,is_recovery_dest_file   IN VARCHAR2       default 'NO'
 ,rsr_recid               IN NUMBER         default NULL
 ,rsr_stamp               IN NUMBER         default NULL
 ,compressed              IN VARCHAR2       default 'NO'
 ,encrypted               IN VARCHAR2       default 'NO'
 ,backed_by_osb           IN VARCHAR2       default 'NO'
 ,ba_access               IN VARCHAR2       default 'U'
 ,vbkey                   IN NUMBER         default NULL
 ,chk_last_recid          IN BOOLEAN        default TRUE
 ,lib_key                 IN NUMBER         default NULL
 ,guid                    IN RAW            default NULL
 ,template_key            IN NUMBER         default NULL
 ,dropped_pdb             IN BINARY_INTEGER default 0
) RETURN NUMBER IS
   localbs  bs%rowtype;
   localbp  bp%rowtype;
   localrsr rsr%rowtype;
   piece_exists BINARY_INTEGER := 0;
   l_copyno NUMBER := 1;
   l_update_bs_pieces BOOLEAN := FALSE;
   l_pdb_key NUMBER;
   l_bp_recid NUMBER;
BEGIN
 
  IF (chk_last_recid) THEN
     IF (last_bp_recid IS NULL) THEN
       raise_application_error(-20037, 'Invalid last recid');
     END IF;
 
     IF (bp_recid < last_bp_recid) THEN
       deb('checkBackupPiece - last_bp_recid=' || last_bp_recid);
       raise_application_error(-20036, 'Invalid record order');
     END IF;
 
     IF (bp_recid > last_bp_recid + 1) THEN
--
--
       NULL;
     END IF;
     last_bp_recid := bp_recid;
  END IF;
 
  IF (bp_stamp > 0 and bp_stamp < kccdivts) THEN
     deb('checkBackupPiece - ignoring record kccdivts='||kccdivts);
     RETURN NULL;               -- obsolete record from a backup controlfile
  END IF;
 
--
  IF handle IS NULL AND status != 'D' THEN
     deb('checkBackupPiece - handle is null, ignore this row');
     RETURN NULL;
  END IF;
 
--
--
--
--
--
--
--
--
--
  IF bp_recid = 0 OR this_wmrec.high_bp_recid >= 0 THEN
     this_high_bp_recid := this_high_bp_recid + 1;
     l_bp_recid := this_high_bp_recid;
     deb('checkBackupPiece - generating bp_recid=' || l_bp_recid ||
         ', ba_access=' || ba_access || ',handle=' || handle);
  ELSE
     l_bp_recid := bp_recid;
  END IF;
 
--
--
--
 
  l_pdb_key := guidToPdbKey(guid, dropped_pdb);
 
--
  BEGIN
    SELECT * into localbs from bs
      WHERE bs.db_key = this_db_key
        AND   bs.set_stamp = checkBackupPiece.set_stamp
        AND   bs.set_count = checkBackupPiece.set_count FOR UPDATE OF bs.bs_key;
    deb('checkBackupPiece - locked bs_key' || localbs.bs_key);
    
    IF this_db_unique_name = upper(this_server.wallet_alias) THEN
      deb('checkBackupPiece - doing reconcile is TRUE');
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
    END IF;
 
  EXCEPTION
    WHEN no_data_found THEN
      IF status != 'D' THEN
        INSERT INTO bs
          (bs_key, db_key, bs_recid, bs_stamp,
           set_stamp, set_count,
           bck_type, incr_level, pieces, start_time, completion_time, status,
           controlfile_included, site_key, multi_section, pdb_key)
        VALUES
--
--
--
--
--
--
--
--
          (rman_seq.nextval, this_db_key, 0, checkBackupPiece.set_stamp,
          checkBackupPiece.set_stamp, checkBackupPiece.set_count,
          NULL, NULL, checkBackupPiece.piece#,
          checkBackupPiece.start_time, checkBackupPiece.completion_time, 'O',
          'NONE', this_site_key, NULL, l_pdb_key)
        RETURNING bs_key INTO localbs.bs_key;
 
        cntbs := cntbs + 1;
        updatebs(cntbs) := localbs.bs_key;
      ELSE
--
         RETURN NULL;
      END IF;
  END;
 
--
--
  IF (status = 'D') THEN
     cntbs:= cntbs + 1;
     updatebs(cntbs) := localbs.bs_key;
     RETURN NULL;
  END IF;
 
--
  IF (localbs.bs_recid is null OR localbs.bs_recid = 0) AND
    checkBackupPiece.piece# > localbs.pieces THEN
    l_update_bs_pieces := TRUE;
  ELSE
--
--
--
--
    SELECT NVL(MAX(copy#), 0)+1 INTO l_copyno
      FROM bp
      WHERE piece# = checkBackupPiece.piece#
      AND bs_key = localbs.bs_key;
  END IF;
 
--
  BEGIN
      SELECT rsr_key
        INTO localrsr.rsr_key
        FROM rsr
       WHERE rsr.dbinc_key = this_dbinc_key
         AND (rsr.site_key = this_site_key OR
              rsr.site_key is null AND this_site_key is NULL)
         AND rsr.rsr_stamp = checkBackupPiece.rsr_stamp
         AND rsr.rsr_recid = checkBackupPiece.rsr_recid;
  EXCEPTION
    WHEN no_data_found THEN
--
      NULL;
  END;
 
  SELECT MAX(bp_key) INTO localbp.bp_key
    FROM bp
   WHERE bp.handle                       = checkBackupPiece.handle
     AND bp.device_type                  = checkBackupPiece.device_type
     AND bp.bs_key                       = localbs.bs_key
     AND ((disk_backups_shared = TRUE# AND bp.device_type = 'DISK') OR
          (tape_backups_shared = TRUE# AND bp.device_type <> 'DISK') OR
          (this_site_key = nvl(bp.site_key, this_site_key)));
 
  BEGIN
     IF (localbp.bp_key IS NOT NULL) THEN
        UPDATE bp
           SET bp_recid              = l_bp_recid,
               bp_stamp              = checkBackupPiece.bp_stamp,
               comments              = checkBackupPiece.comments,
               media                 = checkBackupPiece.media,
               media_pool            = checkBackupPiece.media_pool,
               concur                = decode(checkBackupPiece.concur,
                                              'YES', 'Y', 'N'),
               start_time            = checkBackupPiece.start_time,
               completion_time       = checkBackupPiece.completion_time,
               bytes                 = checkBackupPiece.bytes,
               is_recovery_dest_file = checkBackupPiece.is_recovery_dest_file,
               rsr_key               = localrsr.rsr_key,
               site_key              = this_site_key,
               backed_by_osb         = decode(checkBackupPiece.backed_by_osb,
                                              'YES', 'Y', 'N')
         WHERE bp_key = localbp.bp_key;
     ELSE
--
--
--
        IF (this_is_ors             AND -- in ORS schema?
            ba_access = 'U'         AND -- record pushed by rman resync?
            isOrsMedia(checkBackupPiece.media)) THEN
           deb('checkBackupPiece - ORS media backup piece - skipping');
           cntbs:= cntbs + 1;
           updatebs(cntbs) := localbs.bs_key;
           RETURN NULL;
        END IF;
        INSERT INTO bp
           (bp_key, bs_key, piece#, db_key, bp_recid, bp_stamp, tag,
            device_type, copy#, handle, handle_hashkey, comments, media,
            media_pool, concur, start_time, completion_time, status, bytes,
            is_recovery_dest_file, rsr_key, compressed, site_key, encrypted,
            backed_by_osb, ba_access, vb_key, lib_key, purged, pdb_key,
            template_key)
        VALUES
           (rman_seq.nextval, localbs.bs_key, checkBackupPiece.piece#,
            this_db_key, l_bp_recid, checkBackupPiece.bp_stamp,
            checkBackupPiece.tag, checkBackupPiece.device_type,
            l_copyno, checkBackupPiece.handle,
            substr(checkBackupPiece.device_type,1,10) ||
            substr(checkBackupPiece.handle,1,10)      ||
            substr(checkBackupPiece.handle,-10),
            checkBackupPiece.comments, checkBackupPiece.media,
            checkBackupPiece.media_pool,
            decode(checkBackupPiece.concur,'YES','Y','N'),
            checkBackupPiece.start_time,
            checkBackupPiece.completion_time,
            checkBackupPiece.status, checkBackupPiece.bytes,
            checkBackupPiece.is_recovery_dest_file, localrsr.rsr_key, 
            checkBackupPiece.compressed, this_site_key,
            decode(checkBackupPiece.encrypted, 'YES', 'Y', 'N'), 
            decode(checkBackupPiece.backed_by_osb, 'YES', 'Y', 'N'),
            checkBackupPiece.ba_access,
            checkBackupPiece.vbkey, checkBackupPiece.lib_key,
            decode(checkBackupPiece.ba_access, 'U', 'U', 'N'),
            l_pdb_key, checkBackupPiece.template_key)
         RETURNING bp_key INTO localbp.bp_key;
 
--
        IF this_is_ors THEN
          UPDATE sbt_template_db std
             SET std.last_bp_key = localbp.bp_key
           WHERE std.db_key = this_db_key
             AND std.last_bp_key > localbp.bp_key;
        END IF;
 
     END IF;
 
--
     IF this_is_ors AND getValueFromConfig('_enable_populate_rsr_key') = 1 THEN
        EXECUTE IMMEDIATE
         'BEGIN dbms_rai_populate_rsr_key(:1,:2); END;'
         USING localbp.bp_key, localbs.bs_key;
     END IF;
--
     deleteDuplicateBP(l_bp_recid, bp_stamp, localbs.bs_key,
                       device_type, handle);
 
--
--
     IF l_update_bs_pieces THEN
       UPDATE bs
          SET bs.pieces = checkBackupPiece.piece#
        WHERE bs.bs_key = localbs.bs_key
          AND bs.bck_type IS NULL;
     END IF;
 
--
     updateBackupSetRec(localbs.bs_key);
  EXCEPTION
    WHEN dup_val_on_index THEN
      deb('checkBackupPiece - Inside dup_val_on_index exception');
--
--
      SELECT * INTO localbp
      FROM bp
      WHERE bp.bs_key = localbs.bs_key
      AND   bp.bp_recid = l_bp_recid
      AND   bp.bp_stamp = checkBackupPiece.bp_stamp;
 
--
      IF client_site_aware AND this_site_key <> localbp.site_key THEN
          raise_application_error(-20081, 'change stamp for the record');
      END IF;
 
--
      IF (piece# <> localbp.piece#) THEN
        raise_application_error(-20093, 'Invalid piece#');
      END IF;
 
--
      IF localbp.site_key IS NULL THEN
         UPDATE bp SET site_key = this_site_key
         WHERE  bp.bs_key = localbs.bs_key
          AND   bp.bp_recid = l_bp_recid
          AND   bp.bp_stamp = checkBackupPiece.bp_stamp;
      END IF;
    WHEN OTHERS THEN
       deb('checkBackupPiece - inside exception hndle='||sqlerrm);
       RAISE;
  END;
 
  RETURN localbp.bp_key;
END checkBackupPiece;
 
PROCEDURE endBackupPieceResync IS
BEGIN
  IF (this_cf_type = 'CURRENT' OR
      (this_cf_type = 'STANDBY' AND this_db_unique_name is not null)) THEN
     deb('endBackupPieceResync - last_bp_recid=' || last_bp_recid);
     UPDATE node SET high_bp_recid = last_bp_recid
     WHERE site_key = this_site_key;
  END IF;
 
  sessionWaterMarks.high_bp_recid := last_bp_recid;
  last_bp_recid := NULL;
 
END endBackupPieceResync;
 
/*-------------------------*
 * Backup Datafile resync  *
 *-------------------------*/
 
PROCEDURE addBackupControlFile(
  bs_key             IN NUMBER
 ,bcf_recid          IN NUMBER
 ,bcf_stamp          IN NUMBER
 ,dbinc_key          IN NUMBER
 ,ckp_scn            IN NUMBER
 ,ckp_time           IN DATE
 ,create_time        IN DATE
 ,min_offr_recid     IN NUMBER
 ,blocks             IN NUMBER
 ,block_size         IN NUMBER
 ,controlfile_type   IN VARCHAR2
 ,cfile_abck_year    IN number
 ,cfile_abck_mon_day IN number
 ,cfile_abck_seq     IN number
 ,pdb_key            IN NUMBER
) IS
 
local    bcf%rowtype;
l_conflict_count NUMBER := 0;
BEGIN
  BEGIN
    INSERT INTO bcf(bcf_key, bs_key, dbinc_key, bcf_recid, bcf_stamp,
                    ckp_scn, ckp_time, create_time, min_offr_recid, block_size,
                    controlfile_type, blocks, autobackup_date,
                    autobackup_sequence, pdb_key)
    VALUES (rman_seq.nextval, bs_key, dbinc_key, bcf_recid, bcf_stamp,
            ckp_scn, ckp_time, create_time, min_offr_recid,block_size,
            controlfile_type, blocks,
            decode(cfile_abck_year, 0, to_date(NULL),
                   to_date(to_char(cfile_abck_year)||
                           lpad(to_char(cfile_abck_mon_day), 4, '0'),
                           'YYYYMMDD', 'NLS_CALENDAR=Gregorian')),
            cfile_abck_seq, pdb_key);
    IF (duplicatebs.exists(addBackupControlFile.bs_key)) THEN
       DECLARE
         CURSOR bcf_conflicts(bs_key_new IN NUMBER ) IS
           SELECT bs_key, bcf_key, dbinc_key, ckp_scn, ckp_time, block_size, 
                  controlfile_type, blocks, pdb_key 
             FROM bcf
            WHERE bcf.bs_key = bs_key_new;
         conflict_rec bcf_conflicts%rowtype;
       BEGIN
         FOR conflict_rec IN bcf_conflicts(addBackupControlFile.bs_key)
         LOOP
           deb('addBackupControlfile set stamp set count conflict rec- ' ||
                ' bs_key '           || to_char(conflict_rec.bs_key)     ||
                ' bcf_key '          || to_char(conflict_rec.bcf_key)    ||
                ' dbinc_key '        || to_char(conflict_rec.dbinc_key)  ||
                ' ckp_scn '          || to_char(conflict_rec.ckp_scn)    ||
                ' ckp_time '         || to_char(conflict_rec.ckp_time)   ||
                ' block_size '       || to_char(conflict_rec.block_size) ||
                ' controlfile_type ' || conflict_rec.controlfile_type    ||
                ' blocks '           || to_char(conflict_rec.blocks)     ||
                ' pdb_key '          || to_char(conflict_rec.pdb_key));
         END LOOP;
       END;
       raise_application_error(-20110, 'set stamp set count conflict');
    END IF;
 
  EXCEPTION
    WHEN dup_val_on_index THEN
      deb('addBackupControlfile - Inside dup_val_on_index exception');
      
      SELECT count(*) INTO l_conflict_count 
        FROM bcf
       WHERE bcf.bs_key  =  addBackupControlFile.bs_key 
         AND (
                bcf.ckp_scn          <> addBackupControlFile.ckp_scn 
             OR bcf.ckp_time         <> addBackupControlFile.ckp_time
             OR bcf.block_size       <> addBackupControlFile.block_size
             OR bcf.controlfile_type <> addBackupControlFile.controlfile_type
             OR bcf.blocks           <> addBackupControlFile.blocks
             )
         AND ROWNUM       = 1 ;
      IF (l_conflict_count > 0) THEN
         DECLARE
           CURSOR bcf_conflicts(bs_key_new IN NUMBER, ckp_scn_new IN NUMBER, 
                                ckp_time_new IN DATE, block_size_new IN NUMBER,
                                controlfile_type_new IN VARCHAR2, 
                                blocks_new IN NUMBER)
           IS
             SELECT bs_key, bcf_key, dbinc_key, ckp_scn, ckp_time, block_size, 
                    controlfile_type, blocks, pdb_key
               FROM bcf
              WHERE bcf.bs_key = bs_key_new
                AND (
                       bcf.ckp_scn          <> ckp_scn_new
                    OR bcf.ckp_time         <> ckp_time_new
                    OR bcf.block_size       <> block_size_new
                    OR bcf.controlfile_type <> controlfile_type_new
                    OR bcf.blocks           <> blocks_new
                    );
         BEGIN
           FOR conflict_rec IN bcf_conflicts(addBackupControlFile.bs_key, 
                                   addBackupControlFile.ckp_scn,
                                   addBackupControlFile.ckp_time,
                                   addBackupControlFile.block_size,
                                   addBackupControlFile.controlfile_type,
                                   addBackupControlFile.blocks)
           LOOP
             deb('addBackupControlfile set stamp set count existing rec- ' ||
                 ' bs_key '           || to_char(conflict_rec.bs_key)      ||
                 ' bcf_key '          || to_char(conflict_rec.bcf_key)     ||
                 ' dbinc_key '        || to_char(conflict_rec.dbinc_key)   ||
                 ' ckp_scn '          || to_char(conflict_rec.ckp_scn)     ||
                 ' ckp_time '         || to_char(conflict_rec.ckp_time)    ||
                 ' block_size '       || to_char(conflict_rec.block_size)  ||
                 ' controlfile_type ' || conflict_rec.controlfile_type     ||
                 ' blocks '           || to_char(conflict_rec.blocks)      ||
                 ' pdb_key '          || to_char(conflict_rec.pdb_key));
           END LOOP;
           deb('addBackupControlfile set stamp set count new conflict rec- ' ||
               ' bs_key '      || to_char(addBackupControlfile.bs_key)     ||
               ' dbinc_key '   || to_char(addBackupControlfile.dbinc_key)  ||
               ' ckp_scn '     || to_char(addBackupControlfile.ckp_scn)    ||
               ' ckp_time '    || to_char(addBackupControlfile.ckp_time)   ||
               ' block_size '  || to_char(addBackupControlfile.block_size) ||
               ' controlfile_type ' || addBackupControlfile.controlfile_type ||
               ' blocks '      || to_char(addBackupControlfile.blocks)     ||
               ' pdb_key '     || to_char(addBackupControlfile.pdb_key));
         END;
         raise_application_error(-20110, 'set stamp set count conflict');
      END IF;
 
--
--
      SELECT ckp_scn, ckp_time, bcf_recid, bcf_stamp INTO 
             local.ckp_scn, local.ckp_time, local.bcf_recid, local.bcf_stamp
      FROM bcf
      WHERE bcf.bs_key = addBackupControlFile.bs_key;
 
--
      IF (ckp_scn <> local.ckp_scn or ckp_time <> local.ckp_time) THEN
        deb('addBackupControlfile - ckp_scn '||ckp_scn||' ckp_time '||
            to_char(ckp_time));
        deb('addBackupControlfile - lckp_scn '||local.ckp_scn||' lckp_time '||
            to_char(local.ckp_time));
        raise_application_error(-20095, 'Invalid ckp_scn or ckp_time');
      END IF;
 
--
      IF local.bcf_recid <> bcf_recid or local.bcf_stamp <> bcf_stamp THEN
         UPDATE bcf set bcf_recid = addBackupControlFile.bcf_recid,
                        bcf_stamp = addBackupControlFile.bcf_stamp
         WHERE bcf.bs_key = addBackupControlFile.bs_key;
      END IF;
  END;
END addBackupControlFile;
 
PROCEDURE addBackupDataFile(
  bs_key          IN NUMBER
 ,bdf_recid       IN NUMBER
 ,bdf_stamp       IN NUMBER
 ,file#           IN NUMBER
 ,create_scn      IN NUMBER
 ,dbinc_key       IN NUMBER
 ,incr_level      IN NUMBER
 ,incr_scn        IN NUMBER
 ,ckp_scn         IN NUMBER
 ,ckp_time        IN DATE
 ,abs_fuzzy_scn   IN NUMBER
 ,datafile_blocks IN NUMBER
 ,blocks          IN NUMBER
 ,block_size      IN NUMBER
 ,completion_time IN DATE
 ,blocks_read     IN NUMBER
 ,create_time     IN DATE
 ,marked_corrupt  IN NUMBER
 ,used_chg_track  IN VARCHAR2
 ,used_optim      IN VARCHAR2
 ,foreign_dbid      IN NUMBER
 ,plugged_readonly  IN VARCHAR2
 ,plugin_scn        IN NUMBER
 ,plugin_reset_scn  IN NUMBER
 ,plugin_reset_time IN DATE
 ,section_size      IN NUMBER
 ,pdb_key           IN NUMBER
 ,sparse_backup     IN VARCHAR2
 ,isReSync          IN BOOLEAN
 ,isVirtual         IN BOOLEAN
) IS
 
local            bdf%rowtype;
l_conflict_count NUMBER          := 0;
l_UB4MAXVAL      CONSTANT NUMBER := 4294967295;
 
BEGIN
 
  deb('addBackupDataFile - bs_key ' || bs_key || '  file# ' || file#);
 
  BEGIN
    INSERT INTO bdf(bdf_key, dbinc_key, bdf_recid, bdf_stamp, bs_key,
       file#, create_scn, incr_level, incr_scn,
       ckp_scn, ckp_time, abs_fuzzy_scn, datafile_blocks, blocks, block_size,
       completion_time, blocks_read, create_time, marked_corrupt,
       used_chg_track, used_optim, foreign_dbid, plugged_readonly,
       plugin_scn, plugin_reset_scn, plugin_reset_time, section_size,
       pdb_key, sparse_backup)
    VALUES
      (rman_seq.nextval, dbinc_key, bdf_recid, bdf_stamp, bs_key,
       file#, create_scn, incr_level, incr_scn,
       ckp_scn, ckp_time, abs_fuzzy_scn, datafile_blocks, blocks, block_size,
       completion_time, nvl(blocks_read, datafile_blocks), create_time, 
       marked_corrupt, decode(used_chg_track, 'YES', 'Y', 'N'),
       decode(used_optim, 'YES', 'Y', 'N'), foreign_dbid, plugged_readonly,
       plugin_scn, plugin_reset_scn, plugin_reset_time, section_size,
       pdb_key, sparse_backup);
    IF (duplicatebs.exists(addBackupDataFile.bs_key)) THEN
       DECLARE
         CURSOR bdf_conflicts(bs_key_new IN NUMBER) IS
           SELECT bs_key, bdf_key, dbinc_key, file#, bdf_recid, bdf_stamp,
                  ckp_scn, ckp_time, datafile_blocks, block_size, plugin_scn, 
                  section_size
             FROM bdf
            WHERE bdf.bs_key = bs_key_new;
         conflict_rec bdf_conflicts%rowtype;
       BEGIN
         FOR conflict_rec IN bdf_conflicts(addBackupDatafile.bs_key)
         LOOP
           deb('addBackupDatafile set stamp set count conflict - '         ||
               ' bs_key '          || to_char(conflict_rec.bs_key)          ||
               ' bdf_key '         || to_char(conflict_rec.bdf_key)         ||
               ' dbinc_key '       || to_char(conflict_rec.dbinc_key)       ||
               ' file# '           || to_char(conflict_rec.file#)           ||
               ' bdf_recid '       || to_char(conflict_rec.bdf_recid)       ||
               ' bdf_stamp '       || to_char(conflict_rec.bdf_stamp)       ||
               ' ckp_scn '         || to_char(conflict_rec.ckp_scn)         ||
               ' ckp_time '        || to_char(conflict_rec.ckp_time)        ||
               ' datafile_blocks ' || to_char(conflict_rec.datafile_blocks) ||
               ' block_size '      || to_char(conflict_rec.block_size)      ||
               ' plugin_scn '      || to_char(conflict_rec.plugin_scn)      ||
               ' section_size '    || to_char(conflict_rec.section_size));
           END LOOP;
         END;
       raise_application_error(-20110, 'set stamp set count conflict');
    END IF;
 
  EXCEPTION
    WHEN dup_val_on_index THEN
      deb('addBackupDataFile - Inside dup_val_on_index exception');
 
      SELECT count(*) INTO l_conflict_count 
        FROM bdf
       WHERE bdf.bs_key = addBackupDataFile.bs_key 
         AND bdf.file#  = addBackupDataFile.file# 
         AND (
                bdf.ckp_scn         <> addBackupDataFile.ckp_scn 
             OR bdf.ckp_time        <> addBackupDataFile.ckp_time
             OR bdf.datafile_blocks <> addBackupDataFile.datafile_blocks
             OR bdf.block_size      <> addBackupDataFile.block_size
             OR bdf.plugin_scn      <> addBackupDataFile.plugin_scn
             ) 
         AND ROWNUM    = 1;
              
      
      deb('addBackupDataFile - l_conflict_count: '|| l_conflict_count);
      deb('addBackupDataFile - sect size: '|| addBackupDataFile.section_size);
  
      IF (l_conflict_count > 0 AND addBackupDataFile.section_size = 0) THEN
         DECLARE
           CURSOR bdf_conflicts(bs_key_new          IN NUMBER
                               ,file_new            IN NUMBER 
                               ,ckp_scn_new         IN NUMBER
                               ,ckp_time_new        IN DATE
                               ,datafile_blocks_new IN NUMBER
                               ,block_size_new      IN NUMBER
                               ,plugin_scn_new      IN NUMBER) 
           IS
             SELECT bs_key, bdf_key, dbinc_key, file#, bdf_recid, bdf_stamp,
                    ckp_scn, ckp_time, datafile_blocks, block_size, plugin_scn,
                    section_size 
               FROM bdf
              WHERE bdf.bs_key = bs_key_new
                AND bdf.file#  = file_new
                AND (
                       bdf.ckp_scn         <> ckp_scn_new
                    OR bdf.ckp_time        <> ckp_time_new
                    OR bdf.datafile_blocks <> datafile_blocks_new
                    OR bdf.block_size      <> block_size_new
                    OR bdf.plugin_scn      <> plugin_scn_new
                    );
           conflict_rec bdf_conflicts%rowtype;
         BEGIN
           FOR conflict_rec IN bdf_conflicts(
                                   addBackupDatafile.bs_key,
                                   addBackupDatafile.file#, 
                                   addBackupDatafile.ckp_scn, 
                                   addBackupDatafile.ckp_time, 
                                   addBackupDatafile.datafile_blocks, 
                                   addBackupDatafile.block_size, 
                                   addBackupDatafile.plugin_scn)
           LOOP
             deb('addBackupDatafile set stamp set count existing rec-'       ||
                 ' bs_key '     || to_char(conflict_rec.bs_key)              ||
                 ' bdf_key '    || to_char(conflict_rec.bdf_key)             ||
                 ' dbinc_key '  || to_char(conflict_rec.dbinc_key)           ||
                 ' file# '      || to_char(conflict_rec.file#)               ||
                 ' bdf_recid '  || to_char(conflict_rec.bdf_recid)           ||
                 ' bdf_stamp '  || to_char(conflict_rec.bdf_stamp)           ||
                 ' ckp_scn '    || to_char(conflict_rec.ckp_scn)             ||
                 ' ckp_time '   || to_char(conflict_rec.ckp_time)            ||
                 ' dfbloks '    || to_char(conflict_rec.datafile_blocks)     ||
                 ' block_size ' || to_char(conflict_rec.block_size)          ||
                 ' plugin_scn ' || to_char(conflict_rec.plugin_scn)          ||
                 ' secsize '    || to_char(conflict_rec.section_size));
             END LOOP;
             deb('addBackupDatafile set stamp set count new conflict rec- '  ||
                 ' bs_key '    || to_char(addBackupDataFile.bs_key)          ||
                 ' dbinc_key'  || to_char(addBackupDataFile.dbinc_key)       ||
                 ' file# '     || to_char(addBackupDataFile.file#)           ||
                 ' bdf_recid ' || to_char(addBackupDataFile.bdf_recid)       ||
                 ' bdf_stamp ' || to_char(addBackupDataFile.bdf_stamp)       ||
                 ' ckp_scn '   || to_char(addBackupDataFile.ckp_scn)         ||
                 ' ckp_time '  || to_char(addBackupDataFile.ckp_time)        ||
                 ' dfblocks '  || to_char(addBackupDataFile.datafile_blocks) ||
                 ' block_size '|| to_char(addBackupDataFile.block_size)      ||
                 ' plugin_scn '|| to_char(addBackupDataFile.plugin_scn)      ||
                 ' secsize '   || to_char(addBackupDataFile.section_size));
           END;
         raise_application_error(-20110, 'set stamp set count conflict');
      END IF;
 
--
--
      SELECT dbinc_key, create_scn, bdf_key, bdf_recid,
             bdf_stamp, plugin_scn, completion_time,
             abs_fuzzy_scn, datafile_blocks, blocks,
             nvl(blocks_read, datafile_blocks), ckp_scn, ckp_time,
             used_optim, used_chg_track, nvl(marked_corrupt, 0)
        INTO local.dbinc_key, local.create_scn, local.bdf_key, local.bdf_recid,
             local.bdf_stamp, local.plugin_scn, local.completion_time,
             local.abs_fuzzy_scn, local.datafile_blocks, local.blocks,
             local.blocks_read, local.ckp_scn, local.ckp_time,
             local.used_optim, local.used_chg_track, local.marked_corrupt
      FROM bdf
      WHERE bdf.bs_key = addBackupDataFile.bs_key
        AND bdf.file#  = addBackupDataFile.file#;
 
--
      deb('addBackupDataFile - dbinc_key: ' ||to_char(dbinc_key));
      deb('addBackupDataFile - local.dbinc_key: '|| to_char(local.dbinc_key) ||
          ' local.completion_time: '|| to_char(local.completion_time) ||
          ' local.abs_fuzzy_scn: '|| to_char(local.abs_fuzzy_scn) ||
          ' local.blocks_read: '|| to_char(local.blocks_read) ||
          ' local.marked_corrupt: '|| to_char(local.marked_corrupt));
 
      IF (dbinc_key <> local.dbinc_key) THEN
        raise_application_error(-20096, 'Invalid dbinc_key');
      END IF;
 
      IF (create_scn <> local.create_scn AND
          plugin_scn <> local.plugin_scn) THEN
        raise_application_error(-20097, 'Invalid create scn');
      END IF;
 
--
--
      IF bdf_recid <> local.bdf_recid OR bdf_stamp <> local.bdf_stamp THEN
         local.bdf_recid := bdf_recid;
         local.bdf_stamp := bdf_stamp;
      END IF;
 
--
--
      IF (local.completion_time < addBackupDataFile.completion_time) THEN
        local.completion_time := addBackupDataFile.completion_time;
      END IF;
 
      /*
       * Following are the scenarios that traverse this code path:
       *
       * 1. Resync: resync can happen for both normal msection
       *    backups and virtual msection backups. If a resync
       *    happens during processing of these backups, like say
       *    there are 5 section pieces, and the resync happens
       *    once after the 3rd piece, and once after all 5 pieces,
       *    then the data stored in blocks_read, blocks and marked_corrupt
       *    may be a little more than it needs to be. However,
       *    ckp_scn and abs_fuzzy_scn would be fine as we are taking
       *    the minimum and maximum of each respectively.
       *    In the case of the other parameters, we need to accumulate
       *    their values across sections and there is no easy way
       *    to achieve that.
       * 2. Prior to 12.2, parameters blocks_read, blocks and marked_corrupt
       *    are at value '0'. However, there is a fix in progress to 
       *    capture the actual values. Once that lands, the scenario
       *    listed in #1 will further manifest itself, with larger than
       *    possible values for blocks, blocks_read and marked_corrupt
       * 3. We need to limit the calculations for copy#1, that way copy to tape
       *    or additional copies created on the backup command using copies
       *    does not further throw off the values on blocks_read, blocks
       *    or marked_corrupt. However, there is no easy way to determine
       *    that at this point in code. Copy2tape currently sets a value
       *    of zero only.
       *
       *  For now, we will take minimum of checkpoint scn's and maximum of 
       *  absolute fuzzy scn's. And only in the case of msection case,
       *  add the values of blocks, blocks_read and marked_corrupt 
       */
 
--
--
--
      IF (local.ckp_scn > addBackupDataFile.ckp_scn) THEN
         deb('addBackupDataFile - updated bdf ckp_scn: '||
             to_char(addBackupDataFile.ckp_scn) || ' local bdf ckp_scn:' ||
             to_char(local.ckp_scn));
         local.ckp_scn  := addBackupDataFile.ckp_scn;
         local.ckp_time := addBackupDataFile.ckp_time;
      END IF;
 
      /*
       * This applies to regular backups as well but more so for multi-section 
       * backup.
       * Lets assume that there are two sections  (ckp_scn, abs_scn) notation.
       *
       * Section 1: (100, 101)
       * Section 2: (200, 0)  this is not fuzzy. however there can be blocks 
       *           at 150, 160..
       * IF you were to perform a point in time recovery scenario to 150 and 
       * if you take the minimum of the checkpointscns and the maximum of the 
       * absolute fuzzy then the restored datafile will be (100, 101). 
       * This is wrong as recovery will not be able to unfuzzy the block at 
       * scn 150, 160.. as it cannot roll backwards.
       *
       * The correct way of addressing this is to update the bdf with the 
       * appropriate fuzziness by also taking into fact the checkpoint of the 
       * file
       * This is done in restore logic as below (krbr.c:krbr3b2)
       *          f->curfuzz_krbrf =
       *          (*KSCNMAX(f->pkcvfh_krbrf->kcvfhafs,
       *                    KSCNMAX(f->pkcvfh_krbrf->kcvfhrfs,
       *                            f->pkcvfh_krbrf->kcvfhckp.kcvcpscn)));
       *
       * The same is being done below.
       */
 
--
--
      deb('addBackupDataFile - bdf local.abs_fuzzy_scn: ' ||
          to_char(local.abs_fuzzy_scn));
      local.abs_fuzzy_scn :=
         GREATEST(local.abs_fuzzy_scn, addBackupDataFile.abs_fuzzy_scn);
--
--
      IF (local.abs_fuzzy_scn < local.ckp_scn) THEN
         local.abs_fuzzy_scn := 0;
         deb('addBackupDataFile - updated bdf abs_fuzzy_scn to 0');
      END IF;
 
      IF (local.abs_fuzzy_scn = addBackupDataFile.abs_fuzzy_scn) THEN
        deb('addBackupDataFile - updated bdf abs_fuzzy_scn: '||
            to_char(local.abs_fuzzy_scn));
      END IF;
 
--
--
      local.datafile_blocks :=
         GREATEST(local.datafile_blocks, addBackupDataFile.datafile_blocks);
 
--
--
--
--
--
--
--
--
      IF (isVirtual AND addBackupDataFile.section_size > 0) THEN
        local.blocks_read := local.blocks_read + addBackupDataFile.blocks_read;
        local.blocks      := local.blocks + addBackupDataFile.blocks;
        local.marked_corrupt :=
           local.marked_corrupt + addBackupDataFile.marked_corrupt;
      ELSE
        local.blocks_read :=
           GREATEST(local.blocks_read, addBackupDataFile.blocks_read);
        local.blocks :=
           GREATEST(local.blocks, addBackupDataFile.blocks);
        local.marked_corrupt :=
           GREATEST(local.marked_corrupt, addBackupDataFile.marked_corrupt);
      END IF;
 
--
      local.blocks      := LEAST(local.blocks, local.datafile_blocks);
      local.blocks_read := LEAST(local.blocks_read, local.datafile_blocks);
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
      IF (local.blocks > l_UB4MAXVAL) THEN
--
         deb('addBackupDataFile - blocks overflow'||
              to_char(local.blocks) || ' ' ||
              to_char(local.datafile_blocks));
         local.blocks := l_UB4MAXVAL;
      END IF;
 
      IF (local.blocks_read > l_UB4MAXVAL) THEN
--
         deb('addBackupDataFile - blocks_read overflow'||
              to_char(local.blocks_read) || ' ' ||
              to_char(local.datafile_blocks));
         local.blocks_read := l_UB4MAXVAL;
      END IF;
 
      IF (addBackupDataFile.used_chg_track = 'YES') THEN
         local.used_chg_track := 'Y';
      END IF;
 
      IF (addBackupDataFile.used_optim = 'YES') THEN
         local.used_optim := 'Y';
      END IF;
 
--
--
      UPDATE bdf
         SET bdf_recid       = local.bdf_recid,
             bdf_stamp       = local.bdf_stamp,
             completion_time = local.completion_time,
             ckp_scn         = local.ckp_scn,
             ckp_time        = local.ckp_time,
             abs_fuzzy_scn   = local.abs_fuzzy_scn,
             blocks_read     = local.blocks_read,
             blocks          = local.blocks,
             datafile_blocks = local.datafile_blocks,
             marked_corrupt  = local.marked_corrupt,
             used_chg_track  = local.used_chg_track,
             used_optim      = local.used_optim
       WHERE bdf.bdf_key = local.bdf_key;
  END;
END addBackupDataFile;
 
FUNCTION beginBackupDataFileResync RETURN NUMBER IS
BEGIN
  checkResync;
 
  IF (this_cf_type = 'CURRENT' OR
      (this_cf_type = 'STANDBY' AND this_db_unique_name is not null)) THEN
     SELECT high_bdf_recid INTO last_bdf_recid
     FROM node
     WHERE site_key = this_site_key;
  ELSE
     last_bdf_recid := sessionWaterMarks.high_bdf_recid;
  END IF;
 
  deb('beginBackupDataFileResync returning' || last_bdf_recid);
  RETURN last_bdf_recid;
END beginBackupDataFileResync;
 
 
PROCEDURE checkBackupDataFile(
  bdf_recid       IN NUMBER
 ,bdf_stamp       IN NUMBER
 ,set_stamp       IN NUMBER
 ,set_count       IN NUMBER
 ,file#           IN NUMBER
 ,create_scn      IN NUMBER
 ,create_time     IN DATE
 ,reset_scn       IN NUMBER
 ,reset_time      IN DATE
 ,incr_level      IN NUMBER
 ,incr_scn        IN NUMBER
 ,ckp_scn         IN NUMBER
 ,ckp_time        IN DATE
 ,abs_fuzzy_scn   IN NUMBER
 ,datafile_blocks IN NUMBER
 ,blocks          IN NUMBER
 ,block_size      IN NUMBER
 ,min_offr_recid  IN NUMBER
 ,completion_time IN DATE
 ,controlfile_type
                    IN VARCHAR2       DEFAULT NULL
 ,cfile_abck_year   IN NUMBER         DEFAULT NULL -- contains marked_corrupt
 ,cfile_abck_mon_day
                    IN NUMBER         DEFAULT NULL -- contains media_corrupt
 ,cfile_abck_seq    IN NUMBER         DEFAULT NULL -- contains logical_corrupt
 ,chk_last_recid    IN BOOLEAN        DEFAULT TRUE
 ,blocks_read       IN NUMBER         DEFAULT NULL
 ,used_chg_track    IN VARCHAR2       DEFAULT 'NO'
 ,used_optim        IN VARCHAR2       DEFAULT 'NO'
 ,foreign_dbid      IN NUMBER         DEFAULT 0
 ,plugged_readonly  IN VARCHAR2       DEFAULT 'NO'
 ,plugin_scn        IN NUMBER         DEFAULT 0
 ,plugin_reset_scn  IN NUMBER         DEFAULT 0
 ,plugin_reset_time IN DATE           DEFAULT NULL
 ,section_size      IN NUMBER         DEFAULT NULL
 ,guid              IN RAW            DEFAULT NULL
 ,sparse_backup     IN VARCHAR2       DEFAULT 'NO'
 ,isReSync          IN BOOLEAN        DEFAULT TRUE
 ,isVirtual         IN BOOLEAN        DEFAULT FALSE
 ,dropped_pdb       IN BINARY_INTEGER DEFAULT 0
) IS
 
bs_key    NUMBER;
dbinc_key NUMBER;
l_pdb_key NUMBER;
 
BEGIN
 
--
 IF chk_last_recid THEN
    IF (last_bdf_recid IS NULL) THEN
       raise_application_error(-20037, 'Invalid last recid');
    END IF;
 
    IF (bdf_recid < last_bdf_recid) THEN
       raise_application_error(-20036, 'Invalid record order');
    END IF;
 
    IF (bdf_recid > last_bdf_recid + 1) THEN
--
       NULL;
    END IF;
    last_bdf_recid := bdf_recid;
  END IF;
 
--
  BEGIN
    SELECT bs_key INTO bs_key
    FROM bs
    WHERE bs.db_key = this_db_key
    AND   bs.set_stamp = checkBackupDataFile.set_stamp
    AND   bs.set_count = checkBackupDataFile.set_count FOR UPDATE OF bs.bs_key;
    deb('checkBackupDataFile - locked bs_key' || bs_key);
  EXCEPTION
    WHEN no_data_found THEN
--
--
--
--
--
--
--
       return;
  END;
 
  BEGIN
--
--
    IF (checkBackupDatafile.incr_level > 0) THEN
      UPDATE bs SET bs.incr_level = checkBackupDataFile.incr_level,
                    bs.bck_type = 'I'
      WHERE bs.bs_key = checkBackupDataFile.bs_key
      AND   bs.bck_type IS NULL;
    ELSE
      UPDATE bs SET bs.incr_level = checkBackupDataFile.incr_level,
                    bs.bck_type = 'D'
      WHERE bs.bs_key = checkBackupDataFile.bs_key
      AND   bs.bck_type IS NULL;
    END IF;
    IF (file# = 0 and controlfile_type is not null) then
      UPDATE bs SET bs.controlfile_included=
                 decode(checkBackupDatafile.controlfile_type,'B','BACKUP',
                                                             'S','STANDBY',
                                                             'NONE')
      WHERE bs.bs_key = checkBackupDataFile.bs_key
      AND   bs.controlfile_included = 'NONE';
    END IF;
  END;
 
--
  dbinc_key := checkIncarnation(reset_scn, reset_time);
 
  l_pdb_key := guidToPdbKey(guid, dropped_pdb);
 
  IF (file# = 0) THEN
    addBackupControlFile(bs_key, bdf_recid, bdf_stamp, dbinc_key,
         ckp_scn, ckp_time, create_time, min_offr_recid, blocks, block_size,
         controlfile_type, cfile_abck_year, cfile_abck_mon_day,
         cfile_abck_seq, l_pdb_key);
  ELSE
    addBackupDataFile(bs_key, bdf_recid, bdf_stamp, file#, create_scn,
         dbinc_key, incr_level, incr_scn, ckp_scn, ckp_time,
         abs_fuzzy_scn, datafile_blocks, blocks, block_size, completion_time,
         blocks_read, create_time, cfile_abck_year, used_chg_track, 
         used_optim, foreign_dbid, plugged_readonly, plugin_scn,
         plugin_reset_scn, plugin_reset_time, section_size, l_pdb_key,
         sparse_backup, isReSync, isVirtual);
  END IF;
 
END checkBackupDataFile;
 
PROCEDURE endBackupDataFileResync IS
BEGIN
  IF (this_cf_type = 'CURRENT' OR
      (this_cf_type = 'STANDBY' AND this_db_unique_name is not null)) THEN
     UPDATE node SET high_bdf_recid = last_bdf_recid
     WHERE site_key = this_site_key;
  END IF;
 
  sessionWaterMarks.high_bdf_recid := last_bdf_recid;
  last_bdf_recid := NULL;
 
END endBackupDataFileResync;
 
/*-----------------------*
 * Backup SPFILE resync  *
 *-----------------------*/
 
FUNCTION beginBackupSpFileResync RETURN NUMBER IS
BEGIN
  checkResync;
 
  IF (this_cf_type = 'CURRENT' OR
      (this_cf_type = 'STANDBY' AND this_db_unique_name is not null)) THEN
     SELECT high_bsf_recid INTO last_bsf_recid
     FROM node
     WHERE site_key = this_site_key;
  ELSE
     last_bsf_recid := sessionWaterMarks.high_bsf_recid;
  END IF;
 
  RETURN last_bsf_recid;
END beginBackupSpFileResync;
 
PROCEDURE addBackupSpFile(
  bs_key             IN NUMBER
 ,bsf_recid          IN NUMBER
 ,bsf_stamp          IN NUMBER
 ,modification_time  IN DATE
 ,bytes              IN NUMBER
 ,db_unique_name     IN VARCHAR2
 ,pdb_key            IN NUMBER
) IS
 
local    bsf%rowtype;
l_conflict_count number := 0 ;
BEGIN
  deb('addBackupSpfile');
  INSERT INTO bsf(bsf_key, bs_key, db_key, bsf_recid, bsf_stamp,
                  modification_time, bytes, db_unique_name, pdb_key)
  VALUES (rman_seq.nextval, bs_key, this_db_key, bsf_recid, bsf_stamp,
          modification_time, bytes, db_unique_name, pdb_key);
  IF (duplicatebs.exists(addBackupSpFile.bs_key)) THEN
     DECLARE
       CURSOR bsf_conflicts(bs_key_new IN NUMBER ) IS
         SELECT bs_key, bsf_key, bsf_recid, bsf_stamp, bytes, pdb_key 
           FROM bsf
          WHERE bsf.bs_key = bs_key_new;
       conflict_rec bsf_conflicts%rowtype;
     BEGIN
       FOR conflict_rec IN bsf_conflicts(addBackupSpFile.bs_key)
       LOOP
         deb('addBackupSpFile set stamp set count conflict - ' ||
             ' bs_key '    || to_char(conflict_rec.bs_key)       ||
             ' bsf_key '   || to_char(conflict_rec.bsf_key)      ||
             ' bsf_recid ' || to_char(conflict_rec.bsf_recid)    ||
             ' bsf_stamp ' || to_char(conflict_rec.bsf_stamp)    ||
             ' bytes '     || to_char(conflict_rec.bytes)        ||
             ' pdb_key '   || to_char(conflict_rec.pdb_key));
       END LOOP;
     END;
     raise_application_error(-20110, 'set stamp set count conflict');
  END IF;
 
EXCEPTION
  WHEN dup_val_on_index THEN
    deb('addBackupSpfile - Inside dup_val_on_index exception');
--
--
--
--
 
--
--
    SELECT * INTO local
    FROM bsf
    WHERE bsf.bs_key = addBackupSpFile.bs_key;
 
--
    IF (modification_time <> local.modification_time) THEN
      raise_application_error(-20101, 'Invalid modification_time');
    END IF;
 
--
    IF (db_unique_name <> local.db_unique_name) THEN
      raise_application_error(-20101, 
                           'Invalid db_unique_name=' || db_unique_name ||
                           'expected db_unique_name=' || local.db_unique_name);
    END IF;
 
--
    IF local.bsf_recid <> bsf_recid or local.bsf_stamp <> bsf_stamp THEN
       UPDATE bsf set bsf_recid = addBackupSpFile.bsf_recid,
                      bsf_stamp = addBackupSpFile.bsf_stamp
       WHERE bsf.bs_key = addBackupSpFile.bs_key;
    END IF;
END addBackupSpFile;
 
PROCEDURE checkBackupSpFile(
  bsf_recid         IN NUMBER
 ,bsf_stamp         IN NUMBER
 ,set_stamp         IN NUMBER
 ,set_count         IN NUMBER
 ,modification_time IN DATE
 ,bytes             IN NUMBER
 ,chk_last_recid    IN BOOLEAN        DEFAULT TRUE
 ,db_unique_name    IN VARCHAR2       DEFAULT NULL
 ,guid              IN RAW            DEFAULT NULL
 ,dropped_pdb       IN BINARY_INTEGER DEFAULT 0
) IS
 
bs_key    NUMBER;
site_key  NUMBER;
l_pdb_key NUMBER;
 
BEGIN
  IF chk_last_recid THEN
     IF (last_bsf_recid IS NULL) THEN
       raise_application_error(-20037, 'Invalid last recid');
     END IF;
 
    IF (bsf_recid < last_bsf_recid) THEN
       raise_application_error(-20036, 'Invalid record order');
     END IF;
 
     IF (bsf_recid > last_bsf_recid + 1) THEN
--
       NULL;
     END IF;
     last_bsf_recid := bsf_recid;
  END IF;
 
--
  BEGIN
    SELECT bs_key INTO bs_key
    FROM bs
    WHERE bs.db_key = this_db_key
    AND   bs.set_stamp = checkBackupSpFile.set_stamp
    AND   bs.set_count = checkBackupSpFile.set_count FOR UPDATE OF bs.bs_key;
    deb('checkBackupSpFile - locked bs_key' || bs_key);
  EXCEPTION
    WHEN no_data_found THEN
       return;
  END;
 
--
--
  UPDATE bs SET bs.bck_type = 'D'
   WHERE bs.bs_key = checkBackupSpFile.bs_key
     AND bs.bck_type IS NULL;
 
  l_pdb_key := guidToPdbKey(guid, dropped_pdb);
 
  addBackupSpFile(bs_key, bsf_recid, bsf_stamp, modification_time, bytes, 
                  db_unique_name, l_pdb_key);
 
END checkBackupSpFile;
 
PROCEDURE endBackupSpFileResync IS
BEGIN
  IF (this_cf_type = 'CURRENT' OR
      (this_cf_type = 'STANDBY' AND this_db_unique_name is not null)) THEN
     UPDATE node SET high_bsf_recid = last_bsf_recid
     WHERE site_key = this_site_key;
  END IF;
 
  sessionWaterMarks.high_bsf_recid := last_bsf_recid;
  last_bsf_recid := NULL;
 
END endBackupSpFileResync;
 
/*-------------------------*
 * Backup Redo Log resync  *
 *-------------------------*/
 
FUNCTION beginBackupRedoLogResync RETURN NUMBER IS
BEGIN
  checkResync;
 
  IF (this_cf_type = 'CURRENT' OR
      (this_cf_type = 'STANDBY' AND this_db_unique_name is not null)) THEN
     SELECT high_brl_recid INTO last_brl_recid
     FROM node
     WHERE site_key = this_site_key;
  ELSE
     last_brl_recid := sessionWaterMarks.high_brl_recid;
  END IF;
 
  RETURN last_brl_recid;
END beginBackupRedoLogResync;
 
PROCEDURE checkBackupRedoLog(
  brl_recid      IN NUMBER
 ,brl_stamp      IN NUMBER
 ,set_stamp      IN NUMBER
 ,set_count      IN NUMBER
 ,thread#        IN NUMBER
 ,sequence#      IN NUMBER
 ,reset_scn      IN NUMBER
 ,reset_time     IN DATE
 ,low_scn        IN NUMBER
 ,low_time       IN DATE
 ,next_scn       IN NUMBER
 ,next_time      IN DATE
 ,blocks         IN NUMBER
 ,block_size     IN NUMBER
 ,chk_last_recid IN BOOLEAN  DEFAULT TRUE
 ,terminal       IN VARCHAR2 DEFAULT 'NO'
 ,activation     IN VARCHAR2 DEFAULT NULL
) IS
 
local brl%rowtype;
bskeep number;
l_conflict_count number :=0;
 
BEGIN
--
--
--
  IF brl_stamp = 0 THEN 
     deb('checkBackupRedoLog: ignoring this record as brl_stamp is 0'); 
     RETURN; 
  END IF; 
 
--
  IF chk_last_recid THEN
     IF (last_brl_recid IS NULL) THEN
        raise_application_error(-20037, 'Invalid last recid');
     END IF;
 
     IF (brl_recid < last_brl_recid) THEN
        raise_application_error(-20036, 'Invalid record order');
     END IF;
 
     IF (brl_recid > last_brl_recid + 1) THEN
--
--
        NULL;
     END IF;
     last_brl_recid := brl_recid;
  END IF;
 
  IF (this_dbinc_key IS NULL) THEN
    raise_application_error(-20020, 'Database incarnation not set');
  END IF;
 
--
  BEGIN
    SELECT bs_key,keep_options INTO local.bs_key, bskeep
    FROM bs
    WHERE bs.db_key = this_db_key
    AND   bs.set_stamp = checkBackupRedoLog.set_stamp
    AND   bs.set_count = checkBackupRedoLog.set_count FOR UPDATE OF bs.bs_key;
    deb('checkBackupRedoLog - locked bs_key' || local.bs_key);
  EXCEPTION
    WHEN no_data_found THEN
       RETURN;
  END;
 
  BEGIN
--
--
    UPDATE bs SET bs.bck_type = 'L'
    WHERE bs.bs_key = local.bs_key
    AND   bs.bck_type IS NULL;
  END;
 
--
  local.dbinc_key := checkIncarnation(reset_scn, reset_time);
 
  BEGIN
    INSERT INTO brl
        (brl_key, dbinc_key, brl_recid, brl_stamp,
         thread#, sequence#, low_scn, low_time, next_scn, next_time,
         blocks, block_size, bs_key, terminal, activation)
    VALUES
        (rman_seq.nextval, local.dbinc_key, brl_recid, brl_stamp,
         thread#, sequence#, low_scn, low_time, next_scn, next_time,
         blocks, block_size, local.bs_key, terminal, activation);
    IF (duplicatebs.exists(local.bs_key)) THEN
       DECLARE
         CURSOR brl_conflicts(bs_key_new IN NUMBER) IS
           SELECT bs_key, brl_key, dbinc_key, brl_recid, 
                  brl_stamp, thread#, sequence#, blocks, block_size 
             FROM brl
            WHERE brl.bs_key = bs_key_new;
         conflict_rec brl_conflicts%rowtype;
       BEGIN
         FOR conflict_rec IN brl_conflicts(local.bs_key)
         LOOP
           deb('checkBackupRedoLog set stamp set count conflict - ' ||
               ' bs_key '     || to_char(conflict_rec.bs_key)    ||
               ' brl_key '    || to_char(conflict_rec.brl_key)   ||
               ' dbinc_key '  || to_char(conflict_rec.dbinc_key) ||
               ' brl_recid '  || to_char(conflict_rec.brl_recid) ||
               ' brl_stamp '  || to_char(conflict_rec.brl_stamp) ||
               ' thread# '    || to_char(conflict_rec.thread#)   ||
               ' sequence# '  || to_char(conflict_rec.sequence#) ||
               ' blocks '     || to_char(conflict_rec.blocks)    ||
               ' block_size ' || to_char(conflict_rec.block_size));
         END LOOP;
       END;
       raise_application_error(-20110, 'set stamp set count conflict');
    END IF;
 
  EXCEPTION
    WHEN dup_val_on_index THEN
      deb('checkBackupRedoLog - Inside dup_val_on_index exception');
--
      SELECT count(*) INTO l_conflict_count
      FROM brl
      WHERE brl.bs_key = local.bs_key
        AND  brl.thread# = checkBackupRedoLog.thread#
        AND  brl.sequence# = checkBackupRedoLog.sequence#
        AND (
               brl.blocks     <> checkBackupRedoLog.blocks
            OR brl.block_size <> checkBackupRedoLog.block_size
            )
        AND ROWNUM = 1;
      IF (l_conflict_count > 0) THEN
         DECLARE
           CURSOR brl_conflicts(bs_key_new IN NUMBER, thread_new IN NUMBER, 
                                sequence_new IN NUMBER, blocks_new IN NUMBER,
                                block_size_new IN NUMBER ) 
           IS
             SELECT bs_key, brl_key, dbinc_key, brl_recid, brl_stamp, thread#,
                    sequence#, blocks, block_size
               FROM brl
              WHERE brl.bs_key = bs_key_new
                AND brl.thread# = thread_new
                AND brl.sequence# = sequence_new
                AND (
                       brl.blocks = blocks_new
                    OR brl.block_size = block_size_new
                    );
           conflict_rec brl_conflicts%rowtype;
         BEGIN
           FOR conflict_rec IN brl_conflicts(local.bs_key,
                                             checkBackupRedoLog.thread#,
                                             checkBackupRedoLog.sequence#,
                                             checkBackupRedoLog.blocks,
                                             checkBackupRedoLog.block_size)
           LOOP
             deb('checkBackupRedoLog set stamp set count existing rec-  '  || 
                 ' bs_key '         || to_char(conflict_rec.bs_key)    ||
                 ' brl_key '        || to_char(conflict_rec.brl_key)   ||
                 ' dbinc_key '      || to_char(conflict_rec.dbinc_key) ||
                 ' brl_recid '      || to_char(conflict_rec.brl_recid) ||
                 ' brl_stamp '      || to_char(conflict_rec.brl_stamp) ||
                 ' thread# '        || to_char(conflict_rec.thread#)   ||
                 ' sequence# '      || to_char(conflict_rec.sequence#) ||
                 ' blocks '         || to_char(conflict_rec.blocks)    ||
                 ' block_size '     || to_char(conflict_rec.block_size));
           END LOOP;
           deb('checkBackupRedoLog set stamp set count new conflict rec- '  ||
               ' bs_key '     || to_char(local.bs_key)    ||
               ' dbinc_key '  || to_char(local.dbinc_key) ||
               ' brl_recid '  || to_char(checkBackupRedoLog.brl_recid) ||
               ' brl_stamp '  || to_char(checkBackupRedoLog.brl_stamp) ||
               ' thread# '    || to_char(checkBackupRedoLog.thread#)   ||
               ' sequence# '  || to_char(checkBackupRedoLog.sequence#) ||
               ' blocks '     || to_char(checkBackupRedoLog.blocks)    ||
               ' block_size ' || to_char(checkBackupRedoLog.block_size));
         END;
         
         raise_application_error(-20110, 'set stamp set count conflict');
      END IF;
 
--
--
      SELECT low_scn, brl_recid, brl_stamp 
        INTO local.low_scn, local.brl_recid, local.brl_stamp
      FROM brl
      WHERE brl.bs_key = local.bs_key
       AND  brl.thread# = checkBackupRedoLog.thread#
       AND  brl.sequence# = checkBackupRedoLog.sequence#;
 
--
      IF (low_scn <> local.low_scn) THEN
        raise_application_error(-20098, 'Invalid low scn');
      END IF;
 
--
      IF local.brl_recid <> brl_recid or local.brl_stamp <> brl_stamp THEN
         UPDATE brl set brl_recid = checkBackupRedoLog.brl_recid,
                        brl_stamp = checkBackupRedoLog.brl_stamp
         WHERE brl.bs_key = local.bs_key
           AND brl.thread# = checkBackupRedoLog.thread#
           AND brl.sequence# = checkBackupRedoLog.sequence#;
      END IF;
  END;
 
  IF (bskeep > 0) THEN
    updateRestorePoint(low_scn, next_scn);
  END IF;
 
END checkBackupRedoLog;
 
PROCEDURE endBackupRedoLogResync IS
BEGIN
  IF (this_cf_type = 'CURRENT' OR
      (this_cf_type = 'STANDBY' AND this_db_unique_name is not null)) THEN
     UPDATE node SET high_brl_recid = last_brl_recid
     WHERE site_key = this_site_key;
  END IF;
 
  sessionWaterMarks.high_brl_recid := last_brl_recid;
  last_brl_recid := NULL;
 
END endBackupRedoLogResync;
 
/*----------------------------*
 * Datafile Copy resync       *
 *----------------------------*/
 
PROCEDURE deleteDuplicateCCF(recid IN NUMBER,
                             stamp IN NUMBER,
                             fname IN VARCHAR2) IS
   lfname ccf.fname%TYPE;
BEGIN
    lfname := fname;
 
    IF lfname IS NULL THEN
       BEGIN
          SELECT fname INTO lfname FROM ccf
          WHERE ccf.dbinc_key IN
                (SELECT dbinc_key FROM dbinc WHERE dbinc.db_key = this_db_key)
            AND ccf_recid   = recid
            AND ccf_stamp   = stamp;
       EXCEPTION
          WHEN no_data_found THEN
             RETURN;
          WHEN too_many_rows THEN -- unique_key is dbinc_key, recid and stamp
             RETURN;
       END;
    END IF;
 
--
    DELETE ccf
    WHERE ccf.dbinc_key IN
            (SELECT dbinc_key FROM dbinc WHERE dbinc.db_key = this_db_key)
    AND   ccf.fname = lfname
    AND   ((disk_backups_shared = TRUE#) OR
           (this_site_key = nvl(ccf.site_key, this_site_key)))
    AND   ccf.fname_hashkey = substr(lfname, 1, 10) || substr(lfname, -10)
    AND   NOT (ccf.ccf_recid = recid AND
               ccf.ccf_stamp = stamp);
 
END deleteDuplicateCCF;
 
PROCEDURE addControlFileCopy(
  ccf_recid        IN NUMBER
 ,ccf_stamp        IN NUMBER
 ,fname            IN VARCHAR2
 ,tag              IN VARCHAR2
 ,dbinc_key        IN NUMBER
 ,ckp_scn          IN NUMBER
 ,ckp_time         IN DATE
 ,create_time      IN DATE
 ,min_offr_recid   IN NUMBER
 ,block_size       IN NUMBER
 ,completion_time  IN DATE
 ,status           IN VARCHAR2
 ,controlfile_type IN VARCHAR2 DEFAULT NULL
 ,keep_options     IN NUMBER   DEFAULT 0
 ,keep_until       IN DATE     DEFAULT NULL
 ,is_recovery_dest_file IN VARCHAR2
 ,rsr_key          IN NUMBER   DEFAULT NULL
 ,blocks           IN NUMBER
 ,pdb_key          IN NUMBER
) IS
 
local    ccf%rowtype;
 
BEGIN
  BEGIN
    IF (status <> 'D') THEN
       INSERT INTO ccf(ccf_key, dbinc_key, ccf_recid, ccf_stamp, fname,
          fname_hashkey, tag,
          ckp_scn, ckp_time, create_time, min_offr_recid, block_size,
          completion_time, status, controlfile_type, keep_options, keep_until,
          is_recovery_dest_file, rsr_key, blocks, site_key, pdb_key)
       VALUES (rman_seq.nextval, dbinc_key, ccf_recid, ccf_stamp, fname,
         substr(fname,1,10)||substr(fname,-10), tag,
         ckp_scn, ckp_time, create_time, min_offr_recid, block_size,
         completion_time, status, controlfile_type, keep_options, keep_until,
         is_recovery_dest_file, rsr_key, blocks, this_site_key, pdb_key);
   
       deleteDuplicateCCF(ccf_recid, ccf_stamp, fname);
    END IF;
 
  EXCEPTION
    WHEN dup_val_on_index THEN
      deb('addControlFileCopy - Inside dup_val_on_index exception');
--
      SELECT * INTO local
      FROM ccf
      WHERE ccf.dbinc_key = addControlFileCopy.dbinc_key
      AND   ccf.ccf_recid = addControlFileCopy.ccf_recid
      AND   ccf.ccf_stamp = addControlFileCopy.ccf_stamp;
 
--
      IF client_site_aware AND this_site_key <> local.site_key THEN
          raise_application_error(-20081, 'change stamp for the record');
      END IF;
 
--
      IF (ckp_scn <> local.ckp_scn) THEN
        raise_application_error(-20095, 'Invalid ckp_scn');
      END IF;
 
--
      IF local.site_key IS NULL THEN
         UPDATE ccf SET site_key = this_site_key
         WHERE ccf.dbinc_key = addControlFileCopy.dbinc_key
           AND ccf.ccf_recid = addControlFileCopy.ccf_recid
           AND ccf.ccf_stamp = addControlFileCopy.ccf_stamp;
      END IF;
  END;
 
END addControlFileCopy;
 
PROCEDURE deleteDuplicateCDF(recid IN NUMBER,
                             stamp IN NUMBER,
                             fname IN VARCHAR2) IS
   lfname cdf.fname%TYPE;
BEGIN
    lfname := fname;
 
    IF lfname IS NULL THEN
       BEGIN
          SELECT fname INTO lfname FROM cdf
          WHERE cdf.dbinc_key IN
            (SELECT dbinc_key FROM dbinc WHERE dbinc.db_key = this_db_key)
            AND cdf_recid = recid
            AND cdf_stamp = stamp;
       EXCEPTION
          WHEN no_data_found THEN
             RETURN;
          WHEN too_many_rows THEN -- unique_key is dbinc_key, recid and stamp
             RETURN;
       END;
    END IF;
 
--
    DELETE cdf
    WHERE cdf.dbinc_key IN
            (SELECT dbinc_key FROM dbinc WHERE dbinc.db_key = this_db_key)
    AND   cdf.fname = lfname
    AND   ((disk_backups_shared = TRUE#) OR
           (this_site_key = nvl(cdf.site_key, this_site_key)))
    AND   cdf.fname_hashkey = substr(lfname, 1, 10) || substr(lfname, -10)
    AND   NOT (cdf.cdf_recid = recid AND
               cdf.cdf_stamp = stamp);
 
END deleteDuplicateCDF;
 
                             
PROCEDURE addDataFileCopy(
  cdf_recid       IN NUMBER
 ,cdf_stamp       IN NUMBER
 ,fname           IN VARCHAR2
 ,tag             IN VARCHAR2
 ,file#           IN NUMBER
 ,create_scn      IN NUMBER
 ,dbinc_key       IN NUMBER
 ,incr_level      IN NUMBER
 ,ckp_scn         IN NUMBER
 ,ckp_time        IN DATE
 ,onl_fuzzy       IN VARCHAR2
 ,bck_fuzzy       IN VARCHAR2
 ,abs_fuzzy_scn   IN NUMBER
 ,rcv_fuzzy_scn   IN NUMBER
 ,rcv_fuzzy_time  IN DATE
 ,blocks          IN NUMBER
 ,block_size      IN NUMBER
 ,completion_time IN DATE
 ,status          IN VARCHAR2
 ,keep_options    IN NUMBER
 ,keep_until      IN DATE
 ,scanned         IN VARCHAR2
 ,is_recovery_dest_file IN VARCHAR2
 ,rsr_key         IN NUMBER
 ,create_time     IN DATE
 ,marked_corrupt  IN NUMBER
 ,foreign_dbid      IN NUMBER
 ,plugged_readonly  IN VARCHAR2
 ,plugin_scn        IN NUMBER
 ,plugin_reset_scn  IN NUMBER
 ,plugin_reset_time IN DATE
 ,pdb_key           IN NUMBER
 ,sparse_backup     IN VARCHAR2
) IS
 
local    cdf%rowtype;
 
BEGIN
 
  BEGIN
    IF (status <> 'D') THEN
       INSERT INTO cdf(cdf_key, dbinc_key, cdf_recid, cdf_stamp,
          file#, create_scn, fname, fname_hashkey, tag, incr_level,
          ckp_scn, ckp_time, onl_fuzzy, bck_fuzzy, abs_fuzzy_scn,
          rcv_fuzzy_scn, rcv_fuzzy_time, blocks, block_size, completion_time,
          status, keep_options, keep_until, scanned, is_recovery_dest_file, 
          rsr_key, create_time, marked_corrupt, site_key, foreign_dbid,
          plugged_readonly, plugin_scn, plugin_reset_scn, plugin_reset_time,
          pdb_key, sparse_backup)
       VALUES
         (rman_seq.nextval, dbinc_key, cdf_recid, cdf_stamp,
          file#, create_scn, fname, substr(fname,1,10)||substr(fname, -10),
          tag, incr_level, ckp_scn, ckp_time,
          decode(onl_fuzzy,'YES','Y','NO','N'),
          decode(bck_fuzzy,'YES','Y','NO','N'), abs_fuzzy_scn,
          rcv_fuzzy_scn, rcv_fuzzy_time, blocks, block_size, completion_time,
          status, keep_options, keep_until,
          decode(scanned,'YES','Y','NO','N'), is_recovery_dest_file, 
          rsr_key, create_time, marked_corrupt, this_site_key,
          foreign_dbid, plugged_readonly, plugin_scn, plugin_reset_scn,
          plugin_reset_time, pdb_key, sparse_backup);
 
       deleteDuplicateCDF(cdf_recid, cdf_stamp, fname);
    END IF;
 
  EXCEPTION
    WHEN dup_val_on_index THEN
      deb('addDataFileCopy - Inside dup_val_on_index exception');
      SELECT * INTO local
      FROM cdf
      WHERE cdf.dbinc_key = addDataFileCopy.dbinc_key
      AND   cdf.cdf_recid = addDataFileCopy.cdf_recid
      AND   cdf.cdf_stamp = addDataFileCopy.cdf_stamp;
 
--
      IF client_site_aware AND this_site_key <> local.site_key THEN
          raise_application_error(-20081, 'change stamp for the record');
      END IF;
 
--
      IF (file# <> local.file#) THEN
        raise_application_error(-20096, 'Invalid file');
      END IF;
      IF (create_scn <> local.create_scn AND
          plugin_scn <> local.plugin_scn) THEN
        raise_application_error(-20097, 'Invalid create scn');
      END IF;
 
--
      IF local.site_key IS NULL THEN
         UPDATE cdf SET site_key = this_site_key
         WHERE cdf.dbinc_key = addDataFileCopy.dbinc_key
           AND cdf.cdf_recid = addDataFileCopy.cdf_recid
           AND cdf.cdf_stamp = addDataFileCopy.cdf_stamp;
      END IF;
  END;
 
END addDataFileCopy;
 
FUNCTION beginDataFileCopyResync RETURN NUMBER IS
BEGIN
  checkResync;
 
  IF (this_cf_type = 'CURRENT' OR
      (this_cf_type = 'STANDBY' AND this_db_unique_name is not null)) THEN
     SELECT high_cdf_recid INTO last_cdf_recid
     FROM node
     WHERE site_key = this_site_key;
  ELSE
     last_cdf_recid := sessionWaterMarks.high_cdf_recid;
  END IF;
 
  RETURN last_cdf_recid;
END beginDataFileCopyResync;
 
PROCEDURE checkDataFileCopy(
  cdf_recid        IN NUMBER
 ,cdf_stamp        IN NUMBER
 ,fname            IN VARCHAR2
 ,tag              IN VARCHAR2
 ,file#            IN NUMBER
 ,create_scn       IN NUMBER
 ,create_time      IN DATE
 ,reset_scn        IN NUMBER
 ,reset_time       IN DATE
 ,incr_level       IN NUMBER
 ,ckp_scn          IN NUMBER
 ,ckp_time         IN DATE
 ,onl_fuzzy        IN VARCHAR2
 ,bck_fuzzy        IN VARCHAR2
 ,abs_fuzzy_scn    IN NUMBER
 ,rcv_fuzzy_scn    IN NUMBER
 ,rcv_fuzzy_time   IN DATE
 ,blocks           IN NUMBER
 ,block_size       IN NUMBER
 ,min_offr_recid   IN NUMBER
 ,completion_time  IN DATE
 ,status           IN VARCHAR2
 ,controlfile_type IN VARCHAR2        DEFAULT NULL
 ,keep_options     IN NUMBER          DEFAULT 0
 ,keep_until       IN DATE            DEFAULT NULL
 ,scanned          IN VARCHAR2        DEFAULT 'NO'
 ,is_recovery_dest_file IN VARCHAR2   DEFAULT 'NO'
 ,rsr_recid        IN NUMBER          DEFAULT NULL
 ,rsr_stamp        IN NUMBER          DEFAULT NULL
 ,marked_corrupt   IN NUMBER          DEFAULT NULL
 ,foreign_dbid      IN NUMBER         DEFAULT 0
 ,plugged_readonly  IN VARCHAR2       DEFAULT 'NO'
 ,plugin_scn        IN NUMBER         DEFAULT 0
 ,plugin_reset_scn  IN NUMBER         DEFAULT 0
 ,plugin_reset_time IN DATE           DEFAULT NULL
 ,guid              IN RAW            DEFAULT NULL
 ,sparse_backup     IN VARCHAR2       DEFAULT 'NO'
 ,dropped_pdb       IN BINARY_INTEGER DEFAULT 0
) IS
 
dbinc_key NUMBER;
localrsr  rsr%rowtype;
l_pdb_key NUMBER;
 
BEGIN
  IF (last_cdf_recid IS NULL) THEN
    raise_application_error(-20037, 'Invalid last recid');
  END IF;
 
  IF (cdf_recid < last_cdf_recid) THEN
    raise_application_error(-20036, 'Invalid record order');
  END IF;
 
  IF (cdf_recid > last_cdf_recid + 1) THEN
--
--
    NULL;
  END IF;
  last_cdf_recid := cdf_recid;
 
  IF (cdf_stamp > 0 and cdf_stamp < kccdivts) THEN
     deb('checkBackupDatafileCopy - ignoring record kccdivts='||kccdivts);
     RETURN;                    -- obsolete record from a backup controlfile
  END IF;
 
--
  dbinc_key := checkIncarnation(reset_scn, reset_time);
 
  l_pdb_key := guidToPdbKey(guid, dropped_pdb);
 
--
  BEGIN
      SELECT rsr_key
        INTO localrsr.rsr_key
        FROM rsr
       WHERE rsr.dbinc_key = this_dbinc_key
         AND (rsr.site_key = this_site_key OR
              rsr.site_key is null AND this_site_key is null)
         AND rsr.rsr_stamp = checkDataFileCopy.rsr_stamp
         AND rsr.rsr_recid = checkDataFileCopy.rsr_recid;
  EXCEPTION
  WHEN no_data_found THEN
--
      NULL;
  END;
 
  IF (file# = 0) THEN
    addControlFileCopy(cdf_recid, cdf_stamp, fname, tag, dbinc_key,
         ckp_scn, ckp_time, create_time, min_offr_recid, block_size,
         completion_time, status, controlfile_type, keep_options, keep_until,
         is_recovery_dest_file, localrsr.rsr_key, blocks, l_pdb_key);
  ELSE
    addDataFileCopy(cdf_recid, cdf_stamp, fname, tag, file#, create_scn,
         dbinc_key, incr_level, ckp_scn, ckp_time,
         onl_fuzzy, bck_fuzzy, abs_fuzzy_scn, rcv_fuzzy_scn, rcv_fuzzy_time,
         blocks, block_size, completion_time, status,
         keep_options, keep_until, scanned, is_recovery_dest_file,
         localrsr.rsr_key, create_time, marked_corrupt, foreign_dbid,
         plugged_readonly, plugin_scn, plugin_reset_scn, plugin_reset_time,
         l_pdb_key, sparse_backup);
  END IF;
END checkDataFileCopy;
 
PROCEDURE endDataFileCopyResync IS
BEGIN
  IF (this_cf_type = 'CURRENT' OR
      (this_cf_type = 'STANDBY' AND this_db_unique_name is not null)) THEN
     UPDATE node SET high_cdf_recid = last_cdf_recid
     WHERE site_key = this_site_key;
  END IF;
 
  sessionWaterMarks.high_cdf_recid := last_cdf_recid;
  last_cdf_recid := NULL;
 
END endDataFileCopyResync;
 
/*----------------------------*
 * Proxy Datafile resync      *
 *----------------------------*/
 
PROCEDURE deleteDuplicateXCF(recid       IN NUMBER,
                             stamp       IN NUMBER,
                             device_type IN VARCHAR2,
                             handle      IN VARCHAR2) IS
   lhandle      xcf.handle%TYPE;
   ldevice_type xcf.device_type%TYPE;
 
BEGIN
    lhandle := handle;
 
    IF lhandle IS NULL OR ldevice_type IS NULL THEN
       BEGIN
          SELECT handle, device_type INTO lhandle, ldevice_type FROM xcf
          WHERE xcf.dbinc_key IN
            (SELECT dbinc_key FROM dbinc WHERE dbinc.db_key = this_db_key)
            AND xcf_recid = recid
            AND xcf_stamp = stamp;
       EXCEPTION
          WHEN no_data_found THEN
             RETURN;
          WHEN too_many_rows THEN -- unique_key is dbinc_key, recid and stamp
             RETURN;
       END;
    END IF;
 
--
    DELETE xcf
    WHERE xcf.dbinc_key IN
            (SELECT dbinc_key FROM dbinc WHERE dbinc.db_key = this_db_key)
    AND   xcf.device_type = ldevice_type
    AND   xcf.handle = lhandle
    AND   ((tape_backups_shared = TRUE#) OR
           (this_site_key = nvl(xcf.site_key, this_site_key)))
    AND   xcf.handle_hashkey =
              substr(ldevice_type, 1, 10) ||
              substr(lhandle, 1, 10) ||
              substr(lhandle, -10)
    AND   NOT (xcf.xcf_recid = recid AND
               xcf.xcf_stamp = stamp);
 
END deleteDuplicateXCF;
 
PROCEDURE addProxyControlFile(
  dbinc_key       IN NUMBER
 ,xcf_recid       IN NUMBER
 ,xcf_stamp       IN NUMBER
 ,tag             IN VARCHAR2
 ,ckp_scn         IN NUMBER
 ,ckp_time        IN DATE
 ,create_time     IN DATE
 ,min_offr_recid  IN NUMBER
 ,block_size      IN NUMBER
 ,device_type     IN VARCHAR2
 ,handle          IN VARCHAR2
 ,comments        IN VARCHAR2
 ,media           IN VARCHAR2
 ,media_pool      IN NUMBER
 ,start_time      IN VARCHAR2
 ,completion_time IN DATE
 ,status          IN VARCHAR2
 ,controlfile_type
                  IN VARCHAR2
 ,keep_options    IN NUMBER
 ,keep_until      IN DATE
 ,rsr_key         IN NUMBER
 ,blocks          IN NUMBER
 ,pdb_key         IN NUMBER
) IS
 
local    xcf%rowtype;
 
BEGIN
  BEGIN
    IF (status <> 'D') THEN
      INSERT INTO xcf(xcf_key, dbinc_key, xcf_recid, xcf_stamp, tag,
        ckp_scn, ckp_time, create_time, min_offr_recid, block_size,
        device_type, handle, handle_hashkey, comments, media, media_pool,
        start_time, completion_time, status, controlfile_type, keep_options,
        keep_until, rsr_key, site_key, pdb_key)
      VALUES (rman_seq.nextval, dbinc_key, xcf_recid, xcf_stamp, tag,
        ckp_scn, ckp_time, create_time, min_offr_recid, block_size,
        device_type, handle,
        substr(device_type,1,10)||substr(handle,1,10)||substr(handle,-10),
        comments, media, media_pool, start_time, completion_time, status,
        controlfile_type, keep_options, keep_until, rsr_key, this_site_key,
        pdb_key);
 
      deleteDuplicateXCF(xcf_recid, xcf_stamp, device_type, handle);
    END IF;
 
  EXCEPTION
    WHEN dup_val_on_index THEN
      deb('addProxyControlFile - Inside dup_val_on_index exception');
--
      SELECT * INTO local
      FROM xcf
      WHERE xcf.dbinc_key = addProxyControlFile.dbinc_key
      AND   xcf.xcf_recid = addProxyControlFile.xcf_recid
      AND   xcf.xcf_stamp = addProxyControlFile.xcf_stamp;
 
--
      IF client_site_aware AND this_site_key <> local.site_key THEN
          raise_application_error(-20081, 'change stamp for the record');
      END IF;
 
--
      IF (ckp_scn <> local.ckp_scn) THEN
        raise_application_error(-20095, 'Invalid ckp_scn');
      END IF;
 
--
      IF local.site_key IS NULL THEN
         UPDATE xcf SET site_key = this_site_key
         WHERE xcf.dbinc_key = addProxyControlFile.dbinc_key
           AND xcf.xcf_recid = addProxyControlFile.xcf_recid
           AND xcf.xcf_stamp = addProxyControlFile.xcf_stamp;
      END IF;
  END;
 
END addProxyControlFile;
 
PROCEDURE deleteDuplicateXDF(recid       IN NUMBER,
                             stamp       IN NUMBER,
                             device_type IN VARCHAR2,
                             handle      IN VARCHAR2) IS
   lhandle      xdf.handle%TYPE;
   ldevice_type xdf.device_type%TYPE;
 
BEGIN
    lhandle := handle;
 
    IF lhandle IS NULL OR ldevice_type IS NULL THEN
       BEGIN
          SELECT handle, device_type INTO lhandle, ldevice_type FROM xdf
           WHERE xdf.dbinc_key IN
                 (SELECT dbinc_key FROM dbinc WHERE dbinc.db_key = this_db_key)
            AND xdf_recid = recid
            AND xdf_stamp = stamp;
       EXCEPTION
          WHEN no_data_found THEN
             RETURN;
          WHEN too_many_rows THEN -- unique_key is dbinc_key, recid and stamp
             RETURN;
       END;
    END IF;
 
--
    DELETE xdf
    WHERE xdf.dbinc_key IN
            (SELECT dbinc_key FROM dbinc WHERE dbinc.db_key = this_db_key)
    AND   xdf.device_type = ldevice_type
    AND   xdf.handle = lhandle
    AND   ((tape_backups_shared = TRUE#) OR
           (this_site_key = nvl(xdf.site_key, this_site_key)))
    AND   xdf.handle_hashkey =
              substr(ldevice_type, 1, 10) ||
              substr(lhandle, 1, 10) ||
              substr(lhandle, -10)
    AND   NOT (xdf.xdf_recid = recid AND
               xdf.xdf_stamp = stamp);
 
END deleteDuplicateXDF;
 
PROCEDURE addProxyDataFile(
  dbinc_key       IN NUMBER
 ,xdf_recid       IN NUMBER
 ,xdf_stamp       IN NUMBER
 ,tag             IN VARCHAR2
 ,file#           IN NUMBER
 ,create_scn      IN NUMBER
 ,incr_level      IN NUMBER
 ,ckp_scn         IN NUMBER
 ,ckp_time        IN DATE
 ,onl_fuzzy       IN VARCHAR2
 ,bck_fuzzy       IN VARCHAR2
 ,abs_fuzzy_scn   IN NUMBER
 ,rcv_fuzzy_scn   IN NUMBER
 ,rcv_fuzzy_time  IN DATE
 ,blocks          IN NUMBER
 ,block_size      IN NUMBER
 ,device_type     IN VARCHAR2
 ,handle          IN VARCHAR2
 ,comments        IN VARCHAR2
 ,media           IN VARCHAR2
 ,media_pool      IN NUMBER
 ,start_time      IN VARCHAR2
 ,completion_time IN DATE
 ,status          IN VARCHAR2
 ,keep_options    IN NUMBER   DEFAULT 0
 ,keep_until      IN DATE     DEFAULT NULL
 ,rsr_key         IN NUMBER
 ,create_time     IN DATE
 ,foreign_dbid      IN NUMBER
 ,plugged_readonly  IN VARCHAR2
 ,plugin_scn        IN NUMBER
 ,plugin_reset_scn  IN NUMBER
 ,plugin_reset_time IN DATE
 ,pdb_key           IN NUMBER
) IS
 
local    xdf%rowtype;
 
BEGIN
 
  BEGIN
    IF (status <> 'D') THEN
      INSERT INTO xdf(xdf_key, dbinc_key, xdf_recid, xdf_stamp,
         file#, create_scn, tag, incr_level,
         ckp_scn, ckp_time, onl_fuzzy, bck_fuzzy, abs_fuzzy_scn,
         rcv_fuzzy_scn, rcv_fuzzy_time, blocks, block_size,
         device_type, handle, handle_hashkey, comments, media, media_pool,
         start_time, completion_time, status,
         keep_options, keep_until, rsr_key, site_key, foreign_dbid,
         plugged_readonly, plugin_scn, plugin_reset_scn, plugin_reset_time,
         pdb_key)
      VALUES
        (rman_seq.nextval, dbinc_key, xdf_recid, xdf_stamp,
         file#, create_scn, tag,
         incr_level, ckp_scn, ckp_time, decode(onl_fuzzy,'YES','Y','NO','N'),
         decode(bck_fuzzy,'YES','Y','NO','N'), abs_fuzzy_scn,
         rcv_fuzzy_scn, rcv_fuzzy_time, blocks, block_size,
         device_type, handle,
         substr(device_type,1,10)||substr(handle,1,10)||substr(handle,-10),
         comments, media, media_pool, start_time, completion_time, status,
         keep_options, keep_until, rsr_key, this_site_key, foreign_dbid,
         plugged_readonly, plugin_scn, plugin_reset_scn, plugin_reset_time,
         pdb_key);
 
       deleteDuplicateXDF(xdf_recid, xdf_stamp, device_type, handle);
    END IF;
 
 
  EXCEPTION
    WHEN dup_val_on_index THEN
      deb('addProxyDatafile - Inside dup_val_on_index exception');
      SELECT * INTO local
      FROM xdf
      WHERE xdf.dbinc_key = addProxyDataFile.dbinc_key
      AND   xdf.xdf_recid = addProxyDataFile.xdf_recid
      AND   xdf.xdf_stamp = addProxyDataFile.xdf_stamp;
 
--
      IF client_site_aware AND this_site_key <> local.site_key THEN
          raise_application_error(-20081, 'change stamp for the record');
      END IF;
 
--
      IF (file# <> local.file#) THEN
        raise_application_error(-20096, 'Invalid file');
      END IF;
      IF (create_scn <> local.create_scn AND
          plugin_scn <> local.plugin_scn) THEN
        raise_application_error(-20097, 'Invalid create scn');
      END IF;
 
--
      IF local.site_key IS NULL THEN
         UPDATE xdf SET site_key = this_site_key
         WHERE xdf.dbinc_key = addProxyDataFile.dbinc_key
           AND xdf.xdf_recid = addProxyDataFile.xdf_recid
           AND xdf.xdf_stamp = addProxyDataFile.xdf_stamp;
      END IF;
  END;
 
END addProxyDataFile;
 
PROCEDURE deleteDuplicateXAL(recid       IN NUMBER,
                             stamp       IN NUMBER,
                             device_type IN VARCHAR2,
                             handle      IN VARCHAR2) IS
   lhandle      xal.handle%TYPE;
   ldevice_type xal.device_type%TYPE;
 
BEGIN
    lhandle := handle;
 
    IF lhandle IS NULL OR ldevice_type IS NULL THEN
       BEGIN
          SELECT handle, device_type INTO lhandle, ldevice_type FROM xal
          WHERE xal.dbinc_key IN
            (SELECT dbinc_key FROM dbinc WHERE dbinc.db_key = this_db_key)
            AND xal_recid = recid
            AND xal_stamp = stamp;
       EXCEPTION
          WHEN no_data_found THEN
             RETURN;
          WHEN too_many_rows THEN -- unique_key is dbinc_key, recid and stamp
             RETURN;
       END;
    END IF;
 
--
    DELETE xal
    WHERE xal.dbinc_key IN
            (SELECT dbinc_key FROM dbinc WHERE dbinc.db_key = this_db_key)
    AND   xal.device_type = ldevice_type
    AND   xal.handle = lhandle
    AND   ((tape_backups_shared = TRUE#) OR
           (this_site_key = nvl(xal.site_key, this_site_key)))
    AND   xal.handle_hashkey =
              substr(ldevice_type, 1, 10) ||
              substr(lhandle, 1, 10) ||
              substr(lhandle, -10)
    AND   NOT (xal.xal_recid = recid AND
               xal.xal_stamp = stamp);
 
END deleteDuplicateXAL;
 
PROCEDURE addProxyArchivedLog(
  dbinc_key           IN NUMBER
 ,xal_recid           IN NUMBER
 ,xal_stamp           IN NUMBER
 ,tag                 IN VARCHAR2
 ,thread#             IN NUMBER
 ,sequence#           IN NUMBER
 ,resetlogs_change#   IN NUMBER
 ,resetlogs_time      IN DATE
 ,first_change#       IN NUMBER
 ,first_time          IN DATE
 ,next_change#        IN NUMBER
 ,next_time           IN DATE
 ,blocks              IN NUMBER
 ,block_size          IN NUMBER
 ,device_type         IN VARCHAR2
 ,handle              IN VARCHAR2
 ,comments            IN VARCHAR2
 ,media               IN VARCHAR2
 ,media_pool          IN NUMBER
 ,start_time          IN VARCHAR2
 ,completion_time     IN DATE
 ,status              IN VARCHAR2
 ,rsr_key             IN NUMBER
 ,terminal            IN VARCHAR2 default 'NO'
 ,keep_until          IN DATE      default NULL
 ,keep_options        IN NUMBER    default 0
) IS
 
local    xal%rowtype;
 
BEGIN
 
  BEGIN
    IF (status <> 'D') THEN
      INSERT INTO xal(xal_key, dbinc_key, xal_recid, xal_stamp, tag,
         thread#, sequence#, low_scn, low_time, next_scn, next_time,
         blocks, block_size, device_type, handle, handle_hashkey,
         comments, media, media_pool, start_time, completion_time, status,
         rsr_key, terminal, keep_until, keep_options, site_key)
      VALUES
        (rman_seq.nextval, dbinc_key, xal_recid, xal_stamp, tag,
         thread#, sequence#, first_change#, first_time, next_change#,
         next_time, blocks, block_size, device_type, handle,
         substr(device_type,1,10)||substr(handle,1,10)||substr(handle,-10),
         comments, media, media_pool, start_time, completion_time, status,
         rsr_key, terminal, keep_until, keep_options, this_site_key);
 
      deleteDuplicateXAL(xal_recid, xal_stamp, device_type, handle);
    END IF;
 
  EXCEPTION
    WHEN dup_val_on_index THEN
      deb('addProxyArchivedLog - Inside dup_val_on_index exception');
      SELECT * INTO local
      FROM xal
      WHERE xal.dbinc_key = addProxyArchivedLog.dbinc_key
      AND   xal.xal_recid = addProxyArchivedLog.xal_recid
      AND   xal.xal_stamp = addProxyArchivedLog.xal_stamp;
 
--
      IF client_site_aware AND this_site_key <> local.site_key THEN
          raise_application_error(-20081, 'change stamp for the record');
      END IF;
 
--
      IF (first_change# <> local.low_scn) THEN
        raise_application_error(-20098, 'Invalid low scn');
      END IF;
 
--
      IF local.site_key IS NULL THEN
         UPDATE xal SET site_key = this_site_key
         WHERE xal.dbinc_key = addProxyArchivedLog.dbinc_key
           AND xal.xal_recid = addProxyArchivedLog.xal_recid
           AND xal.xal_stamp = addProxyArchivedLog.xal_stamp;
      END IF;
  END;
 
  IF (keep_options > 0) THEN
    updateRestorePoint(first_change#, next_change#);
  END IF;
END addProxyArchivedLog;
 
--
--
FUNCTION beginProxyResync RETURN NUMBER IS
BEGIN
  checkResync;
 
  IF (this_cf_type = 'CURRENT' OR
      (this_cf_type = 'STANDBY' AND this_db_unique_name is not null)) THEN
     SELECT high_pc_recid INTO last_xdf_recid
     FROM node
     WHERE site_key = this_site_key;
  ELSE
     last_xdf_recid := sessionWaterMarks.high_pc_recid;
  END IF;
 
  last_xal_recid := last_xdf_recid;
 
  RETURN last_xdf_recid;
END beginProxyResync;
 
PROCEDURE checkProxyDataFile(
  xdf_recid       IN NUMBER
 ,xdf_stamp       IN NUMBER
 ,tag             IN VARCHAR2
 ,file#           IN NUMBER
 ,create_scn      IN NUMBER
 ,create_time     IN DATE
 ,reset_scn       IN NUMBER
 ,reset_time      IN DATE
 ,incr_level      IN NUMBER
 ,ckp_scn         IN NUMBER
 ,ckp_time        IN DATE
 ,onl_fuzzy       IN VARCHAR2
 ,bck_fuzzy       IN VARCHAR2
 ,abs_fuzzy_scn   IN NUMBER
 ,rcv_fuzzy_scn   IN NUMBER
 ,rcv_fuzzy_time  IN DATE
 ,blocks          IN NUMBER
 ,block_size      IN NUMBER
 ,min_offr_recid  IN NUMBER
 ,device_type     IN VARCHAR2
 ,handle          IN VARCHAR2
 ,comments        IN VARCHAR2
 ,media           IN VARCHAR2
 ,media_pool      IN NUMBER
 ,start_time      IN DATE
 ,completion_time IN DATE
 ,status          IN VARCHAR2
 ,controlfile_type
                  IN VARCHAR2         DEFAULT NULL
 ,keep_options    IN NUMBER           DEFAULT 0
 ,keep_until      IN DATE             DEFAULT NULL
 ,rsr_recid       IN NUMBER           DEFAULT NULL
 ,rsr_stamp       IN NUMBER           DEFAULT NULL
 ,foreign_dbid      IN NUMBER         DEFAULT 0
 ,plugged_readonly  IN VARCHAR2       DEFAULT 'NO'
 ,plugin_scn        IN NUMBER         DEFAULT 0
 ,plugin_reset_scn  IN NUMBER         DEFAULT 0
 ,plugin_reset_time IN DATE           DEFAULT NULL
 ,guid              IN RAW            DEFAULT NULL
 ,dropped_pdb       IN BINARY_INTEGER DEFAULT 0
) IS
 
dbinc_key NUMBER;
localrsr  rsr%rowtype;
l_pdb_key NUMBER;
 
BEGIN
  IF (last_xdf_recid IS NULL) THEN
    raise_application_error(-20037, 'Invalid last recid');
  END IF;
 
  IF (xdf_recid < last_xdf_recid) THEN
    raise_application_error(-20036, 'Invalid record order');
  END IF;
 
--
--
  last_xdf_recid := xdf_recid;
 
  IF (xdf_stamp > 0 and xdf_stamp < kccdivts) THEN
     deb('checkProxyDatafile - ignoring record kccdivts='||kccdivts);
     RETURN;                    -- obsolete record from a backup controlfile
  END IF;
 
--
--
  dbinc_key := checkIncarnation(reset_scn, reset_time);
 
  l_pdb_key := guidToPdbKey(guid, dropped_pdb);
 
--
  BEGIN
      SELECT rsr_key
        INTO localrsr.rsr_key
        FROM rsr
       WHERE rsr.dbinc_key = this_dbinc_key
         AND (rsr.site_key = this_site_key OR
              rsr.site_key is null AND this_site_key is null)
         AND rsr.rsr_stamp = checkProxyDataFile.rsr_stamp
         AND rsr.rsr_recid = checkProxyDataFile.rsr_recid;
  EXCEPTION
  WHEN no_data_found THEN
--
      NULL;
  END;
 
  IF (file# = 0) THEN
    addProxyControlFile(dbinc_key, xdf_recid, xdf_stamp, tag,
         ckp_scn, ckp_time, create_time, min_offr_recid, block_size,
         device_type, handle, comments, media, media_pool, start_time,
         completion_time, status, controlfile_type, keep_options, keep_until,
         localrsr.rsr_key, blocks, l_pdb_key);
  ELSE
    addProxyDataFile(dbinc_key, xdf_recid, xdf_stamp, tag, file#, create_scn,
         incr_level, ckp_scn, ckp_time,
         onl_fuzzy, bck_fuzzy, abs_fuzzy_scn, rcv_fuzzy_scn, rcv_fuzzy_time,
         blocks, block_size, device_type, handle, comments, media, media_pool,
         start_time, completion_time, status, keep_options, keep_until,
         localrsr.rsr_key, create_time, foreign_dbid, plugged_readonly,
         plugin_scn, plugin_reset_scn, plugin_reset_time, l_pdb_key);
  END IF;
 
END checkProxyDataFile;
 
PROCEDURE checkProxyArchivedLog(
  xal_recid          IN NUMBER
 ,xal_stamp          IN NUMBER
 ,tag                IN VARCHAR2
 ,thread#            IN NUMBER
 ,sequence#          IN NUMBER
 ,resetlogs_change#  IN NUMBER
 ,resetlogs_time     IN DATE
 ,first_change#      IN NUMBER
 ,first_time         IN DATE
 ,next_change#       IN NUMBER
 ,next_time          IN DATE
 ,blocks             IN NUMBER
 ,block_size         IN NUMBER
 ,device_type        IN VARCHAR2
 ,handle             IN VARCHAR2
 ,comments           IN VARCHAR2
 ,media              IN VARCHAR2
 ,media_pool         IN NUMBER
 ,start_time         IN DATE
 ,completion_time    IN DATE
 ,status             IN VARCHAR2
 ,rsr_recid          IN NUMBER
 ,rsr_stamp          IN NUMBER
 ,terminal           IN VARCHAR2  default 'NO'
 ,keep_until         IN DATE      default NULL
 ,keep_options       IN NUMBER    default 0
) IS
dbinc_key NUMBER;
localrsr  rsr%rowtype;
BEGIN
  IF (last_xal_recid IS NULL) THEN
    raise_application_error(-20037, 'Invalid last recid');
  END IF;
 
  IF (xal_recid < last_xal_recid) THEN
    raise_application_error(-20036, 'Invalid record order');
  END IF;
 
--
--
  last_xal_recid := xal_recid;
 
  IF (xal_stamp > 0 and xal_stamp < kccdivts) THEN
     deb('checkProxyArchivedLog - ignoring record kccdivts='||kccdivts);
     RETURN;                    -- obsolete record from a backup controlfile
  END IF;
 
--
--
  dbinc_key := checkIncarnation(resetlogs_change#, resetlogs_time);
 
--
  BEGIN
      SELECT rsr_key
        INTO localrsr.rsr_key
        FROM rsr
       WHERE rsr.dbinc_key = this_dbinc_key
         AND (rsr.site_key = this_site_key OR
              rsr.site_key is null AND this_site_key is null)
         AND rsr.rsr_stamp = checkProxyArchivedLog.rsr_stamp
         AND rsr.rsr_recid = checkProxyArchivedLog.rsr_recid;
  EXCEPTION
  WHEN no_data_found THEN
--
      NULL;
  END;
 
  addProxyArchivedLog(dbinc_key, xal_recid, xal_stamp, tag, thread#, sequence#,
         resetlogs_change#, resetlogs_time, first_change#, first_time,
         next_change#, next_time, blocks, block_size, device_type, handle,
         comments, media, media_pool, start_time, completion_time, status,
         localrsr.rsr_key, terminal, keep_until, keep_options);
 
END checkProxyArchivedLog;
 
PROCEDURE endProxyResync IS
  last_pc_recid number :=
                   greatest(nvl(last_xdf_recid,0), nvl(last_xal_recid,0));
BEGIN
  IF (this_cf_type = 'CURRENT' OR
      (this_cf_type = 'STANDBY' AND this_db_unique_name is not null)) THEN
     UPDATE node SET high_pc_recid = last_pc_recid
     WHERE site_key = this_site_key;
  END IF;
 
  sessionWaterMarks.high_pc_recid := last_pc_recid;
  last_xdf_recid := NULL;
  last_xal_recid := NULL;
 
END endProxyResync;
 
/*----------------------------*
 * Corrupt Block resync       *
 *----------------------------*/
 
FUNCTION beginBackupCorruptionResync RETURN NUMBER IS
BEGIN
  checkResync;
 
  IF (this_cf_type = 'CURRENT' OR
      (this_cf_type = 'STANDBY' AND this_db_unique_name is not null)) THEN
     SELECT high_bcb_recid INTO last_bcb_recid
     FROM node
     WHERE site_key = this_site_key;
  ELSE
     last_bcb_recid := sessionWaterMarks.high_bcb_recid;
  END IF;
 
  RETURN last_bcb_recid;
END beginBackupCorruptionResync;
 
PROCEDURE checkBackupCorruption(
  bcb_recid       IN NUMBER
 ,bcb_stamp       IN NUMBER
 ,set_stamp       IN NUMBER
 ,set_count       IN NUMBER
 ,piece#          IN NUMBER
 ,file#           IN NUMBER
 ,block#          IN NUMBER
 ,blocks          IN NUMBER
 ,corrupt_scn     IN NUMBER
 ,marked_corrupt  IN VARCHAR2
 ,corruption_type IN VARCHAR2
) IS
 
local   bcb%rowtype;
 
BEGIN
  IF (last_bcb_recid IS NULL) THEN
    raise_application_error(-20037, 'Invalid last recid');
  END IF;
 
  IF (bcb_recid < last_bcb_recid) THEN
    raise_application_error(-20036, 'Invalid record order');
  END IF;
 
  IF (bcb_recid > last_bcb_recid + 1) THEN
--
--
    NULL;
  END IF;
  last_bcb_recid := bcb_recid;
 
  IF (bcb_stamp > 0 and bcb_stamp < kccdivts) THEN
     deb('checkBackupCorruption - ignoring record kccdivts='||kccdivts);
     RETURN;                    -- obsolete record from a backup controlfile
  END IF;
 
--
  BEGIN
    SELECT bdf_key INTO local.bdf_key
    FROM  bdf, bs
    WHERE bdf.bs_key = bs.bs_key
    AND   bs.db_key = this_db_key
    AND   bs.set_stamp = checkBackupCorruption.set_stamp
    AND   bs.set_count = checkBackupCorruption.set_count
    AND   bdf.file# =    checkBackupCorruption.file#;
  EXCEPTION
    WHEN no_data_found THEN
--
      RETURN;
  END;
 
  BEGIN
    INSERT INTO bcb
      (bdf_key, bcb_recid, bcb_stamp, piece#, block#, blocks,
       corrupt_scn, marked_corrupt, corruption_type)
    VALUES
      (local.bdf_key, bcb_recid, bcb_stamp, piece#, block#, blocks,
       corrupt_scn, decode(marked_corrupt,'YES','Y','NO','N'),
       corruption_type);
  EXCEPTION
    WHEN dup_val_on_index THEN
--
      RETURN;
  END;
 
END checkBackupCorruption;
 
PROCEDURE endBackupCorruptionResync IS
BEGIN
  IF (this_cf_type = 'CURRENT' OR
      (this_cf_type = 'STANDBY' AND this_db_unique_name is not null)) THEN
     UPDATE node SET high_bcb_recid = last_bcb_recid
     WHERE site_key = this_site_key;
  END IF;
 
  sessionWaterMarks.high_bcb_recid := last_bcb_recid;
  last_bcb_recid := NULL;
 
END endBackupCorruptionResync;
 
FUNCTION beginCopyCorruptionResync RETURN NUMBER IS
BEGIN
  checkResync;
 
  IF (this_cf_type = 'CURRENT' OR
      (this_cf_type = 'STANDBY' AND this_db_unique_name is not null)) THEN
     SELECT high_ccb_recid INTO last_ccb_recid
     FROM node
     WHERE site_key = this_site_key;
  ELSE
     last_ccb_recid :=  sessionWaterMarks.high_ccb_recid;
  END IF;
 
  RETURN last_ccb_recid;
END beginCopyCorruptionResync;
 
PROCEDURE checkCopyCorruption(
  ccb_recid       IN NUMBER
 ,ccb_stamp       IN NUMBER
 ,cdf_recid       IN NUMBER
 ,cdf_stamp       IN NUMBER
 ,file#           IN NUMBER
 ,block#          IN NUMBER
 ,blocks          IN NUMBER
 ,corrupt_scn     IN NUMBER
 ,marked_corrupt  IN VARCHAR2
 ,corruption_type IN VARCHAR2
) IS
 
local   ccb%rowtype;
 
BEGIN
   IF (last_ccb_recid IS NULL) THEN
    raise_application_error(-20037, 'Invalid last recid');
  END IF;
 
  IF (ccb_recid < last_ccb_recid) THEN
    raise_application_error(-20036, 'Invalid record order');
  END IF;
 
  IF (ccb_recid > last_ccb_recid + 1) THEN
--
--
    NULL;
  END IF;
  last_ccb_recid := ccb_recid;
 
  IF (ccb_stamp > 0 and ccb_stamp < kccdivts) THEN
     deb('checkCopyCorruption - ignoring record kccdivts='||kccdivts);
     RETURN;                    -- obsolete record from a backup controlfile
  END IF;
 
--
  BEGIN
    SELECT cdf_key INTO local.cdf_key
    FROM  cdf
    WHERE cdf.dbinc_key = this_dbinc_key
    AND   cdf.cdf_recid = checkCopyCorruption.cdf_recid
    AND   cdf.cdf_stamp = checkCopyCorruption.cdf_stamp
    AND   cdf.file# = checkCopyCorruption.file#;
  EXCEPTION
    WHEN no_data_found THEN
--
      RETURN;
  END;
 
  BEGIN
    INSERT INTO ccb
      (cdf_key, ccb_recid, ccb_stamp, block#, blocks,
       corrupt_scn, marked_corrupt, corruption_type)
    VALUES
      (local.cdf_key, ccb_recid, ccb_stamp, block#, blocks,
       corrupt_scn, decode(marked_corrupt,'YES','Y','NO','N'),
       corruption_type);
  EXCEPTION
    WHEN dup_val_on_index THEN
--
      RETURN;
  END;
END checkCopyCorruption;
 
PROCEDURE endCopyCorruptionResync IS
BEGIN
  IF (this_cf_type = 'CURRENT' OR
      (this_cf_type = 'STANDBY' AND this_db_unique_name is not null)) THEN
     UPDATE node SET high_ccb_recid = last_ccb_recid
     WHERE site_key = this_site_key;
  END IF;
 
  sessionWaterMarks.high_ccb_recid := last_ccb_recid;
  last_ccb_recid := NULL;
 
END endCopyCorruptionResync;
 
FUNCTION beginBlockCorruptionResync(
  low_bcr_recid IN number)
RETURN NUMBER IS
   old_bcr_recid number;
BEGIN
  checkResync;
 
  SELECT high_bcr_recid, low_bcr_recid
    INTO last_bcr_recid, old_bcr_recid
    FROM node
   WHERE site_key = this_site_key;
 
--
--
--
--
--
--
--
--
  IF (old_bcr_recid != low_bcr_recid) THEN
     DELETE bcr
      WHERE site_key = this_site_key
        AND bcr_recid < low_bcr_recid;
     UPDATE node SET low_bcr_recid = low_bcr_recid
     WHERE site_key = this_site_key;
  END IF;
 
  RETURN last_bcr_recid;
END beginBlockCorruptionResync;
 
PROCEDURE checkBlockCorruption(
  bcr_recid       IN NUMBER
 ,bcr_stamp       IN NUMBER
 ,file#           IN NUMBER
 ,create_scn      IN NUMBER
 ,create_time     IN DATE
 ,block#          IN NUMBER
 ,blocks          IN NUMBER
 ,corrupt_scn     IN NUMBER
 ,corruption_type IN VARCHAR2
) IS
 
local   df%rowtype;
 
BEGIN
  IF (last_bcr_recid IS NULL) THEN
    raise_application_error(-20037, 'Invalid last recid');
  END IF;
 
  IF (bcr_recid < last_bcr_recid) THEN
    raise_application_error(-20036, 'Invalid record order');
  END IF;
 
  IF (bcr_recid > last_bcr_recid + 1) THEN
--
--
    NULL;
  END IF;
 
  last_bcr_recid := bcr_recid;
 
--
  BEGIN
    SELECT distinct df.df_key INTO local.df_key
    FROM  df, site_dfatt
    WHERE df.df_key = site_dfatt.df_key
    AND   site_dfatt.site_key = this_site_key
    AND   df.file# = checkBlockCorruption.file#
    AND   df.create_scn = checkBlockCorruption.create_scn
    AND   df.create_time = checkBlockCorruption.create_time;
  EXCEPTION
    WHEN no_data_found THEN
--
      deb('checkBlockCorruption - no df_key found');
      RETURN;
  END;
 
  deb('checkBlockCorruption - df_key=' || local.df_key);
 
  BEGIN
    INSERT INTO bcr 
      (bcr_recid, bcr_stamp, df_key, site_key,
       block#, blocks, corrupt_scn, corruption_type)
    VALUES
      (bcr_recid, bcr_stamp, local.df_key, this_site_key,
       block#, blocks, corrupt_scn, corruption_type);
  EXCEPTION
    WHEN dup_val_on_index THEN
--
      RETURN;
  END;
END checkBlockCorruption;
 
PROCEDURE endBlockCorruptionResync IS
BEGIN
  IF (this_cf_type = 'CURRENT' OR
      (this_cf_type = 'STANDBY' AND this_db_unique_name is not null)) THEN
     UPDATE node SET high_bcr_recid = last_bcr_recid
      WHERE site_key = this_site_key;
  END IF;
 
  sessionWaterMarks.high_bcr_recid := last_bcr_recid;
  last_bcr_recid := NULL;
END endBlockCorruptionResync;
 
/*----------------------------*
 * Deleted Object resync      *
 *----------------------------*/
 
FUNCTION beginDeletedObjectResync RETURN NUMBER IS
BEGIN
  checkResync;
 
  IF (this_cf_type = 'CURRENT' OR
      (this_cf_type = 'STANDBY' AND this_db_unique_name is not null)) THEN
     SELECT high_do_recid INTO last_do_recid
     FROM node
     WHERE site_key = this_site_key;
  ELSE
     last_do_recid := sessionWaterMarks.high_do_recid;
  END IF;
 
  deb('beginDeletedObjectResync - last_do_recid='||last_do_recid);
  RETURN last_do_recid;
END beginDeletedObjectResync;
 
PROCEDURE checkDeletedObject(
  do_recid          IN NUMBER
 ,do_stamp          IN NUMBER
 ,object_type       IN VARCHAR2
 ,object_recid      IN NUMBER
 ,object_stamp      IN NUMBER
 ,object_data       IN NUMBER   DEFAULT NULL
 ,object_fname      IN VARCHAR2 DEFAULT NULL
 ,object_create_scn IN NUMBER   DEFAULT NULL
 ,set_stamp         IN NUMBER   DEFAULT NULL
 ,set_count         IN NUMBER   DEFAULT NULL
 ,handle            IN VARCHAR2 DEFAULT NULL
 ,device_type       IN VARCHAR2 DEFAULT NULL)
IS
  local            bp%rowtype;
  new_status       VARCHAR2(1);
  rc               boolean;
  keep_options     number := NULL;
  keep_until       date   := NULL;
  new_recid        number := NULL;
BEGIN
  IF (last_do_recid IS NULL) THEN
    raise_application_error(-20037, 'Invalid last recid');
  END IF;
 
  IF (do_recid < last_do_recid) THEN
    deb('checkDeletedObject - last_do_recid=' || last_do_recid);
    raise_application_error(-20036, 'Invalid record order');
  END IF;
 
--
  IF (do_recid > last_do_recid + 1) THEN
--
    NULL;
  END IF;
  last_do_recid := do_recid;
 
  IF (do_stamp > 0 AND do_stamp < kccdivts) THEN
     deb('checkDeletedObject - ignoring record kccdivts='||kccdivts);
     RETURN;                    -- obsolete record from a backup controlfile
  END IF;
 
--
--
--
 
  IF (object_type like 'BACKUP SET%') THEN
    IF (object_type = 'BACKUP SET KEEP UNTIL') THEN 
      IF (object_data > 0) THEN
         keep_until := stamp2date(object_data);
      END IF;
    ELSIF (object_type = 'BACKUP SET KEEP OPTIONS') THEN
       keep_options := object_data;
    ELSE
        raise_application_error(-20999,
           'Internal error in checkDeletedObject(): bad object_type '||
           object_type);
    END IF;
 
    changeBackupSet(object_recid, object_stamp,
                    keep_options, keep_until);
  END IF;
 
  IF (object_type like 'BACKUP PIECE%') THEN
    IF (object_type = 'BACKUP PIECE') THEN
       new_status := 'D';
    ELSIF (object_type = 'BACKUP PIECE AVAILABLE') THEN
       new_status := 'A';
    ELSIF (object_type = 'BACKUP PIECE EXPIRED') THEN
       new_status := 'X';
    ELSIF (object_type = 'BACKUP PIECE UNAVAILABLE') THEN
       new_status := 'U';
    ELSE
       raise_application_error(-20999,
           'Internal error in checkDeletedObject(): bad object_type '||
           object_type);
    END IF;
    changeBackupPiece(object_recid, object_stamp, new_status,
                      set_stamp, set_count, NULL /* osite_key */,
                      NULL /*nsite_key */, handle, device_type);
  END IF;
 
  IF (object_type like 'DATAFILE COPY%') THEN
    IF (object_type = 'DATAFILE COPY') THEN
       new_status := 'D';
    ELSIF (object_type = 'DATAFILE COPY AVAILABLE') THEN
       new_status := 'A';
    ELSIF (object_type = 'DATAFILE COPY EXPIRED') THEN
       new_status := 'X';
    ELSIF (object_type = 'DATAFILE COPY UNAVAILABLE') THEN
       new_status := 'U';
    ELSIF (object_type = 'DATAFILE COPY KEEP UNTIL') THEN
       new_status := NULL;
       keep_until := stamp2date(object_data);
    ELSIF (object_type = 'DATAFILE COPY KEEP OPTIONS') THEN
       new_status := NULL;
       keep_options := object_data;
    ELSIF (object_type = 'DATAFILE COPY MOVED') THEN
       new_status := NULL;
       new_recid := object_data;
    ELSE
        raise_application_error(-20999,
           'Internal error in checkDeletedObject(): bad object_type '||
           object_type);
    END IF;
    changeDatafileCopy(object_recid, object_stamp, new_status,
                       keep_options, keep_until, new_recid);
  END IF;
 
  IF (object_type like 'ARCHIVED LOG%') THEN
    IF (object_type = 'ARCHIVED LOG') THEN
       new_status := 'D';
    ELSIF (object_type = 'ARCHIVED LOG AVAILABLE') THEN
       new_status := 'A';
    ELSIF (object_type = 'ARCHIVED LOG EXPIRED') THEN
       new_status := 'X';
    ELSIF (object_type = 'ARCHIVED LOG UNAVAILABLE') THEN
       new_status := 'U';
    ELSIF (object_type = 'ARCHIVED LOG MOVED') THEN
       new_status := NULL;
       new_recid := object_data;
    ELSE
       raise_application_error(-20999,
           'Internal error in checkDeletedObject(): bad object_type '||
           object_type);
    END IF;
    changeArchivedLog(object_recid, object_stamp, new_status, new_recid);
  END IF;
 
  IF (object_type like 'PROXY COPY%') THEN
    IF (object_type = 'PROXY COPY') THEN
       new_status := 'D';
    ELSIF (object_type = 'PROXY COPY AVAILABLE') THEN
       new_status := 'A';
    ELSIF (object_type = 'PROXY COPY EXPIRED') THEN
       new_status := 'X';
    ELSIF (object_type = 'PROXY COPY UNAVAILABLE') THEN
       new_status := 'U';
    ELSIF (object_type = 'PROXY COPY KEEP UNTIL') THEN
       new_status := NULL;
       keep_until := stamp2date(object_data);
    ELSIF (object_type = 'PROXY COPY KEEP OPTIONS') THEN
       new_status := NULL;
       keep_options := object_data;
    ELSE
       raise_application_error(-20999,
           'Internal error in checkDeletedObject(): bad object_type '||
           object_type);
    END IF;
    changeProxyCopy(object_recid, object_stamp, new_status,
                    keep_options, keep_until);
  END IF;
 
  IF (object_type = 'DATAFILE RENAME ON RESTORE')
  THEN
    deb('checkDeletedObject - renaming file#='||object_data||' to '||
        object_fname);
 
--
--
--
--
--
    DECLARE
      local_df_key NUMBER;
    BEGIN
      SELECT DISTINCT df_key INTO local_df_key FROM df
      WHERE dbinc_key = this_dbinc_key
        AND   df.file# = object_data
        AND   df.create_scn = object_create_scn;
 
      UPDATE site_dfatt SET
        fname = object_fname
      WHERE 
        site_key = this_site_key AND
        df_key   = local_df_key;
 
      IF (NOT SQL%FOUND) THEN
        deb('checkDeletedObject - doing an insert');
        INSERT INTO site_dfatt (fname, df_key, site_key)
          VALUES (object_fname, local_df_key, this_site_key);
      END IF;
    EXCEPTION
     WHEN no_data_found THEN
        NULL;
    END;
  END IF;
 
  IF (object_type = 'PLUGGED READONLY RENAME')
  THEN
    deb('In checkDeletedObject, renaming plugged readonly file#='||
        object_data||' to ' ||object_fname);
--
--
--
--
--
--
--
    DECLARE
      CURSOR df_key_plugin_cur(file# IN NUMBER,
                               plugin_scn IN NUMBER) IS
        SELECT df_key FROM df
          WHERE dbinc_key = this_dbinc_key
            AND   df.file# = df_key_plugin_cur.file#
            AND   df.plugin_scn = df_key_plugin_cur.plugin_scn;
    BEGIN
      FOR plugin_df_key IN df_key_plugin_cur(object_data, object_create_scn)
      LOOP
        UPDATE site_dfatt
           SET fname = object_fname
         WHERE site_key = this_site_key AND
           df_key = plugin_df_key.df_key;
 
        IF (NOT SQL%FOUND) THEN
          deb('checkDeletedObject - doing an insert');
          INSERT INTO site_dfatt (fname, df_key, site_key)
            VALUES (object_fname, plugin_df_key.df_key, this_site_key);
        END IF;
      END LOOP;
    END;
  END IF;
 
  IF (object_type = 'TEMPFILE RENAME')
  THEN
    deb('checkDeletedObject - renaming temp file#='||object_data||' to'||
        object_fname);
--
--
--
--
--
    DECLARE
      local_tf_key NUMBER;
    BEGIN
      SELECT tf_key INTO local_tf_key FROM tf
      WHERE dbinc_key = this_dbinc_key
        AND   tf.file# = object_data
        AND   tf.create_scn = object_create_scn;
 
      UPDATE site_tfatt SET
         fname = object_fname
      WHERE 
        site_key = this_site_key AND
        tf_key   = local_tf_key;
 
      IF (NOT SQL%FOUND) THEN
        INSERT INTO site_tfatt (fname, tf_key, site_key)
          VALUES (object_fname, local_tf_key, this_site_key);
      END IF;
    EXCEPTION
     WHEN no_data_found THEN
        NULL;
    END;
  END IF;
 
  IF (object_type = 'DATABASE BLOCK CORRUPTION') THEN
     DELETE bcr
      WHERE site_key  = this_site_key
        AND bcr_recid = object_recid
        AND bcr_stamp = object_stamp;
  END IF;
 
  IF (object_type = 'RESTORE POINT') THEN
    DELETE nrsp
      WHERE site_key  = this_site_key
        AND nrsp_recid = object_recid
        AND nrsp_stamp = object_stamp;
  END IF;
 
  IF (object_type = 'INSTANT RESTORE') THEN
--
--
--
--
    deb('checkDeletedObject - type ='||object_type||
        ' datafile no ='||object_data||' backing file ='||object_fname);
  END IF;
END checkDeletedObject;
 
PROCEDURE endDeletedObjectResync IS
BEGIN
  IF (this_cf_type = 'CURRENT' OR
      (this_cf_type = 'STANDBY' AND this_db_unique_name is not null)) THEN
     deb('endDeletedObjectResync - last_do_recid=' || last_do_recid);
     UPDATE node SET high_do_recid = last_do_recid
     WHERE site_key = this_site_key;
  END IF;
 
  sessionWaterMarks.high_do_recid := last_do_recid;
  last_do_recid := NULL;
 
END endDeletedObjectResync;
 
 
/*----------------------------*
 * RMAN Output resync         *
 *----------------------------*/
 
FUNCTION beginRmanOutputResync(start_timestamp IN NUMBER) RETURN NUMBER IS
  doRoutMining    BOOLEAN;
  last_rout_stamp NUMBER;
BEGIN
  last_rout_stamp := beginRmanOutputResync(start_timestamp, doRoutMining);
  RETURN last_rout_stamp;
END beginRmanOutputResync;
 
FUNCTION beginRmanOutputResync(start_timestamp IN  NUMBER,
                               doRoutMining    OUT BOOLEAN)
RETURN NUMBER IS
BEGIN
--
  getRmanOutputLogging(rman_keep_output);
 
--
  IF (session_keep_output = 0) or (rman_keep_output = 0) THEN
     deb('beginRmanOutputResync - rman output logging is disabled');
     return MAXNUMVAL;
  END IF;
 
  deb('beginRmanOutputResync - input instance start time='||start_timestamp);
 
  checkResync;
 
--
  SELECT inst_startup_stamp, high_rout_stamp into 
     last_inst_startup_stamp, last_rout_stamp from node where
     node.db_key = this_db_key and
     ((this_db_unique_name is null and node.db_unique_name is null) or
      node.db_unique_name = this_db_unique_name);
 
  deb('beginRmanOutputResync - last_inst_startup_stamp='||
      last_inst_startup_stamp||',last_rout_stamp='||last_rout_stamp);
  
--
--
  IF (last_inst_startup_stamp <> start_timestamp) THEN
     last_rout_stamp := sessionWaterMarks.high_rout_stamp;
     last_inst_startup_stamp := start_timestamp;
     doRoutMining := TRUE;
  ELSE
     doRoutMining := FALSE;
  END IF;
 
  RETURN last_rout_stamp;
END beginRmanOutputResync;
 
--
PROCEDURE insertCachedROUT IS
  errors NUMBER;
  dml_errors EXCEPTION;
  PRAGMA EXCEPTION_INIT(dml_errors, -24381);
BEGIN
  IF lrout_curridx = 0 THEN
    RETURN;
  END IF;
  deb('doing bulk update of ' || lrout_curridx || ' rows into ROUT');
  BEGIN
    FORALL i in 1..lrout_curridx SAVE EXCEPTIONS
      INSERT INTO ROUT VALUES lrout_table(i);
  EXCEPTION
    WHEN dml_errors THEN
      errors := SQL%BULK_EXCEPTIONS.COUNT;
      deb('Number of statements that failed: ' || errors);
      FOR i IN 1..errors LOOP
        deb('Error #' || i || ' occurred during '|| 
            'iteration #' || SQL%BULK_EXCEPTIONS(i).ERROR_INDEX); 
        deb('Error message is ' || 
            SQLERRM(-SQL%BULK_EXCEPTIONS(i).ERROR_CODE));
--
        IF -SQL%BULK_EXCEPTIONS(i).ERROR_CODE = -1 THEN
          UPDATE /*+ index(ROUT ROUT_U1) */ ROUT 
            SET rout_text = lrout_table(i).rout_text
            WHERE db_key = this_db_key
              AND rsr_key = lrout_table(i).rsr_key
              AND rout_skey = lrout_table(i).rout_skey
              AND rout_stamp = lrout_table(i).rout_stamp
              AND rout_recid = lrout_table(i).rout_recid
              AND site_key = this_site_key;
        ELSE
          lrout_curridx := 0;
          RAISE;
        END IF;
      END LOOP;
   END;
   lrout_curridx := 0;
END insertCachedROUT;
 
PROCEDURE checkRmanOutput( recid             IN NUMBER
                          ,stamp             IN NUMBER
                          ,session_recid     IN NUMBER
                          ,session_stamp     IN NUMBER
                          ,rman_status_recid IN NUMBER
                          ,rman_status_stamp IN NUMBER
                          ,output       IN VARCHAR2) IS
BEGIN
    deb('checkRmanOutput', RCVCAT_LEVEL_HI);
 
--
    IF (session_keep_output = 0) or (rman_keep_output = 0) THEN
        deb('checkRmanOutput - rman output logging is disabled');
        return;
    END IF;
 
--
    IF (last_rout_stamp < stamp) THEN
       last_rout_stamp := stamp;
    END IF;
 
    IF lrman_status_recid = rman_status_recid AND 
       lrman_status_stamp = rman_status_stamp THEN
       goto rsr_key_known;
    END IF;
 
    deb('checkRmanOutput - Find rsr_ key');
    BEGIN
      select rsr_key into lrsr_key from rsr where 
             rsr.dbinc_key = this_dbinc_key and
             ((rsr.site_key = this_site_key) or
              (rsr.site_key is null AND this_site_key is null)) and
             rsr.rsr_recid = rman_status_recid and
             rsr.rsr_stamp = rman_status_stamp;
    EXCEPTION
    WHEN no_data_found THEN
--
      deb('checkRmanOutput - ignoring following RMAN output row');
      RETURN;
    END;
 
<<rsr_key_known>>
 
    IF lsession_recid = session_recid AND 
       lsession_stamp = session_stamp THEN
       goto rout_skey_known;
    END IF;
 
    deb('checkRmanOutput - Find session key');
    BEGIN
--
--
--
--
--
      select max(rsr_key) into lrout_skey from rsr, dbinc where 
             rsr.dbinc_key  = dbinc.dbinc_key and
             dbinc.db_key   = this_db_key and
             (rsr.site_key = this_site_key or
              rsr.site_key is null AND this_site_key is null) and
             rsr.rsr_srecid = session_recid and
             rsr.rsr_sstamp = session_stamp and
             rsr.rsr_type   = 'SESSION';
    EXCEPTION
    WHEN no_data_found THEN
--
      deb('checkRmanOutput - ignoring following RMAN output row, cause2');
      RETURN;
    WHEN others THEN
      deb('checkRmanOutput - signal error for RMAN output row');
      RAISE;
    END;
 
<<rout_skey_known>>
 
    IF lrout_skey is null THEN
--
      deb('checkRmanOutput: skey not found, ignoring RMAN output row');
      RETURN;
    END IF;
 
--
--
    BEGIN
      lrout_curridx := lrout_curridx + 1;        
      lrout_table(lrout_curridx).db_key        := this_db_key;
      lrout_table(lrout_curridx).rsr_key       := lrsr_key;
      lrout_table(lrout_curridx).rout_skey     := lrout_skey;
      lrout_table(lrout_curridx).rout_recid    := recid;
      lrout_table(lrout_curridx).rout_stamp    := stamp;
      lrout_table(lrout_curridx).site_key      := this_site_key;
      lrout_table(lrout_curridx).rout_text     :=
          substrb(output, 1, krbmror_llength_bytes); -- bug 5906892
--
      IF lrout_curridx = 1000 THEN
        insertCachedROUT;
      END IF;
    END;
 
    lrman_status_recid := rman_status_recid;
    lrman_status_stamp := rman_status_stamp;
    lsession_recid := session_recid;
    lsession_stamp := session_stamp;
 
END checkRmanOutput;
 
PROCEDURE endRmanOutputResync IS
BEGIN
 
--
   IF (session_keep_output = 0) or (rman_keep_output = 0) THEN
      deb('endRmanOutputResync - rman output logging is disabled');
      return;
   END IF;
 
   IF lrout_curridx > 0 THEN
      insertCachedROUT;
   END IF;
 
   UPDATE node SET high_rout_stamp    = last_rout_stamp,
                   inst_startup_stamp = last_inst_startup_stamp
     WHERE node.db_key = this_db_key and
           ((this_db_unique_name is null and node.db_unique_name is null) or
            node.db_unique_name = this_db_unique_name);
  sessionWaterMarks.high_rout_stamp := last_rout_stamp;
  last_rout_stamp := NULL;
  last_inst_startup_stamp := NULL;
  lrsr_key := NULL;
  lrout_skey := NULL;
  lsession_recid := NULL;
  lsession_stamp := NULL;
  lrman_status_recid := NULL;
  lrman_status_stamp := NULL;
 
END endRmanOutputResync;
 
/*----------------------------*
 * RMAN Status resync         *
 *----------------------------*/
 
FUNCTION beginRmanStatusResync RETURN NUMBER IS
BEGIN
  checkResync;
 
  IF (this_cf_type = 'CURRENT' OR
      (this_cf_type = 'STANDBY' AND this_db_unique_name is not null)) THEN
     SELECT high_rsr_recid INTO last_rsr_recid
     FROM node
     WHERE site_key = this_site_key;
  ELSE
     last_rsr_recid := sessionWaterMarks.high_rsr_recid;
  END IF;
 
  RETURN last_rsr_recid;
END beginRmanStatusResync;
 
PROCEDURE checkRmanStatus( recid            IN NUMBER
                          ,stamp            IN NUMBER
                          ,parent_recid     IN NUMBER
                          ,parent_stamp     IN NUMBER
                          ,row_level        IN NUMBER
                          ,row_type         IN VARCHAR2
                          ,command_id       IN VARCHAR2
                          ,operation        IN VARCHAR2
                          ,status           IN VARCHAR2
                          ,mbytes_processed IN NUMBER
                          ,start_time       IN DATE
                          ,end_time         IN DATE
                          ,ibytes           IN NUMBER default null
                          ,obytes           IN NUMBER default null
                          ,optimized        IN VARCHAR2 default null
                          ,otype            IN VARCHAR2 default null
                          ,session_recid    IN NUMBER default null
                          ,session_stamp    IN NUMBER default null
                          ,odevtype         IN VARCHAR2 default null
                          ,osb_allocated    IN VARCHAR2 default 'NO') IS
 
parent   rsr%rowtype;
 
BEGIN
  IF (last_rsr_recid IS NULL) THEN
    raise_application_error(-20037, 'Invalid last recid');
  END IF;
 
  IF (recid < last_rsr_recid) THEN
    raise_application_error(-20036, 'Invalid record order');
  END IF;
 
  IF (stamp < kccdivts) THEN
     RETURN;                    -- obsolete record from a backup controlfile
  END IF;
 
  parent.rsr_pkey := NULL;
  parent.rsr_l0key := NULL;
--
--
--
  IF (checkRmanStatus.row_level > 0)
  THEN
    deb('checkRmanStatus - row_level='||to_char(checkRmanStatus.row_level));
    BEGIN
      SELECT rsr_key, decode(rsr_level, 0, rsr_key, rsr_l0key)
      INTO parent.rsr_key, parent.rsr_l0key
      FROM rsr
      WHERE rsr.dbinc_key = this_dbinc_key
      AND   (rsr.site_key = this_site_key OR
             rsr.site_key is null AND this_site_key is null)
      AND   rsr.rsr_stamp  = checkRmanStatus.parent_stamp
      AND   rsr.rsr_recid  = checkRmanStatus.parent_recid;
    EXCEPTION
    WHEN no_data_found THEN
--
      deb('checkRmanStatus - ignoring this record');
      RETURN;
    END;
  END IF;
 
  BEGIN
 
    deb('checkRmanStatus - inserting into rsr');
    deb('checkRmanStatus - this_dbinc_key:'||to_char(this_dbinc_key));
    deb('checkRmanStatus - recid:         '||to_char(recid));
    deb('checkRmanStatus - stamp:         '||to_char(stamp));
    deb('checkRmanStatus - srecid:        '||to_char(session_recid));
    deb('checkRmanStatus - sstamp:        '||to_char(session_stamp));
    INSERT INTO rsr
      (rsr_key, dbinc_key, rsr_recid, rsr_stamp, rsr_pkey,
       rsr_l0key, rsr_level, rsr_type, rsr_oper, rsr_cmdid,
       rsr_status, rsr_mbytes, rsr_start, rsr_end, rsr_ibytes, 
       rsr_obytes, rsr_optimized, rsr_otype, rsr_srecid, rsr_sstamp, 
       rsr_odevtype, site_key, rsr_osb_allocated)
    VALUES
      (rman_seq.nextval, this_dbinc_key, recid, stamp, parent.rsr_key,
       parent.rsr_l0key, row_level, row_type, operation, command_id,
       status, mbytes_processed, start_time, end_time, ibytes, 
       obytes, optimized, otype, session_recid, session_stamp, odevtype,
       this_site_key, decode(osb_allocated, 'YES', 'Y', 'N'));
 
--
--
    DELETE rsr WHERE
           rsr.dbinc_key = this_dbinc_key 
       AND rsr.rsr_recid = recid
       AND rsr.rsr_stamp = stamp
       AND ((this_site_key is not null AND rsr.site_key is NULL) OR
            (this_site_key is null and rsr.site_key is not null));
  EXCEPTION
     WHEN dup_val_on_index THEN
--
     deb('checkRmanStatus - exception catch');
     deb('checkRmanStatus - this_dbinc_key:'||to_char(this_dbinc_key));
     deb('checkRmanStatus - recid:         '||to_char(recid));
     deb('checkRmanStatus - stamp:         '||to_char(stamp));
     deb('checkRmanStatus - srecid:        '||to_char(session_recid));
     deb('checkRmanStatus - sstamp:        '||to_char(session_stamp));
     UPDATE rsr
        SET rsr_pkey   = parent.rsr_key,
            rsr_l0key  = parent.rsr_l0key,
            rsr_level  = row_level,
            rsr_type   = row_type,
            rsr_oper   = operation,
            rsr_cmdid  = command_id,
            rsr_status = status,
            rsr_mbytes = mbytes_processed,
            rsr_start  = start_time,
            rsr_end    = end_time,
            rsr_ibytes = ibytes,
            rsr_obytes = obytes,
            rsr_optimized = optimized,
            rsr_otype =  otype,
            rsr_odevtype = odevtype,
            rsr_osb_allocated = decode(osb_allocated, 'YES', 'Y', 'N')
      WHERE rsr.rsr_stamp = stamp
      AND   rsr.rsr_recid = recid
      AND   (rsr.site_key = this_site_key OR
             rsr.site_key is null and this_site_key is null)
      AND   rsr.rsr_srecid = session_recid
      AND   rsr.rsr_sstamp = session_stamp
      AND   rsr.dbinc_key = this_dbinc_key;
  END;
END checkRmanStatus;
 
PROCEDURE endRmanStatusResync(recid number) IS
BEGIN
 
  IF (last_rsr_recid IS NULL) THEN
    raise_application_error(-20037, 'Invalid last recid');
  END IF;
 
  IF (recid < last_rsr_recid) THEN
    raise_application_error(-20036, 'Invalid record order');
  END IF;
 
  IF (this_cf_type = 'CURRENT' OR
      (this_cf_type = 'STANDBY' AND this_db_unique_name is not null)) THEN
     UPDATE node SET high_rsr_recid = recid
     WHERE site_key = this_site_key;
  END IF;
 
  sessionWaterMarks.high_rsr_recid := recid;
  last_rsr_recid := NULL;
 
END endRmanStatusResync;
 
PROCEDURE updateRmanStatusRow( recid   IN number
                              ,stamp   IN number
                              ,mbytes  IN number
                              ,status  IN binary_integer ) IS
BEGIN
 
  IF (this_dbinc_key IS NULL) THEN
    return;
  END IF;
 
  UPDATE rsr SET
         rsr_status = decode(status, 1, 'RUNNING',
                                   1+8, 'RUNNING WITH WARNINGS',
                                  1+16, 'RUNNING WITH ERRORS',
                                1+8+16, 'RUNNING WITH ERRORS',
                                     2, 'COMPLETED',
                                   2+8, 'COMPLETED WITH WARNINGS',
                                  2+16, 'COMPLETED WITH ERRORS',
                                2+8+16, 'COMPLETED WITH ERRORS',
                                        'FAILED'),
         rsr_mbytes = mbytes
   WHERE rsr.rsr_stamp = stamp
   AND   rsr.rsr_recid = recid
   AND   (rsr.site_key = this_site_key OR
          rsr.site_key is null AND this_site_key is null)
   AND   rsr.dbinc_key = this_dbinc_key;
 
   commitChanges('updateRmanStatusRow');
 
END updateRmanStatusRow;
 
PROCEDURE rsDeleteBackupPiece(bp_key IN number, purged IN varchar2)
IS
   bs_key number;
   db_key number;
   retention_time timestamp with time zone;
BEGIN
 
--
  SELECT bp.bs_key, bp.db_key INTO bs_key, db_key
    FROM bp, bs
   WHERE bp.bp_key = rsDeleteBackupPiece.bp_key 
     AND bp.bs_key = bs.bs_key FOR UPDATE OF bs.bs_key;
  deb('rsDeleteBackupPiece - locked bs_key' || bs_key);
 
--
  UPDATE bp SET bp.status = 'D',
                bp.purged = rsDeleteBackupPiece.purged
   WHERE bp.bp_key = rsDeleteBackupPiece.bp_key;
 
  IF (purged = 'Y') THEN
     IF this_is_ors THEN
        this_enable_populate_rsr := 
                             getValueFromConfig('_enable_populate_rsr_key');
     END IF;
     updateBackupSetRec(bs_key);
--
--
     IF this_is_ors THEN
        this_enable_populate_rsr := NULL;
        this_upstream_site_key := NULL;
     END IF;
  END IF;
 
--
END rsDeleteBackupPiece;
 
FUNCTION getValueFromConfig(entry IN VARCHAR2) RETURN varchar2 IS
   entryVal config.value%TYPE;
BEGIN
   SELECT UPPER(value)
     INTO entryVal
     FROM config
     WHERE name = entry;
   
   return entryVal;
END getValueFromConfig;
 
/*-------------------*
 * Change Procedures *
 *-------------------*/
 
/*
 * In these change procedures, we don't check that we found the record,
 * because we are processing a DL record - i.e. we already processed the
 * other cf records and hence it might already be flagged deleted.  This
 * applies to any status change because we might make it available and
 * then delete the object, so the object would be marked as deleted when
 * we process the object and the available status change (first DL) would
 * fail to find the object, so would a following DL that marks it deleted.
 */
 
PROCEDURE changeDatafileCopy(
  cdf_recid    IN NUMBER
 ,cdf_stamp    IN NUMBER
 ,status       IN VARCHAR2
 ,keep_options IN NUMBER DEFAULT NULL  -- null means do not update
 ,keep_until   IN DATE   DEFAULT NULL
 ,osite_key    IN number DEFAULT NULL  -- old site_key for the record
 ,nsite_key    IN number DEFAULT NULL  -- null means do not update
 ,new_recid    IN NUMBER DEFAULT NULL 
) IS
  local    dbinc%rowtype;
  fno      cdf.file#%type;
BEGIN
  IF (this_dbinc_key IS NULL) THEN
    raise_application_error(-20020, 'Database incarnation not set');
  END IF;
 
--
  BEGIN
--
     SELECT file# into fno
       FROM cdf
      WHERE dbinc_key in
               (select dbinc_key from dbinc where db_key = this_db_key)
      AND   ((osite_key is null AND cdf.site_key is null) OR 
             cdf.site_key = nvl(osite_key, cdf.site_key))
      AND   cdf.cdf_recid = changeDatafileCopy.cdf_recid
      AND   cdf.cdf_stamp = changeDatafileCopy.cdf_stamp;
  EXCEPTION
     WHEN no_data_found THEN
        BEGIN
--
           SELECT 0 into fno
             FROM ccf
            WHERE dbinc_key in
                     (select dbinc_key from dbinc where db_key = this_db_key)
            AND   ((osite_key is null AND ccf.site_key is null) OR 
                   ccf.site_key = nvl(osite_key, ccf.site_key))
            AND   ccf.ccf_recid = changeDatafileCopy.cdf_recid
            AND   ccf.ccf_stamp = changeDatafileCopy.cdf_stamp;
 
--
           changeControlfileCopy(cdf_recid, cdf_stamp, status,
                                 keep_options, keep_until,
                                 osite_key, nsite_key, new_recid);
           RETURN;
        EXCEPTION
           WHEN no_data_found THEN
              RETURN; -- already deleted (we are processing a DL record)
        END;
     WHEN OTHERS THEN
        RAISE;
  END;
 
  IF  status IS NULL THEN
--
--
    IF keep_until IS NOT NULL THEN
      UPDATE cdf SET keep_until = changeDatafileCopy.keep_until
      WHERE cdf.dbinc_key in
        (select dbinc_key from dbinc where dbinc.db_key = this_db_key)
      AND   ((osite_key is null AND cdf.site_key is null) OR 
             cdf.site_key = nvl(osite_key, cdf.site_key))
      AND   cdf.cdf_recid = changeDatafileCopy.cdf_recid
      AND   cdf.cdf_stamp = changeDatafileCopy.cdf_stamp;
    END IF;
    IF keep_options IS NOT NULL THEN
      UPDATE cdf SET keep_options = changeDatafileCopy.keep_options
      WHERE cdf.dbinc_key in
        (select dbinc_key from dbinc where dbinc.db_key = this_db_key)
      AND   ((osite_key is null AND cdf.site_key is null) OR 
             cdf.site_key = nvl(osite_key, cdf.site_key))
      AND   cdf.cdf_recid = changeDatafileCopy.cdf_recid
      AND   cdf.cdf_stamp = changeDatafileCopy.cdf_stamp;
    END IF;
    IF new_recid IS NOT NULL THEN
      UPDATE cdf SET cdf_recid = changeDatafileCopy.new_recid
      WHERE cdf.dbinc_key in
        (select dbinc_key from dbinc where dbinc.db_key = this_db_key)
      AND   ((osite_key is null AND cdf.site_key is null) OR
             cdf.site_key = nvl(osite_key, cdf.site_key))
      AND   cdf.cdf_recid = changeDatafileCopy.cdf_recid
      AND   cdf.cdf_stamp = changeDatafileCopy.cdf_stamp;
    END IF;
  ELSIF status IN ('A','U','X') THEN
--
--
    UPDATE cdf SET status = changeDatafileCopy.status,
                   site_key = nvl(nsite_key, site_key)
    WHERE cdf.dbinc_key in
      (select dbinc_key from dbinc where dbinc.db_key = this_db_key)
      AND   ((osite_key is null AND cdf.site_key is null) OR 
             cdf.site_key = nvl(osite_key, cdf.site_key))
      AND   cdf.cdf_recid = changeDatafileCopy.cdf_recid
      AND   cdf.cdf_stamp = changeDatafileCopy.cdf_stamp;
--
    IF sql%rowcount > 0 and nsite_key is not null THEN
       deleteDuplicateCDF(cdf_recid, cdf_stamp, null);
    END IF;
 
  ELSIF status IN ('R','D') THEN
    DELETE FROM cdf
    WHERE cdf.dbinc_key in
      (select dbinc_key from dbinc where dbinc.db_key = this_db_key)
      AND   ((osite_key is null AND cdf.site_key is null) OR 
             cdf.site_key = nvl(osite_key, cdf.site_key))
      AND   cdf.cdf_recid = changeDatafileCopy.cdf_recid
      AND   cdf.cdf_stamp = changeDatafileCopy.cdf_stamp;
  ELSE
    raise_application_error(-20100, 'Invalid status');
  END IF;
 
--
  commitChanges('changeDatafileCopy');
 
END changeDatafileCopy;
 
PROCEDURE changeControlfileCopy(
  cdf_recid    IN NUMBER
 ,cdf_stamp    IN NUMBER
 ,status       IN VARCHAR2
 ,keep_options IN NUMBER DEFAULT NULL  -- null means do not update
 ,keep_until   IN DATE   DEFAULT NULL
 ,osite_key    IN number DEFAULT NULL  -- old site_key for the record
 ,nsite_key    IN number DEFAULT NULL  -- null means do not update
 ,new_recid    IN NUMBER DEFAULT NULL
) IS
 
local    dbinc%rowtype;
 
BEGIN
  IF (this_dbinc_key IS NULL) THEN
    raise_application_error(-20020, 'Database incarnation not set');
  END IF;
 
  IF  status IS NULL THEN
--
--
    IF keep_until IS NOT NULL THEN
      UPDATE ccf SET keep_until = changeControlfileCopy.keep_until
      WHERE  ccf.dbinc_key in
        (select dbinc_key from dbinc where dbinc.db_key = this_db_key)
        AND  ((osite_key is null AND ccf.site_key is null) OR 
              ccf.site_key = nvl(osite_key, ccf.site_key))
        AND  ccf.ccf_recid = changeControlfileCopy.cdf_recid
        AND  ccf.ccf_stamp = changeControlfileCopy.cdf_stamp;
    END IF;
    IF keep_options IS NOT NULL THEN
      UPDATE ccf SET keep_options = changeControlfileCopy.keep_options
      WHERE  ccf.dbinc_key in
        (select dbinc_key from dbinc where dbinc.db_key = this_db_key)
        AND  ((osite_key is null AND ccf.site_key is null) OR 
              ccf.site_key = nvl(osite_key, ccf.site_key))
        AND  ccf.ccf_recid = changeControlfileCopy.cdf_recid
        AND  ccf.ccf_stamp = changeControlfileCopy.cdf_stamp;
    END IF;
    IF new_recid IS NOT NULL THEN
      UPDATE ccf SET ccf_recid = changeControlfileCopy.new_recid
      WHERE  ccf.dbinc_key in
        (select dbinc_key from dbinc where dbinc.db_key = this_db_key)
        AND  ((osite_key is null AND ccf.site_key is null) OR
              ccf.site_key = nvl(osite_key, ccf.site_key))
        AND  ccf.ccf_recid = changeControlfileCopy.cdf_recid
        AND  ccf.ccf_stamp = changeControlfileCopy.cdf_stamp;
    END IF;
  ELSIF status IN ('A','U','X') THEN
--
--
    UPDATE ccf SET status = changeControlfileCopy.status,
                   site_key = nvl(nsite_key, site_key)
    WHERE  ccf.dbinc_key in
      (select dbinc_key from dbinc where dbinc.db_key = this_db_key)
      AND  ((osite_key is null AND ccf.site_key is null) OR 
            ccf.site_key = nvl(osite_key, ccf.site_key))
      AND   ccf.ccf_recid = changeControlfileCopy.cdf_recid
      AND   ccf.ccf_stamp = changeControlfileCopy.cdf_stamp;
--
    IF sql%rowcount > 0 and nsite_key is not null THEN
       deleteDuplicateCCF(cdf_recid, cdf_stamp, null);
    END IF;
  ELSIF status IN ('R','D') THEN
    DELETE FROM ccf
    WHERE ccf.dbinc_key in
      (select dbinc_key from dbinc where dbinc.db_key = this_db_key)
      AND  ((osite_key is null AND ccf.site_key is null) OR 
            ccf.site_key = nvl(osite_key, ccf.site_key))
      AND   ccf.ccf_recid = changeControlfileCopy.cdf_recid
      AND   ccf.ccf_stamp = changeControlfileCopy.cdf_stamp;
  ELSE
    raise_application_error(-20100, 'Invalid status');
  END IF;
 
--
  commitChanges('changeControlfileCopy');
 
END changeControlfileCopy;
 
PROCEDURE changeArchivedLog(
  al_recid  IN NUMBER
 ,al_stamp  IN NUMBER
 ,status    IN VARCHAR2
 ,osite_key IN NUMBER DEFAULT NULL        -- old site_key for the record
 ,nsite_key IN NUMBER DEFAULT NULL        -- null means do not update
 ,new_recid IN NUMBER DEFAULT NULL
) IS
BEGIN
  IF (this_dbinc_key IS NULL) THEN
    raise_application_error(-20020, 'Database incarnation not set');
  END IF;
 
  IF status IS NULL THEN
     IF (new_recid IS NOT NULL) THEN
        UPDATE al SET al_recid = changeArchivedLog.new_recid
         WHERE al.dbinc_key in
               (select dbinc_key from dbinc where dbinc.db_key = this_db_key)
           AND al.al_recid = changeArchivedLog.al_recid
           AND al.al_stamp = changeArchivedLog.al_stamp
           AND ((osite_key is null AND al.site_key is null) OR
                al.site_key = nvl(osite_key, al.site_key));
     END IF;
  ELSIF status IN ('A','U','X') THEN
--
--
     UPDATE al SET status = changeArchivedLog.status,
                   site_key = nvl(nsite_key, site_key)
     WHERE al.dbinc_key in
       (select dbinc_key from dbinc where dbinc.db_key = this_db_key)
     AND   al.al_recid = changeArchivedLog.al_recid
     AND   al.al_stamp = changeArchivedLog.al_stamp
     AND   ((osite_key is null AND al.site_key is null) OR 
            al.site_key = nvl(osite_key, al.site_key));
--
     IF sql%rowcount > 0 and nsite_key is not null THEN
        deleteDuplicateAL(al_recid, al_stamp, null);
     END IF;
  ELSIF status IN ('R','D') THEN
--
--
--
    DELETE FROM al
    WHERE al.dbinc_key IN
      (SELECT dbinc_key FROM dbinc WHERE dbinc.db_key = this_db_key)
      AND   ((osite_key is null AND al.site_key is null) OR 
             al.site_key = nvl(osite_key, al.site_key))
      AND al.al_recid = changeArchivedLog.al_recid
      AND al.al_stamp = changeArchivedLog.al_stamp;
  ELSE
    raise_application_error(-20100, 'Invalid status');
  END IF;
 
--
  commitChanges('changeArchivedLog');
 
END changeArchivedLog;
 
PROCEDURE changeBackupSet(
  recid        IN number
 ,stamp        IN number
 ,keep_options IN number   -- null means do not update
 ,keep_until   IN date
 ,osite_key    IN number    DEFAULT NULL  -- old site_key for the record
 ,nsite_key    IN number    DEFAULT NULL  -- null means do not update
) IS
   local    bs%rowtype;
   CURSOR dflist IS
      SELECT * FROM bdf
      WHERE bdf.bs_key = local.bs_key;
   CURSOR rllist IS
      SELECT * FROM brl
      WHERE brl.bs_key = local.bs_key;
   has_virtual boolean := TRUE;
   l_virtual   number  := 0;
BEGIN
  IF (this_db_key IS NULL) THEN
    raise_application_error(-20021, 'Database not set');
  END IF;
 
  BEGIN
    SELECT * INTO local
    FROM bs
    WHERE bs.db_key = this_db_key
    AND   bs.bs_recid = changeBackupSet.recid
    AND   bs.bs_stamp = changeBackupSet.stamp FOR UPDATE OF bs.bs_key;
    deb('changeBackupSet - locked bs_key' || local.bs_key);
  EXCEPTION
    WHEN NO_DATA_FOUND THEN
      RETURN; -- already deleted (we are processing a DL record)
  END;
 
  BEGIN
    SELECT bp.vb_key INTO l_virtual 
    FROM bp,bs 
    WHERE bp.bs_key = bs.bs_key
    AND   bp.vb_key IS NOT NULL
    AND   bs.bs_key = local.bs_key;
  EXCEPTION
    WHEN NO_DATA_FOUND THEN
      has_virtual := FALSE;  -- no virtual found
  END;  
 
  IF has_virtual THEN
    deb('changeBackupSet - virtual backup piece key (AM)' || l_virtual);
  END IF;
 
  IF nsite_key is not null THEN
     UPDATE bp SET site_key = nsite_key WHERE bs_key = local.bs_key;
     UPDATE bs SET site_key = nsite_key WHERE bs_key = local.bs_key;
  END IF;
 
  IF NOT has_virtual THEN 
    UPDATE bs SET bs.keep_until = changeBackupSet.keep_until
    WHERE  bs.bs_key = local.bs_key;
  END IF;
 
  IF NOT has_virtual AND keep_options IS NOT NULL THEN
    UPDATE bs SET bs.keep_options = changeBackupSet.keep_options
    WHERE  bs.bs_key = local.bs_key;
 
--
    IF (local.bck_type = 'L') THEN
      FOR rlrec IN rllist LOOP
        updateRestorePoint(rlrec.low_scn, rlrec.next_scn);
      END LOOP;
    END IF;
    IF (local.bck_type = 'D') THEN
      FOR dfrec IN dflist LOOP
        updateRestorePoint(dfrec.ckp_scn, null);
      END LOOP;
    END IF;
  END IF;
 
--
  commitChanges('changeBackupSet');
 
END changeBackupSet;
 
PROCEDURE changeBackupPiece(
  bp_recid  IN NUMBER
 ,bp_stamp  IN NUMBER
 ,status    IN VARCHAR2
 ,set_stamp IN NUMBER    DEFAULT NULL
 ,set_count IN NUMBER    DEFAULT NULL
 ,osite_key IN NUMBER    DEFAULT NULL  -- old site_key for the record
 ,nsite_key IN NUMBER    DEFAULT NULL  -- null means do not update
 ,handle    IN VARCHAR2  DEFAULT NULL  -- null means not known
 ,device_type IN VARCHAR2 DEFAULT NULL -- null means not known
) IS
   CURSOR bsQ(bp_recid IN NUMBER, bp_stamp IN NUMBER) IS
      SELECT bs_key
        FROM bp
       WHERE bp.db_key   = this_db_key
         AND ((osite_key is null AND bp.site_key is null) OR 
              bp.site_key = nvl(osite_key, bp.site_key))
         AND bp.bp_recid = bsQ.bp_recid
         AND bp.bp_stamp = bsQ.bp_stamp;
   bsQrec       bsQ%ROWTYPE;
   totalbp      number;
   chgbskey     number := NULL;
   l_ba_access  bp.ba_access%type;
   l_bp_key     number;
   l_bp_recid   number;
   l_bp_stamp   number;
BEGIN
  IF (this_db_key IS NULL) THEN
    raise_application_error(-20021, 'Database not set');
  END IF;
 
  l_bp_recid := changeBackupPiece.bp_recid; 
  l_bp_stamp := changeBackupPiece.bp_stamp; 
 
--
--
  IF (set_stamp is not null AND set_count is not null) THEN
     BEGIN
        SELECT bs_key INTO chgbskey
          FROM bs
         WHERE bs.db_key    = this_db_key
           AND bs.set_stamp = changeBackupPiece.set_stamp
           AND bs.set_count = changeBackupPiece.set_count 
         FOR UPDATE OF bs.bs_key;
        deb('changeBackupPiece - locked bs_key' || chgbskey);
     EXCEPTION
       WHEN NO_DATA_FOUND THEN
         RETURN; -- already deleted (we are processing a DL record)
     END;
     deb('changeBackupPiece - chgbskey=' || chgbskey);
  ELSE
--
--
--
--
--
       
     SELECT count(*) INTO totalbp
       FROM bp
      WHERE bp.db_key   = this_db_key
        AND ((osite_key is null AND bp.site_key is null) OR 
             bp.site_key = nvl(osite_key, bp.site_key))
        AND bp.bp_recid = l_bp_recid
        AND bp.bp_stamp = l_bp_stamp
        AND bp.bs_key   = nvl(chgbskey, bp.bs_key);
 
     deb('changeBackupPiece - number of backup pieces match ' || totalbp);
 
     IF totalbp = 0 then
        RETURN; -- already deleted (we are processing a DL record)
     END IF;
  END IF;
 
  IF changeBackupPiece.handle is NOT NULL AND chgbskey IS NOT NULL THEN
     BEGIN
       deb('changeBackupPiece - Override bp_recid/bp_stamp for ' ||
           handle || ', on ' || device_type);
       SELECT bp_recid, bp_stamp INTO
              l_bp_recid, l_bp_stamp
         FROM bp
         WHERE bp.db_key = this_db_key
           AND bp.bs_key = chgbskey
           AND bp.handle = changeBackupPiece.handle
           AND bp.device_type = changeBackupPiece.device_type;
     EXCEPTION
       WHEN NO_DATA_FOUND THEN
         deb('changeBackupPiece - Not found ');
       WHEN OTHERS THEN
         deb('changeBackupPiece(DO_NOT_IGNORE) - Error ' || sqlerrm);
     END;
     deb('changeBackupPiece - recid='||l_bp_recid||', stamp='||l_bp_stamp);
  END IF;
 
--
--
--
 
  IF status in ('A','U','X') THEN
--
--
    UPDATE bp SET status = changeBackupPiece.status,
                  site_key = nvl(nsite_key, site_key)
    WHERE bp.db_key   = this_db_key
      AND ((osite_key is null AND bp.site_key is null) OR 
           bp.site_key = nvl(osite_key, bp.site_key))
      AND bp.bp_recid = l_bp_recid
      AND bp.bp_stamp = l_bp_stamp
      AND bp.bs_key   = nvl(chgbskey, bp.bs_key)
      AND bp.ba_access != 'L'    -- AM: no status changing
      AND bp.status  != 'D';
 
--
    IF sql%rowcount > 0 and nsite_key is not null THEN
--
--
       IF chgbskey is not null THEN
          UPDATE bs SET site_key=null WHERE bs_key = chgbskey; 
       ELSE
          UPDATE bs SET site_key=null WHERE bs_key in 
            (SELECT bs_key FROM bp
             WHERE bp.db_key   = this_db_key
              AND ((osite_key is null AND bp.site_key is null) OR
                   bp.site_key = nvl(osite_key, bp.site_key))
              AND bp.bp_recid = l_bp_recid
              AND bp.bp_stamp = l_bp_stamp);
       END IF;
       deleteDuplicateBP(l_bp_recid, l_bp_stamp, chgbskey, null, null);
    END IF;
  ELSIF status not in ('R', 'D') THEN
     raise_application_error(-20100, 'Invalid status');
  END IF;
 
  IF this_is_ors AND this_ckp_key IS NULL THEN
     this_enable_populate_rsr := getValueFromConfig('_enable_populate_rsr_key');
  END IF;
 
  IF (chgbskey IS NULL) THEN
     FOR bsQrec in bsQ(l_bp_recid, l_bp_stamp) LOOP
--
--
        IF status in ('R', 'D') THEN
           UPDATE bp SET bp.status = 'D'
            WHERE bp.db_key   = this_db_key
              AND ((osite_key is null AND bp.site_key is null) OR 
                   bp.site_key = nvl(osite_key, bp.site_key))
              AND bp.bp_recid = l_bp_recid
              AND bp.bp_stamp = l_bp_stamp
              AND bp.bs_key   = bsQrec.bs_key
           RETURNING bp.ba_access, bp.bp_key INTO l_ba_access, l_bp_key;
 
--
           IF l_ba_access != 'U' THEN
              DELETE FROM bp WHERE bp.bp_key = l_bp_key;
           END IF;
        END IF;
--
        updateBackupSetRec(bsQrec.bs_key);
     END LOOP;
  ELSE
     IF status in ('R', 'D') THEN
         UPDATE bp SET bp.status = 'D'
         WHERE bp.db_key   = this_db_key
           AND ((osite_key is null AND bp.site_key is null) OR 
                bp.site_key = nvl(osite_key, bp.site_key))
           AND bp.bp_recid = l_bp_recid
           AND bp.bp_stamp = l_bp_stamp
           AND bp.bs_key   = chgbskey
           AND bp.ba_access != 'L'    -- AM: no status changing
         RETURNING bp.ba_access, bp.bp_key INTO l_ba_access, l_bp_key;
 
--
        IF l_ba_access = 'U' THEN
           DELETE FROM bp WHERE bp.bp_key = l_bp_key;
        END IF;
     END IF;
--
     updateBackupSetRec(chgbskey);
  END IF;
--
--
  IF this_is_ors AND this_ckp_key IS NULL THEN
     this_enable_populate_rsr := NULL;
     this_upstream_site_key := NULL;
  END IF;
--
  commitChanges('changeBackupPiece');
 
END changeBackupPiece;
 
PROCEDURE changeProxyCopy(
  pc_recid     IN NUMBER
 ,pc_stamp     IN NUMBER
 ,status       IN VARCHAR2
 ,keep_options IN NUMBER DEFAULT NULL  -- null means do not update
 ,keep_until   IN DATE   DEFAULT NULL
 ,osite_key    IN number DEFAULT NULL  -- old site_key for the record
 ,nsite_key    IN number DEFAULT NULL  -- null means do not update
) IS
  low_scn   number;
  next_scn  number;
  xobjid    rowid;  -- proxy object rowid
BEGIN
  IF this_db_key IS NULL THEN
    raise_application_error(-20021, 'Database not set');
  END IF;
 
  IF status IS NULL THEN
--
--
    IF keep_until IS NOT NULL THEN
      UPDATE xdf SET xdf.keep_until = changeProxyCopy.keep_until
      WHERE   xdf.dbinc_key in
        (select dbinc_key from dbinc where dbinc.db_key = this_db_key)
      AND   ((osite_key is null AND xdf.site_key is null) OR 
             xdf.site_key = nvl(osite_key, xdf.site_key))
      AND    xdf.xdf_recid = changeProxyCopy.pc_recid
      AND    xdf.xdf_stamp = changeProxyCopy.pc_stamp;
--
      IF sql%rowcount = 0 THEN
        UPDATE xcf SET xcf.keep_until = changeProxyCopy.keep_until
        WHERE  xcf.dbinc_key in
          (select dbinc_key from dbinc where dbinc.db_key = this_db_key)
        AND   ((osite_key is null AND xcf.site_key is null) OR 
               xcf.site_key = nvl(osite_key, xcf.site_key))
        AND   xcf.xcf_recid = changeProxyCopy.pc_recid
        AND   xcf.xcf_stamp = changeProxyCopy.pc_stamp;
      END IF;
    END IF;
    IF keep_options IS NOT NULL THEN
      SELECT min(ckp_scn), min(rowid) into low_scn, xobjid
      FROM xdf
      WHERE   xdf.dbinc_key in
        (select dbinc_key from dbinc where dbinc.db_key = this_db_key)
      AND    ((osite_key is null AND xdf.site_key is null) OR 
              xdf.site_key = nvl(osite_key, xdf.site_key))
      AND    xdf.xdf_recid = changeProxyCopy.pc_recid
      AND    xdf.xdf_stamp = changeProxyCopy.pc_stamp;
 
--
      IF xobjid IS NOT NULL THEN
        updateRestorePoint(low_scn, null);
        UPDATE xdf SET xdf.keep_options = changeProxyCopy.keep_options
        WHERE rowid = xobjid;
      ELSE
--
        UPDATE xcf SET xcf.keep_options = changeProxyCopy.keep_options
        WHERE  xcf.dbinc_key in
          (select dbinc_key from dbinc where dbinc.db_key = this_db_key)
        AND ((osite_key is null AND xcf.site_key is null) OR 
             xcf.site_key = nvl(osite_key, xcf.site_key))
        AND   xcf.xcf_recid = changeProxyCopy.pc_recid
        AND   xcf.xcf_stamp = changeProxyCopy.pc_stamp;
--
        IF sql%rowcount = 0 THEN
          SELECT min(xal.low_scn), min(xal.next_scn), min(rowid)
                 into low_scn, next_scn, xobjid
          FROM xal
          WHERE  xal.dbinc_key in
            (select dbinc_key from dbinc where dbinc.db_key = this_db_key)
          AND ((osite_key is null AND xal.site_key is null) OR 
               xal.site_key = nvl(osite_key, xal.site_key))
          AND   xal.xal_recid = changeProxyCopy.pc_recid
          AND   xal.xal_stamp = changeProxyCopy.pc_stamp;
--
          IF xobjid IS NOT NULL THEN
            updateRestorePoint(low_scn, next_scn);
            UPDATE xal SET xal.keep_options = changeProxyCopy.keep_options
            WHERE rowid = xobjid;
          END IF;
        END IF;
      END IF;
    END IF;
  ELSIF status in ('A','U','X') THEN
--
--
    UPDATE xdf SET status = changeProxyCopy.status,
                   site_key = nvl(nsite_key, site_key)
    WHERE xdf.dbinc_key in
      (select dbinc_key from dbinc where dbinc.db_key = this_db_key)
    AND   ((osite_key is null AND xdf.site_key is null) OR 
           xdf.site_key = nvl(osite_key, xdf.site_key))
    AND   xdf.xdf_recid = changeProxyCopy.pc_recid
    AND   xdf.xdf_stamp = changeProxyCopy.pc_stamp;
--
    IF sql%rowcount > 0 and nsite_key is not null THEN
       deleteDuplicateXDF(pc_recid, pc_stamp, null, null);
    END IF;
 
--
    IF sql%rowcount = 0 THEN
      UPDATE xcf SET status = changeProxyCopy.status,
                   site_key = nvl(nsite_key, site_key)
      WHERE xcf.dbinc_key in
        (select dbinc_key from dbinc where dbinc.db_key = this_db_key)
      AND   ((osite_key is null AND xcf.site_key is null) OR 
             xcf.site_key = nvl(osite_key, xcf.site_key))
      AND   xcf.xcf_recid = changeProxyCopy.pc_recid
      AND   xcf.xcf_stamp = changeProxyCopy.pc_stamp;
--
      IF sql%rowcount > 0 and nsite_key is not null THEN
         deleteDuplicateXCF(pc_recid, pc_stamp, null, null);
      END IF;
    END IF;
 
--
    IF sql%rowcount = 0 THEN
      UPDATE xal SET status = changeProxyCopy.status,
                   site_key = nvl(nsite_key, site_key)
      WHERE xal.dbinc_key in
        (select dbinc_key from dbinc where dbinc.db_key = this_db_key)
      AND   ((osite_key is null AND xal.site_key is null) OR 
             xal.site_key = nvl(osite_key, xal.site_key))
      AND   xal.xal_recid = changeProxyCopy.pc_recid
      AND   xal.xal_stamp = changeProxyCopy.pc_stamp;
--
      IF sql%rowcount > 0 and nsite_key is not null THEN
          deleteDuplicateXAL(pc_recid, pc_stamp, null, null);
      END IF;
    END IF;
  ELSIF status IN ('R','D') THEN
--
    SELECT min(ckp_scn), min(rowid) into low_scn, xobjid
    FROM xdf
    WHERE xdf.dbinc_key in
      (select dbinc_key from dbinc where dbinc.db_key = this_db_key)
    AND   ((osite_key is null AND xdf.site_key is null) OR 
           xdf.site_key = nvl(osite_key, xdf.site_key))
    AND   xdf.xdf_recid = changeProxyCopy.pc_recid
    AND   xdf.xdf_stamp = changeProxyCopy.pc_stamp;
--
    IF xobjid IS NOT NULL THEN
      updateRestorePoint(low_scn, null);
      DELETE FROM xdf
      WHERE rowid = xobjid;
    ELSE
--
      DELETE FROM xcf
      WHERE xcf.dbinc_key in
        (select dbinc_key from dbinc where dbinc.db_key = this_db_key)
      AND   ((osite_key is null AND xcf.site_key is null) OR 
             xcf.site_key = nvl(osite_key, xcf.site_key))
      AND   xcf.xcf_recid = changeProxyCopy.pc_recid
      AND   xcf.xcf_stamp = changeProxyCopy.pc_stamp;
 
--
      IF sql%rowcount = 0 THEN
        SELECT min(xal.low_scn), min(xal.next_scn), min(rowid)
               into low_scn, next_scn, xobjid
        FROM xal
        WHERE xal.dbinc_key in
          (select dbinc_key from dbinc where dbinc.db_key = this_db_key)
        AND   ((osite_key is null AND xal.site_key is null) OR 
               xal.site_key = nvl(osite_key, xal.site_key))
        AND   xal.xal_recid = changeProxyCopy.pc_recid
        AND   xal.xal_stamp = changeProxyCopy.pc_stamp;
        IF xobjid IS NOT NULL THEN
          updateRestorePoint(low_scn, next_scn);
          DELETE FROM xal
          WHERE rowid = xobjid;
        END IF;
      END IF;
    END IF;
  ELSE
    raise_application_error(-20100, 'Invalid status');
  END IF;
 
--
  commitChanges('changeProxyCopy');
 
END changeProxyCopy;
 
/*----------------------------*
 * Stored Script Procedures   *
 *----------------------------*/
 
PROCEDURE createScript(name IN VARCHAR2) IS
BEGIN
  createScript(name, NULL, FALSE);
END;
 
PROCEDURE createScript(name IN VARCHAR2,
                       scr_com IN VARCHAR2,
                       global IN boolean) IS
  foo NUMBER;
  dbkey  NUMBER := this_db_key;
BEGIN
  scr_key := NULL;                      -- for safety
  IF global THEN
     dbkey := NULL;
     scr_glob := TRUE;
  ELSE
     scr_glob := FALSE;
     IF (this_db_key IS NULL) THEN
        raise_application_error(-20021, 'Database not set');
     END IF;
  END IF;
  SELECT count(*)
    INTO foo
    FROM scr
   WHERE ((dbkey is not null and scr.db_key = dbkey)
      OR  (dbkey is null and scr.db_key is null))
     AND scr.scr_name = createScript.name;
  IF foo > 0 THEN
    raise_application_error(-20401, 'script '||name||' already exists');
  END IF;
 
  INSERT INTO scr VALUES(rman_seq.nextval, dbkey, name, scr_com)
  RETURNING scr_key INTO scr_key;
  scr_line := 1;
 
--
  commitChanges('createScript');
 
END;
 
PROCEDURE replaceScript(name IN VARCHAR2) IS
 
BEGIN
   replaceScript(name, NULL, FALSE);
END;
 
PROCEDURE replaceScript(name IN VARCHAR2,
                        scr_com IN VARCHAR2,
                        global IN boolean) IS
  dbkey  NUMBER := this_db_key;
BEGIN
  IF global THEN
     dbkey := NULL;
     scr_glob := TRUE;
  ELSE
     scr_glob := FALSE;
     IF (this_db_key IS NULL) THEN
        raise_application_error(-20021, 'Database not set');
     END IF;
  END IF;
 
  SELECT scr_key
    INTO scr_key
    FROM scr
   WHERE ((dbkey is not null and scr.db_key = dbkey)
      OR  (dbkey is null and scr.db_key is null))
     AND scr.scr_name = replaceScript.name;
 
  UPDATE scr
     SET scr_comment = scr_com
   WHERE scr.scr_key = dbms_rcvcat.scr_key;
 
  DELETE FROM scrl
   WHERE scrl.scr_key = dbms_rcvcat.scr_key;
 
  scr_line := 1;
 
--
  commitChanges('replaceScript');
 
EXCEPTION
  WHEN NO_DATA_FOUND THEN
    createScript(name, scr_com, global);
 
END;
 
PROCEDURE putLine(line IN VARCHAR2) IS
 
BEGIN
  IF not scr_glob and this_db_key IS NULL THEN
    raise_application_error(-20021, 'Database not set');
  END IF;
  IF (scr_key IS NULL) THEN
    raise_application_error(-20402, 'createScript or replaceScript not done');
  END IF;
 
  INSERT INTO scrl(scr_key, linenum, text) VALUES(scr_key, scr_line, line);
  scr_line := scr_line + 1;
 
END;
 
PROCEDURE deleteScript(name IN VARCHAR2) IS
 
BEGIN
   deleteScript(name, 0);
END;
 
PROCEDURE deleteScript(name IN VARCHAR2, glob IN NUMBER) IS
  dbkey  NUMBER := this_db_key;
BEGIN
  IF glob = 1 THEN
     dbkey := NULL;
  ELSE
     IF (this_db_key IS NULL) THEN
        raise_application_error(-20021, 'Database not set');
     END IF;
  END IF;
 
  SELECT scr_key INTO scr_key
  FROM scr
   WHERE ((dbkey is not null and scr.db_key = dbkey)
      OR  (dbkey is null and scr.db_key is null))
     AND scr.scr_name = deleteScript.name;
 
  DELETE FROM scr
  WHERE scr.scr_key = dbms_rcvcat.scr_key;
  scr_key := NULL;
 
--
  commitChanges('deleteScript');
 
EXCEPTION
  WHEN NO_DATA_FOUND THEN
    scr_key := NULL;
    raise_application_error(-20400, 'stored script not found');
 
END;
 
PROCEDURE getScript(name IN VARCHAR2) IS
BEGIN
   getScript(name, 0);
END;
 
PROCEDURE getScript(name IN VARCHAR2, glob IN NUMBER) IS
  dbkey  NUMBER := this_db_key;
BEGIN
  IF glob = 1 THEN
     dbkey := NULL;
     scr_glob := TRUE;
  ELSE
     scr_glob := FALSE;
     IF (this_db_key IS NULL) THEN
        raise_application_error(-20021, 'Database not set');
     END IF;
  END IF;
 
  SELECT scr_key INTO scr_key
  FROM scr
   WHERE ((dbkey is not null and scr.db_key = dbkey)
      OR  (dbkey is null and scr.db_key is null))
     AND scr.scr_name = getScript.name;
 
  IF scrlQ%ISOPEN THEN
    CLOSE scrlQ;
  END IF;
  OPEN scrlQ(scr_key);
EXCEPTION
  WHEN NO_DATA_FOUND THEN
    scr_key := NULL;
    raise_application_error(-20400, 'stored script not found');
END;
 
FUNCTION getLine RETURN VARCHAR2 IS
  scrl_row   scrlQ%rowtype;
BEGIN
  IF not scr_glob and this_db_key IS NULL THEN
    raise_application_error(-20021, 'Database not set');
  END IF;
  IF NOT scrlQ%ISOPEN THEN
    raise_application_error(-20403, 'getScript not done');
  END IF;
  FETCH scrlQ INTO scrl_row;
  IF scrlQ%NOTFOUND THEN  -- end of fetch
    close scrlQ;
    return NULL;
  END IF;
  RETURN scrl_row.text;
END;
 
PROCEDURE commitChanges(msg IN varchar2 DEFAULT NULL) IS
BEGIN
  IF (this_ckp_key IS NULL) THEN
    deb(msg || ',commitChanges commit, release locks');
    commit;
  ELSE
    deb(msg || ',resync active, commitChanges ignored');
  END IF;
END;
 
/*---------------------------------------*
 * Procedures for EM xml store support   *
 *---------------------------------------*/
procedure createXMLFile (name        IN varchar2 
                        ,name_tag    IN varchar2
                        ,xmldoc      IN     clob
                        ,doctype     IN varchar2
                        ,xml_comment IN varchar2
                        ,schema_ver  IN varchar2
                        ) IS
begin
 
--
   insert into xmlstore
      (store_key, 
       creation_time, 
       name, 
       name_tag, 
       doctype, 
       schema_ver, 
       xml_comment,
       xmldoc) 
   values
      (rman_seq.nextval, 
       sys_extract_utc(systimestamp),
       createXMLFile.name,
       createXMLFile.name_tag, 
       createXMLFile.doctype,
       createXMLFile.schema_ver, 
       createXMLFile.xml_comment,
       XMLType.createXML(createXMLFile.xmldoc, schema_ver));
   commitChanges('createXMLFile');
 
end createXMLFile;
 
procedure updateXMLFile (name        IN varchar2
                        ,name_tag    IN varchar2
                        ,xmldoc      IN clob
                        ,xml_comment IN varchar2
                        ,schema_ver  IN varchar2
                        ,new_name    IN varchar2
                        ,new_name_tag IN varchar2
                        ,new_version  IN BOOLEAN ) IS
   oldrec          xmlstore%ROWTYPE;
begin
 
--
   begin
      select * into oldrec
      from xmlstore
      where name = updateXMLFile.name
         and (name_tag = updateXMLFile.name_tag or
              (name_tag is null and updateXMLFile.name_tag is null))
      for update;
   exception
      when too_many_rows then
         select * into oldrec
         from xmlstore
          where name = updateXMLFile.name
            and (name_tag = updateXMLFile.name_tag or
                 (name_tag is null and updateXMLFile.name_tag is null))
            and version_num = 
                (select max(version_num) from xmlstore
                 where name = updateXMLFile.name
                   and (name_tag = updateXMLFile.name_tag or
                         (name_tag is null 
                          and updateXMLFile.name_tag is null)))
          for update;
   end;
 
--
   if xmldoc is not null then
      oldrec.xmldoc := 
         XMLType.createXML(xmldoc, nvl(schema_ver, oldrec.schema_ver));
   end if;
 
   if xml_comment is not null then
      oldrec.xml_comment := xml_comment;
   end if;
 
   if schema_ver is not null then
      oldrec.schema_ver := schema_ver;
   end if;
 
   if new_name is not null then
      oldrec.name := new_name;
   end if;
 
   if new_name_tag is not null then
      oldrec.name_tag := new_name_tag;
   end if;
 
--
--
   if new_version then
      oldrec.version_num := oldrec.version_num + 1;
      select rman_seq.nextval into oldrec.store_key from dual;
      insert into xmlstore values oldrec;
   else
     oldrec.modified_time := sys_extract_utc(systimestamp);
      update xmlstore p set row = oldrec
         where p.name = updateXMLFile.name
            and (p.name_tag = updateXMLFile.name_tag or
                 (p.name_tag is null and updateXMLFile.name_tag is null))
            and p.version_num = oldrec.version_num;
   end if;
 
   commitChanges('updateXMLFile');
 
end updateXMLFile;
 
procedure deleteXMLFile (name     IN varchar2
                        ,name_tag IN varchar2) IS
begin
 
--
   delete xmlstore 
      where name = deleteXMLFile.name
        and (name_tag = deleteXMLFile.name_tag or
             (name_tag is null and deleteXMLFile.name_tag is null));
   if sql%rowcount = 0 then
      raise no_data_found;
   end if;
   commitChanges('deleteXMLFile');
 
end deleteXMLFile;
 
procedure readXMLFile   (name        IN varchar2
                        ,name_tag    IN varchar2
                        ,version_num IN number
                        ,xmldoc      OUT clob) IS
begin
 
--
   if version_num is null then
      begin
         select XMLType.getClobVal(xmldoc) into readXMLFile.xmldoc
         from xmlstore
         where name = readXMLFile.name
            and (name_tag = readXMLFile.name_tag or
                 (name_tag is null and readXMLFile.name_tag is null));
      exception
         when too_many_rows then
            select XMLType.getClobVal(xmldoc) into readXMLFile.xmldoc
            from xmlstore
             where name = readXMLFile.name
              and (name_tag = readXMLFile.name_tag or
                   (name_tag is null and readXMLFile.name_tag is null))
              and version_num = 
                  (select max(version_num) from xmlstore
                   where name = readXMLFile.name
                    and (name_tag = readXMLFile.name_tag or
                         (name_tag is null and readXMLFile.name_tag is null)));
      end;
   else
      select XMLType.getClobVal(xmldoc) into readXMLFile.xmldoc
      from xmlstore
      where name = readXMLFile.name
         and (name_tag = readXMLFile.name_tag or
              (name_tag is null and readXMLFile.name_tag is null))
         and version_num = readXMLFile.version_num;
   end if;
 
end readXMLFile;
 
procedure getXMLFileAttr (name        IN varchar2
                         ,name_tag    IN varchar2
                         ,version_num IN number
                         ,doctype     OUT varchar2
                         ,file_size   OUT number
                         ,xml_comment OUT varchar2
                         ,schema_ver  OUT varchar2) is
   myrec xmlstore%ROWTYPE;
begin
 
--
--
   if version_num is null then
      begin
         select * into myrec
         from xmlstore
         where name = getXMLFileAttr.name
           and (name_tag = getXMLFileAttr.name_tag or 
                (name_tag is null and getXMLFileAttr.name_tag is null));
      exception
         when too_many_rows then
            select * into myrec
            from xmlstore
             where name = getXMLFileAttr.name
               and (name_tag = getXMLFileAttr.name_tag or
                    (name_tag is null and getXMLFileAttr.name_tag is null))
               and version_num = 
                   (select max(version_num) from xmlstore
                    where name = getXMLFileAttr.name
                      and (name_tag = getXMLFileAttr.name_tag or
                           (name_tag is null 
                            and getXMLFileAttr.name_tag is null)));
      end;
   else
      select * into myrec
      from xmlstore
      where name = getXMLFileAttr.name
         and (name_tag = getXMLFileAttr.name_tag or
              (name_tag is null and getXMLFileAttr.name_tag is null))
         and version_num = getXMLFileAttr.version_num;
   end if;
 
--
   doctype := myrec.doctype;
   file_size := dbms_lob.getlength(XMLType.getClobVal(myrec.xmldoc));
   xml_comment := myrec.xml_comment;
   schema_ver := myrec.schema_ver;
 
end getXMLFileAttr;
 
--
--
--
FUNCTION getPackageVersion RETURN VARCHAR2 IS
   version raschemaver.version%type;
   table_not_found EXCEPTION;
   PRAGMA EXCEPTION_INIT(table_not_found, -942);
BEGIN
  IF version_counter > version_max_index THEN
    version_counter := 1;
    RETURN NULL;
  END IF;
 
  version_counter := version_counter + 1;
 
--
  BEGIN
     SELECT to_char(max(version), '09')
       INTO version 
       FROM raschemaver;
  EXCEPTION
     WHEN table_not_found THEN
        version := NULL;
  END;
 
  IF (version IS NULL) THEN
     version := '00';
  END IF;
 
--
  return version_list(version_counter - 1) || '.' || version;
END;
 
FUNCTION getCatalogVersion RETURN VARCHAR2 IS
version rcver.version%type;
BEGIN
  IF NOT rcverQ%ISOPEN THEN
    open rcverQ;
  END IF;
 
  FETCH rcverQ into version;
 
  IF rcverQ%NOTFOUND THEN  -- end of fetch
    close rcverQ;
    return NULL;
  END IF;
 
  RETURN version;
 
END;
 
/*---------------------------------------*
 * Procedures for clone database support *
 *---------------------------------------*/
 
PROCEDURE setCloneName(file#            IN  NUMBER
                      ,creation_change# IN  NUMBER
                      ,new_clone_fname  IN  VARCHAR2
                      ,old_clone_fname  IN  VARCHAR2
                      ,changedauxname   OUT boolean
                      ,plugin_change#   IN NUMBER   DEFAULT 0) IS
lfname df.clone_fname%TYPE;
BEGIN
  deb('setCloneName: file#='           || to_char(file#)||
                  ', creation_fname='  || to_char(nvl(creation_change#, ''))||
                  ', plugin_change#='  || to_char(nvl(plugin_change#, ''))||
                  ', old_clone_fname=' || old_clone_fname ||
                  ', new_clone_fname=' || new_clone_fname);
  changedauxname := FALSE;
--
--
  IF (new_clone_fname = 'UNKNOWN') THEN
     RETURN;
  END IF;
  IF old_clone_fname is NULL THEN
     IF new_clone_fname = 'NONE' THEN
--
        RETURN;
     ELSE
        lfname := new_clone_fname;
     END IF;
  ELSE
     IF new_clone_fname = 'NONE' THEN
        lfname := NULL;
     ELSIF old_clone_fname = new_clone_fname THEN
--
        RETURN;
     ELSE
        lfname := new_clone_fname;
     END IF;
  END IF;
 
  UPDATE df SET df.clone_fname = lfname
   WHERE df.dbinc_key = this_dbinc_key
     AND df.file# = setCloneName.file#
     AND df.create_scn = setCloneName.creation_change#
     AND df.plugin_scn = setCloneName.plugin_change#;
  changedauxname := TRUE;
 
  deb('setCloneName - changed auxname for file# '||to_char(file#)||
      ' from '||nvl(old_clone_fname, 'NULL')||' to '||
      nvl(lfname, 'NULL'));
EXCEPTION
  WHEN NO_DATA_FOUND THEN
    raise_application_error(-20105, 'datafile missing');
END;
 
--
--
FUNCTION getCloneName( file#            IN NUMBER
                      ,creation_change# IN NUMBER
                      ,plugin_change#   IN NUMBER DEFAULT 0)
RETURN VARCHAR2 IS
 
ret df.clone_fname%TYPE;
 
BEGIN
 
--
--
  ret := dbms_rcvman.getCloneName(file#, creation_change#, plugin_change#);
 
  RETURN ret;
 
EXCEPTION
  WHEN NO_DATA_FOUND THEN
    raise_application_error(-20105, 'datafile missing');
END;
 
 
/*-----------------------------------*
 * Procedures for RMAN configuration *
 *-----------------------------------*/
 
--
PROCEDURE setConfig(conf#            IN NUMBER
                   ,name             IN VARCHAR2
                   ,value            IN VARCHAR2) IS
BEGIN
 
  IF (this_db_key IS NULL) THEN
    raise_application_error(-20021, 'Database not set');
  END IF;
 
  INSERT INTO
         conf(     db_key, conf#, name, value, cleanup, db_unique_name,
                 site_key)
       VALUES(this_db_key, conf#, name, value,   'YES',           NULL,
                        0);
 
EXCEPTION
  WHEN dup_val_on_index THEN
    UPDATE conf SET
           conf.name = name,
           conf.value = value WHERE conf.conf# = conf#
                              AND   conf.db_key = this_db_key;
  RETURN;
END;
 
--
PROCEDURE setConfig2(conf#     IN NUMBER
                    ,name      IN VARCHAR2
                    ,value     IN VARCHAR2
                    ,nodespec  IN BOOLEAN) IS
  lname    conf.name%TYPE;
  lvalue   conf.value%TYPE;
BEGIN
 
  IF (this_db_key IS NULL) THEN
    raise_application_error(-20021, 'Database not set');
  END IF;
 
--
--
  IF (nodespec)
  THEN
    INSERT INTO
          conf(     db_key, conf#, name, value,  cleanup, db_unique_name,
                  site_key)
        VALUES(this_db_key, conf#, name, value,     'NO', this_db_unique_name,
               this_site_key);
  ELSE
    INSERT INTO
          conf(     db_key, conf#, name, value,  cleanup,  db_unique_name,
                  site_key)
        VALUES(this_db_key, conf#, name, value,     'NO',           NULL,
                           0);
 
  END IF;
 
  deb('setConfig - Added name=(' || name ||
      '), value=(' || maskConnectString(value) ||
      ') to node ' || this_db_unique_name ||
      '('|| conf# ||')');
 
  EXCEPTION
--
--
    WHEN dup_val_on_index THEN
      select name, value into lname, lvalue from conf where
             conf.conf# = setConfig2.conf# AND
             conf.db_key = this_db_key AND
             db_unique_name = this_db_unique_name;
      IF (lname = name AND lvalue = value) THEN
        RETURN;
      END IF;
 
      deb('setConfig - lname=' || lname ||
          ', lvalue=' || maskConnectString(lvalue));
      RAISE;
    WHEN others THEN
      deb('setConfig - this_db_unique_name='||this_db_unique_name||
          ', conf#='||conf#);
      RAISE;
END;
 
--
--
FUNCTION setConfig3(name            IN VARCHAR2
                    ,value           IN VARCHAR2
                    ,db_unique_name  IN VARCHAR2) 
  RETURN NUMBER IS
  lname     conf.name%TYPE NOT NULL := name;
  lvalue    conf.value%TYPE NOT NULL := value;
  ldbuname  conf.db_unique_name%TYPE NOT NULL := upper(db_unique_name);
  lsite_key NUMBER;
  lconf_key NUMBER;
BEGIN
 
  IF (this_db_key IS NULL) THEN
    raise_application_error(-20021, 'Database not set');
  END IF;
 
  deb('setConfig3 - Remote setConfig for '||ldbuname);
 
  SELECT site_key into lsite_key from node 
         where node.db_unique_name = ldbuname AND
         node.db_key = this_db_key;
  deb('setConfig3 - remote_site_key='||lsite_key);
 
--
--
  INSERT INTO conf(db_key, conf#, name, value,  cleanup, db_unique_name,
                   site_key)
      VALUES(this_db_key, rman_seq.nextval, name, value, 'NO', ldbuname,
             lsite_key)
  RETURNING conf# INTO lconf_key;
 
  UPDATE node SET node.force_resync2cf = 'YES'
    WHERE node.db_key = this_db_key
      AND node.db_unique_name = ldbuname;
 
  commitChanges('setConfig3');
 
  deb('setConfig3 - Added name=(' || lname ||
      '), value=(' || maskConnectString(lvalue) ||
      ') to node ' || ldbuname ||
      '('|| lconf_key ||')');
 
  RETURN lconf_key;
 
EXCEPTION
  WHEN OTHERS THEN
    deb('setConfig3 - rollback all, release locks');
    ROLLBACK;
    RAISE;
END;
 
--
--
PROCEDURE deleteConfig3(conf#        IN NUMBER
                    ,db_unique_name  IN VARCHAR2) IS
BEGIN
  IF (this_db_key IS NULL) THEN
    raise_application_error(-20021, 'Database not set');
  END IF;
 
--
--
--
  DELETE conf
  WHERE  conf.db_key = this_db_key AND
         conf.db_unique_name = deleteConfig3.db_unique_name AND
         conf.conf# = deleteConfig3.conf#;
 
  IF sql%rowcount <> 1 AND sql%rowcount <> 0 THEN
     raise_application_error(-20999,
            'Internal error in deleteConfig3, deleted rows= ' || sql%rowcount);
  END IF;
 
  UPDATE node SET node.force_resync2cf = 'YES'
    WHERE node.db_key = this_db_key
      AND node.db_unique_name = deleteconfig3.db_unique_name;
 
  commitChanges('deleteConfig3');
EXCEPTION
  WHEN OTHERS THEN
    deb('deleteConfig3 - rollback all, release locks');
    ROLLBACK;
    RAISE;
END;
 
PROCEDURE resetConfig IS
BEGIN
  IF (this_db_key IS NULL) THEN
    raise_application_error(-20021, 'Database not set');
  END IF;
 
  DELETE conf
  WHERE  conf.db_key = this_db_key;
 
EXCEPTION
  WHEN NO_DATA_FOUND THEN
--
  RETURN;
END resetConfig;
 
PROCEDURE resetConfig2 (nodespec IN BOOLEAN, high_conf_recid IN NUMBER DEFAULT NULL) IS
BEGIN
  IF (this_db_key IS NULL) THEN
    raise_application_error(-20021, 'Database not set');
  END IF;
 
--
--
--
  DELETE conf
  WHERE  conf.db_key = this_db_key AND conf.cleanup = 'YES';
 
--
--
--
  IF (nodespec)
  THEN
    DELETE conf
    WHERE  conf.db_key = this_db_key AND
           conf.db_unique_name = this_db_unique_name;
  ELSE
 
--
--
--
    force_resync2cf := 'YES';
 
    DELETE conf
    WHERE  conf.db_key = this_db_key AND
           conf.db_unique_name IS NULL;
  END IF;
 
  IF high_conf_recid IS NOT NULL THEN
     last_conf_recid := high_conf_recid;
     deb('resetConfig2 - updated last_conf_recid=' || last_conf_recid);
  END IF;
 
EXCEPTION
  WHEN NO_DATA_FOUND THEN
--
  RETURN;
END resetConfig2;
 
PROCEDURE deleteConfig(conf#            IN NUMBER) IS
BEGIN
--
--
  raise_application_error(-20999,
         'Internal error in deleteConfig should not be called ');
END;
 
/*-------------------------*
 * Catalog upgrade support *
 *-------------------------*/
 
/* NOTES:
 *
 * These procedures *must* tolerate being called *before* dbinc_key
 * has been set.
 */
 
/*-------------------*
 * Utility functions *
 *-------------------*/
 
PROCEDURE bsStatusRecalc(status IN varchar2) IS
 
cursor bsQ(status varchar2) IS
  SELECT bs_key
  FROM bs
  WHERE bs.status = bsStatusRecalc.status
--
  AND bs.db_key = this_db_key;
 
bsQrec bsQ%ROWTYPE;
 
BEGIN
 
  IF this_is_ors AND this_ckp_key IS NULL THEN
     this_enable_populate_rsr := getValueFromConfig('_enable_populate_rsr_key');
  END IF;
 
  FOR bsQrec in bsQ(status) LOOP
    updateBackupSetRec(bsQrec.bs_key);
  END LOOP;
--
--
  IF this_is_ors AND this_ckp_key IS NULL THEN
     this_enable_populate_rsr := NULL;
     this_upstream_site_key := NULL;
  END IF;
 
END;
 
PROCEDURE reNormalize(newname IN varchar2, oldname OUT varchar2) IS
BEGIN
   IF newname IS NULL THEN -- initialize
      IF reNorm_dfatt_c%ISOPEN THEN
         CLOSE reNorm_dfatt_c;
      END IF;
      IF reNorm_orl_c%ISOPEN THEN
         CLOSE reNorm_orl_c;
      END IF;
      IF reNorm_al_c%ISOPEN THEN
         CLOSE reNorm_al_c;
      END IF;
      IF reNorm_bp_c%ISOPEN THEN
         CLOSE reNorm_bp_c;
      END IF;
      IF reNorm_ccf_c%ISOPEN THEN
         CLOSE reNorm_ccf_c;
      END IF;
      IF reNorm_cdf_c%ISOPEN THEN
         CLOSE reNorm_cdf_c;
      END IF;
      IF reNorm_tfatt_c%ISOPEN THEN
         CLOSE reNorm_tfatt_c;
      END IF;
 
      reNorm_state := RENORM_DFATT;
   ELSE -- update the previous row
      IF reNorm_state = RENORM_DFATT THEN
         UPDATE site_dfatt SET fname = newname WHERE CURRENT OF reNorm_dfatt_c;
      ELSIF reNorm_state = RENORM_ORL THEN
         UPDATE orl SET fname = newname WHERE CURRENT OF reNorm_orl_c;
      ELSIF reNorm_state = RENORM_AL THEN
         UPDATE al SET fname = newname,
           fname_hashkey = substr(newname,1,10) || substr(newname, -10)
           WHERE CURRENT OF reNorm_al_c;
      ELSIF reNorm_state = RENORM_BP THEN
         UPDATE bp SET handle = newname,
           handle_hashkey = substr(device_type,1,10) ||
                            substr(newname,1,10)     ||
                            substr(newname,-10)
           WHERE CURRENT OF reNorm_bp_c;
      ELSIF reNorm_state = RENORM_CCF THEN
         UPDATE ccf SET fname = newname,
           fname_hashkey = substr(newname,1,10) || substr(newname, -10)
           WHERE CURRENT OF reNorm_ccf_c;
      ELSIF reNorm_state = RENORM_CDF THEN
         UPDATE cdf SET fname = newname,
           fname_hashkey = substr(newname,1,10) || substr(newname, -10)
           WHERE CURRENT OF reNorm_cdf_c;
      ELSIF reNorm_state = RENORM_TFATT THEN
         UPDATE site_tfatt SET fname = newname WHERE CURRENT OF reNorm_tfatt_c;
      END IF;
   END IF;
 
   IF reNorm_state = RENORM_DFATT THEN
      IF NOT reNorm_dfatt_c%ISOPEN THEN
         OPEN reNorm_dfatt_c;
      END IF;
 
      FETCH reNorm_dfatt_c INTO oldname;
 
      IF reNorm_dfatt_c%NOTFOUND THEN
         CLOSE reNorm_dfatt_c;
         reNorm_state := RENORM_ORL;
      END IF;
   END IF;
 
   IF reNorm_state = RENORM_ORL THEN
      IF NOT reNorm_orl_c%ISOPEN THEN
         OPEN reNorm_orl_c;
      END IF;
 
      FETCH reNorm_orl_c INTO oldname;
 
      IF reNorm_orl_c%NOTFOUND THEN
         CLOSE reNorm_orl_c;
         reNorm_state := RENORM_AL;
      END IF;
   END IF;
 
   IF reNorm_state = RENORM_AL THEN
      IF NOT reNorm_al_c%ISOPEN THEN
         OPEN reNorm_al_c;
      END IF;
 
      FETCH reNorm_al_c INTO oldname;
 
      IF reNorm_al_c%NOTFOUND THEN
         CLOSE reNorm_al_c;
         reNorm_state := RENORM_BP;
      END IF;
   END IF;
 
   IF reNorm_state = RENORM_BP THEN
      IF NOT reNorm_bp_c%ISOPEN THEN
         OPEN reNorm_bp_c;
      END IF;
 
      FETCH reNorm_bp_c INTO oldname;
 
      IF reNorm_bp_c%NOTFOUND THEN
         CLOSE reNorm_bp_c;
         reNorm_state := RENORM_CCF;
      END IF;
   END IF;
 
   IF reNorm_state = RENORM_CCF THEN
      IF NOT reNorm_ccf_c%ISOPEN THEN
         OPEN reNorm_ccf_c;
      END IF;
 
      FETCH reNorm_ccf_c INTO oldname;
 
      IF reNorm_ccf_c%NOTFOUND THEN
         CLOSE reNorm_ccf_c;
         reNorm_state := RENORM_CDF;
      END IF;
   END IF;
 
   IF reNorm_state = RENORM_CDF THEN
      IF NOT reNorm_cdf_c%ISOPEN THEN
         OPEN reNorm_cdf_c;
      END IF;
 
      FETCH reNorm_cdf_c INTO oldname;
 
      IF reNorm_cdf_c%NOTFOUND THEN
         CLOSE reNorm_cdf_c;
         reNorm_state := RENORM_TFATT;
      END IF;
   END IF;
 
   IF reNorm_state = RENORM_TFATT THEN
      IF NOT reNorm_tfatt_c%ISOPEN THEN
         OPEN reNorm_tfatt_c;
      END IF;
 
      FETCH reNorm_tfatt_c INTO oldname;
 
      IF reNorm_tfatt_c%NOTFOUND THEN
         CLOSE reNorm_tfatt_c;
         reNorm_state := NULL;
         oldname := NULL;
         commitChanges('reNormalize');
      END IF;
   END IF;
END reNormalize;
 
 
 
 
--
--
--
 
--
PROCEDURE cleanupResyncedBS;
PROCEDURE cleanupCKP;
PROCEDURE cleanupRLH;
PROCEDURE cleanupRSR;
PROCEDURE cleanupBV;
PROCEDURE cleanupROUT;
PROCEDURE cleanupNRS;
PROCEDURE cleanupDO;
PROCEDURE sanityCheck IS
BEGIN
 
  cleanupResyncedBS;
  cleanupCKP;
  cleanupRLH;
  cleanupRSR;
  cleanupBV;
  cleanupROUT;
  cleanupNRS;
  cleanupDO;
 
END sanityCheck;
 
PROCEDURE cleanupDO IS
  start_time     DATE := sysdate;
BEGIN
 
--
   DELETE deleted_object 
      WHERE db_key = this_db_key
        AND create_time < start_time - 30;
 
   deb('cleanupDO - deleted ' || sql%rowcount || ' rows from deleted_object');
   deb('cleanupDO - took ' || ((sysdate - start_time) * 86400) || ' seconds');
 
END cleanupDO;
 
PROCEDURE cleanupResyncedBS IS
   cnt    number;
BEGIN
 
--
--
--
--
 
  deb('cleanupResyncedBS - cntbs='||cntbs);
 
  IF cntbs is NULL THEN
    raise_application_error(-20107, 'invalid bskey counter');
  END IF;
 
  FOR i IN 1 .. cntbs LOOP
    SELECT count(*) into cnt from bs where bs_key = updatebs(i);
    IF cnt > 0 THEN
      deb('cleanupResyncedBS - updating bs_key='||updatebs(i));
      updateBackupSetRec(updatebs(i));
    END IF;
  END LOOP;
 
  cntbs := 0;
 
END cleanupResyncedBS;
 
PROCEDURE cleanupCKP IS
  scn            NUMBER;
  seq            NUMBER;
  keep_ckp_key_1 NUMBER;
  keep_ckp_key_2 NUMBER;
  start_time     DATE := sysdate;
BEGIN
 
--
--
--
--
 
  IF (this_db_key IS NULL) THEN
    raise_application_error(-20021, 'Database not set');
  END IF;
 
  dbms_rcvman.getCheckpoint(scn, seq, keep_ckp_key_1, keep_ckp_key_2);
 
  deb('cleanupCKP - scn=' || scn);
  deb('cleanupCKP - seq=' || seq);
  deb('cleanupCKP - keep_ckp_key_1=' || keep_ckp_key_1);
  deb('cleanupCKP - keep_ckp_key_2=' || keep_ckp_key_2);
 
--
--
--
 
  delete from ckp where dbinc_key = this_dbinc_key and ckp_key in
    (select ckp_key1 from
     (select ckp_key ckp_key1 from ckp where dbinc_key = this_dbinc_key) ckp1,
     (select keep_ckp_key_1 ckp_key2 from dual union
      select keep_ckp_key_2 from dual union
      select nvl(max(ckp_key),0) from ckp where dbinc_key=this_dbinc_key union
      select start_ckp_key from tsatt where dbinc_key = this_dbinc_key union
      select nvl(end_ckp_key,0) from tsatt where dbinc_key = this_dbinc_key)
     ckp2
     where ckp_key1 = ckp_key2(+) and ckp_key2 is null) and
    site_key = this_site_key;
 
   deb('cleanupCKP - deleted ' || sql%rowcount || ' rows from ckp table');
   deb('cleanupCKP - took ' || ((sysdate - start_time) * 86400) || ' seconds');
 
END cleanupCKP;
 
PROCEDURE cleanupRLH IS
  oldscn         NUMBER;
  start_time     DATE := sysdate;
BEGIN
 
--
--
--
--
--
 
  IF (this_db_key IS NULL) THEN
    raise_application_error(-20021, 'Database not set');
  END IF;
 
  SELECT nvl(min(scn),power(2,64)-1)
    INTO oldscn
    FROM
        (
         SELECT min(brl.low_scn) scn
           FROM brl
          WHERE brl.dbinc_key = this_dbinc_key
         UNION
         SELECT min(al.low_scn)
           FROM al
          WHERE al.dbinc_key = this_dbinc_key
         UNION
         SELECT min(xal.low_scn)
           FROM xal
          WHERE xal.dbinc_key = this_dbinc_key
         UNION
         SELECT min(bdf.ckp_scn)
           FROM bdf
          WHERE bdf.dbinc_key = this_dbinc_key
         UNION
         SELECT min(cdf.ckp_scn)
           FROM cdf
          WHERE cdf.dbinc_key = this_dbinc_key
         UNION
         SELECT min(xdf.ckp_scn)
           FROM xdf
          WHERE xdf.dbinc_key = this_dbinc_key
         UNION
         SELECT min(bcf.ckp_scn)
           FROM bcf
          WHERE bcf.dbinc_key = this_dbinc_key
         UNION
         SELECT min(ccf.ckp_scn)
           FROM ccf
          WHERE ccf.dbinc_key = this_dbinc_key
         UNION
         SELECT min(xcf.ckp_scn)
           FROM xcf
          WHERE xcf.dbinc_key = this_dbinc_key
           );
 
  deb('cleanupRLH - scn='||oldscn);
 
  DELETE
    FROM rlh
   WHERE rlh.dbinc_key = this_dbinc_key
     AND low_scn < oldscn;
 
   deb('cleanupRLH - deleted ' || sql%rowcount || ' rows from rlh table');
   deb('cleanupRLH - took ' || ((sysdate - start_time) * 86400) || ' seconds');
 
END cleanupRLH;
 
PROCEDURE cleanupBV IS
  start_time DATE := sysdate;
BEGIN
 
--
--
--
 
   DELETE FROM bs
     WHERE db_key = this_db_key
       AND ((input_file_scan_only='YES' AND SYSDATE - completion_time >= 60)
            OR
            (nvl(input_file_scan_only,'NO')='NO' AND status='D'))
       AND NOT EXISTS (SELECT 1 FROM bp
                        WHERE bp.bs_key = bs.bs_key);
 
   deb('cleanupBV - deleted ' || sql%rowcount || ' rows from bs table');
   deb('cleanupBV - took ' || ((sysdate - start_time) * 86400) || ' seconds');
 
END cleanupBV;
 
FUNCTION getDbid RETURN NUMBER IS
  dbid   NUMBER;
BEGIN
  SELECT db.db_id
    INTO dbid
    FROM db
   WHERE db_key = this_db_key
     AND curr_dbinc_key = this_dbinc_key;
  RETURN dbid;
  EXCEPTION
     WHEN no_data_found THEN
        raise_application_error(-20001, 'Database not found');
END getDbid;
 
FUNCTION beginIncarnationResync(return_Recid in boolean DEFAULT FALSE)
RETURN NUMBER IS
local_kccdivts number;
BEGIN
  checkResync;
 
  IF return_Recid THEN
    IF (this_cf_type = 'CURRENT' OR
        (this_cf_type = 'STANDBY' AND this_db_unique_name is not null)) THEN
       SELECT high_ic_recid INTO last_ic_recid
       FROM node
       WHERE site_key = this_site_key;
    ELSE
       last_ic_recid := sessionWaterMarks.high_ic_recid;
    END IF;
 
    RETURN last_ic_recid;
  ELSE
    IF (this_cf_type = 'CURRENT' OR
        (this_cf_type = 'STANDBY' AND this_db_unique_name is not null)) THEN
       SELECT last_kccdivts INTO local_kccdivts
       FROM node
       WHERE site_key = this_site_key;
    ELSE
       local_kccdivts := 0;
    END IF;
 
    IF (local_kccdivts IS NULL) THEN
       local_kccdivts := 0;
    END IF;
    RETURN local_kccdivts;
  END IF;
 
END beginIncarnationResync;
 
 
--
--
--
 
FUNCTION checkIncarnation(reset_scn         IN NUMBER,
                          reset_time        IN DATE,
                          prior_reset_scn   IN NUMBER DEFAULT NULL,
                          prior_reset_time  IN DATE DEFAULT NULL,
                          db_name           IN VARCHAR2 DEFAULT 'UNKNOWN')
                        RETURN NUMBER IS
local             dbinc%rowtype;
prior_dbinc_key   number := NULL;
d_name            VARCHAR2(8);
 
BEGIN
 
  BEGIN
    SELECT dbinc_key, parent_dbinc_key, db_name
       INTO local.dbinc_key, local.parent_dbinc_key, local.db_name
    FROM dbinc
    WHERE dbinc.db_key = this_db_key
    AND   dbinc.reset_scn = checkIncarnation.reset_scn
    AND   dbinc.reset_time = checkIncarnation.reset_time;
  EXCEPTION
    WHEN no_data_found THEN
      local.dbinc_key := NULL;
      local.parent_dbinc_key := NULL;
      local.db_name := 'UNKNOWN';
  END;
 
  IF (local.parent_dbinc_key IS NULL AND
      checkIncarnation.prior_reset_scn IS NOT NULL) THEN
     BEGIN
        SELECT dbinc_key
           INTO prior_dbinc_key
        FROM dbinc
        WHERE dbinc.db_key = this_db_key
        AND   dbinc.reset_scn = checkIncarnation.prior_reset_scn
        AND   dbinc.reset_time = checkIncarnation.prior_reset_time;
     EXCEPTION
       WHEN no_data_found THEN
          prior_dbinc_key := NULL;
     END;
  END IF;
 
  IF (local.dbinc_key IS NOT NULL) THEN
--
    IF (local.parent_dbinc_key IS NULL AND
        prior_dbinc_key IS NOT NULL) THEN
      UPDATE dbinc SET parent_dbinc_key = prior_dbinc_key
      WHERE dbinc.dbinc_key = local.dbinc_key;
    END IF;
 
--
    IF (local.db_name != 'UNKNOWN' AND
        checkIncarnation.db_name != 'UNKNOWN') THEN
      UPDATE dbinc SET db_name = checkIncarnation.db_name
      WHERE dbinc.dbinc_key = local.dbinc_key;
    END IF;
 
    deb('checkIncarnation - returning ' || local.dbinc_key);
    RETURN local.dbinc_key;
  END IF;
 
  IF (this_lock_ors_inspect) THEN
--
--
    deb('checkincarnation:server_error for db_key='||this_db_key);
    EXECUTE IMMEDIATE 'BEGIN  dbms_ra_scheduler.log_error(
            p_component => ''INSPECT'',
            p_severity  => dbms_ra_scheduler.SEVERITY_WARNING,
            p_db_key => :1,
            p_keep_stack => TRUE,
            p_errno => dbms_ra_scheduler.E_NEW_INC_ERROR_NUM); END;'
            USING this_db_key ;
  END IF;
--
  BEGIN
--
    d_name := checkIncarnation.db_name;
    IF (d_name = 'UNKNOWN') THEN
       BEGIN
          SELECT db_name
             INTO d_name
          FROM db, dbinc
          WHERE dbinc.db_key = this_db_key
            AND db.curr_dbinc_key = dbinc.dbinc_key;
          EXCEPTION
             WHEN no_data_found THEN
                deb('database name not set');
                d_name := checkIncarnation.db_name;
       END;
    END IF;
    
    INSERT INTO dbinc
      (dbinc_key, db_key, db_name, reset_scn, reset_time, parent_dbinc_key)
    VALUES
      (rman_seq.nextval, this_db_key,
       upper(d_name), checkIncarnation.reset_scn,checkIncarnation.reset_time,
       prior_dbinc_key)
    RETURNING dbinc_key INTO local.dbinc_key;
  EXCEPTION
    WHEN dup_val_on_index THEN
      raise_application_error(-20009, 'Db incarnation already registered');
  END;
 
  inheritPdbInc(
     this_db_key, local.dbinc_key, reset_scn, prior_dbinc_key);
   deb('checkIncarnation - (2) returning ' || local.dbinc_key);
  RETURN local.dbinc_key;
END checkIncarnation;
 
PROCEDURE endIncarnationResync(high_kccdivts IN NUMBER,
                               high_ic_recid IN NUMBER DEFAULT 0) IS
BEGIN
 
--
--
  IF (last_ic_recid IS NOT NULL) THEN
    IF (this_cf_type = 'CURRENT' OR
        (this_cf_type = 'STANDBY' AND this_db_unique_name is not null)) THEN
--
       UPDATE node SET high_ic_recid = endIncarnationResync.high_ic_recid,
                       last_kccdivts = endIncarnationResync.high_kccdivts
              WHERE site_key = this_site_key;
    END IF;
    sessionWaterMarks.high_ic_recid := high_ic_recid;
    last_ic_recid := NULL;
  ELSE
    IF (this_cf_type = 'CURRENT' OR
        (this_cf_type = 'STANDBY' AND this_db_unique_name is not null)) THEN
       UPDATE node SET last_kccdivts = high_kccdivts
       WHERE site_key = this_site_key;
    END IF;
  END IF;
 
--
  recomputeDbincStatus(this_db_key, this_dbinc_key);
 
--
--
  IF NOT this_lock_ors_inspect THEN
   this_clr_ba_newinc_err := TRUE;
  END IF;
 
END endIncarnationResync;
 
/*--------------------------------*
 * Pluggable DB Incaration Resync *
 *--------------------------------*/
 
PROCEDURE fetchPic IS                   -- this is private to the pkg body
BEGIN
  FETCH picQ INTO picRec;               -- get next row
  IF picQ%NOTFOUND THEN
    picRec      := NULL;
    picRec.guid := NULL;                -- indicate end of fetch
    CLOSE picQ;
  ELSE
    deb('fetchPic - '||picRec.con_id||'('||to_char(picRec.con_id)||') '||
        to_char(picRec.pdbinc_key));
  END IF;
END fetchPic;
 
FUNCTION beginPluggableDbincResync RETURN NUMBER IS
BEGIN
  checkResync;
 
  IF (this_cf_type = 'CURRENT' OR
      (this_cf_type = 'STANDBY' AND this_db_unique_name is not null)) THEN
     SELECT high_pic_recid INTO last_pic_recid
     FROM node
     WHERE site_key = this_site_key;
  ELSE
     last_pic_recid := sessionWaterMarks.high_pic_recid;
  END IF;
 
  IF (picQ%ISOPEN) THEN
     CLOSE picQ;
  END IF;
 
  OPEN picQ;                          -- just open that cursor please
  fetchPic;                           -- do priming read
 
  RETURN last_pic_recid;
END beginPluggableDbincResync;
 
PROCEDURE checkPluggableDbinc(
  recid               IN NUMBER
 ,guid                IN RAW
 ,curr_pdbinc         IN VARCHAR2
 ,inc_scn             IN NUMBER
 ,begin_reset_scn     IN NUMBER
 ,begin_reset_time    IN DATE
 ,end_reset_scn       IN NUMBER
 ,db_reset_scn        IN NUMBER
 ,db_reset_time       IN DATE
 ,pr_inc_scn          IN NUMBER
 ,pr_end_reset_scn    IN NUMBER
 ,pr_db_reset_scn     IN NUMBER
 ,pr_db_reset_time    IN DATE
 ,chk_last_recid      IN BOOLEAN
) IS
   local_pdb_key       number;
   local_pdbinc_key    number;
   local_pr_pdbinc_key number;
   born_dbinc_key      number;
   pr_born_dbinc_key   number;
   pr_pdbinc_key       number;
BEGIN
  IF (chk_last_recid) THEN
     IF (last_pic_recid IS NULL) THEN
       raise_application_error(-20037, 'Invalid last recid');
     END IF;
 
--
--
--
--
     last_pic_recid := recid;
  END IF;
 
  IF (end_reset_scn = 0) THEN
     deb('checkPluggableDbinc - skipping partial record');
     RETURN;
  END IF;
 
--
  WHILE (guid > picRec.guid)
  LOOP
    fetchPic;
  END LOOP;
 
--
  WHILE (guid = picRec.guid  AND
         (begin_reset_scn  > picRec.begin_reset_scn   OR
          begin_reset_time > picRec.begin_reset_time  OR
          end_reset_scn    > picRec.end_reset_scn))
  LOOP
     fetchPic;
  END LOOP;
 
--
  IF (guid             = picRec.guid             AND
      begin_reset_scn  = picRec.begin_reset_scn  AND
      begin_reset_time = picRec.begin_reset_time AND 
      end_reset_scn    = picRec.end_reset_scn) THEN
 
     deb('checkPluggableDbinc - pdbinc already known');
 
--
     local_pdb_key       := picRec.pdb_key;
     local_pdbinc_key    := picRec.pdbinc_key;
     local_pr_pdbinc_key := picRec.parent_pdbinc_key;
  END IF;
 
  IF (local_pr_pdbinc_key IS NULL) THEN
--
     IF (local_pdb_key IS NULL) THEN
        local_pdb_key := guidToPdbKey(checkPluggableDbinc.guid, 0);
        deb('checkPluggableDbinc - pdb_key=' || local_pdb_key);
     END IF;
 
     IF (pr_db_reset_scn = 0 OR pr_end_reset_scn = 0) THEN
        pr_pdbinc_key := NULL;
        deb('checkPluggableDbinc - no parent_pdbinc_key');
     ELSE
--
        pr_born_dbinc_key :=
           checkIncarnation(pr_db_reset_scn, pr_db_reset_time);
        deb('checkPluggableDbinc - pr_born_dbinc_key=' || pr_born_dbinc_key);
 
        BEGIN
           SELECT pdbinc_key
             INTO pr_pdbinc_key
             FROM pdbinc
            WHERE pdbinc.born_dbinc_key = pr_born_dbinc_key
              AND pdbinc.pdb_key        = local_pdb_key
              AND pdbinc.end_reset_scn  = pr_end_reset_scn;
        EXCEPTION
           WHEN no_data_found THEN
              pr_pdbinc_key := NULL;
        END;
 
        deb('checkPluggableDbinc - parent_pdbinc_key=' || pr_pdbinc_key);
     END IF;
  END IF;
 
  IF (local_pdbinc_key IS NULL) THEN
     born_dbinc_key := checkIncarnation(db_reset_scn, db_reset_time);
     deb('checkPluggableDbinc - born_dbinc_key=' || born_dbinc_key);
 
--
     INSERT INTO pdbinc
       (pdbinc_key, pdb_key, born_dbinc_key, inc_scn, begin_reset_scn,
        begin_reset_time, end_reset_scn, parent_pdbinc_key)
     VALUES
       (rman_seq.nextval, local_pdb_key, born_dbinc_key, inc_scn,
        begin_reset_scn, begin_reset_time, end_reset_scn, pr_pdbinc_key)
     RETURNING pdbinc_key INTO local_pdbinc_key;
  ELSE
     IF (local_pr_pdbinc_key IS NULL AND pr_pdbinc_key IS NOT NULL) THEN
        UPDATE pdbinc SET parent_pdbinc_key = pr_pdbinc_key
         WHERE pdbinc_key = local_pdbinc_key;
     END IF;
  END IF;
 
  IF (curr_pdbinc = 'YES') THEN
     UPDATE pdb_dbinc
        SET curr_pdbinc_key = local_pdbinc_key,
            drop_scn = NULL
      WHERE dbinc_key = this_dbinc_key
        AND pdb_key   = local_pdb_key;
 
     IF (sql%rowcount = 0) THEN 
        INSERT INTO pdb_dbinc
           (dbinc_key, pdb_key, drop_scn, drop_time, curr_pdbinc_key)
        VALUES
           (this_dbinc_key, local_pdb_key, NULL, NULL, local_pdbinc_key);
     END IF;
  END IF;
END checkPluggableDbinc;
 
PROCEDURE endPluggableDbincResync(high_pic_recid IN NUMBER) IS
BEGIN
  IF (last_pic_recid IS NOT NULL) THEN
     IF (this_cf_type = 'CURRENT' OR
         (this_cf_type = 'STANDBY' AND this_db_unique_name is not null)) THEN
        UPDATE node SET high_pic_recid = endPluggableDbincResync.high_pic_recid
        WHERE site_key = this_site_key;
     END IF;
 
     sessionWaterMarks.high_pic_recid := high_pic_recid;
     last_pic_recid := NULL;
  END IF;
 
--
  recomputePluggableDbincStatus(this_dbinc_key);
 
  IF (picQ%ISOPEN) THEN
     picRec.guid := NULL;         -- indicate end of fetch
     CLOSE picQ;
  END IF;
END endPluggableDbincResync;
 
/*-----------------------------*
 * Normal restore point Resync *
 *-----------------------------*/
 
FUNCTION beginRestorePointResync RETURN NUMBER IS
BEGIN
  checkResync;
 
  IF (this_cf_type = 'CURRENT' OR
      (this_cf_type = 'STANDBY' AND this_db_unique_name is not null)) THEN
     SELECT high_nrsp_recid INTO last_nrsp_recid
     FROM node
     WHERE site_key = this_site_key;
  ELSE
     last_nrsp_recid := sessionWaterMarks.high_nrsp_recid;
  END IF;
 
  RETURN last_nrsp_recid;
END beginRestorePointResync;
 
PROCEDURE checkRestorePoint(
  nrsp_recid    IN NUMBER
 ,nrsp_stamp    IN NUMBER
 ,nrsp_name     IN VARCHAR2
 ,reset_scn     IN NUMBER
 ,reset_time    IN DATE
 ,to_scn        IN NUMBER
 ,nrsp_time     IN DATE
 ,create_time   IN DATE
 ,deleted       IN NUMBER
 ,con_id        IN NUMBER   DEFAULT NULL
 ,clean         IN VARCHAR2 DEFAULT 'NO'
) IS
   my_dbinc_key  NUMBER;
   inscheck      NUMBER;
   local_pdb_key NUMBER;
BEGIN
  IF (last_nrsp_recid IS NULL) THEN
    raise_application_error(-20037, 'Invalid last recid');
  END IF;
 
  IF (nrsp_recid < last_nrsp_recid) THEN
    raise_application_error(-20036, 'Invalid record order');
  END IF;
 
  IF (nrsp_recid > last_nrsp_recid + 1) THEN
--
--
    NULL;
  END IF;
  last_nrsp_recid := nrsp_recid;
 
  IF (this_dbinc_key IS NULL) THEN
    raise_application_error(-20020, 'Database incarnation not set');
  END IF;
 
  IF (nrsp_stamp > 0 and nrsp_stamp < kccdivts) THEN
     deb('checkRestorePoint - ignoring record kccdivts='||kccdivts);
     RETURN;                    -- obsolete record from a backup controlfile
  END IF;
 
--
  my_dbinc_key := checkIncarnation(reset_scn, reset_time);
 
--
--
  deb('checkRestorePoint - con_id=' || con_id || ',deleted=' || deleted);
  SELECT pdb.pdb_key INTO local_pdb_key
    FROM pdb, pdb_dbinc
   WHERE pdb_dbinc.drop_scn IS NULL
     AND pdb.con_id  IN
         (checkRestorePoint.con_id,
          0, 
          decode(nvl(checkRestorePoint.con_id, 0), 0, 1))
     AND pdb.pdb_key         = pdb_dbinc.pdb_key
     AND pdb_dbinc.dbinc_key = my_dbinc_key;
  deb('checkRestorePoint - local_pdb_key=' || local_pdb_key);
 
--
  IF (deleted = 1)
  THEN
    DELETE nrsp
    WHERE checkRestorePoint.nrsp_recid = nrsp_recid
      AND checkRestorePoint.nrsp_stamp = nrsp_stamp
      AND my_dbinc_key = nrsp.dbinc_key
      AND this_site_key = site_key;
  ELSE
--
--
    DELETE nrsp
    WHERE this_site_key = nrsp.site_key
      AND local_pdb_key = nrsp.pdb_key
      AND checkRestorePoint.nrsp_name = nrsp.rspname;
 
    IF SQL%ROWCOUNT > 0 THEN
       deb('checkRestorePoint:deleted duplicate restore point:' 
           || checkRestorePoint.nrsp_name);
    END IF;
 
    INSERT INTO nrsp
        (nrsp_recid
        ,nrsp_stamp
        ,rspname
        ,dbinc_key
        ,site_key
        ,to_scn
        ,rsptime
        ,creation_time
        ,long_term
        ,pdb_key
        ,clean)
    VALUES
        (checkRestorePoint.nrsp_recid
        ,checkRestorePoint.nrsp_stamp
        ,checkRestorePoint.nrsp_name
        ,my_dbinc_key
        ,this_site_key
        ,checkRestorePoint.to_scn
        ,checkRestorePoint.nrsp_time
        ,checkRestorePoint.create_time
        ,NULL   -- UNKNOWN: cleanupNRS will reset to YES/NO
        ,local_pdb_key
        ,clean);
  END IF;
 
  EXCEPTION
      WHEN dup_val_on_index THEN
        deb('checkRestorePoint - Inside dup_val_on_index exception for' ||
            ' recid ' || checkRestorePoint.nrsp_recid ||
            ' stamp ' || checkRestorePoint.nrsp_stamp);
        SELECT min(nrsp.nrsp_recid) INTO inscheck
        FROM nrsp
        WHERE nrsp.nrsp_recid = checkRestorePoint.nrsp_recid
          AND nrsp.nrsp_stamp = checkRestorePoint.nrsp_stamp
          AND nrsp.dbinc_key = my_dbinc_key
          AND nrsp.site_key = this_site_key
          AND nrsp.rspname = checkRestorePoint.nrsp_name
          AND nrsp.to_scn = checkRestorePoint.to_scn
          AND nrsp.pdb_key = local_pdb_key;
        IF inscheck IS NULL THEN -- Some internal error to indicate no match
          raise_application_error(-20999,
                              'internal error: no match for restore point');
        END IF;
        RETURN;
      WHEN others THEN
         RAISE;
END checkRestorePoint;
 
PROCEDURE endRestorePointResync(lowrecid IN number) IS
   lowscn number;
BEGIN
--
  IF (lowrecid = 0)
  THEN
    low_nrsp_recid := NULL;
  ELSE
    low_nrsp_recid := lowrecid;
  END IF;
 
--
  IF (this_cf_type = 'CURRENT' OR
      (this_cf_type = 'STANDBY' AND this_db_unique_name is not null)) THEN
     UPDATE node SET high_nrsp_recid = last_nrsp_recid
     WHERE site_key = this_site_key;
  END IF;
 
  sessionWaterMarks.high_nrsp_recid := last_nrsp_recid;
  last_nrsp_recid := NULL;
END endRestorePointResync;
 
 
PROCEDURE listScriptNames(glob IN number,
                          allnames IN number) IS
   lglob number  := NULL;
   lalln number  := NULL;
BEGIN
    deb('listScriptNames - List script Names called with glob: '||
        nvl(to_char(glob), 'NULL')||'and allnames: '||
        nvl(to_char(allnames), 'NULL'));
    IF glob = 1 then
       lglob := 1;
    END IF;
    IF allnames = 1 then
       lalln := 1;
    END IF;
    IF lscrnames_c%ISOPEN THEN
       deb('listScriptNames - Closing lscrnames_c cursor');
       CLOSE lscrnames_c;
    END IF;
    deb('listScriptNames - Opening lscrnames_c cursor');
    OPEN lscrnames_c(lglob, lalln);
END listScriptNames;
 
PROCEDURE getScriptNames(dbname  OUT varchar2,
                         scnm    OUT varchar2,
                         sccom   OUT varchar2) IS
   ldum  number  := NULL;
BEGIN
   IF NOT lscrnames_c%ISOPEN THEN
      raise_application_error(-20403, 'listScriptNames not done');
   END IF;
 
    deb('getScriptNames - Fetching lscrnames_c cursor');
   FETCH lscrnames_c
   INTO  ldum, dbname, scnm, sccom;
 
   IF lscrnames_c%NOTFOUND THEN
      deb('getScriptNames - Closing lscrnames_c cursor');
      CLOSE lscrnames_c;
      raise no_data_found;
   END IF;
END getScriptNames;
 
--
--
PROCEDURE cleanupRSR IS
  nowTime date;
BEGIN
 
  SELECT SYSDATE INTO nowTime from dual;
 
  IF (this_dbinc_key IS NULL) THEN
    raise_application_error(-20020, 'Database incarnation not set');
  END IF;
 
--
--
--
--
 
  DELETE FROM rsr
        WHERE rsr_end < nowTime-60 
          AND rsr.dbinc_key IN 
              (select dbinc_key from dbinc 
               where dbinc.db_key = this_db_key);
 
   deb('cleanupRSR - deleted ' || sql%rowcount || ' rows from rsr table');
   deb('cleanupRSR - took ' || ((sysdate - nowTime) * 86400) || ' seconds');
 
END cleanupRSR;
 
--
--
PROCEDURE cleanupROUT IS
  start_time       date;
  high_stamp       number;
  high_session_key number;
  days             number;
BEGIN
  IF (this_db_key IS NULL) THEN
    raise_application_error(-20021, 'Database not set');
  END IF;
 
  IF session_keep_output IS NULL THEN 
     getRmanOutputLogging(days);
     deb('cleanupROUT - keep output is configured to ' || days);
  ELSIF session_keep_output = 0 THEN
     deb('cleanupROUT - session keep output is set to 0, not cleaning up');
     return;
  ELSE
     days := session_keep_output;
     deb('cleanupROUT - session keep output is set to ' || days);
  END IF;
 
  start_time      := SYSDATE;
  high_stamp      := date2stamp(start_time-days);
 
  SELECT max(rsr_key) into high_session_key
    FROM rsr, dbinc
   WHERE dbinc.db_key = this_db_key
     AND rsr.dbinc_key = dbinc.dbinc_key
     AND rsr.site_key = this_site_key
     AND rsr.rsr_stamp < high_stamp;
 
  deb('cleanupROUT select took ' || ((sysdate - start_time) * 86400) ||
      ' seconds');
 
--
  If high_session_key IS NOT NULL THEN
     DELETE FROM rout
     WHERE  db_key     = this_db_key
       AND  (site_key IS NULL) or (site_key  = this_site_key)
       AND  rout_skey <= high_session_key;
     deb('cleanupROUT deleted ' || sql%rowcount || ' rows from rout table');
  END IF;
 
  deb('cleanupROUT took ' || ((sysdate - start_time) * 86400) || ' seconds');
 
END cleanupROUT;
 
--
PROCEDURE cleanupNRS IS
  start_time       date;
BEGIN
  deb('cleanupNRS - low_nrsp_recid is ' ||
      NVL(TO_CHAR(low_nrsp_recid), 'NULL'));
  start_time := SYSDATE;
 
--
--
--
--
--
--
--
--
--
--
--
--
  UPDATE nrsp SET LONG_TERM = 'YES'
  WHERE long_term IS NULL
   AND this_site_key = site_key
   AND nrsp_recid in
   (SELECT nrsp.nrsp_recid
    FROM bs, brl, nrsp
    WHERE bs.bs_key = brl.bs_key
      AND bs.keep_options > 0
      AND brl.low_scn <= nrsp.to_scn
      AND brl.next_scn > nrsp.to_scn
      AND this_site_key = bs.site_key
      AND this_site_key = nrsp.site_key
   UNION
    SELECT nrsp.nrsp_recid
    FROM xal, nrsp
    WHERE xal.keep_options > 0
      AND xal.low_scn <= nrsp.to_scn
      AND xal.next_scn > nrsp.to_scn
      AND this_site_key = xal.site_key
      AND this_site_key = nrsp.site_key
   UNION
    SELECT nrsp_recid
    FROM bs, bdf, nrsp
    WHERE bs.bs_key = bdf.bs_key
      AND bs.keep_options > 0
      AND bdf.ckp_scn = nrsp.to_scn+1
      AND this_site_key = bs.site_key
      AND this_site_key = nrsp.site_key
   UNION
    SELECT nrsp_recid
    FROM xdf, nrsp
    WHERE xdf.keep_options > 0
      AND xdf.ckp_scn = nrsp.to_scn+1
      AND this_site_key = xdf.site_key
      AND this_site_key = nrsp.site_key);
  deb('cleanupNRS - updated ' || sql%rowcount || ' rows to LONG_TERM = YES');
 
--
  UPDATE nrsp SET LONG_TERM = 'NO'
  WHERE long_term IS NULL
   AND this_site_key = site_key;
  deb('cleanupNRS - updated ' || sql%rowcount || ' rows to LONG_TERM = NO');
 
--
--
  DELETE nrsp WHERE nrsp_recid < low_nrsp_recid
                AND long_term = 'NO'
                AND site_key = this_site_key;
  low_nrsp_recid := NULL;
  deb('cleanupNRS - deleted ' || sql%rowcount || ' rows from nrsp table');
  deb('cleanupNRS - took ' || ((sysdate - start_time) * 86400) || ' seconds');
END;
 
PROCEDURE updateOldestFlashbackSCN (
   oldest_flashback_scn     IN NUMBER -- obsolete column
  ,oldest_flashback_time    IN DATE   DEFAULT NULL
) IS
  tmp    NUMBER;
BEGIN
 
   deb('updateOldestFlashbackSCN - guaranteed_flashback_scn=' ||
       nvl(to_char(oldest_flashback_scn), 'NULL') || ' flashback_time=' ||
       nvl(to_char(oldest_flashback_time), 'NULL'));
 
--
   IF (oldest_flashback_scn IS NULL AND oldest_flashback_time IS NULL) THEN
      DELETE FROM fb
       WHERE db_unique_name = this_db_unique_name
         AND dbinc_key      = this_dbinc_key;
      RETURN;
   END IF;
 
   BEGIN
      SELECT 0 INTO tmp
        FROM fb
       WHERE db_unique_name = this_db_unique_name
         AND dbinc_key      = this_dbinc_key;
   EXCEPTION
      WHEN no_data_found THEN
         INSERT INTO fb
            (dbinc_key, db_unique_name, oldest_flashback_scn,
             oldest_flashback_time)
         VALUES
            (this_dbinc_key, this_db_unique_name, oldest_flashback_scn,
             oldest_flashback_time);
         RETURN;
      WHEN others THEN
         RAISE;
   END;
 
   UPDATE fb SET
     oldest_flashback_scn =
        updateOldestFlashbackSCN.oldest_flashback_scn,
     oldest_flashback_time =
        updateOldestFlashbackSCN.oldest_flashback_time
   WHERE db_unique_name = this_db_unique_name
     AND dbinc_key      = this_dbinc_key;
END updateOldestFlashbackSCN;
 
FUNCTION getDbinc RETURN NUMBER IS
BEGIN
  IF (this_dbinc_key IS NULL) THEN
    raise_application_error(-20020, 'Database incarnation not set');
  END IF;
 
  RETURN this_dbinc_key;
END getDbinc;
 
--
--
--
FUNCTION isDuplicateRecord(recid    IN NUMBER
                          ,stamp    IN NUMBER
                          ,type     IN VARCHAR2) RETURN BOOLEAN IS
  rec_count NUMBER;
BEGIN
   checkResync;
 
   IF (type = 'AL') THEN
      SELECT count(*)
        INTO rec_count
        FROM al, dbinc
       WHERE dbinc.db_key = this_db_key
         AND al.dbinc_key = dbinc.dbinc_key
         AND isDuplicateRecord.recid = al.al_recid
         AND isDuplicateRecord.stamp = al.al_stamp
         AND al.site_key = this_site_key;
   ELSIF (type = 'BP') THEN
      SELECT count(*)
        INTO rec_count
        FROM bp
       WHERE bp.db_key = this_db_key
         AND isDuplicateRecord.recid = bp.bp_recid
         AND isDuplicateRecord.stamp = bp.bp_stamp
         AND bp.site_key = this_site_key;
   ELSIF (type = 'DC') THEN
      SELECT count(*)
        INTO rec_count 
        FROM cdf, dbinc
       WHERE dbinc.db_key = this_db_key
         AND cdf.dbinc_key = dbinc.dbinc_key
         AND isDuplicateRecord.recid = cdf.cdf_recid
         AND isDuplicateRecord.stamp = cdf.cdf_stamp
         AND cdf.site_key = this_site_key;
 
      IF (rec_count = 0) THEN
         SELECT count(*)
           INTO rec_count 
           FROM ccf, dbinc
          WHERE dbinc.db_key = this_db_key
            AND ccf.dbinc_key = dbinc.dbinc_key
            AND isDuplicateRecord.recid = ccf.ccf_recid
            AND isDuplicateRecord.stamp = ccf.ccf_stamp
            AND ccf.site_key = this_site_key;
      END IF;
   ELSE
      raise_application_error(-20999,
         'Internal error in isDuplicateRecord(): bad type '|| type);
   END IF;
 
   IF rec_count > 0 THEN
      RETURN TRUE;
   ELSE
      RETURN FALSE;
   END IF;
END isDuplicateRecord;
 
--
--
--
--
--
--
FUNCTION doDuplicateMining RETURN BOOLEAN IS
  last_recid number;
BEGIN
  checkResync;
 
  IF (this_cf_type != 'CURRENT' and this_cf_type != 'STANDBY') THEN
     RETURN TRUE;
  END IF;
 
--
--
  IF (this_cf_type = 'STANDBY' and this_db_unique_name is NULL) THEN
     RETURN TRUE;
  END IF;
 
--
--
--
  SELECT high_rlh_recid INTO last_recid
     FROM node
     WHERE site_key = this_site_key;
 
  IF (last_recid = 0) THEN
     deb('doDuplicateMining returns TRUE');
     RETURN TRUE;
  ELSE
     RETURN FALSE;
  END IF;
 
END doDuplicateMining;
 
--
FUNCTION isRoutDuplicateRecord(recid             IN NUMBER
                              ,stamp             IN NUMBER
                              ,session_recid     IN NUMBER
                              ,session_stamp     IN NUMBER
                              ,rman_status_recid IN NUMBER
                              ,rman_status_stamp IN NUMBER)
 
  RETURN BOOLEAN IS
  lrsrkey    NUMBER;
  lroutskey  NUMBER;
  rec_count  NUMBER;
BEGIN
   checkResync;
 
    deb('isRoutDuplicateRecord - Find rsr_ key');
    BEGIN
      select rsr_key into lrsrkey from rsr, dbinc where 
             rsr.dbinc_key = dbinc.dbinc_key and
             dbinc.db_key  = this_db_key and
             dbinc.dbinc_key = this_dbinc_key and
             ((rsr.site_key = this_site_key) or
              (rsr.site_key is null AND this_site_key is null)) and
             rsr.rsr_recid = rman_status_recid and
             rsr.rsr_stamp = rman_status_stamp;
    EXCEPTION
    WHEN no_data_found THEN
--
      deb('isRoutDuplicateRecord - ignoring following RMAN output row');
      RETURN FALSE;
    END;
 
 
    deb('isRoutDuplicateRecord - Find session key');
    BEGIN
--
--
--
--
--
      select rsr_key into lroutskey from rsr, dbinc where
             rsr.dbinc_key  = dbinc.dbinc_key and
             dbinc.db_key   = this_db_key and
             (rsr.site_key = this_site_key or
              rsr.site_key is null AND this_site_key is null) and
             rsr.rsr_srecid = session_recid and
             rsr.rsr_sstamp = session_stamp and
             rsr.rsr_type   = 'SESSION';
    EXCEPTION
    WHEN no_data_found THEN
--
      deb('isRoutDuplicateRecord -ignoring following RMAN output row, cause2');
      RETURN FALSE;
    WHEN others THEN
      deb('isRoutDuplicateRecord(DO_NOT_IGNORE) - signal err');
      RETURN FALSE;
    END;
 
--
   SELECT count(*)
     INTO rec_count
     FROM rout, db
    WHERE db.db_key = this_db_key
      AND rout.rout_recid = isRoutDuplicateRecord.recid
      AND rout.rout_stamp = isRoutDuplicateRecord.stamp
      AND rout.rsr_key    = lrsrkey
      AND rout.rout_skey  = lroutskey
      AND rout.site_key = this_site_key;
 
   IF rec_count > 0 THEN
    deb('isRoutDuplicateRecord - Return TRUE');
      RETURN TRUE;
   ELSE
    deb('isRoutDuplicateRecord - Return FALSE');
      RETURN FALSE;
   END IF;
END isRoutDuplicateRecord;
 
PROCEDURE unregisterSite(db_unique_name IN VARCHAR2,
                         incbcks        IN BINARY_INTEGER ) IS
 
  lsite_key        number;
  new_ckp_site_key number;
  cnt              number := 0;
  db_role          node.database_role%TYPE;
 
BEGIN
 
   deb('unregisterSite - remove meta-data for node '|| db_unique_name);
 
   IF (this_db_key IS NULL) THEN
      raise_application_error(-20021, 'Database not set');
   END IF;
 
--
   IF this_db_unique_name = upper(db_unique_name) THEN
      raise_application_error(-20244,
                              db_unique_name || 
                              ' can not unregister connected target database');
   END IF;
 
--
   BEGIN
      select site_key, database_role into lsite_key, db_role from node 
         where node.db_unique_name = upper(unregisterSite.db_unique_name)
           and node.db_key = this_db_key;
 
   EXCEPTION
      WHEN no_data_found THEN
         raise_application_error(
                             -20243,
                             upper(unregisterSite.db_unique_name) || 
                             ' db_unique_name unknown to recovery catalog:');
   END;
   lockForCkpt;
 
--
--
   select count(*) into cnt from bp
      where bp.site_key = lsite_key and bp.ba_access != 'U';
 
   IF (cnt <> 0) THEN
     cancelCkpt;
     raise_application_error(-20301, 'Cannot unregister database');
   END IF;
  
--
--
--
--
   select site_key into new_ckp_site_key from 
      (select site_key from node
         where db_key=this_db_key
           and site_key <> lsite_key
         order by database_role)
      where rownum = 1;
   IF new_ckp_site_key is not null THEN
      update ckp set site_key = new_ckp_site_key 
         where site_key = lsite_key
           and ckp_type = 'FULL'
           and ckp_key in
               (select start_ckp_key from tsatt 
                  where dbinc_key in 
                     (select dbinc_key from dbinc
                         where db_key=this_db_key)
                union
                select end_ckp_key from tsatt 
                  where dbinc_key in 
                     (select dbinc_key from dbinc
                         where db_key=this_db_key));
      deb('updated ' || sql%rowcount || ' rows in ckp, site_key to ' || 
          new_ckp_site_key);
   END IF;
 
--
   IF incbcks <> 0 THEN
      delete bp WHERE site_key = lsite_key;
      deb('deleted ' || sql%rowcount || ' rows from bp table');
      delete bs WHERE site_key = lsite_key;
      deb('deleted ' || sql%rowcount || ' rows from bs table');
      delete ccf WHERE site_key = lsite_key;
      deb('deleted ' || sql%rowcount || ' rows from ccf table');
      delete xcf WHERE site_key = lsite_key;
      deb('deleted ' || sql%rowcount || ' rows from xcf table');
      delete cdf WHERE site_key = lsite_key;
      deb('deleted ' || sql%rowcount || ' rows from cdf table');
      delete xdf WHERE site_key = lsite_key;
      deb('deleted ' || sql%rowcount || ' rows from xdf table');
      delete xal WHERE site_key = lsite_key;
      deb('deleted ' || sql%rowcount || ' rows from xal table');
   ELSE
      update bp set site_key = NULL WHERE site_key = lsite_key;
      deb('updated ' || sql%rowcount || ' rows from bp table');
      update bs set site_key = NULL WHERE site_key = lsite_key;
      deb('updated ' || sql%rowcount || ' rows from bs table');
      update ccf set site_key = NULL WHERE site_key = lsite_key;
      deb('updated ' || sql%rowcount || ' rows from ccf table');
      update xcf set site_key = NULL WHERE site_key = lsite_key;
      deb('updated ' || sql%rowcount || ' rows from xcf table');
      update cdf set site_key = NULL WHERE site_key = lsite_key;
      deb('updated ' || sql%rowcount || ' rows from cdf table');
      update xdf set site_key = NULL WHERE site_key = lsite_key;
      deb('updated ' || sql%rowcount || ' rows from xdf table');
      update xal set site_key = NULL WHERE site_key = lsite_key;
      deb('updated ' || sql%rowcount || ' rows from xal table');
   END IF;
 
--
   delete node where site_key = lsite_key;
   deb('deleted ' || sql%rowcount || ' rows from node table');
   delete fb
      where db_unique_name = unregisterSite.db_unique_name 
        and dbinc_key in 
            (select dbinc_key from dbinc where db_key = this_db_key);
   deb('deleted ' || sql%rowcount || ' rows from fb table');
 
  UPDATE db
    SET reg_db_unique_name =
      (SELECT max(db_unique_name) FROM
         (SELECT db_unique_name 
          FROM node, db
          WHERE node.db_key = this_db_key
            AND node.db_unique_name <> unRegisterSite.db_unique_name
            AND node.db_unique_name <> db.reg_db_unique_name
            AND node.db_unique_name NOT LIKE '%$%'
            AND node.database_role IN ('PRIMARY','STANDBY')
          ORDER BY node.database_role, node.db_unique_name)
          WHERE ROWNUM =1)
	WHERE db_key = this_db_key
	  AND reg_db_unique_name = unregisterSite.db_unique_name;
 
--
--
--
   delete conf 
     where name = 'DB_UNIQUE_NAME' 
       and db_key = this_db_key 
       and upper(unregisterSite.db_unique_name) =
           upper(substr(value, 2, instr(substr(value, 2, 32), 
                                               substr(value, 1,1))-1))
       and db_unique_name is null;
   deb('deleted ' || sql%rowcount || ' rows from conf table(2)');
 
--
--
   if sql%rowcount <> 0 then
      update node set force_resync2cf = 'YES'
         where db_key = this_db_key;
   end if;
 
--
   delete conf where site_key = lsite_key;
   deb('deleted ' || sql%rowcount || ' rows from conf table (site rows)');
   commitChanges('unregisterSite');
 
END unregisterSite;
 
--
PROCEDURE renameSite(from_db_unique_name IN VARCHAR2, 
                     to_db_unique_name IN VARCHAR2) IS
   rec_count NUMBER;
   my_dbinc_key NUMBER;
BEGIN
   deb('renameSite - rename meta-data from '|| from_db_unique_name ||
       ' to ' || to_db_unique_name);
 
--
   IF this_db_key IS NULL THEN
      BEGIN
         SELECT curr_dbinc_key into my_dbinc_key FROM db
         WHERE db_key = (SELECT db_key FROM node where
                            db_unique_name = upper(from_db_unique_name));
         setDatabase(my_dbinc_key);
      EXCEPTION
         WHEN no_data_found THEN
            raise_application_error(-20243,
                                    from_db_unique_name || 
                                    ' site unknown to recovery catalog:');
      END;
   END IF;
 
   IF (this_db_key IS NULL) THEN
      raise_application_error(-20021, 'Database not set');
   END IF;
 
--
   IF this_db_unique_name = upper(from_db_unique_name) THEN
      raise_application_error(-20244,
                              from_db_unique_name || 
                              ' can not rename connected target database');
   END IF;
 
--
   SELECT count(*) INTO rec_count FROM node 
      WHERE node.db_unique_name = upper(from_db_unique_name) 
        AND node.db_key = this_db_key;
 
   IF rec_count = 0 THEN
      raise_application_error(-20243,
                              from_db_unique_name || 
                              ' site unknown to recovery catalog:');
   END IF;
 
--
   SELECT count(*) INTO rec_count FROM node 
      WHERE node.db_unique_name = upper(to_db_unique_name) 
        AND node.db_key = this_db_key;
 
   IF rec_count = 1 THEN
      raise_application_error(-20246,
                              to_db_unique_name || 
                              ' site known to recovery catalog:');
   END IF;
 
   UPDATE NODE SET db_unique_name = upper(to_db_unique_name)
      WHERE db_unique_name = upper(from_db_unique_name)
        AND db_key = this_db_key;
   deb('renamed db_unique_name ' || sql%rowcount || ' row updated');
 
   UPDATE CONF SET db_unique_name = upper(to_db_unique_name)
      WHERE db_unique_name = upper(from_db_unique_name)
        AND db_key = this_db_key;
   deb('updated ' || sql%rowcount || ' rows in conf table');
 
--
   UPDATE FB SET db_unique_name = upper(to_db_unique_name)
      WHERE db_unique_name = upper(from_db_unique_name)
        AND dbinc_key IN 
            (select dbinc_key from dbinc where db_key = this_db_key);
   deb('updated ' || sql%rowcount || ' rows in fb table');
 
   commitChanges('renameSite');
 
END renameSite;
 
--
--
 
PROCEDURE resyncAddDBUname(cdbunstr IN varchar2) IS
     dbuname    node.db_unique_name%TYPE;
     numentries number;
 
  BEGIN
--
--
--
--
--
--
--
--
--
--
--
    deb('resyncAddDBUname - cdbunstr = '|| cdbunstr);
    dbuname := substr(cdbunstr, 2, 30); -- strip out the first quote
--
--
    deb('resyncAddDBUname - dbuname before = '|| dbuname);
    dbuname := substr(dbuname, 1, instr(dbuname, substr(cdbunstr,1,1))-1);
 
    deb('resyncAddDBUname - db_unique_name = '|| dbuname);
 
--
--
    insert into node (db_unique_name, db_key, force_resync2cf, 
                      database_role, site_key)
    values(upper(dbuname), this_db_key, 'YES', 'STANDBY', rman_seq.nextval);
 
    deb('resyncAddDBUname - adding node row with value ' || dbuname);
 
EXCEPTION
   WHEN dup_val_on_index THEN
--
     RETURN;
 
END resyncAddDBUname;
 
 
--
FUNCTION getThisSiteKey(db_unique_name in VARCHAR2 DEFAULT NULL) 
   return NUMBER
IS
   ret_site_key number;
BEGIN
   deb('getThisSiteKey - This site key is '||this_site_key);
   if db_unique_name is not null then
      ret_site_key := dbms_rcvman.getSiteKey(db_unique_name);
   else
      ret_site_key := this_site_key;
   end if;
   deb('Returning site key is '||ret_site_key);
   return ret_site_key;
END getThisSiteKey;
 
--
FUNCTION  isAMSchema RETURN BOOLEAN IS
BEGIN
   return this_is_ors;
END isAMSchema;
 
--
FUNCTION  getAMTstlevel RETURN NUMBER IS
   am_tst_level number := 0;
BEGIN
   if this_is_ors then
      select nvl(max(value), 0) into am_tst_level from config 
         where name = '_oam_tst_level';
      deb('getAMTstlevel from config ='||am_tst_level);
   else
      deb('getAMTstlevel='||am_tst_level||' for non-OAM schema');
   end if;
   return am_tst_level;
END getAMTstlevel;
 
PROCEDURE enableResyncActions IS
BEGIN
   deb('enableResyncActions - resync action tracing enabled');
   doResyncReasons := TRUE;
END enableResyncActions;
 
PROCEDURE setReason(reason IN number, forceSet IN boolean default FALSE) IS
BEGIN
   IF doResyncReasons THEN
--
--
      IF resync_reason = RESYNC_REASON_NONE OR forceSet THEN
         resync_reason := reason;
         deb('setReason - resync_reason: '||to_char(resync_reason));
      END IF;
   ELSE
      resync_reason := RESYNC_REASON_NOACTION;
   END IF;
END setReason;
 
FUNCTION getReason RETURN number IS
BEGIN
   IF doResyncReasons THEN
      deb('getReason - resync_reason: '||to_char(resync_reason));
      RETURN resync_reason;
   ELSE
      RETURN RESYNC_REASON_NOACTION;
   END IF;
END getReason;
 
PROCEDURE incResyncActions(action      IN number,
                           objno       IN number,
                           objname     IN varchar2) IS
BEGIN
   IF not doResyncReasons THEN
      deb('incResynActions - Not debugging');
      RETURN;
   END IF;
 
   BEGIN
      deb('incResynActions - for action: '||to_char(action)||' objno '||
          nvl(to_char(objno), 'IS NULL')||' objname '||nvl(objname, 'IS NULL'),
          RCVCAT_LEVEL_HI);
      IF debOK(RCVCAT_LEVEL_HI) THEN
         dumpResyncActions;
      END IF;
      IF not fullResyncAction.active THEN
         RETURN;
      END IF;
      IF objno is NOT NULL THEN
         IF fullResyncAction.lastobjno = objno THEN
            IF fullResyncAction.actTaken(action) THEN
--
               deb('incResyncActions - '||
                   RESYNC_ACTION_OBJECTS(fullResyncAction.objtype)||' '||
                   to_char(objno)||' already '||
                   RESYNC_ACTION_NAMES(action), RCVCAT_LEVEL_HI);
               RETURN;
            ELSE
               fullResyncAction.actTaken(action) := TRUE;
            END IF;
         ELSE
--
            fullResyncAction.lastobjno := objno;
            fullResyncAction.actTaken  := 
                resyncActionTaken_t(FALSE, FALSE, FALSE, 
                                    FALSE, FALSE, FALSE);
            fullResyncAction.actTaken(action) := TRUE;
         END IF;
      END IF;
 
      fullResyncAction.actCount(action) := fullResyncAction.actCount(action) + 1;
      fullResyncAction.valid := TRUE;
      IF objno is NOT NULL THEN
         IF objname is NOT NULL THEN
            deb('incResyncActions - '||
                RESYNC_ACTION_OBJECTS(fullResyncAction.objtype)||' '||
                objname||'('||to_char(objno)||') '||
                RESYNC_ACTION_NAMES(action), RCVCAT_LEVEL_HI);
         ELSE
            deb('incResyncActions - '||
                RESYNC_ACTION_OBJECTS(fullResyncAction.objtype)||' '||
                to_char(objno)||' '|| RESYNC_ACTION_NAMES(action), 
                RCVCAT_LEVEL_HI);
         END IF;
      ELSE
         deb('incResyncActions - '||
             RESYNC_ACTION_OBJECTS(fullResyncAction.objtype)||' '||
             to_char(objname)||' '|| RESYNC_ACTION_NAMES(action),
             RCVCAT_LEVEL_HI);
      END IF;
      deb('incResyncActions - Exiting', RCVCAT_LEVEL_HI);
   EXCEPTION
      WHEN others THEN
         deb('incResyncActions(DO_NOT_IGNORE) - caught exception '||
             substr(sqlerrm, 1, 132) || ' for '||
             to_char(action) || ' objno ' || nvl(to_char(objno), 'IS NULL') ||
             ' objname ' || nvl(objname, 'IS NULL'));
   END;
END incResyncActions;
 
PROCEDURE dumpResyncActions IS
   i   number;
BEGIN
   IF not doResyncReasons OR not debOK(RCVCAT_LEVEL_HI) THEN
      RETURN;
   END IF;
 
   deb('dumpResyncActions - resync_reason: '||to_char(nvl(resync_reason, -1)));
 
   IF resync_reason = RESYNC_REASON_NOACTION THEN
      RETURN;
   END IF;
 
   IF fullResyncAction.active THEN
      deb('dumpResyncActions - Container is active');
   ELSE
      deb('dumpResyncActions - Container is NOT active');
   END IF;
   IF fullResyncAction.valid THEN
      deb('dumpResyncActions - Container is valid');
   ELSE
      deb('dumpResyncActions - Container is NOT valid');
   END IF;
   IF fullResyncAction.objtype IS NOT NULL THEN
      deb('dumpResyncActions - objtype: '||
          RESYNC_ACTION_OBJECTS(fullResyncAction.objtype));
   ELSE
      deb('dumpResyncActions - objtype is NULL');
   END IF;
   IF fullResyncAction.lastobjno IS NOT NULL THEN
      deb('dumpResyncActions - lastobjno: '||
          to_char(fullResyncAction.lastobjno));
   ELSE
      deb('dumpResyncActions - lastobjno is NULL');
   END IF;
 
   FOR i IN 1..6 LOOP
      IF fullResyncAction.actTaken(i) THEN
         deb('dumpResyncActions - '||RESYNC_ACTION_NAMES(i)||' TRUE - '||
             fullResyncAction.actCount(i));
      ELSE
         deb('dumpResyncActions - '||RESYNC_ACTION_NAMES(i)||' FALSE - '||
             fullResyncAction.actCount(i));
      END IF;
   END LOOP;
END dumpResyncActions;
 
PROCEDURE getResyncActions(valid      OUT boolean
                           ,added     OUT number
                           ,dropped   OUT number
                           ,changed   OUT number
                           ,recreated OUT number
                           ,renamed   OUT number
                           ,resized   OUT number) IS                        
BEGIN
   IF doResyncReasons THEN
      IF debOK(RCVCAT_LEVEL_HI) THEN
         deb('getResyncActions - called', RCVCAT_LEVEL_HI);
         dumpResyncActions;
      END IF;
      fullResyncAction.active := FALSE;
      valid  := fullResyncAction.valid;
      fullResyncAction.valid := FALSE;
      added     := fullResyncAction.actCount(RESYNC_ACTION_ADD);
      dropped   := fullResyncAction.actCount(RESYNC_ACTION_DROP);
      changed   := fullResyncAction.actCount(RESYNC_ACTION_CHANGE);
      recreated := fullResyncAction.actCount(RESYNC_ACTION_RECREATE);
      renamed   := fullResyncAction.actCount(RESYNC_ACTION_RENAME);
      resized   := fullResyncAction.actCount(RESYNC_ACTION_RESIZE);
      setReason(RESYNC_REASON_NONE, TRUE);
   ELSE
      setReason(RESYNC_REASON_NOACTION, TRUE);
   END IF;
END getResyncActions;
 
PROCEDURE clearResyncActions IS
BEGIN
   fullResyncAction.active    := FALSE;
   fullResyncAction.valid     := FALSE;
   fullResyncAction.lastobjno := -1;
   fullResyncAction.objtype   := NULL;
   fullResyncAction.actTaken  := resyncActionTaken_t(FALSE, FALSE, FALSE, 
                                                     FALSE, FALSE, FALSE);
   fullResyncAction.actCount  := resyncActionCounts_t(0, 0, 0, 0, 0, 0);
   dumpResyncActions;
END clearResyncActions;
 
 
/*-------------------------------------------------*
 * Private functions for import catalog processing *
 *-------------------------------------------------*/
--
--
--
--
--
--
PROCEDURE adjustRmanSeq
IS
  currval                          NUMBER;
  newval                           NUMBER;
  incseq                           NUMBER;
BEGIN
  LOOP
    SELECT rman_seq.nextval
      INTO currval
      FROM dual;
 
    EXECUTE IMMEDIATE
      'SELECT rman_seq.nextval@'
    || dbms_assert.qualified_sql_name(import_dblink)
    || ' FROM dual'
      INTO incseq;
 
    EXECUTE IMMEDIATE
    'ALTER SEQUENCE rman_seq INCREMENT BY ' || incseq;
 
    SELECT rman_seq.nextval - incseq
      INTO import_offset
      FROM dual;
 
    EXECUTE IMMEDIATE
    'ALTER SEQUENCE rman_seq INCREMENT BY 1';
 
--
--
--
--
    EXIT WHEN (import_offset >= currval); 
  END LOOP;
END adjustRmanSeq;
 
--
--
--
--
--
--
--
FUNCTION isColumnASeq(
  column_name                      IN VARCHAR2
)
RETURN BOOLEAN
IS
BEGIN
  IF (column_name LIKE '%KEY')
  THEN
    FOR i in 1..key_columns.COUNT
    LOOP
      IF (key_columns(i) = column_name)
      THEN
        RETURN TRUE;
      END IF;
    END LOOP;
 
--
--
--
--
    RAISE_APPLICATION_ERROR(-20999, 'Internal error in ' ||
                            'isColumnASeq(): bad column '|| column_name);
  END IF;
  RETURN FALSE;
END isColumnASeq; 
 
--
--
--
--
--
--
--
FUNCTION getColumnName(
  table_name                       IN VARCHAR2
, offset                           IN NUMBER DEFAULT NULL
)
RETURN VARCHAR2
IS
  v_table                          user_objects.object_name%TYPE;
  v_column                         VARCHAR2(1024);
  isaseq                           BOOLEAN;
 
  CURSOR column_c(tname VARCHAR2)
  IS
    SELECT column_name, data_type
      FROM user_tab_columns
     WHERE table_name = tname
     ORDER BY column_name;
 
  FUNCTION add_comma (
    v_column                       IN VARCHAR2
  )
  RETURN VARCHAR2
  IS
  BEGIN
    IF (v_column IS NULL)
    THEN
      RETURN NULL;
    ELSE
      RETURN ',';
    END IF;
  END add_comma;
 
  FUNCTION add_offset(
    offset                         IN NUMBER
  , data_type                      IN VARCHAR2
  , column_name                    IN VARCHAR2
  )
  RETURN VARCHAR2
  IS
  BEGIN
    IF (offset IS NULL)
    THEN
      RETURN NULL;
    END IF;
    IF (data_type = 'NUMBER' AND isColumnASeq(column_name))
    THEN
      RETURN '+' || offset;
    END IF;
    RETURN null;
  END add_offset;
BEGIN
  SELECT object_name
    INTO v_table
    FROM user_objects
   WHERE object_name = UPPER(table_name)
     AND object_type = 'TABLE';
 
--
  FOR cRec in column_c(v_table)
  LOOP
    v_column := v_column
             || add_comma(v_column)
             || dbms_assert.simple_sql_name(table_name)
             || '.'
             || dbms_assert.simple_sql_name(cRec.column_name)
             || add_offset(offset, cRec.data_type, cRec.column_name);
  END LOOP;
  RETURN v_column;
END getColumnName;
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE importTable (
  table_name                       IN VARCHAR2
, from_table                       IN ts_name_list
, uniq_rows                        IN BOOLEAN
, where_clause                     IN VARCHAR2
)
IS
  insert_columns                   VARCHAR2(2048);
  from_columns                     VARCHAR2(2048);
  source_table                     VARCHAR2(2048);
  uniq_keyword                     VARCHAR2(8);
  start_time                       DATE;
BEGIN
  deb('Entering importTable table=' || table_name);
  insert_columns := getColumnName(table_name);
  from_columns   := getColumnName(table_name, import_offset);
  source_table   := dbms_assert.qualified_sql_name(
                      table_name || '@' || import_dblink
                    );
  FOR i IN 1..from_table.COUNT
  LOOP
    source_table := source_table
                 || ','
                 || dbms_assert.qualified_sql_name(
                      from_table(i) || '@' || import_dblink
                    );
  END LOOP;
 
  IF (uniq_rows)
  THEN
    uniq_keyword := 'DISTINCT';
  END IF;
--
--
--
--
--
--
--
--
  start_time := SYSDATE;
  EXECUTE IMMEDIATE
     'INSERT INTO '
  || dbms_assert.qualified_sql_name(table_name)
  || '('
  || insert_columns
  || ')'
  || 'SELECT ' || uniq_keyword || ' ' || from_columns
  || '  FROM ' || source_table
  || ' '
  || where_clause;
 
  deb('imported rows = ' || SQL%ROWCOUNT);
  deb('importTable took ' || ((SYSDATE - start_time) * 86400) || ' seconds');
  deb('Finished importTable table=' || table_name);
END importTable;
 
--
--
--
--
--
--
--
--
PROCEDURE registerImportDb (
  idb                              IN VARCHAR2
, idbinc                           IN VARCHAR2
)
IS
  TYPE cur_typ IS ref CURSOR;
  update_c                         cur_typ;
  from_table                       ts_name_list;
  from_columns                     VARCHAR2(2048);
  currkeys                         numTab_t;
  dbids                            numTab_t;
  dbkeys                           numTab_t;
  reg_dbuname                      key_columns_list;
  strg_prov                        sp_columns_list;
BEGIN
  deb('Entering registerImportDb');
  from_columns := getColumnName('db', import_offset);
 
--
--
--
--
--
--
--
--
  EXECUTE IMMEDIATE
     'INSERT INTO db (db.db_key, db.db_id)'
  || 'SELECT db.db_key + ' || import_offset
  || '     , db.db_id'
  || '  FROM db@' ||  dbms_assert.qualified_sql_name(import_dblink)
  || '    ,' || dbms_assert.qualified_sql_name(idb || '@' || import_dblink)
  || ' WHERE db.db_key = '
  || dbms_assert.simple_sql_name(idb) || '.db_key';
 
  deb('Total db imported = ' || SQL%ROWCOUNT);
 
--
  from_table.DELETE;
  from_table(1) := idbinc;
  importTable (
    table_name   => 'dbinc'
  , from_table   => from_table
  , uniq_rows    => FALSE
  , where_clause => 'WHERE dbinc.dbinc_key = '
                 || idbinc || '.dbinc_key'
  );
 
--
--
  OPEN update_c FOR
--
--
--
--
--
--
--
  'SELECT ' || from_columns || 
  '  FROM db@' || dbms_assert.qualified_sql_name(import_dblink)
               || ','
               || dbms_assert.qualified_sql_name(idb || '@' || import_dblink)
               ||
  ' WHERE db.db_key = ' || dbms_assert.simple_sql_name(idb) || '.db_key';
  FETCH update_c BULK COLLECT INTO currkeys, dbids, dbkeys, reg_dbuname, 
                                   strg_prov;
  CLOSE update_c;
 
--
  FORALL i IN 1..dbids.COUNT
   UPDATE db
      SET curr_dbinc_key = currkeys(i)
        , reg_db_unique_name = reg_dbuname(i)
        , storage_prov = strg_prov(i)
    WHERE db.db_key = dbkeys(i);
 
  deb('Finished registerImportDb');
EXCEPTION
  WHEN DUP_VAL_ON_INDEX
  THEN RAISE_APPLICATION_ERROR(-20512, 'Database already registered');
END registerImportDb;
 
--
--
--
--
--
--
--
--
PROCEDURE dropTempResource (
  name                             IN VARCHAR2
, data_type                        IN VARCHAR2
)
IS
  e_dblink_not_found               EXCEPTION;
  e_dblink_not_open                EXCEPTION;
  e_resource_not_found             EXCEPTION;
  e_table_not_found                EXCEPTION;
  PRAGMA EXCEPTION_INIT(e_dblink_not_found, -2024);
  PRAGMA EXCEPTION_INIT(e_dblink_not_open, -2081);
  PRAGMA EXCEPTION_INIT(e_resource_not_found, -20509);
  PRAGMA EXCEPTION_INIT(e_table_not_found, -942);
BEGIN
  deb('Entering dropTempResource name = ' || name ||
      ' , data_type = '|| data_type);
  commitChanges('dropTempResource');
 
--
  IF (NOT lockTempResource(name, data_type))
  THEN
    deb('Finished dropTempResource - resource busy');
    RETURN;
  END IF;
 
  IF (data_type = 'TABLE')
  THEN
    EXECUTE IMMEDIATE
      'DROP TABLE ' || dbms_assert.qualified_sql_name(name);
  ELSIF (data_type = 'DBLINK')
  THEN
    BEGIN
      EXECUTE IMMEDIATE
        'ALTER SESSION CLOSE DATABASE LINK '
      || dbms_assert.qualified_sql_name(name);
    EXCEPTION
      WHEN e_dblink_not_open
      THEN NULL;
    END;
    EXECUTE IMMEDIATE
      'DROP DATABASE LINK '
    || dbms_assert.qualified_sql_name(name);
  END IF;
 
--
  DELETE tempres
   WHERE tempres.name = dropTempResource.name;
 
  commitChanges('dropTempResource-2');
  deb('Finished dropTempResource');
EXCEPTION
  WHEN e_resource_not_found THEN
    DELETE FROM tempres WHERE tempres.name = dropTempResource.name;
    commitChanges('dropTempResource-3');
    deb('Finished dropTempResource - resource_not_found ' || name);
  WHEN e_dblink_not_found THEN
    deb('Finished dropTempResource - dblink_not_found' || name);
  WHEN e_table_not_found THEN
    deb('Finished dropTempResource - table_not_found' || name);
  WHEN OTHERS THEN
    deb('(DO_NOT_IGNORE)caught exception during dropTempResource ' ||
         SUBSTR(SQLERRM, 1, 512));
END dropTempResource;
 
--
--
--
--
--
--
--
--
PROCEDURE importGlobalScript
IS
   type cur_typ is ref cursor;
   global_scr_c    cur_typ;
   global_scr_q    varchar2(1024);
   local           scr%rowtype;
   given_name      scr.scr_name%type;
   from_table      ts_name_list;
   from_columns   varchar2(2048);
   copycnt         number;
   unique_violated exception;
   pragma exception_init(unique_violated, -1);
BEGIN
--
   from_columns := getColumnName('scr');
   global_scr_q := 'SELECT '
                || from_columns
                || '  FROM scr@'
                || dbms_assert.qualified_sql_name(import_dblink)
                || ' WHERE db_key IS NULL';
 
   OPEN global_scr_c FOR global_scr_q;
   LOOP
      FETCH global_scr_c
       INTO local.db_key, local.scr_comment, 
            local.scr_key, local.scr_name;
      EXIT WHEN global_scr_c%NOTFOUND;
      copycnt := 0;
      given_name := local.scr_name;
<<tryagain>>
      BEGIN
--
--
--
--
--
         EXECUTE IMMEDIATE
         'INSERT INTO scr (' || from_columns || ') VALUES ' ||
         '( null,' ||
            case when local.scr_comment is not null then
               '''' || local.scr_comment || ''','
            else
               'null,'
            end ||
            local.scr_key || '+' || import_offset || ',' ||
            '''' || local.scr_name || ''')';
      EXCEPTION
         WHEN unique_violated THEN
--
            copycnt := copycnt + 1;
            IF (copycnt = 1) THEN
               local.scr_name := 'COPY OF ' || given_name;
            ELSE
               local.scr_name := 'COPY(' || copycnt || ') OF ' || given_name;
            END IF;
            goto tryagain;
      END;
   END LOOP;
 
--
   from_table.delete;
   from_table(1) := 'scr';
   importTable(table_name    => 'scrl'
              ,from_table    => from_table
              ,uniq_rows     => FALSE
              ,where_clause  => 'where scr.db_key is null' ||
                                '  and scr.scr_key = scrl.scr_key');
END importGlobalScript;
 
/*------------------------------------------------*
 * Public functions for import catalog processing *
 *------------------------------------------------*/
--
--
--
--
--
PROCEDURE createTempResource(
   name       IN varchar2
  ,data_type  IN varchar2)
IS
   unique_violated exception;
   pragma exception_init(unique_violated ,-1);
BEGIN
--
   INSERT INTO tempres (name, data_type)
   VALUES (name, data_type);
   commitChanges('createTempResource');
EXCEPTION
   WHEN unique_violated THEN
      raise_application_error(-20508, 'resource already in use ' || name);
END createTempResource;
 
--
--
--
--
--
--
FUNCTION lockTempResource(
   name      IN varchar2
  ,data_type IN varchar2)
RETURN BOOLEAN IS
   local         tempres%ROWTYPE;
   found         number;
   resource_busy exception;
   pragma exception_init(resource_busy, -54);
BEGIN
  deb('Entering lockTempResource ' || name);
 
  SELECT name, data_type
    INTO local.name, local.data_type
    FROM tempres
   WHERE name = lockTempResource.name
     FOR UPDATE NOWAIT;
 
  IF (data_type = 'TABLE') THEN
     SELECT count(*)
       INTO found
       FROM user_tab_columns
      WHERE table_name = lockTempResource.name;
  ELSIF (data_type = 'DBLINK') THEN
     SELECT count(*)
       INTO found
       FROM user_db_links
      WHERE db_link = lockTempResource.name;
  ELSE
     raise_application_error(-20999,
        'Internal error in localTempResource(): bad data_type '|| data_type);
  END IF;
 
  IF (found = 0) THEN
     deb('Finished lockTempResource with resource not found');
     raise_application_error(-20509, 'resource not found ' || name);
  END IF;
 
  deb('Finished lockTempResource'); 
  RETURN TRUE;
EXCEPTION
  WHEN resource_busy THEN
     deb('Finished lockTempResource with resource_busy');
     RETURN FALSE;
  WHEN no_data_found THEN
     deb('Finished lockTempResource with no_data_found'); 
     RETURN FALSE;
END lockTempResource;
 
--
--
--
--
--
PROCEDURE cleanupTempResource IS
   CURSOR temp_c IS
      SELECT name, data_type
        FROM tempres;
BEGIN
   FOR tempRec in temp_c LOOP
      dropTempResource(tempRec.name, tempRec.data_type);
   END LOOP;
END cleanupTempResource;
 
--
--
--
--
--
--
--
--
PROCEDURE addDbidToImport(
   first    IN binary_integer
  ,idb      IN varchar2
  ,idbinc   IN varchar2
  ,dbid     IN number    DEFAULT NULL
  ,dbname   IN varchar2  DEFAULT NULL)
IS
   dummy       tempres.name%TYPE;
   ldbid       db.db_id%TYPE := dbid;
   dbid_exists number;
BEGIN
--
   IF (NOT lockTempResource(idb, 'TABLE')) THEN
      raise_application_error(-20508, 'resource already in use ' || idb);
   ELSIF (NOT lockTempResource(idbinc, 'TABLE')) THEN
      raise_application_error(-20508, 'resource already in use ' || idbinc);
   END IF;
 
   IF (dbid IS NULL AND dbname IS NULL) THEN
      EXECUTE IMMEDIATE
      'INSERT INTO ' || idb || '(db_key, db_id) ' ||
      '(SELECT db_key, db_id FROM db)';
 
      IF (sql%rowcount = 0) THEN
         raise_application_error(-20510, 'import database not found');
      END IF;
 
      EXECUTE IMMEDIATE
      'INSERT INTO ' || idbinc || '(dbinc_key) ' ||
      '(SELECT dbinc_key ' ||
      '   FROM dbinc, ' || idb ||
      '  WHERE dbinc.db_key = ' || idb ||'.db_key)'; 
      commitChanges('addDbidToImport');
      RETURN;
   ELSIF (dbname IS NOT NULL) THEN
      BEGIN
         SELECT db.db_id
           INTO ldbid
           FROM db, dbinc
          WHERE db.curr_dbinc_key = dbinc.dbinc_key
            AND dbinc.db_name = upper(addDbidtoImport.dbname);
      EXCEPTION
         WHEN no_data_found THEN
           raise_application_error(-20510, 'import database not found');
         WHEN too_many_rows THEN
           raise_application_error(-20511, 'import database name is ambiguous');
      END;
   ELSE
      BEGIN
         SELECT db.db_id
           INTO ldbid
           FROM db
          WHERE db.db_id = ldbid;
      EXCEPTION
         WHEN no_data_found THEN
           raise_application_error(-20510, 'import database not found');
      END;
   END IF;
 
--
--
   IF (first = 0) THEN
      FOR i in 1..import_dbid.count LOOP
         EXECUTE IMMEDIATE
            'SELECT count(*) FROM ' || idb ||
            ' WHERE ' || idb || '.db_id =' || import_dbid(i)
            INTO dbid_exists;
         IF (dbid_exists != 1) THEN
            raise_application_error(-20508, 'resource already in use ' || idb);
         END IF;
      END LOOP;
 
      EXECUTE IMMEDIATE
         'SELECT count(*) FROM ' || idb INTO dbid_exists;
      IF (dbid_exists != import_dbid.count) THEN
         raise_application_error(-20508, 'resource already in use ' || idb);
      END IF;
      import_dbid(import_dbid.count + 1) := ldbid;
   ELSE
      import_dbid.delete;
      import_dbid(1) := ldbid;
   END IF;
 
   EXECUTE IMMEDIATE
   'INSERT INTO ' || idb || '(db_key, db_id) ' ||
   '(SELECT db_key, db_id FROM db ' ||
   '  WHERE db_id = ' || ldbid || ')';
 
   EXECUTE IMMEDIATE
   'INSERT INTO ' || idbinc || '(dbinc_key) ' ||
   '(SELECT dbinc_key ' ||
   '    FROM dbinc, ' || idb ||
   '  WHERE dbinc.db_key = ' || idb || '.db_key ' ||
   '    AND ' || idb || '.db_id = ' || ldbid || ')'; 
 
   commitChanges('addDbidToImport-2');
 
--
   IF (NOT lockTempResource(idb, 'TABLE')) THEN
      raise_application_error(-20508, 'resource already in use ' || idb);
   ELSIF (NOT lockTempResource(idbinc, 'TABLE')) THEN
      raise_application_error(-20508, 'resource already in use ' || idbinc);
   END IF;
END addDbidToImport;
 
--
--
--
--
--
--
--
PROCEDURE lockDbidToImport(
   idb   IN varchar2)
IS
   TYPE cur_typ IS ref CURSOR;
   idb_c           cur_typ;
   idb_q           varchar2(512);
   local_db_key    db.db_key%TYPE;
   local_db_id     db.db_key%TYPE;
BEGIN
   idb_q := 'SELECT db_key FROM ' || idb;
   OPEN idb_c FOR idb_q;
   LOOP
      FETCH idb_c INTO local_db_key; 
      EXIT WHEN idb_c%NOTFOUND;
      SELECT db_id INTO local_db_id
        FROM db
       WHERE db.db_key = local_db_key
         FOR UPDATE OF db.db_key;
   END LOOP;
END lockDbidToImport;
 
--
--
--
--
--
--
PROCEDURE importSchema(
   dblink  IN varchar2
  ,idb     IN varchar2
  ,idbinc  IN varchar2)
IS
   from_table     ts_name_list;
BEGIN
   import_dblink := dblink;
   adjustRmanSeq;
   registerImportDb(idb, idbinc);
 
--
   from_table.delete;
   from_table(1) := idb;
   importTable(table_name    => 'pdb'
              ,from_table    => from_table
              ,uniq_rows     => FALSE
              ,where_clause  => 'where pdb.db_key = ' ||
                                idb || '.db_key');
 
--
   from_table.delete;
   from_table(1) := idb;
   from_table(2) := 'pdb';
   importTable(table_name    => 'pdbinc'
              ,from_table    => from_table
              ,uniq_rows     => FALSE
              ,where_clause  => 'where pdb.db_key = ' ||
                                idb || '.db_key'  ||
                                '  and pdbinc.pdb_key = pdb.pdb_key');
 
--
   from_table.delete;
   from_table(1) := idbinc;
   importTable(table_name    => 'pdb_dbinc'
              ,from_table    => from_table
              ,uniq_rows     => FALSE
              ,where_clause  => 'where pdb_dbinc.dbinc_key = ' ||
                                idbinc || '.dbinc_key');
 
--
   from_table.delete;
   from_table(1) := idb;
   importTable(table_name    => 'conf'
              ,from_table    => from_table
              ,uniq_rows     => FALSE
              ,where_clause  => 'where conf.db_key = ' || idb || '.db_key');
 
--
   from_table.delete;
   from_table(1) := idb;
   importTable(table_name    => 'node'
              ,from_table    => from_table
              ,uniq_rows     => FALSE
              ,where_clause  => 'where node.db_key = ' || idb || '.db_key');
 
--
   from_table.delete;
   from_table(1) := idbinc;
   importTable(table_name    => 'ckp'
              ,from_table    => from_table
              ,uniq_rows     => FALSE
              ,where_clause  => 'where ckp.dbinc_key = ' ||
                                 idbinc || '.dbinc_key');
 
--
   from_table.delete;
   from_table(1) := idbinc;
   importTable(table_name    => 'ts'
              ,from_table    => from_table
              ,uniq_rows     => FALSE
              ,where_clause  => 'where ts.dbinc_key = ' ||
                                idbinc || '.dbinc_key');
 
--
   from_table.delete;
   from_table(1) := idbinc;
   importTable(table_name    => 'tsatt'
              ,from_table    => from_table
              ,uniq_rows     => FALSE
              ,where_clause  => 'where tsatt.dbinc_key = ' ||
                                idbinc || '.dbinc_key');
 
--
   from_table.delete;
   from_table(1) := idbinc;
   importTable(table_name    => 'df'
              ,from_table    => from_table
              ,uniq_rows     => FALSE
              ,where_clause  => 'where df.dbinc_key = ' ||
                                idbinc || '.dbinc_key');
 
--
   from_table.delete;
   from_table(1) := idb;
   from_table(2) := 'node';
   importTable(table_name    => 'site_dfatt'
              ,from_table    => from_table
              ,uniq_rows     => TRUE
              ,where_clause  => 'where node.db_key = ' ||
                                idb || '.db_key'  ||
                                '  and site_dfatt.site_key = node.site_key');
 
--
   from_table.delete;
   from_table(1) := idbinc;
   importTable(table_name    => 'offr'
              ,from_table    => from_table
              ,uniq_rows     => FALSE
              ,where_clause  => 'where offr.dbinc_key = ' ||
                                idbinc || '.dbinc_key');
 
--
   from_table.delete;
   from_table(1) := idbinc;
   importTable(table_name    => 'tf'
              ,from_table    => from_table
              ,uniq_rows     => FALSE
              ,where_clause  => 'where tf.dbinc_key = ' ||
                                idbinc || '.dbinc_key');
 
--
   from_table.delete;
   from_table(1) := idb;
   from_table(2) := 'node';
   importTable(table_name    => 'site_tfatt'
              ,from_table    => from_table
              ,uniq_rows     => TRUE
              ,where_clause  => 'where node.db_key = ' ||
                                idb || '.db_key'  ||
                                '  and site_tfatt.site_key = node.site_key');
 
--
   from_table.delete;
   from_table(1) := idbinc;
   importTable(table_name    => 'rr'
              ,from_table    => from_table
              ,uniq_rows     => FALSE
              ,where_clause  => 'where rr.dbinc_key = ' ||
                                idbinc || '.dbinc_key');
 
--
   from_table.delete;
   from_table(1) := idbinc;
   importTable(table_name    => 'rt'
              ,from_table    => from_table
              ,uniq_rows     => FALSE
              ,where_clause  => 'where rt.dbinc_key = ' ||
                                idbinc || '.dbinc_key');
 
--
   from_table.delete;
   from_table(1) := idbinc;
   importTable(table_name    => 'orl'
              ,from_table    => from_table
              ,uniq_rows     => FALSE
              ,where_clause  => 'where orl.dbinc_key = ' ||
                                idbinc || '.dbinc_key');
 
--
   from_table.delete;
   from_table(1) := idbinc;
   importTable(table_name    => 'rlh'
              ,from_table    => from_table
              ,uniq_rows     => FALSE
              ,where_clause  => 'where rlh.dbinc_key = ' ||
                                idbinc || '.dbinc_key');
 
--
   from_table.delete;
   from_table(1) := idbinc;
   importTable(table_name    => 'al'
              ,from_table    => from_table
              ,uniq_rows     => FALSE
              ,where_clause  => 'where al.dbinc_key = ' ||
                                idbinc || '.dbinc_key');
 
--
   from_table.delete;
   from_table(1) := idb;
   importTable(table_name    => 'bs'
              ,from_table    => from_table
              ,uniq_rows     => FALSE
              ,where_clause  => 'where bs.db_key = ' || idb || '.db_key');
 
--
   from_table.delete;
   from_table(1) := idb;
   importTable(table_name    => 'bp'
              ,from_table    => from_table
              ,uniq_rows     => FALSE
              ,where_clause  => 'where bp.db_key = ' || idb || '.db_key');
 
--
   from_table.delete;
   from_table(1) := idbinc;
   importTable(table_name    => 'bcf'
              ,from_table    => from_table
              ,uniq_rows     => FALSE
              ,where_clause  => 'where bcf.dbinc_key = ' ||
                                idbinc || '.dbinc_key');
 
--
   from_table.delete;
   from_table(1) := idbinc;
   importTable(table_name    => 'ccf'
              ,from_table    => from_table
              ,uniq_rows     => FALSE
              ,where_clause  => 'where ccf.dbinc_key = ' ||
                                idbinc || '.dbinc_key');
 
--
   from_table.delete;
   from_table(1) := idbinc;
   importTable(table_name    => 'xcf'
              ,from_table    => from_table
              ,uniq_rows     => FALSE
              ,where_clause  => 'where xcf.dbinc_key = ' ||
                                idbinc || '.dbinc_key');
 
--
   from_table.delete;
   from_table(1) := idb;
   importTable(table_name    => 'bsf'
              ,from_table    => from_table
              ,uniq_rows     => FALSE
              ,where_clause  => 'where bsf.db_key = ' || idb || '.db_key');
 
--
   from_table.delete;
   from_table(1) := idbinc;
   importTable(table_name    => 'bdf'
              ,from_table    => from_table
              ,uniq_rows     => FALSE
              ,where_clause  => 'where bdf.dbinc_key = ' ||
                                idbinc || '.dbinc_key');
 
--
   from_table.delete;
   from_table(1) := idbinc;
   importTable(table_name    => 'cdf'
              ,from_table    => from_table
              ,uniq_rows     => FALSE
              ,where_clause  => 'where cdf.dbinc_key = ' ||
                                idbinc || '.dbinc_key');
 
--
   from_table.delete;
   from_table(1) := idbinc;
   importTable(table_name    => 'xdf'
              ,from_table    => from_table
              ,uniq_rows     => FALSE
              ,where_clause  => 'where xdf.dbinc_key = ' ||
                                idbinc || '.dbinc_key');
 
--
   from_table.delete;
   from_table(1) := idbinc;
   importTable(table_name    => 'xal'
              ,from_table    => from_table
              ,uniq_rows     => FALSE
              ,where_clause  => 'where xal.dbinc_key = ' ||
                                idbinc || '.dbinc_key');
 
--
   from_table.delete;
   from_table(1) := idbinc;
   importTable(table_name    => 'brl'
              ,from_table    => from_table
              ,uniq_rows     => FALSE
              ,where_clause  => 'where brl.dbinc_key = ' ||
                                idbinc || '.dbinc_key');
 
--
   from_table.delete;
   from_table(1) := idbinc;
   from_table(2) := 'bdf';
   importTable(table_name    => 'bcb'
              ,from_table    => from_table
              ,uniq_rows     => FALSE
              ,where_clause  => 'where bdf.bdf_key = bcb.bdf_key' ||
                                '  and bdf.dbinc_key = ' ||
                                       idbinc || '.dbinc_key');
 
--
   from_table.delete;
   from_table(1) := idbinc;
   from_table(2) := 'cdf';
   importTable(table_name    => 'ccb'
              ,from_table    => from_table
              ,uniq_rows     => FALSE
              ,where_clause  => 'where cdf.cdf_key = ccb.cdf_key' ||
                                '  and cdf.dbinc_key = ' ||
                                       idbinc || '.dbinc_key');
 
--
   from_table.delete;
   from_table(1) := idbinc;
   importTable(table_name    => 'rsr'
              ,from_table    => from_table
              ,uniq_rows     => FALSE
              ,where_clause  => 'where rsr.dbinc_key= ' ||idbinc||
                                '.dbinc_key');
 
--
   from_table.delete;
   from_table(1) := idb;
   importTable(table_name    => 'scr'
              ,from_table    => from_table
              ,uniq_rows     => FALSE
              ,where_clause  => 'where scr.db_key = ' || idb || '.db_key');
 
--
   from_table.delete;
   from_table(1) := idb;
   from_table(2) := 'scr';
   importTable(table_name    => 'scrl'
              ,from_table    => from_table
              ,uniq_rows     => FALSE
              ,where_clause  => 'where scr.db_key = ' || idb || '.db_key' ||
                                '  and scr.scr_key = scrl.scr_key');
 
--
   importGlobalScript;
 
--
   from_table.delete;
   from_table(1) := idb;
   importTable(table_name    => 'rout'
              ,from_table    => from_table
              ,uniq_rows     => FALSE
              ,where_clause  => 'where rout.db_key = ' || idb || '.db_key');
 
--
--
--
 
--
   from_table.delete;
   from_table(1) := idbinc;
   importTable(table_name    => 'fb'
              ,from_table    => from_table
              ,uniq_rows     => FALSE
              ,where_clause  => 'where fb.dbinc_key = '|| idbinc ||
                                '.dbinc_key');
 
--
   from_table.delete;
   from_table(1) := idbinc;
   importTable(table_name    => 'grsp'
              ,from_table    => from_table
              ,uniq_rows     => FALSE
              ,where_clause  => 'where grsp.dbinc_key = '|| idbinc ||
                                '.dbinc_key');
 
--
   from_table.delete;
   from_table(1) := idb;
   from_table(2) := 'node';
   importTable(table_name    => 'bcr'
              ,from_table    => from_table
              ,uniq_rows     => FALSE
              ,where_clause  => 'where bcr.site_key = node.site_key' ||
                                '  and node.db_key = ' ||
                                       idb || '.db_key');
--
   from_table.delete;
   from_table(1) := idbinc;
   importTable(table_name    => 'nrsp'
              ,from_table    => from_table
              ,uniq_rows     => FALSE
              ,where_clause  => 'where nrsp.dbinc_key = '|| idbinc ||
                                '.dbinc_key');
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
 
   commitChanges('importSchema');
EXCEPTION
   WHEN others THEN
      deb('importSchema - release locks');
      ROLLBACK;
      RAISE;
END importSchema;
 
--
--
--
--
--
--
PROCEDURE unregisterDatabase(
   idb   IN varchar2)
IS
   TYPE cur_typ IS ref CURSOR;
   idb_c           cur_typ;
   idb_q           varchar2(512);
   local_db_id     db.db_id%TYPE;
BEGIN
   idb_q := 'SELECT db_id FROM ' || idb;
   OPEN idb_c FOR idb_q;
   LOOP
      FETCH idb_c INTO local_db_id;
      EXIT WHEN idb_c%NOTFOUND;
      unregisterDatabase(db_id => local_db_id);
   END LOOP;
END unregisterDatabase;
 
PROCEDURE clearUnarchivedLogs IS 
BEGIN
   deb('clearUnarchivedLogs for this_db_key='||this_db_key);
   delete from al
    where archived = 'N'
      and dbinc_key in (select dbinc_key from dbinc where db_key = this_db_key);
   commitChanges('clearUnarchivedLogs');
END clearUnarchivedLogs;
 
/*----------------------------*
 * Virtual Private Catalog    *
 *----------------------------*/
 
--
--
--
--
--
--
--
--
--
--
 
FUNCTION grant_get_dbid(dbname IN varchar2) RETURN number IS
   dbid number;
   cnt  number;
BEGIN
   select max(db_id), count(*) into dbid, cnt from db join
      (select distinct db_key,db_name from dbinc) using(db_key)
      where db_name = dbname;
 
   deb('grant_get_dbid - got dbid and cnt ' || dbid || ' cnt ' ||
       cnt);
 
   if cnt = 0 then
      raise_application_error(-20018, 'database ' || dbname ||
                              ' not found in recovery catalog');
   end if;
 
   if cnt > 1 then
      raise_application_error(-20019, 'database ' || dbname ||
                              ' not unique in recovery catalog');
   end if;
 
   return dbid;
END;
 
FUNCTION get_db_numeric_uid(uname IN VARCHAR2) RETURN NUMBER IS
  numeric_uid NUMBER;
BEGIN
  SELECT user_id INTO numeric_uid FROM all_users WHERE username = uname;
  RETURN numeric_uid;
  EXCEPTION
    WHEN NO_DATA_FOUND
    THEN raise_application_error(-20022, 'user ' || uname || ' not found');
END;
 
PROCEDURE clean_old_uids IS
BEGIN
  DELETE vpc_databases
   WHERE filter_uid NOT IN (SELECT user_id FROM all_users);
  DELETE vpc_users
   WHERE filter_uid NOT IN (SELECT user_id FROM all_users);
 
--
--
 
END;
 
FUNCTION is_vpd_enabled (
  i_full_check                     BOOLEAN DEFAULT TRUE
)
RETURN BOOLEAN
IS
  l_dummy                          VARCHAR2(1);
BEGIN
--
--
  IF (this_is_ors)
  THEN
    RETURN TRUE;
  END IF;
--
--
  IF (SYS_CONTEXT('SYS_SESSION_ROLES', 'RECOVERY_CATALOG_OWNER_VPD') = 'TRUE')
  THEN
    NULL;
  ELSE
--
--
    BEGIN
      SELECT 'x'
        INTO l_dummy
        FROM session_privs
       WHERE privilege IN (
--
               'ADMINISTER DATABASE TRIGGER'
--
             , 'CREATE ANY SYNONYM', 'DROP ANY SYNONYM'
             )
      HAVING COUNT(*) = 3;
    EXCEPTION
      WHEN NO_DATA_FOUND
      THEN RETURN FALSE;
    END;
  END IF;
--
--
--
  BEGIN
    SELECT 'x'
      INTO l_dummy
      FROM all_tab_privs
     WHERE (table_schema, table_name, privilege, grantee) IN (
             ('SYS', 'DBMS_RLS', 'EXECUTE', 'RECOVERY_CATALOG_OWNER_VPD')
           , ('SYS', 'DBMS_RLS', 'EXECUTE', 'RECOVERY_CATALOG_OWNER')
           , ('SYS', 'DBMS_RLS', 'EXECUTE', g_catowner)
           )
    HAVING COUNT(*) > 0;
  EXCEPTION
    WHEN NO_DATA_FOUND
    THEN RETURN FALSE;
  END;
  IF (i_full_check)
  THEN
--
--
--
    BEGIN
      SELECT 'x'
        INTO l_dummy
        FROM user_policies
      HAVING COUNT(*) = g_vpd_required_policies;
    EXCEPTION
      WHEN NO_DATA_FOUND
      THEN RETURN FALSE;
    END;
--
    BEGIN
      SELECT 'x'
        INTO l_dummy
        FROM user_triggers
       WHERE trigger_name = 'VPC_CONTEXT_TRG';
      EXCEPTION
        WHEN NO_DATA_FOUND
        THEN RETURN FALSE;
    END;
  END IF;
  RETURN TRUE;
END;
 
PROCEDURE revoke_clean_userid (
  userid                           IN VARCHAR2
)
IS
  l_privs_remaining                NUMBER;
  l_schema                         user_users.username%TYPE;
  l_eschema                        VARCHAR2(130);
  e_no_synonym                     EXCEPTION;
  PRAGMA EXCEPTION_INIT(e_no_synonym, -1434);
BEGIN
  assert_schema(l_schema, l_eschema, userid);
  
  DELETE vpc_users
   WHERE filter_user = userid
     AND add_new_db = 'N'
     AND NOT EXISTS (
           SELECT *
             FROM vpc_databases
            WHERE filter_user = l_schema
         );
 
  commitChanges('revoke_clean_userid');
 
  SELECT COUNT(*)
    INTO l_privs_remaining
    FROM vpc_users
   WHERE filter_user = l_schema;
 
  deb('revoke_clean_userid - commit, release locks, userid=' || l_schema ||
      ', privs_remaining=' || l_privs_remaining);
 
  IF l_privs_remaining > 0 THEN RETURN; END IF;
 
  IF (NOT this_is_ors)
  THEN
    BEGIN
      EXECUTE IMMEDIATE
        'REVOKE recovery_catalog_user FROM ' || l_eschema;
    EXCEPTION
      WHEN OTHERS
      THEN  deb('revoke_clean_userid(DO_NOT_IGNORE)');
    END;
  END IF;
  BEGIN
    EXECUTE IMMEDIATE
      'DROP SYNONYM ' || l_eschema || '."DBMS_RCVMAN"';
  EXCEPTION
    WHEN e_no_synonym
    THEN NULL;
  END;
  BEGIN
    EXECUTE IMMEDIATE
      'DROP SYNONYM ' || l_eschema || '."DBMS_RCVCAT"';
  EXCEPTION
    WHEN e_no_synonym
    THEN NULL;
  END;
END;
 
PROCEDURE do_vpc_grants (
  userid                           IN VARCHAR2
)
IS
  l_schema                         user_users.username%TYPE;
  l_eschema                        VARCHAR2(130);
BEGIN
  IF (NOT is_vpd_enabled)
  THEN
    RAISE_APPLICATION_ERROR(e_no_vpd_setup, e_no_vpd_setup_m);
  END IF;
 
  assert_schema(l_schema, l_eschema, userid);
 
  IF (NOT this_is_ors)
  THEN
    EXECUTE IMMEDIATE
      'GRANT recovery_catalog_user TO ' || l_eschema;
  END IF;
  /* While stemming from rman client PL/SQL context alter session
   * set current_schema has no effect as far as visibility to packages
   * are concerned. So the additional steps below. (bandaid)
   * Since DDL is, in general, bad activity we have to limit it
   * making sure that the synonyms are created only if they don't
   * exist.
   */
  FOR s IN (
    SELECT synonym_name
      FROM (
           SELECT 'DBMS_RCVMAN' synonym_name FROM dual
            UNION ALL
           SELECT 'DBMS_RCVCAT' FROM dual
           ) x
     WHERE NOT EXISTS (
             SELECT NULL
               FROM all_synonyms s
              WHERE s.table_owner = g_catowner
                AND s.table_name = x.synonym_name
                AND s.owner = userid
                AND s.synonym_name = x.synonym_name
           )
  )
  LOOP
    EXECUTE IMMEDIATE
      'CREATE OR REPLACE SYNONYM '
    || l_eschema   || '.' || s.synonym_name
    || ' FOR '
    || g_ecatowner || '.' || s.synonym_name;
  END LOOP;
END;
 
PROCEDURE grant_catalog(userid IN varchar2, dbname IN varchar2) IS
BEGIN
  grant_catalog(userid, grant_get_dbid(dbname));
END;
 
PROCEDURE grant_catalog(userid             IN varchar2, 
                        dbid               IN number,
                        reg_db_unique_name IN varchar2 default null) IS
   user_count  number;
   numeric_uid number;
   p_dbun      node.db_unique_name%TYPE := upper(reg_db_unique_name);
   p_dbid      number not null := dbid;
BEGIN
   clean_old_uids;
 
   do_vpc_grants(userid);
 
   SELECT COUNT(*), MAX(filter_uid) INTO user_count, numeric_uid FROM vpc_users
    WHERE filter_user = userid;
 
   if user_count = 0 then
      numeric_uid := get_db_numeric_uid(userid);
      insert into vpc_users(filter_user, filter_uid, add_new_db)
         values(userid, numeric_uid, 'N');
   end if;
 
--
--
   update vpc_databases
      set db_id = dbid,
          reg_db_unique_name = null
    where filter_user = userid
      and db_id = 0
      and reg_db_unique_name = p_dbun;
 
--
--
   if sql%rowcount = 0 then
     insert into vpc_databases
        (filter_user, filter_uid, reg_db_unique_name, db_id)
        select userid, numeric_uid, decode(dbid, 0, p_dbun, null), dbid
          from dual
           where not exists
              (select 1 from vpc_databases
                  where filter_user = userid
                    and ((db_id = 0 and reg_db_unique_name = p_dbun) or
                         (db_id <> 0 and db_id = dbid)));
   end if;
 
   commitChanges('grant_catalog');
END;
 
PROCEDURE grant_register(userid IN varchar2) IS
   numeric_uid number := get_db_numeric_uid(userid);
BEGIN
   clean_old_uids;
 
   do_vpc_grants(userid);
 
   MERGE INTO vpc_users USING dual ON (filter_user = userid)
      WHEN MATCHED THEN UPDATE SET add_new_db = 'Y'
      WHEN NOT MATCHED THEN
         INSERT(filter_user, filter_uid,  add_new_db)
         VALUES(userid,      numeric_uid, 'Y');
 
   commitChanges('grant_register');
END;
 
PROCEDURE revoke_catalog(userid IN varchar2, dbname IN varchar2) IS
BEGIN
   revoke_catalog(userid, grant_get_dbid(dbname));
END;
 
PROCEDURE revoke_catalog(userid             IN varchar2, 
                         dbid               IN number,
                         reg_db_unique_name IN varchar2 default null) IS
   p_dbun      node.db_unique_name%TYPE := upper(reg_db_unique_name);
   p_dbid      number not null := dbid;
BEGIN
   IF (NOT is_vpd_enabled)
   THEN
     RAISE_APPLICATION_ERROR(e_no_vpd_setup, e_no_vpd_setup_m);
   END IF;
   clean_old_uids;
   deb('revoke_catalog - After clean_old_uids');
   delete from vpc_databases 
      where filter_user = userid 
        and ((dbid <> 0 and db_id = dbid) or
             (dbid = 0 and reg_db_unique_name = p_dbun));
   revoke_clean_userid(userid);
   commitChanges('revoke_catalog');
END;
 
PROCEDURE revoke_register(userid IN varchar2) IS
BEGIN
   IF (NOT is_vpd_enabled)
   THEN
     RAISE_APPLICATION_ERROR(e_no_vpd_setup, e_no_vpd_setup_m);
   END IF;
   clean_old_uids;
   update vpc_users set add_new_db='N' where filter_user=userid;
   revoke_clean_userid(userid);
   commitChanges('revoke_register');
END;
 
PROCEDURE revoke_all (
  userid                           IN VARCHAR2
)
IS
BEGIN
  clean_old_uids;
  DELETE vpc_databases WHERE filter_user = userid;
  DELETE vpc_users     WHERE filter_user = userid;
  revoke_clean_userid(userid);
  commitChanges('revoke_all');
END;
 
PROCEDURE create_virtual_catalog IS
BEGIN
  NULL;
END create_virtual_catalog;
 
PROCEDURE drop_virtual_catalog IS
BEGIN
  NULL;
END drop_virtual_catalog;
 
/*
 * New VPC based on VPD 
 * This routine is setup to be idempotent, can be called
 * again and again.
 * Input i_oper: Can be used to drop the policies on an upgrade
 * when i_oper == 0. Sets the policies when i_oper <> 0
 */
PROCEDURE setupVPD (
  i_oper                           NUMBER
)
IS
  lc_policy_str                    CONSTANT VARCHAR2(32) :=
    'dbms_rcvvpc.f_';
  lc_policy_str_passall            CONSTANT VARCHAR2(32) :=
    'dbms_rcvvpc.filter_pass_all';
  l_policy_str                     VARCHAR2(64);
  e_policy_notexists               EXCEPTION;
  PRAGMA                           EXCEPTION_INIT(e_policy_notexists, -28102);
  l_granted_to                     VARCHAR2(32) := CASE
                                                     WHEN this_is_ors
                                                     THEN 'PUBLIC'
                                                     ELSE 'recovery_catalog_user'
                                                   END;
BEGIN
--
--
--
--
--
  IF (      SYS_CONTEXT('USERENV', 'SESSION_USER') <> g_catowner
     OR NOT is_vpd_enabled(i_full_check => FALSE)
  )
  THEN
    RETURN;
  END IF;
 
  FOR i IN 1..vpd_table_list.COUNT
  LOOP
    EXECUTE IMMEDIATE 'GRANT '
                   || vtr_privs(i)
                   || ' ON '
                   || vtr_tname(i)
                   || ' TO '
                   || l_granted_to;
    IF vtr_policy_required(i)
    THEN
      BEGIN
        EXECUTE IMMEDIATE '
        BEGIN
          dbms_rls.drop_policy (
            object_schema => :1
          , object_name   => :2
          , policy_name   => :3
          );
        END;' USING g_ecatowner
                  , vtr_tname(i)
                  , vtr_tname(i);
      EXCEPTION
        WHEN e_policy_notexists
        THEN NULL;
      END;
 
      IF (i_oper = 0)
      THEN 
        l_policy_str := lc_policy_str_passall;
      ELSE
        l_policy_str := lc_policy_str || vtr_tname(i);
      END IF;
      
      IF (vtr_update_check(i))
      THEN
        EXECUTE IMMEDIATE '
        BEGIN
           dbms_rls.add_policy (
             object_schema   => :1
           , object_name     => :2
           , policy_name     => :3
           , function_schema => :4
           , policy_function => :5
           , policy_type     => dbms_rls.shared_context_sensitive
           , update_check    => TRUE
           );
         END;' USING g_ecatowner
                   , vtr_tname(i)
                   , vtr_tname(i)
                   , g_ecatowner
                   , l_policy_str;
      ELSE
        EXECUTE IMMEDIATE '
        BEGIN
           dbms_rls.add_policy (
             object_schema   => :1
           , object_name     => :2
           , policy_name     => :3
           , function_schema => :4
           , policy_function => :5
           , policy_type     => dbms_rls.shared_context_sensitive
           , update_check    => FALSE
           );
         END;' USING g_ecatowner
                   , vtr_tname(i)
                   , vtr_tname(i)
                   , g_ecatowner
                   , l_policy_str;
      END IF;
    END IF;
  END LOOP;
 
  FOR r IN (
    SELECT view_name
      FROM user_views
     WHERE view_name LIKE 'RC~_%' ESCAPE '~'
        OR view_name LIKE 'RCI~_%' ESCAPE '~'
        OR view_name LIKE '~_RS~_RC~_%' ESCAPE '~'
        OR view_name LIKE '~_RS~_RCI~_%' ESCAPE '~'
  )
  LOOP
    EXECUTE IMMEDIATE
      'GRANT SELECT ON '
    || dbms_assert.enquote_name(r.view_name)
    || ' TO ' || l_granted_to;
  END LOOP;
 
  IF (this_is_ors)
  THEN
    EXECUTE IMMEDIATE 'GRANT EXECUTE ON dbms_rai_owner TO PUBLIC';
    EXECUTE IMMEDIATE
      'CREATE OR REPLACE PUBLIC SYNONYM dbms_rai_owner FOR dbms_rai_owner';
    EXECUTE IMMEDIATE 'GRANT EXECUTE ON dbms_rai_verifier TO PUBLIC';
    EXECUTE IMMEDIATE 'GRANT EXECUTE ON dbms_rai_inst_addresses TO PUBLIC';
    EXECUTE IMMEDIATE 'GRANT EXECUTE ON dbms_rai_sbt_parms TO PUBLIC';
    EXECUTE IMMEDIATE 'GRANT EXECUTE ON dbms_rai_url TO PUBLIC';
    EXECUTE IMMEDIATE 'GRANT EXECUTE ON dbms_rai_wallet2url TO PUBLIC';
    EXECUTE IMMEDIATE 'GRANT EXECUTE ON dbms_rai_throttle_alloc TO PUBLIC';
    EXECUTE IMMEDIATE 'GRANT EXECUTE ON dbms_rai_fix_error TO PUBLIC';
    EXECUTE IMMEDIATE 'GRANT EXECUTE ON dbms_rai_populate_rsr_key TO PUBLIC';
  END IF;
 
  deb('setupVPD - after adding policy and grants');
 
--
--
--
  IF (i_oper <> 0)
  THEN
    IF (this_is_ors)
    THEN
    EXECUTE IMMEDIATE REGEXP_REPLACE(REGEXP_REPLACE(q'{
CREATE OR REPLACE TRIGGER vpc_context_trg
AFTER LOGON ON DATABASE
WHEN (
  SYS_CONTEXT('USERENV', 'SESSION_USER') NOT IN (
    'SYSBACKUP', 'XDB', 'SYSMAN', 'ANONYMOUS', 'APPQOSSYS'
  , 'AUDSYS', 'CTXSYS', 'DIP'
  , 'DMSYS', 'EXFSYS', 'GSMADMIN_INTERNAL', 'GSMCATUSER'
  , 'GSMUSER' , 'MDSYS', 'ORABPEL', 'ORACLE_OCM'
  , 'ORAESB', 'ORAWSM', 'ORDPLUGINS', 'ORDSYS', 'OUTLN'
  , 'SI_INFORMTN_SCHEMA', 'SYSDG', 'SYSKM', 'TSMSYS'
  , 'WKSYS', 'WMSYS', 'XS$NULL'
  )
)
DECLARE
  l_dummy                          VARCHAR2(1);
BEGIN
--
--
--
  IF (  SYS_CONTEXT('USERENV', 'SESSION_USER') IN (
         '%o', 'SYS', 'SYSTEM', 'DBSNMP'
        )
  )
  THEN
    EXECUTE IMMEDIATE
      'ALTER SESSION SET NLS_NUMERIC_CHARACTERS = ''.,''';
  ELSE
--
--
    SELECT 'Y'
      INTO l_dummy
      FROM vpc_users
     WHERE filter_uid = SYS_CONTEXT('USERENV', 'SESSION_USERID');
    EXECUTE IMMEDIATE
      'ALTER SESSION SET NLS_NUMERIC_CHARACTERS = ''.,'' CURRENT_SCHEMA = %e';
  END IF;
EXCEPTION
  WHEN NO_DATA_FOUND
  THEN -- All regular users who have access to RA catalog must
--
       IF (SYS_CONTEXT('SYS_SESSION_ROLES', 'RA_CATALOG_SELECT') = 'TRUE')
       THEN
         EXECUTE IMMEDIATE
           'ALTER SESSION SET NLS_NUMERIC_CHARACTERS = ''.,''';
       END IF;
END;
}', '%e', g_ecatowner), '%o', g_catowner);
    ELSE
    EXECUTE IMMEDIATE REGEXP_REPLACE(REGEXP_REPLACE(q'{
CREATE OR REPLACE TRIGGER vpc_context_trg
AFTER LOGON ON DATABASE
WHEN (
  SYS_CONTEXT('USERENV', 'SESSION_USER') NOT IN (
    '%o', 'SYS', 'SYSTEM', 'SYSBACKUP'
  , 'XDB', 'SYSMAN', 'ANONYMOUS', 'APPQOSSYS'
  , 'AUDSYS', 'CTXSYS', 'DIP'
  , 'DMSYS', 'EXFSYS', 'GSMADMIN_INTERNAL', 'GSMCATUSER'
  , 'GSMUSER' , 'MDSYS', 'ORABPEL', 'ORACLE_OCM'
  , 'ORAESB', 'ORAWSM', 'ORDPLUGINS', 'ORDSYS', 'OUTLN'
  , 'SI_INFORMTN_SCHEMA', 'SYSDG', 'SYSKM', 'TSMSYS'
  , 'WKSYS', 'WMSYS', 'XS$NULL'
  )
)
DECLARE
  l_dummy                          VARCHAR2(1);
BEGIN
  SELECT 'Y'
    INTO l_dummy
    FROM vpc_users
   WHERE filter_uid = SYS_CONTEXT('USERENV', 'SESSION_USERID');
  EXECUTE IMMEDIATE 'ALTER SESSION SET CURRENT_SCHEMA = %e';
EXCEPTION
  WHEN NO_DATA_FOUND
  THEN NULL;
END;
}', '%e', g_ecatowner), '%o', g_catowner);
    END IF;
  END IF;
 
  deb('setupVPD - create or replace trigger');
END setupVPD;
 
PROCEDURE dumpPkgState (msg in varchar2 default NULL) IS
begin
   deb('Global variables package state ' || nvl(msg,' '));
   deb('Number variables');
   deb('dbglvl: ' || nvl(to_char(dbglvl), 'NULL'));
   deb('this_db_key: ' || nvl(to_char(this_db_key), 'NULL'));
   deb('this_dbinc_key: ' || nvl(to_char(this_dbinc_key), 'NULL'));
   deb('this_ckp_key: ' || nvl(to_char(this_ckp_key), 'NULL'));
   deb('this_ckp_scn: ' || nvl(to_char(this_ckp_scn), 'NULL'));
   deb('this_site_key: ' || nvl(to_char(this_site_key), 'NULL'));
   deb('logs_shared: ' || nvl(to_char(logs_shared), 'NULL'));
   deb('disk_backups_shared: ' || nvl(to_char(disk_backups_shared), 'NULL'));
   deb('tape_backups_shared: ' || nvl(to_char(tape_backups_shared), 'NULL'));
   deb('reNorm_state: ' || nvl(to_char(reNorm_state), 'NULL'));
   deb('resync_reason: ' || nvl(to_char(resync_reason), 'NULL'));
   deb('scr_key: ' || nvl(to_char(scr_key), 'NULL'));
   deb('scr_line: ' || nvl(to_char(scr_line), 'NULL'));
   deb('kccdivts: ' || nvl(to_char(kccdivts), 'NULL'));
   deb('cntbs: ' || nvl(to_char(cntbs), 'NULL'));
   deb('last_full_ckp_scn: ' || nvl(to_char(last_full_ckp_scn), 'NULL'));
   deb('last_con_id_ts#: ' || nvl(to_char(last_con_id_ts#), 'NULL'));
   deb('last_ts#: ' || nvl(to_char(last_ts#), 'NULL'));
   deb('last_file#: ' || nvl(to_char(last_file#), 'NULL'));
   deb('last_thread#: ' || nvl(to_char(last_thread#), 'NULL'));
   deb('last_ts_recid: ' || nvl(to_char(last_ts_recid), 'NULL'));
   deb('last_df_recid: ' || nvl(to_char(last_df_recid), 'NULL'));
   deb('last_tf_recid: ' || nvl(to_char(last_tf_recid), 'NULL'));
   deb('last_rt_recid: ' || nvl(to_char(last_rt_recid), 'NULL'));
   deb('last_orl_recid: ' || nvl(to_char(last_orl_recid), 'NULL'));
   deb('last_conf_recid: ' || nvl(to_char(last_conf_recid), 'NULL'));
   deb('force_resync2cf: ' || nvl(to_char(force_resync2cf), 'NULL'));
   deb('last_rlh_recid: ' || nvl(to_char(last_rlh_recid), 'NULL'));
   deb('last_al_recid: ' || nvl(to_char(last_al_recid), 'NULL'));
   deb('last_offr_recid: ' || nvl(to_char(last_offr_recid), 'NULL'));
   deb('last_bs_recid: ' || nvl(to_char(last_bs_recid), 'NULL'));
   deb('last_bp_recid: ' || nvl(to_char(last_bp_recid), 'NULL'));
   deb('last_bdf_recid: ' || nvl(to_char(last_bdf_recid), 'NULL'));
   deb('last_bsf_recid: ' || nvl(to_char(last_bsf_recid), 'NULL'));
   deb('last_brl_recid: ' || nvl(to_char(last_brl_recid), 'NULL'));
   deb('last_cdf_recid: ' || nvl(to_char(last_cdf_recid), 'NULL'));
   deb('last_bcb_recid: ' || nvl(to_char(last_bcb_recid), 'NULL'));
   deb('last_ccb_recid: ' || nvl(to_char(last_ccb_recid), 'NULL'));
   deb('last_do_recid: ' || nvl(to_char(last_do_recid), 'NULL'));
   deb('last_xdf_recid: ' || nvl(to_char(last_xdf_recid), 'NULL'));
   deb('last_xal_recid: ' || nvl(to_char(last_xal_recid), 'NULL'));
   deb('last_rsr_recid: ' || nvl(to_char(last_rsr_recid), 'NULL'));
   deb('last_rout_stamp: ' || nvl(to_char(last_rout_stamp), 'NULL'));
   deb('last_inst_startup_stamp: ' ||
       nvl(to_char(last_inst_startup_stamp), 'NULL'));
   deb('lrsr_key: ' || nvl(to_char(lrsr_key), 'NULL'));
   deb('lrout_skey: ' || nvl(to_char(lrout_skey), 'NULL'));
   deb('lsession_recid: ' || nvl(to_char(lsession_recid), 'NULL'));
   deb('lsession_stamp: ' || nvl(to_char(lsession_stamp), 'NULL'));
   deb('lrman_status_recid: ' || nvl(to_char(lrman_status_recid), 'NULL'));
   deb('lrman_status_stamp: ' || nvl(to_char(lrman_status_stamp), 'NULL'));
   deb('krbmror_llength_bytes: ' ||
       nvl(to_char(krbmror_llength_bytes), 'NULL'));
   deb('last_ic_recid: ' || nvl(to_char(last_ic_recid), 'NULL'));
   deb('last_reset_scn: ' || nvl(to_char(last_reset_scn), 'NULL'));
   deb('last_dbinc_key: ' || nvl(to_char(last_dbinc_key), 'NULL'));
   deb('low_nrsp_recid: ' || nvl(to_char(low_nrsp_recid), 'NULL'));
   deb('last_nrsp_recid: ' || nvl(to_char(last_nrsp_recid), 'NULL'));
   deb('last_grsp_recid: ' || nvl(to_char(last_grsp_recid), 'NULL'));
   deb('last_bcr_recid: ' || nvl(to_char(last_bcr_recid), 'NULL'));
   deb('last_pdb_recid: ' || nvl(to_char(last_pdb_recid), 'NULL'));
   deb('last_resync_cksum: ' || nvl(to_char(last_resync_cksum), 'NULL'));
 
   deb('Date variables');
   deb('this_ckp_time: ' ||
       nvl(to_char(this_ckp_time, 'DD/MM/YYYY HH24:MI:SS'), 'NULL'));
   deb('last_reset_time: ' ||
       nvl(to_char(last_reset_time, 'DD/MM/YYYY HH24:MI:SS'), 'NULL'));
   deb('last_cf_version_time: ' ||
        nvl(to_char(last_cf_version_time, 'DD/MM/YYYY HH24:MI:SS'), 'NULL'));
 
   deb('Char variables');
   deb('last_fname: ' || nvl(last_fname, 'NULL'));
   deb('last_rspname: '|| nvl(last_rspname, 'NULL'));         
   deb('last_pdb_key: '|| last_pdb_key);
   deb('this_cf_type: '|| nvl(this_cf_type, 'NULL'));
   deb('this_db_unique_name: ' || nvl(this_db_unique_name, 'NULL'));
 
   deb('Boolean variables');
   if debug is NULL then
      deb('debug is NULL');
   elsif scr_glob then
      deb('debug is TRUE');
   else
      deb('debug is FALSE');
   end if;
 
   if client_site_aware is NULL then
      deb('client_site_aware is NULL');
   elsif client_site_aware then
      deb('client_site_aware is TRUE');
   else
      deb('client_site_ware is FALSE');
   end if;
 
   if scr_glob is NULL then
      deb('scr_glob is NULL');
   elsif scr_glob then
      deb('scr_glob is TRUE');
   else
      deb('scr_glob is FALSE');
   end if;
 
   if do_temp_ts_resync is NULL then
      deb('do_temp_ts_resync is NULL');
   elsif do_temp_ts_resync then
      deb('do_temp_ts_resync is TRUE');
   else
      deb('do_temp_ts_resync is FALSE');
   end if;
end dumpPkgState;
 
/*--------------------------------------------------*
 * package private fns required for recover server  *
 *--------------------------------------------------*/
PROCEDURE read_from_http(resp IN OUT utl_http.resp, clobvar IN OUT CLOB) IS
   data raw(1024);
   pos Integer;
   amt Binary_Integer;
BEGIN
   dbms_lob.createtemporary(clobvar, TRUE);
   pos := 1;
   BEGIN
      LOOP
         utl_http.read_raw(resp, data);
         amt := length(utl_raw.cast_to_varchar2(data)); 
         dbms_lob.write(clobvar, amt, pos, utl_raw.cast_to_varchar2(data));
         pos := pos + amt;
      END LOOP;
   EXCEPTION
      WHEN utl_http.end_of_body THEN
      NULL;
   END;
END;
 
PROCEDURE display_http_response(resp IN OUT utl_http.resp) IS
   hdrcnt integer;
   name varchar2(256);
   value varchar2(256);
BEGIN
   IF not debug THEN
      RETURN;
   END IF;
   hdrcnt := utl_http.get_header_count(resp);
   deb('^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ');
   deb('Response header count = ' || hdrcnt);
   deb('^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ');
   loop
      exit when hdrcnt = 0;
      utl_http.get_header(resp, hdrcnt, name, value);
      deb('Hdr# '|| hdrcnt || ' Name= ' || name || 
                           ' Value= ' || value);
      hdrcnt := hdrcnt - 1;
   end loop;
END;
 
PROCEDURE display_clob(val IN CLOB) IS
   buf varchar2(2048 CHAR);
   origlen integer;
   len integer;
   pos integer;
   amt integer;
BEGIN
   IF not debug THEN
      RETURN;
   END IF;
   deb('DISPLAY_CLOB BEGIN');
   amt := 2048; -- amount to read at a time
   len := dbms_lob.getlength(val);
   origlen := len;
   deb('xmlfile len = ' || len);
   pos := 1;
   loop
      exit when pos > origlen;
      if len < amt then
         dbms_lob.read(val, len, pos, buf);
         pos := pos + len;
      else
         dbms_lob.read(val, amt, pos, buf);
         len := len - amt;
         pos := pos + amt;
      end if;
--
--
--
   end loop;
   deb('DISPLAY_CLOB END');
END;
 
FUNCTION get_Complete_URL (bktname in varchar2,
                           objname in varchar2,
                           awsr    OUT varchar2,
                           parms   in varchar2 DEFAULT null) 
RETURN VARCHAR2 IS
   complete_url varchar2(2048);
   aws_resource varchar2(512);
BEGIN
   IF this_amazon_server THEN
     complete_url := bktname || '.' || this_server_url;
   ELSE
     complete_url := this_server_url || '/orssv';
     aws_resource := '/orssv';
   END IF;
 
   IF this_server_url IS NULL THEN
      raise_application_error(-20999, 'internal error:this_server_url');
   END IF;
 
   IF this_url_db_unique_name IS NULL THEN
      raise_application_error(-20999, 'internal error:this_url_db_unique_name');
   END IF;
 
   complete_url := complete_url || '/rcfile/' || objname || '?' || 
                   'x-DBUName=' || this_url_db_unique_name;
   if parms is not null then
      complete_url := complete_url || '&' || parms;
   end if;
 
   aws_resource := aws_resource || '/rcfile/' || objname;
   awsr := aws_resource;
 
   IF debug THEN
      deb('URL=' || complete_url);
      deb('awsr=' || awsr);
   END IF;
   RETURN complete_url;
END get_Complete_URL;
 
/*----------------------------------------------------*
 * package public fns required for recover server     *
 * The concept of bucket is used only for amazon S3   *
 *----------------------------------------------------*/
PROCEDURE put_bucket(bktname in varchar2) IS
   objval CLOB := NULL;
BEGIN
   IF this_amazon_server THEN
     put_object(bktname, null, null, objval);
   END IF;
END;
 
FUNCTION get_bucket(bktname in varchar2) RETURN CLOB IS
BEGIN
   IF this_amazon_server THEN
      return get_object(bktname, null);
   END IF;
   return NULL;
END;
 
PROCEDURE delete_bucket(bktname in varchar2) IS
BEGIN
   IF this_amazon_server THEN
      delete_object(bktname, null);
   END IF;
END;
 
PROCEDURE utl_httl_12cR1fns(req IN OUT utl_http.req, awsr IN VARCHAR2) IS
BEGIN
   $IF DBMS_DB_VERSION.VERSION < 12 $THEN
      raise_application_error(-20999,
         'internal error: not support database version');
   $ELSE
      IF this_amazon_server then
         execute immediate 'begin utl_http.set_property(
                               :req,  
                               ''aws-canonicalized-resource'', :awsr); end;'
                 using in out req, in awsr;
         deb('sqlcode after set_property on: ' || sqlcode);
 
         execute immediate ' begin 
                                 utl_http.set_authentication_from_wallet(
                                                  r      => :req, 
                                                  alias  => :wallet_alias,
                                                  scheme => ''AWS''); end;'
                  using in out req, in this_server.wallet_alias;
         deb('sqlcode after set_authentication_from_wallet on: ' || sqlcode);
      ELSE
         execute immediate ' begin 
                                utl_http.set_authentication(
                                                 r        => :req,
                                                 username => :username,
                                                 password => :password,
                                                 scheme   => ''Digest''); end;'
                 using in out req, in this_server_uname,
                       in this_server_passw;
         deb('sqlcode after set_authentication on: ' || sqlcode);
      END IF;
   $END
END;
 
PROCEDURE put_object(bktname in varchar2, 
                     objname in varchar2,
                     objtype in varchar2,
                     objval in out CLOB) is
   req utl_http.req;
   resp utl_http.resp;
   len Integer;
   pos Integer;
   amt Integer;
   origlen Integer;
   buf raw(2048);
   cbuf varchar2(2048 CHAR);
   local_response_val CLOB;
   ct timestamp(0);
   cdt varchar2(50);
   awsr varchar2(512);
   timeout_secs number;
   retries      number := -1;
 
BEGIN
 
   IF this_server.server_host IS NULL THEN
      deb('put_object: this_server.server_host is null');
      return;
   END IF;
 
   deb('Enter put_object ' || objname);
 
   timeout_secs := this_server.timeout_secs;
 
<<retry_request_again>>
 
   BEGIN
      retries := retries + 1;
      deb('retries count is ' || retries);
      timeout_secs := timeout_secs + retries * timeout_secs;
 
      select sys_extract_utc(current_timestamp) into ct from dual;
      cdt := to_char(ct, 'Dy, DD Mon YYYY HH24:MI:SS') || ' GMT';
 
      utl_http.set_transfer_timeout(timeout_secs);
      req := utl_http.begin_request(get_Complete_URL(bktname, objname, awsr), 
                                    'PUT', utl_http.HTTP_VERSION_1_1);
 
      utl_http.set_header(req, 'Date', cdt);
      if objname is not null then
         utl_http.set_header(req, 'Content-Type', objtype);
      end if;
      
      utl_httl_12cR1fns( req, awsr);
 
      IF objname is null THEN
         utl_http.set_header(req, 'Content-Length', 0);
      ELSE
         dbms_lob.open(objval, dbms_lob.lob_readonly);
         len := dbms_lob.getlength(objval);
         deb('Content-length = ' || len);
         utl_http.set_header(req, 'Content-Length',len);
         origlen := len;
         amt := 2048;
         pos := 1;
         if lower(objtype) = 'text/xml' then
            loop
               exit when pos > origlen;
               if len < amt then
                  dbms_lob.read(objval, len, pos, cbuf);
                  pos := pos + len;
               else
                  dbms_lob.read(objval, amt, pos, cbuf);
                  len := len - amt;
                  pos := pos + amt;
               end if;
               utl_http.write_raw(req, utl_raw.cast_to_raw(cbuf));
            end loop;
         ELSE
            loop
               exit when pos > origlen;
               if len < amt then
                  dbms_lob.read(objval, len, pos, buf);
                  pos := pos + len;
               else
                  dbms_lob.read(objval, amt, pos, buf);
                  len := len - amt;
                  pos := pos + amt;
               end if;
               utl_http.write_raw(req, buf);
            end loop;
         end if;
         dbms_lob.close(objval);
      END IF;
 
      resp := utl_http.get_response(req);
 
      display_http_response(resp);
 
      read_from_http(resp, local_response_val);
      display_clob(local_response_val);
 
      utl_http.end_response(resp);
      deb('Exit put_object');
 
   EXCEPTION
      WHEN Utl_Http.request_failed THEN
         deb ('Request_Failed:' || 
                               Utl_Http.get_detailed_sqlerrm);
         Utl_Http.end_request (req);
      WHEN Utl_Http.http_server_error THEN
         deb ('Http_Server_Error: ' ||
                               Utl_Http.get_detailed_sqlerrm);
         Utl_Http.end_request (req);
      WHEN Utl_Http.http_client_error THEN
         deb ('Http_Client_Error: ' || 
                               Utl_Http.get_detailed_sqlerrm);
         Utl_Http.end_request (req);
      WHEN OTHERS THEN
         deb('HTTP Other error:' || sqlerrm);
         if retries <= 5 and substr(sqlerrm, 1, 9)  = 'ORA-29276' then
            goto retry_request_again;
         else
            raise;
         end if;
   END;
END put_object;
 
PROCEDURE delete_object(bktname in varchar2, objname in varchar2) is
   req utl_http.req;
   resp utl_http.resp;
   tmpfile CLOB := NULL;
   ct timestamp(0);
   cdt varchar2(50);
   awsr varchar2(512);
BEGIN
 
   IF this_server.server_host IS NULL THEN
      deb('delete_object: this_server.server_host is null');
      return;
   END IF;
 
   deb('Enter delete_object');
 
   select sys_extract_utc(current_timestamp) into ct from dual;
   cdt := to_char(ct, 'Dy, DD Mon YYYY HH24:MI:SS') || ' GMT';
 
   utl_http.set_transfer_timeout(this_server.timeout_secs);
   req := utl_http.begin_request(get_Complete_URL(bktname, objname, awsr), 
                                 'DELETE', utl_http.HTTP_VERSION_1_1);
 
   utl_http.set_header(req, 'Date', cdt);
      
   utl_httl_12cR1fns( req, awsr);
 
   resp := utl_http.get_response(req);
   display_http_response(resp);
 
   read_from_http(resp, tmpfile);
   display_clob(tmpfile);
 
   utl_http.end_response(resp);
   deb('Exit delete_object');
 
EXCEPTION
   WHEN Utl_Http.request_failed THEN
      deb ('Request_Failed:' || 
                            Utl_Http.get_detailed_sqlerrm);
      Utl_Http.end_request (req);
   WHEN Utl_Http.http_server_error THEN
      deb ('Http_Server_Error: ' ||
                            Utl_Http.get_detailed_sqlerrm);
      Utl_Http.end_request (req);
   WHEN Utl_Http.http_client_error THEN
      deb ('Http_Client_Error: ' || 
                            Utl_Http.get_detailed_sqlerrm);
      Utl_Http.end_request (req);
      return;
   WHEN OTHERS THEN
      deb('HTTP Other error: ' || sqlerrm);
      raise;
END delete_object;
 
FUNCTION get_object(bktname in varchar2, 
                    objname in varchar2,
                    parms   in varchar2 DEFAULT null) return CLOB is
   req          utl_http.req;
   resp         utl_http.resp;
   objval       CLOB := NULL;
   ct           timestamp(0);
   cdt          varchar2(50);
   awsr         varchar2(512);
   timeout_secs number;
   retries      number := -1;
 
begin
 
   IF this_server.server_host IS NULL THEN
      deb('get_object: this_server.server_host is null');
      return NULL;
   END IF;
 
   deb('Enter get_object ' || objname);
 
   timeout_secs := this_server.timeout_secs;
 
<<retry_request_again>>
 
   BEGIN
      retries := retries + 1;
      deb('retries count is ' || retries);
      timeout_secs := timeout_secs + retries * timeout_secs;
 
 
      select sys_extract_utc(current_timestamp) into ct from dual;
      cdt := to_char(ct, 'Dy, DD Mon YYYY HH24:MI:SS') || ' GMT';
 
      utl_http.set_transfer_timeout(timeout_secs);
      req := utl_http.begin_request(
                                  get_Complete_URL(bktname,objname,awsr,parms),
                                  'GET', utl_http.HTTP_VERSION_1_1);
 
      utl_http.set_header(req, 'Date', cdt);
      utl_httl_12cR1fns( req, awsr);
      resp := utl_http.get_response(req);
      display_http_response(resp);
 
      read_from_http(resp, objval);
      display_clob(objval);
 
      utl_http.end_response(resp);
 
      IF dbms_lob.getlength(objval) > 0 then
         IF objname is null THEN
            delete from rcfile where name = parms;
            insert into rcfile(rcfile_key, creation_time, name, xmldoc)
               values (rman_seq.nextval, sys_extract_utc(systimestamp), parms, 
                       XMLType.createXML(objval));
            deb('got rows for ' || parms);
            commitChanges('get_object-1');
         ELSE
            delete from rcfile where name = objname;
            insert into rcfile(rcfile_key, creation_time, name, xmldoc)
               values (rman_seq.nextval, sys_extract_utc(systimestamp),objname,
                       XMLType.createXML(objval));
            deb('got rows for ' || objname);
            commitChanges('get_object-2');
         END IF;
      END IF;
      deb('Exit get_object');
   
   return objval;
   EXCEPTION
      WHEN Utl_Http.request_failed THEN
         deb ('Request_Failed:' || 
                               Utl_Http.get_detailed_sqlerrm);
         Utl_Http.end_request (req);
      WHEN Utl_Http.http_server_error THEN
         deb ('Http_Server_Error: ' ||
                               Utl_Http.get_detailed_sqlerrm);
         Utl_Http.end_request (req);
      WHEN Utl_Http.http_client_error THEN
         deb ('Http_Client_Error: ' || 
                               Utl_Http.get_detailed_sqlerrm);
         Utl_Http.end_request (req);
      WHEN OTHERS THEN
         deb('HTTP Other error: ' || sqlerrm);
         if retries <= 5 and substr(sqlerrm, 1, 9)  = 'ORA-29276' then
            goto retry_request_again;
         else
            raise;
         end if;
   END;
END get_object;
 
PROCEDURE displayRCWatermarks(cmt IN VARCHAR2, wmrec IN RC_WATERMARKS%ROWTYPE) IS
BEGIN
   IF NOT debug THEN
      RETURN;
   END IF;
 
   deb(cmt || 'DB_KEY=' || wmrec.DB_KEY);
   deb(cmt || 'DB_UNIQUE_NAME=' || wmrec.DB_UNIQUE_NAME);
   deb(cmt || 'RS_VERSION_STAMP=' || wmrec.RS_VERSION_STAMP);
   deb(cmt || 'HIGH_BP_RECID=' || wmrec.HIGH_BP_RECID);
   deb(cmt || 'HIGH_DO_KEY=' || wmrec.HIGH_DO_KEY);
   deb(cmt || 'CF_VERSION_STAMP=' || wmrec.CF_VERSION_STAMP);
   deb(cmt || 'HIGH_DF_RECID=' || wmrec.HIGH_DF_RECID);
   deb(cmt || 'HIGH_TS_RECID=' || wmrec.HIGH_TS_RECID);
   deb(cmt || 'HIGH_TF_RECID=' || wmrec.HIGH_TF_RECID);
   deb(cmt || 'HIGH_OFFR_RECID=' || wmrec.HIGH_OFFR_RECID);
END displayRCWatermarks;
 
PROCEDURE displayRCSite(cmt IN VARCHAR2, siterec IN RC_SITE%ROWTYPE) IS
BEGIN
   IF NOT debug THEN
      RETURN;
   END IF;
 
   deb(cmt || 'SITE_KEY=' || siterec.SITE_KEY);
   deb(cmt || 'DB_KEY=' || siterec.DB_KEY);
   deb(cmt || 'DATABASE_ROLE=' || siterec.DATABASE_ROLE);
   deb(cmt || 'CF_CREATE_TIME=' || siterec.CF_CREATE_TIME);
   deb(cmt || 'DB_UNIQUE_NAME=' || siterec.DB_UNIQUE_NAME);
   deb(cmt || 'HIGH_CONF_RECID=' || siterec.HIGH_CONF_RECID);
   deb(cmt || 'FORCE_RESYNC2CF=' || siterec.FORCE_RESYNC2CF);
   deb(cmt || 'HIGH_ROUT_STAMP=' || siterec.HIGH_ROUT_STAMP);
   deb(cmt || 'INST_STARTUP_STAMP=' || siterec.INST_STARTUP_STAMP);
   deb(cmt || 'LAST_KCCDIVTS=' || stamp2date(siterec.LAST_KCCDIVTS));
   deb(cmt || 'HIGH_IC_RECID=' || siterec.HIGH_IC_RECID);
   deb(cmt || 'DBINC_KEY=' || siterec.DBINC_KEY);
   deb(cmt || 'CKP_SCN=' || siterec.CKP_SCN);
   deb(cmt || 'FULL_CKP_CF_SEQ=' || siterec.FULL_CKP_CF_SEQ);
   deb(cmt || 'JOB_CKP_CF_SEQ=' || siterec.JOB_CKP_CF_SEQ);
   deb(cmt || 'HIGH_TS_RECID=' || siterec.HIGH_TS_RECID);
   deb(cmt || 'HIGH_DF_RECID=' || siterec.HIGH_DF_RECID);
   deb(cmt || 'HIGH_RT_RECID=' || siterec.HIGH_RT_RECID);
   deb(cmt || 'HIGH_ORL_RECID=' || siterec.HIGH_ORL_RECID);
   deb(cmt || 'HIGH_OFFR_RECID=' || siterec.HIGH_OFFR_RECID);
   deb(cmt || 'HIGH_RLH_RECID=' || siterec.HIGH_RLH_RECID);
   deb(cmt || 'HIGH_AL_RECID=' || siterec.HIGH_AL_RECID);
   deb(cmt || 'HIGH_BS_RECID=' || siterec.HIGH_BS_RECID);
   deb(cmt || 'HIGH_BP_RECID=' || siterec.HIGH_BP_RECID);
   deb(cmt || 'HIGH_BDF_RECID=' || siterec.HIGH_BDF_RECID);
   deb(cmt || 'HIGH_CDF_RECID=' || siterec.HIGH_CDF_RECID);
   deb(cmt || 'HIGH_BRL_RECID=' || siterec.HIGH_BRL_RECID);
   deb(cmt || 'HIGH_BCB_RECID=' || siterec.HIGH_BCB_RECID);
   deb(cmt || 'HIGH_CCB_RECID=' || siterec.HIGH_CCB_RECID);
   deb(cmt || 'HIGH_DO_RECID=' || siterec.HIGH_DO_RECID);
   deb(cmt || 'HIGH_PC_RECID=' || siterec.HIGH_PC_RECID);
   deb(cmt || 'HIGH_BSF_RECID=' || siterec.HIGH_BSF_RECID);
   deb(cmt || 'HIGH_RSR_RECID=' || siterec.HIGH_RSR_RECID);
   deb(cmt || 'HIGH_TF_RECID=' || siterec.HIGH_TF_RECID);
   deb(cmt || 'HIGH_GRSP_RECID=' || siterec.HIGH_GRSP_RECID);
   deb(cmt || 'HIGH_NRSP_RECID=' || siterec.HIGH_NRSP_RECID);
   deb(cmt || 'HIGH_BCR_RECID=' || siterec.HIGH_BCR_RECID);
   deb(cmt || 'LOW_BCR_RECID=' || siterec.LOW_BCR_RECID);
   deb(cmt || 'BCR_IN_USE=' || siterec.BCR_IN_USE);
   deb(cmt || 'HIGH_PDB_RECID=' || siterec.HIGH_PDB_RECID);
   deb(cmt || 'HIGH_PIC_RECID=' || siterec.HIGH_PIC_RECID);
END displayRCSite;
 
PROCEDURE displayRCDatabaseIncarnation
   (cmt IN VARCHAR2, icrec IN RC_DATABASE_INCARNATION%ROWTYPE) IS
BEGIN
   IF NOT debug THEN
      RETURN;
   END IF;
 
   deb(cmt || 'DB_KEY=' || icrec.DB_KEY); 
   deb(cmt || 'DBID=' || icrec.DBID); 
   deb(cmt || 'DBINC_KEY=' || icrec.DBINC_KEY);  
   deb(cmt || 'NAME=' || icrec.NAME); 
   deb(cmt || 'RESETLOGS_CHANGE#=' || icrec.RESETLOGS_CHANGE#); 
   deb(cmt || 'RESETLOGS_TIME=' || icrec.RESETLOGS_TIME);
   deb(cmt || 'CURRENT_INCARNATION=' || icrec.CURRENT_INCARNATION);
   deb(cmt || 'PARENT_DBINC_KEY=' || icrec.PARENT_DBINC_KEY); 
   deb(cmt || 'PRIOR_RESETLOGS_CHANGE#=' || icrec.PRIOR_RESETLOGS_CHANGE#);
   deb(cmt || 'PRIOR_RESETLOGS_TIME=' || icrec.PRIOR_RESETLOGS_TIME);
   deb(cmt || 'STATUS=' || icrec.STATUS);
   deb(cmt || 'REG_DB_UNIQUE_NAME=' || icrec.REG_DB_UNIQUE_NAME);
   deb(cmt || 'CON_ID=' || icrec.CON_ID);
   deb(cmt || 'GUID=' || icrec.GUID);
END displayRCDatabaseIncarnation;
 
PROCEDURE writeForWatermarks(bktname   IN VARCHAR2 DEFAULT NULL,
                             full_ckpt IN BOOLEAN) IS
   v_ctx     DBMS_XMLGen.ctxHandle;
   v_xml     CLOB;
   v_xml_tmp CLOB;
   type record_sql_type is table of varchar2(2048) 
             index by binary_integer;
   type record_tbl_type is table of varchar2(30) 
             index by binary_integer;
   record_sql  record_sql_type;
   record_tbl  record_tbl_type;
   my_dbid      number;
   write_xml_filename rcfile.name%TYPE;
 
BEGIN
--
   IF this_server.server_host IS NULL THEN
      deb('writeForWaterMarks: this_server.server_host is null');
      return;
   END IF;
 
   IF (this_db_key IS NULL) THEN
      raise_application_error(-20021, 'Database not set');
   END IF;
 
   SELECT DBID INTO MY_DBID FROM RC_DATABASE WHERE DB_KEY=this_db_key;
 
   record_tbl(0)   := 'RC_DATABASE';
   record_sql(0)   := 'SELECT * FROM RC_DATABASE ' || 
                              'WHERE DB_KEY = ' || this_db_key;
 
   record_tbl(1)   := 'RC_DATABASE_INCARNATION';
   record_sql(1)   := 'SELECT * FROM RC_DATABASE_INCARNATION ' ||
                              'WHERE DB_KEY = ' || this_db_key;
 
   record_tbl(2)   := 'RC_SITE';
   IF full_ckpt THEN
      deb('writeForWatermarks for remote readFixedSections');
--
--
--
      record_sql(2)   := 'SELECT -1 high_bp_recid FROM RCI_SITE ' ||
                            'WHERE DB_KEY   = ' || this_db_key ||
                            '  AND SITE_KEY = ' || this_site_key;
   ELSE
      deb('writeForWatermarks for local readBackupSections');
      record_sql(2)   := 'SELECT * FROM RCI_SITE ' ||
                            'WHERE DB_KEY   = ' || this_db_key ||
                            '  AND SITE_KEY = ' || this_site_key;
   END IF;
 
   v_xml := this_xml_signature_beg;
   dbms_session.set_nls('NLS_DATE_FORMAT','''DD-MM-YYYY HH24:MI:SS''');
 
   FOR idx in 0..2 LOOP
      deb('writing XML file for ' || idx);
      deb('executing query:'|| record_sql(idx));
 
      v_ctx := DBMS_XMLGen.newContext(record_sql(idx));
 
--
      DBMS_XMLGen.setRowsetTag(v_ctx, 'TABLE_' || record_tbl(idx));
      v_xml_tmp := DBMS_XMLGen.GetXML(v_ctx);
      DBMS_XMLGen.closeContext(v_ctx);
 
      deb('XML len for ' || idx || '=' || DBMS_LOB.GETLENGTH(v_xml_tmp));
      IF v_xml_tmp IS NOT NULL THEN
         DBMS_LOB.COPY(v_xml, v_xml_tmp, DBMS_LOB.LOBMAXSIZE, 
                       DBMS_LOB.GETLENGTH(v_xml),
                       DBMS_LOB.INSTR(v_xml_tmp, 
                                  '<TABLE_' || record_tbl(idx) ||'>'));
      END IF;
   END LOOP;
 
   v_xml := v_xml || this_xml_signature_end;
 
   write_xml_filename := this_forwatermarks || my_dbid || '.xml';
   put_bucket(bktname);
   put_object(bktname, write_xml_filename, 'text/xml', v_xml);
 
END writeForWatermarks;
 
PROCEDURE rsReadWaterMarks(bktname  IN VARCHAR2 DEFAULT NULL) IS
   xml_filename RCFILE.NAME%TYPE;
   my_dbid      NUMBER;
   v_xml_tmp    CLOB;
   v_ctx        DBMS_XMLGen.ctxHandle;
   verrec       RC_RCVER%ROWTYPE;
   curr_inc     RC_DATABASE_INCARNATION%ROWTYPE;
   wmrec        RC_WATERMARKS%ROWTYPE;
 
   CURSOR rc_rcver_c IS
   SELECT VERSION
   FROM "_RS_RC_RCVER_"
   WHERE RS_RCFILE_NAME = xml_filename;
 
   CURSOR rc_watermarks_c IS
   SELECT DB_KEY,
          DB_UNIQUE_NAME,
          RS_VERSION_STAMP,
          HIGH_BP_RECID,
          HIGH_DO_KEY,
          CF_VERSION_STAMP,
          HIGH_DF_RECID,
          HIGH_TS_RECID,
          HIGH_TF_RECID,
          HIGH_OFFR_RECID
   FROM "_RS_RC_WATERMARKS_"
   WHERE RS_RCFILE_NAME = xml_filename;
 
   CURSOR rc_database_incarnation_c IS
   SELECT DB_KEY, 
          DBID, 
          DBINC_KEY,  
          NAME, 
          RESETLOGS_CHANGE#, 
          RESETLOGS_TIME,
          CURRENT_INCARNATION,
          PARENT_DBINC_KEY, 
          PRIOR_RESETLOGS_CHANGE#,
          PRIOR_RESETLOGS_TIME,
          STATUS,
          REG_DB_UNIQUE_NAME,
          CON_ID,
          GUID
   FROM "_RS_RC_DATABASE_INCARNATION_"
   WHERE RS_RCFILE_NAME = xml_filename
     AND STATUS = 'CURRENT';
 
   upstream_dbrec RCI_RA_UPSTREAM_DATABASE%ROWTYPE;
   CURSOR rci_ra_upstream_database_c IS
   SELECT  DBID,
           NAME
   FROM "_RS_RCI_RA_UPSTREAM_DATABASE_"
   WHERE RS_RCFILE_NAME = xml_filename;
 
   CURSOR local_current_incarnation_c IS
   SELECT *
   FROM RC_DATABASE_INCARNATION
   WHERE DBINC_KEY = this_dbinc_key;
   local_curr_inc RC_DATABASE_INCARNATION%ROWTYPE;
 
BEGIN
 
--
   IF this_server.server_host IS NULL THEN
      deb('rsReadWaterMarks: this_server.server_host is null');
      return;
   END IF;
 
   IF (this_db_key IS NULL) THEN
      raise_application_error(-20021, 'Database not set');
   END IF;
 
   SELECT DBID INTO MY_DBID FROM RC_DATABASE
      WHERE DB_KEY=this_db_key;
 
--
--
   xml_filename := this_watermarks || my_dbid || '.xml';
   v_xml_tmp := get_object(bktname, xml_filename);
 
--
   dbms_session.set_nls('NLS_DATE_FORMAT','''DD-MM-YYYY HH24:MI:SS''');
 
--
   OPEN rc_rcver_c;
   FETCH rc_rcver_c INTO verrec;
   CLOSE rc_rcver_c;
 
--
   OPEN rc_watermarks_c;
   FETCH rc_watermarks_c INTO wmrec;
   CLOSE rc_watermarks_c;
 
--
   OPEN rc_database_incarnation_c;
   FETCH rc_database_incarnation_c INTO curr_inc;
   CLOSE rc_database_incarnation_c;
 
--
   OPEN local_current_incarnation_c;
   FETCH local_current_incarnation_c INTO local_curr_inc;
   CLOSE local_current_incarnation_c;
 
--
   OPEN rci_ra_upstream_database_c;
   FETCH rci_ra_upstream_database_c INTO upstream_dbrec;
   CLOSE rci_ra_upstream_database_c;
 
--
   IF curr_inc.dbid <> rsReadWaterMarks.my_dbid THEN
      raise_application_error(-20141, 
                 'Target database id mismatch with registered database in ORS');
   END IF;
 
--
--
--
--
   v_ctx := DBMS_XMLGen.newContext('SELECT DB_KEY, DB_UNIQUE_NAME, ' ||
                'RS_VERSION_STAMP,'||
                'HIGH_BP_RECID,'||
                'HIGH_DO_KEY, CF_VERSION_STAMP,'||
                'HIGH_DF_RECID, '||
                'HIGH_TS_RECID, HIGH_TF_RECID, HIGH_OFFR_RECID '||
                'FROM "_RS_RC_WATERMARKS_" '||
                'WHERE RS_RCFILE_NAME = ''' || xml_filename || '''');
 
--
   DBMS_XMLGen.setRowsetTag(v_ctx, 'TABLE_RC_WATERMARKS');
   this_v_wmrec := DBMS_XMLGen.GetXML(v_ctx);
   DBMS_XMLGen.closeContext(v_ctx);
 
   IF upstream_dbrec.name IS NULL THEN
      raise_application_error(-20999, 'internal error: no rows for upstreamdb');
   END IF;
 
   this_verrec := verrec;
   this_curr_inc := curr_inc;
   this_wmrec  := wmrec;
   this_upstream_dbrec := upstream_dbrec;
 
   IF debug THEN
      deb('rsReadWatermarks: remote reconcile dbname=' || 
           this_upstream_dbrec.name);
      deb('this_curr_inc.dbid: ' || this_curr_inc.dbid);
 
      displayRCWatermarks('rsReadWatermarks remote:', this_wmrec);
      displayRCDatabaseIncarnation('rsReadWatermarks remote:', curr_inc);
      displayRCDatabaseIncarnation('rsReadWatermarks local:', local_curr_inc);
   END IF;
 
   
--
--
   IF curr_inc.resetlogs_change# <> local_curr_inc.resetlogs_change# OR
      curr_inc.resetlogs_time <> local_curr_inc.resetlogs_time THEN
      deb('Clearing this_wmrec.cf_version_stamp so all fixed records are sent');
      this_wmrec.cf_version_stamp := NULL;
   END IF;
 
END rsReadWaterMarks;
 
--
PROCEDURE rsWriteWaterMarks (input_xml_filename  IN VARCHAR2,
                             bktname IN VARCHAR2 DEFAULT NULL) IS
   v_ctx     DBMS_XMLGen.ctxHandle;
   v_xml     CLOB;
   v_xml_tmp CLOB;
   type record_sql_type is table of varchar2(2048) 
             index by binary_integer;
   type record_tbl_type is table of varchar2(30) 
             index by binary_integer;
   record_sql  record_sql_type;
   record_tbl  record_tbl_type;
   my_dbid      number;
   l_max_do_key number;
   l_high_do_key number;
 
   write_xml_filename rcfile.name%TYPE;
 
   curr_inc RC_DATABASE_INCARNATION%ROWTYPE;
   CURSOR rc_database_incarnation_c(curr_inc_val IN VARCHAR2 DEFAULT NULL) IS
   SELECT DB_KEY, 
          DBID, 
          DBINC_KEY,  
          NAME, 
          RESETLOGS_CHANGE#, 
          RESETLOGS_TIME,
          CURRENT_INCARNATION,
          PARENT_DBINC_KEY, 
          PRIOR_RESETLOGS_CHANGE#,
          PRIOR_RESETLOGS_TIME,
          STATUS,
          REG_DB_UNIQUE_NAME,
          CON_ID,
          GUID
   FROM "_RS_RC_DATABASE_INCARNATION_"
   WHERE RS_RCFILE_NAME = input_xml_filename
     AND (curr_inc_val IS NULL OR
          CURRENT_INCARNATION = curr_inc_val);
 
   CURSOR rc_site_c IS
   SELECT  SITE_KEY,
           DB_KEY,
           DATABASE_ROLE,
           CF_CREATE_TIME,
           DB_UNIQUE_NAME,
           HIGH_CONF_RECID,
           FORCE_RESYNC2CF,
           HIGH_ROUT_STAMP,
           INST_STARTUP_STAMP,
           LAST_KCCDIVTS,
           HIGH_IC_RECID,
           DBINC_KEY,
           CKP_SCN,
           FULL_CKP_CF_SEQ,
           JOB_CKP_CF_SEQ,
           HIGH_TS_RECID,
           HIGH_DF_RECID,
           HIGH_RT_RECID,
           HIGH_ORL_RECID,
           HIGH_OFFR_RECID,
           HIGH_RLH_RECID,
           HIGH_AL_RECID,
           HIGH_BS_RECID,
           HIGH_BP_RECID,
           HIGH_BDF_RECID,
           HIGH_CDF_RECID,
           HIGH_BRL_RECID,
           HIGH_BCB_RECID,
           HIGH_CCB_RECID,
           HIGH_DO_RECID,
           HIGH_PC_RECID,
           HIGH_BSF_RECID,
           HIGH_RSR_RECID,
           HIGH_TF_RECID,
           HIGH_GRSP_RECID,
           HIGH_NRSP_RECID,
           HIGH_BCR_RECID,
           LOW_BCR_RECID,
           BCR_IN_USE,
           HIGH_PDB_RECID,
           HIGH_PIC_RECID
   FROM "_RS_RC_SITE_"
   WHERE RS_RCFILE_NAME = input_xml_filename;
 
   l_stmts   NUMBER;
 
BEGIN
 
--
   my_dbid := to_number(substr(input_xml_filename, 
                               length(this_forwatermarks)+1, 
                               instr(input_xml_filename,'.xml')-1
                                     -length(this_forwatermarks)));
 
   deb('rsWriteWaterMarks:remote my_dbid=' || my_dbid);
 
--
   dbms_session.set_nls('NLS_DATE_FORMAT','''DD-MM-YYYY HH24:MI:SS''');
 
--
   OPEN rc_database_incarnation_c(curr_inc_val => 'YES');
   FETCH rc_database_incarnation_c INTO curr_inc;
   CLOSE rc_database_incarnation_c;
 
--
   OPEN rc_site_c;
   FETCH rc_site_c INTO this_rsiterec;
   CLOSE rc_site_c;
   IF debug THEN
      displayRCSite('rsWriteWaterMarks:remote ', this_rsiterec);
   END IF;
 
--
   IF curr_inc.dbid <> my_dbid THEN
      raise_application_error(-20141, 
                 'Target database id mismatch with registered database in ORS');
   END IF;
 
 
   record_tbl(0)   := 'RCI_RA_UPSTREAM_DATABASE';
   record_sql(0)   := 'SELECT * FROM RCI_RA_UPSTREAM_DATABASE';
 
   record_tbl(1)   := 'RC_RCVER';
   record_sql(1)   := 'SELECT * FROM RC_RCVER ';
 
 
   l_stmts  := 1;
 
--
   BEGIN
      SELECT DB_KEY INTO this_db_key FROM DB
         WHERE db_id = my_dbid;
 
      deb('rsWriteWaterMarks:this_db_key=' || this_db_key);
 
--
      dbms_session.set_nls('NLS_DATE_FORMAT','''DD-MM-YYYY HH24:MI:SS''');
 
 
      record_tbl(2)   := 'RC_DATABASE_INCARNATION';
      record_sql(2)   := 'SELECT * FROM RC_DATABASE_INCARNATION ' || 
                            'WHERE DB_KEY = ' || this_db_key;
 
      record_tbl(3)   := 'RC_WATERMARKS';
      record_sql(3)   := 'SELECT * FROM RC_WATERMARKS ' || 
                            'WHERE DB_KEY = ' || this_db_key;
 
      l_stmts  := 3;
 
--
      BEGIN
         SELECT high_do_key INTO l_high_do_key 
            FROM watermarks WHERE db_key = this_db_key;
         SELECT curr_value INTO l_max_do_key 
            FROM do_seq WHERE db_key = this_db_key;
         IF l_max_do_key > l_high_do_key THEN
            UPDATE watermarks
               SET high_do_key = l_max_do_key
               WHERE db_key = this_db_key;
            commitChanges('rsWritewaterMarks, set high_do_key='||l_max_do_key);
         END IF;
      EXCEPTION
         WHEN NO_DATA_FOUND THEN
            NULL;
      END;
 
   EXCEPTION
      WHEN NO_DATA_FOUND THEN
         deb('rsWritewaterMarks: database with dbid=' || my_dbid ||
                                 ' not found in recovery catalog');
   END;
 
 
--
      v_xml := this_xml_signature_beg;
      FOR idx in 0..l_stmts  LOOP
         deb('writing XML file for ' || idx);
         deb('executing query:'|| record_sql(idx));
   
         v_ctx := DBMS_XMLGen.newContext(record_sql(idx));
 
--
         DBMS_XMLGen.setRowsetTag(v_ctx, 'TABLE_' || record_tbl(idx));
         v_xml_tmp := DBMS_XMLGen.GetXML(v_ctx);
         DBMS_XMLGen.closeContext(v_ctx);
 
         deb('XML len for ' || idx || '=' || DBMS_LOB.GETLENGTH(v_xml_tmp));
         IF v_xml_tmp IS NOT NULL THEN
            DBMS_LOB.COPY(v_xml, v_xml_tmp, DBMS_LOB.LOBMAXSIZE, 
                          DBMS_LOB.GETLENGTH(v_xml),
                          DBMS_LOB.INSTR(v_xml_tmp, 
                                     '<TABLE_' || record_tbl(idx) ||'>'));
         END IF;
      END LOOP;
      v_xml := v_xml || this_xml_signature_end;
 
--
      write_xml_filename := this_watermarks || my_dbid || '.xml';
      IF this_amazon_server THEN
         put_object(null /*bktname */, write_xml_filename, 'text/xml', v_xml);
      ELSE
         delete rcfile where name = write_xml_filename;
         insert into rcfile(rcfile_key, creation_time, name, xmldoc)
            values (rman_seq.nextval, sys_extract_utc(systimestamp), 
                    write_xml_filename, XMLType.createXML(v_xml));
      END IF;
 
--
      IF this_rsiterec.high_bp_recid >= 0 THEN
         deb('rsWritewaterMarks called for remote readBackupSections');
         writeBackupSections(input_xml_filename, bktname);
      ELSE
         deb('rsWritewaterMarks called for local readFixedSections');
      END IF;
 
--
      IF this_amazon_server THEN
         delete_object(null, this_forwatermarks || my_dbid || '.xml');
      ELSE
         delete rcfile where name = this_forwatermarks || my_dbid || '.xml';
      END IF;
 
      commitChanges('rsWritewaterMarks(suc)');
   EXCEPTION
      WHEN OTHERS THEN
         deb('rsWriteWatermarks(fail)- rollback (release locks):' || sqlerrm);
         rollback;
         raise;
END rsWriteWaterMarks;
 
PROCEDURE writeFixedSections(bktname IN VARCHAR2 DEFAULT NULL) IS
   v_ctx     DBMS_XMLGen.ctxHandle;
   v_xml     CLOB;
   v_xml_tmp CLOB;
   type record_sql_type is table of varchar2(2048) 
             index by binary_integer;
   type record_tbl_type is table of varchar2(30) 
             index by binary_integer;
   type record_watermarks_type is table of number 
             index by binary_integer;
   record_sql  record_sql_type;
   record_tbl  record_tbl_type;
   read_wm     record_watermarks_type;
   curr_wm     record_watermarks_type;
 
   my_dbid      number;
   write_xml_filename rcfile.name%TYPE;
 
   full_ckp_key      number;
   curr_dbinc_key    number;
   full_ckp_site_key number;
   noderec           node%ROWTYPE;
 
BEGIN
 
   deb('writeFixedSections - enter');
 
--
   IF this_server.server_host IS NULL THEN
      deb('writeFixedSections: this_server.server_host is null');
      return;
   END IF;
 
   IF (this_db_key IS NULL) THEN
      raise_application_error(-20021, 'Database not set');
   END IF;
 
--
--
   BEGIN
      writeForWatermarks(bktname, TRUE);
      rsReadWaterMarks(bktname);
   EXCEPTION
      WHEN OTHERS THEN
         deb('writeFixedSections: error during watermarks read:' || sqlerrm);
         RAISE;
   END;
 
--
   BEGIN
      SELECT ckp_key, site_key INTO full_ckp_key, full_ckp_site_key
         FROM RC_CHECKPOINT
         WHERE CKP_KEY =
            (SELECT MAX(CKP_KEY) FROM RC_CHECKPOINT 
               WHERE DB_KEY = this_db_key 
               AND CKP_TYPE = 'FULL');
   EXCEPTION
      WHEN no_data_found THEN
         deb('writeFixedSections: no full resync yet done for this database');
         return;
   END;
 
   SELECT dbinc_key INTO curr_dbinc_key FROM RC_DATABASE
      WHERE DB_KEY = this_db_key;
 
   SELECT * INTO noderec FROM NODE WHERE SITE_KEY=full_ckp_site_key;
   deb('noderec.cf_version_stamp: ' || noderec.cf_create_time);
   deb('noderec.db_unique_name: ' || noderec.db_unique_name);
   deb('noderec.high_df_recid: ' || noderec.high_df_recid);
   deb('noderec.high_tf_recid: ' || noderec.high_tf_recid);
   deb('noderec.high_ts_recid: ' || noderec.high_ts_recid);
   select nvl(max(offr_key), 0) INTO noderec.high_offr_recid 
      from rc_offline_range where db_key=this_db_key;
   deb('noderec.high_offr_recid: ' || noderec.high_offr_recid);
 
--
   IF noderec.cf_create_time = this_wmrec.cf_version_stamp AND
      noderec.high_ts_recid = this_wmrec.high_ts_recid AND
      noderec.high_df_recid = this_wmrec.high_df_recid AND
      noderec.high_tf_recid = this_wmrec.high_tf_recid AND
      noderec.high_offr_recid = this_wmrec.high_offr_recid THEN
     deb('writeFixedSections: No event of interest occured at catalog');
     return;
   END IF;
 
   IF noderec.cf_create_time <> this_wmrec.cf_version_stamp OR
      this_wmrec.cf_version_stamp IS NULL THEN
      deb('Clearing fixed record section watermarks');
      this_wmrec.high_df_recid := NULL;
      this_wmrec.high_ts_recid := NULL;
      this_wmrec.high_tf_recid := NULL;
      this_wmrec.high_offr_recid := NULL;
   END IF;
 
   SELECT DBID INTO MY_DBID FROM RC_DATABASE WHERE DB_KEY=this_db_key;
 
   record_tbl(0)   := 'RC_DATABASE';
   record_sql(0)   := 'SELECT * FROM RC_DATABASE ' || 
                         'WHERE DB_KEY = ' || this_db_key;
   read_wm(0)      := -1; /* no watermark check for this record */
 
   record_tbl(1)   := 'RC_DATABASE_INCARNATION';
   record_sql(1)   := 'SELECT * FROM RC_DATABASE_INCARNATION ' ||
                         'WHERE DB_KEY = ' || this_db_key;
   read_wm(1)      := -1; /* no watermark check for this record */
 
   record_tbl(2)   := 'RC_SITE';
   record_sql(2)   := 'SELECT * FROM RCI_SITE ' ||
                         'WHERE DB_KEY   = ' || this_db_key ||
                         '  AND SITE_KEY = ' || full_ckp_site_key;
   read_wm(2)      := -1; /* no watermark check for this record */
 
   record_tbl(3)   := 'RC_RMAN_CONFIGURATION';
   record_sql(3)   := 'SELECT * FROM RC_RMAN_CONFIGURATION ' ||
                         'WHERE DB_KEY   = ' || this_db_key ||
                         '  AND (SITE_KEY = ' || full_ckp_site_key ||
                         '       OR SITE_KEY = 0)';
   read_wm(3)      := -1; /* no watermark check for this record */
 
   record_tbl(4)   := 'RC_TABLESPACE';
   record_sql(4)   := 'SELECT * FROM RC_TABLESPACE ' ||
                         'WHERE DB_KEY = ' || this_db_key ||
                         '  AND DBINC_KEY = ' || curr_dbinc_key ||
                         '  AND DROP_CHANGE# IS NULL';
   read_wm(4)      := -1; /* watermark check only if required */
   IF this_wmrec.cf_version_stamp = noderec.cf_create_time THEN
      read_wm(4)      := this_wmrec.high_ts_recid;
      curr_wm(4)      := noderec.high_ts_recid;
   END IF;
 
   record_tbl(5)   := 'RC_REDO_THREAD';
   record_sql(5)   := 'SELECT * FROM RC_REDO_THREAD ' ||
                         'WHERE DB_KEY = ' || this_db_key ||
                         '  AND DBINC_KEY = ' || curr_dbinc_key;
   read_wm(5)      := -1; /* no watermark check for this record */
 
   record_tbl(6)   := 'RCI_DATAFILE';
   record_sql(6)   := 'SELECT * FROM RCI_DATAFILE ' ||
                         'WHERE DB_KEY = ' || this_db_key ||
                         '  AND DBINC_KEY = ' || curr_dbinc_key ||
                         '  AND SITE_KEY = ' || full_ckp_site_key ||
                         '  AND DROP_CHANGE# IS NULL';
   read_wm(6)      := -1; /* watermark check only if required */
   IF this_wmrec.cf_version_stamp = noderec.cf_create_time THEN
      read_wm(6)      := this_wmrec.high_df_recid;
      curr_wm(6)      := noderec.high_df_recid;
   END IF;
 
   record_tbl(7)   := 'RCI_TEMPFILE';
   record_sql(7)   := 'SELECT * FROM RCI_TEMPFILE ' ||
                         'WHERE DB_KEY = ' || this_db_key ||
                         '  AND DBINC_KEY = ' || curr_dbinc_key ||
                         '  AND SITE_KEY = ' || full_ckp_site_key ||
                         '  AND DROP_CHANGE# IS NULL';
   read_wm(7)      := -1; /* watermark check only if required */
   IF this_wmrec.cf_version_stamp = noderec.cf_create_time THEN
      read_wm(7)      := this_wmrec.high_tf_recid;
      curr_wm(7)      := noderec.high_tf_recid;
   END IF;
 
   record_tbl(8)   := 'RC_REDO_LOG';
   record_sql(8)   := 'SELECT * FROM RC_REDO_LOG ' ||
                         'WHERE DB_KEY = ' || this_db_key ||
                         '  AND DBINC_KEY = ' || curr_dbinc_key ||
                         '  AND SITE_KEY = ' || full_ckp_site_key;
   read_wm(8)      := -1; /* no watermark check for this record */
 
   record_tbl(9)   := 'RC_CHECKPOINT';
   record_sql(9)   := 'SELECT * FROM RC_CHECKPOINT ' ||
                         'WHERE CKP_KEY = ' || full_ckp_key;
   read_wm(9)      := -1; /* no watermark check for this record */
 
   record_tbl(10)  := 'RC_OFFLINE_RANGE';
   record_sql(10)  := 'SELECT * FROM RC_OFFLINE_RANGE ' ||
                         'WHERE DB_KEY = ' || this_db_key ||
                         '  AND OFFR_KEY >'||nvl(this_wmrec.high_offr_recid,0);
   read_wm(10)     := -1; /* watermark check not required, send new records */
 
   record_tbl(11)   := 'RCI_PDBS';
   record_sql(11)   := 'SELECT * FROM RCI_PDBS ' || 
                         'WHERE DB_KEY = ' || this_db_key;
   read_wm(11)      := -1; /* no watermark check for this record */
 
   record_tbl(12)   := 'RC_PLUGGABLE_DATABASE_INC';
   record_sql(12)   := 'SELECT * FROM RC_PLUGGABLE_DATABASE_INC ' ||
                         'WHERE DB_KEY = ' || this_db_key;
   read_wm(12)      := -1; /* no watermark check for this record */
 
   record_tbl(13)   := 'RCI_RA_UPSTREAM_DATABASE';
   record_sql(13)   := 'SELECT * FROM RCI_RA_UPSTREAM_DATABASE';
   read_wm(13)      := -1; /* no watermark check for this record */
 
--
   v_xml := this_xml_signature_beg;
   dbms_session.set_nls('NLS_DATE_FORMAT','''DD-MM-YYYY HH24:MI:SS''');
   FOR idx in 0..13 LOOP
      deb('writing XML file for ' || idx);
      IF read_wm (idx) <> -1 AND read_wm(idx) <> 0 AND 
         read_wm(idx) = curr_wm(idx) THEN
         deb('skipping query:'|| record_sql(idx));
      ELSE
         deb('executing query:'|| record_sql(idx));
         v_ctx := DBMS_XMLGen.newContext(record_sql(idx));
 
--
         DBMS_XMLGen.setRowsetTag(v_ctx, 'TABLE_' || record_tbl(idx));
         v_xml_tmp := DBMS_XMLGen.GetXML(v_ctx);
         DBMS_XMLGen.closeContext(v_ctx);
 
         deb('XML len for ' || idx || '=' || DBMS_LOB.GETLENGTH(v_xml_tmp));
         IF v_xml_tmp IS NOT NULL THEN
            DBMS_LOB.COPY(v_xml, v_xml_tmp, DBMS_LOB.LOBMAXSIZE, 
                          DBMS_LOB.GETLENGTH(v_xml),
                          DBMS_LOB.INSTR(v_xml_tmp, 
                                     '<TABLE_' || record_tbl(idx) ||'>'));
         END IF;
      END IF;
   END LOOP;
 
   deb('XML len for v_wmrec=' || DBMS_LOB.GETLENGTH(this_v_wmrec));
   IF this_v_wmrec IS NOT NULL THEN
            DBMS_LOB.COPY(v_xml, this_v_wmrec, DBMS_LOB.LOBMAXSIZE, 
                          DBMS_LOB.GETLENGTH(v_xml),
                          DBMS_LOB.INSTR(this_v_wmrec, 
                                     '<TABLE_RC_WATERMARKS>'));
   ELSE
      deb('writeFixedSections: no watermarks added to uploaded file');
   END IF;
 
   v_xml := v_xml || this_xml_signature_end;
 
--
   write_xml_filename := this_database || my_dbid || '.xml';
   put_bucket(bktname);
   put_object(bktname, write_xml_filename, 'text/xml', v_xml);
 
--
--
--
--
--
--
--
--
--
--
--
--
--
  
   deb('writeFixedSections:(suc)');
END writeFixedSections;
 
--
PROCEDURE readFixedSections(input_xml_filename  IN VARCHAR2,
                            bktname IN VARCHAR2 DEFAULT NULL) IS
 
   ckp_type     NUMBER;
 
   database_already_registered EXCEPTION;
   PRAGMA EXCEPTION_INIT(database_already_registered, -20002);
 
   incarnation_already_registered EXCEPTION;
   PRAGMA EXCEPTION_INIT(incarnation_already_registered, -20009);
 
   resync_not_needed EXCEPTION;
   PRAGMA EXCEPTION_INIT(resync_not_needed, -20034);
 
   local_wmrec  RC_WATERMARKS%ROWTYPE;
   wmrec  RC_WATERMARKS%ROWTYPE;
   CURSOR rc_watermarks_c IS
   SELECT DB_KEY,
          DB_UNIQUE_NAME,
          RS_VERSION_STAMP,
          HIGH_BP_RECID,
          HIGH_DO_KEY,
          CF_VERSION_STAMP,
          HIGH_DF_RECID,
          HIGH_TS_RECID,
          HIGH_TF_RECID,
          HIGH_OFFR_RECID
   FROM "_RS_RC_WATERMARKS_"
   WHERE RS_RCFILE_NAME = input_xml_filename;
 
   local_siterec RC_SITE%ROWTYPE;
   siterec RC_SITE%ROWTYPE;
   CURSOR rc_site_c IS
   SELECT  SITE_KEY,
           DB_KEY,
           DATABASE_ROLE,
           CF_CREATE_TIME,
           DB_UNIQUE_NAME,
           HIGH_CONF_RECID,
           FORCE_RESYNC2CF,
           HIGH_ROUT_STAMP,
           INST_STARTUP_STAMP,
           LAST_KCCDIVTS,
           HIGH_IC_RECID,
           DBINC_KEY,
           CKP_SCN,
           FULL_CKP_CF_SEQ,
           JOB_CKP_CF_SEQ,
           HIGH_TS_RECID,
           HIGH_DF_RECID,
           HIGH_RT_RECID,
           HIGH_ORL_RECID,
           HIGH_OFFR_RECID,
           HIGH_RLH_RECID,
           HIGH_AL_RECID,
           HIGH_BS_RECID,
           HIGH_BP_RECID,
           HIGH_BDF_RECID,
           HIGH_CDF_RECID,
           HIGH_BRL_RECID,
           HIGH_BCB_RECID,
           HIGH_CCB_RECID,
           HIGH_DO_RECID,
           HIGH_PC_RECID,
           HIGH_BSF_RECID,
           HIGH_RSR_RECID,
           HIGH_TF_RECID,
           HIGH_GRSP_RECID,
           HIGH_NRSP_RECID,
           HIGH_BCR_RECID,
           LOW_BCR_RECID,
           BCR_IN_USE,
           HIGH_PDB_RECID,
           HIGH_PIC_RECID
   FROM "_RS_RC_SITE_"
   WHERE RS_RCFILE_NAME = input_xml_filename;
 
   upstream_dbrec rci_ra_upstream_database%ROWTYPE;
   CURSOR rci_ra_upstream_database_c IS
   SELECT  DBID,
           NAME
   FROM "_RS_RCI_RA_UPSTREAM_DATABASE_"
   WHERE RS_RCFILE_NAME = input_xml_filename;
 
   icrec    RC_DATABASE_INCARNATION%ROWTYPE;
   curr_inc RC_DATABASE_INCARNATION%ROWTYPE;
   CURSOR rc_database_incarnation_c(curr_inc_val IN VARCHAR2 DEFAULT NULL) IS
   SELECT DB_KEY, 
          DBID, 
          DBINC_KEY,  
          NAME, 
          RESETLOGS_CHANGE#, 
          RESETLOGS_TIME,
          CURRENT_INCARNATION,
          PARENT_DBINC_KEY, 
          PRIOR_RESETLOGS_CHANGE#,
          PRIOR_RESETLOGS_TIME,
          STATUS,
          REG_DB_UNIQUE_NAME,
          CON_ID,
          GUID
   FROM "_RS_RC_DATABASE_INCARNATION_"
   WHERE RS_RCFILE_NAME = input_xml_filename
     AND (curr_inc_val IS NULL OR
          CURRENT_INCARNATION = curr_inc_val)
   ORDER BY RESETLOGS_CHANGE#;
   
   tbsrec RC_TABLESPACE%ROWTYPE;
   CURSOR rc_tablespace_c IS
   SELECT DB_KEY, 
          DBINC_KEY,
          DB_NAME,
          CON_ID,
          PDB_NAME,
          PDB_KEY,
          PDBINC_KEY,
          TS#, 
          NAME,
          CREATION_CHANGE#,
          CREATION_TIME,
          DROP_CHANGE#,
          DROP_TIME,
          INCLUDED_IN_DATABASE_BACKUP,
          BIGFILE,
          TEMPORARY,
          ENCRYPT_IN_BACKUP,
          PLUGIN_CHANGE#
   FROM "_RS_RC_TABLESPACE_"
   WHERE RS_RCFILE_NAME = input_xml_filename
   ORDER BY CON_ID, TS#;
 
   dfrec RCI_DATAFILE%ROWTYPE;
   CURSOR rci_datafile_c IS
   SELECT  DB_KEY,
           DBINC_KEY,
           DB_NAME,
           CON_ID,
           PDB_NAME,
           PDB_KEY,
           PDB_CLOSED,
           PDBINC_KEY,
           TS#,
           TABLESPACE_NAME,
           FILE#,
           CREATION_CHANGE#,
           CREATION_TIME,
           DROP_CHANGE#,
           DROP_TIME,
           BYTES,
           BLOCKS,
           BLOCK_SIZE,
           NAME,
           STOP_CHANGE#,
           STOP_TIME,
           READ_ONLY,
           RFILE#,
           INCLUDED_IN_DATABASE_BACKUP,
           AUX_NAME,
           ENCRYPT_IN_BACKUP,
           SITE_KEY,
           DB_UNIQUE_NAME,
           FOREIGN_DBID,
           FOREIGN_CREATION_CHANGE#,
           FOREIGN_CREATION_TIME,
           PLUGGED_READONLY,
           PLUGIN_CHANGE#,
           PLUGIN_RESETLOGS_CHANGE#,
           PLUGIN_RESETLOGS_TIME,
           CREATION_THREAD,
           CREATION_SIZE,
           PDB_FOREIGN_DBID,
           PDB_FOREIGN_CKP_SCN,
           PDB_NOBACKUP,
           PDB_FOREIGN_AFN
   FROM "_RS_RCI_DATAFILE_"
   WHERE RS_RCFILE_NAME = input_xml_filename
   ORDER BY FILE#;
 
   tfrec RCI_TEMPFILE%ROWTYPE;
   CURSOR rci_tempfile_c IS 
   SELECT  DB_KEY,
           DBINC_KEY,
           DB_NAME,
           CON_ID,
           PDB_NAME,
           PDB_KEY,
           TS#,
           TABLESPACE_NAME,
           FILE#,
           CREATION_CHANGE#,
           CREATION_TIME,
           DROP_CHANGE#,
           DROP_TIME,
           BYTES,
           BLOCKS,
           BLOCK_SIZE,
           NAME,
           RFILE#,
           AUTOEXTEND,
           MAXSIZE,
           NEXTSIZE,
           BIGFILE,
           SITE_KEY,
           DB_UNIQUE_NAME,
           TABLESPACE_CREATION_CHANGE#,
           TABLESPACE_CREATION_TIME,
           TABLESPACE_DROP_CHANGE#,
           TABLESPACE_DROP_TIME
   FROM "_RS_RCI_TEMPFILE_"
   WHERE RS_RCFILE_NAME = input_xml_filename
   ORDER BY FILE#;
 
   rtrec RC_REDO_THREAD%ROWTYPE;
   CURSOR rc_redo_thread_c IS 
   SELECT  DB_KEY,
           DBINC_KEY,
           DB_NAME,
           THREAD#,
           STATUS,
           SEQUENCE#,
           ENABLE_CHANGE#,
           ENABLE_TIME,
           DISABLE_CHANGE#,
           DISABLE_TIME
   FROM "_RS_RC_REDO_THREAD_"
   WHERE RS_RCFILE_NAME = input_xml_filename
   ORDER BY THREAD#;
 
   orlrec RC_REDO_LOG%ROWTYPE;
   CURSOR rc_redo_log_c IS 
   SELECT  DB_KEY,
           DBINC_KEY,
           DB_NAME,
           THREAD#,
           GROUP#,
           NAME,
           SITE_KEY,
           BYTES,
           TYPE
   FROM "_RS_RC_REDO_LOG_"
   WHERE RS_RCFILE_NAME = input_xml_filename
   ORDER BY NAME;
 
   ckprec RC_CHECKPOINT%ROWTYPE;
   CURSOR rc_checkpoint_c IS 
   SELECT  DB_KEY,
           DBINC_KEY,
           DB_NAME,
           CKP_KEY,
           CKP_SCN,
           CKP_CF_SEQ,
           CKP_TIME,
           CKP_TYPE,
           CKP_DB_STATUS,
           SITE_KEY
   FROM "_RS_RC_CHECKPOINT_"
   WHERE RS_RCFILE_NAME = input_xml_filename;
 
   offrrec RC_OFFLINE_RANGE%ROWTYPE;
   CURSOR rc_offline_range_c IS 
   SELECT  DB_KEY,
           DBINC_KEY,
           DB_NAME,
           RECID,
           STAMP,
           FILE#,
           CREATION_CHANGE#,
           OFFLINE_CHANGE#,
           ONLINE_CHANGE#,
           ONLINE_TIME,
           CF_CREATE_TIME,
           RESETLOGS_CHANGE#,
           RESETLOGS_TIME,
           OFFR_KEY
   FROM "_RS_RC_OFFLINE_RANGE_"
   WHERE RS_RCFILE_NAME = input_xml_filename
   ORDER BY OFFR_KEY;
 
   pdbrec  RCI_PDBS%ROWTYPE;
   CURSOR rci_pdbs_c IS 
   SELECT PDB_KEY,
          DB_KEY,
          NAME,
          CON_ID,
          DBID,
          CREATION_CHANGE#,
          GUID,
          NOBACKUP
   FROM "_RS_RCI_PDBS_"
   WHERE RS_RCFILE_NAME = input_xml_filename;
 
   picrec1 RC_PLUGGABLE_DATABASE_INC%ROWTYPE;
   CURSOR rc_pluggable_database_inc_c IS 
   SELECT PDB_KEY,
          NAME,
          CON_ID,
          DBID,
          GUID,
          CREATE_SCN,
          PDBINC_KEY,
          DB_KEY,
          CURRENT_INCARNATION,
          INCARNATION_SCN,
          BEGIN_RESETLOGS_SCN,
          BEGIN_RESETLOGS_TIME,
          END_RESETLOGS_SCN,
          DBINC_KEY,
          DB_RESETLOGS_SCN,
          DB_RESETLOGS_TIME,
          PRIOR_PDBINC_KEY,
          PRIOR_INCARNATION_SCN,
          PRIOR_BEGIN_RESETLOGS_SCN,
          PRIOR_BEGIN_RESETLOGS_TIME,
          PRIOR_END_RESETLOGS_SCN,
          PRIOR_DBINC_KEY,
          PRIOR_DB_RESETLOGS_SCN,
          PRIOR_DB_RESETLOGS_TIME,
          STATUS
   FROM "_RS_RC_PLUGGABLE_DATABASE_INC_"
   WHERE RS_RCFILE_NAME = input_xml_filename
   ORDER BY PDBINC_KEY;
 
   offr_key              NUMBER;
   parent_dbinc_key      NUMBER;
   dbid                  NUMBER;
   foundrec              BOOLEAN;
   newincarnation        BOOLEAN := FALSE;
   loc_db_key            NUMBER;
   cdb_mode              NUMBER;
   last_full_ckp_scn     NUMBER;
   local_dbincrec        RC_DATABASE_INCARNATION%ROWTYPE;
 
BEGIN
 
   deb('readFixedSections - enter');
 
--
   dbms_session.set_nls('NLS_DATE_FORMAT','''DD-MM-YYYY HH24:MI:SS''');
 
--
   dbid := to_number(substr(input_xml_filename,length(this_database)+1, 
                    instr(input_xml_filename,'.xml')-1-length(this_database)));
 
   deb('readFixedSections: dbid=' || dbid);
 
--
   OPEN rc_watermarks_c;
   LOOP
      FETCH rc_watermarks_c INTO wmrec;
      EXIT WHEN rc_watermarks_c%NOTFOUND;
   END LOOP;
   CLOSE rc_watermarks_c;
   IF debug THEN
      displayRCWatermarks('readFixedSections remote:', wmrec);
   END IF;
 
--
   OPEN rc_site_c;
   FETCH rc_site_c INTO siterec;
   CLOSE rc_site_c;
   IF debug THEN
      displayRCSite('readFixedSections:remote ', siterec);
   END IF;
 
--
   OPEN rci_ra_upstream_database_c;
   FETCH rci_ra_upstream_database_c INTO upstream_dbrec;
   CLOSE rci_ra_upstream_database_c;
   this_upstream_dbrec := upstream_dbrec;
   deb('readFixedSections: upstream dbname=' || this_upstream_dbrec.name ||
       'reconcile dbname' || siterec.db_unique_name);
 
--
   OPEN rc_database_incarnation_c(curr_inc_val => 'YES');
   FETCH rc_database_incarnation_c INTO curr_inc;
   CLOSE rc_database_incarnation_c;
   IF debug THEN
      displayRCDatabaseIncarnation('readFixedSections: remote ', curr_inc);
   END IF;
 
--
   OPEN rc_checkpoint_c;
   FETCH rc_checkpoint_c INTO ckprec;
   CLOSE rc_checkpoint_c;
 
--
   IF curr_inc.dbid IS NULL THEN
      raise_application_error(-20999, 'internal error: no rows for curr_inc');
   END IF;
 
--
   IF curr_inc.dbid <> readFixedSections.dbid THEN
      raise_application_error(-20141, 
                 'Target database id mismatch with registered database in ORS');
   END IF;
 
--
   BEGIN
      registerDatabase(db_id => curr_inc.dbid,
                       db_name => curr_inc.name,
                       reset_scn => curr_inc.resetlogs_change#,
                       reset_time => curr_inc.resetlogs_time,
                       db_unique_name => curr_inc.reg_db_unique_name,
                       con_id => curr_inc.con_id,
                       guid => curr_inc.guid);
     deb('readFixedSections: registered dbname=' || siterec.db_unique_name);
   EXCEPTION
      WHEN database_already_registered THEN
         deb('database already registered');
         NULL;
     WHEN no_data_found THEN
         deb('database has yet to be added via add_db, dbuname=' || 
             siterec.db_unique_name);
         raise_application_error(-20140, 'Database not yet registered in ORS');
   END;
 
--
--
--
   BEGIN
      SELECT * INTO local_dbincrec
         FROM rc_database_incarnation
         WHERE dbid = dbid 
           AND resetlogs_change# = curr_inc.resetlogs_change#
           AND resetlogs_time = curr_inc.resetlogs_time;
      IF local_dbincrec.status = 'CURRENT' THEN
--
--
         SELECT max(ckp_scn) INTO last_full_ckp_scn
            FROM ckp
            WHERE ckp_type = 'FULL'
              AND dbinc_key = local_dbincrec.dbinc_key;
         IF last_full_ckp_scn > ckprec.ckp_scn THEN
            deb('readFixedSections (wait):Downstream ahead of upstream');
            RETURN;
         END IF;
      ELSE
--
--
--
--
         deb('readFixedSections: Upstream is in a different incarnation');
         IF debug THEN
            displayRCDatabaseIncarnation('readFixedSections: local ',
                                          local_dbincrec);
         END IF;
         IF local_dbincrec.status = 'ORPHAN' THEN
            deb('readFixedSections: local incarnation is orphan');
         ELSE
            deb('readFixedSections (wait): Let upstream catchup');
            RETURN;
         END IF;
      END IF;
   EXCEPTION
      WHEN NO_DATA_FOUND THEN
         deb('readFixedSections: New incarnation in upstream');
         IF debug THEN
            displayRCDatabaseIncarnation('readFixedSections: remote ',
                                          curr_inc);
         END IF;
   END;
 
--
   BEGIN
      resetDatabase(db_id => curr_inc.dbid,
                    db_name => curr_inc.name,
                    reset_scn => curr_inc.resetlogs_change#,
                    reset_time => curr_inc.resetlogs_time,
                    parent_reset_scn => curr_inc.prior_resetlogs_change#,
                    parent_reset_time => curr_inc.prior_resetlogs_time);
      deb('readFixedSections: registered newinc ' || siterec.db_unique_name);
      newincarnation := TRUE;
   EXCEPTION
      WHEN incarnation_already_registered THEN
         deb('database incarnation already known');
         NULL;
   END;
 
--
--
   curr_inc.dbinc_key :=
      resetDatabase(db_id => curr_inc.dbid,
                    db_name => curr_inc.name,
                    reset_scn => curr_inc.resetlogs_change#,
                    reset_time => curr_inc.resetlogs_time,
                    parent_reset_scn => curr_inc.prior_resetlogs_change#,
                    parent_reset_time => curr_inc.prior_resetlogs_time);
 
   deb('current dbinc_key = ' || curr_inc.dbinc_key);
 
--
   IF this_upstream_dbrec.name IS NULL THEN
      raise_application_error(-20999, 'internal error: no rows for upstreamdb');
   END IF;
   IF siterec.site_key IS NULL THEN
      raise_application_error(-20999, 'internal error: no rows for siterec');
   END IF;
 
   setDatabase(db_name => curr_inc.name,
               reset_scn => curr_inc.resetlogs_change#,
               reset_time => curr_inc.resetlogs_time,
               db_id => curr_inc.dbid,
               db_unique_name => 
                        this_upstream_dbrec.name||'$'||siterec.db_unique_name,
               dummy_instance => FALSE,
               cf_type => CF_STANDBY,
               site_aware => TRUE,
               ors_instance => TRUE);
 
--
   IF newincarnation THEN
      deb('Clearing watermarks at catalog');
      UPDATE watermarks SET
         high_df_recid = 0,
         high_ts_recid = 0,
         high_tf_recid = 0,
         high_offr_recid = 0,
         cf_version_stamp = null
      WHERE db_key = this_db_key;
      UPDATE node SET
         high_df_recid = 0,
         high_ts_recid = 0,
         high_tf_recid = 0,
         high_offr_recid = 0
      WHERE db_key = this_db_key
        AND site_key = this_site_key;
      commitChanges('readFixedSections-1');
   END IF;
 
   select * into local_siterec from rci_site 
      where db_key = this_db_key
        and site_key = this_site_key;
   displayRCSite('readFixedSections:local ', local_siterec);
 
--
--
--
   BEGIN
      SELECT db_key, db_unique_name, rs_version_stamp, high_bp_recid, 
             high_do_key, cf_version_stamp, high_df_recid, high_ts_recid, 
             high_tf_recid, high_offr_recid 
         INTO local_wmrec 
         FROM watermarks 
         WHERE db_key = this_db_key;
      IF debug THEN
         displayRCWatermarks('readFixedSections:local ', local_wmrec);
      END IF;
   EXCEPTION
      WHEN NO_DATA_FOUND THEN
         deb('readFixedSections:database with db_key=' || this_db_key ||
                                 ' no watermarks set yet');
   END;
 
--
--
--
   IF local_siterec.last_kccdivts = 0 THEN
      local_siterec.last_kccdivts := date2stamp(local_wmrec.cf_version_stamp);
      update node set last_kccdivts = local_siterec.last_kccdivts,
                      cf_create_time = local_wmrec.cf_version_stamp,
                      high_ts_recid = local_wmrec.high_ts_recid,
                      high_df_recid = local_wmrec.high_df_recid,
                      high_tf_recid = local_wmrec.high_tf_recid,
                      high_offr_recid = local_wmrec.high_offr_recid,
                      high_bp_recid = local_wmrec.high_bp_recid,
                      high_do_recid = local_wmrec.high_do_key
         where db_key = this_db_key
           and site_key = this_site_key;
      commitChanges('readFixedSections-2');
 
      select * into local_siterec from rci_site 
         where db_key = this_db_key
           and site_key = this_site_key;
      displayRCSite('readFixedSections:local,re-fetch ', local_siterec);
   END IF;
 
   deb('CRossed  from watermarks');
 
--
--
--
   IF wmrec.rs_version_stamp is not null AND
      local_wmrec.rs_version_stamp <> wmrec.rs_version_stamp THEN
      raise_application_error(-20142, 
         'The version stamp of backup XML set is different');
   END IF;
 
--
--
   lockForCkpt;
   ckp_type := ckptNeeded(ckp_scn => siterec.ckp_scn,
                          ckp_cf_seq => siterec.full_ckp_cf_seq,
                          cf_version => stamp2date(siterec.last_kccdivts),
                          cf_type => CF_CURRENT,
                          high_df_recid => siterec.high_df_recid,
                          high_orl_recid => siterec.high_orl_recid,
                          high_cdf_recid => NULL,
                          high_al_recid => NULL,
                          high_bp_recid => NULL,
                          high_do_recid => NULL,
                          high_offr_recid => siterec.high_offr_recid,
                          high_pc_recid => NULL,
                          high_conf_recid => siterec.high_conf_recid,
                          rltime => curr_inc.resetlogs_time,
                          high_ts_recid => siterec.high_ts_recid,
                          high_bs_recid => NULL,
                          lopen_reset_scn => NULL,
                          lopen_reset_time => NULL,
                          high_ic_recid => siterec.high_ic_recid,
                          high_tf_recid => siterec.high_tf_recid,
                          high_rt_recid => siterec.high_rt_recid,
                          high_grsp_recid => NULL,
                          high_nrsp_recid => NULL,
                          high_bcr_recid => NULL,
                          high_pdb_recid => siterec.high_pdb_recid,
                          high_pic_recid => siterec.high_pic_recid);
 
   IF ckp_type <> RESYNC_FULL AND ckp_type <> RESYNC_PARTIAL THEN
      deb('readFixedSections (abort) - ckptNeeded returned ' || ckp_type);
      cancelCkpt;
      return;
   END IF;
 
   BEGIN
      beginCkpt(ckp_scn => siterec.ckp_scn,
                ckp_cf_seq => siterec.full_ckp_cf_seq,
                cf_version => stamp2date(siterec.last_kccdivts),
                ckp_time => ckprec.ckp_time,
                ckp_type => 'FULL',
                ckp_db_status => ckprec.ckp_db_status,
                high_df_recid => siterec.high_df_recid,
                cf_type => 'CURRENT');
   EXCEPTION
      WHEN resync_not_needed THEN
         deb('readFixedSections (abort) - resync not needed ' || ckp_type);
         return;
   END;
 
   deb('readFixedSections: have records to read ' || siterec.db_unique_name);
 
--
   foundrec := FALSE;
   IF beginPluggableDBResync(siterec.high_pdb_recid) then
      OPEN rci_pdbs_c;
      LOOP
         FETCH rci_pdbs_c INTO pdbrec;
         EXIT WHEN rci_pdbs_c%NOTFOUND;
 
         deb('Calling checkPluggableDB name=' ||
              pdbrec.name || ' dbid=' || pdbrec.dbid);
         checkPluggableDB(pdbrec.name, pdbrec.con_id, pdbrec.dbid,
                          pdbrec.creation_change#, pdbrec.guid,
                          pdbrec.nobackup);
         foundrec := TRUE;
      END LOOP;
      CLOSE rci_pdbs_c;
      endPluggableDBResync;
 
      IF NOT foundrec THEN
--
--
         raise_application_error(-20150, 
                'no records found to resync for plugged databases');
      END IF;
   END IF;
 
--
   foundrec := FALSE;
   newincarnation := FALSE;
   IF siterec.high_ic_recid > beginIncarnationResync(return_recid => TRUE) THEN
      OPEN rc_database_incarnation_c;
      LOOP
         FETCH rc_database_incarnation_c INTO icrec;
         EXIT WHEN rc_database_incarnation_c%NOTFOUND;
 
         deb('Calling checkIncarnation from readfixedsection');
         parent_dbinc_key :=
             dbms_rcvcat.checkIncarnation(icrec.resetlogs_change#,
                                          icrec.resetlogs_time,
                                          icrec.prior_resetlogs_change#,
                                          icrec.prior_resetlogs_time,
                                          icrec.name);
         foundrec := TRUE;
         newincarnation := TRUE;
      END LOOP;
      CLOSE rc_database_incarnation_c;
      endIncarnationResync(siterec.last_kccdivts, siterec.high_ic_recid);
 
      IF NOT foundrec THEN
--
--
         raise_application_error(-20143, 
                'no records found to resync for incarnation view');
      END IF;
   END IF;
 
--
--
   SELECT count(*) INTO cdb_mode FROM pdb 
   WHERE con_id >= 1 
     AND db_key = this_db_key;
  
--
   foundrec := FALSE;
   IF ((cdb_mode > 0) AND 
       (siterec.high_pic_recid > beginPluggableDbincResync OR
        newincarnation)) THEN
      OPEN rc_pluggable_database_inc_c;
      LOOP
       FETCH rc_pluggable_database_inc_c INTO picrec1;
         EXIT WHEN rc_pluggable_database_inc_c%NOTFOUND;
  
         deb('Calling checkPluggableDbinc for record' ||
             ' pdbname= ' || picrec1.name ||
             ' dbid=' || picrec1.dbid ||
             ' curr=' || picrec1.current_incarnation ||
             ' inc_scn=' || picrec1.incarnation_scn ||
             ' end_reset_scn=' || picrec1.end_resetlogs_scn ||
             ' pr_inc_scn=' || nvl(picrec1.prior_incarnation_scn, '') ||
             ' pr_reset_scn=' || nvl(picrec1.prior_end_resetlogs_scn, ''));
         checkPluggableDbinc(
            NULL, picrec1.guid,
            picrec1.current_incarnation, picrec1.incarnation_scn,
            picrec1.begin_resetlogs_scn, picrec1.begin_resetlogs_time,
            picrec1.end_resetlogs_scn, picrec1.db_resetlogs_scn,
            picrec1.db_resetlogs_time, picrec1.prior_incarnation_scn,
            picrec1.prior_end_resetlogs_scn, picrec1.prior_db_resetlogs_scn,
            picrec1.prior_db_resetlogs_time, FALSE);
         foundrec := TRUE;
      END LOOP;
      CLOSE rc_pluggable_database_inc_c;
      endPluggableDbincResync(siterec.high_pic_recid);
  
      IF NOT foundrec THEN
--
--
         raise_application_error(-20151, 
                'no records found to resync for pluggable db incarnation view');
      END IF;
   END IF;
 
--
   foundrec := FALSE;
   IF beginTableSpaceResync(siterec.high_ts_recid, FALSE) THEN
      OPEN rc_tablespace_c;
      LOOP
         FETCH rc_tablespace_c INTO tbsrec;
         EXIT WHEN rc_tablespace_c%NOTFOUND;
 
--
--
         deb('Calling checkTableSpace');
         checkTableSpace(tbsrec.name, tbsrec.ts#, tbsrec.creation_change#,
                         tbsrec.creation_time, 0 /* rbs_count not populated */,
                         tbsrec.included_in_database_backup, tbsrec.bigfile,
                         tbsrec.temporary, tbsrec.encrypt_in_backup,
                         tbsrec.plugin_change#, tbsrec.con_id, FALSE);
         foundrec := TRUE;
      END LOOP;
      CLOSE rc_tablespace_c;
      endTableSpaceResync;
 
      IF NOT foundrec THEN
--
--
         raise_application_error(-20144, 
                'no records found to resync for tablespace view');
      END IF;
   END IF;
 
--
   foundrec := FALSE;
   IF beginDataFileResync(siterec.high_df_recid) THEN
      OPEN rci_datafile_c;
      LOOP
         FETCH rci_datafile_c INTO dfrec;
         EXIT WHEN rci_datafile_c%NOTFOUND;
 
         checkDataFile(
            file#               => dfRec.file#,
            fname               => dfRec.name,
            create_scn          => dfRec.creation_change#,
            create_time         => dfRec.creation_time,
            blocks              => dfRec.blocks,
            block_size          => dfRec.block_size,
            ts#                 => dfRec.ts#,
            stop_scn            => dfRec.stop_change#,
            read_only           => dfRec.read_only,
            stop_time           => dfRec.stop_time,
            rfile#              => dfRec.rfile#,
            aux_fname           => dfRec.aux_name,
            foreign_dbid        => dfRec.foreign_dbid,
            foreign_create_scn  => dfRec.foreign_creation_change#,
            foreign_create_time => dfRec.foreign_creation_time,
            plugged_readonly    => dfRec.plugged_readonly,
            plugin_scn          => dfRec.plugin_change#,
            plugin_reset_scn    => dfRec.plugin_resetlogs_change#,
            plugin_reset_time   => dfRec.plugin_resetlogs_time,
            create_thread       => dfRec.creation_thread,
            create_size         => dfRec.creation_size,
            con_id              => dfRec.con_id,
            pdb_closed          => dfRec.pdb_closed,
            pdb_dict_check      => FALSE,
            pdb_foreign_dbid    => dfRec.pdb_foreign_dbid,
            pdb_foreign_ckp_scn => dfRec.pdb_foreign_ckp_scn,
            pdb_foreign_afn     => dfRec.pdb_foreign_afn);
 
         foundrec := TRUE;
      END LOOP;
      CLOSE rci_datafile_c;
      endDataFileResync;
 
      IF NOT foundrec THEN
--
--
         raise_application_error(-20145, 
                'no records found to resync for datafile view');
      END IF;
   END IF;
 
--
--
   foundrec := FALSE;
   IF beginTempFileResync(siterec.high_tf_recid) THEN
      OPEN rci_tempfile_c;
      LOOP
         FETCH rci_tempfile_c INTO tfrec;
         EXIT WHEN rci_tempfile_c%NOTFOUND;
 
         checkTempFile(
            file#          => tfrec.file#,
            fname          => tfrec.name,
            create_scn     => tfrec.creation_change#,
            create_time    => tfrec.creation_time,
            blocks         => tfrec.blocks,
            block_size     => tfrec.block_size,
            ts#            => tfrec.ts#,
            rfile#         => tfrec.rfile#,
            autoextend     => tfrec.autoextend,
            max_size       => tfrec.maxsize,
            next_size      => tfrec.nextsize,
            con_id         => tfrec.con_id,
            pdb_dict_check => FALSE);
         foundrec := TRUE;
 
      END LOOP;
      CLOSE rci_tempfile_c;
      endTempFileResync;
 
      IF NOT foundrec THEN
--
--
         raise_application_error(-20145, 
                'no records found to resync for tempfile view');
      END IF;
   END IF;
 
--
   foundrec := FALSE;
   IF beginThreadResync(siterec.high_rt_recid) THEN
      OPEN rc_redo_thread_c;
      LOOP
         FETCH rc_redo_thread_c INTO rtrec;
         EXIT WHEN rc_redo_thread_c%NOTFOUND;
 
         dbms_rcvcat.checkThread
              (rtrec.thread#, rtrec.sequence#, rtrec.enable_change#,
              rtrec.enable_time, rtrec.disable_change#, rtrec.disable_time,
              rtrec.status);
         foundrec := TRUE;
      END LOOP;
      CLOSE rc_redo_thread_c;
      endThreadResync;
 
      IF NOT foundrec THEN
--
--
         raise_application_error(-20146, 
                'no records found to resync for thread view');
      END IF;
   END IF;
 
--
   foundrec := FALSE;
   IF beginOnlineRedoLogResync(siterec.high_orl_recid) THEN
      OPEN rc_redo_log_c;
      LOOP
         FETCH rc_redo_log_c INTO orlrec;
         EXIT WHEN rc_redo_log_c%NOTFOUND;
 
         checkOnlineRedoLog
              (orlrec.thread#, orlrec.group#, orlrec.name,
               orlrec.bytes, orlrec.type);
         foundrec := TRUE;
      END LOOP;
      CLOSE rc_redo_log_c;
      endOnlineRedoLogResync;
 
      IF NOT foundrec THEN
--
--
         raise_application_error(-20147, 
                'no records found to resync for online redo log view');
      END IF;
   END IF;
 
   offr_key := beginOfflineRangeResync;
   IF ((wmrec.high_offr_recid IS NOT NULL AND
        wmrec.high_offr_recid > 0 AND
        local_wmrec.high_offr_recid = wmrec.high_offr_recid) OR
       (siterec.high_offr_recid = 0)) THEN
      foundrec := TRUE;
   ELSE
      foundrec := FALSE;
   END IF;
 
   OPEN rc_offline_range_c;
   LOOP
      FETCH rc_offline_range_c INTO offrrec;
      EXIT WHEN rc_offline_range_c%NOTFOUND;
 
--
--
--
      checkOfflineRange(
              offrrec.offr_key, offrrec.stamp, offrrec.file#,
              offrrec.creation_change#,
              offrrec.offline_change#, offrrec.online_change#,
              offrrec.online_time, offrrec.cf_create_time, 
              offrrec.resetlogs_change#, offrrec.resetlogs_time);
      foundrec := TRUE;
   END LOOP;
   CLOSE rc_offline_range_c;
   endOfflineRangeResync;
 
   IF NOT foundrec THEN
--
--
      deb('wmrec.high_offr_recid=' || wmrec.high_offr_recid);
      deb('local_wmrec.high_offr_recid=' || local_wmrec.high_offr_recid);
      raise_application_error(-20148, 
             'no records found to resync for offline range view');
   END IF;
   
 
--
 
   sanityCheck;
   endCkpt;
 
   deb('readFixedSections: (suc) ' || siterec.db_unique_name);
 
EXCEPTION
   WHEN OTHERS THEN
      deb('readFixedSections: (fail) ' || siterec.db_unique_name);
      cancelCkpt;
      raise;
END readFixedSections;
 
--
--
PROCEDURE writeBackupSections(input_xml_filename  IN VARCHAR2,
                              bktname IN VARCHAR2 DEFAULT NULL) IS
   v_ctx     DBMS_XMLGen.ctxHandle;
   v_xml     CLOB;
   v_xml_tmp CLOB;
   type record_sql_type is table of varchar2(2048) 
             index by binary_integer;
   type record_tbl_type is table of varchar2(30) 
             index by binary_integer;
   record_sql  record_sql_type;
   record_tbl  record_tbl_type;
   my_dbid      number;
 
   write_xml_filename rcfile.name%TYPE;
   local_wmrec        rc_watermarks%ROWTYPE;
   l_prefix           rcfile.name%TYPE;
   l_job_ckp_cf_seq   number;
 
BEGIN
 
   deb('writeBackupSections:enter, expects caller to commit');
 
--
   my_dbid := to_number(substr(input_xml_filename,
                               length(this_forwatermarks)+1,
                               instr(input_xml_filename,'.xml')-1
                                     -length(this_forwatermarks)));
   deb('writeBackupSections:my_dbid=' || my_dbid);
 
   BEGIN
      SELECT DB_KEY INTO this_db_key FROM DB
         WHERE db_id = my_dbid;
   EXCEPTION
      WHEN NO_DATA_FOUND THEN
         deb('writeBackupSections:database with dbid=' || my_dbid ||
                                 ' not found in recovery catalog');
         RETURN;
   END;
 
   deb('writeBackupSections:this_db_key=' || this_db_key);
   BEGIN
      select * into local_wmrec from rc_watermarks where db_key = this_db_key;
      displayRCWatermarks('writeBackupSections local:', local_wmrec);
   EXCEPTION
      WHEN NO_DATA_FOUND THEN
         deb('writeBackupSections:database with dbid=' || my_dbid ||
                                 ' no setDatabase called yet');
         RETURN;
   END;
 
--
   l_job_ckp_cf_seq := local_wmrec.high_bp_recid + local_wmrec.high_do_key;
   IF this_rsiterec.cf_create_time = local_wmrec.rs_version_stamp AND
      this_rsiterec.job_ckp_cf_seq = l_job_ckp_cf_seq THEN
      deb('writeBackupSections:No new backup piece or deleted object added');
      RETURN;
   END IF;
 
   record_tbl(0)   := 'RC_DATABASE';
   record_sql(0)   := 'SELECT * FROM RC_DATABASE ' || 
                         'WHERE DB_KEY = ' || this_db_key;
 
   record_tbl(1)   := 'RCI_BACKUP_SET';
   record_sql(1)   := 'SELECT * FROM RCI_BACKUP_SET ' || 
                         'WHERE DB_KEY = ' || this_db_key ||
                         '  AND BS_KEY IN ' ||
                         '    (SELECT DISTINCT BS_KEY FROM BP ' ||
                         '       WHERE BP_RECID > '||
                         NVL(this_rsiterec.high_bp_recid, 0) ||
                         '    )';
 
   record_tbl(2)   := 'RCI_BACKUP_PIECE';
   record_sql(2)   := 'SELECT * FROM RCI_BACKUP_PIECE ' ||
                         'WHERE DB_KEY = ' || this_db_key ||
                         '  AND RECID > ' || 
                         NVL(this_rsiterec.high_bp_recid,0);
 
   record_tbl(3)   := 'RCI_BACKUP_DATAFILE';
   record_sql(3)   := 'SELECT * FROM RCI_BACKUP_DATAFILE ' ||
                         'WHERE DB_KEY   = ' || this_db_key ||
                         '  AND BS_KEY IN ' ||
                         '    (SELECT DISTINCT BS_KEY FROM BP ' ||
                         '       WHERE BP_RECID > ' || 
                         NVL(this_rsiterec.high_bp_recid, 0) ||
                         '    )';
 
   record_tbl(4)   := 'RCI_BACKUP_CONTROLFILE';
   record_sql(4)   := 'SELECT * FROM RCI_BACKUP_CONTROLFILE ' ||
                         'WHERE DB_KEY   = ' || this_db_key ||
                         '  AND BS_KEY IN ' ||
                         '    (SELECT DISTINCT BS_KEY FROM BP ' ||
                         '       WHERE BP_RECID > ' || 
                         NVL(this_rsiterec.high_bp_recid, 0) ||
                         '    )';
 
   record_tbl(5)   := 'RC_BACKUP_REDOLOG';
   record_sql(5)   := 'SELECT * FROM RC_BACKUP_REDOLOG ' ||
                         'WHERE DB_KEY   = ' || this_db_key ||
                         '  AND BS_KEY IN ' ||
                         '    (SELECT DISTINCT BS_KEY FROM BP ' ||
                         '       WHERE BP_RECID > ' || 
                         NVL(this_rsiterec.high_bp_recid, 0) ||
                         '    )';
 
   record_tbl(6)   := 'RCI_BACKUP_SPFILE';
   record_sql(6)   := 'SELECT * FROM RCI_BACKUP_SPFILE ' ||
                         'WHERE DB_KEY   = ' || this_db_key ||
                         '  AND BS_KEY IN ' ||
                         '    (SELECT DISTINCT BS_KEY FROM BP ' ||
                         '       WHERE BP_RECID > ' || 
                         NVL(this_rsiterec.high_bp_recid, 0) ||
                         '    )';
 
   record_tbl(7)   := 'RC_RCVER';
   record_sql(7)   := 'SELECT * FROM RC_RCVER ';
 
 
   record_tbl(8)   := 'RC_WATERMARKS';
   record_sql(8)   := 'SELECT * FROM RC_WATERMARKS ' || 
                         'WHERE DB_KEY = ' || this_db_key;
 
   record_tbl(9)   := 'RC_DELETED_OBJECT';
   record_sql(9)   := 'SELECT * FROM RC_DELETED_OBJECT ' ||
                         'WHERE DB_KEY = ' || this_db_key ||
                         '  AND DO_KEY > ' || 
                         NVL(this_rsiterec.high_do_recid, 0);
 
--
   v_xml := this_xml_signature_beg;
   FOR idx in 0..9 LOOP
      deb('writing XML file for ' || idx);
      deb('executing query:'|| record_sql(idx));
 
      v_ctx := DBMS_XMLGen.newContext(record_sql(idx));
 
--
      DBMS_XMLGen.setRowsetTag(v_ctx, 'TABLE_' || record_tbl(idx));
      v_xml_tmp := DBMS_XMLGen.GetXML(v_ctx);
      DBMS_XMLGen.closeContext(v_ctx);
 
      deb('XML len for '||idx||'=' || DBMS_LOB.GETLENGTH(v_xml_tmp));
      IF v_xml_tmp IS NOT NULL THEN
         DBMS_LOB.COPY(v_xml, v_xml_tmp, DBMS_LOB.LOBMAXSIZE, 
                       DBMS_LOB.GETLENGTH(v_xml),
                       DBMS_LOB.INSTR(v_xml_tmp, 
                                  '<TABLE_' || record_tbl(idx) ||'>'));
      END IF;
   END LOOP;
   v_xml := v_xml || this_xml_signature_end;
 
--
   l_prefix := 
      this_backupsets || my_dbid || '_' || 
      date2stamp(local_wmrec.rs_version_stamp) || '_';
   write_xml_filename :=  l_prefix || l_job_ckp_cf_seq || '.xml';
 
   IF this_amazon_server THEN
      put_object(null /*bktname */, write_xml_filename, 'text/xml', v_xml);
   ELSE
      DELETE rcfile WHERE name LIKE l_prefix || '%';
      IF SQL%ROWCOUNT > 0 THEN
         deb('writeBackupSections:deleted old backupset rows:' ||SQL%ROWCOUNT);
      END IF;
      INSERT INTO rcfile(rcfile_key, creation_time, name, xmldoc)
         VALUES (rman_seq.nextval, sys_extract_utc(systimestamp), 
                 write_xml_filename, XMLType.createXML(v_xml));
   END IF;
 
   deb('writeBackupSections:(suc) file:' || write_xml_filename);
END writeBackupSections;
 
PROCEDURE readBackupSections(bktname IN VARCHAR2 DEFAULT NULL) IS
 
 
   bs_xml_filename RCFILE.NAME%TYPE;
 
   bsrec  RCI_BACKUP_SET%ROWTYPE;
   CURSOR rci_backup_set_c IS
   SELECT DB_KEY,
          DB_ID, 
          BS_KEY,  
          RECID, 
          STAMP, 
          SET_STAMP,
          SET_COUNT,
          BACKUP_TYPE,
          INCREMENTAL_LEVEL,
          PIECES,
          START_TIME,
          COMPLETION_TIME,
          ELAPSED_SECONDS,
          STATUS,
          CONTROLFILE_INCLUDED,
          INPUT_FILE_SCAN_ONLY,
          KEEP,
          KEEP_UNTIL,
          decode (KEEP_OPTIONS, 'LOGS'         , 256
                              , 'NOLOGS'       , 512
                              , 'BACKUP_LOGS'  , 1024
                                               , 0) KEEP_OPTIONS,
          BLOCK_SIZE,
          SITE_KEY,
          MULTI_SECTION,
          GUID,
          PDB_KEY
   FROM "_RS_RCI_BACKUP_SET_"
   WHERE RS_RCFILE_NAME = bs_xml_filename
   ORDER BY RECID;
 
   bprec  RCI_BACKUP_PIECE%ROWTYPE;
   CURSOR rci_backup_piece_c IS
   SELECT DB_KEY,
          DB_ID,
          BP_KEY,
          RECID,
          STAMP,
          BS_KEY,
          SET_STAMP,
          SET_COUNT,
          BACKUP_TYPE,
          INCREMENTAL_LEVEL,
          PIECE#,
          COPY#,
          DEVICE_TYPE,
          HANDLE,
          COMMENTS,
          MEDIA,
          MEDIA_POOL,
          CONCUR,
          TAG,
          START_TIME,
          COMPLETION_TIME,
          ELAPSED_SECONDS,
          STATUS,
          BYTES,
          IS_RECOVERY_DEST_FILE,
          RSR_KEY,
          COMPRESSED,
          SITE_KEY,
          ENCRYPTED,
          BACKED_BY_OSB,
          SUBSTR(BA_ACCESS,1,1) BA_ACCESS,
          VB_KEY,
          VIRTUAL,
          LIB_KEY,
          GUID,
          PDB_KEY
   FROM "_RS_RCI_BACKUP_PIECE_"
   WHERE RS_RCFILE_NAME = bs_xml_filename
   ORDER BY RECID;
 
   bdfrec  RCI_BACKUP_DATAFILE%ROWTYPE;
   CURSOR rci_backup_datafile_c IS
   SELECT DB_KEY,
          DBINC_KEY,
          DB_NAME,
          BDF_KEY,
          RECID,
          STAMP,
          BS_KEY,
          SET_STAMP,
          SET_COUNT,
          BS_RECID,
          BS_STAMP,
          BACKUP_TYPE,
          INCREMENTAL_LEVEL,
          COMPLETION_TIME,
          FILE#,
          CREATION_CHANGE#,
          CREATION_TIME,
          RESETLOGS_CHANGE#,
          RESETLOGS_TIME,
          INCREMENTAL_CHANGE#,
          CHECKPOINT_CHANGE#,
          CHECKPOINT_TIME,
          ABSOLUTE_FUZZY_CHANGE#,
          DATAFILE_BLOCKS,
          BLOCKS,
          BLOCK_SIZE,
          STATUS,
          BS_LEVEL,
          PIECES,
          BLOCKS_READ,
          MARKED_CORRUPT,
          USED_CHANGE_TRACKING,
          USED_OPTIMIZATION,
          PCT_NOTREAD,
          FOREIGN_DBID,
          PLUGGED_READONLY,
          PLUGIN_CHANGE#,
          PLUGIN_RESETLOGS_CHANGE#,
          PLUGIN_RESETLOGS_TIME,
          SECTION_SIZE,
          GUID,
          SPARSE_BACKUP,
          PDB_KEY
   FROM "_RS_RCI_BACKUP_DATAFILE_"
   WHERE RS_RCFILE_NAME = bs_xml_filename
   UNION
      SELECT DB_KEY,
          DBINC_KEY,
          DB_NAME,
          BCF_KEY,
          RECID,
          STAMP,
          BS_KEY,
          SET_STAMP,
          SET_COUNT,
          BS_RECID,      
          BS_STAMP,      
          decode(BS_LEVEL, 0, 'D', null, 'D', 'I') BACKUP_TYPE,
          BS_LEVEL INCREMENTAL_LEVEL,
          COMPLETION_TIME,
          0 FILE#,
          0 CREATION_CHANGE#,
          CREATION_TIME,
          RESETLOGS_CHANGE#,
          RESETLOGS_TIME,
          0 INCREMENTAL_CHANGE#,
          CHECKPOINT_CHANGE#,
          CHECKPOINT_TIME,
          0 ABSOLUTE_FUZZY_CHANGE#,
          0 DATAFILE_BLOCKS,
          BLOCKS,        
          BLOCK_SIZE,
          STATUS,        
          BS_LEVEL,
          NULL PIECES,
          NULL BLOCKS_READ,
--
--
--
          to_number(to_char(to_date(autobackup_date),'YYYY')) MARKED_CORRUPT,
          'NO' USED_CHANGE_TRACKING,
          'NO' USED_OPTIMIZATION,
          AUTOBACKUP_SEQUENCE PCT_NOTREAD,
          0 FOREIGN_DBID,
          CONTROLFILE_TYPE PLUGGED_READONLY, 
          OLDEST_OFFLINE_RANGE PLUGIN_CHANGE#,
          to_number(to_char(to_date(autobackup_date),'MM')||
             to_char(to_date(autobackup_date),'DD')) PLUGIN_RESETLOGS_CHANGE#,
          NULL PLUGIN_RESETLOGS_TIME,
          NULL SECTION_SIZE,
          GUID,
          'NO' sparse_backup,
          PDB_KEY
   FROM "_RS_RCI_BACKUP_CONTROLFILE_"
   WHERE RS_RCFILE_NAME = bs_xml_filename
   ORDER BY 5;
 
   bsfrec  RCI_BACKUP_SPFILE%ROWTYPE;
   CURSOR rci_backup_spfile_c IS
   SELECT DB_KEY,
          BSF_KEY,
          RECID,
          STAMP,
          BS_KEY,
          SET_STAMP,
          SET_COUNT,
          MODIFICATION_TIME,
          STATUS,
          BS_RECID,
          BS_STAMP,
          COMPLETION_TIME,
          BYTES,
          DB_UNIQUE_NAME,
          GUID
   FROM "_RS_RCI_BACKUP_SPFILE_"
   WHERE RS_RCFILE_NAME = bs_xml_filename
   ORDER BY RECID;
 
   brlrec  RC_BACKUP_REDOLOG%ROWTYPE;
   CURSOR rc_backup_redolog_c IS
   SELECT DB_KEY,
          DBINC_KEY,                                
          DB_NAME,                                  
          BRL_KEY,                                  
          RECID,                                    
          STAMP,                                    
          BS_KEY,                                   
          SET_STAMP,                                
          SET_COUNT,                                
          BACKUP_TYPE,                                       
          COMPLETION_TIME,                                   
          THREAD#,                                  
          SEQUENCE#,                                
          RESETLOGS_CHANGE#,                        
          RESETLOGS_TIME,                           
          FIRST_CHANGE#,                            
          FIRST_TIME,                               
          NEXT_CHANGE#,                             
          NEXT_TIME,                                
          BLOCKS,                                   
          BLOCK_SIZE,                               
          STATUS,                                            
          BS_RECID,
          BS_STAMP,
          PIECES,
          TERMINAL,
          PARTIAL
   FROM "_RS_RC_BACKUP_REDOLOG_"
   WHERE RS_RCFILE_NAME = bs_xml_filename
   ORDER BY RECID;
 
   dlrec  RC_DELETED_OBJECT%ROWTYPE;
   CURSOR rc_deleted_object_c IS
   SELECT DB_KEY,
          DO_KEY,
          OBJECT_TYPE,
          OBJECT_KEY,                                  
          OBJECT_STAMP,                                  
          OBJECT_DATA,                                    
          SET_STAMP,                                
          SET_COUNT,
          HANDLE,
          DEVICE_TYPE
   FROM "_RS_RC_DELETED_OBJECT_"
   WHERE RS_RCFILE_NAME = bs_xml_filename
   ORDER BY DO_KEY;
 
   bsname "_RS_RC_GET_OBJECT_LIST_"%ROWTYPE;
   CURSOR bsnames_c(prefix in varchar2) IS
   SELECT *
   FROM "_RS_RC_GET_OBJECT_LIST_"
   WHERE prefix = bsnames_c.prefix
   ORDER BY rcfile_name asc;
 
   my_dbid      NUMBER;
   ckp_type     NUMBER;
   v_xml_tmp    CLOB; -- TODO remove this after changing get_object prototype
   local_node   NODE%ROWTYPE;
   prefix_value    "_RS_RC_GET_OBJECT_LIST_".PREFIX%TYPE;
 
   resync_not_needed EXCEPTION;
   PRAGMA EXCEPTION_INIT(resync_not_needed, -20034);
 
   incarnation_not_known EXCEPTION;
   PRAGMA EXCEPTION_INIT(incarnation_not_known, -20003);
   
   max_copy_num     NUMBER;
   l_bs_key         NUMBER;
   cursor_name      INTEGER;
   dummy            INTEGER;
   
   r_bp_key       NUMBER;
   r_dbver        NUMBER;
   r_dbid         NUMBER;
   r_db_name      dbinc.db_name%TYPE;
   r_handle       bp.handle%TYPE;
   r_setstamp     NUMBER;
   r_setcount     NUMBER;
   r_pieceno      NUMBER;
   r_pieceblksize NUMBER;
   r_tag          bp.tag%TYPE;
   r_bstyp        NUMBER;
   r_cnt          NUMBER;
   l_dbkey        NUMBER;
   l_cnt          NUMBER;
   l_compressed   bp.compressed%TYPE;
   l_encrypted    bp.encrypted%TYPE;
   l_incremental  NUMBER;
   l_bstyp        NUMBER;
   l_recid        NUMBER;
   l_job_ckp_cf_seq NUMBER;
 
BEGIN
   deb('readBackupSections - enter');
 
--
   IF this_server.server_host IS NULL THEN
      deb('readBackupSections: this_server.server_host is null');
      return;
   END IF;
 
   IF this_curr_inc.dbid IS NULL OR this_wmrec.cf_version_stamp IS NULL THEN
      deb('readBackupSections: DB was registered or inc mismatch, re-read');
      writeForWatermarks(bktname, TRUE);
      rsReadWaterMarks(bktname);
   END IF;
 
--
   IF this_upstream_dbrec.name IS NULL THEN
      raise_application_error(-20999, 'internal error: no rows for upstreamdb');
   END IF;
 
   IF this_url_db_unique_name IS NULL THEN
      raise_application_error(-20999,'internal error:this_url_db_unique_name2');
   END IF;
 
   IF (this_curr_inc.dbid IS NULL) THEN
      raise_application_error(-20021, 'Database not set');
   END IF;
 
   BEGIN 
      setDatabase(db_name => this_curr_inc.name,
                  reset_scn => this_curr_inc.resetlogs_change#,
                  reset_time => this_curr_inc.resetlogs_time,
                  db_id => this_curr_inc.dbid,
                  db_unique_name => 
                     this_upstream_dbrec.name||'$'|| this_url_db_unique_name,
                  dummy_instance => FALSE,
                  cf_type => CF_STANDBY,
                  site_aware => TRUE,
                  ors_instance => TRUE);
   EXCEPTION
      WHEN incarnation_not_known THEN
--
--
--
         deb('readBackupSections: New incarnation not yet known to upstream');
         IF debug THEN
            displayRCDatabaseIncarnation('readBackupSections: remote ', 
                                          this_curr_inc);
         END IF;
         RETURN;
   END;
 
--
   dbms_session.set_nls('NLS_DATE_FORMAT','''DD-MM-YYYY HH24:MI:SS''');
 
--
--
   BEGIN
      writeForWatermarks(bktname, FALSE);
      rsReadWaterMarks(bktname);
   EXCEPTION
      WHEN OTHERS THEN
         deb('readBackupSections: error during watermarks read:' || sqlerrm);
         RAISE;
   END;
 
   IF this_wmrec.rs_version_stamp is NULL THEN
      deb('readBackupSections: no watermarks yet populated at ORS');
      RETURN;
   END IF;
 
   SELECT * into local_node FROM NODE
      WHERE db_key = this_db_key
        AND site_key = this_site_key;
 
--
   l_job_ckp_cf_seq := this_wmrec.high_bp_recid + this_wmrec.high_do_key;
   IF local_node.cf_create_time = this_wmrec.rs_version_stamp AND
      local_node.job_ckp_cf_seq = l_job_ckp_cf_seq THEN
--
      deb('readBackuupSections: no events to reconcile from ORS to catalog');
      return;
   END IF;
 
   deb('local_node.cf_create_time='||local_node.cf_create_time);
   deb('local_node.job_ckp_cf_seq='||local_node.job_ckp_cf_seq);
 
--
   lockForCkpt;
   ckp_type := ckptNeeded(ckp_scn => 0,
                          ckp_cf_seq => l_job_ckp_cf_seq,
                          cf_version => this_wmrec.rs_version_stamp,
                          cf_type => CF_STANDBY,
                          high_df_recid => 0,
                          high_orl_recid => 0,
                          high_cdf_recid => 0,
                          high_al_recid => 0,
                          high_bp_recid => this_wmrec.high_bp_recid,
                          high_do_recid => this_wmrec.high_do_key,
                          high_offr_recid => 0,
                          high_pc_recid => 0,
                          high_conf_recid => 0,
                          rltime => this_curr_inc.resetlogs_time,
                          high_ts_recid => 0,
                          high_bs_recid => 0,
                          lopen_reset_scn => NULL,
                          lopen_reset_time => NULL,
                          high_ic_recid => 0,
                          high_tf_recid => 0,
                          high_rt_recid => 0,
                          high_grsp_recid => 0,
                          high_nrsp_recid => 0,
                          high_bcr_recid => 0,
                          high_pdb_recid => 0,
                          high_pic_recid => 0);
   IF ckp_type <> RESYNC_PARTIAL THEN
      deb('readBackupSections: resync not required, ckp_type=' || ckp_type);
      cancelCkpt;
      return;
   END IF;
 
   BEGIN
      beginCkpt(ckp_scn => 0,
                ckp_cf_seq => l_job_ckp_cf_seq,
                cf_version => this_wmrec.rs_version_stamp,
                ckp_time => NULL,
                ckp_type => 'PARTIAL',
                ckp_db_status => NULL,
                high_df_recid => 0,
                cf_type => 'STANDBY');
   EXCEPTION
      WHEN resync_not_needed THEN
         deb('readBackupSections:resync not needed from beginCkpt');
         return;
   END;
 
--
--
   SELECT DBID INTO MY_DBID FROM RC_DATABASE
      WHERE DB_KEY=this_db_key;
 
--
   prefix_value := this_backupsets || my_dbid || '_' ||
                   date2stamp(this_wmrec.rs_version_stamp) || '_';
 
--
--
--
   v_xml_tmp := get_object(bktname, null, 'prefix='||prefix_value);
 
   OPEN bsnames_c(prefix_value);
   LOOP
      FETCH bsnames_c INTO bsname;
      EXIT WHEN bsnames_c%NOTFOUND;
      bs_xml_filename := bsname.rcfile_name;
 
      deb('readBackupSections: got file ' || bs_xml_filename);
 
--
      v_xml_tmp := get_object(bktname, bs_xml_filename);
 
--
      l_recid := beginBackupsetResync;
      OPEN rci_backup_set_c;
      LOOP
         FETCH rci_backup_set_c INTO bsrec;
         EXIT WHEN rci_backup_set_c%NOTFOUND;
 
         deb('Calling checkBackupset');
         dbms_rcvcat.checkBackupSet(
                 bsrec.recid, bsrec.stamp, bsrec.set_stamp, bsrec.set_count,
                 bsrec.backup_type, bsrec.incremental_level, bsrec.pieces,
                 bsrec.start_time, bsrec.completion_time,
                 bsrec.controlfile_included, bsrec.input_file_scan_only,
                 bsrec.keep_options, bsrec.keep_until, bsrec.block_size,
                 bsrec.multi_section, FALSE /* chk_last_recid */,
                 bsrec.guid);
      END LOOP;
      CLOSE rci_backup_set_c;
      endBackupsetResync;
 
--
      l_recid := beginBackupPieceResync;
      OPEN rci_backup_piece_c;
      LOOP
         FETCH rci_backup_piece_c INTO bprec;
         EXIT WHEN rci_backup_piece_c%NOTFOUND;
         
--
         SELECT bs_key INTO l_bs_key FROM bs
           WHERE bs.db_key = this_db_key
             AND   bs.set_stamp = bprec.set_stamp
             AND   bs.set_count = bprec.set_count;
         
         SELECT NVL(MAX(copy#), 0)
           INTO max_copy_num 
           FROM bp
           WHERE bs_key = l_bs_key;
         
         IF bprec.ba_access != 'U' THEN
            deb('Calling CheckBackupPiece, handle='|| bprec.handle ||',tag=' ||
                bprec.tag || ',max_copy_num=' || max_copy_num ||',l_bs_key=' ||
                l_bs_key || ',bp_recid=' || bprec.recid);
 
            dbms_rcvcat.checkBackupPiece(
                 bprec.recid, bprec.stamp, bprec.set_stamp, bprec.set_count,
                 bprec.piece#, bprec.tag, 'SBT_TAPE', bprec.handle,
                 bprec.comments, this_server.rep_server_name, bprec.concur,
                 bprec.start_time, bprec.completion_time, bprec.status,
                 max_copy_num + 1, bprec.media_pool,
                 bprec.bytes, bprec.is_recovery_dest_file,
                 bprec.rsr_key, null /* rman_status_stamp */,
                 bprec.compressed, bprec.encrypted, bprec.backed_by_osb,
                 'R', NULL /* bprec.vb_key */,
                 TRUE /* chk_last_recid */, this_lib_key, bprec.guid, NULL);
              
--
           SELECT bp_key INTO r_bp_key
             FROM bp
             WHERE handle=bprec.handle
               AND piece#=bprec.piece#;
              
--
--
           EXECUTE IMMEDIATE 'SELECT COUNT(*) FROM sbt_catalog WHERE bp_key=:1'
                       INTO l_cnt USING r_bp_key;
 
           IF l_cnt = 0 THEN 
--
--
             cursor_name := dbms_sql.open_cursor;
                
             sys.dbms_sql.parse(cursor_name,   
                               'begin sys.kbrsi_icd.rsAddToSbtCatalog(
                                    bpkey        => :l_bpkey,
                                    dbver        => :l_dbver,
                                    dbname       => :l_dbname,
                                    dbid         => :l_dbid,
                                    handle       => :l_handle,
                                    setstamp     => :l_setstamp,
                                    setcount     => :l_setcount,
                                    pieceno      => :l_pieceno,
                                    pieceblksize => :l_pieceblksize,
                                    tag          => :l_tag,
                                    bstyp        => :l_bstyp
                                 ); end;',
                                 DBMS_SQL.NATIVE);
                
--
--
--
             IF l_dbkey IS NULL THEN
               SELECT db_key INTO l_dbkey
                 FROM db
                 WHERE db_id=bprec.db_id;
 
               EXECUTE IMMEDIATE 'SELECT MAX(cmpvsn) FROM vbdf WHERE db_key=:1'
                 INTO r_dbver USING l_dbkey;
 
               SELECT db_name INTO r_db_name FROM dbinc
                 WHERE dbinc_key = 
                       (SELECT curr_dbinc_key FROM db WHERE db_key = l_dbkey);
             END IF;
                
             IF r_dbver IS NULL THEN
--
--
--
--
--
--
--
--
--
--
--
               deb ('readBackupSections: r_dbver is NULL - set to 0.0.0.0');
               r_dbver := 0;
             END IF;
 
             SELECT block_size, incr_level
               INTO r_pieceblksize, l_incremental
               FROM bs
               WHERE bs_key=l_bs_key;
                
             r_dbid         := bprec.db_id;
             r_handle       := bprec.handle;
             r_setstamp     := bprec.set_stamp;
             r_setcount     := bprec.set_count;
             r_pieceno      := bprec.piece#;
             r_tag          := bprec.tag;
             
--
--
             r_bstyp := 4;
--
--
             IF l_incremental IS NOT NULL THEN
               r_bstyp := r_bstyp + 16;
             END IF;
                
             IF bprec.compressed = 'YES' THEN
               r_bstyp := r_bstyp + 32;
             END IF;
 
             IF bprec.encrypted = 'Y' THEN
               r_bstyp := r_bstyp + 64;
             END IF;
                
             DBMS_SQL.BIND_VARIABLE(cursor_name, ':l_bpkey',   r_bp_key   );
             DBMS_SQL.BIND_VARIABLE(cursor_name, ':l_dbver',   r_dbver    );
             DBMS_SQL.BIND_VARIABLE(cursor_name, ':l_dbname',  r_db_name  );
             DBMS_SQL.BIND_VARIABLE(cursor_name, ':l_dbid',    r_dbid     );
             DBMS_SQL.BIND_VARIABLE(cursor_name, ':l_handle',  r_handle   );
             DBMS_SQL.BIND_VARIABLE(cursor_name, ':l_setstamp',r_setstamp );
             DBMS_SQL.BIND_VARIABLE(cursor_name, ':l_setcount',r_setcount );
             DBMS_SQL.BIND_VARIABLE(cursor_name, ':l_pieceno', r_pieceno  );
             DBMS_SQL.BIND_VARIABLE(cursor_name, ':l_pieceblksize',
                                                            r_pieceblksize);
             DBMS_SQL.BIND_VARIABLE(cursor_name, ':l_tag',     r_tag      );
             DBMS_SQL.BIND_VARIABLE(cursor_name, ':l_bstyp',   r_bstyp    );
 
             deb('Calling rsAddToSbtCatalog');
             dummy := sys.dbms_sql.execute(cursor_name);
             sys.dbms_sql.close_cursor(cursor_name);
 
           END IF;
                
        ELSE 
          deb('Calling CheckBackupPiece ***NOT***, handle='||bprec.handle||
              ',tag=' || bprec.tag || ',max_copy_num=' || max_copy_num ||
              ',l_bs_key=' || l_bs_key || ',bp_recid=' || bprec.recid);
          deb('Ignoring BP rec with bprec.ba_access=' || bprec.ba_access);
        END IF;
      END LOOP;
      CLOSE rci_backup_piece_c;
      endBackupPieceResync;
 
--
      l_recid := beginBackupDataFileResync;
      OPEN rci_backup_datafile_c;
      LOOP
         FETCH rci_backup_datafile_c INTO bdfrec;
         EXIT WHEN rci_backup_datafile_c%NOTFOUND;
 
         deb('Calling checkBackupDatafile');
         dbms_rcvcat.checkBackupDataFile(
                 bdfrec.recid, bdfrec.stamp, bdfrec.set_stamp,
                 bdfrec.set_count, bdfrec.file#, bdfrec.creation_change#,
                 bdfrec.creation_time,
                 bdfrec.resetlogs_change#, bdfrec.resetlogs_time,
                 bdfrec.incremental_level, bdfrec.incremental_change#,
                 bdfrec.checkpoint_change#, bdfrec.checkpoint_time,
                 bdfrec.absolute_fuzzy_change#, bdfrec.datafile_blocks,
                 bdfrec.blocks, bdfrec.block_size, 
                 bdfrec.plugin_change# /*oldest_offline_range*/,
                 bdfrec.completion_time, 
                 bdfrec.plugged_readonly /*controlfile_type*/,
                 bdfrec.marked_corrupt /* cfile_abck_year */, 
                 bdfrec.plugin_resetlogs_change# /* cfile_abck_mon_day */,
                 bdfrec.pct_notread /* cfile_abck_seq */, 
                 FALSE /* chk_last_recid */, bdfrec.blocks_read,
                 bdfrec.used_change_tracking, bdfrec.used_optimization,
                 bdfrec.foreign_dbid, bdfrec.plugged_readonly,
                 bdfrec.plugin_change#, bdfrec.plugin_resetlogs_change#,
                 bdfrec.plugin_resetlogs_time,
                 bdfrec.section_size, bdfrec.guid, bdfrec.sparse_backup);
      END LOOP;
      CLOSE rci_backup_datafile_c;
      endBackupDatafileResync;
 
--
      l_recid := beginBackupRedoLogResync;
      OPEN rc_backup_redolog_c;
      LOOP
         FETCH rc_backup_redolog_c INTO brlrec;
         EXIT WHEN rc_backup_redolog_c%NOTFOUND;
  
         deb('Calling checkBackupRedoLog');
         dbms_rcvcat.checkBackupRedoLog(
                 brlrec.recid, brlrec.stamp, brlrec.set_stamp,
                 brlrec.set_count,
                 brlrec.thread#, brlrec.sequence#, brlrec.resetlogs_change#,
                 brlrec.resetlogs_time, brlrec.first_change#,
                 brlrec.first_time,
                 brlrec.next_change#, brlrec.next_time, brlrec.blocks,
                 brlrec.block_size, FALSE /* chk_last_recid */,
                 brlrec.terminal);
      END LOOP;
      CLOSE rc_backup_redolog_c;
      endBackupRedoLogResync;
 
--
      l_recid := beginBackupSpFileResync;
      OPEN rci_backup_spfile_c;
      LOOP
         FETCH rci_backup_spfile_c INTO bsfrec;
         EXIT WHEN rci_backup_spfile_c%NOTFOUND;
  
         deb('Calling checkBackupSpFile');
         dbms_rcvcat.checkBackupSpFile(
                 bsfrec.recid, bsfrec.stamp, bsfrec.set_stamp, 
                 bsfrec.set_count, bsfrec.modification_time, bsfrec.bytes, 
                 FALSE /* chk_last_recid */,
                 bsfrec.db_unique_name, bsfrec.guid);
      END LOOP;
      CLOSE rci_backup_spfile_c;
      endBackupSpFileResync;
 
--
      l_recid := beginDeletedObjectResync;
      OPEN rc_deleted_object_c;
      LOOP
         FETCH rc_deleted_object_c INTO dlrec;
         EXIT WHEN rc_deleted_object_c%NOTFOUND;
  
         deb('Calling checkDeletedObject for do_key(recid) ' ||
               dlrec.do_key                ||' object type '    ||
               dlrec.object_type           ||' with key '       ||
               dlrec.object_key            ||', stamp '       ||
               dlrec.object_stamp          ||', data '       ||
               dlrec.object_data           ||' and set_stamp '  ||
               nvl(to_char(dlrec.set_stamp), 'NULL') ||' and set_count '  ||
               nvl(to_char(dlrec.set_count), 'NULL') ||', handle ' ||
               dlrec.handle                ||', device_type ' ||
               dlrec.device_type);
 
         dbms_rcvcat.checkDeletedObject(
              dlrec.do_key /* do_recid */, 0 /* do_stamp */,
              dlrec.object_type, dlrec.object_key, dlrec.object_stamp,
              dlrec.object_data,
              null /* dlrec.object_fname */,
              null /* dlrec.object_create_scn */,
              dlrec.set_stamp, dlrec.set_count,
              dlrec.handle, dlrec.device_type);
      END LOOP;
      CLOSE rc_deleted_object_c;
      endDeletedObjectResync;
 
   END LOOP;
   CLOSE bsnames_c;
 
   sanityCheck;
 
--
   deb('readBackupSections:last xml file resynced ' || bs_xml_filename);
   delete rcfile where name like prefix_value || '%' 
                      and name <> bs_xml_filename;
   IF bs_xml_filename IS NOT NULL THEN
      endCkpt;
      deb('readBackupSections(suc)');
   ELSE
      deb('readBackupSections(no_files_found - re-try again)');
      cancelCkpt;
   END IF;
EXCEPTION
   WHEN OTHERS THEN
      deb('readBackupSections(fail):'||sqlerrm);
      cancelCkpt;
      raise;
END readBackupSections;
 
/*----------------------------------------------------------------------------
 * This is for oam front end congestion control. If the requirement for a new  
 * backup job exceeds the system bottleneck the job will have to wait.
 *--------------------------------------------------------------------------*/
 
PROCEDURE throttle_me(p_oam_job_id         IN VARCHAR2,
                      p_channels_reqd      IN NUMBER,
                      p_request_time       IN DATE,
                      p_wait               OUT BOOLEAN,
                      p_error_str          OUT VARCHAR2)
IS
   l_wait      integer;
BEGIN
  
--
  IF NOT this_is_ors THEN
    p_wait := false;
    RETURN;
  END IF;
  
  deb ('throttle_me: request for db: ' || this_db_unique_name);
  
  EXECUTE IMMEDIATE 'begin dbms_rai_throttle_alloc(
                     :p_oam_job_id, :p_db_unique_name, :p_channels_reqd, 
                     :p_request_time, :l_wait, :p_error_str); end;'
          USING IN p_oam_job_id, IN this_db_unique_name, IN p_channels_reqd, 
                IN p_request_time, OUT l_wait, OUT p_error_str;
 
  p_wait := (l_wait > 0);
 
END throttle_me;
 
FUNCTION assert_schema (
  i_schema                   IN VARCHAR2
, i_enquote                  IN BOOLEAN DEFAULT FALSE
)
RETURN VARCHAR2
IS
  l_eschema                  VARCHAR2(130);
  l_schema                   VARCHAR2(130);
BEGIN
  dbms_utility.canonicalize(
    dbms_assert.enquote_name(i_schema, FALSE)
  , l_eschema, 130
  );
  l_schema := dbms_assert.schema_name(l_eschema);
  IF (i_enquote)
  THEN
    RETURN dbms_assert.enquote_name(l_eschema, FALSE);
  ELSE
    RETURN l_schema;
  END IF;
END assert_schema;
 
PROCEDURE assert_schema (
  o_schema                   OUT NOCOPY VARCHAR2
, o_eschema                  OUT NOCOPY VARCHAR2
, i_schema                   IN VARCHAR2
)
IS
BEGIN
  dbms_utility.canonicalize(dbms_assert.enquote_name(i_schema), o_eschema, 130);
  o_schema := dbms_assert.schema_name(o_eschema);
END assert_schema;
 
/*--------------------------------------------------*
 * Package Instantiation:  Initialize Package State *
 *--------------------------------------------------*/
BEGIN
 
  tsRec.ts# := NULL;                    -- not in TableSpaceResync
  dfRec.file# := NULL;                  -- not in middle of dfResync
  version_max_index := version_list.COUNT; -- must match highest index
 
--
--
--
--
--
--
 
--
--
 
--
--
 
--
--
--
--
--
--
--
 
--
--
--
--
--
 
--
--
--
--
--
--
 
--
--
--
 
--
 
--
 
--
 
--
 
  
--
  initOrsAdmin;
 
  IF (orsadmin_user = user) THEN
     this_is_ors_admin := TRUE;
  END IF;
 
  IF (orsadmin_user IS NOT NULL) THEN
     this_is_ors := TRUE;
  END IF;
 
--
  FOR i IN 1..vpd_table_list.COUNT
  LOOP
    IF (vtr_policy_required(i))
    THEN
      g_vpd_required_policies := g_vpd_required_policies + 1;
    END IF;
  END LOOP;
 
  init_package_vars(NULL);
END dbms_rcvcat;
>>>
 
define prvtrmnu_plb
<<<
--
--
--
 
CREATE OR REPLACE PACKAGE BODY dbms_rcvman IS
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
 
--
--
--
 
--
--
--
 
 
MAXSCNVAL  CONSTANT number := 9e125; -- guaranteed higher than any SCN
UB6MAXVAL  CONSTANT number := 281474976710655;
UB8MAXVAL  CONSTANT number := 18446744073709551615;
MAXSEQVAL  CONSTANT number := 2**32-1;
MINDATEVAL CONSTANT date   := to_date('01/01/1900','MM/DD/YYYY');
MAXDATEVAL CONSTANT date   := to_date('12/31/9999','MM/DD/YYYY');
CONST2GVAL CONSTANT number := 2**31;
CONST4GVAL CONSTANT number := 2**32;
 
--
KEEP_NO      CONSTANT number := 0;
KEEP_LOGS    CONSTANT number := 256;
KEEP_NOLOGS  CONSTANT number := 512;
KEEP_CONSIST CONSTANT number := 1024;
 
DEB_UNDEF  CONSTANT number := 0;
DEB_PRINT  CONSTANT number := 0;
DEB_ENTER  CONSTANT number := 1;
DEB_EXIT   CONSTANT number := 2;
DEB_IN     CONSTANT number := 3;
DEB_OPEN   CONSTANT number := 4;
DEB_DEF_PNAME CONSTANT varchar2(50) := 'prvtrmnu';
 
--
BACKUP_SPARSENESS_UNSPECIFIED CONSTANT number := 0;
BACKUP_SPARSENESS_SPARSE      CONSTANT number := 1;
BACKUP_SPARSENESS_NONSPARSE   CONSTANT number := 2;
 
--
--
--
 
--
--
--
highscnval            number := UB6MAXVAL;
 
this_db_key         number := NULL;
this_dbinc_key      number := NULL;
this_reset_scn      number := NULL;
this_reset_time     date;
this_db_unique_name node.db_unique_name%TYPE;  -- used only to identify rows of
this_site_key       number := NULL;        -- configuration and flashback tbl
--
--
this_dummy_instance boolean := FALSE;
this_stdby_controlfile_scn number := NULL;  -- standby controlfile scn used
--
 
--
--
--
--
--
--
--
--
translation_site_key NUMBER := NULL;      -- Never NULL
 
realf_site_key      number := NULL;        -- override df/tf/online log txln
user_site_key       number := NULL;        -- override log/backups/conf/rp txln
user_db_unique_name node.db_unique_name%TYPE; -- corresponds to user_site_key 
client_site_aware   number := 0;
 
--
--
--
--
--
--
logs_shared           number := 0; -- used only when client_site_aware is 1
disk_backups_shared   number := 1; -- indicates shared accross all sites
tape_backups_shared   number := 1; -- indicates shared accross all sites
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
 
TYPE incarnation_set_c IS TABLE OF rc_database_incarnation%ROWTYPE
         index by binary_integer;
inc_list incarnation_set_c;  -- 0th one is current incarnation, see setDatabase
max_inc_idx binary_integer;
currInc     binary_integer;  -- temp variable used to keep track of incarnation
 
--
TYPE pdb_incarnation_set_t IS TABLE OF pdb_incarnation_t
   index by binary_integer;
TYPE pdb_incarnation_coll_t IS TABLE OF pdb_incarnation_set_t
   index by binary_integer;
pdb_inc_list pdb_incarnation_coll_t; -- 0th one is current sub incarnation
 
type pnames is table of varchar2(50) index by binary_integer;
pname_i         number :=0;
last_pnames     pnames;
debug           boolean := FALSE;
rsdebug         boolean := NULL;
 
--
--
--
--
--
--
--
--
this_baseline_cap      number;
this_baseline_cap_scn  number := NULL;
 
--
--
--
 
TYPE rcvRecTab_t IS TABLE OF rcvRec_t;          -- recovery record stack type
 
rcvRecStack rcvRecTab_t := rcvRecTab_t();       -- recovery record stack
 
--
--
--
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
catalogVersion CONSTANT VARCHAR2(11) := '18.04.00.00'; -- @@VERSION_CHANGE@@ set
 
--
--
--
 
TYPE versionList_t IS TABLE OF varchar2(11);
 
--
--
versionList  versionList_t := versionList_t(
                '08.00.04.00'
               ,'08.00.05.00'
               ,'08.01.03.00'
               ,'08.01.05.00'
               ,'08.01.06.00'
               ,'08.01.07.00'
               ,'09.00.00.00'
               ,'09.02.00.00'
               ,'10.01.00.00'
               ,'10.02.00.00'
               ,'10.02.00.01'
               ,'11.01.00.00'
               ,'11.01.00.01'
               ,'11.01.00.02'
               ,'11.01.00.03'
               ,'11.01.00.04'
               ,'11.01.00.05'
               ,'11.01.00.06'
               ,'11.01.00.07'
               ,'11.02.00.00'
               ,'11.02.00.01'
               ,'11.02.00.02'
               ,'12.01.00.00'
               ,'12.01.00.01'
               ,'12.01.00.02'
               ,'12.02.00.00'
               ,'12.02.00.01'
               ,'12.02.00.02'
               ,catalogVersion -- @@VSN_CHANGE@@
               );
versionMaxIndex         binary_integer;
versionCounter          binary_integer;
 
--
--
--
 
 
--
getParentIncarnationKey number;
 
--
--
--
 
allIncarnations number;                 -- allow records from non-current
--
 
ignoreCreationSCN number;               -- a stupid flag that is here
--
--
--
--
 
--
lbacked_al_next_scn        NUMBER;
standby_became_primary_scn NUMBER;
 
--
--
TYPE lognames_set_c IS TABLE OF al.fname%TYPE
         index by binary_integer;
lognames_list lognames_set_c;  -- All the log names returned for same logseq
max_lognames_idx binary_integer;
 
--
--
--
--
canApplyAnyRedo number := FALSE#;
 
--
--
--
--
craGetAllCfBackups number := FALSE#;
 
--
--
--
canConvert_Cf number := FALSE#;
 
redoRec      rcvRec_t;
 
untilSCN        number;
untilTime       date;
rpoint_set      boolean;
 
restoreSource   number;
restoreSparse   number := BACKUP_SPARSENESS_UNSPECIFIED;
restoreTag      bp.tag%TYPE;
 
onlyStandby     number;
 
--
--
--
 
TYPE deviceList_t IS TABLE OF rc_backup_piece.device_type%TYPE
     INDEX BY binary_integer;
 
deviceList      deviceList_t;
deviceCount     number;
diskDevice      boolean;
anyDevice       number;
 
--
--
--
recoveryDestFile  boolean;
 
--
--
--
localOrsSiteKey number := null;
 
--
--
--
restoreRangeDevTyp varchar2(10) := null;
 
--
--
--
skipOfflineRangeAboveSCN number := null;
 
--
--
--
orsLocalFile  boolean := null;
orsLibKey     number  := null;
orsAnyFile    boolean := null;
 
--
--
--
--
--
--
--
--
--
redoLogDeletionPolicyType  varchar2(512) := 'TO NONE';
 
--
--
--
extendFullSCN  CONSTANT BINARY_INTEGER := 2**0;
extendIncrSCN  CONSTANT BINARY_INTEGER := 2**1;
extendLogSCN   CONSTANT BINARY_INTEGER := 2**2;
extendAllSCN   CONSTANT BINARY_INTEGER :=
   extendFullSCN + extendIncrSCN + extendLogSCN;
 
--
--
--
--
--
--
--
--
--
--
--
--
--
 
--
noHint constant binary_integer         := 0;
redundantHint constant binary_integer  := 1;
localityHint constant binary_integer   := 2;
 
TYPE cacheBsRecRow_t IS RECORD
(
   deviceindx   binary_integer,    -- index into cacheBsRecTable.devicelist
   tag          varchar2(32),      -- may be null
   copyNumber   binary_integer,    -- null if code 2 or 3
   code         binary_integer     -- 1 => same copy#
--
--
);
TYPE cacheBsRecIndex_t IS TABLE OF cacheBsRecRow_t INDEX BY BINARY_INTEGER;
TYPE cacheBsRecHash_t IS RECORD
(
   bskey       number,             -- backupset key
   mixcopy     boolean := FALSE,   -- TRUE if mixcopy can make set usuable
   copy        cacheBsRecIndex_t   -- list of copies
);
TYPE cacheBsRecHashList_t IS TABLE OF cacheBsRecHash_t INDEX BY BINARY_INTEGER;
TYPE cacheBsRecBsKey_t IS RECORD
(
   bsindex     binary_integer := 1,    -- index into bslist
   bslist      cacheBsRecHashList_t    -- list of backupset keys in hash table
);
TYPE cacheBsRec_t IS TABLE OF cacheBsRecBsKey_t INDEX BY BINARY_INTEGER;
TYPE cacheBsRecTable_t IS RECORD
(
   initlimit   boolean := FALSE,              -- is limit initialized?
   limit       number  := bsRecCacheLowLimit, -- cache size
   chit        number  := 0,                  -- no: of hits in cache
   mixcopy     boolean := FALSE,              -- does cache have mix of copyno?
   minbskey    number  := 0,                  -- minimum valid bskey
 
   hint        binary_integer := noHint, -- access pattern hint
--
--
--
--
   devicetype  rc_backup_piece.device_type%TYPE,
   mask        binary_integer,
   tag         rc_backup_piece.tag%TYPE,
 
   devicelist  deviceList_t,       -- list of devices
   devicecount binary_integer := 0,
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
   bsRec    cacheBsRec_t,
 
--
--
--
   hitindex    binary_integer := 1,     -- index into hit list
   hitlist     numTab_t
--
--
--
--
--
--
--
--
--
--
--
);
cacheBsRecTable  cacheBsRecTable_t;
 
TYPE cacheRequest_t IS RECORD
(
   bskey                  number,
   icopy                  binary_integer
);
findValidCacheRequest     cacheRequest_t;
 
--
--
--
 
TYPE rcvRecStackState_t IS RECORD
(
   lowAction   number,                  -- action with lowest from_scn on
--
--
--
--
--
   savePoint   number,                  -- most recently added full_act_t
   fullBackups number,                  -- number of full_act_t
   top         number                   -- top of stack at start of a recursive
--
--
);
 
rcvRecStackState        rcvRecStackState_t;
 
--
--
--
 
computeRA_allRecords    number;         -- do not stop at first full backup and
--
 
computeRA_fullBackups   number;         -- stop when reached these many full
--
 
computeRA_restorable    boolean;        -- cannot recover the datafile we've
--
--
--
 
computeRA_available     boolean;        -- there is a backup available on
--
 
computeRA_availableMask binary_integer;
 
computeRA_rcvCopy_avail boolean;        -- there is a backup available on
--
--
--
 
--
action_OK                number := 0;
action_FAIL              number := 1;
action_SKIP              number := 2;
action_OLD_REDO          number := 3;
action_WRONG_INCARNATION number := 4;
action_OLD_INC_REDO      number := 5;
 
old_redo exception;                     -- redo from old incarnation
pragma exception_init(old_redo, -20501);
 
--
--
--
 
getRA_containerMask     number;
getRA_actionMask        number;
getRA_likePattern       cdf.fname%TYPE;
 
getRA_completedAfter    date;
getRA_completedBefore   date;
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
rcvRecBackupAge         number;      -- requested age of backup
thisBackupAge           number;      -- current age of backup
getBS_status            number;      -- status of current backup
 
--
--
--
tc_thread               number;
tc_fromTime             date;
tc_toTime               date;
tc_fromSCN              number;
tc_toSCN                number;
tc_fromSeq              number;
tc_toSeq                number;
tc_pattern              varchar2(512);
 
TYPE fileTab_t IS TABLE of boolean index by binary_integer;
tc_fno                  fileTab_t;
tc_database             number;
 
TYPE sequenceTab_t IS TABLE of boolean index by binary_integer;
TYPE threadseqTab_t IS TABLE of sequenceTab_t index by binary_integer;
tc_threadSeq            threadSeqTab_t;
 
TYPE dbidTab_t IS TABLE OF boolean index by binary_integer;
tc_dbid                 dbidTab_t;
tc_anydbid              number;
 
--
--
--
--
--
canHandleTransportableTbs number := FALSE#;
 
guidQualifier        varchar2(32);
guid2pdbkeyQualifier number;
 
--
--
--
actual_dbinc_key number := NULL; -- see comments on getActualDbinc
 
--
--
SESSION_KEY number;
SESSION_FROMTIME DATE;
SESSION_UNTILTIME DATE;
 
--
--
--
--
--
--
--
lb_NeedObsoleteData   number := TRUE#;
CURSOR listBackup_c
RETURN lbRec_t IS
   SELECT
--
           bs.bs_key               list_order1,
           0                       list_order2,
           bs.bs_key               pkey,
           backupset_txt           backup_type,
           backupset_txt           file_type,
           decode(bs.keep_options,
                  0, 'NO',
                     'YES')        keep,
           bs.keep_until           keep_until,
           decode(bs.keep_options,
                  256,  'LOGS',
                  512,  'NOLOGS',
                  1024, 'BACKUP_LOGS',
                         null)     keep_options,
           null                    status,
           null                    fname,
           null                    tag,
           null                    media,
           bs.bs_recid             recid,
           bs.bs_stamp             stamp,
           null                    device_type,
           0                       block_size,
           bs.completion_time      completion_time,
           'NO'                    is_rdf,
           null                    compressed,
           null                    obsolete,
           null                    keep_for_dbpitr,
           null                    bytes,
           bs.bs_key               bs_key,
           bs.set_count            bs_count,
           bs.set_stamp            bs_stamp,
           decode(bs.bck_type,
                  'L', archivedlog_txt,
                       datafile_txt)
                                   bs_type,
           decode(bs.incr_level,
                  0, full_txt,
                  1, incr1_txt,
                  2, incr2_txt,
                  3, incr3_txt,
                  4, incr4_txt,
                  decode(bs.bck_type, 'I', incr_txt, full_txt))
                                   bs_incr_type,
           bs.pieces               bs_pieces,
           null                    bs_copies,
           bs.completion_time      bs_completion_time,
           null                    bs_status,
           null                    bs_bytes,
           null                    bs_compressed,
           null                    bs_tag,
           null                    bs_device_type,
           null                    bp_piece#,
           null                    bp_copy#,
           null                    bp_vb_key,
           null                    bp_ba_access,
           null                    bp_lib_key,
           null                    df_file#,
           null                    df_ts#,
           null                    df_plugin_change#,
           null                    df_foreign_dbid,
           null                    df_tablespace,
           null                    df_resetlogs_change#,
           null                    df_creation_change#,
           null                    df_checkpoint_change#,
           null                    df_ckp_mod_time,
           null                    df_incremental_change#,
           null                    rl_thread#,
           null                    rl_sequence#,
           null                    rl_resetlogs_change#,
           null                    rl_first_change#,
           null                    rl_first_time,
           null                    rl_next_change#,
           null                    rl_next_time,
           null                    rl_snapstandby,
           null                    sf_db_unique_name,
           null                    con_id
     FROM  bs
    WHERE bs.db_key     = this_db_key
      AND (bs.site_key IS NULL         OR -- always return null site_key
           user_site_key = bs.site_key OR -- user interested in one site
           (user_site_key IS NULL AND     -- return rows per access attr
            (disk_backups_shared = TRUE# OR
             tape_backups_shared = TRUE# OR
             this_site_key = bs.site_key)))
 
   UNION ALL
   SELECT
--
           bp.bs_key               list_order1,
           1                       list_order2,
           bp.bp_key               pkey,
           backupset_txt           backup_type,
           piece_txt               file_type,
           null                    keep,
           null                    keep_until,
           null                    keep_options,
           decode(bp.status,
                  'A', available_txt,
                  'U', unavailable_txt,
                  'X', expired_txt,
                       other_txt)  status,
           bp.handle               fname,
           bp.tag                  tag,
           bp.media                media,
           bp.bp_recid             recid,
           bp.bp_stamp             stamp,
           bp.device_type          device_type,
           0                       block_size,
           bp.completion_time      completion_time,
           bp.is_recovery_dest_file
                                   is_rdf,
           bp.compressed           compressed,
           null                    obsolete,
           null                    keep_for_dbpitr,
           bp.bytes                bytes,
           bp.bs_key               bs_key,
           null                    bs_count,
           null                    bs_stamp,
           null                    bs_type,
           null                    bs_incr_type,
           null                    bs_pieces,
           null                    bs_copies,
           null                    bs_completion_time,
           null                    bs_status,
           null                    bs_bytes,
           null                    bs_compressed,
           null                    bs_tag,
           null                    bs_device_type,
           bp.piece#               bp_piece#,
           bp.copy#                bp_copy#,
           bp.vb_key               bp_vb_key,
           bp.ba_access            bp_ba_access,
           bp.lib_key              bp_lib_key,
           null                    df_file#,
           null                    df_ts#,
           null                    df_plugin_change#,
           null                    df_foreign_dbid,
           null                    df_tablespace,
           null                    df_resetlogs_change#,
           null                    df_creation_change#,
           null                    df_checkpoint_change#,
           null                    df_ckp_mod_time,
           null                    df_incremental_change#,
           null                    rl_thread#,
           null                    rl_sequence#,
           null                    rl_resetlogs_change#,
           null                    rl_first_change#,
           null                    rl_first_time,
           null                    rl_next_change#,
           null                    rl_next_time,
           null                    rl_snapstandby,
           null                    sf_db_unique_name,
           null                    con_id
     FROM bp
    WHERE bp.db_key = this_db_key
      AND bp.status != 'D'
      AND ((user_site_key = bp.site_key) OR
           (user_site_key IS NULL AND
            ((disk_backups_shared = TRUE# AND bp.device_type = 'DISK') OR
             (tape_backups_shared = TRUE# AND bp.device_type <> 'DISK') OR
             (this_site_key = nvl(bp.site_key, this_site_key)))))
 
   UNION ALL
   SELECT
--
           bdf.bs_key              list_order1,
           2                       list_order2,
           bdf.bdf_key             pkey,
           backupset_txt           backup_type,
           datafile_txt            file_type,
           null                    keep,
           null                    keep_until,
           null                    keep_options,
           null                    status,
           null                    fname,
           null                    tag,
           null                    media,
           bdf.bdf_recid           recid,
           bdf.bdf_stamp           stamp,
           null                    device_type,
           bdf.block_size          block_size,
           bdf.completion_time     completion_time,
           'NO'                    is_rdf,
           null                    compressed,
           null                    obsolete,
           null                    keep_for_dbpitr,
           bdf.block_size * bdf.blocks
                                   bytes,
           bdf.bs_key              bs_key,
           null                    bs_count,
           null                    bs_stamp,
           null                    bs_type,
           decode(bdf.incr_level,
                  0, full_txt,
                  1, incr1_txt,
                  2, incr2_txt,
                  3, incr3_txt,
                  4, incr4_txt,
                  decode(greatest(bdf.create_scn, bdf.incr_scn),
                         bdf.create_scn, full_txt, incr_txt))
                                   bs_incr_type,
           null                    bs_pieces,
           null                    bs_copies,
           null                    bs_completion_time,
           null                    bs_status,
           null                    bs_bytes,
           null                    bs_compressed,
           null                    bs_tag,
           null                    bs_device_type,
           null                    bp_piece#,
           null                    bp_copy#,
           null                    bp_vb_key,
           null                    bp_ba_access,
           null                    bp_lib_key,
           bdf.file#               df_file#,
           null                    df_ts#,
           null                    df_plugin_change#,
           null                    df_foreign_dbid,
           null                    df_tablespace,
           dbinc.reset_scn         df_resetlogs_change#,
           bdf.create_scn          df_creation_change#,
           bdf.ckp_scn             df_checkpoint_change#,
           bdf.ckp_time            df_ckp_mod_time,
           bdf.incr_scn            df_incremental_change#,
           null                    rl_thread#,
           null                    rl_sequence#,
           null                    rl_resetlogs_change#,
           null                    rl_first_change#,
           null                    rl_first_time,
           null                    rl_next_change#,
           null                    rl_next_time,
           null                    rl_snapstandby,
           null                    sf_db_unique_name,
           null                    con_id
     FROM bdf, dbinc
    WHERE dbinc.db_key     = this_db_key
      AND dbinc.dbinc_key  = bdf.dbinc_key
 
   UNION ALL
   SELECT
--
           bcf.bs_key              list_order1,
           2                       list_order2,
           bcf.bcf_key             pkey,
           backupset_txt           backup_type,
           controlfile_txt         file_type,
           null                    keep,
           null                    keep_until,
           null                    keep_options,
           null                    status,
           null                    fname,
           null                    tag,
           null                    media,
           bcf.bcf_recid           recid,
           bcf.bcf_stamp           stamp,
           null                    device_type,
           bcf.block_size          block_size,
           null                    completion_time,
           'NO'                    is_rdf,
           null                    compressed,
           null                    obsolete,
           null                    keep_for_dbpitr,
           bcf.block_size * bcf.blocks
                                   bytes,
           bcf.bs_key              bs_key,
           null                    bs_count,
           null                    bs_stamp,
           null                    bs_type,
           full_txt                bs_incr_type,
           null                    bs_pieces,
           null                    bs_copies,
           null                    bs_completion_time,
           null                    bs_status,
           null                    bs_bytes,
           null                    bs_compressed,
           null                    bs_tag,
           null                    bs_device_type,
           null                    bp_piece#,
           null                    bp_copy#,
           null                    bp_vb_key,
           null                    bp_ba_access,
           null                    bp_lib_key,
           0                       df_file#,
           null                    df_ts#,
           null                    df_plugin_change#,
           null                    df_foreign_dbid,
           null                    df_tablespace,
           dbinc.reset_scn         df_resetlogs_change#,
           0                       df_creation_change#,
           bcf.ckp_scn             df_checkpoint_change#,
           bcf.ckp_time            df_ckp_mod_time,
           null                    df_incremental_change#,
           null                    rl_thread#,
           null                    rl_sequence#,
           null                    rl_resetlogs_change#,
           null                    rl_first_change#,
           null                    rl_first_time,
           null                    rl_next_change#,
           null                    rl_next_time,
           null                    rl_snapstandby,
           null                    sf_db_unique_name,
           null                    con_id
     FROM bcf, dbinc
    WHERE dbinc.db_key     = this_db_key
      AND dbinc.dbinc_key  = bcf.dbinc_key
 
   UNION ALL
   SELECT
--
           brl.bs_key              list_order1,
           2                       list_order2,
           brl.brl_key             pkey,
           backupset_txt           backup_type,
           archivedlog_txt         file_type,
           null                    keep,
           null                    keep_until,
           null                    keep_options,
           null                    status,
           null                    fname,
           null                    tag,
           null                    media,
           brl.brl_recid           recid,
           brl.brl_stamp           stamp,
           null                    device_type,
           brl.block_size          block_size,
           null                    completion_time,
           'NO'                    is_rdf,
           null                    compressed,
           null                    obsolete,
           null                    keep_for_dbpitr,
           brl.block_size * brl.blocks
                                   bytes,
           brl.bs_key              bs_key,
           null                    bs_count,
           null                    bs_stamp,
           null                    bs_type,
           null                    bs_incr_type,
           null                    bs_pieces,
           null                    bs_copies,
           null                    bs_completion_time,
           null                    bs_status,
           null                    bs_bytes,
           null                    bs_compressed,
           null                    bs_tag,
           null                    bs_device_type,
           null                    bp_piece#,
           null                    bp_copy#,
           null                    bp_vb_key,
           null                    bp_ba_access,
           null                    bp_lib_key,
           null                    df_file#,
           null                    df_ts#,
           null                    df_plugin_change#,
           null                    df_foreign_dbid,
           null                    df_tablespace,
           null                    df_resetlogs_change#,
           null                    df_creation_change#,
           null                    df_checkpoint_change#,
           null                    df_ckp_mod_time,
           null                    df_incremental_change#,
           brl.thread#             rl_thread#,
           brl.sequence#           rl_sequence#,
           dbinc.reset_scn         rl_resetlogs_change#,
           brl.low_scn             rl_first_change#,
           brl.low_time            rl_first_time,
           brl.next_scn            rl_next_change#,
           brl.next_time           rl_next_time,
           'NO'                    rl_snapstandby,
           null                    sf_db_unique_name,
           null                    con_id
     FROM brl, dbinc
    WHERE dbinc.db_key      = this_db_key
      AND dbinc.dbinc_key   = brl.dbinc_key
 
   UNION ALL
   SELECT
--
           bsf.bs_key              list_order1,
           2                       list_order2,
           bsf.bsf_key             pkey,
           backupset_txt           backup_type,
           spfile_txt              file_type,
           null                    keep,
           null                    keep_until,
           null                    keep_options,
           null                    status,
           null                    fname,
           null                    tag,
           null                    media,
           bsf.bsf_recid           recid,
           bsf.bsf_stamp           stamp,
           null                    device_type,
           0                       block_size,
           null                    completion_time,
           'NO'                    is_rdf,
           null                    compressed,
           null                    obsolete,
           null                    keep_for_dbpitr,
           bsf.bytes               bytes,
           bsf.bs_key              bs_key,
           null                    bs_count,
           null                    bs_stamp,
           null                    bs_type,
           full_txt                bs_incr_type,
           null                    bs_pieces,
           null                    bs_copies,
           null                    bs_completion_time,
           null                    bs_status,
           null                    bs_bytes,
           null                    bs_compressed,
           null                    bs_tag,
           null                    bs_device_type,
           null                    bp_piece#,
           null                    bp_copy#,
           null                    bp_vb_key,
           null                    bp_ba_access,
           null                    bp_lib_key,
           null                    df_file#,
           null                    df_ts#,
           null                    df_plugin_change#,
           null                    df_foreign_dbid,
           null                    df_tablespace,
           0                       df_resetlogs_change#,
           0                       df_creation_change#,
           0                       df_checkpoint_change#,
           bsf.modification_time   df_ckp_mod_time,
           null                    df_incremental_change#,
           null                    rl_thread#,
           null                    rl_sequence#,
           null                    rl_resetlogs_change#,
           null                    rl_first_change#,
           null                    rl_first_time,
           null                    rl_next_change#,
           null                    rl_next_time,
           null                    rl_snapstandby,
           db_unique_name          sf_db_unique_name,
           null                    con_id
     FROM bsf
    WHERE bsf.db_key     = this_db_key
 
   UNION ALL
   SELECT
--
           cdf.cdf_key             list_order1,
           -1                      list_order2,
           cdf.cdf_key             pkey,
           copy_txt                backup_type,
           datafile_txt            file_type,
           decode(cdf.keep_options,
                  0, 'NO',
                     'YES')        keep,
           cdf.keep_until          keep_until,
           decode(cdf.keep_options,
                  256,  'LOGS',
                  512,  'NOLOGS',
                  1024, 'BACKUP_LOGS',
                         NULL)     keep_options,
           decode(cdf.status,
                  'A', available_txt,
                  'U', unavailable_txt,
                  'X', expired_txt,
                       other_txt)  status,
           cdf.fname               fname,
           cdf.tag                 tag,
           null                    media,
           cdf.cdf_recid           recid,
           cdf.cdf_stamp           stamp,
           'DISK'                  device_type,
           cdf.block_size          block_size,
           cdf.completion_time     completion_time,
           cdf.is_recovery_dest_file
                                   is_rdf,
           null                    compressed,
           null                    obsolete,
           null                    keep_for_dbpitr,
           cdf.block_size * cdf.blocks
                                   bytes,
           null                    bs_key,
           null                    bs_count,
           null                    bs_stamp,
           null                    bs_type,
           null                    bs_incr_type,
           null                    bs_pieces,
           null                    bs_copies,
           null                    bs_completion_time,
           null                    bs_status,
           null                    bs_bytes,
           null                    bs_compressed,
           null                    bs_tag,
           null                    bs_device_type,
           null                    bp_piece#,
           null                    bp_copy#,
           null                    bp_vb_key,
           null                    bp_ba_access,
           null                    bp_lib_key,
           cdf.file#               df_file#,
           null                    df_ts#,
           null                    df_plugin_change#,
           null                    df_foreign_dbid,
           null                    df_tablespace,
           dbinc.reset_scn         df_resetlogs_change#,
           cdf.create_scn          df_creation_change#,
           cdf.ckp_scn             df_checkpoint_change#,
           cdf.ckp_time            df_ckp_mod_time,
           null                    df_incremental_change#,
           null                    rl_thread#,
           null                    rl_sequence#,
           null                    rl_resetlogs_change#,
           null                    rl_first_change#,
           null                    rl_first_time,
           null                    rl_next_change#,
           null                    rl_next_time,
           null                    rl_snapstandby,
           null                    sf_db_unique_name,
           null                    con_id
     FROM cdf, dbinc
    WHERE dbinc.db_key     = this_db_key
      AND dbinc.dbinc_key  = cdf.dbinc_key
      AND ((user_site_key = cdf.site_key) OR
           (user_site_key IS NULL AND
            ((disk_backups_shared = TRUE#) OR
             (this_site_key = nvl(cdf.site_key, this_site_key)))))
   UNION ALL
   SELECT
--
           ccf.ccf_key             list_order1,
           -1                      list_order2,
           ccf.ccf_key             pkey,
           copy_txt                backup_type,
           controlfile_txt         file_type,
           decode(ccf.keep_options,
                  0, 'NO',
                     'YES')        keep,
           ccf.keep_until          keep_until,
           decode(ccf.keep_options,
                  256,  'LOGS',
                  512,  'NOLOGS',
                  1024, 'BACKUP_LOGS',
                         NULL)     keep_options,
           decode(ccf.status,
                  'A', available_txt,
                  'U', unavailable_txt,
                  'X', expired_txt,
                       other_txt)  status,
           ccf.fname               fname,
           ccf.tag                 tag,
           null                    media,
           ccf.ccf_recid           recid,
           ccf.ccf_stamp           stamp,
           'DISK'                  device_type,
           ccf.block_size          block_size,
           ccf.completion_time     completion_time,
           ccf.is_recovery_dest_file
                                   is_rdf,
           null                    compressed,
           null                    obsolete,
           null                    keep_for_dbpitr,
           null
                                   bytes,
           null                    bs_key,
           null                    bs_count,
           null                    bs_stamp,
           null                    bs_type,
           null                    bs_incr_type,
           null                    bs_pieces,
           null                    bs_copies,
           null                    bs_completion_time,
           null                    bs_status,
           null                    bs_bytes,
           null                    bs_compressed,
           null                    bs_tag,
           null                    bs_device_type,
           null                    bp_piece#,
           null                    bp_copy#,
           null                    bp_vb_key,
           null                    bp_ba_access,
           null                    bp_lib_key,
           0                       df_file#,
           null                    df_ts#,
           null                    df_plugin_change#,
           null                    df_foreign_dbid,
           null                    df_tablespace,
           dbinc.reset_scn         df_resetlogs_change#,
           0                       df_creation_change#,
           ccf.ckp_scn             df_checkpoint_change#,
           ccf.ckp_time            df_ckp_mod_time,
           null                    df_incremental_change#,
           null                    rl_thread#,
           null                    rl_sequence#,
           null                    rl_resetlogs_change#,
           null                    rl_first_change#,
           null                    rl_first_time,
           null                    rl_next_change#,
           null                    rl_next_time,
           null                    rl_snapstandby,
           null                    sf_db_unique_name,
           null                    con_id
     FROM ccf, dbinc
    WHERE dbinc.db_key     = this_db_key
      AND dbinc.dbinc_key  = ccf.dbinc_key
      AND ((user_site_key  = ccf.site_key) OR
           (user_site_key IS NULL AND
            ((disk_backups_shared = TRUE#) OR
             (this_site_key = nvl(ccf.site_key, this_site_key)))))
 
   UNION ALL
   SELECT
--
           al.al_key               list_order1,
           -1                      list_order2,
           al.al_key               pkey,
           copy_txt                backup_type,
           archivedlog_txt         file_type,
           null                    keep,
           null                    keep_until,
           null                    keep_options,
           decode(al.status,
                  'A', available_txt,
                  'U', unavailable_txt,
                  'X', expired_txt,
                       other_txt)  status,
           al.fname                fname,
           null                    tag,
           null                    media,
           al.al_recid             recid,
           al.al_stamp             stamp,
           'DISK'                  device_type,
           al.block_size           block_size,
           al.completion_time      completion_time,
           al.is_recovery_dest_file
                                   is_rdf,
           al.compressed           compressed,
           null                    obsolete,
           null                    keep_for_dbpitr,
           al.block_size * al.blocks
                                   bytes,
           null                    bs_key,
           null                    bs_count,
           null                    bs_stamp,
           null                    bs_type,
           null                    bs_incr_type,
           null                    bs_pieces,
           null                    bs_copies,
           null                    bs_completion_time,
           null                    bs_status,
           null                    bs_bytes,
           null                    bs_compressed,
           null                    bs_tag,
           null                    bs_device_type,
           null                    bp_piece#,
           null                    bp_copy#,
           null                    bp_vb_key,
           null                    bp_ba_access,
           null                    bp_lib_key,
           null                    df_file#,
           null                    df_ts#,
           null                    df_plugin_change#,
           null                    df_foreign_dbid,
           null                    df_tablespace,
           null                    df_resetlogs_change#,
           null                    df_creation_change#,
           null                    df_checkpoint_change#,
           null                    df_ckp_mod_time,
           null                    df_incremental_change#,
           al.thread#              rl_thread#,
           al.sequence#            rl_sequence#,
           dbinc.reset_scn         rl_resetlogs_change#,
           al.low_scn              rl_first_change#,
           al.low_time             rl_first_time,
           al.next_scn             rl_next_change#,
           al.next_time            rl_next_time,
           'NO'                    rl_snapstandby,
           null                    sf_db_unique_name,
           null                    con_id
     FROM dbinc,
          al
          LEFT OUTER JOIN
          grsp
          ON al.next_scn   >= grsp.from_scn
         AND al.low_scn    <= (grsp.to_scn + 1)
         AND al.dbinc_key   = grsp.dbinc_key
         AND grsp.from_scn <= grsp.to_scn   -- filter clean grp
         AND grsp.from_scn != 0
         AND grsp.guaranteed = 'YES'
    WHERE dbinc.db_key      = this_db_key
      AND dbinc.dbinc_key   = al.dbinc_key
      AND al.archived = 'Y'
      AND grsp.from_scn is null
      AND ((client_site_aware = TRUE# AND
            ((user_site_key = al.site_key) OR
             (user_site_key IS NULL AND
              (logs_shared = TRUE# OR
               this_site_key = nvl(al.site_key, this_site_key))))) OR
           (client_site_aware = FALSE#))
 
   UNION ALL
   SELECT
--
           xdf.xdf_key             list_order1,
           -1                      list_order2,
           xdf.xdf_key             pkey,
           proxycopy_txt           backup_type,
           datafile_txt            file_type,
           decode(xdf.keep_options,
                  0, 'NO',
                     'YES')        keep,
           xdf.keep_until          keep_until,
           decode(xdf.keep_options,
                  256,  'LOGS',
                  512,  'NOLOGS',
                  1024, 'BACKUP_LOGS',
                         NULL)     keep_options,
           decode(xdf.status,
                  'A', available_txt,
                  'U', unavailable_txt,
                  'X', expired_txt,
                       other_txt)  status,
           xdf.handle              fname,
           xdf.tag                 tag,
           xdf.media               media,
           xdf.xdf_recid           recid,
           xdf.xdf_stamp           stamp,
           xdf.device_type         device_type,
           xdf.block_size          block_size,
           xdf.completion_time     completion_time,
           'NO'                    is_rdf,
           null                    compressed,
           null                    obsolete,
           null                    keep_for_dbpitr,
           xdf.block_size * xdf.blocks
                                   bytes,
           null                    bs_key,
           null                    bs_count,
           null                    bs_stamp,
           null                    bs_type,
           null                    bs_incr_type,
           null                    bs_pieces,
           null                    bs_copies,
           null                    bs_completion_time,
           null                    bs_status,
           null                    bs_bytes,
           null                    bs_compressed,
           null                    bs_tag,
           null                    bs_device_type,
           null                    bp_piece#,
           null                    bp_copy#,
           null                    bp_vb_key,
           null                    bp_ba_access,
           null                    bp_lib_key,
           xdf.file#               df_file#,
           null                    df_ts#,
           null                    df_plugin_change#,
           null                    df_foreign_dbid,
           null                    df_tablespace,
           dbinc.reset_scn         df_resetlogs_change#,
           xdf.create_scn          df_creation_change#,
           xdf.ckp_scn             df_checkpoint_change#,
           xdf.ckp_time            df_ckp_mod_time,
           null                    df_incremental_change#,
           null                    rl_thread#,
           null                    rl_sequence#,
           null                    rl_resetlogs_change#,
           null                    rl_first_change#,
           null                    rl_first_time,
           null                    rl_next_change#,
           null                    rl_next_time,
           null                    rl_snapstandby,
           null                    sf_db_unique_name,
           null                    con_id
     FROM xdf, dbinc
    WHERE dbinc.db_key     = this_db_key
      AND dbinc.dbinc_key  = xdf.dbinc_key
      AND ((user_site_key  = xdf.site_key) OR
           (user_site_key IS NULL AND
            ((tape_backups_shared = TRUE#) OR
             (this_site_key = nvl(xdf.site_key, this_site_key)))))
   UNION ALL
   SELECT
--
           xcf.xcf_key             list_order1,
           -1                      list_order2,
           xcf.xcf_key             pkey,
           proxycopy_txt           backup_type,
           controlfile_txt         file_type,
           decode(xcf.keep_options,
                  0, 'NO',
                     'YES')        keep,
           xcf.keep_until          keep_until,
           decode(xcf.keep_options,
                  256,  'LOGS',
                  512,  'NOLOGS',
                  1024, 'BACKUP_LOGS',
                         NULL)     keep_options,
           decode(xcf.status,
                  'A', available_txt,
                  'U', unavailable_txt,
                  'X', expired_txt,
                       other_txt)  status,
           xcf.handle              fname,
           xcf.tag                 tag,
           xcf.media               media,
           xcf.xcf_recid           recid,
           xcf.xcf_stamp           stamp,
           xcf.device_type         device_type,
           xcf.block_size          block_size,
           xcf.completion_time     completion_time,
           'NO'                    is_rdf,
           null                    compressed,
           null                    obsolete,
           null                    keep_for_dbpitr,
           null                    bytes,
           null                    bs_key,
           null                    bs_count,
           null                    bs_stamp,
           null                    bs_type,
           null                    bs_incr_type,
           null                    bs_pieces,
           null                    bs_copies,
           null                    bs_completion_time,
           null                    bs_status,
           null                    bs_bytes,
           null                    bs_compressed,
           null                    bs_tag,
           null                    bs_device_type,
           null                    bp_piece#,
           null                    bp_copy#,
           null                    bp_vb_key,
           null                    bp_ba_access,
           null                    bp_lib_key,
           0                       df_file#,
           null                    df_ts#,
           null                    df_plugin_change#,
           null                    df_foreign_dbid,
           null                    df_tablespace,
           dbinc.reset_scn         df_resetlogs_change#,
           0                       df_creation_change#,
           xcf.ckp_scn             df_checkpoint_change#,
           xcf.ckp_time            df_ckp_mod_time,
           null                    df_incremental_change#,
           null                    rl_thread#,
           null                    rl_sequence#,
           null                    rl_resetlogs_change#,
           null                    rl_first_change#,
           null                    rl_first_time,
           null                    rl_next_change#,
           null                    rl_next_time,
           null                    rl_snapstandby,
           null                    sf_db_unique_name,
           null                    con_id
     FROM xcf, dbinc
    WHERE dbinc.db_key     = this_db_key
      AND dbinc.dbinc_key  = xcf.dbinc_key
      AND ((user_site_key  = xcf.site_key) OR
           (user_site_key IS NULL AND
            ((tape_backups_shared = TRUE#) OR
             (this_site_key = nvl(xcf.site_key, this_site_key)))))
 
   UNION ALL
   SELECT
--
           xal.xal_key             list_order1,
           -1                      list_order2,
           xal.xal_key             pkey,
           proxycopy_txt           backup_type,
           archivedlog_txt         file_type,
           decode(xal.keep_options,
                  0, 'NO',
                     'YES')        keep,
           xal.keep_until          keep_until,
           decode(xal.keep_options,
                  256,  'LOGS',
                  512,  'NOLOGS',
                  1024, 'BACKUP_LOGS',
                         NULL)     keep_options,
           decode(xal.status,
                  'A', available_txt,
                  'U', unavailable_txt,
                  'X', expired_txt,
                       other_txt)  status,
           xal.handle              fname,
           xal.tag                 tag,
           xal.media               media,
           xal.xal_recid           recid,
           xal.xal_stamp           stamp,
           xal.device_type         device_type,
           xal.block_size          block_size,
           xal.completion_time     completion_time,
           'NO'                    is_rdf,
           null                    compressed,
           null                    obsolete,
           null                    keep_for_dbpitr,
           xal.block_size * xal.blocks
                                   bytes,
           null                    bs_key,
           null                    bs_count,
           null                    bs_stamp,
           null                    bs_type,
           null                    bs_incr_type,
           null                    bs_pieces,
           null                    bs_copies,
           null                    bs_completion_time,
           null                    bs_status,
           null                    bs_bytes,
           null                    bs_compressed,
           null                    bs_tag,
           null                    bs_device_type,
           null                    bp_piece#,
           null                    bp_copy#,
           null                    bp_vb_key,
           null                    bp_ba_access,
           null                    bp_lib_key,
           null                    df_file#,
           null                    df_ts#,
           null                    df_plugin_change#,
           null                    df_foreign_dbid,
           null                    df_tablespace,
           dbinc.reset_scn         df_resetlogs_change#,
           0                       df_creation_change#,
           null                    df_checkpoint_change#,
           null                    df_ckp_mod_time,
           null                    df_incremental_change#,
           xal.thread#             rl_thread#,
           xal.sequence#           rl_sequence#,
           dbinc.reset_scn         rl_resetlogs_change#,
           xal.low_scn             rl_first_change#,
           xal.low_time            rl_first_time,
           xal.next_scn            rl_next_change#,
           xal.next_time           rl_next_time,
           'NO'                    rl_snapstandby,
           null                    sf_db_unique_name,
           null                    con_id
     FROM xal, dbinc
    WHERE dbinc.db_key      = this_db_key
      AND dbinc.dbinc_key   = xal.dbinc_key
      AND ((user_site_key   = xal.site_key) OR
           (user_site_key IS NULL AND
            ((tape_backups_shared = TRUE#) OR
             (this_site_key = nvl(xal.site_key, this_site_key)))))
 
--
--
   ORDER BY list_order1, list_order2, bp_piece#;
 
--
--
--
 
--
--
--
--
 
CURSOR findControlfileBackup_c(
   sourcemask           IN     number
  ,currentIncarnation   IN     number         DEFAULT TRUE#
  ,tag                  IN     varchar2       DEFAULT NULL
  ,pattern              IN     varchar2       DEFAULT NULL
  ,completedAfter       IN     date           DEFAULT NULL
  ,completedBefore      IN     date           DEFAULT NULL
  ,untilSCN             IN     number         DEFAULT NULL
  ,statusMask           IN     binary_integer DEFAULT BSavailable
--
  ,needstby             IN     number         DEFAULT NULL
  ,typemask             IN     binary_integer DEFAULT BScfile_all
  ,fromSCN              IN     number         DEFAULT 0
--
)
RETURN rcvRec_t IS
   SELECT imageCopy_con_t       type_con,
          ccf_key               key_con,
          ccf_recid             recid_con,
          ccf_stamp             stamp_con,
          to_number(null)       setStamp_con,
          to_number(null)       setCount_con,
          to_number(null)       bsRecid_con,
          to_number(null)       bsStamp_con,
          to_number(null)       bsKey_con,
          to_number(null)       bsLevel_con,
          to_char(null)         bsType_con,
          to_number(null)       elapseSecs_con,
          to_number(null)       pieceCount_con,
          fname                 fileName_con,
          tag                   tag_con,
          to_number(null)       copyNumber_con,
          status                status_con,
          to_number(null)       blocks_con,     -- ccf doesn't have blocks
          block_size            blockSize_con,
          'DISK'                deviceType_con,
          completion_time       compTime_con,
          create_time           cfCreationTime_con,
          to_number(null)       pieceNumber_con,
          to_date(null)         bpCompTime_con,
          to_char(null)         bpCompressed_con,
          to_char(null)         multi_section_con,
 
          full_act_t            type_act,
          0                     fromSCN_act,
          ccf.ckp_scn           toSCN_act,
          ccf.ckp_time          toTime_act,
          dbinc.reset_scn       rlgSCN_act,
          dbinc.reset_time      rlgTime_act,
          ccf.dbinc_key         dbincKey_act,
          to_number(null)       level_act,
          0                     section_size_act,
 
          0                     dfNumber_obj,
          0                     dfCreationSCN_obj,
          to_number(null)       cfSequence_obj,
          to_date(null)         cfDate_obj,
          to_number(null)       logSequence_obj,
          to_number(null)       logThread_obj,
          to_number(null)       logRlgSCN_obj,
          to_date(null)         logRlgTime_obj,
          to_number(null)       logLowSCN_obj,
          to_date(null)         logLowTime_obj,
          to_number(null)       logNextSCN_obj,
          to_date(null)         logNextTime_obj,
          to_char(null)         logTerminal_obj,
          nvl(controlfile_type, 'B')
                                cfType_obj,
          ccf.pdb_key           pdbKey_obj,
 
          ccf.keep_options      keep_options,
          ccf.keep_until        keep_until,
 
          to_number(null)       afzSCN_act,
          to_date(null)         rfzTime_act,
          to_number(null)       rfzSCN_act,
          to_char(null)         media_con,
          is_recovery_dest_file isrdf_con,
          site_key              site_key_con,
          0                     foreignDbid_obj,
          0                     pluggedRonly_obj,
          0                     pluginSCN_obj,
          0                     pluginRlgSCN_obj,
          to_date(null)         pluginRlgTime_obj,
 
          to_number(null)       newDfCreationSCN_obj,
          to_number(null)       newToSCN_act,
          to_number(null)       newRlgSCN_act,
          to_date(null)         newRlgTime_act,
          to_char(null)         sfDbUniqueName_obj,
          to_char(null)         sparse_backup_con,
          0                     ppl_pdb_id_con,
          0                     ppl_cdb_dbid_con
     FROM ccf, dbinc
   WHERE dbinc.db_key = this_db_key            -- belongs to this database
     AND dbinc.dbinc_key = ccf.dbinc_key
     AND (findControlfileBackup_c.currentIncarnation = FALSE# OR
          this_dbinc_key = ccf.dbinc_key)
     AND (findControlfileBackup_c.tag is NULL OR
          findControlfileBackup_c.tag = tag)
     AND (findControlfileBackup_c.pattern is NULL OR
          fname LIKE replace(replace(findControlfileBackup_c.pattern,
                                     '*','**'), '_', '*_')
                    ESCAPE '*')
     AND (findControlfileBackup_c.completedAfter is NULL OR
          completion_time >= findControlfileBackup_c.completedAfter)
     AND (findControlfileBackup_c.completedBefore is NULL OR
          completion_time <= findControlfileBackup_c.completedBefore)
     AND (findControlfileBackup_c.untilSCN is NULL OR
          ccf.ckp_scn <= findControlfileBackup_c.untilSCN)
      AND decode(statusMask, BSavailable,
                 decode(status, 'A', TRUE#, FALSE#),
                 isStatusMatch(status, statusMask)) = TRUE#
     AND (needstby is NULL OR
          nvl(controlfile_type,'B') = decode(needstby, TRUE#, 'S', 'B') OR
          canConvert_Cf = TRUE#)
     AND (sourcemask is NULL OR bitand(sourcemask, imageCopy_con_t) != 0)
     AND ((user_site_key = ccf.site_key) OR
          (user_site_key IS NULL AND
           ((disk_backups_shared = TRUE#) OR
            (this_site_key = nvl(ccf.site_key, this_site_key)))))
     AND ccf.ckp_scn >= findControlfileBackup_c.fromSCN
     AND (guidQualifier IS NULL OR ccf.pdb_key = guid2pdbKeyQualifier)
 
   UNION ALL
 
   SELECT proxyCopy_con_t       type_con,
          xcf_key               key_con,
          xcf_recid             recid_con,
          xcf_stamp             stamp_con,
          to_number(null)       setStamp_con,
          to_number(null)       setCount_con,
          to_number(null)       bsRecid_con,
          to_number(null)       bsStamp_con,
          to_number(null)       bsKey_con,
          to_number(null)       bsLevel_con,
          to_char(null)         bsType_con,
          to_number(null)       elapseSecs_con,
          to_number(null)       pieceCount_con,
          handle                fileName_con,
          tag                   tag_con,
          to_number(null)       copyNumber_con,
          status                status_con,
          to_number(null)       blocks_con,     -- xcf doesn't have blocks
          block_size            blockSize_con,
          device_type           deviceType_con,
          completion_time       compTime_con,
          to_date(null)         cfCreationTime_con,
          to_number(null)       pieceNumber_con,
          to_date(null)         bpCompTime_con,
          to_char(null)         bpCompressed_con,
          to_char(null)         multi_section_con,
 
          full_act_t            type_act,
          0                     fromSCN_act,
          xcf.ckp_scn           toSCN_act,
          xcf.ckp_time          toTime_act,
          dbinc.reset_scn       rlgSCN_act,
          dbinc.reset_time      rlgTime_act,
          xcf.dbinc_key         dbincKey_act,
          to_number(null)       level_act,
          0                     section_size_act,
 
          0                     dfNumber_obj,
          0                     dfCreationSCN_obj,
          to_number(null)       cfSequence_obj,
          to_date(null)         cfDate_obj,
          to_number(null)       logSequence_obj,
          to_number(null)       logThread_obj,
          to_number(null)       logRlgSCN_obj,
          to_date(null)         logRlgTime_obj,
          to_number(null)       logLowSCN_obj,
          to_date(null)         logLowTime_obj,
          to_number(null)       logNextSCN_obj,
          to_date(null)         logNextTime_obj,
          to_char(null)         logTerminal_obj,
          nvl(controlfile_type, 'B')
                                cfType_obj,
          xcf.pdb_key           pdbKey_obj,
 
          xcf.keep_options      keep_options,
          xcf.keep_until        keep_until,
 
          to_number(null)       afzSCN_act,
          to_date(null)         rfzTime_act,
          to_number(null)       rfzSCN_act,
          media                 media_con,
          'NO'                  isrdf_con,
          site_key              site_key_con,
          0                     foreignDbid_obj,
          0                     pluggedRonly_obj,
          0                     pluginSCN_obj,
          0                     pluginRlgSCN_obj,
          to_date(null)         pluginRlgTime_obj,
 
          to_number(null)       newDfCreationSCN_obj,
          to_number(null)       newToSCN_act,
          to_number(null)       newRlgSCN_act,
          to_date(null)         newRlgTime_act,
          to_char(null)         sfDbUniqueName_obj,
          to_char(null)         sparse_backup_con,
          0                     ppl_pdb_id_con,
          0                     ppl_cdb_dbid_con
     FROM xcf, dbinc
   WHERE db_key = this_db_key          -- belongs to this database
     AND dbinc.dbinc_key = xcf.dbinc_key
     AND (findControlfileBackup_c.currentIncarnation = FALSE# OR
          this_dbinc_key = xcf.dbinc_key)
     AND (findControlfileBackup_c.tag is NULL OR
          findControlfileBackup_c.tag = tag)
     AND (findControlfileBackup_c.pattern is NULL OR
          handle LIKE replace(replace(findControlfileBackup_c.pattern,
                                     '*','**'), '_', '*_')
                    ESCAPE '*')
     AND (findControlfileBackup_c.completedAfter is NULL OR
          completion_time >= findControlfileBackup_c.completedAfter)
     AND (findControlfileBackup_c.completedBefore is NULL OR
          completion_time <= findControlfileBackup_c.completedBefore)
     AND (findControlfileBackup_c.untilSCN is NULL OR
          xcf.ckp_scn <= findControlfileBackup_c.untilSCN)
     AND decode(statusMask, BSavailable,
                decode(status, 'A', TRUE#, FALSE#),
                isStatusMatch(status, statusMask)) = TRUE#
     AND (needstby is NULL OR
          nvl(controlfile_type,'B') = decode(needstby, TRUE#, 'S', 'B') OR
          canConvert_Cf = TRUE#)
     AND (sourcemask is NULL OR bitand(sourcemask, proxyCopy_con_t) != 0)
     AND ((user_site_key  = xcf.site_key) OR
          (user_site_key IS NULL AND
           ((tape_backups_shared = TRUE#) OR
            (this_site_key = nvl(xcf.site_key, this_site_key)))))
     AND xcf.ckp_scn >= findControlfileBackup_c.fromSCN
     AND (guidQualifier IS NULL OR xcf.pdb_key = guid2pdbKeyQualifier)
 
   UNION ALL
 
   SELECT backupSet_con_t       type_con,
          bcf_key               key_con,
          bcf_recid             recid_con,
          bcf_stamp             stamp_con,
          bs.set_stamp          setStamp_con,
          bs.set_count          setCount_con,
          bs.bs_recid           bsRecid_con,
          bs.bs_stamp           bsStamp_con,
          bs.bs_key             bsKey_con,
          bs.incr_level         bsLevel_con,
          bs.bck_type           bsType_con,
          abs((bs.completion_time - bs.start_time) * 86400)
                                elapseSecs_con,
          bs.pieces             pieceCount_con,
          to_char(null)         fileName_con,
          to_char(null)         tag_con,
          to_number(null)       copyNumber_con,
          to_char(null)         status_con,
          bcf.blocks            blocks_con,
          bcf.block_size        blockSize_con,
          to_char(null)         deviceType_con,
          bs.completion_time    compTime_con,
          bcf.create_time       cfCreationTime_con,
          to_number(null)       pieceNumber_con,
          to_date(null)         bpCompTime_con,
          to_char(null)         bpCompressed_con,
          multi_section         multi_section_con,
 
          full_act_t            type_act,
          0                     fromSCN_act,
          bcf.ckp_scn           toSCN_act,
          bcf.ckp_time          toTime_act,
          dbinc.reset_scn       rlgSCN_act,
          dbinc.reset_time      rlgTime_act,
          bcf.dbinc_key         dbincKey_act,
          to_number(null)       level_act,
          0                     section_size_act,
 
          0                     dfNumber_obj,
          0                     dfCreationSCN_obj,
          bcf.autobackup_sequence
                                cfSequence_obj,
          bcf.autobackup_date   cfDate_obj,
          to_number(null)       logSequence_obj,
          to_number(null)       logThread_obj,
          to_number(null)       logRlgSCN_obj,
          to_date(null)         logRlgTime_obj,
          to_number(null)       logLowSCN_obj,
          to_date(null)         logLowTime_obj,
          to_number(null)       logNextSCN_obj,
          to_date(null)         logNextTime_obj,
          to_char(null)         logTerminal_obj,
          nvl(controlfile_type, 'B')
                                cfType_obj,
          bcf.pdb_key           pdbKey_obj,
 
          bs.keep_options       keep_options,
          bs.keep_until         keep_until,
 
          to_number(null)       afzSCN_act,
          to_date(null)         rfzTime_act,
          to_number(null)       rfzSCN_act,
          to_char(null)         media_con,
          'NO'                  isrdf_con,
          bs.site_key           site_key_con,
          0                     foreignDbid_obj,
          0                     pluggedRonly_obj,
          0                     pluginSCN_obj,
          0                     pluginRlgSCN_obj,
          to_date(null)         pluginRlgTime_obj,
 
          to_number(null)       newDfCreationSCN_obj,
          to_number(null)       newToSCN_act,
          to_number(null)       newRlgSCN_act,
          to_date(null)         newRlgTime_act,
          to_char(null)         sfDbUniqueName_obj,
          to_char(null)         sparse_backup_con,
          0                     ppl_pdb_id_con,
          0                     ppl_cdb_dbid_con
     FROM bs, bcf, dbinc
   WHERE dbinc.db_key = this_db_key            -- belongs to this database
     AND bs.db_key = this_db_key               -- belongs to this database
     AND bcf.dbinc_key = dbinc.dbinc_key       -- join bcf and dbinc
     AND bcf.bs_key = bs.bs_key                -- join bcf and bs
     AND bs.bck_type != 'L'                    -- ignore archivelog backups
     AND (findControlfileBackup_c.currentIncarnation = FALSE# OR
          this_dbinc_key = bcf.dbinc_key)
     AND (findControlfileBackup_c.completedAfter is NULL OR
          bs.completion_time >= findControlfileBackup_c.completedAfter)
     AND (findControlfileBackup_c.completedBefore is NULL OR
          bs.completion_time <= findControlfileBackup_c.completedBefore)
     AND (findControlfileBackup_c.untilSCN is NULL OR
          bcf.ckp_scn <= findControlfileBackup_c.untilSCN)
     AND (needstby is NULL OR
          nvl(controlfile_type,'B') = decode(needstby, TRUE#, 'S', 'B') OR
          canConvert_Cf = TRUE#)
     AND ((typemask = 0 AND bcf.autobackup_date IS NULL)  OR -- no autobackups
          (bitand(typemask, BScfile_all) != 0)            OR -- all backups
          (bcf.autobackup_date IS NOT NULL AND             -- only autobackups
           bitand(typemask, BScfile_auto) != 0))
     AND (sourcemask is NULL OR bitand(sourcemask, backupSet_con_t) != 0)
     AND (bs.site_key IS NULL         OR -- always return null site_key
          user_site_key = bs.site_key OR -- user interested in one site
          (user_site_key IS NULL AND     -- return rows per access attr
           (disk_backups_shared = TRUE# OR
            tape_backups_shared = TRUE# OR
            this_site_key = bs.site_key)))
     AND bcf.ckp_scn >= findControlfileBackup_c.fromSCN
     AND (guidQualifier IS NULL OR bcf.pdb_key = guid2pdbKeyQualifier)
 
   ORDER BY toSCN_act desc,
            stamp_con desc;
 
--
--
--
 
CURSOR findSpfileBackup_c(
   completedAfter        IN     date           DEFAULT NULL
  ,completedBefore       IN     date           DEFAULT NULL
  ,untilTime             IN     date           DEFAULT NULL
  ,rmanCmd               IN     number         DEFAULT unknownCmd_t)
RETURN rcvRec_t IS
--
   SELECT backupSet_con_t       type_con,
          bsf_key               key_con,
          bsf_recid             recid_con,
          bsf_stamp             stamp_con,
          bs.set_stamp          setStamp_con,
          bs.set_count          setCount_con,
          bs.bs_recid           bsRecid_con,
          bs.bs_stamp           bsStamp_con,
          bs.bs_key             bsKey_con,
          bs.incr_level         bsLevel_con,
          bs.bck_type           bsType_con,
          abs((bs.completion_time - bs.start_time) * 86400)
                                elapseSecs_con,
          bs.pieces             pieceCount_con,
          to_char(null)         fileName_con,
          to_char(null)         tag_con,
          to_number(null)       copyNumber_con,
          to_char(null)         status_con,
          0                     blocks_con,
          0                     blockSize_con,
          to_char(null)         deviceType_con,
          bs.completion_time    compTime_con,
          to_date(null)         cfCreationTime_con,
          to_number(null)       pieceNumber_con,
          to_date(null)         bpCompTime_con,
          to_char(null)         bpCompressed_con,
          multi_section         multi_section_con,
 
          full_act_t            type_act,
          0                     fromSCN_act,
          0                     toSCN_act,
          nvl(modification_time, bs.completion_time)     toTime_act,
          to_number(null)       rlgSCN_act,
          to_date(null)         rlgTime_act,
          to_number(null)       dbincKey_act,
          to_number(null)       level_act,
          0                     section_size_act,
 
          to_number(null)       dfNumber_obj,
          to_number(null)       dfCreationSCN_obj,
          to_number(null)       cfSequence_obj,
          to_date(null)         cfDate_obj,
          to_number(null)       logSequence_obj,
          to_number(null)       logThread_obj,
          to_number(null)       logRlgSCN_obj,
          to_date(null)         logRlgTime_obj,
          to_number(null)       logLowSCN_obj,
          to_date(null)         logLowTime_obj,
          to_number(null)       logNextSCN_obj,
          to_date(null)         logNextTime_obj,
          to_char(null)         logTerminal_obj,
          to_char(null)         cfType_obj,
          bsf.pdb_key           pdbKey_obj,
 
          bs.keep_options       keep_options,
          bs.keep_until         keep_until,
 
          to_number(null)       afzSCN_act,
          to_date(null)         rfzTime_act,
          to_number(null)       rfzSCN_act,
          to_char(null)         media_con,
          'NO'                  isrdf_con,
          bs.site_key           site_key_con,
          0                     foreignDbid_obj,
          0                     pluggedRonly_obj,
          0                     pluginSCN_obj,
          0                     pluginRlgSCN_obj,
          to_date(null)         pluginRlgTime_obj,
 
          to_number(null)       newDfCreationSCN_obj,
          to_number(null)       newToSCN_act,
          to_number(null)       newRlgSCN_act,
          to_date(null)         newRlgTime_act,
          db_unique_name        sfDbUniqueName_obj,
          to_char(null)         sparse_backup_con,
          0                     ppl_pdb_id_con,
          0                     ppl_cdb_dbid_con
     FROM bsf, bs, db
--
--
--
    WHERE rmanCmd != obsoleteCmd_t
      AND bsf.bs_key = bs.bs_key                -- join bsf and bs
      AND bs.bck_type != 'L'                    -- ignore archivelog backups
      AND bs.db_key = this_db_key               -- belongs to this database
      AND bsf.db_key = db.db_key                -- join bsf and db
      AND (findSpfileBackup_c.completedAfter is NULL OR
           bs.completion_time >= findSpfileBackup_c.completedAfter)
      AND (findSpfileBackup_c.completedBefore is NULL OR
           bs.completion_time <= findSpfileBackup_c.completedBefore)
      AND (findSpfileBackup_c.untilTime is NULL OR
           nvl(modification_time,bs.start_time)
               <= findSpfileBackup_c.untilTime)
      AND (rmanCmd != restoreCmd_t OR
           (rmanCmd = restoreCmd_t AND
            (bsf.db_unique_name is NULL OR
             nvl(user_db_unique_name, this_db_unique_name) =
              bsf.db_unique_name)))
      AND (bs.site_key IS NULL         OR -- always return null site_key
           (disk_backups_shared = TRUE# OR
            tape_backups_shared = TRUE# OR
            this_site_key = bs.site_key))
     AND (guidQualifier IS NULL OR bsf.pdb_key = guid2pdbKeyQualifier)
 
   UNION ALL
 
--
   SELECT backupSet_con_t       type_con,
          bsf_key               key_con,
          bsf_recid             recid_con,
          bsf_stamp             stamp_con,
          bs.set_stamp          setStamp_con,
          bs.set_count          setCount_con,
          bs.bs_recid           bsRecid_con,
          bs.bs_stamp           bsStamp_con,
          bs.bs_key             bsKey_con,
          bs.incr_level         bsLevel_con,
          bs.bck_type           bsType_con,
          abs((bs.completion_time - bs.start_time) * 86400)
                                elapseSecs_con,
          bs.pieces             pieceCount_con,
          to_char(null)         fileName_con,
          to_char(null)         tag_con,
          to_number(null)       copyNumber_con,
          to_char(null)         status_con,
          0                     blocks_con,
          0                     blockSize_con,
          to_char(null)         deviceType_con,
          bs.completion_time    compTime_con,
          to_date(null)         cfCreationTime_con,
          to_number(null)       pieceNumber_con,
          to_date(null)         bpCompTime_con,
          to_char(null)         bpCompressed_con,
          multi_section         multi_section_con,
 
          full_act_t            type_act,
          0                     fromSCN_act,
          0                     toSCN_act,
          nvl(modification_time, bs.completion_time)     toTime_act,
          to_number(null)       rlgSCN_act,
          to_date(null)         rlgTime_act,
          to_number(null)       dbincKey_act,
          to_number(null)       level_act,
          0                     section_size_act,
 
          to_number(null)       dfNumber_obj,
          to_number(null)       dfCreationSCN_obj,
          to_number(null)       cfSequence_obj,
          to_date(null)         cfDate_obj,
          to_number(null)       logSequence_obj,
          to_number(null)       logThread_obj,
          to_number(null)       logRlgSCN_obj,
          to_date(null)         logRlgTime_obj,
          to_number(null)       logLowSCN_obj,
          to_date(null)         logLowTime_obj,
          to_number(null)       logNextSCN_obj,
          to_date(null)         logNextTime_obj,
          to_char(null)         logTerminal_obj,
          to_char(null)         cfType_obj,
          bsf.pdb_key           pdbKey_obj,
 
          bs.keep_options       keep_options,
          bs.keep_until         keep_until,
 
          to_number(null)       afzSCN_act,
          to_date(null)         rfzTime_act,
          to_number(null)       rfzSCN_act,
          to_char(null)         media_con,
          'NO'                  isrdf_con,
          bs.site_key           site_key_con,
          0                     foreignDbid_obj,
          0                     pluggedRonly_obj,
          0                     pluginSCN_obj,
          0                     pluginRlgSCN_obj,
          to_date(null)         pluginRlgTime_obj,
 
          to_number(null)       newDfCreationSCN_obj,
          to_number(null)       newToSCN_act,
          to_number(null)       newRlgSCN_act,
          to_date(null)         newRlgTime_act,
          db_unique_name        sfDbUniqueName_obj,
          to_char(null)         sparse_backup_con,
          0                     ppl_pdb_id_con,
          0                     ppl_cdb_dbid_con
     FROM bsf, bs, db,
          (SELECT bs_key,
                  count(distinct piece#) pieces
             FROM  bp
            WHERE rmanCmd = obsoleteCmd_t
              AND bp.db_key  = this_db_key         -- this database
              AND bp.status  = 'A'
              AND (anyDevice = TRUE# OR
                   isDeviceTypeAllocated(bp.device_type) = TRUE#)
              AND ((user_site_key = bp.site_key) OR
                   (user_site_key IS NULL AND
                    ((disk_backups_shared=TRUE# AND bp.device_type='DISK') OR
                     (tape_backups_shared=TRUE# AND bp.device_type<>'DISK') OR
                     (this_site_key = nvl(bp.site_key, this_site_key)))))
         GROUP BY bs_key, device_type) bp
--
--
--
    WHERE rmanCmd = obsoleteCmd_t
      AND bsf.bs_key = bs.bs_key                -- join bsf and bs
      AND bs.bck_type != 'L'                    -- ignore archivelog backups
      AND bs.db_key = this_db_key               -- belongs to this database
      AND bs.bs_key = bp.bs_key                 -- join bs and bp
      AND bs.pieces = bp.pieces
      AND bsf.db_key = db.db_key                -- join bsf and db
      AND (findSpfileBackup_c.completedAfter is NULL OR
           bs.completion_time >= findSpfileBackup_c.completedAfter)
      AND (findSpfileBackup_c.completedBefore is NULL OR
           bs.completion_time <= findSpfileBackup_c.completedBefore)
      AND (findSpfileBackup_c.untilTime is NULL OR
           nvl(modification_time,bs.start_time)
               <= findSpfileBackup_c.untilTime)
     AND (guidQualifier IS NULL OR bsf.pdb_key = guid2pdbKeyQualifier)
 
    ORDER BY toTime_act desc, -- for finding best backup
             stamp_con desc;  -- to get most recent
 
--
--
--
getDatafileBackupLast   rcvRec_t;
 
CURSOR findDatafileBackup_c(
   sourcemask           IN     number
  ,fno                  IN     number         DEFAULT NULL
  ,crescn               IN     number         DEFAULT NULL
--
  ,tag                  IN     varchar2       DEFAULT NULL
  ,pattern              IN     varchar2       DEFAULT NULL
  ,reset_scn            IN     number         DEFAULT NULL
  ,reset_time           IN     date           DEFAULT NULL
  ,level                IN     number         DEFAULT NULL
  ,completedAfter       IN     date           DEFAULT NULL
  ,completedBefore      IN     date           DEFAULT NULL
  ,untilSCN             IN     number         DEFAULT NULL
  ,statusMask           IN     binary_integer DEFAULT BSavailable
--
  ,onlyrdf              IN     binary_integer DEFAULT 0
--
  ,duplicates           IN     number         DEFAULT NULL
  ,onlytc               IN     binary_integer DEFAULT FALSE#
--
  ,pluginSCN            IN     number         DEFAULT 0
  ,allowCumuLevelN      IN     binary_integer DEFAULT FALSE#
--
)
 
RETURN rcvRec_t IS
 
   SELECT imageCopy_con_t       type_con,
          cdf.cdf_key           key_con,
          cdf.cdf_recid         recid_con,
          cdf.cdf_stamp         stamp_con,
          to_number(null)       setStamp_con,
          to_number(null)       setCount_con,
          to_number(null)       bsRecid_con,
          to_number(null)       bsStamp_con,
          to_number(null)       bsKey_con,
          to_number(null)       bsLevel_con,
          to_char(null)         bsType_con,
          to_number(null)       elapseSecs_con,
          to_number(null)       pieceCount_con,
          cdf.fname             fileName_con,
          cdf.tag               tag_con,
          to_number(null)       copyNumber_con,
          cdf.status            status_con,
          cdf.blocks            blocks_con,
          cdf.block_size        blockSize_con,
          'DISK'                deviceType_con,
          cdf.completion_time   compTime_con,
          to_date(null)         cfCreationTime_con,
          to_number(null)       pieceNumber_con,
          to_date(null)         bpCompTime_con,
          to_char(null)         bpCompressed_con,
          to_char(null)         multi_section_con,
 
          full_act_t            type_act,
          0                     fromSCN_act,
          cdf.ckp_scn           toSCN_act,
          cdf.ckp_time          toTime_act,
          dbinc.reset_scn       rlgSCN_act,
          dbinc.reset_time      rlgTime_act,
          cdf.dbinc_key         dbincKey_act,
          cdf.incr_level        level_act,
          0                     section_size_act,
 
          cdf.file#             dfNumber_obj,
          cdf.create_scn        dfCreationSCN_obj,
          to_number(null)       cfSequence_obj,
          to_date(null)         cfDate_obj,
          to_number(null)       logSequence_obj,
          to_number(null)       logThread_obj,
          to_number(null)       logRlgSCN_obj,
          to_date(null)         logRlgTime_obj,
          to_number(null)       logLowSCN_obj,
          to_date(null)         logLowTime_obj,
          to_number(null)       logNextSCN_obj,
          to_date(null)         logNextTime_obj,
          to_char(null)         logTerminal_obj,
          to_char(null)         cfType_obj,
          cdf.pdb_key           pdbKey_obj,
 
          cdf.keep_options      keep_options,
          cdf.keep_until        keep_until,
 
          cdf.abs_fuzzy_scn     afzSCN_act,
          cdf.rcv_fuzzy_time    rfzTime_act,
          cdf.rcv_fuzzy_scn     rfzSCN_act,
          to_char(null)         media_con,
          is_recovery_dest_file isrdf_con,
          site_key              site_key_con,
          cdf.foreign_dbid      foreignDbid_obj,
          decode(cdf.plugged_readonly, 'YES', 1, 0)
                                pluggedRonly_obj,
          cdf.plugin_scn        pluginSCN_obj,
          cdf.plugin_reset_scn  pluginRlgSCN_obj,
          cdf.plugin_reset_time pluginRlgTime_obj,
 
          to_number(null)       newDfCreationSCN_obj,
          decode(cdf.plugged_readonly, 'NO', cdf.ckp_scn,
                 cdf.plugin_scn)
                                newToSCN_act,
          decode(cdf.plugin_scn, 0, dbinc.reset_scn,
                 cdf.plugin_reset_scn)
                                newRlgSCN_act,
          decode(cdf.plugin_scn, 0, dbinc.reset_time,
                 cdf.plugin_reset_time)
                                newRlgTime_act,
          to_char(null)         sfDbUniqueName_obj,
          cdf.sparse_backup     sparse_backup_con,
          0                     ppl_pdb_id_con,
          0                     ppl_cdb_dbid_con
     FROM cdf, dbinc,
          (SELECT DISTINCT max(cdf_recid) duprecid
             FROM cdf, dbinc
            WHERE (findDatafileBackup_c.tag is NULL OR
                   tag = findDatafileBackup_c.tag)
              AND cdf.dbinc_key = dbinc.dbinc_key
              AND dbinc.db_key  = this_db_key
              AND (findDatafileBackup_c.pattern is NULL OR
                   cdf.fname
                     LIKE replace(replace(findDatafileBackup_c.pattern,
                                     '*','**'), '_', '*_')
                      ESCAPE '*')
         GROUP BY cdf.file#, cdf.create_scn, dbinc.reset_scn,
                  dbinc.reset_time, cdf.ckp_time, cdf.ckp_scn,
                  cdf.abs_fuzzy_scn, cdf.rcv_fuzzy_scn,
                  cdf.bck_fuzzy, cdf.onl_fuzzy, dbinc.db_key,
                  cdf.plugin_scn, cdf.plugin_reset_scn,
                  cdf.plugin_reset_time) dup
   WHERE cdf.cdf_recid = dup.duprecid(+)
     AND (sourcemask is NULL OR bitand(sourcemask, imageCopy_con_t) != 0)
     AND (dbinc.db_key = this_db_key)            -- belongs to this database
     AND (dbinc.dbinc_key = cdf.dbinc_key)       -- join cdf and dbinc
     AND (findDatafileBackup_c.reset_scn is NULL OR
          canApplyAnyRedo = TRUE# OR
          (cdf.plugged_readonly = 'NO' AND
           findDatafileBackup_c.reset_scn = dbinc.reset_scn AND
           findDatafileBackup_c.reset_time = dbinc.reset_time) OR
          (cdf.plugged_readonly = 'YES' AND
           findDatafileBackup_c.reset_scn = cdf.plugin_reset_scn AND
           findDatafileBackup_c.reset_time = cdf.plugin_reset_time))
     AND cdf.file# = nvl(findDatafileBackup_c.fno, cdf.file#)
--
--
     AND cdf.file# != 0                           -- no ctrl bkps
     AND (onlytc = FALSE#     OR
          tc_database = TRUE# OR
          isTranslatedFno(cdf.file#) = TRUE#)     -- only tnslated files
     AND ((findDatafileBackup_c.pluginSCN = 0  AND
           cdf.plugin_scn = 0                  AND
           cdf.create_scn = findDatafileBackup_c.crescn)
          OR
          (findDatafileBackup_c.pluginSCN != 0 AND
           cdf.plugin_scn = findDatafileBackup_c.pluginSCN)
          OR
          (findDatafileBackup_c.pluginSCN = 0 AND
           findDatafileBackup_c.crescn IS NULL))
     AND decode(statusMask, BSavailable,
                decode(status, 'A', TRUE#, FALSE#),
                isStatusMatch(status, statusMask)) = TRUE#
     AND (findDatafileBackup_c.tag is NULL OR
          tag = findDatafileBackup_c.tag)
     AND (findDatafileBackup_c.pattern is NULL OR
          cdf.fname LIKE replace(replace(findDatafileBackup_c.pattern,
                                     '*','**'), '_', '*_')
                    ESCAPE '*')
     AND (findDatafileBackup_c.completedAfter is NULL OR
          cdf.completion_time >= findDatafileBackup_c.completedAfter)
     AND (findDatafileBackup_c.completedBefore is NULL OR
          cdf.completion_time <= findDatafileBackup_c.completedBefore)
     AND (findDatafileBackup_c.untilSCN is NULL OR
          (cdf.plugged_readonly = 'NO' AND
           cdf.ckp_scn <= findDatafileBackup_c.untilSCN) OR
          (cdf.plugged_readonly = 'YES' AND
           cdf.plugin_scn <= findDatafileBackup_c.untilSCN))
     AND (findDatafileBackup_c.level is NULL OR
          cdf.incr_level <= findDatafileBackup_c.level)
     AND (findDatafileBackup_c.onlyrdf = 0 OR
          cdf.is_recovery_dest_file = 'YES')
     AND (duplicates IS NULL OR duplicates = TRUE# OR
          (duplicates = FALSE# AND duprecid IS NOT NULL))
     AND ((user_site_key = cdf.site_key) OR
          (user_site_key IS NULL AND
           ((disk_backups_shared = TRUE#) OR
            (this_site_key = nvl(cdf.site_key, this_site_key)))))
     AND (guidQualifier IS NULL OR cdf.pdb_key = guid2pdbKeyQualifier)
 
   UNION ALL
 
   SELECT proxyCopy_con_t       type_con,
          xdf.xdf_key           key_con,
          xdf.xdf_recid         recid_con,
          xdf.xdf_stamp         stamp_con,
          to_number(null)       setStamp_con,
          to_number(null)       setCount_con,
          to_number(null)       bsRecid_con,
          to_number(null)       bsStamp_con,
          to_number(null)       bsKey_con,
          to_number(null)       bsLevel_con,
          to_char(null)         bsType_con,
          to_number(null)       elapseSecs_con,
          to_number(null)       pieceCount_con,
          xdf.handle            fileName_con,
          xdf.tag               tag_con,
          to_number(null)       copyNumber_con,
          xdf.status            status_con,
          xdf.blocks            blocks_con,
          xdf.block_size        blockSize_con,
          xdf.device_type       deviceType_con,
          xdf.completion_time   compTime_con,
          to_date(null)         cfCreationTime_con,
          to_number(null)       pieceNumber_con,
          to_date(null)         bpCompTime_con,
          to_char(null)         bpCompressed_con,
          to_char(null)         multi_section_con,
 
          full_act_t            type_act,
          0                     fromSCN_act,
          xdf.ckp_scn           toSCN_act,
          xdf.ckp_time          toTime_act,
          dbinc.reset_scn       rlgSCN_act,
          dbinc.reset_time      rlgTime_act,
          xdf.dbinc_key         dbincKey_act,
          xdf.incr_level        level_act,
          0                     section_size_act,
 
          xdf.file#             dfNumber_obj,
          xdf.create_scn        dfCreationSCN_obj,
          to_number(null)       cfSequence_obj,
          to_date(null)         cfDate_obj,
          to_number(null)       logSequence_obj,
          to_number(null)       logThread_obj,
          to_number(null)       logRlgSCN_obj,
          to_date(null)         logRlgTime_obj,
          to_number(null)       logLowSCN_obj,
          to_date(null)         logLowTime_obj,
          to_number(null)       logNextSCN_obj,
          to_date(null)         logNextTime_obj,
          to_char(null)         logTerminal_obj,
          to_char(null)         cfType_obj,
          xdf.pdb_key           pdbKey_obj,
 
          xdf.keep_options      keep_options,
          xdf.keep_until        keep_until,
 
          xdf.abs_fuzzy_scn     afzSCN_act,
          xdf.rcv_fuzzy_time    rfzTime_act,
          xdf.rcv_fuzzy_scn     rfzSCN_act,
          xdf.media             media_con,
          'NO'                  isrdf_con,
          site_key              site_key_con,
          xdf.foreign_dbid      foreignDbid_obj,
          decode(xdf.plugged_readonly, 'YES', 1, 0)
                                pluggedRonly_obj,
          xdf.plugin_scn        pluginSCN_obj,
          xdf.plugin_reset_scn  pluginRlgSCN_obj,
          xdf.plugin_reset_time pluginRlgTime_obj,
 
          to_number(null)       newDfCreationSCN_obj,
          decode(xdf.plugged_readonly, 'NO', xdf.ckp_scn,
                 xdf.plugin_scn)
                                newToSCN_act,
          decode(xdf.plugin_reset_scn, 0, dbinc.reset_scn,
                 xdf.plugin_reset_scn)
                                newRlgSCN_act,
          nvl(xdf.plugin_reset_time, dbinc.reset_time)
                                newRlgTime_act,
          to_char(null)         sfDbUniqueName_obj,
          to_char(null)         sparse_backup_con,
          0                     ppl_pdb_id_con,
          0                     ppl_cdb_dbid_con
     FROM xdf, dbinc
   WHERE (sourcemask is NULL OR bitand(sourcemask, proxyCopy_con_t) != 0)
     AND (findDatafileBackup_c.onlyrdf = 0)
     AND (dbinc.db_key = this_db_key)            -- belongs to this database
     AND (dbinc.dbinc_key = xdf.dbinc_key)       -- join xdf and dbinc
     AND (findDatafileBackup_c.reset_scn is NULL OR
          canApplyAnyRedo = TRUE# OR
          (xdf.plugged_readonly = 'NO' AND
           findDatafileBackup_c.reset_scn = dbinc.reset_scn AND
           findDatafileBackup_c.reset_time = dbinc.reset_time) OR
          (xdf.plugged_readonly = 'YES' AND
           findDatafileBackup_c.reset_scn = xdf.plugin_reset_scn AND
           findDatafileBackup_c.reset_time = xdf.plugin_reset_time))
     AND xdf.file# = nvl(findDatafileBackup_c.fno, xdf.file#)
     AND xdf.file# != 0                         -- no ctrl bkps
     AND (onlytc = FALSE#     OR
          tc_database = TRUE# OR
          isTranslatedFno(xdf.file#) = TRUE#)   -- only tnslated files
     AND ((findDatafileBackup_c.pluginSCN = 0  AND
           xdf.plugin_scn = 0                  AND
           xdf.create_scn = findDatafileBackup_c.crescn)
          OR
          (findDatafileBackup_c.pluginSCN != 0 AND
           xdf.plugin_scn = findDatafileBackup_c.pluginSCN)
          OR
          (findDatafileBackup_c.pluginSCN = 0 AND
           findDatafileBackup_c.crescn IS NULL))
     AND decode(statusMask, BSavailable,
                decode(xdf.status, 'A', TRUE#, FALSE#),
                isStatusMatch(xdf.status, statusMask)) = TRUE#
     AND (findDatafileBackup_c.tag is NULL OR
          xdf.tag = findDatafileBackup_c.tag)
     AND (findDatafileBackup_c.pattern is NULL OR
          xdf.handle LIKE replace(replace(findDatafileBackup_c.pattern,
                                     '*','**'), '_', '*_')
                    ESCAPE '*')
     AND (findDatafileBackup_c.completedAfter is NULL OR
          xdf.completion_time >= findDatafileBackup_c.completedAfter)
     AND (findDatafileBackup_c.completedBefore is NULL OR
          xdf.completion_time <= findDatafileBackup_c.completedBefore)
     AND (findDatafileBackup_c.untilSCN is NULL OR
          (xdf.plugged_readonly = 'NO' AND
           xdf.ckp_scn <= findDatafileBackup_c.untilSCN) OR
          (xdf.plugged_readonly = 'YES' AND
           xdf.plugin_scn <= findDatafileBackup_c.untilSCN))
     AND (findDatafileBackup_c.level is NULL OR
          xdf.incr_level <= findDatafileBackup_c.level)
     AND dbinc.db_key=this_db_key
     AND ((user_site_key  = xdf.site_key) OR
          (user_site_key IS NULL AND
           ((tape_backups_shared = TRUE#) OR
            (this_site_key = nvl(xdf.site_key, this_site_key)))))
     AND (guidQualifier IS NULL OR xdf.pdb_key = guid2pdbKeyQualifier)
 
   UNION ALL
 
   SELECT backupSet_con_t       type_con,
          bdf.bdf_key           key_con,
          bdf.bdf_recid             recid_con,
          bdf.bdf_stamp             stamp_con,
          bs.set_stamp          setStamp_con,
          bs.set_count          setCount_con,
          bs.bs_recid              bsRecid_con,
          bs.bs_stamp              bsStamp_con,
          bs.bs_key             bsKey_con,
          bs.incr_level  bsLevel_con,
          bs.bck_type        bsType_con,
          abs((bs.completion_time - bs.start_time) * 86400)
                                elapseSecs_con,
          bs.pieces             pieceCount_con,
          to_char(null)         fileName_con,
          to_char(null)         tag_con,
          to_number(null)       copyNumber_con,
          to_char(null)         status_con,
          bdf.blocks            blocks_con,
          bdf.block_size        blockSize_con,
          to_char(null)         deviceType_con,
          bs.completion_time    compTime_con,
          to_date(null)         cfCreationTime_con,
          to_number(null)       pieceNumber_con,
          to_date(null)         bpCompTime_con,
          to_char(null)         bpCompressed_con,
          multi_section         multi_section_con,
 
          decode(bdf.incr_scn, 0, full_act_t, incremental_act_t)
                                type_act,
          bdf.incr_scn          fromSCN_act,
          bdf.ckp_scn           toSCN_act,
          bdf.ckp_time          toTime_act,
          dbinc.reset_scn       rlgSCN_act,
          dbinc.reset_time      rlgTime_act,
          bdf.dbinc_key         dbincKey_act,
          bdf.incr_level        level_act,
          bdf.section_size      section_size_act,
 
          bdf.file#             dfNumber_obj,
          bdf.create_scn        dfCreationSCN_obj,
          to_number(null)       cfSequence_obj,
          to_date(null)         cfDate_obj,
          to_number(null)       logSequence_obj,
          to_number(null)       logThread_obj,
          to_number(null)       logRlgSCN_obj,
          to_date(null)         logRlgTime_obj,
          to_number(null)       logLowSCN_obj,
          to_date(null)         logLowTime_obj,
          to_number(null)       logNextSCN_obj,
          to_date(null)         logNextTime_obj,
          to_char(null)         logTerminal_obj,
          to_char(null)         cfType_obj,
          bdf.pdb_key           pdbKey_obj,
 
          bs.keep_options       keep_options,
          bs.keep_until         keep_until,
 
          bdf.abs_fuzzy_scn     afzSCN_act,
          to_date(null)         rfzTime_act,
          to_number(null)       rfzSCN_act,
          to_char(null)         media_con,
          'NO'                  isrdf_con,
          bs.site_key           site_key_con,
          bdf.foreign_dbid      foreignDbid_obj,
          decode(bdf.plugged_readonly, 'YES', 1, 0)
                                pluggedRonly_obj,
          bdf.plugin_scn        pluginSCN_obj,
          bdf.plugin_reset_scn  pluginRlgSCN_obj,
          bdf.plugin_reset_time pluginRlgTime_obj,
 
          to_number(null)       newDfCreationSCN_obj,
          decode(bdf.plugged_readonly, 'NO', bdf.ckp_scn,
                 bdf.plugin_scn)
                                newToSCN_act,
          decode(bdf.plugin_scn, 0, dbinc.reset_scn,
                 bdf.plugin_reset_scn)
                                newRlgSCN_act,
          decode(bdf.plugin_scn, 0, dbinc.reset_time,
                 bdf.plugin_reset_time)
                                newRlgTime_act,
          to_char(null)         sfDbUniqueName_obj,
          bdf.sparse_backup     sparse_backup_con,
          0                     ppl_pdb_id_con,
          0                     ppl_cdb_dbid_con
--
--
--
     FROM  bs, bdf, dbinc
   WHERE (sourcemask is NULL OR bitand(sourcemask, backupSet_con_t) != 0)
     AND (findDatafileBackup_c.onlyrdf = 0)
     AND (dbinc.db_key = this_db_key)            -- belongs to this database
     AND (bs.db_key = this_db_key)               -- belongs to this database
     AND (bdf.dbinc_key = dbinc.dbinc_key)       -- join bdf and dbinc
     AND (bdf.bs_key = bs.bs_key)                -- join bdf and bs
     AND bs.bck_type != 'L'                      -- only datafile backups
     AND (findDatafileBackup_c.reset_scn is NULL  OR
          canApplyAnyRedo = TRUE# OR
          (bdf.plugged_readonly = 'NO' AND
           findDatafileBackup_c.reset_scn  = dbinc.reset_scn AND
           findDatafileBackup_c.reset_time = dbinc.reset_time) OR
          (bdf.plugged_readonly = 'YES' AND
           findDatafileBackup_c.reset_scn  = bdf.plugin_reset_scn AND
           findDatafileBackup_c.reset_time = bdf.plugin_reset_time))
     AND bdf.file# = nvl(findDatafileBackup_c.fno, bdf.file#)
     AND bdf.file# != 0                              -- no ctrl bkps
     AND (onlytc = FALSE#     OR
          tc_database = TRUE# OR
          isTranslatedFno(bdf.file#) = TRUE#)        -- only tnslated files
     AND ((findDatafileBackup_c.pluginSCN = 0  AND
           bdf.plugin_scn = 0                  AND
           bdf.create_scn = findDatafileBackup_c.crescn)
          OR
          (findDatafileBackup_c.pluginSCN != 0 AND
           bdf.plugin_scn = findDatafileBackup_c.pluginSCN)
          OR
          (findDatafileBackup_c.pluginSCN = 0 AND
           findDatafileBackup_c.crescn IS NULL))
     AND (findDatafileBackup_c.completedAfter is NULL OR
          bs.completion_time >= findDatafileBackup_c.completedAfter)
     AND (findDatafileBackup_c.completedBefore is NULL OR
          bs.completion_time <= findDatafileBackup_c.completedBefore)
     AND (findDatafileBackup_c.untilSCN is NULL OR
          (bdf.plugged_readonly = 'NO' AND
           bdf.ckp_scn <= findDatafileBackup_c.untilSCN) OR
          (bdf.plugged_readonly = 'YES' AND
           bdf.plugin_scn <= findDatafileBackup_c.untilSCN))
--
--
--
--
--
--
--
     AND (findDatafileBackup_c.level is NULL OR
         bdf.incr_level <= findDatafileBackup_c.level OR
         (findDatafileBackup_c.allowCumuLevelN = TRUE# AND
          bdf.create_scn = bdf.incr_scn AND
          bdf.foreign_dbid = 0))
     AND (bs.site_key IS NULL         OR -- always return null site_key
          user_site_key = bs.site_key OR -- user interested in one site
          (user_site_key IS NULL AND     -- return rows per access attr
           (disk_backups_shared = TRUE# OR
            tape_backups_shared = TRUE# OR
            this_site_key = bs.site_key)))
     AND (guidQualifier IS NULL OR bdf.pdb_key = guid2pdbKeyQualifier)
 
  ORDER BY  dfNumber_obj,         -- dfNumber_obj
            newRlgSCN_act  desc,  -- rlgSCN_act, last incarnation first
            newRlgTime_act desc,  -- rlgTime_act
            newToSCN_act   desc,  -- toSCN_act
            stamp_con      desc;  -- stamp_con
 
 
CURSOR findDatafileCopyKey(
   copyKey              IN     number
  ,statusMask           IN     binary_integer)
RETURN rcvRec_t IS
--
   SELECT imageCopy_con_t       type_con,
          cdf_key               key_con,
          cdf_recid             recid_con,
          cdf_stamp             stamp_con,
          to_number(null)       setStamp_con,
          to_number(null)       setCount_con,
          to_number(null)       bsRecid_con,
          to_number(null)       bsStamp_con,
          to_number(null)       bsKey_con,
          to_number(null)       bsLevel_con,
          to_char(null)         bsType_con,
          to_number(null)       elapseSecs_con,
          to_number(null)       pieceCount_con,
          fname                 fileName_con,
          tag                   tag_con,
          to_number(null)       copyNumber_con,
          status                status_con,
          blocks                blocks_con,
          block_size            blockSize_con,
          'DISK'                deviceType_con,
          completion_time       compTime_con,
          to_date(null)         cfCreationTime_con,
          to_number(null)       pieceNumber_con,
          to_date(null)         bpCompTime_con,
          to_char(null)         bpCompressed_con,
          to_char(null)         multi_section_con,
 
          full_act_t            type_act,
          0                     fromSCN_act,
          cdf.ckp_scn           toSCN_act,
          cdf.ckp_time          toTime_act,
          dbinc.reset_scn       rlgSCN_act,
          dbinc.reset_time      rlgTime_act,
          cdf.dbinc_key         dbincKey_act,
          incr_level            level_act,
          0                     section_size_act,
 
          file#                 dfNumber_obj,
          create_scn            dfCreationSCN_obj,
          to_number(null)       cfSequence_obj,
          to_date(null)         cfDate_obj,
          to_number(null)       logSequence_obj,
          to_number(null)       logThread_obj,
          to_number(null)       logRlgSCN_obj,
          to_date(null)         logRlgTime_obj,
          to_number(null)       logLowSCN_obj,
          to_date(null)         logLowTime_obj,
          to_number(null)       logNextSCN_obj,
          to_date(null)         logNextTime_obj,
          to_char(null)         logTerminal_obj,
          to_char(null)         cfType_obj,
          cdf.pdb_key           pdbKey_obj,
 
          cdf.keep_options      keep_options,
          cdf.keep_until        keep_until,
 
          cdf.abs_fuzzy_scn     afzSCN_act,
          cdf.rcv_fuzzy_time    rfzTime_act,
          cdf.rcv_fuzzy_scn     rfzSCN_act,
          to_char(null)         media_con,
          is_recovery_dest_file isrdf_con,
          site_key              site_key_con,
          cdf.foreign_dbid      foreignDbid_obj,
          decode(cdf.plugged_readonly, 'YES', 1, 0)
                                pluggedRonly_obj,
          cdf.plugin_scn        pluginSCN_obj,
          cdf.plugin_reset_scn  pluginRlgSCN_obj,
          cdf.plugin_reset_time pluginRlgTime_obj,
 
          to_number(null)       newDfCreationSCN_obj,
          to_number(null)       newToSCN_act,
          to_number(null)       newRlgSCN_act,
          to_date(null)         newRlgTime_act,
          to_char(null)         sfDbUniqueName_obj,
          cdf.sparse_backup     sparse_backup_con,
          0                     ppl_pdb_id_con,
          0                     ppl_cdb_dbid_con
     FROM cdf, dbinc
    WHERE dbinc.db_key = this_db_key            -- belongs to this database
      AND dbinc.dbinc_key = cdf.dbinc_key       -- join cdf and dbinc
      AND (findDatafileCopyKey.copyKey = cdf_key)
      AND decode(statusMask, BSavailable,
                 decode(status, 'A', TRUE#, FALSE#),
                 isStatusMatch(status, statusMask)) = TRUE#
      AND ((user_site_key = cdf.site_key) OR
           (user_site_key IS NULL AND
            ((disk_backups_shared = TRUE#) OR
             (this_site_key = nvl(cdf.site_key, this_site_key)))))
 
    ORDER BY dfNumber_obj,              -- for duplicate filtering
             decode(pluggedRonly_obj, 0, toSCN_act, pluginSCN_obj) desc,
--
             stamp_con desc;            -- to get most recent
 
CURSOR findControlFileCopyKey(
   copyKey              IN     number
  ,statusMask           IN     binary_integer)
RETURN rcvRec_t IS
--
   SELECT imageCopy_con_t       type_con,
          ccf_key               key_con,
          ccf_recid             recid_con,
          ccf_stamp             stamp_con,
          to_number(null)       setStamp_con,
          to_number(null)       setCount_con,
          to_number(null)       bsRecid_con,
          to_number(null)       bsStamp_con,
          to_number(null)       bsKey_con,
          to_number(null)       bsLevel_con,
          to_char(null)         bsType_con,
          to_number(null)       elapseSecs_con,
          to_number(null)       pieceCount_con,
          fname                 fileName_con,
          tag                   tag_con,
          to_number(null)       copyNumber_con,
          status                status_con,
          to_number(null)       blocks_con,
          block_size            blockSize_con,
          'DISK'                deviceType_con,
          completion_time       compTime_con,
          create_time           cfCreationTime_con,
          to_number(null)       pieceNumber_con,
          to_date(null)         bpCompTime_con,
          to_char(null)         bpCompressed_con,
          to_char(null)         multi_section_con,
 
          full_act_t            type_act,
          0                     fromSCN_act,
          ccf.ckp_scn           toSCN_act,
          ccf.ckp_time          toTime_act,
          dbinc.reset_scn       rlgSCN_act,
          dbinc.reset_time      rlgTime_act,
          ccf.dbinc_key         dbincKey_act,
          to_number(null)       level_act,
          0                     section_size_act,
 
          0                     dfNumber_obj,
          0                     dfCreationSCN_obj,
          to_number(null)       cfSequence_obj,
          to_date(null)         cfDate_obj,
          to_number(null)       logSequence_obj,
          to_number(null)       logThread_obj,
          to_number(null)       logRlgSCN_obj,
          to_date(null)         logRlgTime_obj,
          to_number(null)       logLowSCN_obj,
          to_date(null)         logLowTime_obj,
          to_number(null)       logNextSCN_obj,
          to_date(null)         logNextTime_obj,
          to_char(null)         logTerminal_obj,
          nvl(controlfile_type, 'B')
                                cfType_obj,
          ccf.pdb_key           pdbKey_obj,
 
          ccf.keep_options      keep_options,
          ccf.keep_until        keep_until,
 
          to_number(null)       afzSCN_act,
          to_date(null)         rfzTime_act,
          to_number(null)       rfzSCN_act,
          to_char(null)         media_con,
          is_recovery_dest_file isrdf_con,
          site_key              site_key_con,
          0                     foreignDbid_obj,
          0                     pluggedRonly_obj,
          0                     pluginSCN_obj,
          0                     pluginRlgSCN_obj,
          to_date(null)         pluginRlgTime_obj,
 
          to_number(null)       newDfCreationSCN_obj,
          to_number(null)       newToSCN_act,
          to_number(null)       newRlgSCN_act,
          to_date(null)         newRlgTime_act,
          to_char(null)         sfDbUniqueName_obj,
          to_char(null)         sparse_backup_con,
          0                     ppl_pdb_id_con,
          0                     ppl_cdb_dbid_con
     FROM ccf, dbinc
    WHERE dbinc.db_key = this_db_key            -- belongs to this database
      AND dbinc.dbinc_key = ccf.dbinc_key       -- join cdf and dbinc
      AND (findControlFileCopyKey.copyKey = ccf_key)
      AND decode(statusMask, BSavailable,
                 decode(status, 'A', TRUE#, FALSE#),
                 isStatusMatch(status, statusMask)) = TRUE#
      AND ((user_site_key = ccf.site_key) OR
           (user_site_key IS NULL AND
            ((disk_backups_shared = TRUE#) OR
             (this_site_key = nvl(ccf.site_key, this_site_key)))))
 
    ORDER BY toSCN_act desc,            -- for tag translation
             stamp_con desc;            -- to get most recent
 
 
 
CURSOR findBackupsetFiles(
   bskey                IN     number)
RETURN rcvRec_t IS
--
   SELECT backupSet_con_t       type_con,
          bdf_key               key_con,
          bdf_recid             recid_con,
          bdf_stamp             stamp_con,
          bs.set_stamp          setStamp_con,
          bs.set_count          setCount_con,
          bs.bs_recid           bsRecid_con,
          bs.bs_stamp           bsStamp_con,
          bs.bs_key             bsKey_con,
          bs.incr_level         bsLevel_con,
          bs.bck_type           bsType_con,
          abs((bs.completion_time - bs.start_time) * 86400)
                                elapseSecs_con,
          bs.pieces             pieceCount_con,
          to_char(null)         fileName_con,
          to_char(null)         tag_con,
          to_number(null)       copyNumber_con,
          to_char(null)         status_con,
          bdf.blocks            blocks_con,
          bdf.block_size        blockSize_con,
          to_char(null)         deviceType_con,
          bs.completion_time    compTime_con,
          to_date(null)         cfCreationTime_con,
          to_number(null)       pieceNumber_con,
          to_date(null)         bpCompTime_con,
          to_char(null)         bpCompressed_con,
          to_char(null)         multi_section_con,
 
          decode(bdf.incr_scn, 0, full_act_t, incremental_act_t)
                                type_act,
          bdf.incr_scn          fromSCN_act,
          bdf.ckp_scn           toSCN_act,
          bdf.ckp_time          toTime_act,
          dbinc.reset_scn       rlgSCN_act,
          dbinc.reset_time      rlgTime_act,
          bdf.dbinc_key         dbincKey_act,
          bdf.incr_level        level_act,
          bdf.section_size      section_size_act,
 
          file#                 dfNumber_obj,
          create_scn            dfCreationSCN_obj,
          to_number(null)       cfSequence_obj,
          to_date(null)         cfDate_obj,
          to_number(null)       logSequence_obj,
          to_number(null)       logThread_obj,
          to_number(null)       logRlgSCN_obj,
          to_date(null)         logRlgTime_obj,
          to_number(null)       logLowSCN_obj,
          to_date(null)         logLowTime_obj,
          to_number(null)       logNextSCN_obj,
          to_date(null)         logNextTime_obj,
          to_char(null)         logTerminal_obj,
          to_char(null)         cfType_obj,
          bdf.pdb_key           pdbKey_obj,
 
          bs.keep_options       keep_options,
          bs.keep_until         keep_until,
 
          bdf.abs_fuzzy_scn     afzSCN_act,
          to_date(null)         rfzTime_act,
          to_number(null)       rfzSCN_act,
          to_char(null)         media_con,
          'NO'                  isrdf_con,
          bs.site_key           site_key_con,
          bdf.foreign_dbid      foreignDbid_obj,
          decode(bdf.plugged_readonly, 'YES', 1, 0)
                                pluggedRonly_obj,
          bdf.plugin_scn        pluginSCN_obj,
          bdf.plugin_reset_scn  pluginRlgSCN_obj,
          bdf.plugin_reset_time pluginRlgTime_obj,
 
          to_number(null)       newDfCreationSCN_obj,
          to_number(null)       newToSCN_act,
          to_number(null)       newRlgSCN_act,
          to_date(null)         newRlgTime_act,
          to_char(null)         sfDbUniqueName_obj,
          bdf.sparse_backup     sparse_backup_con,
          0                     ppl_pdb_id_con,
          0                     ppl_cdb_dbid_con
     FROM bdf, bs, dbinc
    WHERE (allIncarnations = TRUE# OR
           canApplyAnyRedo = TRUE# OR dbinc.dbinc_key = this_dbinc_key)
      AND dbinc.db_key     = this_db_key        -- belongs to this database
      AND dbinc.dbinc_key  = bdf.dbinc_key      -- join bdf and dbinc
      AND bdf.bs_key       = bs.bs_key          -- join bdf and bs
      AND bs.bs_key        = bskey
      AND bs.bck_type     != 'L'                -- only datafile backups
      AND (bs.site_key IS NULL         OR       -- always return null site_key
           user_site_key = bs.site_key OR       -- user interested in one site
           (user_site_key IS NULL AND           -- return rows per access attr
            (disk_backups_shared = TRUE# OR
             tape_backups_shared = TRUE# OR
             this_site_key = bs.site_key)))
    UNION ALL
--
   SELECT backupSet_con_t       type_con,
          bcf_key               key_con,
          bcf_recid             recid_con,
          bcf_stamp             stamp_con,
          bs.set_stamp          setStamp_con,
          bs.set_count          setCount_con,
          bs.bs_recid           bsRecid_con,
          bs.bs_stamp           bsStamp_con,
          bs.bs_key             bsKey_con,
          bs.incr_level         bsLevel_con,
          bs.bck_type           bsType_con,
          abs((bs.completion_time - bs.start_time) * 86400)
                                elapseSecs_con,
          bs.pieces             pieceCount_con,
          to_char(null)         fileName_con,
          to_char(null)         tag_con,
          to_number(null)       copyNumber_con,
          to_char(null)         status_con,
          nvl(bcf.blocks,0)     blocks_con,
          bcf.block_size        blockSize_con,
          to_char(null)         deviceType_con,
          bs.completion_time    compTime_con,
          to_date(null)         cfCreationTime_con,
          to_number(null)       pieceNumber_con,
          to_date(null)         bpCompTime_con,
          to_char(null)         bpCompressed_con,
          multi_section         multi_section_con,
 
          full_act_t            type_act,
          to_number(null)       fromSCN_act,
          bcf.ckp_scn           toSCN_act,
          bcf.ckp_time          toTime_act,
          dbinc.reset_scn       rlgSCN_act,
          dbinc.reset_time      rlgTime_act,
          bcf.dbinc_key         dbincKey_act,
          to_number(null)       level_act,
          0                     section_size_act,
 
          0                     dfNumber_obj,
          0                     dfCreationSCN_obj,
          bcf.autobackup_sequence
                                cfSequence_obj,
          bcf.autobackup_date   cfDate_obj,
          to_number(null)       logSequence_obj,
          to_number(null)       logThread_obj,
          to_number(null)       logRlgSCN_obj,
          to_date(null)         logRlgTime_obj,
          to_number(null)       logLowSCN_obj,
          to_date(null)         logLowTime_obj,
          to_number(null)       logNextSCN_obj,
          to_date(null)         logNextTime_obj,
          to_char(null)         logTerminal_obj,
          nvl(controlfile_type, 'B')
                                 cfType_obj,
          bcf.pdb_key           pdbKey_obj,
 
          bs.keep_options       keep_options,
          bs.keep_until         keep_until,
 
          to_number(null)       afzSCN_act,
          to_date(null)         rfzTime_act,
          to_number(null)       rfzSCN_act,
          to_char(null)         media_con,
          'NO'                  isrdf_con,
          bs.site_key           site_key_con,
          0                     foreignDbid_obj,
          0                     pluggedRonly_obj,
          0                     pluginSCN_obj,
          0                     pluginRlgSCN_obj,
          to_date(null)         pluginRlgTime_obj,
 
          to_number(null)       newDfCreationSCN_obj,
          to_number(null)       newToSCN_act,
          to_number(null)       newRlgSCN_act,
          to_date(null)         newRlgTime_act,
          to_char(null)         sfDbUniqueName_obj,
          to_char(null)         sparse_backup_con,
          0                     ppl_pdb_id_con,
          0                     ppl_cdb_dbid_con
     FROM bcf, bs, dbinc
    WHERE (allIncarnations = TRUE# OR
           canApplyAnyRedo = TRUE# OR dbinc.dbinc_key = this_dbinc_key)
      AND dbinc.db_key     = this_db_key        -- belongs to this database
      AND dbinc.dbinc_key  = bcf.dbinc_key      -- join bcf and dbinc
      AND bcf.bs_key       = bs.bs_key          -- join bcf and bs
      AND bs.bs_key        = bskey
      AND bs.bck_type     != 'L'                -- ignore archivelog backups
      AND (bs.site_key IS NULL         OR       -- always return null site_key
           user_site_key = bs.site_key OR       -- user interested in one site
           (user_site_key IS NULL AND           -- return rows per access attr
            (disk_backups_shared = TRUE# OR
             tape_backups_shared = TRUE# OR
             this_site_key = bs.site_key)))
    UNION ALL
--
   SELECT backupSet_con_t       type_con,
          bsf_recid             key_con,
          bsf_recid             recid_con,
          bsf_stamp             stamp_con,
          bs.set_stamp          setStamp_con,
          bs.set_count          setCount_con,
          bs.bs_recid           bsRecid_con,
          bs.bs_stamp           bsStamp_con,
          bs.bs_key             bsKey_con,
          bs.incr_level         bsLevel_con,
          bs.bck_type           bsType_con,
          abs((bs.completion_time - bs.start_time) * 86400)
                                elapseSecs_con,
          bs.pieces             pieceCount_con,
          to_char(null)         fileName_con,
          to_char(null)         tag_con,
          to_number(null)       copyNumber_con,
          to_char(null)         status_con,
          0                     blocks_con,
          0                     blockSize_con,
          to_char(null)         deviceType_con,
          bs.completion_time    compTime_con,
          to_date(null)         cfCreationTime_con,
          to_number(null)       pieceNumber_con,
          to_date(null)         bpCompTime_con,
          to_char(null)         bpCompressed_con,
          multi_section         multi_section_con,
 
          full_act_t            type_act,
          0                     fromSCN_act,
          0                     toSCN_act,
          modification_time     toTime_act,
          to_number(null)       rlgSCN_act,
          to_date(null)         rlgTime_act,
          to_number(null)       dbincKey_act,
          to_number(null)       level_act,
          0                     section_size_act,
 
          to_number(null)       dfNumber_obj,
          to_number(null)       dfCreationSCN_obj,
          to_number(null)       cfSequence_obj,
          to_date(null)         cfDate_obj,
          to_number(null)       logSequence_obj,
          to_number(null)       logThread_obj,
          to_number(null)       logRlgSCN_obj,
          to_date(null)         logRlgTime_obj,
          to_number(null)       logLowSCN_obj,
          to_date(null)         logLowTime_obj,
          to_number(null)       logNextSCN_obj,
          to_date(null)         logNextTime_obj,
          to_char(null)         logTerminal_obj,
          to_char(null)         cfType_obj,
          bsf.pdb_key           pdbKey_obj,
 
          bs.keep_options       keep_options,
          bs.keep_until         keep_until,
 
          to_number(null)       afzSCN_act,
          to_date(null)         rfzTime_act,
          to_number(null)       rfzSCN_act,
          to_char(null)         media_con,
          'NO'                  isrdf_con,
          bs.site_key           site_key_con,
          0                     foreignDbid_obj,
          0                     pluggedRonly_obj,
          0                     pluginSCN_obj,
          0                     pluginRlgSCN_obj,
          to_date(null)         pluginRlgTime_obj,
 
          to_number(null)       newDfCreationSCN_obj,
          to_number(null)       newToSCN_act,
          to_number(null)       newRlgSCN_act,
          to_date(null)         newRlgTime_act,
          to_char(null)         sfDbUniqueName_obj,
          to_char(null)         sparse_backup_con,
          0                     ppl_pdb_id_con,
          0                     ppl_cdb_dbid_con
     FROM bsf, bs, db
    WHERE bsf.bs_key = bs.bs_key                -- join bsf and bs
      AND bs.db_key = this_db_key               -- belongs to this database
      AND bsf.db_key = db.db_key                -- join bsf and db
      AND bs.bs_key = bskey
      AND bs.bck_type != 'L'                    -- ignore archivelog backups
      AND (bs.site_key IS NULL         OR       -- always return null site_key
           user_site_key = bs.site_key OR       -- user interested in one site
           (user_site_key IS NULL AND           -- return rows per access attr
            (disk_backups_shared = TRUE# OR
             tape_backups_shared = TRUE# OR
             this_site_key = bs.site_key)))
    UNION ALL
--
   SELECT backupSet_con_t       type_con,
          brl.brl_key           key_con,
          brl.brl_recid         recid_con,
          brl.brl_stamp         stamp_con,
          bs.set_stamp          setStamp_con,
          bs.set_count          setCount_con,
          bs.bs_recid           bsRecid_con,
          bs.bs_stamp           bsStamp_con,
          bs.bs_key             bsKey_con,
          to_number(null)       bsLevel_con,
          bs.bck_type           bsType_con,
          abs((bs.completion_time - bs.start_time) * 86400)
                                elapseSecs_con,
          bs.pieces             pieceCount_con,
          to_char(null)         fileName_con,
          to_char(null)         tag_con,
          to_number(null)       copyNumber_con,
          to_char(null)         status_con,
          brl.blocks            blocks_con,
          brl.block_size        blockSize_con,
          to_char(null)         deviceType_con,
          bs.completion_time    compTime_con,
          to_date(null)         cfCreationTime_con,
          to_number(null)       pieceNumber_con,
          to_date(null)         bpCompTime_con,
          to_char(null)         bpCompressed_con,
          multi_section         multi_section_con,
 
          full_act_t            type_act,
          to_number(null)       fromSCN_act,
          to_number(null)       toSCN_act,
          to_date(null)         toTime_act,
          to_number(null)       rlgSCN_act,
          to_date(null)         rlgTime_act,
          dbinc.dbinc_key       dbincKey_act,
          to_number(null)       level_act,
          0                     section_size_act,
 
          to_number(null)       dfNumber_obj,
          to_number(null)       dfCreationSCN_obj,
          to_number(null)       cfSequence_obj,
          to_date(null)         cfDate_obj,
          brl.sequence#         logSequence_obj,
          brl.thread#           logThread_obj,
          dbinc.reset_scn       logRlgSCN_obj,
          dbinc.reset_time      logRlgTime_obj,
          brl.low_scn           logLowSCN_obj,
          brl.low_time          logLowTime_obj,
          brl.next_scn          logNextSCN_obj,
          brl.next_time         logNextTime_obj,
          brl.terminal          logTerminal_obj,
          to_char(null)         cfType_obj,
          to_number(null)       pdbKey_obj,
 
          to_number(null)       keep_options,
          to_date(null)         keep_until,
 
          to_number(null)       afzSCN_act,
          to_date(null)         rfzTime_act,
          to_number(null)       rfzSCN_act,
          to_char(null)         media_con,
          'NO'                  isrdf_con,
          bs.site_key           site_key_con,
          0                     foreignDbid_obj,
          0                     pluggedRonly_obj,
          0                     pluginSCN_obj,
          0                     pluginRlgSCN_obj,
          to_date(null)         pluginRlgTime_obj,
 
          to_number(null)       newDfCreationSCN_obj,
          to_number(null)       newToSCN_act,
          to_number(null)       newRlgSCN_act,
          to_date(null)         newRlgTime_act,
          to_char(null)         sfDbUniqueName_obj,
          to_char(null)         sparse_backup_con,
          0                     ppl_pdb_id_con,
          0                     ppl_cdb_dbid_con
     FROM brl, bs, dbinc
    WHERE (allIncarnations = TRUE# OR
           canApplyAnyRedo = TRUE# OR dbinc.dbinc_key = this_dbinc_key)
      AND dbinc.db_key     = this_db_key        -- belongs to this database
      AND dbinc.dbinc_key  = brl.dbinc_key      -- join brl and dbinc
      AND brl.bs_key       = bs.bs_key          -- join brl and bs
      AND bs.bs_key        = bskey
      AND bs.bck_type      = 'L'                -- only archivelog backups
      AND (bs.site_key IS NULL         OR       -- always return null site_key
           user_site_key = bs.site_key OR       -- user interested in one site
           (user_site_key IS NULL AND           -- return rows per access attr
            (disk_backups_shared = TRUE# OR
             tape_backups_shared = TRUE# OR
             this_site_key = bs.site_key)))
--
    ORDER BY dfNumber_obj,
             logThread_obj,
             logSequence_obj,
             logTerminal_obj desc;
 
--
--
--
 
CURSOR findProxyCopy(
   tag                  IN     varchar2       DEFAULT NULL
  ,handle               IN     varchar2       DEFAULT NULL
  ,deviceType           IN     varchar2       DEFAULT NULL
  ,statusMask           IN     binary_integer
  ,pdbKey               IN     number         DEFAULT NULL
  ,guid                 IN     varchar2       DEFAULT NULL)
RETURN rcvRec_t IS
   SELECT proxyCopy_con_t       type_con,
          xdf_key               key_con,
          xdf_recid             recid_con,
          xdf_stamp             stamp_con,
          to_number(null)       setStamp_con,
          to_number(null)       setCount_con,
          to_number(null)       bsRecid_con,
          to_number(null)       bsStamp_con,
          to_number(null)       bsKey_con,
          to_number(null)       bsLevel_con,
          to_char(null)         bsType_con,
          to_number(null)       elapseSecs_con,
          to_number(null)       pieceCount_con,
          handle                fileName_con,
          tag                   tag_con,
          to_number(null)       copyNumber_con,
          status                status_con,
          blocks                blocks_con,
          block_size            blockSize_con,
          device_type           deviceType_con,
          completion_time       compTime_con,
          to_date(null)         cfCreationTime_con,
          to_number(null)       pieceNumber_con,
          to_date(null)         bpCompTime_con,
          to_char(null)         bpCompressed_con,
          to_char(null)         multi_section_con,
 
          full_act_t            type_act,
          0                     fromSCN_act,
          xdf.ckp_scn           toSCN_act,
          xdf.ckp_time          toTime_act,
          dbinc.reset_scn       rlgSCN_act,
          dbinc.reset_time      rlgTime_act,
          xdf.dbinc_key         dbincKey_act,
          incr_level            level_act,
          0                     section_size_act,
 
          file#                 dfNumber_obj,
          create_scn            dfCreationSCN_obj,
          to_number(null)       cfSequence_obj,
          to_date(null)         cfDate_obj,
          to_number(null)       logSequence_obj,
          to_number(null)       logThread_obj,
          to_number(null)       logRlgSCN_obj,
          to_date(null)         logRlgTime_obj,
          to_number(null)       logLowSCN_obj,
          to_date(null)         logLowTime_obj,
          to_number(null)       logNextSCN_obj,
          to_date(null)         logNextTime_obj,
          to_char(null)         logTerminal_obj,
          to_char(null)         cfType_obj,
          xdf.pdb_key           pdbKey_obj,
 
          xdf.keep_options      keep_options,
          xdf.keep_until        keep_until,
 
          xdf.abs_fuzzy_scn     afzSCN_act,
          xdf.rcv_fuzzy_time    rfzTime_act,
          xdf.rcv_fuzzy_scn     rfzSCN_act,
          xdf.media             media_con,
          'NO'                  isrdf_con,
          site_key              site_key_con,
          xdf.foreign_dbid      foreignDbid_obj,
          decode(xdf.plugged_readonly, 'YES', 1, 0)
                                pluggedRonly_obj,
          xdf.plugin_scn        pluginSCN_obj,
          xdf.plugin_reset_scn  pluginRlgSCN_obj,
          xdf.plugin_reset_time pluginRlgTime_obj,
 
          to_number(null)       newDfCreationSCN_obj,
          to_number(null)       newToSCN_act,
          to_number(null)       newRlgSCN_act,
          to_date(null)         newRlgTime_act,
          to_char(null)         sfDbUniqueName_obj,
          to_char(null)         sparse_backup_con,
          0                     ppl_pdb_id_con,
          0                     ppl_cdb_dbid_con
     FROM xdf, dbinc
    WHERE dbinc.db_key = this_db_key            -- belongs to this database
      AND dbinc.dbinc_key = xdf.dbinc_key       -- join xdf and dbinc
      AND (findProxyCopy.tag IS NULL OR
           findProxyCopy.tag = tag)
      AND (findProxyCopy.handle IS NULL OR
           findProxyCopy.handle = handle)
      AND (findProxyCopy.deviceType IS NULL OR
           findProxyCopy.deviceType = device_type)
      AND decode(statusMask, BSavailable,
                 decode(status, 'A', TRUE#, FALSE#),
                 isStatusMatch(status, statusMask)) = TRUE#
      AND ((user_site_key  = xdf.site_key) OR
           (user_site_key IS NULL AND
            ((tape_backups_shared = TRUE#) OR
             (this_site_key = nvl(xdf.site_key, this_site_key)))))
      AND (guid IS NULL OR findProxyCopy.pdbKey = xdf.pdb_key)
 
    UNION ALL
 
   SELECT proxyCopy_con_t       type_con,
          xcf_key               key_con,
          xcf_recid             recid_con,
          xcf_stamp             stamp_con,
          to_number(null)       setStamp_con,
          to_number(null)       setCount_con,
          to_number(null)       bsRecid_con,
          to_number(null)       bsStamp_con,
          to_number(null)       bsKey_con,
          to_number(null)       bsLevel_con,
          to_char(null)         bsType_con,
          to_number(null)       elapseSecs_con,
          to_number(null)       pieceCount_con,
          handle                fileName_con,
          tag                   tag_con,
          to_number(null)       copyNumber_con,
          status                status_con,
          to_number(null)       blocks_con,     -- xcf doesn't have blocks
          block_size            blockSize_con,
          device_type           deviceType_con,
          completion_time       compTime_con,
          to_date(null)         cfCreationTime_con,
          to_number(null)       pieceNumber_con,
          to_date(null)         bpCompTime_con,
          to_char(null)         bpCompressed_con,
          to_char(null)         multi_section_con,
 
          full_act_t            type_act,
          0                     fromSCN_act,
          xcf.ckp_scn           toSCN_act,
          xcf.ckp_time          toTime_act,
          dbinc.reset_scn       rlgSCN_act,
          dbinc.reset_time      rlgTime_act,
          xcf.dbinc_key         dbincKey_act,
          to_number(null)       level_act,
          0                     section_size_act,
 
          0                     dfNumber_obj,
          0                     dfCreationSCN_obj,
          to_number(null)       cfSequence_obj,
          to_date(null)         cfDate_obj,
          to_number(null)       logSequence_obj,
          to_number(null)       logThread_obj,
          to_number(null)       logRlgSCN_obj,
          to_date(null)         logRlgTime_obj,
          to_number(null)       logLowSCN_obj,
          to_date(null)         logLowTime_obj,
          to_number(null)       logNextSCN_obj,
          to_date(null)         logNextTime_obj,
          to_char(null)         logTerminal_obj,
          nvl(controlfile_type, 'B')
                                cfType_obj,
          xcf.pdb_key           pdbKey_obj,
 
          xcf.keep_options      keep_options,
          xcf.keep_until        keep_until,
 
          to_number(null)       afzSCN_act,
          to_date(null)         rfzTime_act,
          to_number(null)       rfzSCN_act,
          media                 media_con,
          'NO'                  isrdf_con,
          site_key              site_key_con,
          0                     foreignDbid_obj,
          0                     pluggedRonly_obj,
          0                     pluginSCN_obj,
          0                     pluginRlgSCN_obj,
          to_date(null)         pluginRlgTime_obj,
 
          to_number(null)       newDfCreationSCN_obj,
          to_number(null)       newToSCN_act,
          to_number(null)       newRlgSCN_act,
          to_date(null)         newRlgTime_act,
          to_char(null)         sfDbUniqueName_obj,
          to_char(null)         sparse_backup_con,
          0                     ppl_pdb_id_con,
          0                     ppl_cdb_dbid_con
     FROM xcf, dbinc
    WHERE db_key = this_db_key          -- belongs to this database
      AND dbinc.dbinc_key = xcf.dbinc_key       -- join dbinc and xcf
      AND (findProxyCopy.tag IS NULL OR
           findProxyCopy.tag = tag)
      AND (findProxyCopy.handle IS NULL OR
           findProxyCopy.handle = handle)
      AND (findProxyCopy.deviceType IS NULL OR
           findProxyCopy.deviceType = device_type)
      AND decode(statusMask, BSavailable,
                 decode(status, 'A', TRUE#, FALSE#),
                 isStatusMatch(status, statusMask)) = TRUE#
      AND ((user_site_key  = xcf.site_key) OR
           (user_site_key IS NULL AND
            ((tape_backups_shared = TRUE#) OR
             (this_site_key = nvl(xcf.site_key, this_site_key)))))
      AND (guid IS NULL OR findProxyCopy.pdbKey = xcf.pdb_key)
 
    UNION ALL
 
   SELECT proxyCopy_con_t       type_con,
          xal_key               key_con,
          xal_recid             recid_con,
          xal_stamp             stamp_con,
          to_number(null)       setStamp_con,
          to_number(null)       setCount_con,
          to_number(null)       bsRecid_con,
          to_number(null)       bsStamp_con,
          to_number(null)       bsKey_con,
          to_number(null)       bsLevel_con,
          to_char(null)         bsType_con,
          to_number(null)       elapseSecs_con,
          to_number(null)       pieceCount_con,
          handle                fileName_con,
          tag                   tag_con,
          to_number(null)       copyNumber_con,
          xal.status            status_con,
          xal.blocks            blocks_con,
          xal.block_size        blockSize_con,
          xal.device_type       deviceType_con,
          xal.completion_time   compTime_con,
          to_date(null)         cfCreationTime_con,
          to_number(null)       pieceNumber_con,
          to_date(null)         bpCompTime_con,
          to_char(null)         bpCompressed_con,
          to_char(null)         multi_section_con,
 
          redo_act_t            type_act,
          0                     fromSCN_act,
          to_number(null)       toSCN_act,
          to_date(null)         toTime_act,
          to_number(null)       rlgSCN_act,
          to_date(null)         rlgTime_act,
          dbinc.dbinc_key       dbincKey_act,
          to_number(null)       level_act,
          0                     section_size_act,
 
          -1                    dfNumber_obj,         -- to sort last
          to_number(null)       dfCreationSCN_obj,
          to_number(null)       cfSequence_obj,
          to_date(null)         cfDate_obj,
          xal.sequence#         logSequence_obj,
          xal.thread#           logThread_obj,
          dbinc.reset_scn       logRlgSCN_obj,
          dbinc.reset_time      logRlgTime_obj,
          xal.low_scn           logLowSCN_obj,
          xal.low_time          logLowTime_obj,
          xal.next_scn          logNextSCN_obj,
          xal.next_time         logNextTime_obj,
          xal.terminal          logTerminal_obj,
          to_char(null)         cfType_obj,
          to_number(null)       pdbKey_obj,
 
          to_number(null)       keep_options,
          to_date(null)         keep_until,
 
          to_number(null)       afzSCN_act,
          to_date(null)         rfzTime_act,
          to_number(null)       rfzSCN_act,
          media                 media_con,
          'NO'                  isrdf_con,
          site_key              site_key_con,
          0                     foreignDbid_obj,
          0                     pluggedRonly_obj,
          0                     pluginSCN_obj,
          0                     pluginRlgSCN_obj,
          to_date(null)         pluginRlgTime_obj,
 
          to_number(null)       newDfCreationSCN_obj,
          to_number(null)       newToSCN_act,
          to_number(null)       newRlgSCN_act,
          to_date(null)         newRlgTime_act,
          to_char(null)         sfDbUniqueName_obj,
          to_char(null)         sparse_backup_con,
          0                     ppl_pdb_id_con,
          0                     ppl_cdb_dbid_con
     FROM xal, dbinc
    WHERE db_key = this_db_key                  -- belongs to this database
      AND dbinc.dbinc_key = xal.dbinc_key       -- join dbinc and xal
--
      AND (findProxyCopy.tag IS NULL OR
           findProxyCopy.tag = tag)
      AND (findProxyCopy.handle IS NULL OR
           findProxyCopy.handle = handle)
      AND (findProxyCopy.deviceType IS NULL OR
           findProxyCopy.deviceType = device_type)
      AND decode(statusMask, BSavailable,
                 decode(status, 'A', TRUE#, FALSE#),
                 isStatusMatch(status, statusMask)) = TRUE#
      AND ((user_site_key  = xal.site_key) OR
           (user_site_key IS NULL AND
            ((tape_backups_shared = TRUE#) OR
             (this_site_key = nvl(xal.site_key, this_site_key)))))
      AND (findProxyCopy.guid IS NULL)
 
    ORDER BY dfnumber_obj;
 
CURSOR findProxyCopyKey(
   key                  IN     number         DEFAULT NULL
  ,deviceType           IN     varchar2       DEFAULT NULL
  ,statusMask           IN     binary_integer)
RETURN rcvRec_t IS
   SELECT proxyCopy_con_t       type_con,
          xdf_key               key_con,
          xdf_recid             recid_con,
          xdf_stamp             stamp_con,
          to_number(null)       setStamp_con,
          to_number(null)       setCount_con,
          to_number(null)       bsRecid_con,
          to_number(null)       bsStamp_con,
          to_number(null)       bsKey_con,
          to_number(null)       bsLevel_con,
          to_char(null)         bsType_con,
          to_number(null)       elapseSecs_con,
          to_number(null)       pieceCount_con,
          handle                fileName_con,
          tag                   tag_con,
          to_number(null)       copyNumber_con,
          status                status_con,
          blocks                blocks_con,
          block_size            blockSize_con,
          device_type           deviceType_con,
          completion_time       compTime_con,
          to_date(null)         cfCreationTime_con,
          to_number(null)       pieceNumber_con,
          to_date(null)         bpCompTime_con,
          to_char(null)         bpCompressed_con,
          to_char(null)         multi_section_con,
 
          full_act_t            type_act,
          0                     fromSCN_act,
          xdf.ckp_scn           toSCN_act,
          xdf.ckp_time          toTime_act,
          dbinc.reset_scn       rlgSCN_act,
          dbinc.reset_time      rlgTime_act,
          xdf.dbinc_key         dbincKey_act,
          incr_level            level_act,
          0                     section_size_act,
 
          file#                 dfNumber_obj,
          create_scn            dfCreationSCN_obj,
          to_number(null)       cfSequence_obj,
          to_date(null)         cfDate_obj,
          to_number(null)       logSequence_obj,
          to_number(null)       logThread_obj,
          to_number(null)       logRlgSCN_obj,
          to_date(null)         logRlgTime_obj,
          to_number(null)       logLowSCN_obj,
          to_date(null)         logLowTime_obj,
          to_number(null)       logNextSCN_obj,
          to_date(null)         logNextTime_obj,
          to_char(null)         logTerminal_obj,
          to_char(null)         cfType_obj,
          xdf.pdb_key           pdbKey_obj,
 
          xdf.keep_options      keep_options,
          xdf.keep_until        keep_until,
 
          xdf.abs_fuzzy_scn     afzSCN_act,
          xdf.rcv_fuzzy_time    rfzTime_act,
          xdf.rcv_fuzzy_scn     rfzSCN_act,
          media                 media_con,
          'NO'                  isrdf_con,
          site_key              site_key_con,
          xdf.foreign_dbid      foreignDbid_obj,
          decode(xdf.plugged_readonly, 'YES', 1, 0)
                                pluggedRonly_obj,
          xdf.plugin_scn        pluginSCN_obj,
          xdf.plugin_reset_scn  pluginRlgSCN_obj,
          xdf.plugin_reset_time pluginRlgTime_obj,
 
          to_number(null)       newDfCreationSCN_obj,
          to_number(null)       newToSCN_act,
          to_number(null)       newRlgSCN_act,
          to_date(null)         newRlgTime_act,
          to_char(null)         sfDbUniqueName_obj,
          to_char(null)         sparse_backup_con,
          0                     ppl_pdb_id_con,
          0                     ppl_cdb_dbid_con
     FROM xdf, dbinc
    WHERE dbinc.db_key = this_db_key            -- belongs to this database
      AND dbinc.dbinc_key = xdf.dbinc_key       -- join xdf and dbinc
      AND (findProxyCopyKey.key = xdf_key)
      AND (findProxyCopyKey.deviceType IS NULL OR
           findProxyCopyKey.deviceType = device_type)
      AND decode(statusMask, BSavailable,
                 decode(status, 'A', TRUE#, FALSE#),
                 isStatusMatch(status, statusMask)) = TRUE#
      AND ((user_site_key  = xdf.site_key) OR
           (user_site_key IS NULL AND
            ((tape_backups_shared = TRUE#) OR
             (this_site_key = nvl(xdf.site_key, this_site_key)))))
 
    UNION ALL
 
   SELECT proxyCopy_con_t       type_con,
          xcf_key               key_con,
          xcf_recid             recid_con,
          xcf_stamp             stamp_con,
          to_number(null)       setStamp_con,
          to_number(null)       setCount_con,
          to_number(null)       bsRecid_con,
          to_number(null)       bsStamp_con,
          to_number(null)       bsKey_con,
          to_number(null)       bsLevel_con,
          to_char(null)         bsType_con,
          to_number(null)       elapseSecs_con,
          to_number(null)       pieceCount_con,
          handle                fileName_con,
          tag                   tag_con,
          to_number(null)       copyNumber_con,
          status                status_con,
          to_number(null)       blocks_con,     -- xcf doesn't have blocks
          block_size            blockSize_con,
          device_type           deviceType_con,
          completion_time       compTime_con,
          to_date(null)         cfCreationTime_con,
          to_number(null)       pieceNumber_con,
          to_date(null)         bpCompTime_con,
          to_char(null)         bpCompressed_con,
          to_char(null)         multi_section_con,
 
          full_act_t            type_act,
          0                     fromSCN_act,
          xcf.ckp_scn           toSCN_act,
          xcf.ckp_time          toTime_act,
          dbinc.reset_scn       rlgSCN_act,
          dbinc.reset_time      rlgTime_act,
          xcf.dbinc_key         dbincKey_act,
          to_number(null)       level_act,
          0                     section_size_act,
 
          0                     dfNumber_obj,
          0                     dfCreationSCN_obj,
          to_number(null)       cfSequence_obj,
          to_date(null)         cfDate_obj,
          to_number(null)       logSequence_obj,
          to_number(null)       logThread_obj,
          to_number(null)       logRlgSCN_obj,
          to_date(null)         logRlgTime_obj,
          to_number(null)       logLowSCN_obj,
          to_date(null)         logLowTime_obj,
          to_number(null)       logNextSCN_obj,
          to_date(null)         logNextTime_obj,
          to_char(null)         logTerminal_obj,
          nvl(controlfile_type, 'B')
                                cfType_obj,
          xcf.pdb_key           pdbKey_obj,
 
          xcf.keep_options      keep_options,
          xcf.keep_until        keep_until,
 
          to_number(null)       afzSCN_act,
          to_date(null)         rfzTime_act,
          to_number(null)       rfzSCN_act,
          media                 media_con,
          'NO'                  isrdf_con,
          site_key              site_key_con,
          0                     foreignDbid_obj,
          0                     pluggedRonly_obj,
          0                     pluginSCN_obj,
          0                     pluginRlgSCN_obj,
          to_date(null)         pluginRlgTime_obj,
 
          to_number(null)       newDfCreationSCN_obj,
          to_number(null)       newToSCN_act,
          to_number(null)       newRlgSCN_act,
          to_date(null)         newRlgTime_act,
          to_char(null)         sfDbUniqueName_obj,
          to_char(null)         sparse_backup_con,
          0                     ppl_pdb_id_con,
          0                     ppl_cdb_dbid_con
     FROM xcf, dbinc
    WHERE db_key = this_db_key          -- belongs to this database
      AND dbinc.dbinc_key = xcf.dbinc_key       -- join dbinc and xcf
      AND (findProxyCopyKey.key = xcf_key)
      AND (findProxyCopyKey.deviceType IS NULL OR
           findProxyCopyKey.deviceType = device_type)
      AND decode(statusMask, BSavailable,
                 decode(status, 'A', TRUE#, FALSE#),
                 isStatusMatch(status, statusMask)) = TRUE#
      AND ((user_site_key  = xcf.site_key) OR
           (user_site_key IS NULL AND
            ((tape_backups_shared = TRUE#) OR
             (this_site_key = nvl(xcf.site_key, this_site_key)))))
 
   UNION ALL
 
   SELECT proxyCopy_con_t       type_con,
          xal_key               key_con,
          xal_recid             recid_con,
          xal_stamp             stamp_con,
          to_number(null)       setStamp_con,
          to_number(null)       setCount_con,
          to_number(null)       bsRecid_con,
          to_number(null)       bsStamp_con,
          to_number(null)       bsKey_con,
          to_number(null)       bsLevel_con,
          to_char(null)         bsType_con,
          to_number(null)       elapseSecs_con,
          to_number(null)       pieceCount_con,
          handle                fileName_con,
          tag                   tag_con,
          to_number(null)       copyNumber_con,
          xal.status            status_con,
          xal.blocks            blocks_con,
          xal.block_size        blockSize_con,
          xal.device_type       deviceType_con,
          xal.completion_time   compTime_con,
          to_date(null)         cfCreationTime_con,
          to_number(null)       pieceNumber_con,
          to_date(null)         bpCompTime_con,
          to_char(null)         bpCompressed_con,
          to_char(null)         multi_section_con,
 
          redo_act_t            type_act,
          0                     fromSCN_act,
          to_number(null)       toSCN_act,
          to_date(null)         toTime_act,
          to_number(null)       rlgSCN_act,
          to_date(null)         rlgTime_act,
          dbinc.dbinc_key       dbincKey_act,
          to_number(null)       level_act,
          0                     section_size_act,
 
          to_number(null)       dfNumber_obj,
          to_number(null)       dfCreationSCN_obj,
          to_number(null)       cfSequence_obj,
          to_date(null)         cfDate_obj,
          xal.sequence#         logSequence_obj,
          xal.thread#           logThread_obj,
          dbinc.reset_scn       logRlgSCN_obj,
          dbinc.reset_time      logRlgTime_obj,
          xal.low_scn           logLowSCN_obj,
          xal.low_time          logLowTime_obj,
          xal.next_scn          logNextSCN_obj,
          xal.next_time         logNextTime_obj,
          xal.terminal          logTerminal_obj,
          to_char(null)         cfType_obj,
          to_number(null)       pdbKey_obj,
 
          to_number(null)       keep_options,
          to_date(null)         keep_until,
 
          to_number(null)       afzSCN_act,
          to_date(null)         rfzTime_act,
          to_number(null)       rfzSCN_act,
          media                 media_con,
          'NO'                  isrdf_con,
          site_key              site_key_con,
          0                     foreignDbid_obj,
          0                     pluggedRonly_obj,
          0                     pluginSCN_obj,
          0                     pluginRlgSCN_obj,
          to_date(null)         pluginRlgTime_obj,
 
          to_number(null)       newDfCreationSCN_obj,
          to_number(null)       newToSCN_act,
          to_number(null)       newRlgSCN_act,
          to_date(null)         newRlgTime_act,
          to_char(null)         sfDbUniqueName_obj,
          to_char(null)         sparse_backup_con,
          0                     ppl_pdb_id_con,
          0                     ppl_cdb_dbid_con
      FROM xal, dbinc
    WHERE db_key = this_db_key                  -- belongs to this database
      AND dbinc.dbinc_key = xal.dbinc_key       -- join dbinc and xal
      AND (findProxyCopyKey.key = xal_key)
      AND (findProxyCopyKey.deviceType IS NULL OR
           findProxyCopyKey.deviceType = device_type)
      AND ((user_site_key  = xal.site_key) OR
           (user_site_key IS NULL AND
            ((tape_backups_shared = TRUE#) OR
             (this_site_key = nvl(xal.site_key, this_site_key)))))
      AND decode(statusMask, BSavailable,
                 decode(status, 'A', TRUE#, FALSE#),
                 isStatusMatch(status, statusMask)) = TRUE#;
 
 
--
--
--
--
--
--
--
--
--
 
CURSOR findArchivedLogCopy(
   currentIncarnation   IN     number
  ,thread               IN     number
  ,sequence             IN     number
  ,lowSCN               IN     number
  ,pattern              IN     varchar2       DEFAULT NULL
  ,completedAfter       IN     date           DEFAULT NULL
  ,completedBefore      IN     date           DEFAULT NULL
  ,statusMask           IN     binary_integer
  ,needstby             IN     number         DEFAULT NULL)
RETURN rcvRec_t IS
--
   SELECT imageCopy_con_t       type_con,
          al_key                key_con,
          recid                 recid_con,
          stamp                 stamp_con,
          to_number(null)       setStamp_con,
          to_number(null)       setCount_con,
          to_number(null)       bsRecid_con,
          to_number(null)       bsStamp_con,
          to_number(null)       bsKey_con,
          to_number(null)       bsLevel_con,
          to_char(null)         bsType_con,
          to_number(null)       elapseSecs_con,
          to_number(null)       pieceCount_con,
          name                  fileName_con,
          to_date(null)         tag_con,
          to_number(null)       copyNumber_con,
          status                status_con,
          blocks                blocks_con,
          block_size            blockSize_con,
          'DISK'                deviceType_con,
          completion_time       compTime_con,
          to_date(null)         cfCreationTime_con,
          to_number(null)       pieceNumber_con,
          to_date(null)         bpCompTime_con,
          to_char(null)         bpCompressed_con,
          to_char(null)         multi_section_con,
 
          full_act_t            type_act,
          to_number(null)       fromSCN_act,
          to_number(null)       toSCN_act,
          to_date(null)         toTime_act,
          to_number(null)       rlgSCN_act,
          to_date(null)         rlgTime_act,
          dbinc_key             dbincKey_act,
          to_number(null)       level_act,
          0                     section_size_act,
 
          to_number(null)       dfNumber_obj,
          to_number(null)       dfCreationSCN_obj,
          to_number(null)       cfSequence_obj,
          to_date(null)         cfDate_obj,
          sequence#             logSequence_obj,
          thread#               logThread_obj,
          resetlogs_change#     logRlgSCN_obj,
          resetlogs_time        logRlgTime_obj,
          first_change#         logLowSCN_obj,
          first_time            logLowTime_obj,
          next_change#          logNextSCN_obj,
          next_time             logNextTime_obj,
          terminal              logTerminal_obj,
          to_char(null)         cfType_obj,
          to_number(null)       pdbKey_obj,
 
          to_number(null)       keep_options,
          to_date(null)         keep_until,
 
          to_number(null)       afzSCN_act,
          to_date(null)         rfzTime_act,
          to_number(null)       rfzSCN_act,
          to_char(null)         media_con,
          is_recovery_dest_file isrdf_con,
          site_key              site_key_con,
          0                     foreignDbid_obj,
          0                     pluggedRonly_obj,
          0                     pluginSCN_obj,
          0                     pluginRlgSCN_obj,
          to_date(null)         pluginRlgTime_obj,
 
          to_number(null)       newDfCreationSCN_obj,
          to_number(null)       newToSCN_act,
          to_number(null)       newRlgSCN_act,
          to_date(null)         newRlgTime_act,
          to_char(null)         sfDbUniqueName_obj,
          to_char(null)         sparse_backup_con,
          0                     ppl_pdb_id_con,
          0                     ppl_cdb_dbid_con
     FROM rc_archived_log
    WHERE db_key = this_db_key                    -- belongs to this database
      AND(findArchivedLogCopy.currentIncarnation = FALSE# OR
           canApplyAnyRedo = TRUE# OR
           this_dbinc_key = dbinc_key)
      AND (thread IS NULL OR thread# = thread)
      AND (sequence IS NULL OR sequence# = sequence)
      AND (lowSCN IS NULL OR first_change# = lowSCN)
--
--
--
--
      AND (pattern IS NULL OR name LIKE pattern)
      AND (completedAfter IS NULL OR completion_time >= completedAfter)
      AND (completedBefore IS NULL OR completion_time <= completedBefore)
      AND decode(statusMask, BSavailable,
                 decode(status, 'A', TRUE#, FALSE#),
                 isStatusMatch(status, statusMask)) = TRUE#
      AND ((client_site_aware = TRUE# AND
            ((user_site_key = site_key) OR -- interested in specific site
             (user_site_key IS NULL AND
              ((logs_shared = TRUE#) OR
               (this_site_key = nvl(site_key, this_site_key)))))) OR
           (client_site_aware = FALSE# AND
            (needstby is NULL OR
             nvl(is_standby, 'NO') = decode(needstby, TRUE#, 'YES', 'NO') OR
             (terminal = 'YES') OR
             (first_change# >= lbacked_al_next_scn AND
              first_change# <= standby_became_primary_scn))))
--
--
      AND (archived = 'YES')
      AND (tc_thread IS NULL   OR thread# = tc_thread)
      AND (tc_fromSeq IS NULL  OR sequence# >= tc_fromSeq)
      AND (tc_toSeq IS NULL    OR sequence# <= tc_toSeq)
      AND (tc_fromSCN IS NULL  OR next_change# > tc_fromSCN)
      AND (tc_toSCN IS NULL    OR first_change# < tc_toSCN)
      AND (tc_pattern IS NULL  OR name like tc_pattern)
      AND (tc_fromTime IS NULL OR next_time > tc_fromTime)
      AND (tc_toTime IS NULL   OR first_time <= tc_toTime)
    ORDER BY resetlogs_change#, resetlogs_time, thread#, sequence#,
             terminal desc, stamp_con desc;
 
CURSOR findArcLogBackup(
   sourcemask           IN     number
  ,currentIncarnation   IN     number         DEFAULT TRUE#
  ,thread               IN     number
  ,sequence             IN     number
  ,lowSCN               IN     number
  ,tag                  IN     varchar2       DEFAULT NULL
  ,pattern              IN     varchar2       DEFAULT NULL
  ,completedAfter       IN     date           DEFAULT NULL
  ,completedBefore      IN     date           DEFAULT NULL
  ,statusMask           IN     binary_integer DEFAULT BSavailable)
RETURN rcvRec_t IS
   SELECT backupSet_con_t       type_con,
          brl.brl_key           key_con,
          brl.brl_recid         recid_con,
          brl.brl_stamp         stamp_con,
          bs.set_stamp          setStamp_con,
          bs.set_count          setCount_con,
          bs.bs_recid           bsRecid_con,
          bs.bs_stamp           bsStamp_con,
          bs.bs_key             bsKey_con,
          to_number(null)       bsLevel_con,
          bs.bck_type           bsType_con,
          abs((bs.completion_time - bs.start_time) * 86400)
                                elapseSecs_con,
          bs.pieces             pieceCount_con,
          to_char(null)         fileName_con,
          to_char(null)         tag_con,
          to_number(null)       copyNumber_con,
          to_char(null)         status_con,
          brl.blocks            blocks_con,
          brl.block_size        blockSize_con,
          to_char(null)         deviceType_con,
          bs.completion_time    compTime_con,
          to_date(null)         cfCreationTime_con,
          to_number(null)       pieceNumber_con,
          to_date(null)         bpCompTime_con,
          to_char(null)         bpCompressed_con,
          multi_section         multi_section_con,
 
          full_act_t            type_act,
          to_number(null)       fromSCN_act,
          to_number(null)       toSCN_act,
          to_date(null)         toTime_act,
          to_number(null)       rlgSCN_act,
          to_date(null)         rlgTime_act,
          dbinc.dbinc_key       dbincKey_act,
          to_number(null)       level_act,
          0                     section_size_act,
 
          to_number(null)       dfNumber_obj,
          to_number(null)       dfCreationSCN_obj,
          to_number(null)       cfSequence_obj,
          to_date(null)         cfDate_obj,
          brl.sequence#         logSequence_obj,
          brl.thread#           logThread_obj,
          dbinc.reset_scn       logRlgSCN_obj,
          dbinc.reset_time      logRlgTime_obj,
          brl.low_scn           logLowSCN_obj,
          brl.low_time          logLowTime_obj,
          brl.next_scn          logNextSCN_obj,
          brl.next_time         logNextTime_obj,
          brl.terminal          logTerminal_obj,
          to_char(null)         cfType_obj,
          to_number(null)       pdbKey_obj,
 
          to_number(null)       keep_options,
          to_date(null)         keep_until,
 
          to_number(null)       afzSCN_act,
          to_date(null)         rfzTime_act,
          to_number(null)       rfzSCN_act,
          to_char(null)         media_con,
          'NO'                  isrdf_con,
          bs.site_key           site_key_con,
          0                     foreignDbid_obj,
          0                     pluggedRonly_obj,
          0                     pluginSCN_obj,
          0                     pluginRlgSCN_obj,
          to_date(null)         pluginRlgTime_obj,
 
          to_number(null)       newDfCreationSCN_obj,
          to_number(null)       newToSCN_act,
          to_number(null)       newRlgSCN_act,
          to_date(null)         newRlgTime_act,
          to_char(null)         sfDbUniqueName_obj,
          to_char(null)         sparse_backup_con,
          0                     ppl_pdb_id_con,
          0                     ppl_cdb_dbid_con
     FROM brl, bs, dbinc
    WHERE (sourcemask is NULL OR bitand(sourcemask, backupSet_con_t) != 0)
      AND  dbinc.db_key = this_db_key             -- belongs to this database
      AND (currentIncarnation = FALSE# OR
           canApplyAnyRedo = TRUE# OR
           this_dbinc_key = dbinc.dbinc_key)
      AND (thread IS NULL OR brl.thread# = thread)
      AND (sequence IS NULL OR brl.sequence# = sequence)
      AND (lowSCN IS NULL OR brl.low_scn = lowSCN)
      AND dbinc.dbinc_key = brl.dbinc_key      -- join dbinc, brl
      AND bs.bs_key       = brl.bs_key         -- join bs, brl
      AND bs.bck_type     = 'L'                -- only archivelog backups
--
--
      AND (completedAfter  IS NULL OR bs.completion_time >= completedAfter)
      AND (completedBefore IS NULL OR bs.completion_time <= completedBefore)
      AND (tc_thread IS NULL       OR brl.thread# = tc_thread)
      AND (tc_fromSeq IS NULL      OR brl.sequence# >= tc_fromSeq)
      AND (tc_toSeq IS NULL        OR brl.sequence# <= tc_toSeq)
      AND (tc_fromSCN IS NULL      OR brl.next_scn > tc_fromSCN)
      AND (tc_toSCN IS NULL        OR brl.low_scn < tc_toSCN)
      AND (tc_fromTime IS NULL     OR brl.next_time > tc_fromTime)
      AND (tc_toTime IS NULL       OR brl.low_time <= tc_toTime)
      AND (bs.site_key IS NULL         OR -- always return null site_key
           user_site_key = bs.site_key OR -- user interested in one site
           (user_site_key IS NULL AND     -- return rows per access attr
            (disk_backups_shared = TRUE# OR
             tape_backups_shared = TRUE# OR
             this_site_key = bs.site_key)))
 
   UNION ALL
 
--
   SELECT proxyCopy_con_t       type_con,
          xal_key               key_con,
          xal_recid             recid_con,
          xal_stamp             stamp_con,
          to_number(null)       setStamp_con,
          to_number(null)       setCount_con,
          to_number(null)       bsRecid_con,
          to_number(null)       bsStamp_con,
          to_number(null)       bsKey_con,
          to_number(null)       bsLevel_con,
          to_char(null)         bsType_con,
          to_number(null)       elapseSecs_con,
          to_number(null)       pieceCount_con,
          handle                fileName_con,
          tag                   tag_con,
          to_number(null)       copyNumber_con,
          xal.status            status_con,
          xal.blocks            blocks_con,
          xal.block_size        blockSize_con,
          xal.device_type       deviceType_con,
          xal.completion_time   compTime_con,
          to_date(null)         cfCreationTime_con,
          to_number(null)       pieceNumber_con,
          to_date(null)         bpCompTime_con,
          to_char(null)         bpCompressed_con,
          to_char(null)         multi_section_con,
 
          redo_act_t            type_act,
          0                     fromSCN_act,
          to_number(null)       toSCN_act,
          to_date(null)         toTime_act,
          to_number(null)       rlgSCN_act,
          to_date(null)         rlgTime_act,
          dbinc.dbinc_key       dbincKey_act,
          to_number(null)       level_act,
          0                     section_size_act,
 
          to_number(null)       dfNumber_obj,
          to_number(null)       dfCreationSCN_obj,
          to_number(null)       cfSequence_obj,
          to_date(null)         cfDate_obj,
          xal.sequence#         logSequence_obj,
          xal.thread#           logThread_obj,
          dbinc.reset_scn       logRlgSCN_obj,
          dbinc.reset_time      logRlgTime_obj,
          xal.low_scn           logLowSCN_obj,
          xal.low_time          logLowTime_obj,
          xal.next_scn          logNextSCN_obj,
          xal.next_time         logNextTime_obj,
          xal.terminal          logTerminal_obj,
          to_char(null)         cfType_obj,
          to_number(null)       pdbKey_obj,
 
          xal.keep_options      keep_options,
          xal.keep_until        keep_until,
 
          to_number(null)       afzSCN_act,
          to_date(null)         rfzTime_act,
          to_number(null)       rfzSCN_act,
          media                 media_con,
          'NO'                  isrdf_con,
          site_key              site_key_con,
          0                     foreignDbid_obj,
          0                     pluggedRonly_obj,
          0                     pluginSCN_obj,
          0                     pluginRlgSCN_obj,
          to_date(null)         pluginRlgTime_obj,
 
          to_number(null)       newDfCreationSCN_obj,
          to_number(null)       newToSCN_act,
          to_number(null)       newRlgSCN_act,
          to_date(null)         newRlgTime_act,
          to_char(null)         sfDbUniqueName_obj,
          to_char(null)         sparse_backup_con,
          0                     ppl_pdb_id_con,
          0                     ppl_cdb_dbid_con
      FROM xal, dbinc
    WHERE (sourcemask is NULL OR bitand(sourcemask, proxyCopy_con_t) != 0)
      AND  dbinc.db_key = this_db_key             -- belongs to this database
      AND (currentIncarnation = FALSE# OR
           canApplyAnyRedo = TRUE# OR
           this_dbinc_key = dbinc.dbinc_key)
      AND (thread IS NULL OR xal.thread# = thread)
      AND (sequence IS NULL OR xal.sequence# = sequence)
      AND (lowSCN IS NULL OR xal.low_scn = lowSCN)
      AND dbinc.dbinc_key = xal.dbinc_key      -- join dbinc, xal
      AND decode(statusMask, BSavailable,
                 decode(xal.status, 'A', TRUE#, FALSE#),
                 isStatusMatch(xal.status, statusMask)) = TRUE#
      AND (findArcLogBackup.tag is NULL OR
           tag = findArcLogBackup.tag)
      AND (findArcLogBackup.pattern IS NULL OR
           xal.handle LIKE findArcLogBackup.pattern)
      AND (completedAfter  IS NULL OR xal.completion_time >= completedAfter)
      AND (completedBefore IS NULL OR xal.completion_time <= completedBefore)
      AND (tc_thread IS NULL       OR xal.thread# = tc_thread)
      AND (tc_fromSeq IS NULL      OR xal.sequence# >= tc_fromSeq)
      AND (tc_toSeq IS NULL        OR xal.sequence# <= tc_toSeq)
      AND (tc_fromSCN IS NULL      OR xal.next_scn > tc_fromSCN)
      AND (tc_toSCN IS NULL        OR xal.low_scn < tc_toSCN)
      AND (tc_fromTime IS NULL     OR xal.next_time > tc_fromTime)
      AND (tc_toTime IS NULL       OR xal.low_time <= tc_toTime)
      AND ((user_site_key  = xal.site_key) OR
           (user_site_key IS NULL AND
            ((tape_backups_shared = TRUE#) OR
             (this_site_key = nvl(xal.site_key, this_site_key)))))
 
--
    ORDER BY logRlgSCN_obj,
             logRlgTime_obj,
             logThread_obj,
             logSequence_obj,
             logTerminal_obj desc,
             stamp_con desc;
 
--
--
--
CURSOR findRangeArcLogBackup(
   sourcemask           IN     number
  ,currentIncarnation   IN     number         DEFAULT TRUE#
  ,minthread            IN     number
  ,minsequence          IN     number
  ,minlowSCN            IN     number
  ,maxthread            IN     number
  ,maxsequence          IN     number
  ,maxlowSCN            IN     number
  ,tag                  IN     varchar2       DEFAULT NULL
  ,pattern              IN     varchar2       DEFAULT NULL
  ,completedAfter       IN     date           DEFAULT NULL
  ,completedBefore      IN     date           DEFAULT NULL
  ,statusMask           IN     binary_integer DEFAULT BSavailable)
RETURN rcvRec_t IS
   SELECT backupSet_con_t       type_con,
          brl.brl_key           key_con,
          brl.brl_recid         recid_con,
          brl.brl_stamp         stamp_con,
          bs.set_stamp          setStamp_con,
          bs.set_count          setCount_con,
          bs.bs_recid           bsRecid_con,
          bs.bs_stamp           bsStamp_con,
          bs.bs_key             bsKey_con,
          to_number(null)       bsLevel_con,
          bs.bck_type           bsType_con,
          abs((bs.completion_time - bs.start_time) * 86400)
                                elapseSecs_con,
          bs.pieces             pieceCount_con,
          to_char(null)         fileName_con,
          to_char(null)         tag_con,
          to_number(null)       copyNumber_con,
          to_char(null)         status_con,
          brl.blocks            blocks_con,
          brl.block_size        blockSize_con,
          to_char(null)         deviceType_con,
          bs.completion_time    compTime_con,
          to_date(null)         cfCreationTime_con,
          to_number(null)       pieceNumber_con,
          to_date(null)         bpCompTime_con,
          to_char(null)         bpCompressed_con,
          multi_section         multi_section_con,
 
          full_act_t            type_act,
          to_number(null)       fromSCN_act,
          to_number(null)       toSCN_act,
          to_date(null)         toTime_act,
          to_number(null)       rlgSCN_act,
          to_date(null)         rlgTime_act,
          dbinc.dbinc_key       dbincKey_act,
          to_number(null)       level_act,
          0                     section_size_act,
 
          to_number(null)       dfNumber_obj,
          to_number(null)       dfCreationSCN_obj,
          to_number(null)       cfSequence_obj,
          to_date(null)         cfDate_obj,
          brl.sequence#         logSequence_obj,
          brl.thread#           logThread_obj,
          dbinc.reset_scn       logRlgSCN_obj,
          dbinc.reset_time      logRlgTime_obj,
          brl.low_scn           logLowSCN_obj,
          brl.low_time          logLowTime_obj,
          brl.next_scn          logNextSCN_obj,
          brl.next_time         logNextTime_obj,
          brl.terminal          logTerminal_obj,
          to_char(null)         cfType_obj,
          to_number(null)       pdbKey_obj,
 
          to_number(null)       keep_options,
          to_date(null)         keep_until,
 
          to_number(null)       afzSCN_act,
          to_date(null)         rfzTime_act,
          to_number(null)       rfzSCN_act,
          to_char(null)         media_con,
          'NO'                  isrdf_con,
          bs.site_key           site_key_con,
          0                     foreignDbid_obj,
          0                     pluggedRonly_obj,
          0                     pluginSCN_obj,
          0                     pluginRlgSCN_obj,
          to_date(null)         pluginRlgTime_obj,
 
          to_number(null)       newDfCreationSCN_obj,
          to_number(null)       newToSCN_act,
          to_number(null)       newRlgSCN_act,
          to_date(null)         newRlgTime_act,
          to_char(null)         sfDbUniqueName_obj,
          to_char(null)         sparse_backup_con,
          0                     ppl_pdb_id_con,
          0                     ppl_cdb_dbid_con
     FROM brl, bs, dbinc
    WHERE (sourcemask is NULL OR bitand(sourcemask, backupSet_con_t) != 0)
      AND  dbinc.db_key = this_db_key             -- belongs to this database
      AND (currentIncarnation = FALSE# OR
           canApplyAnyRedo = TRUE# OR
           this_dbinc_key = dbinc.dbinc_key)
      AND brl.thread# between minthread and maxthread
      AND brl.sequence# between minsequence and maxsequence
      AND brl.low_scn between minlowSCN and maxlowSCN
      AND dbinc.dbinc_key = brl.dbinc_key      -- join dbinc, brl
      AND bs.bs_key       = brl.bs_key         -- join bs, brl
      AND bs.bck_type     = 'L'                -- only archivelog backups
--
--
      AND (completedAfter  IS NULL OR bs.completion_time >= completedAfter)
      AND (completedBefore IS NULL OR bs.completion_time <= completedBefore)
      AND (bs.site_key IS NULL         OR -- always return null site_key
           user_site_key = bs.site_key OR -- user interested in one site
           (user_site_key IS NULL AND     -- return rows per access attr
            (disk_backups_shared = TRUE# OR
             tape_backups_shared = TRUE# OR
             this_site_key = bs.site_key)))
 
   UNION ALL
 
--
   SELECT proxyCopy_con_t       type_con,
          xal_key               key_con,
          xal_recid             recid_con,
          xal_stamp             stamp_con,
          to_number(null)       setStamp_con,
          to_number(null)       setCount_con,
          to_number(null)       bsRecid_con,
          to_number(null)       bsStamp_con,
          to_number(null)       bsKey_con,
          to_number(null)       bsLevel_con,
          to_char(null)         bsType_con,
          to_number(null)       elapseSecs_con,
          to_number(null)       pieceCount_con,
          handle                fileName_con,
          tag                   tag_con,
          to_number(null)       copyNumber_con,
          xal.status            status_con,
          xal.blocks            blocks_con,
          xal.block_size        blockSize_con,
          xal.device_type       deviceType_con,
          xal.completion_time   compTime_con,
          to_date(null)         cfCreationTime_con,
          to_number(null)       pieceNumber_con,
          to_date(null)         bpCompTime_con,
          to_char(null)         bpCompressed_con,
          to_char(null)         multi_section_con,
 
          redo_act_t            type_act,
          0                     fromSCN_act,
          to_number(null)       toSCN_act,
          to_date(null)         toTime_act,
          to_number(null)       rlgSCN_act,
          to_date(null)         rlgTime_act,
          dbinc.dbinc_key       dbincKey_act,
          to_number(null)       level_act,
          0                     section_size_act,
 
          to_number(null)       dfNumber_obj,
          to_number(null)       dfCreationSCN_obj,
          to_number(null)       cfSequence_obj,
          to_date(null)         cfDate_obj,
          xal.sequence#         logSequence_obj,
          xal.thread#           logThread_obj,
          dbinc.reset_scn       logRlgSCN_obj,
          dbinc.reset_time      logRlgTime_obj,
          xal.low_scn           logLowSCN_obj,
          xal.low_time          logLowTime_obj,
          xal.next_scn          logNextSCN_obj,
          xal.next_time         logNextTime_obj,
          xal.terminal          logTerminal_obj,
          to_char(null)         cfType_obj,
          to_number(null)       pdbKey_obj,
 
          to_number(null)       keep_options,
          to_date(null)         keep_until,
 
          to_number(null)       afzSCN_act,
          to_date(null)         rfzTime_act,
          to_number(null)       rfzSCN_act,
          media                 media_con,
          'NO'                  isrdf_con,
          site_key              site_key_con,
          0                     foreignDbid_obj,
          0                     pluggedRonly_obj,
          0                     pluginSCN_obj,
          0                     pluginRlgSCN_obj,
          to_date(null)         pluginRlgTime_obj,
 
          to_number(null)       newDfCreationSCN_obj,
          to_number(null)       newToSCN_act,
          to_number(null)       newRlgSCN_act,
          to_date(null)         newRlgTime_act,
          to_char(null)         sfDbUniqueName_obj,
          to_char(null)         sparse_backup_con,
          0                     ppl_pdb_id_con,
          0                     ppl_cdb_dbid_con
      FROM xal, dbinc
    WHERE (sourcemask is NULL OR bitand(sourcemask, proxyCopy_con_t) != 0)
      AND  dbinc.db_key = this_db_key             -- belongs to this database
      AND (currentIncarnation = FALSE# OR
           canApplyAnyRedo = TRUE# OR
           this_dbinc_key = dbinc.dbinc_key)
      AND xal.thread# between minthread and maxthread
      AND xal.sequence# between minsequence and maxsequence
      AND xal.low_scn between minlowSCN and maxlowSCN
      AND dbinc.dbinc_key = xal.dbinc_key      -- join dbinc, xal
      AND decode(statusMask, BSavailable,
                 decode(xal.status, 'A', TRUE#, FALSE#),
                 isStatusMatch(xal.status, statusMask)) = TRUE#
      AND (findRangeArcLogBackup.tag is NULL OR
           tag = findRangeArcLogBackup.tag)
      AND (findRangeArcLogBackup.pattern IS NULL OR
           xal.handle LIKE findRangeArcLogBackup.pattern)
      AND (completedAfter  IS NULL OR xal.completion_time >= completedAfter)
      AND (completedBefore IS NULL OR xal.completion_time <= completedBefore)
      AND ((user_site_key  = xal.site_key) OR
           (user_site_key IS NULL AND
            ((tape_backups_shared = TRUE#) OR
             (this_site_key = nvl(xal.site_key, this_site_key)))))
 
--
--
    ORDER BY logRlgSCN_obj desc,
             logRlgTime_obj desc,
             logLowSCN_obj desc,
             logTerminal_obj desc, -- records marked 'YES' must be first
             stamp_con desc;
 
CURSOR findAllBackupPiece(
   backupType           IN     binary_integer
  ,tag                  IN     varchar2
  ,statusMask           IN     binary_integer
  ,completedAfter       IN     date
  ,completedBefore      IN     date
  ,onlyrdf              IN     binary_integer)
RETURN rcvRec_t IS
   SELECT backupset_con_t       type_con,
          bp.bp_key             key_con,
          bp.bp_recid           recid_con,
          bp.bp_stamp           stamp_con,
          bs.set_stamp          setStamp_con,
          bs.set_count          setCount_con,
          bs.bs_recid           bsRecid_con,
          bs.bs_stamp           bsStamp_con,
          bs.bs_key             bsKey_con,
          bs.incr_level         bsLevel_con,
          bs.bck_type           bsType_con,
          abs((bs.completion_time - bs.start_time) * 86400)
                                elapseSecs_con,
          bs.pieces             pieceCount_con,
          bp.handle             fileName_con,
          bp.tag                tag_con,
          bp.copy#              copyNumber_con,
          bp.status             status_con,
          ceil(bp.bytes / bs.block_size)
                                blocks_con,
          bs.block_size         blockSize_con,
          bp.device_type        deviceType_con,
          bs.completion_time    compTime_con,
          to_date(null)         cfCreationTime_con,
          bp.piece#             pieceNumber_con,
          bp.completion_time    bpCompTime_con,
          bp.compressed         bpCompressed_con,
          multi_section         multi_section_con,
 
          to_number(null)       type_act,
          to_number(null)       fromSCN_act,
          to_number(null)       toSCN_act,
          to_date(null)         toTime_act,
          to_number(null)       rlgSCN_act,
          to_date(null)         rlgTime_act,
          to_number(null)       dbincKey_act,
          to_number(null)       level_act,
          0                     section_size_act,
 
          to_number(null)       dfNumber_obj,
          to_number(null)       dfCreationSCN_obj,
          to_number(null)       cfSequence_obj,
          to_date(null)         cfDate_obj,
          to_number(null)       logSequence_obj,
          to_number(null)       logThread_obj,
          to_number(null)       logRlgSCN_obj,
          to_date(null)         logRlgTime_obj,
          to_number(null)       logLowSCN_obj,
          to_date(null)         logLowTime_obj,
          to_number(null)       logNextSCN_obj,
          to_date(null)         logNextTime_obj,
          to_char(null)         logTerminal_obj,
          to_char(null)         cfType_obj,
          to_number(null)       pdbKey_obj,
 
          bs.keep_options       keep_options,
          bs.keep_until         keep_until,
 
          to_number(null)       afzSCN_act,
          to_date(null)         rfzTime_act,
          to_number(null)       rfzSCN_act,
          bp.media              media_con,
          is_recovery_dest_file isrdf_con,
          bs.site_key           site_key_con,
          0                     foreignDbid_obj,
          0                     pluggedRonly_obj,
          0                     pluginSCN_obj,
          0                     pluginRlgSCN_obj,
          to_date(null)         pluginRlgTime_obj,
 
          to_number(null)       newDfCreationSCN_obj,
          to_number(null)       newToSCN_act,
          to_number(null)       newRlgSCN_act,
          to_date(null)         newRlgTime_act,
          to_char(null)         sfDbUniqueName_obj,
          to_char(null)         sparse_backup_con,
          0                     ppl_pdb_id_con,
          0                     ppl_cdb_dbid_con
     FROM bp, bs
    WHERE (bp.bs_key = bs.bs_key)       -- join bp and bs
      AND (bs.db_key = this_db_key)     -- this database
      AND (bp.status != 'D')
      AND (completedAfter IS NULL OR bs.completion_time >= completedAfter)
      AND (completedBefore IS NULL OR bs.completion_time <= completedBefore)
      AND (findAllBackupPiece.tag IS NULL or bp.tag = findAllBackupPiece.tag)
      AND (anyDevice = TRUE# OR isDeviceTypeAllocated(bp.device_type) = TRUE#)
      AND decode(statusMask, BSavailable,
                 decode(bp.status, 'A', TRUE#, FALSE#),
                 isStatusMatch(bp.status, statusMask)) = TRUE#
      AND (findAllBackupPiece.backupType IS NULL OR
           isBackupTypeMatch(bs.bck_type, backupType) = TRUE#)
      AND (findAllBackupPiece.onlyrdf = 0 OR
           bp.is_recovery_dest_file = 'YES')
      AND ((user_site_key = bp.site_key) OR
           (user_site_key IS NULL AND
            ((disk_backups_shared = TRUE# AND bp.device_type = 'DISK') OR
             (tape_backups_shared = TRUE# AND bp.device_type <> 'DISK') OR
             (this_site_key = nvl(bp.site_key, this_site_key)))))
--
    ORDER BY bs.bs_key, bp.device_type, bp.tag, bp.copy#, bp.piece#;
 
--
--
--
 
getValidBackupSetLast   validBackupSetRec_t;
 
getValidBackupSetCursor varchar2(30);    -- to indicate what cursor was used
 
--
--
--
--
 
--
--
--
 
--
--
--
 
CURSOR findValidBackupSet_c(
   bsKey                   IN number
  ,pieceCount              IN number
  ,deviceType              IN varchar2 DEFAULT NULL
  ,tag                     IN varchar2 DEFAULT NULL
  ,mask                    IN binary_integer)
RETURN dbms_rcvman.validBackupSetRec_t IS
 
--
--
--
--
--
--
 
--
--
   SELECT device_type, tag,
          decode(ba_access, 'Replication', 3, 'Tape', 2, nvl2(vb_key, 1, 0)),
          copy#, 1
     FROM rc_backup_piece
    WHERE bs_key = findValidBackupSet_c.bsKey
      AND decode(mask, BSavailable,
                 decode(status, 'A', TRUE#, FALSE#),
                 isStatusMatch(status, mask)) = TRUE#
      AND (findValidBackupSet_c.tag IS NULL OR
           findValidBackupSet_c.tag = tag)
      AND (findValidBackupSet_c.deviceType IS NULL OR
           findValidBackupSet_c.deviceType = device_type)
      AND ((user_site_key = rc_backup_piece.site_key) OR
           (user_site_key IS NULL AND
            ((disk_backups_shared = TRUE# AND
              rc_backup_piece.device_type = 'DISK') OR
             (tape_backups_shared = TRUE# AND
              rc_backup_piece.device_type <> 'DISK') OR
             (this_site_key = nvl(rc_backup_piece.site_key, this_site_key)))))
      AND (localOrsSiteKey IS NULL OR 
           (restoreRangeDevTyp IN ('RA$DISK', 'RA$ANY') AND 
            rc_backup_piece.ba_access IN ('Disk', 'Local')) OR 
           (restoreRangeDevTyp IN ('RA$SBT', 'RA$ANY') AND 
            rc_backup_piece.ba_access IN ('Tape', 'Replication') AND 
            localOrsSiteKey = rc_backup_piece.site_key))
    GROUP BY device_type, tag, copy#
   HAVING ((bitand(mask, dbms_rcvman.BSpartial_avail) = 0 AND
            count(DISTINCT piece#) = findValidBackupSet_c.pieceCount) OR
           (bitand(mask, dbms_rcvman.BSpartial_avail) <> 0 AND
            count(DISTINCT piece#) <= findValidBackupSet_c.pieceCount))
 
    UNION ALL
 
--
--
--
   SELECT device_type, tag,
          decode(ba_access, 'Replication', 3, 'Tape', 2, nvl2(vb_key, 1, 0)),
          to_number(null), 2
     FROM rc_backup_piece
    WHERE bs_key = findValidBackupSet_c.bsKey
      AND decode(mask, BSavailable,
                 decode(status, 'A', TRUE#, FALSE#),
                 isStatusMatch(status, mask)) = TRUE#
      AND (findValidBackupSet_c.tag IS NULL OR
           findValidBackupSet_c.tag = tag)
      AND (findValidBackupSet_c.deviceType IS NULL OR
           findValidBackupSet_c.deviceType = device_type)
      AND ((user_site_key = rc_backup_piece.site_key) OR
           (user_site_key IS NULL AND
            ((disk_backups_shared = TRUE# AND
              rc_backup_piece.device_type = 'DISK') OR
             (tape_backups_shared = TRUE# AND
              rc_backup_piece.device_type <> 'DISK') OR
             (this_site_key = nvl(rc_backup_piece.site_key, this_site_key)))))
      AND (localOrsSiteKey IS NULL OR 
           (restoreRangeDevTyp IN ('RA$DISK', 'RA$ANY') AND 
            rc_backup_piece.ba_access IN ('Disk', 'Local')) OR 
           (restoreRangeDevTyp IN ('RA$SBT', 'RA$ANY') AND 
            rc_backup_piece.ba_access IN ('Tape', 'Replication') AND
            localOrsSiteKey = rc_backup_piece.site_key))
    GROUP BY device_type, tag
   HAVING ((bitand(mask, dbms_rcvman.BSpartial_avail) = 0 AND
            count(DISTINCT piece#) = findValidBackupSet_c.pieceCount) OR
           (bitand(mask, dbms_rcvman.BSpartial_avail) <> 0 AND
            count(DISTINCT piece#) <= findValidBackupSet_c.pieceCount))
 
    UNION ALL
 
--
--
--
--
--
--
--
   SELECT device_type, to_char(null),
          decode(ba_access, 'Replication', 3, 'Tape', 2, nvl2(vb_key, 1, 0)),
          to_number(null), 3
     FROM rc_backup_piece
    WHERE bs_key = findValidBackupSet_c.bsKey
      AND decode(mask, BSavailable,
                 decode(status, 'A', TRUE#, FALSE#),
                 isStatusMatch(status, mask)) = TRUE#
      AND (findValidBackupSet_c.tag IS NULL OR
           findValidBackupSet_c.tag = tag)
      AND (findValidBackupSet_c.deviceType IS NULL OR
           findValidBackupSet_c.deviceType = device_type)
      AND ((user_site_key = rc_backup_piece.site_key) OR
           (user_site_key IS NULL AND
            ((disk_backups_shared = TRUE# AND
              rc_backup_piece.device_type = 'DISK') OR
             (tape_backups_shared = TRUE# AND
              rc_backup_piece.device_type <> 'DISK') OR
             (this_site_key = nvl(rc_backup_piece.site_key, this_site_key)))))
      AND (localOrsSiteKey IS NULL OR 
           (restoreRangeDevTyp IN ('RA$DISK', 'RA$ANY') AND 
            rc_backup_piece.ba_access IN ('Disk', 'Local')) OR 
           (restoreRangeDevTyp IN ('RA$SBT', 'RA$ANY') AND 
            rc_backup_piece.ba_access IN ('Tape', 'Replication') AND
            localOrsSiteKey = rc_backup_piece.site_key))
    GROUP BY device_type
   HAVING ((bitand(mask, dbms_rcvman.BSpartial_avail) = 0 AND
            count(DISTINCT piece#) = findValidBackupSet_c.pieceCount) OR
           (bitand(mask, dbms_rcvman.BSpartial_avail) <> 0 AND
            count(DISTINCT piece#) <= findValidBackupSet_c.pieceCount))
    ORDER BY 1,2,3,4,5;
 
--
--
--
CURSOR findValidBackupSet1P_c(
   bsKey                   IN number
  ,pieceCount              IN number
  ,deviceType              IN varchar2 DEFAULT NULL
  ,tag                     IN varchar2 DEFAULT NULL
  ,mask                    IN binary_integer)
RETURN validBackupSetRec_t IS
 
--
--
--
--
--
--
--
--
--
   SELECT device_type, tag,
          decode(ba_access, 'Replication', 3, 'Tape', 2, nvl2(vb_key, 1, 0)),
          copy#, 1
      FROM rc_backup_piece
   WHERE bs_key = findValidBackupSet1P_c.bsKey
      AND decode(mask, BSavailable,
                 decode(status, 'A', TRUE#, FALSE#),
                 isStatusMatch(status, mask)) = TRUE#
      AND ((user_site_key = rc_backup_piece.site_key) OR
           (user_site_key IS NULL AND
            ((disk_backups_shared = TRUE# AND
              rc_backup_piece.device_type = 'DISK') OR
             (tape_backups_shared = TRUE# AND
              rc_backup_piece.device_type <> 'DISK') OR
             (this_site_key = nvl(rc_backup_piece.site_key, this_site_key)))))
      AND (findValidBackupSet1P_c.tag IS NULL OR
           findValidBackupSet1P_c.tag = tag)
      AND (findValidBackupSet1P_c.deviceType IS NULL OR
           findValidBackupSet1P_c.deviceType = device_type) ;
 
--
--
--
 
--
--
--
--
 
CURSOR findBackupPiece_c(
   tag          IN     varchar2 DEFAULT NULL
  ,handle       IN     varchar2 DEFAULT NULL
  ,deviceType   IN     varchar2 DEFAULT NULL
  ,copyNumber   IN     number   DEFAULT NULL
  ,statusMask   IN     binary_integer
  ,pdbKey       IN     number   DEFAULT NULL
  ,guid         IN     varchar2 DEFAULT NULL)
RETURN bpRec_t IS
   SELECT bp_recid,
          bp_stamp,
          bp_key,
          bp.bs_key,
          set_stamp,
          set_count,
          bs.bck_type,
          piece#,
          copy#,
          bp.status,
          bp.completion_time,
          handle,
          tag,
          device_type,
          media,
          bytes,
          compressed,
          bs.site_key,
          bp.vb_key,
          bp.ba_access am_access,
          bp.ba_access,
          0 ppl_pdb_id,
          0 ppl_cdb_dbid
     FROM bp, bs
    WHERE bp.db_key = this_db_key               -- belongs to this db
      AND bs.db_key = this_db_key               -- belongs to this db
      AND bp.bs_key = bs.bs_key                 -- join bp and bs
      AND bp.status != 'D'
      AND (findBackupPiece_c.tag IS NULL OR
           tag = findBackupPiece_c.tag)
      AND (findBackupPiece_c.handle IS NULL OR
           handle = findBackupPiece_c.handle)
      AND (findBackupPiece_c.deviceType IS NULL OR
           device_type = findBackupPiece_c.deviceType)
      AND (findBackupPiece_c.copyNumber IS NULL OR
           copy# = findBackupPiece_c.copyNumber)
      AND decode(statusMask, BSavailable,
                 decode(bp.status, 'A', TRUE#, FALSE#),
                 isStatusMatch(bp.status, statusMask)) = TRUE#
      AND ((user_site_key = bp.site_key) OR
           (user_site_key IS NULL AND
            ((disk_backups_shared = TRUE# AND bp.device_type = 'DISK') OR
             (tape_backups_shared = TRUE# AND bp.device_type <> 'DISK') OR
             (this_site_key = nvl(bp.site_key, this_site_key)))))
      AND (guid IS NULL OR pdbKey = bp.pdb_key)
--
--
    ORDER BY piece#, decode(ba_access, 'R', 3, 'T', 2, nvl2(vb_key, 1, 0)),
             copy# desc, bp_stamp desc;
 
CURSOR findBackupPieceBpKey(
   bpKey        IN     number
  ,tag          IN     varchar2 DEFAULT NULL
  ,handle       IN     varchar2 DEFAULT NULL
  ,deviceType   IN     varchar2 DEFAULT NULL
  ,copyNumber   IN     number   DEFAULT NULL
  ,statusMask   IN     binary_integer)
RETURN bpRec_t IS
   SELECT bp_recid,
          bp_stamp,
          bp_key,
          bp.bs_key,
          set_stamp,
          set_count,
          bs.bck_type,
          piece#,
          copy#,
          bp.status,
          bp.completion_time,
          handle,
          tag,
          device_type,
          media,
          bytes,
          compressed,
          bs.site_key,
          bp.vb_key,
          bp.ba_access am_access,
          bp.ba_access,
          0 ppl_pdb_id,
          0 ppl_cdb_dbid
     FROM bp, bs
    WHERE bp.db_key = this_db_key
      AND bs.db_key = this_db_key
      AND bp.status != 'D'
      AND bp.bs_key = bs.bs_key
      AND (bp_key = findBackupPieceBpKey.bpkey)
      AND (findBackupPieceBpKey.tag IS NULL OR
           tag = findBackupPieceBpKey.tag)
      AND (findBackupPieceBpKey.handle IS NULL OR
           handle = findBackupPieceBpKey.handle)
      AND (findBackupPieceBpKey.deviceType IS NULL OR
           device_type = findBackupPieceBpKey.deviceType)
      AND (findBackupPieceBpKey.copyNumber IS NULL OR
           copy# = findBackupPieceBpKey.copyNumber)
      AND decode(statusMask, BSavailable,
                 decode(bp.status, 'A', TRUE#, FALSE#),
                 isStatusMatch(bp.status, statusMask)) = TRUE#
      AND ((user_site_key = bp.site_key) OR
           (user_site_key IS NULL AND
            ((disk_backups_shared = TRUE# AND bp.device_type = 'DISK') OR
             (tape_backups_shared = TRUE# AND bp.device_type <> 'DISK') OR
             (this_site_key = nvl(bp.site_key, this_site_key)))))
--
--
    ORDER BY piece#, decode(ba_access, 'R', 3, 'T', 2, nvl2(vb_key, 1, 0)),
             copy# desc, bp_stamp desc;
 
CURSOR findBackupPieceBsKey1(
   bsKey        IN     number
  ,tag          IN     varchar2 DEFAULT NULL
  ,handle       IN     varchar2 DEFAULT NULL
  ,deviceType   IN     varchar2 DEFAULT NULL
  ,copyNumber   IN     number   DEFAULT NULL
  ,statusMask   IN     binary_integer)
RETURN bpRec_t IS
   SELECT bp_recid,
          bp_stamp,
          bp_key,
          bp.bs_key,
          set_stamp,
          set_count,
          bs.bck_type,
          piece#,
          copy#,
          bp.status,
          bp.completion_time,
          handle,
          tag,
          device_type,
          media,
          bytes,
          compressed,
          bs.site_key,
          bp.vb_key,
          bp.ba_access am_access,
          bp.ba_access,
          0 ppl_pdb_id,
          0 ppl_cdb_dbid
     FROM bp, bs
    WHERE bp.db_key = this_db_key
      AND bs.db_key = this_db_key
      AND bp.status != 'D'
      AND bp.bs_key = bs.bs_key
      AND (bs.bs_key = findBackupPieceBsKey1.bsKey)
      AND (findBackupPieceBsKey1.tag IS NULL OR
           tag = findBackupPieceBsKey1.tag)
      AND (findBackupPieceBsKey1.handle IS NULL OR
           handle = findBackupPieceBsKey1.handle)
      AND (findBackupPieceBsKey1.deviceType IS NULL OR
           device_type = findBackupPieceBsKey1.deviceType)
      AND (findBackupPieceBsKey1.copyNumber IS NULL OR
           copy# = findBackupPieceBsKey1.copyNumber)
      AND decode(statusMask, BSavailable,
                 decode(bp.status, 'A', TRUE#, FALSE#),
                 isStatusMatch(bp.status, statusMask)) = TRUE#
      AND ((user_site_key = bp.site_key) OR
           (user_site_key IS NULL AND
            ((disk_backups_shared = TRUE# AND bp.device_type = 'DISK') OR
             (tape_backups_shared = TRUE# AND bp.device_type <> 'DISK') OR
             (this_site_key = nvl(bp.site_key, this_site_key)))))
--
--
    ORDER BY piece#, decode(ba_access, 'R', 3, 'T', 2, nvl2(vb_key, 1, 0)),
             copy# desc, bp_stamp desc;
 
CURSOR findBackupPieceBsKey2(
   startBsKey     IN      number
  ,tag            IN      varchar2
  ,statusMask     IN      binary_integer)
RETURN bpRec_t IS
   SELECT bp_recid,
          bp_stamp,
          bp_key,
          bp.bs_key,
          set_stamp,
          set_count,
          bs.bck_type,
          piece#,
          copy#,
          bp.status,
          bp.completion_time,
          handle,
          tag,
          device_type,
          media,
          bytes,
          compressed,
          bs.site_key,
          bp.vb_key,
          bp.ba_access am_access,
          bp.ba_access,
          0 ppl_pdb_id,
          0 ppl_cdb_dbid
     FROM bp, bs
    WHERE bp.db_key = this_db_key
      AND bs.db_key = this_db_key
      AND bp.status != 'D'
      AND bp.bs_key = bs.bs_key
      AND (bs.bs_key >= startBsKey)
      AND (findBackupPieceBsKey2.tag IS NULL OR
           bp.tag = findBackupPieceBsKey2.tag)
      AND decode(statusMask, BSavailable,
                 decode(bp.status, 'A', TRUE#, FALSE#),
                 isStatusMatch(bp.status, statusMask)) = TRUE#
      AND ((user_site_key = bp.site_key) OR
           (user_site_key IS NULL AND
            ((disk_backups_shared = TRUE# AND bp.device_type = 'DISK') OR
             (tape_backups_shared = TRUE# AND bp.device_type <> 'DISK') OR
             (this_site_key = nvl(bp.site_key, this_site_key)))))
--
--
    ORDER BY bs.bs_key, device_type,
             piece#, decode(ba_access, 'R', 3, 'T', 2, nvl2(vb_key, 1, 0)),
             copy# desc, bp_stamp desc;
 
--
--
--
 
TYPE noRows_t IS RECORD
(
   error        number,                 -- error number
   msg          varchar2(100)           -- error msg
);
 
--
--
TYPE tablespace_t IS RECORD
(
   name   rc_tablespace.name%TYPE, -- tablespace name
   pdbId  number                   -- pdb id
);
TYPE tablespaceList_t IS TABLE OF tablespace_t INDEX BY BINARY_INTEGER;
skipTablespaceList    tablespaceList_t;
 
--
--
TYPE pdbNameList_t is table of pdbNameRec_t index by rc_pdbs.name%TYPE;
pdbNameList           pdbNameList_t;
pdbGuidList           pdbNameList_t;
 
--
TYPE pdbId2NameList_t is table of rc_pdbs.name%TYPE index by binary_integer;
pdbId2NameList        pdbId2NameList_t;
 
--
--
TYPE pdbIdList_t is table of boolean index by binary_integer;
pdbIdList             pdbIdList_t;
 
--
TYPE pdbFileList_t is table of pdbFileRec_t index by binary_integer;
pdbFileList           pdbFileList_t;
 
--
--
--
 
getDatafileCursor varchar2(30);         -- pointer to current cursor
getDatafileNoRows noRows_t;             -- Set by function that opens cursor
getDatafileLast   dfRec_t;              -- The last row returned
 
--
--
--
--
--
--
--
--
CURSOR translateDatabase_c(
   fromSCN number,
   toSCN   number)
RETURN dfRec_t IS
   SELECT rcd.file#, rcd.creation_change#, creation_time,
          name, tablespace_name, ts#,
          null, blocks, block_size, bytes / 1024,
          null, stop_change#, read_only, rfile#,
          decode(included_in_database_backup, 'YES', 1, 0),
          aux_name,
          rcd.dbinc_key,
          offr.offline_scn, offr.online_scn, offr.online_time,
          decode(encrypt_in_backup, 'ON', 1, 'OFF',2, 3) encrypt,
--
          rcd.foreign_dbid,
          decode(rcd.plugged_readonly, 'YES', 1, 0),
          rcd.plugin_change#,
          rcd.plugin_resetlogs_change#,
          rcd.plugin_resetlogs_time,
          to_number(null) newDfCreationSCN,
          creation_thread,
          creation_size,
          con_id pdbId,
          pdb_key pdbKey,
          pdb_name pdbName,
          pdb_closed pdbClosed,
          rcd.pdb_foreign_dbid pdbForeignDbid,
          rcd.pdb_foreign_ckp_scn pdbForeignCkpScn,
          decode(rcd.pdb_nobackup, 'Y', 1, 0) noBackupPdb,
          rcd.pdb_foreign_afn pdbForeignAfn
     FROM rci_datafile_this_dbinc rcd, offr
    WHERE db_key = this_db_key AND                  -- belongs to this database
          rcd.dbinc_key = this_dbinc_key AND
          (this_stdby_controlfile_scn is NULL OR 
           decode(rcd.plugin_change#, 0, rcd.creation_change#, 
                  rcd.plugin_change#) <= this_stdby_controlfile_scn) AND
          offr.file#(+) = rcd.file# AND         -- outer join with offr
          offr.create_scn(+) = creation_change# AND
          offr.dbinc_key(+) = this_dbinc_key AND
          offr.offr_stamp(+) = 0 AND          -- only offline ranges from kccfe
          decode(rcd.plugin_change#, 0, rcd.creation_change#,
                 rcd.plugin_change#) <= toSCN AND
          (drop_change# is null OR drop_change# > fromSCN) AND
          (canHandleTransportableTbs = TRUE# OR
           rcd.plugged_readonly = 'NO') AND
--
--
          (nvl(realf_site_key, translation_site_key) = site_key)
    ORDER BY rcd.file#;
 
CURSOR translateDatabaseOfPdbId_c(
   fromSCN number,
   toSCN   number,
   pdbId   number)
RETURN dfRec_t IS
   SELECT rcd.file#, rcd.creation_change#, creation_time,
          name, tablespace_name, ts#,
          null, blocks, block_size, bytes / 1024,
          null, stop_change#, read_only, rfile#,
          decode(included_in_database_backup, 'YES', 1, 0),
          aux_name,
          rcd.dbinc_key,
          offr.offline_scn, offr.online_scn, offr.online_time,
          decode(encrypt_in_backup, 'ON', 1, 'OFF',2, 3) encrypt,
--
          rcd.foreign_dbid,
          decode(rcd.plugged_readonly, 'YES', 1, 0),
          rcd.plugin_change#,
          rcd.plugin_resetlogs_change#,
          rcd.plugin_resetlogs_time,
          to_number(null) newDfCreationSCN,
          creation_thread,
          creation_size,
          con_id pdbId,
          pdb_key pdbKey,
          pdb_name pdbName,
          pdb_closed pdbClosed,
          rcd.pdb_foreign_dbid pdbForeignDbid,
          rcd.pdb_foreign_ckp_scn pdbForeignCkpScn,
          decode(rcd.pdb_nobackup, 'Y', 1, 0) noBackupPdb,
          rcd.pdb_foreign_afn pdbForeignAfn
     FROM rci_datafile_this_dbinc rcd, offr
    WHERE db_key = this_db_key AND                  -- belongs to this database
          rcd.dbinc_key = this_dbinc_key AND
          (this_stdby_controlfile_scn is NULL OR 
           decode(rcd.plugin_change#, 0, rcd.creation_change#, 
                  rcd.plugin_change#) <= this_stdby_controlfile_scn) AND
          offr.file#(+) = rcd.file# AND         -- outer join with offr
          offr.create_scn(+) = creation_change# AND
          offr.dbinc_key(+) = this_dbinc_key AND
          offr.offr_stamp(+) = 0 AND          -- only offline ranges from kccfe
          decode(rcd.plugin_change#, 0, rcd.creation_change#,
                 rcd.plugin_change#) <= toSCN AND
          (drop_change# is null OR drop_change# > fromSCN) AND
          (canHandleTransportableTbs = TRUE# OR
           rcd.plugged_readonly = 'NO') AND
--
--
          (nvl(realf_site_key, translation_site_key) = site_key) AND
          con_id = translateDatabaseOfPdbId_c.pdbId
    ORDER BY rcd.file#;
 
CURSOR translateDatabaseOfPdbIdL_c(
   fromSCN number,
   toSCN   number)
RETURN dfRec_t IS
   SELECT rcd.file#, rcd.creation_change#, creation_time,
          name, tablespace_name, ts#,
          null, blocks, block_size, bytes / 1024,
          null, stop_change#, read_only, rfile#,
          decode(included_in_database_backup, 'YES', 1, 0),
          aux_name,
          rcd.dbinc_key,
          offr.offline_scn, offr.online_scn, offr.online_time,
          decode(encrypt_in_backup, 'ON', 1, 'OFF',2, 3) encrypt,
--
          rcd.foreign_dbid,
          decode(rcd.plugged_readonly, 'YES', 1, 0),
          rcd.plugin_change#,
          rcd.plugin_resetlogs_change#,
          rcd.plugin_resetlogs_time,
          to_number(null) newDfCreationSCN,
          creation_thread,
          creation_size,
          con_id pdbId,
          pdb_key pdbKey,
          pdb_name pdbName,
          pdb_closed pdbClosed,
          rcd.pdb_foreign_dbid pdbForeignDbid,
          rcd.pdb_foreign_ckp_scn pdbForeignCkpScn,
          decode(rcd.pdb_nobackup, 'Y', 1, 0) noBackupPdb,
          rcd.pdb_foreign_afn pdbForeignAfn
     FROM rci_datafile_this_dbinc rcd, offr
    WHERE db_key = this_db_key AND                  -- belongs to this database
          rcd.dbinc_key = this_dbinc_key AND
          (this_stdby_controlfile_scn is NULL OR 
           decode(rcd.plugin_change#, 0, rcd.creation_change#, 
                  rcd.plugin_change#) <= this_stdby_controlfile_scn) AND
          offr.file#(+) = rcd.file# AND         -- outer join with offr
          offr.create_scn(+) = creation_change# AND
          offr.dbinc_key(+) = this_dbinc_key AND
          offr.offr_stamp(+) = 0 AND          -- only offline ranges from kccfe
          decode(rcd.plugin_change#, 0, rcd.creation_change#,
                 rcd.plugin_change#) <= toSCN AND
          (drop_change# is null OR drop_change# > fromSCN) AND
          (canHandleTransportableTbs = TRUE# OR
           rcd.plugged_readonly = 'NO') AND
--
--
          (nvl(realf_site_key, translation_site_key) = site_key) AND
          isTranslatedPdbId(con_id) = TRUE#
    ORDER BY rcd.file#;
 
--
--
CURSOR translateTablespace_c(
   tsName  varchar2
  ,pdbId   number)
RETURN dfRec_t IS
   SELECT file#, creation_change#, creation_time,
          name, tablespace_name, ts#,
          null, blocks, block_size, bytes / 1024,
          null, stop_change#, read_only, rfile#,
          decode(included_in_database_backup, 'YES', 1, 0),
          aux_name,
          dbinc_key,
          NULL, NULL, NULL,
          decode(encrypt_in_backup, 'ON', 1, 'OFF',2, 3) encrypt,
--
          rcd.foreign_dbid,
          decode(rcd.plugged_readonly, 'YES', 1, 0),
          rcd.plugin_change#,
          rcd.plugin_resetlogs_change#,
          rcd.plugin_resetlogs_time,
          to_number(null) newDfCreationSCN,
          creation_thread,
          creation_size,
          con_id pdbId,
          pdb_key pdbKey,
          pdb_name pdbName,
          pdb_closed pdbClosed,
          rcd.pdb_foreign_dbid pdbForeignDbid,
          rcd.pdb_foreign_ckp_scn pdbForeignCkpScn,
          decode(rcd.pdb_nobackup, 'Y', 1, 0) noBackupPdb,
          rcd.pdb_foreign_afn pdbForeignAfn
     FROM rci_datafile_this_dbinc rcd 
    WHERE db_key = this_db_key AND              -- part of this db
          tablespace_name = translateTablespace_c.tsName AND
          dbinc_key = this_dbinc_key AND
          (this_stdby_controlfile_scn is NULL OR 
           decode(rcd.plugin_change#, 0, rcd.creation_change#, 
                  rcd.plugin_change#) <= this_stdby_controlfile_scn) AND
          ((untilSCN is null AND drop_change# is null) OR
           ((decode(plugin_change#, 0, creation_change#,
                    plugin_change#) <= untilSCN) AND
            (drop_change# is null or drop_change# > untilSCN))) AND
          (nvl(realf_site_key, translation_site_key) = site_key) AND
          (canHandleTransportableTbs = TRUE# OR
           rcd.plugged_readonly = 'NO') AND
          con_id = translateTablespace_c.pdbId
    ORDER BY file#;
 
--
--
 
CURSOR translateDatafileName(
   fileName varchar2)
RETURN dfRec_t IS
   SELECT file#, creation_change#, creation_time,
          name, tablespace_name, ts#,
          null, blocks, block_size, bytes / 1024,
          null, stop_change#, read_only, rfile#,
          decode(included_in_database_backup, 'YES', 1, 0),
          aux_name,
          dbinc_key,
          NULL, NULL, NULL,
          decode(encrypt_in_backup, 'ON', 1, 'OFF',2, 3) encrypt,
--
          rcd.foreign_dbid,
          decode(rcd.plugged_readonly, 'YES', 1, 0),
          rcd.plugin_change#,
          rcd.plugin_resetlogs_change#,
          rcd.plugin_resetlogs_time,
          to_number(null) newDfCreationSCN,
          creation_thread,
          creation_size,
          con_id pdbId,
          pdb_key pdbKey,
          pdb_name pdbName,
          pdb_closed pdbClosed,
          rcd.pdb_foreign_dbid pdbForeignDbid,
          rcd.pdb_foreign_ckp_scn pdbForeignCkpScn,
          decode(rcd.pdb_nobackup, 'Y', 1, 0) noBackupPdb,
          rcd.pdb_foreign_afn pdbForeignAfn
     FROM rci_datafile_this_dbinc rcd 
    WHERE db_key = this_db_key AND              -- belongs to this database
          name = translateDatafilename.fileName AND -- filename matches
          dbinc_key = this_dbinc_key AND
          drop_change# is null AND      -- filename currently part of db
          (untilSCN is null OR
           decode(plugin_change#, 0, creation_change#,
                  plugin_change#) < untilSCN) AND
--
          ((untilSCN is null) OR         -- no until clause
           ((untilTime is not null) AND NOT EXISTS
            (SELECT 1
               FROM rci_datafile_this_dbinc 
              WHERE dbinc_key = this_dbinc_key AND
                    name = translateDatafilename.fileName AND
                    (plugin_change# != 0 OR
                     nvl(creation_time, MINDATEVAL) < untilTime) AND
                    drop_time > untilTime AND
                    (nvl(realf_site_key, translation_site_key) = site_key))) OR
           ((untilSCN is not null) AND NOT EXISTS
            (SELECT 1
               FROM rci_datafile_this_dbinc
              WHERE dbinc_key = this_dbinc_key AND
                    name = translateDatafilename.fileName AND
                    decode(plugin_change#, 0, creation_change#,
                           plugin_change#) < untilSCN AND
                    drop_change# > untilSCN AND
                    (nvl(realf_site_key, translation_site_key)=site_key)))) AND
          (canHandleTransportableTbs = TRUE# OR plugged_readonly = 'NO');
 
--
--
 
CURSOR translateDatafileNumber(
   fno  number)
RETURN dfRec_t IS
   SELECT file#, creation_change#, creation_time,
          name, tablespace_name, ts#,
          null, blocks, block_size, bytes / 1024,
          null, stop_change#, read_only, rfile#,
          decode(included_in_database_backup, 'YES', 1, 0),
          aux_name,
          dbinc_key,
          NULL, NULL, NULL,
          decode(encrypt_in_backup, 'ON', 1, 'OFF',2, 3) encrypt,
--
          rcd.foreign_dbid,
          decode(rcd.plugged_readonly, 'YES', 1, 0),
          rcd.plugin_change#,
          rcd.plugin_resetlogs_change#,
          rcd.plugin_resetlogs_time,
          to_number(null) newDfCreationSCN,
          creation_thread,
          creation_size,
          con_id pdbId,
          pdb_key pdbKey,
          pdb_name pdbName,
          pdb_closed pdbClosed,
          rcd.pdb_foreign_dbid pdbForeignDbid,
          rcd.pdb_foreign_ckp_scn pdbForeignCkpScn,
          decode(rcd.pdb_nobackup, 'Y', 1, 0) noBackupPdb,
          rcd.pdb_foreign_afn pdbForeignAfn
     FROM rci_datafile_this_dbinc rcd
    WHERE db_key = this_db_key AND              -- belongs to this database
          file# = translateDataFileNumber.fno AND       -- filenumber matches
          dbinc_key = this_dbinc_key AND
          ((untilSCN is null AND drop_change# is null) OR
           ((nvl(creation_time, MINDATEVAL) < untilTime OR
             decode(plugin_change#, 0, creation_change#,
                    plugin_change#) < untilSCN) AND
            (drop_time > untilTime OR
             drop_change# > untilSCN OR
             drop_change# is null))) AND
          (nvl(realf_site_key, translation_site_key) = site_key) AND
          (canHandleTransportableTbs = TRUE# OR plugged_readonly = 'NO');
 
--
--
 
CURSOR translateDatafileCheckpoint(
   fno          number
  ,ckpSCN       number)
RETURN dfRec_t IS
   SELECT file#, creation_change#, creation_time,
          name, tablespace_name, ts#,
          null, blocks, block_size, bytes / 1024,
          null, stop_change#, read_only, rfile#,
          decode(included_in_database_backup, 'YES', 1, 0),
          aux_name,
          dbinc_key,
          NULL, NULL, NULL,
          decode(encrypt_in_backup, 'ON', 1, 'OFF',2, 3) encrypt,
--
          rcd.foreign_dbid,
          decode(rcd.plugged_readonly, 'YES', 1, 0),
          rcd.plugin_change#,
          rcd.plugin_resetlogs_change#,
          rcd.plugin_resetlogs_time,
          to_number(null) newDfCreationSCN,
          creation_thread,
          creation_size,
          con_id pdbId,
          pdb_key pdbKey,
          pdb_name pdbName,
          pdb_closed pdbClosed,
          rcd.pdb_foreign_dbid pdbForeignDbid,
          rcd.pdb_foreign_ckp_scn pdbForeignCkpScn,
          decode(rcd.pdb_nobackup, 'Y', 1, 0) noBackupPdb,
          rcd.pdb_foreign_afn pdbForeignAfn
     FROM rci_datafile_this_dbinc rcd
    WHERE db_key = this_db_key                  -- belongs to this database
      AND file# = translateDatafileCheckpoint.fno       -- filenumber matches
      AND dbinc_key = this_dbinc_key
      AND translateDatafileCheckpoint.ckpSCN >=
          decode(plugin_change#, 0, creation_change#, plugin_change#)
      AND (drop_change# IS NULL OR
           translateDatafileCheckpoint.ckpSCN < drop_change#)
      AND (canHandleTransportableTbs = TRUE# OR plugged_readonly = 'NO')
      AND (nvl(realf_site_key, translation_site_key) = site_key);
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
CURSOR translateAllDf_c
RETURN dfRec_t IS
   SELECT DISTINCT
          file#                 dfNumber,
          creation_change#      dfCreationSCN,
          creation_time         dfCreationTime,
          name                  fileName,
          tablespace_name       tsName,
          ts#                   tsNumber,
          to_char(null)         status,
          blocks                blocks,
          block_size            blockSize,
          bytes / 1024          kbytes,
          to_number(null)       unrecovSCN,
          stop_change#          stopSCN,
          FALSE#                readOnly,
          rfile#                rfNumber,
          decode(included_in_database_backup, 'YES', 1, 0)
                                inBackup,
          aux_name              auxNAme,
          dbinc_key             dbincKey,
          NULL                  dfOfflineSCN,
          NULL                  dfOnlineSCN,
          NULL                  dfOnlineTime,
          decode(encrypt_in_backup, 'ON', 1, 'OFF',2, 3) encrypt,
--
          rcd.foreign_dbid,
          decode(rcd.plugged_readonly, 'YES', 1, 0),
          rcd.plugin_change#,
          rcd.plugin_resetlogs_change#,
          rcd.plugin_resetlogs_time,
          decode(rcd.plugin_change#, 0, rcd.creation_change#,
                 rcd.plugin_change#) newDfCreationSCN,
          creation_thread,
          creation_size,
          con_id pdbId,
          pdb_key pdbKey,
          pdb_name pdbName,
          pdb_closed pdbClosed,
          rcd.pdb_foreign_dbid pdbForeignDbid,
          rcd.pdb_foreign_ckp_scn pdbForeignCkpScn,
          decode(rcd.pdb_nobackup, 'Y', 1, 0) noBackupPdb,
          rcd.pdb_foreign_afn pdbForeignAfn
     FROM rci_datafile rcd
    WHERE db_key = this_db_key
      AND (canHandleTransportableTbs = TRUE# OR plugged_readonly = 'NO')
      AND (nvl(realf_site_key, translation_site_key) = site_key)
    ORDER BY file#, decode(dbinc_key, this_dbinc_key, 0, 1),
             newDfCreationSCN desc;
 
CURSOR translateAllDfOfPdbId_c(
   pdbId number)
RETURN dfRec_t IS
   SELECT DISTINCT
          file#                 dfNumber,
          creation_change#      dfCreationSCN,
          creation_time         dfCreationTime,
          name                  fileName,
          tablespace_name       tsName,
          ts#                   tsNumber,
          to_char(null)         status,
          blocks                blocks,
          block_size            blockSize,
          bytes / 1024          kbytes,
          to_number(null)       unrecovSCN,
          stop_change#          stopSCN,
          FALSE#                readOnly,
          rfile#                rfNumber,
          decode(included_in_database_backup, 'YES', 1, 0)
                                inBackup,
          aux_name              auxNAme,
          dbinc_key             dbincKey,
          NULL                  dfOfflineSCN,
          NULL                  dfOnlineSCN,
          NULL                  dfOnlineTime,
          decode(encrypt_in_backup, 'ON', 1, 'OFF',2, 3) encrypt,
--
          rcd.foreign_dbid,
          decode(rcd.plugged_readonly, 'YES', 1, 0),
          rcd.plugin_change#,
          rcd.plugin_resetlogs_change#,
          rcd.plugin_resetlogs_time,
          decode(rcd.plugin_change#, 0, rcd.creation_change#,
                 rcd.plugin_change#) newDfCreationSCN,
          creation_thread,
          creation_size,
          con_id pdbId,
          pdb_key pdbKey,
          pdb_name pdbName,
          pdb_closed pdbClosed,
          rcd.pdb_foreign_dbid pdbForeignDbid,
          rcd.pdb_foreign_ckp_scn pdbForeignCkpScn,
          decode(rcd.pdb_nobackup, 'Y', 1, 0) noBackupPdb,
          rcd.pdb_foreign_afn pdbForeignAfn
     FROM rci_datafile rcd
    WHERE db_key = this_db_key
      AND (canHandleTransportableTbs = TRUE# OR plugged_readonly = 'NO')
      AND (nvl(realf_site_key, translation_site_key) = site_key)
      AND con_id = translateAllDfOfPdbId_c.pdbId
    ORDER BY file#, decode(dbinc_key, this_dbinc_key, 0, 1),
             newDfCreationSCN desc;
 
CURSOR translateAllDfOfPdbIdL_c
RETURN dfRec_t IS
   SELECT DISTINCT
          file#                 dfNumber,
          creation_change#      dfCreationSCN,
          creation_time         dfCreationTime,
          name                  fileName,
          tablespace_name       tsName,
          ts#                   tsNumber,
          to_char(null)         status,
          blocks                blocks,
          block_size            blockSize,
          bytes / 1024          kbytes,
          to_number(null)       unrecovSCN,
          stop_change#          stopSCN,
          FALSE#                readOnly,
          rfile#                rfNumber,
          decode(included_in_database_backup, 'YES', 1, 0)
                                inBackup,
          aux_name              auxNAme,
          dbinc_key             dbincKey,
          NULL                  dfOfflineSCN,
          NULL                  dfOnlineSCN,
          NULL                  dfOnlineTime,
          decode(encrypt_in_backup, 'ON', 1, 'OFF',2, 3) encrypt,
--
          rcd.foreign_dbid,
          decode(rcd.plugged_readonly, 'YES', 1, 0),
          rcd.plugin_change#,
          rcd.plugin_resetlogs_change#,
          rcd.plugin_resetlogs_time,
          decode(rcd.plugin_change#, 0, rcd.creation_change#,
                 rcd.plugin_change#) newDfCreationSCN,
          creation_thread,
          creation_size,
          con_id pdbId,
          pdb_key pdbKey,
          pdb_name pdbName,
          pdb_closed pdbClosed,
          rcd.pdb_foreign_dbid pdbForeignDbid,
          rcd.pdb_foreign_ckp_scn pdbForeignCkpScn,
          decode(rcd.pdb_nobackup, 'Y', 1, 0) noBackupPdb,
          rcd.pdb_foreign_afn pdbForeignAfn
     FROM rci_datafile rcd
    WHERE db_key = this_db_key
      AND (canHandleTransportableTbs = TRUE# OR plugged_readonly = 'NO')
      AND (nvl(realf_site_key, translation_site_key) = site_key)
      AND isTranslatedPdbId(con_id) = TRUE#
    ORDER BY file#, decode(dbinc_key, this_dbinc_key, 0, 1),
             newDfCreationSCN desc;
 
--
--
CURSOR translateCorruptList_c
RETURN dfRec_t IS
   SELECT DISTINCT
          rcd.file#, rcd.creation_change#, rcd.creation_time,
          rcd.name, rcd.tablespace_name, rcd.ts#,
          null, rcd.blocks, rcd.block_size, rcd.bytes / 1024,
          null, rcd.stop_change#, rcd.read_only, rcd.rfile#,
          decode(rcd.included_in_database_backup, 'YES', 1, 0),
          aux_name, rcd.dbinc_key, NULL, NULL, NULL,
          decode(rcd.encrypt_in_backup, 'ON', 1, 'OFF',2, 3) encrypt,
--
          rcd.foreign_dbid,
          decode(rcd.plugged_readonly, 'YES', 1, 0),
          rcd.plugin_change#,
          rcd.plugin_resetlogs_change#,
          rcd.plugin_resetlogs_time,
          to_number(null) newDfCreationSCN,
          rcd.creation_thread,
          rcd.creation_size,
          rcd.con_id pdbId,
          rcd.pdb_key pdbKey,
          rcd.pdb_name pdbName,
          rcd.pdb_closed pdbClosed,
          rcd.pdb_foreign_dbid pdbForeignDbid,
          rcd.pdb_foreign_ckp_scn pdbForeignCkpScn,
          decode(rcd.pdb_nobackup, 'Y', 1, 0) noBackupPdb,
          rcd.pdb_foreign_afn pdbForeignAfn
     FROM rci_datafile_this_dbinc rcd,
          (select distinct file#
             from rc_database_block_corruption
            where dbinc_key = this_dbinc_key
              and corruption_type != 'NOLOGGING') bc
    WHERE rcd.db_key = this_db_key AND          -- belongs to this database
          rcd.file# = bc.file# AND              -- filenumber matches
          rcd.dbinc_key = this_dbinc_key AND
          (canHandleTransportableTbs = TRUE# OR
           rcd.plugged_readonly = 'NO') AND
          ((untilSCN is null AND rcd.drop_change# is null) OR
           ((nvl(rcd.creation_time, MINDATEVAL) < untilTime OR
             decode(rcd.plugin_change#, 0, rcd.creation_change#,
                    rcd.plugin_change#) < untilSCN) AND
            (rcd.drop_time > untilTime OR
             rcd.drop_change# > untilSCN OR
             rcd.drop_change# is null))) AND
          (nvl(realf_site_key, translation_site_key) = site_key)
     ORDER BY rcd.file#;  -- do not change this as krmkcortr is
--
 
--
--
--
getTempfileCursor varchar2(30);         -- pointer to current cursor
 
--
--
--
--
CURSOR translateTempfile_c
RETURN tfRec_t IS
   SELECT file#              tfNumber,
          creation_change#   tfCreationSCN,
          creation_time      tfCreationTime,
          name               fileName,
          tablespace_name    tsName,
          ts#                tsNumber,
          decode(autoextend, 'ON', 16, 0)
                             status,
          bigfile            isSFT,
          blocks             blocks,
          block_size         blockSize,
          maxsize            maxSize,
          nextsize           nextSize,
          rfile#             rfNumber,
          dbinc_key          dbincKey,
          con_id             pdbId,
          pdb_key            pdbKey,
          pdb_name           pdbName
   FROM rc_tempfile
  WHERE dbinc_key = this_dbinc_key         -- belongs to this incarnation
    AND drop_change# is NULL               -- tempfile exists now
    AND (untilSCN is NULL OR
         ((tablespace_creation_change# < untilSCN OR
           nvl(tablespace_creation_time, MINDATEVAL) < untilTime) AND
          tablespace_drop_change# IS NULL))
    AND (nvl(realf_site_key, translation_site_key) = site_key)
    AND name is not NULL
    ORDER BY file#;
 
CURSOR translateTempfileOfPdbId_c(
   pdbId number)
RETURN tfRec_t IS
   SELECT file#              tfNumber,
          creation_change#   tfCreationSCN,
          creation_time      tfCreationTime,
          name               fileName,
          tablespace_name    tsName,
          ts#                tsNumber,
          decode(autoextend, 'ON', 16, 0)
                             status,
          bigfile            isSFT,
          blocks             blocks,
          block_size         blockSize,
          maxsize            maxSize,
          nextsize           nextSize,
          rfile#             rfNumber,
          dbinc_key          dbincKey,
          con_id             pdbId,
          pdb_key            pdbKey,
          pdb_name           pdbName
   FROM rc_tempfile
  WHERE dbinc_key = this_dbinc_key         -- belongs to this incarnation
    AND drop_change# is NULL               -- tempfile exists now
    AND (untilSCN is NULL OR
         ((tablespace_creation_change# < untilSCN OR
           nvl(tablespace_creation_time, MINDATEVAL) < untilTime) AND
          tablespace_drop_change# IS NULL))
    AND (nvl(realf_site_key, translation_site_key) = site_key)
    AND name is not NULL
    AND con_id = translateTempfileOfPdbId_c.pdbId
    ORDER BY file#;
 
CURSOR translateTempfileOfPdbIdL_c
RETURN tfRec_t IS
   SELECT file#              tfNumber,
          creation_change#   tfCreationSCN,
          creation_time      tfCreationTime,
          name               fileName,
          tablespace_name    tsName,
          ts#                tsNumber,
          decode(autoextend, 'ON', 16, 0)
                             status,
          bigfile            isSFT,
          blocks             blocks,
          block_size         blockSize,
          maxsize            maxSize,
          nextsize           nextSize,
          rfile#             rfNumber,
          dbinc_key          dbincKey,
          con_id             pdbId,
          pdb_key            pdbKey,
          pdb_name           pdbName
   FROM rc_tempfile
  WHERE dbinc_key = this_dbinc_key         -- belongs to this incarnation
    AND drop_change# is NULL               -- tempfile exists now
    AND (untilSCN is NULL OR
         ((tablespace_creation_change# < untilSCN OR
           nvl(tablespace_creation_time, MINDATEVAL) < untilTime) AND
          tablespace_drop_change# IS NULL))
    AND (nvl(realf_site_key, translation_site_key) = site_key)
    AND name is not NULL
    AND isTranslatedPdbId(con_id) = TRUE#
    ORDER BY file#;
 
CURSOR translateTempfileName_c(fileName IN varchar2)
RETURN tfRec_t IS
   SELECT file#              tfNumber,
          creation_change#   tfCreationSCN,
          creation_time      tfCreationTime,
          name               fileName,
          tablespace_name    tsName,
          ts#                tsNumber,
          decode(autoextend, 'ON', 16, 0)
                             status,
          bigfile            isSFT,
          blocks             blocks,
          block_size         blockSize,
          maxsize            maxSize,
          nextsize           nextSize,
          rfile#             rfNumber,
          dbinc_key          dbincKey,
          con_id             pdbId,
          pdb_key            pdbKey,
          pdb_name           pdbName
   FROM rc_tempfile
  WHERE dbinc_key = this_dbinc_key         -- belongs to this incarnation
    AND drop_change# is NULL               -- tempfile exists now
    AND (untilSCN is NULL OR
         ((tablespace_creation_change# < untilSCN OR
           nvl(tablespace_creation_time, MINDATEVAL) < untilTime) AND
          tablespace_drop_change# IS NULL))
    AND name = translateTempfileName_c.fileName -- filename matches
    AND (nvl(realf_site_key, translation_site_key) = site_key)
    AND name is not NULL
    ORDER BY file#;
 
CURSOR translateTempfileNumber_c(fno IN number)
RETURN tfRec_t IS
   SELECT file#              tfNumber,
          creation_change#   tfCreationSCN,
          creation_time      tfCreationTime,
          name               fileName,
          tablespace_name    tsName,
          ts#                tsNumber,
          decode(autoextend, 'ON', 16, 0)
                             status,
          bigfile            isSFT,
          blocks             blocks,
          block_size         blockSize,
          maxsize            maxSize,
          nextsize           nextSize,
          rfile#             rfNumber,
          dbinc_key          dbincKey,
          con_id             pdbId,
          pdb_key            pdbKey,
          pdb_name           pdbName
   FROM rc_tempfile
  WHERE dbinc_key = this_dbinc_key         -- belongs to this incarnation
    AND drop_change# is NULL               -- tempfile exists now
    AND (untilSCN is NULL OR
         ((tablespace_creation_change# < untilSCN OR
           nvl(tablespace_creation_time, MINDATEVAL) < untilTime) AND
          tablespace_drop_change# IS NULL))
    AND file# = translateTempfileNumber_c.fno -- filenumber matches
    AND (nvl(realf_site_key, translation_site_key) = site_key)
    AND name is not NULL
    ORDER BY file#;
 
--
--
--
 
CURSOR translateOnlineLogs_c(srls IN number) IS
   SELECT thread#, group#, name
     FROM rc_redo_log
    WHERE dbinc_key = this_dbinc_key
     AND (nvl(realf_site_key, translation_site_key) = site_key)
     AND  ((type = 'ONLINE' AND srls = 0) OR
           (type = 'STANDBY' AND srls = 1))
    ORDER BY thread#, group#, name;
 
--
--
--
 
getArchivedLogNoRows            noRows_t;
getArchivedLogDuplicates        number;         -- Duplicate filtering flag
getArchivedLogLast              alRec_t;        -- used for duplicate filtering
getArchivedLogCursor            varchar2(40);
getArchivedLogDoingRecovery     number;        -- for filtering orphan logs
getArchivedLogOnlyrdf           number := 0;
getrcvRecLast                   rcvRec_t;
 
CURSOR translateArcLogKey(
   alKey        IN     number)
RETURN alRec_t IS
   SELECT al_key,
          recid,
          stamp,
          thread#,
          sequence#,
          name,
          first_change#,
          first_time,
          next_change#,
          next_time,
          resetlogs_change#,
          resetlogs_time,
          blocks,
          block_size,
          status,
          completion_time,
          0,
          is_recovery_dest_file,
          compressed,
          decode(is_standby, 'YES', 'Y', 'N') stby,
          terminal,
          site_key,
          0 site_key_order_col,
          0 source_dbid
     FROM rc_archived_log
    WHERE db_key = this_db_key
      AND archived = 'YES'
      AND al_key = translateArcLogKey.alKey;
 
CURSOR translateArcLogName(
   fname        IN varchar2
  ,statusMask   IN binary_integer
  ,online       IN number                       -- IGNORED!
  ,needstby     IN number  DEFAULT NULL)
RETURN alRec_t IS
   SELECT al_key,
          recid,
          stamp,
          thread#,
          sequence#,
          name,
          first_change#,
          first_time,
          next_change#,
          next_time,
          resetlogs_change#,
          resetlogs_time,
          blocks,
          block_size,
          status,
          completion_time,
          0,
          is_recovery_dest_file,
          compressed,
          decode(is_standby, 'YES', 'Y', 'N') stby,
          terminal,
          site_key,
          0 site_key_order_col,
          0 source_dbid
     FROM rc_archived_log
    WHERE db_key = this_db_key
      AND name = translateArcLogName.fname
      AND decode(statusMask, BSavailable,
                 decode(status, 'A', TRUE#, FALSE#),
                 isStatusMatch(status, statusMask)) = TRUE#
      AND ((client_site_aware = TRUE# AND
            ((user_site_key = site_key) OR -- interested in specific site
             (user_site_key IS NULL AND
              ((logs_shared = TRUE#) OR
               (this_site_key = nvl(site_key, this_site_key)))))) OR
           (client_site_aware = FALSE# AND
            (needstby is NULL OR
             nvl(is_standby, 'NO') = decode(needstby, TRUE#, 'YES', 'NO') OR
             (terminal = 'YES') OR
             (first_change# >= lbacked_al_next_scn AND
              first_change# <= standby_became_primary_scn))))
    ORDER BY is_recovery_dest_file desc, stamp desc;
 
CURSOR translateArcLogSeqRange(
   thread#      IN number
  ,incarn       IN number
  ,fromseq#     IN number
  ,toseq#       IN number
  ,pattern      IN varchar2
  ,statusMask   IN binary_integer
  ,online       IN number                       -- IGNORED!
  ,needstby     IN number  DEFAULT NULL)
RETURN alRec_t IS
   SELECT al_key,
          recid,
          stamp,
          thread#,
          sequence#,
          name,
          first_change#,
          first_time,
          next_change#,
          next_time,
          resetlogs_change#,
          resetlogs_time,
          blocks,
          block_size,
          status,
          completion_time,
          0,
          is_recovery_dest_file,
          compressed,
          decode(is_standby, 'YES', 'Y', 'N') stby,
          terminal,
          site_key,
          0 site_key_order_col,
          0 source_dbid
     FROM rc_archived_log
    WHERE db_key = this_db_key
      AND dbinc_key = DECODE (translateArcLogSeqRange.incarn,
                                            -1, this_dbinc_key,
                                            0, dbinc_key,
                                            translateArcLogSeqRange.incarn)
      AND (translateArcLogSeqRange.thread# IS NULL OR
           thread# = translateArcLogSeqRange.thread#)
      AND sequence# between nvl(fromseq#, 0)
                        and nvl(toseq#, MAXSEQVAL)
      AND (pattern is null OR name like pattern)
      AND isstatusMatch(status,statusMask) = TRUE#
      AND archived = 'YES'  -- this will also filter out cleared logs
      AND ((client_site_aware = TRUE# AND
            ((user_site_key = site_key) OR -- interested in specific site
             (user_site_key IS NULL AND
              ((logs_shared = TRUE#) OR
               (this_site_key = NVL(site_key, this_site_key)))))) OR
           (client_site_aware = FALSE# AND
            (needstby IS NULL OR
             nvl(is_standby, 'NO') = DECODE(needstby, TRUE#, 'YES', 'NO') OR
             (terminal = 'YES') OR
             (first_change# >= lbacked_al_next_scn AND
              first_change# <= standby_became_primary_scn))))
    ORDER BY thread#, sequence#, terminal DESC,
             is_recovery_dest_file DESC, stamp DESC;
 
--
CURSOR translateArcLogSeqRange2(
   thread#      IN number
  ,incarn       IN number
  ,fromseq#     IN number
  ,toseq#       IN number
  ,statusMask   IN binary_integer  -- must atleast have BSdeleted
  ,online       IN number
  ,needstby     IN number  DEFAULT NULL)
RETURN alRec_t IS
   SELECT al_key,
          recid,
          DECODE(next_change#, highscnval, -2, stamp) stamp,
          thread#,
          sequence#,
          name,
          first_change#,
          first_time,
          next_change#,
          next_time,
          resetlogs_change#,
          resetlogs_time,
          blocks,
          block_size,
          status,
          completion_time,
          0,
          is_recovery_dest_file,
          compressed,
          decode(is_standby, 'YES', 'Y', 'N') stby,
          terminal,
          site_key,
          0 site_key_order_col,
          0 source_dbid
     FROM rc_archived_log
    WHERE db_key = this_db_key
      AND dbinc_key = DECODE (translateArcLogSeqRange2.incarn,
                                            -1, this_dbinc_key,
                                            0, dbinc_key,
                                            translateArcLogSeqRange2.incarn)
      AND (translateArcLogSeqRange2.thread# IS NULL OR
           thread# = translateArcLogSeqRange2.thread#)
      AND sequence# between NVL(fromseq#, 0)
                        and NVL(toseq#, MAXSEQVAL)
      AND (archived = 'YES' OR     -- this will also filter out cleared logs
           (online = TRUE#
            and archived = 'NO'
            and name IS NOT NULL))
      AND ((client_site_aware = TRUE# AND
            ((user_site_key = site_key) OR -- interested in specific site
             (user_site_key IS NULL AND
              ((logs_shared = TRUE#) OR
               (this_site_key = NVL(site_key, this_site_key)))))) OR
           (client_site_aware = FALSE# AND
            (needstby IS NULL OR
             nvl(is_standby, 'NO') = decode(needstby, TRUE#, 'YES', 'NO') OR
             (terminal = 'YES') OR
             (first_change# >= lbacked_al_next_scn AND
              first_change# <= standby_became_primary_scn))))
      AND isstatusMatch(status,statusMask) = TRUE#
 
    UNION ALL
 
   SELECT DISTINCT                              -- to filter duplicates
          TO_NUMBER(NULL),
          TO_NUMBER(NULL),
          -1,                                   -- to sort last (desc)
          brl.thread#,
          brl.sequence#,
          TO_CHAR(NULL),
          brl.low_scn,
          brl.low_time,
          brl.next_scn,
          brl.next_time,
          dbinc.reset_scn,
          dbinc.reset_time,
          brl.blocks,
          brl.block_size,
          'D',
          TO_DATE(NULL),
          0,
          'NO',
          'NO',
          'N',
          brl.terminal,
          0,
          0 site_key_order_col,
          0 source_dbid
     FROM brl, dbinc
    WHERE brl.dbinc_key = dbinc.dbinc_key       -- join condition
      AND dbinc.db_key = this_db_key
      AND brl.dbinc_key = DECODE (translateArcLogSeqRange2.incarn,
                                          -1, this_dbinc_key,
                                          0, brl.dbinc_key,
                                          translateArcLogSeqRange2.incarn)
      AND (translateArcLogSeqRange2.thread# IS NULL OR
           brl.thread# = translateArcLogSeqRange2.thread#)
      AND brl.sequence# BETWEEN NVL(fromseq#, 0)
                        AND NVL(toseq#, MAXSEQVAL)
--
--
 
    UNION                      -- to filter duplicates between brl and xal
 
   SELECT DISTINCT                              -- to filter duplicates
          TO_NUMBER(NULL),
          TO_NUMBER(NULL),
          -1,                                   -- to sort last (desc)
          xal.thread#,
          xal.sequence#,
          TO_CHAR(NULL),
          xal.low_scn,
          xal.low_time,
          xal.next_scn,
          xal.next_time,
          dbinc.reset_scn,
          dbinc.reset_time,
          xal.blocks,
          xal.block_size,
          'D',
          TO_DATE(NULL),
          0,
          'NO',
          'NO',
          'N',
          xal.terminal,
          xal.site_key,
          0 site_key_order_col,
          0 source_dbid
     FROM xal, dbinc
    WHERE xal.dbinc_key = dbinc.dbinc_key       -- join condition
      AND dbinc.db_key = this_db_key
      AND xal.dbinc_key = DECODE (translateArcLogSeqRange2.incarn,
                                          -1, this_dbinc_key,
                                          0, xal.dbinc_key,
                                          translateArcLogSeqRange2.incarn)
      AND (translateArcLogSeqRange2.thread# IS NULL OR
           xal.thread# = translateArcLogSeqRange2.thread#)
      AND xal.sequence# BETWEEN NVL(fromseq#, 0)
                        AND NVL(toseq#, MAXSEQVAL)
--
--
      AND ((user_site_key  = xal.site_key) OR
           (user_site_key IS NULL AND
            ((tape_backups_shared = TRUE#) OR
             (this_site_key = NVL(xal.site_key, this_site_key)))))
 
--
--
    ORDER BY     4,       5,       21 DESC,                   18 DESC, 3 DESC;
 
--
CURSOR translateArcLogTimeRange(
   thread#      IN number
  ,incarn       IN number
  ,fromTime     IN date
  ,toTime       IN date
  ,pattern      IN varchar2
  ,statusMask   IN binary_integer
  ,online       IN number               -- IGNORED!
  ,needstby     IN number   DEFAULT NULL)
RETURN alRec_t IS
   SELECT al_key,
          recid,
          stamp,
          thread#,
          sequence#,
          name,
          first_change#,
          first_time,
          next_change#,
          next_time,
          resetlogs_change#,
          resetlogs_time,
          blocks,
          block_size,
          status,
          completion_time,
          0,
          is_recovery_dest_file,
          compressed,
          decode(is_standby, 'YES', 'Y', 'N') stby,
          terminal,
          site_key,
          0 site_key_order_col,
          0 source_dbid
     FROM rc_archived_log
    WHERE db_key = this_db_key
      AND (canApplyAnyRedo = TRUE# OR dbinc_key = this_dbinc_key)
      AND dbinc_key = DECODE (translateArcLogTimeRange.incarn,
                                       -1, this_dbinc_key,
                                       0, dbinc_key,
                                       translateArcLogTimeRange.incarn)
      AND (translateArcLogTimeRange.thread# IS NULL OR
           thread# = translateArcLogTimeRange.thread#)
      AND next_time >  NVL(fromTime, MINDATEVAL)
      AND first_time  <= NVL(toTime, MAXDATEVAL)
      AND (pattern IS NULL OR name LIKE pattern)
      AND DECODE(statusMask, BSavailable,
                 DECODE(status, 'A', TRUE#, FALSE#),
                 isStatusMatch(status, statusMask)) = TRUE#
      AND archived = 'YES'  -- this will also filter out cleared logs
      AND ((client_site_aware = TRUE# AND
            ((user_site_key = site_key) OR -- interested in specific site
             (user_site_key IS NULL AND
              ((logs_shared = TRUE#) OR
               (this_site_key = NVL(site_key, this_site_key)))))) OR
           (client_site_aware = FALSE# AND
            (needstby IS NULL OR
             nvl(is_standby, 'NO') = DECODE(needstby, TRUE#, 'YES', 'NO') OR
             (terminal = 'YES') OR
             (first_change# >= lbacked_al_next_scn AND
              first_change# <= standby_became_primary_scn))))
--
    ORDER BY resetlogs_change#, resetlogs_time, thread#, sequence#,
             terminal DESC, is_recovery_dest_file DESC, stamp DESC;
 
--
--
CURSOR translateArcLogTimeRange2(
   thread#      IN number
  ,incarn       IN number
  ,fromTime     IN date
  ,toTime       IN date
  ,statusMask   IN binary_integer  -- must atleast have BSdeleted
  ,online       IN number
  ,needstby     IN number   DEFAULT NULL)
RETURN alRec_t IS
   SELECT al_key,
          recid,
          DECODE(next_change#, highscnval, -2, stamp) stamp,
          thread#,
          sequence#,
          name,
          first_change#,
          first_time,
          next_change#,
          next_time,
          resetlogs_change#,
          resetlogs_time,
          blocks,
          block_size,
          status,
          completion_time,
          0,
          is_recovery_dest_file,
          compressed,
          DECODE(is_standby, 'YES', 'Y', 'N') stby,
          terminal,
          site_key,
          0 site_key_order_col,
          0 source_dbid
     FROM rc_archived_log
    WHERE db_key = this_db_key
      AND (canApplyAnyRedo = TRUE# OR dbinc_key = this_dbinc_key)
      AND dbinc_key = DECODE (translateArcLogTimeRange2.incarn,
                                       -1, this_dbinc_key,
                                       0, dbinc_key,
                                       translateArcLogTimeRange2.incarn)
      AND (translateArcLogTimeRange2.thread# IS NULL OR
           thread# = translateArcLogTimeRange2.thread#)
      AND next_time >  NVL(fromTime, MINDATEVAL)
      AND first_time  <= NVL(toTime, MAXDATEVAL)
      AND (archived = 'YES' OR   -- this will also filter out cleared logs
           (online = TRUE#
            AND archived = 'NO'
            AND name IS NOT NULL
            AND resetlogs_change# = this_reset_scn
            AND resetlogs_time = this_reset_time))
      AND ((client_site_aware = TRUE# AND
            ((user_site_key = site_key) OR -- interested in specific site
             (user_site_key IS NULL AND
              ((logs_shared = TRUE#) OR
               (this_site_key = NVL(site_key, this_site_key)))))) OR
           (client_site_aware = FALSE# AND
            (needstby IS NULL OR
             NVL(is_standby, 'NO') = DECODE(needstby, TRUE#, 'YES', 'NO') OR
             (terminal = 'YES') OR
             (first_change# >= lbacked_al_next_scn AND
              first_change# <= standby_became_primary_scn))))
      AND isstatusMatch(status,statusMask) = TRUE#
 
    UNION ALL
 
   SELECT DISTINCT                              -- to filter duplicates
          TO_NUMBER(NULL),
          TO_NUMBER(NULL),
          -1,                                   -- to sort last
          thread#,
          sequence#,
          TO_CHAR(NULL),
          low_scn,
          low_time,
          next_scn,
          next_time,
          reset_scn,
          reset_time,
          blocks,
          block_size,
          'D',
          TO_DATE(NULL),
          0,
          'NO',
          'NO',
          'N',
          terminal,
          0,
          0 site_key_order_col,
          0 source_dbid
     FROM brl, dbinc
    WHERE brl.dbinc_key = dbinc.dbinc_key       -- join condition
      AND dbinc.db_key = this_db_key
      AND (canApplyAnyRedo = TRUE# OR brl.dbinc_key = this_dbinc_key)
      AND dbinc.dbinc_key = DECODE (translateArcLogTimeRange2.incarn,
                                             -1, this_dbinc_key,
                                             0, dbinc.dbinc_key,
                                             translateArcLogTimeRange2.incarn)
      AND next_time >  NVL(fromTime, MINDATEVAL)
      AND low_time  <= NVL(toTime, MAXDATEVAL)
      AND (translateArcLogTimeRange2.thread# IS NULL OR
           thread# = translateArcLogTimeRange2.thread#)
--
--
 
    UNION                      -- to filter duplicates between brl and xal
 
   SELECT DISTINCT                              -- to filter duplicates
          TO_NUMBER(NULL),
          TO_NUMBER(NULL),
          -1,                                   -- to sort last
          thread#,
          sequence#,
          TO_CHAR(NULL),
          low_scn,
          low_time,
          next_scn,
          next_time,
          reset_scn,
          reset_time,
          blocks,
          block_size,
          'D',
          TO_DATE(NULL),
          0,
          'NO',
          'NO',
          'N',
          terminal,
          site_key,
          0 site_key_order_col,
          0 source_dbid
     FROM xal, dbinc
    WHERE xal.dbinc_key = dbinc.dbinc_key       -- join condition
      AND dbinc.db_key = this_db_key
      AND (canApplyAnyRedo = TRUE# OR xal.dbinc_key = this_dbinc_key)
      AND dbinc.dbinc_key = DECODE (translateArcLogTimeRange2.incarn,
                                             -1, this_dbinc_key,
                                             0, dbinc.dbinc_key,
                                             translateArcLogTimeRange2.incarn)
      AND next_time >  NVL(fromTime, MINDATEVAL)
      AND low_time  <= NVL(toTime, MAXDATEVAL)
      AND (translateArcLogTimeRange2.thread# IS NULL OR
           thread# = translateArcLogTimeRange2.thread#)
--
--
--
--
--
      AND ((user_site_key  = xal.site_key) OR
           (user_site_key IS NULL AND
            ((tape_backups_shared = TRUE#) OR
             (this_site_key = NVL(xal.site_key, this_site_key)))))
 
    ORDER BY        11,         12,       4,       5,
                       21 DESC,     18 DESC,  3 DESC;
 
--
--
CURSOR translateArcLogSCNRange(
   thread#      IN number
  ,incarn       IN number
  ,sequence#    IN number
  ,fromSCN      IN number
  ,toSCN        IN number
  ,pattern      IN varchar2
  ,statusMask   IN binary_integer
  ,online       IN number
  ,needstby     IN number  DEFAULT NULL
  ,reset_scn    IN number
  ,reset_time   IN date)
RETURN alRec_t IS
   SELECT al_key,
          recid,
          DECODE(next_change#, highscnval, -2, stamp) stamp,
          thread#,
          sequence#,
          name,
          first_change#,
          first_time,
          next_change#,
          next_time,
          resetlogs_change#,
          resetlogs_time,
          blocks,
          block_size,
          status,
          completion_time,
          0,
          is_recovery_dest_file,
          compressed,
          DECODE(is_standby, 'YES', 'Y', 'N') stby,
          terminal,
          site_key,
          0 site_key_order_col,
          0 source_dbid
     FROM rc_archived_log
    WHERE db_key = this_db_key
      AND ((canApplyAnyRedo = TRUE# AND
              (translateArcLogSCNRange.reset_scn IS NULL OR
              (translateArcLogSCNRange.reset_scn = resetlogs_change# AND
               translateArcLogSCNRange.reset_time = resetlogs_time))) OR
           (dbinc_key = this_dbinc_key))
      AND dbinc_key = DECODE (translateArcLogSCNRange.incarn,
                                             -1, this_dbinc_key,
                                             0, dbinc_key,
                                             translateArcLogSCNRange.incarn)
      AND (translateArcLogSCNRange.thread# IS NULL OR
           thread# = translateArcLogSCNRange.thread#)
      AND (translateArcLogSCNRange.sequence# IS NULL OR
           sequence# = translateArcLogSCNRange.sequence#)
      AND next_change# > NVL(fromSCN, 0)
      AND first_change#  < NVL(toSCN, MAXSCNVAL)
      AND (pattern IS NULL OR name LIKE pattern)
      AND decode(statusMask, BSavailable,
                 DECODE(status, 'A', TRUE#, FALSE#),
                 isStatusMatch(status, statusMask)) = TRUE#
      AND (archived = 'YES' OR      -- this will also filter out cleared logs
           (online = TRUE#
            and archived = 'NO'
            and name IS NOT NULL
            and resetlogs_change# = this_reset_scn
            and resetlogs_time = this_reset_time))
      AND ((client_site_aware = TRUE# AND
            ((user_site_key = site_key) OR -- interested in specific site
             (user_site_key IS NULL AND
              ((logs_shared = TRUE#) OR
               (this_site_key = NVL(site_key, this_site_key)))))) OR
           (client_site_aware = FALSE# AND
            (needstby IS NULL OR
             NVL(is_standby, 'NO') = DECODE(needstby, TRUE#, 'YES', 'NO') OR
             (terminal = 'YES') OR
             (first_change# >= lbacked_al_next_scn AND
              first_change# <= standby_became_primary_scn))))
--
    ORDER BY resetlogs_change#, resetlogs_time, thread#, sequence#,
             terminal DESC, is_recovery_dest_file DESC, stamp DESC;
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
CURSOR translateArcLogSCNRange2(
   thread#      IN number
  ,incarn       IN number
  ,sequence#    IN number
  ,fromSCN      IN number
  ,toSCN        IN number
  ,toTime       IN date
  ,statusMask   IN binary_integer  -- must atleast have BSdeleted
  ,online       IN number
  ,needstby     IN number  DEFAULT NULL  -- IGNORED
  ,reset_scn    IN number
  ,reset_time   IN date)
RETURN alRec_t IS
   SELECT al_key,
          recid,
          DECODE(next_change#, highscnval, -2, stamp) stamp,
          thread#,
          sequence#,
          name,
          first_change#,
          first_time,
          next_change#,
          next_time,
          resetlogs_change#,
          resetlogs_time,
          blocks,
          block_size,
          status,
          completion_time,
          0,
          is_recovery_dest_file,
          compressed,
          DECODE(is_standby, 'YES', 'Y', 'N') stby,
          terminal,
          site_key,
          DECODE(next_change#, highscnval, -1,
                 DECODE(site_key, this_site_key, 1, 0)) site_key_order_col,
          0 source_dbid
     FROM rc_archived_log
    WHERE db_key = this_db_key
      AND ((canApplyAnyRedo = TRUE# AND
              (translateArcLogSCNRange2.reset_scn IS NULL OR
              (translateArcLogSCNRange2.reset_scn = resetlogs_change# AND
               translateArcLogSCNRange2.reset_time = resetlogs_time))) OR
           (dbinc_key = this_dbinc_key))
      AND dbinc_key = DECODE (translateArcLogSCNRange2.incarn,
                                             -1, this_dbinc_key,
                                             0, dbinc_key,
                                             translateArcLogSCNRange2.incarn)
      AND (translateArcLogSCNRange2.thread# IS NULL OR
           thread# = translateArcLogSCNRange2.thread#)
      AND (translateArcLogSCNRange2.sequence# IS NULL OR
           sequence# = translateArcLogSCNRange2.sequence#)
      AND next_change# > NVL(fromSCN, 0)
      AND first_change#  < NVL(toSCN, MAXSCNVAL)
      AND (toTime IS NULL OR first_time < toTime)
      AND (archived = 'YES' OR   -- this will also filter out cleared logs
           (online = TRUE#
            and archived = 'NO'
            and name IS NOT NULL
            and resetlogs_change# = this_reset_scn
            and resetlogs_time = this_reset_time))
      AND isstatusMatch(status,statusMask) = TRUE#
 
    UNION ALL
 
   SELECT DISTINCT                              -- to filter duplicates
          TO_NUMBER(NULL),
          TO_NUMBER(NULL),
          -1,                                   -- to sort last
          brl.thread#,
          brl.sequence#,
          TO_CHAR(NULL),
          brl.low_scn,
          brl.low_time,
          brl.next_scn,
          brl.next_time,
          dbinc.reset_scn,
          dbinc.reset_time,
          brl.blocks,
          brl.block_size,
          'D',
          TO_DATE(NULL),
          0,
          'NO',
          'NO',
          'N',
          brl.terminal,
          0,
          DECODE(brl.activation, 'Y', -2, 0) site_key_order_col,
          0 source_dbid
     FROM brl, dbinc
    WHERE brl.dbinc_key = dbinc.dbinc_key       -- join condition
      AND dbinc.db_key = this_db_key
      AND ((canApplyAnyRedo = TRUE# AND
              (translateArcLogSCNRange2.reset_scn IS NULL OR
               (translateArcLogSCNRange2.reset_scn = dbinc.reset_scn AND
                translateArcLogSCNRange2.reset_time = dbinc.reset_time))) OR
           (dbinc.dbinc_key = this_dbinc_key))
      AND brl.dbinc_key = DECODE (translateArcLogSCNRange2.incarn,
                                               -1, this_dbinc_key,
                                               0, brl.dbinc_key,
                                               translateArcLogSCNRange2.incarn)
      AND (translateArcLogSCNRange2.thread# IS NULL OR
           thread# = translateArcLogSCNRange2.thread#)
      AND (translateArcLogSCNRange2.sequence# IS NULL OR
           sequence# = translateArcLogSCNRange2.sequence#)
      AND next_scn > NVL(fromSCN, 0)
      AND low_scn  < NVL(toSCN, MAXSCNVAL)
      AND (toTime IS NULL OR low_time < toTime)
--
--
 
    UNION                      -- to filter duplicates between brl and xal
 
   SELECT DISTINCT                              -- to filter duplicates
          TO_NUMBER(NULL),
          TO_NUMBER(NULL),
          -1,                                   -- to sort last
          xal.thread#,
          xal.sequence#,
          TO_CHAR(NULL),
          xal.low_scn,
          xal.low_time,
          xal.next_scn,
          xal.next_time,
          dbinc.reset_scn,
          dbinc.reset_time,
          xal.blocks,
          xal.block_size,
          'D',
          TO_DATE(NULL),
          0,
          'NO',
          'NO',
          'N',
          xal.terminal,
          xal.site_key,
          0 site_key_order_col,
          0 source_dbid
     FROM xal, dbinc
    WHERE xal.dbinc_key = dbinc.dbinc_key       -- join condition
      AND dbinc.db_key = this_db_key
      AND ((canApplyAnyRedo = TRUE# AND
              (translateArcLogSCNRange2.reset_scn IS NULL OR
              (translateArcLogSCNRange2.reset_scn = dbinc.reset_scn AND
               translateArcLogSCNRange2.reset_time = dbinc.reset_time))) OR
           (dbinc.dbinc_key = this_dbinc_key))
      AND xal.dbinc_key = DECODE (translateArcLogSCNRange2.incarn,
                                        -1, this_dbinc_key,
                                        0, xal.dbinc_key,
                                        translateArcLogSCNRange2.incarn)
      AND (translateArcLogSCNRange2.thread# IS NULL OR
           thread# = translateArcLogSCNRange2.thread#)
      AND (translateArcLogSCNRange2.sequence# IS NULL OR
           sequence# = translateArcLogSCNRange2.sequence#)
      AND next_scn > NVL(fromSCN, 0)
      AND low_scn  < NVL(toSCN, MAXSCNVAL)
      AND (toTime IS NULL OR low_time < toTime)
--
--
      AND ((user_site_key  = xal.site_key) OR
           (user_site_key IS NULL AND
            ((tape_backups_shared = TRUE#) OR
             (this_site_key = NVL(xal.site_key, this_site_key)))))
 
--
--
--
    ORDER BY         11,         12,       4,       5, 21 DESC,
                     23 DESC,      18 DESC,  3 DESC;
 
CURSOR translateArcLogPattern(
   pattern      IN varchar2
  ,statusMask   IN binary_integer
  ,online       IN number                       -- IGNORED!
  ,needstby     IN number   DEFAULT NULL)
RETURN alRec_t IS
   SELECT al_key,
          recid,
          stamp,
          thread#,
          sequence#,
          name,
          first_change#,
          first_time,
          next_change#,
          next_time,
          resetlogs_change#,
          resetlogs_time,
          blocks,
          block_size,
          status,
          completion_time,
          0,
          is_recovery_dest_file,
          compressed,
          decode(is_standby, 'YES', 'Y', 'N') stby,
          terminal,
          site_key,
          0 site_key_order_col,
          0 source_dbid
     FROM rc_archived_log
    WHERE (canApplyAnyRedo = TRUE# OR dbinc_key = this_dbinc_key)
      AND db_key = this_db_key
      AND (pattern is null or name like pattern)
      AND decode(statusMask, BSavailable,
                 decode(status, 'A', TRUE#, FALSE#),
                 isStatusMatch(status, statusMask)) = TRUE#
      AND archived = 'YES'
      AND ((client_site_aware = TRUE# AND
            ((user_site_key = site_key) OR -- interested in specific site
             (user_site_key IS NULL AND
              ((logs_shared = TRUE#) OR
               (this_site_key = nvl(site_key, this_site_key)))))) OR
           (client_site_aware = FALSE# AND
            (needstby is NULL OR
             nvl(is_standby, 'NO') = decode(needstby, TRUE#, 'YES', 'NO') OR
             (terminal = 'YES') OR
             (first_change# >= lbacked_al_next_scn AND
              first_change# <= standby_became_primary_scn))))
--
    ORDER BY resetlogs_change#, resetlogs_time, thread#, sequence#,
             terminal desc, is_recovery_dest_file desc, stamp desc;
 
--
--
--
 
getControlFileCopySingleRow     boolean;
getControlFileCopyCursor        varchar2(30);
 
--
--
--
 
getDatafileCopyCursor           varchar2(30);
getDatafileCopyNoRows           noRows_t;
getDatafileCopyDuplicates       number;   -- match file number
getDatafileCopyLast             rcvRec_t;
getDatafileCopySingleRow        boolean;
getDatafileCopyLatestOnly       boolean;
 
--
--
--
 
getProxyCopyCursor              varchar2(30);
getProxyCopyNoRows              noRows_t;
getProxyCopyByHandle            boolean;
 
--
--
--
 
getBackupPieceCursor            varchar2(30);
getBackupPieceNoRows            noRows_t;
getBackupPieceDuplicates        number; -- TRUE# -> duplicates OK
--
getBackupPieceLast              bpRec_t;
--
--
getBackupPieceDeviceType        bp.device_type%TYPE;
getBackupPieceExpectedPieces    number;
getBackupPiecePieceCount        number;
getBackupPieceByHandle          boolean;
getBackupPieceAvailableMask     binary_integer;
getBackupPieceSeekLast          bpRec_t;
getBackupPieceCopyNumber        number;
getBackupPieceBskey             number;
 
--
--
--
findSpfileBackupCursor          boolean; -- TRUE# -> cursor opened
findControlfileBackupCursor     boolean; -- TRUE# -> cursor opened
 
 
--
--
--
 
listGetBackupTag                bp.tag%TYPE;
listGetBackupAvailableMask      binary_integer;
 
listGetProxyDatafileCursor      varchar2(30);
 
 
--
--
 
CURSOR lbal2(thread#       number,
             lowseq        number,
             highseq       number,
             lowscn        number,
             highscn       number,
             from_time     date  ,
             until_time    date)
RETURN rcvRec_t IS
   SELECT backupSet_con_t       type_con,
          brl.brl_key           key_con,
          brl.brl_recid         recid_con,
          brl.brl_stamp         stamp_con,
          bs.set_stamp          setStamp_con,
          bs.set_count          setCount_con,
          bs.bs_recid           bsRecid_con,
          bs.bs_stamp           bsStamp_con,
          bs.bs_key             bsKey_con,
          to_number(null)       bsLevel_con,
          bs.bck_type           bsType_con,
          abs((bs.completion_time - bs.start_time) * 86400)
                                elapseSecs_con,
          bs.pieces             pieceCount_con,
          to_char(null)         fileName_con,
          to_char(null)         tag_con,
          to_number(null)       copyNumber_con,
          to_char(null)         status_con,
          brl.blocks            blocks_con,
          brl.block_size        blockSize_con,
          to_char(null)         deviceType_con,
          bs.completion_time    compTime_con,
          to_date(null)         cfCreationTime_con,
          to_number(null)       pieceNumber_con,
          to_date(null)         bpCompTime_con,
          to_char(null)         bpCompressed_con,
          multi_section         multi_section_con,
 
          full_act_t            type_act,
          to_number(null)       fromSCN_act,
          to_number(null)       toSCN_act,
          to_date(null)         toTime_act,
          to_number(null)       rlgSCN_act,
          to_date(null)         rlgTime_act,
          dbinc.dbinc_key       dbincKey_act,
          to_number(null)       level_act,
          0                     section_size_act,
 
          to_number(null)       dfNumber_obj,
          to_number(null)       dfCreationSCN_obj,
          to_number(null)       cfSequence_obj,
          to_date(null)         cfDate_obj,
          brl.sequence#         logSequence_obj,
          brl.thread#           logThread_obj,
          dbinc.reset_scn       logRlgSCN_obj,
          dbinc.reset_time      logRlgTime_obj,
          brl.low_scn           logLowSCN_obj,
          brl.low_time          logLowTime_obj,
          brl.next_scn          logNextSCN_obj,
          brl.next_time         logNextTime_obj,
          brl.terminal          logTerminal_obj,
          to_char(null)         cfType_obj,
          to_number(null)       pdbKey_obj,
 
          to_number(null)       keep_options,
          to_date(null)         keep_until,
 
          to_number(null)       afzSCN_act,
          to_date(null)         rfzTime_act,
          to_number(null)       rfzSCN_act,
          to_char(null)         media_con,
          'NO'                  isrdf_con,
          bs.site_key           site_key_con,
          0                     foreignDbid_obj,
          0                     pluggedRonly_obj,
          0                     pluginSCN_obj,
          0                     pluginRlgSCN_obj,
          to_date(null)         pluginRlgTime_obj,
 
          to_number(null)       newDfCreationSCN_obj,
          to_number(null)       newToSCN_act,
          to_number(null)       newRlgSCN_act,
          to_date(null)         newRlgTime_act,
          to_char(null)         sfDbUniqueName_obj,
          to_char(null)         sparse_backup_con,
          0                     ppl_pdb_id_con,
          0                     ppl_cdb_dbid_con
  from  brl, bs, dbinc
  where dbinc.db_key    = this_db_key      -- this database
  and   dbinc.dbinc_key = brl.dbinc_key    -- join dbinc, brl
  and   bs.bs_key       = brl.bs_key       -- join bs, brl
  and  (lbal2.thread# is null or brl.thread# = lbal2.thread#)
  and  (brl.sequence# between nvl(lbal2.lowseq, 0)
                     and     nvl(lbal2.highseq, MAXSEQVAL))
  and  (lowscn        is null or brl.low_scn >= lowscn)
  and  (highscn       is null or brl.next_scn<  highscn)
  and  (from_time     is null or bs.completion_time >= from_time)
  and  (until_time    is null or bs.completion_time <= until_time)
--
  and   bs.status != 'D'
  and   bs.bck_type = 'L'                  -- only archivelog backups
  order by bs.bs_key, brl.thread#, brl.sequence#, brl.terminal desc;
 
CURSOR ldbi(
   db_name varchar2,
   all_databases number)
IS
   SELECT db_key, dbinc_key, name, dbid, current_incarnation,
          resetlogs_change#, resetlogs_time, status dbinc_status
     FROM rc_database_incarnation
    WHERE (all_databases = 1) OR -- user wants all database incarnations
          ((all_databases = 0) AND
           ((name = ldbi.db_name) OR -- user asked for specific database
            (db_name is NULL AND this_db_key=db_key))) -- user wants mounted db
    ORDER BY db_key, resetlogs_change#, dbinc_key;
 
CURSOR lnni(
   db_name varchar2,
   alldbs  number)
IS
   SELECT node.db_key, dbid, name, database_role, db_unique_name
     FROM rc_database, node
    WHERE rc_database.db_key = node.db_key
      AND ((alldbs = 1) OR
           (lnni.db_name IS NOT NULL AND upper(lnni.db_name) = name) OR
           (lnni.db_name IS NULL AND this_db_key = node.db_key))
      AND substr(nvl(db_unique_name, 'A'),1,1) <> '$'
    ORDER BY dbid, database_role;
--
 
CURSOR lrtbs
IS
   SELECT DISTINCT ts.ts#, ts.ts_name, pdbinc.name
     FROM ts, tsatt, ckp, rci_pdbinc_this_dbinc pdbinc
 
--
    WHERE pdbinc.dbinc_key = this_dbinc_key 
      AND ts.pdbinc_key    = pdbinc.pdbinc_key
      AND (untilSCN is NULL or pdbinc.create_scn < untilSCN)
      AND (pdbinc.drop_scn is NULL or pdbinc.drop_scn > untilSCN)
      AND ts.dbinc_key     = tsatt.dbinc_key
      AND ts.ts#           = tsatt.ts#
      AND ts.pdbinc_key    = tsatt.pdbinc_key
      AND ts.create_scn    = tsatt.create_scn
--
--
--
      AND ckp.ckp_key(+)   = tsatt.end_ckp_key
 
--
      AND ts.dbinc_key     = this_dbinc_key
 
--
--
--
      AND (ts.create_scn < untilSCN or untilSCN is NULL)
 
--
--
--
--
--
      AND (ts.drop_scn > untilSCN or ts.drop_scn is NULL)
 
--
--
--
--
      AND (ckp.ckp_scn > untilSCN or ckp.ckp_scn is NULL)
 
--
--
      AND tsatt.rbs_count > 0
    ORDER BY 1,    -- ts#
             3;    -- pdbname
 
--
--
--
 
rcvRec_last     rcvRec_t;                       -- last record returned from:
--
--
 
--
--
--
 
CURSOR getOfflineRangeCopy_c(
   offrRecid    number
  ,offrCkpSCN   number
  ,cfCreTime    date
  ,dbincKey     number)
RETURN rcvRec_t IS
   SELECT imageCopy_con_t       type_con,
          ccf_key               key_con,
          ccf_recid             recid_con,
          ccf_stamp             stamp_con,
          to_number(null)       setStamp_con,
          to_number(null)       setCount_con,
          to_number(null)       bsRecid_con,
          to_number(null)       bsStamp_con,
          to_number(null)       bsKey_con,
          to_number(null)       bsLevel_con,
          to_char(null)         bsType_con,
          to_number(null)       elapseSecs_con,
          to_number(null)       pieceCount_con,
          fname                 fileName_con,
          tag                   tag_con,
          to_number(null)       copyNumber_con,
          status                status_con,
          to_number(null)       blocks_con,     -- ccf doesn't have blocks
          block_size            blockSize_con,
          'DISK'                deviceType_con,
          completion_time       compTime_con,
          create_time           cfCreationTime_con,
          to_number(null)       pieceNumber_con,
          to_date(null)         bpCompTime_con,
          to_char(null)         bpCompressed_con,
          to_char(null)         multi_section_con,
 
          full_act_t            type_act,
          0                     fromSCN_act,
          ccf.ckp_scn           toSCN_act,
          ccf.ckp_time          toTime_act,
          dbinc.reset_scn       rlgSCN_act,
          dbinc.reset_time      rlgTime_act,
          ccf.dbinc_key         dbincKey_act,
          to_number(null)       level_act,
          0                     section_size_act,
 
          0                     dfNumber_obj,
          0                     dfCreationSCN_obj,
          to_number(null)       cfSequence_obj,
          to_date(null)         cfDate_obj,
          to_number(null)       logSequence_obj,
          to_number(null)       logThread_obj,
          to_number(null)       logRlgSCN_obj,
          to_date(null)         logRlgTime_obj,
          to_number(null)       logLowSCN_obj,
          to_date(null)         logLowTime_obj,
          to_number(null)       logNextSCN_obj,
          to_date(null)         logNextTime_obj,
          to_char(null)         logTerminal_obj,
          to_char(null)         cfType_obj,
          ccf.pdb_key           pdbKey_obj,
 
          ccf.keep_options      keep_options,
          ccf.keep_until        keep_until,
 
          to_number(null)       afzSCN_act,
          to_date(null)         rfzTime_act,
          to_number(null)       rfzSCN_act,
          to_char(null)         media_con,
          is_recovery_dest_file isrdf_con,
          site_key              site_key_con,
          0                     foreignDbid_obj,
          0                     pluggedRonly_obj,
          0                     pluginSCN_obj,
          0                     pluginRlgSCN_obj,
          to_date(null)         pluginRlgTime_obj,
 
          to_number(null)       newDfCreationSCN_obj,
          to_number(null)       newToSCN_act,
          to_number(null)       newRlgSCN_act,
          to_date(null)         newRlgTime_act,
          to_char(null)         sfDbUniqueName_obj,
          to_char(null)         sparse_backup_con,
          0                     ppl_pdb_id_con,
          0                     ppl_cdb_dbid_con
     FROM ccf, dbinc
    WHERE dbinc.dbinc_key = getOfflineRangeCopy_c.dbincKey
      AND dbinc.dbinc_key = ccf.dbinc_key
      AND getOfflineRangeCopy_c.cfCretime = create_time
      AND getOfflineRangeCopy_c.offrCkpSCN < ccf.ckp_scn
      AND getOfflineRangeCopy_c.offrRecid >= min_offr_recid
      AND status = 'A'
      AND ((user_site_key = ccf.site_key) OR
           (user_site_key IS NULL AND
            ((disk_backups_shared = TRUE#) OR
             (this_site_key = nvl(ccf.site_key, this_site_key)))))
 
    ORDER BY stamp_con desc;
 
--
--
 
cursor rddf is
 
--
 
  select 2 preference,
         file#, COPY filetype, checkpoint_change#, checkpoint_time,
         resetlogs_change#, resetlogs_time, 0 incremental_change#,
         decode(decode(online_fuzzy,'NO',0,1)+decode(backup_fuzzy,'NO',0,1),
            0,greatest(nvl(absolute_fuzzy_change#,0),
                       nvl(recovery_fuzzy_change#,0)),
            maxscnval) fuzzy_change#,
            recid, stamp, name, 0 set_stamp, 0 set_count, cdf_key key,
            completion_time, 'DISK' device_type
  from rc_datafile_copy
  where db_key = this_db_key
    and status != 'D'
    and ((user_site_key = rc_datafile_copy.site_key) OR
         (user_site_key IS NULL AND
          ((disk_backups_shared = TRUE#) OR
           (this_site_key = nvl(rc_datafile_copy.site_key, this_site_key)))))
 
  union all
 
--
 
  select 3,
         file#, PROXY, checkpoint_change#, checkpoint_time,
         resetlogs_change#, resetlogs_time, 0,
         decode(decode(online_fuzzy,'NO',0,1)+decode(backup_fuzzy,'NO',0,1),
            0,greatest(nvl(absolute_fuzzy_change#,0),
                       nvl(recovery_fuzzy_change#,0)),
            maxscnval),
            recid, stamp, handle, 0, 0, xdf_key, completion_time, device_type
  from rc_proxy_datafile
  where db_key = this_db_key
    and status != 'D'
    and ((user_site_key  = rc_proxy_datafile.site_key) OR
         (user_site_key IS NULL AND
          ((tape_backups_shared = TRUE#) OR
           (this_site_key = nvl(rc_proxy_datafile.site_key, this_site_key)))))
 
  union all
 
--
 
  select decode(bs.bck_type, 'D', 4,
                             'I', 5),
         file#,
         decode(bs.bck_type, 'D', FULL_DF_BACKUP,
                             'I', INCREMENTAL_DF_BACKUP),
         bdf.ckp_scn, bdf.ckp_time,
         dbinc.reset_scn, dbinc.reset_time, bdf.incr_scn,
         nvl(bdf.abs_fuzzy_scn,0),
         bs.bs_recid, bs.bs_stamp, null, bs.set_stamp, bs.set_count, bs.bs_key,
         bs.completion_time, null
  from bdf, bs, dbinc
  where dbinc.db_key    = this_db_key          -- this database
  and   dbinc.dbinc_key = bdf.dbinc_key        -- join dbinc, bdf
  and   bdf.bs_key      = bs.bs_key            -- join bdf, bs
  and   bs.status      != 'D'
  and   bs.bck_type    != 'L'                  -- only datafile backups
  and   (bs.site_key IS NULL         OR        -- always return null site_key
         user_site_key = bs.site_key OR        -- user interested in one site
         (user_site_key IS NULL AND            -- return rows per access attr
          (disk_backups_shared = TRUE# OR
           tape_backups_shared = TRUE# OR
           this_site_key = bs.site_key)))
 
  union all
 
--
 
  select 2,
         0, COPY, checkpoint_change#, checkpoint_time,
         resetlogs_change#, resetlogs_time, 0, 0, recid, stamp, name, 0, 0,
         ccf_key, completion_time, 'DISK'
  from rc_controlfile_copy
  where db_key = this_db_key
    and status != 'D'
    and ((user_site_key = rc_controlfile_copy.site_key) OR
         (user_site_key IS NULL AND
          ((disk_backups_shared = TRUE#) OR
           (this_site_key = nvl(rc_controlfile_copy.site_key,this_site_key)))))
 
  union all
 
--
 
  select 3,
         0, PROXY, checkpoint_change#, checkpoint_time,
         resetlogs_change#, resetlogs_time, 0, 0, recid, stamp, handle, 0, 0,
         xcf_key, completion_time, device_type
  from rc_proxy_controlfile
  where db_key = this_db_key
    and status != 'D'
    and ((user_site_key  = rc_proxy_controlfile.site_key) OR
         (user_site_key IS NULL AND
          ((tape_backups_shared = TRUE#) OR
           (this_site_key =nvl(rc_proxy_controlfile.site_key,this_site_key)))))
 
  union all
 
--
 
  select 4,
         0, FULL_DF_BACKUP,
         bcf.ckp_scn, bcf.ckp_time, dbinc.reset_scn, dbinc.reset_time,
         0, 0, bs.bs_recid, bs.bs_stamp, null,
         bs.set_stamp, bs.set_count, bs.bs_key, bs.completion_time, null
  from bcf, bs, dbinc
  where dbinc.db_key = this_db_key              -- this database
  and   dbinc.dbinc_key = bcf.dbinc_key         -- join dbinc, bcf
  and   bcf.bs_key = bs.bs_key                  -- join bcf, bs
  and   bs.status != 'D'
  and   bs.bck_type != 'L'                      -- ignore archivelog backups
  and   (bs.site_key IS NULL         OR         -- always return null site_key
         user_site_key = bs.site_key OR         -- user interested in one site
         (user_site_key IS NULL AND             -- return rows per access attr
          (disk_backups_shared = TRUE# OR
           tape_backups_shared = TRUE# OR
           this_site_key = bs.site_key)))
 
  union all
 
--
 
  select 1,
         file#, OFFLINE_RANGE, online_change#, online_time,
         resetlogs_change#, resetlogs_time, offline_change#, 0,
         recid, stamp, null, 0, 0, 0, online_time, null
  from rc_offline_range ofr
  where ofr.db_key = this_db_key
 
--
--
 
  order by 2 asc,  -- file#
           4 desc, -- checkpoint_change#
           1 asc,  -- preference
          15 desc; -- completion_time, to break ties if all else is equal
 
--
--
--
--
CURSOR translateDatabaseCorruption_c(dfnumber IN number)
IS
   SELECT file#, block#, blocks
     FROM rc_database_block_corruption bc
    WHERE bc.db_key = this_db_key AND           -- belongs to this database
          bc.dbinc_key = this_dbinc_key AND
          bc.file# = nvl(translateDatabaseCorruption_c.dfnumber, bc.file#) AND
          bc.corruption_type != 'NOLOGGING'
    ORDER BY file#, block#;   -- order same as in translateCorruptList_c.
--
--
--
 
 
--
--
--
 
CURSOR cntConfig_c
IS
   SELECT COUNT(*) FROM CONF
   WHERE db_key         = this_db_key
   AND   db_unique_name = nvl(user_db_unique_name, this_db_unique_name);
 
CURSOR getPrimarySite_c
IS
   SELECT db_unique_name FROM NODE
   WHERE db_key        = this_db_key
   AND   database_role = 'PRIMARY';
 
CURSOR findConfig_c(
   name varchar2,
   value varchar2,
   db_unique_name varchar2)
IS
    SELECT conf#, name, value
    FROM   rc_rman_configuration rm
    WHERE  db_key = this_db_key                  -- part of this database
    AND    (findConfig_c.name is null OR
            UPPER(findConfig_c.name) = UPPER(rm.name)) AND
           (findConfig_c.value is null OR
            UPPER(findConfig_c.value) = UPPER(rm.value)) AND
--
           ((nvl(findConfig_c.db_unique_name, rm.db_unique_name) =
             rm.db_unique_name) OR
            rm.db_unique_name IS NULL)                  -- generic conf rows
    ORDER BY conf#;
--
--
 
--
--
--
 
getLastBackupHistory bhistoryRec_t;
 
--
CURSOR dfBackupHistory_c1(
   file#       IN   number
  ,crescn      IN   number
  ,device_type IN   varchar2)
RETURN bhistoryRec_t IS
   SELECT
      bdf.file#                dfNumber,
      bdf.create_scn           create_scn,
      dbinc.reset_scn          reset_scn,
      dbinc.reset_time         reset_time,
      bdf.ckp_scn              ckp_scn,
      bdf.ckp_time             ckp_time,
      nvl(df.stop_scn, 0)      stop_scn,
      to_number(null)          logThread,
      to_number(null)          logSequence,
      to_number(null)          setStamp,
      to_number(null)          setCount,
      bs.completion_time       compTime,
      0                        nbackups,
      to_char(null)            logTerminal,
      to_number(null)          next_scn,
      0                        pluggedRonly,
      0                        pluginSCN,
      0                        pluginRlgSCN,
      to_date(null)            pluginRlgTime,
      to_number(null)          newcreate_scn,
      to_number(null)          newreset_scn,
      to_date(null)            newreset_time
   FROM bdf,
        dbinc,
        rci_pdbinc_this_dbinc pdbinc,
        (SELECT /*+no_merge*/ file#, create_scn, stop_scn, pdbinc_key
           FROM df
          WHERE create_scn = dfBackupHistory_c1.crescn
            AND file#      = dfBackupHistory_c1.file#
            AND dbinc_key  = this_dbinc_key) df,
        (SELECT bs.bs_key,
                bs.completion_time
           FROM bs, bp
          WHERE bp.status    = 'A'               -- only available pieces
            AND bs.bck_type  != 'L'              -- ignore al backups
            AND bs.bs_key    = bp.bs_key         -- join bs, bp
            AND bs.db_key    = this_db_key       -- this database
            AND bp.db_key    = this_db_key       -- this database
            AND (dfBackupHistory_c1.device_type IS NULL OR
                 dfBackupHistory_c1.device_type = bp.device_type)
            AND ((user_site_key = bp.site_key) OR
                 (user_site_key IS NULL AND
                  ((disk_backups_shared = TRUE# AND bp.device_type = 'DISK') OR
                   (tape_backups_shared = TRUE# AND bp.device_type <>'DISK') OR
                   (this_site_key = nvl(bp.site_key, this_site_key)))))
        GROUP BY bs.bs_key, bp.device_type, bp.copy#,
                 bs.pieces, bs.completion_time
          HAVING count(distinct bp.piece#) = bs.pieces) bs
   WHERE bdf.dbinc_key    = dbinc.dbinc_key       -- join dbinc, bdf
     AND dbinc.db_key     = this_db_key           -- this database
     AND bdf.create_scn   = df.create_scn         -- create scn match
     AND bdf.file#        = df.file#              -- join bdf, df
     AND bdf.bs_key       = bs.bs_key             -- join bdf, bs
     AND df.pdbinc_key    = pdbinc.pdbinc_key
     AND pdbinc.dbinc_key = this_dbinc_key
     AND bdf.ckp_scn NOT BETWEEN                 -- filter out orphan backups
         pdbinc.next_inc_scn AND pdbinc.next_end_reset_scn
 
   UNION ALL
 
   SELECT
      cdf.file#                dfNumber,
      cdf.create_scn           create_scn,
      dbinc.reset_scn          reset_scn,
      dbinc.reset_time         reset_time,
      cdf.ckp_scn              ckp_scn,
      cdf.ckp_time             ckp_time,
      nvl(df.stop_scn, 0)      stop_scn,
      to_number(null)          logThread,
      to_number(null)          logSequence,
      to_number(null)          setStamp,
      to_number(null)          setCount,
      cdf.completion_time      compTime,
      0                        nbackups,
      to_char(null)            logTerminal,
      to_number(null)          next_scn,
      0                        pluggedRonly,
      0                        pluginSCN,
      0                        pluginRlgSCN,
      to_date(null)            pluginRlgTime,
      to_number(null)          newcreate_scn,
      to_number(null)          newreset_scn,
      to_date(null)            newreset_time
   FROM cdf,
        dbinc,
        rci_pdbinc_this_dbinc pdbinc,
        (SELECT /*+no_merge */ file#, create_scn, stop_scn, pdbinc_key
           FROM df
          WHERE create_scn = dfBackupHistory_c1.crescn
            AND file#      = dfBackupHistory_c1.file#
            AND dbinc_key  = this_dbinc_key) df
   WHERE cdf.dbinc_key   = dbinc.dbinc_key       -- join dbinc, cdf
     AND dbinc.db_key    = this_db_key           -- this database
     AND cdf.create_scn  = df.create_scn         -- create scn match
     AND cdf.file#       = df.file#              -- join cdf, df
     AND cdf.status      = 'A'                   -- available copy
     AND (dfBackupHistory_c1.device_type IS NULL OR
          dfBackupHistory_c1.device_type = 'DISK')
     AND ((user_site_key = cdf.site_key) OR
          (user_site_key IS NULL AND
           ((disk_backups_shared = TRUE#) OR
            (this_site_key = nvl(cdf.site_key, this_site_key)))))
     AND df.pdbinc_key    = pdbinc.pdbinc_key
     AND pdbinc.dbinc_key = dbinc.dbinc_key
     AND pdbinc.dbinc_key = this_dbinc_key
     AND cdf.ckp_scn NOT BETWEEN                 -- filter out orphan backups
         pdbinc.next_inc_scn AND pdbinc.next_end_reset_scn
 
   UNION ALL
 
   SELECT
      xdf.file#                dfNumber,
      xdf.create_scn           create_scn,
      dbinc.reset_scn          reset_scn,
      dbinc.reset_time         reset_time,
      xdf.ckp_scn              ckp_scn,
      xdf.ckp_time             ckp_time,
      nvl(df.stop_scn, 0)      stop_scn,
      to_number(null)          logThread,
      to_number(null)          logSequence,
      to_number(null)          setStamp,
      to_number(null)          setCount,
      xdf.completion_time      compTime,
      0                        nbackups,
      to_char(null)            logTerminal,
      to_number(null)          next_scn,
      0                        pluggedRonly,
      0                        pluginSCN,
      0                        pluginRlgSCN,
      to_date(null)            pluginRlgTime,
      to_number(null)          newcreate_scn,
      to_number(null)          newreset_scn,
      to_date(null)            newreset_time
   FROM xdf,
        dbinc,
        rci_pdbinc_this_dbinc pdbinc,
        (SELECT /*+no_merge*/ file#, create_scn, stop_scn, pdbinc_key
           FROM df
          WHERE create_scn = dfBackupHistory_c1.crescn
            AND file#      = dfBackupHistory_c1.file#
            AND dbinc_key  = this_dbinc_key) df
   WHERE xdf.dbinc_key   = dbinc.dbinc_key       -- join xdf, dbinc
     AND dbinc.db_key    = this_db_key           -- this database
     AND xdf.create_scn  = df.create_scn         -- create scn match
     AND xdf.file#       = df.file#              -- join xdf, df
     AND xdf.status      = 'A'                   -- available proxy df
     AND (dfBackupHistory_c1.device_type IS NULL OR
          dfBackupHistory_c1.device_type = xdf.device_type)
     AND ((user_site_key  = xdf.site_key) OR
          (user_site_key IS NULL AND
           ((tape_backups_shared = TRUE#) OR
            (this_site_key = nvl(xdf.site_key, this_site_key)))))
     AND df.pdbinc_key    = pdbinc.pdbinc_key
     AND pdbinc.dbinc_key = this_dbinc_key
     AND xdf.ckp_scn NOT BETWEEN                 -- filter out orphan backups
         pdbinc.next_inc_scn AND pdbinc.next_end_reset_scn
 
--
   ORDER BY  dfNumber,
             create_scn,
             reset_scn,
             reset_time,
             ckp_scn  desc,
             stop_scn desc,
             compTime;
 
CURSOR dfBackupHistory_c2(
   device_type  IN varchar2
  ,cmd          IN varchar2
  ,ktag         IN varchar2
  ,pattern1     IN varchar2
  ,pattern2     IN varchar2
  ,pattern3     IN varchar2
  ,pattern4     IN varchar2)
RETURN bhistoryRec_t IS
   SELECT
      bdf.file#                dfNumber,
      bdf.create_scn           create_scn,
      dbinc.reset_scn          reset_scn,
      dbinc.reset_time         reset_time,
      bdf.ckp_scn              ckp_scn,
      bdf.ckp_time             ckp_time,
      nvl(df.stop_scn, 0)      stop_scn,
      to_number(null)          logThread,
      to_number(null)          logSequence,
      to_number(null)          setStamp,
      to_number(null)          setCount,
      bs.completion_time       compTime,
      0                        nbackups,
      to_char(null)            logTerminal,
      to_number(null)          next_scn,
      decode(bdf.plugged_readonly, 'YES', 1, 0)
                               pluggedRonly,
      bdf.plugin_scn           pluginSCN,
      bdf.plugin_reset_scn     pluginRlgSCN,
      bdf.plugin_reset_time    pluginRlgTime,
      decode(bdf.plugin_scn, 0,
             bdf.create_scn, bdf.plugin_scn)
                               newcreate_scn,
      decode(bdf.plugin_reset_scn, 0,
             dbinc.reset_scn, bdf.plugin_reset_scn)
                               newreset_scn,
      nvl(bdf.plugin_reset_time, dbinc.reset_time)
                               newreset_time
   FROM bdf,
        dbinc,
        df,
        rci_pdbinc_this_dbinc pdbinc,
        (SELECT bs.bs_key,
                bs.completion_time
           FROM bs, bp
          WHERE bp.status    = 'A'               -- only available pieces
            AND bs.bck_type  != 'L'              -- ignore al backups
            AND bs.bs_key    = bp.bs_key         -- join bs, bp
            AND bs.db_key    = this_db_key       -- this database
            AND bp.db_key    = this_db_key       -- this database
            AND ((user_site_key = bp.site_key) OR
                 (user_site_key IS NULL AND
                  ((disk_backups_shared = TRUE# AND bp.device_type = 'DISK') OR
                   (tape_backups_shared = TRUE# AND bp.device_type <>'DISK') OR
                   (this_site_key = nvl(bp.site_key, this_site_key)))))
            AND (dfBackupHistory_c2.cmd is null OR       -- bug 6658764
                 dfBackupHistory_c2.cmd != 'B' OR
                 (dfBackupHistory_c2.cmd = 'B' AND       -- Backup command and
                  (dfBackupHistory_c2.ktag is null AND   -- nokeep cmd matches
                   bs.keep_options = 0) OR               -- nokeep backup or
                  (dfBackupHistory_c2.ktag = bp.tag and  -- keep backup cmd tag
                   bs.keep_options != 0)))               -- matches keep backup
            AND (dfBackupHistory_c2.device_type IS NULL OR
                 dfBackupHistory_c2.device_type = bp.device_type)
            AND ((dfBackupHistory_c2.pattern1 IS NULL AND
                  dfBackupHistory_c2.pattern2 IS NULL AND
                  dfBackupHistory_c2.pattern3 IS NULL AND
                  dfBackupHistory_c2.pattern4 IS NULL) OR
                 (bp.handle LIKE dfBackupHistory_c2.pattern1 OR
                  bp.handle LIKE dfBackupHistory_c2.pattern2 OR
                  bp.handle LIKE dfBackupHistory_c2.pattern3 OR
                  bp.handle LIKE dfBackupHistory_c2.pattern4))
        GROUP BY bs.bs_key, bp.device_type, bp.copy#,
                 bs.pieces, bs.completion_time
          HAVING count(distinct bp.piece#) = bs.pieces) bs
   WHERE bdf.dbinc_key   = dbinc.dbinc_key       -- join dbinc, bdf
     AND dbinc.db_key    = this_db_key           -- this database
     AND df.dbinc_key    = this_dbinc_key        -- this incarnation
     AND ((df.plugin_scn = 0  AND                -- create/plugin scn match
           bdf.plugin_scn = 0 AND
           bdf.create_scn = df.create_scn) OR
          (df.plugin_scn != 0 AND
           bdf.plugin_scn = df.plugin_scn))
     AND bdf.file#       = df.file#              -- join bdf, df
     AND bdf.bs_key      = bs.bs_key             -- join bdf, bs
     AND (tc_database = TRUE# OR isTranslatedFno(df.file#) = TRUE#)
     AND df.pdbinc_key    = pdbinc.pdbinc_key
     AND pdbinc.dbinc_key = this_dbinc_key
     AND bdf.ckp_scn NOT BETWEEN                 -- filter out orphan backups
         pdbinc.next_inc_scn AND pdbinc.next_end_reset_scn
 
   UNION ALL
 
   SELECT
      cdf.file#                dfNumber,
      cdf.create_scn           create_scn,
      dbinc.reset_scn          reset_scn,
      dbinc.reset_time         reset_time,
      cdf.ckp_scn              ckp_scn,
      cdf.ckp_time             ckp_time,
      nvl(df.stop_scn, 0)      stop_scn,
      to_number(null)          logThread,
      to_number(null)          logSequence,
      to_number(null)          setStamp,
      to_number(null)          setCount,
      cdf.completion_time      compTime,
      0                        nbackups,
      to_char(null)            logTerminal,
      to_number(null)          next_scn,
      decode(cdf.plugged_readonly, 'YES', 1, 0)
                               pluggedRonly,
      cdf.plugin_scn           pluginSCN,
      cdf.plugin_reset_scn     pluginRlgSCN,
      cdf.plugin_reset_time    pluginRlgTime,
      decode(cdf.plugin_scn, 0,
             cdf.create_scn, cdf.plugin_scn)
                               newcreate_scn,
      decode(cdf.plugin_reset_scn, 0,
             dbinc.reset_scn, cdf.plugin_reset_scn)
                               newreset_scn,
      nvl(cdf.plugin_reset_time, dbinc.reset_time)
                               newreset_time
   FROM cdf,
        dbinc,
        df,
        rci_pdbinc_this_dbinc pdbinc
   WHERE cdf.dbinc_key   = dbinc.dbinc_key       -- join dbinc, cdf
     AND dbinc.db_key    = this_db_key           -- this database
     AND df.dbinc_key    = this_dbinc_key        -- this incarnation
     AND ((df.plugin_scn = 0  AND                -- create/plugin scn match
           cdf.plugin_scn = 0 AND
           cdf.create_scn = df.create_scn) OR
          (df.plugin_scn != 0 AND
           cdf.plugin_scn = df.plugin_scn))
     AND cdf.file#       = df.file#              -- join cdf, df
     AND cdf.status      = 'A'                   -- available copy
     AND (tc_database = TRUE# OR isTranslatedFno(df.file#) = TRUE#)
     AND (dfBackupHistory_c2.cmd is null OR        -- bug 6658764
          dfBackupHistory_c2.cmd != 'B' OR
          (dfBackupHistory_c2.cmd = 'B' AND        -- Backup command and
           (dfBackupHistory_c2.ktag is null AND    -- nokeep cmd matches
            cdf.keep_options = 0) OR               -- nokeep backup or
           (dfBackupHistory_c2.ktag = cdf.tag and  -- keep backup cmd tag
            cdf.keep_options != 0)))               -- matches keep backup
     AND (dfBackupHistory_c2.device_type IS NULL OR
          dfBackupHistory_c2.device_type = 'DISK')
     AND ((dfBackupHistory_c2.pattern1 IS NULL AND
           dfBackupHistory_c2.pattern2 IS NULL AND
           dfBackupHistory_c2.pattern3 IS NULL AND
           dfBackupHistory_c2.pattern4 IS NULL) OR
          (cdf.fname LIKE dfBackupHistory_c2.pattern1 OR
           cdf.fname LIKE dfBackupHistory_c2.pattern2 OR
           cdf.fname LIKE dfBackupHistory_c2.pattern3 OR
           cdf.fname LIKE dfBackupHistory_c2.pattern4))
     AND ((user_site_key = cdf.site_key) OR
          (user_site_key IS NULL AND
           ((disk_backups_shared = TRUE#) OR
            (this_site_key = nvl(cdf.site_key, this_site_key)))))
     AND df.pdbinc_key    = pdbinc.pdbinc_key
     AND pdbinc.dbinc_key = this_dbinc_key
     AND cdf.ckp_scn NOT BETWEEN                   -- filter out orphan backups
         pdbinc.next_inc_scn AND pdbinc.next_end_reset_scn
 
   UNION ALL
 
   SELECT
      xdf.file#                dfNumber,
      xdf.create_scn           create_scn,
      dbinc.reset_scn          reset_scn,
      dbinc.reset_time         reset_time,
      xdf.ckp_scn              ckp_scn,
      xdf.ckp_time             ckp_time,
      nvl(df.stop_scn, 0)      stop_scn,
      to_number(null)          logThread,
      to_number(null)          logSequence,
      to_number(null)          setStamp,
      to_number(null)          setCount,
      xdf.completion_time      compTime,
      0                        nbackups,
      to_char(null)            logTerminal,
      to_number(null)          next_scn,
      decode(xdf.plugged_readonly, 'YES', 1, 0)
                               pluggedRonly,
      xdf.plugin_scn           pluginSCN,
      xdf.plugin_reset_scn     pluginRlgSCN,
      xdf.plugin_reset_time    pluginRlgTime,
      decode(xdf.plugin_scn, 0,
             xdf.create_scn, xdf.plugin_scn)
                               newcreate_scn,
      decode(xdf.plugin_reset_scn, 0,
             dbinc.reset_scn, xdf.plugin_reset_scn)
                               newreset_scn,
      nvl(xdf.plugin_reset_time, dbinc.reset_time)
                               newreset_time
   FROM xdf,
        dbinc,
        df,
        rci_pdbinc_this_dbinc pdbinc
   WHERE xdf.dbinc_key   = dbinc.dbinc_key       -- join xdf, dbinc
     AND dbinc.db_key    = this_db_key           -- this database
     AND df.dbinc_key    = this_dbinc_key        -- this incarnation
     AND ((df.plugin_scn = 0  AND                -- create/plugin scn match
           xdf.plugin_scn = 0 AND
           xdf.create_scn = df.create_scn) OR
          (df.plugin_scn != 0 AND
           xdf.plugin_scn = df.plugin_scn))
     AND xdf.file#       = df.file#              -- join xdf, df
     AND xdf.status      = 'A'                   -- available proxy df
     AND (tc_database = TRUE# OR isTranslatedFno(df.file#) = TRUE#)
     AND (dfBackupHistory_c2.cmd is null OR        -- bug 6658764
          dfBackupHistory_c2.cmd != 'B' OR
          (dfBackupHistory_c2.cmd = 'B' AND        -- Backup command and
           (dfBackupHistory_c2.ktag is null AND    -- nokeep cmd matches
            xdf.keep_options = 0) OR               -- nokeep backup or
           (dfBackupHistory_c2.ktag = xdf.tag and  -- keep backup cmd tag
            xdf.keep_options != 0)))               -- matches keep backup
     AND (dfBackupHistory_c2.device_type IS NULL OR
          dfBackupHistory_c2.device_type = xdf.device_type)
     AND ((dfBackupHistory_c2.pattern1 IS NULL AND
           dfBackupHistory_c2.pattern2 IS NULL AND
           dfBackupHistory_c2.pattern3 IS NULL AND
           dfBackupHistory_c2.pattern4 IS NULL) OR
          (xdf.handle LIKE dfBackupHistory_c2.pattern1 OR
           xdf.handle LIKE dfBackupHistory_c2.pattern2 OR
           xdf.handle LIKE dfBackupHistory_c2.pattern3 OR
           xdf.handle LIKE dfBackupHistory_c2.pattern4))
     AND ((user_site_key  = xdf.site_key) OR
          (user_site_key IS NULL AND
           ((tape_backups_shared = TRUE#) OR
            (this_site_key = nvl(xdf.site_key, this_site_key)))))
     AND df.pdbinc_key    = pdbinc.pdbinc_key
     AND pdbinc.dbinc_key = this_dbinc_key
     AND xdf.ckp_scn NOT BETWEEN                  -- filter out orphan backups
         pdbinc.next_inc_scn AND pdbinc.next_end_reset_scn
 
--
   ORDER BY  dfNumber,
             newcreate_scn,
             newreset_scn,
             newreset_time,
             ckp_scn desc,
             stop_scn desc,
             compTime desc;  --bug 8412297
 
CURSOR dcBackupHistory_c(
   device_type    IN varchar2
  ,cmd            IN varchar2
  ,ktag           IN varchar2
  ,pattern1       IN varchar2
  ,pattern2       IN varchar2
  ,pattern3       IN varchar2
  ,pattern4       IN varchar2
  ,backedUpAnyScn IN number)
RETURN bhistoryRec_t IS
WITH
my_dbinc AS
   (SELECT db_key, 
           dbinc_key, 
           reset_scn,
           reset_time, 
           PRIOR reset_scn next_reset_scn
    FROM dbinc START WITH dbinc_key = this_dbinc_key
    CONNECT BY PRIOR parent_dbinc_key = dbinc_key
    UNION ALL
    SELECT this_dbinc_key dbinc_key,
           null           db_key,
           null           reset_scn,
           null           reset_time,
           null           next_reset_scn
    FROM dual)
   SELECT
      bdf.file#                dfNumber,
      bdf.create_scn           create_scn,
      dbinc.reset_scn          reset_scn,
      dbinc.reset_time         reset_time,
      bdf.ckp_scn              ckp_scn,
      bdf.ckp_time             ckp_time,
      cdf.ckp_scn              stop_scn,
      to_number(null)          logThread,
      to_number(null)          logSequence,
      to_number(null)          setStamp,
      to_number(null)          setCount,
      bs.completion_time       compTime,
      0                        nbackups,
      to_char(null)            logTerminal,
      to_number(null)          next_scn,
      decode(bdf.plugged_readonly, 'YES', 1, 0)
                               pluggedRonly,
      bdf.plugin_scn           pluginSCN,
      bdf.plugin_reset_scn     pluginRlgSCN,
      bdf.plugin_reset_time    pluginRlgTime,
      decode(bdf.plugin_scn, 0,
             bdf.create_scn, bdf.plugin_scn)
                               newcreate_scn,
      decode(bdf.plugin_reset_scn, 0,
             dbinc.reset_scn, bdf.plugin_reset_scn)
                               newreset_scn,
      nvl(bdf.plugin_reset_time, dbinc.reset_time)
                               newreset_time
   FROM bdf,
        my_dbinc dbinc,
        (SELECT DISTINCT
                cdf.file#, cdf.create_scn, cdf.plugin_scn,
                cdf.plugged_readonly, cdf.ckp_scn, cdf.ckp_time, cdf.dbinc_key,
                cdf.abs_fuzzy_scn
           FROM cdf, my_dbinc dbinc
          WHERE cdf.dbinc_key = dbinc.dbinc_key
            AND dbinc.db_key  = this_db_key
            AND ((user_site_key = cdf.site_key) OR
                 (user_site_key IS NULL AND
                  ((disk_backups_shared = TRUE#) OR
                   (this_site_key = nvl(cdf.site_key, this_site_key)))))
            AND cdf.status    = 'A'
            AND (dcBackupHistory_c.backedUpAnyScn = FALSE# OR
                 (dcBackupHistory_c.backedUpAnyScn = TRUE# AND
                  cdf.file# >0 AND
                  (dbinc.next_reset_scn IS NULL OR
                   cdf.abs_fuzzy_scn <= dbinc.next_reset_scn)))) cdf,
        (SELECT bs.bs_key,
                bs.completion_time
           FROM bs, bp
          WHERE bp.status    = 'A'               -- only available pieces
            AND bs.bck_type  != 'L'              -- ignore al backups
            AND bs.bs_key    = bp.bs_key         -- join bs, bp
            AND bs.db_key    = this_db_key       -- this database
            AND bp.db_key    = this_db_key       -- this database
            AND (dcBackupHistory_c.cmd is null OR       -- bug 6658764
                 dcBackupHistory_c.cmd != 'B' OR
                 (dcBackupHistory_c.cmd = 'B' AND       -- Backup command and
                  (dcBackupHistory_c.ktag is null AND   -- nokeep cmd matches
                   bs.keep_options = 0) OR              -- nokeep backup or
                  (dcBackupHistory_c.ktag = bp.tag and  -- keep backup cmd tag
                   bs.keep_options != 0)))              -- matches keep backup
            AND (dcBackupHistory_c.device_type IS NULL OR
                 dcBackupHistory_c.device_type = bp.device_type)
            AND ((dcBackupHistory_c.pattern1 IS NULL AND
                  dcBackupHistory_c.pattern2 IS NULL AND
                  dcBackupHistory_c.pattern3 IS NULL AND
                  dcBackupHistory_c.pattern4 IS NULL) OR
                 (bp.handle LIKE dcBackupHistory_c.pattern1 OR
                  bp.handle LIKE dcBackupHistory_c.pattern2 OR
                  bp.handle LIKE dcBackupHistory_c.pattern3 OR
                  bp.handle LIKE dcBackupHistory_c.pattern4))
            AND ((user_site_key = bp.site_key) OR
                 (user_site_key IS NULL AND
                  ((disk_backups_shared = TRUE# AND bp.device_type = 'DISK') OR
                   (tape_backups_shared = TRUE# AND bp.device_type <>'DISK') OR
                   (this_site_key = nvl(bp.site_key, this_site_key)))))
        GROUP BY bs.bs_key, bp.device_type, bp.copy#,
                 bs.pieces, bs.completion_time
          HAVING count(distinct bp.piece#) = bs.pieces) bs
   WHERE bdf.dbinc_key  = dbinc.dbinc_key       -- join dbinc, bdf
     AND dbinc.db_key   = this_db_key           -- this database (all inc)
     AND cdf.plugin_scn = bdf.plugin_scn
     AND cdf.plugged_readonly = bdf.plugged_readonly
     AND bdf.create_scn = cdf.create_scn        -- create scn match
     AND bdf.file#      = cdf.file#             -- join bdf, cdf
     AND (dcBackupHistory_c.backedUpAnyScn = TRUE# OR
          (bdf.ckp_scn   = cdf.ckp_scn AND 
           bdf.ckp_time  = cdf.ckp_time))
     AND bdf.dbinc_key  = cdf.dbinc_key
     AND (bdf.incr_scn  = 0 OR
          bdf.incr_scn  = cdf.create_scn)       -- full backup
     AND bdf.bs_key     = bs.bs_key             -- join bdf, bs
 
   UNION ALL
 
   SELECT
      0                        dfNumber,
      0                        create_scn,
      dbinc.reset_scn          reset_scn,
      dbinc.reset_time         reset_time,
      bcf.ckp_scn              ckp_scn,
      bcf.ckp_time             ckp_time,
      ccf.ckp_scn              stop_scn,
      to_number(null)          logThread,
      to_number(null)          logSequence,
      to_number(null)          setStamp,
      to_number(null)          setCount,
      bs.completion_time       compTime,
      0                        nbackups,
      to_char(null)            logTerminal,
      to_number(null)          next_scn,
      0                        pluggedRonly,
      0                        pluginSCN,
      0                        pluginRlgSCN,
      to_date(null)            pluginRlgTime,
      0                        newcreate_scn,
      dbinc.reset_scn          newreset_scn,
      dbinc.reset_time         newreset_time
   FROM bcf,
        my_dbinc dbinc,
        (SELECT DISTINCT
                ccf.ckp_scn, ccf.ckp_time, ccf.dbinc_key
           FROM ccf, my_dbinc dbinc
          WHERE ccf.dbinc_key = dbinc.dbinc_key
            AND dbinc.db_key  = this_db_key
            AND ccf.status    = 'A') ccf,
        (SELECT bs.bs_key,
                bs.completion_time
           FROM bs, bp
          WHERE bp.status    = 'A'               -- only available pieces
            AND bs.bck_type  != 'L'              -- ignore al backups
            AND bs.bs_key    = bp.bs_key         -- join bs, bp
            AND bs.db_key    = this_db_key       -- this database
            AND bp.db_key    = this_db_key       -- this database
            AND (dcBackupHistory_c.cmd is null OR       -- bug 6658764
                 dcBackupHistory_c.cmd != 'B' OR
                 (dcBackupHistory_c.cmd = 'B' AND       -- Backup command and
                  (dcBackupHistory_c.ktag is null AND   -- nokeep cmd matches
                   bs.keep_options = 0) OR              -- nokeep backup or
                  (dcBackupHistory_c.ktag = bp.tag and  -- keep backup cmd tag
                   bs.keep_options != 0)))              -- matches keep backup
            AND (dcBackupHistory_c.device_type IS NULL OR
                 dcBackupHistory_c.device_type = bp.device_type)
            AND ((dcBackupHistory_c.pattern1 IS NULL AND
                  dcBackupHistory_c.pattern2 IS NULL AND
                  dcBackupHistory_c.pattern3 IS NULL AND
                  dcBackupHistory_c.pattern4 IS NULL) OR
                 (bp.handle LIKE dcBackupHistory_c.pattern1 OR
                  bp.handle LIKE dcBackupHistory_c.pattern2 OR
                  bp.handle LIKE dcBackupHistory_c.pattern3 OR
                  bp.handle LIKE dcBackupHistory_c.pattern4))
            AND ((user_site_key = bp.site_key) OR
                 (user_site_key IS NULL AND
                  ((disk_backups_shared = TRUE# AND bp.device_type = 'DISK') OR
                   (tape_backups_shared = TRUE# AND bp.device_type <>'DISK') OR
                   (this_site_key = nvl(bp.site_key, this_site_key)))))
        GROUP BY bs.bs_key, bp.device_type, bp.copy#,
                 bs.pieces, bs.completion_time
          HAVING count(distinct bp.piece#) = bs.pieces) bs
   WHERE bcf.dbinc_key  = dbinc.dbinc_key       -- join dbinc, bcf
     AND dbinc.db_key   = this_db_key           -- this database (all inc)
     AND bcf.ckp_scn    = ccf.ckp_scn
     AND bcf.ckp_time   = ccf.ckp_time
     AND bcf.dbinc_key  = ccf.dbinc_key
     AND bcf.bs_key     = bs.bs_key             -- join bcf, bs
 
   UNION ALL
 
   SELECT
      cdf.file#                dfNumber,
      cdf.create_scn           create_scn,
      dbinc.reset_scn          reset_scn,
      dbinc.reset_time         reset_time,
      cdf.ckp_scn              ckp_scn,
      cdf.ckp_time             ckp_time,
      cdf.ckp_scn              stop_scn,
      to_number(null)          logThread,
      to_number(null)          logSequence,
      to_number(null)          setStamp,
      to_number(null)          setCount,
      cdf.completion_time      compTime,
      0                        nbackups,
      to_char(null)            logTerminal,
      to_number(null)          next_scn,
      decode(cdf.plugged_readonly, 'YES', 1, 0)
                                pluggedRonly,
      cdf.plugin_scn            pluginSCN,
      cdf.plugin_reset_scn      pluginRlgSCN,
      cdf.plugin_reset_time     pluginRlgTime,
      decode(cdf.plugin_scn, 0,
             cdf.create_scn, cdf.plugin_scn)
                                newcreate_scn,
      decode(cdf.plugin_reset_scn, 0,
             dbinc.reset_scn, cdf.plugin_reset_scn)
                                newreset_scn,
      nvl(cdf.plugin_reset_time, dbinc.reset_time)
                                newreset_time
   FROM cdf, my_dbinc dbinc
   WHERE cdf.dbinc_key   = dbinc.dbinc_key        -- join xdf, dbinc
     AND dbinc.db_key    = this_db_key            -- this database (all inc)
     AND cdf.status      = 'A'                    -- available backup
     AND (dcBackupHistory_c.cmd is null OR        -- bug 6658764
          dcBackupHistory_c.cmd != 'B' OR
          (dcBackupHistory_c.cmd = 'B' AND        -- Backup command and
           (dcBackupHistory_c.ktag is null AND    -- nokeep cmd matches
            cdf.keep_options = 0) OR              -- nokeep backup or
           (dcBackupHistory_c.ktag = cdf.tag and  -- keep backup cmd tag
            cdf.keep_options != 0)))              -- matches keep backup
     AND (dcBackupHistory_c.device_type IS NULL OR
          dcBackupHistory_c.device_type = 'DISK')
     AND (dcBackupHistory_c.pattern1 IS NOT NULL OR
          dcBackupHistory_c.pattern2 IS NOT NULL OR
          dcBackupHistory_c.pattern3 IS NOT NULL OR
          dcBackupHistory_c.pattern4 IS NOT NULL)
     AND (cdf.fname LIKE dcBackupHistory_c.pattern1 OR
          cdf.fname LIKE dcBackupHistory_c.pattern2 OR
          cdf.fname LIKE dcBackupHistory_c.pattern3 OR
          cdf.fname LIKE dcBackupHistory_c.pattern4)
     AND ((user_site_key  = cdf.site_key) OR
          (user_site_key IS NULL AND
           ((tape_backups_shared = TRUE#) OR
            (this_site_key = nvl(cdf.site_key, this_site_key)))))
 
   UNION ALL
 
   SELECT
      xdf.file#                dfNumber,
      xdf.create_scn           create_scn,
      dbinc.reset_scn          reset_scn,
      dbinc.reset_time         reset_time,
      xdf.ckp_scn              ckp_scn,
      xdf.ckp_time             ckp_time,
      cdf.ckp_scn              stop_scn,
      to_number(null)          logThread,
      to_number(null)          logSequence,
      to_number(null)          setStamp,
      to_number(null)          setCount,
      xdf.completion_time      compTime,
      0                        nbackups,
      to_char(null)            logTerminal,
      to_number(null)          next_scn,
      decode(xdf.plugged_readonly, 'YES', 1, 0)
                                pluggedRonly,
      xdf.plugin_scn            pluginSCN,
      xdf.plugin_reset_scn      pluginRlgSCN,
      xdf.plugin_reset_time     pluginRlgTime,
      decode(xdf.plugin_scn, 0,
             xdf.create_scn, xdf.plugin_scn)
                                newcreate_scn,
      decode(xdf.plugin_reset_scn, 0,
             dbinc.reset_scn, xdf.plugin_reset_scn)
                                newreset_scn,
      nvl(xdf.plugin_reset_time, dbinc.reset_time)
                                newreset_time
   FROM xdf,
        dbinc,
        (SELECT DISTINCT
                cdf.file#, cdf.create_scn, cdf.plugin_scn,
                cdf.plugged_readonly, cdf.ckp_scn, cdf.ckp_time, cdf.dbinc_key,
                cdf.abs_fuzzy_scn
           FROM cdf, my_dbinc dbinc
         WHERE cdf.dbinc_key  = dbinc.dbinc_key
            AND dbinc.db_key  = this_db_key
            AND cdf.status    = 'A'
            AND (dcBackupHistory_c.backedUpAnyScn = FALSE# OR
                 (dcBackupHistory_c.backedUpAnyScn = TRUE# AND
                  cdf.file# > 0 AND
                  (dbinc.next_reset_scn IS NULL OR
                   cdf.abs_fuzzy_scn <= dbinc.next_reset_scn)))) cdf
   WHERE xdf.dbinc_key   = dbinc.dbinc_key         -- join xdf, dbinc
     AND dbinc.db_key    = this_db_key             -- this database (all inc)
     AND xdf.file#       = cdf.file#               -- join xdf, cdf
     AND xdf.plugged_readonly = cdf.plugged_readonly
     AND xdf.plugin_scn  = cdf.plugin_scn
     AND xdf.create_scn  = cdf.create_scn          -- create scn match
     AND xdf.dbinc_key   = cdf.dbinc_key
     AND (dcBackupHistory_c.backedUpAnyScn = TRUE# OR
          (xdf.ckp_scn   = cdf.ckp_scn AND
           xdf.ckp_time  = cdf.ckp_time))
     AND xdf.status      = 'A'                    -- available proxy df
     AND (dcBackupHistory_c.cmd is null OR        -- bug 6658764
          dcBackupHistory_c.cmd != 'B' OR
          (dcBackupHistory_c.cmd = 'B' AND        -- Backup command and
           (dcBackupHistory_c.ktag is null AND    -- nokeep cmd matches
            xdf.keep_options = 0) OR              -- nokeep backup or
           (dcBackupHistory_c.ktag = xdf.tag and  -- keep backup cmd tag
            xdf.keep_options != 0)))              -- matches keep backup
     AND (dcBackupHistory_c.device_type IS NULL OR
          dcBackupHistory_c.device_type = xdf.device_type)
     AND ((dcBackupHistory_c.pattern1 IS NULL AND
           dcBackupHistory_c.pattern2 IS NULL AND
           dcBackupHistory_c.pattern3 IS NULL AND
           dcBackupHistory_c.pattern4 IS NULL) OR
          (xdf.handle LIKE dcBackupHistory_c.pattern1 OR
           xdf.handle LIKE dcBackupHistory_c.pattern2 OR
           xdf.handle LIKE dcBackupHistory_c.pattern3 OR
           xdf.handle LIKE dcBackupHistory_c.pattern4))
     AND ((user_site_key  = xdf.site_key) OR
          (user_site_key IS NULL AND
           ((tape_backups_shared = TRUE#) OR
            (this_site_key = nvl(xdf.site_key, this_site_key)))))
--
   ORDER BY  dfNumber,
             newcreate_scn,
             newreset_scn,
             newreset_time,
             ckp_scn         desc,
             stop_scn        desc,
             compTime;
 
--
CURSOR alBackupHistory_c1(
   thread#     IN number,
   sequence#   IN number,
   device_type IN varchar2)
RETURN bhistoryRec_t IS
   SELECT
      to_number(null)          dfNumber,
      to_number(null)          create_scn,
      dbinc.reset_scn          reset_scn,
      dbinc.reset_time         reset_time,
      to_number(null)          ckp_scn,
      to_date(null)            ckp_time,
      to_number(null)          stop_scn,
      brl.thread#              logThread,
      brl.sequence#            logSequence,
      to_number(null)          setStamp,
      to_number(null)          setCount,
      bs.completion_time       compTime,
      0                        nbackups,
      brl.terminal             logTerminal,
      brl.next_scn             next_scn,
      0                        pluggedRonly,
      0                        pluginSCN,
      0                        pluginRlgSCN,
      to_date(null)            pluginRlgTime,
      to_number(null)          newcreate_scn,
      to_number(null)          newreset_scn,
      to_date(null)            newreset_time
   FROM brl,
        dbinc,
        (SELECT /*+no_merge*/ DISTINCT thread#, sequence#
           FROM al
          WHERE al.thread#   = alBackupHistory_c1.thread#
            AND al.sequence# = alBackupHistory_c1.sequence#
            AND al.dbinc_key = this_dbinc_key
            AND al.status    = 'A'
            AND al.archived  = 'Y') al,
        (SELECT bs.bs_key,
                bs.completion_time
           FROM bs, bp
          WHERE bp.status    = 'A'               -- only available pieces
            AND bs.bck_type  = 'L'               -- only al backups
            AND bs.bs_key    = bp.bs_key         -- join bs, bp
            AND bs.db_key    = this_db_key       -- this database
            AND bp.db_key    = this_db_key       -- this database
            AND (alBackupHistory_c1.device_type IS NULL OR
                 alBackupHistory_c1.device_type = bp.device_type)
            AND ((user_site_key = bp.site_key) OR
                 (user_site_key IS NULL AND
                  ((disk_backups_shared = TRUE# AND bp.device_type = 'DISK') OR
                   (tape_backups_shared = TRUE# AND bp.device_type <>'DISK') OR
                   (this_site_key = nvl(bp.site_key, this_site_key)))))
        GROUP BY bs.bs_key, bp.device_type, bp.copy#,
                 bs.pieces, bs.completion_time
          HAVING count(distinct bp.piece#) = bs.pieces) bs
   WHERE dbinc.dbinc_key = this_dbinc_key           -- this incarnation
     AND brl.dbinc_key   = dbinc.dbinc_key          -- join brl, dbinc
     AND dbinc.db_key    = this_db_key
     AND brl.thread#     = al.thread#              -- join brl and al
     AND brl.sequence#   = al.sequence#
     AND brl.dbinc_key   = this_dbinc_key
     AND brl.bs_key      = bs.bs_key               -- join brl,bs
 
   UNION ALL
 
   SELECT
      to_number(null)          dfNumber,
      to_number(null)          crescn,
      dbinc.reset_scn          reset_scn,
      dbinc.reset_time         reset_time,
      to_number(null)          ckp_scn,
      to_date(null)            ckp_time,
      to_number(null)          stop_scn,
      xal.thread#              logThread,
      xal.sequence#            logSequence,
      to_number(null)          setStamp,
      to_number(null)          setCount,
      xal.completion_time      compTime,
      0                        nbackups,
      xal.terminal             logTerminal,
      xal.next_scn             next_scn,
      0                        pluggedRonly,
      0                        pluginSCN,
      0                        pluginRlgSCN,
      to_date(null)            pluginRlgTime,
      to_number(null)          newcreate_scn,
      to_number(null)          newreset_scn,
      to_date(null)            newreset_time
   FROM xal,
        dbinc,
        (SELECT /*+no_merge*/ DISTINCT thread#, sequence#
           FROM al
          WHERE al.thread#   = alBackupHistory_c1.thread#
            AND al.sequence# = alBackupHistory_c1.sequence#
            AND al.dbinc_key = this_dbinc_key
            AND al.status    = 'A'
            AND al.archived  = 'Y') al
   WHERE xal.dbinc_key  = dbinc.dbinc_key          -- join xal, dbinc
     AND dbinc.db_key   = this_db_key              -- this database
     AND xal.thread#    = al.thread#
     AND xal.sequence#  = al.sequence#
     AND xal.dbinc_key  = this_dbinc_key
     AND xal.status     = 'A'
     AND (alBackupHistory_c1.device_type IS NULL OR
          alBackupHistory_c1.device_type = xal.device_type)
     AND ((user_site_key  = xal.site_key) OR
          (user_site_key IS NULL AND
           ((tape_backups_shared = TRUE#) OR
            (this_site_key = nvl(xal.site_key, this_site_key)))))
 
--
--
--
   ORDER BY reset_scn,
            reset_time,
            logThread,
            logSequence,
            logTerminal desc,
            compTime;
 
CURSOR alBackupHistory_c2(
   device_type  IN varchar2
  ,cmd          IN varchar2
  ,ktag         IN varchar2
  ,pattern1     IN varchar2
  ,pattern2     IN varchar2
  ,pattern3     IN varchar2
  ,pattern4     IN varchar2)
RETURN bhistoryRec_t IS
   SELECT
      to_number(null)          dfNumber,
      to_number(null)          create_scn,
      dbinc.reset_scn          reset_scn,
      dbinc.reset_time         reset_time,
      to_number(null)          ckp_scn,
      to_date(null)            ckp_time,
      to_number(null)          stop_scn,
      brl.thread#              logThread,
      brl.sequence#            logSequence,
      to_number(null)          setStamp,
      to_number(null)          setCount,
      bs.completion_time       compTime,
      0                        nbackups,
      brl.terminal             logTerminal,
      brl.next_scn             next_scn,
      0                        pluggedRonly,
      0                        pluginSCN,
      0                        pluginRlgSCN,
      to_date(null)            pluginRlgTime,
      to_number(null)          newcreate_scn,
      to_number(null)          newreset_scn,
      to_date(null)            newreset_time
   FROM brl,
        dbinc,
        (SELECT DISTINCT al.thread#, al.sequence#, al.dbinc_key
           FROM al, dbinc
          WHERE dbinc.dbinc_key = al.dbinc_key
            AND dbinc.db_key    = this_db_key
            AND al.status       = 'A'
            AND al.archived     = 'Y'
            AND (tc_thread IS NULL   OR al.thread# = tc_thread)
            AND (tc_fromSeq IS NULL  OR al.sequence# >= tc_fromSeq)
            AND (tc_toSeq IS NULL    OR al.sequence# <= tc_toSeq)
            AND (tc_fromSCN IS NULL  OR al.next_scn > tc_fromSCN)
            AND (tc_toSCN IS NULL    OR al.low_scn < tc_toSCN)
            AND (tc_pattern IS NULL  OR al.fname like tc_pattern)
            AND (tc_fromTime IS NULL OR al.next_time > tc_fromTime)
            AND (tc_toTime IS NULL   OR al.low_time <= tc_toTime)) al,
        (SELECT DISTINCT
                bs.bs_key,
                bs.completion_time
           FROM bs, bp
          WHERE bp.status    = 'A'               -- only available pieces
            AND bs.bck_type  = 'L'               -- only al backups
            AND bs.status    = 'A'               -- available backupset
            AND bs.bs_key    = bp.bs_key         -- join bs, bp
            AND bs.db_key    = this_db_key       -- this database
            AND bp.db_key    = this_db_key       -- this database
            AND (alBackupHistory_c2.cmd is null OR       -- bug 6658764
                 (alBackupHistory_c2.cmd != 'B' AND
                  alBackupHistory_c2.cmd != 'D') OR
                 ((alBackupHistory_c2.cmd = 'B' OR       -- Backup command or
                   alBackupHistory_c2.cmd = 'D') AND     -- Delete command and
                  ((alBackupHistory_c2.ktag is null AND  -- nokeep cmd matches
                    bs.keep_options = 0) OR              -- nokeep backup or
                   (alBackupHistory_c2.ktag = bp.tag AND -- keep backup cmd tag
                    bs.keep_options != 0))))             -- matches keep backup
            AND (alBackupHistory_c2.device_type IS NULL OR
                 alBackupHistory_c2.device_type = bp.device_type)
            AND ((alBackupHistory_c2.pattern1 IS NULL AND
                  alBackupHistory_c2.pattern2 IS NULL AND
                  alBackupHistory_c2.pattern3 IS NULL AND
                  alBackupHistory_c2.pattern4 IS NULL) OR
                 (bp.handle LIKE alBackupHistory_c2.pattern1 OR
                  bp.handle LIKE alBackupHistory_c2.pattern2 OR
                  bp.handle LIKE alBackupHistory_c2.pattern3 OR
                  bp.handle LIKE alBackupHistory_c2.pattern4))
            AND ((user_site_key = bp.site_key) OR
                 (user_site_key IS NULL AND
                  ((disk_backups_shared = TRUE# AND bp.device_type = 'DISK') OR
                   (tape_backups_shared = TRUE# AND bp.device_type <>'DISK') OR
                   (this_site_key = nvl(bp.site_key, this_site_key)))))
        GROUP BY bs.bs_key, bp.device_type, bp.copy#,
                 bs.pieces, bs.completion_time
          HAVING count(distinct bp.piece#) = bs.pieces) bs
   WHERE (canApplyAnyRedo = TRUE# OR dbinc.dbinc_key = this_dbinc_key)
     AND brl.dbinc_key   = dbinc.dbinc_key         -- join brl, dbinc
     AND dbinc.db_key    = this_db_key
     AND brl.thread#     = al.thread#              -- join brl and al
     AND brl.sequence#   = al.sequence#
     AND brl.dbinc_key   = al.dbinc_key
     AND brl.bs_key      = bs.bs_key               -- join brl,bs
 
   UNION ALL
 
   SELECT
      to_number(null)          dfNumber,
      to_number(null)          crescn,
      dbinc.reset_scn          reset_scn,
      dbinc.reset_time         reset_time,
      to_number(null)          ckp_scn,
      to_date(null)            ckp_time,
      to_number(null)          stop_scn,
      xal.thread#              logThread,
      xal.sequence#            logSequence,
      to_number(null)          setStamp,
      to_number(null)          setCount,
      xal.completion_time      compTime,
      0                        nbackups,
      xal.terminal             logTerminal,
      xal.next_scn             next_scn,
      0                        pluggedRonly,
      0                        pluginSCN,
      0                        pluginRlgSCN,
      to_date(null)            pluginRlgTime,
      to_number(null)          newcreate_scn,
      to_number(null)          newreset_scn,
      to_date(null)            newreset_time
   FROM xal,
        dbinc,
        (SELECT DISTINCT al.thread#, al.sequence#, al.dbinc_key
           FROM al, dbinc
          WHERE dbinc.dbinc_key = al.dbinc_key
            AND dbinc.db_key    = this_db_key
            AND al.status       = 'A'
            AND al.archived     = 'Y'
            AND (tc_thread IS NULL   OR al.thread# = tc_thread)
            AND (tc_fromSeq IS NULL  OR al.sequence# >= tc_fromSeq)
            AND (tc_toSeq IS NULL    OR al.sequence# <= tc_toSeq)
            AND (tc_fromSCN IS NULL  OR al.next_scn > tc_fromSCN)
            AND (tc_toSCN IS NULL    OR al.low_scn < tc_toSCN)
            AND (tc_pattern IS NULL  OR al.fname like tc_pattern)
            AND (tc_fromTime IS NULL OR al.next_time > tc_fromTime)
            AND (tc_toTime IS NULL   OR al.low_time <= tc_toTime)) al
   WHERE (canApplyAnyRedo = TRUE# OR dbinc.dbinc_key = this_dbinc_key)
     AND xal.dbinc_key  = dbinc.dbinc_key          -- join xal, dbinc
     AND dbinc.db_key   = this_db_key              -- this database
     AND xal.thread#    = al.thread#
     AND xal.sequence#  = al.sequence#
     AND xal.dbinc_key  = al.dbinc_key
     AND xal.status     = 'A'
     AND (alBackupHistory_c2.cmd is null OR       -- bug 6658764
          (alBackupHistory_c2.cmd != 'B' AND
           alBackupHistory_c2.cmd != 'D') OR
          ((alBackupHistory_c2.cmd = 'B' OR        -- Backup command or
            alBackupHistory_c2.cmd = 'D') AND      -- Delete command and
           ((alBackupHistory_c2.ktag is null AND   -- nokeep cmd matches
             xal.keep_options = 0) OR              -- nokeep backup or
            (alBackupHistory_c2.ktag = xal.tag AND -- keep backup cmd tag
             xal.keep_options != 0))))             -- matches keep backup
     AND (alBackupHistory_c2.device_type IS NULL OR
          alBackupHistory_c2.device_type = xal.device_type)
     AND ((alBackupHistory_c2.pattern1 IS NULL AND
           alBackupHistory_c2.pattern2 IS NULL AND
           alBackupHistory_c2.pattern3 IS NULL AND
           alBackupHistory_c2.pattern4 IS NULL) OR
          (xal.handle LIKE alBackupHistory_c2.pattern1 OR
           xal.handle LIKE alBackupHistory_c2.pattern2 OR
           xal.handle LIKE alBackupHistory_c2.pattern3 OR
           xal.handle LIKE alBackupHistory_c2.pattern4))
     AND ((user_site_key  = xal.site_key) OR
          (user_site_key IS NULL AND
           ((tape_backups_shared = TRUE#) OR
            (this_site_key = nvl(xal.site_key, this_site_key)))))
 
--
--
--
   ORDER BY reset_scn,
            reset_time,
            logThread,
            logSequence,
            logTerminal desc,
            compTime;
 
CURSOR bsBackupHistory_c1(
   set_stamp   IN   number
  ,set_count   IN   number
  ,device_type IN   varchar2
  ,pattern1    IN   varchar2
  ,pattern2    IN   varchar2
  ,pattern3    IN   varchar2
  ,pattern4    IN   varchar2
  )
RETURN bhistoryRec_t IS
   SELECT
      to_number(null)           dfNumber,
      to_number(null)           create_scn,
      to_number(null)           reset_scn,
      to_date(null)             reset_time,
      to_number(null)           ckp_scn,
      to_date(null)             ckp_time,
      to_number(null)           stop_scn,
      to_number(null)           logThread,
      to_number(null)           logSequence,
      bs.set_stamp              setStamp,
      bs.set_count              setCount,
      max(bp.completion_time)   compTime,
      0                         nbackups,
      to_char(null)             logTerminal,
      to_number(null)           next_scn,
      0                         pluggedRonly,
      0                         pluginSCN,
      0                         pluginRlgSCN,
      to_date(null)             pluginRlgTime,
      to_number(null)           newcreate_scn,
      to_number(null)           newreset_scn,
      to_date(null)             newreset_time
     FROM bs,
          bp
     WHERE bs.db_key       = this_db_key             -- this database
       AND bp.bs_key       = bs.bs_key               -- join bs, bp
       AND bs.set_stamp    = bsBackupHistory_c1.set_stamp
       AND bs.set_count    = bsBackupHistory_c1.set_count
       AND bs.status       = 'A'
       AND bp.status      != 'D'
       AND (bsBackupHistory_c1.device_type IS NULL OR
            bsBackupHistory_c1.device_type = bp.device_type)
       AND ((bsBackupHistory_c1.pattern1 IS NULL AND
             bsBackupHistory_c1.pattern2 IS NULL AND
             bsBackupHistory_c1.pattern3 IS NULL AND
             bsBackupHistory_c1.pattern4 IS NULL) OR
            (bp.handle LIKE bsBackupHistory_c1.pattern1 OR
             bp.handle LIKE bsBackupHistory_c1.pattern2 OR
             bp.handle LIKE bsBackupHistory_c1.pattern3 OR
             bp.handle LIKE bsBackupHistory_c1.pattern4))
       AND ((user_site_key = bp.site_key) OR
            (user_site_key IS NULL AND
             ((disk_backups_shared = TRUE# AND bp.device_type = 'DISK') OR
              (tape_backups_shared = TRUE# AND bp.device_type <> 'DISK') OR
              (this_site_key = nvl(bp.site_key, this_site_key)))))
  GROUP BY bs.set_stamp, bs.set_count, bs.pieces,
           bp.copy#, bp.device_type
    HAVING count(distinct bp.piece#) = bs.pieces
 
--
   ORDER BY setStamp, setCount, compTime;
 
CURSOR bsBackupHistory_c2(
   device_type  IN varchar2
  ,cmd          IN varchar2
  ,ktag         IN varchar2
  ,pattern1     IN varchar2
  ,pattern2     IN varchar2
  ,pattern3     IN varchar2
  ,pattern4     IN varchar2)
RETURN bhistoryRec_t IS
   SELECT
      to_number(null)           dfNumber,
      to_number(null)           create_scn,
      to_number(null)           reset_scn,
      to_date(null)             reset_time,
      to_number(null)           ckp_scn,
      to_date(null)             ckp_time,
      to_number(null)           stop_scn,
      to_number(null)           logThread,
      to_number(null)           logSequence,
      bs.set_stamp              setStamp,
      bs.set_count              setCount,
      max(bp.completion_time)   compTime,
      0                         nbackups,
      to_char(null)             logTerminal,
      to_number(null)           next_scn,
      0                         pluggedRonly,
      0                         pluginSCN,
      0                         pluginRlgSCN,
      to_date(null)             pluginRlgTime,
      to_number(null)           newcreate_scn,
      to_number(null)           newreset_scn,
      to_date(null)             newreset_time
   FROM bs,
        bp
     WHERE bs.db_key       = this_db_key             -- this database
       AND bp.bs_key       = bs.bs_key               -- join bs, bp
       AND bs.status       = 'A'
       AND bp.status      != 'D'
       AND (bsBackupHistory_c2.device_type IS NULL OR
            bsBackupHistory_c2.device_type = bp.device_type)
       AND ((bsBackupHistory_c2.pattern1 IS NULL AND
             bsBackupHistory_c2.pattern2 IS NULL AND
             bsBackupHistory_c2.pattern3 IS NULL AND
             bsBackupHistory_c2.pattern4 IS NULL) OR
            (bp.handle LIKE bsBackupHistory_c2.pattern1 OR
             bp.handle LIKE bsBackupHistory_c2.pattern2 OR
             bp.handle LIKE bsBackupHistory_c2.pattern3 OR
             bp.handle LIKE bsBackupHistory_c2.pattern4))
       AND ((user_site_key = bp.site_key) OR
            (user_site_key IS NULL AND
             ((disk_backups_shared = TRUE# AND bp.device_type = 'DISK') OR
              (tape_backups_shared = TRUE# AND bp.device_type <> 'DISK') OR
              (this_site_key = nvl(bp.site_key, this_site_key)))))
  GROUP BY bs.set_stamp, bs.set_count, bs.pieces,
           bp.copy#, bp.device_type
    HAVING count(distinct bp.piece#) = bs.pieces
 
--
   ORDER BY setStamp, setCount, compTime;
 
--
--
--
CURSOR getCopyofDatafile_c2(
   itag        varchar2
)
IS
   SELECT /*+ first_rows */
      file#,
      creation_change#,
      resetlogs_change#,
      resetlogs_time,
      recid,
      stamp,
      name,
      tag,
      status,
      blocks,
      block_size,
      completion_time,
      checkpoint_change#,
      checkpoint_time,
      decode(plugged_readonly, 'YES', 1, 0) pluggedRonly,
      plugin_change#,
      plugin_resetlogs_change#,
      plugin_resetlogs_time,
      absolute_fuzzy_change#
   FROM
      rc_datafile_copy
   WHERE status            = 'A'
     AND (itag is NULL or tag = itag)
     AND (tc_database = TRUE# OR
          isTranslatedFno(file#) = TRUE#)   -- only translated files
     AND ((user_site_key = rc_datafile_copy.site_key) OR
          (user_site_key IS NULL AND
           ((disk_backups_shared = TRUE#) OR
            (this_site_key = nvl(rc_datafile_copy.site_key, this_site_key)))))
  ORDER BY file#, decode(plugged_readonly, 'YES',
                  plugin_change#, checkpoint_change#) desc, recid desc;
 
--
--
--
--
CURSOR getCopyofDatafile_c(
   dfnumber    number
  ,itag        varchar2
  ,crescn      number
  ,rlgscn      number
  ,rlgtime     date
  ,pluginSCN   number
)
IS
   SELECT /*+ first_rows */
      recid,
      stamp,
      name,
      tag,
      status,
      blocks,
      block_size,
      completion_time,
      checkpoint_change#,
      checkpoint_time,
      creation_change#,
      resetlogs_change#,
      resetlogs_time,
      decode(plugged_readonly, 'YES', 1, 0) pluggedRonly
   FROM
      rc_datafile_copy
   WHERE status            = 'A'
     AND (itag is NULL or tag = itag)
     AND file#             = dfnumber
     AND ((pluginSCN = 0 AND creation_change# = crescn) OR
          (pluginSCN != 0 AND plugin_change# = pluginSCN))
     AND ((plugged_readonly = 'NO' AND
           resetlogs_change# = rlgscn AND
           resetlogs_time    = rlgtime) OR
          (plugged_readonly = 'YES' AND
           plugin_resetlogs_change# = rlgscn AND
           plugin_resetlogs_time = rlgtime))
     AND ((user_site_key = rc_datafile_copy.site_key) OR
          (user_site_key IS NULL AND
           ((disk_backups_shared = TRUE#) OR
            (this_site_key = nvl(rc_datafile_copy.site_key, this_site_key)))))
 
  ORDER BY
      decode(plugged_readonly, 'YES',
             plugin_change#, checkpoint_change#) desc;
 
--
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
 
--
TYPE rcvRecCursor_t IS RECORD
(
   currc1         rcvRec_t,            -- current fetched rcvRecCursor1_c data
   reqfno         number,              -- requested file number
   reqcrescn      number,              -- requested file number's create scn
   reqpluginSCN   number,              -- requested file number's plugin scn
   excludeAction  binary_integer       -- type of action that is excluded
);
rcvRecCursor rcvRecCursor_t;
 
CURSOR rcvRecCursor1_c(
rmanCmd       IN binary_integer
)
RETURN rcvRec_t IS
 
--
 
   SELECT offlineRangeRec_con_t                 type_con,
          offr.offr_key                         key_con,
          offr.offr_recid                       recid_con,
          offr.offr_stamp                       stamp_con,
          to_number(null)                       setStamp_con,
          to_number(null)                       setCount_con,
          to_number(null)                       bsRecid_con,
          to_number(null)                       bsStamp_con,
          to_number(null)                       bsKey_con,
          to_number(null)                       bsLevel_con,
          to_char(null)                         bsType_con,
          to_number(null)                       elapseSecs_con,
          to_number(null)                       pieceCount_con,
          to_char(null)                         fileName_con,
          to_char(null)                         tag_con,
          to_number(null)                       copyNumber_con,
          to_char(null)                         status_con,
          to_number(null)                       blocks_con,
          to_number(null)                       blockSize_con,
          to_char(null)                         deviceType_con,
          to_date(null)                         compTime_con,
          offr.cf_create_time                   cfCreationTime_con,
          to_number(null)                       pieceNumber_con,
          to_date(null)                         bpCompTime_con,
          to_char(null)                         bpCompressed_con,
          to_char(null)                         multi_section_con,
 
          offlineRange_act_t                    type_act,
          offr.offline_scn                      fromSCN_act,
          offr.online_scn                       toSCN_act,
          offr.online_time                      toTime_act,
          dbinc.reset_scn                       rlgSCN_act,
          dbinc.reset_time                      rlgTime_act,
          dbinc.dbinc_key                       dbincKey_act,
          to_number(null)                       level_act,
          0                                     section_size_act,
 
          offr.file#                            dfNumber_obj,
          offr.create_scn                       dfCreationSCN_obj,
          to_number(null)                       cfSequence_obj,
          to_date(null)                         cfDate_obj,
          to_number(null)                       logSequence_obj,
          to_number(null)                       logThread_obj,
          to_number(null)                       logRlgSCN_obj,
          to_date(null)                         logRlgTime_obj,
          to_number(null)                       logLowSCN_obj,
          to_date(null)                         logLowTime_obj,
          to_number(null)                       logNextSCN_obj,
          to_date(null)                         logNextTime_obj,
          to_char(null)                         logTerminal_obj,
          to_char(null)                         cfType_obj,
          to_number(null)                       pdbKey_obj,
 
          to_number(null)                       keep_options,
          to_date(null)                         keep_until,
 
          to_number(null)                       afzSCN_act,
          to_date(null)                         rfzTime_act,
          to_number(null)                       rfzSCN_act,
          to_char(null)                         media_con,
          'NO'                                  isrdf_con,
          0                                     site_key_con,
          0                                     foreignDbid_obj,
          0                                     pluggedRonly_obj,
          0                                     pluginSCN_obj,
          0                                     pluginRlgSCN_obj,
          to_date(null)                         pluginRlgTime_obj,
 
          offr.create_scn                       newDfCreationSCN_obj,
          offr.online_scn                       newToSCN_act,
          to_number(null)                       newRlgSCN_act,
          to_date(null)                         newRlgTime_act,
          to_char(null)                         sfDbUniqueName_obj,
          to_char(null)                         sparse_backup_con,
          0                                     ppl_pdb_id_con,
          0                                     ppl_cdb_dbid_con
     FROM offr, dbinc
    WHERE (tc_database = TRUE# OR isTranslatedFno(offr.file#) = TRUE#)
      AND (untilSCN is null OR offr.online_scn < untilSCN)
--
--
--
--
--
--
      AND offr.cf_create_time is not null
--
      AND offr.offr_stamp <> 0          -- stamp = 0 -> from kccfe
      AND offr.dbinc_key  = this_dbinc_key
      AND offr.dbinc_key = dbinc.dbinc_key
 
   UNION ALL
 
--
 
   SELECT imageCopy_con_t                       type_con,
          cdf.cdf_key                           key_con,
          cdf.cdf_recid                         recid_con,
          cdf.cdf_stamp                         stamp_con,
          to_number(null)                       setStamp_con,
          to_number(null)                       setCount_con,
          to_number(null)                       bsRecid_con,
          to_number(null)                       bsStamp_con,
          to_number(null)                       bsKey_con,
          to_number(null)                       bsLevel_con,
          to_char(null)                         bsType_con,
          to_number(null)                       elapseSecs_con,
          to_number(null)                       pieceCount_con,
          cdf.fname                             fileName_con,
          cdf.tag                               tag_con,
          to_number(null)                       copyNumber_con,
          cdf.status                            status_con,
          cdf.blocks                            blocks_con,
          cdf.block_size                        blockSize_con,
          'DISK'                                deviceType_con,
          cdf.completion_time                   compTime_con,
          to_date(null)                         cfCreationTime_con,
          to_number(null)                       pieceNumber_con,
          to_date(null)                         bpCompTime_con,
          to_char(null)                         bpCompressed_con,
          to_char(null)                         multi_section_con,
 
          full_act_t                            type_act,
          0                                     fromSCN_act,
          cdf.ckp_scn                           toSCN_act,
          cdf.ckp_time                          toTime_act,
          dbinc.reset_scn                       rlgSCN_act,
          dbinc.reset_time                      rlgTime_act,
          dbinc.dbinc_key                       dbincKey_act,
          cdf.incr_level                        level_act,
          0                                     section_size_act,
 
          cdf.file#                             dfNumber_obj,
          cdf.create_scn                        dfCreationSCN_obj,
          to_number(null)                       cfSequence_obj,
          to_date(null)                         cfDate_obj,
          to_number(null)                       logSequence_obj,
          to_number(null)                       logThread_obj,
          to_number(null)                       logRlgSCN_obj,
          to_date(null)                         logRlgTime_obj,
          to_number(null)                       logLowSCN_obj,
          to_date(null)                         logLowTime_obj,
          to_number(null)                       logNextSCN_obj,
          to_date(null)                         logNextTime_obj,
          to_char(null)                         logTerminal_obj,
          to_char(null)                         cfType_obj,
          cdf.pdb_key                           pdbKey_obj,
 
          cdf.keep_options                      keep_options,
          cdf.keep_until                        keep_until,
 
          cdf.abs_fuzzy_scn                     afzSCN_act,
          cdf.rcv_fuzzy_time                    rfzTime_act,
          cdf.rcv_fuzzy_scn                     rfzSCN_act,
          to_char(null)                         media_con,
          cdf.is_recovery_dest_file             isrdf_con,
          site_key                              site_key_con,
          cdf.foreign_dbid                      foreignDbid_obj,
          decode(cdf.plugged_readonly, 'YES', 1, 0)
                                                pluggedRonly_obj,
          cdf.plugin_scn                        pluginSCN_obj,
          cdf.plugin_reset_scn                  pluginRlgSCN_obj,
          cdf.plugin_reset_time                 pluginRlgTime_obj,
 
          decode(cdf.plugin_scn, 0, cdf.create_scn,
                 cdf.plugin_scn)                newDfCreation_obj,
          decode(cdf.plugged_readonly, 'NO', cdf.ckp_scn,
                 cdf.plugin_scn)                newToSCN_act,
          to_number(null)                       newRlgSCN_act,
          to_date(null)                         newRlgTime_act,
          to_char(null)                         sfDbUniqueName_obj,
          cdf.sparse_backup                     sparse_backup_con,
          0                                     ppl_pdb_id_con,
          0                                     ppl_cdb_dbid_con
     FROM cdf, dbinc
    WHERE (tc_database = TRUE# OR isTranslatedFno(cdf.file#) = TRUE#)
      AND (untilSCN is null OR
           (cdf.plugged_readonly = 'NO' AND
            greatest(cdf.ckp_scn, cdf.abs_fuzzy_scn,
                     cdf.rcv_fuzzy_scn) <= untilSCN) OR
           (cdf.plugged_readonly = 'YES' AND
            cdf.plugin_scn <= untilSCN))
      AND cdf.status = 'A'
      AND (restoreSource is NULL                        OR
           bitand(restoreSource, imageCopy_con_t) != 0)
      AND cdf.dbinc_key = dbinc.dbinc_key
      AND dbinc.db_key = this_db_key
      AND rmanCmd != recoverCmd_t
      AND ((user_site_key = cdf.site_key) OR
           (user_site_key IS NULL AND
            ((disk_backups_shared = TRUE#) OR
             (this_site_key = nvl(cdf.site_key, this_site_key)))))
      AND (cdf.file# = 0 OR -- backup mode is not applicable for control files
           restoreSparse = BACKUP_SPARSENESS_UNSPECIFIED     OR
           (restoreSparse = BACKUP_SPARSENESS_SPARSE AND
            cdf.sparse_backup = 'YES')                       OR
           (restoreSparse = BACKUP_SPARSENESS_NONSPARSE AND
            cdf.sparse_backup = 'NO'))
 
   UNION ALL
 
--
 
   SELECT imageCopy_con_t                       type_con,
          ccf.ccf_key                           key_con,
          ccf.ccf_recid                         recid_con,
          ccf.ccf_stamp                         stamp_con,
          to_number(null)                       setStamp_con,
          to_number(null)                       setCount_con,
          to_number(null)                       bsRecid_con,
          to_number(null)                       bsStamp_con,
          to_number(null)                       bsKey_con,
          to_number(null)                       bsLevel_con,
          to_char(null)                         bsType_con,
          to_number(null)                       elapseSecs_con,
          to_number(null)                       pieceCount_con,
          ccf.fname                             fileName_con,
          ccf.tag                               tag_con,
          to_number(null)                       copyNumber_con,
          ccf.status                            status_con,
          to_number(null)                       blocks_con,
          ccf.block_size                        blockSize_con,
          'DISK'                                deviceType_con,
          ccf.completion_time                   compTime_con,
          to_date(null)                         cfCreationTime_con,
          to_number(null)                       pieceNumber_con,
          to_date(null)                         bpCompTime_con,
          to_char(null)                         bpCompressed_con,
          to_char(null)                         multi_section_con,
 
          full_act_t                            type_act,
          0                                     fromSCN_act,
          ccf.ckp_scn                           toSCN_act,
          ccf.ckp_time                          toTime_act,
          dbinc.reset_scn                       rlgSCN_act,
          dbinc.reset_time                      rlgTime_act,
          dbinc.dbinc_key                       dbincKey_act,
          to_number(null)                       level_act,
          0                                     section_size_act,
 
          0                                     dfNumber_obj,
          0                                     dfCreationSCN_obj,
          to_number(null)                       cfSequence_obj,
          to_date(null)                         cfDate_obj,
          to_number(null)                       logSequence_obj,
          to_number(null)                       logThread_obj,
          to_number(null)                       logRlgSCN_obj,
          to_date(null)                         logRlgTime_obj,
          to_number(null)                       logLowSCN_obj,
          to_date(null)                         logLowTime_obj,
          to_number(null)                       logNextSCN_obj,
          to_date(null)                         logNextTime_obj,
          to_char(null)                         logTerminal_obj,
          nvl(ccf.controlfile_type, 'B')        cfType_obj,
          ccf.pdb_key                           pdbKey_obj,
 
          ccf.keep_options                      keep_options,
          ccf.keep_until                        keep_until,
 
          to_number(null)                       afzSCN_act,
          to_date(null)                         rfzTime_act,
          to_number(null)                       rfzSCN_act,
          to_char(null)                         media_con,
          is_recovery_dest_file                 isrdf_con,
          site_key                              site_key_con,
          0                                     foreignDbid_obj,
          0                                     pluggedRonly_obj,
          0                                     pluginSCN_obj,
          0                                     pluginRlgSCN_obj,
          to_date(null)                         pluginRlgTime_obj,
 
          0                                     newDfCreationSCN_obj,
          ccf.ckp_scn                           newToSCN_act,
          to_number(null)                       newRlgSCN_act,
          to_date(null)                         newRlgTime_act,
          to_char(null)                         sfDbUniqueName_obj,
          to_char(null)                         sparse_backup_con,
          0                                     ppl_pdb_id_con,
          0                                     ppl_cdb_dbid_con
     FROM ccf, dbinc
    WHERE (tc_database = TRUE# OR isTranslatedFno(0) = TRUE#)
      AND (untilSCN is null OR
           ccf.ckp_scn <= untilSCN)
      AND ccf.status = 'A'
      AND (restoreSource is NULL                        OR
           bitand(restoreSource, imageCopy_con_t) != 0)
      AND ccf.dbinc_key = dbinc.dbinc_key
      AND dbinc.db_key = this_db_key
      AND rmanCmd NOT IN (recoverCmd_t, blkRestoreCmd_t)
      AND ((user_site_key = ccf.site_key) OR
           (user_site_key IS NULL AND
            ((disk_backups_shared = TRUE#) OR
             (this_site_key = nvl(ccf.site_key, this_site_key)))))
 
   UNION ALL
 
--
--
 
   SELECT backupSet_con_t                       type_con,
          bdf.bdf_key                           key_con,
          bdf.bdf_recid                         recid_con,
          bdf.bdf_stamp                         stamp_con,
          bs.set_stamp                          setStamp_con,
          bs.set_count                          setCount_con,
          bs.bs_recid                           bsRecid_con,
          bs.bs_stamp                           bsStamp_con,
          bs.bs_key                             bsKey_con,
          bs.incr_level                         bsLevel_con,
          bs.bck_type                           bsType_con,
          abs((bs.completion_time - bs.start_time) * 86400)
                                                elapseSecs_con,
          bs.pieces                             pieceCount_con,
          to_char(null)                         fileName_con,
          to_char(null)                         tag_con,
          to_number(null)                       copyNumber_con,
          to_char(null)                         status_con,
          bdf.blocks                            blocks_con,
          bdf.block_size                        blockSize_con,
          to_char(null)                         deviceType_con,
          bdf.completion_time                   compTime_con,
          to_date(null)                         cfCreationTime_con,
          to_number(null)                       pieceNumber_con,
          to_date(null)                         bpCompTime_con,
          to_char(null)                         bpCompressed_con,
          multi_section                         multi_section_con,
 
          decode(bdf.incr_scn,
                 0, full_act_t,
                 bdf.create_scn,
                 decode(rmanCmd,
                        rcvCopyCmd_t,
                        incremental_act_t,
                        recoverCmd_t,
                        incremental_act_t,
                        full_act_t),
                 incremental_act_t)             type_act,
          decode(bdf.incr_scn,
                 bdf.create_scn,
                 decode(rmanCmd,
                        rcvCopyCmd_t,
                        bdf.incr_scn,
                        recoverCmd_t,
                        bdf.incr_scn,
                        0),
                 bdf.incr_scn)                  fromSCN_act,
          bdf.ckp_scn                           toSCN_act,
          bdf.ckp_time                          toTime_act,
          dbinc.reset_scn                       rlgSCN_act,
          dbinc.reset_time                      rlgTime_act,
          dbinc.dbinc_key                       dbincKey_act,
          bdf.incr_level                        level_act,
          bdf.section_size                      section_size_act,
 
          bdf.file#                             dfNumber_obj,
          bdf.create_scn                        dfCreationSCN_obj,
          to_number(null)                       cfSequence_obj,
          to_date(null)                         cfDate_obj,
          to_number(null)                       logSequence_obj,
          to_number(null)                       logThread_obj,
          to_number(null)                       logRlgSCN_obj,
          to_date(null)                         logRlgTime_obj,
          to_number(null)                       logLowSCN_obj,
          to_date(null)                         logLowTime_obj,
          to_number(null)                       logNextSCN_obj,
          to_date(null)                         logNextTime_obj,
          to_char(null)                         logTerminal_obj,
          to_char(null)                         cfType_obj,
          bdf.pdb_key                           pdbKey_obj,
 
          bs.keep_options                       keep_options,
          bs.keep_until                         keep_until,
 
          bdf.abs_fuzzy_scn                     afzSCN_act,
          to_date(null)                         rfzTime_act,
          to_number(null)                       rfzSCN_act,
          to_char(null)                         media_con,
          'NO'                                  isrdf_con,
          bs.site_key                           site_key_con,
          bdf.foreign_dbid                      foreignDbid_obj,
          decode(bdf.plugged_readonly, 'YES', 1, 0)
                                                pluggedRonly_obj,
          bdf.plugin_scn                        pluginSCN_obj,
          bdf.plugin_reset_scn                  pluginRlgSCN_obj,
          bdf.plugin_reset_time                 pluginRlgTime_obj,
 
          decode(bdf.plugin_scn, 0, bdf.create_scn,
                 bdf.plugin_scn)                newDfCreationSCN_obj,
          decode(bdf.plugged_readonly, 'NO', bdf.ckp_scn,
                 bdf.plugin_scn)                newToSCN_act,
          to_number(null)                       newRlgSCN_act,
          to_date(null)                         newRlgTime_act,
          to_char(null)                         sfDbUniqueName_obj,
          bdf.sparse_backup                     sparse_backup_con,
          0                                     ppl_pdb_id_con,
          0                                     ppl_cdb_dbid_con
     FROM bdf, bs, dbinc
--
--
--
    WHERE rmanCmd != obsoleteCmd_t
      AND (tc_database = TRUE# OR isTranslatedFno(bdf.file#) = TRUE#)
      AND bs.status = 'A'
      AND bs.bck_type != 'L'               -- only datafile backups
      AND (untilSCN IS NULL OR
           (bdf.plugged_readonly = 'NO' AND
            greatest(bdf.ckp_scn, bdf.abs_fuzzy_scn) <= untilSCN) OR
           (bdf.plugged_readonly = 'YES' AND
            bdf.plugin_scn <= untilSCN))
      AND dbinc.dbinc_key  = bdf.dbinc_key   -- join dbinc, bdf
      AND bs.bs_key        = bdf.bs_key      -- join bs, bdf
      AND dbinc.db_key     = this_db_key
      AND (rmanCmd = rcvCopyCmd_t OR -- use incr for recover copy cmd
           rmanCmd = recoverCmd_t OR
           (restoreSource IS NULL OR
            bitand(restoreSource, backupSet_con_t) != 0))
      AND (bdf.file# = 0 OR -- backup mode is not applicable for control files
           restoreSparse = BACKUP_SPARSENESS_UNSPECIFIED      OR
           (restoreSparse = BACKUP_SPARSENESS_SPARSE AND
            bdf.sparse_backup = 'YES')                        OR
           (restoreSparse = BACKUP_SPARSENESS_NONSPARSE AND
            bdf.sparse_backup = 'NO'))
      AND ((rmanCmd = rcvCopyCmd_t AND bdf.incr_scn > 0)               OR
           (rmanCmd = recoverCmd_t AND bdf.incr_scn > 0)               OR
           (rmanCmd IN (restoreCmd_t, blkRestoreCmd_t) AND
            bdf.incr_scn <= bdf.create_scn)                            OR
           (rmanCmd = unknownCmd_t))
      AND (bs.site_key IS NULL         OR -- always return null site_key
           user_site_key = bs.site_key OR -- user interested in one site
           (user_site_key IS NULL AND     -- return rows per access attr
            (disk_backups_shared = TRUE# OR
             tape_backups_shared = TRUE# OR
             this_site_key = bs.site_key)))
 
   UNION ALL
 
--
--
 
   SELECT backupSet_con_t                       type_con,
          bdf.bdf_key                           key_con,
          bdf.bdf_recid                         recid_con,
          bdf.bdf_stamp                         stamp_con,
          bs.set_stamp                          setStamp_con,
          bs.set_count                          setCount_con,
          bs.bs_recid                           bsRecid_con,
          bs.bs_stamp                           bsStamp_con,
          bs.bs_key                             bsKey_con,
          bs.incr_level                         bsLevel_con,
          bs.bck_type                           bsType_con,
          abs((bs.completion_time - bs.start_time) * 86400)
                                                elapseSecs_con,
          bs.pieces                             pieceCount_con,
          to_char(null)                         fileName_con,
          to_char(null)                         tag_con,
          to_number(null)                       copyNumber_con,
          to_char(null)                         status_con,
          bdf.blocks                            blocks_con,
          bdf.block_size                        blockSize_con,
          to_char(null)                         deviceType_con,
          bdf.completion_time                   compTime_con,
          to_date(null)                         cfCreationTime_con,
          to_number(null)                       pieceNumber_con,
          to_date(null)                         bpCompTime_con,
          to_char(null)                         bpCompressed_con,
          multi_section                         multi_section_con,
 
          decode(bdf.incr_scn,
                 0, full_act_t,
                 bdf.create_scn,
                 full_act_t,
                 incremental_act_t)             type_act,
          bdf.incr_scn                          fromSCN_act,
          bdf.ckp_scn                           toSCN_act,
          bdf.ckp_time                          toTime_act,
          dbinc.reset_scn                       rlgSCN_act,
          dbinc.reset_time                      rlgTime_act,
          dbinc.dbinc_key                       dbincKey_act,
          bdf.incr_level                        level_act,
          bdf.section_size                      section_size_act,
 
          bdf.file#                             dfNumber_obj,
          bdf.create_scn                        dfCreationSCN_obj,
          to_number(null)                       cfSequence_obj,
          to_date(null)                         cfDate_obj,
          to_number(null)                       logSequence_obj,
          to_number(null)                       logThread_obj,
          to_number(null)                       logRlgSCN_obj,
          to_date(null)                         logRlgTime_obj,
          to_number(null)                       logLowSCN_obj,
          to_date(null)                         logLowTime_obj,
          to_number(null)                       logNextSCN_obj,
          to_date(null)                         logNextTime_obj,
          to_char(null)                         logTerminal_obj,
          to_char(null)                         cfType_obj,
          bdf.pdb_key                           pdbKey_obj,
 
          bs.keep_options                       keep_options,
          bs.keep_until                         keep_until,
 
          bdf.abs_fuzzy_scn                     afzSCN_act,
          to_date(null)                         rfzTime_act,
          to_number(null)                       rfzSCN_act,
          to_char(null)                         media_con,
          'NO'                                  isrdf_con,
          bs.site_key                           site_key_con,
          bdf.foreign_dbid                      foreignDbid_obj,
          decode(bdf.plugged_readonly, 'YES', 1, 0)
                                                pluggedRonly_obj,
          bdf.plugin_scn                        pluginSCN_obj,
          bdf.plugin_reset_scn                  pluginRlgSCN_obj,
          bdf.plugin_reset_time                 pluginRlgTime_obj,
 
          decode(bdf.plugin_scn, 0, bdf.create_scn,
                 bdf.plugin_scn)                newDfCreationSCN_obj,
          decode(bdf.plugged_readonly, 'NO', bdf.ckp_scn,
                 bdf.plugin_scn)                newToSCN_act,
          to_number(null)                       newRlgSCN_act,
          to_date(null)                         newRlgTime_act,
          to_char(null)                         sfDbUniqueName_obj,
          bdf.sparse_backup                     sparse_backup_con,
          0                                     ppl_pdb_id_con,
          0                                     ppl_cdb_dbid_con
     FROM bdf, bs, dbinc,
          (SELECT bs_key,
                  count(distinct piece#) pieces
             FROM  bp
            WHERE rmanCmd = obsoleteCmd_t
              AND bp.db_key  = this_db_key         -- this database
              AND bp.status  = 'A'
              AND (anyDevice = TRUE# OR
                   isDeviceTypeAllocated(bp.device_type) = TRUE#)
              AND ((user_site_key = bp.site_key) OR
                   (user_site_key IS NULL AND
                    ((disk_backups_shared =TRUE# AND bp.device_type='DISK') OR
                     (tape_backups_shared =TRUE# AND bp.device_type<>'DISK') OR
                     (this_site_key = nvl(bp.site_key, this_site_key)))))
           GROUP BY bs_key, device_type) bp
--
--
--
    WHERE rmanCmd = obsoleteCmd_t
--
--
--
      AND bs.status = 'A'
      AND bs.bck_type != 'L'                 -- only datafile backups
      AND (untilSCN IS NULL OR
           (bdf.plugged_readonly = 'NO' AND
            greatest(bdf.ckp_scn, bdf.abs_fuzzy_scn) <= untilSCN) OR
           (bdf.plugged_readonly = 'YES' AND
            bdf.plugin_scn <= untilSCN))
      AND dbinc.dbinc_key  = bdf.dbinc_key   -- join dbinc, bdf
      AND bs.bs_key        = bdf.bs_key      -- join bs, bdf
      AND dbinc.db_key     = this_db_key
      AND (restoreSource IS NULL OR
           bitand(restoreSource, backupSet_con_t) != 0)
      AND (bdf.file# = 0 OR -- backup mode is not applicable for control files
           restoreSparse = BACKUP_SPARSENESS_UNSPECIFIED      OR
           (restoreSparse = BACKUP_SPARSENESS_SPARSE AND
            bdf.sparse_backup = 'YES')                        OR
           (restoreSparse = BACKUP_SPARSENESS_NONSPARSE AND
            bdf.sparse_backup = 'NO'))
      AND bp.bs_key        = bs.bs_key
      AND bp.pieces        = bs.pieces
 
   UNION ALL
 
--
--
 
   SELECT backupSet_con_t                       type_con,
          bcf.bcf_key                           key_con,
          bcf.bcf_recid                         recid_con,
          bcf.bcf_stamp                         stamp_con,
          bs.set_stamp                          setStamp_con,
          bs.set_count                          setCount_con,
          bs.bs_recid                           bsRecid_con,
          bs.bs_stamp                           bsStamp_con,
          bs.bs_key                             bsKey_con,
          0                                     bsLevel_con,
          bs.bck_type                           bsType_con,
          abs((bs.completion_time - bs.start_time) * 86400)
                                                elapseSecs_con,
          bs.pieces                             pieceCount_con,
          to_char(null)                         fileName_con,
          to_char(null)                         tag_con,
          to_number(null)                       copyNumber_con,
          to_char(null)                         status_con,
          to_number(null)                       blocks_con,
          bcf.block_size                        blockSize_con,
          to_char(null)                         deviceType_con,
          bs.completion_time                    compTime_con,
          to_date(null)                         cfCreationTime_con,
          to_number(null)                       pieceNumber_con,
          to_date(null)                         bpCompTime_con,
          to_char(null)                         bpCompressed_con,
          multi_section                         multi_section_con,
 
          full_act_t                            type_act,
          0                                     fromSCN_act,
          bcf.ckp_scn                           toSCN_act,
          bcf.ckp_time                          toTime_act,
          dbinc.reset_scn                       rlgSCN_act,
          dbinc.reset_time                      rlgTime_act,
          dbinc.dbinc_key                       dbincKey_act,
          to_number(null)                       level_act,
          0                                     section_size_act,
 
          0                                     dfNumber_obj,
          0                                     dfCreationSCN_obj,
          to_number(null)                       cfSequence_obj,
          to_date(null)                         cfDate_obj,
          to_number(null)                       logSequence_obj,
          to_number(null)                       logThread_obj,
          to_number(null)                       logRlgSCN_obj,
          to_date(null)                         logRlgTime_obj,
          to_number(null)                       logLowSCN_obj,
          to_date(null)                         logLowTime_obj,
          to_number(null)                       logNextSCN_obj,
          to_date(null)                         logNextTime_obj,
          to_char(null)                         logTerminal_obj,
          nvl(bcf.controlfile_type, 'B')        cfType_obj,
          bcf.pdb_key                           pdbKey_obj,
 
          bs.keep_options                       keep_options,
          bs.keep_until                         keep_until,
 
          to_number(null)                       afzSCN_act,
          to_date(null)                         rfzTime_act,
          to_number(null)                       rfzSCN_act,
          to_char(null)                         media_con,
          'NO'                                  isrdf_con,
          bs.site_key                           site_key_con,
          0                                     foreignDbid_obj,
          0                                     pluggedRonly_obj,
          0                                     pluginSCN_obj,
          0                                     pluginRlgSCN_obj,
          to_date(null)                         pluginRlgTime_obj,
 
          0                                     newDfCreationSCN_obj,
          bcf.ckp_scn                           newToSCN_act,
          to_number(null)                       newRlgSCN_act,
          to_date(null)                         newRlgTime_act,
          to_char(null)                         sfDbUniqueName_obj,
          to_char(null)                         sparse_backup_con,
          0                                     ppl_pdb_id_con,
          0                                     ppl_cdb_dbid_con
     FROM bcf, bs, dbinc
--
--
--
    WHERE rmanCmd != obsoleteCmd_t
      AND (tc_database = TRUE# OR isTranslatedFno(0) = TRUE#)
      AND bs.status = 'A'
      AND bs.bck_type != 'L'                 -- ignore archivelog backups
      AND (untilSCN IS NULL OR
           bcf.ckp_scn <= untilSCN)
      AND (restoreSource IS NULL OR
           bitand(restoreSource, backupSet_con_t) != 0)
      AND dbinc.dbinc_key  = bcf.dbinc_key   -- join dbinc, bcf
      AND bs.bs_key        = bcf.bs_key      -- join bs, bcf
      AND dbinc.db_key     = this_db_key
      AND rmanCmd NOT IN (recoverCmd_t, blkRestoreCmd_t)
      AND (bs.site_key IS NULL         OR    -- always return null site_key
           user_site_key = bs.site_key OR    -- user interested in one site
          (user_site_key IS NULL AND         -- return rows per access attr
           (disk_backups_shared = TRUE# OR
            tape_backups_shared = TRUE# OR
            this_site_key = bs.site_key)))
 
   UNION ALL
 
--
--
 
   SELECT backupSet_con_t                       type_con,
          bcf.bcf_key                           key_con,
          bcf.bcf_recid                         recid_con,
          bcf.bcf_stamp                         stamp_con,
          bs.set_stamp                          setStamp_con,
          bs.set_count                          setCount_con,
          bs.bs_recid                           bsRecid_con,
          bs.bs_stamp                           bsStamp_con,
          bs.bs_key                             bsKey_con,
          0                                     bsLevel_con,
          bs.bck_type                           bsType_con,
          abs((bs.completion_time - bs.start_time) * 86400)
                                                elapseSecs_con,
          bs.pieces                             pieceCount_con,
          to_char(null)                         fileName_con,
          to_char(null)                         tag_con,
          to_number(null)                       copyNumber_con,
          to_char(null)                         status_con,
          to_number(null)                       blocks_con,
          bcf.block_size                        blockSize_con,
          to_char(null)                         deviceType_con,
          bs.completion_time                    compTime_con,
          to_date(null)                         cfCreationTime_con,
          to_number(null)                       pieceNumber_con,
          to_date(null)                         bpCompTime_con,
          to_char(null)                         bpCompressed_con,
          multi_section                         multi_section_con,
 
          full_act_t                            type_act,
          0                                     fromSCN_act,
          bcf.ckp_scn                           toSCN_act,
          bcf.ckp_time                          toTime_act,
          dbinc.reset_scn                       rlgSCN_act,
          dbinc.reset_time                      rlgTime_act,
          dbinc.dbinc_key                       dbincKey_act,
          to_number(null)                       level_act,
          0                                     section_size_act,
 
          0                                     dfNumber_obj,
          0                                     dfCreationSCN_obj,
          to_number(null)                       cfSequence_obj,
          to_date(null)                         cfDate_obj,
          to_number(null)                       logSequence_obj,
          to_number(null)                       logThread_obj,
          to_number(null)                       logRlgSCN_obj,
          to_date(null)                         logRlgTime_obj,
          to_number(null)                       logLowSCN_obj,
          to_date(null)                         logLowTime_obj,
          to_number(null)                       logNextSCN_obj,
          to_date(null)                         logNextTime_obj,
          to_char(null)                         logTerminal_obj,
          nvl(bcf.controlfile_type, 'B')        cfType_obj,
          bcf.pdb_key                           pdbKey_obj,
 
          bs.keep_options                       keep_options,
          bs.keep_until                         keep_until,
 
          to_number(null)                       afzSCN_act,
          to_date(null)                         rfzTime_act,
          to_number(null)                       rfzSCN_act,
          to_char(null)                         media_con,
          'NO'                                  isrdf_con,
          bs.site_key                           site_key_con,
          0                                     foreignDbid_obj,
          0                                     pluggedRonly_obj,
          0                                     pluginSCN_obj,
          0                                     pluginRlgSCN_obj,
          to_date(null)                         pluginRlgTime_obj,
 
          0                                     newDfCreationSCN_obj,
          bcf.ckp_scn                           newToSCN_act,
          to_number(null)                       newRlgSCN_act,
          to_date(null)                         newRlgTime_act,
          to_char(null)                         sfDbUniqueName_obj,
          to_char(null)                         sparse_backup_con,
          0                                     ppl_pdb_id_con,
          0                                     ppl_cdb_dbid_con
     FROM bcf, bs, dbinc,
          (SELECT bs_key,
                  count(distinct piece#) pieces
             FROM  bp
            WHERE rmanCmd = obsoleteCmd_t
              AND bp.db_key  = this_db_key         -- this database
              AND bp.status  = 'A'
              AND (anyDevice = TRUE# OR
                   isDeviceTypeAllocated(bp.device_type) = TRUE#)
              AND ((user_site_key = bp.site_key) OR
                   (user_site_key IS NULL AND
                    ((disk_backups_shared =TRUE# AND bp.device_type ='DISK') OR
                     (tape_backups_shared =TRUE# AND bp.device_type<>'DISK') OR
                     (this_site_key = nvl(bp.site_key, this_site_key)))))
         GROUP BY bs_key, device_type) bp
--
--
--
    WHERE rmanCmd = obsoleteCmd_t
--
--
--
      AND bs.status = 'A'
      AND bs.bck_type != 'L'                 -- ignore archivelog backups
      AND (untilSCN IS NULL OR
           bcf.ckp_scn <= untilSCN)
      AND (restoreSource IS NULL OR
           bitand(restoreSource, backupSet_con_t) != 0)
      AND dbinc.dbinc_key  = bcf.dbinc_key   -- join dbinc, bcf
      AND bs.bs_key        = bcf.bs_key      -- join bs, bcf
      AND dbinc.db_key     = this_db_key
      AND bs.bs_key        = bp.bs_key       -- join bp, bs
      AND bp.pieces        = bs.pieces
 
   UNION ALL
 
--
 
   SELECT proxyCopy_con_t                       type_con,
          xdf.xdf_key                           key_con,
          xdf.xdf_recid                         recid_con,
          xdf.xdf_stamp                         stamp_con,
          to_number(null)                       setStamp_con,
          to_number(null)                       setCount_con,
          to_number(null)                       bsRecid_con,
          to_number(null)                       bsStamp_con,
          to_number(null)                       bsKey_con,
          to_number(null)                       bsLevel_con,
          to_char(null)                         bsType_con,
          to_number(null)                       elapseSecs_con,
          to_number(null)                       pieceCount_con,
          xdf.handle                            fileName_con,
          xdf.tag                               tag_con,
          to_number(null)                       copyNumber_con,
          xdf.status                            status_con,
          xdf.blocks                            blocks_con,
          xdf.block_size                        blockSize_con,
          xdf.device_type                       deviceType_con,
          xdf.completion_time                   compTime_con,
          to_date(null)                         cfCreationTime_con,
          to_number(null)                       pieceNumber_con,
          to_date(null)                         bpCompTime_con,
          to_char(null)                         bpCompressed_con,
          to_char(null)                         multi_section_con,
 
          full_act_t                            type_act,
          0                                     fromSCN_act,
          xdf.ckp_scn                           toSCN_act,
          xdf.ckp_time                          toTime_act,
          dbinc.reset_scn                       rlgSCN_act,
          dbinc.reset_time                      rlgTime_act,
          dbinc.dbinc_key                       dbincKey_act,
          to_number(null)                       level_act,
          0                                     section_size_act,
 
          xdf.file#                             dfNumber_obj,
          xdf.create_scn                        dfCreationSCN_obj,
          to_number(null)                       cfSequence_obj,
          to_date(null)                         cfDate_obj,
          to_number(null)                       logSequence_obj,
          to_number(null)                       logThread_obj,
          to_number(null)                       logRlgSCN_obj,
          to_date(null)                         logRlgTime_obj,
          to_number(null)                       logLowSCN_obj,
          to_date(null)                         logLowTime_obj,
          to_number(null)                       logNextSCN_obj,
          to_date(null)                         logNextTime_obj,
          to_char(null)                         logTerminal_obj,
          to_char(null)                         cfType_obj,
          xdf.pdb_key                           pdbKey_obj,
 
          keep_options                          keep_options,
          keep_until                            keep_until,
 
          xdf.abs_fuzzy_scn                     afzSCN_act,
          xdf.rcv_fuzzy_time                    rfzTime_act,
          xdf.rcv_fuzzy_scn                     rfzSCN_act,
          xdf.media                             media_con,
          'NO'                                  isrdf_con,
          site_key                              site_key_con,
          xdf.foreign_dbid                      foreignDbid_obj,
          decode(xdf.plugged_readonly, 'YES', 1, 0)
                                                pluggedRonly_obj,
          xdf.plugin_scn                        pluginSCN_obj,
          xdf.plugin_reset_scn                  pluginRlgSCN_obj,
          xdf.plugin_reset_time                 pluginRlgTime_obj,
 
          decode(xdf.plugin_scn, 0, xdf.create_scn,
                 xdf.plugin_scn)                newDfCreationSCN_obj,
          decode(xdf.plugged_readonly, 'NO', xdf.ckp_scn,
                 xdf.plugin_scn)                newToSCN_act,
          to_number(null)                       newRlgSCN_act,
          to_date(null)                         newRlgTime_act,
          to_char(null)                         sfDbUniqueName_obj,
          to_char(null)                         sparse_backup_con,
          0                                     ppl_pdb_id_con,
          0                                     ppl_cdb_dbid_con
     FROM xdf, dbinc
    WHERE (tc_database = TRUE# OR isTranslatedFno(xdf.file#) = TRUE#)
      AND (untilSCN IS NULL OR
           (xdf.plugged_readonly = 'NO' AND
            greatest(xdf.ckp_scn, xdf.abs_fuzzy_scn,
                     xdf.rcv_fuzzy_scn) <= untilSCN) OR
           (xdf.plugged_readonly = 'YES' AND
            xdf.plugin_scn <= untilSCN))
      AND xdf.status = 'A'
      AND (restoreSource is NULL OR
           bitand(restoreSource, proxyCopy_con_t) != 0)
      AND dbinc.db_key = this_db_key
      AND xdf.dbinc_key = dbinc.dbinc_key
      AND rmanCmd NOT IN (recoverCmd_t, blkRestoreCmd_t)
      AND ((user_site_key  = xdf.site_key) OR
           (user_site_key IS NULL AND
            ((tape_backups_shared = TRUE#) OR
             (this_site_key = nvl(xdf.site_key, this_site_key)))))
 
    UNION ALL
 
--
 
   SELECT proxyCopy_con_t                       type_con,
          xcf.xcf_key                           key_con,
          xcf.xcf_recid                         recid_con,
          xcf.xcf_stamp                         stamp_con,
          to_number(null)                       setStamp_con,
          to_number(null)                       setCount_con,
          to_number(null)                       bsRecid_con,
          to_number(null)                       bsStamp_con,
          to_number(null)                       bsKey_con,
          to_number(null)                       bsLevel_con,
          to_char(null)                         bsType_con,
          to_number(null)                       elapseSecs_con,
          to_number(null)                       pieceCount_con,
          xcf.handle                            fileName_con,
          xcf.tag                               tag_con,
          to_number(null)                       copyNumber_con,
          xcf.status                            status_con,
          to_number(null)                       blocks_con,
          xcf.block_size                        blockSize_con,
          xcf.device_type                       deviceType_con,
          xcf.completion_time                   compTime_con,
          to_date(null)                         cfCreationTime_con,
          to_number(null)                       pieceNumber_con,
          to_date(null)                         bpCompTime_con,
          to_char(null)                         bpCompressed_con,
          to_char(null)                         multi_section_con,
 
          full_act_t                            type_act,
          0                                     fromSCN_act,
          xcf.ckp_scn                           toSCN_act,
          xcf.ckp_time                          toTime_act,
          dbinc.reset_scn                       rlgSCN_act,
          dbinc.reset_time                      rlgTime_act,
          dbinc.dbinc_key                       dbincKey_act,
          to_number(null)                       level_act,
          0                                     section_size_act,
 
          0                                     dfNumber_obj,
          0                                     dfCreationSCN_obj,
          to_number(null)                       cfSequence_obj,
          to_date(null)                         cfDate_obj,
          to_number(null)                       logSequence_obj,
          to_number(null)                       logThread_obj,
          to_number(null)                       logRlgSCN_obj,
          to_date(null)                         logRlgTime_obj,
          to_number(null)                       logLowSCN_obj,
          to_date(null)                         logLowTime_obj,
          to_number(null)                       logNextSCN_obj,
          to_date(null)                         logNextTime_obj,
          to_char(null)                         logTerminal_obj,
          nvl(xcf.controlfile_type, 'B')        cfType_obj,
          xcf.pdb_key                           pdbKey_obj,
 
          xcf.keep_options                      keep_options,
          xcf.keep_until                        keep_until,
 
          to_number(null)                       afzSCN_act,
          to_date(null)                         rfzTime_act,
          to_number(null)                       rfzSCN_act,
          xcf.media                             media_con,
          'NO'                                  isrdf_con,
          site_key                              site_key_con,
          0                                     foreignDbid_obj,
          0                                     pluggedRonly_obj,
          0                                     pluginSCN_obj,
          0                                     pluginRlgSCN_obj,
          to_date(null)                         pluginRlgTime_obj,
 
          0                                     newDfCreationSCN_obj,
          xcf.ckp_scn                           newToSCN_act,
          to_number(null)                       newRlgSCN_act,
          to_date(null)                         newRlgTime_act,
          to_char(null)                         sfDbUniqueName_obj,
          to_char(null)                         sparse_backup_con,
          0                                     ppl_pdb_id_con,
          0                                     ppl_cdb_dbid_con
     FROM xcf, dbinc
    WHERE (tc_database = TRUE# OR isTranslatedFno(0) = TRUE#)
      AND (untilSCN IS NULL OR
           xcf.ckp_scn <= untilSCN)
      AND xcf.status = 'A'
      AND (restoreSource is NULL OR
           bitand(restoreSource, proxyCopy_con_t) != 0)
      AND dbinc.db_key = this_db_key
      AND xcf.dbinc_key = dbinc.dbinc_key
      AND rmanCmd NOT IN (recoverCmd_t, blkRestoreCmd_t)
      AND ((user_site_key  = xcf.site_key) OR
           (user_site_key IS NULL AND
            ((tape_backups_shared = TRUE#) OR
             (this_site_key = nvl(xcf.site_key, this_site_key)))))
 
    ORDER BY dfNumber_obj         asc,
             newDfCreationSCN_obj asc,
             newToSCN_act         desc,
             fromSCN_act          asc,
             type_con             asc,
             setStamp_con         desc,     /* better value, but may be null */
             setCount_con         desc,       /* ensures uniqueness with ORS */
             stamp_con            desc;      /* needed when setStamp is null */
 
    /* ORS Preference: Latest backup is returned first. Since virtual copy
    ** has higher set_count, they go first in the restore list than file chunks.
    ** We really don't have the meta-data here to find out whether the piece
    ** exists on tape, replication or file chunk to sort it out. This
    ** requires another join with bp table which is expensive.
    */
 
--
CURSOR rcvRecCursor1Filter_c(
   dbincKey      IN     number
  ,fno           IN     number
  ,creSCN        IN     number
  ,dfCkpSCN      IN     number
  ,dbincRlgSCN   IN     number
  ,dbincRlgTime  IN     date
  ,offlSCN       IN     number
  ,onlSCN        IN     number
  ,onlTime       IN     date
  ,cleanSCN      IN     number
  ,clean2SCN     IN     number
  ,clean2Time    IN     date
  ,targetSCN     IN     number
  ,c1rec         IN     rcvRec_t
  ,foreignDbid   IN     number
  ,pluggedRonly  IN     binary_integer
  ,pluginSCN     IN     number
  ,pluginRlgSCN  IN     number
  ,pluginRlgTime IN     date
  ,rmanCmd       IN     binary_integer)
RETURN rcvRec_t IS
 
--
 
   SELECT c1rec.type_con                        type_con,
          c1rec.key_con                         key_con,
          c1rec.recid_con                       recid_con,
          c1rec.stamp_con                       stamp_con,
          c1rec.setStamp_con                    setStamp_con,
          c1rec.setCount_con                    setCount_con,
          c1rec.bsRecid_con                     bsRecid_con,
          c1rec.bsStamp_con                     bsStamp_con,
          c1rec.bsKey_con                       bsKey_con,
          c1rec.bsLevel_con                     bsLevel_con,
          c1rec.bsType_con                      bsType_con,
          c1rec.elapseSecs_con                  elapseSecs_con,
          c1rec.pieceCount_con                  pieceCount_con,
          c1rec.fileName_con                    fileName_con,
          c1rec.tag_con                         tag_con,
          c1rec.copyNumber_con                  copyNumber_con,
          c1rec.status_con                      status_con,
          c1rec.blocks_con                      blocks_con,
          c1rec.blockSize_con                   blockSize_con,
          c1rec.deviceType_con                  deviceType_con,
          c1rec.compTime_con                    compTime_con,
          c1rec.cfCreationTime_con              cfCreationTime_con,
          c1rec.pieceNumber_con                 pieceNumber_con,
          c1rec.bpCompTime_con                  bpCompTime_con,
          c1rec.bpCompressed_con                bpCompressed_con,
          c1rec.multi_section_con               multi_section_con,
 
          c1rec.type_act                        type_act,
          c1rec.fromSCN_act                     fromSCN_act,
          c1rec.toSCN_act                       toSCN_act,
          c1rec.toTime_act                      toTime_act,
          c1rec.rlgSCN_act                      rlgSCN_act,
          c1rec.rlgTime_act                     rlgTime_act,
          c1rec.dbincKey_act                    dbincKey_act,
          c1rec.level_act                       level_act,
          c1rec.section_size_act                section_size_act,
 
          c1rec.dfNumber_obj                    dfNumber_obj,
          c1rec.dfCreationSCN_obj               dfCreationSCN_obj,
          c1rec.cfSequence_obj                  cfSequence_obj,
          c1rec.cfDate_obj                      cfDate_obj,
          c1rec.logSequence_obj                 logSequence_obj,
          c1rec.logThread_obj                   logThread_obj,
          c1rec.logRlgSCN_obj                   logRlgSCN_obj,
          c1rec.logRlgTime_obj                  logRlgTime_obj,
          c1rec.logLowSCN_obj                   logLowSCN_obj,
          c1rec.logLowTime_obj                  logLowTime_obj,
          c1rec.logNextSCN_obj                  logNextSCN_obj,
          c1rec.logNextTime_obj                 logNextTime_obj,
          c1rec.logTerminal_obj                 logTerminal_obj,
          c1rec.cfType_obj                      cfType_obj,
          c1rec.pdbKey_obj                      pdbKey_obj,
 
          c1rec.keep_options                    keep_options,
          c1rec.keep_until                      keep_until,
 
          c1rec.afzSCN_act                      afzSCN_act,
          c1rec.rfzTime_act                     rfzTime_act,
          c1rec.rfzSCN_act                      rfzSCN_act,
          c1rec.media_con                       media_con,
          c1rec.isrdf_con                       isrdf_con,
          c1rec.site_key_con                    site_key_con,
          c1rec.foreignDbid_obj                 foreignDbid_obj,
          c1rec.pluggedRonly_obj                pluggedRonly_obj,
          c1rec.pluginSCN_obj                   pluginSCN_obj,
          c1rec.pluginRlgSCN_obj                pluginRlgSCN_obj,
          c1rec.pluginRlgTime_obj               pluginRlgTime_obj,
 
          c1rec.newDfCreationSCN_obj            newDfCreationSCN_obj,
          c1rec.newToSCN_act                    newToSCN_act,
          c1rec.newRlgSCN_act                   newRlgSCN_act,
          c1rec.newRlgTime_act                  newRlgTime_act,
          c1rec.sfDbUniqueName_obj              sfDbUniqueName_obj,
          c1rec.sparse_backup_con               sparse_backup_con,
          0                                     ppl_pdb_id_con,
          0                                     ppl_cdb_dbid_con
     FROM dual
    WHERE c1rec.type_con = offlineRangeRec_con_t
     AND rcvRecCursor1Filter_c.pluggedRonly = 0
     AND c1rec.dbincKey_act = rcvRecCursor1Filter_c.dbincKey
     AND (rcvRecCursor1Filter_c.dfCkpSCN is null OR
          rcvRecCursor1Filter_c.dfCkpSCN <= c1rec.fromSCN_act)
     AND (rcvRecCursor1Filter_c.targetSCN is null OR
          c1rec.toSCN_act <= rcvRecCursor1Filter_c.targetSCN)
 
   UNION ALL
 
--
   SELECT c1rec.type_con                        type_con,
          c1rec.key_con                         key_con,
          c1rec.recid_con                       recid_con,
          c1rec.stamp_con                       stamp_con,
          c1rec.setStamp_con                    setStamp_con,
          c1rec.setCount_con                    setCount_con,
          c1rec.bsRecid_con                     bsRecid_con,
          c1rec.bsStamp_con                     bsStamp_con,
          c1rec.bsKey_con                       bsKey_con,
          c1rec.bsLevel_con                     bsLevel_con,
          c1rec.bsType_con                      bsType_con,
          c1rec.elapseSecs_con                  elapseSecs_con,
          c1rec.pieceCount_con                  pieceCount_con,
          c1rec.fileName_con                    fileName_con,
          c1rec.tag_con                         tag_con,
          c1rec.copyNumber_con                  copyNumber_con,
          c1rec.status_con                      status_con,
          c1rec.blocks_con                      blocks_con,
          c1rec.blockSize_con                   blockSize_con,
          c1rec.deviceType_con                  deviceType_con,
          c1rec.compTime_con                    compTime_con,
          c1rec.cfCreationTime_con              cfCreationTime_con,
          c1rec.pieceNumber_con                 pieceNumber_con,
          c1rec.bpCompTime_con                  bpCompTime_con,
          c1rec.bpCompressed_con                bpCompressed_con,
          c1rec.multi_section_con               multi_section_con,
 
          c1rec.type_act                        type_act,
          c1rec.fromSCN_act                     fromSCN_act,
          c1rec.toSCN_act                       toSCN_act,
          c1rec.toTime_act                      toTime_act,
          c1rec.rlgSCN_act                      rlgSCN_act,
          c1rec.rlgTime_act                     rlgTime_act,
          c1rec.dbincKey_act                    dbincKey_act,
          c1rec.level_act                       level_act,
          c1rec.section_size_act                section_size_act,
 
          c1rec.dfNumber_obj                    dfNumber_obj,
          c1rec.dfCreationSCN_obj               dfCreationSCN_obj,
          c1rec.cfSequence_obj                  cfSequence_obj,
          c1rec.cfDate_obj                      cfDate_obj,
          c1rec.logSequence_obj                 logSequence_obj,
          c1rec.logThread_obj                   logThread_obj,
          c1rec.logRlgSCN_obj                   logRlgSCN_obj,
          c1rec.logRlgTime_obj                  logRlgTime_obj,
          c1rec.logLowSCN_obj                   logLowSCN_obj,
          c1rec.logLowTime_obj                  logLowTime_obj,
          c1rec.logNextSCN_obj                  logNextSCN_obj,
          c1rec.logNextTime_obj                 logNextTime_obj,
          c1rec.logTerminal_obj                 logTerminal_obj,
          c1rec.cfType_obj                      cfType_obj,
          c1rec.pdbKey_obj                      pdbKey_obj,
 
          c1rec.keep_options                    keep_options,
          c1rec.keep_until                      keep_until,
 
          c1rec.afzSCN_act                      afzSCN_act,
          c1rec.rfzTime_act                     rfzTime_act,
          c1rec.rfzSCN_act                      rfzSCN_act,
          c1rec.media_con                       media_con,
          c1rec.isrdf_con                       isrdf_con,
          c1rec.site_key_con                    site_key_con,
          c1rec.foreignDbid_obj                 foreignDbid_obj,
          c1rec.pluggedRonly_obj                pluggedRonly_obj,
          c1rec.pluginSCN_obj                   pluginSCN_obj,
          c1rec.pluginRlgSCN_obj                pluginRlgSCN_obj,
          c1rec.pluginRlgTime_obj               pluginRlgTime_obj,
 
          c1rec.newDfCreationSCN_obj            newDfCreationSCN_obj,
          c1rec.newToSCN_act                    newToSCN_act,
          c1rec.newRlgSCN_act                   newRlgSCN_act,
          c1rec.newRlgTime_act                  newRlgTime_act,
          c1rec.sfDbUniqueName_obj              sfDbUniqueName_obj,
          c1rec.sparse_backup_con               sparse_backup_con,
          0                                     ppl_pdb_id_con,
          0                                     ppl_cdb_dbid_con
     FROM dual
    WHERE c1rec.type_con = imageCopy_con_t
      AND ((canApplyAnyRedo = TRUE# AND c1rec.dfNumber_obj <> 0) OR
           (craGetAllCfBackups = TRUE# AND c1rec.dfNumber_obj = 0) OR
           (c1rec.pluggedRonly_obj = 0 AND
            c1rec.dbincKey_act = rcvRecCursor1Filter_c.dbincKey) OR
           (c1rec.pluggedRonly_obj != 0 AND
            c1rec.pluginRlgSCN_obj = rcvRecCursor1Filter_c.dbincRlgSCN AND
            c1rec.pluginRlgTime_obj = rcvRecCursor1Filter_c.dbincRlgTime))
      AND (rcvRecCursor1Filter_c.dfCkpSCN is null OR
           rmanCmd = blkRestoreCmd_t OR
           rcvRecCursor1Filter_c.dfCkpSCN <= c1rec.toSCN_act)
      AND (rcvRecCursor1Filter_c.targetSCN is null OR
           (c1rec.pluggedRonly_obj = 0 AND
            c1rec.toSCN_act <= rcvRecCursor1Filter_c.targetSCN) OR
           (c1rec.pluggedRonly_obj != 0 AND
            c1rec.pluginSCN_obj <= rcvRecCursor1Filter_c.targetSCN))
      AND (restoreTag is NULL OR
           c1rec.tag_con = restoreTag OR
           computeRA_allRecords = TRUE#)
      AND ((c1rec.foreignDbid_obj = rcvRecCursor1Filter_c.foreignDbid) OR
           (c1rec.foreignDbid_obj = 0 AND
            c1rec.pluginSCN_obj = 0   AND
            rcvRecCursor1Filter_c.pluginSCN = 0))
--
--
--
   UNION ALL
 
--
 
   SELECT c1rec.type_con                        type_con,
          c1rec.key_con                         key_con,
          c1rec.recid_con                       recid_con,
          c1rec.stamp_con                       stamp_con,
          c1rec.setStamp_con                    setStamp_con,
          c1rec.setCount_con                    setCount_con,
          c1rec.bsRecid_con                     bsRecid_con,
          c1rec.bsStamp_con                     bsStamp_con,
          c1rec.bsKey_con                       bsKey_con,
          c1rec.bsLevel_con                     bsLevel_con,
          c1rec.bsType_con                      bsType_con,
          c1rec.elapseSecs_con                  elapseSecs_con,
          c1rec.pieceCount_con                  pieceCount_con,
          c1rec.fileName_con                    fileName_con,
          c1rec.tag_con                         tag_con,
          c1rec.copyNumber_con                  copyNumber_con,
          c1rec.status_con                      status_con,
          c1rec.blocks_con                      blocks_con,
          c1rec.blockSize_con                   blockSize_con,
          c1rec.deviceType_con                  deviceType_con,
          c1rec.compTime_con                    compTime_con,
          c1rec.cfCreationTime_con              cfCreationTime_con,
          c1rec.pieceNumber_con                 pieceNumber_con,
          c1rec.bpCompTime_con                  bpCompTime_con,
          c1rec.bpCompressed_con                bpCompressed_con,
          c1rec.multi_section_con               multi_section_con,
 
          c1rec.type_act                        type_act,
          c1rec.fromSCN_act                     fromSCN_act,
          c1rec.toSCN_act                       toSCN_act,
          c1rec.toTime_act                      toTime_act,
          c1rec.rlgSCN_act                      rlgSCN_act,
          c1rec.rlgTime_act                     rlgTime_act,
          c1rec.dbincKey_act                    dbincKey_act,
          c1rec.level_act                       level_act,
          c1rec.section_size_act                section_size_act,
 
          c1rec.dfNumber_obj                    dfNumber_obj,
          c1rec.dfCreationSCN_obj               dfCreationSCN_obj,
          c1rec.cfSequence_obj                  cfSequence_obj,
          c1rec.cfDate_obj                      cfDate_obj,
          c1rec.logSequence_obj                 logSequence_obj,
          c1rec.logThread_obj                   logThread_obj,
          c1rec.logRlgSCN_obj                   logRlgSCN_obj,
          c1rec.logRlgTime_obj                  logRlgTime_obj,
          c1rec.logLowSCN_obj                   logLowSCN_obj,
          c1rec.logLowTime_obj                  logLowTime_obj,
          c1rec.logNextSCN_obj                  logNextSCN_obj,
          c1rec.logNextTime_obj                 logNextTime_obj,
          c1rec.logTerminal_obj                 logTerminal_obj,
          c1rec.cfType_obj                      cfType_obj,
          c1rec.pdbKey_obj                      pdbKey_obj,
 
          c1rec.keep_options                    keep_options,
          c1rec.keep_until                      keep_until,
 
          c1rec.afzSCN_act                      afzSCN_act,
          c1rec.rfzTime_act                     rfzTime_act,
          c1rec.rfzSCN_act                      rfzSCN_act,
          c1rec.media_con                       media_con,
          c1rec.isrdf_con                       isrdf_con,
          c1rec.site_key_con                    site_key_con,
          c1rec.foreignDbid_obj                 foreignDbid_obj,
          c1rec.pluggedRonly_obj                pluggedRonly_obj,
          c1rec.pluginSCN_obj                   pluginSCN_obj,
          c1rec.pluginRlgSCN_obj                pluginRlgSCN_obj,
          c1rec.pluginRlgTime_obj               pluginRlgTime_obj,
 
          c1rec.newDfCreationSCN_obj            newDfCreationSCN_obj,
          c1rec.newToSCN_act                    newToSCN_act,
          c1rec.newRlgSCN_act                   newRlgSCN_act,
          c1rec.newRlgTime_act                  newRlgTime_act,
          c1rec.sfDbUniqueName_obj              sfDbUniqueName_obj,
          c1rec.sparse_backup_con               sparse_backup_con,
          0                                     ppl_pdb_id_con,
          0                                     ppl_cdb_dbid_con
     FROM dual
    WHERE c1rec.type_con = backupSet_con_t
      AND ((canApplyAnyRedo     = TRUE# AND c1rec.dfNumber_obj <> 0) OR
           (craGetAllCfBackups = TRUE# AND c1rec.dfNumber_obj = 0) OR
           (c1rec.pluggedRonly_obj = 0 AND
            c1rec.dbincKey_act = rcvRecCursor1Filter_c.dbincKey) OR
           (c1rec.pluggedRonly_obj != 0 AND
            c1rec.pluginRlgSCN_obj = rcvRecCursor1Filter_c.dbincRlgSCN AND
            c1rec.pluginRlgTime_obj = rcvRecCursor1Filter_c.dbincRlgTime))
      AND (rcvRecCursor1Filter_c.dfCkpSCN IS NULL OR
           rmanCmd = blkRestoreCmd_t OR
           rcvRecCursor1Filter_c.dfCkpSCN < c1rec.toSCN_act)
      AND (rcvRecCursor1Filter_c.targetSCN IS NULL OR
           (c1rec.pluggedRonly_obj = 0 AND
            c1rec.toSCN_act <= rcvRecCursor1Filter_c.targetSCN) OR
           (c1rec.pluggedRonly_obj != 0 AND
            c1rec.pluginSCN_obj <= rcvRecCursor1Filter_c.targetSCN))
      AND ((c1rec.foreignDbid_obj = rcvRecCursor1Filter_c.foreignDbid) OR
           (c1rec.foreignDbid_obj = 0 AND
            c1rec.pluginSCN_obj = 0   AND
            rcvRecCursor1Filter_c.pluginSCN = 0))
--
--
--
   UNION ALL
 
--
 
   SELECT c1rec.type_con                        type_con,
          c1rec.key_con                         key_con,
          c1rec.recid_con                       recid_con,
          c1rec.stamp_con                       stamp_con,
          c1rec.setStamp_con                    setStamp_con,
          c1rec.setCount_con                    setCount_con,
          c1rec.bsRecid_con                     bsRecid_con,
          c1rec.bsStamp_con                     bsStamp_con,
          c1rec.bsKey_con                       bsKey_con,
          c1rec.bsLevel_con                     bsLevel_con,
          c1rec.bsType_con                      bsType_con,
          c1rec.elapseSecs_con                  elapseSecs_con,
          c1rec.pieceCount_con                  pieceCount_con,
          c1rec.fileName_con                    fileName_con,
          c1rec.tag_con                         tag_con,
          c1rec.copyNumber_con                  copyNumber_con,
          c1rec.status_con                      status_con,
          c1rec.blocks_con                      blocks_con,
          c1rec.blockSize_con                   blockSize_con,
          c1rec.deviceType_con                  deviceType_con,
          c1rec.compTime_con                    compTime_con,
          c1rec.cfCreationTime_con              cfCreationTime_con,
          c1rec.pieceNumber_con                 pieceNumber_con,
          c1rec.bpCompTime_con                  bpCompTime_con,
          c1rec.bpCompressed_con                bpCompressed_con,
          c1rec.multi_section_con               multi_section_con,
 
          c1rec.type_act                        type_act,
          c1rec.fromSCN_act                     fromSCN_act,
          c1rec.toSCN_act                       toSCN_act,
          c1rec.toTime_act                      toTime_act,
          c1rec.rlgSCN_act                      rlgSCN_act,
          c1rec.rlgTime_act                     rlgTime_act,
          c1rec.dbincKey_act                    dbincKey_act,
          c1rec.level_act                       level_act,
          c1rec.section_size_act                section_size_act,
 
          c1rec.dfNumber_obj                    dfNumber_obj,
          c1rec.dfCreationSCN_obj               dfCreationSCN_obj,
          c1rec.cfSequence_obj                  cfSequence_obj,
          c1rec.cfDate_obj                      cfDate_obj,
          c1rec.logSequence_obj                 logSequence_obj,
          c1rec.logThread_obj                   logThread_obj,
          c1rec.logRlgSCN_obj                   logRlgSCN_obj,
          c1rec.logRlgTime_obj                  logRlgTime_obj,
          c1rec.logLowSCN_obj                   logLowSCN_obj,
          c1rec.logLowTime_obj                  logLowTime_obj,
          c1rec.logNextSCN_obj                  logNextSCN_obj,
          c1rec.logNextTime_obj                 logNextTime_obj,
          c1rec.logTerminal_obj                 logTerminal_obj,
          c1rec.cfType_obj                      cfType_obj,
          c1rec.pdbKey_obj                      pdbKey_obj,
 
          c1rec.keep_options                    keep_options,
          c1rec.keep_until                      keep_until,
 
          c1rec.afzSCN_act                      afzSCN_act,
          c1rec.rfzTime_act                     rfzTime_act,
          c1rec.rfzSCN_act                      rfzSCN_act,
          c1rec.media_con                       media_con,
          c1rec.isrdf_con                       isrdf_con,
          c1rec.site_key_con                    site_key_con,
          c1rec.foreignDbid_obj                 foreignDbid_obj,
          c1rec.pluggedRonly_obj                pluggedRonly_obj,
          c1rec.pluginSCN_obj                   pluginSCN_obj,
          c1rec.pluginRlgSCN_obj                pluginRlgSCN_obj,
          c1rec.pluginRlgTime_obj               pluginRlgTime_obj,
 
          c1rec.newDfCreationSCN_obj            newDfCreationSCN_obj,
          c1rec.newToSCN_act                    newToSCN_act,
          c1rec.newRlgSCN_act                   newRlgSCN_act,
          c1rec.newRlgTime_act                  newRlgTime_act,
          c1rec.sfDbUniqueName_obj              sfDbUniqueName_obj,
          c1rec.sparse_backup_con               sparse_backup_con,
          0                                     ppl_pdb_id_con,
          0                                     ppl_cdb_dbid_con
     FROM dual
    WHERE c1rec.type_con = proxyCopy_con_t
      AND rmanCmd != blkRestoreCmd_t
      AND ((canApplyAnyRedo     = TRUE# AND c1rec.dfNumber_obj <> 0) OR
           (craGetAllCfBackups = TRUE# AND c1rec.dfNumber_obj = 0) OR
           (c1rec.pluggedRonly_obj = 0 AND
            c1rec.dbincKey_act = rcvRecCursor1Filter_c.dbincKey) OR
           (c1rec.pluggedRonly_obj != 0 AND
            c1rec.pluginRlgSCN_obj = rcvRecCursor1Filter_c.dbincRlgSCN AND
            c1rec.pluginRlgTime_obj = rcvRecCursor1Filter_c.dbincRlgTime))
      AND (rcvRecCursor1Filter_c.dfCkpSCN IS NULL OR
           rcvRecCursor1Filter_c.dfCkpSCN < c1rec.toSCN_act)
      AND (rcvRecCursor1Filter_c.targetSCN IS NULL OR
           (c1rec.pluggedRonly_obj = 0 AND
            c1rec.toSCN_act <= rcvRecCursor1Filter_c.targetSCN) OR
           (c1rec.pluggedRonly_obj != 0 AND
            c1rec.pluginSCN_obj <= rcvRecCursor1Filter_c.targetSCN))
      AND (restoreTag is NULL OR
           c1rec.tag_con = restoreTag OR
           computeRA_allRecords = TRUE#)
      AND ((c1rec.foreignDbid_obj = rcvRecCursor1Filter_c.foreignDbid) OR
           (c1rec.foreignDbid_obj = 0 AND
            c1rec.pluginSCN_obj = 0   AND
            rcvRecCursor1Filter_c.pluginSCN = 0));
--
--
--
 
CURSOR rcvRecCursor2_c(
   dbincKey      IN     number
  ,fno           IN     number
  ,creSCN        IN     number
  ,dfCkpSCN      IN     number
  ,dbincRlgSCN   IN     number
  ,dbincRlgTime  IN     date
  ,offlSCN       IN     number
  ,onlSCN        IN     number
  ,onlTime       IN     date
  ,cleanSCN      IN     number
  ,clean2SCN     IN     number
  ,clean2Time    IN     date
  ,targetSCN     IN     number
  ,c1frec        IN     rcvRec_t
  ,excludeAction IN     binary_integer
  ,foreignDbid    IN    number
  ,pluggedRonly   IN    binary_integer
  ,pluginSCN     IN     number
  ,pluginRlgSCN  IN     number
  ,pluginRlgTime IN     date)
RETURN rcvRec_t IS
 
--
 
   SELECT c1frec.type_con                       type_con,
          c1frec.key_con                        key_con,
          c1frec.recid_con                      recid_con,
          c1frec.stamp_con                      stamp_con,
          c1frec.setStamp_con                   setStamp_con,
          c1frec.setCount_con                   setCount_con,
          c1frec.bsRecid_con                    bsRecid_con,
          c1frec.bsStamp_con                    bsStamp_con,
          c1frec.bsKey_con                      bsKey_con,
          c1frec.bsLevel_con                    bsLevel_con,
          c1frec.bsType_con                     bsType_con,
          c1frec.elapseSecs_con                 elapseSecs_con,
          c1frec.pieceCount_con                 pieceCount_con,
          c1frec.fileName_con                   fileName_con,
          c1frec.tag_con                        tag_con,
          c1frec.copyNumber_con                 copyNumber_con,
          c1frec.status_con                     status_con,
          c1frec.blocks_con                     blocks_con,
          c1frec.blockSize_con                  blockSize_con,
 
          c1frec.deviceType_con                 deviceType_con,
          c1frec.compTime_con                   compTime_con,
          c1frec.cfCreationTime_con             cfCreationTime_con,
          c1frec.pieceNumber_con                pieceNumber_con,
          c1frec.bpCompTime_con                 bpCompTime_con,
          c1frec.bpCompressed_con               bpCompressed_con,
          c1frec.multi_section_con              multi_section_con,
 
          c1frec.type_act                       type_act,
          c1frec.fromSCN_act                    fromSCN_act,
          c1frec.toSCN_act                      toSCN_act,
          c1frec.toTime_act                     toTime_act,
          c1frec.rlgSCN_act                     rlgSCN_act,
          c1frec.rlgTime_act                    rlgTime_act,
          c1frec.dbincKey_act                   dbincKey_act,
          c1frec.level_act                      level_act,
          c1frec.section_size_act               section_size_act,
 
          c1frec.dfNumber_obj                   dfNumber_obj,
          c1frec.dfCreationSCN_obj              dfCreationSCN_obj,
          c1frec.cfSequence_obj                 cfSequence_obj,
          c1frec.cfDate_obj                     cfDate_obj,
          c1frec.logSequence_obj                logSequence_obj,
          c1frec.logThread_obj                  logThread_obj,
          c1frec.logRlgSCN_obj                  logRlgSCN_obj,
          c1frec.logRlgTime_obj                 logRlgTime_obj,
          c1frec.logLowSCN_obj                  logLowSCN_obj,
          c1frec.logLowTime_obj                 logLowTime_obj,
          c1frec.logNextSCN_obj                 logNextSCN_obj,
          c1frec.logNextTime_obj                logNextTime_obj,
          c1frec.logTerminal_obj                logTerminal_obj,
          c1frec.cfType_obj                     cfType_obj,
          c1frec.pdbKey_obj                     pdbKey_obj,
 
          c1frec.keep_options                   keep_options,
          c1frec.keep_until                     keep_until,
 
          c1frec.afzSCN_act                     afzSCN_act,
          c1frec.rfzTime_act                    rfzTime_act,
          c1frec.rfzSCN_act                     rfzSCN_act,
          c1frec.media_con                      media_con,
          c1frec.isrdf_con                      isrdf_con,
          c1frec.site_key_con                   site_key_con,
          c1frec.foreignDbid_obj                foreignDbid_obj,
          c1frec.pluggedRonly_obj               pluggedRonly_obj,
          c1frec.pluginSCN_obj                  pluginSCN_obj,
          c1frec.pluginRlgSCN_obj               pluginRlgSCN_obj,
          c1frec.pluginRlgTime_obj              pluginRlgTime_obj,
 
          c1frec.newDfCreationSCN_obj           newDfCreationSCN_obj,
          c1frec.newToSCN_act                   newToSCN_act,
          c1frec.newRlgSCN_act                  newRlgSCN_act,
          c1frec.newRlgTime_act                 newRlgTime_act,
          c1frec.sfDbUniqueName_obj             sfDbUniqueName_obj,
          c1frec.sparse_backup_con              sparse_backup_con,
          0                                     ppl_pdb_id_con,
          0                                     ppl_cdb_dbid_con
     FROM dual
    WHERE c1frec.type_con is not null
 
   UNION ALL
 
--
--
 
   SELECT offlineRangeRec_con_t                 type_con,
          to_number(null)                       key_con,
          to_number(null)                       recid_con,
          to_number(null)                       stamp_con,
          to_number(null)                       setStamp_con,
          to_number(null)                       setCount_con,
          to_number(null)                       bsRecid_con,
          to_number(null)                       bsStamp_con,
          to_number(null)                       bsKey_con,
          to_number(null)                       bsLevel_con,
          to_char(null)                         bsType_con,
          to_number(null)                       elapseSecs_con,
          to_number(null)                       pieceCount_con,
          to_char(null)                         fileName_con,
          to_char(null)                         tag_con,
          to_number(null)                       copyNumber_con,
          to_char(null)                         status_con,
          to_number(null)                       blocks_con,
          to_number(null)                       blockSize_con,
          to_char(null)                         deviceType_con,
          to_date(null)                         compTime_con,
          to_date(null)                         cfCreationTime_con,
          to_number(null)                       pieceNumber_con,
          to_date(null)                         bpCompTime_con,
          to_char(null)                         bpCompressed_con,
          to_char(null)                         multi_section_con,
 
          implicitRange_act_t                   type_act,
          rcvRecCursor2_c.offlSCN               fromSCN_act,
          rcvRecCursor2_c.onlSCN                toSCN_act,
          rcvRecCursor2_c.onlTime               toTime_act,
          rcvRecCursor2_c.dbincRlgSCN           rlgSCN_act,
          rcvRecCursor2_c.dbincRlgTime          rlgTime_act,
          rcvRecCursor2_c.dbincKey              dbincKey_act,
          to_number(null)                       level_act,
          0                                     section_size_act,
 
          fno                                   dfNumber_obj,
          crescn                                dfCreationSCN_obj,
          to_number(null)                       cfSequence_obj,
          to_date(null)                         cfDate_obj,
          to_number(null)                       logSequence_obj,
          to_number(null)                       logThread_obj,
          to_number(null)                       logRlgSCN_obj,
          to_date(null)                         logRlgTime_obj,
          to_number(null)                       logLowSCN_obj,
          to_date(null)                         logLowTime_obj,
          to_number(null)                       logNextSCN_obj,
          to_date(null)                         logNextTime_obj,
          to_char(null)                         logTerminal_obj,
          to_char(null)                         cfType_obj,
          to_number(null)                       pdbKey_obj,
 
          to_number(null)                       keep_options,
          to_date(null)                         keep_until,
 
          to_number(null)                       afzSCN_act,
          to_date(null)                         rfzTime_act,
          to_number(null)                       rfzSCN_act,
          to_char(null)                         media_con,
          'NO'                                  isrdf_con,
          0                                     site_key_con,
          rcvRecCursor2_c.foreignDbid           foreignDbid_obj,
          rcvRecCursor2_c.pluggedRonly          pluggedRonly_obj,
          rcvRecCursor2_c.pluginSCN             pluginSCN_obj,
          rcvRecCursor2_c.pluginRlgSCN          pluginRlgSCN_obj,
          rcvRecCursor2_c.pluginRlgTime         pluginRlgTime_obj,
 
          crescn                                newDfCreationSCN_obj,
          rcvRecCursor2_c.onlSCN                newToSCN_act,
          to_number(null)                       newRlgSCN_act,
          to_date(null)                         newRlgTime_act,
          to_char(null)                         sfDbUniqueName_obj,
          to_char(null)                         sparse_backup_con,
          0                                     ppl_pdb_id_con,
          0                                     ppl_cdb_dbid_con
     FROM dual
    WHERE bitand(rcvRecCursor2_c.excludeAction,implicitRange_act_t) = 0
      AND rcvRecCursor2_c.pluggedRonly = 0
      AND offlSCN <> 0
      AND (rcvRecCursor2_c.dfCkpSCN is null OR
           rcvRecCursor2_c.dfCkpSCN <=
           rcvRecCursor2_c.offlSCN)
      AND (rcvRecCursor2_c.onlSCN >=   -- belongs to this incarnation
           rcvRecCursor2_c.dbincRlgSCN)
      AND (rcvRecCursor2_c.targetSCN is null OR
           rcvRecCursor2_c.onlscn <=   -- don't advance ckpt beyond
           rcvRecCursor2_c.targetSCN)  -- targetSCN
      AND (untilSCN is null OR        -- don't advance ckpt beyond until scn
           rcvRecCursor2_c.onlSCN < untilSCN)
 
   UNION ALL
 
   SELECT offlineRangeRec_con_t                 type_con,
          to_number(null)                       key_con,
          to_number(null)                       recid_con,
          to_number(null)                       stamp_con,
          to_number(null)                       setStamp_con,
          to_number(null)                       setCount_con,
          to_number(null)                       bsRecid_con,
          to_number(null)                       bsStamp_con,
          to_number(null)                       bsKey_con,
          to_number(null)                       bsLevel_con,
          to_char(null)                         bsType_con,
          to_number(null)                       elapseSecs_con,
          to_number(null)                       pieceCount_con,
          to_char(null)                         fileName_con,
          to_char(null)                         tag_con,
          to_number(null)                       copyNumber_con,
          to_char(null)                         status_con,
          to_number(null)                       blocks_con,
          to_number(null)                       blockSize_con,
          to_char(null)                         deviceType_con,
          to_date(null)                         compTime_con,
          to_date(null)                         cfCreationTime_con,
          to_number(null)                       pieceNumber_con,
          to_date(null)                         bpCompTime_con,
          to_char(null)                         bpCompressed_con,
          to_char(null)                         multi_section_con,
 
          cleanRange_act_t                      type_act,
          rcvRecCursor2_c.cleanSCN              fromSCN_act,
          rcvRecCursor2_c.clean2SCN             toSCN_act,
          rcvRecCursor2_c.clean2Time            toTime_act,
          rcvRecCursor2_c.dbincRlgSCN           rlgSCN_act,
          rcvRecCursor2_c.dbincRlgTime          rlgTime_act,
          rcvRecCursor2_c.dbincKey              dbincKey_act,
          to_number(null)                       level_act,
          0                                     section_size_act,
 
          fno                                   dfNumber_obj,
          crescn                                dfCreationSCN_obj,
          to_number(null)                       cfSequence_obj,
          to_date(null)                         cfDate_obj,
          to_number(null)                       logSequence_obj,
          to_number(null)                       logThread_obj,
          to_number(null)                       logRlgSCN_obj,
          to_date(null)                         logRlgTime_obj,
          to_number(null)                       logLowSCN_obj,
          to_date(null)                         logLowTime_obj,
          to_number(null)                       logNextSCN_obj,
          to_date(null)                         logNextTime_obj,
          to_char(null)                         logTerminal_obj,
          to_char(null)                         cfType_obj,
          to_number(null)                       pdbKey_obj,
 
          to_number(null)                       keep_options,
          to_date(null)                         keep_until,
 
          to_number(null)                       afzSCN_act,
          to_date(null)                         rfzTime_act,
          to_number(null)                       rfzSCN_act,
          to_char(null)                         media_con,
          'NO'                                  isrdf_con,
          0                                     site_key_con,
          rcvRecCursor2_c.foreignDbid           foreignDbid_obj,
          rcvRecCursor2_c.pluggedRonly          pluggedRonly_obj,
          rcvRecCursor2_c.pluginSCN             pluginSCN_obj,
          rcvRecCursor2_c.pluginRlgSCN          pluginRlgSCN_obj,
          rcvRecCursor2_c.pluginRlgTime         pluginRlgTime_obj,
 
          crescn                                newDfCreationSCN_obj,
          rcvRecCursor2_c.clean2SCN             newToSCN_act,
          to_number(null)                       newRlgSCN_act,
          to_date(null)                         newRlgTime_act,
          to_char(null)                         sfDbUniqueName_obj,
          to_char(null)                         sparse_backup_con,
          0                                     ppl_pdb_id_con,
          0                                     ppl_cdb_dbid_con
     FROM dual
    WHERE bitand(rcvRecCursor2_c.excludeAction, cleanRange_act_t) = 0
      AND rcvRecCursor2_c.pluggedRonly = 0
      AND rcvRecCursor2_c.cleanscn <> 0
      AND (rcvRecCursor2_c.dfCkpSCN is null OR
           rcvRecCursor2_c.dfCkpSCN <=
           rcvRecCursor2_c.cleanscn)
      AND -- belongs to this incarnation
          (rcvRecCursor2_c.clean2scn >=
           rcvRecCursor2_c.dbincRlgSCN)
      AND -- ignore if starts beyond target
          (rcvRecCursor2_c.targetscn is null OR
           rcvRecCursor2_c.cleanscn <
           rcvRecCursor2_c.targetSCN)
      AND -- If clean2scn is infinite, then we processed this when scanning
--
          (rcvRecCursor2_c.targetSCN is null OR
           rcvRecCursor2_c.clean2SCN <=
           rcvRecCursor2_c.targetSCN)
      AND -- don't advance ckpt beyond until scn, unless we don't know
--
          (untilscn is null OR
           rcvRecCursor2_c.clean2SCN <= untilSCN OR
           rcvRecCursor2_c.clean2SCN = highscnval)
 
   UNION ALL
 
   SELECT offlineRangeRec_con_t                 type_con,
          to_number(null)                       key_con,
          to_number(null)                       recid_con,
          to_number(null)                       stamp_con,
          to_number(null)                       setStamp_con,
          to_number(null)                       setCount_con,
          to_number(null)                       bsRecid_con,
          to_number(null)                       bsStamp_con,
          to_number(null)                       bsKey_con,
          to_number(null)                       bsLevel_con,
          to_char(null)                         bsType_con,
          to_number(null)                       elapseSecs_con,
          to_number(null)                       pieceCount_con,
          to_char(null)                         fileName_con,
          to_char(null)                         tag_con,
          to_number(null)                       copyNumber_con,
          to_char(null)                         status_con,
          to_number(null)                       blocks_con,
          to_number(null)                       blockSize_con,
          to_char(null)                         deviceType_con,
          to_date(null)                         compTime_con,
          to_date(null)                         cfCreationTime_con,
          to_number(null)                       pieceNumber_con,
          to_date(null)                         bpCompTime_con,
          to_char(null)                         bpCompressed_con,
          to_char(null)                         multi_section_con,
          
          cleanRange_act_t                      type_act,
          rcvRecCursor2_c.pluginSCN             fromSCN_act,
          rcvRecCursor2_c.clean2SCN             toSCN_act,
          rcvRecCursor2_c.clean2Time            toTime_act,
          rcvRecCursor2_c.dbincRlgSCN           rlgSCN_act,
          rcvRecCursor2_c.dbincRlgTime          rlgTime_act,
          rcvRecCursor2_c.dbincKey              dbincKey_act,
          to_number(null)                       level_act,
          0                                     section_size_act,
 
          fno                                   dfNumber_obj,
          crescn                                dfCreationSCN_obj,
          to_number(null)                       cfSequence_obj,
          to_date(null)                         cfDate_obj,
          to_number(null)                       logSequence_obj,
          to_number(null)                       logThread_obj,
          to_number(null)                       logRlgSCN_obj,
          to_date(null)                         logRlgTime_obj,
          to_number(null)                       logLowSCN_obj,
          to_date(null)                         logLowTime_obj,
          to_number(null)                       logNextSCN_obj,
          to_date(null)                         logNextTime_obj,
          to_char(null)                         logTerminal_obj,
          to_char(null)                         cfType_obj,
          to_number(null)                       pdbKey_obj,
 
          to_number(null)                       keep_options,
          to_date(null)                         keep_until,
 
          to_number(null)                       afzSCN_act,
          to_date(null)                         rfzTime_act,
          to_number(null)                       rfzSCN_act,
          to_char(null)                         media_con,
          'NO'                                  isrdf_con,
          0                                     site_key_con,
          rcvRecCursor2_c.foreignDbid           foreignDbid_obj,
          rcvRecCursor2_c.pluggedRonly          pluggedRonly_obj,
          rcvRecCursor2_c.pluginSCN             pluginSCN_obj,
          rcvRecCursor2_c.pluginRlgSCN          pluginRlgSCN_obj,
          rcvRecCursor2_c.pluginRlgTime         pluginRlgTime_obj,
 
          crescn                                newDfCreationSCN_obj,
          rcvRecCursor2_c.clean2SCN             newToSCN_act,
          to_number(null)                       newRlgSCN_act,
          to_date(null)                         newRlgTime_act,
          to_char(null)                         sfDbUniqueName_obj,
          to_char(null)                         sparse_backup_con,
          0                                     ppl_pdb_id_con,
          0                                     ppl_cdb_dbid_con
 FROM dual
    WHERE bitand(rcvRecCursor2_c.excludeAction, cleanRange_act_t) = 0
      AND rcvRecCursor2_c.pluggedRonly = 1
      AND rcvRecCursor2_c.cleanscn <> 0
      AND rcvRecCursor2_c.cleanscn <= rcvRecCursor2_c.pluginSCN
      AND (rcvRecCursor2_c.dfCkpSCN is null OR
           rcvRecCursor2_c.dfCkpSCN <=
           rcvRecCursor2_c.pluginSCN)
      AND -- belongs to this incarnation
          (rcvRecCursor2_c.clean2scn >=
           rcvRecCursor2_c.dbincRlgSCN)
      AND -- ignore if starts beyond target
          (rcvRecCursor2_c.targetscn is null OR
           rcvRecCursor2_c.pluginSCN <
           rcvRecCursor2_c.targetSCN)
      AND -- If clean2scn is infinite, then we processed this when scanning
--
          (rcvRecCursor2_c.targetSCN is null OR
           rcvRecCursor2_c.clean2SCN <=
           rcvRecCursor2_c.targetSCN)
      AND -- don't advance ckpt beyond until scn, unless we don't know
--
          (untilscn is null OR
           rcvRecCursor2_c.clean2SCN <= untilSCN OR
           rcvRecCursor2_c.clean2SCN = highscnval)
 
   UNION ALL
 
   SELECT offlineRangeRec_con_t                 type_con,
          to_number(null)                       key_con,
          to_number(null)                       recid_con,
          to_number(null)                       stamp_con,
          to_number(null)                       setStamp_con,
          to_number(null)                       setCount_con,
          to_number(null)                       bsRecid_con,
          to_number(null)                       bsStamp_con,
          to_number(null)                       bsKey_con,
          to_number(null)                       bsLevel_con,
          to_char(null)                         bsType_con,
          to_number(null)                       elapseSecs_con,
          to_number(null)                       pieceCount_con,
          to_char(null)                         fileName_con,
          to_char(null)                         tag_con,
          to_number(null)                       copyNumber_con,
          to_char(null)                         status_con,
          to_number(null)                       blocks_con,
          to_number(null)                       blockSize_con,
          to_char(null)                         deviceType_con,
          to_date(null)                         compTime_con,
          to_date(null)                         cfCreationTime_con,
          to_number(null)                       pieceNumber_con,
          to_date(null)                         bpCompTime_con,
          to_char(null)                         bpCompressed_con,
          to_char(null)                         multi_section_con,
 
          cleanRange_act_t                      type_act,
          rcvRecCursor2_c.pluginSCN             fromSCN_act,
          rcvRecCursor2_c.crescn                toSCN_act,
          to_date(null)                         toTime_act,
          rcvRecCursor2_c.dbincRlgSCN           rlgSCN_act,
          rcvRecCursor2_c.dbincRlgTime          rlgTime_act,
          rcvRecCursor2_c.dbincKey              dbincKey_act,
          to_number(null)                       level_act,
          0                                     section_size_act,
 
          fno                                   dfNumber_obj,
          crescn                                dfCreationSCN_obj,
          to_number(null)                       cfSequence_obj,
          to_date(null)                         cfDate_obj,
          to_number(null)                       logSequence_obj,
          to_number(null)                       logThread_obj,
          to_number(null)                       logRlgSCN_obj,
          to_date(null)                         logRlgTime_obj,
          to_number(null)                       logLowSCN_obj,
          to_date(null)                         logLowTime_obj,
          to_number(null)                       logNextSCN_obj,
          to_date(null)                         logNextTime_obj,
          to_char(null)                         logTerminal_obj,
          to_char(null)                         cfType_obj,
          to_number(null)                       pdbKey_obj,
 
          to_number(null)                       keep_options,
          to_date(null)                         keep_until,
 
          to_number(null)                       afzSCN_act,
          to_date(null)                         rfzTime_act,
          to_number(null)                       rfzSCN_act,
          to_char(null)                         media_con,
          'NO'                                  isrdf_con,
          0                                     site_key_con,
          rcvRecCursor2_c.foreignDbid           foreignDbid_obj,
          rcvRecCursor2_c.pluggedRonly          pluggedRonly_obj,
          rcvRecCursor2_c.pluginSCN             pluginSCN_obj,
          rcvRecCursor2_c.pluginRlgSCN          pluginRlgSCN_obj,
          rcvRecCursor2_c.pluginRlgTime         pluginRlgTime_obj,
 
          crescn                                newDfCreationSCN_obj,
          crescn                                newToSCN_act,
          to_number(null)                       newRlgSCN_act,
          to_date(null)                         newRlgTime_act,
          to_char(null)                         sfDbUniqueName_obj,
          to_char(null)                         sparse_backup_con,
          0                                     ppl_pdb_id_con,
          0                                     ppl_cdb_dbid_con
     FROM dual
    WHERE bitand(rcvRecCursor2_c.excludeAction, cleanRange_act_t) = 0
      AND rcvRecCursor2_c.pluggedRonly = 0
      AND rcvRecCursor2_c.pluginSCN <> 0
      AND (rcvRecCursor2_c.dfCkpSCN is null OR
           rcvRecCursor2_c.dfCkpSCN <=
           rcvRecCursor2_c.pluginSCN)
      AND -- belongs to this incarnation
          (crescn >= rcvRecCursor2_c.dbincRlgSCN)
      AND (rcvRecCursor2_c.targetSCN is null OR
           crescn <=   -- don't advance ckpt beyond
           rcvRecCursor2_c.targetSCN)  -- targetSCN
      AND -- don't advance ckpt beyond until scn, unless we don't know
--
          (untilscn is null OR crescn < untilSCN)
 
   UNION ALL
 
   SELECT offlineRangeRec_con_t                 type_con,
          to_number(null)                       key_con,
          to_number(null)                       recid_con,
          to_number(null)                       stamp_con,
          to_number(null)                       setStamp_con,
          to_number(null)                       setCount_con,
          to_number(null)                       bsRecid_con,
          to_number(null)                       bsStamp_con,
          to_number(null)                       bsKey_con,
          to_number(null)                       bsLevel_con,
          to_char(null)                         bsType_con,
          to_number(null)                       elapseSecs_con,
          to_number(null)                       pieceCount_con,
          to_char(null)                         fileName_con,
          to_char(null)                         tag_con,
          to_number(null)                       copyNumber_con,
          to_char(null)                         status_con,
          to_number(null)                       blocks_con,
          to_number(null)                       blockSize_con,
          to_char(null)                         deviceType_con,
          to_date(null)                         compTime_con,
          to_date(null)                         cfCreationTime_con,
          to_number(null)                       pieceNumber_con,
          to_date(null)                         bpCompTime_con,
          to_char(null)                         bpCompressed_con,
          to_char(null)                         multi_section_con,
 
          spanningRange_act_t                   type_act,
          rcvRecCursor2_c.targetSCN             fromSCN_act,
          to_number(null)                       toSCN_act,
          to_date(null)                         toTime_act,
          rcvRecCursor2_c.dbincRlgSCN           rlgSCN_act,
 
          rcvRecCursor2_c.dbincRlgTime          rlgTime_act,
          rcvRecCursor2_c.dbincKey              dbincKey_act,
          to_number(null)                       level_act,
          0                                     section_size_act,
 
          fno                                   dfNumber_obj,
          crescn                                dfCreationSCN_obj,
          to_number(null)                       cfSequence_obj,
          to_date(null)                         cfDate_obj,
          to_number(null)                       logSequence_obj,
          to_number(null)                       logThread_obj,
          to_number(null)                       logRlgSCN_obj,
          to_date(null)                         logRlgTime_obj,
          to_number(null)                       logLowSCN_obj,
          to_date(null)                         logLowTime_obj,
          to_number(null)                       logNextSCN_obj,
          to_date(null)                         logNextTime_obj,
          to_char(null)                         logTerminal_obj,
          to_char(null)                         cfType_obj,
          to_number(null)                       pdbKey_obj,
 
          to_number(null)                       keep_options,
          to_date(null)                         keep_until,
 
          to_number(null)                       afzSCN_act,
          to_date(null)                         rfzTime_act,
          to_number(null)                       rfzSCN_act,
          to_char(null)                         media_con,
          'NO'                                  isrdf_con,
          0                                     site_key_con,
          rcvRecCursor2_c.foreignDbid           foreignDbid_obj,
          rcvRecCursor2_c.pluggedRonly          pluggedRonly_obj,
          rcvRecCursor2_c.pluginSCN             pluginSCN_obj,
          rcvRecCursor2_c.pluginRlgSCN          pluginRlgSCN_obj,
          rcvRecCursor2_c.pluginRlgTime         pluginRlgTime_obj,
 
          crescn                                newDfCreationSCN_obj,
          to_number(null)                       newToSCN_act,
          to_number(null)                       newRlgSCN_act,
          to_date(null)                         newRlgTime_act,
          to_char(null)                         sfDbUniqueName_obj,
          to_char(null)                         sparse_backup_con,
          0                                     ppl_pdb_id_con,
          0                                     ppl_cdb_dbid_con
     FROM dual
    WHERE bitand(rcvRecCursor2_c.excludeAction, spanningRange_act_t) = 0
--
--
      AND rcvRecCursor2_c.pluggedRonly = 0
      AND rcvRecCursor2_c.targetSCN <
          rcvRecCursor2_c.dbincRlgSCN
 
    ORDER BY newToSCN_act desc,
             fromSCN_act  desc,
             type_con     asc,
             stamp_con    desc;
 
--
--
--
CURSOR sinceLastBackedAL_c (devtype      IN VARCHAR2,
                            numofbackups IN NUMBER) IS
  SELECT * FROM
    (
    SELECT low_scn,
           next_scn,
           next_time,
           count(*) over
             (partition by sequence#, thread#, dbinc_key) nbackups
      FROM
      (
      SELECT sequence#,
             thread#,
             low_scn,
             next_scn,
             next_time,
             dbinc_key
        FROM brl,
          (SELECT UNIQUE bs.bs_key,
                         copy#,
                         pieces,
                         count(piece#) over
                           (partition by bs.bs_key, copy#) pieces_count,
                         device_type,
                         bs.completion_time
             FROM bs, bp
            WHERE bs.db_key   = this_db_key
              AND bp.status   = 'A'
              AND bs.bck_type = 'L'
              AND bs.bs_key   = bp.bs_key
              AND (devtype IS NULL OR devtype = device_type)
              AND ((user_site_key = bp.site_key) OR
                   (user_site_key IS NULL AND
                    ((disk_backups_shared=TRUE# AND bp.device_type = 'DISK') OR
                     (tape_backups_shared=TRUE# AND bp.device_type <>'DISK') OR
                     (this_site_key = nvl(bp.site_key, this_site_key)))))
          ) allbs
        WHERE brl.bs_key         = allbs.bs_key
          AND allbs.pieces_count = allbs.pieces
 
      UNION ALL
 
      SELECT sequence#,
             thread#,
             first_change#,
             next_change#,
             next_time,
             dbinc_key
        FROM rc_proxy_archivedlog
       WHERE db_key = this_db_key
         AND status = 'A'
         AND (devtype IS NULL OR devtype = device_type)
      )
    )
    WHERE nbackups >= numofbackups
  ORDER BY next_time       DESC;
 
 
--
CURSOR restore_point_c (con_id IN NUMBER, name  IN VARCHAR2) IS
  SELECT r.name,
         r.dbinc_key dbinc#,
         scn,
         creation_time,
         restore_point_time,
         guarantee_flashback_database guaranteed,
         preserved,
         d.reset_scn,
         d.reset_time,
         pdb.con_id con_id,
         r.clean clean
  FROM rc_restore_point r, dbinc d, pdb, pdb_dbinc
  WHERE d.dbinc_key = r.dbinc_key
    AND site_key = nvl(user_site_key, this_site_key)
    AND (r.name = restore_point_c.name OR restore_point_c.name is null)
    AND pdb.db_key = this_db_key
    AND r.pdb_key = pdb.pdb_key
    AND pdb_dbinc.pdb_key = pdb.pdb_key
    AND pdb_dbinc.drop_scn IS NULL
    AND pdb_dbinc.dbinc_key = this_dbinc_key
  ORDER BY decode(pdb.con_id, restore_point_c.con_id, -1, pdb.con_id),
        scn, creation_time;
 
 
--
CURSOR translatePdbName_c IS
   SELECT con_id, name, guid
     FROM rci_pdbinc_this_dbinc pdbinc
    WHERE pdbinc.dbinc_key  = this_dbinc_key
      AND (untilSCN IS NULL OR pdbinc.create_scn < untilSCN)
      AND (pdbinc.drop_scn IS NULL OR pdbinc.drop_scn > untilSCN)
      AND con_id > 1
 ORDER BY pdbinc.drop_scn desc;
 
--
CURSOR translatePdbFile_c(fromSCN IN number, toSCN IN number) IS
   SELECT con_id, file#, stop_change# stopSCN
     FROM rci_datafile_this_dbinc rcd
    WHERE rcd.dbinc_key  = this_dbinc_key
      AND decode(plugin_change#, 0, creation_change#, plugin_change#) <= toSCN
      AND (drop_change# is null OR drop_change# > fromSCN)
      AND (nvl(realf_site_key, translation_site_key) = site_key);
 
CURSOR translateNoBackupPdb_c(pdbname IN varchar2) IS
   SELECT decode(pdbinc.nobackup, 'Y', 1, 0) noBackupPdb
     FROM rci_pdbinc_this_dbinc pdbinc
    WHERE pdbinc.dbinc_key = this_dbinc_key
      AND pdbinc.name = translateNoBackupPdb_c.pdbname
      AND (untilSCN IS NULL OR pdbinc.create_scn < untilSCN)
      AND (pdbinc.drop_scn IS NULL OR pdbinc.drop_scn > untilSCN);
 
--
PROCEDURE debout(
   line IN varchar2
)
IS
    isrs            number;
BEGIN
--
--
   IF rsdebug IS NULL
   THEN
     SELECT COUNT(*) INTO isrs FROM user_tables WHERE table_name = 'BLOCKS';
     rsdebug := isrs > 0;
   END IF;
 
--
   IF rsdebug
   THEN
     EXECUTE IMMEDIATE 'BEGIN sys.kbrsi_icd.rsTrace(:1); END;' USING line;
   ELSE
     dbms_output.put_line(line);
   END IF;
 
EXCEPTION
   WHEN others THEN
     dbms_output.put_line(line);
END debout;
 
 
--
--
--
 
--
--
--
--
--
--
--
--
--
--
 
--
--
--
 
--
PROCEDURE deb(
   type IN number
  ,line IN varchar2 DEFAULT NULL
)
IS
    pname           varchar2(512);
    pref            varchar2(11) := 'DBGRCVMAN: ';
    dstr            varchar2(1000);
BEGIN
   IF (not debug) THEN
      RETURN;
   END IF;
 
   IF type = DEB_ENTER THEN
      pname := line;
      dstr := (pref||rpad(' ',pname_i)||'ENTERING '||pname);
      pname_i := pname_i + 1;
      last_pnames(pname_i) := pname;
   ELSIF type = DEB_IN THEN
      dstr := (pref||rpad(' ',pname_i+2)||last_pnames(pname_i)||
                           ' '||line);
   ELSIF type = DEB_EXIT THEN
      IF (pname_i >= 1) THEN
          pname := last_pnames(pname_i);
          pname_i := pname_i - 1;
      ELSE
          pname := DEB_DEF_PNAME;
      END IF;
      IF line is not NULL THEN
         dstr := (pref||rpad(' ', pname_i)||'EXITING '||pname||
                              ' '||line);
      ELSE
         dstr := (pref||rpad(' ', pname_i)||'EXITING '||pname);
      END IF;
   ELSIF type = DEB_OPEN THEN
      pname := last_pnames(pname_i);
      dstr := (pref||rpad(' ', pname_i)||'OPENING cursor '||
                           line||' in '||pname);
   ELSE
      dstr := (pref||line);
   END IF;
 
   debout(dstr);
 
EXCEPTION
   WHEN others THEN
      debout('caught exception during deb ' || substr(sqlerrm, 1, 512));
END;
 
FUNCTION bool2char(
   flag IN boolean)
RETURN varchar2 IS
BEGIN
   IF (flag) THEN
      RETURN 'TRUE';
   ELSE
      RETURN 'FALSE';
   END IF;
END bool2char;
 
--
--
--
 
--
PROCEDURE setAlTransClause(
   thread   IN NUMBER   DEFAULT NULL
  ,fromTime IN DATE     DEFAULT NULL
  ,toTime   IN DATE     DEFAULT NULL
  ,fromSCN  IN NUMBER   DEFAULT NULL
  ,toSCN    IN NUMBER   DEFAULT NULL
  ,fromSeq  IN NUMBER   DEFAULT NULL
  ,toSeq    IN NUMBER   DEFAULT NULL
  ,pattern  IN VARCHAR2 DEFAULT NULL)
IS
BEGIN
   tc_thread   := thread;
   tc_fromTime := fromTime;
   tc_toTime   := toTime;
   tc_fromSCN  := fromSCN;
   tc_toSCN    := toSCN;
   tc_fromSeq  := fromSeq;
   tc_toSeq    := toSeq;
   tc_pattern  := pattern;
   deb(DEB_PRINT, 'tc_thread='   || tc_thread);
   deb(DEB_PRINT, 'tc_fromSCN='  || fromSCN);
   deb(DEB_PRINT, 'tc_toSCN='    || toSCN);
   deb(DEB_PRINT, 'tc_fromSeq='  || fromSeq);
   deb(DEB_PRINT, 'tc_fromTime=' || fromTime);
   deb(DEB_PRINT, 'tc_toTime='   || toTime);
   deb(DEB_PRINT, 'tc_toSeq='    || toSeq);
   deb(DEB_PRINT, 'tc_pattern='  || pattern);
END setAlTransClause;
 
--
PROCEDURE setDfTransClause(
   fno IN NUMBER)
IS
BEGIN
   tc_fno(fno) := TRUE;
END setDfTransClause;
 
--
PROCEDURE setDBTransClause
IS
BEGIN
   deb(DEB_PRINT, 'tc_database=TRUE');
   tc_database := TRUE#;
END setDBTransClause;
 
--
PROCEDURE resetAlTransClause
IS
BEGIN
   tc_thread   := to_number(null);
   tc_fromTime := to_date(null);
   tc_toTime   := to_date(null);
   tc_fromSCN  := to_number(null);
   tc_toSCN    := to_number(null);
   tc_fromSeq  := to_number(null);
   tc_toSeq    := to_number(null);
   tc_pattern  := to_char(null);
   currInc     := -1;
   getArchivedLogDoingRecovery := FALSE#;    -- clear for next time
   getArchivedLogOnlyrdf := 0;
   tc_threadSeq.delete;
END resetAlTransClause;
 
--
PROCEDURE resetDBTransClause
IS
BEGIN
   tc_database := FALSE#;
   tc_fno.delete;
END resetDBTransClause;
 
--
PROCEDURE resetDbidTransClause
IS
BEGIN
   tc_anydbid := FALSE#;
   tc_dbid.delete;
END resetDBidTransClause;
 
--
--
--
 
--
 
--
FUNCTION skipTableSpace(
   tsName   IN varchar2
  ,pdbId    IN number)
RETURN boolean IS
BEGIN
   deb(DEB_ENTER, 'skipTableSpace');
   FOR i in 1..skipTablespaceList.count LOOP
      IF (tsName = skipTablespaceList(i).name AND
          pdbId  = skipTablespaceList(i).pdbId) THEN
         deb(DEB_EXIT, 'with: TRUE');
         RETURN TRUE;
      END IF;
   END LOOP;
   deb(DEB_EXIT, 'with: FALSE');
   RETURN FALSE;
END;
 
--
FUNCTION isDeviceTypeAllocated(
   deviceType IN varchar2)
RETURN NUMBER IS
BEGIN
   IF (anyDevice = TRUE#) THEN
      RETURN TRUE#;
   END IF;
 
   FOR i IN 1..deviceCount LOOP
      IF deviceType = deviceList(i) THEN
         RETURN TRUE#;
      END IF;
   END LOOP;
 
   RETURN FALSE#;
END isDeviceTypeAllocated;
 
--
--
--
 
--
--
--
--
FUNCTION computeAvailableMask(
   available            IN number
  ,unavailable          IN number
  ,deleted              IN number
  ,expired              IN number
  ,partial_avail        IN number DEFAULT 0)
RETURN binary_integer IS
   rc           binary_integer := 0;
BEGIN
   deb(DEB_ENTER, 'computeAvailableMask');
   IF (available > 0) THEN
      rc := rc + dbms_rcvman.BSavailable;
   END IF;
   IF (unavailable > 0 ) THEN
      rc := rc + dbms_rcvman.BSunavailable;
   END IF;
   IF (deleted > 0 ) THEN
      rc := rc + dbms_rcvman.BSdeleted;
   END IF;
   IF (expired > 0 ) THEN
      rc := rc + dbms_rcvman.BSexpired;
   END IF;
   IF (partial_avail > 0 ) THEN
      rc := rc + dbms_rcvman.BSpartial_avail;
   END IF;
 
   deb(DEB_EXIT, 'with rc:'||to_char(rc));
   RETURN rc;
END computeAvailableMask;
 
--
FUNCTION validateBackupSet0(
   tag                     IN     varchar2 DEFAULT NULL
  ,tagMatchRequired        IN     boolean  DEFAULT TRUE
  ,checkDeviceIsAllocated  IN     boolean  DEFAULT TRUE
  ,validRec                OUT    NOCOPY validBackupSetRec_t)
RETURN binary_integer IS
   local        validBackupSetRec_t;
   rc           binary_integer;
   gotRecord    number;
BEGIN
   deb(DEB_ENTER, 'validateBackupSet0');
   <<validationLoop>>
   LOOP
      <<nextRow>>
      gotRecord := getValidBackupSet(validBackupSetRec      => local,
                                     checkDeviceIsAllocated => FALSE#);
 
      EXIT WHEN gotRecord = FALSE#;             -- cursor is closed already
 
      IF (checkDeviceIsAllocated) THEN
         IF (anyDevice = FALSE# AND
             isDeviceTypeAllocated(local.deviceType) = FALSE#) THEN
            deb(DEB_IN, 'device is not allocated');
--
--
            IF (rc IS NULL OR rc <> SUCCESS) THEN
               deb(DEB_IN, 'set rc to available');
               rc := dbms_rcvman.AVAILABLE;
            END IF;
            GOTO nextRow;
         END IF;
      END IF;
 
      validRec := local;                        -- set OUT mode arg
 
      IF (tag IS NOT NULL AND NOT tagMatchRequired) THEN
--
--
--
--
         IF (tag = local.tag) THEN
--
--
--
--
--
--
--
            deb(DEB_IN, 'tag matches');
            rc := SUCCESS;
            deb(DEB_IN, 'exiting loop with rc: SUCCESS');
            EXIT validationLoop;
         ELSE
--
--
--
            deb(DEB_IN, 'tag does not match, continuing search');
            rc := SUCCESS;
         END IF;
      ELSE
--
--
--
         rc := SUCCESS;
         deb(DEB_IN, 'exiting loop with rc: SUCCESS');
         EXIT validationLoop;
      END IF;
   END LOOP;
 
   IF (rc IS NULL) THEN
      deb(DEB_IN, 'rc is null, setting to unavailable');
      rc := dbms_rcvman.UNAVAILABLE;
   END IF;
 
   deb(DEB_EXIT, 'with rc:'||to_char(rc));
   RETURN rc;
 
END validateBackupSet0;
 
--
--
--
 
--
FUNCTION getRecStackCount
RETURN binary_integer IS
BEGIN
  RETURN rcvRecStack.count;
END getRecStackCount;
 
--
FUNCTION getRecFullCount
RETURN binary_integer IS
BEGIN
  RETURN rcvRecStackState.fullBackups;
END getRecFullCount;
 
--
PROCEDURE rcvRecPush(
   rcvRec IN rcvRec_t)
IS
BEGIN
   rcvRecStack.extend;
   deb(DEB_PRINT,'rcvRecPush:from_scn='||rcvRec.fromSCN_act||',to_scn='||rcvRec.toSCN_act||',rcvRecStackCount='||rcvRecStack.count);
   rcvRecStack(rcvRecStack.last) := rcvRec;
END rcvRecPush;
 
--
PROCEDURE rcvRecGet(
   indx   IN  number
  ,rcvRec OUT NOCOPY rcvRec_t)
IS
BEGIN
   rcvRec := rcvRecStack(indx);
END rcvRecGet;
 
--
PROCEDURE rcvRecTop(
   rcvRec OUT NOCOPY rcvRec_t)
IS
BEGIN
   IF (rcvRecStack.count = 0) THEN
      rcvRec := NULL;
   ELSE
      rcvRecGet(rcvRecStack.count, rcvRec);
      deb(DEB_PRINT,'rcvRecPop:from_scn='||rcvRec.fromSCN_act||
                    ',to_scn='||rcvRec.toSCN_act||
                    ',rcvRecStackCount='||rcvRecStack.count );
   END IF;
END rcvRecTop;
 
--
PROCEDURE rcvRecPop(
   rcvRec OUT NOCOPY rcvRec_t)
IS
BEGIN
   rcvRecTop(rcvRec);
   rcvRecStack.trim;
END rcvRecPop;
 
--
PROCEDURE rcvRecConvert(
   rcvRec IN OUT NOCOPY rcvRec_t)
IS
BEGIN
--
--
 
  rcvRec.recid_con      := nvl(rcvRec.recid_con, 0);
  rcvRec.stamp_con      := nvl(rcvRec.stamp_con, 0);
  rcvRec.setStamp_con   := nvl(rcvRec.setStamp_con, 0);
  rcvRec.setCount_con   := nvl(rcvRec.setCount_con, 0);
  rcvRec.fileName_con   := nvl(rcvRec.fileName_con, 'NULL');
  rcvRec.blockSize_con  := nvl(rcvRec.blockSize_con, 0);
  rcvRec.blocks_con     := nvl(rcvRec.blocks_con, 0);
  rcvRec.deviceType_con := nvl(rcvRec.deviceType_con, 'NULL');
END rcvRecConvert;
 
--
PROCEDURE printRcvRec(
   action  IN rcvRec_t
  ,summary IN boolean default FALSE)
IS
   l              varchar2(600);
   cfcretime      varchar2(100);
   action_deleted boolean;
 
   procedure prt(str in out varchar2) is begin
      if length(str) > 2 then
         deb(DEB_PRINT, str);
         str := ' ';
      end if;
   end;
BEGIN
 
--
--
--
   deb(DEB_PRINT, 'DUMPING RECOVERY CONTAINER');
--
   IF (action.type_con = backupSet_con_t) THEN
      IF (action.type_act = full_act_t) THEN
         deb(DEB_PRINT, ' Full Backup Set');
      ELSE
         deb(DEB_PRINT, ' Incremental Backup Set');
      END IF;
   ELSIF (action.type_con = proxyCopy_con_t) THEN
      deb(DEB_PRINT, ' Proxy Backup');
   ELSIF (action.type_con = imageCopy_con_t) THEN
      deb(DEB_PRINT, ' Datafile Copy');
   ELSIF (action.type_con = offlineRangeRec_con_t) THEN
      IF (action.type_act = offlineRange_act_t) THEN
         deb(DEB_PRINT, ' Offline Range Record');
      ELSIF (action.type_act = cleanRange_act_t) THEN
         deb(DEB_PRINT, ' Clean Range');
      ELSIF (action.type_act = implicitRange_act_t) THEN
         deb(DEB_PRINT, ' Implicit Offline Range');
      ELSIF (action.type_act = spanningRange_act_t) THEN
         deb(DEB_PRINT, ' Spanning Offline Range');
      ELSE
         deb(DEB_PRINT, ' Unknown Offline Range Action Type');
      END IF;
   ELSIF (action.type_con = datafile_con_t) THEN
      deb(DEB_PRINT, ' datafile container type');
   ELSIF (action.type_con = addredo_con_t) THEN
      deb(DEB_PRINT,'Add Redo');
   ELSE
      deb(DEB_PRINT, ' Unknown recovery container type');
   END IF;
 
--
   IF (action.type_con = backupSet_con_t) THEN
      deb(DEB_PRINT, '   bsKey=' || to_char(action.bsKey_con) ||
          '  bsRecid=' || to_char(action.bsRecid_con) ||
          '  bsStamp=' || to_char(action.bsStamp_con) ||
          '  setStamp=' || to_char(action.setStamp_con) ||
          '  setCount=' || to_char(action.setCount_con) ||
          '  site_key=' || to_char(action.site_key_con));
      deb(DEB_PRINT, '   bsLevel=' || to_char(action.bsLevel_con) ||
          '  bsType=' || action.bsType_con ||
          '  pieceCount=' || to_char(action.pieceCount_con));
      deb(DEB_PRINT, '   multi_section=' ||
                     nvl(action.multi_section_con, 'NULL'));
   ELSIF (action.type_con = proxyCopy_con_t OR
          action.type_con = imageCopy_con_t) THEN
      deb(DEB_PRINT, '   fileName=' || action.fileName_con);
      deb(DEB_PRINT, '   media=' || action.media_con);
   END IF;
 
   IF (summary) THEN
      RETURN;
   END IF;
 
--
   l := ' ';
 
--
   IF (action.key_con is not null) THEN
      l := l || '  key=' || to_char(action.key_con);
   END IF;
 
--
   IF (action.recid_con is not null) THEN
      l := l || '  recid=' || to_char(action.recid_con) ||
                '  stamp=' || to_char(action.stamp_con);
   END IF;
 
--
   IF (action.status_con is not null) THEN
      l := l || '  status=' || action.status_con;
   END IF;
 
   IF (action.type_con = imageCopy_con_t OR
       action.type_con = backupSet_con_t) THEN
      l := l || '  sparse_backup_con =' || action.sparse_backup_con;
   END IF;
 
 
   prt(l);
 
--
   IF (action.tag_con is not null) THEN
      l := l || '  tag=' || action.tag_con;
   END IF;
 
--
   IF (action.compTime_con is not null) THEN
      l := l || '  compTime=' || to_char(action.compTime_con);
   END IF;
 
   prt(l);
 
   IF (action.deviceType_con is not null) THEN
      l := l || '  deviceType=' || action.deviceType_con;
   END IF;
 
   IF (action.blocks_con is not null) THEN
      l := l || '  blocks=' || to_char(action.blocks_con) ||
           '  blockSize=' || to_char(action.blockSize_con);
   END IF;
 
   IF (action.cfCreationTime_con is not null) THEN
      l := l || '  cfCreationTime=' || to_char(action.cfCreationTime_con);
   END IF;
 
   IF (action.pieceNumber_con is not null) THEN
      l := l || '  pieceNumberl=' || to_char(action.pieceNumber_con);
   END IF;
 
   IF (action.bpCompTime_con is not null) THEN
      l := l || '  bpCompTime=' || to_char(action.bpCompTime_con);
   END IF;
 
   IF (action.bpCompressed_con is not null) THEN
      l := l || '  bpCompressed=' || to_char(action.bpCompressed_con);
   END IF;
 
   prt(l);
 
--
--
--
 
--
   IF (action.fromSCN_act is not null) THEN
      l := l || '  fromSCN=' || to_char(action.fromSCN_act);
   END IF;
 
--
   IF (action.toSCN_act is not null) THEN
      l := l || '  toSCN=' || to_char(action.toSCN_act) ||
           '  toTime=' || to_char(action.toTime_act);
   END IF;
 
--
   IF (action.level_act is not null) THEN
      l := l || '  level=' || to_char(action.level_act);
   END IF;
 
--
   IF (action.section_size_act is not null) THEN
      l := l || '  section_size=' || to_char(action.section_size_act);
   END IF;
 
   prt(l);
 
   IF (action.rlgSCN_act is not null) THEN
      l := l || '  rlgSCN=' || to_char(action.rlgSCN_act) ||
           '  rlgTime=' || to_char(action.rlgTime_act) ||
           '  dbincKey=' || to_char(action.dbincKey_act);
   END IF;
 
   prt(l);
 
   IF (action.afzSCN_act is not null) THEN
      l := l || '  afzSCN=' || to_char(action.afzSCN_act);
   END IF;
 
   prt(l);
 
   IF (action.rfzSCN_act is not null AND action.rfzSCN_act != 0) THEN
      l := l || '  rfzSCN=' || to_char(action.rfzSCN_act) ||
           '  rfzTime=' || nvl(to_char(action.rfzTime_act), 'NULL');
   END IF;
 
   prt(l);
 
--
--
--
 
   IF (action.pdbKey_obj IS NOT NULL) THEN
      l := l || ' pdbKey=' || to_char(action.pdbKey_obj);
   END IF;
 
   prt(l);
 
   IF (action.dfNumber_obj IS NOT NULL) THEN
      l := l || '  dfNumber=' || to_char(action.dfNumber_obj) ||
                '  creationSCN=' || to_char(action.dfCreationSCN_obj) ||
                '  pluginSCN=' || to_char(action.pluginSCN_obj) ||
                '  foreignDbid=' || to_char(action.foreignDbid_obj) ||
                '  pluggedRonly=' || to_char(action.pluggedRonly_obj);
      deb(DEB_PRINT, l);
      l := ' ';
      l := l || '  cfType=' || nvl(action.cfType_obj, 'NULL');
      deb(DEB_PRINT, l);
      l := ' ';
      l := l || '  keep_options=' || nvl(to_char(action.keep_options), 'NULL') ||
                '  keep_until='   || nvl(to_char(action.keep_until), 'NULL');
      deb(DEB_PRINT, l);
      IF (action.cfSequence_obj IS NOT NULL) THEN
         l := ' ';
         l := l || '  cfSequence=' || to_char(action.cfSequence_obj) ||
                   '  cfDate=' || nvl(to_char(action.cfDate_obj), 'NULL');
         deb(DEB_PRINT, l);
      END IF;
   ELSIF (action.logSequence_obj IS NOT NULL) THEN
      l := l || '  logSequence=' || to_char(action.logSequence_obj);
      deb(DEB_PRINT, l);
      l := ' ';
      l := l || '  logThread=' || to_char(action.logThread_obj);
      deb(DEB_PRINT, l);
      l := ' ';
      l := l || '  logLowSCN=' || to_char(action.logLowSCN_obj);
      deb(DEB_PRINT, l);
      l := ' ';
      l := l || '  logLowTime=' || to_char(action.logLowTime_obj);
      deb(DEB_PRINT, l);
      l := ' ';
      l := l || '  logNextSCN=' || nvl(to_char(action.logNextSCN_obj), 'NULL');
      deb(DEB_PRINT, l);
      l := ' ';
      l := l || '  logNextTime=' || nvl(to_char(action.logNextTime_obj), 'NULL');
      deb(DEB_PRINT, l);
      l := ' ';
      l := l || '  logTerminalEor=' || action.logTerminal_obj;
      deb(DEB_PRINT, l);
      l := ' ';
      l := l || '  logRlgSCN=' || nvl(to_char(action.logRlgSCN_obj), 'NULL');
      deb(DEB_PRINT, l);
      l := ' ';
      l := l || '  logRlgTime=' || nvl(to_char(action.logRlgTime_obj), 'NULL');
      deb(DEB_PRINT, l);
   ELSIF (action.toTime_act IS NOT NULL) THEN
      deb(DEB_PRINT, '  SPFILE');
      deb(DEB_PRINT, '  modification_time=' ||  to_char(action.toTime_act));
      deb(DEB_PRINT, '  db_unique_name=' || action.sfDbUniqueName_obj);
 
      l := ' ';
      l := l || '  keep_options=' || nvl(to_char(action.keep_options), 'NULL') ||
                '  keep_until='   || nvl(to_char(action.keep_until), 'NULL');
      deb(DEB_PRINT, l);
   ELSE
      deb(DEB_PRINT, '  Unknown Recovery Object');
   END IF;
 
EXCEPTION
   WHEN OTHERS THEN
   deb(DEB_PRINT, 'printRcvRec: caught an exception, aborting print');
   RETURN;
END printRcvRec;
 
--
--
--
 
--
FUNCTION redoNeeded(
   action IN rcvRec_t)
RETURN boolean IS
BEGIN
   deb(DEB_ENTER, 'redoNeeded');
   IF (rcvRecStackState.lowAction > 0 AND   -- Have a non-full_act_t on stack?
       action.toSCN_act <
       rcvRecStack(rcvRecStackState.lowAction).fromSCN_act) THEN
      deb(DEB_EXIT, 'with: TRUE');
      RETURN TRUE;
   ELSE
      deb(DEB_EXIT, 'with: FALSE');
      RETURN FALSE;
   END IF;
END redoNeeded;
 
--
FUNCTION canAddRedo(
   isAncestor    IN boolean
  ,from_scn      IN number
  ,from_rlgscn   IN number
  ,to_action     IN rcvRec_t
  ,partial_rcv   IN boolean
  ,doingRecovery IN boolean)
RETURN number IS
BEGIN
   deb(DEB_ENTER, 'canAddRedo');
   IF (from_rlgscn = this_reset_scn) THEN
      IF (partial_rcv) THEN
         deb(DEB_EXIT, 'with: action_OK');
         RETURN action_OK;
      ELSE
--
--
--
--
--
--
--
--
--
--
--
--
         deb(DEB_EXIT, 'with: action_FAIL');
         RETURN action_FAIL;
      END IF;
   ELSE
      deb(DEB_IN, 'from_rlgscn=' || nvl(to_char(from_rlgscn), 'NULL') ||
          ' this_reset_scn=' || to_char(this_reset_scn));
      IF (isAncestor) THEN
         deb(DEB_IN, 'isAncestor is TRUE;');
         IF (canApplyAnyRedo = TRUE# AND
             from_scn >=
               nvl(inc_list(max_inc_idx-1).prior_resetlogs_change#,
                   inc_list(max_inc_idx-1).resetlogs_change#)) THEN
            deb(DEB_PRINT, 'canAddRedo: return action_OLD_INC_REDO');
            return action_OLD_INC_REDO;
         ELSE
--
--
--
--
--
--
--
--
--
--
--
--
--
--
            IF (doingRecovery) THEN
              deb(DEB_PRINT, 'with: action_OLD_REDO (doingRecovery)');
              RETURN action_OLD_REDO;
            ELSIF (allIncarnations = TRUE#) THEN
              deb(DEB_PRINT, 'canAddRedo: returning action_OK');
              RETURN action_OK;
            ELSE
              deb(DEB_PRINT, 'canAddRedo: returning action_OLD_REDO');
              RETURN action_OLD_REDO;
            END IF;
         END IF;
      ELSE
         deb(DEB_IN, 'isAncestor is FALSE;');
--
--
         deb(DEB_EXIT, 'with: action_OLD_REDO');
         RETURN action_OLD_REDO;
      END IF;
   END IF;
   deb(DEB_EXIT, 'with undefined status');
END canAddRedo;
 
--
FUNCTION addRedo(
   isAncestor    IN boolean
  ,from_scn      IN number
  ,from_rlgscn   IN number
  ,to_action     IN rcvRec_t
  ,partial_rcv   IN boolean
  ,doingRecovery IN boolean)
RETURN number IS
   canAdd      number;
BEGIN
   deb(DEB_ENTER, 'addRedo');
   deb(DEB_IN,'Enter - from_scn=' || from_scn|| ',from_rlgscn=' ||from_rlgscn);
 
   canAdd := canAddRedo(isAncestor, from_scn, from_rlgscn,
                        to_action, partial_rcv, doingRecovery);
   IF (canAdd = action_FAIL) THEN
--
--
--
--
--
--
 
--
--
--
--
--
--
      rcvRecStackState.lowAction := 0;
 
      rcvRecStack.trim(rcvRecStack.last -
                       greatest(rcvRecStackState.savePoint,
                                rcvRecStackState.top));
 
      deb(DEB_IN,'trimming savepoint1, rcvRecStackCount='|| rcvRecStack.count);
      deb(DEB_EXIT, 'with: action_FAIL');
      RETURN action_FAIL;
   ELSIF (canAdd = action_OK) THEN
      redoRec.type_act          := redo_act_t;
      redoRec.fromSCN_act       := from_scn;
      redoRec.toSCN_act         := to_action.fromSCN_act;
      redoRec.toTime_act        := to_date(null);
      redoRec.rlgSCN_act        := from_rlgscn;
      redoRec.dfNumber_obj      := to_action.dfNumber_obj;
      redoRec.dfCreationSCN_obj := to_action.dfCreationSCN_obj;
      redoRec.pluginSCN_obj     := 0;
      redoRec.pluggedRonly_obj  := 0;
      rcvRecPush(redoRec);
 
      deb(DEB_EXIT, 'with: action_OK');
      RETURN action_OK;
   ELSIF (canAdd = action_OLD_INC_REDO) THEN
      redoRec.type_con          := addredo_con_t;
      redoRec.type_act          := redo_act_t;
      redoRec.fromSCN_act       := from_scn;
      redoRec.toSCN_act         := to_action.fromSCN_act;
      redoRec.toTime_act        := to_date(null);
      redoRec.rlgSCN_act        := from_rlgscn;
      redoRec.dfNumber_obj      := to_action.dfNumber_obj;
      redoRec.dfCreationSCN_obj := to_action.dfCreationSCN_obj;
      redoRec.pluginSCN_obj     := 0;
      redoRec.pluggedRonly_obj  := 0;
 
      deb(DEB_EXIT, 'with: action_OLD_INC_REDO');
      RETURN action_OLD_INC_REDO;
   ELSE                                         -- ancestral incarnation
--
--
--
--
      deb(DEB_EXIT, 'with: action_OLD_REDO');
      RETURN action_OLD_REDO;
   END IF;
   deb(DEB_EXIT, 'with undefined status');
END addRedo;
 
--
--
FUNCTION isPdbScnOrphan(fromSCN IN NUMBER,
                        toSCN   IN NUMBER,
                        afzSCN  IN NUMBER,
                        pdbId   IN NUMBER)
RETURN BOOLEAN IS
--
   l_afzSCN NUMBER := nvl(greatest(afzSCN, toSCN), toSCN);
BEGIN
   IF (pdb_inc_list.exists(pdbId)) THEN
      FOR inc_idx in 0..pdb_inc_list(pdbId).count-1 LOOP
         IF ((fromSCN = 0 OR
              fromSCN > pdb_inc_list(pdbId)(inc_idx).erscn) AND
             (l_afzSCN > pdb_inc_list(pdbId)(inc_idx).erscn)) THEN
            EXIT;
         END IF;
 
         IF ((fromSCN  >= pdb_inc_list(pdbId)(inc_idx).incscn AND
              fromSCN  <= pdb_inc_list(pdbId)(inc_idx).erscn) OR
             (l_afzSCN >= pdb_inc_list(pdbId)(inc_idx).incscn AND
              l_afzSCN <= pdb_inc_list(pdbId)(inc_idx).erscn)) THEN
            deb(DEB_PRINT, 'isPdbScnOrphan: inc=' || inc_idx||
                           ',fromSCN =' || fromSCN ||
                           ',toSCN ='   || toSCN   ||
                           ',afzSCN ='  || nvl(afzSCN, '')  ||
                           ',incSCN ='  ||
                           pdb_inc_list(pdbId)(inc_idx).incscn ||
                           ',erscn=' ||
                           pdb_inc_list(pdbId)(inc_idx).erscn);
            deb(DEB_PRINT, 'isPdbScnOrphan: belongs to orphan branch ' ||
                           'of this sub incarnation:');
            RETURN TRUE;
         END IF;
      END LOOP;
   END IF;
 
   RETURN FALSE;
END isPdbScnOrphan;
 
--
--
--
FUNCTION CheckRecAction(
   action   IN rcvRec_t
  ,pdbId    IN number
  ,cleanSCN IN number)
RETURN number IS
   rlgSCN   number;
   rlgTime  date;
   toSCN    number;
   fromSCN  number;
   afzSCN   number;
   creSCN   number;
BEGIN
 
  IF (canApplyAnyRedo = FALSE#) THEN
     return SUCCESS;
  END IF;
 
  IF (action.pluggedRonly_obj != 0) THEN
     deb(DEB_PRINT, 'CheckRecAction called for plugged readonly action');
 
     rlgSCN  := action.pluginRlgSCN_obj;
     rlgTime := action.pluginRlgTime_obj;
 
     toSCN   := action.pluginSCN_obj;
     fromSCN := action.pluginSCN_obj;
     creSCN  := action.pluginSCN_obj;
  ELSE
     rlgSCN  := action.rlgSCN_act;
     rlgTime := action.rlgTime_act;
 
     toSCN   := action.toSCN_act;
     fromSCN := action.fromSCN_act;
     afzSCN  := action.afzSCN_act;
     creSCN  := action.dfCreationSCN_obj;
  END IF;
 
  deb(DEB_PRINT, ' CheckRecAction called '||
                   to_char(rlgTime,'MM/DD/RR HH24:MI:SS')||
                  '; rlgscn='||rlgSCN || '; pdbId=' || pdbId ||
                  '; cleanscn=' || nvl(to_char(cleanSCN), 'NULL'));
 
  IF (action.type_con = backupSet_con_t OR
      action.type_con = imageCopy_con_t OR
      action.type_con = proxyCopy_con_t OR
      action.type_con = offlineRangeRec_con_t) THEN
    FOR inc_idx in 0..max_inc_idx-1 LOOP
      IF (rlgSCN = inc_list(inc_idx).resetlogs_change#  AND
          rlgTime = inc_list(inc_idx).resetlogs_time ) THEN
        IF (inc_idx = 0 OR
            nvl(greatest(afzSCN, toSCN), toSCN) <
               inc_list(inc_idx-1).resetlogs_change#) THEN
           deb(DEB_PRINT, 'CheckRecAction:matches inc='||inc_idx||
                          ',fromscn='|| fromSCN ||
                          ',toscn='  || toSCN   ||
                          ',afzSCN=' || nvl(afzSCN, ''));
           IF (pdbId > 1 AND
               isPdbScnOrphan(fromSCN, toSCN, afzSCN, pdbId)) THEN
              return action_SKIP;
           END IF;
 
           IF (action.type_con = offlineRangeRec_con_t AND 
                    (fromSCN > skipOfflineRangeAboveSCN OR 
                     toSCN > skipOfflineRangeAboveSCN)) THEN
               return action_SKIP; 
           ELSE
              return SUCCESS;
           END IF;
        ELSE
           deb(DEB_PRINT, 'CheckRecAction: inc='||inc_idx||
                          ',toscn='||toSCN||
                          ' exceeds '||inc_list(inc_idx-1).resetlogs_change#);
           deb(DEB_PRINT, 'CheckRecAction:belongs to orphan branch ' ||
                          'of this incarnation:');
           return action_SKIP;
        END IF;
      END IF;
    END LOOP;
 
    deb(DEB_PRINT, 'CheckRecAction:not known to incarnation table');
 
--
    IF (nvl(afzSCN,0) = 0 AND toSCN = cleanSCN) THEN
       deb(DEB_PRINT, 'CheckRecAction: ok because backup ckpscn eq cleanscn');
       return SUCCESS;
    END IF;
  ELSE
     return SUCCESS;
  END IF;
 
--
--
--
  return action_SKIP;
END CheckRecAction;
 
--
FUNCTION isValidAction(action  IN rcvRec_t)
RETURN boolean IS
valid boolean := TRUE;
BEGIN
   IF (bitand(action.type_con, getRA_containerMask) = 0) THEN
      deb(DEB_PRINT, 'isValidAction: skipping non-selected container type');
      deb(DEB_PRINT, 'isValidAction: Container type : '|| action.type_con);
      deb(DEB_PRINT, 'isValidAction: Container Mask : '|| getRA_containerMask);
      valid := FALSE;                           -- then skip this action
   ELSIF (bitand(action.type_act, getRA_actionMask) = 0) THEN
      deb(DEB_PRINT, 'isValidAction: skipping non-selected action type');
      deb(DEB_PRINT, 'isValidAction: Action type : '|| action.type_act);
      deb(DEB_PRINT, 'isValidAction: Action Mask : '|| getRA_actionMask);
      valid := FALSE;                           -- then skip this action
   ELSIF (bitand(action.type_con, deleted_con_t) > 0) THEN
      deb(DEB_PRINT, 'isValidAction: deleted action skipped:');
      valid := FALSE;                             -- then skip this action
--
   ELSIF (computeRA_allRecords = TRUE# AND
          restoreTag is not null AND
          bitand(action.type_con, tagMask_con_t) > 0 AND
          (action.tag_con <> restoreTag OR action.tag_con is null)) THEN
      deb(DEB_PRINT, 'isValidAction: tag mismatch - skipped:');
      valid := FALSE;                             -- then skip this action
--
--
   ELSIF (getRA_completedAfter IS NOT NULL AND
          action.compTime_con < getRA_completedAfter) THEN
      deb(DEB_PRINT, 'isValidAction: compTime < completedAfter - skipped:');
      valid := FALSE;                             -- then skip this action
--
   ELSIF (getRA_completedBefore IS NOT NULL AND
          action.compTime_con > getRA_completedBefore) THEN
      deb(DEB_PRINT, 'isValidAction: compTime > completedBefore - skipped:');
      valid := FALSE;
--
   ELSIF (getRA_likePattern IS NOT NULL AND
          action.fileName_con NOT LIKE getRA_likePattern) THEN
      deb(DEB_PRINT, 'isValidAction: LikePattern not matched - skipped:');
      valid := FALSE;
   END IF;
 
   RETURN valid;
END isValidAction;
 
--
PROCEDURE resetrcvRecStack IS
BEGIN
   IF (rcvRecStack.count > 0) THEN
      rcvRecStack.trim(rcvRecStack.count);
   END IF;
 
   rcvRecStackState.lowAction   := 0;
   rcvRecStackState.savePoint   := 0;
   rcvRecStackState.fullBackups := 0;
   rcvRecStackState.top         := 0;
END resetrcvRecStack;
 
--
--
--
--
--
--
--
--
PROCEDURE fetchCursor1RecoveryAction(
   dbincKey      IN     number
  ,fno           IN     number
  ,creSCN        IN     number
  ,dfCkpSCN      IN     number
  ,dbincRlgSCN   IN     number
  ,dbincRlgTime  IN     date
  ,offlSCN       IN     number
  ,onlSCN        IN     number
  ,onlTime       IN     date
  ,cleanSCN      IN     number
  ,clean2SCN     IN     number
  ,clean2Time    IN     date
  ,targetSCN     IN     number
  ,opcode        IN     binary_integer  -- 1 => seeknext, 2 => seekcurrent
  ,foreignDbid   IN     number
  ,pluggedRonly  IN     binary_integer  -- 1 => readonly, 0 => readwrite
  ,pluginSCN     IN     number
  ,pluginRlgSCN  IN     number
  ,pluginRlgTime IN     date
  ,rmanCmd       IN     binary_integer)
IS
  action    rcvRec_t;
  actCreSCN number;
  inpCreSCN number;
BEGIN
   deb(DEB_ENTER, 'fetchCursor1RecoveryAction');
   deb(DEB_IN, 'opcode=' || to_char(opcode));
 
--
   IF (rcvRecCursor1_c%NOTFOUND) THEN
      rcvRecCursor.currc1.type_con := to_number(null);
      deb(DEB_EXIT, 'no more records');
      RETURN;
   END IF;
 
   IF (pluginSCN != 0) THEN
      inpCreSCN := pluginSCN;
   ELSE
      inpCreSCN := creSCN;
   END IF;
 
--
   IF (opcode = 1) THEN
      goto seekNext;
   ELSIF (opcode = 2) THEN
      goto seekCurrent;
   ELSE
      raise_application_error(-20999, 'fetchCursor1RecoveryAction - 1');
   END IF;
 
--
<<seekNext>>
   deb(DEB_IN, 'seekNext');
   LOOP
      rcvRecCursor.currc1.type_con := to_number(null);
      FETCH rcvRecCursor1_c INTO rcvRecCursor.currc1;
      IF (rcvRecCursor1_c%NOTFOUND) THEN
         rcvRecCursor.currc1.type_con := to_number(null);
         deb(DEB_IN, 'no more records');
         EXIT;
      END IF;
      
--
      IF (rcvRecCursor.currc1.pluggedRonly_obj = 1) THEN
         deb(DEB_IN, 'rcvRecCursor1_c plugged read only object');
         deb(DEB_IN, 'adjust toSCN ' || rcvRecCursor.currc1.toSCN_act ||
             ' to pluginSCN ' || rcvRecCursor.currc1.pluginSCN_obj);
         rcvRecCursor.currc1.toSCN_act := rcvRecCursor.currc1.pluginSCN_obj;
      END IF;
 
      IF (rcvRecCursor.currc1.pluginSCN_obj != 0) THEN
         actCreSCN := rcvRecCursor.currc1.pluginSCN_obj;
      ELSE
         actCreSCN := rcvRecCursor.currc1.dfCreationSCN_obj;
      END IF;
      deb(DEB_IN, 'rcvRecCursor1_c record');
      printRcvRec(rcvRecCursor.currc1);
      IF (rcvRecCursor.currc1.dfNumber_obj > fno           OR
          (rcvRecCursor.currc1.dfNumber_obj = fno AND
           actCreSCN > inpCreSCN)                          OR
          (rcvRecCursor.currc1.dfNumber_obj = fno AND
           actCreSCN = inpCreSCN)) THEN
--
--
         EXIT;
      END IF;
      IF (debug) THEN
         deb(DEB_IN, 'skipped following record: summary');
         printRcvRec(rcvRecCursor.currc1, TRUE);
      END IF;
   END LOOP;
 
<<seekCurrent>>
   IF (rcvRecCursor.currc1.pluginSCN_obj != 0) THEN
      actCreSCN := rcvRecCursor.currc1.pluginSCN_obj;
   ELSE
      actCreScN := rcvRecCursor.currc1.dfCreationSCN_obj;
   END IF;
 
   IF (rcvRecCursor.currc1.type_con is null         OR
       rcvRecCursor.currc1.dfNumber_obj > fno       OR
       (rcvRecCursor.currc1.dfNumber_obj = fno AND
        actCreSCN > inpCreSCN)) THEN
      deb(DEB_EXIT, 'seekCurrent - beyond current fno, creSCN');
      RETURN;
   END IF;
 
   IF (rcvRecCursor.currc1.dfNumber_obj != fno OR
       actCreSCN != inpCreSCN) THEN
      raise_application_error(-20999, 'fetchCursor1RecoveryAction ' ||
               'dfNumber_obj=' || to_char(rcvRecCursor.currc1.dfNumber_obj) ||
               ' dfCreationSCN_obj=' || to_char(actCreSCN));
   END IF;
 
--
--
   IF (rmanCmd = blkRestoreCmd_t) THEN
      IF (rcvRecCursor.currc1.toSCN_act > targetSCN) THEN
         deb(DEB_IN, 'a. simple filter rejected - trying next');
         goto seekNext;
      END IF;
   ELSE
      IF (rcvRecCursor.currc1.toSCN_act < dfCkpSCN AND
          rcvRecCursor.currc1.fromSCN_act < dfCkpSCN) THEN
         deb(DEB_IN, 'b. simple filter rejected - trying next');
         goto seekNext;
      END IF;
   END IF;
 
--
   OPEN rcvRecCursor1Filter_c( dbincKey        => dbincKey
                              ,fno             => fno
                              ,creSCN          => creSCN
                              ,dfCkpSCN        => dfCkpSCN
                              ,dbincRlgSCN     => dbincRlgSCN
                              ,dbincRlgTime    => dbincRlgTime
                              ,offlSCN         => offlSCN
                              ,onlSCN          => onlSCN
                              ,onlTime         => onlTime
                              ,cleanSCN        => cleanSCN
                              ,clean2SCN       => clean2SCN
                              ,clean2Time      => clean2Time
                              ,targetSCN       => targetSCN
                              ,c1rec           => rcvRecCursor.currc1
                              ,foreignDbid     => foreignDbid
                              ,pluggedRonly    => pluggedRonly
                              ,pluginSCN       => pluginSCN
                              ,pluginRlgSCN    => pluginRlgSCN
                              ,pluginRlgTime   => pluginRlgTime
                              ,rmanCmd         => rmanCmd);
    FETCH rcvRecCursor1Filter_c INTO action;
    IF (rcvRecCursor1Filter_c%NOTFOUND) THEN
--
       CLOSE rcvRecCursor1Filter_c;
       deb(DEB_IN, 'real filter rejected - trying next');
       goto seekNext;
    END IF;
    CLOSE rcvRecCursor1Filter_c;
    deb(DEB_EXIT, 'filter accepted');
END fetchCursor1RecoveryAction;
 
--
FUNCTION fetchRecoveryAction(
   dbincKey      IN     number
  ,fno           IN     number
  ,creSCN        IN     number
  ,dfCkpSCN      IN     number
  ,dbincRlgSCN   IN     number
  ,dbincRlgTime  IN     date
  ,offlSCN       IN     number
  ,onlSCN        IN     number
  ,onlTime       IN     date
  ,cleanSCN      IN     number
  ,clean2SCN     IN     number
  ,clean2Time    IN     date
  ,targetSCN     IN     number
  ,action        IN OUT NOCOPY rcvRec_t
  ,rmanCmd       IN     binary_integer
  ,foreignDbid   IN     number
  ,pluggedRonly  IN     binary_integer  -- 1 => readonly, 0 => readwrite
  ,pluginSCN     IN     number
  ,pluginRlgSCN  IN     number
  ,pluginRlgTime IN     date)
RETURN boolean IS
   top             rcvRec_t;
   c1frec          rcvRec_t;       -- filtered cursor1 record
   actCreSCN       number;
   inpCreSCN       number;
   actRlgSCN       number;
   topRlgSCN       number;
BEGIN
   deb(DEB_ENTER, 'fetchRecoveryAction');
 
   IF (pluginSCN != 0) THEN
      inpCreSCN := pluginSCN;
   ELSE
      inpCreSCN := creSCN;
   END IF;
 
   <<retry>>
   IF (rcvRecCursor.currc1.pluginSCN_obj != 0) THEN
      actCreSCN := rcvRecCursor.currc1.pluginSCN_obj;
   ELSE
      actCreSCN := rcvRecCursor.currc1.dfCreationSCN_obj;
   END IF;
 
   IF (rcvRecCursor.currc1.type_con is null          OR
       rcvRecCursor.currc1.dfNumber_obj != fno       OR
       actCreSCN != inpCreSCN) THEN
      c1frec.type_con := to_number(null);
   ELSE
      c1frec := rcvRecCursor.currc1;
   END IF;
 
   OPEN rcvRecCursor2_c( dbincKey        => dbincKey
                        ,fno             => fno
                        ,creSCN          => creSCN
                        ,dfCkpSCN        => dfCkpSCN
                        ,dbincRlgSCN     => dbincRlgSCN
                        ,dbincRlgTime    => dbincRlgTime
                        ,offlSCN         => offlSCN
                        ,onlSCN          => onlSCN
                        ,onlTime         => onlTime
                        ,cleanSCN        => cleanSCN
                        ,clean2SCN       => clean2SCN
                        ,clean2Time      => clean2Time
                        ,targetSCN       => targetSCN
                        ,c1frec          => c1frec
                        ,excludeAction   => rcvRecCursor.excludeAction
                        ,foreignDbid     => foreignDbid
                        ,pluggedRonly    => pluggedRonly
                        ,pluginSCN       => pluginSCN
                        ,pluginRlgSCN    => pluginRlgSCN
                        ,pluginRlgTime   => pluginRlgTime);
 
   FETCH rcvRecCursor2_c INTO action;
 
   IF (rcvRecCursor2_c%NOTFOUND) THEN
      action.type_con := NULL;
      action.type_act := NULL;
      CLOSE rcvRecCursor2_c;
      deb(DEB_EXIT, 'no_data_found with: FALSE');
      RETURN FALSE;
   END IF;
 
   IF (action.type_act = spanningRange_act_t  OR
       action.type_act = cleanRange_act_t     OR
       action.type_act = implicitRange_act_t)  THEN
--
      rcvRecCursor.excludeAction :=
                              rcvRecCursor.excludeAction + action.type_act;
   ELSE
--
      fetchCursor1RecoveryAction(
         dbincKey      => dbincKey
        ,fno           => fno
        ,creSCN        => creSCN
        ,dfCkpSCN      => dfCkpSCN
        ,dbincRlgSCN   => dbincRlgSCN
        ,dbincRlgTime  => dbincRlgTime
        ,offlSCN       => offlSCN
        ,onlSCN        => onlSCN
        ,onlTime       => onlTime
        ,cleanSCN      => cleanSCN
        ,clean2SCN     => clean2SCN
        ,clean2Time    => clean2Time
        ,targetSCN     => targetSCN
        ,opcode        => 1
        ,foreignDbid   => foreignDbid
        ,pluggedRonly  => pluggedRonly
        ,pluginSCN     => pluginSCN
        ,pluginRlgSCN  => pluginRlgSCN
        ,pluginRlgTime => pluginRlgTime
        ,rmanCmd       => rmanCmd);
   END IF;
 
   IF (action.compTime_con IS NULL AND          -- was null in 8.0.2
       action.type_con = backupSet_con_t) THEN
      action.compTime_con := stamp2date(action.bsStamp_con);
   END IF;
 
   IF (rmanCmd = obsoleteCmd_t AND action.type_act = incremental_act_t) THEN
      deb(DEB_PRINT, 'fetchRecoveryAction: incr backup set for obsolete cmd');
   ELSE
      IF (computeRA_allRecords = TRUE#) THEN
         CLOSE rcvRecCursor2_c;
         deb(DEB_EXIT, 'with TRUE');
         RETURN TRUE;
      END IF;
 
      IF (computeRA_fullBackups > 1) THEN
         CLOSE rcvRecCursor2_c;
         deb(DEB_EXIT, 'with TRUE');
         RETURN TRUE;
      END IF;
   END IF;
 
--
--
--
--
--
   IF (rcvRecStack.count > 0) THEN
      rcvRecTop(top);
      IF (action.pluginSCN_obj != 0) THEN
         actRlgSCN := action.pluginRlgSCN_obj;
      ELSE
         actRlgSCN := action.rlgSCN_act;
      END IF;
      IF (top.pluginSCN_obj != 0) THEN
         topRlgSCN := top.pluginRlgSCN_obj;
      ELSE
         topRlgSCN := top.rlgSCN_act;
      END IF;
      IF (not (action.fromSCN_act < top.fromSCN_act) AND
          actrlgSCN = toprlgSCN) THEN
         IF (debug) THEN
            deb(DEB_IN, 'discarding this action:');
            printRcvRec(action);
         END IF;
         CLOSE rcvRecCursor2_c;
         GOTO retry;
      END IF;
   END IF;
 
   CLOSE rcvRecCursor2_c;
   deb(DEB_EXIT, 'with TRUE');
   RETURN TRUE;
END fetchRecoveryAction;
 
--
PROCEDURE openRecoveryActionCursor(
   dbincKey      IN     number
  ,fno           IN     number
  ,creSCN        IN     number
  ,dfCkpSCN      IN     number
  ,dbincRlgSCN   IN     number
  ,dbincRlgTime  IN     date
  ,offlSCN       IN     number
  ,onlSCN        IN     number
  ,onlTime       IN     date
  ,cleanSCN      IN     number
  ,clean2SCN     IN     number
  ,clean2Time    IN     date
  ,targetSCN     IN     number
  ,rmanCmd       IN     binary_integer
  ,foreignDbid   IN     number
  ,pluggedRonly  IN     binary_integer
  ,pluginSCN     IN     number
  ,pluginRlgSCN  IN     number
  ,pluginRlgTime IN     date)
IS
  openCursor1   boolean := FALSE;     -- TRUE if cursor1 is to be opened
  opcode        binary_integer := 0;  -- seekNext or seekCurrent
  reqCreSCN     number;
  inpCreSCN     number;
  actCreSCN     number;
BEGIN
   deb(DEB_ENTER, 'openRecoveryActionCursor');
 
   IF (pluginSCN != 0) THEN
      inpCreSCN := pluginSCN;
   ELSE
      inpCreSCN := creSCN;
   END IF;
 
   deb(DEB_IN,'target scn is ' ||
       nvl(to_char(targetSCN), 'NULL') || ',creSCN=' || creSCN ||
       ',dfCkpSCN=' || dfCkpSCN || ',dbincRlgSCN=' || dbincRlgSCN ||
       ',offlSCN=' || offlSCN || ',onlSCN=' || onlSCN ||
       ',cleanSCN=' || cleanSCN || ',clean2SCN=' || clean2SCN ||
       ',fno=' || fno || ',pluginSCN=' || pluginSCN ||
       ',rmanCmd=' || rmanCmd);
 
   deb(DEB_IN, 'currc1.type_con=' ||
               nvl(to_char(rcvRecCursor.currc1.type_con),'NULL') ||
               ' currc1.fno=' ||
               nvl(to_char(rcvRecCursor.currc1.dfNumber_obj), 'NULL') ||
               ' currc1.crescn=' ||
               nvl(to_char(rcvRecCursor.currc1.dfCreationSCN_obj), 'NULL'));
 
   deb(DEB_IN, 'restoreSource=' || restoreSource ||
               ', restoreSparse='|| restoreSparse);
 
   IF (rcvRecCursor1_c%ISOPEN) THEN
      deb(DEB_IN, 'cursor1 already open');
      IF (tc_database = TRUE# OR isTranslatedFno(fno) = TRUE#) THEN
         deb(DEB_IN,'cursor1 translated');
         IF (rcvRecCursor.reqpluginSCN != 0) THEN
            reqCreSCN := rcvRecCursor.reqpluginSCN;
         ELSE
            reqCreSCN := rcvRecCursor.reqcrescn;
         END IF;
         IF (rcvRecCursor.currc1.pluginSCN_obj != 0) THEN
            actCreSCN := rcvRecCursor.currc1.pluginSCN_obj;
         ELSE
            actCreSCN := rcvRecCursor.currc1.dfCreationSCN_obj;
         END IF;
         IF ((rcvRecCursor.reqfno = fno AND reqCreSCN >= inpCreSCN) OR
             (rcvRecCursor.reqfno > fno)) THEN
--
--
            deb(DEB_IN, 'cursor1 unusable');
            openCursor1 := TRUE;
         ELSIF (rcvRecCursor.currc1.type_con is null    OR
                rcvRecCursor.currc1.dfNumber_obj < fno  OR
                (rcvRecCursor.currc1.dfNumber_obj = fno AND
                 actCreSCN < inpCreSCN)) THEN
               deb(DEB_IN,'reusing cursor1 after seek');
               opcode := 1; -- seekNext
         ELSIF (rcvRecCursor.currc1.dfNumber_obj = fno AND
                actCreSCN = inpCreSCN) THEN
            deb(DEB_IN,'reusing cursor1 with no seek');
            opcode := 2; -- seekCurrent
         ELSE
            deb(DEB_IN,'do nothing to cursor1');
         END IF;
      ELSE
         deb(DEB_IN,'cursor1 did not translate');
         openCursor1 := TRUE;
      END IF;
   ELSE
      deb(DEB_IN,'cursor1 not open yet');
      openCursor1 := TRUE;
   END IF;
 
   IF (openCursor1) THEN
      IF (rcvRecCursor1_c%ISOPEN) THEN
         CLOSE rcvRecCursor1_c;
      END IF;
 
      setDfTransClause(fno => fno);
      rcvRecCursor.currc1.type_con := to_number(null);
      deb(DEB_OPEN, 'rcvRecCursor1_c');
      OPEN rcvRecCursor1_c(rmanCmd => rmanCmd);
      opcode := 1;  -- seekNext
   END IF;
 
--
   IF (opcode != 0) THEN
      fetchCursor1RecoveryAction(
         dbincKey      => dbincKey
        ,fno           => fno
        ,creSCN        => creSCN
        ,dfCkpSCN      => dfCkpSCN
        ,dbincRlgSCN   => dbincRlgSCN
        ,dbincRlgTime  => dbincRlgTime
        ,offlSCN       => offlSCN
        ,onlSCN        => onlSCN
        ,onlTime       => onlTime
        ,cleanSCN      => cleanSCN
        ,clean2SCN     => clean2SCN
        ,clean2Time    => clean2Time
        ,targetSCN     => targetSCN
        ,opcode        => opcode
        ,foreignDbid   => foreignDbid
        ,pluggedRonly  => pluggedRonly
        ,pluginSCN     => pluginSCN
        ,pluginRlgSCN  => pluginRlgSCN
        ,pluginRlgTime => pluginRlgTime
        ,rmanCmd       => rmanCmd);
   END IF;
 
--
   rcvRecCursor.excludeAction := 0;
 
--
   rcvRecCursor.reqfno := fno;
   rcvRecCursor.reqcrescn := creSCN;
   rcvRecCursor.reqpluginSCN := pluginSCN;
 
--
   IF (rcvRecCursor1Filter_c%ISOPEN) THEN
      CLOSE rcvRecCursor1Filter_c;
   END IF;
 
   IF (rcvRecCursor2_c%ISOPEN) THEN
      CLOSE rcvRecCursor2_c;
   END IF;
 
   deb(DEB_EXIT);
END openRecoveryActionCursor;
 
--
 
FUNCTION trimRecoveryActions(
   maxActions           IN number
  ,containerMask        IN number
  ,actionMask           IN number)
RETURN NUMBER IS
   dummy     rcvRec_t;
   remaining number;
BEGIN
 
   deb(DEB_ENTER,'trimRecoveryActions[function](maxactions='||maxActions||')');
   IF (rcvRecStack.count > 0) THEN
      rcvRecPop(dummy);
      remaining := trimRecoveryActions(maxActions, containerMask, actionMask);
 
--
--
--
--
--
--
      IF ((bitand(dummy.type_con, containerMask) = 0) OR
           (bitand(dummy.type_act, actionMask) = 0)) THEN
--
--
         rcvRecPush(dummy);
         deb(DEB_EXIT, 'with: '||to_char(remaining));
         RETURN remaining;
      ELSE
         IF (remaining < maxActions) THEN
            rcvRecPush(dummy);          -- put back on stack
            deb(DEB_EXIT, 'with: '||to_char(remaining+1));
            RETURN remaining + 1;
         ELSE
--
            IF (debug) THEN
               deb(DEB_IN, 'deleting action:');
               printRcvRec(dummy);
               deb(DEB_EXIT, 'with: '||to_char(remaining));
            END IF;
 
            RETURN remaining;
         END IF;
      END IF;
   ELSE
      deb(DEB_EXIT, 'with: 0');
      RETURN 0;
   END IF;
END trimRecoveryActions;
 
--
PROCEDURE setCraGetAllCfBackups(
   flag IN boolean)
IS
BEGIN
   IF (flag) THEN
      deb(DEB_PRINT, 'craGetAllCfBackups is set to TRUE');
      craGetAllCfBackups := TRUE#;
   ELSE
      deb(DEB_PRINT, 'craGetAllCfBackups is set to FALSE');
      craGetAllCfBackups := FALSE#;
   END IF;
END setCraGetAllCfBackups;
 
--
--
FUNCTION isTranslatedArchivedLog(
   thread#   IN  number
  ,sequence# IN  number) RETURN BOOLEAN
IS
  thrbck   binary_integer;
  seqbck   binary_integer;
BEGIN
--
   IF (thread# >= CONST2GVAL) THEN
      thrbck := CONST2GVAL - thread#;
   ELSE
      thrbck := thread#;
   END IF;
 
--
   IF (sequence# >= CONST2GVAL) THEN
      seqbck := CONST2GVAL - sequence#;
   ELSE
      seqbck := sequence#;
   END IF;
 
   IF NOT tc_threadSeq.exists(thrbck) THEN
      RETURN FALSE;
   ELSIF NOT tc_threadSeq(thrbck).exists(seqbck) THEN
      RETURN FALSE;
   ELSE
      RETURN TRUE;
   END IF;
END isTranslatedArchivedLog;
 
--
FUNCTION getRangeArchivedLogBackup(
   rcvRec  OUT NOCOPY rcvRec_t)
RETURN binary_integer IS
   local        rcvRec_t;
   BSstatus     number;
BEGIN
   deb(DEB_ENTER, 'getRangeArchivedLogBackup');
 
   IF (getRecStackCount = 0) THEN
--
--
      deb(DEB_EXIT, 'with: UNAVAILABLE');
      RETURN UNAVAILABLE;
   END IF;
 
   rcvRecPop(local);
--
--
   IF (local.status_con = '*') THEN
      local.status_con := 'A';
      BSstatus := AVAILABLE;
   ELSE
      BSstatus := SUCCESS;
   END IF;
 
   IF (debug) THEN
      printRcvRec(local);
   END IF;
   rcvRec := local;
 
   IF (BSstatus = AVAILABLE) THEN
      deb(DEB_EXIT, 'with: AVAILABLE');
      RETURN AVAILABLE;
   ELSE
      deb(DEB_EXIT, 'with: SUCCESS');
      RETURN SUCCESS;
   END IF;
END getRangeArchivedLogBackup;
 
--
--
FUNCTION startWithPattern(
   toDest IN varchar2) RETURN VARCHAR2
IS
BEGIN
   IF (toDest IS NULL) THEN
      RETURN NULL;
   END IF;
 
   RETURN toDest || '%';
END startWithPattern;
 
 
--
--
PROCEDURE extendKeepSCN(lbDfRec    IN OUT NOCOPY lbDfRec_t,
                        toSCN      IN            number,
                        rlgSCN     IN            number,
                        extendMask IN            binary_integer,
                        force      IN            boolean,
                        dbgcomment IN            varchar2)
IS
BEGIN
   IF (bitand(extendMask, extendFullSCN) != 0) THEN
      IF (force OR toSCN < lbDfRec.fullmin_scn) THEN
         lbDfRec.fullmin_scn    := toSCN;
         lbDfRec.fullmin_rlgscn := rlgSCN;
         IF (debug) THEN
            deb(DEB_PRINT, dbgcomment || ': Extending fullmin_scn to '    ||
                to_char(toSCN));
            deb(DEB_PRINT, dbgcomment || ': Extending fullmin_rlgscn to ' ||
                nvl(to_char(rlgSCN), 'null'));
         END IF;
      END IF;
   END IF;
 
   IF (bitand(extendMask, extendIncrSCN) != 0) THEN
      IF (force OR toSCN < lbDfRec.incrmin_scn) THEN
         lbDfRec.incrmin_scn    := toSCN;
         lbDfRec.incrmin_rlgscn := rlgSCN;
         IF (debug) THEN
            deb(DEB_PRINT, dbgcomment || ': Extending incrmin_scn to '    || 
                to_char(toSCN));
            deb(DEB_PRINT, dbgcomment || ': Extending incrmin_rlgscn to ' || 
                nvl(to_char(rlgSCN), 'null'));
         END IF;
      END IF;
   END IF;
 
   IF (bitand(extendMask, extendLogSCN) != 0) THEN
      IF (force OR toSCN < lbDfRec.logmin_scn) THEN
         lbDfRec.logmin_scn    := toSCN;
         lbDfRec.logmin_rlgscn := rlgSCN;
         IF (debug) THEN
            deb(DEB_PRINT, dbgcomment || ': Extending logmin_scn to '    || 
                to_char(toSCN));
            deb(DEB_PRINT, dbgcomment || ': Extending logmin_rlgscn to ' || 
                nvl(to_char(rlgSCN), 'null'));
         END IF;
      END IF;
   END IF;
END extendKeepSCN;
 
--
PROCEDURE resetPdbNameList IS
BEGIN
   pdbNameList.delete;
   pdbGuidList.delete;
   pdbId2NameList.delete;
END resetPdbNameList;
 
--
PROCEDURE initPdbNameList IS
   local    pdbNameRec_t;
BEGIN
   IF (pdbNameList.count != 0) THEN
      RETURN;
   END IF;
 
   IF (translatePdbName_c%ISOPEN) THEN
      raise_application_error(-20203, 'Translation already started');
   END IF;
 
   resetPdbNameList;
   OPEN translatePdbName_c;
 
<<nextRow>>
   FETCH translatePdbName_c INTO local;
   IF translatePdbName_c%NOTFOUND THEN
      CLOSE translatePdbName_c;
   ELSE
      pdbNameList(local.name) := local;
      pdbGuidList(local.pdbGuid) := local;
      pdbId2NameList(local.pdbId) := local.name;
      goto nextRow;
   END IF;
 
   local.name := cdbRoot_txt;
   local.pdbId := 1;
   local.pdbGuid := 0;
   pdbNameList(local.name) := local;
   pdbGuidList(local.pdbGuid) := local;
   pdbId2NameList(local.pdbId) := local.name;
END initPdbNameList;
 
--
PROCEDURE resetPdbFileList IS
BEGIN
   pdbFileList.delete;
END resetPdbFileList;
 
--
PROCEDURE initPdbFileList IS
   local    pdbFileRec_t;
BEGIN
   IF (pdbFileList.count != 0) THEN
      RETURN;
   END IF;
 
   IF (translatePdbFile_c%ISOPEN) THEN
      raise_application_error(-20203, 'Translation already started');
   END IF;
 
   deb(DEB_PRINT, 'initPdbFileList');
   resetPdbFileList;
   OPEN translatePdbFile_c(
          fromSCN => nvl(untilSCN, MAXSCNVAL),
          toSCN   => nvl(untilSCN, MAXSCNVAL));
 
<<nextRow>>
   FETCH translatePdbFile_c INTO local;
   IF translatePdbFile_c%NOTFOUND THEN
      CLOSE translatePdbFile_c;
   ELSE
      pdbFileList(local.file#) := local;
      goto nextRow;
   END IF;
 
   local.file#    := 0;
   local.pdbId    := 0;
   local.stopSCN  := null;
   pdbFileList(0) := local;
END initPdbFileList;
 
--
FUNCTION translatePdbFile(
   file#    IN  NUMBER
  ,cleanSCN OUT NUMBER)
RETURN NUMBER IS
   local  pdbFileRec_t;
BEGIN
   initPdbFileList;
 
   IF (pdbFileList.exists(file#)) THEN
      local    := pdbFileList(file#);
      cleanSCN := local.stopSCN;
   ELSE
      deb(DEB_PRINT, 'translatePdbFile could not find file# ' || file#);
      IF (NOT pdbFileList.exists(1)) THEN
         raise_application_error(-20999, 'internal error: translatePdbFile');
      END IF;
      local    := pdbFileList(1);
      cleanSCN := NULL;
   END IF;
   RETURN local.pdbId;
END translatePdbFile;
 
--
 
--
PROCEDURE resetBsRecCache(
   reload  IN boolean)
IS
BEGIN
   BEGIN
      deb(DEB_PRINT, '*****BsRecCache Statistics*****');
      deb(DEB_PRINT, 'Cache size=' || to_char(cacheBsRecTable.bsRec.count) ||
                      ' hit=' || to_char(cacheBsRecTable.chit));
   EXCEPTION
      WHEN no_data_found THEN
         deb(DEB_PRINT, 'No statistics available');
   END;
 
   cacheBsRecTable.bsRec.delete;
   IF (NOT reload) THEN
      cacheBsRecTable.hitlist.delete;
      cacheBsRecTable.hitindex := 1;
      cacheBsRecTable.hint := noHint;
   END IF;
   cacheBSRecTable.chit := 0;
   cacheBsRecTable.mixcopy := FALSE;
   cacheBsRecTable.minbskey := 0;
END resetBsRecCache;
 
--
FUNCTION setCachedDeviceType(
   type IN varchar2)
RETURN binary_integer IS
BEGIN
   FOR i IN 1..cacheBsRecTable.devicecount LOOP
      IF cacheBsRecTable.devicelist(i) = type THEN
         RETURN i;
      END IF;
   END LOOP;
   cacheBsRecTable.devicecount := cacheBsRecTable.devicecount + 1;
   cacheBsRecTable.devicelist(cacheBsRecTable.devicecount) := type;
   RETURN cacheBsRecTable.devicecount;
END setCachedDeviceType;
 
 
--
PROCEDURE lkBsRecCache(
   bskey           IN    number
  ,icopy           IN    binary_integer
  ,bsrec           OUT   NOCOPY cacheBsRecRow_t)
IS
  bucket      number;
  sb4_bucket  binary_integer;
BEGIN
   bucket := mod(bskey, CONST4GVAL);
   IF (bucket >= CONST2GVAL) THEN
      sb4_bucket := CONST2GVAL - bucket;
   ELSE
      sb4_bucket := bucket;
   END IF;
 
   BEGIN
      FOR i in 1..cacheBsRecTable.bsRec(sb4_bucket).bslist.count LOOP
         IF (cacheBsRecTable.bsRec(sb4_bucket).bslist(i).bskey = bskey) THEN
            bsrec := cacheBsRecTable.bsRec(sb4_bucket).bslist(i).copy(icopy);
            RETURN;
         END IF;
      END LOOP;
   EXCEPTION
      WHEN no_data_found THEN
         NULL;
   END;
 
   RAISE no_data_found;
END lkBsRecCache;
 
--
FUNCTION addKeyToBsRecCache(
   bskey           IN number)
RETURN BOOLEAN IS
   bsk             cacheBsRecBsKey_t;
   bslist          cacheBsRecHash_t;
   bucket          number;
   sb4_bucket      binary_integer;
   bsindex         binary_integer;
BEGIN
   bucket := mod(bskey, CONST4GVAL);
   IF (bucket >= CONST2GVAL) THEN
      sb4_bucket := CONST2GVAL - bucket;
   ELSE
      sb4_bucket := bucket;
   END IF;
 
--
   IF (cacheBsRecTable.bsRec.exists(sb4_bucket)) THEN
      FOR i in 1..cacheBsRecTable.bsRec(sb4_bucket).bslist.count LOOP
         IF (cacheBsRecTable.bsRec(sb4_bucket).bslist(i).bskey = bskey) THEN
            RETURN FALSE;
         END IF;
      END LOOP;
      bsindex := cacheBsRecTable.bsRec(sb4_bucket).bsindex;
   ELSE
      cacheBsRecTable.bsRec(sb4_bucket) := bsk;
      bsindex := cacheBsRecTable.bsRec(sb4_bucket).bsindex;
      cacheBsRecTable.bsRec(sb4_bucket).bslist(bsindex) := bslist;
   END IF;
 
--
   cacheBsRecTable.bsRec(sb4_bucket).bslist(bsindex).bskey := bskey;
   cacheBsRecTable.bsRec(sb4_bucket).bsindex := bsindex + 1;
   RETURN TRUE;
END addKeyToBsRecCache;
 
--
PROCEDURE addToBsRecCache(
   bskey           IN number
  ,icopy           IN binary_integer
  ,deviceindx      IN binary_integer
  ,tag             IN varchar2
  ,copyNumber      IN binary_integer
  ,code            IN binary_integer)
IS
   bsindex         binary_integer := NULL;
   bsrec           cacheBsRecRow_t;
   bucket          number;
   sb4_bucket      binary_integer;
   addstatus       boolean;
BEGIN
   bucket := mod(bskey, CONST4GVAL);
   IF (bucket >= CONST2GVAL) THEN
      sb4_bucket := CONST2GVAL - bucket;
   ELSE
      sb4_bucket := bucket;
   END IF;
 
   bsrec.deviceindx := deviceindx;
   bsrec.tag := tag;
   bsrec.copyNumber := copyNumber;
   bsrec.code := code;
 
   IF (NOT cacheBsRecTable.bsRec.exists(sb4_bucket)) THEN
      addstatus := addKeyToBsRecCache(bskey);
   END IF;
 
   FOR i in 1..cacheBsRecTable.bsRec(sb4_bucket).bslist.count LOOP
      IF (cacheBsRecTable.bsRec(sb4_bucket).bslist(i).bskey = bskey) THEN
         bsindex := i;
         EXIT;
      END IF;
   END LOOP;
 
   IF (bsindex IS NULL) THEN
      addstatus := addKeyToBsRecCache(bskey);
      bsindex := 1;
   END IF;
 
   cacheBsRecTable.bsRec(sb4_bucket).bslist(bsindex).copy(icopy) := bsrec;
END addToBsRecCache;
 
--
FUNCTION hitBsRecCache(
   bskey       IN   number
  ,deviceType  IN   varchar2
  ,tag         IN   varchar2
  ,mask        IN   binary_integer)
RETURN BOOLEAN IS
  bucket      number;
  sb4_bucket  binary_integer;
BEGIN
--
   IF (deviceType != cacheBsRecTable.deviceType AND
       (deviceType IS NOT NULL OR
        cacheBsRecTable.deviceType IS NOT NULL)) THEN
      RETURN FALSE;
   END IF;
 
--
   IF (nvl(tag, '  ') != nvl(cacheBsRecTable.tag, nvl(tag, '  '))) THEN
      RETURN FALSE;
   END IF;
 
--
   IF (mask != cacheBsRecTable.mask) THEN
      RETURN FALSE;
   END IF;
 
   bucket := mod(bskey, CONST4GVAL);
   IF (bucket >= CONST2GVAL) THEN
      sb4_bucket := CONST2GVAL - bucket;
   ELSE
      sb4_bucket := bucket;
   END IF;
 
   IF (NOT cacheBsRecTable.bsRec.exists(sb4_bucket)) THEN
      IF (bskey < cacheBsRecTable.minbskey) THEN
--
--
--
--
         RETURN TRUE;
      ELSE
         RETURN FALSE;
      END IF;
   END IF;
 
   FOR i in 1..cacheBsRecTable.bsRec(sb4_bucket).bslist.count LOOP
      IF (cacheBsRecTable.bsRec(sb4_bucket).bslist(i).bskey = bskey) THEN
          cacheBsRecTable.chit := cacheBsRecTable.chit + 1;
--
         IF (cacheBsRecTable.hitindex > bsRecCacheLowLimit * 0.25) THEN
             cacheBsRecTable.hitindex := 1;
         END IF;
 
--
         cacheBsRecTable.hitlist(cacheBsRecTable.hitindex) := bskey;
         cacheBsRecTable.hitindex := cacheBsRecTable.hitindex + 1;
         RETURN TRUE;
      END IF;
   END LOOP;
 
   RETURN FALSE;
END hitBsRecCache;
 
--
FUNCTION canMixCopy(
   bskey IN   number)
RETURN BOOLEAN IS
  bucket      number;
  sb4_bucket  binary_integer;
BEGIN
   bucket := mod(bskey, CONST4GVAL);
   IF (bucket >= CONST2GVAL) THEN
      sb4_bucket := CONST2GVAL - bucket;
   ELSE
      sb4_bucket := bucket;
   END IF;
 
   IF (NOT cacheBsRecTable.bsRec.exists(sb4_bucket)) THEN
      raise_application_error(-20999, 'internal error: canMixCopy1');
   END IF;
 
   FOR i in 1..cacheBsRecTable.bsRec(sb4_bucket).bslist.count LOOP
      IF (cacheBsRecTable.bsRec(sb4_bucket).bslist(i).bskey = bskey) THEN
         RETURN cacheBsRecTable.bsRec(sb4_bucket).bslist(i).mixCopy;
      END IF;
   END LOOP;
 
   raise_application_error(-20999, 'internal error: canMixCopy2');
END canMixCopy;
 
--
PROCEDURE loadBsRecCache(
   from_bsRec  IN   rcvRec_t
  ,deviceType  IN   varchar2 DEFAULT NULL
  ,tag         IN   varchar2 DEFAULT NULL
  ,mask        IN   binary_integer
  ,mixcopy     IN   number)
IS
--
--
--
--
--
--
 
--
--
 
--
--
--
--
--
--
--
 
   CURSOR loadBsRecCache_c IS
      SELECT bs.bs_key                             bskey,
             bp.device_type                        deviceType,
             bp.tag                                tag,
             bp.copy#                              copyNumber,
             1                                     code,
             decode(bp.ba_access, 'R', 3, 'T', 2, nvl2(vb_key, 1, 0))
                                                   order1,
             bs.pieces                             pieces
        FROM bp, bs
      WHERE loadBsRecCache.mixcopy = FALSE#
        AND bs.db_key = this_db_key
        AND bp.db_key = this_db_key
        AND bp.status != 'D'
        AND bp.bs_key = bs.bs_key
        AND isBsRecCacheMatch(bs.bs_key, bp.device_type, bp.tag,
                              bp.status) = TRUE#  -- See NOTE
        AND ((user_site_key = bp.site_key) OR
             (user_site_key IS NULL AND
              ((disk_backups_shared = TRUE# AND bp.device_type = 'DISK') OR
               (tape_backups_shared = TRUE# AND bp.device_type <> 'DISK') OR
               (this_site_key = nvl(bp.site_key, this_site_key)))))
    GROUP BY bs.bs_key, bs.pieces, bp.device_type, bp.tag, bp.copy#,
             bp.ba_access, bp.vb_key
   HAVING ((bitand(mask, dbms_rcvman.BSpartial_avail) = 0 AND
            count(DISTINCT piece#) = bs.pieces) OR
           (bitand(mask, dbms_rcvman.BSpartial_avail) <> 0 AND
            count(DISTINCT piece#) <= bs.pieces))
 
    UNION ALL
 
--
--
--
 
      SELECT bs.bs_key                             bskey,
             bp.device_type                        deviceType,
             bp.tag                                tag,
             to_number(null)                       copyNumber,
             2                                     code,
             0                                     order1,
             bs.pieces                             pieces
       FROM bp, bs
      WHERE loadBsRecCache.mixcopy = TRUE#
        AND bs.db_key = this_db_key
        AND bp.db_key = this_db_key
        AND bp.status != 'D'
        AND bp.bs_key = bs.bs_key
        AND isBsRecCacheMatch(bs.bs_key, bp.device_type, bp.tag,
                              bp.status) = TRUE#  -- See NOTE
        AND ((user_site_key = bp.site_key) OR
             (user_site_key IS NULL AND
              ((disk_backups_shared = TRUE# AND bp.device_type = 'DISK') OR
               (tape_backups_shared = TRUE# AND bp.device_type <> 'DISK') OR
               (this_site_key = nvl(bp.site_key, this_site_key)))))
    GROUP BY bs.bs_key, bs.pieces, bp.device_type, bp.tag
   HAVING ((bitand(mask, dbms_rcvman.BSpartial_avail) = 0 AND
            count(DISTINCT piece#) = bs.pieces) OR
           (bitand(mask, dbms_rcvman.BSpartial_avail) <> 0 AND
            count(DISTINCT piece#) <= bs.pieces))
 
    UNION ALL
 
--
--
--
 
      SELECT bs.bs_key                             bskey,
             bp.device_type                        deviceType,
             to_char(null)                         tag,
             to_number(null)                       copyNumber,
             3                                     code,
             0                                     order1,
             bs.pieces                             pieces
       FROM bp, bs
      WHERE loadBsRecCache.mixcopy = TRUE#
        AND bs.db_key = this_db_key
        AND bp.db_key = this_db_key
        AND bp.status != 'D'
        AND bp.bs_key = bs.bs_key
        AND isBsRecCacheMatch(bs.bs_key, bp.device_type, bp.tag,
                              bp.status) = TRUE#  -- See NOTE
        AND ((user_site_key = bp.site_key) OR
             (user_site_key IS NULL AND
              ((disk_backups_shared = TRUE# AND bp.device_type = 'DISK') OR
               (tape_backups_shared = TRUE# AND bp.device_type <> 'DISK') OR
               (this_site_key = nvl(bp.site_key, this_site_key)))))
    GROUP BY bs.bs_key, bs.pieces, bp.device_type, bp.ba_access, bp.vb_key
   HAVING ((bitand(mask, dbms_rcvman.BSpartial_avail) = 0 AND
            count(DISTINCT piece#) = bs.pieces) OR
           (bitand(mask, dbms_rcvman.BSpartial_avail) <> 0 AND
            count(DISTINCT piece#) <= bs.pieces))
 
   ORDER BY 1,       -- bskey
            5,       -- code
            6;       -- order1
 
   CURSOR loadRedundDf_c IS
      SELECT bs_key
        FROM (SELECT bs_key, file#
                FROM bdf, dbinc
               WHERE dbinc.db_key = this_db_key
                 AND dbinc.dbinc_key = bdf.dbinc_key
                 AND file# >= nvl(from_bsRec.dfNumber_obj, 0)
              UNION ALL
              SELECT bs_key, 0 file#
                FROM bcf, dbinc
               WHERE dbinc.db_key = this_db_key
                 AND dbinc.dbinc_key = bcf.dbinc_key
                 AND nvl(from_bsRec.dfNumber_obj, 0) = 0
              UNION ALL
              SELECT bs_key, -1 file#
                FROM bsf
               WHERE from_bsRec.dfNumber_obj IS NULL
                 AND from_bsRec.fromSCN_act = 0
                 AND bsf.db_key = this_db_key)
       GROUP BY bs_key 
       ORDER BY min(file#),
                abs(bs_key - from_bsRec.bsKey_con);
 
   CURSOR loadRedundAl_c IS
      SELECT bs_key
        FROM (SELECT bs_key, thread#, sequence#
                FROM brl, dbinc
               WHERE dbinc.db_key = this_db_key
                 AND dbinc.dbinc_key = brl.dbinc_key
                 AND low_scn >= from_bsRec.logLowSCN_obj
                 AND ((thread# = from_bsRec.logThread_obj AND
                       sequence# >= from_bsRec.logSequence_obj) OR
                      (thread# > from_bsRec.logThread_obj)))
       GROUP BY bs_key 
       ORDER BY min(thread#),
                min(sequence#),
                abs(bs_key - from_bsRec.bsKey_con);
 
   CURSOR loadLocality_c(minbskey   IN number,
                         backupType IN varchar2) IS
      SELECT bs_key bskey
        FROM bs
       WHERE bs.db_key = this_db_key
         AND bs.bs_key >= loadLocality_c.minbskey
         AND (loadLocality_c.backupType IS NULL OR
              decode(bs.bck_type, 'L', 'L', 'D')=loadLocality_c.backupType)
      ORDER BY abs(bs_key - from_bsRec.bsKey_con);
 
   icopy            binary_integer := 0;
   bsrec            cacheBsRec_t;
   bsrow            cacheBsRecRow_t;
   prev_bskey       number := 0;
   low_bskey        number;
   deviceindx       binary_integer;
   addperset        binary_integer;     -- no: entries added to cache per set
   bslist           numTab_t;
   addstatus        boolean;
   freec            number;
   backupType       varchar2(1);
BEGIN
   deb(DEB_ENTER, 'loadBsRecCache');
   deb(DEB_IN, 'mixcopy=' || to_char(mixcopy));
 
--
   IF (NOT cacheBsRecTable.initlimit AND this_db_key IS NOT NULL) THEN
--
      SELECT count(*) INTO cacheBsRecTable.limit
        FROM bs, dbinc
       WHERE dbinc.db_key  = this_db_key    -- belongs to this database
         AND dbinc.db_key  = bs.db_key;     -- join bs and dbinc
 
      IF (cacheBsRecTable.limit > bsRecCacheHighLimit) THEN
         cacheBsRecTable.limit := bsRecCacheHighLimit;
      ELSIF (cacheBsRecTable.limit < bsRecCacheLowLimit) THEN
         cacheBsRecTable.limit := bsRecCacheLowLimit;
      END IF;
      cacheBsRecTable.initlimit := TRUE;
   END IF;
 
   IF (mixcopy = FALSE#) THEN
--
      resetBsRecCache(TRUE);
 
      cacheBsRecTable.bsRec := bsrec;
 
--
      cacheBsRecTable.tag := tag;
      cacheBsRecTable.deviceType := deviceType;
      cacheBsRecTable.mask := mask;
   ELSIF (cacheBsRecTable.mixcopy) THEN
      deb(DEB_EXIT, 'loadBsRecCache already loaded with mixcopy');
      RETURN;
   ELSE
      cacheBsRecTable.mixcopy := TRUE;
      FOR rec in loadBsRecCache_c LOOP
         deviceindx :=  setCachedDeviceType(rec.deviceType);
--
--
--
--
--
         <<mixCopyLoop>>
         FOR i in 1..255 LOOP
            BEGIN
               lkBsRecCache(bskey    => rec.bskey,
                            icopy    => i,
                            bsrec    => bsrow);
               EXIT mixCopyLoop WHEN (bsrow.deviceindx = deviceindx AND
                                      bsrow.code < rec.code);
            EXCEPTION
               WHEN no_data_found THEN
                  addToBsRecCache(bskey      => rec.bskey,
                                  icopy      => i,
                                  deviceindx => deviceindx,
                                  tag        => rec.tag,
                                  copyNumber => rec.copyNumber,
                                  code       => rec.code);
                  EXIT mixCopyLoop;
            END;
         END LOOP;
      END LOOP;
      deb(DEB_EXIT, 'loadBsRecCache loaded with mixcopy');
      RETURN;
   END IF;
 
--
   addstatus := addKeyToBsRecCache(bskey => from_bsRec.bsKey_con);
 
--
--
   IF (cacheBsRecTable.hint = redundantHint) THEN
      freec := cacheBsRecTable.limit;           -- only redundant
   ELSIF (cacheBsRecTable.hint = localityHint) THEN
      freec := 0;                               -- only locality
   ELSE
      freec := floor(cacheBsRecTable.limit/2);  -- redundant + locality
   END IF;
 
--
   IF (freec != 0) THEN
      IF (from_bsRec.dfNumber_obj IS NOT NULL OR
          from_bsRec.fromSCN_act = 0) THEN
         deb(DEB_IN, 'loadRedundDf_c');
         OPEN loadRedundDf_c;
         FETCH loadRedundDf_c BULK COLLECT
          INTO bslist LIMIT freec;
         CLOSE loadRedundDf_c;
      ELSIF (from_bsRec.logLowSCN_obj IS NOT NULL) THEN
         deb(DEB_IN, 'loadRedundAl_c');
         OPEN loadRedundAl_c;
         FETCH loadRedundAl_c BULK COLLECT
          INTO bslist LIMIT freec;
         CLOSE loadRedundAl_c; 
      END IF;
 
--
      FOR i in 1..bslist.count LOOP
         addstatus := addKeyToBsRecCache(bslist(i));
      END LOOP;
   END IF;
 
   freec := cacheBsRecTable.limit - bslist.count;
   bslist.delete;     -- free memory
 
--
   FOR i in 1..cacheBsRecTable.hitlist.count LOOP
      IF (addKeyToBsRecCache(cacheBsRecTable.hitlist(i))) THEN
         freec := freec - 1;
      END IF;
      EXIT WHEN (freec <= 0);
   END LOOP;
 
   IF (cacheBsRecTable.minbskey = 0) THEN
      BEGIN
         SELECT nvl(min(bp.bs_key), 0)
           INTO cacheBsRecTable.minbskey
           FROM bp
          WHERE bp.db_key = this_db_key
            AND bp.status != 'D'
            AND ((user_site_key = bp.site_key) OR
                 (user_site_key IS NULL AND
                  ((disk_backups_shared = TRUE# AND bp.device_type = 'DISK') OR
                   (tape_backups_shared = TRUE# AND bp.device_type <>'DISK') OR
                   (this_site_key = nvl(bp.site_key, this_site_key)))))
            AND ((mask = BSavailable AND bp.status = 'A') OR
                 isStatusMatch(bp.status, mask) = TRUE#);
      EXCEPTION
          WHEN no_data_found THEN
             cacheBsRecTable.minbskey := 0;
      END;
   END IF;
 
--
--
   IF (freec > 0) THEN
      backupType := to_char(null);
      IF (cacheBsRecTable.hint = redundantHint) THEN
--
         BEGIN
            SELECT decode(bck_type, 'L', 'L', 'D')
              INTO backupType
              FROM bs
             WHERE bs_key = from_bsRec.bsKey_con;
         EXCEPTION
            WHEN no_data_found THEN
               backupType := 'D';
         END;
      END IF;
 
--
      OPEN loadLocality_c(cacheBsRecTable.minbskey, backupType);
      LOOP
         FETCH loadLocality_c BULK COLLECT
          INTO bslist LIMIT freec;
         FOR i in 1..bslist.count LOOP
            IF (addKeyToBsRecCache(bslist(i))) THEN
               freec := freec - 1;
            END IF;
         END LOOP;
         bslist.delete;     -- free memory
         EXIT WHEN (loadLocality_c%NOTFOUND OR freec <= 0);
      END LOOP;
      CLOSE loadLocality_c;
   END IF;
 
--
   FOR rec in loadBsRecCache_c LOOP
      deviceindx :=  setCachedDeviceType(rec.deviceType);
--
      IF (prev_bskey = rec.bskey AND
          prev_bskey != 0) THEN
         icopy := icopy + 1;
      ELSE
         icopy := 1;           -- start with index 1 because this is new set
      END IF;
 
      addToBsRecCache(bskey      => rec.bskey,
                      icopy      => icopy,
                      deviceindx => deviceindx,
                      tag        => rec.tag,
                      copyNumber => rec.copyNumber,
                      code       => rec.code);
 
--
      prev_bskey := rec.bskey;
   END LOOP;
 
   deb(DEB_IN, 'tag=' || nvl(cacheBsRecTable.tag, 'NULL') ||
               ' deviceType=' || nvl(cacheBsRecTable.deviceType, 'NULL') ||
               ' mask=' || to_char(mask));
 
--
   deb(DEB_IN, 'Cache contains ' || to_char(cacheBsRecTable.bsRec.count) ||
               ' buckets');
--
--
--
--
--
 
   deb(DEB_IN, 'Minimum bskey=' || to_char(cacheBsRecTable.minbskey));
 
   deb(DEB_EXIT);
END loadBsRecCache;
 
--
PROCEDURE cacheFindValidBackupSet(
   bsRec                IN     rcvRec_t
  ,deviceType           IN     varchar2 DEFAULT NULL
  ,tag                  IN     varchar2 DEFAULT NULL
  ,availableMask        IN     binary_integer)
IS
BEGIN
   deb(DEB_PRINT,'cacheFindValidBackupSet:' ||
       ' bskey =' || to_char(bsRec.bsKey_con) ||
       ' tag=' || nvl(tag, 'NULL') ||
       ' deviceType=' || nvl(deviceType, 'NULL') ||
       ' mask=' || to_char(availableMask));
 
   IF (NOT hitBsRecCache(bskey      => bsRec.bsKey_con,
                         deviceType => deviceType,
                         tag        => tag,
                         mask       => availableMask)) THEN
      loadBsRecCache(from_bsRec     => bsRec,
                     deviceType     => deviceType,
                     tag            => tag,
                     mask           => availableMask,
                     mixcopy        => FALSE#);
      cacheBsRecTable.chit := cacheBsRecTable.chit + 1;
   END IF;
 
   findValidCacheRequest.bskey := bsRec.bsKey_con;
   findValidCacheRequest.icopy := 0;
END cacheFindValidBackupSet;
 
--
FUNCTION cacheGetValidBackupSet(
   validBackupSetRec            OUT NOCOPY validBackupSetRec_t
  ,checkDeviceIsAllocated       IN  number DEFAULT FALSE#)
RETURN number IS
   local        validBackupSetRec_t;
   bsrec        cacheBsRecRow_t;
   nullbsrec    rcvRec_t;
BEGIN
 
<<nextRow>>
 
   findValidCacheRequest.icopy := findValidCacheRequest.icopy + 1;
   BEGIN
      lkBsRecCache(
         bskey      => findValidCacheRequest.bskey,
         icopy      => findValidCacheRequest.icopy,
         bsrec      => bsrec);
   EXCEPTION
      WHEN no_data_found THEN
--
         IF (findValidCacheRequest.icopy != 1) THEN
            RAISE;
         END IF;
 
         IF (findValidCacheRequest.bskey< cacheBsRecTable.minbskey) THEN
            deb(DEB_PRINT, 'bskey < cacheBsRecTable.minbskey');
            RAISE;
         END IF;
 
         IF (NOT canMixCopy(bskey => findValidCacheRequest.bskey)) THEN
            RAISE;
         END IF;
 
--
         loadBsRecCache(from_bsRec     => nullbsrec,
                        deviceType     => cacheBsRecTable.deviceType,
                        tag            => cacheBsRecTable.tag,
                        mask           => cacheBsRecTable.mask,
                        mixcopy        => TRUE#);
         lkBsRecCache(
            bskey      => findValidCacheRequest.bskey,
            icopy      => findValidCacheRequest.icopy,
            bsrec      => bsrec);
   END;
 
--
   local.deviceType := cacheBsRecTable.devicelist(bsrec.deviceindx);
   local.tag := bsrec.tag;
   local.copyNumber := bsrec.copyNumber;
   local.code := bsrec.code;
 
   IF (checkDeviceIsAllocated = TRUE#) THEN
      IF (anyDevice = FALSE# AND
          isDeviceTypeAllocated(local.deviceType) = FALSE#) THEN
         GOTO nextRow;
      END IF;
   END IF;
   validBackupSetRec := local;                  -- set OUT mode arg
   deb(DEB_PRINT,'cacheGetValidBackupSet: returning valid rec deviceType=' ||
       local.deviceType || ' tag=' || local.tag || ' copyNumber=' ||
       to_char(local.copyNumber));
   RETURN TRUE#;
EXCEPTION
   WHEN no_data_found THEN
      RETURN FALSE#;
END cacheGetValidBackupSet;
 
--
--
--
 
--
PROCEDURE validateState(
   anyCursor IN varchar2)
IS
BEGIN
   deb(DEB_ENTER,'validateState');
   IF (this_db_key IS NULL) THEN
      raise_application_error(-20021, 'database not set');
   END IF;
   IF (this_dbinc_key IS NULL) THEN
      raise_application_error(-20020, 'Database incarnation not set');
   END IF;
   IF (translation_site_key IS NULL) THEN
      raise_application_error(-20082, 'Translation site key not set');
   END IF;
   IF (anyCursor IS NOT NULL) THEN
      raise_application_error(-20203, 'Translation already started');
   END IF;
 
--
--
   IF this_db_unique_name is NOT NULL AND this_site_key is NULL AND
      NOT this_dummy_instance THEN
      select site_key into this_site_key from node
         where db_unique_name=this_db_unique_name
           and db_key = this_db_key;
      deb(DEB_PRINT,'this_site_key=' || this_site_key);
   END IF;
   deb(DEB_EXIT,'validateState');
END;
 
--
--
--
 
--
--
--
--
--
--
--
--
--
--
--
--
--
 
--
PROCEDURE computeUntilSCN(
   timeStamp IN  date
  ,scn       OUT number
  ,allinc    IN  number)
IS
   mySCN     number;
BEGIN
   deb(DEB_ENTER, 'computeUntilSCN');
 
--
--
--
   SELECT nvl(max(rlh.low_scn),0)
     INTO mySCN
     FROM rlh,
          (SELECT dbinc_key,
                  reset_scn,
                  PRIOR reset_scn next_reset_scn
           FROM dbinc
          WHERE allinc = TRUE#
           START WITH dbinc_key = this_dbinc_key
           CONNECT BY PRIOR parent_dbinc_key = dbinc_key
           UNION ALL
           SELECT this_dbinc_key dbinc_key,
                  null           reset_scn,
                  null           next_reset_scn
             FROM dual) d2
    WHERE rlh.dbinc_key     = d2.dbinc_key
      AND (allinc = FALSE#           OR
           d2.next_reset_scn IS NULL OR
           (rlh.low_scn >= d2.reset_scn AND
            rlh.low_scn <  d2.next_reset_scn))
      AND rlh.low_time     <= timeStamp;
 
   SELECT greatest(nvl(max(al.low_scn), 0), mySCN)
     INTO mySCN
     FROM al,
          (SELECT dbinc_key,
                  reset_scn,
                  PRIOR reset_scn next_reset_scn
           FROM dbinc
          WHERE allinc = TRUE#
           START WITH dbinc_key = this_dbinc_key
           CONNECT BY PRIOR parent_dbinc_key = dbinc_key
           UNION ALL
           SELECT this_dbinc_key dbinc_key,
                  null           reset_scn,
                  null           next_reset_scn
             FROM dual) d2
    WHERE al.dbinc_key     = d2.dbinc_key
      AND (allinc = FALSE#           OR
           d2.next_reset_scn IS NULL OR
           (al.low_scn >= d2.reset_scn AND
            al.low_scn <  d2.next_reset_scn))
      AND al.low_time      <= timeStamp;
 
   SELECT greatest(nvl(max(bdf.ckp_scn),0), mySCN)
     INTO mySCN
     FROM bdf,
          (SELECT dbinc_key,
                  reset_scn,
                  PRIOR reset_scn next_reset_scn
           FROM dbinc
          WHERE allinc = TRUE#
           START WITH dbinc_key = this_dbinc_key
           CONNECT BY PRIOR parent_dbinc_key = dbinc_key
           UNION ALL
           SELECT this_dbinc_key dbinc_key,
                  null           reset_scn,
                  null           next_reset_scn
             FROM dual) d2
    WHERE bdf.dbinc_key      = d2.dbinc_key
      AND (allinc = FALSE#           OR
           d2.next_reset_scn IS NULL OR
           (bdf.ckp_scn >= d2.reset_scn AND
            bdf.ckp_scn <  d2.next_reset_scn))
      AND bdf.ckp_time <= timeStamp;
 
   SELECT greatest(nvl(max(bcf.ckp_scn),0), mySCN)
     INTO mySCN
     FROM bcf,
          (SELECT dbinc_key,
                  reset_scn,
                  PRIOR reset_scn next_reset_scn
           FROM dbinc
          WHERE allinc = TRUE#
           START WITH dbinc_key = this_dbinc_key
           CONNECT BY PRIOR parent_dbinc_key = dbinc_key
           UNION ALL
           SELECT this_dbinc_key dbinc_key,
                  null           reset_scn,
                  null           next_reset_scn
             FROM dual) d2
    WHERE bcf.dbinc_key      = d2.dbinc_key
      AND (allinc = FALSE#           OR
           d2.next_reset_scn IS NULL OR
           (bcf.ckp_scn >= d2.reset_scn AND
            bcf.ckp_scn <  d2.next_reset_scn))
      AND bcf.ckp_time      <= timeStamp;
 
   SELECT greatest(nvl(max(cdf.ckp_scn),0), mySCN)
     INTO mySCN
     FROM cdf,
          (SELECT dbinc_key,
                  reset_scn,
                  PRIOR reset_scn next_reset_scn
           FROM dbinc
          WHERE allinc = TRUE#
           START WITH dbinc_key = this_dbinc_key
           CONNECT BY PRIOR parent_dbinc_key = dbinc_key
           UNION ALL
           SELECT this_dbinc_key dbinc_key,
                  null           reset_scn,
                  null           next_reset_scn
             FROM dual) d2
    WHERE cdf.dbinc_key      = d2.dbinc_key
      AND (allinc = FALSE#           OR
           d2.next_reset_scn IS NULL OR
           (cdf.ckp_scn >= d2.reset_scn AND
            cdf.ckp_scn <  d2.next_reset_scn))
      AND cdf.ckp_time      <= timeStamp;
 
   SELECT greatest(nvl(max(cdf.rcv_fuzzy_scn),0), mySCN)
     INTO mySCN
     FROM cdf,
          (SELECT dbinc_key,
                  reset_scn,
                  PRIOR reset_scn next_reset_scn
           FROM dbinc
          WHERE allinc = TRUE#
           START WITH dbinc_key = this_dbinc_key
           CONNECT BY PRIOR parent_dbinc_key = dbinc_key
           UNION ALL
           SELECT this_dbinc_key dbinc_key,
                  null           reset_scn,
                  null           next_reset_scn
             FROM dual) d2
    WHERE cdf.dbinc_key      = d2.dbinc_key
      AND (allinc = FALSE#           OR
           d2.next_reset_scn IS NULL OR
           (cdf.rcv_fuzzy_scn >= d2.reset_scn AND
            cdf.rcv_fuzzy_scn <  d2.next_reset_scn))
      AND cdf.rcv_fuzzy_time <= timeStamp;
 
   SELECT greatest(nvl(max(ccf.ckp_scn),0), mySCN)
     INTO mySCN
     FROM ccf,
          (SELECT dbinc_key,
                  reset_scn,
                  PRIOR reset_scn next_reset_scn
           FROM dbinc
          WHERE allinc = TRUE#
           START WITH dbinc_key = this_dbinc_key
           CONNECT BY PRIOR parent_dbinc_key = dbinc_key
           UNION ALL
           SELECT this_dbinc_key dbinc_key,
                  null           reset_scn,
                  null           next_reset_scn
             FROM dual) d2
    WHERE ccf.dbinc_key      = d2.dbinc_key
      AND (allinc = FALSE#           OR
           d2.next_reset_scn IS NULL OR
           (ccf.ckp_scn >= d2.reset_scn AND
            ccf.ckp_scn <  d2.next_reset_scn))
      AND ccf.ckp_time <= timeStamp;
 
   SELECT greatest(nvl(max(xdf.ckp_scn),0), mySCN)
     INTO mySCN
     FROM xdf,
          (SELECT dbinc_key,
                  reset_scn,
                  PRIOR reset_scn next_reset_scn
           FROM dbinc
          WHERE allinc = TRUE#
           START WITH dbinc_key = this_dbinc_key
           CONNECT BY PRIOR parent_dbinc_key = dbinc_key
           UNION ALL
           SELECT this_dbinc_key dbinc_key,
                  null           reset_scn,
                  null           next_reset_scn
             FROM dual) d2
    WHERE xdf.dbinc_key      = d2.dbinc_key
      AND (allinc = FALSE#           OR
           d2.next_reset_scn IS NULL OR
           (xdf.ckp_scn >= d2.reset_scn AND
            xdf.ckp_scn <  d2.next_reset_scn))
      AND xdf.ckp_time <= timeStamp;
 
   SELECT greatest(nvl(max(xdf.rcv_fuzzy_scn),0), mySCN)
     INTO mySCN
     FROM xdf,
          (SELECT dbinc_key,
                  reset_scn,
                  PRIOR reset_scn next_reset_scn
           FROM dbinc
          WHERE allinc = TRUE#
           START WITH dbinc_key = this_dbinc_key
           CONNECT BY PRIOR parent_dbinc_key = dbinc_key
           UNION ALL
           SELECT this_dbinc_key dbinc_key,
                  null           reset_scn,
                  null           next_reset_scn
             FROM dual) d2
    WHERE xdf.dbinc_key      = d2.dbinc_key
      AND (allinc = FALSE#           OR
           d2.next_reset_scn IS NULL OR
           (xdf.rcv_fuzzy_scn >= d2.reset_scn AND
            xdf.rcv_fuzzy_scn <  d2.next_reset_scn))
      AND xdf.rcv_fuzzy_time<= timeStamp;
 
   SELECT greatest(nvl(max(df.create_scn), 0), mySCN)
     INTO mySCN
     FROM df,
          (SELECT dbinc_key,
                  reset_scn,
                  PRIOR reset_scn next_reset_scn
           FROM dbinc
          WHERE allinc = TRUE#
           START WITH dbinc_key = this_dbinc_key
           CONNECT BY PRIOR parent_dbinc_key = dbinc_key
           UNION ALL
           SELECT this_dbinc_key dbinc_key,
                  null           reset_scn,
                  null           next_reset_scn
             FROM dual) d2
    WHERE df.dbinc_key       = d2.dbinc_key
      AND (allinc = FALSE#           OR
           d2.next_reset_scn IS NULL OR
           (df.create_scn >= d2.reset_scn AND
            df.create_scn <  d2.next_reset_scn))
      AND df.create_time    <= timeStamp;
 
   SELECT greatest(nvl(max(df.stop_scn), 0), mySCN)
     INTO mySCN
     FROM df,
          (SELECT dbinc_key,
                  reset_scn,
                  PRIOR reset_scn next_reset_scn
           FROM dbinc
          WHERE allinc = TRUE#
           START WITH dbinc_key = this_dbinc_key
           CONNECT BY PRIOR parent_dbinc_key = dbinc_key
           UNION ALL
           SELECT this_dbinc_key dbinc_key,
                  null           reset_scn,
                  null           next_reset_scn
             FROM dual) d2
    WHERE df.dbinc_key       = d2.dbinc_key
      AND (allinc = FALSE#           OR
           d2.next_reset_scn IS NULL OR
           (df.stop_scn >= d2.reset_scn AND
            df.stop_scn <  d2.next_reset_scn))
      AND df.stop_time      <= timeStamp;
 
   SELECT greatest(nvl(max(offr.online_scn), 0), mySCN)
     INTO mySCN
     FROM offr,
          (SELECT dbinc_key,
                  reset_scn,
                  PRIOR reset_scn next_reset_scn
           FROM dbinc
          WHERE allinc = TRUE#
           START WITH dbinc_key = this_dbinc_key
           CONNECT BY PRIOR parent_dbinc_key = dbinc_key
           UNION ALL
           SELECT this_dbinc_key dbinc_key,
                  null           reset_scn,
                  null           next_reset_scn
             FROM dual) d2
    WHERE offr.dbinc_key     = d2.dbinc_key
      AND (allinc = FALSE#           OR
           d2.next_reset_scn IS NULL OR
           (offr.online_scn >= d2.reset_scn AND
            offr.online_scn <  d2.next_reset_scn))
      AND offr.online_time  <= timeStamp;
 
   scn := mySCN;
   deb(DEB_EXIT, 'with '||to_char(scn));
END computeUntilSCN;
 
--
PROCEDURE computeSpfileTime(
   inSCN     IN  number
  ,outTime   OUT date
  ,allinc    IN  number
  ,estimated OUT boolean)
IS
   startTime date;
BEGIN
   deb(DEB_ENTER, 'computeSpfileTime');
 
   outTime := NULL;
 
--
   IF rpoint_set THEN
      estimated := FALSE;
      SELECT MIN(rtime) INTO outTime
      FROM (SELECT NVL(rsptime, creation_time) rtime
            FROM nrsp
            WHERE to_scn = inSCN - 1
           UNION
            SELECT NVL(rsptime, creation_time) rtime
            FROM grsp
            WHERE to_scn = inSCN - 1);
   END IF;
 
--
   IF outTime IS NULL THEN
      estimated := TRUE;
      startTime := to_date('01/01/1900','DD/MM/YYYY');
 
--
      SELECT nvl(max(bs.start_time), startTime)
      INTO outTime
      FROM bcf,bs,
           (SELECT dbinc_key,
                   reset_scn,
                   PRIOR reset_scn next_reset_scn
            FROM dbinc
            WHERE allinc = TRUE#
            START WITH dbinc_key = this_dbinc_key
            CONNECT BY PRIOR parent_dbinc_key = dbinc_key
           UNION ALL
            SELECT this_dbinc_key dbinc_key,
                   null           reset_scn,
                   null           next_reset_scn
              FROM dual) d2
      WHERE bcf.dbinc_key = d2.dbinc_key
        AND bs.bs_key = bcf.bs_key
        AND (allinc = FALSE#           OR
             d2.next_reset_scn IS NULL OR
             (bcf.ckp_scn >= d2.reset_scn AND
              bcf.ckp_scn <  d2.next_reset_scn))
        AND bcf.ckp_scn <= inSCN;
 
--
 
--
      SELECT greatest(nvl(max(xcf.start_time), startTime), outTime)
      INTO outTime
      FROM xcf,
           (SELECT dbinc_key,
                   reset_scn,
                   PRIOR reset_scn next_reset_scn
            FROM dbinc
            WHERE allinc = TRUE#
            START WITH dbinc_key = this_dbinc_key
            CONNECT BY PRIOR parent_dbinc_key = dbinc_key
           UNION ALL
            SELECT this_dbinc_key dbinc_key,
                   null           reset_scn,
                   null           next_reset_scn
              FROM dual) d2
       WHERE xcf.dbinc_key      = d2.dbinc_key
         AND (allinc = FALSE#           OR
              d2.next_reset_scn IS NULL OR
              (xcf.ckp_scn >= d2.reset_scn AND
               xcf.ckp_scn <  d2.next_reset_scn))
         AND xcf.ckp_scn <= inSCN;
 
--
      IF startTime = outTime THEN
         outTime := NULL;
      END IF;
   END IF;
 
--
--
   outTime := outTime + 1/24/60/60; -- Add one second
 
   deb(DEB_EXIT, 'with ' || to_char(outTime, 'DD-MON-YY HH24:MI:SS'));
END computeSpfileTime;
 
--
--
--
 
--
 
--
PROCEDURE findBackupSet(
   bsKey        IN     number DEFAULT NULL
  ,recid        IN     number DEFAULT NULL
  ,stamp        IN     number DEFAULT NULL
  ,bsRec        OUT    NOCOPY bsRec_t)
IS
BEGIN
   deb(DEB_ENTER, 'findBackupSet');
   deb(DEB_IN, 'bsKey:'||nvl(bsKey, -1));
   IF (bsKey IS NOT NULL) THEN
      SELECT recid,
             stamp,
             bs_key,
             set_stamp,
             set_count,
             backup_type,
             incremental_level,
             elapsed_seconds,
             completion_time,
             status,
             pieces,
             decode (keep_options, 'LOGS'         , KEEP_LOGS
                                 , 'NOLOGS'       , KEEP_NOLOGS
                                 , 'BACKUP_LOGS'  , KEEP_CONSIST
                                                  , KEEP_NO),
             keep_until,
             substr(multi_section, 1, 1),
             0 ppl_pdb_id,
             0 ppl_cdb_dbid
        INTO bsRec
        FROM rc_backup_set
       WHERE db_key = this_db_key
         AND findBackupSet.bsKey = bs_key;
   ELSE
      SELECT recid,
             stamp,
             bs_key,
             set_stamp,
             set_count,
             backup_type,
             incremental_level,
             elapsed_seconds,
             completion_time,
             status,
             pieces,
             decode (keep_options, 'LOGS'         , KEEP_LOGS
                                 , 'NOLOGS'       , KEEP_NOLOGS
                                 , 'BACKUP_LOGS'  , KEEP_CONSIST
                                                  , KEEP_NO),
             keep_until,
             substr(multi_section, 1, 1),
             0 ppl_pdb_id,
             0 ppl_cdb_dbid
        INTO bsRec
        FROM rc_backup_set
       WHERE db_key = this_db_key
         AND findBackupSet.recid = recid
         AND findBackupSet.stamp = stamp;
   END IF;
   deb(DEB_EXIT);
EXCEPTION
   WHEN no_data_found THEN
      deb(DEB_EXIT, 'with error 20215');
      raise_application_error(-20215, 'Backup set is missing');
END findBackupSet;
 
--
--
--
 
--
--
--
 
--
PROCEDURE findValidBackupSet(
   bsKey                IN     number
  ,pieceCount           IN     number
  ,deviceType           IN     varchar2 DEFAULT NULL
  ,tag                  IN     varchar2 DEFAULT NULL
  ,availableMask        IN     binary_integer)
IS
   bsRec rcvRec_t;
BEGIN
   IF (bsRecCacheEnabled) THEN
      bsRec.bsKey_con := bsKey;
      bsRec.pieceCount_con := pieceCount;
      cacheFindValidBackupSet(bsRec         => bsRec,
                              deviceType    => deviceType,
                              tag           => tag,
                              availableMask => availableMask);
      RETURN;
   END IF;
 
   deb(DEB_ENTER, 'findValidBackupSet');
 
   IF (pieceCount = 1) THEN
      IF (findValidBackupSet1P_c%ISOPEN) THEN
         CLOSE findValidBackupSet1P_c;
      END IF;
--
--
--
--
      deb(DEB_OPEN, 'findValidBackupSet1P_c');
      OPEN findValidBackupSet1P_c(bsKey         => bsKey,
                                  pieceCount    => pieceCount,
                                  deviceType    => deviceType,
                                  tag           => tag,
                                  mask          => availableMask);
      getValidBackupSetCursor := 'findValidBackupSet1P_c';
   ELSE           -- more than one piece exists in this set
      IF (findValidBackupSet_c%ISOPEN) THEN
         CLOSE findValidBackupSet_c;
      END IF;
      deb(DEB_OPEN, 'findValidBackupSet_c');
      OPEN findValidBackupSet_c(bsKey         => bsKey,
                                pieceCount    => pieceCount,
                                deviceType    => deviceType,
                                tag           => tag,
                                mask          => availableMask);
      getValidBackupSetCursor := 'findValidBackupSet_c';
   END IF;
 
   deb(DEB_IN, 'bsKey=' || to_char(bsKey) || ' pieceCount=' ||
          to_char(pieceCount) ||' tag=' || nvl(tag, 'NULL'));
   deb(DEB_IN, ' deviceType=' || nvl(deviceType, 'NULL') ||
          ' mask=' || to_char(availableMask));
   getValidBackupSetLast.code       := 99;      -- init for getValidBackupSet
   deb(DEB_EXIT);
END findValidBackupSet;
 
--
FUNCTION validateBackupSet(
   backupSetRec            IN     rcvRec_t
  ,tag                     IN     varchar2 DEFAULT NULL
  ,tagMatchRequired        IN     boolean  DEFAULT TRUE
  ,checkDeviceIsAllocated  IN     boolean  DEFAULT TRUE
  ,availableMask           IN     binary_integer
  ,validRec                OUT    NOCOPY validBackupSetRec_t)
RETURN binary_integer IS
   findTag      bp.tag%TYPE;
BEGIN
   deb(DEB_ENTER, 'validateBackupSet');
   IF (tagMatchRequired) THEN
      findTag := tag;
   ELSE
--
--
--
      findTag := NULL;
   END IF;
 
   deb(DEB_IN, 'calling findValidBackupSet with:');
   deb(DEB_IN, ' tag=' || nvl(tag, 'NULL') ||
                    ' findTag=' || nvl(findTag, 'NULL') ||
                    ' tagMatchRequired=' || bool2char(tagMatchRequired) ||
                    ' checkDevice=' || bool2char(checkDeviceIsAllocated) ||
                    ' availableMask=' || to_char(availableMask));
 
  
   IF (bsRecCacheEnabled) THEN
      cacheFindValidBackupSet(bsRec         => backupSetRec,
                              tag           => findTag,
                              availableMask => availableMask);
   ELSE
      findValidBackupSet(bsKey         => backupSetRec.bsKey_con,
                         pieceCount    => backupSetRec.pieceCount_con,
                         tag           => findTag,
                         availableMask => availableMask);
   END IF;
 
   deb(DEB_EXIT, 'with result from validateBackupSet0');
   RETURN validateBackupSet0(
      tag                    => tag,
      tagMatchRequired       => tagMatchRequired,
      checkDeviceIsAllocated => checkDeviceIsAllocated,
      validRec               => validRec);
END validateBackupSet;
 
--
--
--
 
--
PROCEDURE findBackupPiece(
   bpKey        IN     number          DEFAULT NULL
  ,bsKey        IN     number          DEFAULT NULL
  ,tag          IN     varchar2        DEFAULT NULL
  ,handle       IN     varchar2        DEFAULT NULL
  ,deviceType   IN     varchar2        DEFAULT NULL
  ,copyNumber   IN     number          DEFAULT NULL
  ,statusMask   IN     binary_integer  DEFAULT BSavailable
  ,startBsKey   IN     number          DEFAULT NULL
  ,pdbKey       IN     number          DEFAULT NULL
  ,guid         IN     varchar2        DEFAULT NULL)
IS
BEGIN
   deb(DEB_ENTER, 'findBackupPiece');
   deb(DEB_IN, 'bpKey:'||nvl(bpKey, -1)||
          ' and bsKey:'||nvl(bsKey, -1));
   validateState(getBackupPieceCursor);
 
   IF (bpKey IS NOT NULL) THEN
      deb(DEB_OPEN, 'findBackupPieceBpKey');
      OPEN findBackupPieceBpKey(bpKey       => bpKey,
                                tag         => tag,
                                handle      => handle,
                                deviceType  => deviceType,
                                copyNumber  => copyNumber,
                                statusMask  => statusMask);
      getBackupPieceCursor := 'findBackupPieceBpKey';
   ELSIF (bsKey IS NOT NULL) THEN
      deb(DEB_OPEN, 'findBackupPieceBsKey1');
      OPEN findBackupPieceBsKey1(bsKey       => bsKey,
                                 tag         => tag,
                                 handle      => handle,
                                 deviceType  => deviceType,
                                 copyNumber  => copyNumber,
                                 statusMask  => statusMask);
      getBackupPieceCursor := 'findBackupPieceBsKey1';
   ELSIF (startBsKey IS NOT NULL) THEN
      OPEN findBackupPieceBsKey2(startBsKey  => startBsKey,
                                 tag         => tag,
                                 statusMask  => statusMask);
      getBackupPieceCursor := 'findBackupPieceBsKey2';
   ELSE
      deb(DEB_OPEN, 'findBackupPiece_c');
      OPEN findBackupPiece_c(   tag         => tag,
                                handle      => handle,
                                deviceType  => deviceType,
                                copyNumber  => copyNumber,
                                statusMask  => statusMask,
                                pdbKey      => pdbKey,
                                guid        => guid);
      getBackupPieceCursor := 'findBackupPiece_c';
   END IF;
 
--
--
 
   getBackupPieceNoRows.error     := NULL;
   getBackupPieceDuplicates       := TRUE#;
   getBackupPieceLast.pieceNumber := NULL;
   getBackupPieceDeviceType       := deviceType;
   getBackupPieceExpectedPieces   := NULL;
   getBackupPiecePieceCount       := 0;
   getBackupPieceByHandle         := FALSE;
   getBackupPieceAvailableMask    := NULL;
   getBackupPieceSeekLast.bskey   := NULL;
   getBackupPieceCopyNumber       := NULL;
   getBackupPieceBskey            := bsKey;
   deb(DEB_EXIT);
 
END findBackupPiece;
 
--
--
--
 
--
FUNCTION addAction(                             -- add to the rcvRecStack
   actionIN      IN     rcvRec_t                -- if a backup set, we fill
--
  ,partial_rcv   IN     boolean
  ,isAncestor    IN     boolean
  ,cf_scn        IN     number  DEFAULT NULL
  ,cf_cretime    IN     date    DEFAULT NULL
  ,cf_offrrid    IN     number  DEFAULT NULL
  ,allCopies     IN     boolean DEFAULT FALSE
  ,doingRecovery IN     boolean
  ,rmanCmd       IN     binary_integer
  ,pdbId         IN     number
  ,cleanSCN      IN     number)
RETURN number IS
   dummy                rcvRec_t;
   action               rcvRec_t;
   validate_rc          number;
   cf_count             number;
   addRedo_rc           number;
   chkact_rc            number;
   tagMatchRequired     boolean;
   validationRec        validBackupSetRec_t;
   lowAction            rcvRec_t;
   canrecover           boolean;
   toSCN                number;
BEGIN
   deb(DEB_ENTER, 'addAction');
   deb(DEB_IN, ' action.type_con='|| to_char(action.type_con));
 
   action := actionIN;                  -- copy to local variable
 
--
--
--
--
--
--
--
--
 
   IF (redoNeeded(action)) THEN
--
--
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
      rcvRecGet(rcvRecStackState.lowAction, lowAction);
      addRedo_rc := addRedo(isAncestor,
                            action.toSCN_act, action.rlgSCN_act,
                            lowAction,
                            partial_rcv, doingRecovery);
 
      IF (addRedo_rc = action_OLD_REDO) THEN
--
--
--
         deb(DEB_EXIT, 'with addRedo_rc: '||to_char(addRedo_rc));
         RETURN addRedo_rc;
      ELSE
--
--
--
--
--
         NULL;
      END IF;
   ELSE                                 -- redo not needed
--
--
--
--
      NULL;
   END IF;
 
--
--
   chkact_rc := CheckRecAction(action, pdbId, cleanSCN);
 
   IF (chkact_rc = action_SKIP) THEN
      deb(DEB_EXIT, 'with action_SKIP');
      RETURN action_SKIP;
   END IF;
 
 
--
--
--
--
 
   IF (action.type_con = backupSet_con_t) THEN
      IF (computeRA_allRecords = TRUE# OR restoreTag IS NULL) THEN
         tagMatchRequired := FALSE;
      ELSE
         tagMatchRequired := TRUE;
      END IF;
 
      IF (rmanCmd = rcvCopyCmd_t) THEN
--
--
         tagMatchRequired := FALSE;
      END IF;
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
 
      IF (rmanCmd != obsoleteCmd_t OR 
          (restoreTag IS NOT NULL AND this_baseline_cap >= 0)) THEN
         validate_rc :=
            validateBackupSet(backupSetRec           => action,
                              tag                    => restoreTag,
                              tagMatchRequired       => tagMatchRequired,
                              checkDeviceIsAllocated => TRUE,
                              availableMask          => computeRA_availableMask,
                              validRec               => validationRec);
      ELSE
--
--
         validate_rc := SUCCESS;
      END IF;
 
      IF (validate_rc = dbms_rcvman.UNAVAILABLE) THEN
         deb(DEB_EXIT, '(backup set is unavailable) with: action_FAIL');
         RETURN action_FAIL;
      ELSIF (validate_rc = dbms_rcvman.AVAILABLE) THEN
--
--
--
         deb(DEB_IN,'dont have required device type');
 
--
--
--
--
         IF (rmanCmd = rcvCopyCmd_t) THEN
            computeRA_rcvCopy_avail := TRUE;
         ELSE
            computeRA_available := TRUE;
         END IF;
         deb(DEB_EXIT, 'returning FAIL');
         RETURN action_FAIL;
      END IF;
--
--
--
   ELSIF (action.type_con = proxyCopy_con_t) THEN
--
      IF (anyDevice = FALSE# AND
          isDeviceTypeAllocated(action.deviceType_con) = FALSE#) THEN
--
--
--
         IF (rmanCmd = rcvCopyCmd_t) THEN
            computeRA_rcvCopy_avail := TRUE;
         ELSE
            computeRA_available := TRUE;
         END IF;
         deb(DEB_EXIT, '(dont have required device type for proxy)'||
             ' with: action_FAIL');
         RETURN action_FAIL;
      END IF;
   ELSIF (action.type_con = imageCopy_con_t) THEN
--
--
--
      IF (rmanCmd != rcvCopyCmd_t AND not diskDevice) THEN
--
--
         computeRA_available := TRUE;
         deb(DEB_EXIT, '(dont have required device type for imagecopy)'||
             ' with: action_FAIL');
         RETURN action_FAIL;
      END IF;
 
--
--
--
      IF (rmanCmd = rcvCopyCmd_t) THEN
         canrecover := FALSE;
         computeRA_available := computeRA_rcvCopy_avail;
         toSCN := action.toSCN_act;
         deb(DEB_IN,'rcvCopyCmd count= ' || rcvRecStack.count ||
             ' lowAction= ' || rcvRecStackState.lowAction ||
             ' toSCN= ' || toSCN);
         IF (rcvRecStack.count > 0) THEN
            FOR i IN REVERSE 1..rcvRecStackState.lowAction LOOP
               rcvRecGet(i, dummy);
--
               IF (dummy.type_act = incremental_act_t OR
                   dummy.type_con = offlineRangeRec_con_t) THEN
--
--
--
--
                  EXIT WHEN (toSCN < dummy.fromSCN_act);
 
--
                  IF (dummy.type_con = offlineRangeRec_con_t) THEN
                     toSCN := dummy.toSCN_act;
                     deb(DEB_IN,'extending toSCN= ' || toSCN);
                  ELSE -- this is incremental
                     IF (anyDevice = TRUE# OR
                         isDeviceTypeAllocated(dummy.deviceType_con)=TRUE#)
                     THEN
--
                        deb(DEB_IN,'canrecover is TRUE - 2');
                        canrecover := TRUE;
                        computeRA_available := NULL;
                        EXIT;
                     ELSE
--
--
--
                        deb(DEB_IN,'canrecover is FALSE');
                        canrecover := FALSE;
                        computeRA_available := TRUE;
                     END IF;
                  END IF;
               ELSIF (debug) THEN
                  deb(DEB_IN,'rcvCopyCmd skipping');
                  printRcvRec(dummy);
               END IF;
            END LOOP;
         END IF;
 
--
--
--
         IF not canrecover THEN
            resetrcvRecStack;
            deb(DEB_EXIT, 'no valid incrementals with: action_FAIL');
            RETURN action_FAIL;
         END IF;
      END IF;
   ELSIF (action.type_con = offlineRangeRec_con_t AND
          action.type_act = offlineRange_act_t) THEN
--
--
--
--
--
--
       IF (cf_cretime IS NULL AND rmanCmd = obsoleteCmd_t) THEN
--
--
         NULL;
       ELSIF (cf_cretime = action.cfCreationTime_con AND
              action.recid_con >= cf_offrrid AND
              cf_offrrid > 0 AND       -- contains at least 1 record
              cf_scn >= action.toSCN_act) THEN
         NULL;                         -- range is in current cf, we're cool
      ELSE
         SELECT count(*)
         INTO cf_count
         FROM ccf
         WHERE ccf.create_time = action.cfCreationTime_con AND
               ccf.min_offr_recid <= action.recid_con AND
               ccf.ckp_scn >= action.toSCN_act AND
               ((user_site_key = ccf.site_key) OR
                (user_site_key IS NULL AND
                 ((disk_backups_shared = TRUE#) OR
                  (this_site_key = nvl(ccf.site_key, this_site_key))))) AND
               ccf.min_offr_recid > 0;         -- contains at least 1 record
         IF (cf_count = 0) THEN
            deb(DEB_EXIT, '(no controlfile copy with offline range)'||
                          ' with: action_FAIL');
            RETURN action_FAIL;
         END IF;
      END IF;
   END IF;
 
--
--
   IF (addRedo_rc = action_OLD_INC_REDO) THEN
 
      rcvRecStackState.lowAction := 0;
 
      rcvRecStack.trim(rcvRecStack.last -
                       greatest(rcvRecStackState.savePoint,
                                rcvRecStackState.top));
      deb(DEB_IN,'trimming stack, rcvRecStackCount='|| rcvRecStack.count);
   END IF;
 
   <<addAnother>>
 
--
--
--
   IF (validate_rc      = SUCCESS         AND
       action.type_con  = backupSet_con_t AND
       (rmanCmd         != obsoleteCmd_t OR
        (restoreTag IS NOT NULL AND this_baseline_cap >= 0))) THEN
--
--
--
--
--
--
--
      IF (validationRec.tag = restoreTag OR
          restoreTag IS NULL) THEN
         action.tag_con := validationRec.tag;
      END IF;
      action.deviceType_con := validationRec.deviceType;
      action.copyNumber_con := validationRec.copyNumber;
   END IF;
 
   IF (debug) THEN
      printRcvRec(action);
   END IF;
 
   IF (action.type_act = full_act_t) THEN
 
      IF (thisBackupAge < rcvRecBackupAge) THEN
--
--
--
--
--
--
--
 
--
--
--
--
--
--
--
--
 
--
--
--
--
--
         deb(DEB_IN, 'skipping action because thisBackupAge (' ||
                      thisBackupAge || ') < rcvRecBackupAge('  ||
                      rcvRecBackupAge || ')');
         thisBackupAge := thisBackupAge + 1;
         deb(DEB_EXIT, 'with: action_SKIP');
         RETURN action_SKIP;
      END IF;
 
--
      IF (rcvRecStackState.fullBackups >= computeRA_fullBackups) THEN
--
--
         IF (rmanCmd = obsoleteCmd_t AND action.keep_options = 0) THEN
            deb(DEB_IN, 'skipping action because this action has NO KEEP');
            deb(DEB_EXIT, 'with action_SKIP');
            RETURN action_SKIP;
         ELSIF (rmanCmd != obsoleteCmd_t) THEN
            deb(DEB_IN, 'skipping action because stack has enough fullBackups');
            deb(DEB_EXIT, 'with action_SKIP');
            RETURN action_SKIP;
         END IF;
      END IF;
   END IF;
 
--
   IF (rmanCmd = obsoleteCmd_t and NOT isValidAction(action)) THEN
      deb(DEB_EXIT, 'with action_SKIP');
      RETURN action_SKIP;
   END IF;
 
   rcvRecPush(action);               -- add record for this action
 
   deb(DEB_IN, ' Added action:');
 
   IF (allCopies AND action.type_con = backupSet_con_t) THEN
--
      deb(DEB_IN,'allCopies is TRUE, trying to add other copies');
      validate_rc :=
         validateBackupSet0(tag                    => restoreTag,
                            tagMatchRequired       => tagMatchRequired,
                            checkDeviceIsAllocated => TRUE,
                            validRec               => validationRec);
      IF (validate_rc <> SUCCESS) THEN
         GOTO done;
      END IF;
      GOTO addAnother;
   END IF;
 
   <<done>>
 
--
 
   IF (action.type_act = full_act_t) THEN
--
      deb(DEB_IN, ' action.type_act is range/full => setting savePoint='||
           to_char(rcvRecStack.last));
      rcvRecStackState.savePoint   := rcvRecStack.last;
 
--
--
      IF (rmanCmd != obsoleteCmd_t OR action.keep_options = KEEP_NO) THEN
         rcvRecStackState.fullBackups := rcvRecStackState.fullBackups + 1;
      END IF;
   ELSIF (rcvRecStackState.lowAction = 0) THEN
--
      rcvRecStackState.lowAction := rcvRecStack.last;
   ELSIF (action.fromSCN_act <
          rcvRecStack(rcvRecStackState.lowAction).fromSCN_act) THEN
      rcvRecStackState.lowAction := rcvRecStack.last;   -- new lowAction
   END IF;
 
   deb(DEB_EXIT, 'with: action_OK');
   RETURN action_OK;
 
END addAction;
 
--
--
--
FUNCTION computeRecoveryActions2(
   fno         IN number        -- Datafile number.
  ,crescn      IN number        -- Datafile creation SCN.
  ,cretime     IN date          -- Datafile creation time.
  ,df_rlgscn   IN number        -- Datafile resetlogs SCN.
--
--
--
  ,df_rlgtime  IN date          -- Datafile resetlogs time.
--
--
  ,df_ckpscn   IN number        -- Datafile checkpoint SCN.
--
--
  ,offlscn     IN number        -- kccfeofs (may be 0).
  ,onlscn      IN number        -- kccfeonc (0 if offlscn is 0).
  ,onltime     IN date          -- kccfeonc_time (ignored if kccfeofs is 0)
  ,cleanscn    IN number        -- kccfecps if either SOR or WCC set, else 0.
  ,clean2scn   IN number        -- CF ckpt SCN if WCC set.
--
  ,clean2time  IN date          -- cf_checkpoint_time if WCC,
--
  ,allowfuzzy  IN boolean       -- TRUE if can be fuzzy at until SCN/time,
--
  ,partial_rcv IN boolean
  ,target_scn  IN number        -- This is the SCN to which we want to recover
--
--
--
--
--
--
--
--
--
--
  ,dbinc_key   IN number        -- The key of the database incarnation to
--
--
--
  ,cf_scn      IN number
  ,cf_cretime  IN date          -- controlfile creation time.
--
  ,cf_offrrid  IN number        -- recid of oldest offline range in controlfile
--
  ,test_search IN boolean       -- if TRUE, then we have called ourself
--
--
  ,done        IN OUT boolean   -- set to TRUE if successful.  (IN mode so
--
  ,allCopies   IN boolean       -- if true, then stack all copies of
--
  ,recover     IN boolean
  ,rmanCmd     IN binary_integer
  ,foreignDbid   IN     number
  ,pluggedRonly  IN     binary_integer  -- 1 => readonly, 0 => readwrite
  ,pluginSCN     IN     number
  ,pluginRlgSCN  IN     number
  ,pluginRlgTime IN     date
  ,creation_thread IN   number
  ,creation_size   IN   number
  ,pdbId           IN   number
  ,pdbForeignDbid  IN   number)
--
--
--
--
--
--
--
 
RETURN boolean IS
 
--
--
--
 
   null_action          rcvRec_t;
   action               rcvRec_t;       -- current row
   lastAction           rcvRec_t;
   parentDbincKey       number;         -- my parent dbinc's key
 
   dbinc_rlgscn         number;         -- resetlogs scn for dbinc_key
 
   dbinc_rlgtime        date;           -- resetlogs time for dbinc_key
 
   CURSOR dbinc_cursor(db_key number, rstscn number) IS
   SELECT dbinc_key
     FROM dbinc
    WHERE dbinc.db_key = dbinc_cursor.db_key
      AND dbinc.reset_scn < dbinc_cursor.rstscn;
 
   dbinc_row            dbinc_cursor%ROWTYPE;
 
   savedrcvRecStackState rcvRecStackState_t;
 
   addAction_rc         number;         -- return code
 
   addRedo_rc           number;         -- return code
 
   isAncestor           boolean;        -- TRUE if we find an action we could
--
 
   rc                   boolean;        -- return code from recursive search
--
 
   done_flag            boolean;        -- for use in recursive calls
 
   doingRecovery        boolean;        -- doing RECOVER
   stack_df_rlgscn      number;
   savedBackupAge       number;
 
BEGIN
   deb(DEB_ENTER, 'computeRecoveryActions2');
 
   done := FALSE;
 
   doingRecovery := recover;
 
   IF (doingRecovery is null) THEN
--
--
     IF (df_rlgscn is not null) THEN                      -- doing RECOVER
        doingRecovery := TRUE;
     ELSE
        doingRecovery := FALSE;
     END IF;
   END IF;
 
   IF (doingRecovery) THEN                                 -- doing RECOVER
      deb(DEB_IN, ' Doing recovery.');
   ELSE
      deb(DEB_IN, ' Not doing recovery.');
   END IF;
 
--
   SELECT reset_scn, reset_time
     INTO dbinc_rlgscn, dbinc_rlgtime
     FROM dbinc
    WHERE dbinc.dbinc_key = computeRecoveryActions2.dbinc_key;
 
   IF (doingRecovery AND canApplyAnyRedo = FALSE# ) THEN
--
--
--
--
 
      IF (dbinc_rlgscn < df_rlgscn) THEN
         deb(DEB_IN, 'dbinc_rlgscn < df_rlgscn (' || to_char(dbinc_rlgscn) ||
             ' < ' || to_char(df_rlgscn) || ')');
         deb(DEB_EXIT,'computeRecoveryActions2 - 1 with FALSE');
         RETURN FALSE;
      ELSIF (dbinc_rlgscn = df_rlgscn AND dbinc_rlgtime <> df_rlgtime) THEN
         deb(DEB_IN, 'dbinc_rlgtime <> df_rlgtime');
         deb(DEB_EXIT,'computeRecoveryActions2 - 2 with FALSE');
         RETURN FALSE;
      END IF;
   END IF;
 
   IF (not test_search) THEN
--
--
      deb(DEB_IN, ' This is ancestor.');
      isAncestor := TRUE;
   ELSE
      isAncestor := FALSE;
   END IF;
 
   openRecoveryActionCursor( dbincKey     => dbinc_key
                            ,fno          => fno
                            ,creSCN       => crescn
                            ,dfCkpSCN     => df_ckpscn
                            ,dbincRlgSCN  => dbinc_rlgscn
                            ,dbincRlgTime => dbinc_rlgtime
                            ,offlSCN      => offlscn
                            ,onlSCN       => onlscn
                            ,onlTime      => onltime
                            ,cleanSCN     => cleanscn
                            ,clean2SCN    => clean2scn
                            ,clean2Time   => clean2time
                            ,targetSCN    => target_scn
                            ,rmanCmd      => rmanCmd
                            ,foreignDbid  => foreignDbid
                            ,pluggedRonly => pluggedRonly
                            ,pluginSCN    => pluginSCN
                            ,pluginRlgSCN => pluginRlgSCN
                            ,pluginRlgTime=> pluginRlgTime);
 
--
--
--
 
<<action_loop>>
   LOOP
      <<next_row>>
     IF (fetchRecoveryAction(  dbincKey     => dbinc_key
                              ,fno          => fno
                              ,creSCN       => crescn
                              ,dfCkpSCN     => df_ckpscn
                              ,dbincRlgSCN  => dbinc_rlgscn
                              ,dbincRlgTime => dbinc_rlgtime
                              ,offlSCN      => offlscn
                              ,onlSCN       => onlscn
                              ,onlTime      => onltime
                              ,cleanSCN     => cleanscn
                              ,clean2SCN    => clean2scn
                              ,clean2Time   => clean2time
                              ,targetSCN    => target_scn
                              ,action       => action
                              ,rmanCmd      => rmanCmd
                              ,foreignDbid  => foreignDbid
                              ,pluggedRonly => pluggedRonly
                              ,pluginSCN    => pluginSCN
                              ,pluginRlgSCN => pluginRlgSCN
                              ,pluginRlgTime=> pluginRlgTime)) THEN
         deb(DEB_PRINT, 'fetched recovery action');
         printRcvRec(action);
 
--
--
--
 
         IF (bitand(action.type_con, backupMask_con_t) > 0 AND
             action.toSCN_act = target_scn) THEN
            deb(DEB_IN, ' This is ancestor.');
            isAncestor := TRUE;
         END IF;
 
         IF (action.type_con = offlineRangeRec_con_t) THEN
--
--
--
            deb(DEB_IN, ' found an offline range' ||
                ' from=' || to_char(action.fromSCN_act) ||
                ' to=' || to_char(action.toSCN_act));
 
            IF (action.type_act = spanningRange_act_t) THEN
--
--
--
               deb(DEB_IN, ' offline range started before this resetlogs SCN');
 
--
--
--
               addAction_rc := action_OK;
            ELSE
               addAction_rc := addAction(actionIN      => action,
                                         partial_rcv   => partial_rcv,
                                         isAncestor    => isAncestor,
                                         cf_scn        => cf_scn,
                                         cf_cretime    => cf_cretime,
                                         cf_offrrid    => cf_offrrid,
                                         doingRecovery => doingRecovery,
                                         rmanCmd       => rmanCmd,
                                         pdbId         => pdbId,
                                         cleanSCN      => cleanSCN);
            END IF;
         ELSIF (action.type_con = backupSet_con_t AND
                action.type_act = incremental_act_t) THEN
--
--
--
            deb(DEB_IN, 'found an incremental backup set');
 
            addAction_rc := addAction(actionIN      => action,
                                      partial_rcv   => partial_rcv,
                                      isAncestor    => isAncestor,
                                      allCopies     => allCopies,
                                      doingRecovery => doingRecovery,
                                      rmanCmd       => rmanCmd,
                                      pdbId         => pdbId,
                                      cleanSCN      => cleanSCN);
         ELSIF (action.type_act = full_act_t) THEN
--
--
--
            deb(DEB_IN, 'found a copy/full/level0/proxy copy');
 
            IF (doingRecovery) THEN                  -- if doing a RECOVER
--
--
--
--
--
--
               IF (rmanCmd = rcvCopyCmd_t) THEN
                  addAction_rc := addAction(actionIN      => action,
                                            partial_rcv   => partial_rcv,
                                            isAncestor    => isAncestor,
                                            allCopies     => allCopies,
                                            doingRecovery => doingRecovery,
                                            rmanCmd       => rmanCmd,
                                            pdbId         => pdbId,
                                            cleanSCN      => cleanSCN);
               ELSE
                  IF (isAncestor) THEN
                     rcvRecTop(lastAction);
                     IF (not redoNeeded(action) OR
                         canAddRedo(isAncestor,
                                    action.toSCN_act, action.rlgSCN_act,
                                    lastAction, partial_rcv, doingRecovery) <>
                         action_OLD_REDO) THEN
                        computeRA_restorable := TRUE;
                     END IF;
                  END IF;
                  addAction_rc := action_SKIP;
               END IF;
            ELSE                                -- not doing a RECOVER
               addAction_rc := addAction(actionIN      => action,
                                         partial_rcv   => partial_rcv,
                                         isAncestor    => isAncestor,
                                         allCopies     => allCopies,
                                         doingRecovery => doingRecovery,
                                         rmanCmd       => rmanCmd,
                                         pdbId         => pdbId,
                                         cleanSCN      => cleanSCN);
            END IF;
         ELSE
--
--
--
            deb(DEB_IN, 'unknown container type: ' ||
                 to_char(action.type_con) ||
                ' or action type: ' || to_char(action.type_act));
 
--
--
            deb(DEB_EXIT, 'with error 20999');
            raise_application_error(-20999, 'unknown action kind');
         END IF;                                -- "switch" on ACTION.KIND
 
--
--
--
 
         deb(DEB_IN, 'addAction returned code ' || to_char(addAction_rc));
 
         IF (addAction_rc = action_OK) THEN     -- the action was added
 
--
--
--
 
            IF (action.type_act = full_act_t AND
                this_baseline_cap >= 0 AND
                (action.toSCN_act < this_baseline_cap_scn OR
                 this_baseline_cap_scn IS NULL)) THEN
               deb(DEB_IN, 'Found a backup older than baseline_cap');
               done := TRUE;
               deb(DEB_PRINT,'done set to true - 0');
               EXIT action_loop;
            END IF;
 
            IF (rcvRecStackState.savePoint > 0 AND
                computeRA_allRecords = FALSE#  AND
                rcvRecStackState.fullBackups >= computeRA_fullBackups) THEN
--
--
--
--
--
               deb(DEB_IN, 'savePoint > 0' ||
                   ' and computeRA_allRecords = FALSE#');
               done := TRUE;
               deb(DEB_PRINT,'done set to true - 1');
               EXIT action_loop;
            END IF;
 
            IF (doingRecovery) THEN                   -- if doing RECOVER
               IF (action.type_con = offlineRangeRec_con_t) THEN
--
--
                  IF (df_ckpscn = action.fromSCN_act) THEN
                     done := TRUE;
                     deb(DEB_PRINT,'done set to true - 2');
                     EXIT action_loop;
                  END IF;
               ELSE
--
--
                  IF (df_ckpscn >= action.fromSCN_act) THEN
                     done := TRUE;
                     deb(DEB_PRINT,'done set to true - 3');
                     EXIT action_loop;
                  END IF;
               END IF;
            END IF;
 
--
--
--
 
--
--
--
--
 
            IF (action.type_con = offlineRangeRec_con_t AND
                action.fromSCN_act < dbinc_rlgscn AND
                canApplyAnyRedo = FALSE#) THEN
 
               deb(DEB_IN, 'offline range spanning a resetlogs');
 
--
--
--
--
--
--
 
--
 
               SELECT parent_dbinc_key
                 INTO parentDbincKey
                 FROM dbinc
                WHERE dbinc.dbinc_key = computeRecoveryActions2.dbinc_key;
 
               IF (parentDbincKey is null) THEN -- we don't know our parent
 
--
--
--
--
--
--
                  deb(DEB_OPEN, 'dbinc_cursor');
                  OPEN dbinc_cursor(this_db_key, dbinc_rlgscn);
 
                  deb(DEB_IN,
                      'doing scan of all possible parent incarnations, top=' ||
                      to_char(rcvRecStack.last));
 
                  <<dbinc_loop>>
                  LOOP
                     FETCH dbinc_cursor
                      INTO dbinc_row;
                     EXIT WHEN dbinc_cursor%NOTFOUND;
                     deb(DEB_IN,
                         'starting test search of incarnation key=' ||
                         to_char(dbinc_row.dbinc_key));
 
                     savedrcvRecStackState := rcvRecStackState;
                     rcvRecStackState.top := rcvRecStack.last;
 
                     savedBackupAge        := thisBackupAge;
 
--
--
--
 
                     thisBackupAge         := rcvRecBackupAge;
 
                     rc := computeRecoveryActions2(fno, crescn, cretime,
                                                  df_rlgscn, df_rlgtime,
                                                  df_ckpscn,
                                                  offlscn,
                                                  onlscn, onltime,
                                                  cleanscn,
                                                  clean2scn, clean2time,
                                                  allowfuzzy, partial_rcv,
                                    rcvRecStack(rcvRecStack.count).fromSCN_act,
                                                  dbinc_row.dbinc_key,
                                                  cf_scn, cf_cretime,
                                                  cf_offrrid,
                                                  TRUE, done_flag, allCopies,
                                                  doingRecovery,
                                                  rmanCmd, foreignDbid,
                                                  pluggedRonly, pluginSCN,
                                                  pluginRlgSCN, pluginRlgTime,
                                                  creation_thread,
                                                  creation_size, pdbId,
                                                  pdbForeignDbid);
 
--
--
--
--
                     deb(DEB_IN, 'last=' || to_char(rcvRecStack.last) ||
                         ' trimming last ' ||
                         to_char(rcvRecStack.last - rcvRecStackState.top)
                        );
                     rcvRecStack.trim(rcvRecStack.last - rcvRecStackState.top);
                     rcvRecStackState      := savedrcvRecStackState;
                     deb(DEB_PRINT,'restoring rcvRecStackCount after test search'||rcvRecStack.count);
                     thisBackupAge         := savedBackupAge;
                     deb(DEB_IN, 'count is now '|| to_char(rcvRecStack.count));
 
                     IF (rc) THEN
--
--
--
--
--
--
--
--
--
--
--
--
--
                        IF (parentDbincKey is null) THEN
                           parentDbincKey := dbinc_row.dbinc_key;
                        ELSE
--
--
--
                           deb(DEB_IN,
                               'aborting search due to ambiguous ancestory');
                           CLOSE dbinc_cursor;
                           EXIT action_loop;
                        END IF;
                     END IF;
                  END LOOP;     -- dbinc_loop
               END IF;          -- if we don't know our parent
 
--
--
               IF (parentDbincKey is not null) THEN
                  deb(DEB_IN, 'starting search of parent incarnation key='||
                      to_char(parentDbincKey));
                  rc := computeRecoveryActions2(fno, crescn, cretime,
                                               df_rlgscn, df_rlgtime,
                                               df_ckpscn,
                                               offlscn,
                                               onlscn, onltime,
                                               cleanscn,
                                               clean2scn, clean2time,
                                               allowfuzzy, partial_rcv,
                                     rcvRecStack(rcvRecStack.last).fromSCN_act,
                                               parentDbincKey,
                                               cf_scn, cf_cretime,
                                               cf_offrrid,
                                               FALSE, done_flag, allCopies,
                                               doingRecovery,
                                               rmanCmd, foreignDbid,
                                               pluggedRonly, pluginSCN,
                                               pluginRlgSCN, pluginRlgTime,
                                               creation_thread,
                                               creation_size, pdbId,
                                               pdbForeignDbid);
                  IF (done_flag) THEN
                     deb(DEB_PRINT,'done set to true - 4');
                     done := TRUE;
                  END IF;
 
                  IF (action.type_act = spanningRange_act_t) THEN
--
--
--
--
--
--
                     isAncestor := rc;
                  END IF;
               END IF;          -- we know or found our parent
               EXIT action_loop;
            END IF;             -- offline range start SCN < dbinc_rlgscn
         ELSIF (addAction_rc = action_FAIL) THEN         -- FAIL
--
--
            NULL;
         ELSIF (addAction_rc = action_SKIP) THEN        -- SKIP
--
            NULL;
         ELSIF (addAction_rc = action_OLD_REDO) THEN    -- OLD_REDO
--
--
--
--
--
--
            EXIT action_loop;
         ELSE                                   -- unknown return code
            deb(DEB_EXIT, 'with error 20999');
            raise_application_error(-20999, 'unknown add action return code');
         END IF;
      ELSE                                      -- rcvRecCursor exhausted
         deb(DEB_IN, 'end of cursor reached');
         EXIT action_loop;
      END IF;                                   -- if fetchRecoveryAction
   END LOOP;
 
   IF (done) THEN
      deb(DEB_EXIT,'computeRecoveryActions2 - 3');
      RETURN isAncestor;
   END IF;
 
--
--
--
 
   IF (doingRecovery) THEN                      -- if doing RECOVER
      deb(DEB_PRINT,'computeRecoveryActions2:recovery final check');
      deb(DEB_IN, 'crescn=' || crescn ||';this_reset_scn='||this_reset_scn);
      deb(DEB_IN, 'df_rlgscn='||df_rlgscn||';df_rlgtime='||
                  to_char(df_rlgtime));
 
      IF (rmanCmd = rcvCopyCmd_t) THEN
--
--
--
         deb(DEB_PRINT,'computeRecoveryActions2: no copies stacked');
         resetrcvRecStack;
         done := FALSE;
      ELSIF (rcvRecStack.count > 0) THEN           -- if found some action
         deb(DEB_PRINT,'computeRecoveryActions2:'|| rcvRecStack.count ||
                       ' actions stacked');
--
--
--
--
         rcvRecTop(lastAction);
         stack_df_rlgscn := df_rlgscn;
         IF (df_rlgscn is NULL) THEN
            stack_df_rlgscn := this_reset_scn;
         END IF;
         addRedo_rc := addRedo(isAncestor, df_ckpscn, stack_df_rlgscn,
                               lastAction, partial_rcv, doingRecovery);
         IF (addRedo_rc = action_OK OR addRedo_rc = action_FAIL
             OR addRedo_rc = action_OLD_INC_REDO) THEN
--
--
--
--
--
--
            done := TRUE;
         END IF;
         IF (addRedo_rc = action_OLD_INC_REDO) THEN
--
            rcvRecStack.trim(rcvRecStack.count);
         END IF;
      ELSE
         deb(DEB_PRINT,'computeRecoveryActions2: no actions stacked');
--
--
         IF (df_rlgscn = this_reset_scn AND
             df_rlgtime = this_reset_time) THEN
            done := TRUE;
         ELSIF (action_OLD_INC_REDO =
                        addRedo(isAncestor, df_ckpscn, df_rlgscn,
                               null, partial_rcv, doingRecovery)) THEN
            done := TRUE;
         END IF;
--
--
--
         IF (df_rlgscn is NULL AND           -- df may be created during rcv
             cretime > cf_cretime  AND       -- df created after cf creation
             crescn >  nvl(inc_list(max_inc_idx-1).prior_resetlogs_change#,
                           inc_list(max_inc_idx-1).resetlogs_change#)) THEN
--
            done := TRUE;
         END IF;
      END IF;
   ELSE                                         -- not doing a RECOVER
--
--
--
      IF (rcvRecStackState.savePoint = 0) THEN
--
--
--
--
--
         deb(DEB_IN, 'could try create datafile');
 
         rcvRecStack.trim(rcvRecStack.count - rcvRecStackState.top);
         rcvRecStackState.lowAction := rcvRecStack.count;
         deb(DEB_IN, 'rcvRecStackState :' || rcvRecStackState.top || ' ' ||
                      rcvRecStackState.savePoint || ' ' ||
                      rcvRecStackState.lowAction);
--
 
--
--
--
--
--
--
         IF ((computeRA_available = FALSE)  AND    -- no backup found
             pluginSCN = 0                  AND    -- not a plugin file
             foreignDbid = 0                AND    -- not a foreign file
             pdbForeignDbid = 0             AND    -- not a pdb plugin file
             (creation_thread IS NULL or creation_thread > 0) AND
--
             (creation_size IS NULL or creation_size > 0) AND
--
             (cretime > cf_cretime)  AND           -- df created after cf
             (crescn >  nvl(inc_list(max_inc_idx-1).prior_resetlogs_change#,
                            inc_list(max_inc_idx-1).resetlogs_change#)) AND
--
             (bitand(createdatafile_act_t, getRA_actionMask) != 0) AND
--
             restoreTag is null) THEN              -- from tag not specified
             action          := null_action;
             action.type_con := datafile_con_t;
             action.type_act := createdatafile_act_t;
             action.dfNumber_obj := fno;
             action.dfCreationSCN_obj := crescn;
             action.fromSCN_act := 0;
             action.toSCN_act := crescn;
             action.toTime_act := cretime;
             action.pluggedRonly_obj := 0;
             action.pluginSCN_obj := 0;
             FOR inc_idx in 0..max_inc_idx-1 LOOP
                IF (crescn > inc_list(inc_idx).resetlogs_change#) THEN
                    deb(DEB_PRINT, 'data file created with resetlogs scn='||
                                    inc_list(inc_idx).resetlogs_change#);
                    action.rlgSCN_act := inc_list(inc_idx).resetlogs_change#;
                    action.rlgTime_act := inc_list(inc_idx).resetlogs_time;
                    exit;
                END IF;
             END LOOP;
             IF (action.rlgSCN_act IS NULL) THEN
                deb(DEB_IN, 'rlgSCN is null');
                addAction_rc := action_FAIL;
             ELSE
                addAction_rc := addAction(actionIN      => action,
                                          partial_rcv   => partial_rcv,
                                          isAncestor    => isAncestor,
                                          allCopies     => allCopies,
                                          doingRecovery => doingRecovery,
                                          rmanCmd       => rmanCmd,
                                          pdbId         => pdbId,
                                          cleanSCN      => cleanSCN);
             END IF;
 
             IF (addAction_rc = action_OK) THEN     -- the action was added
                done := TRUE;
                deb(DEB_IN, 'added create datafile action for '||fno);
             ELSE
                deb(DEB_IN, 'failed to add create datafile action for '||fno);
             END IF;
         END IF;
         IF computeRA_available = TRUE THEN
           deb(DEB_IN, 'need different device type channels to restore');
         END IF;
      ELSE
--
--
--
--
--
         deb(DEB_IN, 'trim all actions after savePoint='||
                to_char(greatest(rcvRecStackState.savePoint,
                                 rcvRecStackState.top)));
         rcvRecStack.trim(rcvRecStack.last -
                          greatest(rcvRecStackState.savePoint,
                                   rcvRecStackState.top));
         done := TRUE;
      END IF;
      deb(DEB_PRINT,'computeRecoveryActions2: set rcvRecStackCount='||rcvRecStack.count);
   END IF;                                      -- if doing recover
 
   IF (done) THEN
      deb(DEB_IN, 'done is TRUE');
   ELSE
      deb(DEB_IN, 'done is FALSE');
   END IF;
 
   deb(DEB_EXIT,'computeRecoveryActions2 - 4');
   RETURN isAncestor;
 
END computeRecoveryActions2;
 
--
FUNCTION getParentIncarnation(
   dbinc_key         OUT number
  ,resetlogs_change# OUT number)
RETURN number IS
BEGIN
   deb(DEB_ENTER, 'getParentIncarnation');
 
   SELECT resetlogs_change#, parent_dbinc_key
     INTO resetlogs_change#, dbinc_key
     FROM rc_database_incarnation where dbinc_key = getParentIncarnationKey;
   deb(DEB_EXIT, 'with: TRUE#');
EXCEPTION
   WHEN no_data_found THEN
      deb(DEB_EXIT, 'with: FALSE#');
      RETURN FALSE#;
END getParentIncarnation;
 
--
--
--
FUNCTION getPointInTimeInc(
   toscn IN number)
RETURN NUMBER IS
   pitrlgscn  number;
BEGIN
   IF (getPointInTimeInc.toscn >= this_reset_scn) THEN
      RETURN this_reset_scn;
   END IF;
 
   SELECT dbinc.reset_scn
     INTO pitrlgscn
     FROM (SELECT reset_scn, PRIOR reset_scn next_reset_scn
             FROM dbinc
            START WITH dbinc_key = this_dbinc_key
             CONNECT BY PRIOR parent_dbinc_key = dbinc_key) dbinc
    WHERE dbinc.reset_scn <= getPointInTimeInc.toscn
      AND dbinc.next_reset_scn > getPointInTimeInc.toscn;
 
   RETURN pitrlgscn;
EXCEPTION
   WHEN no_data_found THEN
      RETURN NULL;
END getPointInTimeInc;
 
--
--
--
--
 
FUNCTION get_cfUntilScn
RETURN number IS
  ret_scn number := untilSCN;
  max_scn number;
  max_tag bp.tag%type;
--
  CURSOR keepscn(scn NUMBER) IS
   SELECT bckscn, tag
   FROM
   (SELECT brl.next_scn bckscn, bp.tag
    FROM bs, brl, bp
    WHERE bs.bs_key = brl.bs_key
      AND bs.bs_key = bp.bs_key
      AND bs.keep_options > 0
      AND bp.status = 'A'
      AND brl.low_scn <= scn
      AND brl.next_scn > scn
      AND this_site_key = bs.site_key
      AND this_dbinc_key = dbinc_key
   UNION
    SELECT xal.next_scn bckscn, xal.tag
    FROM xal
    WHERE xal.keep_options > 0
      AND xal.status = 'A'
      AND xal.low_scn <= scn
      AND xal.next_scn > scn
      AND this_site_key = xal.site_key
      AND this_dbinc_key = dbinc_key
   UNION
    SELECT bdf.ckp_scn bckscn, bp.tag
    FROM bs, bdf, bp
    WHERE bs.bs_key = bdf.bs_key
      AND bs.bs_key = bp.bs_key
      AND bs.keep_options > 0
      AND bp.status = 'A'
      AND bdf.ckp_scn = scn+1
      AND this_site_key = bs.site_key
      AND this_dbinc_key = dbinc_key
   UNION
    SELECT xdf.ckp_scn bckscn, xdf.tag
    FROM xdf
    WHERE xdf.keep_options > 0
      AND xdf.status = 'A'
      AND xdf.ckp_scn = scn+1
      AND this_site_key = xdf.site_key
      AND this_dbinc_key = dbinc_key)
   ORDER BY bckscn DESC;
BEGIN
   IF rpoint_set THEN
--
      OPEN keepscn(untilSCN - 1);
      FETCH keepscn INTO max_scn, max_tag;
      CLOSE keepscn;
 
--
      SELECT NVL(MIN(cfscn)+1, untilSCN) INTO ret_scn
      FROM
       (SELECT bcf.ckp_scn cfscn
        FROM bcf, bs, bp
        WHERE bcf.bs_key = bs.bs_key
          AND bs.bs_key = bp.bs_key
          AND bp.status = 'A'
          AND this_site_key = bs.site_key
          AND this_dbinc_key = dbinc_key
          AND bp.tag = max_tag
          AND bcf.ckp_scn > max_scn
       UNION ALL
        SELECT ckp_scn
        FROM ccf
        WHERE this_site_key = site_key
          AND this_dbinc_key = dbinc_key
          AND status = 'A'
          AND tag = max_tag
          AND ckp_scn > max_scn
       UNION ALL
        SELECT ckp_scn
        FROM xcf
        WHERE this_site_key = site_key
          AND this_dbinc_key = dbinc_key
          AND status = 'A'
          AND tag = max_tag
          AND ckp_scn > max_scn);
   deb(DEB_PRINT, 'new scn is ' || ret_scn);
   END IF;
 
   RETURN ret_scn;
END get_cfUntilScn;
 
--
--
 
FUNCTION IsDuplicateAlName(samelog IN number, filename varchar2)
RETURN BOOLEAN IS
  duplicate number;
BEGIN
--
--
--
--
   duplicate := FALSE#;
   IF (samelog = TRUE#) THEN
       FOR log_idx in 0..max_lognames_idx-1 LOOP
          IF lognames_list(log_idx) = filename THEN
            duplicate := TRUE#;
            EXIT;
          END IF;
       END LOOP;
       lognames_list(max_lognames_idx) := filename;
       max_lognames_idx := max_lognames_idx + 1;
   ELSE
     lognames_list(0) := filename;
     max_lognames_idx := 1;
   END IF;
 
   IF duplicate = TRUE# THEN
     deb(DEB_PRINT, 'Filter duplicate log name' || filename);
     RETURN TRUE;
   ELSE
     RETURN FALSE;
   END IF;
 
END IsDuplicateAlName;
 
--
--
--
 
--
--
--
PROCEDURE getCurrentIncarnation(
   db_id          IN  number
  ,reset_scn      OUT number
  ,reset_time     OUT date) IS
BEGIN
   deb(DEB_ENTER, ' getCurrentIncarnation');
   deb(DEB_IN, ' db_id=' || to_char(db_id));
   SELECT  dbinc.reset_scn, dbinc.reset_time
      INTO reset_scn, reset_time
      FROM db, dbinc
      WHERE db_id = getCurrentIncarnation.db_id       -- should return 1 row
      AND dbinc.dbinc_key = db.curr_dbinc_key;
   deb(DEB_EXIT, 'reset_scn='||reset_scn||' reset_time='||reset_time);
 EXCEPTION
    WHEN no_data_found THEN
       deb(DEB_EXIT, 'with error 20001');
       raise_application_error(-20001, 'Database not found');
END;
 
--
--
--
FUNCTION getPrimaryDfName(
     fno IN number)
RETURN varchar2 IS
  local_fname  varchar2(513);
BEGIN
  SELECT fname INTO local_fname
  FROM site_dfatt s, df, node
  WHERE node.database_role = 'PRIMARY'
    AND node.db_key = this_db_key
    AND node.site_key = s.site_key
    AND s.df_key = df.df_key
    AND df.dbinc_key = node.dbinc_key
    AND df.file# = fno
    AND df.dbinc_key = this_dbinc_key
    AND df.drop_scn is NULL
    AND ROWNUM=1;
  RETURN local_fname;
END getPrimaryDfName;
 
--
PROCEDURE setDbincLst
IS
   CURSOR inc_record_c IS
     SELECT * from rc_database_incarnation
       WHERE db_key=this_db_key
         START WITH dbinc_key=this_dbinc_key
         CONNECT BY PRIOR parent_dbinc_key = dbinc_key
       ORDER BY resetlogs_change# DESC;
 
   CURSOR pdb_inc_record_c IS
      SELECT pdbinc.con_id con_id, pdbinc.pdbinc_key,
             pdbinc.inc_scn incscn, pdbinc.end_reset_scn erscn,
             pdbinc_status status
        FROM rci_pdbinc_this_dbinc pdbinc
       WHERE pdbinc.dbinc_key = this_dbinc_key
         AND pdbinc.con_id > 1
       ORDER BY pdbinc.con_id, pdbinc.end_reset_scn DESC;
 
   inc_rec       rc_database_incarnation%ROWTYPE;
   inc_idx       binary_integer;
   pdb_inc_set   pdb_incarnation_set_t;
   pdb_inc_rec   pdb_incarnation_t;
 
BEGIN
   deb(DEB_ENTER, 'setDbincLst');
   IF this_dbinc_key is  NULL OR this_db_key is  NULL THEN
      raise_application_error(-20999, 'internal err: setDbincLst-1');
   END IF;
 
   deb(DEB_PRINT, 'Setting incarnation records as per this_dbinc_key');
   inc_idx := 0;
   FOR inc_rec IN inc_record_c LOOP
      inc_list(inc_idx) := inc_rec;
      deb(DEB_PRINT, 'incarnation record id=' || inc_idx);
      deb(DEB_PRINT, 'icprs=' ||inc_list(inc_idx).prior_resetlogs_change# ||
                     ',icprc='|| inc_list(inc_idx).prior_resetlogs_time);
      deb(DEB_PRINT, 'icrls=' || inc_list(inc_idx).resetlogs_change# ||
                     ',icrlc='|| inc_list(inc_idx).resetlogs_time);
      deb(DEB_PRINT, 'icpinc=' || inc_list(inc_idx).parent_dbinc_key);
      deb(DEB_PRINT, 'icflg=' || inc_list(inc_idx).status);
      inc_idx := inc_idx + 1;
   END LOOP;
 
   max_inc_idx := inc_idx;
   deb(DEB_PRINT, 'number of incarnation=' || max_inc_idx);
 
--
   deb(DEB_PRINT, 'Fetching pdb sub incarnation records');
   pdb_inc_list.delete;
   FOR pdb_inc_rec in pdb_inc_record_c LOOP
      IF (NOT pdb_inc_list.exists(pdb_inc_rec.con_id)) THEN
         pdb_inc_list(pdb_inc_rec.con_id) := pdb_inc_set;
      END IF;
      inc_idx := pdb_inc_list(pdb_inc_rec.con_id).count;
      pdb_inc_list(pdb_inc_rec.con_id)(inc_idx) := pdb_inc_rec;
      deb(DEB_PRINT, 'incarnation record id=' || inc_idx);
      deb(DEB_PRINT, 'con_id='     || pdb_inc_rec.con_id ||  
                    ',pdbinc_key=' || pdb_inc_rec.pdbinc_key);
      deb(DEB_PRINT, 'incscn='     || pdb_inc_rec.incscn ||  
                    ',erscn='      || pdb_inc_rec.erscn);    
      deb(DEB_PRINT, 'status='     || pdb_inc_rec.status);
   END LOOP;
 
   deb(DEB_EXIT);
END setDbincLst;
 
--
--
--
 
--
PROCEDURE setDatabase(
   db_name        IN varchar2
  ,reset_scn      IN number
  ,reset_time     IN date
  ,db_id          IN number
  ,db_unique_name IN varchar2 default NULL
  ,site_aware     IN boolean default FALSE
  ,dummy_instance IN boolean default FALSE
  ,ors_instance   IN boolean default FALSE)
IS
   local        dbinc%rowtype;                    -- local variables
   dbnm         dbinc.db_name%TYPE;
   dbnm_in      dbinc.db_name%TYPE;
   current_inc  varchar2(3);
   rid          varchar2(18);
   ever_resynced number;
BEGIN
   deb(DEB_ENTER, 'setDatabase');
   this_db_key := NULL;                  -- clear in case exception raised
   this_dbinc_key := NULL;
   this_reset_scn := NULL;
   this_reset_time := NULL;
   this_db_unique_name := NULL;
   translation_site_key := NULL;
   this_site_key := NULL;
   dbnm_in := upper(db_name);
 
--
   BEGIN
      SELECT null
        INTO local.db_key
        FROM rcver
       WHERE substr(version,1,11) = catalogVersion;
   EXCEPTION
      WHEN no_data_found THEN
         deb(DEB_EXIT, 'with error 20299');
         raise_application_error(-20299, 'Recovery catalog version mismatch');
   END;
 
--
--
--
--
 
   IF (db_id is not NULL) THEN
      deb(DEB_IN, ' db_id=' || to_char(db_id));
      IF dbms_rcvcat.registerDbPending.dbid = db_id THEN
        dbms_rcvcat.registerDatabase(
          db_id, dbnm_in, reset_scn, reset_time, db_unique_name,
          dbms_rcvcat.registerDbPending.con_id,
          dbms_rcvcat.registerDbPending.guid);
      END IF;  
      BEGIN
         SELECT db.db_key, curr_dbinc_key,
                dbinc.reset_scn, dbinc.reset_time, dbinc.db_name
           INTO local.db_key, local.dbinc_key,
                local.reset_scn, local.reset_time, local.db_name
           FROM db, dbinc
          WHERE db_id = setDatabase.db_id       -- should return 1 row
            AND dbinc.dbinc_key = db.curr_dbinc_key;
      EXCEPTION
         WHEN no_data_found THEN
            deb(DEB_EXIT, 'with error 20001');
            raise_application_error(-20001, 'Database not found');
      END;
 
--
      IF (dbnm_in is NOT NULL) THEN
--
--
--
--
         BEGIN
            SELECT decode(dbinc.dbinc_key, db.curr_dbinc_key, 'YES', 'NO'),
                   dbinc.db_name, dbinc.rowid
              INTO current_inc,
                   dbnm,
                   rid
              FROM db, dbinc
             WHERE db.db_key = dbinc.db_key
               AND db.db_id = setDatabase.db_id
               AND dbinc.reset_scn = setDatabase.reset_scn
               AND dbinc.reset_time = setDatabase.reset_time;
         EXCEPTION
            WHEN no_data_found THEN
               deb(DEB_EXIT, 'with error 20003');
               raise_application_error(-20003,
                                       'Database incarnation not found');
         END;
 
         IF (current_inc = 'NO') THEN
            deb(DEB_EXIT, 'with error 20011');
            raise_application_error(-20011,
                                    'Database incarnation not current');
         END IF;
         IF (dbnm != dbnm_in) THEN
            deb(DEB_PRINT, 'DB_NAME changed from '||dbnm||' to '|| dbnm_in);
            UPDATE dbinc
               SET dbinc.db_name = dbnm_in
             WHERE rowid = rid;
            COMMIT;
         END IF;
      END IF;
   ELSIF (dbnm_in is NOT NULL) THEN
--
      deb(DEB_IN, 'db_id is null');
      BEGIN
         SELECT db.db_key, db.curr_dbinc_key, dbinc.reset_scn, dbinc.reset_time
           INTO local.db_key, local.dbinc_key,
                local.reset_scn, local.reset_time
           FROM db, dbinc
          WHERE db.curr_dbinc_key = dbinc.dbinc_key
            AND dbinc.db_name = dbnm_in;
      EXCEPTION
         WHEN no_data_found THEN
            deb(DEB_EXIT, 'with error 20001');
            raise_application_error(-20001, 'Database not found');
         WHEN too_many_rows THEN
            deb(DEB_EXIT, 'with error 20005');
            raise_application_error(-20005, 'Database name is ambiguous');
      END;
   ELSE
      deb(DEB_EXIT, 'with error 20006');
      raise_application_error(-20006, 'Database name is missing');
   END IF;
 
--
--
   IF dummy_instance THEN
      deb(DEB_PRINT, 'dummy_instance is TRUE');
      this_dummy_instance := TRUE;
   END IF;
   this_db_unique_name := upper(db_unique_name);
   this_db_key         := local.db_key;
   this_dbinc_key      := local.dbinc_key;
   this_reset_scn      := local.reset_scn;
   this_reset_time     := local.reset_time;
 
--
--
--
   IF ors_instance THEN
      IF db_unique_name IS NULL THEN
         raise_application_error(-20999,
           'internal error:db_unique_name must be specified for ORS instance');
      END IF;
      IF db_id IS NULL THEN
         raise_application_error(-20999,
           'internal error: db_id must be specified for ORS instance');
      END IF;
      IF instr(this_db_unique_name, '$'|| db_id) = 0 THEN
         this_db_unique_name := this_db_unique_name || '$' || db_id;
      END IF;
      IF substr(this_db_unique_name, 1, 1) <> '$' THEN
         this_db_unique_name := '$' || this_db_unique_name;
      END IF;
   END IF;
 
 
   deb(DEB_PRINT, 'this_db_unique_name= ' || this_db_unique_name);
   deb(DEB_PRINT, 'this_site_key= ' || this_site_key);
   deb(DEB_PRINT, 'this_db_key='||this_db_key);
   deb(DEB_PRINT, 'this_dbinc_key='||this_dbinc_key);
 
   setDbincLst;
 
   BEGIN
      SELECT site_key into this_site_key FROM node
         where db_unique_name=upper(this_db_unique_name)
           AND db_key = this_db_key;
      deb(DEB_PRINT, 'this_site_key=' || this_site_key);
   EXCEPTION
      WHEN no_data_found THEN
        deb(DEB_PRINT, 'this_site_key is NULL');
   END;
 
   BEGIN
      IF site_aware THEN
         client_site_aware := 1;
         deb(DEB_PRINT, 'client_site_aware=' || client_site_aware);
      END IF;
 
      IF NOT ors_instance AND site_aware AND this_site_key is not NULL THEN
        translation_site_key := this_site_key;
        deb(DEB_PRINT, 'translation_site_key=' || translation_site_key);
      ELSE
        BEGIN
           SELECT site_key into translation_site_key FROM node
              WHERE database_role='PRIMARY'
                AND db_key = this_db_key;
           deb(DEB_PRINT, 'translation_site_key(primary)=' ||
                          translation_site_key);
        EXCEPTION
           WHEN no_data_found THEN
--
--
--
--
--
--
--
--
              select count(*) into ever_resynced from rci_datafile
                 where site_key = this_site_key;
              IF ever_resynced > 0 THEN
                 translation_site_key := this_site_key;
              ELSE
                 select max(site_key) into translation_site_key from node
                    where db_key=this_db_key;
              END IF;
              deb(DEB_PRINT, 'translation_site_key(no_data_found)=' ||
                          translation_site_key);
           WHEN too_many_rows THEN
--
--
--
--
              select max(site_key) into translation_site_key from node
                 where db_key=this_db_key
                   and database_role ='PRIMARY';
              deb(DEB_PRINT, 'translation_site_key(too_many_rows)=' ||
                          translation_site_key);
        END;
      END IF;
   EXCEPTION
      WHEN no_data_found THEN
        deb(DEB_PRINT, 'translation_site_key is NULL');
   END;
 
   IF site_aware AND this_site_key is NULL THEN
      this_site_key := translation_site_key;
      deb(DEB_PRINT, 'this_site_key is set to same  as translation_site_key');
   END IF;
 
   IF site_aware THEN
      setArchiveFileScopeAttributes(logs_shared => 0);
      setBackupFileScopeAttributes (disk_backups_shared => 0,
                                    tape_backups_shared => 1);
   END IF;
   deb(DEB_EXIT);
END setDatabase;
 
--
FUNCTION getDbUniqueName(
   db_id IN number)
RETURN varchar2
IS
   dbunqnm  node.db_unique_name%TYPE;
   CURSOR dbunqnm_c IS
      SELECT node.db_unique_name
        FROM node, db
       WHERE db.db_id  = getDbUniqueName.db_id
         AND db.db_key = node.db_key;
BEGIN
   SELECT node.db_unique_name
     INTO dbunqnm
     FROM node, db
    WHERE db.db_id  = getDbUniqueName.db_id
      AND db.db_key = node.db_key;
 
   RETURN dbunqnm;
EXCEPTION
   WHEN no_data_found THEN
      RETURN NULL;
END getDbUniqueName;
 
--
FUNCTION getDbKey RETURN NUMBER IS
BEGIN
   return this_db_key;
END;
 
--
FUNCTION getMinRcvStartScn RETURN NUMBER IS
   minrcvstartScn   NUMBER;
BEGIN
   SELECT NVL(min(LOW_SCN), 0)
     INTO minrcvstartScn
     FROM rrcache
    WHERE range_type = 'RA$DISK'
    AND db_key = this_db_key;
   RETURN minrcvstartScn;
END;
 
--
PROCEDURE resetDbKey IS
BEGIN 
  this_db_key := NULL;
END;
 
--
PROCEDURE setDbincKey(
   key IN number)
IS
BEGIN
   deb(DEB_ENTER, 'setDbincKey');
   IF (key is not null) THEN
      this_dbinc_key := key;
   ELSE
--
      SELECT curr_dbinc_key
        INTO this_dbinc_key
        FROM db;
   END IF;
 
   SELECT db_key, reset_scn, reset_time
     INTO this_db_key, this_reset_scn, this_reset_time
     FROM dbinc
    WHERE dbinc_key = this_dbinc_key;
 
   setDbincLst;
 
   deb(DEB_EXIT);
END setDbincKey;
 
--
FUNCTION getParentIncarnation(
   resetlogs_change# IN OUT number
  ,resetlogs_time    IN OUT date)
RETURN number IS
BEGIN
   deb(DEB_ENTER, 'getParentIncarnation');
--
--
   IF (resetlogs_change# is null) THEN
      getParentIncarnationKey := this_dbinc_key;
   END IF;
   SELECT resetlogs_change#, resetlogs_time, parent_dbinc_key
     INTO resetlogs_change#, resetlogs_time, getParentIncarnationKey
     FROM rc_database_incarnation where dbinc_key = getParentIncarnationKey;
   deb(DEB_EXIT, 'with: TRUE#');
   RETURN TRUE#;
EXCEPTION
   WHEN no_data_found THEN
      deb(DEB_EXIT, 'with: FALSE#');
      RETURN FALSE#;
END getParentIncarnation;
 
--
PROCEDURE getCheckpoint(
   scn OUT number
  ,seq OUT number
  ,ckp_key_1 OUT number
  ,ckp_key_2 OUT number)
 
IS
  full_row   ckp%ROWTYPE;
  either_row ckp%ROWTYPE;
BEGIN
   deb(DEB_ENTER, 'getCheckpoint');
   IF (this_dbinc_key is NULL) THEN
     deb(DEB_EXIT, 'with error 20020');
     raise_application_error(-20020, 'Database incarnation not set');
   END IF;
 
--
--
 
--
--
--
 
--
--
--
--
--
--
--
 
   FOR r IN (SELECT /*+ first_rows */ * FROM ckp
             WHERE dbinc_key = this_dbinc_key AND
                   ckp_type  = 'FULL' AND
                   site_key = this_site_key
             ORDER BY ckp_scn DESC, cf_create_time DESC, ckp_cf_seq DESC)
   LOOP
     full_row := r;
     EXIT;
   END LOOP;
 
   FOR r IN (SELECT /*+ first_rows */ * FROM ckp
             WHERE dbinc_key      = this_dbinc_key AND
                   cf_create_time = full_row.cf_create_time AND
                   site_key       = this_site_key
             ORDER BY ckp_scn DESC, ckp_cf_seq DESC, ckp_type DESC)
   LOOP
     either_row := r;
     EXIT;
   END LOOP;
 
   IF either_row.ckp_key IS NOT NULL THEN
      scn       := either_row.ckp_scn;
      seq       := either_row.ckp_cf_seq;
      ckp_key_1 := full_row.ckp_key;
      ckp_key_2 := either_row.ckp_key;
   ELSE
      scn       := 0;
      seq       := 0;
      ckp_key_1 := 0;
      ckp_key_2 := 0;
   END IF;
 
   deb(DEB_EXIT);
END getCheckpoint;
 
PROCEDURE getCheckpoint(
   scn OUT number
  ,seq OUT number)
 
IS
   ckp_key_1 number;
   ckp_key_2 number;
BEGIN
   getCheckpoint(scn, seq, ckp_key_1, ckp_key_2);
END getCheckpoint;
 
--
--
--
 
--
PROCEDURE setUntilTime(
   unttime IN date)
IS
    walk_dbinc_key  number := NULL;
    parent_dbinc_key  number := NULL;
BEGIN
   deb(DEB_ENTER, 'setUntilTime');
   IF (this_dbinc_key is NULL) THEN
      deb(DEB_EXIT, 'with error 20020');
      raise_application_error(-20020, 'Database incarnation not set');
   END IF;
 
   walk_dbinc_key := this_dbinc_key;
 
<<parent_inc>>
   untilSCN  := NULL;
   untilTime := unttime;
   rpoint_set := FALSE;
 
   BEGIN
      SELECT resetlogs_change#
         INTO untilSCN
         FROM rc_database_incarnation
      WHERE dbinc_key = walk_dbinc_key
         AND resetlogs_time < untilTime;
   EXCEPTION
      WHEN no_data_found THEN
         BEGIN
            IF (allIncarnations = TRUE#) THEN
               SELECT parent_dbinc_key
                  INTO parent_dbinc_key
                  FROM dbinc
               WHERE dbinc.dbinc_key = walk_dbinc_key;
 
               walk_dbinc_key := parent_dbinc_key;
               IF (walk_dbinc_key IS NULL) THEN
                  deb(DEB_IN, 'parent_dbinc_key=NULL -> exiting');
                  untilSCN := 0;                         -- begining of world
               ELSE
                  deb(DEB_IN, 'parent_dbinc_key=' ||
                     to_char(parent_dbinc_key));
                  GOTO parent_inc;           -- get scn of parent incarnation
               END IF;
            ELSE
               deb(DEB_EXIT, 'with error 20207');
               raise_application_error(-20207,
                                 'until time is before resetlogs time');
            END IF;
         END;
   END;
 
   IF walk_dbinc_key != this_dbinc_key THEN
      actual_dbinc_key := walk_dbinc_key;
      deb(DEB_IN, 'actual_dbinc_key set to:  '||to_char(actual_dbinc_key));
   END IF;
 
--
--
--
--
--
   deb(DEB_IN, 'calling computeUntilSCN. untilSCN=  '||to_char(untilSCN));
   deb(DEB_IN, 'calling computeUntilSCN. untilTime= '||to_char(untilTime));
   computeUntilSCN(untilTime, untilSCN, allIncarnations);
   deb(DEB_IN, 'untilSCN= '||to_char(untilSCN));
   deb(DEB_EXIT, 'untilTime='||to_char(untilTime));
   IF (untilSCN IS NULL) THEN
      raise_application_error(-20213, 'UNTIL TIME could not be translated to 
                                       an UNTIL CHANGE');
   END IF;
EXCEPTION
   WHEN no_data_found THEN
      deb(DEB_EXIT, 'with error 20207');
      raise_application_error(-20207, 'until time is before resetlogs time');
END setUntilTime;
 
--
PROCEDURE setUntilScn(
   scn     IN number
  ,rlgscn  IN number  DEFAULT NULL
  ,rlgtime IN date    DEFAULT NULL
  ,flbrp   IN boolean DEFAULT FALSE
  ,rpoint  IN boolean DEFAULT FALSE)
IS
   walk_dbinc_key    number := NULL;
   walk_dbinc_scn    number := NULL;
   walk_dbinc_time   date   := NULL;
   parent_dbinc_key  number := NULL;
BEGIN
   deb(DEB_ENTER, 'setUntilSCN');
 
   IF (this_dbinc_key is NULL) THEN
      deb(DEB_EXIT, 'with error 20020');
      raise_application_error(-20020, 'Database incarnation not set');
   END IF;
 
   IF (flbrp AND rlgscn IS NOT NULL AND rlgtime IS NOT NULL) THEN
--
--
      BEGIN
         SELECT dbinc_key
           INTO walk_dbinc_key
           FROM rc_database_incarnation
          WHERE resetlogs_change# = rlgscn
            AND resetlogs_time = rlgtime
            AND db_key = this_db_key;
      EXCEPTION
         WHEN no_data_found THEN
            deb(DEB_EXIT, 'with error 20212');
            raise_application_error(-20212,
                                    'until SCN is an orphan incarnation');
      END;
   ELSE
      walk_dbinc_Key := this_dbinc_key;
   END IF;
 
<<parent_inc>>
   untilSCN := scn;
   untilTime := NULL;
 
   BEGIN
      SELECT untilSCN, resetlogs_change#, resetlogs_time
         INTO untilSCN, walk_dbinc_scn, walk_dbinc_time
         FROM rc_database_incarnation
      WHERE dbinc_key = walk_dbinc_key
         AND resetlogs_change# < untilSCN;
   EXCEPTION
      WHEN no_data_found THEN
         BEGIN
            IF (allIncarnations = TRUE#) THEN
               SELECT parent_dbinc_key
                  INTO parent_dbinc_key
                  FROM dbinc
               WHERE dbinc.dbinc_key = walk_dbinc_key;
 
               walk_dbinc_key := parent_dbinc_key;
               IF (walk_dbinc_key IS NULL) THEN
                  deb(DEB_EXIT, 'parent_dbinc_key=NULL, with error 20208');
                  raise_application_error(-20208,
                                    'until SCN is before resetlogs SCN');
               ELSE
                  deb(DEB_IN, 'parent_dbinc_key=' ||
                     to_char(parent_dbinc_key));
                  GOTO parent_inc;           -- get scn of parent incarnation
               END IF;
            ELSE
               deb(DEB_EXIT, 'with error 20208');
               raise_application_error(-20208,
                                 'until SCN is before resetlogs SCN');
            END IF;
         END;
   END;
 
   IF (rlgscn != walk_dbinc_scn OR rlgtime != walk_dbinc_time) THEN
      deb(DEB_EXIT, 'with error 20212');
      raise_application_error(-20212, 'until SCN is an orphan incarnation');
   END IF;
 
--
   rpoint_set := rpoint and not flbrp;
 
   IF walk_dbinc_key != this_dbinc_key THEN
      actual_dbinc_key := walk_dbinc_key;
      deb(DEB_IN, 'actual_dbinc_key set to:  '||to_char(actual_dbinc_key));
   END IF;
 
   deb(DEB_EXIT);
EXCEPTION
   WHEN no_data_found THEN
      deb(DEB_EXIT, 'with error 20208');
      raise_application_error(-20208,'until SCN is before resetlogs SCN');
END setUntilScn;
 
--
PROCEDURE setUntilLog(
   sequence# IN number
  ,thread#   IN number)
IS
    walk_dbinc_key  number := NULL;
    parent_dbinc_key  number := NULL;
BEGIN
   deb(DEB_ENTER, 'setUntilLog');
   rpoint_set := FALSE;
 
   IF (this_dbinc_key is NULL) THEN
      deb(DEB_EXIT, 'with error 20020');
      raise_application_error(-20020, 'Database incarnation not set');
   END IF;
 
   IF (sequence# is NULL) THEN
      deb(DEB_EXIT, 'with error 20205');
      raise_application_error(-20205, 'Incomplete UNTIL clause');
   END IF;
 
   walk_dbinc_Key := this_dbinc_key;
 
<<parent_inc>>
   untilTime := NULL;
   untilSCN := NULL;
 
   BEGIN
--
      SELECT first_change#
        INTO untilSCN
        FROM rc_log_history
       WHERE dbinc_key = walk_dbinc_key
         AND thread# = nvl(setUntilLog.thread#, 1)  -- default thread# is 1
         AND sequence# = setUntilLog.sequence#;
   EXCEPTION
      WHEN no_data_found THEN
         BEGIN
--
--
            SELECT next_change#
              INTO untilSCN
              FROM rc_log_history
             WHERE dbinc_key = this_dbinc_key
--
               AND thread# = nvl(setUntilLog.thread#, 1)
               AND sequence# = setUntilLog.sequence# - 1;
         EXCEPTION
            WHEN no_data_found THEN
               BEGIN
                  IF (allIncarnations = TRUE#) THEN
                     SELECT parent_dbinc_key
                       INTO parent_dbinc_key
                       FROM dbinc
                      WHERE dbinc.dbinc_key = walk_dbinc_key;
 
                     walk_dbinc_key := parent_dbinc_key;
                     IF (walk_dbinc_key IS NULL) THEN
                        deb(DEB_EXIT, 'with error 20206');
                        raise_application_error(-20206,
                                               'Specified log does not exist');
                     ELSE
                        deb(DEB_IN, 'parent_dbinc_key=' ||
                                    to_char(parent_dbinc_key));
                        GOTO parent_inc;     -- get scn of parent incarnation
                     END IF;
                  ELSE
                     deb(DEB_EXIT, 'with error 20206');
                     raise_application_error(-20206,
                                             'Specified log does not exist');
                  END IF;
               END;
         END;
   END;
 
   IF walk_dbinc_key != this_dbinc_key THEN
      actual_dbinc_key := walk_dbinc_key;
      deb(DEB_IN, 'actual_dbinc_key set to:  '||to_char(actual_dbinc_key));
   END IF;
 
   deb(DEB_EXIT);
END setUntilLog;
 
--
PROCEDURE setToLog(
   sequence# IN number
  ,thread#   IN number)
IS
BEGIN
   deb(DEB_ENTER, 'setToLog');
   untilTime := NULL;
   untilSCN := NULL;
   rpoint_set := FALSE;
 
   IF (this_dbinc_key is NULL) THEN
      deb(DEB_EXIT, 'with error 20020');
      raise_application_error(-20020, 'Database incarnation not set');
   END IF;
 
   IF (sequence# is NULL) THEN
      deb(DEB_EXIT, 'with error 20205');
      raise_application_error(-20205, 'Incomplete TO clause');
   END IF;
 
   BEGIN
--
      SELECT (next_change# - 1)
        INTO untilSCN
        FROM rc_log_history
       WHERE dbinc_key = this_dbinc_key
         AND thread# = nvl(setToLog.thread#, 1)        -- default thread# is 1
         AND sequence# = setToLog.sequence#;
   EXCEPTION
      WHEN no_data_found THEN
         BEGIN
--
--
            SELECT (first_change# - 1)
              INTO untilSCN
              FROM rc_log_history
             WHERE dbinc_key = this_dbinc_key
--
               AND thread# = nvl(setToLog.thread#, 1)
               AND sequence# = setToLog.sequence# + 1;
         EXCEPTION
            WHEN no_data_found THEN
               deb(DEB_EXIT, 'with error 20206');
               raise_application_error(-20206, 'Specified log does not exist');
         END;
   END;
   deb(DEB_EXIT);
END setToLog;
 
--
PROCEDURE getRedoLogDeletionPolicy(
  policy  OUT varchar2)
IS
BEGIN
   raise_application_error(-20999, 'Not supported in recovery catalog');
END getRedoLogDeletionPolicy;
 
--
PROCEDURE setRedoLogDeletionPolicy(
  policy  IN varchar2
 ,alldest IN number)
IS
BEGIN
   raise_application_error(-20999, 'Not supported in recovery catalog');
END setRedoLogDeletionPolicy;
 
--
PROCEDURE resetAll(
  transclause IN boolean DEFAULT TRUE)
IS
BEGIN
   deb(DEB_PRINT, 'resetAll');
 
--
   setRAflags(kindMask   => allKind,
              allRecords => FALSE);
   setAllFlag(FALSE);
   setLikePattern(NULL);
   setCompletedRange(after => NULL, before => NULL);
   resetUntil;
   setFrom(NULL);
   resetDeviceType;
   setTag(NULL);                        -- restoreTag := NULL
   setStandby(NULL);
   setGuid(NULL);
   versionCounter        := 1;     -- for getPackageVersion
   getArchivedLogCursor  := NULL;
   getBackupPieceCursor  := NULL;
   getDatafileCopyCursor := NULL;
   getDatafileCursor     := NULL;
   getProxyCopyCursor    := NULL;
   localOrsSiteKey       := NULL;
 
   IF (transclause) THEN
      deb(DEB_PRINT, 'reset transclause');
      resetAlTransClause;                  -- reset AlTransClause
      resetDBTransClause;                  -- reset DBTransClause
      resetDbidTransClause;                -- reset DbidTransClause
      resetPdbIdList;                      -- reset PdbIdList
      resetPdbNameList;                    -- reset PdbNameList
      resetPdbFileList;                    -- reset PdbFileList
   END IF;
   resetBsRecCache(FALSE);              -- reset findvalid backupset cache
 
   setRcvRecBackupAge(0);               -- reset backup age variables
   setRecoveryDestFile(FALSE);          -- reset to all files
   setOrsFile(NULL, NULL);              -- reset to all files
   findSpfileBackupCursor      := FALSE;
   findControlfileBackupCursor := FALSE;
 
--
   rcvRecCursor.currc1.type_con := to_number(null);
   rcvRecCursor.reqfno := to_number(null);
   rcvRecCursor.reqcrescn := to_number(null);
   rcvRecCursor.reqpluginSCN := 0;
   rcvRecCursor.excludeAction := 0;
 
--
   resetrcvRecStack;
 
   pname_i := 0;                        -- reset debuging
 
   IF findControlfileBackup_c%ISOPEN THEN
      CLOSE findControlfileBackup_c;
   END IF;
   IF findSpfileBackup_c%ISOPEN THEN
      CLOSE findSpfileBackup_c;
   END IF;
   IF findControlFileCopyKey%ISOPEN THEN
      CLOSE findControlFileCopyKey;
   END IF;
   IF findDatafileCopyKey%ISOPEN THEN
      CLOSE findDatafileCopyKey;
   END IF;
   IF findDatafileBackup_c%ISOPEN THEN
      CLOSE findDatafileBackup_c;
   END IF;
   IF findProxyCopy%ISOPEN THEN
      CLOSE findProxyCopy;
   END IF;
   IF findProxyCopyKey%ISOPEN THEN
      CLOSE findProxyCopyKey;
   END IF;
   IF findArchivedLogCopy%ISOPEN THEN
      CLOSE findArchivedLogCopy;
   END IF;
   IF findArcLogBackup%ISOPEN THEN
      CLOSE findArcLogBackup;
   END IF;
   IF findRangeArcLogBackup%ISOPEN THEN
      CLOSE findRangeArcLogBackup;
   END IF;
   IF findValidBackupSet_c%ISOPEN THEN
      CLOSE findValidBackupSet_c;
   END IF;
   IF findValidBackupSet1P_c%ISOPEN THEN
      CLOSE findValidBackupSet1P_c;
   END IF;
   IF findBackupPiece_c%ISOPEN THEN
      CLOSE findBackupPiece_c;
   END IF;
   IF findBackupPieceBpKey%ISOPEN THEN
      CLOSE findBackupPieceBpKey;
   END IF;
   IF findBackupPieceBsKey1%ISOPEN THEN
      CLOSE findBackupPieceBsKey1;
   END IF;
   IF findBackupPieceBsKey2%ISOPEN THEN
      CLOSE findBackupPieceBsKey2;
   END IF;
   IF translateDatabase_c%ISOPEN THEN
      CLOSE translateDatabase_c;
   END IF;
   IF translateDatabaseOfPdbId_c%ISOPEN THEN
      CLOSE translateDatabaseOfPdbId_c;
   END IF;
   IF translateDatabaseOfPdbIdL_c%ISOPEN THEN
      CLOSE translateDatabaseOfPdbIdL_c;
   END IF;
   IF translateTablespace_c%ISOPEN THEN
      CLOSE translateTablespace_c;
   END IF;
   IF translateDatafileName%ISOPEN THEN
      CLOSE translateDatafileName;
   END IF;
   IF translateDatafileNumber%ISOPEN THEN
      CLOSE translateDatafileNumber;
   END IF;
   IF translateDatafileCheckpoint%ISOPEN THEN
      CLOSE translateDatafileCheckpoint;
   END IF;
   IF translateAllDf_c%ISOPEN THEN
      CLOSE translateAllDf_c;
   END IF;
   IF translateAllDfOfPdbId_c%ISOPEN THEN
      CLOSE translateAllDfOfPdbId_c;
   END IF;
   IF translateAllDfOfPdbIdL_c%ISOPEN THEN
      CLOSE translateAllDfOfPdbIdL_c;
   END IF;
   IF translateCorruptList_c%ISOPEN THEN
      CLOSE translateCorruptList_c;
   END IF;
   IF translateTempfile_c%ISOPEN THEN
      CLOSE translateTempfile_c;
   END IF;
   IF translateTempfileOfPdbId_c%ISOPEN THEN
      CLOSE translateTempfileOfPdbId_c;
   END IF;
   IF translateTempfileOfPdbIdL_c%ISOPEN THEN
      CLOSE translateTempfileOfPdbIdL_c;
   END IF;
   IF translateTempfileName_c%ISOPEN THEN
      CLOSE translateTempfileName_c;
   END IF;
   IF translateTempfileNumber_c%ISOPEN THEN
      CLOSE translateTempfileNumber_c;
   END IF;
   IF translateOnlineLogs_c%ISOPEN THEN
      CLOSE translateOnlineLogs_c;
   END IF;
   IF translateArcLogKey%ISOPEN THEN
      CLOSE translateArcLogKey;
   END IF;
   IF translateArcLogName%ISOPEN THEN
      CLOSE translateArcLogName;
   END IF;
   IF translateArcLogSeqRange%ISOPEN THEN
      CLOSE translateArcLogSeqRange;
   END IF;
   IF translateArcLogSeqRange2%ISOPEN THEN
      CLOSE translateArcLogSeqRange2;
   END IF;
   IF translateArcLogTimeRange%ISOPEN THEN
      CLOSE translateArcLogTimeRange;
   END IF;
   IF translateArcLogTimeRange2%ISOPEN THEN
      CLOSE translateArcLogTimeRange2;
   END IF;
   IF translateArcLogSCNRange%ISOPEN THEN
      CLOSE translateArcLogSCNRange;
   END IF;
   IF translateArcLogSCNRange2%ISOPEN THEN
      CLOSE translateArcLogSCNRange2;
   END IF;
   IF translateArcLogPattern%ISOPEN THEN
      CLOSE translateArcLogPattern;
   END IF;
   IF lbal2%ISOPEN THEN
      CLOSE lbal2;
   END IF;
   IF ldbi%ISOPEN THEN
      CLOSE ldbi;
   END IF;
   IF lnni%ISOPEN THEN
      CLOSE lnni;
   END IF;
   IF lrtbs%ISOPEN THEN
      CLOSE lrtbs;
   END IF;
   IF getOfflineRangeCopy_c%ISOPEN THEN
      CLOSE getOfflineRangeCopy_c;
   END IF;
   IF rddf%ISOPEN THEN
      CLOSE rddf;
   END IF;
   IF translateDatabaseCorruption_c%ISOPEN THEN
      CLOSE translateDatabaseCorruption_c;
   END IF;
   IF findConfig_c%ISOPEN THEN
      CLOSE findConfig_c;
   END IF;
   IF findBackupsetFiles%ISOPEN THEN
      CLOSE findBackupsetFiles;
   END IF;
   IF findAllBackupPiece%ISOPEN THEN
      CLOSE findAllBackupPiece;
   END IF;
   IF dfBackupHistory_c1%ISOPEN THEN
      CLOSE dfBackupHistory_c1;
   END IF;
   IF dfBackupHistory_c2%ISOPEN THEN
      CLOSE dfBackupHistory_c2;
   END IF;
   IF dcBackupHistory_c%ISOPEN THEN
      CLOSE dcBackupHistory_c;
   END IF;
   IF alBackupHistory_c1%ISOPEN THEN
      CLOSE alBackupHistory_c1;
   END IF;
   IF alBackupHistory_c2%ISOPEN THEN
      CLOSE alBackupHistory_c2;
   END IF;
   IF bsBackupHistory_c1%ISOPEN THEN
      CLOSE bsBackupHistory_c1;
   END IF;
   IF bsBackupHistory_c1%ISOPEN THEN
      CLOSE bsBackupHistory_c1;
   END IF;
   IF getCopyofDatafile_c%ISOPEN THEN
      CLOSE getCopyofDatafile_c;
   END IF;
   IF getCopyofDatafile_c2%ISOPEN THEN
      CLOSE getCopyofDatafile_c2;
   END IF;
   IF rcvRecCursor1_c%ISOPEN THEN
      CLOSE rcvRecCursor1_c;
   END IF;
   IF rcvRecCursor1Filter_c%ISOPEN THEN
      CLOSE rcvRecCursor1Filter_c;
   END IF;
   IF rcvRecCursor2_c%ISOPEN THEN
      CLOSE rcvRecCursor2_c;
   END IF;
   IF listBackup_c%ISOPEN THEN
      CLOSE listBackup_c;
   END IF;
   IF translatePdbName_c%ISOPEN THEN
      CLOSE translatePdbName_c;
   END IF;
   IF translatePdbFile_c%ISOPEN THEN
      CLOSE translatePdbFile_c;
   END IF;
   getArchivedLogLast   := NULL;             -- clear for next time
   getArchivedLogDoingRecovery := FALSE#;    -- clear for next time
   getArchivedLogOnlyrdf := 0;
   lbacked_al_next_scn := NULL;
   standby_became_primary_scn := NULL;
   getrcvRecLast := NULL;
   this_stdby_controlfile_scn := NULL;
   setSkipOfflineRangeAboveSCN(NULL);
END resetAll;
 
--
--
--
 
--
PROCEDURE findValidBackupSet(
   backupSetRec            IN     rcvRec_t
  ,deviceType              IN     varchar2       DEFAULT NULL
  ,tag                     IN     varchar2       DEFAULT NULL
  ,available               IN     number         DEFAULT TRUE#  -- for compat.
  ,unavailable             IN     number         DEFAULT FALSE# -- for compat.
  ,deleted                 IN     number         DEFAULT FALSE# -- for compat.
  ,expired                 IN     number         DEFAULT FALSE# -- for compat.
  ,availableMask           IN     binary_integer DEFAULT NULL)  -- for compat.
IS
BEGIN
   deb(DEB_ENTER, 'findValidBackupSet');
   IF (bsRecCacheEnabled) THEN
      cacheFindValidBackupSet(
         bsRec         => backupSetRec,
         deviceType    => deviceType,
         tag           => tag,
         availableMask => NVL(availableMask,
            computeAvailableMask(available, unavailable, deleted, expired)));
   ELSE
      findValidBackupSet(
         bsKey         => backupSetRec.bsKey_con,
         pieceCount    => backupSetRec.pieceCount_con,
         deviceType    => deviceType,
         tag           => tag,
         availableMask => NVL(availableMask,
            computeAvailableMask(available, unavailable, deleted, expired)));
   END IF;
   deb(DEB_EXIT);
END findValidBackupSet;
 
--
--
PROCEDURE findValidBackupSet(
   backupSetRec            IN     bsRec_t
  ,deviceType              IN     varchar2       DEFAULT NULL
  ,tag                     IN     varchar2       DEFAULT NULL
  ,available               IN     number         DEFAULT TRUE#  -- for compat.
  ,unavailable             IN     number         DEFAULT FALSE# -- for compat.
  ,deleted                 IN     number         DEFAULT FALSE# -- for compat.
  ,expired                 IN     number         DEFAULT FALSE# -- for compat.
  ,availableMask           IN     binary_integer DEFAULT NULL)  -- for compat.
IS
BEGIN
   deb(DEB_ENTER, 'findValidBackupSet bsRec_t');
   findValidBackupSet(bsKey         => backupSetRec.key,
                      pieceCount    => backupSetRec.pieceCount,
                      deviceType    => deviceType,
                      tag           => tag,
                      availableMask => NVL(availableMask,
                          computeAvailableMask(available, unavailable, deleted,
                                               expired)));
   deb(DEB_EXIT);
END findValidBackupSet;
 
--
 
--
PROCEDURE getDatafile(
   file#                        OUT number
  ,crescn                       OUT number
  ,creation_time                OUT date
  ,fname                        OUT varchar2
  ,ts_name                      OUT varchar2
  ,status                       OUT number
  ,blksize                      OUT number
  ,kbytes                       OUT number
  ,blocks                       OUT number
  ,unrecoverable_change#        OUT number
  ,stop_change#                 OUT number
  ,read_only                    OUT number)
IS
   dfRec        dfRec_t;
BEGIN
   deb(DEB_ENTER, 'getDataFile_2');
   getDatafile(dfRec, oldClient => TRUE);
 
   file#                 := dfRec.dfNumber;
   crescn                := dfRec.dfCreationSCN;
   creation_time         := dfRec.dfCreationTime;
   fname                 := dfRec.fileName;
   ts_name               := dfRec.tsName;
   status                := 0; -- this is kccfesta, which we don't have
   blksize               := dfRec.blockSize;
   kbytes                := dfRec.kbytes;
   blocks                := dfRec.blocks;
   unrecoverable_change# := 0; -- this is kccfeurs which isn't kept in rcvcat
   stop_change#          := dfRec.stopSCN;
   read_only             := dfRec.readOnly;
   deb(DEB_EXIT);
EXCEPTION
   WHEN no_data_found THEN
--
      file# := NULL;
   deb(DEB_EXIT, 'with no more records');
END getDatafile;
 
--
--
--
--
--
--
--
--
 
--
PROCEDURE listTranslateProxyDFRecid(
   recid              IN number
  ,stamp              IN number
  ,xdf_key            OUT number
  ,file#              OUT number
  ,status             OUT varchar2
  ,handle             OUT varchar2
  ,completion_time    OUT date
  ,checkpoint_change# OUT number
  ,checkpoint_time    OUT date)
IS
BEGIN
   deb(DEB_ENTER, 'listTranslateProxyDFRecid');
--
--
--
--
--
 
   IF (recid <> rcvRec_last.recid_con OR
       stamp <> rcvRec_last.stamp_con) THEN
  select d.xdf_key, d.file#, d.status, d.handle, d.completion_time,
         d.checkpoint_change#, d.checkpoint_time
  into xdf_key, file#, status, handle, completion_time, checkpoint_change#,
       checkpoint_time
  from   rc_proxy_datafile d
  where  db_key = this_db_key
    and ((user_site_key  = d.site_key) OR
         (user_site_key IS NULL AND
          ((tape_backups_shared = TRUE#) OR
           (this_site_key = nvl(d.site_key, this_site_key)))))
    and  d.recid = listTranslateProxyDFRecid.recid
    and  d.stamp = listTranslateProxyDFRecid.stamp
  union all
  select c.xcf_key, 0, c.status, c.handle, c.completion_time,
         c.checkpoint_change#, c.checkpoint_time
  from   rc_proxy_controlfile c
  where  db_key = this_db_key
    and ((user_site_key  = c.site_key) OR
         (user_site_key IS NULL AND
          ((tape_backups_shared = TRUE#) OR
           (this_site_key = nvl(c.site_key, this_site_key)))))
    and  c.recid = listTranslateProxyDFRecid.recid
    and  c.stamp = listTranslateProxyDFRecid.stamp;
 
   ELSE
      deb(DEB_PRINT, 'listTranslateProxyDFRecid: using cached rcvRec_last');
      xdf_key            := rcvRec_last.key_con;
      file#              := rcvRec_last.dfNumber_obj;
      status             := rcvRec_last.status_con;
      handle             := rcvRec_last.fileName_con;
      completion_time    := rcvRec_last.compTime_con;
      checkpoint_change# := rcvRec_last.toSCN_act;
      checkpoint_time    := rcvRec_last.toTime_act;
   END IF;
   deb(DEB_EXIT);
END listTranslateProxyDFRecid;
 
--
--
--
 
--
--
--
--
--
--
--
--
 
--
PROCEDURE findOfflineRangeCopy(
   offr_recid   IN number
  ,offr_ckpscn  IN number
  ,cf_cretime   IN date
  ,dbinc_key    IN number)
IS
BEGIN
   deb(DEB_ENTER, 'findOfflineRangeCopy');
   validateState(null);
 
   deb(DEB_OPEN, 'getOfflineRangeCopy_c');
   OPEN getOfflineRangeCopy_c(offrRecid  => offr_recid,
                              offrCkpSCN => offr_ckpscn,
                              cfCreTime  => cf_cretime,
                              dbincKey   => dbinc_key);
   deb(DEB_EXIT);
END findOfflineRangeCopy;
 
--
PROCEDURE getOfflineRangeCopy(
   rcvRec  OUT NOCOPY rcvRec_t)
IS
BEGIN
   deb(DEB_ENTER, 'getOfflineRangeCopy');
   IF (NOT getOfflineRangeCopy_c%ISOPEN) THEN
      deb(DEB_EXIT, 'with error 20204');
      raise_application_error(-20204, 'Translation not started');
   END IF;
 
   FETCH getOfflineRangeCopy_c
    INTO rcvRec;
 
   IF (getOfflineRangeCopy_c%NOTFOUND) THEN
      CLOSE getOfflineRangeCopy_c;
      deb(DEB_EXIT, 'with no more records');
      RAISE no_data_found;
   END IF;
   CLOSE getOfflineRangeCopy_c;
   deb(DEB_EXIT);
END getOfflineRangeCopy;
 
--
 
--
FUNCTION getOfflineRangeCopy
RETURN varchar2 IS
   rcvRec       rcvRec_t;
BEGIN
   deb(DEB_ENTER, 'getOfflineRangeCopy815');
   getOfflineRangeCopy(rcvRec);
   deb(DEB_EXIT, 'with: fileName');
   RETURN rcvRec.fileName_con;
EXCEPTION
   WHEN no_data_found THEN
      deb(DEB_EXIT, 'with: NULL');
      RETURN NULL;
END getOfflineRangeCopy;
 
--
--
--
 
--
FUNCTION computeRecoveryActions(
fno        IN number,   -- Datafile number.
crescn     IN number,   -- Datafile creation SCN.
df_rlgscn  IN number    -- Datafile resetlogs SCN.  Null unless we are doing
   default null,        -- a RECOVER, in which case is the value in the
--
df_rlgtime IN date      -- Datafile resetlogs time.  Null if df_rlgscn is
   default null,        -- null, else value from datafile header.
df_ckpscn  IN number    -- Datafile checkpoint SCN.  Null if df_rlgscn is
   default null,        -- null, else value from datafile header.
offlscn    IN number    -- kccfeofs (0 -> no offline range)
   default 0,
onlscn     IN number    -- kccfeonc (0 if offlscn is 0).
   default 0,
onltime    IN date      -- kccfonc_time
   default null,
cleanscn   IN number    -- kccfecps if either SOR or WCC set, else 0.
   default 0,
clean2scn  IN number    -- CF ckpt SCN if WCC set, infinity if SOR bit set
   default 0,           -- else 0.
clean2time IN date      -- controlfile ckpt time if WCC, SYSDATE if SOR, else
   default null,        -- this is ignored if cleanscn is 0
allowfuzzy IN boolean   -- TRUE if can be fuzzy at until SCN/time, FALSE if
  default FALSE,        -- not.  default is FALSE.
partial_rcv IN boolean  -- TRUE if can do partial recovery, FALSE if not.
  default FALSE,        -- A partial recovery would be to recover a datafile
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
cf_scn     IN number    -- controlfile ckpt SCN (NULL if none mounted)
  default NULL,
cf_cretime IN date      -- controlfile creation time (NULL if none mounted)
  default NULL,
cf_offrrid IN number    -- recid of oldest offline range in controlfile
  default NULL,         -- (NULL if none mounted)
allCopies  IN boolean
  default FALSE,
df_cretime IN DATE
  default NULL,
rmanCmd    IN binary_integer
  default unknownCmd_t,
foreignDbid   IN number
  default 0,
pluggedRonly  IN binary_integer
  default 0,
pluginSCN     IN number
  default 0,
pluginRlgSCN  IN number
  default 0,
pluginRlgTime IN date
  default NULL,
creation_thread IN number
  default NULL,
creation_size   IN number
  default NULL,
pdbId IN number
  default 1,
pdbForeignDbid IN number
  default 0)
RETURN binary_integer IS
   rc              boolean;
   last            number;
   this            number;
   succ_flag       boolean;
   thisAct         rcvRec_t;
   doingRecovery   boolean;
   lrmanCmd        binary_integer := rmanCmd;
   target_scn      number         := to_number(null);
BEGIN
   deb(DEB_ENTER, 'computeRecoveryActions');
   IF (this_dbinc_key is NULL) THEN
      deb(DEB_EXIT, 'with error 20020');
      raise_application_error(-20020, 'Database incarnation not set');
   END IF;
 
   deb(DEB_IN, '  fno:          '||fno);
   deb(DEB_IN, '  crescn:       '||crescn);
   deb(DEB_IN, '  df_rlgscn:    '||df_rlgscn);
   deb(DEB_IN, '  df_ckpscn:    '||to_char(df_ckpscn));
   deb(DEB_IN, '  offlscn:      '||to_char(offlscn));
   deb(DEB_IN, '  onlscn:       '||to_char(onlscn));
   deb(DEB_IN, '  cleanscn:     '||to_char(cleanscn));
   deb(DEB_IN, '  clean2scn:    '||to_char(clean2scn));
   deb(DEB_IN, '  cf_scn:       '||to_char(cf_scn));
   deb(DEB_IN, '  cf_offrrid:   '||to_char(cf_offrrid));
   deb(DEB_IN, '  foreignDbid:  '||to_char(foreignDbid));
   deb(DEB_IN, '  pluggedRonly: '||to_char(pluggedRonly));
   deb(DEB_IN, '  pluginSCN:    '||to_char(pluginSCN));
   deb(DEB_IN, '  pluginRlgSCN: '||to_char(pluginRlgSCN));
   deb(DEB_IN, '  creation_thread: '||to_char(creation_thread));
   deb(DEB_IN, '  creation_size:   '||to_char(creation_size));
   deb(DEB_IN, '  pdbid:           '||to_char(pdbId));
   deb(DEB_IN, '  pdbForeignDbid:  '||to_char(pdbForeignDbid));
 
   resetrcvRecStack;
 
   computeRA_restorable    := FALSE;
   computeRA_available     := FALSE;
   computeRA_rcvCopy_avail := FALSE;
 
   IF (allCopies) THEN
      deb(DEB_IN, 'allCopies is TRUE');
   ELSE
      deb(DEB_IN, 'allCopies is FALSE');
   END IF;
 
   IF (df_cretime is null AND  -- pre10g rman client
       lrmanCmd = unknownCmd_t AND
       df_ckpscn is not null) THEN
      deb(DEB_IN, 'rmanCmd set to recoverCmd_t for pre10g rman');
      lrmanCmd := recoverCmd_t;
   END IF;
 
   IF (lrmanCmd = rcvCopyCmd_t) THEN
      deb(DEB_PRINT, 'doing recover copy');
      doingRecovery := TRUE;
   ELSIF (lrmanCmd = recoverCmd_t) THEN
      deb(DEB_PRINT, 'doing recover');
      doingRecovery := TRUE;
   ELSIF (lrmanCmd = obsoleteCmd_t) THEN
      deb(DEB_PRINT, 'doing report obsolete');
      doingRecovery := NULL;
      IF (allCopies) THEN
--
--
--
--
         raise_application_error(-20999,
                                'internal error: computeRecoveryActions ' ||
                                'obsoleteCmd cannot be called with allCopies');
      END IF;
      IF (tc_database = FALSE#) THEN
--
--
         raise_application_error(-20999,
              'internal error: computeRecoveryActions ' ||
              'obsoleteCmd cannot be called for specific files');
      END IF;
   ELSIF (lrmanCmd = restoreCmd_t) THEN
      deb(DEB_PRINT, 'doing restore');
      doingRecovery := NULL;
   ELSIF (lrmanCmd = blkRestoreCmd_t) THEN
      deb(DEB_PRINT, 'doing block restore');
      doingRecovery := FALSE;
      target_scn := df_ckpscn;
   ELSIF (lrmanCmd = unknownCmd_t) THEN
      deb(DEB_PRINT, 'command unknown or called by pre-10i rman');
      doingRecovery := NULL;
   ELSE
      raise_application_error(-20999, 'internal error: computeRecoveryActions'
                              || ' rmanCmd='||nvl(to_char(lrmanCmd), 'NULL'));
   END IF;
 
   deb(DEB_IN, 'this_dbinc_key is:'||to_char(this_dbinc_key));
   rc := computeRecoveryActions2(fno, crescn, df_cretime,
                                df_rlgscn, df_rlgtime, df_ckpscn,
                                offlscn, onlscn, onltime,
                                cleanscn, clean2scn, clean2time,
                                allowfuzzy, partial_rcv,
                                target_scn, this_dbinc_key,
                                cf_scn, cf_cretime, cf_offrrid,
                                FALSE, succ_flag, allCopies, doingRecovery,
                                lrmanCmd, foreignDbid,
                                pluggedRonly, pluginSCN, pluginRlgSCN,
                                pluginRlgTime, creation_thread, creation_size,
                                pdbId, pdbForeignDbid);
 
   IF (succ_flag) THEN
      IF (rcvRecStack.count > 0) THEN
         IF (computeRA_allRecords = FALSE#) THEN
--
--
--
--
 
--
--
 
--
--
 
--
--
--
--
--
--
 
            last := rcvRecStack.count;
            deb(DEB_IN,'computeRecoveryActions: Top of stack='||
                       rcvRecStack.count);
            FOR this IN REVERSE 2..rcvRecStack.count - 1 LOOP
               IF ((rcvRecStack(last).toSCN_act >=
                    rcvRecStack(this-1).fromSCN_act)
                   AND NOT
--
                   (allCopies                       AND
                    ((rcvRecStack(last).key_con =
                      rcvRecStack(this).key_con   AND
                      rcvRecStack(last).type_con =
                      rcvRecStack(this).type_con) OR
                     (rcvRecStack(this-1).key_con =
                      rcvRecStack(this).key_con   AND
                      rcvRecStack(this-1).type_con =
                      rcvRecStack(this).type_con))))
                  THEN
                  deb(DEB_PRINT, 
                    'computeRecoveryActions: marking this action deleted:');
                  rcvRecGet(this, thisAct);
                  IF (debug) THEN
                     printRcvRec(thisAct);
                  END IF;
                  rcvRecStack(this).type_con :=
                     rcvRecStack(this).type_con + deleted_con_t;
               ELSE
--
                  last := this;
               END IF;
            END LOOP;
         END IF;                -- computeRA_allRecords = FALSE#
         deb(DEB_EXIT, 'with: SUCCESS');
         RETURN SUCCESS;
      ELSE
         deb(DEB_EXIT, 'with: NO_ACTION');
         RETURN NO_ACTION;      -- a recovery that can only use redo
      END IF;
   ELSIF (computeRA_available) THEN
      deb(DEB_EXIT, 'with: AVAILABLE');
      RETURN dbms_rcvman.AVAILABLE;
   ELSIF (computeRA_restorable) THEN
      deb(DEB_EXIT, 'with: RESTORABLE');
      RETURN RESTORABLE;
   ELSE
      deb(DEB_EXIT, 'with: UNAVAILABLE');
      RETURN dbms_rcvman.UNAVAILABLE;
   END IF;
 
END computeRecoveryActions;
 
--
--
--
 
--
 
--
FUNCTION reportGetDFDel(
   file#               OUT number
  ,filetype            OUT number
  ,checkpoint_change#  OUT number
  ,checkpoint_time     OUT date
  ,resetlogs_change#   OUT number
  ,resetlogs_time      OUT date
  ,incremental_change# OUT number
  ,fuzzy_change#       OUT number
  ,recid               OUT number
  ,stamp               OUT number
  ,fname               OUT varchar2
  ,restorable          OUT number
  ,key                 OUT number
  ,completion_time     OUT date)
RETURN number IS
   device_type rc_backup_piece.device_type%TYPE;
   mytype      number;
   set_stamp   number;
   set_count   number;
   pref        number;
   bsRec       bsRec_t;
   validRec    validBackupSetRec_t;
   rcvRec      rcvRec_t;
BEGIN
   deb(DEB_ENTER, 'reportGetDFDel');
   FETCH rddf
    INTO pref, file#, mytype, checkpoint_change#, checkpoint_time,
         resetlogs_change#, resetlogs_time, incremental_change#, fuzzy_change#,
         recid, stamp, fname, set_stamp, set_count, key, completion_time,
         device_type;
   filetype := mytype;
   IF (rddf%found) THEN
      IF (mytype in (FULL_DF_BACKUP, INCREMENTAL_DF_BACKUP)) THEN
         findBackupSet(recid => recid,
                       stamp => stamp,
                       bsRec => bsRec);
--
--
         rcvRec.bsKey_con      := bsRec.key;
         rcvRec.elapseSecs_con := bsRec.elapseSecs;
         rcvRec.pieceCount_con := bsRec.pieceCount;
         restorable := validateBackupSet(
            backupSetRec           => rcvRec,
            checkDeviceIsAllocated => TRUE,
            availableMask          => dbms_rcvman.BSavailable,
            validRec               => validRec);
      ELSIF (mytype = OFFLINE_RANGE) THEN
         restorable := SUCCESS;
      ELSE
         IF (anyDevice = TRUE# OR
             isDeviceTypeAllocated(device_type) = TRUE#) THEN
            restorable := SUCCESS;
         ELSE
            restorable := dbms_rcvman.AVAILABLE;
         END IF;
      END IF;
      deb(DEB_EXIT, 'with: '||TRUE#);
      RETURN TRUE#;
   ELSE
      CLOSE rddf;
      deb(DEB_EXIT, 'with: '||FALSE#);
      RETURN FALSE#;
   END IF;
END reportGetDFDel;
 
--
--
--
 
--
FUNCTION getCloneName(
   fno    IN number
  ,crescn IN number
  ,pluscn IN number DEFAULT 0)
RETURN varchar2 IS
   fname rci_datafile.aux_name%TYPE;
BEGIN
   deb(DEB_ENTER, 'getCloneName');
   IF (this_dbinc_key is NULL) THEN
      deb(DEB_EXIT, 'with error 20020');
      raise_application_error(-20020, 'Database incarnation not set');
   END IF;
 
   SELECT aux_name
     INTO fname
     FROM rci_datafile_this_dbinc
    WHERE dbinc_key = this_dbinc_key
      AND (nvl(realf_site_key, translation_site_key) = site_key)
      AND file# = fno
      AND creation_change# = crescn
      AND plugin_change# = pluscn
      AND drop_change# IS NULL;
 
   deb(DEB_EXIT, 'with: '||fname);
   RETURN fname;
EXCEPTION
   WHEN no_data_found THEN
--
--
      deb(DEB_EXIT, 'with error 20218');
      raise_application_error(-20218,
                              'Datafile not found in recovery catalog');
   WHEN others THEN
      deb(DEB_EXIT, 'Just raising error');
      raise;
END getCloneName;
 
--
--
--
 
--
FUNCTION wasFileOffline(
   fno    IN number
  ,untilscn IN number)
RETURN number IS
   x     number;
BEGIN
   deb(DEB_ENTER, 'wasFileOffline');
  select 1
    into x
    from rc_offline_range ofr, rc_database_incarnation di
   where ofr.db_key = this_db_key
     and di.db_key = this_db_key
     and ofr.dbinc_key = di.dbinc_key
     and untilscn >= offline_change#
     and untilscn < online_change#
     and file# = fno;
 
   deb(DEB_EXIT, 'with: TRUE#');
   RETURN TRUE#;
 
EXCEPTION
   WHEN no_data_found THEN
      deb(DEB_EXIT, 'with: FALSE#');
      RETURN FALSE#;
END wasFileOffline;
 
--
--
--
--
 
FUNCTION getmaxcopyno(
   bsstamp         IN    number
  ,bscount         IN    number)
RETURN number IS
   maxcopy number;
BEGIN
   select max(copy#)
      into maxcopy
      from rc_backup_piece  bp
      where bp.set_stamp = bsstamp
      and   bp.set_count = bscount
--
--
--
--
--
--
      and   bp.db_key = this_db_key;
   return maxcopy;
END getmaxcopyno;
 
--
FUNCTION getMaxDfNumber
RETURN number IS
   maxfile# number;
BEGIN
   select max(file#) into maxfile# from df;
   return maxfile#;
END getMaxDfNumber;
 
--
PROCEDURE getdropOSFiles(
   first         IN  boolean
  ,agedFileRec   OUT NOCOPY agedFileRec_t)
IS
BEGIN
   raise_application_error(-20999, 'Not supported in recovery catalog');
END getdropOSFiles;
 
--
PROCEDURE getBackedUpFiles(
   first         IN  boolean
  ,agedFileRec   OUT NOCOPY agedFileRec_t)
IS
BEGIN
   raise_application_error(-20999, 'Not supported in recovery catalog');
END getBackedUpFiles;
 
--
FUNCTION validateStandbyConfig(
   policy  IN  varchar2
  ,alldest IN  number)
RETURN NUMBER IS
BEGIN
   raise_application_error(-20999, 'Not supported in recovery catalog');
   return dbms_rcvman.FALSE#;
END validateStandbyConfig;
 
--
PROCEDURE getSCNForAppliedPolicy(
   minscn    OUT  number
  ,rlgscn    OUT  number)
IS
BEGIN
   raise_application_error(-20999, 'Not supported in recovery catalog');
END getSCNForAppliedPolicy;
 
--
PROCEDURE getAppliedAl(
   first           IN   boolean
  ,agedFileRec     OUT  NOCOPY agedFileRec_t)
IS
BEGIN
   raise_application_error(-20999, 'Not supported in recovery catalog');
END getAppliedAl;
 
--
PROCEDURE getRequiredSCN(
   reqscn   OUT  number
  ,rlgscn   OUT  number
  ,streams  IN   number DEFAULT 0
  ,alldest  IN   number DEFAULT 0)
IS
BEGIN
   raise_application_error(-20999, 'Not supported in recovery catalog');
END getRequiredSCN;
 
--
PROCEDURE getAppliedSCN(
   appscn   OUT  number
  ,rlgscn   OUT  number
  ,alldest  IN   number)
IS
BEGIN
   raise_application_error(-20999, 'Not supported in recovery catalog');
END getAppliedSCN;
 
--
FUNCTION isBsRecCacheMatch(
   key         IN   number
  ,deviceType  IN   varchar2
  ,tag         IN   varchar2
  ,status      IN   varchar2)
RETURN NUMBER IS
  bucket      number;
  sb4_bucket  binary_integer;
BEGIN
   bucket := mod(key, CONST4GVAL);
   IF (bucket >= CONST2GVAL) THEN
      sb4_bucket := CONST2GVAL - bucket;
   ELSE
      sb4_bucket := bucket;
   END IF;
 
   IF (NOT cacheBsRecTable.bsRec.exists(sb4_bucket)) THEN
      RETURN FALSE#;
   END IF;
 
   FOR i in 1..cacheBsRecTable.bsRec(sb4_bucket).bslist.count LOOP
      IF (cacheBsRecTable.bsRec(sb4_bucket).bslist(i).bskey = key) THEN
--
         IF (cacheBsRecTable.mask = BSavailable) THEN
            IF (status != 'A') THEN
               RETURN FALSE#;
            END IF;
         ELSIF (isStatusMatch(status, cacheBsRecTable.mask) = FALSE#) THEN
            RETURN FALSE#;
         END IF;
 
--
         IF (deviceType != cacheBsRecTable.deviceType) THEN
            RETURN FALSE#;
         END IF;
 
--
         IF (nvl(tag, '  ') != nvl(cacheBsRecTable.tag, nvl(tag, '  '))) THEN
            RETURN FALSE#;
         END IF;
 
--
         cacheBsRecTable.bsRec(sb4_bucket).bslist(i).mixcopy := TRUE;
 
         RETURN TRUE#;
      END IF;
   END LOOP;
   RETURN FALSE#;
END isBsRecCacheMatch;
 
--
PROCEDURE resetReclRecid
IS
BEGIN
   raise_application_error(-20999, 'Not supported in recovery catalog');
END resetReclRecid;
 
--
PROCEDURE setReclRecid(
   rectype  IN  binary_integer
  ,recid    IN  number)
IS
BEGIN
   raise_application_error(-20999, 'Not supported in recovery catalog');
END setReclRecid;
 
--
FUNCTION IsReclRecid(
   rectype  IN  binary_integer
  ,recid    IN  number)
RETURN NUMBER IS
BEGIN
   raise_application_error(-20999, 'Not supported in recovery catalog');
END IsReclRecid;
 
--
FUNCTION getSpaceRecl(ceilAsm IN binary_integer default 0)
RETURN NUMBER IS
BEGIN
   raise_application_error(-20999, 'Not supported in recovery catalog');
END getSpaceRecl;
 
--
--
--
PROCEDURE getFlashbackInfo(
   fbUntilTime   OUT DATE
  ,minGrsp       OUT NUMBER)
IS
   clean_grsp   number;
   count_grsp   number;
BEGIN
   BEGIN
      SELECT nvl(oldest_flashback_time, MAXDATEVAL)
        INTO fbUntiltime
        FROM fb
       WHERE dbinc_key = this_dbinc_key
         AND db_unique_name = this_db_unique_name;
   EXCEPTION
      WHEN no_data_found THEN
         fbUntilTime := MAXDATEVAL;
   END;
 
   BEGIN
      SELECT min(to_scn),
             count(*),
             count(case when from_scn <= to_scn then 1 else 0 end)
        INTO minGrsp, count_grsp, clean_grsp
        FROM grsp, dbinc
       WHERE grsp.dbinc_key = dbinc.dbinc_key
         AND dbinc.db_key = this_db_key
         AND grsp.site_key = this_site_key
         AND grsp.guaranteed = 'YES'
         AND from_scn != 0;
 
--
--
      IF (clean_grsp = 1 AND count_grsp = 1) THEN
         minGrsp := MAXSCNVAL;
      END IF;
   EXCEPTION
      WHEN no_data_found THEN
         minGrsp := MAXSCNVAL;
   END;
 
   deb(DEB_PRINT, 'getFlashbackInfo: fbUntilTime=' || to_char(fbUntilTime) ||
                  ' minGrsp=' || minGrsp);
END getFlashbackInfo;
 
--
PROCEDURE openLbCursor(lbc  OUT NOCOPY lbCursor_t) IS
BEGIN
 
   IF (lbc%ISOPEN)
   THEN
     CLOSE lbc;
   END IF;
 
   OPEN lbc FOR
 
   SELECT
--
           bs.bs_key               list_order1,
           0                       list_order2,
           bs.bs_key               pkey,
           backupset_txt           backup_type,
           backupset_txt           file_type,
           decode(bs.keep_options,
                  0, 'NO',
                     'YES')        keep,
           bs.keep_until           keep_until,
           decode(bs.keep_options,
                  256,  'LOGS',
                  512,  'NOLOGS',
                  1024, 'BACKUP_LOGS',
                         null)     keep_options,
           null                    status,
           null                    fname,
           null                    tag,
           null                    media,
           bs.bs_recid             recid,
           bs.bs_stamp             stamp,
           null                    device_type,
           0                       block_size,
           bs.completion_time      completion_time,
           'NO'                    is_rdf,
           null                    compressed,
           null                    obsolete,
           null                    keep_for_dbpitr,
           null                    bytes,
           bs.bs_key               bs_key,
           bs.set_count            bs_count,
           bs.set_stamp            bs_stamp,
           decode(bs.bck_type,
                  'L', archivedlog_txt,
                       datafile_txt)
                                   bs_type,
           decode(bs.incr_level,
                  0, full_txt,
                  1, incr1_txt,
                  2, incr2_txt,
                  3, incr3_txt,
                  4, incr4_txt,
                  decode(bs.bck_type, 'I', incr_txt, full_txt))
                                   bs_incr_type,
           bs.pieces               bs_pieces,
           null                    bs_copies,
           bs.completion_time      bs_completion_time,
           null                    bs_status,
           null                    bs_bytes,
           null                    bs_compressed,
           null                    bs_tag,
           null                    bs_device_type,
           null                    bp_piece#,
           null                    bp_copy#,
           null                    bp_vb_key,
           null                    bp_ba_access,
           null                    bp_lib_key,
           null                    df_file#,
           null                    df_ts#,
           null                    df_plugin_change#,
           null                    df_foreign_dbid,
           null                    df_tablespace,
           null                    df_resetlogs_change#,
           null                    df_creation_change#,
           null                    df_checkpoint_change#,
           null                    df_ckp_mod_time,
           null                    df_incremental_change#,
           null                    rl_thread#,
           null                    rl_sequence#,
           null                    rl_resetlogs_change#,
           null                    rl_first_change#,
           null                    rl_first_time,
           null                    rl_next_change#,
           null                    rl_next_time,
           null                    rl_snapstandby,
           null                    sf_db_unique_name,
           null                    con_id
     FROM  bs
    WHERE bs.db_key     = this_db_key
 
   UNION ALL
   SELECT
--
           bp.bs_key               list_order1,
           1                       list_order2,
           bp.bp_key               pkey,
           backupset_txt           backup_type,
           piece_txt               file_type,
           null                    keep,
           null                    keep_until,
           null                    keep_options,
           decode(bp.status,
                  'A', available_txt,
                  'U', unavailable_txt,
                  'X', expired_txt,
                       other_txt)  status,
           bp.handle               fname,
           bp.tag                  tag,
           bp.media                media,
           bp.bp_recid             recid,
           bp.bp_stamp             stamp,
           bp.device_type          device_type,
           0                       block_size,
           bp.completion_time      completion_time,
           bp.is_recovery_dest_file
                                   is_rdf,
           bp.compressed           compressed,
           null                    obsolete,
           null                    keep_for_dbpitr,
           bp.bytes                bytes,
           bp.bs_key               bs_key,
           null                    bs_count,
           null                    bs_stamp,
           null                    bs_type,
           null                    bs_incr_type,
           null                    bs_pieces,
           null                    bs_copies,
           null                    bs_completion_time,
           null                    bs_status,
           null                    bs_bytes,
           null                    bs_compressed,
           null                    bs_tag,
           null                    bs_device_type,
           bp.piece#               bp_piece#,
           bp.copy#                bp_copy#,
           bp.vb_key               bp_vb_key,
           null                    bp_ba_access,
           null                    bp_lib_key,
           null                    df_file#,
           null                    df_ts#,
           null                    df_plugin_change#,
           null                    df_foreign_dbid,
           null                    df_tablespace,
           null                    df_resetlogs_change#,
           null                    df_creation_change#,
           null                    df_checkpoint_change#,
           null                    df_ckp_mod_time,
           null                    df_incremental_change#,
           null                    rl_thread#,
           null                    rl_sequence#,
           null                    rl_resetlogs_change#,
           null                    rl_first_change#,
           null                    rl_first_time,
           null                    rl_next_change#,
           null                    rl_next_time,
           null                    rl_snapstandby,
           null                    sf_db_unique_name,
           null                    con_id
     FROM bp
    WHERE bp.db_key = this_db_key
      AND bp.status != 'D'
      AND ((user_site_key = bp.site_key) OR
           (user_site_key IS NULL AND
            ((disk_backups_shared = TRUE# AND bp.device_type = 'DISK') OR
             (tape_backups_shared = TRUE# AND bp.device_type <>'DISK') OR
             (this_site_key = nvl(bp.site_key, this_site_key)))))
 
   UNION ALL
   SELECT
--
           bdf.bs_key              list_order1,
           2                       list_order2,
           bdf.bdf_key             pkey,
           backupset_txt           backup_type,
           datafile_txt            file_type,
           null                    keep,
           null                    keep_until,
           null                    keep_options,
           null                    status,
           null                    fname,
           null                    tag,
           null                    media,
           bdf.bdf_recid           recid,
           bdf.bdf_stamp           stamp,
           null                    device_type,
           bdf.block_size          block_size,
           bdf.completion_time     completion_time,
           'NO'                    is_rdf,
           null                    compressed,
           null                    obsolete,
           null                    keep_for_dbpitr,
           bdf.block_size * bdf.blocks
                                   bytes,
           bdf.bs_key              bs_key,
           null                    bs_count,
           null                    bs_stamp,
           null                    bs_type,
           decode(bdf.incr_level,
                  0, full_txt,
                  1, incr1_txt,
                  2, incr2_txt,
                  3, incr3_txt,
                  4, incr4_txt,
                  decode(greatest(bdf.create_scn, bdf.incr_scn),
                         bdf.create_scn, full_txt, incr_txt))
                                   bs_incr_type,
           null                    bs_pieces,
           null                    bs_copies,
           null                    bs_completion_time,
           null                    bs_status,
           null                    bs_bytes,
           null                    bs_compressed,
           null                    bs_tag,
           null                    bs_device_type,
           null                    bp_piece#,
           null                    bp_copy#,
           null                    bp_vb_key,
           null                    bp_ba_access,
           null                    bp_lib_key,
           bdf.file#               df_file#,
           null                    df_ts#,
           null                    df_plugin_change#,
           null                    df_foreign_dbid,
           null                    df_tablespace,
           dbinc.reset_scn         df_resetlogs_change#,
           bdf.create_scn          df_creation_change#,
           bdf.ckp_scn             df_checkpoint_change#,
           bdf.ckp_time            df_ckp_mod_time,
           bdf.incr_scn            df_incremental_change#,
           null                    rl_thread#,
           null                    rl_sequence#,
           null                    rl_resetlogs_change#,
           null                    rl_first_change#,
           null                    rl_first_time,
           null                    rl_next_change#,
           null                    rl_next_time,
           null                    rl_snapstandby,
           null                    sf_db_unique_name,
           null                    con_id
     FROM bdf, dbinc
    WHERE dbinc.db_key     = this_db_key
      AND dbinc.dbinc_key  = bdf.dbinc_key
 
   UNION ALL
   SELECT
--
           bcf.bs_key              list_order1,
           2                       list_order2,
           bcf.bcf_key             pkey,
           backupset_txt           backup_type,
           controlfile_txt         file_type,
           null                    keep,
           null                    keep_until,
           null                    keep_options,
           null                    status,
           null                    fname,
           null                    tag,
           null                    media,
           bcf.bcf_recid           recid,
           bcf.bcf_stamp           stamp,
           null                    device_type,
           bcf.block_size          block_size,
           null                    completion_time,
           'NO'                    is_rdf,
           null                    compressed,
           null                    obsolete,
           null                    keep_for_dbpitr,
           bcf.block_size * bcf.blocks
                                   bytes,
           bcf.bs_key              bs_key,
           null                    bs_count,
           null                    bs_stamp,
           null                    bs_type,
           full_txt                bs_incr_type,
           null                    bs_pieces,
           null                    bs_copies,
           null                    bs_completion_time,
           null                    bs_status,
           null                    bs_bytes,
           null                    bs_compressed,
           null                    bs_tag,
           null                    bs_device_type,
           null                    bp_piece#,
           null                    bp_copy#,
           null                    bp_vb_key,
           null                    bp_ba_access,
           null                    bp_lib_key,
           0                       df_file#,
           null                    df_ts#,
           null                    df_plugin_change#,
           null                    df_foreign_dbid,
           null                    df_tablespace,
           dbinc.reset_scn         df_resetlogs_change#,
           0                       df_creation_change#,
           bcf.ckp_scn             df_checkpoint_change#,
           bcf.ckp_time            df_ckp_mod_time,
           null                    df_incremental_change#,
           null                    rl_thread#,
           null                    rl_sequence#,
           null                    rl_resetlogs_change#,
           null                    rl_first_change#,
           null                    rl_first_time,
           null                    rl_next_change#,
           null                    rl_next_time,
           null                    rl_snapstandby,
           null                    sf_db_unique_name,
           null                    con_id
     FROM bcf, dbinc
    WHERE dbinc.db_key     = this_db_key
      AND dbinc.dbinc_key  = bcf.dbinc_key
 
   UNION ALL
   SELECT
--
           brl.bs_key              list_order1,
           2                       list_order2,
           brl.brl_key             pkey,
           backupset_txt           backup_type,
           archivedlog_txt         file_type,
           null                    keep,
           null                    keep_until,
           null                    keep_options,
           null                    status,
           null                    fname,
           null                    tag,
           null                    media,
           brl.brl_recid           recid,
           brl.brl_stamp           stamp,
           null                    device_type,
           brl.block_size          block_size,
           null                    completion_time,
           'NO'                    is_rdf,
           null                    compressed,
           null                    obsolete,
           null                    keep_for_dbpitr,
           brl.block_size * brl.blocks
                                   bytes,
           brl.bs_key              bs_key,
           null                    bs_count,
           null                    bs_stamp,
           null                    bs_type,
           null                    bs_incr_type,
           null                    bs_pieces,
           null                    bs_copies,
           null                    bs_completion_time,
           null                    bs_status,
           null                    bs_bytes,
           null                    bs_compressed,
           null                    bs_tag,
           null                    bs_device_type,
           null                    bp_piece#,
           null                    bp_copy#,
           null                    bp_vb_key,
           null                    bp_ba_access,
           null                    bp_lib_key,
           null                    df_file#,
           null                    df_ts#,
           null                    df_plugin_change#,
           null                    df_foreign_dbid,
           null                    df_tablespace,
           null                    df_resetlogs_change#,
           null                    df_creation_change#,
           null                    df_checkpoint_change#,
           null                    df_ckp_mod_time,
           null                    df_incremental_change#,
           brl.thread#             rl_thread#,
           brl.sequence#           rl_sequence#,
           dbinc.reset_scn         rl_resetlogs_change#,
           brl.low_scn             rl_first_change#,
           brl.low_time            rl_first_time,
           brl.next_scn            rl_next_change#,
           brl.next_time           rl_next_time,
           'NO'                    rl_snapstandby,
           null                    sf_db_unique_name,
           null                    con_id
     FROM brl, dbinc
    WHERE dbinc.db_key      = this_db_key
      AND dbinc.dbinc_key   = brl.dbinc_key
 
   UNION ALL
   SELECT
--
           bsf.bs_key              list_order1,
           2                       list_order2,
           bsf.bsf_key             pkey,
           backupset_txt           backup_type,
           spfile_txt              file_type,
           null                    keep,
           null                    keep_until,
           null                    keep_options,
           null                    status,
           null                    fname,
           null                    tag,
           null                    media,
           bsf.bsf_recid           recid,
           bsf.bsf_stamp           stamp,
           null                    device_type,
           0                       block_size,
           null                    completion_time,
           'NO'                    is_rdf,
           null                    compressed,
           null                    obsolete,
           null                    keep_for_dbpitr,
           bsf.bytes               bytes,
           bsf.bs_key              bs_key,
           null                    bs_count,
           null                    bs_stamp,
           null                    bs_type,
           full_txt                bs_incr_type,
           null                    bs_pieces,
           null                    bs_copies,
           null                    bs_completion_time,
           null                    bs_status,
           null                    bs_bytes,
           null                    bs_compressed,
           null                    bs_tag,
           null                    bs_device_type,
           null                    bp_piece#,
           null                    bp_copy#,
           null                    bp_vb_key,
           null                    bp_ba_access,
           null                    bp_lib_key,
           null                    df_file#,
           null                    df_ts#,
           null                    df_plugin_change#,
           null                    df_foreign_dbid,
           null                    df_tablespace,
           0                       df_resetlogs_change#,
           0                       df_creation_change#,
           0                       df_checkpoint_change#,
           bsf.modification_time   df_ckp_mod_time,
           null                    df_incremental_change#,
           null                    rl_thread#,
           null                    rl_sequence#,
           null                    rl_resetlogs_change#,
           null                    rl_first_change#,
           null                    rl_first_time,
           null                    rl_next_change#,
           null                    rl_next_time,
           null                    rl_snapstandby,
           db_unique_name          sf_db_unique_name,
           null                    con_id
     FROM bsf
    WHERE bsf.db_key     = this_db_key
 
   UNION ALL
   SELECT
--
           cdf.cdf_key             list_order1,
           -1                      list_order2,
           cdf.cdf_key             pkey,
           copy_txt                backup_type,
           datafile_txt            file_type,
           decode(cdf.keep_options,
                  0, 'NO',
                     'YES')        keep,
           cdf.keep_until          keep_until,
           decode(cdf.keep_options,
                  256,  'LOGS',
                  512,  'NOLOGS',
                  1024, 'BACKUP_LOGS',
                         NULL)     keep_options,
           decode(cdf.status,
                  'A', available_txt,
                  'U', unavailable_txt,
                  'X', expired_txt,
                       other_txt)  status,
           cdf.fname               fname,
           cdf.tag                 tag,
           null                    media,
           cdf.cdf_recid           recid,
           cdf.cdf_stamp           stamp,
           'DISK'                  device_type,
           cdf.block_size          block_size,
           cdf.completion_time     completion_time,
           cdf.is_recovery_dest_file
                                   is_rdf,
           null                    compressed,
           null                    obsolete,
           null                    keep_for_dbpitr,
           cdf.block_size * cdf.blocks
                                   bytes,
           null                    bs_key,
           null                    bs_count,
           null                    bs_stamp,
           null                    bs_type,
           null                    bs_incr_type,
           null                    bs_pieces,
           null                    bs_copies,
           null                    bs_completion_time,
           null                    bs_status,
           null                    bs_bytes,
           null                    bs_compressed,
           null                    bs_tag,
           null                    bs_device_type,
           null                    bp_piece#,
           null                    bp_copy#,
           null                    bp_vb_key,
           null                    bp_ba_access,
           null                    bp_lib_key,
           cdf.file#               df_file#,
           null                    df_ts#,
           null                    df_plugin_change#,
           null                    df_foreign_dbid,
           null                    df_tablespace,
           dbinc.reset_scn         df_resetlogs_change#,
           cdf.create_scn          df_creation_change#,
           cdf.ckp_scn             df_checkpoint_change#,
           cdf.ckp_time            df_ckp_mod_time,
           null                    df_incremental_change#,
           null                    rl_thread#,
           null                    rl_sequence#,
           null                    rl_resetlogs_change#,
           null                    rl_first_change#,
           null                    rl_first_time,
           null                    rl_next_change#,
           null                    rl_next_time,
           null                    rl_snapstandby,
           null                    sf_db_unique_name,
           null                    con_id
     FROM cdf, dbinc
    WHERE dbinc.db_key     = this_db_key
      AND dbinc.dbinc_key  = cdf.dbinc_key
      AND ((user_site_key = cdf.site_key) OR
           (user_site_key IS NULL AND
            ((disk_backups_shared = TRUE#) OR
             (this_site_key = nvl(cdf.site_key, this_site_key)))))
 
   UNION ALL
   SELECT
--
           ccf.ccf_key             list_order1,
           -1                      list_order2,
           ccf.ccf_key             pkey,
           copy_txt                backup_type,
           controlfile_txt         file_type,
           decode(ccf.keep_options,
                  0, 'NO',
                     'YES')        keep,
           ccf.keep_until          keep_until,
           decode(ccf.keep_options,
                  256,  'LOGS',
                  512,  'NOLOGS',
                  1024, 'BACKUP_LOGS',
                         NULL)     keep_options,
           decode(ccf.status,
                  'A', available_txt,
                  'U', unavailable_txt,
                  'X', expired_txt,
                       other_txt)  status,
           ccf.fname               fname,
           ccf.tag                 tag,
           null                    media,
           ccf.ccf_recid           recid,
           ccf.ccf_stamp           stamp,
           'DISK'                  device_type,
           ccf.block_size          block_size,
           ccf.completion_time     completion_time,
           ccf.is_recovery_dest_file
                                   is_rdf,
           null                    compressed,
           null                    obsolete,
           null                    keep_for_dbpitr,
           null
                                   bytes,
           null                    bs_key,
           null                    bs_count,
           null                    bs_stamp,
           null                    bs_type,
           null                    bs_incr_type,
           null                    bs_pieces,
           null                    bs_copies,
           null                    bs_completion_time,
           null                    bs_status,
           null                    bs_bytes,
           null                    bs_compressed,
           null                    bs_tag,
           null                    bs_device_type,
           null                    bp_piece#,
           null                    bp_copy#,
           null                    bp_vb_key,
           null                    bp_ba_access,
           null                    bp_lib_key,
           0                       df_file#,
           null                    df_ts#,
           null                    df_plugin_change#,
           null                    df_foreign_dbid,
           null                    df_tablespace,
           dbinc.reset_scn         df_resetlogs_change#,
           0                       df_creation_change#,
           ccf.ckp_scn             df_checkpoint_change#,
           ccf.ckp_time            df_ckp_mod_time,
           null                    df_incremental_change#,
           null                    rl_thread#,
           null                    rl_sequence#,
           null                    rl_resetlogs_change#,
           null                    rl_first_change#,
           null                    rl_first_time,
           null                    rl_next_change#,
           null                    rl_next_time,
           null                    rl_snapstandby,
           null                    sf_db_unique_name,
           null                    con_id
     FROM ccf, dbinc
    WHERE dbinc.db_key     = this_db_key
      AND dbinc.dbinc_key  = ccf.dbinc_key
      AND ((user_site_key  = ccf.site_key) OR
           (user_site_key IS NULL AND
            ((disk_backups_shared = TRUE#) OR
             (this_site_key = nvl(ccf.site_key, this_site_key)))))
 
   UNION ALL
 
   SELECT
--
           al.al_key               list_order1,
           -1                      list_order2,
           al.al_key               pkey,
           copy_txt                backup_type,
           archivedlog_txt         file_type,
           null                    keep,
           null                    keep_until,
           null                    keep_options,
           decode(al.status,
                  'A', available_txt,
                  'U', unavailable_txt,
                  'X', expired_txt,
                       other_txt)  status,
           al.fname                fname,
           null                    tag,
           null                    media,
           al.al_recid             recid,
           al.al_stamp             stamp,
           'DISK'                  device_type,
           al.block_size           block_size,
           al.completion_time      completion_time,
           al.is_recovery_dest_file
                                   is_rdf,
           al.compressed           compressed,
           null                    obsolete,
           null                    keep_for_dbpitr,
           al.block_size * al.blocks
                                   bytes,
           null                    bs_key,
           null                    bs_count,
           null                    bs_stamp,
           null                    bs_type,
           null                    bs_incr_type,
           null                    bs_pieces,
           null                    bs_copies,
           null                    bs_completion_time,
           null                    bs_status,
           null                    bs_bytes,
           null                    bs_compressed,
           null                    bs_tag,
           null                    bs_device_type,
           null                    bp_piece#,
           null                    bp_copy#,
           null                    bp_vb_key,
           null                    bp_ba_access,
           null                    bp_lib_key,
           null                    df_file#,
           null                    df_ts#,
           null                    df_plugin_change#,
           null                    df_foreign_dbid,
           null                    df_tablespace,
           null                    df_resetlogs_change#,
           null                    df_creation_change#,
           null                    df_checkpoint_change#,
           null                    df_ckp_mod_time,
           null                    df_incremental_change#,
           al.thread#              rl_thread#,
           al.sequence#            rl_sequence#,
           dbinc.reset_scn         rl_resetlogs_change#,
           al.low_scn              rl_first_change#,
           al.low_time             rl_first_time,
           al.next_scn             rl_next_change#,
           al.next_time            rl_next_time,
           'NO'                    rl_snapstandby,
           null                    sf_db_unique_name,
           null                    con_id
     FROM dbinc,
          al
          LEFT OUTER JOIN
          grsp
          ON al.next_scn   >= grsp.from_scn
         AND al.low_scn    <= (grsp.to_scn + 1)
         AND al.dbinc_key   = grsp.dbinc_key
         AND grsp.from_scn <= grsp.to_scn   -- filter clean grp
         AND grsp.from_scn != 0
         AND grsp.guaranteed = 'YES'
    WHERE dbinc.db_key      = this_db_key
      AND dbinc.dbinc_key   = al.dbinc_key
      AND al.archived       = 'Y'
      AND grsp.from_scn is null
      AND ((client_site_aware = TRUE# AND
            ((user_site_key = al.site_key) OR -- interested in specific site
             (user_site_key IS NULL AND
              ((logs_shared = TRUE#) OR
               (this_site_key = nvl(al.site_key, this_site_key)))))) OR
           (client_site_aware = FALSE#))
 
   UNION ALL
 
   SELECT
--
           xdf.xdf_key             list_order1,
           -1                      list_order2,
           xdf.xdf_key             pkey,
           proxycopy_txt           backup_type,
           datafile_txt            file_type,
           decode(xdf.keep_options,
                  0, 'NO',
                     'YES')        keep,
           xdf.keep_until          keep_until,
           decode(xdf.keep_options,
                  256,  'LOGS',
                  512,  'NOLOGS',
                  1024, 'BACKUP_LOGS',
                         NULL)     keep_options,
           decode(xdf.status,
                  'A', available_txt,
                  'U', unavailable_txt,
                  'X', expired_txt,
                       other_txt)  status,
           xdf.handle              fname,
           xdf.tag                 tag,
           xdf.media               media,
           xdf.xdf_recid           recid,
           xdf.xdf_stamp           stamp,
           xdf.device_type         device_type,
           xdf.block_size          block_size,
           xdf.completion_time     completion_time,
           'NO'                    is_rdf,
           null                    compressed,
           null                    obsolete,
           null                    keep_for_dbpitr,
           xdf.block_size * xdf.blocks
                                   bytes,
           null                    bs_key,
           null                    bs_count,
           null                    bs_stamp,
           null                    bs_type,
           null                    bs_incr_type,
           null                    bs_pieces,
           null                    bs_copies,
           null                    bs_completion_time,
           null                    bs_status,
           null                    bs_bytes,
           null                    bs_compressed,
           null                    bs_tag,
           null                    bs_device_type,
           null                    bp_piece#,
           null                    bp_copy#,
           null                    bp_vb_key,
           null                    bp_ba_access,
           null                    bp_lib_key,
           xdf.file#               df_file#,
           null                    df_ts#,
           null                    df_plugin_change#,
           null                    df_foreign_dbid,
           null                    df_tablespace,
           dbinc.reset_scn         df_resetlogs_change#,
           xdf.create_scn          df_creation_change#,
           xdf.ckp_scn             df_checkpoint_change#,
           xdf.ckp_time            df_ckp_mod_time,
           null                    df_incremental_change#,
           null                    rl_thread#,
           null                    rl_sequence#,
           null                    rl_resetlogs_change#,
           null                    rl_first_change#,
           null                    rl_first_time,
           null                    rl_next_change#,
           null                    rl_next_time,
           null                    rl_snapstandby,
           null                    sf_db_unique_name,
           null                    con_id
     FROM xdf, dbinc
    WHERE dbinc.db_key     = this_db_key
      AND dbinc.dbinc_key  = xdf.dbinc_key
      AND ((user_site_key  = xdf.site_key) OR
           (user_site_key IS NULL AND
            ((tape_backups_shared = TRUE#) OR
             (this_site_key = nvl(xdf.site_key, this_site_key)))))
 
   UNION ALL
   SELECT
--
           xcf.xcf_key             list_order1,
           -1                      list_order2,
           xcf.xcf_key             pkey,
           proxycopy_txt           backup_type,
           controlfile_txt         file_type,
           decode(xcf.keep_options,
                  0, 'NO',
                     'YES')        keep,
           xcf.keep_until          keep_until,
           decode(xcf.keep_options,
                  256,  'LOGS',
                  512,  'NOLOGS',
                  1024, 'BACKUP_LOGS',
                         NULL)     keep_options,
           decode(xcf.status,
                  'A', available_txt,
                  'U', unavailable_txt,
                  'X', expired_txt,
                       other_txt)  status,
           xcf.handle              fname,
           xcf.tag                 tag,
           xcf.media               media,
           xcf.xcf_recid           recid,
           xcf.xcf_stamp           stamp,
           xcf.device_type         device_type,
           xcf.block_size          block_size,
           xcf.completion_time     completion_time,
           'NO'                    is_rdf,
           null                    compressed,
           null                    obsolete,
           null                    keep_for_dbpitr,
           null                    bytes,
           null                    bs_key,
           null                    bs_count,
           null                    bs_stamp,
           null                    bs_type,
           null                    bs_incr_type,
           null                    bs_pieces,
           null                    bs_copies,
           null                    bs_completion_time,
           null                    bs_status,
           null                    bs_bytes,
           null                    bs_compressed,
           null                    bs_tag,
           null                    bs_device_type,
           null                    bp_piece#,
           null                    bp_copy#,
           null                    bp_vb_key,
           null                    bp_ba_access,
           null                    bp_lib_key,
           0                       df_file#,
           null                    df_ts#,
           null                    df_plugin_change#,
           null                    df_foreign_dbid,
           null                    df_tablespace,
           dbinc.reset_scn         df_resetlogs_change#,
           0                       df_creation_change#,
           xcf.ckp_scn             df_checkpoint_change#,
           xcf.ckp_time            df_ckp_mod_time,
           null                    df_incremental_change#,
           null                    rl_thread#,
           null                    rl_sequence#,
           null                    rl_resetlogs_change#,
           null                    rl_first_change#,
           null                    rl_first_time,
           null                    rl_next_change#,
           null                    rl_next_time,
           null                    rl_snapstandby,
           null                    sf_db_unique_name,
           null                    con_id
     FROM xcf, dbinc
    WHERE dbinc.db_key     = this_db_key
      AND dbinc.dbinc_key  = xcf.dbinc_key
      AND ((user_site_key  = xcf.site_key) OR
           (user_site_key IS NULL AND
            ((tape_backups_shared = TRUE#) OR
             (this_site_key = nvl(xcf.site_key, this_site_key)))))
 
   UNION ALL
   SELECT
--
           xal.xal_key             list_order1,
           -1                      list_order2,
           xal.xal_key             pkey,
           proxycopy_txt           backup_type,
           archivedlog_txt         file_type,
           decode(xal.keep_options,
                  0, 'NO',
                     'YES')        keep,
           xal.keep_until          keep_until,
           decode(xal.keep_options,
                  256,  'LOGS',
                  512,  'NOLOGS',
                  1024, 'BACKUP_LOGS',
                         NULL)     keep_options,
           decode(xal.status,
                  'A', available_txt,
                  'U', unavailable_txt,
                  'X', expired_txt,
                       other_txt)  status,
           xal.handle              fname,
           xal.tag                 tag,
           xal.media               media,
           xal.xal_recid           recid,
           xal.xal_stamp           stamp,
           xal.device_type         device_type,
           xal.block_size          block_size,
           xal.completion_time     completion_time,
           'NO'                    is_rdf,
           null                    compressed,
           null                    obsolete,
           null                    keep_for_dbpitr,
           xal.block_size * xal.blocks
                                   bytes,
           null                    bs_key,
           null                    bs_count,
           null                    bs_stamp,
           null                    bs_type,
           null                    bs_incr_type,
           null                    bs_pieces,
           null                    bs_copies,
           null                    bs_completion_time,
           null                    bs_status,
           null                    bs_bytes,
           null                    bs_compressed,
           null                    bs_tag,
           null                    bs_device_type,
           null                    bp_piece#,
           null                    bp_copy#,
           null                    bp_vb_key,
           null                    bp_ba_access,
           null                    bp_lib_key,
           0                       df_file#,
           null                    df_ts#,
           null                    df_plugin_change#,
           null                    df_foreign_dbid,
           null                    df_tablespace,
           dbinc.reset_scn         df_resetlogs_change#,
           0                       df_creation_change#,
           null                    df_checkpoint_change#,
           null                    df_ckp_mod_time,
           null                    df_incremental_change#,
           xal.thread#             rl_thread#,
           xal.sequence#           rl_sequence#,
           dbinc.reset_scn         rl_resetlogs_change#,
           xal.low_scn             rl_first_change#,
           xal.low_time            rl_first_time,
           xal.next_scn            rl_next_change#,
           xal.next_time           rl_next_time,
           'NO'                    rl_snapstandby,
           null                    sf_db_unique_name,
           null                    con_id
     FROM xal, dbinc
    WHERE dbinc.db_key      = this_db_key
      AND dbinc.dbinc_key   = xal.dbinc_key
      AND ((user_site_key   = xal.site_key) OR
           (user_site_key IS NULL AND
            ((tape_backups_shared = TRUE#) OR
             (this_site_key = nvl(xal.site_key, this_site_key)))))
 
--
--
   ORDER BY list_order1, list_order2, bp_piece#;
 
END openLbCursor;
 
--
--
FUNCTION DbUniqueNameIsStandby
    RETURN NUMBER
IS
   is_standby number;
BEGIN
   deb(DEB_ENTER, 'DbUniqueNameIsStandby');
 
   IF NOT this_dummy_instance THEN
--
--
      SELECT count(*) INTO is_standby FROM node
      WHERE node.db_key = this_db_key
        AND node.db_unique_name = this_db_unique_name
        AND node.database_role = 'STANDBY';
   END IF;
 
   IF is_standby is NULL THEN
      is_standby := 0;
   END IF;
   deb(DEB_EXIT, ' with ' || is_standby);
   return is_standby;
END DbUniqueNameIsStandby;
 
--
--
--
PROCEDURE clrSiteName
IS
BEGIN
  deb(DEB_ENTER, 'clrSiteName, user_site_key, realf_site_key set to null');
  user_site_key := NULL;
  realf_site_key := NULL;
  user_db_unique_name := NULL;
  deb(DEB_EXIT);
END clrSiteName;
 
--
FUNCTION getSiteKey(db_unique_name IN VARCHAR2)
   RETURN NUMBER
IS
   resynced     NUMBER;
   ret_site_key NUMBER;
BEGIN
--
--
   IF (this_db_key IS NULL) THEN
      raise_application_error(-20021, 'database not set');
   END IF;
 
--
   SELECT count(*) INTO resynced FROM node
      WHERE node.db_unique_name = upper(getSiteKey.db_unique_name)
        AND node.db_key = this_db_key;
 
   IF resynced = 0 THEN
      raise_application_error(-20243,
                              getSiteKey.db_unique_name ||
                              'site unknown to recovery catalog:');
   END IF;
 
   SELECT site_key into ret_site_key FROM node
      WHERE node.db_unique_name = upper(getSiteKey.db_unique_name)
        AND node.db_key = this_db_key;
 
   RETURN ret_site_key;
END getSiteKey;
 
--
FUNCTION getSiteName(site_key IN NUMBER)
   RETURN VARCHAR2
IS
   ldb_unique_name node.db_unique_name%TYPE;
BEGIN
   deb(DEB_ENTER, 'getSiteName, site_key=' || site_key);
   SELECT db_unique_name INTO ldb_unique_name FROM node
   WHERE site_key = getSiteName.site_key;
   deb(DEB_EXIT, ' with ' || ldb_unique_name);
   RETURN ldb_unique_name;
END getSiteName;
 
--
PROCEDURE setSiteName(db_unique_name IN VARCHAR2,
                      for_realfiles  IN NUMBER)
IS
BEGIN
   deb(DEB_ENTER, 'setSiteName'||db_unique_name);
   If db_unique_name IS NOT NULL THEN
      IF for_realfiles != 0 THEN
        realf_site_key := getSiteKey(db_unique_name);
      ELSE
        user_site_key := getSiteKey(db_unique_name);
        user_db_unique_name := upper(db_unique_name);
      END IF;
      deb(DEB_PRINT, 'user_site_key='|| user_site_key);
      deb(DEB_PRINT, 'realf_site_key='  || realf_site_key);
      deb(DEB_PRINT, 'user_db_unique_name='||user_db_unique_name);
   END IF;
   deb(DEB_EXIT);
END setSiteName;
 
--
--
PROCEDURE setArchiveFileScopeAttributes(logs_shared  IN NUMBER) IS
BEGIN
   deb(DEB_ENTER, 'setArchiveFileScopeAttributes');
 
   IF logs_shared > 0 THEN
      dbms_rcvman.logs_shared := TRUE#;
   ELSE
      dbms_rcvman.logs_shared := FALSE#;
   END IF;
   deb(DEB_PRINT, 'logs_shared = ' || dbms_rcvman.logs_shared);
 
   deb(DEB_EXIT);
END setArchiveFileScopeAttributes;
 
--
--
PROCEDURE setFirstFullBckScopeAttributes(baseline_cap IN NUMBER) IS
BEGIN
   deb(DEB_ENTER, 'setFirstFullBckScopeAttributes');
 
   this_baseline_cap := baseline_cap;
   this_baseline_cap_scn := NULL;
 
   deb(DEB_PRINT, 'baseline_cap = ' || this_baseline_cap);
 
   deb(DEB_EXIT);
END setFirstFullBckScopeAttributes;
 
--
--
PROCEDURE setBackupFileScopeAttributes(
                 disk_backups_shared IN NUMBER,
                 tape_backups_shared IN NUMBER) IS
   lsite_key NUMBER;
BEGIN
   deb(DEB_ENTER, 'setBackupFileScopeAttributes');
 
   IF disk_backups_shared IS NOT NULL THEN
      IF disk_backups_shared > 0 THEN
         dbms_rcvman.disk_backups_shared := TRUE#;
      ELSE
         dbms_rcvman.disk_backups_shared := FALSE#;
      END IF;
   END IF;
 
   IF tape_backups_shared IS NOT NULL THEN
      IF tape_backups_shared > 0 THEN
         dbms_rcvman.tape_backups_shared := TRUE#;
      ELSE
         dbms_rcvman.tape_backups_shared := FALSE#;
      END IF;
   END IF;
 
   deb(DEB_PRINT, 'disk_backups_shared='||dbms_rcvman.disk_backups_shared);
   deb(DEB_PRINT, 'tape_backups_shared='||dbms_rcvman.tape_backups_shared);
 
   deb(DEB_EXIT);
END setBackupFileScopeAttributes;
 
--
PROCEDURE addBackupToMKL(lbMkTab       IN OUT NOCOPY rcvRecTabII_t
                        ,rcvRec        IN rcvRec_t) IS
   nelem       number;              -- number of elements in each bucket
   key         number;              -- key to be added to table
   bucket      number;
   i           binary_integer;
   rcvRecI     rcvRecTabI_t;
BEGIN
   IF (rcvRec.type_con = backupSet_con_t) THEN
      key := rcvRec.bsKey_con;
   ELSIF (rcvRec.type_con = imageCopy_con_t OR
          rcvRec.type_con = proxyCopy_con_t) THEN
      key := rcvRec.key_con;
   ELSE
      raise_application_error(-20999, 'internal error: addBackupToMKL' ||
                              ' type=' || rcvRec.type_con);
   END IF;
 
   bucket := mod(key, CONST4GVAL);
   IF (bucket >= CONST2GVAL) THEN
      i := CONST2GVAL - bucket;
   ELSE
      i := bucket;
   END IF;
 
   IF (NOT lbMkTab.exists(i)) THEN
      lbMkTab(i) := rcvRecI;
   END IF;
 
--
   nelem := lbMkTab(i).count;
   IF (nelem > 0) THEN
      FOR j in 0 ..nelem-1 LOOP
         IF (rcvRec.type_con = lbMkTab(i)(j).type_con) THEN
--
            IF (rcvRec.type_con = backupSet_con_t  AND
                (lbMkTab(i)(j).bsKey_con = rcvRec.bsKey_con OR
                (lbMkTab(i)(j).setStamp_con = rcvRec.setStamp_con AND
                 lbMkTab(i)(j).setCount_con = rcvRec.setCount_con))) THEN
               RETURN;
            ELSIF ((rcvRec.type_con = imageCopy_con_t    AND
                    rcvRec.type_con = proxyCopy_con_t) OR
                   lbMkTab(i)(j).recid_con = rcvRec.recid_con AND
                   lbMkTab(i)(j).stamp_con = rcvRec.stamp_con AND
                   lbMkTab(i)(j).key_con   = rcvRec.key_con) THEN
               RETURN;
            END IF;
         END IF;
      END LOOP;
   END IF;
 
   lbMkTab(i)(nelem) := rcvRec;
END addBackupToMKL;
 
--
--
FUNCTION listBackupInMKL(lbMkTab       IN rcvRecTabII_t
                        ,lbRec         IN lbRec_t)
RETURN BOOLEAN IS
   nelem       number;               -- number of elements in each bucket
   key         number;               -- key in question?
   bucket      number;
   i           binary_integer;
BEGIN
   IF (lbRec.backup_type = backupset_txt) THEN
      key := lbRec.bs_key;
   ELSIF (lbRec.backup_type = copy_txt OR
          lbRec.backup_type = proxycopy_txt) THEN
      key := lbRec.pkey;
   ELSE
      raise_application_error(-20999, 'internal error: listBackupToMKL' ||
                              ' type=' || lbRec.backup_type);
   END IF;
 
   bucket := mod(key, CONST4GVAL);
   IF (bucket >= CONST2GVAL) THEN
      i := CONST2GVAL - bucket;
   ELSE
      i := bucket;
   END IF;
 
   IF (NOT lbMkTab.exists(i)) THEN
      RETURN FALSE;
   END IF;
 
   nelem := lbMkTab(i).count;
   FOR j in 0 ..nelem-1 LOOP
--
      IF (lbMkTab(i)(j).type_con = backupSet_con_t  AND
          lbRec.backup_type = backupset_txt      AND
          (lbMkTab(i)(j).bsKey_con = lbRec.bs_key OR
           (lbMkTab(i)(j).setStamp_con = lbRec.bs_stamp AND
            lbMkTab(i)(j).setCount_con = lbRec.bs_count))) THEN
         RETURN TRUE;
      ELSIF (((lbMkTab(i)(j).type_con = imageCopy_con_t    AND
               lbRec.backup_type = copy_txt) OR
              (lbMkTab(i)(j).type_con = proxyCopy_con_t    AND
               lbRec.backup_type = proxycopy_txt))  AND
              lbMkTab(i)(j).recid_con = lbRec.recid AND
              lbMkTab(i)(j).stamp_con = lbRec.stamp AND
              lbMkTab(i)(j).key_con   = lbRec.pkey) THEN
         RETURN TRUE;
      END IF;
   END LOOP;
 
   RETURN FALSE;
END listBackupInMKL;
 
--
--
--
PROCEDURE SetGetSinceLastBackedAL(ntimes  IN number DEFAULT 1,
                                  devtype IN varchar2 DEFAULT NULL,
                                  sbpscn  IN number) IS
  last_alrec sinceLastBackedAL_c%ROWTYPE;
BEGIN
  deb(DEB_ENTER, 'SetGetSinceLastBackedAl');
 
--
  lbacked_al_next_scn        := 0;
  standby_became_primary_scn := 0;
 
  IF client_site_aware = TRUE# or sbpscn IS NULL or sbpscn = 0 THEN
    deb(DEB_IN, 'SetGetSinceLastBackedAl: lbacked_al_next_scn is 0');
  ELSE
--
--
--
--
    standby_became_primary_scn := sbpscn + 1;
 
    OPEN sinceLastBackedAL_c(devtype, ntimes);
    FETCH sinceLastBackedAL_c into last_alrec;
    IF NOT sinceLastBackedAL_c%NOTFOUND  THEN
      lbacked_al_next_scn := nvl(last_alrec.next_scn,
                                 last_alrec.low_scn);
    END IF;
    CLOSE sinceLastBackedAL_c;
  END IF;
  deb(DEB_IN, 'SetGetSinceLastBackedAl: al_next_scn=' || lbacked_al_next_scn ||
              ' sbpscn=' || standby_became_primary_scn);
  deb(DEB_EXIT, 'SetGetSinceLastBackedAl');
END SetGetSinceLastBackedAL;
 
--
FUNCTION getEncryptTSCount RETURN BINARY_INTEGER IS
   encrypt_ts_count NUMBER;
BEGIN
   SELECT  count(*) into encrypt_ts_count FROM rc_tablespace
      WHERE dbinc_key=this_dbinc_key AND
            encrypt_in_backup = 'ON';
 
   RETURN encrypt_ts_count;
END getEncryptTSCount;
 
--
--
--
--
--
FUNCTION getArchivedNextSCN
RETURN NUMBER IS
   mySCN        number;
BEGIN
   deb(DEB_ENTER, 'getArchivedNextSCN');
   SELECT nvl(max(al.next_scn),0)
     INTO mySCN
     FROM al,
          (SELECT dbinc_key,
                  reset_scn,
                  PRIOR reset_scn next_reset_scn
           FROM dbinc
           START WITH dbinc_key = this_dbinc_key
           CONNECT BY PRIOR parent_dbinc_key = dbinc_key
           UNION ALL
           SELECT this_dbinc_key dbinc_key,
                  null           reset_scn,
                  null           next_reset_scn
             FROM dual) d2
    WHERE al.archived = 'Y'
      AND al.dbinc_key = d2.dbinc_key
      AND (d2.next_reset_scn IS NULL OR
           (al.low_scn >= d2.reset_scn AND
            al.low_scn < d2.next_reset_scn));
 
   SELECT greatest(nvl(max(brl.next_scn), 0), mySCN)
     INTO mySCN
     FROM brl,
          (SELECT dbinc_key,
                  reset_scn,
                  PRIOR reset_scn next_reset_scn
           FROM dbinc
           START WITH dbinc_key = this_dbinc_key
           CONNECT BY PRIOR parent_dbinc_key = dbinc_key
           UNION ALL
           SELECT this_dbinc_key dbinc_key,
                  null           reset_scn,
                  null           next_reset_scn
             FROM dual) d2
    WHERE brl.dbinc_key = d2.dbinc_key
      AND (d2.next_reset_scn IS NULL OR
           (brl.low_scn >= d2.reset_scn AND
            brl.low_scn <  d2.next_reset_scn));
 
   SELECT greatest(nvl(max(xal.next_scn), 0), mySCN)
     INTO mySCN
     FROM xal,
          (SELECT dbinc_key,
                  reset_scn,
                  PRIOR reset_scn next_reset_scn
           FROM dbinc
           START WITH dbinc_key = this_dbinc_key
           CONNECT BY PRIOR parent_dbinc_key = dbinc_key
           UNION ALL
           SELECT this_dbinc_key dbinc_key,
                  null           reset_scn,
                  null           next_reset_scn
             FROM dual) d2
    WHERE xal.dbinc_key = d2.dbinc_key
      AND (d2.next_reset_scn IS NULL OR
           (xal.low_scn  >= d2.reset_scn AND
            xal.low_scn  <  d2.next_reset_scn));
 
   deb(DEB_EXIT, 'with '||to_char(mySCN));
   RETURN mySCN;
END getArchivedNextSCN;
 
--
FUNCTION isArchivedLogMissing(fromSCN IN NUMBER, untilSCN IN NUMBER)
RETURN number IS
   thread    number;
   sequence  number;
   dbinc_key number;
BEGIN
   deb(DEB_ENTER, 'isArchivedLogMissing');
   deb(DEB_IN, 'fromSCN ='  || nvl(to_char(fromSCN), 'NULL') ||
               ' untilSCN=' || nvl(to_char(untilSCN), 'NULL'));
 
--
--
   SELECT thread#, sequence#, dbinc_key
     INTO thread, sequence, dbinc_key
     FROM (SELECT dbinc_key, thread#, sequence#, lead(sequence#, 1, sequence#+1)
             OVER (PARTITION BY thread#, dbinc_key
                       ORDER BY sequence#) nextseq
             FROM (SELECT al.thread#, al.sequence#, al.dbinc_key
                     FROM al,
                          (SELECT dbinc_key,
                                  reset_scn,
                                  PRIOR reset_scn next_reset_scn
                           FROM dbinc
                           START WITH dbinc_key = this_dbinc_key
                           CONNECT BY PRIOR parent_dbinc_key = dbinc_key
                           UNION ALL
                           SELECT this_dbinc_key dbinc_key,
                                  null           reset_scn,
                                  null           next_reset_scn
                             FROM dual) d2
                    WHERE al.dbinc_key = d2.dbinc_key
                      AND (d2.next_reset_scn IS NULL OR
                           (al.low_scn  >= d2.reset_scn AND
                            al.low_scn  <  d2.next_reset_scn))
                      AND low_scn >= fromSCN
                      AND (untilSCN IS NULL OR low_scn < untilSCN)
 
                   UNION ALL
 
                   SELECT brl.thread#, brl.sequence#, brl.dbinc_key
                     FROM brl,
                          (SELECT dbinc_key,
                                  reset_scn,
                                  PRIOR reset_scn next_reset_scn
                           FROM dbinc
                           START WITH dbinc_key = this_dbinc_key
                           CONNECT BY PRIOR parent_dbinc_key = dbinc_key
                           UNION ALL
                           SELECT this_dbinc_key dbinc_key,
                                  null           reset_scn,
                                  null           next_reset_scn
                             FROM dual) d2
                    WHERE brl.dbinc_key = d2.dbinc_key
                      AND (d2.next_reset_scn IS NULL OR
                           (brl.low_scn  >= d2.reset_scn AND
                            brl.low_scn  <  d2.next_reset_scn))
                      AND low_scn >= fromSCN
                      AND (untilSCN IS NULL OR low_scn < untilSCN)
 
                   UNION ALL
 
                   SELECT xal.thread#, xal.sequence#, xal.dbinc_key
                     FROM xal,
                          (SELECT dbinc_key,
                                  reset_scn,
                                  PRIOR reset_scn next_reset_scn
                           FROM dbinc
                           START WITH dbinc_key = this_dbinc_key
                           CONNECT BY PRIOR parent_dbinc_key = dbinc_key
                           UNION ALL
                           SELECT this_dbinc_key dbinc_key,
                                  null           reset_scn,
                                  null           next_reset_scn
                             FROM dual) d2
                    WHERE xal.dbinc_key = d2.dbinc_key
                      AND (d2.next_reset_scn IS NULL OR
                           (xal.low_scn  >= d2.reset_scn AND
                            xal.low_scn  <  d2.next_reset_scn))
                      AND low_scn >= fromSCN
                      AND (untilSCN IS NULL OR low_scn < untilSCN))
          )
   WHERE nextseq NOT IN (sequence#, sequence#+1)
     AND rownum = 1;
 
   deb(DEB_IN, 'missing sequence is (dbinc_key, thread, sequence)=('||
               to_char(dbinc_key)  || ',' ||
               to_char(thread)     || ',' ||
               to_char(sequence+1) || ')');
   deb(DEB_EXIT, 'with TRUE');
   RETURN TRUE#;
EXCEPTION
   WHEN no_data_found THEN
      deb(DEB_EXIT, 'with FALSE');
      RETURN FALSE#;
END isArchivedLogMissing;
 
--
FUNCTION getMaxRedoSCN(maxScn      OUT NUMBER,
                       maxTime     OUT DATE,
                       maxDbIncKey OUT NUMBER,
                       maxRlgScn   OUT NUMBER,
                       maxRlgTime  OUT DATE,
                       isOrs       IN  NUMBER)
RETURN boolean IS
 
highScn  number;
highTime date;
dbIncKey number;
rlgscn   number;
 
BEGIN
  deb(DEB_ENTER,'getMaxRedoSCN');
 
  SELECT next_scn, next_time, dbinc_key, reset_scn
    INTO highScn, highTime, dbIncKey, rlgscn
  FROM
    (SELECT next_scn, next_time, dbinc_key, reset_scn
       FROM (SELECT (CASE 
                 WHEN al.next_scn > d2.next_reset_scn THEN d2.next_reset_scn 
                 ELSE al.next_scn END) next_scn,
                 al.next_time, al.dbinc_key, d2.reset_scn
              FROM al,
                   (SELECT dbinc_key,
                           reset_scn,
                           PRIOR reset_scn next_reset_scn
                      FROM dbinc
                      START WITH dbinc_key = this_dbinc_key
                      CONNECT BY PRIOR parent_dbinc_key = dbinc_key
                      UNION ALL
                      SELECT this_dbinc_key dbinc_key,
                             null           reset_scn,
                             null           next_reset_scn
                        FROM dual) d2
              WHERE al.dbinc_key = d2.dbinc_key
                AND (d2.next_reset_scn IS NULL OR
                     (al.low_scn  >= d2.reset_scn AND
                      al.low_scn  <  d2.next_reset_scn))
                AND (isOrs = TRUE# OR 
                     (restoreRangeDevTyp IN ('RC$DISK', 'RC$ANY')))
                AND (localOrsSiteKey IS NULL OR localOrsSiteKey = al.site_key) 
                AND ((client_site_aware = TRUE# AND
                      ((user_site_key = al.site_key) OR
                       (user_site_key IS NULL AND
                        (logs_shared = TRUE# OR
                         this_site_key = nvl(al.site_key, this_site_key))))) OR
                     (client_site_aware = FALSE#))
 
             UNION ALL
 
             SELECT (CASE
                 WHEN brl.next_scn > d2.next_reset_scn THEN d2.next_reset_scn
                 ELSE brl.next_scn END) next_scn, 
                 brl.next_time, brl.dbinc_key, d2.reset_scn
               FROM brl, bp,
                    (SELECT dbinc_key,
                            reset_scn,
                            PRIOR reset_scn next_reset_scn
                       FROM dbinc
                       START WITH dbinc_key = this_dbinc_key
                       CONNECT BY PRIOR parent_dbinc_key = dbinc_key
                       UNION ALL
                       SELECT this_dbinc_key dbinc_key,
                              null           reset_scn,
                              null           next_reset_scn
                         FROM dual) d2
               WHERE brl.bs_key = bp.bs_key
                 AND brl.dbinc_key = d2.dbinc_key
                 AND (d2.next_reset_scn IS NULL OR
                       (brl.low_scn  >= d2.reset_scn AND
                          brl.low_scn  <  d2.next_reset_scn))
                 AND (isOrs = TRUE# OR 
                      ((restoreRangeDevTyp = 'RC$DISK' AND 
                        bp.device_type = 'DISK') OR 
                       (restoreRangeDevTyp = 'RC$SBT' AND
                        bp.device_type = 'SBT_TAPE') OR 
                       restoreRangeDevTyp = 'RC$ANY'))
                 AND (localOrsSiteKey IS NULL OR 
                      (restoreRangeDevTyp IN ('RA$DISK', 'RA$ANY') AND 
                       bp.ba_access IN ('D', 'L')) OR
                      (restoreRangeDevTyp IN ('RA$SBT', 'RA$ANY') AND 
                       (bp.ba_access IN ('T', 'R') AND 
                        localOrsSiteKey = bp.site_key)))
                 AND bp.db_key = this_db_key
                 AND bp.status != 'D'
                 AND ((user_site_key = bp.site_key) OR
                      (user_site_key IS NULL AND
                       ((disk_backups_shared = TRUE# AND 
                         bp.device_type = 'DISK') OR
                        (tape_backups_shared = TRUE# AND 
                         bp.device_type <> 'DISK') OR
                        (this_site_key = nvl(bp.site_key, this_site_key)))))
 
             UNION ALL
 
             SELECT (CASE
                 WHEN xal.next_scn > d2.next_reset_scn THEN d2.next_reset_scn
                 ELSE xal.next_scn END) next_scn, 
                 xal.next_time, xal.dbinc_key, d2.reset_scn
               FROM xal,
                    (SELECT dbinc_key,
                            reset_scn,
                            PRIOR reset_scn next_reset_scn
                       FROM dbinc
                       START WITH dbinc_key = this_dbinc_key
                       CONNECT BY PRIOR parent_dbinc_key = dbinc_key
                       UNION ALL
                       SELECT this_dbinc_key dbinc_key,
                              null           reset_scn,
                              null           next_reset_scn
                         FROM dual) d2
               WHERE xal.dbinc_key = d2.dbinc_key
                 AND (d2.next_reset_scn IS NULL OR
                       (xal.low_scn  >= d2.reset_scn AND
                          xal.low_scn  <  d2.next_reset_scn))
                 AND (isOrs = TRUE# OR 
                      (restoreRangeDevTyp IN ('RC$SBT', 'RC$ANY')))
                 AND (localOrsSiteKey IS NULL OR localOrsSiteKey = xal.site_key)
                 AND ((user_site_key  = xal.site_key) OR
                      (user_site_key IS NULL AND
                       ((tape_backups_shared = TRUE#) OR
                        (this_site_key = NVL(xal.site_key, this_site_key)))))
            ) ORDER BY next_scn DESC) 
  WHERE rownum = 1;
 
  maxScn      := highScn;
  maxTime     := highTime;
  maxDbIncKey := dbIncKey;
  maxRlgScn   := rlgscn;
  deb(DEB_IN, 'Max scn is = '||to_char(maxScn));
  deb(DEB_EXIT, 'with TRUE');
  RETURN TRUE;
EXCEPTION
  WHEN no_data_found THEN
     deb(DEB_EXIT, 'with FALSE');
     RETURN FALSE;
END getMaxRedoSCN;
 
--
FUNCTION getNextAvailableSCN(fromScn           IN   NUMBER,
                             nextAvailableSCN  OUT  NUMBER,
                             isOrs             IN   NUMBER)
RETURN boolean IS
 
lowScn number;
 
BEGIN
  deb(DEB_ENTER,'getNextAvailableSCN');
  deb(DEB_IN, 'finding next avilable scn after '
               || nvl(to_char(fromSCN), 'NULL'));
 
 
  SELECT min(low_scn) INTO lowScn
    FROM (SELECT  al.low_scn
            FROM al,
                 (SELECT dbinc_key,
                         reset_scn,
                         PRIOR reset_scn next_reset_scn
                    FROM dbinc
                    START WITH dbinc_key = this_dbinc_key
                    CONNECT BY PRIOR parent_dbinc_key = dbinc_key
                    UNION ALL
                    SELECT this_dbinc_key dbinc_key,
                           null           reset_scn,
                           null           next_reset_scn
                      FROM dual) d2
            WHERE al.dbinc_key = d2.dbinc_key
              AND (d2.next_reset_scn IS NULL OR
                   (al.low_scn  >= d2.reset_scn AND
                    al.low_scn  <  d2.next_reset_scn))
              AND al.low_scn > fromScn
              AND (isOrs = TRUE# OR 
                   (restoreRangeDevTyp IN ('RC$DISK', 'RC$ANY')))
              AND (localOrsSiteKey IS NULL OR localOrsSiteKey = al.site_key)
              AND ((client_site_aware = TRUE# AND
                    ((user_site_key = al.site_key) OR
                     (user_site_key IS NULL AND
                      (logs_shared = TRUE# OR
                       this_site_key = nvl(al.site_key, this_site_key))))) OR
                   (client_site_aware = FALSE#))
 
          UNION ALL
 
          SELECT  brl.low_scn
            FROM brl, bp,
                 (SELECT dbinc_key,
                         reset_scn,
                         PRIOR reset_scn next_reset_scn
                    FROM dbinc
                    START WITH dbinc_key = this_dbinc_key
                    CONNECT BY PRIOR parent_dbinc_key = dbinc_key
                    UNION ALL
                    SELECT this_dbinc_key dbinc_key,
                           null           reset_scn,
                           null           next_reset_scn
                      FROM dual) d2
            WHERE brl.bs_key = bp.bs_key
              AND brl.dbinc_key = d2.dbinc_key
              AND (d2.next_reset_scn IS NULL OR
                    (brl.low_scn  >= d2.reset_scn AND
                       brl.low_scn  <  d2.next_reset_scn))
              AND brl.low_scn > fromScn
              AND (isOrs = TRUE# OR 
                   ((restoreRangeDevTyp = 'RC$DISK' AND
                     bp.device_type = 'DISK') OR  
                    (restoreRangeDevTyp = 'RC$SBT' AND
                     bp.device_type = 'SBT_TAPE') OR
                    restoreRangeDevTyp = 'RC$ANY'))
              AND (localOrsSiteKey IS NULL OR 
                   (restoreRangeDevTyp IN ('RA$DISK', 'RA$ANY') AND
                    bp.ba_access IN ('D', 'L')) OR
                   (restoreRangeDevTyp IN ('RA$SBT', 'RA$ANY') AND
                    (bp.ba_access IN ('T', 'R') AND
                     localOrsSiteKey = bp.site_key)))
              AND bp.db_key = this_db_key
              AND bp.status != 'D'
              AND ((user_site_key = bp.site_key) OR
                   (user_site_key IS NULL AND
                    ((disk_backups_shared = TRUE# AND 
                      bp.device_type = 'DISK') OR
                     (tape_backups_shared = TRUE# AND 
                      bp.device_type <> 'DISK') OR
                     (this_site_key = nvl(bp.site_key, this_site_key)))))
    
          UNION ALL
 
          SELECT  xal.low_scn
            FROM xal,
                 (SELECT dbinc_key,
                         reset_scn,
                         PRIOR reset_scn next_reset_scn
                    FROM dbinc
                    START WITH dbinc_key = this_dbinc_key
                    CONNECT BY PRIOR parent_dbinc_key = dbinc_key
                    UNION ALL
                    SELECT this_dbinc_key dbinc_key,
                           null           reset_scn,
                           null           next_reset_scn
                      FROM dual) d2
            WHERE xal.dbinc_key = d2.dbinc_key
              AND (d2.next_reset_scn IS NULL OR
                    (xal.low_scn  >= d2.reset_scn AND
                       xal.low_scn  <  d2.next_reset_scn))
              AND xal.low_scn > fromScn
              AND (isOrs = TRUE# OR 
                   (restoreRangeDevTyp IN ('RC$SBT', 'RC$ANY')))
              AND (localOrsSiteKey IS NULL OR localOrsSiteKey = xal.site_key)
              AND ((user_site_key  = xal.site_key) OR
                   (user_site_key IS NULL AND
                    ((tape_backups_shared = TRUE#) OR
                     (this_site_key = NVL(xal.site_key, this_site_key))))));
 
   nextAvailableSCN := lowScn;
   deb(DEB_IN, 'next available scn is = '||to_char(nextAvailableSCN));
   deb(DEB_EXIT, 'with TRUE');
   RETURN TRUE;
EXCEPTION
   WHEN no_data_found THEN
      deb(DEB_EXIT, 'with FALSE');
      RETURN FALSE;
END getNextAvailableSCN;
 
--
FUNCTION findLogBreakPoint(logBreakPointScn       OUT NUMBER,
                           logBreakPointTime      OUT DATE,
                           logBreakPointDbIncKey  OUT NUMBER,
                           logBreakPointRlgScn    OUT NUMBER,
                           logBreakPointRlgTime   OUT DATE,
                           fromSCN                IN  NUMBER,
                           untilSCN               IN  NUMBER,
                           isOrs                  IN  NUMBER)
RETURN boolean IS
   thread    number;
   sequence  number;
   dbinc_key number;
   nxtscn    number;
   nxttime   date;
   rlgscn    number;
BEGIN
   deb(DEB_ENTER, 'findLogBreakPoint');
   deb(DEB_IN, 'fromSCN ='  || nvl(to_char(fromSCN), 'NULL') ||
               ' untilSCN=' || nvl(to_char(untilSCN), 'NULL'));
 
--
--
 
   SELECT thread#, sequence#, dbinc_key, next_scn, next_time, reset_scn
     INTO thread, sequence, dbinc_key, nxtscn, nxttime, rlgscn
     FROM (SELECT dbinc_key, thread#, sequence#, next_scn, next_time,
                   reset_scn, lead(sequence#, 1, sequence#+1)
             OVER (PARTITION BY thread#, dbinc_key
                       ORDER BY sequence#) nextseq
           FROM (
                   SELECT al.thread#, al.sequence#, al.dbinc_key,       
                   (CASE
                   WHEN al.next_scn > d2.next_reset_scn THEN d2.next_reset_scn
                     ELSE al.next_scn END) next_scn,
                     al.next_time, d2.reset_scn
                     FROM al,
                          (SELECT dbinc_key,
                                  reset_scn,
                                  PRIOR reset_scn next_reset_scn
                           FROM dbinc
                           START WITH dbinc_key = this_dbinc_key
                           CONNECT BY PRIOR parent_dbinc_key = dbinc_key
                           UNION ALL
                           SELECT this_dbinc_key dbinc_key,
                                  null           reset_scn,
                                  null           next_reset_scn
                             FROM dual) d2
                     WHERE al.dbinc_key = d2.dbinc_key
                       AND (d2.next_reset_scn IS NULL OR
                            (al.low_scn  >= d2.reset_scn AND
                             al.low_scn  <  d2.next_reset_scn))
                       AND next_scn >= fromSCN
                       AND (untilSCN IS NULL OR low_scn < untilSCN)
                       AND (isOrs = TRUE# OR (restoreRangeDevTyp IN
                           ('RC$DISK', 'RC$ANY')))
                       AND (localOrsSiteKey IS NULL OR 
                            localOrsSiteKey = al.site_key)
                       AND ((client_site_aware = TRUE# AND
                             ((user_site_key = al.site_key) OR
                              (user_site_key IS NULL AND
                               (logs_shared = TRUE# OR
                                this_site_key = 
                                nvl(al.site_key, this_site_key))))) OR
                            (client_site_aware = FALSE#))
 
                 UNION ALL
 
                   SELECT brl.thread#, brl.sequence#, brl.dbinc_key,
                   (CASE
                   WHEN brl.next_scn > d2.next_reset_scn THEN d2.next_reset_scn
                     ELSE brl.next_scn END) next_scn,
                      brl.next_time, d2.reset_scn
                     FROM brl, bp,
                          (SELECT dbinc_key,
                                  reset_scn,
                                  PRIOR reset_scn next_reset_scn
                           FROM dbinc
                           START WITH dbinc_key = this_dbinc_key
                           CONNECT BY PRIOR parent_dbinc_key = dbinc_key
                           UNION ALL
                           SELECT this_dbinc_key dbinc_key,
                                  null           reset_scn,
                                  null           next_reset_scn
                             FROM dual) d2
                     WHERE brl.bs_key = bp.bs_key
                       AND brl.dbinc_key = d2.dbinc_key
                       AND (d2.next_reset_scn IS NULL OR
                            (brl.low_scn  >= d2.reset_scn AND
                             brl.low_scn  <  d2.next_reset_scn))
--
--
--
                       AND next_scn >= fromSCN
                       AND (untilSCN IS NULL OR low_scn < untilSCN)
                       AND (isOrs = TRUE# OR 
                            ((restoreRangeDevTyp = 'RC$DISK' AND
                              bp.device_type = 'DISK') OR 
                             (restoreRangeDevTyp = 'RC$SBT' AND
                              bp.device_type = 'SBT_TAPE') OR
                             restoreRangeDevTyp = 'RC$ANY'))
                       AND (localOrsSiteKey IS NULL OR 
                            (restoreRangeDevTyp IN ('RA$DISK', 'RA$ANY') AND 
                             bp.ba_access IN ('D', 'L')) OR
                            (restoreRangeDevTyp IN ('RA$SBT', 'RA$ANY') AND 
                             (bp.ba_access IN ('T', 'R') AND 
                              localOrsSiteKey = bp.site_key)))
                       AND bp.db_key = this_db_key
                       AND bp.status != 'D'
                       AND ((user_site_key = bp.site_key) OR
                            (user_site_key IS NULL AND
                             ((disk_backups_shared = TRUE# AND 
                               bp.device_type = 'DISK') OR
                              (tape_backups_shared = TRUE# AND 
                               bp.device_type <> 'DISK') OR
                              (this_site_key = 
                               nvl(bp.site_key, this_site_key)))))
 
                UNION ALL
 
                SELECT xal.thread#, xal.sequence#, xal.dbinc_key,
                   (CASE
                   WHEN xal.next_scn > d2.next_reset_scn THEN d2.next_reset_scn
                     ELSE xal.next_scn END) next_scn,
                      xal.next_time, d2.reset_scn
                     FROM xal,
                          (SELECT dbinc_key,
                                  reset_scn,
                                  PRIOR reset_scn next_reset_scn
                           FROM dbinc
                           START WITH dbinc_key = this_dbinc_key
                           CONNECT BY PRIOR parent_dbinc_key = dbinc_key
                           UNION ALL
                           SELECT this_dbinc_key dbinc_key,
                                  null           reset_scn,
                                  null           next_reset_scn
                             FROM dual) d2
                     WHERE xal.dbinc_key = d2.dbinc_key
                       AND (d2.next_reset_scn IS NULL OR
                            (xal.low_scn  >= d2.reset_scn AND
                             xal.low_scn  <  d2.next_reset_scn))
                       AND next_scn >= fromSCN
                       AND (untilSCN IS NULL OR low_scn < untilSCN)
                       AND (isOrs = TRUE# OR (restoreRangeDevTyp IN
                           ('RC$SBT', 'RC$ANY')))
                       AND (localOrsSiteKey IS NULL OR 
                           localOrsSiteKey = xal.site_key)
                       AND ((user_site_key  = xal.site_key) OR
                            (user_site_key IS NULL AND
                             ((tape_backups_shared = TRUE#) OR
                              (this_site_key = 
                               NVL(xal.site_key, this_site_key))))))
            )
     WHERE nextseq NOT IN (sequence#, sequence#+1)
       AND rownum = 1;
 
   logBreakPointScn      := nxtscn;
   logBreakPointTime     := nxttime;
   logBreakPointDbIncKey := dbinc_key;
   logBreakPointRlgScn   := rlgscn;
   deb(DEB_IN, 'missing sequence is 
               (dbinc_key, thread, sequence, nextscn)=('||
               to_char(dbinc_key)  || ',' ||
               to_char(thread)     || ',' ||
               to_char(sequence+1) || ',' ||
               to_char(nxtscn)    || ')');
   deb(DEB_EXIT, 'with TRUE');
   RETURN TRUE;
EXCEPTION
   WHEN no_data_found THEN
      deb(DEB_EXIT, 'with FALSE');
      RETURN FALSE;
END findLogBreakPoint;
 
--
FUNCTION getDropSCN(dfNum        IN  NUMBER,
                    creScn       IN  NUMBER,
                    creTime      IN  DATE,
                    plugScn      IN  NUMBER,
                    foreignDbId  IN  NUMBER,
                    dropScn      OUT NUMBER,
                    dropTime     OUT DATE,
                    dropDbIncKey OUT NUMBER,
                    dropRlgScn   OUT NUMBER,
                    dropRlgTime  OUT DATE)
RETURN boolean IS
BEGIN
 
  deb(DEB_ENTER, 'getDropSCN');
 
  SELECT drop_scn, drop_time, dbinc_key, reset_scn, reset_time
    INTO dropScn, dropTime, dropDbIncKey, dropRlgScn, dropRlgTime
    FROM (SELECT drop_scn, drop_time, df.dbinc_key, reset_scn, reset_time
            FROM df, dbinc
           WHERE df.dbinc_key  = dbinc.dbinc_key
             AND dbinc.db_key  = this_db_key
             AND file#         = dfNum
             AND create_scn    = creScn
             AND create_time   = creTime
             AND plugin_scn    = plugScn
             AND foreign_dbid  = foreignDbId
             AND (dbinc_status = 'PARENT' OR
                  dbinc_status = 'CURRENT')
           ORDER BY reset_scn desc)
   WHERE rownum = 1;
 
  IF (dropScn IS NULL) THEN
     deb(DEB_EXIT, 'with FALSE');
     RETURN FALSE;
  ELSE
    deb(DEB_EXIT, 'with TRUE');
    RETURN TRUE;
  END IF;
EXCEPTION
    WHEN OTHERS THEN
      deb(DEB_IN, 'found exception: ' || substr(sqlerrm, 1, 512));
      deb(DEB_EXIT, 'with FALSE');
      RETURN FALSE;
END getDropSCN;
 
--
FUNCTION setLocalOrsSiteKey(db_id IN NUMBER)
RETURN boolean IS
  dbUnqName               node.db_unique_name%TYPE;
  l_db_id                 NUMBER;
BEGIN
 
  deb(DEB_ENTER, 'setLocalOrsSiteKey ' || db_id);
  l_db_id := db_id;
 
  localOrsSiteKey := NULL;
 
  IF (user_site_key IS NOT NULL) THEN
    deb(DEB_IN, 'user_site_key is set');
    deb(DEB_EXIT, 'with TRUE');
    return TRUE;
  END IF;
 
  BEGIN
    EXECUTE IMMEDIATE 'select rtrim(ltrim(value)) 
       from sys.v_$parameter where lower(name)=''db_unique_name'''
       into dbUnqName;
 
  EXCEPTION
    WHEN OTHERS THEN
      deb(DEB_EXIT, 'with FALSE');
      RETURN FALSE;
  END;
 
  deb(DEB_IN, 'ORS db_uniqune_name is ' || dbUnqName); 
 
  IF l_db_id IS NULL THEN
     SELECT db_id INTO l_db_id from db where db_key = this_db_key;
     deb(DEB_IN, 'using default db_id from setDatabase ' || l_db_id);
  END IF;
 
  BEGIN
    SELECT SITE_KEY INTO localOrsSiteKey FROM node
      WHERE UPPER(DB_UNIQUE_NAME) = 
            UPPER('$'||dbUnqName||'$'||to_char(l_db_id));
 
  EXCEPTION
    WHEN OTHERS THEN
      deb(DEB_EXIT, 'with FALSE');
      RETURN FALSE;
  END;
 
  deb(DEB_IN, 'Local Ors site key ' || to_char(localOrsSiteKey));
  deb(DEB_EXIT, 'with TRUE');
  return TRUE;
 
END setLocalOrsSiteKey;
 
--
PROCEDURE resetLocalOrsSiteKey IS
BEGIN
   deb(DEB_ENTER, 'resetLocalOrsSiteKey');
   localOrsSiteKey := NULL;
   deb(DEB_EXIT);
END resetLocalOrsSiteKey;
 
--
FUNCTION getIncarnationKey(untilSCN IN NUMBER)
RETURN number IS
   myInc number;
BEGIN
   deb(DEB_ENTER, 'getIncarnationKey');
 
   IF (untilSCN <= this_reset_scn) THEN
      SELECT dbinc.dbinc_key
        INTO myInc
        FROM (SELECT dbinc_key, reset_scn, PRIOR reset_scn next_reset_scn
                FROM dbinc
          START WITH dbinc_key = this_dbinc_key
          CONNECT BY PRIOR parent_dbinc_key = dbinc_key) dbinc
       WHERE dbinc.reset_scn < untilSCN
         AND dbinc.next_reset_scn >= untilSCN;
   ELSE
      myInc := 0;
   END IF;
 
   deb(DEB_EXIT, 'with incKey=' || to_char(myInc));
   RETURN myInc;
END getIncarnationKey;
 
 
--
FUNCTION getMaxScn
RETURN number IS
   logmaxnt  date;
BEGIN
   return getMaxScn(logmaxnt);
END;
 
FUNCTION getMaxScn(logmaxnt OUT date) return number IS
   minmaxnc  number;
   minmaxnt  date;
BEGIN
   IF (this_dbinc_key is NULL) THEN
      deb(DEB_EXIT, 'with error 20020');
      raise_application_error(-20020, 'Database incarnation not set');
   END IF;
 
   /* Bug 2377581: Find SCN from enabled threads only. */
   select min(maxnc), min(maxnt)
     into minmaxnc, minmaxnt
     from (select max(next_scn) maxnc, max(NEXT_TIME) maxnt
             from (select a.next_scn, a.next_time, a.thread# tno
                     from al a, rt t
                    where a.THREAD#            = t.THREAD#
                      and a.ARCHIVED           = 'Y'
                      and t.status             not in ('D', 'I')
                      and t.dbinc_key          = this_dbinc_key
                      and a.dbinc_key          = this_dbinc_key
                    union
                   select b.next_scn, b.next_time, b.thread# tno
                     from brl b, rt t
                    where b.THREAD#            = t.THREAD#
                      and t.status             not in ('D', 'I')
                      and t.dbinc_key          = this_dbinc_key
                      and b.dbinc_key          = this_dbinc_key)
             group by tno);
   logmaxnt := minmaxnt;
   return minmaxnc;
END getMaxScn;
 
--
FUNCTION getActualDbinc RETURN NUMBER
IS
BEGIN
   return actual_dbinc_key;
END getActualDbinc;
 
--
PROCEDURE setStdbyCtrlScn(
   ctrlSCN IN NUMBER)
IS
BEGIN
   deb(DEB_PRINT, 'Setting this_stdby_controlfile_scn' || ctrlSCN);
   this_stdby_controlfile_scn := ctrlSCN;
END setStdbyCtrlScn;
 
--
FUNCTION guidToPdbKey(guid IN VARCHAR2) RETURN NUMBER IS
   pdbKey NUMBER;
BEGIN
   IF (guid IS NULL) THEN
      RETURN NULL;
   END IF;
 
   SELECT max(pdb_key) INTO pdbKey
     FROM pdb
    WHERE pdb.guid = guidToPdbKey.guid
      AND pdb.db_key = this_db_key;
 
   RETURN pdbKey;
END guidToPdbKey;
 
--
FUNCTION pdbHasDatafile(pdbId IN NUMBER)
RETURN NUMBER IS
   datafile_count NUMBER;
BEGIN
   deb(DEB_ENTER, 'pdbHasDatafile, pdbId=' || pdbId);
 
--
   SELECT count(*) INTO datafile_count
      FROM rci_datafile_this_dbinc
     WHERE db_key = this_db_key
       AND dbinc_key = this_dbinc_key
       AND con_id = pdbHasDatafile.pdbId
       AND rownum = 1;
 
   IF (datafile_count > 0) THEN
      deb(DEB_EXIT, 'with: TRUE#');
      RETURN TRUE#;
   ELSE
      deb(DEB_EXIT, 'with: FALSE#');
      RETURN FALSE#;
   END IF;
END pdbHasDatafile;
 
--
--
--
--
--
--
--
--
--
--
--
 
--
--
--
 
--
FUNCTION dumpState(
   lineno IN number)
RETURN varchar2 IS
BEGIN
   IF    lineno =  1 THEN RETURN 'this_db_key=' || 
                                 nvl(to_char(this_db_key), 'NULL');
   ELSIF lineno =  2 THEN RETURN 'this_dbinc_key=' ||
                                 nvl(to_char(this_dbinc_key), 'NULL');
   ELSIF lineno =  3 THEN RETURN 'this_reset_scn=' ||
                                 nvl(to_char(this_reset_scn), 'NULL');
   ELSIF lineno =  4 THEN RETURN 'this_reset_time=' ||
                                 nvl(to_char(this_reset_time), 'NULL');
   ELSIF lineno =  5 THEN RETURN 'untilSCN=' ||
                                 nvl(to_char(untilSCN), 'NULL');
   ELSIF lineno =  6 THEN RETURN 'untilTime=' ||
                                 nvl(to_char(untilTime), 'NULL');
   ELSIF lineno =  7 THEN RETURN 'getRA_completedAfter=' ||
                                 nvl(to_char(getRA_completedAfter), 'NULL');
   ELSIF lineno =  8 THEN RETURN 'getRA_completedBefore=' ||
                                 nvl(to_char(getRA_completedBefore), 'NULL');
   ELSIF lineno =  9 THEN RETURN 'getRA_likePattern=' ||
                                 nvl(getRA_likePattern, 'NULL');
   ELSIF lineno = 10 THEN RETURN 'getRA_containerMask=' ||
                                 nvl(to_char(getRA_containerMask), 'NULL');
   ELSIF lineno = 11 THEN RETURN 'getRA_actionMask=' ||
                                 nvl(to_char(getRA_actionMask), 'NULL');
   ELSIF lineno = 12 THEN RETURN 'computeRA_allRecords=' ||
                                 nvl(to_char(computeRA_allRecords), 'NULL');
   ELSIF lineno = 13 THEN RETURN 'computeRA_fullBackups=' ||
                                 nvl(to_char(computeRA_fullBackups), 'NULL');
   ELSIF lineno = 14 THEN RETURN 'allIncarnations=' ||
                                 nvl(to_char(allIncarnations), 'NULL');
   ELSE RETURN NULL;
   END IF;
END dumpState;
 
--
PROCEDURE dumpPkgState(msg in varchar2 default null) IS
   line varchar2(132);
   lno number := 1;
BEGIN
   deb(DEB_ENTER, 'dumpPkgState ' || nvl(msg, ' '));
   loop
       line := dumpState(lno);
       if line is NULL then
          exit;
       else
          deb(DEB_PRINT, line);
          lno := lno + 1;
       end if;
   end loop;
   deb(DEB_EXIT);
END dumpPkgState;
 
--
PROCEDURE setDebugOn
IS
BEGIN
   if debug is null or not debug then
--
--
--
--
      dbms_output.enable(buffer_size => null);
      debug := TRUE;
   else
      deb(DEB_PRINT, 'Debug on - debug lready enabled');
   end if;
END setDebugOn;
 
--
PROCEDURE setDebugOff
IS
BEGIN
   dumpPkgState('Debug Off');
   dbms_output.disable;  -- free memory
   debug := FALSE;
END setDebugOff;
 
--
--
--
 
--
--
--
--
 
--
PROCEDURE initialize(
   rman_vsn IN number)
IS
BEGIN
   NULL;
END initialize;
 
--
PROCEDURE set_package_constants
IS
BEGIN
--
--
--
--
   NULL;
END set_package_constants;
 
--
--
--
 
--
FUNCTION stamp2date(
   stamp IN number)
RETURN date
IS
   x    number;
   dt   varchar2(19);
BEGIN
   x := stamp;
 
   dt := to_char(mod(x,60), 'FM09'); -- seconds
   x := floor(x/60);
 
   dt := to_char(mod(x,60), 'FM09') || ':' || dt; -- minutes
   x := floor(x/60);
 
   dt := to_char(mod(x,24), 'FM09') || ':' || dt; -- hours
   x := floor(x/24);
 
   dt := to_char(mod(x,31)+1, 'FM09') || ' ' || dt; -- days
   x := floor(x/31);
 
   dt := to_char(mod(x,12)+1, 'FM09') || '/' || dt; -- months
 
   dt := to_char(floor(x/12)+1988)   || '/' || dt;
 
   RETURN to_date(dt, 'YYYY/MM/DD HH24:MI:SS');
END stamp2date;
 
--
--
--
 
--
--
PROCEDURE setAllFlag(
   flag IN boolean)
IS
BEGIN
   setAllIncarnations(flag);
   IF (flag) THEN
      ignoreCreationSCN := TRUE#;
   ELSE
      ignoreCreationSCN := FALSE#;
   END IF;
END setAllFlag;
 
--
FUNCTION getUntilTime
RETURN date IS
BEGIN
   RETURN untilTime;
END getUntilTime;
 
--
FUNCTION getUntilScn
RETURN number IS
BEGIN
   RETURN untilScn;
END getUntilScn;
 
--
PROCEDURE resetUntil
IS
BEGIN
   untilSCN := NULL;
   untilTime := NULL;
   rpoint_set := FALSE;
END resetUntil;
 
--
PROCEDURE setFrom(
   restorefrom IN number DEFAULT NULL)
IS
BEGIN
   IF (restorefrom = BACKUP) THEN
      restoreSource := backupSet_con_t + proxyCopy_con_t;
   ELSIF (restorefrom = COPY) THEN
      restoreSource := imageCopy_con_t;
   ELSIF (restorefrom = NONPROXY) THEN
      restoreSource := imageCopy_con_t + backupSet_con_t;
   ELSIF (restorefrom = AVMCOPY) THEN
--
      IF (dbms_rcvcat.isAMSchema) THEN
         restoreSource := avmImageCopy_con_t;
      END IF;
--
      IF (bitand(nvl(restoreSource, 0), avmImageCopy_con_t) = 0) THEN
         raise_application_error(-20514,
            'feature requires Availability Machine recovery catalog');
      END IF;
   ELSIF (restorefrom is NULL) THEN
      restoreSource := NULL;
   ELSE
      raise_application_error(-20200, 'Invalid restore source');
   END IF;
 
END setFrom;
 
--
PROCEDURE setSparseness(
   sparseness IN number DEFAULT NULL)
IS
BEGIN
   deb(DEB_ENTER, 'setSparseness');
   deb(DEB_IN, 'restoreSparse='|| restoreSparse);
   IF (sparseness = SPARSE) THEN
      restoreSparse := BACKUP_SPARSENESS_SPARSE;
   ELSIF (sparseness = NONSPARSE) THEN
      restoreSparse := BACKUP_SPARSENESS_NONSPARSE;
   ELSE
      restoreSparse := BACKUP_SPARSENESS_UNSPECIFIED;
   END IF;
   deb(DEB_IN, 'restoreSparse='|| restoreSparse);
   deb(DEB_EXIT);
END setSparseness;
 
--
PROCEDURE setDeviceType(
   type IN varchar2)
IS
BEGIN
   IF (deviceCount >= 8) THEN
      raise_application_error(-20280, 'Too many device types');
   END IF;
   deviceCount := deviceCount + 1;
   deviceList(deviceCount) := type;
   IF (type = 'DISK') THEN
      diskDevice := TRUE;
   END IF;
END setDeviceType;
 
--
PROCEDURE setStandby(
   stby IN boolean)
IS
BEGIN
   if stby is NULL then
      onlyStandby := NULL;
   elsif stby then
      onlyStandby := TRUE#;
   else
      onlyStandby := FALSE#;
   end if;
END setStandby;
 
--
PROCEDURE setDeviceTypeAny
IS
BEGIN
   diskDevice  := TRUE;
   anyDevice   := TRUE#;
   deviceCount := 0;
END setDeviceTypeAny;
 
--
PROCEDURE resetDeviceType
IS
BEGIN
   FOR i in 1..8 LOOP
      deviceList(i) := NULL;
   END LOOP;
   deviceCount := 0;
   diskDevice  := FALSE;
   anyDevice   := FALSE#;
END resetDeviceType;
 
--
PROCEDURE setTag(
   tag IN varchar2 DEFAULT NULL)
IS
BEGIN
   restoreTag := tag;
END setTag;
 
--
PROCEDURE setRecoveryDestFile(onlyrdf IN BOOLEAN)
IS
BEGIN
  if onlyrdf then
     recoveryDestFile := TRUE;
  else
     recoveryDestFile := FALSE;
  end if;
END setRecoveryDestFile;
 
--
PROCEDURE setOrsFile(localOnly IN BOOLEAN, libKey IN NUMBER)
IS
BEGIN
  orsLocalFile := localOnly;
  orsLibKey    := libKey;
  orsAnyFile   := (NOT localOnly AND libKey IS NULL);
END setOrsFile;
 
--
--
--
 
--
FUNCTION getValidBackupSet(
   validBackupSetRec            OUT NOCOPY validBackupSetRec_t
  ,checkDeviceIsAllocated       IN  number DEFAULT FALSE#)
RETURN number IS
   lastCode     number;
   checkRc      number;
   local        validBackupSetRec_t;
BEGIN
   IF (bsRecCacheEnabled) THEN
      RETURN cacheGetValidBackupSet(
                          validBackupSetRec      => validBackupSetRec,
                          checkDeviceIsAllocated => checkDeviceIsAllocated);
   END IF;
 
   deb(DEB_ENTER, 'getValidBackupSet');
 
--
   IF (getValidBackupSetCursor = 'findValidBackupSet1P_c') THEN
      IF (NOT findValidBackupSet1P_c%ISOPEN) THEN
         RETURN FALSE#;
      END IF;
   ELSIF (getValidBackupSetCursor = 'findValidBackupSet_c') THEN
      IF (NOT findValidBackupSet_c%ISOPEN) THEN
         RETURN FALSE#;
      END IF;
   ELSE
      raise_application_error(-20204, 'Translation not started');
   END IF;
 
<<nextRow>>
   IF (getValidBackupSetCursor = 'findValidBackupSet1P_c') THEN
      FETCH findValidBackupSet1P_c
         INTO local;
 
      IF (findValidBackupSet1P_c%NOTFOUND) THEN
         CLOSE findValidBackupSet1P_c;
         deb(DEB_EXIT, 'with: FALSE#');
         RETURN FALSE#;
      END IF;
   ELSIF (getValidBackupSetCursor = 'findValidBackupSet_c') THEN
      FETCH findValidBackupSet_c
         INTO local;
 
      IF (findValidBackupSet_c%NOTFOUND) THEN
         CLOSE findValidBackupSet_c;
         deb(DEB_EXIT, 'with: FALSE#');
         RETURN FALSE#;
      END IF;
   END IF;
 
   lastCode := getValidBackupSetLast.code;      -- save for test below
   getValidBackupSetLast := local;              -- save for next time here
 
   IF (local.code <= lastCode) THEN
--
--
--
--
--
--
--
 
--
--
--
--
 
--
--
--
--
--
 
--
--
--
--
 
      IF (checkDeviceIsAllocated = TRUE#) THEN
         IF (anyDevice = FALSE# AND
             isDeviceTypeAllocated(local.deviceType) = FALSE#) THEN
            deb(DEB_IN, 'device type not allocated: ' ||
                local.deviceType);
            GOTO nextRow;
         END IF;
      END IF;
      validBackupSetRec := local;               -- set OUT mode arg
      deb(DEB_IN, 'returning valid rec deviceType=' ||
          local.deviceType || ' tag=' || local.tag || ' copyNumber=' ||
          to_char(local.copyNumber));
      deb(DEB_EXIT, 'with: TRUE#');
      RETURN TRUE#;
   ELSE
      deb(DEB_IN, ' local.code=' || to_char(local.code) ||
          ' lastCode=' || to_char(lastCode));
      GOTO nextRow;
   END IF;
   deb(DEB_EXIT);
END getValidBackupSet;
 
--
--
--
 
--
FUNCTION getRcvRec(
   funCode      IN number
  ,rcvRec       OUT NOCOPY rcvRec_t
  ,callAgain    OUT number)
RETURN number IS
   rc           number;
BEGIN
   deb(DEB_ENTER, 'getRcvRec');
   rc := 0;                                     -- init for procedures
   callAgain := TRUE#;
 
   deb(DEB_IN, ' funCode=' || to_char(funCode));
 
   IF (funCode = getCfCopy) THEN
      getControlfileCopy(rcvRec);
   ELSIF (funCode = getDfCopy) THEN
      getDatafileCopy(rcvRec);
   ELSIF (funCode = getAnyProxy) THEN
      getProxyCopy(rcvRec);
   ELSIF (funCode = getCfBackup) THEN
      rc := getControlfileBackup(rcvRec);
      IF (rc != SUCCESS OR NOT findControlfileBackupCursor) THEN
         callAgain := FALSE#;
      END IF;
   ELSIF (funCode = getSfBackup) THEN
      rc := getSpfileBackup(rcvRec => rcvRec);
      IF (rc != SUCCESS OR NOT findSpfileBackupCursor) THEN
         callAgain := FALSE#;
      END IF;
   ELSIF (funCode = listCfCopy) THEN
      listGetControlfileCopy(rcvRec);
   ELSIF (funCode = listDfCopy) THEN
      listGetDatafileCopy(rcvRec);
   ELSIF (funCode = listCfBackup) THEN
      listGetControlfileBackup(rcvRec);
   ELSIF (funCode = listSfBackup) THEN
      listGetSpfileBackup(rcvRec);
   ELSIF (funCode = listDfBackup) THEN
      listGetDatafileBackup(rcvRec);
   ELSIF (funCode = listAlBackup) THEN
      listGetArchivedLogBackup(rcvRec);
   ELSIF (funCode = listDfProxy) THEN
      listGetProxyDatafile(rcvRec);
   ELSIF (funCode = listAlProxy) THEN
      listGetProxyArchivedLog(rcvRec);
   ELSIF (funCode = getRecovAction) THEN
      callAgain := getRecoveryAction(rcvRec);
   ELSIF (funCode = getAlBackup) THEN
      rc := getArchivedLogBackup(rcvRec);
      IF (rc != SUCCESS) THEN
         callAgain := FALSE#;
      END IF;
   ELSIF (funCode = getRangeAlBackup) THEN
      rc := getRangeArchivedLogBackup(rcvRec);
      IF (rc = UNAVAILABLE) THEN
         callAgain := FALSE#;
      END IF;
   ELSIF (funCode = listAlCopy) THEN
      listGetArchivedLogCopy(rcvRec);
   ELSIF (funCode = listBSet) THEN
      listGetBackupsetFiles(rcvRec);
   ELSIF (funCode = getAllBSet) THEN
      getAllBackupSet(rcvRec);
   ELSE
      deb(DEB_EXIT, 'with error 20999');
      raise_application_error(-20999, 'getRcvRec: unknown funCode: ' ||
                              to_char(funCode));
   END IF;
 
   IF (debug) THEN
      printRcvRec(rcvRec);
      deb(DEB_EXIT, 'with rc:'||TO_CHAR(rc));
   END IF;
 
--
--
--
 
   RETURN rc;
 
EXCEPTION
   WHEN no_data_found THEN
      deb(DEB_EXIT, 'with no more records');
      RAISE no_data_found;
END getRcvRec;
 
--
--
--
 
--
PROCEDURE translateDatabase(
   sinceUntilSCN IN number DEFAULT NULL)
IS
   fromSCN      number;
   toSCN        number;
BEGIN
   deb(DEB_ENTER, 'translateDatabase');
   validateState(getDatafileCursor);
 
   IF (untilSCN is NULL) THEN
--
      fromSCN := MAXSCNVAL;
      toSCN   := MAXSCNVAL;
   ELSE                                 -- an until clause is in effect
      fromSCN := untilSCN;
      IF (sinceUntilSCN = TRUE#) THEN
--
--
--
         toSCN := MAXSCNVAL;
      ELSE
--
--
--
         toSCN := fromSCN;
      END IF;
   END IF;
 
   IF (pdbIdList.count = 0) THEN
      deb(DEB_OPEN, 'translateDatabase_c');
      OPEN translateDatabase_c(fromSCN, toSCN);
      getDatafileCursor := 'translateDatabase';
      getDatafileNoRows.error := NULL;             -- error not possible
   ELSIF (pdbIdList.count = 1) THEN
      deb(DEB_OPEN, 'translateDatabaseOfPdbId_c');
      OPEN translateDatabaseOfPdbId_c
              (fromSCN, toSCN, pdbIdList.first + CONST2GVAL);
      getDatafileCursor := 'translateDatabaseOfPdbId';
   ELSE
      deb(DEB_OPEN, 'translateDatabaseOfPdbIdL_c');
      OPEN translateDatabaseOfPdbIdL_c(fromSCN, toSCN);
      getDatafileCursor := 'translateDatabaseOfPdbIdL';
   END IF;
 
   IF (untilSCN IS NOT NULL AND pdbIdList.count != 0) THEN
      getDatafileNoRows.error := -20513;
      getDatafileNoRows.msg   :=
         'UNTIL TIME or SCN is before plugggable database CREATION SCN';
   END IF;
   getDatafileLast.dfNumber := NULL;            -- no last row yet
   skipTablespaceList.delete;
   setDBTransClause;
   deb(DEB_EXIT);
END translateDatabase;
 
--
 
--
PROCEDURE skipTableSpace(
   tsName  IN varchar2
  ,pdbId   IN number DEFAULT 0)
IS
  tsRec tablespace_t;
BEGIN
   tsRec.name    := tsName;
   tsRec.pdbId   := pdbId;
   skipTablespaceList(skipTablespaceList.count + 1) := tsRec;
 
EXCEPTION
   WHEN VALUE_ERROR THEN
--
--
--
--
     IF (instr(tsName, ':') <> 0) THEN
       deb(DEB_PRINT, 'skipTableSpace: pdb name could be prepended to ts');
       raise_application_error(-20044, 'Invalid tablespace name');
     END IF;
 
     deb(DEB_EXIT, 'skipTableSpace: exit due to exception');
     RAISE;
 
END skipTableSpace;
 
--
PROCEDURE translateTablespace(
   ts_name  IN varchar2
  ,pdb_id   IN number DEFAULT 0)
IS
BEGIN
   deb(DEB_ENTER, 'translateTablespace');
   validateState(getDatafileCursor);
 
   deb(DEB_OPEN, 'translateTablespace_c');
   OPEN translateTablespace_c(tsName => ts_name, pdbId => pdb_id);
 
   getDatafileCursor       := 'translateTablespace';
   getDatafileNoRows.error := -20202;
   getDatafileNoRows.msg   := 'Tablespace does not exist';
   getDatafileLast.dfNumber := NULL;            -- no last row yet
   skipTablespaceList.delete;
   deb(DEB_EXIT);
END translateTablespace;
 
--
PROCEDURE translateDataFile(
   fname IN varchar2)
IS
BEGIN
   deb(DEB_ENTER, 'translateDataFile_1');
   validateState(getDatafileCursor);
 
   deb(DEB_OPEN, 'translateDatafileName');
   OPEN translateDatafileName(fileName => fname);
 
   IF (untilSCN is NULL and untilTime is NULL) THEN
      getDatafileNoRows.error := -20201;
      getDatafileNoRows.msg   := 'Datafile does not exist';
   ELSE
      getDatafileNoRows.error := -20222;
      getDatafileNoRows.msg   :=
         'Datafile name does not exist or is ambiguous';
   END IF;
 
   getDatafileCursor   := 'translateDatafileName';
   getDatafileLast.dfNumber := NULL;            -- no last row yet
   skipTablespaceList.delete;
   deb(DEB_EXIT);
END translateDatafile;
 
--
PROCEDURE translateDataFile(
   fno IN number)
IS
BEGIN
   deb(DEB_ENTER, 'translateDataFile_2');
   validateState(getDatafileCursor);
 
   deb(DEB_OPEN, 'translateDatafileNumber');
   OPEN translateDatafileNumber(fno => fno);
 
   getDatafileCursor       := 'translateDatafileNumber';
   getDatafileNoRows.error :=  -20201;
   getDatafileNoRows.msg   := 'Datafile does not exist';
   getDatafileLast.dfNumber := NULL;            -- no last row yet
   skipTablespaceList.delete;
   setDfTransClause(fno => fno);
   deb(DEB_EXIT);
END translateDatafile;
 
--
PROCEDURE translateDataFile(
   fno    IN number
  ,ckpscn IN number)
IS
BEGIN
   deb(DEB_ENTER, 'translateDataFile_3');
   validateState(getDatafileCursor);
 
   deb(DEB_OPEN, 'translateDatafileCheckpoint');
   OPEN translateDatafileCheckpoint(fno    => fno,
                                    ckpSCN => ckpscn);
 
   getDatafileCursor       := 'translateDatafileCheckpoint';
   getDatafileNoRows.error :=  -20201;
   getDatafileNoRows.msg   := 'Datafile does not exist';
   getDatafileLast.dfNumber := NULL;            -- no last row yet
   skipTablespaceList.delete;
   setDfTransClause(fno => fno);
   deb(DEB_EXIT);
END translateDatafile;
 
--
PROCEDURE translateAllDatafile
IS
BEGIN
   deb(DEB_ENTER, 'translateAllDataFile');
   validateState(getDatafileCursor);
 
   IF (pdbIdList.count = 0) THEN
      deb(DEB_OPEN, 'translateAllDf_c');
      OPEN translateAllDf_c;
      getDatafileCursor := 'translateAllDf';
   ELSIF (pdbIdList.count = 1) THEN
      deb(DEB_OPEN, 'translateAllDfOfPdbId_c');
      OPEN translateAllDfOfPdbId_c(pdbIdList.first + CONST2GVAL);
      getDatafileCursor := 'translateAllDfOfPdbId';
   ELSE
      deb(DEB_OPEN, 'translateAllDfOfPdbIdL_c');
      OPEN translateAllDfOfPdbIdL_c;
      getDatafileCursor := 'translateAllDfOfPdbIdList';
   END IF;
 
   getDatafileNoRows.error := NULL;             -- error not possible
   getDatafileLast.dfNumber := NULL;            -- no last row yet
   skipTablespaceList.delete;
   setDBTransClause;
   deb(DEB_EXIT);
END;
 
--
PROCEDURE translateCorruptList
IS
BEGIN
   validateState(getDatafileCursor);
 
   OPEN translateCorruptList_c;
 
   getDatafileCursor       := 'translateCorruptList';
   getDatafileNoRows.error :=  -20504;
   getDatafileNoRows.msg   := 'Corruption List does not exist';
   getDatafileLast.dfNumber := NULL;            -- no last row yet
   skipTablespaceList.delete;
END translateCorruptList;
 
--
 
--
PROCEDURE getDatafile(
   dfRec     OUT NOCOPY dfRec_t
  ,oldClient IN  boolean DEFAULT FALSE)
IS
   getDatafileRowcount  number;
   local                dfRec_t;
BEGIN
   deb(DEB_ENTER, 'getDataFile_1');
<<nextRow>>
   IF (getDatafileCursor = 'translateDatabase') THEN
      FETCH translateDatabase_c
       INTO local;
 
      IF (translateDatabase_c%NOTFOUND) THEN
--
         getDatafileRowcount := translateDatabase_c%ROWCOUNT;
         CLOSE translateDatabase_c;
      END IF;
   ELSIF (getDatafileCursor = 'translateDatabaseOfPdbId') THEN
      FETCH translateDatabaseOfPdbId_c
       INTO local;
 
      IF (translateDatabaseOfPdbId_c%NOTFOUND) THEN
--
         getDatafileRowcount := translateDatabaseOfPdbId_c%ROWCOUNT;
         CLOSE translateDatabaseOfPdbId_c;
      END IF;
   ELSIF (getDatafileCursor = 'translateDatabaseOfPdbIdL') THEN
      FETCH translateDatabaseOfPdbIdL_c
       INTO local;
 
      IF (translateDatabaseOfPdbIdL_c%NOTFOUND) THEN
--
         getDatafileRowcount := translateDatabaseOfPdbIdL_c%ROWCOUNT;
         CLOSE translateDatabaseOfPdbIdL_c;
      END IF;
   ELSIF (getDatafileCursor = 'translateAllDf') THEN
      FETCH translateAllDf_c
       INTO local;
 
      IF (translateAllDf_c%NOTFOUND) THEN
--
         getDatafileRowcount := translateAllDf_c%ROWCOUNT;
         CLOSE translateAllDf_c;
      END IF;
   ELSIF (getDatafileCursor = 'translateAllDfOfPdbId') THEN
      FETCH translateAllDfOfPdbId_c
       INTO local;
 
      IF (translateAllDfOfPdbId_c%NOTFOUND) THEN
--
         getDatafileRowcount := translateAllDfOfPdbId_c%ROWCOUNT;
         CLOSE translateAllDfOfPdbId_c;
      END IF;
   ELSIF (getDatafileCursor = 'translateAllDfOfPdbIdList') THEN
      FETCH translateAllDfOfPdbIdL_c
       INTO local;
 
      IF (translateAllDfOfPdbIdL_c%NOTFOUND) THEN
--
         getDatafileRowcount := translateAllDfOfPdbIdL_c%ROWCOUNT;
         CLOSE translateAllDfOfPdbIdL_c;
      END IF;
   ELSIF (getDatafileCursor = 'translateTablespace') THEN
      FETCH translateTablespace_c
       INTO local;
 
      IF (translateTablespace_c%NOTFOUND) THEN
--
         getDatafileRowcount := translateTablespace_c%ROWCOUNT;
         CLOSE translateTablespace_c;
      END IF;
   ELSIF (getDatafileCursor = 'translateDatafileName') THEN
      FETCH translateDatafileName
       INTO local;
 
      IF (translateDatafileName%NOTFOUND) THEN
--
         getDatafileRowcount := translateDatafileName%ROWCOUNT;
         CLOSE translateDatafileName;
      END IF;
 
      IF (oldClient) THEN
--
         IF (translateDatafileName%ISOPEN) THEN
            CLOSE translateDatafileName;
         END IF;
         getDatafileCursor := NULL;
      END IF;
   ELSIF (getDatafileCursor = 'translateDatafileNumber') THEN
      FETCH translateDatafileNumber
       INTO local;
 
      IF (translateDatafileNumber%NOTFOUND) THEN
--
         getDatafileRowcount := translateDatafileNumber%ROWCOUNT;
         CLOSE translateDatafileNumber;
      END IF;
 
      IF (oldClient) THEN
--
         IF (translateDatafileNumber%ISOPEN) THEN
            CLOSE translateDatafileNumber;
         END IF;
         getDatafileCursor := NULL;
      END IF;
   ELSIF (getDatafileCursor = 'translateDatafileCheckpoint') THEN
      FETCH translateDatafileCheckpoint
       INTO local;
 
      IF (translateDatafileCheckpoint%NOTFOUND) THEN
--
         getDatafileRowcount := translateDatafileCheckpoint%ROWCOUNT;
         CLOSE translateDatafileCheckpoint;
      END IF;
 
      IF (oldClient) THEN
--
         IF (translateDatafileCheckpoint%ISOPEN) THEN
            CLOSE translateDatafileCheckpoint;
         END IF;
         getDatafileCursor := NULL;
      END IF;
   ELSIF (getDatafileCursor = 'translateCorruptList') THEN
      FETCH translateCorruptList_c
       INTO local;
 
      IF (translateCorruptList_c%NOTFOUND) THEN
--
         getDatafileRowcount := translateCorruptList_c%ROWCOUNT;
         CLOSE translateCorruptList_c;
      END IF;
   ELSE
      deb(DEB_EXIT, 'with error 20204');
      raise_application_error(-20204, 'Translation not started');
   END IF;
 
   IF (getDatafileRowcount IS NOT NULL) THEN    -- if %NOTFOUND
      getDatafileCursor := NULL;                -- we closed it above
      IF (getDatafileRowcount = 0 AND
          getDatafileNoRows.error IS NOT NULL) THEN
--
         deb(DEB_EXIT, 'with norows error');
         raise_application_error(getDatafileNoRows.error,
                                 getDatafileNoRows.msg);
      ELSE
         deb(DEB_EXIT, 'with no more records');
         RAISE no_data_found;                   -- signal end-of-fetch
      END IF;
   END IF;
 
   IF (skipTablespace(local.tsName, local.pdbId)) THEN
      GOTO nextRow;
   END IF;
 
--
   IF (getDatafileLast.dfNumber = local.dfNumber) THEN
      IF (getDatafileLast.pluginSCN != 0) THEN
         IF (getDatafileLast.pluginSCN = local.pluginSCN) THEN
            deb(DEB_PRINT, 'not returning' || local.fileName);
            GOTO nextRow;
         END IF;
      ELSIF (getDatafileLast.dfCreationSCN = local.dfCreationSCN) THEN
         deb(DEB_PRINT, 'not returning' || local.fileName);
         GOTO nextRow;
      END IF;
   END IF;
 
--
--
--
   IF (local.pdbName IS NULL) THEN
      local.pdbName := translatePdb2Name(local.pdbId);
   END IF;
 
   getDatafileLast := local;
 
   setDfTransClause(fno => local.dfNumber);
 
   dfRec := local;                              -- set OUT mode arg
   deb(DEB_EXIT);
END getDatafile;
 
--
--
--
 
--
PROCEDURE translateOnlineLogs(srls IN number DEFAULT 0)
IS
BEGIN
   deb(DEB_ENTER, 'translateOnlineLogs');
   IF (translateOnlineLogs_c%ISOPEN) THEN
      validateState('translateOnlineLogs_c');                -- raise the error
   END IF;
 
   deb(DEB_OPEN, 'translateOnlineLogs_c, srls='||srls);
   OPEN translateOnlineLogs_c(srls);
   deb(DEB_EXIT);
 
END translateOnlineLogs;
 
--
PROCEDURE getOnlineLog(
   fname        OUT varchar2
  ,thread#      OUT number
  ,group#       OUT number)
IS
BEGIN
   deb(DEB_ENTER, 'getOnlineLog');
   FETCH translateOnlineLogs_c
    INTO thread#, group#, fname;
   IF (translateOnlineLogs_c%NOTFOUND) THEN
      CLOSE translateOnlineLogs_c;
      deb(DEB_EXIT, 'with NULL (no archivelog found)'||fname);
      fname := NULL;                            -- indicate end-of-fetch
      RETURN;
   END IF;
   deb(DEB_EXIT, 'with archivelog:'||fname);
END getOnlineLog;
 
 
--
--
--
 
--
PROCEDURE getArchivedLog(
   alRec       OUT NOCOPY alRec_t,
   closeCursor IN  boolean DEFAULT FALSE)
IS
   getArchivedLogRowcount       number;
   local                        alRec_t;
BEGIN
   deb(DEB_ENTER, 'getArchivedLog');
 
<<nextRow>>
 
   IF (getArchivedLogCursor = 'translateArcLogKey') THEN
      FETCH translateArcLogKey
       INTO local;
      IF (translateArcLogKey%NOTFOUND) THEN
         getArchivedLogRowcount := translateArcLogKey%ROWCOUNT;
         CLOSE translateArcLogKey;
      END IF;
      IF (closeCursor AND translateArcLogKey%ISOPEN) THEN
         CLOSE translateArcLogKey;
      END IF;
   ELSIF (getArchivedLogCursor = 'translateArcLogName') THEN
      FETCH translateArcLogName
       INTO local;
      IF (translateArcLogName%NOTFOUND) THEN
         getArchivedLogRowcount := translateArcLogName%ROWCOUNT;
         CLOSE translateArcLogName;
      END IF;
      IF (closeCursor AND translateArcLogName%ISOPEN) THEN
         CLOSE translateArcLogName;
      END IF;
   ELSIF (getArchivedLogCursor = 'translateArcLogSeqRange') THEN
      FETCH translateArcLogSeqRange
       INTO local;
      IF (translateArcLogSeqRange%NOTFOUND) THEN
         getArchivedLogRowcount := translateArcLogSeqRange%ROWCOUNT;
         CLOSE translateArcLogSeqRange;
      END IF;
      IF (closeCursor AND translateArcLogSeqRange%ISOPEN) THEN
         CLOSE translateArcLogSeqRange;
      END IF;
   ELSIF (getArchivedLogCursor = 'translateFrgnArcLogSeqRange') THEN
--
      raise_application_error(-20999, 'Not supported in recovery catalog');
--
   ELSIF (getArchivedLogCursor = 'translateArcLogSeqRange2') THEN
      FETCH translateArcLogSeqRange2
       INTO local;
      IF (translateArcLogSeqRange2%NOTFOUND) THEN
         getArchivedLogRowcount := translateArcLogSeqRange2%ROWCOUNT;
         CLOSE translateArcLogSeqRange2;
      END IF;
      IF (closeCursor AND translateArcLogSeqRange2%ISOPEN) THEN
         CLOSE translateArcLogSeqRange2;
      END IF;
   ELSIF (getArchivedLogCursor = 'translateArcLogTimeRange') THEN
      FETCH translateArcLogTimeRange
       INTO local;
      IF (translateArcLogTimeRange%NOTFOUND) THEN
         getArchivedLogRowcount := translateArcLogTimeRange%ROWCOUNT;
         CLOSE translateArcLogTimeRange;
      END IF;
      IF (closeCursor AND translateArcLogTimeRange%ISOPEN) THEN
         CLOSE translateArcLogTimeRange;
      END IF;
   ELSIF (getArchivedLogCursor = 'translateFrgnArcLogTimeRange') THEN
--
      raise_application_error(-20999, 'Not supported in recovery catalog');
--
   ELSIF (getArchivedLogCursor = 'translateArcLogTimeRange2') THEN
      FETCH translateArcLogTimeRange2
       INTO local;
      IF (translateArcLogTimeRange2%NOTFOUND) THEN
         getArchivedLogRowcount := translateArcLogTimeRange2%ROWCOUNT;
         CLOSE translateArcLogTimeRange2;
      END IF;
      IF (closeCursor AND translateArcLogTimeRange2%ISOPEN) THEN
         CLOSE translateArcLogTimeRange2;
      END IF;
   ELSIF (getArchivedLogCursor = 'translateArcLogSCNRange') THEN
      FETCH translateArcLogSCNRange
       INTO local;
      IF (translateArcLogSCNRange%NOTFOUND) THEN
         getArchivedLogRowcount := translateArcLogSCNRange%ROWCOUNT;
         CLOSE translateArcLogSCNRange;
      END IF;
      IF (closeCursor AND translateArcLogSCNRange%ISOPEN) THEN
         CLOSE translateArcLogSCNRange;
      END IF;
   ELSIF (getArchivedLogCursor = 'translateFrgnArcLogSCNRange') THEN
--
      raise_application_error(-20999, 'Not supported in recovery catalog');
--
   ELSIF (getArchivedLogCursor = 'translateArcLogSCNRange2') THEN
      FETCH translateArcLogSCNRange2
       INTO local;
      IF (translateArcLogSCNRange2%NOTFOUND) THEN
         getArchivedLogRowcount := translateArcLogSCNRange2%ROWCOUNT;
         CLOSE translateArcLogSCNRange2;
      END IF;
      IF (closeCursor AND translateArcLogSCNRange2%ISOPEN) THEN
         CLOSE translateArcLogSCNRange2;
      END IF;
   ELSIF (getArchivedLogCursor = 'translateArcLogPattern') THEN
      FETCH translateArcLogPattern
       INTO local;
      IF (translateArcLogPattern%NOTFOUND) THEN
         getArchivedLogRowcount := translateArcLogPattern%ROWCOUNT;
         CLOSE translateArcLogPattern;
      END IF;
      IF (closeCursor AND translateArcLogPattern%ISOPEN) THEN
         CLOSE translateArcLogPattern;
      END IF;
   ELSIF (getArchivedLogCursor = 'translateFrgnArcLogPattern') THEN
--
      raise_application_error(-20999, 'Not supported in recovery catalog');
--
   ELSE
      deb(DEB_EXIT, 'with error 20204');
      raise_application_error(-20204, 'Translation not started');
   END IF;
 
   IF (closeCursor) THEN
      getArchivedLogCursor := NULL;
   END IF;
 
   IF (getArchivedLogRowcount IS NOT NULL) THEN
      getArchivedLogCursor := NULL;             -- we closed it above
      getArchivedLogDoingRecovery := FALSE#;    -- clear for next time
      getArchivedLogOnlyrdf := 0;               -- clear for next time
      currInc := -1;
      deb(DEB_PRINT, 'getArchivedLogDoingRecovery cleared');
--
--
      IF ((getArchivedLogRowcount = 0 OR
           getArchivedLogLast.thread is NULL) AND
          getArchivedLogNoRows.error IS NOT NULL) THEN
--
         getArchivedLogLast   := NULL;          -- clear for next time
         deb(DEB_EXIT, 'with norows error');
         raise_application_error(getArchivedLogNoRows.error,
                                 getArchivedLogNoRows.msg);
      ELSE
         deb(DEB_EXIT, 'with no more records');
         getArchivedLogLast   := NULL;          -- clear for next time
         RAISE no_data_found;                   -- signal end-of-fetch
      END IF;
   END IF;
 
   deb(DEB_PRINT, 'getArchivedLog - resetscn='||local.rlgSCN||
                  ' thread='||local.thread||
                  ' seq='||local.sequence||
                  ' lowscn='||local.lowSCN||
                  ' nextscn='||local.nextSCN||
                  ' terminal='||local.terminal||
                  ' site_key_order_col='||local.site_key_order_col||
                  ' isrdf='||local.isrdf||
                  ' stamp='||local.stamp);
 
--
   IF (getArchivedLogDoingRecovery = TRUE#) THEN
--
     IF (getArchivedLogLast.rlgSCN = local.rlgSCN AND
         getArchivedLogLast.rlgTime = local.rlgTime AND currInc <> -1) THEN
       deb(DEB_PRINT,
               'getArchivedLog - currInc =' || currInc);
--
       IF (currInc > 0 AND
           local.lowSCN >= inc_list(currInc-1).resetlogs_change#-1) THEN
           deb(DEB_PRINT,
               'getArchivedLog - Skip log - belongs to orphan branch');
           GOTO nextRow;
       END IF;
     ELSE
--
       currInc := -1;
       FOR inc_idx in 0..max_inc_idx-1 LOOP
 
--
--
         IF tc_fromSCN > inc_list(inc_idx).resetlogs_change# AND
            local.rlgSCN < inc_list(inc_idx).resetlogs_change#  THEN
            deb(DEB_PRINT,
                'getArchivedLog -Skip log precedes recovery SCN - '||inc_idx);
            EXIT;
         END IF;
 
--
--
--
--
         IF (local.rlgSCN = inc_list(inc_idx).resetlogs_change# AND
             local.rlgTime = inc_list(inc_idx).resetlogs_time) THEN
 
--
--
            IF inc_idx > 0 THEN
              IF local.lowSCN < inc_list(inc_idx-1).resetlogs_change# - 1 THEN
                  currInc := inc_idx;
                  deb(DEB_PRINT, 'getArchivedLog - currInc2 set to '||currInc);
               END IF;
            ELSE
               currInc := inc_idx;
               deb(DEB_PRINT, 'getArchivedLog - currIn3 set to '||currInc);
            END IF;
            EXIT;
         END IF;
       END LOOP;
       IF (currInc = -1) THEN
         deb(DEB_PRINT,'getArchivedLog - Skip log - not required by recovery');
         GOTO nextRow;
       END IF;
     END IF;
   END IF;
 
--
   IF (local.thread   = getArchivedLogLast.thread AND
       local.sequence = getArchivedLogLast.sequence AND
       local.terminal = getArchivedLogLast.terminal AND
       local.lowSCN   = getArchivedLogLast.lowSCN AND
       local.rlgSCN   = getArchivedLogLast.rlgSCN AND
       local.rlgTime  = getArchivedLogLast.rlgTime) THEN
     local.duplicate := TRUE#;
   END IF;
 
   IF (getArchivedLogDuplicates = FALSE# AND    -- if don't want duplicates
       local.duplicate = TRUE#) THEN
      deb(DEB_PRINT, 'getArchivedLog - dont want duplicates');
      GOTO nextRow;
   END IF;
 
--
--
--
--
--
--
--
--
--
--
--
   IF (getArchivedLogOnlyrdf = 1 AND
       local.duplicate = FALSE# AND
       local.isrdf = 'NO') THEN
      deb(DEB_PRINT, 'getArchiveLog - dont want non-recovery area log ');
      GOTO nextRow;
   END IF;
 
--
--
--
   IF IsDuplicateAlName(local.duplicate, local.filename) THEN
     GOTO nextRow;
   END IF;
 
--
--
   IF (local.thread   = getArchivedLogLast.thread AND
       local.sequence = getArchivedLogLast.sequence AND
       local.lowSCN   = getArchivedLogLast.lowSCN AND
       local.rlgSCN   = getArchivedLogLast.rlgSCN AND
       local.rlgTime  = getArchivedLogLast.rlgTime AND
       getArchivedLogLast.terminal = 'YES' AND
       local.terminal = 'NO') THEN
     deb(DEB_PRINT, 'getArchivedLog - Skip log - not an EOR log');
     GOTO nextRow;
   END IF;
--
 
--
   IF (getArchivedLogDoingRecovery = TRUE#) THEN
     IF (local.thread = getArchivedLogLast.thread AND
         local.lowSCN <> getArchivedLogLast.lowSCN AND
         local.sequence = getArchivedLogLast.sequence) THEN
        deb(DEB_PRINT, 'getArchivedLog - Skip log - filter bad sequence log');
        GOTO nextRow;
     END IF;
   END IF;
 
--
--
   IF (local.stamp <= 0) THEN
      local.stamp := NULL;
   END IF;
 
   IF getArchivedLogCursor IS NULL THEN
      getArchivedLogLast := NULL;               -- clear for next time
      getArchivedLogDoingRecovery := FALSE#;    -- clear for next time
      getArchivedLogOnlyrdf := 0;
      currInc := -1;
      deb(DEB_PRINT, 'getArchivedLogDoingRecovery cleared');
      deb(DEB_PRINT, 'getArchivedLogLast := NULL');
   ELSE
      getArchivedLogLast := local;
      deb(DEB_PRINT,'getArchivedLogLast('||getArchivedLogCursor||') := local');
      deb(DEB_PRINT, 'getArchivedLogLast := local');
   END IF;
   alRec := local;                              -- set OUT mode arg
   deb(DEB_EXIT);
END getArchivedLog;
 
--
PROCEDURE translateArchivedLogKey(
   alKey        IN number
  ,needstby     IN number DEFAULT NULL)
IS
BEGIN
   deb(DEB_ENTER, 'translateArchivedLogKey');
   validateState(getArchivedLogCursor);
 
   deb(DEB_OPEN, 'translateArcLogKey');
   OPEN translateArcLogKey(alKey => alKey);
 
   getArchivedLogCursor       := 'translateArcLogKey';
   getArchivedLogDuplicates   := NULL;
   getArchivedLogNoRows.error := -20240;
   getArchivedLogNoRows.msg   := 'Archived log does not exist';
   deb(DEB_EXIT);
END translateArchivedLogKey;
 
--
PROCEDURE translateArchivedLogKey(
   al_key       IN  number
  ,available    IN  number DEFAULT 1     -- ignored (for compatability)
  ,unavailable  IN  number DEFAULT 1     -- ignored (for compatability)
  ,deleted      IN  number DEFAULT 1     -- ignored (for compatability)
  ,online       IN  number DEFAULT 1     -- ignored (for compatability)
  ,recid        OUT number
  ,stamp        OUT number
  ,thread#      OUT number
  ,sequence#    OUT number
  ,low_scn      OUT number
  ,reset_scn    OUT number
  ,block_size   OUT number
  ,fname        OUT varchar2
  ,needstby     IN number DEFAULT NULL)
IS
   alRec        alRec_t;
BEGIN
   deb(DEB_ENTER, 'translateArchivedLogKey816');
   translateArchivedLogKey(alKey => al_key, needstby => needstby);
 
   getArchivedLog(alRec       => alRec,
                  closeCursor => TRUE);
 
   recid        := alRec.recid;
   stamp        := alRec.stamp;
   thread#      := alRec.thread;
   sequence#    := alRec.sequence;
   low_scn      := alRec.lowSCN;
   reset_scn    := alRec.rlgSCN;
   block_size   := alRec.blockSize;
   fname        := alRec.fileName;
   deb(DEB_EXIT);
END translateArchivedLogKey;
 
--
--
--
--
 
--
PROCEDURE translateArchivedLogName(
   fname        IN varchar2
  ,available    IN number         DEFAULT NULL   -- for compatability
  ,unavailable  IN number         DEFAULT NULL   -- for compatability
  ,deleted      IN number         DEFAULT NULL   -- for compatability
  ,online       IN number                        -- ignored
  ,duplicates   IN number
  ,statusMask   IN binary_integer DEFAULT NULL   -- for compatability
  ,needstby     IN number         DEFAULT NULL)
IS
BEGIN
   deb(DEB_ENTER, 'translateArchivedLogName');
   validateState(getArchivedLogCursor);
 
   deb(DEB_OPEN, 'translateArcLogName');
   OPEN translateArcLogName(fname       => fname,
                            online      => online,
                            statusMask  => NVL(statusMask,
                                   computeAvailableMask(available, unavailable,
                                                        deleted, 0)),
                            needstby    => needstby);
 
   getARchivedLogCursor       := 'translateArcLogName';
   getArchivedLogDuplicates   := duplicates;
   getArchivedLogNoRows.error := -20240;
   getArchivedLogNoRows.msg   := 'Archived log does not exist';
   deb(DEB_EXIT);
END translateArchivedLogName;
 
--
--
--
--
--
--
--
--
--
--
--
--
--
 
--
PROCEDURE translateArchivedLogSeqRange(
   thread#      IN number
  ,fromseq#     IN number
  ,toseq#       IN number
  ,pattern      IN varchar2
  ,available    IN number         DEFAULT NULL   -- for compatability
  ,unavailable  IN number         DEFAULT NULL   -- for compatability
  ,deleted      IN number         DEFAULT NULL   -- for compatability
  ,online       IN number                        -- ignored
  ,duplicates   IN number
  ,statusMask   IN binary_integer DEFAULT NULL   -- for compatability
  ,needstby     IN number         DEFAULT NULL   -- for compatability
  ,foreignal    IN binary_integer DEFAULT 0      -- for compatability
  ,incarn       IN number         DEFAULT NULL)  -- for compatibility
IS
   mask    number := NVL(statusMask,
                     computeAvailableMask(available, unavailable, deleted, 0));
   lincarn number := incarn;
BEGIN
   deb(DEB_ENTER, 'translateArchivedLogSeqRange');
   validateState(getArchivedLogCursor);
 
   IF (thread# is NULL) THEN
      deb(DEB_EXIT, 'with error 20210');
      raise_application_error(-20210, 'Thread# is missing');
   END IF;
 
   setAlTransClause(thread     => thread#,
                    fromSeq    => fromseq#,
                    toSeq      => toseq#,
                    pattern    => pattern);
 
--
--
--
--
 
   IF (foreignal != 0) THEN
      IF (tc_dbid.count = 0) THEN
         tc_anydbid := TRUE#;
      END IF;
      deb(DEB_OPEN, 'translateFrgnArcLogSeqRange');
--
      raise_application_error(-20999, 'Not supported in recovery catalog');
--
   ELSE
      IF (bitand(mask,BSdeleted) != 0 AND pattern IS NULL) THEN
--
--
--
--
         deb(DEB_OPEN, 'translateArcLogSeqRange2');
         OPEN translateArcLogSeqRange2(thread#     => thread#,
                                       incarn      => NVL(lincarn,-1),
                                       fromseq#    => fromseq#,
                                       toseq#      => toseq#,
                                       statusMask  => mask,
                                       online      => online,
                                       needstby    => needstby);
         getArchivedLogCursor       := 'translateArcLogSeqRange2';
      ELSE
         deb(DEB_OPEN, 'translateArcLogSeqRange');
         OPEN translateArcLogSeqRange(thread#     => thread#,
                                      incarn      => NVL(lincarn,-1),
                                      fromseq#    => fromseq#,
                                      toseq#      => toseq#,
                                      pattern     => pattern,
                                      statusMask  => mask,
                                      online      => online,
                                      needstby    => needstby);
         getArchivedLogCursor       := 'translateArcLogSeqRange';
      END IF;
      getArchivedLogNoRows.error := -20242;
      getArchivedLogNoRows.msg   := 'No archived logs in the range specified';
   END IF;
   getArchivedLogDuplicates   := duplicates;
   deb(DEB_EXIT);
END translateArchivedLogSeqRange;
 
--
--
--
--
--
--
--
--
PROCEDURE translateArchivedLogTimeRange(
   thread#      IN number
  ,fromTime     IN date
  ,toTime       IN date
  ,pattern      IN varchar2
  ,available    IN number         DEFAULT NULL    -- for compatability
  ,unavailable  IN number         DEFAULT NULL    -- for compatability
  ,deleted      IN number         DEFAULT NULL    -- for compatability
  ,online       IN number                         -- ignored
  ,duplicates   IN number
  ,statusMask   IN binary_integer DEFAULT NULL    -- for compatability
  ,needstby     IN number         DEFAULT NULL    -- for compatability
  ,foreignal    IN binary_integer DEFAULT 0       -- for compatability
  ,incarn       IN number         DEFAULT NULL)   -- for compatibility
IS
   mask    number := NVL(statusMask,
                     computeAvailableMask(available, unavailable, deleted, 0));
   lincarn number := incarn;
BEGIN
   deb(DEB_ENTER, 'translateArchivedLogTimeRange');
   validateState(getArchivedLogCursor);
 
   setAlTransClause(thread   => thread#,
                    fromTime => fromTime,
                    toTime   => toTime,
                    pattern  => pattern);
 
--
--
--
--
 
   IF (foreignal != 0) THEN
      IF (tc_dbid.count = 0) THEN
         tc_anydbid := TRUE#;
      END IF;
      deb(DEB_OPEN, 'translateFrgnArcLogTimeRange');
--
      raise_application_error(-20999, 'Not supported in recovery catalog');
--
   ELSE
      IF (bitand(mask,BSdeleted) != 0 AND pattern IS NULL) THEN
--
--
--
--
         deb(DEB_OPEN, 'translateArcLogTimeRange2');
         OPEN translateArcLogTimeRange2(thread#     => thread#,
                                        incarn      => NVL(lincarn,0),
                                        fromTime    => fromTime,
                                        toTime      => toTime,
                                        statusMask  => mask,
                                        online      => online,
                                        needstby    => needstby);
         getArchivedLogCursor       := 'translateArcLogTimeRange2';
      ELSE
         deb(DEB_OPEN, 'translateArcLogTimeRange');
         OPEN translateArcLogTimeRange(thread#     => thread#,
                                       incarn      => NVL(lincarn,0),
                                       fromTime    => fromTime,
                                       toTime      => toTime,
                                       pattern     => pattern,
                                       statusMask  => mask,
                                       online      => online,
                                       needstby    => needstby);
         getArchivedLogCursor       := 'translateArcLogTimeRange';
      END IF;
      getArchivedLogNoRows.error := -20242;
      getArchivedLogNoRows.msg   := 'No archived logs in the range specified';
   END IF;
   getArchivedLogDuplicates   := duplicates;
   deb(DEB_EXIT);
END translateArchivedLogTimeRange;
 
--
--
--
--
--
--
--
 
--
PROCEDURE translateArchivedLogSCNRange(
   thread#      IN number
  ,fromSCN      IN number
  ,toSCN        IN number
  ,pattern      IN varchar2
  ,available    IN number         DEFAULT NULL    -- for compatability
  ,unavailable  IN number         DEFAULT NULL    -- for compatability
  ,deleted      IN number         DEFAULT NULL    -- for compatability
  ,online       IN number
  ,duplicates   IN number
  ,statusMask   IN binary_integer DEFAULT NULL    -- for compatability
  ,needstby     IN number         DEFAULT NULL
  ,doingRecovery IN  number DEFAULT FALSE#
  ,onlyrdf      IN binary_integer DEFAULT 0
  ,reset_scn    IN number         DEFAULT NULL    -- for compatibility
  ,reset_time   IN date           DEFAULT NULL    -- for compatibility
  ,sequence#    IN number         DEFAULT NULL    -- for compatibility
  ,foreignal    IN binary_integer DEFAULT 0       -- for compatability
  ,incarn       IN number         DEFAULT NULL)   -- for compatibility
IS
   adjusted_toSCN number;
   mask           number := NVL(statusMask,
                     computeAvailableMask(available, unavailable, deleted, 0));
   lincarn        number := incarn;
BEGIN
   deb(DEB_ENTER, 'translateArchivedLogSCNRange');
   validateState(getArchivedLogCursor);
 
   IF (untilTime IS NULL) THEN
--
--
--
--
      adjusted_toSCN := least(nvl(toSCN, untilSCN), nvl(untilSCN, toSCN));
   ELSE
--
--
--
--
--
--
      adjusted_toSCN := toSCN;
   END IF;
 
--
--
--
--
--
   IF (adjusted_toSCN <= fromSCN) THEN
      adjusted_toSCN := fromSCN+1;
   END IF;
 
   setAlTransClause(thread  => thread#,
                    fromSCN => fromSCN,
                    toSCN   => adjusted_toSCN,
                    pattern => pattern);
 
--
--
--
--
 
  IF (foreignal != 0) THEN
      IF (tc_dbid.count = 0) THEN
         tc_anydbid := TRUE#;
      END IF;
      deb(DEB_OPEN, 'translateFrgnArcLogSCNRange');
--
      raise_application_error(-20999, 'Not supported in recovery catalog');
--
   ELSE
      IF (bitand(mask,BSdeleted) != 0 AND pattern IS NULL) THEN
--
--
--
--
         deb(DEB_OPEN, 'translateArcLogSCNRange2');
         OPEN translateArcLogSCNRange2(thread#     => thread#,
                                       incarn      => NVL(lincarn,0),
                                       sequence#   => sequence#,
                                       fromSCN     => fromSCN,
                                       toSCN       => adjusted_toSCN,
                                       toTime      => untilTime,
                                       statusMask  => mask,
                                       online      => online,
                                       needstby    => needstby,
                                       reset_scn   => reset_scn,
                                       reset_time  => reset_time);
         getArchivedLogCursor       := 'translateArcLogSCNRange2';
         deb(DEB_IN, ' using cursor 2 fromSCN=' ||
             to_char(fromSCN) || ' toSCN=' || to_char(adjusted_toSCN));
      ELSE
         deb(DEB_OPEN, 'translateArcLogSCNRange');
         OPEN translateArcLogSCNRange(thread#     => thread#,
                                      incarn      => NVL(lincarn,0),
                                      sequence#   => sequence#,
                                      fromSCN     => fromSCN,
                                      toSCN       => adjusted_toSCN,
                                      pattern     => pattern,
                                      statusMask  => mask,
                                      online      => online,
                                      needstby    => needstby,
                                      reset_scn   => reset_scn,
                                      reset_time  => reset_time);
         getArchivedLogCursor       := 'translateArcLogSCNRange';
      END IF;
      getArchivedLogNoRows.error := -20242;
      getArchivedLogNoRows.msg   := 'No archived logs in the range specified';
   END IF;
   getArchivedLogDuplicates   := duplicates;
   getArchivedLogDoingRecovery := DoingRecovery;
   IF (DoingRecovery = TRUE#) THEN
     deb(DEB_PRINT, 'getArchivedLogDoingRecovery set to TRUE');
   END IF;
   getArchivedLogOnlyrdf := onlyrdf;
   deb(DEB_EXIT);
END translateArchivedLogSCNRange;
 
--
--
 
--
PROCEDURE translateArchivedLogPattern(
   pattern      IN varchar2
  ,available    IN number         DEFAULT NULL    -- for compatability
  ,unavailable  IN number         DEFAULT NULL    -- for compatability
  ,deleted      IN number         DEFAULT NULL    -- for compatability
  ,online       IN number
  ,duplicates   IN number
  ,statusMask   IN binary_integer DEFAULT NULL    -- for compatability
  ,needstby     IN number         DEFAULT NULL    -- for compatability
  ,foreignal    IN binary_integer DEFAULT 0)      -- for compatability
IS
   mask           number := NVL(statusMask,
                     computeAvailableMask(available, unavailable, deleted, 0));
BEGIN
   deb(DEB_ENTER, 'translateArchivedLogPattern');
   IF (bitand(mask,BSdeleted) != 0 AND pattern IS NULL) THEN
--
--
--
--
--
     translateArchivedLogSCNRange(
        thread#     => NULL,
        fromscn     => 0,
        toscn       => highscnval+1,
        pattern     => NULL,
        statusMask  => mask,
        online      => online,
        duplicates  => duplicates,
        foreignal   => foreignal);
   ELSE
     validateState(getArchivedLogCursor);
     setAlTransClause(pattern => pattern);
     IF (foreignal != 0) THEN
        IF (tc_dbid.count = 0) THEN
           tc_anydbid := TRUE#;
        END IF;
        deb(DEB_OPEN, 'translateFrgnArcLogPattern');
--
        raise_application_error(-20999, 'Not supported in recovery catalog');
--
     ELSE
        deb(DEB_OPEN, 'translateArcLogPattern');
        OPEN translateArcLogPattern(pattern     => pattern,
                                    statusMask  => mask,
                                    online      => online);
        getArchivedLogCursor       := 'translateArcLogPattern';
        getArchivedLogNoRows.error := -20242;
        getArchivedLogNoRows.msg   :=
           'No archived logs in the range specified';
     END IF;
     getArchivedLogDuplicates   := duplicates;
   END IF;
   deb(DEB_EXIT);
END translateArchivedLogPattern;
 
--
PROCEDURE translateArchivedLogCancel
IS
BEGIN
   deb(DEB_ENTER, 'translateArchivedLogCancel');
   IF (getArchivedLogCursor = 'translateArcLogKey') THEN
      CLOSE translateArcLogKey;
   ELSIF (getArchivedLogCursor = 'translateArcLogName') THEN
      CLOSE translateArcLogName;
   ELSIF (getArchivedLogCursor = 'translateArcLogSeqRange') THEN
      CLOSE translateArcLogSeqRange;
   ELSIF (getArchivedLogCursor = 'translateFrgnArcLogSeqRange') THEN
--
      raise_application_error(-20999, 'Not supported in recovery catalog');
--
   ELSIF (getArchivedLogCursor = 'translateArcLogSeqRange2') THEN
      CLOSE translateArcLogSeqRange2;
   ELSIF (getArchivedLogCursor = 'translateArcLogTimeRange') THEN
      CLOSE translateArcLogTimeRange;
   ELSIF (getArchivedLogCursor = 'translateFrgnArcLogTimeRange') THEN
--
      raise_application_error(-20999, 'Not supported in recovery catalog');
--
   ELSIF (getArchivedLogCursor = 'translateArcLogTimeRange2') THEN
      CLOSE translateArcLogTimeRange2;
   ELSIF (getArchivedLogCursor = 'translateArcLogSCNRange') THEN
      CLOSE translateArcLogSCNRange;
   ELSIF (getArchivedLogCursor = 'translateFrgnArcLogSCNRange') THEN
--
      raise_application_error(-20999, 'Not supported in recovery catalog');
--
   ELSIF (getArchivedLogCursor = 'translateArcLogSCNRange2') THEN
      CLOSE translateArcLogSCNRange2;
   ELSIF (getArchivedLogCursor = 'translateArcLogPattern') THEN
      CLOSE translateArcLogPattern;
   ELSIF (getArchivedLogCursor = 'translateFrgnArcLogPattern') THEN
--
      raise_application_error(-20999, 'Not supported in recovery catalog');
--
   END IF;
   getArchivedLogCursor := NULL;                -- we closed it above
   getArchivedLogLast   := NULL;                -- clear for next time
   getArchivedLogDoingRecovery := FALSE#;       -- clear for next time
   resetAlTransClause;
   deb(DEB_EXIT);
END translateArchivedLogCancel;
 
--
--
--
 
--
PROCEDURE getArchivedLog(
   recid        OUT number
  ,stamp        OUT number
  ,thread#      OUT number
  ,sequence#    OUT number
  ,low_scn      OUT number
  ,nxt_scn      OUT number
  ,fname        OUT varchar2
  ,reset_scn    OUT number
  ,block_size   OUT number
  ,blocks       OUT number)
IS
   alRec alRec_t;
BEGIN
   deb(DEB_ENTER, 'getArchivedLog');
<<retry>>
   getArchivedLog(alRec);
 
--
--
--
 
--
   recid      := nvl(alRec.recid,0);    -- no null indicator before 8.1.6
   stamp      := nvl(alRec.stamp, 0);   -- no null indicator before 8.1.6
   thread#    := alRec.thread;
   sequence#  := alRec.sequence;
   low_scn    := alRec.lowSCN;
   nxt_scn    := alRec.nextSCN;
   fname      := nvl(alRec.fileName, 'null');   -- no null indicator
   reset_scn  := alRec.rlgSCN;
   block_size := alRec.blockSize;
   blocks     := alRec.blocks;
   deb(DEB_EXIT);
 
EXCEPTION
   WHEN no_data_found THEN
      recid := NULL;                    -- indicate end-of-fetch
      stamp := NULL;
      deb(DEB_EXIT, 'with no more records');
END getArchivedLog;
 
--
--
--
 
--
 
--
PROCEDURE translateControlFileCopyName(
   fname        IN varchar2
  ,available    IN number           DEFAULT NULL  -- for compatability
  ,unavailable  IN number           DEFAULT NULL  -- for compatability
  ,duplicates   IN number
  ,statusMask   IN binary_integer   DEFAULT NULL  -- for compatability
  ,onlyone      IN number           DEFAULT 1) IS
BEGIN
   deb(DEB_ENTER, 'translateControlFileCopyName');
--
   getControlFileCopyCursor := 'findControlfileBackup_c';
   deb(DEB_OPEN, 'findControlfileBackup_c');
   OPEN findControlfileBackup_c(sourcemask         => imageCopy_con_t,
                                pattern            => fname,
                                currentIncarnation => FALSE#,
                                statusMask         => NVL(statusMask,
                                computeAvailableMask(available,unavailable,0,0)));
 
--
   IF (duplicates = FALSE# and onlyone is NOT NULL) THEN
      getControlFileCopySingleRow := TRUE;
   ELSE
      getControlFileCopySingleRow := FALSE;
   END IF;
   deb(DEB_EXIT);
END translateControlFileCopyName;
 
 
--
 
--
PROCEDURE translateControlFileCopyTag(
   cftag        IN varchar2
  ,available    IN number           DEFAULT NULL -- for compatability
  ,unavailable  IN number           DEFAULT NULL -- for compatability
  ,duplicates   IN number
  ,statusMask   IN binary_integer   DEFAULT NULL
  ,onlyone      IN number           DEFAULT 1) IS
BEGIN
   deb(DEB_ENTER, 'translateControlFileCopyTag');
--
   deb(DEB_OPEN, 'findControlfileBackup_c');
   getControlFileCopyCursor := 'findControlfileBackup_c';
   OPEN findControlfileBackup_c(
                            sourcemask         => imageCopy_con_t,
                            tag                => cftag,
                            currentIncarnation => FALSE#,
                            statusMask         => NVL(statusMask,
                            computeAvailableMask(available,unavailable,0,0)));
 
--
   IF (duplicates = FALSE# and onlyone is NOT NULL) THEN
      getControlFileCopySingleRow := TRUE;
   ELSE
      getControlFileCopySingleRow := FALSE;
   END IF;
   deb(DEB_EXIT);
END translateControlFileCopyTag;
 
 
--
 
--
PROCEDURE translateControlFileCopyKey(
   key          IN number
  ,available    IN number         DEFAULT NULL    -- for compatability
  ,unavailable  IN number         DEFAULT NULL    -- for compatability
  ,statusMask   IN binary_integer DEFAULT NULL) IS -- for compatability
BEGIN
   deb(DEB_ENTER, 'translateControlFileCopyKey');
 
--
   deb(DEB_OPEN, 'findControlFileCopyKey');
 
--
--
   getControlFileCopyCursor := 'findControlFileCopyKey';
   OPEN findControlFileCopyKey(
                            copyKey            => key,
                            statusMask         => NVL(statusMask,
                            computeAvailableMask(available,unavailable,0,0)));
 
   deb(DEB_EXIT);
 
END translateControlFileCopyKey;
 
 
--
PROCEDURE getControlFileCopy(
   rcvRec       IN OUT NOCOPY rcvRec_t)
IS
   getControlFileCopyRowcount   number;
BEGIN
   deb(DEB_ENTER, 'getControlFileCopy');
   IF (getControlFileCopyCursor = 'findControlFileCopyKey'
       AND findControlFileCopyKey%ISOPEN) THEN
      FETCH findControlFileCopyKey
       INTO rcvRec;
 
<<NextRow>>
      IF (findControlFileCopyKey%NOTFOUND) THEN
 
--
         getControlFileCopyRowcount := findControlFileCopyKey%ROWCOUNT;
         CLOSE findControlFileCopyKey;
 
         IF (getControlFileCopyRowcount = 0) THEN
            deb(DEB_EXIT, 'with error 20220');
            raise_application_error(-20220, 'Controlfile copy does not exist');
         ELSE
            deb(DEB_EXIT, 'with no more records');
            RAISE no_data_found;                   -- signal end-of-fetch
         END IF;
      END IF;
      IF (getControlFileCopySingleRow = TRUE AND
          findControlFileCopyKey%ROWCOUNT > 1) THEN
--
--
         CLOSE findControlFileCopyKey;
         deb(DEB_EXIT, 'with no more records');
         RAISE no_data_found;
      END IF;
   ELSIF (getControlFileCopyCursor = 'findControlfileBackup_c'
          AND findControlfileBackup_c%ISOPEN) THEN
      FETCH findControlfileBackup_c
       INTO rcvRec;
 
      IF (findControlfileBackup_c%NOTFOUND) THEN
 
--
         getControlFileCopyRowcount := findControlfileBackup_c%ROWCOUNT;
         CLOSE findControlfileBackup_c;
 
         IF (getControlFileCopyRowcount = 0) THEN
            deb(DEB_EXIT, 'with error 20220');
            raise_application_error(-20220, 'Controlfile copy does not exist');
         ELSE
            deb(DEB_EXIT, 'with no more records');
            RAISE no_data_found;                   -- signal end-of-fetch
         END IF;
      END IF;
      IF (getControlFileCopySingleRow = TRUE AND
          findControlfileBackup_c%ROWCOUNT > 1) THEN
--
--
         CLOSE findControlfileBackup_c;
         deb(DEB_EXIT, 'with no more records');
         RAISE no_data_found;
      END IF;
   ELSE
      deb(DEB_EXIT, 'with error 20204');
      raise_application_error(-20204, 'Translation not started (' ||
                                       getControlFileCopyCursor || ')');
   END IF;
   deb(DEB_EXIT);
END getControlFileCopy;
 
--
 
--
PROCEDURE getControlFileCopy(
   recid        OUT number
  ,stamp        OUT number
  ,reset_scn    OUT number
  ,ckp_scn      OUT number
  ,block_size   OUT number)
IS
   rcvRec       rcvRec_t;
BEGIN
   deb(DEB_ENTER, 'getControlFileCopy');
   getControlFileCopy(rcvRec);
 
   recid      := rcvRec.recid_con;
   stamp      := rcvRec.stamp_con;
   reset_scn  := rcvRec.rlgSCN_act;
   ckp_scn    := rcvRec.toSCN_act;
   block_size := rcvRec.blockSize_con;
   deb(DEB_EXIT);
EXCEPTION
   WHEN no_data_found THEN
      deb(DEB_EXIT, 'with no more records');
--
      recid := NULL;                    -- signal end-of-fetch to caller
END getControlFileCopy;
 
--
--
--
 
--
PROCEDURE getDataFileCopy(
   rcvRec      OUT NOCOPY rcvRec_t
  ,closeCursor IN  boolean DEFAULT FALSE)
IS
   getDataFileCopyRowcount      number;
   local                        rcvRec_t;
BEGIN
   deb(DEB_ENTER, 'getDataFileCopy');
 
<<nextRow>>
   IF (getDatafileCopyCursor = 'findDatafileCopyKey') THEN
      FETCH findDatafileCopyKey
       INTO local;
 
      IF (findDatafileCopyKey%NOTFOUND) THEN
         getDataFileCopyRowcount := findDatafileCopyKey%ROWCOUNT;
         CLOSE findDatafileCopyKey;
      END IF;
 
      IF (closeCursor AND findDatafileCopyKey%ISOPEN) THEN
         CLOSE findDatafileCopyKey;
      END IF;
   ELSIF (getDatafileCopyCursor = 'findDatafileBackup_c') THEN
      IF (getDataFileCopySingleRow = TRUE AND
          findDatafileBackup_c%ROWCOUNT > 1) THEN
--
--
         CLOSE findDatafileBackup_c;
         getDatafileCopyCursor := NULL;
         deb(DEB_EXIT, 'with no more records');
         RAISE no_data_found;
      END IF;
 
      FETCH findDatafileBackup_c
       INTO local;
 
      IF (findDatafileBackup_c%NOTFOUND) THEN
         getDataFileCopyRowcount := findDatafileBackup_c%ROWCOUNT;
         CLOSE findDatafileBackup_c;
      END IF;
 
      IF (closeCursor AND findDatafileBackup_c%ISOPEN) THEN
         CLOSE findDatafileBackup_c;
      END IF;
   ELSE
      deb(DEB_EXIT, 'with error 20204');
      raise_application_error(-20204, 'Translation not started');
   END IF;
 
   IF (closeCursor) THEN
      getDatafileCopyCursor := NULL;
   END IF;
 
   IF (getDataFileCopyRowcount IS NOT NULL) THEN
      getDatafileCopyCursor := NULL;
      IF (getDataFileCopyRowcount = 0 AND
          getDatafileCopyNoRows.error IS NOT NULL) THEN
         deb(DEB_EXIT, 'with norows error');
         raise_application_error(getDatafileCopyNoRows.error,
                                 getDatafileCopyNoRows.msg);
      ELSE
         deb(DEB_EXIT, 'with no more records');
         RAISE no_data_found;                   -- signal end-of-fetch
      END IF;
   END IF;
 
   IF (getDataFileCopyLatestOnly = TRUE AND
       getDataFileCopyLast.dfNumber_obj = local.dfNumber_obj) THEN
      GOTO nextRow;
   END IF;
 
   getDataFileCopyLast := local;                -- save for duplicate filtering
   rcvRec := local;                             -- set OUT mode arg
   setDfTransClause(fno => local.dfNumber_obj);
   deb(DEB_EXIT);
END getDataFileCopy;
 
--
PROCEDURE translateDataFileCopyKey(
   cdf_key      IN number
  ,available    IN number         DEFAULT NULL   -- for compatability
  ,unavailable  IN number         DEFAULT NULL   -- for compatability
  ,statusMask   IN binary_integer DEFAULT NULL)  -- for compatability
IS
BEGIN
   deb(DEB_ENTER, 'translateDataFileCopyKey');
   validateState(getDatafileCopyCursor);
 
--
   deb(DEB_OPEN, 'findDataFileCopyKey');
   OPEN findDataFileCopyKey(copyKey            => cdf_key,
                            statusMask         => NVL(statusMask,
                               computeAvailableMask(available, unavailable,
                                                    0, 0)));
 
   getDatafileCopyCursor       := 'findDatafileCopyKey';
   getDataFileCopyNoRows.error := -20230;
   getDataFileCopyNoRows.msg   := 'Datafile copy does not exist';
   getDataFileCopyDuplicates   := NULL;
   getDataFileCopySingleRow    := NULL;
   deb(DEB_EXIT);
END translateDatafileCopyKey;
 
--
--
PROCEDURE translateDataFileCopyKey(
   cdf_key      IN number
  ,available    IN number
  ,unavailable  IN number
  ,recid        OUT number
  ,stamp        OUT number
  ,file#        OUT number
  ,fname        OUT varchar2
  ,reset_scn    OUT number
  ,create_scn   OUT number
  ,ckp_scn      OUT number
  ,block_size   OUT number
  ,blocks       OUT number)
IS
   rcvRec       rcvRec_t;
BEGIN
   deb(DEB_ENTER, 'translateDataFileCopyKey815');
   translateDataFileCopyKey(cdf_key     => cdf_key,
                            available   => available,
                            unavailable => unavailable);
 
   getDataFileCopy(rcvRec      => rcvRec,
                   closeCursor => TRUE);
 
   recid        := rcvRec.recid_con;
   stamp        := rcvRec.stamp_con;
   file#        := rcvRec.dfNumber_obj;
   fname        := rcvRec.fileName_con;
   reset_scn    := rcvRec.rlgSCN_act;
   create_scn   := rcvRec.dfCreationSCN_obj;
   ckp_scn      := rcvRec.toSCN_act;
   block_size   := rcvRec.blockSize_con;
   blocks       := rcvRec.blocks_con;
   deb(DEB_EXIT);
END translateDataFileCopyKey;
 
--
--
--
--
 
--
PROCEDURE translateDatafileCopyName(
   fname       IN varchar2
  ,available   IN number         DEFAULT NULL   -- for compatability
  ,unavailable IN number         DEFAULT NULL   -- for compatability
  ,duplicates  IN number
  ,statusMask  IN binary_integer DEFAULT NULL   -- for compatability
  ,onlyone     IN number         DEFAULT 1
  ,pluginSCN   IN number         DEFAULT 0)
IS
BEGIN
   deb(DEB_ENTER, 'translateDatafileCopyName');
   validateState(getDatafileCopyCursor);
 
--
   deb(DEB_OPEN, 'findDatafileBackup_c');
   OPEN findDatafileBackup_c(
                        sourcemask   => imageCopy_con_t,
                        pattern      => fname,
                        statusMask   => nvl(statusMask,
                                            computeAvailableMask(available,
                                                                 unavailable,
                                                                 0, 0)),
                        duplicates   => duplicates,
                        pluginSCN    => pluginSCN
                        );
   getDatafileCopyCursor            := 'findDatafileBackup_c';
   getDatafileCopyNoRows.error      := -20230;
   getDatafileCopyNoRows.msg        := 'Datafile copy does not exist';
   getDatafileCopyDuplicates        := duplicates;
   getDatafileCopyLast.dfNumber_obj := NULL;
   getDatafileCopyLatestOnly        := FALSE;
   IF (duplicates = FALSE# and onlyone is NOT NULL) THEN
      getDatafileCopySingleRow := TRUE;
   ELSE
      getDatafileCopySingleRow := FALSE;
   END IF;
   deb(DEB_EXIT);
END translateDatafileCopyName;
 
--
--
--
--
--
--
--
--
 
--
PROCEDURE translateDataFileCopyTag(
   tag          IN varchar2
  ,available    IN number         DEFAULT NULL    -- for compatibility
  ,unavailable  IN number         DEFAULT NULL    -- for compatibility
  ,duplicates   IN number
  ,statusMask   IN binary_integer DEFAULT NULL    -- for compatibility
  ,pluginSCN    IN number         DEFAULT 0
  ,onlytc       IN binary_integer DEFAULT FALSE#) -- for compatibility
IS
BEGIN
   deb(DEB_ENTER, 'translateDataFileCopyTag');
   validateState(getDatafileCopyCursor);
 
--
--
--
--
   deb(DEB_OPEN, 'findDataFileBackup_c');
 
   if (onlytc != FALSE#) THEN
      deb(DEB_PRINT, 'onytc is TRUE#');
   end if;
 
   OPEN findDatafileBackup_c(
                         sourcemask   => imageCopy_con_t,
                         tag          => tag,
                         reset_scn    => this_reset_scn,
                         reset_time   => this_reset_time,
                         statusMask   => nvl(statusMask,
                                             computeAvailableMask(available,
                                                                  unavailable,
                                                                  0, 0)),
                         duplicates   => duplicates,
                         pluginSCN    => pluginSCN,
                         onlytc       => onlytc
                         );
 
   getDatafileCopyCursor            := 'findDatafileBackup_c';
   getDataFileCopyNoRows.error      := -20232;
   getDataFileCopyNoRows.msg        := 'Datafile copy tag does not match';
   getDataFileCopyDuplicates        := duplicates;
   getDataFileCopyLast.dfNumber_obj := NULL;
   getDataFileCopySingleRow         := FALSE;
   getDataFileCopyLatestOnly        := FALSE;
   deb(DEB_EXIT);
END translateDataFileCopyTag;
 
--
--
--
--
 
--
PROCEDURE translateDatafileCopyFno(
   fno         IN number
  ,available   IN number         DEFAULT NULL
  ,unavailable IN number         DEFAULT NULL
  ,duplicates  IN number
  ,statusMask  IN binary_integer DEFAULT NULL
  ,pluginSCN   IN number         DEFAULT 0)
IS
BEGIN
   deb(DEB_ENTER, 'translateDatafileCopyFno');
   validateState(getDatafileCopyCursor);
 
   deb(DEB_OPEN, 'findDatafileBackup_c');
   OPEN findDatafileBackup_c(
                         duplicates   => duplicates,
                         sourcemask   => imageCopy_con_t,
                         fno          => fno,
                         statusMask   =>  NVL(statusMask,
                                              computeAvailableMask(available,
                                                                   unavailable,
                                                                   0, 0)),
                         pluginSCN    => pluginSCN
                         );
   getDatafileCopyCursor            := 'findDatafileBackup_c';
   getDatafileCopyNoRows.error      := -20230;
   getDatafileCopyNoRows.msg        := 'Datafile copy does not exist';
   getDatafileCopyDuplicates        := duplicates;
   getDatafileCopyLatestOnly        := FALSE;
   getDatafileCopyLast.dfNumber_obj := NULL;
   IF (duplicates = FALSE#) THEN
      getDatafileCopySingleRow := TRUE;
   ELSE
      getDatafileCopySingleRow := FALSE;
   END IF;
   setDfTransClause(fno => fno);
   deb(DEB_EXIT);
END translateDatafileCopyFno;
 
--
--
PROCEDURE getDataFileCopy(
   recid OUT number
  ,stamp OUT number
  ,file# OUT number
  ,fname OUT varchar2
  ,reset_scn OUT number
  ,create_scn OUT number
  ,ckp_scn OUT number
  ,block_size OUT number
  ,blocks OUT number)
IS
   rcvRec       rcvRec_t;
BEGIN
   deb(DEB_ENTER, 'getDataFileCopy');
   getDataFileCopy(rcvRec);
 
   recid        := rcvRec.recid_con;
   stamp        := rcvRec.stamp_con;
   file#        := rcvRec.dfNumber_obj;
   fname        := rcvRec.fileName_con;
   reset_scn    := rcvRec.rlgSCN_act;
   create_scn   := rcvRec.dfCreationSCN_obj;
   ckp_scn      := rcvRec.toSCN_act;
   block_size   := rcvRec.blockSize_con;
   blocks       := rcvRec.blocks_con;
   deb(DEB_EXIT);
EXCEPTION
   WHEN no_data_found THEN
      recid := NULL;                    -- signal end-of-fetch to client
      deb(DEB_EXIT, 'with no more records');
END getDataFileCopy;
 
--
--
--
 
--
PROCEDURE getProxyCopy(
   rcvRec      OUT NOCOPY rcvRec_t
  ,closeCursor IN  boolean DEFAULT FALSE)
IS
   getProxyCopyRowcount number;
   dummy                rcvRec_t;
BEGIN
   deb(DEB_ENTER, 'getProxyCopy');
   IF (getProxyCopyCursor = 'findProxyCopy') THEN
      FETCH findProxyCopy
       INTO rcvRec;
 
      IF (findProxyCopy%NOTFOUND) THEN
         getProxyCopyRowcount := findProxyCopy%ROWCOUNT;
         CLOSE findProxyCopy;
      ELSE
         IF (getProxyCopyByHandle) THEN
--
            FETCH findProxyCopy
             INTO dummy;
            IF (NOT findProxyCopy%NOTFOUND) THEN
               CLOSE findProxyCopy;
               deb(DEB_EXIT, 'with error 20311');
               raise_application_error(-20311, 'Ambiguous proxy copy handle');
            END IF;
         END IF;
      END IF;
 
      IF (closeCursor AND findProxyCopy%ISOPEN) THEN
         CLOSE findProxyCopy;
      END IF;
   ELSIF (getProxyCopyCursor = 'findProxyCopyKey') THEN
      FETCH findProxyCopyKey
       INTO rcvRec;
 
      IF (findProxyCopyKey%NOTFOUND) THEN
         getProxyCopyRowcount := findProxyCopyKey%ROWCOUNT;
         CLOSE findProxyCopyKey;
      END IF;
 
      IF (closeCursor AND findProxyCopyKey%ISOPEN) THEN
         CLOSE findProxyCopyKey;
      END IF;
   ELSE
      deb(DEB_EXIT, 'with errors 20204');
      raise_application_error(-20204, 'Translation not started');
   END IF;
 
   IF (closeCursor) THEN
      getProxyCopyCursor := NULL;
   END IF;
 
   IF (getProxyCopyRowcount IS NOT NULL) THEN
      getProxyCopyCursor := NULL;
      IF (getProxyCopyRowcount = 0 AND
          getProxyCopyNoRows.error IS NOT NULL) THEN
         deb(DEB_EXIT, 'with norows error');
         raise_application_error(getProxyCopyNoRows.error,
                                 getProxyCopyNoRows.msg);
      ELSE
         deb(DEB_EXIT, 'with no more records');
         RAISE no_data_found;                   -- signal end-of-fetch
      END IF;
   END IF;
   deb(DEB_EXIT);
 
END getProxyCopy;
 
--
PROCEDURE translateProxyCopyKey(
   pc_key       IN number
  ,deviceType   IN varchar2
  ,available    IN number           DEFAULT NULL   -- for compatability
  ,unavailable  IN number           DEFAULT NULL   -- for compatability
  ,deleted      IN number           DEFAULT NULL   -- for compatability
  ,expired      IN number           DEFAULT NULL   -- for compatability
  ,statusMask   IN binary_integer   DEFAULT NULL)  -- for compatability
IS
BEGIN
   deb(DEB_ENTER, 'translateProxyCopyKey');
   validateState(getProxyCopyCursor);
 
   deb(DEB_OPEN, 'findProxyCopyKey');
   OPEN findProxyCopyKey(key            => pc_key,
                         deviceType     => deviceType,
                         statusMask     => NVL(statusMask,
                  computeAvailableMask(available, unavailable, deleted,
                                       expired)));
   getProxyCopyCursor       := 'findProxyCopyKey';
   getProxyCopyNoRows.error := -20310;
   getProxyCopyNoRows.msg   := 'proxy copy is missing';
   getProxyCopyByHandle     := FALSE;
   deb(DEB_EXIT);
END translateProxyCopyKey;
 
--
 
--
PROCEDURE translateProxyCopyKey(
   pc_key       IN number
  ,device_type  IN varchar2
  ,available    IN number
  ,unavailable  IN number
  ,deleted      IN number
  ,recid        OUT number
  ,stamp        OUT number
  ,handle       OUT varchar2)
IS
   rcvRec       rcvRec_t;
BEGIN
   deb(DEB_ENTER, 'translateProxyCopyKey815');
   translateProxyCopyKey(pc_key         => pc_key,
                         deviceType     => device_type,
                         available      => available,
                         unavailable    => unavailable,
                         deleted        => deleted,
                         expired        => unavailable);
 
   getProxyCopy(rcvRec      => rcvRec,
                closeCursor => TRUE);
 
   recid  := rcvRec.recid_con;
   stamp  := rcvRec.stamp_con;
   handle := rcvRec.fileName_con;
   deb(DEB_EXIT);
END translateProxyCopyKey;
 
--
PROCEDURE translateProxyCopyHandle(
   handle       IN varchar2
  ,deviceType   IN varchar2
  ,available    IN number           DEFAULT NULL   -- for compatability
  ,unavailable  IN number           DEFAULT NULL   -- for compatability
  ,deleted      IN number           DEFAULT NULL   -- for compatability
  ,expired      IN number           DEFAULT NULL   -- for compatability
  ,statusMask   IN binary_integer   DEFAULT NULL)  -- for compatability
IS
BEGIN
   deb(DEB_ENTER, 'translateProxyCopyHandle');
   validateState(getProxyCopyCursor);
 
   deb(DEB_OPEN, 'findProxyCopy');
   OPEN findProxyCopy(handle      => handle,
                      deviceType  => deviceType,
                      statusMask  => NVL(statusMask,
                          computeAvailableMask(available, unavailable, deleted,
                                               expired)));
   getProxyCopyCursor       := 'findProxyCopy';
   getProxyCopyNoRows.error := -20310;
   getProxyCopyNoRows.msg   := 'proxy copy is missing';
   getProxyCopyByHandle     := TRUE;
   deb(DEB_EXIT);
END translateProxyCopyHandle;
 
--
 
--
PROCEDURE translateProxyCopyHandle(
   handle       IN varchar2
  ,device_type  IN varchar2
  ,available    IN number
  ,unavailable  IN number
  ,deleted      IN number
  ,recid        OUT number
  ,stamp        OUT number)
IS
   rcvRec       rcvRec_t;
BEGIN
   deb(DEB_ENTER, 'translateProxyCopyHandle815');
   translateProxyCopyHandle(handle      => handle,
                            deviceType  => device_type,
                            available   => available,
                            unavailable => unavailable,
                            deleted     => deleted,
                            expired     => unavailable);
 
   getProxyCopy(rcvRec      => rcvRec,
                closeCursor => TRUE);
 
   recid  := rcvRec.recid_con;
   stamp  := rcvRec.stamp_con;
   deb(DEB_EXIT);
END translateProxyCopyHandle;
 
--
 
--
PROCEDURE translateProxyCopyTag(
   tag         IN varchar2
  ,device_type IN varchar2
  ,available   IN number           DEFAULT NULL   -- for compatability
  ,unavailable IN number           DEFAULT NULL   -- for compatability
  ,deleted     IN number           DEFAULT NULL   -- for compatability
  ,statusMask  IN binary_integer   DEFAULT NULL)  -- for compatability
IS
BEGIN
   deb(DEB_ENTER, 'translateProxyCopyTag');
   validateState(getProxyCopyCursor);
   deb(DEB_OPEN, 'findProxyCopy');
   OPEN findProxyCopy(tag            => tag,
                      deviceType     => device_type,
                      statusMask     => NVL(statusMask,
                          computeAvailableMask(available, unavailable, deleted,
                                               unavailable/*expired*/)));
   getProxyCopyCursor       := 'findProxyCopy';
   getProxyCopyNoRows.error := -20310;
   getProxyCopyNoRows.msg   := 'no matching proxy copy found';
   getProxyCopyByHandle     := FALSE;
   deb(DEB_EXIT);
END translateProxyCopyTag;
 
--
PROCEDURE translateProxyCopyGuid(
   guid        IN varchar2
  ,device_type IN varchar2
  ,statusMask  IN binary_integer)
IS
   pdbKey number := NULL;
BEGIN
   deb(DEB_ENTER, 'translateProxyCopyGuid');
   validateState(getProxyCopyCursor);
   deb(DEB_OPEN, 'findProxyCopy');
 
--
   pdbKey := guidToPdbKey(guid);
--
 
   OPEN findProxyCopy(pdbKey         => pdbKey,
                      guid           => guid,
                      deviceType     => device_type,
                      statusMask     => NVL(statusMask, 0));
   getProxyCopyCursor       := 'findProxyCopy';
   getProxyCopyNoRows.error := -20310;
   getProxyCopyNoRows.msg   := 'no matching proxy copy found';
   getProxyCopyByHandle     := FALSE;
   deb(DEB_EXIT);
END translateProxyCopyGuid;
 
 
--
 
--
PROCEDURE getProxyCopy(
   recid        OUT number
  ,stamp        OUT number
  ,handle       OUT varchar2)
IS
   rcvRec       rcvRec_t;
BEGIN
   deb(DEB_ENTER, 'getProxyCopyHandle');
   getProxyCopy(rcvRec);
   recid  := rcvRec.recid_con;
   stamp  := rcvRec.stamp_con;
   handle := rcvRec.fileName_con;
   deb(DEB_EXIT);
EXCEPTION
   WHEN no_data_found THEN
      recid := NULL;                    -- indicate end-of-fetch
      deb(DEB_EXIT, 'with no more records');
END getProxyCopy;
 
--
--
--
 
--
PROCEDURE getBackupPiece(
   bpRec        OUT NOCOPY bpRec_t
  ,closeCursor  IN  boolean DEFAULT FALSE)
IS
   dummy        bpRec_t;
   local        bpRec_t;
   eof          boolean := FALSE;
   eob          boolean := FALSE;
   raiseError   boolean := FALSE;
BEGIN
   deb(DEB_ENTER, 'getBackupPiece');
   IF (getBackupPieceDuplicates = FALSE# AND
       getBackupPieceDeviceType IS NULL) THEN
--
--
--
      deb(DEB_EXIT, 'with error 20999');
      raise_application_error(-20999, 'deviceType must be specified');
   END IF;
 
<<nextRow>>
 
   IF (getBackupPieceCursor = 'findBackupPieceBpKey') THEN
      FETCH findBackupPieceBpKey
       INTO local;
 
      IF (findBackupPieceBpKey%NOTFOUND) THEN
         eof := TRUE;
         CLOSE findBackupPieceBpKey;
      END IF;
 
      IF (closeCursor AND findBackupPieceBpKey%ISOPEN) THEN
         CLOSE findBackupPieceBpKey;
      END IF;
   ELSIF (getBackupPieceCursor = 'findBackupPieceBsKey1') THEN
      FETCH findBackupPieceBsKey1
       INTO local;
 
      IF (findBackupPieceBsKey1%NOTFOUND) THEN
         eof := TRUE;
         CLOSE findBackupPieceBsKey1;
      END IF;
 
      IF (closeCursor AND findBackupPieceBsKey1%ISOPEN) THEN
         CLOSE findBackupPieceBsKey1;
      END IF;
   ELSIF (getBackupPieceCursor = 'findBackupPieceBsKey2') THEN
--
      local := getBackupPieceSeekLast;
      deb(DEB_PRINT, 'bskey = ' || local.bskey);
 
--
      IF (local.bskey != getBackupPieceBsKey              OR
          local.deviceType != getBackupPieceDeviceType    OR
          (getBackupPieceCopyNumber IS NOT NULL AND
           local.copyNumber != getBackupPieceCopyNumber)) THEN
         eob := TRUE;
         deb(DEB_PRINT, 'end of backupset');
      ELSE
         <<checkAgain>>
         LOOP
--
            FETCH findBackupPieceBsKey2
             INTO dummy;
 
            IF (findBackupPieceBsKey2%NOTFOUND) THEN
               CLOSE findBackupPieceBsKey2;
               dummy.bskey := 0;
            END IF;
 
            IF (dummy.bskey != getBackupPieceBsKey               OR
                dummy.deviceType != getBackupPieceDeviceType     OR
                getBackupPieceCopyNumber IS NULL                 OR
                dummy.copyNumber = getBackupPieceCopyNumber) THEN
               getBackupPieceSeekLast := dummy;
               EXIT checkAgain;
            END IF;
         END LOOP;
         deb(DEB_PRINT, 'next bskey=' || getBackupPieceSeekLast.bskey);
      END IF;
   ELSIF (getBackupPieceCursor = 'findBackupPiece_c') THEN
      FETCH findBackupPiece_c
       INTO local;
 
      IF (findBackupPiece_c%NOTFOUND) THEN
         eof := TRUE;
         CLOSE findBackupPiece_c;
      ELSE
         IF (getBackupPieceByHandle) THEN
--
            FETCH findBackupPiece_c
             INTO dummy;
            IF (NOT findBackupPiece_c%NOTFOUND) THEN
               raiseError := TRUE;
--
--
--
--
--
--
--
--
 
 
               
               IF (raiseError) THEN
                  CLOSE findBackupPiece_c;
                  deb(DEB_EXIT, 'with error 20261');
                  raise_application_error(-20261,
                                          'Ambiguous backup piece handle');
               END IF;
            END IF;
         END IF;
      END IF;
 
      IF (closeCursor AND findBackupPiece_c%ISOPEN) THEN
         CLOSE findBackupPiece_c;
      END IF;
   ELSE
      deb(DEB_EXIT, 'with error 20204');
      raise_application_error(-20204, 'Translation not started');
   END IF;
 
   IF (closeCursor OR eof) THEN
      getBackupPieceCursor := NULL;
   END IF;
 
   IF (eof OR eob) THEN           -- if end of fetch or end of backupset
--
--
      IF (getBackupPieceDuplicates = FALSE#) THEN
--
--
--
         IF (getBackupPieceExpectedPieces IS NOT NULL AND
             (getBackupPieceAvailableMask IS NULL  OR
              bitand(getBackupPieceAvailableMask,
                     dbms_rcvman.BSpartial_avail) = 0) AND
             getBackupPieceExpectedPieces <> getBackupPiecePieceCount) THEN
             deb(DEB_EXIT, 'with error 20216');
             raise_application_error(-20216, 'Backup piece is missing');
         END IF;
      END IF;
      IF (getBackupPiecePieceCount = 0 AND
          getBackupPieceNoRows.error IS NOT NULL) THEN
         deb(DEB_EXIT, 'with norows error');
         raise_application_error(getBackupPieceNoRows.error,
                                 getBackupPieceNoRows.msg);
      ELSE
         deb(DEB_EXIT, 'no more records');
         RAISE no_data_found;
      END IF;
   END IF;
 
   IF (getBackupPieceDuplicates = FALSE#) THEN
--
--
      IF (local.pieceNumber = getBackupPieceLast.pieceNumber) THEN
--
         GOTO nextRow;
      END IF;
   END IF;
 
   getBackupPieceLast := local;
   bpRec := local;                              -- set OUT mode arg
 
   getBackupPiecePieceCount := getBackupPiecePieceCount + 1;
   deb(DEB_EXIT);
END getBackupPiece;
 
--
PROCEDURE translateBackupPieceKey(
   key          IN number
  ,available    IN number             DEFAULT TRUE#
  ,unavailable  IN number             DEFAULT TRUE#
  ,expired      IN number             DEFAULT TRUE#
  ,statusMask   IN binary_integer     DEFAULT NULL)  -- for compatability
IS
BEGIN
--
--
--
--
--
 
   deb(DEB_ENTER, 'translateBackupPieceKey');
   findBackupPiece(bpKey       => key,
                   statusMask  => NVL(statusMask,
                computeAvailableMask(available, unavailable, 0, unavailable)));
 
   getBackupPieceNoRows.error   := -20260;
   getBackupPieceNoRows.msg     := 'Backup piece is missing';
   getBackupPieceAvailableMask  := statusMask;
   deb(DEB_EXIT);
END translateBackupPieceKey;
 
--
PROCEDURE translateBackupPieceKey(
   bp_key       IN number
  ,available    IN number
  ,unavailable  IN number
  ,recid        OUT number
  ,stamp        OUT number
  ,handle       OUT varchar2
  ,set_stamp    OUT number
  ,set_count    OUT number
  ,piece#       OUT number)
IS
   bpRec        bpRec_t;
BEGIN
   deb(DEB_ENTER, 'translateBackupPieceKey');
--
--
--
--
--
--
--
 
   translateBackupPieceKey(key => bp_key,
                   statusMask  =>
                computeAvailableMask(available, unavailable, 0,
                                     unavailable/*expired*/));
 
   getBackupPiece(bpRec       => bpRec,
                  closeCursor => TRUE);
 
   recid     := bpRec.recid;
   stamp     := bpRec.stamp;
   handle    := bpRec.handle;
   set_stamp := bpRec.setStamp;
   set_count := bpRec.setCount;
   piece#    := bpRec.pieceNumber;
   deb(DEB_EXIT);
 
END translateBackupPieceKey;
 
--
PROCEDURE translateBackupPieceHandle(
   handle       IN varchar2
  ,deviceType   IN varchar2
  ,available    IN number             DEFAULT NULL   -- for compatability
  ,unavailable  IN number             DEFAULT NULL   -- for compatability
  ,expired      IN number             DEFAULT NULL   -- for compatability
  ,statusMask   IN binary_integer     DEFAULT NULL)  -- for compatability
IS
BEGIN
   deb(DEB_ENTER, 'translateBackupPieceHandle');
   findBackupPiece(handle      => handle,
                   deviceType  => deviceType,
                   statusMask  => NVL(statusMask,
                  computeAvailableMask(available, unavailable, 0, expired)));
 
   getBackupPieceNoRows.error   := -20260;
   getBackupPieceNoRows.msg     := 'Backup piece is missing';
   getBackupPieceByHandle       := TRUE;
   getBackupPieceAvailableMask  := statusMask;
   deb(DEB_EXIT);
END translateBackupPieceHandle;
 
--
PROCEDURE translateBackupPieceHandle(                     -- only used in 8.1.6
   handle       IN varchar2
  ,device_type  IN varchar2
  ,available    IN number
  ,unavailable  IN number
  ,recid        OUT number
  ,stamp        OUT number
  ,set_stamp    OUT number
  ,set_count    OUT number
  ,piece#       OUT number)
IS
   bpRec        bpRec_t;
BEGIN
   deb(DEB_ENTER, 'translateBackupPieceHandle816');
   translateBackupPieceHandle(handle      => handle,
                              deviceType  => device_type,
                              statusMask  =>
                             computeAvailableMask(available, unavailable, 0,
                                                  unavailable/*expired*/));
 
   getBackupPiece(bpRec       => bpRec,
                  closeCursor => TRUE);
 
   recid     := bpRec.recid;
   stamp     := bpRec.stamp;
   set_stamp := bpRec.setStamp;
   set_count := bpRec.setCount;
   piece#    := bpRec.pieceNumber;
   deb(DEB_EXIT);
END translateBackupPieceHandle;
 
--
--
PROCEDURE translateBackupPieceTag(
   tag         IN varchar2
  ,available   IN number             DEFAULT NULL     -- for compatability
  ,unavailable IN number             DEFAULT NULL     -- for compatability
  ,statusMask  IN binary_integer     DEFAULT NULL)
IS
BEGIN
   deb(DEB_ENTER, 'translateBackupPieceTag');
 
   findBackupPiece(tag         => tag,
                   statusMask  => NVL(statusMask,
                  computeAvailableMask(available, unavailable, 0,
                                       /* expired = */unavailable)));
   deb(DEB_EXIT);
END translateBackupPieceTag;
 
--
--
PROCEDURE translateBackupPieceGuid(
   guid        IN varchar2
  ,statusMask  IN binary_integer)
IS
   pdbKey  number := NULL;
BEGIN
   deb(DEB_ENTER, 'translateBackupPieceGuid');
 
--
   pdbKey := guidToPdbKey(guid);
--
 
   findBackupPiece(pdbKey      => pdbKey,
                   guid        => guid,
                   statusMask  => NVL(statusMask, 0));
   deb(DEB_EXIT);
END translateBackupPieceGuid;
 
--
PROCEDURE translateBackupPieceBSKey(
   key          IN number
  ,tag          IN varchar2        DEFAULT NULL
  ,deviceType   IN varchar2        DEFAULT NULL
  ,pieceCount   IN number
  ,duplicates   IN number          DEFAULT TRUE#
  ,copyNumber   IN number          DEFAULT NULL
  ,available    IN number          DEFAULT TRUE#
  ,unavailable  IN number          DEFAULT FALSE#
  ,deleted      IN number          DEFAULT FALSE#
  ,expired      IN number          DEFAULT FALSE#
  ,statusMask   IN binary_integer  DEFAULT NULL)
IS
BEGIN
   deb(DEB_ENTER, 'translateBackupPieceBSKey');
   findBackupPiece(bsKey       => key,
                   tag         => tag,
                   deviceType  => deviceType,
                   copyNumber  => copyNumber,
                   statusMask  => NVL(statusMask,
              computeAvailableMask(available, unavailable, deleted, expired)));
 
   getBackupPieceDuplicates     := duplicates;
   getBackupPieceExpectedPieces := pieceCount;
   getBackupPieceAvailableMask  := statusMask;
   deb(DEB_EXIT);
END translateBackupPieceBSKey;
 
--
PROCEDURE translateBackupPieceBsKey(
   startBsKey   IN number
  ,tag          IN varchar2           DEFAULT NULL
  ,statusMask   IN binary_integer     DEFAULT NULL)
IS
BEGIN
   findBackupPiece(startBsKey  => startBskey,
                   tag         => tag,
                   statusMask  => NVL(statusMask,
                computeAvailableMask(TRUE#    /* available */,
                                     FALSE# /* unavailable */,
                                     FALSE#     /* deleted */,
                                     FALSE#     /* expired */)));
   getBackupPieceAvailableMask  := statusMask;
END translateBackupPieceBsKey;
 
--
PROCEDURE translateSeekBpBsKey(
   bsKey        IN number
  ,deviceType   IN varchar2
  ,pieceCount   IN number
  ,duplicates   IN number    DEFAULT TRUE#
  ,copyNumber   IN number    DEFAULT NULL)
IS
BEGIN
   deb(DEB_ENTER, 'translateSeekBpBsKey');
   deb(DEB_IN, 'bskey=' || bsKey);
 
   IF (getBackupPieceCursor IS NULL OR
       getBackupPieceCursor != 'findBackupPieceBsKey2') THEN
      raise_application_error(-20204, 'Translation not started');
   ELSIF (deviceType IS NULL) THEN
      raise_application_error(-20999, 'deviceType must be specified');
   END IF;
 
--
--
   getBackupPieceNoRows.error     := NULL;
   getBackupPieceDuplicates       := duplicates;
   getBackupPieceLast.pieceNumber := NULL;
   getBackupPieceDeviceType       := deviceType;
   getBackupPieceExpectedPieces   := pieceCount;
   getBackupPiecePieceCount       := 0;
   getBackupPieceByHandle         := FALSE;
   getBackupPieceCopyNumber       := copyNumber;
   getBackupPieceBskey            := bsKey;
 
<<checkAgain>>
   LOOP
      IF (NOT findBackupPieceBsKey2%ISOPEN) THEN      -- all done
         deb(DEB_EXIT, 'cursor not open');
         RAISE no_data_found;
      END IF;
 
      IF (getBackupPieceSeekLast.bskey > bsKey) THEN  -- gone over the key
         deb(DEB_EXIT, 'gone over key seek=' || getBackupPieceSeekLast.bskey
                       || ' key=' || bsKey);
         RAISE no_data_found;
      END IF;
 
--
      IF (getBackupPieceSeekLast.bskey = bsKey              AND
          getBackupPieceSeekLast.deviceType = deviceType    AND
          (copyNumber IS NULL OR
           getBackupPieceSeekLast.copyNumber = copyNumber)) THEN
         EXIT checkAgain;
      END IF;
 
      FETCH findBackupPieceBsKey2
       INTO getBackupPieceSeekLast;
 
      IF (findBackupPieceBsKey2%NOTFOUND) THEN       -- all done
        CLOSE findBackupPieceBsKey2;
        deb(DEB_EXIT, 'no more data');
        RAISE no_data_found;
      END IF;
   END LOOP;
   deb(DEB_EXIT, 'got key=' || bsKey);
END translateSeekBpBsKey;
 
--
PROCEDURE translateBpBsKeyCancel
IS
BEGIN
   IF (findBackupPieceBsKey1%ISOPEN) THEN
      CLOSE findBackupPieceBsKey1;
   END IF;
   IF (findBackupPieceBsKey2%ISOPEN) THEN
      CLOSE findBackupPieceBsKey2;
   END IF;
   getBackupPieceCursor := NULL;
END translateBpBsKeyCancel;
 
--
--
PROCEDURE translateBackupSetKey(
   bs_key          IN  number
  ,device_type     IN  varchar2
  ,available       IN  number
  ,unavailable     IN  number
  ,deleted         IN  number
  ,duplicates      IN  number
  ,backup_type     OUT varchar2
  ,recid           OUT number
  ,stamp           OUT number
  ,set_stamp       OUT number
  ,set_count       OUT number
  ,bslevel         OUT number
  ,completion_time OUT date)
IS
   bsRec           bsRec_t;
BEGIN
   deb(DEB_ENTER, 'translateBackupSetKey815');
   findBackupSet(bsKey => bs_key,               -- Lookup backset by key
                 bsRec => bsRec);
 
   backup_type     := bsRec.bsType;
   recid           := bsRec.recid;
   stamp           := bsRec.stamp;
   set_stamp       := bsRec.setStamp;
   set_count       := bsRec.setCount;
   bslevel         := bsRec.level;
   completion_time := bsRec.compTime;
 
--
--
--
--
--
--
 
--
   translateBackupPieceBSKey(key         => bs_key,
                             deviceType  => device_type,
                             pieceCount  => bsRec.pieceCount,
                             available   => available,
                             unavailable => unavailable,
                             deleted     => deleted,
                             expired     => unavailable);
 
   getBackupPieceDuplicates := duplicates;
 
   IF (device_type IS NULL) THEN
--
--
--
--
--
--
--
--
--
      getBackupPieceDuplicates := TRUE#;        -- yes, we want duplicates
   END IF;
 
   IF (getBackupPieceDuplicates = FALSE#) THEN
--
--
--
      getBackupPieceExpectedPieces := bsRec.pieceCount;
   END IF;
   deb(DEB_EXIT);
END translateBackupSetKey;
 
--
--
PROCEDURE translateBackupSetKey(
   bs_key          IN  number
  ,device_type     IN  varchar2
  ,available       IN  number
  ,unavailable     IN  number
  ,deleted         IN  number
  ,duplicates      IN  number
  ,backup_type     OUT varchar2
  ,recid           OUT number
  ,stamp           OUT number)
IS
   set_stamp       number;
   set_count       number;
   bslevel         number;
   completion_time date;
BEGIN
   deb(DEB_ENTER, 'translateBackupSetKey80');
   translateBackupSetKey(bs_key, device_type, available, unavailable, deleted,
                         duplicates, backup_type, recid, stamp, set_stamp,
                         set_count, bslevel, completion_time);
   deb(DEB_EXIT);
END translateBackupSetKey;
 
--
--
PROCEDURE translateBackupSetRecid(
   recid       IN  number
  ,stamp       IN  number
  ,device_type IN  varchar2
  ,bs_key      OUT number
  ,bslevel     OUT number
  ,completed   OUT date)
IS
   bsRec                bsRec_t;
   pieceCount           number;
   validationRec        validBackupSetRec_t;
   gotRecord            number;
   duplicates_flag      number;
BEGIN
   deb(DEB_ENTER, 'translateBackupSetRecid815');
   findBackupSet(recid => recid,
                 stamp => stamp,
                 bsRec => bsRec);
 
   bs_key    := bsRec.key;
   bslevel   := bsRec.level;
   completed := bsRec.compTime;
 
--
--
--
--
 
   findValidBackupSet(backupSetRec              => bsRec,
                      tag                       => restoreTag,
                      deviceType                => device_type,
                      available                 => TRUE#);
 
   gotRecord := getValidBackupSet(validBackupSetRec => validationRec);
 
   IF (getValidBackupSetCursor = 'findValidBackupSet_c') THEN
      CLOSE findValidBackupSet_c;
   ELSIF (getValidBackupSetCursor = 'findValidBackupSet1P_c') THEN
      CLOSE findValidBackupSet1P_c;
   END IF;
 
   IF (gotRecord = FALSE#) THEN
--
--
--
--
      validationRec.copyNumber := NULL;
   END IF;
 
   IF (device_type IS NULL) THEN
--
      duplicates_flag := TRUE#;
   ELSE
--
      duplicates_flag := FALSE#;
   END IF;
 
   translateBackupPieceBSKey(key         => bsRec.key,
                             tag         => validationRec.tag,
                             deviceType  => device_type,
                             pieceCount  => bsRec.pieceCount,
                             duplicates  => duplicates_flag,
                             copyNumber  => validationRec.copyNumber,
                             available   => TRUE#);
   deb(DEB_EXIT);
END translateBackupSetRecid;
 
--
 
--
PROCEDURE translateBackupSetRecid(
   recid       IN  number
  ,stamp       IN  number
  ,device_type IN  varchar2)
IS
   bs_key    number;
   bslevel   number;
   completed date;
BEGIN
   deb(DEB_ENTER, 'translateBackupSetRecid80');
   translateBackupSetRecid(recid, stamp, device_type, bs_key, bslevel,
                          completed);
   deb(DEB_EXIT);
END translateBackupSetRecid;
 
--
--
PROCEDURE getBackupPiece(
   recid      OUT number
  ,stamp      OUT number
  ,bpkey      OUT number
  ,set_stamp  OUT number
  ,set_count  OUT number
  ,piece#     OUT number
  ,copy#      OUT number
  ,status     OUT varchar2
  ,completion OUT date
  ,handle     OUT varchar2)
IS
   bpRec      bpRec_t;
BEGIN
   deb(DEB_ENTER, 'getBackupPiece815');
   getBackupPiece(bpRec);
 
   recid        := bpRec.recid;
   stamp        := bpRec.stamp;
   bpkey        := bpRec.key;
   set_stamp    := bpRec.setStamp;
   set_count    := bpRec.setCount;
   piece#       := bpRec.pieceNumber;
   copy#        := bpRec.copyNumber;
   status       := bpRec.status;
   completion   := bpRec.compTime;
   handle       := bpRec.handle;
   deb(DEB_EXIT);
EXCEPTION
   WHEN no_data_found THEN
      deb(DEB_EXIT, 'with no more records');
      bpRec.recid := NULL;              -- indicate end-of-fetch to client
END getBackupPiece;
 
--
--
PROCEDURE getBackupPiece(
   recid     OUT number
  ,stamp     OUT number
  ,set_stamp OUT number
  ,set_count OUT number
  ,piece#    OUT number
  ,handle    OUT varchar2)
IS
   bpRec     bpRec_t;
BEGIN
   deb(DEB_ENTER, 'getBackupPiece80');
   getBackupPiece(bpRec);
 
   recid        := bpRec.recid;
   stamp        := bpRec.stamp;
   set_stamp    := bpRec.setStamp;
   set_count    := bpRec.setCount;
   piece#       := bpRec.pieceNumber;
   handle       := bpRec.handle;
   deb(DEB_EXIT);
EXCEPTION
   WHEN no_data_found THEN
      bpRec.recid := NULL;              -- indicate end-of-fetch to client
      deb(DEB_EXIT, 'with no more records');
END getBackupPiece;
 
--
--
--
 
--
PROCEDURE translateBackupSetKey(
   key        IN  number
  ,bsRec      OUT NOCOPY bsRec_t)
IS
BEGIN
   deb(DEB_ENTER, 'translateBackupSetKey');
   findBackupSet(bsKey => key,
                 bsRec => bsRec);
   deb(DEB_EXIT);
END translateBackupSetKey;
 
--
--
--
 
--
--
FUNCTION findControlFileBackup(
   type         OUT number
  ,recid        OUT number
  ,stamp        OUT number
  ,fname        OUT varchar2
  ,device_type  OUT varchar2
  ,ckp_scn      OUT number)
RETURN number IS
   rcvRec       rcvRec_t;
   rc           number;
BEGIN
   deb(DEB_ENTER, 'findControlFileBackup804');
   rc := getControlfileBackup(rcvRec);
 
   IF (rc = SUCCESS) THEN
      IF (rcvRec.type_con = imageCopy_con_t) THEN
         type := COPY;
      ELSIF (rcvRec.type_con = backupSet_con_t) THEN
         type := BACKUP;
      ELSIF (rcvRec.type_con = proxyCopy_con_t) THEN
         type := PROXY;
      ELSE
--
         deb(DEB_EXIT, 'with: UNAVAILABLE');
         RETURN dbms_rcvman.UNAVAILABLE;
      END IF;
 
      IF (type = BACKUP) THEN
         recid := rcvRec.bsRecid_con;
         stamp := rcvRec.bsStamp_con;
      ELSE
         recid := rcvRec.recid_con;
         stamp := rcvRec.stamp_con;
      END IF;
      fname       := rcvRec.fileName_con;
      device_type := rcvRec.deviceType_con;
      ckp_scn     := rcvRec.toSCN_act;
      deb(DEB_EXIT, 'with: SUCCESS');
      RETURN SUCCESS;
   ELSE
      deb(DEB_EXIT, 'with: '||to_char(rc));
      RETURN rc;
   END IF;
   deb(DEB_EXIT);
 
END findControlFileBackup;
 
--
--
FUNCTION findControlFileBackup(
   type         OUT number
  ,recid        OUT number
  ,stamp        OUT number
  ,fname        OUT varchar2
  ,device_type  OUT varchar2
  ,ckp_scn      OUT number
  ,rlg_scn      OUT number
  ,blksize      OUT number)
RETURN number IS
   rcvRec       rcvRec_t;
   rc           number;
BEGIN
   deb(DEB_ENTER, 'findControlFileBackup815');
   rc := getControlfileBackup(rcvRec);
 
   IF (rc = SUCCESS) THEN
      IF (rcvRec.type_con = imageCopy_con_t) THEN
         type := COPY;
      ELSIF (rcvRec.type_con = backupSet_con_t) THEN
         type := BACKUP;
      ELSIF (rcvRec.type_con = proxyCopy_con_t) THEN
         type := PROXY;
         rcvRec_last := rcvRec;         -- save for translateProxyDFRecid
      ELSE
--
         deb(DEB_EXIT, 'with: UNAVAILABLE');
         RETURN dbms_rcvman.UNAVAILABLE;
      END IF;
 
      IF (type = BACKUP) THEN
         recid := rcvRec.bsRecid_con;
         stamp := rcvRec.bsStamp_con;
      ELSE
         recid := rcvRec.recid_con;
         stamp := rcvRec.stamp_con;
      END IF;
      fname       := rcvRec.fileName_con;
      device_type := rcvRec.deviceType_con;
      ckp_scn     := rcvRec.toSCN_act;
      rlg_scn     := rcvRec.rlgSCN_act;
      blksize     := rcvRec.blockSize_con;
      deb(DEB_EXIT, 'with: SUCCESS');
      RETURN SUCCESS;
   ELSE
      deb(DEB_EXIT, 'with: '||to_char(rc));
      RETURN rc;
   END IF;
END findControlFileBackup;
 
--
--
--
--
--
FUNCTION findArchivedLogBackup(
   thread#      IN number
  ,sequence#    IN number
  ,low_scn      IN number
  ,type         OUT number
  ,recid        OUT number
  ,stamp        OUT number
  ,device_type  OUT varchar2)
RETURN number IS
   rcvRec       rcvRec_t;
   RC           binary_integer;
BEGIN
   deb(DEB_ENTER, 'findArchivedLogBackup');
--
--
--
 
   findArchivedLogBackup(thread#, sequence#, low_scn);
 
   RC := getArchivedLogbackup(rcvRec);
 
   IF (RC = SUCCESS) THEN
      type        := BACKUP;
      recid       := rcvRec.bsRecid_con;
      stamp       := rcvRec.bsStamp_con;
      device_type := rcvRec.deviceType_con;
   END IF;
 
   deb(DEB_EXIT, 'with: '||to_char(RC));
   RETURN RC;
END findArchivedLogBackup;
 
--
--
--
 
--
PROCEDURE listTranslateControlfileCopy(
   tag             IN varchar2
  ,completedAfter  IN date
  ,completedBefore IN date
  ,statusMask      IN binary_integer DEFAULT
                        BSavailable+BSunavailable+BSexpired
  ,liststby        IN binary_integer DEFAULT NULL -- default for 8.1
  ,file_pattern    IN varchar2       DEFAULT NULL)
IS
  currentIncarnation number;
BEGIN
   deb(DEB_ENTER, 'listTranslateControlfileCopy');
   IF (findControlfileBackup_c%ISOPEN) THEN -- should not be open
      CLOSE findControlfileBackup_c;
   END IF;
 
   IF (allIncarnations = TRUE#) THEN
      currentIncarnation := FALSE#;             -- don't care about dbinc_key
   ELSE
      currentIncarnation := TRUE#;
   END IF;
 
--
   deb(DEB_OPEN, 'findControlfileBackup_c');
   OPEN findControlfileBackup_c(
                            sourcemask         => imageCopy_con_t,
                            currentIncarnation => currentIncarnation,
                            tag                => tag,
                            completedAfter     => completedAfter,
                            completedBefore    => completedBefore,
                            statusMask         => statusMask,
                            pattern            => file_pattern,
                            needstby           => liststby);
 
   deb(DEB_EXIT);
END listTranslateControlfileCopy;
 
--
PROCEDURE listGetControlfileCopy(
   rcvRec OUT NOCOPY rcvRec_t)
IS
BEGIN
   deb(DEB_ENTER, 'listGetControlfileCopy');
   FETCH findControlfileBackup_c
    INTO rcvRec;
 
   IF (findControlfileBackup_c%NOTFOUND) THEN
      CLOSE findControlfileBackup_c;
      deb(DEB_EXIT, 'with no more records');
      RAISE no_data_found;
   END IF;
 
--
--
--
   deb(DEB_EXIT);
END listGetControlfileCopy;
 
--
 
--
FUNCTION listGetControlfileCopy(
   bcfkey     OUT number,
   ckpscn     OUT number,
   ckptime    OUT date,
   status     OUT varchar2,
   completion OUT date,
   fname      OUT varchar2) RETURN number
IS
   rcvRec     rcvRec_t;
BEGIN
   deb(DEB_ENTER, 'listGetControlfileCopy');
   listGetControlfileCopy(rcvRec);
 
   bcfkey     := rcvRec.key_con;
   ckpscn     := rcvRec.toSCN_act;
   ckptime    := rcvRec.toTime_act;
   status     := rcvRec.status_con;
   completion := rcvRec.compTime_con;
   fname      := rcvRec.fileName_con;
   deb(DEB_EXIT, 'with: TRUE#');
   RETURN TRUE#;
EXCEPTION
   WHEN no_data_found THEN
      deb(DEB_EXIT, 'with: FALSE#');
      RETURN FALSE#;
END listGetControlfileCopy;
 
--
PROCEDURE listTranslateDataFileCopy(
   file#             IN number
  ,creation_change#  IN number
  ,tag               IN varchar2        DEFAULT NULL
  ,file_name_pattern IN varchar2        DEFAULT NULL
  ,completedAfter    IN date            DEFAULT NULL
  ,completedBefore   IN date            DEFAULT NULL
  ,statusMask        IN binary_integer  DEFAULT BSavailable+BSunavailable
--
  ,pluginSCN         IN number          DEFAULT 0)
IS
   creationSCN        number;
   reset_scn          number := NULL;
   reset_time         date   := NULL;
BEGIN
   deb(DEB_ENTER, 'listTranslateDataFileCopy');
   IF (allIncarnations = TRUE#) THEN
      reset_scn  := NULL;
      reset_time := NULL;
      IF (ignoreCreationSCN = TRUE#) THEN
--
--
--
--
         creationSCN := NULL;
      ELSE
         creationSCN := creation_change#;
      END IF;
   ELSE
      reset_scn   := this_reset_scn;
      reset_time  := this_reset_time;
      creationSCN := creation_change#;
   END IF;
 
--
   deb(DEB_OPEN, 'findDatafileBackup_c');
   OPEN findDatafileBackup_c(sourcemask         => imageCopy_con_t,
                             fno                => file#,
                             crescn             => creationSCN,
                             reset_scn          => reset_scn,
                             reset_time         => reset_time,
                             tag                => tag,
                             pattern            => file_name_pattern,
                             completedAfter     => completedAfter,
                             completedBefore    => completedBefore,
                             statusMask         => statusMask,
                             pluginSCN          => pluginSCN);
   deb(DEB_EXIT);
END listTranslateDataFileCopy;
 
--
PROCEDURE listGetDataFileCopy(
   rcvRec OUT NOCOPY rcvRec_t)
IS
BEGIN
   deb(DEB_ENTER, 'listGetDataFileCopy');
   FETCH findDatafileBackup_c
    INTO rcvRec;
 
   IF (findDatafileBackup_c%NOTFOUND) THEN
      CLOSE findDatafileBackup_c;
      deb(DEB_EXIT, 'with no more records');
      RAISE no_data_found;
   END IF;
 
--
--
--
   deb(DEB_EXIT);
END listGetDatafileCopy;
 
--
 
--
FUNCTION listGetDataFileCopy(
   cdf_key            OUT number
  ,status             OUT varchar2
  ,fname              OUT varchar2
  ,completion_time    OUT date
  ,checkpoint_change# OUT number
  ,checkpoint_time    OUT date)
RETURN number IS
   rcvRec             rcvRec_t;
BEGIN
   deb(DEB_ENTER, 'listGetDataFileCopy815');
   listGetDatafileCopy(rcvRec);
 
   cdf_key            := rcvRec.key_con;
   status             := rcvRec.status_con;
   fname              := rcvRec.fileName_con;
   completion_time    := rcvRec.compTime_con;
   checkpoint_change# := rcvRec.toSCN_act;
   checkpoint_time    := rcvRec.toTime_act;
   deb(DEB_EXIT, 'with: TRUE#');
   RETURN TRUE#;
EXCEPTION
   WHEN no_data_found THEN
      deb(DEB_EXIT, 'with: FALSE#');
      RETURN FALSE#;
END listGetDataFileCopy;
 
--
PROCEDURE listTranslateArchivedLogCopy(
   thread#           IN number
  ,sequence#         IN number
  ,first_change#     IN number
  ,file_name_pattern IN varchar2        DEFAULT NULL
  ,completedAfter    IN date            DEFAULT NULL
  ,completedBefore   IN date            DEFAULT NULL
  ,statusMask        IN binary_integer  DEFAULT
                       BSavailable+BSunavailable+BSexpired  -- 8.0/8.1 defaults
  ,needstby          IN number          DEFAULT NULL)
IS
   currentIncarnation number;
BEGIN
 
   deb(DEB_ENTER, 'listTranslateArchivedLogCopy');
 
   IF (allIncarnations = TRUE#) THEN
      currentIncarnation := FALSE#;             -- don't care about dbinc_key
   ELSE
      currentIncarnation := TRUE#;
   END IF;
 
   deb(DEB_OPEN, 'findArchivedLogCopy');
   OPEN findArchivedLogCopy(currentIncarnation => currentIncarnation,
                            thread             => thread#,
                            sequence           => sequence#,
                            lowSCN             => first_change#,
                            pattern            => file_name_pattern,
                            completedAfter     => completedAfter,
                            completedBefore    => completedBefore,
                            statusMask         => statusMask,
--
                            needstby           => NULL);
   getrcvRecLast := NULL;
   deb(DEB_EXIT);
END listTranslateArchivedLogCopy;
 
--
PROCEDURE listGetArchivedLogCopy(
   rcvRec OUT NOCOPY rcvRec_t)
IS
duplicate           number;              -- used for filtering duplicate names
BEGIN
   deb(DEB_ENTER, 'listGetArchivedLogCopy');
 
--
--
--
   IF (restoreTag is not NULL OR
       not diskDevice)            THEN
      CLOSE findArchivedLogCopy;
      deb(DEB_EXIT, 'tag specified or no diskDevice allocated');
      RAISE no_data_found;
   END IF;
 
--
   IF (guidQualifier IS NOT NULL) THEN
      IF (findArchivedLogCopy%ISOPEN) THEN
         CLOSE findArchivedLogCopy;
      END IF;
      deb(DEB_EXIT, 'guid not valid for archivelog');
      RAISE no_data_found;
   END IF;
 
<<nextRow>>
   FETCH findArchivedLogCopy
    INTO rcvRec;
 
   IF (findArchivedLogCopy%NOTFOUND) THEN
      CLOSE findArchivedLogCopy;
      deb(DEB_EXIT, 'with no more records');
      RAISE no_data_found;
   END IF;
 
--
--
--
   IF (rcvRec.logThread_obj   = getrcvRecLast.logThread_obj AND
       rcvRec.logSequence_obj = getrcvRecLast.logSequence_obj AND
       rcvRec.loglowSCN_obj   = getrcvRecLast.loglowSCN_obj AND
       rcvRec.logrlgSCN_obj   = getrcvRecLast.logrlgSCN_obj AND
       rcvRec.logrlgTime_obj  = getrcvRecLast.logrlgTime_obj ) THEN
       duplicate := TRUE#;
   ELSE
       duplicate := FALSE#;
   END IF;
 
   IF IsDuplicateAlName(duplicate, rcvRec.filename_con) THEN
     GOTO nextRow;
   END IF;
 
   getrcvRecLast := rcvRec;
--
 
   deb(DEB_EXIT);
END listGetArchivedLogCopy;
 
--
 
--
FUNCTION listGetArchivedLogCopy(
   al_key          OUT number
  ,status          OUT varchar2
  ,fname           OUT varchar2
  ,completion_time OUT date)
RETURN number IS
   rcvRec          rcvRec_t;
BEGIN
   deb(DEB_ENTER, 'listGetArchivedLogCopy');
   listGetArchivedLogCopy(rcvRec);
 
   al_key          := rcvRec.key_con;
   status          := rcvRec.status_con;
   fname           := rcvRec.fileName_con;
   completion_time := rcvRec.compTime_con;
   deb(DEB_EXIT, 'with: TRUE#');
   RETURN TRUE#;
EXCEPTION
   WHEN no_data_found THEN
      deb(DEB_EXIT, 'with: FALSE#');
      RETURN FALSE#;
END listGetArchivedLogCopy;
 
--
--
--
 
--
PROCEDURE listTranslateControlfileBackup(
   tag             IN  varchar2
  ,completedAfter  IN  date
  ,completedBefore IN  date
  ,statusMask      IN  binary_integer   DEFAULT
                      BSavailable+BSunavailable+BSexpired   -- 8.0/8.1 defaults
  ,autobackup      IN  binary_integer   DEFAULT BScfile_all
  ,liststby        IN  binary_integer   DEFAULT NULL)
IS
   currentIncarnation number;
BEGIN
   deb(DEB_ENTER, 'listTranslateControlfileBackup');
   IF (findControlfileBackup_c%ISOPEN) THEN     -- should not be open
      CLOSE findControlfileBackup_c;
   END IF;
 
   IF (allIncarnations = TRUE#) THEN
      currentIncarnation := FALSE#;             -- don't care about dbinc_key
   ELSE
      currentIncarnation := TRUE#;
   END IF;
 
--
--
   deb(DEB_OPEN, 'findControlfileBackup_c');
   OPEN findControlfileBackup_c(sourcemask         => backupSet_con_t,
                                currentIncarnation => currentIncarnation,
                                completedAfter     => completedAfter,
                                completedBefore    => completedBefore,
                                typemask           => autobackup,
                                needstby           => liststby);
 
--
--
--
--
--
 
   listGetBackupTag           := tag;
   listGetBackupAvailableMask := statusMask;
   deb(DEB_EXIT);
END listTranslateControlfileBackup;
 
--
PROCEDURE listGetControlfileBackup(
   rcvRec OUT NOCOPY rcvRec_t)
IS
BEGIN
   deb(DEB_ENTER, 'listGetControlfileBackup');
   FETCH findControlfileBackup_c
    INTO rcvRec;
 
--
--
 
   IF (findControlfileBackup_c%NOTFOUND) THEN
      CLOSE findControlfileBackup_c;
      deb(DEB_EXIT, 'with no more records');
      RAISE no_data_found;
   END IF;
   deb(DEB_EXIT);
END listGetControlfileBackup;
 
--
--
FUNCTION listGetControlfileBackup(
   bskey      OUT number,
   ckpscn     OUT number,
   ckptime    OUT date)
RETURN number IS
   rcvRec               rcvRec_t;
   validationRec        validBackupSetRec_t;
   validationRC         binary_integer;
BEGIN
   deb(DEB_ENTER, 'listGetControlfileBackup815');
   <<nextRow>>
   BEGIN
      listGetControlfileBackup(rcvRec);
   EXCEPTION
      WHEN no_data_found THEN
         deb(DEB_EXIT, 'with: FALSE#');
         RETURN FALSE#;
   END;
 
   validationRC :=
      validateBackupSet(backupSetRec           => rcvRec,
                        tag                    => listGetBackupTag,
                        tagMatchRequired       => TRUE,
                        checkDeviceIsAllocated => TRUE,
                        availableMask          => listGetBackupAvailableMask,
                        validRec               => validationRec);
 
   IF (validationRC <> SUCCESS) THEN
      GOTO nextRow;
   END IF;
 
   bskey      := rcvRec.bsKey_con;
   ckpscn     := rcvRec.toSCN_act;
   ckptime    := rcvRec.toTime_act;
   deb(DEB_EXIT, 'with: TRUE#');
   RETURN TRUE#;
EXCEPTION
    WHEN no_data_found THEN
       deb(DEB_EXIT, 'with: FALSE#');
       RETURN FALSE#;
END listGetControlfileBackup;
 
--
PROCEDURE listTranslateSpfileBackup(
   completedAfter  IN  date
  ,completedBefore IN  date)
IS
BEGIN
   deb(DEB_ENTER, 'listTranslateSpfileBackup');
   IF (findSpfileBackup_c%ISOPEN) THEN                   -- should not be open
      CLOSE findSpfileBackup_c;
   END IF;
 
   deb(DEB_OPEN, 'findSpfileBackup_c');
   OPEN findSpfileBackup_c(completedAfter     => completedAfter,
                           completedBefore    => completedBefore);
 
   deb(DEB_EXIT);
END listTranslateSpfileBackup;
 
--
PROCEDURE listGetSpfileBackup(
   rcvRec OUT NOCOPY rcvRec_t)
IS
BEGIN
   deb(DEB_ENTER, 'listGetSpfileBackup');
   FETCH findSpfileBackup_c
    INTO rcvRec;
 
--
--
 
   IF (findSpfileBackup_c%NOTFOUND) THEN
      CLOSE findSpfileBackup_c;
      deb(DEB_EXIT, 'with no more records');
      RAISE no_data_found;
   END IF;
 
   deb(DEB_EXIT);
END listGetSpfileBackup;
 
--
PROCEDURE listTranslateDataFileBackup(
   file#             IN number
  ,creation_change#  IN number
  ,tag               IN varchar2        DEFAULT NULL
  ,completedAfter    IN date            DEFAULT NULL
  ,completedBefore   IN date            DEFAULT NULL
  ,statusMask        IN binary_integer  DEFAULT
                      BSavailable+BSunavailable+BSexpired   -- 8.0/8.1 defaults
  ,pluginSCN         IN number          DEFAULT 0)
IS
   rlgSCN       number;
   rlgTime      date;
   crescn       number;
BEGIN
   deb(DEB_ENTER, 'listTranslateDataFileBackup');
   IF (findDatafileBackup_c%ISOPEN) THEN
      CLOSE findDatafileBackup_c;
   END IF;
 
   IF (allIncarnations = TRUE#) THEN
      IF (ignoreCreationSCN = TRUE#) THEN
--
--
--
--
--
         crescn := NULL;
      ELSE
         crescn := creation_change#;
      END IF;
   ELSE
--
--
      rlgSCN  := this_reset_scn;
      rlgTime := this_reset_time;
      crescn  := creation_change#;
   END IF;
 
--
   deb(DEB_OPEN, 'findDatafileBackup_c');
   OPEN findDatafileBackup_c(sourceMask         => backupSet_con_t,
                             fno                => file#,
                             crescn             => crescn,
                             reset_scn          => rlgSCN,
                             reset_time         => rlgTime,
                             completedAfter     => completedAfter,
                             completedBefore    => completedBefore,
                             pluginSCN          => pluginSCN);
 
--
--
--
--
--
 
   listGetBackupTag           := tag;
   listGetBackupAvailableMask := statusMask;
   deb(DEB_EXIT);
END listTranslateDataFileBackup;
 
--
PROCEDURE listGetDataFileBackup(
   rcvRec OUT NOCOPY rcvRec_t)
IS
BEGIN
   deb(DEB_ENTER, 'listGetDataFileBackup');
   FETCH findDatafileBackup_c
    INTO rcvRec;
 
   IF (findDatafileBackup_c%NOTFOUND) THEN
      CLOSE findDatafileBackup_c;
      deb(DEB_EXIT, 'with no more records');
      RAISE no_data_found;
   END IF;
   deb(DEB_EXIT);
END listGetDataFileBackup;
 
--
 
--
FUNCTION listGetDataFileBackup(
   bs_key             OUT number
  ,backup_type        OUT varchar2
  ,incremental_level  OUT number
  ,completion_time    OUT date
  ,checkpoint_change# OUT number
  ,checkpoint_time    OUT date)
RETURN number IS
   rcvRec             rcvRec_t;
   valRC              binary_integer;
   validationRec      validBackupSetRec_t;
BEGIN
   deb(DEB_ENTER, 'listGetDataFileBackup815');
<<nextRow>>
   BEGIN
      listGetDataFileBackup(rcvRec => rcvRec);
   EXCEPTION
      WHEN no_data_found THEN
         deb(DEB_EXIT, 'with: FALSE#');
         RETURN FALSE#;
   END;
 
   valRC :=
      validateBackupSet(backupSetRec           => rcvRec,
                        tag                    => listGetBackupTag,
                        tagMatchRequired       => TRUE,
                        checkDeviceIsAllocated => TRUE,
                        availableMask          => listGetBackupAvailableMask,
                        validRec               => validationRec);
 
   IF (valRC <> SUCCESS) THEN
      GOTO nextRow;
   END IF;
 
   bs_key             := rcvRec.bsKey_con;
   IF (rcvRec.fromSCN_act = 0) THEN
      backup_type := 'Full';
   ELSE
      backup_type := 'Incremental';
   END IF;
   incremental_level  := rcvRec.level_act;
   completion_time    := rcvRec.compTime_con;           -- somewhat bogus
   checkpoint_change# := rcvRec.toSCN_act;
   checkpoint_time    := rcvRec.toTime_act;
   deb(DEB_EXIT, 'with: TRUE#');
   RETURN TRUE#;
END listGetDataFileBackup;
 
--
 
--
PROCEDURE translateBackupFile(
   bs_recid    IN  number
  ,bs_stamp    IN  number
  ,fno         IN  number
  ,bskey       OUT number
  ,inclevel    OUT number
  ,backup_type OUT varchar2
  ,completed   OUT date)
IS
BEGIN
   deb(DEB_ENTER, 'translateBackupFile');
--
--
--
--
--
--
--
   IF (rcvRec_last.type_con <> backupSet_con_t OR
       rcvRec_last.bsRecid_con <> bs_recid OR
       rcvRec_last.bsStamp_con <> bs_stamp) THEN
      deb(DEB_EXIT, 'with error 20204');
      raise_application_error(-20204, 'Translation not started');
   END IF;
 
   bskey     := rcvRec_last.bsKey_con;
   inclevel  := rcvRec_last.level_act;
   completed := rcvRec_last.compTime_con;
 
   IF (rcvRec_last.logSequence_obj IS NOT NULL) THEN
      backup_type := 'Archived Log';
   ELSE
      IF (rcvRec_last.fromSCN_act = 0) THEN
         backup_type := 'Full';
      ELSE
         backup_type := 'Incremental';
      END IF;
   END IF;
   deb(DEB_EXIT);
END translateBackupFile;
 
--
--
PROCEDURE listTranslateArchivedLogBackup(
   thread#              IN number
  ,sequence#            IN number
  ,first_change#        IN number
  ,completedAfter       IN date           DEFAULT NULL
  ,completedBefore      IN date           DEFAULT NULL
  ,statusMask           IN binary_integer DEFAULT
                      BSavailable+BSunavailable+BSexpired)  -- 8.0/8.1 defaults
IS
   currentInc number;
BEGIN
   deb(DEB_ENTER, 'listTranslateArchivedLogBackup');
 
   IF (allIncarnations = TRUE#) THEN
      currentInc := FALSE#;                      -- don't care about dbinc_key
   ELSE
      currentInc := TRUE#;
   END IF;
 
   deb(DEB_OPEN, 'findArcLogBackup');
   OPEN findArcLogBackup(sourcemask         => backupSet_con_t,
                         currentIncarnation => currentInc,
                         thread             => thread#,
                         sequence           => sequence#,
                         lowSCN             => first_change#,
                         completedAfter     => completedAfter,
                         completedBefore    => completedBefore);
   listGetBackupAvailableMask := statusMask;
   deb(DEB_EXIT);
END listTranslateArchivedLogBackup;
 
--
PROCEDURE listGetArchivedLogBackup(
   rcvRec OUT NOCOPY rcvRec_t)
IS
BEGIN
   deb(DEB_ENTER, 'listGetArchivedLogBackup');
 
--
   IF (guidQualifier IS NOT NULL) THEN
      IF (findArcLogBackup%ISOPEN) THEN
         CLOSE findArcLogBackup;
      END IF;
      deb(DEB_EXIT, 'guid not valid for archivelog');
      RAISE no_data_found;
   END IF;
 
   FETCH findArcLogBackup
    INTO rcvRec;
 
   IF (findArcLogBackup%NOTFOUND) THEN
      CLOSE findArcLogBackup;
      deb(DEB_EXIT, 'with no more records');
      RAISE no_data_found;
   END IF;
   deb(DEB_EXIT);
END listGetArchivedLogBackup;
 
--
 
--
FUNCTION listGetArchivedLogBackup(
   bs_key          OUT number
  ,completion_time OUT date)
RETURN number IS
   rcvRec       rcvRec_t;
   validRec     validBackupSetRec_t;
   valRC        binary_integer;
BEGIN
   deb(DEB_ENTER, 'listGetArchivedLogBackup');
<<get_next>>
   listGetArchivedLogBackup(rcvRec);
 
   valRC :=
      validateBackupSet(backupSetRec           => rcvRec,
                        checkDeviceIsAllocated => TRUE,
                        availableMask          => listGetBackupAvailableMask,
                        validRec               => validRec);
   IF (valRC <> SUCCESS) THEN
      GOTO get_next;
   END IF;
 
   bs_key          := rcvRec.bsKey_con;
   completion_time := rcvRec.compTime_con;
   deb(DEB_EXIT, 'with: TRUE#');
   RETURN TRUE#;
EXCEPTION
   WHEN no_data_found THEN
      deb(DEB_EXIT, 'with: FALSE#');
      RETURN FALSE#;
END listGetArchivedLogBackup;
 
--
--
--
--
PROCEDURE listTranslateArchivedLogBackup(
   thread#      IN number   DEFAULT NULL
  ,lowseq       IN number   DEFAULT NULL
  ,highseq      IN number   DEFAULT NULL
  ,lowscn       IN number   DEFAULT NULL
  ,highscn      IN number   DEFAULT NULL
  ,from_time    IN date     DEFAULT NULL
  ,until_time   IN date     DEFAULT NULL
  ,pattern      IN varchar2 DEFAULT NULL)
IS
BEGIN
   deb(DEB_ENTER, 'listTranslateArchivedLogBackup815');
   if lbal2%isopen then
      close lbal2;
   end if;
   deb(DEB_OPEN, 'lbal2');
   open lbal2(thread#, lowseq, highseq, lowscn, highscn, from_time, until_time);
   deb(DEB_EXIT);
END listTranslateArchivedLogBackup;
 
--
--
FUNCTION listGetArchivedLogBackup(
   bs_key          OUT number
  ,thread#         OUT number
  ,sequence#       OUT number
  ,first_change#   OUT number
  ,next_change#    OUT number
  ,first_time      OUT date
  ,next_time       OUT date)
RETURN number IS
   rcvRec          rcvRec_t;
   validRec        validBackupSetRec_t;
BEGIN
   deb(DEB_ENTER, 'listGetArchivedLogBackup815');
<<get_next>>
  fetch lbal2 into rcvRec;
  if lbal2%found then
    IF (debug) THEN
       deb(DEB_PRINT, 'listGetArchivedLogBackup: got a backupset:');
       printRcvRec(rcvRec);
    END IF;
 
    if validateBackupSet(backupSetRec           => rcvRec,
                         checkDeviceIsAllocated => TRUE,
                         availableMask          => dbms_rcvman.BSavailable +
                                                   dbms_rcvman.BSunavailable +
                                                   dbms_rcvman.BSexpired,
                         validRec               => validRec) <> SUCCESS then
       goto get_next;
    end if;
    bs_key          := rcvRec.bsKey_con;
    thread#         := rcvRec.logThread_obj;
    sequence#       := rcvRec.logSequence_obj;
    first_change#   := rcvRec.logLowSCN_obj;
    next_change#    := rcvRec.logNextSCN_obj;
    first_time      := rcvRec.logLowTime_obj;
    next_time       := rcvRec.logNextTime_obj;
    deb(DEB_EXIT, 'with: TRUE#');
    RETURN TRUE#;
  else
    close lbal2;
    deb(DEB_EXIT, 'with: FALSE#');
    RETURN FALSE#;
  end if;
END listGetArchivedLogBackup;
 
--
--
--
 
PROCEDURE listTranslateBackupsetFiles(
   bs_key          IN  number)
IS
BEGIN
   IF findBackupsetFiles%ISOPEN THEN
      CLOSE findBackupsetFiles;
   END IF;
   OPEN findBackupsetFiles(bs_key);
END;
 
PROCEDURE listGetBackupsetFiles(
   rcvRec OUT NOCOPY rcvRec_t)
IS
BEGIN
   FETCH findBackupsetFiles
    INTO rcvRec;
 
   IF (findBackupsetFiles%NOTFOUND) THEN
      CLOSE findBackupsetFiles;
      RAISE no_data_found;
   END IF;
END;
 
--
--
--
 
PROCEDURE translateAllBackupSet(
   backupType            IN  binary_integer
  ,tag                   IN  varchar2
  ,statusMask            IN  binary_integer
  ,completedAfter        IN  date
  ,completedBefore       IN  date
  ,onlyrdf               IN  binary_integer DEFAULT 0)
IS
BEGIN
   IF findAllBackupPiece%ISOPEN THEN
      CLOSE findAllBackupPiece;
   END IF;
   OPEN findAllBackupPiece(backupType       => backupType
                           ,tag              => tag
                           ,statusMask       => statusMask
                           ,completedAfter   => completedAfter
                           ,completedBefore  => completedBefore
                           ,onlyrdf          => onlyrdf);
END;
 
PROCEDURE getAllBackupSet(
   rcvRec OUT NOCOPY rcvRec_t)
IS
BEGIN
   FETCH findAllBackupPiece
    INTO rcvRec;
 
   IF (findAllBackupPiece%NOTFOUND) THEN
      CLOSE findAllBackupPiece;
      RAISE no_data_found;
   END IF;
END;
 
--
--
--
 
--
 
--
PROCEDURE listTranslateProxyDataFile(
   file#             IN number
  ,creation_change#  IN number
  ,tag               IN varchar2        DEFAULT NULL
  ,handle_pattern    IN varchar2        DEFAULT NULL
  ,completedAfter    IN date            DEFAULT NULL
  ,completedBefore   IN date            DEFAULT NULL
  ,statusMask        IN binary_integer
                           DEFAULT BSavailable+BSunavailable+BSexpired
  ,liststby          IN binary_integer  DEFAULT NULL
  ,pluginSCN         IN number          DEFAULT 0)
IS
   currentInc   number;
   crescn       number;
   reset_scn    number := NULL;
   reset_time   date   := NULL;
BEGIN
   deb(DEB_ENTER, 'listTranslateProxyDataFile');
   validateState(null);
 
   IF (allIncarnations = TRUE#) THEN
      currentInc := FALSE#;                     -- don't care about dbinc_key
      IF (ignoreCreationSCN = TRUE#) THEN
--
--
--
--
         crescn := NULL;
      ELSE
         crescn := creation_change#;
      END IF;
   ELSE
      currentInc := TRUE#;
      crescn     := creation_change#;
   END IF;
 
   IF (currentInc = TRUE#) THEN
      reset_scn  := this_reset_scn;
      reset_time := this_reset_time;
   END IF;
 
   IF (file# = 0) THEN
      IF (findControlfileBackup_c%ISOPEN) THEN
         CLOSE findControlfileBackup_c;
      END IF;
 
--
      deb(DEB_OPEN, 'findControlfileBackup_c');
      OPEN findControlfileBackup_c( sourcemask         => proxyCopy_con_t,
                                    currentIncarnation => currentInc,
                                    tag                => tag,
                                    pattern            => handle_pattern,
                                    completedAfter     => completedAfter,
                                    completedBefore    => completedBefore,
                                    statusMask         => statusMask,
                                    needstby           => liststby);
      listGetProxyDatafileCursor := 'findControlfileBackup_c';
   ELSE
      IF (findDatafileBackup_c%ISOPEN) THEN
         CLOSE findDatafileBackup_c;
      END IF;
 
--
      OPEN findDatafileBackup_c(sourcemask         => proxyCopy_con_t,
                                fno                => file#,
                                crescn             => crescn,
                                reset_scn          => reset_scn,
                                reset_time         => reset_time,
                                tag                => tag,
                                pattern            => handle_pattern,
                                completedAfter     => completedAfter,
                                completedBefore    => completedBefore,
                                statusMask         => statusMask,
                                pluginSCN          => pluginSCN);
      listGetProxyDatafileCursor := 'findDatafileBackup_c';
   END IF;
   deb(DEB_EXIT);
END listTranslateProxyDataFile;
 
--
PROCEDURE listGetProxyDataFile(
   rcvRec OUT NOCOPY rcvRec_t)
IS
   local rcvRec_t;
BEGIN
   deb(DEB_ENTER, 'listGetProxyDataFile');
 
<<nextRow>>
 
   IF (listGetProxyDatafileCursor = 'findControlfileBackup_c') THEN
      FETCH findControlfileBackup_c
       INTO local;
      IF (findControlfileBackup_c%NOTFOUND) THEN
         CLOSE findControlfileBackup_c;
         deb(DEB_EXIT, 'with no more records');
         RAISE no_data_found;
      END IF;
   ELSIF (listGetProxyDatafileCursor = 'findDatafileBackup_c') THEN
      FETCH findDatafileBackup_c
       INTO local;
      IF (findDatafileBackup_c%NOTFOUND) THEN
         CLOSE findDatafileBackup_c;
         deb(DEB_EXIT, 'with no more records');
         RAISE no_data_found;
      END IF;
   ELSE
      deb(DEB_EXIT, 'with error 20204');
      raise_application_error(-20204, 'Translation not started');
   END IF;
 
--
--
   IF (anyDevice = FALSE# AND
       isDeviceTypeAllocated(local.deviceType_con) = FALSE#) THEN
      GOTO nextRow;
   END IF;
 
   rcvRec := local;                             -- set OUT mode arg
   deb(DEB_EXIT);
END listGetProxyDataFile;
 
--
 
--
FUNCTION listGetProxyDataFile(
   xdf_key            OUT number
  ,recid              OUT number
  ,stamp              OUT number
  ,status             OUT varchar2
  ,handle             OUT varchar2
  ,completion_time    OUT date
  ,checkpoint_change# OUT number
  ,checkpoint_time    OUT date)
RETURN number IS
   rcvRec             rcvRec_t;
BEGIN
   deb(DEB_ENTER, 'listGetProxyDataFile815');
   listGetProxyDataFile(rcvRec);
 
   xdf_key              := rcvRec.key_con;
   recid                := rcvRec.recid_con;
   stamp                := rcvRec.stamp_con;
   status               := rcvRec.status_con;
   handle               := rcvRec.fileName_con;
   completion_time      := rcvRec.compTime_con;
   checkpoint_change#   := rcvRec.toSCN_act;
   checkpoint_time      := rcvRec.toTime_act;
   deb(DEB_EXIT, 'with: TRUE#');
   RETURN TRUE#;
EXCEPTION
   WHEN no_data_found THEN
      deb(DEB_EXIT, 'with: FALSE#');
      RETURN FALSE#;
END listGetProxyDataFile;
 
--
PROCEDURE listTranslateProxyArchivedLog(
   thread#           IN number
  ,sequence#         IN number
  ,first_change#     IN number
  ,tag               IN varchar2        DEFAULT NULL
  ,handle_pattern    IN varchar2        DEFAULT NULL
  ,completedAfter    IN date            DEFAULT NULL
  ,completedBefore   IN date            DEFAULT NULL
  ,statusMask        IN binary_integer  DEFAULT
                                        BSavailable+BSunavailable+BSexpired)
IS
   currentIncarnation number;
BEGIN
   deb(DEB_ENTER, 'listTranslateProxyArchivedLog');
 
   IF (allIncarnations = TRUE#) THEN
      currentIncarnation := FALSE#;             -- don't care about dbinc_key
   ELSE
      currentIncarnation := TRUE#;
   END IF;
 
   deb(DEB_OPEN, 'findArcLogBackup');
   OPEN findArcLogBackup(sourcemask         => proxyCopy_con_t,
                         currentIncarnation => currentIncarnation,
                         thread             => thread#,
                         sequence           => sequence#,
                         lowSCN             => first_change#,
                         tag                => tag,
                         pattern            => handle_pattern,
                         completedAfter     => completedAfter,
                         completedBefore    => completedBefore,
                         statusMask         => statusMask);
   deb(DEB_EXIT);
END listTranslateProxyArchivedLog;
 
--
PROCEDURE listGetProxyArchivedLog(
   rcvRec OUT NOCOPY rcvRec_t)
IS
   local rcvRec_t;
BEGIN
   deb(DEB_ENTER, 'listGetProxyArchivedLog');
 
--
   IF (guidQualifier IS NOT NULL) THEN
      IF (findArcLogBackup%ISOPEN) THEN
         CLOSE findArcLogBackup;
      END IF;
      deb(DEB_EXIT, 'guid not valid for archivelog');
      RAISE no_data_found;
   END IF;
 
<<nextRow>>
 
   FETCH findArcLogBackup
   INTO local;
   IF (findArcLogBackup%NOTFOUND) THEN
      CLOSE findArcLogBackup;
      deb(DEB_EXIT, 'with no more records');
      RAISE no_data_found;
   END IF;
 
--
--
   IF (anyDevice = FALSE# AND
       isDeviceTypeAllocated(local.deviceType_con) = FALSE#) THEN
      GOTO nextRow;
   END IF;
 
   rcvRec := local;                             -- set OUT mode arg
   deb(DEB_EXIT);
END listGetProxyArchivedLog;
 
--
--
--
 
--
PROCEDURE listTranslateDBIncarnation(
   db_name       IN varchar2 DEFAULT NULL,
   all_databases IN number DEFAULT 0)
IS
BEGIN
   deb(DEB_ENTER, 'listTranslateDBIncarnation');
   IF (ldbi%isopen) THEN
      CLOSE ldbi;
   END IF;
   deb(DEB_OPEN, 'ldbi');
   OPEN ldbi(upper(db_name), all_databases);
   deb(DEB_EXIT);
END listTranslateDBIncarnation;
 
--
FUNCTION listGetDBIncarnation(
   db_key            OUT number
  ,dbinc_key         OUT number
  ,db_name           OUT varchar2
  ,db_id             OUT number
  ,current_inc       OUT varchar2
  ,resetlogs_change# OUT number
  ,resetlogs_time    OUT date
  ,dbinc_status      OUT varchar2)
RETURN number
IS
BEGIN
   deb(DEB_ENTER, 'listGetDBIncarnation');
   FETCH ldbi
    INTO db_key, dbinc_key, db_name, db_id, current_inc,
         resetlogs_change#, resetlogs_time, dbinc_status;
   IF (ldbi%found) THEN
      deb(DEB_EXIT, 'with: TRUE#');
      RETURN TRUE#;
   ELSE
      CLOSE ldbi;
      deb(DEB_EXIT, 'with: FALSE#');
      RETURN FALSE#;
   END IF;
   deb(DEB_EXIT);
END listGetDBIncarnation;
 
--
FUNCTION listGetDBIncarnation(
   db_key            OUT number
  ,dbinc_key         OUT number
  ,db_name           OUT varchar2
  ,db_id             OUT number
  ,current_inc       OUT varchar2
  ,resetlogs_change# OUT number
  ,resetlogs_time    OUT date)
RETURN number
IS
  dbinc_status varchar2(9);
BEGIN
  RETURN listGetDBIncarnation(db_key, dbinc_key, db_name, db_id, current_inc,
                              resetlogs_change#, resetlogs_time, dbinc_status);
END listGetDBIncarnation;
 
 
--
--
--
 
--
PROCEDURE listTranslateDBSite(
   db_name      IN varchar2 DEFAULT NULL,
   alldbs       IN binary_integer DEFAULT 1)
IS
BEGIN
   deb(DEB_ENTER, 'listTranslateDBSite');
   IF (lnni%isopen) THEN
      CLOSE lnni;
   END IF;
   deb(DEB_OPEN, 'lnni');
   OPEN lnni(db_name, alldbs);
   deb(DEB_EXIT);
END listTranslateDBSite;
 
--
FUNCTION listGetDBSite(
   db_key            OUT number
  ,db_id             OUT number
  ,db_name           OUT varchar2
  ,db_role           OUT varchar2
  ,db_unique_name    OUT varchar2)
RETURN number
IS
BEGIN
   deb(DEB_ENTER, 'listGetDBSite');
   FETCH lnni
    INTO db_key, db_id, db_name, db_role, db_unique_name;
 
   deb(DEB_PRINT, 'site name =['||db_unique_name||']');
   IF (lnni%found) THEN
      deb(DEB_EXIT, 'with: TRUE#');
      RETURN TRUE#;
   ELSE
      CLOSE lnni;
      deb(DEB_EXIT, 'with: FALSE#');
      RETURN FALSE#;
   END IF;
   deb(DEB_EXIT);
END listGetDBSite;
 
--
--
--
 
--
PROCEDURE listRollbackSegTableSpace
IS
BEGIN
   deb(DEB_ENTER, 'listRollbackSegTableSpace');
--
   IF (lrtbs%ISOPEN) THEN
      CLOSE lrtbs;
   END IF;
 
   deb(DEB_OPEN, 'lrtbs');
   OPEN lrtbs;
--
--
   deb(DEB_EXIT);
END listRollbackSegTableSpace;
 
--
FUNCTION listGetTableSpace(
   ts#               OUT number
  ,ts_name           OUT varchar2)
RETURN number IS
  pdbname  varchar2(128);
BEGIN
  RETURN listGetTableSpace(ts#, ts_name, pdbname);
END listGetTableSpace;
 
FUNCTION listGetTableSpace(
   ts#               OUT number
  ,ts_name           OUT varchar2
  ,pdbname          OUT varchar2)
RETURN number IS
BEGIN
   deb(DEB_ENTER, 'listGetTableSpace');
--
   FETCH lrtbs
    INTO ts#, ts_name, pdbname;
 
   IF (lrtbs%FOUND) THEN
      deb(DEB_EXIT, 'with: TRUE#');
      RETURN TRUE#;
   ELSE
      CLOSE lrtbs;
      deb(DEB_EXIT, 'with: FALSE#');
      RETURN FALSE#;
   END IF;
--
--
   deb(DEB_EXIT);
END listGetTableSpace;
 
--
--
--
 
--
PROCEDURE getIncrementalScn(
   first        IN  boolean                  -- open the cursor if this is TRUE
  ,file#        IN  number
  ,create_scn   IN  number
  ,reset_scn    IN  number
  ,reset_time   IN  date
  ,incr_level   IN  number
  ,cumulative   IN  number
  ,rcvRec       OUT NOCOPY rcvRec_t
  ,sourcemask   IN  number    DEFAULT NULL
  ,tag          IN  varchar2  DEFAULT NULL
  ,pluginSCN    IN  number    DEFAULT 0
  ,keep         IN  boolean   DEFAULT NULL)
IS
   ilevel                number;
   local                 rcvRec_t;
   validRec              validBackupSetRec_t;
   usable_incr           rcvRec_t;
   available_fromSCN_act number;
   pdbId                 number;
   cleanSCN              number;
BEGIN
   deb(DEB_ENTER, 'getIncrementalScn');
 
   IF (incr_level not in (1,2,3,4) OR incr_level is NULL) THEN
      raise_application_error(-20270, 'invalid incremental level');
   END IF;
   IF (cumulative not in (0,1) OR cumulative is NULL) THEN
      raise_application_error(-20271, 'invalid cumulative option');
   END IF;
 
--
 
--
--
--
--
--
 
--
--
--
 
   IF (cumulative = TRUE#) THEN
      ilevel := incr_level - 1;         -- Consider only higher level backups
   ELSE
      ilevel := incr_level;
   END IF;
 
--
   IF (file# IS NOT NULL) THEN
      setDfTransClause(fno => file#);
   END IF;
 
   IF first THEN
      IF (findDatafileBackup_c%ISOPEN) THEN
         CLOSE findDatafileBackup_c;
      END IF;
 
      getDatafileBackupLast.type_con := NULL; -- clear the last backup record
 
--
      cacheBsRecTable.hint := redundantHint;
 
--
      OPEN findDatafileBackup_c(
        sourcemask      => sourcemask,
        fno             => file#,
        crescn          => create_scn,
        reset_scn       => nvl(reset_scn, this_reset_scn),
        reset_time      => nvl(reset_time, this_reset_time),
        level           => ilevel,
        statusMask      => BSavailable,
        tag             => tag,
        onlytc          => TRUE#,
        pluginSCN       => pluginSCN,
        allowCumuLevelN => TRUE#);
   END IF;
 
   IF (NOT findDatafileBackup_c%ISOPEN) THEN
      raise_application_error(-20272, 'cannot take incremental backup');
   END IF;
 
   LOOP
   <<nextRow>>
      FETCH findDatafileBackup_c
       INTO local;
 
      IF (findDatafileBackup_c%NOTFOUND) THEN
         deb(DEB_PRINT, 'closing cursor');
         CLOSE findDatafileBackup_c;
         cacheBsRecTable.hint := noHint;
         IF (file# is NOT NULL) THEN
--
            deb(DEB_EXIT, 'with: cannot take incr backup');
            raise_application_error(-20272, 'cannot take incremental backup');
         ELSE
            deb(DEB_EXIT, 'with: no data found');
            raise no_data_found;        -- no more datafile backups
         END IF;
      END IF;
 
--
--
--
--
--
      IF (keep IS NOT NULL AND                       -- NULL means 10g client
          ((local.keep_options != 0 AND NOT keep) OR -- local_keep and not keep
           (local.keep_options = 0 AND keep))) THEN  -- not local_keep and keep
         deb(DEB_PRINT, 'Keep does not match for ' || local.key_con ||
                        ' completed at ' ||
                        to_char(local.compTime_con, 'DD-MON-YY HH24:MI:SS'));
         GOTO nextRow;                          -- keep attributes do not match
      END IF;
 
      IF (available_fromSCN_act IS NULL AND
          getDatafileBackupLast.type_con IS NOT NULL AND
          getDatafileBackupLast.dfNumber_obj = local.dfNumber_obj) THEN
        deb(DEB_PRINT, 'already returned incremental scn for file# ' ||
                        local.dfNumber_obj);
        GOTO nextRow;    -- this is a duplicate of what we returned earlier
      END IF;
 
--
--
--
      IF (available_fromSCN_act IS NOT NULL AND
          (usable_incr.dfNumber_obj <> local.dfNumber_obj OR
           (usable_incr.dfNumber_obj = local.dfNumber_obj AND
            usable_incr.dfCreationSCN_obj <> local.dfCreationSCN_obj))) THEN
          deb(DEB_PRINT, 'no level 0 found for this file# ' ||
                         usable_incr.dfNumber_obj || ', creation_scn '||
                         usable_incr.dfCreationSCN_obj);
          usable_incr := NULL;
          available_fromSCN_act := NULL;
      END IF;
 
      pdbId := translatePdbFile(local.dfNumber_obj, cleanSCN);
      IF (CheckRecAction(local, pdbId, cleanSCN) = action_SKIP) THEN
        deb(DEB_PRINT, 'on orphan branch');
        GOTO nextRow;    -- this action belongs to orphan branch
      END IF;
 
      IF (usable_incr.dfNumber_obj = local.dfNumber_obj AND
          usable_incr.dfCreationSCN_obj = local.dfCreationSCN_obj AND
          local.fromSCN_act > 0 AND
          available_fromSCN_act < local.fromSCN_act) THEN
          deb(DEB_PRINT, 'overlapping incremental found for file# ' ||
                         usable_incr.dfNumber_obj || ', creation_scn '||
                         usable_incr.dfCreationSCN_obj);
          GOTO nextRow;                            -- overlapping incremental
      END IF;
 
      IF (local.type_con = backupSet_con_t) THEN
--
--
         IF (validateBackupSet(backupSetRec           => local,
                               tag                    => tag,
                               tagMatchRequired       => TRUE,
                               checkDeviceIsAllocated => FALSE,
                               availableMask          => BSavailable,
                               validRec               => validRec)
                = dbms_rcvman.UNAVAILABLE) THEN
            deb(DEB_PRINT, 'incremental is unavailable');
            GOTO nextRow; -- can't create an incr based on unavail backup
         END IF;
      END IF;
 
--
--
--
--
--
--
--
      IF (available_fromSCN_act IS NULL OR
          (usable_incr.dfNumber_obj = local.dfNumber_obj AND
           usable_incr.dfCreationSCN_obj = local.dfCreationSCN_obj AND
           local.toSCN_act < available_fromSCN_act)) THEN
         IF (available_fromSCN_act IS NULL) THEN
            deb(DEB_PRINT, 'available_fromSCN_act set to ' ||
                           available_fromSCN_act || ' for file# ' ||
                           local.dfNumber_obj || ', creation_scn '||
                           local.dfCreationSCN_obj);
         ELSE
            deb(DEB_PRINT, 'broken chain, available_fromSCN_act set to ' ||
                           available_fromSCN_act || ' for file ' ||
                           local.dfNumber_obj || ', creation_scn '||
                           local.dfCreationSCN_obj);
         END IF;
         usable_incr := local;
         available_fromSCN_act := local.fromSCN_act;
      END IF;
 
--
--
--
      IF (usable_incr.dfNumber_obj = local.dfNumber_obj AND
          usable_incr.dfCreationSCN_obj = local.dfCreationSCN_obj AND
          local.toSCN_act >= available_fromSCN_act AND
          local.fromSCN_act < available_fromSCN_act) THEN
         available_fromSCN_act := local.fromSCN_act;
         deb(DEB_PRINT, 'available_fromSCN_act moved to ' ||
                        available_fromSCN_act || ' for file# ' ||
                        local.dfNumber_obj || ', creation_scn '||
                        local.dfCreationSCN_obj);
      END IF;
 
--
--
      IF (available_fromSCN_act != usable_incr.dfCreationSCN_obj AND
          available_fromSCN_act > 0) THEN
         deb(DEB_PRINT, 'need more incrementals to validate chain');
         GOTO nextRow;
      END IF;
 
 
      If (available_fromSCN_act = usable_incr.dfCreationSCN_obj OR
          available_fromSCN_act = 0) THEN
         deb(DEB_PRINT, 'validated incremental to level 0, incremental scn=' ||
                        usable_incr.toSCN_act || 'for file ' ||
                        usable_incr.dfNumber_obj);
         rcvRec := usable_incr;
      ELSE
         rcvRec := local;
         deb(DEB_PRINT, 'using level0 proxy/copy, incremental scn=' ||
                        local.toSCN_act || ' for file ' ||
                        local.dfNumber_obj);
      END IF;
 
      getDatafileBackupLast := rcvRec;   -- remember the last record returned
 
      deb(DEB_EXIT, 'with: valid record ');
      EXIT;   -- valid record. Create Incremental based on this SCN
   END LOOP;
EXCEPTION
   WHEN others THEN
      cacheBsRecTable.hint := noHint;
      deb(DEB_PRINT, 'caught an exception during getIncrementalScn');
      deb(DEB_EXIT, substr(sqlerrm, 1, 512));
      raise;
END getIncrementalScn;
 
--
FUNCTION getIncrementalScn(
   file#        IN number
  ,create_scn   IN number
  ,reset_scn    IN number
  ,reset_time   IN date
  ,incr_level   IN number
  ,cumulative   IN number
  ,sourcemask   IN number    DEFAULT NULL
  ,tag          IN varchar2  DEFAULT NULL
  ,pluginSCN    IN number    DEFAULT 0)
RETURN number IS
  rcvRec    rcvRec_t;
BEGIN
   getIncrementalScn(
      first        => TRUE
     ,file#        => file#
     ,create_scn   => create_scn
     ,reset_scn    => reset_scn
     ,reset_time   => reset_time
     ,incr_level   => incr_level
     ,cumulative   => cumulative
     ,rcvRec       => rcvRec
     ,sourcemask   => sourcemask
     ,tag          => tag
     ,pluginSCN    => pluginSCN);
 
   IF (findDatafileBackup_c%ISOPEN) THEN
      CLOSE findDatafileBackup_c; -- close the one opened in getIncrementalScn
   END IF;
 
   RETURN rcvRec.toSCN_act;
END getIncrementalScn;
 
--
--
--
 
--
PROCEDURE setComputeRecoveryActionMasks(
   containerMask        IN number
  ,actionMask           IN number
  ,allRecords           IN number
  ,availableMask        IN binary_integer
  ,fullBackups          IN number DEFAULT NULL)
IS
BEGIN
   deb(DEB_ENTER, 'setComputeRecoveryActionMasks');
   IF (allRecords = FALSE# AND fullBackups IS NULL) THEN
      computeRA_fullBackups := 1;
   ELSE
      computeRA_fullBackups := fullBackups;
   END IF;
   getRA_containerMask      := containerMask;
   getRA_actionMask         := actionMask;
   computeRA_allRecords     := allRecords;
   computeRA_availableMask  := availableMask;
 
--
--
--
--
   IF (restoreSource IS NULL) THEN
      restoreSource := proxyCopy_con_t + imageCopy_con_t + backupSet_con_t;
 
      IF (bitand(getRA_containerMask, proxyCopy_con_t) = 0) THEN
         restoreSource := restoreSource - proxyCopy_con_t;
      END IF;
      IF (bitand(getRA_containerMask, imageCopy_con_t) = 0) THEN
         restoreSource := restoreSource - imageCopy_con_t;
      END IF;
      IF (bitand(getRA_containerMask, backupSet_con_t) = 0) THEn
         restoreSource := restoreSource - backupSet_con_t;
      END IF;
 
      IF (restoreSource = 0) THEN
         restoreSource := NULL;
      END IF;
   END IF;
 
   deb(DEB_EXIT);
END setComputeRecoveryActionMasks;
 
--
--
PROCEDURE setComputeRecoveryActionMasks(
   containerMask        IN number
  ,actionMask           IN number
  ,allRecords           IN number)
IS
BEGIN
   deb(DEB_ENTER, 'setComputeRecoveryActionMasks816');
   setComputeRecoveryActionMasks(
      containerMask  => containerMask,
      actionMask     => actionMask,
      allRecords     => allRecords,
      availableMask  => dbms_rcvman.BSavailable,
      fullBackups    => to_number(null));
   deb(DEB_EXIT);
END setComputeRecoveryActionMasks;
 
--
--
PROCEDURE setRAflags(
   kindMask    IN number
  ,allRecords  IN boolean)
IS
   containerMask        number;
   actionMask           number;
   allRecs              number;
BEGIN
   deb(DEB_ENTER, 'setRAflags');
 
--
 
   containerMask := 0;
 
   IF (bitand(kindMask, implicitOfflRange + cleanRange + applyOfflRange) > 0)
   THEN
      containerMask := containerMask + offlineRangeRec_con_t;
   END IF;
 
   IF (bitand(kindMask, dfCopy) > 0) THEN
      containerMask := containerMask + imageCopy_con_t;
   END IF;
 
   IF (bitand(kindMask, buSet + applyIncremental) > 0) THEN
      containerMask := containerMask + backupSet_con_t;
   END IF;
 
   IF (bitand(kindMask, proxyFull) > 0) THEN
      containerMask := containerMask + proxyCopy_con_t;
   END IF;
 
--
 
   actionMask := 0;
 
   IF (bitand(kindMask, dfCopy + ProxyFull + buSet) > 0) THEN
      actionMask := actionMask + full_act_t;
   END IF;
 
   IF (bitand(kindMask, applyIncremental) > 0) THEN
      actionMask := actionMask + incremental_act_t;
   END IF;
 
   IF (bitand(kindMask, redo) > 0) THEN
      actionMask := actionMask + redo_act_t;
   END IF;
 
   IF (bitand(kindMask, implicitOfflRange) > 0) THEN
      actionMask := actionMask + implicitRange_act_t;
   END IF;
 
   IF (bitand(kindMask, cleanRange) > 0) THEN
      actionMask := actionMask + cleanRange_act_t;
   END IF;
 
   IF (bitand(kindMask, applyOfflRange) > 0) THEN
      actionMask := actionMask + offlineRange_act_t;
   END IF;
 
   IF (allRecords) THEN
      allRecs := TRUE#;
   ELSE
      allRecs := FALSE#;
   END IF;
 
   deb(DEB_PRINT, 'setRAflags kindMask=' || to_char(kindMask) ||
       ' containerMask=' || to_char(containerMask) ||
       ' actionMask=' || to_char(actionMask));
 
   setComputeRecoveryActionMasks(containerMask, actionMask, allRecs);
   deb(DEB_EXIT);
END setRAflags;
 
--
FUNCTION getRecoveryAction(
   action OUT NOCOPY rcvRec_t)
RETURN binary_integer IS
   redoAction rcvRec_t;
   local      rcvRec_t;
   top        rcvRec_t;
BEGIN
   deb(DEB_ENTER, 'getRecoveryAction');
<<getNext>>
   IF (rcvRecStack.count = 0) THEN
--
--
--
--
--
--
--
--
--
--
--
      deb(DEB_EXIT, 'with no more records');
      raise no_data_found;
   END IF;
 
   rcvRecPop(local);
 
--
   IF (not isValidAction(local)) THEN
     IF (debug) THEN
       printRcvRec(local);
     END IF;
     goto getNext;
   END IF;
 
<<merge_actions>>
   IF (rcvRecStack.count > 0) THEN
--
--
--
      rcvRecTop(top);
      IF (local.type_act = redo_act_t AND
          top.type_act = redo_act_t) THEN
--
--
--
         redoAction := local;
         rcvRecPop(local);
         local.fromSCN_act := redoAction.fromSCN_act;
         GOTO merge_actions;
      END IF;
      action := local;
      rcvRec_last := local;
      deb(DEB_EXIT, 'with: TRUE#');
      RETURN TRUE#;                     -- more actions to return yet
   ELSE
      action := local;
      rcvRec_last := local;
      deb(DEB_EXIT, 'with: FALSE#');
      RETURN FALSE#;                    -- this is the last action
   END IF;
 
END getRecoveryAction;
 
--
 
--
FUNCTION getRecoveryAction(
   kind       OUT number
  ,set_stamp  OUT number
  ,set_count  OUT number
  ,recid      OUT number
  ,stamp      OUT number
  ,fname      OUT varchar2
  ,blocksize  OUT number
  ,blocks     OUT number
  ,devtype    OUT varchar2
  ,from_scn   OUT number
  ,to_scn     OUT number
  ,to_time    OUT date
  ,rlgscn     OUT number
  ,rlgtime    OUT date
  ,cfcretime  OUT date
  ,dbinc_key  OUT number)
RETURN binary_integer IS
   rcvRec     rcvRec_t;
   rc         binary_integer;
BEGIN
   deb(DEB_ENTER, 'getRecoveryAction815');
   rc := getRecoveryAction(rcvRec);
 
   IF (rcvRec.type_con = offlineRangeRec_con_t) THEN
      IF (rcvRec.type_act = offlineRange_act_t) THEN
         kind := applyOfflRange;
      ELSIF (rcvRec.type_act = cleanRange_act_t) THEN
         kind := cleanRange;
      ELSIF (rcvRec.type_act = implicitRange_act_t) THEN
         kind := implicitOfflRange;
      ELSE
         deb(DEB_PRINT, 'cannot convert type_con=' || to_char(rcvRec.type_con) ||
             ' type_act=' || to_char(rcvRec.type_act) ||
             ' to recovery action kind');
         deb(DEB_EXIT, 'with error 20999');
         raise_application_error(-20999, 'internal error: getRecoveryAction');
      END IF;
   ELSIF (rcvRec.type_con = backupSet_con_t) THEN
      IF (rcvRec.type_act = full_act_t) THEN
         kind := buSet;
      ELSE
         kind := applyIncremental;
      END IF;
   ELSIF (rcvRec.type_con = proxyCopy_con_t) THEN
      kind := proxyFull;
   ELSIF (rcvRec.type_con = imageCopy_con_t) THEN
      kind := dfCopy;
   ELSIF (rcvRec.type_con IS NULL) THEN
      IF (rcvRec.type_act = redo_act_t) THEN
         kind := redo;
      END IF;
   END IF;
 
   deb(DEB_PRINT, 'getRecoveryAction: kind=' || nvl(to_char(kind), 'null'));
   rcvRecConvert(rcvRec);                       -- get rid of nulls
   IF (debug) THEN
      printRcvRec(rcvRec);
   END IF;
 
   set_stamp := rcvRec.setStamp_con;
   set_count := rcvRec.setCount_con;
   IF (rcvRec.type_con = backupSet_con_t) THEN
      recid     := rcvRec.bsRecid_con;
      stamp     := rcvRec.bsStamp_con;
   ELSE
      recid     := rcvRec.recid_con;
      stamp     := rcvRec.stamp_con;
   END IF;
   fname     := rcvRec.fileName_con;
   blocksize := rcvRec.blockSize_con;
   blocks    := rcvRec.blocks_con;
   devtype   := rcvRec.deviceType_con;
   from_scn  := rcvRec.fromSCN_act;
   to_scn    := rcvRec.toSCN_act;
   to_time   := rcvRec.toTime_act;              -- null OK
   rlgscn    := rcvRec.rlgSCN_act;
   rlgtime   := rcvRec.rlgTime_act;
   cfcretime := rcvRec.cfCreationTime_con;      -- null OK
   dbinc_key := rcvRec.dbincKey_act;            -- null OK
 
   deb(DEB_EXIT, 'with: '||to_char(rc));
   RETURN rc;
END;
 
--
PROCEDURE printRecoveryActions
IS
   action rcvRec_t;
   rc     number;
BEGIN
   IF (not debug) THEN
      return;
   END IF;
 
   deb(DEB_PRINT, '===== ' || to_char(rcvRecStack.count) ||
       ' actions stacked =====');
 
   IF (rcvRecStack.count = 0) THEN
      return;
   END IF;
 
   LOOP
      rc := getRecoveryAction(action);
      printRcvRec(action);
      EXIT WHEN rc = FALSE#;
   END LOOP;
END printRecoveryActions;
 
--
PROCEDURE trimRecoveryActions(
   maxActions           IN number
  ,containerMask        IN number
  ,actionMask           IN number)
IS
   n                    number;
BEGIN
   deb(DEB_ENTER, 'trimRecoveryActions[procedure]');
   n := trimRecoveryActions(maxActions, containerMask, actionMask);
   deb(DEB_PRINT, 'trimRecoveryActions[procedure] returned '||n);
   deb(DEB_EXIT);
END trimRecoveryActions;
 
--
--
--
 
--
PROCEDURE reportTranslateDFDel
IS
BEGIN
   deb(DEB_ENTER, 'reportTranslateDFDel');
   IF (rddf%isopen) THEN
      CLOSE rddf;
   END IF;
   deb(DEB_OPEN, 'rddf');
   OPEN rddf;
   deb(DEB_EXIT);
END reportTranslateDFDel;
 
--
 
--
FUNCTION reportGetDFDel(
   file#               OUT number
  ,filetype            OUT number
  ,checkpoint_change#  OUT number
  ,checkpoint_time     OUT date
  ,resetlogs_change#   OUT number
  ,resetlogs_time      OUT date
  ,incremental_change# OUT number
  ,fuzzy_change#       OUT number
  ,recid               OUT number
  ,stamp               OUT number
  ,fname               OUT varchar2
  ,restorable          OUT number)
RETURN number IS
   rc              number;
   mytype          number;
   key             number;
   completion_time date;
BEGIN
   deb(DEB_ENTER, 'reportGetDFDel80');
   <<get_next>>
   rc := reportGetDFDel( file#
                        ,mytype
                        ,checkpoint_change#
                        ,checkpoint_time
                        ,resetlogs_change#
                        ,resetlogs_time
                        ,incremental_change#
                        ,fuzzy_change#
                        ,recid
                        ,stamp
                        ,fname
                        ,restorable
                        ,key
                        ,completion_time);
   IF (rc = TRUE#) THEN
      IF (mytype = PROXY) THEN
         GOTO get_next;
      END IF;
      filetype := mytype;
   END IF;
   deb(DEB_EXIT, 'with: '||to_char(rc));
   RETURN rc;
END reportGetDFDel;
 
--
--
--
--
PROCEDURE getConfig(
   conf#          OUT    number
  ,name           IN OUT varchar2
  ,value          IN OUT varchar2
  ,first          IN     boolean)
IS
   eof          boolean := FALSE;
   conf_exist   number  := 0;
   primary_db_unique_name varchar2(512); /* node.db_unique_name%TYPE */
BEGIN
 
   IF (first) THEN
      IF (findConfig_c%ISOPEN) THEN
         CLOSE findConfig_c;
      END IF;
 
      OPEN cntConfig_c;
      FETCH cntConfig_c INTO conf_exist;
      CLOSE cntConfig_c;
      IF conf_exist > 0 THEN
         IF user_db_unique_name is not null THEN
            deb(DEB_PRINT, 'getConfig: configurations exists for user site');
            OPEN findConfig_c(name, value, user_db_unique_name);
         ELSE
            deb(DEB_PRINT, 'getConfig: configurations exists for this site');
            OPEN findConfig_c(name, value, this_db_unique_name);
         END IF;
      ELSE
         OPEN getPrimarySite_c;
         FETCH getPrimarySite_c INTO primary_db_unique_name;
         IF getPrimarySite_c%NOTFOUND THEN
            deb(DEB_PRINT, 'getConfig: no/multiple primary/site conf');
            OPEN findConfig_c(name, value, NULL);
         ELSE
            deb(DEB_PRINT, 'getConfig: using primary configurations');
            OPEN findConfig_c(name, value, primary_db_unique_name);
         END IF;
         CLOSE getPrimarySite_c;
      END IF;
   END IF;
 
   FETCH findConfig_c INTO conf#, name, value;
 
   IF (findConfig_c%NOTFOUND) THEN
      eof := TRUE;
      CLOSE findConfig_c;
   END IF;
 
   IF (eof) THEN                                --- if end of fetch
     RAISE no_data_found;
   END IF;
 
END getConfig;
 
--
--
--
--
 
PROCEDURE bmrAddCorruptTable(
   dfnumber    OUT number
  ,blknumber   OUT number
  ,range       OUT number
  ,first       IN  boolean)
IS
   eof    boolean := FALSE;
BEGIN
 
   IF (first) THEN
      IF (translateDatabaseCorruption_c%ISOPEN) THEN
         CLOSE translateDatabaseCorruption_c;
      END IF;
      OPEN translateDatabaseCorruption_c(dfnumber => NULL);
   END IF;
 
   FETCH translateDatabaseCorruption_c INTO dfnumber, blknumber, range;
 
   IF (translateDatabaseCorruption_c%NOTFOUND) THEN
      eof := TRUE;
      CLOSE translateDatabaseCorruption_c;
   END IF;
 
   IF (eof) THEN                                --- if end of fetch
     RAISE no_data_found;
   END IF;
 
END bmrAddCorruptTable;
 
--
 
--
--
--
 
--
--
 
--
FUNCTION getPackageVersion
RETURN varchar2 IS
BEGIN
   deb(DEB_ENTER, 'getPackageVersion');
   IF (versionCounter > versionMaxIndex) THEN
      versionCounter := 1;
      deb(DEB_EXIT, 'with: NULL');
      RETURN NULL;
   END IF;
   versionCounter := versionCounter + 1;
   deb(DEB_EXIT, 'with: '||versionList(versionCounter - 1));
   RETURN versionList(versionCounter - 1);
END getPackageVersion;
 
FUNCTION isStatusMatch(status      IN VARCHAR2,
                       mask        IN NUMBER) RETURN NUMBER IS
BEGIN
--
--
--
--
   IF (bitand(mask, BSavailable)     != 0 AND status = 'A') OR
      (bitand(mask, BSunavailable)   != 0 AND status = 'U') OR
      (bitand(mask, BSdeleted)       != 0 AND status = 'D') OR
      (bitand(mask, BSexpired)       != 0 AND status = 'X') THEN
      RETURN TRUE#;
   ELSE
      RETURN FALSE#;
   END IF;
END isStatusMatch;
 
--
FUNCTION isBackupTypeMatch(btype       IN VARCHAR2,
                           mask        IN binary_integer) RETURN NUMBER IS
BEGIN
   IF (bitand(mask, BSdatafile_full) !=0  AND  btype = 'D') OR
      (bitand(mask, BSdatafile_incr) !=0  AND  btype = 'I') OR
      (bitand(mask, BSarchivelog)    !=0  AND  btype = 'L') THEN
      RETURN TRUE#;
   ELSE
      RETURN FALSE#;
   END IF;
END isBackupTypeMatch;
 
--
PROCEDURE setRcvRecBackupAge(age IN number)
IS
BEGIN
   rcvRecBackupAge := age;
   deb(DEB_PRINT, 'rcvRecBackupAge= '  || rcvRecBackupAge);
   resetthisBackupAge;
END setRcvRecBackupAge;
 
--
PROCEDURE resetthisBackupAge
IS
BEGIN
   thisBackupAge := 0;
   deb(DEB_PRINT, 'thisBackupAge= '  || thisBackupAge);
END resetthisBackupAge;
 
--
PROCEDURE printLbRec(
   lbRec IN lbRec_t)
IS
BEGIN
 
  deb(DEB_ENTER, 'printLbRec');
  deb(DEB_IN, 'fetch backup_type:  '||lbRec.backup_type);
  deb(DEB_IN, '      file_type:    '||lbRec.file_type);
  deb(DEB_IN, '      pkey:         '||lbRec.pkey);
  deb(DEB_IN, '      recid:        '||lbRec.recid);
  deb(DEB_IN, '      stamp:        '||lbRec.stamp);
  deb(DEB_IN, '      is_rdf:       '||lbRec.is_rdf);
  IF (lbRec.file_type = datafile_txt)
  THEN
    deb(DEB_IN, '      df_file#:     '||lbRec.df_file#);
    deb(DEB_IN, '      df_ts#:       '||lbRec.df_ts#);
    deb(DEB_IN, '      df_plugin_change#: '||lbRec.df_plugin_change#);
    deb(DEB_IN, '      df_foreidn_dbid:   '||lbRec.df_foreign_dbid);
    deb(DEB_IN, '      df_creation_change#:'||lbRec.df_creation_change#);
    deb(DEB_IN, '      df_checkpoint_change#:'||lbRec.df_checkpoint_change#);
    deb(DEB_IN, '      df_incremental_change#:'||
                       nvl(to_char(lbRec.df_incremental_change#), 'NULL'));
  END IF;
  IF (lbRec.file_type = archivedlog_txt)
  THEN
    deb(DEB_IN, '      rl_thread#:   '||lbRec.rl_thread#);
    deb(DEB_IN, '      rl_sequence#: '||lbRec.rl_sequence#);
    deb(DEB_IN, '      rl_next_change#:'||lbRec.rl_next_change#);
  END IF;
  IF (lbRec.backup_type = backupset_txt)
  THEN
    deb(DEB_IN, '      bs_key:       '||lbRec.bs_key);
    deb(DEB_IN, '      bs_stamp:     '||lbRec.bs_stamp);
    deb(DEB_IN, '      bs_count:     '||lbRec.bs_count);
    deb(DEB_IN, '      bs_incr_type: '||lbRec.bs_incr_type);
  END IF;
  IF (lbRec.file_type = piece_txt)
  THEN
    deb(DEB_IN, '      bp_piece#:    '||lbRec.bp_piece#);
    deb(DEB_IN, '      bp_copy#:     '||lbRec.bp_copy#);
    deb(DEB_IN, '      status:       '||lbRec.status);
    deb(DEB_IN, '      device_type:  '||lbRec.device_type);
    deb(DEB_IN, '      tag:          '||lbRec.tag);
  END IF;
  deb(DEB_EXIT, 'ok');
 
EXCEPTION
  WHEN OTHERS THEN
    deb(DEB_EXIT, 'with exception: '||substr(sqlerrm, 1, 512));
    RETURN;
END printLbRec;
 
--
--
FUNCTION listBackupInMKS(lbDfRecTabUs      IN lbDfRecTab_t
                        ,lbRec             IN lbRec_t
                        ,maxDfNumber       IN number
                        ,forIncr           IN boolean)
RETURN BOOLEAN IS
   i          number;
   min_scn    number;
   min_rlgscn number;
BEGIN
--
--
--
   i := lbRec.df_file#;
   <<loop_dfRecTab>>
   LOOP
      IF (NOT lbDfRecTabUs.exists(i)) THEN
         deb(DEB_PRINT,'Dropped datafile: df_file#=' || lbRec.df_file#);
         IF (lbRec.df_ckp_mod_time < untilTime OR
             (untilTime IS NULL AND
              lbRec.df_checkpoint_change# <= untilSCN)) THEN
            deb(DEB_PRINT,'Outside untilTime/untilSCN');
            RETURN FALSE;
         ELSE
            deb(DEB_PRINT,'Inside untilTime/untilSCN');
            RETURN TRUE;
         END IF;
      END IF;
      IF (lbDfRecTabUs(i).dfRec.dfNumber = lbRec.df_file# AND
          (lbRec.df_file# = 0 OR
           lbDfRecTabUs(i).dfRec.dfCreationSCN =
              lbRec.df_creation_change#)) THEN
         IF (forIncr) THEN
            min_scn    := lbDfRecTabUs(i).incrmin_scn;
            min_rlgscn := lbDfRecTabUs(i).incrmin_rlgscn;
         ELSE
            min_scn    := lbDfRecTabUs(i).fullmin_scn;
            min_rlgscn := lbDfRecTabUs(i).fullmin_rlgscn;
         END IF;
 
         IF (min_scn < lbRec.df_checkpoint_change# AND
             (min_rlgscn IS NULL                      OR
              min_rlgscn = lbRec.df_resetlogs_change# OR
              min_scn <= lbRec.df_resetlogs_change#)) THEN
            RETURN TRUE;
         ELSE
            RETURN FALSE;
         END IF;
      END IF;
      i := i + maxDfNumber;
   END LOOP;
 
   RETURN FALSE;
END listBackupInMKS;
 
--
PROCEDURE listBackupProcessPiece(lbRec         IN            lbRec_t
                                ,lbRecOut      OUT    NOCOPY lbRec_t
                                ,lbState       IN OUT NOCOPY lbState_t)
IS
BEGIN
  IF (debug) THEN -- protect for performance
     deb(DEB_ENTER, 'listBackupProcessPiece');
  END IF;
--
--
--
--
--
--
  IF (anyDevice = TRUE# OR isDeviceTypeAllocated(lbRec.device_type) = TRUE#)
  THEN
    IF (recoveryDestFile AND lbRec.is_rdf = 'NO')
    OR (orsAnyFile AND lbRec.bp_ba_access IN ('U','D'))
    OR ((orsLocalFile OR orsLibKey IS NOT NULL) AND
        (lbRec.bp_ba_access IN ('U','D') OR
         nvl(lbRec.bp_lib_key, 0) != nvl(orsLibKey, 0)))
    THEN
      IF (debug) THEN -- protect for performance
        deb(DEB_IN, 'file_type: ' || lbRec.file_type ||
                    ' not a recovery area or ors file pkey: ' || lbRec.pkey);
      END IF;
    ELSE
--
       IF (lbRec.bp_copy# > lbState.lbCopyCount)
       THEN
         lbState.lbCopyCount := lbRec.bp_copy#;
       END IF;
--
--
       BEGIN
         lbState.lbPieceCountTab(lbRec.bp_copy#-1) :=
                 lbState.lbPieceCountTab(lbRec.bp_copy#-1) + 1;
       EXCEPTION
         WHEN no_data_found THEN   -- lbPieceCountTab(i) uninitialized
           lbState.lbPieceCountTab(lbRec.bp_copy#-1) := 1;
--
--
           lbState.lbRecCmn.bs_copies := lbState.lbRecCmn.bs_copies + 1;
       END;
 
--
--
       IF (lbState.lbRecCmn.bs_status is NULL)
       THEN
         lbState.lbRecCmn.bs_status := lbRec.status;
       ELSIF (lbRec.status <> lbState.lbRecCmn.bs_status)
       THEN
--
--
         lbState.lbRecCmn.bs_status := other_txt;
       END IF;
 
--
--
--
--
       lbState.lbRecCmn.bs_bytes := lbState.lbRecCmn.bs_bytes +
                                    lbRec.bytes;
 
--
--
       IF (lbState.lbRecCmn.bs_device_type is NULL)
       THEN
         lbState.lbRecCmn.bs_device_type := lbRec.device_type;
       ELSIF (instr(lbState.lbRecCmn.bs_device_type, lbRec.device_type) = 0)
       THEN
         BEGIN
            lbState.lbRecCmn.bs_device_type :=
               lbState.lbRecCmn.bs_device_type||','||lbRec.device_type;
         EXCEPTION
            WHEN value_error THEN
               deb(DEB_IN, 'dev buffer overflow length=' ||
                   lengthb(lbState.lbRecCmn.bs_device_type));
         END;
       END IF;
 
--
--
       IF (lbState.lbRecCmn.bs_compressed is NULL)
       THEN
         lbState.lbRecCmn.bs_compressed := lbRec.compressed;
       ELSIF (lbState.lbRecCmn.bs_compressed != lbRec.compressed)
       THEN
          lbState.lbRecCmn.bs_compressed := '###';
       END IF;
 
--
--
       IF (lbRec.tag IS NOT NULL) THEN
         IF (lbState.lbRecCmn.bs_tag is NULL) THEN
           lbState.lbRecCmn.bs_tag := lbRec.tag;
         ELSIF (instr(lbState.lbRecCmn.bs_tag, lbRec.tag) = 0) THEN
           BEGIN
              lbState.lbRecCmn.bs_tag :=
                 lbState.lbRecCmn.bs_tag||','||lbRec.tag;
           EXCEPTION
              WHEN value_error THEN
                 deb(DEB_IN, 'tag buffer overflow length=' ||
                     lengthb(lbState.lbRecCmn.bs_tag));
           eND;
         END IF;
       END IF;
    END IF;
  ELSE
    IF (debug) THEN
      deb(DEB_IN, 'device type not allocated');
    END IF;
  END IF;
 
  IF (debug) THEN  -- protect for performance
     deb(DEB_EXIT, 'OK');
  END IF;
END listBackupProcessPiece;
 
PROCEDURE setNeedObsoleteData(NeedObsoleteData IN boolean DEFAULT TRUE) IS
BEGIN
  IF NeedObsoleteData THEN
     lb_NeedObsoleteData := TRUE#;
  ELSE
     lb_NeedObsoleteData := FALSE#;
  END IF;
END;
 
--
FUNCTION listBackup(lbRecOut      OUT    NOCOPY lbRec_t
                   ,firstCall     IN     boolean
                   ,only_obsolete IN     boolean
                   ,redundancy    IN     number
                   ,piped_call    IN     boolean  -- not called by RMAN client
                   ,lbCursor      IN OUT NOCOPY lbCursor_t
                   ,lbState       IN OUT NOCOPY lbState_t
                   ,extRlKeepSCN  IN     number DEFAULT NULL)
RETURN boolean IS
  lbRec                lbRec_t;
  null_lbRec           lbRec_t := NULL;
  i                    binary_integer;
  j                    binary_integer;
  tmp                  binary_integer;
  rc                   binary_integer;
  found                boolean;
  lbCursor_notfound    boolean := FALSE;
  numBackups           number;
  oldest_flashback_scn number;
  fullBackups          number;
  actionMask           number;
  containerMask        number;
 
--
  full_df_backup       boolean;
  incr_df_backup       boolean;
  arc_log_backup       boolean;
  keep                 varchar2(3);
  keep_until           date;
 
--
  save_dbinc_key       number;
  save_reset_scn       number;
  dfRec                dfRec_t;
  rcvRecNxt            rcvRec_t;
  rcvRec               rcvRec_t;
  rcvRecStack_count    binary_integer;
  extendMask           binary_integer;
BEGIN
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
 
  IF (debug) THEN -- protect for performance
     deb(DEB_ENTER, 'listBackup');
  END IF;
 
--
  lbRecOut := NULL;
 
  IF (firstCall)
  THEN
    IF (debug) THEN -- protect for performance
       deb(DEB_IN, 'FIRST');
    END IF;
 
--
    validateState(NULL);
 
--
    setAllIncarnations(TRUE);
 
--
--
--
--
    setCanApplyAnyRedo(TRUE);
 
    setCanHandleTransportableTbs(TRUE);
 
--
    cacheBsRecTable.hint := redundantHint;
 
--
    lbState.lbRecOutTab.delete;
    lbState.lbRecOutTab_count := 0;
 
--
    lbState.lbRecTmpTab.delete;
 
--
--
    lbState.lbDfRecTabUs.delete;
 
--
    lbState.lbDfRecTab.delete;
 
--
--
--
    lbState.lbPieceCountTab.delete;
    lbState.lbCopyCount       := 0;
 
--
    lbState.lbMkTab.delete;
 
--
    lbState.lbMkITab.delete;
 
--
--
    SELECT SYSDATE INTO lbState.lbNowTime from dual;
 
--
--
--
--
--
--
--
    dfRec.dfNumber      := 0;
    dfRec.dfCreationSCN := 0;
    dfRec.inBackup      := 1;
    dfRec.noBackupPdb   := 0;
    dfRec.foreignDbid   := 0;
    dfRec.pluggedRonly  := 0;
    dfRec.pluginSCN     := 0;
 
    lbState.lbDfRecTabUs(0).dfRec          := dfRec;
    lbState.lbDfRecTabUs(0).fullmin_scn    := MAXSCNVAL;
    lbState.lbDfRecTabUs(0).fullmin_rlgscn := MAXSCNVAL;
    lbState.lbDfRecTabUs(0).incrmin_scn    := MAXSCNVAL;
    lbState.lbDfRecTabUs(0).incrmin_rlgscn := MAXSCNVAL;
    lbState.lbDfRecTabUs(0).logmin_scn     := MAXSCNVAL;
    lbState.lbDfRecTabUs(0).logmin_rlgscn  := MAXSCNVAL;
 
    IF lb_NeedObsoleteData = TRUE# THEN
      lbState.lbNeedObsoleteData  := TRUE;
    ELSE
      lbState.lbNeedObsoleteData  := FALSE;
      deb(DEB_PRINT,'listBackup:caller not interested in Obsolete Data');
    END IF;
--
    save_dbinc_key := this_dbinc_key;
    save_reset_scn := this_reset_scn;
--
    lbState.lbMaxDfNumber := getMaxDfNumber;
    <<loop_travelinc>>
    LOOP
      translateDatabase(TRUE#);
      <<loop_genDfRecTab>>
      LOOP
        BEGIN
          getDatafile(dfRec);
        EXCEPTION
          WHEN no_data_found THEN EXIT loop_genDfRecTab;
        END;
--
--
--
--
--
        j := dfRec.dfNumber;
        <<loop_scanDfRecTab>>
        LOOP
          BEGIN
--
--
--
--
--
            IF (lbState.lbDfRecTabUs(j).dfRec.dfNumber = 0)
            THEN
              RAISE no_data_found;
            END IF;
            IF (dfRec.dfNumber =
                   lbState.lbDfRecTabUs(j).dfRec.dfNumber  AND
                dfRec.dfCreationSCN =
                   lbState.lbDfRecTabUs(j).dfRec.dfCreationSCN)
            THEN
--
              EXIT loop_scanDfRecTab;
            ELSE
--
--
              j := j + lbState.lbMaxDfNumber;
            END IF;
          EXCEPTION
            WHEN no_data_found
            THEN
              lbState.lbDfRecTabUs(j).dfRec          := dfRec;
              lbState.lbDfRecTabUs(j).fullmin_scn    := MAXSCNVAL;
              lbState.lbDfRecTabUs(j).fullmin_rlgscn := MAXSCNVAL;
              lbState.lbDfRecTabUs(j).logmin_scn     := MAXSCNVAL;
              lbState.lbDfRecTabUs(j).logmin_rlgscn  := MAXSCNVAL;
              lbState.lbDfRecTabUs(j).incrmin_scn    := MAXSCNVAL;
              lbState.lbDfRecTabUs(j).incrmin_rlgscn := MAXSCNVAL;
          END;
        END LOOP;
      END LOOP;
--
--
--
--
      IF (untilSCN IS NOT NULL AND untilSCN < this_reset_scn)
      THEN
        rc := getParentIncarnation(this_dbinc_key, this_reset_scn);
        EXIT loop_travelinc WHEN rc = FALSE#;
      ELSE
        EXIT loop_travelinc;
      END IF;
    END LOOP;
--
    this_dbinc_key := save_dbinc_key;
    this_reset_scn := save_reset_scn;
 
--
    getFlashbackInfo(lbState.lbFbUntilTime, lbState.lbMinGrsp);
    IF (debug) THEN
       deb(DEB_IN, 'lbFbUntilTime= ' || to_char(lbState.lbFbUntilTime) ||
                   ' lbMinGrsp=' || to_char(lbState.lbMinGrsp));
    END IF;
 
    lbState.lbRlKeepRlgSCN  := MAXSCNVAL;
    lbState.lbRlKeepSCN     := MAXSCNVAL;
    IF (extRlKeepSCN IS NOT NULL) THEN
       lbState.lbRlKeepSCN     := extRlKeepSCN;
       lbState.lbRlKeepRlgSCN  := getPointInTimeInc(extRlKeepSCN);
       IF (debug) THEN
           deb(DEB_IN, 'Extending lbRlKeepSCN for external keepscn to '||
               to_char(lbState.lbRlKeepSCN));
           deb(DEB_IN, 'Extending lbRlKeepRlgSCN for external keepscn to '||
               to_char(lbState.lbRlKeepRlgSCN));
       END IF;
    END IF;
 
    IF (this_baseline_cap >= 0) THEN
       this_baseline_cap_scn := untilSCN;
       deb(DEB_IN, 'baseline_cap_scn = ' || this_baseline_cap_scn);
--
--
--
       resetUntil;
--
--
       setDeviceType('SBT_TAPE');
       containerMask := backupSet_con_t +
                        imageCopy_con_t +
                        offlineRangeRec_con_t;
    ELSE
       containerMask := backupSet_con_t +
                        proxyCopy_con_t +
                        imageCopy_con_t +
                        offlineRangeRec_con_t;
    END IF;
 
--
--
--
    actionMask := full_act_t + offlineRange_act_t + implicitRange_act_t +
                  cleanRange_act_t;
    IF (untilTime IS NOT NULL OR untilSCN IS NOT NULL) THEN
       actionMask := actionMask + incremental_act_t;
    END IF;
 
--
--
--
    setComputeRecoveryActionMasks(containerMask   => containerMask,
                                  actionMask      => actionMask,
                                  allRecords      => TRUE#,
                                  availableMask   => BSavailable,
                                  fullBackups     => redundancy);
 
--
--
--
    setCraGetAllCfBackups(TRUE);
 
--
--
--
--
    IF NOT (lbState.lbNeedObsoleteData OR this_baseline_cap >= 0) THEN
      goto ObsoleteDataSkip;
    END IF;
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
    i := to_number(null);
    LOOP
      IF (i is null) THEN
         i := lbState.lbDfRecTabUs.first;
      ELSE
         i := lbState.lbDfRecTabUs.next(i);
      END IF;
      EXIT WHEN i IS NULL;
      dfRec := lbState.lbDfRecTabUs(i).dfRec;
 
      IF (this_baseline_cap >= 0) AND 
         NOT setLocalOrsSiteKey(db_id => NULL) THEN
         deb(DEB_IN, 'local ORS site_key not set, no backups yet recieved');
      ELSE
--
--
--
--
--
--
--
         rc := computeRecoveryActions(
                                   fno           => dfRec.dfNumber,
                                   crescn        => dfRec.dfCreationSCN,
                                   allowfuzzy    => FALSE,
                                   partial_rcv   => FALSE,
                                   allCopies     => FALSE,
                                   cleanscn      => dfRec.stopSCN,
                                   clean2scn     => highscnval,
                                   clean2time    => lbState.lbNowTime,
                                   onlscn        => dfRec.dfOnlineSCN,
                                   offlscn       => dfRec.dfOfflineSCN,
                                   onltime       => dfRec.dfOnlineTime,
                                   rmanCmd       => obsoleteCmd_t,
                                   foreignDbid   => dfRec.foreignDbid,
                                   pluggedRonly  => dfRec.pluggedRonly,
                                   pluginSCN     => dfRec.pluginSCN,
                                   pluginRlgSCN  => dfRec.pluginRlgSCN,
                                   pluginRlgTime => dfRec.pluginRlgTime,
                                   creation_thread  => dfRec.creation_thread,
                                   creation_size    => dfRec.creation_size,
                                   pdbId            => dfRec.pdbId,
                                   pdbForeignDbid   => dfRec.pdbForeignDbid);
      END IF;
 
      IF (this_baseline_cap >= 0) THEN
         deb(DEB_IN, 'Found a new datafile ' || dfRec.dfNumber);
         lbRec.df_file#            := dfRec.dfNumber;
         lbRec.df_ts#              := dfRec.tsNumber;
         lbRec.df_plugin_change#   := dfRec.pluginSCN;
         lbRec.df_foreign_dbid     := dfRec.foreignDbid;
         lbRec.df_tablespace       := dfRec.tsName;
         lbRec.df_creation_change# := dfRec.dfCreationSCN;
 
         lbRec.file_type             := NULL;
         lbRec.backup_type           := NULL;
         lbRec.bs_key                := NULL;
         lbRec.df_checkpoint_change# := NULL;
      END IF;
 
      numBackups := 0;
      fullBackups := getRecFullCount;
      LOOP
        EXIT WHEN (getRecStackCount = 0 OR
                   (this_baseline_cap >= 0 AND lbRec.bs_key IS NOT NULL));
--
--
        IF (this_baseline_cap >= 0) THEN
          IF getRecStackCount = 1 THEN
             rcvRecPop(rcvRec);
          ELSIF getRecStackCount > 1 THEN
             rcvRecGet(1, rcvRec);
             rcvRecGet(2, rcvRecNxt);
          END IF;
          deb(DEB_IN, 'Newest RcvRec record');
          printRcvRec(rcvRec, TRUE);
          deb(DEB_IN, 'Next to New RcvRec record');
          printRcvRec(rcvRecNxt, TRUE);
        ELSE
          rcvRecPop(rcvRec);
        END IF;
 
        IF (this_baseline_cap >= 0) THEN
          IF (rcvRec.type_act = full_act_t AND
              (rcvRec.toSCN_act > this_baseline_cap_scn OR
               this_baseline_cap_scn IS NULL)) THEN
             lbRec.bs_key := rcvRec.bsKey_con;
             lbRec.df_checkpoint_change# := rcvRec.toSCN_act;
             deb(DEB_IN, 'Found-1 newest backup within baseline_cap for ' ||
                 lbRec.df_file# || ' as ' || lbRec.bs_key);
          ELSE 
             IF (rcvRecNxt.type_act = full_act_t AND
                 ((rcvRec.type_act = offlineRange_act_t OR
                   rcvRec.type_act = cleanRange_act_t   OR
                   rcvRec.type_act = implicitRange_act_t) AND
                  (rcvRec.toSCN_act >= this_baseline_cap_scn OR
                   rcvRec.toSCN_act = MAXSCNVAL))) THEN
                  lbRec.bs_key := rcvRecNxt.bsKey_con;
                  lbRec.df_checkpoint_change# := rcvRec.toSCN_act;
                  deb(DEB_IN, 'Found-2 newest backup with baseline_cap for '
                              || lbRec.df_file# || ' as ' || lbRec.bs_key);
             END IF;
          END IF;
          EXIT;
        END IF;
 
        IF (rcvRec.type_act = full_act_t)
        THEN
          IF (rcvRec.keep_options = KEEP_NO)                  -- nokeep backup
          THEN
            addBackupToMKL(lbState.lbMkTab, rcvRec);
            extendKeepSCN(lbState.lbDfRecTabUs(i),
                          rcvRec.toSCN_act,
                          rcvRec.rlgSCN_act,
                          extendAllSCN,
                          FALSE,
                          'extendFullBackup (NoKeep)');
            numBackups := numBackups+1;          -- bump the number of backups
          ELSIF (NVL(rcvRec.keep_until,MAXDATEVAL) > lbState.lbNowTime)
--
          THEN
--
--
            IF (rcvRec.keep_options =  KEEP_LOGS)                 -- keep logs?
            THEN
              extendKeepSCN(lbState.lbDfRecTabUs(i),
                            rcvRec.toSCN_act,
                            rcvRec.rlgSCN_act,
                            extendLogSCN + extendIncrSCN,
                            FALSE,
                            'extendFullBackup (Keep)');
            END IF;
          END IF;
 
        ELSIF (rcvRec.type_act = offlineRange_act_t OR
               rcvRec.type_act = cleanRange_act_t   OR
               rcvRec.type_act = implicitRange_act_t)
        THEN
           extendMask := 0;
           IF (lbState.lbDfRecTabUs(i).fullmin_scn = rcvRec.fromSCN_act) THEN
              extendMask := extendMask + extendFullSCN;
           END IF;
 
           IF (lbState.lbDfRecTabUs(i).incrmin_scn = rcvRec.fromSCN_act) THEN
              extendMask := extendMask + extendIncrSCN;
           END IF;
 
           IF (lbState.lbDfRecTabUs(i).logmin_scn = rcvRec.fromSCN_act) THEN
              extendMask := extendMask + extendLogSCN;
           END IF;
 
           extendKeepSCN(lbState.lbDfRecTabUs(i), 
                         rcvRec.toSCN_act,
                         rcvRec.rlgSCN_act,
                         extendMask,
                         TRUE,
                         'extendMiscRange');
        ELSIF (rcvRec.type_act = incremental_act_t)
        THEN
          IF (lbState.lbDfRecTabUs(i).incrmin_scn >= rcvRec.fromSCN_act AND
              lbState.lbDfRecTabUs(i).incrmin_scn < rcvRec.toSCN_act)
          THEN
            addBackupToMKL(lbState.lbMkITab, rcvRec);
            extendKeepSCN(lbState.lbDfRecTabUs(i),
                          rcvRec.toSCN_act,
                          rcvRec.rlgSCN_act,
                          extendIncrSCN,
                          TRUE,
                          'extendIncrBackup');
          END IF;
        END IF;
      END LOOP;
 
--
--
--
--
 
--
--
--
      IF ((lbState.lbDfRecTabUs(i).fullmin_scn = MAXSCNVAL OR -- no bkp
           numBackups < redundancy) AND             -- not enough backups
          dfRec.inBackup = 1 AND                    -- file not excluded
          dfRec.noBackupPdb = 0 AND                 -- not a excluded PDB
          dfRec.pluggedRonly = 0)                   -- not a plugged readonly
 
      THEN
        extendKeepSCN(lbState.lbDfRecTabUs(i),
                      dfRec.dfCreationSCN,
                      getPointInTimeInc(dfRec.dfCreationSCN),
                      extendAllSCN,
                      TRUE,
                      'extendNoBackup');
      END IF;
 
--
--
      IF (lbState.lbRlKeepSCN > lbState.lbDfRecTabUs(i).logmin_scn)
      THEN
        lbState.lbRlKeepSCN    := lbState.lbDfRecTabUs(i).logmin_scn;
        lbState.lbRlKeepRlgSCN := lbState.lbDfRecTabUs(i).logmin_rlgscn;
        IF (debug) THEN -- protect for performance
           deb(DEB_IN, 'Extending lbRlKeepSCN to '||
               to_char(lbState.lbRlKeepSCN));
           deb(DEB_IN, 'Extending lbRlKeepRlgSCN to '||
               nvl(to_char(lbState.lbRlKeepRlgSCN), 'null'));
        END IF;
      END IF;
 
      IF (this_baseline_cap >= 0) THEN
         lbState.lbRecOutTab(lbState.lbRecOutTab_count) := lbRec;
         lbState.lbRecOutTab_count := lbState.lbRecOutTab_count + 1;
      END IF;
    END LOOP;
 
--
    LOOP
      BEGIN
--
        IF (getSpfileBackup(rcvRec     => rcvRec,
                            redundancy => redundancy,
                            rmanCmd    => obsoleteCmd_t) = SUCCESS) THEN
          addBackupToMKL(lbState.lbMkTab, rcvRec);
        ELSE
          EXIT;
        END IF;
      EXCEPTION
        WHEN no_data_found THEN EXIT;
      END;
    END LOOP;
 
<<ObsoleteDataSkip>>
 
--
--
    translateAllDatafile;
    LOOP
      BEGIN
        getDatafile(dfRec);
      EXCEPTION
        WHEN no_data_found THEN EXIT;
      END;
      lbState.lbDfRecTab(lbState.lbDfRecTab.count) := dfRec;
    END LOOP;
 
--
--
    IF (piped_call)
    THEN
      openLbCursor(lbCursor);
    ELSE
      IF (listBackup_c%ISOPEN)
      THEN
        CLOSE listBackup_c;
      END IF;
      OPEN listBackup_c;
    END IF;
 
--
--
--
--
--
--
    lbState.lbObsoleteRetention := FALSE;
    lbState.lbKeepForDbpitr     := FALSE;
 
--
--
    lbState.lbObsoleteKeep := FALSE;
--
    lbState.lbRecTmpTab.delete;
    lbState.lbCopyCount := 0;
    lbState.lbPieceCountTab.delete;
    lbState.lbRecCmn := null_lbRec;
 
    IF (debug) THEN
      deb(DEB_IN, 'Must Keep List:');
      i := lbState.lbMkTab.first;
      LOOP
        EXIT WHEN i IS NULL;
        FOR j in 0..lbState.lbMkTab(i).count-1 LOOP
          IF (lbState.lbMkTab(i)(j).type_con = backupSet_con_t) THEN
            deb(DEB_PRINT, 'Backup Set bskey=' ||
                lbState.lbMkTab(i)(j).bsKey_con || ' set_stamp=' ||
                lbState.lbMkTab(i)(j).setStamp_con || ' set_count=' ||
                lbState.lbMkTab(i)(j).setCount_con);
          ELSIF (lbState.lbMkTab(i)(j).type_con = imageCopy_con_t) THEN
            deb(DEB_PRINT, 'Datafile Copy key=' ||
                lbState.lbMkTab(i)(j).key_con || ' recid=' ||
                lbState.lbMkTab(i)(j).recid_con || ' stamp=' ||
                lbState.lbMkTab(i)(j).stamp_con);
          ELSIF (lbState.lbMkTab(i)(j).type_con = proxyCopy_con_t) THEN
            deb(DEB_PRINT, 'Proxy Backup key=' ||
                lbState.lbMkTab(i)(j).key_con || ' recid=' ||
                lbState.lbMkTab(i)(j).recid_con || ' stamp=' ||
                lbState.lbMkTab(i)(j).stamp_con);
          ELSE
            deb(DEB_PRINT, 'Unknown Type=' || lbState.lbMkTab(i)(j).type_con);
          END IF;
        END LOOP;
        i := lbState.lbMkTab.next(i);
     END LOOP;
    END IF;
 
--
--
    cacheBsRecTable.hint := noHint;
  END IF; -- first call
 
  IF (this_baseline_cap >= 0) THEN
     goto listBackup_returnRec; 
  END IF;
 
  <<main_loop>>
 
 
  WHILE (lbState.lbRecOutTab_count = 0)     -- while there is nothing to return
  LOOP
 
    IF (piped_call)
    THEN
      FETCH lbCursor INTO lbRec;
      IF (lbCursor%NOTFOUND)
      THEN
        lbCursor_notfound := TRUE;
      END IF;
    ELSE
      FETCH listBackup_c INTO lbRec;
      IF (listBackup_c%NOTFOUND)
      THEN
        lbCursor_notfound := TRUE;
      END IF;
    END IF;
 
    IF (lbCursor_notfound OR
        (lbRec.file_type = backupset_txt) OR
        (lbRec.backup_type IN (copy_txt, proxycopy_txt)) OR
        (lbRec.backup_type = backupset_txt AND
         lbRec.file_type <> backupset_txt AND
         (lbState.lbRecCmn.recid IS NULL OR
          lbState.lbRecCmn.bs_stamp <> lbRec.bs_stamp OR
          lbState.lbRecCmn.bs_count <> lbRec.bs_count)))
    THEN
--
--
--
--
--
--
--
--
      IF (lbState.lbRecTmpTab.count > 0 AND lbState.lbCopyCount > 0 AND
          (NOT only_obsolete OR lbState.lbObsoleteRetention OR
           lbState.lbObsoleteKeep))
      THEN
--
--
--
        IF lbState.lbNeedObsoleteData THEN
          IF (lbState.lbObsoleteRetention OR lbState.lbObsoleteKeep)
          THEN
            IF (debug) THEN -- protect for performance
               deb(DEB_IN, 'E: Obsolete!!!');
            END IF;
            lbState.lbRecCmn.obsolete := 'YES';
            lbState.lbRecCmn.keep_for_dbpitr := 'NO';
          ELSE
            IF (debug) THEN -- protect for performance
               deb(DEB_IN, 'E: Not obsolete!!!');
            END IF;
            lbState.lbRecCmn.obsolete := 'NO';
            IF (lbState.lbKeepForDbpitr) THEN
               lbState.lbRecCmn.keep_for_dbpitr := 'YES';
            ELSE
               lbState.lbRecCmn.keep_for_dbpitr := 'NO';
            END IF;
          END IF;
        END IF;
 
--
--
        IF (lbState.lbRecCmn.status <> other_txt)
        THEN
          <<loop_copy>>
          FOR i IN 0..lbState.lbCopyCount-1
          LOOP
            BEGIN
              IF (lbState.lbRecCmn.bs_pieces != lbState.lbPieceCountTab(i))
              THEN
                lbState.lbRecCmn.status := other_txt;
                EXIT loop_copy;
              END IF;
            EXCEPTION
              WHEN no_data_found THEN  -- lbPieceCountTab(i) uninitialized
                EXIT loop_copy;
            END;
          END LOOP;
        END IF;
 
--
        IF (debug) THEN -- protect for performance
           deb(DEB_IN, 'pipelineing backup set '||lbState.lbRecCmn.bs_key);
        END IF;
 
        FOR i IN 0..lbState.lbRecTmpTab.count-1
        LOOP
--
          IF (recoveryDestFile AND lbState.lbRecTmpTab(i).is_rdf = 'NO')
          OR (orsAnyFile     AND
              lbState.lbRecTmpTab(i).bp_ba_access IN ('U','D'))
          OR (orsLocalFile   AND
              lbState.lbRecTmpTab(i).bp_ba_access IN ('U','D','T','R'))
          OR (orsLibKey IS NOT NULL AND
              nvl(lbState.lbRecTmpTab(i).bp_lib_key, 0) != orsLibKey)
          THEN
--
             IF (debug) THEN -- protect for performance
                deb(DEB_IN, 'not a recovery area or ors file type');
             END IF;
          ELSIF (anyDevice = FALSE# AND         -- not all device is allocated
                 lbState.lbRecTmpTab(i).file_type = piece_txt AND
                 isDevicetypeAllocated(lbState.lbRecTmpTab(i).device_type) =
                   FALSE#) THEN
--
--
--
             IF (debug) THEN -- protect for performance
                deb(DEB_IN, 'device type not allocated');
             END IF;
          ELSE
--
--
--
 
             tmp := lbState.lbRecOutTab_count;
             lbState.lbRecOutTab(tmp) :=
                lbState.lbRecTmpTab(i);
             lbState.lbRecOutTab(tmp).obsolete :=
                lbState.lbRecCmn.obsolete;
             lbState.lbRecOutTab(tmp).keep_for_dbpitr :=
                lbState.lbRecCmn.keep_for_dbpitr;
             lbState.lbRecOutTab(tmp).bs_status :=
                lbState.lbRecCmn.bs_status;
             lbState.lbRecOutTab(tmp).bs_copies :=
                lbState.lbRecCmn.bs_copies;
             lbState.lbRecOutTab(tmp).bs_bytes :=
                lbState.lbRecCmn.bs_bytes / lbState.lbRecCmn.bs_copies;
             lbState.lbRecOutTab(tmp).bs_compressed :=
                lbState.lbRecCmn.bs_compressed;
             lbState.lbRecOutTab(tmp).bs_tag :=
                lbState.lbRecCmn.bs_tag;
             lbState.lbRecOutTab(tmp).bs_device_type :=
                lbState.lbRecCmn.bs_device_type;
             IF (lbState.lbRecCmn.recid IS NOT NULL) THEN
--
--
                lbState.lbRecOutTab(tmp).backup_type :=
                   lbState.lbRecCmn.backup_type;
                lbState.lbRecOutTab(tmp).keep :=
                   lbState.lbRecCmn.keep;
                lbState.lbRecOutTab(tmp).keep_options:=
                   lbState.lbRecCmn.keep_options;
                lbState.lbRecOutTab(tmp).keep_until :=
                   lbState.lbRecCmn.keep_until;
                lbState.lbRecOutTab(tmp).bs_key :=
                   lbState.lbRecCmn.bs_key;
                lbState.lbRecOutTab(tmp).bs_count :=
                   lbState.lbRecCmn.bs_count;
                lbState.lbRecOutTab(tmp).bs_stamp :=
                   lbState.lbRecCmn.bs_stamp;
                lbState.lbRecOutTab(tmp).bs_type :=
                   lbState.lbRecCmn.bs_type;
                lbState.lbRecOutTab(tmp).bs_incr_type :=
                   lbState.lbRecCmn.bs_incr_type;
                lbState.lbRecOutTab(tmp).bs_pieces :=
                   lbState.lbRecCmn.bs_pieces;
                lbState.lbRecOutTab(tmp).bs_completion_time :=
                   lbState.lbRecCmn.bs_completion_time;
             END IF;
             lbState.lbRecOutTab_count := tmp + 1;
          END IF;
        END LOOP;
      END IF;
 
--
      IF (lbCursor_notfound)
      THEN
        exit main_loop;
      END IF;
 
--
--
--
--
--
      IF (lbRec.file_type <> backupset_txt AND
          lbRec.backup_type = backupset_txt)
      THEN
        IF (debug) THEN
          deb(DEB_IN, 'setting lbObsoleteRetention to FALSE');
        END IF;
        lbState.lbObsoleteRetention := FALSE;
      ELSE
        IF (debug) THEN
          deb(DEB_IN, 'setting lbObsoleteRetention to TRUE');
        END IF;
        lbState.lbObsoleteRetention := TRUE;
      END IF;
 
--
--
      lbState.lbObsoleteKeep  := FALSE;
      lbState.lbKeepForDbpitr := FALSE;
 
--
      lbState.lbRecTmpTab.delete;
      lbState.lbCopyCount := 0;
      lbState.lbPieceCountTab.delete;
      lbState.lbRecCmn := null_lbRec;
    END IF;
 
    IF (debug) THEN  -- protect for performance
       printLbRec(lbRec);
 
--
--
       IF (lbRec.backup_type = backupset_txt AND
           lbRec.file_type <> backupset_txt) THEN
          IF ((lbState.lbRecCmn.bs_stamp = lbRec.bs_stamp AND
               lbState.lbRecCmn.bs_count = lbRec.bs_count) OR
              lbState.lbRecCmn.bs_key = lbRec.bs_key) THEN
             deb(DEB_IN, 'bs->bp->bdf/bsf/brl same bs');
          ELSE
             deb(DEB_IN, 'bs->bp->bdf/bsf/brl **no** bs (or) **not** same bs');
          END IF;
       END IF;
    END IF;
 
--
--
--
--
 
    If lbState.lbNeedObsoleteData THEN
      lbRec.obsolete := 'YES';                -- assume that backup is obsolete
      lbRec.keep_for_dbpitr := 'NO';
    END IF;
 
    IF (lbState.lbObsoleteRetention AND NOT lbState.lbObsoleteKeep AND
        lbState.lbNeedObsoleteData) THEN
--
       full_df_backup := FALSE;
       incr_df_backup := FALSE;
       arc_log_backup := FALSE;
 
       IF (lbRec.backup_type = backupset_txt) THEN
          IF (lbRec.file_type = archivedlog_txt) THEN
             arc_log_backup := TRUE;
          ELSIF (lbRec.file_type IN (spfile_txt, controlfile_txt)) THEN
             full_df_backup := TRUE;
          ELSIF (lbRec.file_type = datafile_txt) THEN
             IF (lbRec.df_incremental_change# = lbRec.df_creation_change# OR
                 lbRec.bs_incr_type = full_txt) THEN
                full_df_backup := TRUE;
             ELSIF (lbRec.bs_incr_type <> full_txt) THEN
                incr_df_backup := TRUE;
             END IF;
          END IF;
       ELSIF (lbRec.backup_type IN (copy_txt, proxycopy_txt) AND
              lbRec.file_type   IN (datafile_txt, controlfile_txt)) THEN
          full_df_backup := TRUE;
       END IF;
 
--
       keep := NVL(lbRec.keep, 'NO');
       keep_until := NVL(lbRec.keep_until, MAXDATEVAL);
       IF ((full_df_backup OR arc_log_backup OR incr_df_backup) AND
           lbRec.backup_type = backupset_txt)
       THEN
          keep := NVL(lbState.lbRecCmn.keep, 'NO');
          keep_until := NVL(lbState.lbRecCmn.keep_until, MAXDATEVAL);
       END IF;
 
--
       IF (keep = 'YES') THEN
          IF (debug) THEN -- protect for performance
             deb(DEB_IN, 'Keep backup until ' || keep_until ||
                         ' - Checking ...');
          END IF;
          IF (keep_until < lbState.lbNowtime) THEN
             IF (debug) THEN  -- protect for performance
               deb(DEB_IN, 'expired -> obsolete by keep');
             END IF;
             lbState.lbObsoleteKeep := TRUE;
          ELSE
             IF (debug) THEN  -- protect for performance
               deb(DEB_IN, 'not expired -> no obsolete');
             END IF;
             lbState.lbObsoleteRetention := FALSE;
          END IF;
       END IF;
 
--
       IF (full_df_backup) THEN
          IF (keep != 'YES') THEN                             -- nokeep backup
             IF (debug) THEN  -- protect for performance
                deb(DEB_IN, 'Full backup - Checking ...');
             END IF;
             IF ((lbRec.file_type = spfile_txt AND
                  lbRec.df_ckp_mod_time <            -- it is SPFILE outside RW
                     NVL(untilTime, MAXDATEVAL))   OR
                 (lbRec.file_type <> spfile_txt AND  -- other file outside RW
                  ((untilTime IS NULL AND untilSCN IS NULL) OR
                   lbRec.df_ckp_mod_time < untilTime        OR
                   (untilTime IS NULL AND
                    lbRec.df_checkpoint_change# <= untilSCN)))) THEN
                IF (debug) THEN  -- protect for performance
                   deb(DEB_IN, 'nokeep backup outside RW');
                END IF;
                IF (listBackupInMKL(lbState.lbMkTab, lbRec)) THEN
                   IF (debug) THEN -- protect for performance
                      deb(DEB_IN, 'inside MKL -> no obsolete');
                      deb(DEB_IN, 'keep_for_dbpitr = YES');
                   END IF;
                   lbState.lbObsoleteRetention := FALSE;
                   lbState.lbKeepForDbpitr     := TRUE;
                ELSIF (lbRec.file_type <> spfile_txt AND
                       listBackupInMKS(lbState.lbDfRecTabUs, lbRec,
                                       lbState.lbMaxDfNumber, FALSE)) THEN
--
--
--
--
                   IF (debug) THEN -- protect for performance
                      deb(DEB_IN, 'inside MKS -> no obsolete');
                   END IF;
                   lbState.lbObsoleteRetention := FALSE;
                   lbState.lbKeepForDbpitr     := FALSE;
                END IF;
             ELSE                          -- inside Recovery Win, not obsolete
                IF (debug) THEN -- protect for performance
                   deb(DEB_IN, 'nokeep backup: inside RW -> no obsolete');
                END IF;
                lbState.lbObsoleteRetention := FALSE;
             END IF;
          END IF;
       ELSIF (incr_df_backup) THEN
          IF (debug) THEN -- protect for performance
             deb(DEB_IN, 'Incremental backup - Checking ...');
          END IF;
          IF (listBackupInMKL(lbState.lbMkITab, lbRec)) THEN
             IF (debug) THEN -- protect for performance
                deb(DEB_IN, 'inside MKL -> no obsolete');
                deb(DEB_IN, 'keep_for_dbpitr = YES');
             END IF;
             lbState.lbObsoleteRetention := FALSE;
             lbState.lbKeepForDbpitr     := TRUE;
          ELSIF (listBackupInMKS(lbState.lbDfRecTabUs, lbRec,
                                 lbState.lbMaxDfNumber, TRUE)) THEN
            IF (debug) THEN -- protect for performance
               deb(DEB_IN, 'inside MKS -> no obsolete');
            END IF;
            lbState.lbObsoleteRetention := FALSE;      -- need this incremental
            lbState.lbKeepForDbpitr     := FALSE;
          END IF;
       ELSIF (lbRec.file_type = archivedlog_txt) THEN              --- redo log
--
          IF (recoveryDestFile AND lbRec.rl_snapstandby = 'YES') THEN
             IF (debug) THEN 
                deb(DEB_IN, 'snapshot standby archivelog');
             END IF;
--
--
--
--
          ELSIF ((lbRec.rl_next_change# >= lbState.lbMinGrsp AND
               lbRec.backup_type != copy_txt)                      OR  -- (a)
              lbRec.rl_next_time >= lbState.lbFbUntilTime          OR  -- (b)
              (lbRec.rl_next_change# >= lbState.lbRlKeepSCN AND        -- (c)
               (lbState.lbRlKeepRlgSCN IS NULL                          OR
                lbRec.rl_resetlogs_change# = lbState.lbRlKeepRlgSCN     OR
                lbRec.rl_resetlogs_change# >= lbState.lbRlKeepSCN))) THEN
             IF (debug) THEN -- protect for performance
                IF (lbRec.rl_next_time >= lbState.lbFbUntilTime) THEN
                   deb(DEB_IN, 'Redolog after lbFbUntilTime -> no obsolete');
                ELSIF (lbRec.rl_next_change# >= lbState.lbMinGrsp AND
                       lbRec.backup_type != copy_txt) THEN
                   deb(DEB_IN, 'Redolog after lbMinGrsp -> no obsolete');
                ELSE
                   deb(DEB_IN, 'Redolog after lbRlkeepSCN -> no obsolete');
                END IF;
             END IF;
             lbState.lbObsoleteRetention := FALSE;    -- this redo must be kept
          END IF;
       END IF;
    END IF;
 
    IF (NOT lbState.lbKeepForDbpitr AND lbRec.file_type = archivedlog_txt) THEN
       IF (lbRec.rl_next_change# >= lbState.lbRlKeepSCN AND
           (lbRec.rl_first_change# <= untilSCN OR
            lbRec.rl_first_time <= untilTime)           AND
           (lbState.lbRlKeepRlgSCN IS NULL                      OR
            lbRec.rl_resetlogs_change# = lbState.lbRlKeepRlgSCN OR
            lbRec.rl_resetlogs_change# >= lbState.lbRlKeepSCN)) THEN
          IF (debug) THEN
             deb(DEB_IN, 'keep_for_dbpitr = YES');
          END IF;
          lbState.lbKeepForDbpitr := TRUE;
       END IF;
    END IF;
 
--
--
    IF (NOT lbState.lbObsoleteRetention AND NOT lbState.lbObsoleteKeep AND
        lbState.lbNeedObsoleteData)
    THEN
      IF (debug) THEN
         deb(DEB_IN, 'Not obsolete');
      END IF;
      lbRec.obsolete := 'NO';
      lbState.lbRecCmn.obsolete := 'NO';
      IF (lbState.lbKeepForDbpitr) THEN
         lbState.lbRecCmn.keep_for_dbpitr := 'YES';
         lbRec.keep_for_dbpitr := 'YES';
      ELSE
         lbState.lbRecCmn.keep_for_dbpitr := 'NO';
         lbRec.keep_for_dbpitr := 'NO';
      END IF;
      IF (only_obsolete)
      THEN
        GOTO listBackup_end;
      END IF;
    END IF;
 
--
--
--
    IF (lbRec.backup_type IN (backupset_txt, copy_txt) AND
        lbRec.file_type   = datafile_txt)
    THEN
      found := FALSE;
 
--
--
      <<loop_lbDfRecTab>>
      FOR i in lbRec.df_file#-1..lbState.lbDfRecTab.count-1
      LOOP
        IF (lbState.lbDfRecTab(i).dfNumber = lbRec.df_file# AND
            lbState.lbDfRecTab(i).dfCreationSCN = lbRec.df_creation_change#)
        THEN
          IF (lbRec.backup_type = backupset_txt)
          THEN
            lbRec.fname := lbState.lbDfRecTab(i).fileName;
          END IF;
          lbRec.df_tablespace := lbState.lbDfRecTab(i).tsName;
          found := TRUE;
          EXIT loop_lbDfRecTab;
        ELSIF (lbState.lbDfRecTab(i).dfNumber > lbRec.df_file#) THEN
          EXIT loop_lbDfRecTab;
        END IF;
      END LOOP;
 
      IF (NOT found) THEN
--
        <<reverse_loop_lbDfRecTab>>
        FOR i in REVERSE 0..least(lbRec.df_file#-1, lbState.lbDfRecTab.count-1)
        LOOP
          IF (lbState.lbDfRecTab(i).dfNumber = lbRec.df_file# AND
              lbState.lbDfRecTab(i).dfCreationSCN = lbRec.df_creation_change#)
          THEN
            IF (lbRec.backup_type = backupset_txt)
            THEN
              lbRec.fname := lbState.lbDfRecTab(i).fileName;
            END IF;
            lbRec.df_tablespace := lbState.lbDfRecTab(i).tsName;
            found := TRUE;
            EXIT reverse_loop_lbDfRecTab;
          ELSIF (lbState.lbDfRecTab(i).dfNumber < lbRec.df_file#) THEN
            EXIT reverse_loop_lbDfRecTab;
          END IF;
        END LOOP;
      END IF;
    END IF;
 
--
--
--
--
--
    IF (lbRec.backup_type = backupset_txt)
    THEN
      IF (lbRec.file_type = backupset_txt)
      THEN
--
--
--
 
--
        lbState.lbRecTmpTab.delete;
        lbState.lbCopyCount := 0;
        lbState.lbPieceCountTab.delete;
 
--
--
        lbState.lbRecCmn := lbRec;
        lbState.lbRecCmn.bs_copies := 0;
        lbState.lbRecCmn.bs_bytes  := 0;
      ELSIF lbRec.file_type in (datafile_txt, controlfile_txt,
                                spfile_txt  , archivedlog_txt,
                                piece_txt)
      THEN
        IF (NOT only_obsolete OR lbRec.file_type = piece_txt)
        THEN
--
           lbState.lbRecTmpTab(lbState.lbRecTmpTab.count) := lbRec;
           IF (lbRec.file_type = piece_txt)
           THEN
              listBackupProcessPiece(lbRec, lbRecOut, lbState);
           END IF;
        END IF;
      ELSE
--
        deb(DEB_EXIT, 'with error 20999');
        raise_application_error(-20999, 'internal error: listBackup_2');
      END IF;
    ELSIF (lbRec.backup_type = copy_txt)
    THEN
--
--
 
--
--
--
--
--
      IF (diskDevice)
      THEN
        IF (recoveryDestFile AND lbRec.is_rdf = 'NO') THEN
           IF (debug) THEN  -- protect for performance
              deb(DEB_IN,
                  'copy not recovery area or ors file pkey: ' || lbRec.pkey);
           END IF;
        ELSE
           IF (debug) THEN -- protect for performance
              deb(DEB_IN, 'device allocated: pipelineing copy '||lbRec.pkey);
           END IF;
           lbState.lbRecOutTab(lbState.lbRecOutTab_count) := lbRec;
           lbState.lbRecOutTab_count := lbState.lbRecOutTab_count+1;
        END IF;
      ELSE
        IF (debug) THEN -- protect for performance
           deb(DEB_IN, 'device not allocated: skiping copy '||lbRec.pkey);
        END IF;
      END IF;
    ELSIF (lbRec.backup_type = proxycopy_txt)
      THEN
--
--
 
--
--
--
--
--
      IF (anyDevice = TRUE# OR
          isDeviceTypeAllocated(lbRec.device_type) = TRUE#)
      THEN
        IF (recoveryDestFile AND lbRec.is_rdf = 'NO') THEN
           IF (debug) THEN -- protect for performance
              deb(DEB_IN, 'proxycopy not a recovery area file pkey: ' ||
                  lbRec.pkey);
           END IF;
        ELSE
          IF (debug) THEN -- protect for performance
             deb(DEB_IN, 'device allocated: pipelineing proxycopy '||
                 lbRec.pkey);
          END IF;
          lbState.lbRecOutTab(lbState.lbRecOutTab_count) := lbRec;
          lbState.lbRecOutTab_count := lbState.lbRecOutTab_count+1;
        END IF;
      ELSE
        IF (debug) THEN  -- protect for performance
           deb(DEB_IN, 'device not allocated: skiping proxycopy '||lbRec.pkey);
        END IF;
      END IF;
    ELSE
      deb(DEB_EXIT, 'with error 20999');
      raise_application_error(-20999, 'internal error: listBackup_3');
    END IF;
  END LOOP;
 
<<listBackup_returnRec>>
--
  IF (lbState.lbRecOutTab_count > 0)
  THEN
    lbState.lbRecOutTab_count := lbState.lbRecOutTab_count - 1;
    lbRecOut := lbState.lbRecOutTab(lbState.lbRecOutTab_count);
  END IF;
 
<<listBackup_end>>
--
--
 
  IF (lbState.lbRecOutTab_count = 0)
  THEN
    IF (this_baseline_cap >= 0) THEN
      deb(DEB_EXIT, 'FALSE');
      RETURN FALSE;
    END IF;
 
    IF (piped_call)
    THEN
      IF (lbCursor%NOTFOUND)
      THEN
        CLOSE lbCursor;
        cacheBsRecTable.hint := noHint;
        IF (debug) THEN -- protect for performance
           deb(DEB_EXIT, 'FALSE');
        END IF;
        RETURN FALSE;
      END IF;
    ELSE
      IF (listBackup_c%NOTFOUND)
      THEN
        CLOSE listBackup_c;
        cacheBsRecTable.hint := noHint;
        IF (debug) THEN -- protect for performance
           deb(DEB_EXIT, 'FALSE');
        END IF;
        RETURN FALSE;
      END IF;
    END IF;
  END IF;
 
  deb(DEB_EXIT, 'TRUE');
  RETURN TRUE;
 
EXCEPTION
  WHEN OTHERS THEN
    IF (piped_call)
    THEN
      IF (lbCursor%ISOPEN) THEN
        CLOSE lbCursor;
      END IF;
    ELSE
      IF (listBackup_c%ISOPEN) THEN
        CLOSE listBackup_c;
      END IF;
    END IF;
    deb(DEB_EXIT, 'with exception: '||substr(sqlerrm, 1, 512));
    RAISE;
 
END listBackup;
 
--
FUNCTION getRestoreRangeSet(restoreRangeTab OUT restoreRangeTab_t,
                            opCode          IN  varchar2,
                            db_id           IN  number)
 
RETURN boolean IS
 
  i                       number;
  j                       number;
  ret                     boolean;
  rc                      binary_integer;
  restoreRange            restoreRange_t;
  dfRecTab                dfRecTab_t;
  dfRec                   dfRec_t;
  rcvRec                  rcvRec_t;
  maxScn                  number;
  maxRlgScn               number;
  maxRlgTime              date;
  minScn                  number;          
  fromScn                 number;
  tmpScn                  number;
  dropScn                 number;
  dropTime                date;
  dropDbIncKey            number;
  dropRlgScn              number;
  dropRlgTime             date;
  lastBkupScn             number;
  cfcrescn                number;
  cfcretime               date;
  tmpDbIncKey             number;
  tmpRlgScn               number;
  tmpRlgTime              date;
  actionMask              number;
  dfBackupFound           number;
  offlnRngFound           number;
  dfCreation              number;
  logBreakPointScn        number;
  logBreakPointTime       date;
  logBreakDbIncKey        number;
  logBreakRlgScn          number;
  logBreakRlgTime         date;
  nextAvailableScn        number;
  logMissing              boolean;
  nxtScnExist             boolean;
  maxScnExist             boolean;
  dropScnExist            boolean;
  maxTime                 date;
  maxDbIncKey             number;
  tmpTime                 date;
  nowTime                 date;
  logRangeCount           number;
  isOrs                   number;
  type isActnFoundTab is table of boolean index by binary_integer;  
  isActnFound             isActnFoundTab;
  con_id                  number;
  canCreateDf             boolean;
  dfCreateSCN             number;
  firstDf                 boolean;
BEGIN
 
  deb(DEB_ENTER, 'getRestoreRangeSet');
  deb(DEB_IN, 'backupLocation = ' || opCode);
  if (substr(opCode,  4, 3) = 'ANY') then
     restoreRangeDevTyp := substr(opCode, 1, 6);
  elsif (substr(opCode,  4, 4) = 'DISK') then
     restoreRangeDevTyp := substr(opCode, 1, 7);
  elsif (substr(opCode,  4, 3) = 'SBT') then
     restoreRangeDevTyp := substr(opCode, 1, 6);
  elsif (substr(opCode,  1, 5) = 'V$ANY') then
     restoreRangeDevTyp := substr(opCode, 3, 3);
  elsif (substr(opCode,  1, 6) = 'V$DISK') then
     restoreRangeDevTyp := substr(opCode, 3, 4);
  elsif (substr(opCode,  1, 5) = 'V$SBT') then
     restoreRangeDevTyp := substr(opCode, 3, 3);
  end if;
 
--
  IF (opCode = 'RA$ANY' OR opCode = 'RA$DISK' OR opCode = 'RA$SBT') THEN
     IF user_site_key IS NULL THEN
        ret := setLocalOrsSiteKey(db_id);
        IF ret = FALSE THEN
           resetLocalOrsSiteKey;
           deb(DEB_EXIT, 'with FALSE');
           return FALSE;
        END IF;
     END IF;
     isOrs := TRUE#;
  ELSE
     isOrs := FALSE#;
  END IF;
 
  restoreRangeTab.delete;
 
  setCraGetAllCfBackups(TRUE);
  setAllIncarnations(TRUE);
  canApplyAnyRedo := TRUE#;
 
--
  maxScnExist  := getMaxRedoSCN(maxScn, maxTime, maxDbIncKey, maxRlgScn, 
                                maxRlgTime, isOrs);
  IF (maxScnExist = FALSE) THEN
    resetLocalOrsSiteKey;
    deb(DEB_EXIT, 'with FALSE');
    return FALSE;
  END IF;
  deb(DEB_IN, 'Max scn is ' || to_char(maxScn));
 
--
  nxtScnExist := getNextAvailableSCN(0, minScn, isOrs);
  IF (nxtScnExist = FALSE) THEN
    resetLocalOrsSiteKey;
    deb(DEB_EXIT, 'with FALSE');
    return FALSE;
  END IF;
  fromScn := minScn;
 
  con_id := 0;
 
--
--
--
--
--
--
--
--
--
  i := 0; 
  LOOP
    EXIT WHEN fromScn >= maxScn;
    logMissing := findLogBreakPoint(logBreakPointScn, logBreakPointTime, 
                                    logBreakDbIncKey, logBreakRlgScn, 
                                    logBreakRlgTime, fromScn, maxScn, isOrs);
--
    IF (logMissing = FALSE) THEN
      restoreRangeTab(i).startScn     := fromScn;
      restoreRangeTab(i).highScn      := maxScn;
      restoreRangeTab(i).highTime     := maxTime;
      restoreRangeTab(i).highDbIncKey := maxDbIncKey;
      restoreRangeTab(i).highRlgScn   := maxRlgScn;
      restoreRangeTab(i).highRlgTime  := maxRlgTime;
      restoreRangeTab(i).con_id       := con_id;
      EXIT;
--
--
    ELSE 
      restoreRangeTab(i).startScn     := fromScn;
      restoreRangeTab(i).highScn      := logBreakPointScn;
      restoreRangeTab(i).highTime     := logBreakPointTime;
      restoreRangeTab(i).highDbIncKey := logBreakDbIncKey;
      restoreRangeTab(i).highRlgScn   := logBreakRlgScn;
      restoreRangeTab(i).highRlgTime  := logBreakRlgTime;
      restoreRangeTab(i).con_id       := con_id;
 
--
      nxtScnExist := getNextAvailableSCN(logBreakPointScn, nextAvailableScn, 
                                         isOrs);
      IF (nxtScnExist = TRUE) THEN
        fromScn := nextAvailableScn;
      ELSE
        EXIT;
      END IF;
    END IF;
    i := i + 1;
  END LOOP;
 
--
  logRangeCount := i + 1;
 
--
  i := 0;
  WHILE i < logRangeCount LOOP
    restoreRangeTab(i).isValidRange := FALSE;
    restoreRangeTab(i).cfBkupFound  := FALSE;
    i := i + 1;
  END LOOP;
 
  deb(DEB_IN, 'Printing continuous log-ranges');
  i := 0;
  WHILE i < logRangeCount LOOP
    deb(DEB_IN, 'Range '||to_char(i+1)||' lowscn = '||
                 to_char(restoreRangeTab(i).startScn) ||' highscn = '||
                 to_char(restoreRangeTab(i).highScn));
    i := i + 1;
  END LOOP;
 
--
  dfRecTab.delete;
  translateAllDatafile;
  LOOP
    BEGIN
      getDatafile(dfRec);
    EXCEPTION
      WHEN no_data_found THEN EXIT;
    END;
 
--
    IF (dfRec.PdbId <= 1 OR translatePdb2Name(dfRec.PdbId) IS NOT NULL) THEN
      dfRecTab(dfRecTab.count) := dfRec;
    END IF;
  END LOOP;
 
  SELECT SYSDATE INTO nowTime from dual;
 
--
--
  actionMask := full_act_t + offlineRange_act_t + implicitRange_act_t + 
                cleanRange_act_t + incremental_act_t + createdatafile_act_t;
 
--
--
--
  setComputeRecoveryActionMasks(containerMask   => backupMask_con_t +
                                                   offlineRangeRec_con_t,
                                actionMask      => actionMask,
                                allRecords      => TRUE#,
                                availableMask   => BSavailable,
                                fullBackups     => NULL);
 
--
--
  findControlfileBackup(FALSE, FALSE, TRUE, 0, 0);
 
  IF getRecStackCount <> 0 THEN
     rcvRecPop(rcvRec);
     cfcrescn := 0;
     cfcretime := rcvRec.cfCreationTime_con;
  END IF;
 
--
--
  j := to_number(null);
  LOOP
    IF (j is null) THEN
       j := dfRecTab.first;
    ELSE
       j := dfRecTab.next(j);
    END IF;
    EXIT WHEN j IS NULL;
    dfRec := dfRecTab(j);
 
--
--
    IF (dfRec.pluginSCN       = 0  AND 
        dfRec.foreignDbid     = 0  AND
        dfRec.pdbForeignDbid  = 0  AND
        dfRec.creation_thread > 0  AND
        dfRec.creation_size   > 0)   
    THEN
       canCreateDf := TRUE; 
    ELSE
       canCreateDf := FALSE;
    END IF;
    dfCreateSCN := dfRec.dfCreationSCN;
 
    dropScnExist := getDropSCN(dfRec.dfNumber, dfRec.dfCreationSCN, 
                               dfRec.dfCreationTime, dfRec.pluginSCN, 
                               dfRec.foreignDbid, dropScn, dropTime,
                               dropDbIncKey, dropRlgScn, dropRlgTime);
 
    IF (dropScnExist = TRUE) THEN
       deb(DEB_IN, 'Datafile belongs to tablespace# ' || 
                    to_char(dfRec.dfNumber) || 'which has a dropscn' ||
                    dropScn);
    END IF;
 
--
    rc := computeRecoveryActions(fno              => dfRec.dfNumber,
                                 crescn           => dfRec.dfCreationSCN,
                                 df_cretime       => dfRec.dfCreationTime,
                                 cf_scn           => cfcrescn,
                                 cf_cretime       => cfcretime,
                                 allowfuzzy       => FALSE,
                                 partial_rcv      => FALSE,
                                 allCopies        => FALSE,
                                 cleanscn         => dfRec.stopSCN,
                                 clean2scn        => highscnval,
                                 clean2time       => nowTime,
                                 onlscn           => dfRec.dfOnlineSCN,
                                 offlscn          => dfRec.dfOfflineSCN,
                                 onltime          => dfRec.dfOnlineTime,
                                 rmanCmd          => restoreCmd_t,
                                 foreignDbid      => dfRec.foreignDbid,
                                 pluggedRonly     => dfRec.pluggedRonly,
                                 pluginSCN        => dfRec.pluginSCN,
                                 pluginRlgSCN     => dfRec.pluginRlgSCN,
                                 pluginRlgTime    => dfRec.pluginRlgTime,
                                 creation_thread  => dfRec.creation_thread,
                                 creation_size    => dfRec.creation_size,
                                 pdbId            => dfRec.pdbId,
                                 pdbForeignDbid   => dfRec.pdbForeignDbid);
 
--
    deb(DEB_IN, 'Considering backups for the datafile ' 
                 ||to_char(dfRec.dfNumber));
        
--
--
--
--
    i := 0;
    WHILE i < logRangeCount LOOP
      isActnFound(i) := FALSE;
      i := i + 1;
    END LOOP;
 
--
    IF (rc = SUCCESS)
    THEN
      LOOP
          EXIT WHEN getRecStackCount = 0;
          rcvRecPop(rcvRec);
          dfBackupFound := FALSE#;
          offlnRngFound := FALSE#;
          dfCreation    := FALSE#;
--
          IF (rcvRec.type_act = full_act_t) THEN
--
             tmpScn := rcvRec.toSCN_act;
             tmpTime := rcvRec.toTime_act;
             tmpDbIncKey := rcvRec.dbincKey_act;
             tmpRlgScn   := rcvRec.rlgSCN_act;
             tmpRlgTime  := rcvRec.rlgTime_act;
             dfBackupFound := TRUE#;
--
          ELSIF (rcvRec.type_act = createdatafile_act_t) THEN
             dfCreation  := TRUE#;
             deb(DEB_IN, 'The df can be created');
--
          ELSIF (rcvRec.type_act = cleanRange_act_t) THEN
             deb(DEB_IN, 'A clean range found');
             lastBkupScn := tmpScn; 
             offlnRngFound := TRUE#; 
          END IF;
 
          IF (dfRec.dfNumber = 1)
          THEN
             firstDf := TRUE;
          ELSE
             firstDf := FALSE;
             IF (con_id > 1)
             THEN
                IF (dfRec.tsNumber = 0 AND dfRec.rfNumber IN (1, 1024))
                THEN
                   firstDf := TRUE;
                END IF;
             END IF;
          END IF;
 
--
          IF (firstDf AND dfBackupFound = TRUE#) THEN
             deb(DEB_IN, 'backup scn = ' || to_char(tmpScn));
--
             i := 0;
             WHILE i < logRangeCount LOOP
                IF (restoreRangeTab(i).startScn <= tmpScn AND 
                    restoreRangeTab(i).highScn >= tmpScn AND 
                    isActnFound(i) = FALSE) THEN
--
--
                   restoreRangeTab(i).lowScn        := tmpScn;
                   restoreRangeTab(i).lowTime       := tmpTime;
                   restoreRangeTab(i).lowDbIncKey   := tmpDbIncKey;
                   restoreRangeTab(i).lowRlgScn     := tmpRlgScn;
                   restoreRangeTab(i).lowRlgTime    := tmpRlgTime;
                   restoreRangeTab(i).rcvStartScn   := tmpScn;
                   restoreRangeTab(i).rcvStartTime  := tmpTime;
                   isActnFound(i)          := TRUE;
                   restoreRangeTab(i).isValidRange  := TRUE;
                   deb(DEB_IN, 'backup belongs to ' || to_char(i+1) || 
                               '-th range' );
                END IF;
                i := i + 1;
             END LOOP;
 
--
--
          ELSIF (NOT firstDf AND dfBackupFound = TRUE#) THEN
             deb(DEB_IN, 'backup scn = ' || to_char(tmpScn));
--
             i := 0;
             WHILE i < logRangeCount LOOP
                IF (restoreRangeTab(i).startScn <= tmpScn AND 
                    restoreRangeTab(i).highScn >= tmpScn AND 
                    restoreRangeTab(i).isValidRange = TRUE AND 
                    isActnFound(i) = FALSE) THEN
 
                   deb(DEB_IN, 'backup belongs to ' || to_char(i+1) ||
                               '-th range' );
                   isActnFound(i) := TRUE;
--
--
--
--
--
                   IF (tmpScn >= restoreRangeTab(i).lowScn AND
                       (NOT (canCreateDf    AND 
                             restoreRangeTab(i).startScn <= dfCreateSCN AND
                             restoreRangeTab(i).highScn  >= dfCreateSCN))) THEN
                      restoreRangeTab(i).lowScn := tmpScn;
                      restoreRangeTab(i).lowTime := tmpTime;
                      restoreRangeTab(i).lowDbIncKey   := tmpDbIncKey;
                      restoreRangeTab(i).lowRlgScn     := tmpRlgScn;
                      restoreRangeTab(i).lowRlgTime    := tmpRlgTime;
                      deb(DEB_IN, 'updating lowscn to ' || to_char(tmpScn));
                   ELSE
                      deb(DEB_IN, 'not updating lowscn');
                   END IF;
 
                   IF (tmpScn < restoreRangeTab(i).rcvStartScn) THEN
                      restoreRangeTab(i).rcvStartScn   := tmpScn;
                      restoreRangeTab(i).rcvStartTime  := tmpTime;
                      deb(DEB_IN, 'updating media rcv scn to ' || 
                                  to_char(tmpScn));
                   ELSE
                      deb(DEB_IN, 'not updating media rcv scn');
                   END IF;
                END IF;
               
--
--
--
--
--
--
 
                IF (canCreateDf  AND
                    restoreRangeTab(i).startScn <= dfCreateSCN AND
                    restoreRangeTab(i).isValidRange = TRUE AND
                    isActnFound(i) = FALSE) THEN
                   deb(DEB_IN, 'creation scn belongs to ' || to_char(i+1) || 
                               '-th range. Marking the action to True');
                   isActnFound(i) := TRUE;
                   
                   IF (dfCreateSCN < restoreRangeTab(i).rcvStartScn AND
                       restoreRangeTab(i).highScn  >= dfCreateSCN) THEN
                      restoreRangeTab(i).rcvStartScn   := dfCreateSCN;
                      restoreRangeTab(i).rcvStartTime  := dfRec.dfCreationTime;
                      deb(DEB_IN, 'updating media rcv scn to DF createscn ' || 
                                  to_char(dfCreateSCN));
                   END IF;
                ELSIF ( NOT canCreateDf AND 
                        restoreRangeTab(i).highScn <  dfCreateSCN AND
                        restoreRangeTab(i).isValidRange = TRUE AND
                        isActnFound(i) = FALSE) THEN
                   deb(DEB_IN, 'Df non-creatable. Restore range highscn '||
                               restoreRangeTab(i).highScn || ' less than df' ||
                               'creation scn ' || dfCreateSCN || '.Marking ' ||
                               to_char(i+1) || '-th range to true');
                   isActnFound(i) := TRUE;
                END IF;
                i := i + 1;
             END LOOP;
 
--
--
          ELSIF (dfCreation = TRUE#) THEN
             tmpScn  := dfRec.dfCreationSCN;
             i := 0;
             WHILE i < logRangeCount LOOP
                IF (restoreRangeTab(i).startScn <= tmpScn AND
                    restoreRangeTab(i).isValidRange = TRUE AND
                    isActnFound(i) = FALSE) THEN
 
                   deb(DEB_IN, 'creation scn belongs to ' ||
                               to_char(i+1) || '-th range' );
                   isActnFound(i) := TRUE;
 
                END IF;
                i := i + 1;
             END LOOP;
 
--
--
--
          ELSIF (NOT firstDf AND  offlnRngFound = TRUE#) THEN
             deb(DEB_IN, 'offline range from scn = ' || 
                         to_char(rcvRec.fromSCN_act) ||
                         'to scn = ' || to_char(rcvRec.toSCN_act));
--
             i := 0;
             WHILE i < logRangeCount LOOP
                IF (restoreRangeTab(i).startScn <= rcvRec.toSCN_act AND
                    restoreRangeTab(i).isValidRange = TRUE AND
                    isActnFound(i) = FALSE AND
                    rcvRec.fromSCN_act <= lastBkupScn) THEN
 
                   deb(DEB_IN, 'offline range belongs to ' ||
                               to_char(i+1) || '-th range' );
                   isActnFound(i) := TRUE;
 
                END IF;
                i := i + 1;
             END LOOP;
          END IF;
 
--
          IF (dropScnExist = TRUE) THEN
             i := 0;
             WHILE i < logRangeCount LOOP
                IF (restoreRangeTab(i).startScn >= dropScn AND
                    restoreRangeTab(i).isValidRange = TRUE AND
                    isActnFound(i) = FALSE) THEN
 
                   deb(DEB_IN, 'file has been dropped before ' ||
                               to_char(i+1) || '-th range' );
                   isActnFound(i) := TRUE;
 
                ELSIF (restoreRangeTab(i).startScn < dropScn AND
                       restoreRangeTab(i).highScn > dropScn AND
                       restoreRangeTab(i).isValidRange = TRUE AND
                       isActnFound(i) = FALSE) THEN
                   deb(DEB_IN, 'file has been dropped in ' ||
                               to_char(i+1) || '-th range' );
                   isActnFound(i) := TRUE;
                   restoreRangeTab(i).lowScn        := dropScn; 
                   restoreRangeTab(i).lowTime       := dropTime;
                   restoreRangeTab(i).lowDbIncKey   := dropDbIncKey;
                   restoreRangeTab(i).lowRlgScn     := dropRlgScn;
                   restoreRangeTab(i).lowRlgTime    := dropRlgTime;
                   deb(DEB_IN, 'updating media low scn to ' || dropScn);
                END IF;
                i := i + 1;
             END LOOP;
          END IF;
      END LOOP;
 
--
--
      i := 0;
      WHILE i < logRangeCount 
      LOOP
         IF (isActnFound(i) = FALSE) THEN
            restoreRangeTab(i).isValidRange := FALSE;
         END IF;
         i := i + 1;
      END LOOP;
 
--
--
    ELSE
      i := 0;
      WHILE i < logRangeCount LOOP
          restoreRangeTab(i).isValidRange := FALSE;
          i := i + 1;
      END LOOP;
      EXIT;
    END IF;
--
  END LOOP;
 
--
--
--
  IF (con_id <= 1)
  THEN
     findControlfileBackup(FALSE, TRUE, TRUE, 0, 0);
 
     IF (getBS_status = SUCCESS) THEN
     LOOP
        EXIT WHEN getRecStackCount = 0;
        rcvRecPop(rcvRec);
       
--
        tmpScn := rcvRec.toSCN_act;
        deb(DEB_IN, 'cf backup scn = ' || to_char(tmpScn));
 
--
        i := 0;
        WHILE i < logRangeCount
        LOOP
           IF (restoreRangeTab(i).startScn <= tmpScn AND
                restoreRangeTab(i).highScn >= tmpScn AND 
                  restoreRangeTab(i).cfBkupFound = FALSE AND
                   restoreRangeTab(i).isValidRange = TRUE) THEN
 
               deb(DEB_IN, 'cf backup belongs to ' || to_char(i+1) ||
                        '-th range' );
               restoreRangeTab(i).cfBkupFound := TRUE;
--
--
--
               IF (restoreRangeTab(i).lowScn < tmpScn) THEN
                   restoreRangeTab(i).lowScn := tmpScn;
                   deb(DEB_IN, 'updating lowscn to ' || to_char(tmpScn));
               END IF;
--
--
           END IF;
           i := i + 1;
        END LOOP;
     END LOOP;       
     END IF;
 
--
--
     i := 0;
     WHILE i < logRangeCount
     LOOP
        IF (restoreRangeTab(i).cfBkupFound = FALSE) THEN
           restoreRangeTab(i).isValidRange := FALSE;
        END IF;
        i := i + 1;
     END LOOP;
  END IF;
 
  resetLocalOrsSiteKey;
  deb(DEB_EXIT, 'with TRUE');
  RETURN TRUE;
 
EXCEPTION
  WHEN OTHERS THEN
    resetLocalOrsSiteKey;
    deb(DEB_EXIT, 'with FALSE');
    RETURN FALSE;
 
END getRestoreRangeSet;
 
--
PROCEDURE sv_setSessionKey(skey IN NUMBER) IS
BEGIN
   session_key := skey;
   deb(DEB_PRINT, 'Session Key Filter='|| session_key);
END;
FUNCTION sv_getSessionKey RETURN NUMBER IS
BEGIN
   return session_key;
END;
 
--
PROCEDURE sv_setSessionTimeRange(fromTime IN DATE, untilTime IN DATE) IS
BEGIN
  session_fromTime := fromTime;
  session_untilTime := untilTime;
  deb(DEB_PRINT, 'Session Time range Filter='||
                 to_char(session_fromTime, 'MM/DD/YYYY HH24:MI:SS')  ||
                 ' To ' ||
                 to_char(session_untilTime, 'MM/DD/YYYY HH24:MI:SS'));
END;
FUNCTION sv_getSessionfromTimeRange RETURN DATE IS
BEGIN
   return session_fromtime;
END;
FUNCTION sv_getSessionUntilTimeRange RETURN DATE IS
BEGIN
   return session_untilTime;
END;
 
--
PROCEDURE getRetentionPolicy(recovery_window OUT number
                            ,redundancy      OUT number)
IS
  conf_value             varchar2(512);
  conf_name              varchar2(512) := 'RETENTION POLICY';
  conf#                  binary_integer;
  l1                     binary_integer;
  l2                     binary_integer;
  l3                     binary_integer;
BEGIN
 
  deb(DEB_ENTER, 'getRetentionPolicy');
 
  recovery_window := 0;
  redundancy      := 1;
 
  IF (findConfig_c%ISOPEN) THEN
    CLOSE findConfig_c;
  END IF;
  OPEN findConfig_c(conf_name, conf_value, null);
  FETCH findConfig_c INTO conf#, conf_name, conf_value;
  IF (NOT findConfig_c%NOTFOUND) THEN
    IF (conf_value like '%RECOVERY WINDOW%')
    THEN
      l1 := length('TO RECOVERY WINDOW OF ');
      l2 := length(' DAYS');
      l3 := length(conf_value);
      recovery_window := to_number(substr(conf_value, l1, l3-l2-l1+1));
    END IF;
    IF (conf_value like '%REDUNDANCY%')
    THEN
      l1 := length('TO REDUNDANCY ');
      l2 := length(conf_value);
      redundancy := to_number(substr(conf_value, l1, l2-l1+1));
    END IF;
    IF (conf_value like '%NONE%')
    THEN
--
--
      redundancy := 0;
      recovery_window := 0;
    END IF;
  END IF;
  CLOSE findConfig_c;
 
  deb(DEB_IN, 'recovery window = '||recovery_window);
  deb(DEB_IN, 'redundancy      = '||redundancy);
 
  deb(DEB_EXIT, 'getRetentionPolicy');
 
END getRetentionPolicy;
 
--
PROCEDURE translateDataFileCopy(
   duplicates   IN number
  ,statusMask   IN binary_integer
  ,onlyrdf      IN binary_integer
  ,pluginSCN    IN number DEFAULT 0)
IS
BEGIN
   validateState(getDatafileCopyCursor);
 
--
--
--
--
   OPEN findDatafileBackup_c(
                         sourcemask   => imageCopy_con_t,
                         reset_scn    => this_reset_scn,
                         reset_time   => this_reset_time,
                         statusMask   => statusMask,
                         duplicates   => duplicates,
                         onlyrdf      => onlyrdf,
                         pluginSCN    => pluginSCN
                         );
 
   getDatafileCopyCursor            := 'findDatafileBackup_c';
   getDataFileCopyNoRows.error      := NULL;
   getDataFileCopyNoRows.msg        := 'Datafile copy does not exists';
   getDataFileCopyDuplicates        := duplicates;
   getDataFileCopyLast.dfNumber_obj := NULL;
   getDataFileCopySingleRow         := FALSE;
END translateDataFileCopy;
 
--
--
--
PROCEDURE getDfBackupHistory(
   backedUpDev     IN   varchar2
  ,first           IN   boolean
  ,bhistoryRec     OUT  NOCOPY bhistoryRec_t
  ,recentbackup    IN   boolean  DEFAULT FALSE
  ,doingCmd        IN   varchar2 DEFAULT NULL
  ,keepTag         IN   varchar2 DEFAULT NULL
  ,toDest1         IN   varchar2 DEFAULT NULL
  ,toDest2         IN   varchar2 DEFAULT NULL
  ,toDest3         IN   varchar2 DEFAULT NULL
  ,toDest4         IN   varchar2 DEFAULT NULL)
IS
   eof         boolean := FALSE;
   local       bhistoryRec_t;
   icount      number  := 0;
   locCreSCN   number;
   lastCreSCN  number;
   locRlgSCN   number;
   lastRlgSCN  number;
   locRlgTime  date;
   lastRlgTime date;
   locCkpSCN   number;
   lastCkpSCN  number;
BEGIN
   deb(DEB_ENTER, 'getDfBackupHistory');
 
   IF (first) THEN
      getLastBackupHistory.dfNumber := NULL;
      IF (dfBackupHistory_c2%ISOPEN) THEN
         CLOSE dfBackupHistory_c2;
      END IF;
      deb(DEB_OPEN, 'dfBackupHistory_c2');
      OPEN dfBackupHistory_c2(device_type => backedUpDev,
                              cmd         => doingCmd,
                              ktag        => keepTag,
                              pattern1    => startWithPattern(toDest1),
                              pattern2    => startWithPattern(toDest2),
                              pattern3    => startWithPattern(toDest3),
                              pattern4    => startWithPattern(toDest4));
   END IF;
 
   IF (getLastBackupHistory.dfNumber IS NOT NULL AND
       (recentbackup OR
        getLastBackupHistory.ckp_scn = getLastBackupHistory.stop_scn)) THEN
--
      icount := 1;
   END IF;
 
   IF (getLastBackupHistory.dfNumber IS NOT NULL) THEN
      deb(DEB_IN, 'with file# = ' || to_char(getLastBackupHistory.dfNumber) ||
                  ' icount= '     || to_char(icount) ||
                  ' ckp_scn= '    || to_char(getLastBackupHistory.ckp_scn) ||
                  ' compTime= '   || to_char(getLastBackupHistory.compTime,
                                            'DD-MON-RR HH24:MI:SS'));
   END IF;
 
   IF (NOT dfBackupHistory_c2%ISOPEN) THEN
      eof := TRUE;
      goto lastRow;
   END IF;
 
<<nextRow>>
   FETCH dfBackupHistory_c2 INTO local;
 
   IF (dfBackupHistory_c2%NOTFOUND) THEN
      CLOSE dfBackupHistory_c2;
      eof := TRUE;
   ELSE
      IF (local.pluginSCN != 0) THEN
         locCreSCN   := local.pluginSCN;
         locRlgSCN   := local.pluginRlgSCN;
         locRlgTime  := local.pluginRlgTime;
         lastCreSCN  := getLastBackupHistory.pluginSCN;
         lastRlgSCN  := getLastBackupHistory.pluginRlgSCN;
         lastRlgTime := getLastBackupHistory.pluginRlgTime;
      ELSE
         locCreSCN   := local.create_scn;
         locRlgSCN   := local.reset_scn;
         locRlgTime  := local.reset_time;
         lastCreSCN  := getLastBackupHistory.create_scn;
         lastRlgSCN  := getLastBackupHistory.reset_scn;
         lastRlgTime := getLastBackupHistory.reset_time;
      END IF;
 
      IF (local.pluggedRonly = 1) THEN
         locCkpSCN  := local.pluginSCN;
         lastCkpSCN := getLastBackupHistory.pluginSCN;
      ELSE
         locCkpSCN  := local.ckp_scn;
         lastCkpSCN := getLastBackupHistory.ckp_scn;
      END IF;
 
      IF (getLastBackupHistory.dfNumber IS NULL OR
          (getLastBackupHistory.dfNumber = local.dfNumber AND
           lastCreSCN                    = locCreSCN      AND
           lastRlgSCN                    = locRlgSCN      AND
           lastRlgTime                   = locRlgTime)) THEN
         IF (recentbackup) THEN
            IF (getLastBackupHistory.dfNumber IS NULL OR
                locCkpSCN = lastCkpSCN) THEN
--
               icount := icount + 1;
            END IF;
         ELSIF (local.ckp_scn = local.stop_scn OR local.pluggedRonly = 1) THEN
--
--
            icount := icount + 1;          -- bump the number of copies
         END IF;
 
         IF (getLastBackupHistory.dfNumber IS NULL) THEN
            getLastBackupHistory := local;     -- remember the recent backup
         END IF;
         deb(DEB_IN, 'with file# = ' || to_char(local.dfNumber) ||
                     ' icount= '     || to_char(icount) ||
                     ' ckp_scn= '    || to_char(local.ckp_scn) ||
                     ' compTime= '   || to_char(local.compTime,
                                               'DD-MON-RR HH24:MI:SS'));
         goto nextRow;
      END IF;
   END IF;
 
--
--
 
<<lastRow>>
   IF (eof AND getLastBackupHistory.dfNumber IS NULL) THEN
      deb(DEB_EXIT, 'with: no_data_found');
      RAISE no_data_found;
   END IF;
 
--
--
   bhistoryRec             := getLastBackupHistory;
   bhistoryRec.nbackups    := icount;
 
   IF (eof) THEN
      getLastBackupHistory.dfNumber := NULL; -- for next time to raise no_data
   ELSE
--
      getLastBackupHistory := local;
   END IF;
 
   deb(DEB_EXIT, 'with file# = ' || to_char(bhistoryRec.dfNumber) ||
                 ' nbackups= '   || to_char(bhistoryRec.nbackups) ||
                 ' ckp_scn= '    || to_char(bhistoryRec.ckp_scn) ||
                 ' compTime= '   || to_char(bhistoryRec.compTime,
                                           'DD-MON-RR HH24:MI:SS'));
END getDfBackupHistory;
 
PROCEDURE getDcBackupHistory(
   backedUpDev     IN   varchar2
  ,first           IN   boolean
  ,bhistoryRec     OUT  NOCOPY bhistoryRec_t
  ,doingCmd        IN   varchar2 DEFAULT NULL
  ,keepTag         IN   varchar2 DEFAULT NULL
  ,toDest1         IN   varchar2 DEFAULT NULL
  ,toDest2         IN   varchar2 DEFAULT NULL
  ,toDest3         IN   varchar2 DEFAULT NULL
  ,toDest4         IN   varchar2 DEFAULT NULL
  ,atAnyScn        IN   boolean  DEFAULT FALSE) 
IS
   eof                boolean := FALSE;
   local              bhistoryRec_t;
   icount             number  := 0;
   locCreSCN          number;
   lastCreSCN         number;
   locRlgSCN          number;
   lastRlgSCN         number;
   locRlgTime         date;
   lastRlgTime        date;
   locCkpSCN          number;
   lastCkpSCN         number;
   backedUpAnyScn     number;
BEGIN
   deb(DEB_ENTER, 'getDcBackupHistory');
 
--
--
--
 
   IF (atAnyScn) THEN
      backedUpAnyScn := TRUE#;
   ELSE
      backedUpAnyScn := FALSE#;
   END IF;
 
   IF (first) THEN
      getLastBackupHistory.dfNumber := NULL;
      IF (dcBackupHistory_c%ISOPEN) THEN
         CLOSE dcBackupHistory_c;
      END IF;
   
      deb(DEB_OPEN, 'dcBackupHistory_c');
      OPEN dcBackupHistory_c(device_type    => backedUpDev,
                             cmd            => doingCmd,
                             ktag           => keepTag,
                             pattern1       => startWithPattern(toDest1),
                             pattern2       => startWithPattern(toDest2),
                             pattern3       => startWithPattern(toDest3),
                             pattern4       => startWithPattern(toDest4),
                             backedUpAnyScn => backedUpAnyScn);
   END IF;
 
   IF (getLastBackupHistory.dfNumber IS NOT NULL AND
       getLastBackupHistory.ckp_scn = getLastBackupHistory.stop_scn) THEN
      icount := 1;
   END IF;
 
   IF (NOT dcBackupHistory_c%ISOPEN) THEN
      eof := TRUE;
      goto lastRow;
   END IF;
 
   IF (getLastBackupHistory.dfNumber IS NOT NULL) THEN
      deb(DEB_IN, 'with file# = ' || to_char(getLastBackupHistory.dfNumber) ||
                  ' create_scn= ' || to_char(getLastBackupHistory.create_scn) ||
                  ' reset_scn= '  || to_char(getLastBackupHistory.reset_scn) ||
                  ' reset_time= ' || to_char(getLastBackupHistory.reset_time,
                                            'DD-MON-RR HH24:MI:SS') ||
                  ' ckp_scn= '    || to_char(getLastBackupHistory.ckp_scn) ||
                  ' stop_scn= '   || to_char(getLastBackupHistory.stop_scn) ||
                  ' nbackups= '   || to_char(getLastBackupHistory.nbackups) ||
                  ' compTime= '   || to_char(getLastBackupHistory.compTime,
                                            'DD-MON-RR HH24:MI:SS'));
   END IF;
 
<<nextRow>>
   FETCH dcBackupHistory_c INTO local;
 
   IF (dcBackupHistory_c%NOTFOUND) THEN
      CLOSE dcBackupHistory_c;
      eof := TRUE;
   ELSE
      IF (local.pluginSCN != 0) THEN
         locCreSCN   := local.pluginSCN;
         locRlgSCN   := local.pluginRlgSCN;
         locRlgTime  := local.pluginRlgTime;
         lastCreSCN  := getLastBackupHistory.pluginSCN;
         lastRlgSCN  := getLastBackupHistory.pluginRlgSCN;
         lastRlgTime := getLastBackupHistory.pluginRlgTime;
      ELSE
         locCreSCN   := local.create_scn;
         locRlgSCN   := local.reset_scn;
         locRlgTime  := local.reset_time;
         lastCreSCN  := getLastBackupHistory.create_scn;
         lastRlgSCN  := getLastBackupHistory.reset_scn;
         lastRlgTime := getLastBackupHistory.reset_time;
      END IF;
 
      IF (getLastBackupHistory.dfNumber IS NULL OR
          (getLastBackupHistory.dfNumber     = local.dfNumber     AND
           lastCreSCN                        = locCreSCN          AND
           getLastBackupHistory.ckp_scn      = local.ckp_scn      AND
           getLastBackupHistory.ckp_time     = local.ckp_time     AND
           getLastBackupHistory.pluggedRonly = local.pluggedRonly AND
           lastRlgSCN                        = locRlgSCN          AND
           lastRlgTime                       = locRlgTime)) THEN
         IF (local.ckp_scn = local.stop_scn OR local.pluggedRonly = 1) THEN
--
            icount  := icount + 1;          -- bump the number of copies
         END IF;
         getLastBackupHistory := local;     -- remember the last copy
 
         deb(DEB_IN, 'with file# = ' || to_char(local.dfNumber) ||
                     ' create_scn= ' || to_char(local.create_scn) ||
                     ' reset_scn= '  || to_char(local.reset_scn) ||
                     ' reset_time= ' || to_char(local.reset_time,
                                               'DD-MON-RR HH24:MI:SS') ||
                     ' ckp_scn= '    || to_char(local.ckp_scn) ||
                     ' stop_scn= '   || to_char(local.stop_scn) ||
                     ' nbackups= '   || to_char(local.nbackups) ||
                     ' compTime= '   || to_char(local.compTime,
                                               'DD-MON-RR HH24:MI:SS'));
         goto nextRow;
      END IF;
   END IF;
 
--
--
 
<<lastRow>>
   IF (eof AND getLastBackupHistory.dfNumber IS NULL) THEN
      deb(DEB_EXIT, 'with: no_data_found');
      RAISE no_data_found;
   END IF;
 
--
--
   bhistoryRec             := getLastBackupHistory;
   bhistoryRec.nbackups    := icount;
 
   IF (eof) THEN
      getLastBackupHistory.dfNumber := NULL; -- for next time to raise no_data
   ELSE
--
      getLastBackupHistory := local;
   END IF;
 
   deb(DEB_EXIT, 'with file# = ' || to_char(bhistoryRec.dfNumber) ||
                 ' create_scn= ' || to_char(bhistoryRec.create_scn) ||
                 ' reset_scn= '  || to_char(bhistoryRec.reset_scn) ||
                 ' reset_time= ' || to_char(bhistoryRec.reset_time,
                                           'DD-MON-RR HH24:MI:SS') ||
                 ' ckp_scn= '    || to_char(bhistoryRec.ckp_scn) ||
                 ' stop_scn= '   || to_char(bhistoryRec.stop_scn) ||
                 ' nbackups= '   || to_char(bhistoryRec.nbackups) ||
                 ' compTime= '   || to_char(bhistoryRec.compTime,
                                           'DD-MON-RR HH24:MI:SS'));
END getDcBackupHistory;
 
PROCEDURE getAlBackupHistory(
   backedUpDev     IN   varchar2
  ,first           IN   boolean
  ,bhistoryRec     OUT  NOCOPY bhistoryRec_t
  ,doingCmd        IN   varchar2 DEFAULT NULL
  ,keepTag         IN   varchar2 DEFAULT NULL
  ,toDest1         IN   varchar2 DEFAULT NULL
  ,toDest2         IN   varchar2 DEFAULT NULL
  ,toDest3         IN   varchar2 DEFAULT NULL
  ,toDest4         IN   varchar2 DEFAULT NULL)
IS
   eof       boolean := FALSE;
   local     bhistoryRec_t;
   icount    number  := 0;
BEGIN
   deb(DEB_ENTER, 'getAlBackupHistory');
 
   IF (first) THEN
      getLastBackupHistory.logThread := NULL;
      IF (alBackupHistory_c2%ISOPEN) THEN
         CLOSE alBackupHistory_c2;
      END IF;
      deb(DEB_OPEN, 'alBackupHistory_c2');
      OPEN alBackupHistory_c2(device_type => backedUpDev,
                              cmd         => doingCmd,
                              ktag        => keepTag,
                              pattern1    => startWithPattern(toDest1),
                              pattern2    => startWithPattern(toDest2),
                              pattern3    => startWithPattern(toDest3),
                              pattern4    => startWithPattern(toDest4));
   END IF;
 
   IF (getLastBackupHistory.logThread IS NOT NULL) THEN
      icount := 1;
   END IF;
 
   IF (NOT alBackupHistory_c2%ISOPEN) THEN
      eof := TRUE;
      goto lastRow;
   END IF;
 
<<nextRow>>
   FETCH alBackupHistory_c2 INTO local;
 
   IF (alBackupHistory_c2%NOTFOUND) THEN
      CLOSE alBackupHistory_c2;
      eof := TRUE;
   ELSIF (getLastBackupHistory.logThread IS NULL OR
          (getLastBackupHistory.logThread = local.logThread AND
           getLastBackupHistory.logSequence = local.logSequence AND
           getLastBackupHistory.logTerminal = local.logTerminal AND
           getLastBackupHistory.next_scn = local.next_scn AND
           getLastBackupHistory.reset_scn = local.reset_scn AND
           getLastBackupHistory.reset_time = local.reset_time)) THEN
      icount  := icount + 1;             -- bump the number of copies
      getLastBackupHistory := local;     -- remember the last copy
 
      deb(DEB_IN,
            'with (reset_scn, reset_time, thread#, sequence#, terminal)=(' ||
            to_char(local.reset_scn)  || ',' ||
            to_char(local.reset_time,'DD-MON-RR HH24:MI:SS')  || ',' ||
            to_char(local.logThread)  || ',' ||
            to_char(local.logSequence) || ',' ||
            to_char(local.logTerminal) || ')' ||
            ' nbackups= ' || local.nbackups||
            ' compTime= '   || to_char(local.compTime,
                                       'DD-MON-RR HH24:MI:SS'));
      goto nextRow;
   END IF;
 
--
--
 
<<lastRow>>
   IF (eof AND getLastBackupHistory.logThread IS NULL) THEN
      deb(DEB_EXIT, 'with: no_data_found');
      RAISE no_data_found;
   END IF;
 
--
--
   bhistoryRec := getLastBackupHistory;
   bhistoryRec.nbackups    := icount;
 
   IF (eof) THEN
      getLastBackupHistory.logThread := NULL; -- for next time to raise no_data
   ELSE
--
      getLastBackupHistory := local;
   END IF;
 
   deb(DEB_EXIT,
            'with (reset_scn, reset_time, thread#, sequence#, terminal)=(' ||
            to_char(bhistoryRec.reset_scn)  || ',' ||
            to_char(bhistoryRec.reset_time,'DD-MON-RR HH24:MI:SS')  || ',' ||
            to_char(bhistoryRec.logThread)  || ',' ||
            to_char(bhistoryRec.logSequence) || ',' ||
            to_char(bhistoryRec.logTerminal) || ')' ||
            ' nbackups= ' || bhistoryRec.nbackups||
            ' compTime= '   || to_char(bhistoryRec.compTime, 
                                       'DD-MON-RR HH24:MI:SS'));
END getAlBackupHistory;
 
PROCEDURE getBsBackupHistory(
   backedUpDev     IN   varchar2
  ,first           IN   boolean
  ,set_stamp       IN   number  DEFAULT NULL
  ,set_count       IN   number  DEFAULT NULL
  ,bhistoryRec     OUT  NOCOPY bhistoryRec_t
  ,doingCmd        IN   varchar2 DEFAULT NULL
  ,keepTag         IN   varchar2 DEFAULT NULL
  ,toDest1         IN   varchar2 DEFAULT NULL
  ,toDest2         IN   varchar2 DEFAULT NULL
  ,toDest3         IN   varchar2 DEFAULT NULL
  ,toDest4         IN   varchar2 DEFAULT NULL)
IS
   eof       boolean := FALSE;
   local     bhistoryRec_t;
   icount    number  := 0;
   bpRec     bpRec_t;
BEGIN
   deb(DEB_ENTER, 'getBsBackupHistory');
 
   IF (set_stamp IS NOT NULL AND set_count IS NOT NULL) THEN
      IF (NOT first) THEN
         deb(DEB_EXIT, 'with: no_data_found');
         RAISE no_data_found;
      END IF;
 
      bpRec.setStamp := set_stamp;
      bpRec.setCount := set_count;
      getBackupHistory(bpRec            => bpRec,
                       backedUpDev      => backedUpDev,
                       nbackupsFlag     => 1,
                       bscompletionFlag => 1,
                       nbackups         => bhistoryRec.nbackups,
                       bscompletion     => bhistoryRec.compTime,
                       todest1          => toDest1,
                       todest2          => toDest2,
                       todest3          => todest3,
                       todest4          => todest4);
 
      IF (bhistoryRec.nbackups = 0) THEN
         deb(DEB_EXIT, 'with: no_data_found');
         RAISE no_data_found;
      END IF;
 
      bhistoryRec.setStamp := set_stamp;
      bhistoryRec.setCount := set_count;
      deb(DEB_EXIT, 'with set_stamp = ' || to_char(bhistoryRec.setStamp) ||
                    ' set_count = ' || to_char(bhistoryRec.setCount) ||
                    ' nbackups= '  || to_char(bhistoryRec.nbackups)  ||
                    ' compTime= '  || to_char(bhistoryRec.compTime,
                                              'DD-MON-RR HH24:MI:SS'));
      RETURN;
   END IF;
 
   IF (first) THEN
      getLastBackupHistory.setStamp := NULL;
      IF (bsBackupHistory_c2%ISOPEN) THEN
         CLOSE bsBackupHistory_c2;
      END IF;
      deb(DEB_OPEN, 'bsBackupHistory_c2');
      OPEN bsBackupHistory_c2(device_type => backedUpDev,
                              cmd         => doingCmd,
                              ktag        => keepTag,
                              pattern1    => startWithPattern(toDest1),
                              pattern2    => startWithPattern(toDest2),
                              pattern3    => startWithPattern(toDest3),
                              pattern4    => startWithPattern(toDest4));
   END IF;
 
   IF (getLastBackupHistory.setStamp IS NOT NULL) THEN
      icount := 1;
   END IF;
 
   IF (NOT bsBackupHistory_c2%ISOPEN) THEN
      eof := TRUE;
      goto lastRow;
   END IF;
 
<<nextRow>>
   FETCH bsBackupHistory_c2 INTO local;
 
   IF (bsBackupHistory_c2%NOTFOUND) THEN
      CLOSE bsBackupHistory_c2;
      eof := TRUE;
   ELSIF (getLastBackupHistory.setStamp IS NULL OR
          (getLastBackupHistory.setStamp = local.setStamp AND
           getLastBackupHistory.setCount = local.setCount)) THEN
      icount := icount + 1;           -- bump the number of copies
      getLastBackupHistory := local;  -- remember the last copy
      goto nextRow;
   END IF;
 
--
--
<<lastRow>>
   IF (eof AND getLastBackupHistory.setStamp IS NULL) THEN
      deb(DEB_EXIT, 'with: no_data_found');
      RAISE no_data_found;
   END IF;
 
--
--
   bhistoryRec := getLastBackupHistory;
   bhistoryRec.nbackups    := icount;
 
   IF (eof) THEN
      getLastBackupHistory.setStamp := NULL; -- for next time to raise no_data
   ELSE
--
      getLastBackupHistory := local;
   END IF;
 
   deb(DEB_EXIT, 'with set_stamp = ' || to_char(bhistoryRec.setStamp) ||
                 'set_count = ' || to_char(bhistoryRec.setCount) ||
                 ' nbackups= '  || to_char(bhistoryRec.nbackups)  ||
                 ' compTime= '  || to_char(bhistoryRec.compTime,
                                           'DD-MON-RR HH24:MI:SS'));
END getBsBackupHistory;
 
--
--
 
PROCEDURE getBackupHistory(
   dfRec            IN  dfRec_t
  ,backedUpDev      IN  varchar2
  ,nbackupsFlag     IN  number
  ,bscompletionFlag IN  number
  ,nbackups         OUT number
  ,bscompletion     OUT date)
IS
   local bhistoryRec_t;
BEGIN
   deb(DEB_ENTER, 'getBackupHistory');
 
   nbackups := 0;
   bscompletion := NULL;
 
--
   IF ((nbackupsFlag != 1  OR backedUpDev IS NULL) AND
       bscompletionFlag != 1) THEN
      deb(DEB_EXIT, 'with not interested');
      RETURN;
   END IF;
 
   IF (dfBackupHistory_c1%ISOPEN) THEN
      CLOSE dfBackupHistory_c1;
   END IF;
 
   OPEN dfBackupHistory_c1(file#        => dfRec.dfNumber
                          ,crescn       => dfRec.dfCreationSCN
                          ,device_type  => backedUpDev);
<<nextRow>>
   FETCH dfBackupHistory_c1 INTO local;
   IF (dfBackupHistory_c1%NOTFOUND) THEN
      CLOSE dfBackupHistory_c1;
   ELSE
      IF (local.reset_scn  = this_reset_scn AND
          local.reset_time = this_reset_time AND
          local.ckp_scn = dfRec.stopSCN) THEN
         nbackups := nbackups + 1;
      END IF;
      bscompletion := local.compTime;
      goto nextRow;
   END IF;
   deb(DEB_EXIT);
END getBackupHistory;
 
--
--
 
PROCEDURE getBackupHistory(
   alRec            IN  alRec_t
  ,backedUpDev      IN  varchar2
  ,nbackupsFlag     IN  number
  ,bscompletionFlag IN  number
  ,nbackups         OUT number
  ,bscompletion     OUT date)
IS
   local bhistoryRec_t;
BEGIN
   deb(DEB_ENTER, 'getBackupHistory');
 
   nbackups := 0;
   bscompletion := NULL;
 
--
   IF ((nbackupsFlag != 1  OR backedUpDev IS NULL) AND
       bscompletionFlag != 1) THEN
      deb(DEB_EXIT, 'with not interested');
      RETURN;
   END IF;
 
   IF (alBackupHistory_c1%ISOPEN) THEN
      CLOSE alBackupHistory_c1;
   END IF;
 
   OPEN alBackupHistory_c1(thread#      => alRec.thread
                          ,sequence#    => alRec.sequence
                          ,device_type  => backedUpDev);
<<nextRow>>
   FETCH alBackupHistory_c1 INTO local;
   IF (alBackupHistory_c1%NOTFOUND) THEN
      CLOSE alBackupHistory_c1;
   ELSE
      nbackups := nbackups + 1;
      bscompletion := local.compTime;
      goto nextRow;
   END IF;
 
   deb(DEB_EXIT);
END getBackupHistory;
 
--
PROCEDURE getBackupHistory(
   bpRec            IN  bpRec_t
  ,backedUpDev      IN  varchar2
  ,nbackupsFlag     IN  number
  ,bscompletionFlag IN  number
  ,nbackups         OUT number
  ,bscompletion     OUT date
  ,todest1          IN  varchar2 DEFAULT NULL
  ,todest2          IN  varchar2 DEFAULT NULL
  ,todest3          IN  varchar2 DEFAULT NULL
  ,todest4          IN  varchar2 DEFAULT NULL)
IS
   local bhistoryRec_t;
BEGIN
   deb(DEB_ENTER, 'getBackupHistory');
 
   nbackups := 0;
   bscompletion := NULL;
 
--
   IF ((nbackupsFlag != 1  OR backedUpDev IS NULL) AND
       bscompletionFlag != 1) THEN
      deb(DEB_EXIT, 'with not interested');
      RETURN;
   END IF;
 
   IF (bsBackupHistory_c1%ISOPEN) THEN
      CLOSE bsBackupHistory_c1;
   END IF;
 
   OPEN bsBackupHistory_c1(set_stamp    => bpRec.setStamp
                          ,set_count    => bpRec.setCount
                          ,device_type  => backedUpDev
                          ,pattern1     => startWithPattern(toDest1)
                          ,pattern2     => startWithPattern(toDest2)
                          ,pattern3     => startWithPattern(toDest3)
                          ,pattern4     => startWithPattern(toDest4));
<<nextRow>>
   FETCH bsBackupHistory_c1 INTO local;
   IF (bsBackupHistory_c1%NOTFOUND) THEN
      CLOSE bsBackupHistory_c1;
   ELSE
      nbackups := nbackups + 1;
      bscompletion := local.compTime;
      goto nextRow;
   END IF;
 
   deb(DEB_EXIT);
END getBackupHistory;
 
--
--
--
--
PROCEDURE findControlfileBackup(
   allCopies      IN boolean default FALSE,
   allBackups     IN boolean default FALSE,
   allIncarnation IN boolean default FALSE,
   fromSCN        IN number  default 0,
   pdbId          IN number  default 0)
IS
   cfrec        rcvRec_t;
   tag          varchar2(32);
   valRC        binary_integer;
   validateRec  validBackupSetRec_t;
   currentInc   number;
   cfUntilScn   number;
   cfRlgScn     number;
BEGIN
   deb(DEB_ENTER, 'findControlfileBackup');
   validateState(null);
 
   IF (allCopies) THEN
      deb(DEB_IN, 'allCopies is TRUE');
   ELSE
      deb(DEB_IN, 'allCopies is FALSE');
   END IF;
 
   IF onlyStandby IS NULL THEN
      deb(DEB_IN, 'onlyStandby is set to NULL ');
   ELSIF onlyStandby = TRUE# THEN
      deb(DEB_IN, 'onlyStandby is set to TRUE ');
   ELSE
      deb(DEB_IN, 'onlyStandby is set to FALSE ');
   END IF;
 
   cfUntilScn := get_cfUntilScn();
   deb(DEB_IN, 'cfUntilScn = ' || nvl(to_char(cfUntilScn), 'NULL'));
 
   IF (allIncarnations = TRUE#) THEN
      deb(DEB_IN, 'allIncarnations = TRUE# ');
      currentInc := FALSE#;                       -- don't care about dbinc_key
      cfRlgScn   := getPointInTimeInc(cfUntilScn);
   ELSE
      deb(DEB_IN, 'allIncarnations <> TRUE# ');
      currentInc := TRUE#;
      cfRlgScn   := this_reset_scn;
   END IF;
   deb(DEB_IN, 'cfRlgScn= ' || nvl(to_char(cfRlgScn), 'NULL'));
 
--
   OPEN findControlfileBackup_c(sourcemask         => restoreSource,
                                currentIncarnation => currentInc,
                                tag                => restoreTag,
                                untilSCN           => cfUntilScn,
                                statusMask         => BSavailable,
                                needstby           => onlyStandby,
                                fromSCN            => fromSCN);
 
--
--
--
   findControlfileBackupCursor := TRUE;
 
--
   resetthisBackupAge;
   getBS_status := NULL;
 
   resetrcvRecStack;
 
   LOOP
      valRC := NULL;
 
      FETCH findControlfileBackup_c
         INTO cfrec;
 
      EXIT WHEN findControlfileBackup_c%NOTFOUND ;
 
      IF (cfrec.type_con = imageCopy_con_t) THEN
         deb(DEB_IN, 'findControlfileBackup found a controlfilecopy:');
         IF (diskDevice) THEN
            valRC := SUCCESS;
         ELSE
            valRC := AVAILABLE;
         END IF;
      ELSIF (cfrec.type_con = backupSet_con_t) THEN
         deb(DEB_IN, 'findControlfileBackup found a controlfile backup:');
         valRC := validateBackupSet(
            backupSetRec           => cfrec,
            tag                    => restoreTag,
            tagMatchRequired       => TRUE,
            checkDeviceIsAllocated => TRUE,
            availableMask          => BSavailable,
            validRec               => validateRec);
      ELSIF (cfrec.type_con = proxyCopy_con_t) THEN
         deb(DEB_IN, 'findControlfileBackup found a controlfile proxy copy:');
         IF (restoreTag is not NULL AND cfrec.tag_con != restoreTag) THEN
--
--
--
            deb(DEB_IN, 'tag does not match');
            valRC := UNAVAILABLE;
         ELSIF (anyDevice = TRUE# OR
                isDeviceTypeAllocated(cfrec.deviceType_con) = TRUE#) THEN
            valRC := SUCCESS;
         ELSE
            valRC := AVAILABLE;
         END IF;
      END IF;
 
--
--
--
--
      IF (cfRlgScn != cfrec.rlgSCN_act AND valRC IS NOT NULL) THEN
         deb(DEB_IN, 'rlgSCN_act= ' || nvl(to_char(cfrec.rlgSCN_act), 'NULL'));
         valRC := NULL;
         IF (cfRlgScn > cfrec.rlgSCN_act AND cfRlgScn > cfrec.toSCN_act) THEN
            deb(DEB_IN, 'findControlfileBackup belongs to parent incarnation');
            EXIT;
         ELSE
            deb(DEB_IN, 'findControlfileBackup belongs to orphan incarnation');
         END IF;
      END IF;
 
--
      IF (valRC IS NOT NULL AND pdbId > 1) THEN
         IF (isPdbScnOrphan(0, cfrec.toSCN_act, 0, pdbId)) THEN
            deb(DEB_IN, 'findControlfileBackup in orphan pdb sub inc');
            valRC := NULL;
         END IF;
      END IF;
 
   <<addAnother>>
      IF (getBS_status IS NULL AND valRC = AVAILABLE) THEN
         getBS_status := valRC;
      END IF;
 
      IF (debug) THEN
         printRcvRec(cfrec);
      END IF;
 
      IF (valRC = SUCCESS) THEN
         IF (thisBackupAge < rcvRecBackupAge) THEN
            deb(DEB_IN, 'skipping action because thisBackupAge (' ||
                         thisBackupAge || ') < rcvRecBackupAge('  ||
                         rcvRecBackupAge || ')');
            thisBackupAge  := thisBackupAge + 1;
         ELSE
            deb(DEB_IN, ' Added cfrec:');
 
            IF (cfrec.type_con = backupSet_con_t) THEN
               cfrec.tag_con        := validateRec.tag;
               cfrec.deviceType_con := validateRec.deviceType;
               cfrec.copyNumber_con := validateRec.copyNumber;
            END IF;
 
            rcvRecPush(cfrec);     -- add record for this action
 
            getBS_status := SUCCESS;
 
            IF (allCopies and cfrec.type_con = backupSet_con_t) THEN
--
--
--
               valRC := validateBackupSet0(
                                      tag                    => restoreTag,
                                      tagMatchRequired       => TRUE,
                                      checkDeviceIsAllocated => TRUE,
                                      validRec               => validateRec);
               IF (valRC = SUCCESS) THEN
                  GOTO addAnother;
               END IF;
            END IF;
            IF (allBackups = FALSE) THEN
                EXIT;
            END IF;
         END IF;
      END IF;
   END LOOP;
 
   CLOSE findControlfileBackup_c;
 
   IF (getBS_status = SUCCESS) THEN
      deb(DEB_EXIT, 'with: SUCCESS');
   ELSIF (getBS_status = AVAILABLE) THEN
      deb(DEB_EXIT, 'with: AVAILABLE');
   ELSE
      getBS_status := UNAVAILABLE;
      deb(DEB_EXIT, 'with: UNAVAILABLE');
   END IF;
END findControlfileBackup;
 
--
FUNCTION getControlfileBackup(
   rcvRec  OUT NOCOPY rcvRec_t)
RETURN number IS
   local        rcvRec_t;
BEGIN
   deb(DEB_ENTER, 'getControlfileBackupBackup');
 
   IF (NOT findControlfileBackupCursor) THEN
--
      findControlfileBackup(FALSE, FALSE, FALSE);
      findControlfileBackupCursor := FALSE;
   END IF;
 
   IF (getRecStackCount = 0) THEN
      IF (getBS_status = SUCCESS) THEN
         deb(DEB_EXIT, 'with no more records');
         raise no_data_found;
      ELSIF (getBS_status = AVAILABLE) THEN
         deb(DEB_EXIT, 'with: AVAILABLE');
         RETURN AVAILABLE;
      ELSE
         deb(DEB_EXIT, 'with: UNAVAILABLE');
         RETURN UNAVAILABLE;
      END IF;
   END IF;
 
   rcvRecPop(local);
   IF (debug) THEN
      printRcvRec(local);
   END IF;
   rcvRec := local;
 
   deb(DEB_EXIT, 'with: SUCCESS');
   RETURN SUCCESS;
END getControlfileBackup;
 
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE findRangeArchivedLogBackup(
   minthread    IN number
  ,minsequence  IN number
  ,minlowSCN    IN number
  ,maxthread    IN number
  ,maxsequence  IN number
  ,maxlowSCN    IN number
  ,allCopies    IN boolean default FALSE)
IS
   lastrec      rcvRec_t;
   brlrec       rcvRec_t;
   validateRec  validBackupSetRec_t;
   tapebkp      rcvRecTabI_t;-- stack of tape backups
   valRC        number;
   BSstatus     number;      -- status of current backup
   skipped      boolean;
   FUNCTION dupbs(bs1 in rcvRec_t, bs2 in rcvRec_t)
      RETURN BOOLEAN IS
   BEGIN
      IF (bs1.type_con != backupSet_con_t OR
          bs2.type_con != backupSet_con_t) THEN
         RETURN FALSE;
      END IF;
 
      IF (bs1.setStamp_con != bs2.setStamp_con OR
          bs1.setCount_con != bs2.setCount_con) THEN
         RETURN FALSE;
      END IF;
 
      RETURN TRUE;
   END dupbs;
 
   FUNCTION pushTapeBackup(tapebkp in rcvRecTabI_t)
      RETURN BOOLEAN IS
      found boolean := FALSE;
   BEGIN
      deb(DEB_IN, 'looking for tape backups');
      FOR i IN 1..tapebkp.count LOOP
--
         EXIT when (found AND NOT dupbs(tapebkp(i), tapebkp(i-1)));
         IF (thisBackupAge < rcvRecBackupAge) THEN
            deb(DEB_IN, 'skipping action because thisBackupAge (' ||
                         thisBackupAge || ') < rcvRecBackupAge('  ||
                         rcvRecBackupAge || ')');
--
            IF (i = 1 OR NOT dupbs(tapebkp(i), tapebkp(i-1))) THEN
               thisBackupAge  := thisBackupAge + 1;
            END IF;
         ELSE
            deb(DEB_IN, 'Added tape backup ' || i);
            rcvRecPush(tapebkp(i));
            found := TRUE;
         END IF;
      END LOOP;
      RETURN found;
   END pushTapeBackup;
BEGIN
   deb(DEB_ENTER, 'findRangeArchivedLogBackup');
 
   validateState(null);
   lastrec.logThread_obj := 0;
 
--
--
--
   deb(DEB_OPEN, 'findRangeArcLogBackup');
   OPEN findRangeArcLogBackup(sourcemask         => to_number(null),
                              minthread          => minthread,
                              minsequence        => minsequence,
                              minlowSCN          => minlowSCN,
                              maxthread          => maxthread,
                              maxsequence        => maxsequence,
                              maxlowSCN          => maxlowSCN);
 
 
   resetrcvRecStack;
   tapebkp.delete;
   BSstatus := NULL;
 
   IF (allCopies) THEN
      deb(DEB_IN, 'allCopies is TRUE');
   ELSE
      deb(DEB_IN, 'allCopies is FALSE');
   END IF;
 
   LOOP
   <<nextbrlRec>>
      valRC := NULL;
 
      FETCH findRangeArcLogBackup
       INTO brlrec;
 
      IF (findRangeArcLogBackup%NOTFOUND) THEN
--
--
--
         IF (BSstatus IS NULL OR BSstatus != SUCCESS) THEN
            IF (pushTapeBackup(tapebkp)) THEN
               BSstatus := SUCCESS;
            END IF;
         END IF;
 
--
--
         IF (BSstatus = AVAILABLE AND lastrec.logThread_obj != 0) THEN
            deb(DEB_IN, ' Added lastlrec:');
--
--
--
            lastrec.status_con := '*';
            rcvRecPush(lastrec);
         END IF;
         EXIT;
      END IF;
 
--
--
      IF (brlrec.logSequence_obj != lastrec.logSequence_obj OR
          brlrec.logThread_obj   != lastrec.logThread_obj   OR
          brlrec.logRlgSCN_obj   != lastrec.logRlgSCN_obj   OR
          brlrec.logRlgTime_obj  != lastrec.logRlgTime_obj  OR
          brlrec.logLowSCN_obj   != lastrec.logLowSCN_obj   OR
          brlrec.logNextSCN_obj   != lastrec.logNextSCN_obj) THEN
--
--
--
         IF (BSstatus IS NULL OR BSstatus != SUCCESS) THEN
            IF (pushTapeBackup(tapebkp)) THEN
               BSstatus := SUCCESS;
            END IF;
         END IF;
 
         resetthisBackupAge;            -- init stack, age, status variables
         tapebkp.delete;
         IF (BSstatus = AVAILABLE) THEN
--
--
--
            deb(DEB_IN, ' Added lastlrec:');
            lastrec.status_con := '*';
            rcvRecPush(lastrec);
         END IF;
         BSstatus := NULL;              -- reset backup status for next record
 
--
         IF NOT isTranslatedArchivedLog(
                   thread#   => brlrec.logThread_obj
                  ,sequence# => brlrec.logSequence_obj) THEN
            deb(DEB_IN, 'skip not translated brlrec' ||
                ' thread=' || brlrec.logThread_obj ||
                ' sequence=' || brlrec.logSequence_obj);
            goto nextbrlRec;
         END IF;
 
--
--
         lastrec := brlrec;
         deb(DEB_IN, 'looking backups for' ||
             ' thread=' || brlrec.logThread_obj ||
             ' sequence=' || brlrec.logSequence_obj);
      END IF;
 
      IF (BSstatus = SUCCESS) THEN
         deb(DEB_IN, 'skip already stacked brlrec' ||
             ' thread=' || brlrec.logThread_obj ||
             ' sequence=' || brlrec.logSequence_obj);
         goto nextbrlRec;
      END IF;
 
      IF (brlrec.type_con = backupSet_con_t) THEN
         deb(DEB_IN, 'found a backupset:');
         valRC :=
           validateBackupSet(backupSetRec           => brlrec,
                             checkDeviceIsAllocated => TRUE,
                             tag                    => restoreTag,
                             tagMatchRequired       => TRUE,
                             availableMask          => BSavailable,
                             validRec               => validateRec);
      ELSIF (brlrec.type_con = proxyCopy_con_t) THEN
         deb(DEB_IN, 'found a proxy copy:');
         IF (restoreTag is not NULL AND brlrec.tag_con != restoreTag) THEN
--
--
--
            deb(DEB_EXIT, 'tag does not match');
            valRC := UNAVAILABLE;
         ELSIF (anyDevice = TRUE# OR
                isDeviceTypeAllocated(brlrec.deviceType_con) = TRUE#) THEN
            valRC := SUCCESS;
         ELSE
            valRC := AVAILABLE;
         END IF;
      END IF;
 
      skipped := FALSE;
 
   <<addAnother>>
      IF (BSstatus IS NULL AND valRC = AVAILABLE) THEN
         BSstatus := valRC;
      END IF;
 
      IF (debug) THEN
         printRcvRec(brlrec);
      END IF;
 
      IF (valRC = SUCCESS) THEN
         IF (brlrec.type_con = backupSet_con_t) THEN
            brlrec.tag_con        := validateRec.tag;
            brlrec.deviceType_con := validateRec.deviceType;
            brlrec.copyNumber_con := validateRec.copyNumber;
         END IF;
 
--
--
--
--
         IF (NOT skipped AND
             brlrec.deviceType_con = 'DISK' AND
             thisBackupAge < rcvRecBackupAge) THEN
            deb(DEB_IN, 'skipping action because thisBackupAge (' ||
                         thisBackupAge || ') < rcvRecBackupAge('  ||
                         rcvRecBackupAge || ')');
--
--
            skipped := TRUE;
            thisBackupAge  := thisBackupAge + 1;
         ELSE
            IF (brlrec.deviceType_con = 'DISK') THEN
               IF (NOT skipped) THEN
                  deb(DEB_IN, ' Added brlrec:');
                  rcvRecPush(brlrec);     -- add record for this action
                  BSstatus := SUCCESS;
               END IF;
            ELSE
--
               deb(DEB_IN, ' Added brlrec to tapebkp stack:' ||
                           to_char(tapebkp.count+1));
               tapebkp(tapebkp.count+1) := brlrec;
            END IF;
         END IF;
 
         IF (allCopies AND brlrec.type_con = backupSet_con_t) THEN
--
--
--
            valRC := validateBackupSet0(
                                  tag                    => restoreTag,
                                  tagMatchRequired       => TRUE,
                                  checkDeviceIsAllocated => TRUE,
                                  validRec               => validateRec);
            IF (valRC = SUCCESS) THEN
               GOTO addAnother;
            END IF;
         END IF;
      END IF;
   END LOOP;
 
   CLOSE findRangeArcLogBackup;
 
   deb(DEB_EXIT);
END findRangeArchivedLogBackup;
 
--
--
PROCEDURE findArchivedLogBackup(
   thread    IN number
  ,sequence  IN number
  ,lowSCN    IN number
  ,allCopies IN boolean default FALSE)
IS
   local        rcvRec_t;
BEGIN
   deb(DEB_ENTER, 'findArchivedLogBackup');
 
--
   setArchivedLogRecord(thread#   => thread
                       ,sequence# => sequence
                       ,first     => TRUE);
 
--
--
--
   findRangeArchivedLogBackup(minthread   => thread,
                             minsequence => sequence,
                             minlowSCN   => lowSCN,
                             maxthread   => thread,
                             maxsequence => sequence,
                             maxlowSCN   => lowSCN,
                             allCopies   => allCopies);
   IF (getRecStackCount = 0) THEN
      getBS_status := NULL;
      deb(DEB_EXIT, 'with UNAVAILABLE');
   ELSE
      rcvRecTop(local);
--
--
      IF (local.status_con = '*') THEN
         getBS_status := AVAILABLE;
         resetrcvRecStack;
         deb(DEB_EXIT, 'with AVAILABLE');
      ELSE
         getBS_status := SUCCESS;
         deb(DEB_EXIT, 'with SUCCESS');
      END IF;
   END IF;
END findArchivedLogBackup;
 
--
--
FUNCTION getArchivedLogBackup(
   rcvRec  OUT NOCOPY rcvRec_t)
RETURN binary_integer IS
   local        rcvRec_t;
BEGIN
   deb(DEB_ENTER, 'getArchivedLogBackup');
 
   IF (getRecStackCount = 0) THEN
      IF (getBS_status = SUCCESS) THEN
         deb(DEB_EXIT, 'with no more records');
         raise no_data_found;
      ELSIF (getBS_status = AVAILABLE) THEN
         deb(DEB_EXIT, 'with: AVAILABLE');
         RETURN AVAILABLE;
      ELSE
         deb(DEB_EXIT, 'with: UNAVAILABLE');
         RETURN UNAVAILABLE;
      END IF;
   END IF;
 
   rcvRecPop(local);
   IF (debug) THEN
      printRcvRec(local);
   END IF;
   rcvRec := local;
 
   deb(DEB_EXIT, 'with: SUCCESS');
   RETURN SUCCESS;
END getArchivedLogBackup;
 
--
--
--
 
--
PROCEDURE findSpfileBackup(
   allCopies  IN boolean default FALSE         -- duplex copies
  ,redundancy IN number  default NULL          -- number of redundant copies
  ,rmanCmd    IN number  default unknownCmd_t) -- called for what rman command?
IS
  scn_warn number;
BEGIN
  findSpfileBackup(allCopies, redundancy, rmanCmd, scn_warn);
END findSpfileBackup;
 
PROCEDURE findSpfileBackup(
   allCopies  IN boolean default FALSE         -- duplex copies
  ,redundancy IN number  default NULL          -- number of redundant copies
  ,rmanCmd    IN number  default unknownCmd_t  -- called for what rman command?
  ,scn_warn  OUT number)
IS
   bsfrec       rcvRec_t;
   tag          varchar2(32);
   valRC        binary_integer;
   validateRec  validBackupSetRec_t;
   lcopies      number;
   findtime     date;
   estimated    boolean := TRUE;
BEGIN
   deb(DEB_ENTER, 'findSpfileBackup');
   validateState(null);
 
--
   scn_warn := 0;
   IF (untilScn IS NOT NULL AND untilTime IS NULL) THEN
      computeSpfileTime(untilScn, findtime, allIncarnations, estimated);
      IF estimated THEN scn_warn := 1; END IF;
   ELSE
      findtime := untilTime;
   END IF;
 
--
   deb(DEB_OPEN, 'findSpfileBackup_c,rmanCmd=' || rmanCmd);
 
   OPEN findSpfileBackup_c(untilTime => findTime,
                           rmanCmd   => rmanCmd);
 
--
--
--
   findSpfileBackupCursor := TRUE;
 
--
   resetthisBackupAge;
   getBS_status := NULL;
 
   resetrcvRecStack;
 
   IF (allCopies) THEN
      deb(DEB_IN, 'allCopies is TRUE');
   ELSE
      deb(DEB_IN, 'allCopies is FALSE');
   END IF;
 
   lcopies := redundancy;
 
--
   IF (rmanCmd = obsoleteCmd_t AND allCopies) THEN
      raise_application_error(-20999, 'internal error: findSpfileBackup_1');
   END IF;
 
   LOOP
      valRC := NULL;
 
      FETCH findSpfileBackup_c
       INTO bsfrec;
 
      EXIT WHEN findSpfileBackup_c%NOTFOUND ;
 
      IF user_site_key is not null and user_db_unique_name is NOT NULL THEN
         user_site_key := null;
         deb(DEB_IN, 'Spfile backups are identified based on db_unique_name');
      END IF;
 
      IF (rmanCmd = obsoleteCmd_t) THEN
--
--
         valRC := SUCCESS;
      ELSE
         valRC := validateBackupSet(
               backupSetRec           => bsfrec,
               tag                    => restoreTag,
               tagMatchRequired       => TRUE,
               checkDeviceIsAllocated => TRUE,
               availableMask          => BSavailable,
               validRec               => validateRec);
      END IF;
 
   <<addAnother>>
      IF (getBS_status IS NULL AND valRC = AVAILABLE) THEN
         getBS_status := valRC;
      END IF;
 
      IF (debug) THEN
         printRcvRec(bsfRec);
      END IF;
 
      IF (valRC = SUCCESS) THEN
         IF (thisBackupAge < rcvRecBackupAge) THEN
            deb(DEB_IN, 'skipping action because thisBackupAge (' ||
                         thisBackupAge || ') < rcvRecBackupAge('  ||
                         rcvRecBackupAge || ')');
            thisBackupAge  := thisBackupAge + 1;
         ELSIF (rmanCmd = obsoleteCmd_t) THEN
            deb(DEB_IN, ' Added bsfRec:');
 
            rcvRecPush(bsfRec);     -- add record for this action
            getBS_status := SUCCESS;
            IF (lcopies > 1) THEN
               lcopies := lcopies - 1;
            ELSE
               EXIT;              -- we are done
            END IF;
         ELSE
            deb(DEB_IN, ' Added bsfRec:');
 
            bsfrec.tag_con        := validateRec.tag;
            bsfrec.deviceType_con := validateRec.deviceType;
            bsfrec.copyNumber_con := validateRec.copyNumber;
 
            rcvRecPush(bsfRec);     -- add record for this action
 
            getBS_status := SUCCESS;
 
            IF (allCopies) THEN                   -- requested duplex copies
--
--
               valRC :=
                  validateBackupSet0(tag                    => restoreTag,
                                     tagMatchRequired       => TRUE,
                                     checkDeviceIsAllocated => TRUE,
                                     validRec               => validateRec);
               IF (valRC = SUCCESS) THEN
                  GOTO addAnother;
               END IF;
            END IF;
 
            IF (lcopies > 1) THEN
               lcopies := lcopies - 1;
            ELSE
               EXIT;              -- we are done
            END IF;
         END IF;
      END IF;
   END LOOP;
 
   CLOSE findSpfileBackup_c;
 
   IF (getBS_status = AVAILABLE) THEN
      deb(DEB_EXIT, 'with: AVAILABLE');
   ELSIF (getBS_status = SUCCESS) THEN
      deb(DEB_EXIT, 'with: SUCCESS');
   ELSE
      getBS_status := UNAVAILABLE;
      deb(DEB_EXIT, 'with: UNAVAILABLE');
   END IF;
END findSpfileBackup;
 
--
FUNCTION getSpfileBackup(
   rcvRec     OUT NOCOPY rcvRec_t
  ,redundancy IN         number default NULL
  ,rmanCmd    IN         number default unknownCmd_t)
RETURN number IS
   local        rcvRec_t;
   dummy        number;
BEGIN
   deb(DEB_ENTER, 'getSpfileBackup');
 
   IF (NOT findSpfileBackupCursor) THEN
--
      findSpfileBackup(allcopies  => FALSE,
                       redundancy => redundancy,
                       rmanCmd    => rmanCmd,
                       scn_warn   => dummy);
   END IF;
 
   IF (getRecStackCount = 0) THEN
      IF (getBS_status = SUCCESS) THEN
         deb(DEB_EXIT, 'with no more records');
         raise no_data_found;
      ELSIF (getBS_status = AVAILABLE) THEN
         deb(DEB_EXIT, 'with: AVAILABLE');
         RETURN AVAILABLE;
      ELSE
         deb(DEB_EXIT, 'with: UNAVAILABLE');
         RETURN UNAVAILABLE;
      END IF;
   END IF;
 
   rcvRecPop(local);
   IF (debug) THEN
      printRcvRec(local);
   END IF;
   rcvRec := local;
 
   deb(DEB_EXIT, 'with: SUCCESS');
   RETURN SUCCESS;
END getSpfileBackup;
 
--
PROCEDURE getCopyofDatafile(
   first           IN      boolean
  ,itag            IN      varchar2
  ,fno             OUT     number
  ,crescn          OUT     number
  ,rlogscn         OUT     number
  ,rlgtime         OUT     date
  ,recid           OUT     binary_integer
  ,stamp           OUT     binary_integer
  ,name            OUT     varchar2
  ,otag            OUT     varchar2
  ,status          OUT     varchar2
  ,nblocks         OUT     number
  ,bsz             OUT     binary_integer
  ,ctime           OUT     date
  ,toscn           OUT     number
  ,totime          OUT     date
  ,pluggedRonly    OUT     binary_integer
  ,pluginSCN       OUT     number
  ,pluginRlgSCN    OUT     number
  ,pluginRlgTime   OUT     date)
IS
   inc_idx     binary_integer;
   afzSCN      number;
BEGIN
   deb(DEB_ENTER, 'getCopyofDatafile');
 
   IF first THEN
      IF (getCopyofDatafile_c2%ISOPEN) THEN
         CLOSE getCopyofDatafile_c2;
      END IF;
 
      deb(DEB_PRINT, 'opening cursor');
      OPEN getCopyofDatafile_c2(itag);
   END IF;
 
<<next>>
   FETCH getCopyofDatafile_c2
    INTO fno, crescn, rlogscn, rlgtime, recid, stamp, name, otag, status,
         nblocks, bsz, ctime, toscn, totime, pluggedRonly, pluginSCN,
         pluginRlgSCN, pluginRlgTime, afzSCN;
 
   IF getCopyofDatafile_c2%NOTFOUND THEN
      deb(DEB_PRINT, 'closing cursor');
      CLOSE getCopyofDatafile_c2;
      deb(DEB_EXIT, 'with: no data found');
      RAISE no_data_found;
   END IF;
 
   FOR inc_idx in 0..max_inc_idx-1 LOOP
      IF (rlogscn = inc_list(inc_idx).resetlogs_change#  AND
          rlgtime = inc_list(inc_idx).resetlogs_time ) THEN
         IF (inc_idx = 0 OR
             nvl(greatest(afzSCN, toSCN), toSCN) <
                inc_list(inc_idx-1).resetlogs_change#) THEN
            deb(DEB_PRINT, 'matches inc=' ||inc_idx);
--
--
--
--
--
--
--
--
            EXIT;
--
         ELSE
            deb(DEB_PRINT, 'inc='||inc_idx|| ',toscn='||toscn||
                           ' exceeds '||inc_list(inc_idx-1).resetlogs_change#);
            deb(DEB_PRINT, 'belongs to orphan branch of this incarnation:');
            GOTO next;
         END IF;
      END IF;
   END LOOP;
 
   deb(DEB_EXIT, 'with: file found');
END getCopyOfDatafile;
 
--
--
PROCEDURE getCopyofDatafile(
   dfnumber        IN      number
  ,itag            IN      varchar2
  ,crescn          IN  OUT number
  ,rlogscn         IN  OUT number
  ,rlgtime         IN  OUT date
  ,recid           OUT     binary_integer
  ,stamp           OUT     binary_integer
  ,name            OUT     varchar2
  ,otag            OUT     varchar2
  ,status          OUT     varchar2
  ,nblocks         OUT     binary_integer
  ,bsz             OUT     binary_integer
  ,ctime           OUT     date
  ,toscn           OUT     number
  ,totime          OUT     date
  ,pluggedRonly    OUT     binary_integer
  ,pluginSCN       IN      number)
IS
BEGIN
OPEN getCopyofDatafile_c(dfnumber, itag, crescn, rlogscn,
                         rlgtime, pluginSCN);
 
FETCH getCopyofDatafile_c
 INTO recid, stamp, name, otag, status, nblocks,
      bsz, ctime, toscn, totime, crescn,
      rlogscn, rlgtime, pluggedRonly;
 
IF getCopyofDatafile_c%NOTFOUND THEN
   CLOSE getCopyofDatafile_c;
   RAISE no_data_found;
END IF;
 
CLOSE getCopyofDatafile_c;
END getCopyOfDatafile;
 
--
PROCEDURE getCopyofDatafile(
   dfnumber        IN  number
  ,itag            IN  varchar2
  ,crescn          IN  number
  ,rlogscn         IN  number
  ,rlgtime         IN  date
  ,recid           OUT binary_integer
  ,stamp           OUT binary_integer
  ,name            OUT varchar2
  ,otag            OUT varchar2
  ,status          OUT varchar2
  ,nblocks         OUT binary_integer
  ,bsz             OUT binary_integer
  ,ctime           OUT date
  ,toscn           OUT number
  ,totime          OUT date)
IS
   loc_crescn    number := crescn;
   loc_rlogscn   number := rlogscn;
   loc_rlgtime   date   := rlgtime;
   pluggedRonly  binary_integer;
   pluginSCN     number;
BEGIN
   getCopyOfDatafile(dfnumber  => dfnumber
                    ,itag      => itag
                    ,crescn    => loc_crescn
                    ,rlogscn   => loc_rlogscn
                    ,rlgtime   => loc_rlgtime
                    ,recid     => recid
                    ,stamp     => stamp
                    ,name      => name
                    ,otag      => otag
                    ,status    => status
                    ,nblocks   => nblocks
                    ,bsz       => bsz
                    ,ctime     => ctime
                    ,toscn     => toscn
                    ,totime    => totime
                    ,pluggedRonly => pluggedRonly
                    ,pluginSCN => 0);
END getCopyOfDatafile;
 
 
--
--
--
 
--
PROCEDURE setCompletedRange(
   after  IN date
  ,before IN date)
IS
BEGIN
   getRA_completedAfter  := after;
   getRA_completedBefore := before;
END setCompletedRange;
 
--
PROCEDURE setLikePattern(
   pattern IN varchar2)
IS
BEGIN
   getRA_likePattern := pattern;
END setLikePattern;
 
--
PROCEDURE setcanApplyAnyRedo(
   flag IN boolean)
IS
BEGIN
   IF (flag) THEN
      deb(DEB_PRINT, 'canApplyAnyRedo is set to TRUE');
      canApplyAnyRedo := TRUE#;
   ELSE
      deb(DEB_PRINT, 'canApplyAnyRedo is set to FALSE');
      canApplyAnyRedo := FALSE#;
   END IF;
END setcanApplyAnyRedo;
 
--
PROCEDURE setCanConvertCf(
   flag IN boolean)
IS
BEGIN
   IF (flag) THEN
      deb(DEB_PRINT, 'canConvert_Cf is set to TRUE');
      canConvert_Cf := TRUE#;
   ELSE
      deb(DEB_PRINT, 'canConvert_Cf is set to FALSE');
      canConvert_Cf := FALSE#;
   END IF;
END setCanConvertCf;
 
--
PROCEDURE setAllIncarnations(
   flag IN boolean)
IS
BEGIN
   IF (flag) THEN
      deb(DEB_PRINT, 'allIncarnations is set to TRUE');
      allIncarnations := TRUE#;
   ELSE
      deb(DEB_PRINT, 'allIncarnations is set to FALSE');
      allIncarnations := FALSE#;
   END IF;
END setAllIncarnations;
 
--
FUNCTION isTranslatedFno(fno IN NUMBER) RETURN NUMBER IS
BEGIN
   IF (tc_database = TRUE# OR fno = 0 OR tc_fno.exists(fno)) THEN
      RETURN TRUE#;
   ELSE
      RETURN FALSE#;
   END IF;
END isTranslatedFno;
 
--
PROCEDURE setUntilResetlogs
IS
BEGIN
   untilSCN := this_reset_scn;
   untilTime := NULL;
   rpoint_set := FALSE;
 
   IF (this_reset_scn is NULL) THEN
      raise_application_error(-20020, 'Database incarnation not set');
   END IF;
END setUntilResetlogs;
 
--
PROCEDURE setGuid(
   guid IN varchar2 DEFAULT NULL)
IS
BEGIN
   guidQualifier := guid;
--
   guid2pdbKeyQualifier := guidToPdbKey(guid);
--
END setGuid;
 
--
--
--
--
PROCEDURE translateTempfile
IS
BEGIN
   IF (translateTempfile_c%ISOPEN) THEN
      validateState('translateTempfile_c');                  -- raise the error
   END IF;
 
   IF (pdbIdList.count = 0) THEN
      OPEN translateTempfile_c;
      getTempfileCursor := 'translateTempfile_c';
   ELSIF (pdbIdList.count = 1) THEN
      OPEN translateTempfileOfPdbId_c(pdbIdList.first + CONST2GVAL);
      getTempfileCursor := 'translateTempfileOfPdbId_c';
   ELSE
      OPEN translateTempfileOfPdbIdL_c;
      getTempfileCursor := 'translateTempfileOfPdbIdL_c';
   END IF;
END translateTempfile;
 
--
PROCEDURE translateTempfile(
   fname IN varchar2)
IS
BEGIN
   IF (translateTempfileName_c%ISOPEN) THEN
      validateState('translateTempfileName_c');              -- raise the error
   END IF;
 
   OPEN translateTempfileName_c(fileName => fname);
   getTempfileCursor := 'translateTempfileName_c';
END translateTempfile;
 
--
PROCEDURE translateTempfile(
   fno IN number)
IS
BEGIN
   IF (translateTempfileNumber_c%ISOPEN) THEN
      validateState('translateTempfileNumber_c');            -- raise the error
   END IF;
 
   OPEN translateTempfileNumber_c(fno => fno);
   getTempfileCursor := 'translateTempfileNumber_c';
END translateTempfile;
 
--
PROCEDURE getTempfile(
   tfRec  OUT NOCOPY tfRec_t)
IS
   eof   boolean := FALSE;
BEGIN
   IF (getTempfileCursor = 'translateTempfile_c') THEN
      FETCH translateTempfile_c
       INTO tfRec;
      IF (translateTempfile_c%NOTFOUND) THEN
         CLOSE translateTempfile_c;
         eof := TRUE;
      END IF;
   ELSIF (getTempfileCursor = 'translateTempfileOfPdbId_c') THEN
      FETCH translateTempfileOfPdbId_c
       INTO tfRec;
      IF (translateTempfileOfPdbId_c%NOTFOUND) THEN
         CLOSE translateTempfileOfPdbId_c;
         eof := TRUE;
      END IF;
   ELSIF (getTempfileCursor = 'translateTempfileOfPdbIdL_c') THEN
      FETCH translateTempfileOfPdbIdL_c
       INTO tfRec;
      IF (translateTempfileOfPdbIdL_c%NOTFOUND) THEN
         CLOSE translateTempfileOfPdbIdL_c;
         eof := TRUE;
      END IF;
   ELSIF (getTempfileCursor = 'translateTempfileName_c') THEN
      FETCH translateTempfileName_c
       INTO tfRec;
      IF (translateTempfileName_c%NOTFOUND) THEN
         CLOSE translateTempfileName_c;
         eof := TRUE;
      END IF;
   ELSIF (getTempfileCursor = 'translateTempfileNumber_c') THEN
      FETCH translateTempfileNumber_c
       INTO tfRec;
      IF (translateTempfileNumber_c%NOTFOUND) THEN
         CLOSE translateTempfileNumber_c;
         eof := TRUE;
      END IF;
   ELSE
      deb(DEB_EXIT, 'with error 20204');
      raise_application_error(-20204, 'Translation not started');
   END IF;
 
   IF (eof) THEN
      getTempfileCursor := NULL;
      RAISE no_data_found;                   -- signal end-of-fetch
   END IF;
 
--
--
--
   IF (tfRec.pdbName IS NULL) THEN
      tfRec.pdbName := translatePdb2Name(tfRec.pdbid);
   END IF;
END getTempfile;
 
--
PROCEDURE translateDatafileCancel IS
BEGIN
   IF (getDatafileCursor = 'translateDatafileName') THEN
      CLOSE translateDatafileName;
   ELSIF (getDatafileCursor = 'translateDatafileNumber') THEN
      CLOSE translateDatafileNumber;
   ELSIF (getDatafileCursor = 'translateDatafileCheckpoint') THEN
      CLOSE translateDatafileCheckpoint;
   END IF;
   getDatafileCursor := NULL;                   -- we closed it above
   getDatafileNoRows.error := NULL;             -- clear for next time
   getDatafileLast.dfNumber := NULL;            -- clear for next time
END translateDatafileCancel;
 
--
FUNCTION Num2DisplaySize(input_size IN NUMBER) return VARCHAR2 IS
   OneK number := 1024;
   OneM number := OneK * 1024;
   OneG number := OneM * 1024;
   OneT number := OneG * 1024;
   OneP number := OneT * 1024;
BEGIN
   IF input_size IS NULL THEN
      return NULL;
   ELSE
     IF (input_size < OneM) THEN
        return to_char(input_size/OneK,'9990.09') ||'K';
     ELSIF (input_size < OneG)  THEN
        return to_char(input_size/OneM,'9990.09') ||'M';
     ELSIF (input_size < OneT) THEN
        return to_char(input_size/OneG,'9990.09') ||'G';
     ELSIF (input_size < OneP) THEN
        return to_char(input_size/OneT,'9990.09') ||'T';
     ELSE
        return to_char(input_size/OneP,'9990.09') ||'P';
     END IF;
   END IF;
END Num2DisplaySize;
 
--
FUNCTION Sec2DisplayTime(input_secs IN NUMBER) return VARCHAR2 IS
   inputsecs number ; 
BEGIN
   IF input_secs IS NULL THEN
      return NULL;
   END IF;
   inputsecs := round(input_secs) ;
   RETURN to_char(floor(inputsecs/3600),'FM09')||':'||
            to_char(floor(mod(inputsecs,3600)/60),'FM09')||':'||
            to_char(mod(inputsecs,60),'FM09');
END Sec2DisplayTime;
 
--
PROCEDURE setArchivedLogRecord(
   thread#   IN  number
  ,sequence# IN  number
  ,first     IN  boolean)
IS
  seqTab   sequenceTab_t;
  thrbck   binary_integer;
  seqbck   binary_integer;
BEGIN
   IF first THEN
      tc_threadSeq.delete;
   END IF;
 
--
   IF (thread# >= CONST2GVAL) THEN
      thrbck := CONST2GVAL - thread#;
   ELSE
      thrbck := thread#;
   END IF;
 
--
   IF (sequence# >= CONST2GVAL) THEN
      seqbck := CONST2GVAL - sequence#;
   ELSE
      seqbck := sequence#;
   END IF;
 
   IF NOT tc_threadSeq.exists(thrbck) THEN
      tc_threadSeq(thrbck) := seqTab;
   END IF;
   tc_threadseq(thrbck)(seqbck) := TRUE;
END setArchivedLogRecord;
 
--
PROCEDURE setCanHandleTransportableTbs(
   flag IN boolean)
IS
BEGIN
   IF (flag) THEN
      deb(DEB_PRINT, 'canHandleTransportableTbs is set to TRUE');
      canHandleTransportableTbs := TRUE#;
   ELSE
      deb(DEB_PRINT, 'canHandleTransportableTbs is set to FALSE');
      canHandleTransportableTbs := FALSE#;
   END IF;
END setCanHandleTransportableTbs;
 
--
PROCEDURE getRestorePoint(
   name         IN  varchar2
  ,rlgscn       OUT number
  ,rlgtime      OUT date
  ,scn          OUT number
  ,guaranteed   OUT number)
IS
   clean      number;
   out_con_id number;
BEGIN
   getRestorePoint(name, rlgscn, rlgtime, scn, guaranteed,
                   0, clean, out_con_id);
END getRestorePoint;
 
PROCEDURE getRestorePoint(
   name         IN  varchar2
  ,rlgscn       OUT number
  ,rlgtime      OUT date
  ,scn          OUT number
  ,guaranteed   OUT number
  ,con_id       IN  number
  ,clean        OUT number
  ,out_con_id   OUT number)
IS
   rsp  restore_point_c%ROWTYPE;
   rsp2 restore_point_c%ROWTYPE;
BEGIN
   deb(DEB_ENTER, 'getRestorePoint');
   IF (restore_point_c%isopen) THEN
      CLOSE restore_point_c;
   END IF;
 
   OPEN restore_point_c(con_id, name);
   FETCH restore_point_c INTO rsp;
   IF restore_point_c%NOTFOUND
   THEN
      rlgscn     := NULL;
      rlgtime    := NULL;
      scn        := NULL;
      guaranteed := NULL;
      clean      := NULL;
   ELSE
      rlgscn     := rsp.reset_scn;
      rlgtime    := rsp.reset_time;
      scn        := rsp.scn;
      out_con_id := rsp.con_id;
      IF (rsp.clean = 'YES')
      THEN
         clean := 1;
      ELSE
         clean := 0;
      END IF;
      IF (rsp.guaranteed = 'YES')
      THEN
        guaranteed := 1;
      ELSE
        guaranteed := 0;
      END IF;
   END IF;
 
   FETCH restore_point_c INTO rsp2;
 
--
   IF ((NOT restore_point_c%NOTFOUND) AND (rsp.con_id = rsp2.con_id))
   THEN
      deb(DEB_EXIT, 'with error 20513');
      raise_application_error(-20513,
         'Restore point name is ambiguous, specify the SCN instead');
   END IF;
   CLOSE restore_point_c;
   deb(DEB_EXIT);
END getRestorePoint;
 
--
PROCEDURE listTranslateRestorePoint(
   name       IN  varchar2)
IS
BEGIN
   deb(DEB_ENTER, 'listTranslateRestorePoint');
 
   IF (restore_point_c%isopen) THEN
      CLOSE restore_point_c;
   END IF;
 
   deb(DEB_OPEN, 'restore_point_c');
   OPEN restore_point_c(con_id => 0, name => name);
   deb(DEB_EXIT);
END listTranslateRestorePoint;
 
--
PROCEDURE listGetRestorePoint(
   name         OUT varchar2
  ,scn          OUT number
  ,rsptime      OUT date
  ,cretime      OUT date
  ,rsptype      OUT varchar2)
IS
  pdbname  varchar2(128);
BEGIN
   listGetRestorePoint(name, scn, rsptime, cretime, rsptype, pdbname);
END listGetRestorePoint;
   
PROCEDURE listGetRestorePoint(
   name         OUT varchar2
  ,scn          OUT number
  ,rsptime      OUT date
  ,cretime      OUT date
  ,rsptype      OUT varchar2
  ,pdbname      OUT varchar2)
IS
   rsp restore_point_c%ROWTYPE;
BEGIN
   deb(DEB_ENTER, 'listGetRestorePoint');
 
   FETCH restore_point_c INTO rsp;
   IF (restore_point_c%NOTFOUND) THEN
      CLOSE restore_point_c;
      deb(DEB_EXIT, 'with no more records');
      RAISE no_data_found;
   END IF;
 
   name := rsp.name;
   scn := rsp.scn;
   rsptime := rsp.restore_point_time;
   cretime := rsp.creation_time;
--
   rsptype := ' ';
   IF rsp.preserved = 'YES'
   THEN
     rsptype := 'PRESERVED';
   END IF;
--
   IF rsp.guaranteed = 'YES'
   THEN
     rsptype := 'GUARANTEED';
   END IF;
   pdbname := translatePdb2Name(rsp.con_id);
   deb(DEB_EXIT);
END listGetRestorePoint;
 
--
PROCEDURE setDbidTransClause(dbid IN  number)
IS
  dbidbck  binary_integer;
BEGIN
--
   IF (dbid >= CONST2GVAL) THEN
      dbidbck := CONST2GVAL - dbid;
   ELSE
      dbidbck := dbid;
   END IF;
   tc_dbid(dbidbck) := TRUE;
END setDbidTransClause;
 
--
FUNCTION isTranslatedDbid(dbid IN NUMBER) RETURN NUMBER
IS
  dbidbck  binary_integer;
BEGIN
   IF (tc_anydbid = TRUE#) THEN
      RETURN TRUE#;
   ELSE
--
      IF (dbid >= CONST2GVAL) THEN
         dbidbck := CONST2GVAL - dbid;
      ELSE
         dbidbck := dbid;
      END IF;
      IF (tc_dbid.exists(dbidbck)) THEN
         RETURN TRUE#;
      END IF;
   END IF;
   RETURN FALSE#;
END isTranslatedDbid;
 
--
FUNCTION translatePdbName(pdbName IN VARCHAR2) 
RETURN NUMBER IS
   pdbGuid  VARCHAR2(128);
BEGIN
    RETURN translatePdbName(pdbName, pdbGuid);
END translatePdbName;
 
--
FUNCTION translatePdbName(pdbName IN VARCHAR2, pdbGuid OUT VARCHAR2)
RETURN NUMBER IS
   local    pdbNameRec_t;
BEGIN
   initPdbNameList;
 
   IF (pdbNameList.exists(pdbName)) THEN
      local := pdbNameList(pdbName);
      pdbGuid := local.pdbGuid;
      RETURN local.pdbId;
   ELSE
      pdbGuid := NULL;
      RETURN NULL;
   END IF;
END translatePdbName;
 
--
PROCEDURE resetPdbIdList IS
BEGIN
   pdbIdList.delete;
END resetPdbIdList;
 
--
PROCEDURE setPdbId(pdbId IN NUMBER, first IN BOOLEAN) IS
BEGIN
   IF (first) THEN
      resetPdbIdList;
   END IF;
 
   pdbIdList(pdbId - CONST2GVAL) := TRUE;
END setPdbId;
 
--
FUNCTION isTranslatedPdbId(pdbId IN NUMBER) RETURN NUMBER IS
BEGIN
   IF (pdbIdList.exists(pdbId - CONST2GVAL)) THEN
      RETURN TRUE#;
   END IF;
   
   RETURN FALSE#;
END isTranslatedPdbId;
 
--
FUNCTION isPdbScnOrphan(untilSCN IN NUMBER, pdbId IN NUMBER)
RETURN NUMBER IS
   toSCN NUMBER := untilSCN - 1;
BEGIN
   IF (isPdbScnOrphan(0, toSCN, 0, pdbId)) THEN
      RETURN TRUE#;
   ELSE
      RETURN FALSE#;
   END IF;
END isPdbScnOrphan;
 
--
FUNCTION translatePdb2Name(pdbId IN NUMBER) RETURN VARCHAR2 IS
   pdbname  VARCHAR2(128);
BEGIN
--
--
   IF (pdbId IS NULL) THEN
      RETURN NULL;
   END IF;
 
   IF (pdbId <= 1) THEN
      RETURN NULL;
   END IF;
 
   initPdbNameList;
 
   IF (pdbId2NameList.exists(pdbId)) THEN
      RETURN pdbId2NameList(pdbId);
   ELSE
      RETURN NULL;
   END IF;
 
END translatePdb2Name;
 
--
FUNCTION translatePdbGuid2Name(pdbGuid IN VARCHAR2, pdbId OUT NUMBER) 
RETURN VARCHAR2 IS
   local      pdbNameRec_t;
BEGIN
--
--
   IF (pdbGuid IS NULL) THEN
      pdbId := NULL;
      RETURN NULL;
   END IF;
 
   initPdbNameList;
 
   IF (pdbGuidList.exists(pdbGuid)) THEN
      local := pdbGuidList(pdbGuid);
      pdbId := local.pdbId;
      RETURN local.name;
   ELSE
      pdbId := NULL;
      RETURN NULL;
   END IF;
 
END translatePdbGuid2Name;
 
--
PROCEDURE setRestoreRangeDevTyp(typ IN VARCHAR2)
IS
BEGIN
   deb(DEB_ENTER, 'setRestoreRangeDevTyp');
 
   restoreRangeDevTyp := typ;
   deb(DEB_EXIT);
END setRestoreRangeDevTyp;
 
--
PROCEDURE setSkipOfflineRangeAboveSCN(maxCheckpointSCN IN NUMBER)
IS
BEGIN
   deb(DEB_ENTER, 'setSkipOfflineRangeAboveSCN');
   skipOfflineRangeAboveSCN := maxCheckpointSCN;
   deb(DEB_EXIT);
END setSkipOfflineRangeAboveSCN;
 
--
PROCEDURE resetRestoreRangeDevTyp
IS
BEGIN
   deb(DEB_ENTER, 'resetRestoreRangeDevTyp');
 
   restoreRangeDevTyp := null;
   deb(DEB_EXIT);
END resetRestoreRangeDevTyp;
 
--
PROCEDURE translatePrePluginDf(con_id IN number)
IS
BEGIN
   deb(DEB_ENTER, 'translatePrePluginDf');
--
   raise_application_error(-20999, 'Not supported in recovery catalog');
--
 
   deb(DEB_EXIT);
END translatePrePluginDf;
 
--
FUNCTION getPrePluginDf(
   prePluginDfRec OUT NOCOPY prePluginDfRec_t)
RETURN NUMBER IS
BEGIN
   deb(DEB_ENTER, 'getPrePluginDf');
--
   raise_application_error(-20999, 'Not supported in recovery catalog');
--
 
   deb(DEB_EXIT, 'with FALSE#');
   RETURN FALSE#;
END getPrePluginDf;
 
--
PROCEDURE setBigScnAware
IS
BEGIN
   deb(DEB_PRINT, 'Database is BIGSCN aware, higscnval set to UB8MAXVAL');
   highscnval := UB8MAXVAL; 
END setBigScnAware;
 
--
FUNCTION isNoBackupPdb(pdbname IN VARCHAR2)
RETURN NUMBER IS 
   nobackup NUMBER;
BEGIN
   deb(DEB_ENTER, 'isNoBackupPdb');
   IF (translateNoBackupPdb_c%ISOPEN) THEN
      CLOSE translateNoBackupPdb_c;
   END IF;
 
   OPEN translateNoBackupPdb_c(pdbname => pdbname);
   FETCH translateNoBackupPdb_c INTO nobackup;
   IF (translateNoBackupPdb_c%NOTFOUND) THEN
      nobackup := 0;
   END IF;
   CLOSE translateNoBackupPdb_c;
   deb(DEB_EXIT, 'with '||nobackup);
   RETURN nobackup;
END isNoBackupPdb;
 
--
--
--
 
--
PROCEDURE listApplicationPdbs(
   root_con_id       IN number)
IS
BEGIN
   deb(DEB_ENTER, 'listApplicationPdbs');
--
      raise_application_error(-20999, 'Not supported in recovery catalog');
--
   deb(DEB_EXIT);
END listApplicationPdbs;
 
--
FUNCTION listGetAppPdb(
   pdb_name          OUT varchar2)
RETURN number IS
BEGIN
   deb(DEB_ENTER, 'listGetAppPdb');
   deb(DEB_EXIT);
END listGetAppPdb;
 
--
 
--
--
--
 
BEGIN
--
--
 
--
   versionCounter  := 1;
   versionMaxIndex := versionList.COUNT; -- must match highest index
 
   resetAll;                              -- init package variables to defaults
END dbms_rcvman;
 
>>>
 
define prvtrvpc_plb
<<<
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
 
CREATE OR REPLACE PACKAGE BODY dbms_rcvvpc
AS
 
  g_catowner_uid                  CONSTANT user_users.username%TYPE :=
                                    SYS_CONTEXT('USERENV', 'CURRENT_USERID');
 
  FUNCTION is_ra RETURN BOOLEAN;
  this_is_ra                      CONSTANT BOOLEAN := is_ra;
 
  SUBTYPE predicate_t IS VARCHAR2(256);
  TYPE predicates_t IS VARRAY(14) OF predicate_t;
 
  g_p                             CONSTANT predicates_t :=
    predicates_t(
      'filter_user = SYS_CONTEXT(''USERENV'', ''SESSION_USER'')'  -- 1
    , 'db_id IN (SELECT vpc.db_id FROM vpc_databases vpc)'        -- 2
    , 'db_key IN (SELECT db.db_key FROM db)'                      -- 3
    , 'pdb_key IN (SELECT pdb.pdb_key FROM pdb)'                  -- 4
    , 'dbinc_key IN (SELECT dbinc.dbinc_key FROM dbinc)'          -- 5
    , 'db_key IN (SELECT db.db_key FROM db) OR db_key IS NULL'    -- 6
    , 'bdf_key IN (SELECT bdf.bdf_key FROM bdf)'                  -- 7
    , 'cdf_key IN (SELECT cdf.cdf_key FROM cdf)'                  -- 8
    , 'scr_key IN (SELECT scr.scr_key FROM scr)'                  -- 9
    , 'EXISTS (SELECT NULL FROM vpc_databases)'                   -- 10
    , 'df_key IN (SELECT df.df_key FROM df)'                      -- 11
    , 'created_user = SYS_CONTEXT(''USERENV'', ''SESSION_USER'')' -- 12
    , 'filter_user = SYS_CONTEXT(''USERENV'', ''SESSION_USER'')'  -- 13
    , 'site_key IN (SELECT node.site_key FROM node)'              -- 14
    );
 
  FUNCTION is_ra
  RETURN BOOLEAN
  IS
    l_owner                        all_users.username%TYPE;
  BEGIN
    EXECUTE IMMEDIATE 'BEGIN :owner := dbms_rai_owner; END;'
      USING OUT l_owner;
    RETURN (l_owner IS NOT NULL);
  EXCEPTION
    WHEN OTHERS
    THEN RETURN FALSE;
  END is_ra;
 
  PROCEDURE p (
    i_table                        VARCHAR2
  , i_msg                          VARCHAR2 DEFAULT NULL
  )
  IS
  BEGIN
$IF FALSE
$THEN
    sys.dbms_system.ksdwrt (
       sys.dbms_system.alert_file
     , 'filter_client_data: '
    || SYS_CONTEXT('USERENV', 'SID')
    || ' '
    || i_table
    || ' '
    || SYS_CONTEXT('USERENV', 'CURRENT_USER')
    || ' '
    || SYS_CONTEXT('USERENV', 'SESSION_USER')
    || ' ['
    || i_msg
    || ']'
    );
$ELSE
    NULL;
$END
  END p;
 
  FUNCTION filter_pass_all (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2
  IS
  BEGIN
    RETURN NULL;
  END filter_pass_all;
 
  FUNCTION f_p (
    i_table                        IN VARCHAR2
  , i_predicate                    IN BINARY_INTEGER
  )
  RETURN VARCHAR2
  IS
  BEGIN
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
    IF (SYS_CONTEXT('USERENV', 'SESSION_USERID') IN (g_catowner_uid, 0))
    THEN
      p(i_table, NULL);
      RETURN NULL;
    ELSE
      p(i_table, g_p(i_predicate));
      RETURN
         g_p(i_predicate)
      || CASE
           WHEN this_is_ra
           THEN
           q'{ OR SYS_CONTEXT('SYS_SESSION_ROLES','RA_CATALOG_SELECT')='TRUE'}'
         END
      || q'{ OR SYS_CONTEXT('SYS_SESSION_ROLES','RMAN_CATALOG_ACCESS')='TRUE'}';
    END IF;
  END f_p;
 
  FUNCTION f_vpc_databases (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2
  IS
  BEGIN
    RETURN f_p(table_p, 1);
  END f_vpc_databases;
 
  FUNCTION f_db (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2
  IS
  BEGIN
    RETURN f_p(table_p, 2);
  END f_db;
 
  FUNCTION f_dbinc (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2
  IS
  BEGIN
    RETURN f_p(table_p, 3);
  END f_dbinc;
 
  FUNCTION f_bp (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2
  IS
  BEGIN
    RETURN f_p(table_p, 3);
  END f_bp;
 
  FUNCTION f_bsf (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2
  IS
  BEGIN
    RETURN f_p(table_p, 3);
  END f_bsf;
 
  FUNCTION f_bs (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2
  IS
  BEGIN
    RETURN f_p(table_p, 3);
  END f_bs;
 
  FUNCTION f_conf (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2
  IS
  BEGIN
    RETURN f_p(table_p, 3);
  END f_conf;
 
  FUNCTION f_deleted_object (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2
  IS
  BEGIN
    RETURN f_p(table_p, 3);
  END f_deleted_object;
 
  FUNCTION f_do_seq (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2
  IS
  BEGIN
    RETURN f_p(table_p, 3);
  END f_do_seq;
 
  FUNCTION f_node (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2
  IS
  BEGIN
    RETURN f_p(table_p, 3);
  END f_node;
 
  FUNCTION f_pdb (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2
  IS
  BEGIN
    RETURN f_p(table_p, 3);
  END f_pdb;
 
  FUNCTION f_rout (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2
  IS
  BEGIN
    RETURN f_p(table_p, 3);
  END f_rout;
 
  FUNCTION f_watermarks (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2
  IS
  BEGIN
    RETURN f_p(table_p, 3);
  END f_watermarks;
 
  FUNCTION f_sbt_template_db (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2
  IS
  BEGIN
    RETURN f_p(table_p, 3);
  END f_sbt_template_db;
 
  FUNCTION f_rrcache (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2
  IS
  BEGIN
    RETURN f_p(table_p, 3);
  END f_rrcache;
 
  FUNCTION f_pdbinc (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2
  IS
  BEGIN
    RETURN f_p(table_p, 4);
  END f_pdbinc;
 
  FUNCTION f_pdb_dbinc (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2
  IS
  BEGIN
    RETURN f_p(table_p, 4);
  END f_pdb_dbinc;
 
  FUNCTION f_al (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2
  IS
  BEGIN
    RETURN f_p(table_p, 5);
  END f_al;
 
  FUNCTION f_bcf (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2
  IS
  BEGIN
    RETURN f_p(table_p, 5);
  END f_bcf;
 
  FUNCTION f_bdf (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2
  IS
  BEGIN
    RETURN f_p(table_p, 5);
  END f_bdf;
 
  FUNCTION f_brl (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2
  IS
  BEGIN
    RETURN f_p(table_p, 5);
  END f_brl;
 
  FUNCTION f_ccf (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2
  IS
  BEGIN
    RETURN f_p(table_p, 5);
  END f_ccf;
 
  FUNCTION f_cdf (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2
  IS
  BEGIN
    RETURN f_p(table_p, 5);
  END f_cdf;
 
  FUNCTION f_ckp (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2
  IS
  BEGIN
    RETURN f_p(table_p, 5);
  END f_ckp;
 
  FUNCTION f_df (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2
  IS
  BEGIN
    RETURN f_p(table_p, 5);
  END f_df;
 
  FUNCTION f_fb (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2
  IS
  BEGIN
    RETURN f_p(table_p, 5);
  END f_fb;
 
  FUNCTION f_grsp (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2
  IS
  BEGIN
    RETURN f_p(table_p, 5);
  END f_grsp;
 
  FUNCTION f_nrsp (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2
  IS
  BEGIN
    RETURN f_p(table_p, 5);
  END f_nrsp;
 
  FUNCTION f_offr (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2
  IS
  BEGIN
    RETURN f_p(table_p, 5);
  END f_offr;
 
  FUNCTION f_orl (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2
  IS
  BEGIN
    RETURN f_p(table_p, 5);
  END f_orl;
 
  FUNCTION f_rlh (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2
  IS
  BEGIN
    RETURN f_p(table_p, 5);
  END f_rlh;
 
  FUNCTION f_rr (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2
  IS
  BEGIN
    RETURN f_p(table_p, 5);
  END f_rr;
 
  FUNCTION f_rsr (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2
  IS
  BEGIN
    RETURN f_p(table_p, 5);
  END f_rsr;
 
  FUNCTION f_rt (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2
  IS
  BEGIN
    RETURN f_p(table_p, 5);
  END f_rt;
 
  FUNCTION f_tf (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2
  IS
  BEGIN
    RETURN f_p(table_p, 5);
  END f_tf;
 
  FUNCTION f_tsatt (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2
  IS
  BEGIN
    RETURN f_p(table_p, 5);
  END f_tsatt;
 
  FUNCTION f_ts (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2
  IS
  BEGIN
    RETURN f_p(table_p, 5);
  END f_ts;
 
  FUNCTION f_xal (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2
  IS
  BEGIN
    RETURN f_p(table_p, 5);
  END f_xal;
 
  FUNCTION f_xcf (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2
  IS
  BEGIN
    RETURN f_p(table_p, 5);
  END f_xcf;
 
  FUNCTION f_xdf (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2
  IS
  BEGIN
    RETURN f_p(table_p, 5);
  END f_xdf;
 
  FUNCTION f_scr (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2
  IS
  BEGIN
    RETURN f_p(table_p, 6);
  END f_scr;
 
  FUNCTION f_bcb (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2
  IS
  BEGIN
    RETURN f_p(table_p, 7);
  END f_bcb;
 
  FUNCTION f_ccb (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2
  IS
  BEGIN
    RETURN f_p(table_p, 8);
  END f_ccb;
 
  FUNCTION f_scrl (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2
  IS
  BEGIN
    RETURN f_p(table_p, 9);
  END f_scrl;
 
  FUNCTION f_cfs (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2
  IS
  BEGIN
    RETURN f_p(table_p, 10);
  END f_cfs;
 
  FUNCTION f_config (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2
  IS
  BEGIN
    RETURN f_p(table_p, 10);
  END f_config;
 
  FUNCTION f_orsevent (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2
  IS
  BEGIN
    RETURN f_p(table_p, 10);
  END f_orsevent;
 
  FUNCTION f_rcfile (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2
  IS
  BEGIN
    RETURN f_p(table_p, 10);
  END f_rcfile;
 
  FUNCTION f_bcr (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2
  IS
  BEGIN
    RETURN f_p(table_p, 11);
  END f_bcr;
 
  FUNCTION f_xmlstore (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2
  IS
  BEGIN
    RETURN f_p(table_p, 12);
  END f_xmlstore;
 
  FUNCTION f_server (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2
  IS
  BEGIN
    RETURN f_p(table_p, 13);
  END f_server;
 
  FUNCTION f_vpc_users (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2
  IS
  BEGIN
    RETURN f_p(table_p, 13);
  END f_vpc_users;
 
  FUNCTION f_site_dfatt (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2
  IS
  BEGIN
    RETURN f_p(table_p, 14);
  END f_site_dfatt;
 
  FUNCTION f_site_tfatt (
    schema_p                       IN VARCHAR2
  , table_p                        IN VARCHAR2
  )
  RETURN VARCHAR2
  IS
  BEGIN
    RETURN f_p(table_p, 14);
  END f_site_tfatt;
 
END dbms_rcvvpc;
>>>
 
 
define create_catalog_lock1
<<<
--
--
--
create or replace function get_lock_on_catalog (lock_type IN integer) 
return integer 
authid current_user
is
lock_handle varchar2(128);
ret integer;
str1 varchar2(256);
str2 varchar2(100);
x_mode number;
s_mode number;
begin
--
--
--
--
--
--
--
--
--
--
 
   str2 := 'ORA$RMAN_CATALOG_LOCK';
   str1 := 'begin dbms_lock.allocate_unique(:1||dbms_catowner, :2,'||
              ' 2147483647); end;';
   execute immediate str1 using str2, out lock_handle; 
    
   ret := -1;
 
--
--
      
   str1 := 'begin :1 := dbms_lock.X_MODE ; :2 := dbms_lock.S_MODE; end;';
   execute immediate str1 using out x_mode, out s_mode;
 
   if (lock_type = x_mode) then
--
      if (user = dbms_catowner) then
--
--
--
             
         str1 := 'begin :1 := dbms_lock.convert(:2, dbms_lock.X_MODE,1); end;';
         execute immediate str1 using out ret, lock_handle;  
 
--
--
--
--
--
         if (ret = 4) then 
--
            str1 :=  'begin :1 := dbms_lock.request(:2, dbms_lock.X_MODE, 1, '||
                        ' FALSE); end;'; 
            execute immediate str1 using out ret, lock_handle;
         end if;
      end if;
 
   elsif (lock_type = s_mode) then
      if (user = dbms_catowner) then
--
--
 
         str1 := 'begin :1 := dbms_lock.request(:2, dbms_lock.S_MODE, 1, '||
                    ' FALSE); end;';
         execute immediate str1 using out ret, lock_handle;
--
--
--
         if (ret != 0) then
            str1 := 'begin :1  := dbms_lock.convert(:2, dbms_lock.S_MODE, 1);'||
                       ' end;';
            execute immediate str1 using out ret, lock_handle;
 
--
--
            if (ret != 0) then
               ret := 1;
            end if;
         end if;
--
      else
         str1 := 'begin :1 := dbms_lock.request(:2, dbms_lock.S_MODE, 1,'||
                    ' FALSE); end;';
         execute immediate str1 using OUT ret, lock_handle;
      end if;
   end if;
 
   return ret;
end get_lock_on_catalog;
>>>
 
define create_catalog_lock2
<<<
--
--
 
grant execute on get_lock_on_catalog to recovery_catalog_owner, 
      recovery_catalog_user
>>>
 
 
 
define upgcat_1 <<< alter table ckp add (ckp_db_status VARCHAR2(7)) >>>
define upgcat_2
<<<
alter table ts add CONSTRAINT ts_u2 UNIQUE (dbinc_key, ts_name, create_scn)
>>>
define upgcat_3 <<< alter table df add (clone_fname VARCHAR2(1024)) >>>
define upgcat_4 <<< alter table bdf add (completion_time date) >>>
define upgcat_5 <<< alter table offr add (cf_create_time date) >>>
define upgcat_6 <<< alter table offr drop constraint offr_u2 drop index >>>
define upgcat_7
<<<
alter table offr add constraint offr_u2
  UNIQUE (dbinc_key, file#, create_scn, offline_scn, cf_create_time)
>>>
 
define upgcat_9  <<< alter table df add (stop_scn number) >>>
define upgcat_10 <<< alter table df add (read_only number) >>>
define upgcat_11 <<< update df set stop_scn = null, read_only = 0 
                      where read_only is null>>>
define upgcat_12 <<< alter table df modify (read_only not null) >>>
 
define upgcat_15 <<< alter table bp add (media_pool number) >>>
define upgcat_16 <<< alter table bp add (copy# number) >>>
define upgcat_17 <<< update bp set copy# = 1 where copy# is null>>>
define upgcat_18 <<< alter table bp modify (copy# not null) >>>
define upgcat_19 <<< alter table bp drop constraint bp_c_status drop index >>>
define upgcat_20
<<<
alter table bp add constraint bp_c_status check (status in ('A','U','D','X'))
>>>
define upgcat_21
<<< alter table dbinc add (high_pc_recid  number default 0) >>>
define upgcat_22 <<< update dbinc set high_pc_recid = 0 >>>
define upgcat_23 <<< alter table dbinc modify (high_pc_recid not null) >>>
define upgcat_24
<<< alter table rlh add constraint rlh_f1
FOREIGN KEY (dbinc_key) REFERENCES dbinc ON DELETE CASCADE >>>
define upgcat_25
<<< alter table al add constraint al_f1
FOREIGN KEY (dbinc_key) REFERENCES dbinc ON DELETE CASCADE >>>
define upgcat_26
<<< alter table ccf add constraint ccf_f1
FOREIGN KEY (dbinc_key) REFERENCES dbinc ON DELETE CASCADE >>>
define upgcat_27
<<< alter table xcf add constraint xcf_f1
FOREIGN KEY (dbinc_key) REFERENCES dbinc ON DELETE CASCADE >>>
define upgcat_28
<<< alter table cdf add constraint cdf_f1
FOREIGN KEY (dbinc_key) REFERENCES dbinc ON DELETE CASCADE >>>
define upgcat_29
<<< alter table xdf add constraint xdf_f1
FOREIGN KEY (dbinc_key) REFERENCES dbinc ON DELETE CASCADE >>>
define upgcat_30 <<< alter table bs modify (bs_recid NULL) >>>
define upgcat_31 <<< alter table bs modify (bs_stamp NULL) >>>
define upgcat_32 <<< alter table bs modify (bck_type NULL) >>>
define upgcat_33 <<< alter table bs modify (incr_level NULL) >>>
define upgcat_34 <<< alter table bs modify (status NULL) >>>
define upgcat_35 <<< alter table bs drop constraint bs_u1 drop index >>>
define upgcat_36 <<< alter table bs modify (start_time NULL) >>>
define upgcat_37 <<< alter table bs modify (completion_time NULL) >>>
define upgcat_38 <<< alter table df add (stop_time date) >>>
 
define upgcat_39 <<< alter table bcf add (controlfile_type
                                          varchar2(1) NULL) >>>
define upgcat_40 <<< alter table bcf add CONSTRAINT bcf_c_cf_type
CHECK (controlfile_type in ('S','B')) >>>
define upgcat_41 <<< alter table bs add (controlfile_included
                                         varchar2(7) NULL) >>>
define upgcat_42 <<< alter table bs add
CONSTRAINT bs_c_controlfile_included CHECK (controlfile_included in
                                            ('NONE','BACKUP','STANDBY')) >>>
define upgcat_43 <<< alter table ccf add (controlfile_type
                                          varchar2(1) NULL) >>>
define upgcat_44 <<< alter table ccf add CONSTRAINT ccf_c_cf_type
CHECK (controlfile_type in ('S','B')) >>>
define upgcat_45 <<< alter table xcf add (controlfile_type
                                          varchar2(1) NULL) >>>
define upgcat_46 <<< alter table xcf add CONSTRAINT xcf_c_cf_type
CHECK (controlfile_type in ('S','B')) >>>
define upgcat_47 <<< alter table al drop constraint al_u1 drop index >>>
define upgcat_48 <<< alter table al add (is_standby varchar2(1) NULL) >>>
define upgcat_49 <<< alter table al add constraint al_u1
 UNIQUE (dbinc_key, al_recid, al_stamp, is_standby) >>>
define upgcat_50 <<< alter table al add constraint al_c_is_standby
CHECK (is_standby in ('Y','N')) >>>
define upgcat_51 <<< alter table bs add (input_file_scan_only varchar2(3)) >>>
 
define upgcat_52 <<< alter table al drop constraint al_c_status drop index >>>
define upgcat_53
<<<
alter table al add constraint al_c_status check (status in ('A','U','D','X'))
>>>
define upgcat_54 <<< alter table ccf drop constraint ccf_c_status drop index >>>
define upgcat_55
<<<
alter table ccf add constraint ccf_c_status check (status in ('A','U','D','X'))
>>>
 
define upgcat_58 <<< alter table db add (high_conf_recid number) >>>
 
define upgcat_59 <<< alter table df add (rfile# number) >>>
define upgcat_60 <<< alter table al add (dictionary_begin varchar2(3)) >>>
define upgcat_61 <<< alter table al add (dictionary_end varchar2(3)) >>>
define upgcat_62
<<<
alter table ts add (included_in_database_backup varchar2(3) default 'YES')
>>>
 
define upgcat_63
<<< alter table bs  add (keep_options NUMBER DEFAULT 0 NOT NULL) >>>
define upgcat_64 <<< alter table bs  add (keep_until DATE NULL) >>>
define upgcat_65
<<< alter table xdf add (keep_options NUMBER DEFAULT 0 NOT NULL) >>>
define upgcat_66 <<< alter table xdf add (keep_until DATE NULL) >>>
define upgcat_67
<<< alter table xcf add (keep_options NUMBER DEFAULT 0 NOT NULL) >>>
define upgcat_68 <<< alter table xcf add (keep_until DATE NULL) >>>
define upgcat_69
<<< alter table cdf add (keep_options NUMBER DEFAULT 0 NOT NULL) >>>
define upgcat_70 <<< alter table cdf add (keep_until DATE NULL) >>>
define upgcat_71
<<< alter table ccf add (keep_options NUMBER DEFAULT 0 NOT NULL) >>>
define upgcat_72 <<< alter table ccf add (keep_until DATE NULL) >>>
 
define upgcat_73 <<< alter table bcf add (autobackup_date date) >>>
define upgcat_74 <<< alter table bcf add (autobackup_sequence number) >>>
define upgcat_75
<<<
alter table ts add (included_in_database_backup varchar2(3) default 'YES')
>>>
define upgcat_76 <<< alter table bcf add (blocks number) >>>
define upgcat_77 <<< alter table ckp drop constraint ckp_f2 drop index >>>
define upgcat_78 <<< alter table ckp drop column prev_ckp_key >>>
 
define upgcat_79 <<< alter table cdf add (scanned varchar2(1)) >>>
define upgcat_80 <<< alter table bcb add (corruption_type varchar2(9)) >>>
define upgcat_81 <<< alter table ccb add (corruption_type varchar2(9)) >>>
define upgcat_82 <<< alter table db add (last_kccdivts number default 0) >>>
define upgcat_99 <<<
--
declare
   cursor broken_pieces is
      select bs_key, piece#
        from bp
       where copy# = 1
       group by bs_key, piece#
      having count(piece#) > 1;
 
   cursor fix_piece(bskey number, pno number) is
      select bp_key
        from bp
       where bs_key = fix_piece.bskey
         and piece# = fix_piece.pno
         for update of copy#;
 
   rows_cnt number;
   rows_per_iteration number := 500;
begin
  loop
    rows_cnt := 0;
    for bp in broken_pieces loop
      for fp in fix_piece(bp.bs_key, bp.piece#) loop
        rows_cnt := fix_piece%rowcount;
        update bp set copy# = rows_cnt where current of fix_piece;
      end loop;
      rows_cnt := broken_pieces%rowcount;
      exit when rows_cnt = rows_per_iteration;
    end loop;
    commit;
    exit when rows_cnt < rows_per_iteration;
  end loop;
end;
>>>
 
define upgcat_100
<<< alter table dbinc add (high_bsf_recid NUMBER DEFAULT 0 NOT NULL) >>>
 
define upgcat_101
<<< drop package dbms_rcvman >>>
 
define upgcat_102
<<< alter table ts add (bigfile varchar2(3) default 'NO' NOT NULL) >>>
 
define upgcat_103
<<< alter table dbinc add(dbinc_status
                          VARCHAR2(8) DEFAULT 'ORPHAN' NOT NULL) >>>
define upgcat_104
<<< alter table dbinc add constraint dbinc_status
    CHECK(dbinc_status in ('CURRENT', 'PARENT', 'ORPHAN')) >>>
 
 
define upgcat_106
<<< alter table al  add (is_recovery_dest_file
                         VARCHAR2(3) DEFAULT 'NO' NOT NULL) >>>
 
define upgcat_107
<<< alter table cdf add (is_recovery_dest_file
                         VARCHAR2(3) DEFAULT 'NO' NOT NULL) >>>
 
define upgcat_108
<<< alter table ccf add (is_recovery_dest_file
                         VARCHAR2(3) DEFAULT 'NO' NOT NULL) >>>
 
define upgcat_109
<<< alter table bp  add (is_recovery_dest_file
                         VARCHAR2(3) DEFAULT 'NO' NOT NULL) >>>
 
define upgcat_110
<<< alter table bp  add (bytes NUMBER DEFAULT NULL) >>>
 
define upgcat_111
<<< alter table dbinc add (high_rsr_recid NUMBER DEFAULT 0 NOT NULL) >>>
define upgcat_112 <<< alter table bp  add (rsr_key number) >>>
define upgcat_113 <<< alter table cdf add (rsr_key number) >>>
define upgcat_114 <<< alter table ccf add (rsr_key number) >>>
define upgcat_115 <<< alter table xdf add (rsr_key number) >>>
define upgcat_116 <<< alter table xcf add (rsr_key number) >>>
 
define upgcat_117
<<< update cdf set scanned='N' where scanned is null >>>
 
define upgcat_118
<<< alter table cdf modify(scanned varchar2(1) DEFAULT 'N') >>>
 
define upgcat_119
<<< alter table cdf modify(scanned varchar2(1) NOT NULL) >>>
 
define upgcat_120
<<< alter table db modify(last_kccdivts NUMBER DEFAULT 0) >>>
 
define upgcat_121
<<<
   update ts set included_in_database_backup='YES'
   where included_in_database_backup is null
>>>
 
define upgcat_122
<<< alter table ts modify(included_in_database_backup DEFAULT 'YES') >>>
 
define upgcat_123
<<< alter table ts modify(included_in_database_backup NOT NULL) >>>
 
define upgcat_124
<<< alter table bp add (compressed varchar2(3) DEFAULT 'NO') >>>
 
define upgcat_125
<<< alter table al add (compressed varchar2(3) DEFAULT 'NO') >>>
 
define upgcat_126 <<< alter table scr add (scr_comment varchar2(255)) >>>
define upgcat_127 <<< alter table scr modify db_key null >>>
 
define upgcat_128
<<< update bs set keep_options = 0 where keep_options is null >>>
define upgcat_129
<<< alter table bs modify(keep_options NUMBER DEFAULT 0 NOT NULL) >>>
define upgcat_130
<<< update xdf set keep_options = 0 where keep_options is null >>>
define upgcat_131
<<< alter table xdf modify(keep_options NUMBER DEFAULT 0 NOT NULL) >>>
define upgcat_132
<<< update xcf set keep_options = 0 where keep_options is null >>>
define upgcat_133
<<< alter table xcf modify(keep_options NUMBER DEFAULT 0 NOT NULL) >>>
define upgcat_134
<<< update cdf set keep_options = 0 where keep_options is null >>>
define upgcat_135
<<< alter table cdf modify(keep_options NUMBER DEFAULT 0 NOT NULL) >>>
define upgcat_136
<<< update ccf set keep_options = 0 where keep_options is null >>>
define upgcat_137
<<< alter table ccf modify(keep_options NUMBER DEFAULT 0 NOT NULL) >>>
 
define upgcat_138
<<< alter table conf add (db_unique_name  VARCHAR2(512) DEFAULT NULL,
                          cleanup         VARCHAR2(3)   DEFAULT 'YES') >>>
 
define upgcat_139
<<< alter table conf drop constraint conf_p1 drop index >>>
 
define upgcat_140
<<< alter table conf add constraint conf_f1 
     FOREIGN KEY(db_key)
     REFERENCES db ON DELETE CASCADE >>>
 
define upgcat_141
<<< alter table bdf add (blocks_read number) >>>
 
define upgcat_142
<<< update bdf set blocks_read = datafile_blocks where blocks_read is null >>>
 
define upgcat_143
<<< alter table bdf modify(blocks_read NOT NULL) >>>
 
define bp_i_rsr  <<< CREATE INDEX bp_i_rsr  on bp(rsr_key)  &tablespace& >>>
define cdf_i_rsr <<< CREATE INDEX cdf_i_rsr on cdf(rsr_key) &tablespace& >>>
define ccf_i_rsr <<< CREATE INDEX ccf_i_rsr on ccf(rsr_key) &tablespace& >>>
define xdf_i_rsr <<< CREATE INDEX xdf_i_rsr on xdf(rsr_key) &tablespace& >>>
define xcf_i_rsr <<< CREATE INDEX xcf_i_rsr on xcf(rsr_key) &tablespace& >>>
define xal_i_rsr <<< CREATE INDEX xal_i_rsr on xal(rsr_key) &tablespace& >>>
define tsatt_i_sck <<< CREATE INDEX tsatt_i_sck on tsatt(start_ckp_key) &tablespace& >>>
define tsatt_i_eck <<< CREATE INDEX tsatt_i_eck on tsatt(end_ckp_key) &tablespace& >>>
define ckp_i_dbinc <<< CREATE INDEX ckp_i_dbinc on ckp(dbinc_key) &tablespace& >>>
define rsr_i_dbinc <<< CREATE INDEX rsr_i_dbinc on rsr(dbinc_key) &tablespace& >>>
define rsr_i_stamp <<< CREATE INDEX rsr_i_stamp on rsr(rsr_sstamp, rsr_srecid) &tablespace& >>>
define rout_i_db <<< CREATE INDEX rout_i_db on rout(db_key) &tablespace& >>>
define rout_i_rsr <<< CREATE INDEX rout_i_rsr on rout(rsr_key) &tablespace& >>>
define rout_i_skey <<< CREATE INDEX rout_i_skey on rout(rout_skey) &tablespace& >>>
define rout_i_site_key <<< CREATE INDEX rout_i_site_key on rout(site_key)  &tablespace& >>>
 
define upgcat_144
<<< alter table db add (high_ic_recid NUMBER DEFAULT 0) >>>
 
define upgcat_145
<<< alter table bs add (block_size NUMBER DEFAULT NULL) >>>
 
define upgcat_146
<<<
--
--
--
--
--
declare
   cursor null_bs is
      select bs_key
        from bs
        where block_size is null;
 
   calblksize number;
 
   function getBSBlockSize(bs_key number) return number is
      blksize number := 0;
   begin
      begin
         select max(bdf.block_size)
           into blksize
           from bdf, bs
           where bdf.bs_key = bs.bs_key
             and bs.bs_key = getBSBlockSize.bs_key; 
         return blksize;    
      exception
         when no_data_found then
            null;
      end;
 
      begin
         select max(brl.block_size)
           into blksize
           from brl, bs
           where brl.bs_key = bs.bs_key
             and bs.bs_key = getBSBlockSize.bs_key;
         return blksize;
      exception
         when no_data_found then
            null;
      end;
 
      begin
         select max(bcf.block_size)
           into blksize
           from bcf, bs
          where bcf.bs_key = bs.bs_key
            and bs.bs_key = getBSBlockSize.bs_key;
         return blksize;
      exception
         when no_data_found then
            null;
      end;
 
      return null;
   end getBSBlockSize;
begin
   for bs_rec in null_bs loop
      calblksize := getBSBlockSize(bs_rec.bs_key);
      if (calblksize != 0 and calblksize is not null) then
         update bs set block_size = calblksize
          where bs_key = bs_rec.bs_key;
      end if;
   end loop;
end;
>>>
 
define upgcat_147
<<< alter table rsr add (rsr_ibytes NUMBER,
                         rsr_obytes NUMBER,
                         rsr_optimized VARCHAR2(3),
                         rsr_otype VARCHAR2(80),
                         rsr_srecid  number,
                         rsr_sstamp  number,
                         rsr_odevtype VARCHAR2(17)) >>>
 
define upgcat_148
<<< alter table node add (high_rout_stamp NUMBER default 0,
                          inst_startup_stamp NUMBER default 0) >>>
 
define upgcat_149
<<< alter table ccf add (blocks          NUMBER DEFAULT NULL) >>>
 
define upgcat_150
<<< alter table xcf add (blocks          NUMBER DEFAULT NULL) >>>
 
define upgcat_151
<<< alter table cdf add (create_time       DATE DEFAULT NULL,
                         marked_corrupt    NUMBER DEFAULT NULL) >>>
 
define upgcat_152
<<< alter table bdf add (create_time       DATE DEFAULT NULL, 
                         marked_corrupt    NUMBER DEFAULT NULL,
                         used_chg_track    VARCHAR2(1) DEFAULT 'N',
                         used_optim        VARCHAR2(1) DEFAULT 'N') >>>
 
define upgcat_153
<<< alter table xdf add (create_time       DATE DEFAULT NULL) >>>
 
define upgcat_154
<<< alter table fb add (oldest_flashback_time DATE DEFAULT NULL) >>>
 
define upgcat_155
<<< alter table al add (creator         VARCHAR2(7) DEFAULT NULL) >>>
 
 
define upgcat_156
<<< alter table dbinc add (high_tf_recid NUMBER DEFAULT 0 NOT NULL) >>>
 
define upgcat_157
<<< alter table ts add (temporary varchar2(3) default 'NO' NOT NULL) >>>
 
define upgcat_158
<<<
--
--
--
--
declare
   is_db_role number;
   no_conf    number;
   cursor node_c is
      select db_key, count(*) no_db_unique_name
        from node
    group by db_key;
   cursor db_c is
      select db_key
        from db;
begin
   select count(*) into is_db_role
     from user_tab_columns
    where table_name = 'NODE'
      and column_name = 'DATABASE_ROLE';
   if is_db_role = 0 then
      for noderec in node_c loop
         if (noderec.no_db_unique_name > 1) then
            delete from node where node.db_key = noderec.db_key;
            delete from conf where conf.db_key = noderec.db_key;
            update db set db.high_conf_recid = 0
             where db.db_key = noderec.db_key;
         end if;
      end loop;
   else
--
--
--
--
      for dbrec in db_c loop
         select count(*) into no_conf
           from conf
          where conf.db_key = dbrec.db_key;
         if no_conf = 0 then
            update node set node.high_conf_recid = 0
             where node.db_key = dbrec.db_key;
            update db set db.high_conf_recid = 0 
             where db.db_key = dbrec.db_key;
         end if;
      end loop;
   end if;
end;
>>>
 
define upgcat_159
<<< 
--
begin
   update dbinc set dbinc.db_name       = upper(dbinc.db_name);
   update conf  set conf.db_unique_name = upper(conf.db_unique_name);
   update node  set node.db_unique_name = upper(node.db_unique_name);
   update fb    set fb.db_unique_name   = upper(fb.db_unique_name);
end;
>>>
 
define upgcat_160
<<< alter table node add (database_role varchar2(7)
                          default 'PRIMARY' NOT NULL) >>>
define upgcat_161
<<< alter table node add constraint node_u1 unique(db_key, db_unique_name) >>>
 
define upgcat_162
<<<
alter table ts add (encrypt_in_backup varchar2(3))
>>>
 
define upgcat_163
<<< alter table al add (terminal   VARCHAR2(3) DEFAULT 'NO') >>>
 
define upgcat_164
<<< alter table xal add (terminal  VARCHAR2(3) DEFAULT 'NO') >>>
 
define upgcat_165
<<< alter table brl add (terminal  VARCHAR2(3) DEFAULT 'NO') >>>
 
define upgcat_166
<<< alter table cdf drop CONSTRAINT cdf_c_status drop index >>>
 
define upgcat_167
<<< alter table cdf add CONSTRAINT cdf_c_status 
    CHECK (status in ('A','U','D','X','F')) >>>
 
define upgcat_168
<<< alter table rlh drop constraint rlh_u2 drop index >>>
 
define upgcat_add_scrl_dbkey
<<< alter table scrl add (db_key NUMBER) >>>
 
define upgcat_populate_scrl_dbkey
<<< update scrl set db_key = (select db_key from scr
    where scr.scr_key = scrl.scr_key) >>>
 
define upgcat_bug_4754328
<<< 
--
--
--
--
--
declare
   cursor dbinc_c is
      select dbinc_key
        from dbinc
         for update;
   tempts_cnt    number;
   tempts_fixed number;
begin
   select count(*)
     into tempts_fixed
     from user_procedures
    where object_name='DBMS_RCVCAT'
      and procedure_name='TEMPFILETORESYNC';
   if tempts_fixed = 0 then
      for dbincrec in dbinc_c loop
         select count(*) into tempts_cnt
           from ts
          where temporary = 'YES'
            and drop_scn is null
            and dbinc_key = dbincrec.dbinc_key;
         if (tempts_cnt = 0) then
            delete from ts
             where temporary = 'YES'
               and dbinc_key = dbincrec.dbinc_key;
--
         end if;
      end loop;
   end if;
end;
>>>
 
define upgcat_df_add_fdbid
<<<
   alter table df add (foreign_dbid number default 0 not null)
>>>
 
define upgcat_df_add_fcrescn
<<<
   alter table df add (foreign_create_scn number default 0 not null)
>>>
 
define upgcat_df_add_fcretim
<<<
   alter table df add (foreign_create_time date)
>>>
 
define upgcat_df_add_pronly
<<<
   alter table df add (plugged_readonly varchar2(3) default 'NO' not null)
>>>
 
define upgcat_df_add_plus
<<<
   alter table df add (plugin_scn number default 0 not null)
>>>
 
define upgcat_df_add_prlgscn
<<<
   alter table df add (plugin_reset_scn number default 0 not null)
>>>
 
define upgcat_df_add_prlgtim
<<<
   alter table df add (plugin_reset_time date)
>>>
 
define upgcat_df_add_pfdbid
<<<
   alter table df add (pdb_foreign_dbid number default 0 not null)
>>>
 
define upgcat_df_drop_df_p
<<<
  alter table df drop constraint df_p drop index 
>>>
 
define upgcat_bdf_add_fdbid
<<<
   alter table bdf add (foreign_dbid number default 0 not null)
>>>
 
define upgcat_bdf_add_pronly
<<<
   alter table bdf add (plugged_readonly varchar2(3) default 'NO' not null)
>>>
 
define upgcat_bdf_add_plus
<<<
   alter table bdf add (plugin_scn number default 0 not null)
>>>
 
define upgcat_bdf_add_prlgscn
<<<
   alter table bdf add (plugin_reset_scn number default 0 not null)
>>>
 
define upgcat_bdf_add_prlgtim
<<<
   alter table bdf add (plugin_reset_time date)
>>>
 
define upgcat_bdf_add_secsize
<<<
   alter table bdf add (section_size number)
>>>
 
define upgcat_bdf_add_sparse_backup
<<<
   alter table bdf add (sparse_backup varchar2(3) default 'NO' not null)
   add CONSTRAINT bdf_c_sparse_backup CHECK (sparse_backup in ('YES', 'NO'))
>>>
 
define upgcat_cdf_add_fdbid
<<<
   alter table cdf add 
   (foreign_dbid number default 0 not null)
>>>
 
define upgcat_cdf_add_pronly
<<<
   alter table cdf add
   (plugged_readonly varchar2(3) default 'NO' not null)
>>>
 
define upgcat_cdf_add_plus
<<<
   alter table cdf add (plugin_scn number default 0 not null)
>>>
 
define upgcat_cdf_add_prlgscn
<<<
   alter table cdf add
   (plugin_reset_scn number default 0 not null)
>>>
 
define upgcat_cdf_add_prlgtim
<<<
   alter table cdf add (plugin_reset_time date)
>>>
 
define upgcat_cdf_add_sparse_backup
<<<
   alter table cdf add (sparse_backup varchar2(3) default 'NO' not null)
   add CONSTRAINT cdf_c_sparse_backup CHECK (sparse_backup in ('YES', 'NO'))
>>>
 
define upgcat_xdf_add_fdbid
<<<
   alter table xdf add (foreign_dbid number default 0 not null)
>>>
 
define upgcat_xdf_add_pronly
<<<
   alter table xdf add (plugged_readonly varchar2(3) default 'NO' not null)
>>>
 
define upgcat_xdf_add_plus
<<<
   alter table xdf add (plugin_scn number default 0 not null)
>>>
 
define upgcat_xdf_add_prlgscn
<<<
   alter table xdf add (plugin_reset_scn number default 0 not null)
>>>
 
define upgcat_xdf_add_prlgtim
<<<
   alter table xdf add (plugin_reset_time date)
>>>
 
define add_siteaware_columns_to_node
<<< 
   alter table node add (site_key number default 0 not null,
                         last_kccdivts   NUMBER DEFAULT 0,
                         high_ic_recid   NUMBER DEFAULT 0,
                         cf_create_time  DATE,
                         dbinc_key       NUMBER DEFAULT 0 NOT NULL,
                         ckp_scn         NUMBER DEFAULT 0 NOT NULL,
                         full_ckp_cf_seq NUMBER DEFAULT 0 NOT NULL,
                         job_ckp_cf_seq  NUMBER DEFAULT 0 NOT NULL,
                         high_ts_recid   NUMBER,
                         high_df_recid   NUMBER,
                         high_rt_recid   NUMBER,
                         high_orl_recid  NUMBER,
                         high_offr_recid NUMBER DEFAULT 0 NOT NULL,
                         high_rlh_recid  NUMBER DEFAULT 0 NOT NULL,
                         high_al_recid   NUMBER DEFAULT 0 NOT NULL,
                         high_bs_recid   NUMBER DEFAULT 0 NOT NULL,
                         high_bp_recid   NUMBER DEFAULT 0 NOT NULL,
                         high_bdf_recid  NUMBER DEFAULT 0 NOT NULL,
                         high_cdf_recid  NUMBER DEFAULT 0 NOT NULL,
                         high_brl_recid  NUMBER DEFAULT 0 NOT NULL,
                         high_bcb_recid  NUMBER DEFAULT 0 NOT NULL,
                         high_ccb_recid  NUMBER DEFAULT 0 NOT NULL,
                         high_do_recid   NUMBER DEFAULT 0 NOT NULL,
                         high_pc_recid   NUMBER DEFAULT 0 NOT NULL,
                         high_bsf_recid  NUMBER DEFAULT 0 NOT NULL,
                         high_rsr_recid  NUMBER DEFAULT 0 NOT NULL,
                         high_tf_recid   NUMBER DEFAULT 0 NOT NULL,
                         high_grsp_recid NUMBER DEFAULT 0 NOT NULL,
                         high_nrsp_recid NUMBER DEFAULT 0 NOT NULL,
                         high_bcr_recid  NUMBER DEFAULT 0 NOT NULL,
                         low_bcr_recid   NUMBER DEFAULT 0 NOT NULL,
                         bcr_in_use      VARCHAR2(3) DEFAULT 'NO' NOT NULL)
>>>
 
define update_site_key_in_node
<<< 
declare
   cursor node_c is
      select site_key
        from node
      where site_key = 0
      for update;
   cursor site_fromconf is
      select db_key, db_unique_name,
             count(*) over (partition by db_key) num_of_sites
      from (select distinct db_key, db_unique_name from conf
            where db_unique_name is not null 
              and db_key not in (select db_key from node));
   cursor db_not_known_c is 
      select db_key from db
         where not exists (select * from node where db_key = db.db_key);
   last_db_key number;
begin
--
   for noderec in node_c loop
     update node set site_key = rman_seq.nextval
      where current of node_c;
   end loop;
 
--
--
   for siterec in site_fromconf loop
     begin
       insert into node(db_key, db_unique_name, site_key, database_role,
                        force_resync2cf)
              values (siterec.db_key, siterec.db_unique_name,rman_seq.nextval,
                      decode(siterec.num_of_sites, 1, 'PRIMARY','STANDBY'),
                      'YES');
     exception
       when dup_val_on_index then
         null;
     end;
   end loop;
 
--
   for dbrec in db_not_known_c loop
     INSERT INTO node(db_key, database_role, site_key, force_resync2cf)
               VALUES(dbrec.db_key, 'PRIMARY', rman_seq.nextval, 'NO');
   end loop;
 
   commit;
end;
>>>
 
define add_node_p_constraint
<<< alter table node add CONSTRAINT node_p PRIMARY KEY (site_key) >>>
 
define add_site_key_check_constraint
<<< alter table node add CONSTRAINT check_site_key CHECK (site_key > 0) >>>
 
define add_site_key_to_conf
<<< alter table conf add (site_key number default 0 not null) >>>
 
define assign_site_key_in_conf
<<< 
--
--
declare
   cursor conf_c is
      select db_key, db_unique_name, site_key
        from conf
      where db_unique_name is not null
      for update;
   conf_site_key number;
begin
   for confrec in conf_c loop
     select site_key into conf_site_key from node
       where confrec.db_unique_name = node.db_unique_name and
             confrec.db_key = node.db_key;
     update conf set site_key = conf_site_key
      where current of conf_c;
   end loop;
   commit;
end;
>>>
 
define add_site_key_to_al
<<< alter table al add (site_key   number) >>>
 
define add_al_f2_constraint
<<< 
  alter table al add CONSTRAINT al_f2 FOREIGN KEY (site_key) 
    REFERENCES node ON DELETE CASCADE
>>>
 
define add_site_key_to_bp
<<< alter table bp add (site_key number) >>>
 
define add_encrypted_and_backed_by_osb_to_bp
<<< alter table bp add (encrypted VARCHAR2(1) DEFAULT 'N',
                        backed_by_osb VARCHAR2(1) DEFAULT 'N') >>>
 
define add_bp_f2_constraint
<<<  
  alter table bp add CONSTRAINT bp_f2 FOREIGN KEY (site_key) 
    REFERENCES node
>>>
 
define add_site_key_to_ccf
<<< alter table ccf add (site_key   number) >>>
 
define add_ccf_f2_constraint
<<< 
  alter table ccf add CONSTRAINT ccf_f2 FOREIGN KEY (site_key) 
    REFERENCES node
>>>
 
define add_site_key_to_xcf
<<< alter table xcf add (site_key   number) >>>
 
define add_xcf_f2_constraint
<<< 
  alter table xcf add CONSTRAINT xcf_f2 FOREIGN KEY (site_key) 
    REFERENCES node
>>>
 
define add_site_key_to_cdf
<<< alter table cdf add (site_key   number) >>>
 
define add_cdf_f2_constraint
<<< 
  alter table cdf add CONSTRAINT cdf_f3 FOREIGN KEY (site_key) 
    REFERENCES node
>>>
 
define add_site_key_to_xdf
<<< alter table xdf add (site_key   number) >>>
 
define add_xdf_f2_constraint
<<< 
  alter table xdf add CONSTRAINT xdf_f3 FOREIGN KEY (site_key) 
    REFERENCES node
>>>
 
define add_site_key_to_xal
<<< alter table xal add (site_key   number) >>>
 
define add_xal_f2_constraint
<<< 
  alter table xal add CONSTRAINT xal_f2 FOREIGN KEY (site_key) 
    REFERENCES node
>>>
 
define add_keep_to_xal
<<<
  alter table xal add (keep_options number default 0 not null,
                       keep_until date) 
>>>
 
define add_site_key_to_rsr
<<< alter table rsr add (site_key   number) >>>
 
define add_rsr_osb_allocated_to_rsr
<<< alter table rsr add (rsr_osb_allocated   varchar2(1)) >>>
 
define drop_rsr_u1_constraint
<<< alter table rsr drop CONSTRAINT rsr_u1 drop index >>>
 
define add_rsr_u2_constraint
<<< 
  alter table rsr add CONSTRAINT rsr_u2 UNIQUE 
    (dbinc_key, rsr_recid, rsr_stamp, site_key)
>>>
 
define add_rsr_f2_constraint
<<< 
  alter table rsr add CONSTRAINT rsr_f2 FOREIGN KEY (site_key) 
    REFERENCES node ON DELETE CASCADE
>>>
 
define add_site_key_to_bs
<<< alter table bs add (site_key   number) >>>
 
define add_bs_f2_constraint
<<< 
  alter table bs add CONSTRAINT bs_f2 FOREIGN KEY (site_key) 
    REFERENCES node
>>>
 
define drop_bcf_u1_constraint
<<< alter table bcf drop CONSTRAINT bcf_u1 drop index >>>
 
define drop_bsf_u1_constraint
<<< alter table bsf drop CONSTRAINT bsf_u1 drop index >>>
 
define drop_bsf_i_bs_key_index
<<< drop index bsf_i_bs_key >>>
 
define add_bsf_u2_constraint
<<< alter table bsf add CONSTRAINT bsf_u2 UNIQUE (bs_key) >>>
 
define drop_bdf_u1_constraint
<<< alter table bdf drop CONSTRAINT bdf_u1 drop index >>>
 
define add_bdf_u2_constraint
<<< alter table bdf add CONSTRAINT bdf_u2 UNIQUE (bs_key, file#) >>>
 
define drop_brl_u1_constraint
<<< alter table brl drop CONSTRAINT brl_u1 drop index >>>
 
define add_brl_u2_constraint
<<<alter table brl add CONSTRAINT brl_u2 UNIQUE (bs_key, thread#, sequence#)>>>
 
define drop_offr_u1_constraint
<<< alter table offr drop CONSTRAINT offr_u1 drop index >>>
 
define add_df_key_blocks_to_df
<<< alter table df add (df_key NUMBER, blocks NUMBER) >>>
 
define add_df_key_site_key_to_dfatt
<<< alter table dfatt add (df_key NUMBER, site_key NUMBER) >>>
 
define drop_dfatt_f3_constraint
<<< alter table dfatt drop CONSTRAINT dfatt_f3 drop index >>>
 
define make_df_dfatt_siteaware
<<< 
DECLARE
   TYPE            cur_typ IS REF CURSOR;
   dfatt_c         cur_typ;
   dfattrec        df%ROWTYPE;
   dfrec           df%ROWTYPE;
   sql_stmt        VARCHAR2(200);
   distinct_files  NUMBER;
   distinct_fnames NUMBER;
   rid             VARCHAR2(18);
   nextval         NUMBER;
BEGIN
--
--
    EXECUTE IMMEDIATE 'delete dfatt where end_ckp_key is not null and ' ||
                      'end_ckp_key <> 0';
 
    OPEN dfatt_c FOR
      'SELECT dbinc_key, file#, create_scn, blocks, rowid ' ||
      '  FROM dfatt ' ||
      'WHERE end_ckp_key IS NULL FOR UPDATE';
 
--
    LOOP
       FETCH dfatt_c INTO
             dfattrec.dbinc_key, dfattrec.file#,
             dfattrec.create_scn, dfattrec.blocks, rid;
       EXIT WHEN dfatt_c%NOTFOUND;
 
       SELECT * INTO dfrec FROM df
          WHERE dbinc_key = dfattrec.dbinc_key
          AND   file#     = dfattrec.file#
          AND   create_scn= dfattrec.create_scn;
       IF dfrec.df_key IS NULL THEN
          SELECT rman_seq.nextval INTO nextval FROM dual;
          UPDATE df SET df_key = nextval,
                        blocks = dfattrec.blocks
             WHERE file#       = dfrec.file#
              AND  create_scn  = dfrec.create_scn
              AND  ts#         = dfrec.ts#
              AND  dbinc_key IN
                 (SELECT dbinc_key FROM dbinc
                     WHERE db_key = (SELECT db_key FROM dbinc
                                     WHERE dbinc_key = dfattrec.dbinc_key));
         IF SQL%ROWCOUNT = 0 THEN
             RAISE_APPLICATION_ERROR(-20000,'not updated any data file');
         END IF;
         EXECUTE IMMEDIATE 'UPDATE dfatt SET df_key = rman_seq.currval ' ||
            'WHERE ROWID = :1' USING rid;
         IF SQL%ROWCOUNT <> 1 THEN
             RAISE_APPLICATION_ERROR(-20001,'not updated dfatt for file');
         END IF;
      ELSE
         EXECUTE IMMEDIATE 'DELETE dfatt WHERE ROWID = :1' USING rid;
      END IF;
   END LOOP;
   CLOSE dfatt_c;
 
   SELECT COUNT(*) INTO distinct_files FROM
      (SELECT DISTINCT db.db_key, file#, create_scn, ts# 
         FROM df, dbinc, db
       WHERE df.dbinc_key = dbinc.dbinc_key
       AND   dbinc.db_key = db.db_key);
 
   OPEN dfatt_c FOR 'SELECT COUNT(*) FROM dfatt';
   FETCH dfatt_c INTO distinct_fnames;
   CLOSE dfatt_c;
 
   IF distinct_files <> distinct_fnames THEN
        RAISE_APPLICATION_ERROR(-20003,'distinct file count mismatch '||
           distinct_files || ',' || distinct_fnames);
   END IF;
 
--
   EXECUTE IMMEDIATE 'UPDATE dfatt SET end_ckp_key = 0';
 
   COMMIT;
END;
>>>
 
define modify_df_key_not_null
<<< alter table df modify(df_key NOT NULL) >>>
 
define drop_dfatt_f1_constraint
<<< alter table dfatt drop CONSTRAINT dfatt_f1 drop index >>>
 
define drop_dfatt_f2_constraint
<<< alter table dfatt drop CONSTRAINT dfatt_f2 drop index >>>
 
define drop_dfatt_u1_constraint
<<< alter table dfatt drop CONSTRAINT dfatt_u1 drop index >>>
 
define drop_dbinc_key_from_dfatt
<<< alter table dfatt drop column dbinc_key >>>
 
define drop_end_ckp_key_from_dfatt
<<< alter table dfatt drop column end_ckp_key >>>
 
define drop_start_ckp_key_from_dfatt
<<< alter table dfatt drop column start_ckp_key >>>
 
define "drop_file#_from_dfatt"
<<< alter table dfatt drop column file# >>>
 
define drop_create_scn_from_dfatt
<<< alter table dfatt drop column create_scn >>>
 
define drop_blocks_from_dfatt
<<< alter table dfatt drop column blocks >>>
 
define rename_dfatt_to_site_dfatt
<<< alter table dfatt rename to site_dfatt >>>
 
define rename_ba_restore_range_cache_to_rrcache
<<< alter table ba_restore_range_cache rename to rrcache >>>
 
define modify_df_key_in_site_dfatt_not_null
<<< alter table site_dfatt modify(df_key not null) >>>
 
define add_site_dfatt_p_constraint
<<<
   alter table site_dfatt add CONSTRAINT site_dfatt_p
              PRIMARY KEY (df_key, site_key)
>>>
 
define add_site_dfatt_f2_constraint
<<<
   alter table site_dfatt add CONSTRAINT site_dfatt_f2
              FOREIGN KEY (site_key) REFERENCES node ON DELETE CASCADE
>>>
 
define assign_site_key_in_site_dfatt
<<< 
declare
   db_key_rec number;
   cursor all_dbkey_c is
     select db_key from db;
 
   cursor site_dfatt_c(dbkey number) is
      select site_dfatt.df_key, node.site_key, site_dfatt.site_key nullkey
         from site_dfatt, df, dbinc, node
         where site_dfatt.site_key is null
           and node.db_key = site_dfatt_c.dbkey
           and node.database_role = 'PRIMARY'
           and site_dfatt.df_key=df.df_key
           and df.dbinc_key = dbinc.dbinc_key
           and dbinc.db_key = node.db_key for update of site_dfatt.site_key;
begin
   open all_dbkey_c;
 
   loop
     fetch all_dbkey_c into db_key_rec;
     exit when all_dbkey_c%NOTFOUND;
     for site_dfatt_rec in site_dfatt_c(db_key_rec) loop
        update site_dfatt set site_key = site_dfatt_rec.site_key
          where current of site_dfatt_c;
     end loop;
     commit;
   end loop;
end;
>>>
 
define modify_site_key_in_site_dfatt_not_null
<<< alter table site_dfatt modify(site_key NOT NULL) >>>
 
define add_siteaware_columns_to_tf
<<< alter table tf add (tf_key NUMBER, blocks NUMBER, autoextend VARCHAR2(3),
                        max_size NUMBER, next_size NUMBER)
>>>
 
define add_tf_key_site_key_to_tfatt
<<< alter table tfatt add (tf_key NUMBER, site_key NUMBER) >>>
 
define drop_tfatt_f3_constraint
<<< alter table tfatt drop CONSTRAINT tfatt_f3 drop index >>>
 
define make_tf_tfatt_siteaware
<<< 
DECLARE
   TYPE            cur_typ IS REF CURSOR;
   tfatt_c         cur_typ;
   tfattrec        tf%ROWTYPE;
   tfrec           tf%ROWTYPE;
   tfrec_blocks    NUMBER;
   tfrec_autoextend VARCHAR2(3);
   tfrec_max_size  NUMBER;
   tfrec_next_size NUMBER;
   sql_stmt        VARCHAR2(200);
   distinct_files  NUMBER;
   distinct_fnames NUMBER;
   rid             VARCHAR2(18);
   nextval         NUMBER;
BEGIN
--
--
    EXECUTE IMMEDIATE 'delete tfatt where end_ckp_key is not null and ' ||
                      'end_ckp_key <> 0';
 
    OPEN tfatt_c FOR
      'SELECT dbinc_key, file#, create_scn, blocks, autoextend,' ||
      '       max_size, next_size, rowid ' ||
      '  FROM tfatt ' ||
      'WHERE end_ckp_key IS NULL FOR UPDATE';
 
--
    LOOP
       FETCH tfatt_c INTO
             tfattrec.dbinc_key, tfattrec.file#,
             tfattrec.create_scn, tfrec_blocks, tfrec_autoextend,
             tfrec_max_size, tfrec_next_size, rid;
       EXIT WHEN tfatt_c%NOTFOUND;
 
       SELECT * INTO tfrec FROM tf
          WHERE dbinc_key = tfattrec.dbinc_key
          AND   file#     = tfattrec.file#
          AND   create_scn= tfattrec.create_scn;
       IF tfrec.tf_key IS NULL THEN
          SELECT rman_seq.nextval INTO nextval FROM dual;
          EXECUTE IMMEDIATE
             'UPDATE tf SET tf_key = :1, ' ||
             '          blocks     = :2, ' ||
             '          autoextend = :3, ' ||
             '          max_size   = :4, ' ||
             '          next_size  = :5 ' ||
             'WHERE file#       = :6 ' ||
             'AND  create_scn  = :7 ' ||
             'AND  (create_time = :8 ' ||
             '   OR create_time IS NULL AND :9 IS NULL) ' ||
             'AND  ts#         = :10 ' ||
             'AND  rfile#      = :11 ' ||
             'AND  dbinc_key IN ' ||
             '   (SELECT dbinc_key FROM dbinc ' ||
             '       WHERE db_key = (SELECT db_key FROM dbinc ' ||
             '                       WHERE dbinc_key = :12))'
             USING nextval, tfrec_blocks, tfrec_autoextend,
                   tfrec_max_size, tfrec_next_size,
                   tfrec.file#, tfrec.create_scn, tfrec.create_time,
                   tfrec.create_time, tfrec.ts#, tfrec.rfile#, 
                   tfattrec.dbinc_key;
         IF SQL%ROWCOUNT = 0 THEN
             RAISE_APPLICATION_ERROR(-20004,'not updated any temp file');
         END IF;
         EXECUTE IMMEDIATE 'UPDATE tfatt SET tf_key = rman_seq.currval ' ||
            'WHERE ROWID = :1' USING rid;
         IF SQL%ROWCOUNT <> 1 THEN
             RAISE_APPLICATION_ERROR(-20005,'not updated tfatt for file');
         END IF;
      ELSE
         EXECUTE IMMEDIATE 'DELETE tfatt WHERE ROWID = :1' USING rid;
      END IF;
   END LOOP;
   CLOSE tfatt_c;
 
   SELECT COUNT(*) INTO distinct_files FROM
      (SELECT DISTINCT db.db_key, file#, create_scn, create_time, ts#, rfile#
         FROM tf, dbinc, db
       WHERE tf.dbinc_key = dbinc.dbinc_key
       AND   dbinc.db_key = db.db_key);
 
   OPEN tfatt_c FOR 'SELECT COUNT(*) FROM tfatt';
   FETCH tfatt_c INTO distinct_fnames;
   CLOSE tfatt_c;
 
   IF distinct_files <> distinct_fnames THEN
        RAISE_APPLICATION_ERROR(-20006,'distinct file count mismatch '||
           distinct_files || ',' || distinct_fnames);
   END IF;
 
--
   EXECUTE IMMEDIATE 'UPDATE tfatt SET end_ckp_key = 0';
 
   COMMIT;
END;
>>>
 
define modify_tf_key_not_null_in_tf
<<< alter table tf modify(tf_key NOT NULL) >>>
 
define drop_tfatt_f1_constraint
<<< alter table tfatt drop CONSTRAINT tfatt_f1 drop index >>>
 
define drop_tfatt_f2_constraint
<<< alter table tfatt drop CONSTRAINT tfatt_f2 drop index >>>
 
define drop_tfatt_u1_constraint
<<< alter table tfatt drop CONSTRAINT tfatt_u1 drop index >>>
 
define drop_dbinc_key_from_tfatt
<<< alter table tfatt drop column dbinc_key >>>
 
define drop_end_ckp_key_from_tfatt
<<< alter table tfatt drop column end_ckp_key >>>
 
define drop_start_ckp_key_from_tfatt
<<< alter table tfatt drop column start_ckp_key >>>
 
define "drop_file#_from_tfatt"
<<< alter table tfatt drop column file# >>>
 
define drop_create_scn_from_tfatt
<<< alter table tfatt drop column create_scn >>>
 
define drop_blocks_from_tfatt
<<< alter table tfatt drop column blocks >>>
 
define drop_autoextend_from_tfatt
<<< alter table tfatt drop column autoextend >>>
 
define drop_max_size_from_tfatt
<<< alter table tfatt drop column max_size >>>
 
define drop_next_size_from_tfatt
<<< alter table tfatt drop column next_size >>>
 
define rename_tfatt_to_site_tfatt
<<< alter table tfatt rename to site_tfatt >>>
 
define modify_tf_key_in_site_tfatt_not_null
<<< alter table site_tfatt modify(tf_key not null) >>>
 
define add_site_tfatt_p_constraint
<<< 
  alter table site_tfatt add CONSTRAINT site_tfatt_p
     PRIMARY KEY (tf_key, site_key)
>>>
 
define add_site_tfatt_f2_constraint
<<< 
   alter table site_tfatt add CONSTRAINT site_tfatt_f2
              FOREIGN KEY (site_key) REFERENCES node ON DELETE CASCADE
>>>
 
define assign_site_key_in_site_tfatt
<<< 
declare
   cursor site_tfatt_c is
      select site_tfatt.tf_key, node.site_key, site_tfatt.site_key nullkey
         from site_tfatt, tf, dbinc, node
         where site_tfatt.site_key is null
           and node.database_role = 'PRIMARY'
           and site_tfatt.tf_key=tf.tf_key 
           and tf.dbinc_key = dbinc.dbinc_key 
           and dbinc.db_key = node.db_key for update of site_tfatt.site_key;
begin
   for site_tfatt_rec in site_tfatt_c loop
      update site_tfatt set site_key = site_tfatt_rec.site_key
        where current of site_tfatt_c;
   end loop;
end;
>>>
 
define modify_site_key_in_site_tfatt_not_null
<<< alter table site_tfatt modify(site_key NOT NULL) >>>
 
define add_site_key_to_ckp
<<< alter table ckp add (site_key number default 0 not null) >>>
 
define update_site_key_in_ckp
<<< 
declare
   cursor ckp_c is
      select ckp.site_key unassigned, node.site_key
        from ckp, dbinc, node
      where ckp.site_key = 0
        and ckp.dbinc_key = dbinc.dbinc_key 
        and dbinc.db_key = node.db_key
        and node.database_role = 'PRIMARY'
      for update of ckp.site_key;
begin
   for ckprec in ckp_c loop
     update ckp set site_key = ckprec.site_key
      where current of ckp_c;
   end loop;
   commit;
end;
>>>
 
define add_ckp_f3_constraint
<<< 
   alter table ckp add constraint ckp_f3 FOREIGN KEY (site_key)
      REFERENCES node ON DELETE CASCADE
>>>
 
define drop_high_df_recid_from_ckp
<<< alter table ckp drop column high_df_recid >>>
 
define drop_high_conf_recid_from_db
<<< alter table db drop column high_conf_recid >>>
 
define drop_last_kccdivts_from_db
<<< alter table db drop column last_kccdivts >>>
 
define drop_high_ic_recid_from_db
<<< alter table db drop column high_ic_recid >>>
 
define drop_cf_create_time_from_dbinc
<<< alter table dbinc drop column cf_create_time >>>
 
define drop_ckp_scn_from_dbinc
<<< alter table dbinc drop column ckp_scn >>>
 
define drop_full_ckp_cf_seq_from_dbinc
<<< alter table dbinc drop column full_ckp_cf_seq >>>
 
define drop_job_ckp_cf_seq_from_dbinc
<<< alter table dbinc drop column job_ckp_cf_seq >>>
 
define drop_high_ts_recid_from_dbinc
<<< alter table dbinc drop column high_ts_recid >>>
 
define drop_high_df_recid_from_dbinc
<<< alter table dbinc drop column high_df_recid >>>
 
define drop_high_rt_recid_from_dbinc
<<< alter table dbinc drop column high_rt_recid >>>
 
define drop_high_orl_recid_from_dbinc
<<< alter table dbinc drop column high_orl_recid >>>
 
define drop_high_offr_recid_from_dbinc
<<< alter table dbinc drop column high_offr_recid >>>
 
define drop_high_rlh_recid_from_dbinc
<<< alter table dbinc drop column high_rlh_recid >>>
 
define drop_high_al_recid_from_dbinc
<<< alter table dbinc drop column high_al_recid >>>
 
define drop_high_bs_recid_from_dbinc
<<< alter table dbinc drop column high_bs_recid >>>
 
define drop_high_bp_recid_from_dbinc
<<< alter table dbinc drop column high_bp_recid >>>
 
define drop_high_bdf_recid_from_dbinc
<<< alter table dbinc drop column high_bdf_recid >>>
 
define drop_high_cdf_recid_from_dbinc
<<< alter table dbinc drop column high_cdf_recid >>>
 
define drop_high_brl_recid_from_dbinc
<<< alter table dbinc drop column high_brl_recid >>>
 
define drop_high_bcb_recid_from_dbinc
<<< alter table dbinc drop column high_bcb_recid >>>
 
define drop_high_ccb_recid_from_dbinc
<<< alter table dbinc drop column high_ccb_recid >>>
 
define drop_high_do_recid_from_dbinc
<<< alter table dbinc drop column high_do_recid >>>
 
define drop_high_pc_recid_from_dbinc
<<< alter table dbinc drop column high_pc_recid >>>
 
define drop_high_bsf_recid_from_dbinc
<<< alter table dbinc drop column high_bsf_recid >>>
 
define drop_high_rsr_recid_from_dbinc
<<< alter table dbinc drop column high_rsr_recid >>>
 
define drop_high_tf_recid_from_dbinc
<<< alter table dbinc drop column high_tf_recid >>>
 
define drop_high_grsp_recid_from_dbinc
<<< alter table dbinc drop column high_grsp_recid >>>
 
define add_ors_timezone_col_to_dbinc
<<< alter table dbinc add (dbinc_timezone VARCHAR2(64)) >>>
 
define add_type_to_orl
<<< alter table orl add (type varchar2(7) default 'ONLINE') >>>
 
define add_bytes_to_orl
<<< alter table orl add (bytes number default NULL) >>>
 
define add_site_key_to_orl
<<< alter table orl add (site_key number) >>>
 
define add_orl_f2_constraint
<<<  
  alter table orl add CONSTRAINT orl_f2 FOREIGN KEY (site_key) 
    REFERENCES node ON DELETE CASCADE
>>>
 
define update_site_key_in_orl
<<< 
declare
   cursor orl_c is
      select orl.site_key unassigned, node.site_key
        from orl, dbinc, node
      where orl.site_key is null
        and orl.dbinc_key = dbinc.dbinc_key 
        and dbinc.db_key = node.db_key
        and node.database_role = 'PRIMARY'
      for update of orl.site_key;
begin
   for orlrec in orl_c loop
     update orl set site_key = orlrec.site_key
      where current of orl_c;
   end loop;
   commit;
end;
>>>
 
define add_db_unique_name_to_bsf
<<< alter table bsf add (db_unique_name varchar2(30)) >>>
 
define drop_site_key_from_bsf
<<< alter table bsf drop column site_key >>>
 
define upgcat_bs_multi_section
<<< alter table bs add (multi_section varchar2(1)) >>>
 
define add_site_key_to_grsp
<<< alter table grsp add (site_key number) >>>
 
define add_creation_time_to_grsp
<<< alter table grsp add (creation_time date default NULL) >>>
 
define add_rsptime_to_grsp
<<< alter table grsp add (rsptime date default NULL) >>>
 
define add_guaranteed_to_grsp
<<< alter table grsp add (guaranteed varchar2(3) default 'YES') >>>
 
define update_site_key_in_grsp
<<<
declare
   cursor grsp_c is
      select grsp.site_key unassigned, node.site_key
        from grsp, dbinc, node
      where grsp.site_key is null
        and grsp.dbinc_key = dbinc.dbinc_key
        and dbinc.db_key = node.db_key
        and node.database_role = 'PRIMARY'
      for update of grsp.site_key;
begin
   for grsprec in grsp_c loop
     update grsp set site_key = grsprec.site_key
      where current of grsp_c;
   end loop;
   commit;
end;
>>>
 
define check_grsp_u1_constraint
<<<
declare
   cursor grsp_c is
   select site_key, rspname
     from grsp
    order by site_key, rspname
   for update of grsp.site_key;
   prev_site_key number;
   prev_rspname  grsp.rspname%type;
begin
   delete from grsp where site_key is null;
   for grsprec in grsp_c loop
      if (prev_site_key = grsprec.site_key and
          prev_rspname  = grsprec.rspname) then
         delete grsp where current of grsp_c;
      else
         prev_site_key := grsprec.site_key;
         prev_rspname  := grsprec.rspname;
      end if;
   end loop;
end;
>>>
 
define add_grsp_u1_constraint
<<<
alter table grsp add constraint grsp_u1 UNIQUE(site_key, rspname)
>>>
 
define add_grsp_u3_constraint
<<<
   alter table grsp add constraint grsp_u3 FOREIGN KEY (site_key)
      REFERENCES node ON DELETE CASCADE
>>>
 
define upgcat_rcver_constraint
<<< alter table rcver add constraint rcver_version_unique unique(version) >>>
 
define drop_tf_u2_constraint
<<< alter table tf drop CONSTRAINT tf_u2 drop index >>>
 
define drop_df_u2_constraint
<<< alter table df drop CONSTRAINT df_u2 drop index >>>
 
define delete_dup_brl_bsf_bdf_rows
<<< 
  declare
    cursor brl_c is
    select  bs_key, thread#, sequence#,
            lead(sequence#, 1) over
                (partition by bs_key, thread# order by sequence#) nextseq#
    from brl
    for update of brl.bs_key;
    cursor bsf_c is
    select  bs_key, lead(bs_key, 1) over (order by bs_key) next_bs_key
    from bsf
    for update of bsf.bs_key;
    cursor bdf_c is
    select  bs_key, file#,
            lead(file#, 1) over
                (partition by bs_key order by file#) nextfile#
    from bdf
    for update of bdf.bs_key;
  begin
--
    delete brl where brl_stamp = 0;
--
    for brlrec in brl_c loop
       if (brlrec.sequence# = brlrec.nextseq#)
       then
          delete brl where current of brl_c;
       end if;
    end loop;
--
    for bsfrec in bsf_c loop
        if bsfrec.bs_key = bsfrec.next_bs_key
        then
           delete bsf where current of bsf_c;
        end if;
    end loop;
    for bdfrec in bdf_c loop
       if (bdfrec.file# = bdfrec.nextfile#)
       then
          delete bdf where current of bdf_c;
       end if;
    end loop;
    commit;
  end;
>>>
 
define add_some_cols_to_site_tfatt
<<< 
    alter table site_tfatt add (drop_scn   number,
                                drop_time  date ,
                                blocks     number,
                                autoextend varchar2(3),
                                max_size   number,
                                next_size  number)
>>>
 
define populate_some_cols_in_site_tfatt
<<< 
  DECLARE
    TYPE              cur_typ IS REF CURSOR;
    site_tfatt_c      cur_typ;
    site_tfatt_rec    site_tfatt%ROWTYPE;
    site_tfatt_rid    VARCHAR2(18);
    tf_drop_scn       NUMBER;
    tf_drop_time      DATE;
    tf_blocks         NUMBER;
    tf_autoextend     VARCHAR2(3);
    tf_max_size       NUMBER;
    tf_next_size      NUMBER;
  BEGIN
    OPEN site_tfatt_c FOR 
       'SELECT  site_tfatt.drop_scn, site_tfatt.drop_time, ' ||
       '     site_tfatt.blocks, site_tfatt.autoextend, ' ||
       '     site_tfatt.max_size, site_tfatt.next_size, ' ||
       '     tf.drop_scn tf_drop_scn, tf.drop_time tf_drop_time, ' ||
       '     tf.blocks tf_blocks, tf.autoextend tf_autoextend, ' ||
       '     tf.max_size tf_max_size, tf.next_size tf_next_size, ' ||
       '     site_tfatt.ROWID site_tfatt_rowid ' ||
       'FROM site_tfatt, tf ' ||
       'WHERE site_tfatt.tf_key = tf.tf_key ' ||
       'FOR UPDATE OF site_tfatt.drop_scn, site_tfatt.drop_time, '||
       '              site_tfatt.blocks, site_tfatt.autoextend,  '||
       '              site_tfatt.max_size, site_tfatt.next_size';
 
    LOOP
       FETCH site_tfatt_c INTO
             site_tfatt_rec.drop_scn, site_tfatt_rec.drop_time,
             site_tfatt_rec.blocks, site_tfatt_rec.autoextend,
             site_tfatt_rec.max_size, site_tfatt_rec.next_size,
             tf_drop_scn, tf_drop_time, tf_blocks, tf_autoextend,
             tf_max_size, tf_next_size, site_tfatt_rid;
       EXIT WHEN site_tfatt_c%NOTFOUND;
       EXECUTE IMMEDIATE 
          'update site_tfatt set drop_scn = :1, drop_time = :2, ' ||
          '   blocks = :3, autoextend = :4, max_size = :5, next_size = :6 ' ||
          '   where ROWID = :7' 
       USING tf_drop_scn,  tf_drop_time, 
             tf_blocks, tf_autoextend, tf_max_size, tf_next_size, 
             site_tfatt_rid;
    END LOOP;
    COMMIT;
  END;
>>>
 
define drop_tf_u1
<<< alter table tf drop constraint tf_u1 drop index >>>
 
define drop_drop_scn_from_tf
<<< alter table tf drop column drop_scn >>>
 
define drop_drop_time_from_tf
<<< alter table tf drop column drop_time >>>
 
define drop_blocks_from_tf
<<< alter table tf drop column blocks >>>
 
define drop_autoextend_from_tf
<<< alter table tf drop column autoextend >>>
 
define drop_max_size_from_tf
<<< alter table tf drop column max_size >>>
 
define drop_next_size_from_tf
<<< alter table tf drop column next_size >>>
 
define upgcat_strt_0
<<<
create or replace package dbms_rcvcat authid current_user is
   function getPackageVersion return varchar2;
   function getCatalogVersion return varchar2;
 
--
   UPGRADE_COMPLETED CONSTANT number := 0;
end;
>>>
define upgcat_strt_1
<<<
create or replace package body dbms_rcvcat is
   function getPackageVersion return varchar2 is
   begin
     return '18.04.00.00';
   end;
   function getCatalogVersion return varchar2 is
   begin
     return '18.04.00.00';
   end;
end;
>>>
 
define add_create_thread_size_to_df
<<< ALTER TABLE df ADD (create_thread NUMBER, create_size NUMBER) >>>
 
define remove_null_db_unique_name_rows_from_node
<<<
declare 
   cursor db_with_null_db_unique_name_c is 
      select db_key, db_unique_name, 
          count(*) over (partition by db_key) num_of_sites 
      from node 
      where db_key in 
         (select db_key from node where db_unique_name is null) 
      for update of node.db_key; 
begin 
   for db_with_null_db_unique_name in db_with_null_db_unique_name_c loop 
      if db_with_null_db_unique_name.num_of_sites > 1 and 
         db_with_null_db_unique_name.db_unique_name is null then 
            delete node where current of db_with_null_db_unique_name_c; 
      end if; 
   end loop; 
   commit; 
end;
>>>
 
define drop_constraint_status_rt
<<< alter table rt drop CONSTRAINT rt_c_status drop index >>>
 
define recreate_constraint_status_rt
<<< alter table rt add CONSTRAINT rt_c1_status 
    CHECK (status in ('D','E','O','I')) >>>
 
define set_site_key_for_single_site_dbs
<<<
declare
   cursor onesite is 
      select * from 
         (select site_key, db_key, 
                 count(db_key) over (partition by db_key) num_sites  from node
          where site_key > 0
            and substr(nvl(db_unique_name, 'A'),1,1) <> '$')
      where num_sites=1;
begin
   for onesite_row in onesite loop
      update ckp set site_key = onesite_row.site_key where
         site_key is null and
         ckp_key in (select ckp_key from ckp, dbinc
                       where dbinc.dbinc_key = ckp.dbinc_key
                         and dbinc.db_key = onesite_row.db_key);
      update site_dfatt set site_key = onesite_row.site_key where
         site_key is null and
         df_key in (select df_key from df, dbinc
                       where dbinc.dbinc_key = df.dbinc_key
                         and dbinc.db_key = onesite_row.db_key);
      update site_tfatt set site_key = onesite_row.site_key where
         site_key is null and
         tf_key in (select tf_key from tf, dbinc
                       where dbinc.dbinc_key = tf.dbinc_key
                         and dbinc.db_key = onesite_row.db_key);
      update orl set site_key = onesite_row.site_key where
         site_key is null and
         dbinc_key in (select dbinc_key from dbinc
                          where db_key = onesite_row.db_key);
      update al set site_key = onesite_row.site_key where
         site_key is null and
         dbinc_key in (select dbinc_key from dbinc
                          where db_key = onesite_row.db_key);
      update bp set site_key = onesite_row.site_key where
         site_key is null and
         bs_key in (select bs_key from bs
                       where bs.db_key = onesite_row.db_key);
      update bs set site_key = onesite_row.site_key where
         site_key is null and
         db_key = onesite_row.db_key;
      update rout set site_key = onesite_row.site_key where
         site_key is null and
         db_key = onesite_row.db_key;
      update ccf set site_key = onesite_row.site_key where
         site_key is null and
         dbinc_key in (select dbinc_key from dbinc
                          where db_key = onesite_row.db_key);
      update xcf set site_key = onesite_row.site_key where
         site_key is null and
         dbinc_key in (select dbinc_key from dbinc
                          where db_key = onesite_row.db_key);
      update cdf set site_key = onesite_row.site_key where
         site_key is null and
         dbinc_key in (select dbinc_key from dbinc
                          where db_key = onesite_row.db_key);
      update xdf set site_key = onesite_row.site_key where
         site_key is null and
         dbinc_key in (select dbinc_key from dbinc
                          where db_key = onesite_row.db_key);
      update xal set site_key = onesite_row.site_key where
         site_key is null and
         dbinc_key in (select dbinc_key from dbinc
                          where db_key = onesite_row.db_key);
      update rsr set site_key = onesite_row.site_key where
         site_key is null and
         dbinc_key in (select dbinc_key from dbinc
                          where db_key = onesite_row.db_key);
      update grsp set site_key = onesite_row.site_key where
         site_key is null and
         dbinc_key in (select dbinc_key from dbinc
                          where db_key = onesite_row.db_key);
      update nrsp set site_key = onesite_row.site_key where
         site_key is null and
         dbinc_key in (select dbinc_key from dbinc
                          where db_key = onesite_row.db_key);
      update bcr set site_key = onesite_row.site_key where
         site_key is null and
         df_key in (select df_key from df, dbinc
                       where dbinc.dbinc_key = df.dbinc_key
                         and dbinc.db_key = onesite_row.db_key);
--
--
      commit;
   end loop;
end;
>>>
 
define add_plugin_scn_to_ts
<<<
  alter table ts add (plugin_scn number default 0 not null)
>>>
 
define add_plugin_scn_to_tsatt
<<<
  alter table tsatt add (plugin_scn number default 0 not null)
>>>
 
define upgcat_drop_tsatt_f1
<<<
  alter table tsatt drop constraint tsatt_f1 drop index
>>>
 
define upgcat_drop_tf_f1
<<<
  alter table tf drop constraint tf_f1 drop index
>>>
 
define upgcat_drop_df_f1
<<<
  alter table df drop constraint df_f1 drop index
>>>
 
define upgcat_drop_df_f2
<<<
  alter table df drop constraint df_f2 drop index
>>>
 
define upgcat_drop_df_f3
<<<
  alter table df drop constraint df_f3 drop index
>>>
 
define upgcat_drop_df_f4
<<<
  alter table df drop constraint df_f4 drop index
>>>
 
define upgcat_drop_df_f5
<<<
  alter table df drop constraint df_f5 drop index
>>>
 
define upgcat_drop_ts_p
<<< 
  alter table ts drop constraint ts_p drop index
>>>
 
define upgcat_drop_ts_u1
<<<
   alter table ts drop constraint ts_u1 drop index
>>>
 
define upgcat_drop_ts_u2
<<<
  alter table ts drop constraint ts_u2 drop index
>>>
 
define upgcat_drop_tsatt_u1
<<<
  alter table tsatt drop constraint tsatt_u1 drop index
>>>
 
define upgcat_add_plugin_scn_to_tf
<<<
  alter table tf add (plugin_scn number default 0 not null)
>>>
 
define upgcat_add_tf_c1_plugin_scn
<<<
  alter table tf add CONSTRAINT tf_c1_plugin_scn CHECK (plugin_scn = 0)
>>>
 
define upgcat_fix_plugin_scn_in_ts_and_tsatt
<<<
   begin
      for plugin_df_row in
      (
         select distinct df.dbinc_key, df.ts#, df.ts_create_scn,
                         df.ts_plugin_scn, df.drop_scn, df.pdbinc_key
         from df
         where df.ts_plugin_scn <> 0
              and not exists (select 1 from ts
                              where ts.plugin_scn = df.ts_plugin_scn
                              and ts.dbinc_key    = df.dbinc_key
                              and ts.create_scn   = df.ts_create_scn
                              and ts.pdbinc_key   = df.pdbinc_key
                              and ts.ts#          = df.ts#)
         order by df.drop_scn
      )
      loop
         begin
            update ts set plugin_scn = plugin_df_row.ts_plugin_scn
            where ts.dbinc_key          = plugin_df_row.dbinc_key
                  and ts.ts#            = plugin_df_row.ts#
                  and ts.create_scn     = plugin_df_row.ts_create_scn
                  and ts.plugin_scn     = 0
                  and ts.pdbinc_key     = plugin_df_row.pdbinc_key
                  and ((nvl(ts.drop_scn, -1) = nvl(plugin_df_row.drop_scn, -1))
                      or (ts.drop_scn <= plugin_df_row.drop_scn));
            if (sql%rowcount > 1) then
               raise_application_error(num=>-20017,
                  msg=>'illegal ts plugin_scn update operation');
            end if;
         exception
            when dup_val_on_index then
               null;
         end;
 
         begin
            update tsatt set plugin_scn = plugin_df_row.ts_plugin_scn
            where tsatt.dbinc_key       = plugin_df_row.dbinc_key
                  and tsatt.ts#         = plugin_df_row.ts#
                  and tsatt.create_scn  = plugin_df_row.ts_create_scn
                  and tsatt.plugin_scn  = 0;
            if (sql%rowcount > 1) then
               raise_application_error(num=>-20017,
                  msg=>'illegal tsatt plugin_scn update operation');
            end if;
         exception
            when dup_val_on_index then
               null;
         end; 
 
         commit;
      end loop;
   end; 
>>>
 
define upgcat_add_ts_pdbinc_key
<<<
   alter table ts add (pdbinc_key number)
>>>
 
define upgcat_add_tsatt_pdbinc_key
<<<
   alter table tsatt add (pdbinc_key number)
>>>
 
define upgcat_add_df_pdbinc_key
<<<
   alter table df add (pdbinc_key number)
>>>
 
define upgcat_add_tf_pdb_key
<<<
   alter table tf add (pdb_key number)
>>>
 
define upgcat_add_df_ts_pdbinc_key
<<<
   alter table df add (ts_pdbinc_key number)
>>>
 
define upgcat_add_tf_ts_pdbinc_key
<<<
   alter table tf add (ts_pdbinc_key number)
>>>
 
define upgcat_add_rout_site_key
<<<
   alter table rout add (site_key NUMBER)
>>>
 
define upgcat_add_rout_f3
<<<
  alter table rout add CONSTRAINT rout_f3 FOREIGN KEY(site_key) 
    REFERENCES node ON DELETE CASCADE
>>>
 
define upgcat_remove_orphan_bcf
<<<
   delete bcf where not exists
      (select 1 from dbinc where dbinc.dbinc_key = bcf.dbinc_key)
>>>
 
define upgcat_add_bcf_f3
<<<
   alter table bcf add CONSTRAINT bcf_f3 FOREIGN KEY (dbinc_key) 
     REFERENCES dbinc ON DELETE CASCADE
>>>
 
define upgcat_remove_orphan_bdf
<<<
   delete bdf where not exists
      (select 1 from dbinc where dbinc.dbinc_key = bdf.dbinc_key)
>>>
 
define upgcat_add_bdf_f3
<<<
   alter table bdf add CONSTRAINT bdf_f3 FOREIGN KEY
      (dbinc_key) REFERENCES dbinc ON DELETE CASCADE
>>>
 
define add_non_cdb_to_pdb
<<<
declare
--
   cursor ncdb_c is
      select db.db_key, db.db_id, dbinc.dbinc_key,
             dbinc.reset_scn, dbinc.reset_time
        from db, dbinc
       where db.db_key = dbinc.db_key
         and not exists (select 1 from pdb where pdb.db_key = db.db_key)
--
       order by db.db_key, nvl2(dbinc.parent_dbinc_key, 1, 0),
                dbinc.reset_time, dbinc.reset_scn;
   new_pdb_key    number;
   new_pdbinc_key number;
   prev_db_key    number  := -1;
   zero_guid      raw(16) := HEXTORAW(RPAD('0', 32, '0'));
begin
   for r in ncdb_c loop
     if (r.db_key <> prev_db_key) then
        prev_db_key := r.db_key;
 
        insert into pdb
           (pdb_key, db_key, db_id, name, con_id, create_scn, guid)
        values
           (rman_seq.nextval, r.db_key, r.db_id, NULL, 0, 1, zero_guid)
        returning pdb_key into new_pdb_key;
 
        update bs  set pdb_key = new_pdb_key where bs.db_key  = r.db_key;
        update bp  set pdb_key = new_pdb_key where bp.db_key  = r.db_key;
        update bsf set pdb_key = new_pdb_key where bsf.db_key = r.db_key;
 
        insert into pdbinc
           (pdbinc_key, pdb_key, born_dbinc_key, inc_scn, begin_reset_scn,
            begin_reset_time, end_reset_scn, parent_pdbinc_key, pdbinc_status)
        values
           (rman_seq.nextval, new_pdb_key, r.dbinc_key, 1, r.reset_scn,
            r.reset_time, 1, NULL, 'CURRENT')
        returning pdbinc_key into new_pdbinc_key;
 
        for r1 in (select dbinc_key from dbinc where db_key = r.db_key) loop
           insert into pdb_dbinc
              (dbinc_key, pdb_key, drop_scn, drop_time, curr_pdbinc_key)
           values
              (r1.dbinc_key, new_pdb_key, NULL, NULL, new_pdbinc_key);
 
           update ts set pdbinc_key = new_pdbinc_key
            where ts.dbinc_key = r1.dbinc_key;
 
           update tsatt set pdbinc_Key = new_pdbinc_key
            where tsatt.dbinc_key = r1.dbinc_key;
 
           update df
              set pdbinc_key    = new_pdbinc_key,
                  ts_pdbinc_key = new_pdbinc_key
            where df.dbinc_key = r1.dbinc_key;
 
           update tf
              set pdb_key       = new_pdb_key,
                  ts_pdbinc_key = new_pdbinc_key
            where tf.dbinc_key = r1.dbinc_key;
 
           update bdf set pdb_key = new_pdb_key
            where bdf.dbinc_key = r1.dbinc_key;
           update bcf set pdb_key = new_pdb_key
            where bcf.dbinc_key = r1.dbinc_key;
           update cdf set pdb_key = new_pdb_key
            where cdf.dbinc_key = r1.dbinc_key;
           update ccf set pdb_key = new_pdb_key
            where ccf.dbinc_key = r1.dbinc_key;
           update xdf set pdb_key = new_pdb_key
            where xdf.dbinc_key = r1.dbinc_key;
           update xcf set pdb_key = new_pdb_key
            where xcf.dbinc_key = r1.dbinc_key;
        end loop;
     end if;
--
     commit;
   end loop;
end;
>>>
 
define upgcat_add_bs_pdb_key
<<< alter table bs add (pdb_key number) >>>
 
define upgcat_add_bp_pdb_key
<<< alter table bp add (pdb_key number) >>>
 
define upgcat_add_bdf_pdb_key
<<< alter table bdf add (pdb_key number) >>>
 
define upgcat_add_bcf_pdb_key
<<< alter table bcf add (pdb_key number) >>>
 
define upgcat_add_bsf_pdb_key
<<< alter table bsf add (pdb_key number) >>>
 
define upgcat_add_cdf_pdb_key
<<< alter table cdf add (pdb_key number) >>>
 
define upgcat_add_ccf_pdb_key
<<< alter table ccf add (pdb_key number) >>>
 
define upgcat_add_xdf_pdb_key
<<< alter table xdf add (pdb_key number) >>>
 
define upgcat_add_bp_template_key
<<< alter table bp add (template_key number) >>>
 
define upgcat_add_xcf_pdb_key
<<< alter table xcf add (pdb_key number) >>>
 
define modify_ts_pdbinc_key_not_null
<<< alter table ts modify(pdbinc_key NOT NULL) >>>
 
define modify_tsatt_pdbinc_key_not_null
<<< alter table tsatt modify(pdbinc_key NOT NULL) >>>
 
define modify_df_pdbinc_key_not_null
<<< alter table df modify(pdbinc_key NOT NULL) >>>
 
define modify_tf_pdb_key_not_null
<<< alter table tf modify(pdb_key NOT NULL) >>>
 
define modify_df_ts_pdbinc_key_not_null
<<< alter table df modify(ts_pdbinc_key NOT NULL) >>>
 
define modify_tf_ts_pdbinc_key_not_null
<<< alter table tf modify(ts_pdbinc_key NOT NULL) >>>
 
define modify_bs_pdb_key_not_null
<<< alter table bs modify(pdb_key NOT NULL) >>>
 
define modify_bp_pdb_key_not_null
<<< alter table bp modify(pdb_key NOT NULL) >>>
 
define modify_bdf_pdb_key_not_null
<<< alter table bdf modify(pdb_key NOT NULL) >>>
 
define modify_bcf_pdb_key_not_null
<<< alter table bcf modify(pdb_key NOT NULL) >>>
 
define modify_bsf_pdb_key_not_null
<<< alter table bsf modify(pdb_key NOT NULL) >>>
 
define modify_cdf_pdb_key_not_null
<<< alter table cdf modify(pdb_key NOT NULL) >>>
 
define modify_ccf_pdb_key_not_null
<<< alter table ccf modify(pdb_key NOT NULL) >>>
 
define modify_xdf_pdb_key_not_null
<<< alter table xdf modify(pdb_key NOT NULL) >>>
 
define modify_xcf_pdb_key_not_null
<<< alter table xcf modify(pdb_key NOT NULL) >>>
 
define upgcat_add_bs_f3
<<<
    alter table bs add CONSTRAINT bs_f3 FOREIGN KEY
       (pdb_key) REFERENCES pdb
>>>
 
define upgcat_add_bp_f4
<<<
    alter table bp add CONSTRAINT bp_f4 FOREIGN KEY 
       (pdb_key) REFERENCES pdb
>>>
 
define upgcat_add_bcf_f2
<<<
    alter table bcf add CONSTRAINT bcf_f2 FOREIGN KEY
       (pdb_key) REFERENCES pdb
>>>
 
define upgcat_add_ccf_f3
<<<
   alter table ccf add CONSTRAINT ccf_f3 FOREIGN KEY
       (pdb_key) REFERENCES pdb
>>>
 
define upgcat_add_xcf_f3
<<<
   alter table xcf add CONSTRAINT xcf_f3 FOREIGN KEY
       (pdb_key) REFERENCES pdb
>>>
 
define upgcat_add_bsf_f2
<<<
   alter table bsf add CONSTRAINT bsf_f2 FOREIGN KEY
       (pdb_key) REFERENCES pdb
>>>
 
define upgcat_add_bdf_f2
<<<
   alter table bdf add CONSTRAINT bdf_f2 FOREIGN KEY
       (pdb_key) REFERENCES pdb
>>>
 
define upgcat_add_cdf_f4
<<<
   alter table cdf add CONSTRAINT cdf_f4 FOREIGN KEY
       (pdb_key) REFERENCES pdb
>>>
 
define upgcat_add_xdf_f4
<<<
   alter table xdf add CONSTRAINT xdf_f4 FOREIGN KEY
       (pdb_key) REFERENCES pdb
>>>
 
define upgcat_drop_ts_p1
<<<
   alter table ts drop constraint ts_p1 drop index
>>>
 
define upgcat_drop_ts_u3
<<<
   alter table ts drop constraint ts_u3 drop index
>>>
 
define upgcat_add_ts_p2
<<<
   alter table ts add CONSTRAINT ts_p2 PRIMARY KEY
      (dbinc_key, pdbinc_key, ts#, create_scn, plugin_scn)
>>>
 
define upgcat_add_ts_u5
<<<
   alter table ts add CONSTRAINT ts_u5 UNIQUE
      (dbinc_key, pdbinc_key, ts_name, create_scn, plugin_scn)
>>>
 
define upgcat_add_ts_u4
<<<
   alter table ts add CONSTRAINT ts_u4 UNIQUE
      (dbinc_key, pdbinc_key, ts#, drop_scn)
>>>
 
define upgcat_enable_ts_u4
<<<
   alter table ts enable CONSTRAINT ts_u4
>>>
 
define upgcat_add_ts_f2
<<<
   alter table ts add CONSTRAINT ts_f2 FOREIGN KEY
      (pdbinc_key) REFERENCES pdbinc ON DELETE CASCADE
>>>
 
define upgcat_drop_tsatt_u2
<<<
   alter table tsatt drop constraint tsatt_u2 drop index
>>>
 
define upgcat_drop_tsatt_f4
<<<
   alter table tsatt drop constraint tsatt_f4 drop index
>>>
 
define upgcat_add_tsatt_u3
<<<
   alter table tsatt add CONSTRAINT tsatt_u3 UNIQUE
      (dbinc_key, pdbinc_key, ts#, create_scn, plugin_scn,end_ckp_key)
>>>
 
define upgcat_add_tsatt_f5
<<<
   alter table tsatt add CONSTRAINT tsatt_f5 FOREIGN KEY
      (dbinc_key, pdbinc_key, ts#, create_scn, plugin_scn)
      REFERENCES ts ON DELETE CASCADE INITIALLY DEFERRED
>>>
 
define upgcat_add_tsatt_f6
<<<
   alter table tsatt add CONSTRAINT tsatt_f6 FOREIGN KEY
      (pdbinc_key) REFERENCES pdbinc ON DELETE CASCADE
>>>
 
define upgcat_drop_df_u1
<<<
   alter table df drop constraint df_u1 drop index
>>>
 
define upgcat_drop_df_u3
<<<
   alter table df drop constraint df_u3 drop index
>>>
 
define upgcat_add_df_ts_plugin_scn
<<<
   alter table df add (ts_plugin_scn number default 0 not null)
>>>
 
define upgcat_init_df_ts_plugin_scn
<<<
declare
   l_plugin_scn number;
   cursor df_c is
      select df.read_only, df.plugin_scn,
             df.plugin_reset_scn, ts.plugin_scn ts_plugin_scn
        from df, ts
--
      where df.dbinc_key = ts.dbinc_key
        and df.ts# = ts.ts#
        and df.ts_create_scn = ts.create_scn
        and (df.plugin_scn = ts.plugin_scn or df.plugin_scn = 0)
        and df.ts_plugin_scn != ts.plugin_scn
      for update of df.ts_plugin_scn;
begin
   for dfrec in df_c loop
--
     if (dfrec.plugin_reset_scn = 0) then
        l_plugin_scn := 0;
     else
        l_plugin_scn := dfrec.plugin_scn;
     end if;
 
--
     update df
        set ts_plugin_scn = dfrec.ts_plugin_scn, plugin_scn = l_plugin_scn
      where current of df_c;
   end loop;
   commit;
end;
>>>
 
define upgcat_add_df_pdb_closed
<<< alter table df add (pdb_closed number default 0 not null) >>>
 
define upgcat_add_df_p1
<<<
  alter table df add CONSTRAINT df_p1 PRIMARY KEY
     (dbinc_key, pdbinc_key, file#, create_scn, plugin_scn)
>>>
 
define upgcat_add_df_u3
<<<
   alter table df add CONSTRAINT df_u3 UNIQUE
      (dbinc_key, pdbinc_key, file#, drop_scn)
>>>
 
define upgcat_add_df_u4
<<<
   alter table df add CONSTRAINT df_u4 UNIQUE
      (dbinc_key, pdbinc_key, df_key)
>>>
 
define upgcat_add_df_f6
<<<
   alter table df add CONSTRAINT df_f6 FOREIGN KEY
      (dbinc_key, ts_pdbinc_key, ts#, ts_create_scn, ts_plugin_scn)
   REFERENCES ts ON DELETE CASCADE
>>>
 
define upgcat_add_df_f7
<<<
   alter table df add CONSTRAINT df_f7 FOREIGN KEY
      (pdbinc_key) REFERENCES pdbinc ON DELETE CASCADE
>>>
 
define upgcat_drop_tf_f2
<<<
   alter table tf drop constraint tf_f2 drop index
>>>
 
define upgcat_add_tf_f3
<<<
  alter table tf add CONSTRAINT tf_f3 FOREIGN KEY
     (dbinc_key, ts_pdbinc_key, ts#, ts_create_scn, plugin_scn)
     REFERENCES ts ON DELETE CASCADE
>>>
 
define upgcat_add_tf_f4
<<<
  alter table tf add CONSTRAINT tf_f4 FOREIGN KEY
     (pdb_key) REFERENCES pdb ON DELETE CASCADE
>>>
 
define pdb_i_3
<<<
   create unique index pdb_i_3 on pdb
      (decode(con_id, 0, pdb_key, 1, pdb_key),
       decode(con_id, 0, 0, 1, 0)) &tablespace&
>>>
 
define add_high_pdb_recid_to_node
<<< alter table node add (high_pdb_recid number) >>>
 
define add_high_pic_recid_to_node
<<< alter table node add (high_pic_recid number default 0 not null) >>>
 
define add_ors_bp_key_poll_col_to_node
<<< alter table node add (bp_key_poll number default 0 not null) >>>
 
define add_ors_timezone_col_to_node
<<< alter table node add (
db_timezone     VARCHAR2(64),
timezone_src    VARCHAR2(1))
add CONSTRAINT check_timezone_src CHECK (timezone_src IN ('A', 'P','R','S'))
>>>
 
define update_ors_col_in_bp
<<< alter table bp rename column am_access to ba_access >>>
 
define add_ors_col_to_bp
<<< alter table bp add (
ct_key      NUMBER,
ba_access   VARCHAR2(1) DEFAULT 'U',
vb_key      NUMBER,
lib_key     NUMBER,
purged VARCHAR(1) DEFAULT 'U' NOT NULL)
add CONSTRAINT bp_u2 UNIQUE (ct_key)
add CONSTRAINT bp_c_rs CHECK (ba_access IN ('U', 'D', 'L', 'T', 'R'))
add CONSTRAINT bp_c_lib_key CHECK
   ((lib_key IS NOT NULL AND vb_key  IS NULL AND ba_access IN ('T', 'R')) OR
    (lib_key IS NULL     AND ba_access IN ('D', 'L', 'U')))
add CONSTRAINT bp_c_purged CHECK
   ((purged in ('Y','N') AND status  = 'D' AND ba_access != 'U') OR
    (purged = 'N'        AND status != 'D' AND ba_access != 'U') OR
    (purged = 'U'        AND ba_access = 'U')
)
>>>
 
define add_activation_to_brl
<<< alter table brl add (activation varchar2(1)) >>>
 
define limit_rman_seq_to_ub8
<<<
ALTER SEQUENCE rman_seq MAXVALUE 18446744073709551615 CACHE 100 ORDER NOCYCLE
>>>
 
define add_issft_to_df
<<< alter table df add (issft number) >>>
 
define add_config_p_constraint
<<<alter table config add CONSTRAINT config_p PRIMARY KEY (name)>>>
 
define add_create_time_to_deleted_object
<<< alter table deleted_object add (create_time date) >>>
 
define delete_old_deleted_object_rec
<<<
begin
   delete deleted_object where create_time is null;
   commit;
end;
>>>
 
define modify_deleted_object_create_time
<<< alter table deleted_object modify(create_time NOT NULL) >>>
 
 
define high_df_recid_update
<<<
declare
    rcver_i VARCHAR2(15);
begin 
    select max(version) into rcver_i from rcver ;
    IF rcver_i < '12.01.00.00' OR rcver_i < '12.01.00.00.00' THEN
      update node set high_df_recid = 0 ;
    END IF;
end;    
>>>
 
define drop_bp_insert_trigger
<<<
    drop trigger bp_insert_trigger
>>>
 
define drop_bs_insert_trigger
<<<
    drop trigger bs_insert_trigger
>>>
 
define drop_bdf_insert_trigger
<<<
    drop trigger bdf_insert_trigger
>>>
 
define drop_bcf_insert_trigger
<<<
    drop trigger bcf_insert_trigger
>>>
 
define drop_bsf_insert_trigger
<<<
    drop trigger bsf_insert_trigger
>>>
 
define drop_brl_insert_trigger
<<<
    drop trigger brl_insert_trigger
>>>
 
define drop_do_insert_trigger
<<<
    drop trigger do_insert_trigger
>>>
 
define recomp_invalid_objs
<<<
BEGIN
  FOR cur_rec IN (SELECT object_name,
                         object_type,
                         DECODE(object_type, 'PACKAGE', 1,
                                             'PACKAGE BODY', 2,
                                             'VIEW', 3) AS recompile_order
                  FROM   user_objects
                  WHERE  object_type IN ('PACKAGE', 'PACKAGE BODY', 'VIEW')
                  AND    status != 'VALID'
                  AND   (object_name like 'RA_%' OR
                         object_name like 'RAI_%' OR
                         object_name like 'DBMS_RA%' OR
                         object_name like 'DBMS_RCV%' OR
                         object_name like 'RCI_%' OR
                         object_name like 'RC_%' OR
                         object_name like '_RS_RC%')
                  ORDER BY 3)
  LOOP
    BEGIN
      dbms_output.put_line('compiling ' || cur_rec.object_name);
      IF cur_rec.object_type in ('PACKAGE', 'VIEW') THEN
        EXECUTE IMMEDIATE 'ALTER ' || cur_rec.object_type || 
            '"' || cur_rec.object_name || '" COMPILE';
      ElSE
        EXECUTE IMMEDIATE 'ALTER PACKAGE ' || 
            '"' || cur_rec.object_name || '" COMPILE BODY';
      END IF;
    END;
  END LOOP;
END;
>>>
 
define upgcat_drop_bp_f1
<<<
  alter table bp drop CONSTRAINT bp_f1 drop index
>>>
 
define upgcat_add_bp_f3
<<<
  alter table bp add CONSTRAINT bp_f3 FOREIGN KEY
     (bs_key) REFERENCES bs
>>>
  
define upgcat_add_bp_c_copyno
<<<
  alter table bp ADD CONSTRAINT bp_c_copyno CHECK (copy# > 0 AND copy# <= 256)
>>>
 
define add_set_stamp_count_2_deleted_object
<<<
  alter table deleted_object add (set_stamp NUMBER, set_count NUMBER)
>>>
 
define remove_bs_key_from_deleted_object
<<<
  alter table deleted_object drop column bs_key
>>>  
 
define upgcat_drop_server_u1_constraint
<<<
  alter table server drop constraint server_u1
>>>
 
define upgcat_drop_server_u2_constraint
<<<
  alter table server drop constraint server_u2
>>>
 
define upgcat_drop_server_http_add_column
<<<
  alter table server drop column rs_http_add
>>>
 
define upgcat_rename_rs_proxy_port_in_server
<<<
  alter table server rename column rs_proxy_port to proxy_port
>>>
 
define upgcat_rename_rs_proxy_url_in_server
<<<
  alter table server rename column rs_proxy_url to proxy_url 
>>>
 
define upgcat_drop_proxy_add_from_server
<<<
  alter table server drop column proxy_add
>>>
 
define upgcat_drop_rs_http_url_from_server
<<<
  alter table server drop column rs_http_url
>>>
 
define upgcat_add_server_host_to_server
<<<
  alter table server add (server_host clob not null)
>>>
 
define upgcat_rename_rs_http_port_in_server
<<<
  alter table server rename column rs_http_port to server_port 
>>>
 
define upgcat_add_constr_1
<<<
  alter table server add CONSTRAINT 
              server_u1 UNIQUE(filter_user, wallet_alias, wallet_path)
>>>
 
define upgcat_rename_rs_server_name_in_server
<<<
  alter table server rename column rs_server_name to rep_server_name
>>>
 
define upgcat_rename_rs_server_key
<<<
  alter table server rename column rs_server_key to server_key
>>>
 
define upgcat_add_constr_2
<<<
  alter table server add CONSTRAINT server_u2 UNIQUE(rep_server_name)
>>>
 
define upgcat_add_constr_3
<<<
  alter table server add CONSTRAINT server_c1 CHECK (server_port > 0)
>>>
 
define upgcat_add_constr_4
<<<
  alter table server add CONSTRAINT server_c2 CHECK (proxy_port  > 0)
>>>
 
define upgcat_add_constr_5
<<<
  alter table server add CONSTRAINT server_p PRIMARY KEY (server_key)
>>>
 
define add_handle_device_type_2_deleted_object
<<<
  alter table deleted_object
     add (handle varchar2(1024), device_type varchar2(255))
>>>
 
define update_bs_stamp
<<<
declare
    rcver_i VARCHAR2(15);
begin
    select max(version) into rcver_i from rcver ;
    IF rcver_i < '12.01.00.00' OR rcver_i < '12.01.00.00.00' THEN
      update bs set bs_stamp = set_stamp where bs_recid = 0;
    END IF;
end;
>>>
 
define add_check_database_role_c2_to_node
<<< 
alter table node add constraint check_database_role_c2 CHECK 
  ((substr(db_unique_name,1,1) = '$' AND database_role = 'RA') OR
   (substr(nvl(db_unique_name, 'A'),1,1) <> '$' AND 
     database_role IN ('PRIMARY', 'STANDBY')))
>>>
 
define upgcat_drop_deleted_object_p
<<< alter table deleted_object drop CONSTRAINT deleted_object_p drop index >>>
 
define upgcat_add_deleted_object_p1
<<<
  alter table deleted_object add CONSTRAINT deleted_object_p1
     PRIMARY KEY (do_key, db_key)
>>>
 
define upgcat_add_deleted_object_f1
<<<
  alter table deleted_object add CONSTRAINT deleted_object_f1 FOREIGN KEY
     (db_key) REFERENCES db ON DELETE CASCADE
>>>
 
define upgcat_drop_1unwated_cols_from_watermarks
<<<
  alter table watermarks drop (stamp_low_key, stamp_high_key, high_bp_key,
      high_bs_key, high_bdf_key, high_bcf_key, high_brl_key, high_bsf_key,
      last_bp_key, last_do_key)
>>>  
 
define add_high_bp_recid_2_watermarks
<<<
  alter table watermarks add (high_bp_recid number default 0 not null)
>>>
 
define resize_name_tempres
<<<
  alter table tempres modify (name varchar2(1024))
>>>
 
define resize_server_rep_server_name
<<<
  alter table server modify (rep_server_name varchar2(128))
>>>
 
define drop_check_database_role_c1
<<<
  alter table node drop constraint check_database_role_c1 
>>>
 
define rename_baschemaver_p_constraint
<<<  
  alter table baschemaver rename constraint baschemaver_p to raschemaver_p
>>>
 
define rename_baschemaver_to_raschemaver
<<<  
  alter table baschemaver rename to raschemaver
>>>
 
define resize_pdb_name
<<<
alter table pdb modify (name varchar2(128))
>>>
 
define add_nrsp_add_pdb_key
<<<
   alter table nrsp add (pdb_key number)
>>>
 
define init_nrsp_pdb_key 
<<<
declare
   cursor nrsp_c is
      select distinct nrsp.rowid rid, dbinc.db_key db_key
        from nrsp, dbinc
       where nrsp.pdb_key is null
         and nrsp.dbinc_key = dbinc.dbinc_key
       order by dbinc.db_key;
   prev_db_key   number := 0;
   local_pdb_key number;
begin
   for r in nrsp_c loop
     if (r.db_key <> prev_db_key) then
        prev_db_key := r.db_key;
        select pdb_key into local_pdb_key
          from pdb
         where pdb.con_id in (1, 0)
           and pdb.db_key = r.db_key;
     end if;
 
     update nrsp set pdb_key = local_pdb_key where rowid = r.rid;
   end loop;
end;
>>>
 
define modify_nrsp_pdb_key_not_null
<<< alter table nrsp modify(pdb_key NOT NULL) >>>
 
define add_nrsp_add_clean
<<<
   alter table nrsp add (clean varchar(3) default 'NO')
>>>
 
define add_nrsp_u2_constraint
<<<
   alter table nrsp add constraint nrsp_u2 UNIQUE(site_key, rspname, pdb_key)
>>>
 
define add_nrsp_f3_constraint
<<<
   alter table nrsp add constraint nrsp_f3
      FOREIGN KEY (pdb_key) REFERENCES pdb ON DELETE CASCADE
>>>
 
define add_nrsp_c1_constraint
<<<
   alter table nrsp add constraint nrsp_c1 CHECK (clean IN ('YES','NO'))
>>>
 
define add_grsp_add_pdb_key
<<<
   alter table grsp add (pdb_key number)
>>>
 
define init_grsp_pdb_key
<<<
declare
   cursor grsp_c is
      select distinct grsp.rowid rid, dbinc.db_key db_key
        from grsp, dbinc
       where grsp.pdb_key is null
         and grsp.dbinc_key = dbinc.dbinc_key
       order by dbinc.db_key;
   prev_db_key   number := 0;
   local_pdb_key number;
begin
   for r in grsp_c loop
     if (r.db_key <> prev_db_key) then
        prev_db_key := r.db_key;
        select pdb_key into local_pdb_key
          from pdb
         where pdb.con_id in (1, 0)
           and pdb.db_key = r.db_key;
     end if;
 
     update grsp set pdb_key = local_pdb_key where rowid = r.rid;
   end loop;
end;
>>>
 
define modify_grsp_pdb_key_not_null
<<< alter table grsp modify(pdb_key NOT NULL) >>>
 
define add_grsp_add_clean
<<<
   alter table grsp add (clean varchar(3) default 'NO')
>>>
 
define drop_grsp_u1_constraint
<<<
   alter table grsp drop constraint grsp_u1
>>>
 
define add_grsp_u4_constraint
<<<
   alter table grsp add constraint grsp_u4 UNIQUE(site_key, rspname, pdb_key)
>>>
 
define add_grsp_f1_constraint
<<<
   alter table grsp add constraint grsp_f1
      FOREIGN KEY (pdb_key) REFERENCES pdb ON DELETE CASCADE
>>>
 
define add_grsp_c1_constraint
<<<
   alter table grsp add constraint grsp_c1 CHECK (clean IN ('YES','NO'))
>>>
 
define add_pdb_nobackup
<<<
   alter table pdb add (nobackup VARCHAR2(1) DEFAULT 'N' NOT NULL)
>>>
 
define add_pdb_c_nobackup_constraint
<<<
   alter table pdb add constraint pdb_c_nobackup CHECK (nobackup in ('Y','N'))
>>>
 
define upgcat_df_add_pfckpscn
<<<
   alter table df add (pdb_foreign_ckp_scn number default 0 not null)
>>>
 
define upgcat_df_add_pfafn
<<<
   alter table df add (pdb_foreign_afn number default 0 not null)
>>>
 
 
define drpcat_revoke_everything
<<<
BEGIN
  FOR c IN (
    SELECT NULL
      FROM dual
     WHERE EXISTS (
             SELECT NULL
               FROM user_tables
              WHERE table_name = 'VPC_USERS'
           )
       AND 2 = (
             SELECT COUNT(*)
               FROM user_objects
              WHERE object_name = 'DBMS_RCVCAT'
                AND object_type IN ('PACKAGE', 'PACKAGE BODY')
                AND status = 'VALID'
           )
  )
  LOOP
    EXECUTE IMMEDIATE '
    BEGIN
      FOR i IN (SELECT filter_user FROM vpc_users)
      LOOP
        BEGIN
          dbms_rcvcat.revoke_all(i.filter_user);
        EXCEPTION
          WHEN OTHERS
          THEN NULL;
        END;
      END LOOP;
    END;
    ';
  END LOOP;
END;
>>>
define drpcat_1  <<< DROP SEQUENCE rman_seq >>>
define drpcat_2  <<< DROP TABLE rcver >>>
define drpcat_3  <<< DROP TABLE db cascade constraints >>>
define drpcat_4  <<< DROP TABLE conf cascade constraints >>>
define drpcat_5  <<< DROP TABLE dbinc cascade constraints >>>
define drpcat_6  <<< DROP TABLE ckp cascade constraints >>>
define drpcat_7  <<< DROP TABLE ts cascade constraints >>>
define drpcat_8  <<< DROP TABLE tsatt cascade constraints >>>
define drpcat_9  <<< DROP TABLE df cascade constraints >>>
define drpcat_10 <<< DROP TABLE site_dfatt cascade constraints >>>
define drpcat_11 <<< DROP TABLE offr cascade constraints >>>
define drpcat_12 <<< DROP TABLE rr cascade constraints >>>
define drpcat_13 <<< DROP TABLE rt cascade constraints >>>
define drpcat_14 <<< DROP TABLE orl cascade constraints >>>
define drpcat_15 <<< DROP TABLE rlh cascade constraints >>>
define drpcat_16 <<< DROP TABLE bs cascade constraints >>>
define drpcat_17 <<< DROP TABLE bp cascade constraints >>>
define drpcat_18 <<< DROP TABLE bcf cascade constraints >>>
define drpcat_19 <<< DROP TABLE ccf cascade constraints >>>
define drpcat_20 <<< DROP TABLE xcf cascade constraints >>>
define drpcat_21 <<< DROP TABLE bdf cascade constraints >>>
define drpcat_22 <<< DROP TABLE cdf cascade constraints >>>
define drpcat_23 <<< DROP TABLE xdf cascade constraints >>>
define drpcat_24 <<< DROP TABLE brl cascade constraints >>>
define drpcat_25 <<< DROP TABLE al cascade constraints >>>
define drpcat_26 <<< DROP TABLE bcb cascade constraints >>>
define drpcat_27 <<< DROP TABLE ccb cascade constraints >>>
define drpcat_28 <<< DROP TABLE scr cascade constraints >>>
define drpcat_29 <<< DROP TABLE scrl cascade constraints >>>
define drpcat_30 <<< DROP VIEW rc_database >>>
define drpcat_31 <<< DROP VIEW rc_database_incarnation >>>
define drpcat_32 <<< DROP VIEW rc_resync >>>
define drpcat_33 <<< DROP VIEW rc_checkpoint >>>
define drpcat_34 <<< DROP VIEW rc_tablespace >>>
define drpcat_35 <<< DROP VIEW rc_datafile >>>
define drpcat_36 <<< DROP VIEW rc_redo_thread >>>
define drpcat_37 <<< DROP VIEW rc_redo_log >>>
define drpcat_38 <<< DROP VIEW rc_log_history >>>
define drpcat_39 <<< DROP VIEW rc_archived_log >>>
define drpcat_40 <<< DROP VIEW rc_backup_set >>>
define drpcat_41 <<< DROP VIEW rc_backup_piece >>>
define drpcat_42 <<< DROP VIEW rc_backup_datafile >>>
define drpcat_43 <<< DROP VIEW rc_backup_controlfile >>>
define drpcat_44 <<< DROP VIEW rc_datafile_copy >>>
define drpcat_45 <<< DROP VIEW rc_controlfile_copy >>>
define drpcat_46 <<< DROP VIEW rc_backup_redolog >>>
define drpcat_47 <<< DROP VIEW rc_backup_corruption >>>
define drpcat_48 <<< DROP VIEW rc_copy_corruption >>>
define drpcat_49 <<< DROP VIEW rc_offline_range >>>
define drpcat_50 <<< DROP VIEW rc_stored_script >>>
define drpcat_51 <<< DROP VIEW rc_stored_script_line >>>
define drpcat_52 <<< DROP VIEW rc_proxy_datafile >>>
define drpcat_53 <<< DROP VIEW rc_proxy_controlfile >>>
define drpcat_54 <<< DROP VIEW rc_rman_configuration >>>
define drpcat_vpc 
<<< 
BEGIN
  BEGIN
    EXECUTE IMMEDIATE 'DROP PACKAGE dbms_rcvvpc';
  EXCEPTION
    WHEN OTHERS
    THEN NULL;
  END;
  BEGIN
    EXECUTE IMMEDIATE 'DROP TRIGGER vpc_context_trg';
  EXCEPTION
    WHEN OTHERS
    THEN NULL;
  END;
END;
>>>
define drpcat_55 <<< DROP PACKAGE dbms_rcvcat >>>
define drpcat_56 <<< DROP PACKAGE dbms_rcvman >>>
define drpcat_57 <<< DROP TABLE config >>>
define drpcat_58 <<< DROP TABLE sfile >>>
define drpcat_59 <<< DROP VIEW rc_stored_file >>>
define drpcat_60 <<< DROP VIEW rc_database_block_corruption >>>
define drpcat_61 <<< DROP TABLE bsf >>>
define drpcat_62 <<< DROP VIEW rc_backup_spfile >>>
define drpcat_63 <<< DROP TABLE xal cascade constraints >>>
define drpcat_64 <<< DROP VIEW rc_proxy_archivedlog >>>
define drpcat_65 <<< DROP VIEW rc_backup_files >>>
define drpcat_66 <<< DROP TABLE rsr cascade constraints >>>
define drpcat_67 <<< DROP VIEW RC_RMAN_STATUS cascade constraints >>>
define drpcat_68 <<< DROP TABLE fb >>>
define drpcat_69 <<< DROP TABLE tf cascade constraints >>>
define drpcat_70 <<< DROP TABLE site_tfatt cascade constraints >>>
define drpcat_71 <<< DROP VIEW rc_tempfile >>>
define drpcat_72 <<< DROP TABLE raschemaver >>>
define drop_rc_restore_range <<< DROP VIEW rc_restore_range >>>
define drop_rc_disk_restore_range <<< DROP VIEW rc_disk_restore_range >>>
define drop_rc_sbt_restore_range <<< DROP VIEW rc_sbt_restore_range >>>
define drop_dfatt <<< DROP TABLE dfatt cascade constraints >>>
define drop_tfatt <<< DROP TABLE tfatt cascade constraints >>>
define drop_vpc_users <<< DROP TABLE vpc_users >>>
define drop_vpc_databases <<< DROP TABLE vpc_databases >>>
define drop_cfs <<< DROP TABLE cfs >>>
define drop_xmlstore <<< DROP TABLE xmlstore >>>
define drop_node <<< DROP TABLE NODE cascade constraints >>>
define drop_tempres
<<<
declare
   tempres_present number;
   type cur_typ is ref cursor;
   tempres_c       cur_typ;
   tempres_q       varchar2(256) := 'select name, data_type from tempres';
   name            varchar2(256);
   data_type       varchar2(256);
begin
    select count(*)
      into tempres_present
      from user_tab_columns
     where table_name = 'TEMPRES';
   if (tempres_present = 0) then
      return;
   end if;
   open tempres_c for tempres_q;
   loop
      fetch tempres_c into name, data_type;
      exit when tempres_c%notfound;
      begin
         if data_type = 'TABLE' then
            execute immediate 'drop table ' || name;
         elsif data_type = 'DBLINK' then
            execute immediate 'drop database link ' || name;
         end if;
      exception
         when others then
            null;
      end;
   end loop;
   execute immediate 'drop table tempres';
end;
>>>
define drop_grsp   <<< DROP TABLE grsp cascade constraints >>>
define drop_nrsp   <<< DROP TABLE nrsp >>>
define drop_bcr    <<< DROP TABLE bcr cascade constraints >>>
define drop_pdb    <<< DROP TABLE pdb cascade constraints >>>
define drop_pdbinc <<< DROP TABLE pdbinc cascade constraints >>>
define drop_pdb_dbinc <<< DROP TABLE pdb_dbinc cascade constraints >>>
 
define drop_server  <<< DROP TABLE server cascade constraints >>>
define drop_deleted_object 
    <<< DROP TABLE deleted_object cascade constraints >>>
define drop_deleted_object_seq 
    <<< DROP TABLE do_seq cascade constraints >>>
 
define drop_watermarks  <<< DROP TABLE watermarks cascade constraints >>>
define drop_rcfile <<< DROP TABLE rcfile >>>
define drop_orsevent <<< DROP TABLE orsevent >>>
define drop_avm_restore_range_cache <<< DROP TABLE rrcache >>>
define drop_rs_rc_get_object_list <<< DROP VIEW "_RS_RC_GET_OBJECT_LIST_" >>>
define drop_rc_rcver <<< DROP VIEW RC_RCVER >>>
define drop_rc_deleted_object <<< DROP VIEW RC_DELETED_OBJECT >>>
define drop_rc_watermarks <<< DROP VIEW RC_WATERMARKS >>>
 
define drop_xml_table_names_views
<<<
DECLARE
   CURSOR rs_xml_views_c IS 
      SELECT view_name FROM user_views 
          where view_name like '_RS_%_';
BEGIN
   FOR rs_xml_view IN rs_xml_views_c LOOP
      EXECUTE IMMEDIATE 'DROP VIEW "' || rs_xml_view.view_name || '"';
   END LOOP;
END;
>>>
 
define drop_rci_tempfile
<<< DROP VIEW rci_tempfile >>>
define drop_rci_datafile
<<< DROP VIEW rci_datafile >>>
define drop_rci_datafile_this_dbinc
<<< DROP VIEW rci_datafile_this_dbinc >>>
define drop_rci_tablespace_this_dbinc
<<< DROP VIEW rci_tablespace_this_dbinc >>>
define drop_rci_backup_set
<<< DROP VIEW rci_backup_set >>>
define drop_rci_backup_piece
<<< DROP VIEW rci_backup_piece >>>
define drop_rci_backup_controlfile
<<< DROP VIEW rci_backup_controlfile >>>
define drop_rci_backup_datafile
<<< DROP VIEW rci_backup_datafile >>>
define drop_rci_backup_spfile
<<< DROP VIEW rci_backup_spfile >>>
define drop_rci_avm_upstream_database
<<<  DROP VIEW rci_ra_upstream_database >>>  
 
define drop_get_lock_on_catalog <<< drop function get_lock_on_catalog >>>
 
 
define abort_avm <<< 
begin 
  execute immediate 'begin dbms_ra.abort_recovery_appliance; end;'; 
exception
  when others then null;
end;
>>>
 
define drop_unreg_database_trigger <<< drop trigger unreg_database_trigger >>>
define drop_node_insert_update <<< drop trigger node_insert_update >>>
define drop_update_sbt_catalog_pieceinc
   <<< drop trigger update_sbt_catalog_pieceinc >>>
define drop_chk_delete_sbt_catalog <<< drop trigger chk_delete_sbt_catalog >>>
define drop_new_df_check <<< drop trigger new_df_check >>>
define drop_rs_instance_startup_trigger <<< drop trigger ba_startup >>>
define drop_rs_instance_startup_job 
<<< 
begin 
  dbms_scheduler.drop_job('RA$TRIGGER_JOB', TRUE); 
end;
>>>
define drop_rs_instance_shutdown_trigger <<< drop trigger ba_shutdown >>>
 
 
define drop_rs_sq <<< drop sequence rai_sq >>>
define drop_rs_recid <<< drop sequence rai_recid >>>
define drop_blocks <<< drop table blocks >>>
define drop_chunks <<< drop table chunks >>>
define drop_df_seq <<< drop table df_seq >>>
define drop_bp_foreign_lib_key 
<<< alter table bp drop constraint bp_foreign_lib_key drop index >>>
define drop_bp_foreign_template_key 
<<< alter table bp drop constraint bp_foreign_template_key drop index >>>
define drop_sbt_task <<< drop table sbt_task >>>
define drop_sbt_task_history <<< drop table sbt_task_history >>>
define drop_sbt_template_db <<< drop table sbt_template_db >>>
define drop_sbt_template_df <<< drop table sbt_template_df >>>
define drop_sbt_job_template <<< drop table sbt_job_template >>>
define drop_sbt_attr_set <<< drop table sbt_attr_set >>>
define drop_sbt_lib_inst_rlist <<< drop table sbt_library_inst_rlist >>>
define drop_sbt_lib_desc <<< drop table sbt_lib_desc >>>
 
define drop_unreg_database <<< drop table unreg_database >>>
define drop_dbsl <<< drop table dbsl >>>
define drop_prvlg <<< drop table prvlg >>>
define drop_rep_server <<< drop table rep_server >>>
 
define drop_vbdf <<< drop table vbdf >>>
define drop_plans_det  <<< drop table plans_details >>>
define drop_plans <<< drop table plans >>>
 
define drop_sbt_session <<< drop table sbt_session >>>
define drop_sbt_catalog <<< drop table sbt_catalog >>>
 
define drop_task_chunk_cache <<< drop table task_chunk_cache >>>
define drop_task <<< drop table task >>>
define drop_task_history <<< drop table task_history >>>
define drop_tasktypenames <<< drop table tasktypenames >>>
define drop_error_log <<< drop table error_log >>>
define drop_polling_history <<< drop table polling_history >>>
define drop_sessions <<< drop table sessions >>>
define drop_odb <<< drop table odb >>>
define drop_odb_stats_cache <<< drop table odb_stats_cache >>>
define drop_prot <<< drop table prot >>>
define drop_poll <<< drop table poll >>>
define drop_storage_histogram <<< drop table storage_histogram >>>
define drop_metadata_filenames <<< drop table metadata_filenames >>>
define drop_contained_filenames <<< drop table contained_filenames >>>
define drop_missing_metadata_filenames 
       <<< drop table missing_metadata_filenames >>>
define drop_storage_dests <<< drop table storage_dests >>>
define drop_sl <<< drop table sl >>>
define drop_sl_sizing <<< drop table sl_sizing >>>
define drop_rs_locks_table_type <<< drop type rai_locks_table_type >>>
define drop_rs_locks_type <<< drop type rai_locks_type >>>
define drop_rs_jobs_table_type <<< drop type rai_jobs_table_type >>>
define drop_rs_jobs_type <<< drop type rai_jobs_type >>>
define drop_timer_task <<< drop table timer_task >>>
define drop_avm_pending_jobs <<< drop table rai_pending_jobs >>>
 
define drop_bp_i_lib_key <<< drop index bp_i_lib_key >>>
define drop_bp_i_template_key <<< drop index bp_i_template_key >>>
 
define drop_host <<< drop table host >>>
 
 
define drop_am_catalog_select 
   <<< drop role ra_catalog_select >>>
define drop_internal_purge_queue
   <<< drop view rai_purge_queue >>>
define drop_internal_sbt_performance
   <<< drop view rai_sbt_performance >>>
define drop_internal_recovery_window_space
   <<< drop view rai_recovery_window_space >>>
define drop_rai_oldest_backup
   <<< drop view rai_oldest_backup >>>
define drop_rai_recwingoal_scn
   <<< drop view rai_recwingoal_scn >>>
define drop_rai_maxrecwin_stamp
   <<< drop view rai_maxrecwin_stamp >>>
define drop_rai_unprotected_window
   <<< drop view rai_unprotected_window >>>
define drop_rs_server
   <<< drop view ra_server >>>
define drop_rs_storage_location
   <<< drop view ra_storage_location >>>
define drop_rs_storage_histogram
   <<< drop view ra_storage_histogram >>>
define drop_rs_purging_queue
   <<< drop view ra_purging_queue >>>
define drop_rs_polling_policy
   <<< drop view ra_polling_policy >>>
define drop_rs_db_access
   <<< drop view ra_db_access >>>
define drop_rs_database_synonym
   <<< drop view ra_database_synonym >>>
define drop_rs_protection_policy
   <<< drop view ra_protection_policy >>>
define drop_rs_database
   <<< drop view ra_database >>>
define drop_rs_database_storage_usage
   <<< drop view ra_database_storage_usage >>>
define drop_rs_task
   <<< drop view ra_task >>>
define drop_rs_time_usage
   <<< drop view ra_time_usage >>>
define drop_rs_restore_range_i
   <<< drop view rai_restore_range >>>
define drop_rs_disk_restore_range_i
   <<< drop view rai_disk_restore_range >>>
define drop_rs_sbt_restore_range_i
   <<< drop view rai_sbt_restore_range >>>
define drop_rs_restore_range
   <<< drop view ra_restore_range >>>
define drop_rs_disk_restore_range
   <<< drop view ra_disk_restore_range >>>
define drop_rs_sbt_restore_range
   <<< drop view ra_sbt_restore_range >>>
define drop_rs_sbt_library
   <<< drop view ra_sbt_library >>>
define drop_rs_sbt_attr_set
   <<< drop view ba_sbt_attr_set >>>
define drop_rs_sbt_job
   <<< drop view ra_sbt_job >>>
define drop_rs_sbt_task
   <<< drop view ra_sbt_task >>>
define drop_rs_sbt_attribute_set
   <<< drop view ra_sbt_attribute_set >>>
define drop_rs_config
   <<< drop view ra_config >>>
define drop_rs_api_history
   <<< drop view ra_api_history >>>
define drop_rs_replication_server
   <<< drop view ra_replication_server >>>
define drop_rs_incident_log
   <<< drop view ra_incident_log >>>
define drop_rs_incoming_backup_pieces
   <<< drop view ra_incoming_backup_pieces >>>
define drop_am_host 
   <<< drop view rai_host >>>
define drop_avm_em_sbt_job
   <<< drop view ra_em_sbt_job_template >>>
 
 
define create_rs_sq
<<<
CREATE SEQUENCE rai_sq MAXVALUE 18446744073709551615 CACHE 500
>>>
 
define create_rs_recid 
<<< create sequence rai_recid start with 100000 maxvalue 4294967296 cycle >>>
 
define create_sl
<<<
create table sl                           -- Storage Location
(
sl_key            number,                 -- primary key
sl_name           varchar2(128) not null, -- storage location name
sl_type           number        not null, -- storage location type, one of:
--
--
--
sl_cg_name        varchar2(4000),          -- name of container group (if any)
sl_space          number         not null, -- size of storage location in bytes
sl_hist_usage     number,                  -- recent allocations for this SL
--
sl_curr_hist_slot number,                  -- last storage histogram slot
sl_freespace_goal number,                  -- freespace goal in bytes
sl_last_check_files timestamp with time zone,
--
--
sl_min_alloc      number,                  -- allocation granule (au size)
sl_needs_repair   number default null,     -- storage location needs to be
--
sl_state          varchar2(1),             -- repair state:
--
--
--
--
--
constraint sl_p primary key (sl_key),
constraint sl_u unique      (sl_name),
constraint sl_alloc check ((bitand(sl_min_alloc,sl_min_alloc-1) = 0) and
                           (sl_min_alloc >= 2*1024)),
constraint sl_state check (sl_state IN ('F', 'E', 'I'))
) &tablespace&
>>>
 
define create_storage_dests
<<<
create table storage_dests
(
sl_key          number,                 -- storage location
dest            varchar2(4000) not null,-- disk group name or directory path
needsize        number default 0 not null,
--
--
cursize         number default 0 not null,
--
usersize        number default null,    -- user's requested storage dest size
--
constraint      storage_dests_unique unique (sl_key, dest),
constraint      storage_dests_f1 foreign key (sl_key) references sl
   on delete cascade,
constraint      storage_dests_needsize check (needsize >= 0),
constraint      storage_dests_cursize  check (cursize >= 0)
) &tablespace&
>>>
 
define create_sl_sizing
<<<
create table sl_sizing
(
disk_group      varchar2(128) not null, -- name of disk group
init_ok         varchar2(1) not null,   -- 'Y' => ok for sl allocation
sl_space        number not null,        -- maximum space that can be used for
--
--
constraint      sl_sizing_init check (init_ok IN ('Y', 'N'))
) &tablespace&
>>>
 
define create_poll
<<<
create table poll                       -- Polling Policies
(
poll_key        number,                 -- primary key
poll_name       varchar2(128),          -- polling policy name
sl_key          number not null,        -- storage location to poll
poll_flags      number,                 -- actions for polling code
poll_freq       interval day(9) to second, -- how often to poll
poll_last_prune timestamp with time zone,  -- time polling history last cleaned
constraint poll_p primary key (poll_key),
constraint poll_u unique      (poll_name),
constraint poll_f foreign key (sl_key) references sl
) &tablespace&
>>>
 
define create_prot
<<<
create table prot                                 -- Protection Policy
(
prot_key                 number,                  -- primary key
prot_name                varchar2(128) not null,  -- policy name
prot_description         varchar2(128),           -- description of policy
sl_key                   number        not null,  -- default storage location
poll_key                 number,                  -- polling area to be used
prot_recovery_window_goal interval day(9) to second,
--
--
--
--
prot_max_retention_window interval day(9) to second,
--
--
prot_recovery_window_sbt interval day(9) to second,-- how far back from now
--
--
prot_out_compression    varchar2(99),    -- how to compress VB during a restore
--
prot_disk_cache         varchar2(3),            -- sl acting as cache for disk
prot_unprotected_window interval day(9) to second,-- Recovery beyond this point
--
--
constraint prot_p primary key (prot_key),
constraint prot_u unique      (prot_name),
constraint prot_f foreign key (sl_key) references sl,
constraint prot_p2 foreign key (poll_key) references poll,
constraint prot_cache check (prot_disk_cache = 'YES' or prot_disk_cache = 'NO')
) &tablespace&
>>>
 
 
define create_odb
<<<
create table odb                      -- Oracle Data Base
(
db_key               number,          -- primary key
bs2_timestamp        timestamp with time zone,
--
--
purge_session        number,          -- session id of current purger
purge_instance       number,          -- instance id of current purger
prot_key             number not null, -- protection policy
future_prot_key      number not null, -- same as prot_key or future prot.
purge_scn            number,          -- Most recent SCN used to purge db
purge_inc            number,          -- Most recent DBINC_KEY used to purge db
sls_used             number,          -- Number of sls with storage for this db
total_allocation     number,          -- Sum of allocations across all sl's
not_taped            number default 0 not null, -- space not written to sbt
not_taped_state      varchar2(1),     -- Valid/Invalid/No tape/NULL
wait_space           number,          -- null, unless waiting for cache space
reserved_space       number not null, -- current reserved space, in bytes
base_reserved_space  number not null, -- admin assigned reserved space in bytes
recovery_window_goal  interval day(9) to second,   -- how far back from now the
--
--
--
move_phase           number,          -- If not null, phase of move db
--
sl_key               number,          -- storage location for new allocations
sl_min_alloc         number,          -- allocation granule for sl_key
allocated_space      number,          -- space allocated to sl_key for this odb
used_space           number,          -- space in use in sl_key by this odb
cumulative_usage     number,          -- cum. space used by foreground activity
cumulative_rep_usage number,          -- bytes sent to replication server
cumulative_sbt_usage number,          -- bytes sent to tape
create_time          timestamp with time zone, -- when odb row was created
last_optimize        timestamp with time zone, -- last time optimize was begun
prev_optimize        timestamp with time zone, -- previous optimize start
last_validate        timestamp with time zone, -- last time validate was run
last_crosscheck      timestamp with time zone, -- last time x-check was run
last_replication     timestamp with time zone, 
--
next_reconcile       timestamp with time zone, -- next scheduled reconcile time
last_reconcile       timestamp with time zone, -- last time of reconcile
platform_id          number,          -- platform id of protected database
platform_name        varchar2(101),   -- platform name of protected database
same_endian  varchar2(1) default 'U',  -- 'Y' => YES, 'N' => NO, 'U' => Unknown
db_state             number default null, -- odb state:
--
pending_rep_setup    varchar2(1) default NULL,-- 'Y'- need to complete repsetup
--
--
--
--
--
constraint odb_p  primary key (db_key),
constraint odb_f2 foreign key (prot_key) references prot,
constraint odb_sl foreign key (sl_key)   references sl,
constraint odb_c1 check (used_space >= 0),
constraint odb_c2 check (allocated_space >= used_space),
constraint odb_c3 check (total_allocation >= allocated_space),
constraint odb_c4 check (db_state is null or db_state = 1)
) &tablespace&
>>>
 
define add_constraint_odb_f1
<<<
   alter table odb add constraint odb_f1
      foreign key (db_key) references db on delete cascade
>>>
 
define create_odb_stats_cache
<<<
create table odb_stats_cache           -- Cache for ra_database statistics
(
db_key               number,          -- primary key
footprint            number,          -- size of a full backup
recovery_window_start date,           -- time for first available full backup
db_size              number,          -- size of the full database
deduplication_factor number,          -- deduplication factor for db
minimum_recovery_start date,          -- time for latest available full backup
bdf1count            number,          -- number of backups for file #1
unprotected          number,          -- number of days in unprotected window
nzdl_active          varchar2(3),     -- is dataguard shipping redo?
last_refresh         timestamp with time zone,
--
--
constraint odb_stats_p  primary key (db_key)
) &tablespace&
>>>
 
define create_prvlg
<<<
create table prvlg                      -- Privilege
(
type      number       not null,        -- type of access granted
db_key    number               ,        -- database to which privilege applies
user_id   number       not null,        -- userid to whom privilege issued
db_unique_name varchar2(32)    ,        -- db_unique_name if db_key is null
constraint prvlg_u  unique      (db_key, user_id, db_unique_name),
constraint prvlg_f1 foreign key (db_key) references odb on delete cascade,
constraint prvlg_c1 CHECK ((db_key is null and db_unique_name is not null) or
                           (db_key is not null and db_unique_name is null))
) &tablespace&
>>>
 
define create_prvlg_i1
<<<
create index prvlg_i1 on prvlg(user_id, db_key, type) compress 1 
&tablespace&
>>>
 
define create_prvlg_i2
<<<
create index prvlg_i2 on prvlg(user_id, db_unique_name, type) compress 2
&tablespace&
>>>
 
define create_orsownerfn
<<<
create or replace function dbms_rai_owner return varchar2 is
begin
   return sys.rai_schema(TRUE);
end;
>>>
 
define create_orsverifierfn
<<<
create or replace function dbms_rai_verifier return varchar2 is
   u varchar2(512);
begin
   select sys.kbrsi_icd.getVerifier into u from dual
    where exists (select 1 from prvlg p where p.user_id = uid);
   return u;
exception
   when no_data_found then
      return null;
end;
>>>
 
define create_am_inst_addresses
<<<
create or replace function dbms_rai_inst_addresses(
   client      in varchar2       default 'BACKUP',
   level       in number         default 0,
   gethost     in binary_integer default 0)
   return sys.odcivarchar2list pipelined as
   ip       sys.odcivarchar2list;
   found    boolean := FALSE;
   hostname varchar2(1024);
   cursor hostlst_c(hostlst in varchar2, level in number) is
     with table_to_parse as
        (select hostlst str from dual),
          myhost as
        (select upper(ltrim(rtrim(new_str))) ip_address, rownum id
           from table_to_parse,
                xmltable('r/c' passing xmltype('<r><c>' ||
                replace(str,',','</c><c>') || '</c></r>')
                columns new_str varchar2(512) path '.'))
        select ip_address from myhost
         where (id = level or level = 0);
begin
   for r in (select case when client = 'ADMIN' then
                            admin_ip_address
                         when client = 'BACKUP' then
                            backup_ip_address
                         when client = 'REPLICATION' then
                            nvl(replication_ip_address, backup_ip_address)
                    end ip_address
               from rai_host) loop
      for hostRec in hostlst_c(r.ip_address, level) loop
         hostname := hostRec.ip_address;
         if (gethost > 0) then
            hostname := sys.rai_host_name(hostname);
         end if;
         pipe row(hostname);
         found := TRUE;
      end loop;
   end loop;
 
   if (not found and level <= 1) then
      ip := sys.rai_inst_addresses;
      for i in 1..ip.count loop
         hostname := ip(1);
         if (gethost > 0) then
            hostname := sys.rai_host_name(hostname);
         end if;
         pipe row(hostname);
      end loop;
   end if;
end;
>>>
 
define create_am_sbt_parms
<<<
create or replace procedure dbms_rai_sbt_parms(
   nossl      IN  binary_integer,
   verifier   OUT varchar2,
   ssl        OUT binary_integer,
   port       OUT number,
   chunk_size OUT number,
   dbname     OUT varchar2,
   hostname   OUT varchar2) is
   ip       sys.odcivarchar2list;
   hostlst  host.backup_ip_address%type;
   cursor hostlst_c(hostlst in varchar2, level in number) is
     with table_to_parse as
        (select hostlst str from dual),
          myhost as
        (select upper(ltrim(rtrim(new_str))) ip_address, rownum id
           from table_to_parse,
                xmltable('r/c' passing xmltype('<r><c>' ||
                replace(str,',','</c><c>') || '</c></r>')
                columns new_str varchar2(512) path '.'))
        select ip_address from myhost
         where (id = level or level = 0);
begin
   port := 0;
 
   if (nossl <= 0) then
      ssl  := 1;
      port := dbms_xdb_config.gethttpsport;
   end if;
 
   if (port is null or port = 0) then
      ssl  := 0;
      port := dbms_xdb_config.gethttpport;
   end if;
 
   verifier := dbms_rai_verifier;
 
   select nvl(max(to_number(value)), 0)
     into chunk_size
     from config
    where name = 'network_chunksize';
 
   dbname   := upper(sys_context('USERENV', 'DB_NAME'));
 
   hostname := null;
--
   for i in (select 1 from rai_host where rownum = 1) loop
      select backup_ip_address ip_address
        into hostlst
        from rai_host h, v$instance i
       where h.node_name = i.host_name;
      for hostRec in hostlst_c(hostlst, 1) loop
         hostname := hostRec.ip_address;
      end loop;
   end loop;
 
   if (hostname is null) then 
      ip := sys.rai_inst_addresses;
      hostname := ip(1);
   end if;
 
   hostname := sys.rai_host_name(hostname);
end;
>>>
 
define create_am_url
<<<
create or replace procedure dbms_rai_url(
   client    IN  varchar2,
   level     IN  number,
   url       OUT varchar2,
   hostname  OUT varchar2,
   port      OUT number) is
   chunk_size number;
   ssl        binary_integer;
   ip         sys.odcivarchar2list;
   sslstring  varchar2(1);
   hostlst    host.backup_ip_address%type;
   cursor hostlst_c(hostlst in varchar2, level in number) is
     with table_to_parse as
        (select hostlst str from dual),
          myhost as
        (select upper(ltrim(rtrim(new_str))) ip_address, rownum id
           from table_to_parse,
                xmltable('r/c' passing xmltype('<r><c>' ||
                replace(str,',','</c><c>') || '</c></r>')
                columns new_str varchar2(512) path '.'))
        select ip_address from myhost
         where (level = 0 or id = level);
begin
   ssl  := 1;
   port := dbms_xdb_config.gethttpsport;
 
   if (port is null or port = 0) then
      ssl  := 0;
      port := dbms_xdb_config.gethttpport;
   end if;
 
   hostname := null;
--
   for i in (select 1 from rai_host where rownum = 1) loop
      select case when client = 'ADMIN' then
                     admin_ip_address
                  when client = 'BACKUP' then
                     backup_ip_address
                  when client = 'REPLICATION' then
                     nvl(replication_ip_address, backup_ip_address)
              end ip_address
        into hostlst
        from rai_host h, v$instance i
       where h.node_name = i.host_name;
 
      for hostRec in hostlst_c(hostlst, level) loop
         hostname := hostRec.ip_address;
      end loop;
   end loop;
 
   if (hostname is null and level = 1) then
      ip := sys.rai_inst_addresses;
      hostname := ip(1);
   end if;
 
   if (hostname is null) then
      raise no_data_found;
   end if;
 
   hostname := sys.rai_host_name(hostname);
   if (ssl > 0) then
      sslstring := 's';
   end if;
 
   url := 'http' || sslstring || '://' || hostname || ':' || port;
end;
>>>
 
define create_am_wallet2url
<<<
create or replace procedure dbms_rai_wallet2url(
   wallet_loc IN  varchar2,
   cred_alias IN  varchar2,
   username   OUT varchar2,
   password   OUT varchar2,
   url        OUT varchar2,
   client     IN  varchar2) is
begin
   sys.kbrsi_icd.wallet2url(
      wallet_loc, cred_alias, username, password, url, client);
end;
>>>
 
define create_avm_throttle_alloc
<<<
create or replace procedure dbms_rai_throttle_alloc(
   ba_job_id      IN  varchar2,
   db_unique_name  IN  varchar2,
   channels_reqd   IN  number,
   request_time    IN  date,
   wait            OUT integer,
   error_str       OUT varchar2) is
   l_wait  boolean;
begin
   dbms_ra_int.throttle_me_int(ba_job_id,db_unique_name,
      channels_reqd,request_time,l_wait,error_str);
 
   IF (l_wait) THEN
      wait := 1;
   ELSE
      wait := 0;
   END IF;
 
end;
>>>
 
define create_ba_resync_clear_error
<<<
create or replace procedure dbms_rai_fix_error(
      error_num IN number) is
begin
 
    dbms_ra_scheduler.fix_error(
         p_error_num => error_num,
         p_db_key    => dbms_rcvman.getDbKey);
 
end;
>>>   
 
define populate_rsr_key
<<<
create or replace procedure dbms_rai_populate_rsr_key(
        bp_key   IN number,
        bs_key   IN number) IS
begin
    dbms_ra_int.populate_rsr_key(bp_key, bs_key);
end;
>>>
 
define create_unreg_database
<<<
create table unreg_database
(
db_unique_name varchar2(32),
sl_key         number,
prot_key       number,
reserved_space number,
constraint unreg_database_p  primary key (db_unique_name),
constraint unreg_database_f1 foreign key (sl_key) references sl,
constraint unreg_database_f2 foreign key (prot_key) references prot
) &tablespace&
>>>
 
define create_unreg_database_trigger
<<<
create or replace trigger unreg_database_trigger before insert or update
   on unreg_database for each row
declare
   cnt number;
begin
   select count(*) into cnt from node
      where db_unique_name = upper(:new.db_unique_name);
   if (cnt > 0) then
      raise dup_val_on_index;
   end if;
end;
>>>
 
define add_constraint_node_u2
<<< alter table node add constraint node_u2 unique(db_unique_name) 
    using index
    (create unique index node_u2 on node(db_unique_name) &tablespace&) 
>>>
 
define drop_constraint_node_u1
<<< alter table node drop constraint node_u1 drop index >>>
 
define create_node_insert_update
<<<
create or replace trigger node_insert_update before insert or update on node
   for each row
declare
   db_uname varchar2(32);
   l_db_id  number;
   l_cnt    number;
   cursor unreg_db(db_uname in varchar2) is 
      select prot_key, reserved_space from unreg_database
      where db_unique_name = upper(unreg_db.db_uname) for update;
   cnt number;
begin
  if (UPDATING AND
      NVL(:old.db_unique_name, '@') = NVL(:new.db_unique_name, '@')) THEN
    return;
  end if;
  if substr(:new.db_unique_name, 1,1) = '$' then
     db_uname := substr(:new.db_unique_name, 2,
                        instr(substr(:new.db_unique_name, 2, 32), '$') - 1);
  else
     db_uname := :new.db_unique_name;
  end if;
 
--
--
  for rec in unreg_db(db_uname) loop
    insert into odb (db_key, sls_used, total_allocation,sl_key,
                     sl_min_alloc,allocated_space, used_space, 
                     cumulative_usage, 
                     cumulative_rep_usage, cumulative_sbt_usage,
                     create_time,
                     last_optimize, last_validate, last_crosscheck,
                     prot_key, future_prot_key, pending_rep_setup,
                     reserved_space, base_reserved_space,
                     recovery_window_goal, not_taped, not_taped_state)
         (select :new.db_key, 1, 0, sl.sl_key, sl.sl_min_alloc,
                 0, 0, 0, 0, 0,
                 SYSTIMESTAMP,
                 SYSTIMESTAMP, SYSTIMESTAMP, SYSTIMESTAMP,
                 prot.prot_key, prot.prot_key, NULL,
                 rec.reserved_space, rec.reserved_space,
                 prot.prot_recovery_window_goal, 1,
                 decode(prot.prot_disk_cache, 'YES', 'I', null)
          from prot, sl
          where prot_key = rec.prot_key
            and prot.sl_key = sl.sl_key);
 
--
--
--
--
    select count (*) into l_cnt from rep_server, odb
      where odb.db_key= :new.db_key
        and odb.prot_key=rep_server.prot_key;
    if l_cnt > 0 then
      update odb set pending_rep_setup='Y'
        where db_key = :new.db_key;
    end if;
 
    update prvlg set db_key = :new.db_key,
                     db_unique_name = null
      where db_unique_name = upper(db_uname);
 
--
--
    select db_id into l_db_id from db where db_key=:new.db_key;
    select count(*) into l_cnt from vpc_databases 
       where db_id = l_db_id and reg_db_unique_name is null;
    if l_cnt = 0 then
       update vpc_databases set db_id=l_db_id, 
                                reg_db_unique_name=null 
         where reg_db_unique_name=:new.db_unique_name
           and db_id = 0;
    else
       delete vpc_databases
         where reg_db_unique_name=:new.db_unique_name
           and db_id = 0;
    end if;
 
    delete unreg_database where current of unreg_db;
 
    update db set storage_prov = 'Y' 
       where db_key = :new.db_key;
  end loop;
--
 
   select count(*) into cnt from unreg_database
      where db_unique_name = upper(:new.db_unique_name);
   if (cnt > 0) then
      raise dup_val_on_index;
   end if;
end;
>>>
 
define create_dbsl
<<<
create table dbsl                      -- Storage usage for db in sl's
--
(
db_key               number not null,  -- from db table
sl_key               number not null,  -- from sl table
dbsl_used_space      number not null,  -- space used in this sl for db
constraint dbsl_p    primary key (db_key, sl_key),
constraint dbsl_f1   foreign key (db_key) references db,
constraint dbsl_sl   foreign key (sl_key) references sl
) &tablespace&
>>>
 
define create_chunks
<<<
create table chunks        -- master chunk table
(
df_key    number,          -- datafile key
chunkno   number,          -- chunk number
sl_key    number not null, -- storage location key
dbinc_key number not null, -- database incarnation key
clean_key number,          -- Key to recover not-resumable operation
filesize  number not null, -- size of the chunk in bytes
filename  varchar2(512),   -- OMF name for the chunk
constraint chunks_u     primary key (df_key, chunkno),
constraint chunks_dbinc foreign key (dbinc_key)         references dbinc,
constraint chunks_sl    foreign key (sl_key)            references sl
--
--
) organization index
  compress 1
  initrans 2
  pctfree 20
  including filesize overflow 
  &tablespace&
  partition by hash (df_key) partitions 1024
  &tablespace&
>>>
 
define create_df_seq
<<<
create table df_seq                    -- Sequence numbers for chunks.chunkno
(
df_key               number,           -- from df table
chunkno              number not null,  -- next available chunk number for df
constraint df_seq_p  primary key (df_key) using index (
  create unique index df_seq_p on df_seq(df_key)
  local)
) partition by hash (df_key) partitions 16
  &tablespace&
>>>
 
define create_blocks
<<<
create table blocks        -- Master block table
(
dbinc_key number not null, -- Database incarnation
df_key    number not null, -- Data file key
blockno   number not null, -- Data block number
ckp_id    number not null, -- Backup ckp_scn (we add 1 for each read only)
scn       number not null, -- Data block SCN.
chunkno   number not null, -- Chunk number
used      number not null, -- size includes chunk block kcbh and tail if needed
coffset   number not null  -- chunk offset in bytes
)
  pctfree 2
  partition by hash (df_key) partitions 1024
  &tablespace&
>>>
 
define add_index_blocks_u
<<<
create unique index blocks_u
on blocks (df_key, blockno, scn DESC, ckp_id DESC, chunkno DESC,
           coffset, used, dbinc_key)
local compress 2
&tablespace&
>>>
 
define add_index_blocks_c
<<<
create index blocks_c
on blocks (df_key, chunkno, blockno)
local compress 2
&tablespace&
>>>
 
 
define create_vbdf
<<<
create table vbdf
(
vb_key        number not null,  -- Virtual Backup ID
df_key        number not null,  -- Datafile key
db_key        number not null,  -- Database Key
pdbinc_key    number,           -- Pluggable Database Incarnation Key
dbinc_key     number not null,  -- Database Incarnation Key
incr_scn      number,           -- Incremental start SCN
ckp_scn       number not null,  -- Checkpoint SCN
abs_scn       number,           -- Absolute fuzzy SCN
ckp_id        number not null,  -- Backup ckp_scn (we add 1 for each read only)
unorder_id    number,           -- max(ckp_id) for last "unordered" block
min_id        number,           -- Latest level 0 ckp_id
file#         number not null,  -- Data file number
blocks        number not null,  -- Data file size in blocks
firstblk      number not null,  -- First block in a multi-section piece
lastblk       number not null,  -- Last block in a multi-section piece
cmpvsn        number,           -- Version  (ph->kccfh_krbph.kccfhcvn)
relfno        number,           -- Backup relative file#
state         number not null,  -- See VBDF_* constants in DBMS_RA_INT package
krbph_dfkey   number,           -- DF_KEY to which the krbph is assigned.
krbph_chunkno number,           -- Chunk# to find krbph, null if not current
new_krbph     number,           -- krbph chunk# when being moved
dfbytes       number,           -- Estimate size of the datafile (if restore)
dfblocks      number,           -- Not size (# of logical blocks)
signature     number,           -- Numeric signature for virtual backup
srcbp_key     number,           -- Source bp_key
vcbp_key      number,           -- Virtual Copy bp_key
corrupt       varchar2(1),      -- Y if corruption in this df, null if not
chunks_used   number,           -- Chunks freed when virtual backup is deleted
constraint vbdf_u     primary key (vb_key, df_key),
constraint vbdf_u2    unique      (dbinc_key, df_key, ckp_id),
constraint vbdf_u3    unique      (df_key, ckp_scn, vb_key),
constraint vbdf_key   check       (vb_key > 0 and   -- UB8MAXVAL
                                   vb_key < 18446744073709551615),
constraint vbdf_min   check       (min_id <= ckp_id),
constraint vbdf_dbinc foreign key (dbinc_key)         references dbinc,
constraint vbdf_db    foreign key (db_key)            references db
--
--
--
--
) &tablespace&
>>>
 
define create_bp_i_vbkey
<<< create index bp_i_vbkey on bp (vb_key) &tablespace& >>>
 
define create_plans
<<<
create table plans
(
type      number not null, -- Type of plan
db_key    number not null, -- Database Key
vb_key    number not null, -- Virtual Backup Key
df_key    number not null, -- Datafile key
task_id   number,          -- Optional task_id for temp plans
old       number,          -- For plans ready to be deleted
blksread  number,          -- Total number of blocks to read
maxrank   number,          -- For purge, duplicate blockno have rankings
numchunks number,          -- count of distinct chunks in plan
readsize  number,          -- computation of buffer size to use for read
needchunk number,          -- Number of chunks needed to purge this vb_key
freechunk number,          -- Number of chunks freed by purging this vb
constraint plans_u  primary key (df_key, type, vb_key),
constraint plans_db foreign key (db_key) references db
) &tablespace&
>>>
 
define create_plans_det
<<<
create table plans_details
(
df_key        number, -- Datafile key
type          number, -- Type of plan
vb_key        number, -- Virtual Backup ID
blkrank       number, -- block ranking (used in purge)
blockno       number, -- block number
chunkno       number, -- chunk number
numblks       number, -- number of logical blocks to copy
coffset       number, -- offset in chunk
numbytes      number, -- number of bytes to copy
signature     number, -- (opt) sum of all the datafile block scn values
constraint plans_det_u  primary key (df_key, type, vb_key,
                                     blkrank, blockno, chunkno)
) organization index
  compress 4
  initrans 2
  pctfree 2
  partition by hash (df_key) partitions 1024
  &tablespace&
>>>
 
 
define create_sbt_catalog
<<<
create table sbt_catalog               -- Files received by SBT
(
ct_key     number,
db_key     number         not null,
cretime    timestamp with time zone not null,
handle     varchar2(1024) not null,
pieceinc   varchar2(32)   not null,
endupload  varchar2(1),   -- 'Y', 'N', 'D' for file chunks. Otherwise, NULL.
bp_key     number,
ftype      varchar2(1)    not null, -- 'F'(file piece), 'T'(tape piece),
--
--
xmldoc     sys.xmltype,
--
sl_key          number,
sl_min_alloc    number,
filename        varchar2(1024),
filesize        number,
last_entry      timestamp with time zone,
completed       varchar2(1),    -- Y or N (storage complete)
--
constraint sbt_catalog_p  primary key (ct_key),
constraint sbt_catalog_u1 unique (handle, pieceinc),
constraint sbt_catalog_u2 unique (bp_key),
constraint sbt_catalog_c1 check
   ((endupload in ('Y', 'N', 'D') and endupload is not null and ftype  = 'F')
    or
    (endupload is null and ftype != 'F')),
constraint sbt_catalog_c2 check (ftype in ('F', 'T', 'D', 'V')),
constraint sbt_catalog_c3 check (ftype = 'F' or filesize is null),
constraint sbt_catalog_c4 check
   ((completed in ('Y', 'N') and completed is not null and ftype  = 'F') or
    (completed is null       and ftype != 'F')),
constraint sbt_catalog_c5 check
   ((ftype = 'F') or (filesize is null and ftype != 'F')),
constraint sbt_catalog_c6 check
   ((nvl(completed, 'Y') = 'Y' and nvl(endupload, 'Y') = 'Y' and
     bp_key is not null        and xmldoc is not null)            or
    (bp_key is null)),
constraint sbt_catalog_f1 foreign key (db_key) references db,
constraint sbt_catalog_f2 foreign key (bp_key) references bp
   on delete cascade deferrable initially deferred
) &tablespace& 
xmltype xmldoc store as clob 
>>>
 
define create_bp_foreign_ct_key
<<<
alter table bp add constraint bp_foreign_ct_key foreign key (ct_key)
   references sbt_catalog deferrable initially deferred
>>>
 
define create_sbt_catalog_i_1
<<<
create unique index sbt_catalog_i_1 on sbt_catalog
(case when (nvl(completed, 'Y') = 'Y' or bp_key is not null or endupload = 'Y')
 then handle else null end) &tablespace&
>>>
 
define create_sbt_catalog_i_2
<<<
create unique index sbt_catalog_i_2 on sbt_catalog
(case when (filesize is not null) then filename else null end) &tablespace&
>>>
 
define create_sbt_catalog_i_3
<<<
create index sbt_catalog_i_3 on sbt_catalog(db_key, handle) &tablespace&
>>>
 
define create_update_sbt_catalog_pieceinc
<<<
create or replace trigger update_sbt_catalog_pieceinc
before update on sbt_catalog for each row
when (new.ct_key = old.ct_key and new.pieceinc != old.pieceinc)
begin
   with o as
      (select extractValue(:old.xmldoc, '//ChunkPrefix/text()') prefix
         from dual),
        n as
      (select regexp_replace(o.prefix, :old.pieceinc, :new.pieceinc,
                             instr(o.prefix, :old.pieceinc, -1 , 1)) prefix
         from o)
   select XMLQuery('copy $i := $p1 modify
                    ((for $j in $i//Incarnation
                      return replace value of node $j with $p2),
                     (for $j in $i//ChunkPrefix
                      return replace value of node $j with $p3))
                    return $i'
           passing :old.xmldoc AS "p1", :new.pieceinc AS "p2",
                    n.prefix AS "p3" RETURNING CONTENT)
     into :new.xmldoc
     from n;
end;
>>>
 
define create_chk_delete_sbt_catalog
<<<
create or replace trigger chk_delete_sbt_catalog
after delete on sbt_catalog for each row
when (old.filesize is not null)
begin
  sys.dbms_sys_error.raise_system_error(-45113 /*E_INTERNAL_ERROR_NUM*/,
                    'illegal sbt_catalog delete of bp_key ' || :old.bp_key);
end;
>>>
 
define create_new_df_check
<<<
create or replace trigger new_df_check
after insert on df for each row
begin
  dbms_ra_scheduler.newdfkey(:new.df_key,:new.dbinc_key,:new.pdbinc_key);
end;
>>>
 
define create_sbt_session
<<<
create table sbt_session
(
session_id  varchar2(64),
db_key      number        not null,
cretime     timestamp with time zone     not null,
modtime     timestamp with time zone     not null,
constraint sbt_session_p primary key (session_id),
constraint sbt_session_f1 foreign key (db_key)
   references db on delete cascade
) &tablespace&
>>>
 
 
define create_sessions
<<<
create table sessions
(
ba_session_id   number,
current_task    number,
current_task_type number,
spid            varchar2(128),
instance_id     number,
sid             number,
serial#         number,
audsid          number,
logon_time      date,
start_time      timestamp with time zone,
trace_file      varchar2(512),
last_task_start    timestamp with time zone,
last_config_change timestamp with time zone,
last_quiesce       timestamp with time zone,
last_busywork_stop timestamp with time zone, 
purpose         number,      -- task_type (special task process)
purpose_param1  number,      -- special task param1 (or max task_type)
purpose_param2  number,      -- special task param2
job_name        varchar2(128),
constraint sessions_p primary key (ba_session_id),
constraint sessions_u unique(current_task)
) &tablespace&
>>>
 
define create_task
<<<
create table task
(
task_id           number,
task_type         number,
priority          number,
flags             number,
db_key            number,
sl_key            number,
state             number,
pending_interrupt number,
interrupt_count   number,
savepoint         number,
param_num1        number,
param_num2        number,
param_num3        number,
param_char1       varchar2(1000),
param_char2       varchar2(1000),
param             varchar2(4000),
ba_session_id     number,
execute_inst_id   number,
schedule_time     timestamp with time zone,
execute_time      timestamp with time zone,
last_execute_time timestamp with time zone,
completion_time   timestamp with time zone,
last_interrupt_time timestamp with time zone,
error_count       number,
purge_reserve     number,
elapsed_time      interval day(9) to second(6),
com_time          timestamp with time zone,
sbt_task_id       number,
creator_task_id   number,
creator_sid       number,
creator_instance  number,
constraint task_p primary key (task_id),
constraint task_c1 check (nvl(purge_reserve,0) >= 0),
                                                         /*TASK_SESSION_TIMES*/
constraint task_c2 check (flags is not null or task_type >= 2000),
constraint task_c3 check (nvl(flags,0) between 0 and to_number('007f','xxxx'))
) &tablespace&
>>>
 
define create_task_i1
<<< create index task_i1 on task(task_type, param_num1) &tablespace& >>>
 
define create_task_i2
<<< create index task_i2 on task(priority, state, task_id, task_type, execute_inst_id, sbt_task_id, pending_interrupt) &tablespace& >>>
 
define create_task_i3
<<< create index task_i3 on task(state, db_key)  &tablespace&>>>
 
define create_task_i4
<<< create index task_i4 on task(pending_interrupt)  &tablespace&>>>
 
define create_task_i5
<<< create index task_i5 on task(sbt_task_id) &tablespace&>>>
 
define create_task_spawn_sbt_i
<<< create unique index task_spawn_sbt_i on task(
       case when task_type = 1 and state in (1, 2) then param_num1 end
      ,case when task_type = 1 and state in (1, 2) then param_num2 end)
    &tablespace&
>>>
 
define create_task_f1
<<<
   alter table task add constraint task_f1
      foreign key(sbt_task_id) references sbt_task
      on delete set null initially deferred deferrable
>>>
 
define drop_task_f1
<<< alter table task drop constraint task_f1 >>>
 
define create_task_history
<<<
create table task_history &tablespace& 
--
--
--
as select * from task where 1=0 
>>>
 
 
define create_task_chunk_cache
<<<
create table task_chunk_cache
(
inst_id           number,
task_id           number,
chunk_cache       number not null,
cumulative_incr   number not null,
constraint tcc_u1 primary key (task_id) using index (
  create unique index tcc_u1 on task_chunk_cache(task_id)
  global partition by hash (task_id) partitions 16),
constraint tcc_f1 foreign key (task_id) references task,
constraint tcc_c1 check (inst_id > 0)
)
partition by range(inst_id)
(
  partition p001 values less than(02)
, partition p002 values less than(03)
, partition p003 values less than(04)
, partition p004 values less than(05)
, partition p005 values less than(06)
, partition p006 values less than(07)
, partition p007 values less than(08)
, partition p008 values less than(09)
, partition p009 values less than(10)
, partition p010 values less than(11)
, partition p011 values less than(12)
, partition p012 values less than(13)
, partition p013 values less than(14)
, partition p014 values less than(15)
, partition p015 values less than(16)
, partition p016 values less than(17)
, partition p256 values less than(257)
)
&tablespace&
>>>
 
define create_tasktypenames
<<<
create table tasktypenames
(
task_type         number,
task_type_name    varchar2(30),
constraint ttn_u primary key (task_type)
) organization index
&tablespace&
>>>
 
define create_timer_task
<<<
create table timer_task
(
timer_type      number,
timer_location  number,
flags           number,
next_execute    timestamp with time zone,
timer_interval  interval day(9) to second(6),
param_num1      number,
constraint timer_task_p primary key (timer_type, timer_location)
) &tablespace&
>>>
 
define create_timer_task_t
<<< create index timer_task_t on timer_task (next_execute) &tablespace& >>>
 
define create_storage_histogram
<<<
create table storage_histogram
(
sl_key number,
slot   number,
usage  number,
constraint storage_histogram_p primary key (sl_key, slot),
constraint storage_histogram_f1 foreign key (sl_key) references sl
   on delete cascade
) &tablespace&
>>>
 
define create_error_log
<<<
create table error_log
(
incident#  number,
error_num  number,
sl_key     number,
db_key     number,
param_num  number,
param_char varchar2(1000),
task_id    number,
status     varchar2(6),
component  varchar2(30),
severity   number,
error_text varchar2(4000),
first_seen timestamp with time zone not null,
last_seen  timestamp with time zone not null,
seen_count number not null,
ospid      varchar2(24),
inst_id    number,
trace_file varchar2(512),
call_stack varchar2(4000),
final_call_stack varchar2(4000),
final_backtrace_stack varchar2(4000),
constraint error_log_u1 unique (error_num,sl_key,db_key,param_num,param_char),
constraint error_log_c1 check (status IN ('ACTIVE', 'FIXED', 'RESET')),
constraint error_log_f1 foreign key (sl_key) references sl
   on delete cascade,
constraint error_log_f2 foreign key (db_key) references odb
   on delete cascade
) &tablespace&
>>>
 
define create_error_log_i1
<<< create index error_log_i1 on error_log(status, severity) &tablespace& >>>
 
define create_polling_history
<<<
create table polling_history
(
poll_key  number,
fname     varchar2(512),
fsize     number,
status    varchar2(1),
fail_time timestamp with time zone,
--
constraint polling_history_c1
    check (status in ('P', 'C', 'D', 'F', 'E', 'T', 'R')),
constraint polling_history_f1 foreign key (poll_key) references poll
    on delete cascade
) &tablespace&
>>>
 
define create_polling_history_i1
<<<
create index polling_history_i1 on
 polling_history (poll_key, status, fname) &tablespace&
>>>
 
define create_metadata_filenames
<<<
create table metadata_filenames
(
sl_key    number,
fname     varchar2(512),
constraint mf_u primary key (sl_key, fname),
constraint mf_f1 foreign key (sl_key) references sl
   on delete cascade
) organization index compress &tablespace&
>>>
 
define create_contained_filenames
<<<
create table contained_filenames
(
sl_key    number,
fname     varchar2(512),
constraint contf_u primary key (sl_key, fname),
constraint contf_f1 foreign key (sl_key) references sl 
   on delete cascade
) organization index compress &tablespace&
>>>
 
define create_missing_metadata_filenames
<<<
create table missing_metadata_filenames
(
sl_key    number,
fname     varchar2(512),
entered   timestamp with time zone,
latest    timestamp with time zone,
constraint mmf_u primary key (sl_key, fname),
constraint mmf_f1 foreign key (sl_key) references sl
   on delete cascade
) organization index compress &tablespace&
>>>
 
define create_rs_jobs_type
<<<
create or replace type rai_jobs_type is object
(
job_name        varchar2(128),
instance_id     number,
comments        varchar2(240)
)
>>>
 
define create_rs_jobs_table_type
<<<
create or replace type rai_jobs_table_type is table of rai_jobs_type
>>>
 
define create_rs_locks_type
<<<
create or replace type rai_locks_type is object
(
inst_id         number,
ba_type        number,
key             number,
lmode           number,
ctime           number,
sid             number
)
>>>
 
define create_rs_locks_table_type
<<<
create or replace type rai_locks_table_type is table of rai_locks_type
>>>
 
 
define create_avm_pending_jobs
<<<
create table rai_pending_jobs
(
ba_job_id        varchar2(256),
request_time      date,
channels_reqd     number,
last_ping_time    date,
db_unique_name    varchar2(32),
approval_time     date,
constraint        rai_pending_jobs_p primary key(ba_job_id)
) organization index &tablespace&
>>>
 
define create_sbt_lib_desc
<<<
create table sbt_lib_desc
(
lib_key            number not null,             -- seq generated primary key
lib_name           varchar2(128) not null,      -- a unique library name
drives             number not null,             -- total # of tape drives
restore_drives     number default 0 not null,   -- drives reserved for restore
parms              varchar2(1024),              -- sbt parms
send               varchar2(1024),              -- sbt send command
server_key         number,                      -- Server key for rep server
--
status             varchar2(1),                 -- 'R' - Ready, 'P' - Pause
--
failure_cnt        number not null,             -- # of contiguous failure
dynamic_drives     varchar2(1) not null,        -- 'Y' - drives dynamically
--
constraint sbt_lib_desc_p  primary key (lib_key), -- primary key
constraint sbt_lib_desc_u  unique(lib_name),
constraint sbt_lib_desc_c1 check (drives > 0),
constraint sbt_lib_desc_c2 check (status in ('R', 'P', 'E')),
constraint sbt_lib_desc_c3 check (dynamic_drives in ('Y', 'N'))
) &tablespace&
>>>
 
define create_sbt_lib_inst_rlist
<<<
create table sbt_library_inst_rlist
(
lib_key            number not null,
instance_name      varchar2(16) not null,
constraint sbt_library_inst_rlist_u unique(lib_key, instance_name),
constraint sbt_library_inst_rlist_f foreign key(lib_key)
   references sbt_lib_desc on delete cascade
) &tablespace&
>>>
 
define drop_ba_drives_sbt_lib_desc
<<< alter table sbt_lib_desc drop column ba_drives >>>
 
define create_bp_foreign_lib_key
<<<
alter table bp add constraint bp_foreign_lib_key foreign key (lib_key)
   references sbt_lib_desc
>>>
 
define create_bp_foreign_template_key
<<<
alter table bp add constraint bp_foreign_template_key foreign key (template_key)
   references sbt_job_template
   on delete set null initially deferred deferrable
>>>
 
define create_bp_i_lib_key 
<<< create index bp_i_lib_key on bp (lib_key) &tablespace& >>>
 
define create_bp_i_template_key 
<<< create index bp_i_template_key on bp (template_key) &tablespace& >>>
 
define create_sbt_attr_set
<<<
create table sbt_attr_set
(
lib_key       number not null,       -- sbt_library to which this attr belongs
attr_key      number not null,       -- sequence generated primary key
attr_name     varchar2(128) not null,-- unique name describing the attribute
streams       number,                -- total # of streams used for this attr
poolid        number,                -- pool integer passed to sbt api
parms         varchar2(1024),        -- sbt parms; merged with sbt_library_conf
send          varchar2(1024),        -- merged with sbt_lib_desc
constraint  sbt_attr_set_p  primary key (attr_key), -- primary key
constraint  sbt_attr_set_u  unique  (attr_name),
constraint  sbt_attr_set_f  foreign key (lib_key) references sbt_lib_desc
  on delete cascade,
constraint  sbt_attr_set_c1 check (streams is null or streams > 0)
) &tablespace&
>>>
 
define create_sbt_job_template
<<<
create table sbt_job_template
(
template_key       number,                    -- primary key
template_name      varchar2(128) not null,    -- template name
full_template_key  number,                    -- full template key
prot_key           number,                    -- protection policy key
db_key             number,                    -- database key
bck_type           number not null,           -- 1       -> all backup
--
--
--
from_tag           varchar2(32),              -- tag to filter the source
priority           number default 100,        -- priority of db to do sbt backup
attr_key           number,                    -- sbt attribute key
copies             number default 1 not null, -- # of duplex copies
schedule_time      timestamp with time zone,  -- job scheduled at this timestamp
window             interval day to second,    -- window interval for the job
completion_time    timestamp with time zone,  -- end time of job
constraint sbt_job_template_p  primary key (template_key),
constraint sbt_job_template_u1 unique (template_name),
constraint sbt_job_template_u2 unique (template_key, attr_key),
constraint sbt_job_template_u3 unique (template_key, full_template_key),
constraint sbt_job_template_f1 foreign key (attr_key)
   references sbt_attr_set on delete cascade,
constraint sbt_job_template_f2 foreign key (prot_key)
   references prot on delete cascade,
constraint sbt_job_template_f3 foreign key (db_key)
   references odb on delete cascade,
constraint sbt_job_template_f4 foreign key (full_template_key)
   references sbt_job_template(template_key),
constraint sbt_job_template_c1 check
   (bck_type in (1,2,4,6,8,10,12,14,32)),
constraint sbt_job_template_c2 check (copies between 1 and 4)
) &tablespace&
>>>
 
define create_sbt_job_template_i1
<<< 
create index sbt_job_template_i1 on sbt_job_template(completion_time) 
&tablespace&
>>>
 
define create_sbt_job_template_i2
<<<
create index sbt_job_template_i2 on sbt_job_template(full_template_key)
&tablespace&
>>>
 
define create_sbt_job_template_i3
<<<
create index sbt_job_template_i3 on sbt_job_template(db_key)
&tablespace&
>>>
 
define create_sbt_template_db_i1
<<<
create index sbt_template_db_i1 on sbt_template_db(template_key)
&tablespace&
>>>
 
define create_sbt_template_db_f1
<<<
alter table sbt_template_db add
constraint sbt_template_db_f1 foreign key (db_key)
   references odb on delete cascade
>>>
 
define create_sbt_template_db_f2
<<<
alter table sbt_template_db add
constraint sbt_template_db_f2 foreign key (template_key)
   references sbt_job_template on delete cascade
>>>
 
define create_sbt_template_df
<<<
create table sbt_template_df
(
db_key                 number not null,
template_key           number not null,
df_file#               number,
df_ts#                 number,
df_plugin_change#      number,
df_foreign_dbid        number,
df_tablespace          varchar2(30),
df_creation_change#    number,
backup_type            varchar2(30),
file_type              varchar2(30),
bs_key                 number,
df_checkpoint_change#  number,
constraint sbt_template_df_u1 unique 
   (db_key, template_key, df_file#, df_creation_change#, df_plugin_change#),
constraint sbt_template_df_f1 foreign key (db_key, template_key)
   references sbt_template_db on delete cascade,
constraint sbt_template_df_f2 foreign key (template_key)
   references sbt_job_template on delete cascade
) &tablespace&
>>>
 
define create_sbt_template_df_i1
<<<
create index sbt_template_df_i1 on 
  sbt_template_df(template_key, db_key, df_file#)
&tablespace&
>>>
 
define create_sbt_task
<<<
create table sbt_task
(
task_id           number,
bs_key            number,
piece#            number,
template_key      number,
full_template_key number,
attr_key          number,
lib_key           number,
copies            number,
rep_server_key    number,
failure_cnt       number not null,
restore           varchar2(1), -- 'Y' or 'N'
src_bpkey         number,   -- bp_key that we are copying off to sbt
delete_source     varchar2(1), -- 'Y' or 'N', used for archiving.  Del original bp after copy
format            varchar2(512), -- format string for copied piece
constraint sbt_task_p  primary key (task_id),
constraint sbt_task_u1 unique (bs_key, piece#, full_template_key),
constraint sbt_task_f1 foreign key (template_key, attr_key)
    references sbt_job_template(template_key, attr_key) 
    on delete cascade deferrable initially deferred,
constraint sbt_task_f2 foreign key (lib_key) references sbt_lib_desc
   on delete cascade,
constraint sbt_task_f3 foreign key (bs_key) references bs
   on delete cascade,
constraint sbt_task_f4 foreign key (rep_server_key) references rep_server
   on delete cascade,
constraint sbt_task_f5 foreign key(task_id) references task
   initially deferred deferrable,
constraint sbt_task_f6 foreign key (full_template_key) references
    sbt_job_template on delete cascade,
constraint sbt_task_c1 check (restore in ('Y', 'N')),
constraint sbt_task_c2 check (delete_source in ('Y', 'N'))
) &tablespace&
>>>
 
define create_sbt_task_i1
<<<
create index sbt_task_i1 on sbt_task(task_id, template_key, bs_key, piece#)
&tablespace&
>>>
 
define create_sbt_task_i2
<<< create index sbt_task_i2 on sbt_task(bs_key) &tablespace& >>>
 
define create_sbt_task_i3
<<< 
create index sbt_task_i3 on sbt_task(template_key, attr_key) &tablespace& 
>>>
 
define create_sbt_task_history
<<<
create table sbt_task_history
(
task_id           number,
bs_key            number,
piece#            number,
template_key      number,
full_template_key number,
attr_key          number,
lib_key           number,
copies            number,
rep_server_key    number,
failure_cnt       number not null,
restore           varchar2(1), -- 'Y' or 'N'
src_bpkey         number,   -- bp_key that we are copying off to sbt
delete_source     varchar2(1), -- 'Y' or 'N', used for archiving.  Del original bp after copy
format            varchar2(512), -- format string for copied piece
constraint sbt_task_history_p  primary key (task_id),
--
--
--
constraint sbt_task_history_f1 foreign key (template_key) 
   references sbt_job_template on delete set null,
constraint sbt_task_history_f2 foreign key (attr_key) references sbt_attr_set
   on delete set null,
constraint sbt_task_history_f3 foreign key (lib_key) references sbt_lib_desc
   on delete cascade,
constraint sbt_task_history_f4 foreign key (bs_key) references bs
   on delete cascade,
constraint sbt_task_history_f5 foreign key (rep_server_key) 
   references rep_server on delete cascade,
constraint sbt_task_history_f6 foreign key (full_template_key) 
   references sbt_job_template on delete cascade,
constraint sbt_task_history_c1 check (restore in ('Y', 'N')),
constraint sbt_task_history_c2 check (delete_source in ('Y', 'N'))
) &tablespace&
>>>
 
define create_sbt_task_history_i1
<<<
create index sbt_task_history_i1 on
    sbt_task_history(task_id, template_key, bs_key, piece#)
&tablespace&
>>>
 
define create_sbt_task_history_i2
<<<
create index sbt_task_history_i2 on sbt_task_history(bs_key)
&tablespace&
>>>
 
define create_rep_server
<<<
create table rep_server     -- Replication Server definition
(
rep_server_key number,      -- primary key
server_key     number,      -- joinable with sbt_lib_desc or server tables
prot_key       number,      -- protection policy(ies) using this
--
status         varchar2(1), -- status of replication server
--
constraint rep_server_status_c1
    check (status in ('A', 'C', 'D', 'T')),
constraint rep_server_p primary key (rep_server_key),
constraint rep_server_f1 foreign key (server_key)
   references server on delete cascade,
constraint rep_server_f2 foreign key (prot_key) references prot
) &tablespace&
>>>
 
define create_host
<<<
create table host         -- AM Host IP Addresses
(
node_name              varchar2(256)  not null, -- node name with domain name
admin_ip_address       varchar2(4000) not null, -- admin interface
backup_ip_address      varchar2(4000) not null, -- client interface
replication_ip_address varchar2(4000) null,     -- backup interface
constraint host_p primary key (backup_ip_address),
constraint host_unique unique (node_name, backup_ip_address)
) &tablespace&
>>>
 
 
 
define dbmsrsi_plb
<<<
CREATE OR REPLACE PACKAGE dbms_ra_int IS
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
 
--
  TRACE_RSI        CONSTANT NUMBER :=   2;
  TRACE_RSI_MAX    CONSTANT NUMBER :=   4;
  TRACE_RSJS       CONSTANT NUMBER :=   8;
  TRACE_RCVCAT     CONSTANT NUMBER :=  16;
  TRACE_RCVCAT_MAX CONSTANT NUMBER :=  32;
  TRACE_KRBS       CONSTANT NUMBER :=  64;
  TRACE_KRBS_SQL   CONSTANT NUMBER := 128;
  TRACE_KRBR       CONSTANT NUMBER := 256;
 
--
  INC_ARC_PREFIX CONSTANT VARCHAR2(30) := 'I_ARC$';
 
--
--
  BIGNUM         CONSTANT NUMBER := 9999999999999999999999999999999999999999;
 
--
  UB8MAXVAL  CONSTANT NUMBER := 18446744073709551615;
  UB4MAXVAL  CONSTANT NUMBER := 4294967295;
 
--
  KBRSCHKTYPE_FILE    CONSTANT NUMBER := 1;  /* BPs in an SL */
  KBRSCHKTYPE_VIRTUAL CONSTANT NUMBER := 2;  /* BPs from block pool */
  KBRSCHKTYPE_TAPE    CONSTANT NUMBER := 3;  /* BPs on tape */
  KBRSCHKTYPE_DISK    CONSTANT NUMBER := 4;  /* BPs on disk we do not manage */
 
--
  BACKUP_READ         CONSTANT NUMBER := 2**0;
  BACKUP_WRITE        CONSTANT NUMBER := 2**1;
  RECONCILE_READ      CONSTANT NUMBER := 2**2;
  RECONCILE_WRITE     CONSTANT NUMBER := 2**3;
 
--
--
--
--
  incremental_no_fit EXCEPTION;
  PRAGMA EXCEPTION_INIT(incremental_no_fit, -45107);
 
--
  backup_cannot_fit EXCEPTION;
  PRAGMA EXCEPTION_INIT(backup_cannot_fit, -45108);
 
--
  bad_block_metadata_num CONSTANT NUMBER := -45109;
  bad_block_metadata EXCEPTION;
  PRAGMA EXCEPTION_INIT(bad_block_metadata, -45109);
 
 
--
--
--
  TYPE kccbs_t IS RECORD
  (
     bsstm   number,
     bsbss   number,
     bsbsc   number,
     bspct   number,
     bstyp   number,
     bslvl   number,
     bskpt   number,
     bsbsz   number,
     bspfw   number,
     bsplw   number,
     bscal   number,
     bsoid   raw(16),
     bsste   number
  );
 
--
--
--
  TYPE kccbp_t IS RECORD
  (
     bpstm   number,
     bpbss   number,
     bpbsc   number,
     bpflg   number,
     bpnum   number,
     bptim   number,
     bpext   number,
     bpsz1   number,
     bpdev   varchar2(17),
     bphdl   varchar2(513),
     bpmdh   varchar2(81),
     bpcmt   varchar2(65),
     bptag   varchar2(32),
     bpoid   raw(16),
     bpsts   number
  );
 
--
--
--
  TYPE kccbf_t IS RECORD
  (
     bfstm   number,
     bfbss   number,
     bfbsc   number,
     bfflg   number,
     bfdfp   number,
     bflvl   number,
     bfcrs   number,
     bfcrt   number,
     bfcps   number,
     bfcpt   number,
     bfrls   number,
     bfrlc   number,
     bfics   number,
     bfafs   number,
     bfncb   number,
     bfmcb   number,
     bflcb   number,
     bffsz   number,
     bfbct   number,
     bfbsz   number,
     bflor   number,
     bfbrd   number,
     bfsix   number,
     bffdi   number,
     bfplus  number,
     bfprls  number,
     bfprlt  number,
     bfptsn  number,
     bfssb   number,
     bfssz   number,
     bfoid   raw(16),
     bfste   number
  );
 
--
--
--
  TYPE kccbl_t IS RECORD
  (
     blstm   number,
     blbss   number,
     blbsc   number,
     blthp   number,
     blseq   number,
     blrls   number,
     blrlc   number,
     bllos   number,
     bllot   number,
     blnxs   number,
     blnxt   number,
     blbct   number,
     blbsz   number,
     blsix   number,
     blflg   number,
     blste   number
  );
 
--
--
--
  TYPE kccbi_t IS RECORD
  (
     bistm   number,
     bibss   number,
     bibsc   number,
     biflg   number,
     bifsz   number,
     bisix   number,
     bimdt   number,
     bidun   varchar2(30),
     bioid   raw(16)
  );
 
--
--
--
  TYPE kccal_t IS RECORD
  (
    alstm   number,
    alflg   number,
    althp   number,
    alseq   number,
    alrls   number,
    alrlc   number,
    allos   number,
    allot   number,
    alnxs   number,
    alnxt   number,
    albct   number,
    albsz   number,
    altoa   number,
    aldly   number,
    alacd   number,
    alfl2   number,
    aldst   number,
    alnam   varchar2(513)
  );
 
--
  TYPE callstack_line IS RECORD (line NUMBER, unit VARCHAR2(128));
  TYPE callstack IS TABLE OF callstack_line;
  TYPE error_payload IS RECORD (
                                 dynamic_stack callstack
                               , backtrace_stack callstack
                               , error_depth PLS_INTEGER
                               , action varchar2(64)
                               , module varchar2(64));
         
  TYPE payload_stack IS TABLE OF error_payload;
 
  s_pl_stack payload_stack := payload_stack();
 
--
  FUNCTION stamp2date(stamp IN NUMBER) RETURN DATE;
  FUNCTION date2stamp(dt IN DATE) RETURN NUMBER;
 
--
  FUNCTION dbkey2name(p_dbkey IN NUMBER) RETURN VARCHAR2;
 
--
  PROCEDURE write_lock(p_type IN NUMBER, p_key IN NUMBER);
  FUNCTION write_lock_wait(p_type IN NUMBER, p_key IN NUMBER) RETURN BOOLEAN;
  FUNCTION read_lock(p_type IN NUMBER, p_key IN NUMBER) RETURN BOOLEAN;
  PROCEDURE unlock(p_type IN NUMBER, p_key IN NUMBER);
 
  KEY_DF    CONSTANT NUMBER := 1;
  KEY_BP    CONSTANT NUMBER := 2;
  KEY_AL    CONSTANT NUMBER := 3;
  KEY_SY    CONSTANT NUMBER := 4; -- sbt library object
  KEY_CT    CONSTANT NUMBER := 5; -- sbt catalog object
  KEY_VB    CONSTANT NUMBER := 6;
 
--
--
  AM_DEBUG_OFF       CONSTANT NUMBER := 0;  -- Debug off
  AM_DEBUG_ON        CONSTANT NUMBER := 1;  -- Always on, for exeptions only
  AM_DEBUG_LOW       CONSTANT NUMBER := 2;  -- Odd and rare conditions
  AM_DEBUG_MED       CONSTANT NUMBER := 3;  -- Common, but not too wordy
  AM_DEBUG_HIGH      CONSTANT NUMBER := 4;  -- Everything worth showing.
--
  PROCEDURE setDebug(p_level IN NUMBER,
                     p_outtype IN NUMBER DEFAULT sys.dbms_system.trace_file);
 
 
--
  PROCEDURE save_error_int;
 
--
  PROCEDURE clear_error_int(reset BOOLEAN DEFAULT FALSE);
 
--
  FUNCTION get_error RETURN VARCHAR2;
 
  PROCEDURE unlock_vb(p_vbkey   IN NUMBER,
                      p_novbkey IN BOOLEAN);  -- Do not unlock vbkey
 
--
  PROCEDURE validateBackupPiece(p_dbkey IN NUMBER, 
                                p_bpkey IN NUMBER);
 
--
  FUNCTION file2handle(p_fname VARCHAR2) RETURN VARCHAR2;
 
--
  PROCEDURE createSbtCatalog(p_dbid        IN  NUMBER,
                             p_handle      IN  VARCHAR2,
                             p_pieceinc    IN  VARCHAR2,
                             p_ftype       IN  NUMBER,
                             p_xmldoc      IN  CLOB,
                             p_commit      IN  BOOLEAN,
                             p_ct_key      OUT NUMBER);
 
--
  PROCEDURE copySbtCatalog(p_handle      IN VARCHAR2,
                           p_oldpieceinc IN VARCHAR2,
                           p_newpieceinc IN VARCHAR2);
 
--
  PROCEDURE endUploadSbtCatalog(p_handle      IN VARCHAR2,
                                p_pieceinc    IN VARCHAR2,
                                p_xmldoc      IN CLOB);
 
--
  PROCEDURE finalizeSbtCatalog(p_bp_key IN NUMBER,
                               p_ct_key IN NUMBER,
                               p_xmldoc IN CLOB);
 
--
  PROCEDURE deleteSbtCatalog(p_handle   IN VARCHAR2,
                             p_pieceinc IN VARCHAR2);
 
--
  PROCEDURE readSbtCatalog(p_handle   IN         VARCHAR2,
                           p_xmldoc   OUT NOCOPY CLOB,
                           p_affinity IN         BINARY_INTEGER,
                           p_sbtinfo2 IN         BINARY_INTEGER);
 
--
--
  FUNCTION checkSbtCatalog(p_handle   IN VARCHAR2,
                           p_affinity IN BINARY_INTEGER)
     RETURN BINARY_INTEGER;
 
--
--
--
  PROCEDURE purgescncheck(p_dbid  IN NUMBER);
 
--
  PROCEDURE tickSbtSession(p_session_id IN VARCHAR2,
                           p_db_key     IN NUMBER,
                           p_module     IN VARCHAR2,
                           p_action     IN VARCHAR2);
 
--
  PROCEDURE purgeSbtSession(p_session_id IN VARCHAR2);
 
--
--
--
--
--
--
--
--
--
--
--
--
  FUNCTION has_privilege(user_id    IN NUMBER,
                         db_key     IN NUMBER,
                         db_uname   IN VARCHAR2,
                         operation  IN VARCHAR2,
                         accesstype IN VARCHAR2,
                         prvlg_code IN NUMBER DEFAULT NULL)
     RETURN BINARY_INTEGER;
 
--
--
--
--
  TYPE savebp IS RECORD
  (
   fuzzyscn      NUMBER,
   nmcorrupt     NUMBER,
   blocks_read   NUMBER,
   complete_time DATE
  );
  TYPE savebplst IS TABLE OF savebp INDEX BY binary_integer;
  s_bp_save       savebplst;
 
--
--
  PROCEDURE saveBPdata(fno              IN NUMBER,
                       fuzzyScn         IN NUMBER DEFAULT NULL,
                       blocks_read      IN NUMBER DEFAULT NULL,
                       corrupt          IN NUMBER DEFAULT NULL,
                       completion_stamp IN NUMBER DEFAULT NULL,
                       completion_time  IN DATE DEFAULT NULL);
 
--
  PROCEDURE checkBackupSet(bs IN kccbs_t);
 
--
--
  FUNCTION checkBackupPiece(vbkey         IN NUMBER
                           ,lib_key       IN NUMBER
                           ,ba_access     IN VARCHAR2
                           ,bp            IN kccbp_t
                           ,template_key  IN NUMBER) RETURN NUMBER;
 
--
  PROCEDURE checkBackupDatafile(bf IN kccbf_t);
 
--
  PROCEDURE checkBackupRedolog(bl IN kccbl_t);
 
--
  PROCEDURE checkBackupSpfile(bi IN kccbi_t);
 
--
  PROCEDURE checkArchivedLog(al IN kccal_t);
 
 
--
--
--
--
--
--
--
--
--
  FUNCTION number2null(p_name IN VARCHAR2)  RETURN NUMBER;
  FUNCTION varchar2null(p_name IN VARCHAR2) RETURN VARCHAR2;
  FUNCTION intervalnull(p_name IN VARCHAR2) RETURN DSINTERVAL_UNCONSTRAINED;
  FUNCTION isparamdef(p_name IN VARCHAR2)   RETURN BOOLEAN;
 
--
--
  FUNCTION statBpSbt(db_key  IN  NUMBER,
                     handle  IN  VARCHAR2,
                     mhandle OUT NOCOPY SYS.KBRSI_ICD.NAMES$_T,
                     single  OUT BINARY_INTEGER) RETURN BINARY_INTEGER;
 
--
--
--
--
 
 
--
--
--
--
--
--
--
--
--
--
--
--
  FUNCTION dg_is_db_ok(p_dbid IN NUMBER) RETURN NUMBER;
 
--
--
--
--
--
--
--
--
--
--
--
--
  PROCEDURE dg_register_log(p_dbid IN NUMBER, p_filename IN VARCHAR2);
 
--
--
--
--
--
--
--
--
--
  FUNCTION dg_get_platform_id(p_dbid IN NUMBER) RETURN NUMBER;
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
  PROCEDURE dg_backup_log(p_dbid     IN NUMBER,
                          p_filename IN VARCHAR2,
                          p_complete IN BOOLEAN,
                          p_delete   IN BOOLEAN DEFAULT TRUE);
 
--
--
--
--
--
--
--
--
--
  PROCEDURE RebuildBlockPool(p_dfkey IN NUMBER);
 
 
--
--
--
--
--
--
  FUNCTION sbt_default_drives RETURN NUMBER;
 
 
--
--
--
--
--
  PROCEDURE info_start(p_module VARCHAR2, p_action IN VARCHAR2);
 
--
--
--
--
--
--
  PROCEDURE info_end(p_reset BOOLEAN DEFAULT FALSE);
 
--
--
--
--
--
--
--
 
  PROCEDURE populate_rsr_key(p_bp_key    IN NUMBER,
                             p_bs_key    IN NUMBER);
 
--
--
--
  PROCEDURE throttle_me_int(p_ba_job_id         IN VARCHAR2,
                            p_db_unique_name     IN VARCHAR2,
                            p_channels_reqd      IN NUMBER,
                            p_request_time       IN DATE,
                            p_wait               OUT BOOLEAN,
                            p_error_str          OUT VARCHAR2);
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
  PROCEDURE canonicalize (
                          name                             IN VARCHAR2,
                          canon_name                       OUT VARCHAR2,
                          canon_len                        IN BINARY_INTEGER);
 
--
--
--
  FUNCTION build_rep_tpl_name (rep_srv_name  IN VARCHAR2,
                               db_key        IN NUMBER,
                               prot_key      IN NUMBER
                              ) RETURN VARCHAR2;
 
--
--
--
  FUNCTION build_rep_lib_name ( rep_srv_name IN VARCHAR2,
                                server_key IN NUMBER DEFAULT NULL
                              ) RETURN VARCHAR2;
 
--
--
--
  FUNCTION build_rep_atr_name ( rep_srv_name IN VARCHAR2,
                                server_key IN NUMBER DEFAULT NULL
                              ) RETURN VARCHAR2;
 
--
--
  PROCEDURE replication_reconcile (
                              db_unique_name          IN VARCHAR2 DEFAULT NULL,
                              replication_server_name IN VARCHAR2 DEFAULT NULL);
--
  PROCEDURE replication_reconcile (protection_policy_name IN VARCHAR2);
 
--
--
--
  PROCEDURE replicate_one_backup(bpkey IN NUMBER,
                              replication_server_name IN VARCHAR2 DEFAULT NULL);
 
--
--
--
  PROCEDURE replicate_backups(db_unique_name         IN VARCHAR2,
                             replication_server_name IN VARCHAR2 DEFAULT NULL);
 
--
--
--
--
  PROCEDURE replication_reconcile_reset (db_unique_name IN VARCHAR2);
 
--
  PROCEDURE lock_api_int (p_op_type     IN NUMBER DEFAULT NULL,
                          p_routine     IN VARCHAR2 DEFAULT NULL,
                          p_dbgnotes    IN VARCHAR2 DEFAULT NULL);
 
--
  PROCEDURE unlock_api_int (p_routine     IN VARCHAR2 DEFAULT NULL,
                            p_dbgnotes    IN VARCHAR2 DEFAULT NULL,
                            p_the_num     IN NUMBER DEFAULT 0,
                            p_results     IN BOOLEAN DEFAULT TRUE,
                            p_docommit    IN BOOLEAN DEFAULT FALSE);
 
--
  PROCEDURE verify_reserved_space (
    p_slkey IN NUMBER,
    p_newdb IN BOOLEAN DEFAULT FALSE);
 
--
  FUNCTION is_repair_needed RETURN BOOLEAN;
 
--
  PROCEDURE testTask(taskid   IN NUMBER DEFAULT NULL,
                     tasktype IN NUMBER DEFAULT NULL,
                     num1     IN NUMBER DEFAULT NULL,
                     num2     IN NUMBER DEFAULT NULL,
                     num3     IN NUMBER DEFAULT NULL,
                     char1    IN VARCHAR2 DEFAULT NULL,
                     char2    IN VARCHAR2 DEFAULT NULL,
                     param    IN VARCHAR2 DEFAULT NULL,
                     slkey    IN NUMBER DEFAULT NULL,
                     dbkey    IN NUMBER DEFAULT NULL,
                     settrace IN NUMBER DEFAULT NULL,
                     newsession IN BOOLEAN DEFAULT FALSE);
 
--
  PROCEDURE killTask(taskid   IN NUMBER);
 
  FUNCTION sbt_job_backup_type_to_num(backup_type IN VARCHAR2) RETURN NUMBER;
 
  PROCEDURE create_sbt_job_template_int(
   template_name       IN VARCHAR2,
   prot_name           IN VARCHAR2,
   attr_name           IN VARCHAR2,
   backup_type         IN VARCHAR2,
   full_template_name  IN VARCHAR2          DEFAULT NULL,
   from_tag            IN VARCHAR2          DEFAULT NULL,
   priority            IN NUMBER            DEFAULT 100, -- SBT_PRIORITY_MEDIUM
   copies              IN NUMBER            DEFAULT 1,
   window              IN DSINTERVAL_UNCONSTRAINED DEFAULT NULL,
   do_commit           IN BOOLEAN DEFAULT TRUE);
 
  PROCEDURE create_sbt_job_template_int(
   template_name       IN VARCHAR2,
   db_unique_name      IN VARCHAR2,
   attr_name           IN VARCHAR2,
   backup_type         IN VARCHAR2,
   full_template_name  IN VARCHAR2          DEFAULT NULL,
   from_tag            IN VARCHAR2          DEFAULT NULL,
   priority            IN NUMBER            DEFAULT 100,  -- SBT_PRIORITY_MEDIUM
   copies              IN NUMBER            DEFAULT 1,
   window              IN DSINTERVAL_UNCONSTRAINED DEFAULT NULL,
   do_commit           IN BOOLEAN DEFAULT TRUE);
 
--
  PROCEDURE wait_for_job (p_jobname VARCHAR2, p_poll_time NUMBER);
 
--
--
  PROCEDURE am_tracei (p_message IN VARCHAR2);
 
--
--
--
  FUNCTION pparmi (p_value IN VARCHAR2) RETURN VARCHAR2;
  FUNCTION pparmi (p_value IN NUMBER) RETURN VARCHAR2;
  FUNCTION pparmi (p_value IN BOOLEAN) RETURN VARCHAR2;
 
--
--
--
--
  FUNCTION b_p_i (p_varname IN VARCHAR2,
                  p_strval  IN VARCHAR2 DEFAULT NULL,
                  p_first   IN BOOLEAN DEFAULT FALSE,
                  p_last    IN BOOLEAN DEFAULT FALSE) RETURN VARCHAR2;
  FUNCTION b_p_i (p_varname IN VARCHAR2,
                  p_numval  IN NUMBER DEFAULT NULL,
                  p_first   IN BOOLEAN DEFAULT FALSE,
                  p_last    IN BOOLEAN DEFAULT FALSE) RETURN VARCHAR2;
  FUNCTION b_p_i (p_varname IN VARCHAR2,
                  p_boolval IN BOOLEAN DEFAULT NULL,
                  p_first   IN BOOLEAN DEFAULT FALSE,
                  p_last    IN BOOLEAN DEFAULT FALSE) RETURN VARCHAR2;
  FUNCTION b_p_i (p_varname  IN VARCHAR2,
                  p_intval   IN DSINTERVAL_UNCONSTRAINED DEFAULT NULL,
                  p_first    IN BOOLEAN DEFAULT FALSE,
                  p_last     IN BOOLEAN DEFAULT FALSE) RETURN VARCHAR2;
 
--
  FUNCTION item_not_foundi (p_obj_name IN VARCHAR2, p_obj_type IN VARCHAR2)
                            RETURN VARCHAR2;
 
--
  PTYPE_STR        CONSTANT NUMBER := 1;
  PTYPE_NUM        CONSTANT NUMBER := 2;
  PTYPE_INT        CONSTANT NUMBER := 3;
  PTYPE_BOOL       CONSTANT NUMBER := 4;
 
  s_lockapi_level       NUMBER := 0;     -- locking depth for api locks
  s_lockapi_type        NUMBER := 0;     -- locking type for existing api locks
  s_lockapi_routine     VARCHAR2(128);   -- routine that holds current api lock
  s_lockapi_notes       VARCHAR2(128);   -- any other debugging notes for lcok
 
 
--
--
--
--
--
--
--
--
--
  PROCEDURE tracing_on;
 
--
--
--
--
--
--
--
--
--
--
  PROCEDURE validate_bp(bpkey IN NUMBER);
 
END dbms_ra_int;
>>>
 
define dbmsrsjs_plb
<<<
CREATE OR REPLACE PACKAGE dbms_ra_scheduler AS
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
 
--
--
--
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
 
--
--
  PROCEDURE init (p_instance_only IN BOOLEAN DEFAULT FALSE, 
                  p_repair IN BOOLEAN DEFAULT FALSE);
 
--
  PROCEDURE repair_rs;
 
--
  FUNCTION restart_timer_process (do_check BOOLEAN) RETURN NUMBER;
 
--
--
  PROCEDURE timer_functions;
 
--
  PROCEDURE spawn_job (p_name     IN VARCHAR2,
                       p_action   IN VARCHAR2,
                       p_instance IN NUMBER,
                       p_comments IN VARCHAR2);
 
--
--
--
  PROCEDURE queue_spawn_sbt(p_libkey     IN NUMBER,
                            p_forpurge   IN BOOLEAN,
                            p_check_work IN BOOLEAN DEFAULT FALSE);
 
--
--
--
--
  PROCEDURE schedule (p_task_type IN NUMBER DEFAULT NULL,
                      p_param1    IN NUMBER DEFAULT NULL,
                      p_param2    IN NUMBER DEFAULT NULL,
                      p_settrace  IN NUMBER DEFAULT NULL);
 
--
  PROCEDURE testTask(p_taskid   IN NUMBER DEFAULT NULL,
                     p_tasktype IN NUMBER DEFAULT NULL,
                     p_num1     IN NUMBER DEFAULT NULL,
                     p_num2     IN NUMBER DEFAULT NULL,
                     p_num3     IN NUMBER DEFAULT NULL,
                     p_char1    IN VARCHAR2 DEFAULT NULL,
                     p_char2    IN VARCHAR2 DEFAULT NULL,
                     p_param    IN VARCHAR2 DEFAULT NULL,
                     p_slkey    IN NUMBER DEFAULT NULL,
                     p_dbkey    IN NUMBER DEFAULT NULL,
                     p_settrace IN NUMBER DEFAULT NULL,
                     p_newsession IN BOOLEAN DEFAULT FALSE);
 
--
  PROCEDURE get_lock(p_type IN NUMBER,
                     p_key  IN NUMBER);
 
--
  PROCEDURE unlock(p_type IN NUMBER,
                   p_key  IN NUMBER);
 
--
  PROCEDURE show_locks (p_type IN NUMBER,
                        p_key  IN NUMBER);
 
 
--
--
  PROCEDURE get_lock_direct_waitable(p_type IN NUMBER,
                                   p_key IN NUMBER,
                                   wait_time_in_seconds IN NUMBER);
 
--
  PROCEDURE release_blocked_tasks(p_task_id IN NUMBER,
                                  p_db_key IN NUMBER DEFAULT NULL);
 
--
  PROCEDURE raise_purge_priority (p_dfkey IN NUMBER);
 
--
  PROCEDURE release_restore_wait (p_instance NUMBER DEFAULT NULL);
 
--
--
--
  PROCEDURE avoid_sl(p_type  IN NUMBER, -- TASK_PURGE or TASK_INDEX_BACKUP
                     p_slkey IN NUMBER);
 
--
--
--
--
--
  PROCEDURE avoid_db (p_db_key IN NUMBER);
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
  PROCEDURE avoid_bs(p_dbkey IN NUMBER, p_bskey IN NUMBER, p_bpkey IN NUMBER);
 
--
--
  PROCEDURE new_task (task_rec   IN OUT task%ROWTYPE,
                      p_commit   IN BOOLEAN DEFAULT TRUE,
                      p_delay    IN BOOLEAN DEFAULT FALSE,
                      p_sbt_task IN BOOLEAN DEFAULT FALSE);
 
--
  PROCEDURE newdfkey (p_dfkey IN NUMBER,
                      p_dbinckey IN NUMBER,
                      p_pdbinckey IN NUMBER);
 
--
  FUNCTION get_savepoint RETURN NUMBER;
 
--
  FUNCTION set_blocking_purge(p_dbkey IN NUMBER,
                              p_space IN NUMBER DEFAULT NULL) RETURN NUMBER;
 
--
  PROCEDURE log_error (p_errno NUMBER,
                       p_param1 VARCHAR2 DEFAULT NULL,
                       p_param2 VARCHAR2 DEFAULT NULL,
                       p_param3 VARCHAR2 DEFAULT NULL,
                       p_param4 VARCHAR2 DEFAULT NULL,
                       p_keep_stack BOOLEAN DEFAULT TRUE,
                       p_component VARCHAR2,
                       p_severity NUMBER,
                       p_sl_key NUMBER DEFAULT NULL, 
                       p_db_key NUMBER DEFAULT NULL, 
                       p_param_char VARCHAR2 DEFAULT NULL,
                       p_param_num NUMBER DEFAULT NULL);
 
--
  PROCEDURE write_error (p_component VARCHAR2, 
                         p_severity NUMBER,
                         p_sl_key NUMBER DEFAULT NULL, 
                         p_db_key NUMBER DEFAULT NULL, 
                         p_param_char VARCHAR2 DEFAULT NULL,
                         p_param_num NUMBER DEFAULT NULL);
 
--
  PROCEDURE fix_error (p_error_num NUMBER, 
                       p_sl_key NUMBER DEFAULT NULL, 
                       p_db_key NUMBER DEFAULT NULL, 
                       p_param_char VARCHAR2 DEFAULT NULL,
                       p_param_num NUMBER DEFAULT NULL,
                       p_timestamp TIMESTAMP WITH TIME ZONE DEFAULT NULL);
 
--
  PROCEDURE reset_error (p_incident# NUMBER);
 
--
  PROCEDURE assert_owner;
 
--
  PROCEDURE setTracing(p_trc_on IN NUMBER,
                       p_perf_on IN NUMBER DEFAULT 0,
                       p_stall_on IN NUMBER DEFAULT 0,
                       p_safe_mode IN NUMBER DEFAULT 0);
 
--
  PROCEDURE load_config;
 
--
PROCEDURE stop_scheduler_jobs (p_stop_jobs IN NUMBER,
                               p_instance_only IN BOOLEAN,
                               p_db_key IN NUMBER DEFAULT NULL);
 
--
  PROCEDURE stop (p_instance_only IN BOOLEAN DEFAULT FALSE,
                  p_quiesce_first IN BOOLEAN DEFAULT FALSE);
 
--
  PROCEDURE enqueue_timer_reload_config;
 
--
  PROCEDURE enqueue_verify_timer_task;
  
--
  PROCEDURE queue_set_reconcile_timer (p_db_key IN NUMBER);
 
--
  PROCEDURE reset_reconcile_timer;
 
--
  PROCEDURE check_for_interrupt (p_state IN NUMBER DEFAULT NULL);
 
--
  PROCEDURE purge_immediate(p_sl_key      IN NUMBER,
                            p_db_key      IN NUMBER,
                            p_allocation  IN NUMBER);
 
--
 
--
--
--
--
  SUBTYPE interrupt_t IS BINARY_INTEGER RANGE 1..2;
  INTERRUPT_FOR_MOVE               CONSTANT interrupt_t := 1;
  INTERRUPT_FOR_PURGE              CONSTANT interrupt_t := 2;
 
  PROCEDURE interrupt_tasks (p_interrupt IN interrupt_t,
                             p_task_id   IN NUMBER DEFAULT NULL,
                             p_db_key    IN NUMBER DEFAULT NULL);
 
--
  PROCEDURE quiesce_rs;
 
--
  PROCEDURE unquiesce_rs;
 
--
  FUNCTION interval2secs (p_interval IN DSINTERVAL_UNCONSTRAINED) RETURN NUMBER;
 
--
  FUNCTION type2priority (p_tasktype IN NUMBER) RETURN NUMBER;
 
--
  FUNCTION tasktype2name (p_task_type NUMBER) RETURN VARCHAR2;
 
--
  FUNCTION taskstate2name (p_task_state NUMBER,
                           p_pending_interrupt NUMBER DEFAULT 0
                          ) RETURN VARCHAR2;
 
--
  PROCEDURE make_amjobs (name VARCHAR2 DEFAULT 'RA$%');
 
--
  PROCEDURE make_amlocks;
  
--
  PROCEDURE queue_sbt_backup_task(template_name IN VARCHAR2,
                                  src_bpkey     IN NUMBER   DEFAULT NULL,
                                  delete_source IN VARCHAR2 DEFAULT 'N',
                                  format        IN VARCHAR2 DEFAULT NULL);
 
--
  PROCEDURE queue_restore_task(request_id    IN NUMBER,
                               sbt_sessionid IN VARCHAR2,
                               handle        IN VARCHAR2);
 
--
--
  FUNCTION wait_for_resource(request_id IN NUMBER,
                             handle     IN VARCHAR2) RETURN BINARY_INTEGER;
 
--
  PROCEDURE replicate_existing_backups(
                      p_template_name IN sbt_job_template.template_name%TYPE,
                      p_db_key        IN NUMBER DEFAULT NULL, 
                      p_server_key    IN NUMBER DEFAULT NULL);
 
--
--
  PROCEDURE replicate_one_bp (p_db_key IN NUMBER,
                              p_bp_key IN NUMBER,
                              p_server_key IN NUMBER DEFAULT NULL);
 
--
  PROCEDURE queue_replication_task(p_bp_key           IN NUMBER,
                                   p_handle           IN VARCHAR2,
                                   p_db_key           IN NUMBER,
                                   p_bs_key           IN NUMBER,
                                   p_piece_no         IN NUMBER,
                                   p_rep_server_key   IN NUMBER,
                                   p_sbt_template_key IN NUMBER,
                                   p_sbt_attr_set_key IN NUMBER,
                                   p_sbt_lib_key      IN NUMBER);
  
--
  FUNCTION add_to_task_history_table (
                                       task_type   NUMBER,
                                       db_key      NUMBER DEFAULT NULL,
                                       sl_key      NUMBER DEFAULT NULL,
                                       param       VARCHAR2 DEFAULT NULL,
                                       param_num1  NUMBER DEFAULT NULL,
                                       param_num2  NUMBER DEFAULT NULL,
                                       param_num3  NUMBER DEFAULT NULL,
                                       param_char1 VARCHAR2 DEFAULT NULL,
                                       param_char2 VARCHAR2 DEFAULT NULL
                                       ) RETURN NUMBER;
  
--
  PROCEDURE update_task_history_entry (
                                    task_id     NUMBER,
                                    db_key      NUMBER DEFAULT NULL,
                                    sl_key      NUMBER DEFAULT NULL,
                                    param       VARCHAR2 DEFAULT NULL,
                                    param_num1  NUMBER DEFAULT NULL,
                                    param_num2  NUMBER DEFAULT NULL,
                                    param_num3  NUMBER DEFAULT NULL,
                                    param_char1 VARCHAR2 DEFAULT NULL,
                                    param_char2 VARCHAR2 DEFAULT NULL,
                                    do_commit   IN BOOLEAN DEFAULT FALSE
                                    );
  
--
--
--
--
--
--
--
--
--
--
  PROCEDURE copy_one_backuppiece(p_bpkey            IN NUMBER,
                                 p_format           IN VARCHAR2,
                                 p_deletesource     IN VARCHAR2,
                                 p_template_key     IN NUMBER DEFAULT NULL);
  
--
--
--
  PROCEDURE delete_one_backuppiece(p_bpkey IN NUMBER);
 
--
--
--
--
--
--
--
  FUNCTION reconcile_db (p_db_key          IN NUMBER,
                         p_server_key      IN NUMBER DEFAULT NULL,
                         p_only_active     IN BOOLEAN DEFAULT TRUE,
                         p_force_reconcile IN BOOLEAN DEFAULT FALSE,
                         rec_cnt           OUT NUMBER
                        ) RETURN BOOLEAN;
 
--
  FUNCTION check_do_pending_rep_setup(p_db_key IN VARCHAR2) RETURN BOOLEAN;
 
--
--
--
--
--
--
  FUNCTION delete_db_task_is_benign (p_task_type IN NUMBER) RETURN NUMBER;
 
  /*-------------------------*
   * Package State Variables *
   *-------------------------*/
  s_trace_file          VARCHAR2(512) := NULL;
--
  s_current_task        NUMBER := NULL;   -- task executing in this session
  s_current_task_type   NUMBER := NULL;   -- type of task executing by session
  s_cached_storage      BOOLEAN := FALSE; -- current task has storage cached
--
  s_polled_input        BOOLEAN := FALSE; -- adding polled file into blockpool
  s_now_serving         NUMBER  := 0;     -- sequence for task executions
  s_purging_active      BOOLEAN := FALSE; -- set to TRUE if purging is active
  s_sysreserve_ok       BOOLEAN := FALSE; -- TRUE if sys purge area can be used
  s_no_wait_on_allocate BOOLEAN := FALSE; -- If allocate requires purge, raise
--
  s_pending_interrupt   NUMBER := NULL;   -- task that is blocking current task
  s_instance            NUMBER := sys_context('USERENV', 'INSTANCE');
  s_last_busywork_stop  TIMESTAMP WITH TIME ZONE := SYSTIMESTAMP - 365;
--
  s_repair_active       BOOLEAN := FALSE; -- ORS repair underway in session
  s_amjobs rai_jobs_table_type;            -- table for make_amjobs  
  s_amlocks rai_locks_table_type;          -- table for make_amlocks  
 
/*---------------------------*
 * Initialization Parameters *
 *---------------------------*/
s_alloc_increment     NUMBER;           -- allocation increments
s_chunk_cache         NUMBER;           -- size of task based chunk cache
s_chunkno_alloc       NUMBER;           -- # of chunknos to reserve at a time
s_purging_reserve     NUMBER;           -- reserve for inline purging
s_purge_wait          NUMBER;           -- polling wait against purger task
s_purge_autoshrink    NUMBER;           -- automatic shrink of preallocated 
--
s_quiesce_wait        NUMBER;           -- wait before retrying quiesce
s_quiesce_session_wait DSINTERVAL_UNCONSTRAINED;
--
--
s_lock_refused_wait   NUMBER;           -- polling wait getting key locks
s_interrupt_wait      NUMBER;           -- polling wait for interrupted tasks
s_purge_threshold     NUMBER;           -- amount of freespace_goal to trigger
--
s_scheduling_wait     NUMBER;           -- polling wait to look for work
s_session_count       NUMBER;           -- # of scheduler sessions per instance
s_restricted_session_count  NUMBER;     -- # of session for high priority work
s_min_sessions_for_busywork NUMBER;     -- # of free sessions before busywork
s_busywork_inhibit_time DSINTERVAL_UNCONSTRAINED;
--
--
--
s_timer_loop_sleep    NUMBER;           -- number of seconds between checks of
--
s_db_stats_refresh_interval   DSINTERVAL_UNCONSTRAINED;
--
s_servlet_wait_seconds        NUMBER;   -- if client has not responded in this
--
s_histogram_slot_interval     DSINTERVAL_UNCONSTRAINED;
--
s_histogram_cycle_slots       NUMBER;   -- # of slots within storage histograms
s_histogram_window_slots      NUMBER;   -- # of slots actually considered
s_histogram_goal_percentile   NUMBER;   -- percentile histogram bucket to use 
--
s_initial_freespace_ratio     NUMBER;   -- part of sl to use as freespace_goal
--
s_min_freespace_ratio         NUMBER;   -- minimum part of sl to be used as
--
s_task_maintenance_interval   DSINTERVAL_UNCONSTRAINED;
--
--
s_storage_maintenance_interval DSINTERVAL_UNCONSTRAINED;
--
--
s_obsolete_sbt_interval       DSINTERVAL_UNCONSTRAINED;
--
s_polling_timeout_interval    DSINTERVAL_UNCONSTRAINED;
--
--
--
s_polling_deleted_files_check DSINTERVAL_UNCONSTRAINED;
--
--
--
--
s_history_partition_interval  DSINTERVAL_UNCONSTRAINED;
--
--
s_history_retention           NUMBER;
--
--
s_rm_incomplete_files_interval      DSINTERVAL_UNCONSTRAINED;
--
s_expire_files_interval       DSINTERVAL_UNCONSTRAINED;
--
--
s_max_task_restarts           NUMBER;-- max number of times to restart a task
--
--
s_optimize_df_tasks           NUMBER;
--
--
s_crosscheck_throttle         NUMBER;-- max number of crosscheck tasks
--
s_late_for_warning            NUMBER;
--
--
s_orphan_file_wait            DSINTERVAL_UNCONSTRAINED;
--
--
s_reconcile_short_interval    DSINTERVAL_UNCONSTRAINED;
--
--
s_reconcile_long_interval     DSINTERVAL_UNCONSTRAINED;
--
--
s_trim_factor                 NUMBER;
--
--
--
s_defer_delete                BINARY_INTEGER;
--
--
 
s_aggressive_delete           BINARY_INTEGER;
--
 
s_dumper_inhibit_interval     DSINTERVAL_UNCONSTRAINED;
--
--
 
s_check_sbtsched_interval     DSINTERVAL_UNCONSTRAINED;
--
--
 
s_max_sbt_failures            NUMBER;-- max number of sbt failures allowed
--
--
s_sbt_active_interval         DSINTERVAL_UNCONSTRAINED;
--
--
s_resumable_timeout           NUMBER;-- expressed in seconds, specifies a
--
--
s_rsrange_refresh_secs        NUMBER;
--
--
s_stall_when                  BOOLEAN;
--
--
--
--
s_debug_when                  NUMBER;
--
--
--
--
s_interrupt_when              BOOLEAN;
--
--
--
--
--
s_purge_opt_free              NUMBER;
--
--
--
s_purge_opt_pct               NUMBER;
--
--
--
--
s_fragmentation               NUMBER;
--
--
--
s_plans_maintained            NUMBER;
--
--
--
--
--
 
s_part_threshold              NUMBER;
--
--
--
s_part_index_style            NUMBER;
--
--
--
--
--
s_part_index_size             NUMBER;
--
--
--
s_part_parallel_degree        NUMBER;
--
--
--
--
--
--
--
s_alg_over_alloc      BINARY_INTEGER;
--
--
--
--
--
s_ra_pool_freespace_threshold NUMBER; -- Fraction of the pool tablespace that
--
--
s_ra_pool_full_free_count    NUMBER; -- Number of FULL_POOL waiting tasks 
--
 
--
--
--
--
--
--
--
  TASK_QUIESCE_RS           CONSTANT PLS_INTEGER  := 00;
  TASK_SPAWN_SBT            CONSTANT PLS_INTEGER  := 01;
  TASK_PURGE_DF_NOW         CONSTANT PLS_INTEGER  := 10;
  TASK_REPAIR_DB            CONSTANT PLS_INTEGER  := 20;
  TASK_STORAGE_HISTOGRAM    CONSTANT PLS_INTEGER  := 30;
  TASK_RESTORE              CONSTANT PLS_INTEGER  := 40; --used in kbrs.c
  TASK_DEFERRED_DELETE      CONSTANT PLS_INTEGER  := 55;
  TASK_GCOPY_COMPUTE        CONSTANT PLS_INTEGER  := 57;
  TASK_PURGE_DUP_DF         CONSTANT PLS_INTEGER  := 60;
  TASK_PURGE_IMMEDIATE      CONSTANT PLS_INTEGER  := 70;
  TASK_PURGE_DF             CONSTANT PLS_INTEGER  := 80;
  TASK_DELETE_DB            CONSTANT PLS_INTEGER  := 85;
  TASK_TRIM_DB              CONSTANT PLS_INTEGER  := 90;
  TASK_PURGE                CONSTANT PLS_INTEGER  := 100;
  TASK_NEWDFKEY             CONSTANT PLS_INTEGER  := 110;
  TASK_BACKUP_ARCH          CONSTANT PLS_INTEGER  := 120;
  TASK_INC_ARCH             CONSTANT PLS_INTEGER  := 130;
  TASK_PLAN_SBT             CONSTANT PLS_INTEGER  := 135;
  TASK_INDEX_BACKUP         CONSTANT PLS_INTEGER  := 140; --used in recover2.txt
  TASK_POLL                 CONSTANT PLS_INTEGER  := 150;
  TASK_BACKUP_SBT           CONSTANT PLS_INTEGER  := 160;
  TASK_RESTORE_SBT          CONSTANT PLS_INTEGER  := 170; --used in kbrs.c
  TASK_PURGE_SBT            CONSTANT PLS_INTEGER  := 180;
  TASK_OBSOLETE_SBT         CONSTANT PLS_INTEGER  := 190;
  TASK_RM_INCOMPLETE_FILES  CONSTANT PLS_INTEGER  := 200;
  TASK_RECONCILE            CONSTANT PLS_INTEGER  := 210;
  TASK_MOVE_DF              CONSTANT PLS_INTEGER  := 220;
  TASK_MOVE_ALL_DB          CONSTANT PLS_INTEGER  := 230;
 
--
  TASK_RESERVE_SBT          CONSTANT PLS_INTEGER  := 250;
 
  TASK_INSERT_FAULT         CONSTANT PLS_INTEGER  := 290;
 
--
  TASK_DB_STATS_REFRESH     CONSTANT PLS_INTEGER  := 300;
  TASK_RESTORE_RANGE_REFRESH CONSTANT PLS_INTEGER  := 305;
  TASK_OPTIMIZE_CHUNKS_DF   CONSTANT PLS_INTEGER  := 310;
  TASK_OPTIMIZE_CHUNKS      CONSTANT PLS_INTEGER  := 320;
  TASK_REBUILD_INDEX        CONSTANT PLS_INTEGER  := 325;
  TASK_VALIDATE_DB          CONSTANT PLS_INTEGER  := 330;
  TASK_PLAN_DF              CONSTANT PLS_INTEGER  := 335;
  TASK_CHECK_FILES          CONSTANT PLS_INTEGER  := 340;
  TASK_CROSSCHECK_DB        CONSTANT PLS_INTEGER  := 350;
 
--
  TASK_TEST_DUMMY           CONSTANT PLS_INTEGER  := 410;
 
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
  TASK_SESSION_TIMES        CONSTANT PLS_INTEGER  := 2000;
 
--
--
--
--
--
--
  TASK_ERROR_INFO           CONSTANT PLS_INTEGER   := 2001;
 
--
  TASK_MIN_API                    CONSTANT PLS_INTEGER  := 10000;
  TASK_API_ADD_DB                 CONSTANT PLS_INTEGER  := 10000;
  TASK_API_UPD_DB                 CONSTANT PLS_INTEGER  := 10010;
  TASK_API_DEL_DB                 CONSTANT PLS_INTEGER  := 10020;
  TASK_API_REN_DB                 CONSTANT PLS_INTEGER  := 10030;
  TASK_API_GRANT_DB               CONSTANT PLS_INTEGER  := 10050;
  TASK_API_REVOKE_DB              CONSTANT PLS_INTEGER  := 10060;
  TASK_API_ADD_SL                 CONSTANT PLS_INTEGER  := 10070;
  TASK_API_UPD_SL                 CONSTANT PLS_INTEGER  := 10080;
  TASK_API_DEL_SL                 CONSTANT PLS_INTEGER  := 10090;
  TASK_API_ADD_PROT_POLICY        CONSTANT PLS_INTEGER  := 10100;
  TASK_API_UPD_PROT_POLICY        CONSTANT PLS_INTEGER  := 10110;
  TASK_API_DEL_PROT_POLICY        CONSTANT PLS_INTEGER  := 10120;
  TASK_API_ADD_POLL_POLICY        CONSTANT PLS_INTEGER  := 10130;
  TASK_API_UPD_POLL_POLICY        CONSTANT PLS_INTEGER  := 10140;
  TASK_API_DEL_POLL_POLICY        CONSTANT PLS_INTEGER  := 10150;
  TASK_API_ADD_SBT_LIB            CONSTANT PLS_INTEGER  := 10160;
  TASK_API_UPD_SBT_LIB            CONSTANT PLS_INTEGER  := 10170;
  TASK_API_DEL_SBT_LIB            CONSTANT PLS_INTEGER  := 10180;
  TASK_API_ADD_RESTRICT_SBT_INST  CONSTANT PLS_INTEGER  := 10190;
  TASK_API_DEL_RESTRICT_SBT_INST  CONSTANT PLS_INTEGER  := 10200;
  TASK_API_ADD_SBT_ATTR_SET       CONSTANT PLS_INTEGER  := 10210;
  TASK_API_UPD_SBT_ATTR_SET       CONSTANT PLS_INTEGER  := 10220;
  TASK_API_DEL_SBT_ATTR_SET       CONSTANT PLS_INTEGER  := 10230;
  TASK_API_ADD_SBT_JOB            CONSTANT PLS_INTEGER  := 10240;
  TASK_API_UPD_SBT_JOB            CONSTANT PLS_INTEGER  := 10250;
  TASK_API_DEL_SBT_JOB            CONSTANT PLS_INTEGER  := 10260;
  TASK_API_PAU_SBT_LIB            CONSTANT PLS_INTEGER  := 10270;
  TASK_API_RES_SBT_LIB            CONSTANT PLS_INTEGER  := 10280;
  TASK_API_ADD_REPOSITORY         CONSTANT PLS_INTEGER  := 10290;
  TASK_API_DEL_REPOSITORY         CONSTANT PLS_INTEGER  := 10300;
  TASK_API_ADD_REP_SERVER         CONSTANT PLS_INTEGER  := 10310;
  TASK_API_REM_REP_SERVER         CONSTANT PLS_INTEGER  := 10320;
  TASK_API_STARTUP                CONSTANT PLS_INTEGER  := 10330;
  TASK_API_SHUTDOWN               CONSTANT PLS_INTEGER  := 10340;
  TASK_API_ABORT                  CONSTANT PLS_INTEGER  := 10350;
  TASK_API_CONFIG                 CONSTANT PLS_INTEGER  := 10360;
  TASK_API_POPULATE               CONSTANT PLS_INTEGER  := 10370;
  TASK_API_MOVE_BACKUP            CONSTANT PLS_INTEGER  := 10380;
  TASK_API_COPY_BACKUP            CONSTANT PLS_INTEGER  := 10390;
  TASK_API_MOVE_BACKUP_PIECE      CONSTANT PLS_INTEGER  := 10400;
  TASK_API_COPY_BACKUP_PIECE      CONSTANT PLS_INTEGER  := 10410;
  TASK_API_REPLICATE_EXISTING     CONSTANT PLS_INTEGER  := 10420;
  TASK_API_REPLICATION_RECONCILE  CONSTANT PLS_INTEGER  := 10430;
  TASK_API_REPLICATE_ONE_PIECE    CONSTANT PLS_INTEGER  := 10440;
  TASK_API_MIGRATE_TAPE           CONSTANT PLS_INTEGER  := 10460;
  TASK_API_PAU_REP_SRV            CONSTANT PLS_INTEGER  := 10470;
  TASK_API_RES_REP_SRV            CONSTANT PLS_INTEGER  := 10480;
  TASK_API_REPAIR_SL              CONSTANT PLS_INTEGER  := 10490;
  TASK_API_TESTTASK               CONSTANT PLS_INTEGER  := 10500;
  TASK_API_CRE_REP_SERVER         CONSTANT PLS_INTEGER  := 10510;
  TASK_API_UPD_REP_SERVER         CONSTANT PLS_INTEGER  := 10530;
  TASK_API_DEL_REP_SERVER         CONSTANT PLS_INTEGER  := 10520;
--
  TASK_MAX_API                    CONSTANT PLS_INTEGER  := 14999;
 
--
--
  PRIO_QUIESCE_RS           CONSTANT PLS_INTEGER  := 01; -- must be first!
  PRIO_SPAWN_SBT            CONSTANT PLS_INTEGER  := 02; -- must be second!
  PRIO_PURGE_DF_NOW         CONSTANT PLS_INTEGER  := 10; -- must be third!
  PRIO_REPAIR_DB            CONSTANT PLS_INTEGER  := 20;
  PRIO_STORAGE_HISTOGRAM    CONSTANT PLS_INTEGER  := 30;
  PRIO_RESTORE              CONSTANT PLS_INTEGER  := 40;
  PRIO_DEFERRED_DELETE      CONSTANT PLS_INTEGER  := 50;
  PRIO_GCOPY_COMPUTE        CONSTANT PLS_INTEGER  := 57;
  PRIO_PURGE_DUP_DF         CONSTANT PLS_INTEGER  := 60; -- before purge_imm
  PRIO_PURGE_IMMEDIATE      CONSTANT PLS_INTEGER  := 70;
  PRIO_PURGE_DF             CONSTANT PLS_INTEGER  := 80;
  PRIO_DELETE_DB            CONSTANT PLS_INTEGER  := 85;
  PRIO_TRIM_DB              CONSTANT PLS_INTEGER  := 90;
  PRIO_PURGE                CONSTANT PLS_INTEGER  := 100;
  PRIO_NEWDFKEY             CONSTANT PLS_INTEGER  := 110;
  PRIO_BACKUP_ARCH          CONSTANT PLS_INTEGER  := 120;
  PRIO_INC_ARCH             CONSTANT PLS_INTEGER  := 130;
  PRIO_PLAN_SBT             CONSTANT PLS_INTEGER  := 135;
  PRIO_INDEX_BACKUP         CONSTANT PLS_INTEGER  := 140;
  PRIO_POLL                 CONSTANT PLS_INTEGER  := 150;
  PRIO_BACKUP_SBT           CONSTANT PLS_INTEGER  := 160;
  PRIO_RESTORE_SBT          CONSTANT PLS_INTEGER  := 170;
  PRIO_PURGE_SBT            CONSTANT PLS_INTEGER  := 180;
  PRIO_OBSOLETE_SBT         CONSTANT PLS_INTEGER  := 190;
  PRIO_RM_INCOMPLETE_FILES  CONSTANT PLS_INTEGER  := 200;
  PRIO_RECONCILE            CONSTANT PLS_INTEGER  := 210;
  PRIO_MOVE_DF              CONSTANT PLS_INTEGER  := 220;
  PRIO_MOVE_ALL_DB          CONSTANT PLS_INTEGER  := 230;
 
  PRIO_INSERT_FAULT         CONSTANT PLS_INTEGER  := 290;
 
--
  PRIO_MIN_BUSYWORK         CONSTANT PLS_INTEGER  := 299;
 
  PRIO_DB_STATS_REFRESH     CONSTANT PLS_INTEGER  := 300;
  PRIO_RESTORE_RANGE_REFRESH CONSTANT PLS_INTEGER  := 305;
  PRIO_OPTIMIZE_CHUNKS_DF   CONSTANT PLS_INTEGER  := 310;
  PRIO_OPTIMIZE_CHUNKS      CONSTANT PLS_INTEGER  := 320;
  PRIO_REBUILD_INDEX        CONSTANT PLS_INTEGER  := 325;
  PRIO_VALIDATE_DB          CONSTANT PLS_INTEGER  := 330;
  PRIO_PLAN_DF              CONSTANT PLS_INTEGER  := 335;
  PRIO_CHECK_FILES          CONSTANT PLS_INTEGER  := 340;
  PRIO_CROSSCHECK_DB        CONSTANT PLS_INTEGER  := 350;
 
--
  PRIO_TEST_DUMMY           CONSTANT PLS_INTEGER  := 410;
 
 
  PRIO_MAX_BUSYWORK         CONSTANT PLS_INTEGER  := 999;
 
 
--
--
--
--
--
--
  STATE_EXECUTABLE          CONSTANT PLS_INTEGER  := 1;
  STATE_RUNNING             CONSTANT PLS_INTEGER  := 2;
  STATE_COMPLETED           CONSTANT PLS_INTEGER  := 3;
  STATE_ORDERING_WAIT       CONSTANT PLS_INTEGER  := 4;
  STATE_TASK_WAIT           CONSTANT PLS_INTEGER  := 5;
  STATE_RESTORE_WAIT        CONSTANT PLS_INTEGER  := 6;
  STATE_RETRYING            CONSTANT PLS_INTEGER  := 7; -- used only in views
  STATE_FAILED              CONSTANT PLS_INTEGER  := 8; -- not seen in task
  STATE_CANCEL              CONSTANT PLS_INTEGER  := 9;
  STATE_CANCELING           CONSTANT PLS_INTEGER  := 10;
  STATE_CANCELED            CONSTANT PLS_INTEGER  := 11; -- not seen in task
 
--
--
--
  TASKS_RECEIVED_BACKUP CONSTANT NUMBER := TO_NUMBER('0001','XXXX');
  TASKS_BLOCKING_TASK   CONSTANT NUMBER := TO_NUMBER('0002','XXXX');
  TASKS_OUT_OF_ORDER    CONSTANT NUMBER := TO_NUMBER('0004','XXXX');
  TASKS_DELETE_INPUT    CONSTANT NUMBER := TO_NUMBER('0008','XXXX');
  TASKS_POLLED_INPUT    CONSTANT NUMBER := TO_NUMBER('0010','XXXX');
  TASKS_CHUNK_CACHE_ACTIVE CONSTANT NUMBER := TO_NUMBER('0020','XXXX');
  TASKS_TOO_MANY_INTERRUPTS CONSTANT NUMBER := TO_NUMBER('0040','XXXX');
 
 
--
--
--
--
  LOCK_DB_KEY           CONSTANT NUMBER := 5; -- Locks for storage management
  LOCK_SL_KEY           CONSTANT NUMBER := 6; -- Locks for storage management
  LOCK_COMMON           CONSTANT NUMBER := 7; -- Misc locks qualified by id2
    LOCK_TIMER          CONSTANT NUMBER := 1; -- Timer process lock
    LOCK_SCHED          CONSTANT NUMBER := 2; -- Serialize access to task table
    LOCK_API            CONSTANT NUMBER := 3; -- Serialize API execution
    LOCK_QUIESCE        CONSTANT NUMBER := 4; -- Quiesces recovery server
--
--
  LOCK_PURGE            CONSTANT NUMBER := 8; -- Locks for purging
  LOCK_KEY              CONSTANT NUMBER := 9; -- Locks for reading/writing
--
 
 
--
--
--
--
  LOCK_QUIESCE_PENDING  CONSTANT NUMBER := 1;
 
--
--
--
--
--
  LOCK_DELETE_DB_UNREGISTER  CONSTANT NUMBER := 2;
 
--
--
--
  SEVERITY_WARNING      CONSTANT NUMBER := 1;    -- warning messages
  SEVERITY_ERROR        CONSTANT NUMBER := 10;   -- non-specific error
  SEVERITY_INTERNAL     CONSTANT NUMBER := 20;   -- unhandled exception
 
--
--
--
  MOVE_PHASE_NULL   CONSTANT NUMBER := NULL;  -- Db is not moving
  MOVE_PHASE_PEND   CONSTANT NUMBER := 1;     -- Move is pending
  MOVE_PHASE_START  CONSTANT NUMBER := 2;     -- Waiting to move metadata
  MOVE_PHASE_POOL   CONSTANT NUMBER := 3;     -- Moving Block pool -- purge
--
--
  MOVE_PHASE_FILES  CONSTANT NUMBER := 4;     -- Moving remaining files
--
--
 
--
--
--
--
--
--
  SERVLET_PSEUDO_TASK   CONSTANT NUMBER := -1;  -- waiting for servlet(restore)
  SPACE_PSEUDO_TASK     CONSTANT NUMBER := -2;  -- backup_piece waiting
--
  OPT_DF_PSEUDO_TASK    CONSTANT NUMBER := -3;  -- Opt_df tasks waiting for
--
  TEST_PSEUDO_TASK      CONSTANT NUMBER := -4;  -- wait for test_task scheduler
  RESOURCE_PSEUDO_TASK  CONSTANT NUMBER := -5;  -- wait for contention on
--
  MAX_RESOURCE_WAIT_PROCESSES CONSTANT NUMBER := 99999;
  STALL_PSEUDO_TASK     CONSTANT NUMBER := -6;  -- _stall_when is set
  LIBRARY_PSEUDO_TASK   CONSTANT NUMBER := -7;  -- wait for stalled library
--
  POOL_FULL_PSEUDO_TASK CONSTANT NUMBER := -8;  -- waiting for space to be
--
 
--
--
--
  POLLING_HISTORY_PROCESSING    CONSTANT CHAR(1) := 'P';
  POLLING_HISTORY_COMPLETED     CONSTANT CHAR(1) := 'C';
  POLLING_HISTORY_BAD_DBID      CONSTANT CHAR(1) := 'D';
  POLLING_HISTORY_BAD_FTYPE     CONSTANT CHAR(1) := 'F';
  POLLING_HISTORY_ERROR         CONSTANT CHAR(1) := 'E';
  POLLING_HISTORY_TIMED_OUT     CONSTANT CHAR(1) := 'T';
  POLLING_HISTORY_REMOVED       CONSTANT CHAR(1) := 'R'; -- file removed
 
--
--
--
  POLL_FLAGS_DELETE_INPUT       CONSTANT NUMBER := 2**0;
  POLL_FLAGS_UNDO_DBID_ERROR    CONSTANT NUMBER := 2**1;
  POLL_FLAGS_UNDO_TIMEOUT_ERROR CONSTANT NUMBER := 2**2;
 
--
--
--
  FTYPE_ARCHIVELOG      CONSTANT NUMBER := 4;  -- skgfrfALOG
  FTYPE_BACKUP          CONSTANT NUMBER := 9;  -- skgfrfDBKUP
  FTYPE_INCBACKUP       CONSTANT NUMBER := 10; -- skgfrfDIBKUP
  FTYPE_ARCHBACKUP      CONSTANT NUMBER := 11; -- skgfrfABKUP
  FTYPE_AUTOBACKUP      CONSTANT NUMBER := 20; -- skgfrfAUBKUP
  FTYPE_CHUNK           CONSTANT NUMBER := 40; -- skgfrfCHUNK
 
--
--
--
  COPY_BA_POLL         CONSTANT NUMBER := 1;  -- KRBYX_ORS_POLL   
  COPY_BA_CPMV         CONSTANT NUMBER := 2;  -- KRBYX_ORS_CPMV   
  COPY_BA_XALG         CONSTANT NUMBER := 3;  -- KRBYX_ORS_XALG
 
--
--
--
  STOP_JOBS_ALL         CONSTANT NUMBER := 1;  -- Stop all jobs
  STOP_JOBS_DB          CONSTANT NUMBER := 2;  -- Stop jobs for a given db
 
--
--
--
--
--
--
  DB_STATE_IN_DELETE    CONSTANT NUMBER := 1;    -- Database is being deleted
 
--
--
--
  DB_TASK_IS_BENIGN     CONSTANT NUMBER := 1;    -- Task type is benign
--
  DB_TASK_IS_NOT_BENIGN CONSTANT NUMBER := 2;    -- Task type is NOT benign
--
 
--
--
--
 
  E_RESOURCE_BUSY                    EXCEPTION; 
  PRAGMA EXCEPTION_INIT              (E_RESOURCE_BUSY, -54);
 
  E_ORA_600                          EXCEPTION; 
  PRAGMA EXCEPTION_INIT              (E_ORA_600, -600);
 
  E_SNAPSHOT_TOO_OLD                 EXCEPTION;
  PRAGMA EXCEPTION_INIT              (E_SNAPSHOT_TOO_OLD, -1555);
 
  E_TOO_MANY_ROLLBACK_EXTENTS        EXCEPTION; 
  PRAGMA EXCEPTION_INIT              (E_TOO_MANY_ROLLBACK_EXTENTS, -1628);
 
  E_UNABLE_EXTEND_TEMPSEG            EXCEPTION; 
  PRAGMA EXCEPTION_INIT              (E_UNABLE_EXTEND_TEMPSEG, -1652);
 
  E_TABLE_TS_FULL_NUM                CONSTANT NUMBER := -1653;
  E_TABLE_TS_FULL                    EXCEPTION; 
  PRAGMA EXCEPTION_INIT              (E_TABLE_TS_FULL,  -1653);
 
  E_INDEX_TS_FULL                    EXCEPTION; 
  PRAGMA EXCEPTION_INIT              (E_INDEX_TS_FULL, -1654);
 
  E_INDEXPART_TS_FULL                EXCEPTION; 
  PRAGMA EXCEPTION_INIT              (E_INDEXPART_TS_FULL, -1683);
 
  E_TABLEPART_TS_FULL                EXCEPTION; 
  PRAGMA EXCEPTION_INIT              (E_TABLEPART_TS_FULL, -1688);
 
 
  E_NO_LONGER_EXISTS                 EXCEPTION;
  PRAGMA EXCEPTION_INIT              (E_NO_LONGER_EXISTS, -8103);
 
  E_CONSISTENT_READ                  EXCEPTION; PRAGMA EXCEPTION_INIT (
  E_CONSISTENT_READ,                                    -8176         );
  E_CONSISTENT_READ_NUM              CONSTANT NUMBER := -8176;
 
  E_PQ_FAILURE                       EXCEPTION;
  PRAGMA EXCEPTION_INIT              (E_PQ_FAILURE, -12805);
 
  E_INSTANCE_UNAVAILABLE             EXCEPTION;
  PRAGMA EXCEPTION_INIT              (E_INSTANCE_UNAVAILABLE, -16639);
 
  E_BACKUP_IO_ERROR_RMAN_NUM         CONSTANT NUMBER := -19624;
  E_BACKUP_IO_ERROR_RMAN             EXCEPTION;
  PRAGMA EXCEPTION_INIT              (E_BACKUP_IO_ERROR_RMAN, -19624);
 
  E_ERROR_ID_FILE_NUM                CONSTANT NUMBER := -19625;
  E_ERROR_ID_FILE                    EXCEPTION;
  PRAGMA EXCEPTION_INIT              (E_ERROR_ID_FILE, -19625);
 
  E_ROW_CACHE_LOCK                   EXCEPTION;
  PRAGMA EXCEPTION_INIT              (E_ROW_CACHE_LOCK, -27355);
 
  E_JOB_WONT_STOP                    EXCEPTION;
  PRAGMA EXCEPTION_INIT              (E_JOB_WONT_STOP, -27365);
 
  E_JOB_NOT_RUNNING                  EXCEPTION;
  PRAGMA EXCEPTION_INIT              (E_JOB_NOT_RUNNING, -27366);
 
  E_JOB_NOT_FOUND                    EXCEPTION;
  PRAGMA EXCEPTION_INIT              (E_JOB_NOT_FOUND, -27475);
 
  E_JOB_DOES_NOT_EXIST               EXCEPTION;
  PRAGMA EXCEPTION_INIT              (E_JOB_DOES_NOT_EXIST, -27476);
 
  E_JOB_ALREADY_EXISTS               EXCEPTION;
  PRAGMA EXCEPTION_INIT              (E_JOB_ALREADY_EXISTS, -27477);
 
  E_RESUMABLE_TIMEOUT                EXCEPTION;
  PRAGMA EXCEPTION_INIT              (E_RESUMABLE_TIMEOUT, -30032);
 
  E_CANT_EXTEND_UNDO                 EXCEPTION;
  PRAGMA EXCEPTION_INIT              (E_CANT_EXTEND_UNDO, -30036);
 
  /* Below referenced from dbmsbkrs.pls */
  E_CORRUPT_NUM                      CONSTANT NUMBER := -19599;
  E_CORRUPT                          EXCEPTION;
  PRAGMA EXCEPTION_INIT              (E_CORRUPT, -19599);
 
  E_UCONSTRAINT_NUM                  CONSTANT NUMBER := -1;
  E_UCONSTRAINT                      EXCEPTION;
  PRAGMA EXCEPTION_INIT              (E_UCONSTRAINT, -1);
 
--
--
--
--
--
--
 
  E_REPAIR_AVM_METADATA              EXCEPTION; PRAGMA EXCEPTION_INIT (
  E_REPAIR_AVM_METADATA,                                -45100        );
  E_REPAIR_AVM_METADATA_NUM          CONSTANT NUMBER := -45100;
 
  E_BAD_CHUNK_NUMBER                 EXCEPTION; PRAGMA EXCEPTION_INIT (
  E_BAD_CHUNK_NUMBER,                                   -45101        );
  E_BAD_CHUNK_NUMBER_NUM             CONSTANT NUMBER := -45101;
 
  E_NO_MORE_STORAGE                  EXCEPTION; PRAGMA EXCEPTION_INIT (
  E_NO_MORE_STORAGE,                                    -45102        );
  E_NO_MORE_STORAGE_NUM              CONSTANT NUMBER := -45102;
 
  E_BAD_STORAGE_LOCATION             EXCEPTION; PRAGMA EXCEPTION_INIT (
  E_BAD_STORAGE_LOCATION,                               -45103        );
  E_BAD_STORAGE_LOCATION_NUM         CONSTANT NUMBER := -45103;
 
  E_BACKUP_NOT_FOUND                 EXCEPTION; PRAGMA EXCEPTION_INIT (
  E_BACKUP_NOT_FOUND,                                   -45104        );
  E_BACKUP_NOT_FOUND_NUM             CONSTANT NUMBER := -45104;
 
  E_NOT_IN_PURGE                     EXCEPTION; PRAGMA EXCEPTION_INIT (
  E_NOT_IN_PURGE,                                       -45105        );
  E_NOT_IN_PURGE_NUM                 CONSTANT NUMBER := -45105;
 
  E_BAD_VBID                         EXCEPTION; PRAGMA EXCEPTION_INIT (
  E_BAD_VBID,                                           -45106        );
  E_BAD_VBID_NUM                     CONSTANT NUMBER := -45106;
 
  E_PENDING_INTERRUPT                EXCEPTION; PRAGMA EXCEPTION_INIT (
  E_PENDING_INTERRUPT,                                  -45110        );
  E_PENDING_INTERRUPT_NUM            CONSTANT NUMBER := -45110;
 
  E_TOO_MANY_RESTARTS                EXCEPTION; PRAGMA EXCEPTION_INIT (
  E_TOO_MANY_RESTARTS,                                  -45111        );
  E_TOO_MANY_RESTARTS_NUM            CONSTANT NUMBER := -45111;
 
  E_RETRY_ERROR                      EXCEPTION; PRAGMA EXCEPTION_INIT (
  E_RETRY_ERROR,                                        -45112        );
  E_RETRY_ERROR_NUM                  CONSTANT NUMBER := -45112;
 
  E_INTERNAL_ERROR                   EXCEPTION; PRAGMA EXCEPTION_INIT (
  E_INTERNAL_ERROR,                                     -45113        );
  E_INTERNAL_ERROR_NUM               CONSTANT NUMBER := -45113;
 
  E_ORPHAN_FILE                      EXCEPTION; PRAGMA EXCEPTION_INIT (
  E_ORPHAN_FILE,                                        -45114        );
  E_ORPHAN_FILE_NUM                  CONSTANT NUMBER := -45114;
 
  E_TOO_BIG_TO_MOVE                  EXCEPTION; PRAGMA EXCEPTION_INIT (
  E_TOO_BIG_TO_MOVE,                                    -45115        );
  E_TOO_BIG_TO_MOVE_NUM              CONSTANT NUMBER := -45115;
 
  E_RETRY_RESERVE                    EXCEPTION; PRAGMA EXCEPTION_INIT (
  E_RETRY_RESERVE,                                      -45117        );
  E_RETRY_RESERVE_NUM                CONSTANT NUMBER := -45117;
 
  E_ORPHAN_BP_PIECE                  EXCEPTION; PRAGMA EXCEPTION_INIT (
  E_ORPHAN_BP_PIECE,                                    -45128        );
  E_ORPHAN_BP_PIECE_NUM              CONSTANT NUMBER := -45128;
 
  E_BAD_ODB_USAGE                    EXCEPTION; PRAGMA EXCEPTION_INIT (
  E_BAD_ODB_USAGE,                                      -45129        );
  E_BAD_ODB_USAGE_NUM                CONSTANT NUMBER := -45129;
 
  E_BAD_TOTAL_ALLOC                  EXCEPTION; PRAGMA EXCEPTION_INIT (
  E_BAD_TOTAL_ALLOC,                                    -45133        );
  E_BAD_TOTAL_ALLOC_NUM              CONSTANT NUMBER := -45133;
 
  E_CORRUPT_BACKUP                   EXCEPTION; PRAGMA EXCEPTION_INIT (
  E_CORRUPT_BACKUP,                                     -45116        );
  E_CORRUPT_BACKUP_NUM               CONSTANT NUMBER := -45116;
 
  E_OAM_NOT_RUNNING                  EXCEPTION; PRAGMA EXCEPTION_INIT (
  E_OAM_NOT_RUNNING,                                    -45164        );
  E_OAM_NOT_RUNNING_NUM              CONSTANT NUMBER := -45164;
 
  E_CORRUPT_BACKUPPIECE              EXCEPTION; PRAGMA EXCEPTION_INIT (
  E_CORRUPT_BACKUPPIECE,                                -45165        );
  E_CORRUPT_BACKUPPIECE_NUM          CONSTANT NUMBER := -45165;
 
  E_NO_MORE_SGA                      EXCEPTION; PRAGMA EXCEPTION_INIT (
  E_NO_MORE_SGA,                                        -45134        );
  E_NO_MORE_SGA_NUM                  CONSTANT NUMBER := -45134;
 
  E_CORRUPT_BLOCK                    EXCEPTION; PRAGMA EXCEPTION_INIT (
  E_CORRUPT_BLOCK,                                      -45132        );
  E_CORRUPT_BLOCK_NUM                CONSTANT NUMBER := -45132;
 
  E_TERMINATED                       EXCEPTION; PRAGMA EXCEPTION_INIT (
  E_TERMINATED,                                         -45135        );
  E_TERMINATED_NUM                   CONSTANT NUMBER := -45135;
 
  E_NEED_MORE_SPACE                  EXCEPTION; PRAGMA EXCEPTION_INIT (
  E_NEED_MORE_SPACE,                                    -45146        );
  E_NEED_MORE_SPACE_NUM              CONSTANT NUMBER := -45146;
 
  E_TOO_MANY_MOVES                   EXCEPTION; PRAGMA EXCEPTION_INIT (
  E_TOO_MANY_MOVES,                                     -45147        );
  E_TOO_MANY_MOVES_NUM               CONSTANT NUMBER := -45147;
 
  E_ERRORS_FOUND                     EXCEPTION; PRAGMA EXCEPTION_INIT (
  E_ERRORS_FOUND,                                       -45148        );
  E_ERRORS_FOUND_NUM                 CONSTANT NUMBER := -45148;
 
  E_BAD_TASK_TYPE                    EXCEPTION; PRAGMA EXCEPTION_INIT (
  E_BAD_TASK_TYPE,                                      -45149        );
  E_BAD_TASK_TYPE_NUM                CONSTANT NUMBER := -45149;
 
  E_BAD_DBID                         EXCEPTION; PRAGMA EXCEPTION_INIT (
  E_BAD_DBID,                                           -45150        );
  E_BAD_DBID_NUM                     CONSTANT NUMBER := -45150;
 
  E_BAD_LOCKING_PROTOCOL             EXCEPTION; PRAGMA EXCEPTION_INIT (
  E_BAD_LOCKING_PROTOCOL,                               -45151        );
  E_BAD_LOCKING_PROTOCOL_NUM         CONSTANT NUMBER := -45151;
 
  E_BAD_BACKUP_PIECE                 EXCEPTION; PRAGMA EXCEPTION_INIT (
  E_BAD_BACKUP_PIECE,                                   -45152        );
  E_BAD_BACKUP_PIECE_NUM             CONSTANT NUMBER := -45152;
 
  E_UNKNOWN_DATAFILE                 EXCEPTION; PRAGMA EXCEPTION_INIT (
  E_UNKNOWN_DATAFILE,                                   -45153        );
  E_UNKNOWN_DATAFILE_NUM             CONSTANT NUMBER := -45153;
 
  E_UNKNOWN_FILE                     EXCEPTION; PRAGMA EXCEPTION_INIT (
  E_UNKNOWN_FILE,                                       -45154        );
  E_UNKNOWN_FILE_NUM                 CONSTANT NUMBER := -45154;
 
  E_SBT_JOB_NOTFOUND                 EXCEPTION; PRAGMA EXCEPTION_INIT (
  E_SBT_JOB_NOTFOUND,                                   -45156        );
  E_SBT_JOB_NOTFOUND_NUM             CONSTANT NUMBER := -45156;
 
  E_SBT_LIB_NOT_READY                EXCEPTION; PRAGMA EXCEPTION_INIT (
  E_SBT_LIB_NOT_READY,                                  -45158        );
  E_SBT_LIB_NOT_READY_NUM            CONSTANT NUMBER := -45158;
 
  E_REC_WINDOW_LOST                  EXCEPTION; PRAGMA EXCEPTION_INIT (
  E_REC_WINDOW_LOST,                                    -45159        );
  E_REC_WINDOW_LOST_NUM              CONSTANT NUMBER := -45159;
 
  E_INCR_LOST                        EXCEPTION; PRAGMA EXCEPTION_INIT (
  E_INCR_LOST,                                          -45160        );
  E_INCR_LOST_NUM                    CONSTANT NUMBER := -45160;
 
  E_PIECE_TOO_BIG                    EXCEPTION; PRAGMA EXCEPTION_INIT (
  E_PIECE_TOO_BIG,                                      -45161        );
  E_PIECE_TOO_BIG_NUM                CONSTANT NUMBER := -45161;
 
  E_BAD_USER                         EXCEPTION; PRAGMA EXCEPTION_INIT (
  E_BAD_USER,                                           -45163        );
  E_BAD_USER_NUM                     CONSTANT NUMBER := -45163;
 
  E_BAD_FILE                         EXCEPTION; PRAGMA EXCEPTION_INIT (
  E_BAD_FILE,                                           -45166        );
  E_BAD_FILE_NUM                     CONSTANT NUMBER := -45166;
 
  E_BAD_VALIDATE                     EXCEPTION; PRAGMA EXCEPTION_INIT (
  E_BAD_VALIDATE,                                       -45167        );
  E_BAD_VALIDATE_NUM                 CONSTANT NUMBER := -45167;
 
  E_BAD_TASK                         EXCEPTION; PRAGMA EXCEPTION_INIT (
  E_BAD_TASK,                                           -45168        );
  E_BAD_TASK_NUM                     CONSTANT NUMBER := -45168;
 
  E_TIMER_EXIT                       EXCEPTION; PRAGMA EXCEPTION_INIT (
  E_TIMER_EXIT,                                         -45169        );
  E_TIMER_EXIT_NUM                   CONSTANT NUMBER := -45169;
 
  E_SL_FULL                          EXCEPTION; PRAGMA EXCEPTION_INIT (
  E_SL_FULL,                                            -45170        );
  E_SL_FULL_NUM                      CONSTANT NUMBER := -45170;
 
  E_LATE_OPTIMIZE                    EXCEPTION; PRAGMA EXCEPTION_INIT (
  E_LATE_OPTIMIZE,                                      -45171        );
  E_LATE_OPTIMIZE_NUM                CONSTANT NUMBER := -45171;
 
  E_LATE_VALIDATE                    EXCEPTION; PRAGMA EXCEPTION_INIT (
  E_LATE_VALIDATE,                                      -45172        );
  E_LATE_VALIDATE_NUM                CONSTANT NUMBER := -45172;
 
  E_LATE_CHECKFILES                  EXCEPTION; PRAGMA EXCEPTION_INIT (
  E_LATE_CHECKFILES,                                    -45173        );
  E_LATE_CHECKFILES_NUM              CONSTANT NUMBER := -45173;
 
  E_REPLICATION_ERROR                EXCEPTION; PRAGMA EXCEPTION_INIT (
  E_REPLICATION_ERROR,                                  -45174        );
  E_REPLICATION_ERROR_NUM            CONSTANT NUMBER := -45174;
 
  E_SBT_ERROR                        EXCEPTION; PRAGMA EXCEPTION_INIT (
  E_SBT_ERROR,                                          -45175        );
  E_SBT_ERROR_NUM                    CONSTANT NUMBER := -45175;
 
  E_MISSING_POLL_FILE                EXCEPTION; PRAGMA EXCEPTION_INIT (
  E_MISSING_POLL_FILE,                                  -45177        );
  E_MISSING_POLL_FILE_NUM            CONSTANT NUMBER := -45177;
 
  E_LATE_RECONCILE                   EXCEPTION; PRAGMA EXCEPTION_INIT (
  E_LATE_RECONCILE,                                     -45179        );
  E_LATE_RECONCILE_NUM               CONSTANT NUMBER := -45179;
 
  E_LATE_CROSSCHECK                  EXCEPTION; PRAGMA EXCEPTION_INIT (
  E_LATE_CROSSCHECK,                                    -45180        );
  E_LATE_CROSSCHECK_NUM              CONSTANT NUMBER := -45180;
 
  E_DUP_FILE                         EXCEPTION; PRAGMA EXCEPTION_INIT (
  E_DUP_FILE,                                           -45181        );
  E_DUP_FILE_NUM                     CONSTANT NUMBER := -45181;
 
  E_FAILED                           EXCEPTION; PRAGMA EXCEPTION_INIT (
  E_FAILED,                                             -45186        );
  E_FAILED_NUM                       CONSTANT NUMBER := -45186;
 
  E_SL_REBUILD_FATAL_NUM             CONSTANT NUMBER := -45187;
  E_SL_REBUILD_RECOVERABLE_NUM       CONSTANT NUMBER := -45188;
  E_SL_RENAME_NUM                    CONSTANT NUMBER := -45189;
 
  E_SBT_LIB_NOT_AVAIL_NUM            CONSTANT NUMBER := -45191;
  E_SBT_LIB_RESERV_EXISTS_NUM        CONSTANT NUMBER := -45192;
  E_SBT_MULT_LIB_EXISTS_NUM          CONSTANT NUMBER := -45193;
  E_BA_METADATABCK_FAIL_NUM          CONSTANT NUMBER := -45194;
  E_SBT_LIB_RES_TIMED_OUT_NUM        CONSTANT NUMBER := -45195;
 
  E_SBT_LIB_UNRES_FAILED             EXCEPTION; PRAGMA EXCEPTION_INIT (
  E_SBT_LIB_UNRES_FAILED,                               -45196        );
  E_SBT_LIB_UNRES_FAILED_NUM         CONSTANT NUMBER := -45196;
 
  E_SBT_LIB_RES_NOT_FOUND_NUM        CONSTANT NUMBER := -45197;
  
  E_BA_TEST_RECV_FAIL_NUM            CONSTANT NUMBER := -45264;
  E_BA_BKP_HLTH_CHCK_FAIL_NUM        CONSTANT NUMBER := -45265;
  E_BA_DB_HLTH_CHCK_FAIL_NUM         CONSTANT NUMBER := -45266;
 
  E_SHUTTING_DOWN_NUM                CONSTANT NUMBER := -64700;
  E_SL_OUT_OF_SPACE_NUM              CONSTANT NUMBER := -64701;
  E_CONTAINER_REBUILD_ERROR_NUM      CONSTANT NUMBER := -64702;
  E_RESOURCE_ERROR_NUM               CONSTANT NUMBER := -64703;
  E_NEW_INC_ERROR_NUM                CONSTANT NUMBER := -64735;
  E_TOO_MANY_INTERRUPTS_NUM          CONSTANT NUMBER := -64736;
  E_REC_WINDOW_LOW_NUM               CONSTANT NUMBER := -64739;
  E_UNPROTECTED_WINDOW_LOST_NUM      CONSTANT NUMBER := -64740;
 
  E_SERVLET_ERROR                    EXCEPTION; PRAGMA EXCEPTION_INIT (
  E_SERVLET_ERROR,                                      -45201        );
  E_SERVLET_ERROR_NUM                CONSTANT NUMBER := -45201;
 
  E_FULL_BACKUP_NOT_FOUND            EXCEPTION; PRAGMA EXCEPTION_INIT (
  E_FULL_BACKUP_NOT_FOUND,                              -64737        );
  E_FULL_BACKUP_NOT_FOUND_NUM        CONSTANT NUMBER := -64737;
 
  E_GCOPY_SUSPENDED                  EXCEPTION; PRAGMA EXCEPTION_INIT (
  E_GCOPY_SUSPENDED,                                    -64738        );
  E_GCOPY_SUSPENDED_NUM              CONSTANT NUMBER := -64738;
 
  E_COULDNT_STOP_JOB_NUM             CONSTANT NUMBER := -64741;
 
  E_DELETE_DB_CHUNKS                 EXCEPTION; PRAGMA EXCEPTION_INIT (
  E_DELETE_DB_CHUNKS,                                   -64743        );
  E_DELETE_DB_CHUNKS_NUM             CONSTANT NUMBER := -64743;
 
  E_DBFS_WAIT_FAILURE                EXCEPTION; PRAGMA EXCEPTION_INIT (
  E_DBFS_WAIT_FAILURE,                                  -64750        );
  E_DBFS_WAIT_FAILURE_NUM            CONSTANT NUMBER := -64750;
 
  E_SBT_TASK_NOT_FOUND               CONSTANT NUMBER := -45216;
 
  E_BACKUP_FAILED                    CONSTANT NUMBER := -64752;
 
  E_BAD_RESTORE                      EXCEPTION; PRAGMA EXCEPTION_INIT (
  E_BAD_RESTORE,                                        -64757        );
  E_BAD_RESTORE_NUM                  CONSTANT NUMBER := -64757;
 
  E_POOL_FULL                        EXCEPTION; PRAGMA EXCEPTION_INIT (
  E_POOL_FULL,                                          -64758        );
  E_POOL_FULL_NUM                    CONSTANT NUMBER := -64758;
 
  E_END_RESOURCE_WAIT                EXCEPTION; PRAGMA EXCEPTION_INIT (
  E_END_RESOURCE_WAIT,                                  -64759        );
  E_END_RESOURCE_WAIT_NUM            CONSTANT NUMBER := -64759;
 
  E_ORDERING_WAIT                    EXCEPTION; PRAGMA EXCEPTION_INIT (
  E_ORDERING_WAIT,                                      -64760        );
  E_ORDERING_WAIT_NUM                CONSTANT NUMBER := -64760;
 
  E_CANCELED                         EXCEPTION; PRAGMA EXCEPTION_INIT (
  E_CANCELED,                                           -64756        );
  E_CANCELED_NUM                     CONSTANT NUMBER := -64756;
 
END dbms_ra_scheduler;
>>>
 
define dbmsrssm_plb
<<<
CREATE OR REPLACE PACKAGE dbms_ra_storage AS
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
 
--
  PROCEDURE copy_piece(p_fname  IN  VARCHAR2 DEFAULT NULL,
                       p_db_key IN  NUMBER DEFAULT NULL,
                       p_action IN  NUMBER DEFAULT 0);
 
--
  PROCEDURE move_all_db;
 
--
  PROCEDURE  move_database_metadata (p_db_key IN NUMBER,
                                     p_old_sl_key IN NUMBER,
                                     p_sl_key IN NUMBER);  
 
--
  FUNCTION freespace (p_sl_key IN NUMBER) RETURN NUMBER;
 
--
  PROCEDURE purge_database         (p_db_key IN NUMBER,
                                    p_sl_key IN NUMBER DEFAULT NULL,
                                    p_inline IN BOOLEAN DEFAULT FALSE);
 
--
  PROCEDURE allocate_backup_piece_name(
                        p_db_id     IN NUMBER,
                        p_piecename IN VARCHAR2,
                        p_fincarn   IN VARCHAR2);
 
--
  PROCEDURE allocate_backup_piece(
                        p_piecename IN VARCHAR2,
                        p_fincarn   IN VARCHAR2,
                        p_filesize  IN NUMBER,
                        p_ct_key   OUT NUMBER);
 
--
  PROCEDURE name_backup_piece(
                      p_ct_key       IN NUMBER,
                      p_filename     IN VARCHAR2);
 
--
  PROCEDURE finish_backup_piece(
                        p_db_key       IN NUMBER,
                        p_handle       IN VARCHAR2,
                        p_pieceinc     IN VARCHAR2,
                        p_ct_key       IN NUMBER);
 
--
  PROCEDURE finish_file(p_newfname IN  VARCHAR2,
                        p_filesize IN  NUMBER,
                        p_handle   OUT VARCHAR2,
                        p_move_bp  OUT NUMBER);
 
 
--
  PROCEDURE swap_backup_piece(p_bpkey      IN NUMBER);
 
--
  PROCEDURE free_backup_piece(
                        p_dbkey     IN NUMBER,
                        p_piecename IN VARCHAR2,
                        p_ftype     IN NUMBER   DEFAULT NULL,
                        p_fincarn   IN VARCHAR2 DEFAULT NULL,
                        p_can_defer IN BOOLEAN  DEFAULT FALSE);
 
--
--
  PROCEDURE free_backup_piece_opt(
                            p_dbkey      IN NUMBER,
                            p_piecename  IN VARCHAR2,
                            p_db_slkey   IN NUMBER,
                            p_dbid       IN NUMBER,
                            p_currinc    IN NUMBER,
                            p_bpkey      IN NUMBER,
                            p_ftype      IN NUMBER    DEFAULT NULL,
                            p_fincarn    IN VARCHAR2  DEFAULT NULL,
                            p_libkey     IN NUMBER    DEFAULT NULL,
                            p_spawn_job  IN BOOLEAN   DEFAULT TRUE,
                            p_notasks    IN BOOLEAN   DEFAULT FALSE,
                            p_noplans    IN BOOLEAN   DEFAULT FALSE);
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
   
--
  FUNCTION get_chunkno(
                        p_df_key    IN NUMBER,
                        p_count     IN NUMBER DEFAULT 1) RETURN NUMBER;
 
--
  PROCEDURE preallocate_chunks(
                        p_db_key    IN NUMBER,
                        p_count     IN NUMBER,
                        p_required  IN BOOLEAN DEFAULT FALSE);
 
--
  PROCEDURE allocate_block_pool_chunk(
                        p_db_key    IN NUMBER,
                        p_dbinc_key IN NUMBER,
                        p_df_key    IN NUMBER,
                        p_vb_key    IN NUMBER,
                        p_chunkno  OUT NUMBER);
 
--
  PROCEDURE free_block_pool_chunk(
                        p_db_key    IN NUMBER,
                        p_dbinc_key IN NUMBER,
                        p_df_key    IN NUMBER,
                        p_chunkno   IN NUMBER);
 
--
  PROCEDURE free_block_pool_chunks(
                        p_sl_key    IN NUMBER,
                        p_db_key    IN NUMBER,
                        p_df_key    IN NUMBER,
                        p_chunks    IN dbms_sql.number_table);
 
--
  PROCEDURE free_task_storage (p_task_id NUMBER DEFAULT NULL);
 
--
  FUNCTION reserve_block_pool_space(
                        p_db_key   IN NUMBER,
                        p_chunks   IN NUMBER,
                        p_maxchunks OUT NUMBER) RETURN NUMBER;
 
--
  PROCEDURE finish_block_pool_chunk(
                        p_db_key    IN NUMBER);
 
--
 
  PROCEDURE purge_storage_location (p_sl_key      IN NUMBER,
                                    p_db_key      IN NUMBER,
                                    p_spaceneed   IN NUMBER,
                                    p_immediate   IN BOOLEAN);
 
--
  PROCEDURE backupArch(p_dbkey    IN NUMBER,
                       p_fname    IN VARCHAR2,
                       p_complete IN BOOLEAN,
                       p_delete   IN BOOLEAN DEFAULT TRUE);
 
--
  PROCEDURE trim_database_for_move (p_db_key IN NUMBER, p_alloc IN NUMBER);
 
--
  PROCEDURE  trim_database_as_job (p_db_key IN NUMBER,
                                   p_sl_key IN NUMBER,
                                   p_allocation IN NUMBER);
 
--
  PROCEDURE check_files (p_sl_key            IN  NUMBER,
                         p_execute_time      IN  TIMESTAMP WITH TIME ZONE,
                         p_savepoint         IN  NUMBER,
                         p_repair            IN  BOOLEAN);
 
--
  PROCEDURE lock_db (p_db_key IN NUMBER);
 
--
  PROCEDURE unlock_db (p_db_key IN NUMBER);
 
--
  PROCEDURE lock_sl (p_sl_key IN NUMBER);
 
--
  PROCEDURE unlock_sl (p_sl_key IN NUMBER);
 
--
  PROCEDURE setTracing(p_trc_on IN NUMBER,
                       p_perf_on IN NUMBER DEFAULT 0,
                       p_stall_on IN NUMBER DEFAULT 0,
                       p_safe_mode IN NUMBER DEFAULT 0);
 
END dbms_ra_storage;
>>>
 
define dbmsrs_plb
<<<
CREATE OR REPLACE PACKAGE dbms_ra IS
--
 
--
--
--
 
 
--
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
 
--
--
--
 
--
--
--
 
--
--
--
--
 
--
--
 
--
--
--
--
--
--
--
--
--
--
 
--
--
 
--
 
--
 
--
--
--
--
--
--
 
--
--
--
 
--
--
--
 
--
--
--
 
--
 
--
--
--
--
--
 
--
--
--
--
--
--
--
--
 
--
  BA_STORAGE_DISK        CONSTANT NUMBER := 1;
  BA_STORAGE_HTTP        CONSTANT NUMBER := 2;
  BA_STORAGE_NFS_ORACLE  CONSTANT NUMBER := 3;
 
  PROCEDURE startup;
 
--
 
  PROCEDURE startup_recovery_appliance;
 
--
 
--
--
 
--
--
--
--
--
--
--
--
 
  PROCEDURE shutdown;
 
--
 
  PROCEDURE shutdown_recovery_appliance;
 
--
 
--
--
--
--
 
  PROCEDURE abort;
 
--
 
  PROCEDURE abort_recovery_appliance;
 
--
--
 
--
--
--
--
--
--
--
 
  PROCEDURE create_storage_location (
     storage_location_name  IN VARCHAR2,
     storage_location_dests  IN VARCHAR2);
 
--
--
--
 
--
--
 
--
--
 
--
 
--
 
--
 
--
--
--
--
--
 
--
 
--
 
--
 
--
 
--
--
--
--
--
 
--
--
 
--
 
--
--
--
 
--
 
  PROCEDURE delete_storage_location (
     storage_location_name IN VARCHAR2);
 
--
 
--
--
--
--
--
 
--
 
--
 
  PROCEDURE update_storage_location (
     storage_location_name  IN VARCHAR2,
     storage_location_dests IN VARCHAR2 DEFAULT NULL);
 
--
--
--
 
--
 
--
 
--
 
--
--
--
--
 
--
--
--
--
--
--
--
--
--
--
 
--
--
--
 
--
--
--
--
 
--
--
--
--
--
--
 
 
  PROCEDURE add_db (
     db_unique_name         IN VARCHAR2,
     protection_policy_name IN VARCHAR2,
     reserved_space         IN VARCHAR2);
 
--
--
--
--
 
--
--
--
--
--
 
--
--
--
--
 
--
 
--
 
--
 
--
--
 
--
 
--
--
 
--
--
--
 
--
 
--
 
--
 
--
 
--
 
--
 
--
 
--
 
--
 
 
  PROCEDURE update_db (
     db_unique_name         IN VARCHAR2,
     protection_policy_name IN VARCHAR2 DEFAULT NULL,
     reserved_space         IN VARCHAR2 DEFAULT NULL,
     db_timezone            IN VARCHAR2 DEFAULT NULL,
     incarnations           IN VARCHAR2 DEFAULT  'CURRENT');
 
--
 
--
 
--
 
--
 
--
--
 
--
--
--
--
--
 
--
--
--
 
--
--
 
--
  
--
  
--
 
--
--
--
--
--
 
--
 
--
--
--
--
--
--
--
 
  PROCEDURE delete_db (
     db_unique_name IN VARCHAR2,
     wait           IN BOOLEAN DEFAULT TRUE);
 
--
--
--
 
--
--
--
--
--
--
--
--
--
--
 
--
 
--
 
--
 
--
--
--
--
--
 
  PROCEDURE rename_db (
     db_unique_name_old IN VARCHAR2,
     db_unique_name_new IN VARCHAR2);
 
--
--
 
--
--
--
 
--
 
--
 
--
 
--
 
 
  PROCEDURE create_protection_policy (
     protection_policy_name   IN VARCHAR2,
     description              IN VARCHAR2 DEFAULT NULL,
     storage_location_name    IN VARCHAR2,
     polling_policy_name      IN VARCHAR2 DEFAULT NULL,
     recovery_window_goal     IN DSINTERVAL_UNCONSTRAINED,
     max_retention_window     IN DSINTERVAL_UNCONSTRAINED DEFAULT NULL,
     recovery_window_sbt      IN DSINTERVAL_UNCONSTRAINED DEFAULT NULL,
     unprotected_window       IN DSINTERVAL_UNCONSTRAINED DEFAULT NULL,
     guaranteed_copy          IN VARCHAR2 DEFAULT 'NO');
 
--
 
--
 
--
 
--
 
--
 
--
 
--
--
--
--
--
 
--
 
--
--
--
--
 
--
 
--
--
--
--
--
 
--
--
--
 
--
 
--
--
--
--
--
--
 
--
 
--
--
--
--
--
 
--
--
--
--
 
--
--
--
 
--
 
--
--
--
--
--
--
 
--
--
--
  
--
 
--
--
--
--
--
--
 
--
--
--
--
--
 
--
--
--
--
--
--
 
 
 
--
 
--
--
--
--
 
--
--
--
--
--
--
 
  PROCEDURE update_protection_policy (
     protection_policy_name   IN VARCHAR2,
     description              IN VARCHAR2 DEFAULT NULL,
     storage_location_name    IN VARCHAR2 DEFAULT NULL,
     polling_policy_name      IN VARCHAR2 
                                 DEFAULT dbms_ra_int.varchar2null('p1'),
     recovery_window_goal     IN DSINTERVAL_UNCONSTRAINED DEFAULT NULL,
     max_retention_window     IN DSINTERVAL_UNCONSTRAINED
                                 DEFAULT dbms_ra_int.intervalnull('p3'),
     recovery_window_sbt      IN DSINTERVAL_UNCONSTRAINED
                                 DEFAULT dbms_ra_int.intervalnull('p2'),
     unprotected_window       IN DSINTERVAL_UNCONSTRAINED
                                 DEFAULT dbms_ra_int.intervalnull('p4'),
     guaranteed_copy          IN VARCHAR2 DEFAULT NULL);
 
--
 
--
--
 
--
  
--
  
--
 
--
 
--
  
--
 
--
--
--
 
--
  
--
 
--
--
  
--
 
--
 
--
 
--
 
--
--
--
  
--
 
--
  
--
--
 
--
 
--
--
 
--
 
--
  
--
 
  
  PROCEDURE delete_protection_policy (
     protection_policy_name IN VARCHAR2);
 
--
 
--
 
--
 
--
  
  PROCEDURE add_replication_server (
     replication_server_name IN VARCHAR2,
     protection_policy_name  IN VARCHAR2);
 
--
--
--
--
 
--
 
--
 
--
  
--
 
--
  
  
  PROCEDURE remove_replication_server (
     replication_server_name IN VARCHAR2,
     protection_policy_name  IN VARCHAR2);
 
--
--
--
--
--
 
--
 
--
  
--
 
--
--
  
  PROCEDURE create_polling_policy(
     polling_policy_name   IN VARCHAR2,
     polling_location      IN VARCHAR2,
     polling_frequency     IN DSINTERVAL_UNCONSTRAINED DEFAULT NULL,
     delete_input          IN BOOLEAN DEFAULT FALSE);
 
--
 
--
--
--
--
 
--
--
--
--
--
--
 
--
 
--
 
--
 
--
--
--
 
--
 
--
--
 
--
--
 
--
 
--
--
--
--
--
 
  PROCEDURE update_polling_policy (
     polling_policy_name   IN VARCHAR2,
     polling_location      IN VARCHAR2 DEFAULT NULL,
     polling_frequency     IN DSINTERVAL_UNCONSTRAINED DEFAULT NULL,
     delete_input          IN BOOLEAN DEFAULT NULL);
 
--
 
--
 
--
  
--
  
--
  
--
  
--
  
--
  
--
  
--
 
  PROCEDURE delete_polling_policy (
     polling_policy_name IN VARCHAR2);
 
--
 
--
  
--
 
  PROCEDURE create_sbt_library (
     lib_name       IN VARCHAR2,
     drives         IN NUMBER,
     restore_drives IN NUMBER   DEFAULT 0,
     parms          IN VARCHAR2 DEFAULT NULL,
     send           IN VARCHAR2 DEFAULT NULL);
 
--
--
--
--
 
--
 
--
--
 
--
 
--
--
--
 
--
 
--
--
 
--
--
--
--
 
--
--
--
 
--
 
--
--
--
--
 
--
 
--
--
--
--
 
 
  PROCEDURE update_sbt_library (
     lib_name       IN VARCHAR2,
     drives         IN NUMBER   DEFAULT NULL,
     restore_drives IN NUMBER   DEFAULT NULL,
     parms          IN VARCHAR2 DEFAULT dbms_ra_int.varchar2null('p1'),
     send           IN VARCHAR2 DEFAULT dbms_ra_int.varchar2null('p2'));
 
--
 
--
--
 
--
 
--
  
--
  
--
  
--
  
--
 
--
  
--
    
--
--
 
--
  
--
 
--
--
 
  PROCEDURE delete_sbt_library (lib_name IN VARCHAR2);
 
--
 
--
--
 
--
 
--
  
--
 
  PROCEDURE pause_sbt_library(
     lib_name      IN VARCHAR2);
 
--
--
--
--
--
 
--
 
--
 
--
 
 
  PROCEDURE resume_sbt_library(
     lib_name      IN VARCHAR2);
 
--
 
--
--
 
--
 
--
 
  PROCEDURE set_restrict_sbt_instance (
     lib_name      IN VARCHAR2,
     instance_name IN VARCHAR2);
 
--
 
--
--
 
--
--
--
--
--
--
 
--
 
--
 
--
 
--
 
--
--
 
  PROCEDURE clear_restrict_sbt_instance (
     lib_name      IN VARCHAR2,
     instance_name IN VARCHAR2);
 
--
 
--
--
 
--
 
--
 
--
 
--
 
--
--
 
  PROCEDURE create_sbt_attribute_set(
     lib_name             IN VARCHAR2,
     attribute_set_name   IN VARCHAR2,
     streams              IN NUMBER   DEFAULT NULL,
     poolid               IN NUMBER   DEFAULT NULL,
     parms                IN VARCHAR2 DEFAULT NULL,
     send                 IN VARCHAR2 DEFAULT NULL);
 
--
 
--
--
--
--
--
 
--
 
--
 
--
 
--
--
 
--
 
--
--
--
--
--
 
--
 
--
--
--
 
--
 
--
--
--
--
--
--
 
--
 
--
--
--
--
--
--
--
 
  PROCEDURE update_sbt_attribute_set(
     attribute_set_name IN VARCHAR2,
     streams            IN NUMBER   DEFAULT dbms_ra_int.number2null('p1'),
     poolid             IN NUMBER   DEFAULT NULL,
     parms              IN VARCHAR2 DEFAULT dbms_ra_int.varchar2null('p2'),
     send               IN VARCHAR2 DEFAULT dbms_ra_int.varchar2null('p3'));
 
--
 
--
--
 
--
 
--
 
--
 
--
 
--
--
 
--
 
--
 
--
 
--
 
--
--
 
--
 
--
 
--
--
 
  PROCEDURE delete_sbt_attribute_set(
     attribute_set_name IN VARCHAR2);
 
--
 
--
 
--
 
 
--
  SBT_PRIORITY_LOW      CONSTANT NUMBER := 1000;
  SBT_PRIORITY_MEDIUM   CONSTANT NUMBER := 100;
  SBT_PRIORITY_HIGH     CONSTANT NUMBER := 10;
  SBT_PRIORITY_CRITICAL CONSTANT NUMBER := 1;
 
  PROCEDURE create_sbt_job_template (
     template_name          IN VARCHAR2,
     protection_policy_name IN VARCHAR2,
     attribute_set_name     IN VARCHAR2,
     backup_type            IN VARCHAR2,
     full_template_name     IN VARCHAR2    DEFAULT NULL,
     from_tag               IN VARCHAR2    DEFAULT NULL,
     priority               IN NUMBER      DEFAULT SBT_PRIORITY_MEDIUM,
     copies                 IN NUMBER      DEFAULT 1,
     window                 IN DSINTERVAL_UNCONSTRAINED DEFAULT NULL);
 
--
--
--
--
--
 
--
--
--
 
--
 
--
 
--
 
--
--
--
 
--
 
--
 
--
 
--
--
 
--
 
--
--
 
--
--
 
--
--
--
--
--
 
--
 
--
--
--
--
--
--
--
--
--
--
 
--
  
--
--
 
--
 
--
--
--
--
 
--
 
--
 
--
 
--
 
--
--
 
--
 
--
--
 
--
 
--
--
--
 
  PROCEDURE create_sbt_job_template (
     template_name      IN VARCHAR2,
     db_unique_name     IN VARCHAR2,
     attribute_set_name IN VARCHAR2,
     backup_type        IN VARCHAR2,
     full_template_name IN VARCHAR2    DEFAULT NULL,
     from_tag           IN VARCHAR2    DEFAULT NULL,
     priority           IN NUMBER      DEFAULT SBT_PRIORITY_MEDIUM,
     copies             IN NUMBER      DEFAULT 1,
     window             IN DSINTERVAL_UNCONSTRAINED DEFAULT NULL);
 
--
--
--
--
--
--
--
 
--
 
--
--
--
 
  PROCEDURE update_sbt_job_template (
     template_name      IN VARCHAR2,
     attribute_set_name IN VARCHAR2               DEFAULT NULL,
     backup_type        IN VARCHAR2               DEFAULT NULL,
     from_tag           IN VARCHAR2               DEFAULT
        dbms_ra_int.varchar2null('p1'),
     priority           IN NUMBER                 DEFAULT NULL,
     copies             IN NUMBER                 DEFAULT NULL,
     window             IN DSINTERVAL_UNCONSTRAINED DEFAULT
        dbms_ra_int.intervalnull('p2'));
 
--
 
--
--
 
--
  
--
 
--
 
--
 
--
  
--
 
--
  
--
 
--
--
 
--
 
--
 
--
 
--
 
--
 
--
 
--
--
 
  PROCEDURE delete_sbt_job_template (
     template_name IN VARCHAR2);
 
--
 
--
 
--
--
 
 
--
  RESERVE_BACKUP_TYPE CONSTANT NUMBER := 32; 
 
  PROCEDURE queue_sbt_backup_task(
     template_name IN VARCHAR2);
 
--
--
--
 
--
  
--
--
--
  
  PROCEDURE abort_sbt_task(
     task_id       IN NUMBER);
--
 
--
 
--
 
--
 
  PROCEDURE config(p_name  VARCHAR2,
                   p_value VARCHAR2);
 
--
 
--
--
 
--
--
 
  PROCEDURE create_replication_server (
     replication_server_name    IN VARCHAR2,
     sbt_so_name                IN VARCHAR2,
     sbt_parms                  IN VARCHAR2  DEFAULT NULL,
     max_streams                IN NUMBER    DEFAULT NULL,
     catalog_user_name          IN VARCHAR2,
     wallet_alias               IN VARCHAR2,
     wallet_path                IN VARCHAR2,
     proxy_url                  IN VARCHAR2  DEFAULT NULL,
     proxy_port                 IN NUMBER    DEFAULT NULL,
     http_timeout               IN NUMBER    DEFAULT NULL);
 
--
--
 
--
--
--
--
--
--
 
--
  
--
 
--
 
--
--
--
--
 
--
 
--
--
--
--
 
--
--
 
--
--
 
--
 
--
--
 
--
 
--
--
--
 
--
 
--
--
--
 
--
 
--
--
--
 
--
  
--
  
--
  
--
  
--
  
--
  
--
 
--
--
--
 
  PROCEDURE update_replication_server (
     replication_server_name    IN VARCHAR2,
     sbt_so_name            IN VARCHAR2  DEFAULT NULL,
     sbt_parms              IN VARCHAR2  DEFAULT NULL,
     max_streams            IN NUMBER    DEFAULT
                                         dbms_ra_int.number2null('p4'),
     catalog_user_name      IN VARCHAR2  DEFAULT NULL,
     wallet_alias           IN VARCHAR2  DEFAULT NULL,
     wallet_path            IN VARCHAR2  DEFAULT dbms_ra_int.varchar2null('p1'),
     proxy_url              IN VARCHAR2  DEFAULT dbms_ra_int.varchar2null('p2'),
     proxy_port             IN NUMBER    DEFAULT dbms_ra_int.number2null('p3'),
     http_timeout           IN NUMBER    DEFAULT NULL);
 
--
 
--
 
--
--
--
--
 
--
--
--
 
--
--
 
--
 
--
 
--
 
--
 
--
 
--
 
--
 
--
 
--
--
 
--
 
--
 
--
 
--
 
--
 
--
 
--
--
 
--
 
--
 
--
--
 
--
 
--
 
--
--
 
--
 
--
  
  PROCEDURE delete_replication_server (replication_server_name IN VARCHAR2,
                                       force IN BOOLEAN DEFAULT FALSE);
  
--
--
  
--
  
--
  
--
 
--
--
--
--
--
--
 
  PROCEDURE pause_replication_server  (replication_server_name IN VARCHAR2);
  
--
 
--
--
--
--
--
--
--
 
--
  
--
  
  
  PROCEDURE resume_replication_server (replication_server_name IN VARCHAR2);
 
--
--
 
--
  
--
  
  PROCEDURE grant_db_access (username       IN VARCHAR2, 
                             db_unique_name IN VARCHAR2);
 
--
--
--
--
 
--
  
--
 
--
 
--
 
  PROCEDURE revoke_db_access (username       IN VARCHAR2,
                              db_unique_name IN VARCHAR2);
 
--
--
 
--
  
--
 
--
 
--
 
  PROCEDURE populate_backup_piece(backup_piece_key IN NUMBER);
 
--
 
--
--
--
--
--
 
--
 
--
--
--
--
--
--
--
 
  PROCEDURE copy_backup (tag               IN VARCHAR2,
                         format            IN VARCHAR2,
                         template_name     IN VARCHAR2);
  
--
--
--
--
 
--
 
--
  
--
 
--
--
  
--
 
--
 
--
--
--
  
  PROCEDURE copy_backup_piece (bp_key            IN NUMBER, 
                               format            IN VARCHAR2,
                               template_name     IN VARCHAR2);
 
--
--
 
--
 
--
--
 
--
 
--
--
  
--
 
--
 
--
--
--
  
  PROCEDURE move_backup (tag               IN VARCHAR2,
                         format            IN VARCHAR2,
                         template_name     IN VARCHAR2);
  
--
--
 
--
--
--
--
 
--
 
--
  
--
 
--
--
  
--
 
--
 
--
--
--
  
  PROCEDURE move_backup_piece (bp_key            IN NUMBER, 
                               format            IN VARCHAR2,
                               template_name     IN VARCHAR2);
 
--
--
 
--
--
--
--
  
--
 
--
--
  
--
 
--
--
  
--
 
--
 
--
--
--
 
 
  PROCEDURE migrate_tape_backup(db_unique_name IN VARCHAR2,
                                sbt_lib_name   IN VARCHAR2);
 
--
--
--
--
--
 
--
--
--
--
--
 
--
 
--
--
--
--
 
--
 
--
--
 
  PROCEDURE reset_error(incident# IN NUMBER);
 
--
--
--
--
--
--
--
 
--
 
--
--
 
  PROCEDURE repair_storage_location (
     storage_location_name    IN VARCHAR2,
     repair_type              IN VARCHAR2);
--
--
 
  FUNCTION estimate_space (
     db_unique_name      IN VARCHAR2,
     target_window       IN DSINTERVAL_UNCONSTRAINED)  RETURN NUMBER;
--
--
 
  PROCEDURE dump (do_dpdump BOOLEAN DEFAULT FALSE);
--
--
  
  
--
--
--
--
--
--
 
--
  UNKNOWN_OPERATION_PRVLG       EXCEPTION; PRAGMA EXCEPTION_INIT (
  UNKNOWN_OPERATION_PRVLG,                         -45119        );
  UNKNOWN_OPERATION_PRVLG_NUM   CONSTANT NUMBER := -45119;
 
--
  SPACE_QUOTA_VIOLATION         EXCEPTION; PRAGMA EXCEPTION_INIT (
  SPACE_QUOTA_VIOLATION,                           -45120        );
  SPACE_QUOTA_VIOLATION_NUM     CONSTANT NUMBER := -45120;
 
--
  UNKNOWN_MANAGE_PRVLG_PARAM    EXCEPTION; PRAGMA EXCEPTION_INIT (
  UNKNOWN_MANAGE_PRVLG_PARAM,                       -45121       );
  UNKNOWN_MANAGE_PRVLG_PARAM_NUM CONSTANT NUMBER := -45121;
 
--
  INVALID_SIZENUMBER            EXCEPTION; PRAGMA EXCEPTION_INIT (
  INVALID_SIZENUMBER,                              -45122        );
  INVALID_SIZENUMBER_NUM        CONSTANT NUMBER := -45122;
 
--
  DUP_NAME                      EXCEPTION; PRAGMA EXCEPTION_INIT (
  DUP_NAME,                                        -45123        );
  DUP_NAME_NUM                  CONSTANT NUMBER := -45123;
 
--
  OBJ_IS_REFERENCED             EXCEPTION; PRAGMA EXCEPTION_INIT (
  OBJ_IS_REFERENCED,                               -45124        );
  OBJ_IS_REFERENCED_NUM         CONSTANT NUMBER := -45124;
 
--
  OBJ_NOT_FOUND                 EXCEPTION; PRAGMA EXCEPTION_INIT (
  OBJ_NOT_FOUND,                                   -45125        );
  OBJ_NOT_FOUND_NUM             CONSTANT NUMBER := -45125;
 
--
  CANT_DELETE_DB                EXCEPTION; PRAGMA EXCEPTION_INIT (
  CANT_DELETE_DB,                                  -45126        );
  CANT_DELETE_DB_NUM            CONSTANT NUMBER := -45126;
 
--
  E_INTERNAL_ERROR              EXCEPTION; PRAGMA EXCEPTION_INIT (
  E_INTERNAL_ERROR,                                -45113        );
  E_INTERNAL_ERROR_NUM          CONSTANT NUMBER := -45113;
 
--
  MISSING_PARAM                 EXCEPTION; PRAGMA EXCEPTION_INIT (
  MISSING_PARAM,                                   -45127        );
  MISSING_PARAM_NUM             CONSTANT NUMBER := -45127;
 
--
  E_SHARED_PARAMS               EXCEPTION; PRAGMA EXCEPTION_INIT (
  E_SHARED_PARAMS,                                 -45130        );
  E_SHARED_PARAMS_NUM           CONSTANT NUMBER := -45130;
 
--
  BAD_RECOMPR                   EXCEPTION; PRAGMA EXCEPTION_INIT (
  BAD_RECOMPR,                                     -45131        );
  BAD_RECOMPR_NUM               CONSTANT NUMBER := -45131;
 
--
  INVALID_VAL                   EXCEPTION; PRAGMA EXCEPTION_INIT (
  INVALID_VAL,                                     -45136        );
  INVALID_VAL_NUM               CONSTANT NUMBER := -45136;
 
--
  UNKNOWN_PLATFORM              EXCEPTION; PRAGMA EXCEPTION_INIT (
  UNKNOWN_PLATFORM,                                -45137        );
  UNKNOWN_PLATFORM_NUM          CONSTANT NUMBER := -45137;
 
--
  UNKNONW_BP                    EXCEPTION; PRAGMA EXCEPTION_INIT (
  UNKNONW_BP,                                      -45138        );
  UNKNONW_BP_NUM                CONSTANT NUMBER := -45138;
 
--
  NO_FIND_USEFUL_BP             EXCEPTION; PRAGMA EXCEPTION_INIT (
  NO_FIND_USEFUL_BP,                               -45139        );
  NO_FIND_USEFUL_BP_NUM         CONSTANT NUMBER := -45139;
 
--
  NO_INSERT_BP                  EXCEPTION; PRAGMA EXCEPTION_INIT (
  NO_INSERT_BP,                                    -45140        );
  NO_INSERT_BP_NUM              CONSTANT NUMBER := -45140;
  
--
  MISSING_INIT_REP_TYPE         EXCEPTION; PRAGMA EXCEPTION_INIT (
  MISSING_INIT_REP_TYPE,                           -45144        );
  MISSING_INIT_REP_TYPE_NUM     CONSTANT NUMBER := -45144;
 
--
  USER_NOT_FOUND                EXCEPTION; PRAGMA EXCEPTION_INIT (
  USER_NOT_FOUND,                                  -45145        );
  USER_NOT_FOUND_NUM            CONSTANT NUMBER := -45145;
  
--
  INVALID_PARAM                 EXCEPTION; PRAGMA EXCEPTION_INIT (
  INVALID_PARAM,                                   -45157        );
  INVALID_PARAM_NUM             CONSTANT NUMBER := -45157;
 
--
  BA_NOT_RUNNING_PARAM          EXCEPTION; PRAGMA EXCEPTION_INIT (
  BA_NOT_RUNNING_PARAM,                            -45164        );
  BA_NOT_RUNNING_PARAM_NUM      CONSTANT NUMBER := -45164;
 
--
  REP_SRVR_RUNNING              EXCEPTION; PRAGMA EXCEPTION_INIT (
  REP_SRVR_RUNNING,                                -45176        );
  REP_SRVR_RUNNING_NUM          CONSTANT NUMBER := -45176;
 
--
  BAD_AU_SIZE                   EXCEPTION; PRAGMA EXCEPTION_INIT (
  BAD_AU_SIZE,                                     -45178        );
  BAD_AU_SIZE_NUM               CONSTANT NUMBER := -45178;
 
--
  NOT_OAMADMIN                  EXCEPTION; PRAGMA EXCEPTION_INIT (
  NOT_OAMADMIN,                                    -45182        );
  NOT_OAMADMIN_NUM              CONSTANT NUMBER := -45182;
  
--
  API_BLOCKED_NUM               CONSTANT NUMBER := -45183;
 
--
  NOT_RA                        EXCEPTION; PRAGMA EXCEPTION_INIT (
  NOT_RA,                                          -45198        );
  NOT_RA_NUM                    CONSTANT NUMBER := -45198;
 
--
  USER_NOT_EXISTS               EXCEPTION; PRAGMA EXCEPTION_INIT (
  USER_NOT_EXISTS,                                 -45213        );
  USER_NOT_EXISTS_NUM           CONSTANT NUMBER := -45213;
 
--
  NUM_CONVERSION_ERROR          EXCEPTION; PRAGMA EXCEPTION_INIT (
  NUM_CONVERSION_ERROR,                            -45214        );
  NUM_CONVERSION_ERROR_NUM      CONSTANT NUMBER := -45214;
 
--
  REP_SERVER_ACTIVE             EXCEPTION; PRAGMA EXCEPTION_INIT (
  REP_SERVER_ACTIVE,                               -45215        );
  REP_SERVER_ACTIVE_NUM         CONSTANT NUMBER := -45215;
 
--
  SBT_TASK_NOT_FOUND           EXCEPTION; PRAGMA EXCEPTION_INIT (
  SBT_TASK_NOT_FOUND,                              -45217        );
  SBT_TASK_NOT_FOUND_NUM        CONSTANT NUMBER := -45217;
 
--
  CREATE_CONTAINER_FAILED       EXCEPTION; PRAGMA EXCEPTION_INIT (
  CREATE_CONTAINER_FAILED,                         -45276        );
  CREATE_CONTAINER_FAILED_NUM   CONSTANT NUMBER := -45276;
 
--
  UNBAL_PAREN                   EXCEPTION; PRAGMA EXCEPTION_INIT (
  UNBAL_PAREN,                                     -64704        );
  UNBAL_PAREN_NUM               CONSTANT NUMBER := -64704;
 
--
  NO_DEST                       EXCEPTION; PRAGMA EXCEPTION_INIT (
  NO_DEST,                                         -64705        );
  NO_DEST_NUM                   CONSTANT NUMBER := -64705;
 
--
  BAD_STORAGE_SIZE              EXCEPTION; PRAGMA EXCEPTION_INIT (
  BAD_STORAGE_SIZE,                                -64706        );
  BAD_STORAGE_SIZE_NUM          CONSTANT NUMBER := -64706;
 
--
  NO_STORAGE_SIZE               EXCEPTION; PRAGMA EXCEPTION_INIT (
  NO_STORAGE_SIZE,                                 -64707        );
  NO_STORAGE_SIZE_NUM           CONSTANT NUMBER := -64707;
 
--
  MULTIPLE_POLLING              EXCEPTION; PRAGMA EXCEPTION_INIT (
  MULTIPLE_POLLING,                                -64708        );
  MULTIPLE_POLLING_NUM          CONSTANT NUMBER := -64708;
 
--
  ASM_POLLING                   EXCEPTION; PRAGMA EXCEPTION_INIT (
  ASM_POLLING,                                     -64709        );
  ASM_POLLING_NUM               CONSTANT NUMBER := -64709;
 
--
--
  POLLING_SIZE                  EXCEPTION; PRAGMA EXCEPTION_INIT (
  POLLING_SIZE,                                    -64710        );
  POLLING_SIZE_NUM              CONSTANT NUMBER := -64710;
 
--
  MIXED_STORAGE_TYPES           EXCEPTION; PRAGMA EXCEPTION_INIT (
  MIXED_STORAGE_TYPES,                             -64711        );
  MIXED_STORAGE_TYPES_NUM       CONSTANT NUMBER := -64711;
 
--
  MULTIPLE_NON_ASM              EXCEPTION; PRAGMA EXCEPTION_INIT (
  MULTIPLE_NON_ASM,                                -64712        );
  MULTIPLE_NON_ASM_NUM          CONSTANT NUMBER := -64712;
 
--
  DEST_SIZE_TOO_SMALL           EXCEPTION; PRAGMA EXCEPTION_INIT (
  DEST_SIZE_TOO_SMALL,                             -64713        );
  DEST_SIZE_TOO_SMALL_NUM       CONSTANT NUMBER := -64713;
 
--
  DEST_SIZE_TOO_BIG             EXCEPTION; PRAGMA EXCEPTION_INIT (
  DEST_SIZE_TOO_BIG,                               -64714        );
  DEST_SIZE_TOO_BIG_NUM         CONSTANT NUMBER := -64714;
 
--
  REDUNDANCY_TYPE_BAD           EXCEPTION; PRAGMA EXCEPTION_INIT (
  REDUNDANCY_TYPE_BAD,                             -64715        );
  REDUNDANCY_TYPE_BAD_NUM       CONSTANT NUMBER := -64715;
 
--
--
  ALLOC_SIZE_DISCREPANCY        EXCEPTION; PRAGMA EXCEPTION_INIT (
  ALLOC_SIZE_DISCREPANCY,                          -64716        );
  ALLOC_SIZE_DISCREPANCY_NUM    CONSTANT NUMBER := -64716;
 
--
--
  NETCS_SIZE_DISCREPANCY        EXCEPTION; PRAGMA EXCEPTION_INIT (
  NETCS_SIZE_DISCREPANCY,                          -64717        );
  NETCS_SIZE_DISCREPANCY_NUM    CONSTANT NUMBER := -64717;
 
--
  ALLOC_SIZE_NOT_PWR_OF_2       EXCEPTION; PRAGMA EXCEPTION_INIT (
  ALLOC_SIZE_NOT_PWR_OF_2,                         -64718        );
  ALLOC_SIZE_NOT_PWR_OF_2_NUM   CONSTANT NUMBER := -64718;
 
--
  ALLOC_SIZE_TOO_SMALL          EXCEPTION; PRAGMA EXCEPTION_INIT (
  ALLOC_SIZE_TOO_SMALL,                            -64719        );
  ALLOC_SIZE_TOO_SMALL_NUM      CONSTANT NUMBER := -64719;
 
--
  CREATED_NO_CONTAINERS         EXCEPTION; PRAGMA EXCEPTION_INIT (
  CREATED_NO_CONTAINERS,                           -64720        );
  CREATED_NO_CONTAINERS_NUM     CONSTANT NUMBER := -64720;
 
--
  RSRVD_SPACE_TOO_SMALL         EXCEPTION; PRAGMA EXCEPTION_INIT (
  RSRVD_SPACE_TOO_SMALL,                           -64721        );
  RSRVD_SPACE_TOO_SMALL_NUM     CONSTANT NUMBER := -64721;
 
--
  NUM_DRIVES_TOO_SMALL          EXCEPTION; PRAGMA EXCEPTION_INIT (
  NUM_DRIVES_TOO_SMALL,                            -64722        );
  NUM_DRIVES_TOO_SMALL_NUM      CONSTANT NUMBER := -64722;
 
--
  NUM_RDRIVES_TOO_SMALL         EXCEPTION; PRAGMA EXCEPTION_INIT (
  NUM_RDRIVES_TOO_SMALL,                           -64723        );
  NUM_RDRIVES_TOO_SMALL_NUM     CONSTANT NUMBER := -64723;
 
--
  NUM_RDRIVES_TOO_LARGE         EXCEPTION; PRAGMA EXCEPTION_INIT (
  NUM_RDRIVES_TOO_LARGE,                           -64724        );
  NUM_RDRIVES_TOO_LARGE_NUM     CONSTANT NUMBER := -64724;
 
--
  NUM_STREAMS_TOO_SMALL         EXCEPTION; PRAGMA EXCEPTION_INIT (
  NUM_STREAMS_TOO_SMALL,                           -64725        );
  NUM_STREAMS_TOO_SMALL_NUM     CONSTANT NUMBER := -64725;
 
--
  NUM_STREAMS_TOO_LARGE         EXCEPTION; PRAGMA EXCEPTION_INIT (
  NUM_STREAMS_TOO_LARGE,                           -64726        );
  NUM_STREAMS_TOO_LARGE_NUM     CONSTANT NUMBER := -64726;
 
--
  BAD_NUM_COPIES                EXCEPTION; PRAGMA EXCEPTION_INIT (
  BAD_NUM_COPIES,                                  -64727        );
  BAD_NUM_COPIES_NUM            CONSTANT NUMBER := -64727;
 
--
  REP_SRVR_NM_BAD_LEN           EXCEPTION; PRAGMA EXCEPTION_INIT (
  REP_SRVR_NM_BAD_LEN,                             -64728        );
  REP_SRVR_NM_BAD_LEN_NUM       CONSTANT NUMBER := -64728;
 
--
  REP_SRVR_BAD_PORT             EXCEPTION; PRAGMA EXCEPTION_INIT (
  REP_SRVR_BAD_PORT,                               -64729        );
  REP_SRVR_BAD_PORT_NUM         CONSTANT NUMBER := -64729;
 
--
  REP_SRVR_PORT_NULL            EXCEPTION; PRAGMA EXCEPTION_INIT (
  REP_SRVR_PORT_NULL,                              -64730        );
  REP_SRVR_PORT_NULL_NUM        CONSTANT NUMBER := -64730;
 
--
  REP_SRVR_PROXY_NULL           EXCEPTION; PRAGMA EXCEPTION_INIT (
  REP_SRVR_PROXY_NULL,                             -64731        );
  REP_SRVR_PROXY_NULL_NUM       CONSTANT NUMBER := -64731;
 
--
  REP_SRVR_HOST_NOT_CONFIG      EXCEPTION; PRAGMA EXCEPTION_INIT (
  REP_SRVR_HOST_NOT_CONFIG,                        -64732        );
  REP_SRVR_HOST_NOT_CONFIG_NUM  CONSTANT NUMBER := -64732;
 
--
  COPY_MOVE_NOT_KEEP            EXCEPTION; PRAGMA EXCEPTION_INIT (
  COPY_MOVE_NOT_KEEP,                              -64733        );
  COPY_MOVE_NOT_KEEP_NUM        CONSTANT NUMBER := -64733;
 
--
  SMALL_CG_FILE_SIZE            EXCEPTION; PRAGMA EXCEPTION_INIT (
  SMALL_CG_FILE_SIZE,                              -64734        );
  SMALL_CG_FILE_SIZE_NUM        CONSTANT NUMBER := -64734;
 
--
  CANT_DELETE_DB_RUNNING        EXCEPTION; PRAGMA EXCEPTION_INIT (
  CANT_DELETE_DB_RUNNING,                          -64742        );
  CANT_DELETE_DB_RUNNING_NUM    CONSTANT NUMBER := -64742;
 
--
  REP_SETUP_ERROR               EXCEPTION; PRAGMA EXCEPTION_INIT (
  REP_SETUP_ERROR,                                 -64751        );
  REP_SETUP_ERROR_NUM           CONSTANT NUMBER := -64751;
 
--
  API_BAD_OBJECT               EXCEPTION; PRAGMA EXCEPTION_INIT (
  API_BAD_OBJECT,                                 -64753        );
  API_BAD_OBJECT_NUM           CONSTANT NUMBER := -64753;
 
--
  SL_REP_SBT_CONFLICT_ERROR     EXCEPTION; PRAGMA EXCEPTION_INIT (
  SL_REP_SBT_CONFLICT_ERROR,                       -64754        );
  SL_REP_SBT_CONFLICT_ERROR_NUM CONSTANT NUMBER := -64754;
 
--
  CANT_DELETE_DB_DOWN           EXCEPTION; PRAGMA EXCEPTION_INIT (
  CANT_DELETE_DB_DOWN,                             -64755        );
  CANT_DELETE_DB_DOWN_NUM       CONSTANT NUMBER := -64755;
 
--
  DISKGROUP_NOT_USABLE_NUM      CONSTANT NUMBER := -64761;
 
--
--
--
  LOCKAPI_CREATE        CONSTANT NUMBER := 1;
  LOCKAPI_READ          CONSTANT NUMBER := 2;
  LOCKAPI_MODIFY        CONSTANT NUMBER := 3;
  LOCKAPI_DELETE        CONSTANT NUMBER := 4;
 
END dbms_ra;
>>>
 
define dbmsrsdmp_plb
<<<
CREATE OR REPLACE PACKAGE dbms_ra_dump IS
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
 
PROCEDURE dumper (ospid        IN VARCHAR2,
                  quiesce      IN BOOLEAN DEFAULT FALSE,
                  datapumpdump IN BOOLEAN DEFAULT TRUE);
END dbms_ra_dump;
>>>
 
define dbmsrspl_plb
<<<
CREATE OR REPLACE PACKAGE dbms_ra_pool AS
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
 
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
 
 
 
/*-------------------*
 * Package Constants *
 *-------------------*/
--
--
  AM_DEBUG_ON        CONSTANT NUMBER := 1;  -- Always on, for exeptions only
  AM_DEBUG_LOW       CONSTANT NUMBER := 2;  -- Odd and rare conditions
  AM_DEBUG_MED       CONSTANT NUMBER := 3;  -- Common, but not too wordy
  AM_DEBUG_HIGH      CONSTANT NUMBER := 4;  -- Everything worth showing.
  AM_DEBUG_OFF       CONSTANT NUMBER := 5;  -- Debug off
 
--
  KBRSOPER_CLSPOST   CONSTANT NUMBER := 1;  -- Post read, close file
  KBRSOPER_POST      CONSTANT NUMBER := 2;  -- Post a read
  KBRSOPER_RELEASE   CONSTANT NUMBER := 3;  -- Just release (only used in C)
  KBRSOPER_COPY      CONSTANT NUMBER := 4;  -- Copy some blocks
--
  KBRSOPER_DEL       CONSTANT NUMBER := 5;  -- Needed for delete plans
--
  KBRSOPER_NEWFILE   CONSTANT NUMBER := 6;  -- New file, relative# and file#
  KBRSOPER_NEXT      CONSTANT NUMBER := 7;  -- Get Next part of restore plan
  KBRSOPER_DONE      CONSTANT NUMBER := 8;  -- All restore plan parts done
 
--
  KBRSPLBLD_PIECE       CONSTANT NUMBER := 1;  -- Fetch a backup piece
  KBRSPLBLD_PURGE       CONSTANT NUMBER := 2;  -- Fetch blocks for purging
  KBRSPLBLD_SMALLPURGE  CONSTANT NUMBER := 3;  -- Fetch from limitted chunks
  KBRSPLBLD_OPTPURGE    CONSTANT NUMBER := 4;  -- Fetch efficiently for purge
  KBRSPLBLD_ALLPURGE    CONSTANT NUMBER := 5;  -- Fetch nothing, delete df
  KBRSPLBLD_OPTIMIZE    CONSTANT NUMBER := 6;  -- Fetch non-contiguous blocks
  KBRSPLBLD_DUPPURGE    CONSTANT NUMBER := 7;  -- Fetch to remove old duplicates
  KBRSPLBLD_ORIGPIECE   CONSTANT NUMBER := 8;  -- Fetch an incr level 1 bp
  KBRSPLBLD_FULLPIECE   CONSTANT NUMBER := 10; -- Mult-section support 
 
--
  VBDF_COMPLETE       CONSTANT NUMBER :=   1; -- (Must be first)
  VBDF_BUILDING       CONSTANT NUMBER :=   2; -- Process_backup_piece working
  VBDF_ABORT          CONSTANT NUMBER :=   3; -- Purge forced abort of build
  VBDF_FIN_NOBP       CONSTANT NUMBER :=   4; -- File fin, but no bp rec
  VBDF_CLEANUP        CONSTANT NUMBER :=   5; -- Process_backup_piece cleanup
  VBDF_REPOPULATE     CONSTANT NUMBER :=   6; -- Populate_backup_piece
  VBDF_OBSOLETE       CONSTANT NUMBER :=   7; -- Essentially deleted (history)
  VBDF_REPAIR         CONSTANT NUMBER :=   8; -- Used in meta repair only stage
 
--
--
  BIGNUM         CONSTANT NUMBER := 1E40;
  KSCNINV        CONSTANT NUMBER := 281474976710655;
 
--
  CHUNK_NOT_SHARED  CONSTANT NUMBER := 1;  -- DBkey_inc owns not shared chunk
  CHUNK_OWNER       CONSTANT NUMBER := 2;  -- DBkey_inc owns shared chunk
  CHUNK_DEPENDENT   CONSTANT NUMBER := 3;  -- DBkey_inc shares does not own
 
--
--
  KBRS_SAVE_INFO_POOL     CONSTANT NUMBER := 0; -- save name and chunk# for pool
  KBRS_SAVE_INFO_CFFILE   CONSTANT NUMBER := 1; -- control file piece name info
  KBRS_SAVE_INFO_SPFILE   CONSTANT NUMBER := 2; -- sp file piece name info
 
 
--
--
  type nolst is table of NUMBER index by binary_integer;
  type nmlst is table of VARCHAR2(30) index by binary_integer;
 
--
  PROCEDURE setDebug(p_level IN NUMBER,
                     p_safemode IN NUMBER,
                     p_outtype IN NUMBER DEFAULT sys.dbms_system.trace_file);
 
 
--
  FUNCTION incrLevel(p_create_scn    IN NUMBER,  -- bdf.create_scn
                     p_incr_scn      IN NUMBER)  -- bdf.incr_scn
      RETURN NUMBER;
 
  PROCEDURE prep_piece_read(
                          p_inbpkey     IN  NUMBER,
                          p_loc         OUT VARCHAR2, -- Storage location
                          p_dbkey       OUT NUMBER,
                          p_db_id       OUT NUMBER,
                          p_dfkey       OUT NUMBER,   -- 0 if more than 1 df
                          p_vbkey       OUT NUMBER,
                          p_blksize     OUT NUMBER,
                          p_original    OUT NUMBER,   -- 1 == Virtual copy
                          p_read_bufs   OUT NUMBER,
                          p_read_size   OUT NUMBER,
                          p_read_waste  OUT NUMBER);
 
  PROCEDURE prep_read(
                    p_type        IN    NUMBER, /* KBRSPLBLD_% */
                    p_bskey       IN    NUMBER, /* optional */
                    p_vbkey       IN    NUMBER,
                    p_dfkey       IN    NUMBER,
                    p_blksize     OUT   NUMBER,
                    p_read_bufs   OUT   NUMBER,
                    p_read_size   OUT   NUMBER,
                    p_read_waste  OUT   NUMBER);
 
  PROCEDURE dealloc_plan_bp(p_bskey NUMBER);
 
  PROCEDURE obsoletePlans(p_dfkey       IN NUMBER,
                          p_chk_krbph   IN NUMBER DEFAULT 1,
                          p_lock        IN NUMBER DEFAULT 1);
 
  PROCEDURE build_read_plan(
                     p_dbkey IN NUMBER,      -- Database key
                     p_vbkey IN NUMBER,       -- Virtual backup id
                     p_dfkey IN NUMBER,      -- Datafile key
                     p_bufsize IN NUMBER,    -- size of read buffers
                     p_type IN NUMBER,       -- KBRSBLD_ type
                     p_chunks IN NUMBER,     -- Number of chunks to write.
                     p_stored OUT NUMBER);   -- Is 1 if plan was stored
 
  PROCEDURE ok4pool(p_dbkey    IN  NUMBER,
                    p_bpkey    IN  NUMBER,
                    p_update   IN  BOOLEAN,
                    p_hasdups  OUT BOOLEAN,
                    p_nofityet OUT BOOLEAN,
                    p_isok     OUT BOOLEAN);
 
  PROCEDURE process_backup_piece(p_dbkey     IN  NUMBER,    -- Database key
                                 p_bpkey     IN  NUMBER,    -- BackupPiece key
                                 p_upd       IN  NUMBER DEFAULT 0, -- update op
                                 p_complete  OUT BOOLEAN);
 
  PROCEDURE purgeDB(p_slkey   IN NUMBER,                 -- Storage location
                    p_dbkey   IN NUMBER,                 -- Database key
                    p_inline  IN BOOLEAN DEFAULT FALSE); -- True when testing
 
  PROCEDURE validateDB(p_dbkey IN NUMBER);
 
  FUNCTION plannedSpace (p_slkey      IN NUMBER,
                         p_enable_dup IN NUMBER) RETURN NUMBER;
 
  FUNCTION plannedDBSpace(p_db_key IN NUMBER) -- Database key
    RETURN NUMBER;
 
  FUNCTION copied_to_tape(p_dbkey IN NUMBER) RETURN NUMBER;
 
  PROCEDURE optimizeDF(p_dbkey IN NUMBER,      -- Database key
                       p_dfkey IN NUMBER,      -- Datafile key
                       p_onlylost IN BOOLEAN DEFAULT FALSE);
 
  PROCEDURE purgeDupDF(p_dfkey    IN NUMBER,   -- Datafile key
                       p_vbkey    IN NUMBER,   -- Virtual backup key
                       p_bpkey    IN NUMBER,   -- (optional) bp_key for locking
                       p_newplans IN BOOLEAN DEFAULT TRUE); -- Inhibit new plan
 
  PROCEDURE moveDF(p_dbkey IN NUMBER,      -- Database key
                   p_dfkey IN NUMBER);      -- Datafile key
 
  PROCEDURE purgeDF(p_type  IN NUMBER,      -- Type of purge to perform
                    p_dfkey IN NUMBER,      -- Datafile key
                    p_vbkey IN NUMBER);     -- Oldest available vbkey
 
  PROCEDURE planDF(p_type   IN NUMBER,    -- Type of plan to build
                   p_dfkey  IN NUMBER,    -- Datafile key
                   p_vbkey  IN NUMBER,    -- Vbkey associated with the plan
                   p_res    IN NUMBER DEFAULT 0, -- Chunks to reserve
                   p_locked IN BOOLEAN DEFAULT FALSE, -- Key lock already held
                   p_must   IN BOOLEAN DEFAULT FALSE, -- Guarenteed plan
                   p_plock  IN BOOLEAN DEFAULT FALSE);-- Purge lock already held
 
  PROCEDURE save_krbph(p_dfkey     IN NUMBER,   -- krbph df_key
                       p_chunkno   IN NUMBER,   -- krbph chunk number
                       p_name      IN VARCHAR2, -- krbph chunk name
                       p_splittype IN NUMBER ); -- splitting for block pool,
--
--
--
--
 
  PROCEDURE begin_df(
                   p_vbkey     IN OUT NUMBER,  -- Virtual backup ID
                   p_ckpid     IN OUT NUMBER,  -- ckp_scn --> ckp_id
                   p_dbid      IN     NUMBER,  -- Database ID
                   p_fno       IN     NUMBER,  -- Datafile number
                   p_blocks    IN     NUMBER,  -- (opt) Datafile size in blocks
                   p_incrscn   IN     NUMBER,  -- (opt) Incr_scn for backup
                   p_crescn    IN     NUMBER,  -- (opt) Datafile creation scn
                   p_crestamp  IN     NUMBER,  -- (opt) Datafile creation time
                   p_rstscn    IN     NUMBER,  -- (opt) reset scn
                   p_rststamp  IN     NUMBER,  -- (opt) reset stamp
                   p_dfkey     OUT    NUMBER,  -- Datafile key
                   p_dbkey     OUT    NUMBER,  -- Database key
                   p_dbinckey  OUT    NUMBER,  -- Database incarnation key
                   p_unorderid OUT    NUMBER,  -- (opt) max(unorder_id)
                   p_firstblk  IN     NUMBER,  -- First block
                   p_lastblk   IN     NUMBER); -- Last  block
 
  PROCEDURE end_df(   p_vbkey     IN NUMBER,    -- Virtual backup ID
                      p_dfkey     IN NUMBER,    -- Datafile key
                      p_relfno    IN NUMBER,    -- Backupset relative file num
                      p_ckpscn    IN NUMBER,    -- Checkpoint scn
                      p_absscn    IN NUMBER,    -- Absolute fuzzy scn
                      p_repair    IN BOOLEAN,   -- True if repair in progress
                      p_cmpvsn    IN NUMBER,    -- backup version#
                      p_issft     IN NUMBER,    -- IS Single File Tablespace
                      p_unorder   IN NUMBER,    -- 1 if gap block found
                      p_replev    IN NUMBER DEFAULT NULL); -- Repair incr level
 
  PROCEDURE repair_df(p_vbkey     IN OUT NUMBER,  -- Virtual backup ID
                      p_newvb     IN OUT NUMBER,  -- NULL, 1 begin_df, 0 repair
                      p_dbid      IN     NUMBER,  -- Database ID
                      p_fno       IN     NUMBER,  -- Datafile number
                      p_blocks    IN     NUMBER,  -- Datafile size in blocks
                      p_relfno    IN     NUMBER,  -- Backupset relative fileno
                      p_crescn    IN     NUMBER,  -- Datafile creation scn
                      p_crestamp  IN     NUMBER,  -- Datafile creation time
                      p_rstscn    IN     NUMBER,  -- reset scn
                      p_rststamp  IN     NUMBER,  -- reset stamp
                      p_startscn  IN     NUMBER,  -- Incremental start scn
                      p_ckpscn    IN     NUMBER,  -- Checkpoint scn
                      p_cmpvsn    IN     NUMBER,  -- backup version#
                      p_issft     IN     NUMBER,  -- Single File Tablespace
                      p_firstblk  IN     NUMBER,  -- First block
                      p_lastblk   IN     NUMBER,  -- Last Block
                      p_replev    IN     NUMBER); -- iLevel if invalid incrscn
 
--
  PROCEDURE deleteVB(p_slkey   IN NUMBER,
                     p_dbkey   IN NUMBER,
                     p_currinc IN NUMBER,
                     p_bpkey   IN NUMBER,
                     p_noplans IN BOOLEAN,
                     p_notasks IN BOOLEAN);
 
--
  PROCEDURE repairChunks(p_dbkey  IN NUMBER);
 
--
--
--
  TYPE collapse_bin_t IS RECORD (
    blockno                        NUMBER
  , scn                            NUMBER
  , chunkno                        NUMBER
  , used                           NUMBER
  , coffset                        NUMBER
  );
--
  TYPE collapse_blocks_c IS REF CURSOR RETURN collapse_bin_t;
 
--
  TYPE collapse_b_t IS RECORD (
    blockno                        NUMBER -- min
  , chunkno                        NUMBER
  , numblks                        NUMBER -- count
  , coffset                        NUMBER -- min
  , numbytes                       NUMBER -- sum(used)
  , signature                      NUMBER -- sum(scn)
  );
--
  TYPE collapse_blocks_t IS TABLE OF collapse_b_t;
 
  /*
  The function accepts a cursor i_cur and attempts to collapse conjuncted
  set of blocks within a chunk.  The idea here is to return the range of
  blocks back to the caller, so a corresponding post for read can be done.
  */
  FUNCTION collapse (
    i_cur                          IN collapse_blocks_c
  )
  RETURN collapse_blocks_t
  PIPELINED;
 
--
--
--
  TYPE skip_last_bin_t IS RECORD (
    blockno                        NUMBER
  , ckp_id                         NUMBER
  , scn                            NUMBER
  , chunkno                        NUMBER
  , used                           NUMBER
  , coffset                        NUMBER
  );
--
  TYPE skip_last_blocks_c IS REF CURSOR RETURN skip_last_bin_t;
 
--
--
  TYPE skip_last_blocks_t IS TABLE OF skip_last_bin_t;
 
  /*
  The function accepts a cursor i_cur and removes the top most record
  from the result set, that's done according to the ORDER BY specification.
  The function is named skip_last because the eventual goal is to make
  blocks_u index having keys stored in the ascending order.
  */
  FUNCTION skip_last (
    i_cur                          IN skip_last_blocks_c
  )
  RETURN skip_last_blocks_t
  PIPELINED;
 
END dbms_ra_pool;
>>>
 
define setup_tasktypenames
<<<
begin
insert into tasktypenames 
  values(dbms_ra_scheduler.task_quiesce_rs,        'QUIESCE');
insert into tasktypenames 
  values(dbms_ra_scheduler.task_spawn_sbt,         'SPAWN_SBT');
insert into tasktypenames 
  values(dbms_ra_scheduler.task_purge_df_now,      'PURGE_DF_NOW');
insert into tasktypenames 
  values(dbms_ra_scheduler.task_restore,           'RESTORE');
insert into tasktypenames 
  values(dbms_ra_scheduler.task_storage_histogram, 'HISTOGRAM');
insert into tasktypenames 
  values(dbms_ra_scheduler.task_gcopy_compute,     'GCOPY_COMPUTE');
insert into tasktypenames 
  values(dbms_ra_scheduler.task_purge_dup_df,      'PURGE_DUP');
insert into tasktypenames 
  values(dbms_ra_scheduler.task_deferred_delete,   'DEFERRED_DEL');
insert into tasktypenames 
  values(dbms_ra_scheduler.task_purge_immediate,   'PURGE_IMM');
insert into tasktypenames 
  values(dbms_ra_scheduler.task_purge_df,          'PURGE_DF');
insert into tasktypenames 
  values(dbms_ra_scheduler.task_delete_db,         'DELETE_DB');
insert into tasktypenames 
  values(dbms_ra_scheduler.task_trim_db,           'TRIM_DB');
insert into tasktypenames 
  values(dbms_ra_scheduler.task_purge,             'PURGE');
insert into tasktypenames 
  values(dbms_ra_scheduler.task_backup_arch,       'BACKUP_ARCH');
insert into tasktypenames 
  values(dbms_ra_scheduler.task_inc_arch,          'INCOMPLETE_ARCH');
insert into tasktypenames 
  values(dbms_ra_scheduler.task_plan_sbt,           'PLAN_SBT');
insert into tasktypenames 
  values(dbms_ra_scheduler.task_index_backup,      'INDEX_BACKUP');
insert into tasktypenames 
  values(dbms_ra_scheduler.task_plan_df,           'PLAN_DF');
insert into tasktypenames 
  values(dbms_ra_scheduler.task_newdfkey,          'NEW_DFKEY');
insert into tasktypenames 
  values(dbms_ra_scheduler.task_move_df,           'MOVE_DF');
insert into tasktypenames 
  values(dbms_ra_scheduler.task_move_all_db,       'MOVE_ALL_DB');
insert into tasktypenames 
  values(dbms_ra_scheduler.task_poll,              'POLL');
insert into tasktypenames 
  values(dbms_ra_scheduler.task_restore_sbt,       'RESTORE_SBT');
insert into tasktypenames 
  values(dbms_ra_scheduler.task_backup_sbt,        'BACKUP_SBT');
insert into tasktypenames 
  values(dbms_ra_scheduler.task_insert_fault,      'INSERT_FAULT');
insert into tasktypenames 
  values(dbms_ra_scheduler.task_purge_sbt,         'PURGE_SBT');
insert into tasktypenames 
  values(dbms_ra_scheduler.task_obsolete_sbt,      'OBSOLETE_SBT');
insert into tasktypenames 
  values(dbms_ra_scheduler.task_rm_incomplete_files,'RM_INC_FILES');
insert into tasktypenames 
  values(dbms_ra_scheduler.task_reconcile,         'RECONCILE');
insert into tasktypenames 
  values(dbms_ra_scheduler.task_repair_db,         'REPAIR_DB');
insert into tasktypenames 
  values(dbms_ra_scheduler.task_db_stats_refresh,  'DB_STATS_REFRESH');
insert into tasktypenames 
  values(dbms_ra_scheduler.task_restore_range_refresh, 
                                                    'RESTORE_RANGE_REFRESH');
insert into tasktypenames 
  values(dbms_ra_scheduler.task_optimize_chunks_df,'OPT_DF');
insert into tasktypenames 
  values(dbms_ra_scheduler.task_optimize_chunks,   'OPTIMIZE');
insert into tasktypenames 
  values(dbms_ra_scheduler.task_rebuild_index,     'REBUILD_INDEX');
insert into tasktypenames 
  values(dbms_ra_scheduler.task_validate_db,       'VALIDATE');
insert into tasktypenames 
  values(dbms_ra_scheduler.task_check_files,       'CHECK_FILES');
insert into tasktypenames 
  values(dbms_ra_scheduler.task_crosscheck_db,     'CROSSCHECK_DB');
insert into tasktypenames 
  values(dbms_ra_scheduler.task_session_times,     'SESSION_TIMES');
insert into tasktypenames 
  values(dbms_ra_scheduler.task_error_info,        'ERROR_INFO');
insert into tasktypenames 
  values(dbms_ra_scheduler.task_test_dummy,        'TEST_DUMMY');
insert into tasktypenames 
  values(dbms_ra_scheduler.task_api_add_db,        'API_ADD_DB');
insert into tasktypenames 
  values(dbms_ra_scheduler.task_api_upd_db,        'API_UPD_DB');
insert into tasktypenames 
  values(dbms_ra_scheduler.task_api_del_db,        'API_DEL_DB');
insert into tasktypenames 
  values(dbms_ra_scheduler.task_api_ren_db,        'API_REN_DB');    
insert into tasktypenames 
  values(dbms_ra_scheduler.task_api_grant_db,      'API_GRANT_DB');
insert into tasktypenames 
  values(dbms_ra_scheduler.task_api_revoke_db,     'API_REVOKE_DB');
insert into tasktypenames 
  values(dbms_ra_scheduler.task_api_add_sl,        'API_ADD_SL');    
insert into tasktypenames 
  values(dbms_ra_scheduler.task_api_upd_sl,        'API_UPD_SL');    
insert into tasktypenames 
  values(dbms_ra_scheduler.task_api_del_sl,        'API_DEL_SL');    
insert into tasktypenames 
  values(dbms_ra_scheduler.task_api_add_prot_policy, 'API_ADD_PROT_POLICY');
insert into tasktypenames 
  values(dbms_ra_scheduler.task_api_upd_prot_policy, 'API_UPD_PROT_POLICY'); 
insert into tasktypenames 
  values(dbms_ra_scheduler.task_api_del_prot_policy, 'API_DEL_PROT_POLICY');
insert into tasktypenames 
  values(dbms_ra_scheduler.task_api_add_poll_policy, 'API_ADD_POLL_POLICY');
insert into tasktypenames 
  values(dbms_ra_scheduler.task_api_upd_poll_policy, 'API_UPD_POLL_POLICY');
insert into tasktypenames 
  values(dbms_ra_scheduler.task_api_del_poll_policy, 'API_DEL_POLL_POLICY');
insert into tasktypenames 
  values(dbms_ra_scheduler.task_api_add_sbt_lib,   'API_ADD_SBT_LIB');    
insert into tasktypenames 
  values(dbms_ra_scheduler.task_api_upd_sbt_lib,   'API_UPD_SBT_LIB');    
insert into tasktypenames 
  values(dbms_ra_scheduler.task_api_del_sbt_lib,   'API_DEL_SBT_LIB');    
insert into tasktypenames 
  values(dbms_ra_scheduler.task_api_add_restrict_sbt_inst,
                                                  'API_ADD_RESTRICT_SBT_INST');
insert into tasktypenames 
  values(dbms_ra_scheduler.task_api_del_restrict_sbt_inst,
                                                  'API_DEL_RESTRICT_SBT_INST');
insert into tasktypenames 
  values(dbms_ra_scheduler.task_api_add_sbt_attr_set, 'API_ADD_SBT_ATTR_SET');
insert into tasktypenames 
  values(dbms_ra_scheduler.task_api_upd_sbt_attr_set, 'API_UPD_SBT_ATTR_SET');
insert into tasktypenames 
  values(dbms_ra_scheduler.task_api_del_sbt_attr_set, 'API_DEL_SBT_ATTR_SET');
insert into tasktypenames 
  values(dbms_ra_scheduler.task_api_add_sbt_job,      'API_ADD_SBT_JOB');    
insert into tasktypenames 
  values(dbms_ra_scheduler.task_api_upd_sbt_job,      'API_UPD_SBT_JOB');    
insert into tasktypenames 
  values(dbms_ra_scheduler.task_api_del_sbt_job,      'API_DEL_SBT_JOB');    
insert into tasktypenames 
  values(dbms_ra_scheduler.task_api_pau_sbt_lib,      'API_PAU_SBT_LIB');    
insert into tasktypenames 
  values(dbms_ra_scheduler.task_api_res_sbt_lib,      'API_RES_SBT_LIB');    
insert into tasktypenames 
  values(dbms_ra_scheduler.task_api_add_repository,   'API_ADD_REPOSITORY');
insert into tasktypenames 
  values(dbms_ra_scheduler.task_api_del_repository,   'API_DEL_REPOSITORY');
insert into tasktypenames 
  values(dbms_ra_scheduler.task_api_add_rep_server,   'API_ADD_REP_SERVER');
insert into tasktypenames 
  values(dbms_ra_scheduler.task_api_rem_rep_server,   'API_REM_REP_SERVER');
insert into tasktypenames 
  values(dbms_ra_scheduler.task_api_startup,          'API_STARTUP');
insert into tasktypenames 
  values(dbms_ra_scheduler.task_api_shutdown,         'API_SHUTDOWN');    
insert into tasktypenames 
  values(dbms_ra_scheduler.task_api_abort,            'API_ABORT');
insert into tasktypenames 
  values(dbms_ra_scheduler.task_api_config,           'API_CONFIG'); 
insert into tasktypenames 
  values(dbms_ra_scheduler.task_api_populate,         'API_POPULATE'); 
insert into tasktypenames 
  values(dbms_ra_scheduler.task_api_move_backup,      'API_MOVE_BACKUP');
insert into tasktypenames 
  values(dbms_ra_scheduler.task_api_copy_backup,      'API_COPY_BACKUP');    
insert into tasktypenames 
  values(dbms_ra_scheduler.task_api_move_backup_piece,'API_MOVE_BACKUP_PIECE');
insert into tasktypenames 
  values(dbms_ra_scheduler.task_api_copy_backup_piece,'API_COPY_BACKUP_PIECE');
insert into tasktypenames 
  values(dbms_ra_scheduler.task_api_replicate_existing,
                                                    'API_REPLICATE_EXISTING');
insert into tasktypenames 
  values(dbms_ra_scheduler.task_api_replication_reconcile,
                                                   'API_REPLICATION_RECONCILE');
insert into tasktypenames 
  values(dbms_ra_scheduler.task_api_replicate_one_piece,
                                                   'API_REPLICATE_ONE_PIECE');
insert into tasktypenames 
  values(dbms_ra_scheduler.task_api_migrate_tape,
                                                    'API_MIGRATE_TAPE_BACKUP');
insert into tasktypenames 
  values(dbms_ra_scheduler.task_api_pau_rep_srv,     'API_PAUSE_REPLICATION');
insert into tasktypenames 
  values(dbms_ra_scheduler.task_api_res_rep_srv,     'API_RESUME_REPLICATION');
insert into tasktypenames 
  values(dbms_ra_scheduler.task_api_repair_sl,       'API_REPAIR_SL'); 
insert into tasktypenames 
  values(dbms_ra_scheduler.task_api_testtask,        'API_TESTTASK'); 
insert into tasktypenames 
  values(dbms_ra_scheduler.task_api_cre_rep_server,  'API_CREATE_REP_SERVER');
insert into tasktypenames 
  values(dbms_ra_scheduler.task_api_upd_rep_server,  'API_UPDATE_REP_SERVER');
insert into tasktypenames 
  values(dbms_ra_scheduler.task_api_del_rep_server,  'API_DELETE_REP_SERVER');
 
commit;
end;
>>>
 
define delete_old_tasktypenames_entries
<<<
begin
DELETE FROM tasktypenames WHERE task_type_name = 'RESERVE_SBT';
--
FOR t IN (SELECT task_id
            FROM task
            WHERE task_type = dbms_ra_scheduler.TASK_RESERVE_SBT) LOOP
  DELETE FROM sbt_job_template jt
    WHERE jt.template_key IN (
      SELECT st.template_key 
        FROM sbt_task st
       WHERE st.task_id = t.task_id );
 
  DELETE FROM sbt_task
    WHERE task_id = t.task_id;
 
  DELETE FROM task
    WHERE task_id = t.task_id;
END LOOP;
commit;
end;
>>>
 
 
 
define create_taskdata_obj
<<<
CREATE OR REPLACE TYPE taskdata AS OBJECT
  ( task_state VARCHAR2(32)
  , task_id    VARCHAR2(20)
  , db_uname   VARCHAR2(32)
  , exe_time   VARCHAR2(8)
  , task_type  VARCHAR2(30)
  , task_param VARCHAR2(32)
  , client_id  VARCHAR2(64)
  , module     VARCHAR2(64)
  , action     VARCHAR2(64)
  )
>>>
 
define create_taskdata_type
<<<
CREATE OR REPLACE TYPE taskinfo AS TABLE OF taskdata
>>>
 
define create_taskdata_func
<<<
CREATE OR REPLACE FUNCTION taskdata_func RETURN taskinfo PIPELINED 
AS
  CURSOR tasklist IS
    SELECT t.task_id
         , t.db_key
         , t.sl_key
         , task_type
         , TO_CHAR(t.last_execute_time, 'HH24:MI:SS') EXE_TIME
         , (CASE WHEN t.state = dbms_ra_scheduler.STATE_TASK_WAIT
                THEN 'WAIT ON ' || PENDING_INTERRUPT
                ELSE NULL
            END) pending
         , dbms_ra_scheduler.taskstate2name(
                  NVL(t.state, dbms_ra_scheduler.STATE_RUNNING),
                  t.pending_interrupt) task_state
         , NVL2(task_type, 
                tasktypenames.task_type_name,
                v.client_identifier) taskt
         , t.state
         , t.param_num1
         , t.param_num2
         , v.client_identifier client_id
         , v.module
         , v.action
      FROM task t
      FULL OUTER JOIN
           (SELECT client_identifier, module, action,
              to_number(decode(substr(client_identifier, 1, 4), 'RA$T',
                               substr(client_identifier, 5, 60), NULL)) task_id
            FROM sys.gv_$session s
            WHERE (client_identifier LIKE 'RA$S%' OR
                   client_identifier LIKE 'RA$T%')) v
      ON t.task_id = v.task_id
      JOIN tasktypenames USING (task_type)
      WHERE t.task_id IS NOT NULL OR v.module IS NOT NULL
      ORDER BY DECODE(t.state,  -- most interesting stuff should be last
                      dbms_ra_scheduler.STATE_RUNNING, 100,
                      dbms_ra_scheduler.STATE_CANCELING, 99,
                      dbms_ra_scheduler.STATE_CANCEL, 98,
                      NULL, 90,
                      t.state)
             , t.task_id
             , v.module;
 
  ids1             NUMBER;
  ids2             NUMBER;
  fail             NUMBER;
  check_failures   NUMBER;
  l_last_seen      DATE;
  l_component      VARCHAR2(14);
  l_error_text     VARCHAR2(100);
  l_param1         VARCHAR2(100);
  l_param2         VARCHAR2(100);
  l_temp           VARCHAR2(100);
BEGIN
--
  SELECT COUNT(*) INTO fail
  FROM config WHERE name = '_recovery_server_state' AND value = 'OFF';
 
--
  SELECT COUNT(*) INTO check_failures
    FROM config
    WHERE name = '_debug_flags'
      AND BITAND(value, 33554432) > 0; /* kbrs2.h KBRSTRC_STALL */
 
--
  PIPE ROW(taskdata(NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL));
  PIPE ROW(taskdata('To use:', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL));
  PIPE ROW(taskdata('SET PAGES 10000', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL));
  PIPE ROW(taskdata('SET ARRAYSIZE 1', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL));
  PIPE ROW(taskdata(NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL));
 
  FOR i IN 1 .. 10 LOOP
    PIPE ROW(taskdata(NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL));
  END LOOP;
 
--
  WHILE fail = 0 LOOP
--
    PIPE ROW(taskdata('TASK_STATE', 'TASK_ID', 'DB_UNAME',
                      'EXE_TIME', 'TYPE_OF_TASK', 'TASK_PARAM',
                      'CLIENT_ID', 'MODULE', 'ACTION'));
    PIPE ROW(taskdata('----------', '-------', '--------',
                      '--------', '------------', '----------',
                      '---------', '------', '------'));
 
--
    FOR t IN tasklist LOOP
      l_param1 := NULL;
      l_param2 := NULL;
 
      CASE 
        WHEN t.task_type = dbms_ra_scheduler.TASK_INDEX_BACKUP
        THEN
          SELECT MAX(tag) INTO l_param1 FROM bp WHERE bp_key = t.param_num1;
        WHEN t.task_type = dbms_ra_scheduler.TASK_RESTORE
          OR t.task_type = dbms_ra_scheduler.TASK_RESTORE_SBT
        THEN
          SELECT substr(tag,1,18) INTO l_temp
            FROM bp WHERE bp_key = t.param_num2;
          SELECT MAX(file#) || ' ' || l_temp INTO l_param1
            FROM bdf
            WHERE bs_key = (SELECT bs_key FROM bp WHERE bp_key = t.param_num2);
        WHEN t.task_type = dbms_ra_scheduler.TASK_PURGE_IMMEDIATE
          OR t.task_type = dbms_ra_scheduler.TASK_PURGE
        THEN
          IF t.db_key IS NOT NULL THEN
            l_param1 := 'db: ' || t.db_key;
            SELECT 'spc: ' || TO_CHAR(used_space/1024/1024) || 'M'
            INTO l_param2
              FROM odb WHERE odb.db_key = t.db_key;
          ELSE
            l_param1 := 'sl: ' || t.sl_key;
          END IF;
        WHEN t.task_type = dbms_ra_scheduler.TASK_PURGE_DF
        THEN
          l_param1 := 'dfkey: ' || t.param_num1;
          SELECT 'spc: ' || TO_CHAR(used_space/1024/1024) || 'M' INTO l_param2
            FROM odb WHERE odb.db_key = t.db_key;
        ELSE
          l_param1 := NULL;
      END CASE;
 
--
      PIPE ROW(taskdata(  substr(t.task_state,1,32)
                        , substr(t.task_id,1,20)
                        , dbms_ra_int.dbkey2name(t.db_key)
                        , t.exe_time
                        , t.taskt
                        , substr(l_param1,1,32)
                        , t.client_id
                        , t.module
                        , t.action || t.pending
                          ));
 
--
      IF l_param2 IS NOT NULL THEN
        PIPE ROW(taskdata(  substr(t.task_state,1,32)
                          , NULL
                          , dbms_ra_int.dbkey2name(t.db_key)
                          , NULL
                          , NULL
                          , NULL
                          , NULL
                          , NULL
                          , substr(l_param2,1,32)
                            ));
      END IF;
    END LOOP;
 
--
    PIPE ROW(taskdata(NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL));
    PIPE ROW(taskdata(NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL));
    PIPE ROW(taskdata(NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL));
 
--
    ids1 := NULL;
    WHILE (ids1 IS NULL OR ids1 = ids2) AND fail = 0 LOOP
      dbms_lock.sleep(1);
 
--
      SELECT NVL(COUNT(*) + SUM(module_hash) /* + SUM(action_hash) */, 0)
        INTO ids2
        FROM sys.gv_$session 
        WHERE (client_identifier LIKE 'RA$S%' OR
               client_identifier LIKE 'RA$T%');
 
--
      SELECT nvl(sum(task_id) + sum(state), 0) + ids2 INTO ids2 FROM task;
 
--
      IF ids1 IS NULL THEN
        ids1 := ids2;
      END IF;
 
--
      IF check_failures > 0 AND ids1 = ids2 THEN
        SELECT count(*) INTO fail
          FROM error_log
          WHERE severity >= dbms_ra_scheduler.SEVERITY_ERROR
            AND status = 'ACTIVE'
            AND ROWNUM = 1;
      END IF;
 
--
      IF fail = 0 THEN
        SELECT COUNT(*) INTO fail
          FROM config
          WHERE name = '_recovery_appliance_state' AND VALUE = 'OFF';
      END IF;
    END LOOP;
  END LOOP;
 
--
  IF fail > 0 THEN
    SELECT last_seen,  substr(component, 1, 20), substr(error_text, 1, 64)
      INTO l_last_seen, l_component, l_error_text
      FROM error_log
      WHERE severity >= dbms_ra_scheduler.SEVERITY_ERROR
        AND status = 'ACTIVE'
        AND ROWNUM = 1;
    PIPE ROW(taskdata('Error:', NULL, NULL,
                      to_char(l_last_seen, 'HH24:MI:SS'), 
                      l_component, NULL,
                      l_error_text, l_error_text, l_error_text));
    PIPE ROW(taskdata(NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL));
  END IF;
  RETURN;
END taskdata_func;
>>>
 
define create_taskdata_view
<<<
CREATE OR REPLACE VIEW rai_dynamic_tasks AS SELECT * FROM TABLE(taskdata_func) t
>>>
 
define drop_taskdata_obj
<<<
DROP TYPE taskdata
>>>
 
define drop_taskdata_type
<<<
DROP TYPE taskinfo
>>>
 
define drop_taskdata_func
<<<
DROP FUNCTION taskdata_func
>>>
 
define drop_taskdata_view
<<<
DROP VIEW rai_dynamic_tasks
>>>
 
define create_active_session_view
<<<
create or replace view ra_active_session
  (inst_id, instance_name, host_name, sid, serial#, spid, db_key,
   db_unique_name, sbt_sid, client_identifier, module, action, sql_id,
   event, p1, p2, p3, wait_time, seconds_in_wait, state,
   task_id, task_type, priority, task_state, job_name)
  as
  with se as
     (select /*+PARAM('_module_action_old_length',0)*/ s.*,
             to_number(decode(substr(client_identifier, 1, 4), 'RA$T',
                              substr(client_identifier, 5, 60), NULL)) task_id
        from gv$session s
       where s.client_identifier like 'RA$%') 
   select /*+ LEADING(se proc sbt i) USE_HASH(proc sbt i) PUSH_PRED(t.t) */
          i.inst_id,
          i.instance_name,
          i.host_name,
          se.sid,
          se.serial#,
          proc.spid,
          coalesce(t.db_key, sbt.db_key),
          coalesce(t.db_unique_name, db.reg_db_unique_name),
          se.client_info,
          se.client_identifier,
          se.module,
          se.action,
          se.sql_id,
          se.event,
          se.p1,
          se.p2,
          se.p3,
          se.wait_time,
          se.seconds_in_wait,
          se.state,
          t.task_id,
          t.task_type,
          t.priority,
          t.state,
          usrj.job_name
     from gv$process proc, gv$instance i, se
     left outer join sbt_session sbt
       on se.client_info = sbt.session_id
     left outer join ra_task t
       on t.task_id = se.task_id
      and t.instance_id = se.inst_id
      and t.archived = 'N'
     left outer join user_scheduler_running_jobs usrj
       on se.inst_id = usrj.running_instance
      and se.sid = usrj.session_id
     left outer join db on db.db_key = sbt.db_key
    where proc.inst_id = se.inst_id
      and se.inst_id = i.inst_id
      and se.paddr = proc.addr
>>>
 
define create_comment_active_session
<<<
begin
execute immediate 'comment on table ra_active_session is ' ||
'''This view lists information about active client sessions currently ' || 
  'running in the Recovery Appliance.''';
 
execute immediate 'comment on column ra_active_session.' ||
'inst_id is ' ||
'''The Recovery Appliance instance number where this session is running.''';
 
execute immediate 'comment on column ra_active_session.' ||
'instance_name is ' ||
'''The Recovery Appliance instance name where this session is running.''';
 
execute immediate 'comment on column ra_active_session.' ||
'host_name is ' ||
'''The Recovery Appliance host name where this session is running.''';
 
execute immediate 'comment on column ra_active_session.' ||
'sid is ' ||
'''The session ID for the active session.''';
 
execute immediate 'comment on column ra_active_session.' ||
'serial# is ' ||
'''The session serial number, which uniquely identifies ' ||
  'the objects in a session.''';
 
execute immediate 'comment on column ra_active_session.' ||
'spid is ' ||
'''The operating system process identifier.''';
 
execute immediate 'comment on column ra_active_session.' ||
'db_key is ' ||
'''The primary key for this database in the recovery catalog.''';
 
execute immediate 'comment on column ra_active_session.' ||
'db_unique_name is' ||
'''The unique database name.''';
 
execute immediate 'comment on column ra_active_session.' ||
'sbt_sid is' ||
'''The SBT session identifier.''';
 
execute immediate 'comment on column ra_active_session.' ||
'client_identifier is' ||
'''The client Identifier of the session.''';
 
execute immediate 'comment on column ra_active_session.' ||
'module is' ||
'''The name of the module that is currently executing.''';
 
execute immediate 'comment on column ra_active_session.' ||
'action is' ||
'''The name of the action that is currently executing.''';
 
execute immediate 'comment on column ra_active_session.' ||
'sql_id is' ||
'''The SQL identifier of the SQL statement that is ' ||
  'currently being executed.''';
 
execute immediate 'comment on column ra_active_session.' ||
'event is' ||
'''The resource or event for which the session is waiting.''';
 
execute immediate 'comment on column ra_active_session.' ||
'p1 is' ||
'''First wait event parameter''';
 
execute immediate 'comment on column ra_active_session.' ||
'p2 is' ||
'''The second wait event parameter.''';
 
execute immediate 'comment on column ra_active_session.' ||
'p3 is' ||
'''The third wait event parameter.''';
 
execute immediate 'comment on column ra_active_session.' ||
'wait_time is ' ||
'''The wait time in hundredths of a second. ' ||
  'See description of ' ||
  '<Emphasis Role = "CodeInline">V$SESSION.WAIT_TIME</Emphasis> ' ||
  'for more information.''';
 
execute immediate 'comment on column ra_active_session.' ||
'seconds_in_wait is ' ||
'''The wait time (in seconds). If the session is currently waiting, ' ||
  'then the value is the amount of time ' ||
  'waited for the current wait. If the session is not in a wait, then the ' ||
  'value is the amount of time since the start of the most recent wait.''';
 
execute immediate 'comment on column ra_active_session.' ||
'state is' ||
'''The state of the wait event: ' ||
  '<Emphasis Role = "CodeInline">WAITING</Emphasis>, ' ||
  '<Emphasis Role = "CodeInline">WAITED UNKNOWN TIME</Emphasis>, ' ||
  '<Emphasis Role = "CodeInline">WAITED SHORT TIME</Emphasis>, ' ||
  '<Emphasis Role = "CodeInline">WAITED KNOWN TIME</Emphasis>. ' ||
  'See description of ' ||
  '<Emphasis Role = "CodeInline">V$SESSION.STATE</Emphasis> ' ||
  'for more information.''';
 
execute immediate 'comment on column ra_active_session.' ||
'task_id is ' ||
'''The task identifier.''';
 
execute immediate 'comment on column ra_active_session.' ||
'task_type is ' ||
'''The task type.''';
 
execute immediate 'comment on column ra_active_session.' ||
'priority is ' ||
'''The task priority.''';
 
execute immediate 'comment on column ra_active_session.' ||
'task_state is ' ||
'''The processing state for the task: <Emphasis Role =' ||
  '"CodeInline">EXECUTABLE</Emphasis>, ' ||
  '<Emphasis Role = "CodeInline">RUNNING</Emphasis>, ' ||
  '<Emphasis Role = "CodeInline">COMPLETED</Emphasis>, ' ||
  '<Emphasis Role = "CodeInline">TASK_WAIT</Emphasis>, ' ||
  '<Emphasis Role = "CodeInline">FAILED</Emphasis>, ' ||
  'and so on.''';
 
execute immediate 'comment on column ra_active_session.' ||
'job_name is ' ||
'''The <Emphasis Role = "CodeInline">DBMS_SCHEDULER</Emphasis> job name.''';
end;
>>>
 
define drop_active_session_view
<<<
drop view ra_active_session
>>>
 
define create_active_session_history_view
<<<
create or replace view rai_active_session_history
  (inst_id, instance_name, host_name, sid, serial#, db_key,
   db_unique_name, client_identifier, module, action, sql_id,
   event, p1, p2, p3, state, task_id, task_type, priority, task_state)
  as
  with se as
     (select s.*,
             to_number(decode(substr(client_id, 1, 4), 'RA$T',
                              substr(client_id, 5, 60), NULL)) task_id
        from gv$active_session_history s
       where s.client_id like 'RA$%')
   select i.inst_id,
          i.instance_name,
          i.host_name,
          se.session_id,
          se.session_serial#,
          t.db_key,
          t.db_unique_name,
          se.client_id,
          se.module,
          se.action,
          se.sql_id,
          se.event,
          se.p1,
          se.p2,
          se.p3,
          se.session_state,
          se.task_id,
          t.task_type,
          t.priority,
          t.state
     from gv$instance i, se
     left outer join ra_task t
       on t.task_id = se.task_id
      and t.instance_id = se.inst_id
    where se.inst_id = i.inst_id
>>>
 
define drop_active_session_history_view
<<<
DROP VIEW rai_active_session_history
>>>
 
define create_scheduler_error_info
<<<
create or replace view rai_scheduler_error_info as
   select task_id           task_error_id
        , pending_interrupt task_type
        , interrupt_count   failing_task_id
        , error_count       task_copy_id
        , param_num1        ra_sched_purpose
        , param_num2        ra_sched_purpose_param1
        , savepoint         dbms_scheduler_error#
        , param             dbms_scheduler_additional_info
        , param_char1       dbms_scheduler_status
        , param_char2       tracefile
        , ba_session_id     sid
        , execute_inst_id   inst_id
        , schedule_time     sched_start_time
        , execute_time      task_start_time
        , completion_time   error_time
     from task_history
    where task_type = 2000 /* TASK_SESSION_TIMES */
>>>
 
define drop_scheduler_error_info
<<<
DROP VIEW rai_scheduler_error_info
>>>
 
 
define create_internal_purge_queue
<<<
create or replace view rai_purge_queue
      (sl_key, db_key, new_retention,
       overspace, newsecs, goalsecs, overretentionsecs) as
/* Select 3 */
  select sl_key, db_key, newint, overspace, newsecs, goalsecs,
         decode (sign (newsecs - goalsecs),
                 1, (newsecs - goalsecs) /
                    decode(goalsecs, 0, .0001, goalsecs),
                 0) overretentionsecs
    from
/* Select 2 */
      (select sl_key, db_key, newint,
              newint - goalint overint,
              ((extract(second from (newint))) +
               (extract(minute from (newint)) * 60) +
               (extract(hour   from (newint)) * 3600) +
               (extract(day    from (newint)) * 86400)) newsecs,
              ((extract(second from (goalint))) +
               (extract(minute from (goalint)) * 60) +
               (extract(hour   from (goalint)) * 3600) +
               (extract(day    from (goalint)) * 86400)) goalsecs,
              overspace
         from
/* Select 1 */
              (select sl_key, db_key,
                      nvl((systimestamp - bs2_timestamp),
                          numtodsinterval(365, 'day'))  newint,
                      recovery_window_goal goalint,
                      (total_allocation - reserved_space)
                                       / reserved_space overspace
                 from odb
                 where NVL(move_phase,0) NOT IN (2,3) 
                       /*MOVE_PHASE_START,MOVE_PHASE_POOL*/))
>>>
 
 
 
define create_internal_sbt_performance
<<<
create or replace view rai_sbt_performance
  (task_id, filename, start_time, bytes, bs_key, piece#) as
  with backupio as
     (select sid, serial, inst_id, filename, bytes 
        from gv$backup_sync_io
       where type = 'OUTPUT'
         and filename is not null
         and status = 'IN PROGRESS'
         and device_type = 'SBT_TAPE'
      union all
      select sid, serial, inst_id, filename, bytes
        from gv$backup_async_io
       where type = 'OUTPUT'
         and filename is not null
         and status = 'IN PROGRESS'
         and device_type = 'SBT_TAPE'
      )
  select t.task_id, v.filename, s.start_time, v.bytes, st.bs_key, st.piece#
    from backupio v, sessions s, task t, sbt_task st
    where s.sid = v.sid
      and s.serial# = v.serial
      and s.current_task = t.task_id
      and s.instance_id = v.inst_id
      and t.task_type in (150, 160)
      and t.state = 2
      and st.task_id = t.task_id
>>>
 
define create_internal_recovery_window_space
<<<
create or replace view rai_recovery_window_space (
db_key, footprint, recwindowstart, minrectime, bdf1count
)
as
with bssizelist (db_key, bs_key, piecesize, filesize)
as
(
select /*+
         QB_NAME(bssizelist)
         LEADING(dbinc bdf df bp bs)
         USE_HASH(bdf df dbinc bp bs)
       */
       dbinc.db_key
     , max(bdf.bs_key) bs_key
     , sum(bp.bytes)
         keep (dense_rank last order by bdf.bs_key, bp.copy#)
     , max(bdf.blocks * bdf.block_size)
         keep (dense_rank last order by bdf.bs_key, bp.copy#)
  from bdf
     , df
     , dbinc
     , bp
     , bs
 where df.dbinc_key = bdf.dbinc_key
   and dbinc.dbinc_key = bdf.dbinc_key
   and df.file# = bdf.file#
   and df.create_scn = bdf.create_scn
--
--
   and (bdf.incr_scn = 0 or (df.create_scn >= bdf.incr_scn))
   and bp.bs_key = bdf.bs_key
   and bp.db_key = dbinc.db_key
   and bp.ba_access = 'L'
   and bp.status <> 'D'
   and bs.bs_key = bp.bs_key
   and bs.keep_options = 0
 group by dbinc.db_key, bdf.file#
)
, nodupbslist (db_key, bytes, dfcount) as
--
--
--
--
--
(
select /*+ QB_NAME(nodupbslist) */
       bsl.db_key
     , least(sum(bsl.filesize), max(bsl.piecesize))
     , count(*)
  from bssizelist bsl
 group by bsl.db_key, bsl.bs_key
)
, dbfootprint (db_key, space) as
--
--
(
select /*+
         QB_NAME(dbfootprint)
         LEADING(odb)
         USE_HASH(nodupbslist)
       */
       odb.db_key
     , sum(nvl(nodupbslist.bytes, 0))
     + sum(dfcount) * min(odb.sl_min_alloc) *.5
  from odb
     , nodupbslist
 where odb.db_key = nodupbslist.db_key
 group by odb.db_key
)
, keepsize (db_key, space) as
--
(
select /*+
         QB_NAME(keepsize)
         LEADING(bs)
         USE_HASH(bp)
       */
       bp.db_key
     , sum(bytes)
  from bp
  join bs using(bs_key)
 where bp.ba_access = 'L'
   and bp.status <> 'D'
   and bs.keep_options <> 0
 group by bp.db_key
)
, dbrectimes (db_key, recwindowstart, minrectime) as
--
--
--
--
--
--
--
--
--
--
(
select /*+ QB_NAME(dbrectimes) */
       db_key
     , max(recwindowstart)
     , min(minrectime)
  from (select /*+
                 QB_NAME(idbrectimes)
                 LEADING(db dbinc df bdf bp bs)
                 USE_HASH(db dbinc df bdf bp bs)
               */
               db_key
             , nvl(min(bdf.ckp_time), max(df.create_time)) recwindowstart
             , nvl(max(bdf.ckp_time),max(df.create_time)) minrectime
          from
               (select db_key
                     , dbinc_key
                     , reset_scn
                     , nvl(prior reset_scn, 1E40) next_reset_scn
                  from dbinc
                  start with dbinc_key = (select curr_dbinc_key
                                            from db 
                                           where db.db_key = dbinc.db_key
                                         )
                  connect by prior parent_dbinc_key = dbinc_key
               ) incs
               join df using (dbinc_key)
               left outer join bdf using (file#, dbinc_key)
               left outer join bp using (bs_key, db_key)
               left outer join bs using (bs_key, db_key)
         where df.stop_scn is null
           and df.drop_scn is null
           and bdf.ckp_scn >= incs.reset_scn
           and bdf.ckp_scn < incs.next_reset_scn
           and bp.ba_access = 'L'
           and bs.keep_options = 0
         group by db_key, file#
       )
  group by db_key
) 
, backupf1count (db_key, bdf1count) as
--
--
--
(
select /*+
         QB_NAME(backupf1count)
         LEADING(dbinc)
         USE_HASH(bdf)
       */
       dbinc.db_key
     , count(distinct bdf.bs_key)
  from bdf
     , dbinc
 where dbinc.dbinc_key = bdf.dbinc_key
   and bdf.file# = 1
 group by dbinc.db_key
)
select /*+
         QB_NAME(irws)
         LEADING(odb dbfootprint keepsize dbrectimes backupf1count)
         USE_HASH(dbfootprint keepsize dbrectimes backupf1count)
       */
       db_key
     , dbfootprint.space + nvl(keepsize.space, 0) footprint
     , recwindowstart
     , minrectime
     , bdf1count
  from odb
  left outer join dbfootprint using (db_key)
  left outer join keepsize using (db_key)
  left outer join dbrectimes using (db_key)
  left outer join backupf1count using (db_key)
>>>
 
define create_rai_oldest_backup
<<<
create or replace view rai_oldest_backup as
  select /*+ 
           QB_NAME(oldestbackup)
           LEADING(dbinc bdf bp bs)
           USE_HASH(dbinc bdf bp bs)
         */
         db_key
       , cast (min(bp.completion_time)  
                                    as timestamp with time zone) oldest_backup
    from dbinc
         left outer join bdf using (dbinc_key)
         left outer join bp using (bs_key, db_key)
         left outer join bs using (bs_key, db_key)
   where bdf.file# = 1
     and bp.ba_access = 'L'
     and bs.keep_options = 0
   group by db_key
>>>
 
define create_rai_recwingoal_scn
<<<
create or replace view rai_recwingoal_scn (db_id, minscn) as
  with params(db_id, db_key, rwg_start) as
    (select db_id
          , db_key 
          , cast((systimestamp-recovery_window_goal)
                                             at time zone db_timezone as date)
       from node join db using (db_key) join odb using (db_key)
       where node.db_unique_name not like '$%')
  select db_id
       , nvl(min(bdf.ckp_scn), 0)
    from
         (select db_key
               , dbinc_key
               , reset_scn
               , nvl(prior reset_scn, 1E40) next_reset_scn
            from dbinc
            start with dbinc_key = (select curr_dbinc_key
                                      from db 
                                     where db.db_key = dbinc.db_key
                                   )
            connect by prior parent_dbinc_key = dbinc_key
         ) incs
         join df using (dbinc_key)
         join params using (db_key)
         left outer join bdf using (file#, dbinc_key, create_scn, plugin_scn)
         left outer join bp using (bs_key, db_key)
         left outer join bs using (bs_key, db_key)
   where df.stop_scn is null
     and df.drop_scn is null
     and bdf.ckp_scn >= incs.reset_scn
     and bdf.ckp_scn < incs.next_reset_scn
     and bp.ba_access = 'L'
     and bs.keep_options = 0
     and bdf.completion_time >= rwg_start
   group by db_id
>>>
 
define create_rai_maxrecwin_stamp
<<<
create or replace view rai_maxrecwin_stamp
                                 (db_id, high_time, reset_scn, reset_time) as
  with orderedrange as
    (select db_key,
            high_time,
            high_dbinc_key,
            row_number () over (partition by db_key order by high_time desc)
                                                                         as rn
--
--
       from rrcache
--
      where range_type = 'RA$DISK')
  , params as
    (select db_id, high_time, reset_scn, reset_time
       from db using
       join orderedrange using (db_key)
       join dbinc using (db_key)
      where dbinc.dbinc_key = orderedrange.high_dbinc_key
        and orderedrange.rn = 1)    
  select db_id,
         (((((to_number(to_char(high_time, 'yyyy'))-1988)*12
          +  (to_number(to_char(high_time, 'mm'))-1))*31
          +  (to_number(to_char(high_time, 'dd'))-1))*24
          +  (to_number(to_char(high_time, 'hh24'))))*60
          +  (to_number(to_char(high_time, 'mi'))))*60
          +  (to_number(to_char(high_time, 'ss'))),
         reset_scn,
         (((((to_number(to_char(reset_time, 'yyyy'))-1988)*12
          +  (to_number(to_char(reset_time, 'mm'))-1))*31
          +  (to_number(to_char(reset_time, 'dd'))-1))*24
          +  (to_number(to_char(reset_time, 'hh24'))))*60
          +  (to_number(to_char(reset_time, 'mi'))))*60
          +  (to_number(to_char(reset_time, 'ss')))
  from params
>>>
 
define create_rai_unprotected_window
<<<
create or replace view 
                   rai_unprotected_window (db_key, nzdl_active, unprotected) as
  with nodedata (db_key, odbsysdate) as
  (
  select db_key
       , cast((systimestamp at time zone to_char(max(db_timezone))) as date)
    from node
   where substr(node.db_unique_name,1,1) <> '$'
   group by db_key   
  )
  , uw_raw (db_key, nzdl_active, nzdl_days, range_days) as
  (
  select db_key
       , osc.nzdl_active
       , osc.unprotected
       , (odbsysdate-high_time) range_days
    from odb_stats_cache osc
    join nodedata using (db_key)
    left outer join (select db_key, max(high_time) high_time
                       from ra_disk_restore_range
                       group by db_key) using (db_key)
  )
  select db_key
       , nzdl_active
       , case when (nzdl_active = 'YES') and (range_days is not null) 
              then least(nzdl_days, range_days) 
              else range_days 
         end 
    from uw_raw  
>>>
 
define create_rs_server
<<<
create or replace view ra_server as
  select 
    substr((select substr(value,1,3) from config 
             where name = '_recovery_appliance_state'),1,5) state,
    substr((select value/(1024*1024) from config 
             where name = 'network_chunksize'),1,20) network_chunksize,
    substr((select decode(value, '99999', 'UNLIMITED', value) from config 
             where name = '_resource_wait_task_limit'),1,12) 
                                                     resource_wait_task_limit
  from dual
>>>
 
define create_comment_0
<<<
begin
execute immediate 'comment on table ra_server is ' ||
'''This view describes the current settings for the Recovery Appliance.''';
 
execute immediate 'comment on column ra_server.' ||
'state is ' ||
'''The state of the Recovery Appliance: <Emphasis Role = "CodeInline">ON</Emphasis> ' ||
  'if the Recovery Appliance is running; ' ||
  '<Emphasis Role = "CodeInline">OFF</Emphasis> if it is not active.''';
 
execute immediate 'comment on column ra_server.network_chunksize is ' ||
'''The size (in MB) of network messages used by the Recovery Appliance ' ||
  'Backup Module to communicate with the Recovery Appliance.''';
 
execute immediate 'comment on column ra_server.resource_wait_task_limit is ' ||
'''The limitations on task concurrency caused by resource waits.''';
end;
>>>
 
define create_rs_storage_location
<<<
create or replace view ra_storage_location
    (name, sl_key, disk_groups,
     min_alloc, total_space, used_space, 
     freespace, freespace_goal,
     last_check_files, system_purging_space) as
--
  with dbs (sl_key, used_space) as 
  (
  select sl_key, sum(space) used_space
    from (
         select sl_key, used_space space
           from odb
         union all
         select sl_key, dbsl_used_space space
           from dbsl
         )
    group by sl_key
  )
--
  , dests (sl_key, csv) as
  (
  select sl_key
       , listagg(dest, ',') within group (order by dest) csv 
    from storage_dests
    group by sl_key
  )
--
  , sps(n) as
  (
  select to_number(value)
    from config 
    where name='_purging_reserve'
  )
  select sl.sl_name,
         sl.sl_key,
         dests.csv,
         sl.sl_min_alloc/(1024*1024*1024),
         sl.sl_space/(1024*1024*1024),
         NVL(dbs.used_space,0)/(1024*1024*1024),
         (sl.sl_space-(NVL(dbs.used_space,0)+sps.n))/(1024*1024*1024),
         sl.sl_freespace_goal/(1024*1024*1024),
         sl.sl_last_check_files,
         decode (sl.sl_space, 1, 1, sps.n/(1024*1024*1024))
  from sl
       left outer join  dbs on dbs.sl_key = sl.sl_key
       left outer join dests on dests.sl_key = sl.sl_key
       join sps on (1=1)
  where sl_space > 0
>>>
 
define create_comment_1
<<<
begin
execute immediate 'comment on table ra_storage_location is ' ||
'''This view lists defined Recovery Appliance storage locations and their ' ||
  'allocations.''';
 
execute immediate 'comment on column ra_storage_location.' ||
'name is ' ||
'''The Recovery Appliance storage location name.''';
 
execute immediate 'comment on column ra_storage_location.' ||
'sl_key is ' ||
'''The primary key for this Recovery Appliance storage location ' ||
  'in the recovery catalog.''';
 
execute immediate 'comment on column ra_storage_location.' ||
'disk_groups is ' ||
'''The list of names of Oracle ASM disk groups used for storage.''';
 
execute immediate 'comment on column ra_storage_location.' ||
'min_alloc is ' ||
'''The minimum amount of storage (in GB) that may be allocated.''';
 
execute immediate 'comment on column ra_storage_location.' ||
'total_space is ' ||
'''The maximum amount of storage (in GB) that the Recovery Appliance storage ' ||
  'location can use for backup data.''';
 
execute immediate 'comment on column ra_storage_location.' ||
'used_space is ' ||
'''The amount of space (in GB) currently used in the ' ||
  'Recovery Appliance storage location.''';
 
execute immediate 'comment on column ra_storage_location.' ||
'freespace is ' ||
'''The amount of space (in GB) available for immediate use.''';
 
execute immediate
'comment on column ra_storage_location.' ||
'freespace_goal is ' ||
'''The expected free space requirement (in GB) based on usage history. ' ||
  'Purges may occur to meet this goal.''';
 
execute immediate
'comment on column ra_storage_location.' ||
'last_check_files is ' ||
'''The most recent time that files were checked for consistency.''';
 
execute immediate 
'comment on column ra_storage_location.' ||
'system_purging_space is ' ||
'''The amount of space (in GB) reserved for purging operations.''';
end;
>>>
 
define create_rs_storage_histogram
<<<
create or replace view ra_storage_histogram
    (name, sl_key, slot, usage) as
  select sl.sl_name,
         sl_key,
         mod(hist.slot + numslots - (nvl(sl.sl_curr_hist_slot,0)+1), numslots),
         hist.usage/(1024*1024*1024)
  from sl
  join storage_histogram hist using(sl_key)
  cross join (select nvl(max(to_number(value)), 8*30) numslots
        from config
        where name = '_histogram_cycle_slots')
  where (nvl(sl.sl_space,0) != 0)
>>>
 
define create_comment_2
<<<
begin
execute immediate 'comment on table ra_storage_histogram is ' ||
'''This view describes the storage allocation history for recent time periods.''';
 
execute immediate 'comment on column ra_storage_histogram.' ||
'name is ' ||
'''The name of the Recovery Appliance storage location.''';
 
execute immediate 'comment on column ra_storage_histogram.' ||
'sl_key is ' ||
'''The primary key for this Recovery Appliance storage location in ' ||
  'the recovery catalog.''';
 
execute immediate 'comment on column ra_storage_histogram.' ||
'slot is ' ||
'''The slot (ordered by sampling time period) in the histogram.''';
 
execute immediate 'comment on column ra_storage_histogram.' ||
'usage is ' ||
'''The amount of space (in GB) that was allocated during the ' ||
  'histogram slot.''';
end;
>>>
 
define create_rs_purging_queue
<<<
create or replace view ra_purging_queue
    (sl_name, sl_key, db_unique_name, db_key, purge_order, new_recovery_window,
     new_pct_recovery, pct_storage) as
  select sl.sl_name,
         sl_key,
         db.reg_db_unique_name,
         db_key,
         row_number() over (partition by sl_key
                           order by ipq.overretentionsecs desc, 
                                    ipq.overspace desc),
         nvl2(odb.bs2_timestamp,ipq.new_retention,null),
         nvl2(odb.bs2_timestamp,(ipq.newsecs/ipq.goalsecs)*100,null),
         (1+ipq.overspace)*100
  from rai_purge_queue ipq
  join sl using(sl_key)
  join odb using (sl_key, db_key)
  left outer join db using (db_key)
>>>
 
define create_comment_3
<<<
begin
execute immediate 'comment on table ra_purging_queue is ' ||
'''This view describes the order in which protected databases will have their oldest backups deleted when space is low.''';
 
execute immediate 'comment on column ra_purging_queue.' ||
'sl_name is ' ||
'''The Recovery Appliance storage location name.''';
 
execute immediate 'comment on column ra_purging_queue.' ||
'sl_key is ' ||
'''The primary key for this Recovery Appliance storage location in the recovery ' ||
  'catalog.''';
 
execute immediate 'comment on column ra_purging_queue.' ||
'db_unique_name is ' ||
'''The unique name of the protected database whose backups the Recovery ' ||
  'Appliance will purge.''';
 
execute immediate 'comment on column ra_purging_queue.' ||
'db_key is ' ||
'''The primary key for the protected database whose backups ' ||
  'the Recovery Appliance will purge.''';
 
execute immediate 'comment on column ra_purging_queue.' ||
'purge_order is ' ||
'''The order in which this protected database is eligible for purging.''';
 
execute immediate 'comment on column ra_purging_queue.' ||
'new_recovery_window is ' ||
'''The recovery window goal for this protected database after a purge.''';
 
execute immediate 'comment on column ra_purging_queue.' ||
'new_pct_recovery is ' ||
'''The percentage of the recovery window goal remaining for ' ||
  'this protected database after a purge.''';
 
execute immediate 'comment on column ra_purging_queue.' ||
'pct_storage is ' ||
'''The percentage of reserved space being consumed by this ' ||
  'protected database.''';
end;
>>>
 
define create_rs_polling_policy
<<<
create or replace view ra_polling_policy
    (polling_name, polling_key, dest, frequency, delete_input) as
  select poll.poll_name,
         poll.poll_key,
         sd.dest,
         poll.poll_freq,
         DECODE (BITAND(poll.poll_flags,1), 0, 'FALSE', 'TRUE')
  from sl
  join storage_dests sd using(sl_key)
  join poll using(sl_key)
  where (nvl(sl.sl_space, 0) = 0)
>>>
 
define create_comment_4
<<<
begin
execute immediate 'comment on table ra_polling_policy is ' ||
'''This view lists the defined backup polling policies.''';
 
execute immediate 'comment on column ra_polling_policy.' ||
'polling_name is ' ||
'''The name of this backup polling policy.''';
 
execute immediate 'comment on column ra_polling_policy.' ||
'polling_key is ' ||
'''The primary key for this backup polling policy in the recovery catalog.''';
 
execute immediate 'comment on column ra_polling_policy.' ||
'dest is ' ||
'''The file system directory corresponding to the backup polling location.''';
 
execute immediate 'comment on column ra_polling_policy.' ||
'frequency is ' ||
'''The interval at which the Recovery Appliance scans the backup polling ' ||
  'location for new files.''';
 
execute immediate 'comment on column ra_polling_policy.' ||
'delete_input is ' ||
'''The deletion policy for the polling location: ' ||
  '<Emphasis Role = "CodeInline">TRUE</Emphasis> to delete files ' ||
  'as they are accepted; <Emphasis Role = "CodeInline">FALSE</Emphasis> ' ||
  'to keep all files.''';
end;
>>>
 
define create_rs_db_access
<<<
create or replace view ra_db_access
    (username, db_unique_name, db_key) as
  select 
    username,
    substr(decode(prvlg.db_key, null, db_unique_name,
    db.reg_db_unique_name),1,32),
    prvlg.db_key
  from prvlg
  left outer join db on db.db_key = prvlg.db_key,
  all_users au 
  where prvlg.user_id = au.user_id
>>>
 
define create_comment_5
<<<
begin
execute immediate 'comment on table ra_db_access is ' ||
'''This view describes which Recovery Appliance user accounts have access to which protected databases.''';
 
execute immediate 'comment on column ra_db_access.' ||
'username is ' ||
'''The name of the Recovery Appliance user account.''';
 
execute immediate 'comment on column ra_db_access.' ||
'db_unique_name is ' ||
'''The unique name of the protected database accessed by the ' ||
  'Recovery Appliance user account.''';
 
execute immediate 'comment on column ra_db_access.' ||
'db_key is ' ||
'''The primary key for the protected database accessed by the ' ||
  'Recovery Appliance user account.''';
end;
>>>
 
define create_rs_database_synonym
<<<
create or replace view ra_database_synonym (db_unique_name, dbid) as
  select node.db_unique_name,
         db.db_id
  from node
  join db using(db_key)
  where node.db_unique_name not like '%$%'
  union all
  select db_unique_name,
         null db_id
  from unreg_database
>>>
 
define create_comment_6
<<<
begin
execute immediate 'comment on table ra_database_synonym is ' ||
'''This view lists the protected databases and their equivalent names.''';
 
execute immediate 'comment on column ra_database_synonym.' ||
'db_unique_name is '||
'''The unique name of the protected database.''';
 
execute immediate 'comment on column ra_database_synonym.' ||
'dbid is ' ||
'''The DBID for all protected databases that are equivalent to this database.''';
end;
>>>
 
define create_rs_protection_policy
<<<
create or replace view ra_protection_policy
        (policy_name, description, prot_key, sl_name, sl_key, polling_name,
         recovery_window_goal, max_retention_window, recovery_window_sbt,
         unprotected_window, guaranteed_copy, 
         replication_server_list) as
  select prot.prot_name,
         prot.prot_description,
         prot.prot_key,
         sl.sl_name,
         sl.sl_key,
         poll.poll_name,
         prot.prot_recovery_window_goal,
         prot.prot_max_retention_window,
         prot.prot_recovery_window_sbt,
         prot.prot_unprotected_window,
         prot.prot_disk_cache,
         (SELECT listagg(server.rep_server_name, ',') 
           within GROUP (ORDER BY server.rep_server_name) 
           FROM server, rep_server
           WHERE prot.prot_key=rep_server.prot_key 
             AND rep_server.server_key = server.server_key) 
                                                       replication_server_list
  from prot
  join sl on prot.sl_key = sl.sl_key
  left outer join poll on prot.poll_key = poll.poll_key
>>>
 
define create_comment_7
<<<
begin
execute immediate 'comment on table ra_protection_policy is '||
'''This view lists the protection policies defined for this Recovery Appliance.''';
 
execute immediate 'comment on column ra_protection_policy.' ||
'policy_name is '||
'''The user-created name of the protection policy.''';
 
execute immediate 'comment on column ra_protection_policy.' ||
'description is '||
'''The protection policy description.''';
 
execute immediate 'comment on column ra_protection_policy.' ||
'prot_key is '||
'''The primary key for this protection policy in the Recovery Appliance metadata database.''';
 
execute immediate 'comment on column ra_protection_policy.' ||
'sl_name is '||
'''The name of the Recovery Appliance storage location used by this protection policy.''';
 
execute immediate 'comment on column ra_protection_policy.' ||
'sl_key is '||
'''The primary key of the Recovery Appliance storage location used by this protection policy.''';
 
execute immediate 'comment on column ra_protection_policy.' ||
'polling_name is '||
'''The name of the backup polling policy assigned to this protection policy.''';
 
execute immediate 
'comment on column ra_protection_policy.' ||
'recovery_window_goal is '||
'''The recovery window goal for restoring backups stored on disk.''';
 
execute immediate
'comment on column ra_protection_policy.' ||
'max_retention_window is '||
'''The maximum amount of time that the Recovery Appliance must retain disk backups.''';
 
execute immediate 
'comment on column ra_protection_policy.' ||
'recovery_window_sbt is '||
'''The recovery window for restoring backups stored on tape.''';
 
execute immediate
'comment on column ra_protection_policy.' ||
'guaranteed_copy is '||
'''The status of the guaranteed copy setting: ' ||
  '<Emphasis Role = "CodeInline">YES</Emphasis> means that ' ||
  'the Recovery Appliance replicates backups or copies them to tape before deleting them; ' ||
  '<Emphasis Role = "CodeInline">NO</Emphasis> means that ' ||
  'the Recovery Appliance accepts new backups even if old backups ' ||
  'must be purged because free space is low.''';
 
execute immediate
'comment on column ra_protection_policy.' ||
'unprotected_window is '||
'''The point beyond which recovery is not possible unless additional redo is available.''';
 
execute immediate 
'comment on column ra_protection_policy.' ||
'replication_server_list is '||
'''The list of replication server configurations associated with this protection policy.''';
end;
>>>
 
define create_rs_database
<<<
create or replace view ra_database as
  with nodedata (db_key, db_timezone, odbsysdate) as
  (
  select db_key
       , max(db_timezone)
       , cast((systimestamp at time zone to_char(max(db_timezone))) as date)
    from node
   where substr(node.db_unique_name,1,1) <> '$'
   group by db_key   
  )
  , rgd(db_key, recovery_goal_days) as
  (
  select db_key,
         to_number(extract(day    from recovery_window_goal))
       + to_number(extract(hour   from recovery_window_goal)) / (24)
       + to_number(extract(minute from recovery_window_goal)) / (24*60)
    FROM odb
  )
  , rws (db_key, recovery_window_space) as
  (
--
--
  select db_key,
         case 
           when osc.recovery_window_start is null
             or osc.bdf1count  < 3
             or (odbsysdate - osc.recovery_window_start) <= 0
           then odb.reserved_space
           else
             ceil( 
                   ( 
                     ( (odb.total_allocation - osc.footprint) 
                     * rgd.recovery_goal_days 
                     / (odbsysdate - osc.recovery_window_start)
                     )
                     + osc.footprint
                   )
                   / odb.sl_min_alloc
                 )
             * odb.sl_min_alloc
         end
    from odb
         join rgd using (db_key)
         join nodedata using (db_key)
         left outer join odb_stats_cache osc using (db_key)
  )
--
  , lo (db_key, task_exists) as
--
--
  (
  select db_key, nvl2(task_id, 1, 0)
    from odb
         left outer join task using (db_key)
   where nvl(task_type, 310) = 310 /*task_optimize_chunks_df*/
     and rownum = 1
  )
  select db.reg_db_unique_name db_unique_name,
         db_key,
         DECODE(db_state, NULL, 'NO',
                          1, 'YES',
                             'UNKNOWN') deleting,
         db_id dbid,
         create_time creation_time,
         prot_name policy_name,
         sl_name storage_location,
         recovery_window_goal,
         prot_max_retention_window max_retention_window,
         prot_recovery_window_sbt recovery_window_sbt,
         db_timezone timezone,
         total_allocation/(1024*1024*1024) space_usage,
         reserved_space/(1024*1024*1024) disk_reserved_space,
         prot_disk_cache guaranteed_copy,
         cumulative_usage/(1024*1024*1024) cumulative_usage,
         cumulative_rep_usage/(1024*1024*1024) replication_usage,
         cumulative_sbt_usage/(1024*1024*1024) sbt_usage,
         DECODE(odb.pending_rep_setup, NULL, NULL,
                                       'Y', 'PENDING',
                                       'N', 'SUCCESS',
                                            'UNKNOWN') replication_setup_status,
         case when lo.task_exists = 0
              then last_optimize else prev_optimize end last_optimize,
         last_validate last_validate,
         last_crosscheck last_crosscheck,
         sls_used storage_location_count,
         DECODE(odb.move_phase, NULL, 'NOT MOVING',
                                       1, 'PENDING MOVE',
                                       2, 'STARTING MOVE',
                                       3, 'MOVING BLOCK POOLS',
                                       4, 'MOVING FILES',
                                          'UNKNOWN') storage_movement_phase,
         osc.db_size/(1024*1024*1024) size_estimate,
         rws.recovery_window_space/(1024*1024*1024) recovery_window_space,
         osc.deduplication_factor,
         (odbsysdate - osc.minimum_recovery_start) * to_dsinterval('1 0:0:0') 
                                                       minimum_recovery_needed,
         prot_unprotected_window unprotected_window_threshold,
         numtodsinterval(ruw.unprotected, 'day') unprotected_window,
         ruw.nzdl_active
  from odb
  join db using(db_key)
  join prot on (odb.future_prot_key = prot.prot_key)
  join rgd using (db_key)
  join sl ON odb.sl_key = sl.sl_key
  join nodedata using (db_key)
  join rai_unprotected_window ruw using(db_key) 
  left outer join odb_stats_cache osc using(db_key)
  left outer join rws using(db_key)
  left outer join lo using(db_key)
union all
  select db_unique_name,
         NULL db_key,
         'NO' deleting,
         NULL db_id,
         NULL creation_time,
         prot.prot_name policy_name,
         sl_name storage_location,
         prot_recovery_window_goal recovery_window_goal,
         prot_max_retention_window max_retention_window,
         prot_recovery_window_sbt recovery_window_sbt,
         NULL timezone,
         0 space_usage,
         reserved_space/(1024*1024*1024) disk_reserved_space,
         prot_disk_cache guaranteed_copy,
         0 cumulative_usage,
         0 replication_usage,
         0 sbt_usage,
         null replication_status,
         null last_optimize,
         null last_validate,
         null last_crosscheck,
         1 storage_location_count,
         'NOT MOVING' storage_movement_phase,
         NULL size_estimate,
         NULL recovery_window_space,
         NULL deduplication_factor,
         NULL minimum_recovery_needed,
         prot_unprotected_window unprotected_window_threshold,
         NULL unprotected_window,
         'NO' nzdl_active
  from unreg_database u
  join prot using(prot_key)
  join sl ON u.sl_key = sl.sl_key
>>>
 
define create_comment_8
<<<
begin
execute immediate 'comment on table ra_database is ' ||
'''This view lists the databases protected by this Recovery Appliance.''';
 
execute immediate 'comment on column ra_database.' ||
'db_unique_name is '||
'''The unique name of this protected database.''';
 
execute immediate 'comment on column ra_database.' ||
'db_key is '||
'''The primary key for this database in the Recovery Appliance metadata database.''';
 
execute immediate 'comment on column ra_database.' ||
'deleting is '||
'''<Emphasis Role = "CodeInline">YES</Emphasis> if this ' ||
  'database is currently being deleted.''';
 
execute immediate 'comment on column ra_database.' ||
'dbid is '||
'''The DBID for this protected database.''';
 
execute immediate 'comment on column ra_database.' ||
'creation_time is '||
'''The time when this database was added to the Recovery Appliance.''';
 
execute immediate 'comment on column ra_database.' ||
'policy_name is '||
'''The name of the protection policy used by this database.''';
 
execute immediate 'comment on column ra_database.' ||
'storage_location is '||
'''The name of the Recovery Appliance storage location used by this protected database.''';
 
execute immediate 'comment on column ra_database.' ||
'recovery_window_goal is '||
'''The recovery window goal for backups on disk, as specified in the protection policy.''';
 
execute immediate 'comment on column ra_database.' ||
'max_retention_window is '||
'''The maximum amount of time to retain disk backups. The Recovery Appliance deletes ' ||
  'disk backups when they are older than this window. However, backups may be retained ' ||
  'longer if deleting them would negatively affect the ' ||
  '<Emphasis Role = "CodeInline">recovery_window_goal</Emphasis> requirement.''';
 
execute immediate 'comment on column ra_database.' ||
'recovery_window_sbt is '||
'''The recovery window for backups on tape, as specified in the protection policy.''';
 
execute immediate 'comment on column ra_database.' ||
'timezone is '||
'''The time zone offset of the protected database.''';
 
execute immediate 'comment on column ra_database.' ||
'space_usage is '||
'''The amount of disk space (in GB) currently used by this protected database.''';
 
execute immediate 'comment on column ra_database.' ||
'disk_reserved_space is '||
'''The amount of disk space (in GB) reserved for the exclusive use of this database''';
 
execute immediate 'comment on column ra_database.' ||
'guaranteed_copy is '||
'''The status of the guaranteed copy setting: ' ||
  '<Emphasis Role = "CodeInline">YES</Emphasis> means that ' ||
  'the Recovery Appliance replicates backups or copies them to tape before deleting them; ' ||
  '<Emphasis Role = "CodeInline">NO</Emphasis> means that ' ||
  'the Recovery Appliance accepts new backups even if old backups ' ||
  'must be purged because free space is low.''';
 
execute immediate 'comment on column ra_database.' ||
'cumulative_usage is '||
'''The cumulative amount of disk space (in GB) allocated for ' ||
  'all backups received for this database.''';
 
execute immediate 'comment on column ra_database.' ||
'replication_usage is '||
'''The cumulative amount of disk space (in GB) replicated ' ||
  'for this protected database.''';
 
execute immediate 'comment on column ra_database.' ||
'sbt_usage is '||
'''The cumulative amount of disk space (in GB) sent to SBT from this ' ||
  'protected database.''';
 
execute immediate 'comment on column ra_database.' ||
'replication_setup_status is '||
'''The status of the setup for the downstream replication appliance for this database.''';
 
execute immediate 'comment on column ra_database.' ||
'last_optimize is '||
'''The time when the most recent data placement optimization was completed.''';
 
execute immediate 'comment on column ra_database.' ||
'last_validate is '||
'''The time when the most recent validation of backup data was completed.''';
 
execute immediate 'comment on column ra_database.' ||
'last_crosscheck is '||
'''The time when the most recent crosscheck of backup data was completed.''';
 
execute immediate 'comment on column ra_database.' ||
'storage_location_count is '||
'''The number of storage locations used by this database. If greater than ' ||
  'one, then a storage location movement operation is in progress for this database.''';
 
execute immediate 'comment on column ra_database.' ||
'storage_movement_phase is '||
'''The phase of the storage location movement operation for this protected database.''';
 
execute immediate 'comment on column ra_database.' ||
'size_estimate is '||
'''The estimated space (in GB) consumed by the entire protected database.''';
 
execute immediate 'comment on column ra_database.' ||
'recovery_window_space is '||
'''The estimated space (in GB) that is needed to meet the recovery window goal.''';
 
execute immediate 'comment on column ra_database.' ||
'deduplication_factor is '||
'''The ratio of the total size of backups to the consumed space.''';
 
execute immediate 'comment on column ra_database.' ||
'minimum_recovery_needed is '||
'''The minimum interval needed to restore the protected database to ' ||
  'the present.''';
 
execute immediate 'comment on column ra_database.' ||
'unprotected_window_threshold is '||
'''The user-specified maximum amount of data loss for protected databases ' ||
  'that are subject to a protection policy. The Recovery Appliance generates ' ||
  'an alert if the unprotected window of this database exceeds this value.''';
 
execute immediate 'comment on column ra_database.' ||
'unprotected_window is '||
'''The point beyond which recovery is impossible unless additional redo is available.''';
 
execute immediate 'comment on column ra_database.' ||
'nzdl_active is '||
'''<Emphasis Role = "CodeInline">YES</Emphasis> if real-time redo transport is ' ||
  'active. <Emphasis Role = "CodeInline">NO</Emphasis> if redo has ' ||
  'not recently been received.''';
end;
>>>
 
define create_rs_database_storage
<<<
create or replace view ra_database_storage_usage as
  select db.reg_db_unique_name db_unique_name,
         o.db_key,
         sl.sl_name storage_location,
         o.used_space /(1024*1024*1024) used_space
  from (select db_key, sl_key, used_space from odb
        union all
        select db_key, sl_key, dbsl_used_space used_space from dbsl) o
  join sl ON o.sl_key = sl.sl_key
  left outer join db on db.db_key = o.db_key
>>>
 
define create_comment_8a
<<<
begin
execute immediate 'comment on table ra_database_storage_usage is '||
'''This view lists the storage usage for each protected database.''';
 
execute immediate 'comment on column ra_database_storage_usage.' ||
'db_unique_name is '||
'''The unique name of the protected database.''';
 
execute immediate 'comment on column ra_database_storage_usage.' ||
'db_key is '||
'''The primary key for this protected database in the ' ||
  'Recovery Appliance metadata database.''';
 
execute immediate 'comment on column ra_database_storage_usage.' ||
'storage_location is '||
'''The name of the Recovery Appliance storage location used by this protected database.''';
 
execute immediate 'comment on column ra_database_storage_usage.' ||
'used_space is ' ||
'''The amount of space (in GB) used by this database in its ' ||
  'Recovery Appliance storage locations. Backups for a protected database ' ||
  'typically reside in only one storage location, but can reside ' ||
  'in two locations when a movement operation is in progress.''';
end;
>>>
 
define create_rs_task
<<<
create or replace view ra_task
       (task_id, task_type, priority, state, waiting_on, 
        creation_time, completion_time,
        elapsed_seconds, error_count, interrupt_count, last_interrupt_time,
        execute_instance_id, last_execute_time,
        db_unique_name, db_key, sl_name, sl_key, ospid, instance_id,
        archived) as
  select t.task_id, 
         tasktypenames.task_type_name, 
         priority, state, waiting_on, t.creation_time, t.completion_time,
         ((extract(second from (t.elapsed_time))) +
          (extract(minute from (t.elapsed_time)) * 60) +
          (extract(hour   from (t.elapsed_time)) * 3600) +
          (extract(day    from (t.elapsed_time)) * 86400)),
         nvl(t.error_count,0), nvl(t.interrupt_count,0), last_interrupt_time, 
         t.execute_inst_id, last_execute_time,
         db.reg_db_unique_name,
         t.db_key, sl.sl_name, t.sl_key, t.ospid, t.instance_id, archived
  from (select task_id, task_type, priority,
               (case state
                  when 1 then 'EXECUTABLE'
                  when 2 then NVL2(a.sid, 'RUNNING', 'RETRYING')
                  when 3 then 'COMPLETED'
                  when 4 then 'ORDERING_WAIT'
                  when 5 then (case pending_interrupt 
                                 when -1 then 'SERVLET_WAIT'
                                 when -2 then 'SPACE_WAIT'
                                 when -3 then 'OPT_DF_WAIT'
                                 when -4 then 'TEST_WAIT'
                                 when -5 then 'RESOURCE_WAIT'
                                 when -6 then 'STALL_WHEN_WAIT'
                                 when -7 then 'LIBRARY_WAIT'
                                 when -8 then 'POOL_FULL_WAIT'
                                 else 'TASK_WAIT' end)
                  when 6 then 'RESTORE_WAIT'
                  when 8 then 'FAILED'
                  when 9 then 'CANCEL'
                  when 10 then 'CANCELING'
                  when 11 then 'CANCELED'
                  else 'UNKNOWN' end) state,
               (case when pending_interrupt < 0 then null
                 else pending_interrupt end) waiting_on,
               schedule_time creation_time, completion_time, 
               (case when s.ba_session_id is not null
                     then (elapsed_time + (systimestamp - s.last_task_start))
                     else elapsed_time end)  elapsed_time,
               error_count, interrupt_count, last_interrupt_time,
               execute_inst_id, last_execute_time, db_key, sl_key,
               s.spid ospid, s.instance_id, 'N' archived
        from task 
             left outer join sessions s on (s.current_task = task.task_id)
             left outer join sys.rai_active_sessions a
                             on (    a.inst_id = s.instance_id
                                 and a.audsid = s.audsid
                                 and a.sid = s.sid
                                 and a.serial# = s.serial#
                                 and a.logon_time = s.logon_time)
        union all
        select task_id, task_type, priority,
               DECODE(state, 
                      3,  'COMPLETED',
                      8,  'FAILED', 
                      11, 'CANCELED',
                          'UNKNOWN' || state) state, NULL waiting_on,
               schedule_time, completion_time, elapsed_time,
               error_count, interrupt_count, last_interrupt_time,
               execute_inst_id,  last_execute_time, db_key,
               th.sl_key, NULL ospid,
               NULL instance_id, 'Y' archived
        from task_history th
        where (th.task_type < 
                            2000 /*dbms_ra_scheduler.task_session_times*/)) t
        left outer join sl on sl.sl_key = t.sl_key
        join tasktypenames using (task_type)
        left outer join db on db.db_key = t.db_key
>>>
 
define create_comment_9
<<<
begin
execute immediate 'comment on table ra_task is '||
'''This view lists queued background tasks and their run statuses.''';
 
execute immediate 'comment on column ra_task.' ||
'task_id is '||
'''The ID for the task.''';
 
execute immediate 'comment on column ra_task.' ||
'task_type is '||
'''The type of processing performed by the task.''';
 
execute immediate 'comment on column ra_task.' ||
'priority is '||
'''The run priority for the task.''';
 
execute immediate 'comment on column ra_task.' ||
'state is '||
'''The processing state for the task: <Emphasis Role = "CodeInline">' ||
  'EXECUTABLE</Emphasis>, ' ||
  '<Emphasis Role = "CodeInline">RUNNING</Emphasis>, ' ||
  '<Emphasis Role = "CodeInline">COMPLETED</Emphasis>, ' ||
  '<Emphasis Role = "CodeInline">TASK_WAIT</Emphasis>, ' ||
  '<Emphasis Role = "CodeInline">FAILED</Emphasis>, ' ||
  'and so on.''';
 
execute immediate 'comment on column ra_task.' ||
'waiting_on is '||
'''The ID of the task that is blocking this task when its state ' ||
  'is <Emphasis Role = "CodeInline">TASK_WAIT</Emphasis>.''';
 
execute immediate 'comment on column ra_task.' ||
'creation_time is '||
'''The time of task creation.''';
 
execute immediate 'comment on column ra_task.' ||
'completion_time is '||
'''The timestamp for task completion. The column is null ' ||
  'if the task is not complete.''';
 
execute immediate 'comment on column ra_task.' ||
'elapsed_seconds is '||
'''The elapsed run time (in seconds) for the task.''';
 
execute immediate 'comment on column ra_task.' ||
'error_count is '||
'''Number of times that the task had errors''';
 
execute immediate 'comment on column ra_task.' ||
'interrupt_count is '||
'''The number of times that the task was interrupted.''';
 
execute immediate 'comment on column ra_task.' ||
'last_interrupt_time is '||
'''The most recent time that the task was interrupted.''';
 
execute immediate 'comment on column ra_task.' ||
'execute_instance_id is '||
'''The ID of the database instance on which the task must run. ' ||
  'The column is null if the task can run on any instance.''';
 
execute immediate 'comment on column ra_task.' ||
'last_execute_time is '||
'''The most recent time that the task was restarted.''';
 
execute immediate 'comment on column ra_task.' ||
'db_unique_name is '||
'''The unique name of the protected database for which the task is running.''';
 
execute immediate 'comment on column ra_task.' ||
'db_key is '||
'''The primary key of the protected database for which the task is running.''';
 
execute immediate 'comment on column ra_task.' ||
'sl_name is '||
'''The name of the Recovery Appliance storage location used by the task.''';
 
execute immediate 'comment on column ra_task.' ||
'sl_key is '||
'''The primary key of the Recovery Appliance storage location used by the task.''';
 
execute immediate 'comment on column ra_task.' ||
'ospid is '||
'''The platform-specific ID of the process in which the task is current running.''';
 
execute immediate 'comment on column ra_task.' ||
'instance_id is '||
'''The ID of the database instance on which the task is currently running.''';
 
execute immediate 'comment on column ra_task.' ||
'archived is '||
'''The archive status of the task: ' ||
  '<Emphasis Role = "CodeInline">Y</Emphasis> ' ||
  'if it has moved to the archive; otherwise, <Emphasis Role = ' ||
  '"CodeInline">N</Emphasis>.''';
end;
>>>
 
define create_rs_time_usage
<<<
create or replace view ra_time_usage (total_time, idle_time) as
  select elapsed, elapsed - used
  from (select sum((extract(second from (elapsed))) +
                   (extract(minute from (elapsed)) * 60) +
                   (extract(hour   from (elapsed)) * 3600) +
                   (extract(day    from (elapsed)) * 86400)) elapsed
              /* Elapsed time for active sessions */
        from (select (nvl(last_task_start, systimestamp) - start_time) elapsed
              from sessions
              union all
              /* Elapsed time for dead sessions */
              select elapsed_time elapsed
              from task_history
              join tasktypenames using (task_type)
              where tasktypenames.task_type_name = 'SESSION_TIMES'
                and elapsed_time is not null)),
       (select sum((extract(second from (used))) +
                   (extract(minute from (used)) * 60) +
                   (extract(hour   from (used)) * 3600) +
                   (extract(day    from (used)) * 86400)) used
             /* Used time from completed tasks */
        from (select elapsed_time used
              from task_history
              join tasktypenames using (task_type)
              where tasktypenames.task_type_name != 'SESSION_TIMES'
                and elapsed_time is not null
              union all
              /* Used time from active tasks */
              select elapsed_time used
              from task
              where elapsed_time is not null))
>>>
 
define create_comment_10
<<<
begin
execute immediate 'comment on table ra_time_usage is '||
'''This view describes the Recovery Appliance elapsed and idle time ' ||
  'for the last 30 days.''';
 
execute immediate 'comment on column ra_time_usage.' ||
'total_time is '||
'''The sum of the elapsed times (in seconds) across all sessions.''';
 
execute immediate 'comment on column ra_time_usage.' ||
'idle_time is '||
'''The sum of the idle times (in seconds) across all sessions.''';
end;
>>>
 
define create_rs_restore_range_i
<<<
  create or replace view rai_restore_range
       as select db_key,
                 low_time,
                 high_time,
                 low_scn,
                 high_scn,
                 low_dbinc_key,
                 high_dbinc_key
                 from TABLE(rc_listRsRangePipe('RA$ANY'))
>>>
 
define create_rs_disk_restore_range_i
<<<
  create or replace view rai_disk_restore_range
       as select db_key,
                 low_time,
                 high_time,
                 low_scn,
                 high_scn,
                 low_dbinc_key,
                 high_dbinc_key
                 from TABLE(rc_listRsRangePipe('RA$DISK'))
>>>
 
define create_rs_sbt_restore_range_i
<<<
  create or replace view rai_sbt_restore_range
       as select db_key,
                 low_time,
                 high_time,
                 low_scn,
                 high_scn,
                 low_dbinc_key,
                 high_dbinc_key
                 from TABLE(rc_listRsRangePipe('RA$SBT'))
>>>
 
define create_rs_restore_range
<<<
  create or replace view ra_restore_range
       as select db_key,
                 low_time,
                 high_time,
                 low_scn,
                 high_scn,
                 low_dbinc_key,
                 high_dbinc_key,
                 last_updated
                 from rrcache
                 where range_type = 'RA$ANY'
>>>
 
define create_rs_disk_restore_range
<<<
  create or replace view ra_disk_restore_range
       as select db_key,
                 low_time,
                 high_time,
                 low_scn,
                 high_scn,
                 low_dbinc_key,
                 high_dbinc_key,
                 last_updated
                 from rrcache
                 where range_type = 'RA$DISK'
>>>
 
define create_rs_sbt_restore_range
<<<
  create or replace view ra_sbt_restore_range
       as select db_key,
                 low_time,
                 high_time,
                 low_scn,
                 high_scn,
                 low_dbinc_key,
                 high_dbinc_key,
                 last_updated
                 from rrcache
                 where range_type = 'RA$SBT'
>>>
 
define create_comment_rs_restore_range
<<<
begin
execute immediate 'comment on table ra_restore_range is ' ||
'''This view describes the restore range of each protected database ' ||
  'from all backups on this Recovery Appliance.''';
 
execute immediate 'comment on column ra_restore_range.' ||
'db_key is ' ||
'''The primary key of the protected database.''';
 
execute immediate 'comment on column ra_restore_range.' ||
'low_time is ' ||
'''The earliest time to which the protected database can be restored.''';
 
execute immediate 'comment on column ra_restore_range.' ||
'high_time is ' ||
'''The latest time to which the protected database can be restored.''';
 
execute immediate 'comment on column ra_restore_range.' ||
'low_scn is ' ||
'''The lowest SCN to which the database can be restored.''';
 
execute immediate 'comment on column ra_restore_range.' ||
'high_scn is ' ||
'''The highest SCN to which the protected database can be restored.''';
 
execute immediate 'comment on column ra_restore_range.' ||
'low_dbinc_key is ' ||
'''The primary key for the incarnation of the target database to which the low SCN belongs.''';
 
execute immediate 'comment on column ra_restore_range.' ||
'high_dbinc_key is ' ||
'''The primary key for the incarnation of the target database to which the high SCN belongs.''';
 
execute immediate 'comment on column ra_restore_range.' ||
'last_updated is ' ||
'''The time that the restore range for this database was updated.''';
end;
 
>>>
 
define create_comment_rs_disk_restore_range
<<<
begin
execute immediate 'comment on table ra_disk_restore_range is ' ||
'''The restore range of each protected database from disk backups ' ||
  'on this Recovery Appliance.''';
 
execute immediate 'comment on column ra_disk_restore_range.' ||
'db_key is ' ||
'''The primary key of the protected database.''';
 
execute immediate 'comment on column ra_disk_restore_range.' ||
'low_time is ' ||
'''The earliest time to which the protected database can be restored.''';
 
execute immediate 'comment on column ra_disk_restore_range.' ||
'high_time is ' ||
'''The latest time to which the protected database can be restored.''';
 
execute immediate 'comment on column ra_disk_restore_range.' ||
'low_scn is ' ||
'''The lowest SCN to which the protected database can be restored.''';
 
execute immediate 'comment on column ra_disk_restore_range.' ||
'high_scn is ' ||
'''The highest SCN to which the protected database can be restored.''';
 
execute immediate 'comment on column ra_disk_restore_range.' ||
'low_dbinc_key is ' ||
'''The primary key for the incarnation of the target database to which ' ||
  '<Emphasis Role = "CodeInline">LOW_SCN</Emphasis> belongs.''';
 
execute immediate 'comment on column ra_disk_restore_range.' ||
'high_dbinc_key is ' ||
'''The primary key for the incarnation of the target database to which ' ||
  '<Emphasis Role = "CodeInline">HIGH_SCN</Emphasis> belongs.''';
 
execute immediate 'comment on column ra_disk_restore_range.' ||
'last_updated is ' ||
'''The time that the restore range for this protected database was updated.''';
end;
>>>
 
define create_comment_rs_sbt_restore_range
<<<
begin
execute immediate 'comment on table ra_sbt_restore_range is ' ||
'''This view describes the restore range of each database from SBT backups on the Recovery Appliance.''';
 
execute immediate 'comment on column ra_sbt_restore_range.' ||
'db_key is ' ||
'''The primary key of the protected database.''';
 
execute immediate 'comment on column ra_sbt_restore_range.' ||
'low_time is ' ||
'''The earliest time to which the database can be restored.''';
 
execute immediate 'comment on column ra_sbt_restore_range.' ||
'high_time is ' ||
'''The latest time to which the database can be restored.''';
 
execute immediate 'comment on column ra_sbt_restore_range.' ||
'low_scn is ' ||
'''The lowest SCN to which the database can be restored.''';
 
execute immediate 'comment on column ra_sbt_restore_range.' ||
'high_scn is ' ||
'''The highest SCN to which the database can be restored.''';
 
execute immediate 'comment on column ra_sbt_restore_range.' ||
'low_dbinc_key is ' ||
'''The primary key for the incarnation of the target database to which the low SCN belongs.''';
 
execute immediate 'comment on column ra_sbt_restore_range.' ||
'high_dbinc_key is ' ||
'''The primary key for the incarnation of the target database to which the high SCN belongs.''';
 
execute immediate 'comment on column ra_sbt_restore_range.' ||
'last_updated is ' ||
'''The time that the restore range for this protected database was last updated.''';
end;
>>>
 
define create_rs_sbt_library
<<<
create or replace view ra_sbt_library
  (lib_key, lib_name, drives, restore_drives, parms, send, status,
   last_error_text)
  as
   with errsbt as
      (select lib_key,
              min(error_text) keep(
              dense_rank last order by task_id nulls first) error_text
         from (select e.error_text, s.lib_key, s.task_id
                 from sbt_task_history s, error_log e
               where e.task_id = s.task_id
                 and e.status = 'ACTIVE'
               union all
               select e.error_text, s.lib_key, s.task_id
                 from sbt_task s, error_log e 
                where e.task_id = s.task_id
                  and e.status = 'ACTIVE')
       group by lib_key)
   select lib.lib_key,
          lib.lib_name,
          lib.drives,
          lib.restore_drives,
          lib.parms,
          lib.send,
          decode(lib.status, 'R', 'READY', 'P', 'PAUSE', 'E', 'ERROR', NULL),
          errsbt.error_text
     from sbt_lib_desc lib
     left outer join errsbt
       on errsbt.lib_key = lib.lib_key
>>>
 
define create_comment_rs_sbt_library
<<<
begin
execute immediate 'comment on table ra_sbt_library is ' ||
'''This view lists the defined SBT libraries.''';
 
execute immediate
'comment on column ra_sbt_library.' ||
'lib_key is '||
'''The key of this SBT library in the Recovery Appliance metadata database.''';  
 
execute immediate 'comment on column ra_sbt_library.' ||
'lib_name is ' ||
'''The SBT library name.''';
 
execute immediate 'comment on column ra_sbt_library.' ||
'drives is ' ||
'''The number of drives available for use by this SBT library.''';
 
execute immediate 'comment on column ra_sbt_library.' ||
'restore_drives is ' ||
'''The number of drives reserved for restore operations.''';
 
execute immediate 'comment on column ra_sbt_library.' ||
'parms is ' ||
'''The SBT parameters passed while allocating an RMAN channel.''';
 
execute immediate 'comment on column ra_sbt_library.' ||
'send is ' ||
'''The <Emphasis Role = "CodeInline">SEND</Emphasis> command string ' ||
  'passed to the allocated channel.''';
 
execute immediate 'comment on column ra_sbt_library.' ||
'status is ' ||
'''The SBT library status: <Emphasis Role = "CodeInline">READY</Emphasis>, '||
  '<Emphasis Role = "CodeInline">PAUSE</Emphasis>, ' ||
  '<Emphasis Role = "CodeInline">ERROR</Emphasis>, or null.''';
 
execute immediate 'comment on column ra_sbt_library.' ||
'last_error_text is '||
'''The most recent error text of the task that failed.''';
end;
>>>
 
define create_rs_sbt_attr_set
<<<
create or replace view ra_sbt_attribute_set
  (attribute_set_key, attribute_set_name, lib_name, streams,
   poolid, parms, send)
  as select attr.attr_key,
            attr.attr_name,
            lib.lib_name,
            attr.streams,
            attr.poolid,
            attr.parms,
            attr.send
       from sbt_lib_desc lib, sbt_attr_set attr
      where lib.lib_key = attr.lib_key
>>>
 
define create_comment_rs_sbt_attr_set
<<<
begin
execute immediate 'comment on table ra_sbt_attribute_set is ' ||
'''This view describes the defined SBT attribute set.''';
  
execute immediate
'comment on column ra_sbt_attribute_set.' ||
'attribute_set_key is '||
'''The key of this SBT attribute set in the Recovery Appliance metadata database.''';  
 
execute immediate
'comment on column ra_sbt_attribute_set.' ||
'attribute_set_name is '||
'''The SBT attribute set name.''';  
 
execute immediate
'comment on column ra_sbt_attribute_set.' ||
'lib_name is '||
'''The name of the SBT library object with which this attribute set is associated.''';  
 
execute immediate 'comment on column ra_sbt_attribute_set.' ||
'streams is ' ||
'''The number of parallel streams available for jobs that run with this attribute set.''';
  
execute immediate 'comment on column ra_sbt_attribute_set.' ||
'poolid is ' ||
'''The media pool identifier.''';
 
execute immediate 'comment on column ra_sbt_attribute_set.' ||
'parms is ' ||
'''The SBT parameters passed while allocating the RMAN channel.''';
 
execute immediate 'comment on column ra_sbt_attribute_set.' ||
'send is ' ||
'''The <Emphasis Role = "CodeInline">SEND</Emphasis> command string passed' ||
  ' to the allocated channel.''';
end;
>>>
 
define create_rs_sbt_job
<<<
create or replace view ra_sbt_job
  (template_key, template_name, attribute_set_name, lib_name, policy_name, 
   db_key, db_unique_name, backup_type, from_tag, 
   priority, copies, last_schedule_time, window)
  as select job.template_key,
            job.template_name,
            attr.attr_name,
            lib.lib_name,
            prot.prot_name,
            job.db_key,
            case
             when job.db_key is not null then
                db.reg_db_unique_name
             else null end,
            case job.bck_type
             when 1  then 'ALL'
             when 2  then 'FULL'
             when 4  then 'INCR'
             when 6  then 'FULL, INCR'
             when 8  then 'ARCH'
             when 10 then 'FULL, ARCH'
             when 12 then 'INCR, ARCH'
             when 14 then 'FULL, INCR, ARCH'
             when 32 then 'TAPE RESERVE'
             else '?'
            end bck_type,
            job.from_tag,
            job.priority,
            job.copies,
            job.schedule_time,
            job.window
       from sbt_lib_desc lib, sbt_attr_set attr, sbt_job_template job
       left outer join prot
         on prot.prot_key = job.prot_key
       left outer join db 
       on db.db_key = job.db_key
      where ((lib.lib_key = attr.lib_key
        and job.attr_key = attr.attr_key) or (job.bck_type = 32))
>>>
 
define create_comment_rs_sbt_job
<<<
begin
execute immediate 'comment on table ra_sbt_job is ' ||
'''This view describes the defined SBT job templates.''';
 
execute immediate 'comment on column ra_sbt_job.' ||
'template_key is ' ||
'''The key of this SBT job template in the Recovery Appliance metadata database.''';
 
execute immediate 'comment on column ra_sbt_job.' ||
'template_name is ' ||
'''The SBT job template name.''';
 
execute immediate 'comment on column ra_sbt_job.' ||
'attribute_set_name is ' ||
'''The SBT attribute set name.''';
 
execute immediate 'comment on column ra_sbt_job.' ||
'lib_name is ' ||
'''The SBT library name.''';
 
execute immediate 'comment on column ra_sbt_job.' || 
'policy_name is ' ||
'''The protection policy specifying databases whose backups ' ||
  'the Recovery Appliance considers eligible for copying to tape.''';
 
execute immediate 'comment on column ra_sbt_job.' ||
'db_key is ' ||
'''The primary key of the protected database whose backups ' ||
  'the Recovery Appliance considers eligible for copying to tape.''';
 
execute immediate 'comment on column ra_sbt_job.' ||
'db_unique_name is ' ||
'''The unique name of the protected database whose backups ' ||
  'the Recovery Appliance considers eligible for copying to tape.''';
 
execute immediate 'comment on column ra_sbt_job.' ||
'backup_type is ' ||
'''The types of backups to be copied to tape by this job: ' ||
  '<Emphasis Role = "CodeInline">ALL</Emphasis>, ' ||
  '<Emphasis Role = "CodeInline">FULL</Emphasis>, ' ||
  '<Emphasis Role = "CodeInline">INCR</Emphasis>, ' ||
  '<Emphasis Role = "CodeInline">ARCH</Emphasis>, or ' ||
  '<Emphasis Role = "CodeInline">TAPE_RESERVE</Emphasis>.''';
 
execute immediate 'comment on column ra_sbt_job.' ||
'from_tag is ' ||
'''The backups with the specified tag to be copied to tape by this job.''';
 
execute immediate 'comment on column ra_sbt_job.' ||
'priority is ' ||
'''The priority for scheduling this job.''';
 
execute immediate 'comment on column ra_sbt_job.' ||
'copies is ' ||
'''The number of copies to be created on tape.''';
 
execute immediate 'comment on column ra_sbt_job.' ||
'last_schedule_time is ' ||
'''The last time at which this SBT job was scheduled to run.''';
 
execute immediate 'comment on column ra_sbt_job.' ||
'window is ' ||
'''The time allotted for copy tasks to start for this job.''';
end;
>>>
 
define create_rs_sbt_task
<<<
create or replace view ra_sbt_task
  (task_id, state, completion_time, elapsed_seconds, execute_instance_id,
   error_count, error_text, db_unique_name, db_key, restore_task,
   bs_key, piece#, copies, template_name, attribute_set_name, lib_name,
   replication, filename, start_time, bytes, total)
  as 
  with bpnew as 
  (select bs_key, piece#, 
          max(bytes) total 
     from bp
    where bp.ba_access != 'U'
      and bp.status != 'D'
    group by bs_key, piece#)
   select st.task_id, t.state, t.completion_time, t.elapsed_seconds,
          t.execute_instance_id, t.error_count, e.error_text,
          t.db_unique_name, t.db_key,
          decode(st.restore, 'Y', 'YES', 'NO'),
          st.bs_key, st.piece#, st.copies, job.template_name,
          attr.attr_name, lib.lib_name,
          NVL2(lib.server_key, 'YES', 'NO'),
          isp.filename, isp.start_time, 
          decode(t.state, 'COMPLETED', bpnew.total, isp.bytes), bpnew.total
     from ra_task t, sbt_lib_desc lib,
          (select task_id, restore, bs_key, piece#, copies,
                  lib_key, attr_key, template_key
             from sbt_task st
           union all
           select task_id, restore, bs_key, piece#, copies,
                  lib_key, attr_key, template_key
             from sbt_task_history sth) st
       left outer join error_log e
         on st.task_id = e.task_id
        and e.status = 'ACTIVE'
       left outer join sbt_attr_set attr
         on st.attr_key = attr.attr_key
       left outer join sbt_job_template job
         on st.template_key = job.template_key
       left outer join rai_sbt_performance isp
         on st.task_id = isp.task_id
        and st.piece# = isp.piece#
        and st.bs_key = isp.bs_key
       left outer join bpnew
         on st.piece# = bpnew.piece#
        and st.bs_key = bpnew.bs_key
     where st.task_id = t.task_id
       and st.lib_key = lib.lib_key
>>>
 
define create_comment_rs_sbt_task
<<<
begin
execute immediate 'comment on table ra_sbt_task is ' ||
'''This view lists the queued background SBT tasks and their run statuses.''';
 
execute immediate 'comment on column ra_sbt_task.' ||
'task_id is ' ||
'''The ID for the task.''';
 
execute immediate 'comment on column ra_sbt_task.' ||
'state is ' ||
'''The processing state for the task: ' ||
  '<Emphasis Role = "CodeInline">EXECUTABLE</Emphasis>, ' ||
  '<Emphasis Role = "CodeInline">RUNNING</Emphasis>, ' ||
  '<Emphasis Role = "CodeInline">COMPLETED</Emphasis>, ' ||
  '<Emphasis Role = "CodeInline">TASK_WAIT</Emphasis>, ' ||
  '<Emphasis Role = "CodeInline">FAILED</Emphasis>, ' ||
  'and so on.''';
 
execute immediate 'comment on column ra_sbt_task.' ||
'completion_time is ' ||
'''The timestamp for task completion. The column is null '||
  'if the task is not complete.''';
 
execute immediate 'comment on column ra_sbt_task.' ||
'elapsed_seconds is ' ||
'''The elapsed run time (in seconds) for the task.''';
 
execute immediate 'comment on column ra_sbt_task.' ||
'execute_instance_id is ' ||
'''The ID of the database instance ID on which the task must run. ' ||
  'The column is null if the task can run on any instance.''';
 
execute immediate 'comment on column ra_sbt_task.' ||
'error_count is '||
'''The number of times that the task had errors.''';
 
execute immediate 'comment on column ra_sbt_task.' ||
'error_text is '||
'''The error text for the task that failed.''';
 
execute immediate 'comment on column ra_sbt_task.' ||
'db_unique_name is ' ||
'''The unique name of the protected database for which the task is running.''';
 
execute immediate 'comment on column ra_sbt_task.' ||
'db_key is ' ||
'''The primary key of the protected database for which the task is running.''';
 
execute immediate 'comment on column ra_sbt_task.' ||
'restore_task is ' ||
'''The type of task: <Emphasis Role = "CodeInline">YES</Emphasis> if this ' ||
  'is a restore task; <Emphasis Role = "CodeInline">NO</Emphasis> if this ' ||
  'is a backup task.''';
 
execute immediate 'comment on column ra_sbt_task.' ||
'bs_key is ' ||
'''The key of the backup set that is accessed by this task.''';
 
execute immediate 'comment on column ra_sbt_task.' ||
'piece# is ' ||
'''The number of the backup piece that is accessed by this task.''';
 
execute immediate 'comment on column ra_sbt_task.' ||
'copies is ' ||
'''The number of copies created by this task.''';
 
execute immediate 'comment on column ra_sbt_task.' ||
'template_name is ' ||
'''The SBT job template to which this task belongs.''';
 
execute immediate 'comment on column ra_sbt_task.' ||
'attribute_set_name is ' ||
'''The name of the SBT attribute set to which this task belongs.''';
 
execute immediate 'comment on column ra_sbt_task.' ||
'lib_name is ' ||
'''The name of the SBT library used by this task.''';
 
execute immediate 'comment on column ra_sbt_task.' ||
'replication is ' ||
'''The type of task: <Emphasis Role = "CodeInline">YES</Emphasis> ' ||
  'if this is a replication task; ' ||
  '<Emphasis Role = "CodeInline">NO</Emphasis> ' ||
  'if this is an SBT task.''';
 
execute immediate 'comment on column ra_sbt_task.' ||
'filename is ' ||
'''The name of the backup file being read or written.''';
 
execute immediate 'comment on column ra_sbt_task.' ||
'start_time is ' ||
'''The start time of this task.''';
 
execute immediate 'comment on column ra_sbt_task.' ||
'bytes is ' ||
'''The number of bytes read or written so far.''';
 
execute immediate 'comment on column ra_sbt_task.' ||
'total is '||
'''The total number of bytes to be read or written.''';
end;
>>>
 
define create_rs_api_history
<<<
 
create or replace view ra_api_history
as select th.param_char2 results, 
          th.execute_time, 
          tasktypenames.task_type_name task_name, 
          th.param command_issued,
          ((extract(second from (th.elapsed_time))) + 
           (extract(minute from (th.elapsed_time)) * 60) + 
           (extract(hour   from (th.elapsed_time)) * 3600) +
           (extract(day    from (th.elapsed_time)) * 86400)
          ) elapsed_seconds
   from task_history th
   join tasktypenames using (task_type)
   join (select min(task_type) low, max(task_type) high
           from tasktypenames where task_type_name like 'API_%') limits ON(1=1)
   where (task_type between limits.low and limits.high)
   order by th.execute_time
>>>
 
define create_comment_rs_api_history
<<<
begin
execute immediate 'comment on table ra_api_history is ' ||
'''This view describes the history of user-issued API commands.''';
 
execute immediate 'comment on column ra_api_history.' ||
'results is ' ||
'''The results from running this command: ' ||
  '<Emphasis Role = "CodeInline">SUCCESS</Emphasis> ' ||
  'or <Emphasis Role = "CodeInline">FAIL</Emphasis>.''';
 
execute immediate 'comment on column ra_api_history.' ||
'execute_time is ' ||
'''The time at which the command started.''';
 
execute immediate 'comment on column ra_api_history.' ||
'task_name is ' ||
'''The name of the task.''';
 
execute immediate 'comment on column ra_api_history.' ||
'command_issued is ' ||
'''The full command as submitted by the user.''';
 
execute immediate 'comment on column ra_api_history.' ||
'elapsed_seconds is '||
'''The elapsed run time (in seconds) for the task.''';
end;
>>>
 
define create_rs_config
<<<
create or replace view ra_config
        (name, value) as
  select config.name, config.value
    from config
    where name not like '\_%' escape '\'
      and name <> 'compatible'
    order by config.name
>>>
 
define create_comment_rs_config
<<<
begin
execute immediate 'comment on table ra_config is ' ||
'''This view lists the user configuration settings.''';
 
execute immediate 'comment on column ra_config.' ||
'name is ' ||
'''The name of the configuration variable.''';
 
execute immediate 'comment on column ra_config.' ||
'value is ' ||
'''The value of the configuration variable''';
end;
>>>
 
define create_rs_replication_server
<<<
create or replace view ra_replication_server
  (replication_server_name, replication_server_state,
   protection_policy, rep_server_connect_name, proxy_http_address,
   proxy_timeout, sbt_library_name,
   sbt_library_parms, attribute_name, attribute_parms, wallet_path,
   wallet_alias, server_host) as
  select s.rep_server_name,
        decode(r.status,
           'C', 'CREATING',
           'D', 'DELETING',
           'T', 'TESTING COMMUNICATION',
           'A',
           decode(l.status, 'R', 'RUNNING', 'P', 'PAUSED', 'E', 'ERROR', NULL),
          NULL),
    p.prot_name, s.filter_user,
         NVL2(s.proxy_port, 
           s.proxy_url || ':' || TO_CHAR(s.proxy_port, 'FM99999'), s.proxy_url),
         s.timeout_secs, l.lib_name, l.parms,
         a.attr_name, a.parms, s.wallet_path, s.wallet_alias, s.server_host
    from server s
         join sbt_lib_desc l on l.server_key=s.server_key 
         join sbt_attr_set a on a.lib_key=l.lib_key
         left outer join rep_server r on s.server_key=r.server_key
         left outer join prot p on r.prot_key = p.prot_key
    order by p.prot_name, s.rep_server_name
>>>
 
define create_comment_rs_replication_server
<<<
begin
execute immediate 'comment on table ra_replication_server is ' ||
'''This view lists the replication server configurations.''';
 
execute immediate 'comment on column ra_replication_server.' ||
'replication_server_name is ' ||
'''The user-assigned name of the replication server configuration.''';
 
execute immediate 'comment on column ra_replication_server.' ||
'replication_server_state is ' ||
'''The replication status of the downstream Recovery Appliance: ' ||
  '<Emphasis Role = "CodeInline">AVAILABLE</Emphasis>, ' ||
  '<Emphasis Role = "CodeInline">CREATING</Emphasis>, ' ||
  '<Emphasis Role = "CodeInline">DELETING</Emphasis>, ' ||
  '<Emphasis Role = "CodeInline">TESTING COMMUNICATION</Emphasis>, ' ||
  'or null.''';
 
execute immediate 'comment on column ra_replication_server.' ||
'protection_policy is ' ||
'''The protection policy associated with this replication server' ||
  ' configuration.''';
 
execute immediate 'comment on column ra_replication_server.' ||
'rep_server_connect_name is ' ||
'''The user name used to connect to the downstream Recovery Appliance.''';
 
execute immediate 'comment on column ra_replication_server.' ||
'proxy_http_address is ' ||
'''The address of the proxy server in the form ' ||
  '<Emphasis Role = "Italic">proxy_server_http_address:port_' ||
  'of_proxy_server</Emphasis>.''';
 
execute immediate 'comment on column ra_replication_server.' ||
'proxy_timeout is ' ||
'''The timeout period for the proxy server connection.''';
 
execute immediate 'comment on column ra_replication_server.' ||
'sbt_library_name is ' ||
'''The name of the SBT library with which this replication server ' ||
  'configuration is associated.''';
 
execute immediate 'comment on column ra_replication_server.' ||
'sbt_library_parms is ' ||
'''The SBT library parameters.''';
 
execute immediate 'comment on column ra_replication_server.' ||
'attribute_name is '||
'''The SBT attribute set name.''';  
 
execute immediate 'comment on column ra_replication_server.' ||
'attribute_parms is ' ||
'''The SBT parameters passed while allocating the RMAN channel.''';
 
execute immediate 'comment on column ra_replication_server.' ||
'wallet_path is ' ||
'''The path to the local Oracle wallet (excluding the wallet file name).''';
 
execute immediate 'comment on column ra_replication_server.' ||
'wallet_alias is ' ||
'''The alias that identifies the Oracle wallet credentials ' ||
  'that this Recovery Appliance uses to log in to the downstream Recovery Appliance.''';
 
execute immediate 'comment on column ra_replication_server.' ||
'server_host is ' ||
'''The server name or address of the downstream Recovery Appliance.''';
end;
>>>
 
define create_rs_incident_log
<<<
create or replace view ra_incident_log
    (incident_id, error_code, parameter, error_text, 
     sl_key, sl_name, db_key, db_unique_name, task_id,
     status, component, severity, first_seen, last_seen, seen_count) as
  select incident#, 
         error_num, NVL(param_char, TO_CHAR(param_num)), error_text, 
         sl.sl_key, sl.sl_name, error_log.db_key,
         db.reg_db_unique_name,
         task_id, status, component,
         DECODE (severity,  1, 'WARNING',
                           10, 'ERROR',
                           20, 'INTERNAL', 'INVALID' || TO_CHAR(severity)),
         first_seen, last_seen, seen_count
     from error_log
          left outer join sl on error_log.sl_key = sl.sl_key
          left outer join db on db.db_key = error_log.db_key
>>>
 
define create_comment_rs_incident_log
<<<
begin
execute immediate 'comment on table ra_incident_log is ' ||
'''This view describes the Recovery Appliance incidents.''';
 
execute immediate 'comment on column ra_incident_log.' ||
'incident_id is ' ||
'''The unique ID for the incident.''';
 
execute immediate 'comment on column ra_incident_log.' ||
'error_code is ' ||
'''The Oracle error code for the message describing the incident.''';
 
execute immediate 'comment on column ra_incident_log.' ||
'parameter is ' ||
'''The parameter qualifying the scope of the error code.''';
 
execute immediate 'comment on column ra_incident_log.' ||
'error_text is ' ||
'''The text of the message for the last detection of this error condition.''';
 
execute immediate 'comment on column ra_incident_log.' ||
'sl_key is ' ||
'''Primary key of the storage location (if any) involved in this incident''';
 
execute immediate 'comment on column ra_incident_log.' ||
'sl_name is ' ||
'''The primary key of the Recovery Appliance storage location (if any) ' ||
  'involved in this incident.''';
 
execute immediate 'comment on column ra_incident_log.' ||
'db_key is ' ||
'''The primary key of the protected database (if any) involved in this incident.''';
 
execute immediate 'comment on column ra_incident_log.' ||
'db_unique_name is ' ||
'''The unique name of the protected database (if any) involved in this incident.''';
 
execute immediate 'comment on column ra_incident_log.' ||
'task_id is ' ||
'''The ID for the task (if any) in which this incident was detected.''';
 
execute immediate 'comment on column ra_incident_log.' ||
'status is ' ||
'''The status of this incident: <Emphasis Role = ' ||
  '"CodeInline">ACTIVE</Emphasis>, ' ||
  '<Emphasis Role = "CodeInline">FIXED</Emphasis>, or ' ||
  '<Emphasis Role = "CodeInline">RESET</Emphasis>.''';
 
execute immediate 'comment on column ra_incident_log.' ||
'component is ' ||
'''The component of the Recovery Appliance detecting this incident.''';
 
execute immediate 'comment on column ra_incident_log.' ||
'severity is ' ||
'''The importance of this incident to the smooth operation of the ' ||
  'Recovery Appliance.''';
 
execute immediate 'comment on column ra_incident_log.' ||
'first_seen is ' ||
'''The timestamp when the Recovery Appliance first detected the incident.''';
 
execute immediate 'comment on column ra_incident_log.' ||
'last_seen is ' ||
'''The timestamp when the Recovery Appliance most recently detected the incident.''';
 
execute immediate 'comment on column ra_incident_log.' ||
'seen_count is ' ||
'''The number of times that the Recovery Appliance detected the incident.''';
end;
>>>
 
define create_rs_incoming_backup_pieces
<<<
create or replace view ra_incoming_backup_pieces
    (sl_key, sl_name, db_key, db_unique_name,
     handle, current_size, last_update) as
  select sl.sl_key, sl.sl_name, sbt_catalog.db_key,
         db.reg_db_unique_name,
         handle, filesize/(1024*1024*1024), last_entry
     from sbt_catalog
          left outer join sl on sbt_catalog.sl_key = sl.sl_key
          left outer join db on db.db_key = sbt_catalog.db_key
     where completed = 'N'
  union all /* Polling pieces */
  select sl.sl_key, sl.sl_name, task.db_key, 
         db.reg_db_unique_name,
         bp.handle, bp.bytes/(1024*1024*1024), 
         nvl(task.last_execute_time,task.schedule_time)
     from task
     left outer join db on db.db_key = task.db_key, bp, odb, sl
     where task.task_type = 140 /* task_index_backup */
       and bitand(task.flags,16) = 16 /* tasks_polled_input */
       and task.param_num1 = bp.bp_key
       and task.db_key = odb.db_key
       and odb.sl_key = sl.sl_key
>>>
 
define create_comment_rs_incoming_backup_pieces
<<<
begin
execute immediate 'comment on table ra_incoming_backup_pieces is ' ||
'''This view describes the backup pieces being received by the Recovery Appliance.''';
 
execute immediate 'comment on column ra_incoming_backup_pieces.' ||
'sl_key is ' ||
'''The primary key of the Recovery Appliance storage location storing this ' ||
  'backup piece.''';
 
execute immediate 'comment on column ra_incoming_backup_pieces.' ||
'sl_name is ' ||
'''The name of the Recovery Appliance storage location storing this backup piece.''';
 
execute immediate 'comment on column ra_incoming_backup_pieces.' ||
'db_key is ' ||
'''The primary key of the protected database creating this backup piece.''';
 
execute immediate 'comment on column ra_incoming_backup_pieces.' ||
'db_unique_name is ' ||
'''The unique name of the protected database creating this backup piece.''';
 
execute immediate 'comment on column ra_incoming_backup_pieces.' ||
'handle is ' ||
'''The handle assigned to this backup piece.''';
 
execute immediate 'comment on column ra_incoming_backup_pieces.' ||
'current_size is ' ||
'''The size (in GB) currently allocated for this backup piece.''';
 
execute immediate 'comment on column ra_incoming_backup_pieces.' ||
'last_update is ' ||
'''The time when the backup piece was completely received.''';
end;
>>>
 
define create_avm_em_sbt_job
<<<
CREATE OR REPLACE VIEW ra_em_sbt_job_template
AS
WITH j AS
(
SELECT /*+ LEADING(l a j h p) */
       j.template_key
     , j.template_name
     , h.template_name full_template_name
     , a.attr_name
     , l.lib_name
     , p.prot_name
     , j.db_key
     , j.bck_type
     , j.from_tag
     , j.priority
     , j.copies
     , j.window
     , l.status lib_status
  FROM sbt_lib_desc l
     , sbt_attr_set a
     , sbt_job_template j
     , sbt_job_template h
     , prot p
 WHERE l.lib_key = a.lib_key
   AND j.attr_key = a.attr_key
   AND l.server_key IS NULL
   AND j.full_template_key = h.template_key
   AND p.prot_key(+) = j.prot_key
)
, backupio AS
(
SELECT sid, serial, inst_id, bytes
  FROM gv$backup_sync_io
 WHERE type = 'OUTPUT'
   AND filename is not null
   AND status = 'IN PROGRESS'
   AND device_type = 'SBT_TAPE'
UNION ALL
SELECT sid, serial, inst_id, bytes
  FROM gv$backup_async_io
 WHERE type = 'OUTPUT'
   AND filename is not null
   AND status = 'IN PROGRESS'
   AND device_type = 'SBT_TAPE'
)
, isp AS
(
SELECT s.current_task task_id, v.bytes bytes
  FROM backupio v
     , sessions s
 WHERE s.sid = v.sid
   AND s.serial# = v.serial
   AND s.instance_id = v.inst_id
)
, ct AS
(
SELECT template_key
     , MIN(error_text) KEEP (
         DENSE_RANK LAST ORDER BY last_seen NULLS FIRST
      ) error_text
     , MAX(last_seen) error_last_seen
     , COUNT(executable) executable
     , COUNT(running) running
     , COUNT(completed) completed
     , MAX(ct) completion_time
     , SUM(bytes) bytes
  FROM (
       SELECT /*+
                 LEADING(l st t e)
                 USE_HASH(st)
                 USE_HASH(t)
                 USE_HASH(e)
                 USE_HASH(isp)
              */
              template_key
            , completion_time ct
            , DECODE(state, 1, 1) executable
            , DECODE(state, 2, 1) running
            , DECODE(state, 3, 1) completed
            , error_text
            , last_seen
            , bytes
         FROM sbt_lib_desc l
            , sbt_task st
            , task t
         LEFT OUTER JOIN error_log e
           ON e.task_id = t.task_id
          AND e.status = 'ACTIVE'
         LEFT OUTER JOIN isp
           ON t.task_id = isp.task_id
        WHERE l.server_key IS NULL
          AND l.lib_key = st.lib_key
          AND st.task_id = t.task_id
        UNION ALL
       SELECT /*+
                 LEADING(l st t e)
                 USE_HASH(st)
                 USE_HASH(t)
                 USE_HASH(e)
              */
              template_key
            , completion_time
            , NULL
            , NULL
            , DECODE(state
                    , 8, CAST(NULL AS NUMBER)
                       , 1
              ) completed
            , error_text
            , last_seen
            , 0
         FROM sbt_lib_desc l
            , sbt_task_history st
            , task_history t
         LEFT OUTER JOIN error_log e
           ON e.task_id = t.task_id
          AND e.status = 'ACTIVE'
        WHERE l.server_key IS NULL
          AND l.lib_key = st.lib_key
          AND st.task_id = t.task_id
          AND t.task_type < 2000
          AND completion_time >= SYSTIMESTAMP - INTERVAL '24' HOUR
       )
 GROUP BY
       template_key
)
, t AS
(
SELECT /*+ LEADING(j) USE_HASH(ct) */
       template_name
     , full_template_name
     , prot_name
     , db_key
     , attr_name
     , lib_name
     , bck_type
     , priority
     , copies
     , window
     , from_tag
     , error_text
     , error_last_seen
     , executable
     , running
     , completed
     , completion_time
     , lib_status
     , bytes
  FROM j
     , ct
 WHERE ct.template_key(+) = j.template_key
)
, d AS
(
  SELECT /*+ PUSH_PRED */
         db_key
       , db_unique_name
       , ROW_NUMBER() OVER (
           PARTITION BY db_key
               ORDER BY database_role
                      , db_unique_name
         ) rn
    FROM node
   WHERE db_unique_name NOT LIKE '%$%'
)
SELECT template_name
     , full_template_name
     , prot_name policy_name
     , db_unique_name
     , attr_name attribute_set_name
     , lib_name
     , CASE bck_type
         WHEN  1 THEN 'ALL'
         WHEN  2 THEN 'FULL'
         WHEN  4 THEN 'INCR'
         WHEN  6 THEN 'FULL, INCR'
         WHEN  8 THEN 'ARCH'
         WHEN 10 THEN 'FULL, ARCH'
         WHEN 12 THEN 'INCR, ARCH'
         WHEN 14 THEN 'FULL, INCR, ARCH'
         WHEN 32 THEN 'TAPE RESERVE'
         ELSE '?'
       END backup_type
     , priority
     , copies
     , window
     , from_tag
     , error_text
     , error_last_seen
     , executable
     , running
     , completed
     , completion_time
     , DECODE(lib_status
             , 'R', 'READY'
             , 'P', 'PAUSE'
             , 'E', 'ERROR'
       ) status
     , bytes
  FROM t
     , d
 WHERE d.db_key(+) = t.db_key
   AND d.rn(+) = 1
>>>
 
define create_comment_avm_em_sbt_job
<<<
begin
execute immediate 'comment on table ra_em_sbt_job_template is ' ||
'''This view lists defined SBT jobs and their statuses for ' ||
  'Oracle Enterprise Manager.''';
 
execute immediate 'comment on column ra_em_sbt_job_template.' ||
'template_name is ' || 
'''The name of the SBT job template.''';
 
execute immediate 'comment on column ra_em_sbt_job_template.' ||
'full_template_name is ' || 
'''The full name of the SBT job template.''';
 
execute immediate 'comment on column ra_em_sbt_job_template.' ||
'policy_name is ' ||
'''The protection policy specifying the protected databases whose ' ||
  'backups the Recovery Appliance considers eligible for copying.''';
 
execute immediate 'comment on column ra_em_sbt_job_template.' ||
'db_unique_name is ' || 
'''The unique name of the protected database whose ' ||
  'backups the Recovery Appliance considers eligible for copying.''';
 
execute immediate 'comment on column ra_em_sbt_job_template.' ||
'attribute_set_name is ' || 
'''The name of the SBT attribute set.''';
 
execute immediate 'comment on column ra_em_sbt_job_template.' ||
'lib_name is ' ||
'''The name of the SBT library.''';
 
execute immediate 'comment on column ra_em_sbt_job_template.' ||
'backup_type is ' ||
'''The types of backups to be copied to tape by this job: ' ||
  '<Emphasis Role = "CodeInline">ALL</Emphasis>, ' ||
  '<Emphasis Role = "CodeInline">FULL</Emphasis>, ' ||
  '<Emphasis Role = "CodeInline">INCR</Emphasis>, ' ||
  '<Emphasis Role = "CodeInline">ARCH</Emphasis>, or ' ||
  '<Emphasis Role = "CodeInline">TAPE_RESERVE</Emphasis>.''';
 
execute immediate 'comment on column ra_em_sbt_job_template.' ||
'priority is ' ||
'''The priority for scheduling this job.''';
 
execute immediate 'comment on column ra_em_sbt_job_template.' ||
'copies is ' ||
'''The number of copies to be created on tape.''';
 
execute immediate 'comment on column ra_em_sbt_job_template.' ||
'window is ' ||
'''The time allotted for copy tasks to start for this job.''';
 
execute immediate 'comment on column ra_em_sbt_job_template.' ||
'from_tag is ' ||
'''The tag for the backup to be copied to tape by this job.''';
 
execute immediate 'comment on column ra_em_sbt_job_template.' ||
'error_text is '||
'''The error text for the task that failed.''';
 
execute immediate 'comment on column ra_em_sbt_job_template.' ||
'error_last_seen is ' || 
'''The timestamp when the Recovery Appliance most recently detected the error.''';
 
execute immediate 'comment on column ra_em_sbt_job_template.' ||
'executable is ' ||
'''The number of tasks in an executable state.''';
 
execute immediate 'comment on column ra_em_sbt_job_template.' ||
'running is ' ||
'''The number of tasks that are running or retrying.''';
 
execute immediate 'comment on column ra_em_sbt_job_template.' ||
'completed is ' ||
'''The number of completed tasks.''';
 
execute immediate 'comment on column ra_em_sbt_job_template.' ||
'completion_time is ' || 
'''The time of the most recent completed task.''';
 
execute immediate 'comment on column ra_em_sbt_job_template.' ||
'status is ' ||
'''The status of the SBT library: ' ||
  '<Emphasis Role = "CodeInline">READY</Emphasis>, ' ||
  '<Emphasis Role = "CodeInline">PAUSE</Emphasis>, or ' ||
  '<Emphasis Role = "CodeInline">ERROR</Emphasis>.''';
 
execute immediate 'comment on column ra_em_sbt_job_template.' ||
'bytes is ' ||
'''The number of bytes read or written so far.''';
end;
>>>
 
define create_am_catalog_select
<<<
DECLARE
  l_role                       CONSTANT VARCHAR2(128) := 'RA_CATALOG_SELECT';
  l_privileges                 CONSTANT VARCHAR2(128) := 'SELECT';
  l_user                       CONSTANT VARCHAR2(128) := 'DBSNMP';
  e_role_already_exist         EXCEPTION;
  PRAGMA EXCEPTION_INIT(e_role_already_exist, -1921);
  e_user_or_role_doesnt_exist  EXCEPTION;
  PRAGMA EXCEPTION_INIT(e_user_or_role_doesnt_exist, -1917);
  e_insufficient_privileges    EXCEPTION;
  PRAGMA EXCEPTION_INIT(e_insufficient_privileges, -1031);
BEGIN
  BEGIN
    EXECUTE IMMEDIATE 'CREATE ROLE ' || l_role;
  EXCEPTION 
    WHEN e_role_already_exist
    THEN NULL;
  END;
--
--
--
  FOR i IN (
    SELECT view_name
      FROM user_views
     WHERE view_name LIKE 'RA\_%' ESCAPE '\'
        OR view_name LIKE 'RC\_%' ESCAPE '\'
        OR view_name = 'RAI_RECWINGOAL_SCN'
        OR view_name = 'RAI_MAXRECWIN_STAMP'
  )
  LOOP
    EXECUTE IMMEDIATE
      'CREATE OR REPLACE PUBLIC SYNONYM ' || i.view_name
                                          || ' FOR ' || i.view_name;
    EXECUTE IMMEDIATE
      'GRANT ' || l_privileges || ' ON ' || i.view_name || ' TO ' || l_role;
 
  END LOOP;
  BEGIN
    EXECUTE IMMEDIATE 'GRANT ' || l_role  || ' TO ' || l_user;
  EXCEPTION
    WHEN e_user_or_role_doesnt_exist
    THEN NULL;
    WHEN e_insufficient_privileges
    THEN NULL;
  END;
--
  EXECUTE IMMEDIATE 'GRANT select ON rai_recwingoal_scn TO public';
  EXECUTE IMMEDIATE 'GRANT select ON rai_maxrecwin_stamp TO public';
--
  EXECUTE IMMEDIATE 'GRANT select ON ra_server TO public';
END;
>>>
 
 
 
define create_am_host
<<<
create or replace view rai_host
    (node_name, admin_ip_address, backup_ip_address, 
     replication_ip_address) as
    select node_name, admin_ip_address, backup_ip_address, 
           replication_ip_address from host
>>>
 
define drop_rai_FullRecSet_t
<<< drop type rai_FullRecSet_t >>>
 
define drop_rai_FullRec_t
<<< drop type rai_FullRec_t >>>
 
 
define rai_FullRec_t
<<<
create or replace type rai_FullRec_t authid current_user as object
   (
      db_key            NUMBER,
      df_file#          NUMBER,
      df_ts#            NUMBER,
      df_plugin_change# NUMBER,
      df_foreign_dbid   NUMBER,
      df_tablespace     VARCHAR2(30),
      df_creation_change# NUMBER,
      backup_type       VARCHAR2(32),
      file_type         VARCHAR2(32),
      bs_key            NUMBER,
      df_checkpoint_change#  NUMBER
   )
>>>
 
define rai_FullRecSet_t
<<<
    create or replace type rai_FullRecSet_t as table of rai_FullRec_t
>>>
 
define drop_rai_FullRecSetImpl_t
<<<
   drop type rai_FullRecSetImpl_t
>>>
 
define rai_FullRecSetImpl_t
<<<
create or replace type rai_FullRecSetImpl_t authid current_user as object
  (
  curval                number,   -- current rownum
  done                  number,   -- done with the query
  needobsolete          number,   -- user interested in obsolete col
 
  static function ODCITableStart(sctx   IN OUT rai_FullRecSetImpl_t)
    return number,
 
  member function ODCITableFetch(self   IN OUT rai_FullRecSetImpl_t,
                                 nrows  IN     number,
                                 objSet OUT    rai_FullRecSet_t)
    return number,
 
  member function ODCITableClose(self   IN     rai_FullRecSetImpl_t)
    return number
   )
>>>
 
define bai_FullRecSetImplbody_t
<<<
create or replace type body rai_FullRecSetImpl_t is
 
--
--
--
 
  static function ODCITableStart(sctx IN OUT rai_FullRecSetImpl_t)
    return number is
  begin
--
    sctx:=rai_FullRecSetImpl_t(0, 0, 1);
    return SYS.ODCIConst.Success;
  end ODCITableStart;
 
--
--
--
--
  member function ODCITableFetch(self   IN OUT rai_FullRecSetImpl_t,
                                 nrows  IN     number,
                                 objSet OUT    rai_FullRecSet_t)
    return number is
    n               number := 0;
    firstCall       boolean := TRUE;
    ret             boolean := TRUE;
    redundancy      number;
    baseline_cap    number := 0;
    lbRec           dbms_rcvman.lbrec_t;
    lbCursor        dbms_rcvman.lbCursor_t;
    lbState         dbms_rcvman.lbState_t;
  begin
    objSet := rai_FullRecSet_t();
 
--
    dbms_rcvman.setAllIncarnations(TRUE);
 
    select GREATEST(nvl(max(value), 0), 0) into baseline_cap from config
       where name = '_baseline_cap';
 
--
    if (baseline_cap > 0) then
      dbms_rcvman.setUntilTime(SYSDATE - baseline_cap);
    end if;
 
    dbms_rcvman.setFirstFullBckScopeAttributes(baseline_cap);
 
    while ret and self.done = 0 loop
     ret := dbms_rcvman.listBackup(lbRec, firstCall, FALSE,
                                    redundancy, TRUE, lbCursor, lbState, null);
      if (lbRec.df_file# is not null) then
        objSet.extend;
        n := n + 1;
        objSet(n):= rai_FullRec_t(
                            to_char(null),     -- db_key
                            to_number(null),   -- df_file#
                            to_number(null),   -- df_ts#
                            to_number(null),   -- df_plugin_change#
                            to_number(null),   -- df_foreign_dbid
                            to_char(null),     -- df_tablespace
                            to_number(null),   -- df_creation_change#
                            to_char(null),     -- backup_type
                            to_char(null),     -- file_type
                            to_number(null),   -- bs_key
                            to_number(null));  -- df_checkpoint_change#
        objSet(n).db_key                 := dbms_rcvman.getDbKey;
        objSet(n).df_file#               := lbRec.df_file#;
        objSet(n).df_ts#                 := lbRec.df_ts#;
        objSet(n).df_plugin_change#      := lbRec.df_plugin_change#;
        objSet(n).df_foreign_dbid        := lbRec.df_foreign_dbid;
        objSet(n).df_tablespace          := lbRec.df_tablespace;
        objSet(n).df_creation_change#    := lbRec.df_creation_change#;
        objSet(n).backup_type            := lbRec.backup_type;
        objSet(n).file_type              := lbRec.file_type;
        objSet(n).bs_key                 := lbRec.bs_key;
        objSet(n).df_checkpoint_change#  := lbRec.df_checkpoint_change#;
      end if;
      firstCall := false;
      self.curval:=self.curval+1;
      if not ret then
        self.done := 1;
      end if;
    end loop;
    dbms_rcvman.setFirstFullBckScopeAttributes(null);
 
    return SYS.ODCIConst.Success;
  end ODCITableFetch;
 
  member function ODCITableClose(self IN rai_FullRecSetImpl_t)
    return number is
  begin
    return SYS.ODCIConst.Success;
  end ODCITableClose;
end;
>>>
 
define drop_bai_listFullBackupPipe
<<< drop function bai_listFullBackupPipe >>>
 
define bai_listFullBackupPipe
<<<
  CREATE OR REPLACE FUNCTION bai_listFullBackupPipe
   RETURN rai_FullRecSet_t AUTHID DEFINER PIPELINED using rai_FullRecSetImpl_t;
>>>
 
define grant_bai_listFullBackupPipe
<<<
grant execute on bai_listFullBackupPipe to public
>>>
 
define create_rai_full_backup_files
<<<
  create or replace view rai_full_backup_files
       as select db_key,
                 df_file#,
                 df_ts#,
                 df_plugin_change#,
                 df_foreign_dbid,
                 df_tablespace,
                 df_creation_change#,
                 backup_type,
                 file_type,
                 bs_key,
                 df_checkpoint_change#
                 from TABLE(bai_listFullBackupPipe)
>>>
 
define create_ra_sbt_template_mdf
<<<
  create or replace view ra_sbt_template_mdf
       as select stf.template_key,
                 stf.db_key,
                 d.reg_db_unique_name db_unique_name,
                 stf.df_file#,
                 stf.df_ts#,
                 stf.df_plugin_change#,
                 stf.df_foreign_dbid,
                 stf.df_tablespace,
                 stf.df_creation_change#
            from sbt_template_df stf, db d
           where d.db_key = stf.db_key 
             and stf.bs_key IS NULL
>>>
 
define create_comment_ra_sbt_template_mdf
<<<
begin
execute immediate 'comment on table ra_sbt_template_mdf is ' ||
'''This view lists missing level 0 data file backups for each SBT template.''';
execute immediate 'comment on column ra_sbt_template_mdf.' ||
'template_key is ' ||
'''The key identifying the SBT template.''';
execute immediate 'comment on column ra_sbt_template_mdf.' ||
'db_key is ' ||
'''The key for the protected database that contains the missing file.''';
execute immediate 'comment on column ra_sbt_template_mdf.' ||
'db_unique_name is ' ||
'''The unique name of the database that contains the missing data file.''';
execute immediate 'comment on column ra_sbt_template_mdf.' ||
'df_file# is ' ||
'''The number of the missing data file.''';
execute immediate 'comment on column ra_sbt_template_mdf.' ||
'df_ts# is ' ||
'''The tablespace number of the missing data file.''';
execute immediate 'comment on column ra_sbt_template_mdf.' ||
'df_plugin_change# is ' ||
'''The plugin SCN for the missing data file.''';
execute immediate 'comment on column ra_sbt_template_mdf.' ||
'df_foreign_dbid is ' ||
'''The foreign DBID for the database that contains the missing data file.''';
execute immediate 'comment on column ra_sbt_template_mdf.' ||
'df_tablespace is ' ||
'''The tablespace that contains the missing data file.''';
execute immediate 'comment on column ra_sbt_template_mdf.' ||
'df_creation_change# is ' ||
'''The creation SCN for the missing data file.''';
end;
>>>
 
define drop_rai_full_backup_files
<<<
DROP VIEW rai_full_backup_files
>>>
 
define drop_ra_sbt_template_mdf
<<<
DROP VIEW ra_sbt_template_mdf
>>>
 
 
 
 
define delete_from_config
<<<
begin
delete from config where name <> 'compatible';
commit;
end;
>>>
 
define setup_ors_defaults
<<<
 
declare
   procedure ra_config_insert(name in config.name%TYPE, 
                              value in config.value%TYPE ) is
   begin
     merge into config using dual on (name = ra_config_insert.name)
       when not matched then
         insert (name, value)
           values (ra_config_insert.name, ra_config_insert.value);
   end;
 
begin
ra_config_insert('_enable_populate_rsr_key',   1);
ra_config_insert('_waitfordbfs',              NULL);
ra_config_insert('_dbfs_time_out_days',     5*1/24/60);
ra_config_insert('_last_incarnation',         NULL);
ra_config_insert('_def_contfilesize',         '2t');
ra_config_insert('_spare_asm_disks',          '2');
ra_config_insert('_compress',                 'YES');
ra_config_insert('_alg_over_alloc',         125);
ra_config_insert('_piece_affinity',           'YES');
ra_config_insert('_recovery_appliance_state', 'OFF');
ra_config_insert('_def_min_alloc',           4 * 1024 * 1024);
ra_config_insert('_chunk_cache',            512);
ra_config_insert('_chunkno_alloc',          1024);
ra_config_insert('network_chunksize',       128 * 1024 * 1024);
ra_config_insert('_alloc_increment',        4.0 * 1024 * 1024 * 1024);
ra_config_insert('_purging_reserve',         4 * 1024 * 1024 * 100);
ra_config_insert('_purge_wait',             15);
ra_config_insert('_purge_autoshrink',       .1);
ra_config_insert('_quiesce_wait',           15);
ra_config_insert('_quiesce_session_wait_days', 5/24/60);
ra_config_insert('_interrupt_wait',         20);
ra_config_insert('_lock_refused_wait',      5);
ra_config_insert('_purge_threshold',        .9);
ra_config_insert('_scheduling_wait',        5);
ra_config_insert('_sched_run_wait',         5);
ra_config_insert('_sched_sleep_wait',       5);
ra_config_insert('_sched_icd_wait',         5*60);
ra_config_insert('_sched_max_locktime',     5*60);
ra_config_insert('_timer_loop_sleep_seconds',       15);
ra_config_insert('_histogram_slot_days', 1/24*3);
ra_config_insert('_histogram_cycle_slots',  365*24/3);
ra_config_insert('_histogram_window_slots',  30*24/3);
ra_config_insert('_histogram_goal_percentile', .95);
ra_config_insert('_initial_freespace_ratio', .05);
ra_config_insert('_min_freespace_ratio', .01);
ra_config_insert('_task_maintenance_days', 1/24/60 * 5);
ra_config_insert('_storage_maintenance_days', 1/24/60 * 60);
ra_config_insert('_obsolete_sbt_days', 1);
ra_config_insert('_default_poll_frequency_days', 1/24);
ra_config_insert('_polling_timeout_days',  1/24/60 * 90);
ra_config_insert('_polling_del_files_check_days', 1);
ra_config_insert('_history_partition_days', 1);
ra_config_insert('_history_retention', 30);
ra_config_insert('_rm_incomplete_files_days', 10 * 1/24/60);
ra_config_insert('_expire_files_days',  1/24/60 * 90);
ra_config_insert('_max_task_restarts',      10);
ra_config_insert('_interrupt_max',         300);
ra_config_insert('_busy_interrupt_max',    500);
ra_config_insert('optimize_chunks_days', 7);
ra_config_insert('_optimize_space_limit', 1/10);
ra_config_insert('validate_db_days',    14);
ra_config_insert('check_files_days',    14);
ra_config_insert('percent_late_for_warning',    50);
ra_config_insert('_orphan_file_wait_days', 1/24/60 * 5);
ra_config_insert('_restricted_session_count',  5);
ra_config_insert('_min_sessions_for_busywork',  4);
ra_config_insert('_busywork_inhibit_time', 5*1/24/60);
ra_config_insert('_fragmentation',          10);
ra_config_insert('_reconcile_short_delay_days', 1/24 * 1);
ra_config_insert('_reconcile_long_delay_days',  1);
ra_config_insert('_trim_factor',  2);
ra_config_insert('_defer_delete', 'NO');
ra_config_insert('_trace_file_days', 3/24);
ra_config_insert('_dumper_last_dump_timestamp', 
                          to_char(systimestamp-365, 'dd-mm-rr hh24:mi:ss'));
ra_config_insert('_dumper_inhibit_days', 1);
ra_config_insert('_dumper_params', 'NODATAPUMP,NOBLOCKS,NOCHUNKS');
ra_config_insert('_dumper_file_ext', '.dat');
ra_config_insert('_check_sbtsched_days',1/24/60*30);
ra_config_insert('_max_sbt_failures', 25);
ra_config_insert('crosscheck_db_days', 1);
ra_config_insert('_crosscheck_throttle', 5);
ra_config_insert('_servlet_wait_seconds', 512);
ra_config_insert('_replication_streams_per_node', 4);
ra_config_insert('_replication_min_streams', 4);
ra_config_insert('_replication_max_streams', 64);
ra_config_insert('_api_lock_wait_seconds', 30);
ra_config_insert('_db_stats_refresh_days', 10/24/60);
ra_config_insert('_throttle_max_channels', 1000);
ra_config_insert('_throttle_threshold_channels', 872);
ra_config_insert('_throttle_wait_aft_apprvl_secs', 300);
ra_config_insert('_throttle_wait_for_crash_secs', 1800);
ra_config_insert('_throttle_sbt_active_hours', 12);
ra_config_insert('_throttle_max_single_chan_req', 128);
ra_config_insert('_throttle_wait_repeat_req_secs', 300);
ra_config_insert('_incident_alert_threshold', 
                                            dbms_ra_scheduler.severity_error);
ra_config_insert('_incident_dump_threshold',
                                         dbms_ra_scheduler.severity_internal);
ra_config_insert('_resumable_timeout', 86400);
ra_config_insert('_baseline_cap', 14);
ra_config_insert('_resource_wait_timeout_days', 15*1/24/60);
ra_config_insert('_resource_wait_relax_rate', 150/100);
ra_config_insert('_resource_wait_task_limit',
                                dbms_ra_scheduler.max_resource_wait_processes);
ra_config_insert('_aggressive_delete' , 'YES');
ra_config_insert('_stall_when'        , 'OFF');
ra_config_insert('_debug_when'        , 0);
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
ra_config_insert('_debug_error', TO_NUMBER('F0047CE6','XXXXXXXX'));
ra_config_insert('_purge_opt_free'    , 4);
ra_config_insert('_purge_opt_pct'     , 0.5);
ra_config_insert('_plans_maintained'  , 5);
ra_config_insert('_part_threshold'    , 0.40);
ra_config_insert('_part_index_style'  , 1);
ra_config_insert('_part_index_size'   , 1.5 * 1024 * 1024 * 1024);
ra_config_insert('_nzdl_is_alive_days', 10 *1/24/60);
ra_config_insert('_sbt_library_home', '?/lib');
ra_config_insert('_c2t_optimization', 'ON');
ra_config_insert('_ra_pool_freespace_threshold', .01);
ra_config_insert('_ra_pool_full_free_count', 10);
ra_config_insert('_ordering_wait_timeout_days', 2);
commit;
end;
>>>
 
define delete_old_config_entries
<<<
begin
delete from config where name IN ('_reserve_backup_drives',
                                  '_drive_reserve_minutes',
                                  '_drive_wait_minutes'
                                 );
commit;
end;
>>>
 
 
define upg_task_interval
<<<
  alter table task modify (elapsed_time interval day(9) to second(6))
>>>
define upg_task_sessions
<<<
  alter table task add 
        constraint task_f2 foreign key(ba_session_id) references sessions
>>>
define upg_task_history_interval
<<<
  alter table task_history modify (elapsed_time interval day(9) to second(6))
>>>
define upg_timer_task_interval
<<<
  alter table timer_task   
        modify (timer_interval interval day(9) to second(6))
>>>
define upg_ors_defaults
<<<
  begin
--
    update config
       set value = case upper(value)
                        when 'ON'  then '1' -- Force KBRSTRC_ERROR
                        when 'OFF' then '0' 
                        else  value
                   end
       where name = '_debug_when';
     commit;
   end;
>>>
 
define upg_odb_stats_cache_nzdl
<<<
  alter table odb_stats_cache add (nzdl_active varchar2(3))
>>>
 
define upg_task_creator
<<<
  alter table task add (creator_task_id   number,
                        creator_sid       number,
                        creator_instance  number)
>>>
 
define upg_task_history_creator
<<<
  alter table task_history add (creator_task_id   number,
                                creator_sid       number,
                                creator_instance  number)
>>>
 
 
 
define prvtrsi_plb
<<<
CREATE OR REPLACE PACKAGE BODY dbms_ra_int IS
--
--
--
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
 
/*-------------------------*
 * v$ table definition     *
 *-------------------------*/
type backup_set_t is record
(
RECID                                    NUMBER         ,
STAMP                                    NUMBER         ,
SET_STAMP                                NUMBER         ,
SET_COUNT                                NUMBER         ,
BACKUP_TYPE                              VARCHAR2(1)    ,
CONTROLFILE_INCLUDED                     VARCHAR2(3)    ,
INCREMENTAL_LEVEL                        NUMBER         ,
PIECES                                   NUMBER         ,
START_TIME                               DATE           ,
COMPLETION_TIME                          DATE           ,
ELAPSED_SECONDS                          NUMBER         ,
BLOCK_SIZE                               NUMBER         ,
INPUT_FILE_SCAN_ONLY                     VARCHAR2(3)    ,
KEEP                                     VARCHAR2(3)    ,
KEEP_UNTIL                               DATE           ,
KEEP_OPTIONS                             VARCHAR2(13)   ,
MULTI_SECTION                            VARCHAR2(3)    ,
GUID                                     RAW(16)
);
 
type backup_piece_t is record
(
RECID                                   NUMBER,
STAMP                                   NUMBER,
SET_STAMP                               NUMBER,
SET_COUNT                               NUMBER,
PIECE#                                  NUMBER,
COPY#                                   NUMBER,
DEVICE_TYPE                             VARCHAR2(17),
HANDLE                                  VARCHAR2(513),
COMMENTS                                VARCHAR2(81),
MEDIA                                   VARCHAR2(65),
MEDIA_POOL                              NUMBER,
CONCUR                                  VARCHAR2(3),
TAG                                     VARCHAR2(32),
STATUS                                  VARCHAR2(1),
DELETED                                 VARCHAR2(3),
START_TIME                              DATE,
COMPLETION_TIME                         DATE,
ELAPSED_SECONDS                         NUMBER,
BYTES                                   NUMBER,
IS_RECOVERY_DEST_FILE                   VARCHAR2(3),
RMAN_STATUS_RECID                       NUMBER,
RMAN_STATUS_STAMP                       NUMBER,
COMPRESSED                              VARCHAR2(3),
BACKED_BY_VSS                           VARCHAR2(3),
ENCRYPTED                               VARCHAR2(3),
BACKED_BY_OSB                           VARCHAR2(3),
GUID                                    RAW(16)
);
 
type backup_datafile_t is record
(
 RECID                                  NUMBER,
 STAMP                                  NUMBER,
 SET_STAMP                              NUMBER,
 SET_COUNT                              NUMBER,
 FILE#                                  NUMBER,
 CREATION_CHANGE#                       NUMBER,
 CREATION_TIME                          DATE,
 RESETLOGS_CHANGE#                      NUMBER,
 RESETLOGS_TIME                         DATE,
 INCREMENTAL_LEVEL                      NUMBER,
 INCREMENTAL_CHANGE#                    NUMBER,
 CHECKPOINT_CHANGE#                     NUMBER,
 CHECKPOINT_TIME                        DATE,
 ABSOLUTE_FUZZY_CHANGE#                 NUMBER,
 MARKED_CORRUPT                         NUMBER,
 MEDIA_CORRUPT                          NUMBER,
 LOGICALLY_CORRUPT                      NUMBER,
 DATAFILE_BLOCKS                        NUMBER,
 BLOCKS                                 NUMBER,
 BLOCK_SIZE                             NUMBER,
 OLDEST_OFFLINE_RANGE                   NUMBER,
 COMPLETION_TIME                        DATE,
 CONTROLFILE_TYPE                       VARCHAR2(1),
 USED_CHANGE_TRACKING                   VARCHAR2(3),
 BLOCKS_READ                            NUMBER,
 USED_OPTIMIZATION                      VARCHAR2(3),
 FOREIGN_DBID                           NUMBER,
 PLUGGED_READONLY                       VARCHAR2(3),
 PLUGIN_CHANGE#                         NUMBER,
 PLUGIN_RESETLOGS_CHANGE#               NUMBER,
 PLUGIN_RESETLOGS_TIME                  DATE,
 SECTION_SIZE                           NUMBER,
 UNDO_OPTIMIZED                         VARCHAR2(3),
 BLOCKS_SKIPPED_IN_CELL                 NUMBER,
 GUID                                   RAW(16)
);
 
type backup_redolog_t is record
(
RECID                                   NUMBER,
STAMP                                   NUMBER,
SET_STAMP                               NUMBER,
SET_COUNT                               NUMBER,
THREAD#                                 NUMBER,
SEQUENCE#                               NUMBER,
RESETLOGS_CHANGE#                       NUMBER,
RESETLOGS_TIME                          DATE,
FIRST_CHANGE#                           NUMBER,
FIRST_TIME                              DATE,
NEXT_CHANGE#                            NUMBER,
NEXT_TIME                               DATE,
BLOCKS                                  NUMBER,
BLOCK_SIZE                              NUMBER,
TERMINAL                                VARCHAR2(3),
ACTIVATION                              VARCHAR2(1)
);
 
type backup_spfile_t is record
(
RECID                                   NUMBER,
STAMP                                   NUMBER,
SET_STAMP                               NUMBER,
SET_COUNT                               NUMBER,
MODIFICATION_TIME                       DATE,
BYTES                                   NUMBER,
COMPLETION_TIME                         DATE,
DB_UNIQUE_NAME                          node.db_unique_name%TYPE,
GUID                                    RAW(16)
);
 
type archived_log_t is record
(
RECID                                  NUMBER,
STAMP                                  NUMBER,
NAME                                   VARCHAR2(513),
DEST_ID                                NUMBER,
THREAD#                                NUMBER,
SEQUENCE#                              NUMBER,
RESETLOGS_CHANGE#                      NUMBER,
RESETLOGS_TIME                         DATE,
RESETLOGS_ID                           NUMBER,
FIRST_CHANGE#                          NUMBER,
FIRST_TIME                             DATE,
NEXT_CHANGE#                           NUMBER,
NEXT_TIME                              DATE,
BLOCKS                                 NUMBER,
BLOCK_SIZE                             NUMBER,
CREATOR                                VARCHAR2(7),
REGISTRAR                              VARCHAR2(7),
STANDBY_DEST                           VARCHAR2(3),
ARCHIVED                               VARCHAR2(3),
APPLIED                                VARCHAR2(9),
DELETED                                VARCHAR2(3),
STATUS                                 VARCHAR2(1),
COMPLETION_TIME                        DATE,
DICTIONARY_BEGIN                       VARCHAR2(3),
DICTIONARY_END                         VARCHAR2(3),
END_OF_REDO                            VARCHAR2(3),
BACKUP_COUNT                           NUMBER,
ARCHIVAL_THREAD#                       NUMBER,
ACTIVATION#                            NUMBER,
IS_RECOVERY_DEST_FILE                  VARCHAR2(3),
COMPRESSED                             VARCHAR2(3),
FAL                                    VARCHAR2(3),
END_OF_REDO_TYPE                       VARCHAR2(10),
BACKED_BY_VSS                          VARCHAR2(3)
);
 
 
--
type paramdef_t is table of boolean index by varchar2(2);
paramtab paramdef_t;
 
/*-------------------------*
 * Private constants       *
 *-------------------------*/
--
TRUE#  CONSTANT NUMBER := 1;
FALSE# CONSTANT NUMBER := 0;
 
/*----------------------------------------*
 * Session scoped Package State Variables *
 *----------------------------------------*/
--
debug              NUMBER := AM_DEBUG_HIGH; --AM_DEBUG_ON;
debug_outtype      NUMBER := sys.dbms_system.trace_file;
 
--
--
--
--
s_purgescn         NUMBER := NULL;
 
--
type chrlst is table of VARCHAR(64) index by binary_integer;
s_info_module   chrlst;
s_info_action   chrlst;
 
--
--
s_last_throttled    DATE;
 
PROCEDURE replication_reconcile_int (p_db_key IN NUMBER DEFAULT NULL,
                                     p_server_key IN NUMBER DEFAULT NULL);
 
/*------------------*
 * Local Procedures *
 *------------------*/
 
--
PROCEDURE deb(p_line IN varchar2, p_level IN NUMBER DEFAULT AM_DEBUG_HIGH)
 IS
BEGIN
  IF debug >= p_level and p_level > AM_DEBUG_OFF
  THEN
--
--
--
--
--
--
    sys.kbrsi_icd.rsTrace('RSI: ' || p_line);
  END IF;
END deb;
 
PROCEDURE save_error IS 
BEGIN
  save_error_int;
END save_error;
 
--
PROCEDURE clear_error(reset BOOLEAN DEFAULT FALSE) IS
BEGIN
  dbms_ra_int.clear_error_int(reset);
END clear_error;
 
FUNCTION print (p_value IN BOOLEAN) RETURN VARCHAR2 IS
BEGIN
  IF p_value THEN
    RETURN 'TRUE';
  ELSIF p_value IS NULL THEN
    RETURN 'NULL';
  ELSE
    RETURN 'FALSE';
  END IF;
END print;
 
--
FUNCTION stamp2date(stamp IN NUMBER) RETURN DATE IS
 x NUMBER;
 dt VARCHAR2(19);
BEGIN
   x := stamp;
 
   IF (stamp = 0) THEN
      RETURN NULL;
   END IF;
 
   dt := TO_CHAR(MOD(x,60), 'FM09'); -- seconds
   x := FLOOR(x/60);
 
   dt := TO_CHAR(MOD(x,60), 'FM09') || ':' || dt; -- minutes
   x := FLOOR(x/60);
 
   dt := TO_CHAR(MOD(x,24), 'FM09') || ':' || dt; -- hours
   x := FLOOR(x/24);
 
   dt := TO_CHAR(MOD(x,31)+1, 'FM09') || ' ' || dt; -- days
   x := FLOOR(x/31);
 
   dt := TO_CHAR(MOD(x,12)+1, 'FM09') || '/' || dt; -- months
 
   dt := TO_CHAR(FLOOR(x/12)+1988)   || '/' || dt;
 
   return TO_DATE(dt, 'YYYY/MM/DD HH24:MI:SS', 'NLS_CALENDAR=Gregorian');
END stamp2date;
 
FUNCTION date2stamp(dt IN DATE) RETURN NUMBER IS
  stamp NUMBER;
BEGIN
  stamp := (((((TO_NUMBER(TO_CHAR(dt, 'YYYY'))-1988)*12
         +     (TO_NUMBER(TO_CHAR(dt, 'MM'))-1))*31
         +     (TO_NUMBER(TO_CHAR(dt, 'DD'))-1))*24
         +     (TO_NUMBER(TO_CHAR(dt, 'HH24'))))*60
         +     (TO_NUMBER(TO_CHAR(dt, 'MI'))))*60
         +     (TO_NUMBER(TO_CHAR(dt, 'SS')));
  RETURN stamp;
END date2stamp;
 
--
FUNCTION dbkey2name(p_dbkey IN NUMBER) RETURN VARCHAR2 IS
  l_dbname VARCHAR(512);
BEGIN
--
--
--
--
  SELECT max(reg_db_unique_name) INTO l_dbname
    FROM db
    WHERE db.db_key = p_dbkey;
  RETURN l_dbname;
END dbkey2name;
 
--
FUNCTION keylockstr(p_type IN NUMBER) RETURN VARCHAR2 IS
  l_typstr     VARCHAR2(10);
BEGIN
  CASE p_type
    WHEN KEY_BP THEN l_typstr := 'bpkey ';
    WHEN KEY_DF THEN l_typstr := 'dfkey ';
    WHEN KEY_AL THEN l_typstr := 'alkey ';
    WHEN KEY_SY THEN l_typstr := 'lib_key ';
    WHEN KEY_CT THEN l_typstr := 'ctkey ';
    WHEN KEY_VB THEN l_typstr := 'vbkey ';
    ELSE
      SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(
          DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM, 
          'keylockstr: unknown type ' || p_type);
  END CASE;
 
  RETURN l_typstr;
END keylockstr;
 
--
--
--
--
--
--
PROCEDURE write_lock(p_type IN NUMBER, p_key IN NUMBER)
 IS
  l_exists NUMBER;
  l_typstr VARCHAR2(10) := keylockstr(p_type);
BEGIN
--
  dbms_ra_scheduler.get_lock(dbms_ra_scheduler.LOCK_KEY, p_key);
  deb('write_lock ' || l_typstr || p_key ||
      ', got - ' || TO_CHAR(SYSTIMESTAMP, 'HH:MI:SS.FF3'), AM_DEBUG_ON);
 
--
  CASE p_type
    WHEN KEY_BP
    THEN
      SELECT COUNT(*) INTO l_exists FROM bp
        WHERE bp_key = p_key; /* @@RG: doing this break FREE AND status != 'D'; */
    WHEN KEY_DF
    THEN
      l_exists := 1;  -- Datafiles never go away, no need to check.
    WHEN KEY_AL
    THEN
       SELECT COUNT(*) INTO l_exists FROM al WHERE al_key = p_key;
    WHEN KEY_SY  
    THEN
       SELECT COUNT(*) INTO l_exists FROM sbt_lib_desc
        WHERE lib_key = p_key;
    WHEN KEY_CT
    THEN
       SELECT COUNT(*) INTO l_exists FROM sbt_catalog WHERE ct_key = p_key;
    WHEN KEY_VB
    THEN
       SELECT COUNT(*) INTO l_exists FROM vbdf WHERE vb_key = p_key;
    ELSE
--
      dbms_ra_scheduler.unlock(dbms_ra_scheduler.LOCK_KEY, p_key);
      SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(
          DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM, 
          'WRITE_LOCK: lock ' || p_key || ' has unknown type ' || p_type);
  END CASE;
 
  IF l_exists = 0
  THEN
--
    dbms_ra_scheduler.unlock(dbms_ra_scheduler.LOCK_KEY, p_key);
--
--
    RAISE dbms_ra_scheduler.e_retry_error;
  END IF;
END write_lock;
 
 
--
--
--
--
--
--
FUNCTION write_lock_wait(p_type IN NUMBER, p_key IN NUMBER) RETURN BOOLEAN
 IS
  l_dummy  BOOLEAN;
  l_typstr VARCHAR2(10) := keylockstr(p_type);
  l_exists NUMBER;
BEGIN
--
  deb('write_lock ' || l_typstr || p_key ||
      ', start - ' || TO_CHAR(SYSTIMESTAMP, 'HH:MI:SS.FF3'), AM_DEBUG_ON);
  l_dummy := sys.kbrsi_icd.rsKeyWriteLock(p_key, TRUE);
  deb('write_lock ' || l_typstr || p_key ||
      ', got - ' || TO_CHAR(SYSTIMESTAMP, 'HH:MI:SS.FF3'), AM_DEBUG_ON);
 
--
  CASE p_type
    WHEN KEY_BP
    THEN
      SELECT COUNT(*) INTO l_exists FROM bp
        WHERE bp_key = p_key AND status != 'D';
    WHEN KEY_DF
    THEN
      l_exists := 1;  -- Datafiles never go away, no need to check.
    WHEN KEY_AL
    THEN
       SELECT COUNT(*) INTO l_exists FROM al WHERE al_key = p_key;
    WHEN KEY_SY  
    THEN
       SELECT COUNT(*) INTO l_exists FROM sbt_lib_desc
        WHERE lib_key = p_key;
    WHEN KEY_CT
    THEN
       SELECT COUNT(*) INTO l_exists FROM sbt_catalog WHERE ct_key = p_key;
    WHEN KEY_VB
    THEN
       SELECT COUNT(*) INTO l_exists FROM vbdf WHERE vb_key = p_key;
    ELSE
--
      dbms_ra_scheduler.unlock(dbms_ra_scheduler.LOCK_KEY, p_key);
      SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(
          DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM, 
          'WRITE_LOCK_WAIT: lock ' || p_key || ' has unknown type ' || p_type);
  END CASE;
 
  IF l_exists = 0
  THEN
    dbms_ra_scheduler.show_locks(dbms_ra_scheduler.LOCK_KEY, p_key);
    dbms_ra_scheduler.unlock(dbms_ra_scheduler.LOCK_KEY, p_key);
    RETURN FALSE;
  ELSE
    RETURN TRUE;
  END IF;
END write_lock_wait;
 
 
--
--
--
--
--
FUNCTION read_lock(p_type IN NUMBER, p_key IN NUMBER) RETURN BOOLEAN
 IS
  l_lockstate  BOOLEAN;
  l_exists     NUMBER;
  l_typstr     VARCHAR2(10) := keylockstr(p_type);
BEGIN
--
  deb('read_lock ' || l_typstr || p_key ||
      ', start - ' || TO_CHAR(SYSTIMESTAMP, 'HH:MI:SS.FF3'), AM_DEBUG_ON);
  l_lockstate := sys.kbrsi_icd.rsKeyReadLock(p_key, TRUE);
  deb('read_lock ' || l_typstr || p_key ||
      ', got - ' || TO_CHAR(SYSTIMESTAMP, 'HH:MI:SS.FF3'), AM_DEBUG_ON);
 
--
  CASE p_type
    WHEN KEY_BP
    THEN
      SELECT COUNT(*) INTO l_exists FROM bp
        WHERE bp_key = p_key AND ba_access != 'U' AND purged = 'N';
    WHEN KEY_DF
    THEN
      l_exists := 1;  -- Datafiles never go away, no need to check.
    WHEN KEY_AL
    THEN
      SELECT COUNT(*) INTO l_exists FROM al WHERE al_key = p_key;
    WHEN KEY_SY  
    THEN
      SELECT COUNT(*) INTO l_exists FROM sbt_lib_desc
       WHERE lib_key = p_key;
    WHEN KEY_CT
    THEN
      SELECT COUNT(*) INTO l_exists FROM sbt_catalog WHERE ct_key = p_key;
    WHEN KEY_VB
    THEN
       SELECT COUNT(*) INTO l_exists FROM vbdf WHERE vb_key = p_key;
    ELSE
--
      dbms_ra_scheduler.unlock(dbms_ra_scheduler.LOCK_KEY, p_key);
      SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(
          DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM,
          'READ_LOCK: lock ' || p_key || ' has unknown type ' || p_type);
  END CASE;
 
  IF l_exists = 0
  THEN
    dbms_ra_scheduler.unlock(dbms_ra_scheduler.LOCK_KEY, p_key);
    RETURN FALSE;
  ELSE
    RETURN TRUE;
  END IF;
END read_lock;
 
 
--
--
--
PROCEDURE unlock(p_type IN NUMBER, p_key IN NUMBER)
 IS
BEGIN
  dbms_ra_scheduler.unlock(dbms_ra_scheduler.LOCK_KEY, p_key);
  CASE p_type
    WHEN KEY_BP
    THEN
      deb('unlock bpkey ' || p_key ||
          ' - ' || TO_CHAR(SYSTIMESTAMP, 'HH:MI:SS.FF3'), AM_DEBUG_ON);
    WHEN KEY_DF
    THEN
      deb('unlock dfkey ' || p_key ||
          ' - ' || TO_CHAR(SYSTIMESTAMP, 'HH:MI:SS.FF3'), AM_DEBUG_ON);
    WHEN KEY_AL
    THEN
      deb('unlock alkey ' || p_key ||
          ' - ' || TO_CHAR(SYSTIMESTAMP, 'HH:MI:SS.FF3'), AM_DEBUG_ON);
    WHEN KEY_CT
    THEN
      deb('unlock ctkey ' || p_key ||
          ' - ' || TO_CHAR(SYSTIMESTAMP, 'HH:MI:SS.FF3'), AM_DEBUG_ON);
    WHEN KEY_SY
    THEN
      deb('unlock lib_key ' || p_key ||
          ' - ' || TO_CHAR(SYSTIMESTAMP, 'HH:MI:SS.FF3'), AM_DEBUG_ON);
    WHEN KEY_VB
    THEN
      deb('unlock vbkey ' || p_key ||
          ' - ' || TO_CHAR(SYSTIMESTAMP, 'HH:MI:SS.FF3'), AM_DEBUG_ON);
    ELSE
      deb('unlock unknown key ' || p_key ||
          ' - ' || TO_CHAR(SYSTIMESTAMP, 'HH:MI:SS.FF3'), AM_DEBUG_ON);
  END CASE;
END unlock;
 
 
--
--
FUNCTION pieceAffinity(handle  IN  VARCHAR2,
                       db_key  OUT NUMBER,
                       lib_key OUT NUMBER)
  RETURN NUMBER IS
   not_found     BOOLEAN := FALSE;
   l_ct_key      NUMBER;
   l_bp_key      NUMBER;
   l_status      bp.status%TYPE;
   bs_key        NUMBER;
   bpno          NUMBER;
   l_endupload   sbt_catalog.endupload%TYPE;
   CURSOR bpQ(bs_key IN NUMBER, bpno IN NUMBER) IS
      SELECT ct.ct_key, ct.db_key, bp.lib_key
        FROM sbt_catalog ct, bp
       WHERE bp.bp_key = ct.bp_key
         AND bp.bs_key = bpQ.bs_key
         AND bp.status = 'A'
         AND bp.ba_access != 'U'
         AND bp.piece# = bpQ.bpno
      ORDER BY decode(ba_access, 'R', 3, 'T', 2, nvl2(vb_key, 1, 0)),
               bp.copy# desc;
   CURSOR ctQ(handle IN VARCHAR2) IS
      SELECT ct.ct_key, ct.db_key, ct.bp_key, bp.status, bp.lib_key,
             ct.endupload, bp.bs_key, bp.piece#
        FROM sbt_catalog ct
             LEFT OUTER JOIN bp
          ON ct.bp_key = bp.bp_key
         AND bp.ba_access != 'U'
       WHERE ct.handle = ctQ.handle
        ORDER by ct.bp_key nulls last,
                 decode(ct.endupload, 'Y', 0, 1);
BEGIN
--
--
--
   OPEN ctQ(handle);
   FETCH ctQ INTO l_ct_key, db_key, l_bp_key, l_status,
                  lib_key, l_endupload, bs_key, bpno;
   IF (ctQ%NOTFOUND) THEN
     CLOSE ctQ;
     RAISE no_data_found;
   END IF;
   CLOSE ctQ;
 
   IF (l_status != 'D') THEN
      RETURN l_ct_key;
   END IF;
 
--
--
   IF (l_endupload = 'Y' and l_bp_key IS NULL) THEN
      RETURN l_ct_key;
   END IF;
 
--
   IF (l_bp_key IS NULL) THEN
      deb('pieceAffinity: bp_key not found', AM_DEBUG_MED);
      not_found := TRUE;
   ELSE -- complete piece but it is purged. Look for alternate piece
      OPEN bpQ(bs_key, bpno);
      FETCH bpQ INTO l_ct_key, db_key, lib_key;
      IF (bpQ%NOTFOUND) THEN
         deb('pieceAffinity: no alternate piece found', AM_DEBUG_MED);
         not_found := TRUE;
      END IF;
      CLOSE bpQ;
   END IF;
 
   IF (not_found) THEN
      RAISE no_data_found;
   END IF;
 
   RETURN l_ct_key;
END pieceAffinity;
 
/*-------------------*
 * Global Procedures *
 *-------------------*/
 
--
--
--
PROCEDURE setDebug(p_level IN NUMBER,
                   p_outtype IN NUMBER DEFAULT sys.dbms_system.trace_file)
 IS
BEGIN
  debug := p_level;
  debug_outtype := p_outtype;
END setDebug;
 
--
PROCEDURE save_error_int IS 
  l_error_depth PLS_INTEGER := utl_call_stack.error_depth;
  l_newds callstack := callstack();
  l_newbt callstack := callstack();
BEGIN
  deb('save_error_int at depth=' || l_error_depth);
--
--
  IF s_pl_stack.COUNT > 0 THEN
    IF l_error_depth <= s_pl_stack(s_pl_stack.LAST).error_depth THEN
      RETURN;
    END IF;
  END IF;
 
--
  s_pl_stack.EXTEND;
 
--
--
  FOR l_line IN 3..utl_call_stack.dynamic_depth LOOP
    l_newds.EXTEND;
    l_newds(l_newds.LAST).line := utl_call_stack.unit_line(l_line);
    l_newds(l_newds.LAST).unit := 
      utl_call_stack.concatenate_subprogram(utl_call_stack.subprogram(l_line));
  END LOOP;
 
--
 
--
  FOR l_line IN REVERSE 1..utl_call_stack.backtrace_depth LOOP
    l_newbt.EXTEND;
    l_newbt(l_newbt.LAST).line := utl_call_stack.backtrace_line(l_line);
    l_newbt(l_newbt.LAST).unit := utl_call_stack.backtrace_unit(l_line);
  END LOOP;
 
  s_pl_stack(s_pl_stack.LAST).dynamic_stack := l_newds;
  s_pl_stack(s_pl_stack.LAST).backtrace_stack := l_newbt;
  s_pl_stack(s_pl_stack.LAST).error_depth := l_error_depth;
  s_pl_stack(s_pl_stack.LAST).action := SYS_CONTEXT('USERENV', 'ACTION');
  s_pl_stack(s_pl_stack.LAST).module := SYS_CONTEXT('USERENV', 'MODULE');
EXCEPTION
  WHEN OTHERS THEN
    deb('save_error_int failed with: ' || SQLERRM);
    deb(' at line '  || utl_call_stack.backtrace_line(1));
    RAISE;
END save_error_int;
 
--
PROCEDURE clear_error_int(reset BOOLEAN DEFAULT FALSE) IS
  l_error_depth PLS_INTEGER := utl_call_stack.error_depth;
BEGIN
  deb('save_error_int at depth=' || l_error_depth);
  IF reset THEN
    s_pl_stack.DELETE;
  ELSE
--
--
    FOR f IN REVERSE 1..s_pl_stack.COUNT LOOP
      IF l_error_depth <= s_pl_stack(f).error_depth THEN
        s_pl_stack.TRIM;
      ELSE
--
        RETURN;
      END IF;
    END LOOP;
  END IF;
EXCEPTION
  WHEN OTHERS THEN
    deb('clear_error_int failed with: ' || SQLERRM);
    deb(' at line '  || utl_call_stack.backtrace_line(1));
    RAISE;
END clear_error_int;
 
--
FUNCTION get_error RETURN VARCHAR2 IS
  NEWLN CONSTANT CHAR(1) := CHR(10);
  l_errormsg VARCHAR2(32000);
  l_payload error_payload;
  l_nextbt callstack;
  l_nextds callstack;
  l_unit VARCHAR2(128);
  E_STRING_ERROR                     EXCEPTION; PRAGMA EXCEPTION_INIT (
  E_STRING_ERROR,                                       -6502         );
  E_STRING_ERROR_NUM                 CONSTANT NUMBER := -6502;
BEGIN
  IF s_pl_stack.COUNT = 0 THEN
    RETURN 'No Call Stack Saved';
  END IF;
 
  l_errormsg := '';
  FOR l_frame IN 1..s_pl_stack.COUNT LOOP
--
    IF s_pl_stack.COUNT > 1 THEN
      l_errormsg := l_errormsg || NEWLN || NEWLN || 'Error frame ' || l_frame;
    ELSE
      l_errormsg := 'Error stack:';
    END IF;
 
--
    l_payload := s_pl_stack(l_frame);
    l_nextbt := l_payload.backtrace_stack;
    l_nextds := l_payload.dynamic_stack;
 
--
    l_errormsg := l_errormsg || NEWLN ||
                  RPAD('Backtrace unit',40) || LPAD('Line', 10);
 
    FOR l_line IN 1..l_nextbt.COUNT LOOP
      l_unit := l_nextbt(l_line).unit;
 
      IF LENGTH(l_unit) > 40 THEN
--
        l_unit := SUBSTR(l_unit,-40);
      END IF;
 
      l_errormsg := l_errormsg || NEWLN ||
                  RPAD(l_unit, 40) ||
                  LPAD(l_nextbt(l_line).line, 10);
    END LOOP;
 
--
    l_errormsg := l_errormsg || NEWLN || NEWLN ||
                  RPAD('Call stack unit',40) || LPAD('Line', 10);
 
    FOR l_line IN 1..l_nextds.COUNT LOOP
      l_unit := l_nextds(l_line).unit;
      IF LENGTH(l_unit) > 40 THEN
--
        l_unit := SUBSTR(l_unit,-40);
      END IF;
      l_errormsg := l_errormsg || NEWLN || 
                  RPAD(l_unit, 40) ||
                  LPAD(l_nextds(l_line).line, 10);
    END LOOP;
  END LOOP;
 
  RETURN l_errormsg;
EXCEPTION
  WHEN E_STRING_ERROR THEN
    deb('return what we have so far...');
    RETURN SUBSTR(l_errormsg, 1, 31995) || '...';
  WHEN OTHERS THEN
    deb('get_error failed with: ' || SQLERRM);
    deb(' at line '  || utl_call_stack.backtrace_line(1));
    RAISE;
END get_error;
 
--
--
--
PROCEDURE unlock_vb(p_vbkey   IN NUMBER,
                    p_novbkey IN BOOLEAN) -- Do not unlock vbkey
 IS
 CURSOR dfnums(in_vbkey number) IS
  SELECT db_key, vb_key, df_key
  FROM vbdf
  WHERE vb_key = in_vbkey;
 CURSOR bpnums(in_vbkey number) IS
  SELECT bp_key FROM bp WHERE vb_key = in_vbkey;
BEGIN
--
  FOR l IN dfnums(p_vbkey) LOOP
    unlock(KEY_DF, l.df_key);
  END LOOP;
 
--
  IF NOT p_novbkey
  THEN
    FOR l IN bpnums(p_vbkey) LOOP
      unlock(KEY_BP, l.bp_key);
    END LOOP;
  END IF;
END unlock_vb;
 
 
--
--
--
PROCEDURE validateBackupPiece(p_dbkey IN NUMBER, 
                              p_bpkey IN NUMBER)
 IS
  l_blksize            NUMBER := 0;
  l_sameendian         NUMBER := 0;
  l_fname              VARCHAR2(1024):= NULL;
  l_msection           NUMBER;
  l_pieces             NUMBER;
BEGIN
 
  deb(' validateBackupPiece, db_key:' || p_dbkey || ' :  bp_key: ' || p_bpkey,
      AM_DEBUG_MED);
 
--
  SELECT block_size INTO l_blksize
     FROM bp, bs 
     WHERE bp.bs_key=bs.bs_key 
     AND vb_key IS NULL
     AND bp_key = p_bpkey;
 
  SELECT DECODE(multi_section, 'Y', 1, 0), pieces
    INTO l_msection, l_pieces
      FROM bs 
      WHERE bs_key = (SELECT bs_key from bp where bp_key = p_bpkey) ;
 
  deb(' validateBackupPiece, bp_key:' || p_bpkey || 
      ' blksize: ' || l_blksize || ' l_msection ' || l_msection ||
      ' pieces: ' || l_pieces, AM_DEBUG_MED);
 
  BEGIN
--
--
 
    IF (l_pieces = 1 OR l_msection = 1) THEN
      SELECT filename INTO l_fname FROM sbt_catalog WHERE bp_key = p_bpkey;
      sys.kbrsi_icd.validatePiece(filename => l_fname, 
                                  blksize => l_blksize);
    END IF;
  EXCEPTION
    WHEN OTHERS THEN
         save_error;
         SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(
                                  DBMS_RA_SCHEDULER.E_CORRUPT_BACKUPPIECE_NUM,
                                  p_bpkey);
  END;
END validateBackupPiece;
 
 
--
FUNCTION file2handle(p_fname VARCHAR2) RETURN VARCHAR2 IS
  l_handle   VARCHAR2(512);
BEGIN
  IF dbms_ra_scheduler.s_current_task_type = dbms_ra_scheduler.TASK_INC_ARCH
  THEN
    l_handle := INC_ARC_PREFIX || substr(p_fname,1,512);
  ELSE
    l_handle := '$' || substr(p_fname,1,511);
  END IF;
 
 RETURN l_handle;
END file2handle;
 
 
--
PROCEDURE createSbtCatalog(p_dbid      IN  NUMBER,
                           p_handle    IN  VARCHAR2,
                           p_pieceinc  IN  VARCHAR2,
                           p_ftype     IN  NUMBER,
                           p_xmldoc    IN  CLOB,
                           p_commit    IN  BOOLEAN,
                           p_ct_key    OUT NUMBER)
IS
   db_key      NUMBER;
   ftypestr    VARCHAR2(1);
   l_completed sbt_catalog.completed%TYPE := NULL;
   l_endupload sbt_catalog.endupload%TYPE := NULL;
   l_filename  sbt_catalog.filename%TYPE  := NULL;
BEGIN
  BEGIN
     SELECT db_key INTO db_key
       FROM db
      WHERE db_id = p_dbid;
  EXCEPTION
     WHEN no_data_found THEN
        save_error;
        raise_application_error(-20001, 'Database not found');
  END;
 
  CASE p_ftype
     WHEN DBMS_RA_INT.KBRSCHKTYPE_VIRTUAL
     THEN
       ftypestr := 'V';
     WHEN DBMS_RA_INT.KBRSCHKTYPE_TAPE
     THEN
       ftypestr := 'T';
     WHEN DBMS_RA_INT.KBRSCHKTYPE_FILE
     THEN
       ftypestr    := 'F';
       l_completed := 'N';
       l_endupload := 'N';
     WHEN DBMS_RA_INT.KBRSCHKTYPE_DISK
     THEN
       ftypestr := 'D';
       l_filename := p_handle;
     ELSE SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(
             DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM, 'unknown_ftype');
  END CASE;
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
  BEGIN
    INSERT INTO sbt_catalog
      (ct_key, db_key, cretime, handle, pieceinc, endupload,
       ftype, xmldoc, completed, filename)
      VALUES
      (rman_seq.nextval, db_key, systimestamp,
       p_handle, p_pieceinc, l_endupload, ftypestr,
       sys.xmltype.createxml(p_xmldoc), l_completed, l_filename)
      RETURNING ct_key INTO p_ct_key;
  EXCEPTION
    WHEN DUP_VAL_ON_INDEX THEN
      save_error;
      clear_error;
 
      SELECT ct_key INTO p_ct_key FROM sbt_catalog s
        WHERE s.db_key = createSbtCatalog.db_key
          AND handle = p_handle
          AND pieceinc = p_pieceinc;
  END;
 
  IF (p_commit) THEN
     COMMIT;
  END IF;
END createSbtCatalog;
 
--
PROCEDURE copySbtCatalog(p_handle      IN VARCHAR2,
                         p_oldpieceinc IN VARCHAR2,
                         p_newpieceinc IN VARCHAR2)
IS
  l_entry          sbt_catalog%ROWTYPE;
  l_newchunkprefix varchar2(1024);
BEGIN
--
  SELECT * INTO l_entry
    FROM sbt_catalog
    WHERE handle = p_handle
      AND pieceinc = p_oldpieceinc;
 
--
  SELECT sl_key INTO l_entry.sl_key FROM odb, bp
    WHERE odb.db_key = bp.db_key
      AND bp.bp_key = l_entry.bp_key;
 
  l_entry.ct_key    := rman_seq.nextval;
  l_entry.pieceinc  := p_newpieceinc;
  l_entry.bp_key    := NULL;  -- Needed to avoid constraint violation
 
--
  SELECT regexp_replace(prefix, p_oldpieceinc, p_newpieceinc, 
                        instr(prefix, p_oldpieceinc, -1 , 1))
    INTO l_newchunkprefix
    FROM (SELECT extractValue(l_entry.xmldoc, '//ChunkPrefix/text()') prefix
          FROM dual);
 
--
--
--
--
--
 
  SELECT XMLQuery('copy $i := $p1 modify
                   ((for $j in $i//Incarnation
                     return replace value of node $j with $p2),
                    (for $j in $i//ChunkPrefix
                     return replace value of node $j with $p3))
                   return $i'
         PASSING l_entry.xmldoc AS "p1", p_newpieceinc AS "p2", 
                 l_newchunkprefix AS "p3" RETURNING CONTENT)
    INTO l_entry.xmldoc
    FROM dual;
 
--
  IF (l_entry.endupload IS NOT NULL) THEN
     l_entry.endupload := 'N';
  END IF;
  IF (l_entry.completed IS NOT NULL) THEN
     l_entry.completed := 'N';
  END IF;
 
  l_entry.filename   := NULL;
  l_entry.filesize   := NULL;
  l_entry.last_entry := SYSTIMESTAMP;
 
--
  INSERT INTO sbt_catalog VALUES l_entry;
END copySbtCatalog;
 
--
PROCEDURE endUploadSbtCatalog(p_handle      IN VARCHAR2,
                              p_pieceinc    IN VARCHAR2,
                              p_xmldoc      IN CLOB)
IS
   l_ct_key    NUMBER;
BEGIN
   SELECT ct.ct_key INTO l_ct_key
     FROM sbt_catalog ct
    WHERE ct.handle   = p_handle
      AND ct.pieceinc = p_pieceinc
      AND ct.bp_key IS NULL;
 
   UPDATE sbt_catalog ct
      SET ct.endupload = 'Y'
         ,ct.xmldoc = sys.xmltype.createxml(p_xmldoc)
    WHERE ct.ct_key = l_ct_key;
 
   COMMIT;
END endUploadSbtCatalog;
 
--
PROCEDURE finalizeSbtCatalog(p_bp_key IN NUMBER,
                             p_ct_key IN NUMBER,
                             p_xmldoc IN CLOB)
IS
   l_ftype sbt_catalog.ftype%TYPE;
   l_bskey NUMBER;
BEGIN
   IF debug >= AM_DEBUG_HIGH AND p_xmldoc IS NOT NULL THEN
      deb('finalizeSbtCatalog xmldoc = ');
      deb(dbms_lob.substr(p_xmldoc, 4000, 1));
   END IF;
 
   SELECT bs_key into l_bskey from bs
     WHERE bs.bs_key = (SELECT bs_key from bp WHERE bp.bp_key = p_bp_key)
     FOR UPDATE of bs.bs_key;
 
   IF debug >= AM_DEBUG_HIGH THEN
      deb('finalizeSbtCatalog locked bs_key = ' || l_bskey);
   END IF;
 
   UPDATE sbt_catalog ct
      SET ct.bp_key    = p_bp_key
         ,ct.completed = nvl2(ct.completed, 'Y', null)
         ,ct.endupload = nvl2(ct.endupload, 'Y', null)
         ,ct.xmldoc    =
             case when ct.xmldoc is null then sys.xmltype.createxml(p_xmldoc)
             else ct.xmldoc end
    WHERE ct_key = p_ct_key
   RETURNING ct.ftype INTO l_ftype;
 
   UPDATE bp
      SET bp.ct_key = p_ct_key
    WHERE bp.bp_key = p_bp_key;
 
 
   IF (l_ftype = 'V') THEN
      UPDATE vbdf v SET state = DBMS_RA_POOL.VBDF_COMPLETE
       WHERE state = DBMS_RA_POOL.VBDF_FIN_NOBP
         AND EXISTS (SELECT 1 FROM bp p, bdf d
                      WHERE p.bs_key = d.bs_key
                        AND p.bp_key = p_bp_key
                        AND p.vb_key = v.vb_key
                        AND d.file#  = v.file#);
   END IF;
END finalizeSbtCatalog;
 
--
PROCEDURE deleteSbtCatalog(p_handle    IN VARCHAR2,
                           p_pieceinc  IN VARCHAR2)
IS
 
   l_ct_key   NUMBER;
   l_bp_key   NUMBER;
   bp_key     NUMBER;
BEGIN
   IF (p_pieceinc IS NOT NULL) THEN
      SELECT ct.ct_key, ct.bp_key INTO l_ct_key, l_bp_key
        FROM sbt_catalog ct
       WHERE ct.handle   = p_handle
         AND ct.pieceinc = p_pieceinc;
   ELSE
      SELECT ct.ct_key, ct.bp_key INTO l_ct_key, l_bp_key
        FROM sbt_catalog ct, bp
       WHERE ct.handle = p_handle
         AND bp.status != 'D'
         AND bp.bp_key = ct.bp_key
         AND bp.ct_key = ct.ct_key;
   END IF;
 
   IF (l_bp_key IS NULL) THEN
--
--
      UPDATE sbt_catalog ct SET ct.endupload = 'D'
       WHERE ct.ct_key = l_ct_key;
   ELSE
--
--
--
      deb('deleteSbtCatalog piece complete; handle = ' || p_handle ||
          ' ;leave it to rsDeleteBackupPiece');
   END IF;
 
   COMMIT;
EXCEPTION
   WHEN no_data_found THEN
      save_error;
      deb('deleteSbtCatalog no_data_found: handle= ' || p_handle);
      clear_error;
END deleteSbtCatalog;
 
--
PROCEDURE readSbtCatalog(p_handle   IN         VARCHAR2,
                         p_xmldoc   OUT NOCOPY CLOB,
                         p_affinity IN         BINARY_INTEGER,
                         p_sbtinfo2 IN         BINARY_INTEGER)
IS
   l_ct_ftype            sbt_catalog.ftype%TYPE;
   l_ct_key              NUMBER;
   l_lib_key             NUMBER;
   l_db_key              NUMBER;
   l_mclob               CLOB;
   l_status              BINARY_INTEGER;
   l_mhandle             SYS.KBRSI_ICD.NAMES$_T;
   l_single              BINARY_INTEGER;
   l_network_chunksize   NUMBER;
   l_ct_endupload        sbt_catalog.endupload%TYPE;
   l_ct_completed        sbt_catalog.completed%TYPE;
   l_ct_pieceinc         sbt_catalog.pieceinc%TYPE;
   l_bp_key              NUMBER;
   l_chunks              NUMBER;
   l_filesize            NUMBER;
   l_call_finish_bp      BOOLEAN := FALSE;
BEGIN
--
   IF (p_affinity > 0) THEN
      l_ct_key := pieceAffinity(p_handle, l_db_key, l_lib_key);
   ELSE
      SELECT ct.ct_key, ct.db_key, bp.lib_key
        INTO l_ct_key, l_db_key, l_lib_key
        FROM sbt_catalog ct, bp
       WHERE ct.handle = p_handle
         AND ct.bp_key = bp.bp_key
         AND bp.status != 'D';
   END IF;
 
   IF (p_sbtinfo2 > 0) THEN
      SELECT bp.lib_key, ct.db_key, ct.endupload,
             ct.completed, ct.pieceinc, ct.ftype, bp.bp_key
        INTO l_lib_key, l_db_key, l_ct_endupload,
             l_ct_completed, l_ct_pieceinc, l_ct_ftype, l_bp_key
        FROM sbt_catalog ct
             LEFT OUTER JOIN bp
          ON ct.bp_key = bp.bp_key
         AND bp.status != 'D'
       WHERE ct.ct_key = l_ct_key;
 
--
--
--
--
--
--
      IF (l_ct_completed = 'N' AND l_ct_endupload = 'Y' AND
          l_ct_ftype = 'F'     AND l_bp_key IS NULL) THEN
         l_call_finish_bp := TRUE;
      END IF;
   END IF;
 
--
   IF (l_lib_key IS NOT NULL) THEN
      l_status := dbms_ra_int.statBpSbt(
                   db_key  => l_db_key,
                   handle  => p_handle,
                   mhandle => l_mhandle,
                   single  => l_single);
      IF (l_status = 0) THEN
         SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(DBMS_RA.OBJ_NOT_FOUND_NUM,
                                               p_handle,
                                               'tape file',
                                               FALSE);
      END IF;
   END IF;
 
   SELECT nvl(max(to_number(value)), 0)
     INTO l_network_chunksize
     FROM config
    WHERE name = 'network_chunksize';
 
   IF (l_mhandle.count > 0) THEN
      l_mclob := '<MediaInfo>';
 
      FOR i in 0..l_mhandle.count-1 LOOP
         IF (l_mhandle(i) IS NOT NULL) THEN
            l_mclob := l_mclob || '<MediaHandle>' ||
                       l_mhandle(i)||'</MediaHandle>';
         END IF;
      END LOOP;
 
      IF (l_single > 0) THEN
         l_mclob := l_mclob || '<Single>TRUE</Single>';
      ELSE
         l_mclob := l_mclob || '<Single>FALSE</Single>';
      END IF;
 
      l_mclob := l_mclob || '</MediaInfo>';
      
--
--
--
--
 
      SELECT XMLQuery('copy $i := $p1 modify
                       (for $j in $i//MediaInfo
                        return replace node $j with $p2)
                       return $i'
              PASSING ct.xmldoc AS "p1", XMLType(l_mclob) AS "p2"
              RETURNING CONTENT).getClobVal(),
              filesize
        INTO p_xmldoc, l_filesize
        FROM sbt_catalog ct
       WHERE ct.ct_key = l_ct_key;
   ELSE
      SELECT ct.xmldoc.getClobVal(), filesize
        INTO p_xmldoc, l_filesize
        FROM sbt_catalog ct
       WHERE ct.ct_key = l_ct_key;
   END IF;
 
   IF (l_network_chunksize != 0) THEN
--
--
--
--
--
--
--
--
      IF (l_filesize IS NULL) THEN
         l_chunks := dbms_ra_int.UB8MAXVAL;
      ELSE
         l_chunks := ceil(l_filesize/l_network_chunksize);
      END IF;
 
--
--
--
--
--
 
      SELECT XMLQuery('copy $i := $p1 modify
                      ((for $j in $i//ChunkSize
                        return replace value of node $j with $p2),
                       (for $j in $i//Chunks
                        return replace value of node $j with $p3))
                      return $i'
             PASSING XMLType(p_xmldoc) AS "p1",
                     to_char(l_network_chunksize) AS "p2",
                     to_char(l_chunks) AS "p3"
             RETURNING CONTENT).getClobVal()
        INTO p_xmldoc
        FROM dual;
   END IF;
 
--
--
--
--
   IF (l_call_finish_bp) THEN
      dbms_ra_storage.finish_backup_piece(
                    p_db_key   => l_db_key,
                    p_handle   => p_handle,
                    p_pieceinc => l_ct_pieceinc,
                    p_ct_key   => l_ct_key);
   END IF;
END readSbtCatalog;
 
 
--
--
FUNCTION checkSbtCatalog(p_handle   IN VARCHAR2,
                         p_affinity IN BINARY_INTEGER)
RETURN BINARY_INTEGER IS
   l_ct_key  NUMBER;
   l_db_key  NUMBER;
   l_lib_key NUMBER;
BEGIN
--
   IF (p_affinity > 0) THEN
      l_ct_key := pieceAffinity(p_handle, l_db_key, l_lib_key);
   ELSE
      SELECT ct.ct_key INTO l_ct_key
        FROM sbt_catalog ct, bp
       WHERE ct.handle = p_handle
         AND ct.bp_key = bp.bp_key
         AND bp.status != 'D';
   END IF;
   RETURN 1;
EXCEPTION
   WHEN no_data_found THEN
      save_error;
      clear_error;
      RETURN 0;
END checkSbtCatalog;
 
 
--
--
--
PROCEDURE purgescncheck(p_dbid  IN NUMBER)
IS
  l_purgescn NUMBER;
  l_dbkey    NUMBER;
BEGIN
--
--
--
--
--
--
--
--
  IF NVL(s_purgescn, 0) > 0 THEN
    SELECT odb.db_key, purge_scn INTO l_dbkey, l_purgescn
      FROM odb, db
      WHERE odb.db_key = db.db_key
        AND db_id = p_dbid;
 
--
--
    IF l_purgescn > s_purgescn THEN
       UPDATE odb SET purge_scn = NULL,
                      purge_inc = NULL,
                      bs2_timestamp = NULL
         WHERE db_key = l_dbkey;
      COMMIT;
    END IF;
    s_purgescn := NULL;
  END IF;
END purgescncheck;
 
--
PROCEDURE tickSbtSession(p_session_id IN VARCHAR2,
                         p_db_key     IN NUMBER,
                         p_module     IN VARCHAR2,
                         p_action     IN VARCHAR2)
IS
   l_rowid    rowid;
   l_modtime  timestamp;
   l_currtime timestamp := systimestamp;
BEGIN
   sys.dbms_application_info.set_client_info(p_session_id);
   sys.dbms_application_info.set_module(p_module, p_action);
 
   SELECT se.modtime, ROWID
     INTO l_modtime, l_rowid
     FROM sbt_session se
    WHERE se.session_id = p_session_id;
 
--
   IF (l_currtime > 
       (l_modtime + dbms_ra_scheduler.s_sbt_active_interval/4)) THEN
      UPDATE sbt_session se
         SET se.modtime = l_currtime
       WHERE ROWID = l_rowid;
      COMMIT;
   END IF;
EXCEPTION
   WHEN no_data_found THEN
      save_error;
      INSERT INTO sbt_session(session_id, db_key, cretime, modtime)
      VALUES (p_session_id, p_db_key, l_currtime, l_currtime);
      COMMIT;
      clear_error;
END tickSbtSession;
 
--
PROCEDURE purgeSbtSession(p_session_id IN VARCHAR2)
IS
BEGIN
   DELETE sbt_session se
    WHERE se.session_id = p_session_id;
   COMMIT;
END purgeSbtSession;
 
--
--
FUNCTION get_prvlg_code(operation  IN VARCHAR2,
                        accesstype IN VARCHAR2)
RETURN NUMBER IS
   writeop      BOOLEAN := FALSE;
BEGIN
   IF (accesstype = 'READ') THEN
      writeop := FALSE;
   ELSIF (accesstype = 'WRITE') THEN
      writeop := TRUE;
   ELSE
      SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(
         DBMS_RA.INVALID_VAL_NUM, 'accesstype');
   END IF;
 
--
   IF (operation = 'BACKUP') THEN
      IF (writeop) THEN
         RETURN BACKUP_READ;
      ELSE
         RETURN BACKUP_WRITE;
      END IF;
   ELSIF (operation = 'RECONCILE') THEN
      IF (writeop) THEN
         RETURN RECONCILE_READ;
      ELSE
         RETURN RECONCILE_WRITE;
      END IF;
   ELSE
      SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(
         DBMS_RA.INVALID_VAL_NUM, 'operation');
   END IF;
   RETURN NULL;
END get_prvlg_code;
 
--
--
FUNCTION has_privilege_int(user_id     IN NUMBER,
                           db_key      IN NUMBER,
                           db_uname    IN VARCHAR2,
                           prvlg_code  IN NUMBER)
RETURN BINARY_INTEGER IS
  has_prvlg  BINARY_INTEGER := 0;
BEGIN
  IF (has_privilege_int.db_key IS NOT NULL) THEN
    SELECT /*+ INDEX(pv prvlg(user_id db_key type)) */ 1d
      INTO has_prvlg
      FROM prvlg pv 
     WHERE pv.user_id = has_privilege_int.user_id
       AND pv.db_key = has_privilege_int.db_key
       AND bitand(pv.type, prvlg_code) = prvlg_code
       AND ROWNUM = 1;
  ELSE
    SELECT /*+ INDEX(pv prvlg(user_id db_unique_name type)) */ 1d
      INTO has_prvlg
      FROM prvlg pv 
     WHERE pv.user_id = has_privilege_int.user_id
       AND pv.db_unique_name = has_privilege_int.db_uname
       AND bitand(pv.type, prvlg_code) = prvlg_code
       AND ROWNUM = 1;
  END IF;
 
  RETURN has_prvlg;
EXCEPTION
  WHEN NO_DATA_FOUND THEN
     save_error;
     clear_error;   
     RETURN 0;
END has_privilege_int;
 
--
FUNCTION has_privilege(user_id     IN NUMBER,
                       db_key      IN NUMBER,
                       db_uname    IN VARCHAR2,
                       operation   IN VARCHAR2,
                       accesstype  IN VARCHAR2,
                       prvlg_code  IN NUMBER DEFAULT NULL)
RETURN BINARY_INTEGER IS
   l_prvlg_code     NUMBER := prvlg_code;
BEGIN
   IF (l_prvlg_code IS NULL) THEN
      l_prvlg_code := get_prvlg_code(upper(operation), upper(accesstype));
   END IF;
   RETURN has_privilege_int(user_id,
                            db_key,
                            upper(db_uname),
                            l_prvlg_code);
END has_privilege;
 
--
--
--
--
--
--
PROCEDURE saveBPdata(fno              IN NUMBER,
                     fuzzyScn         IN NUMBER DEFAULT NULL,
                     blocks_read      IN NUMBER DEFAULT NULL,
                     corrupt          IN NUMBER DEFAULT NULL,
                     completion_stamp IN NUMBER DEFAULT NULL,
                     completion_time  IN DATE DEFAULT NULL)
IS
  i BINARY_INTEGER := fno;
BEGIN
--
  IF fuzzyScn IS NOT NULL THEN
    s_bp_save(i).fuzzyscn := fuzzyScn;
  END IF;
  
  IF blocks_read IS NOT NULL THEN
    s_bp_save(i).blocks_read := blocks_read;
  END IF;
 
  IF corrupt IS NOT NULL THEN
    s_bp_save(i).nmcorrupt := corrupt;
  END IF;
 
  IF completion_stamp IS NOT NULL THEN
    s_bp_save(i).complete_time := stamp2date(completion_stamp);
  END IF;
 
  IF completion_time IS NOT NULL THEN
    s_bp_save(i).complete_time := completion_time;
  END IF;
END saveBPdata;
 
 
--
PROCEDURE checkBackupSet(bs IN kccbs_t)
IS
   local        backup_set_t;
   keep_options NUMBER;
   l_completion_time DATE := NULL;
BEGIN
--
   IF s_bp_save.EXISTS(s_bp_save.LAST) THEN
     l_completion_time := s_bp_save(s_bp_save.LAST).complete_time;
   END IF;
 
--
--
   SELECT rai_recid.nextval,
          bs.bsstm,
          bs.bsbss,
          bs.bsbsc,
          decode(bitand(bs.bstyp, 11), 1, 'D', 2, 'I', 8, 'L'),
          decode(bitand(bs.bstyp, 4 + 64), 4, 'YES', 68, 'SBY', 'NO'),
          decode(bitand(bs.bstyp, 16 + 8192), 16, bs.bslvl, NULL),
          bs.bspct,
          stamp2date(bs.bsbss),
          nvl(l_completion_time, stamp2date(bs.bsste)), /* KCCBSCAT is true */
          abs(nvl(l_completion_time, stamp2date(bs.bsste)) -
              stamp2date(bs.bsbss)) * 86400,
          bs.bsbsz,
          decode(bitand(bs.bstyp,128),128,'YES','NO'),
          decode(bitand(bs.bstyp, 1792), 0, 'NO', 'YES'),
          stamp2date(bs.bskpt),
          decode(bitand(bs.bstyp, 1792),
                 256, 'LOGS', 512, 'NOLOGS', 1024, 'BACKUP_LOGS', NULL),
          decode(bitand(bs.bstyp, 16384), 16384, 'YES', 'NO'),
          bs.bsoid
     INTO local
     FROM dual
    WHERE bitand(bs.bstyp,32) != 32;
 
--
--
   SELECT decode(local.keep_options,
                 'LOGS', 256, 'NOLOGS', 512, 'BACKUP_LOGS', 1024, 0)
     INTO keep_options
     FROM dual;
 
--
   dbms_rcvcat.checkBackupSet(
      local.recid, local.stamp, local.set_stamp, local.set_count,
      local.backup_type, local.incremental_level, local.pieces,
      local.start_time, local.completion_time,
      local.controlfile_included, local.input_file_scan_only,
      keep_options, local.keep_until, local.block_size,
      local.multi_section, FALSE, local.guid);
END checkBackupSet;
 
 
--
FUNCTION checkBackupPiece(vbkey         IN NUMBER
                         ,lib_key       IN NUMBER
                         ,ba_access     IN VARCHAR2
                         ,bp            IN kccbp_t
                         ,template_key  IN NUMBER)
RETURN NUMBER IS
   local             backup_piece_t;
   bp_key            NUMBER;
   l_completion_time DATE := NULL;
BEGIN
--
   IF s_bp_save.EXISTS(s_bp_save.LAST) THEN
     l_completion_time := s_bp_save(s_bp_save.LAST).complete_time;
   END IF;
 
--
--
   SELECT 0,    -- want catalog to create bp_recid in strictly increasing order
          bp.bpstm,
          bp.bpbss,
          bp.bpbsc,
          bp.bpnum,
          NULL, /* copy# no longer in use */
          bp.bpdev,
          bp.bphdl,
          bp.bpcmt,
          bp.bpmdh,
          bitand(bp.bpflg, 4080) / 16,
          decode(bitand(bp.bpflg, 2), 1,'YES','NO'),
          bp.bptag,
          decode(bitand(bp.bpflg, 1 + 4096 + 8192), 0, 'A', 1, 'D',
                 4096, 'X',8192,'U','?'),
          decode(bitand(bp.bpflg, 1), 1, 'YES','NO'),
          stamp2date(bp.bpsts),
          nvl(l_completion_time, stamp2date(bp.bptim)),
          abs(nvl(l_completion_time, stamp2date(bp.bptim)) -
              stamp2date(bp.bpsts)) * 86400,
          ((floor(bp.bpext/512) * 4294967296) + bp.bpsz1) * 512,
          decode(bitand(bp.bpflg, 16384), 0, 'NO', 'YES'),
          0, -- rman_status_recid unknown
          0, -- rman_status_stamp unknown
          decode(bitand(bp.bpext, 64), 64, 'YES', 'NO'),
          decode(bitand(bp.bpflg, 16384), 0,'NO',
                 decode(bitand(bp.bpext, 256), 0, 'NO', 'YES')),
          decode(bitand(bp.bpext, 128), 128, 'YES', 'NO'),
          decode(bitand(bp.bpflg, 16384), 16384, 'NO',
                 decode(bitand(bp.bpext,256), 0, 'NO', 'YES')),
          bp.bpoid
     INTO local
     FROM dual;
 
--
   IF ba_access <> 'L' OR vbkey IS NOT NULL THEN
     s_purgescn := 0;
   END IF;
 
--
   bp_key := dbms_rcvcat.checkBackupPiece(
      local.recid, local.stamp, local.set_stamp, local.set_count,
      local.piece#, local.tag, local.device_type, local.handle,
      local.comments, local.media, local.concur,
      local.start_time, local.completion_time, local.status,
      local.copy#, local.media_pool, local.bytes,
      local.is_recovery_dest_file,
      local.rman_status_recid, local.rman_status_stamp,
      local.compressed, local.encrypted, local.backed_by_osb,
      ba_access, vbkey, FALSE, lib_key, local.guid, template_key);
 
   RETURN bp_key;
END checkBackupPiece;
 
 
--
PROCEDURE checkBackupDatafile(bf IN kccbf_t)
IS
   local           backup_datafile_t;
   l_purgescn      NUMBER;
   l_dbkey         NUMBER;
   i               BINARY_INTEGER := bf.bfdfp;
   l_fuzzyscn      NUMBER := NULL;
   l_nmcorrupt     NUMBER := NULL;
   l_blocks_read   NUMBER := NULL;
   l_complete_time DATE := NULL;
   l_bs_key        NUMBER := NULL;
   l_isVirtual     VARCHAR2(1);
BEGIN
--
--
   IF s_bp_save.EXISTS(i) THEN
     l_fuzzyscn := s_bp_save(i).fuzzyscn;
     l_nmcorrupt := s_bp_save(i).nmcorrupt;
     l_blocks_read := s_bp_save(i).blocks_read;
     l_complete_time := s_bp_save(i).complete_time;
 
     deb('checkBackupDatafile ' || i ||
         ', fuzzy ' || l_fuzzyscn ||
         ', corr ' || l_nmcorrupt ||
         ', blks ' || l_blocks_read ||
         ', time ' || l_complete_time,
         AM_DEBUG_MED);
   END IF;
 
--
--
   SELECT rai_recid.nextval,
          bf.bfstm,
          bf.bfbss,
          bf.bfbsc,
          bf.bfdfp,
          to_number(bf.bfcrs),
          stamp2date(bf.bfcrt),
          to_number(bf.bfrls),
          stamp2date(bf.bfrlc),
          decode(bitand(bf.bfflg, 1 + 8), 1, bf.bflvl, NULL),
          to_number(bf.bfics),
          to_number(bf.bfcps),
          stamp2date(bf.bfcpt),
          nvl(l_fuzzyscn, to_number(bf.bfafs)),
          nvl(l_nmcorrupt, bf.bfncb),
          bf.bfmcb,
          bf.bflcb,
          bf.bffsz,
          bf.bfbct,
          bf.bfbsz,
          bf.bflor,
          nvl(l_complete_time, stamp2date(bf.bfste)),
          decode(bf.bfdfp, 0, decode(bitand(bf.bfflg, 2), 2, 'S', 'B'), NULL),
          decode(bitand(bf.bfflg, 4), 4, 'YES', 'NO'),
          nvl(l_blocks_read, bf.bfbrd),
          decode(bitand(bf.bfflg, 16), 16, 'YES', 'NO'),
          bf.bffdi,
          decode(bitand(bf.bfflg, 32), 0, 'NO', 'YES'),
          bf.bfplus,
          bf.bfprls,
          stamp2date(bf.bfprlt),
          bf.bfssz,
          decode(bitand(bf.bfflg, 128), 0, 'NO', 'YES'),
          bf.bfssb,
          bf.bfoid
     INTO local
     FROM dual
    WHERE bitand(bf.bfflg, 64) != 64;
 
   SELECT CASE MIN(NVL(vb_key, 0)) WHEN 0 THEN 'F' ELSE 'T' END
     INTO l_isVirtual
     FROM bs, bp
    WHERE bs.bs_key = bp.bs_key 
      AND bs.db_key = dbms_rcvcat.this_db_key
      AND bs.set_stamp = local.set_stamp
      AND bs.set_count = local.set_count;
 
--
   s_purgescn := LEAST(NVL(s_purgescn, BIGNUM), local.checkpoint_change#);
 
--
   dbms_rcvcat.checkBackupDataFile(
      local.recid, local.stamp, local.set_stamp, local.set_count,
      local.file#, local.creation_change#, local.creation_time,
      local.resetlogs_change#, local.resetlogs_time,
      local.incremental_level, local.incremental_change#,
      local.checkpoint_change#, local.checkpoint_time,
      local.absolute_fuzzy_change#, local.datafile_blocks,
      local.blocks, local.block_size, local.oldest_offline_range,
      local.completion_time, local.controlfile_type,
      local.marked_corrupt, local.media_corrupt,
      local.logically_corrupt, FALSE, local.blocks_read,
      local.used_change_tracking, local.used_optimization,
      local.foreign_dbid, local.plugged_readonly,
      local.plugin_change#, local.plugin_resetlogs_change#,
      local.plugin_resetlogs_time,
      local.section_size, local.guid, 'NO' /* sparse backup */,
      FALSE, CASE l_isVirtual WHEN 'F' THEN FALSE ELSE TRUE END);
 
--
--
--
   IF local.section_size <> 0 THEN
 
      SELECT bs_key
        INTO l_bs_key
        FROM bs
       WHERE db_key = dbms_rcvcat.this_db_key
         AND bs.set_stamp = local.set_stamp
         AND bs.set_count = local.set_count;
 
      deb('dbms_rs_int:checkBackupDataFile msection bs_key' || l_bs_key);
      deb('dbms_rs_int:checkBackupDataFile db_key' || dbms_rcvcat.this_db_key);
 
--
--
--
--
      UPDATE vbdf 
         SET ckp_scn = (SELECT ckp_scn 
                          FROM bdf 
                         WHERE bs_key = l_bs_key
                           AND file#  = local.file#
                       )
         WHERE vb_key IN 
           (SELECT bp.vb_key 
              FROM bp 
                   JOIN vbdf
                ON bp.vb_key = vbdf.vb_key
             WHERE bp.bs_key = l_bs_key 
               AND bp.vb_key IS NOT NULL
               AND vbdf.ckp_scn > (SELECT ckp_scn
                                     FROM bdf
                                    WHERE bs_key = l_bs_key
                                      AND file#  = local.file#
                                  )
               AND vbdf.state = DBMS_RA_POOL.VBDF_COMPLETE);
 
      deb('dbms_rs_int:checkBackupDataFile UPDATED vbdfs' || l_bs_key);
 
   END IF;
   
END checkBackupDatafile;
 
 
--
PROCEDURE checkBackupRedolog(bl IN kccbl_t)
IS
   local  backup_redolog_t;
BEGIN
--
--
   SELECT rai_recid.nextval,
          bl.blstm,
          bl.blbss,
          bl.blbsc,
          bl.blthp,
          bl.blseq,
          to_number(bl.blrls),
          stamp2date(bl.blrlc),
          to_number(bl.bllos),
          stamp2date(bl.bllot),
          to_number(bl.blnxs),
          stamp2date(bl.blnxt),
          bl.blbct,
          bl.blbsz,
          decode(bitand(bl.blflg, 1), 1, 'YES', 'NO'),
          decode(bitand(bl.blflg, 4), 4, 'Y', null)
     INTO local
     FROM dual
    WHERE bitand(bl.blflg, 2) != 2;
 
--
   dbms_rcvcat.checkBackupRedoLog(
      local.recid, local.stamp, local.set_stamp, local.set_count,
      local.thread#, local.sequence#, local.resetlogs_change#,
      local.resetlogs_time, local.first_change#, local.first_time,
      local.next_change#, local.next_time, local.blocks,
      local.block_size, FALSE, local.terminal, local.activation);
END checkBackupRedolog;
 
 
--
PROCEDURE checkBackupSpfile(bi IN kccbi_t)
IS
   local  backup_spfile_t;
BEGIN
--
--
   SELECT rai_recid.nextval,
          bi.bistm,
          bi.bibss,
          bi.bibsc,
          stamp2date(bi.bimdt),
          bi.bifsz,
          stamp2date(bi.bistm),
          bi.bidun,
          bi.bioid
     INTO local
     FROM dual
    WHERE bitand(bi.biflg, 1) != 1;
 
--
  dbms_rcvcat.checkBackupSpFile(
     local.recid, local.stamp, local.set_stamp, local.set_count,
     local.modification_time, local.bytes, FALSE,
     local.db_unique_name, local.guid);
END checkBackupSpfile;
 
 
--
PROCEDURE checkArchivedLog(al IN kccal_t)
IS
   local  archived_log_t;
   l_archived varchar2(10);
   l_is_standby varchar2(1);
   l_terminal   varchar2(3);
 
BEGIN
--
--
   SELECT rai_recid.nextval,
          al.alstm,
          al.alnam,
          al.aldst,
          al.althp,
          al.alseq,
          al.alrls,
          stamp2date(al.alrlc),
          al.alrlc,
          al.allos,
          stamp2date(al.allot),
          al.alnxs,
          stamp2date(al.alnxt),
          al.albct,
          al.albsz,
          decode(bitand(al.alflg, 16+32+64+128+256),
              16, 'ARCH',
              32, 'FGRD',
              64, 'RMAN',
              128,'SRMN',
              256,'LGWR',
                  'UNKNOWN'),
          decode(bitand(al.alflg, 4),
              4,  'RFS',
              decode(bitand(al.alflg, 16+32+64+128+256),
              16, 'ARCH',
              32, 'FGRD',
              64, 'RMAN',
              128,'SRMN',
              256,'LGWR',
                  'UNKNOWN')),
          decode(bitand(al.alflg, 8),0,'NO','YES'),
          decode(bitand(al.alflg, 2),0,'NO','YES'),
          decode(bitand(al.alflg, 1024),0,
                   (decode(bitand(al.alfl2, 16384),0,'NO','IN-MEMORY')),'YES'),
          decode(bitand(al.alflg, 1),0,'NO','YES'),
          decode(bitand(al.alflg, 1+2048+4096),
              0,   'A',
              1,   'D',
              2048,'X',
              4096,'U',
                   '?'),
          stamp2date(al.alstm),
          decode(bitand(al.alflg,8192),0,'NO','YES'),
          decode(bitand(al.alflg,16384),0,'NO','YES'),
          decode(bitand(al.alflg,32768),0,'NO','YES'),
          to_number(bitand(al.alfl2,15)),
          al.altoa,
          al.alacd,
          decode(bitand(al.alfl2,64),0,'NO','YES'),
          decode(bitand(al.alfl2,128),0,'NO','YES'),
          decode(bitand(al.alflg,512),0,'NO','YES'),
          decode(bitand(al.alfl2,256+512+1024),
                 256, 'TERMINAL',
                 512, 'ACTIVATION',
                1024, 'RESETLOGS',
                decode(bitand(al.alflg,32768),0,'','SWITCHOVER')),
          decode(bitand(al.alfl2,4096), 0, null, 'Y')
     INTO local
     FROM dual;
 
--
--
--
  SELECT decode(local.archived, 'YES', 'Y', 'NO', 'N', 'UNKNOWN'),
         decode(local.registrar, 'RFS', 'Y', 'SRMN', 'Y', 'N'),
         decode (local.end_of_redo_type, 'TERMINAL', 'YES', 'NO')
  INTO l_archived, l_is_standby, l_terminal
  FROM dual;
 
  dbms_rcvcat.checkArchivedLog(
    local.recid, local.stamp, local.thread#,
    local.sequence#, local.resetlogs_change#, local.resetlogs_time,
    local.first_change#, local.first_time, local.next_change#,
    local.next_time, local.blocks, local.block_size, local.name,
    l_archived,
    local.completion_time, local.status,
    l_is_standby,
    null, null, local.is_recovery_dest_file, local.compressed, local.creator,
    l_terminal, FALSE);
 
END checkArchivedLog;
 
 
--
FUNCTION number2null(p_name IN VARCHAR2) RETURN NUMBER IS
BEGIN
   paramtab(p_name) := TRUE;
   return NULL;
END number2null;
 
FUNCTION varchar2null(p_name IN VARCHAR2) RETURN VARCHAR2 IS
BEGIN
   paramtab(p_name) := TRUE;
   return NULL;
END varchar2null;
 
 
FUNCTION intervalnull(p_name IN VARCHAR2) RETURN DSINTERVAL_UNCONSTRAINED IS
BEGIN
   paramtab(p_name) := TRUE;
   return NULL;
END intervalnull;
 
 
FUNCTION isparamdef(p_name IN VARCHAR2) RETURN BOOLEAN IS
   loc boolean := FALSE;
BEGIN
   if (paramtab.exists(p_name)) then
      loc := paramtab(p_name);
      paramtab(p_name) := FALSE;
   end if;
   return loc;
END isparamdef;
 
 
--
FUNCTION statBpSbt(db_key  IN  NUMBER,
                   handle  IN  VARCHAR2,
                   mhandle OUT NOCOPY SYS.KBRSI_ICD.NAMES$_T,
                   single  OUT BINARY_INTEGER)
RETURN BINARY_INTEGER IS
   status        BINARY_INTEGER;
   parms         VARCHAR2(1024);
   node          VARCHAR2(512);
   devtype       VARCHAR2(512);
   l_lib_key     NUMBER;
   l_lib_name    sbt_lib_desc.lib_name%TYPE;
   l_lib_status    sbt_lib_desc.status%TYPE;
BEGIN
   deb('statBpSbt: handle= ' || handle);
 
--
   SELECT lib.parms, lib.status, lib.lib_name, lib.lib_key
     INTO parms, l_lib_status, l_lib_name, l_lib_key
     FROM sbt_lib_desc lib, bp
    WHERE bp.lib_key = lib.lib_key
      AND bp.handle = statBpSbt.handle
      AND bp.db_key = statBpSbt.db_key;
 
--
   IF (l_lib_status != 'R') THEN
      deb('statBpSbt: library not ready');
      RETURN 1;
   END IF;
   
--
   devtype := sys.dbms_backup_restore.deviceAllocate(
                 ident        => 'RA$SBT',
                 node         => node,
                 type         => 'SBT_TAPE',
                 params       => parms,
                 dupcnt       => 1,
                 allowmts     => TRUE,
                 ors_lib_key  => l_lib_key,
                 db_name      => NULL,
                 platform_id  => 0);
 
--
   status := sys.kbrsi_icd.statBpSbt(
                handle    => handle,
                mhandle   => mhandle,
                single    => single);
 
--
   sys.dbms_backup_restore.deviceDeallocate;
 
   RETURN status;
EXCEPTION
   WHEN others THEN
      save_error;
--
      IF (devtype IS NOT NULL) THEN
         sys.dbms_backup_restore.deviceDeallocate;
      END IF;
      sys.kbrsi_icd.rsClearErr;
      clear_error;
      deb('statBpSbt: failed ' || sqlerrm);
      RETURN 0;
END statBpSbt;
 
 
--
FUNCTION dg_is_db_ok(p_dbid IN NUMBER) RETURN NUMBER IS
  l_answer NUMBER;
  l_dbkey  NUMBER;
  l_slkey  NUMBER;
  l_state  NUMBER;
  l_repair NUMBER;
BEGIN
--
  IF NOT sys.kbrsi_icd.isorsalive THEN
    deb('dg_is_db_ok: BA is DOWN');
    RETURN FALSE#;
  END IF;
 
--
--
--
  BEGIN
    SELECT db.db_key, odb.sl_key INTO l_dbkey, l_slkey
      FROM db, odb, sl
      WHERE db.db_id = p_dbid
        AND db.db_key = odb.db_key
        AND odb.sl_key = sl.sl_key
        AND odb.db_state IS NULL
        AND odb.platform_id IS NOT NULL
        AND sl.sl_needs_repair IS NULL;
    l_answer := TRUE#;
  EXCEPTION
    WHEN no_data_found THEN
      save_error;
      BEGIN
        SELECT odb.db_state, sl.sl_needs_repair INTO l_state, l_repair
          FROM db, odb, sl
         WHERE db.db_id = p_dbid
           AND db.db_key = odb.db_key
           AND odb.sl_key = sl.sl_key;
      deb('dg_is_db_ok: NO DATA FOUND, db_state: ' || TO_CHAR(l_state) ||
          ', needs_repair: ' || TO_CHAR(l_repair));
      EXCEPTION
        WHEN OTHERS THEN
          save_error;
          deb('dg_is_db_ok: no_data_found debugging query failed: ' ||
              SQLCODE || ' ' || SQLERRM);
          clear_error;
      END;
      l_answer := FALSE#;
      clear_error;
  END;
 
--
  RETURN l_answer;
END dg_is_db_ok;
 
 
--
FUNCTION dg_get_platform_id(p_dbid IN NUMBER) RETURN NUMBER IS
  l_platid NUMBER;
BEGIN
  deb('dg_get_platform_id: For dbid ' || to_char(p_dbid));
 
  SELECT odb.platform_id INTO l_platid
    FROM db, odb 
    WHERE db.db_id = p_dbid
      AND db.db_key = odb.db_key;
 
  deb('dg_get_platform_id: return ' || to_char(l_platid));
 
  RETURN l_platid;
END dg_get_platform_id;
 
 
--
PROCEDURE dg_register_log(p_dbid IN NUMBER, p_filename IN VARCHAR2)
IS
  task_rec            task%ROWTYPE;
BEGIN
  deb('dg_register_log: ' || p_filename, AM_DEBUG_MED);
 
  /* THIS CAN BE RETIRED */
END dg_register_log;
 
 
--
PROCEDURE dg_backup_log(p_dbid     IN NUMBER,
                        p_filename IN VARCHAR2,
                        p_complete IN BOOLEAN,
                        p_delete   IN BOOLEAN DEFAULT TRUE) IS
  task_rec            task%ROWTYPE;
BEGIN
  deb('dg_backup_log: ' || p_filename, AM_DEBUG_MED);
 
--
--
--
  SELECT db_key INTO task_rec.db_key FROM db WHERE db_id = p_dbid;
  IF p_complete THEN
    task_rec.task_type   := dbms_ra_scheduler.TASK_BACKUP_ARCH;
  ELSE
    task_rec.task_type   := dbms_ra_scheduler.TASK_INC_ARCH;
  END IF;
 
--
--
--
  task_rec.param       := p_filename;
  task_rec.param_num1  := p_dbid;
  IF p_delete THEN
    task_rec.param_num2  := 1;
  ELSE
    task_rec.param_num2  := 0;
  END IF;
 
  dbms_ra_scheduler.new_task (task_rec);
END dg_backup_log;
 
 
--
--
--
PROCEDURE RebuildBlockPool(p_dfkey IN NUMBER) IS
BEGIN
  deb('RebuildBlockPool for df ' || p_dfkey, AM_DEBUG_MED);
--
  dbms_ra_scheduler.stop (p_quiesce_first => FALSE);
 
--
--
--
  UPDATE config SET value = '.9994'
    WHERE name = '_last_incarnation';
 
--
  DELETE vbdf WHERE vbdf.df_key = p_dfkey;
  deb('RebuildBlockPool: Deleted ' || SQL%ROWCOUNT || ' vbdfs', AM_DEBUG_MED);
 
--
  DELETE blocks  WHERE df_key = p_dfkey;
  deb('RebuildBlockPool: Deleted ' || SQL%ROWCOUNT || ' blocks', AM_DEBUG_MED);
 
--
  DELETE chunks WHERE chunks.df_key = p_dfkey;
  deb('RebuildBlockPool: Deleted ' || SQL%ROWCOUNT || ' chunks', AM_DEBUG_MED);
  COMMIT;
 
--
  dbms_ra_scheduler.init (p_repair => TRUE);
  deb('RebuildBlockPool: Completed ', AM_DEBUG_MED);
END RebuildBlockPool;
 
--
--
--
FUNCTION sbt_default_drives RETURN NUMBER IS
   l_drives_per_node NUMBER;
   l_min_drives      NUMBER;
   l_max_drives      NUMBER;
   l_instances       NUMBER;
   l_drives NUMBER;
BEGIN
   SELECT nvl(max(to_number(value)), 4)
     INTO l_drives_per_node
     FROM config
    WHERE name = '_replication_streams_per_node';
 
   SELECT nvl(max(to_number(value)), 4)
     INTO l_min_drives
     FROM config
    WHERE name = '_replication_min_streams';
 
   SELECT nvl(max(to_number(value)), 64)
     INTO l_max_drives
     FROM config
    WHERE name = '_replication_max_streams';
 
   SELECT count(*)
     INTO l_instances
     FROM sys.rai_active_instances;
 
   l_drives := l_drives_per_node * l_instances;
 
   IF l_drives < l_min_drives THEN
     l_drives := l_min_drives;
   END IF;
 
   IF l_drives > l_max_drives THEN
     l_drives := l_max_drives;
   END IF;
 
   RETURN l_drives;
END sbt_default_drives;
 
 
--
--
--
--
--
PROCEDURE info_start(p_module VARCHAR2, p_action IN VARCHAR2) IS
  c BINARY_INTEGER := s_info_module.COUNT;
BEGIN
  s_info_module(c) := p_module;
  s_info_action(c) := p_action;
  dbms_application_info.set_module(p_module, p_action);
 
  deb('info_start ' || s_info_module.COUNT, AM_DEBUG_MED);
END info_start;
 
--
--
--
--
--
--
PROCEDURE info_end(p_reset BOOLEAN DEFAULT FALSE) IS
BEGIN
  deb('info_end ' || s_info_module.COUNT, AM_DEBUG_MED);
 
--
  IF s_info_module.COUNT = 0 AND NOT p_reset THEN
--
    IF debug >= AM_DEBUG_MED THEN
      sys.dbms_sys_error.raise_system_error(
            dbms_ra_scheduler.E_INTERNAL_ERROR_NUM,
            'Missing info_start call');
    ELSE
      deb('info_end: Missing info_start, count is ' || s_info_module.COUNT,
          AM_DEBUG_ON);
 
      s_info_module(0) := 'ILLEGAL INDEX';
      s_info_action(0) := 'ILLEGAL INDEX';
    END IF;
  END IF;
 
--
  IF p_reset THEN
    IF s_info_module.COUNT > 1 THEN
      deb('info_end reset done, count ' || s_info_module.COUNT);
    END IF;
 
--
    WHILE (s_info_module.COUNT > 1) LOOP
      s_info_module.DELETE(s_info_module.LAST);
      s_info_action.DELETE(s_info_action.LAST);
    END LOOP;
  ELSE
    IF s_info_module.COUNT > 1 THEN
      s_info_module.DELETE(s_info_module.LAST);
      s_info_action.DELETE(s_info_action.LAST);
    ELSE
      s_info_module(0) := NULL;
      s_info_action(0) := NULL;
    END IF;
  END IF;
 
  dbms_application_info.set_module(s_info_module(s_info_module.LAST),
                                   s_info_action(s_info_action.LAST));
END info_end;
 
--
--
--
--
--
--
PROCEDURE populate_rsr_key(p_bp_key  IN NUMBER,
                           p_bs_key  IN NUMBER) IS
l_rsr_key       NUMBER;
l_vb_key        NUMBER;
l_rsr           NUMBER;
l_srcbp_key     NUMBER;
l_ba_access     bp.ba_access%TYPE;
l_device_type   bp.device_type%TYPE;
BEGIN
  
  deb('populate_rsr_key : Entered p_bp_key = ' || p_bp_key ||
      ' p_bs_key = ' || p_bs_key);
 
  SELECT vb_key, rsr_key, ba_access, device_type
    INTO l_vb_key, l_rsr_key, l_ba_access, l_device_type
    FROM bp
   WHERE bp_key = p_bp_key;
 
--
  IF l_vb_key IS NULL THEN
    IF l_rsr_key IS NULL THEN
--
--
--
      BEGIN
        SELECT rsr_key INTO l_rsr
          FROM bp
         WHERE bs_key = p_bs_key
           AND rsr_key IS NOT NULL
           AND rownum = 1;
      EXCEPTION
        WHEN no_data_found THEN
          deb('populate_rsr_key : No bp rows with bs_key = '|| p_bs_key || 
              ' has rsr_key. Resync is yet to happen.');
          RETURN;
      END;
 
      UPDATE bp
         SET rsr_key = l_rsr
       WHERE bp_key  = p_bp_key
         AND rsr_key IS NULL;
 
      deb('populate_rsr_key : Updated ' || SQL%ROWCOUNT || ' rows in bp '||
          'with rsr_key = ' || l_rsr || ' ;copy2tape/replication bkps');
    ELSE
--
--
 
--
--
      BEGIN
        SELECT vb_key INTO l_vb_key
          FROM vbdf
         WHERE srcbp_key = p_bp_key
           AND rownum = 1;
      EXCEPTION
        WHEN no_data_found THEN
--
          IF l_ba_access = 'U' AND l_device_type = 'DISK' THEN
--
--
--
            UPDATE bp
               SET rsr_key = l_rsr_key
             WHERE (bs_key IN (SELECT bs_key
                               FROM   bp
                               WHERE  vb_key
                               IN (SELECT vb_key
                                   FROM   vbdf
                                   WHERE  srcbp_key
                                   IN (SELECT bp_key
                                       FROM   bp
                                       WHERE  bs_key = p_bs_key)))
                    OR bs_key = p_bs_key)
               AND rsr_key IS NULL;
 
            deb('populate_rsr_key : Updated ' || SQL%ROWCOUNT || 
                ' rows in bp with rsr_key = ' || l_rsr_key || ' ;polling bkps');
          ELSE
--
--
--
            UPDATE bp
               SET rsr_key = l_rsr_key
             WHERE bs_key  = p_bs_key;
 
            deb('populate_rsr_key : Updated ' || SQL%ROWCOUNT || 
                ' rows in bp with rsr_key = ' || l_rsr_key || ' ;resync - ' ||
                ' non-datafiles copy2tape/replication ');
          END IF;
          RETURN;
      END;
 
      UPDATE bp
         SET rsr_key = l_rsr_key
       WHERE bs_key IN (SELECT bs_key 
                        FROM   bp 
                        WHERE  vb_key = l_vb_key)
         AND rsr_key IS NULL;
 
      deb('populate_rsr_key : Updated ' || SQL%ROWCOUNT || 
          ' rows in bp with rsr_key = ' || l_rsr_key || ' ;resync -' || 
          'virtual bkps and their copy2tape and replication bkps');
    END IF;
  ELSE
--
--
--
      BEGIN
        SELECT srcbp_key INTO l_srcbp_key
          FROM vbdf
         WHERE vb_key = l_vb_key
           AND rownum = 1;
 
        IF l_srcbp_key IS NOT NULL THEN
          SELECT rsr_key INTO l_rsr
            FROM bp
           WHERE bp_key = l_srcbp_key;
        END IF;
 
      EXCEPTION
        WHEN no_data_found THEN
           deb('populate_rsr_key : no parent bp row available' ||  
                'for vb_key= ' || l_vb_key);
           RETURN;
      END;
     
      IF l_rsr IS NOT NULL THEN
        UPDATE bp
           SET rsr_key = l_rsr
         WHERE bp_key  = p_bp_key
           AND rsr_key IS NULL;
 
        deb('populate_rsr_key : Updated ' || SQL%ROWCOUNT || 
            ' rows in bp with rsr_key = ' || l_rsr || '; virtual backups');
      END IF;
  END IF;
 
END populate_rsr_key;
 
 
/*----------------------------------------------------------------------------
 * This is for avm front end congestion control. If the requirement for a new
 * backup job exceeds the system bottleneck the job will have to wait.
 *
 * This is a co-operative throttling algorithm, where there will be many RMAN
 * jobs simultaneously requesting for AvM resources. Each RMAN client will
 * ping AvM at regular intervals (set to 1 min currently) until it gets a green
 * signal from the AvM side. AvM decides this based on the currently active
 * backup streams (channels) and the maximum allowable number of channels. AvM
 * will serve the clients in a first come first served manner. Once a client
 * gets approval it can go ahead with all its channel allocation.
 *
 * The algorithm uses the following four config parameters, viz,
 * _throttle_max_channels :
 *           This denotes the maximum number of channels allowed in AvM. In
 *           other words, this is the maximum limit after which we assume all
 *           AvM resources will be used up and no further allocation is
 *            possible until some of the previous jobs are done. If it is not
 *           set (or set to 0), we assume that resource control is not enabled.
 * _throttle_threshold_channels (default, _throttle_max_channels -(minus)
 *            _throttle_max_single_chan_req  ) :
 *           There is really no point throttling when the current allocation
 *           is way too less than the maximum allowable. This parameter
 *           specifies the value after which we force each job to go 
 *           through the throttling logic.
 * _throttle_wait_aft_apprvl_secs (default, 180 secs) :
 *           This specifies the time for which the next job will have to wait
 *           after the previous job is approved. This is basically a heuristic
 *           to guess the time interval between the approval of a job and the
 *           actual channel allocations by that job. When a job is approved,
 *           it'll need some time to actually allocate the channels and for
 *           this short duration the current allocation count will be in a
 *           transient state. So, we are assuming that by this time the
 *           previous job will be done allocating all its channels and the
 *           current allocation count will be stable and the next job can go
 *           ahead with its request.
 * _throttle_wait_for_crash_secs (default, 30 mins) :
 *           There can be cases where an RMAN job is crashed after requesting
 *           channel resources. There should be some mechanism to remove the
 *           crashed jobs from the waiting queue. This time is used for this
 *           purpose. If there is no ping from the client for this much time
 *           we assume that the job is killed and we remove the job from the
 *           waiting queue.
 * _throttle_sbt_active_hours (default, 12 hours) :
 *           BA will clear up the active sessions which are older than this
 *           time
 * _throttle_max_single_chan_req (default, 128) :
 *           This specifies the maximum channels that can be requested in
 *           one request
 * _throttle_wait_repeat_req_secs (default, 300 secs) :
 *           This specifies the minimum time for which the client has to wait
 *           before requesting for channels again
 *
 * Following is the high-level overview of the algorithm used:
 *
 * Inputs:
 *     p_ba_job_id :   unique identifier for the client requesting resources.
 *     p_channels_reqd: number of channels required by the client.
 *     p_request_time:  time when the request is made.
 * Outputs:
 *     p_wait : boolean output indicating wheather the client nedds to wait
 *              more. if p_wait = false, its a green signal from AvM and the
 *              client can go ahead with the allocation, otherwise the client
 *              will have to wait and re-ping after some time.
 *     p_error_str: indicates if there is any error condition.
 *
 * Algorithm:
 *     0. All the parameters that control the congestion algorithm will be
 * read only once per RMAN client.
 *     1. We allow the job to allocate required_channels if any of the
 * following is true -
 *             a) If number of currently allocated channels/active SBT streams
 *        (currently_active_channels) is less than _throttle_threshold_channels
 *             b) required_channels + currently_active_channels <
 *        _threshold_max_channels and this is the first job in the queue.
 *     2. We remove a job from the queue in the following two cases -
 *             a) When it is given go ahead with channel allocation and current
 *        time is past throttle_waitsecs_after_approval
 *             b) When there is no ping from an RMAN client beyond
 *        _threshold_waitsecs_for_crash
 *     3. In all other cases, job from top of queue is approved when required
 * number of SBT streams are freed up at AvM.
 *---------------------------------------------------------------------------*/
PROCEDURE throttle_me_int(p_ba_job_id          IN VARCHAR2,
                          p_db_unique_name     IN VARCHAR2,
                          p_channels_reqd      IN NUMBER,
                          p_request_time       IN DATE,
                          p_wait               OUT BOOLEAN,
                          p_error_str          OUT VARCHAR2)
IS
   l_min_request_time       DATE;
   l_active_sbt_sessions    NUMBER;
   l_rowids                 dbms_sql.urowid_table;
   l_max_channel            NUMBER;
   l_wait_after_approve     NUMBER;
   l_wait_for_crash         NUMBER;
   l_threshold_channels     NUMBER;
   l_ba_job_id              VARCHAR2(256);
   l_max_single_req         NUMBER;
   l_wait_for_repeat_req    NUMBER;
   l_approved_sessions      NUMBER;
   type avmlst is table of VARCHAR2(256) index by binary_integer;
   l_ba_job_ids            avmlst;
   type sbtlst is table of VARCHAR2(32) index by binary_integer;
   l_sbt_sessions           sbtlst;
   l_lock_retval            NUMBER;
   l_lock_handle            VARCHAR2(200);
   l_is_locked              BOOLEAN := FALSE;
   l_ba_job_id_dbunq        VARCHAR2(256);
   PROCEDURE release_lock IS
   BEGIN
     IF l_is_locked THEN
       l_lock_retval := dbms_lock.release(l_lock_handle);
     END IF;
   END;
   
BEGIN
  p_wait := true;
  p_error_str := null;
--
--
  l_ba_job_id_dbunq := p_ba_job_id || p_db_unique_name;
 
--
--
  IF sys.kbrsi_icd.rskeyreadlock (dbms_ra_scheduler.lock_quiesce_pending,
                                  FALSE) THEN
--
    SYS.KBRSI_ICD.RSKEYUNLOCK(DBMS_RA_SCHEDULER.LOCK_QUIESCE_PENDING);
  ELSE
    deb('Throttle: Quiesce is pending.  Go away.');
    RETURN;
  END IF;
 
  deb('Throttle: throttling for db: ' || p_db_unique_name);
 
--
  SELECT /*+ RESULT_CACHE */
      NVL(MAX(DECODE(name, '_throttle_max_channels', value)), 1000) mc,
      NVL(MAX(DECODE(name, '_throttle_threshold_channels', value)), 872) tc,
      NVL(MAX(DECODE(name, '_throttle_wait_aft_apprvl_secs', value)), 300) wap,
      NVL(MAX(DECODE(name, '_throttle_wait_for_crash_secs', value)), 1800) wfc,
      NVL(MAX(DECODE(name, '_throttle_max_single_chan_req', value)), 128) mscr,
      NVL(MAX(DECODE(name, '_throttle_wait_repeat_req_secs', value)), 300) wrr
   INTO l_max_channel, l_threshold_channels, l_wait_after_approve,
        l_wait_for_crash, l_max_single_req,
        l_wait_for_repeat_req
   FROM config
     WHERE name IN (
           '_throttle_max_channels',
           '_throttle_threshold_channels',
           '_throttle_wait_aft_apprvl_secs',
           '_throttle_wait_for_crash_secs',
           '_throttle_max_single_chan_req',
           '_throttle_wait_repeat_req_secs'
           );
 
--
--
--
  IF (((SYSDATE - s_last_throttled) * 86400) <=
      l_wait_for_repeat_req) THEN
     p_wait := TRUE;
     RETURN;
  END IF;
 
--
--
  IF p_channels_reqd > l_max_single_req THEN
     p_error_str := 'client can request only max of ' || l_max_single_req ||
                    ' channels';
     RETURN;
  END IF;
 
--
  IF l_max_channel  > 0 THEN
 
--
--
--
--
    BEGIN
      SELECT rowid, ba_job_id
        BULK COLLECT INTO
              l_rowids, l_ba_job_ids
        FROM  rai_pending_jobs
        WHERE ((sysdate - approval_time) * 86400) >= l_wait_after_approve
          OR  ((sysdate - last_ping_time) * 86400) >= l_wait_for_crash
          FOR UPDATE SKIP LOCKED;
        FOR i IN 1 .. l_rowids.COUNT LOOP
          DELETE rai_pending_jobs
            WHERE ROWID = l_rowids(i);
          deb('Throttle: Deleting entry ' || l_ba_job_ids(i) ||
              ' from rai_pending_jobs');
        END LOOP;
    END;
 
--
--
    BEGIN
      SELECT rowid, session_id
        BULK COLLECT INTO
              l_rowids, l_sbt_sessions
        FROM  sbt_session
        WHERE systimestamp >
              (modtime + dbms_ra_scheduler.s_sbt_active_interval)
          FOR UPDATE SKIP LOCKED;
 
        FOR i IN 1 .. l_rowids.COUNT LOOP
          DELETE sbt_session
            WHERE ROWID = l_rowids(i);
          deb('Throttle: Deleting entry ' || l_sbt_sessions(i) ||
              ' from sbt_active_sessions');
        END LOOP;
    END;
 
--
--
    BEGIN
      INSERT INTO rai_pending_jobs
                  (ba_job_id, request_time, channels_reqd,
                   db_unique_name, last_ping_time)
        VALUES (l_ba_job_id_dbunq, p_request_time,
                 p_channels_reqd, p_db_unique_name, sysdate);
      COMMIT;
      deb('Throttle: New RMAN job ' || l_ba_job_id_dbunq);
    EXCEPTION
      WHEN dup_val_on_index THEN
        save_error;
        UPDATE rai_pending_jobs SET last_ping_time = sysdate
          WHERE ba_job_id = l_ba_job_id_dbunq;
        COMMIT;
        clear_error;
    END;
    
    BEGIN
--
--
--
      dbms_lock.allocate_unique('ORA$ZDLRA_SBT_CHANNEL_THROTTLE', 
                                 l_lock_handle);
      l_lock_retval := dbms_lock.request(l_lock_handle);
 
      IF l_lock_retval <> 0 THEN
         deb('Throttle:Unable to get lock ORA$ZDLRA_SBT_CHANNEL_THROTTLE err = '
                                    || l_lock_retval);
 
         sys.dbms_sys_error.raise_system_error(
            DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM,
            'Throttle:Unable to get lock for throttling. Error=' || 
              l_lock_retval);
      END IF;
      l_is_locked := TRUE;
 
--
      SELECT COUNT(*) INTO l_active_sbt_sessions FROM sbt_session;
      deb('Throttle: Active backup/restore sessions=' || l_active_sbt_sessions);
 
      SELECT nvl(sum(channels_reqd), 0) INTO l_approved_sessions
         FROM rai_pending_jobs
            WHERE (approval_time IS NOT NULL AND
                   ((sysdate - approval_time) * 86400) <=
                   l_wait_after_approve);
 
      deb('Throttle: Allowed connections=' || l_approved_sessions);
 
--
      IF (l_active_sbt_sessions + l_approved_sessions >= 
          l_threshold_channels) THEN
 
--
--
--
        IF (l_active_sbt_sessions + p_channels_reqd + l_approved_sessions <=
            l_max_channel) THEN
 
--
--
          BEGIN
             SELECT request_time, ba_job_id
               INTO l_min_request_time, l_ba_job_id
               FROM (
                   SELECT request_time, ba_job_id
                      FROM ra_database ad, rai_pending_jobs ap
                      WHERE ad.db_unique_name = ap.db_unique_name AND
                            approval_time IS NULL AND
                            (((sysdate - last_ping_time) * 86400) <=
                             (0.2 * l_wait_for_crash))
                      ORDER BY recovery_window_goal DESC, request_time)
                WHERE ROWNUM = 1;
 
             deb('Throttle: Selected job is: ' || l_ba_job_id ||
                 ' request time is: ' || l_min_request_time);
             deb('Throttle: Current job request time is: ' ||
                 p_request_time);
 
             IF l_min_request_time = p_request_time AND
                l_ba_job_id = l_ba_job_id_dbunq THEN
               p_wait := false;
--
--
--
--
               s_last_throttled := SYSDATE;
             ELSE
               deb('Throttle: need to wait');
             END IF;
 
          EXCEPTION
             WHEN NO_DATA_FOUND THEN
               save_error;
               NULL;
               clear_error;
          END;
        END IF;
      ELSE
--
         p_wait := FALSE;
      END IF;
    EXCEPTION
      WHEN OTHERS THEN
--
        release_lock;
        RAISE;
    END;
 
  ELSE
--
     p_wait := FALSE;
  END IF;
 
  BEGIN
    IF p_wait = FALSE THEN
       UPDATE rai_pending_jobs SET approval_time = sysdate
          WHERE ba_job_id = l_ba_job_id_dbunq  
          AND   approval_time IS NULL;
       IF SQL%ROWCOUNT = 1 THEN
          deb('Throttle: setting wait to false');
          COMMIT;
       ELSE
--
--
          deb('Throttle: Unexpected, rai_pending_jobs rows updated ' ||
               sql%rowcount);
          ROLLBACK;
       END IF;
    END IF;
 
--
    release_lock;
  EXCEPTION
    WHEN OTHERS THEN
--
      release_lock;
      RAISE;
  END;
END throttle_me_int;
 
/*----------------------------------------------------------------------------
 * This routine is DBLRA specific but mimics the dbms_utility.canonicalize().
 * see $ORACLE_HOME/rdbms/admin/dbmsutil.sql The interface is kept the same,
 * although the functionality is tailored to support longer identifiers as
 * well as restrict the number of supported characters to avoid customers
 * specifying cryptic names.
 *
 * Neither dbms_utility.canonicalize nor dbms_assert.enquote_name nor this
 * implementation does use a generic_m NLS sorting. I.e. e.g. customers from
 * Germany should not anticipate to see the conversion of Eszett symbol to
 * double S -- see http://en.wikipedia.org/wiki/German_alphabet. For
 * illustration purposes review this script:
 *
 * -- setenv NLS_LANG AMERICAN_AMERICA.UTF8
 * -- export NLS_LANG=AMERICAN_AMERICA.UTF8
 * SET SERVEROUTPUT ON
 * DECLARE
 *   l_e                              VARCHAR2(1 CHAR) := UNISTR('\00DF');
 *   l_canon                          VARCHAR2(1 CHAR);
 *   l_length                         BINARY_INTEGER := 1;
 *   PROCEDURE p(s VARCHAR) IS BEGIN dbms_output.put_line(s); END;
 * BEGIN
 *   p('original=[' || l_e || ']');
 *   p('upper=[' || UPPER(l_e) || ']');
 *   p('nls_upper=[' || NLS_UPPER(l_e) || ']');
 *   -- http://en.wikipedia.org/wiki/German_alphabet
 *   -- "Eszett is sorted as though it were ss."
 *   p('nls_upper_gen_m=[' || NLS_UPPER(l_e, 'NLS_SORT=GENERIC_M') || ']');
 *   p('enquote_name=[' || dbms_assert.enquote_name(l_e) || ']');
 *   p('enquote_name w/o capitalization=['
 *   || dbms_assert.enquote_name(l_e, FALSE) || ']');
 *   dbms_utility.canonicalize(l_e, l_canon, l_length);
 *   p('dbms_utility.canonicalize=[' || l_canon || ']');
 *   dbms_ra_int.canonicalize(l_e, l_canon, l_length);
 *  p('dbms_ra_int.canonicalize=[' || l_canon || ']');
 * END;
 * /
 *
 * If this implementation is changed one must correct the corresponding
 * unit test tkrmrsapi.sql script
 *---------------------------------------------------------------------------*/
PROCEDURE canonicalize (
  name                             IN VARCHAR2
, canon_name                       OUT VARCHAR2
, canon_len                        IN BINARY_INTEGER
)
IS
--
--
  lc_length_limit                  CONSTANT BINARY_INTEGER := 1000;
 
--
--
--
--
--
--
--
--
  lc_allowed_re                    CONSTANT VARCHAR2(128) := '-_:#[:alnum:]';
  lc_not_allowed_re                CONSTANT VARCHAR2(128) :=
    CASE WHEN lc_allowed_re IS NOT NULL THEN '[^' || lc_allowed_re || ']' END;
 
--
--
--
--
--
--
  lc_leading_restricted_chars_re   CONSTANT VARCHAR2(128) := '^[-_:#[:digit:]]';
 
--
  l_name                           VARCHAR2(32767 BYTE);
 
--
  l_bad_char_pos                   BINARY_INTEGER;
BEGIN
--
  IF (name IS NULL) THEN RETURN; END IF;
 
--
  IF (canon_len IS NULL OR canon_len < 1)
  THEN
    sys.dbms_sys_error.raise_system_error(-64744, 'canon_len', FALSE);
  END IF;
 
--
  IF (LENGTH(name) > lc_length_limit OR canon_len > lc_length_limit)
  THEN
    sys.dbms_sys_error.raise_system_error(
      -64745, TO_CHAR(lc_length_limit), FALSE
    );
  END IF;
 
--
--
--
  BEGIN
    l_name := TRIM(BOTH '"' FROM dbms_assert.enquote_name(str => name));
  EXCEPTION
    WHEN VALUE_ERROR
      OR dbms_assert.INVALID_SQL_NAME
    THEN sys.dbms_sys_error.raise_system_error(-64746, FALSE);
  END;
 
--
  l_bad_char_pos := GREATEST(
                     REGEXP_INSTR(l_name, lc_not_allowed_re)
                   , REGEXP_INSTR(l_name, lc_leading_restricted_chars_re)
                   );
  IF (l_bad_char_pos > 0)
  THEN
    sys.dbms_sys_error.raise_system_error(
      -64747, SUBSTR(l_name, l_bad_char_pos, 1), TO_CHAR(l_bad_char_pos), FALSE
    );
  END IF;
 
--
  canon_name := SUBSTR(l_name, 1, canon_len);
END canonicalize;
 
--
--
--
--
--
--
--
FUNCTION build_rep_tpl_name ( rep_srv_name IN VARCHAR2,
                              db_key       IN NUMBER,
                              prot_key     IN NUMBER) RETURN VARCHAR2
IS
  tmp_name       VARCHAR2(1024);
  l_server_key  NUMBER;
  l_rep_srv_key  NUMBER;
BEGIN
  SELECT server_key
    INTO l_server_key
    FROM server
    WHERE rep_server_name=build_rep_tpl_name.rep_srv_name;
 
  SELECT rep_server_key
    INTO l_rep_srv_key
    FROM rep_server
      WHERE server_key = l_server_key
        AND prot_key   = build_rep_tpl_name.prot_key;
 
--
--
--
  tmp_name :=
    'REP$TPL_' || l_rep_srv_key || '_' || db_key || '_' || rep_srv_name;
  RETURN substr(tmp_name, 1, 128);
 
EXCEPTION
  WHEN NO_DATA_FOUND THEN
--
--
--
    save_error;
 
--
    am_tracei('BUILD_REP_TPL_NAME:  Did not find needed info.' ||
              ', rep server=' || rep_srv_name ||
              ', db_key=' || db_key ||
              ', l_server_key=' || l_server_key ||
              ', l_prot_key=' || prot_key ||
              ', l_rep_srv_key=' || l_rep_srv_key);
    sys.dbms_sys_error.raise_system_error(
            DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM,
            'BUILD_REP_TPL_NAME:  Did not find needed info.' ||
              ', rep server=' || rep_srv_name ||
              ', db_key=' || db_key ||
              ', l_server_key=' || l_server_key ||
              ', l_prot_key=' || prot_key ||
              ', l_rep_srv_key=' || l_rep_srv_key,
            FALSE);
END build_rep_tpl_name;
 
--
--
--
--
--
--
--
FUNCTION build_rep_lib_name (rep_srv_name IN VARCHAR2,
                             server_key   IN NUMBER DEFAULT NULL
                             ) RETURN VARCHAR2
IS
  tmp_name     VARCHAR2(1024);
  l_skey       VARCHAR2(128) := to_char(server_key);
BEGIN
  IF server_key IS NULL THEN
    SELECT to_char(server_key)
      INTO l_skey
      FROM server
      WHERE rep_server_name=rep_srv_name;
  END IF;
  tmp_name := 'REP$LIB_' || l_skey || '_' || rep_srv_name;
 
  RETURN substr(tmp_name, 1, 128);
 
EXCEPTION
  WHEN NO_DATA_FOUND THEN
--
--
--
    save_error;
 
--
    am_tracei('BUILD_REP_LIB_NAME:  Did not find rep server ' || rep_srv_name);
    sys.dbms_sys_error.raise_system_error(
            DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM,
            'BUILD_REP_LIB_NAME:  Did not find rep server ' || rep_srv_name,
            FALSE);
END build_rep_lib_name;
 
--
--
--
--
--
FUNCTION build_rep_atr_name (rep_srv_name IN VARCHAR2,
                             server_key   IN NUMBER DEFAULT NULL)
                             RETURN VARCHAR2
IS
  tmp_name     VARCHAR2(1024);
  l_skey       VARCHAR2(128) := to_char(server_key);
BEGIN
  IF server_key IS NULL THEN
    SELECT to_char(server_key)
      INTO l_skey
      FROM server
      WHERE rep_server_name=rep_srv_name;
  END IF;
  tmp_name := 'REP$ATR_' || l_skey || '_' || rep_srv_name;
 
  RETURN substr(tmp_name, 1, 128);
 
EXCEPTION
  WHEN NO_DATA_FOUND THEN
--
--
--
    save_error;
 
--
    am_tracei('BUILD_REP_ATR_NAME:  Did not find rep server ' || rep_srv_name);
    sys.dbms_sys_error.raise_system_error(
            DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM,
            'BUILD_REP_ATR_NAME:  Did not find rep server ' || rep_srv_name,
            FALSE);
END build_rep_atr_name;
 
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE lock_api_int (p_op_type     IN NUMBER DEFAULT NULL,
                    p_routine     IN VARCHAR2 DEFAULT NULL,
                    p_dbgnotes    IN VARCHAR2 DEFAULT NULL)
IS
  CURSOR existing_locks IS
    SELECT ba_type, key
      FROM sys.rai_js_locks
      WHERE sid = SYS_CONTEXT('USERENV', 'SID')
        AND (ba_type IN (DBMS_RA_SCHEDULER.LOCK_KEY,
                          DBMS_RA_SCHEDULER.LOCK_PURGE,
                          DBMS_RA_SCHEDULER.LOCK_SL_KEY,
                          DBMS_RA_SCHEDULER.LOCK_DB_KEY) OR
             (ba_type = DBMS_RA_SCHEDULER.LOCK_COMMON AND
              key = DBMS_RA_SCHEDULER.LOCK_API));
 
  l_sid NUMBER;
  l_instance NUMBER;
  l_existing_locks NUMBER;
  l_api_lock_wait NUMBER;
 
BEGIN
  am_tracei ('LOCK_API_INT for:  ' || p_routine ||
            ', lock type:     ' || p_op_type ||
            ', with dbg notes:' || p_dbgnotes);
 
--
--
--
  SELECT COUNT(*) INTO l_existing_locks
    FROM sys.rai_js_locks
    WHERE sid = SYS_CONTEXT('USERENV', 'SID')
      AND (ba_type IN (DBMS_RA_SCHEDULER.LOCK_KEY,
                        DBMS_RA_SCHEDULER.LOCK_PURGE,
                        DBMS_RA_SCHEDULER.LOCK_SL_KEY,
                        DBMS_RA_SCHEDULER.LOCK_DB_KEY) OR
           (ba_type = DBMS_RA_SCHEDULER.LOCK_COMMON AND
            key = DBMS_RA_SCHEDULER.LOCK_API));
 
--
--
--
--
--
--
--
--
 
  IF (s_lockapi_level <> 0) OR (l_existing_locks <> 0) THEN
--
    SELECT SYS_CONTEXT('USERENV', 'SID') INTO l_sid FROM dual;
    SELECT sys_context('USERENV', 'INSTANCE') INTO l_instance FROM dual;
 
    am_tracei('LOCK_API_INT:  ERROR - API lock exists for this session: '
           || ' existing_lock_cnt=' || l_existing_locks
           || ' s_lockapi_level=' || s_lockapi_level
           || ' l_instance=' || l_instance
           || ' l_sid=' || l_sid);
  END IF;
 
  IF (l_existing_locks <> 0) THEN
    am_tracei('LOCK_API_INT:  Releasing all API locks help by this session');
 
--
    FOR l IN existing_locks LOOP
      am_tracei('LOCK_API_INT:  Releasing API lock due to ctrl-c: ' ||
             ' Lock type:'               || l.ba_type ||
             ', Lock key:'               || l.key );
      CASE l.ba_type
        WHEN DBMS_RA_SCHEDULER.LOCK_DB_KEY
            THEN dbms_ra_storage.unlock_db(l.key);
        WHEN DBMS_RA_SCHEDULER.LOCK_SL_KEY
            THEN dbms_ra_storage.unlock_sl(l.key);
        WHEN DBMS_RA_SCHEDULER.LOCK_PURGE
            THEN sys.kbrsi_icd.rspurgeunlock(l.key);
        WHEN DBMS_RA_SCHEDULER.LOCK_KEY
            THEN sys.kbrsi_icd.rskeyunlock(l.key);
        WHEN DBMS_RA_SCHEDULER.LOCK_COMMON
            THEN unlock_api_int(p_results=>FALSE, p_docommit=>FALSE);
      END CASE;
    END LOOP;
 
--
    ROLLBACK;
 
--
    s_lockapi_level := 0;
 
  END IF;
 
--
--
  s_lockapi_routine  := p_routine;
  s_lockapi_notes    := p_dbgnotes;
  s_lockapi_type     := p_op_type;
 
--
  SELECT value INTO l_api_lock_wait
    FROM config
    WHERE name = '_api_lock_wait_seconds';
 
--
  WHILE NOT sys.kbrsi_icd.rsapilock LOOP
    BEGIN
--
      IF l_api_lock_wait > 0 THEN
        l_api_lock_wait := l_api_lock_wait - 1;
        dbms_lock.sleep(1);
        CONTINUE;
      END IF;
 
--
      SELECT inst_id, sid INTO l_instance, l_sid
        FROM sys.rai_js_gvlocks
        WHERE ba_type = dbms_ra_scheduler.lock_common
          AND key = dbms_ra_scheduler.lock_api
          AND lmode = 6; -- =KSQMX (exclusive mode)
 
      sys.dbms_sys_error.raise_system_error(DBMS_RA.API_BLOCKED_NUM,
                                            l_sid,
                                            l_instance,
                                            FALSE);
 
    EXCEPTION
      WHEN NO_DATA_FOUND THEN
        dbms_lock.sleep(1);
        CONTINUE;
    END;
 
  END LOOP;
 
  s_lockapi_level := s_lockapi_level + 1;
 
EXCEPTION
  WHEN OTHERS THEN
    am_tracei ('LOCK_API_INT EXCEPTION: '  || SQLERRM);
    RAISE;
 
END lock_api_int;
--
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE unlock_api_int (p_routine     IN VARCHAR2 DEFAULT NULL,
                      p_dbgnotes    IN VARCHAR2 DEFAULT NULL,
                      p_the_num     IN NUMBER DEFAULT 0,
                      p_results     IN BOOLEAN DEFAULT TRUE,
                      p_docommit    IN BOOLEAN DEFAULT FALSE)
IS
BEGIN
  am_tracei ('UNLOCK_API_INT for ' || p_routine || '()' || p_dbgnotes);
 
--
  IF (p_the_num > 0) THEN
    dbms_ra_scheduler.update_task_history_entry (
       task_id => p_the_num ,
       param_char2 => CASE WHEN
             p_results THEN 'SUCCESS' ELSE 'FAIL' END ,
             do_commit => p_docommit );
  END IF;
 
--
--
--
  SELECT COUNT(*) INTO s_lockapi_level
    FROM sys.rai_js_locks
    WHERE sid = SYS_CONTEXT('USERENV', 'SID')
      AND ba_type = DBMS_RA_SCHEDULER.LOCK_COMMON
      AND key = DBMS_RA_SCHEDULER.LOCK_API;
 
  IF (s_lockapi_level > 0) THEN
    s_lockapi_routine  := NULL;
    s_lockapi_notes    := NULL;
    s_lockapi_type     := NULL;
 
--
    sys.kbrsi_icd.rsapiunlock;
 
    s_lockapi_level := s_lockapi_level - 1;
  END IF;
 
EXCEPTION
  WHEN OTHERS THEN
    am_tracei ('UNLOCK_API_INT EXCEPTION: '  || SQLERRM);
    RAISE;
 
END unlock_api_int;
--
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
FUNCTION build_parameter (p_paramtype IN NUMBER,
                          p_varname   IN VARCHAR2,
                          p_strval    IN VARCHAR2 DEFAULT NULL,
                          p_numval    IN NUMBER DEFAULT NULL,
                          p_boolval   IN BOOLEAN DEFAULT NULL,
                          p_intval    IN DSINTERVAL_UNCONSTRAINED DEFAULT NULL,
                          p_first     IN BOOLEAN DEFAULT FALSE,
                          p_last      IN BOOLEAN DEFAULT FALSE) RETURN VARCHAR2
IS
  l_str     VARCHAR2(4000);
BEGIN
 
  IF p_first THEN
    l_str := l_str || '(';
  END IF;
 
  IF NOT p_first THEN
    l_str := l_str || ', ';
  END IF;
 
  l_str := l_str || p_varname || '=>';
 
  CASE p_paramtype
 
    WHEN PTYPE_STR THEN
      IF p_strval IS NULL THEN
        l_str := l_str || 'NULL';
      ELSE
        l_str := l_str || '''' || p_strval || '''';
      END IF;
 
    WHEN PTYPE_NUM THEN
      IF p_numval IS NULL THEN
        l_str := l_str || 'NULL';
      ELSE
        l_str := l_str || p_numval;
      END IF;
 
    WHEN PTYPE_BOOL THEN
      IF p_boolval IS NULL THEN
        l_str := l_str || 'NULL';
      ELSIF p_boolval THEN
        l_str := l_str || 'TRUE';
      ELSE
        l_str := l_str || 'FALSE';
      END IF;
 
    WHEN PTYPE_INT THEN
      IF p_intval IS NULL THEN
        l_str := l_str || 'NULL';
      ELSE
--
        l_str := l_str || p_intval;
      END IF;
 
  ELSE
    l_str := l_str || '<OTHER>';
  END CASE;
 
 
  IF p_last THEN
    l_str := l_str || ')';
  END IF;
 
  RETURN l_str;
 
END build_parameter;
--
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
FUNCTION b_p_i (p_varname IN VARCHAR2,
                p_strval  IN VARCHAR2 DEFAULT NULL,
                p_first   IN BOOLEAN DEFAULT FALSE,
                p_last    IN BOOLEAN DEFAULT FALSE) RETURN VARCHAR2
IS
BEGIN
 
  RETURN build_parameter (p_paramtype => PTYPE_STR,
                          p_varname   => p_varname,
                          p_strval    => p_strval,
                          p_first     => p_first,
                          p_last      => p_last);
 
END b_p_i;
--
 
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
FUNCTION b_p_i (p_varname IN VARCHAR2,
                p_numval  IN NUMBER DEFAULT NULL,
                p_first   IN BOOLEAN DEFAULT FALSE,
                p_last    IN BOOLEAN DEFAULT FALSE) RETURN VARCHAR2
IS
BEGIN
 
  RETURN build_parameter (p_paramtype => PTYPE_NUM,
                          p_varname   => p_varname,
                          p_numval    => p_numval,
                          p_first     => p_first,
                          p_last      => p_last);
 
END b_p_i;
--
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
FUNCTION b_p_i (p_varname IN VARCHAR2,
                p_boolval IN BOOLEAN DEFAULT NULL,
                p_first   IN BOOLEAN DEFAULT FALSE,
                p_last    IN BOOLEAN DEFAULT FALSE) RETURN VARCHAR2
IS
BEGIN
 
  RETURN build_parameter (p_paramtype => PTYPE_BOOL,
                          p_varname   => p_varname,
                          p_boolval   => p_boolval,
                          p_first     => p_first,
                          p_last      => p_last);
 
END b_p_i;
--
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
FUNCTION b_p_i (p_varname  IN VARCHAR2,
                p_intval   IN DSINTERVAL_UNCONSTRAINED DEFAULT NULL,
                p_first    IN BOOLEAN DEFAULT FALSE,
                p_last     IN BOOLEAN DEFAULT FALSE) RETURN VARCHAR2
IS
BEGIN
 
  RETURN build_parameter (p_paramtype => PTYPE_INT,
                          p_varname   => p_varname,
                          p_intval    => p_intval,
                          p_first     => p_first,
                          p_last      => p_last);
END b_p_i;
--
 
--
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE am_tracei (p_message IN VARCHAR2) IS
BEGIN
--
 
  sys.kbrsi_icd.rsTrace('BA: ' || p_message);
--
END am_tracei;
--
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
FUNCTION item_not_foundi (p_obj_name IN VARCHAR2,
                          p_obj_type IN VARCHAR2) RETURN VARCHAR2 IS
BEGIN
  RETURN 'item not found: ' || p_obj_name ||' (' || p_obj_type || ')';
END item_not_foundi;
--
 
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE replication_reconcile_reset (db_unique_name IN VARCHAR2)
IS
BEGIN
  NULL;
--
END;
--
 
--
--
--
--
--
PROCEDURE rep_rec_by_prot_int (p_prot_key IN NUMBER)
IS
  l_cnt             NUMBER;
  l_db_key          NUMBER;
  l_rep_server_key          NUMBER;
  l_all_reconciled  BOOLEAN := TRUE;
 
--
  CURSOR toreconcile_cursor(pp_key IN NUMBER) IS
    select rep_server_key rep_server_key, o.db_key db_key, rs.server_key
      from rep_server rs, odb o
      where rs.prot_key = pp_key
        and rs.status = 'A'
        and o.prot_key = rs.prot_key
        and o.db_state is NULL;
BEGIN
  am_tracei('reconcile by prot prot_key=' || p_prot_key);
 
--
  IF p_prot_key IS NULL THEN
     am_tracei('replication_reconcile_prot_int NULL prot_key');
     sys.dbms_sys_error.raise_system_error
        (DBMS_RA.INVALID_VAL_NUM,
         'replication_reconcile_prot_int NULL prot_key',
         FALSE);
  END IF;
 
--
--
--
  FOR r IN toreconcile_cursor(p_prot_key) LOOP
    am_tracei('reconcile by prot prot_key=' || p_prot_key || ', r.db_key=' ||
              r.db_key || ', r.rep_server_key=' || r.rep_server_key ||
              ', r.server_key=' || r.server_key) ;
    replication_reconcile_int (r.db_key, r.server_key);
  END LOOP;
 
  am_tracei('reconcile by prot SUCCESS - prot_key=' || p_prot_key);
 
END rep_rec_by_prot_int;
--
 
--
--
--
--
--
PROCEDURE replication_reconcile_int (p_db_key IN NUMBER DEFAULT NULL,
                                     p_server_key IN NUMBER DEFAULT NULL)
IS
  l_cnt        NUMBER;
  l_success    BOOLEAN;
  l_exp_cnt    NUMBER;
BEGIN
 
--
  IF p_db_key IS NULL THEN
    am_tracei('replication_reconcile_int NULL db_key');
    sys.dbms_sys_error.raise_system_error
      (DBMS_RA.INVALID_VAL_NUM,
       'replication_reconcile_int NULL db_key',
       FALSE);
  END IF;
 
  IF p_server_key IS NOT NULL THEN
    l_exp_cnt := 1;
  ELSE
    SELECT count(*) INTO l_exp_cnt FROM rep_server rs
      WHERE rs.prot_key = (SELECT prot_key FROM odb WHERE db_key=p_db_key
                           and db_state is NULL);
  END IF;
 
--
  l_success := dbms_ra_scheduler.reconcile_db (
                             p_db_key          => p_db_key,
                             p_server_key      => p_server_key,
                             p_only_active     => FALSE,
                             p_force_reconcile => TRUE,
                             rec_cnt           => l_cnt);
 
  IF NOT l_success OR l_cnt <> l_exp_cnt THEN
    dbms_ra_scheduler.log_error(p_errno => dbms_ra.REP_SETUP_ERROR_NUM,
                                p_db_key => p_db_key,
                                p_param1 => 'reconcile_db',
                                p_param2 => 'USER_REC_SRV_KEY=p_server_key',
                                p_param3  => dbms_ra_int.dbkey2name(p_db_key),
                                P_keep_stack => FALSE,
                                p_component =>'REPLICATION_RECONCILE',
                                p_severity => dbms_ra_scheduler.SEVERITY_ERROR,
                                p_param_char => 'RECONCILE');
  ELSE
    dbms_ra_scheduler.fix_error (p_error_num  => dbms_ra.REP_SETUP_ERROR_NUM,
                                 p_db_key     => p_db_key,
                                 p_param_char => 'RECONCILE');
  END IF;
 
END replication_reconcile_int;
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE replication_reconcile (
                               db_unique_name          IN VARCHAR2 DEFAULT NULL,
                               replication_server_name IN VARCHAR2 DEFAULT NULL)
IS
  l_the             NUMBER;
  l_db_key          NUMBER := NULL;
  l_rep_server_key  NUMBER := NULL;
  l_server_key      NUMBER := NULL;
  l_cnt             NUMBER;
  l_obj_type        VARCHAR2(128);
  l_obj_name        VARCHAR2(128);
  c_db_unique_name  VARCHAR2(128);
  c_rep_server_name VARCHAR2(128);
  locked            BOOLEAN := FALSE;
 
--
--
  CURSOR prot_list IS
    select prot.prot_name, prot.prot_key from prot
      where prot.prot_key in
      (select prot_key from rep_server
       where status = 'A');
 
--
  CURSOR repserv_by_name_cursor(repsrvr_name IN VARCHAR2) IS
    select rs.rep_server_key, rs.prot_key, rs.server_key
      from rep_server rs, server s
      where s.rep_server_name = repsrvr_name
        and rs.server_key = s.server_key
        and rs.status = 'A';
 
--
  CURSOR repserv_by_dbs_prot(odb_db_key in NUMBER) IS
    select rs.rep_server_key, rs.server_key
      from rep_server rs, odb o, server s
      where o.db_key = odb_db_key
        and o.db_state is NULL
        and rs.prot_key = o.prot_key
        and s.server_key = rs.server_key
        and rs.status = 'A';
 
BEGIN
  am_tracei('reconcile db_unique_name=' || db_unique_name ||
            ', replication_server_name=' || replication_server_name);
 
  lock_api_int(DBMS_RA.LOCKAPI_MODIFY, 'replication_reconcile');
 
  locked := TRUE;
 
  dbms_ra_int.canonicalize(db_unique_name,
                            c_db_unique_name, 128);
  dbms_ra_int.canonicalize(replication_server_name,
                            c_rep_server_name, 128);
 
--
  IF c_db_unique_name IS NOT NULL THEN
    BEGIN
      SELECT db_key INTO l_db_key FROM node
        WHERE node.db_unique_name = c_db_unique_name;
    EXCEPTION
      WHEN NO_DATA_FOUND THEN
        l_obj_type := 'db unique name';
        l_obj_name := c_db_unique_name;
        RAISE DBMS_RA.OBJ_NOT_FOUND;
    END;
  END IF;
 
  l_the := dbms_ra_scheduler.add_to_task_history_table (
                task_type => dbms_ra_scheduler.TASK_API_REPLICATION_RECONCILE,
                param     => 'replication_reconcile' ||
                  b_p_i('db_unique_name', c_db_unique_name, p_first=>TRUE) ||
                  b_p_i('replication_server_name', c_rep_server_name,
                        p_last=>TRUE));
 
  IF c_db_unique_name IS NULL THEN
--
    IF c_rep_server_name IS NULL THEN
--
--
--
      FOR p IN prot_list LOOP
        am_tracei ('replication_reconcile (1): prot_key=' || p.prot_key);
        rep_rec_by_prot_int (p.prot_key);
      END LOOP;
 
    ELSE
--
--
--
      FOR r IN repserv_by_name_cursor(c_rep_server_name) LOOP
        am_tracei ('replication_reconcile (2): prot_key=' || r.prot_key);
        rep_rec_by_prot_int (r.prot_key);
      END LOOP;
    END IF;
 
  ELSE -- db_unique is not NULL - IE db name was specified
--
    IF c_rep_server_name IS NULL THEN
--
--
--
      am_tracei ('replication_reconcile (3b): l_db_key=' || l_db_key);
      FOR r IN repserv_by_dbs_prot(l_db_key) LOOP
        am_tracei ('replication_reconcile (3c): l_db_key=' || l_db_key ||
                   ', l_rep_server_key=' || r.rep_server_key);
        replication_reconcile_int (l_db_key, r.server_key);
      END LOOP;
    ELSE
--
--
--
       BEGIN
         am_tracei ('replication_reconcile (4b): rs_name=' ||
                    c_rep_server_name);
--
--
         SELECT rs.rep_server_key, rs.server_key
           INTO l_rep_server_key, l_server_key
           FROM rep_server rs, server s, odb o
           WHERE s.rep_server_name = c_rep_server_name
             AND s.server_key = rs.server_key
             AND rs.status = 'A'
             AND o.db_key = l_db_key
             AND o.db_state is NULL
             AND rs.prot_key = o.prot_key;
       EXCEPTION
         WHEN NO_DATA_FOUND THEN
--
--
           l_obj_type := 'rep server name';
           l_obj_name := c_rep_server_name;
           RAISE DBMS_RA.OBJ_NOT_FOUND;
       END;
       am_tracei ('replication_reconcile (4c): l_db_key=' || l_db_key ||
                  ', l_rep_server_key=' || l_rep_server_key ||
                  ', l_server_key=' || l_server_key);
       replication_reconcile_int (l_db_key, l_server_key);
    END IF;
  END IF;
 
  unlock_api_int(p_the_num=>l_the, p_results=>TRUE, p_docommit=>TRUE);
  locked := FALSE;
 
EXCEPTION
  WHEN DBMS_RA.OBJ_NOT_FOUND THEN
--
    IF locked THEN
      unlock_api_int(p_the_num=>l_the, p_results=>FALSE, p_docommit=>TRUE);
      locked := FALSE;
    END IF;
 
--
    IF l_obj_type IS NOT NULL THEN
      am_tracei ('replication_reconcile fail: ' || item_not_foundi(l_obj_name,
                                                         l_obj_type));
      sys.dbms_sys_error.raise_system_error(DBMS_RA.OBJ_NOT_FOUND_NUM,
                                            l_obj_name,
                                            l_obj_type,
                                            FALSE);
    ELSE
      RAISE;
    END IF;
  WHEN OTHERS THEN
    IF locked THEN
      unlock_api_int(p_the_num=>l_the, p_results=>FALSE, p_docommit=>TRUE);
      locked := FALSE;
    END IF;
    am_tracei ('replication_reconcile fail: sqlcode=' || sqlcode ||
               ', sqlerrm=' || SQLERRM);
    RAISE;
END replication_reconcile;
 
--
PROCEDURE replication_reconcile (protection_policy_name IN VARCHAR2)
IS
  l_the             NUMBER;
  l_cnt             NUMBER;
 
  l_obj_type        VARCHAR2(128);
  l_obj_name        VARCHAR2(128);
 
  l_prot_key        NUMBER := NULL;
  c_protection_policy_name   VARCHAR2(128);
  locked            BOOLEAN := FALSE;
 
BEGIN
  am_tracei('reconcile by prot prot_name=' || protection_policy_name);
 
  lock_api_int(DBMS_RA.LOCKAPI_MODIFY, 'replication_reconcile');
 
  locked := TRUE;
 
  dbms_ra_int.canonicalize(protection_policy_name,
                            c_protection_policy_name, 128);
 
  BEGIN
    SELECT prot_key INTO l_prot_key FROM prot
      WHERE prot.prot_name = c_protection_policy_name;
  EXCEPTION
    WHEN NO_DATA_FOUND THEN
      l_obj_type := 'protection policy name';
      l_obj_name := protection_policy_name;
      RAISE DBMS_RA.OBJ_NOT_FOUND;
  END;
 
  l_the := dbms_ra_scheduler.add_to_task_history_table (
                task_type => dbms_ra_scheduler.TASK_API_REPLICATION_RECONCILE,
                        param     => 'replication_reconcile' ||
                        b_p_i('protection_policy_name', protection_policy_name,
                               p_first=>TRUE, p_last=>TRUE));
 
  rep_rec_by_prot_int (l_prot_key);
 
  unlock_api_int(p_the_num=>l_the, p_results=>TRUE, p_docommit=>TRUE);
  locked := FALSE;
 
EXCEPTION
  WHEN DBMS_RA.OBJ_NOT_FOUND THEN
--
    IF locked THEN
      unlock_api_int(p_the_num=>l_the, p_results=>FALSE, p_docommit=>TRUE);
      locked := FALSE;
    END IF;
--
    IF l_obj_type IS NOT NULL THEN
      am_tracei ('replication_reconcile: ' || item_not_foundi(l_obj_name,
                                                         l_obj_type));
      sys.dbms_sys_error.raise_system_error(DBMS_RA.OBJ_NOT_FOUND_NUM,
                                            l_obj_name,
                                            l_obj_type,
                                            FALSE);
    ELSE
      RAISE;
    END IF;
  WHEN OTHERS THEN
    IF locked THEN
      unlock_api_int(p_the_num=>l_the, p_results=>FALSE, p_docommit=>TRUE);
      locked := FALSE;
    END IF;
    am_tracei ('replication_reconcile fail: sqlcode=' || sqlcode ||
               ', sqlerrm=' || SQLERRM);
    RAISE;
 
END replication_reconcile;
--
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE replicate_one_backup(bpkey IN NUMBER,
                               replication_server_name IN VARCHAR2 DEFAULT NULL)
IS
  l_db_key          NUMBER;
  l_rep_server_key  NUMBER := NULL;
  l_server_key      NUMBER := NULL;
  l_repcnt          NUMBER;
  l_obj_type        VARCHAR2(128);
  l_obj_name        VARCHAR2(128);
  c_rep_server_name  VARCHAR2(128);
BEGIN
 
  am_tracei ('replicate_one_backup: bp_key=' || bpkey ||
             ' ,replication_server_name=' || replication_server_name);
 
  dbms_ra_int.canonicalize(replication_server_name,
                           c_rep_server_name, 128);
 
--
--
 
--
--
--
 
--
--
--
  l_obj_type := 'replicate one backup piece';
  l_obj_name := 'bp_key=' || bpkey;
  SELECT db_key
    INTO l_db_key
    FROM bp
    WHERE bp_key=bp_key
      AND status = 'A'
      AND ba_access = 'L';
 
--
--
--
  IF replication_server_name IS NULL THEN
--
--
--
    SELECT count(*) INTO l_repcnt
      FROM odb o, rep_server rs
      WHERE o.prot_key = rs.prot_key
        AND o.db_key = l_db_key
        AND o.db_state is NULL
        AND rs.status = 'A';
    IF l_repcnt = 0 THEN
      l_obj_type := 'replication_server';
      l_obj_name := 'bp_key=' || bpkey;
      RAISE NO_DATA_FOUND;
    END IF;
  ELSE
    l_obj_type := 'replication_server';
    l_obj_name := 'bp_key=' || bpkey || ', rs_name=' || replication_server_name;
 
--
--
    SELECT rep_server_key, rs.server_key INTO l_rep_server_key, l_server_key
      FROM odb o, rep_server rs, server s
      WHERE o.prot_key = rs.prot_key
        AND o.db_key = l_db_key
        AND o.db_state is NULL
        AND rs.server_key = s.server_key
        AND s.rep_server_name = c_rep_server_name
        AND rs.status = 'A';
    l_repcnt := 1;
  END IF;
 
  IF l_repcnt > 0 THEN
    am_tracei ('replicate_one_backup: creating replication tasks db_key=' ||
               l_db_key || ', bp_key=' || bpkey || ', rep_server_key=' ||
               l_rep_server_key || ', server_key=' || l_server_key ||
               ', rep_cnt=' || l_repcnt);
    dbms_ra_scheduler.replicate_one_bp (p_db_key => l_db_key,
                                        p_bp_key => bpkey,
                                        p_server_key => l_server_key);
  END IF;
 
EXCEPTION
  WHEN NO_DATA_FOUND THEN
    am_tracei ('replicate_one_backup: ' || item_not_foundi(l_obj_name,
                                                           l_obj_type));
    sys.dbms_sys_error.raise_system_error(DBMS_RA.OBJ_NOT_FOUND_NUM,
                                          l_obj_name,
                                          l_obj_type,
                                          FALSE);
END;
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE replicate_backups_int (p_db_unique_name IN VARCHAR2,
                                 p_rep_serv_name IN VARCHAR2 DEFAULT NULL)
IS
  l_repsrv_key              NUMBER := NULL;
  l_prot_name               prot.prot_name%TYPE;
  l_prot_key                NUMBER := NULL;
  l_db_key                  NUMBER := NULL;
  l_server_key              NUMBER := NULL;
  l_obj_type                VARCHAR2(128);
  l_obj_name                VARCHAR2(128);
  l_cnt                     NUMBER;
  l_lib_key                 NUMBER;
  l_template_name           sbt_job_template.template_name%TYPE;
  l_backup_type             VARCHAR2(128);
  l_invalid_val             VARCHAR2(128);
  l_success                 BOOLEAN;
  l_exp_cnt                 NUMBER;
  l_num_rec                 NUMBER;
  l_pending_rep_setup       odb.pending_rep_setup%type := NULL;
  l_rep_atr_name            sbt_attr_set.attr_name%TYPE;
 
BEGIN
 
--
--
  BEGIN
    SELECT node.db_key, odb.prot_key
      INTO l_db_key, l_prot_key
      FROM node, odb
      WHERE node.db_unique_name = p_db_unique_name
        AND node.db_key=odb.db_key
        AND odb.db_state is NULL;
  EXCEPTION
    WHEN NO_DATA_FOUND THEN
      l_obj_type := 'db unique name';
      l_obj_name := p_db_unique_name;
      RAISE DBMS_RA.OBJ_NOT_FOUND;
  END;
 
--
--
--
  SELECT COUNT(*)
    INTO l_cnt
    FROM rep_server
    WHERE prot_key=l_prot_key
      AND status = 'A';
 
  IF (l_cnt = 0) THEN
    l_obj_type := 'replication server';
    l_obj_name := 'none found';
    RAISE DBMS_RA.OBJ_NOT_FOUND;
  END IF;
 
--
  IF p_rep_serv_name IS NOT NULL THEN
    l_obj_type := 'replication server';
    l_obj_name := p_rep_serv_name;
--
--
    SELECT rs.server_key INTO l_server_key
      FROM odb o, rep_server rs, server s
      WHERE o.prot_key = rs.prot_key
        AND o.db_key = l_db_key
        AND o.db_state is NULL
        AND s.rep_server_name = p_rep_serv_name
        AND rs.status = 'A';
  END IF;
 
  SELECT pending_rep_setup INTO l_pending_rep_setup FROM odb
    WHERE odb.db_key=l_db_key;
  IF l_pending_rep_setup = 'Y' THEN
    IF NOT dbms_ra_scheduler.check_do_pending_rep_setup(l_db_key) THEN
      am_tracei ('REPLICATE_BACKUPS: Unable to complete replication ' ||
                 'setup for database ' || dbms_ra_int.dbkey2name(l_db_key));
      sys.dbms_sys_error.raise_system_error(dbms_ra.REP_SETUP_ERROR_NUM,
                                            'complete_rep_setup',
                                            'USER_BACKUP_EXISTING',
                                            dbms_ra_int.dbkey2name(l_db_key),
                                            FALSE);
    ELSE
--
--
--
--
--
--
--
      am_tracei('REPLICATE_BACKUPS: Exit. pending_rep_setup=' ||
                l_pending_rep_setup);
      RETURN;
    END IF;
  END IF;
 
  IF (l_pending_rep_setup IS NULL) OR (l_pending_rep_setup <> 'N') THEN
    am_tracei('REPLICATE_BACKUPS: Rep server not yet setup');
    RETURN;
  END IF;
 
--
  SELECT prot_name
    INTO l_prot_name
    FROM prot
    WHERE prot_key = l_prot_key;
 
--
  FOR s IN
    (SELECT server.server_key, rep_server_name
     FROM rep_server, server, odb
     WHERE rep_server.prot_key=l_prot_key
     AND rep_server.status = 'A'
     AND server.server_key = rep_server.server_key
     AND odb.db_key = l_db_key
     AND odb.db_state is NULL
     AND odb.prot_key = rep_server.prot_key)
  LOOP
    BEGIN
--
      IF p_rep_serv_name IS NOT NULL THEN
        IF upper(s.rep_server_name) <> upper(p_rep_serv_name) THEN
          CONTINUE;
        END IF;
      END IF;
 
--
      SELECT lib_key INTO l_lib_key
        FROM sbt_lib_desc
        WHERE server_key = s.server_key;
 
--
      l_success := dbms_ra_scheduler.reconcile_db (
                                     p_db_key          => l_db_key,
                                     p_server_key      => s.server_key,
                                     p_only_active     => FALSE,
                                     p_force_reconcile => TRUE,
                                     rec_cnt           => l_num_rec);
      IF NOT l_success OR l_num_rec <> 1 THEN
        dbms_ra_scheduler.log_error(p_errno => dbms_ra.REP_SETUP_ERROR_NUM,
                          p_db_key  => l_db_key,
                          p_param1  => 'user_backup_existing',
                          p_param2  => s.rep_server_name,
                          p_param3  => p_db_unique_name,
                          P_keep_stack => FALSE,
                          p_component =>'REPLICATION_RECONCILE',
                          p_severity => dbms_ra_scheduler.SEVERITY_ERROR,
                          p_param_char => 'RECONCILE');
      ELSE
--
--
--
        dbms_ra_scheduler.fix_error(p_error_num  => dbms_ra.REP_SETUP_ERROR_NUM,
                                    p_db_key     => l_db_key,
                                    p_param_char => 'RECONCILE');
 
--
--
 
--
        dbms_ra_scheduler.queue_set_reconcile_timer (l_db_key);
 
--
--
        l_template_name := dbms_ra_int.build_rep_tpl_name (
                                             rep_srv_name => s.rep_server_name,
                                             db_key       => l_db_key,
                                             prot_key     => l_prot_key);
 
--
--
--
--
        BEGIN
          l_rep_atr_name := dbms_ra_int.build_rep_atr_name(s.rep_server_name);
          dbms_ra_int.create_sbt_job_template_int(
                                    template_name   => l_template_name,
                                    db_unique_name  => p_db_unique_name,
                                    attr_name       => l_rep_atr_name,
                                    backup_type     => 'ALL',
                                    do_commit       => TRUE);
        EXCEPTION
          WHEN DBMS_RA.DUP_NAME THEN
--
            NULL;
        END;
 
        dbms_ra_scheduler.replicate_existing_backups(
                                            p_template_name => l_template_name);
 
      END IF;
 
    EXCEPTION
      WHEN OTHERS THEN
--
--
      UPDATE sbt_lib_desc
      SET status =
      (CASE WHEN failure_cnt + 1 <
            dbms_ra_scheduler.s_max_sbt_failures THEN 'R'
              ELSE 'E' END),
               failure_cnt = failure_cnt + 1
         WHERE status = 'R'
           AND lib_key = l_lib_key;
         COMMIT;
         RAISE;
    END;
  END LOOP;
 
EXCEPTION
  WHEN DBMS_RA.OBJ_NOT_FOUND THEN
--
    IF l_obj_type IS NOT NULL THEN
      am_tracei ('replicate_backups: ' || item_not_foundi(l_obj_name,
                                                        l_obj_type));
      sys.dbms_sys_error.raise_system_error(DBMS_RA.OBJ_NOT_FOUND_NUM,
                                            l_obj_name,
                                            l_obj_type,
                                            FALSE);
    ELSE
      RAISE;
    END IF;
 
  WHEN DBMS_RA.MISSING_INIT_REP_TYPE THEN
--
    am_tracei ('replicate_backups: required intial_replication ' ||
              'parameter not defined');
    RAISE;
 
 
  WHEN DBMS_RA.INVALID_VAL THEN
    IF l_invalid_val IS NOT NULL THEN
      am_tracei ('replicate_backups: Invalid value for initial_replication - '
                || l_invalid_val);
      sys.dbms_sys_error.raise_system_error(DBMS_RA.INVALID_VAL_NUM,
                                            l_invalid_val,
                                            FALSE);
    ELSE
      RAISE;
    END IF;
 
  WHEN OTHERS THEN
    ROLLBACK;
    am_tracei ('replicate_backups exception: ' ||
              ' db_unique_name:'    || p_db_unique_name ||
              ', err:' || SQLERRM);
    RAISE;
 
END replicate_backups_int;
--
PROCEDURE replicate_backups (db_unique_name         IN VARCHAR2,
                             replication_server_name IN VARCHAR2 DEFAULT NULL)
IS
  l_the                     NUMBER;
 
BEGIN
  lock_api_int(DBMS_RA.LOCKAPI_MODIFY, 'replicate_backups');
 
  l_the := dbms_ra_scheduler.add_to_task_history_table (
                task_type => dbms_ra_scheduler.TASK_API_REPLICATE_EXISTING,
                param     => 'replicate_backups' ||
                  b_p_i('db_unique_name', db_unique_name, p_first=>TRUE,
                     p_last=>TRUE));
 
  replicate_backups_int (upper(db_unique_name), upper(replication_server_name));
 
  unlock_api_int(p_the_num=>l_the, p_results=>TRUE, p_docommit=>TRUE);
 
EXCEPTION
  WHEN OTHERS THEN
    rollback;
    unlock_api_int(p_the_num=>l_the, p_results=>FALSE, p_docommit=>TRUE);
    RAISE;
END replicate_backups;
--
 
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE verify_reserved_space (p_slkey IN NUMBER,
                                 p_newdb IN BOOLEAN DEFAULT FALSE) IS
  l_sl_space      NUMBER;
  l_curr_res      NUMBER;
  l_future_res    NUMBER;
  l_bigdb         NUMBER;
  l_count         NUMBER;
  l_nospace       BOOLEAN;
  l_moving_space  NUMBER;
  l_padding_space NUMBER := 20 * 1024 * 1024; /* retain some unclaimed space */
BEGIN
--
--
--
--
--
  IF is_repair_needed THEN
    am_tracei('verify_reserved_space:  Repair is needed');
    RETURN;
  END IF;
 
--
  SELECT sl_space INTO l_sl_space
    FROM sl
    WHERE sl_key = p_slkey;
  SELECT l_sl_space - nvl(VALUE, 0) INTO l_sl_space
    FROM config WHERE name = '_purging_reserve';
 
--
  IF p_newdb THEN
    SELECT NVL(MAX(d.base_reserved_space), 0) INTO l_bigdb
      FROM prot p, odb d
      WHERE (d.prot_key = p.prot_key OR
             d.future_prot_key = p.prot_key)
        AND (d.sl_key = p_slkey OR p.sl_key = p_slkey)
        AND d.move_phase IS NOT NULL;
 
--
--
    SELECT (NVL(TO_NUMBER(MIN(VALUE)), 2) * l_bigdb) - l_bigdb
      INTO l_padding_space
      FROM config WHERE name = '_trim_factor';
  END IF;
 
--
--
--
  SELECT SUM(reserved_space) INTO l_future_res
    FROM (SELECT d.base_reserved_space reserved_space
          FROM prot p, odb d
          WHERE p.sl_key = p_slkey
            AND d.future_prot_key = p.prot_key
         UNION ALL
          SELECT d.reserved_space
          FROM prot p, unreg_database d
          WHERE p.sl_key = p_slkey
            AND d.prot_key = p.prot_key);
 
--
  SELECT SUM(reserved_space) INTO l_curr_res
    FROM (SELECT reserved_space
          FROM odb
          WHERE sl_key = p_slkey
         UNION ALL
          SELECT reserved_space
          FROM prot p, unreg_database d
          WHERE p.sl_key = p_slkey
            AND d.prot_key = p.prot_key
         UNION ALL
          SELECT dbsl_used_space reserved_space
          FROM dbsl
          WHERE sl_key = p_slkey
            AND sl_key NOT IN
               (SELECT sl_key FROM odb
                WHERE move_phase > dbms_ra_scheduler.MOVE_PHASE_PEND));
 
--
  IF (l_sl_space - l_padding_space) < l_future_res
  OR (l_sl_space - l_padding_space) < l_curr_res
  THEN
    ROLLBACK;
    RAISE DBMS_RA.SPACE_QUOTA_VIOLATION;
  END IF;
 
--
--
--
--
  IF NOT p_newdb THEN
--
--
    SELECT MAX(base_reserved_space) INTO l_future_res
      FROM odb d, prot p
      WHERE p.prot_key = d.future_prot_key
        AND p.sl_key = p_slkey
        AND d.sl_key <> p.sl_key
        AND d.move_phase > dbms_ra_scheduler.MOVE_PHASE_PEND;
 
    IF l_future_res IS NOT NULL THEN  /* check current reservations */
--
--
      SELECT NVL(SUM(reserved_space), 0) INTO l_curr_res
        FROM (SELECT reserved_space reserved_space
              FROM odb d
              WHERE d.sl_key = p_slkey
             UNION ALL
              SELECT d.reserved_space
              FROM prot p, unreg_database d
              WHERE p.sl_key = p_slkey
                AND d.prot_key = p.prot_key);
 
      IF (l_sl_space - l_padding_space) < (l_curr_res + l_future_res) THEN
        ROLLBACK;
        RAISE DBMS_RA.SPACE_QUOTA_VIOLATION;
      END IF;
    END IF;
  END IF;
 
--
--
  FOR x IN (SELECT db_key, used_space, base_reserved_space,
                   not_taped, not_taped_state
            FROM odb d, prot p
            WHERE d.prot_key = p.prot_key
              AND d.not_taped > d.base_reserved_space
              AND p.prot_disk_cache = 'YES')
  LOOP
--
--
--
    CASE
      WHEN x.not_taped_state = 'V' THEN /* Valid */
        l_nospace := (x.base_reserved_space < x.not_taped);
      WHEN x.not_taped_state = 'N' THEN /* No Tape */
        l_nospace := (x.base_reserved_space < x.used_space);
      WHEN x.not_taped_state IS NULL THEN /* feature Disabled */
        l_nospace := FALSE;
      WHEN x.not_taped_state = 'C' THEN /* Computing new value */
        l_nospace := FALSE;
      WHEN x.not_taped_state = 'B' THEN /* Broken, computed val is too high */
--
        UPDATE odb SET not_taped_state = 'C' WHERE db_key = x.db_key;
        l_nospace := FALSE;
      WHEN x.not_taped_state = 'I' THEN /* Invalid value */
        IF x.base_reserved_space < x.not_taped THEN
--
          UPDATE odb SET not_taped_state = 'C' WHERE db_key = x.db_key;
        END IF;
 
        l_nospace := FALSE;
      ELSE
        sys.dbms_sys_error.raise_system_error(
                          DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM,
                          'Bad not_taped_state value: ' || x.not_taped_state,
                          FALSE);
    END CASE;
 
    IF l_nospace THEN
      ROLLBACK;
      RAISE DBMS_RA.SPACE_QUOTA_VIOLATION;
    END IF;
  END LOOP;
END;
--
 
--
--
--
--
--
--
--
--
FUNCTION is_repair_needed RETURN BOOLEAN
IS
  l_current_incarn  NUMBER;
  l_last_incarn     NUMBER;
BEGIN
  SELECT incarnation# INTO l_current_incarn
    FROM sys.v_$database_incarnation
    WHERE status='CURRENT';
 
  SELECT NVL(MIN(value), l_current_incarn) INTO l_last_incarn
    FROM config
    WHERE name = '_last_incarnation';
 
  IF l_current_incarn <> l_last_incarn THEN
    am_tracei ('is_repair_needed: Old incarn: ' || l_last_incarn ||
                              '; New incarn: ' || l_current_incarn);
    RETURN TRUE;
  END IF;
  RETURN FALSE;
END;
--
 
--
--
--
--
--
--
--
--
--
FUNCTION pparmi (p_value IN VARCHAR2) RETURN VARCHAR2
IS
BEGIN
  IF p_value IS NULL THEN
    RETURN 'NULL';
  ELSE
    RETURN '''' || p_value || '''';
  END IF;
END pparmi;
 
FUNCTION pparmi (p_value IN NUMBER) RETURN VARCHAR2
IS
BEGIN
  RETURN pparmi(TO_CHAR(p_value));
END pparmi;
 
FUNCTION pparmi (p_value IN BOOLEAN) RETURN VARCHAR2
IS
BEGIN
  IF p_value IS NULL THEN
    RETURN 'NULL';
  ELSIF p_value THEN
    RETURN 'TRUE';
  ELSE
    RETURN 'FALSE';
  END IF;
END pparmi;
--
 
--
--
--
--
--
--
--
--
--
PROCEDURE wait_for_job (p_jobname VARCHAR2, p_poll_time NUMBER) IS
KBRSTRC_STALL  CONSTANT NUMBER := TO_NUMBER('2000000', 'XXXXXXXX');
l_debug_flags           NUMBER;
l_error_count           NUMBER;
 
BEGIN
  LOOP
--
    dbms_ra_scheduler.make_amjobs(p_jobname);
    EXIT WHEN dbms_ra_scheduler.s_amjobs.COUNT = 0;
 
--
    SELECT NVL(MIN(value),0) INTO l_debug_flags
      FROM config
      WHERE name = '_debug_flags';
 
    IF BITAND (l_debug_flags, KBRSTRC_STALL) <> 0 THEN
      SELECT COUNT(*) INTO l_error_count
        FROM error_log
       WHERE severity >= DBMS_RA_SCHEDULER.SEVERITY_ERROR
         AND status = 'ACTIVE'
         AND ROWNUM = 1;
 
      am_tracei('wait_for_job: ' || p_jobname ||
                ' error_count =' || l_error_count);
      EXIT WHEN l_error_count > 0;
    END IF;
 
    dbms_lock.sleep(p_poll_time);
  END LOOP;
 
END wait_for_job;
--
 
--
--
FUNCTION sbt_job_backup_type_to_num(backup_type IN VARCHAR2) RETURN NUMBER
IS
   l_bck_type    NUMBER := 0;
 
   CURSOR backup_type_c(btype IN VARCHAR2) IS
      WITH table_to_parse as
         (select btype str from dual)
      SELECT DISTINCT upper(ltrim(rtrim(new_str))) new_str
        FROM table_to_parse,
             xmltable('r/c' passing xmltype('<r><c>' ||
             replace(str,',','</c><c>') || '</c></r>')
             columns new_str varchar2(512) path '.');
   btypeRec backup_type_c%ROWTYPE;
BEGIN
   FOR btypeRec IN backup_type_c(backup_type) LOOP
      CASE btypeRec.new_str
         WHEN 'ALL' THEN
            l_bck_type := l_bck_type + 1;
         WHEN 'FULL' THEN
            l_bck_type := l_bck_type + 2;
         WHEN 'INCR' THEN
            l_bck_type := l_bck_type + 4;
         WHEN 'ARCH' THEN
            l_bck_type := l_bck_type + 8;
      ELSE
         sys.dbms_sys_error.raise_system_error
            (DBMS_RA.INVALID_PARAM_NUM, btyperec.new_str, 'backup type', FALSE);
      END CASE;
   END LOOP;
 
   IF (l_bck_type = 0) THEN
      sys.dbms_sys_error.raise_system_error
         (DBMS_RA.INVALID_PARAM_NUM, '', 'backup type', FALSE);
   END IF;
 
--
   IF (bitand(l_bck_type, 1) = 1) THEN -- all
      l_bck_type := 1;
   ELSIF (bitand(l_bck_type, 2 + 4 + 8) = 14) THEN -- same as all
      l_bck_type := 1;
   END IF;
 
   RETURN l_bck_type;
END sbt_job_backup_type_to_num;
   
--
PROCEDURE create_sbt_job_template_int(
   template_name       IN VARCHAR2,
   prot_name           IN VARCHAR2,
   attr_name           IN VARCHAR2,
   backup_type         IN VARCHAR2,
   full_template_name  IN VARCHAR2       DEFAULT NULL,
   from_tag            IN VARCHAR2       DEFAULT NULL,
   priority            IN NUMBER         DEFAULT 100, -- dbms_ra.SBT_PRIORITY_MEDIUM
   copies              IN NUMBER         DEFAULT 1,
   window              IN DSINTERVAL_UNCONSTRAINED DEFAULT NULL,
   do_commit           IN BOOLEAN DEFAULT TRUE)
IS
   l_attr_key             NUMBER;
   l_prot_key             NUMBER;
   l_bck_type             NUMBER;
   l_invalid_val          VARCHAR(128);
   l_full_template_key    NUMBER := NULL;
   l_template_key         NUMBER;
BEGIN
   IF (copies IS NULL OR copies < 1 OR copies > 4) THEN
     am_tracei('create_sbt_job w/ prot policy: num copies invalid: ' ||
                                              pparmi(copies));
     sys.dbms_sys_error.raise_system_error(DBMS_RA.BAD_NUM_COPIES_NUM,
                                           pparmi(copies),
                                           FALSE);
   END IF;
 
--
   SELECT attr.attr_key INTO l_attr_key
     FROM sbt_attr_set attr
    WHERE attr.attr_name = create_sbt_job_template_int.attr_name;
 
--
   SELECT prot.prot_key INTO l_prot_key
     FROM prot
    WHERE prot.prot_name = create_sbt_job_template_int.prot_name;
 
   l_bck_type    := sbt_job_backup_type_to_num(backup_type);
   
   l_template_key := rman_seq.nextval;
 
--
--
--
   IF ((bitand(l_bck_type, 1) <> 0) OR (bitand(l_bck_type, 2) <> 0)) THEN
     IF ((full_template_name IS NOT NULL) AND 
         (full_template_name <> template_name)) THEN
       l_invalid_val := 'full_template_name should be same as template_name';
       RAISE DBMS_RA.INVALID_VAL;
     ELSE
       l_full_template_key := l_template_key;
     END IF;
   ELSIF (full_template_name IS NULL) THEN
     SELECT job.template_key INTO l_full_template_key
       FROM sbt_job_template job
      WHERE job.prot_key = l_prot_key
       AND  (create_sbt_job_template_int.from_tag IS NULL OR 
             job.from_tag = create_sbt_job_template_int.from_tag)
       AND (bitand(job.bck_type,1) = 1 OR bitand(job.bck_type,2) = 2);
   ELSE
--
--
--
     SELECT job.template_key INTO l_full_template_key
       FROM sbt_job_template job
      WHERE job.template_name = create_sbt_job_template_int.full_template_name
        AND job.prot_key = l_prot_key
        AND (bitand(job.bck_type,1) = 1 OR bitand(job.bck_type,2) = 2);
   END IF;
 
--
   INSERT INTO sbt_job_template job
      (template_key, template_name, full_template_key, prot_key, db_key,
       bck_type, from_tag, priority, attr_key, copies, window)
   VALUES
      (l_template_key, template_name, l_full_template_key, l_prot_key, NULL, 
       l_bck_type, from_tag, priority, l_attr_key, copies, window);
   
   IF do_commit THEN 
--
      COMMIT;
   END IF;
      
EXCEPTION
   WHEN DUP_VAL_ON_INDEX THEN
     sys.dbms_sys_error.raise_system_error
        (DBMS_RA.DUP_NAME_NUM, template_name, 'Sbt Job Template', FALSE);
 
   WHEN DBMS_RA.INVALID_VAL THEN
     IF l_invalid_val IS NOT NULL THEN
      am_tracei('create_sbt_job_template_int raising invalid value: ' ||
        l_invalid_val);
        sys.dbms_sys_error.raise_system_error
       (DBMS_RA.INVALID_VAL_NUM, l_invalid_val, FALSE);
     ELSE
       RAISE;
     END IF;
 
   WHEN NO_DATA_FOUND THEN
     IF (l_attr_key IS NULL) THEN
         am_tracei('create_sbt_job w/prot policy: ' ||
                     item_not_foundi(attr_name, 'sbt attribute set'));
         sys.dbms_sys_error.raise_system_error
            (DBMS_RA.OBJ_NOT_FOUND_NUM, attr_name, 'sbt attribute set', FALSE);
      ELSIF (l_prot_key IS NULL) THEN
         am_tracei('create_sbt_job w/prot policy: ' ||
                     item_not_foundi(prot_name, 'protection policy'));
         sys.dbms_sys_error.raise_system_error
            (DBMS_RA.OBJ_NOT_FOUND_NUM, prot_name, 'protection policy', FALSE);
      ELSIF (full_template_name IS NULL) THEN
         sys.dbms_sys_error.raise_system_error
          (DBMS_RA.OBJ_NOT_FOUND_NUM, template_name,'full template name',
           FALSE);
      ELSE
         am_tracei('create_sbt_job w/prot policy: ' ||
                     item_not_foundi(full_template_name, 'full template name'));
         sys.dbms_sys_error.raise_system_error
           (DBMS_RA.OBJ_NOT_FOUND_NUM, full_template_name,'full template name',
            FALSE);
      END IF;
 
   WHEN TOO_MANY_ROWS THEN
     sys.dbms_sys_error.raise_system_error
     (DBMS_RA.OBJ_NOT_FOUND_NUM, template_name, 'full template name',
      FALSE);
 
END create_sbt_job_template_int;
 
 
 
--
PROCEDURE create_sbt_job_template_int(
   template_name       IN VARCHAR2,
   db_unique_name      IN VARCHAR2,
   attr_name           IN VARCHAR2,
   backup_type         IN VARCHAR2,
   full_template_name  IN VARCHAR2   DEFAULT NULL,
   from_tag            IN VARCHAR2   DEFAULT NULL,
   priority            IN NUMBER     DEFAULT 100, -- dbms_ra.SBT_PRIORITY_MEDIUM
   copies              IN NUMBER     DEFAULT 1,
   window              IN DSINTERVAL_UNCONSTRAINED DEFAULT NULL,
   do_commit           IN BOOLEAN DEFAULT TRUE)
IS
   l_attr_key       NUMBER;
   l_db_key         NUMBER;
   l_bck_type       NUMBER;
   l_invalid_val    VARCHAR(128);
   l_full_template_key       NUMBER := NULL;
   l_template_key   NUMBER;
BEGIN
   IF (copies IS NULL OR copies < 1 OR copies > 4) THEN
     am_tracei('create_sbt_job: num copies invalid: ' || pparmi(copies));
     sys.dbms_sys_error.raise_system_error(DBMS_RA.BAD_NUM_COPIES_NUM,
                                           pparmi(copies),
                                           FALSE);
   END IF;
   
--
   SELECT attr.attr_key INTO l_attr_key
     FROM sbt_attr_set attr
    WHERE attr.attr_name = create_sbt_job_template_int.attr_name;
 
--
   SELECT db_key INTO l_db_key FROM node
     WHERE node.db_unique_name = create_sbt_job_template_int.db_unique_name
--
--
       AND NOT EXISTS (SELECT db_state
                         FROM odb
                        WHERE odb.db_key = node.db_key
                          AND db_state IS NOT NULL);
 
   l_bck_type    := sbt_job_backup_type_to_num(backup_type);
   
   l_template_key := rman_seq.nextval;
 
--
--
--
   IF ((bitand(l_bck_type, 1) <> 0) OR (bitand(l_bck_type, 2) <> 0)) THEN
     IF ((full_template_name IS NOT NULL) AND
         (full_template_name <> template_name)) THEN
       l_invalid_val := 'full_template_name should be same as template_name';
       RAISE DBMS_RA.INVALID_VAL;
     ELSE
       l_full_template_key := l_template_key;
     END IF;
   ELSIF (full_template_name IS NULL) THEN
--
     SELECT job.template_key INTO l_full_template_key
       FROM sbt_job_template job
      WHERE job.db_key = l_db_key
       AND  (create_sbt_job_template_int.from_tag IS NULL OR
             job.from_tag = create_sbt_job_template_int.from_tag)
       AND (bitand(job.bck_type,1) = 1 OR bitand(job.bck_type,2) = 2);
   ELSE
--
--
--
     SELECT job.template_key INTO l_full_template_key
       FROM sbt_job_template job
      WHERE job.template_name = create_sbt_job_template_int.full_template_name
        AND job.db_key = l_db_key
        AND (bitand(bck_type,1) = 1 OR bitand(bck_type,2) = 2);
   END IF;
 
--
   INSERT INTO sbt_job_template job
      (template_key, template_name, full_template_key, prot_key, db_key, 
       bck_type, from_tag, priority, attr_key, copies, window)
   VALUES
      (l_template_key, template_name, l_full_template_key, NULL, l_db_key, 
       l_bck_type, from_tag, priority, l_attr_key, copies, window);
   
   IF do_commit THEN 
--
      COMMIT;
   END IF;
      
EXCEPTION
 
   WHEN DUP_VAL_ON_INDEX THEN
     sys.dbms_sys_error.raise_system_error
        (DBMS_RA.DUP_NAME_NUM, template_name, 'Sbt Job Template', FALSE);
 
   WHEN DBMS_RA.INVALID_VAL THEN
     IF l_invalid_val IS NOT NULL THEN
      am_tracei('create_sbt_job_template_int raising invalid value: ' ||
        l_invalid_val);
        sys.dbms_sys_error.raise_system_error
       (DBMS_RA.INVALID_VAL_NUM, l_invalid_val, FALSE);
     ELSE
       RAISE;
     END IF;
 
   WHEN NO_DATA_FOUND THEN
      IF (l_attr_key IS NULL) THEN
         am_tracei('create_sbt_job w/db name: ' ||
                     item_not_foundi(attr_name, 'sbt attribute set'));
         sys.dbms_sys_error.raise_system_error
            (DBMS_RA.OBJ_NOT_FOUND_NUM, attr_name, 'sbt attribute set', FALSE);
      ELSIF (l_db_key IS NULL) THEN
         am_tracei('create_sbt_job w/db name: ' ||
                     item_not_foundi(db_unique_name, 'db unique name'));
         sys.dbms_sys_error.raise_system_error
            (DBMS_RA.OBJ_NOT_FOUND_NUM, db_unique_name, 'db unique name',FALSE);
      ELSIF (full_template_name IS NULL) THEN
         sys.dbms_sys_error.raise_system_error
          (DBMS_RA.OBJ_NOT_FOUND_NUM, template_name,'full template name',
           FALSE);
      ELSE
         am_tracei('create_sbt_job w/prot policy: ' ||
                     item_not_foundi(full_template_name, 'full template name'));
         sys.dbms_sys_error.raise_system_error
           (DBMS_RA.OBJ_NOT_FOUND_NUM, full_template_name,'full template name',
            FALSE);
      END IF;
 
   WHEN TOO_MANY_ROWS THEN
     sys.dbms_sys_error.raise_system_error
     (DBMS_RA.OBJ_NOT_FOUND_NUM, template_name, 'full template name', FALSE);
 
END create_sbt_job_template_int;
 
 
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE testTask(taskid   IN NUMBER DEFAULT NULL,
                   tasktype IN NUMBER DEFAULT NULL,
                   num1     IN NUMBER DEFAULT NULL,
                   num2     IN NUMBER DEFAULT NULL,
                   num3     IN NUMBER DEFAULT NULL,
                   char1    IN VARCHAR2 DEFAULT NULL,
                   char2    IN VARCHAR2 DEFAULT NULL,
                   param    IN VARCHAR2 DEFAULT NULL,
                   slkey    IN NUMBER DEFAULT NULL,
                   dbkey    IN NUMBER DEFAULT NULL,
                   settrace IN NUMBER DEFAULT NULL,
                   newsession IN BOOLEAN DEFAULT FALSE)
IS
  l_the             NUMBER;
BEGIN
  l_the := dbms_ra_scheduler.add_to_task_history_table (
      task_type => dbms_ra_scheduler.TASK_API_TESTTASK,
      param     => 'testtask' ||
        b_p_i('taskid', taskid, p_first=>TRUE) ||
        b_p_i('tasktype', tasktype) ||
        b_p_i('num1', num1) ||
        b_p_i('num2', num2) ||
        b_p_i('num3', num3) ||
        b_p_i('char1', char1) ||
        b_p_i('char2', char2) ||
        b_p_i('param', param) ||
        b_p_i('slkey', slkey) ||
        b_p_i('dbkey', dbkey) ||
        b_p_i('settrace', settrace) ||
        b_p_i('newsession', newsession, p_last=>TRUE));
 
  dbms_ra_scheduler.testtask(
                  p_taskid => taskid
                , p_tasktype => tasktype
                , p_num1 => num1
                , p_num2 => num2
                , p_num3 => num3
                , p_char1 => char1
                , p_char2 => char2
                , p_param => param
                , p_slkey => slkey
                , p_dbkey => dbkey
                , p_settrace => settrace
                , p_newsession => newsession);
 
  unlock_api_int(p_the_num=>l_the, p_results=>TRUE, p_docommit=>TRUE);
EXCEPTION
  WHEN OTHERS THEN
    unlock_api_int(p_the_num=>l_the, p_results=>FALSE, p_docommit=>TRUE);
    RAISE;
END;
--
 
 
--
--
--
--
--
--
--
--
--
PROCEDURE killTask(taskid   IN NUMBER)
IS
l_rowcount NUMBER;
BEGIN
--
  SYS.KBRSI_ICD.RSSCHEDLOCK (waitforwork => 0);
 
--
  UPDATE task
     SET state = DBMS_RA_SCHEDULER.STATE_CANCEL
   WHERE task_id = taskid
     AND state NOT IN (DBMS_RA_SCHEDULER.STATE_RUNNING, 
                       DBMS_RA_SCHEDULER.STATE_CANCELING);
  l_rowcount := SQL%ROWCOUNT;
  COMMIT;
 
  IF l_rowcount = 0 THEN
    sys.dbms_sys_error.raise_system_error(
                          DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM,
                          'Task ' || taskid ||
                                ' is either running or no longer exists',
                          FALSE);
  END IF;
 
--
  SYS.KBRSI_ICD.RSSCHEDUNLOCK;
 
EXCEPTION
  WHEN OTHERS THEN
--
    SYS.KBRSI_ICD.RSSCHEDUNLOCK;
    RAISE;  
END;
--
 
 
--
--
--
--
--
--
PROCEDURE tracing_on
IS
BEGIN
--
--
  dbms_ra_scheduler.load_config;
 
--
  sys.kbrsi_icd.rsSetTrace(0,1);
 
--
--
--
--
END tracing_on;
--
 
--
--
--
--
--
--
--
--
--
--
PROCEDURE validate_bp(bpkey IN NUMBER)
IS
  l_dbkey  NUMBER;
  l_vbkey  NUMBER;
BEGIN
--
  SELECT db_key, vb_key INTO l_dbkey, l_vbkey
    FROM bp
    WHERE bp_key = bpkey;
 
--
  tracing_on;
 
--
  IF l_vbkey IS NULL THEN
--
    dbms_ra_int.validateBackupPiece(l_dbkey, bpkey);
  ELSE
--
    sys.kbrsi_icd.validateTask(bpkey => bpkey);
  END IF;
 
EXCEPTION
  WHEN no_data_found THEN
    RAISE dbms_ra_scheduler.E_BACKUP_NOT_FOUND;
END validate_bp;
--
 
END dbms_ra_int;
>>>
 
define prvtrsjs_plb
<<<
CREATE OR REPLACE PACKAGE BODY dbms_ra_scheduler AS
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
 
/*-------------------------*
 * Package State Variables *
 *-------------------------*/
s_debug_flags         NUMBER  := NULL;
s_debug_error         NUMBER  := 1;
s_trace_file_days     NUMBER;
s_trace_file_open     DATE := SYSDATE-365;
s_tracing_on          BOOLEAN := FALSE;
s_perf_on             BOOLEAN := FALSE;
s_safe_mode           BOOLEAN := FALSE;
 
s_ba_session_id       NUMBER := NULL;   -- id for this scheduler
s_current_sid         NUMBER := NULL;   -- sid of this scheduler session
s_config_time         TIMESTAMP WITH TIME ZONE;  -- Time config vars were set
s_init_done           BOOLEAN := FALSE; -- true if packages vars initialized
s_inst_name           VARCHAR2(32) := sys_context('USERENV', 'INSTANCE_NAME');
--
s_timer_process_instance                -- for timer processes, the instance
                      NUMBER := NULL;   -- upon which they are running
s_libkey              NUMBER := NULL;   -- device type allocated in this
--
s_enable_dup          NUMBER := 1;      -- When space runs out only normal
--
--
s_next_dead_scheduler_check TIMESTAMP WITH TIME ZONE := SYSTIMESTAMP;
--
--
s_resource_wait_timeout NUMBER := 1;
--
--
--
s_resource_wait_active  BOOLEAN := FALSE;
s_resource_wait_last_alter  TIMESTAMP WITH TIME ZONE;
--
--
s_resource_wait_relax_rate NUMBER;   -- Multiplier for resource_wait_task_limit
--
--
s_optimize_space_limit NUMBER;       -- Fraction of reserved space that can be
--
s_setup_next_reconcile  BOOLEAN := TRUE;
s_interrupt_max NUMBER;              -- # of interrupts of regular task 
--
s_busy_interrupt_max NUMBER;         -- # of interrupts of busywork task
--
s_ordering_wait_timeout NUMBER;      -- # of days until we warn about
--
 
--
s_pool_tablespace  user_tablespaces.tablespace_name%TYPE;
 
 
--
s_tasktype2name DBMS_SQL.VARCHAR2A;
 
--
s_c2t_optimization NUMBER := 1;
s_baseline_cap     NUMBER := 0;
 
--
--
--
  PROCEDURE wait_for_repair (p_sl_key IN NUMBER,
                             p_db_key IN NUMBER);
  PROCEDURE exec_timer_storage_maintenance;
  PROCEDURE exec_timer_task_maintenance;
  PROCEDURE verify_timer_tasks;
  PROCEDURE timer_task_upsert    (p_type IN NUMBER, 
                                  p_interval IN DSINTERVAL_UNCONSTRAINED);
  PROCEDURE cleanup_dead_schedulers (p_restart BOOLEAN);
  PROCEDURE execute_quiesce;
  PROCEDURE execute_spawn_sbt(p_task_rec IN OUT NOCOPY task%ROWTYPE);
  PROCEDURE execute_restore      (p_task_rec IN OUT NOCOPY task%ROWTYPE);
  PROCEDURE execute_backup_arch  (p_task_rec IN OUT NOCOPY task%ROWTYPE);
  PROCEDURE execute_inc_arch (p_task_rec IN OUT NOCOPY task%ROWTYPE);
  PROCEDURE execute_index_backup (p_task_rec IN OUT NOCOPY task%ROWTYPE);
  PROCEDURE execute_newdfkey     (p_task_rec IN OUT NOCOPY task%ROWTYPE);
  PROCEDURE release_ordering_wait (p_dbkey IN NUMBER);
  PROCEDURE execute_deferred_delete(p_task_rec IN OUT NOCOPY task%ROWTYPE);
  PROCEDURE execute_gcopy_compute(p_task_rec IN OUT NOCOPY task%ROWTYPE);
  PROCEDURE execute_purge        (p_task_rec IN OUT NOCOPY task%ROWTYPE);
  PROCEDURE execute_poll         (p_task_rec IN OUT NOCOPY task%ROWTYPE);
  PROCEDURE execute_rm_incomplete_files (sbtonly IN BOOLEAN DEFAULT FALSE);
  PROCEDURE execute_purge_df     (p_task_rec IN OUT NOCOPY task%ROWTYPE);
  PROCEDURE execute_purge_dup_df (p_task_rec IN OUT NOCOPY task%ROWTYPE);
  PROCEDURE execute_plan_df      (p_task_rec IN OUT NOCOPY task%ROWTYPE);
  PROCEDURE execute_storage_histogram;
  PROCEDURE execute_db_stats_refresh;
  PROCEDURE execute_restore_range_refresh (p_task_rec IN task%ROWTYPE);
  PROCEDURE execute_optimize_chunks_df (p_task_rec IN task%ROWTYPE);
  PROCEDURE execute_optimize_chunks (p_task_rec IN task%ROWTYPE);
  PROCEDURE execute_rebuild_index      (p_task_rec IN task%ROWTYPE);
  PROCEDURE execute_validate_db (p_task_rec IN task%ROWTYPE);
  PROCEDURE execute_delete_db (p_task_rec IN task%ROWTYPE);
  PROCEDURE execute_check_files (p_task_rec IN task%ROWTYPE);
  PROCEDURE execute_crosscheck_db (p_task_rec IN task%ROWTYPE);
  PROCEDURE execute_trim_db (p_task_rec IN task%ROWTYPE);
  PROCEDURE execute_move_all_db;
  PROCEDURE execute_move_df (p_task_rec IN task%ROWTYPE);
  PROCEDURE execute_backup_sbt (p_task_rec IN task%ROWTYPE);
  PROCEDURE execute_restore_sbt (p_task_rec IN task%ROWTYPE);
  PROCEDURE execute_purge_sbt (p_task_rec IN task%ROWTYPE);
  PROCEDURE execute_obsolete_sbt(p_task_rec IN task%ROWTYPE);
  PROCEDURE execute_reconcile(p_task_rec IN task%ROWTYPE);
  PROCEDURE execute_repair_db(p_task_rec IN task%ROWTYPE);
  PROCEDURE execute_insert_fault (p_task_rec IN task%ROWTYPE);
  PROCEDURE complete_task (p_action IN VARCHAR2, 
                           p_taskname IN VARCHAR2,
                           p_current_execution_time TIMESTAMP WITH TIME ZONE,
                           p_final_state NUMBER);
  PROCEDURE suspend_task (p_newstate IN NUMBER,
                          p_current_execution_time TIMESTAMP WITH TIME ZONE);
  PROCEDURE trace_task (p_action VARCHAR2, p_taskname IN VARCHAR2);
  FUNCTION  define_task (task_rec   IN OUT NOCOPY task%ROWTYPE,
                         p_sbt_task IN BOOLEAN DEFAULT FALSE) RETURN NUMBER;
                   
--
  PROCEDURE copy_sbt (p_task_rec IN task%ROWTYPE);
  PROCEDURE log_sbt_error(p_db_key      IN NUMBER,
                          p_lib_key     IN NUMBER,
                          p_failure_cnt IN NUMBER,
                          p_retry       IN BOOLEAN);
  PROCEDURE log_sbt_task_error(p_db_key       IN NUMBER,
                               p_bs_key       IN NUMBER,
                               p_bp_key       IN NUMBER,
                               p_template_key IN NUMBER,
                               p_lib_key      IN NUMBER);
  PROCEDURE restore_sbt (p_task_rec IN task%ROWTYPE);
  PROCEDURE cleanup_task (p_task_type IN NUMBER);
  PROCEDURE crosscheck_db(p_db_key IN NUMBER);
  PROCEDURE purge_obsolete_sbt(
                          p_dbkey    IN NUMBER,
                          p_libkey   IN NUMBER,
                          p_sbt_ret  IN DSINTERVAL_UNCONSTRAINED);
  PROCEDURE spawn_sbt_job(p_libkey  IN NUMBER);
  PROCEDURE spawn_purge_sbt_job(p_libkey  IN NUMBER);
  PROCEDURE set_reconcile_timer(p_db_key  IN NUMBER);
  PROCEDURE set_resumable_timeout;
  PROCEDURE setDatabase(p_dbkey    IN NUMBER,
                        p_dbid     OUT NUMBER,
                        p_currinc  OUT NUMBER,
                        p_db_slkey OUT NUMBER);
  PROCEDURE wait_for_dbfs;
 
--
--
--
  FUNCTION print (p_value IN BOOLEAN) RETURN VARCHAR2;
  FUNCTION print (p_value IN NUMBER) RETURN VARCHAR2;
  FUNCTION print (p_value IN DSINTERVAL_UNCONSTRAINED) RETURN VARCHAR2;
  FUNCTION print (p_value IN VARCHAR2) RETURN VARCHAR2;
  FUNCTION print (p_value IN TIMESTAMP WITH TIME ZONE) RETURN VARCHAR2;
  FUNCTION print (p_value IN DATE) RETURN VARCHAR2;
  FUNCTION bittst (p_mask IN NUMBER, p_bit IN NUMBER) RETURN BOOLEAN;
  FUNCTION bitclr (p_mask IN NUMBER, p_bit IN NUMBER) RETURN NUMBER;
  FUNCTION bitset (p_mask IN NUMBER, p_bit IN NUMBER) RETURN NUMBER;
  PROCEDURE tracex (message IN VARCHAR2);
  PROCEDURE trace1 (message IN VARCHAR2);
  FUNCTION check_when (p_view IN VARCHAR2, p_task_id IN NUMBER) RETURN BOOLEAN;
  PROCEDURE avoid_delete_db(p_dbkey IN NUMBER DEFAULT NULL);
  FUNCTION delete_db_disruptive_running RETURN NUMBER;
--
  PROCEDURE delete_db_remove_remaining (p_dbkey IN NUMBER);
 
--
--
--
 
--
--
  PROCEDURE inValidateBaseLevelBcks (p_db_key       IN NUMBER,
                                     p_currinc      IN NUMBER,
                                     p_template_key IN NUMBER,
                                     p_baseline_scn IN OUT NUMBER);
 
--
  PROCEDURE baselineTimezone(p_db_key               IN NUMBER,
                             p_baseline_time        OUT NOCOPY DATE,
                             p_baseline_untscn      OUT NOCOPY NUMBER,
                             p_recovery_window_sbt  OUT NOCOPY DATE);
 
--
  PROCEDURE queueBaseLevelBcks(p_db_key            IN NUMBER,
                               p_dbid             OUT NUMBER,
                               p_currinc       IN OUT NUMBER,
                               p_db_slkey      IN OUT NUMBER,
                               p_from_tag          IN VARCHAR2,
                               p_template_key      IN NUMBER,
                               p_baseline_scn  IN OUT NUMBER,
                               p_lib_key           IN NUMBER,
                               p_attr_key          IN NUMBER,
                               p_copies            IN NUMBER,
                               p_delete_source     IN VARCHAR2,
                               p_format            IN VARCHAR2,
                               p_last_bp_key       IN NUMBER,
                               p_max_bp_key        IN NUMBER,
                               p_server_key        IN NUMBER);
  
--
  PROCEDURE queueMissingDFBcks(p_db_key            IN NUMBER,
                               p_from_tag          IN VARCHAR2,
                               p_template_key      IN NUMBER,
                               p_baseline_scn      IN NUMBER,
                               p_lib_key           IN NUMBER,
                               p_attr_key          IN NUMBER,
                               p_copies            IN NUMBER,
                               p_delete_source     IN VARCHAR2,
                               p_format            IN VARCHAR2,
                               p_last_bp_key       IN NUMBER,
                               p_server_key        IN NUMBER);
  
--
  PROCEDURE logMissingDfBcksError(p_db_key        IN NUMBER,
                                  p_currinc       IN NUMBER,
                                  p_template_key  IN NUMBER);
  
--
  PROCEDURE queueIncrementalBcks(p_db_key            IN NUMBER,
                                 p_from_tag          IN VARCHAR2,
                                 p_template_key      IN NUMBER,
                                 p_full_template_key IN NUMBER,
                                 p_baseline_scn      IN NUMBER,
                                 p_lib_key           IN NUMBER,
                                 p_attr_key          IN NUMBER,
                                 p_copies            IN NUMBER,
                                 p_delete_source     IN VARCHAR2,
                                 p_format            IN VARCHAR2,
                                 p_init_cf_bs_key    IN NUMBER,
                                 p_last_bp_key       IN NUMBER,
                                 p_server_key        IN NUMBER);
    
--
  PROCEDURE queueArchivedLogBcks(p_db_key            IN NUMBER,
                                 p_from_tag          IN VARCHAR2,
                                 p_template_key      IN NUMBER,
                                 p_full_template_key IN NUMBER,
                                 p_baseline_scn      IN NUMBER,
                                 p_lib_key           IN NUMBER,
                                 p_attr_key          IN NUMBER,
                                 p_copies            IN NUMBER,
                                 p_delete_source     IN VARCHAR2,
                                 p_format            IN VARCHAR2,
                                 p_init_cf_bs_key    IN NUMBER,
                                 p_last_bp_key       IN NUMBER,
                                 p_server_key        IN NUMBER);
  
--
  PROCEDURE queueKeepBcks (p_db_key            IN NUMBER,
                           p_from_tag          IN VARCHAR2,
                           p_template_key      IN NUMBER,
                           p_baseline_scn      IN NUMBER,
                           p_lib_key           IN NUMBER,
                           p_attr_key          IN NUMBER,
                           p_copies            IN NUMBER,
                           p_delete_source     IN VARCHAR2,
                           p_format            IN VARCHAR2,
                           p_last_bp_key       IN NUMBER,
                           p_server_key        IN NUMBER);
 
--
  PROCEDURE create_replication_tasks(p_db_key IN NUMBER,
                                     p_bp_key IN NUMBER DEFAULT NULL,
                                     p_bs_key IN NUMBER DEFAULT NULL,
                                     p_piece_no IN NUMBER DEFAULT NULL,
                                     p_server_key IN NUMBER DEFAULT NULL,
                                     p_lib_key IN NUMBER DEFAULT NULL);
 
--
--
--
 
--
--
--
  TIMER_RELOAD_CONFIG       CONSTANT NUMBER := 0;
  TIMER_VERIFY              CONSTANT NUMBER := 1;
  TIMER_POLLING             CONSTANT NUMBER := 2;
  TIMER_HISTORY_PRUNE       CONSTANT NUMBER := 3;
  TIMER_RM_INCOMPLETE_FILES CONSTANT NUMBER := 4;
  TIMER_STORAGE_HISTOGRAM   CONSTANT NUMBER := 5;
  TIMER_STORAGE_MAINTENANCE CONSTANT NUMBER := 6;
  TIMER_TASK_MAINTENANCE    CONSTANT NUMBER := 7;
  TIMER_OBSOLETE_SBT        CONSTANT NUMBER := 8;
  TIMER_RECONCILE           CONSTANT NUMBER := 9;
  TIMER_SPAWN_SBT           CONSTANT NUMBER := 10;
  TIMER_SET_RECONCILE_TIMER CONSTANT NUMBER := 11;
  TIMER_DB_STATS_REFRESH    CONSTANT NUMBER := 12;
--
--
  TIMER_RM_SBT_SESSION      CONSTANT NUMBER := 15;
 
--
  COPIED_TO_TAPE            CONSTANT NUMBER := 1;
  NOT_COPIED_TO_TAPE        CONSTANT NUMBER := 0;
 
--
--
PROCEDURE save_error IS 
BEGIN
  DBMS_RA_INT.SAVE_ERROR_INT;
END save_error;
 
--
--
PROCEDURE clear_error(reset BOOLEAN DEFAULT FALSE) IS
BEGIN
  DBMS_RA_INT.CLEAR_ERROR_INT(reset);
END clear_error;
 
--
--
 
PROCEDURE init (p_instance_only IN BOOLEAN DEFAULT FALSE, 
                p_repair IN BOOLEAN DEFAULT FALSE) IS
  l_alert_text          VARCHAR2(100);
  l_current_incarnation NUMBER;
  l_last_incarnation    NUMBER;
  l_state               VARCHAR2(3);
  l_waitcount           NUMBER := 0;
  l_debug_flags         NUMBER := 0;
  l_num                 NUMBER;
BEGIN
  /* Config overrides init.ora value, if set */
  /* Get value from config and set the debug flags - Start */
 
  BEGIN
    SELECT NVL(MAX(TO_NUMBER(value)), 0) INTO l_debug_flags
      FROM config
      WHERE name = '_debug_flags';
  EXCEPTION
      WHEN NO_DATA_FOUND THEN
        save_error;
        clear_error;
  END;
 
--
--
  IF SYS.rai_schema <> ('"' || USER || '"') THEN
    SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(e_bad_user_num, SYS.rai_schema);
  END IF;
 
  sys.kbrsi_icd.rsSetDebugFlags(l_debug_flags);
  /* Get value from config and set the debug flags - End */
 
  sys.kbrsi_icd.rsSetTrace(1);
  s_current_task_type := 0;  -- Just to make the trace work out.
  trace_task('INIT_JOB_SCHED', 'INIT');
 
  trace1 ('INIT: instance_only=' || print(p_instance_only) ||
              '; repair=' || print(p_repair) ||
              '; user=' || USER);
 
--
--
--
  SELECT value into l_state
    FROM config
    WHERE name = '_recovery_appliance_state';
 
--
--
--
  IF p_instance_only AND l_state <> 'ON' THEN
    trace1 ('INIT:  Exiting since recovery appliance wasnt manually started');
    RETURN;     
  END IF;
 
--
--
--
  SYS.DBMS_SYSTEM.KSDWRT(SYS.DBMS_SYSTEM.ALERT_FILE,
                'Startup of ZDLRA at ' || SYSTIMESTAMP || 
                CASE p_instance_only 
                  WHEN TRUE 
                  THEN ' for instance ' || s_inst_name
                END ||
                CASE l_debug_flags 
                  WHEN 0 THEN NULL
                  ELSE ' with _debug flags = ' || l_debug_flags || 
                       '(' || TO_CHAR(l_debug_flags, 'FMXXXXXXXXXXXXXXXX') ||
                       ')'
                END);
 
--
--
--
  DBMS_RA_INT.LOCK_API_INT(DBMS_RA.LOCKAPI_CREATE, 'start recovery appliance');
 
--
--
--
  SELECT incarnation# INTO l_current_incarnation
    FROM sys.v_$database_incarnation 
    WHERE status='CURRENT';
 
  SELECT TO_NUMBER(NVL(MIN(value),-1)) INTO l_last_incarnation
    FROM config
    WHERE name = '_last_incarnation';
 
  trace1 ('INIT: Old incarn: ' || l_last_incarnation ||
              '; New incarn: ' || l_current_incarnation);
 
  IF l_current_incarnation <> l_last_incarnation THEN
--
--
--
--
    IF l_last_incarnation <> -1 THEN
      BEGIN
        IF p_repair THEN
          trace1 ('INIT: Need to fix up bad ors metadata.');
--
--
--
--
--
          fix_error (p_error_num => E_REPAIR_AVM_METADATA_NUM);
          COMMIT;
 
          repair_rs;
        ELSE
          trace1 ('INIT: Turn off recovery appliance state');
--
          UPDATE config SET value = 'OFF'
            WHERE name = '_recovery_appliance_state';
          COMMIT;
          SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(e_repair_avm_metadata_num, 
                                                l_last_incarnation,
                                                l_current_incarnation);
        END IF;
      EXCEPTION
        WHEN OTHERS THEN
          save_error;
          write_error (p_component => 'REPAIR', 
                       p_severity  => SEVERITY_ERROR);
 
          DBMS_RA_INT.UNLOCK_API_INT (p_the_num=>0,
                              p_results=>FALSE, 
                              p_docommit=>FALSE);
          RAISE;
      END;
    END IF;
 
--
--
--
    UPDATE config SET value = TO_CHAR(l_current_incarnation)
      WHERE name = '_last_incarnation';
    COMMIT;
 
--
--
--
--
--
    fix_error (p_error_num => E_REPAIR_AVM_METADATA_NUM);
    COMMIT;
 
  END IF;
 
--
--
--
--
--
--
--
  IF SYS.KBRSI_ICD.RSTIMERCHECK THEN
    UPDATE poll
      SET poll_flags = poll_flags - 
                       BITAND(poll_flags, POLL_FLAGS_UNDO_TIMEOUT_ERROR) +
                       POLL_FLAGS_UNDO_TIMEOUT_ERROR;
 
--
--
--
    UPDATE config SET value = MAX_RESOURCE_WAIT_PROCESSES
      WHERE name = '_resource_wait_task_limit';
 
    UPDATE task SET state = STATE_EXECUTABLE,
                    pending_interrupt = NULL
      WHERE state = STATE_TASK_WAIT
        AND pending_interrupt = RESOURCE_PSEUDO_TASK;
    trace1('INIT: Cleared ' || SQL%ROWCOUNT || ' resource wait tasks');
    COMMIT;
  END IF;
 
--
--
--
  IF NOT p_instance_only THEN
    trace1 ('INIT: Turn on recovery appliance state');
    UPDATE config SET value = 'ON'
      WHERE name = '_recovery_appliance_state';
    COMMIT;
 
--
--
--
    fix_error(p_error_num => E_SHUTTING_DOWN_NUM);
 
--
--
--
    fix_error(p_error_num => E_COULDNT_STOP_JOB_NUM);
    COMMIT;
  END IF;
 
--
--
--
--
  trace1 ('INIT: Starting timer session');
 
--
--
--
  BEGIN
    DBMS_SCHEDULER.DROP_JOB(
                job_name => 'RA$_TIMER_' || TO_CHAR(s_instance),
                force => TRUE);
    trace1 ('INIT: Stopped RA$_TIMER_' || TO_CHAR(s_instance));
  EXCEPTION
    WHEN E_JOB_NOT_RUNNING OR E_JOB_NOT_FOUND OR E_JOB_DOES_NOT_EXIST THEN
      save_error;
      clear_error;
  END;
  
  l_num := restart_timer_process (FALSE);
 
--
--
--
  DBMS_RA_INT.UNLOCK_API_INT (p_the_num=>0,
                              p_results=>FALSE, p_docommit=>FALSE);
 
  trace1 ('INIT: Up and running');
 
EXCEPTION
  WHEN OTHERS THEN
    save_error;
    DBMS_RA_INT.UNLOCK_API_INT (p_the_num=>0,
                                p_results=>FALSE, p_docommit=>FALSE);
    RAISE;
END init;
 
--
--
--
--
--
--
--
PROCEDURE display_cf_errors (p_amrvkey NUMBER, 
                             p_sl_name VARCHAR2, 
                             p_sl_key NUMBER) IS
BEGIN 
  FOR m IN (SELECT msg
              FROM sys.amrv$msg
             WHERE amrv_key = p_amrvkey
              AND (msgcode IN (202, 203, 200)
--
--
--
                  OR msgcode BETWEEN 1000 AND 1999)
--
            ORDER BY msgtime) LOOP
    log_error (p_errno => E_CONTAINER_REBUILD_ERROR_NUM,
               p_param1 => p_sl_name,
               p_param2 => m.msg,
               p_component => 'REPAIR',
               p_sl_key    => p_sl_key,
               p_severity  => SEVERITY_ERROR);
  END LOOP;
END display_cf_errors;
 
--
--
--
--
--
--
--
PROCEDURE repair_rs IS
  CURSOR bp_cursor IS
    SELECT ct.ct_key, bs.keep_options, ct.db_key, bs.bs_key, bp.bp_key
      FROM sbt_catalog ct, bp, bs, 
           (SELECT bdf.bs_key, MAX(bdf.ckp_time) ckp_time
              FROM bdf
              GROUP BY bs_key) bdf
      WHERE ct.pieceinc = 'NEEDS_REPAIR'
        AND ct.bp_key = bp.bp_key
        AND ct.completed = 'Y'
        AND bp.status != 'D'
        AND bp.bs_key = bs.bs_key
        AND bdf.bs_key = bs.bs_key
      ORDER BY bdf.ckp_time;
 
  CURSOR odb_cursor IS
    SELECT o.db_key, NVL(d.sls_used,0)+1 sls_used, d.dbsl_used_space, 
           p.prot_recovery_window_goal, o.prot_key, 
           o.future_prot_key, fp.sl_key future_sl_key, o.sl_key,
           o.allocated_space, d.dbsl_sl_key
    FROM odb o
         JOIN prot p ON (o.prot_key = p.prot_key)
         JOIN prot fp ON (o.future_prot_key = fp.prot_key)
         LEFT OUTER JOIN (SELECT db_key, SUM(dbsl_used_space) dbsl_used_space, 
                                 COUNT(*) sls_used, MIN(sl_key) dbsl_sl_key
                          FROM dbsl
                          GROUP BY db_key) d ON (d.db_key = o.db_key);
  l_start_time  TIMESTAMP WITH TIME ZONE := SYSTIMESTAMP;
  l_destlist    VARCHAR2(4000);
  l_bad_sls     NUMBER := 0;
  l_gname       VARCHAR2(31);
  l_amrvkey     NUMBER;
  l_sl_space    NUMBER;
 
  l_freespace   NUMBER;
  l_lastdb      dbinc.db_name%TYPE;
  l_task_rec task%ROWTYPE;
  l_count       NUMBER;
 
BEGIN
  trace1 ('REPAIR_RS');
  s_repair_active := TRUE;
 
--
--
--
--
  DELETE FROM sbt_catalog WHERE completed = 'N';
  trace1('REPAIR_RS: Deleted ' || SQL%ROWCOUNT || ' incomplete backup pieces');
 
  UPDATE task SET state = CASE state
                            WHEN STATE_RUNNING THEN STATE_EXECUTABLE
                            WHEN STATE_CANCELING THEN STATE_CANCEL
                          END
    WHERE state IN (STATE_RUNNING, STATE_CANCELING);
  trace1('REPAIR_RS: Modified ' || SQL%ROWCOUNT || ' tasks');
 
  UPDATE sessions SET current_task=NULL,
                      current_task_type=NULL
    WHERE current_task IS NOT NULL;
  trace1('REPAIR_RS: Modified ' || SQL%ROWCOUNT || ' sessions');
  COMMIT;
 
--
--
--
  quiesce_rs ();
 
--
--
--
  UPDATE sl SET sl_needs_repair = 1
    WHERE sl_space > 0;
  trace1('REPAIR_RS: Marked ' || SQL%ROWCOUNT || ' storage locations');
  COMMIT;
 
--
--
--
--
  UPDATE task SET state = STATE_CANCEL
    WHERE task_type = TASK_DELETE_DB;
  COMMIT;
 
--
--
--
--
--
 
  DELETE FROM task_chunk_cache;
  trace1('REPAIR_RS: Deleted ' || SQL%ROWCOUNT || ' task_chunk_cache rows');
 
  DELETE FROM task
    WHERE task_type IN (TASK_PURGE_DF_NOW, TASK_PURGE_DUP_DF, TASK_PURGE_DF,
                        TASK_TRIM_DB, TASK_PURGE,
                        TASK_MOVE_DF, TASK_MOVE_ALL_DB);
  trace1('REPAIR_RS: Deleted ' || SQL%ROWCOUNT || ' task rows');
 
  UPDATE task SET state=STATE_EXECUTABLE,
                  pending_interrupt=NULL,
                  interrupt_count=0,
                  savepoint=NULL,
                  ba_session_id=NULL,
                  purge_reserve=NULL,
                  flags = flags - BITAND(flags, TASKS_CHUNK_CACHE_ACTIVE);
 
  trace1('REPAIR_RS: Updated ' || SQL%ROWCOUNT || ' task rows');
  COMMIT;
 
--
--
--
--
  cleanup_dead_schedulers (p_restart => FALSE);
 
--
--
--
  EXECUTE IMMEDIATE 'TRUNCATE TABLE plans_details';
  EXECUTE IMMEDIATE 'TRUNCATE TABLE plans';
  trace1 ('REPAIR_RS: tasks and plans are gone');
 
--
--
--
--
  DELETE FROM sbt_catalog WHERE completed = 'N';
  trace1('REPAIR_RS: Deleted ' || SQL%ROWCOUNT || ' sbt_catalog rows');
 
--
--
--
  UPDATE odb SET db_state = NULL;
  COMMIT;
 
--
--
--
--
  FOR s IN (SELECT sl_key, sl_name, sl_cg_name, sl_state
              FROM sl
              WHERE sl_space > 0) LOOP
    trace1('REPAIR_RS: Repairing sl_key=' || s.sl_key ||
                              '; cgname=' || s.sl_cg_name ||
                              '; state=' || s.sl_state);
 
--
--
--
--
    SELECT SUBSTR (SYS_CONNECT_BY_PATH (dest, ','), 2) INTO l_destlist
      FROM (SELECT ROWNUM rn, dest,                    
                   COUNT (*) OVER () cnt
            FROM storage_dests
            WHERE sl_key = s.sl_key)
      WHERE rn = cnt
      START with rn = 1
      CONNECT by rn = prior rn + 1;
 
--
--
--
    IF s.sl_state = 'I' THEN
      l_gname := s.sl_name;
 
      IF sys.kbrsi_icd.repair_container_group(gname => s.sl_name,
                                              amrvkey => l_amrvkey) = 0 THEN
        log_error(p_errno => E_SL_REBUILD_RECOVERABLE_NUM,
                  p_param1 => s.sl_name,
                  p_param2 => l_amrvkey,
                  p_component => 'REPAIR',
                  p_sl_key    => s.sl_key,
                  p_severity  => SEVERITY_ERROR);
 
--
        display_cf_errors (l_amrvkey, s.sl_name, s.sl_key);
 
--
        l_bad_sls := l_bad_sls + 1;
        UPDATE sl SET sl_state = 'E'
          WHERE sl_key = s.sl_key;
        COMMIT;
        CONTINUE;
      END IF;
 
    ELSE -- User did not request repair...
--
--
--
      SYS.KBRSI_ICD.DROP_CONTAINER_GROUP(gname => s.sl_name,
                                         force => 1,
                                         keep_container => 1);
 
      trace1('REPAIR_RS:  Container metadata has been cleared');
 
      IF sys.kbrsi_icd.rebuild_container_group(pathlist => l_destlist, 
                                               gname => l_gname, 
                                               amrvkey => l_amrvkey) = 0 THEN
        trace1('REPAIR_RS:  Error seen on container group=' || l_gname ||
                                                    '; amrvkey=' || l_amrvkey);
 
--
--
--
        IF l_gname IS NULL THEN
          log_error(p_errno => E_SL_REBUILD_FATAL_NUM,
                    p_param1 => s.sl_name,
                    p_param2 => l_amrvkey,
                    p_component => 'REPAIR',
                    p_sl_key    => s.sl_key,
                    p_severity  => SEVERITY_ERROR);
 
--
          display_cf_errors (l_amrvkey, s.sl_name, s.sl_key);
 
--
          UPDATE sl SET sl_state = 'F'
            WHERE sl_key = s.sl_key;
          COMMIT;
        ELSE 
          log_error(p_errno => E_SL_REBUILD_RECOVERABLE_NUM,
                    p_param1 => s.sl_name,
                    p_param2 => l_amrvkey,
                    p_component => 'REPAIR',
                    p_sl_key    => s.sl_key,
                    p_severity  => SEVERITY_ERROR);
 
--
          display_cf_errors (l_amrvkey, s.sl_name, s.sl_key);
 
--
          UPDATE sl SET sl_state = 'E'
            WHERE sl_key = s.sl_key;
          COMMIT;
        END IF;  
 
--
--
--
        l_bad_sls := l_bad_sls + 1;
        CONTINUE;
      END IF;
    END IF;
 
--
--
--
    trace1('REPAIR_RS:  Container metadata is good.');
    UPDATE sl SET sl_state = NULL
      WHERE sl_key = s.sl_key;
    COMMIT;
 
--
--
--
    IF s.sl_name <> l_gname THEN
      log_error(p_errno => E_SL_RENAME_NUM,
                p_param1 => l_gname,
                p_param2 => s.sl_name,
                p_component => 'REPAIR',
                p_sl_key    => s.sl_key,
                p_severity  => SEVERITY_ERROR);
      l_bad_sls := l_bad_sls + 1;
      CONTINUE;
    END IF;
 
--
--
--
    UPDATE sl
      SET sl_space = (SELECT total_space FROM sys.am$container_group
                        WHERE group_name = s.sl_name)
      WHERE sl_key = s.sl_key
      RETURNING sl_space INTO l_sl_space;
    COMMIT;
 
    trace1('REPAIR_RS:  Container rebuild of ' ||  s.sl_cg_name ||
                  ' succeeded with a size of ' ||  
                        l_sl_space/(1024*1024*1024) || 'GB');
 
--
--
--
    BEGIN
      DBMS_RA_INT.VERIFY_RESERVED_SPACE (s.sl_key, FALSE);
    EXCEPTION
      WHEN DBMS_RA.SPACE_QUOTA_VIOLATION THEN
        save_error;
        log_error(p_errno => E_SL_OUT_OF_SPACE_NUM,
                  p_param1 => s.sl_name,
                  p_component => 'REPAIR',
                  p_sl_key    => s.sl_key,
                  p_severity  => SEVERITY_ERROR);
        l_bad_sls := l_bad_sls + 1;
        clear_error;
        CONTINUE;
    END;
 
 
--
--
--
--
    testTask(p_tasktype => TASK_CHECK_FILES,
             p_slkey => s.sl_key,
             p_num1 => 1);
 
    DELETE FROM sessions WHERE purpose = TASK_CHECK_FILES;
    COMMIT;
 
  END LOOP;
  trace1('REPAIR_RS: Files are repaired');
 
--
--
--
  IF l_bad_sls > 0 THEN
    unquiesce_rs();
    s_repair_active := FALSE;
    trace1('REPAIR_RS: Bad container termination.');
    SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(E_ERRORS_FOUND_NUM, l_bad_sls);
  END IF;
 
--
--
--
--
--
  FOR b IN bp_cursor LOOP
    UPDATE sbt_catalog SET pieceinc = 'REPAIRED'
      WHERE ct_key = b.ct_key;
 
--
--
--
--
    IF b.keep_options = 0 THEN
      l_task_rec.task_type   := DBMS_RA_SCHEDULER.TASK_INDEX_BACKUP;
      l_task_rec.flags       := DBMS_RA_SCHEDULER.TASKS_RECEIVED_BACKUP;
      l_task_rec.db_key      := b.db_key;
      l_task_rec.param_num1  := b.bp_key;
      DBMS_RA_SCHEDULER.NEW_TASK (task_rec => l_task_rec);
    ELSE
      COMMIT;
    END IF;
 
  END LOOP;
  trace1('REPAIR_RS: Backups are queued');
 
--
--
--
  FOR o IN odb_cursor LOOP
--
--
--
--
    trace1('REPAIR_RS: Repairing db_key=' || o.db_key);
    UPDATE odb
      SET purge_session = NULL,
          purge_instance = NULL,       
          sls_used = o.sls_used,
          total_allocation = used_space + NVL(o.dbsl_used_space,0),
          not_taped = used_space + NVL(o.dbsl_used_space,0),
          wait_space = NULL,
          reserved_space = base_reserved_space,
          recovery_window_goal = o.prot_recovery_window_goal,
          move_phase = 
                      DECODE (o.sls_used, 1, MOVE_PHASE_NULL, MOVE_PHASE_PEND),
          allocated_space = used_space
      WHERE db_key = o.db_key;
 
--
--
--
--
    IF (o.sls_used = 2) AND 
       (o.allocated_space = 0) AND 
       (o.dbsl_sl_key = o.future_sl_key) THEN
 
      trace1('Move has completed for db_key=' || o.db_key);
      DBMS_RA_STORAGE.MOVE_DATABASE_METADATA(
                                        o.db_key, o.sl_key, o.future_sl_key);
      UPDATE odb 
        SET move_phase = MOVE_PHASE_NULL,
            sls_used = 1
        WHERE db_key = o.db_key;
    END IF;         
 
    COMMIT;
  END LOOP;
  trace1('REPAIR_RS: ODB rows have been updated');
 
--
--
--
--
--
  FOR s IN (SELECT sl_key, sl_name, sl_space
              FROM sl
              WHERE sl_space > 0) LOOP
 
    l_freespace := DBMS_RA_STORAGE.FREESPACE(s.sl_key);
 
    IF l_freespace < 0 THEN
      trace1 ('REPAIR_RS: Storage location ' || s.sl_name || ' needs ' ||
                        l_freespace || ' more storage');
 
      log_error (p_errno => E_NEED_MORE_SPACE_NUM,
                 p_param1 => s.sl_name,
                 p_param2 => -l_freespace,
                 p_component => 'REPAIR',
                 p_severity  => SEVERITY_ERROR);
    END IF;
  END LOOP;
  trace1('REPAIR_RS: Unreasonable storage location check is complete.');
 
--
--
--
--
--
--
--
--
--
--
  l_lastdb := NULL;
  FOR o IN (SELECT odb.sls_used, dbinc.db_name
              FROM odb
                   JOIN db ON odb.db_key = db.db_key
                   JOIN dbinc ON (db.db_key = dbinc.db_key) AND
                                  (db.curr_dbinc_key = dbinc.dbinc_key)
              WHERE odb.sls_used > 1) LOOP
    IF l_lastdb IS NULL THEN
      trace1(o.db_name || ' is in the middle of a move');
      l_lastdb := o.db_name;
    ELSE
      trace1 ('REPAIR_RS: ' || l_lastdb || ' and ' || o.db_name ||
                          ' are both in more than one storage location.');
 
      log_error (p_errno => E_TOO_MANY_MOVES_NUM,
                 p_param1 => l_lastdb,
                 p_param2 => o.db_name,
                 p_component => 'REPAIR',
                 p_severity  => SEVERITY_ERROR);
    END IF;
  END LOOP;
  trace1('REPAIR_RS: Movement check completed.');
 
--
--
--
--
  l_task_rec.task_type     := TASK_MOVE_ALL_DB;
  l_task_rec.flags         := 0;
  new_task(l_task_rec);
 
--
--
--
  FOR d IN (SELECT db_key, sl_key FROM odb) LOOP
    l_task_rec.task_type     := TASK_REPAIR_DB;
    l_task_rec.db_key        := d.db_key;
    l_task_rec.sl_key        := d.sl_key;
    l_task_rec.flags         := 0;
    new_task(l_task_rec);
  END LOOP;
  trace1('REPAIR_RS: Pool repair tasks submitted.');
 
--
--
--
  SELECT COUNT(*) INTO l_count
    FROM error_log
    WHERE last_seen > l_start_time
      AND severity >= SEVERITY_ERROR
      AND ROWNUM = 1;
 
  IF l_count > 0 THEN
    trace1 ('REPAIR_RS: ' || l_count || 
             ' errors need to be fixed before restarting the recovery appliance');
 
    SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(E_ERRORS_FOUND_NUM, l_count);
  END IF; 
 
--
--
--
--
  fix_error (p_error_num => E_NEED_MORE_SPACE_NUM,
             p_timestamp => l_start_time);
 
  fix_error (p_error_num => E_TOO_MANY_MOVES_NUM,
             p_timestamp => l_start_time);
 
  fix_error (p_error_num => E_SL_REBUILD_RECOVERABLE_NUM,
             p_timestamp => l_start_time);
 
  fix_error (p_error_num => E_SL_REBUILD_FATAL_NUM,
             p_timestamp => l_start_time);
 
  fix_error (p_error_num => E_SL_REBUILD_RECOVERABLE_NUM,
             p_timestamp => l_start_time);
 
  fix_error (p_error_num => E_SL_RENAME_NUM,
             p_timestamp => l_start_time);
 
  fix_error (p_error_num => E_SL_OUT_OF_SPACE_NUM,
             p_timestamp => l_start_time);
 
  fix_error (p_error_num => E_CONTAINER_REBUILD_ERROR_NUM,
             p_timestamp => l_start_time);
  COMMIT;
    
--
--
--
  unquiesce_rs();
  s_repair_active := FALSE;
  trace1('REPAIR_RS: Completed');
 
EXCEPTION
  WHEN OTHERS THEN
    save_error;
    unquiesce_rs();
    s_repair_active := FALSE;
    RAISE;
END repair_rs;
 
--
--
--
--
--
--
--
--
--
 
PROCEDURE wait_for_repair (p_sl_key IN NUMBER,
                           p_db_key IN NUMBER) IS
  l_id          NUMBER;
BEGIN
--
--
--
--
  SELECT MAX(task_id) INTO l_id
    FROM task 
    WHERE task_type = TASK_REPAIR_DB;
 
  IF l_id IS NOT NULL THEN
    trace1('WAIT_FOR_REPAIR: Waiting for task ' || l_id);
    s_pending_interrupt := l_id;
    RAISE E_RETRY_ERROR;
  END IF;
 
  trace1('WAIT_FOR_REPAIR: Nothing to wait for ');
  RETURN;
 
END wait_for_repair;
 
--
--
--
--
--
--
--
--
 
FUNCTION restart_timer_process (do_check BOOLEAN) RETURN NUMBER IS
l_retval        NUMBER :=1;
BEGIN
  trace1('RESTART_TIMER_PROCESS do_check=' || print(do_check));
 
  IF do_check THEN
    SELECT COUNT(*)  INTO l_retval
      FROM config
      WHERE name = '_recovery_appliance_state'
        AND value = 'ON';
    
  END IF;
 
  IF l_retval = 1 THEN
    BEGIN
      spawn_job ('RA$_TIMER_' || TO_CHAR(s_instance),
                 'dbms_ra_scheduler.timer_functions;',
                 s_instance,
                 NULL);
    EXCEPTION
      WHEN E_JOB_ALREADY_EXISTS THEN
        save_error;
        trace1('RESTART_TIMER_PROCESS: Timer session already active');
        clear_error;
    END;
  END IF;
 
  trace1('RESTART_TIMER_PROCESS:  Retval=' || l_retval);
  RETURN l_retval;
END restart_timer_process;
 
 
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE spawn_job (p_name     IN VARCHAR2,
                     p_action   IN VARCHAR2,
                     p_instance IN NUMBER,
                     p_comments IN VARCHAR2) IS
 
sts VARCHAR2(3);
 
BEGIN
  trace1('SPAWN_JOB: ' || p_name);
 
--
--
--
  SELECT shutdown_pending INTO sts 
    FROM v$instance;
 
  IF sts = 'YES' THEN
    trace1('SPAWN_JOB: No dice.  Instance shutting down');
    RETURN;
  END IF; 
 
--
--
--
  SELECT value INTO sts 
    FROM config
    WHERE name = '_recovery_appliance_state';
 
  IF sts = 'OFF' THEN
    trace1('SPAWN_JOB: No dice.  recovery appliance is not running');
    RETURN;
  END IF; 
 
--
--
--
  DBMS_SCHEDULER.CREATE_JOB(
             job_name   => p_name
            ,job_type   => 'plsql_block'
            ,job_action => p_action
            ,enabled    => FALSE
            ,auto_drop  => TRUE
            ,comments   => p_comments);
 
  IF dbms_utility.is_cluster_database AND
     p_instance IS NOT NULL  THEN
    trace1('SPAWN_JOB: On instance ' || p_instance);
 
    DBMS_SCHEDULER.SET_ATTRIBUTE (
               name       =>  p_name
              ,attribute  =>  'instance_id'
              ,value      =>  p_instance);
  END IF;
 
  DBMS_SCHEDULER.ENABLE (name => p_name);
END spawn_job;
 
--
--
--
--
--
PROCEDURE spawn_purge_sbt_job(p_libkey  IN NUMBER)  IS
--
--
--
   PURGE_SCHEDULER_PER_INST CONSTANT NUMBER := 3;
 
   CURSOR missing_schedulers IS
    WITH rs AS -- running schedulers
       (SELECT NVL(instance_id, 1) instance_id,
               COUNT(*) session_count
          FROM TABLE(CAST(s_amjobs AS rai_jobs_table_type))
          WHERE comments = TO_CHAR(p_libkey)
            AND job_name LIKE 'RA$_PURGE_SBT%'
          GROUP BY instance_id)
    SELECT i.inst_number, NVL(rs.session_count, 0) session_count
      FROM sys.rai_active_instances i
      LEFT OUTER JOIN rs
      ON i.inst_number = rs.instance_id
   WHERE NVL(rs.session_count, 0) < PURGE_SCHEDULER_PER_INST;
BEGIN
--
   make_amjobs (name => 'RA$_PURGE_SBT%');
   FOR ms IN missing_schedulers LOOP
      FOR i IN ms.session_count..PURGE_SCHEDULER_PER_INST-1 LOOP
         spawn_job (dbms_scheduler.generate_job_name('RA$_PURGE_SBT_'),
                    'dbms_ra_scheduler.schedule(' ||
                    '  p_task_type => dbms_ra_scheduler.TASK_PURGE_SBT,' ||
                    '  p_param1    => ' || TO_CHAR(p_libkey) || ');',
                    ms.inst_number,
                    TO_CHAR(p_libkey));
      END LOOP;
   END LOOP;
END spawn_purge_sbt_job;
 
--
--
--
--
--
PROCEDURE spawn_sbt_job(p_libkey  IN NUMBER)  IS
   TYPE msRecord_t IS RECORD
   (
      inst_number   NUMBER,
      session_count NUMBER
   );
 
   TYPE msTable_t IS TABLE OF msRecord_t INDEX BY BINARY_INTEGER;
 
   CURSOR missing_schedulers IS
    WITH rs AS -- running schedulers
      (SELECT NVL(instance_id, 1) instance_id,
              COUNT(*) session_count
         FROM TABLE(CAST(s_amjobs AS rai_jobs_table_type))
       WHERE comments = TO_CHAR(p_libkey)
         AND job_name LIKE 'RA$_BKRS_SBT%'
        GROUP BY instance_id)
    SELECT i.inst_number, NVL(rs.session_count, 0) session_count
      FROM sys.rai_active_instances i
      LEFT OUTER JOIN rs
      ON i.inst_number = rs.instance_id
--
   ORDER BY 2, 1;
 
   drives_inuse NUMBER;
   l_proc       NUMBER;
   l_drives     NUMBER;
   first        BOOLEAN;
   min_job_cnt  NUMBER;
   mslist       msTable_t;
BEGIN
   make_amjobs (name => 'RA$_BKRS_SBT%');
 
--
--
   OPEN missing_schedulers;
   FETCH missing_schedulers BULK COLLECT INTO mslist;
   CLOSE missing_schedulers;
 
   SELECT count(*)
     INTO drives_inuse
     FROM TABLE(CAST(s_amjobs AS rai_jobs_table_type))
     WHERE comments = TO_CHAR(p_libkey);
 
   BEGIN
     SELECT l.drives, (l.drives - drives_inuse)
       INTO l_drives, l_proc
       FROM sbt_lib_desc l
      WHERE l.lib_key = p_libkey;
   EXCEPTION
     WHEN no_data_found THEN 
       save_error;
       trace1('SPAWN_SBT_JOB: Library/Replication server has been deleted.');
 
--
--
       SYS.KBRSI_ICD.RSSCHEDLOCK (waitforwork => 0);
       UPDATE task 
          SET state = STATE_CANCEL
        WHERE task_type IN (TASK_BACKUP_SBT, TASK_PURGE_SBT,
                            TASK_OBSOLETE_SBT, TASK_RESTORE_SBT)
         AND EXISTS (SELECT 1 
                       FROM sbt_task st
                      WHERE st.task_id = task.task_id 
                        AND st.lib_key = p_libkey)
         AND state NOT IN (STATE_RUNNING, STATE_CANCELING);
       trace1('SPAWN_SBT_JOB: Killed ' || SQL%ROWCOUNT || ' task(s).');
       COMMIT;
       SYS.KBRSI_ICD.RSSCHEDUNLOCK;
   END;
 
   trace1('SPAWN_SBT_JOB: drives_inuse=' || drives_inuse ||
          ', proc=' || l_proc);
 
--
   WHILE (l_proc > 0) LOOP
      first := TRUE;
      FOR i in 1..mslist.count LOOP
         IF (first) THEN
            min_job_cnt := mslist(i).session_count;
            first       := FALSE;
         ELSE
            EXIT WHEN (mslist(i).session_count > min_job_cnt);
         END IF;
         spawn_job (dbms_scheduler.generate_job_name('RA$_BKRS_SBT_'),
                    'dbms_ra_scheduler.schedule(' ||
                    '  p_task_type => dbms_ra_scheduler.TASK_BACKUP_SBT,' ||
                    '  p_param1    => ' || TO_CHAR(p_libkey) || ');',
                    mslist(i).inst_number,
                    TO_CHAR(p_libkey));
         mslist(i).session_count := mslist(i).session_count + 1;
         l_proc := l_proc - 1;
         EXIT WHEN l_proc = 0;
      END LOOP;
   END LOOP;
END spawn_sbt_job;
 
--
--
--
--
--
 
PROCEDURE queue_spawn_sbt(p_libkey     IN NUMBER,
                          p_forpurge   IN BOOLEAN,
                          p_check_work IN BOOLEAN DEFAULT FALSE) IS
  l_tasks           NUMBER;
  l_forpurge        NUMBER;
  new_task_rec      task%ROWTYPE;
  l_task_work       NUMBER;
  l_drives          NUMBER;
  l_new_drives      NUMBER;
  l_dynamic_drives  sbt_lib_desc.dynamic_drives%TYPE;
 
--
--
--
--
  CURSOR spawn_sbt_tasks(l_forpurge IN NUMBER) IS
    WITH rs AS -- running schedulers
       (SELECT param_num2 forpurge
          FROM task
         WHERE task_type = TASK_SPAWN_SBT
           AND state IN (STATE_EXECUTABLE, STATE_RUNNING)
           AND param_num1 = p_libkey
           AND param_num2 = nvl(l_forpurge, param_num2)
        GROUP BY param_num2),
         ds AS -- dead schedulers
       (SELECT 1 forpurge
          FROM dual
         WHERE nvl(l_forpurge, 1) = 1
        UNION
        SELECT 0 forpurge 
          FROM dual
         WHERE nvl(l_forpurge, 0) = 0)
    SELECT ds.forpurge
      FROM ds
     WHERE NOT EXISTS (SELECT 1 FROM rs WHERE rs.forpurge = ds.forpurge);
BEGIN
--
  IF (p_forpurge IS NULL) THEN
    l_forpurge := NULL;
  ELSIF (p_forpurge) THEN
    l_forpurge := 1;
  ELSE
    l_forpurge := 0;
  END IF;
 
  trace1('QUEUE_SPAWN_SBT: called for lib_key=' || p_libkey ||
         '; forpurge=' || nvl(to_char(l_forpurge), 'NULL'));
 
  BEGIN
     SELECT /*+ RESULT_CACHE */ l.dynamic_drives, l.drives
       INTO l_dynamic_drives, l_drives
       FROM sbt_lib_desc l
      WHERE l.lib_key  = p_libkey;
  EXCEPTION
     WHEN no_data_found THEN
        save_error;
        trace1('QUEUE_SPAWN_SBT: library not found');
        clear_error;
        RETURN;
  END;
 
  IF (l_dynamic_drives = 'Y') THEN
     l_new_drives := dbms_ra_int.sbt_default_drives;
     IF (l_new_drives != l_drives) THEN
        UPDATE sbt_lib_desc l
           SET l.drives = l_new_drives
         WHERE l.lib_key = p_libkey;
 
        COMMIT;
     END IF;
  END IF;
 
  FOR spt IN spawn_sbt_tasks(l_forpurge) LOOP
     IF (p_check_work) THEN
        trace1('QUEUE_SPAWN_SBT: scheduler checking for work');
        IF (spt.forpurge = 1) THEN
           SELECT COUNT(*) INTO l_task_work
             FROM task t, sbt_lib_desc l
            WHERE t.state = STATE_EXECUTABLE
              AND t.task_type = TASK_PURGE_SBT
              AND t.param_num1 = l.lib_key
              AND t.param_num1 = p_libkey
              AND l.status = 'R' -- filter ready libs
              AND rownum = 1;
        ELSE
           SELECT COUNT(*) INTO l_task_work
             FROM  task t, sbt_lib_desc l, sbt_task st
                   LEFT OUTER JOIN
                   sbt_job_template j
                   ON j.template_key = st.template_key
                   AND st.restore = 'N' -- backup jobs
                   AND (j.completion_time IS NULL OR
                        SYSTIMESTAMP < j.completion_time)
             WHERE t.state = STATE_EXECUTABLE
               AND t.task_id = st.task_id
               AND t.task_type IN (TASK_BACKUP_SBT, TASK_RESTORE_SBT)
               AND (j.template_key IS NOT NULL OR st.restore = 'Y')
               AND st.lib_key = l.lib_key
               AND l.status = 'R'   -- filter ready libs
               AND st.lib_key = p_libkey
               AND rownum = 1;
        END IF;
     ELSE
        l_task_work := 1;
     END IF;
 
     IF (l_task_work != 0) THEN
        trace1('QUEUE_SPAWN_SBT: adding spawn sbt task for lib_key='  ||
               p_libkey || '; forpurge=' || spt.forpurge);
        BEGIN
           new_task_rec.task_type  := TASK_SPAWN_SBT;
           new_task_rec.flags      := 0;
           new_task_rec.param_num1 := p_libkey;
           new_task_rec.param_num2 := spt.forpurge;
           new_task (new_task_rec);
        EXCEPTION
           WHEN DUP_VAL_ON_INDEX THEN
              save_error;
--
--
              IF (SQLERRM NOT LIKE '%TASK_SPAWN_SBT_I%') THEN
                 RAISE;
              END IF;
              clear_error;
        END;
     END IF;
  END LOOP;
END queue_spawn_sbt;
 
--
--
--
--
--
 
PROCEDURE timer_functions IS
  l_debug_flags         NUMBER := 0;
  l_next_timer          timer_task%ROWTYPE;
  l_sts                 VARCHAR2(10);
  l_seq                 NUMBER;
  new_task_rec          task%ROWTYPE;
  l_count               NUMBER;
  l_active_schedulers   NUMBER;
 
--
--
  CURSOR timer_cursor IS
     SELECT i.inst_name, i.inst_number
       FROM sys.rai_active_instances i
        WHERE NOT EXISTS (SELECT 1
                            FROM 
                              TABLE(CAST(s_amlocks AS rai_locks_table_type)) l
                             WHERE i.inst_number = l.inst_id
                               AND key = LOCK_TIMER);
 
--
  CURSOR reconcile_cursor IS
     SELECT db_key
       FROM odb
       WHERE NVL(next_reconcile, SYSTIMESTAMP + 1) <= SYSTIMESTAMP AND
             db_state IS NULL AND
             NOT EXISTS (SELECT 1 FROM task
                           WHERE task_type = TASK_RECONCILE AND
                                 task.db_key = odb.db_key)
        ORDER BY next_reconcile DESC;
     
--
--
  CURSOR sbt_spawn_cursor IS
     SELECT SUM(CASE WHEN t.state = STATE_RUNNING THEN 1 ELSE 0 END),
            st.lib_key
       FROM task t, sbt_lib_desc l, sbt_task st 
            LEFT OUTER JOIN
            sbt_job_template j
            ON j.template_key = st.template_key
            AND st.restore = 'N' -- backup jobs
            AND (j.completion_time IS NULL OR
                 SYSTIMESTAMP < j.completion_time)
      WHERE t.state IN (STATE_RUNNING, STATE_EXECUTABLE)
        AND t.task_id = st.task_id
        AND t.task_type IN (TASK_BACKUP_SBT, TASK_RESTORE_SBT)
        AND (j.template_key IS NOT NULL OR st.restore = 'Y')
        AND st.lib_key = l.lib_key
        AND l.status = 'R'   -- filter ready libs
   GROUP BY st.lib_key;
 
--
--
  CURSOR sbt_purge_cursor IS
     SELECT SUM(CASE WHEN t.state = STATE_RUNNING THEN 1 ELSE 0 END),
            t.param_num1
       FROM task t
            LEFT OUTER JOIN
            sbt_lib_desc l
            ON t.param_num1 = l.lib_key
      WHERE t.state IN (STATE_RUNNING, STATE_EXECUTABLE)
        AND t.task_type = TASK_PURGE_SBT
        AND (l.status = 'R' OR l.status IS NULL) -- filter ready libs
   GROUP BY t.param_num1; -- lib_key
 
  l_db_key              NUMBER;
  l_rec_bp_key          NUMBER;
  l_libkey              NUMBER;
  l_cnt                 NUMBER := 0;
 
BEGIN
--
  assert_owner;
 
  /* User timer process to set debug flags as each RAC instance starts */
  /* Get value from config and set the debug flags - Start */
  BEGIN
    SELECT NVL(MAX(TO_NUMBER(value)), 0) INTO l_debug_flags
      FROM config
      WHERE name = '_debug_flags';
 
    SYS.KBRSI_ICD.RSSETDEBUGFLAGS(l_debug_flags);
 
  EXCEPTION
      WHEN NO_DATA_FOUND THEN 
        save_error;
        clear_error;
  END;
 
  /* Get value from config and set the debug flags - End */
 
 
--
  sys.kbrsi_icd.rsSetTrace;
  trace1('TIMER activated as user ' || SYS_CONTEXT('USERENV','SESSION_USER'));
  trace1('TIMER activated as login user ' || USER);
  trace1('TIMER schema set to ' || SYS_CONTEXT('USERENV','CURRENT_SCHEMA'));
 
--
--
--
  wait_for_dbfs;
 
--
--
--
  set_resumable_timeout;
 
--
--
--
  SYS.KBRSI_ICD.RSTIMERLOCK;
  trace1('TIMER locked out other timer jobs');
 
--
--
--
--
  s_timer_process_instance := s_instance;
 
--
--
--
--
  enqueue_timer_reload_config;
 
--
--
--
  dbms_session.set_identifier('RA$ACTIVE_TIMER');
  WHILE TRUE LOOP
    clear_error(reset => TRUE);
    new_task_rec := NULL;
    dbms_application_info.set_module('TIMER_FUNCTIONS', NULL);
 
--
--
--
--
    IF ((s_trace_file_open + s_trace_file_days) < SYSDATE) THEN
      trace1('TIMER_FUNCTIONS: Ending tracefile');
      s_trace_file := NULL;
      s_trace_file_open := SYSDATE;
      EXECUTE IMMEDIATE 
        'ALTER SESSION SET tracefile_identifier="ra_' || 
                        TO_CHAR(s_trace_file_open, 'YYYYMMDDHH24MI') || '"'; 
    END IF;
 
--
--
--
    SELECT * INTO l_next_timer
        FROM timer_task
        WHERE next_execute = (SELECT MIN(next_execute) FROM timer_task) AND
              ROWNUM = 1;
 
--
--
--
--
    IF (l_next_timer.next_execute > SYSTIMESTAMP) THEN
      DBMS_LOCK.SLEEP(s_timer_loop_sleep);
 
--
      sys.kbrsi_icd.rsSetTrace;
 
--
--
--
      SELECT /*+ RESULT_CACHE */ value INTO l_sts
        FROM config
        WHERE (name = '_recovery_appliance_state');
 
      IF l_sts = 'OFF' THEN
         trace1('TIMER_FUNCTIONS: Exiting because recovery appliance shut down.');
         SYS.KBRSI_ICD.RSRUNSCHED; -- wake up other schedulers.
         RETURN;
      END IF;
 
--
--
--
--
--
--
--
      IF s_next_dead_scheduler_check <= SYSTIMESTAMP THEN
        s_next_dead_scheduler_check := 
                                SYSTIMESTAMP + NUMTODSINTERVAL(5, 'MINUTE');
        cleanup_dead_schedulers (p_restart => TRUE);
 
--
--
--
        make_amlocks();
        FOR t IN timer_cursor LOOP
          trace1('TIMER_FUNCTIONS: Starting timer process on instance ' ||
                                                            t.inst_name);
 
          BEGIN
            spawn_job ('RA$_TIMER_' || t.inst_number,
                       'dbms_ra_scheduler.timer_functions;',
                       t.inst_number,
                       NULL);
 
          EXCEPTION
            WHEN E_JOB_ALREADY_EXISTS THEN
              save_error;
              trace1 ('TIMER_FUNCTIONS: Timer session already active ' ||
                                   'for instance ' || t.inst_number);
              clear_error;
          END;
        END LOOP;
      END IF;
 
      CONTINUE;
    END IF;
 
--
--
--
    trace1('TIMER_FUNCTIONS: Current timer is: ' || l_next_timer.timer_type);
    dbms_application_info.set_module('TIMER_FUNCTIONS',
                                     l_next_timer.timer_type);
 
    CASE l_next_timer.timer_type
--
--
      WHEN TIMER_RELOAD_CONFIG THEN
        load_config;
        set_resumable_timeout;
        verify_timer_tasks;
 
--
--
      WHEN TIMER_VERIFY THEN
        verify_timer_tasks;
 
--
--
      WHEN TIMER_POLLING THEN
--
--
--
        SELECT COUNT(*) INTO l_count FROM task
          WHERE task_type = TASK_POLL
            AND param_num1 = l_next_timer.timer_location
            AND ROWNUM = 1;
 
        IF l_count = 0 THEN
          new_task_rec.task_type  := TASK_POLL;
          new_task_rec.flags      := 0;
          new_task_rec.param_num1 := l_next_timer.timer_location;
 
          new_task (new_task_rec);
        END IF;
 
--
--
      WHEN TIMER_HISTORY_PRUNE THEN
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
        DELETE FROM task_history
          WHERE completion_time < 
            (SYSTIMESTAMP-(s_history_partition_interval*s_history_retention));
        COMMIT;
        trace1('TIMER_FUNCTIONS: Deleted ' || SQL%ROWCOUNT || ' history rows');
 
        DELETE FROM error_log
          WHERE last_seen < (SYSTIMESTAMP -
                        (s_history_partition_interval*s_history_retention));
        COMMIT;
        trace1('TIMER_FUNCTIONS: Deleted ' || SQL%ROWCOUNT || ' error rows');
 
--
--
        DELETE FROM sbt_task_history sth
         WHERE (sth.failure_cnt > 0 OR sth.restore = 'Y')
           AND NOT EXISTS (SELECT 1 FROM task_history th
                            WHERE th.task_id = sth.task_id);
        COMMIT;
 
--
--
      WHEN TIMER_RM_INCOMPLETE_FILES THEN
--
--
--
        SELECT COUNT(*) INTO l_count FROM task
          WHERE task_type = TASK_RM_INCOMPLETE_FILES
            AND ROWNUM = 1;
 
        IF l_count = 0 THEN
          new_task_rec.task_type  := TASK_RM_INCOMPLETE_FILES;
          new_task_rec.flags      := 0;
 
          new_task (new_task_rec);
        END IF;
 
--
--
      WHEN TIMER_STORAGE_HISTOGRAM THEN
--
--
--
        SELECT COUNT(*) INTO l_count FROM task
          WHERE task_type = TASK_STORAGE_HISTOGRAM
            AND ROWNUM = 1;
 
        IF l_count = 0 THEN
          new_task_rec.task_type  := TASK_STORAGE_HISTOGRAM;
          new_task_rec.flags      := 0;
 
          new_task (new_task_rec);
        END IF;
 
--
--
      WHEN TIMER_STORAGE_MAINTENANCE THEN
          exec_timer_storage_maintenance;
 
--
--
      WHEN TIMER_TASK_MAINTENANCE THEN
          exec_timer_task_maintenance;
 
--
--
      WHEN TIMER_OBSOLETE_SBT THEN
--
--
--
        SELECT COUNT(*) INTO l_count FROM task
          WHERE task_type = TASK_OBSOLETE_SBT
            AND ROWNUM = 1;
 
        IF l_count = 0 THEN
          new_task_rec.task_type  := TASK_OBSOLETE_SBT;
          new_task_rec.flags      := 0;
 
          new_task (new_task_rec);
        END IF;
        
--
--
      WHEN TIMER_SET_RECONCILE_TIMER THEN
--
--
        trace1 ('TIMER_FUNCTIONS_SET_RECONCILE_TIMER: dbkey=' ||
                l_next_timer.param_num1);
        IF l_next_timer.param_num1 IS NULL THEN
          timer_task_upsert (TIMER_RECONCILE, NULL);
        ELSE
          set_reconcile_timer (l_next_timer.param_num1);
        END IF;
 
--
--
      WHEN TIMER_RECONCILE THEN
--
--
--
        BEGIN
            trace1 ('TIMER_FUNCTIONS_RECONCILE: Finding reconciles...');
            OPEN reconcile_cursor;
            LOOP
               FETCH reconcile_cursor INTO l_db_key;
               EXIT WHEN reconcile_cursor%NOTFOUND;
 
               trace1 ('TIMER_FUNCTIONS_RECONCILE: create TASK_RECONCILE ' ||
                       ' l_db_key=' || l_db_key);
 
               new_task_rec.task_type  := TASK_RECONCILE;
               new_task_rec.db_key     := l_db_key;
               new_task_rec.flags      := 0;
 
               new_task (new_task_rec);
               l_cnt := l_cnt + 1;
            END LOOP;
            CLOSE reconcile_cursor;
 
         EXCEPTION
            WHEN OTHERS THEN
               trace1 ('TIMER_FUNCTIONS_RECONCILE: EXCEPTION: sqlcode='
                       || SQLCODE);
               IF l_cnt = 0 THEN
                 NULL;
--
--
--
               END IF;
               save_error;
               CLOSE reconcile_cursor;
               RAISE;
        END;
 
        IF l_cnt = 0 THEN
--
--
--
--
--
--
          
--
--
          NULL;
        END IF;
 
--
--
--
--
        SELECT MAX(db_key) INTO l_db_key
          FROM odb 
          WHERE (next_reconcile IS NOT NULL) AND
                ((SYSTIMESTAMP - next_reconcile) >
                 (s_late_for_warning *  s_reconcile_long_interval));
 
        IF l_db_key IS NULL THEN
          fix_error (p_error_num => E_LATE_RECONCILE_NUM);
        ELSE
          log_error (p_errno => E_LATE_RECONCILE_NUM,
                     p_param1 => DBMS_RA_INT.DBKEY2NAME(l_db_key),
                     p_component => 'RECONCILE',
                     p_severity  => SEVERITY_WARNING);
        END IF;
 
--
--
      WHEN TIMER_SPAWN_SBT THEN
        BEGIN
          OPEN sbt_spawn_cursor;
          LOOP 
            FETCH sbt_spawn_cursor INTO l_count, l_libkey;
            EXIT WHEN sbt_spawn_cursor%NOTFOUND;
 
            IF (l_count = 0) THEN
              new_task_rec.task_type  := TASK_SPAWN_SBT;
              new_task_rec.flags      := 0;
              new_task_rec.param_num1 := l_libkey;
              new_task_rec.param_num2 := 0; -- forpurge
              new_task (new_task_rec);
            END IF;
          END LOOP;
          CLOSE sbt_spawn_cursor;
        EXCEPTION
          WHEN DUP_VAL_ON_INDEX THEN
            save_error;
            CLOSE sbt_spawn_cursor;
--
--
            IF (SQLERRM NOT LIKE '%TASK_SPAWN_SBT_I%') THEN
              RAISE;
            END IF;
            clear_error;
          WHEN OTHERS THEN
            save_error;
            CLOSE sbt_spawn_cursor;
            RAISE;
        END;
 
        BEGIN
          OPEN sbt_purge_cursor;
          LOOP 
            FETCH sbt_purge_cursor INTO l_count, l_libkey;
            EXIT WHEN sbt_purge_cursor%NOTFOUND;
 
            IF (l_count = 0) THEN
              new_task_rec.task_type  := TASK_SPAWN_SBT;
              new_task_rec.flags      := 0;
              new_task_rec.param_num1 := l_libkey;
              new_task_rec.param_num2 := 1; -- forpurge
              new_task (new_task_rec);
            END IF;
          END LOOP;
          CLOSE sbt_purge_cursor;
        EXCEPTION
          WHEN DUP_VAL_ON_INDEX THEN
            save_error;
            CLOSE sbt_purge_cursor;
--
--
            IF (SQLERRM NOT LIKE '%TASK_SPAWN_SBT_I%') THEN
              RAISE;
            END IF;
            clear_error;
          WHEN OTHERS THEN
            save_error;
            CLOSE sbt_purge_cursor;
            RAISE;
        END;
 
--
--
      WHEN TIMER_DB_STATS_REFRESH THEN
--
--
--
--
        SELECT COUNT(*) INTO l_count
          FROM task
          WHERE task_type = TASK_DB_STATS_REFRESH
            AND ROWNUM = 1;
 
        IF l_count = 0 THEN
          new_task_rec.task_type  := TASK_DB_STATS_REFRESH;
          new_task_rec.flags      := 0;
          new_task (new_task_rec);
        END IF;
 
--
--
      WHEN TIMER_RM_SBT_SESSION THEN
        DELETE FROM sbt_session
         WHERE systimestamp > (modtime + s_sbt_active_interval);
 
--
--
      ELSE
        trace1('TIMER_FUNCTIONS: Unknown Timer function : Type - ' || 
                l_next_timer.timer_type);
        log_error (p_errno     => E_BAD_TASK_TYPE_NUM,
                   p_param1    => 'TIMER TASK ' || 
                                  print(l_next_timer.timer_type),
                   p_component => 'TIMER',
                   p_severity  => SEVERITY_WARNING);
    END CASE;
 
--
--
--
    IF l_next_timer.timer_interval IS NULL THEN
      trace1('TIMER_FUNCTIONS: Deleting timer row location=' ||
             l_next_timer.timer_location ||
             ', type=' || l_next_timer.timer_type);
      DELETE FROM timer_task
        WHERE timer_type = l_next_timer.timer_type AND
              timer_location =  l_next_timer.timer_location;
    ELSE
      trace1('TIMER_FUNCTIONS: Rescheduling timer row');
      UPDATE timer_task SET next_execute = SYSTIMESTAMP + timer_interval
        WHERE timer_type = l_next_timer.timer_type AND
              timer_location =  l_next_timer.timer_location;
    END IF;
    COMMIT;
 
  END LOOP;
EXCEPTION
  WHEN E_ORA_600 THEN
    save_error;
--
--
--
    write_error (p_component => 'TIMER',
                 p_severity  => SEVERITY_INTERNAL);
    RAISE;
  WHEN OTHERS THEN
    save_error;
--
--
    log_error (p_errno => E_TIMER_EXIT_NUM,
               p_component => 'TIMER',
               p_severity  => SEVERITY_INTERNAL);
    RAISE;
END timer_functions;
 
 
--
--
--
--
--
PROCEDURE exec_timer_storage_maintenance IS
  l_count               NUMBER;
  l_freespace           NUMBER;
  l_sl_name             sl.sl_name%TYPE;
  l_db_key              NUMBER;
 
  new_task_rec          task%ROWTYPE;
 
  l_resource_wait_task_limit  NUMBER;
 
  l_last_optimize             TIMESTAMP WITH TIME ZONE;
  l_optimize_chunks_days      NUMBER;
  l_optimize_chunks_interval  DSINTERVAL_UNCONSTRAINED;
  l_optimize_late             DSINTERVAL_UNCONSTRAINED;
 
  l_validate_db_days          NUMBER;
  l_validate_db_interval      DSINTERVAL_UNCONSTRAINED;
 
  l_check_files_days          NUMBER;
  l_check_files_interval      DSINTERVAL_UNCONSTRAINED;
 
  l_crosscheck_db_days        NUMBER;
  l_crosscheck_db_interval    DSINTERVAL_UNCONSTRAINED;
 
BEGIN
--
--
--
  SELECT MAX(DECODE(name, '_resource_wait_task_limit', TO_NUMBER(value)))
       , MAX(DECODE(name, 'optimize_chunks_days',      TO_NUMBER(value)))
       , MAX(DECODE(name, 'validate_db_days',          TO_NUMBER(value)))
       , MAX(DECODE(name, 'check_files_days',          TO_NUMBER(value)))
       , MAX(DECODE(name, 'crosscheck_db_days',        TO_NUMBER(value)))
    INTO l_resource_wait_task_limit, l_optimize_chunks_days, 
         l_validate_db_days, l_check_files_days, l_crosscheck_db_days
    FROM config
   WHERE name IN ('_resource_wait_task_limit', 'optimize_chunks_days',
                  'validate_db_days', 'check_files_days','crosscheck_db_days');
 
--
--
--
--
--
--
--
  IF l_resource_wait_task_limit < MAX_RESOURCE_WAIT_PROCESSES THEN
    trace1('EXEC_TIMER_STORAGE_MAINTENANCE: ' ||
                              'No busy work when we are resource constrained');
    RETURN;
  END IF;
 
--
--
--
--
--
--
--
--
--
--
--
  FOR sl IN (SELECT sl_key, sl_freespace_goal
               FROM sl
              WHERE sl_hist_usage IS NOT NULL
                AND sl_space <> 0) LOOP
 
--
    l_freespace := DBMS_RA_STORAGE.FREESPACE(sl.sl_key) +  s_purging_reserve;
 
    trace1('TIMER_STORAGE_MAINTENANCE for sl ' || sl.sl_key ||
                             ' goal is ' || sl.sl_freespace_goal ||
                             ' freespace is ' || l_freespace);
 
--
    IF l_freespace < (sl.sl_freespace_goal * s_purge_threshold) THEN
--
      SELECT COUNT(*) INTO l_count
        FROM task
        WHERE (task_type = TASK_PURGE) AND
              (sl_key = sl.sl_key)
          AND ROWNUM = 1;
 
      IF l_count = 0 THEN
--
        new_task_rec.task_type  := TASK_PURGE;
        new_task_rec.sl_key     := sl.sl_key;
        new_task_rec.db_key     := NULL;
        new_task_rec.flags      := 0;
        new_task (new_task_rec);
      END IF;
    END IF;
  END LOOP;
 
--
--
--
--
--
--
  l_optimize_chunks_interval := NUMTODSINTERVAL(l_optimize_chunks_days, 'day');
 
  trace1 ('EXEC_TIMER_STORAGE_MAINTENANCE_OPTIMIZE: checking schedule' ||
                  ' optimize_chunks_days=' || l_optimize_chunks_days ||
                  ' optimize_chunks_interval=' ||
                  interval2secs(l_optimize_chunks_interval));
       
  FOR d IN (
           SELECT db_key
             FROM odb
            WHERE NVL((  last_optimize + l_optimize_chunks_interval)
                       , SYSTIMESTAMP)
                  <= SYSTIMESTAMP
              AND db_key NOT IN 
                       (
                       SELECT db_key 
                         FROM task
                        WHERE task_type IN (  TASK_OPTIMIZE_CHUNKS_DF
                                            , TASK_OPTIMIZE_CHUNKS
                                           )
                       )
           ) LOOP
    new_task_rec            := NULL;
    new_task_rec.task_type  := TASK_OPTIMIZE_CHUNKS;
    new_task_rec.flags      := 0;
    new_task_rec.db_key     := d.db_key;
 
    new_task (new_task_rec);
  END LOOP;
 
--
--
--
--
--
--
--
  l_optimize_late := s_late_for_warning *  l_optimize_chunks_interval;
  SELECT MAX(db_key) INTO l_db_key
    FROM odb
    WHERE (last_optimize + l_optimize_late < SYSTIMESTAMP)
       OR (
              NVL(prev_optimize,last_optimize)+l_optimize_late < last_optimize
          AND db_key IN (SELECT db_key 
                           FROM task
                           WHERE task_type = TASK_OPTIMIZE_CHUNKS_DF
                        )
          ); 
 
  IF l_db_key IS NULL THEN
    trace1 ('EXEC_TIMER_STORAGE_MAINTENANCE_OPTIMIZE: ' ||
                                                'fixing E_LATE_OPTIMIZE_NUM');
    fix_error (p_error_num => E_LATE_OPTIMIZE_NUM);
  ELSE
    trace1 ('EXEC_TIMER_STORAGE_MAINTENANCE_OPTIMIZE: ' ||
                                                'logging E_LATE_OPTIMIZE_NUM');
    log_error (p_errno => E_LATE_OPTIMIZE_NUM,
               p_component => 'OPTIMIZE',
               p_severity  => SEVERITY_WARNING);
  END IF;
 
--
--
--
--
--
  l_validate_db_interval := NUMTODSINTERVAL(l_validate_db_days,'day');
 
  trace1 ('EXEC_TIMER_STORAGE_MAINTENANCE_VALIDATE: checking schedule' ||
                  ' validate_db_days=' || l_validate_db_days ||
                  ' validate_db_interval=' ||
                  interval2secs(l_validate_db_interval));
 
  FOR v IN (SELECT o.db_key, task_id,
                   NVL(last_validate,
                       SYSTIMESTAMP - l_validate_db_interval) last_time
              FROM odb o
                   LEFT OUTER JOIN task t ON (o.db_key = t.db_key)
                                             AND (task_type = TASK_VALIDATE_DB)
              WHERE ((NVL(last_validate, SYSTIMESTAMP - l_validate_db_interval)
                     + l_validate_db_interval) <= SYSTIMESTAMP)
              ORDER BY NVL(last_validate,SYSTIMESTAMP)) LOOP
 
  trace1 ('EXEC_TIMER_STORAGE_MAINTENANCE_VALIDATE:' ||
                  ' v.db_key=' || v.db_key ||
                  ' v.task_id=' || v.task_id ||
                  ' v.last_time=' || TO_CHAR(v.last_time) ||
                  ' SYSTIMESTAMP=' || TO_CHAR(SYSTIMESTAMP));
 
    IF v.task_id IS NULL THEN
--
      trace1 ('EXEC_TIMER_STORAGE_MAINTENANCE: running TASK_VALIDATE_DB');
      
      new_task_rec            := NULL;
      new_task_rec.task_type  := TASK_VALIDATE_DB;
      new_task_rec.db_key     := v.db_key;
      new_task_rec.flags      := 0;
 
      new_task (new_task_rec);
    ELSE
      trace1 ('EXEC_TIMER_STORAGE_MAINTENANCE_VALIDATE: ' ||
                              'not running new TASK_VALIDATE_DB for odb ' ||
                              DBMS_RA_INT.DBKEY2NAME(v.db_key));
    END IF;
  END LOOP;
 
--
--
--
--
  SELECT MAX(db_key) INTO l_db_key
    FROM odb 
    WHERE last_validate + (s_late_for_warning *  l_validate_db_interval)
          <= SYSTIMESTAMP;
 
  IF l_db_key IS NULL THEN
    trace1 ('EXEC_TIMER_STORAGE_MAINTENANCE: fixing E_LATE_VALIDATE_NUM');
    fix_error (p_error_num => E_LATE_VALIDATE_NUM);
  ELSE
    trace1 ('EXEC_TIMER_STORAGE_MAINTENANCE: logging E_LATE_VALIDATE_NUM');
    log_error (p_errno => E_LATE_VALIDATE_NUM,
               p_component => 'VALIDATE',
               p_severity  => SEVERITY_WARNING);
  END IF;
 
--
--
--
--
--
  l_check_files_interval := NUMTODSINTERVAL(l_check_files_days,'day');
 
  trace1 ('EXEC_TIMER_STORAGE_MAINTENANCE_CHECKFILE: checking schedule' ||
          ' check_files_days=' || l_check_files_days ||
          ' check_files_interval=' ||
          interval2secs(l_check_files_interval));
       
  FOR c IN (SELECT s.sl_key, sl_name, task_id,
                   NVL(sl_last_check_files, 
                       SYSTIMESTAMP - l_check_files_interval)
              FROM sl s
                   LEFT OUTER JOIN task t ON (s.sl_key = t.sl_key)
                                             AND (task_type = TASK_CHECK_FILES)
              WHERE ((NVL(sl_last_check_files,
                          SYSTIMESTAMP - l_check_files_interval)
                      + l_check_files_interval) <= SYSTIMESTAMP)
                AND NVL(sl_space, 0) <> 0
                AND NOT EXISTS (SELECT 1 FROM config
                                WHERE name = 'disable_check_files')
              ORDER BY NVL(sl_last_check_files,SYSTIMESTAMP)) LOOP
 
    IF c.task_id IS NULL THEN
--
      trace1 ('EXEC_TIMER_STORAGE_MAINTENANCE_CHECKFILE: ' ||
              'running TASK_CHECK_FILES for sl ' ||
              TO_CHAR(c.sl_key));
      new_task_rec := NULL;
      new_task_rec.task_type  := TASK_CHECK_FILES;
      new_task_rec.sl_key     := c.sl_key;
      new_task_rec.flags      := 0;
      new_task_rec.param_num1 := 0;
 
      new_task (new_task_rec);
    ELSE
      trace1 ('EXEC_TIMER_STORAGE_MAINTENANCE_CHECKFILE: ' ||
              'not running new TASK_CHECK_FILES for sl ' ||
              TO_CHAR(c.sl_key));
    END IF;
          END LOOP;
 
--
--
--
--
  SELECT MAX(sl_name) INTO l_sl_name
    FROM sl
    WHERE sl_space > 0
      AND sl_last_check_files + (s_late_for_warning *  l_check_files_interval) 
          <= SYSTIMESTAMP;
 
  IF l_sl_name IS NULL THEN
    trace1 ('EXEC_TIMER_STORAGE_MAINTENANCE: fixing E_LATE_CHECKFILES_NUM');
    fix_error (p_error_num => E_LATE_CHECKFILES_NUM);
  ELSE
    trace1 ('EXEC_TIMER_STORAGE_MAINTENANCE: logging E_LATE_CHECKFILES_NUM');
    log_error (p_errno => E_LATE_CHECKFILES_NUM,
               p_component => 'CHECK_FILES',
               p_severity  => SEVERITY_WARNING);
  END IF;
 
--
--
--
--
--
  l_crosscheck_db_interval := NUMTODSINTERVAL(l_crosscheck_db_days, 'day');
 
  trace1 ('EXEC_TIMER_STORAGE_MAINTENANCE_CROSSCHECK: checking schedule' ||
          ' crosscheck_db_days=' || l_crosscheck_db_days ||
          ' crosscheck_db_interval=' ||
                                      interval2secs(l_crosscheck_db_interval));
 
  FOR cc IN (SELECT db_key, last_crosscheck
              FROM odb
              WHERE ((NVL(last_crosscheck,
                          SYSTIMESTAMP - l_crosscheck_db_interval)
                       + l_crosscheck_db_interval) <= SYSTIMESTAMP)
                AND NOT EXISTS (SELECT 1 FROM task
                                WHERE task_type = TASK_CROSSCHECK_DB
                                  AND task.db_key = odb.db_key)
              ORDER BY last_crosscheck DESC) LOOP
 
    trace1 ('EXEC_TIMER_STORAGE_MAINTENANCE_CROSSCHECK: ' ||
            'running TASK_CROSSCHECK_DB cc.db_key=' || cc.db_key ||
            ' cc.last_crosscheck=' ||
            TO_CHAR(cc.last_crosscheck,'DD-MM-YYYY HH:MI:SS') ||
            ' SYSTIMESTAMP=' || TO_CHAR(SYSTIMESTAMP,'DD-MM-YYYY HH:MI:SS'));
 
    new_task_rec.task_type  := TASK_CROSSCHECK_DB;
    new_task_rec.db_key     := cc.db_key;
    new_task_rec.flags      := 0;
 
    new_task (new_task_rec);
  END LOOP;
 
--
--
--
--
  SELECT MAX(db_key) INTO l_db_key
    FROM odb 
    WHERE last_crosscheck + (s_late_for_warning * l_crosscheck_db_interval) 
          <= SYSTIMESTAMP;
 
  IF l_db_key IS NULL THEN
    trace1 ('EXEC_TIMER_STORAGE_MAINTENANCE: fixing E_LATE_CROSSCHECK_NUM');
    fix_error (p_error_num => E_LATE_CROSSCHECK_NUM);
  ELSE
    trace1 ('EXEC_TIMER_STORAGE_MAINTENANCE: logging E_LATE_CROSSCHECK_NUM');
    log_error (p_errno => E_LATE_CROSSCHECK_NUM,
               p_component => 'CROSSCHECK',
               p_severity  => SEVERITY_WARNING);
  END IF;
END exec_timer_storage_maintenance;
 
--
--
--
--
--
--
--
PROCEDURE exec_timer_task_maintenance IS
  l_count               NUMBER;
  l_last_interrupt      TIMESTAMP WITH TIME ZONE;
  l_last_year           TIMESTAMP WITH TIME ZONE 
                                := SYSTIMESTAMP - NUMTODSINTERVAL(365,'DAY');
  l_concurrent_tasks    NUMBER;
  l_max_concurrent_tasks NUMBER;
  l_status              BINARY_INTEGER;
  l_message             VARCHAR2(256);
  l_timestamp           TIMESTAMP WITH TIME ZONE;
 
BEGIN
--
--
--
--
--
--
--
  FOR d IN (SELECT db_key, wait_space FROM odb p
            WHERE (wait_space > used_space OR
                   wait_space IS NULL)
              AND EXISTS (SELECT 1 FROM task t
                          WHERE t.db_key = p.db_key
                          AND pending_interrupt = SPACE_PSEUDO_TASK))
  LOOP
--
    IF d.wait_space IS NOT NULL THEN
      BEGIN
        DBMS_RA_STORAGE.LOCK_DB (d.db_key);
        UPDATE odb SET wait_space = NULL WHERE db_key = d.db_key;
        COMMIT;
        DBMS_RA_STORAGE.UNLOCK_DB (d.db_key);
      EXCEPTION
        WHEN OTHERS THEN
          save_error;
          DBMS_RA_STORAGE.UNLOCK_DB (d.db_key);
          RAISE;
      END;
    END IF;
 
    release_blocked_tasks(SPACE_PSEUDO_TASK, d.db_key);
  END LOOP;
 
--
--
--
--
--
--
--
  release_blocked_tasks(OPT_DF_PSEUDO_TASK);
 
--
--
--
--
--
--
--
  release_blocked_tasks(SERVLET_PSEUDO_TASK);
 
--
--
--
--
--
--
--
  SELECT COUNT(*) INTO l_count FROM sbt_lib_desc WHERE status = 'R';
  IF l_count > 0 THEN
    release_blocked_tasks(LIBRARY_PSEUDO_TASK);
  END IF;
 
--
--
--
--
--
--
--
--
  SELECT NVL(MAX(last_interrupt_time), l_last_year), COUNT(*) 
    INTO l_last_interrupt, l_count
    FROM task
   WHERE state = STATE_TASK_WAIT
     AND pending_interrupt = RESOURCE_PSEUDO_TASK;
 
  trace1('EXEC_TIMER_TASK_MAINTENANCE: RESOURCE ' ||
                                      ' count=' || l_count ||
                                      ' last_interrupt=' || l_last_interrupt);
 
  IF l_count <> 0 THEN
--
--
--
--
--
    IF NOT s_resource_wait_active THEN
      trace1('EXEC_TIMER_TASK_MAINTENANCE: Entering resource wait state');
      s_resource_wait_active := TRUE;
 
--
--
--
--
--
      s_resource_wait_last_alter := l_last_interrupt;
 
--
--
--
--
--
      SYS.KBRSI_ICD.RSSCHEDLOCK (waitforwork => 0);
 
      UPDATE task SET pending_interrupt = RESOURCE_PSEUDO_TASK,
                      state = CASE state
                                WHEN STATE_EXECUTABLE THEN STATE_TASK_WAIT
                                ELSE state
                                END
       WHERE priority > PRIO_MIN_BUSYWORK;
      COMMIT;
 
      SYS.KBRSI_ICD.RSSCHEDUNLOCK;
 
      trace1('EXEC_TIMER_TASK_MAINTENANCE: Stuck it to ' || SQL%ROWCOUNT ||
                                ' busywork tasks.');
    ELSE
      s_resource_wait_last_alter := GREATEST (s_resource_wait_last_alter,
                                              l_last_interrupt);
    END IF;
 
--
--
--
--
    IF (SYSTIMESTAMP - s_resource_wait_last_alter) > 
       NUMTODSINTERVAL(s_resource_wait_timeout, 'day') THEN
      UPDATE config SET value = ROUND(value * s_resource_wait_relax_rate)
        WHERE name = '_resource_wait_task_limit';
      COMMIT;
 
      s_resource_wait_last_alter := SYSTIMESTAMP;
    END IF;
 
--
--
--
--
    SELECT COUNT(*) INTO l_concurrent_tasks
      FROM sessions
     WHERE current_task IS NOT NULL;
 
    SELECT TO_NUMBER(value) INTO l_max_concurrent_tasks
      FROM config
     WHERE name = '_resource_wait_task_limit';
 
    trace1('EXEC_TIMER_TASK_MAINTENANCE: ' ||
                      ' l_concurrent_tasks=' || l_concurrent_tasks ||
                      '; l_max_concurrent_tasks=' || l_max_concurrent_tasks);
 
--
--
--
--
--
--
    IF ((SYSTIMESTAMP - l_last_interrupt)
         > NUMTODSINTERVAL(s_resource_wait_timeout, 'DAY'))
       AND (l_max_concurrent_tasks > l_concurrent_tasks) THEN
 
      SYS.KBRSI_ICD.RSSCHEDLOCK (waitforwork => 0);
 
      BEGIN
        FOR t IN (SELECT task_id
                    FROM task
                   WHERE state = STATE_TASK_WAIT
                     AND pending_interrupt = RESOURCE_PSEUDO_TASK
                   ORDER BY priority, task_id) LOOP
 
          EXIT WHEN l_concurrent_tasks >= l_max_concurrent_tasks;
 
--
--
--
          UPDATE task
            SET pending_interrupt = NULL,
                state = STATE_EXECUTABLE
            WHERE task_id = t.task_id;
 
          l_concurrent_tasks := l_concurrent_tasks + 1;
 
          trace1('EXEC_TIMER_TASK_MAINTENANCE: ' ||
                        'Released resource waiting task_id ' || t.task_id);
 
        END LOOP;
 
      EXCEPTION
        WHEN OTHERS THEN
          save_error;
          COMMIT;
          SYS.KBRSI_ICD.RSSCHEDUNLOCK(nomorejobs => 0);
          RAISE;
      END;
 
      COMMIT;
 
--
--
--
--
      IF (l_max_concurrent_tasks > l_concurrent_tasks) THEN
        trace1('EXEC_TIMER_TASK_MAINTENANCE: Leaving Resource Wait State');
 
--
--
--
        l_status := UTL_LMS.GET_MESSAGE(errnum => -E_END_RESOURCE_WAIT_NUM,
                                        product => 'rdbms',
                                        facility => 'ora',
                                        language => NULL,
                                        message => l_message);
 
        IF l_status = 0 THEN
          SYS.DBMS_SYSTEM.KSDWRT(SYS.DBMS_SYSTEM.ALERT_FILE, l_message);
        END IF; 
    
        UPDATE config SET value = MAX_RESOURCE_WAIT_PROCESSES
         WHERE name = '_resource_wait_task_limit';
        COMMIT;
 
        fix_error (p_error_num => E_RESOURCE_ERROR_NUM);
        s_resource_wait_active := FALSE;
      END IF;
      SYS.KBRSI_ICD.RSSCHEDUNLOCK(nomorejobs => 0);
 
    END IF;
  END IF;
 
--
--
--
--
--
--
  SELECT COUNT(*) INTO l_count
    FROM task
   WHERE state = STATE_TASK_WAIT
     AND pending_interrupt = POOL_FULL_PSEUDO_TASK;
 
  trace1('EXEC_TIMER_TASK_MAINTENANCE: POOL_FULL ' ||
                                      ' count=' || l_count);
 
  IF l_count = 0 THEN
    fix_error (p_error_num => E_POOL_FULL_NUM);
    COMMIT;
  ELSE
--
--
--
    IF s_pool_tablespace IS NULL THEN
      SELECT tablespace_name into s_pool_tablespace
        FROM user_segments 
       WHERE segment_name IN ('PLANS', 'PLANS_DETAILS', 'CHUNKS', 'BLOCKS')
         AND tablespace_name IS NOT NULL
         AND ROWNUM = 1;
    END IF;
 
    IF s_pool_tablespace IS NOT NULL THEN
--
--
--
--
      FOR r in (
        SELECT fs.freespace/ts.totalspace freespace_ratio
          FROM (SELECT SUM(bytes) totalspace 
                  FROM dba_data_files 
                 WHERE tablespace_name = s_pool_tablespace
                 GROUP BY tablespace_name) ts, 
               (SELECT NVL(SUM(bytes), 0) freespace 
                  FROM dba_free_space 
                 WHERE tablespace_name = s_pool_tablespace) fs) LOOP
 
--
--
--
--
--
--
--
--
--
--
        IF r.freespace_ratio > s_ra_pool_freespace_threshold THEN
          l_count := s_ra_pool_full_free_count;
        ELSE
          l_count := 1;
        END IF;
 
        trace1('EXEC_TIMER_TASK_MAINTENANCE: FULL_POOL_PSEUDO_TASK' ||
                          ': freespace_ratio=' || r.freespace_ratio ||
                          '; count=' || l_count);
 
      END LOOP;
 
--
--
--
--
--
--
      FOR t IN (SELECT task_id
                  FROM task
                 WHERE state = STATE_TASK_WAIT
                   AND pending_interrupt = POOL_FULL_PSEUDO_TASK
                 ORDER BY priority, task_id) LOOP
 
--
--
--
        UPDATE task
           SET pending_interrupt = NULL,
               state = STATE_EXECUTABLE
         WHERE task_id = t.task_id;
 
        trace1('EXEC_TIMER_TASK_MAINTENANCE: ' ||
                          'Released pool waiting task_id ' || t.task_id);
 
        l_count := l_count - 1;
        EXIT WHEN l_count <= 0;
      END LOOP;
      COMMIT;
    END IF;
  END IF;
 
--
--
--
--
--
--
  l_timestamp := SYSTIMESTAMP;
 
  FOR o in (SELECT db_key
              FROM task
             WHERE task_type = TASK_INDEX_BACKUP
               AND state = STATE_ORDERING_WAIT
               AND (SYSTIMESTAMP - last_execute_time) > 
                               NUMTODSINTERVAL(s_ordering_wait_timeout, 'DAY')
             GROUP BY db_key) LOOP
 
    trace1('EXEC_TIMER_TASK_MAINTENANCE: Ordering wait timeout on db: ' ||
                                                                     o.db_key);
    log_error (p_errno     => E_ORDERING_WAIT_NUM,
               p_param1    => DBMS_RA_INT.DBKEY2NAME(o.db_key),
               p_param2    => s_ordering_wait_timeout,
               p_component => 'INDEX_BACKUP',
               p_severity  => SEVERITY_WARNING,
               p_db_key    => o.db_key);
  END LOOP;
 
--
--
--
  fix_error (p_error_num => E_ORDERING_WAIT_NUM,
             p_timestamp => l_timestamp);
 
--
--
--
--
--
--
--
--
--
--
--
--
  SYS.KBRSI_ICD.RSSCHEDLOCK (waitforwork => 0);
 
  UPDATE task SET state = STATE_CANCEL
   WHERE execute_inst_id IS NOT NULL
     AND task_type IN (TASK_RESTORE, TASK_RESTORE_SBT)
     AND state NOT IN (STATE_RUNNING, STATE_CANCELING)
     AND NOT EXISTS (SELECT 1 FROM sys.rai_active_instances i
                       WHERE task.execute_inst_id = i.inst_number);
  trace1('EXEC_TIMER_TASK_MAINTENANCE: Canceled ' || SQL%ROWCOUNT || 
                                                                ' task(s).');
  COMMIT;   
  SYS.KBRSI_ICD.RSSCHEDUNLOCK;
END exec_timer_task_maintenance;
 
--
--
--
--
--
--
--
--
--
--
PROCEDURE queue_set_reconcile_timer (p_db_key IN NUMBER) IS
  l_timer_task          timer_task%ROWTYPE;
BEGIN
 
  trace1 ('QUEUE_SET_RECONCILE_TIMER: p_db_key=' || p_db_key);
--
--
--
--
--
  trace1 ('QUEUE_SET_RECONCILE_TIMER_TASK');
 
  l_timer_task.timer_type     := TIMER_SET_RECONCILE_TIMER;
  l_timer_task.timer_location := rai_sq.nextval;
  l_timer_task.flags          := 0;
  l_timer_task.param_num1     := p_db_key;
  l_timer_task.next_execute   := SYSTIMESTAMP-100;
  l_timer_task.timer_interval := NULL;
 
  INSERT INTO timer_task VALUES l_timer_task;
  COMMIT;
  
END queue_set_reconcile_timer;
 
 
 
--
--
--
--
--
--
--
--
--
--
--
--
 
PROCEDURE set_reconcile_timer (p_db_key IN NUMBER)
IS
 
  l_timer_task              timer_task%ROWTYPE;
  l_count                   NUMBER;
  l_last_bp_key             NUMBER;
  l_base_time               timestamp;    -- Start time to base reconcile on
  l_next_run_time_this_odb  timestamp;    -- new next run time for this odb
  l_next_run_time_all_odbs  timestamp;    -- new next run time for all odb's
  l_next_reconcile_time     timestamp;    -- next scheduled time.
  l_last_reconcile_time     timestamp;    -- last reconciled time.
  l_last_rep_time           timestamp;    -- finish time of last replication
  l_set_long_interval       BOOLEAN := FALSE;
  l_set_now_reconcile       BOOLEAN := FALSE;
  l_task_rec                task%ROWTYPE; -- used for doing initial replication
  l_success                 BOOLEAN;
  l_num_rec                 NUMBER;
  l_exp_rec_cnt             NUMBER;
 
BEGIN
 
  trace1 ('SET_RECONCILE_TIMER: p_db_key=' || p_db_key);
 
--
--
--
--
  IF p_db_key IS NOT NULL THEN
    SELECT count(*) INTO l_count FROM odb where db_key = p_db_key
        AND db_state IS NULL;
    IF l_count = 0 THEN
      trace1('SET_RECONCILE_TIMER: Completing reconcile_timer.  odb no ' ||
             ' longer exists or is being deleted p_db_key=' || p_db_key);
      queue_set_reconcile_timer(NULL);
      RETURN;
    END IF;
  END IF;
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
 
  SELECT last_replication, next_reconcile, last_reconcile
    INTO l_last_rep_time, l_next_reconcile_time, l_last_reconcile_time
    FROM odb
    WHERE db_key = p_db_key;
 
  l_base_time := SYSTIMESTAMP;
 
  IF l_last_reconcile_time IS NULL THEN
--
    l_set_now_reconcile := TRUE;
  ELSIF l_last_rep_time = 0 THEN
--
    l_set_long_interval := TRUE;
  ELSE
--
 
--
--
--
    IF l_last_rep_time <=
        (l_base_time - (2*s_reconcile_short_interval)) THEN
      l_set_long_interval := TRUE;
    ELSE
      IF l_next_reconcile_time <=
            (l_last_rep_time + (2 * s_reconcile_short_interval)) THEN
        l_base_time := l_last_rep_time + s_reconcile_short_interval;
      ELSE
        l_base_time := l_last_rep_time;
      END IF;
      l_set_long_interval := FALSE;
    END IF;
  END IF;
 
 
--
--
--
--
--
--
--
  IF l_set_now_reconcile = TRUE THEN
    l_next_run_time_this_odb := SYSTIMESTAMP - 10;
  ELSIF l_set_long_interval = TRUE THEN
    IF s_reconcile_long_interval = 0 THEN
      l_next_run_time_this_odb := NULL;
    ELSE
      l_next_run_time_this_odb := l_base_time + s_reconcile_long_interval;
    END IF;
  ELSE
    IF s_reconcile_short_interval = 0 THEN
      l_next_run_time_this_odb := NULL;
    ELSE
      l_next_run_time_this_odb := l_base_time + s_reconcile_short_interval;
    END IF;
 
  END IF;
 
--
--
--
  IF l_next_run_time_this_odb IS NOT NULL AND
    l_next_reconcile_time IS NOT NULL AND
    l_next_reconcile_time < l_next_run_time_this_odb AND
    l_next_reconcile_time > l_last_reconcile_time
  THEN
    l_next_run_time_this_odb := l_next_reconcile_time;
    trace1 ('SET_RECONCILE_TIMER: Modifying next run time to ' ||
      l_next_run_time_this_odb);
  END IF;
 
  trace1 ('SET_RECONCILE_TIMER: ' ||
          ' l_base_time='        || l_base_time ||
          ', l_next_run_time='  || l_next_run_time_this_odb ||
          ', l_last_replication_time=' || l_last_rep_time ||
          ', pre-existing_reconcile_time=' || l_next_reconcile_time);
 
 
--
--
--
--
--
--
--
 
--
  SELECT count(*) INTO l_count
    FROM timer_task
    WHERE timer_type = TIMER_RECONCILE;
 
 
--
--
--
    trace1 ('SET_RECONCILE_TIMER: ' ||
          ' Update next_reconcile to =' || l_next_run_time_this_odb);
    UPDATE odb
      SET next_reconcile = l_next_run_time_this_odb
      WHERE db_key = p_db_key;
 
--
--
  SELECT MIN(next_reconcile) INTO l_next_run_time_all_odbs
    FROM odb;
 
--
--
  IF l_next_run_time_all_odbs IS NOT NULL THEN
    IF l_count = 0 THEN
--
--
--
--
      l_timer_task.timer_type     := TIMER_RECONCILE;
      l_timer_task.timer_location := rai_sq.nextval;
      l_timer_task.flags          := 0;
      l_timer_task.next_execute   := l_next_run_time_all_odbs;
      l_timer_task.timer_interval := NULL;
 
      INSERT INTO timer_task VALUES l_timer_task;
 
      trace1 ('SET_RECONCILE_TIMER: add new reconcile timer.  ' ||
              ' timer_location='  || l_timer_task.timer_location ||
              ', next_run_time='   || l_timer_task.next_execute);
    ELSE
--
--
      SELECT * INTO l_timer_task
        FROM timer_task
        WHERE timer_type = TIMER_RECONCILE;
 
--
--
      trace1 ('SET_RECONCILE_TIMER: updating reconcile timer.  ' ||
              ' next_run_time='   || l_timer_task.next_execute);
 
      UPDATE timer_task
        SET timer_interval = NULL,
        flags = 0,
        next_execute = l_next_run_time_all_odbs,
        timer_location = rai_sq.nextval
        WHERE timer_type = TIMER_RECONCILE;
    END IF;
  ELSE
--
--
    trace1('SET_RECONCILE_TIMER: Deleting reconcile timer.  No replicating db');
    DELETE FROM timer_task WHERE timer_type = TIMER_RECONCILE;
  END IF;
 
  COMMIT;
 
EXCEPTION
  WHEN OTHERS THEN
    trace1 ('SET_RECONCILE_TIMER: EXCEPTION - Skipping timer setup - sqlcode='||
            SQLCODE);
    save_error;
--
    s_setup_next_reconcile := TRUE;
    COMMIT;
    RAISE;
 
END set_reconcile_timer;
 
--
--
--
--
PROCEDURE reset_reconcile_timer IS
BEGIN
  queue_set_reconcile_timer (NULL);
END reset_reconcile_timer;
 
--
--
--
--
--
--
 
PROCEDURE enqueue_timer_reload_config IS
  l_timer_task          timer_task%ROWTYPE;
 
BEGIN
--
--
--
--
  trace1 ('ENQUEUE_TIMER_RELOAD_CONFIG');
  l_timer_task.timer_type     := TIMER_RELOAD_CONFIG;
  l_timer_task.timer_location := rai_sq.nextval;
  l_timer_task.flags          := 0;
  l_timer_task.next_execute   := SYSTIMESTAMP-101;
  l_timer_task.timer_interval := NULL;
 
  INSERT INTO timer_task VALUES l_timer_task;
  COMMIT;
 
END enqueue_timer_reload_config;
 
--
--
--
--
--
--
--
--
 
PROCEDURE enqueue_verify_timer_task IS
  PRAGMA AUTONOMOUS_TRANSACTION;
  l_timer_task          timer_task%ROWTYPE;
 
BEGIN
--
--
--
--
  trace1 ('ENQUEUE_VERIFY_TIMER_TASK');
  l_timer_task.timer_type     := TIMER_VERIFY;
  l_timer_task.timer_location := rai_sq.nextval;
  l_timer_task.flags          := 0;
  l_timer_task.next_execute   := SYSTIMESTAMP-100;
  l_timer_task.timer_interval := NULL;
 
  INSERT INTO timer_task VALUES l_timer_task;
  COMMIT;
 
END enqueue_verify_timer_task;
 
--
--
--
--
--
--
 
PROCEDURE verify_timer_tasks IS
 
  CURSOR polling_areas IS
    SELECT NVL(tt.timer_location,-1), p.poll_key, p.poll_freq
      FROM poll p
           LEFT OUTER JOIN timer_task tt ON
                           (tt.timer_type = TIMER_POLLING) AND
                           (tt.timer_location = p.poll_key)
      WHERE ((tt.timer_location IS NULL) OR
             (p.poll_freq  != tt.timer_interval));
  l_newrowflag          NUMBER;
  l_timer_location      NUMBER;
  l_timer_interval      DSINTERVAL_UNCONSTRAINED;
 
BEGIN
  trace1('VERIFY_TIMER_TASKS');
 
--
--
--
  FOR t IN (SELECT tt.timer_location poll_key
              FROM timer_task tt
              WHERE (tt.timer_type = TIMER_POLLING)
                AND NOT EXISTS (SELECT 1
                                  FROM poll p
                                  WHERE tt.timer_location = p.poll_key)
                AND NOT EXISTS (SELECT 1
                                  FROM task
                                  WHERE task.task_type = TASK_POLL
                                    AND tt.timer_location = task.param_num1))
    LOOP
      trace1 ('VERIFY_TIMER_TASKS: deleting old poll ' || t.poll_key);
      DELETE polling_history WHERE poll_key = t.poll_key;
      DELETE timer_task tt WHERE tt.timer_location = t.poll_key;
      COMMIT;
    END LOOP;
 
--
--
--
  OPEN polling_areas;
  LOOP
    FETCH polling_areas
       INTO l_newrowflag, l_timer_location, l_timer_interval;
    EXIT WHEN polling_areas%NOTFOUND;
 
--
--
    l_timer_interval := LEAST (l_timer_interval, NUMTODSINTERVAL(99, 'day'));
 
    IF (l_newrowflag = -1) THEN
      trace1('VERIFY_TIMER_TASKS: new polling location ' || l_timer_location);
      INSERT INTO timer_task (timer_type,      timer_location,     flags,
                                  next_execute, timer_interval)
                          VALUES (TIMER_POLLING, l_timer_location, 0,
                                  SYSTIMESTAMP,  l_timer_interval);
    ELSE
      trace1('VERIFY_TIMER_TASKS: polling location changed '
                                                         || l_timer_location);
      UPDATE timer_task
         SET next_execute = 
                    CASE 
                      WHEN l_timer_interval < timer_interval THEN SYSTIMESTAMP
                      ELSE next_execute
                    END,
             timer_interval = l_timer_interval
       WHERE (timer_type = TIMER_POLLING) 
         AND (timer_location = l_timer_location);
    END IF;
  END LOOP;
  CLOSE polling_areas;
 
--
--
--
  timer_task_upsert (TIMER_HISTORY_PRUNE, s_history_partition_interval/2);
 
--
--
--
  timer_task_upsert(TIMER_RM_INCOMPLETE_FILES, s_rm_incomplete_files_interval);
 
--
--
--
  timer_task_upsert(TIMER_STORAGE_HISTOGRAM, s_histogram_slot_interval);
 
--
--
--
  timer_task_upsert(TIMER_STORAGE_MAINTENANCE, s_storage_maintenance_interval);
 
--
--
--
--
  timer_task_upsert(TIMER_TASK_MAINTENANCE, s_task_maintenance_interval);
 
--
--
--
--
  timer_task_upsert(TIMER_OBSOLETE_SBT, s_obsolete_sbt_interval);
 
--
--
--
--
  reset_reconcile_timer();
 
--
--
--
  timer_task_upsert(TIMER_SPAWN_SBT, s_check_sbtsched_interval);
   
--
--
--
  timer_task_upsert(TIMER_DB_STATS_REFRESH, s_db_stats_refresh_interval);
 
--
--
--
  timer_task_upsert(TIMER_RM_SBT_SESSION, s_sbt_active_interval/2);
   
  COMMIT;
 
END verify_timer_tasks;
 
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE timer_task_upsert (p_type IN NUMBER, 
                             p_interval IN DSINTERVAL_UNCONSTRAINED) IS
BEGIN
  trace1('TIMER_TASK_UPSERT: Type=' || p_type || 
                           ';  new interval=' || p_interval);
--
--
--
--
  MERGE INTO timer_task USING dual ON (timer_type = p_type)
    WHEN NOT MATCHED THEN
      INSERT   (timer_type, timer_location, flags, 
                next_execute, timer_interval)
        VALUES (p_type, 0, NULL,
                SYSTIMESTAMP, p_interval)
    WHEN MATCHED THEN
      UPDATE SET next_execute = 
                        CASE 
                          WHEN p_interval < timer_interval THEN SYSTIMESTAMP
                          ELSE next_execute
                        END,
                 timer_interval = p_interval;
 
END timer_task_upsert;
 
--
--
--
--
--
--
--
--
 
PROCEDURE cleanup_dead_schedulers (p_restart BOOLEAN) IS
 
  CURSOR dead_schedulers IS
    SELECT *
      FROM sessions s
      WHERE NOT EXISTS (SELECT 1
                          FROM sys.rai_active_sessions a
                          WHERE a.inst_id = s.instance_id
                            AND a.audsid = s.audsid
                            AND a.sid = s.sid
                            AND a.serial# = s.serial#
                            AND a.logon_time = s.logon_time);
 
  CURSOR dead_sbt_schedulers IS
    SELECT s.purpose, s.purpose_param1
      FROM sessions s
      WHERE NOT EXISTS (SELECT 1
                          FROM sys.rai_active_sessions a
                          WHERE a.inst_id = s.instance_id
                            AND a.audsid = s.audsid
                            AND a.sid = s.sid
                            AND a.serial# = s.serial#
                            AND a.logon_time = s.logon_time)
        AND s.purpose IN (TASK_BACKUP_SBT, TASK_PURGE_SBT)
        AND s.current_task IS NOT NULL
   GROUP BY s.purpose, s.purpose_param1;
 
  type numTab_t is table of number index by binary_integer;
  sbt_purpose numTab_t;
  sbt_lib_key numTab_t;
 
--
--
--
--
--
  CURSOR missing_schedulers IS
    SELECT i.inst_number,
           NVL(sc.all_session_count,0) all_session_count,
           NVL(sc.restricted_session_count,0) restricted_session_count
      FROM sys.rai_active_instances i
      LEFT OUTER JOIN (SELECT NVL(jobs.instance_id,1) instance_id, 
                              COUNT(*) all_session_count,
                              COUNT(se.purpose_param1) restricted_session_count
                         FROM TABLE(CAST(s_amjobs AS rai_jobs_table_type)) jobs
                         LEFT OUTER JOIN sessions se 
                           ON (se.instance_id = jobs.instance_id 
                               AND se.job_name = jobs.job_name)
                         GROUP BY jobs.instance_id) sc
      ON i.inst_number = sc.instance_id;
  l_task_rec       task%ROWTYPE;
  l_flags          NUMBER;
  l_error_count    NUMBER;
  l_purge_reserve  NUMBER;
  l_db_key         NUMBER;
  l_session_info_id NUMBER;
  l_restrictions   NUMBER;
  l_sched_error#   NUMBER;
  l_sched_log_id   NUMBER;
  l_sched_additional_info VARCHAR2(4000);
  l_sched_status   VARCHAR2(30);
  l_sched_log_date TIMESTAMP WITH TIME ZONE;
  l_new_sessions   NUMBER;
 
BEGIN
  trace1('CLEANUP_DEAD_SCHEDULERS');
 
--
--
--
  OPEN dead_sbt_schedulers;
  FETCH dead_sbt_schedulers BULK COLLECT INTO sbt_purpose, sbt_lib_key;
  CLOSE dead_sbt_schedulers;
 
--
--
--
  FOR ds IN dead_schedulers LOOP
 
    l_session_info_id := CASE WHEN ds.current_task IS NULL
                              THEN NULL
                              ELSE rai_sq.nextval END;
 
    IF (ds.purpose IS NOT NULL) AND (ds.current_task IS NULL) THEN
      trace1('CLEANUP_DEAD_SCHEDULERS: Scheduler ' || 
              ds.serial# || '.' || ds.ba_session_id ||
             ' of type ' || tasktype2name(ds.purpose) ||
             ' exited normally');
    ELSE
      trace1('CLEANUP_DEAD_SCHEDULERS: Scheduler ' || 
              ds.serial# || '.' || ds.ba_session_id ||
               ' with OS PID ' || ds.spid ||
               ' died while processing task id ' ||
                 print(ds.current_task));
 
--
--
--
--
      SYS.KBRSI_ICD.RSSCHEDLOCK (waitforwork => 0);
 
--
--
--
--
--
      BEGIN
        SELECT * INTO l_task_rec
          FROM task 
          WHERE task_id = ds.current_task
            AND ba_session_id = ds.ba_session_id;
      EXCEPTION
        WHEN NO_DATA_FOUND THEN
          l_task_rec := NULL;
      END;
 
--
--
--
      IF l_task_rec.task_id IS NOT NULL THEN
--
--
--
--
        IF l_task_rec.task_type IN (TASK_RESTORE, TASK_RESTORE_SBT) THEN
          release_restore_wait (ds.instance_id);
        END IF;
 
--
--
--
--
--
--
--
        SELECT flags INTO l_flags
          FROM task
          WHERE task_id = ds.current_task;
 
        IF BITAND (l_flags, TASKS_CHUNK_CACHE_ACTIVE) <> 0 THEN
          DBMS_RA_STORAGE.FREE_TASK_STORAGE (ds.current_task);
        END IF;
 
--
--
--
--
--
        UPDATE task
          SET ba_session_id = NULL,
              state = CASE l_task_rec.state
                        WHEN STATE_CANCELING THEN STATE_CANCEL
                        ELSE STATE_EXECUTABLE
                      END,
              error_count = NVL(error_count,0) + 1
          WHERE task_id = ds.current_task
          RETURNING flags, error_count, purge_reserve, db_key
               INTO l_flags, l_error_count, l_purge_reserve, l_db_key;
 
        trace1 ('CLEANUP_DEAD_SCHEDULERS:  Task ' ||  ds.current_task ||
                ' has now restarted ' || l_error_count || ' times.');
 
--
--
--
        IF bittst (l_flags, TASKS_BLOCKING_TASK) THEN
          UPDATE task
            SET pending_interrupt = NULL,
                state = (CASE state 
                          WHEN STATE_RUNNING THEN STATE_RUNNING 
                          WHEN STATE_CANCEL  THEN STATE_CANCEL 
                          WHEN STATE_CANCELING THEN STATE_CANCELING 
                          ELSE STATE_EXECUTABLE 
                        END)
            WHERE pending_interrupt = ds.current_task;
        END IF;
 
--
--
--
--
        IF (ds.current_task_type IN (TASK_PURGE_DF, TASK_PURGE_DF_NOW))
          AND (l_purge_reserve IS NOT NULL) THEN
          trace1 ('CLEANUP_DEAD_SCHEDULERS: Boosting priority of task');
          UPDATE task
            SET task_type = TASK_PURGE_DF_NOW,
                priority = PRIO_PURGE_DF_NOW,
                error_count = 0
            WHERE task_id = ds.current_task;
        END IF;
 
--
--
--
--
        IF ds.purpose = TASK_PURGE_IMMEDIATE AND
           ds.current_task_type = TASK_PURGE_IMMEDIATE THEN
          UPDATE task
            SET task_type = TASK_PURGE
            WHERE task_id = ds.current_task;
          trace1 ('CLEANUP_DEAD_SCHEDULERS:  Reset task_type to TASK_PURGE');
        END IF;
 
        IF ds.purpose = TASK_TRIM_DB AND
           ds.current_task_type = TASK_TRIM_DB THEN
          DELETE task
             WHERE task_id = ds.current_task;
          trace1 ('CLEANUP_DEAD_SCHEDULERS: Delete TRIM_DB task');
        END IF;
 
 
--
--
--
        l_task_rec.task_id := l_session_info_id;
        l_task_rec.task_type := TASK_ERROR_INFO;
        INSERT INTO task_history VALUES l_task_rec;      
 
      END IF;  -- ds.current task is not null
    END IF;    -- (ds.purpose IS NOT NULL) AND (ds.current_task IS NULL) 
 
--
--
--
--
--
    l_sched_error# := NULL;
    l_sched_log_id := NULL;
    l_sched_additional_info:= NULL;
    l_sched_status := NULL;
    l_sched_log_date := SYSTIMESTAMP;
 
    FOR i IN (SELECT error#, log_id, additional_info, status, log_date
                FROM user_scheduler_job_run_details
               WHERE instance_id = ds.instance_id
                 AND job_name = ds.job_name
               ORDER BY NVL2(additional_info,2,1)) LOOP
 
      l_sched_error# := i.error#;
      l_sched_log_id := i.log_id;
      l_sched_additional_info := i.additional_info;
      l_sched_status := i.status;
      l_sched_log_date := i.log_date;
 
    END LOOP;
 
--
--
--
    INSERT INTO task_history (task_id, task_type, flags, 
                              pending_interrupt, interrupt_count, 
                              savepoint, param_num1, param_num2,
                              param_num3, 
                              param, param_char1, 
                              param_char2, ba_session_id, execute_inst_id,
                              schedule_time, execute_time, completion_time, 
                              elapsed_time,
                              error_count)
                      VALUES (ds.ba_session_id, TASK_SESSION_TIMES, 0,
                              ds.current_task_type, ds.current_task,
                              l_sched_error#, ds.purpose, ds.purpose_param1,
                              l_sched_log_id, 
                              l_sched_additional_info, l_sched_status,
                              ds.trace_file, ds.sid, ds.instance_id, 
                              ds.start_time, 
                              NVL(ds.last_task_start,ds.start_time),
                              l_sched_log_date,
                              NVL(ds.last_task_start,ds.start_time) - 
                                                                ds.start_time,
                              l_session_info_id);
 
    DELETE FROM sessions WHERE ba_session_id = ds.ba_session_id;
 
    COMMIT;
 
--
    SYS.KBRSI_ICD.RSSCHEDUNLOCK(nomorejobs => 0);
 
  END LOOP;
  trace1('CLEANUP_DEAD_SCHEDULERS: No more dead schedulers');
 
  IF p_restart THEN
--
--
--
--
    IF s_session_count IS NULL THEN
      BEGIN
        SELECT TO_NUMBER(value) * 2 INTO s_session_count
          FROM sys.v_$parameter WHERE name = 'cpu_count';
      EXCEPTION
        WHEN NO_DATA_FOUND THEN
          save_error;
          s_session_count := 2;
          clear_error;
      END;
 
      IF s_session_count < 2 THEN
        s_session_count := 2;
      END IF;
      trace1 ('CLEANUP_DEAD_SCHEDULERS: ' || s_session_count || 
              ' schedulers per instance.');
    END IF;
 
--
--
--
--
--
--
--
--
--
    make_amjobs (name => 'RA$_SCHED%');
    FOR ms IN missing_schedulers LOOP
      trace1('CLEANUP_DEAD_SCHEDULERS: Instance ' || 
                                                  ms.inst_number || ' has ' ||
              print(ms.all_session_count) || ' sessions active and ' ||
              print(ms.restricted_session_count) || ' restricted sessions.');
 
      IF NVL(ms.all_session_count, 0) < s_session_count THEN
        l_new_sessions := 
                CEIL((s_session_count - NVL(ms.all_session_count, 0)) / 2);
 
        FOR i IN 0 .. l_new_sessions - 1 LOOP
--
--
--
--
          IF ms.restricted_session_count + i  < s_restricted_session_count THEN
            l_restrictions := PRIO_INDEX_BACKUP - 1;
          ELSE
            l_restrictions := NULL;
          END IF;
 
          trace1('CLEANUP_DEAD_SCHEDULERS: Restarting session ' || 
                                   TO_CHAR(ms.all_session_count+1+i) ||
                                   ' of ' || TO_CHAR(s_session_count) ||
                                   ' with maximum priority of ' ||
                                                       print(l_restrictions) ||
                                   ' on instance ' || ms.inst_number);
          spawn_job ('RA$_SCHED_' || TO_CHAR(rai_sq.nextval),
                     'dbms_ra_scheduler.schedule(' ||
                               'p_param1 => ' || print(l_restrictions) || ');',
                     ms.inst_number,
                     NULL);
 
--
--
--
--
--
--
--
          s_next_dead_scheduler_check := SYSTIMESTAMP;
        END LOOP;
      END IF;
    END LOOP;
 
    FOR i in 1..sbt_purpose.count LOOP
       IF (sbt_purpose(i) = TASK_BACKUP_SBT) THEN
          trace1('CLEANUP_DEAD_SCHEDULERS: Restarting sbt schedulers ' ||
                 'task_type TASK_BACKUP_SBT lib_key= ' || sbt_lib_key(i));
          spawn_sbt_job(p_libkey => sbt_lib_key(i));
       ELSIF (sbt_purpose(i) = TASK_PURGE_SBT) THEN
          trace1('CLEANUP_DEAD_SCHEDULERS: Restarting sbt schedulers ' ||
                 'task_type TASK_PURGE_SBT lib_key= ' || sbt_lib_key(i));
          spawn_purge_sbt_job(p_libkey => sbt_lib_key(i));
       END IF;
    END LOOP;
 
--
--
--
    SYS.KBRSI_ICD.RSRUNSCHED;
  END IF;
 
EXCEPTION
  WHEN E_PQ_FAILURE THEN
    save_error;
--
--
    trace1('CLEANUP_DEAD_SCHEDULERS: Instance failure...try again later');
    clear_error;
    RETURN;
END cleanup_dead_schedulers;
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
 
PROCEDURE schedule (p_task_type IN NUMBER DEFAULT NULL,
                    p_param1    IN NUMBER DEFAULT NULL,
                    p_param2    IN NUMBER DEFAULT NULL,
                    p_settrace  IN NUMBER DEFAULT NULL) IS
--
    l_serial#           NUMBER;
    l_audsid            NUMBER;
    l_logon_time        DATE;
    l_spid              VARCHAR2(128);
    l_job_name          DBMS_ID;
    l_task_rec          task%ROWTYPE;
    l_sts               VARCHAR2(10);
    l_exit_scheduler    BOOLEAN := FALSE;
    l_count             NUMBER;
    l_active_count      NUMBER;
    l_failing           BOOLEAN;
    l_canceling         BOOLEAN;
    l_idle_count        NUMBER;
    l_timing            NUMBER;                -- centisecond counter
    l_taskstr           VARCHAR2(30);
    l_end_str           VARCHAR2(30);
    l_task_work         NUMBER := NULL;
    l_dummy_bool        BOOLEAN;
    l_flags             NUMBER;
    l_key               NUMBER;
    l_ba_type           NUMBER;
    l_other_work        NUMBER;
    l_dbkey             NUMBER;
    l_current_execution_time TIMESTAMP WITH TIME ZONE;
    l_max_task_prio     NUMBER := NVL(p_param1, PRIO_MAX_BUSYWORK);
    l_curr_max_prio     NUMBER;
    l_new_config_time   TIMESTAMP WITH TIME ZONE;
    l_last_quiesce      TIMESTAMP WITH TIME ZONE;
    l_dbok              NUMBER;
 
  CURSOR task_locks IS  /* key and purging locks */
    SELECT key, ba_type
      FROM sys.rai_js_locks
      WHERE sid = SYS_CONTEXT('USERENV', 'SID')
        AND ba_type IN (LOCK_DB_KEY, LOCK_SL_KEY, LOCK_PURGE, LOCK_KEY);
 
--
  CURSOR sbt_task_cursor IS
    WITH sbt_task_int AS
    (SELECT /*+ LEADING(t) USE_HASH(st) */ t.*,
            st.lib_key,
            st.copies,
            st.restore,
            st.failure_cnt,
            st.template_key,
            SUM(CASE WHEN (t.state = STATE_RUNNING     AND
                           st.template_key IS NOT NULL AND
                           st.attr_key IS NOT NULL)
                     THEN st.copies
                     ELSE 0
                 END) OVER (PARTITION BY st.template_key)
                           inuse_streams,
            SUM(CASE WHEN (t.state = STATE_RUNNING AND
                           t.task_type = TASK_BACKUP_SBT AND st.restore = 'N')
                     THEN st.copies
                     ELSE 0
                 END) OVER (PARTITION BY st.lib_key) backup_drives_inuse,
            SUM(CASE WHEN (t.state = STATE_RUNNING AND st.restore = 'R')
                     THEN st.copies
                     ELSE 0
                 END) OVER (PARTITION BY st.lib_key) restore_drives_inuse
       FROM sbt_task st, task t
      WHERE st.task_id = t.task_id
        AND t.state IN (STATE_RUNNING, STATE_EXECUTABLE)
        AND t.task_type IN (TASK_BACKUP_SBT, TASK_RESTORE_SBT)
        AND st.lib_key = schedule.p_param1),
       sbt_job_attr AS
     (SELECT /*+ NO_PUSH_PRED NO_MERGE USE_HASH(j) */ 
             a.streams, j.template_key, j.priority, j.attr_key
        FROM sbt_job_template j
             LEFT OUTER JOIN sbt_attr_set a
--
--
             ON  a.lib_key = schedule.p_param1
             AND j.attr_key = a.attr_key
       WHERE (j.completion_time IS NULL OR SYSTIMESTAMP < j.completion_time)
         AND ((a.attr_key IS NULL AND
               j.bck_type = dbms_ra.RESERVE_BACKUP_TYPE) OR
              (a.attr_key IS NOT NULL AND
               j.bck_type != dbms_ra.RESERVE_BACKUP_TYPE)))
    SELECT /*+ LEADING(st) USE_HASH(j) USE_HASH(l) */
           st.task_id,    -- all task table rows (task.*)
           st.task_type,
           st.priority,
           st.flags,
           st.db_key,
           st.sl_key,
           st.state,
           st.pending_interrupt,
           st.interrupt_count,
           st.savepoint,
           st.param_num1,
           st.param_num2,
           st.param_num3,
           st.param_char1,
           st.param_char2,
           st.param,
           st.ba_session_id,
           st.execute_inst_id,
           st.schedule_time,
           st.execute_time,
           st.last_execute_time,
           st.completion_time,
           st.last_interrupt_time,
           st.error_count,
           st.purge_reserve,
           st.elapsed_time,
           st.com_time,
           st.sbt_task_id,
           st.creator_task_id,
           st.creator_sid,
           st.creator_instance
      FROM sbt_lib_desc l, sbt_task_int st
           LEFT OUTER JOIN sbt_job_attr j
            ON  j.template_key = st.template_key
            AND st.restore = 'N' -- backup jobs
     WHERE st.state = STATE_EXECUTABLE
       AND (st.execute_inst_id IS NULL       OR
--
--
--
--
            st.task_type != TASK_RESTORE_SBT OR
            st.execute_inst_id = s_instance)
       AND l.lib_key = st.lib_key
       AND l.status = 'R'   -- filter ready libs
       AND (j.streams IS NULL OR
            st.copies <= (j.streams - nvl(st.inuse_streams, 0)))
       AND ((j.template_key  IS NOT NULL AND -- backup task
             st.copies <= (l.drives - l.restore_drives -
                           nvl(st.backup_drives_inuse, 0) -
                           nvl(st.restore_drives_inuse, 0))) OR
            (st.restore = 'Y' AND -- restore task
             st.copies <= (l.drives -
                           nvl(st.backup_drives_inuse, 0) -
                           nvl(st.restore_drives_inuse, 0))))
--
  ORDER BY st.restore desc, j.priority,
           nvl(st.error_count, 0), st.failure_cnt, st.task_id;
 
--
  CURSOR sbt_purge_cursor IS
     SELECT *
       FROM
         (SELECT t.*
            FROM task t
                 LEFT OUTER JOIN sbt_lib_desc l
                 ON t.param_num1 = l.lib_key
           WHERE t.state = STATE_EXECUTABLE
             AND t.task_type = TASK_PURGE_SBT
             AND t.param_num1 = schedule.p_param1
             AND (l.status = 'R' OR l.status IS NULL) -- filter ready libs
          UNION ALL
          SELECT t.*
            FROM task t
           WHERE t.state = STATE_EXECUTABLE
             AND t.task_type = TASK_QUIESCE_RS) t
--
  ORDER BY t.task_type, NVL(t.param_num1,0), t.task_id;
 
BEGIN
  sys.kbrsi_icd.rsSetTrace;
 
--
--
--
  assert_owner;
 
  dbms_session.set_identifier('RA$');
  IF p_task_type IS NULL THEN
    dbms_ra_int.info_start('SCHEDULE', NULL);
  ELSE
    dbms_ra_int.info_start('SCHEDULE', tasktype2name(p_task_type));
  END IF;
 
--
 
  SELECT spid, sid, serial#, audsid, logon_time
    INTO l_spid,s_current_sid, l_serial#, l_audsid, l_logon_time
    FROM sys.rai_my_ospid;
 
  SELECT MAX(job_name) INTO l_job_name
    FROM user_scheduler_running_jobs
   WHERE session_id = s_current_sid 
     AND running_instance = s_instance;
 
  trace1('SCHEDULE: SID=' || s_current_sid || ', SERIAL#=' || l_serial# ||
         ', audsid=' || l_audsid ||
         ', INST_ID=' || s_instance || ', OS/PID=' || l_spid ||
         ', current_schema=' || SYS_CONTEXT ('USERENV', 'CURRENT_SCHEMA') ||
         ', user=' || USER ||
         ', session_user=' || SYS_CONTEXT ('USERENV', 'SESSION_USER') ||
         ', type=' || print(p_task_type) ||
         ', job_name=' || print(l_job_name) ||
         ', param1=' || print(p_param1) ||
         ', param2=' || print(p_param2));
 
--
--
--
  set_resumable_timeout;
 
--
--
--
--
--
--
--
--
--
  IF (p_task_type IS NULL) THEN
    l_dummy_bool := SYS.KBRSI_ICD.RSQUIESCECHECK (wait=>TRUE);
    SYS.KBRSI_ICD.RSQUIESCEUNLOCK;
  END IF;
 
  INSERT INTO sessions (ba_session_id,
                        current_task, current_task_type, spid,
                        instance_id, sid, serial#, audsid, logon_time, 
                        start_time, trace_file,
                        purpose, purpose_param1, purpose_param2, job_name,
                        last_config_change)
              VALUES   (rai_sq.nextval,
                        NULL, NULL, l_spid,
                        s_instance, s_current_sid, l_serial#, l_audsid, 
                        l_logon_time,
                        SYSTIMESTAMP, NULL,
                        p_task_type, p_param1, p_param2, l_job_name,
                        s_config_time)
              RETURNING ba_session_id INTO s_ba_session_id;
  COMMIT;
 
--
--
--
  wait_for_dbfs;
 
--
  WHILE (l_task_work IS NULL OR l_task_work>0) AND (NOT l_exit_scheduler) LOOP
--
    sys.kbrsi_icd.rsSetTrace;
 
--
--
--
--
    IF (NVL(p_task_type,0) <> TASK_TEST_DUMMY) AND 
       SYS.KBRSI_ICD.RSTIMERCHECK THEN
--
--
--
--
      SELECT value INTO l_sts
        FROM config
        WHERE (name = '_recovery_appliance_state');
 
      IF l_sts = 'OFF' THEN
         trace1('SCHEDULE: Exiting because recovery appliance has been stopped.');
         SYS.KBRSI_ICD.RSRUNSCHED; -- wake up other schedulers.
         EXIT;
      END IF;
 
      trace1 ('SCHEDULE: Starting timer session');
 
      BEGIN
        spawn_job ('RA$_TIMER_' || s_instance,
                   'dbms_ra_scheduler.timer_functions;',
                   s_instance,
                   NULL);
      EXCEPTION
        WHEN E_JOB_ALREADY_EXISTS THEN
          save_error;
          trace1 ('SCHEDULE: Timer session already active for instance ' || 
                                                                s_instance);
          clear_error;
      END;
    END IF;
 
    l_failing := FALSE;
    l_canceling := FALSE;
 
--
--
--
--
--
--
--
--
--
--
    IF p_task_type IS NULL THEN
      SYS.KBRSI_ICD.RSSCHEDLOCK (waitforwork => 1);
    ELSE
      SYS.KBRSI_ICD.RSSCHEDLOCK (waitforwork => 0);
    END IF;
 
    BEGIN
--
--
--
      IF (p_task_type = TASK_PURGE_IMMEDIATE) THEN
--
        SELECT * INTO l_task_rec
        FROM
          (SELECT * FROM task
           WHERE (state = STATE_EXECUTABLE)
             AND (task_type IN (TASK_QUIESCE_RS, 
                                TASK_PURGE_DF,
                                TASK_PURGE_DUP_DF * s_enable_dup,
                                TASK_PURGE_DF_NOW, TASK_PURGE_IMMEDIATE))
             AND sl_key = p_param1
           ORDER BY task_type, task_id)
        WHERE ROWNUM = 1;
      ELSIF (p_task_type = TASK_TRIM_DB) THEN
--
        SELECT * INTO l_task_rec
        FROM
          (SELECT * FROM task
           WHERE (state = STATE_EXECUTABLE)
             AND (task_type IN (TASK_QUIESCE_RS,
                                TASK_PURGE_DF, TASK_PURGE_DF_NOW,
                                TASK_PURGE_DUP_DF, TASK_TRIM_DB))
             AND sl_key = p_param1
             AND db_key = p_param2
           ORDER BY task_type, task_id)
        WHERE ROWNUM = 1;
      ELSIF (p_task_type = TASK_RESTORE) THEN
--
        SELECT * INTO l_task_rec
        FROM
          (SELECT * FROM task
           WHERE state = STATE_EXECUTABLE
             AND task_type IN  (TASK_QUIESCE_RS, TASK_RESTORE)
             AND execute_inst_id = s_instance
           ORDER BY task_type, task_id)
        WHERE ROWNUM = 1;
      ELSIF (p_task_type = TASK_TEST_DUMMY) THEN
--
        SELECT * INTO l_task_rec
        FROM
          (SELECT *
             FROM task
            WHERE (task_id = p_param1) 
--
           ORDER BY task_type, task_id)
        WHERE ROWNUM = 1;
 
        IF (l_task_rec.task_type <> TASK_QUIESCE_RS)
           AND (l_task_rec.state <> STATE_TASK_WAIT) 
           AND (l_task_rec.pending_interrupt <> TEST_PSEUDO_TASK) THEN
          SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(E_INTERNAL_ERROR_NUM,
                               'cannot schedule testtask on a live task');
        END IF;
 
--
        l_task_work := 0;  /* One chance to get the desired task */
      ELSIF (p_task_type = TASK_BACKUP_SBT) THEN
 
--
--
--
--
--
        BEGIN
          SELECT * INTO l_task_rec
          FROM
            (SELECT *
               FROM task
              WHERE (task_type = TASK_QUIESCE_RS) 
                AND (state = STATE_EXECUTABLE)
             ORDER BY task_type, task_id)
          WHERE ROWNUM = 1;
        EXCEPTION
          WHEN NO_DATA_FOUND THEN
            save_error;
            l_task_rec := NULL;
            clear_error;
        END; 
 
        IF l_task_rec.task_id IS NULL THEN
          OPEN sbt_task_cursor;
          FETCH sbt_task_cursor INTO l_task_rec;
          IF (sbt_task_cursor%NOTFOUND) THEN
            CLOSE sbt_task_cursor;
            RAISE no_data_found;
          END IF;
          CLOSE sbt_task_cursor;
        END IF;
      ELSIF (p_task_type = TASK_PURGE_SBT) THEN
         OPEN sbt_purge_cursor;
         FETCH sbt_purge_cursor INTO l_task_rec;
         IF (sbt_purge_cursor%NOTFOUND) THEN
            CLOSE sbt_purge_cursor;
            RAISE no_data_found;
         END IF;
         CLOSE sbt_purge_cursor;
      ELSE
--
--
--
        IF SYSTIMESTAMP > (s_last_busywork_stop + s_busywork_inhibit_time) THEN
          l_curr_max_prio := LEAST(l_max_task_prio, PRIO_MAX_BUSYWORK);
        ELSE
          l_curr_max_prio := LEAST(l_max_task_prio, PRIO_MIN_BUSYWORK);
        END IF;
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
        SELECT * INTO l_task_rec
        FROM
          (SELECT * FROM task
           WHERE (    state = STATE_EXECUTABLE
                  AND task_type != TASK_PURGE_SBT
                  AND sbt_task_id IS NULL
                  AND (task_type != TASK_RESTORE
                      OR NVL(execute_inst_id, s_instance) = s_instance)
                  AND priority < l_curr_max_prio)
              OR state = STATE_CANCEL
           ORDER BY priority, state, task_id)
        WHERE ROWNUM = 1;
 
        l_canceling := (l_task_rec.state = STATE_CANCEL);
 
        IF NOT l_canceling THEN
--
--
          IF type2priority(l_task_rec.task_type) >= PRIO_MIN_BUSYWORK THEN
            SELECT COUNT(*), COUNT(current_task) INTO l_count, l_active_count
              FROM sessions;
 
            l_idle_count := l_count - l_active_count;
  
            IF (l_idle_count < s_min_sessions_for_busywork) THEN
              trace1 ('SCHEDULE: Too busy for busywork.' ||
                                ' Total sessions=' || l_count ||
                                ' Active sessions=' || l_active_count ||
                                ' Minimum sessions needed=' ||
                                       s_min_sessions_for_busywork ||
                                ' Task id=' || l_task_rec.task_id);
 
--
--
--
--
              s_last_busywork_stop := SYSTIMESTAMP;
 
--
--
--
              UPDATE sessions SET last_busywork_stop = s_last_busywork_stop
                WHERE ba_session_id = s_ba_session_id;
              COMMIT;
 
              l_task_rec := NULL;
            END IF;
          END IF;
        END IF;
      END IF;
 
    EXCEPTION
      WHEN NO_DATA_FOUND THEN
        save_error;
        l_task_rec := NULL;
        clear_error;
    END;
 
    IF l_task_rec.task_id IS NOT NULL THEN
      s_current_task := l_task_rec.task_id;
      s_current_task_type := l_task_rec.task_type;
      s_cached_storage := 
                      BITAND(l_task_rec.flags, TASKS_CHUNK_CACHE_ACTIVE) <> 0;
      s_purging_active := (NVL(l_task_rec.purge_reserve,0) <> 0);
      s_now_serving := s_now_serving + 1;
      s_pending_interrupt := NULL;
--
      clear_error(reset => TRUE);
      l_end_str := NULL;
--
      l_current_execution_time := SYSTIMESTAMP;
      l_timing := dbms_utility.get_time;
 
--
--
--
--
--
--
      UPDATE task
        SET state = CASE l_task_rec.state
                      WHEN STATE_CANCEL THEN STATE_CANCELING
                      ELSE STATE_RUNNING
                    END,
            ba_session_id = s_ba_session_id,
            execute_inst_id = s_instance,
            execute_time = NVL(execute_time, l_current_execution_time),
            last_execute_time = l_current_execution_time,
            elapsed_time = NVL(elapsed_time,INTERVAL '0' MINUTE),
            pending_interrupt = NULL
        WHERE (task_id = s_current_task)
        RETURNING execute_time INTO l_task_rec.execute_time;
 
      UPDATE sessions
        SET current_task = s_current_task,
            current_task_type = s_current_task_type,
            last_task_start = SYSTIMESTAMP
        WHERE ba_session_id = s_ba_session_id
        RETURNING last_config_change, last_quiesce 
             INTO l_new_config_time, l_last_quiesce;
 
--
--
--
--
--
--
      IF    l_last_quiesce IS NOT NULL
        AND l_last_quiesce + s_quiesce_session_wait > SYSTIMESTAMP
        AND l_task_rec.priority > PRIO_PURGE 
        AND NOT l_canceling THEN
--
--
--
        trace1('SCHEDULE: Due to Quiesce, skipping task id ' ||  
                                                             s_current_task);
        ROLLBACK;
        s_current_task := NULL;
        l_task_rec := NULL;
      END IF;
 
--
--
--
      COMMIT;
      SYS.KBRSI_ICD.RSSCHEDUNLOCK;
 
--
--
--
      trace1 ('SCHEDULE: config_time new ' || print(l_new_config_time) ||
              ' vs old ' || print(s_config_time));
      IF l_new_config_time > s_config_time THEN
        load_config();
        set_resumable_timeout;
      END IF;
 
--
--
--
--
      IF ((s_trace_file_open + s_trace_file_days) < SYSDATE) THEN
        trace1('SCHEDULE: Ending tracefile');
        s_trace_file_open := SYSDATE;
        EXECUTE IMMEDIATE 
          'ALTER SESSION SET tracefile_identifier="ra_' || 
                          TO_CHAR(s_trace_file_open, 'YYYYMMDDHH24MI') || '"';
 
--
--
--
        BEGIN
          SELECT value INTO s_trace_file
            FROM v$diag_info 
           WHERE name = 'Default Trace File';
        EXCEPTION
          WHEN NO_DATA_FOUND THEN
            save_error;
            s_trace_file := 'Unknown trace file';
            clear_error;
        END;
 
        UPDATE sessions
          SET trace_file = s_trace_file
          WHERE ba_session_id = s_ba_session_id;
        COMMIT;
 
      END IF;
 
--
--
--
--
      IF s_current_task IS NULL THEN
        DBMS_LOCK.SLEEP(60);
        CONTINUE;
      END IF;
 
--
--
--
--
      IF s_cached_storage THEN
        DBMS_RA_STORAGE.FREE_TASK_STORAGE;
      END IF;
 
--
--
--
      BEGIN
--
--
--
        IF p_settrace IS NOT NULL THEN
          sys.kbrsi_icd.rsSetTrace(0, p_settrace);  -- used by testtask
        ELSIF (    (NVL(s_debug_when, 0) <> 0) 
               AND check_when('RAI_DEBUG_WHEN', l_task_rec.task_id))
        THEN
          sys.kbrsi_icd.rsSetTrace(0, s_debug_when); -- Trace this task only
        END IF;          
 
--
--
--
        IF     (l_task_rec.error_count >= s_max_task_restarts - 1)
           AND NOT l_canceling THEN
          IF l_task_rec.error_count >= s_max_task_restarts THEN
            trace1 ('SCHEDULE: ' ||
                        'Failed on restarts = ' || l_task_rec.error_count ||
                        '; p_task_id = ' || print(s_current_task));
             SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(e_too_many_restarts_num,
                                                  l_task_rec.task_id,
                                                  l_task_rec.error_count);
          END IF;
 
--
          sys.kbrsi_icd.rsSetTrace(0, s_debug_error);
          trace1 ('SCHEDULE: Last chance execute!');
        END IF;
 
--
--
--
        l_taskstr := tasktype2name(l_task_rec.task_type);
        l_end_str := NULL;
 
        IF l_canceling THEN
          trace_task('Cancel_Task', l_taskstr);
          RAISE E_CANCELED;
        END IF;  
 
--
        trace_task('Begin_Task', l_taskstr);
 
        IF s_perf_on THEN
          sys.kbrsi_icd.rsStartStats(l_taskstr);
        END IF;
        dbms_session.set_identifier('RA$T' || l_task_rec.task_id);
        dbms_ra_int.info_start(l_taskstr, NULL);
 
--
--
--
        IF s_stall_when AND check_when('RAI_STALL_WHEN', l_task_rec.task_id)
        AND (NVL(p_task_type,0) <> TASK_TEST_DUMMY) 
        THEN
          s_pending_interrupt := STALL_PSEUDO_TASK;
          RAISE e_retry_error;
        END IF;          
 
--
        IF l_task_rec.db_key IS NOT NULL THEN
--
--
--
          IF delete_db_task_is_benign(
                        l_task_rec.task_type) = DB_TASK_IS_NOT_BENIGN THEN
--
--
--
            SELECT COUNT(*) INTO l_dbok
              FROM odb o
             WHERE o.db_key = l_task_rec.db_key
               AND o.db_state IS NULL;
 
            IF l_dbok = 0 THEN
--
              RAISE E_FAILED;
            END IF;
          END IF;
        END IF;
 
--
--
--
        CASE l_task_rec.task_type
          WHEN TASK_QUIESCE_RS        THEN execute_quiesce;
          WHEN TASK_SPAWN_SBT         THEN execute_spawn_sbt (l_task_rec);
          WHEN TASK_PURGE_DF_NOW      THEN execute_purge_df (l_task_rec);
          WHEN TASK_RESTORE           THEN execute_restore (l_task_rec);
          WHEN TASK_STORAGE_HISTOGRAM THEN execute_storage_histogram;
          WHEN TASK_DEFERRED_DELETE   THEN execute_deferred_delete(l_task_rec);
          WHEN TASK_GCOPY_COMPUTE     THEN execute_gcopy_compute (l_task_rec);
          WHEN TASK_PURGE_IMMEDIATE   THEN execute_purge (l_task_rec);
          WHEN TASK_PURGE_DF          THEN execute_purge_df (l_task_rec);
          WHEN TASK_PURGE_DUP_DF      THEN execute_purge_dup_df (l_task_rec);
          WHEN TASK_TRIM_DB           THEN execute_trim_db (l_task_rec);
          WHEN TASK_PLAN_SBT          THEN execute_plan_df (l_task_rec);
          WHEN TASK_INDEX_BACKUP      THEN execute_index_backup (l_task_rec);
          WHEN TASK_BACKUP_ARCH       THEN execute_backup_arch (l_task_rec);
          WHEN TASK_INC_ARCH          THEN execute_inc_arch (l_task_rec);
          WHEN TASK_NEWDFKEY          THEN execute_newdfkey (l_task_rec);
          WHEN TASK_PURGE             THEN execute_purge (l_task_rec);
          WHEN TASK_PLAN_DF           THEN execute_plan_df (l_task_rec);
          WHEN TASK_MOVE_DF           THEN execute_move_df (l_task_rec);
          WHEN TASK_MOVE_ALL_DB       THEN execute_move_all_db;
          WHEN TASK_POLL              THEN execute_poll (l_task_rec);
          WHEN TASK_BACKUP_SBT        THEN execute_backup_sbt (l_task_rec);
          WHEN TASK_RESTORE_SBT       THEN execute_restore_sbt (l_task_rec);
          WHEN TASK_PURGE_SBT         THEN execute_purge_sbt (l_task_rec);
          WHEN TASK_OBSOLETE_SBT      THEN execute_obsolete_sbt (l_task_rec);
          WHEN TASK_RM_INCOMPLETE_FILES THEN
                                           execute_rm_incomplete_files;
          WHEN TASK_DB_STATS_REFRESH  THEN execute_db_stats_refresh;
          WHEN TASK_RESTORE_RANGE_REFRESH THEN
                                    execute_restore_range_refresh (l_task_rec);
          WHEN TASK_OPTIMIZE_CHUNKS_DF THEN
                                       execute_optimize_chunks_df (l_task_rec);
          WHEN TASK_OPTIMIZE_CHUNKS   THEN execute_optimize_chunks(l_task_rec);
          WHEN TASK_REBUILD_INDEX     THEN execute_rebuild_index (l_task_rec);
          WHEN TASK_VALIDATE_DB       THEN execute_validate_db (l_task_rec);
          WHEN TASK_DELETE_DB         THEN execute_delete_db (l_task_rec);
          WHEN TASK_CHECK_FILES       THEN execute_check_files (l_task_rec);
          WHEN TASK_CROSSCHECK_DB     THEN execute_crosscheck_db (l_task_rec);
          WHEN TASK_RECONCILE         THEN execute_reconcile (l_task_rec);
          WHEN TASK_REPAIR_DB         THEN execute_repair_db (l_task_rec);
          WHEN TASK_INSERT_FAULT      THEN execute_insert_fault (l_task_rec);
         ELSE /*NF_START*/
            trace1 ('SCHEDULE: unknown task type: ' || l_task_rec.task_type);
            SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(E_BAD_TASK_TYPE_NUM, 
                                                  l_task_rec.task_type);
        END CASE;
 
      EXCEPTION
      WHEN E_PENDING_INTERRUPT OR E_RETRY_ERROR OR E_RETRY_RESERVE THEN
        save_error;
        trace1 ('SCHEDULE: Waiting for task id ' ||
                                                   print(s_pending_interrupt));
 
--
--
--
--
        IF SQLCODE = E_RETRY_RESERVE_NUM THEN
          s_enable_dup := 0;
        END IF;
 
--
--
--
--
--
        IF s_pending_interrupt = SPACE_PSEUDO_TASK THEN
          SELECT db_key INTO l_dbkey FROM task WHERE task_id = s_current_task;
          BEGIN
            DBMS_RA_STORAGE.LOCK_DB (l_dbkey);
            UPDATE odb SET wait_space = used_space WHERE db_key = l_dbkey;
            COMMIT;
            DBMS_RA_STORAGE.UNLOCK_DB (l_dbkey);
          EXCEPTION
            WHEN OTHERS THEN
              save_error;
              DBMS_RA_STORAGE.UNLOCK_DB (l_dbkey);
              RAISE;
          END;
        END IF;
 
        IF s_pending_interrupt <> 0 THEN
--
--
--
          suspend_task (STATE_TASK_WAIT, l_current_execution_time);
          l_end_str := 'Waiting_Task'; 
        ELSE
--
--
--
          suspend_task (STATE_EXECUTABLE, l_current_execution_time);
          l_end_str := 'Interrupt_Task';
        END IF;
 
--
--
--
        l_task_rec.task_id := NULL;
        clear_error;
 
      WHEN E_NO_MORE_SGA THEN
        save_error;
        trace1 ('SCHEDULE: NO_MORE_SGA');
        suspend_task (STATE_RESTORE_WAIT, l_current_execution_time);
        l_end_str := 'Interrupt_Task';
 
--
--
--
        l_task_rec.task_id := NULL;
        clear_error;
 
      WHEN E_SNAPSHOT_TOO_OLD OR E_UNABLE_EXTEND_TEMPSEG 
        OR E_TOO_MANY_ROLLBACK_EXTENTS OR E_CANT_EXTEND_UNDO THEN
        save_error;
        ROLLBACK;
--
--
--
        log_error (p_errno => E_RESOURCE_ERROR_NUM,
                   p_keep_stack => TRUE,
                   p_component => 'SCHEDULER',
                   p_severity  => SEVERITY_WARNING,
                   p_param_num => SQLCODE);
 
 
--
--
--
--
--
        SELECT FLOOR(COUNT(*)*.9) INTO l_count
          FROM sessions
         WHERE current_task IS NOT NULL;
 
        trace1 ('SCHEDULE: Try to reset resource restrictions to ' || l_count);
        
--
--
--
--
        UPDATE config SET value = GREATEST(LEAST(value, l_count),3)
          WHERE name = '_resource_wait_task_limit'
          RETURNING value INTO l_count;
        trace1 ('SCHEDULE: Resource restrictions set to ' || l_count);
        COMMIT;
 
--
--
--
--
        s_pending_interrupt := RESOURCE_PSEUDO_TASK;
        suspend_task (STATE_TASK_WAIT, l_current_execution_time);
        l_end_str := 'Waiting_Task';
 
--
--
--
        l_task_rec.task_id := NULL;
 
--
--
--
--
        l_exit_scheduler := TRUE;
        clear_error;
 
      WHEN E_TABLE_TS_FULL OR E_INDEX_TS_FULL OR
           E_INDEXPART_TS_FULL OR E_TABLEPART_TS_FULL OR
           E_RESUMABLE_TIMEOUT THEN
--
        save_error;
 
--
        IF s_pool_tablespace IS NULL THEN
          SELECT tablespace_name INTO s_pool_tablespace
            FROM user_segments 
           WHERE segment_name IN ('PLANS', 'PLANS_DETAILS', 'CHUNKS', 'BLOCKS')
             AND ROWNUM = 1;
        END IF;
 
        trace1('SCHEDULE: Tablespace ' || s_pool_tablespace || ' is full');
        IF INSTR(SYS.DBMS_UTILITY.FORMAT_ERROR_STACK,
                 s_pool_tablespace) = 0 THEN
          RAISE;
        END IF;
 
        ROLLBACK;
 
--
--
--
        log_error (p_errno => E_POOL_FULL_NUM,
                   p_param1 => s_pool_tablespace,
                   p_keep_stack => TRUE,
                   p_component => 'SCHEDULER',
                   p_severity  => SEVERITY_ERROR);
 
--
--
--
--
        s_pending_interrupt := POOL_FULL_PSEUDO_TASK;
        suspend_task (STATE_TASK_WAIT, l_current_execution_time);
        l_end_str := 'Waiting_Task';
 
--
--
--
        l_task_rec.task_id := NULL;
 
 
      WHEN E_TOO_MANY_RESTARTS THEN
        save_error;
--
        write_error (p_component => 'SCHEDULER',
                     p_severity  =>  SEVERITY_INTERNAL,
                     p_param_num => l_task_rec.task_id);
        l_failing := TRUE;
        clear_error;
 
      WHEN E_TERMINATED THEN
        save_error;
--
--
--
        trace1 ('SCHEDULE: E_TERMINATED handled.');
        clear_error;
 
      WHEN E_FAILED THEN
        save_error;
--
        trace1 ('SCHEDULE: E_FAILED handled.');
        l_end_str := 'Failed_Task';
        l_failing := TRUE;
        clear_error;
 
      WHEN E_CANCELED THEN
        save_error;
--
        trace1 ('SCHEDULE: E_CANCELED handled.');
        l_end_str := 'Canceled_Task';
        clear_error;
      END;
 
--
--
--
      IF l_task_rec.task_id IS NULL
      THEN
        FOR l IN task_locks LOOP
          CASE l.ba_type
           WHEN LOCK_DB_KEY THEN DBMS_RA_STORAGE.UNLOCK_DB(l.key);
           WHEN LOCK_SL_KEY THEN DBMS_RA_STORAGE.UNLOCK_SL(l.key);
           WHEN LOCK_PURGE  THEN SYS.KBRSI_ICD.RSPURGEUNLOCK(l.key);
           WHEN LOCK_KEY    THEN SYS.KBRSI_ICD.RSKEYUNLOCK(l.key);
          END CASE;
        END LOOP;
      END IF;
      sys.kbrsi_icd.rsStopStats;
      dbms_ra_int.info_end(TRUE);
      dbms_session.set_identifier('RA$');
 
--
--
--
      IF l_task_rec.task_id IS NOT NULL
      THEN
--
--
--
        l_timing := dbms_utility.get_time - l_timing;
        trace1 ('SCHEDULE: Execution time was ' || l_timing);
 
--
--
--
        complete_task (NVL(l_end_str,'End_task'), 
                       l_taskstr, 
                       l_current_execution_time,
                       CASE
                         WHEN l_failing THEN STATE_FAILED
                         WHEN l_canceling THEN STATE_CANCELED
                         ELSE STATE_COMPLETED
                       END);
      ELSE
--
--
--
--
        trace_task(NVL(l_end_str,'Nulled_task'), l_taskstr);
      END IF;
 
      l_taskstr := NULL;  -- We are done that operation
 
--
--
      s_sysreserve_ok := FALSE;
      s_no_wait_on_allocate := FALSE;
      s_current_task := NULL;
      s_current_task_type := NULL;
      UPDATE sessions
        SET current_task = NULL,
            current_task_type = NULL
        WHERE ba_session_id = s_ba_session_id;
      COMMIT;
    ELSE
--
--
--
--
--
      IF p_task_type = TASK_PURGE_IMMEDIATE THEN
--
        SELECT COUNT(*) INTO l_task_work
        FROM task
        WHERE (task_type IN (TASK_PURGE_IMMEDIATE, TASK_PURGE_DF,
                             TASK_PURGE_DUP_DF, TASK_PURGE_DF_NOW))
          AND sl_key = p_param1
          AND (pending_interrupt IS NULL OR task_type != TASK_PURGE_DUP_DF);
        s_enable_dup := 1;
--
      ELSIF p_task_type = TASK_TRIM_DB THEN
--
        SELECT COUNT(*) INTO l_task_work
        FROM task
        WHERE (task_type IN (TASK_TRIM_DB, TASK_PURGE_DF, TASK_PURGE_DF_NOW))
          AND sl_key = p_param1
          AND db_key = p_param2;
      ELSIF p_task_type = TASK_RESTORE THEN
--
        SELECT COUNT(*) INTO l_task_work
        FROM task
        WHERE task_type = TASK_RESTORE
          AND state = STATE_EXECUTABLE
          AND execute_inst_id = s_instance;
--
      ELSIF (p_task_type = TASK_BACKUP_SBT) THEN
--
        SELECT COUNT(*) INTO l_task_work
        FROM  task t, sbt_lib_desc l, sbt_task st
              LEFT OUTER JOIN
              sbt_job_template j
              ON  j.template_key = st.template_key
              AND st.restore = 'N' -- backup or reserve jobs
              AND (j.completion_time IS NULL OR
                   SYSTIMESTAMP < j.completion_time)
        WHERE t.state = STATE_EXECUTABLE
          AND t.task_id = st.task_id
          AND t.task_type IN (TASK_BACKUP_SBT, TASK_RESTORE_SBT)
          AND (j.template_key IS NOT NULL OR st.restore = 'Y')
          AND st.lib_key = l.lib_key
          AND l.status = 'R'   -- filter ready libs
          AND st.lib_key = schedule.p_param1;
      ELSIF p_task_type = TASK_PURGE_SBT THEN
--
        SELECT COUNT(*) INTO l_task_work
        FROM  task t, sbt_lib_desc l
        WHERE t.state = STATE_EXECUTABLE
          AND t.task_type = TASK_PURGE_SBT
          AND l.status = 'R' -- filter ready libs
          AND t.param_num1 = l.lib_key
          AND t.param_num1 = schedule.p_param1;
      ELSE /* Normal scheduler */
--
--
--
--
--
        SELECT COUNT(*) INTO l_other_work
          FROM DUAL
          WHERE EXISTS (SELECT 1 FROM task
                          WHERE (    state = STATE_EXECUTABLE
                                 AND task_type != TASK_PURGE_SBT
                                 AND sbt_task_id IS NULL)
                             OR state = STATE_CANCEL);
      END IF;
 
--
      IF l_task_work = 0  THEN
        SYS.KBRSI_ICD.RSSCHEDUNLOCK;
        cleanup_task(p_task_type);
      ELSE
--
--
--
--
--
--
--
        trace1 ('SCHEDULE:  No work to be done. Going to sleep');
 
        IF (p_task_type IS NULL) AND (l_other_work = 0) THEN
          SYS.KBRSI_ICD.RSSCHEDUNLOCK(nomorejobs => 1);
        ELSE  
--
--
--
--
--
--
--
--
          SYS.KBRSI_ICD.RSSCHEDUNLOCK;
          DBMS_LOCK.SLEEP(s_scheduling_wait);
        END IF;
      END IF;
    END IF; /* Found a task to execute */
 
--
    IF s_safe_mode THEN
      BEGIN
        SELECT key, ba_type INTO l_key, l_ba_type
          FROM (SELECT key, ba_type
                FROM sys.rai_js_locks
                WHERE sid = SYS_CONTEXT('USERENV', 'SID')
                  AND ba_type IN (LOCK_DB_KEY, LOCK_SL_KEY,
                                  LOCK_PURGE, LOCK_KEY)
--
                  AND NOT ((ba_type = LOCK_KEY) AND 
                           (key = LOCK_QUIESCE_PENDING)) 
                ORDER BY ba_type, key)
          WHERE ROWNUM = 1;
 
        s_tracing_on := TRUE;
        SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(E_INTERNAL_ERROR_NUM, 
               'SCHEDULE: ba_type ' || l_ba_type ||
               ', lock ' || l_key || ' held illegally');
      EXCEPTION
        WHEN no_data_found THEN 
          save_error;
          clear_error; /* no locks is a good thing */
      END;
    END IF;
  END LOOP;
 
--
--
--
  UPDATE sessions SET last_task_start = SYSTIMESTAMP
    WHERE ba_session_id = s_ba_session_id;
  COMMIT;
 
  dbms_application_info.set_module(NULL, NULL);
  dbms_session.set_identifier(NULL);
 
EXCEPTION
    WHEN E_ORA_600 THEN
--
--
      save_error;
 
      IF s_current_task_type IS NULL THEN
        l_taskstr := 'SCHEDULER';
      ELSE
        l_taskstr := tasktype2name(s_current_task_type);
      END IF;
 
      write_error (p_component => l_taskstr,
                   p_severity  => SEVERITY_INTERNAL,
                   p_param_num => s_current_task,
                   p_param_char => l_spid);
      RAISE;
 
    WHEN OTHERS THEN
      save_error;
 
--
      sys.kbrsi_icd.rsStopStats;
 
--
--
 
--
--
      IF (p_task_type = TASK_PURGE_SBT OR p_task_type = TASK_BACKUP_SBT) THEN
         l_spid := NULL;
      END IF;
 
      IF s_current_task_type IS NULL THEN
        l_taskstr := 'SCHEDULER';
      ELSE
        l_taskstr := tasktype2name(s_current_task_type);
      END IF;
 
      log_error (p_errno => E_BAD_TASK_NUM,
                 p_param1 => print(l_task_rec.task_id),
                 p_param2 => (CASE WHEN s_current_task_type IS NOT NULL 
                               THEN l_taskstr
                               ELSE 'NONE' END),
                 p_component => l_taskstr,
                 p_severity  => SEVERITY_INTERNAL,
                 p_param_num => l_task_rec.task_id,
                 p_param_char => l_spid);
 
      SYS.KBRSI_ICD.RSSCHEDUNLOCK(nomorejobs => 0);
      cleanup_task(p_task_type);
 
--
      trace_task('Fail_Task', l_taskstr);
      dbms_application_info.set_module(NULL, NULL);
      dbms_session.set_identifier(NULL);
      RAISE;
END schedule;
 
--
--
--
--
--
--
--
--
--
PROCEDURE testTask(p_taskid   IN NUMBER DEFAULT NULL,
                   p_tasktype IN NUMBER DEFAULT NULL,
                   p_num1     IN NUMBER DEFAULT NULL,
                   p_num2     IN NUMBER DEFAULT NULL,
                   p_num3     IN NUMBER DEFAULT NULL,
                   p_char1    IN VARCHAR2 DEFAULT NULL,
                   p_char2    IN VARCHAR2 DEFAULT NULL,
                   p_param    IN VARCHAR2 DEFAULT NULL,
                   p_slkey    IN NUMBER DEFAULT NULL,
                   p_dbkey    IN NUMBER DEFAULT NULL,
                   p_settrace IN NUMBER DEFAULT NULL,
                   p_newsession IN BOOLEAN DEFAULT FALSE)
IS
  l_value          VARCHAR2(3);
  l_count          NUMBER;
  l_task_rec       task%ROWTYPE;
  l_task_id        NUMBER;
  l_needtask       BOOLEAN := TRUE;
  l_jobname        DBMS_ID;
  l_action         VARCHAR2(200);
BEGIN
--
  IF p_taskid IS NOT NULL THEN
    trace1 ('testTask retry task id ' || p_taskid);
 
--
    SYS.KBRSI_ICD.RSSCHEDLOCK (waitforwork => 0);
 
    BEGIN
      SELECT COUNT(*) INTO l_count FROM task WHERE task_id = p_taskid;
 
--
--
      IF l_count > 0 THEN
--
        SELECT * INTO l_task_rec FROM task WHERE task_id = p_taskid;
 
--
        IF l_task_rec.state IN (STATE_RUNNING, STATE_CANCELING) THEN
--
          SELECT value into l_value
            FROM config
            WHERE name = '_recovery_appliance_state';
 
          IF l_value = 'ON' THEN
--
            SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(E_INTERNAL_ERROR_NUM,
                          'Appliance is on: cannot testtask a running task');
          END IF;
 
--
          IF BITAND (l_task_rec.flags, TASKS_CHUNK_CACHE_ACTIVE) <> 0 THEN
            DBMS_RA_STORAGE.FREE_TASK_STORAGE (p_taskid);
          END IF;
 
--
--
          UPDATE sessions
            SET current_task = NULL,
                current_task_type = NULL
            WHERE current_task = p_taskid;
        END IF;
 
--
        UPDATE task
          SET ba_session_id = NULL,
              state = STATE_TASK_WAIT,
              pending_interrupt = TEST_PSEUDO_TASK,
              error_count = 1
          WHERE task_id = p_taskid;
        COMMIT;
 
        l_needtask := FALSE;
 
--
      ELSE
        BEGIN
          SELECT * INTO l_task_rec FROM task_history WHERE task_id = p_taskid;
          DELETE FROM task_history WHERE task_id = p_taskid;
        EXCEPTION
          WHEN NO_DATA_FOUND THEN
            save_error;
            SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(E_INTERNAL_ERROR_NUM,
                                                  'testtask taskid not found');
        END;
      END IF;
      l_task_rec.pending_interrupt := NULL;
      l_task_rec.error_count := 1;  /* Ensure it runs again. */
      COMMIT;  /* commit the deletes before releasing schedlock */
 
      SYS.KBRSI_ICD.RSSCHEDUNLOCK;
    EXCEPTION
      WHEN OTHERS THEN
        save_error;
        SYS.KBRSI_ICD.RSSCHEDUNLOCK;
        RAISE;
    END;
 
  ELSIF p_tasktype IS NULL THEN
    SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(E_INTERNAL_ERROR_NUM,
                                   'cannot testtask without a taskid or type');
  ELSE
--
    l_task_rec.task_id       := rai_sq.nextval;
    l_task_rec.task_type     := p_tasktype;
    l_task_rec.priority      := type2priority(p_tasktype);
    l_task_rec.param_num1    := p_num1;
    l_task_rec.param_num2    := p_num2;
    l_task_rec.param_num3    := p_num3;
    l_task_rec.param_char1   := p_char1;
    l_task_rec.param_char2   := p_char2;
    l_task_rec.param         := p_param;
    l_task_rec.sl_key        := p_slkey;
    l_task_rec.db_key        := p_dbkey;
    l_task_rec.flags         := 0;
  END IF;
 
--
  trace1 ('testTask type: ' || tasktype2name(l_task_rec.task_type) ||
          ', num1: ' || print(l_task_rec.param_num1) ||
          ', num2: ' || print(l_task_rec.param_num2) ||
          ', num3: ' || print(l_task_rec.param_num3) ||
          ', char1: ' || print(l_task_rec.param_char1) ||
          ', char2: ' || print(l_task_rec.param_char2) ||
          ', param: ' || print(l_task_rec.param) ||
          ', slkey: ' || print(l_task_rec.sl_key) ||
          ', dbkey: ' || print(l_task_rec.db_key));
 
 
--
--
  IF l_needtask THEN
    l_task_id := define_task (task_rec => l_task_rec);
  END IF;
 
  UPDATE task
--
    SET state = STATE_TASK_WAIT,
        pending_interrupt = TEST_PSEUDO_TASK
    WHERE task_id = l_task_id;
  COMMIT;
 
--
--
--
--
  IF p_newsession THEN
    l_jobname := 'RA$TESTTASK_' || rai_sq.nextval;
    l_action := 'DBMS_RA_SCHEDULER.SCHEDULE(' ||
                      '  p_task_type => ' || TASK_TEST_DUMMY ||
                      ', p_param1 => ' || l_task_rec.task_id || 
                      ', p_settrace => ' || print(p_settrace) || ');';
 
    trace1 ('TESTTASK:  spawning ' || l_jobname || ' for ' || l_action);
    spawn_job (l_jobname, l_action, s_instance, NULL);
 
    DBMS_RA_INT.WAIT_FOR_JOB (l_jobname, 5);
  ELSE
    trace1 ('testTask local session start');
    schedule(p_task_type => TASK_TEST_DUMMY
           , p_param1 => l_task_rec.task_id
           , p_settrace => p_settrace);
  END IF;
 
  trace1 ('testTask complete');
    
END testTask;
 
--
--
--
PROCEDURE get_lock(p_type IN NUMBER,
                   p_key  IN NUMBER) IS
 
  l_locked              BOOLEAN := FALSE;
  l_blocking_sid        NUMBER := NULL;
BEGIN
  tracex ('GET_LOCK: for type ' || p_type || ' for key ' ||  p_key); 
--
--
  WHILE NOT l_locked AND l_blocking_sid IS NULL LOOP
    CASE p_type
      WHEN LOCK_KEY THEN l_locked := sys.kbrsi_icd.rsKeyWriteLock(p_key,FALSE);
      WHEN LOCK_PURGE THEN l_locked := sys.kbrsi_icd.rsPurgeLock(p_key);
      ELSE SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(E_INTERNAL_ERROR_NUM, 
                            'Lock on unknown lock type=' || p_type);
    END CASE;
 
--
--
--
    IF NOT l_locked THEN
      <<try_try_again>>
      BEGIN
        SELECT MIN(jsl.sid), NVL(MIN(s.current_task), SERVLET_PSEUDO_TASK)
          INTO l_blocking_sid, s_pending_interrupt
          FROM sys.rai_js_gvlocks jsl
               LEFT OUTER JOIN sessions s 
                           ON (jsl.sid = s.sid AND jsl.inst_id = s.instance_id)
          WHERE jsl.ba_type = p_type
            AND jsl.key = MOD(p_key, POWER(2,32));
      EXCEPTION
        WHEN E_PQ_FAILURE THEN
          save_error;
          clear_error;
--
          GOTO try_try_again;
      END;
    END IF;
  END LOOP;
 
--
  IF NOT l_locked THEN
    tracex ('GET_LOCK not locked: type ' || p_type || ' for key ' ||  p_key); 
    show_locks(p_type, p_key);
    RAISE E_RETRY_ERROR;
  END IF;
END get_lock;
 
--
--
--
PROCEDURE unlock(p_type IN NUMBER,
                 p_key  IN NUMBER) IS
BEGIN
  CASE p_type
    WHEN LOCK_KEY   THEN sys.kbrsi_icd.rsKeyUnlock(p_key);
    WHEN LOCK_PURGE THEN sys.kbrsi_icd.rsPurgeUnlock(p_key);
    ELSE SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(E_INTERNAL_ERROR_NUM, 
                            'Unlock on unknown lock type=' || p_type);
  END CASE;
END unlock;
 
--
--
--
PROCEDURE show_locks (p_type IN NUMBER,
                      p_key  IN NUMBER) IS
  CURSOR locks (in_type IN NUMBER, in_key IN NUMBER) IS
    SELECT l.sid, s.current_task, s.current_task_type
    FROM TABLE(CAST(s_amlocks AS rai_locks_table_type)) l
         LEFT OUTER JOIN sessions s 
                               ON (l.sid = s.sid AND l.inst_id = s.instance_id)
    WHERE l.ba_type = in_type
      AND l.key = mod(in_key, power(2,32));
BEGIN
  IF s_safe_mode THEN
    make_amlocks();
    FOR l IN locks (p_type, p_key) LOOP
      trace1 ('SHOW_LOCKS: type ' || p_type || ', key ' || p_key ||
              ', SID ' || l.sid ||
              ', task id ' || NVL(TO_CHAR(l.current_task),'**Servlet**') ||
              ', task_type ' || tasktype2name(l.current_task_type));
    END LOOP;
  END IF;
END show_locks;
 
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE get_lock_direct_waitable(p_type IN NUMBER,
                                   p_key IN NUMBER,
                                   wait_time_in_seconds IN NUMBER)
IS
  l_exit_loop       NUMBER := 0;
  l_start_time      DATE;
  l_current_time    DATE;
  l_end_time        DATE;
  l_max_time        DATE;
  l_max             NUMBER;
  l_got_lock        BOOLEAN := FALSE;
BEGIN
 
  trace1('Acquiring lock for key=' || p_key || ' type=' || p_type
      || ' retry=' || wait_time_in_seconds);
 
  l_current_time := SYSDATE;
  l_start_time   := l_current_time;
 
  l_end_time := l_start_time + ((1/24/60/60) * wait_time_in_seconds);
--
  l_max := ((1/24/60) * 10);
  IF wait_time_in_seconds > l_max THEN
    l_max := wait_time_in_seconds;
  END IF;
  l_max_time := l_start_time + l_max;
 
  WHILE l_exit_loop = 0 LOOP
 
    CASE p_type
      WHEN LOCK_KEY   THEN
                       l_got_lock := sys.kbrsi_icd.rsKeyWriteLock(p_key,FALSE);
      WHEN LOCK_PURGE THEN l_got_lock := sys.kbrsi_icd.rsPurgeLock(p_key);
      ELSE SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(E_INTERNAL_ERROR_NUM, 
                  'GET_LOCK_DIRECT_WRITABLE on unknown_lock_type= ' || p_type);
    END CASE;
 
    IF l_got_lock = FALSE THEN
      IF wait_time_in_seconds > 0 THEN
        l_current_time := SYSDATE;
        IF (l_current_time > l_end_time) OR (l_current_time > l_max_time) THEN
          l_exit_loop := 1;
        ELSE
          dbms_lock.sleep(s_lock_refused_wait);  -- 5 seconds
        END IF;
      ELSIF wait_time_in_seconds = 0 THEN
        l_exit_loop := 1;
      END IF;
    ELSE
      l_exit_loop := 1;
    END IF;
  END LOOP;
 
  IF l_got_lock = FALSE THEN
    trace1('Unable to get write_lock for key=' || p_key);
  END IF;
 
END get_lock_direct_waitable;
 
 
--
--
--
PROCEDURE release_blocked_tasks(p_task_id IN NUMBER,
                                p_db_key IN NUMBER DEFAULT NULL) IS
  l_max_vb_key          NUMBER;
  l_retention_time      TIMESTAMP;
  l_max_vb_key2         NUMBER;
BEGIN
--
--
--
--
  SYS.KBRSI_ICD.RSSCHEDLOCK (waitforwork => 0);
 
--
--
--
  UPDATE task
    SET pending_interrupt = NULL,
        state = (CASE state 
                   WHEN STATE_RUNNING THEN STATE_RUNNING 
                   WHEN STATE_CANCEL THEN STATE_CANCEL 
                   WHEN STATE_CANCELING THEN STATE_CANCELING 
                   ELSE STATE_EXECUTABLE 
                 END),
        ba_session_id = NULL
    WHERE pending_interrupt = p_task_id
      AND (p_db_key IS NULL OR db_key = p_db_key);
  trace1('RELEASE_BLOCKED_TASKS: Released ' ||  SQL%ROWCOUNT || ' tasks.');
  COMMIT;
  SYS.KBRSI_ICD.RSSCHEDUNLOCK(nomorejobs => 0);
 
EXCEPTION
  WHEN OTHERS THEN
    save_error;
    trace1('RELEASE_BLOCKED_TASKS: Exeception raised ' ||  SQLERRM);
    SYS.KBRSI_ICD.RSSCHEDUNLOCK(nomorejobs => 0);
    RAISE;
END release_blocked_tasks;
 
 
--
--
--
--
--
--
--
--
--
--
PROCEDURE raise_purge_priority (p_dfkey IN NUMBER) IS
BEGIN
  trace1('RAISE_PURGE_PRIORITY on df_key ' || p_dfkey);
 
--
--
--
  SYS.KBRSI_ICD.RSSCHEDLOCK (waitforwork => 0);
 
  UPDATE task SET task_type = TASK_PURGE_DF_NOW,
                  priority = PRIO_PURGE_DF_NOW
    WHERE task_type = TASK_PURGE_DF
      AND param_num1 = p_dfkey
      AND state IN (STATE_RUNNING, STATE_EXECUTABLE);
  trace1('RAISE_PURGE_PRIORITY: Accelerated ' || SQL%ROWCOUNT || ' tasks.');
  COMMIT;
 
  SYS.KBRSI_ICD.RSSCHEDUNLOCK(nomorejobs => 0);
EXCEPTION
  WHEN OTHERS THEN
    save_error;
    trace1('RAISE_PURGE_PRIORITY: Exeception raised ' ||  SQLERRM);
    SYS.KBRSI_ICD.RSSCHEDUNLOCK(nomorejobs => 0);
    RAISE;
END raise_purge_priority;
 
--
--
--
--
PROCEDURE avoid_sl(p_type  IN NUMBER, -- TASK_PURGE or TASK_INDEX_BACKUP
                   p_slkey IN NUMBER) IS
  l_taskid NUMBER;
  l_space  NUMBER;
BEGIN
--
  CASE p_type
    WHEN TASK_PURGE THEN
--
--
--
--
      SELECT MIN(task_id) INTO l_taskid
        FROM task
        WHERE task_type IN (TASK_PURGE,
                            TASK_PURGE_IMMEDIATE,
                            DECODE(s_current_task_type, 
                                   TASK_INDEX_BACKUP, 0, TASK_PURGE_DF),
                            DECODE(s_current_task_type, 
                                   TASK_INDEX_BACKUP, 0, TASK_PURGE_DUP_DF),
                            TASK_PURGE_DF_NOW,
                            TASK_REPAIR_DB,
                            TASK_REBUILD_INDEX)
          AND task_id != s_current_task
          AND (sl_key = p_slkey OR
               (task_type = TASK_REBUILD_INDEX AND state = STATE_RUNNING));
 
    WHEN TASK_INDEX_BACKUP THEN
--
--
--
--
      SELECT SUM(bytes)+MAX(bytes)+MAX(bytes) INTO l_space
        FROM task t, odb d, bp p
        WHERE state = STATE_RUNNING
          AND t.db_key = d.db_key
          AND d.sl_key = p_slkey
          AND t.param_num1 = p.bp_key
          AND t.task_type = TASK_INDEX_BACKUP
          AND BITAND (t.flags, TASKS_CHUNK_CACHE_ACTIVE) = 0;
 
--
      l_taskid := NULL;
      IF dbms_ra_storage.freespace(p_slkey) < l_space THEN
        BEGIN
--
--
          SELECT MIN(rand_task) INTO l_taskid
          FROM (SELECT FIRST_VALUE(task_id)
                       OVER (ORDER BY dbms_random.VALUE) rand_task
                FROM task t, odb d
                WHERE state = STATE_RUNNING
                  AND t.db_key = d.db_key
                  AND d.sl_key = p_slkey
                  AND t.task_type IN 
                        (TASK_INDEX_BACKUP, TASK_PURGE_DF, TASK_PURGE_DUP_DF)
                  AND t.task_id <> s_current_task);
        EXCEPTION
          WHEN no_data_found THEN
            save_error;
            clear_error;  -- OK, this is the only task, so just do it.
        END;
      END IF;
      trace1('AVOID_SL: task ' || l_taskid || ', space ' || l_space);
    ELSE
      SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(E_INTERNAL_ERROR_NUM,
                                               'bad avoid_sl task');
  END CASE;
 
--
  IF l_taskid IS NOT NULL THEN
    trace1('AVOID_SL: throwing retry for sl_key ' || p_slkey);
    s_pending_interrupt := l_taskid;
    RAISE E_RETRY_ERROR;
  END IF;
END avoid_sl;
 
 
--
--
--
--
--
--
PROCEDURE avoid_db (p_db_key IN NUMBER) IS
  l_task_id NUMBER;
BEGIN
--
--
--
  IF type2priority(NVL(s_current_task_type,0)) < PRIO_MIN_BUSYWORK
  THEN
    RETURN;
  END IF;
 
--
--
--
--
  SELECT task_id INTO l_task_id
    FROM task
    WHERE db_key = p_db_key
      AND priority < PRIO_MIN_BUSYWORK
      AND state != STATE_ORDERING_WAIT
      AND task_type NOT IN
                    (TASK_BACKUP_SBT, TASK_RESTORE_SBT, TASK_PURGE_SBT,
                     TASK_OBSOLETE_SBT, TASK_PLAN_SBT)
      AND ROWNUM = 1;
 
--
  trace1('AVOID_DB: throwing retry for db_key ' || p_db_key);
  s_pending_interrupt := l_task_id;
  RAISE E_RETRY_ERROR;
EXCEPTION
  WHEN NO_DATA_FOUND THEN 
    save_error;
    clear_error;
END avoid_db;
 
 
--
--
--
--
--
--
--
PROCEDURE avoid_bs(p_dbkey IN NUMBER, 
                   p_bskey IN NUMBER, 
                   p_bpkey IN NUMBER) IS
  l_taskid  NUMBER;
BEGIN
--
--
--
--
--
--
--
--
--
  SELECT MIN(task_id) INTO l_taskid
    FROM task t, odb p, bp b, bdf d,
         (SELECT * FROM bdf WHERE bdf.bs_key = p_bskey) a
    WHERE t.state = STATE_RUNNING
      AND t.db_key = p.db_key
      AND t.db_key = p_dbkey
      AND t.task_type = TASK_INDEX_BACKUP
      AND t.task_id != s_current_task
      AND t.param_num1 = b.bp_key
      AND b.bs_key = d.bs_key
      AND d.file# = a.file#
      AND b.piece# = (SELECT piece#
                        FROM bp
                        WHERE bp_key = p_bpkey);
                     
--
  IF l_taskid IS NOT NULL THEN
    trace1('AVOID_BS: throwing retry for bs_key ' || p_bskey);
    s_pending_interrupt := l_taskid;
    RAISE E_RETRY_ERROR;
  END IF;
END avoid_bs;
 
 
--
--
--
--
--
PROCEDURE avoid_delete_db(p_dbkey IN NUMBER DEFAULT NULL) IS
BEGIN
--
--
--
--
  SELECT MAX(task_id) INTO s_pending_interrupt
    FROM task 
    WHERE task_type = TASK_DELETE_DB
      AND state = STATE_RUNNING
      AND db_key = NVL(p_dbkey, db_key);
 
--
  IF s_pending_interrupt IS NOT NULL THEN
    trace1('AVOID_DELETE_DB: Waiting for task ' || s_pending_interrupt);
    RAISE E_RETRY_ERROR;
  END IF;
END avoid_delete_db;
 
 
--
--
--
PROCEDURE execute_backup_arch (p_task_rec IN OUT NOCOPY task%ROWTYPE) IS
  l_delete  BOOLEAN;
BEGIN
  trace1('EXECUTE_BACKUP_ARCH: Performing Backup arch Task ' ||
         s_current_task);
  tracex('EXECUTE_BACKUP_ARCH: DB: ' || p_task_rec.db_key ||
                        ' filename: ' || p_task_rec.param);
 
  wait_for_repair (NULL, p_task_rec.db_key);
  
--
--
--
--
  SELECT MIN(task_id) INTO s_pending_interrupt
    FROM task
    WHERE db_key = p_task_rec.db_key
      AND param = p_task_rec.param
      AND task_type IN (TASK_INC_ARCH, TASK_BACKUP_ARCH)
      AND (state = STATE_RUNNING OR task_type = TASK_INC_ARCH)
      AND task_id != s_current_task;
  IF s_pending_interrupt IS NOT NULL THEN
    trace1('EXECUTE_BACKUP_ARCH: Avoiding TASK_INC_ARCH');
    RAISE E_RETRY_ERROR;
  END IF;
 
--
--
  l_delete := (p_task_rec.param_num2 = 1);
 
  dbms_ra_storage.backupArch(p_task_rec.db_key,
                              p_task_rec.param,
                              TRUE,
                              l_delete);
END execute_backup_arch;
 
--
--
--
--
--
--
PROCEDURE execute_inc_arch (p_task_rec IN OUT NOCOPY task%ROWTYPE) IS
  l_delete  BOOLEAN;
BEGIN
  trace1('EXECUTE_INC_ARCH: Performing backup of incomplete arch');
  tracex('EXECUTE_INC_ARCH: DB: ' || p_task_rec.db_key ||
                                ' db_id: ' || p_task_rec.param_num1 ||
                                ' filename: ' || p_task_rec.param);
 
  wait_for_repair (NULL, p_task_rec.db_key);
 
--
--
--
  SELECT MIN(task_id) INTO s_pending_interrupt
    FROM task
    WHERE db_key = p_task_rec.db_key
      AND param = p_task_rec.param
      AND task_type IN (TASK_INC_ARCH, TASK_BACKUP_ARCH)
      AND state = STATE_RUNNING
      AND task_id != s_current_task;
  IF s_pending_interrupt IS NOT NULL THEN
    trace1('EXECUTE_INC_ARCH: Avoiding other backup task');
    RAISE E_RETRY_ERROR;
  END IF;
 
--
--
  l_delete := (p_task_rec.param_num2 = 1);
 
  dbms_ra_storage.backupArch(p_task_rec.db_key,
                              p_task_rec.param,
                              FALSE,
                              l_delete);
END execute_inc_arch;
 
--
--
--
PROCEDURE execute_index_backup  (p_task_rec IN OUT NOCOPY task%ROWTYPE) IS
  l_resource_wait_count NUMBER;
  l_max_vb_key          NUMBER;
  l_max_vb_key2         NUMBER;
  l_processed           BOOLEAN;
  l_flags               NUMBER;
  l_bpkey               NUMBER := NULL;
  l_count               NUMBER;
  l_df_key              NUMBER;
  l_size                NUMBER;
  l_complete            BOOLEAN;
  l_ftype               NUMBER;
  l_dbid                NUMBER;
  new_task_rec          task%ROWTYPE;
  l_sameendian          BINARY_INTEGER;
  l_repcnt              NUMBER;
  l_vcbp                NUMBER;
 
BEGIN
  trace1('EXECUTE_INDEX_BACKUP: Performing Backup Task ' || s_current_task);
  tracex('EXECUTE_INDEX_BACKUP: DB: ' || p_task_rec.db_key ||
                           ' bpkey: ' || p_task_rec.param_num1 ||
                          ' update: ' || p_task_rec.param_num2 ||
                      'polling key: ' || p_task_rec.param_num3 ||
                ' polling filename: ' || p_task_rec.param);
 
--
--
--
  wait_for_repair (NULL, p_task_rec.db_key);
 
--
--
--
--
--
  IF bittst(p_task_rec.flags, TASKS_OUT_OF_ORDER) THEN
    SELECT MAX(vb_key)INTO l_max_vb_key
      FROM vbdf
      WHERE db_key = p_task_rec.db_key;
  END IF;
 
--
--
--
  BEGIN
--
--
--
--
--
    s_polled_input := bittst(p_task_rec.flags, TASKS_POLLED_INPUT);
 
    DBMS_RA_POOL.PROCESS_BACKUP_PIECE(p_task_rec.db_key,
                                      p_task_rec.param_num1,
                                      NVL(p_task_rec.param_num2, 0),
                                      l_processed);
 
    s_polled_input := FALSE;
  EXCEPTION
    WHEN OTHERS THEN
      save_error;
--
--
      IF s_polled_input THEN
        s_polled_input := FALSE;
        sys.kbrsi_icd.rsIsComplete(fname    => p_task_rec.param,
                                   filesize => l_size,
                                   complete => l_complete,
                                   ftype    => l_ftype,
                                   same_endian => l_sameendian,
                                   dbid     => l_dbid);
        IF NOT l_complete THEN
          trace1('EXECUTE_INDEX_BACKUP: disappearing file ' ||
                 p_task_rec.param);
 
          ROLLBACK;
          UPDATE polling_history
            SET fail_time = SYSTIMESTAMP, status = POLLING_HISTORY_PROCESSING
            WHERE fname = p_task_rec.param;
          COMMIT;
 
          DBMS_RA_SCHEDULER.LOG_ERROR (
                 p_errno     => DBMS_RA_SCHEDULER.E_MISSING_POLL_FILE_NUM,
                 p_param1    => p_task_rec.param,
                 p_component => 'INDEX_BACKUP',
                 p_severity  => DBMS_RA_SCHEDULER.SEVERITY_WARNING,
                 p_db_key    => p_task_rec.db_key);
          clear_error;
          sys.kbrsi_icd.rsClearErr;
          RETURN;
        ELSE
          RAISE;
        END IF;
      ELSE
        RAISE;
      END IF;
  END;
 
  IF l_processed THEN
--
--
--
    IF NOT bittst(p_task_rec.flags, TASKS_DELETE_INPUT)
    AND s_aggressive_delete > 0
    THEN
      FOR x IN (SELECT handle, pieceinc
                FROM sbt_catalog
                WHERE bp_key = p_task_rec.param_num1
                  AND ftype = 'F'
                  AND db_key = p_task_rec.db_key)
      LOOP
--
        new_task_rec.task_type   := DBMS_RA_SCHEDULER.TASK_DEFERRED_DELETE;
        new_task_rec.flags       := 0;
        new_task_rec.db_key      := p_task_rec.db_key;
        new_task_rec.param_char1 := x.handle;
        new_task_rec.param_num1  := DBMS_RA_INT.KBRSCHKTYPE_FILE;
        new_task_rec.param_num2  := p_task_rec.param_num1;
        new_task_rec.param_char2 := x.pieceinc;
        trace1 ('EXECUTE_INDEX_BACKUP: Defer task queued ' || x.handle);
 
--
--
        DBMS_RA_SCHEDULER.NEW_TASK (task_rec => new_task_rec,
                                     p_commit => FALSE);
        COMMIT;
      END LOOP;
    END IF;
 
--
--
--
    fix_error(p_error_num => E_CORRUPT_BLOCK_NUM,
              p_db_key    => p_task_rec.db_key);
 
--
--
--
--
--
 
--
--
--
--
    SELECT COUNT(*) INTO l_count
      FROM error_log
      WHERE error_num = E_INCR_LOST_NUM
        AND db_key = p_task_rec.db_key;
 
   IF l_count > 0 THEN
--
--
--
     SELECT MAX(v1.df_key) INTO l_df_key
       FROM vbdf v1, df
       WHERE db_key = p_task_rec.db_key
         AND v1.df_key = df.df_key
         AND df.drop_scn IS NULL
         AND NOT EXISTS (SELECT 1 
                           FROM vbdf v2
                           WHERE v1.db_key = v2.db_key
                             AND v1.df_key = v2.df_key
                             AND v2.state = DBMS_RA_POOL.VBDF_COMPLETE);
 
     trace1('EXECUTE_INDEX_BACKUP: Missing pool for df ' || print(l_df_key));
 
     IF l_df_key IS NULL THEN
       fix_error (p_error_num => E_INCR_LOST_NUM,
                  p_db_key    => p_task_rec.db_key);
       COMMIT;
     END IF;
    END IF;
  END IF;
 
--
--
--
--
--
  IF  NOT l_processed
  AND p_task_rec.param IS NOT NULL
  AND NVL(p_task_rec.param_num2, 0) = 0  /* not populating pool */
  THEN
    trace1('EXECUTE_INDEX_BACKUP - Polled backup being copied');
--
    l_bpkey := p_task_rec.param_num1;
    IF NOT DBMS_RA_INT.READ_LOCK(DBMS_RA_INT.KEY_BP, l_bpkey) THEN
      trace1('EXECUTE_INDEX_BACKUP - Polled backup no longer exists');
      RETURN;
    END IF;
 
    BEGIN
      DBMS_RA_STORAGE.COPY_PIECE(p_task_rec.param, p_task_rec.db_key);
    EXCEPTION
      WHEN OTHERS THEN
        save_error;
        DBMS_RA_INT.UNLOCK(DBMS_RA_INT.KEY_BP, l_bpkey);
        RAISE;
    END;
 
    DBMS_RA_INT.UNLOCK(DBMS_RA_INT.KEY_BP, l_bpkey);
  END IF;
 
  trace1('EXECUTE_INDEX_BACKUP - BACKUP TASK FINISHED');
 
--
--
  IF l_processed AND p_task_rec.param IS NOT NULL THEN
--
--
--
    SELECT count(*) INTO l_repcnt
      FROM odb o, rep_server rs
      WHERE o.prot_key = rs.prot_key
        AND o.db_key = p_task_rec.db_key
        AND rs.status = 'A';
    IF l_repcnt > 0 THEN
      SELECT MAX(vcbp_key) INTO l_vcbp
        FROM vbdf
        WHERE db_key = p_task_rec.db_key
          AND srcbp_key = p_task_rec.param_num1;
      trace1 ('EXECUTE_INDEX_BACKUP: Creating replication tasks for origbp=' ||
              p_task_rec.param_num1 || ', newbp=' || l_vcbp);
      IF l_vcbp IS NOT NULL THEN
--
--
--
        replicate_one_bp (p_db_key => p_task_rec.db_key,
                          p_bp_key => l_vcbp);
 
        trace1('EXECUTE_INDEX_BACKUP - Replication queued');
      END IF;
    END IF;
 
  END IF;
 
  IF bittst(p_task_rec.flags, TASKS_DELETE_INPUT) THEN
 
--
--
--
--
--
--
--
--
    sys.kbrsi_icd.rsDeleteFile(p_task_rec.param);
 
--
--
--
    DBMS_RA_STORAGE.FREE_BACKUP_PIECE(
                      p_dbkey     => p_task_rec.db_key,
                      p_piecename => p_task_rec.param,
                      p_ftype     => DBMS_RA_INT.KBRSCHKTYPE_FILE);
 
--
--
--
    COMMIT;
    UPDATE polling_history SET status = POLLING_HISTORY_REMOVED
      WHERE poll_key = p_task_rec.param_num3
        AND status = POLLING_HISTORY_COMPLETED
        AND fname = p_task_rec.param;
    COMMIT;
  END IF;
 
--
--
--
  release_ordering_wait(p_task_rec.db_key);
 
EXCEPTION
  WHEN dbms_ra_int.incremental_no_fit THEN
    save_error;
--
--
--
    trace1 ('EXECUTE_INDEX_BACKUP: Out of order backup piece: ' ||
                        p_task_rec.db_key || ' ' || p_task_rec.param_num1);
 
 
--
--
--
--
--
--
--
--
--
--
--
--
    IF s_cached_storage THEN
      DBMS_RA_STORAGE.FREE_TASK_STORAGE;
    END IF;
 
    SYS.KBRSI_ICD.RSSCHEDLOCK (waitforwork => 0);
 
--
--
--
    SELECT MAX(vb_key)INTO l_max_vb_key2
      FROM vbdf
      WHERE db_key = p_task_rec.db_key;
 
    trace1 ('EXECUTE_INDEX_BACKUP: new vb_key=' || print(l_max_vb_key2) ||
                                  '; old vb_key=' || print(l_max_vb_key) ||
                                  '; flags =' || print(p_task_rec.flags));
 
--
--
--
--
    IF bittst(p_task_rec.flags, TASKS_OUT_OF_ORDER) AND
       (NVL(l_max_vb_key,0) = NVL(l_max_vb_key2,0)) THEN
      UPDATE task
        SET state = STATE_ORDERING_WAIT, ba_session_id = NULL
        WHERE (task_id = s_current_task)
        RETURNING BITAND(flags,TASKS_BLOCKING_TASK) INTO l_flags;
    ELSE
--
--
--
--
--
--
      UPDATE task
        SET state = STATE_EXECUTABLE, 
            ba_session_id = NULL,
            flags = flags - BITAND(flags, TASKS_OUT_OF_ORDER) 
                          + TASKS_OUT_OF_ORDER
        WHERE (task_id = s_current_task)
        RETURNING BITAND(flags,TASKS_BLOCKING_TASK) INTO l_flags;
    END IF;
 
--
--
--
    IF l_flags <> 0 THEN
      UPDATE task
        SET pending_interrupt = NULL,
            state = (CASE state 
                       WHEN STATE_RUNNING THEN STATE_RUNNING 
                       WHEN STATE_CANCEL THEN STATE_CANCEL 
                       WHEN STATE_CANCELING THEN STATE_CANCELING 
                       ELSE STATE_EXECUTABLE 
                     END),
            ba_session_id = NULL                
        WHERE pending_interrupt = s_current_task;
    END IF;
 
--
--
--
--
    UPDATE sessions
      SET current_task = NULL,
          current_task_type = NULL
      WHERE ba_session_id = s_ba_session_id;
 
--
--
--
    p_task_rec := NULL;
    COMMIT;
    SYS.KBRSI_ICD.RSSCHEDUNLOCK(nomorejobs => 0);
    clear_error;
 
  WHEN E_RETRY_ERROR THEN -- Expected interruption
    save_error;
    RAISE;
 
  WHEN E_RETRY_RESERVE THEN -- Expected interruption
    save_error;
    RAISE;
 
  WHEN OTHERS THEN
    save_error;
    trace1 ('EXECUTE_INDEX_BACKUP: Unloved backup piece: db ' ||
             p_task_rec.db_key || ', backupset key ' || p_task_rec.param_num1);
    trace1 ('EXECUTE_INDEX_BACKUP: Error returned is ' || SQLERRM);
    RAISE;  -- More info recorded in scheduler exception handler
END execute_index_backup;
 
--
--
--
PROCEDURE execute_newdfkey (p_task_rec IN OUT NOCOPY task%ROWTYPE) IS
  l_count   NUMBER;
  l_dbkey   NUMBER;
BEGIN
  trace1('EXECUTE_NEWDFKEY: Handling a new datafile ' || s_current_task);
  tracex('EXECUTE_NEWDFKEY: dfkey: ' || p_task_rec.param_num1 ||
         ' dbinc_key: ' || p_task_rec.param_num2 ||
         ' ;pdbinc_key: ' || p_task_rec.param_num3);
  
--
  SELECT MAX(db_key) INTO l_dbkey FROM dbinc
    WHERE dbinc_key = p_task_rec.param_num2;
 
--
  SELECT COUNT(*) INTO l_count FROM task 
    WHERE state = STATE_ORDERING_WAIT
      AND db_key = l_dbkey;
  IF l_count = 0 THEN
    RETURN;
  END IF;
 
--
  SELECT COUNT(*) INTO l_count FROM df
    WHERE df_key = p_task_rec.param_num1
    AND   dbinc_key = p_task_rec.param_num2
    AND   pdbinc_key = p_task_rec.param_num3;
  IF l_count = 0 THEN
--
    IF sysdate - (1/24) > p_task_rec.schedule_time THEN
      RETURN;  -- We give up
    ELSE
      RAISE E_RETRY_ERROR;  -- Try again later
    END IF;
  END IF;
 
--
  release_ordering_wait(l_dbkey);
END execute_newdfkey;
 
--
--
--
--
PROCEDURE release_ordering_wait (p_dbkey IN NUMBER) IS
  l_rcount NUMBER := 0;
BEGIN
  trace1('release_ordering_wait ' || p_dbkey);
 
--
--
--
--
--
  SYS.KBRSI_ICD.RSSCHEDLOCK (waitforwork => 0);
  UPDATE task
    SET state = STATE_EXECUTABLE
    WHERE (state = STATE_ORDERING_WAIT) AND (db_key = p_dbkey);
  l_rcount := SQL%ROWCOUNT;
  COMMIT;
  SYS.KBRSI_ICD.RSSCHEDUNLOCK(nomorejobs => 0);
 
--
--
--
  IF l_rcount > 0 THEN
    SYS.KBRSI_ICD.RSRUNSCHED;
  END IF;
EXCEPTION
  WHEN OTHERS THEN
    save_error;
    SYS.KBRSI_ICD.RSSCHEDUNLOCK(nomorejobs => 0);
    RAISE;
END release_ordering_wait;
 
 
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE release_restore_wait (p_instance NUMBER DEFAULT NULL) IS
  l_rcount NUMBER := 0;
BEGIN
--
--
--
  SYS.KBRSI_ICD.RSSCHEDLOCK (waitforwork => 0);
  UPDATE task
    SET state = STATE_EXECUTABLE
    WHERE task_id = (SELECT MIN(task_id) 
                       FROM task
                      WHERE state = STATE_RESTORE_WAIT
                        AND execute_inst_id = NVL(p_instance, s_instance));
  l_rcount := SQL%ROWCOUNT;
  COMMIT;
  SYS.KBRSI_ICD.RSSCHEDUNLOCK(nomorejobs => 0);
  trace1 ('RELEASE_RESTORE_WAIT: Tasks released=' || l_rcount);
 
--
--
--
  IF l_rcount > 0 THEN
    SYS.KBRSI_ICD.RSRUNSCHED;
  END IF;
EXCEPTION
  WHEN OTHERS THEN
    save_error;
    SYS.KBRSI_ICD.RSSCHEDUNLOCK(nomorejobs => 0);
    RAISE;
END release_restore_wait;
 
 
--
--
--
--
--
--
--
PROCEDURE execute_quiesce IS
  l_dummy_bool  BOOLEAN;
BEGIN
  tracex ('EXECUTE_QUIESCE');
  l_dummy_bool := SYS.KBRSI_ICD.RSQUIESCECHECK (wait=>TRUE);
  SYS.KBRSI_ICD.RSQUIESCEUNLOCK;
END execute_quiesce;
 
--
--
--
--
--
--
--
PROCEDURE execute_spawn_sbt(p_task_rec IN OUT NOCOPY task%ROWTYPE) IS
BEGIN
  tracex ('EXECUTE_SPAWN_SBT : Performing spawn sbt ' || s_current_task ||
          ' lib_key=' || p_task_rec.param_num1 ||
          ';purge=' || p_task_rec.param_num2);
 
  IF (p_task_rec.param_num2 = 1) THEN -- forpurge?
     spawn_purge_sbt_job(p_libkey => p_task_rec.param_num1);
  ELSE
     spawn_sbt_job(p_libkey => p_task_rec.param_num1);
  END IF;
END execute_spawn_sbt;
 
--
--
--
PROCEDURE execute_restore (p_task_rec IN OUT NOCOPY task%ROWTYPE) IS
  l_skip BOOLEAN := FALSE;
BEGIN
  tracex ('EXECUTE_RESTORE: Performing Restore task ' || s_current_task ||
          '; sessionid=' || p_task_rec.param_char1);
  tracex ('EXECUTE_RESTORE: ' ||
          'handle=' || p_task_rec.param_char2);
  tracex ('EXECUTE_RESTORE: ' ||
          'reqid=' || p_task_rec.param_num1 ||
          '; bpkey=' || p_task_rec.param_num2);
 
  IF (get_savepoint IS NOT NULL) THEN
    trace1('EXECUTE_RESTORE: Cannot restart this task');
    l_skip := TRUE;
  END IF;
 
  IF (p_task_rec.com_time + (1/24/60/60 * s_servlet_wait_seconds)) < sysdate
  THEN
    trace1('EXECUTE_RESTORE: Servlet com_time is too old');
    l_skip := TRUE;
  END IF;
 
--
--
--
  IF NOT l_skip THEN
    sys.kbrsi_icd.restoreVbTask(reqid => p_task_rec.param_num1,
                                bpkey => p_task_rec.param_num2);
  END IF;
 
--
  release_restore_wait;
 
EXCEPTION
  WHEN E_NO_MORE_SGA THEN
    save_error;
    RAISE;
  WHEN dbms_ra_int.bad_block_metadata THEN
    save_error;
    SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(dbms_ra_scheduler.e_bad_restore_num,
                                          p_task_rec.param_num2);
  WHEN OTHERS THEN
    save_error;
    release_restore_wait;
    RAISE;
END execute_restore;                    /* dbms_ra_scheduler.execute_restore */
 
--
--
--
PROCEDURE execute_poll (p_task_rec IN OUT NOCOPY task%ROWTYPE) IS
  l_poll_flags        NUMBER;
  l_delete_input      BOOLEAN;
  l_task_flags        NUMBER;
  l_polling_directory storage_dests.dest%TYPE;
  l_polling_name      poll.poll_name%TYPE;
  l_omf_namespace     VARCHAR2(1)   := NULL;
 
--
  CURSOR file_cursor IS
    SELECT fname_krbmsft
    FROM sys.rai_js_search_file
    WHERE (fname_krbmsft NOT IN
                     (SELECT fname
                      FROM polling_history ph
                      WHERE (poll_key = p_task_rec.param_num1) AND
                            (ph.status NOT IN (POLLING_HISTORY_PROCESSING,
                                               POLLING_HISTORY_REMOVED))));
 
  l_fname             VARCHAR2(513);
  l_ftype             NUMBER;
  l_dbid              NUMBER;
  l_size              NUMBER;
  l_old_size          NUMBER;
  l_complete          BOOLEAN;
  l_backuppiece_id    NUMBER;
  l_db_key            NUMBER;
  l_delete_this_file  BOOLEAN;
  l_newfname          VARCHAR2(513);
  task_rec            task%ROWTYPE;
  l_count             NUMBER;
  l_odb_sameendian    NUMBER;
  l_piece_sameendian  NUMBER;
  l_outfname          VARCHAR2(1024);
  l_pstatus           VARCHAR2(1);
BEGIN
  tracex ('EXECUTE_POLL: Performing Poll task ' || s_current_task ||
          '; poll_key=' || p_task_rec.param_num1);
 
--
--
--
--
--
--
--
--
--
  SELECT poll.poll_name, poll.poll_flags,   sd.dest
    INTO l_polling_name, l_poll_flags,      l_polling_directory
    FROM poll, sl, storage_dests sd
    WHERE poll.sl_key = sl.sl_key
      AND poll.poll_key = p_task_rec.param_num1
      AND poll.sl_key = sd.sl_key;
 
  l_delete_input := bittst(l_poll_flags, POLL_FLAGS_DELETE_INPUT);
 
  trace1 ('EXECUTE_POLL: Delete_input =' || print(l_delete_input) ||
                         ';  directory=' || l_polling_directory ||
                         ';  flags=' || l_poll_flags);
 
--
--
--
--
  IF bittst(l_poll_flags, POLL_FLAGS_UNDO_DBID_ERROR) THEN
    UPDATE polling_history
      SET fail_time = SYSTIMESTAMP, status = POLLING_HISTORY_PROCESSING
      WHERE (poll_key = p_task_rec.param_num1)
        AND (status = POLLING_HISTORY_BAD_DBID);
    trace1 ('EXECUTE_POLL: Reprocessing ' || SQL%ROWCOUNT || 
                                                            ' bad dbid files');
    COMMIT;
  END IF;
 
--
--
--
  IF bittst(l_poll_flags,POLL_FLAGS_UNDO_TIMEOUT_ERROR) THEN
    UPDATE polling_history
      SET fail_time = SYSTIMESTAMP, status = POLLING_HISTORY_PROCESSING
      WHERE (poll_key = p_task_rec.param_num1)
        AND (status = POLLING_HISTORY_TIMED_OUT);
    trace1 ('EXECUTE_POLL: Reprocessing ' || SQL%ROWCOUNT || 
                                                           ' timed out files');
    COMMIT;
  END IF;
 
--
--
--
  l_poll_flags := 
        BITAND(l_poll_flags, 
               POLL_FLAGS_UNDO_DBID_ERROR + POLL_FLAGS_UNDO_TIMEOUT_ERROR);
 
  IF l_poll_flags <> 0 THEN 
    l_poll_flags := bitclr(l_poll_flags, 
                     POLL_FLAGS_UNDO_DBID_ERROR+POLL_FLAGS_UNDO_TIMEOUT_ERROR);
 
    UPDATE poll
      SET poll_flags = poll_flags - BITAND (poll_flags, l_poll_flags)
      WHERE poll.poll_key = p_task_rec.param_num1;
    COMMIT;
  END IF;
 
--
--
--
--
  UPDATE polling_history
    SET fail_time = NULL, status = POLLING_HISTORY_TIMED_OUT
    WHERE (poll_key = p_task_rec.param_num1)
      AND (status = POLLING_HISTORY_PROCESSING)
      AND ((SYSTIMESTAMP - fail_time) > s_polling_timeout_interval);
  trace1 ('EXECUTE_POLL: Timed out ' || SQL%ROWCOUNT || ' files');
  COMMIT;
 
--
--
--
  sys.dbms_backup_restore.searchFiles(pattern => l_polling_directory,
                                      ns      => l_omf_namespace,
                                      ccf     => FALSE,
                                      omf     => FALSE,
                                      ftype   => NULL,
                                      onlyfnm => TRUE,
                                      normfnm => FALSE);
  trace1 ('EXECUTE_POLL: File list created');
 
--
--
--
  OPEN file_cursor;
  LOOP
--
--
--
--
--
--
--
    FETCH file_cursor INTO l_fname;
    EXIT WHEN file_cursor%NOTFOUND;
 
    trace1 ('EXECUTE_POLL: name=' || l_fname);
 
--
--
--
    sys.kbrsi_icd.rsIsComplete(fname       => l_fname,
                               filesize    => l_size,
                               complete    => l_complete,
                               ftype       => l_ftype,
                               same_endian => l_piece_sameendian,
                               dbid        => l_dbid);
 
    IF l_complete THEN
      trace1 ('EXECUTE_POLL: completed=' || print(l_complete) || 
              ',dbid=' || l_dbid ||
              ', ftype ' || l_ftype ||
              ', size ' || l_size ||
              ', same_endian ' || l_piece_sameendian ||
              ', name ' || l_fname);
 
--
      IF l_piece_sameendian = 0 THEN                          -- archivelog xtt
 
        SELECT DECODE(odb.same_endian, 'N', 0, 'Y', 1, -1)
          INTO l_piece_sameendian
          FROM odb
         WHERE db_key = (SELECT db_key 
                           FROM db 
                          WHERE db_id = l_dbid);
 
        IF l_piece_sameendian != 0 THEN
          /* Update db about this */
          UPDATE odb SET same_endian='N'
           WHERE db_key = (SELECT db_key
                           FROM db
                          WHERE db_id = l_dbid);
          COMMIT;
        END IF;
      END IF;
 
    ELSE
      trace1 ('EXECUTE_POLL: Found incomplete ' || l_fname ||
              ' size ' || l_size);
    END IF;
 
--
--
--
--
    SELECT MIN(NVL(fsize,0)) INTO l_old_size 
      FROM polling_history
      WHERE (poll_key=p_task_rec.param_num1) AND (fname = l_fname);
 
    IF l_old_size IS NULL THEN
--
--
--
      INSERT INTO polling_history (fname, fail_time, fsize, status,
                                   poll_key)
        VALUES (l_fname, SYSTIMESTAMP, l_size, POLLING_HISTORY_PROCESSING, 
                p_task_rec.param_num1);
    ELSIF (l_old_size < l_size) THEN
--
--
--
      UPDATE polling_history 
        SET fail_time = SYSTIMESTAMP, fsize = l_size
        WHERE (poll_key=p_task_rec.param_num1) AND (fname = l_fname);
    END IF;
 
--
--
--
--
    IF (l_complete) THEN
      BEGIN
        SELECT db.db_key, DECODE(odb.same_endian, 'N', 0, 'Y', 1, -1)  
          INTO l_db_key, l_odb_sameendian 
          FROM db, odb, prot
          WHERE db_id = l_dbid
            AND db.db_key = odb.db_key
--
            AND odb.db_state IS NULL
            AND odb.prot_key = prot.prot_key
            AND prot.poll_key = p_task_rec.param_num1;
        trace1 ('EXECUTE_POLL: db_key=' || l_db_key ||
                ' sameendian=' || l_odb_sameendian);
 
      EXCEPTION
        WHEN NO_DATA_FOUND THEN
          save_error;
          trace1 ('EXECUTE_POLL: Ignoring unknown dbid: ' || l_dbid ||
                          ' for polling policy ' || l_polling_name);
 
--
--
--
--
--
          UPDATE polling_history
            SET fail_time = NULL, status = POLLING_HISTORY_BAD_DBID
            WHERE (poll_key=p_task_rec.param_num1) AND (fname = l_fname);
          COMMIT;
          clear_error;
          CONTINUE;
      END;
    ELSE
--
--
--
      COMMIT;
      CONTINUE;
    END IF;
 
--
--
--
--
--
--
--
--
    BEGIN
      SELECT 1 INTO l_count FROM bp
        WHERE handle = dbms_ra_int.file2handle(l_fname);
 
--
      log_error (p_errno => E_DUP_FILE_NUM,
                 p_param1 => l_fname,
                 p_component => 'POLLING',
                 p_severity  => SEVERITY_WARNING,
                 p_param_num  => p_task_rec.param_num1,
                 p_param_char => l_fname);
      trace1('EXECUTE_POLL: duplicate file ' || l_fname ||
                                                       ' of type ' || l_ftype);
--
      UPDATE polling_history 
        SET fail_time = NULL, status = POLLING_HISTORY_COMPLETED
        WHERE ((poll_key=p_task_rec.param_num1) AND (fname = l_fname));
      COMMIT;
      CONTINUE;
    EXCEPTION
      WHEN no_data_found THEN
        save_error;
        NULL;  /* The expected result */
        clear_error;
    END;
 
--
--
--
--
    CASE
      WHEN (l_ftype IN
                     (FTYPE_ARCHIVELOG,FTYPE_ARCHBACKUP,FTYPE_AUTOBACKUP)) THEN
        BEGIN
          IF l_ftype = FTYPE_ARCHIVELOG THEN
--
--
--
            trace1 ('EXECUTE_POLL: Archivelog');
            l_size := l_size + (4 * 32 * 1024);  -- max block size 32k
          ELSE
            trace1 ('EXECUTE_POLL: Archbackup or Autopbackup');
          END IF;
 
--
          DBMS_RA_STORAGE.COPY_PIECE(l_fname, l_db_key);
          l_delete_this_file := l_delete_input;
              
          fix_error (p_error_num => E_BACKUP_FAILED,
                     p_db_key    => l_db_key);
 
        EXCEPTION
          WHEN E_BACKUP_IO_ERROR_RMAN THEN
            save_error;
--
--
--
            log_error (p_errno => E_BAD_FILE_NUM,
                       p_param1 => l_fname,
                       p_component => 'POLLING',
                       p_severity  => SEVERITY_ERROR,
                       p_param_num  => p_task_rec.param_num1,
                       p_param_char => l_fname);
 
            UPDATE polling_history 
              SET fail_time = NULL, status = POLLING_HISTORY_ERROR
              WHERE ((poll_key=p_task_rec.param_num1) AND (fname = l_fname));
            COMMIT;
            clear_error;
            CONTINUE;
          WHEN E_NO_MORE_STORAGE OR E_PIECE_TOO_BIG THEN
            save_error;
            log_error (p_errno => E_BACKUP_FAILED,
                       p_component => 'POLLING',
                       p_severity  => SEVERITY_ERROR,
                       p_db_key    => l_db_key,
                       p_param1 => DBMS_RA_INT.DBKEY2NAME(l_db_key));
 
            UPDATE polling_history 
              SET fail_time = NULL, status = POLLING_HISTORY_ERROR
              WHERE ((poll_key=p_task_rec.param_num1) AND (fname = l_fname));
            COMMIT;    
            clear_error;
            CONTINUE;
        END;
 
      WHEN (l_ftype IN (FTYPE_BACKUP,FTYPE_INCBACKUP)) THEN
        BEGIN
          IF l_odb_sameendian = 0 OR l_piece_sameendian = 0 THEN
--
--
--
            IF l_odb_sameendian != 0 AND l_piece_sameendian = 0 THEN
            /* Update db about this */
               UPDATE odb SET same_endian='N'
               WHERE db_key = l_db_key;
               COMMIT;
            END IF;
--
--
            trace1 ('EXECUTE_POLL: same endian from db : ' || l_odb_sameendian 
                    || ' same endian inferred from piece ' || 
                    l_piece_sameendian);
            BEGIN
              DBMS_RA_STORAGE.COPY_PIECE(l_fname, 
                                         l_db_key, 
                                         COPY_BA_POLL /*KRBYX_ORS_POLL*/);
              fix_error (p_error_num => E_BACKUP_FAILED,
                         p_db_key    => l_db_key);
 
            EXCEPTION
            WHEN E_NO_MORE_STORAGE OR E_PIECE_TOO_BIG THEN
              save_error;
              log_error (p_errno => E_BACKUP_FAILED,
                         p_component => 'POLLING',
                         p_severity  => SEVERITY_ERROR,
                         p_db_key    => l_db_key,
                         p_param1 => DBMS_RA_INT.DBKEY2NAME(l_db_key));
 
              UPDATE polling_history 
                SET fail_time = NULL, status = POLLING_HISTORY_ERROR
                WHERE ((poll_key=p_task_rec.param_num1) AND (fname = l_fname));
              COMMIT;
              clear_error;
              CONTINUE;
            END;
            l_outfname := dbms_ra_int.file2handle(l_fname);
 
--
--
--
--
--
            SELECT MIN(bp.bp_key) into l_backuppiece_id
              FROM bp,bdf WHERE handle = l_outfname 
                          AND   bdf.bs_key = bp.bs_key;
 
            l_delete_this_file := l_delete_input;
            task_rec.param := NULL;
            l_task_flags := 0;
          ELSE
--
--
--
--
--
            sys.kbrsi_icd.rsInspectBackupPiece(
                 handle        => l_fname,
                 vbkey         => null,
                 bpsize        => l_size,
                 chktype       => DBMS_RA_INT.KBRSCHKTYPE_DISK,
                 fno           => null,
                 lib_key       => null,/* local disk */
                 ct_key        => null,
                 bpkey         => l_backuppiece_id,
                 template_key  => null);
 
            l_delete_this_file := FALSE;
            l_task_flags := TASKS_POLLED_INPUT;
            IF l_delete_input THEN
              l_task_flags := TASKS_POLLED_INPUT+TASKS_DELETE_INPUT;
            END IF;
            task_rec.param := l_fname;
          END IF;
 
          trace1 ('EXECUTE_POLL: db_key: ' || l_db_key ||
                  ', bpkey: ' || l_backuppiece_id);
 
--
--
--
--
          IF (l_backuppiece_id IS NOT NULL) THEN 
            task_rec.task_type   := TASK_INDEX_BACKUP;
            task_rec.flags       := l_task_flags;
            task_rec.db_key      := l_db_key;
            task_rec.param_num1  := l_backuppiece_id;
            task_rec.param_num3  := p_task_rec.param_num1; -- poll_key
            new_task (task_rec, FALSE);  -- nocommit
          END IF;
        EXCEPTION
          WHEN OTHERS THEN
            save_error;
            trace1 ('EXECUTE_POLL: Processing datafile backup returned: ' ||
                    SQLERRM);
 
            UPDATE polling_history 
              SET fail_time = NULL, status = POLLING_HISTORY_ERROR
              WHERE ((poll_key=p_task_rec.param_num1) AND (fname = l_fname));
            COMMIT;
 
--
            sys.kbrsi_icd.rsClearErr;
 
            clear_error;
            CONTINUE;
        END;
 
      ELSE
        trace1('EXECUTE_POLL: Unknown file ' || l_fname ||
                                                       ' of type ' || l_ftype);
        UPDATE polling_history 
          SET fail_time = NULL, status = POLLING_HISTORY_BAD_FTYPE
          WHERE ((poll_key=p_task_rec.param_num1) AND (fname = l_fname));
        COMMIT;
        CONTINUE;
    END CASE;
 
--
--
--
    l_pstatus := POLLING_HISTORY_COMPLETED;
    IF l_delete_this_file THEN
      sys.kbrsi_icd.rsDeleteFile(l_fname);
      l_pstatus := POLLING_HISTORY_REMOVED;
    END IF;
 
--
--
--
    UPDATE polling_history 
      SET fail_time = NULL, status = l_pstatus
      WHERE ((poll_key=p_task_rec.param_num1) AND (fname = l_fname));
 
    COMMIT;
  END LOOP;
  CLOSE file_cursor;
 
--
--
--
--
  SELECT COUNT(*) INTO l_count
    FROM poll
    WHERE (poll_key = p_task_rec.param_num1) AND
          (poll_last_prune + s_polling_deleted_files_check < SYSTIMESTAMP);
  trace1('EXECUTE_POLL:  prune check is ' || l_count);
 
  IF l_count > 0 THEN
    DELETE FROM polling_history
       WHERE (poll_key = p_task_rec.param_num1) AND
            NOT EXISTS (SELECT 1 FROM sys.rai_js_search_file sf
                          WHERE sf.fname_krbmsft = fname);
    trace1('EXECUTE_POLL:  prune check deleted ' || SQL%ROWCOUNT || ' row(s)');
 
--
--
--
    FOR x IN (SELECT param_char, error_num
                FROM error_log
                WHERE error_num IN (E_BAD_FILE_NUM, E_DUP_FILE_NUM)
                  AND param_num = p_task_rec.param_num1
                  AND NOT EXISTS (SELECT 1 FROM polling_history
                                  WHERE poll_key = p_task_rec.param_num1
                                    AND fname=param_char)) LOOP
 
      fix_error (p_error_num => x.error_num,
                 p_param_num => p_task_rec.param_num1,
                 p_param_char => x.param_char);
    END LOOP;
 
    UPDATE poll SET poll_last_prune = SYSTIMESTAMP
      WHERE (poll_key = p_task_rec.param_num1);
    COMMIT;
  END IF;
 
 
EXCEPTION
    WHEN NO_DATA_FOUND THEN
      save_error;
--
--
--
--
--
      trace1('EXECUTE_POLL:  detected NO_DATA_FOUND');
      enqueue_verify_timer_task;
      clear_error;
      RETURN; 
END execute_poll;
 
--
--
--
--
PROCEDURE execute_deferred_delete(p_task_rec IN OUT NOCOPY task%ROWTYPE) IS
BEGIN
   tracex ('EXECUTE_DEFERRED_DELETE: Performing execute_deferred_delete ' ||
           'dbkey ' || p_task_rec.db_key ||
           ', bpkey '  || p_task_rec.param_num2 ||
           ', handle ' || p_task_rec.param_char1 ||
           ', fincarn ' || p_task_rec.param_char2 ||
           ', ftype ' || p_task_rec.param_num1);
 
--
--
   IF p_task_rec.param_num2 IS NOT NULL THEN
     DBMS_RA_STORAGE.SWAP_BACKUP_PIECE(p_task_rec.param_num2);
   END IF;
 
   DBMS_RA_STORAGE.FREE_BACKUP_PIECE(
      p_dbkey      => p_task_rec.db_key,
      p_piecename  => p_task_rec.param_char1,
      p_ftype      => p_task_rec.param_num1,
      p_fincarn    => p_task_rec.param_char2,
      p_can_defer  => FALSE);
END execute_deferred_delete;
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE execute_gcopy_compute (p_task_rec IN OUT NOCOPY task%ROWTYPE) IS
  l_ontape          NUMBER;
  l_used            NUMBER;
  l_count           NUMBER;
  l_task            NUMBER;
  l_not_taped_state VARCHAR2(1);
BEGIN
  tracex ('EXECUTE_GCOPY_COMPUTE: Compute odb.not_taped value for ' ||
           'dbkey ' || p_task_rec.db_key);
 
--
--
--
  SELECT MIN(task_id) INTO l_task
    FROM task
    WHERE task_type = TASK_GCOPY_COMPUTE
      AND state = STATE_RUNNING
      AND db_key = p_task_rec.db_key
      AND task_id <> s_current_task;
  IF l_task IS NOT NULL THEN
    s_pending_interrupt := l_task;
    RAISE e_retry_error;
  END IF;
 
--
--
--
  SELECT used_space, not_taped_state INTO l_used, l_not_taped_state
    FROM odb
    WHERE db_key = p_task_rec.db_key;
 
--
  IF l_not_taped_state IN ('V', 'N') OR l_not_taped_state IS NULL THEN
    RETURN;
  END IF;
  l_not_taped_state := 'V';
 
--
--
--
--
--
  l_ontape := dbms_ra_pool.copied_to_tape(p_task_rec.db_key);
 
--
  IF l_ontape = 0 THEN
    SELECT COUNT(*) INTO l_count
      FROM bp
      WHERE db_key = p_task_rec.db_key
        AND lib_key IS NOT NULL
        AND ROWNUM = 1;
    IF l_count = 0 THEN
      l_not_taped_state := 'N';
    END IF;
  END IF;
 
--
--
--
--
--
  UPDATE odb
    SET not_taped = l_used - l_ontape,
        not_taped_state = (CASE
                             WHEN not_taped_state IN ('C', 'B')
                              AND base_reserved_space < (l_used - l_ontape)
                             THEN 'B'
                             ELSE l_not_taped_state
                           END)
    WHERE db_key = p_task_rec.db_key
    RETURNING not_taped_state INTO l_not_taped_state;
  COMMIT;
 
  trace1 ('EXECUTE_GCOPY_COMPUTE: not_taped_state ' || l_not_taped_state ||
          'dbkey ' || p_task_rec.db_key);
 
--
--
--
  IF l_not_taped_state <> 'B' THEN
    fix_error (p_error_num => E_GCOPY_SUSPENDED_NUM,
               p_db_key    => p_task_rec.db_key);
  END IF;
END execute_gcopy_compute;
 
--
--
--
--
--
--
PROCEDURE execute_purge (p_task_rec IN OUT NOCOPY task%ROWTYPE) IS
  l_immediate    BOOLEAN := (s_current_task_type = TASK_PURGE_IMMEDIATE);
  l_neededspace  NUMBER;
BEGIN
  tracex ('EXECUTE_PURGE: Performing Purge task ' || s_current_task ||
          '; sl_key=' || p_task_rec.sl_key ||
          '; db_key=' || p_task_rec.db_key ||
          '; needed space ' || p_task_rec.param_num1);
 
  wait_for_repair (p_task_rec.sl_key, NULL);
 
 
--
--
--
  IF l_immediate THEN
    l_neededspace := NVL(p_task_rec.param_num1, s_alloc_increment);
  ELSE
    SELECT sl_freespace_goal INTO l_neededspace
      FROM sl
      WHERE sl_key = p_task_rec.sl_key;
  END IF;
 
--
--
--
  DBMS_RA_STORAGE.PURGE_STORAGE_LOCATION (p_task_rec.sl_key, 
                                          p_task_rec.db_key, 
                                          l_neededspace,
                                          l_immediate);
END execute_purge;
 
--
--
--
PROCEDURE execute_rm_incomplete_files (sbtonly IN BOOLEAN DEFAULT FALSE) IS
 
--
--
--
  CURSOR sbt_file_cursor IS
     SELECT db_key, sc.handle, sc.pieceinc
       FROM sbt_catalog sc JOIN odb o USING (db_key)
      WHERE sc.ftype = 'F'     -- filter file chunks
        AND sc.bp_key IS NULL  -- filter un-inspected pieces
        AND ((sc.last_entry IS NULL AND
              ((sc.cretime+s_expire_files_interval) < SYSTIMESTAMP))    OR
             ((sc.completed = 'N') AND
              ((sc.last_entry+s_expire_files_interval) < SYSTIMESTAMP)) OR
             (sc.endupload = 'D')                                       OR
             (o.db_state = DB_STATE_IN_DELETE));
 
  l_db_key      NUMBER;
  l_handle      VARCHAR2(512);
  l_pieceinc    VARCHAR2(32);
  l_filename    VARCHAR2(512);
  l_retry_seen  BOOLEAN := FALSE;
BEGIN
  trace1 ('EXECUTE_RM_INCOMPLETE_FILES: Performing RM_Incomplete_Files ' ||
                         s_current_task);
 
--
--
--
  trace1 ('EXECUTE_RM_INCOMPLETE_FILES: SBT File Cleanup');
  OPEN sbt_file_cursor;
  LOOP
    FETCH sbt_file_cursor INTO l_db_key, l_handle, l_pieceinc;
    EXIT WHEN sbt_file_cursor%NOTFOUND;
 
    trace1 ('EXECUTE_RM_INCOMPLETE_FILES: db=' || l_db_key ||
                       '; handle=' || l_handle || '; pieceinc ' || l_pieceinc);
 
--
--
--
    BEGIN
      DBMS_RA_STORAGE.FREE_BACKUP_PIECE(p_dbkey     => l_db_key,
                                         p_piecename => l_handle,
                                         p_fincarn   => l_pieceinc);
    EXCEPTION
      WHEN E_RETRY_ERROR THEN
        save_error;
--
--
--
        trace1('EXECUTE_RM_COMPLETE_FILES: ' || l_handle || ' is locked.');
        l_retry_seen := TRUE;
        clear_error;
        CONTINUE;
    END;
  END LOOP;
  CLOSE sbt_file_cursor;
 
--
--
--
  IF l_retry_seen THEN
    RAISE E_RETRY_ERROR;
  END IF;
 
  trace1 ('EXECUTE_RM_INCOMPLETE_FILES: Done');
 
END execute_rm_incomplete_files;
 
--
--
--
--
--
--
--
PROCEDURE execute_purge_df (p_task_rec IN OUT NOCOPY task%ROWTYPE) IS
BEGIN
  tracex ('EXECUTE_PURGE_DF on' ||
          '  db_key=' || p_task_rec.db_key ||
          '; sl_key=' || p_task_rec.sl_key ||
          '; vb_key=' || p_task_rec.param_num2 ||
          '; df_key=' || p_task_rec.param_num1 ||
          '; type='   || p_task_rec.param_num3);
 
--
--
--
--
--
  s_purging_active := TRUE;
  s_no_wait_on_allocate := TRUE;
 
--
--
--
--
  IF NVL(p_task_rec.purge_reserve,0) > 0 THEN
    DBMS_RA_STORAGE.FINISH_BLOCK_POOL_CHUNK (p_task_rec.db_key);
  END IF;
 
--
--
--
  dbms_ra_pool.purgeDF(p_task_rec.param_num3,   -- Type of purge
                       p_task_rec.param_num1,   -- df_key
                       p_task_rec.param_num2);  -- vb_key
 
EXCEPTION
  WHEN OTHERS THEN
    save_error;
    trace1('EXECUTE_PURGE_DF: Exiting on error: ' || SQLERRM);
    
--
--
--
    DBMS_RA_STORAGE.FINISH_BLOCK_POOL_CHUNK (p_task_rec.db_key);
    RAISE;
 
END execute_purge_df;
 
--
--
--
--
--
--
PROCEDURE execute_purge_dup_df (p_task_rec IN OUT NOCOPY task%ROWTYPE) IS
BEGIN
  tracex ('EXECUTE_PURGE_DUP_DF on' ||
          '  db_key=' || p_task_rec.db_key ||
          '; vb_key=' || p_task_rec.param_num2 ||
          '; df_key=' || p_task_rec.param_num1 ||
          '; keylock='|| p_task_rec.param_num3);
 
--
--
--
--
--
--
  s_purging_active := FALSE;
  s_no_wait_on_allocate := TRUE;
 
--
--
--
  dbms_ra_pool.purgeDupDF(p_task_rec.param_num1,   -- df_key
                          p_task_rec.param_num2,   -- vb_key
                          p_task_rec.param_num3);  -- key lock
END execute_purge_dup_df;
 
--
--
--
--
--
--
PROCEDURE execute_plan_df (p_task_rec IN OUT NOCOPY task%ROWTYPE) IS
  l_count    NUMBER;
  l_libstat  sbt_lib_desc.status%TYPE;
  l_libkey   NUMBER;
BEGIN
  tracex ('EXECUTE_PLAN_DF on' ||
          '  db_key=' || p_task_rec.db_key ||
          '; sl_key=' || p_task_rec.sl_key ||
          '; vb_key=' || p_task_rec.param_num2 ||
          '; df_key=' || p_task_rec.param_num1 ||
          '; type='   || p_task_rec.param_num3 ||
          '; bs_key=' || p_task_rec.param);
 
--
--
--
--
  IF s_current_task_type = TASK_PLAN_SBT THEN
    SELECT MAX(l.status), MAX(l.lib_key) INTO l_libstat, l_libkey
      FROM sbt_task s, task t, sbt_lib_desc l
      WHERE s.task_id = t.sbt_task_id
        AND s.lib_key = l.lib_key
        AND s.bs_key = TO_NUMBER(p_task_rec.param)
        AND t.task_type = TASK_BACKUP_SBT
        AND t.state NOT IN (STATE_RUNNING, STATE_CANCEL, STATE_CANCELING);
    IF l_libstat IS NULL THEN  -- No task left, bail quietly.
      trace1 ('EXECUTE_PLAN_DF can find no SBT for ' ||
              '; bs_key=' || p_task_rec.param);
      RETURN;
    END IF;
 
--
    IF l_libstat <> 'R' THEN
--
      s_pending_interrupt := LIBRARY_PSEUDO_TASK;
      trace1 ('EXECUTE_PLAN_DF has stalled library');
      RAISE e_retry_error;
    END IF;
  END IF;
 
--
--
--
  dbms_ra_pool.planDF(p_task_rec.param_num3,   -- Type of plan
                      p_task_rec.param_num1,   -- df_key
                      p_task_rec.param_num2);  -- vb_key
END execute_plan_df;
 
--
--
--
--
PROCEDURE execute_storage_histogram IS
 
--
  CURSOR sl_cursor IS
     SELECT sl_key
       FROM sl
       WHERE sl_hist_usage IS NOT NULL AND
             sl_space <> 0;
 
  l_sl_key              NUMBER;
  l_sl_hist_usage       NUMBER;
  l_sl_curr_hist_slot   NUMBER;
  l_sl_space            NUMBER;
  l_next_slot           NUMBER;
  l_wrap_slot           NUMBER;
  l_freespace_goal      NUMBER;
  l_count               NUMBER;
  new_task_rec          task%ROWTYPE;
 
BEGIN
  tracex ('EXECUTE_STORAGE_HISTOGRAM');
 
--
--
--
  OPEN sl_cursor;
  LOOP
    FETCH sl_cursor INTO l_sl_key;
    EXIT WHEN sl_cursor%NOTFOUND;
 
 
    BEGIN
--
--
--
      DBMS_RA_STORAGE.LOCK_SL (l_sl_key);
 
--
--
--
      SELECT   sl_hist_usage, NVL(sl_curr_hist_slot,-1), sl_space
        INTO l_sl_hist_usage,  l_sl_curr_hist_slot,   l_sl_space
        FROM sl
        WHERE sl_key = l_sl_key;
 
--
--
--
      l_next_slot := MOD(l_sl_curr_hist_slot+1, s_histogram_cycle_slots);
 
      MERGE INTO storage_histogram
          USING dual ON (sl_key = l_sl_key AND slot = l_next_slot)
        WHEN NOT MATCHED THEN
          INSERT      (sl_key,   slot,      usage)
             VALUES (l_sl_key, l_next_slot, l_sl_hist_usage)
        WHEN MATCHED THEN
          UPDATE SET usage = l_sl_hist_usage;
 
 
--
--
--
--
--
--
--
--
      IF (l_next_slot+1) - s_histogram_window_slots < 0 THEN
        l_wrap_slot := s_histogram_cycle_slots -
                         (s_histogram_window_slots - (l_next_slot+1));
      ELSE
        l_wrap_slot := s_histogram_cycle_slots;
      END IF;
 
--
--
--
--
      SELECT PERCENTILE_CONT(s_histogram_goal_percentile) 
               WITHIN GROUP (ORDER BY usage ASC),
             COUNT(*)
        INTO l_freespace_goal, l_count
        FROM storage_histogram
        WHERE sl_key = l_sl_key
          AND ((slot BETWEEN l_next_slot+1 - s_histogram_window_slots
                                                               AND l_next_slot)
               OR
               (slot BETWEEN l_wrap_slot AND (s_histogram_cycle_slots-1)));
 
      trace1('EXECUTE_STORAGE_HISTOGRAM slot count=' || l_count ||
                  '; histogram_goal=' || l_freespace_goal/(1024*124*1024));
 
--
--
--
      IF l_count < 10 THEN
        l_freespace_goal := s_initial_freespace_ratio * l_sl_space;
      END IF;
 
--
--
--
--
--
      l_freespace_goal := GREATEST(l_freespace_goal,
                                   s_min_freespace_ratio * l_sl_space,
                                   (s_alloc_increment*3));
 
      trace1 ('EXECUTE_STORAGE_HISTOGRAM for sl ' || l_sl_key ||
                                        ', slot ' || l_next_slot ||
                                        ', usage ' || l_sl_hist_usage ||
                                        ', newgoal ' || l_freespace_goal);
 
--
--
--
      UPDATE sl
        SET sl_hist_usage = 0,
            sl_curr_hist_slot = l_next_slot,
            sl_freespace_goal = l_freespace_goal
        WHERE sl_key = l_sl_key;
      COMMIT;
 
      DBMS_RA_STORAGE.UNLOCK_SL (l_sl_key);
 
    EXCEPTION
      WHEN OTHERS THEN
        save_error;
        DBMS_RA_STORAGE.UNLOCK_SL (l_sl_key);
        trace1 ('EXECUTE_STORAGE_HISTOGRAM error: ' || SQLERRM);
        RAISE;
    END;
 
--
--
--
    SELECT COUNT(*) INTO l_count
      FROM odb 
      JOIN prot USING(prot_key)
      JOIN rai_oldest_backup rob USING(db_key)
     WHERE odb.sl_key = l_sl_key
--
       AND odb.db_state IS NULL
       AND odb.move_phase IS NULL
       AND odb.used_space > 0
       AND NVL(odb.purge_scn,0) <> DBMS_RA_POOL.BIGNUM
       AND prot.prot_max_retention_window IS NOT NULL
--
       AND (odb.bs2_timestamp IS NULL 
            OR ((SYSTIMESTAMP - odb.bs2_timestamp) > odb.recovery_window_goal))
--
       AND (rob.oldest_backup <
                               (SYSTIMESTAMP - prot.prot_max_retention_window))
       AND ROWNUM = 1;
 
    IF l_count > 0 THEN
--
      SELECT COUNT(*) INTO l_count
        FROM task
        WHERE (task_type = TASK_PURGE) AND
              (sl_key = l_sl_key)
          AND ROWNUM = 1;
 
      IF l_count = 0 THEN
--
        new_task_rec.task_type  := TASK_PURGE;
        new_task_rec.sl_key     := l_sl_key;
        new_task_rec.db_key     := NULL;
        new_task_rec.flags      := 0;
        new_task (new_task_rec);
      END IF;
    END IF;
 
  END LOOP;
  CLOSE sl_cursor;
 
EXCEPTION
  WHEN OTHERS THEN
    save_error;
    CLOSE sl_cursor;
    RAISE;
END execute_storage_histogram;
 
 
--
--
--
PROCEDURE execute_db_stats_refresh IS
  new_task_rec          task%ROWTYPE;
BEGIN
  DELETE odb_stats_cache;
  INSERT /*+
           OPT_PARAM('optimizer_dynamic_sampling' 0)
           OPT_PARAM('_optimizer_adaptive_cursor_sharing' 'false')
           OPT_PARAM('_optimizer_extended_cursor_sharing_rel' 'none')
           OPT_PARAM('_optimizer_use_feedback' 'false')
         */
    INTO odb_stats_cache (
           db_key
         , footprint
         , recovery_window_start
         , db_size
         , deduplication_factor
         , minimum_recovery_start
         , bdf1count
         , unprotected
         , nzdl_active
         , last_refresh
         )
  WITH db_size (db_key, space) AS
--
--
  (
  SELECT /*+
           QB_NAME(db_size) NO_PUSH_PRED NO_MERGE LEADING(dbinc) USE_HASH(df)
           FULL(dbinc) FULL(df)
         */
         dbinc.db_key
       , SUM(df.block_size * df.blocks)
    FROM dbinc
       , df
   WHERE df.drop_scn IS NULL
     AND dbinc.dbinc_key = df.dbinc_key
     AND dbinc.dbinc_status = 'CURRENT'
   GROUP BY dbinc.db_key
  )
  , all_backups (db_key, space) AS
--
--
  (
  SELECT --+ QB_NAME(all_backups) NO_PUSH_PRED NO_MERGE
         db_key
       , SUM(fsize)
    FROM (
--
         SELECT /*+
                  QB_NAME(dfiles) LEADING(bdf)
                  USE_HASH(bp) NO_SWAP_JOIN_INPUTS(bp)
                 */
                 db_key
               , SUM(datafile_blocks * block_size)
                   KEEP (DENSE_RANK LAST ORDER BY bdf_key) fsize
           FROM bp
              , bdf
          WHERE bp.ba_access = 'L'
            AND bdf.bs_key = bp.bs_key
          GROUP BY
                db_key
              , ckp_scn
              , create_scn
              , dbinc_key
              , file#
              , NVL2(bp.vb_key, -1, -2)
         UNION ALL
         SELECT /*+
                    QB_NAME(ofiles) LEADING(bp bsf bcf brl)
                    USE_HASH(bsf) USE_HASH(bcf) USE_HASH(brl)
                    NO_SWAP_JOIN_INPUTS(bsf)
                    NO_SWAP_JOIN_INPUTS(bcf)
                    NO_SWAP_JOIN_INPUTS(brl)
                */
                bp.db_key
              , SUM(NVL(bsf.bytes, 0))                   -- spfiles
              + SUM(NVL(bcf.block_size * bcf.blocks, 0)) -- control files
              + SUM(NVL(brl.block_size * brl.blocks, 0)) -- archive logs
           FROM bp
                LEFT OUTER JOIN bsf USING (bs_key) 
                LEFT OUTER JOIN bcf USING (bs_key)
                LEFT OUTER JOIN brl USING (bs_key)
          WHERE bp.ba_access = 'L'
          GROUP BY
                bp.db_key
         )
    GROUP BY db_key
  )
  , dedup (db_key, deduplication_factor) AS
--
--
--
  (
  SELECT /*+ QB_NAME(dedup) LEADING(odb sc ab) NO_PUSH_PRED NO_MERGE
             USE_HASH(ab) USE_HASH(sc)
         */
         db_key
       , ab.space / GREATEST(odb.total_allocation - NVL(sc.incs, 0), 1)
    FROM odb
         JOIN all_backups ab USING (db_key)
         LEFT OUTER JOIN (
            SELECT /*+ QB_NAME(sc) NO_MERGE NO_PUSH_PRED FULL(sc) */
                   db_key 
                 , SUM(filesize) incs
              FROM sbt_catalog sc
             WHERE filesize IS NOT NULL
               AND completed <> 'Y'
             GROUP BY db_key
         ) sc USING (db_key)
  )
  , dg_raw (db_key, datum_days, value_interval) as
--
  (
  SELECT /*+ LEADING(ds db odb)
         */
         db_key
       , SYSDATE - TO_DATE(MAX(datum_time), 'MM/DD/YYYY HH24:MI:SS')
       , TO_DSINTERVAL(MAX(value))
    FROM odb
    JOIN db USING (db_key)
    LEFT OUTER JOIN v$dataguard_stats ds 
      ON (db_id = ds.source_dbid AND ds.name = 'transport lag')
--
    GROUP BY db_key
  )
  , dg_stats (db_key, nzdl_active, unprotected) as
--
  (
  SELECT db_key
       , CASE WHEN datum_days < config.value THEN 'YES' ELSE 'NO' END
       ,   extract(day    from value_interval)
         + extract(hour   from value_interval) / 24
         + extract(minute from value_interval) / (24*60)
         + extract(second from value_interval) / (24*60*60)
    FROM dg_raw
    JOIN config ON (name = '_nzdl_is_alive_days')
  )
  SELECT /*+
           QB_NAME(osc) LEADING(odb irws db_size dedup)
           USE_HASH(irws) USE_HASH(db_size) USE_HASH(dedup)
           NO_PUSH_PRED(irws.dbfootprint)
           NO_PUSH_PRED(irws.keepsize)
           NO_PUSH_PRED(irws.dbrectimes)
           NO_PUSH_PRED(irws.backupf1count)
         */
         db_key
       , irws.footprint
       , irws.recwindowstart
       , db_size.space
       , dedup.deduplication_factor
       , irws.minrectime
       , irws.bdf1count
       , dgs.unprotected
       , dgs.nzdl_active
       , SYSTIMESTAMP
    FROM odb
    LEFT OUTER JOIN rai_recovery_window_space irws USING (db_key)
    LEFT OUTER JOIN db_size USING (db_key)
    LEFT OUTER JOIN dedup USING (db_key)
    LEFT OUTER JOIN dg_stats dgs USING (db_key)
--
    WHERE odb.db_state IS NULL
  ;
 
  trace1('EXECUTE_DB_STATS_REFRESH: Dbs computed = ' || SQL%ROWCOUNT);
  COMMIT;
  
--
--
--
--
--
--
--
--
--
--
--
  FOR rrrt IN (SELECT db_key
                 FROM odb
                WHERE NOT EXISTS (SELECT 1
                                    FROM task
                                   WHERE task_type = TASK_RESTORE_RANGE_REFRESH
                                     AND odb.db_key = task.db_key)) LOOP
 
    new_task_rec.task_type  := TASK_RESTORE_RANGE_REFRESH;
    new_task_rec.flags      := 0;
    new_task_rec.db_key     := rrrt.db_key;
 
    new_task (task_rec => new_task_rec, p_commit => FALSE);
  END LOOP;
  COMMIT;
  SYS.KBRSI_ICD.RSRUNSCHED;
 
END execute_db_stats_refresh;
 
--
--
--
PROCEDURE execute_restore_range_refresh (p_task_rec IN task%ROWTYPE) IS
 
  l_db_key        NUMBER := p_task_rec.db_key;
  l_currinc       NUMBER;
  l_db_id         NUMBER;
  l_dbid          NUMBER;
  l_reset_scn     NUMBER;
  l_reset_time    DATE;
  l_db_name       dbinc.db_name%TYPE;
  l_db_slkey      NUMBER;
  l_highscn       NUMBER;
  l_count         NUMBER;
  l_current_days  NUMBER;
  l_current_range INTERVAL DAY(9) TO SECOND;
  l_goal_range    INTERVAL DAY(9) TO SECOND;
  l_high_time     DATE;
  l_low_time      DATE;
  l_unprot_win    INTERVAL DAY(9) TO SECOND;
  l_timestamp     DATE;
  l_temp          NUMBER;
  l_unprotected   NUMBER;
  l_create_time   TIMESTAMP WITH TIME ZONE;
  l_create_date   DATE;
BEGIN
  tracex('EXECUTE_RESTORE_RANGE_REFRESH: db_key: ' || l_db_key);
 
--
--
--
  SELECT db.db_id, reset_scn, reset_time, dbinc.db_name
    INTO l_db_id, l_reset_scn, l_reset_time, l_db_name
    FROM db, dbinc
   WHERE db.curr_dbinc_key = dbinc.dbinc_key
     AND dbinc.db_key = db.db_key
     AND db.db_key = l_db_key;
 
  trace1('EXECUTE_RESTORE_RANGE_REFRESH: DBNAME: ' || l_db_name ||
                           '; db_id: ' || l_db_id ||
                       '; reset_scn: ' || l_reset_scn ||
                      '; reset_time: ' || l_reset_time);
 
--
--
--
  setDatabase(l_db_key, l_dbid, l_currinc, l_db_slkey);
 
--
  SELECT MAX(high_scn) INTO l_highscn FROM rai_restore_range;
  SELECT MAX(high_scn) INTO l_highscn FROM rai_disk_restore_range;
  SELECT MAX(high_scn) INTO l_highscn FROM rai_sbt_restore_range;
 
  trace1 ('EXECUTE_RESTORE_RANGE_REFRESH: restore range refreshed for db ' 
              || l_db_name);
 
--
--
--
  SELECT create_time, prot_recovery_window_goal, prot_unprotected_window
    INTO l_create_time, l_goal_range, l_unprot_win
    FROM odb
    JOIN prot USING( prot_key )
    WHERE db_key = p_task_rec.db_key;
  
--
--
--
--
--
 
  BEGIN
    SELECT high_time, low_time 
      INTO l_high_time, l_low_time
      FROM (SELECT high_time, low_time
              FROM ra_restore_range
              WHERE db_key = p_task_rec.db_key
              ORDER BY high_time DESC)
      WHERE ROWNUM = 1;
  EXCEPTION
    WHEN NO_DATA_FOUND THEN
      save_error;
      l_high_time    := NULL;
      l_low_time     := NULL;
      clear_error;
  END;
 
--
--
--
--
--
--
--
--
  SELECT unprotected INTO l_unprotected
    FROM odb_stats_cache
   WHERE db_key = l_db_key;
 
--
--
--
  SELECT CAST(( SYSTIMESTAMP AT TIME ZONE TO_CHAR(db_timezone)) AS DATE),
         CAST(( l_create_time AT TIME ZONE TO_CHAR(db_timezone)) AS DATE)
    INTO l_timestamp, l_create_date
    FROM node
    WHERE db_key = p_task_rec.db_key
      AND database_role = 'PRIMARY'
      AND ROWNUM = 1;
  
--
--
--
--
--
--
  IF (NUMTODSINTERVAL(l_timestamp - l_create_date,'day') > l_goal_range) THEN
     l_temp := l_timestamp - l_low_time ;
     IF (l_low_time IS NULL OR NUMTODSINTERVAL(l_temp,'day') < l_goal_range)
     THEN
        log_error(
                   p_errno     => E_REC_WINDOW_LOW_NUM,
                   p_param1    => DBMS_RA_INT.DBKEY2NAME(l_db_key),
                   p_component => 'RESTORE_RANGE_REFRESH',
                   p_severity  => SEVERITY_WARNING,
                   p_db_key    => l_db_key);
     ELSE
        fix_error(
                   p_error_num => E_REC_WINDOW_LOW_NUM,
                   p_db_key    => l_db_key);
        COMMIT;
     END IF;
  END IF;
 
--
--
--
--
--
--
--
 
  IF (NUMTODSINTERVAL(l_timestamp - l_create_date,'day') > l_unprot_win) 
  THEN
     IF l_high_time IS NULL 
        OR NUMTODSINTERVAL(l_unprotected,'day') > l_unprot_win
     THEN
        trace1('EXECUTE_RESTORE_RANGE_REFRESH: ' ||
                'Current unprotected window is ' ||
                   NUMTODSINTERVAL(l_unprotected,'day') ||
                 '; Unprotected_window goal is ' || l_unprot_win);
        log_error(
                   p_errno     => E_UNPROTECTED_WINDOW_LOST_NUM,
                   p_param1    => DBMS_RA_INT.DBKEY2NAME(l_db_key),
                   p_component => 'RESTORE_RANGE_REFRESH',
                   p_severity  => SEVERITY_WARNING,
                   p_db_key    => l_db_key);
     ELSE
        fix_error(
                   p_error_num => E_UNPROTECTED_WINDOW_LOST_NUM,
                   p_db_key    => l_db_key);
        COMMIT;
     END IF;
  ELSE
--
--
--
     fix_error(
                p_error_num => E_UNPROTECTED_WINDOW_LOST_NUM,
                p_db_key    => l_db_key);
     COMMIT;
  END IF;
 
--
--
--
  SELECT COUNT(*) INTO l_count
    FROM error_log
    WHERE error_num = E_REC_WINDOW_LOST_NUM
      AND db_key = p_task_rec.db_key
      AND ROWNUM=1;
 
  IF l_count > 0 THEN
--
--
--
--
--
    BEGIN
      SELECT high_time - low_time INTO l_current_days
        FROM (SELECT high_time, low_time
                FROM ra_disk_restore_range
                WHERE db_key = p_task_rec.db_key
                ORDER BY high_time DESC)
        WHERE ROWNUM=1;
    EXCEPTION
      WHEN NO_DATA_FOUND THEN
        save_error;
        l_current_days := NULL;
        clear_error;
    END;
 
    l_current_range := NUMTODSINTERVAL(l_current_days, 'day');
 
    trace1('EXECUTE_RESTORE_RANGE_REFRESH: ' ||
                                   'Current Range is ' || l_current_range ||
                                   '; Goal is ' || l_goal_range);
 
    IF l_current_range >= l_goal_range THEN
      fix_error (p_error_num => E_REC_WINDOW_LOST_NUM,
                 p_db_key    => p_task_rec.db_key);
      COMMIT;
    END IF;
  END IF;
 
EXCEPTION
  WHEN NO_DATA_FOUND THEN
    save_error;
    trace1 ('EXECUTE_RESTORE_RANGE_REFRESH: Database not found');
    clear_error;
  WHEN OTHERS THEN
    save_error;
    trace1 ('EXECUTE_RESTORE_RANGE_REFRESH: Some error occurred');
    RAISE;
END execute_restore_range_refresh;
 
--
--
--
--
--
--
--
--
--
--
--
--
 
PROCEDURE execute_optimize_chunks (p_task_rec IN task%ROWTYPE) IS
  CURSOR optdf_cursor IS
    SELECT df_key, MAX(f.blocks)*MAX(f.block_size) filesize 
      FROM df f, dbinc i
     WHERE i.dbinc_key = f.dbinc_key
       AND i.db_key = p_task_rec.db_key
     GROUP BY f.df_key;
 
  l_db_key              NUMBER := p_task_rec.db_key;
  l_last_optimize       TIMESTAMP WITH TIME ZONE;
  l_sl_min_alloc        NUMBER;
  new_task_rec          task%ROWTYPE;
BEGIN
  tracex ('EXECUTE_OPTIMIZE_CHUNKS for db_key=' || l_db_key);
 
--
--
--
  SELECT last_optimize, sl_min_alloc
    INTO l_last_optimize, l_sl_min_alloc
    FROM odb
   WHERE db_key = l_db_key;
 
--
--
--
--
--
  wait_for_repair (NULL, l_db_key);
 
  FOR t IN optdf_cursor LOOP
--
--
    new_task_rec.task_type  := TASK_OPTIMIZE_CHUNKS_DF;
    new_task_rec.flags      := 0;
    new_task_rec.db_key     := l_db_key;
    new_task_rec.param_num1 := t.df_key;
    new_task_rec.param_num2 := GREATEST (t.filesize, l_sl_min_alloc);
    new_task(new_task_rec, p_commit => FALSE);
  END LOOP;
 
--
--
--
--
--
--
  UPDATE odb SET last_optimize = SYSTIMESTAMP,
                 prev_optimize = l_last_optimize
    WHERE db_key = l_db_key;
 
  COMMIT;
  SYS.KBRSI_ICD.RSRUNSCHED;
 
END execute_optimize_chunks;
 
 
--
--
--
PROCEDURE execute_optimize_chunks_df (p_task_rec IN task%ROWTYPE) IS
  l_space_so_far      NUMBER;
  l_db_reserved_space NUMBER;
  l_count             NUMBER;
  l_taskid            NUMBER;
  l_hash              NUMBER;
  l_task_rec          task%ROWTYPE;
BEGIN
  tracex ('EXECUTE_OPTIMIZE_CHUNKS_DF ' ||
          '; db_key=' || p_task_rec.db_key ||
          '; df_key=' || p_task_rec.param_num1 ||
          '; bpsize(MB)=' || p_task_rec.param_num2/1024/1024 ||
          '; alloc(MB)='  || print(p_task_rec.param_num3/1024/1024));
 
  wait_for_repair (NULL, p_task_rec.db_key);
  avoid_db (p_task_rec.db_key);
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
  IF p_task_rec.param_num3 IS NULL THEN
--
--
--
--
--
    BEGIN
      SYS.KBRSI_ICD.RSSCHEDLOCK (waitforwork => 0);
 
      SELECT NVL(SUM(param_num3),0), MIN(task_id)
        INTO l_space_so_far, s_pending_interrupt
        FROM task
       WHERE task_type = TASK_OPTIMIZE_CHUNKS_DF
         AND task_id <> p_task_rec.task_id
         AND db_key = p_task_rec.db_key
         AND param_num3 IS NOT NULL;
 
      SELECT base_reserved_space INTO l_db_reserved_space
        FROM odb
       WHERE db_key = p_task_rec.db_key;
 
      trace1('EXECUTE_OPTIMIZE_CHUNKS_DF' ||
                          ': Usage(MB)=' || l_space_so_far/1024/1024 ||
                          '; Space(MB)=' || l_db_reserved_space/1024/1024 ||
                          '; Wait on task id ' || print(s_pending_interrupt));
 
      IF ((l_space_so_far + p_task_rec.param_num2) > 
                  (s_optimize_space_limit * l_db_reserved_space))
         AND (s_pending_interrupt IS NOT NULL)  THEN
 
--
--
--
--
--
--
        UPDATE task SET pending_interrupt = s_pending_interrupt,
                        state = STATE_TASK_WAIT
          WHERE task_type = TASK_OPTIMIZE_CHUNKS_DF
            AND db_key = p_task_rec.db_key
            AND state =  STATE_EXECUTABLE
            AND task_id <> s_pending_interrupt
            AND param_num3 IS NULL
            AND param_num2 >= p_task_rec.param_num2;
 
        l_count := SQL%ROWCOUNT;
        trace1('EXECUTE_OPTIMIZE_CHUNKS_DF: Put to sleep ' || l_count ||
                                  ' other tasks');
 
--
--
--
        IF l_count > 0 THEN
          UPDATE task
             SET flags = NVL(flags,0) 
                         - BITAND(NVL(flags,0), TASKS_BLOCKING_TASK)
                         + TASKS_BLOCKING_TASK
           WHERE task_id = s_pending_interrupt;
        END IF;
 
        COMMIT;
        SYS.KBRSI_ICD.RSSCHEDUNLOCK;
 
--
--
--
        RAISE E_PENDING_INTERRUPT;
      END IF;
    EXCEPTION
      WHEN OTHERS THEN
        save_error;
        SYS.KBRSI_ICD.RSSCHEDUNLOCK;
        RAISE;
    END;        
 
--
--
--
    UPDATE task SET param_num3=NVL(param_num2,0)
      WHERE task_id = s_current_task;
    COMMIT;
    SYS.KBRSI_ICD.RSSCHEDUNLOCK;
    s_pending_interrupt := NULL;
 
    trace1('EXECUTE_OPTIMIZE_CHUNKS_DF: Enough space to optimize');
  END IF;
 
--
--
--
--
  s_no_wait_on_allocate := TRUE;
 
--
--
--
  dbms_ra_pool.optimizeDF(p_task_rec.db_key, p_task_rec.param_num1);
 
--
--
--
--
  SELECT ORA_HASH(p_task_rec.param_num1, 1023, 0) + 1 INTO l_hash FROM dual;
 
  SELECT MIN(task_id) INTO l_taskid
    FROM task
    WHERE task_type = TASK_REBUILD_INDEX
      AND param_num1 = l_hash;
 
  IF l_taskid IS NULL THEN
    trace1('EXECUTE_OPTIMIZE_CHUNKS_DF: Rebuild blocks partition ' || l_hash);
    l_task_rec.task_type     := TASK_REBUILD_INDEX;
    l_task_rec.param_num1    := l_hash;
    l_task_rec.flags         := 0;
    new_task(l_task_rec);
  END IF;
 
--
--
--
--
--
--
--
--
 
END execute_optimize_chunks_df;
 
 
--
--
--
--
PROCEDURE execute_rebuild_index (p_task_rec IN task%ROWTYPE) IS
  l_partition_name      user_tab_partitions.partition_name%TYPE;
  l_tablespace_name     user_tab_partitions.tablespace_name%TYPE;
  l_table_name          user_tables.table_name%TYPE := 'BLOCKS'; 
  l_index_name          user_indexes.index_name%TYPE := 'BLOCKS_U';
  l_ddl                 VARCHAR2(2048);
BEGIN
  tracex ('EXECUTE_REBUILD_INDEX on' ||
          ' df_hash=' || p_task_rec.param_num1);
 
--
  get_lock(dbms_ra_scheduler.LOCK_PURGE, p_task_rec.param_num1);
 
--
--
--
--
--
  SELECT MAX(task_id) INTO s_pending_interrupt
    FROM task t, bp p, bdf d, df f
    WHERE t.param_num1 = p.bp_key
      AND p.bs_key = d.bs_key
      AND d.dbinc_key = f.dbinc_key
      AND d.create_scn = f.create_scn
      AND d.file# = f.file#
      AND state IN (STATE_RUNNING, STATE_EXECUTABLE)
      AND task_type IN (TASK_INDEX_BACKUP, TASK_CHECK_FILES)
      AND (p_task_rec.param_num1 = ORA_HASH(f.df_key, 1023, 0) + 1
           OR (task_type = TASK_CHECK_FILES AND state = STATE_RUNNING));
  IF s_pending_interrupt IS NOT NULL THEN
    RAISE e_retry_error;
  END IF;
 
  /* See if the size of the partition exceeds the threshold */
  BEGIN
    SELECT --+ LEADING(t st i si)
           i.partition_name, i.tablespace_name
      INTO l_partition_name, l_tablespace_name
      FROM user_tab_partitions t,
           user_segments st,
           user_ind_partitions i,
           user_segments si 
      WHERE t.table_name = l_table_name
        AND st.segment_name = t.table_name
        AND t.partition_name = st.partition_name
        AND t.partition_position = p_task_rec.param_num1
        AND i.index_name = l_index_name
        AND si.segment_name = i.index_name
        AND i.partition_name = si.partition_name
        AND i.partition_position = t.partition_position
        AND si.bytes > s_part_index_size
        AND si.blocks / st.blocks > (s_part_threshold + 1);
  EXCEPTION 
    WHEN NO_DATA_FOUND THEN
--
      save_error;
      unlock(dbms_ra_scheduler.LOCK_PURGE, p_task_rec.param_num1);
      trace1 ('EXECUTE_REBUILD_INDEX nothing to shrink for' ||
              ' df_hash=' || p_task_rec.param_num1);
      clear_error;
      RETURN;
  END;
 
--
  IF s_part_index_style = 1 THEN
    l_ddl := 'ALTER INDEX ' ||
                    dbms_assert.enquote_name(l_index_name) ||
                    ' REBUILD PARTITION ' ||
                    dbms_assert.enquote_name(l_partition_name) ||
                    CASE
                      WHEN s_part_parallel_degree IS NOT NULL
                      THEN ' PARALLEL ' ||
                        CASE
                          WHEN s_part_parallel_degree = 0
                          THEN '(DEGREE DEFAULT)'
                          ELSE TO_CHAR(s_part_parallel_degree)
                        END
                    END ||
                    ' TABLESPACE ' ||
                    dbms_assert.enquote_name(l_tablespace_name) ||
                    ' ONLINE';
  ELSE
    l_ddl := 'ALTER INDEX ' ||
                    dbms_assert.enquote_name(l_index_name) ||
                    ' MODIFY PARTITION ' ||
                    dbms_assert.enquote_name(l_partition_name) ||
                    ' SHRINK SPACE';
  END IF;
 
--
  trace1('EXECUTE_REBUILD_INDEX: ' || l_ddl);
 
--
  EXECUTE IMMEDIATE l_ddl;
 
  unlock(dbms_ra_scheduler.LOCK_PURGE, p_task_rec.param_num1);
EXCEPTION
  WHEN OTHERS THEN
    save_error;
    unlock(dbms_ra_scheduler.LOCK_PURGE, p_task_rec.param_num1);
    RAISE;
END execute_rebuild_index;
 
 
--
--
--
--
--
--
--
 
PROCEDURE execute_validate_db (p_task_rec IN task%ROWTYPE) IS
  l_db_key              NUMBER := p_task_rec.db_key;
  l_execute_time        TIMESTAMP WITH TIME ZONE :=  p_task_rec.execute_time;
BEGIN
  tracex ('EXECUTE_VALIDATE_DB: db_key=' || l_db_key);
  wait_for_repair (NULL, l_db_key);
  avoid_db (l_db_key);
 
--
--
--
  dbms_ra_pool.validateDB(l_db_key);
 
--
--
--
  fix_error (p_error_num => E_BAD_VALIDATE_NUM,
             p_db_key    => l_db_key,
             p_timestamp => l_execute_time);
 
--
--
--
--
  FOR x IN (SELECT param_num
              FROM error_log e
              WHERE error_num = E_CORRUPT_BLOCK_NUM
                AND db_key = p_task_rec.db_key
                AND NOT EXISTS (SELECT 1 FROM bp
                                  WHERE bp_key=e.param_num)) LOOP
 
    fix_error (p_error_num => E_CORRUPT_BLOCK_NUM,
               p_db_key    => p_task_rec.db_key,
               p_param_num => x.param_num);
  END LOOP;
 
--
--
--
  UPDATE odb 
    SET last_validate = SYSTIMESTAMP
    WHERE db_key = p_task_rec.db_key; 
  COMMIT;
END execute_validate_db;
 
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
FUNCTION delete_db_disruptive_running RETURN NUMBER IS
  l_taskid NUMBER := NULL;
BEGIN
  SELECT MAX(task_id) INTO l_taskid
    FROM task t
   WHERE t.state = STATE_RUNNING
--
     AND (t.task_type IN (TASK_RECONCILE, TASK_CHECK_FILES)
          OR (t.task_type = TASK_MOVE_ALL_DB
              AND EXISTS (SELECT move_phase
                            FROM odb
                           WHERE odb.db_key = t.db_key
                             AND odb.move_phase IS NOT NULL)));
 
  RETURN l_taskid;
END delete_db_disruptive_running;
 
 
--
--
--
--
--
--
FUNCTION delete_db_task_is_benign (p_task_type IN NUMBER) RETURN NUMBER IS
BEGIN
  IF p_task_type IN (TASK_DELETE_DB,
                     TASK_PURGE,
                     TASK_PURGE_IMMEDIATE,
                     TASK_PURGE_DF,
                     TASK_PURGE_DF_NOW,
                     TASK_DEFERRED_DELETE,
                     TASK_RM_INCOMPLETE_FILES,
                     TASK_RECONCILE) THEN
    RETURN DB_TASK_IS_BENIGN;
  ELSE
    RETURN DB_TASK_IS_NOT_BENIGN;
  END IF;
END;
 
 
--
--
--
--
PROCEDURE delete_db_remove_remaining (p_dbkey IN NUMBER) IS
 
BEGIN
--
  SYS.KBRSI_ICD.RSSCHEDLOCK (waitforwork => 0);
 
--
--
  UPDATE task SET state = STATE_CANCEL
   WHERE db_key = p_dbkey
     AND state NOT IN (STATE_RUNNING, STATE_CANCELING)
     AND delete_db_task_is_benign(task_type) = DB_TASK_IS_NOT_BENIGN;
  trace1('DELETE_DB_REMOVE_REMAINING: Canceled ' || SQL%ROWCOUNT || 
                                                                ' task(s).');
  COMMIT;
 
--
  SYS.KBRSI_ICD.RSSCHEDUNLOCK;
 
EXCEPTION
  WHEN OTHERS THEN
    save_error;
--
    SYS.KBRSI_ICD.RSSCHEDUNLOCK;
    RAISE;
END delete_db_remove_remaining;
 
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE execute_delete_db (p_task_rec IN task%ROWTYPE) IS
 
  DELETE_DB_SVPNT_START            CONSTANT NUMBER := 0;
  DELETE_DB_SVPNT_WAIT_DISRUPTIV   CONSTANT NUMBER := 1;
  DELETE_DB_SVPNT_SUBMIT_DELETES   CONSTANT NUMBER := 2;
  DELETE_DB_SVPNT_WAIT_DELETES     CONSTANT NUMBER := 3;
  DELETE_DB_SVPNT_FREEBP           CONSTANT NUMBER := 4;
  DELETE_DB_SVPNT_DELFILES         CONSTANT NUMBER := 5;
  DELETE_DB_SVPNT_METADATA         CONSTANT NUMBER := 6;
  DELETE_DB_SVPNT_UNREGISTER       CONSTANT NUMBER := 7;
 
  l_db_key          NUMBER         := p_task_rec.db_key;
  l_db_id           NUMBER         := p_task_rec.param_num1;
  l_db_unique_name  VARCHAR2(1000) := p_task_rec.param_char1;
 
  l_savepoint       NUMBER         := NVL(p_task_rec.savepoint,
                                          DELETE_DB_SVPNT_START);
 
  l_isdown          NUMBER;
  l_chunkcnt        NUMBER;
  l_task_rec        task%ROWTYPE;
  l_task_id         NUMBER;
  l_task_type       NUMBER;
  l_sl_key          NUMBER;
  l_tcount          NUMBER;
  l_count           NUMBER;
  l_more_data       BOOLEAN := FALSE;
  l_krsperr         BINARY_INTEGER;
  l_lockstate       BOOLEAN;
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
 
--
  CURSOR fils IS
    SELECT db_key, df_key, MAX(vb_key) vb_key
      FROM vbdf
      WHERE vbdf.db_key = l_db_key
      GROUP BY db_key, df_key;
 
--
  CURSOR bss IS
    SELECT 1 ord, p.sl_key, p.db_key, bp_key, handle, NULL pieceinc, NULL ftype
      FROM bp b, odb p
      WHERE b.db_key = l_db_key
        AND b.db_key = p.db_key
        AND purged = 'N'
        AND lib_key IS NULL /* Only backups on disk */
        AND b.ba_access = 'L'
    UNION ALL
    SELECT 2 ord, p.sl_key, p.db_key, bp_key, handle, pieceinc, 
                  DECODE(ftype,
                    'F', DBMS_RA_INT.KBRSCHKTYPE_FILE,
                    'V', DBMS_RA_INT.KBRSCHKTYPE_VIRTUAL,
                    'T', DBMS_RA_INT.KBRSCHKTYPE_TAPE,
                    NULL) ftype
      FROM sbt_catalog c, odb p
      WHERE c.db_key = l_db_key
        AND c.db_key = p.db_key
        AND c.completed = 'N'
        AND c.filesize IS NOT NULL /* Only local storage backups */
    ORDER BY ord, db_key, bp_key DESC;
 
--
  CURSOR rep_server_cursor IS 
    SELECT s.rep_server_name, p.prot_name
      FROM rep_server r, prot p, odb o, server s
      WHERE p.prot_key = r.prot_key
        AND s.server_key = r.server_key
        AND o.prot_key = p.prot_key
        AND o.db_key = l_db_key;
BEGIN
--
--
--
--
--
  IF l_savepoint = DELETE_DB_SVPNT_START THEN
 
    trace1 ('EXECUTE_DELETE_DB: ' || print(l_db_unique_name) ||
            '; db_id='  || print(l_db_id) ||
            '; db_key=' || print(l_db_key) ||
            '; savepoint=' || print(l_savepoint));
 
--
--
--
--
--
--
--
--
--
 
--
--
--
--
    stop_scheduler_jobs (STOP_JOBS_DB, FALSE, l_db_key);
    trace1 ('delete_db: ' || print(l_db_unique_name) ||
            ': stop_scheduler_jobs() complete');
 
--
--
--
--
    delete_db_remove_remaining(l_db_key);
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
 
    trace1 ('delete_db: ' || print(l_db_unique_name) ||
            ': database quiet complete');
 
    check_for_interrupt (DELETE_DB_SVPNT_WAIT_DISRUPTIV);
    l_savepoint := DELETE_DB_SVPNT_WAIT_DISRUPTIV;
  END IF; -- DELETE_DB_SVPNT_START
 
--
--
--
--
--
--
--
--
--
--
  delete_db_remove_remaining(l_db_key);
 
--
--
--
--
--
  IF l_savepoint = DELETE_DB_SVPNT_WAIT_DISRUPTIV THEN
 
    trace1 ('delete_db: ' || print(l_db_unique_name) ||
            ': at savepoint ' || print(l_savepoint) ||
            ': wait disruptive');
 
--
    s_pending_interrupt := delete_db_disruptive_running;
 
--
    IF s_pending_interrupt IS NOT NULL THEN
      IF s_tracing_on THEN
          trace1 ('delete_db: ' || print(l_db_unique_name) ||
                  ': waiting on disruptive task id ' || s_pending_interrupt);
      END IF;
      RAISE E_RETRY_ERROR;
    END IF;
 
    trace1 ('delete_db: ' || print(l_db_unique_name) ||
            ': wait disruptive complete');
 
    check_for_interrupt (DELETE_DB_SVPNT_SUBMIT_DELETES);
    l_savepoint := DELETE_DB_SVPNT_SUBMIT_DELETES;
  END IF;
 
--
--
--
--
--
  IF l_savepoint = DELETE_DB_SVPNT_SUBMIT_DELETES THEN
 
    trace1 ('delete_db: ' || print(l_db_unique_name) ||
            ': at savepoint ' || print(l_savepoint) ||
            ': submit tasks');
 
--
--
--
--
--
--
    FOR d IN (SELECT c.handle, c.pieceinc,
                     DECODE(ftype,
                       'F', DBMS_RA_INT.KBRSCHKTYPE_FILE,
                       'V', DBMS_RA_INT.KBRSCHKTYPE_VIRTUAL,
                       'T', DBMS_RA_INT.KBRSCHKTYPE_TAPE,
                       'D', DBMS_RA_INT.KBRSCHKTYPE_DISK,
                       NULL) ftype
               FROM sbt_catalog c
                    LEFT OUTER JOIN bp USING (bp_key)
              WHERE c.db_key = l_db_key
                AND NVL(bp.status, 'A') = 'A'
                AND NVL(bp.ba_access,  'L') = 'L'
                AND bp.lib_key IS NULL /* Only backups on disk */
              ORDER BY c.ct_key DESC) LOOP
 
      l_task_rec.task_type   := task_deferred_delete;
      l_task_rec.flags       := 0;
      l_task_rec.db_key      := l_db_key;
      l_task_rec.param_char1 := d.handle;
      l_task_rec.param_char2 := d.pieceinc;
      l_task_rec.param_num1  := d.ftype;
 
      new_task (task_rec => l_task_rec, p_commit => FALSE);
      trace1 ('delete_db: ' || print(l_db_unique_name) ||
              ': deferred_delete task queued ' || print(d.handle));
    END LOOP;
 
--
--
--
--
--
--
--
--
--
    l_task_rec.task_type := task_rm_incomplete_files;
    l_task_rec.flags     := 0;
    l_task_rec.db_key    := l_db_key;
 
    new_task (task_rec => l_task_rec, p_commit => TRUE);
 
    trace1 ('delete_db: ' || print(l_db_unique_name) ||
            ': submit tasks complete');
 
--
    check_for_interrupt (DELETE_DB_SVPNT_WAIT_DELETES);
    l_savepoint := DELETE_DB_SVPNT_WAIT_DELETES;
  END IF;
 
--
--
--
--
--
  IF l_savepoint = DELETE_DB_SVPNT_WAIT_DELETES THEN
 
    trace1 ('delete_db: ' || print(l_db_unique_name) ||
            ': at savepoint ' || print(l_savepoint) ||
            ': submitted tasks wait');
 
--
    SELECT MAX(task_id) INTO s_pending_interrupt
      FROM task
     WHERE db_key = l_db_key
       AND task_type <> TASK_DELETE_DB;
 
    IF s_pending_interrupt IS NOT NULL THEN
      IF s_tracing_on THEN
        BEGIN
          SELECT task_type INTO l_task_type
            FROM task
           WHERE task_id = s_pending_interrupt;
          trace1 ('delete_db: ' || print(l_db_unique_name) ||
                  ': waiting on ' || tasktype2name(l_task_type));
        EXCEPTION
--
          WHEN NO_DATA_FOUND THEN
            NULL;
        END;
      END IF;
      RAISE E_RETRY_ERROR;
    END IF;
 
    trace1 ('delete_db: ' || print(l_db_unique_name) ||
            ': submitted tasks complete');
 
    check_for_interrupt (DELETE_DB_SVPNT_FREEBP);
    l_savepoint := DELETE_DB_SVPNT_FREEBP;
  END IF;
 
--
--
--
--
--
  IF l_savepoint = DELETE_DB_SVPNT_FREEBP THEN
 
    trace1 ('delete_db: ' || print(l_db_unique_name) ||
            ': at savepoint ' || print(l_savepoint) ||
            ': free_backup_pieces');
 
--
--
    l_more_data := TRUE;
    WHILE l_more_data LOOP
 
      l_more_data := FALSE;
 
      FOR b IN bss LOOP
        l_more_data := TRUE;
 
        trace1('delete_db: ' || print(l_db_unique_name) ||
               ': free_backup_piece_opt() deleting ' || print(b.handle));
        dbms_ra_storage.free_backup_piece_opt(
           p_dbkey     => b.db_key,
           p_piecename => b.handle,
           p_db_slkey  => b.sl_key,
           p_dbid      => l_db_id,
           p_currinc   => NULL,    /* Not in use with noplans/notasks */
           p_bpkey     => b.bp_key,
           p_ftype     => b.ftype,
           p_fincarn   => b.pieceinc,
           p_libkey    => NULL,    /* Only local disk backups deleted */
           p_noplans   => TRUE,
           p_notasks   => TRUE);
      END LOOP;
    END LOOP;
 
    COMMIT;
 
    trace1 ('delete_db: ' || print(l_db_unique_name) ||
            ': free_backup_pieces complete');
 
    check_for_interrupt (DELETE_DB_SVPNT_DELFILES);
    l_savepoint := DELETE_DB_SVPNT_DELFILES;
  END IF;
 
--
--
--
--
--
  IF l_savepoint = DELETE_DB_SVPNT_DELFILES THEN
 
    trace1 ('delete_db: ' || print(l_db_unique_name) ||
            ': at savepoint ' || print(l_savepoint) ||
           ': deleting files');
 
--
--
--
--
    trace1('delete_db: ' || print(l_db_unique_name) || ': deleting files');
    l_more_data := TRUE;
    WHILE l_more_data LOOP
 
      l_more_data := FALSE;
 
      FOR f IN fils LOOP
        l_more_data := TRUE;
        dbms_ra_pool.purgeDF(dbms_ra_pool.KBRSPLBLD_ALLPURGE,
                             f.df_key, f.vb_key);
--
        dbms_ra_pool.optimizeDF(l_db_key, f.df_key, TRUE);
 
        DELETE FROM vbdf
          WHERE df_key = f.df_key
            AND NOT EXISTS (SELECT 1 FROM chunks WHERE df_key = f.df_key);
        IF SQL%ROWCOUNT = 0 THEN
          trace1('delete_db: ' || print(l_db_unique_name) ||
                   ': failed to delete files, df_key ' || f.df_key);
          sys.dbms_sys_error.raise_system_error(E_INTERNAL_ERROR_NUM,
                   'delete_db: ' || print(l_db_unique_name) ||
                   ': failed to delete files, df_key ' || f.df_key,
                   FALSE);
        END IF;
        COMMIT;
      END LOOP;
 
    END LOOP;
    trace1('delete_db: ' || print(l_db_unique_name) ||
           ': deleting files complete');
 
--
    SELECT count(*)
      INTO l_chunkcnt
      FROM chunks, df, dbinc
     WHERE chunks.df_key = df.df_key
       AND df.dbinc_key = dbinc.dbinc_key
       AND dbinc.db_key = l_db_key
       AND ROWNUM =1;
    IF (l_chunkcnt > 0) THEN
      RAISE E_DELETE_DB_CHUNKS;
    END IF;
 
    check_for_interrupt (DELETE_DB_SVPNT_METADATA);
    l_savepoint := DELETE_DB_SVPNT_METADATA;
  END IF;
 
--
--
--
--
--
  IF l_savepoint = DELETE_DB_SVPNT_METADATA THEN
 
    trace1 ('delete_db: ' || print(l_db_unique_name) ||
            ': at savepoint ' || print(l_savepoint) ||
           ': deleting db metadata');
 
--
--
--
    trace1('delete_db: ' || print(l_db_unique_name) || ': plans cleanup');
 
    FOR p IN (SELECT df_key, vb_key, type
                FROM plans
               WHERE db_key = l_db_key) LOOP
      DELETE plans_details
       WHERE df_key = p.df_key
         AND vb_key = p.vb_key
         AND type = p.type;
      COMMIT;
    END LOOP; 
 
    DELETE FROM plans
      WHERE db_key = l_db_key;
    COMMIT;
 
    trace1('delete_db: ' || print(l_db_unique_name) ||
           ': plans cleanup complete');
 
--
    trace1('delete_db: ' || print(l_db_unique_name) ||
             ': calling rsKRSPDeleteDB()');
 
    l_krsperr := sys.kbrsi_icd.rsKRSPDeleteDB(l_db_id);
    IF l_krsperr != 0 THEN
      sys.dbms_sys_error.raise_system_error(E_INTERNAL_ERROR_NUM,
                        'associated Data Guard metadata delete failed ' ||
                        l_krsperr,
                        FALSE);
    END IF;
 
    trace1('delete_db: ' || print(l_db_unique_name) ||
             ': rsKRSPDeleteDB() complete');
 
--
    trace1('delete_db: ' || print(l_db_unique_name) || ': db_key cleanup');
 
    DELETE FROM df_seq
      WHERE df_key IN (SELECT df.df_key
                         FROM df, dbinc
                        WHERE df.dbinc_key = dbinc.dbinc_key
                          AND dbinc.db_key = l_db_key);
 
    trace1('delete_db: ' || print(l_db_unique_name) ||
           ': df_seq cleanup complete');
 
--
    UPDATE db SET storage_prov = 'N'
      WHERE db_key=l_db_key;
 
--
--
--
--
--
--
--
--
--
--
--
--
--
 
    COMMIT;
    trace1('delete_db: ' || print(l_db_unique_name) ||
           ': db_key cleanup complete');
    trace1('delete_db: ' || print(l_db_unique_name) ||
           ': deleting db metadata complete');
 
    check_for_interrupt (DELETE_DB_SVPNT_UNREGISTER);
    l_savepoint := DELETE_DB_SVPNT_UNREGISTER;
  END IF;
 
--
--
--
--
--
  IF l_savepoint = DELETE_DB_SVPNT_UNREGISTER THEN
 
    trace1 ('delete_db: ' || print(l_db_unique_name) ||
            ': at savepoint ' || print(l_savepoint) ||
            ': dbms_rcvcat.unregisterDatabase()');
 
--
--
--
--
--
--
--
--
    get_lock(LOCK_KEY, LOCK_DELETE_DB_UNREGISTER);
 
--
    dbms_rcvcat.unregisterDatabase(l_db_key, l_db_id);
 
    unlock(LOCK_KEY, LOCK_DELETE_DB_UNREGISTER);
 
    trace1('delete_db: ' || print(l_db_unique_name) ||
             ': dbms_rcvcat.unregisterDatabase() complete');
  END IF;
 
  trace1('delete_db: ' || print(l_db_unique_name) || ': complete');
 
EXCEPTION
  WHEN OTHERS THEN
    save_error;
 
--
    IF l_savepoint = DELETE_DB_SVPNT_UNREGISTER THEN
      sys.kbrsi_icd.rsKeyUnlock(LOCK_DELETE_DB_UNREGISTER);
      ROLLBACK;
    END IF;
 
--
--
   RAISE;
END execute_delete_db;
 
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE execute_check_files (p_task_rec IN task%ROWTYPE) IS
 
  l_sl_key              NUMBER := p_task_rec.sl_key;
  l_savepoint           NUMBER := NVL(p_task_rec.savepoint,0);
  l_repair              BOOLEAN := (p_task_rec.param_num1 <> 0);
  l_execute_time        TIMESTAMP WITH TIME ZONE := p_task_rec.execute_time;
 
BEGIN
   tracex ('EXECUTE_CHECK_FILES: sl_key=' || l_sl_key ||
                '; task_start=' || l_execute_time  ||
                '; savepoint=' || print(l_savepoint)  ||
                '; repair=' || print(l_repair));
 
--
   avoid_delete_db();
 
   DBMS_RA_STORAGE.CHECK_FILES(l_sl_key, l_execute_time,l_savepoint, l_repair);
EXCEPTION
  WHEN e_consistent_read THEN
    save_error;
 
--
--
--
    SELECT MAX(task_id) INTO s_pending_interrupt
      FROM task
      WHERE state = STATE_RUNNING
        AND task_type = TASK_REBUILD_INDEX;
 
    RAISE e_retry_error;
END execute_check_files;
 
--
--
--
--
--
PROCEDURE execute_crosscheck_db (p_task_rec IN task%ROWTYPE) IS
  l_db_key              NUMBER := p_task_rec.db_key;
  l_runcount            NUMBER;
BEGIN
  tracex ('EXECUTE_CROSSCHECK_DB: db_key=' || l_db_key);
 
--
--
--
  wait_for_repair (NULL, l_db_key);
  avoid_db (l_db_key); 
 
  IF p_task_rec.param_num2 IS NULL THEN
    BEGIN
      SYS.KBRSI_ICD.RSSCHEDLOCK (waitforwork => 0);
--
--
--
--
--
      SELECT COUNT(*), MIN(task_id)
        INTO l_runcount, s_pending_interrupt
        FROM task
       WHERE task_type = TASK_CROSSCHECK_DB
         AND param_num2 IS NOT NULL
         AND task_id <> p_task_rec.task_id;
 
      trace1('EXECUTE_CROSSCHECK' ||
                        ': Run count=' || l_runcount ||
                        '; Wait on task id ' || print(s_pending_interrupt));
 
      IF l_runcount > s_crosscheck_throttle THEN
--
--
--
--
        RAISE E_PENDING_INTERRUPT;
      ELSE
--
--
--
--
        UPDATE task SET param_num2=1
         WHERE task_id = s_current_task;
        COMMIT;
      END IF;
 
      SYS.KBRSI_ICD.RSSCHEDUNLOCK;
 
    EXCEPTION
      WHEN OTHERS THEN
        save_error;
        SYS.KBRSI_ICD.RSSCHEDUNLOCK;
        RAISE;
    END;        
  END IF;
 
--
--
--
  crosscheck_db(l_db_key);
 
--
--
--
  UPDATE odb SET last_crosscheck = SYSTIMESTAMP
   WHERE db_key = l_db_key;
  COMMIT;
END execute_crosscheck_db;
 
--
--
--
PROCEDURE setDatabase(p_dbkey    IN NUMBER,
                      p_dbid     OUT NUMBER,
                      p_currinc  OUT NUMBER,
                      p_db_slkey OUT NUMBER) IS
   l_currinc     NUMBER;
   l_dbid        NUMBER;
   l_db_slkey    NUMBER;
   l_dbname      VARCHAR2(30);
   l_rlgscn      NUMBER;
   l_rlgtime     DATE;
   l_dbun        VARCHAR2(30);
BEGIN
 
--
   SELECT db.curr_dbinc_key, db.db_id, reset_scn, reset_time,
          dbinc.db_name, odb.sl_key
     INTO l_currinc, l_dbid, l_rlgscn, l_rlgtime, l_dbname, l_db_slkey
     FROM db, dbinc, odb
    WHERE db.curr_dbinc_key = dbinc.dbinc_key
      AND dbinc.db_key = db.db_key
      AND db.db_key = odb.db_key
      AND db.db_key = p_dbkey;
 
--
   select  rtrim(ltrim(value)) into l_dbun
     from sys.v_$parameter where lower(name)='db_unique_name';
   dbms_rcvman.resetAll;
   dbms_rcvcat.setDatabase(db_name        => l_dbname,
                           reset_scn      => l_rlgscn,
                           reset_time     => l_rlgtime,
                           db_id          => l_dbid,
                           db_unique_name => l_dbun,
                           site_aware     => TRUE,
                           cf_type        => 0,    -- this value is overridden
--
                           dummy_instance => FALSE,
                           ors_instance   => TRUE);
 
   dbms_rcvman.setArchiveFileScopeAttributes(logs_shared => 1);
   dbms_rcvman.setBackupFileScopeAttributes(
      disk_backups_shared => 0,
      tape_backups_shared => 1);
 
   p_dbid     := l_dbid;
   p_currinc  := l_currinc;
   p_db_slkey := l_db_slkey;
 
END setDatabase;
 
--
--
--
--
--
--
--
PROCEDURE wait_for_dbfs IS
  l_filename    config.value%TYPE;
  l_dbfs_time_out  number;
BEGIN
--
--
--
  SELECT TO_NUMBER(value)*24*60*60 INTO l_dbfs_time_out
      FROM config
     WHERE name = '_dbfs_time_out_days';
 
  trace1('WAIT_FOR_DBFS: wait time is ' || print(l_dbfs_time_out));
  
--
--
--
  FOR i in 1..l_dbfs_time_out LOOP
    SELECT MIN(value) INTO l_filename
      FROM config
     WHERE name = '_waitfordbfs';
 
    IF MOD(i,60) = 1 THEN
      trace1('WAIT_FOR_DBFS: filename is ' || print(l_filename));
    END IF;
 
    IF l_filename IS NULL THEN
--
--
--
      fix_error (p_error_num => E_DBFS_WAIT_FAILURE_NUM,
                 p_param_num => s_instance);
      COMMIT;
      RETURN;
    END IF;
 
    IF sys.kbrsi_icd.fileexists(l_filename) = 1 THEN
--
--
--
      fix_error (p_error_num => E_DBFS_WAIT_FAILURE_NUM,
                 p_param_num => s_instance);
      COMMIT;
      RETURN;
    END IF;
 
--
--
--
    dbms_lock.sleep(1);
  END LOOP;
 
--
--
--
  SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(E_DBFS_WAIT_FAILURE_NUM,
                                        s_instance,
                                        l_filename);
EXCEPTION
  WHEN E_DBFS_WAIT_FAILURE THEN
    save_error;
    write_error (p_component => 'INITIALIZE', 
                 p_severity  => SEVERITY_ERROR,
                 p_param_num => s_instance);
    RAISE;
END wait_for_dbfs;
 
--
--
--
--
--
--
PROCEDURE crosscheck_db (p_db_key IN NUMBER) IS
  devtype           VARCHAR2(512) := NULL;
  
  l_set_count       NUMBER;
  l_set_stamp       NUMBER;
  l_pieceno         binary_integer;
  l_recid           NUMBER;
  l_stamp           NUMBER;
  l_handle          VARCHAR2(1024);
 
  l_bpkey           NUMBER;
  l_lastlibkey      NUMBER := 0;
  l_thislibkey      NUMBER;
  
  l_parms           VARCHAR2(1028);
  l_node            VARCHAR2(512);
  
  file_in_use       BOOLEAN := FALSE;
  rc                NUMBER;
  rc_in_use         NUMBER;
  found             BOOLEAN;
  l_new_status      VARCHAR2(1);
  l_old_status      VARCHAR2(1);
  l_dbinc_key       NUMBER;
  
  CURSOR bp_cursor(c_db_key IN NUMBER) IS
    SELECT bp.handle, bs.set_stamp, bs.set_count, bp.bp_key, bp.lib_key,
           bp.bp_recid, bp.bp_stamp, bp.piece#, bp.status
      FROM bp, bs, sbt_lib_desc lib
      WHERE bp.db_key     = c_db_key
        AND bs.bs_key     = bp.bs_key
        AND bp.status    != 'D'
        AND bp.ba_access IN ('T', 'R')
        AND bp.lib_key = lib.lib_key
        AND lib.status = 'R' -- filter ready jobs
        AND bp.lib_key IS NOT NULL
      ORDER BY bp.lib_key;
  l_dbid        NUMBER;
  l_currinc     NUMBER;
  l_db_slkey    NUMBER;
BEGIN
  trace1 ('CROSSCHECK_DB: Performing auto crosscheck for db_key=' || p_db_key);
 
--
  BEGIN
    SELECT curr_dbinc_key INTO l_dbinc_key FROM db WHERE db_key=p_db_key;
  EXCEPTION
    WHEN no_data_found THEN  -- Database has been deleted.  Just go away.
      save_error;
      clear_error;
      RETURN;
  END;
 
  setDatabase(p_db_key, l_dbid, l_currinc, l_db_slkey);
  
--
--
  OPEN bp_cursor(p_db_key);
  LOOP
    FETCH bp_cursor 
      INTO l_handle, l_set_stamp, l_set_count, l_bpkey, l_thislibkey,
            l_recid, l_stamp, l_pieceno, l_old_status;
    EXIT WHEN bp_cursor%NOTFOUND;
    
    trace1 ('CROSSCHECK_DB: handle=' || l_handle || ', set_stamp=' ||
            l_set_stamp || ', set_count=' || l_set_count || ', bp_key=' || 
            l_bpkey || ', libkey=' || l_thislibkey ||
            ', start_status=' || l_old_status);
    
--
--
    IF l_thislibkey != l_lastlibkey THEN
      
--
--
      IF (devtype IS NOT NULL) THEN
        sys.dbms_backup_restore.deviceDeallocate;
        devtype := NULL;
      END IF;
      
--
--
      SELECT lib.parms
        INTO l_parms
        FROM sbt_lib_desc lib
        WHERE lib.lib_key = l_thislibkey;
      
--
      devtype := sys.dbms_backup_restore.deviceAllocate(
                 ident        => 'RA$SBT',
                 node         => l_node,
                 type         => 'SBT_TAPE',
                 params       => l_parms,
                 dupcnt       => 1,
                 allowmts     => TRUE,
                 ors_lib_key  => l_thislibkey,
                 db_name      => NULL,
                 platform_id  => 0);
      
      l_lastlibkey := l_thislibkey;
      
    END IF;
 
--
    BEGIN
      file_in_use := FALSE;
      found       := FALSE;
      rc_in_use   := 0;
      
      rc := sys.dbms_backup_restore.validateBackupPiece(
                    recid      => l_recid,
                    stamp      => l_stamp,
                    handle     => l_handle,
                    set_stamp  => l_set_stamp,
                    set_count  => l_set_count,
                    pieceno    => l_pieceno,
                    hdl_isdisk => 0);
      
    EXCEPTION
      WHEN OTHERS THEN
        save_error;
        rc := sys.dbms_backup_restore.validate_file_different;
        sys.kbrsi_icd.rsClearErr;
        clear_error;
    END;
    
    trace1 ('CROSSCHECK_DB: After validate for bp_key=' || l_bpkey ||
            ', rc=' || rc);
 
    rc_in_use := bitand(rc, sys.dbms_backup_restore.validate_in_use);
    rc := bitand(rc, sys.dbms_backup_restore.validate_file_different);
    IF rc = 0 AND rc_in_use = 0 THEN
      found := TRUE;
    END IF;
 
--
    IF found THEN
      l_new_status := 'A';
    ELSE 
      l_new_status := 'X';
    END IF;  
    
    trace1 ('CROSSCHECK_DB: After validate for bp_key=' || l_bpkey ||
           ', modified_rc=' || rc || ', rc_in_use=' || rc_in_use ||
           ', new_status=' || l_new_status || ', old_status=' || l_old_status); 
 
--
    IF (l_old_status != l_new_status) THEN 
      trace1 ('CROSSCHECK_DB: Changing status of handle=' || l_handle || 
              ', bp_key=' || l_bpkey || ' to ' || l_new_status);
      
      dbms_rcvcat.changeBackupPiece(
                     bp_recid     => l_recid,
                     bp_stamp     => l_stamp,
                     status    => l_new_status,
                     set_stamp => l_set_stamp,
                     set_count => l_set_count);
    END IF;
    
  END LOOP;
 
  CLOSE bp_cursor;
 
  IF (devtype IS NOT NULL) THEN
    sys.dbms_backup_restore.deviceDeallocate;
    devtype := NULL;
  END IF;
  
EXCEPTION
   WHEN others THEN
      save_error;
--
      IF (devtype IS NOT NULL) THEN
         sys.dbms_backup_restore.deviceDeallocate;
      END IF;
      IF (bp_cursor%ISOPEN) THEN 
        CLOSE bp_cursor;
      END IF;
 
      RAISE;
      
END crosscheck_db;
 
--
--
--
--
PROCEDURE execute_insert_fault(p_task_rec IN task%ROWTYPE) IS
l_param_num1 NUMBER := NVL(p_task_rec.param_num1,1);
E_NO_SYNONYM EXCEPTION; 
PRAGMA EXCEPTION_INIT (E_NO_SYNONYM, -980);
BEGIN
   trace1('EXECUTE_INSERT_FAULT: Fault is ' || p_task_rec.param);
--
$IF $$RSJS_INSERT_FAULT IS NOT NULL $THEN
--
   CASE p_task_rec.param
     WHEN 'RESOURCE_ERROR' THEN
       trace1('EXECUTE_INSERT_FAULT: Step is ' || l_param_num1);
--
       UPDATE task set param_num1 = l_param_num1 + 1
         WHERE task_id = s_current_task;
       COMMIT;
 
       DBMS_LOCK.SLEEP(1);
       CASE l_param_num1
         WHEN 1 THEN RAISE E_RETRY_ERROR; 
         WHEN 2 THEN RAISE E_SNAPSHOT_TOO_OLD;
         WHEN 3 THEN RAISE E_UNABLE_EXTEND_TEMPSEG;
         WHEN 4 THEN RAISE E_CANT_EXTEND_UNDO;
         WHEN 5 THEN RETURN;
       END CASE;
     WHEN 'POOL_FULL' THEN
       trace1('EXECUTE_INSERT_FAULT: POOL_FULL');
       BEGIN
         FOR i in 1..1000 LOOP
           EXECUTE IMMEDIATE
                 q'{INSERT INTO JUNK_LAST VALUES (RPAD('A', 1000, 'A'))}';
           COMMIT;
         END LOOP;
        EXCEPTION
          WHEN E_NO_SYNONYM THEN
            trace1('EXECUTE_INSERT_FAULT: junk_last was dropped.');
       END;
     WHEN 'SLEEP' THEN
       trace1('EXECUTE_INSERT_FAULT: Sleep time is ' || l_param_num1);
       DBMS_LOCK.SLEEP (p_task_rec.param_num1); 
     WHEN 'ORA-600' THEN
       trace1('EXECUTE_INSERT_FAULT: ORA-600');
       IF NVL(p_task_rec.error_count,0) = 0 THEN
         RAISE E_ORA_600;
       END IF;
     ELSE
       SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(E_INTERNAL_ERROR_NUM,
                                             'Unknown fault: ' ||
                                             p_task_rec.param);
   END CASE;
$END
END execute_insert_fault;
 
 
--
--
--
--
PROCEDURE execute_backup_sbt (p_task_rec IN task%ROWTYPE) IS
   restore                 sbt_task.restore%TYPE;
BEGIN
   BEGIN
      SELECT restore INTO restore FROM sbt_task
       WHERE task_id = s_current_task;
   EXCEPTION
      WHEN NO_DATA_FOUND THEN
        save_error;
        log_sbt_task_error(
           p_db_key       => p_task_rec.db_key,
           p_bs_key       => p_task_rec.param_num1,
           p_bp_key       => NULL,
           p_template_key => p_task_rec.param_num2,
           p_lib_key      => NULL);
        RAISE E_FAILED;
   END;
 
   IF (restore != 'Y') THEN
      copy_sbt(p_task_rec);
      release_blocked_tasks(SPACE_PSEUDO_TASK, p_task_rec.db_key);
   END IF;
END execute_backup_sbt;              /* dbms_ra_scheduler.execute_backup_sbt */
 
 
--
--
--
--
PROCEDURE execute_restore_sbt (p_task_rec IN task%ROWTYPE) IS
   restore                 sbt_task.restore%TYPE;
   l_skip                  BOOLEAN := FALSE;
BEGIN
   BEGIN
      SELECT restore INTO restore FROM sbt_task
       WHERE task_id = s_current_task;
   EXCEPTION
      WHEN NO_DATA_FOUND THEN
        save_error;
        log_sbt_task_error(
           p_db_key       => p_task_rec.db_key,
           p_bs_key       => NULL,
           p_bp_key       => p_task_rec.param_num2,
           p_template_key => NULL,
           p_lib_key      => p_task_rec.param_num3);
        RAISE E_FAILED;
   END;
 
   IF (restore = 'Y') THEN
      IF (get_savepoint IS NOT NULL) THEN
        tracex('EXECUTE_RESTORE_SBT: Cannot restart this task');
        l_skip := TRUE;
      END IF;
 
      IF p_task_rec.com_time + (1/24/60/60 * s_servlet_wait_seconds) < sysdate
      THEN
        tracex('EXECUTE_RESTORE_SBT: Servlet com_time is too old');
        l_skip := TRUE;
      END IF;
 
--
--
--
      IF NOT l_skip THEN
        restore_sbt(p_task_rec);
      END IF;
 
--
      release_restore_wait;
   END IF;
 
EXCEPTION
  WHEN E_NO_MORE_SGA THEN
    save_error;
    RAISE;
  WHEN OTHERS THEN
    save_error;
    release_restore_wait;
    RAISE;
END execute_restore_sbt;            /* dbms_ra_scheduler.execute_restore_sbt */
 
 
 
--
PROCEDURE invalidateTemplateBackup(p_bs_key       IN NUMBER,
                                   p_bp_key       IN NUMBER,
                                   p_db_key       IN NUMBER,
                                   p_template_key IN NUMBER);
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
 
PROCEDURE copy_sbt(p_task_rec IN task%ROWTYPE) IS
 
--
  CURSOR bp_cursor(bskey IN NUMBER, pno IN NUMBER) IS
   SELECT bp.handle, bs.set_stamp, bs.set_count, bp.bp_key
     FROM bp, bs
    WHERE bs.bs_key     = bp.bs_key
      AND bp.bs_key     = bp_cursor.bskey
      AND bp.piece#     = bp_cursor.pno
      AND bp.status    != 'D'
      AND bp.ba_access != 'U'
      AND bp.lib_key is null
      AND bp.template_key is null
    ORDER BY bs.set_stamp, bs.set_count, bp.piece#, bp.copy# DESC;
 
  l_task_rec            task%ROWTYPE;
  set_count             NUMBER;
  set_stamp             NUMBER;
  out_recid             NUMBER;
  out_stamp             NUMBER;
  concur                BOOLEAN;
 
  newfilename           VARCHAR2(1024);
  newfilename1          VARCHAR2(1024);
  srcfilename           VARCHAR2(1024);
  handle                VARCHAR2(1024);
  comment               VARCHAR2(80);
  media                 VARCHAR2(80);
 
  lyear                 VARCHAR2(4);
  lday                  VARCHAR2(2);
  lmonth                VARCHAR2(2);
  lcfaudate             VARCHAR2(512);
 
  devtype               VARCHAR2(512);
  node                  VARCHAR2(255);
  bpsize                NUMBER;
  l_maxcopy             NUMBER;
  l_copynum             NUMBER;
  bpkey                 NUMBER;
  template_key          NUMBER;
  bskey                 NUMBER;
  pno                   NUMBER;
  attr_key              NUMBER;
  l_lib_key             NUMBER;
  dupcnt                NUMBER;
  server_key         NUMBER;
  l_bp_key              NUMBER;
  
  format_str            VARCHAR2(512);
  l_src_bpkey           NUMBER;
  l_delete_src          VARCHAR2(1);
  
  parms                 VARCHAR2(2048);
  l_lparms              VARCHAR2(1024);
  l_pparms              VARCHAR2(1024);
 
  l_count               NUMBER;
  l_failure_cnt         NUMBER;
  l_dbname              dbinc.db_name%TYPE;
  l_platform_id         NUMBER;
  l_send                sbt_attr_set.send%type;
  l_rep_srvr_status     rep_server.status%TYPE;
  l_rep_server_key      NUMBER;
  l_level               NUMBER;
  l_taped               NUMBER;
  l_not_taped_state     VARCHAR2(1);
  l_not_taped           NUMBER;
  l_reserved            NUMBER;
 
--
  l_dbkey               NUMBER := p_task_rec.db_key;
 
BEGIN
   trace1 ('COPY_SBT');
 
--
   SELECT template_key, bs_key, piece#, attr_key, copies, src_bpkey,
          delete_source, format, lib_key, failure_cnt, rep_server_key
     INTO template_key, bskey, pno, attr_key, dupcnt, l_src_bpkey,
          l_delete_src, format_str, l_lib_key, l_failure_cnt, l_rep_server_key
     FROM sbt_task
    WHERE task_id = s_current_task;
 
--
   SELECT attr.parms, lib.parms, server_key, attr.send
     INTO l_lparms, l_pparms, server_key, l_send
     FROM sbt_lib_desc lib, sbt_attr_set attr
    WHERE attr.lib_key = lib.lib_key
      AND attr.attr_key = copy_sbt.attr_key;
   
--
   IF l_rep_server_key IS NOT NULL THEN
     BEGIN
       SELECT status 
         INTO l_rep_srvr_status
         FROM rep_server
         WHERE rep_server_key = l_rep_server_key;
       IF l_rep_srvr_status != 'A' THEN
         RAISE no_data_found;
       END IF;
     EXCEPTION
       WHEN no_data_found THEN 
         save_error;
         trace1('COPY_SBT: Replication Server not available. ' ||
                ' l_rep_server_key=' || l_rep_server_key);
         clear_error;
         RETURN;
     END;
  END IF;
   
--
--
   IF (l_pparms IS NOT NULL) AND (l_lparms IS NOT NULL) THEN
     parms := l_pparms || ', ' || l_lparms;
   ELSIF l_pparms IS NOT NULL THEN
     parms := l_pparms;
   ELSE
     parms := l_lparms;
   END IF;
 
   BEGIN
      IF l_src_bpkey IS NULL THEN 
--
        OPEN bp_cursor(bskey, pno);
        FETCH bp_cursor INTO srcfilename, set_stamp, set_count, l_bp_key;
        IF (bp_cursor%NOTFOUND) THEN
          CLOSE bp_cursor;
          RAISE no_data_found;
        END IF;
        CLOSE bp_cursor;
      ELSE
        l_bp_key := l_src_bpkey;
     
        SELECT handle, bs_key
          INTO srcfilename, bskey
          FROM bp
          WHERE bp_key = l_src_bpkey
            AND status != 'D';
   
        SELECT set_stamp, set_count
          INTO set_stamp, set_count
          FROM bs
          WHERE bs_key = bskey;
      END IF;
   EXCEPTION
      WHEN no_data_found THEN
        save_error;
        trace1 ('COPY_SBT: backup piece not found' ||
                ', bs_key=' || bskey ||
                ', piece#=' || pno ||
                ', bp_key=' || l_src_bpkey);
        RAISE DBMS_RA_SCHEDULER.E_BACKUP_NOT_FOUND;
   END;
     
   IF NOT DBMS_RA_INT.READ_LOCK(DBMS_RA_INT.KEY_BP, l_bp_key) THEN
     trace1 ('COPY_SBT: Unable to get read_lock on bp_key=' || l_bp_key);
--
--
     RAISE dbms_ra_scheduler.e_retry_error;
   END IF;
 
   SELECT db_name INTO l_dbname
     FROM dbinc
    WHERE db_key = l_dbkey
      AND dbinc_status = 'CURRENT';
 
   SELECT platform_id INTO l_platform_id
     FROM odb
    WHERE db_key = l_dbkey;
   
--
--
--
--
--
--
--
--
--
--
--
--
--
--
   
--
--
   IF format_str IS NULL THEN
     format_str := 'RA_SBT_' || template_key || '_%U_' || bskey;
     IF (l_failure_cnt > 0) THEN
        format_str := format_str || '_' || ceil(dbms_random.value(1,100));
     END IF;
     trace1 ('COPY_SBT: format_str=' || format_str);
   END IF;
   
--
   SELECT NVL(MAX(copy#), 0)
     INTO l_maxcopy 
     FROM bp
     WHERE bs_key = bskey;
   
--
   dbms_ra_int.s_bp_save.DELETE;
 
--
   devtype := sys.dbms_backup_restore.deviceAllocate(
                 ident        => 'RA$SBT',
                 node         => node,
                 type         => 'SBT_TAPE',
                 params       => parms,
                 dupcnt       => dupcnt,
                 allowmts     => TRUE,
                 ors_lib_key  => l_lib_key,
                 db_name      => l_dbname,
                 platform_id  => l_platform_id);
 
--
   if (l_send is not null) then
      sys.dbms_backup_restore.deviceCommand(cmd => l_send);
   end if;
 
   l_copynum := 0;
   while (l_copynum < dupcnt) loop
      newfilename := sys.dbms_backup_restore.genPieceName(
                    pno       => pno,
                    set_count => set_count,
                    set_stamp => set_stamp,
                    format    => format_str,
                    copyno    => l_copynum + l_maxcopy + 1,
                    devtype   => 'SBT_TAPE',
                    year      => 0,
                    month     => 0,
                    day       => 0,
                    dbid      => null,  -- computed in server if required
                    ndbname   => null,  -- computed in server if required
                    pdbname   => null,  -- computed in server if required
                    cfseq     => null);
      if (l_copynum > 0) then
         sys.dbms_backup_restore.backupPieceCrtDupSet(l_copynum, newfilename);
      else
         newfilename1 := newfilename;
      end if;
      l_copynum := l_copynum + 1;
   end loop;
 
--
   trace1('COPY_SBT: copying '|| srcfilename || ' to ' || newfilename1);
   sys.dbms_backup_restore.backupBackupPiece(
                    bpname       => srcfilename,
                    fname        => newfilename1,
                    handle       => handle,
                    comment      => comment,
                    media        => media,
                    concur       => concur,
                    recid        => out_recid,
                    stamp        => out_stamp,
                    check_logical=> FALSE,
                    params       => NULL,
                    reuse        => FALSE,
                    deffmt       => 0,
                    copy_recid   => null,
                    copy_stamp   => null,
--
--
                    copyno       => 0,
                    npieces      => pno,
                    dest         => 0,
                    pltfrmfr     => null,
                    ors          => TRUE,
                    bpsize       => bpsize,
                    template_key => template_key);
 
--
   sys.dbms_backup_restore.deviceDeallocate;
   devtype := NULL;
   
--
   dbms_ra_int.s_bp_save.DELETE;
 
   DBMS_RA_INT.unlock(DBMS_RA_INT.KEY_BP, l_bp_key);
   
--
   IF l_delete_src = 'Y' THEN
     delete_one_backuppiece(l_bp_key);
   END IF;
 
--
--
   IF l_delete_src = 'Y' THEN
     l_taped := 0;
   ELSE
--
     SELECT NVL2(MAX(copy#), 0, bpsize) INTO l_taped
       FROM bp
       WHERE bs_key = bskey
         AND piece# = pno
         AND lib_key IS NOT NULL
         AND bp_key <> l_bp_key;
 
--
     IF l_taped > 0 THEN
       SELECT MIN(dbms_ra_pool.incrLevel(create_scn, incr_scn))
         INTO l_level
         FROM bdf 
         WHERE bs_key = bskey;
       IF l_level = 0 THEN
         l_taped := 1;
       END IF;
     END IF;
   END IF;
 
--
   DBMS_RA_STORAGE.LOCK_DB(l_dbkey);
   IF server_key IS NOT NULL AND server_key > 0 THEN
     UPDATE odb SET wait_space = NULL,
                    cumulative_rep_usage = cumulative_rep_usage + bpsize,
                    not_taped = not_taped - l_taped,
                    not_taped_state = 
                          (CASE
                             WHEN not_taped_state = 'B'
                             THEN 'C'
                             WHEN not_taped_state = 'N'
                             THEN 'I'
                             WHEN not_taped_state = 'V' AND l_taped = 1
                             THEN 'I'
                             ELSE not_taped_state
                           END)
       WHERE db_key = l_dbkey
       RETURNING not_taped_state, not_taped, base_reserved_space
         INTO l_not_taped_state, l_not_taped, l_reserved;
   ELSE
     UPDATE odb SET wait_space = NULL,
                    cumulative_sbt_usage = cumulative_sbt_usage + bpsize,
                    not_taped = not_taped - l_taped,
                    not_taped_state = 
                          (CASE
                             WHEN not_taped_state = 'B'
                             THEN 'C'
                             WHEN not_taped_state = 'N'
                             THEN 'I'
                             WHEN not_taped_state = 'V' AND l_taped = 1
                             THEN 'I'
                             ELSE not_taped_state
                           END)
       WHERE db_key = l_dbkey
       RETURNING not_taped_state, not_taped, base_reserved_space
         INTO l_not_taped_state, l_not_taped, l_reserved;
   END IF;
   COMMIT;
   trace1('COPY_SBT: not_taped_state ' || l_not_taped_state ||
          ', not_taped ' || l_not_taped);
   DBMS_RA_STORAGE.UNLOCK_DB(l_dbkey);
 
--
--
   IF server_key IS NOT NULL AND server_key > 0 THEN
--
--
     DBMS_RA_STORAGE.LOCK_DB(l_dbkey);
     UPDATE odb
       SET  last_replication = SYSTIMESTAMP
       WHERE db_key = l_dbkey;
     COMMIT;
     DBMS_RA_STORAGE.UNLOCK_DB(l_dbkey);
 
--
--
     queue_set_reconcile_timer (p_db_key => l_dbkey);
   END IF;
 
--
   UPDATE sbt_lib_desc SET failure_cnt = 0
    WHERE lib_key = l_lib_key;
 
   UPDATE sbt_task SET failure_cnt = 0
    WHERE task_id = s_current_task;
 
--
   fix_error (p_error_num  => (CASE WHEN server_key IS NOT NULL
                                 THEN E_REPLICATION_ERROR_NUM
                                 ELSE E_SBT_ERROR_NUM END),
              p_db_key     => l_dbkey,
              p_param_num  => l_lib_key);
 
--
   COMMIT;
 
--
--
--
   IF l_not_taped_state = 'C'
   OR (l_not_taped_state = 'I' AND l_not_taped + bpsize > l_reserved)
   THEN
     SELECT COUNT(*) INTO l_count
       FROM task
       WHERE task_type = TASK_GCOPY_COMPUTE
         AND db_key = l_dbkey
         AND ROWNUM = 1;
 
     IF l_count = 0 THEN
       l_task_rec.task_type     := TASK_GCOPY_COMPUTE;
       l_task_rec.db_key        := l_dbkey;
       l_task_rec.flags         := 0;
       DBMS_RA_SCHEDULER.NEW_TASK(l_task_rec);
     END IF;
   END IF;
 
--
   dbms_ra_pool.dealloc_plan_bp(bskey);
EXCEPTION
--
--
--
   WHEN E_BACKUP_NOT_FOUND THEN
      save_error;
--
      UPDATE sbt_lib_desc SET failure_cnt = 0
       WHERE lib_key = l_lib_key;
 
      UPDATE sbt_task SET failure_cnt = 0
       WHERE task_id = s_current_task;
 
--
      invalidateTemplateBackup(bskey, l_bp_key, l_dbkey, template_key);
 
      COMMIT;
      clear_error;
 
   WHEN OTHERS THEN
     save_error;
     
     DBMS_RA_STORAGE.UNLOCK_DB(l_dbkey);
 
     DBMS_RA_INT.unlock(DBMS_RA_INT.KEY_BP, l_bp_key);
 
     ROLLBACK;
 
     UPDATE sbt_task SET failure_cnt = failure_cnt + 1
      WHERE task_id = s_current_task
      RETURNING failure_cnt INTO l_failure_cnt;
 
     IF (l_failure_cnt >= s_max_sbt_failures) THEN
        invalidateTemplateBackup(bskey, l_bp_key, l_dbkey, template_key);
     END IF; 
 
     COMMIT;
 
--
     dbms_ra_int.s_bp_save.DELETE;
 
     BEGIN
--
--
       log_sbt_error (l_dbkey, l_lib_key, l_failure_cnt, TRUE);
       RAISE;
 
     EXCEPTION 
       WHEN OTHERS THEN
         save_error;
--
         IF (devtype IS NOT NULL) THEN
--
           sys.dbms_backup_restore.deviceDeallocate;
         END IF;
         RAISE;
     END;
END copy_sbt;
 
--
--
--
--
PROCEDURE log_sbt_error(p_db_key      IN NUMBER,
                        p_lib_key     IN NUMBER,
                        p_failure_cnt IN NUMBER,
                        p_retry       IN BOOLEAN) IS
  l_lib_name            sbt_lib_desc.lib_name%TYPE;
  l_rep_server_name     server.rep_server_name%TYPE;
BEGIN
  trace1('LOG_SBT_ERROR: On ' || SQLERRM);
 
--
--
--
--
  IF SQLCODE IN (E_NO_MORE_SGA_NUM, 
                 E_PENDING_INTERRUPT_NUM, 
                 E_RETRY_ERROR_NUM,
                 E_RETRY_RESERVE_NUM) THEN
    trace1('LOG_SBT_ERROR: Exiting on expected error');
    RETURN;
  END IF;
 
  UPDATE sbt_lib_desc
    SET status = (CASE WHEN failure_cnt + 1 < s_max_sbt_failures THEN 'R'
                  ELSE 'E' END),
        failure_cnt = failure_cnt + 1
    WHERE status = 'R'
      AND lib_key = p_lib_key;
  COMMIT;
 
--
--
--
  IF s_current_task IS NOT NULL THEN
    SELECT lib_name, rep_server_name INTO l_lib_name, l_rep_server_name
      FROM sbt_lib_desc lib
           LEFT OUTER JOIN server ON (lib.server_key=server.server_key)
      WHERE lib.lib_key = p_lib_key;
 
--
--
--
    log_error (p_errno =>  (CASE WHEN l_rep_server_name IS NOT NULL
                                  THEN E_REPLICATION_ERROR_NUM
                                  ELSE E_SBT_ERROR_NUM END),
               p_param1 => NVL(l_rep_server_name, l_lib_name),
               p_component => (CASE WHEN l_rep_server_name IS NOT NULL
                                  THEN 'REPLICATION'
                                  ELSE 'SBT' END),
               p_severity   => SEVERITY_ERROR,
               p_db_key     => p_db_key,
               p_param_num  => p_lib_key,
               p_param_char => NVL(l_rep_server_name, l_lib_name));
 
--
--
--
    SYS.KBRSI_ICD.RSCLEARERR;
 
    IF (NOT p_retry) THEN
       trace1('LOG_SBT_ERROR: raising failed error');
       RAISE E_FAILED;
--
--
--
--
--
--
--
--
--
--
    ELSIF l_rep_server_name IS NOT NULL THEN
--
--
       UPDATE sbt_task SET failure_cnt = 0
          WHERE task_id = s_current_task;
 
       COMMIT;
 
       trace1('LOG_SBT_ERROR: raising retryable replication error');
       RAISE E_RETRY_ERROR;
    ELSIF (p_failure_cnt >= s_max_sbt_failures) THEN
       trace1('LOG_SBT_ERROR: raising failed error');
       RAISE E_FAILED;
    ELSE
       trace1('LOG_SBT_ERROR: raising retryable error');
       RAISE E_RETRY_ERROR;
    END IF;
  END IF;
END log_sbt_error;
 
--
--
--
--
PROCEDURE log_sbt_task_error(
   p_db_key       IN NUMBER,
   p_bs_key       IN NUMBER,
   p_bp_key       IN NUMBER,
   p_template_key IN NUMBER,
   p_lib_key      IN NUMBER) IS
   cnt        NUMBER;
   l_dbname   dbinc.db_name%TYPE;
BEGIN
   IF (p_db_key IS NOT NULL) THEN
      SELECT db_name INTO l_dbname
        FROM dbinc
       WHERE db_key = p_db_key
         AND dbinc_status = 'CURRENT';
   ELSE
      l_dbname := '';
   END IF;
 
   IF (p_bp_key IS NOT NULL) THEN
      SELECT count(*) INTO cnt
        FROM bp
       WHERE bp.bs_key = p_bp_key
         AND bp.status = 'A';
 
      IF (cnt = 0) THEN
         trace1('log_sbt_task_error: bp_key '
                || p_bp_key || ' has been purged');
--
--
--
--
--
--
         RETURN;
      END IF;
   END IF;
 
   IF (p_bs_key IS NOT NULL) THEN
      SELECT count(*) INTO cnt
        FROM bs
       WHERE bs.bs_key = p_bs_key
         AND bs.status = 'A';
 
      IF (cnt = 0) THEN
         trace1('log_sbt_task_error: bs_key '
                || p_bs_key || 'has been purged.');
--
--
--
--
--
--
         RETURN;
      END IF;
   END IF;
 
   IF (p_template_key IS NOT NULL) THEN
      SELECT count(*) INTO cnt
        FROM sbt_job_template j
       WHERE j.template_key = p_template_key;
 
      IF (cnt = 0) THEN
         trace1('log_sbt_task_error: template_key '
                || p_template_key || ' has been purged');
--
--
--
--
--
--
         RETURN;
      END IF;
   END IF;
 
   IF (p_lib_key IS NOT NULL) THEN
      SELECT count(*) INTO cnt
        FROM sbt_lib_desc lib
       WHERE lib.lib_key = p_lib_key;
 
      IF (cnt = 0) THEN
         trace1('log_sbt_task_error: sbt_lib_key '
                || p_lib_key || ' has been purged');
--
--
--
--
--
--
         RETURN;
      END IF;
   END IF;
 
--
--
--
--
   trace1('log_sbt_task_error: usable backup piece has been purged');
   log_error(p_errno     => E_SBT_TASK_NOT_FOUND,
             p_component => 'SBT_TASK',
             p_param1    => 'BACKUP SET',
             p_param2    => print(p_bs_key),
             p_param3    => l_dbname,
             p_severity  => SEVERITY_WARNING);
END log_sbt_task_error;
 
--
--
--
PROCEDURE restore_sbt (p_task_rec IN task%ROWTYPE) IS
   handle        VARCHAR2(1024);
   parms         VARCHAR2(1028);
   node          VARCHAR2(512);
   devtype       VARCHAR2(512);
   l_lib_key     NUMBER;
   l_db_key      NUMBER;
   l_server_key  NUMBER;
   l_dbname      dbinc.db_name%TYPE;
   l_platform_id NUMBER;
BEGIN
   trace1 ('RESTORE_SBT: Performing sbt backup restore');
 
--
   SELECT bp.handle, lib.parms, bp.lib_key, bp.db_key, lib.server_key
     INTO handle, parms, l_lib_key, l_db_key, l_server_key
     FROM sbt_lib_desc lib, bp
    WHERE bp.lib_key = lib.lib_key
      AND bp.bp_key = p_task_rec.param_num2;
 
   SELECT db_name INTO l_dbname
     FROM dbinc
    WHERE db_key = l_db_key
      AND dbinc_status = 'CURRENT';
 
   SELECT platform_id INTO l_platform_id
     FROM odb
    WHERE db_key = l_db_key;
   
--
   devtype := sys.dbms_backup_restore.deviceAllocate(
                 ident        => 'RA$SBT',
                 node         => node,
                 type         => 'SBT_TAPE',
                 params       => parms,
                 dupcnt       => 1,
                 allowmts     => TRUE,
                 ors_lib_key  => l_lib_key,
                 db_name      => l_dbname,
                 platform_id  => l_platform_id);
 
--
   sys.kbrsi_icd.restoreSbtTask(reqid  => p_task_rec.param_num1,
                                handle => handle);
--
   sys.dbms_backup_restore.deviceDeallocate;
   devtype := NULL;
 
--
   UPDATE sbt_lib_desc SET failure_cnt = 0
    WHERE lib_key = l_lib_key;
 
   fix_error (p_error_num  =>  (CASE WHEN l_server_key IS NOT NULL
                                  THEN E_REPLICATION_ERROR_NUM
                                  ELSE E_SBT_ERROR_NUM END),
              p_db_key     => l_db_key,
              p_param_num  => l_lib_key);
 
--
   COMMIT;
 
EXCEPTION
   WHEN others THEN
      save_error;
      ROLLBACK;
 
      BEGIN
--
--
        log_sbt_error (l_db_key, l_lib_key, 0, FALSE);
        RAISE;
 
      EXCEPTION 
        WHEN OTHERS THEN
          save_error;
--
          IF (devtype IS NOT NULL) THEN
--
            sys.dbms_backup_restore.deviceDeallocate;
          END IF;
          RAISE;
      END;
 
END restore_sbt;
 
--
--
--
PROCEDURE cleanup_task(p_task_type IN NUMBER) IS
BEGIN
   IF (p_task_type = TASK_PURGE_SBT) THEN
      IF (s_libkey IS NOT NULL) THEN
         s_libkey := NULL;
         sys.dbms_backup_restore.deviceDeallocate;
      END IF;
   END IF;
END cleanup_task;
 
--
--
--
--
PROCEDURE execute_purge_sbt(p_task_rec IN task%ROWTYPE) IS
   parms         VARCHAR2(1028);
   node          VARCHAR2(512);
   devtype       VARCHAR2(512);
   l_lib_key    NUMBER;
BEGIN
--
   IF (p_task_rec.param_num1 != nvl(s_libkey, -1)) THEN
--
      IF (s_libkey IS NOT NULL) THEN
         s_libkey := NULL;
         sys.dbms_backup_restore.deviceDeallocate;
      END IF;
 
--
      BEGIN
        SELECT lib.parms
          INTO parms
          FROM sbt_lib_desc lib
         WHERE lib.lib_key = p_task_rec.param_num1;
      EXCEPTION
        WHEN no_data_found THEN 
          save_error;
          trace1('EXECUTE_PURGE_SBT: Library/Rep server has been deleted.');
          clear_error;
          RETURN;
      END;
      
--
      devtype := sys.dbms_backup_restore.deviceAllocate(
                    ident        => 'RA$SBT',
                    node         => node,
                    type         => 'SBT_TAPE',
                    params       => parms,
                    dupcnt       => 1,
                    allowmts     => TRUE,
                    ors_lib_key  => l_lib_key,
                    db_name      => NULL,
                    platform_id  => 0);
 
      s_libkey := p_task_rec.param_num1;
   END IF;
 
--
   trace1 ('EXECUTE_PURGE_SBT: Purge backuppiece ' || p_task_rec.param_char1);
   sys.kbrsi_icd.deleteBpSbt(handle => p_task_rec.param_char1);
EXCEPTION
   WHEN no_data_found THEN                -- library doesn't exists anymore
      save_error;
      NULL;
      clear_error;
END execute_purge_sbt;                /* dbms_ra_scheduler.execute_purge_sbt */
 
--
--
--
PROCEDURE execute_trim_db (p_task_rec IN task%ROWTYPE) IS
BEGIN
  tracex ('EXECUTE_TRIM_DB' ||
          ' sl_key=' || p_task_rec.sl_key ||
          '; db_key=' || p_task_rec.db_key);
 
--
--
--
  DBMS_RA_STORAGE.TRIM_DATABASE_FOR_MOVE (p_task_rec.db_key, 
                                          p_task_rec.param_num1);
END execute_trim_db;
 
--
--
--
--
--
--
--
--
--
--
PROCEDURE execute_move_all_db IS
BEGIN
--
  avoid_delete_db();
 
  DBMS_RA_STORAGE.MOVE_ALL_DB;
END execute_move_all_db;
 
--
--
--
PROCEDURE execute_move_df (p_task_rec IN task%ROWTYPE) IS
  l_sl_key      NUMBER;
  l_old_sl_key  NUMBER;
  l_chunks      NUMBER;
BEGIN
  tracex ('EXECUTE_MOVE_DF on database ' || p_task_rec.db_key ||
                            '; df_key= ' || p_task_rec.param_num1);
 
--
--
--
  s_no_wait_on_allocate := TRUE;
 
--
--
--
--
  dbms_ra_pool.moveDF(p_task_rec.db_key, p_task_rec.param_num1);
END execute_move_df;
 
--
--
--
--
--
--
PROCEDURE execute_repair_db (p_task_rec IN task%ROWTYPE) IS
  l_count       NUMBER;
BEGIN
  tracex ('EXECUTE_REPAIR_DB on database ' || print(p_task_rec.db_key) ||
                            '; sl_key= ' || p_task_rec.sl_key);
 
--
--
--
  IF p_task_rec.db_key IS NOT NULL THEN
    dbms_ra_pool.repairChunks(p_task_rec.db_key);
  END IF;
 
--
--
--
  UPDATE task SET db_key = NULL
    WHERE task_id = s_current_task;
  COMMIT;
 
--
--
--
  FOR i IN 1..360 LOOP
    SELECT COUNT(*) INTO l_count
      FROM config
     WHERE name = '_testwait'
       AND LOWER(value) = 'repair';
 
    EXIT WHEN l_count = 0;
    trace1 ('EXECUTE_REPAIR_DB: Waiting for test');
    DBMS_LOCK.SLEEP(10);
  END LOOP;
 
--
--
--
--
  SYS.KBRSI_ICD.RSSCHEDLOCK (waitforwork => 0);
 
  SELECT COUNT(*) INTO l_count
    FROM task 
    WHERE (task_type = TASK_REPAIR_DB)
      AND (db_key IS NOT NULL);
 
  trace1 ('EXECUTE_REPAIR_DB: ' || l_count || ' repair tasks still active');
 
--
--
--
--
--
  IF l_count = 0 THEN
    UPDATE sl SET sl_needs_repair = NULL,
                  sl_state = NULL
      WHERE sl_space <> 0;
    COMMIT;
  END IF;
 
  SYS.KBRSI_ICD.RSSCHEDUNLOCK(nomorejobs => 0);
 
EXCEPTION
  WHEN OTHERS THEN
    save_error;
    SYS.KBRSI_ICD.RSSCHEDUNLOCK(nomorejobs => 0);
    RAISE;
 
END execute_repair_db;
 
--
--
--
--
--
--
PROCEDURE complete_task (p_action VARCHAR2, 
                         p_taskname IN VARCHAR2,
                         p_current_execution_time TIMESTAMP WITH TIME ZONE,
                         p_final_state NUMBER) IS
  l_flags               NUMBER;
  l_purge_reserve       NUMBER := NULL;
  l_db_key              NUMBER;
  l_unlock_needed       BOOLEAN := FALSE;
  l_error_count         NUMBER;
  l_template_name       sbt_job_template.template_name%TYPE := NULL;
  l_task_type           NUMBER;
BEGIN
--
--
--
    IF s_cached_storage THEN
      DBMS_RA_STORAGE.FREE_TASK_STORAGE (s_current_task);
    END IF;
 
--
--
--
    IF s_purging_active THEN
      SELECT purge_reserve, db_key INTO l_purge_reserve, l_db_key
        FROM task
       WHERE task_id = s_current_task;
    END IF;
 
--
--
--
--
    IF NVL(l_purge_reserve, 0) > 0 THEN
      trace1 ('COMPLETE_TASK:  Freeing reserved chunks ' || l_purge_reserve);
 
      l_unlock_needed := TRUE;
      DBMS_RA_STORAGE.LOCK_DB (l_db_key);
      UPDATE odb
        SET used_space = used_space - (l_purge_reserve * sl_min_alloc)
        WHERE db_key = l_db_key;
 
      UPDATE task
         SET purge_reserve = 0
       WHERE task_id = s_current_task;
      COMMIT;
 
      DBMS_RA_STORAGE.UNLOCK_DB (l_db_key);
      l_unlock_needed := FALSE;
    END IF;
 
--
--
--
--
    SYS.KBRSI_ICD.RSSCHEDLOCK (waitforwork => 0);
 
    UPDATE task
      SET state = p_final_state,
          completion_time = SYSTIMESTAMP,
          elapsed_time = 
                elapsed_time + (SYSTIMESTAMP - p_current_execution_time)
      WHERE task_id = s_current_task
      RETURNING db_key,   error_count,   task_type
        INTO  l_db_key, l_error_count, l_task_type;
 
    trace1('COMPLETE_TASK:  Copying to task_history');
    INSERT INTO task_history
      (SELECT * FROM task WHERE task_id = s_current_task);
      
    IF (l_task_type IN (TASK_BACKUP_SBT, TASK_RESTORE_SBT))
      THEN
 
      INSERT INTO sbt_task_history
        (SELECT * FROM sbt_task WHERE task_id = s_current_task);
 
      DELETE FROM sbt_task
        WHERE task_id = s_current_task;
    END IF; -- sbt task
 
--
--
--
    DELETE FROM task
      WHERE task_id = s_current_task
      RETURNING flags, purge_reserve
           INTO l_flags, l_purge_reserve;
 
    IF NVL(l_purge_reserve,0) <> 0 THEN
      SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(
        E_INTERNAL_ERROR_NUM, 'unclaimed purge_reserve=' || l_purge_reserve);
    END IF;
 
    IF BITAND (l_flags, TASKS_CHUNK_CACHE_ACTIVE) <> 0 THEN
      SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(
        E_INTERNAL_ERROR_NUM, 'unclaimed chunk_cache');
    END IF;
 
--
--
--
    UPDATE sessions
       SET current_task = NULL,
           current_task_type = NULL
       WHERE ba_session_id = s_ba_session_id;
 
    IF BITAND(l_flags,TASKS_BLOCKING_TASK) <> 0 THEN
--
--
--
--
--
      UPDATE task
        SET pending_interrupt = NULL,
            state = (CASE state
                       WHEN STATE_RUNNING THEN STATE_RUNNING 
                       WHEN STATE_CANCELING THEN STATE_CANCELING
                       WHEN STATE_CANCEL THEN STATE_CANCEL 
                       ELSE STATE_EXECUTABLE 
                     END)
        WHERE pending_interrupt = s_current_task;
      trace1 ('COMPLETE_TASK: Releasing ' || SQL%ROWCOUNT || ' waiting tasks');
 
      COMMIT;
      SYS.KBRSI_ICD.RSSCHEDUNLOCK(nomorejobs => 0);
    ELSE
      COMMIT;
      SYS.KBRSI_ICD.RSSCHEDUNLOCK;
    END IF;
 
--
--
--
    IF BITAND (l_flags, TASKS_TOO_MANY_INTERRUPTS) <> 0  THEN 
      fix_error (p_error_num => E_TOO_MANY_INTERRUPTS_NUM,
                 p_param_num => s_current_task);
    END IF;
 
    trace_task(p_action, p_taskname);
 
EXCEPTION
  WHEN OTHERS THEN
    save_error;
    trace1('COMPLETE_TASK:  Error seen is ' || SQLERRM);
 
    IF l_unlock_needed THEN
      DBMS_RA_STORAGE.UNLOCK_DB (l_db_key);
    END IF;
 
    SYS.KBRSI_ICD.RSSCHEDUNLOCK;
    RAISE;
END complete_task;
 
--
--
--
PROCEDURE suspend_task (p_newstate IN NUMBER,
                        p_current_execution_time TIMESTAMP WITH TIME ZONE) IS
 
l_newstate      NUMBER := p_newstate;
l_flags         NUMBER;
l_interrupting_type NUMBER;
l_dfkey         NUMBER;
l_vbkey         NUMBER;
l_ptype         NUMBER;
l_priority      NUMBER;
l_interrupt_count NUMBER;
BEGIN
  trace1 ('SUSPEND_TASK:  newstate=' || p_newstate ||
                       '; pending_interrupt=' || print(s_pending_interrupt));
 
--
--
--
  IF s_cached_storage THEN
    DBMS_RA_STORAGE.FREE_TASK_STORAGE;
  END IF;
 
--
--
--
  SYS.KBRSI_ICD.RSSCHEDLOCK (waitforwork => 0);
 
  IF NVL(s_pending_interrupt,0) > 0  THEN
--
--
--
--
--
--
--
--
--
    trace1 ('SUSPEND_TASK: Waiting for task');
    UPDATE task
      SET flags = NVL(flags,0) -
                  BITAND(NVL(flags,0), TASKS_BLOCKING_TASK) +
                  TASKS_BLOCKING_TASK
      WHERE task_id = s_pending_interrupt
        AND state <> STATE_ORDERING_WAIT
        AND NOT (task_type IN 
                    (TASK_BACKUP_SBT, TASK_RESTORE_SBT,
                     TASK_OBSOLETE_SBT)
                 AND state <> STATE_RUNNING)
      RETURNING task_type, param_num1, param_num2, param_num3
           INTO l_interrupting_type, l_dfkey, l_vbkey, l_ptype;
 
    IF SQL%ROWCOUNT = 0 THEN
      trace1 ('SUSPEND_TASK: Interrupting task no longer is around');
      l_newstate := STATE_EXECUTABLE;
      s_pending_interrupt := NULL;
    ELSIF s_current_task_type IN (TASK_PURGE_DF, TASK_PURGE_DF_NOW)
      AND l_interrupting_type IN (TASK_PURGE_DF, TASK_PURGE_DF_NOW) THEN
--
--
--
--
--
--
--
--
--
--
      UPDATE task SET pending_interrupt = 0
        WHERE task_id = s_pending_interrupt
          AND state = STATE_RUNNING
          AND EXISTS (SELECT 1
                        FROM task
                        WHERE task_id = s_current_task
                          AND param_num1 = l_dfkey
                          AND param_num2 > l_vbkey
                          AND param_num3 = l_ptype
                          AND nvl(savepoint, 0) = 0);
 
      IF SQL%ROWCOUNT > 0 THEN
        trace1 ('SUSPEND_TASK: Interrupting task is an obsolete purge.'); 
      END IF;                          
    END IF;
  END IF;
 
--
--
--
  UPDATE task
    SET state = l_newstate,
        pending_interrupt = s_pending_interrupt,
        last_interrupt_time = SYSTIMESTAMP,
        interrupt_count = NVL(interrupt_count,0) + 1,
        elapsed_time = elapsed_time + 
                         (SYSTIMESTAMP - p_current_execution_time),
        ba_session_id = NULL
      WHERE task_id = s_current_task
      RETURNING BITAND(flags,TASKS_BLOCKING_TASK), priority, interrupt_count 
           INTO l_flags, l_priority, l_interrupt_count;
 
--
--
  IF ((l_priority<PRIO_MIN_BUSYWORK) AND (l_interrupt_count>s_interrupt_max))
     OR (l_interrupt_count>s_busy_interrupt_max) THEN
    log_error (p_errno => E_TOO_MANY_INTERRUPTS_NUM,
               p_param1 => TO_CHAR(s_current_task),
               p_param2 => tasktype2name(s_current_task_type),
               p_param3 => TO_CHAR(l_interrupt_count),
               p_component => tasktype2name(s_current_task_type),
               p_severity  => SEVERITY_WARNING,
               p_param_num  => s_current_task);
 
    l_flags := bitset (l_flags, TASKS_TOO_MANY_INTERRUPTS);
    UPDATE task
      SET flags = l_flags 
      WHERE task_id = s_current_task;
  END IF;
 
--
--
--
--
  UPDATE sessions
     SET current_task = NULL,
         current_task_type = NULL
     WHERE ba_session_id = s_ba_session_id;
 
--
--
--
  IF BITAND(l_flags,TASKS_BLOCKING_TASK) <> 0 THEN
    UPDATE task
      SET pending_interrupt = NULL,
          state = (CASE state
                     WHEN STATE_RUNNING THEN STATE_RUNNING 
                     WHEN STATE_CANCELING THEN STATE_CANCELING
                     WHEN STATE_CANCEL THEN STATE_CANCEL 
                     ELSE STATE_EXECUTABLE 
                   END),
          ba_session_id = NULL                
      WHERE pending_interrupt = s_current_task;
    COMMIT;
    SYS.KBRSI_ICD.RSSCHEDUNLOCK(nomorejobs => 0);
  ELSE
    COMMIT;
    SYS.KBRSI_ICD.RSSCHEDUNLOCK;
  END IF;
 
END suspend_task;
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE interrupt_tasks (p_interrupt IN interrupt_t,
                           p_task_id   IN NUMBER DEFAULT NULL,
                           p_db_key    IN NUMBER DEFAULT NULL) IS
l_updated_restore_tasks dbms_sql.number_table;
l_wait_on_task_id       NUMBER := NVL (p_task_id, s_current_task);
l_min                   NUMBER;
l_count                 NUMBER;
BEGIN
  trace1 ('INTERRUPT_TASKS: interrupt type is: ' || p_interrupt);
 
--
--
--
  LOOP
--
--
--
--
    SYS.KBRSI_ICD.RSSCHEDLOCK (waitforwork => 0);
 
--
--
--
    UPDATE task SET flags =  NVL(flags,0) -
                             BITAND(NVL(flags,0), TASKS_BLOCKING_TASK) +
                             TASKS_BLOCKING_TASK
      WHERE task_id = l_wait_on_task_id;
 
    IF SQL%ROWCOUNT = 0 THEN
      trace1 ('INTERRUPT_TASKS: Waiting-on task is missing: ' || 
                                                            l_wait_on_task_id);
      SYS.KBRSI_ICD.RSSCHEDUNLOCK;
      EXIT;
    END IF;
 
--
--
--
    IF (p_interrupt = INTERRUPT_FOR_MOVE)
    THEN
      UPDATE task
         SET pending_interrupt = l_wait_on_task_id
       WHERE task_type IN (TASK_MOVE_ALL_DB, TASK_MOVE_DF)
         AND pending_interrupt IS NULL
         AND task_id != l_wait_on_task_id;
      COMMIT;
    ELSIF (p_interrupt = INTERRUPT_FOR_PURGE)
    THEN
      UPDATE task
         SET pending_interrupt = l_wait_on_task_id
       WHERE task_type IN (TASK_RESTORE, TASK_INDEX_BACKUP)
         AND pending_interrupt IS NULL
         AND task_id != l_wait_on_task_id
         AND db_key = p_db_key
   RETURNING DECODE(task_type, TASK_RESTORE, param_num1)
        BULK COLLECT INTO l_updated_restore_tasks;
      COMMIT;
      FOR i IN 1..l_updated_restore_tasks.COUNT
      LOOP
        IF (l_updated_restore_tasks(i) IS NOT NULL)
        THEN
          SYS.KBRSI_ICD.RESTORESTOPTASK(l_updated_restore_tasks(i));
        END IF;
      END LOOP;
    END IF;
 
    SYS.KBRSI_ICD.RSSCHEDUNLOCK;
 
    IF (p_interrupt = INTERRUPT_FOR_MOVE)
    THEN
      SELECT MIN(task_id), COUNT(*)
        INTO l_min, l_count
        FROM task
       WHERE task_type IN (TASK_MOVE_ALL_DB, TASK_MOVE_DF)
         AND pending_interrupt IS NULL
         AND task_id != l_wait_on_task_id;
    ELSIF (p_interrupt = INTERRUPT_FOR_PURGE)
    THEN
      SELECT MIN(task_id), COUNT(*)
        INTO l_min, l_count
        FROM task
       WHERE task_type IN (TASK_RESTORE, TASK_INDEX_BACKUP)
         AND pending_interrupt IS NULL
         AND task_id != l_wait_on_task_id
         AND db_key = p_db_key;
    END IF;
 
    trace1('INTERRUPT_TASKS: shows ' || l_count ||
           ' tasks running starting with task id ' || l_min);
 
    EXIT WHEN l_count = 0;
    dbms_lock.sleep(s_interrupt_wait);
  END LOOP;
 
END interrupt_tasks;
 
--
--
--
PROCEDURE trace_task (p_action VARCHAR2, p_taskname IN VARCHAR2) IS
BEGIN
--
  IF s_tracing_on
  THEN
    sys.kbrsi_icd.rsTrace('########## ' ||
                          TO_CHAR(SYSTIMESTAMP, 'MM/DD/YYYY HH24:MI:SS.FF3') ||
                          '  ' || rpad(p_action, 15) || rpad(p_taskname,11)  ||
                          ' id ' || rpad(s_current_task || ' ', 14, '#'));
  ELSE
--
    sys.kbrsi_icd.rsTrace(
       '#### ' || p_action || ': ' || p_taskname || ' id ' || s_current_task);
  END IF;
END trace_task;
 
--
--
--
 
FUNCTION  define_task (task_rec   IN OUT NOCOPY task%ROWTYPE,
                       p_sbt_task IN BOOLEAN DEFAULT FALSE) RETURN NUMBER IS
    l_resource_wait_process_count NUMBER;
BEGIN
  trace1 ('DEFINE_TASK');
--
--
  task_rec.task_id       := rai_sq.nextval;
  IF (p_sbt_task) THEN
     task_rec.sbt_task_id := task_rec.task_id;
  ELSE
     task_rec.sbt_task_id := NULL;
  END IF;
  task_rec.priority         := type2priority(task_rec.task_type);
  task_rec.flags            := NVL(task_rec.flags, 0);
  task_rec.state            := STATE_EXECUTABLE;
  task_rec.schedule_time    := SYSTIMESTAMP;
  task_rec.creator_task_id  := NVL(s_current_task, s_timer_process_instance);
  task_rec.creator_sid      := TO_NUMBER(SYS_CONTEXT('USERENV', 'SID'));
  task_rec.creator_instance := s_instance;
 
--
--
--
--
  IF (task_rec.task_type = TASK_INDEX_BACKUP) OR
     (task_rec.priority >= PRIO_MIN_BUSYWORK) THEN
    SELECT TO_NUMBER(value) INTO l_resource_wait_process_count
      FROM config 
     WHERE name = '_resource_wait_task_limit';
 
    IF l_resource_wait_process_count <> MAX_RESOURCE_WAIT_PROCESSES THEN
      trace1 ('DEFINE_TASK: Cannot do busywork if resource wait is on.' ||
                      ' RW process count=' || l_resource_wait_process_count ||
                      ' Task id=' || task_rec.task_id);
 
      task_rec.state := STATE_TASK_WAIT;
      task_rec.pending_interrupt := RESOURCE_PSEUDO_TASK;
    END IF;
  END IF;
 
--
--
--
  IF task_rec.task_type IN (TASK_RESTORE, TASK_RESTORE_SBT) THEN
    task_rec.execute_inst_id := s_instance;
  ELSE
    task_rec.execute_inst_id := NULL;
  END IF;
 
  INSERT INTO task VALUES task_rec;
 
  IF s_tracing_on THEN
    trace1 ('DEFINE_TASK: Assign task_type ' ||
            tasktype2name(task_rec.task_type) || ' (' || task_rec.task_type ||
            '); task_id ' || task_rec.task_id);
  END IF;
  RETURN task_rec.task_id;
END define_task;
 
--
--
--
 
PROCEDURE new_task (task_rec   IN OUT NOCOPY task%ROWTYPE,
                    p_commit   IN BOOLEAN DEFAULT TRUE,
                    p_delay    IN BOOLEAN DEFAULT FALSE,
                    p_sbt_task IN BOOLEAN DEFAULT FALSE) IS
l_task_id NUMBER;
BEGIN
--
--
--
  IF p_delay THEN
    task_rec.pending_interrupt := s_current_task;
 
    UPDATE task SET flags = NVL(flags,0) -
                  BITAND(NVL(flags,0), TASKS_BLOCKING_TASK) +
                  TASKS_BLOCKING_TASK
      WHERE task_id = s_current_task;
    COMMIT;
  END IF;
 
--
--
--
  l_task_id := define_task (task_rec => task_rec, p_sbt_task => p_sbt_task);
 
  IF p_commit THEN
    COMMIT;
  END IF;
 
  IF p_commit AND NOT p_delay THEN
--
--
--
    SYS.KBRSI_ICD.RSRUNSCHED;
  END IF;
END new_task;
 
--
--
--
PROCEDURE newdfkey (p_dfkey IN NUMBER,p_dbinckey IN NUMBER,
                    p_pdbinckey IN NUMBER) IS
PRAGMA AUTONOMOUS_TRANSACTION;
  task_rec         task%ROWTYPE;
  l_count          NUMBER;
BEGIN
--
  SELECT COUNT(*) INTO l_count FROM task WHERE state = STATE_ORDERING_WAIT;
  IF l_count = 0 THEN
    RETURN;
  END IF;
 
  task_rec.task_type   := TASK_NEWDFKEY;
  task_rec.param_num1  := p_dfkey;
  task_rec.param_num2  := p_dbinckey;
  task_rec.param_num3  := p_pdbinckey;
--
--
  new_task (task_rec, false);
  COMMIT;
END newdfkey;
 
--
--
--
 
FUNCTION get_savepoint RETURN NUMBER IS
l_answer NUMBER;
BEGIN
--
--
--
  SELECT MIN(savepoint) INTO l_answer FROM task
  WHERE task_id = s_current_task;
 
  RETURN l_answer;
END get_savepoint;
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
FUNCTION set_blocking_purge(p_dbkey IN NUMBER,
                            p_space IN NUMBER DEFAULT NULL) RETURN NUMBER IS
  l_slkey           NUMBER;
  l_not_taped_state VARCHAR(1);
  l_task_rec        task%ROWTYPE;
BEGIN
  trace1('SET_BLOCKING_PURGE: dbkey' || p_dbkey || 
          ', needed space ' || print(p_space));
 
--
--
--
  SELECT sl_key, not_taped_state INTO l_slkey, l_not_taped_state
    FROM odb WHERE db_key = p_dbkey;
 
--
--
--
  SELECT min(task_id) INTO s_pending_interrupt
    FROM task
    WHERE task_type IN (TASK_PURGE_DF_NOW,
                        TASK_PURGE,
                        TASK_PURGE_IMMEDIATE,
                        TASK_TRIM_DB)
      AND task_id <> NVL(s_current_task,0)
      AND sl_key = l_slkey;
 
--
--
--
--
  IF s_pending_interrupt IS NULL THEN
    SELECT min(task_id) INTO s_pending_interrupt
      FROM task
      WHERE task_type IN (TASK_PURGE_DF_NOW,
                          TASK_PURGE,
                          TASK_PURGE_IMMEDIATE,
                          TASK_PURGE_DUP_DF,
                          TASK_TRIM_DB)
        AND task_id <> NVL(s_current_task,0)
        AND sl_key = l_slkey;
  END IF;
 
--
--
--
--
--
--
  IF s_pending_interrupt IS NULL
  AND s_current_task IS NOT NULL
  AND p_space IS NOT NULL
  THEN
    IF l_not_taped_state IS NOT NULL THEN
      s_pending_interrupt := SPACE_PSEUDO_TASK;
 
    ELSE  -- Make space
      trace1('SET_BLOCKING_PURGE: make space');
      l_task_rec.task_type     := TASK_PURGE_IMMEDIATE;
      l_task_rec.db_key        := p_dbkey;
      l_task_rec.sl_key        := l_slkey;
      l_task_rec.param_num1    := p_space;
      l_task_rec.flags         := 0;
 
--
--
--
--
--
      new_task(l_task_rec);
      s_pending_interrupt := l_task_rec.task_id;
    END IF;
  END IF;
 
  trace1('SET_BLOCKING_PURGE: Waiting for task -- ' ||
                                                   print(s_pending_interrupt));
  RETURN s_pending_interrupt;
END set_blocking_purge;
 
--
--
--
--
--
--
--
--
--
--
--
--
 
PROCEDURE check_for_interrupt (p_state IN NUMBER DEFAULT NULL) IS
  l_session_count       NUMBER;
  l_active_count        NUMBER;
  l_waiting_task        NUMBER;
 
BEGIN
  trace1 ('CHECK_FOR_INTERRUPT');
 
--
--
--
  IF s_current_task IS NULL THEN
    trace1 ('CHECK_FOR_INTERRUPT:  No active task!');
    RETURN;
  END IF;
 
  IF s_repair_active THEN
    trace1 ('CHECK_FOR_INTERRUPT:  Repair is underway!');
    RETURN;
  END IF;
 
--
--
--
  IF (p_state IS NOT NULL) THEN
    UPDATE task SET savepoint = p_state
      WHERE task_id = s_current_task;
    COMMIT;
    trace1 ('CHECK_FOR_INTERRUPT:  savepoint set to ' || p_state);
  END IF;
 
--
  IF s_interrupt_when AND check_when('RAI_INTERRUPT_WHEN', s_current_task)
  AND (NVL(s_current_task_type, 0) <> TASK_TEST_DUMMY)
  THEN
    RAISE E_PENDING_INTERRUPT;
  END IF;
 
--
--
--
--
  IF type2priority(s_current_task_type) >= PRIO_MIN_BUSYWORK THEN
--
--
--
    SELECT COUNT(*), COUNT (current_task) INTO l_session_count, l_active_count
     FROM sessions
     WHERE purpose IS NULL;
 
    IF (l_session_count = l_active_count) THEN
      SELECT COUNT(*) INTO l_waiting_task
        FROM task
        WHERE state = STATE_EXECUTABLE 
          AND ba_session_id IS NULL
          AND priority < PRIO_MIN_BUSYWORK
          AND task_type NOT IN (TASK_BACKUP_SBT, TASK_RESTORE_SBT,
                                TASK_PURGE_SBT)
          AND (task_type != TASK_RESTORE
                  OR NVL(execute_inst_id, s_instance) = s_instance)
          AND ROWNUM = 1;
 
      IF (l_waiting_task > 0) THEN
--
--
--
--
        trace1 ('CHECK_FOR_INTERRUPT: interrupting with' ||
                        ' sessions=' || l_session_count ||
                        ' actives=' || l_active_count);
 
        s_last_busywork_stop := SYSTIMESTAMP;
 
        UPDATE sessions SET last_busywork_stop = s_last_busywork_stop
          WHERE ba_session_id = s_ba_session_id;
        COMMIT;
 
        RAISE E_PENDING_INTERRUPT;
      END IF;
    END IF;
 
--
--
--
    SELECT MIN(task_id) INTO s_pending_interrupt
      FROM task
      WHERE pending_interrupt = s_current_task
        AND priority < type2priority(s_current_task_type);
 
    IF s_pending_interrupt IS NOT NULL THEN
      trace1 ('CHECK_FOR_INTERRUPT: interrupting because blocking task id ' || 
                                        s_pending_interrupt);
      RAISE E_PENDING_INTERRUPT;
    END IF;
  END IF;
 
--
--
--
  SELECT MAX(pending_interrupt) INTO s_pending_interrupt
    FROM task
    WHERE task_id = s_current_task;
 
  IF s_pending_interrupt IS NOT NULL THEN
    trace1 ('CHECK_FOR_INTERRUPT: Pending interrupt from task id ' ||
                                        s_pending_interrupt);
    RAISE E_PENDING_INTERRUPT;
  END IF;
 
END check_for_interrupt;
 
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
 
PROCEDURE log_error (p_errno NUMBER,
                     p_param1 VARCHAR2 DEFAULT NULL,
                     p_param2 VARCHAR2 DEFAULT NULL,
                     p_param3 VARCHAR2 DEFAULT NULL,
                     p_param4 VARCHAR2 DEFAULT NULL,
                     p_keep_stack BOOLEAN DEFAULT TRUE,
                     p_component VARCHAR2,
                     p_severity NUMBER,
                     p_sl_key NUMBER DEFAULT NULL, 
                     p_db_key NUMBER DEFAULT NULL, 
                     p_param_char VARCHAR2 DEFAULT NULL,
                     p_param_num NUMBER DEFAULT NULL) IS
BEGIN
 
  IF    p_param4 IS NOT NULL THEN
    SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(p_errno, p_param1, p_param2, 
                                          p_param3, p_param4, p_keep_stack);
  ELSIF p_param3 IS NOT NULL THEN
    SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(p_errno, p_param1, p_param2, 
                                          p_param3, p_keep_stack);
  ELSIF p_param2 IS NOT NULL THEN
    SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(p_errno, p_param1, p_param2, 
                                          p_keep_stack);
  ELSIF p_param1 IS NOT NULL THEN
    SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(p_errno, p_param1, p_keep_stack);
  ELSE
    SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(p_errno, p_keep_stack);
  END IF;
        
EXCEPTION
  WHEN OTHERS THEN
--
--
--
    IF SQLCODE = p_errno THEN
      write_error (p_component => p_component,
                   p_severity => p_severity,
                   p_sl_key => p_sl_key,
                   p_db_key => p_db_key,
                   p_param_char => p_param_char,
                   p_param_num => p_param_num);
--
    ELSE
      RAISE;
    END IF;
 
END log_error;
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
 
PROCEDURE write_error (p_component VARCHAR2, 
                       p_severity NUMBER,
                       p_sl_key NUMBER DEFAULT NULL, 
                       p_db_key NUMBER DEFAULT NULL, 
                       p_param_char VARCHAR2 DEFAULT NULL,
                       p_param_num NUMBER DEFAULT NULL) IS
 
PRAGMA AUTONOMOUS_TRANSACTION;
  l_call_stack VARCHAR2(4000);
  l_final_backtrace_stack VARCHAR2(4000);
  l_final_call_stack    VARCHAR2(4000);
  l_error_stack   VARCHAR2(4000);
  l_sqlcode       NUMBER := sqlcode;
  l_ospid VARCHAR2(24);
  l_severity NUMBER := p_severity;
  l_save_tracing BOOLEAN;
  l_count NUMBER;
  l_next_dumptime TIMESTAMP;
  l_job_name       VARCHAR2(100);
  l_seen_count NUMBER;
  l_incident_alert NUMBER;
  l_incident_dump NUMBER;
  DUMPTIME_FORMAT CONSTANT VARCHAR2(19) := 'DD-MM-RR HH24:MI:SS';
 
BEGIN
--
--
--
  l_call_stack            := SUBSTR(DBMS_RA_INT.GET_ERROR,1,4000);
  l_error_stack           := 
                        SUBSTR(SYS.DBMS_UTILITY.FORMAT_ERROR_STACK,1,4000);
  l_final_backtrace_stack := 
                        SUBSTR(SYS.DBMS_UTILITY.FORMAT_ERROR_BACKTRACE,1,4000);
  l_final_call_stack      := SUBSTR(SYS.DBMS_UTILITY.FORMAT_CALL_STACK,1,4000);
 
--
--
--
  SELECT spid INTO l_ospid FROM sys.rai_my_ospid WHERE ROWNUM=1;
 
--
--
--
  IF s_trace_file IS NULL THEN
    BEGIN
      SELECT value INTO s_trace_file
        FROM v$diag_info 
        WHERE name = 'Default Trace File';
    EXCEPTION
      WHEN NO_DATA_FOUND THEN
        save_error;
        s_trace_file := 'Unknown trace file';
        clear_error;
    END;
  END IF;
 
--
--
--
--
--
--
--
  FOR i IN 1..100 LOOP
    BEGIN
      MERGE INTO error_log USING dual ON 
                    (error_num = l_sqlcode AND
                     NVL(sl_key, -1) = NVL(p_sl_key, -1) AND
                     NVL(db_key, -1) = NVL(p_db_key, -1) AND
                     NVL(param_char, '?') = NVL(p_param_char, '?') AND
                     NVL(param_num, -1) = NVL(p_param_num, -1))
        WHEN NOT MATCHED THEN
          INSERT (incident#, error_num, 
                  sl_key, db_key, param_char, param_num,
                  status, component, severity, error_text, 
                  first_seen, last_seen, seen_count, 
                  ospid, inst_id, task_id, trace_file,
                  call_stack, final_call_stack, final_backtrace_stack)
          VALUES (rai_sq.nextval, l_sqlcode, 
                  p_sl_key, p_db_key, p_param_char, p_param_num,
                  'ACTIVE', p_component, p_severity, l_error_stack,
                  SYSTIMESTAMP, SYSTIMESTAMP, 1, 
                  l_ospid, s_instance, s_current_task, s_trace_file,
                  l_call_stack, l_final_call_stack, l_final_backtrace_stack)
        WHEN MATCHED THEN
--
          UPDATE SET status = 'ACTIVE',
                     component = p_component,
                     severity = p_severity,
                     error_text = l_error_stack,
                     last_seen = SYSTIMESTAMP, 
                     seen_count = seen_count + 1,
                     ospid = l_ospid,
                     inst_id = s_instance,
                     task_id = s_current_task,
                     trace_file = s_trace_file,
                     call_stack = l_call_stack,
                     final_call_stack = l_final_call_stack,
                     final_backtrace_stack = l_final_backtrace_stack;
 
--
      SELECT seen_count, alert.value, dump.value
        INTO l_seen_count, l_incident_alert, l_incident_dump
        FROM error_log, config alert, config dump
        WHERE (error_num = l_sqlcode AND
               NVL(sl_key, -1) = NVL(p_sl_key, -1) AND
               NVL(db_key, -1) = NVL(p_db_key, -1) AND
               NVL(param_char, '?') = NVL(p_param_char, '?') AND
               NVL(param_num, -1) = NVL(p_param_num, -1))
          AND alert.name = '_incident_alert_threshold'
          AND dump.name = '_incident_dump_threshold';
      COMMIT;
      EXIT;
 
    EXCEPTION
      WHEN DUP_VAL_ON_INDEX OR E_NO_LONGER_EXISTS THEN
        save_error;
        trace1('WRITE_ERROR:  Retrying after ' || SQLERRM);
        DBMS_LOCK.SLEEP(1);
        clear_error;
        CONTINUE;
    END;
  END LOOP;
 
--
--
--
  IF (l_severity >= l_incident_alert) AND (l_seen_count = 1) THEN
    l_save_tracing := s_tracing_on;
    s_tracing_on := TRUE;
 
--
--
--
    SYS.DBMS_SYSTEM.KSDWRT(SYS.DBMS_SYSTEM.ALERT_FILE,
                           'Recovery Appliance failure on ospid: ' || 
                           l_ospid ||
                           '; Errors: '  || l_error_stack);
 
    trace1 ('WRITE_ERROR: Recovery Appliance failure on ospid: ' || l_ospid ||
                           '; Errors: '  || l_error_stack);
 
    trace1 ('WRITE_ERROR saved call stack(s):');
    trace1 (l_call_stack);
    trace1 ('WRITE_ERROR final call stack:');
    trace1 (l_final_call_stack);
    trace1 ('WRITE_ERROR final backtrace: ');
    trace1 (l_final_backtrace_stack);
 
    s_tracing_on := l_save_tracing;
  ELSE
    trace1 ('BA warning: ' || l_error_stack);
  END IF;
 
--
--
--
--
--
--
  IF (p_severity >= l_incident_dump) AND (l_seen_count = 1) THEN
--
--
--
    BEGIN
      SELECT TO_TIMESTAMP(value, DUMPTIME_FORMAT)
        INTO l_next_dumptime
        FROM config
       WHERE (name = '_dumper_last_dump_timestamp')
         FOR UPDATE NOWAIT;
    EXCEPTION
      WHEN E_RESOURCE_BUSY THEN
        save_error; 
--
        l_next_dumptime := SYSTIMESTAMP;
        clear_error;
      WHEN NO_DATA_FOUND THEN
        save_error; 
        l_next_dumptime := NULL;
        clear_error;
    END;
 
    trace1 ('WRITE_ERROR: previous dump time was ' || 
                                NVL(TO_CHAR(l_next_dumptime), 'NULL'));
    IF (l_next_dumptime IS NULL) OR
       ((l_next_dumptime + s_dumper_inhibit_interval) <= SYSTIMESTAMP) THEN
 
--
--
--
      UPDATE config SET value = TO_CHAR(SYSTIMESTAMP, DUMPTIME_FORMAT)
        WHERE name = '_dumper_last_dump_timestamp';
      COMMIT;
 
      l_job_name := 'RA_DUMPER_' || rai_sq.nextval;
      trace1 ('WRITE_ERROR dumping job: ' || l_job_name);
 
--
--
--
      DBMS_SCHEDULER.CREATE_JOB(
             job_name   => l_job_name
            ,job_type   => 'plsql_block'
            ,job_action => 'dbms_ra_dump.dumper(' || l_ospid || ',FALSE,TRUE);'
            ,enabled    => TRUE
            ,auto_drop  => TRUE);
 
--
--
--
      sys.kbrsi_icd.rsOAMDump;
      
--
--
--
      FOR l_x IN 1..360 LOOP
        DBMS_LOCK.SLEEP(10);
 
        make_amjobs (name => l_job_name);
        EXIT WHEN s_amjobs.COUNT = 0;
      END LOOP;
      trace1 ('WRITE_ERROR dump completed');
 
    ELSE
      ROLLBACK;  -- Unlock row in config table if we aren't going to dump.
    END IF;
  END IF;
 
END write_error;
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
 
PROCEDURE fix_error (p_error_num NUMBER, 
                     p_sl_key NUMBER DEFAULT NULL, 
                     p_db_key NUMBER DEFAULT NULL, 
                     p_param_char VARCHAR2 DEFAULT NULL,
                     p_param_num NUMBER DEFAULT NULL,
                     p_timestamp TIMESTAMP WITH TIME ZONE DEFAULT NULL) IS
BEGIN
  UPDATE error_log
    SET status = 'FIXED'
    WHERE error_num = p_error_num
      AND (p_sl_key IS NULL OR sl_key = p_sl_key)
      AND (p_db_key IS NULL OR db_key = p_db_key)
      AND (p_param_char IS NULL OR param_char = p_param_char)
      AND (p_param_num IS NULL OR param_num = p_param_num)
      AND (p_timestamp IS NULL OR last_seen < p_timestamp);
 
  trace1('FIX_ERROR: Cleared ' || SQL%ROWCOUNT || ' errors for ' ||
                     'error_num=' || p_error_num ||
                   '; sl_key=' || print(p_sl_key) ||
                   '; db_key=' || print(p_db_key) ||
                   '; param_char=' || print(p_param_char) ||
                   '; param_num=' || print(p_param_num) ||
                   '; timestamp=' || print(TO_CHAR(p_timestamp)) );
END fix_error;
 
 
--
--
--
--
--
--
--
--
 
PROCEDURE reset_error (p_incident# NUMBER) IS
BEGIN
  UPDATE error_log
    SET status = 'RESET'
    WHERE incident# = p_incident#;
 
  trace1('RESET_ERROR: Cleared ' || SQL%ROWCOUNT || ' errors for incident# ' ||
                       p_incident#);
  COMMIT;
END reset_error;
 
 
--
--
--
--
--
PROCEDURE assert_owner IS
BEGIN
  IF SYS.rai_schema(TRUE) <> SYS_CONTEXT('USERENV','SESSION_USER') THEN
    SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(E_BAD_USER_NUM, SYS.rai_schema);
  END IF;
END assert_owner;
 
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE purge_immediate(p_sl_key      IN NUMBER,
                          p_db_key      IN NUMBER,
                          p_allocation  IN NUMBER) IS
 
  l_task_rec task%ROWTYPE;
BEGIN
--
  trace1 ('PURGE_IMMEDIATE for '  ||
          '  p_sl_key='  || p_sl_key ||
          ', p_db_key='  || p_db_key ||
          ', p_allocation=' || print(p_allocation));
 
--
--
--
  l_task_rec.task_type     := TASK_PURGE_IMMEDIATE;
  l_task_rec.db_key        := p_db_key;
  l_task_rec.sl_key        := p_sl_key; -- Used to query task queue.
  l_task_rec.param_num1    := p_allocation;
  l_task_rec.flags         := 0;
  new_task(l_task_rec);
 
--
--
--
  schedule(p_task_type => TASK_PURGE_IMMEDIATE, p_param1 => p_sl_key);
  trace1 ('PURGE_IMMEDIATE complete');
END purge_immediate;
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE quiesce_rs IS
l_lockflag              BOOLEAN;
l_session_count         NUMBER := 1;
l_task_rec              task%ROWTYPE;
l_sessions              NUMBER := 1;
l_tasks                 NUMBER;
l_backup_pieces         NUMBER := 1;
l_session_rowids        DBMS_SQL.UROWID_TABLE;
 
 
BEGIN
  trace1 ('QUIESCE_RS');
 
--
--
--
--
--
--
--
--
  l_lockflag := SYS.KBRSI_ICD.RSKEYWRITELOCK (LOCK_QUIESCE_PENDING, TRUE); 
  trace1 ('QUIESCE_RS: Locking out new backup pieces');
 
  SYS.KBRSI_ICD.RSQUIESCELOCK;
  trace1 ('QUIESCE_RS: Locking out further activity');
 
--
--
  LOOP
--
--
--
    SYS.KBRSI_ICD.RSSCHEDLOCK (waitforwork => 0);
 
    UPDATE task
      SET pending_interrupt = 0
      WHERE (state = STATE_RUNNING)
        AND (priority >= PRIO_MIN_BUSYWORK)
        AND pending_interrupt IS NULL;
    trace1 ('QUIESCE_RS: Requested interrupts for ' ||
                                                    SQL%ROWCOUNT || ' tasks');
    COMMIT;
 
    SYS.KBRSI_ICD.RSSCHEDUNLOCK;
 
--
--
--
--
--
    SELECT COUNT(*) INTO l_tasks
      FROM task
      WHERE task_type = TASK_QUIESCE_RS
        AND state = STATE_EXECUTABLE
        AND ROWNUM = 1;
 
    IF l_tasks = 0 THEN
      SELECT COUNT(*) INTO l_session_count
        FROM sessions;
 
      FOR i IN 1..l_session_count+1 LOOP
        l_task_rec.task_type      := TASK_QUIESCE_RS;
        l_task_rec.flags          := 0;
        new_task (task_rec => l_task_rec, p_commit=> FALSE);
      END LOOP;
      COMMIT;
 
      trace1 ('QUIESCE_RS: Created ' ||
                                 (l_session_count+1) || ' more quiesce tasks');
 
--
--
--
      SYS.KBRSI_ICD.RSRUNSCHED;
    END IF;
 
--
--
--
--
--
--
--
--
--
--
    BEGIN
      SELECT COUNT(*) INTO l_sessions
        FROM sessions s
        WHERE current_task_type <> TASK_QUIESCE_RS
          AND current_task <> NVL(s_current_task,-1)
          AND EXISTS (SELECT 1
                        FROM sys.rai_active_sessions a
                        WHERE a.inst_id = s.instance_id
                          AND a.audsid = s.audsid
                          AND a.sid = s.sid
                          AND a.serial# = s.serial#
                          AND a.logon_time = s.logon_time);
 
      trace1 ('QUIESCE_RS: Waiting for ' || l_sessions || ' sessions');
    EXCEPTION
      WHEN E_PQ_FAILURE THEN
        save_error;
--
        trace1 ('QUIESCE_RS: E_PQ_FAILURE');
        DBMS_LOCK.SLEEP(1);
        clear_error;
        CONTINUE;
    END;
 
--
--
--
    SELECT COUNT(*) INTO l_backup_pieces
      FROM sbt_catalog
     WHERE completed = 'N'
       AND filesize IS NOT NULL;
 
    trace1 ('QUIESCE_RS: Waiting for ' || l_backup_pieces || ' b/u pieces');
 
--
--
--
    EXIT WHEN (l_sessions = 0) AND (l_backup_pieces = 0);
 
--
--
--
--
    IF (l_backup_pieces <> 0) THEN
      BEGIN
        execute_rm_incomplete_files (sbtonly => TRUE);
      EXCEPTION
--
--
--
        WHEN E_RETRY_ERROR THEN
          save_error;
          clear_error;
      END;
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
      SELECT ROWID BULK COLLECT INTO l_session_rowids
        FROM sessions
       ORDER BY ROWID;
 
      FORALL i IN l_session_rowids.FIRST..l_session_rowids.LAST
        UPDATE sessions SET last_quiesce = SYSTIMESTAMP
          WHERE ROWID = l_session_rowids(i);
      COMMIT;
 
      SYS.KBRSI_ICD.RSQUIESCEUNLOCK;
    END IF;
 
--
--
--
    IF s_tracing_on THEN
      FOR sc IN (SELECT ct_key, db_key, handle, pieceinc, filesize, last_entry
                   FROM sbt_catalog
                   WHERE completed = 'N'
                     AND filesize IS NOT NULL) LOOP
        trace1 ('QUIESCE_RS: Incomplete piece=' || sc.ct_key || 
                        ' for db=' || sc.db_key ||
                        ' lastentry=' || sc.last_entry || 
                        ' filesize=' || sc.filesize);
        trace1 ('QUIESCE_RS:         Handle=' || sc.handle || 
                                    ' Pieceinc=' || sc.pieceinc);
      END LOOP;
 
      FOR sess IN (SELECT current_task FROM sessions s
                    WHERE current_task_type <> TASK_QUIESCE_RS
                      AND current_task <> NVL(s_current_task,-1)) LOOP
        trace1 ('QUIESCE_RS: Blocking task=' || sess.current_task); 
      END LOOP;
    END IF;
 
--
--
--
    DBMS_LOCK.SLEEP(s_quiesce_wait);
 
    IF (l_backup_pieces <> 0) THEN
--
--
--
      SYS.KBRSI_ICD.RSQUIESCELOCK;
    END IF;
  END LOOP;
 
--
--
--
--
  SELECT ROWID BULK COLLECT INTO l_session_rowids
    FROM sessions
   ORDER BY ROWID;
 
  FORALL i IN l_session_rowids.FIRST..l_session_rowids.LAST
    UPDATE sessions 
      SET last_quiesce = NULL
      WHERE ROWID = l_session_rowids(i);
  COMMIT;
 
  trace1 ('QUIESCE_RS: We have quiet.');
END quiesce_rs;
 
 
--
--
--
--
--
--
PROCEDURE unquiesce_rs IS
BEGIN
  trace1 ('UNQUIESCE_RS');
 
--
--
--
  SYS.KBRSI_ICD.RSQUIESCEUNLOCK;
 
  trace1 ('QUIESCE_RS: We no longer have quiet.');
 
--
--
--
  SYS.KBRSI_ICD.RSRUNSCHED;
 
--
--
--
  SYS.KBRSI_ICD.RSKEYUNLOCK(LOCK_QUIESCE_PENDING);
 
END unquiesce_rs;
 
 
--
--
--
--
--
--
--
--
--
--
--
FUNCTION print (p_value IN BOOLEAN) RETURN VARCHAR2 IS
BEGIN
  IF p_value THEN
    RETURN 'TRUE';
  ELSIF p_value IS NULL THEN
    RETURN 'NULL';
  ELSE
    RETURN 'FALSE';
  END IF;
END print;
 
FUNCTION print (p_value IN NUMBER) RETURN VARCHAR2 IS
BEGIN
  RETURN NVL(TO_CHAR(p_value),'NULL');
END print;
 
FUNCTION print (p_value IN DSINTERVAL_UNCONSTRAINED) RETURN VARCHAR2 IS
BEGIN
  RETURN NVL(TO_CHAR(p_value),'NULL');
END print;
 
FUNCTION print (p_value IN VARCHAR2) RETURN VARCHAR2 IS
BEGIN
  RETURN NVL(p_value,'***NULL***');
END print;
 
FUNCTION print (p_value IN TIMESTAMP WITH TIME ZONE) RETURN VARCHAR2 IS
BEGIN
  IF p_value IS NULL THEN
    RETURN '***NULL***';
  ELSE
    RETURN TO_CHAR(p_value, 'DD-MON-YY HH24:MI:SS.FF3');
  END IF;
END print;
 
FUNCTION print (p_value IN DATE) RETURN VARCHAR2 IS
BEGIN
  IF p_value IS NULL THEN
    RETURN '***NULL***';
  ELSE
    RETURN TO_CHAR(p_value, 'DD-MON-YY HH24:MI:SS');
  END IF;
END print;
 
--
--
--
--
--
--
--
--
--
--
--
--
FUNCTION bittst (p_mask IN NUMBER, p_bit IN NUMBER) RETURN BOOLEAN IS
BEGIN
  IF BITAND (p_mask, p_bit) <> 0 THEN
    RETURN TRUE;
  ELSE 
    RETURN FALSE;
  END IF;
END bittst;
 
--
--
--
--
--
--
--
--
--
--
--
--
FUNCTION bitclr (p_mask IN NUMBER, p_bit IN NUMBER) RETURN NUMBER IS
BEGIN
  RETURN p_mask - BITAND (p_mask, p_bit); 
END bitclr;
 
--
--
--
--
--
--
--
--
--
--
--
--
FUNCTION bitset (p_mask IN NUMBER, p_bit IN NUMBER) RETURN NUMBER IS
BEGIN
  RETURN bitclr(p_mask, p_bit) + p_bit; 
END bitset;
 
--
--
--
--
--
--
--
--
--
--
FUNCTION interval2secs (p_interval IN DSINTERVAL_UNCONSTRAINED) RETURN NUMBER IS
  l_seconds            NUMBER;
 
BEGIN
 
  l_seconds := to_number(extract(second from p_interval)) +
    to_number(extract(minute from p_interval)) * 60 +
    to_number(extract(hour from p_interval))   * 60 * 60 +
    to_number(extract(day from p_interval))  * 60 * 60 * 24;
 
  RETURN l_seconds;
END interval2secs;
 
--
--
--
--
--
--
--
--
--
--
--
--
FUNCTION check_when (p_view IN VARCHAR2, p_task_id IN NUMBER) RETURN BOOLEAN IS
  l_tmp     NUMBER;
  l_answer  BOOLEAN;
BEGIN
  BEGIN
    IF p_view = 'RAI_STALL_WHEN' THEN
      EXECUTE IMMEDIATE 'SELECT 1 FROM RAI_STALL_WHEN WHERE TASK_ID = :task'
        INTO l_tmp USING p_task_id;
    ELSIF p_view = 'RAI_DEBUG_WHEN' THEN
      EXECUTE IMMEDIATE 'SELECT 1 FROM RAI_DEBUG_WHEN WHERE TASK_ID = :task'
        INTO l_tmp USING p_task_id;
    ELSIF p_view = 'RAI_INTERRUPT_WHEN' THEN
      EXECUTE IMMEDIATE 'SELECT 1 FROM RAI_INTERRUPT_WHEN WHERE TASK_ID = :task'
        INTO l_tmp USING p_task_id;
    ELSE
      SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(
                                      DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM, 
                                      'Check_when unknown view ' || p_view);
    END IF;
 
    l_answer := TRUE;
  EXCEPTION
    WHEN no_data_found THEN
      save_error;
      l_answer := FALSE;
      clear_error;
    WHEN OTHERS THEN
      save_error;
--
      trace1 ('CHECK_WHEN: Error seen is ' || SQLERRM);
      SYS.KBRSI_ICD.RSCLEARERR;
      clear_error;
  END;
 
  trace1('check_when: ' || p_view || ' id ' || p_task_id ||
                                                   ' is ' || print(l_answer));
  RETURN l_answer;
END check_when;
 
--
--
--
--
--
--
--
--
--
--
FUNCTION type2priority (p_tasktype IN NUMBER) RETURN NUMBER IS
retval NUMBER;
BEGIN
  retval :=
    CASE p_tasktype
      WHEN TASK_QUIESCE_RS        THEN PRIO_QUIESCE_RS
      WHEN TASK_SPAWN_SBT         THEN PRIO_SPAWN_SBT
      WHEN TASK_PURGE_DF_NOW      THEN PRIO_PURGE_DF_NOW
      WHEN TASK_RESTORE           THEN PRIO_RESTORE
      WHEN TASK_STORAGE_HISTOGRAM THEN PRIO_STORAGE_HISTOGRAM
      WHEN TASK_DEFERRED_DELETE   THEN PRIO_DEFERRED_DELETE
      WHEN TASK_GCOPY_COMPUTE     THEN PRIO_GCOPY_COMPUTE
      WHEN TASK_PURGE_IMMEDIATE   THEN PRIO_PURGE_IMMEDIATE
      WHEN TASK_PURGE_DF          THEN PRIO_PURGE_DF
      WHEN TASK_PURGE_DUP_DF      THEN PRIO_PURGE_DUP_DF
      WHEN TASK_TRIM_DB           THEN PRIO_TRIM_DB
      WHEN TASK_DELETE_DB         THEN PRIO_DELETE_DB
      WHEN TASK_BACKUP_ARCH       THEN PRIO_BACKUP_ARCH
      WHEN TASK_INC_ARCH          THEN PRIO_INC_ARCH
      WHEN TASK_PLAN_SBT          THEN PRIO_PLAN_SBT
      WHEN TASK_INDEX_BACKUP      THEN PRIO_INDEX_BACKUP
      WHEN TASK_NEWDFKEY          THEN PRIO_NEWDFKEY
      WHEN TASK_PURGE             THEN PRIO_PURGE
      WHEN TASK_PLAN_DF           THEN PRIO_PLAN_DF
      WHEN TASK_INSERT_FAULT      THEN PRIO_INSERT_FAULT
      WHEN TASK_MOVE_DF           THEN PRIO_MOVE_DF
      WHEN TASK_MOVE_ALL_DB       THEN PRIO_MOVE_ALL_DB
      WHEN TASK_POLL              THEN PRIO_POLL
      WHEN TASK_BACKUP_SBT        THEN PRIO_BACKUP_SBT
      WHEN TASK_RESTORE_SBT       THEN PRIO_RESTORE_SBT
      WHEN TASK_PURGE_SBT         THEN PRIO_PURGE_SBT
      WHEN TASK_OBSOLETE_SBT      THEN PRIO_OBSOLETE_SBT
      WHEN TASK_RM_INCOMPLETE_FILES THEN PRIO_RM_INCOMPLETE_FILES
      WHEN TASK_DB_STATS_REFRESH  THEN PRIO_DB_STATS_REFRESH
      WHEN TASK_RESTORE_RANGE_REFRESH THEN PRIO_RESTORE_RANGE_REFRESH
      WHEN TASK_OPTIMIZE_CHUNKS_DF THEN PRIO_OPTIMIZE_CHUNKS_DF
      WHEN TASK_OPTIMIZE_CHUNKS   THEN PRIO_OPTIMIZE_CHUNKS
      WHEN TASK_REBUILD_INDEX     THEN PRIO_REBUILD_INDEX
      WHEN TASK_VALIDATE_DB       THEN PRIO_VALIDATE_DB
      WHEN TASK_CHECK_FILES       THEN PRIO_CHECK_FILES
      WHEN TASK_CROSSCHECK_DB     THEN PRIO_CROSSCHECK_DB
      WHEN TASK_RECONCILE         THEN PRIO_RECONCILE
      WHEN TASK_REPAIR_DB         THEN PRIO_REPAIR_DB
      ELSE 99999 -- pseudo tasks don't get priorities
    END;
  trace1 ('TYPE2PRIORITY:  Priority is ' || retval);
 
  IF s_safe_mode AND (retval = 99999) THEN
        SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(
               DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM, 
                            'Task type ' || p_tasktype || ' has no priority');
  END IF;
 
  RETURN retval;
END type2priority;
 
--
--
--
--
--
--
--
--
--
--
FUNCTION tasktype2name (p_task_type NUMBER) RETURN VARCHAR2 IS
 
BEGIN
  IF p_task_type IS NULL THEN
    RETURN 'NULL';
  END IF;
 
--
--
--
  IF NOT s_tasktype2name.EXISTS(p_task_type) THEN
    FOR tt IN (SELECT task_type, task_type_name FROM tasktypenames) LOOP
      s_tasktype2name(tt.task_type) := tt.task_type_name;
    END LOOP;
  END IF;
 
  RETURN s_tasktype2name(p_task_type);
EXCEPTION
  WHEN no_data_found THEN
    save_error;
    clear_error;
    RETURN ('ILLEGAL_' || TO_CHAR(p_task_type));     
END tasktype2name;
 
 
--
--
--
--
--
--
--
--
--
--
FUNCTION taskstate2name (p_task_state NUMBER,
                         p_pending_interrupt NUMBER DEFAULT 0
                        ) RETURN VARCHAR2 IS
  l_statestr     VARCHAR2(30);
 
BEGIN
  CASE p_task_state
    WHEN STATE_EXECUTABLE       THEN l_statestr := 'EXECUTABLE';
    WHEN STATE_RUNNING          THEN l_statestr := 'RUNNING';
    WHEN STATE_COMPLETED        THEN l_statestr := 'COMPLETED';
    WHEN STATE_ORDERING_WAIT    THEN l_statestr := 'ORDERING_WAIT';
    WHEN STATE_TASK_WAIT        THEN 
           CASE p_pending_interrupt
                WHEN SERVLET_PSEUDO_TASK  THEN l_statestr := 'SERVLET_WAIT';
                WHEN SPACE_PSEUDO_TASK    THEN l_statestr := 'SPACE_WAIT';
                WHEN OPT_DF_PSEUDO_TASK   THEN l_statestr := 'OPT_DF_WAIT';
                WHEN TEST_PSEUDO_TASK     THEN l_statestr := 'TEST_WAIT';
                WHEN RESOURCE_PSEUDO_TASK THEN l_statestr := 'RESOURCE_WAIT';
                WHEN STALL_PSEUDO_TASK    THEN l_statestr := 'STALL_WHEN_WAIT';
                WHEN LIBRARY_PSEUDO_TASK  THEN l_statestr := 'LIBRARY_WAIT';
                WHEN POOL_FULL_PSEUDO_TASK THEN l_statestr := 'POOL_FULL_WAIT';
                ELSE                           l_statestr := 'TASK_WAIT';
            END CASE;
    WHEN STATE_RESTORE_WAIT     THEN l_statestr := 'RESTORE_WAIT';
    WHEN STATE_RETRYING         THEN l_statestr := 'RETRYING';
    WHEN STATE_FAILED           THEN l_statestr := 'FAILED';
    WHEN STATE_CANCEL           THEN l_statestr := 'CANCEL';
    WHEN STATE_CANCELING        THEN l_statestr := 'CANCELING';
    WHEN STATE_CANCELED         THEN l_statestr := 'CANCELED';
    ELSE l_statestr := 'ILLEGAL_' || TO_CHAR(p_task_state); /*NF_START*/
  END CASE;
  RETURN l_statestr;
END taskstate2name;
 
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE make_amjobs (name VARCHAR2 DEFAULT 'RA$%') IS
  l_done BOOLEAN := FALSE;
BEGIN
  WHILE NOT l_done LOOP
    BEGIN
 
      SELECT rai_jobs_type(job_name, 
                          NVL(instance_id, s_instance), 
                          comments)
        BULK COLLECT INTO s_amjobs
        FROM user_scheduler_jobs
        WHERE job_name LIKE name
          AND enabled = 'TRUE'
          AND state IN ('RUNNING', 'SCHEDULED');
 
      trace1 ('MAKE_AMJOBS: Rows copied=' || SQL%ROWCOUNT);
      l_done := TRUE;
    EXCEPTION
      WHEN E_PQ_FAILURE THEN
        save_error;
        trace1 ('MAKE_AMJOBS: E_PQ_FAILURE');
        DBMS_LOCK.SLEEP(1);
        clear_error;
        CONTINUE;
    END;
  END LOOP;
END make_amjobs;
 
--
--
--
--
--
--
--
--
--
PROCEDURE make_amlocks IS
  l_done BOOLEAN := FALSE;
BEGIN
  WHILE NOT l_done LOOP
    BEGIN
      SELECT rai_locks_type(inst_id, ba_type, key, lmode, ctime, sid) 
          BULK COLLECT INTO s_amlocks
        FROM sys.rai_js_gvlocks;
      trace1 ('MAKE_AMLOCKS: Rows copied=' || SQL%ROWCOUNT);
      l_done := TRUE;
    EXCEPTION
      WHEN E_PQ_FAILURE THEN
        save_error;
        trace1 ('MAKE_AMLOCKS: E_PQ_FAILURE');
        DBMS_LOCK.SLEEP(1);
        clear_error;
        CONTINUE;
    END;
  END LOOP;
END make_amlocks;
 
--
--
--
--
--
--
PROCEDURE load_config IS
  TYPE names_tab IS TABLE OF config.name%TYPE;
  l_names names_tab;
  TYPE values_tab IS TABLE OF config.value%TYPE;
  l_values values_tab;
BEGIN
  IF NOT s_init_done THEN
    sys.kbrsi_icd.rsSetTrace(1); /* Set up tracing for a new session */
  END IF;
 
--
--
--
  s_config_time := SYSTIMESTAMP;
  SELECT name, value
    BULK COLLECT INTO l_names, l_values
    FROM config;
 
--
--
--
  IF l_names.FIRST IS NULL THEN
    sys.dbms_sys_error.raise_system_error(
         E_INTERNAL_ERROR_NUM, 'Config table not initialized');
  END IF;
 
--
--
--
  FOR i IN l_names.FIRST..l_names.LAST LOOP
    CASE l_names(i)
      WHEN '_debug_flags' THEN 
           s_debug_flags := TO_NUMBER(l_values(i));
      WHEN '_debug_error' THEN 
           s_debug_error := TO_NUMBER(l_values(i));
      WHEN '_trace_file_days' THEN 
           s_trace_file_days := TO_NUMBER(l_values(i));
      WHEN '_alloc_increment' THEN 
           s_alloc_increment := TO_NUMBER(l_values(i));
      WHEN '_chunk_cache' THEN 
           s_chunk_cache := TO_NUMBER(l_values(i));
      WHEN '_chunkno_alloc' THEN 
           s_chunkno_alloc := TO_NUMBER(l_values(i));
      WHEN '_purging_reserve' THEN 
           s_purging_reserve := TO_NUMBER(l_values(i));
      WHEN '_purge_wait' THEN 
           s_purge_wait := TO_NUMBER(l_values(i));
      WHEN '_purge_autoshrink' THEN 
           s_purge_autoshrink := TO_NUMBER(l_values(i));
      WHEN '_quiesce_wait' THEN 
           s_quiesce_wait := TO_NUMBER(l_values(i));
      WHEN '_quiesce_session_wait_days' THEN 
           s_quiesce_session_wait := NUMTODSINTERVAL(l_values(i), 'DAY');
      WHEN '_lock_refused_wait' THEN 
           s_lock_refused_wait := TO_NUMBER(l_values(i));
      WHEN '_interrupt_wait' THEN 
           s_interrupt_wait := TO_NUMBER(l_values(i));
      WHEN '_purge_threshold' THEN 
           s_purge_threshold := TO_NUMBER(l_values(i));
      WHEN '_scheduling_wait' THEN 
           s_scheduling_wait := TO_NUMBER(l_values(i));
      WHEN '_session_count' THEN 
           s_session_count := TO_NUMBER(l_values(i));
      WHEN '_timer_loop_sleep_seconds' THEN 
           s_timer_loop_sleep := TO_NUMBER(l_values(i));
      WHEN '_servlet_wait_seconds' THEN 
           s_servlet_wait_seconds := TO_NUMBER(l_values(i));
      WHEN '_db_stats_refresh_days' THEN 
           s_db_stats_refresh_interval := 
                                NUMTODSINTERVAL(l_values(i), 'DAY');
      WHEN '_histogram_slot_days' THEN 
           s_histogram_slot_interval := NUMTODSINTERVAL(l_values(i), 'DAY');
      WHEN '_histogram_cycle_slots' THEN 
           s_histogram_cycle_slots := TO_NUMBER(l_values(i));
      WHEN '_histogram_window_slots' THEN 
           s_histogram_window_slots := TO_NUMBER(l_values(i));
      WHEN '_histogram_goal_percentile' THEN 
           s_histogram_goal_percentile := TO_NUMBER(l_values(i));
      WHEN '_initial_freespace_ratio' THEN 
           s_initial_freespace_ratio := TO_NUMBER(l_values(i));
      WHEN '_min_freespace_ratio' THEN 
           s_min_freespace_ratio := TO_NUMBER(l_values(i));
      WHEN '_task_maintenance_days' THEN 
           s_task_maintenance_interval := NUMTODSINTERVAL(l_values(i),'DAY');
      WHEN '_storage_maintenance_days' THEN 
           s_storage_maintenance_interval := 
                                            NUMTODSINTERVAL(l_values(i),'DAY');
      WHEN '_obsolete_sbt_days' THEN 
           s_obsolete_sbt_interval := NUMTODSINTERVAL(l_values(i), 'DAY');
      WHEN '_polling_timeout_days' THEN 
           s_polling_timeout_interval := NUMTODSINTERVAL(l_values(i), 'DAY');
      WHEN '_polling_del_files_check_days' THEN 
            s_polling_deleted_files_check :=
                                        NUMTODSINTERVAL(l_values(i), 'DAY');
      WHEN '_history_partition_days' THEN 
           s_history_partition_interval := 
                                        NUMTODSINTERVAL(l_values(i), 'DAY');
      WHEN '_history_retention' THEN 
           s_history_retention := TO_NUMBER(l_values(i));
      WHEN '_rm_incomplete_files_days' THEN 
           s_rm_incomplete_files_interval := 
                                        NUMTODSINTERVAL(l_values(i), 'DAY');
      WHEN '_expire_files_days' THEN 
           s_expire_files_interval := NUMTODSINTERVAL(l_values(i), 'DAY');
      WHEN '_max_task_restarts' THEN 
           s_max_task_restarts := TO_NUMBER(l_values(i));
      WHEN '_interrupt_max' THEN 
           s_interrupt_max := TO_NUMBER(l_values(i));
      WHEN '_busy_interrupt_max' THEN 
           s_busy_interrupt_max := TO_NUMBER(l_values(i));
      WHEN '_ordering_wait_timeout_days' THEN 
           s_ordering_wait_timeout :=  TO_NUMBER(l_values(i));
      WHEN '_crosscheck_throttle' THEN 
           s_crosscheck_throttle := TO_NUMBER(l_values(i));
      WHEN '_optimize_space_limit' THEN 
           s_optimize_space_limit := TO_NUMBER(l_values(i));
      WHEN 'percent_late_for_warning' THEN 
           s_late_for_warning := (100 + TO_NUMBER(l_values(i)))/100;
      WHEN '_orphan_file_wait_days' THEN 
            s_orphan_file_wait := NUMTODSINTERVAL(l_values(i), 'DAY');
      WHEN '_restricted_session_count' THEN 
           s_restricted_session_count := TO_NUMBER(l_values(i));
      WHEN '_min_sessions_for_busywork' THEN 
           s_min_sessions_for_busywork := TO_NUMBER(l_values(i));
      WHEN '_reconcile_short_delay_days' THEN 
           s_reconcile_short_interval := NUMTODSINTERVAL(l_values(i), 'DAY');
      WHEN '_reconcile_long_delay_days' THEN 
           s_reconcile_long_interval := NUMTODSINTERVAL(l_values(i), 'DAY');
      WHEN '_trim_factor' THEN 
           s_trim_factor := TO_NUMBER(l_values(i));
      WHEN '_defer_delete' THEN
           IF l_values(i) = 'YES' THEN 
             s_defer_delete := 1;
           ELSE
             s_defer_delete := 0;
           END IF;
      WHEN '_aggressive_delete' THEN
           IF l_values(i) = 'YES' THEN 
             s_aggressive_delete := 1;
           ELSE
             s_aggressive_delete := 0;
           END IF;
      WHEN '_dumper_inhibit_days' THEN 
           s_dumper_inhibit_interval := NUMTODSINTERVAL(l_values(i), 'DAY');
      WHEN '_check_sbtsched_days' THEN 
           s_check_sbtsched_interval := NUMTODSINTERVAL(l_values(i), 'DAY');
      WHEN '_max_sbt_failures' THEN 
           s_max_sbt_failures := TO_NUMBER(l_values(i));
      WHEN '_throttle_sbt_active_hours' THEN 
           s_sbt_active_interval := NUMTODSINTERVAL(l_values(i), 'HOUR');
      WHEN '_resumable_timeout' THEN
--
          s_resumable_timeout := 
                                GREATEST(NVL(TO_NUMBER(l_values(i)), 0), 0);
      WHEN '_resource_wait_timeout_days' THEN 
           s_resource_wait_timeout := TO_NUMBER(l_values(i));
      WHEN '_resource_wait_relax_rate' THEN 
           s_resource_wait_relax_rate := TO_NUMBER(l_values(i));
      WHEN '_busywork_inhibit_time' THEN 
           s_busywork_inhibit_time := NUMTODSINTERVAL(l_values(i), 'DAY');
      WHEN '_part_threshold' THEN
           s_part_threshold := LEAST(TO_NUMBER(l_values(i)), 0.99);
      WHEN '_part_index_style' THEN
           s_part_index_style := TO_NUMBER(l_values(i));
      WHEN '_part_index_size' THEN
           s_part_index_size := TO_NUMBER(l_values(i));
      WHEN '_part_parallel_degree' THEN
           s_part_parallel_degree :=
                                    GREATEST(NVL(TO_NUMBER(l_values(i)), 0), 0);
      WHEN '_stall_when' THEN
           IF UPPER(l_values(i)) = 'ON' THEN 
             s_stall_when := TRUE;
           ELSE
             s_stall_when := FALSE;
           END IF;
      WHEN '_interrupt_when' THEN
           IF l_values(i) = 'ON' THEN 
             s_interrupt_when := TRUE;
           ELSE
             s_interrupt_when := FALSE;
           END IF;
      WHEN '_debug_when' THEN
           s_debug_when := TO_NUMBER(l_values(i));
      WHEN '_purge_opt_free' THEN
           s_purge_opt_free := TO_NUMBER(l_values(i));
      WHEN '_purge_opt_pct' THEN
           s_purge_opt_pct := LEAST(TO_NUMBER(l_values(i)), 0.9);
      WHEN '_fragmentation' THEN
           s_fragmentation := TO_NUMBER(l_values(i));
      WHEN '_plans_maintained' THEN
           s_plans_maintained := TO_NUMBER(l_values(i));
      WHEN '_baseline_cap' THEN 
           s_baseline_cap := TO_NUMBER(l_values(i));
      WHEN '_c2t_optimization' THEN 
           IF l_values(i) = 'ON' THEN 
             s_c2t_optimization := 1;
           ELSE
             s_c2t_optimization := 0;
           END IF;
      WHEN '_alg_over_alloc' THEN
           s_alg_over_alloc := TO_NUMBER(l_values(i));
      WHEN '_ra_pool_freespace_threshold' THEN
           s_ra_pool_freespace_threshold := TO_NUMBER(l_values(i));
      WHEN '_ra_pool_full_free_count' THEN
           s_ra_pool_full_free_count := TO_NUMBER(l_values(i));
      ELSE NULL;
    END CASE;
  END LOOP;
 
--
  s_init_done := TRUE;
 
  IF s_tracing_on THEN
    trace1 ('_debug_flags=' || s_debug_flags);
    trace1 ('_debug_error=' || s_debug_error);
    trace1 ('_trace_file_days=' || s_trace_file_days);
    trace1 ('late_for_warning=' || s_late_for_warning);
    trace1 ('_instance=' || s_instance);
    trace1 ('_alloc_increment=' || s_alloc_increment);
    trace1 ('_chunk_cache=' || s_chunk_cache);
    trace1 ('_chunkno_alloc=' || s_chunkno_alloc);
    trace1 ('_purging_reserve=' || s_purging_reserve);
    trace1 ('_purge_wait=' || s_purge_wait);
    trace1 ('_purge_autoshrink=' || s_purge_autoshrink);
    trace1 ('_quiesce_wait=' || s_quiesce_wait);
    trace1 ('_quiesce_session_wait=' || s_quiesce_session_wait);
    trace1 ('_lock_refused_wait=' || s_lock_refused_wait);
    trace1 ('_interrupt_wait=' || s_interrupt_wait);
    trace1 ('_scheduling_wait=' || s_scheduling_wait);
    trace1 ('_session_count=' || s_session_count);
    trace1 ('_restricted_session_count =' || s_restricted_session_count);
    trace1 ('_min_sessions_for_busywork=' || s_min_sessions_for_busywork);
    trace1 ('_busywork_inhibit_time=' || s_busywork_inhibit_time);
    trace1 ('_timer_loop_sleep_seconds=' || s_timer_loop_sleep);
    trace1 ('_db_stats_refresh_interval=' || s_db_stats_refresh_interval);
    trace1 ('_histogram_slot_days=' || s_histogram_slot_interval);
    trace1 ('_histogram_cycle_slots=' || s_histogram_cycle_slots);
    trace1 ('_histogram_window_slots=' || s_histogram_window_slots);
    trace1 ('_histogram_goal_percentile=' || s_histogram_goal_percentile);
    trace1 ('_initial_freespace_ratio=' || s_initial_freespace_ratio);
    trace1 ('_min_freespace_ratio=' || s_min_freespace_ratio);
    trace1 ('_task_maintenance_days=' || s_task_maintenance_interval);
    trace1 ('_storage_maintenance_days=' || s_storage_maintenance_interval);
    trace1 ('_obsolete_sbt_days=' || s_obsolete_sbt_interval);
    trace1 ('_polling_timeout_days=' || s_polling_timeout_interval);
    trace1 ('_polling_del_files_check_days=' || s_polling_deleted_files_check);
    trace1 ('_history_partition_days=' || s_history_partition_interval);
    trace1 ('_history_retention=' || s_history_retention);
    trace1 ('_rm_incomplete_files_days=' || s_rm_incomplete_files_interval);
    trace1 ('_max_task_restarts=' || s_max_task_restarts);
    trace1 ('_interrupt_max=' || s_interrupt_max);
    trace1 ('_busy_interrupt_max=' || s_busy_interrupt_max);
    trace1 ('_busy_interrupt_max=' || s_busy_interrupt_max);
    trace1 ('_ordering_wait_timeout_days=' || s_ordering_wait_timeout);
    trace1 ('_crosscheck_throttle=' || s_crosscheck_throttle);
    trace1 ('_optimize_space_limit=' || s_optimize_space_limit);
    trace1 ('_expire_files_days=' || s_expire_files_interval);
    trace1 ('_orphan_file_wait_days=' || s_orphan_file_wait);
    trace1 ('_reconcile_short_delay_days=' || s_reconcile_short_interval);
    trace1 ('_reconcile_long_delay_days=' || s_reconcile_long_interval);
    trace1 ('_trim_factor=' || s_trim_factor);
    trace1 ('_defer_delete= ' || s_defer_delete);
    trace1 ('_aggressive_delete=' || s_aggressive_delete);
    trace1 ('_dumper_inhibit_interval=' || s_dumper_inhibit_interval);
    trace1 ('_check_sbtsched_days=' || s_check_sbtsched_interval);
    trace1 ('_max_sbt_failures=' || s_max_sbt_failures);
    trace1 ('_throttle_sbt_active_hours=' || s_sbt_active_interval);
    trace1 ('_resumable_timeout=' || s_resumable_timeout);
    trace1 ('_resource_wait_timeout=' || s_resource_wait_timeout);
    trace1 ('_resource_wait_relax_rate=' || s_resource_wait_relax_rate);
    trace1 ('_purge_opt_free=' || s_purge_opt_free);
    trace1 ('_purge_opt_pct=' || s_purge_opt_pct);
    trace1 ('_fragmentation=' || s_fragmentation);
    trace1 ('_plans_maintained=' || s_plans_maintained);
    trace1 ('_part_threshold=' || s_part_threshold);
    trace1 ('_part_index_style=' || s_part_index_style);
    trace1 ('_part_index_size=' || s_part_index_size);
    trace1 ('_part_parallel_degree=' || s_part_parallel_degree);
    trace1 ('_stall_when=' || print(s_stall_when));
    trace1 ('_interrupt_when=' || print(s_interrupt_when));
    trace1 ('_debug_when=' || print(s_debug_when));
    trace1 ('_c2t_optimization=' || print(s_c2t_optimization));
    trace1 ('_baseline_cap=' || print(s_baseline_cap));
    trace1 ('_alg_over_alloc=' || s_alg_over_alloc);
    trace1 ('_ra_pool_freespace_threshold=' || s_ra_pool_freespace_threshold);
    trace1 ('_ra_pool_full_free_count=' || s_ra_pool_full_free_count);
  END IF;
EXCEPTION
  WHEN OTHERS THEN
    save_error;
    SYS.DBMS_SYSTEM.KSDWRT(SYS.DBMS_SYSTEM.TRACE_FILE, 
                           'LOAD_CONFIG failed with ' || SQLERRM);
    RAISE;
END load_config;
 
 
--
--
--
--
--
--
--
--
--
--
PROCEDURE tracex (message IN VARCHAR2) IS
  l_pos   NUMBER := 1;
  l_hdr   VARCHAR2(100);
BEGIN
--
--
--
  IF NOT s_init_done THEN
    load_config;
    s_init_done := TRUE;
  END IF;
 
--
  IF s_tracing_on
  THEN
    l_hdr := TO_CHAR(SYSTIMESTAMP, 'HH24:MI:SS.FF3') || ' RSJS:';
  ELSE
    l_hdr := 'RSJS:';
  END IF;
 
--
--
--
  LOOP
    sys.kbrsi_icd.rsTrace(l_hdr || SUBSTR(message, l_pos, 1000));
    l_pos := l_pos+1000;
 
    EXIT WHEN l_pos > LENGTH(message);
  END LOOP;
END tracex;
 
--
--
--
--
--
--
--
--
PROCEDURE trace1 (message IN VARCHAR2) IS
  C_LINELEN CONSTANT PLS_INTEGER := 200-18;
  C_NEWLINE CONSTANT CHAR(1) := CHR(10); --linefeed
  l_msglen PLS_INTEGER := LENGTH(message);
  l_nextbuf VARCHAR2(200);
  l_pos PLS_INTEGER := 1;
  l_endpos PLS_INTEGER;
  l_offset PLS_INTEGER;
BEGIN
--
--
--
  IF NOT s_init_done THEN
    load_config;
    s_init_done := TRUE;
  END IF;
 
--
--
--
--
--
--
--
--
  IF s_tracing_on
  THEN
    WHILE l_msglen >= l_pos LOOP
      l_offset := 0;
      l_nextbuf := SUBSTR(message,l_pos,C_LINELEN);
 
      IF INSTR(l_nextbuf, C_NEWLINE) > 0 THEN
        l_endpos := INSTR(l_nextbuf,C_NEWLINE);
        l_offset := -1;
      ELSIF l_msglen + 1 - l_pos <= C_LINELEN THEN
        l_endpos := C_LINELEN;
      ELSIF INSTR(l_nextbuf, ' ', -1) > 0 THEN 
        l_endpos := INSTR(l_nextbuf, ' ', -1);
        l_offset := -1;
      ELSE
        l_endpos := C_LINELEN;
      END IF;
 
      SYS.KBRSI_ICD.RSTRACE('RSJS:' || SUBSTR(l_nextbuf, 1, l_endpos+l_offset));
 
      l_pos := l_pos + l_endpos;
    END LOOP;
  END IF;
END trace1;
 
--
--
PROCEDURE setTracing(p_trc_on IN NUMBER,
                     p_perf_on IN NUMBER DEFAULT 0,
                     p_stall_on IN NUMBER DEFAULT 0,
                     p_safe_mode IN NUMBER DEFAULT 0) IS
BEGIN
  s_tracing_on := (p_trc_on > 0);
  s_perf_on := (p_perf_on > 0);
  s_safe_mode := (p_safe_mode > 0);
END setTracing;
 
--
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE stop_scheduler_jobs (p_stop_jobs IN NUMBER,
                               p_instance_only IN BOOLEAN,
                               p_db_key IN NUMBER DEFAULT NULL) IS
 
--
  TYPE sched_jobs_record_t IS RECORD
  (
     job_name          DBMS_ID,
     ord               NUMBER,
     instance_id       NUMBER,
     current_task      NUMBER,
     current_task_type NUMBER
  );
 
--
  TYPE sched_jobs_cursor_t IS REF CURSOR RETURN sched_jobs_record_t;
 
  l_instance    NUMBER := NULL;
  l_all_gone    BOOLEAN;
  l_jobs_cursor sched_jobs_cursor_t;
  l_jobs_rec    sched_jobs_record_t;
  l_timers_gone BOOLEAN;
  l_debug_flags NUMBER;
  KBRSTRC_STALL CONSTANT NUMBER := TO_NUMBER('02000000','XXXXXXXX');
  l_stall_on_error BOOLEAN;
 
BEGIN
 
--
  IF p_stop_jobs = STOP_JOBS_ALL THEN
    NULL;
  ELSIF p_stop_jobs = STOP_JOBS_DB THEN
    IF p_db_key IS NULL THEN
      sys.dbms_sys_error.raise_system_error(E_INTERNAL_ERROR_NUM,
                          'STOP_SCHEDULER_JOBS: STOP_JOBS_DB: NULL p_db_key');
    END IF;
    IF p_instance_only THEN
      sys.dbms_sys_error.raise_system_error(E_INTERNAL_ERROR_NUM,
                'STOP_SCHEDULER_JOBS: STOP_JOBS_DB: p_instance_only is TRUE');
    END IF;
  ELSE
    sys.dbms_sys_error.raise_system_error(E_INTERNAL_ERROR_NUM,
                                  'STOP_SCHEDULER_JOBS: invalid p_stop_jobs');
  END IF;
 
  IF p_instance_only THEN
--
--
--
    l_instance := s_instance;
  END IF;
 
--
--
--
--
--
  FOR i in 1..600 LOOP
 
--
--
--
 
    trace1 ('STOP_SCHEDULER_JOBS: Loop ' || i);
    l_all_gone := TRUE;
    l_timers_gone := FALSE;
 
    BEGIN
--
      SELECT NVL(MAX(TO_NUMBER(value)), 0) INTO l_debug_flags
        FROM config
       WHERE name = '_debug_flags';
 
--
      l_stall_on_error :=  (BITAND(l_debug_flags, KBRSTRC_STALL) <> 0);
 
      make_amjobs;
 
--
      IF p_stop_jobs = STOP_JOBS_ALL THEN
--
        OPEN l_jobs_cursor FOR 
--
--
--
          SELECT job_name, ord, instance_id, current_task, current_task_type
            FROM (SELECT job_name, 
                         DECODE(SUBSTR(job_name,1,9), 'RA$_TIMER', 1, 
                                   NVL2(current_task,2,3)) ord,
                         amjobs.instance_id,
                         current_task,
                         current_task_type
                    FROM TABLE(CAST(s_amjobs AS rai_jobs_table_type)) amjobs
                    LEFT OUTER JOIN sessions USING (job_name)
                    WHERE job_name LIKE 'RA$%'
                      AND job_name NOT LIKE 'RA$TRIG%'
                      AND amjobs.instance_id =
                            NVL(l_instance,amjobs.instance_id))
            ORDER BY ord;
      ELSE
--
        OPEN l_jobs_cursor FOR 
          SELECT j.job_name, 2, j.instance_id,
                 s.current_task, s.current_task_type
            FROM TABLE(CAST(dbms_ra_scheduler.s_amjobs AS rai_jobs_table_type)) j,
                 sessions s, task t
            WHERE j.job_name = s.job_name
              AND j.instance_id = s.instance_id
              AND s.ba_session_id = t.ba_session_id
              AND t.db_key = p_db_key
              AND delete_db_task_is_benign(t.task_type) = DB_TASK_IS_NOT_BENIGN;
      END IF;
 
--
      LOOP
        FETCH l_jobs_cursor INTO l_jobs_rec;
        EXIT WHEN l_jobs_cursor%NOTFOUND;
 
        IF p_stop_jobs = STOP_JOBS_ALL AND NOT l_timers_gone AND
           l_jobs_rec.ord > 1 THEN
--
--
--
          IF NOT l_stall_on_error THEN 
            SYS.KBRSI_ICD.RSRUNSCHED;
          END IF;
 
          l_timers_gone := TRUE;
        END IF;
 
        BEGIN
          trace1 ('STOP_SCHEDULER_JOBS: Killing ' || l_jobs_rec.job_name ||
                  ' on instance ' || l_jobs_rec.instance_id);
          DBMS_SCHEDULER.STOP_JOB(job_name => l_jobs_rec.job_name,
                                  force => TRUE);
        EXCEPTION
          WHEN OTHERS THEN
            save_error;
--
--
--
--
            trace1 ('STOP_SCHEDULER_JOBS: Error seen is ' || SQLERRM);
            SYS.KBRSI_ICD.RSCLEARERR;
            l_all_gone := FALSE;
 
--
--
--
--
            IF (i >= 10) AND (l_jobs_rec.ord > 1) THEN
              log_error (p_errno  => E_COULDNT_STOP_JOB_NUM,
                         p_param1 => l_jobs_rec.job_name,
                         p_param2 => print(l_jobs_rec.current_task),
                         p_param3 =>
                           tasktype2name(l_jobs_rec.current_task_type),
                         p_param4 => i,
                         p_keep_stack => TRUE,
                         p_component => 'SHUTDOWN',
                         p_severity => SEVERITY_WARNING,
                         p_param_char => l_jobs_rec.job_name);
            END IF;
 
            clear_error;
            CONTINUE;
        END;
      END LOOP;
    EXCEPTION
      WHEN E_ROW_CACHE_LOCK THEN
        save_error;
        trace1 ('STOP_SCHEDULER_JOBS: Row cache lock problem');
        DBMS_LOCK.SLEEP(6);
        l_all_gone := FALSE;
        clear_error;
        CONTINUE;
      WHEN E_PQ_FAILURE THEN
         save_error;
         trace1 ('STOP_SCHEDULER_JOBS: E_PQ_FAILURE');
         l_all_gone := FALSE;
         clear_error;
         CONTINUE;        
    END;
 
--
    IF l_all_gone THEN
      EXIT;
    END IF;
 
    DBMS_LOCK.SLEEP(1);
  END LOOP;
END stop_scheduler_jobs;
 
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE stop (p_instance_only IN BOOLEAN DEFAULT FALSE,
                p_quiesce_first IN BOOLEAN DEFAULT FALSE) IS
 
l_instance          NUMBER := NULL;
l_schema            all_tables.owner%TYPE;
l_ddl               VARCHAR2(200);
l_all_gone          BOOLEAN;
l_need_unquiesce    BOOLEAN := FALSE;
 
BEGIN
--
--
 
  sys.kbrsi_icd.rsSetTrace;
  trace1 ('STOP: p_instance_only=' || print(p_instance_only) ||
              ', p_quiesce_first=' || print(p_quiesce_first));
  trace1 ('STOP: For schema ' || SYS_CONTEXT('USERENV', 'SESSION_USER'));
 
--
--
--
  l_schema := SYS_CONTEXT('USERENV', 'SESSION_USER');
 
  IF l_schema = 'SYS' THEN
--
--
--
    l_schema := SYS.rai_schema;
    l_ddl := 'ALTER SESSION SET CURRENT_SCHEMA =' || l_schema;
    EXECUTE IMMEDIATE l_ddl;
    trace1 ('STOP: Schema set to ' || l_schema);
 
  END IF;  
 
  IF NOT p_instance_only THEN
    IF p_quiesce_first THEN 
--
--
--
      DBMS_RA_INT.LOCK_API_INT(DBMS_RA.LOCKAPI_DELETE, 'stop recovery appliance');
 
--
--
--
--
      l_need_unquiesce := TRUE;   
      quiesce_rs ();
    END IF;
 
--
--
--
    trace1 ('STOP: Turn off recovery appliance state');
    UPDATE config 
      SET value = 'OFF'
      WHERE (name = '_recovery_appliance_state');
    COMMIT; 
  END IF;
 
--
--
--
  stop_scheduler_jobs (STOP_JOBS_ALL, p_instance_only);
 
--
--
--
  IF l_need_unquiesce THEN
    unquiesce_rs;
    l_need_unquiesce := FALSE;
  END IF;
 
 
--
--
--
  fix_error(p_error_num => E_SHUTTING_DOWN_NUM);
  COMMIT;
 
--
--
--
  IF p_quiesce_first THEN
    DBMS_RA_INT.UNLOCK_API_INT (p_the_num=>0,
                                p_results=>FALSE, p_docommit=>FALSE);
  END IF;
 
EXCEPTION
  WHEN e_bad_user THEN 
    save_error;
    RAISE;
 
  WHEN OTHERS THEN
    save_error;
 
    IF l_need_unquiesce THEN
      unquiesce_rs;
    END IF;
 
--
--
--
    IF p_quiesce_first THEN
      DBMS_RA_INT.UNLOCK_API_INT (p_the_num=>0,
                                  p_results=>FALSE, p_docommit=>FALSE);
    END IF;
 
    trace1 ('STOP: Exception for ' || SQLERRM);
 
--
--
--
    log_error(p_errno     => E_INTERNAL_ERROR_NUM,
              p_param1    => 'failure during shutdown or abort',
              p_component => 'SHUTDOWN',
              p_severity  => SEVERITY_INTERNAL); 
 
    RAISE;
 
END stop;
 
--
--
--
--
FUNCTION queue_one_sbt_backup_task(
                                   p_db_key IN NUMBER,
                                   p_bs_key IN NUMBER,
                                   p_piece_no IN NUMBER,
                                   p_template_key IN NUMBER,
                                   p_full_template_key IN NUMBER,
                                   p_attr_set_key IN NUMBER,
                                   p_lib_key IN NUMBER,
                                   p_copies IN NUMBER,
                                   p_src_bpkey IN NUMBER DEFAULT NULL,
                                   p_delete_source IN VARCHAR2 DEFAULT 'N',
                                   p_format IN VARCHAR2 DEFAULT NULL,
                                   p_rep_server_key IN NUMBER DEFAULT NULL
                                  ) RETURN BOOLEAN IS
  new_task_rec      task%ROWTYPE;
  l_spawn_job       BOOLEAN;
  l_count           NUMBER;
  l_rep_srvr_status rep_server.status%TYPE;
BEGIN
    
--
  new_task_rec.task_type  := TASK_BACKUP_SBT;
  new_task_rec.flags      := 0;
  new_task_rec.db_key     := p_db_key;
  new_task_rec.param_num1 := p_bs_key;
  new_task_rec.param_num2 := p_template_key;
  new_task (task_rec => new_task_rec, p_commit => FALSE, p_sbt_task => TRUE);
  
  trace1('QUEUE_ONE_SBT_BACKUP_TASK - add task: ' ||
         ' p_db_key=' || p_db_key ||
         ', p_bs_key=' || p_bs_key ||
         ', p_piece_no=' || p_piece_no ||
         ', p_src_bp_key=' || p_src_bpkey ||
         ', p_template_key=' || p_template_key ||
         ', p_attr_set_key=' || p_attr_set_key ||
         ', p_lib_key=' || p_lib_key ||
         ', p_copies=' || p_copies ||
         ', p_delete_source=' || p_delete_source ||
         ', p_format=' || p_format ||
         ', p_rep_server_key=' || p_rep_server_key ||
         ', new_task_rec.task_id=' || new_task_rec.task_id);
 
  INSERT INTO sbt_task
    (task_id, bs_key, piece#, rep_server_key,
     template_key, full_template_key, attr_key, lib_key, copies,
     failure_cnt, restore, src_bpkey, delete_source, format)
    VALUES
    (new_task_rec.task_id, p_bs_key, p_piece_no, p_rep_server_key,
     p_template_key, p_full_template_key, p_attr_set_key, p_lib_key,
     p_copies, 0, 'N', p_src_bpkey, p_delete_source, p_format);
  
--
  COMMIT;
 
--
  l_spawn_job := TRUE;
 
--
--
  new_task_rec            := NULL;
  new_task_rec.task_type  := TASK_PLAN_SBT;
  new_task_rec.flags      := 0;
  new_task_rec.db_key     := p_db_key;
  new_task_rec.param      := p_bs_key;
 
--
--
--
--
  SELECT MAX(dbms_ra_pool.incrLevel(d.create_scn, d.incr_scn)) + COUNT(*)
    INTO l_count
    FROM bdf d
    WHERE bs_key = p_bs_key;
 
--
  IF l_count = 1 THEN
    new_task_rec.param_num3  := dbms_ra_pool.KBRSPLBLD_PIECE;
  ELSE
    new_task_rec.param_num3  := dbms_ra_pool.KBRSPLBLD_ORIGPIECE;
  END IF;
 
--
--
  FOR i IN (SELECT df_key, vb_key
            FROM bp JOIN bdf USING (bs_key)
                    JOIN df  USING (dbinc_key, create_scn, file#)
            WHERE bs_key = p_bs_key
              AND piece# = p_piece_no
              AND status != 'D'
              AND vb_key IS NOT NULL)
  LOOP
    new_task_rec.param_num1 := i.df_key;
    new_task_rec.param_num2 := i.vb_key;
    new_task (task_rec => new_task_rec, p_commit => FALSE);
  END LOOP;
 
  COMMIT;
 
--
--
--
  SYS.KBRSI_ICD.RSRUNSCHED;
  
  trace1('QUEUE_ONE_SBT_BACKUP_TASK: completed');
  
  RETURN l_spawn_job;
 
EXCEPTION
  WHEN DUP_VAL_ON_INDEX THEN
    ROLLBACK;
    save_error;
--
--
    IF (SQLERRM NOT LIKE '%SBT_TASK_U1%') THEN
      trace1 ('QUEUE_ONE_SBT_BACKUP_TASK: dup_val error - '  || SQLERRM);
      RAISE;
    END IF;
    trace1 ('QUEUE_ONE_SBT_BACKUP_TASK: Skipping existing sbt_task');
    clear_error;
    RETURN FALSE;
 
  WHEN OTHERS THEN
    save_error;
    trace1 ('QUEUE_ONE_SBT_BACKUP_TASK: error - '  || SQLERRM);
    RAISE;
  
END queue_one_sbt_backup_task;
  
 
--
--
--
--
PROCEDURE queue_sbt_backup_task(template_name IN VARCHAR2,
                                src_bpkey IN NUMBER DEFAULT NULL,
                                delete_source IN VARCHAR2 DEFAULT 'N',
                                format IN VARCHAR2 DEFAULT NULL) IS
 
--
  CURSOR odb_cursor(template_key IN NUMBER) IS
    SELECT odb.db_key, job.bck_type, job.full_template_key
      FROM odb, sbt_job_template job
     WHERE odb.prot_key = nvl(job.prot_key, odb.prot_key)
       AND odb.db_key   = nvl(job.db_key, odb.db_key)
       AND job.template_key = odb_cursor.template_key
  ORDER BY 1;
 
  l_last_bp_key         NUMBER;
  l_max_bp_key          NUMBER;
  l_locked              BOOLEAN := FALSE;
  l_spawn_job           BOOLEAN := FALSE;
  l_db_key              NUMBER;
  l_bck_type            NUMBER;
  l_template_key        NUMBER;
  l_full_template_key   NUMBER;
  l_full_attr_key       NUMBER;
  l_full_lib_key        NUMBER;
  l_attr_key            NUMBER;
  l_lib_key             NUMBER;
  l_bs_key              NUMBER;
  l_piece_no            NUMBER;
  l_copies              NUMBER;
  job_exists            NUMBER;
  l_lib_status          sbt_lib_desc.status%TYPE;
  l_sbt_task            NUMBER;
  l_dbid                NUMBER;
  l_currinc             NUMBER;
  l_db_slkey            NUMBER;
  l_is_dest_repserver   NUMBER;
  l_baseline_scn        NUMBER;
  l_init_cf_bs_key      NUMBER;
  l_all_bck_type        BOOLEAN := FALSE;
  l_from_tag            sbt_job_template.from_tag%TYPE;
  l_prot_key            sbt_job_template.prot_key%TYPE;
  l_server_key          NUMBER;
  l_rep_srvr_status     rep_server.status%TYPE;
  l_rep_bp_cnt          NUMBER;
BEGIN
  trace1 ('QUEUE_SBT_BACKUP_TASK: ' || template_name  ||
                                                  '; src_bpkey=' || src_bpkey);
 
--
  SELECT job.template_key, job.attr_key, job.copies, attr.lib_key, 
         lib.status, job.from_tag, job.prot_key
    INTO l_template_key, l_attr_key, l_copies, l_lib_key, 
         l_lib_status, l_from_tag, l_prot_key
    FROM sbt_job_template job, sbt_attr_set attr, sbt_lib_desc lib
   WHERE job.template_name  = queue_sbt_backup_task.template_name
     AND job.attr_key  = attr.attr_key
     AND attr.lib_key  = lib.lib_key;
  
  trace1 ('QUEUE_SBT_BACKUP_TASK: l_attr_key=' || l_attr_key ||
          ',l_template_key=' || l_template_key ||
          ',l_lib_key=' || l_lib_key);
--
--
--
--
--
--
--
--
  IF src_bpkey IS NULL THEN
 
--
--
    IF (NOT dbms_ra_int.write_lock_wait(DBMS_RA_INT.KEY_SY, l_lib_key)) THEN
       RAISE no_data_found;
    END IF;
 
    l_locked := TRUE;
 
--
    OPEN odb_cursor(l_template_key);
    LOOP
      <<get_next_db>>
      FETCH odb_cursor INTO l_db_key, l_bck_type, l_full_template_key;
      EXIT WHEN odb_cursor%NOTFOUND;
 
--
      IF l_full_template_key IS NOT NULL THEN
         SELECT job.attr_key, attr.lib_key
           INTO l_full_attr_key, l_full_lib_key
           FROM sbt_job_template job, sbt_attr_set attr, sbt_lib_desc lib
          WHERE job.template_key = l_full_template_key
            AND job.attr_key  = attr.attr_key
            AND attr.lib_key  = lib.lib_key;
         trace1 ('QUEUE_SBT_BACKUP_TASK: ' ||
                 'l_full_attr_key=' || l_full_attr_key ||
                 ',l_full_template_key=' || l_full_template_key ||
                 ',l_full_lib_key=' || l_full_lib_key);
      END IF;
 
      l_all_bck_type := (bitand(l_bck_type, 1) = 1);
      SELECT curr_dbinc_key INTO l_currinc FROM DB WHERE db_key = l_db_key;
 
--
--
--
      SELECT nvl(max(baseline_scn), 0) INTO l_baseline_scn
        FROM sbt_template_db
       WHERE db_key = l_db_key 
         AND template_key = l_full_template_key;
 
      SELECT nvl(max(last_bp_key), 0) INTO l_last_bp_key  
        FROM sbt_template_db
       WHERE db_key = l_db_key 
         AND template_key = l_template_key;
 
--
--
      IF s_c2t_optimization = 0 THEN
        l_last_bp_key := 0;
        l_baseline_scn := 0;
      END IF;
 
--
      BEGIN
        SELECT rs.server_key, rs.status
          INTO l_server_key , l_rep_srvr_status
          FROM odb o, rep_server rs, sbt_job_template j, sbt_lib_desc l,
                 sbt_attr_set a
         WHERE o.db_key=l_db_key
           AND j.template_key=l_template_key
           AND l.lib_key=l_lib_key
           AND a.attr_key=l_attr_key
           AND l.lib_key=a.lib_key
           AND a.attr_key=j.attr_key
           AND o.prot_key=rs.prot_key
           AND rs.server_key=l.server_key;
       IF l_rep_srvr_status != 'A' THEN
         trace1('QUEUE_SBT_BACKUP_TASK: not active rep server');
         RETURN;
       END IF;
 
       SELECT COUNT(*) INTO l_rep_bp_cnt
         FROM bp
        WHERE bp.db_key = l_db_key
          AND bp.vb_key IS NOT NULL
          AND bp.status = 'A'
          AND ROWNUM = 1;
 
--
       IF l_rep_bp_cnt = 0 THEN
         trace1('QUEUE_SBT_BACKUP_TASK: no DB backup for replication ' ||
                ' l_db_key=' || l_db_key ||
                ' l_template_key=' || l_template_key);
 
         CONTINUE;
       END IF;
 
      EXCEPTION
        WHEN NO_DATA_FOUND THEN
          l_server_key  := NULL;
      END;
 
      trace1('QUEUE_SBT_BACKUP_TASK: is server_key= ' || l_server_key );
--
--
      SELECT NVL(MAX(bp_key), 0) INTO l_max_bp_key FROM bp;
     
--
--
--
--
 
      IF (l_all_bck_type OR (bitand(l_bck_type, 2) = 2)) THEN
--
--
--
         trace1('QUEUE_SBT_BACKUP_TASK: validate base level backup');
         inValidateBaseLevelBcks (l_db_key, l_currinc, l_template_key,
                                  l_baseline_scn);
 
         trace1('QUEUE_SBT_BACKUP_TASK: queue level 0 full backups');
         queueBaseLevelBcks(p_db_key        => l_db_key,
                            p_dbid          => l_dbid,
                            p_currinc       => l_currinc,
                            p_db_slkey      => l_db_slkey,
                            p_from_tag      => l_from_tag,
                            p_template_key  => l_template_key,
                            p_baseline_scn  => l_baseline_scn,
                            p_lib_key       => l_lib_key,
                            p_attr_key      => l_attr_key,
                            p_copies        => l_copies,
                            p_delete_source => delete_source,
                            p_format        => format,
                            p_last_bp_key   => l_last_bp_key,
                            p_max_bp_key    => l_max_bp_key,
                            p_server_key    => l_server_key );
 
         logMissingDfBcksError(p_db_key       => l_db_key,
                               p_currinc      => l_currinc,
                               p_template_key => l_template_key);
      END IF;
 
--
--
      IF l_baseline_scn = 0 and 
         ((bitand(l_bck_type, 4) = 4) or (bitand(l_bck_type, 8) = 8)) THEN
         trace1 ('QUEUE_SBT_BACKUP_TASK initial base full backup not sent');
      END IF;
 
      IF l_baseline_scn > 0 THEN
         SELECT COUNT(*) INTO l_init_cf_bs_key FROM sbt_template_df
            WHERE template_key = l_template_key
              AND db_key       = l_db_key
              AND df_file#    <= 0
              AND bs_key       IS NULL;
      END IF;
 
--
      IF ((l_baseline_scn > 0) AND
          (l_all_bck_type OR (bitand(l_bck_type, 4) = 4))) THEN
         IF (NOT l_all_bck_type) THEN
            trace1('QUEUE_SBT_BACKUP_TASK: queue level 0 missing DF backups');
            queueMissingDFBcks(p_db_key         => l_db_key,
                               p_from_tag       => l_from_tag,
                               p_template_key   => l_full_template_key,
                               p_baseline_scn   => l_baseline_scn,
                               p_lib_key        => l_full_lib_key,
                               p_attr_key       => l_full_attr_key,
                               p_copies         => l_copies,
                               p_delete_source  => delete_source,
                               p_format         => format,
                               p_last_bp_key    => l_last_bp_key,
                               p_server_key     => l_server_key );
            logMissingDfBcksError(p_db_key       => l_db_key,
                                  p_currinc      => l_currinc,
                                  p_template_key => l_full_template_key);
         END IF;
 
         trace1('QUEUE_SBT_BACKUP_TASK: queue incremental backups');
         queueIncrementalBcks(p_db_key            => l_db_key,
                              p_from_tag          => l_from_tag,
                              p_template_key      => l_template_key,
                              p_full_template_key => l_full_template_key,
                              p_baseline_scn      => l_baseline_scn,
                              p_lib_key           => l_lib_key,
                              p_attr_key          => l_attr_key,
                              p_copies            => l_copies,
                              p_delete_source     => delete_source,
                              p_format            => format,
                              p_init_cf_bs_key    => l_init_cf_bs_key,
                              p_last_bp_key       => l_last_bp_key,
                              p_server_key        => l_server_key );
      END IF;
 
--
      IF ((l_baseline_scn > 0) AND
          (l_all_bck_type OR (bitand(l_bck_type, 8) = 8))) THEN
         trace1('QUEUE_SBT_BACKUP_TASK: queue archived log backups');
         queueArchivedLogBcks(p_db_key            => l_db_key,
                              p_from_tag          => l_from_tag,
                              p_template_key      => l_template_key,
                              p_full_template_key => l_full_template_key,
                              p_baseline_scn      => l_baseline_scn,
                              p_lib_key           => l_lib_key,
                              p_attr_key          => l_attr_key,
                              p_copies            => l_copies,
                              p_delete_source     => delete_source,
                              p_format            => format,
                              p_init_cf_bs_key    => l_init_cf_bs_key,
                              p_last_bp_key       => l_last_bp_key,
                              p_server_key        => l_server_key );
 
      END IF;
 
--
      IF ((l_baseline_scn > 0) AND (l_server_key  > 0))  THEN
         trace1('QUEUE_SBT_BACKUP_TASK: queue keep backups');
         queueKeepBcks(p_db_key         => l_db_key,
                       p_from_tag       => l_from_tag,
                       p_template_key   => l_template_key,
                       p_baseline_scn   => l_baseline_scn,
                       p_lib_key        => l_lib_key,
                       p_attr_key       => l_attr_key,
                       p_copies         => l_copies,
                       p_delete_source  => delete_source,
                       p_format         => format,
                       p_last_bp_key    => l_last_bp_key,
                       p_server_key     => l_server_key );
      END IF;
 
--
      IF (l_baseline_scn > 0 AND s_c2t_optimization = 1) THEN
        BEGIN 
          INSERT INTO sbt_template_db
            (db_key, template_key, baseline_scn, last_bp_key, curr_dbinc_key)
            VALUES
            (l_db_key, l_template_key, l_baseline_scn, l_max_bp_key, l_currinc);
          trace1('QUEUE_SBT_BACKUP_TASK row inserted to sbt_template_db' ||
                 ' l_db_key=' || l_db_key || 
                 ' l_template_key=' || l_template_key);
        EXCEPTION
          WHEN dup_val_on_index THEN
             save_error;
--
             UPDATE sbt_template_db
                 SET last_bp_key   = l_max_bp_key  
               WHERE template_key = l_template_key
                 AND db_key = l_db_key
                 AND last_bp_key < l_max_bp_key;
             trace1('QUEUE_SBT_BACKUP_TASK: updated sbt_template_db' ||
                    ' l_template_key=' || l_template_key ||
                    ' l_db_key=' || l_db_key ||
                    ' l_max_bp_key=' || l_max_bp_key ||
                    ' rows updated=' || SQL%ROWCOUNT);
             clear_error;
        END;
        COMMIT;
      END IF;
    END LOOP;
    CLOSE odb_cursor;
 
 
--
    dbms_ra_int.unlock(DBMS_RA_INT.KEY_SY, l_lib_key);
    l_locked := FALSE;
 
  ELSE
--
--
--
    SELECT full_template_key
      INTO l_full_template_key
      FROM  sbt_job_template
      WHERE template_key=l_template_key;
    SELECT bs_key, piece#, db_key
      INTO l_bs_key, l_piece_no, l_db_key
      FROM bp
      WHERE bp_key=src_bpkey;
 
    l_spawn_job := queue_one_sbt_backup_task(
                                   p_db_key => l_db_key,
                                   p_bs_key => l_bs_key,
                                   p_piece_no => l_piece_no,
                                   p_template_key => l_template_key,
                                   p_full_template_key => l_full_template_key,
                                   p_attr_set_key => l_attr_key,
                                   p_lib_key => l_lib_key,
                                   p_copies => l_copies,
                                   p_src_bpkey => src_bpkey,
                                   p_delete_source => delete_source,
                                   p_format => format
                                  );
  END IF;
 
  UPDATE sbt_job_template job
    SET job.schedule_time   = SYSTIMESTAMP,
        job.completion_time =
        nvl2(job.window, job.window + SYSTIMESTAMP, null)
   WHERE job.template_key = l_template_key;
 
  COMMIT;
 
  IF (NOT l_spawn_job) THEN
     trace1 ('QUEUE_SBT_BACKUP_TASK complete with no job');
 
--
     SELECT count(*) INTO l_sbt_task FROM sbt_task t
      WHERE t.restore = 'N'
        AND t.template_key = l_template_key
        AND ROWNUM = 1;
 
     IF (l_sbt_task = 0) THEN
        trace1 ('QUEUE_SBT_BACKUP_TASK no sbt_task queued');
        RETURN;
     END IF;
  END IF;
 
  IF (l_lib_status != 'R') THEN
     trace1 ('QUEUE_SBT_BACKUP_TASK complete as library is not ready');
     RETURN;
  END IF;
 
  queue_spawn_sbt(p_libkey => l_lib_key, p_forpurge => FALSE);
 
  trace1 ('QUEUE_SBT_BACKUP_TASK complete');
EXCEPTION
  WHEN no_data_found THEN
     save_error;
     trace1 ('QUEUE_SBT_BACKUP_TASK handling no_data_found');
--
     IF (l_locked) THEN
        dbms_ra_int.unlock(DBMS_RA_INT.KEY_SY, l_lib_key);
     END IF;
 
--
     SELECT count(*) INTO job_exists
       FROM sbt_job_template job
      WHERE job.template_name = queue_sbt_backup_task.template_name;
 
--
     IF (job_exists = 0) THEN
        SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(
           E_SBT_JOB_NOTFOUND_NUM, template_name);
     ELSE
        RAISE;
     END IF;
 
  WHEN OTHERS THEN
     save_error;
--
     IF (l_locked) THEN
        dbms_ra_int.unlock(DBMS_RA_INT.KEY_SY, l_lib_key);
     END IF;
     RAISE;
END queue_sbt_backup_task;
 
 
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
FUNCTION reconcile_it (p_db_key          IN NUMBER,
                       p_lib_key         IN NUMBER,
                       p_server_key      IN NUMBER,
                       p_force_reconcile IN BOOLEAN DEFAULT FALSE)
                       RETURN BOOLEAN
IS
  l_status      sbt_lib_desc.status%TYPE;
  l_cnt         NUMBER;
  l_err_cnt     NUMBER := 0;
 
  DB_INC_NOT_CURRENT EXCEPTION;
  DB_INC_NOT_FOUND EXCEPTION;
  PRAGMA EXCEPTION_INIT(DB_INC_NOT_CURRENT, -20011);
  PRAGMA EXCEPTION_INIT(DB_INC_NOT_FOUND, -20003);
BEGIN
  trace1 ('RECONCILE_IT: replication cursor ' ||
          ' p_db_key=' || p_db_key ||
          ', p_lib_key=' || p_lib_key ||
          ', p_server_key=' || p_server_key);
 
  SELECT count(*) INTO l_cnt
    FROM sbt_lib_desc
    WHERE lib_key = p_lib_key;
  IF l_cnt = 0 THEN
--
    trace1 ('RECONCILE_IT: Replication Server Library no longer exists (' ||
            p_lib_key || ') - returning ');
    RETURN FALSE;
  END IF;
 
--
--
--
--
  IF NOT DBMS_RA_INT.READ_LOCK(DBMS_RA_INT.KEY_SY, p_lib_key) THEN
    trace1 ('RECONCILE_IT: Replication Server Library (' ||
            p_lib_key || ') - returning - unable to get lock');
    RETURN FALSE;
  END IF;
 
  SELECT status INTO l_status
    FROM sbt_lib_desc
   WHERE lib_key = p_lib_key;
 
  IF NOT p_force_reconcile AND (l_status = 'P') THEN
--
--
--
    DBMS_RA_INT.UNLOCK(DBMS_RA_INT.KEY_SY, p_lib_key);
    trace1 ('RECONCILE_IT: User paused lib_key=' || p_lib_key);
    RETURN FALSE;
  END IF;
 
  IF NOT p_force_reconcile AND (l_status = 'E') THEN
--
--
--
    DBMS_RA_INT.UNLOCK(DBMS_RA_INT.KEY_SY, p_lib_key);
    trace1 ('RECONCILE_IT: Library is in "E"rror condition lib_key=' ||
            p_lib_key);
    RETURN FALSE;
  END IF;
 
  BEGIN
    dbms_rcvcat.doReplicationReconcile(p_db_key        => p_db_key,
                                       p_lib_key       => p_lib_key,
                                       p_server_key    => p_server_key);
 
--
--
    UPDATE sbt_lib_desc
      SET status = (CASE WHEN status = 'E' THEN 'R'
                       ELSE status END),
          failure_cnt = 0
      WHERE lib_key = p_lib_key;
 
--
    fix_error (p_error_num  => E_REPLICATION_ERROR_NUM,
               p_db_key     => p_db_key,
               p_param_num  => p_lib_key);
 
--
   COMMIT;
  EXCEPTION
--
--
    WHEN DB_INC_NOT_CURRENT OR DB_INC_NOT_FOUND THEN
      save_error;
 
--
--
--
      sys.kbrsi_icd.rsClearErr;
      clear_error;
--
 
    WHEN OTHERS THEN
      l_err_cnt := l_err_cnt + 1;
      save_error;
--
--
      log_sbt_error(p_db_key, p_lib_key, 0, FALSE);
 
      sys.kbrsi_icd.rsClearErr;
      clear_error;
--
  END;
 
--
--
--
  DBMS_RA_INT.UNLOCK(DBMS_RA_INT.KEY_SY, p_lib_key);
  RETURN (l_err_cnt = 0);
 
EXCEPTION
  WHEN OTHERS THEN
    save_error;
    DBMS_RA_INT.UNLOCK(DBMS_RA_INT.KEY_SY, p_lib_key);
    RAISE;
END reconcile_it;
 
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
FUNCTION reconcile_db (p_db_key          IN NUMBER,
                       p_server_key      IN NUMBER DEFAULT NULL,
                       p_only_active     IN BOOLEAN DEFAULT TRUE,
                       p_force_reconcile IN BOOLEAN DEFAULT FALSE,
                       rec_cnt           OUT NUMBER
                      ) RETURN BOOLEAN
IS
  CURSOR rep_server_cursor (in_db_key IN NUMBER) IS
    SELECT l.lib_key, rs.server_key, rs.status
      FROM odb o, rep_server rs, sbt_lib_desc l
      WHERE o.db_key=in_db_key
        AND o.prot_key=rs.prot_key
        AND rs.server_key=l.server_key;
 
    l_lib_key           NUMBER;
    l_template_key      NUMBER;
    l_server_key        NUMBER;
    l_rep_srvr_status   rep_server.status%TYPE;
    l_suc_cnt           NUMBER := 0;
    l_err_cnt           NUMBER := 0;
    l_cnt               NUMBER := 0;
    l_rv                BOOLEAN;
    l_rec_time          timestamp;
BEGIN
  trace1 ('RECONCILE_DB p_db_key=' || p_db_key ||
          ', p_server_key=' || p_server_key ||
          ', p_only_active=' || print(p_only_active));
 
  l_suc_cnt := 0;
  l_err_cnt := 0;
  rec_cnt := 0;
  IF p_db_key IS NULL THEN
    trace1 ('RECONCILE_DB: required db_key missing.');
    RETURN FALSE;
  END IF;
 
  IF p_server_key IS NOT NULL THEN
    BEGIN
      SELECT l.lib_key, r.status
        INTO l_lib_key, l_rep_srvr_status
        FROM odb o, sbt_lib_desc l, rep_server r
        WHERE o.db_key=p_db_key
          AND l.server_key = p_server_key
          AND l.server_key = r.server_key
           AND o.prot_key=r.prot_key;
    EXCEPTION
      WHEN no_data_found THEN 
        save_error;
        trace1('RECONCILE_DB: Replication Server not available.');
        clear_error;
--
--
        RETURN TRUE;
    END;
 
    IF l_rep_srvr_status != 'A' THEN
      IF p_only_active THEN
        trace1 ('RECONCILE_DB1: skipping inactive replication server. ' ||
                'server_key=' || p_server_key || ', rep_srvr_status=' ||
                l_rep_srvr_status);
        RETURN TRUE;
      END IF;
    END IF;
 
--
--
    l_rv := reconcile_it (p_db_key        => reconcile_db.p_db_key,
                          p_lib_key       => l_lib_key,
                          p_server_key    => reconcile_db.p_server_key,
                          p_force_reconcile => reconcile_db.p_force_reconcile);
    IF l_rv THEN
      l_suc_cnt := l_suc_cnt + 1;
      UPDATE odb SET last_reconcile = SYSTIMESTAMP
        WHERE db_key = p_db_key
        RETURNING last_reconcile INTO l_rec_time;
      COMMIT;
      trace1('RECONCILE_DB: update last_reconcile_time for ' ||
             ' db_key=' || p_db_key ||
             ', to ' || l_rec_time);
    ELSE
      l_err_cnt := l_err_cnt + 1;
    END IF;
  ELSE
    BEGIN
      OPEN rep_server_cursor(p_db_key);
      LOOP
      FETCH rep_server_cursor
          INTO l_lib_key, l_server_key, l_rep_srvr_status;
        EXIT WHEN rep_server_cursor%NOTFOUND;
 
        IF l_rep_srvr_status != 'A' THEN
          IF p_only_active THEN
            trace1 ('RECONCILE_DB: skipping inactive replication server. ' ||
                    'server_key=' || l_server_key);
            CONTINUE;
          END IF;
        END IF;
 
        l_rv := reconcile_it (p_db_key    => p_db_key,
                          p_lib_key       => l_lib_key,
                          p_server_key    => l_server_key,
                          p_force_reconcile => reconcile_db.p_force_reconcile);
        IF l_rv THEN
          l_suc_cnt := l_suc_cnt + 1;
          UPDATE odb SET last_reconcile = SYSTIMESTAMP
            WHERE db_key = p_db_key
            RETURNING last_reconcile INTO l_rec_time;
          COMMIT;
          trace1('RECONCILE_DB: update last_reconcile_time for ' ||
                 ' db_key=' || p_db_key ||
                 ', to ' || l_rec_time);
        ELSE
          l_err_cnt := l_err_cnt + 1;
        END IF;
 
      END LOOP;
      CLOSE rep_server_cursor;
    END;
  END IF;
 
  rec_cnt := l_suc_cnt;
  RETURN (l_err_cnt = 0);
 
EXCEPTION
  WHEN OTHERS THEN
    save_error;
    trace1 ('RECONCILE_DB: error - '  || SQLERRM);
    RAISE;
 
END reconcile_db;
 
 
--
--
--
--
--
PROCEDURE execute_reconcile(p_task_rec IN task%ROWTYPE) IS
  l_db_key             NUMBER;
  l_rv                 BOOLEAN;
  l_rec_cnt            NUMBER; -- num we reconciled against
  l_exp_rec_cnt        NUMBER; -- num we expected to reconcile against
BEGIN
 
  l_db_key := p_task_rec.db_key;
 
  tracex('EXECUTE_RECONCILE: db_key=' || l_db_key);
  wait_for_repair (NULL, l_db_key);
  avoid_delete_db (l_db_key);
 
  SELECT count(*) INTO l_exp_rec_cnt FROM rep_server rs
    WHERE rs.prot_key = (SELECT prot_key
                           FROM odb
                          WHERE db_key=l_db_key
--
                            AND db_state IS NULL);
 
  IF l_exp_rec_cnt > 0 THEN
    l_rv := reconcile_db (p_db_key          => l_db_key,
                          p_server_key      => NULL,
                          p_only_active     => TRUE,
                          p_force_reconcile => FALSE,
                          rec_cnt           => l_rec_cnt);
    IF l_rv AND l_rec_cnt > 0 AND l_rec_cnt = l_exp_rec_cnt THEN
      fix_error (p_error_num  => dbms_ra.REP_SETUP_ERROR_NUM,
                 p_db_key     => l_db_key,
                 p_param_char => 'RECONCILE');
    END IF;
 
    trace1('EXECUTE_RECONCILE: reconcile complete. rv=' || print(l_rv) ||
           ' actual_reconcile count=' || l_rec_cnt ||
           ', expected_reconcile=' || l_exp_rec_cnt);
 
    IF l_rec_cnt = 0 THEN
      trace1('EXECUTE_RECONCILE: no active replication servers. Aborting task');
    END IF;
  ELSE
--
    trace1('EXECUTE_RECONCILE: Nothing to reconcile. Aborting task');
  END IF;
 
--
--
--
  IF s_setup_next_reconcile THEN
    trace1('EXECUTE_RECONCILE: setup new reconcile timer.' ||
           ' db_key=' || l_db_key);
    queue_set_reconcile_timer(l_db_key);
  END IF;
 
EXCEPTION
  WHEN OTHERS THEN
    save_error;
    trace1 ('execute_reconcile: error - '  || SQLERRM);
    RAISE;
 
END execute_reconcile;
 
 
--
--
--
--
--
PROCEDURE queue_replication_task(p_bp_key       IN NUMBER,
                           p_handle             IN VARCHAR2,
                           p_db_key             IN NUMBER,
                           p_bs_key             IN NUMBER,
                           p_piece_no           IN NUMBER,
                           p_rep_server_key     IN NUMBER,
                           p_sbt_template_key   IN NUMBER,
                           p_sbt_attr_set_key   IN NUMBER,
                           p_sbt_lib_key        IN NUMBER) IS
  l_spawn_job           BOOLEAN := FALSE;
  new_task_rec          task%ROWTYPE;
  l_db_key              NUMBER;
  l_bs_key              NUMBER;
  l_piece_no            NUMBER;
  l_rep_server_key      NUMBER;
  l_sbt_template_key    NUMBER;
  l_sbt_job_attr_key    NUMBER;
  l_sbt_lib_key         NUMBER;
  l_copies              NUMBER;
  l_cnt                 NUMBER;
  l_rep_srvr_status     rep_server.status%TYPE;
BEGIN
 
  trace1 ('QUEUE_REPLICATION_TASK:' ||
          ' p_db_key= ' || p_db_key ||
          ', p_bs_key= ' || p_bs_key ||
          ', p_piece_no= ' || p_piece_no ||
          ', p_bp_key= ' || p_bp_key ||
          ', p_rep_server_key= ' || p_rep_server_key ||
          ', p_sbt_template_key= ' || p_sbt_template_key ||
          ', p_sbt_attr_set_key= ' || p_sbt_attr_set_key ||
          ', p_sbt_lib_key= ' || p_sbt_lib_key ||
          ', p_handle= ' || p_handle);
 
  l_db_key              := p_db_key;
  l_bs_key              := p_bs_key;
  l_piece_no            := p_piece_no;
  l_sbt_template_key    := p_sbt_template_key;
  l_sbt_job_attr_key    := p_sbt_attr_set_key;
  l_sbt_lib_key         := p_sbt_lib_key;
  l_rep_server_key      := p_rep_server_key;
  l_copies              := 1;
 
--
  SELECT count(*) 
    INTO l_cnt
    FROM sbt_lib_desc
    WHERE lib_key = l_sbt_lib_key;
  IF l_cnt = 0 THEN
    trace1('QUEUE_REPLICATION_TASK: Library for Replication Server has ' ||
           ' been deleted.');
    RETURN;
  END IF;
 
--
  BEGIN
    SELECT status
      INTO l_rep_srvr_status
      FROM rep_server
      WHERE rep_server_key = l_rep_server_key;
    IF l_rep_srvr_status != 'A' THEN
      RAISE no_data_found;
    END IF;
  EXCEPTION
    WHEN no_data_found THEN 
      save_error;
      trace1('QUEUE_REPLICATION_TASK: Replication Server not available. ' ||
             ' l_rep_server_key=' || l_rep_server_key);
      clear_error;
      RETURN;
  END;
 
--
  l_spawn_job := queue_one_sbt_backup_task(
                            p_db_key => l_db_key,
                            p_bs_key => l_bs_key,
                            p_piece_no => l_piece_no,
                            p_src_bpkey => p_bp_key,
                            p_template_key => l_sbt_template_key,
                            p_full_template_key => l_sbt_template_key,
                            p_attr_set_key => l_sbt_job_attr_key,
                            p_lib_key => l_sbt_lib_key,
                            p_rep_server_key => l_rep_server_key,
                            p_copies => l_copies);
 
  UPDATE sbt_job_template job
     SET job.schedule_time   = SYSTIMESTAMP,
         job.completion_time =
             nvl2(job.window, job.window + SYSTIMESTAMP, null)
  WHERE job.template_key = l_sbt_template_key;
 
--
  COMMIT;
 
  IF (NOT l_spawn_job) THEN
    trace1 ('QUEUE_REPLICATION_TASK: no job queued for ' ||
            ' l_sbt_template_key=' || l_sbt_template_key ||
            ' l_bs_key=' || l_bs_key ||
            ' l_piece_no=' || l_piece_no);
    RETURN;
  END IF;
 
  queue_spawn_sbt(p_libkey => l_sbt_lib_key, p_forpurge => FALSE);
EXCEPTION
  WHEN OTHERS THEN
    save_error;
    trace1 ('QUEUE_REPLICATION_TASK: error - '  || SQLERRM);
    RAISE;
 
END queue_replication_task;
 
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE replicate_existing_backups(
                    p_template_name IN sbt_job_template.template_name%TYPE,
                    p_db_key        IN NUMBER DEFAULT NULL,
                    p_server_key    IN NUMBER DEFAULT NULL
                    ) IS
  l_cnt       NUMBER;
BEGIN
  IF p_db_key IS NOT NULL THEN
    SELECT count(*) INTO l_cnt FROM bp
      WHERE db_key=p_db_key AND status = 'A' AND ROWNUM=1 AND
            vb_key IS NOT NULL;
  ELSIF p_template_name IS NOT NULL THEN
    SELECT count(*) INTO l_cnt FROM bp WHERE
      status = 'A' AND ROWNUM=1 AND
      vb_key IS NOT NULL AND
      db_key = (SELECT db_key FROM sbt_job_template
                 WHERE template_name=p_template_name);
  END IF;
 
  trace1('replicate_existing_backups by p_db_key= ' || p_db_key ||
         ' rssrvr_key=' || p_server_key ||
         ' template_name=' || p_template_name ||
         ' existing_bu_cnt=' || l_cnt);
 
  IF l_cnt > 0 THEN
    dbms_ra_scheduler.queue_sbt_backup_task(template_name => p_template_name);
  END IF;
 
END replicate_existing_backups;
 
 
--
--
--
--
--
--
--
--
--
--
PROCEDURE create_replication_tasks(p_db_key IN NUMBER,
                                   p_bp_key IN NUMBER DEFAULT NULL,
                                   p_bs_key IN NUMBER DEFAULT NULL,
                                   p_piece_no IN NUMBER DEFAULT NULL,
                                   p_server_key IN NUMBER DEFAULT NULL,
                                   p_lib_key IN NUMBER DEFAULT NULL
                                  ) IS
  CURSOR rep_server_cursor (in_db_key IN NUMBER) IS
    SELECT l.lib_key,a.attr_key,j.template_key,
           rs.server_key,rs.rep_server_key, rs.status
      FROM odb o, rep_server rs, sbt_job_template j, sbt_lib_desc l, 
           sbt_attr_set a
      WHERE o.db_key=in_db_key 
        AND o.prot_key=rs.prot_key 
        AND rs.server_key=l.server_key 
        AND l.lib_key=a.lib_key 
        AND a.attr_key=j.attr_key
        AND o.db_key=j.db_key;
    
  l_handle             VARCHAR2(512) := NULL;
  l_db_key             NUMBER;
  l_bs_key             NUMBER;
  l_piece_no           NUMBER;
  l_sbt_template_key   NUMBER;
  l_sbt_attr_key       NUMBER;
  l_lib_key            NUMBER;
  l_server_key         NUMBER;
  l_rep_server_key     NUMBER;
  l_rep_srvr_status    rep_server.status%TYPE;
BEGIN
  
  trace1 ('CREATE_REPLICATION_TASKS:' ||
          ' p_db_key = '  || p_db_key ||
          ' p_bp_key = '  || p_bp_key ||
          ' p_ba_srv = '  || p_server_key ||
          ' p_lib_key = ' || p_lib_key );
 
  l_db_key := p_db_key;
  l_bs_key := p_bs_key;
  l_piece_no := p_piece_no;
  
  IF l_db_key IS NULL THEN
    trace1 ('CREATE_REPLICATION_TASKS: required db_key missing.');
    RETURN;
  END IF;
  
  IF (p_bs_key IS NULL OR p_piece_no IS NULL) THEN
    IF p_bp_key IS NULL THEN
      trace1 ('CREATE_REPLICATION_TASKS: required bp_key missing.');
      RETURN;
    END IF;
 
    SELECT bs_key, db_key, handle, piece#
      INTO l_bs_key, l_db_key, l_handle, l_piece_no
      FROM bp
      WHERE bp.bp_key = p_bp_key AND bp.status != 'D';
  END IF;
 
  BEGIN
    OPEN rep_server_cursor(l_db_key);
    LOOP
      FETCH rep_server_cursor
        INTO l_lib_key, l_sbt_attr_key, l_sbt_template_key, 
        l_server_key, l_rep_server_key, l_rep_srvr_status;
      EXIT WHEN rep_server_cursor%NOTFOUND;
 
      trace1 ('CREATE_REPLICATION_TASKS: replication cursor ' ||
              ' l_db_key=' || l_db_key ||
              ', p_bp_key=' || p_bp_key ||
              ', l_bs_key=' || l_bs_key ||
              ', l_piece_no=' || l_piece_no ||
              ', template_key=' || l_sbt_template_key ||
              ', lib_key=' || l_lib_key ||
              ', rep_server_key=' || l_rep_server_key ||
              ', attr_key=' || l_sbt_attr_key ||
              ', server_key=' || l_server_key ||
              ', p_server_key=' || p_server_key ||
              ', rep_srvr_status=' || l_rep_srvr_status);
      IF (l_lib_key IS NOT NULL) AND 
        ((p_lib_key is NOT NULL AND p_lib_key=l_lib_key) OR 
         (p_lib_key is NULL)) AND
        ((p_server_key IS NULL) OR
         (p_server_key IS NOT NULL AND
          p_server_key = l_server_key)) AND
        (l_rep_srvr_status = 'A') THEN 
        queue_replication_task(p_bp_key      =>  p_bp_key           ,
                               p_handle      =>  l_handle           ,
                               p_db_key      =>  l_db_key           ,
                               p_bs_key      =>  l_bs_key           ,
                               p_piece_no    =>  l_piece_no         ,
                               p_rep_server_key => l_rep_server_key ,
                               p_sbt_template_key => l_sbt_template_key  ,
                               p_sbt_attr_set_key => l_sbt_attr_key  ,
                               p_sbt_lib_key => l_lib_key );
      END IF;
      
    END LOOP;
    CLOSE rep_server_cursor;
 
  EXCEPTION
    WHEN OTHERS THEN
      save_error;
      CLOSE rep_server_cursor;
      RAISE;
  END;
 
EXCEPTION
  WHEN OTHERS THEN
    save_error;
    trace1 ('CREATE_REPLICATION_TASKS: error - '  || SQLERRM);
    RAISE;
 
END create_replication_tasks;
 
 
--
--
--
--
PROCEDURE queue_restore_task(request_id    IN NUMBER,
                             sbt_sessionid IN VARCHAR2,
                             handle        IN VARCHAR2) IS
  new_task_rec          task%ROWTYPE;
  l_db_key              NUMBER;
  l_lib_key             NUMBER;
  l_bs_key              NUMBER;
  l_bp_key              NUMBER;
  l_piece_no            NUMBER;
  l_count               NUMBER;
  l_status              sbt_lib_desc.status%TYPE;
  l_lib_name            sbt_lib_desc.lib_name%TYPE;
  l_rep_srvr_status     rep_server.status%TYPE;
  l_rep_srvr_key        NUMBER;
  l_rs_srvr_key         NUMBER;
BEGIN
   trace1 ('QUEUE_RESTORE_TASK:' ||
           ' request_id = ' || request_id ||
           ' sbt_sessionid = ' || sbt_sessionid ||
           ' handle = ' || handle);
   
   SELECT bp.db_key, bp.bp_key, bp.bs_key, bp.piece#, bp.lib_key
     INTO l_db_key, l_bp_key, l_bs_key, l_piece_no, l_lib_key
     FROM bp
    WHERE bp.handle = queue_restore_task.handle
     AND bp.status != 'D'
     AND bp.ba_access != 'U';
 
   IF (l_lib_key IS NOT NULL) THEN
      SELECT lib.status, lib.lib_name, lib.server_key
        INTO l_status, l_lib_name, l_rs_srvr_key
        FROM sbt_lib_desc lib
       WHERE lib.lib_key = l_lib_key;
 
      IF (l_status != 'R') THEN
         SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(
            E_SBT_LIB_NOT_READY_NUM, l_lib_name);
      END IF;
 
--
--
--
--
--
--
--
      IF l_rs_srvr_key IS NOT NULL THEN
--
        BEGIN
          SELECT rs.status, rs.rep_server_key
            INTO l_rep_srvr_status, l_rep_srvr_key
            FROM odb o, rep_server rs, sbt_lib_desc l
            WHERE o.db_key=l_db_key
              AND o.prot_key=rs.prot_key
              AND rs.server_key=l.server_key
              AND l.lib_key=l_lib_key;
 
          IF l_rep_srvr_status != 'A' THEN
--
            SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(
                           E_SBT_LIB_NOT_READY_NUM, l_lib_name);
          END IF;
 
        EXCEPTION
          WHEN no_data_found THEN
            save_error;
--
            clear_error;
        END;
      END IF;
   END IF;
 
--
   IF (l_lib_key IS NOT NULL) THEN
      new_task_rec.task_type := TASK_RESTORE_SBT;
   ELSE
      new_task_rec.task_type := TASK_RESTORE;
   END IF;
 
   new_task_rec.flags       := 0;
   new_task_rec.db_key      := l_db_key;
   new_task_rec.param_char1 := sbt_sessionid;
   new_task_rec.param_char2 := handle;
   new_task_rec.param_num1  := request_id;
   new_task_rec.param_num2  := l_bp_key;
   new_task_rec.param_num3  := l_lib_key;
   new_task_rec.com_time    := sysdate;
 
   IF (l_lib_key IS NOT NULL) THEN
      new_task (task_rec => new_task_rec,
                p_commit => FALSE,
                p_sbt_task => TRUE);
      INSERT INTO sbt_task
         (task_id, bs_key, piece#, rep_server_key,
          template_key, attr_key, lib_key, copies, failure_cnt, restore)
      VALUES
         (new_task_rec.task_id, l_bs_key, l_piece_no, l_rep_srvr_key,
          NULL, NULL, l_lib_key, 1, 0, 'Y');
   ELSE
      new_task (task_rec => new_task_rec, p_commit => FALSE);
   END IF;
 
--
   COMMIT;
  
--
--
--
   SYS.KBRSI_ICD.RSRUNSCHED;
 
   IF (l_lib_key IS NOT NULL) THEN -- sbt restore task
      queue_spawn_sbt(p_libkey => l_lib_key, p_forpurge => FALSE);
   ELSE                             -- Virtual restore
--
--
     SELECT COUNT(*) INTO l_count 
       FROM task 
       WHERE state = STATE_RESTORE_WAIT
         AND execute_inst_id = s_instance;
 
     IF l_count = 0 THEN
       spawn_job('RA$_REST_' || rai_sq.nextval,
                 'dbms_ra_scheduler.schedule(' ||
                 '  p_task_type => dbms_ra_scheduler.TASK_RESTORE);',
                 s_instance,
                 NULL);
     END IF;
   END IF;
 
   trace1 ('QUEUE_RESTORE_TASK complete');
END queue_restore_task;
 
 
--
--
--
--
FUNCTION wait_for_resource(request_id IN NUMBER,
                           handle     IN VARCHAR2) RETURN BINARY_INTEGER IS
  l_busy          BINARY_INTEGER := 0;
  maxtries        NUMBER := 100;
  l_state         NUMBER;
  l_task_type     NUMBER;
BEGIN
   trace1 ('WAIT_FOR_RESOURCE:' ||
           ' request_id = ' || request_id ||
           ' handle = ' || handle);
 
--
   BEGIN
      SYS.KBRSI_ICD.RSSCHEDLOCK (waitforwork => 0);
      SELECT t.state, t.task_type
        INTO l_state, l_task_type
        FROM task t
             LEFT OUTER JOIN
             sbt_task st
             ON  st.task_id = t.task_id
             AND st.restore = 'Y' -- restore jobs
       WHERE t.param_num1 = request_id
         AND ((t.task_type = TASK_RESTORE_SBT AND st.task_id IS NOT NULL) OR
              (t.task_type = TASK_RESTORE));
 
      UPDATE task SET com_time = sysdate
        WHERE param_num1 = request_id;
      COMMIT;
      SYS.KBRSI_ICD.RSSCHEDUNLOCK;
   EXCEPTION
      WHEN no_data_found THEN
         save_error;
         SYS.KBRSI_ICD.RSSCHEDUNLOCK;
         trace1('WAIT_FOR_RESOURCE: could not locate task');
         clear_error;
         RETURN l_busy;
   END;
 
   IF (l_state = STATE_RUNNING OR
       l_state = STATE_COMPLETED) THEN
      RETURN l_busy;
   END IF;
 
   IF (l_task_type IN (TASK_RESTORE, TASK_RESTORE_SBT)) THEN 
     IF (l_state NOT IN (STATE_RUNNING, STATE_CANCELING, STATE_CANCEL)) THEN
       l_busy := 1;
     END IF;
   ELSE
      sys.dbms_sys_error.raise_system_error(
         E_INTERNAL_ERROR_NUM, 'unknown task_type ' || nvl(l_task_type, ''));
   END IF;
 
   RETURN l_busy;
END wait_for_resource;
 
 
--
--
--
--
PROCEDURE execute_obsolete_sbt(p_task_rec IN task%ROWTYPE) IS
--
   CURSOR sbt_cursor IS
      SELECT bp.db_key, bp.lib_key, odb.sbt_ret
        FROM (SELECT DISTINCT bp.db_key, bp.lib_key
                FROM bp
               WHERE bp.lib_key IS NOT NULL
                 AND bp.status != 'D'
                 AND bp.ba_access != 'U') bp,
             (SELECT odb.db_key, prot.prot_recovery_window_sbt sbt_ret
                FROM prot, odb
               WHERE prot.prot_key = odb.prot_key) odb
       WHERE bp.db_key = odb.db_key
--
--
   ORDER BY 1, 3;
BEGIN
--
   FOR i in sbt_cursor LOOP
      trace1 ('EXECUTE_OBSOLETE_SBT: db_key=' || i.db_key ||
                                 ' lib_key=' || i.lib_key);
      IF (i.sbt_ret IS NOT NULL) THEN
         purge_obsolete_sbt(p_dbkey   => i.db_key,
                            p_libkey  => i.lib_key,
                            p_sbt_ret => i.sbt_ret);
      END IF;
   END LOOP;
END execute_obsolete_sbt;
 
--
--
--
--
--
PROCEDURE purge_obsolete_sbt(
                       p_dbkey   IN NUMBER,
                       p_libkey  IN NUMBER,
                       p_sbt_ret IN DSINTERVAL_UNCONSTRAINED) IS
   l_spawn_job   BOOLEAN;
   l_untilTime   DATE;
   l_status      BOOLEAN;
   l_firstcall   BOOLEAN;
   lbRec         dbms_rcvman.lbRec_t;
   lbCursor      dbms_rcvman.lbCursor_t;
   l_dbid        NUMBER;
   l_currinc     NUMBER;
   l_db_slkey    NUMBER;
BEGIN
   IF (p_sbt_ret IS NULL) THEN
      RETURN;  -- no retention set
   END IF;
 
   l_untilTime := SYSDATE - p_sbt_ret;
   trace1 ('PURGE_OBSOLTE_SBT: db_key='  || p_dbkey ||
                           ' lib_key='   || p_libkey ||
                           ' untilTime=' || l_untilTime);
 
   setDatabase(p_dbkey, l_dbid, l_currinc, l_db_slkey);
 
--
   BEGIN
      dbms_rcvman.setUntilTime(l_untilTime);
   EXCEPTION
      WHEN OTHERS THEN
         save_error;
         trace1 ('PURGE_OBSOLETE_SBT EXCEPTION: (setUntilTime)'  || SQLERRM);
         sys.kbrsi_icd.rsClearErr;
         clear_error;
         RETURN;
   END;
 
   dbms_rcvman.setDeviceType('SBT_TAPE');
   dbms_rcvman.setOrsFile(localOnly => FALSE, libKey => p_libkey);
   dbms_rcvman.setNeedObsoleteData(TRUE);
 
--
   l_status    := TRUE;
   l_firstcall := TRUE;
   l_spawn_job := FALSE;
   WHILE (l_status)
   LOOP
      l_status := dbms_rcvman.listBackup(
                  lbRecOut      => lbRec,
                  firstcall     => l_firstcall,
                  only_obsolete => TRUE,
                  redundancy    => 1,
                  piped_call    => FALSE,
                  lbCursor      => lbCursor,
                  lbState       => dbms_rcvman.lbStatePck);
 
      l_firstcall := FALSE;
 
      IF (lbRec.pkey IS NOT NULL AND
          lbRec.file_type = dbms_rcvman.piece_txt AND
          (lbRec.status = dbms_rcvman.available_txt OR
           lbRec.status = dbms_rcvman.expired_txt   OR
           lbRec.status = dbms_rcvman.unavailable_txt)) THEN
         DBMS_RA_STORAGE.FREE_BACKUP_PIECE_OPT(
            p_dbkey     => p_dbkey,
            p_piecename => lbRec.fname,
            p_db_slkey  => l_db_slkey,
            p_dbid      => l_dbid,
            p_currinc   => l_currinc,
            p_bpkey     => lbRec.pkey,
            p_ftype     => DBMS_RA_INT.KBRSCHKTYPE_TAPE,
            p_libkey    => p_libkey,
            p_spawn_job => FALSE);
--
         l_spawn_job := TRUE;
      END IF;
   END LOOP;
 
   IF (NOT l_spawn_job) THEN
      RETURN;
   END IF;
 
--
   queue_spawn_sbt(p_libkey => p_libkey, p_forpurge => TRUE);
EXCEPTION
   WHEN OTHERS THEN
       save_error;
       trace1 ('PURGE_OBSOLETE_SBT EXCEPTION: '  || SQLERRM);
       RAISE;
END purge_obsolete_sbt;
 
 
--
--
--
--
FUNCTION add_to_task_history_table (
                                    task_type   NUMBER,
                                    db_key      NUMBER DEFAULT NULL,
                                    sl_key      NUMBER DEFAULT NULL,
                                    param       VARCHAR2 DEFAULT NULL,
                                    param_num1  NUMBER DEFAULT NULL,
                                    param_num2  NUMBER DEFAULT NULL,
                                    param_num3  NUMBER DEFAULT NULL,
                                    param_char1 VARCHAR2 DEFAULT NULL,
                                    param_char2 VARCHAR2 DEFAULT NULL
                                   ) RETURN NUMBER
IS
PRAGMA AUTONOMOUS_TRANSACTION;
l_task_id NUMBER := 0;
BEGIN
  tracex('#### ' || param);
  
  l_task_id := rai_sq.nextval;
--
--
--
  INSERT INTO TASK_HISTORY (task_id,       task_type,          flags,
                            db_key, sl_key, param, 
                            param_num1, param_num2, param_num3,
                            param_char1, param_char2,
                            execute_time, 
                            completion_time,
                            execute_inst_id, state)
    VALUES (l_task_id, task_type, 0,
            db_key, sl_key, SUBSTR(param, 1, 4000),
            param_num1, param_num2, param_num3,
            param_char1, param_char2, 
            SYSTIMESTAMP, SYSTIMESTAMP,
            s_instance, STATE_COMPLETED);
  
  COMMIT;
  RETURN l_task_id;
 
EXCEPTION
   WHEN OTHERS THEN
     save_error;
     trace1 ('ADD_TO_TASK_HISTORY_TABLE EXCEPTION: '  || SQLERRM);
     RAISE;
     
END add_to_task_history_table;
 
 
--
--
--
--
PROCEDURE update_task_history_entry (
                                    task_id     NUMBER,
                                    db_key      NUMBER DEFAULT NULL,
                                    sl_key      NUMBER DEFAULT NULL,
                                    param       VARCHAR2 DEFAULT NULL,
                                    param_num1  NUMBER DEFAULT NULL,
                                    param_num2  NUMBER DEFAULT NULL,
                                    param_num3  NUMBER DEFAULT NULL,
                                    param_char1 VARCHAR2 DEFAULT NULL,
                                    param_char2 VARCHAR2 DEFAULT NULL,
                                    do_commit   IN BOOLEAN DEFAULT FALSE
                                    ) IS
BEGIN
  
  IF db_key IS NOT NULL THEN 
    UPDATE task_history
      SET db_key=update_task_history_entry.db_key
      WHERE task_id = update_task_history_entry.task_id;
  END IF;
  
  IF sl_key IS NOT NULL THEN 
    UPDATE task_history
      SET sl_key=update_task_history_entry.sl_key
      WHERE task_id = update_task_history_entry.task_id;
  END IF;
  
  IF param IS NOT NULL THEN 
    UPDATE task_history
      SET param=SUBSTR(param, 1, 4000)
      WHERE task_id = update_task_history_entry.task_id;
  END IF;
    
  IF param_num1 IS NOT NULL THEN 
    UPDATE task_history
      SET param_num1=update_task_history_entry.param_num1
      WHERE task_id = update_task_history_entry.task_id;
  END IF;
  
  IF param_num2 IS NOT NULL THEN 
    UPDATE task_history
      SET param_num2=update_task_history_entry.param_num2
      WHERE task_id = update_task_history_entry.task_id;
  END IF;
    
  IF param_num3 IS NOT NULL THEN 
    UPDATE task_history
      SET param_num3=update_task_history_entry.param_num3
      WHERE task_id = update_task_history_entry.task_id;
  END IF;
      
  IF param_char1 IS NOT NULL THEN 
    UPDATE task_history
      SET param_char1=update_task_history_entry.param_char1
      WHERE task_id = update_task_history_entry.task_id;
  END IF;
        
  IF param_char2 IS NOT NULL THEN 
    UPDATE task_history
      SET param_char2=update_task_history_entry.param_char2
      WHERE task_id = update_task_history_entry.task_id;
  END IF;
  
--
--
  IF do_commit THEN
    COMMIT;
  END IF;
  
END update_task_history_entry;
 
 
--
--
--
--
--
--
--
--
--
--
PROCEDURE copy_one_backuppiece(p_bpkey            IN NUMBER,
                               p_format           IN VARCHAR2,
                               p_deletesource     IN VARCHAR2,
                               p_template_key     IN NUMBER DEFAULT NULL)
AS
  start_time        timestamp;
  end_time          timestamp;
  howlong           interval day(3) to second(3);
 
  set_count         NUMBER;
  set_stamp         NUMBER;
  recid             NUMBER;
  stamp             NUMBER; 
  out_recid         NUMBER; 
  out_stamp         NUMBER;
  concur            BOOLEAN;
 
  newfilename       varchar2(1024);
  srcfilename       varchar2(1024);
  handle            varchar2(512);
  comment           varchar2(80);
  media             varchar2(80);
 
  lyear             varchar2(4);
  lday              varchar2(2);
  lmonth            varchar2(2);
  lcfaudate         varchar2(512);
 
  devtype           varchar2(512);
  node              varchar2(255);
  thetag            varchar2(255);
  bpsize            number;
  dbkey             NUMBER;
  vbkey             NUMBER;
  pstr              VARCHAR2(4000);
  piecenum          NUMBER;
  l_bskey           NUMBER;
  l_maxcopy         NUMBER;
  l_template_name   sbt_job_template.template_name%TYPE;
  
BEGIN
  
  trace1 ('copy_one_backuppiece: bp_key='  || p_bpkey ||
          ' ,template_key='     || p_template_key ||
          ' ,deletesource = '   || p_deletesource ||
          ' ,format='           || p_format);
 
--
  SELECT bp.handle, bp.bp_recid, bp.bp_stamp, bp.tag, 
            bp.db_key, bp.vb_key, piece#, bs_key
    INTO srcfilename, recid, stamp, thetag, dbkey, vbkey, piecenum, l_bskey
    FROM bp
    WHERE bp.bp_key = p_bpkey;
  
--
  SELECT set_stamp, set_count
    INTO set_stamp, set_count
    FROM bs
    WHERE bs_key=l_bskey;
  
--
  IF (p_template_key IS NOT NULL)
  THEN
--
--
    SELECT template_name 
      INTO l_template_name
      FROM sbt_job_template
      WHERE template_key = p_template_key;
    
--
    dbms_ra_scheduler.queue_sbt_backup_task(template_name => l_template_name,
                                            src_bpkey     => p_bpkey,
                                            delete_source => p_deletesource,
                                            format        => p_format);
 
  ELSE
--
    
--
    start_time := systimestamp;
    devtype := sys.dbms_backup_restore.deviceAllocate(
                                    ident        => 'ORA_DISK_1',
                                    node         => node,
                                    type         => NULL,
                                    params       => NULL,
                                    dupcnt       => 1, 
                                    allowmts     => TRUE,
                                    ors_lib_key  => NULL);
  
--
 
    lcfaudate := NULL;
    SELECT to_char(nvl(to_date(lcfaudate), sysdate), 'YYYY',
                           'NLS_CALENDAR=Gregorian'),
                   to_char(nvl(to_date(lcfaudate), sysdate), 'MM',
                           'NLS_CALENDAR=Gregorian'),
                   to_char(nvl(to_date(lcfaudate), sysdate), 'DD',
                           'NLS_CALENDAR=Gregorian')
      INTO lyear, lmonth, lday
      FROM dual;
  
--
    SELECT NVL(MAX(copy#), 0)
      INTO l_maxcopy 
      FROM bp
      WHERE bs_key = l_bskey;
 
    newfilename := sys.dbms_backup_restore.genPieceName(
                            pno => piecenum,
                            set_count => set_count,
                            set_stamp => set_stamp,
                            format => p_format,
                            copyno => l_maxcopy + 1,
                            devtype => 'DISK',
                            year => lyear,
                            month => lmonth,
                            day => lday,
                            dbid => NULL,    -- computed in server if required
                            ndbname => NULL, -- computed in server if required
                            pdbname => NULL, -- computed in server if required
                            cfseq => NULL);
 
    sys.dbms_backup_restore.backupBackupPiece(
                                   bpname       => srcfilename,
                                   fname        => newfilename,
                                   handle       => handle,
                                   comment      => comment,
                                   media        => media,
                                   concur       => concur,
                                   recid        => out_recid,
                                   stamp        => out_stamp,
                                   check_logical=> FALSE,
                                   tag          => thetag,
                                   params       => null,
                                   reuse        => false,
                                   deffmt       => 0,
                                   copy_recid   => recid,
                                   copy_stamp   => stamp,
--
--
                                   copyno       => 0,
                                   npieces      => 1,
                                   dest         => 0,
                                   pltfrmfr     => null,
                                   ors          => TRUE,
                                   template_key => NULL,
                                   bpsize       => bpsize);
 
--
    sys.dbms_backup_restore.backupCancel;
    sys.dbms_backup_restore.restoreCancel(TRUE);
    sys.dbms_backup_restore.cfileUseCurrent(TRUE);  -- release enqueue
    sys.dbms_backup_restore.deviceDeallocate;
    sys.dbms_backup_restore.set_client_info('');
    sys.dbms_backup_restore.setRmanStatusRowId(rsid=>0, rsts=>0);
 
 
--
    end_time := systimestamp;
    howlong := end_time - start_time;
    trace1('copy_one_backuppiece took ' || howlong || ' seconds');
  END IF;
 
EXCEPTION
  WHEN OTHERS THEN
    save_error;
    IF (p_template_key IS NULL) THEN
        sys.dbms_backup_restore.backupCancel;
        sys.dbms_backup_restore.restoreCancel(TRUE);
        sys.dbms_backup_restore.cfileUseCurrent(TRUE); -- release enqueue
        sys.dbms_backup_restore.deviceDeallocate;
        sys.dbms_backup_restore.set_client_info('');
        sys.dbms_backup_restore.setRmanStatusRowId(rsid=>0, rsts=>0);
 
      ROLLBACK;
    END IF;
    
    RAISE;
END copy_one_backuppiece;
 
--
--
--
--
--
--
PROCEDURE delete_one_backuppiece(p_bpkey IN NUMBER) AS
BEGIN
  DECLARE
    l_dbkey       sbt_catalog.db_key%type;
    l_piecename   sbt_catalog.handle%type;
    l_ftype       sbt_catalog.ftype%type;
    l_fincarn     sbt_catalog.pieceinc%type;
    l_status      VARCHAR2(1);
    l_ba_access   VARCHAR2(1);
    
  BEGIN
    trace1('delete_one_backuppiece - bp_key=' || p_bpkey);
    
    SELECT status, ba_access
      INTO l_status, l_ba_access 
      FROM bp
      WHERE bp_key=p_bpkey;
    
    IF l_ba_access NOT IN ('L', 'D') OR l_status != 'A' THEN
      trace1('delete_one_backuppiece - nothing to delete - status=' || l_status
             || ', ba_access=' || l_ba_access);
      RETURN;
    END IF;
    
    SELECT db_key, handle, ftype, pieceinc
      INTO l_dbkey, l_piecename, l_ftype, l_fincarn
      FROM sbt_catalog
      WHERE bp_key = p_bpkey;
    
    trace1('delete_backuppiece - l_dbkey=' || l_dbkey || ' l_piecename=' || 
            l_piecename || ' l_fincarn=' || l_fincarn);
    
    
--
    FOR l_x IN 1..300 LOOP
      BEGIN
        dbms_ra_storage.free_backup_piece(p_dbkey     => l_dbkey,
                                          p_piecename => l_piecename,
                                          p_fincarn   => l_fincarn);
        EXIT;
        
      EXCEPTION
        WHEN E_RETRY_ERROR THEN
          save_error;
          trace1('delete_backuppiece attempt ' || l_x || 
                 'at getting lock - l_dbkey=' || l_dbkey || ' l_piecename=' || 
                 l_piecename || ' l_fincarn=' || l_fincarn);
          DBMS_LOCK.SLEEP(1);
          clear_error;
          
        WHEN OTHERS THEN
          save_error;
          RAISE;
      END;
    END LOOP;
 
  END;
 
END delete_one_backuppiece;
 
PROCEDURE set_resumable_timeout
IS
BEGIN
  IF (s_resumable_timeout = 0 OR s_resumable_timeout IS NULL)
  THEN
    EXECUTE IMMEDIATE 'ALTER SESSION DISABLE RESUMABLE';
  ELSE
    EXECUTE IMMEDIATE
      'ALTER SESSION ENABLE RESUMABLE TIMEOUT ' || s_resumable_timeout;
  END IF;
END set_resumable_timeout;
 
--
--
--
PROCEDURE inValidateBaseLevelBcks (p_db_key       IN NUMBER,
                                   p_currinc      IN NUMBER,
                                   p_template_key IN NUMBER,
                                   p_baseline_scn IN OUT NUMBER) IS
  CURSOR invalid_bcks_cursor(p_db_key       IN NUMBER,
                             p_currinc      IN NUMBER,
                             p_template_key IN NUMBER) IS
  WITH 
    my_dbinc AS
       (SELECT dbinc_key, reset_scn, PRIOR reset_scn next_reset_scn 
             FROM dbinc
             START WITH dbinc_key = p_currinc  
             CONNECT BY PRIOR parent_dbinc_key=dbinc_key
             ANd db_key = p_db_key
        ),
    my_stf AS
       (SELECT stf.bs_key, stf.df_file#, stf.template_key, 
               bdf.abs_fuzzy_scn, bdf.ckp_scn, bdf.dbinc_key,
               stf.db_key 
          FROM bdf, sbt_template_df stf
          WHERE stf.db_key = p_db_key
            AND stf.template_key = p_template_key
            AND stf.df_file# = bdf.file# 
            AND stf.bs_key = bdf.bs_key)
    SELECT my_stf.bs_key, my_stf.df_file#, my_stf.template_key, my_stf.db_key
      FROM my_stf, my_dbinc
     WHERE my_stf.dbinc_key = my_dbinc.dbinc_key 
       AND greatest(abs_fuzzy_scn, ckp_scn) >= my_dbinc.next_reset_scn
    UNION
    SELECT my_stf.bs_key, my_stf.df_file#, my_stf.template_key, my_stf.db_key
      FROM my_stf
     WHERE my_stf.dbinc_key NOT IN
           (SELECT dbinc_key FROM my_dbinc)
    ORDER BY 1;  -- to avoid deadlocks for parallel updates
 
   l_values         invalid_bcks_cursor%ROWTYPE;
   l_curr_dbinc_key NUMBER;
   l_valid_backups  NUMBER;
BEGIN
 
  trace1('inValidateBaseLevelBcks: db_key=' || p_db_key || ',currdbinc_key=' ||
         p_currinc || ',template_key=' || p_template_key);
  BEGIN
     SELECT curr_dbinc_key INTO l_curr_dbinc_key 
       FROM sbt_template_db
      WHERE db_key = p_db_key
        AND template_key = p_template_key;
  EXCEPTION
      WHEN NO_DATA_FOUND THEN
         save_error;
         trace1('inValidateBaseLevelBcks: no sbt_template_db found');
         clear_error;
         RETURN;
  END;
 
  IF l_curr_dbinc_key = p_currinc THEN
     trace1('inValidateBaseLevelBcks: currinc not changed, nothing to do');
     RETURN;
  END IF;
 
  OPEN invalid_bcks_cursor(p_db_key, p_currinc, p_template_key);
  LOOP
     FETCH invalid_bcks_cursor INTO l_values;
     EXIT WHEN invalid_bcks_cursor%NOTFOUND;
 
     UPDATE sbt_template_df 
        SET bs_key = null, df_checkpoint_change# = null
      WHERE db_key = p_db_key
        AND template_key = p_template_key
        AND df_file# = l_values.df_file#
        AND bs_key = l_values.bs_key;
 
  END LOOP;
  CLOSE invalid_bcks_cursor;
 
--
--
  SELECT COUNT(*) INTO l_valid_backups 
    FROM sbt_template_df
   WHERE db_key       = p_db_key
     AND template_key = p_template_key
     AND df_file#     > 0
     AND bs_key       IS NOT NULL;
 
  IF (l_valid_backups = 0) THEN
     UPDATE sbt_template_db 
        SET baseline_scn = null
      WHERE db_key       = p_db_key
        AND template_key = p_template_key
        AND s_c2t_optimization = 1;
     UPDATE sbt_template_df 
        SET bs_key = null, df_checkpoint_change# = null
      WHERE db_key = p_db_key
        AND template_key = p_template_key
        AND df_file# <= 0;
     p_baseline_scn := 0;
     trace1('inValidateBaseLevelBcks: baseline_scn set to NULL');
  ELSE
     trace1('inValidateBaseLevelBcks: Valid backup count=' || l_valid_backups);
  END IF;
 
--
--
  UPDATE sbt_template_db 
     SET curr_dbinc_key = p_currinc
   WHERE db_key         = p_db_key
     AND template_key   = p_template_key
     AND s_c2t_optimization = 1;
  COMMIT;
END inValidateBaseLevelBcks;
        
--
--
PROCEDURE baselineTimezone(p_db_key               IN NUMBER,
                           p_baseline_time        OUT NOCOPY DATE,
                           p_baseline_untscn      OUT NOCOPY NUMBER,
                           p_recovery_window_sbt  OUT NOCOPY DATE) IS
  l_db_timezone         VARCHAR2(64);
  l_currtime            DATE;
  l_dbid                NUMBER;
  l_currinc             NUMBER;
  l_db_slkey            NUMBER;
BEGIN
 
  setDatabase(p_db_key, l_dbid, l_currinc, l_db_slkey);
 
--
  dbms_rcvman.setAllIncarnations(TRUE);
 
  SELECT MIN(db_timezone) INTO l_db_timezone
    FROM node
   WHERE db_key = p_db_key
     AND database_role = 'PRIMARY';
 
--
  IF (l_db_timezone IS NULL) THEN
    l_currtime := SYSDATE;
  ELSE
    SELECT CAST((SYSTIMESTAMP AT TIME ZONE TO_CHAR(l_db_timezone)) as DATE)
      INTO l_currtime
      FROM dual;
  END IF;
 
  p_baseline_time := l_currtime - s_baseline_cap;
 
--
  dbms_rcvman.setUntilTime(p_baseline_time);
  p_baseline_untscn := NVL(dbms_rcvman.getUntilScn, 0);
 
  BEGIN
    SELECT l_currtime - prot_recovery_window_sbt INTO p_recovery_window_sbt
      FROM prot, odb
      WHERE odb.prot_key = prot.prot_key
        AND odb.db_key = p_db_key;
  EXCEPTION
     WHEN NO_DATA_FOUND THEN
        save_error;
        clear_error;
        p_recovery_window_sbt := NULL;
        trace1('baselineTimezone: No Rec window SBT for db_key=' || p_db_key);
  END;
 
  trace1('baselineTimezone: baseline_cap=' || print(s_baseline_cap) ||
         ',l_currtime=' || print(l_currtime) ||
         ',p_baseline_time=' || print(p_baseline_time) ||
         ',l_db_timezone=' || print(l_db_timezone) ||
         ',p_recovery_window_sbt=' || print(p_recovery_window_sbt) ||
         ',p_baseline_untscn=' || print(p_baseline_untscn));
 
END baselineTimezone;
 
--
--
PROCEDURE queueBaseLevelBcks(p_db_key            IN NUMBER,
                             p_dbid             OUT NUMBER,
                             p_currinc       IN OUT NUMBER,
                             p_db_slkey      IN OUT NUMBER,
                             p_from_tag          IN VARCHAR2,
                             p_template_key      IN NUMBER,
                             p_baseline_scn  IN OUT NUMBER,
                             p_lib_key           IN NUMBER,
                             p_attr_key          IN NUMBER,
                             p_copies            IN NUMBER,
                             p_delete_source     IN VARCHAR2,
                             p_format            IN VARCHAR2,
                             p_last_bp_key       IN NUMBER,
                             p_max_bp_key        IN NUMBER,
                             p_server_key        IN NUMBER) IS
--
--
  CURSOR bp_last_full_cursor(c_baseline_untscn   IN NUMBER) IS
    WITH
       my_dbinc AS
       (SELECT dbinc_key, reset_scn, PRIOR reset_scn next_reset_scn 
          FROM dbinc START WITH dbinc_key = 
               (SELECT curr_dbinc_key from db where db_key=p_db_key) 
          CONNECT BY PRIOR parent_dbinc_key = dbinc_key),
       bp_list AS
--
--
       (SELECT /*+ MATERIALIZE */ 
               bp.* FROM bp, sbt_template_df stf 
         WHERE bp.bs_key = stf.bs_key
           AND stf.template_key = p_template_key
           AND stf.db_key = p_db_key
           AND bp.lib_key IS NULL  
           AND bp.ba_access IN ('D', 'L')
           AND bp.status != 'D'
           AND bp.bp_key <= p_last_bp_key
         UNION ALL 
        SELECT bp.* FROM bp
         WHERE bp.db_key = p_db_key
           AND bp.lib_key IS NULL  
           AND bp.ba_access IN ('D', 'L')
           AND bp.status != 'D'
           AND (p_from_tag IS NULL OR bp.tag = p_from_tag)
           AND bp.bp_key > p_last_bp_key),
       df_backup AS        -- latest datafile backups
       (SELECT * FROM 
          (SELECT RANK() OVER
                (PARTITION BY file#, create_scn, plugin_scn
                 ORDER BY ckp_scn DESC, bdf_key DESC) rank,
               bdf.file#,
               bdf.create_scn,
               bdf.plugin_scn,
               bdf.ckp_scn,
               bdf.ckp_time,
               bp.bs_key,
               bp.bp_key,
               bp.piece#
          FROM bp_list bp, bdf, my_dbinc
         WHERE bp.bs_key = bdf.bs_key
--
--
--
--
           AND bp.vb_key IS NOT NULL
           AND bdf.incr_scn <= bdf.create_scn
           AND bdf.dbinc_key = my_dbinc.dbinc_key
           AND bdf.ckp_scn >= c_baseline_untscn
           AND (decode(bdf.abs_fuzzy_scn, 0, bdf.ckp_scn, bdf.abs_fuzzy_scn) <
                       my_dbinc.next_reset_scn OR
                my_dbinc.next_reset_scn IS NULL))
         WHERE rank = 1),
       cf_backup AS       -- latest controlfile backup
       (SELECT * FROM
          (SELECT RANK() over
               (ORDER BY ckp_scn DESC, bcf_key DESC) rank,
               bp.bs_key,
               bp.bp_key,
               bp.piece#,
               bcf.ckp_scn,
               bcf.ckp_time
          FROM bp_list bp, bcf, my_dbinc
         WHERE bp.bs_key = bcf.bs_key
           AND bcf.dbinc_key = my_dbinc.dbinc_key
           AND bcf.ckp_scn >= c_baseline_untscn
           AND (bcf.ckp_scn < my_dbinc.next_reset_scn OR
                my_dbinc.next_reset_scn IS NULL))
         WHERE rank=1),
       sf_backup AS      -- latest spfile backup
       (SELECT * FROM
          (SELECT RANK() over
               (ORDER BY modification_time DESC, bsf_key DESC) rank,
               bp.bs_key, 
               bp.bp_key,
               bp.piece#, 
               bsf.modification_time
          FROM bp_list bp, bsf
         WHERE bp.bs_key = bsf.bs_key
           AND bsf.db_key = p_db_key)
        WHERE rank=1),
       df_list AS  -- list of all datafiles relevant to baseline_cap days
       (SELECT * FROM
          (SELECT RANK() OVER
               (PARTITION BY df.file#, df.create_scn, df.plugin_scn
                ORDER BY df.dbinc_key DESC) rank,
                  df.file#, df.ts#, df.plugin_scn, df.foreign_dbid,
                  df.create_scn, df.dbinc_key, df.read_only, df.stop_scn
             FROM df, dbinc
            WHERE dbinc.db_key = p_db_key
              AND df.dbinc_key = dbinc.dbinc_key
              AND dbinc.dbinc_status != 'ORPHAN'
              AND (drop_scn IS NULL or drop_scn > c_baseline_untscn))
          WHERE rank = 1),
       last_offr_df AS  
--
       (SELECT * FROM 
          (SELECT RANK() OVER
               (PARTITION BY offr.file#, create_scn -- no plugin_scn
                ORDER BY offr.dbinc_key DESC) rank,
                  offr.file#, offr.create_scn, offr.offline_scn, 
                  offr.online_scn, offr.dbinc_key
             FROM offr, dbinc
            WHERE dbinc.db_key = p_db_key
              AND offr.dbinc_key = dbinc.dbinc_key
              AND dbinc.dbinc_status != 'ORPHAN'
              AND offr.online_scn >= c_baseline_untscn)
         WHERE rank = 1),
       df_attributes AS
--
       (SELECT dl.file#, dl.ts#, dl.create_scn, dl.foreign_dbid,
               dl.plugin_scn, dl.dbinc_key, dl.read_only, dl.stop_scn,
               lod.offline_scn, lod.online_scn
          FROM df_list dl LEFT OUTER JOIN last_offr_df lod
            ON dl.file# = lod.file#
           AND dl.create_scn = lod.create_scn
           AND dl.dbinc_key  = lod.dbinc_key),
       lf_backup AS      -- latest level 0 backup set for datafiles/cf/spfile
       (SELECT bs_key, bp_key, piece#, df_attributes.file#, 
               df_attributes.create_scn, df_attributes.plugin_scn, 
               df_attributes.foreign_dbid, df_attributes.read_only, 
               df_attributes.stop_scn, df_attributes.offline_scn, 
               df_attributes.online_scn, df_backup.ckp_scn, 
               df_backup.ckp_time
          FROM df_attributes LEFT OUTER JOIN df_backup
            ON df_attributes.file# = df_backup.file#
           AND df_attributes.create_scn = df_backup.create_scn
           AND df_attributes.plugin_scn = df_backup.plugin_scn
         UNION ALL
        SELECT bs_key, bp_key, piece#, 0, NULL, NULL, NULL, NULL, 
               NULL, NULL, NULL, ckp_scn, ckp_time
          FROM cf_backup
         UNION ALL
        SELECT bs_key, bp_key, piece#, -1, NULL, NULL, NULL, NULL, 
               NULL, NULL, NULL,
               NULL, modification_time ckp_time
          FROM sf_backup)
--
    SELECT lf.bs_key, lf.piece#, lf.bp_key, lf.file#, 
           lf.create_scn, lf.plugin_scn,
           lf.foreign_dbid, lf.read_only, lf.stop_scn, lf.offline_scn,
           lf.online_scn, lf.ckp_scn, lf.ckp_time,
           CASE 
             WHEN (s_c2t_optimization = 0)
             THEN NOT_COPIED_TO_TAPE
             WHEN EXISTS (SELECT 1 FROM sbt_task_history t
                           WHERE t.failure_cnt = 0
                             AND t.restore = 'N'
                             AND t.full_template_key = p_template_key
                             AND t.bs_key = lf.bs_key
                             AND t.piece# = lf.piece#)
             THEN COPIED_TO_TAPE
             WHEN EXISTS (SELECT 1 FROM sbt_task t
                           WHERE t.restore = 'N'
                             AND t.full_template_key = p_template_key
                             AND t.bs_key = lf.bs_key
                             AND t.piece# = lf.piece#)
             THEN COPIED_TO_TAPE
             ELSE NOT_COPIED_TO_TAPE
           END
           AS bs_copied2tape
      FROM lf_backup lf
  ORDER BY 1, 2;
 
  l_bs_key              NUMBER;
  l_piece_no            NUMBER;
  l_bp_key              NUMBER;
  l_file#               NUMBER;
  l_create_scn          NUMBER;
  l_plugin_scn          NUMBER;
  l_foreign_dbid        NUMBER;
  l_read_only           NUMBER;
  l_stop_scn            NUMBER;
  l_offline_scn         NUMBER;
  l_online_scn          NUMBER;
  l_ckp_scn             NUMBER;
  l_ckp_time            DATE;
  l_spawn_job           BOOLEAN;
  l_baseline_time       DATE;
  l_baseline_untscn     NUMBER := 0;
  l_queued_bs_key       NUMBER;
  l_queued_piece_no     NUMBER;
  l_baseline_scn        NUMBER;
  l_effective_ckp_scn   NUMBER;
  l_spfile_selected     BOOLEAN := FALSE;
  l_cffile_selected     BOOLEAN := FALSE;
  l_bs_copied2tape      NUMBER;
  l_cleanup_std         BOOLEAN := TRUE;
  l_recovery_window_sbt DATE;
  l_bp_start_time       DATE;
 
BEGIN
 
   trace1 ('queueBaseLevelBcks:Sending new baseline, template_key='||
           p_template_key || ' from_tag=' || p_from_tag ||
           ' db_key=' || p_db_key);
 
--
   baselineTimezone(p_db_key, l_baseline_time, l_baseline_untscn, 
                    l_recovery_window_sbt);
 
   BEGIN
      INSERT INTO sbt_template_db (db_key, template_key)
        VALUES(p_db_key, p_template_key);
   EXCEPTION
      WHEN dup_val_on_index THEN
         save_error;
         clear_error;
   END;
 
   OPEN bp_last_full_cursor(l_baseline_untscn);
   LOOP
      FETCH bp_last_full_cursor INTO l_bs_key, l_piece_no, l_bp_key, l_file#,
                                     l_create_scn, l_plugin_scn, 
                                     l_foreign_dbid, l_read_only, l_stop_scn,
                                     l_offline_scn, l_online_scn, l_ckp_scn,
                                     l_ckp_time, l_bs_copied2tape;
 
      EXIT WHEN bp_last_full_cursor%NOTFOUND;
 
      trace1 ('queueBaseLevelBcks: Found l_bs_key=' || l_bs_key ||
              ' l_piece_no=' || l_piece_no ||
              ' l_bp_key=' || l_bp_key ||
              ' l_file#=' || l_file# ||
              ' l_create_scn=' || l_create_scn ||
              ' l_plugin_scn=' || l_plugin_scn ||
              ' l_foreign_dbid=' || l_foreign_dbid ||
              ' l_read_only=' || l_read_only ||
              ' l_stop_scn=' || l_stop_scn ||
              ' l_offline_scn=' || l_offline_scn ||
              ' l_online_scn=' || l_online_scn ||
              ' l_ckp_scn=' || l_ckp_scn ||
              ' l_ckp_time=' || l_ckp_time ||
              ' l_bs_copied2tape=' || l_bs_copied2tape ||
              ' l_queued_bs_key=' || l_queued_bs_key ||
              ' l_queued_piece_no#=' || l_queued_piece_no); 
 
--
      IF (l_cleanup_std) THEN
        DELETE sbt_template_df 
         WHERE db_key = p_db_key
         AND template_key = p_template_key;
        trace1 ('queueBaseLevelBcks:deleted old rows=' || SQL%ROWCOUNT);
        l_cleanup_std := FALSE;
      END IF;
 
      BEGIN
         INSERT INTO sbt_template_df(
            template_key, db_key, df_file#, df_plugin_change#, df_foreign_dbid,
            df_creation_change#, bs_key, df_checkpoint_change#)
         VALUES (p_template_key, p_db_key, l_file#, l_plugin_scn,
                 l_foreign_dbid, l_create_scn, l_bs_key, l_ckp_scn);
      EXCEPTION
         WHEN DUP_VAL_ON_INDEX THEN
            NULL;
      END;
 
      IF l_file# = 0 THEN
         l_cffile_selected := TRUE;
      END IF;
 
      IF l_file# = -1 THEN
         l_spfile_selected := TRUE;
      END IF;
 
      IF l_bs_key IS NULL THEN
        trace1 ('queueBaseLevelBcks: no backup found for file' || l_file#);
        CONTINUE;
      END IF;
 
      IF p_baseline_scn = 0 AND l_read_only = 0 THEN
        IF (l_offline_scn < l_baseline_untscn AND 
          l_online_scn > l_baseline_untscn AND l_offline_scn = l_ckp_scn) THEN
           l_effective_ckp_scn := l_online_scn;   
        ELSE
           l_effective_ckp_scn := l_ckp_scn;
        END IF;
        IF (l_baseline_scn IS NULL OR 
            l_effective_ckp_scn < l_baseline_scn) THEN
           l_baseline_scn := l_effective_ckp_scn;
           trace1('queueBaseLevelBcks: computed l_baseline_scn moved to ' ||
                  l_baseline_scn);
        END IF;
      END IF;
 
--
--
--
      IF s_c2t_optimization = 1 AND
         l_bs_copied2tape = COPIED_TO_TAPE AND 
         l_read_only = 1 AND
         l_recovery_window_sbt IS NOT NULL THEN
        trace1('queueBaseLevelBcks: Read-only file l_bs_key=' || l_bs_key ||
               ' l_piece_no=' || l_piece_no); 
        IF (l_queued_bs_key IS NULL OR
            (l_queued_bs_key <> l_bs_key AND l_piece_no = 1)) THEN
          BEGIN
--
--
            SELECT max(start_time) INTO l_bp_start_time
              FROM bp
              WHERE bp.bs_key = l_bs_key
                AND bp.piece# = 1
                AND bp.template_key = p_template_key;
            trace1('queueBaseLevelBcks: Tape backup written time=' || 
                    l_bp_start_time);
            IF l_bp_start_time IS NULL THEN
               l_bp_start_time := l_recovery_window_sbt;
               trace1('queueBaseLevelBcks: set completion time to SBT window');
            END IF;
          END;
        END IF;
        IF l_bp_start_time <= l_recovery_window_sbt THEN
           l_bs_copied2tape := NOT_COPIED_TO_TAPE;
           trace1('queueBaseLevelBcks: copy again, piece outside SBT window');
        ELSE
           trace1('queueBaseLevelBcks: no copy, piece within SBT window');
        END IF;
      END IF;
 
--
      IF ((l_bs_copied2tape = NOT_COPIED_TO_TAPE) AND 
          (l_queued_bs_key IS NULL OR
           ((l_queued_bs_key = l_bs_key AND l_queued_piece_no <> l_piece_no) OR
           l_queued_bs_key <> l_bs_key))) THEN
        trace1('queueBaseLevelBcks: Queuing l_bs_key=' || l_bs_key ||
               ' l_piece_no=' || l_piece_no); 
 
        IF p_server_key  IS NOT NULL THEN
          create_replication_tasks(p_db_key => p_db_key,
                                   p_bs_key => l_bs_key,
                                   p_piece_no => l_piece_no,
                                   p_bp_key => l_bp_key,
                                   p_server_key => p_server_key );
        ELSE
          l_spawn_job := queue_one_sbt_backup_task(
                               p_db_key => p_db_key,
                               p_bs_key => l_bs_key,
                               p_piece_no => l_piece_no,
                               p_template_key => p_template_key,
                               p_full_template_key => p_template_key,
                               p_attr_set_key => p_attr_key,
                               p_lib_key => p_lib_key,
                               p_copies => p_copies,
                               p_src_bpkey => l_bp_key,
                               p_delete_source => p_delete_source,
                               p_format => p_format);
        END IF;
        l_queued_bs_key := l_bs_key;
        l_queued_piece_no := l_piece_no;
      END IF;
   END LOOP;
 
   CLOSE bp_last_full_cursor;
 
   IF p_baseline_scn = 0 THEN 
      p_baseline_scn := l_baseline_scn;
       UPDATE sbt_template_db
          SET baseline_scn   = p_baseline_scn
        WHERE db_key         = p_db_key
          AND template_key   = p_template_key
          AND s_c2t_optimization = 1;
       IF SQL%ROWCOUNT > 0 THEN
         trace1 ('queueBaseLevelBcks Re-setting baseline_scn to ' || 
                 p_baseline_scn);
       END IF;
   END IF;
 
   trace1 ('queueBaseLevelBcks p_baseline_scn=' || p_baseline_scn);
--
   UPDATE sbt_template_db
      SET last_bp_key    = p_max_bp_key, 
          curr_dbinc_key = p_currinc
    WHERE db_key         = p_db_key
      AND template_key   = p_template_key
      AND s_c2t_optimization = 1;
 
   IF SQL%ROWCOUNT > 0 THEN
     trace1 ('queueBaseLevelBcks setting last_bp_key to ' || 
             p_max_bp_key);
   END IF;
 
   trace1 ('queueBaseLevelBcks: updated sbt_template_db ' || SQL%ROWCOUNT);
 
   IF NOT l_cffile_selected THEN
      INSERT INTO sbt_template_df(template_key, db_key, df_file#)
         VALUES (p_template_key, p_db_key, 0);
   END IF;
 
   IF NOT l_spfile_selected THEN
      INSERT INTO sbt_template_df(template_key, db_key, df_file#)
         VALUES (p_template_key, p_db_key, -1);
   END IF;
 
   COMMIT;
 
 
END queueBaseLevelBcks;
 
--
--
PROCEDURE queueMissingDFBcks(p_db_key            IN NUMBER,
                             p_from_tag          IN VARCHAR2,
                             p_template_key      IN NUMBER,
                             p_baseline_scn      IN NUMBER,
                             p_lib_key           IN NUMBER,
                             p_attr_key          IN NUMBER,
                             p_copies            IN NUMBER,
                             p_delete_source     IN VARCHAR2,
                             p_format            IN VARCHAR2,
                             p_last_bp_key       IN NUMBER,
                             p_server_key        IN NUMBER) IS
  l_bs_key              NUMBER;
  l_piece_no            NUMBER;
  l_bp_key              NUMBER;
  l_queued_bs_key       NUMBER;
  l_queued_piece_no     NUMBER;
  l_spawn_job           BOOLEAN;
  l_df_file#            NUMBER;
  l_df_ckpscn#          NUMBER;
  l_df_crescn#          NUMBER;
  l_df_pc#              NUMBER;
  l_df_is_offline_cln   NUMBER;
  l_count               NUMBER;
 
--
--
  CURSOR bp_ndf_full_cursor IS
    WITH
       my_dbinc AS
       (SELECT dbinc_key, reset_scn, PRIOR reset_scn next_reset_scn 
          FROM dbinc START WITH dbinc_key = 
               (SELECT curr_dbinc_key from db where db_key=p_db_key) 
          CONNECT BY PRIOR parent_dbinc_key = dbinc_key),
       df_backup AS        -- datafile backups
       (SELECT * FROM 
          (SELECT RANK() over
                (PARTITION BY file#, create_scn, plugin_scn
                 ORDER BY ckp_scn DESC, bdf_key DESC) rank,
                bp.bs_key, bp.bp_key, bp.piece#, 
                bdf.ckp_scn df_checkpoint_change#, 
                stf.df_file#, stf.df_creation_change#, stf.df_plugin_change#
             FROM bp, bdf, my_dbinc, sbt_template_df stf
            WHERE bp.bp_key > p_last_bp_key  
              AND bp.bs_key = bdf.bs_key
              AND bdf.file# = stf.df_file#
              AND bdf.create_scn = stf.df_creation_change#
              AND bdf.plugin_scn = stf.df_plugin_change#
              AND bdf.foreign_dbid = stf.df_foreign_dbid
              AND stf.template_key = p_template_key
              AND stf.db_key = p_db_key
              AND bp.db_key = p_db_key
              AND (stf.bs_key IS NULL OR stf.bs_key = -1)
              AND bp.lib_key IS NULL
              AND (p_from_tag IS NULL OR bp.tag = p_from_tag)
              AND bp.template_key IS NULL
              AND bp.ba_access IN ('D', 'L')
              AND bp.status != 'D'
--
--
--
--
              AND bp.vb_key IS NOT NULL
              AND bdf.incr_scn <= bdf.create_scn
              AND bdf.dbinc_key = my_dbinc.dbinc_key
              AND (decode(bdf.abs_fuzzy_scn, 0, bdf.ckp_scn, bdf.abs_fuzzy_scn)
                      < my_dbinc.next_reset_scn OR
                   my_dbinc.next_reset_scn IS NULL))
         WHERE rank = 1),
       cf_backup AS       -- latest controlfile backup
       (SELECT * FROM
          (SELECT RANK() over
               (ORDER BY ckp_scn DESC, bcf_key DESC) rank,
               bp.bs_key,
               bp.bp_key,
               bp.piece#,
               bcf.ckp_scn,
               bcf.ckp_time
          FROM bp, bcf, my_dbinc, sbt_template_df stf
         WHERE bp.bs_key = bcf.bs_key
           AND bp.lib_key IS NULL
           AND bp.bp_key > p_last_bp_key  
           AND stf.df_file# = 0
           AND stf.template_key = p_template_key
           AND stf.db_key = p_db_key
           AND bp.db_key = p_db_key
           AND (stf.bs_key IS NULL OR stf.bs_key = -1)
           AND bp.ba_access IN ('D', 'L')
           AND bp.status != 'D'
           AND (p_from_tag IS NULL OR bp.tag = p_from_tag)
           AND bcf.dbinc_key = my_dbinc.dbinc_key
           AND (bcf.ckp_scn < my_dbinc.next_reset_scn OR
                my_dbinc.next_reset_scn IS NULL))
         WHERE rank=1),
       sf_backup AS      -- latest spfile backup
       (SELECT * FROM
          (SELECT RANK() over
               (ORDER BY modification_time DESC) rank,
               bp.bs_key,
               bp.bp_key,
               bp.piece#,
               bsf.modification_time
          FROM bp, bsf, sbt_template_df stf
         WHERE bp.bs_key = bsf.bs_key
           AND bp.lib_key IS NULL
           AND bp.bp_key > p_last_bp_key  
           AND stf.df_file# = -1
           AND stf.template_key = p_template_key
           AND stf.db_key = p_db_key
           AND bp.db_key = p_db_key
           AND (stf.bs_key IS NULL OR stf.bs_key = -1)
           AND bp.ba_access IN ('D', 'L')
           AND bp.status != 'D'
           AND (p_from_tag IS NULL OR bp.tag = p_from_tag)
           AND bsf.db_key = p_db_key)
        WHERE rank=1),
       ndf_backup AS      -- latest backup for all missing files
         (SELECT bs_key, piece#, bp_key,
                 df_file#, df_creation_change#, df_plugin_change#,
                 df_checkpoint_change#
            FROM df_backup         
           UNION ALL
          SELECT bs_key, piece#, bp_key, 0, NULL, NULL, ckp_scn
            FROM cf_backup
           UNION ALL
          SELECT bs_key, piece#, bp_key, -1, NULL, NULL, NULL 
            FROM sf_backup)
       SELECT ndf.bs_key, ndf.piece#, ndf.bp_key, ndf.df_file#, 
              ndf.df_creation_change#, ndf.df_plugin_change#,
              ndf.df_checkpoint_change#
         FROM ndf_backup ndf
        WHERE ((s_c2t_optimization = 0) OR
               (s_c2t_optimization = 1 AND
                 NOT EXISTS (SELECT 1 FROM sbt_task_history t
                              WHERE t.failure_cnt = 0
                                AND t.restore = 'N'
                                AND t.full_template_key = p_template_key
                                AND t.bs_key = ndf.bs_key
                                AND t.piece# = ndf.piece#)
                 AND NOT EXISTS (SELECT 1 FROM sbt_task t
                              WHERE t.restore = 'N'
                                AND t.full_template_key = p_template_key
                                AND t.bs_key = ndf.bs_key
                                AND t.piece# = ndf.piece#)))
  ORDER BY 1, 2;
 
BEGIN
   trace1 ('queueMissingDFBcks: Sending missing bcks, template_key=' ||
           p_template_key || ' from_tag=' || p_from_tag ||
           ' db_key=' || p_db_key);
--
   MERGE INTO sbt_template_df a
   USING (SELECT DISTINCT p_db_key db_key, file#, ts#, plugin_scn, 
                 foreign_dbid, create_scn FROM df
           WHERE decode(foreign_dbid, 0, create_scn, 
                        plugin_scn) > p_baseline_scn
             AND dbinc_key in (select dbinc_key from dbinc
                                where db_key = p_db_key
                                  and dbinc_status <> 'ORPHAN')) b
   ON (a.db_key = b.db_key 
       AND a.template_key = p_template_key
       AND  a.df_file# = b.file# 
       AND a.df_plugin_change# = b.plugin_scn     
       AND a.df_foreign_dbid = b.foreign_dbid     
       AND a.df_creation_change# = b.create_scn)
   WHEN NOT MATCHED THEN
   INSERT   (a.db_key, a.df_file#, a.df_ts#, a.df_plugin_change#, 
             a.df_foreign_dbid, a.df_creation_change#, a.template_key)
     VALUES (b.db_key, b.file#, b.ts#, b.plugin_scn,
             b.foreign_dbid, b.create_scn, p_template_key);
   IF SQL%ROWCOUNT > 0 THEN
      COMMIT;
      trace1 ('queueMissingDFBcks: row mergred =' || SQL%ROWCOUNT);
   END IF;
 
--
--
   OPEN bp_ndf_full_cursor;
   LOOP
      FETCH bp_ndf_full_cursor 
         INTO l_bs_key, l_piece_no, l_bp_key, l_df_file#, l_df_crescn#, 
              l_df_pc#, l_df_ckpscn#;
      EXIT WHEN bp_ndf_full_cursor%NOTFOUND;
 
--
      IF l_df_ckpscn# < p_baseline_scn THEN
         SELECT COUNT(*) INTO l_df_is_offline_cln 
           FROM DF
          WHERE dbinc_key = 
                (SELECT curr_dbinc_key FROM db WHERE db_key = p_db_key)
            AND drop_scn IS NOT NULL
            AND stop_scn IS NOT NULL
            AND file# = l_df_file#
            AND create_scn = l_df_crescn#
            AND plugin_scn = l_df_pc#;
         IF l_df_is_offline_cln = 0 THEN
            CONTINUE;
         END IF;
      END IF;
 
      trace1 ('queueMissingDFBcks: Found l_bs_key=' || l_bs_key ||
              ' l_piece_no=' || l_piece_no ||
              ' l_df_file#=' || l_df_file# ||
              ' l_df_crescn#=' || l_df_crescn# ||
              ' l_df_pc#=' || l_df_pc# ||
              ' l_queued_bs_key=' || l_queued_bs_key ||
              ' l_queued_piece_no#=' || l_queued_piece_no ||
              ' l_df_ckpscn#=' || l_df_ckpscn#);
 
      IF (l_queued_bs_key IS NULL OR
          ((l_queued_bs_key = l_bs_key AND l_queued_piece_no <> l_piece_no) OR
           l_queued_bs_key <> l_bs_key)) THEN
          trace1('queueMissingDFBcks: Queuing l_bs_key=' || l_bs_key ||
                  ' l_piece_no=' || l_piece_no);
         IF p_server_key  IS NOT NULL THEN
           create_replication_tasks(p_db_key => p_db_key,
                                    p_bs_key => l_bs_key,
                                    p_piece_no => l_piece_no,
                                    p_bp_key => l_bp_key,
                                    p_server_key => p_server_key );
         ELSE
           l_spawn_job := queue_one_sbt_backup_task(
                                p_db_key => p_db_key,
                                p_bs_key => l_bs_key,
                                p_piece_no => l_piece_no,
                                p_template_key => p_template_key,
                                p_full_template_key => p_template_key,
                                p_attr_set_key => p_attr_key,
                                p_lib_key => p_lib_key,
                                p_copies => p_copies,
                                p_src_bpkey => l_bp_key,
                                p_delete_source => p_delete_source,
                                p_format => p_format);
         END IF;
         l_queued_bs_key := l_bs_key;
         l_queued_piece_no := l_piece_no;
      END IF;
 
--
      UPDATE sbt_template_df 
         SET bs_key = l_bs_key,
             df_checkpoint_change# = l_df_ckpscn#
         WHERE db_key = p_db_key 
           AND df_file# = l_df_file#
           AND (df_creation_change# = l_df_crescn# OR l_df_file# <= 0)
           AND (df_plugin_change# = l_df_pc# OR l_df_file# <= 0)
           AND (bs_key IS NULL or bs_key = -1)
           AND template_key = p_template_key;
 
      IF SQL%ROWCOUNT = 1 THEN 
         trace1 ('queueMissingDFBcks: setting bs_key=' || l_bs_key ||
                 'for datafile '|| l_df_file#);
      ELSE
         SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(E_INTERNAL_ERROR_NUM, 
               'queueMissingDFBcks ' || SQL%ROWCOUNT ||
               ' for datafile '|| l_df_file#);
      END IF;
   END LOOP;
 
   CLOSE bp_ndf_full_cursor;
 
   COMMIT;
END queueMissingDFBcks;
 
--
--
PROCEDURE  logMissingDfBcksError(p_db_key        IN NUMBER,
                                 p_currinc       IN NUMBER,
                                 p_template_key  IN NUMBER) IS
   l_cnt_mdf   NUMBER;
BEGIN
--
--
--
--
--
--
   UPDATE sbt_template_df SET bs_key = -1
     WHERE bs_key IS NULL 
       AND db_key = p_db_key
       AND template_key = p_template_key
       AND NOT EXISTS
         (SELECT 1 FROM df
           WHERE df.dbinc_key = p_currinc
             AND df.drop_scn is null
             AND df.file# = df_file# 
             AND df.create_scn = df_creation_change#
             AND df.plugin_scn = df_plugin_change#
             AND df.foreign_dbid = df_foreign_dbid)
        AND sbt_template_df.df_file# <> 0;
 
   IF SQL%ROWCOUNT > 0 THEN 
      trace1 ('logMissingDfBcksError: dropped sbt_template_df count=' ||
              SQL%ROWCOUNT);
      COMMIT;
   END IF;
 
   SELECT count(*) INTO l_cnt_mdf
      FROM sbt_template_df
      WHERE db_key = p_db_key
        AND template_key = p_template_key
        AND df_file# <> -1   -- tolerate non-existence of SPFile Bck
        AND bs_key IS NULL;
 
--
   IF (l_cnt_mdf = 0) THEN
      fix_error(p_error_num => E_FULL_BACKUP_NOT_FOUND_NUM,
                p_db_key    => p_db_key);
      trace1('logMissingDfBcksError: fixing E_FULL_BACKUP_NOT_FOUND_NUM');
   ELSE
      log_error(p_errno     => E_FULL_BACKUP_NOT_FOUND_NUM,
                p_db_key    => p_db_key,
                p_param1    => dbms_ra_int.dbkey2name(p_db_key),
                p_component => 'SBT_FULL_BACKUP',
                p_severity  => SEVERITY_WARNING);
      trace1 ('logMissingDfBcksError: datafile files missing backup');
   END IF;
   
END logMissingDfBcksError;
 
--
--
PROCEDURE queueIncrementalBcks(p_db_key            IN NUMBER,
                               p_from_tag          IN VARCHAR2,
                               p_template_key      IN NUMBER,
                               p_full_template_key IN NUMBER,
                               p_baseline_scn      IN NUMBER,
                               p_lib_key           IN NUMBER,
                               p_attr_key          IN NUMBER,
                               p_copies            IN NUMBER,
                               p_delete_source     IN VARCHAR2,
                               p_format            IN VARCHAR2,
                               p_init_cf_bs_key    IN NUMBER,
                               p_last_bp_key       IN NUMBER,
                               p_server_key        IN NUMBER) IS
 
--
--
  CURSOR bp_incr_cursor IS
    WITH
       new_bp AS
       (SELECT bp.bs_key, bp.piece#, bp.bp_key, bp.vb_key
          FROM bp, bs
         WHERE bp.db_key = p_db_key
           AND bp.bp_key > p_last_bp_key  
           AND bp.bs_key = bs.bs_key
           AND (p_from_tag IS NULL OR bp.tag = p_from_tag)
           AND bp.lib_key  IS NULL
           AND bp.template_key  IS NULL
           AND bp.ba_access IN ('D', 'L')
           AND bp.status != 'D'
           AND bs.bck_type IN ('I', 'D')
           AND bs.keep_options = 0
       ),
       sf_backup AS      -- latest spfile backup, when p_last_bp_key=0
       (SELECT * FROM
          (SELECT RANK() over
               (ORDER BY modification_time DESC, bsf_key DESC) rank,
               bp.bs_key,
               bp.bp_key,
               bp.piece#,
               bsf.modification_time
          FROM bp, bsf
         WHERE bp.bs_key = bsf.bs_key
           AND p_last_bp_key = 0
           AND bp.bp_key > p_last_bp_key
           AND bp.lib_key IS NULL
           AND bp.ba_access IN ('D', 'L')
           AND bp.status != 'D'
           AND (p_from_tag IS NULL OR bp.tag = p_from_tag)
           AND bsf.db_key = p_db_key)
        WHERE rank=1),
       incr_backup AS        
       (SELECT new_bp.bs_key, new_bp.piece#, new_bp.bp_key
          FROM new_bp, bdf
         WHERE bdf.bs_key = new_bp.bs_key
--
--
--
--
           AND new_bp.vb_key IS NOT NULL
           AND bdf.incr_scn > bdf.create_scn
           AND bdf.incr_scn >= p_baseline_scn
        UNION ALL
        SELECT new_bp.bs_key, new_bp.piece#, new_bp.bp_key
          FROM new_bp, bcf
         WHERE bcf.bs_key = new_bp.bs_key
           AND bcf.ckp_scn >= p_baseline_scn
        UNION ALL
        SELECT new_bp.bs_key, new_bp.piece#, new_bp.bp_key
          FROM new_bp, bsf
         WHERE bsf.bs_key = new_bp.bs_key
           AND p_last_bp_key > 0
--
--
--
--
        UNION ALL
        SELECT bs_key, piece#, bp_key
          FROM sf_backup)
--
    SELECT ib.bs_key, ib.piece#, ib.bp_key
      FROM incr_backup ib 
     WHERE ((s_c2t_optimization = 0) OR
            (s_c2t_optimization = 1 
             AND NOT EXISTS (SELECT 1 FROM sbt_task_history t
                              WHERE t.failure_cnt = 0
                                AND t.restore = 'N'
                                AND t.full_template_key  = p_full_template_key
                                AND t.bs_key = ib.bs_key
                                AND t.piece# = ib.piece#)
             AND NOT EXISTS (SELECT 1 FROM sbt_task t
                              WHERE t.restore = 'N'
                                AND t.full_template_key = p_full_template_key
                                AND t.bs_key = ib.bs_key
                                AND t.piece# = ib.piece#)))
  ORDER BY 1, 2;
 
  l_bs_key              NUMBER;
  l_piece_no            NUMBER;
  l_bp_key              NUMBER;
  l_spawn_job           BOOLEAN;
  l_queued_bs_key       NUMBER;
  l_queued_piece_no     NUMBER;
 
BEGIN
   trace1('queueIncrementalBcks: Sending Incrementals, template_key='||
           p_template_key || ' from_tag=' || p_from_tag ||
           ' db_key=' || p_db_key);
   OPEN bp_incr_cursor;
   LOOP
      FETCH bp_incr_cursor INTO l_bs_key, l_piece_no, l_bp_key;
      EXIT WHEN bp_incr_cursor%NOTFOUND;
      trace1('queueIncrementalBcks: l_bs_key=' || l_bs_key ||
                                  ' l_piece_no=' || l_piece_no ||
                                  ' l_bp_key=' || l_bp_key ||
                                  ' l_queued_bs_key=' || l_queued_bs_key ||
                                  ' l_queued_piece_no#=' || l_queued_piece_no);
 
      IF (l_queued_bs_key IS NULL OR
          ((l_queued_bs_key = l_bs_key AND l_queued_piece_no <> l_piece_no) OR
           l_queued_bs_key <> l_bs_key)) THEN
          trace1('queueIncrementalBcks: Queuing l_bs_key=' || l_bs_key ||
                  ' l_piece_no=' || l_piece_no);
        IF p_server_key  IS NOT NULL THEN
          create_replication_tasks(p_db_key => p_db_key,
                                   p_bs_key => l_bs_key,
                                   p_piece_no => l_piece_no,
                                   p_bp_key => l_bp_key,
                                   p_server_key => p_server_key );
        ELSE
          l_spawn_job := queue_one_sbt_backup_task(
                               p_db_key => p_db_key,
                               p_bs_key => l_bs_key,
                               p_piece_no => l_piece_no,
                               p_template_key => p_template_key,
                               p_full_template_key => p_full_template_key,
                               p_attr_set_key => p_attr_key,
                               p_lib_key => p_lib_key,
                               p_copies => p_copies,
                               p_src_bpkey => l_bp_key,
                               p_delete_source => p_delete_source,
                               p_format => p_format);
        END IF;
        l_queued_bs_key := l_bs_key;
        l_queued_piece_no := l_piece_no;
      END IF;
 
      IF p_init_cf_bs_key > 0  THEN
         UPDATE sbt_template_df SET bs_key = l_bs_key
           WHERE template_key = p_template_key
             AND db_key       = p_db_key
             AND df_file#     = 0
             AND bs_key       IS NULL
             AND EXISTS (SELECT bcf.bcf_key FROM bcf
                            WHERE bs_key = l_bs_key); 
         UPDATE sbt_template_df SET bs_key = l_bs_key
           WHERE template_key = p_template_key
             AND db_key       = p_db_key
             AND df_file#     = -1
             AND bs_key       IS NULL
             AND EXISTS (SELECT bsf.bsf_key FROM bsf
                            WHERE bs_key = l_bs_key); 
         COMMIT;
      END IF;
   END LOOP;
   CLOSE bp_incr_cursor;
 
END queueIncrementalBcks;
 
--
--
PROCEDURE queueArchivedLogBcks(p_db_key            IN NUMBER,
                               p_from_tag          IN VARCHAR2,
                               p_template_key      IN NUMBER,
                               p_full_template_key IN NUMBER,
                               p_baseline_scn      IN NUMBER,
                               p_lib_key           IN NUMBER,
                               p_attr_key          IN NUMBER,
                               p_copies            IN NUMBER,
                               p_delete_source     IN VARCHAR2,
                               p_format            IN VARCHAR2,
                               p_init_cf_bs_key    IN NUMBER,
                               p_last_bp_key       IN NUMBER,
                               p_server_key        IN NUMBER) IS
 
--
--
  CURSOR bp_arch_cursor IS
    WITH
       new_bp AS
       (SELECT bp.bs_key, bp.piece#, bp.bp_key
          FROM bp, bs
         WHERE bp.db_key = p_db_key
           AND bp.bp_key > p_last_bp_key  
           AND bp.bs_key = bs.bs_key
           AND (p_from_tag IS NULL OR bp.tag = p_from_tag)
           AND bp.lib_key  IS NULL
           AND bp.ba_access IN ('D', 'L')
           AND bp.status != 'D'
           AND bs.keep_options = 0
       ),      
       arch_backup AS
       (SELECT new_bp.bs_key, new_bp.piece#, new_bp.bp_key
          FROM new_bp, brl
         WHERE brl.bs_key = new_bp.bs_key
           AND brl.next_scn >= p_baseline_scn
        UNION ALL
        SELECT new_bp.bs_key, new_bp.piece#, new_bp.bp_key
          FROM new_bp, bcf
         WHERE bcf.bs_key = new_bp.bs_key
           AND bcf.ckp_scn >= p_baseline_scn
        UNION ALL
        SELECT new_bp.bs_key, new_bp.piece#, new_bp.bp_key
          FROM new_bp, bsf
         WHERE bsf.bs_key = new_bp.bs_key)
--
    SELECT ab.bs_key, ab.piece#, ab.bp_key
      FROM arch_backup ab
     WHERE ((s_c2t_optimization = 0) OR
            (s_c2t_optimization = 1 
             AND NOT EXISTS (SELECT 1 FROM sbt_task_history t
                              WHERE t.failure_cnt = 0
                                AND t.restore = 'N'
                                AND t.full_template_key  = p_full_template_key
                                AND t.bs_key = ab.bs_key
                                AND t.piece# = ab.piece#)
             AND NOT EXISTS (SELECT 1 FROM sbt_task t
                              WHERE t.restore = 'N'
                                AND t.full_template_key = p_full_template_key
                                AND t.bs_key = ab.bs_key
                                AND t.piece# = ab.piece#)))
  ORDER BY 1, 2;
  l_bs_key              NUMBER;
  l_piece_no            NUMBER;
  l_bp_key              NUMBER;
  l_spawn_job           BOOLEAN;
  l_queued_bs_key       NUMBER;
  l_queued_piece_no     NUMBER;
 
BEGIN
 
   trace1('queueArchivedLogBcks: Sending archivelog bcks, template_key='||
           p_template_key || ' from_tag=' || p_from_tag ||
           ' db_key=' || p_db_key);
   OPEN bp_arch_cursor;
   LOOP
      FETCH bp_arch_cursor INTO l_bs_key, l_piece_no, l_bp_key;
      EXIT WHEN bp_arch_cursor%NOTFOUND;
      trace1('queueArchivedLogBcks: l_bs_key=' || l_bs_key ||
                                  ' l_piece_no=' || l_piece_no ||
                                  ' l_bp_key=' || l_bp_key ||
                                  ' l_queued_bs_key=' || l_queued_bs_key ||
                                  ' l_queued_piece_no#=' || l_queued_piece_no);
      IF (l_queued_bs_key IS NULL OR
          ((l_queued_bs_key = l_bs_key AND l_queued_piece_no <> l_piece_no) OR
           l_queued_bs_key <> l_bs_key)) THEN
          trace1('queueBaseLevelBcks: Queuing l_bs_key=' || l_bs_key ||
                  ' l_piece_no=' || l_piece_no);
        IF p_server_key  IS NOT NULL THEN
          create_replication_tasks(p_db_key => p_db_key,
                                   p_bs_key => l_bs_key,
                                   p_piece_no => l_piece_no,
                                   p_bp_key => l_bp_key,
                                   p_server_key => p_server_key );
        ELSE
          l_spawn_job := queue_one_sbt_backup_task(
                               p_db_key => p_db_key,
                               p_bs_key => l_bs_key,
                               p_piece_no => l_piece_no,
                               p_template_key => p_template_key,
                               p_full_template_key => p_full_template_key,
                               p_attr_set_key => p_attr_key,
                               p_lib_key => p_lib_key,
                               p_copies => p_copies,
                               p_src_bpkey => l_bp_key,
                               p_delete_source => p_delete_source,
                               p_format => p_format);
        END IF;
        l_queued_bs_key := l_bs_key;
        l_queued_piece_no := l_piece_no;
      END IF;
 
      IF p_init_cf_bs_key > 0  THEN
         UPDATE sbt_template_df SET bs_key = l_bs_key
           WHERE template_key = p_template_key
             AND db_key       = p_db_key
             AND df_file#     = 0
             AND bs_key       IS NULL
             AND EXISTS (SELECT bcf.bcf_key FROM bcf
                            WHERE bs_key = l_bs_key); 
         UPDATE sbt_template_df SET bs_key = l_bs_key
           WHERE template_key = p_template_key
             AND db_key       = p_db_key
             AND df_file#     = -1
             AND bs_key       IS NULL
             AND EXISTS (SELECT bsf.bsf_key FROM bsf
                            WHERE bs_key = l_bs_key); 
         COMMIT;
      END IF;
   END LOOP;
   CLOSE bp_arch_cursor;
END queueArchivedLogBcks;
 
--
--
PROCEDURE queueKeepBcks (p_db_key            IN NUMBER,
                         p_from_tag          IN VARCHAR2,
                         p_template_key      IN NUMBER,
                         p_baseline_scn      IN NUMBER,
                         p_lib_key           IN NUMBER,
                         p_attr_key          IN NUMBER,
                         p_copies            IN NUMBER,
                         p_delete_source     IN VARCHAR2,
                         p_format            IN VARCHAR2,
                         p_last_bp_key       IN NUMBER,
                         p_server_key        IN NUMBER) IS
 
  l_bs_key              NUMBER;
  l_piece_no            NUMBER;
  l_spawn_job           BOOLEAN;
  l_baseline_untscn     NUMBER;
  l_baseline_time       DATE;
  l_recovery_window_sbt DATE;
 
--
--
  CURSOR bp_all_keep_cursor IS
    SELECT DISTINCT bp.bs_key, bp.piece#
      FROM bp, bs
     WHERE bp.db_key = p_db_key
       AND bp.bs_key = bs.bs_key
       AND bp.template_key  IS NULL
       AND bp.lib_key  IS NULL
       AND bp.ba_access IN ('D', 'L')
       AND bp.status != 'D'
       AND ((p_last_bp_key = 0 AND bp.completion_time > l_baseline_time) OR
            (p_last_bp_key > 0 AND bp.bp_key > p_last_bp_key))
       AND bs.keep_options > 0
       AND (p_from_tag IS NULL OR bp.tag = p_from_tag)
       AND ((s_c2t_optimization = 0) OR
            (s_c2t_optimization = 1
             AND NOT EXISTS (SELECT 1 FROM sbt_task_history t
                              WHERE t.failure_cnt = 0
                                AND t.restore = 'N'
                                AND t.full_template_key  = p_template_key
                                AND t.bs_key = bp.bs_key
                                AND t.piece# = bp.piece#)
             AND NOT EXISTS (SELECT 1 FROM sbt_task t
                              WHERE t.restore = 'N'
                                AND t.full_template_key = p_template_key
                                AND t.bs_key = bp.bs_key
                                AND t.piece# = bp.piece#)))
   ORDER BY 1, 2;
 
BEGIN
 
    IF (p_server_key IS NULL) THEN
       trace1('queueKeepBcks : returning as server_key is null');
       RETURN;
    END IF;
    trace1('queueKeepBcks : Sending KEEP backups, template_key='||
           p_template_key || ' from_tag=' || p_from_tag ||
           ' db_key=' || p_db_key);
 
--
    baselineTimezone(p_db_key, l_baseline_time, l_baseline_untscn, 
                     l_recovery_window_sbt);
 
    OPEN bp_all_keep_cursor;
    LOOP
       FETCH bp_all_keep_cursor INTO l_bs_key, l_piece_no;
       EXIT WHEN bp_all_keep_cursor%NOTFOUND;
       trace1('queueKeepBcks: l_bs_key=' || l_bs_key ||
              ' l_piece_no=' || l_piece_no);
       create_replication_tasks(p_db_key => p_db_key,
                                p_bs_key => l_bs_key,
                                p_piece_no => l_piece_no,
                                p_server_key => p_server_key );
    END LOOP;
    CLOSE bp_all_keep_cursor;
END queueKeepBcks;
 
PROCEDURE invalidateTemplateBackup(p_bs_key       IN NUMBER,
                                   p_bp_key       IN NUMBER,
                                   p_db_key       IN NUMBER,
                                   p_template_key IN NUMBER) IS
BEGIN
--
   UPDATE sbt_template_df stf
      SET bs_key = NULL, 
          df_checkpoint_change# = NULL
      WHERE stf.db_key = p_db_key
        AND stf.template_key = p_template_key
        AND stf.bs_key = p_bs_key;
    
   IF SQL%ROWCOUNT > 0 THEN
      trace1 ('invalidateTemplateBackup: updated sbt_template_df' || 
              SQL%ROWCOUNT);
      log_error(p_errno     => E_FULL_BACKUP_NOT_FOUND_NUM,
                p_db_key    => p_db_key,
                p_param1    => dbms_ra_int.dbkey2name(p_db_key),
                p_component => 'SBT_FULL_BACKUP',
                p_severity  => SEVERITY_WARNING);
      trace1 ('invalidateTemplateBackup: bs_key ' || p_bs_key ||
              ' db_key ' || p_db_key || ' bp_key ' || p_bp_key ||
              ' template_key ' || p_template_key || ' not copied to tape');
   END IF;
 
--
--
   UPDATE sbt_template_db std
      SET std.last_bp_key = p_bp_key - 1
    WHERE std.db_key = p_db_key
      AND std.template_key = p_template_key
      AND std.last_bp_key >= p_bp_key
      AND s_c2t_optimization = 1;
 
   IF SQL%ROWCOUNT = 1 THEN
      trace1 ('invalidateTemplateBackup: updated one sbt_template_db row');
   END IF;
END invalidateTemplateBackup;
 
 
--
--
--
--
--
--
--
--
--
--
--
--
--
FUNCTION check_do_pending_rep_setup(p_db_key IN VARCHAR2) RETURN BOOLEAN
IS
  l_db_key                  NUMBER;
  l_prot_key                NUMBER;
  l_ckpt                    NUMBER;
  l_template_name           sbt_job_template.template_name%TYPE;
  l_prot_name               prot.prot_name%TYPE;
  l_lib_key                 NUMBER;
  l_pending_rep_setup       VARCHAR2(1);
  l_obj_type                VARCHAR2(128);
  l_obj_name                VARCHAR2(128);
  l_rv                      BOOLEAN := FALSE;
  l_all_reconciled          BOOLEAN := TRUE;
  l_all_replicated          BOOLEAN := TRUE;
  l_db_unique_name          node.db_unique_name%TYPE;
  l_lockflag                BOOLEAN;
  l_rec_cnt                 NUMBER; -- num we reconciled against
  l_exp_rec_cnt             NUMBER; -- num we expected to reconcile against
  l_rep_atr_name            sbt_attr_set.attr_name%TYPE;
BEGIN
  IF p_db_key IS NULL THEN
    trace1 ('CHECK_DO_PENDING_REP_SETUP: required db_key missing.');
    SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(E_INTERNAL_ERROR_NUM,
                                   'cannot complete rep setup without a dbkey');
  END IF;
 
  l_db_key := p_db_key;
  l_db_unique_name := dbms_ra_int.dbkey2name(l_db_key);
 
--
--
--
--
--
--
--
  l_lockflag := SYS.KBRSI_ICD.RSKEYWRITELOCK (l_db_key, TRUE);
 
  SELECT pending_rep_setup, prot_key
    INTO l_pending_rep_setup, l_prot_key
    FROM odb o
    WHERE o.db_key = l_db_key;
 
  trace1 ('CHECK_DO_PENDING_REP_SETUP: write lock on db_key=' || l_db_key ||
          ', pending_rep_setup=' || l_pending_rep_setup ||
          ', got_lock=' || print(l_lockflag));
 
--
  IF l_pending_rep_setup <> 'Y' THEN
    IF l_lockflag THEN
      SYS.KBRSI_ICD.RSKEYUNLOCK(l_db_key);
    END IF;
    RETURN TRUE;
  END IF;
 
  trace1 ('CHECK_DO_PENDING_REP_SETUP: Completing rep setup for ' ||
          l_db_unique_name || '(' || l_db_key || ')');
 
  SELECT prot_name
    INTO l_prot_name
    FROM prot
    WHERE prot_key=l_prot_key;
 
  SELECT count(*) INTO l_exp_rec_cnt FROM rep_server rs, odb o
    WHERE rs.prot_key = l_prot_key
      AND o.prot_key = rs.prot_key
      AND o.db_key = l_db_key;
 
  IF l_exp_rec_cnt > 0 THEN
    trace1 ('CHECK_DO_PENDING_REP_SETUP: Expecting to reconcile ' ||
            l_exp_rec_cnt || ' replication servers');
 
    FOR f IN (SELECT rs.server_key, s.rep_server_name
                FROM rep_server rs, server s
               WHERE prot_key=l_prot_key
                 AND s.server_key = rs.server_key)
    LOOP
    BEGIN
      l_rv := reconcile_db (p_db_key          => l_db_key,
                            p_server_key      => f.server_key,
                            p_only_active     => FALSE,
                            p_force_reconcile => TRUE,
                            rec_cnt           => l_rec_cnt);
      trace1('CHECK_DO_PENDING_REP_SETUP: reconcile complete. rv='||
             print(l_rv) ||
             ' actual_reconcile count=' || l_rec_cnt ||
             ', expected_reconcile=' || l_exp_rec_cnt);
 
      IF NOT l_rv OR l_rec_cnt = 0 THEN
        trace1('CHECK_DO_PENDING_REP_SETUP: not all reconciled');
        l_all_reconciled := FALSE;
        dbms_ra_scheduler.log_error(p_errno   => dbms_ra.REP_SETUP_ERROR_NUM,
                          p_db_key  => l_db_key,
                          p_param1  => 'complete_setup_reconcile_' || l_rec_cnt,
                          p_param2  => f.rep_server_name,
                          p_param3  => l_db_unique_name,
                          P_keep_stack => FALSE,
                          p_component =>'REPLICATION_RECONCILE',
                          p_severity => dbms_ra_scheduler.SEVERITY_ERROR,
                          p_param_char => 'RECONCILE');
      END IF;
    END;
    END LOOP;
 
    IF l_all_reconciled AND l_rec_cnt = l_exp_rec_cnt THEN
      fix_error (p_error_num  => dbms_ra.REP_SETUP_ERROR_NUM,
                 p_db_key     => l_db_key,
                 p_param_char => 'RECONCILE');
    END IF;
  ELSE
    l_all_reconciled := FALSE;
    trace1('CHECK_DO_PENDING_REP_SETUP: No dbs to reconcile.' ||
           'Aborting completion of replication setup');
  END IF;
 
--
  IF l_all_reconciled THEN
--
--
    UPDATE odb
      SET pending_rep_setup = 'N'
      WHERE db_key = l_db_key;
    COMMIT;
 
    FOR f IN (SELECT rs.server_key, s.rep_server_name
                FROM rep_server rs, server s
               WHERE prot_key=l_prot_key
                 AND s.server_key = rs.server_key)
    LOOP
    BEGIN
      l_ckpt := 4;
--
      dbms_ra_scheduler.queue_set_reconcile_timer (l_db_key);
 
      l_ckpt := 5;
--
--
--
      l_template_name := dbms_ra_int.build_rep_tpl_name (
                                             rep_srv_name => f.rep_server_name,
                                             db_key       => l_db_key,
                                             prot_key     => l_prot_key);
 
      trace1 ('CHECK_DO_PENDING_REP_SETUP: Creating template ' ||
                  l_template_name);
      BEGIN
        l_rep_atr_name := dbms_ra_int.build_rep_atr_name(f.rep_server_name);
        dbms_ra_int.create_sbt_job_template_int(template_name =>l_template_name,
                                            db_unique_name => l_db_unique_name,
                                            attr_name      => l_rep_atr_name,
                                            backup_type    => 'ALL',
                                            do_commit      => TRUE);
      EXCEPTION
        WHEN DBMS_RA.DUP_NAME THEN
--
          save_error;
          clear_error;
      END;
 
      trace1 ('CHECK_DO_PENDING_REP_SETUP: Queueing replicate_existing '||
              'for db=' ||l_db_unique_name || ', rep_srvr=' ||
              f.rep_server_name);
 
      dbms_ra_scheduler.replicate_existing_backups(
                                            p_template_name => l_template_name);
 
    EXCEPTION
      WHEN OTHERS THEN
        l_all_replicated := FALSE;
--
--
 
        dbms_ra_scheduler.log_error (p_errno => dbms_ra.REP_SETUP_ERROR_NUM,
                               p_db_key  => l_db_key,
                               p_param1 => 'complete_setup_initrep_' || l_ckpt,
                               p_param2 => f.rep_server_name,
                               p_param3 => l_db_unique_name,
                               P_keep_stack => FALSE,
                               p_component  => 'REPLICATION_INITIAL_REP',
                               p_severity   => dbms_ra_scheduler.SEVERITY_ERROR,
                               p_param_char => 'INITIAL_REPLICATION');
    END;
    END LOOP;
 
    IF l_all_replicated THEN
      fix_error (p_error_num  => dbms_ra.REP_SETUP_ERROR_NUM,
                 p_db_key     => l_db_key,
                 p_param_char => 'INITIAL_REPLICATION');
    END IF;
  END IF;
 
  IF l_all_replicated AND l_all_reconciled THEN
    trace1 ('CHECK_DO_PENDING_REP_SETUP: Replication setup completed for ' ||
            l_db_unique_name);
    l_rv := TRUE;
  END IF;
 
  IF l_lockflag THEN
    SYS.KBRSI_ICD.RSKEYUNLOCK(l_db_key);
  END IF;
 
  RETURN l_rv;
 
EXCEPTION
  WHEN OTHERS THEN
    save_error;
    IF l_lockflag THEN
      SYS.KBRSI_ICD.RSKEYUNLOCK(l_db_key);
    END IF;
    clear_error;
    RAISE;
 
END check_do_pending_rep_setup;
--
 
--
--
--
--
--
--
--
--
PROCEDURE replicate_one_bp (p_db_key IN NUMBER,
                            p_bp_key IN NUMBER,
                            p_server_key IN NUMBER DEFAULT NULL)
IS
  l_pending_rep_setup   odb.pending_rep_setup%TYPE;
  l_db_key              NUMBER := p_db_key;
  l_bp_key              NUMBER := p_bp_key;
  l_repcnt              NUMBER;
BEGIN
 
  IF l_db_key IS NULL THEN
    trace1 ('REPLICATE_ONE_BP: required db_key missing.');
    RETURN;
  END IF;
 
  IF l_bp_key IS NULL THEN
    trace1 ('REPLICATE_ONE_BP: required bp_key missing.');
    RETURN;
  END IF;
 
--
--
--
--
--
--
--
--
  SELECT pending_rep_setup INTO l_pending_rep_setup FROM odb
    WHERE odb.db_key=l_db_key;
  IF l_pending_rep_setup = 'Y' THEN
    IF NOT check_do_pending_rep_setup(l_db_key) THEN
      trace1 ('REPLICATE_ONE_BP: Unable to complete replication ' ||
              'setup for database ' || dbms_ra_int.dbkey2name(l_db_key));
      RETURN;
    END IF;
  END IF;
 
--
  SELECT count(*) INTO l_repcnt
    FROM odb o, rep_server rs
    WHERE o.prot_key = rs.prot_key
      AND o.db_key = l_db_key
      AND rs.server_key = NVL(p_server_key, rs.server_key)
      AND rs.status = 'A';
 
  IF l_repcnt > 0 THEN
    DBMS_RA_SCHEDULER.CREATE_REPLICATION_TASKS(p_db_key => l_db_key,
                                               p_bp_key => l_bp_key,
                                               p_server_key => p_server_key);
  END IF;
 
END replicate_one_bp;
--
 
END dbms_ra_scheduler;
>>>
 
define prvtrssm_plb
<<<
CREATE OR REPLACE PACKAGE BODY dbms_ra_storage AS
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
 
/*-------------------------*
 * Package State Variables *
 *-------------------------*/
s_tracing_on          BOOLEAN := FALSE;
s_perf_on             BOOLEAN := FALSE;
s_stall_on            BOOLEAN := FALSE;
s_safe_mode           BOOLEAN := FALSE;
 
s_db_level            BINARY_INTEGER := 0; -- locking depth for database alloc
s_sl_level            BINARY_INTEGER := 0; -- locking depth for storage locs
s_enable_dup          NUMBER := 1;      -- When space runs out only normal
--
--
 
--
--
--
  PROCEDURE repair_orphan_file (p_sl_key NUMBER, p_fname VARCHAR2);
 
  PROCEDURE repair_fileless_metadata (p_fname VARCHAR2);
 
  FUNCTION allocate_db_space (
                       p_sl_key     IN OUT NUMBER,
                       p_db_key     IN NUMBER,
                       p_size       IN NUMBER DEFAULT NULL,
                       p_movepurge  IN BOOLEAN DEFAULT FALSE) RETURN BOOLEAN;
 
  PROCEDURE check_tape_limit(p_db_key           IN NUMBER,
                             p_reserved         IN NUMBER,
                             p_used_space       IN NUMBER,
                             p_not_taped        IN NUMBER,
                             p_not_taped_state  IN VARCHAR2,
                             p_move_phase       IN NUMBER,
                             p_allocation       IN NUMBER);
 
  PROCEDURE return_space (p_size IN NUMBER,
                          p_db_key IN NUMBER,
                          p_sl_key IN NUMBER,
                          p_db_sl_key IN NUMBER);
 
  FUNCTION available_bs(p_sl_key IN NUMBER,
                        p_db_key IN NUMBER,
                        p_alloc  IN NUMBER) RETURN BOOLEAN;
 
  PROCEDURE move_db (p_db_key IN NUMBER);
 
  PROCEDURE used_space_check (p_db_key IN NUMBER,
                              p_sl_key IN NUMBER,
                              p_check_files IN BOOLEAN DEFAULT FALSE,
                              p_repair_sl_key IN NUMBER DEFAULT NULL);
 
--
--
--
  FUNCTION print (p_value IN BOOLEAN) RETURN VARCHAR2;
  FUNCTION print (p_value IN NUMBER) RETURN VARCHAR2;
  FUNCTION print (p_value IN DSINTERVAL_UNCONSTRAINED) RETURN VARCHAR2;
  FUNCTION print (p_value IN VARCHAR2) RETURN VARCHAR2;
  PROCEDURE tracex (message IN VARCHAR2);
  PROCEDURE trace1 (message IN VARCHAR2);
 
--
--
--
  s_init_done           BOOLEAN := FALSE; -- true if packages vars initialized
  sf_chunksize NUMBER := NULL;  -- Chunk size from current db
  sf_curr_db   NUMBER := 0;     -- Remembering curr_db optimizes chunksize get
 
--
--
--
--
--
--
  s_chunkno_cache_execution     NUMBER := -1;
  TYPE numtab IS TABLE OF NUMBER INDEX BY VARCHAR2(16); 
  s_chunkno_cache_first         numtab;
  s_chunkno_cache_next          numtab;
 
--
--
--
--
--
--
  s_sl_info_cache_execution     NUMBER := -1;
  s_sl_info_key                 NUMBER;
  s_sl_info_chunksize           NUMBER;
 
--
--
--
  TRUE#  CONSTANT NUMBER := 1;
  FALSE# CONSTANT NUMBER := 0;
 
--
--
PROCEDURE save_error IS 
BEGIN
  DBMS_RA_INT.SAVE_ERROR_INT;
END save_error;
 
--
--
PROCEDURE clear_error IS
BEGIN
  DBMS_RA_INT.CLEAR_ERROR_INT;
END clear_error;
 
--
--
--
--
--
--
FUNCTION f_chunksize(p_dbkey IN NUMBER) RETURN NUMBER IS
BEGIN
--
  IF sf_curr_db != p_dbkey THEN
    SELECT sl_min_alloc INTO sf_chunksize FROM odb WHERE db_key = p_dbkey;
    sf_curr_db := p_dbkey;
  END IF;
 
  RETURN sf_chunksize;
END f_chunksize;
 
--
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE copy_piece(p_fname  IN  VARCHAR2 DEFAULT NULL,
                     p_db_key IN  NUMBER DEFAULT NULL,
                     p_action IN  NUMBER DEFAULT 0) IS
  l_newfname          VARCHAR2(513) := NULL;
  l_sldir             VARCHAR2(513);
  l_fsize             NUMBER;
  l_bp_key            NUMBER;
  l_alg_over_alloc    NUMBER;
BEGIN
--
--
--
  SELECT sl_cg_name INTO l_sldir FROM sl, odb
    WHERE odb.sl_key = sl.sl_key
    AND odb.db_key = p_db_key;
 
--
--
--
--
  trace1 ('COPY_PIECE: File to be copied from ' || p_fname
          || ' to ' || l_sldir);
  trace1 ('COPY_PIECE: p_action value ' || p_action);
 
--
  dbms_ra_int.s_bp_save.DELETE;
  l_alg_over_alloc := DBMS_RA_SCHEDULER.S_ALG_OVER_ALLOC;
 
  SYS.KBRSI_ICD.RSCOPYFILE (p_fname, l_newfname, l_fsize, l_sldir, p_action,
                            l_alg_over_alloc);
 
--
  dbms_ra_int.s_bp_save.DELETE;
 
--
  SELECT bp_key
    INTO l_bp_key
    FROM sbt_catalog
    WHERE filename = l_newfname
      AND filesize IS NOT NULL;
 
  dbms_ra_scheduler.replicate_one_bp (p_db_key => p_db_key,
                                      p_bp_key => l_bp_key);
 
  EXCEPTION
    WHEN OTHERS THEN
      save_error;
--
      dbms_ra_int.s_bp_save.DELETE;
      RAISE;
END copy_piece;
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE check_files (p_sl_key            IN  NUMBER,
                       p_execute_time      IN  TIMESTAMP WITH TIME ZONE,
                       p_savepoint         IN  NUMBER,
                       p_repair            IN  BOOLEAN) IS
 
  l_sl_count            NUMBER;
  l_savepoint           NUMBER := p_savepoint;
  l_storage_directory   sl.sl_cg_name%TYPE;
  l_sl_name             sl.sl_name%TYPE;
  l_omf_namespace       VARCHAR2(1)   := NULL;
  l_scn                 NUMBER;
  l_repair_sl_key       NUMBER;
  l_blockpool_usage     NUMBER;
  l_sbtpiece_usage      NUMBER;
  l_task_chunk_cache    NUMBER;
  l_task_purge_reserve  NUMBER;
  l_used_space          NUMBER;
  l_dbsl_used           NUMBER;
  l_total_allocation    NUMBER;
  l_computed_allocation NUMBER;
 
BEGIN
  trace1 ('CHECK_FILES: sl_key=' || p_sl_key ||
                      '; savepoint ' || p_savepoint ||
                      '; execute_time ' || p_execute_time);
 
--
--
--
--
--
--
  SELECT COUNT(*) INTO l_sl_count 
    FROM sl
   WHERE sl_space > 0
     AND ROWNUM <= 2;
 
--
--
--
--
--
--
--
    LOOP
      DELETE contained_filenames 
        WHERE sl_key = p_sl_key
          AND ROWNUM < 50000;
      EXIT WHEN SQL%ROWCOUNT = 0;
      COMMIT;
    END LOOP;
 
    LOOP
      DELETE metadata_filenames 
        WHERE sl_key = p_sl_key
          AND ROWNUM < 50000;
      EXIT WHEN SQL%ROWCOUNT = 0;
      COMMIT;
    END LOOP;
    COMMIT;
--
 
  IF l_savepoint = 0 THEN
--
--
--
--
--
--
--
--
    SELECT MIN(sl_cg_name), MIN(sl_name) INTO l_storage_directory, l_sl_name
      FROM sl
      WHERE sl_key = p_sl_key;
 
    IF l_storage_directory IS NULL THEN
      trace1 ('CHECK_FILES: Storage location is no more.');
      RETURN;
    END IF;
 
    trace1 ('CHECK_FILES: Storage is at:  ' || l_storage_directory);
 
--
--
--
--
    INSERT INTO contained_filenames (fname, sl_key)
      (SELECT filename, p_sl_key
         FROM sys.am$file f, sl s
         WHERE s.sl_cg_name = f.params
           AND s.sl_key = p_sl_key);
 
    COMMIT;
 
    trace1 ('CHECK_FILES: File list is created.');
 
--
--
--
--
--
--
 
--
    INSERT INTO metadata_filenames (fname, sl_key)
      (SELECT filename, p_sl_key
         FROM chunks, sl, dbinc, db
         WHERE chunks.sl_key = p_sl_key
           AND chunks.sl_key = sl.sl_key
           AND chunks.dbinc_key = dbinc.dbinc_key
           AND dbinc.db_key = db.db_key
           AND chunks.filename IS NOT NULL);
    trace1('CHECK_FILES: Assembled filenames for ' || SQL%ROWCOUNT ||
                                                ' block pool chunks.');
    COMMIT;
 
    INSERT INTO metadata_filenames (fname, sl_key)
      (SELECT sc.filename, p_sl_key
        FROM sbt_catalog sc
       WHERE sc.sl_key = p_sl_key
         AND sc.ftype = 'F'
         AND sc.filesize IS NOT NULL
         AND sc.filename IS NOT NULL);
 
    trace1('CHECK_FILES: Assembled filenames for ' || SQL%ROWCOUNT ||
                                                ' sbt received files.');
    COMMIT;
 
--
--
--
--
    IF p_repair THEN
      FOR f IN (SELECT mf.fname fname
                  FROM metadata_filenames mf
                  WHERE mf.sl_key = p_sl_key
                MINUS
                SELECT cf.fname
                  FROM contained_filenames cf
                  WHERE cf.sl_key = p_sl_key) LOOP
 
        trace1 ('CHECK_FILES: Fileless metadata for ' || f.fname);
        repair_fileless_metadata (f.fname);
      END LOOP;
    END IF;
 
--
--
--
    FOR f IN
      (SELECT fname
         FROM contained_filenames cf
         WHERE sl_key = p_sl_key
           AND NOT EXISTS (SELECT 1
                             FROM metadata_filenames tmf 
                             WHERE  cf.fname = tmf.fname
                               AND  sl_key = p_sl_key) ) 
    LOOP
      IF p_repair THEN
--
--
--
        repair_orphan_file(p_sl_key, f.fname);
      ELSE
--
--
--
--
--
--
--
        MERGE INTO missing_metadata_filenames mmf
          USING dual ON ((mmf.sl_key = p_sl_key) AND (mmf.fname = f.fname))
          WHEN NOT MATCHED THEN
            INSERT  (  sl_key,   fname, entered,      latest)
             VALUES (p_sl_key, f.fname, SYSTIMESTAMP, SYSTIMESTAMP)
          WHEN MATCHED THEN
            UPDATE SET latest = SYSTIMESTAMP;
 
        trace1 ('CHECK_FILES: Potential orphan file -- ' || f.fname);
      END IF;
    END LOOP;
 
--
--
--
    DELETE contained_filenames WHERE sl_key = p_sl_key;
    COMMIT;
 
    IF NOT p_repair THEN 
--
--
--
--
      DELETE FROM missing_metadata_filenames
        WHERE sl_key = p_sl_key
          AND latest < p_execute_time;
      trace1 ('CHECK_FILES: ' || SQL%ROWCOUNT || ' files left the orphanage');
      COMMIT;
 
--
--
--
      FOR f IN
        (SELECT fname
           FROM missing_metadata_filenames
           WHERE sl_key = p_sl_key
             AND entered < 
                       (p_execute_time - DBMS_RA_SCHEDULER.S_ORPHAN_FILE_WAIT))
      LOOP
        trace1 ('CHECK_FILES: Reportable orphan file -- ' || f.fname);
 
        DBMS_RA_SCHEDULER.LOG_ERROR (
                 p_errno     => DBMS_RA_SCHEDULER.E_ORPHAN_FILE_NUM,
                 p_param1    => f.fname,
                 p_param2    => l_sl_name,
                 p_component => 'CHECK_FILES',
                 p_severity  => DBMS_RA_SCHEDULER.SEVERITY_ERROR,
                 p_sl_key     => p_sl_key,
                 p_param_char => f.fname);
      END LOOP;
 
--
--
--
      trace1 ('CHECK_FILES: Clear corrected orphan_file errors');
      DBMS_RA_SCHEDULER.FIX_ERROR(
                        p_error_num => DBMS_RA_SCHEDULER.E_ORPHAN_FILE_NUM,
                        p_sl_key => p_sl_key,
                        p_timestamp => p_execute_time);
 
    END IF;
 
    trace1 ('CHECK_FILES: File check complete.');    
  END IF;
 
--
--
--
--
--
--
  IF p_repair THEN
    UPDATE task
      SET flags = flags - 
                    BITAND (flags, DBMS_RA_SCHEDULER.TASKS_CHUNK_CACHE_ACTIVE);
 
    DELETE task_chunk_cache;
    COMMIT;
  END IF;
 
--
--
--
  DBMS_RA_SCHEDULER.CHECK_FOR_INTERRUPT(1);
 
--
--
--
--
--
--
  IF (l_savepoint <= 1) AND (NOT p_repair) THEN
--
--
--
    FOR f IN
      (SELECT sc.handle, DBMS_RA_INT.DBKEY2NAME(sc.db_key) db_unique_name
         FROM sbt_catalog sc
         WHERE sc.sl_key = p_sl_key
           AND sc.completed = 'Y'
           AND sc.filesize IS NOT NULL
           AND NOT EXISTS (SELECT 1 
                             FROM bp
                             WHERE bp.db_key = sc.db_key
                               AND bp.handle = sc.handle
                               AND bp.vb_key IS NULL) )
    LOOP
 
      trace1 ('CHECK_FILES: Orphan sbt piece -- ' || f.handle);
 
      DBMS_RA_SCHEDULER.LOG_ERROR (
               p_errno     => DBMS_RA_SCHEDULER.E_ORPHAN_BP_PIECE_NUM,
               p_param1    => f.handle,
               p_param2    => f.db_unique_name,
               p_component => 'CHECK_FILES',
               p_severity  => DBMS_RA_SCHEDULER.SEVERITY_ERROR,
               p_sl_key     => p_sl_key,
               p_param_char => f.handle);
    END LOOP;
    trace1 ('CHECK_FILES: Finished SBT piece check.');
 
--
--
--
    trace1 ('CHECK_FILES: Clear corrected orphan_bp_piece errors');
    DBMS_RA_SCHEDULER.FIX_ERROR(
                        p_error_num => DBMS_RA_SCHEDULER.E_ORPHAN_BP_PIECE_NUM,
                        p_sl_key => p_sl_key,
                        p_timestamp => p_execute_time);
    COMMIT;
  END IF;
 
--
--
--
  DBMS_RA_SCHEDULER.CHECK_FOR_INTERRUPT(2);
 
--
--
--
--
--
--
  IF l_savepoint <= 2 THEN
    IF p_repair THEN
      l_repair_sl_key := p_sl_key;
    ELSE
      l_repair_sl_key := NULL;
    END IF;
 
    FOR u IN
      (SELECT odb.db_key, odb.sl_key, odb.sl_min_alloc chunksize
         FROM odb LEFT OUTER JOIN dbsl ON ((odb.db_key = dbsl.db_key) AND
                                           (dbsl.sl_key = p_sl_key))
        WHERE (odb.sl_key = p_sl_key OR dbsl.sl_key = p_sl_key) )
    LOOP
--
--
--
--
--
--
      used_space_check (u.db_key, p_sl_key, TRUE, l_repair_sl_key);
      IF NOT p_repair THEN
        trace1 ('CHECK_FILES: Clear corrected bad usage errors');
        DBMS_RA_SCHEDULER.FIX_ERROR(
                        p_error_num => DBMS_RA_SCHEDULER.E_BAD_ODB_USAGE_NUM,
                        p_db_key    => u.db_key,
                        p_timestamp => p_execute_time);
 
        trace1 ('CHECK_FILES: Clear corrected bad total allocation errors');
        DBMS_RA_SCHEDULER.FIX_ERROR(
                        p_error_num => DBMS_RA_SCHEDULER.E_BAD_TOTAL_ALLOC_NUM,
                        p_db_key    => u.db_key,
                        p_timestamp => p_execute_time);
    
       END IF;
    END LOOP;
 
--
--
--
    IF p_repair THEN
      trace1 ('CHECK_FILES: Clear corrected bad dbid errors');
      DBMS_RA_SCHEDULER.FIX_ERROR(
                        p_error_num => DBMS_RA_SCHEDULER.E_BAD_DBID_NUM,
                        p_sl_key    => p_sl_key,
                        p_timestamp => p_execute_time);
 
      trace1 ('CHECK_FILES: Clear corrected bad backuppiece errors');
      DBMS_RA_SCHEDULER.FIX_ERROR(
                      p_error_num => DBMS_RA_SCHEDULER.E_BAD_BACKUP_PIECE_NUM,
                      p_sl_key    => p_sl_key,
                      p_timestamp => p_execute_time);
 
      trace1 ('CHECK_FILES: Clear corrected unknown datafile errors');
      DBMS_RA_SCHEDULER.FIX_ERROR(
                      p_error_num => DBMS_RA_SCHEDULER.E_UNKNOWN_DATAFILE_NUM,
                      p_sl_key    => p_sl_key,
                      p_timestamp => p_execute_time);
 
      trace1 ('CHECK_FILES: Clear corrected unknown file type errors');
      DBMS_RA_SCHEDULER.FIX_ERROR(
                      p_error_num => DBMS_RA_SCHEDULER.E_UNKNOWN_FILE_NUM,
                      p_sl_key    => p_sl_key,
                      p_timestamp => p_execute_time);
    END IF;
  END IF;
  COMMIT;
  trace1 ('CHECK_FILES: Finished used_space check.');
--
--
--
  DBMS_RA_SCHEDULER.CHECK_FOR_INTERRUPT(3);
 
--
--
--
  UPDATE sl SET sl_last_check_files = SYSTIMESTAMP
   WHERE sl_key = p_sl_key;
  COMMIT;
 
END check_files;
 
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE repair_orphan_file (p_sl_key NUMBER, p_fname VARCHAR2) IS
  l_size              NUMBER;
  l_complete          BOOLEAN;
  l_backuppiece_id    NUMBER;
  l_ftype             NUMBER;
  l_dbid              NUMBER;
  l_db_key            NUMBER;
  l_dbsl_key          NUMBER;
  l_sl_min_alloc      NUMBER;
  l_allocsize         NUMBER;
  l_newctkey          NUMBER;
--
--
  l_backupset_id      NUMBER;
  l_task_rec          task%ROWTYPE;
  l_repcnt            NUMBER;
  l_dbinc_key         NUMBER;
  l_df_key            NUMBER;
  l_chunkno           NUMBER;
  l_newfincarn        sbt_catalog.pieceinc%TYPE := 'NEEDS_REPAIR';
  l_sameendian        BINARY_INTEGER;
BEGIN
  trace1 ('REPAIR_ORPHAN_FILE for ' || p_fname);
 
--
--
--
  SYS.KBRSI_ICD.RSISCOMPLETE(fname => p_fname,
                             filesize => l_size,
                             complete => l_complete,
                             ftype    => l_ftype,
                             same_endian => l_sameendian,
                             dbid     => l_dbid);
 
  IF l_complete THEN
    trace1 ('REPAIR_ORPHAN_FILE: completed=' || print(l_complete) || 
            ', dbid=' || l_dbid ||
            ', ftype ' || l_ftype ||
            ', size ' || l_size);
  ELSE
    trace1 ('REPAIR_ORPHAN_FILE: Found incomplete.  Size=' || l_size);
    SYS.KBRSI_ICD.RSDELETEFILE(p_fname);
    RETURN;
  END IF;
 
--
--
--
  BEGIN
    SELECT db.db_key, odb.sl_key INTO l_db_key, l_dbsl_key
      FROM db, odb
      WHERE db.db_key = odb.db_key
        AND db_id = l_dbid;
  EXCEPTION
    WHEN NO_DATA_FOUND THEN
      save_error;
      trace1 ('REPAIR_ORPHAN_FILE: File %s references an unknown dbid: ' || 
              l_dbid);
 
      DBMS_RA_SCHEDULER.LOG_ERROR (
                 p_errno     => DBMS_RA_SCHEDULER.E_BAD_DBID_NUM,
                 p_param1    => p_fname,
                 p_param2    => l_dbid,
                 p_keep_stack=> FALSE,
                 p_component => 'REPAIR',
                 p_severity  => DBMS_RA_SCHEDULER.SEVERITY_ERROR,
                 p_sl_key     => p_sl_key,
                 p_param_char => p_fname);
      clear_error;
  END;  
 
  CASE
    WHEN (l_ftype IN (DBMS_RA_SCHEDULER.FTYPE_ARCHBACKUP,
                      DBMS_RA_SCHEDULER.FTYPE_AUTOBACKUP,
                      DBMS_RA_SCHEDULER.FTYPE_BACKUP,
                      DBMS_RA_SCHEDULER.FTYPE_INCBACKUP)) THEN
 
--
--
--
      SELECT sl_min_alloc INTO l_sl_min_alloc
        FROM sl
        WHERE sl_key = p_sl_key;
 
      l_allocsize := CEIL(l_size/l_sl_min_alloc) * l_sl_min_alloc;
      trace1 ('REPAIR_ORPHAN_FILE: min_alloc= ' || l_sl_min_alloc ||
                                '; allocsize= ' || l_allocsize);
 
--
--
--
--
      l_newctkey := rman_seq.NEXTVAL;
 
      INSERT INTO sbt_catalog
          (ct_key, db_key, cretime, handle, pieceinc, endupload, bp_key, ftype, 
           sl_key, sl_min_alloc, filename, filesize, last_entry, completed)
        VALUES
          (l_newctkey, l_db_key, SYSTIMESTAMP,
           p_fname, l_newfincarn, 'Y', NULL, 'F', 
           p_sl_key, l_sl_min_alloc, p_fname, l_allocsize, SYSTIMESTAMP, 'N');
 
--
--
--
--
--
--
--
      IF p_sl_key <> l_dbsl_key THEN
        trace1 ('REPAIR_ORPHAN_FILE: sl_key=' || p_sl_key ||
                                '; dbsl_key=' || l_dbsl_key);
        MERGE INTO dbsl
          USING dual ON ((dbsl.db_key = l_db_key) AND (dbsl.sl_key = p_sl_key))
          WHEN NOT MATCHED THEN
            INSERT   (  db_key, sl_key,   dbsl_used_space)
              VALUES (l_db_key, p_sl_key, l_allocsize);
      END IF;
      COMMIT;
 
--
--
--
      BEGIN
        SYS.KBRSI_ICD.RSINSPECTBACKUPPIECE(
             handle        => p_fname,
             vbkey         => null,
             bpsize        => l_size,
             chktype       => DBMS_RA_INT.KBRSCHKTYPE_FILE,
             fno           => null,
             lib_key       => null,/* local disk */
             ct_key        => l_newctkey,
             bpkey         => l_backuppiece_id,
             template_key  => null);
      EXCEPTION
        WHEN OTHERS THEN
          save_error;
          trace1 ('REPAIR_ORPHAN_FILE: Processing backup returned: ' ||
                  SQLERRM);
 
          DBMS_RA_SCHEDULER.LOG_ERROR (
                 p_errno     => DBMS_RA_SCHEDULER.E_BAD_BACKUP_PIECE_NUM,
                 p_param1    => p_fname,
                 p_component => 'REPAIR',
                 p_severity  => DBMS_RA_SCHEDULER.SEVERITY_ERROR,
                 p_sl_key     => p_sl_key,
                 p_param_char => p_fname);
 
          sys.kbrsi_icd.rsClearErr;
 
          free_backup_piece(p_dbkey     => l_db_key
                           ,p_piecename => p_fname
                           ,p_fincarn   => l_newfincarn
                           ,p_ftype     => DBMS_RA_INT.KBRSCHKTYPE_FILE);
          COMMIT;
          clear_error;
     END;
      
--
--
--
     dbms_ra_scheduler.replicate_one_bp (p_db_key => l_db_key,
                                         p_bp_key => l_backuppiece_id);
 
--
--
--
      COMMIT;
 
    WHEN (l_ftype IN (DBMS_RA_SCHEDULER.FTYPE_CHUNK)) THEN
--
--
--
--
--
      BEGIN
        SELECT df.dbinc_key, df.df_key  INTO l_dbinc_key, l_df_key
          FROM dbinc, df
          WHERE dbinc.dbinc_key = df.dbinc_key
            AND dbinc.db_key = l_db_key
            AND ROWNUM=1;
      EXCEPTION
        WHEN NO_DATA_FOUND THEN
          save_error;
          trace1 ('REPAIR_ORPHAN_FILE: Unknown Datafile for dbid ' || l_dbid);
 
          DBMS_RA_SCHEDULER.LOG_ERROR (
                 p_errno     => DBMS_RA_SCHEDULER.E_UNKNOWN_DATAFILE_NUM,
                 p_param1    => p_fname,
                 p_param2    => l_dbid,
                 p_keep_stack=> FALSE,
                 p_component => 'REPAIR',
                 p_severity  => DBMS_RA_SCHEDULER.SEVERITY_ERROR,
                 p_sl_key     => p_sl_key,
                 p_param_char => p_fname);
          clear_error;
      END;
 
--
--
--
--
--
--
--
      IF p_sl_key <> l_dbsl_key THEN
        trace1 ('REPAIR_ORPHAN_FILE: sl_key=' || p_sl_key ||
                                '; dbsl_key=' || l_dbsl_key);
        MERGE INTO dbsl
          USING dual ON ((dbsl.db_key = l_db_key) AND (dbsl.sl_key = p_sl_key))
          WHEN NOT MATCHED THEN
            INSERT   (  db_key, sl_key,   dbsl_used_space)
              VALUES (l_db_key, p_sl_key, 1);
      END IF;
 
--
--
--
--
--
      l_chunkno := get_chunkno (l_df_key);
      trace1 ('REPAIR_ORPHAN_FILE: Inserting chunkno=' || l_chunkno ||
                                '; df_key=' || l_df_key ||
                                '; dbinc_key=' || l_dbinc_key);
 
      INSERT INTO chunks (  sl_key,   dbinc_key,   df_key,
                            chunkno,   filename, filesize,   clean_key)
                  VALUES (p_sl_key, l_dbinc_key, l_df_key,
                          l_chunkno, p_fname,    1, -1);
      COMMIT;
    ELSE
      trace1('REPAIR_ORPHAN_FILE: ' || p_fname || 
             ' is not a valid recovery appliance file');
 
      DBMS_RA_SCHEDULER.LOG_ERROR (
                 p_errno     => DBMS_RA_SCHEDULER.E_UNKNOWN_FILE_NUM,
                 p_param1    => p_fname,
                 p_component => 'REPAIR',
                 p_severity  => DBMS_RA_SCHEDULER.SEVERITY_ERROR,
                 p_sl_key     => p_sl_key,
                 p_param_char => p_fname);
  END CASE; 
  
END repair_orphan_file;
 
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE repair_fileless_metadata (p_fname VARCHAR2) IS
  l_ct_key      NUMBER;
  l_db_key      NUMBER;
  l_handle      sbt_catalog.handle%TYPE;
  l_dbid        NUMBER;
  l_currinc_key NUMBER;
  l_dbsl_key    NUMBER;
  l_bp_key      NUMBER;
  l_dbinc_key   NUMBER;
  l_df_key      NUMBER;
  l_chunkno     NUMBER;
 
  CURSOR find_chunks IS 
    SELECT db.db_key, c.df_key, c.dbinc_key, db.db_id, db.curr_dbinc_key,
           c.chunkno, bp.bp_key, odb.sl_key, bp.handle
      FROM chunks c
           JOIN dbinc ON c.dbinc_key = dbinc.dbinc_key
           JOIN db ON dbinc.db_key = db.db_key
           JOIN odb ON db.db_key = odb.db_key
           LEFT OUTER JOIN vbdf ON vbdf.krbph_dfkey = c.df_key
                                   AND vbdf.krbph_chunkno = c.chunkno
           LEFT OUTER JOIN bp USING (vb_key)
      WHERE c.filename = p_fname;
 
BEGIN
  trace1('REPAIR_FILELESS_METADATA for ' || p_fname);
  BEGIN
--
--
--
    SELECT db_key,   s.handle, s.bp_key, 
           db.db_id, db.curr_dbinc_key, odb.sl_key 
      INTO l_db_key, l_handle, l_bp_key, 
           l_dbid,   l_currinc_key,     l_dbsl_key
      FROM sbt_catalog s
      JOIN db USING (db_key)
      JOIN odb USING (db_key)
      WHERE s.filename = p_fname;
 
    free_backup_piece_opt (p_dbkey => l_db_key
                          ,p_piecename => l_handle
                          ,p_db_slkey => l_dbsl_key
                          ,p_dbid => l_dbid
                          ,p_currinc => l_currinc_key
                          ,p_bpkey => l_bp_key
                          ,p_spawn_job => FALSE
                          ,p_notasks => TRUE
                          ,p_noplans => TRUE);
    trace1('REPAIR_FILELESS_METADATA: Piece deleted from sbt_catalog');
    RETURN;
  EXCEPTION
    WHEN NO_DATA_FOUND THEN
       save_error;
       trace1('REPAIR_FILELESS_METADATA:  Not in sbt_catalog');
       clear_error;
  END;
 
--
--
--
--
  FOR c IN find_chunks LOOP
 
    trace1('REPAIR_FILELESS_METADATA: bp_key found is ' || print(c.bp_key));
 
    IF c.bp_key IS NOT NULL THEN
--
--
--
      free_backup_piece_opt (p_dbkey => c.db_key
                            ,p_piecename => c.handle
                            ,p_db_slkey => c.sl_key
                            ,p_dbid => c.db_id
                            ,p_currinc => c.curr_dbinc_key
                            ,p_bpkey => c.bp_key
                            ,p_ftype => NULL
                            ,p_fincarn => NULL
                            ,p_libkey => NULL
                            ,p_spawn_job => FALSE
                            ,p_notasks => TRUE
                            ,p_noplans => TRUE);
    END IF;
 
    l_db_key := c.db_key;
    l_dbinc_key := c.dbinc_key;
    l_df_key := c.df_key;
    l_chunkno := c.chunkno;
 
  END LOOP;
 
--
--
--
  DELETE FROM blocks
    WHERE df_key = l_df_key AND chunkno = l_chunkno;
  trace1('REPAIR_FILELESS_METADATA: Deleting ' || SQL%ROWCOUNT || 
         ' rows in blocks table');
 
--
--
--
  free_block_pool_chunk (l_db_key, l_dbinc_key, l_df_key, l_chunkno);
  COMMIT;
END repair_fileless_metadata;
 
--
--
--
--
--
--
--
--
--
--
PROCEDURE move_all_db IS
  l_saved     NUMBER;
  l_count     NUMBER;
  l_dbkey     NUMBER;
  l_old_slkey NUMBER;
  l_new_slkey NUMBER;
BEGIN
  trace1 ('MOVE_ALL_DB');
 
--
--
--
  l_saved := DBMS_RA_SCHEDULER.GET_SAVEPOINT;
  IF l_saved IS NULL THEN      /* verify some other move is not in progress */
    BEGIN
--
    SYS.KBRSI_ICD.RSSCHEDLOCK (waitforwork => 0);
 
--
    SELECT MAX(task_id) INTO DBMS_RA_SCHEDULER.S_PENDING_INTERRUPT
      FROM task
      WHERE task_type = DBMS_RA_SCHEDULER.TASK_MOVE_ALL_DB
        AND task_id != DBMS_RA_SCHEDULER.S_CURRENT_TASK
        AND savepoint IS NOT NULL;
 
--
    IF DBMS_RA_SCHEDULER.S_PENDING_INTERRUPT IS NULL THEN
      DBMS_RA_SCHEDULER.CHECK_FOR_INTERRUPT(0);  -- We are now the mover
      l_saved := 0;            -- Indicate we are the mover
 
--
    ELSE
--
      SELECT COUNT(*) INTO l_count FROM task
        WHERE task_type = DBMS_RA_SCHEDULER.TASK_MOVE_ALL_DB
          AND state = DBMS_RA_SCHEDULER.STATE_TASK_WAIT;
 
      IF l_count = 0 THEN  -- No one else is waiting, let us wait
          RAISE DBMS_RA_SCHEDULER.E_RETRY_ERROR;
      END IF;
    END IF;
 
    SYS.KBRSI_ICD.RSSCHEDUNLOCK;
    EXCEPTION
      WHEN OTHERS THEN
        save_error;
        SYS.KBRSI_ICD.RSSCHEDUNLOCK;
        RAISE;
    END;
 
    IF l_saved IS NULL THEN -- We are not the mover
      RETURN;
    END IF;
  END IF;
 
--
--
--
  SELECT MAX(task_id) INTO DBMS_RA_SCHEDULER.S_PENDING_INTERRUPT
    FROM task
    WHERE task_type = DBMS_RA_SCHEDULER.TASK_MOVE_DF;
  IF DBMS_RA_SCHEDULER.S_PENDING_INTERRUPT IS NOT NULL THEN
    RAISE DBMS_RA_SCHEDULER.E_RETRY_ERROR;
  END IF;
 
--
--
--
  LOOP -- Until we have no more databases to move
--
    SELECT MIN(db_key) INTO l_dbkey
      FROM odb
      WHERE move_phase > DBMS_RA_SCHEDULER.MOVE_PHASE_PEND
--
        AND db_state IS NULL;
 
--
    IF l_dbkey IS NULL THEN
--
--
      SELECT MIN(db_key) INTO l_dbkey
        FROM (SELECT db_key, (unclaimed - reserved_space) space
              FROM /* Unreserved space for each storage location */
                   (SELECT sl_key,
                           (sl_space - SUM(reserved_space)) unclaimed
                    FROM (SELECT s.sl_key, sl_space, d.reserved_space
                          FROM odb d, prot p, sl s
                          WHERE p.sl_key = s.sl_key
                            AND p.prot_key = d.future_prot_key
--
                            AND d.db_state IS NULL
                         UNION
                          SELECT s.sl_key, sl_space, d.reserved_space
                          FROM unreg_database d, prot p, sl s
                          WHERE p.sl_key = s.sl_key
                            AND p.prot_key = d.prot_key)
                    GROUP BY sl_key, sl_space) a,
                    /* Future reserved space for each moving db */
                    (SELECT db_key, prot.sl_key, reserved_space
                     FROM odb, prot
                     WHERE odb.future_prot_key = prot.prot_key
                       AND move_phase IS NOT NULL
--
                       AND db_state IS NULL) b
              WHERE a.sl_key = b.sl_key
              ORDER BY space)
      WHERE ROWNUM = 1;
 
      IF l_dbkey IS NULL THEN
        trace1 ('MOVE_ALL_DB: Completed');
        RETURN;  -- We are all done moving.
      END IF;
    END IF;
 
--
    SELECT COUNT(*) INTO l_count
      FROM odb
      WHERE db_key = l_dbkey
        AND move_phase = DBMS_RA_SCHEDULER.MOVE_PHASE_PEND;
 
    IF l_count > 0 THEN  -- We still need to move this database metadata
--
--
--
--
      trim_database_for_move(l_dbkey, 0);
      DBMS_RA_SCHEDULER.CHECK_FOR_INTERRUPT(0);
 
--
      SELECT d.sl_key, p.sl_key
        INTO l_old_slkey, l_new_slkey
        FROM odb d, prot p
        WHERE d.future_prot_key = p.prot_key
          AND d.db_key = l_dbkey;
 
      trace1('MOVE_ALL_DB: Moving from ' || l_old_slkey || 
                           ' to ' || l_new_slkey);
 
--
--
      dbms_ra_scheduler.avoid_sl(DBMS_RA_SCHEDULER.TASK_PURGE, l_old_slkey);
 
      BEGIN
--
--
        DBMS_RA_SCHEDULER.QUIESCE_RS ();
        DBMS_RA_SCHEDULER.CHECK_FOR_INTERRUPT(NULL);
 
--
--
--
--
        FOR c IN (SELECT task_id
                    FROM task JOIN task_chunk_cache USING (task_id)
                    WHERE db_key = l_dbkey) LOOP
          free_task_storage (c.task_id);
        END LOOP;
 
--
        move_database_metadata (l_dbkey,
                                l_old_slkey,
                                l_new_slkey);
 
--
        DBMS_RA_SCHEDULER.UNQUIESCE_RS ();
 
      EXCEPTION
        WHEN OTHERS THEN
          save_error;
          ROLLBACK;
          DBMS_RA_SCHEDULER.UNQUIESCE_RS ();
          RAISE;
      END;
 
--
--
      trim_database_for_move(l_dbkey, 0);
    END IF;
 
--
    move_db(l_dbkey);
  END LOOP;
END move_all_db;
 
--
--
--
--
--
--
--
--
--
--
PROCEDURE move_db (p_db_key IN NUMBER) IS
  l_sl_key      NUMBER;
  l_db_id       NUMBER;
  l_found_work  BOOLEAN := FALSE;
  l_bpkey       NUMBER;
  l_status      VARCHAR2(1);
  l_got_lock    BOOLEAN;
 
  CURSOR move_block_pool IS
    SELECT DISTINCT chunks.df_key
    FROM chunks, df, dbinc
    WHERE chunks.df_key = df.df_key
      AND df.dbinc_key = dbinc.dbinc_key
      AND dbinc.db_key = p_db_key
      AND chunks.sl_key <> l_sl_key;
 
  l_df_key      NUMBER;
  l_count       NUMBER;
  l_newtask_rec task%ROWTYPE;
  l_bp_key      NUMBER;
  l_bs_key      NUMBER;
 
  CURSOR move_backup_pieces IS
    SELECT ct.filename, ct.handle, ct.pieceinc, ct.filesize, ct.bp_key
    FROM sbt_catalog ct, bp
    WHERE ct.db_key = p_db_key
      AND bp.bp_key = ct.bp_key
      AND ct.sl_key <> l_sl_key
      AND ct.completed = 'Y'
      AND bp.status <> 'D';
 
  l_fname       VARCHAR2(512);
  l_handle      VARCHAR2(512);
  l_fincarn     VARCHAR2(512);
  l_fsize       NUMBER;
 
  l_newfname    VARCHAR2(512);
  l_sldir       VARCHAR2(512);
  l_sls_used    NUMBER;
  l_currinc     NUMBER;
BEGIN
  trace1 ('MOVE_DB on database ' || p_db_key);
 
--
--
--
  DBMS_RA_SCHEDULER.S_NO_WAIT_ON_ALLOCATE := TRUE;
 
--
--
--
  SELECT odb.sl_key, db.db_id, db.curr_dbinc_key
    INTO l_sl_key, l_db_id, l_currinc
    FROM odb, db
    WHERE odb.db_key = p_db_key
      AND odb.db_key = db.db_key;
 
  OPEN move_block_pool;
  LOOP
    FETCH move_block_pool INTO l_df_key;
 
    EXIT WHEN move_block_pool%NOTFOUND;
    l_found_work := TRUE;
 
--
--
--
    SELECT COUNT(*) INTO l_count
      FROM task
      WHERE task_type = DBMS_RA_SCHEDULER.TASK_MOVE_DF
        AND db_key = p_db_key
        AND param_num1 = l_df_key;
 
    trace1 ('MOVE_DB for df_key=' || l_df_key ||
                               '; count=' || l_count );
 
    IF l_count = 0 THEN
      l_newtask_rec.task_type   := DBMS_RA_SCHEDULER.TASK_MOVE_DF;
      l_newtask_rec.flags       := 0;
      l_newtask_rec.db_key      := p_db_key;
      l_newtask_rec.sl_key      := l_sl_key;
      l_newtask_rec.param_num1  := l_df_key;
      DBMS_RA_SCHEDULER.NEW_TASK (l_newtask_rec);
    END IF;
  END LOOP;
  CLOSE move_block_pool;
 
  DBMS_RA_SCHEDULER.CHECK_FOR_INTERRUPT(NULL);
 
--
--
--
--
  SELECT MAX(task_id) INTO DBMS_RA_SCHEDULER.S_PENDING_INTERRUPT
    FROM task
   WHERE task_type = DBMS_RA_SCHEDULER.TASK_MOVE_DF
     AND db_key = p_db_key;
 
  IF DBMS_RA_SCHEDULER.S_PENDING_INTERRUPT IS NOT NULL THEN
    trace1 ('MOVE_DB: Blocking task is ' || 
                                        DBMS_RA_SCHEDULER.S_PENDING_INTERRUPT);
 
--
--
--
--
    RAISE DBMS_RA_SCHEDULER.E_PENDING_INTERRUPT;
  END IF;
 
--
--
--
--
--
--
--
--
--
--
  BEGIN
    lock_db (p_db_key);
 
    UPDATE odb SET move_phase = DBMS_RA_SCHEDULER.MOVE_PHASE_FILES
      WHERE db_key = p_db_key;
    COMMIT;
 
    unlock_db (p_db_key);
    trace1 ('MOVE_DB: Finished moving block pools.');
 
  EXCEPTION
    WHEN OTHERS THEN
      save_error;
      unlock_db (p_db_key);
      RAISE;
  END;
 
--
--
--
  SELECT sl_cg_name INTO l_sldir FROM sl WHERE sl_key = l_sl_key;
 
--
--
--
  OPEN move_backup_pieces;
  LOOP
    FETCH move_backup_pieces
      INTO l_fname, l_handle, l_fincarn, l_fsize, l_bp_key;
 
    EXIT WHEN move_backup_pieces%NOTFOUND;
 
    trace1 ('MOVE_DB for dbfile= ' || l_handle);
    l_found_work := TRUE;
    l_newfname := NULL;
    l_got_lock := FALSE;
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
    BEGIN
      DBMS_RA_INT.WRITE_LOCK(DBMS_RA_INT.KEY_BP, l_bp_key);
      l_got_lock := TRUE;
 
--
--
--
--
      SYS.KBRSI_ICD.RSCOPYFILE (l_fname, l_newfname, l_fsize, l_sldir,
                                DBMS_RA_SCHEDULER.COPY_BA_CPMV 
                                                      /*KRBYX_ORS_CPMV*/);
 
      trace1 ('MOVE_DB: File copied from ' || l_fname
                                               || ' to ' || l_newfname);
 
--
--
--
      DBMS_RA_INT.UNLOCK(DBMS_RA_INT.KEY_BP, l_bp_key);
 
--
--
--
      free_backup_piece_opt(p_dbkey     => p_db_key,
                            p_piecename => l_handle,
                            p_db_slkey  => l_sl_key,
                            p_dbid      => l_db_id,
                            p_currinc   => l_currinc,
                            p_fincarn   => l_fincarn,
                            p_ftype     => DBMS_RA_INT.KBRSCHKTYPE_FILE,
                            p_bpkey     => NULL);
 
    EXCEPTION
      WHEN OTHERS THEN
        save_error;
        IF NOT l_got_lock AND SQLCODE = DBMS_RA_SCHEDULER.E_RETRY_ERROR_NUM
        THEN
          trace1 ('MOVE_DB: Skipping copy of bp_key ' || l_bp_key);
          clear_error;
          CONTINUE;
        END IF;
 
        IF l_bp_key IS NOT NULL AND l_got_lock THEN
          DBMS_RA_INT.UNLOCK(DBMS_RA_INT.KEY_BP, l_bp_key);
        END IF;
        trace1 ('MOVE_DB: Bad copied file: ' || SQLERRM);
        RAISE;
    END;
 
--
--
--
    DBMS_RA_SCHEDULER.CHECK_FOR_INTERRUPT(NULL);
  END LOOP;
  CLOSE move_backup_pieces;
 
--
--
--
--
  IF l_found_work THEN
    DBMS_RA_SCHEDULER.S_PENDING_INTERRUPT := NULL;
    RAISE DBMS_RA_SCHEDULER.E_PENDING_INTERRUPT;
  END IF;
 
--
--
--
--
  UPDATE odb SET move_phase = NULL,
                 reserved_space = base_reserved_space
    WHERE db_key = p_db_key
    RETURN sls_used INTO l_sls_used;
 
--
  DBMS_RA_SCHEDULER.CHECK_FOR_INTERRUPT(NULL);
  COMMIT;
 
--
--
--
--
--
  trace1 ('MOVE_DB: sls_used is ' || l_sls_used);
END move_db;
 
 
--
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE allocate_backup_piece_name(
                        p_db_id     IN NUMBER,
                        p_piecename IN VARCHAR2,
                        p_fincarn   IN VARCHAR2) IS
 
l_bool            BOOLEAN := FALSE;
l_db_sl_key       NUMBER;
l_sl_min_alloc    NUMBER;
l_count           NUMBER;
l_db_id           NUMBER;
l_old_filename    sbt_catalog.filename%TYPE;
l_old_filesize    NUMBER;
l_old_sl_min_alloc NUMBER;
l_new_fincarn     sbt_catalog.pieceinc%TYPE;
l_new_ct_key      NUMBER;
 
BEGIN
  trace1 ('ALLOCATE_BACKUP_PIECE_NAME: dbid ' || p_db_id ||
          ', handle ' || p_piecename);
 
--
--
--
--
--
--
--
  IF DBMS_RA_SCHEDULER.S_CURRENT_TASK IS NULL THEN
    l_bool := 
        SYS.KBRSI_ICD.RSKEYREADLOCK (DBMS_RA_SCHEDULER.LOCK_QUIESCE_PENDING, 
                                     FALSE);
 
--
--
--
--
    IF NOT l_bool THEN
      RAISE DBMS_RA_SCHEDULER.E_RETRY_ERROR;
    END IF;
  END IF;
 
--
--
--
  BEGIN
    SELECT odb.sl_key, odb.sl_min_alloc INTO l_db_sl_key, l_sl_min_alloc
      FROM db, odb
      WHERE db.db_id = p_db_id
        AND db.db_key = odb.db_key;
  EXCEPTION
    WHEN OTHERS THEN
      save_error;
      SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(
                DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM,
                'Allocate_backup_piece_name cannot find sl',
                TRUE);
  END;
 
--
  UPDATE sbt_catalog
        SET sl_key          = l_db_sl_key
          , sl_min_alloc    = l_sl_min_alloc
          , filesize        = 0
          , last_entry      = SYSTIMESTAMP
          , completed       = 'N'
    WHERE handle = p_piecename
      AND pieceinc = p_fincarn
      AND filesize IS NULL;
 
  IF SQL%ROWCOUNT <> 1 THEN
--
--
--
--
    BEGIN
      SELECT db_id, filename, filesize, sl_min_alloc
        INTO l_db_id, l_old_filename, l_old_filesize, l_old_sl_min_alloc
        FROM sbt_catalog
        JOIN db USING (db_key)
       WHERE handle = p_piecename
         AND pieceinc = p_fincarn;
    EXCEPTION
      WHEN NO_DATA_FOUND THEN
        save_error;
        trace1 ('ALLOCATE_BACKUP_PIECE_NAME: No catalog entry found');
        RAISE DBMS_RA_SCHEDULER.E_TERMINATED;
    END;
 
--
--
--
--
--
--
    trace1 ('ALLOCATE_BACKUP_PIECE_NAME: piece previously allocated');
 
--
--
--
    SYS.KBRSI_ICD.RSGENFINCARN (l_new_fincarn);
 
--
--
--
    UPDATE sbt_catalog
        SET sl_key          = l_db_sl_key
          , sl_min_alloc    = l_sl_min_alloc
          , filename        = NULL
          , filesize        = 0
          , last_entry      = SYSTIMESTAMP
          , completed       = 'N'
    WHERE handle = p_piecename
      AND pieceinc = p_fincarn;
 
--
--
--
--
    DBMS_RA_INT.CREATESBTCATALOG (
                          p_dbid        => l_db_id
                        , p_handle      => p_piecename
                        , p_pieceinc    => l_new_fincarn
                        , p_ftype       => DBMS_RA_INT.KBRSCHKTYPE_FILE
                        , p_xmldoc      => NULL
                        , p_commit      => FALSE
                        , p_ct_key      => l_new_ct_key);
 
 
    trace1 ('NAME_BACKUP_PIECE: new ctkey=' || l_new_ct_key ||
                             '; new fincarn=' || l_new_fincarn);
 
--
--
--
    UPDATE sbt_catalog
       SET filename = l_old_filename
         , filesize = l_old_filesize
         , sl_key = l_db_sl_key
         , sl_min_alloc = l_sl_min_alloc
         , last_entry = SYSTIMESTAMP - NUMTODSINTERVAL(365, 'day')
         , completed = 'N'
     WHERE ct_key = l_new_ct_key;
 
  END IF;
  COMMIT;
 
--
  IF DBMS_RA_SCHEDULER.S_CURRENT_TASK IS NULL THEN
    SYS.KBRSI_ICD.RSKEYUNLOCK(DBMS_RA_SCHEDULER.LOCK_QUIESCE_PENDING);
  END IF;
EXCEPTION
  WHEN OTHERS THEN
    save_error;
    IF l_bool THEN
      SYS.KBRSI_ICD.RSKEYUNLOCK(DBMS_RA_SCHEDULER.LOCK_QUIESCE_PENDING);
    END IF;
    RAISE;
END allocate_backup_piece_name;
 
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE allocate_backup_piece(
                        p_piecename IN VARCHAR2,
                        p_fincarn   IN VARCHAR2,
                        p_filesize  IN NUMBER,
                        p_ct_key   OUT NUMBER) IS
 
PRAGMA AUTONOMOUS_TRANSACTION;
l_db_key          NUMBER := NULL;
l_count           NUMBER;
l_sl_key          NUMBER;
l_sl_min_alloc    NUMBER;
l_filesize        NUMBER;
l_totfsize        NUMBER;
l_allocsize       NUMBER;
l_used            NUMBER;
l_needsize        NUMBER;
l_move_phase      NUMBER;
l_not_taped       NUMBER;
l_not_taped_state VARCHAR2(1);
l_reserved        NUMBER;
l_ct_rowid        UROWID;
l_odb_rowid       UROWID;
E_INVALID_ROWID   EXCEPTION;
l_cumulative_incr NUMBER;
l_retcode         BINARY_INTEGER := 0;
l_allocate_ok     BOOLEAN;
 
PRAGMA EXCEPTION_INIT(E_INVALID_ROWID, -1410);
BEGIN
  trace1 ('ALLOCATE_BACKUP_PIECE for'  ||
          '  handle ' || p_piecename ||
          ', pieceinc ' || p_fincarn ||
          ', filesize ' || p_filesize);
 
--
  BEGIN
    SELECT ROWID, ct_key, db_key, filesize, sl_min_alloc
      INTO l_ct_rowid, p_ct_key, l_db_key, l_filesize, l_sl_min_alloc
      FROM sbt_catalog
     WHERE handle = p_piecename
       AND pieceinc = p_fincarn
       AND completed = 'N';
  EXCEPTION
    WHEN OTHERS THEN
      save_error;
      SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(
                DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM,
                'Allocate_backup_piece cannot find ct_key',
                TRUE);
  END;
  
  BEGIN
    l_retcode := SYS.KBRSI_ICD.CONTAINER_BDAPI_GTFB(p_filesize,
                                                   l_sl_min_alloc, l_totfsize);
    trace1 ('ALLOCATE_BACKUP_PIECE filesize ' || p_filesize ||
            'total_filesize '  || l_totfsize);
  EXCEPTION
    WHEN OTHERS THEN
      save_error;
      SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(
                DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM,
                'Allocate_backup_piece: gtfb failure',
                TRUE);
  END;
  
  IF (l_retcode != 0) THEN
    trace1 ('ALLOCATE_BACKUP_PIECE error retrieving total filesize for ' || 
            '  handle '   || p_piecename ||
            ', pieceinc ' || p_fincarn ||
            ', retcode='  || l_retcode);
    SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(
                                        DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM,
                                        'bad bdapi_gtfb ret ' || l_retcode); 
  END IF;
 
--
  IF (l_filesize >= l_totfsize) THEN
    RETURN;
  END IF;
 
--
--
--
--
--
--
  lock_db(l_db_key);
 
--
--
--
--
  LOOP
--
--
--
    BEGIN
--
      SELECT filesize, sl_key, sl_min_alloc
        INTO l_filesize, l_sl_key, l_sl_min_alloc
        FROM sbt_catalog
       WHERE ROWID = l_ct_rowid
         AND handle = p_piecename
         AND pieceinc = p_fincarn
         AND completed = 'N';
    EXCEPTION
--
      WHEN e_invalid_rowid OR NO_DATA_FOUND THEN
         save_error;
--
--
--
--
         BEGIN
           SELECT ROWID, filesize, sl_key, sl_min_alloc
             INTO l_ct_rowid, l_filesize, l_sl_key, l_sl_min_alloc
             FROM sbt_catalog
            WHERE handle = p_piecename
              AND pieceinc = p_fincarn
              AND completed = 'N';
         EXCEPTION
           WHEN e_invalid_rowid OR NO_DATA_FOUND THEN
             save_error;
--
--
             trace1('ALLOCATE_BACKUP_PIECE:  cannot find ct_key on refetch');
             RAISE DBMS_RA_SCHEDULER.E_RETRY_ERROR;
 
           WHEN OTHERS THEN
             save_error;
             SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(
                    DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM,
                    'Allocate_backup_piece: cannot find ct_key on refetch',
                    TRUE);
           END;
           clear_error;
       WHEN OTHERS THEN
         save_error;
         SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(
                DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM,
                'Allocate_backup_piece: cannot find ct_key2',
                TRUE);
 
    END;
 
    trace1 ('ALLOCATE_BACKUP_PIECE: sl_key = ' || l_sl_key);
 
--
--
--
    IF l_filesize >= l_totfsize THEN
      trace1 ('ALLOCATE_BACKUP_PIECE: Space was already allocated.');
      unlock_db (l_db_key);
      RETURN;
    END IF;
 
--
--
--
    l_needsize := 
               CEIL((l_totfsize - l_filesize)/l_sl_min_alloc) * l_sl_min_alloc;
    trace1 ('ALLOCATE_BACKUP_PIECE: l_needsize = ' || l_needsize);
 
--
--
--
    IF (l_odb_rowid IS NULL) THEN
      BEGIN
        SELECT ROWID, allocated_space, used_space
          INTO l_odb_rowid, l_allocsize, l_used
          FROM odb
         WHERE db_key = l_db_key;
      EXCEPTION
        WHEN OTHERS THEN
          save_error;
          SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(
                DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM,
                'Allocate_backup_piece: cannot find odb',
                TRUE);
      END;
    ELSE
      BEGIN
         SELECT allocated_space, used_space
           INTO l_allocsize, l_used
           FROM odb
          WHERE ROWID = l_odb_rowid
            AND db_key = l_db_key;
      EXCEPTION
         WHEN e_invalid_rowid OR NO_DATA_FOUND THEN
            save_error;
            SELECT ROWID, allocated_space, used_space
              INTO l_odb_rowid, l_allocsize, l_used
              FROM odb
             WHERE db_key = l_db_key;
             clear_error;
         WHEN OTHERS THEN
           save_error;
           SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(
                 DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM,
                 'Allocate_backup_piece: cannot find odb2',
                 TRUE);
      END;
    END IF;
 
    trace1 ('ALLOCATE_BACKUP_PIECE:  Allocated = ' || l_allocsize ||
                                         ', Used = ' || l_used);
  
    IF (l_used + l_needsize <= l_allocsize) THEN
--
--
--
      IF NVL(DBMS_RA_SCHEDULER.S_CURRENT_TASK_type,-1) IN (
                                     DBMS_RA_SCHEDULER.TASK_MOVE_ALL_DB,
                                     DBMS_RA_SCHEDULER.TASK_REPAIR_DB) 
      THEN
        l_cumulative_incr := 0;
      ELSE
        l_cumulative_incr := l_needsize;
      END IF; 
 
--
--
--
--
      UPDATE odb
         SET used_space = used_space + l_needsize,
             not_taped = not_taped + l_needsize,
             cumulative_usage = cumulative_usage + l_cumulative_incr
       WHERE ROWID = l_odb_rowid
      RETURNING base_reserved_space, used_space, not_taped,
                not_taped_state, move_phase
        INTO l_reserved, l_used, l_not_taped, 
             l_not_taped_state, l_move_phase;
 
      UPDATE sbt_catalog
         SET filesize = filesize + l_needsize,
             last_entry = SYSTIMESTAMP
       WHERE ROWID = l_ct_rowid
      RETURNING filesize INTO l_filesize;
 
      IF l_filesize > l_reserved THEN
        ROLLBACK;
        RAISE DBMS_RA_SCHEDULER.E_PIECE_TOO_BIG;
      END IF;
 
      check_tape_limit(l_db_key, l_reserved, l_used, l_not_taped, 
                       l_not_taped_state, l_move_phase, l_needsize);
      trace1 ('ALLOCATE_BACKUP_PIECE: allocation granted');
      COMMIT;
      EXIT;
    END IF;
 
--
--
--
    BEGIN
      l_allocate_ok := allocate_db_space(l_sl_key, l_db_key, l_needsize);
    EXCEPTION
      WHEN DBMS_RA_SCHEDULER.E_RETRY_RESERVE 
        OR DBMS_RA_SCHEDULER.E_RETRY_ERROR 
        OR DBMS_RA_SCHEDULER.E_PENDING_INTERRUPT THEN
        save_error;
        RAISE;
      WHEN OTHERS THEN
        save_error;
        SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(
               DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM,
               'Allocate_backup_piece: allocate_db_space failure',
               TRUE);
    END;
 
    IF NOT l_allocate_ok THEN
      ROLLBACK;
      trace1 ('ALLOCATE_BACKUP_PIECE: No storage space found!');
      SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(
                                      DBMS_RA_SCHEDULER.E_NO_MORE_STORAGE_NUM,
                                      DBMS_RA_SCHEDULER.S_ALLOC_INCREMENT);
    END IF;
  END LOOP;
 
  unlock_db (l_db_key);
  
--
  BEGIN
    used_space_check (l_db_key, l_sl_key);
  EXCEPTION
    WHEN OTHERS THEN
      save_error;
      SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(
             DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM,
             'Allocate_backup_piece: used_space_check failure',
             TRUE);
  END;
 
  trace1 ('ALLOCATE_BACKUP_PIECE: Completed.');
EXCEPTION
    WHEN OTHERS THEN
      save_error;
      ROLLBACK;
 
      IF l_db_key IS NOT NULL THEN
--
--
--
--
--
        UPDATE sbt_catalog
          SET last_entry = SYSTIMESTAMP
          WHERE ROWID = l_ct_rowid;
        COMMIT;
        unlock_db (l_db_key);
      END IF;
 
      RAISE;
END allocate_backup_piece;
 
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE name_backup_piece(
                      p_ct_key       IN NUMBER,
                      p_filename     IN VARCHAR2) IS
    l_db_key         NUMBER;
    l_filename       sbt_catalog.filename%TYPE;
    l_filesize       NUMBER;
BEGIN
  trace1 ('NAME_BACKUP_PIECE for ' || 'ctkey ' || p_ct_key ||
          ' fname ' || p_filename);
 
--
--
--
  UPDATE sbt_catalog
     SET filename = p_filename
   WHERE ct_key = p_ct_key;
 
--
--
--
--
--
--
--
--
--
--
--
--
 
--
--
--
--
       
  IF SQL%ROWCOUNT = 0 THEN
    trace1 ('NAME_BACKUP_PIECE: no unallocated backup found');
 
--
--
--
    SELECT filename, filesize
      INTO l_filename, l_filesize
      FROM sbt_catalog
     WHERE ct_key = p_ct_key;
 
    SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(
                DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM,
                'Attempt to name a backup up piece that was already named: ' ||
                'Old name=' || l_filename ||
                '; Old size=' || l_filesize ||
                '; New name=' || p_filename,
                FALSE);
  END IF;
 
  COMMIT;
 
EXCEPTION
  WHEN NO_DATA_FOUND THEN
--
--
--
    save_error;
    trace1 ('NAME_BACKUP_PIECE: backup not found');
    RAISE DBMS_RA_SCHEDULER.E_BACKUP_NOT_FOUND;
END name_backup_piece;
 
--
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE finish_backup_piece(
                        p_db_key       IN NUMBER,
                        p_handle       IN VARCHAR2,
                        p_pieceinc     IN VARCHAR2,
                        p_ct_key       IN NUMBER) IS
 
    l_filesize       NUMBER;
    l_backuppiece_id NUMBER;
    l_backupset_id   NUMBER;
    l_incr_level     NUMBER;
    task_rec         task%ROWTYPE;
    l_files          NUMBER;
    l_piecename      VARCHAR2(513);
    l_cnt            NUMBER;
 
BEGIN
  trace1 ('FINISH_BACKUP_PIECE for' ||
          ' db_key '  || p_db_key ||
          ', handle ' || p_handle ||
          ', pieceinc ' || p_pieceinc);
 
--
 
--
--
--
  BEGIN
    SELECT filesize INTO l_filesize FROM sbt_catalog
     WHERE db_key   = p_db_key
       AND handle   = p_handle
       AND pieceinc = p_pieceinc
       AND ct_key   = p_ct_key;
  EXCEPTION
    WHEN no_data_found THEN
      save_error;
      SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(
           DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM, 'file piece is not right');
    WHEN OTHERS THEN
      save_error;
      RAISE;
  END;
 
  trace1 ('FINISH_BACKUP_PIECE: handle= "' || p_handle ||
                               '" l_filesize=' || l_filesize);
 
--
--
--
  BEGIN
    sys.kbrsi_icd.rsInspectBackupPiece(
       handle        => p_handle,
       vbkey         => null,
       bpsize        => l_filesize,
       chktype       => DBMS_RA_INT.KBRSCHKTYPE_FILE,
       fno           => null,
       lib_key       => null, /* local disk file */
       ct_key        => p_ct_key,
       bpkey         => l_backuppiece_id,
       template_key  => null);
 
--
    SELECT bs_key
      INTO l_backupset_id
      FROM bp
     WHERE bp.bp_key = l_backuppiece_id AND bp.status != 'D';
 
--
--
--
    dbms_ra_scheduler.replicate_one_bp (p_db_key => p_db_key,
                                        p_bp_key => l_backuppiece_id);
 
 
  EXCEPTION
    WHEN OTHERS THEN
        save_error;
        trace1 ('FINISH_BACKUP_PIECE: Backup piece returned:' || SQLERRM);
        RAISE;
  END;
 
  trace1 ('FINISH_BACKUP_PIECE: rsInspectBackupPiece returned ' ||
                    ' dbkey='      || p_db_key        ||
                    ' bskey='      || l_backupset_id  ||
                    ' bpkey='      || l_backuppiece_id);
 
--
  SELECT COUNT(*) INTO l_cnt
    FROM bdf
    WHERE bs_key = l_backupset_id
      AND (incr_level IS NOT NULL OR incr_scn > 0);
  IF (l_cnt > 0)
  THEN
    task_rec.task_type   := DBMS_RA_SCHEDULER.TASK_INDEX_BACKUP;
    task_rec.flags       := DBMS_RA_SCHEDULER.TASKS_RECEIVED_BACKUP;
    task_rec.db_key      := p_db_key;
    task_rec.param_num1  := l_backupset_id;
    task_rec.param_num1  := l_backuppiece_id;
    DBMS_RA_SCHEDULER.NEW_TASK (task_rec);
  END IF;
 
  COMMIT;
  trace1 ('FINISH_BACKUP_PIECE: Fin.');
END finish_backup_piece;
 
 
--
--
--
--
--
--
--
--
--
--
PROCEDURE swap_backup_piece(p_bpkey      IN NUMBER) IS
  l_task NUMBER;
BEGIN
--
--
  FOR srcb IN (SELECT bs_key, bp_key, piece#, v.vcbp_key, v.vb_key
               FROM bp p JOIN sbt_task t USING (bs_key, piece#)
                         JOIN vbdf v ON p.db_key = v.db_key
                                    AND p.bp_key = v.srcbp_key
               WHERE bp_key = p_bpkey
                 AND v.relfno = 1)
  LOOP
--
    SYS.KBRSI_ICD.RSSCHEDLOCK (waitforwork => 0);
 
--
--
    SELECT MAX(task_id) INTO l_task
      FROM task JOIN sbt_task USING (task_id)
      WHERE bs_key = srcb.bs_key
        AND piece# = srcb.piece#
        AND (state = DBMS_RA_SCHEDULER.STATE_RUNNING
             OR failure_cnt > 0);
 
--
    IF l_task IS NULL THEN
      UPDATE sbt_task
        SET bs_key = (SELECT bs_key FROM bp
                      WHERE bp_key = srcb.vcbp_key
                      AND status != 'D'),
            src_bpkey = nvl2(src_bpkey, srcb.vcbp_key, NULL)
        WHERE bs_key = srcb.bs_key
          AND piece# = srcb.piece#;
      IF SQL%ROWCOUNT > 0 THEN
        trace1 ('SWAP_BACKUP_PIECE swap srcbpkey ' || srcb.bp_key ||
                ' with bpkey ' || srcb.vcbp_key);
      END IF;
 
--
      UPDATE vbdf SET srcbp_key = NULL
        WHERE vb_key = srcb.vb_key
          AND srcbp_key = p_bpkey;
 
      COMMIT;
 
      SYS.KBRSI_ICD.RSSCHEDUNLOCK;
    ELSE
--
      trace1('SWAP_BACKUP_PIECE: throwing retry for bpkey ' || srcb.bp_key);
      DBMS_RA_SCHEDULER.S_PENDING_INTERRUPT := l_task;
      RAISE DBMS_RA_SCHEDULER.E_RETRY_ERROR;
    END IF;
  END LOOP;
END swap_backup_piece;
 
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE free_backup_piece(p_dbkey      IN NUMBER,
                            p_piecename  IN VARCHAR2,
                            p_ftype      IN NUMBER   DEFAULT NULL,
                            p_fincarn    IN VARCHAR2 DEFAULT NULL,
                            p_can_defer  IN BOOLEAN  DEFAULT FALSE) IS
   l_dbid          NUMBER;
   l_db_slkey      NUMBER;       -- current sl for database
   l_fincarn       sbt_catalog.pieceinc%type;
   l_bpkey         NUMBER;
   l_ftype         NUMBER;
   l_currinc       NUMBER;
   new_task_rec    task%ROWTYPE;
BEGIN
   trace1 ('FREE_BACKUP_PIECE for '  ||
           ' db_key '     || p_dbkey ||
           ' ,piecename ' || p_piecename);
 
--
   IF (p_can_defer AND DBMS_RA_SCHEDULER.S_DEFER_DELETE > 0) THEN
     SELECT MAX(bp_key) INTO l_bpkey FROM bp WHERE handle = p_piecename;
     IF (l_bpkey IS NOT NULL) THEN
       trace1 ('FREE_BACKUP_PIECE: Test Defer Delete bp_key = ' || l_bpkey);
       dbms_rcvcat.rsDeleteBackupPiece(l_bpkey, 'N');
     END IF;
 
     RAISE DBMS_RA_SCHEDULER.E_RETRY_ERROR;
   END IF;
 
--
   SELECT db.db_id, odb.sl_key, db.curr_dbinc_key
     INTO l_dbid, l_db_slkey, l_currinc
     FROM db, odb
    WHERE db.db_key = p_dbkey AND
          db.db_key = odb.db_key;
 
--
   IF (p_fincarn IS NULL) THEN
      SELECT MIN(pieceinc), MIN(bp_key),
             DECODE(MIN(ftype),
                    'F', DBMS_RA_INT.KBRSCHKTYPE_FILE,
                    'V', DBMS_RA_INT.KBRSCHKTYPE_VIRTUAL,
                    'T', DBMS_RA_INT.KBRSCHKTYPE_TAPE,
                    NULL)
        INTO l_fincarn, l_bpkey, l_ftype
        FROM sbt_catalog ct
       WHERE ct.handle = p_piecename
         AND ct.bp_key IS NOT NULL;
   ELSE
      l_fincarn := p_fincarn;
      SELECT min(bp_key),
             DECODE(MIN(ftype),
                    'F', DBMS_RA_INT.KBRSCHKTYPE_FILE,
                    'V', DBMS_RA_INT.KBRSCHKTYPE_VIRTUAL,
                    'T', DBMS_RA_INT.KBRSCHKTYPE_TAPE,
                    NULL)
        INTO l_bpkey, l_ftype
        FROM sbt_catalog ct
       WHERE ct.pieceinc = l_fincarn
         AND ct.handle = p_piecename;
   END IF;
 
--
   IF (p_ftype IS NOT NULL) THEN
      IF (p_ftype != nvl(l_ftype, p_ftype)) THEN
         sys.dbms_sys_error.raise_system_error
            (DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM, 'mismatched ftype');
      END IF;
      l_ftype := p_ftype;
   END IF;
 
   free_backup_piece_opt(
      p_dbkey     => p_dbkey,
      p_piecename => p_piecename,
      p_db_slkey  => l_db_slkey,
      p_dbid      => l_dbid,
      p_currinc   => l_currinc,
      p_bpkey     => l_bpkey,
      p_ftype     => l_ftype,
      p_fincarn   => l_fincarn);
EXCEPTION
   WHEN NO_DATA_FOUND THEN
     save_error;
     ROLLBACK;
 
--
     SELECT MAX(bp_key) INTO l_bpkey
       FROM sbt_catalog
       WHERE handle = p_piecename
         AND (pieceinc = p_fincarn OR p_fincarn IS NULL)
         AND (bp_key IS NOT NULL OR p_fincarn IS NOT NULL);
     IF l_bpkey IS NULL THEN
       tracex ('FREE_BACKUP_PIECE: already deleted');
       clear_error;
     ELSE
       RAISE;
     END IF;
 
   WHEN DBMS_RA_SCHEDULER.E_RETRY_ERROR THEN
      save_error;
      ROLLBACK;
      trace1 ('FREE_BACKUP_PIECE: retry error');
      IF (NOT p_can_defer) THEN
         RAISE;
      END IF;
 
      IF (l_bpkey IS NOT NULL) THEN
         trace1 ('FREE_BACKUP_PIECE: Defer Delete bp_key = ' || l_bpkey);
         dbms_rcvcat.rsDeleteBackupPiece(l_bpkey, 'N');
      END IF;
 
--
      new_task_rec.task_type   := DBMS_RA_SCHEDULER.TASK_DEFERRED_DELETE;
      new_task_rec.flags       := 0;
      new_task_rec.db_key      := p_dbkey;
      new_task_rec.param_char1 := p_piecename;
      new_task_rec.param_num1  := p_ftype;
      new_task_rec.param_char2 := p_fincarn;
 
      trace1 ('FREE_BACKUP_PIECE: Defer task queued ' || p_piecename);
      DBMS_RA_SCHEDULER.NEW_TASK (task_rec => new_task_rec, p_commit => FALSE);
 
--
      COMMIT;
      clear_error;
 
   WHEN OTHERS THEN
      save_error;
      ROLLBACK;
      RAISE;
END free_backup_piece;
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE free_backup_piece_opt(
   p_dbkey      IN NUMBER,
   p_piecename  IN VARCHAR2,
   p_db_slkey   IN NUMBER,
   p_dbid       IN NUMBER,
   p_currinc    IN NUMBER,
   p_bpkey      IN NUMBER,
   p_ftype      IN NUMBER    DEFAULT NULL,
   p_fincarn    IN VARCHAR2  DEFAULT NULL,
   p_libkey     IN NUMBER    DEFAULT NULL,
   p_spawn_job  IN BOOLEAN   DEFAULT TRUE,
   p_notasks    IN BOOLEAN   DEFAULT FALSE,
   p_noplans    IN BOOLEAN   DEFAULT FALSE)
IS
   l_slkey       NUMBER;
   l_filesize    NUMBER;
   new_task_rec  task%ROWTYPE;
   l_fincarn     sbt_catalog.pieceinc%type := p_fincarn;
   l_ftype       NUMBER := p_ftype;
   l_libkey      NUMBER := p_libkey;
   l_bpkey       NUMBER := p_bpkey;
   l_ctkey       NUMBER;
   l_rsaccess    VARCHAR2(1);
   l_filename    VARCHAR2(512);
   l_db_locked   BOOLEAN := FALSE;
BEGIN
   tracex('FREE_BACKUP_PIECE_OPT for'  ||
          ' db_key='     || p_dbkey ||
          ', piecename=' || p_piecename ||
          ', dbslkey='   || print(p_db_slkey) ||
          ', dbid='      || print(p_dbid) ||
          ', currinc='   || print(p_currinc) ||
          ', bpkey='     || print(p_bpkey) ||
          ', ftype='     || print(p_ftype) ||
          ', fincarn='   || print(p_fincarn));
 
--
   IF (l_bpkey IS NOT NULL AND (p_fincarn IS NULL OR p_ftype IS NULL)) THEN
     BEGIN
       SELECT pieceinc,
              DECODE(ftype,
                     'F', DBMS_RA_INT.KBRSCHKTYPE_FILE,
                     'V', DBMS_RA_INT.KBRSCHKTYPE_VIRTUAL,
                     'T', DBMS_RA_INT.KBRSCHKTYPE_TAPE,
                     'D', DBMS_RA_INT.KBRSCHKTYPE_DISK,
                     NULL)
         INTO l_fincarn, l_ftype
         FROM sbt_catalog ct
         WHERE ct.bp_key = l_bpkey;
     EXCEPTION
       WHEN no_data_found THEN
         save_error;
         clear_error;
         RETURN;  -- No backup piece, nothing to do
     END;
   END IF;
 
   IF l_ftype IS NULL THEN
     trace1('FREE_BACKUP_PIECE_OPT ' || p_piecename || ' already deleted');
     IF p_bpkey IS NOT NULL THEN
       SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(
                DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM, 'already deleted');
     END IF;
     RETURN;
   END IF;
 
--
   IF (l_bpkey IS NOT NULL) THEN
      dbms_ra_int.write_lock(DBMS_RA_INT.KEY_BP, l_bpkey);
   ELSIF (l_ftype = DBMS_RA_INT.KBRSCHKTYPE_FILE) THEN
      SELECT ct_key INTO l_ctkey
        FROM sbt_catalog
       WHERE handle = p_piecename
         AND pieceinc = l_fincarn;
      dbms_ra_int.write_lock(DBMS_RA_INT.KEY_CT, l_ctkey);
   END IF;
 
--
   IF (l_ftype = DBMS_RA_INT.KBRSCHKTYPE_TAPE) THEN
      IF (l_libkey IS NULL) THEN
         SELECT bp.lib_key INTO l_libkey
           FROM bp
          WHERE bp.handle = p_piecename
            AND bp.db_key = p_dbkey;
      END IF;
   END IF;
 
   CASE l_ftype
      WHEN DBMS_RA_INT.KBRSCHKTYPE_FILE THEN
         trace1 ('FREE_BACKUP_PIECE_OPT: file piece');
 
--
--
--
         l_db_locked := TRUE;
         lock_db (p_dbkey);
 
--
--
--
         SELECT MIN(sl_key), MIN(filesize), MIN(filename)
           INTO l_slkey, l_filesize, l_filename
           FROM sbt_catalog
          WHERE pieceinc = l_fincarn AND
                handle = p_piecename;
 
         trace1 ('FREE_BACKUP_PIECE_OPT: filesize=' || print(l_filesize) ||
                 ', fname ' || l_filename);
 
--
--
--
         IF l_filesize IS NOT NULL THEN
--
--
--
--
--
--
--
            l_rsaccess := 'L';
            IF p_bpkey IS NOT NULL AND p_fincarn IS NULL THEN
              SELECT ba_access INTO l_rsaccess FROM bp WHERE bp_key = p_bpkey;
            END IF;
            IF l_rsaccess = 'L' AND l_filename IS NOT NULL THEN
              SYS.KBRSI_ICD.rsDeleteFile(l_filename);
            END IF;
 
--
--
--
            UPDATE sbt_catalog
              SET sl_key          = NULL,
                  filesize        = NULL,
                  last_entry      = NULL
              WHERE handle = p_piecename
                AND pieceinc = l_fincarn;
 
--
--
--
            return_space(l_filesize, p_dbkey, l_slkey, p_db_slkey);
         END IF;
 
--
--
--
         COMMIT;
         unlock_db(p_dbkey);
         l_db_locked := FALSE;
 
--
         IF l_filesize IS NOT NULL THEN
           used_space_check (p_dbkey, l_slkey);
         END IF;
         
         IF (l_bpkey IS NULL) THEN
--
            trace1 ('FREE_BACKUP_PIECE_OPT: Deleting sbt_catalog entry');
            DELETE FROM sbt_catalog
             WHERE handle = p_piecename
               AND pieceinc = l_fincarn;
         END IF;
 
      WHEN DBMS_RA_INT.KBRSCHKTYPE_TAPE THEN
         trace1 ('FREE_BACKUP_PIECE_OPT: tape chunk');
 
      WHEN DBMS_RA_INT.KBRSCHKTYPE_VIRTUAL THEN
         trace1 ('FREE_BACKUP_PIECE_OPT: virtual chunk');
 
--
--
         IF p_noplans AND p_notasks THEN
           trace1('FREE_BACKUP_PIECE_OPT: Skipping deleteVB');
         ELSE
           dbms_ra_pool.deleteVB(p_slkey   => p_db_slkey,
                                 p_dbkey   => p_dbkey,
                                 p_currinc => p_currinc,
                                 p_bpkey   => l_bpkey,
                                 p_noplans => p_noplans,
                                 p_notasks => p_notasks);
         END IF;
 
      WHEN DBMS_RA_INT.KBRSCHKTYPE_DISK THEN
         trace1 ('FREE_BACKUP_PIECE_OPT: disk chunk');
 
      ELSE
         sys.dbms_sys_error.raise_system_error(
            DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM, 'unknown ftype');
   END CASE;
 
   IF (l_bpkey IS NOT NULL) THEN
--
      trace1 ('FREE_BACKUP_PIECE_OPT: Deleting bp_key = ' || l_bpkey);
      dbms_rcvcat.rsDeleteBackupPiece(l_bpkey, 'Y');
   END IF;
 
   IF (l_ftype = DBMS_RA_INT.KBRSCHKTYPE_TAPE) AND (NOT p_notasks) THEN
--
      new_task_rec.task_type   := DBMS_RA_SCHEDULER.TASK_PURGE_SBT;
      new_task_rec.flags       := 0;
      new_task_rec.db_key      := p_dbkey;
      new_task_rec.param_num1  := l_libkey;
      new_task_rec.param_char1 := p_piecename;
      DBMS_RA_SCHEDULER.NEW_TASK (task_rec => new_task_rec, p_commit => FALSE);
   END IF;
 
--
   COMMIT;
 
--
   IF (l_bpkey IS NOT NULL) THEN
      dbms_ra_int.unlock(DBMS_RA_INT.KEY_BP, l_bpkey);
      l_bpkey := NULL;
   END IF;
   IF (l_ctkey IS NOT NULL) THEN
      dbms_ra_int.unlock(DBMS_RA_INT.KEY_CT, l_ctkey);
      l_ctkey := NULL;
   END IF;
   
   IF (l_ftype = DBMS_RA_INT.KBRSCHKTYPE_TAPE) THEN
--
     IF (p_spawn_job) THEN
       dbms_ra_scheduler.queue_spawn_sbt(
          p_libkey => l_libkey, p_forpurge => TRUE);
     END IF;
   END IF;
 
   DBMS_RA_SCHEDULER.CHECK_FOR_INTERRUPT;
   trace1 ('FREE_BACKUP_PIECE_OPT: Done.');
EXCEPTION
   WHEN NO_DATA_FOUND THEN
      save_error;
      trace1 ('FREE_BACKUP_PIECE_OPT: no row found');
      ROLLBACK;
 
      IF l_db_locked THEN
        unlock_db(p_dbkey);
      END IF;
      IF (l_bpkey IS NOT NULL) THEN
        dbms_ra_int.unlock(DBMS_RA_INT.KEY_BP, l_bpkey);
      END IF;
      IF (l_ctkey IS NOT NULL) THEN
        dbms_ra_int.unlock(DBMS_RA_INT.KEY_CT, l_ctkey);
      END IF;
      clear_error;
 
   WHEN OTHERS THEN
      save_error;
      ROLLBACK;
 
      IF l_db_locked THEN
        unlock_db(p_dbkey);
      END IF;
      IF (l_bpkey IS NOT NULL) THEN
        dbms_ra_int.unlock(DBMS_RA_INT.KEY_BP, l_bpkey);
      END IF;
      IF (l_ctkey IS NOT NULL) THEN
        dbms_ra_int.unlock(DBMS_RA_INT.KEY_CT, l_ctkey);
      END IF;
      RAISE;
END free_backup_piece_opt;
 
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE finish_file(p_newfname IN  VARCHAR2,
                      p_filesize IN  NUMBER,
                      p_handle   OUT VARCHAR2,
                      p_move_bp  OUT NUMBER) IS
l_allocsize     NUMBER;
l_sl_min_alloc  NUMBER;
l_needsize      NUMBER;
l_sl_key        NUMBER;
l_db_key        NUMBER;
l_old_ct_key    NUMBER;
l_new_ct_key    NUMBER;
l_repcnt        NUMBER;
BEGIN
  trace1 ('FINISH_FILE for'  ||
          ' newfname ' || p_newfname ||
          ', filesize '  || p_filesize);
 
--
--
--
  SELECT db_key
    INTO l_db_key
    FROM sbt_catalog
   WHERE filename = p_newfname
     AND filesize IS NOT NULL;
 
  lock_db(l_db_key);
 
--
--
--
  SELECT filesize, sl_key, handle, ct_key
    INTO l_allocsize, l_sl_key, p_handle, l_new_ct_key
    FROM sbt_catalog
   WHERE filename = p_newfname
     AND filesize IS NOT NULL;
 
--
--
--
  BEGIN
    SELECT sl_min_alloc INTO l_sl_min_alloc
      FROM sl
     WHERE sl_key = l_sl_key;
 
--
--
--
    l_needsize := CEIL(p_filesize / l_sl_min_alloc) * l_sl_min_alloc;
 
 
    trace1 ('FINISH_FILE: Old allocation was: ' || l_allocsize ||
                        '; New allocation is: ' || l_needsize);
 
    IF l_allocsize < 0 THEN -- Something went horribly wrong.
      SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(
                                DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM,
                                'Bad filesize, difference is ' || l_allocsize);
    END IF;
 
  EXCEPTION
    WHEN NO_DATA_FOUND THEN
      save_error;
      trace1 ('FINISH_FILE: Copied file not found');
      SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(
                                DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM,
                                'Cannot find ' || p_newfname);
   END;
 
  IF l_allocsize < l_needsize THEN
    trace1 ('FINISH_FILE: Copied filesize cannot grow');
    SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(
                                DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM,
                                'Filesize cannot grow ' || l_allocsize);
  END IF;
 
--
--
--
--
  IF DBMS_RA_SCHEDULER.S_CURRENT_TASK_TYPE IN
      (DBMS_RA_SCHEDULER.TASK_MOVE_ALL_DB,DBMS_RA_SCHEDULER.TASK_MOVE_DF) THEN 
 
    SELECT bp.bp_key, ct.ct_key
      INTO p_move_bp, l_old_ct_key
      FROM sbt_catalog ct, bp
      WHERE ct.bp_key = bp.bp_key
        AND ct.handle = p_handle
        AND bp.status != 'D';
 
    trace1 ('FINISH_FILE: p_move_bp=' || print(p_move_bp));
 
--
    UPDATE sbt_catalog ct
       SET ct.completed = nvl2(ct.completed, 'N', null)
          ,ct.endupload = nvl2(ct.endupload, 'D', null)
          ,ct.bp_key    = null
     WHERE ct.ct_key = l_old_ct_key;
 
--
--
--
    dbms_ra_int.finalizeSbtCatalog(p_bp_key => p_move_bp
                                  ,p_ct_key => l_new_ct_key
                                  ,p_xmldoc => NULL);
  END IF;
 
--
--
--
  UPDATE sbt_catalog
    SET filesize = l_needsize
    WHERE db_key = l_db_key
      AND ct_key = l_new_ct_key;
 
--
--
--
  return_space ((l_allocsize - l_needsize), l_db_key, l_sl_key, NULL);
 
  COMMIT;
 
  unlock_db (l_db_key);
 
--
  used_space_check (l_db_key, l_sl_key);
 
  trace1 ('FINISH_FILE: Completed.');
 
EXCEPTION
    WHEN OTHERS THEN
      save_error;
      ROLLBACK;
      unlock_db (l_db_key);
      RAISE;
END finish_file;
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE preallocate_chunks(
                        p_db_key    IN NUMBER,
                        p_count     IN NUMBER,
                        p_required  IN BOOLEAN DEFAULT FALSE) IS
 
l_used            NUMBER;
l_sl_key          NUMBER;
l_allocsize       NUMBER;
l_count           NUMBER := p_count;
l_chunksize       NUMBER;
l_reserved        NUMBER;
l_not_taped       NUMBER;
l_not_taped_state VARCHAR2(1);
l_move_phase      NUMBER;
l_cachescn        NUMBER;
 
BEGIN
  trace1 ('PREALLOCATE_CHUNKS for '  ||
            'db_key  '  || p_db_key ||
            ', count '  || p_count);
 
--
--
--
  IF DBMS_RA_SCHEDULER.S_CURRENT_TASK IS NULL THEN
    sys.dbms_sys_error.raise_system_error(
                                        DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM,
                                        'cannot preallocate without a task');
  END IF;
 
--
--
--
  lock_db(p_db_key);
 
--
--
--
  LOOP
--
--
--
    SELECT allocated_space, used_space, odb.sl_key, odb.sl_min_alloc
      INTO l_allocsize, l_used, l_sl_key, l_chunksize
      FROM odb, sl
      WHERE db_key = p_db_key
        AND odb.sl_key = sl.sl_key;
 
    trace1('PREALLOCATE_CHUNKS: Allocated_space='  || l_allocsize ||
                             ', Used_space='  || l_used);
 
    IF l_used + (l_count * l_chunksize) <= l_allocsize THEN
--
--
--
      UPDATE odb
        SET used_space = used_space + (l_count * l_chunksize),
            not_taped = not_taped + (l_count * l_chunksize)
        WHERE db_key = p_db_key
      RETURNING base_reserved_space, used_space, not_taped,
                not_taped_state, move_phase
        INTO l_reserved, l_used, l_not_taped, 
             l_not_taped_state, l_move_phase;
 
      DBMS_RA_SCHEDULER.S_CACHED_STORAGE := TRUE;
 
      UPDATE task_chunk_cache SET chunk_cache = chunk_cache + l_count
        WHERE inst_id = DBMS_RA_SCHEDULER.S_INSTANCE
          AND task_id = DBMS_RA_SCHEDULER.S_CURRENT_TASK;
 
      IF SQL%ROWCOUNT = 0 THEN
--
        INSERT INTO task_chunk_cache (inst_id, task_id, 
                                      chunk_cache, cumulative_incr)
                              VALUES (DBMS_RA_SCHEDULER.S_INSTANCE, 
                                      DBMS_RA_SCHEDULER.S_CURRENT_TASK,
                                      l_count, 0);
 
        UPDATE task 
          SET flags = flags - 
                   BITAND (flags, DBMS_RA_SCHEDULER.TASKS_CHUNK_CACHE_ACTIVE) +
                   DBMS_RA_SCHEDULER.TASKS_CHUNK_CACHE_ACTIVE
          WHERE task_id = DBMS_RA_SCHEDULER.S_CURRENT_TASK;
      END IF;
 
--
--
--
--
      IF  DBMS_RA_SCHEDULER.S_CURRENT_TASK_TYPE = 
                                      DBMS_RA_SCHEDULER.TASK_INDEX_BACKUP THEN
 
        check_tape_limit(p_db_key, l_reserved, l_used, l_not_taped, 
                         l_not_taped_state, l_move_phase,
                         (l_count * l_chunksize));
      END IF;
 
      COMMIT;
      EXIT;
    END IF;
 
--
--
--
    trace1 ('PREALLOCATE_CHUNKS: Need more disk space');
 
    IF NOT allocate_db_space(l_sl_key, p_db_key, l_count*l_chunksize) THEN
      ROLLBACK;
      SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(
                                     DBMS_RA_SCHEDULER.E_NO_MORE_STORAGE_NUM, 
                                     DBMS_RA_SCHEDULER.S_ALLOC_INCREMENT);
    END IF;
 
  END LOOP;
 
  unlock_db (p_db_key);
 
--
  used_space_check (p_db_key, l_sl_key);
  trace1 ('PREALLOCATE_CHUNKS: Completed.');
 
EXCEPTION
    WHEN DBMS_RA_SCHEDULER.E_RETRY_RESERVE THEN
      save_error;
      ROLLBACK;
      trace1 ('PREALLOCATE_CHUNKS: Forcing a retry');
      unlock_db (p_db_key);
      RAISE;
 
    WHEN OTHERS THEN
      save_error;
      trace1 ('PREALLOCATE_CHUNKS: Unexpected exception:  ' || SQLERRM);
      ROLLBACK;
      unlock_db (p_db_key);
      RAISE;
END preallocate_chunks;
 
--
--
--
--
--
--
--
--
--
--
--
--
FUNCTION get_chunkno(
                        p_df_key    IN NUMBER,
                        p_count     IN NUMBER DEFAULT 1) RETURN NUMBER IS
 
PRAGMA AUTONOMOUS_TRANSACTION;
l_usable_cache  BOOLEAN;
l_df_char       VARCHAR2(16) := TO_CHAR(p_df_key,'FMXXXXXXXXXXXXXXXX');
l_allocation    NUMBER := GREATEST(p_count, DBMS_RA_SCHEDULER.S_CHUNKNO_ALLOC);
 
BEGIN
--
--
--
  IF (s_chunkno_cache_execution <> DBMS_RA_SCHEDULER.S_NOW_SERVING) THEN
    s_chunkno_cache_first.DELETE;
    s_chunkno_cache_next.DELETE;
    s_chunkno_cache_execution := DBMS_RA_SCHEDULER.S_NOW_SERVING;
  END IF;
 
--
--
--
--
  l_usable_cache := s_chunkno_cache_first.EXISTS(l_df_char);
 
  IF l_usable_cache THEN
    l_usable_cache := (s_chunkno_cache_next(l_df_char)  >= 
                       (s_chunkno_cache_first(l_df_char) + p_count));
  END IF;
 
  IF NOT l_usable_cache THEN
--
--
--
--
    FOR i IN 1..100 LOOP
      BEGIN
        UPDATE df_seq SET chunkno = chunkno + l_allocation
          WHERE df_key = p_df_key
          RETURNING chunkno INTO s_chunkno_cache_next(l_df_char);
 
--
--
--
        IF SQL%ROWCOUNT = 0 THEN
          s_chunkno_cache_next(l_df_char) := l_allocation + 1;
          INSERT INTO  df_seq(df_key, chunkno) 
             VALUES (p_df_key, s_chunkno_cache_next(l_df_char));
        END IF;
        COMMIT;
        EXIT;
 
      EXCEPTION
        WHEN DUP_VAL_ON_INDEX THEN
          save_error;
          trace1('GET_CHUNKNO:  Retrying after constraint violation seen');
          DBMS_LOCK.SLEEP(1);
          clear_error;
          CONTINUE;
      END;
    END LOOP;
 
    s_chunkno_cache_first(l_df_char) := 
                                s_chunkno_cache_next(l_df_char) - l_allocation;
    trace1('GET_CHUNKNO:  Allocated ids from ' || 
                          s_chunkno_cache_first(l_df_char) || 'through ' || 
                          print(s_chunkno_cache_next(l_df_char)-1)); 
  END IF;
 
--
--
--
  s_chunkno_cache_first(l_df_char) := 
                                   s_chunkno_cache_first(l_df_char) + p_count;
 
--
--
--
  RETURN s_chunkno_cache_first(l_df_char) - p_count;
END get_chunkno;
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE allocate_block_pool_chunk(
                        p_db_key    IN NUMBER,
                        p_dbinc_key IN NUMBER,
                        p_df_key    IN NUMBER,
                        p_vb_key    IN NUMBER,
                        p_chunkno  OUT NUMBER) IS
 
PRAGMA AUTONOMOUS_TRANSACTION;
l_allocsize       NUMBER;
l_cumulative_incr NUMBER;
l_used            NUMBER;
l_task_purge_reserve NUMBER;
l_task_chunk_cache   NUMBER;
l_allocdone       BOOLEAN := FALSE;
l_chunksize       NUMBER;
 
BEGIN
  trace1 ('ALLOCATE_BLOCK_POOL_CHUNK for '  ||
            'db_key '  || p_db_key ||
          ', df_key '  || p_df_key);
 
--
--
--
  IF (s_sl_info_cache_execution <> DBMS_RA_SCHEDULER.S_NOW_SERVING) THEN
--
--
--
    BEGIN
      SELECT odb.sl_key, sl.sl_min_alloc
        INTO s_sl_info_key, s_sl_info_chunksize
        FROM odb, sl
        WHERE odb.db_key = p_db_key AND
              odb.sl_key = sl.sl_key;
 
      s_sl_info_cache_execution := DBMS_RA_SCHEDULER.S_NOW_SERVING;
      trace1 ('ALLOCATE_BLOCK_POOL_CHUNK: sl_key is: ' || s_sl_info_key);
 
    EXCEPTION
      WHEN NO_DATA_FOUND THEN
        save_error;
        trace1 ('ALLOCATE_BLOCK_POOL_CHUNK: No storage location found');
        RAISE DBMS_RA_SCHEDULER.E_BAD_STORAGE_LOCATION;
    END;
  END IF;
 
--
--
--
  SELECT purge_reserve, NVL(chunk_cache,0)
    INTO l_task_purge_reserve, l_task_chunk_cache
    FROM task LEFT OUTER JOIN task_chunk_cache USING (task_id)
    WHERE task_id = DBMS_RA_SCHEDULER.S_CURRENT_TASK;
 
--
--
--
--
  IF DBMS_RA_SCHEDULER.S_PURGING_ACTIVE AND
     l_task_purge_reserve > 0 THEN
 
--
--
--
--
    DBMS_RA_SCHEDULER.S_CACHED_STORAGE := TRUE;
    UPDATE task
      SET purge_reserve = purge_reserve - 1
      WHERE  task_id = DBMS_RA_SCHEDULER.S_CURRENT_TASK;
 
    trace1 ('ALLOCATE_BLOCK_POOL_CHUNK: Allocated from reserve. Remaining=' ||
                                              TO_CHAR(l_task_purge_reserve-1));
 
  ELSE
--
--
--
--
--
    IF l_task_chunk_cache < 1 THEN
      preallocate_chunks (p_db_key, DBMS_RA_SCHEDULER.S_CHUNK_CACHE);
    END IF; 
 
--
--
--
--
    IF DBMS_RA_SCHEDULER.S_POLLED_INPUT THEN
      l_cumulative_incr := s_sl_info_chunksize;
    ELSE
      l_cumulative_incr := 0;
    END IF; 
 
    DBMS_RA_SCHEDULER.S_CACHED_STORAGE := TRUE;
    UPDATE task_chunk_cache
      SET chunk_cache = chunk_cache - 1,
          cumulative_incr = cumulative_incr + l_cumulative_incr
    WHERE task_id = DBMS_RA_SCHEDULER.S_CURRENT_TASK;
  END IF;
 
--
--
--
  p_chunkno := get_chunkno (p_df_key);
  INSERT INTO chunks (  sl_key,   dbinc_key,    df_key,
                        chunkno,   filesize,    clean_key)
              VALUES (s_sl_info_key, p_dbinc_key,  p_df_key,
                      p_chunkno, 0, p_vb_key)
              RETURNING chunkno INTO p_chunkno;
  COMMIT;
  trace1 ('ALLOCATE_BLOCK_POOL_CHUNK chunkno ' || p_chunkno);
 
--
  used_space_check (p_db_key, s_sl_info_key);
 
  trace1 ('ALLOCATE_BLOCK_POOL_CHUNK: Completed.');
 
EXCEPTION
  WHEN OTHERS THEN
    save_error;
    trace1 ('ALLOCATE_BLOCK_POOL_CHUNK: Exception seen:  ' || SQLERRM);
    RAISE;
END allocate_block_pool_chunk;
 
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE free_block_pool_chunk(
                        p_db_key    IN NUMBER,
                        p_dbinc_key IN NUMBER,
                        p_df_key    IN NUMBER,
                        p_chunkno   IN NUMBER) IS
 
PRAGMA AUTONOMOUS_TRANSACTION;
l_sl_key           NUMBER;
l_move_phase       NUMBER;
l_chunksize        NUMBER;
l_task_chunk_cache NUMBER;
 
BEGIN
  trace1 ('FREE_BLOCK_POOL_CHUNK for '  ||
          ', db_key '  || p_db_key ||
          ', dbinc_key '  || p_dbinc_key ||
          ', df_key '  || p_df_key ||
          ', chunkno '  || p_chunkno);
 
--
--
--
  DELETE FROM chunks
    WHERE  dbinc_key = p_dbinc_key AND
           df_key = p_df_key AND
           chunkno = p_chunkno
    RETURNING sl_key INTO l_sl_key;
 
  IF SQL%ROWCOUNT = 0 THEN
    trace1 ('FREE_BLOCK_POOL_CHUNK: Chunk not found');
    RETURN;
  END IF;
 
  trace1 ('FREE_BLOCK_POOL_CHUNK dbinc_key ' || p_dbinc_key ||
          ' chunkno ' || p_chunkno || ' was deleted');
 
--
--
--
--
--
--
  SELECT move_phase, sl_min_alloc INTO l_move_phase, l_chunksize 
    FROM odb
    WHERE db_key = p_db_key;
 
  IF (l_move_phase IS NOT NULL) OR 
     (DBMS_RA_SCHEDULER.S_CURRENT_TASK IS NULL) THEN
    trace1 ('FREE_BLOCK_POOL_CHUNK: DB is in motion or no active task');
 
--
--
    BEGIN
      lock_db(p_db_key);
 
      return_space(l_chunksize, p_db_key, l_sl_key, NULL);
      COMMIT;
 
      unlock_db(p_db_key);
 
--
      used_space_check (p_db_key, l_sl_key);
    EXCEPTION
      WHEN OTHERS THEN
        save_error;
        trace1 ('FREE_BLOCK_POOL_CHUNK: Exception seen:  ' || SQLERRM);
        unlock_db(p_db_key);
        RAISE;
    END;   
  ELSE
--
--
--
    DBMS_RA_SCHEDULER.S_CACHED_STORAGE := TRUE;
 
    UPDATE task_chunk_cache SET chunk_cache = chunk_cache + 1
      WHERE inst_id = DBMS_RA_SCHEDULER.S_INSTANCE
        AND task_id = DBMS_RA_SCHEDULER.S_CURRENT_TASK
      RETURNING chunk_cache INTO l_task_chunk_cache;
 
    IF SQL%ROWCOUNT = 0 THEN
--
      INSERT INTO task_chunk_cache (inst_id, task_id, 
                                    chunk_cache, cumulative_incr)
                            VALUES (DBMS_RA_SCHEDULER.S_INSTANCE, 
                                    DBMS_RA_SCHEDULER.S_CURRENT_TASK,
                                    1, 0);
      l_task_chunk_cache := 1;
 
      UPDATE task 
        SET flags = flags - 
                 BITAND (flags, DBMS_RA_SCHEDULER.TASKS_CHUNK_CACHE_ACTIVE) +
                 DBMS_RA_SCHEDULER.TASKS_CHUNK_CACHE_ACTIVE
        WHERE task_id = DBMS_RA_SCHEDULER.S_CURRENT_TASK;
    END IF;
 
--
--
--
--
    COMMIT;
 
--
--
--
    IF l_task_chunk_cache >= DBMS_RA_SCHEDULER.S_CHUNK_CACHE THEN
--
--
--
--
      BEGIN
        lock_db(p_db_key);
 
        return_space(l_chunksize * l_task_chunk_cache, 
                     p_db_key, l_sl_key, NULL);
 
        UPDATE task_chunk_cache SET chunk_cache = 0
          WHERE inst_id = DBMS_RA_SCHEDULER.S_INSTANCE
            AND task_id = DBMS_RA_SCHEDULER.S_CURRENT_TASK;
        COMMIT;
 
        unlock_db(p_db_key);
 
--
        used_space_check (p_db_key, l_sl_key);
      EXCEPTION
        WHEN OTHERS THEN
          save_error;
          trace1 ('FREE_BLOCK_POOL_CHUNK: Exception seen:  ' || SQLERRM);
          unlock_db(p_db_key);
          RAISE;
      END;
    END IF;
  END IF;
 
  trace1 ('FREE_BLOCK_POOL_CHUNK: Fin.');
END free_block_pool_chunk;
 
 
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE free_block_pool_chunks(
                        p_sl_key    IN NUMBER,
                        p_db_key    IN NUMBER,
                        p_df_key    IN NUMBER,
                        p_chunks    IN dbms_sql.number_table) IS
l_freed NUMBER;
BEGIN
  trace1('FREE_BLOCK_POOL_CHUNKS: Chunkcount=' || p_chunks.COUNT ||
                                ', sl_key=' || p_sl_key ||
                                ', db_key=' || p_db_key ||
                                ', df_key=' || p_df_key);
 
--
  IF p_chunks.COUNT = 0 THEN
    RETURN;
  END IF;
 
  lock_db(p_db_key);
 
--
  FORALL i IN 1 .. p_chunks.COUNT
    DELETE FROM chunks WHERE df_key = p_df_key AND chunkno = p_chunks(i);
  l_freed := SQL%ROWCOUNT;
 
  IF l_freed <> p_chunks.COUNT THEN
    trace1('FREE_BLOCK_POOL_CHUNKS: Alert - cnt ' || p_chunks.COUNT ||
           ', freed ' || SQL%ROWCOUNT);
    sys.dbms_sys_error.raise_system_error(
                                     DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM,
                                     'Bad free chunks: ' || l_freed ||
                                     ' vs ' || p_chunks.COUNT);
  ELSE
    trace1('FREE_BLOCK_POOL_CHUNKS: freed ' || p_chunks.COUNT);
  END IF;
 
  return_space((f_chunksize(p_db_key) * l_freed),
               p_db_key, p_sl_key, NULL);
  COMMIT;
 
  unlock_db(p_db_key);
 
--
  dbms_ra_storage.used_space_check (p_db_key, p_sl_key);
EXCEPTION
  WHEN OTHERS THEN
    save_error;
    trace1 ('FREE_BLOCK_POOL_CHUNKS: Exception seen:  ' || SQLERRM);
    unlock_db(p_db_key);
    RAISE;
END free_block_pool_chunks;
 
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE free_task_storage (p_task_id NUMBER DEFAULT NULL) IS
l_task_id          NUMBER := NVL(p_task_id, DBMS_RA_SCHEDULER.S_CURRENT_TASK);
l_db_key           NUMBER;
l_chunk_cache      NUMBER;
l_cumulative_incr  NUMBER;
 
BEGIN
  trace1 ('FREE_TASK_STORAGE id ' || l_task_id);
 
--
--
--
--
--
  BEGIN
    SELECT db_key, chunk_cache, cumulative_incr
      INTO l_db_key, l_chunk_cache, l_cumulative_incr
      FROM task JOIN task_chunk_cache USING (task_id)
      WHERE task_id = l_task_id;
  EXCEPTION
    WHEN NO_DATA_FOUND THEN 
      save_error;
      trace1 ('FREE_TASK_STORAGE: No chunk cache row.');
      clear_error;
      RETURN;
  END;
 
--
--
--
--
  lock_db (l_db_key);
 
--
--
--
  DELETE FROM task_chunk_cache WHERE task_id = l_task_id;
 
  UPDATE task
    SET flags = flags - 
                BITAND (flags, DBMS_RA_SCHEDULER.TASKS_CHUNK_CACHE_ACTIVE)
    WHERE task_id = l_task_id;
 
--
--
--
--
  IF (l_db_key IS NOT NULL) THEN
    UPDATE odb 
      SET used_space = used_space - (l_chunk_cache * sl_min_alloc),
          cumulative_usage = cumulative_usage + l_cumulative_incr
      WHERE db_key = l_db_key;
  END IF;
 
--
--
--
  COMMIT;
  unlock_db (l_db_key);
 
 
  IF p_task_id IS NULL THEN
    DBMS_RA_SCHEDULER.S_CACHED_STORAGE := FALSE;
  END IF;
 
  trace1 ('FREE_TASK_STORAGE: transferred chunks=' || l_chunk_cache ||
                           '; cumulative_incr='  || l_cumulative_incr);
 
EXCEPTION
  WHEN OTHERS THEN
    save_error;
    trace1 ('FREE_TASK_STORAGE: Error is ' || SQLERRM);
    unlock_db (l_db_key);
    RAISE;
END free_task_storage;
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE return_space (p_size IN NUMBER,
                        p_db_key IN NUMBER,
                        p_sl_key IN NUMBER,
                        p_db_sl_key IN NUMBER) IS
 
l_db_sl_key          NUMBER;
l_updated_used_space NUMBER;
 
 
l_total_usage NUMBER;
l_blockpool_usage NUMBER;
l_sbtpiece_usage NUMBER;
l_move_phase      NUMBER;
 
 
BEGIN
  trace1 ('RETURN_SPACE:  size=' || p_size ||
                       ', db_key=' || p_db_key ||
                       ', sl_key=' || p_sl_key ||
                       ', db_sl_key=' || print(p_db_sl_key));
 
--
--
--
  IF p_db_sl_key IS NOT NULL THEN
    l_db_sl_key := p_db_sl_key;
  ELSE
    SELECT sl_key INTO l_db_sl_key
      FROM odb
      WHERE db_key = p_db_key;
  END IF;
 
  trace1 ('RETURN_SPACE:  using db_sl_key=' || l_db_sl_key);
 
  IF l_db_sl_key = p_sl_key THEN
--
--
--
    UPDATE odb
      SET used_space = used_space - NVL(p_size, 0)
      WHERE db_key = p_db_key;
  ELSE
--
--
--
--
    UPDATE odb SET total_allocation = total_allocation - NVL(p_size, 0)
      WHERE db_key = p_db_key;
 
    UPDATE dbsl
      SET dbsl_used_space = dbsl_used_space - NVL(p_size, 0)
      WHERE db_key = p_db_key AND
            sl_key = p_sl_key
    RETURNING dbsl_used_space INTO l_updated_used_space;
 
    IF l_updated_used_space = 0 THEN
      trace1 ('RETURN_SPACE:  dbsl row is now empty');
      DELETE dbsl
        WHERE db_key = p_db_key AND
              sl_key = p_sl_key;
      UPDATE odb SET sls_used = sls_used - 1
        WHERE db_key = p_db_key;
    END IF;
  END IF;
 
END return_space;
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
FUNCTION reserve_block_pool_space(
                        p_db_key    IN NUMBER,
                        p_chunks    IN NUMBER,
                        p_maxchunks OUT NUMBER) RETURN NUMBER IS
 
l_sl_key          NUMBER;
l_move_phase      NUMBER;
l_allocated       NUMBER;
l_used            NUMBER;
l_freechunks      NUMBER;
l_availablechunks NUMBER;
l_purge_reserve   NUMBER;
l_reservation     NUMBER;
l_total_allocation NUMBER;
l_chunksize        NUMBER;
 
BEGIN
  trace1 ('RESERVE_BLOCK_POOL_SPACE for '  ||
           ' db_key '  || p_db_key ||
          ', chunks ' || p_chunks);
 
--
  l_chunksize := f_chunksize(p_db_key);
 
--
--
--
  IF p_chunks IS NULL THEN
    sys.kbrsi_icd.rsTrace('RESERVE_BLOCK_POOL_SPACE illegal null input');
    sys.dbms_sys_error.raise_system_error(
                                DBMS_RA_SCHEDULER.E_BAD_CHUNK_NUMBER_NUM,
                                'value','NULL');
  END IF;
 
--
--
--
--
  IF NOT DBMS_RA_SCHEDULER.S_PURGING_ACTIVE THEN
    trace1 ('RESERVE_BLOCK_POOL_SPACE: Not purging!');
    RAISE  DBMS_RA_SCHEDULER.E_NOT_IN_PURGE;
  END IF;
 
  p_maxchunks := DBMS_RA_SCHEDULER.S_PURGING_RESERVE / l_chunksize;
  lock_db(p_db_key);
 
  <<do_reserve>>
  NULL;
 
--
--
--
  BEGIN
    SELECT odb.sl_key, NVL(odb.move_phase,0), odb.allocated_space,
           odb.used_space
      INTO       l_sl_key, l_move_phase, l_allocated, l_used
      FROM odb
      WHERE odb.db_key = p_db_key;
    trace1('RESERVE_BLOCK_POOL_SPACE: Storage location key is: ' || l_sl_key);
 
  EXCEPTION
      WHEN NO_DATA_FOUND THEN
        save_error;
        trace1 ('RESERVE_BLOCK_POOL_SPACE: Bad storage location');
        unlock_db(p_db_key);
        RAISE DBMS_RA_SCHEDULER.E_BAD_STORAGE_LOCATION;
  END;
 
--
--
--
  IF l_move_phase != DBMS_RA_SCHEDULER.MOVE_PHASE_POOL THEN
    BEGIN
      DBMS_RA_SCHEDULER.S_SYSRESERVE_OK := TRUE;
      lock_sl(l_sl_key);
--
--
--
--
      l_freechunks := freespace(l_sl_key) / l_chunksize;
      trace1('RESERVE_BLOCK_POOL_SPACE freechunks=' || l_freechunks ||
                             ' ; allocated=' || l_allocated ||
                             ' ; used=' || l_used ||
                             ' ; chunksize=' || l_chunksize);
      l_availablechunks := l_freechunks + ((l_allocated-l_used) / l_chunksize);
      l_availablechunks := FLOOR(l_availablechunks);
      trace1 ('RESERVE_BLOCK_POOL_SPACE Chunks available = '
                                                        || l_availablechunks);
 
      IF l_availablechunks < p_chunks THEN
        l_purge_reserve := l_availablechunks;
      ELSE
        l_purge_reserve := p_chunks;
      END IF;
 
      trace1('RESERVE_BLOCK_POOL_SPACE: purge_reserve = ' || l_purge_reserve);
 
--
--
--
--
--
--
      UPDATE odb
        SET used_space      = l_used + (l_purge_reserve * l_chunksize),
            not_taped = not_taped + (l_purge_reserve * l_chunksize),
            allocated_space = l_used + (l_purge_reserve * l_chunksize),
            total_allocation = total_allocation - l_allocated +
                                   l_used + (l_purge_reserve * l_chunksize)
        WHERE  db_key = p_db_key;
 
      UPDATE task
        SET purge_reserve = l_purge_reserve
        WHERE  task_id = DBMS_RA_SCHEDULER.S_CURRENT_TASK;
 
      COMMIT;
      unlock_sl(l_sl_key);
    EXCEPTION
      WHEN OTHERS THEN
        save_error;
        unlock_sl(l_sl_key);
        DBMS_RA_SCHEDULER.S_SYSRESERVE_OK := FALSE;
        RAISE;
    END;
  ELSE
--
--
--
--
--
--
--
--
--
    SELECT reserved_space, odb.total_allocation
      INTO l_reservation, l_total_allocation
      FROM odb
      WHERE db_key = p_db_key;
 
    l_freechunks := (l_reservation - l_total_allocation) / l_chunksize;
    l_availablechunks  := l_freechunks + ((l_allocated - l_used) /l_chunksize);
    trace1 ('RESERVE_BLOCK_POOL_SPACE (move) Chunks available =
                                                       ' || l_availablechunks);
 
--
--
--
--
--
--
--
--
    IF l_availablechunks < 2 THEN
      l_availablechunks := 2;
    END IF;
 
--
--
--
    IF l_availablechunks < p_chunks THEN
      l_purge_reserve := l_availablechunks;
    ELSE
      l_purge_reserve := p_chunks;
    END IF;
 
--
--
--
    IF ((l_allocated - l_used) >=  (l_purge_reserve * l_chunksize)) THEN
      UPDATE odb
        SET used_space      = l_used + (l_purge_reserve * l_chunksize),
            not_taped = not_taped + (l_purge_reserve * l_chunksize)
      WHERE  db_key = p_db_key;
 
      UPDATE task
        SET purge_reserve = l_purge_reserve
        WHERE  task_id = DBMS_RA_SCHEDULER.S_CURRENT_TASK;
 
      COMMIT;
    ELSE
--
--
--
      IF NOT allocate_db_space (l_sl_key,
                                p_db_key,
                                (l_purge_reserve * l_chunksize),
                                TRUE) THEN
--
        trace1 ('RESERVE_SPACE: No storage space found!');
        SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(
                                      DBMS_RA_SCHEDULER.E_NO_MORE_STORAGE_NUM,
                                      DBMS_RA_SCHEDULER.S_ALLOC_INCREMENT);
      END IF;
 
--
--
--
--
--
--
      trace1('RESERVE_BLOCK_POOL_SPACE: Looping after allocation');
      GOTO do_reserve;
    END IF;
  END IF;
  unlock_db(p_db_key);
 
  trace1 ('RESERVE_BLOCK_POOL_SPACE: Reserved chunks = ' || l_purge_reserve);
 
  RETURN l_purge_reserve;
 
EXCEPTION
  WHEN OTHERS THEN
    save_error;
    unlock_db(p_db_key);
    RAISE;
END reserve_block_pool_space;
 
 
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE finish_block_pool_chunk(p_db_key IN NUMBER) IS
 
 
  PRAGMA AUTONOMOUS_TRANSACTION;
  l_unused_chunks       NUMBER;
 
BEGIN
  trace1 ('FINISH_BLOCK_POOL_CHUNK for db_key = ' || p_db_key);
 
--
--
--
  lock_db(p_db_key);
 
  SELECT NVL(purge_reserve,0) INTO l_unused_chunks
    FROM task
    WHERE task_id = DBMS_RA_SCHEDULER.S_CURRENT_TASK;
 
  IF l_unused_chunks > 0 THEN
 
    UPDATE odb
      SET used_space = used_space - (l_unused_chunks * sl_min_alloc)
      WHERE db_key = p_db_key;
 
--
--
--
--
--
--
    UPDATE task
      SET purge_reserve = NULL,
          task_type =
              DECODE (task_type, 
                      DBMS_RA_SCHEDULER.TASK_PURGE_DF_NOW, 
                      DBMS_RA_SCHEDULER.TASK_PURGE_DF, 
                      task_type)
      WHERE task_id = DBMS_RA_SCHEDULER.S_CURRENT_TASK;
 
    COMMIT;
    trace1 ('FINISH_BLOCK_POOL_CHUNK: Fin.');
  END IF;
 
  unlock_db (p_db_key);
  trace1 ('FINISH_BLOCK_POOL_CHUNK: Fin.');
 
EXCEPTION
    WHEN OTHERS THEN
      save_error;
      unlock_db (p_db_key);
      RAISE;
END finish_block_pool_chunk;
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
FUNCTION allocate_db_space (
                       p_sl_key     IN OUT NUMBER,
                       p_db_key     IN NUMBER,
                       p_size       IN NUMBER DEFAULT NULL,
                       p_movepurge  IN BOOLEAN DEFAULT FALSE) RETURN BOOLEAN IS
 
l_alloc_size         NUMBER := 
                             NVL (p_size, DBMS_RA_SCHEDULER.S_ALLOC_INCREMENT);
l_allocated_space    NUMBER;
l_preallocated_space NUMBER;
l_move_phase         NUMBER;
l_needs_repair       NUMBER;
l_reserved_space     NUMBER;
  new_task_rec       task%ROWTYPE;
l_freespace          NUMBER;
l_program            VARCHAR2(300);
l_count              NUMBER;
l_job_name           user_scheduler_jobs.job_name%TYPE;
 
BEGIN
--
--
--
  IF (l_alloc_size < DBMS_RA_SCHEDULER.S_ALLOC_INCREMENT) AND 
     NOT p_movepurge THEN
    l_alloc_size := DBMS_RA_SCHEDULER.S_ALLOC_INCREMENT;
  END IF;
 
  trace1 ('ALLOCATE_DB_SPACE for ' ||
          ' sl_key=' || p_sl_key ||
          ', db_key='  || p_db_key ||
          ', size=' || print(p_size) ||
          ', allocsize=' || l_alloc_size ||
          ', movepurge=' || print(p_movepurge));
 
--
--
--
--
  LOOP
--
--
--
    BEGIN
      SELECT allocated_space, allocated_space-used_space, move_phase, sl_key
        INTO l_allocated_space, l_preallocated_space, l_move_phase, p_sl_key
        FROM odb
        WHERE db_key = p_db_key;
 
    EXCEPTION
      WHEN NO_DATA_FOUND THEN
        save_error;
        trace1 ('ALLOCATE_DB_SPACE: No space for DB');
        clear_error;
        RETURN FALSE;
    END;
    trace1 ('ALLOCATE_DB_SPACE: DB allocation is ' || l_allocated_space ||
                             '; preallocation is ' || l_preallocated_space ||
                             '; used_space is ' || 
                         TO_NUMBER(l_allocated_space - l_preallocated_space) ||
                             '; move_phase is ' || l_move_phase);
 
--
--
--
    SELECT sl_needs_repair INTO l_needs_repair
      FROM sl
      WHERE sl_key = p_sl_key;
 
    IF l_needs_repair IS NOT NULL THEN
      trace1 ('ALLOCATE_DB_SPACE: SL under repair');
      RETURN FALSE;
    END IF;
 
--
--
--
--
--
--
    IF (l_move_phase = DBMS_RA_SCHEDULER.MOVE_PHASE_POOL) AND 
       NOT p_movepurge THEN
--
--
--
--
--
--
--
--
      SELECT reserved_space INTO l_reserved_space
        FROM odb
        WHERE odb.db_key = p_db_key;
 
--
--
--
--
      IF l_reserved_space - (l_allocated_space - l_preallocated_space)
                                                        < l_alloc_size THEN
--
--
--
        l_job_name := 'RA$_PURDB_' || TO_CHAR(p_db_key);
        l_program := 'dbms_ra_storage.trim_database_as_job(' ||
                          '  p_db_key=>' || TO_CHAR(p_db_key) ||
                          ', p_sl_key=>' || TO_CHAR(p_sl_key) ||
                          ', p_allocation=>' || TO_CHAR(l_alloc_size) ||
                          ');';
 
        trace1('ALLOCATE_DB_SPACE: Spawning: ' || l_program);
 
        BEGIN
          DBMS_RA_SCHEDULER.SPAWN_JOB (l_job_name, l_program, NULL, NULL);
        EXCEPTION
          WHEN DBMS_RA_SCHEDULER.E_JOB_ALREADY_EXISTS THEN
            save_error;
            trace1 ('ALLOCATE_DB_SPACE: Purging job already exists');
            clear_error;
 
        WHEN OTHERS THEN
          save_error;
          trace1 ('ALLOCATE_DB_SPACE: Spawning exited with: ' || SQLERRM);
          RAISE;
        END;
 
--
--
--
--
        IF DBMS_RA_SCHEDULER.S_NO_WAIT_ON_ALLOCATE THEN
          DBMS_RA_SCHEDULER.S_PENDING_INTERRUPT :=
                       DBMS_RA_SCHEDULER.SET_BLOCKING_PURGE (p_db_key, p_size);
          RAISE DBMS_RA_SCHEDULER.E_RETRY_RESERVE;
        END IF;
 
--
--
--
--
        unlock_db(p_db_key);
 
--
--
--
--
        SYS.KBRSI_ICD.RSSCHEDLOCK (waitforwork => 0);
        UPDATE task
          SET pending_interrupt = NULL,
              state = (CASE WHEN state = DBMS_RA_SCHEDULER.STATE_RUNNING 
                            THEN DBMS_RA_SCHEDULER.STATE_RUNNING 
                            WHEN state = DBMS_RA_SCHEDULER.STATE_CANCEL 
                            THEN DBMS_RA_SCHEDULER.STATE_CANCEL
                            WHEN state = DBMS_RA_SCHEDULER.STATE_CANCELING 
                            THEN DBMS_RA_SCHEDULER.STATE_CANCELING
                            ELSE DBMS_RA_SCHEDULER.STATE_EXECUTABLE END)
          WHERE pending_interrupt = DBMS_RA_SCHEDULER.S_CURRENT_TASK;
        trace1 ('ALLOCATE_DB_SPACE: releasing ' || SQL%ROWCOUNT || ' tasks');
        COMMIT;
        SYS.KBRSI_ICD.RSSCHEDUNLOCK(nomorejobs => 0);
 
--
--
--
--
--
        IF s_safe_mode THEN
          SELECT min(key) INTO l_count
            FROM sys.rai_js_locks
            WHERE sid = SYS_CONTEXT('USERENV', 'SID')
              AND ba_type = DBMS_RA_SCHEDULER.LOCK_KEY
              AND key NOT IN
                  (SELECT MOD(param_num1, POWER(2,32))
                     FROM task
                     WHERE task_id = DBMS_RA_SCHEDULER.S_CURRENT_TASK
                       AND task_type = DBMS_RA_SCHEDULER.TASK_INDEX_BACKUP);
 
          IF l_count IS NOT NULL THEN
            trace1('ALLOCATE_DB_SPACE: (DB) Key lock ' || l_count || 
                                                        ' held illegally');
            sys.dbms_sys_error.raise_system_error(
                                        DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM,
                                        'bad key lock');
          END IF;
        END IF;
 
--
--
--
--
        IF DBMS_RA_SCHEDULER.S_CURRENT_TASK IS NULL THEN
          trace1 ('ALLOCATE_DB_SPACE: Retry exception for servlet wait');
          RAISE DBMS_RA_SCHEDULER.E_RETRY_ERROR;
        END IF;
 
        trace1 ('ALLOCATE_DB_SPACE: ...waiting for db purge...');
        DBMS_LOCK.SLEEP(DBMS_RA_SCHEDULER.S_PURGE_WAIT);
        lock_db(p_db_key);
 
--
--
--
--
--
        CONTINUE;
      END IF;
    END IF;
 
--
--
--
--
--
    lock_sl (p_sl_key);
 
    l_freespace := freespace(p_sl_key);
    trace1 ('ALLOCATE_DB_SPACE (COMMON CODEPATH): freespace ' || l_freespace);
 
    IF l_freespace >= (l_alloc_size - l_preallocated_space)  THEN
--
--
--
      UPDATE odb
        SET allocated_space = 
                allocated_space + (l_alloc_size - l_preallocated_space),
            total_allocation = 
                total_allocation + (l_alloc_size - l_preallocated_space)
        WHERE db_key = p_db_key;
 
--
--
--
--
--
--
--
      IF NVL(DBMS_RA_SCHEDULER.S_CURRENT_TASK_type,-1) NOT IN 
                                    (DBMS_RA_SCHEDULER.TASK_MOVE_DF, 
                                     DBMS_RA_SCHEDULER.TASK_MOVE_ALL_DB,
                                     DBMS_RA_SCHEDULER.TASK_PURGE_IMMEDIATE,
                                     DBMS_RA_SCHEDULER.TASK_PURGE_DF_NOW,
                                     DBMS_RA_SCHEDULER.TASK_OPTIMIZE_CHUNKS_DF,
                                     DBMS_RA_SCHEDULER.TASK_REPAIR_DB) 
      THEN 
        UPDATE sl
          SET sl_hist_usage = 
                NVL(sl_hist_usage,0) + (l_alloc_size - l_preallocated_space)
          WHERE sl_key = p_sl_key;
      END IF;
 
      COMMIT;
      unlock_sl(p_sl_key);
      trace1 ('ALLOCATE_DB_SPACE: Allocation is granted');
 
      RETURN TRUE;
    END IF;
 
--
--
--
    IF NOT available_bs(p_sl_key, 
                        p_db_key, 
                        l_alloc_size - l_preallocated_space) 
    THEN
      trace1 ('ALLOCATE_DB_SPACE: No available space');
      unlock_sl(p_sl_key);
      EXIT;
    END IF;
 
--
--
--
--
--
    unlock_sl(p_sl_key);
    unlock_db(p_db_key);
 
--
--
--
--
--
--
--
--
--
    IF (DBMS_RA_SCHEDULER.S_CURRENT_TASK IS NULL) OR 
       (DBMS_RA_SCHEDULER.TYPE2PRIORITY(DBMS_RA_SCHEDULER.S_CURRENT_TASK_TYPE)
                                < DBMS_RA_SCHEDULER.PRIO_MIN_BUSYWORK) THEN
--
--
--
      l_job_name := 'RA$_PURGE_' || TO_CHAR(p_sl_key);
      l_program := 'dbms_ra_scheduler.purge_immediate(' ||
                        '  p_sl_key=>' || TO_CHAR(p_sl_key) ||
                        ', p_db_key=>' || TO_CHAR(p_db_key) ||
                        ', p_allocation=>' || TO_CHAR(l_alloc_size) || ');';
 
      trace1('ALLOCATE_DB_SPACE: Spawning: ' || l_program);
 
      BEGIN
        DBMS_RA_SCHEDULER.SPAWN_JOB (L_JOB_NAME, L_PROGRAM, NULL, NULL);
      EXCEPTION
        WHEN DBMS_RA_SCHEDULER.E_JOB_ALREADY_EXISTS THEN
          save_error;
          trace1 ('ALLOCATE_DB_SPACE: Purging job already exists');
          clear_error;
 
        WHEN OTHERS THEN
          save_error;
          trace1 ('ALLOCATE_DB_SPACE: Spawning exited with: ' || SQLERRM);
          lock_db(p_db_key);
          RAISE;
      END;
    ELSE
--
--
--
--
      SELECT COUNT(*) INTO l_count
        FROM task
        WHERE task_type IN 
         (DBMS_RA_SCHEDULER.TASK_PURGE, DBMS_RA_SCHEDULER.TASK_PURGE_IMMEDIATE)
          AND sl_key = p_sl_key;
 
      IF l_count = 0 THEN
        new_task_rec.task_type  := DBMS_RA_SCHEDULER.TASK_PURGE;
        new_task_rec.sl_key     := p_sl_key;
        new_task_rec.db_key     := p_db_key;
        new_task_rec.flags      := 0;
        new_task_rec.param_num1 := l_alloc_size;
        DBMS_RA_SCHEDULER.NEW_TASK (new_task_rec);
      END IF;
    END IF;
 
--
--
--
    SYS.KBRSI_ICD.RSSCHEDLOCK (waitforwork => 0);
    UPDATE task
      SET pending_interrupt = NULL,
          state = (CASE WHEN state = DBMS_RA_SCHEDULER.STATE_RUNNING 
                        THEN DBMS_RA_SCHEDULER.STATE_RUNNING 
                            WHEN state = DBMS_RA_SCHEDULER.STATE_CANCEL 
                            THEN DBMS_RA_SCHEDULER.STATE_CANCEL
                            WHEN state = DBMS_RA_SCHEDULER.STATE_CANCELING 
                            THEN DBMS_RA_SCHEDULER.STATE_CANCELING
                        ELSE DBMS_RA_SCHEDULER.STATE_EXECUTABLE END)
      WHERE pending_interrupt = DBMS_RA_SCHEDULER.S_CURRENT_TASK;
    trace1 ('ALLOCATE_DB_SPACE: releasing ' || SQL%ROWCOUNT || ' tasks');
    COMMIT;
    SYS.KBRSI_ICD.RSSCHEDUNLOCK;
 
--
--
--
--
    IF DBMS_RA_SCHEDULER.S_NO_WAIT_ON_ALLOCATE THEN
      DBMS_RA_SCHEDULER.S_PENDING_INTERRUPT := 
        CASE DBMS_RA_SCHEDULER.S_CURRENT_TASK_TYPE
          WHEN DBMS_RA_SCHEDULER.TASK_OPTIMIZE_CHUNKS_DF 
            THEN DBMS_RA_SCHEDULER.OPT_DF_PSEUDO_TASK
          ELSE DBMS_RA_SCHEDULER.SET_BLOCKING_PURGE (p_db_key, p_size)
        END;
      lock_db(p_db_key);
      RAISE DBMS_RA_SCHEDULER.E_RETRY_RESERVE;
    END IF;
 
--
--
--
--
--
    IF s_safe_mode THEN
      SELECT min(key) INTO l_count
        FROM sys.rai_js_locks
        WHERE sid = SYS_CONTEXT('USERENV', 'SID')
          AND ba_type = DBMS_RA_SCHEDULER.LOCK_KEY
          AND key NOT IN
              (SELECT MOD(param_num1, POWER(2,32))
                 FROM task
                   WHERE task_id = DBMS_RA_SCHEDULER.S_CURRENT_TASK
                     AND task_type = DBMS_RA_SCHEDULER.TASK_INDEX_BACKUP);
 
      IF l_count IS NOT NULL THEN
        tracex('ALLOCATE_DB_SPACE: Key lock ' || l_count || ' held illegally');
        sys.dbms_sys_error.raise_system_error(
                                        DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM,
                                        'bad key lock');
      END IF;
    END IF;
 
--
--
--
--
    LOOP
--
--
--
--
       IF DBMS_RA_SCHEDULER.S_CURRENT_TASK IS NULL THEN
         trace1 ('ALLOCATE_DB_SPACE: Retry exception for servlet wait');
         RAISE DBMS_RA_SCHEDULER.E_RETRY_ERROR;
       END IF;
 
      trace1 ('ALLOCATE_DB_SPACE: ...waiting for purge...');
 
--
--
      DBMS_RA_SCHEDULER.CHECK_FOR_INTERRUPT;
 
      DBMS_LOCK.SLEEP(DBMS_RA_SCHEDULER.S_PURGE_WAIT);
 
--
--
--
--
      SELECT sl_key INTO p_sl_key
        FROM odb
        WHERE db_key = p_db_key;
 
      l_freespace := freespace(p_sl_key);
      EXIT WHEN l_freespace > (l_alloc_size - l_preallocated_space);
 
      dbms_ra_scheduler.make_amjobs(name => l_job_name);
      SELECT COUNT(*) INTO l_count
        FROM  TABLE(CAST(DBMS_RA_SCHEDULER.S_AMJOBS AS rai_jobs_table_type));
      EXIT WHEN l_count = 0;
    END LOOP;
    trace1 ('ALLOCATE_DB_SPACE: ... Done waiting');
 
--
--
--
--
    lock_db(p_db_key);
  END LOOP;
 
--
--
--
  trace1 ('ALLOCATE_DB_SPACE: Allocation is refused');
  RETURN FALSE;
END allocate_db_space;
 
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE check_tape_limit(p_db_key           IN NUMBER,
                           p_reserved         IN NUMBER,
                           p_used_space       IN NUMBER,
                           p_not_taped        IN NUMBER,
                           p_not_taped_state  IN VARCHAR2,
                           p_move_phase       IN NUMBER,
                           p_allocation       IN NUMBER) IS
  l_not_taped   NUMBER;
  l_count       NUMBER;
  l_task_rec    task%ROWTYPE;
BEGIN
  trace1 ('CHECK_TAPE_LIMIT: dbkey ' || p_db_key);
 
--
  IF p_not_taped_state IS NULL THEN
    RETURN;
  END IF;
 
--
  IF p_not_taped < p_reserved THEN
    RETURN;
  END IF;
 
--
  IF p_not_taped_state IN ('N', 'B') AND p_used_space < p_reserved THEN
    RETURN;
  END IF;
 
--
  ROLLBACK;
 
--
  IF p_not_taped_state IN ('I', 'C') THEN
    SELECT COUNT(*) INTO l_count
      FROM task
      WHERE task_type = DBMS_RA_SCHEDULER.TASK_GCOPY_COMPUTE
        AND db_key = p_db_key
        AND ROWNUM = 1;
 
--
    IF l_count = 0 THEN
      l_task_rec.task_type     := DBMS_RA_SCHEDULER.TASK_GCOPY_COMPUTE;
      l_task_rec.db_key        := p_db_key;
      l_task_rec.flags         := 0;
      DBMS_RA_SCHEDULER.NEW_TASK(l_task_rec);
    END IF;
 
    RAISE DBMS_RA_SCHEDULER.E_RETRY_RESERVE;
  END IF;
 
--
  trace1 ('CHECK_TAPE_LIMIT: space denied for dbkey ' || p_db_key);
  IF DBMS_RA_SCHEDULER.S_CURRENT_TASK IS NULL THEN
--
    SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(
                                      DBMS_RA_SCHEDULER.E_NO_MORE_STORAGE_NUM,
                                      p_allocation);
  ELSE
--
    DBMS_RA_SCHEDULER.S_PENDING_INTERRUPT := 
                 DBMS_RA_SCHEDULER.SET_BLOCKING_PURGE (p_db_key, p_allocation);
    RAISE DBMS_RA_SCHEDULER.E_RETRY_RESERVE;
  END IF;
END check_tape_limit;  
 
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE purge_storage_location (
                        p_sl_key      IN NUMBER,
                        p_db_key      IN NUMBER,
                        p_spaceneed   IN NUMBER,
                        p_immediate   IN BOOLEAN) IS
 
CURSOR purgedb_cursor IS
    SELECT db_key, overretentionsecs, overspace, newsecs, goalsecs
    FROM rai_purge_queue
    WHERE sl_key = p_sl_key
    ORDER BY overretentionsecs DESC, overspace DESC;
 
--
--
--
--
--
--
CURSOR copies_of_vb IS
  SELECT DISTINCT p.db_key, p.bp_key, p.handle, t.piece# sbt
    FROM odb o JOIN bp p   ON o.db_key = p.db_key
               JOIN vbdf v ON p.db_key = v.db_key AND p.bp_key = v.srcbp_key
         LEFT OUTER JOIN sbt_task t USING (bs_key)
    WHERE p.vb_key IS NULL
      AND p.status != 'D'
      AND p.ba_access = 'L'
      AND o.sl_key = p_sl_key
      AND nvl(t.failure_cnt,0) = 0
      AND v.df_key = v.krbph_dfkey
      AND v.state = DBMS_RA_POOL.VBDF_COMPLETE;
 
l_bs2_timestamp  TIMESTAMP WITH TIME ZONE;
l_purge_scn      NUMBER;
l_oldest_backup  TIMESTAMP WITH TIME ZONE;
i                BINARY_INTEGER;
l_freespace      NUMBER;
l_original_freespace NUMBER;
l_shrinkage      NUMBER;
l_planned_space  NUMBER := 0;
l_preallocated   NUMBER;
l_db_key         NUMBER;
l_overretention  NUMBER;
l_overspace      NUMBER;
l_newsecs        NUMBER;
l_goalsecs       NUMBER;
l_purgedb        NUMBER := NULL;
l_count          NUMBER;
l_1              NUMBER;
l_2              NUMBER;
l_chunksize      NUMBER;
l_resume         NUMBER;
TYPE t_dbkey_list  IS TABLE OF NUMBER;
l_skipped_dbkeys t_dbkey_list := t_dbkey_list();
l_list_ptr       NUMBER;
l_warned_dbkeys  t_dbkey_list := t_dbkey_list();
l_last_free      NUMBER := 0;
l_slname         sl.sl_name%TYPE;
l_excess         NUMBER;
l_extra          NUMBER;
l_bskey          NUMBER;
 
c_autoshrink     CONSTANT NUMBER := DBMS_RA_SCHEDULER.S_PURGE_AUTOSHRINK;
c_alloc_incr     CONSTANT NUMBER := DBMS_RA_SCHEDULER.S_ALLOC_INCREMENT;
ONE_MEG          CONSTANT NUMBER := 1024*1024;
 
BEGIN
 
  trace1 ('PURGE_STORAGE_LOCATION for '  ||
          '  p_sl_key='  || p_sl_key ||
          ', p_db_key='  || print(p_db_key) ||
          ', p_immediate=' || print(p_immediate));
 
--
--
--
--
  FOR srcb IN copies_of_vb LOOP
--
    IF srcb.sbt IS NOT NULL THEN
      BEGIN
        swap_backup_piece(srcb.bp_key);
        free_backup_piece(srcb.db_key, srcb.handle,
                          DBMS_RA_INT.KBRSCHKTYPE_FILE);
      EXCEPTION
        WHEN DBMS_RA_SCHEDULER.E_RETRY_ERROR THEN
          save_error;
          DBMS_RA_SCHEDULER.S_PENDING_INTERRUPT := NULL;
          trace1 ('PURGE_STORAGE_LOCATION: skip bpkey ' || srcb.bp_key);
          clear_error;
      END;
    END IF;
  END LOOP;
 
--
--
--
--
--
--
--
--
--
  FOR trim IN (SELECT db_key 
                FROM odb
                WHERE sl_key = p_sl_key
                  AND db_key <> NVL(p_db_key, 0)
                  AND (allocated_space - used_space) >
                      GREATEST(c_autoshrink * reserved_space, c_alloc_incr))
  LOOP
    lock_db(trim.db_key);
--
--
--
--
--
--
--
--
--
    SELECT LEAST ((allocated_space - used_space),
                  GREATEST(c_autoshrink * reserved_space, c_alloc_incr))
      INTO l_shrinkage
      FROM odb
      WHERE db_key=trim.db_key;
 
    UPDATE odb SET allocated_space = allocated_space - l_shrinkage,
                    total_allocation = total_allocation - l_shrinkage
    WHERE db_key=trim.db_key;
    COMMIT;
 
    trace1('PURGE_STORAGE_LOCATION: Shrunk db_key=' || trim.db_key ||
                                        ' by megs=' || l_shrinkage/ONE_MEG);
 
    unlock_db(trim.db_key);
  END LOOP;
 
 
--
  DBMS_RA_SCHEDULER.GET_LOCK (DBMS_RA_SCHEDULER.LOCK_PURGE, p_sl_key);
 
--
--
  FOR db IN (SELECT db_key, prot_max_retention_window,
                    odb.recovery_window_goal,
                    bs2_timestamp, purge_scn,
                    rob.oldest_backup
               FROM odb 
               JOIN prot USING(prot_key)
               JOIN rai_oldest_backup rob USING(db_key)
              WHERE odb.sl_key = p_sl_key
                AND odb.move_phase IS NULL
                AND odb.used_space > 0
                AND NVL(odb.purge_scn,0) <> DBMS_RA_POOL.BIGNUM
                AND prot.prot_max_retention_window IS NOT NULL
--
                AND (odb.bs2_timestamp IS NULL 
                     OR ((SYSTIMESTAMP - odb.bs2_timestamp) > 
                                                     odb.recovery_window_goal))
--
                AND (rob.oldest_backup <
                         (SYSTIMESTAMP - prot.prot_max_retention_window))) LOOP
 
    trace1('PURGE_STORAGE_LOCATION: for db_key ' || db.db_key ||
                '; max_retention_window is ' || db.prot_max_retention_window);
 
--
--
--
--
    l_bs2_timestamp := db.bs2_timestamp;
    l_purge_scn := db.purge_scn;
    l_oldest_backup := db.oldest_backup;
 
--
--
--
--
--
    WHILE ((l_oldest_backup <= (SYSTIMESTAMP - db.prot_max_retention_window)) 
           AND (NVL(l_purge_scn,0) <> DBMS_RA_POOL.BIGNUM)
--
           AND (l_bs2_timestamp IS NULL 
                OR ((SYSTIMESTAMP - l_bs2_timestamp) > 
                                               db.recovery_window_goal))) LOOP
--
--
--
--
--
--
--
--
--
      trace1 ('PURGE_STORAGE_LOCATION: bs2_timestamp=' || l_bs2_timestamp ||
                '; bs2_timestamp is ' || l_bs2_timestamp ||
                '; purge_scn is ' || l_purge_scn ||
                '; oldest_backup is ' || l_oldest_backup);
 
      purge_database (db.db_key, p_sl_key, FALSE);
 
--
--
--
      DBMS_RA_SCHEDULER.CHECK_FOR_INTERRUPT;
 
--
--
--
      SELECT bs2_timestamp, purge_scn, oldest_backup
        INTO l_bs2_timestamp, l_purge_scn, l_oldest_backup
        FROM odb 
        JOIN rai_oldest_backup rob USING(db_key)
       WHERE db_key = db.db_key;
 
    END LOOP;
  END LOOP;
 
--
  l_resume := NVL(dbms_ra_scheduler.get_savepoint, 0);
  IF l_resume > 0 AND l_db_key IS NOT NULL
  THEN
    SELECT db_key INTO l_db_key 
      FROM task 
      WHERE task_id = DBMS_RA_SCHEDULER.S_CURRENT_TASK;
    trace1 ('PURGE_STORAGE_LOCATION: Resume Purging on ' || l_db_key);
    purge_database (l_db_key, p_sl_key, FALSE);
  END IF;
 
--
  l_original_freespace := freespace(p_sl_key);
  l_freespace := l_original_freespace;
 
--
--
--
  LOOP
--
--
--
    IF p_immediate THEN
--
--
--
--
      SELECT allocated_space - used_space INTO l_preallocated
        FROM odb
        WHERE db_key = p_db_key;
    ELSE 
      l_preallocated := 0;
    END IF;
    tracex ('PURGE_STORAGE_LOCATION:   freespace=' || l_freespace/ONE_MEG ||
                                 '+ planned=' || l_planned_space/ONE_MEG || 
                                 '+ preallocated=' || l_preallocated/ONE_MEG ||
                                 '> spaceneed' || p_spaceneed/ONE_MEG);
 
--
--
--
    EXIT WHEN (l_freespace + l_planned_space + l_preallocated) > p_spaceneed;
 
--
--
--
    IF s_stall_on THEN
      SELECT COUNT(*) INTO l_count FROM error_log
        WHERE severity >= DBMS_RA_SCHEDULER.SEVERITY_ERROR
          AND status = 'ACTIVE';
      IF l_count > 0
      THEN
--
        SYS.KBRSI_ICD.RSRUNSCHED;
      END IF;
    END IF;
 
--
--
--
    IF s_safe_mode THEN
      l_db_key := NULL;
      OPEN purgedb_cursor;
      LOOP
        FETCH purgedb_cursor
          INTO l_db_key, l_overretention, l_overspace, l_newsecs,
               l_goalsecs;
 
        EXIT WHEN purgedb_cursor%NOTFOUND;
 
        SELECT used_space, allocated_space, sl_min_alloc
          INTO l_1, l_2, l_chunksize
          FROM odb
          WHERE db_key = l_db_key;
 
--
--
--
--
--
--
--
        trace1('PURGE_STORAGE_LOCATION stats' ||
               ' db_key=' || lpad(l_db_key,4) ||
               ', %% of time=' || round(l_overretention*100,2) ||
               ', %% over allocated space= ' || round(l_overspace*100,2) ||
               '; used chunks ' || l_1/l_chunksize ||
               '; allocated chunks ' || round(l_2/l_chunksize) ||
               '; (newsecs ' || round(l_newsecs) ||
               ', goalsecs ' || l_goalsecs || ')');
      END LOOP;
      CLOSE purgedb_cursor;
 
--
--
--
--
--
      IF l_db_key IS NULL THEN
        trace1('PURGE_STORAGE_LOCATION: No databases in purge queue!');
        DBMS_RA_SCHEDULER.UNLOCK (DBMS_RA_SCHEDULER.LOCK_PURGE, p_sl_key);
        RETURN;
      END IF;
    END IF;
 
    OPEN purgedb_cursor;
    l_purgedb := NULL;
    LOOP
      BEGIN
        FETCH purgedb_cursor
          INTO l_db_key, l_overretention, l_overspace, l_newsecs,
               l_goalsecs;
 
        IF purgedb_cursor%NOTFOUND THEN  -- bail
          EXIT;
        END IF;
 
--
--
--
--
        IF l_db_key MEMBER OF l_skipped_dbkeys THEN
          trace1('PURGE_STORAGE_LOCATION: skipping db_key=' || l_db_key);
          CONTINUE;
        END IF;
 
--
--
--
         IF l_overretention = 0 AND NOT l_db_key MEMBER OF l_warned_dbkeys
        THEN
          DBMS_RA_SCHEDULER.LOG_ERROR (
                 p_errno     => DBMS_RA_SCHEDULER.E_REC_WINDOW_LOST_NUM,
                 p_param1    => DBMS_RA_INT.DBKEY2NAME(l_db_key),
                 p_component => 'PURGE',
                 p_severity  => DBMS_RA_SCHEDULER.SEVERITY_WARNING,
                 p_db_key    => l_db_key);
 
          l_warned_dbkeys.EXTEND;
          l_list_ptr := l_warned_dbkeys.LAST;
          l_warned_dbkeys(l_list_ptr) := l_db_key;
        END IF;
 
--
--
--
--
        IF (l_overretention <= 0) AND (l_skipped_dbkeys.FIRST IS NOT NULL) THEN
          EXIT;
        END IF;
 
--
--
--
--
--
--
--
--
--
--
        IF (l_overretention > 0) OR (l_overspace > 0) THEN
--
--
--
          l_purgedb := l_db_key;
          EXIT;
        END IF;
 
      EXCEPTION
        WHEN OTHERS THEN
          save_error;
          CLOSE purgedb_cursor;
          RAISE;
      END;
 
    END LOOP;
    CLOSE purgedb_cursor;
 
--
--
--
    IF l_purgedb IS NULL THEN
      trace1 ('PURGE_STORAGE_LOCATION: No database found to purge (yet)!');
--
--
--
--
      IF (l_skipped_dbkeys.FIRST IS NOT NULL) AND p_immediate THEN
--
--
--
--
        FOR i IN l_skipped_dbkeys.FIRST..l_skipped_dbkeys.LAST LOOP
          l_purgedb := l_skipped_dbkeys(i);
          SELECT overretentionsecs, overspace,   newsecs,   goalsecs
            INTO l_overretention, l_overspace, l_newsecs, l_goalsecs
            FROM rai_purge_queue
            WHERE db_key = l_purgedb;
 
          IF l_overretention > 0 THEN
--
--
--
            l_skipped_dbkeys.DELETE(i);
 
--
--
--
            EXIT;
          END IF;
 
--
--
--
          l_purgedb := NULL;
        END LOOP;
 
--
--
--
--
--
        IF l_purgedb IS NULL THEN
          l_list_ptr := l_skipped_dbkeys.FIRST;
          l_purgedb := l_skipped_dbkeys(l_list_ptr);
          l_skipped_dbkeys.DELETE(l_list_ptr);
 
          trace1 ('PURGE_STORAGE_LOCATION: Plan C has chosen dbkey=' ||
                  l_purgedb);                     
          
          SELECT overretentionsecs, overspace,   newsecs,   goalsecs
            INTO l_overretention, l_overspace, l_newsecs, l_goalsecs
            FROM rai_purge_queue
            WHERE db_key = l_purgedb;
 
        END IF;
 
        IF l_purgedb IS NOT NULL THEN
--
--
--
--
          trace1 ('PURGE_STORAGE_LOCATION: Killing tasks for dbkey=' ||
                  l_purgedb);                     
 
          dbms_ra_scheduler.interrupt_tasks(
            p_interrupt => dbms_ra_scheduler.INTERRUPT_FOR_PURGE
          , p_db_key    => l_purgedb
          );
        END IF;
 
      END IF;  -- IF (l_skipped_dbkeys.FIRST IS NOT NULL) ...
    END IF;    -- IF l_purgedb IS NULL ...
 
--
--
--
--
--
--
--
    IF (l_purgedb IS NULL) AND p_immediate AND (p_db_key IS NOT NULL) THEN
      SELECT (allocated_space + NVL(p_spaceneed,0)) - reserved_space 
        INTO l_excess
        FROM odb
        WHERE db_key = p_db_key;
 
      trace1('PURGE_STORAGE_LOCATION: Purge the greedy db');
      IF l_excess > 0 THEN
        SELECT overretentionsecs, overspace, newsecs, goalsecs
          INTO l_overretention, l_overspace, l_newsecs, l_goalsecs
          FROM rai_purge_queue
         WHERE sl_key = p_sl_key
           AND db_key = p_db_key;
 
        l_purgedb := p_db_key;
      END IF;
    END IF;
 
--
--
--
--
    IF l_purgedb IS NULL THEN
      trace1 ('PURGE_STORAGE_LOCATION: No database found to purge!');
      EXIT;
    END IF;
 
--
--
--
--
    IF (l_newsecs < l_goalsecs) THEN
      SELECT sl_name INTO l_slname
        FROM sl
        WHERE sl_key = p_sl_key;
 
      DBMS_RA_SCHEDULER.LOG_ERROR (
                 p_errno     => DBMS_RA_SCHEDULER.E_SL_FULL_NUM,
                 p_param1    => l_slname,
                 p_component => 'PURGE',
                 p_severity  => DBMS_RA_SCHEDULER.SEVERITY_WARNING,
                 p_sl_key    => p_sl_key);
 
--
--
--
--
--
--
      IF ((NOT p_immediate) OR
          ((l_original_freespace + DBMS_RA_SCHEDULER.S_ALLOC_INCREMENT) <
                                         (l_freespace + l_planned_space))) THEN
        trace1 ('PURGE_STORAGE_LOCATION: purgedb is below retention goal: ' ||
                                                                   l_purgedb);
        EXIT;
      END IF;
    ELSE
--
--
--
--
      DBMS_RA_SCHEDULER.FIX_ERROR(
                        p_error_num => DBMS_RA_SCHEDULER.E_SL_FULL_NUM,
                        p_sl_key => p_sl_key);
      COMMIT;
    END IF;
 
    BEGIN
--
--
--
      DBMS_RA_SCHEDULER.CHECK_FOR_INTERRUPT;
 
--
      l_last_free := l_freespace + l_planned_space;
 
      trace1('PURGE_STORAGE_LOCATION: purging' ||
                                              ' db_key=' || lpad(l_db_key,4));
 
--
--
--
--
      UPDATE task
         SET pending_interrupt = NULL,
             db_key = l_purgedb
       WHERE task_id = DBMS_RA_SCHEDULER.S_CURRENT_TASK;
      COMMIT;
 
--
--
--
      purge_database (l_purgedb, p_sl_key, FALSE);
      l_planned_space := f_chunksize(l_purgedb) *
                         dbms_ra_pool.plannedSpace(p_sl_key, s_enable_dup);
 
--
--
--
--
--
      l_skipped_dbkeys := t_dbkey_list();
 
    EXCEPTION
      WHEN DBMS_RA_SCHEDULER.E_RETRY_ERROR THEN
        save_error;
--
--
--
--
--
        l_skipped_dbkeys.EXTEND;
        l_list_ptr := l_skipped_dbkeys.LAST;
        l_skipped_dbkeys(l_list_ptr) := l_purgedb;
        trace1 ('PURGE_STORAGE_LOCATION: Added dbkey=' || l_purgedb || 
                ' to skipped db list');
        clear_error;
 
      WHEN OTHERS THEN
        save_error;
        ROLLBACK;
--
        lock_db (l_purgedb);
        UPDATE odb
          SET total_allocation = total_allocation -
                                     (allocated_space - used_space),
              allocated_space = used_space
          WHERE  db_key = l_purgedb
          RETURNING used_space INTO l_count;
        COMMIT;
        unlock_db (l_purgedb);
        trace1 ('PURGE_STORAGE_LOCATION: ODB allocation (mbs) trimmed to: ' ||
                                                              l_count/ONE_MEG);
        RAISE;
    END;
 
--
--
--
--
--
    lock_db (l_purgedb);
    IF p_immediate AND (l_purgedb = NVL(p_db_key,-1)) THEN
      SELECT LEAST(allocated_space - used_space, NVL(p_spaceneed,0)) 
        INTO l_extra
        FROM odb
        WHERE db_key = l_purgedb;
    ELSE
      l_extra := 0;
    END IF;
 
    UPDATE odb
      SET total_allocation = total_allocation -
                                 (allocated_space - (used_space + l_extra)),
          allocated_space = used_space + l_extra
      WHERE  db_key = l_purgedb
      RETURNING used_space INTO l_count;
    COMMIT;
 
    unlock_db (l_purgedb);
 
--
--
--
    UPDATE task
      SET pending_interrupt = NULL,
          db_key = NULL
      WHERE task_id = DBMS_RA_SCHEDULER.S_CURRENT_TASK;
    COMMIT;
    l_purgedb := NULL;
 
    l_freespace := freespace(p_sl_key);
    trace1 ('PURGE_STORAGE_LOCATION: ODB allocation trimmed to: ' ||
                       l_count || '  freespace(mbs)=' || l_freespace/ONE_MEG);
  END LOOP;
 
--
  DBMS_RA_SCHEDULER.UNLOCK (DBMS_RA_SCHEDULER.LOCK_PURGE, p_sl_key);
 
EXCEPTION
  WHEN OTHERS THEN
    save_error;
    ROLLBACK;
    DBMS_RA_SCHEDULER.UNLOCK (DBMS_RA_SCHEDULER.LOCK_PURGE, p_sl_key);
    trace1 ('PURGE_STORAGE_LOCATION: Failed with: ' || SQLERRM);
    RAISE;
END purge_storage_location;
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
FUNCTION available_bs(p_sl_key IN NUMBER,
                      p_db_key IN NUMBER,
                      p_alloc  IN NUMBER) RETURN BOOLEAN IS
  l_count NUMBER;
  l_ret   BOOLEAN := TRUE;
BEGIN
--
  SELECT COUNT(*) INTO l_count
    FROM odb
    WHERE db_key = p_db_key
      AND used_space + p_alloc >= reserved_space;
 
--
  IF l_count > 0 THEN
    SELECT COUNT(*) INTO l_count
      FROM dual WHERE EXISTS (SELECT 1 FROM bp
                              WHERE db_key = p_db_key
                              AND lib_key IS NULL /* Only backups on disk */
                              AND status = 'A'
                              AND ba_access = 'L');
    IF l_count = 0 THEN
      trace1('AVAILABLE_BS has nothing to delete for db_key ' || p_db_key);
--
      l_ret := FALSE;
    END IF;
  END IF;
 
  RETURN l_ret;
END available_bs;
 
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE purge_database         (p_db_key IN NUMBER,
                                  p_sl_key IN NUMBER DEFAULT NULL,
                                  p_inline IN BOOLEAN DEFAULT FALSE) IS
 
l_sl_key                NUMBER := p_sl_key;
l_count                 NUMBER;
 
BEGIN
  trace1 ('PURGE_DATABASE: db_key=' || p_db_key ||
                       ', sl_key=' || print(p_sl_key) ||
                       ', inline=' || print(p_inline) );
 
  IF l_sl_key IS NULL THEN
    SELECT sl_key INTO l_sl_key
      FROM odb
      WHERE db_key = p_db_key;
    trace1 ('PURGE_DATABASE: sl_key=' || l_sl_key);
  END IF;
 
--
--
--
  DBMS_RA_SCHEDULER.S_PURGING_ACTIVE := TRUE;
  dbms_ra_pool.purgeDB(l_sl_key, p_db_key, p_inline);
  DBMS_RA_SCHEDULER.S_PURGING_ACTIVE := FALSE;
  trace1 ('PURGE_DATABASE: ... Done Purging');
 
--
--
--
  SELECT COUNT(*) INTO l_count FROM odb
    WHERE wait_space > used_space AND db_key = p_db_key;
  IF l_count > 0 THEN
    DBMS_RA_SCHEDULER.RELEASE_BLOCKED_TASKS (
                                DBMS_RA_SCHEDULER.SPACE_PSEUDO_TASK, p_db_key);
    lock_db (p_db_key);
    UPDATE odb SET wait_space = NULL WHERE db_key = p_db_key;
    COMMIT;
    unlock_db (p_db_key);
  END IF;
 
EXCEPTION
  WHEN OTHERS THEN 
    save_error;
    trace1 ('PURGE_DATABASE: Exception: ' || SQLERRM);
 
    DBMS_RA_SCHEDULER.S_PURGING_ACTIVE := FALSE;
    RAISE;
END purge_database;
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE backupArch(p_dbkey    IN NUMBER,
                     p_fname    IN VARCHAR2,
                     p_complete IN BOOLEAN,
                     p_delete   IN BOOLEAN DEFAULT TRUE) IS
  KRSP_SUCCESS CONSTANT NUMBER := 0;  -- As defined in krsp.h
  KRSP_REFETCH CONSTANT NUMBER := 1;  -- As defined in krsp.h
  KRSP_GIVEUP  CONSTANT NUMBER := 2;  -- As defined in krsp.h
  l_ftype             NUMBER;
  l_dbid              NUMBER;
  l_size              NUMBER;
  l_count             NUMBER;
  l_iscomplete        BOOLEAN;
  l_dbinckey          NUMBER;
  l_lowscn            NUMBER;
  l_handle            bp.handle%TYPE;
  l_inchandle         bp.handle%TYPE;
  l_arcwhole          NUMBER;
  l_action            NUMBER := 0;
  l_sameendian        NUMBER;
BEGIN
  trace1('backupArch: dbkey ' || p_dbkey ||
         ', name ' || p_fname);
 
--
  IF p_complete THEN
    l_arcwhole := TRUE#;
  ELSE
    l_arcwhole := FALSE#;
  END IF;
 
--
--
--
  sys.kbrsi_icd.rsIsComplete(fname    => p_fname,
                             filesize => l_size,
                             complete => l_iscomplete,
                             ftype    => l_ftype,
                             same_endian => l_sameendian,
                             dbid     => l_dbid);
  IF NOT l_iscomplete THEN -- There is some issue with the source file.
    trace1('backupArch: Archived Log ' || p_fname || ' cannot be backed up');
--
--
--
    IF p_delete THEN
      SYS.KBRSI_ICD.RSDELETEFILE(p_fname);
    END IF;
 
--
--
--
    SELECT db_id INTO l_dbid FROM db WHERE db_key = p_dbkey;
--
    SYS.KBRSI_ICD.DG_BACKEDUP(l_dbid, p_fname, l_arcwhole, KRSP_REFETCH);
    COMMIT;
    RETURN;
  END IF;
 
--
--
--
--
--
 
--
  BEGIN
    SELECT 1 INTO l_count FROM db WHERE db_key = p_dbkey AND db_id = l_dbid;
  EXCEPTION
    WHEN no_data_found THEN
      save_error;
      tracex('backupArch: Archived Log ' || p_fname ||
             ' has a bad dbid ' || l_dbid);
 
      sys.dbms_sys_error.raise_system_error(
                                        DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM,
                                        'arc log with bad dbid ' || l_dbid);
  END;
 
--
  IF l_size IS NULL OR l_size < 1 THEN
    tracex('backupArch: Archived Log ' || p_fname ||
           ' has a bad size ' || l_size);
      sys.dbms_sys_error.raise_system_error(
                                        DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM,
                                        'arc log with bad size ' || l_size);
  END IF;
 
--
  IF l_sameendian /* skgfrfALGCVT */ = 0 THEN                -- archivelog xtt
     l_action :=  DBMS_RA_SCHEDULER.COPY_BA_XALG /*KRBYX_ORS_XALG*/;
 
     SELECT DECODE(odb.same_endian, 'N', 0, 'Y', 1, -1)
          INTO l_sameendian
          FROM odb
          WHERE db_key = p_dbkey;
 
     IF l_sameendian != 0 THEN
       /* Update db about this */
       UPDATE odb SET same_endian='N'
         WHERE db_key = p_dbkey;
       COMMIT;
       END IF;
  END IF;
 
--
--
--
  BEGIN
    l_handle := dbms_ra_int.file2handle(p_fname);
    copy_piece(p_fname, p_dbkey, l_action);
 
    DBMS_RA_SCHEDULER.fix_error (
                 p_error_num => DBMS_RA_SCHEDULER.E_BACKUP_FAILED,
                 p_db_key    => p_dbkey);
 
  EXCEPTION
    WHEN dbms_ra_scheduler.E_SERVLET_ERROR OR DUP_VAL_ON_INDEX THEN
      save_error;
      SELECT COUNT(*) INTO l_count
        FROM sbt_catalog WHERE handle = l_handle;
      IF l_count = 0 THEN  -- Handle is not already present
        RAISE;             -- we do not know what is wrong.
      END IF;
      tracex('backupArch: File already backed up');
      clear_error;
    WHEN DBMS_RA_SCHEDULER.E_NO_MORE_STORAGE
      OR DBMS_RA_SCHEDULER.E_PIECE_TOO_BIG THEN
      save_error;
      DBMS_RA_SCHEDULER.log_error (
                 p_errno => DBMS_RA_SCHEDULER.E_BACKUP_FAILED,
                 p_component => 'NZDL',
                 p_severity  => DBMS_RA_SCHEDULER.SEVERITY_ERROR,
                 p_db_key    => p_dbkey,
                 p_param1 => DBMS_RA_INT.DBKEY2NAME(p_dbkey));
      clear_error;
 
      IF p_delete THEN
        SYS.KBRSI_ICD.RSDELETEFILE(p_fname);
      END IF;
 
      SYS.KBRSI_ICD.DG_BACKEDUP(l_dbid, p_fname, l_arcwhole, KRSP_GIVEUP);
      RETURN;
  END;
 
--
--
--
  IF DBMS_RA_SCHEDULER.S_CURRENT_TASK_TYPE = 
                                     DBMS_RA_SCHEDULER.TASK_BACKUP_ARCH THEN
    SELECT dbinc_key, low_scn INTO l_dbinckey, l_lowscn
      FROM bp p, brl r
      WHERE p.bs_key = r.bs_key
        AND p.handle = l_handle;
 
    SELECT MIN(p.handle) INTO l_inchandle
      FROM bp p, brl r
      WHERE p.bs_key = r.bs_key
        AND r.dbinc_key = l_dbinckey
        AND r.low_scn = l_lowscn
        AND p.handle LIKE DBMS_RA_INT.INC_ARC_PREFIX || '%';
    IF l_inchandle  IS NOT NULL THEN
      free_backup_piece(p_dbkey, l_inchandle);
    END IF;
  END IF;
 
--
--
--
  IF p_delete THEN
    SYS.KBRSI_ICD.RSDELETEFILE(p_fname);
  END IF;
 
--
--
--
  SYS.KBRSI_ICD.DG_BACKEDUP(l_dbid, p_fname, l_arcwhole, KRSP_SUCCESS);
  COMMIT;
 
EXCEPTION
  WHEN OTHERS THEN
    save_error;
    trace1('backupArch: failure on ' || p_fname);
 
--
--
    SELECT COUNT(*) INTO l_count
      FROM task
      WHERE error_count >= dbms_ra_scheduler.s_max_task_restarts - 1
        AND task_id = dbms_ra_scheduler.s_current_task;
    IF l_count > 0 THEN
      trace1('backupArch: Archived Log ' || p_fname || ' not backed up');
 
--
      IF p_delete THEN
        SYS.KBRSI_ICD.RSDELETEFILE(p_fname);
      END IF;
 
--
      SELECT COUNT(*) INTO l_count FROM db WHERE db_id = l_dbid;
      IF l_count > 0 THEN
        trace1('backupArch: dbid ' || l_dbid);
        SYS.KBRSI_ICD.DG_BACKEDUP(l_dbid, p_fname, l_arcwhole, KRSP_GIVEUP);
      END IF;
      COMMIT;
    END IF;
 
    RAISE;
END backupArch;
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE  move_database_metadata (p_db_key IN NUMBER,
                                   p_old_sl_key IN NUMBER,
                                   p_sl_key IN NUMBER) IS
 
l_sls_used           NUMBER;
l_old_sl_allocated   NUMBER;
l_old_sl_used        NUMBER;
l_new_sl_used        NUMBER;
l_new_purge_reserve  NUMBER;
l_prot_key           NUMBER;
l_prot_recovery_window_goal prot.prot_recovery_window_goal%TYPE;
l_sl_min_alloc       NUMBER;
l_chunksize          NUMBER;
l_task_rec           task%ROWTYPE;
 
BEGIN
  trace1 ('MOVE_DATABASE_METADATA:  db_key=' || p_db_key ||
                                 ', old_sl_key=' || p_old_sl_key ||
                                 ', sl_key=' || p_sl_key);
 
--
--
--
  IF p_sl_key = p_old_sl_key THEN
    trace1 ('MOVE_DATABASE_METADATA:  Nothing to move');
    RETURN;
  END IF;
 
--
--
--
  SELECT allocated_space, used_space,   sls_used,
         prot_key, sl_min_alloc
    INTO   l_old_sl_allocated, l_old_sl_used, l_sls_used,
           l_prot_key, l_chunksize
    FROM odb
    WHERE db_key = p_db_key;
 
  trace1 ('MOVE_DATABASE_METADATA:  old_sl_allocated=' || l_old_sl_allocated ||
                                 ', old_sl_used=' || l_old_sl_used ||
                                 ', sls_used=' || l_sls_used);
 
--
--
--
--
  IF l_old_sl_used > 0 THEN
    INSERT INTO dbsl (  db_key,       sl_key, dbsl_used_space)
              VALUES (p_db_key, p_old_sl_key, l_old_sl_used);
    l_sls_used := l_sls_used + 1;
  END IF;
 
--
--
--
--
  SELECT MIN(dbsl_used_space) INTO l_new_sl_used
    FROM dbsl
    WHERE db_key = p_db_key AND sl_key = p_sl_key;
 
  IF l_new_sl_used IS NULL THEN
    l_new_sl_used := 0;
  ELSE
    DELETE dbsl WHERE db_key = p_db_key AND sl_key = p_sl_key;
    l_sls_used := l_sls_used - 1;
  END IF;
 
--
--
--
  SELECT sl_min_alloc INTO l_sl_min_alloc
    FROM sl
    WHERE sl_key = p_sl_key;
 
--
--
--
  SELECT prot_recovery_window_goal INTO l_prot_recovery_window_goal
    FROM prot
    WHERE prot_key = l_prot_key;
 
--
--
--
--
  UPDATE odb SET sl_key = p_sl_key,
                 sl_min_alloc    = l_sl_min_alloc,
                 total_allocation = total_allocation -
                                          (l_old_sl_allocated - l_old_sl_used),
                 sls_used        = l_sls_used,
                 allocated_space = l_new_sl_used,
                 used_space      = l_new_sl_used,
                 move_phase      = DBMS_RA_SCHEDULER.MOVE_PHASE_POOL,
                 prot_key        = future_prot_key,
                 recovery_window_goal = l_prot_recovery_window_goal
    WHERE db_key = p_db_key;
  COMMIT;
 
  used_space_check (p_db_key, p_sl_key);
 
EXCEPTION
  WHEN OTHERS THEN
    save_error;
    ROLLBACK;
    RAISE;
END move_database_metadata;
 
--
--
--
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE trim_database_for_move (p_db_key IN NUMBER, p_alloc IN NUMBER) IS
l_alloc              NUMBER := NVL(p_alloc, 0);
l_api_lock_wait      NUMBER;
l_total_allocation   NUMBER;
l_planned_purges     NUMBER;
l_sl_key             NUMBER;
l_unclaimed          NUMBER;
l_reservation        NUMBER;
l_base_res           NUMBER;
l_new_res            NUMBER;
l_used_space         NUMBER;
l_phase              NUMBER;
l_newsecs            NUMBER;
l_goalsecs           NUMBER;
 
 CURSOR bp_cursor IS
  SELECT MIN(bp_key) bp_key, vb_key, SUBSTR(MIN(tag),1,15) tag,
         TO_CHAR(MIN(start_time), ' HH:MI:SS') start_time, COUNT(*) bps
  FROM bp
  WHERE vb_key IS NOT NULL
    AND tag LIKE 'LOT_%'
    AND status != 'D'
  GROUP BY vb_key
  ORDER by vb_key;
 
BEGIN
  trace1 ('TRIM_DATABASE_FOR_MOVE db_key=' || p_db_key);
 
--
--
--
--
--
--
 
--
--
--
--
--
  SELECT value INTO l_api_lock_wait
    FROM config
    WHERE name = '_api_lock_wait_seconds';
 
  WHILE NOT SYS.KBRSI_ICD.RSAPILOCK LOOP
    l_api_lock_wait := l_api_lock_wait - 1;
    IF l_api_lock_wait = 0 THEN
      RAISE DBMS_RA_SCHEDULER.E_RETRY_ERROR;
    END IF;
    DBMS_LOCK.SLEEP(1);
  END LOOP;
 
--
--
--
  SELECT sl_key, reserved_space, base_reserved_space, used_space, move_phase
    INTO l_sl_key, l_reservation, l_base_res, l_used_space, l_phase
    FROM odb WHERE db_key = p_db_key;
 
--
--
--
--
--
  SELECT MIN(sl_space -
             DECODE(sl_key, l_sl_key, space - l_reservation, space) -
             DBMS_RA_SCHEDULER.S_PURGING_RESERVE * 2)
    INTO l_unclaimed
    FROM /* List of sl_keys and the claimed space */
         (SELECT sl.sl_key, SUM(reserved_space) space, sl_space
          FROM sl, (SELECT reserved_space, sl_key FROM odb
                    UNION ALL
                    SELECT u.reserved_space, p.sl_key
                    FROM unreg_database u, prot p
                    WHERE u.prot_key = p.prot_key) d
          WHERE d.sl_key = sl.sl_key
          GROUP BY sl.sl_key, sl_space) s
    WHERE sl_key = l_sl_key OR /* list of related sl_keys */
          sl_key IN (SELECT prot.sl_key FROM prot, odb
                     WHERE odb.db_key = p_db_key
                       AND (prot.prot_key = odb.prot_key OR
                            prot.prot_key = odb.future_prot_key));
 
--
--
--
--
--
--
--
--
  IF l_phase = DBMS_RA_SCHEDULER.MOVE_PHASE_PEND THEN
    l_new_res := l_reservation;
  ELSE
    l_new_res := LEAST(l_unclaimed,
                       GREATEST(DBMS_RA_SCHEDULER.S_TRIM_FACTOR * l_base_res,
                                l_used_space + l_alloc) );
  END IF;
  trace1 ('TRIM_DATABASE: new reservation is ' || l_new_res);
 
--
--
--
--
--
  lock_db (p_db_key);
  UPDATE odb
    SET reserved_space = l_new_res
    WHERE  db_key = p_db_key;
  COMMIT;
  unlock_db (p_db_key);
 
--
--
  SYS.KBRSI_ICD.RSAPIUNLOCK;
 
--
--
--
  LOOP
--
--
--
    lock_db (p_db_key);
    UPDATE odb
      SET total_allocation = total_allocation -
                                 (allocated_space - used_space),
          allocated_space = used_space
      WHERE  db_key = p_db_key
      RETURNING total_allocation
           INTO l_total_allocation;
    COMMIT;
    unlock_db (p_db_key);
 
--
--
--
--
    l_planned_purges := f_chunksize(p_db_key) *
                        dbms_ra_pool.plannedDBSpace(p_db_key);
    trace1 ('TRIM_DATABASE: planned_purges ' || l_planned_purges ||
            ', allocation ' || l_total_allocation ||
            ', l_alloc ' || l_alloc);
    EXIT WHEN (l_alloc + l_total_allocation - l_planned_purges) < l_new_res;
 
--
--
--
--
    IF  l_phase = DBMS_RA_SCHEDULER.MOVE_PHASE_PEND
    AND (l_alloc + l_total_allocation - l_planned_purges) < l_unclaimed
    THEN
--
      SELECT newsecs,   goalsecs
        INTO l_newsecs, l_goalsecs
        FROM rai_purge_queue
        WHERE db_key = p_db_key;
      EXIT WHEN (l_newsecs < l_goalsecs);
    END IF;
 
    IF s_tracing_on THEN
      FOR t IN bp_cursor LOOP
        trace1(LPAD(t.vb_key, 6) || LPAD(t.bps, 4) || ' ' ||
               t.tag || t.start_time);
      END LOOP;
    END IF;
 
--
--
--
    BEGIN
      DBMS_RA_SCHEDULER.GET_LOCK (DBMS_RA_SCHEDULER.LOCK_PURGE, l_sl_key);
      purge_database (p_db_key, NULL, FALSE);
      DBMS_RA_SCHEDULER.UNLOCK(DBMS_RA_SCHEDULER.LOCK_PURGE, l_sl_key);
    EXCEPTION
--
      WHEN DBMS_RA_SCHEDULER.E_RETRY_ERROR OR 
           DBMS_RA_SCHEDULER.E_RETRY_RESERVE THEN
        save_error;
        trace1 ('TRIM_DB:  Locking Error...Retry in a bit');
        DBMS_RA_SCHEDULER.UNLOCK (DBMS_RA_SCHEDULER.LOCK_PURGE, l_sl_key);
        SYS.KBRSI_ICD.RSAPIUNLOCK;
        DBMS_LOCK.SLEEP(DBMS_RA_SCHEDULER.S_LOCK_REFUSED_WAIT);
        clear_error;
        CONTINUE;
      WHEN OTHERS THEN
        save_error;
        trace1 ('TRIM_DB: Purge failed with: ' || SQLERRM);
        DBMS_RA_SCHEDULER.UNLOCK (DBMS_RA_SCHEDULER.LOCK_PURGE, l_sl_key);
        SYS.KBRSI_ICD.RSAPIUNLOCK;
        RAISE;
    END;
  END LOOP;
END trim_database_for_move;
 
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE  trim_database_as_job (p_db_key IN NUMBER,
                                 p_sl_key IN NUMBER,
                                 p_allocation IN NUMBER) IS
 
l_task_rec task%ROWTYPE;
 
BEGIN
  trace1 ('TRIM_DATABASE_AS_JOB:  db_key=' || p_db_key ||
                                 ', sl_key=' || p_sl_key ||
                                 ', allocation=' || p_allocation);
 
--
--
--
  l_task_rec.task_type     := DBMS_RA_SCHEDULER.TASK_TRIM_DB;
  l_task_rec.db_key        := p_db_key;
  l_task_rec.sl_key        := p_sl_key; -- Used to query task queue.
  l_task_rec.param_num1    := p_allocation;
  l_task_rec.flags         := 0;
  DBMS_RA_SCHEDULER.NEW_TASK(l_task_rec);
 
--
--
--
  DBMS_RA_SCHEDULER.SCHEDULE (p_task_type => DBMS_RA_SCHEDULER.TASK_TRIM_DB,
                              p_param1 => p_sl_key,
                              p_param2 => p_db_key);
  trace1 ('TRIM_DATABASE_AS_JOB complete');
 
END trim_database_as_job;
 
--
--
--
--
--
--
--
--
--
--
FUNCTION freespace (p_sl_key IN NUMBER) RETURN NUMBER IS
 
l_allocsize     NUMBER;
l_slsize        NUMBER;
l_purgereserve  NUMBER;
l_free          NUMBER;
 
BEGIN
  trace1 ('FREESPACE:  sl_key = ' || p_sl_key);
 
--
--
--
  SELECT ((SELECT NVL(SUM(allocated_space),0)
            FROM odb
            WHERE (odb.sl_key = p_sl_key)) +
          (SELECT NVL(SUM(dbsl_used_space),0)
          FROM dbsl
          WHERE (dbsl.sl_key = p_sl_key))),
         sl_space
  INTO l_allocsize, l_slsize
  FROM sl
  WHERE sl_key = p_sl_key;
 
  trace1 ('FREESPACE:  l_allocsize = ' || l_allocsize ||
                    ', l_slsize = ' || l_slsize);
 
--
--
--
  IF DBMS_RA_SCHEDULER.S_SYSRESERVE_OK THEN
    l_purgereserve := 0;
  ELSE
    l_purgereserve := DBMS_RA_SCHEDULER.S_PURGING_RESERVE;
  END IF;
 
  l_free := (l_slsize - l_purgereserve) - l_allocsize;
  trace1 ('FREESPACE:  sl_key = ' || p_sl_key || '; l_free = ' || l_free);
 
  RETURN l_free;
EXCEPTION
    WHEN NO_DATA_FOUND THEN 
      save_error;
      trace1 ('FREESPACE: No space in storage location');
      RAISE;
END freespace;
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE used_space_check (p_db_key IN NUMBER,  
                            p_sl_key IN NUMBER,
                            p_check_files IN BOOLEAN DEFAULT FALSE,
                            p_repair_sl_key IN NUMBER DEFAULT NULL) IS
l_chunksize             NUMBER;
l_used_space            NUMBER;
l_move_phase            NUMBER;
l_total                 NUMBER;
l_allocated             NUMBER;
l_dbsl_used             NUMBER;
l_task_purge_reserve    NUMBER;
l_task_chunk_cache      NUMBER;
 
l_blockpool_usage       NUMBER;
l_sbtpiece_usage        NUMBER;
BEGIN
  IF s_safe_mode OR p_check_files THEN
    trace1 ('USED_SPACE_CHECK for db_key=' || p_db_key ||
                               '; db_sl_key=' || p_sl_key ||
                               '; check_files=' || print(p_check_files) ||
                               '; repair_sl_key=' || print(p_repair_sl_key));
 
    l_chunksize := f_chunksize(p_db_key);
 
--
--
--
--
    WITH bp_usage AS
    (
    SELECT /*+
             USE_NL_WITH_INDEX(c) LEADING(dbinc df) INDEX(df)
             NO_INDEX_FFS(c) INDEX_RS_ASC(c)
            */
           p_db_key db_key
         , COUNT(*) * l_chunksize blockpool_usage
      FROM chunks c
--
         , df
         , dbinc
     WHERE c.df_key = df.df_key
       AND c.dbinc_key = dbinc.dbinc_key
       AND df.dbinc_key = dbinc.dbinc_key
       AND dbinc.db_key = p_db_key
       AND c.sl_key = NVL(p_repair_sl_key, c.sl_key)
    )
    , sbt_usage AS
    (
    SELECT p_db_key db_key
         , SUM(filesize) sbtpiece_usage
      FROM sbt_catalog
     WHERE db_key = p_db_key
       AND sbt_catalog.sl_key = NVL(p_repair_sl_key, sbt_catalog.sl_key)
    )
    , tasks_usage AS
    (
    SELECT p_db_key db_key
         , SUM(t.purge_reserve) * l_chunksize task_purge_reserve
         , SUM(tcc.chunk_cache) * l_chunksize task_chunk_cache
      FROM task t
      LEFT OUTER JOIN task_chunk_cache tcc USING (task_id)
     WHERE t.db_key = p_db_key
       AND p_sl_key = NVL (p_repair_sl_key, p_sl_key)
    )
    , dbsl_usage AS
    (
    SELECT p_db_key db_key
         , SUM(dbsl_used_space) dbsl_used
      FROM dbsl
     WHERE dbsl.db_key = p_db_key
       AND dbsl.sl_key = NVL(p_repair_sl_key, dbsl.sl_key)
    )
    , odb_usage AS
    (
    SELECT p_db_key db_key
         , odb.used_space used_space 
         , odb.move_phase move_phase
         , total_allocation total
         , allocated_space allocated
      FROM odb
     WHERE odb.db_key = p_db_key
    )
    SELECT /*+
           OPT_PARAM('optimizer_dynamic_sampling' 0)
           OPT_PARAM('_optimizer_adaptive_cursor_sharing' 'false')
           OPT_PARAM('_optimizer_extended_cursor_sharing_rel' 'none')
           OPT_PARAM('_optimizer_use_feedback' 'false')
           LEADING(odb_usage dbsl_usage task_usage sbt_usage bp_usage)
           */
           NVL(MIN(used_space), 0)
         , NVL(MIN(move_phase), 0)
         , NVL(MIN(total), 0)
         , NVL(MIN(allocated), 0)
         , NVL(MIN(dbsl_used), 0)
         , NVL(MIN(task_purge_reserve), 0)
         , NVL(MIN(task_chunk_cache), 0)
         , NVL(MIN(sbtpiece_usage), 0)
         , NVL(MIN(blockpool_usage), 0)
      INTO l_used_space
         , l_move_phase
         , l_total
         , l_allocated
         , l_dbsl_used
         , l_task_purge_reserve
         , l_task_chunk_cache
         , l_sbtpiece_usage
         , l_blockpool_usage
      FROM odb_usage
      LEFT OUTER JOIN dbsl_usage USING (db_key)
      LEFT OUTER JOIN tasks_usage USING (db_key)
      LEFT OUTER JOIN sbt_usage USING (db_key)
      LEFT OUTER JOIN bp_usage USING (db_key);
 
    trace1 ('USED_SPACE_CHECK:  move phase=' || l_move_phase ||
                             '; odb usage=' || l_used_space ||
                             '; dbsl usage=' || l_dbsl_used ||
                             '; pool usage=' || l_blockpool_usage || 
                             '; pieceusage=' || l_sbtpiece_usage ||
                             '; chunk_cache=' || l_task_chunk_cache ||
                             '; purge_reserve=' || l_task_purge_reserve ||
                             '; chunk_size=' || l_chunksize ||
                             '; db_key=' || p_db_key);
 
    IF p_repair_sl_key IS NOT NULL THEN
--
--
--
--
--
--
--
      IF l_dbsl_used = 0  THEN
        UPDATE odb 
          SET used_space       = (l_blockpool_usage + l_sbtpiece_usage),
              allocated_space  = (l_blockpool_usage + l_sbtpiece_usage),
              total_allocation = (l_blockpool_usage + l_sbtpiece_usage)
          WHERE db_key = p_db_key;
      ELSE
        UPDATE dbsl 
          SET dbsl_used_space =  (l_blockpool_usage + l_sbtpiece_usage + 
                                  l_task_chunk_cache + l_task_purge_reserve)
          WHERE db_key = p_db_key
            AND sl_key = p_repair_sl_key;
      END IF;
    ELSIF (NOT DBMS_RA_SCHEDULER.S_REPAIR_ACTIVE) AND
       ((l_blockpool_usage + l_sbtpiece_usage + 
         l_task_chunk_cache + l_task_purge_reserve) <> 
        (l_used_space + l_dbsl_used)) THEN
      trace1 ('USED_SPACE_CHECK:  Check failed...');
 
      DBMS_RA_SCHEDULER.LOG_ERROR (
                 p_errno     => DBMS_RA_SCHEDULER.E_BAD_ODB_USAGE_NUM,
                 p_param1    => l_used_space+l_dbsl_used,
                 p_param2    => DBMS_RA_INT.DBKEY2NAME(p_db_key),
--
                 p_param3    => 'sl_key=' || TO_CHAR(p_sl_key),
                 p_param4    => (l_blockpool_usage + l_sbtpiece_usage + 
                                 l_task_chunk_cache + l_task_purge_reserve),
                 p_component => 'CHECK_FILES',
                 p_severity  => DBMS_RA_SCHEDULER.SEVERITY_ERROR,
                 p_db_key    => p_db_key);
    END IF;
 
    trace1 ('USED_SPACE_CHECK:  total_allocation is ' || l_total ||
                             '; allocation=' || l_allocated || 
                             '; dbsl_used=' || l_dbsl_used ||
                             '; db_key=' || p_db_key);
 
    IF (l_total <> (l_allocated + l_dbsl_used)) AND 
       (NOT DBMS_RA_SCHEDULER.S_REPAIR_ACTIVE) THEN
      DBMS_RA_SCHEDULER.LOG_ERROR (
                 p_errno     => DBMS_RA_SCHEDULER.E_BAD_TOTAL_ALLOC_NUM,
                 p_param1    => l_total,
                 p_param2    => DBMS_RA_INT.DBKEY2NAME(p_db_key),
                 p_param3    => l_allocated+l_dbsl_used,
                 p_component => 'CHECK_FILES',
                 p_severity  => DBMS_RA_SCHEDULER.SEVERITY_ERROR,
                 p_db_key    => p_db_key);
    END IF;
 
  END IF;
EXCEPTION
  WHEN    DBMS_RA_SCHEDULER.E_SNAPSHOT_TOO_OLD 
       OR DBMS_RA_SCHEDULER.E_CONSISTENT_READ THEN
    save_error;
    IF p_check_files THEN
      RAISE;
    ELSE
--
       trace1 ('USED_SPACE_CHECK: Ignoring check due to -- ' || SQLERRM);
       clear_error;       
    END IF;
END used_space_check;
 
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE lock_db (
                        p_db_key    IN NUMBER) IS
 
l_return                NUMBER;
 
BEGIN
  tracex ('LOCK_DB for db_key ' || p_db_key);
  IF (s_db_level <> 0) OR (s_sl_level <> 0) THEN
    tracex('LOCK_DB:  Bad locking protocol: ' ||
                                              s_db_level || ',' || s_sl_level);
--
--
--
--
  ELSE
    SYS.KBRSI_ICD.RSDBLOCK (p_db_key);
    s_db_level := s_db_level + 1;
  END IF;
EXCEPTION
  WHEN OTHERS THEN
    save_error;
    tracex ('LOCK_DB EXCEPTION: '  || SQLERRM);
    RAISE;
END lock_db;
 
 
--
--
--
--
--
--
--
--
--
PROCEDURE unlock_db ( p_db_key    IN NUMBER) IS
 
l_return                NUMBER;
 
BEGIN
  tracex ('UNLOCK_DB for db_key ' || p_db_key);
  IF (s_sl_level <> 0) THEN
    tracex('UNLOCK_DB:  Bad locking protocol: ' ||
                                              s_db_level || ',' || s_sl_level);
--
--
--
--
  ELSIF (s_db_level > 0) THEN
    SYS.KBRSI_ICD.RSDBUNLOCK (p_db_key);
    s_db_level := s_db_level - 1;
  END IF;
END unlock_db;
 
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE lock_sl (p_sl_key    IN NUMBER) IS
 
l_return                NUMBER;
 
BEGIN
  tracex ('LOCK_SL for sl_key ' || p_sl_key);
  IF (s_sl_level <> 0) THEN
    tracex('LOCK_SL:  Bad locking protocol: ' ||
                                              s_db_level || ',' || s_sl_level);
--
--
--
--
  ELSE
    SYS.KBRSI_ICD.RSSLLOCK (p_sl_key);
    s_sl_level := s_sl_level + 1;
  END IF;
EXCEPTION
  WHEN OTHERS THEN
    save_error;
    tracex ('LOCK_SL EXCEPTION: '  || SQLERRM);
    RAISE;
END lock_sl;
 
--
--
--
--
--
--
--
--
--
PROCEDURE unlock_sl ( p_sl_key    IN NUMBER) IS
 
l_return                NUMBER;
 
BEGIN
  tracex ('UNLOCK_SL for sl_key ' || p_sl_key);
  IF (s_sl_level > 0) THEN
    SYS.KBRSI_ICD.RSSLUNLOCK (p_sl_key);
    s_sl_level := s_sl_level - 1;
  END IF;
END unlock_sl;
 
 
--
--
--
--
--
--
--
--
--
--
--
FUNCTION print (p_value IN BOOLEAN) RETURN VARCHAR2 IS
BEGIN
  IF p_value THEN
    RETURN 'TRUE';
  ELSIF p_value IS NULL THEN
    RETURN 'NULL';
  ELSE
    RETURN 'FALSE';
  END IF;
END print;
 
FUNCTION print (p_value IN NUMBER) RETURN VARCHAR2 IS
BEGIN
  RETURN NVL(TO_CHAR(p_value),'NULL');
END print;
 
FUNCTION print (p_value IN DSINTERVAL_UNCONSTRAINED) RETURN VARCHAR2 IS
BEGIN
  RETURN NVL(TO_CHAR(p_value),'NULL');
END print;
 
 
FUNCTION print (p_value IN VARCHAR2) RETURN VARCHAR2 IS
BEGIN
  RETURN NVL(p_value,'***NULL***');
END print;
 
 
--
--
--
--
--
--
--
--
--
--
PROCEDURE tracex (message IN VARCHAR2) IS
  l_pos   NUMBER := 1;
BEGIN
--
--
--
  IF NOT s_init_done THEN
    DBMS_RA_SCHEDULER.LOAD_CONFIG;
    s_init_done := TRUE;
  END IF;
 
--
--
--
  LOOP
    sys.kbrsi_icd.rsTrace('RSSM:' || SUBSTR(message, l_pos, 1000));
    l_pos := l_pos+1000;
 
    EXIT WHEN l_pos > LENGTH(message);
  END LOOP;
END tracex;
 
--
--
--
--
--
--
--
--
PROCEDURE trace1 (message IN VARCHAR2) IS
  l_pos   NUMBER := 1;
BEGIN
--
--
--
  IF NOT s_init_done THEN
    DBMS_RA_SCHEDULER.LOAD_CONFIG;
    s_init_done := TRUE;
  END IF;
 
--
--
--
  IF s_tracing_on
  THEN
    LOOP
      sys.kbrsi_icd.rsTrace('RSSM:' || SUBSTR(message, l_pos, 1000));
      l_pos := l_pos+1000;
 
      EXIT WHEN l_pos > LENGTH(message);
    END LOOP;
  END IF;
END trace1;
 
--
--
PROCEDURE setTracing(p_trc_on IN NUMBER,
                     p_perf_on IN NUMBER DEFAULT 0,
                     p_stall_on IN NUMBER DEFAULT 0,
                     p_safe_mode IN NUMBER DEFAULT 0) IS
BEGIN
 
  s_tracing_on := (p_trc_on > 0);
  s_perf_on := (p_perf_on > 0);
  s_stall_on := (p_stall_on > 0);
  s_safe_mode := (p_safe_mode > 0);
 
END setTracing;
 
END dbms_ra_storage;
>>>
 
define prvtrs_plb
<<<
CREATE OR REPLACE PACKAGE BODY dbms_ra IS
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
 
--
 
  
--
  CCCHK_ALL_APIS                CONSTANT NUMBER := 1;
  CCCHK_CREDEL_REP_SERVER       CONSTANT NUMBER := 2;
 
--
--
 
--
--
  AM_SEC_OPERATION_GRANT        CONSTANT NUMBER := 1;
  AM_SEC_OPERATION_REVOKE       CONSTANT NUMBER := 2;
 
--
  AM_SEC_PRIVTYPE_BACKUP        CONSTANT NUMBER := 10;
  AM_SEC_PRIVTYPE_RECONCILE     CONSTANT NUMBER := 11;
  AM_SEC_PRIVTYPE_ALL           CONSTANT NUMBER := 12;
 
--
  AM_SEC_ACCESSTYPE_READ        CONSTANT NUMBER := 20;
  AM_SEC_ACCESSTYPE_WRITE       CONSTANT NUMBER := 21;
  AM_SEC_ACCESSTYPE_ALL         CONSTANT NUMBER := 22;
 
--
  ONEMEG           CONSTANT NUMBER := 1024 * 1024; /* Just a handy reference */
  FOURMEG          CONSTANT NUMBER := 4 * ONEMEG;  /* Default _def_min_alloc */
  MIN_CG_FILE_SIZE CONSTANT NUMBER := 40 * ONEMEG;   /* Hard code 40 meg min */
  MIN_CG_FILE_SIZE_NUMSTR CONSTANT VARCHAR2(3) := '40M';/* used in error msg */
 
--
  MIN_RESERVATION               CONSTANT NUMBER := 10 * ONEMEG;
 
--
  TYPE destRecord_t IS RECORD
  (
     name_dest VARCHAR2(4000),
     size_dest NUMBER
  );
 
  TYPE destList_t IS TABLE OF destRecord_t INDEX BY BINARY_INTEGER;
 
--
  FUNCTION item_not_found (p_obj_name IN VARCHAR2,
                           p_obj_type IN VARCHAR2
                          ) RETURN VARCHAR2;
 
  FUNCTION numstring_to_num (p_numstr IN VARCHAR2,
                             p_allow0 IN BOOLEAN DEFAULT FALSE
                            ) RETURN NUMBER;
  
  FUNCTION add_repository(catalog_user_name  VARCHAR2,
                          new_server_key     NUMBER,
                          am_server_name     VARCHAR2,
                          wallet_alias       VARCHAR2,
                          wallet_path        VARCHAR2,
                          proxy_url          VARCHAR2   DEFAULT NULL,
                          proxy_port         NUMBER     DEFAULT NULL,
                          http_timeout       NUMBER     DEFAULT NULL
                         ) RETURN NUMBER;
 
  PROCEDURE grant_network_acl_ace(catalog_user_name  VARCHAR2,
                                  wallet_alias       VARCHAR2,
                                  wallet_path        VARCHAR2);
 
  PROCEDURE revoke_network_acl_ace(catalog_user_name  IN VARCHAR2,
                                   wallet_alias       IN VARCHAR2,
                                   wallet_path        IN VARCHAR2);
  
  PROCEDURE delete_replication_server_int(p_rep_server_name IN VARCHAR2,
                                          p_force IN BOOLEAN DEFAULT FALSE);
  
  PROCEDURE remove_rep_from_prot_int (p_replication_server_name IN VARCHAR2,
                                      p_protection_policy_name IN VARCHAR2,
                                      do_commit   IN BOOLEAN DEFAULT TRUE);
 
  PROCEDURE delete_sbt_job_template_int(template_name IN VARCHAR2,
                                        do_commit     IN BOOLEAN DEFAULT TRUE);
  
  PROCEDURE ctrl_c_check(check_what IN NUMBER);
  
  FUNCTION is_ba_running RETURN BOOLEAN;
  
  PROCEDURE create_containers (
   p_slkey     IN  NUMBER,
   p_create    IN  BOOLEAN,
   p_reformat  IN  BOOLEAN DEFAULT FALSE);
 
  FUNCTION parse_dests (p_storage_dests IN VARCHAR2,
                        p_storage_for_poll IN BOOLEAN DEFAULT FALSE
                       ) RETURN destList_t;
  
  PROCEDURE lock_api (p_op_type     IN NUMBER DEFAULT NULL,
                      p_routine     IN VARCHAR2 DEFAULT NULL,
                      p_dbgnotes    IN VARCHAR2 DEFAULT NULL);
 
  PROCEDURE unlock_api (p_routine     IN VARCHAR2 DEFAULT NULL,
                        p_dbgnotes    IN VARCHAR2 DEFAULT NULL,
                        p_the_num     IN NUMBER DEFAULT 0,
                        p_results     IN BOOLEAN DEFAULT TRUE,
                        p_docommit    IN BOOLEAN DEFAULT FALSE);
 
  PROCEDURE upsert_config_parm(p_name  VARCHAR2,
                               p_value VARCHAR2);
 
  FUNCTION is_rep_server(name IN VARCHAR2) RETURN BOOLEAN;
  FUNCTION is_sysgen_obj(name IN VARCHAR2) RETURN BOOLEAN;
  
  PROCEDURE remove_rep_tasks(p_db_key IN NUMBER, p_template in VARCHAR2);
 
  PROCEDURE delete_replicated_backups(p_db_key      IN NUMBER,
                                      p_sbt_lib_key IN NUMBER,
                                      p_force_del   IN BOOLEAN DEFAULT FALSE);
 
  PROCEDURE revoke_db_access_int (p_username IN VARCHAR2,
                                  p_db_unique_name IN VARCHAR2);
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
FUNCTION numstring_to_num (p_numstr IN VARCHAR2,
                           p_allow0 IN BOOLEAN DEFAULT FALSE
                          ) RETURN NUMBER IS
  OneK      NUMBER := 1024;         -- Kilobyte
  OneM      NUMBER := OneK * 1024;  -- Megabyte
  OneG      NUMBER := OneM * 1024;  -- Gigabyte
  OneT      NUMBER := OneG * 1024;  -- Terabyte
  OneP      NUMBER := OneT * 1024;  -- Petabyte
  OneE      NUMBER := OneP * 1024;  -- Exabyte
  OneZ      NUMBER := OneE * 1024;  -- Zetabyte
  OneY      NUMBER := OneZ * 1024;  -- Yottabyte
  sizeunit  CHAR;
  newsize   NUMBER;
  space     NUMBER;   -- Return value in bytes
 
BEGIN
--
--
 
--
  IF (p_numstr IS NULL) THEN
    RAISE INVALID_SIZENUMBER;
  END IF;
 
  sizeunit := upper(substr(p_numstr, -1, 1));
  newsize := to_number(substr(p_numstr, 1, length(p_numstr) - 1));
  CASE sizeunit
    WHEN 'K' THEN
      space := newsize * OneK;
    WHEN 'M' THEN
      space := newsize * OneM;
    WHEN 'G' THEN
      space := newsize * OneG;
    WHEN 'T' THEN
      space := newsize * OneT;
    WHEN 'P' THEN
      space := newsize * oneP;
    WHEN 'E' THEN
      space := newsize * oneE;
    WHEN 'Z' THEN
      space := newsize * OneZ;
    WHEN 'Y' THEN
      space := newsize * OneY;
  ELSE
--
    space := to_number(p_numstr);
  END CASE;
 
  IF space=0 AND NOT p_allow0 THEN
    RAISE INVALID_SIZENUMBER;
  END IF;
 
  RETURN space;
END numstring_to_num;
--
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
FUNCTION item_not_found (p_obj_name IN VARCHAR2,
                         p_obj_type IN VARCHAR2) RETURN VARCHAR2 IS
BEGIN
  RETURN dbms_ra_int.item_not_foundi(p_obj_name => p_obj_name,
                                     p_obj_type => p_obj_type);
END item_not_found;
--
 
--
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE am_trace (p_message IN VARCHAR2) IS
BEGIN
--
  dbms_ra_int.am_tracei(p_message);
END am_trace;
--
 
--
--
--
--
--
--
--
--
--
FUNCTION pparm (p_value IN VARCHAR2) RETURN VARCHAR2
IS
BEGIN
  RETURN dbms_ra_int.pparmi(p_value);
END pparm;
 
FUNCTION pparm (p_value IN NUMBER) RETURN VARCHAR2
IS
BEGIN
  RETURN dbms_ra_int.pparmi(p_value);
END pparm;
 
FUNCTION pparm (p_value IN BOOLEAN) RETURN VARCHAR2
IS
BEGIN
  RETURN dbms_ra_int.pparmi(p_value);
END pparm;
--
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
 
FUNCTION b_p (p_varname IN VARCHAR2,
              p_strval  IN VARCHAR2 DEFAULT NULL,
              p_first   IN BOOLEAN DEFAULT FALSE,
              p_last    IN BOOLEAN DEFAULT FALSE) RETURN VARCHAR2
IS
BEGIN
  RETURN dbms_ra_int.b_p_i(p_varname   => p_varname,
                           p_strval    => p_strval,
                           p_first     => p_first,
                           p_last      => p_last);
END b_p;
--
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
FUNCTION b_p (p_varname IN VARCHAR2,
              p_numval  IN NUMBER DEFAULT NULL,
              p_first   IN BOOLEAN DEFAULT FALSE,
              p_last    IN BOOLEAN DEFAULT FALSE) RETURN VARCHAR2
IS
BEGIN
  RETURN dbms_ra_int.b_p_i(p_varname   => p_varname,
                           p_numval    => p_numval,
                           p_first     => p_first,
                           p_last      => p_last);
END b_p;
--
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
FUNCTION b_p (p_varname IN VARCHAR2,
              p_boolval IN BOOLEAN DEFAULT NULL,
              p_first   IN BOOLEAN DEFAULT FALSE,
              p_last    IN BOOLEAN DEFAULT FALSE) RETURN VARCHAR2
IS
BEGIN
  RETURN dbms_ra_int.b_p_i(p_varname   => p_varname,
                           p_boolval   => p_boolval,
                           p_first     => p_first,
                           p_last      => p_last);
END b_p;
--
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
FUNCTION b_p (p_varname  IN VARCHAR2,
              p_intval   IN DSINTERVAL_UNCONSTRAINED DEFAULT NULL,
              p_first    IN BOOLEAN DEFAULT FALSE,
              p_last     IN BOOLEAN DEFAULT FALSE) RETURN VARCHAR2
IS
BEGIN
  
  RETURN dbms_ra_int.b_p_i(p_varname   => p_varname,
                           p_intval    => p_intval,
                           p_first     => p_first,
                           p_last      => p_last);
END b_p;
--
 
--
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE upsert_config_parm(p_name  VARCHAR2,
                             p_value VARCHAR2)
IS
BEGIN
--
  IF p_name = '_def_sl_size' THEN
    sys.dbms_sys_error.raise_system_error(E_INTERNAL_ERROR_NUM,
                                          '_def_sl_size is no longer supported',
                                          FALSE);
  END IF;
 
  MERGE
    INTO config
    USING (SELECT p_name sq_name, p_value sq_value FROM dual)
    ON (sq_name=name)
    WHEN matched THEN
        UPDATE
        SET value=sq_value
    WHEN NOT matched THEN
        INSERT
        VALUES(sq_name, sq_value);
 
--
--
  dbms_ra_scheduler.load_config;
 
  COMMIT;
END;
--
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE lock_api (p_op_type     IN NUMBER DEFAULT NULL,
                    p_routine     IN VARCHAR2 DEFAULT NULL,
                    p_dbgnotes    IN VARCHAR2 DEFAULT NULL)
IS
BEGIN
  dbms_ra_int.lock_api_int(p_op_type, p_routine, p_dbgnotes);
END lock_api;
--
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE unlock_api (p_routine     IN VARCHAR2 DEFAULT NULL,
                      p_dbgnotes    IN VARCHAR2 DEFAULT NULL,
                      p_the_num     IN NUMBER DEFAULT 0,
                      p_results     IN BOOLEAN DEFAULT TRUE,
                      p_docommit    IN BOOLEAN DEFAULT FALSE)
IS
BEGIN
  dbms_ra_int.unlock_api_int(p_routine,
                             p_dbgnotes,
                             p_the_num,
                             p_results,
                             p_docommit);
END unlock_api;
--
 
--
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE config(p_name  VARCHAR2,
                 p_value VARCHAR2)
IS
  l_the             NUMBER;
 
  KBRSTRC_TO_DISK    CONSTANT NUMBER := 2; 
  TRACING_ACTIVE_NUM CONSTANT NUMBER := -64748;
 
  l_session_rowids  dbms_sql.urowid_table;
  l_name            VARCHAR2(100) := LOWER(p_name);
 
BEGIN
  l_the := dbms_ra_scheduler.add_to_task_history_table (
                         task_type   => dbms_ra_scheduler.TASK_API_CONFIG,
                         param     => 'config' ||
                          b_p('p_name',     p_name, p_first=>TRUE ) ||
                          b_p('p_value',    p_value, p_last=>TRUE));
 
--
  BEGIN
    CASE
      WHEN l_name = 'network_chunksize' THEN
        IF TO_NUMBER (p_value) < 1024*1024 THEN 
          RAISE INVALID_VAL;
        END IF;
      WHEN l_name IN ('optimize_chunks_days' 
                    , 'validate_db_days' 
                    , 'check_files_days'
                    , 'crosscheck_db_days') THEN
        IF TO_NUMBER (p_value) < 1/24/60/60 THEN 
          RAISE INVALID_VAL;
        END IF;
      WHEN l_name = 'percent_late_for_warning' THEN
        IF TO_NUMBER (p_value) < 0 THEN
          RAISE INVALID_VAL;
        END IF;
      ELSE NULL;
    END CASE;
  EXCEPTION
    WHEN INVALID_VAL THEN
      rollback;
      sys.dbms_sys_error.raise_system_error(INVALID_VAL_NUM,
                                            'value',
                                            FALSE);
    WHEN OTHERS THEN
      rollback; 
      sys.dbms_sys_error.raise_system_error(INVALID_VAL_NUM,
                                            'value',
                                            TRUE);
 END;
 
--
  upsert_config_parm(l_name, UPPER(p_value));
 
  IF l_name = '_debug_flags' THEN
    sys.kbrsi_icd.rsSetDebugFlags(p_value);
    IF BITAND(NVL(TO_NUMBER(p_value),0), KBRSTRC_TO_DISK) <> 0 THEN
      dbms_ra_scheduler.log_error (
                p_errno      => TRACING_ACTIVE_NUM,
                p_param1     => '_debug_flags',
                p_component  => 'API',
                p_severity   => dbms_ra_scheduler.severity_warning,
                p_param_char => '_debug_flags');
    ELSE
      dbms_ra_scheduler.fix_error (
                p_error_num  => TRACING_ACTIVE_NUM,
                p_param_char => '_debug_flags');
    END IF;
  END IF;
 
  IF l_name = '_debug_when' THEN
    IF TO_NUMBER(p_value) <> 0 THEN
      dbms_ra_scheduler.log_error (
                p_errno      => TRACING_ACTIVE_NUM,
                p_param1     => '_debug_when',
                p_component  => 'API',
                p_severity   => dbms_ra_scheduler.severity_warning,
                p_param_char => '_debug_when');
    ELSE
      dbms_ra_scheduler.fix_error (
                p_error_num  => TRACING_ACTIVE_NUM,
                p_param_char => '_debug_when');
    END IF;
  END IF;
 
  IF l_name = '_stall_when' AND UPPER(p_value) = 'OFF' THEN
    dbms_ra_scheduler.release_blocked_tasks(
                                      dbms_ra_scheduler.STALL_PSEUDO_TASK);
  END IF;
 
--
--
  SELECT ROWID BULK COLLECT INTO l_session_rowids
    FROM sessions
   ORDER BY ROWID;
  FORALL i IN l_session_rowids.FIRST..l_session_rowids.LAST
    UPDATE sessions 
      SET last_config_change = SYSTIMESTAMP
      WHERE ROWID = l_session_rowids(i);
  COMMIT;
 
--
  dbms_ra_scheduler.enqueue_timer_reload_config;
 
  dbms_ra_scheduler.update_task_history_entry(task_id     => l_the, 
                                              param_char2 => 'SUCCESS',
                                              do_commit   => TRUE);
EXCEPTION
  WHEN OTHERS THEN
    rollback;
    dbms_ra_scheduler.update_task_history_entry(task_id     => l_the, 
                                                param_char2 => 'FAIL',
                                                do_commit   => TRUE);
    RAISE;
 
END;
--
 
 
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE reset_error (incident# NUMBER)
IS
BEGIN
  dbms_ra_scheduler.reset_error(p_incident# => incident#);
END;
--
 
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE move_commit (p_slkey IN NUMBER,
                       p_protkey IN NUMBER DEFAULT NULL,
                       p_dbkey IN NUMBER DEFAULT NULL) IS
  l_task_rec       task%ROWTYPE;
  l_interrupt      NUMBER;
BEGIN
--
  SELECT COUNT(*) INTO l_interrupt
  FROM odb d, prot p
  WHERE p.prot_key = d.future_prot_key
      AND ((p.sl_key = p_slkey AND p_protkey IS NULL AND p_dbkey IS NULL) OR
           p.prot_key = p_protkey OR d.db_key = p_dbkey)
      AND d.sl_key <> p.sl_key
      AND d.move_phase > dbms_ra_scheduler.MOVE_PHASE_PEND;
 
--
--
--
  IF l_interrupt > 0 OR p_protkey IS NOT NULL OR p_dbkey IS NOT NULL THEN
      l_task_rec.task_type     := dbms_ra_scheduler.TASK_MOVE_ALL_DB;
      l_task_rec.sl_key        := p_slkey;
      l_task_rec.flags         := 0;
      dbms_ra_scheduler.new_task(l_task_rec, FALSE);
  END IF;
 
--
  IF l_interrupt > 0 THEN
    dbms_ra_scheduler.interrupt_tasks(
      p_interrupt => dbms_ra_scheduler.INTERRUPT_FOR_MOVE
    , p_task_id   => l_task_rec.task_id
    );
  ELSE
    COMMIT;
  END IF;
END;
--
 
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE repair_storage_location (
     storage_location_name    IN VARCHAR2,
     repair_type              IN VARCHAR2)
IS
  l_the             NUMBER;
  l_count           NUMBER;
  l_storage_location_name   DBMS_ID;
  l_sl_key          NUMBER;
  l_state           sl.sl_state%TYPE;
  l_return          BINARY_INTEGER;
  l_amrvkey         BINARY_INTEGER;
 
  no_container_group EXCEPTION;
  PRAGMA EXCEPTION_INIT(no_container_group, -45279);
BEGIN
  l_the := dbms_ra_scheduler.add_to_task_history_table (
                         task_type   => dbms_ra_scheduler.TASK_API_REPAIR_SL,
                         param     => 'repair_storage_location' ||
                          b_p('storage_location_name',storage_location_name, 
                                p_first=>TRUE) ||
                          b_p('repair_type', repair_type, p_last=>TRUE));
 
--
--
--
  SELECT COUNT(*) INTO l_count
    FROM config
   WHERE config.name = '_recovery_appliance_state'
     AND config.value = 'ON';
 
  IF l_count <> 0 THEN
    sys.dbms_sys_error.raise_system_error(E_INTERNAL_ERROR_NUM,
                                          'recovery appliance is running',
                                          FALSE);
  END IF;
 
 
  dbms_ra_int.canonicalize(storage_location_name,
                            l_storage_location_name, 
                            128);
 
  BEGIN
    SELECT sl_key, NVL(sl_state,' ') INTO l_sl_key, l_state
      FROM sl
     WHERE sl_name = l_storage_location_name;
  EXCEPTION
    WHEN NO_DATA_FOUND THEN
      am_trace ('repair_storage_location: ' || item_not_found(
                                                  l_storage_location_name,
                                                  'storage location'));
      sys.dbms_sys_error.raise_system_error(OBJ_NOT_FOUND_NUM,
                                            l_storage_location_name,
                                            'storage location',
                                            FALSE);
  END;
 
  CASE UPPER(repair_type)
--
    WHEN 'IGNORE_MISSING_DATA' THEN
      IF l_state = 'E' THEN
        UPDATE sl SET sl_state = 'I'
          WHERE sl_key = l_sl_key;
        COMMIT;
      ELSE
        am_trace ('repair_storage_location:  bad repair value');
        sys.dbms_sys_error.raise_system_error(INVALID_VAL_NUM,
                                              'IGNORE_MISSING_DATA',
                                              FALSE);
      END IF;
 
--
    WHEN 'REFORMAT' THEN
--
      IF l_state != 'F' THEN
        am_trace ('repair_storage_location:  bad repair value');
        sys.dbms_sys_error.raise_system_error(INVALID_VAL_NUM,
                                              'REFORMAT',
                                              FALSE);
      END IF;
 
--
--
      BEGIN
        am_trace ('repair_storage_location:  drop container');
        sys.kbrsi_icd.drop_container_group(gname => l_storage_location_name,
                                           force => 1,
                                           keep_container => 0);
      EXCEPTION
         WHEN no_container_group THEN
           am_trace ('repair_storage_location ignored: ' || SQLERRM);
      END;  
 
--
      FOR i IN (SELECT dest
                  FROM storage_dests
                 WHERE sl_key = l_sl_key) LOOP
        am_trace ('repair_storage_location:  remove container -- ' || i.dest);
        IF  sys.kbrsi_icd.remove_containers (pathlist => i.dest,
                                             gname => l_storage_location_name,
                                             amrvkey => l_amrvkey) = 0 THEN
          sys.dbms_sys_error.raise_system_error(
                        dbms_ra_scheduler.e_sl_rebuild_fatal_num,
                        l_storage_location_name,
                        l_amrvkey);
        END IF;
      END LOOP;
 
--
--
      UPDATE storage_dests SET cursize = 0, needsize = 0
        WHERE sl_key = l_sl_key;
 
--
      am_trace ('repair_storage_location:  recreate container group');
      create_containers(l_sl_key, TRUE, TRUE);
 
--
      UPDATE sl SET sl_state = NULL
        WHERE sl_key = l_sl_key;
      COMMIT;
 
    ELSE sys.dbms_sys_error.raise_system_error(INVALID_VAL_NUM,
                                               repair_type,
                                               FALSE);
  END CASE;
 
  dbms_ra_scheduler.update_task_history_entry(task_id     => l_the, 
                                              param_char2 => 'SUCCESS',
                                              do_commit   => TRUE);
EXCEPTION
  WHEN OTHERS THEN
    dbms_ra_scheduler.update_task_history_entry(task_id     => l_the, 
                                                param_char2 => 'FAIL',
                                                do_commit   => TRUE);
    RAISE;
 
END;
--
 
 
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
FUNCTION estimate_space (
     db_unique_name         IN VARCHAR2,
     target_window          IN DSINTERVAL_UNCONSTRAINED) RETURN NUMBER
IS
  l_db_unique_name node.db_unique_name%TYPE := db_unique_name;
  l_unregistered_db NUMBER;
  l_db_key          NUMBER;
  l_total_allocation NUMBER;
  l_footprint       NUMBER;
  l_current_window  NUMBER;
  l_bdf1count       NUMBER;
  l_min_alloc       NUMBER;
  l_target_days     NUMBER;
  l_ratio           NUMBER;
  l_space           NUMBER;
BEGIN
  
  SELECT COUNT(*) INTO l_unregistered_db FROM unreg_database
    WHERE db_unique_name = l_db_unique_name;
 
--
  IF l_unregistered_db > 0 THEN
    RETURN NULL;
  END IF;
 
--
--
--
  BEGIN
    SELECT db_key, total_allocation, sl_min_alloc,
           footprint, 
           odbsysdate-recwindowstart, bdf1count
      INTO l_db_key, l_total_allocation, l_min_alloc,
           l_footprint, l_current_window, l_bdf1count 
      FROM (SELECT db_key
               , CAST((SYSTIMESTAMP AT TIME ZONE TO_CHAR(db_timezone)) AS DATE)
                                                                     odbsysdate
              FROM node
             WHERE db_unique_name = l_db_unique_name
               AND ROWNUM = 1)
           JOIN odb USING (db_key)
           LEFT OUTER JOIN rai_recovery_window_space USING (db_key)
      WHERE db_unique_name = l_db_unique_name
--
        AND db_state IS NULL;
  EXCEPTION
    WHEN no_data_found THEN
      am_trace ('estimate_space: ' || item_not_found(db_unique_name,
                                                     'db unique name'));
      sys.dbms_sys_error.raise_system_error(OBJ_NOT_FOUND_NUM,
                                            l_db_unique_name,
                                            'db unique name',
                                            FALSE);
  END;
 
--
--
--
--
  IF  target_window IS NULL
   OR l_footprint IS NULL
   OR NVL(l_current_window, 0) <= 0
   OR NVL(l_bdf1count, 0) < 3
  THEN
    RETURN NULL;
  END IF;
 
--
--
--
--
  l_target_days := TO_NUMBER(EXTRACT(DAY    FROM target_window))
                 + TO_NUMBER(EXTRACT(HOUR   FROM target_window))/(24)
                 + TO_NUMBER(EXTRACT(MINUTE FROM target_window))/(24*60);
 
--
  l_ratio := l_target_days / l_current_window;
 
--
--
--
  l_space := (l_total_allocation - l_footprint) * l_ratio;
  l_space := l_space + l_footprint;
 
--
  l_space :=  CEIL(l_space/l_min_alloc) * l_min_alloc;
 
--
  l_space := l_space/(1024*1024*1024);
 
  RETURN l_space;
END;
--
 
 
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE dump (do_dpdump BOOLEAN DEFAULT FALSE)
IS
BEGIN
  dbms_ra_dump.dumper('API', FALSE, do_dpdump);
END;
--
 
 
 
--
--
--
--
--
--
--
--
--
--
--
--
 
FUNCTION canStartAVMServices
RETURN BOOLEAN
IS
 l_is_avm          VARCHAR2(16);
BEGIN
 
  SELECT UPPER(TRIM(' ' FROM NVL(is_avm,'FALSE')))
        INTO l_is_avm
        FROM XMLTable('/ORACLE_CLUSTER/PAGE0'
             PASSING XMLTYPE(
                       BFILENAME('DBM_XMLDIR', 'databasemachine.xml')
                     , NLS_CHARSET_ID('AL32UTF8')
                     )
             COLUMNS is_avm VARCHAR2(32) PATH 'BACKUP_APPLIANCE'
            );
  RETURN (l_is_avm = 'TRUE');
EXCEPTION
  WHEN OTHERS THEN
  RETURN FALSE;
END canStartAVMServices;
 
--
 
 
--
--
--
--
--
PROCEDURE startup IS
BEGIN
--
--
--
--
--
  dbms_ra.startup_recovery_appliance;
END startup;
PROCEDURE startup_recovery_appliance IS
  l_the             NUMBER;
 
BEGIN 
  
--
  sys.kbrsi_icd.ba_enabled;
 
  IF dbms_ra.canStartAVMServices = FALSE THEN
    sys.dbms_sys_error.raise_system_error(NOT_RA_NUM);
  END IF;
 
  l_the := dbms_ra_scheduler.add_to_task_history_table (
                           task_type => dbms_ra_scheduler.TASK_API_STARTUP,
                           param     => 'startup_recovery_appliance()');
  dbms_ra_scheduler.init (p_repair => TRUE);
  dbms_ra_scheduler.update_task_history_entry(task_id     => l_the, 
                                              param_char2 => 'SUCCESS',
                                              do_commit   => TRUE);
EXCEPTION
  WHEN OTHERS THEN
    dbms_ra_scheduler.update_task_history_entry(task_id     => l_the, 
                                                param_char2 => 'FAIL',
                                                do_commit   => TRUE);
    RAISE;
                                              
END startup_recovery_appliance;
--
 
 
--
--
--
--
--
--
PROCEDURE shutdown IS
BEGIN
--
--
--
--
--
  dbms_ra.shutdown_recovery_appliance;
END shutdown;
PROCEDURE shutdown_recovery_appliance IS
  l_the             NUMBER;
  l_jobname         sessions.job_name%type;
  l_action          VARCHAR2(200);
  l_value           VARCHAR2(10);
 
BEGIN
--
  dbms_ra_scheduler.assert_owner;
 
  l_the := dbms_ra_scheduler.add_to_task_history_table (
                           task_type => dbms_ra_scheduler.TASK_API_SHUTDOWN,
                           param     => 'shutdown_recovery_appliance()');
 
  dbms_ra_scheduler.log_error(
                p_errno         => dbms_ra_scheduler.e_shutting_down_num,
                P_keep_stack    => FALSE,
                p_component     => 'SHUTDOWN',
                p_severity      => dbms_ra_scheduler.severity_warning);
 
--
--
--
--
  l_jobname := 'RA$SHUTDOWN_' || rai_sq.nextval;
  l_action := 'dbms_ra_scheduler.stop (p_quiesce_first => TRUE);';
 
  am_trace('shutdown:  spawning ' || l_jobname || ' for ' || l_action);
  dbms_scheduler.create_job(
             job_name   => l_jobname
            ,job_type   => 'plsql_block'
            ,job_action => l_action
            ,enabled    => TRUE
            ,auto_drop  => TRUE);
 
--
  dbms_ra_int.wait_for_job (l_jobname, 1);
 
  SELECT DECODE(value, 'OFF', 'SUCCESS', 'FAIL') INTO l_value
    FROM config
    WHERE name = '_recovery_appliance_state';
 
  dbms_ra_scheduler.update_task_history_entry(task_id     => l_the, 
                                               param_char2 => l_value,
                                               do_commit   => TRUE);
EXCEPTION
  WHEN dbms_ra_scheduler.e_bad_user THEN RAISE;
 
  WHEN OTHERS THEN
    dbms_ra_scheduler.update_task_history_entry(task_id     => l_the, 
                                                param_char2 => 'FAIL',
                                                do_commit   => TRUE);
    RAISE;
  
END shutdown_recovery_appliance;
--
 
 
--
--
--
--
--
--
PROCEDURE abort IS
BEGIN
--
--
--
--
--
  dbms_ra.abort_recovery_appliance;
END abort;
PROCEDURE abort_recovery_appliance IS
  l_the             NUMBER;
  l_value           VARCHAR2(10);
 
BEGIN 
--
  dbms_ra_scheduler.assert_owner;
 
  l_the := dbms_ra_scheduler.add_to_task_history_table (
                            task_type => dbms_ra_scheduler.TASK_API_ABORT,
                            param     => 'abort_recovery_appliance()');
  dbms_ra_scheduler.log_error(
                p_errno         => dbms_ra_scheduler.e_shutting_down_num,
                P_keep_stack    => FALSE,
                p_component     => 'ABORT',
                p_severity      => dbms_ra_scheduler.severity_warning);
  dbms_ra_scheduler.stop (p_quiesce_first => FALSE);
 
  SELECT DECODE(value, 'OFF', 'SUCCESS', 'FAIL') INTO l_value
    FROM config
    WHERE name = '_recovery_appliance_state';
 
  dbms_ra_scheduler.update_task_history_entry(task_id     => l_the, 
                                              param_char2 => l_value,
                                              do_commit   => TRUE);
EXCEPTION
  WHEN dbms_ra_scheduler.e_bad_user THEN RAISE;
 
  WHEN OTHERS THEN
    dbms_ra_scheduler.update_task_history_entry(task_id     => l_the, 
                                                param_char2 => 'FAIL',
                                                do_commit   => TRUE);
    RAISE;
  
END abort_recovery_appliance;
--
 
--
--
--
--
--
PROCEDURE clean_old_uids IS
BEGIN
   delete from prvlg
      where user_id not in (select user_id from all_users);
 
--
--
END clean_old_uids;
--
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE grant_privilege_int (p_username         IN VARCHAR2,
                               p_db_unique_name   IN VARCHAR2,
                               p_privilege_type   IN VARCHAR2 DEFAULT NULL,
                               p_accesstype       IN VARCHAR2 DEFAULT NULL)
IS
  l_read_access     BOOLEAN := FALSE;
  l_write_access    BOOLEAN := FALSE;
  l_backup_op       BOOLEAN := FALSE;
  l_reconcile_op    BOOLEAN := FALSE;
  l_req_prvlg       NUMBER := 0;
  l_db_key          NUMBER := NULL;
  l_unregistered_db NUMBER := 0;
  l_db_unique_name  node.db_unique_name%TYPE := p_db_unique_name;
  l_user_id         NUMBER;
 
BEGIN
 
  clean_old_uids;
  
  SELECT COUNT (*) INTO l_unregistered_db FROM unreg_database
    WHERE db_unique_name = p_db_unique_name;
 
--
  IF l_unregistered_db = 0 THEN
    BEGIN
      SELECT db_key INTO l_db_key FROM node
        WHERE node.db_unique_name = p_db_unique_name
--
--
          AND NOT EXISTS (SELECT db_state
                            FROM odb
                           WHERE odb.db_key = node.db_key
                             AND db_state IS NOT NULL);
      l_db_unique_name := NULL;
      
    EXCEPTION
      WHEN NO_DATA_FOUND THEN
        RAISE OBJ_NOT_FOUND;
    END;
  END IF;
 
--
  BEGIN
     SELECT user_id INTO l_user_id
       FROM all_users u where u.username = p_username;
  EXCEPTION
     WHEN NO_DATA_FOUND THEN
        am_trace ('grant_privilege: user not found' || p_username);
        sys.dbms_sys_error.raise_system_error(USER_NOT_FOUND_NUM,
                                              p_username,
                                              FALSE);
  END;
 
--
  IF (p_privilege_type = 'BACKUP') THEN
    l_backup_op := TRUE;
  ELSIF (p_privilege_type = 'RECONCILE') THEN
    l_reconcile_op := TRUE;
  ELSIF (p_privilege_type IS NULL) THEN
    l_backup_op := TRUE;
    l_reconcile_op := TRUE;
  ELSE
    RAISE UNKNOWN_OPERATION_PRVLG;
  END IF;
 
  IF (p_accesstype = 'READ') THEN
    l_read_access := TRUE;
  ELSIF (p_accesstype = 'WRITE') THEN
    l_write_access := TRUE;
  ELSIF (p_accesstype IS NULL) THEN
    l_read_access  := TRUE;
    l_write_access := TRUE;
  ELSE
    RAISE UNKNOWN_OPERATION_PRVLG;
  END IF;
 
--
--
  IF (l_backup_op) THEN
     IF (l_read_access) THEN
        l_req_prvlg := l_req_prvlg + DBMS_RA_INT.BACKUP_READ;
     END IF;
     IF (l_write_access) THEN
        l_req_prvlg := l_req_prvlg + DBMS_RA_INT.BACKUP_WRITE;
     END IF;
  END IF;
 
  IF (l_reconcile_op) THEN
     IF (l_read_access) THEN
        l_req_prvlg := l_req_prvlg + DBMS_RA_INT.RECONCILE_READ;
     END IF;
     IF (l_write_access) THEN
        l_req_prvlg := l_req_prvlg + DBMS_RA_INT.RECONCILE_WRITE;
     END IF;
  END IF;
 
--
  MERGE
    INTO prvlg
    USING dual
    ON
    (
      user_id  = l_user_id AND
      ((db_key = l_db_key) OR
       (l_db_key is null AND db_key is null AND
        db_unique_name = l_db_unique_name)
      )
    )
    WHEN MATCHED THEN
        UPDATE
        SET type = (l_req_prvlg + type - bitand (l_req_prvlg, type))
    WHEN NOT MATCHED THEN
        INSERT VALUES (l_req_prvlg, l_db_key, l_user_id, l_db_unique_name);
 
  COMMIT;
 
EXCEPTION
  WHEN OBJ_NOT_FOUND THEN
    am_trace ('grant_privilege: ' || item_not_found(p_db_unique_name,
                                                    'db unique name'));
    sys.dbms_sys_error.raise_system_error(OBJ_NOT_FOUND_NUM,
                                          p_db_unique_name,
                                          'db unique name',
                                          FALSE);
  WHEN OTHERS THEN
    ROLLBACK;
    am_trace ('grant_privilege exception:'||p_db_unique_name || ',' || 
        p_username || ',' || p_privilege_type ||',' || p_accesstype ||
        ', err:' || SQLERRM);
    RAISE;
 
END grant_privilege_int;
--
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE revoke_privilege_int  (p_username        IN VARCHAR2,
                                 p_db_unique_name  IN VARCHAR2,
                                 p_privilege_type  IN VARCHAR2 DEFAULT NULL,
                                 p_accesstype      IN VARCHAR2 DEFAULT NULL)
IS
  l_read_access      BOOLEAN := FALSE;
  l_write_access     BOOLEAN := FALSE;
  l_backup_op        BOOLEAN := FALSE;
  l_reconcile_op     BOOLEAN := FALSE;
  l_req_prvlg        NUMBER := 0;
  l_has_prvlg        NUMBER := 0;
  l_db_key           NUMBER := NULL;
  l_unregistered_db  NUMBER := 0;
  l_db_unique_name   node.db_unique_name%TYPE := p_db_unique_name;
  l_user_id          NUMBER;
 
BEGIN
  clean_old_uids;
 
  SELECT COUNT (*) INTO l_unregistered_db FROM unreg_database
    WHERE db_unique_name = p_db_unique_name;
 
--
  IF l_unregistered_db = 0 THEN
    BEGIN
      SELECT db_key INTO l_db_key FROM node
        WHERE node.db_unique_name = p_db_unique_name
--
--
          AND NOT EXISTS (SELECT db_state
                            FROM odb
                           WHERE odb.db_key = node.db_key
                             AND db_state IS NOT NULL);
      l_db_unique_name := NULL;
    EXCEPTION
      WHEN NO_DATA_FOUND THEN
        RAISE OBJ_NOT_FOUND;
    END;
  END IF;
 
--
  BEGIN
     SELECT user_id INTO l_user_id
       FROM all_users u where u.username = p_username;
  EXCEPTION
     WHEN NO_DATA_FOUND THEN
        am_trace ('revoke_privilege: user not found' || p_username);
        sys.dbms_sys_error.raise_system_error(USER_NOT_FOUND_NUM,
                                              p_username,
                                              FALSE);
  END;
  
--
  IF (p_privilege_type = 'BACKUP') THEN
    l_backup_op := TRUE;
  ELSIF (p_privilege_type = 'RECONCILE') THEN
    l_reconcile_op := TRUE;
  ELSIF (p_privilege_type IS NULL) THEN
    l_backup_op := TRUE;
    l_reconcile_op := TRUE;
  ELSE
    RAISE UNKNOWN_OPERATION_PRVLG;
  END IF;
 
  IF (p_accesstype = 'READ') THEN
    l_read_access := TRUE;
  ELSIF (p_accesstype = 'WRITE') THEN
    l_write_access := TRUE;
  ELSIF (p_accesstype IS NULL) THEN
    l_read_access  := TRUE;
    l_write_access := TRUE;
  ELSE
    RAISE UNKNOWN_OPERATION_PRVLG;
  END IF;
 
--
  IF (l_backup_op) THEN
     IF (l_read_access) THEN
        l_req_prvlg := l_req_prvlg + DBMS_RA_INT.BACKUP_READ;
     END IF;
     IF (l_write_access) THEN
        l_req_prvlg := l_req_prvlg + DBMS_RA_INT.BACKUP_WRITE;
     END IF;
  END IF;
 
  IF (l_reconcile_op) THEN
     IF (l_read_access) THEN
        l_req_prvlg := l_req_prvlg + DBMS_RA_INT.RECONCILE_READ;
     END IF;        
     IF (l_write_access) THEN
        l_req_prvlg := l_req_prvlg + DBMS_RA_INT.RECONCILE_WRITE;
     END IF;
  END IF;
 
  MERGE INTO prvlg
    USING dual
    ON
    (
      user_id = l_user_id AND
      ((db_key = l_db_key) OR
       (l_db_key is null AND
        db_key is null AND
        db_unique_name = l_db_unique_name)
      )
    )
    WHEN MATCHED THEN
      UPDATE
        SET type = (type - bitand(l_req_prvlg, type));
 
--
  DELETE prvlg WHERE type = 0 AND
    (
      user_id = l_user_id AND
      ((db_key = l_db_key) OR
       (l_db_key is null AND
        db_key is null AND
        db_unique_name = l_db_unique_name)
      )
    );
 
  COMMIT;
 
EXCEPTION
  WHEN OBJ_NOT_FOUND THEN
    am_trace ('revoke_privilege: ' || item_not_found(p_db_unique_name,
                                                     'db unique name'));
    sys.dbms_sys_error.raise_system_error(OBJ_NOT_FOUND_NUM,
                                            p_db_unique_name,
                                            'db unique name',
                                            FALSE);
  WHEN OTHERS THEN
    ROLLBACK;
    am_trace ('revoke_privilege exception:' || p_db_unique_name|| ',' || 
              p_username || ',' || p_privilege_type     || ',' || 
              p_accesstype || ', err:' || SQLERRM);
 
    RAISE;
 
END revoke_privilege_int;
--
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE manage_privilege_int  (p_db_unique_name   IN VARCHAR2,
                                 p_operation        IN NUMBER,
                                 p_privilege_type   IN NUMBER DEFAULT NULL,
                                 p_access_type      IN NUMBER DEFAULT NULL,
                                 p_username         IN VARCHAR2 DEFAULT NULL)
IS
  l_privilege_type  VARCHAR2(32);
  l_accesstype      VARCHAR2(32);
 
BEGIN
 
--
  IF p_privilege_type = AM_SEC_PRIVTYPE_BACKUP THEN
    l_privilege_type := 'BACKUP';
  ELSIF p_privilege_type = AM_SEC_PRIVTYPE_RECONCILE THEN
    l_privilege_type := 'RECONCILE';
  ELSIF p_privilege_type = AM_SEC_PRIVTYPE_ALL THEN
    l_privilege_type := NULL;
  ELSIF p_privilege_type IS NULL THEN
    l_privilege_type := NULL;
  ELSE
    RAISE UNKNOWN_MANAGE_PRVLG_PARAM;
  END IF;
 
--
  IF p_access_type = AM_SEC_ACCESSTYPE_READ THEN
    l_accesstype := 'READ';
  ELSIF p_access_type = AM_SEC_ACCESSTYPE_WRITE THEN
    l_accesstype := 'WRITE';
  ELSIF p_access_type = AM_SEC_ACCESSTYPE_ALL THEN
    l_accesstype := NULL;
  ELSIF p_access_type IS NULL THEN
    l_accesstype := NULL;
  ELSE
    RAISE UNKNOWN_MANAGE_PRVLG_PARAM;
  END IF;
 
--
  IF p_operation = AM_SEC_OPERATION_GRANT THEN
    grant_privilege_int(p_username,
                        p_db_unique_name,
                        l_privilege_type,
                        l_accesstype);
  ELSIF p_operation = AM_SEC_OPERATION_REVOKE THEN
    revoke_privilege_int(p_username,
                         p_db_unique_name,
                         l_privilege_type,
                         l_accesstype);
  ELSE
    RAISE UNKNOWN_MANAGE_PRVLG_PARAM;
  END IF;
  
EXCEPTION
  WHEN OTHERS THEN
    ROLLBACK;
    am_trace ('manage_privilege exception: '|| p_db_unique_name || ',' || 
              p_username || ',' || p_operation   || ',' || p_privilege_type ||
              ',' || p_access_type || ', err:' || SQLERRM);
    RAISE;
 
END manage_privilege_int;
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE fake_sl_sizing (p_diskgroup   IN  VARCHAR2) IS
 
PRAGMA AUTONOMOUS_TRANSACTION;
 
  l_count           NUMBER;
  l_totalspace      NUMBER;
  l_asm_group       NUMBER;
  l_redundancy      NUMBER;
  l_disksize        NUMBER;
  l_sparedisks      NUMBER;
 
BEGIN
--
  SELECT COUNT(*) INTO l_count
    FROM sl_sizing
   WHERE disk_group = p_diskgroup;
 
  IF l_count <> 0 THEN 
    RETURN;
  END IF;
 
--
  BEGIN
    SELECT group_number, total_mb * ONEMEG,
           CASE type
             WHEN 'NORMAL' THEN 2
             WHEN 'HIGH'   THEN 3
             WHEN 'EXTERN' THEN 1
             ELSE 0
           END
      INTO l_asm_group, l_totalspace, l_redundancy
      FROM sys.v_$asm_diskgroup
     WHERE name = p_diskgroup;
 
  EXCEPTION
    WHEN no_data_found THEN
      am_trace('fake_sl_sizing: ' || item_not_found(p_diskgroup,
                                                    'storage destination')); 
      RETURN;
  END;
 
--
  BEGIN
    SELECT MAX(total_mb) * ONEMEG INTO l_disksize
      FROM sys.v_$asm_disk
     WHERE group_number = l_asm_group;
  EXCEPTION
    WHEN no_data_found THEN
      am_trace('fake_sl_sizing: ' ||
                  item_not_found(p_diskgroup,
                                 'storage destination smallest disk'));
      RETURN;
  END;
 
--
  SELECT NVL(MAX(TO_NUMBER(value)), 2)
    INTO l_sparedisks
    FROM config
   WHERE name = '_spare_asm_disks';
 
  am_trace('fake_sl_sizing: totalspace=' || TO_CHAR(l_totalspace) ||
                         '; redundancy=' || TO_CHAR(l_redundancy) ||
                         '; disksize=' || TO_CHAR(l_disksize) ||
                         '; sparedisks=' || TO_CHAR(l_sparedisks));
  
--
--
--
--
--
--
  IF l_redundancy > 1 THEN
    l_totalspace := 
      (l_totalspace - (l_sparedisks * l_disksize)) / l_redundancy;
  ELSE
--
    l_totalspace := .85 * l_totalspace;
  END IF;
 
--
  am_trace('fake_sl_sizing: usable totalspace before FLOOR 0=' ||
                                 TO_CHAR(l_totalspace));
  l_totalspace := GREATEST(l_totalspace, 0); 
    am_trace('fake_sl_sizing: usable totalspace=' || TO_CHAR(l_totalspace));
 
--
  INSERT INTO sl_sizing (disk_group, init_ok, sl_space)
    VALUES (p_diskgroup, 'Y', l_totalspace);
  COMMIT; 
END fake_sl_sizing;
 
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE create_containers (p_slkey     IN  NUMBER,
                             p_create    IN  BOOLEAN,
                             p_reformat  IN  BOOLEAN DEFAULT FALSE)
IS
  l_min_alloc       NUMBER;
  l_invalid_val     VARCHAR2(128);
  l_net_chunksize   NUMBER;
  l_cg_name         sl.sl_name%TYPE;
  l_newcg           BOOLEAN := FALSE;
  l_params          VARCHAR2(100);
  l_cont_size       NUMBER;
  l_this_cont_size  NUMBER;
  l_au_size         NUMBER := NULL;
  l_asm_group       NUMBER;
  l_asm_group_name  DBMS_ID;
  l_init_ok         VARCHAR2(1);
  l_max_diskgroup   NUMBER;
  l_used_diskgroup  NUMBER;    
  l_freespace       NUMBER;
  l_needsize        NUMBER;
  l_asm_count       PLS_INTEGER := 0;
  l_nonasm_count    PLS_INTEGER := 0;
  l_def_cont_size   VARCHAR2(50);
  l_size            NUMBER;
  l_new_cursize     NUMBER;
  l_newcontainer    BOOLEAN := FALSE;
  TWO_TERABYTE      CONSTANT NUMBER := 2*ONEMEG*1024*1024;
 
BEGIN
  am_trace('create_containers: start');
 
--
  SELECT sl_name, sl_min_alloc
    INTO l_cg_name, l_min_alloc
    FROM sl
    WHERE sl_key = p_slkey;
  am_trace('create_containers: sl_name: ' || l_cg_name ||
                 ', sl_min_alloc: ' || pparm(l_min_alloc));
 
--
--
--
--
--
  SELECT MAX(DECODE(name, 'network_chunksize', TO_NUMBER(value))),
         MAX(DECODE(name, '_def_contfilesize', value))
    INTO l_net_chunksize, l_def_cont_size
    FROM config
   WHERE name IN ('network_chunksize',
                  '_def_contfilesize');
  am_trace('create_containers: network_chunksize: ' || l_net_chunksize ||
                 ', _def_contfilesize: ' || l_def_cont_size);
 
--
--
--
--
  FOR i IN (SELECT dest, rowid, cursize, usersize, rownum
              FROM storage_dests
              WHERE sl_key = p_slkey) LOOP
    am_trace('create_containers: verifying destination ' || i.dest);
    am_trace('create_containers: usersize=' || pparm(i.usersize));
 
--
--
--
    IF SUBSTR(i.dest, 1, 1) = '+' THEN
 
      IF l_nonasm_count > 0 THEN
        RAISE MIXED_STORAGE_TYPES;
      END IF;
 
      l_asm_count := l_asm_count + 1;
 
--
      BEGIN
        SELECT group_number, name, allocation_unit_size
          INTO l_asm_group, l_asm_group_name, l_au_size
          FROM sys.v_$asm_diskgroup
          WHERE '+' || name || '/' = i.dest;
      EXCEPTION
        WHEN no_data_found THEN
          am_trace('create_containers: ' || item_not_found(i.dest,
                                            'storage destination'));
          sys.dbms_sys_error.raise_system_error(OBJ_NOT_FOUND_NUM,
                                                i.dest,
                                                'storage destination',
                                                FALSE);
      END;
 
--
--
--
      fake_sl_sizing (l_asm_group_name);
 
--
      BEGIN
        SELECT init_ok, sl_space INTO l_init_ok, l_max_diskgroup
          FROM sl_sizing
         WHERE disk_group = l_asm_group_name;
      EXCEPTION
         WHEN NO_DATA_FOUND THEN
           l_init_ok := 'N';
      END;
 
      IF l_init_ok = 'N' THEN
        sys.dbms_sys_error.raise_system_error(DISKGROUP_NOT_USABLE_NUM,
                                              i.dest,
                                              FALSE);
      END IF;
 
--
--
      SELECT NVL(SUM(fsize),0) INTO l_used_diskgroup
        FROM sys.amcont$
       WHERE fname LIKE i.dest || '%';
 
--
      l_freespace := l_max_diskgroup - l_used_diskgroup;
      am_trace('create_containers: freespace=' || TO_CHAR(l_freespace));
 
--
      am_trace('create_containers: usable freespace before FLOOR 0=' ||
                                 TO_CHAR(l_freespace));
      l_freespace := GREATEST(l_freespace, 0); 
      am_trace('create_containers: usable freespace=' || TO_CHAR(l_freespace));
 
--
      l_needsize := l_freespace;
 
--
--
      IF i.usersize IS NOT NULL THEN
--
 
        IF i.usersize < i.cursize THEN
--
          sys.dbms_sys_error.raise_system_error(DEST_SIZE_TOO_SMALL_NUM,
                                                i.usersize,
                                                i.dest,
                                                i.cursize,
                                                FALSE);
        END IF;
 
        IF i.usersize > i.cursize + l_freespace THEN
--
          sys.dbms_sys_error.raise_system_error(DEST_SIZE_TOO_BIG_NUM,
                                                i.usersize,
                                                i.dest,
                                                i.cursize + l_freespace,
                                                FALSE);
        END IF;
 
--
--
--
--
        l_needsize := i.usersize - i.cursize;
        am_trace('create_containers: granted needsize=' || l_needsize);
      END IF; -- end ASM storage destination
 
--
--
--
    ELSE
      IF l_asm_count > 0 THEN
        RAISE MIXED_STORAGE_TYPES;
      END IF;
 
      l_nonasm_count := l_nonasm_count + 1;
 
--
      IF i.rownum > 1
      THEN
        RAISE MULTIPLE_NON_ASM;
      END IF;
 
--
      IF i.usersize = NULL THEN
          l_invalid_val := 'container ' || i.dest || ' size;' ||
                           ' a size is required for file-based containers';
          RAISE INVALID_VAL;
      END IF;
 
--
      SELECT NVL(value, FOURMEG) INTO l_au_size
        FROM config
       WHERE name = '_def_min_alloc';
 
--
--
      IF p_reformat THEN
        i.cursize := 0;
      END IF;
      am_trace('create_containers: i.cursize=' || i.cursize);
 
--
--
--
      l_needsize := i.usersize - i.cursize;
      am_trace('create_containers: granted needsize=' || l_needsize);
 
      am_trace('create_containers: min alloc=' || TO_CHAR(l_au_size) ||
                         '; usersize=' || TO_CHAR(i.usersize) ||
                         '; cursize=' || TO_CHAR(i.cursize) ||
                         '; needsize=' || TO_CHAR(l_needsize));
 
--
--
      IF l_needsize < 0 THEN
          l_invalid_val := 'container ' || i.dest || ' size;' ||
                           ' requested size ' ||
                           i.usersize ||
                           ' is smaller than existing size ' ||
                           i.cursize;
          RAISE INVALID_VAL;
      END IF;
    END IF; -- end non-ASM (file-based) storage destination
 
--
--
--
 
--
--
--
    l_min_alloc := NVL(l_min_alloc, l_au_size);
    am_trace('create_containers: l_min_alloc: ' || pparm(l_min_alloc));
 
--
    IF (l_min_alloc <> l_au_size) THEN
      sys.dbms_sys_error.raise_system_error(ALLOC_SIZE_DISCREPANCY_NUM,
                                            l_cg_name,
                                            TO_CHAR(l_min_alloc),
                                            i.dest,
                                            TO_CHAR(l_au_size),
                                            FALSE);
    END IF;
 
--
--
    IF (MOD(l_net_chunksize, l_au_size) <> 0) THEN
      sys.dbms_sys_error.raise_system_error(NETCS_SIZE_DISCREPANCY_NUM,
                                            TO_CHAR(l_net_chunksize),
                                            i.dest,
                                            TO_CHAR(l_au_size),
                                            FALSE);
      RAISE INVALID_VAL;
    END IF;
 
--
    IF (BITAND(l_au_size, l_au_size-1) <> 0) THEN
      sys.dbms_sys_error.raise_system_error(ALLOC_SIZE_NOT_PWR_OF_2_NUM,
                                            i.dest,
                                            TO_CHAR(l_au_size),
                                            FALSE);
    END IF;
 
--
    IF (l_au_size < 2*ONEMEG) THEN
      sys.dbms_sys_error.raise_system_error(ALLOC_SIZE_TOO_SMALL_NUM,
                                            i.dest,
                                            TO_CHAR(l_au_size),
                                            TO_CHAR(2*ONEMEG),
                                            FALSE);
    END IF;
 
--
--
--
    am_trace('create_containers: updating ' || i.dest || 
                       ' for needsise ' || l_needsize);
    UPDATE storage_dests
      SET needsize = l_needsize
      WHERE rowid = i.rowid;
 
    am_trace('create_containers: verified destination ' || i.dest);
  END LOOP; -- end all storage destination size change calculations
 
--
--
--
--
--
--
 
--
--
  l_cont_size := numstring_to_num(l_def_cont_size);
  IF l_cont_size > (TWO_TERABYTE - 512) THEN
    l_cont_size := TWO_TERABYTE - 512;
  END IF;
 
  IF p_create THEN
--
    UPDATE sl SET sl_cg_name = '/:' || sl_name,
                  sl_min_alloc = l_au_size,
                  sl_space = 1
      WHERE sl_key = p_slkey
      RETURNING sl_name INTO l_cg_name;
 
--
    am_trace('create_containers: creating container group ' || l_cg_name);
    sys.kbrsi_icd.create_container_group(l_cg_name);
    l_newcg := TRUE;
    am_trace('create_containers: created container group ' || l_cg_name);
  END IF;
 
--
--
--
--
--
--
--
--
--
--
--
--
--
  COMMIT;
 
--
--
  IF dbms_ra_int.is_repair_needed AND NOT p_reformat THEN
    am_trace('create_containers: repairing, but not reformatting');
    RETURN;
  END IF;
 
--
  l_newcontainer := FALSE;
  FOR i IN (SELECT dest, cursize, needsize, rowid
              FROM storage_dests
              WHERE sl_key = p_slkey
                AND needsize >= MIN_CG_FILE_SIZE) LOOP
 
--
    l_size := i.needsize;
 
    am_trace('create_containers: creating containers for ' || i.dest ||
                              '; unused space is ' || l_size);
 
--
    WHILE l_size >= MIN_CG_FILE_SIZE LOOP
 
--
--
--
      IF l_size > l_cont_size THEN
        l_this_cont_size := l_cont_size;
      ELSE
        l_this_cont_size := TRUNC(l_size / l_au_size) * l_au_size;
      END IF;
 
 
      am_trace('create_containers: creating container file of size ' ||
               l_this_cont_size);
 
      BEGIN
        sys.kbrsi_icd.create_container(l_cg_name, l_this_cont_size, i.dest);
        l_newcontainer := TRUE;
      EXCEPTION
        WHEN CREATE_CONTAINER_FAILED THEN
          am_trace('create_containers: Create error: container ''' || i.dest ||
                             ''', SQL error ''' || SQLERRM || '''');
--
--
--
          IF l_asm_count > 0 THEN
--
            l_size := LEAST((l_this_cont_size - (100 * ONEMEG)),
                            ROUND(l_this_cont_size*.9));
            CONTINUE;
          END IF;
          RAISE;
      END;
 
      am_trace('create_containers: created container file of size ' ||
               l_this_cont_size);
 
      l_size := l_size - l_this_cont_size;
 
      am_trace('create_containers: remaining size ' || l_size);
 
    END LOOP;
 
--
--
--
--
--
    l_new_cursize := i.cursize + i.needsize - l_size;
    UPDATE storage_dests
      SET cursize = l_new_cursize
      WHERE rowid = i.rowid;
    am_trace('create_containers: storage dest: ' || i.dest ||
             ', new cursize: ' || l_new_cursize);
  END LOOP;
 
--
  IF p_create AND NOT l_newcontainer THEN
    sys.dbms_sys_error.raise_system_error(CREATED_NO_CONTAINERS_NUM,
                                          l_cg_name,
                                          FALSE);
  END IF;
 
--
  SELECT total_space INTO l_size
    FROM sys.am$container_group
   WHERE group_name = l_cg_name;
 
--
--
--
--
--
--
  IF NOT p_create THEN
    dbms_ra_storage.lock_sl(p_slkey);
  END IF; 
 
  UPDATE sl
     SET sl_space = l_size
   WHERE sl_key = p_slkey;
  COMMIT;
 
  IF NOT p_create THEN
    dbms_ra_storage.unlock_sl(p_slkey);
  END IF; 
 
  am_trace('create_containers: total usable size for ' || l_cg_name ||
           ' is ' || TO_CHAR(l_size));
  am_trace('create_containers: end');
 
EXCEPTION
  WHEN OTHERS THEN
--
    dbms_ra_storage.unlock_sl(p_slkey);
 
    ROLLBACK;
 
--
    IF SQLCODE = MIXED_STORAGE_TYPES_NUM OR
       SQLCODE = MULTIPLE_NON_ASM_NUM THEN
      am_trace('create_containers: raising ' || SQLERRM);
      RAISE;
    END IF;
 
--
    IF p_create AND l_newcg THEN
      am_trace('create_containers exception: dropping container group ' || 
               l_cg_name);
      sys.kbrsi_icd.drop_container_group(gname => l_cg_name,
                                         force => 1,
                                         keep_container => 0);
      DELETE FROM sl WHERE sl_key = p_slkey;
      COMMIT;
    END IF;
 
    IF SQLCODE = INVALID_VAL_NUM AND l_invalid_val IS NOT NULL THEN
       am_trace ('create_containers exception: INVALID_VAL: ' ||
                 l_invalid_val);
 
       sys.dbms_sys_error.raise_system_error(INVALID_VAL_NUM,
                                            l_invalid_val,
                                            FALSE);
    END IF;
 
    RAISE;
END create_containers;
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
FUNCTION parse_dests (p_storage_dests IN VARCHAR2,
                      p_storage_for_poll IN BOOLEAN DEFAULT FALSE
                     ) RETURN destList_t
IS
  i                PLS_INTEGER := 0;
  l_dest_list      destList_t;
  l_dests          VARCHAR2(4000);
  l_dests_len      BINARY_INTEGER;
  l_pos            BINARY_INTEGER := 1;
  l_spec           VARCHAR2(4000);
  l_lparen_col     NUMBER;
  l_rparen_col     NUMBER;
  l_synerr_col     NUMBER;
  l_name           VARCHAR2(4000);
  l_isasm          BOOLEAN := FALSE;
  l_sl_key         NUMBER;
  l_size_spec      VARCHAR2(4000);
  l_size           NUMBER;
  l_dup_name_type  VARCHAR2(256) := NULL;
  l_dup_name       VARCHAR2(256) := NULL;
 
--
--
--
--
--
--
--
--
--
--
 
--
--
--
--
--
--
  l_spec_list_pat  VARCHAR2(128) := '[^,]*,?';
 
--
--
--
--
--
--
--
--
--
  l_spec_item_pat  VARCHAR2(128) := '^([^,()]+)?(\(([^)]*)\))?,?$';
 
--
--
--
--
--
--
--
  l_size_spec_pat  VARCHAR2(128) := '^[0-9]+[KkMmGgTtPpEeZzYy]?$';
 
BEGIN
 
  am_trace('parse_dests: p_storage_for_poll: ' || pparm(p_storage_for_poll));
 
--
  IF p_storage_dests IS NULL THEN
    am_trace('parse_dests: p_storage_dests IS NULL');
    RETURN l_dest_list;
  END IF;
 
--
--
--
--
--
--
--
--
--
--
  l_dests := REPLACE(p_storage_dests,' ','');
 
--
  l_dests_len := LENGTH(l_dests);
 
--
  WHILE TRUE LOOP
 
--
    l_spec := REGEXP_SUBSTR(l_dests,l_spec_list_pat,l_pos,1);
 
--
--
--
    EXIT WHEN l_pos > l_dests_len;
 
--
--
    l_synerr_col := 0;
    l_lparen_col := INSTR(l_spec,'(');
    l_rparen_col := INSTR(l_spec,')');
 
    IF l_lparen_col != 0 AND l_rparen_col = 0 THEN
      l_synerr_col := l_lparen_col;
    ELSIF l_lparen_col = 0 AND l_rparen_col != 0 THEN
      l_synerr_col := l_rparen_col;
    ELSIF l_lparen_col > l_rparen_col THEN
      l_synerr_col := l_rparen_col;
    END IF;
    IF l_synerr_col > 0 THEN
      sys.dbms_sys_error.raise_system_error(UNBAL_PAREN_NUM,
        l_dests, TO_CHAR(l_pos + l_synerr_col - 1), FALSE);
    END IF;
 
--
--
    l_name := REGEXP_SUBSTR(l_spec,l_spec_item_pat,1,1,'',1);
    IF l_name IS NULL THEN
      sys.dbms_sys_error.raise_system_error(NO_DEST_NUM,
        l_dests, TO_CHAR(l_pos), FALSE);
    END IF;
 
--
    l_isasm := SUBSTR(l_name,1,1) = '+';
 
--
--
--
    IF p_storage_for_poll AND l_dest_list.COUNT = 1 THEN
      sys.dbms_sys_error.raise_system_error(MULTIPLE_POLLING_NUM,
        l_dests, TO_CHAR(l_pos), FALSE);
    END IF;
 
--
    IF l_isasm AND p_storage_for_poll THEN
      sys.dbms_sys_error.raise_system_error(ASM_POLLING_NUM,
        l_dests, TO_CHAR(l_pos), FALSE);
    END IF;
 
--
    IF SUBSTR(l_name, -1, 1) != '/' THEN
      l_name := l_name  || '/';
    END IF;
 
--
--
    l_size_spec := REGEXP_SUBSTR(l_spec,l_spec_item_pat,1,1,'',3);
 
--
    IF l_size_spec IS NOT NULL THEN
 
--
      IF p_storage_for_poll THEN
        sys.dbms_sys_error.raise_system_error(POLLING_SIZE_NUM,
          l_dests, TO_CHAR(l_pos + l_lparen_col - 1), FALSE);
      END IF;
 
--
      l_size_spec := REGEXP_SUBSTR(l_size_spec,l_size_spec_pat,1,1);
      IF l_size_spec IS NULL THEN
        sys.dbms_sys_error.raise_system_error(BAD_STORAGE_SIZE_NUM,
          l_dests, TO_CHAR(l_pos + l_lparen_col - 1), FALSE);
      END IF;
    END IF;
 
--
--
--
--
    IF (NOT l_isasm) AND (l_size_spec IS NULL) AND
      (NOT p_storage_for_poll) THEN
        sys.dbms_sys_error.raise_system_error(NO_STORAGE_SIZE_NUM,
          l_dests, TO_CHAR(l_pos), FALSE);
    END IF;
 
--
    l_size := NULL;
    IF l_size_spec IS NOT NULL THEN
      BEGIN
--
        l_size := numstring_to_num(l_size_spec,TRUE);
 
--
        IF l_size < MIN_CG_FILE_SIZE THEN
          sys.dbms_sys_error.raise_system_error(SMALL_CG_FILE_SIZE_NUM,
            MIN_CG_FILE_SIZE_NUMSTR, l_dests, TO_CHAR(l_pos), FALSE);
        END IF;
 
      EXCEPTION
        WHEN INVALID_SIZENUMBER THEN
--
          sys.dbms_sys_error.raise_system_error(BAD_STORAGE_SIZE_NUM,
            l_dests, TO_CHAR(l_pos + l_lparen_col - 1), FALSE);
        WHEN OTHERS THEN
          RAISE;
      END;
    END IF;
 
--
    i := i + 1;
    IF l_isasm THEN
      l_dest_list(i).name_dest := UPPER(l_name);
    ELSE
        l_dest_list(i).name_dest := l_name;
    END IF;
    l_dest_list(i).size_dest := l_size;
    am_trace('parse_dests: inserted into dest_list(' || TO_CHAR(i) || '): ' ||
                        'name: ' || l_dest_list(i).name_dest ||
                        ', size: ' || TO_CHAR(l_dest_list(i).size_dest));
 
--
    l_pos := l_pos + LENGTH(l_spec);
  END LOOP;
 
  RETURN l_dest_list;
 
END parse_dests;
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE create_storage_location_int (
                             p_storage_name   IN VARCHAR2,
                             p_storage_dests  IN VARCHAR2,
                             p_storage_for_poll IN BOOLEAN DEFAULT FALSE)
IS
  l_numrows         NUMBER;
  l_dest_list       destList_t;
  l_sl_key          NUMBER;
  l_sl_name         sl.sl_name%TYPE;
  l_dup_name_type   VARCHAR2(256) := NULL;
  l_dup_name        VARCHAR2(256) := NULL;
 
BEGIN
 
--
--
  SELECT count(*)
    INTO l_numrows
    FROM sl
    WHERE sl.sl_name = p_storage_name;
  IF l_numrows != 0 THEN
    l_dup_name_type := 'storage location';
    l_dup_name := p_storage_name;
    RAISE DUP_VAL_ON_INDEX;
  END IF ;
 
--
  IF p_storage_dests IS NULL THEN
      am_trace ('create_storage_location: required parameter missing:' ||
                ' storage destination');
      sys.dbms_sys_error.raise_system_error(MISSING_PARAM_NUM,
                                            'storage destination',
                                            FALSE);
  END IF;
 
--
--
  am_trace('create_storage_location: parse_dests');
  l_dest_list := parse_dests(p_storage_dests,p_storage_for_poll);
  am_trace('create_storage_location: parse_dests OK');
--
  am_trace('create_storage_location: create SL row');
  INSERT
    INTO sl (sl_key, sl_name, sl_type, sl_space,
             sl_last_check_files, sl_min_alloc)
    VALUES (rman_seq.nextval, p_storage_name, BA_STORAGE_DISK, 0,
            SYSTIMESTAMP, NULL)
    RETURNING sl_key into l_sl_key;
  am_trace('create_storage_location: create SL row OK');
 
--
  FOR i IN l_dest_list.FIRST..l_dest_list.LAST LOOP
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
 
    am_trace('create_storage_location: show existing dests');
    FOR d IN (SELECT dest FROM storage_dests ORDER BY dest) LOOP
        am_trace('create_storage_location: existing dest: ' || d.dest);
    END LOOP;
    am_trace('create_storage_location: show existing dests OK');
 
    am_trace('create_storage_location: name reuse query');
--
    SELECT MIN(sl_name) INTO l_sl_name
      FROM sl JOIN storage_dests sd USING (sl_key)
     WHERE sd.dest = SUBSTR(l_dest_list(i).name_dest, 1, LENGTH(sd.dest)) OR
           l_dest_list(i).name_dest = SUBSTR(sd.dest, 1,
                                             LENGTH(l_dest_list(i).name_dest));
    am_trace('create_storage_location: name reuse query OK');
 
    am_trace('create_storage_location: signal SHARED_PARAMS?');
    IF l_sl_name IS NOT NULL THEN
      am_trace('create_storage_location: signalling SHARED_PARAMS');
      SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(E_SHARED_PARAMS_NUM, l_sl_name);
    END IF;
    am_trace('create_storage_location: signal SHARED_PARAMS OK');
 
    am_trace('create_storage_location: trace creating dests');
    am_trace('create_storage_location: creating dest ' ||
               l_dest_list(i).name_dest ||
               ', size ' ||
               l_dest_list(i).size_dest);
    am_trace('create_storage_location: trace creating dests OK');
 
    am_trace('create_storage_location: insert');
    INSERT INTO storage_dests (sl_key, dest, needsize, cursize, usersize)
      VALUES (l_sl_key, l_dest_list(i).name_dest, 0, 0,
              l_dest_list(i).size_dest);
    am_trace('create_storage_location: insert complete');
  END LOOP;
 
--
--
--
  IF NOT p_storage_for_poll THEN
    am_trace('create_storage_location: calling create_containers');
    create_containers(l_sl_key, TRUE);
    am_trace('create_storage_location: create_containers OK');
  END IF;
  COMMIT;
 
--
  dbms_ra_scheduler.enqueue_verify_timer_task;
 
EXCEPTION
 
  WHEN DUP_VAL_ON_INDEX THEN
    ROLLBACK;
    IF l_dup_name IS NOT NULL THEN
--
      sys.dbms_sys_error.raise_system_error(DUP_NAME_NUM,
        l_dup_name, l_dup_name_type, FALSE);
    ELSE
--
      RAISE;
    END IF;
 
--
  WHEN
--
    MISSING_PARAM OR E_SHARED_PARAMS OR
--
    UNBAL_PAREN OR NO_DEST OR MULTIPLE_POLLING OR ASM_POLLING OR
    POLLING_SIZE OR BAD_STORAGE_SIZE OR NO_STORAGE_SIZE OR
    SMALL_CG_FILE_SIZE OR
--
    CREATE_CONTAINER_FAILED OR MIXED_STORAGE_TYPES OR OBJ_NOT_FOUND OR
    REDUNDANCY_TYPE_BAD OR DEST_SIZE_TOO_SMALL OR DEST_SIZE_TOO_BIG OR
    MIXED_STORAGE_TYPES OR MULTIPLE_NON_ASM OR INVALID_VAL OR
    ALLOC_SIZE_DISCREPANCY OR NETCS_SIZE_DISCREPANCY OR
    ALLOC_SIZE_NOT_PWR_OF_2 OR ALLOC_SIZE_TOO_SMALL OR CREATED_NO_CONTAINERS
    THEN
      ROLLBACK;
      RAISE;
 
--
  WHEN OTHERS THEN
    ROLLBACK;
 
    am_trace ('create_storage_location exception: ' ||
              ' local key: '              || l_sl_key ||
              ' storage_name: '           || p_storage_name ||
              ' storage_dest: '           || p_storage_dests ||
              ' err:' || SQLERRM);
    RAISE;
END create_storage_location_int;
--
PROCEDURE create_storage_location (
                             storage_location_name  IN VARCHAR2,
                             storage_location_dests IN VARCHAR2)
IS
  l_the             NUMBER;
  c_storage_location_name  sl.sl_name%TYPE;
BEGIN
  lock_api(LOCKAPI_CREATE, 'create_storage_location');
  l_the := dbms_ra_scheduler.add_to_task_history_table (
      task_type => dbms_ra_scheduler.TASK_API_ADD_SL,
      param     => 'create_storage_location' ||
        b_p('storage_location_name',  storage_location_name, p_first=>TRUE) ||
        b_p('storage_location_dests',  storage_location_dests, p_last=>TRUE));
 
  dbms_ra_int.canonicalize(storage_location_name,c_storage_location_name, 128);
  create_storage_location_int (c_storage_location_name,
                               storage_location_dests);
  unlock_api(p_the_num=>l_the, p_results=>TRUE, p_docommit=>TRUE);
 
EXCEPTION
  WHEN OTHERS THEN
    rollback;
    unlock_api(p_the_num=>l_the, p_results=>FALSE, p_docommit=>TRUE);
    RAISE;
  
END create_storage_location;
--
 
 
 
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE delete_storage_location_int (p_storage_name IN VARCHAR2)
IS
  l_sl_key          NUMBER := NULL;
  l_sl_cnt          NUMBER := NULL;
  l_cg_name         sl.sl_name%TYPE;
  l_space           NUMBER;
BEGIN
 
--
  BEGIN
    SELECT sl_key, DECODE(sl_space, 0, NULL, sl_name), sl_space
      INTO l_sl_key, l_cg_name, l_space
      FROM sl
      WHERE sl_name = p_storage_name;
  EXCEPTION
    WHEN NO_DATA_FOUND THEN
      RAISE OBJ_NOT_FOUND;
  END;
 
  dbms_ra_storage.lock_sl(l_sl_key);
  
  SELECT count(*)
    INTO l_sl_cnt
    FROM prot
    WHERE prot.sl_key = l_sl_key ;
 
  IF l_sl_cnt = 0 THEN
--
    SELECT count(*)
      INTO l_sl_cnt
      FROM dbsl
      WHERE dbsl.sl_key = l_sl_key ;
  END IF;
 
  IF l_sl_cnt = 0 THEN
--
--
 
--
    DELETE
      FROM error_log
      WHERE sl_key = l_sl_key;         
 
--
    DELETE
      FROM poll
      WHERE sl_key = l_sl_key;
 
--
    IF SQL%ROWCOUNT > 0 THEN
      COMMIT;
      dbms_ra_scheduler.enqueue_verify_timer_task;  
    END IF;
 
--
    DELETE
      FROM unreg_database
      WHERE sl_key = l_sl_key; 
 
--
    DELETE
      FROM sl
      WHERE sl_name = p_storage_name;
  ELSE
    am_trace ('delete_storage_location: cannot delete storage location ' ||
              'that has protection policies or databases or ' || 
              'polling locations referencing it.' ||
              ' storage_name:'            || p_storage_name);
    RAISE OBJ_IS_REFERENCED;
  END IF;
 
--
  IF (l_cg_name IS NOT NULL) AND (NOT dbms_ra_int.is_repair_needed) THEN
    sys.kbrsi_icd.drop_container_group(gname => l_cg_name,
                                       force => 1,
                                       keep_container => 0);
  END IF;
  COMMIT;
 
  dbms_ra_storage.unlock_sl(l_sl_key);
  l_sl_key := NULL;
 
EXCEPTION
  WHEN OBJ_IS_REFERENCED THEN
    dbms_ra_storage.unlock_sl(l_sl_key);
    am_trace ('delete_storage_location: item in use' || p_storage_name);
    sys.dbms_sys_error.raise_system_error(OBJ_IS_REFERENCED_NUM,
                                          p_storage_name,
                                          'storage location',
                                          FALSE);
 
  WHEN OBJ_NOT_FOUND THEN
    dbms_ra_storage.unlock_sl(l_sl_key);
    am_trace ('delete_storage_location: ' || item_not_found(
                                                p_storage_name,
                                                'storage location'));
    sys.dbms_sys_error.raise_system_error(OBJ_NOT_FOUND_NUM,
                                          p_storage_name,
                                          'storage location',
                                          FALSE);
 
  WHEN OTHERS THEN
    ROLLBACK;
    am_trace ('delete_storage_location exception:' ||
              ' storage_name:'            || p_storage_name ||
              ' err:' || SQLERRM);
 
    IF l_sl_key IS NOT NULL THEN
      dbms_ra_storage.unlock_sl(l_sl_key);
      l_sl_key := NULL;
    END IF;
 
    RAISE;
 
END delete_storage_location_int;
--
PROCEDURE delete_storage_location (storage_location_name IN VARCHAR2)
IS
  l_the                     NUMBER;
  c_storage_location_name   sl.sl_name%TYPE;
BEGIN
  lock_api(LOCKAPI_DELETE, 'delete_storage_location');
  
  l_the := dbms_ra_scheduler.add_to_task_history_table (
                  task_type => dbms_ra_scheduler.TASK_API_DEL_SL,
                  param     => 'delete_storage_location' ||
                   b_p('storage_location_name', storage_location_name, 
                         p_first=>TRUE, p_last=>TRUE));
  
  dbms_ra_int.canonicalize(storage_location_name,c_storage_location_name, 128);
  delete_storage_location_int (c_storage_location_name);
  unlock_api(p_the_num=>l_the, p_results=>TRUE, p_docommit=>TRUE);
 
EXCEPTION
  WHEN OTHERS THEN
    rollback;
    unlock_api(p_the_num=>l_the, p_results=>FALSE, p_docommit=>TRUE);
    RAISE;
END delete_storage_location;
--
 
 
 
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE update_storage_location_int (p_storage_name  IN VARCHAR2,
                                       p_storage_dests IN VARCHAR2 DEFAULT NULL)
IS
  l_dest_list       destList_t;
  l_sl_key          NUMBER := NULL;
  l_sl_name         sl.sl_name%TYPE;
 
BEGIN
 
--
  BEGIN
    SELECT sl.sl_key
      INTO l_sl_key
      FROM sl
      WHERE sl_name = p_storage_name;
  EXCEPTION
    WHEN NO_DATA_FOUND THEN
      RAISE OBJ_NOT_FOUND;
  END;
 
--
--
  l_dest_list := parse_dests(p_storage_dests => p_storage_dests);
 
--
--
  IF l_dest_list.COUNT > 0 THEN
    FOR i IN l_dest_list.FIRST..l_dest_list.LAST LOOP
 
      am_trace('update_storage_location: show existing dests');
      FOR d IN (SELECT dest FROM storage_dests ORDER BY dest) LOOP
          am_trace('update_storage_location: existing dest: ' || d.dest);
      END LOOP;
      am_trace('update_storage_location: show existing dests OK');
 
      am_trace('update_storage_location: name reuse query');
--
      SELECT MIN(sl_name) INTO l_sl_name
        FROM sl JOIN storage_dests sd USING (sl_key)
       WHERE (sd.dest = SUBSTR(l_dest_list(i).name_dest, 1, LENGTH(sd.dest)) OR
             l_dest_list(i).name_dest = SUBSTR(sd.dest, 1,
                                             LENGTH(l_dest_list(i).name_dest)))
             AND NOT
             (sd.dest = l_dest_list(i).name_dest AND
             sl_name = p_storage_name);
      am_trace('update_storage_location: name reuse query OK');
 
      am_trace('update_storage_location: signal SHARED_PARAMS?');
      IF l_sl_name IS NOT NULL THEN
        am_trace('update_storage_location: signalling SHARED_PARAMS');
        SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(E_SHARED_PARAMS_NUM, l_sl_name);
      END IF;
      am_trace('update_storage_location: signal SHARED_PARAMS OK');
 
--
      MERGE INTO storage_dests
        USING dual ON (sl_key = l_sl_key AND dest = l_dest_list(i).name_dest)
        WHEN MATCHED THEN
          UPDATE SET usersize = l_dest_list(i).size_dest
        WHEN NOT MATCHED THEN
          INSERT (sl_key, dest, needsize, cursize, usersize)
            VALUES (l_sl_key, l_dest_list(i).name_dest, 0, 0,
                    l_dest_list(i).size_dest);
    END LOOP;
  END IF;
 
--
  am_trace('update_storage_location: calling create_containers');
  create_containers(l_sl_key, FALSE);
  am_trace('update_storage_location: create_containers OK');
 
--
  dbms_ra_scheduler.fix_error(
                        p_error_num => dbms_ra_scheduler.e_sl_full_num,
                        p_sl_key    => l_sl_key);
  commit;
 
EXCEPTION
  WHEN OBJ_NOT_FOUND THEN
    IF l_sl_key IS NULL THEN  -- exception happened here
      am_trace('update_storage_location: ' ||
                  item_not_found(p_storage_name,'storage location'));
      sys.dbms_sys_error.raise_system_error(OBJ_NOT_FOUND_NUM,
        p_storage_name, 'storage location', FALSE);
    ELSE
--
      dbms_ra_storage.unlock_sl(l_sl_key);
      l_sl_key := NULL;
      RAISE;  -- exception happened in a callee
    END IF;
 
--
  WHEN
--
    MISSING_PARAM OR
--
    UNBAL_PAREN OR NO_DEST OR MULTIPLE_POLLING OR ASM_POLLING OR
    POLLING_SIZE OR BAD_STORAGE_SIZE OR NO_STORAGE_SIZE OR
    SMALL_CG_FILE_SIZE OR
--
    CREATE_CONTAINER_FAILED OR MIXED_STORAGE_TYPES OR
    REDUNDANCY_TYPE_BAD OR DEST_SIZE_TOO_SMALL OR DEST_SIZE_TOO_BIG OR
    MIXED_STORAGE_TYPES OR MULTIPLE_NON_ASM OR INVALID_VAL OR
    ALLOC_SIZE_DISCREPANCY OR NETCS_SIZE_DISCREPANCY OR
    ALLOC_SIZE_NOT_PWR_OF_2 OR ALLOC_SIZE_TOO_SMALL OR CREATED_NO_CONTAINERS
    THEN
      ROLLBACK;
--
      IF l_sl_key IS NOT NULL THEN
        dbms_ra_storage.unlock_sl(l_sl_key);
        l_sl_key := NULL;
      END IF;
      RAISE;
 
  WHEN OTHERS THEN
    ROLLBACK;
    am_trace ('update_storage_location exception: ' ||
              ' storage_name:'            || p_storage_name ||
              ' storage_dests:'           || p_storage_dests ||
              ' err:' || SQLERRM);
 
    RAISE;
 
END update_storage_location_int;
--
PROCEDURE update_storage_location (
                              storage_location_name  IN VARCHAR2,
                              storage_location_dests IN VARCHAR2 DEFAULT NULL)
IS
  l_the                     NUMBER;
  c_storage_location_name   sl.sl_name%TYPE;
BEGIN
  lock_api(LOCKAPI_MODIFY, 'update_storage_location');
  
  l_the := dbms_ra_scheduler.add_to_task_history_table (
      task_type => dbms_ra_scheduler.TASK_API_UPD_SL,
       param     => 'update_storage_location' ||
       b_p('storage_location_name',  storage_location_name, p_first=>TRUE ) ||
       b_p('storage_location_dests', storage_location_dests , p_last=>TRUE));
  
  dbms_ra_int.canonicalize(storage_location_name,c_storage_location_name, 128);
 
  update_storage_location_int (c_storage_location_name,
                               storage_location_dests);
  unlock_api(p_the_num=>l_the, p_results=>TRUE, p_docommit=>TRUE);
 
EXCEPTION
  WHEN OTHERS THEN
    rollback;
    unlock_api(p_the_num=>l_the, p_results=>FALSE, p_docommit=>TRUE);
    RAISE;
END update_storage_location;
--
 
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE add_db_int (p_db_unique_name            IN VARCHAR2,
                      p_protection_policy_name    IN VARCHAR2,
                      p_reserved_space            IN VARCHAR2)
IS
  l_prot_key                NUMBER;
  l_db_key                  NUMBER;
  l_deleting                NUMBER;
  l_sl_key                  NUMBER := NULL;
  l_poll_key                NUMBER;
  l_missing_param           VARCHAR2(128);
  l_space                   NUMBER;
  l_cnt                     NUMBER;
  l_pending_rep_setup       odb.pending_rep_setup%type := NULL;
BEGIN
 
--
  IF p_db_unique_name IS NULL THEN
    l_missing_param := 'db_unique_name';
    RAISE MISSING_PARAM;
  END IF;
 
--
  BEGIN
    IF p_protection_policy_name IS NOT NULL THEN
      SELECT prot_key, prot.sl_key, prot.poll_key
        INTO l_prot_key, l_sl_key, l_poll_key
        FROM prot
        WHERE prot_name = p_protection_policy_name;
    ELSE
       l_missing_param := 'protection_policy_name';
       RAISE MISSING_PARAM;
    END IF;
  EXCEPTION
    WHEN NO_DATA_FOUND THEN
      RAISE OBJ_NOT_FOUND;
  END;
 
--
  l_space := numstring_to_num(NVL(p_reserved_space,0));
  IF l_space < MIN_RESERVATION THEN
    am_trace('add_db: reserved_space ' || TO_CHAR(l_space) ||
             ' less than MIN_RESERVATION ' || TO_CHAR(MIN_RESERVATION));
    sys.dbms_sys_error.raise_system_error(RSRVD_SPACE_TOO_SMALL_NUM,
                                          TO_CHAR(l_space),
                                          TO_CHAR(MIN_RESERVATION),
                                          FALSE);
  END IF;
 
--
--
  BEGIN 
    SELECT db_key into l_db_key from node
      WHERE db_unique_name = p_db_unique_name;
 
--
    SELECT COUNT(*) INTO l_deleting
      FROM odb
     WHERE db_key = l_db_key
       AND db_state IS NOT NULL;
 
    IF l_deleting > 0 THEN
      sys.dbms_sys_error.raise_system_error(CANT_DELETE_DB_RUNNING_NUM,
                                            p_db_unique_name,
                                            FALSE);
    END IF;
 
--
--
    SELECT count (*) INTO l_cnt FROM rep_server WHERE prot_key=l_prot_key;
    IF l_cnt > 0 THEN
      l_pending_rep_setup := 'Y';
    END IF;
 
    INSERT INTO odb (db_key, sls_used, total_allocation,sl_key,sl_min_alloc,
                     allocated_space, used_space,
                     cumulative_usage, 
                     cumulative_rep_usage, cumulative_sbt_usage,
                     create_time, last_optimize, last_validate,
                     prot_key, future_prot_key, 
                     base_reserved_space, reserved_space,
                     recovery_window_goal, not_taped, not_taped_state,
                     pending_rep_setup)
         (SELECT l_db_key, 1, 0, sl.sl_key, sl.sl_min_alloc,
                 0, 0, 0, 0, 0,
                 SYSTIMESTAMP, SYSTIMESTAMP, SYSTIMESTAMP,
                 prot.prot_key, prot.prot_key, 
                 l_space, l_space,
                 prot.prot_recovery_window_goal, 
                 1, decode(prot.prot_disk_cache, 'YES', 'I', null),
                 l_pending_rep_setup
          FROM prot, sl
          WHERE prot_key = l_prot_key
           AND prot.sl_key = sl.sl_key);
  EXCEPTION
    WHEN NO_DATA_FOUND THEN
--
      INSERT INTO unreg_database (db_unique_name, sl_key, prot_key, 
                                  reserved_space)
        VALUES (p_db_unique_name, l_sl_key, l_prot_key, l_space);
  END;
 
--
  IF l_poll_key IS NOT NULL THEN
    UPDATE poll
      SET poll_flags = poll_flags - 
                       BITAND(poll_flags,
                              DBMS_RA_SCHEDULER.POLL_FLAGS_UNDO_DBID_ERROR) +
                       DBMS_RA_SCHEDULER.POLL_FLAGS_UNDO_DBID_ERROR
      WHERE poll_key = l_poll_key;
  END IF;
 
--
  dbms_ra_int.verify_reserved_space(l_sl_key, TRUE);
 
--
  move_commit(l_sl_key);
 
--
  dbms_ra_scheduler.enqueue_verify_timer_task;
    
EXCEPTION
  WHEN MISSING_PARAM THEN
    IF l_missing_param IS NOT NULL THEN
      am_trace ('add_db: required parameter missing' ||
                 l_missing_param);
      sys.dbms_sys_error.raise_system_error(MISSING_PARAM_NUM,
                                            l_missing_param,
                                            FALSE);
    ELSE
      RAISE;
    END IF;
 
  WHEN OBJ_NOT_FOUND THEN
    ROLLBACK;
 
    am_trace ('add_db: ' || item_not_found(p_protection_policy_name,
                                           'protection policy'));
    sys.dbms_sys_error.raise_system_error  (OBJ_NOT_FOUND_NUM,
                                            p_protection_policy_name,
                                            'protection policy',
                                            FALSE);
 
  WHEN DUP_VAL_ON_INDEX THEN
    ROLLBACK;
 
    sys.dbms_sys_error.raise_system_error(DUP_NAME_NUM,
                                          p_db_unique_name,
                                          'db unique name',
                                          FALSE);
    
  WHEN OTHERS THEN
    ROLLBACK;
 
    am_trace ('add_db exception: ' ||
              ' db_unique_name:'   || p_db_unique_name          ||
              ' policy_name:'      || p_protection_policy_name  ||
              ' sl_key:'           || l_sl_key ||
              ' err:' || SQLERRM);
    RAISE;
END add_db_int;
--
PROCEDURE add_db (db_unique_name            IN VARCHAR2,
                  protection_policy_name    IN VARCHAR2,
                  reserved_space            IN VARCHAR2)
IS
  l_the                         NUMBER;
  c_protection_policy_name      prot.prot_name%TYPE;
  NUM_CONVERSION_ERROR_NATIVE   EXCEPTION; PRAGMA EXCEPTION_INIT (
  NUM_CONVERSION_ERROR_NATIVE,                     -06502        );
 
BEGIN
  lock_api(LOCKAPI_CREATE, 'add_db');
  
  l_the := dbms_ra_scheduler.add_to_task_history_table (
                  task_type => dbms_ra_scheduler.TASK_API_ADD_DB,
                  param     => 'add_db' ||
                   b_p('db_unique_name', db_unique_name, p_first=>TRUE) ||
                   b_p('protection_policy_name', protection_policy_name) ||
                   b_p('reserved_space', reserved_space, p_last=>TRUE));
  
  dbms_ra_int.canonicalize(protection_policy_name, 
                            c_protection_policy_name, 128);
  add_db_int (upper(db_unique_name),
              c_protection_policy_name,
              reserved_space);
  unlock_api(p_the_num=>l_the, p_results=>TRUE, p_docommit=>TRUE);
 
EXCEPTION
  WHEN NUM_CONVERSION_ERROR_NATIVE THEN
    rollback;
    unlock_api(p_the_num=>l_the, p_results=>FALSE, p_docommit=>TRUE);
    sys.dbms_sys_error.raise_system_error(NUM_CONVERSION_ERROR_NUM,
                                          reserved_space);
  WHEN OTHERS THEN
    rollback;
    unlock_api(p_the_num=>l_the, p_results=>FALSE, p_docommit=>TRUE);
    RAISE;
END add_db;
--
 
 
 
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE update_db_int (p_db_unique_name           IN VARCHAR2,
                         p_protection_policy_name   IN VARCHAR2 DEFAULT NULL,
                         p_reserved_space           IN VARCHAR2 DEFAULT NULL,
                         p_db_timezone              IN VARCHAR2 DEFAULT NULL,
                         p_incarnations             IN VARCHAR2 
                                                        DEFAULT 'CURRENT')
IS
  l_old_prot_key            NUMBER;
  l_prot_key                NUMBER;
  l_new_rep_srv_cnt         NUMBER;
  l_lib_key                 NUMBER;
  l_tmp_lib_key             NUMBER;
  l_db_key                  NUMBER := NULL;
  l_old_sl_key              NUMBER := NULL;
  l_sl_key                  NUMBER := NULL;
  l_rsvn                    NUMBER := 0;
  l_old_rsvn                NUMBER;
  l_move_phase              NUMBER := NULL;
  l_old_poll_key            NUMBER;
  l_poll_key                NUMBER;
  l_old_alloc               NUMBER;
  l_alloc                   NUMBER;
  l_recovery_window_goal    DSINTERVAL_UNCONSTRAINED;
  l_obj_type                VARCHAR2(128);
  l_obj_name                VARCHAR2(128);
  l_quota_name              VARCHAR2(128);
  l_unregistered_db         NUMBER := 0;
  l_not_taped_state         VARCHAR2(1);
  l_gcopy                   VARCHAR2(3) := NULL; -- Guaranteed Copy YES/NO/same
  l_disk_cache              VARCHAR2(3);
  l_invalid_val             VARCHAR2(256);
  l_rep_srv_name            server.rep_server_name%TYPE;
  l_db_unique_name          node.db_unique_name%TYPE;
  l_template_name           sbt_job_template.template_name%TYPE;
  l_prot_name               prot.prot_name%TYPE;
  l_prot_name_old           prot.prot_name%TYPE;
  l_task_rec                task%ROWTYPE;
  l_all_reconciled          BOOLEAN := TRUE;
  l_success                 BOOLEAN;
  l_num_rec                 NUMBER;
  l_rep_atr_name            sbt_attr_set.attr_name%TYPE;
  l_cnt                     NUMBER;
--
  l_tmz_err                 EXCEPTION;
  PRAGMA EXCEPTION_INIT(l_tmz_err, -20244);
BEGIN
 
  SELECT COUNT(*) INTO l_unregistered_db FROM unreg_database
    WHERE db_unique_name = p_db_unique_name;
 
  IF l_unregistered_db = 0 THEN
    l_quota_name := NULL;
 
    l_obj_type := 'db unique name';
    l_obj_name := p_db_unique_name;
    BEGIN
      SELECT db_key INTO l_db_key FROM node
        WHERE db_unique_name = p_db_unique_name
--
--
          AND NOT EXISTS (SELECT db_state
                            FROM odb
                           WHERE odb.db_key = node.db_key
                             AND db_state IS NOT NULL);
    EXCEPTION
      WHEN no_data_found THEN
        RAISE OBJ_NOT_FOUND;
    END;
 
    SELECT prot_key
      INTO l_old_prot_key
      FROM odb
      WHERE db_key = l_db_key;
    
--
    SELECT prot.sl_key, odb.base_reserved_space,
           odb.move_phase, prot.poll_key, sl_min_alloc,
           prot.prot_disk_cache, odb.not_taped_state
      INTO l_old_sl_key, l_rsvn,
           l_move_phase, l_old_poll_key, l_old_alloc,
           l_disk_cache, l_not_taped_state
      FROM odb
      JOIN prot USING (prot_key)
      WHERE odb.db_key = l_db_key;
  ELSE
    l_quota_name := p_db_unique_name;
    SELECT prot_key, prot.sl_key, u.reserved_space, prot.poll_key
      INTO l_old_prot_key, l_old_sl_key, l_rsvn, l_old_poll_key
      FROM unreg_database u
      JOIN prot USING (prot_key)
      WHERE u.db_unique_name = p_db_unique_name
        AND ROWNUM=1;
  END IF;
  
--
  IF p_protection_policy_name IS NOT NULL THEN
--
    l_obj_type := 'protection policy';
    l_obj_name := p_protection_policy_name;
    l_prot_name := p_protection_policy_name;
    BEGIN
      SELECT prot_key, sl_key, poll_key,
             prot_recovery_window_goal, prot_disk_cache
        INTO l_prot_key, l_sl_key, l_poll_key,
             l_recovery_window_goal, l_disk_cache
        FROM prot
        WHERE prot_name = p_protection_policy_name;
    EXCEPTION
      WHEN NO_DATA_FOUND THEN
        RAISE OBJ_NOT_FOUND;
    END;
  ELSE
    SELECT prot_key, prot_name, sl_key, poll_key,
           prot_recovery_window_goal, prot_disk_cache
      INTO l_prot_key, l_prot_name, l_sl_key, l_poll_key,
           l_recovery_window_goal, l_disk_cache
      FROM prot
      WHERE prot_key = l_old_prot_key;
  END IF;
 
--
  l_old_rsvn := l_rsvn;
  IF p_reserved_space IS NOT NULL THEN
    l_rsvn :=  numstring_to_num(p_reserved_space);
    IF l_rsvn < MIN_RESERVATION THEN
      am_trace('update_db: reserved_space ' || TO_CHAR(l_rsvn) ||
               ' less than MIN_RESERVATION ' || TO_CHAR(MIN_RESERVATION));
      sys.dbms_sys_error.raise_system_error(RSRVD_SPACE_TOO_SMALL_NUM,
                                            TO_CHAR(l_rsvn),
                                            TO_CHAR(MIN_RESERVATION),
                                            FALSE);
    END IF;
  END IF;
 
--
--
--
--
--
--
--
--
  IF (l_old_prot_key <> l_prot_key) AND (l_sl_key <>l_old_sl_key) THEN
--
--
    SELECT count(*)
      INTO l_cnt
      FROM sbt_job_template j, sbt_attr_set a, sbt_lib_desc l
      WHERE j.db_key = l_db_key
        AND j.attr_key = a.attr_key
        AND a.lib_key = l.lib_key
        AND l.server_key IS NULL;
    IF l_cnt > 0 THEN
      am_trace('update_db: aborting - existing tape jobs');
      RAISE SL_REP_SBT_CONFLICT_ERROR;
    END IF;
 
--
--
    SELECT COUNT (*)
      INTO l_cnt
      FROM (SELECT server_key FROM rep_server WHERE prot_key=l_old_prot_key
            MINUS
            SELECT server_key FROM rep_server WHERE prot_key=l_prot_key);
    IF l_cnt > 0 THEN
      am_trace('update_db: aborting - rep srvs in old not in new');
      RAISE SL_REP_SBT_CONFLICT_ERROR;
    END IF;
 
--
--
    SELECT COUNT (*)
      INTO l_cnt
      FROM (SELECT server_key FROM rep_server WHERE prot_key=l_prot_key
            MINUS
            SELECT server_key FROM rep_server WHERE prot_key=l_old_prot_key);
    IF l_cnt > 0 THEN
      am_trace('update_db: aborting - rep srvs in new not in old');
      RAISE SL_REP_SBT_CONFLICT_ERROR;
    END IF;
  END IF;
 
 
  IF l_unregistered_db = 1 THEN
    UPDATE unreg_database
      SET prot_key = l_prot_key,
          reserved_space = l_rsvn
      WHERE db_unique_name=p_db_unique_name;
 
--
    dbms_ra_int.verify_reserved_space(l_sl_key);
 
    COMMIT;
  ELSE
--
    SELECT sl_min_alloc INTO l_alloc
      FROM sl WHERE sl_key = l_sl_key;
 
--
    IF l_alloc != l_old_alloc THEN
      RAISE BAD_AU_SIZE;
    END IF;
 
--
    IF (l_not_taped_state IS NULL AND l_disk_cache = 'YES') THEN
      l_gcopy := 'YES';
    END IF;
 
--
    IF (l_not_taped_state IS NOT NULL AND l_disk_cache = 'NO') THEN
      l_gcopy := 'NO';
    END IF;
      
--
    IF (l_poll_key IS NOT NULL) AND (l_poll_key <> l_old_poll_key) THEN
      UPDATE poll
        SET poll_flags = poll_flags - 
                         BITAND(poll_flags,
                              DBMS_RA_SCHEDULER.POLL_FLAGS_UNDO_DBID_ERROR) +
                         DBMS_RA_SCHEDULER.POLL_FLAGS_UNDO_DBID_ERROR
        WHERE poll_key = l_poll_key;
    END IF;
 
--
--
    IF (l_sl_key = l_old_sl_key) AND
       ((l_move_phase IS NULL) OR 
        (l_move_phase = dbms_ra_scheduler.MOVE_PHASE_PEND)) THEN
      UPDATE odb
        SET prot_key = l_prot_key,
            future_prot_key = l_prot_key,
            reserved_space = l_rsvn,
            base_reserved_space = l_rsvn,
            not_taped = DECODE(l_gcopy,
                               'YES', used_space, -- If turned on set to used
                               not_taped),
            not_taped_state = DECODE(l_gcopy,
                                     'YES', 'I',   -- If turned on, Invalid
                                     'NO', NULL, -- If turned off, null
                                     not_taped_state),
            recovery_window_goal = l_recovery_window_goal
        WHERE db_key = l_db_key;
 
--
      IF l_rsvn <> l_old_rsvn THEN
        dbms_ra_int.verify_reserved_space(l_sl_key);
      END IF;
 
      COMMIT;
    ELSE
--
--
--
--
--
      UPDATE odb
        SET future_prot_key = l_prot_key,
            move_phase = NVL(move_phase,dbms_ra_scheduler.MOVE_PHASE_PEND),
            reserved_space = l_rsvn,
            base_reserved_space = l_rsvn,
            not_taped = DECODE(l_gcopy,
                               'YES', used_space, -- If turned on set to used
                               not_taped),
            not_taped_state = DECODE(l_gcopy,
                                     'YES', 'I',   -- If turned on, Invalid
                                     'NO', NULL, -- If turned off, null
                                     not_taped_state),
            recovery_window_goal = l_recovery_window_goal
        WHERE db_key = l_db_key;
 
--
      dbms_ra_int.verify_reserved_space(l_sl_key);
 
--
      move_commit(l_sl_key, NULL, l_db_key);
    END IF;
 
--
    IF l_gcopy = 'YES' THEN
      l_task_rec.task_type     := DBMS_RA_SCHEDULER.TASK_GCOPY_COMPUTE;
      l_task_rec.db_key        := l_db_key;
      l_task_rec.flags         := 0;
      DBMS_RA_SCHEDULER.NEW_TASK(l_task_rec);
    END IF;
 
--
    IF l_gcopy = 'NO' THEN
      dbms_ra_scheduler.release_blocked_tasks(
                              dbms_ra_scheduler.SPACE_PSEUDO_TASK, l_db_key);
 
      dbms_ra_scheduler.fix_error (
                 p_error_num => DBMS_RA_SCHEDULER.E_GCOPY_SUSPENDED_NUM,
                 p_db_key    => l_db_key);
    END IF;
 
--
--
    IF l_old_prot_key != l_prot_key THEN
--
--
      UPDATE odb
        SET last_replication = NULL,
            next_reconcile = NULL,
            last_reconcile = NULL,
            pending_rep_setup = NULL
        WHERE db_key = l_db_key;
      COMMIT;
 
--
      SELECT prot_name
        INTO l_prot_name_old
        FROM prot
        WHERE prot_key = l_old_prot_key;
 
--
      FOR s IN
        (SELECT rs.server_key, srv.rep_server_name
           FROM rep_server rs, server srv
          WHERE prot_key=l_old_prot_key
            AND srv.server_key = rs.server_key)
      LOOP
        l_template_name := dbms_ra_int.build_rep_tpl_name (
                                            rep_srv_name => s.rep_server_name,
                                            db_key       => l_db_key,
                                            prot_key     => l_old_prot_key);
        BEGIN
          remove_rep_tasks(p_db_key => l_db_key, p_template => l_template_name);
 
          delete_sbt_job_template_int(template_name  => l_template_name,
                                      do_commit => FALSE);
        EXCEPTION
          WHEN OBJ_NOT_FOUND THEN
--
            NULL;
        END;
      END LOOP;
      COMMIT;
 
--
--
      FOR rslst IN
        (SELECT server_key FROM rep_server WHERE prot_key=l_old_prot_key
         MINUS
         SELECT server_key FROM rep_server WHERE prot_key=l_prot_key) LOOP
 
        SELECT l.lib_key
          INTO l_tmp_lib_key
          FROM sbt_lib_desc l, server s
          WHERE l.server_key = s.server_key
            AND s.server_key = rslst.server_key;
        am_trace ('UPDATE_DB: Deleting backup piece records' ||
                  ' for ' || dbms_ra_int.dbkey2name(l_db_key));
        delete_replicated_backups(p_db_key      => l_db_key,
                                  p_sbt_lib_key => l_tmp_lib_key,
                                  p_force_del   => TRUE);
      END LOOP;
 
--
 
--
      SELECT COUNT(*) INTO l_new_rep_srv_cnt FROM
        (SELECT server_key FROM rep_server WHERE prot_key=l_prot_key
         MINUS
         SELECT server_key FROM rep_server WHERE prot_key=l_old_prot_key);
 
--
--
--
 
--
      UPDATE odb
        SET pending_rep_setup = 'Y'
        WHERE db_key = l_db_key;
      COMMIT;
 
--
      FOR s IN
        (SELECT server_key FROM rep_server WHERE prot_key=l_prot_key)
      LOOP
        SELECT rep_server_name
          INTO l_rep_srv_name
          FROM server
          WHERE server.server_key = s.server_key;
 
--
--
--
        SELECT lib_key INTO l_lib_key
          FROM sbt_lib_desc
          WHERE server_key = s.server_key;
        l_success := dbms_ra_scheduler.reconcile_db (
                                     p_db_key    => l_db_key,
                                     p_server_key   => s.server_key,
                                     p_only_active     => FALSE,
                                     p_force_reconcile => TRUE,
                                     rec_cnt           => l_num_rec);
        IF NOT l_success OR l_num_rec <> 1 THEN
          l_all_reconciled := FALSE;
          dbms_ra_scheduler.log_error(p_errno => dbms_ra.REP_SETUP_ERROR_NUM,
                          p_db_key  => l_db_key,
                          p_param1  => 'update_db_reconcile-' || l_prot_name,
                          p_param2  => l_rep_srv_name,
                          p_param3  => p_db_unique_name,
                          P_keep_stack => FALSE,
                          p_component =>'REPLICATION_RECONCILE',
                          p_severity => dbms_ra_scheduler.SEVERITY_ERROR,
                          p_param_char => 'RECONCILE');
        ELSE
--
--
          dbms_ra_scheduler.fix_error (
                                 p_error_num  => dbms_ra.REP_SETUP_ERROR_NUM,
                                 p_db_key     => l_db_key,
                                 p_param_char => 'RECONCILE');
--
--
          l_db_unique_name := dbms_ra_int.dbkey2name(l_db_key);
 
--
          dbms_ra_scheduler.queue_set_reconcile_timer (l_db_key);
 
--
--
          l_template_name := dbms_ra_int.build_rep_tpl_name (
                                              rep_srv_name => l_rep_srv_name,
                                              db_key       => l_db_key,
                                              prot_key     => l_prot_key);
 
          BEGIN
            l_rep_atr_name := dbms_ra_int.build_rep_atr_name(l_rep_srv_name);
            dbms_ra_int.create_sbt_job_template_int(
                                          template_name   => l_template_name,
                                          db_unique_name  => l_db_unique_name,
                                          attr_name       => l_rep_atr_name,
                                          backup_type     => 'ALL',
                                          do_commit       => TRUE);
          EXCEPTION
            WHEN DUP_NAME THEN
--
              NULL;
          END;
 
--
          UPDATE odb
            SET pending_rep_setup = 'N'
            WHERE db_key = l_db_key;
          COMMIT;
 
--
          IF l_new_rep_srv_cnt != 0 THEN
            dbms_ra_scheduler.replicate_existing_backups(
                                            p_template_name => l_template_name);
          END IF;
        END IF;
      END LOOP;
      COMMIT;
    END IF;
 
--
    IF l_disk_cache = 'NO' THEN
      dbms_ra_scheduler.release_blocked_tasks(
                              dbms_ra_scheduler.SPACE_PSEUDO_TASK, l_db_key);
    END IF;
  END IF;  -- IF l_unregistered_db = 1 
 
--
  IF (p_db_timezone IS NOT NULL) THEN
    dbms_rcvcat.addTimeZone(p_db_unique_name, 
                        p_db_timezone,
                        'A', 
                        p_incarnations);
  END IF;
 
     
EXCEPTION
  WHEN l_tmz_err THEN
     l_invalid_val := SUBSTR(SQLERRM, 1, 256);
     am_trace('update_db: raising INVALID_VAL ' || l_invalid_val); 
     l_invalid_val := SUBSTR(l_invalid_val, instr(l_invalid_val, ':'));
     sys.dbms_sys_error.raise_system_error(INVALID_VAL_NUM,
                                            l_invalid_val,
                                           FALSE);
  WHEN MISSING_INIT_REP_TYPE THEN
--
    am_trace ('update_db: intial replication parameter not defined');
    RAISE;
 
  WHEN OBJ_NOT_FOUND THEN
--
    IF l_obj_type IS NOT NULL THEN
      am_trace('update_db: ' || item_not_found(l_obj_name,l_obj_type));
      sys.dbms_sys_error.raise_system_error(OBJ_NOT_FOUND_NUM,
                                            l_obj_name,
                                            l_obj_type,
                                            FALSE);
    ELSE
      RAISE;
    END IF;
 
  WHEN OTHERS THEN
    ROLLBACK;
    am_trace ('update_db exception: ' || p_db_unique_name || ',' ||
              p_protection_policy_name || ', err:' || SQLERRM);
    RAISE;
 
END update_db_int;
--
PROCEDURE update_db (db_unique_name           IN VARCHAR2,
                     protection_policy_name   IN VARCHAR2 DEFAULT NULL,
                     reserved_space           IN VARCHAR2 DEFAULT NULL,
                     db_timezone              IN VARCHAR2 DEFAULT NULL,
                     incarnations             IN VARCHAR2 
                                                     DEFAULT 'CURRENT')
IS
  l_the                     NUMBER;
  c_protection_policy_name  prot.prot_name%TYPE;
  
BEGIN
  lock_api(LOCKAPI_MODIFY, 'update_db');
  
  l_the := dbms_ra_scheduler.add_to_task_history_table (
              task_type => dbms_ra_scheduler.TASK_API_UPD_DB,
              param     => 'update_db' ||
               b_p('db_unique_name', db_unique_name, p_first=>TRUE) ||
               b_p('protection_policy_name', protection_policy_name) ||
               b_p('reserved_space', reserved_space, p_last=>TRUE));
  
  dbms_ra_int.canonicalize(protection_policy_name, 
                            c_protection_policy_name, 128);
  update_db_int (upper(db_unique_name),
                 c_protection_policy_name,
                 reserved_space,
                 upper(db_timezone),
                 incarnations);
 
  unlock_api(p_the_num=>l_the, p_results=>TRUE, p_docommit=>TRUE);
  
EXCEPTION
  WHEN OTHERS THEN
    rollback;
    unlock_api(p_the_num=>l_the, p_results=>FALSE, p_docommit=>TRUE);
    RAISE;
END update_db;
--
 
 
 
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE delete_db_int (p_db_unique_name IN VARCHAR2,
                         p_wait IN BOOLEAN)
IS
  l_unreg_db  VARCHAR2(30);
  l_db_id     NUMBER := 0;
  l_db_key    NUMBER := NULL;
  l_obj_type  VARCHAR2(128);
  l_obj_name  VARCHAR2(128);
  l_task_rec  task%ROWTYPE;
  l_texists   NUMBER;
  l_count     NUMBER;
  l_error_num NUMBER;
  l_waiting   BOOLEAN := FALSE;
BEGIN
 
--
--
  BEGIN
    SELECT db_unique_name
      INTO l_unreg_db
      FROM unreg_database
      WHERE db_unique_name = p_db_unique_name
      FOR UPDATE OF db_unique_name;
  EXCEPTION
    WHEN NO_DATA_FOUND THEN
      l_unreg_db := NULL;
  END;
 
  IF l_unreg_db IS NOT NULL THEN
--
--
--
    revoke_db_access_int (NULL, p_db_unique_name);
    DELETE unreg_database
      WHERE db_unique_name=p_db_unique_name;
    COMMIT;
    RETURN;
  ELSE
--
    BEGIN
      l_obj_type := 'db unique name';
      l_obj_name := p_db_unique_name;
      SELECT db_key, db_id INTO l_db_key, l_db_id FROM db
        WHERE reg_db_unique_name = p_db_unique_name;
    EXCEPTION
      WHEN NO_DATA_FOUND THEN
        RAISE OBJ_NOT_FOUND;
    END;
  END IF;
 
--
  SELECT COUNT(*) INTO l_count
    FROM config
   WHERE config.name = '_recovery_appliance_state'
     AND config.value = 'OFF';
 
  IF l_count > 0 THEN
--
    RAISE CANT_DELETE_DB_DOWN;
  END IF;
 
--
  SELECT COUNT(*) INTO l_count
    FROM task t
   WHERE t.task_type = DBMS_RA_SCHEDULER.TASK_DELETE_DB
     AND db_key = l_db_key;
 
  IF l_count > 0 THEN
--
    sys.dbms_sys_error.raise_system_error(CANT_DELETE_DB_RUNNING_NUM,
                                          p_db_unique_name,
                                          FALSE);
  END IF;
 
--
  BEGIN
    dbms_ra_storage.lock_db (l_db_key);
 
--
--
--
--
--
    revoke_db_access_int (NULL, p_db_unique_name);
 
--
--
--
--
--
--
--
--
    UPDATE odb 
       SET db_state = DBMS_RA_SCHEDULER.DB_STATE_IN_DELETE
     WHERE db_key = l_db_key;
 
    COMMIT;
    dbms_ra_storage.unlock_db (l_db_key);
    am_trace ('delete_db: ' || p_db_unique_name ||
              ': database marked for delete');
  EXCEPTION
    WHEN OTHERS THEN
--
      dbms_ra_storage.unlock_db (l_db_key);
 
--
      am_trace('delete_db: ' || p_db_unique_name ||
               ': failed to mark database for delete');
      sys.dbms_sys_error.raise_system_error(E_INTERNAL_ERROR_NUM,
               'delete_db: ' || p_db_unique_name ||
               ': failed to mark database for delete',
               FALSE);
  END;
 
--
  l_task_rec.task_type     := DBMS_RA_SCHEDULER.TASK_DELETE_DB;
  l_task_rec.db_key        := l_db_key;
  l_task_rec.param_num1    := l_db_id;
  l_task_rec.param_char1   := p_db_unique_name;
  l_task_rec.flags         := 0;
 
  dbms_ra_scheduler.new_task(l_task_rec);
 
--
  IF p_wait THEN
--
--
--
--
    dbms_ra_int.info_start('DELETE_DB',
                           p_db_unique_name || ': waiting for completion');
    l_waiting := TRUE;
    LOOP
      SELECT COUNT(*) INTO l_texists
        FROM task
       WHERE task_id = l_task_rec.task_id;
      EXIT WHEN l_texists = 0;
 
--
      SELECT COUNT(*) INTO l_count
        FROM config
       WHERE config.name = '_recovery_appliance_state'
         AND config.value = 'OFF';
      IF l_count > 0 THEN
--
        RAISE CANT_DELETE_DB_DOWN;
      END IF;
 
--
      DBMS_LOCK.SLEEP(10);
    END LOOP;
    dbms_ra_int.info_end;
    l_waiting := FALSE;
 
--
--
    SELECT COUNT(*), MAX(error_num) INTO l_count, l_error_num
      FROM error_log
     WHERE task_id = l_task_rec.task_id;
 
    am_trace('delete_db: ' || p_db_unique_name || ': Found errors=' ||
             l_count || ', ' || pparm(l_error_num));
 
    IF l_count > 0 THEN
      sys.dbms_sys_error.raise_system_error(l_error_num,
                                            p_db_unique_name,
                                            FALSE);
    END IF;
 
--
--
    SELECT COUNT(*) INTO l_count
      FROM db
     WHERE db_key = l_db_key;
 
    IF l_count > 0 THEN
      am_trace('delete_db: ' || p_db_unique_name ||
               ': database has not been deleted,' ||
               ' delete task ' || l_task_rec.task_id);
 
--
      sys.dbms_sys_error.raise_system_error(CANT_DELETE_DB_NUM,
                                            p_db_unique_name,
                                            FALSE);
    END IF;
  END IF;
 
EXCEPTION
  WHEN OBJ_NOT_FOUND THEN
    IF l_waiting THEN
       dbms_ra_int.info_end;
    END IF;
 
--
    IF l_obj_type IS NOT NULL THEN
      am_trace('delete_db: ' ||  p_db_unique_name || ': ' ||
               item_not_found(l_obj_name,l_obj_type));
      sys.dbms_sys_error.raise_system_error(OBJ_NOT_FOUND_NUM,
                                            l_obj_name,
                                            l_obj_type,
                                            FALSE);
    ELSE
      RAISE;
    END IF;
 
  WHEN OTHERS THEN
    IF l_waiting THEN
       dbms_ra_int.info_end;
    END IF;
 
    am_trace ('delete_db exception: ' || p_db_unique_name || 
              ': err: ' ||SQLERRM);
    RAISE;
 
END delete_db_int;
--
PROCEDURE delete_db (db_unique_name IN VARCHAR2,
                     wait           IN BOOLEAN DEFAULT TRUE)
IS
  l_the         NUMBER;
  
BEGIN
  lock_api(LOCKAPI_DELETE, 'delete_db');
  
  l_the := dbms_ra_scheduler.add_to_task_history_table (
              task_type => dbms_ra_scheduler.TASK_API_DEL_DB,
              param     => 'delete_db' ||
                b_p('db_unique_name', db_unique_name, p_first=>TRUE) ||
                b_p('wait',           wait,           p_last=>TRUE));
  
  delete_db_int (upper(db_unique_name), wait);
  unlock_api(p_the_num=>l_the, p_results=>TRUE, p_docommit=>TRUE);
 
EXCEPTION
  WHEN OTHERS THEN
    rollback;
    unlock_api(p_the_num=>l_the, p_results=>FALSE, p_docommit=>TRUE);
    RAISE;
END delete_db;
--
 
 
 
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE rename_db_int (p_db_unique_name_old   IN VARCHAR2,
                         p_db_unique_name_new   IN VARCHAR2)
IS
  l_obj_type    VARCHAR2(128);
  l_obj_name    VARCHAR2(128);
  l_count       NUMBER;  
BEGIN
 
  UPDATE unreg_database
    SET   db_unique_name = p_db_unique_name_new
    WHERE db_unique_name = p_db_unique_name_old;
  
--
  IF SQL%ROWCOUNT = 0 THEN
    l_obj_type := 'db unique name';
    l_obj_name := p_db_unique_name_old;
    BEGIN
--
      SELECT COUNT(*) INTO l_count FROM node
        WHERE db_unique_name = p_db_unique_name_old
--
--
          AND NOT EXISTS (SELECT db_state
                            FROM odb
                           WHERE odb.db_key = node.db_key
                             AND db_state IS NOT NULL);
      IF l_count = 0 THEN
        RAISE OBJ_NOT_FOUND;
      END IF;
    END;
 
    dbms_rcvcat.renameSite(p_db_unique_name_old, p_db_unique_name_new);
  END IF;
 
  COMMIT;
 
EXCEPTION
 
  WHEN DUP_VAL_ON_INDEX THEN
    am_trace ('rename_db: object with name already exists' ||
              p_db_unique_name_new);
    sys.dbms_sys_error.raise_system_error(DUP_NAME_NUM,
                                          p_db_unique_name_new,
                                          'db unique name',
                                          FALSE);
 
  WHEN OBJ_NOT_FOUND THEN
--
    IF l_obj_type IS NOT NULL THEN
      am_trace('update_db: ' || item_not_found(l_obj_name,l_obj_type));
      sys.dbms_sys_error.raise_system_error(OBJ_NOT_FOUND_NUM,
                                            l_obj_name,
                                            l_obj_type,
                                            FALSE);
    ELSE
      RAISE;
    END IF;
 
  WHEN OTHERS THEN
    ROLLBACK;
    am_trace('rename_db exception: ' || p_db_unique_name_old ||
                       ', '          || p_db_unique_name_new ||
                       ', err:'      || SQLERRM);
    RAISE;
 
END rename_db_int;
--
PROCEDURE rename_db (db_unique_name_old   IN VARCHAR2,
                     db_unique_name_new   IN VARCHAR2)
IS
  l_the             NUMBER;
  
BEGIN
  lock_api(LOCKAPI_MODIFY, 'rename_db');
  
  l_the := dbms_ra_scheduler.add_to_task_history_table (
                  task_type => dbms_ra_scheduler.TASK_API_REN_DB,
                  param     => 'rename_db' ||
                   b_p('db_unique_name_old', db_unique_name_old, 
                          p_first=>TRUE) ||
                   b_p('db_unique_name_new', db_unique_name_new,
                          p_last=>TRUE));
 
  rename_db_int (upper(db_unique_name_old), upper(db_unique_name_new));
  unlock_api(p_the_num=>l_the, p_results=>TRUE, p_docommit=>TRUE);
 
EXCEPTION
  WHEN OTHERS THEN
    rollback;
    unlock_api(p_the_num=>l_the, p_results=>FALSE, p_docommit=>TRUE);
    RAISE;
END rename_db;
--
 
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE create_protection_policy_int (
            p_protection_policy_name   IN VARCHAR2,
            p_description              IN VARCHAR2 DEFAULT NULL,
            p_storage_location_name    IN VARCHAR2 DEFAULT NULL,
            p_polling_policy_name      IN VARCHAR2 DEFAULT NULL,
            p_recovery_window_goal     IN DSINTERVAL_UNCONSTRAINED,
            p_max_retention_window     IN DSINTERVAL_UNCONSTRAINED DEFAULT NULL,
            p_recovery_window_sbt      IN DSINTERVAL_UNCONSTRAINED DEFAULT NULL,
            p_unprotected_window       IN DSINTERVAL_UNCONSTRAINED DEFAULT NULL,
            p_guaranteed_copy          IN VARCHAR2 DEFAULT NULL)
IS
  l_sl_key                   NUMBER;
  l_poll_key                 NUMBER;
  l_prot_key                 NUMBER;
  l_numrows                  NUMBER;
  l_restore_compression      VARCHAR2(100);
  l_obj_name                 VARCHAR2(128);
  l_obj_type                 VARCHAR2(128);
  l_missing_param            VARCHAR2(128);
  l_invalid_val              VARCHAR2(128);
  l_algnm                    VARCHAR2(64) := NULL;
  l_cnt                      NUMBER;
 
BEGIN
 
--
--
  SELECT count(*)
    INTO l_numrows
    FROM prot
    WHERE prot.prot_name = p_protection_policy_name;
 
  IF l_numrows != 0 THEN
    RAISE DUP_VAL_ON_INDEX;
  END IF ;
 
--
--
  BEGIN
    IF p_storage_location_name IS NOT NULL THEN
--
--
      l_obj_name := p_storage_location_name;
      SELECT sl_key
        INTO l_sl_key
        FROM sl
        WHERE sl.sl_name = p_storage_location_name;
    ELSE
       l_missing_param := 'storage_location_name';
       RAISE MISSING_PARAM;
    END IF;
  EXCEPTION
    WHEN NO_DATA_FOUND THEN
      l_obj_type := 'storage location';
      RAISE OBJ_NOT_FOUND;
  END;
 
--
--
  BEGIN
    IF p_polling_policy_name IS NOT NULL THEN
--
--
      SELECT poll_key
        INTO l_poll_key
        FROM poll
        WHERE poll.poll_name = p_polling_policy_name;
    END IF;
  EXCEPTION
    WHEN NO_DATA_FOUND THEN
      l_obj_name := p_polling_policy_name;
      l_obj_type := 'polling policy';
      RAISE OBJ_NOT_FOUND;
  END;
 
--
--
--
--
  SELECT MIN(value) INTO l_restore_compression
    FROM config
    WHERE name = '_restore_compression';
 
  IF l_restore_compression IS NOT NULL AND l_restore_compression != 'OFF' THEN
    SELECT max(algorithm_name) INTO l_algnm
      FROM sys.v_$rman_compression_algorithm
      WHERE algorithm_name = 
            DECODE(l_restore_compression, 'BZIP2', 'BASIC',
                   'ZLIB', 'MEDIUM', l_restore_compression)
        AND is_valid = 'YES';
    IF l_algnm IS NULL THEN
      RAISE BAD_RECOMPR;
    END IF;
  END IF;
 
--
--
  IF p_max_retention_window IS NOT NULL AND
     p_max_retention_window < p_recovery_window_goal THEN
    l_invalid_val := 'max_retention_window';
    RAISE INVALID_VAL;
  END IF;
 
--
--
  IF p_guaranteed_copy != 'YES' AND p_guaranteed_copy != 'NO' THEN
     l_invalid_val := 'guaranteed_copy';
     RAISE INVALID_VAL;
  END IF;
  
--
  l_prot_key := rman_seq.nextval;
  INSERT INTO prot (prot_key,
                    prot_name,
                    prot_description,
                    sl_key,
                    poll_key,
                    prot_recovery_window_goal,
                    prot_max_retention_window,
                    prot_recovery_window_sbt,
                    prot_unprotected_window,
                    prot_out_compression,
                    prot_disk_cache)
   VALUES (l_prot_key,
           p_protection_policy_name,
           SUBSTR(p_description,1,128),
           l_sl_key,
           l_poll_key,
           p_recovery_window_goal,
           p_max_retention_window,
           p_recovery_window_sbt,
           p_unprotected_window,
           l_algnm,
           p_guaranteed_copy);
  
  COMMIT;
  
    
EXCEPTION
  WHEN MISSING_PARAM THEN
    IF l_missing_param IS NOT NULL THEN
      am_trace ('create_protection_policy: required parameter missing ' ||
                l_missing_param);
      sys.dbms_sys_error.raise_system_error(MISSING_PARAM_NUM,
                                            l_missing_param,
                                            FALSE);
    ELSE
      RAISE;
    END IF;
 
  WHEN INVALID_VAL THEN
    IF l_invalid_val IS NOT NULL THEN
      am_trace ('create_protection_policy: parameter value is invalid ' ||
                l_invalid_val);
      sys.dbms_sys_error.raise_system_error(INVALID_VAL_NUM,
                                            l_invalid_val,
                                            FALSE);
    ELSE
      RAISE;
    END IF;
 
  WHEN OBJ_NOT_FOUND THEN
--
    IF l_obj_type IS NOT NULL THEN
      am_trace ('create_protection_policy: ' || item_not_found(l_obj_name,
                                                               l_obj_type));
      sys.dbms_sys_error.raise_system_error(OBJ_NOT_FOUND_NUM,
                                            l_obj_name,
                                            l_obj_type,
                                            FALSE);
    ELSE
      RAISE;
    END IF;
 
  WHEN DUP_VAL_ON_INDEX THEN
    am_trace ('create_protection_policy: object with name already exists ' ||
              p_protection_policy_name);
    sys.dbms_sys_error.raise_system_error(DUP_NAME_NUM,
                                          p_protection_policy_name,
                                          'protection policy',
                                          FALSE);
 
  WHEN OTHERS THEN
    ROLLBACK;
    am_trace ('create_protection_policy exception: '  ||
              '  prot_key:'                 || l_prot_key                ||
              ', protection_policy_name:'   || p_protection_policy_name  ||
              ', description:'              || p_description             ||
              ', storage_loc_key:'          || l_sl_key                  ||
              ', polling policy key:'       || l_poll_key                ||
              ', p_recovery_window_goal:'   || p_recovery_window_goal    ||
              ', p_max_retention_window:'   || p_max_retention_window    ||
              ', recovery_window_sbt:'      || p_recovery_window_sbt     ||
              ', unprotected_window:'       || p_unprotected_window      ||
              ', err:' || SQLERRM);
    RAISE;
 
END create_protection_policy_int;
--
PROCEDURE create_protection_policy (
             protection_policy_name   IN VARCHAR2,
             description              IN VARCHAR2 DEFAULT NULL,
             storage_location_name    IN VARCHAR2,
             polling_policy_name      IN VARCHAR2 DEFAULT NULL,
             recovery_window_goal     IN DSINTERVAL_UNCONSTRAINED,
             max_retention_window     IN DSINTERVAL_UNCONSTRAINED DEFAULT NULL,
             recovery_window_sbt      IN DSINTERVAL_UNCONSTRAINED DEFAULT NULL,
             unprotected_window       IN DSINTERVAL_UNCONSTRAINED DEFAULT NULL,
             guaranteed_copy          IN VARCHAR2 DEFAULT 'NO')
IS
  l_the                      NUMBER;
  c_protection_policy_name   prot.prot_name%TYPE;
  c_polling_policy_name      poll.poll_name%TYPE;
  c_storage_location_name    sl.sl_name%TYPE;
BEGIN
  lock_api(LOCKAPI_CREATE, 'create_protection_policy');
  
  l_the := dbms_ra_scheduler.add_to_task_history_table (
               task_type => dbms_ra_scheduler.TASK_API_ADD_PROT_POLICY,
               param     => 'create_protection_policy' ||
                b_p('protection_policy_name', protection_policy_name, 
                       p_first=>TRUE) ||
                b_p('description',            description) ||
                b_p('storage_location_name',  storage_location_name) ||
                b_p('polling_policy_name',    polling_policy_name  ) ||
                b_p('recovery_window_goal',   recovery_window_goal  ) ||
                b_p('max_retention_window',   max_retention_window  ) ||
                b_p('recovery_window_sbt',    recovery_window_sbt) ||
                b_p('unprotected_window',     unprotected_window) ||
                b_p('guaranteed_copy',        guaranteed_copy,
                        p_last=>TRUE));
  
  dbms_ra_int.canonicalize(protection_policy_name, 
                            c_protection_policy_name, 128);
  dbms_ra_int.canonicalize(storage_location_name, 
                            c_storage_location_name, 128);
  dbms_ra_int.canonicalize(polling_policy_name, 
                            c_polling_policy_name, 128);
 
  create_protection_policy_int (c_protection_policy_name,
                                description,
                                c_storage_location_name,
                                c_polling_policy_name,
                                recovery_window_goal,
                                max_retention_window,
                                recovery_window_sbt,
                                unprotected_window,
                                upper(guaranteed_copy));
  unlock_api(p_the_num=>l_the, p_results=>TRUE, p_docommit=>TRUE);
 
EXCEPTION
  WHEN OTHERS THEN
    rollback;
    unlock_api(p_the_num=>l_the, p_results=>FALSE, p_docommit=>TRUE);
    RAISE;
END create_protection_policy;
--
 
 
 
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE update_protection_policy_int (
   p_protection_policy_name  IN VARCHAR2,
   p_description             IN VARCHAR2 DEFAULT NULL,
   p_storage_location_name   IN VARCHAR2 DEFAULT NULL,
   p_polling_policy_name     IN VARCHAR2,
   p_recovery_window_goal    IN DSINTERVAL_UNCONSTRAINED DEFAULT NULL,
   p_max_retention_window    IN DSINTERVAL_UNCONSTRAINED,
   p_recovery_window_sbt     IN DSINTERVAL_UNCONSTRAINED,
   p_unprotected_window      IN DSINTERVAL_UNCONSTRAINED,
   p_guaranteed_copy         IN VARCHAR2 DEFAULT NULL)
IS
  l_needmove                BOOLEAN := FALSE;
  l_prot_key                NUMBER;
  l_old_sl_key              NUMBER;
  l_sl_key                  NUMBER;
  l_poll_key                NUMBER;
  l_old_alloc               NUMBER;
  l_alloc                   NUMBER;
  l_recovery_window_goal    DSINTERVAL_UNCONSTRAINED;
  l_max_retention_window    DSINTERVAL_UNCONSTRAINED;
  l_obj_type                VARCHAR2(128);
  l_obj_name                VARCHAR2(128);
  l_invalid_val             VARCHAR2(128);
  l_polling_retdef          BOOLEAN := dbms_ra_int.isparamdef('p1');
  l_maxret_retdef           BOOLEAN := dbms_ra_int.isparamdef('p3');
  l_sbt_retdef              BOOLEAN := dbms_ra_int.isparamdef('p2');
  l_unprotected_window      BOOLEAN := dbms_ra_int.isparamdef('p4');
  l_restore_compression     VARCHAR2(100);
  l_algnm                   VARCHAR2(64) := NULL;
  l_cache_scn               NUMBER;
  l_cnt                     NUMBER;
  update_sbt_ret            VARCHAR2(1) := 'Y';
  update_polling_ret        VARCHAR2(1) := 'Y';
  update_unprot_win         VARCHAR2(1) := 'Y';  
  l_task_rec                task%ROWTYPE;
  
  CURSOR odbcur IS SELECT db_key
                     FROM odb
                     WHERE odb.prot_key = l_prot_key;
 
BEGIN
 
--
  BEGIN
    SELECT prot.prot_key, prot.sl_key, 
          prot.prot_recovery_window_goal, prot.prot_max_retention_window
      INTO l_prot_key, l_old_sl_key, 
           l_recovery_window_goal, l_max_retention_window
      FROM prot
      WHERE prot_name = p_protection_policy_name;
  EXCEPTION
    WHEN NO_DATA_FOUND THEN
      l_obj_type := 'protection policy';
      l_obj_name := p_protection_policy_name;
      RAISE OBJ_NOT_FOUND;
  END;
 
--
  IF p_storage_location_name IS NOT NULL THEN
    BEGIN
      SELECT sl_key, sl_min_alloc
        INTO l_sl_key, l_alloc
        FROM sl
        WHERE sl.sl_name = p_storage_location_name;
      SELECT sl_min_alloc INTO l_old_alloc
        FROM sl
        WHERE sl_key = l_old_sl_key;
 
--
      IF l_alloc != l_old_alloc THEN
        RAISE BAD_AU_SIZE;
      END IF;
    EXCEPTION
      WHEN NO_DATA_FOUND THEN
        l_obj_type := 'storage location';
        l_obj_name := p_storage_location_name;
        RAISE OBJ_NOT_FOUND;
    END;
  ELSE
    l_sl_key := l_old_sl_key;
  END IF;
 
--
  IF p_polling_policy_name IS NOT NULL THEN
--
    BEGIN
      SELECT poll_key
        INTO l_poll_key
        FROM poll
        WHERE poll.poll_name = p_polling_policy_name;
    EXCEPTION
      WHEN NO_DATA_FOUND THEN
        l_obj_type := 'polling policy';
        l_obj_name := p_polling_policy_name;
        RAISE OBJ_NOT_FOUND;
    END;
  ELSIF l_polling_retdef THEN
--
    update_polling_ret := NULL;
  END IF;
 
--
  IF p_recovery_window_goal IS NOT NULL THEN
    l_recovery_window_goal := p_recovery_window_goal; 
  END IF;
 
--
  IF NOT l_maxret_retdef THEN
    l_max_retention_window := p_max_retention_window; 
  END IF;
 
--
--
  IF l_max_retention_window IS NOT NULL AND
     l_max_retention_window < l_recovery_window_goal THEN
    IF p_max_retention_window IS NOT NULL THEN
      l_invalid_val := 'max_retention_window';
    ELSE
      l_invalid_val := 'recovery_window_goal';
    END IF;
    RAISE INVALID_VAL;
  END IF;
 
--
  IF l_sbt_retdef THEN
    update_sbt_ret := NULL;
  END IF;
 
--
  IF l_unprotected_window THEN
    update_unprot_win := NULL;
  END IF;
--
--
--
--
  SELECT MIN(value) INTO l_restore_compression
    FROM config
    WHERE name = '_restore_compression';
 
  IF l_restore_compression IS NULL THEN  -- Get original value
    SELECT prot_out_compression INTO l_algnm
      FROM prot
      WHERE prot.prot_name = p_protection_policy_name;
    COMMIT;
  ELSE                                   -- Verify provided value
    IF l_restore_compression = 'OFF' THEN
      l_algnm := NULL;
    ELSE
      SELECT max(algorithm_name) INTO l_algnm
        FROM sys.v_$rman_compression_algorithm
        WHERE algorithm_name = 
              DECODE(l_restore_compression, 'BZIP2', 'BASIC',
                     'ZLIB', 'MEDIUM', l_restore_compression)
          AND is_valid = 'YES';
      IF l_algnm IS NULL THEN
        RAISE BAD_RECOMPR;
      END IF;
    END IF;
  END IF;
 
--
--
  IF p_guaranteed_copy IS NOT NULL
  AND p_guaranteed_copy != 'YES' AND p_guaranteed_copy != 'NO' THEN
    l_invalid_val := 'guaranteed_copy';
    RAISE INVALID_VAL;
  END IF;
  
--
--
  UPDATE prot
    SET prot.prot_description = 
                NVL(SUBSTR(p_description,1,128), prot_description),
        prot.sl_key = l_sl_key,
        prot.poll_key = nvl2(update_polling_ret, l_poll_key, prot.poll_key),
        prot.prot_recovery_window_goal = l_recovery_window_goal,
        prot.prot_max_retention_window = l_max_retention_window,
        prot.prot_recovery_window_sbt =
        nvl2(update_sbt_ret,
             p_recovery_window_sbt, prot.prot_recovery_window_sbt),
        prot.prot_unprotected_window=
        nvl2(update_unprot_win,
             p_unprotected_window, prot.prot_unprotected_window),
        prot.prot_out_compression = l_algnm,
        prot.prot_disk_cache = nvl(p_guaranteed_copy, prot.prot_disk_cache)
    WHERE prot.prot_name = p_protection_policy_name;
 
--
--
  IF p_guaranteed_copy IS NOT NULL THEN
--
    UPDATE odb SET 
           not_taped = DECODE(p_guaranteed_copy,
                              'YES',      -- Turn it on
                              DECODE(not_taped_state, 'V', not_taped,
                                                      'I', not_taped,
                                                           used_space),
                              not_taped),
           not_taped_state = DECODE(p_guaranteed_copy,
                                    'YES',      -- Turn it on
                                    DECODE(not_taped_state, 'V', 'V',
                                                            'N', 'N', 'C'),
                                    'NO', NULL, -- Turn it off
                                    not_taped_state)
      WHERE future_prot_key = l_prot_key;
  END IF;
 
--
--
  IF l_sl_key != l_old_sl_key THEN
    UPDATE odb SET move_phase = dbms_ra_scheduler.MOVE_PHASE_PEND
      WHERE future_prot_key = l_prot_key
        AND move_phase IS NULL;
    l_needmove := TRUE;
  END IF;
 
--
  dbms_ra_int.verify_reserved_space(l_sl_key);
 
--
  IF p_polling_policy_name IS NOT NULL THEN
    UPDATE poll
      SET poll_flags = poll_flags - 
                       BITAND(poll_flags,
                              DBMS_RA_SCHEDULER.POLL_FLAGS_UNDO_DBID_ERROR) +
                       DBMS_RA_SCHEDULER.POLL_FLAGS_UNDO_DBID_ERROR
      WHERE poll_key = l_poll_key;
  END IF;
 
--
  IF p_recovery_window_goal IS NOT NULL THEN
    UPDATE odb 
      SET recovery_window_goal =  p_recovery_window_goal
      WHERE prot_key = l_prot_key; 
  END IF;
 
 
--
  IF l_needmove THEN
    move_commit(l_sl_key, l_prot_key);
  ELSE
    COMMIT;
  END IF;
 
--
  IF p_guaranteed_copy IS NOT NULL THEN
    FOR x IN (SELECT db_key, not_taped_state
              FROM odb
              WHERE prot_key = l_prot_key)
      LOOP
--
        IF p_guaranteed_copy = 'YES' AND x.not_taped_state IN ('I','C') THEN
          l_task_rec.task_type     := DBMS_RA_SCHEDULER.TASK_GCOPY_COMPUTE;
          l_task_rec.db_key        := x.db_key;
          l_task_rec.flags         := 0;
          DBMS_RA_SCHEDULER.NEW_TASK(l_task_rec);
 
--
          IF x.not_taped_state = 'C' THEN
            dbms_ra_scheduler.log_error (
                     p_errno => DBMS_RA_SCHEDULER.E_GCOPY_SUSPENDED_NUM,
                     p_param1 => dbms_ra_int.dbkey2name(x.db_key),
                     p_db_key => x.db_key,
                     p_keep_stack => FALSE,
                     p_component => 'UPDATE_POLICY',
                     p_severity  => DBMS_RA_SCHEDULER.SEVERITY_WARNING);
          END IF;
 
--
        ELSIF p_guaranteed_copy = 'NO' AND x.not_taped_state IS NULL THEN
          dbms_ra_scheduler.release_blocked_tasks(
                              dbms_ra_scheduler.SPACE_PSEUDO_TASK, x.db_key);
 
          dbms_ra_scheduler.fix_error (
                     p_error_num => DBMS_RA_SCHEDULER.E_GCOPY_SUSPENDED_NUM,
                     p_db_key    => x.db_key);
        END IF;
      END LOOP;
  END IF;
 
EXCEPTION
  WHEN OBJ_NOT_FOUND THEN
    ROLLBACK;
    IF l_obj_type IS NOT NULL THEN
      am_trace('update_protection_policy: ' ||
                  item_not_found(l_obj_name,l_obj_type));
      sys.dbms_sys_error.raise_system_error(OBJ_NOT_FOUND_NUM,
                                              l_obj_name,
                                              l_obj_type,
                                              FALSE);
    ELSE
      RAISE;
    END IF;
 
  WHEN INVALID_VAL THEN
    IF l_invalid_val IS NOT NULL then
      am_trace ('update_protection_policy: parameter value is invalid' ||
                l_invalid_val);
      sys.dbms_sys_error.raise_system_error(INVALID_VAL_NUM,
                                            l_invalid_val,
                                            FALSE);
    ELSE
      RAISE;
    END IF;
 
  WHEN INVALID_SIZENUMBER THEN
    ROLLBACK;
    am_trace ('update_protection_policy: Invalid size number' ||
              ' protection_policy_name:'   || p_protection_policy_name );
    RAISE;
 
  WHEN BAD_RECOMPR THEN
    ROLLBACK;
    am_trace ('update_protection_policy: Invalid' ||
              ' restore_compression: '   || l_restore_compression);
    RAISE;
 
  WHEN OTHERS THEN
    ROLLBACK;
    am_trace ('update_protection_policy exception:'  ||
              ' prot_key:'                 || l_prot_key                ||
              ', protection_policy_name:'  || p_protection_policy_name  ||
              ', description:'             || p_description             ||
              ', storage_loc_name:'        || p_storage_location_name   ||
              ', polling_policy_name:'     || p_polling_policy_name     ||
              ', recovery_window_goal:'    || p_recovery_window_goal    ||
              ', max_retention_window:'    || p_max_retention_window    ||
              ', recovery_window_sbt:'     || p_recovery_window_sbt     ||
              ', unprotected_window:'      || p_unprotected_window      ||
              ', err:' || SQLERRM);
    RAISE;
 
END update_protection_policy_int;
--
PROCEDURE update_protection_policy (
   protection_policy_name     IN VARCHAR2,
   description                IN VARCHAR2 DEFAULT NULL,
   storage_location_name      IN VARCHAR2 DEFAULT NULL,
   polling_policy_name        IN VARCHAR2 
                                 DEFAULT dbms_ra_int.varchar2null('p1'),
   recovery_window_goal       IN DSINTERVAL_UNCONSTRAINED DEFAULT NULL,
   max_retention_window       IN DSINTERVAL_UNCONSTRAINED
                                 DEFAULT dbms_ra_int.intervalnull('p3'),
   recovery_window_sbt        IN DSINTERVAL_UNCONSTRAINED
                                 DEFAULT dbms_ra_int.intervalnull('p2'),
   unprotected_window         IN DSINTERVAL_UNCONSTRAINED
                                 DEFAULT dbms_ra_int.intervalnull('p4'),
   guaranteed_copy            IN VARCHAR2 DEFAULT NULL)
IS
  l_the                      NUMBER;
  c_protection_policy_name   prot.prot_name%TYPE;
  c_polling_policy_name      poll.poll_name%TYPE;
  c_storage_location_name    sl.sl_name%TYPE;
 
BEGIN
  lock_api(LOCKAPI_MODIFY, 'update_protection_policy');
  
--
  l_the := dbms_ra_scheduler.add_to_task_history_table (
               task_type => dbms_ra_scheduler.TASK_API_UPD_PROT_POLICY,
               param     => 'update_protection_policy' ||
                b_p('protection_policy_name', protection_policy_name, 
                      p_first=>TRUE) ||
                b_p('description',            description)           ||
                b_p('storage_location_name',  storage_location_name) ||
                b_p('polling_policy_name',    polling_policy_name  ) ||
                b_p('recovery_window_goal',   recovery_window_goal  ) ||
                b_p('max_retention_window',   max_retention_window  ) ||
                b_p('recovery_window_sbt',    recovery_window_sbt ) ||
                b_p('unprotected_window',     unprotected_window ) ||
                b_p('guaranteed_copy',       guaranteed_copy, p_last=>TRUE));
  
  dbms_ra_int.canonicalize(protection_policy_name, 
                            c_protection_policy_name, 128);
  dbms_ra_int.canonicalize(storage_location_name, 
                            c_storage_location_name, 128);
  dbms_ra_int.canonicalize(polling_policy_name, 
                            c_polling_policy_name, 128);
 
  update_protection_policy_int (c_protection_policy_name,
                                description,
                                c_storage_location_name,
                                c_polling_policy_name,
                                recovery_window_goal,
                                max_retention_window,
                                recovery_window_sbt,
                                unprotected_window,
                                upper(guaranteed_copy));
  unlock_api(p_the_num=>l_the, p_results=>TRUE, p_docommit=>TRUE);
 
EXCEPTION
  WHEN OTHERS THEN
    rollback;
    unlock_api(p_the_num=>l_the, p_results=>FALSE, p_docommit=>TRUE);
    RAISE;
END update_protection_policy;
--
 
 
 
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE delete_protection_policy_int (p_protection_policy_name IN VARCHAR2)
IS
  l_prot_key                NUMBER := NULL;
  l_prot_cnt                NUMBER := NULL;
  l_odb_key                 NUMBER := NULL;
  l_odb_cnt                 NUMBER := NULL;
 
  CURSOR rep_server_cursor IS
    SELECT s.rep_server_name rep_server_name, p.prot_name prot_name
      FROM rep_server r, prot p, server s
      WHERE r.prot_key = l_prot_key
        AND s.server_key = r.server_key;
BEGIN
 
--
  BEGIN
    SELECT prot.prot_key
      INTO l_prot_key
      FROM prot
      WHERE prot_name = p_protection_policy_name;
  EXCEPTION
    WHEN NO_DATA_FOUND THEN
      RAISE OBJ_NOT_FOUND;
  END;
 
--
  SELECT count(*)
    INTO l_prot_cnt
    FROM odb
    WHERE odb.prot_key = l_prot_key ;
 
  IF l_prot_cnt = 0 THEN
--
    FOR f IN rep_server_cursor LOOP
      BEGIN
        remove_rep_from_prot_int(f.rep_server_name, f.prot_name, FALSE);
      EXCEPTION
        WHEN OBJ_NOT_FOUND THEN
--
          NULL;
      END;
    END LOOP;
 
    DELETE
      FROM prot
      WHERE prot_name = p_protection_policy_name;
  ELSE
    RAISE OBJ_IS_REFERENCED;
  END IF;
 
  COMMIT;
 
EXCEPTION
  WHEN OBJ_NOT_FOUND THEN
--
    am_trace ('delete_protection_policy: ' || item_not_found(
                                                p_protection_policy_name,
                                                'protection policy'));
    sys.dbms_sys_error.raise_system_error(OBJ_NOT_FOUND_NUM,
                                          p_protection_policy_name,
                                          'protection policy',
                                          FALSE);
 
  WHEN OBJ_IS_REFERENCED THEN
--
    am_trace ('delete_protection_policy: protection policy is referenced' ||
              ' protection_policy_name:'   || p_protection_policy_name);
    sys.dbms_sys_error.raise_system_error(OBJ_IS_REFERENCED_NUM,
                                          p_protection_policy_name,
                                          'protection policy', FALSE);
 
  WHEN OTHERS THEN
    ROLLBACK;
    am_trace ('delete_protection_policy exception: ' ||
              ' protection_policy_name:'   || p_protection_policy_name ||
              ' err:' || SQLERRM);
    RAISE;
 
END delete_protection_policy_int;
--
PROCEDURE delete_protection_policy (protection_policy_name IN VARCHAR2)
IS
  l_the                      NUMBER;
  c_protection_policy_name   prot.prot_name%TYPE;
 
BEGIN
  lock_api(LOCKAPI_DELETE, 'delete_protection_policy');
  
  l_the := dbms_ra_scheduler.add_to_task_history_table (
                task_type => dbms_ra_scheduler.TASK_API_DEL_PROT_POLICY,
                param     => 'delete_protection_policy' ||
                  b_p('protection_policy_name', protection_policy_name,
                         p_first=>TRUE, p_last=>TRUE));
 
  dbms_ra_int.canonicalize(protection_policy_name, 
                            c_protection_policy_name, 128);
  delete_protection_policy_int (c_protection_policy_name);
  unlock_api(p_the_num=>l_the, p_results=>TRUE, p_docommit=>TRUE);
 
EXCEPTION
  WHEN OTHERS THEN
    rollback;
    unlock_api(p_the_num=>l_the, p_results=>FALSE, p_docommit=>TRUE);
    RAISE;
END delete_protection_policy;
--
 
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE create_polling_policy_int (p_polling_policy_name   IN VARCHAR2,
                                     p_polling_location      IN VARCHAR2,
             p_polling_frequency DSINTERVAL_UNCONSTRAINED DEFAULT NULL,
             p_delete_input     BOOLEAN)
IS
  l_pol_key                 NUMBER;
  l_sl_key                  NUMBER;
  l_numrows                 NUMBER;
  l_polling_frequency       DSINTERVAL_UNCONSTRAINED;
  l_poll_flags              NUMBER := 0;
  l_delete_input            VARCHAR2(5);
  l_storage_location_name   sl.sl_name%TYPE;
 
BEGIN
 
--
--
  SELECT count(*)
    INTO l_numrows
    FROM poll
    WHERE poll.poll_name = p_polling_policy_name;
 
  IF l_numrows != 0 THEN
    RAISE DUP_VAL_ON_INDEX;
  END IF ;
 
--
  l_storage_location_name := 'AMPOLL$' || rman_seq.nextval;
  
--
--
  create_storage_location_int(
     p_storage_name        => l_storage_location_name,
     p_storage_dests       => p_polling_location,
     p_storage_for_poll    => TRUE);
 
--
--
  BEGIN
    SELECT sl_key
      INTO l_sl_key
      FROM sl
      WHERE sl.sl_name = l_storage_location_name
         OR sl.sl_name = l_storage_location_name || '/';
 
  EXCEPTION
    WHEN NO_DATA_FOUND THEN
      raise OBJ_NOT_FOUND;
  END;
 
  IF p_polling_frequency IS NOT NULL THEN
    l_polling_frequency := p_polling_frequency;
  ELSE
    SELECT numtodsinterval(value, 'day') INTO l_polling_frequency
      FROM config
     WHERE name = '_default_poll_frequency_days';
  END IF;
 
  IF p_delete_input THEN
    l_poll_flags := l_poll_flags + DBMS_RA_SCHEDULER.POLL_FLAGS_DELETE_INPUT;
    l_delete_input := 'TRUE';
  ELSIF p_delete_input IS NULL THEN
    l_delete_input := 'NULL';
  ELSE
    l_delete_input := 'FALSE';
  END IF;
  
--
  l_pol_key := rman_seq.nextval;
 
  INSERT
    INTO poll (poll_key,
               poll_name,
               sl_key,
               poll_flags,
               poll_freq,
               poll_last_prune)
    VALUES (l_pol_key,
            p_polling_policy_name,
            l_sl_key,
            l_poll_flags,
            l_polling_frequency,
            SYSTIMESTAMP);
 
--
  dbms_ra_scheduler.enqueue_verify_timer_task;
 
  COMMIT;
 
EXCEPTION
  WHEN OBJ_NOT_FOUND THEN
--
    am_trace ('create_polling_policy: ' || item_not_found(
                                              l_storage_location_name,
                                              'polling location'));
    sys.dbms_sys_error.raise_system_error(OBJ_NOT_FOUND_NUM,
                                          l_storage_location_name,
                                          'polling location',
                                          FALSE);
 
  WHEN DUP_VAL_ON_INDEX THEN
    am_trace ('create_polling_policy: object with name already exists' ||
               p_polling_policy_name);
    sys.dbms_sys_error.raise_system_error(DUP_NAME_NUM,
                                          p_polling_policy_name,
                                          'polling policy',
                                          FALSE);
 
  WHEN OTHERS THEN
    ROLLBACK;
    am_trace ('create_polling_policy exception: ' ||
              rman_seq.currval          || ', ' ||
              p_polling_policy_name     || ', ' ||
              l_storage_location_name   || ', ' ||
              l_polling_frequency       || ', ' ||
              l_delete_input            || ', ' ||
              ' err:' || SQLERRM);
    RAISE;
 
END create_polling_policy_int;
--
PROCEDURE create_polling_policy (
                        polling_policy_name   IN VARCHAR2,
                        polling_location      IN VARCHAR2,
                        polling_frequency DSINTERVAL_UNCONSTRAINED DEFAULT NULL,
                        delete_input BOOLEAN DEFAULT FALSE)
IS
  l_the                     NUMBER;
  c_polling_policy_name     poll.poll_name%TYPE;
 
BEGIN
  lock_api(LOCKAPI_CREATE, 'create_polling_policy');
  
  l_the := dbms_ra_scheduler.add_to_task_history_table (
                task_type => dbms_ra_scheduler.TASK_API_ADD_POLL_POLICY,
                param     => 'create_polling_policy' ||
                 b_p('polling_policy_name', polling_policy_name, 
                          p_first=>TRUE) ||
                 b_p('polling_location', polling_location) ||
                 b_p('polling_frequency', polling_frequency ) ||
                 b_p('delete_input',   delete_input , p_last=>TRUE));
  
  dbms_ra_int.canonicalize(polling_policy_name, c_polling_policy_name, 128);
 
  create_polling_policy_int (c_polling_policy_name,
                             polling_location,
                             polling_frequency,
                             delete_input);
  unlock_api(p_the_num=>l_the, p_results=>TRUE, p_docommit=>TRUE);
  
EXCEPTION
  WHEN OTHERS THEN
    rollback;
    unlock_api(p_the_num=>l_the, p_results=>FALSE, p_docommit=>TRUE);
    RAISE;
END create_polling_policy;
--
 
 
 
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE update_polling_policy_int (
                      p_polling_policy_name                        IN VARCHAR2,
                      p_polling_location              IN VARCHAR2 DEFAULT NULL,
                      p_polling_frequency DSINTERVAL_UNCONSTRAINED DEFAULT NULL,
                      p_delete_input                    BOOLEAN DEFAULT  NULL)
IS
  l_sl_key                  NUMBER  := NULL;
  l_poll_flags              NUMBER  := 0;
  l_numrows                 NUMBER  := 0;
  l_changes                 BOOLEAN := FALSE;
  l_obj_type                VARCHAR2(128);
  l_obj_name                VARCHAR2(128);
  l_delete_input            VARCHAR2(5);
  l_storage_location_name   sl.sl_name%TYPE;
  l_polling_location        storage_dests.dest%TYPE;
  l_sl_name                 sl.sl_name%TYPE;
BEGIN
 
--
  BEGIN
    SELECT poll_key, poll_flags, sl_key
      INTO l_numrows, l_poll_flags, l_sl_key
      FROM poll
      WHERE poll.poll_name = p_polling_policy_name;
  EXCEPTION
    WHEN NO_DATA_FOUND THEN
      l_obj_type := 'polling policy';
      l_obj_name := p_polling_policy_name;
      RAISE OBJ_NOT_FOUND;
  END;
 
--
  IF p_polling_location IS NOT NULL THEN
--
    l_polling_location := p_polling_location;
    IF SUBSTR(p_polling_location, -1, 1) != '/' THEN
      l_polling_location := l_polling_location || '/';
    END IF;
 
--
    SELECT MIN(sl_name) INTO l_sl_name
      FROM sl JOIN storage_dests sd USING (sl_key)
      WHERE (sd.dest = SUBSTR(l_polling_location, 1, LENGTH(sd.dest))
         OR l_polling_location 
                              = SUBSTR(sd.dest, 1, LENGTH(l_polling_location)))
        AND sl_key <> l_sl_key;
 
    IF l_sl_name IS NOT NULL THEN
      SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(E_SHARED_PARAMS_NUM, l_sl_name);
    END IF;
 
    UPDATE storage_dests SET dest = l_polling_location
      WHERE sl_key = l_sl_key;
 
    l_changes := TRUE;
  END IF;
 
--
  IF p_polling_frequency IS NOT NULL THEN
    UPDATE poll
      SET poll.poll_freq = p_polling_frequency
      WHERE poll.poll_name = p_polling_policy_name;
    l_changes := TRUE;
  END IF;
 
--
  IF p_delete_input IS NOT NULL THEN
    l_poll_flags := l_poll_flags - 
                    BITAND(l_poll_flags, 
                           DBMS_RA_SCHEDULER.POLL_FLAGS_DELETE_INPUT);
    IF p_delete_input THEN
      l_poll_flags := l_poll_flags + DBMS_RA_SCHEDULER.POLL_FLAGS_DELETE_INPUT;
      l_delete_input := 'TRUE';
    ELSE
      l_delete_input := 'FALSE';
    END IF;
 
    UPDATE poll
      SET poll.poll_flags = l_poll_flags
      WHERE poll.poll_name = p_polling_policy_name;
    l_changes := TRUE;
  ELSE
    l_delete_input := 'NULL';
  END IF;
  
--
  IF l_changes = TRUE THEN
--
    dbms_ra_scheduler.enqueue_verify_timer_task;
    COMMIT;
  END IF;
 
EXCEPTION
  WHEN OBJ_NOT_FOUND THEN
 
--
    IF l_obj_type IS NOT NULL THEN
      am_trace('update_polling_policy: ' ||
                  item_not_found(l_obj_name,l_obj_type));
      sys.dbms_sys_error.raise_system_error(OBJ_NOT_FOUND_NUM,
                                            l_obj_name,
                                            l_obj_type,
                                            FALSE);
    ELSE
      RAISE;
    END IF;
 
  WHEN OTHERS THEN
    ROLLBACK;
    am_trace ('update_polling_policy exception: ' ||
              p_polling_policy_name   || ', ' ||
              p_polling_location || ', ' ||
              p_polling_frequency     || ', ' ||
              l_delete_input  || ', ' ||
              ' err:' || SQLERRM);
    RAISE;
 
END update_polling_policy_int;
--
PROCEDURE update_polling_policy (
                        polling_policy_name   IN VARCHAR2,
                        polling_location      IN VARCHAR2,
                        polling_frequency     IN DSINTERVAL_UNCONSTRAINED 
                                                                DEFAULT NULL,
                        delete_input          IN BOOLEAN DEFAULT NULL)
IS
  l_the                     NUMBER;
  c_polling_policy_name     poll.poll_name%TYPE;
 
BEGIN
  lock_api(LOCKAPI_MODIFY, 'update_polling_policy');
  
  l_the := dbms_ra_scheduler.add_to_task_history_table (
                  task_type => dbms_ra_scheduler.TASK_API_UPD_POLL_POLICY,
                  param     => 'update_polling_policy' ||
                   b_p('polling_policy_name', polling_policy_name, 
                         p_first=>TRUE) ||
                   b_p('polling_location ', polling_location      ) ||
                   b_p('polling_frequency', polling_frequency     ) ||
                   b_p('delete_input',  delete_input, p_last=>TRUE));
                         
  dbms_ra_int.canonicalize(polling_policy_name, c_polling_policy_name, 128);
 
  update_polling_policy_int (c_polling_policy_name,
                             polling_location,
                             polling_frequency,
                             delete_input);
  unlock_api(p_the_num=>l_the, p_results=>TRUE, p_docommit=>TRUE);
  
EXCEPTION
  WHEN OTHERS THEN
    rollback;
    unlock_api(p_the_num=>l_the, p_results=>FALSE, p_docommit=>TRUE);
    RAISE;
END update_polling_policy;
--
 
 
 
 
--
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE delete_polling_policy_int (p_polling_policy_name IN VARCHAR2)
IS
  l_poll_key                 NUMBER := 0;
  l_storage_location_name    sl.sl_name%TYPE;
 
BEGIN
 
--
  BEGIN
    SELECT poll_key
      INTO l_poll_key
      FROM poll
      WHERE poll.poll_name = p_polling_policy_name;
  EXCEPTION
    WHEN NO_DATA_FOUND THEN
      RAISE OBJ_NOT_FOUND;
  END;
  
--
  SELECT sl.sl_name INTO l_storage_location_name
    FROM sl, poll
    WHERE poll.poll_name = p_polling_policy_name
      AND poll.sl_key = sl.sl_key;
 
--
  UPDATE prot
    SET poll_key = NULL
    WHERE poll_key = l_poll_key;
 
--
  DELETE FROM error_log
    WHERE error_num IN (DBMS_RA_SCHEDULER.E_BAD_FILE_NUM)
      AND param_num = l_poll_key;
 
--
  DELETE
    FROM poll
    WHERE poll_name = p_polling_policy_name;
 
--
  delete_storage_location_int(l_storage_location_name);
 
--
--
  dbms_ra_scheduler.enqueue_verify_timer_task;
 
  COMMIT;
 
EXCEPTION
  WHEN OBJ_NOT_FOUND THEN
    am_trace('delete_polling_policy: ' ||
                item_not_found(p_polling_policy_name,'polling policy'));
    sys.dbms_sys_error.raise_system_error(OBJ_NOT_FOUND_NUM,
                                          p_polling_policy_name,
                                          'polling policy',
                                          FALSE);
 
  WHEN OTHERS THEN
    ROLLBACK;
    am_trace ('delete_polling_policy exception: ' ||
              ' poll_name:'             || p_polling_policy_name ||
              ' err:' || SQLERRM);
    RAISE;
 
END delete_polling_policy_int;
--
PROCEDURE delete_polling_policy (polling_policy_name IN VARCHAR2)
IS
  l_the                     NUMBER;
  c_polling_policy_name     poll.poll_name%TYPE;
  
BEGIN
  lock_api(LOCKAPI_DELETE, 'delete_polling_policy');
  
  l_the := dbms_ra_scheduler.add_to_task_history_table (
                  task_type => dbms_ra_scheduler.TASK_API_DEL_POLL_POLICY,
                  param     => 'delete_polling_policy' ||
                   b_p('polling_policy_name', polling_policy_name, 
                            p_first=>TRUE, p_last=>TRUE));
 
  dbms_ra_int.canonicalize(polling_policy_name, c_polling_policy_name, 128);
  delete_polling_policy_int (c_polling_policy_name);
  unlock_api(p_the_num=>l_the, p_results=>TRUE, p_docommit=>TRUE);
  
EXCEPTION
  WHEN OTHERS THEN
    rollback;
    unlock_api(p_the_num=>l_the, p_results=>FALSE, p_docommit=>TRUE);
    RAISE;
END delete_polling_policy;
--
 
 
 
--
--
--
 
--
--
--
--
 
PROCEDURE create_sbt_library_int(
  lib_name        IN VARCHAR2,
  drives          IN NUMBER,
  restore_drives  IN NUMBER   DEFAULT 0,
  parms           IN VARCHAR2 DEFAULT NULL,
  send            IN VARCHAR2 DEFAULT NULL,
  server_key      IN NUMBER   DEFAULT NULL,
  p_status        IN VARCHAR2 DEFAULT 'R',
  do_commit       IN BOOLEAN  DEFAULT TRUE)
IS
   l_drives              NUMBER      := drives;
   l_dynamic_drives      VARCHAR2(1) := 'N';
BEGIN
  IF (server_key IS NOT NULL AND l_drives IS NULL) THEN
     l_dynamic_drives := 'Y';
     l_drives := dbms_ra_int.sbt_default_drives;
  END IF;
 
  IF (l_drives <= 0 OR l_drives IS NULL) THEN
    am_trace('create_sbt_library: num drives too small: ' ||
             TO_CHAR(l_drives));
    sys.dbms_sys_error.raise_system_error(NUM_DRIVES_TOO_SMALL_NUM, FALSE);
  END IF;
 
  IF (restore_drives < 0 OR restore_drives IS NULL) THEN
    am_trace('create_sbt_library: num restore drives too small: ' ||
             TO_CHAR(restore_drives));
    sys.dbms_sys_error.raise_system_error(NUM_RDRIVES_TOO_SMALL_NUM, FALSE);
  END IF;
 
  IF (restore_drives >= l_drives) THEN
    am_trace('create_sbt_library: num restore drives ' ||
             TO_CHAR(restore_drives) ||
             ' >= total num drives ' || TO_CHAR(l_drives));
    sys.dbms_sys_error.raise_system_error(NUM_RDRIVES_TOO_LARGE_NUM,
                                          TO_CHAR(restore_drives),
                                          TO_CHAR(l_drives),
                                          FALSE);
  END IF;
  
--
  INSERT INTO sbt_lib_desc
    (lib_key, lib_name, drives, restore_drives, parms, send,
     server_key, status, failure_cnt, dynamic_drives)
    VALUES
    (rman_seq.nextval, lib_name, l_drives, restore_drives, parms, send, 
     server_key, p_status, 0, l_dynamic_drives);
   
  IF do_commit THEN
    COMMIT;
  END IF;
 
EXCEPTION
  WHEN DUP_VAL_ON_INDEX THEN
    sys.dbms_sys_error.raise_system_error
    (DUP_NAME_NUM, lib_name, 'sbt library', FALSE);
END create_sbt_library_int;
 
--
PROCEDURE create_sbt_library(
  lib_name        IN VARCHAR2,
  drives          IN NUMBER,
  restore_drives  IN NUMBER   DEFAULT 0,
  parms           IN VARCHAR2 DEFAULT NULL,
  send            IN VARCHAR2 DEFAULT NULL)
IS
  l_the             NUMBER;
  c_lib_name        sbt_lib_desc.lib_name%TYPE;
  
BEGIN
  lock_api(LOCKAPI_CREATE, 'create_sbt_library');
  
  l_the := dbms_ra_scheduler.add_to_task_history_table (
                 task_type => dbms_ra_scheduler.TASK_API_ADD_SBT_LIB,
                   param   => 'create_sbt_library' ||
                   b_p('lib_name',        lib_name, p_first=>TRUE) ||
                   b_p('drives',          drives                 ) ||
                   b_p('restore_drives',  restore_drives         ) ||
                   b_p('parms',           parms                  ) ||
                   b_p('send',            send , p_last=>TRUE    ));
  
  dbms_ra_int.canonicalize(lib_name, c_lib_name, 128);
  
  create_sbt_library_int(
                     c_lib_name,
                     drives,
                     restore_drives, 
                     parms, 
                     send);
  unlock_api(p_the_num=>l_the, p_results=>TRUE, p_docommit=>TRUE);
  
EXCEPTION
  WHEN OTHERS THEN
    rollback;
    unlock_api(p_the_num=>l_the, p_results=>FALSE, p_docommit=>TRUE);
    RAISE;
END create_sbt_library;
 
 
--
PROCEDURE update_sbt_library_int(
   lib_name        IN VARCHAR2,
   drives          IN NUMBER   DEFAULT NULL,
   restore_drives  IN NUMBER   DEFAULT NULL,
   parms           IN VARCHAR2 DEFAULT dbms_ra_int.varchar2null('p1'),
   send            IN VARCHAR2 DEFAULT dbms_ra_int.varchar2null('p2'),
   dynamic_drives  IN VARCHAR2 DEFAULT 'N')
IS
   parmsdef         BOOLEAN    := dbms_ra_int.isparamdef('p1');
   senddef          BOOLEAN    := dbms_ra_int.isparamdef('p2');
   l_drives_in      NUMBER     := drives;
   update_parms     VARCHAR2(1):= 'Y';
   update_send      VARCHAR2(1):= 'Y';
   l_lib_key        NUMBER;
   l_restore_drives NUMBER;
   l_streams        NUMBER;
   l_drives_out     NUMBER;
BEGIN
   
   IF (parmsdef) THEN
      update_parms := NULL;
   END IF;
 
   IF (senddef) THEN
      update_send := NULL;
   END IF;
 
   IF (dynamic_drives = 'Y') THEN
      l_drives_in := dbms_ra_int.sbt_default_drives;
   END IF;
 
   IF (l_drives_in IS NOT NULL AND l_drives_in <= 0) THEN
      am_trace('update_sbt_library: num drives too small: ' ||
               TO_CHAR(l_drives_in));
      sys.dbms_sys_error.raise_system_error(NUM_DRIVES_TOO_SMALL_NUM, FALSE);
   END IF;
 
   IF (restore_drives < 0) THEN
      am_trace('update_sbt_library: num restore drives too small: ' ||
               TO_CHAR(restore_drives));
      sys.dbms_sys_error.raise_system_error(NUM_RDRIVES_TOO_SMALL_NUM, FALSE);
   END IF;
   
   UPDATE sbt_lib_desc lib SET
      lib.drives =
         nvl(update_sbt_library_int.l_drives_in, lib.drives),
      lib.restore_drives =
         nvl(update_sbt_library_int.restore_drives, lib.restore_drives),
      lib.parms =
         nvl2(update_parms, update_sbt_library_int.parms, lib.parms),
      lib.send =
         nvl2(update_send, update_sbt_library_int.send, lib.send),
      lib.dynamic_drives = update_sbt_library_int.dynamic_drives
    WHERE lib.lib_name = update_sbt_library_int.lib_name
    RETURNING lib_key, drives, restore_drives
         INTO l_lib_key, l_drives_out, l_restore_drives;
 
--
   IF (sql%rowcount = 0) THEN
      am_trace('update_sbt_library: ' ||
                  item_not_found(lib_name, 'sbt library'));
      sys.dbms_sys_error.raise_system_error
       (OBJ_NOT_FOUND_NUM, lib_name, 'sbt library', FALSE);
   END IF;
 
   SELECT max(streams) INTO l_streams
     FROM sbt_attr_set
    WHERE lib_key = l_lib_key;
 
   IF (l_streams > l_drives_out) THEN
      am_trace('update_sbt_library: num streams ' || TO_CHAR(l_streams) ||
               ' > num drives ' || TO_CHAR(l_drives_out));
      sys.dbms_sys_error.raise_system_error(NUM_STREAMS_TOO_LARGE_NUM,
                                            TO_CHAR(l_streams),
                                            TO_CHAR(l_drives_out),
                                            FALSE);
   END IF;
 
   IF (l_restore_drives >= l_drives_out) THEN
      am_trace('update_sbt_library: num restore drives ' ||
               TO_CHAR(l_restore_drives) ||
               ' >= total num drives ' || TO_CHAR(l_drives_out));
      sys.dbms_sys_error.raise_system_error(NUM_RDRIVES_TOO_LARGE_NUM,
                                            TO_CHAR(l_restore_drives),
                                            TO_CHAR(l_drives_out),
                                            FALSE);
   END IF;
END update_sbt_library_int;
--
PROCEDURE update_sbt_library(
   lib_name        IN VARCHAR2,
   drives          IN NUMBER   DEFAULT NULL,
   restore_drives  IN NUMBER   DEFAULT NULL,
   parms           IN VARCHAR2 DEFAULT dbms_ra_int.varchar2null('p1'),
   send            IN VARCHAR2 DEFAULT dbms_ra_int.varchar2null('p2'))
IS
  l_the         NUMBER;
  c_lib_name    sbt_lib_desc.lib_name%TYPE;
 
BEGIN
  lock_api(LOCKAPI_MODIFY, 'update_sbt_library');
  
  l_the := dbms_ra_scheduler.add_to_task_history_table (
                 task_type => dbms_ra_scheduler.TASK_API_UPD_SBT_LIB,
                 param     => 'update_sbt_library' ||
                   b_p('lib_name',        lib_name, p_first=>TRUE) ||
                   b_p('drives',          drives                 ) ||
                   b_p('restore_drives',  restore_drives         ) ||
                   b_p('parms',           parms                  ) ||
                   b_p('send',            send , p_last=>TRUE));
 
  dbms_ra_int.canonicalize(lib_name, c_lib_name, 128);
  update_sbt_library_int(
                         c_lib_name,
                         drives,
                         restore_drives,
                         parms,
                         send,
                         'N');
  unlock_api(p_the_num=>l_the, p_results=>TRUE, p_docommit=>TRUE);
EXCEPTION
  WHEN OTHERS THEN
    rollback;
    unlock_api(p_the_num=>l_the, p_results=>FALSE, p_docommit=>TRUE);
    RAISE;
END update_sbt_library;
 
--
--
PROCEDURE update_bps_for_delete_lib_int(p_db_key     IN NUMBER,
                                        p_lib_key    IN VARCHAR2)
IS
  l_dbid            NUMBER;
  CURSOR
  bp_c (p_db_key IN NUMBER) IS
     SELECT bp.rowid bp_rowid, bp.bp_key, bs.bs_key
       FROM bp, bs
      WHERE bp.db_key = bp_c.p_db_key
        AND bp.bs_key = bs.bs_key
        AND bp.lib_key = p_lib_key
        FOR UPDATE OF bp.bp_key, bs.bs_key ORDER BY BS.BS_KEY;
  bpRec             bp_c%ROWTYPE;
BEGIN
--
--
--
--
--
  am_trace('update_bps_for_delete: locking db_key: ' || p_db_key);
  SELECT db_id INTO l_dbid FROM db WHERE db_key = p_db_key
    FOR UPDATE OF db.db_key;
 
--
  OPEN bp_c(p_db_key);
  FETCH bp_c into bpRec;
 
--
  DELETE FROM sbt_catalog ct
    WHERE ct.bp_key IS NOT NULL
      AND ct.ftype = 'T'
      AND ct.db_key = p_db_key
      AND EXISTS (SELECT 1 FROM bp
                  WHERE bp.bp_key = ct.bp_key
                  AND bp.lib_key = p_lib_key
                  AND bp.db_key = p_db_key
                  AND bp.lib_key IS NOT NULL);
  am_trace('update_bps_for_delete: deleted sbt_catalog rows: ' ||
           sql%rowcount);
 
--
--
  UPDATE bp
    SET ba_access = 'U'
    ,lib_key   = NULL
    ,ct_key    = NULL
    ,purged    = 'U'
    WHERE lib_key = p_lib_key
      AND bp.db_key = p_db_key;
  am_trace('update_bps_for_delete: updated bp rows: ' || sql%rowcount);
 
  CLOSE bp_c;
END;
 
--
PROCEDURE delete_sbt_library_int(lib_name   IN VARCHAR2,
                                 do_commit  IN BOOLEAN DEFAULT TRUE)
IS
  l_lib_key         NUMBER;
  l_not_taped_state VARCHAR2(1);
BEGIN
  SELECT lib.lib_key INTO l_lib_key
    FROM sbt_lib_desc lib
   WHERE lib.lib_name = delete_sbt_library_int.lib_name;
 
  FOR dbrec IN (SELECT DISTINCT db_key FROM sbt_catalog ct
                  WHERE ct.bp_key IS NOT NULL
                    AND ct.ftype = 'T'
                    AND EXISTS (SELECT 1 FROM bp
                                  WHERE bp.bp_key = ct.bp_key
                                    AND bp.lib_key = l_lib_key
                                    AND bp.lib_key IS NOT NULL)
                  ORDER BY db_key) LOOP
 
--
    update_bps_for_delete_lib_int(p_db_key  => dbrec.db_key,
                                  p_lib_key => l_lib_key);
 
--
--
    SELECT not_taped_state INTO l_not_taped_state
      FROM odb WHERE db_key = dbrec.db_key;
 
    IF l_not_taped_state IS NOT NULL THEN
      UPDATE odb SET not_taped_state = 'C' WHERE db_key = dbrec.db_key;
      dbms_ra_scheduler.log_error (
                     p_errno => DBMS_RA_SCHEDULER.E_GCOPY_SUSPENDED_NUM,
                     p_param1 => dbms_ra_int.dbkey2name(dbrec.db_key),
                     p_db_key => dbrec.db_key,
                     p_keep_stack => FALSE,
                     p_component => 'UPDATE_POLICY',
                     p_severity  => DBMS_RA_SCHEDULER.SEVERITY_WARNING);
    END IF;
  END LOOP;
 
--
  DELETE FROM sbt_lib_desc lib
    WHERE lib.lib_key = l_lib_key;
 
--
   IF do_commit THEN
     COMMIT;
   END IF;
EXCEPTION
   WHEN NO_DATA_FOUND THEN
      am_trace('delete_sbt_library: ' ||
                  item_not_found(lib_name, 'sbt library'));
     sys.dbms_sys_error.raise_system_error
       (OBJ_NOT_FOUND_NUM, lib_name, 'sbt library', FALSE);
END delete_sbt_library_int;
--
PROCEDURE delete_sbt_library(lib_name IN VARCHAR2)
IS
  l_the             NUMBER;
  c_lib_name        sbt_lib_desc.lib_name%TYPE;
  
BEGIN
  dbms_ra_int.canonicalize(lib_name, c_lib_name, 128);
  IF is_rep_server(c_lib_name) THEN
    sys.dbms_sys_error.raise_system_error
       (API_BAD_OBJECT_NUM, 'replication server', 'sbt library', FALSE);
  END IF;
 
  lock_api(LOCKAPI_DELETE, 'delete_sbt_library');
  l_the := dbms_ra_scheduler.add_to_task_history_table (
                task_type => dbms_ra_scheduler.TASK_API_DEL_SBT_LIB,
                param     => 'delete_sbt_library' ||
                   b_p('lib_name',  lib_name, p_first=>TRUE, p_last=>TRUE));
 
  delete_sbt_library_int(c_lib_name);
  unlock_api(p_the_num=>l_the, p_results=>TRUE, p_docommit=>TRUE);
  
EXCEPTION
  WHEN OTHERS THEN
    rollback;
    unlock_api(p_the_num=>l_the, p_results=>FALSE, p_docommit=>TRUE);
    RAISE;
END delete_sbt_library;
   
--
PROCEDURE pause_sbt_library_int(lib_name IN VARCHAR2)
IS
BEGIN
  UPDATE sbt_lib_desc lib
     SET lib.status = 'P',
         lib.failure_cnt = 0
    WHERE lib.lib_name = pause_sbt_library_int.lib_name;
 
--
  IF (sql%rowcount = 0) THEN
    am_trace('pause_sbt_library: ' ||
                item_not_found(lib_name, 'sbt library'));
    sys.dbms_sys_error.raise_system_error
      (OBJ_NOT_FOUND_NUM, lib_name, 'sbt library', FALSE);
  END IF;
 
--
  COMMIT;
 
END pause_sbt_library_int;
--
PROCEDURE pause_sbt_library(lib_name IN VARCHAR2)
IS
  l_the             NUMBER;
  c_lib_name        sbt_lib_desc.lib_name%TYPE;
  
BEGIN
  dbms_ra_int.canonicalize(lib_name, c_lib_name, 128);
  IF is_rep_server(c_lib_name) THEN
    sys.dbms_sys_error.raise_system_error
       (API_BAD_OBJECT_NUM, 'replication server', 'sbt library', FALSE);
  END IF;
 
  lock_api(LOCKAPI_MODIFY, 'pause_sbt_library');
  
  l_the := dbms_ra_scheduler.add_to_task_history_table (
             task_type => dbms_ra_scheduler.TASK_API_PAU_SBT_LIB,
             param     => 'pause_sbt_library' ||
              b_p('lib_name', lib_name, p_first=>TRUE, p_last=>TRUE));
 
  pause_sbt_library_int(c_lib_name);
  unlock_api();
  
EXCEPTION
  WHEN OTHERS THEN
    unlock_api();
    RAISE;
END pause_sbt_library;
 
 
--
PROCEDURE resume_sbt_library_int(lib_name IN VARCHAR2)
IS
  l_lib_key       NUMBER;
  l_server_key    NUMBER;
BEGIN
  
  UPDATE sbt_lib_desc lib
     SET lib.status = 'R',
         lib.failure_cnt = 0
    WHERE lib.lib_name = resume_sbt_library_int.lib_name
   RETURNING lib_key, server_key
        INTO l_lib_key, l_server_key;
 
--
  IF (sql%rowcount = 0) THEN
    am_trace('resume_sbt_library: ' ||
                item_not_found(lib_name, 'sbt library'));
    sys.dbms_sys_error.raise_system_error
      (OBJ_NOT_FOUND_NUM, lib_name, 'sbt library', FALSE);
  END IF;
 
--
--
--
  dbms_ra_scheduler.queue_spawn_sbt(
     p_libkey     => l_lib_key,
     p_forpurge   => NULL,
     p_check_work => TRUE); 
 
  IF (l_server_key IS NOT NULL) THEN
     dbms_ra_scheduler.reset_reconcile_timer;
  END IF;
 
--
  COMMIT;
 
--
--
--
--
  dbms_ra_scheduler.release_blocked_tasks(
                                    dbms_ra_scheduler.LIBRARY_PSEUDO_TASK);
END resume_sbt_library_int;
--
PROCEDURE resume_sbt_library(lib_name IN VARCHAR2)
IS
  l_the             NUMBER;
  c_lib_name        sbt_lib_desc.lib_name%TYPE;
 
BEGIN
  dbms_ra_int.canonicalize(lib_name, c_lib_name, 128);
  IF is_rep_server(c_lib_name) THEN
    sys.dbms_sys_error.raise_system_error
       (API_BAD_OBJECT_NUM, 'replication server', 'sbt library', FALSE);
  END IF;
 
  lock_api(LOCKAPI_MODIFY, 'resume_sbt_library');
  
  l_the := dbms_ra_scheduler.add_to_task_history_table (
             task_type => dbms_ra_scheduler.TASK_API_RES_SBT_LIB,
             param     => 'resume_sbt_library' ||
              b_p('lib_name', lib_name, p_first=>TRUE, p_last=>TRUE));
  
  dbms_ra_int.canonicalize(lib_name, c_lib_name, 128);
  resume_sbt_library_int(c_lib_name);
  unlock_api();
EXCEPTION
  WHEN OTHERS THEN
    unlock_api();
    RAISE;
END resume_sbt_library;
 
 
--
PROCEDURE set_restrict_sbt_instance_int(lib_name      IN VARCHAR2,
                                        instance_name IN VARCHAR2)
IS
   l_lib_key        NUMBER;
   doexists         NUMBER;
   upper_inst       sbt_library_inst_rlist.instance_name%TYPE;
 
BEGIN
  
  SELECT lib.lib_key INTO l_lib_key
    FROM sbt_lib_desc lib
    WHERE lib.lib_name = set_restrict_sbt_instance_int.lib_name;
 
--
   upper_inst := upper(instance_name);
 
   MERGE INTO sbt_library_inst_rlist rlist
      USING dual
      ON
      (
         rlist.lib_key = l_lib_key AND
         rlist.instance_name = upper_inst
      )
      WHEN NOT MATCHED THEN
         INSERT (lib_key, instance_name)
         VALUES (l_lib_key, upper_inst);
 
--
   COMMIT;
 
EXCEPTION
  WHEN NO_DATA_FOUND THEN
    am_trace('set_restrict_sbt_instance: ' ||
                item_not_found(lib_name, 'sbt library'));
    sys.dbms_sys_error.raise_system_error
         (OBJ_NOT_FOUND_NUM, lib_name, 'sbt library', FALSE);
END set_restrict_sbt_instance_int;
--
PROCEDURE set_restrict_sbt_instance(lib_name      IN VARCHAR2,
                                    instance_name IN VARCHAR2)
IS
  l_the         NUMBER;
  c_lib_name    sbt_lib_desc.lib_name%TYPE;
  
BEGIN
  dbms_ra_int.canonicalize(lib_name, c_lib_name, 128);
  IF is_rep_server(c_lib_name) THEN
    sys.dbms_sys_error.raise_system_error
       (API_BAD_OBJECT_NUM, 'replication server', 'sbt library', FALSE);
  END IF;
 
  lock_api(LOCKAPI_CREATE, 'set_restrict_sbt_instance');
  
  l_the := dbms_ra_scheduler.add_to_task_history_table (
                task_type => dbms_ra_scheduler.TASK_API_ADD_RESTRICT_SBT_INST,
                param     => 'set_restrict_sbt_instance' ||
                  b_p('lib_name',      lib_name, p_first=>TRUE) ||
                  b_p('instance_name', instance_name , p_last=>TRUE));
  
  set_restrict_sbt_instance_int(c_lib_name,
                                instance_name);
  unlock_api(p_the_num=>l_the, p_results=>TRUE, p_docommit=>TRUE);
EXCEPTION
  WHEN OTHERS THEN
    rollback;
    unlock_api(p_the_num=>l_the, p_results=>FALSE, p_docommit=>TRUE);
    RAISE;
END set_restrict_sbt_instance;
 
 
--
--
--
PROCEDURE clear_restrict_sbt_inst_int(lib_name      IN VARCHAR2,
                                      instance_name IN VARCHAR2)
IS
  l_lib_key  NUMBER;
  upper_inst sbt_library_inst_rlist.instance_name%TYPE;
 
BEGIN
  
  SELECT lib.lib_key INTO l_lib_key
    FROM sbt_lib_desc lib
    WHERE lib.lib_name = clear_restrict_sbt_inst_int.lib_name;
 
--
  upper_inst := upper(instance_name);
  
  DELETE FROM sbt_library_inst_rlist rlist
    WHERE rlist.lib_key = l_lib_key
      AND rlist.instance_name = upper_inst;
 
--
  IF (sql%rowcount = 0) THEN
    am_trace('clear_restrict_sbt_instance: ' ||
                item_not_found(upper_inst, 'instance name'));
    sys.dbms_sys_error.raise_system_error
      (OBJ_NOT_FOUND_NUM, upper_inst, 'instance name', FALSE);
  END IF;
  
--
  COMMIT;
   
EXCEPTION
  WHEN NO_DATA_FOUND THEN
    am_trace('clear_restrict_sbt_instance: ' ||
                item_not_found(lib_name, 'sbt library'));
    sys.dbms_sys_error.raise_system_error
           (OBJ_NOT_FOUND_NUM, lib_name, 'sbt library', FALSE);
END clear_restrict_sbt_inst_int;
--
PROCEDURE clear_restrict_sbt_instance(lib_name      IN VARCHAR2,
                                      instance_name IN VARCHAR2)
IS
  l_lib_key     NUMBER;
  upper_inst    sbt_library_inst_rlist.instance_name%TYPE;
  l_the         NUMBER;
  c_lib_name    sbt_lib_desc.lib_name%TYPE;
  
BEGIN
  dbms_ra_int.canonicalize(lib_name, c_lib_name, 128);
  IF is_rep_server(c_lib_name) THEN
    sys.dbms_sys_error.raise_system_error
       (API_BAD_OBJECT_NUM, 'replication server', 'sbt library', FALSE);
  END IF;
 
  lock_api(LOCKAPI_DELETE, 'clear_restrict_sbt_instance');
  
  l_the := dbms_ra_scheduler.add_to_task_history_table (
                task_type => dbms_ra_scheduler.TASK_API_DEL_RESTRICT_SBT_INST,
                param     => 'clear_restrict_sbt_instance' ||
                   b_p('lib_name',      lib_name, p_first=>TRUE) ||
                   b_p('instance_name', instance_name , p_last=>TRUE));
  
  clear_restrict_sbt_inst_int(c_lib_name,
                              instance_name);
  unlock_api(p_the_num=>l_the, p_results=>TRUE, p_docommit=>TRUE);
EXCEPTION
  WHEN OTHERS THEN
    rollback;
    unlock_api(p_the_num=>l_the, p_results=>FALSE, p_docommit=>TRUE);
    RAISE;
END clear_restrict_sbt_instance;
 
 
 
--
PROCEDURE create_sbt_attr_set_int(
             lib_name             IN VARCHAR2,
             attr_name            IN VARCHAR2,
             streams              IN NUMBER   DEFAULT NULL,
             poolid               IN NUMBER   DEFAULT NULL,
             parms                IN VARCHAR2 DEFAULT NULL,
             send                 IN VARCHAR2 DEFAULT NULL,
             do_commit            IN BOOLEAN  DEFAULT TRUE)
IS
  l_lib_key        NUMBER;
  l_drives         NUMBER;
 
BEGIN
  SELECT lib.lib_key, lib.drives INTO l_lib_key, l_drives
    FROM sbt_lib_desc lib
    WHERE lib.lib_name = create_sbt_attr_set_int.lib_name;
 
  IF (streams <= 0) THEN
     am_trace('create_sbt_attr_set: num streams too small: ' ||
              TO_CHAR(streams));
     sys.dbms_sys_error.raise_system_error(NUM_STREAMS_TOO_SMALL_NUM, FALSE);
  END IF;
  IF (streams > l_drives) THEN
     am_trace('create_sbt_attr_set: num streams ' || TO_CHAR(streams) ||
              ' larger than num drives ' || TO_CHAR(l_drives));
     sys.dbms_sys_error.raise_system_error(NUM_STREAMS_TOO_LARGE_NUM,
                                           TO_CHAR(streams),
                                           TO_CHAR(l_drives),
                                           FALSE);
  END IF;
  
--
  INSERT INTO sbt_attr_set
    (lib_key, attr_key, attr_name, streams,
     poolid, parms, send)
    VALUES
    (l_lib_key, rman_seq.nextval, attr_name, streams,
     poolid, parms, send);
  
  IF do_commit THEN 
--
    COMMIT;
  END IF;
   
 
EXCEPTION
 
  WHEN NO_DATA_FOUND THEN
    am_trace('create_sbt_attr_set: ' ||
                item_not_found(lib_name, 'sbt library'));
    sys.dbms_sys_error.raise_system_error
    (OBJ_NOT_FOUND_NUM, lib_name, 'sbt library', FALSE);
 
  WHEN DUP_VAL_ON_INDEX THEN
    sys.dbms_sys_error.raise_system_error
    (DUP_NAME_NUM, attr_name, 'sbt attribute set', FALSE);
END create_sbt_attr_set_int;
--
PROCEDURE create_sbt_attribute_set(
             lib_name             IN VARCHAR2,
             attribute_set_name   IN VARCHAR2,
             streams              IN NUMBER   DEFAULT NULL,
             poolid               IN NUMBER   DEFAULT NULL,
             parms                IN VARCHAR2 DEFAULT NULL,
             send                 IN VARCHAR2 DEFAULT NULL)
IS
  l_the         NUMBER;
  c_lib_name    sbt_lib_desc.lib_name%TYPE;
  c_attr_name   sbt_attr_set.attr_name%TYPE;
  
BEGIN
  dbms_ra_int.canonicalize(lib_name, c_lib_name, 128);
  IF is_rep_server(c_lib_name) THEN
    sys.dbms_sys_error.raise_system_error
       (API_BAD_OBJECT_NUM, 'replication server', 'sbt library', FALSE);
  END IF;
 
  lock_api(LOCKAPI_CREATE, 'create_sbt_attribute_set');
 
  l_the := dbms_ra_scheduler.add_to_task_history_table (
                  task_type => dbms_ra_scheduler.TASK_API_ADD_SBT_ATTR_SET,
                  param     => 'create_sbt_attribute_set' ||
                   b_p('lib_name',        lib_name, p_first=>TRUE) ||
                   b_p('attribute_set_name', attribute_set_name  ) ||
                   b_p('streams',         streams                ) ||
                   b_p('poolid',          poolid                 ) ||
                   b_p('parms',           parms                  ) ||
                   b_p('send',            send, p_last=>TRUE));
 
  dbms_ra_int.canonicalize(attribute_set_name, c_attr_name, 128);
 
  create_sbt_attr_set_int(
                            c_lib_name,
                            c_attr_name,
                            streams,
                            poolid,
                            parms,
                            send);
  unlock_api(p_the_num=>l_the, p_results=>TRUE, p_docommit=>TRUE);
EXCEPTION
  WHEN OTHERS THEN
    rollback;
    unlock_api(p_the_num=>l_the, p_results=>FALSE, p_docommit=>TRUE);
    RAISE;
END create_sbt_attribute_set;
 
 
 
--
PROCEDURE update_sbt_attr_set_int(
   attr_name       IN VARCHAR2,
   streams         IN NUMBER   DEFAULT dbms_ra_int.number2null('p1'),
   poolid          IN NUMBER   DEFAULT NULL,
   parms           IN VARCHAR2 DEFAULT dbms_ra_int.varchar2null('p2'),
   send            IN VARCHAR2 DEFAULT dbms_ra_int.varchar2null('p3'))
IS
   streamsdef       BOOLEAN     := dbms_ra_int.isparamdef('p1');
   parmsdef         BOOLEAN     := dbms_ra_int.isparamdef('p2');
   senddef          BOOLEAN     := dbms_ra_int.isparamdef('p3');
   update_streams   VARCHAR2(1) := 'Y';
   update_parms     VARCHAR2(1) := 'Y';
   update_send      VARCHAR2(1) := 'Y';
   l_streams        NUMBER;
   l_drives         NUMBER;
   l_lib_key        NUMBER;
BEGIN
   IF (streamsdef) THEN
      update_streams := NULL;
   END IF;
 
   IF (parmsdef) THEN
      update_parms := NULL;
   END IF;
 
   IF (senddef IS NULL) THEN
      update_send := NULL;
   END IF;
 
   IF (streams <= 0) THEN
     am_trace('update_sbt_attr_set: num streams too small: ' ||
              TO_CHAR(streams));
     sys.dbms_sys_error.raise_system_error(NUM_STREAMS_TOO_SMALL_NUM, FALSE);
   END IF;
 
 
   UPDATE sbt_attr_set attr SET
      attr.streams =
         nvl2(update_streams, update_sbt_attr_set_int.streams, attr.streams),
      attr.poolid =
         nvl(update_sbt_attr_set_int.poolid, attr.poolid),
      attr.parms =
         nvl2(update_parms, update_sbt_attr_set_int.parms, attr.parms),
      attr.send =
         nvl2(update_send, update_sbt_attr_set_int.send, attr.send)
    WHERE attr.attr_name = update_sbt_attr_set_int.attr_name
    RETURNING streams, lib_key
         INTO l_streams, l_lib_key;
 
--
   IF (sql%rowcount = 0) THEN
      am_trace('update_sbt_attr_set: ' ||
                  item_not_found(attr_name, 'sbt attribute set'));
      sys.dbms_sys_error.raise_system_error
       (OBJ_NOT_FOUND_NUM, attr_name, 'sbt attribute set', FALSE);
   END IF;
 
   SELECT lib.drives INTO l_drives
     FROM sbt_lib_desc lib
     WHERE lib.lib_key = l_lib_key;
 
   IF (l_streams > l_drives) THEN
     am_trace('update_sbt_attr: num streams ' || TO_CHAR(l_streams) ||
              ' larger than num drives ' || TO_CHAR(l_drives));
     sys.dbms_sys_error.raise_system_error(NUM_STREAMS_TOO_LARGE_NUM,
                                           TO_CHAR(l_streams),
                                           TO_CHAR(l_drives),
                                           FALSE);
   END IF;
 
--
   COMMIT;
END update_sbt_attr_set_int;
--
PROCEDURE update_sbt_attribute_set(
   attribute_set_name IN VARCHAR2,
   streams            IN NUMBER   DEFAULT dbms_ra_int.number2null('p1'),
   poolid             IN NUMBER   DEFAULT NULL,
   parms              IN VARCHAR2 DEFAULT dbms_ra_int.varchar2null('p2'),
   send               IN VARCHAR2 DEFAULT dbms_ra_int.varchar2null('p3'))
IS
  l_the         NUMBER;
  c_attr_name   sbt_attr_set.attr_name%TYPE;
  
BEGIN
  lock_api(LOCKAPI_MODIFY, 'update_sbt_attribute_set');
  
  l_the := dbms_ra_scheduler.add_to_task_history_table (
        task_type => dbms_ra_scheduler.TASK_API_UPD_SBT_ATTR_SET,
        param     => 'update_sbt_attribute_set' ||
        b_p('attribute_set_name', attribute_set_name, p_first=>TRUE) ||
        b_p('streams',         streams                )  ||
        b_p('poolid',          poolid                 )  ||
        b_p('parms',           parms                  )  ||
        b_p('send',            send     , p_last=>TRUE));
  
  dbms_ra_int.canonicalize(attribute_set_name, c_attr_name, 128);
 
  update_sbt_attr_set_int(
                            c_attr_name,
                            streams,
                            poolid,
                            parms,
                            send);
  unlock_api(p_the_num=>l_the, p_results=>TRUE, p_docommit=>TRUE);
EXCEPTION
  WHEN OTHERS THEN
    rollback;
    unlock_api(p_the_num=>l_the, p_results=>FALSE, p_docommit=>TRUE);
    RAISE;
END update_sbt_attribute_set;
 
      
--
PROCEDURE delete_sbt_attr_set_int(attr_name  IN VARCHAR2,
                                  do_commit  IN BOOLEAN DEFAULT TRUE)
IS
 
BEGIN
  
   DELETE FROM sbt_attr_set attr
    WHERE attr.attr_name = delete_sbt_attr_set_int.attr_name;
 
--
   IF (sql%rowcount = 0) THEN
      am_trace('delete_sbt_attr_set: ' ||
                  item_not_found(attr_name, 'sbt attribute set'));
      sys.dbms_sys_error.raise_system_error
         (OBJ_NOT_FOUND_NUM, attr_name, 'sbt attribute set', FALSE);
   END IF;
   
   IF do_commit THEN
--
     COMMIT;
   END IF;
 
END delete_sbt_attr_set_int;
--
PROCEDURE delete_sbt_attribute_set(attribute_set_name IN VARCHAR2)
IS
  l_the             NUMBER;
  c_attr_name       sbt_attr_set.attr_name%TYPE;
 
BEGIN
  dbms_ra_int.canonicalize(attribute_set_name, c_attr_name, 128);
  IF is_rep_server(c_attr_name) THEN
    sys.dbms_sys_error.raise_system_error
       (API_BAD_OBJECT_NUM, 'replication server', 'sbt attribute', FALSE);
  END IF;
 
  lock_api(LOCKAPI_DELETE, 'delete_sbt_attribute_set');
  
  l_the := dbms_ra_scheduler.add_to_task_history_table (
       task_type => dbms_ra_scheduler.TASK_API_DEL_SBT_ATTR_SET,
       param     => 'delete_sbt_library' ||
       b_p('attribute_set_name', attribute_set_name, p_first=>TRUE,
             p_last=>TRUE));
 
  delete_sbt_attr_set_int(c_attr_name);
  unlock_api(p_the_num=>l_the, p_results=>TRUE, p_docommit=>TRUE);
EXCEPTION
  WHEN OTHERS THEN
    rollback;
    unlock_api(p_the_num=>l_the, p_results=>FALSE, p_docommit=>TRUE);
    RAISE;
END delete_sbt_attribute_set;
 
 
--
PROCEDURE create_sbt_job_template(
   template_name          IN VARCHAR2,
   protection_policy_name IN VARCHAR2,
   attribute_set_name     IN VARCHAR2,
   backup_type            IN VARCHAR2,
   full_template_name     IN VARCHAR2 DEFAULT NULL,
   from_tag               IN VARCHAR2 DEFAULT NULL,
   priority               IN NUMBER DEFAULT SBT_PRIORITY_MEDIUM,
   copies                 IN NUMBER DEFAULT 1,
   window                 IN DSINTERVAL_UNCONSTRAINED DEFAULT NULL)
IS
  l_the                 NUMBER;
  c_attr_name           sbt_attr_set.attr_name%TYPE;
  c_prot_name           prot.prot_name%TYPE;
  c_template_name       sbt_job_template.template_name%TYPE;
  c_full_template_name  sbt_job_template.template_name%TYPE;
  c_from_tag            sbt_job_template.from_tag%TYPE;
BEGIN
  dbms_ra_int.canonicalize(attribute_set_name, c_attr_name, 128);
  IF is_rep_server(c_attr_name) THEN
    sys.dbms_sys_error.raise_system_error
       (API_BAD_OBJECT_NUM, 'replication server', 'sbt job template', FALSE);
  END IF;
 
  lock_api(LOCKAPI_CREATE, 'create_sbt_job_template');
  l_the := dbms_ra_scheduler.add_to_task_history_table (
                  task_type => dbms_ra_scheduler.TASK_API_ADD_SBT_JOB,
                  param     => 'create_sbt_job_template' ||
                   b_p('template_name', template_name, p_first=>TRUE) ||
                   b_p('protection_policy_name', protection_policy_name) ||
                   b_p('attribute_set_name', attribute_set_name) ||
                   b_p('backup_type', backup_type                  ) ||
                   b_p('full_template_name', full_template_name) ||
                   b_p('from_tag', from_tag                        ) ||
                   b_p('priority', priority                     ) ||
                   b_p('copies', copies                       ) ||
                   b_p('window', window, p_last=>TRUE));
 
  dbms_ra_int.canonicalize(protection_policy_name, c_prot_name, 128);
  dbms_ra_int.canonicalize(template_name, c_template_name, 128);
  dbms_ra_int.canonicalize(full_template_name, c_full_template_name, 128);
  dbms_ra_int.canonicalize(from_tag, c_from_tag, 32);
 
  dbms_ra_int.create_sbt_job_template_int(
                              template_name  => c_template_name,
                              prot_name => c_prot_name,
                              attr_name => c_attr_name,
                              backup_type => upper(backup_type),
                              full_template_name  => c_full_template_name,
                              from_tag => c_from_tag,
                              priority => priority,
                              copies => copies,
                              window => window);
  unlock_api(p_the_num=>l_the, p_results=>TRUE, p_docommit=>TRUE);
EXCEPTION
  WHEN OTHERS THEN
    rollback;
    unlock_api(p_the_num=>l_the, p_results=>FALSE, p_docommit=>TRUE);
    RAISE;
END create_sbt_job_template;
 
--
PROCEDURE create_sbt_job_template(
   template_name      IN VARCHAR2,
   db_unique_name     IN VARCHAR2,
   attribute_set_name IN VARCHAR2,
   backup_type        IN VARCHAR2,
   full_template_name IN VARCHAR2               DEFAULT NULL,
   from_tag           IN VARCHAR2               DEFAULT NULL,
   priority           IN NUMBER                 DEFAULT SBT_PRIORITY_MEDIUM,
   copies             IN NUMBER                 DEFAULT 1,
   window             IN DSINTERVAL_UNCONSTRAINED DEFAULT NULL)
IS
  l_the                 NUMBER;
  c_attr_name           sbt_attr_set.attr_name%TYPE;
  c_template_name       sbt_job_template.template_name%TYPE;
  c_full_template_name  sbt_job_template.template_name%TYPE;
  c_from_tag            sbt_job_template.from_tag%TYPE;
  
BEGIN
  dbms_ra_int.canonicalize(attribute_set_name, c_attr_name, 128);
  IF is_rep_server(c_attr_name) THEN
    sys.dbms_sys_error.raise_system_error
       (API_BAD_OBJECT_NUM, 'replication server', 'sbt job template', FALSE);
  END IF;
 
  lock_api(LOCKAPI_CREATE, 'create_sbt_job_template');
 
  l_the := dbms_ra_scheduler.add_to_task_history_table (
                  task_type => dbms_ra_scheduler.TASK_API_ADD_SBT_JOB,
                  param     => 'create_sbt_job_template' ||
                   b_p('template_name', template_name, p_first=>TRUE      ) ||
                   b_p('db_unique_name', db_unique_name               ) ||
                   b_p('attribute_set_name', attribute_set_name       ) ||
                   b_p('backup_type',    backup_type                  ) ||
                   b_p('full_template_name', full_template_name       ) ||
                   b_p('from_tag',       from_tag                     ) ||
                   b_p('priority',       priority                     ) ||
                   b_p('copies',         copies                       ) ||
                   b_p('window',         window    , p_last=>TRUE));
 
  dbms_ra_int.canonicalize(template_name, c_template_name, 128);
  dbms_ra_int.canonicalize(full_template_name, c_full_template_name, 128);
  dbms_ra_int.canonicalize(from_tag, c_from_tag, 32);
  dbms_ra_int.create_sbt_job_template_int(
                              template_name => c_template_name,
                              db_unique_name => upper(db_unique_name),
                              attr_name => c_attr_name,
                              backup_type => upper(backup_type),
                              full_template_name => c_full_template_name,
                              from_tag => c_from_tag,
                              priority => priority,
                              copies => copies,
                              window => window);
  unlock_api(p_the_num=>l_the, p_results=>TRUE, p_docommit=>TRUE);
EXCEPTION
  WHEN OTHERS THEN
    rollback;
    unlock_api(p_the_num=>l_the, p_results=>FALSE, p_docommit=>TRUE);
    RAISE;
END create_sbt_job_template;
 
 
 
--
PROCEDURE update_sbt_job_template_int(
   template_name       IN VARCHAR2,
   attr_name           IN VARCHAR2               DEFAULT NULL,
   backup_type         IN VARCHAR2               DEFAULT NULL,
   from_tag            IN VARCHAR2               DEFAULT
      dbms_ra_int.varchar2null('p1'),
   priority            IN NUMBER                 DEFAULT NULL,
   copies              IN NUMBER                 DEFAULT NULL,
   window              IN DSINTERVAL_UNCONSTRAINED DEFAULT
      dbms_ra_int.intervalnull('p2'))
IS
   CURSOR sbt_task_c(l_template_key IN NUMBER, old_attr_key IN NUMBER) IS
      SELECT rowid
        FROM sbt_task st
       WHERE st.template_key  = l_template_key
         AND st.attr_key = old_attr_key
       ORDER BY st.task_id;
   l_rowids         dbms_sql.urowid_table; 
   fromtagdef       BOOLEAN     := dbms_ra_int.isparamdef('p1');
   update_fromtag   VARCHAR2(1) := 'Y';
   windowdef        BOOLEAN     := dbms_ra_int.isparamdef('p2');
   update_window    VARCHAR2(1) := 'Y';
   l_attr_key       NUMBER      := NULL;
   l_bck_type       NUMBER      := NULL;
   l_t_btype        NUMBER      := NULL;
   l_invalid_val    VARCHAR(128);
   l_template_key   NUMBER;
   old_attr_key     NUMBER;
BEGIN
  IF (copies < 1 OR copies > 4) THEN
     am_trace('update_sbt_job: num copies invalid: ' || pparm(copies));
     sys.dbms_sys_error.raise_system_error(BAD_NUM_COPIES_NUM,
                                           pparm(copies),
                                           FALSE);
  END IF;
 
  IF (attr_name IS NOT NULL) THEN
--
    BEGIN
       SELECT attr.attr_key INTO l_attr_key
         FROM sbt_attr_set attr
         WHERE attr.attr_name = update_sbt_job_template_int.attr_name;
    EXCEPTION
       WHEN NO_DATA_FOUND THEN
         am_trace('update_sbt_job: ' ||
                     item_not_found(attr_name, 'sbt attribute set'));
         sys.dbms_sys_error.raise_system_error
            (OBJ_NOT_FOUND_NUM, attr_name, 'sbt attribute set', FALSE);
    END;
  END IF;
  
  IF (fromtagdef) THEN
    update_fromtag := NULL;
  END IF;
 
  IF (windowdef) THEN
    update_window := NULL;
  END IF;
 
  IF (backup_type IS NOT NULL) THEN
     l_bck_type := dbms_ra_int.sbt_job_backup_type_to_num(backup_type);
 
     SELECT job.bck_type INTO l_t_btype
       FROM sbt_job_template job
       WHERE job.template_name = update_sbt_job_template_int.template_name; 
 
--
     IF (l_t_btype != l_bck_type) THEN
        sys.dbms_sys_error.raise_system_error
           (INVALID_PARAM_NUM, backup_type, 'for given template', FALSE);
     END IF;
    
  END IF;
 
  IF (l_attr_key IS NOT NULL) THEN
     SELECT job.attr_key, job.template_key
       INTO old_attr_key, l_template_key
       FROM sbt_job_template job
       WHERE job.template_name = update_sbt_job_template_int.template_name 
       FOR UPDATE;
     OPEN sbt_task_c(l_template_key, old_attr_key);
     LOOP
        FETCH sbt_task_c BULK COLLECT INTO l_rowids LIMIT 1000;
        EXIT WHEN l_rowids.COUNT = 0;
        FORALL i IN 1..l_rowids.COUNT
           UPDATE sbt_task SET attr_key = l_attr_key
            WHERE rowid = l_rowids(i);
     END LOOP;
     CLOSE sbt_task_c;
  END IF;
       
  UPDATE sbt_job_template job SET
      job.attr_key =
         nvl(l_attr_key, job.attr_key),
      job.bck_type =
         nvl(l_bck_type, job.bck_type),
      job.from_tag =
         nvl2(update_fromtag, update_sbt_job_template_int.from_tag, 
              job.from_tag),
      job.priority =
         nvl(update_sbt_job_template_int.priority, job.priority),
      job.copies =
         nvl(update_sbt_job_template_int.copies, job.copies),
      job.window =
         nvl2(update_window, update_sbt_job_template_int.window, job.window)
    WHERE job.template_name = update_sbt_job_template_int.template_name;
 
--
   IF (sql%rowcount = 0) THEN
      am_trace('update_sbt_job: ' || item_not_found(template_name, 
                                                    'sbt job template'));
      sys.dbms_sys_error.raise_system_error
       (OBJ_NOT_FOUND_NUM, template_name, 'Sbt Job Template', FALSE);
   END IF;
 
--
   COMMIT;
EXCEPTION
   WHEN INVALID_VAL THEN
     IF l_invalid_val IS NOT NULL THEN
       am_trace('update_sbt_job_template_int raising invalid value: ' ||
         l_invalid_val);
       sys.dbms_sys_error.raise_system_error
       (INVALID_VAL_NUM, l_invalid_val, FALSE);
     ELSE
       RAISE;
     END IF;
END update_sbt_job_template_int;
--
PROCEDURE update_sbt_job_template(
   template_name      IN VARCHAR2,
   attribute_set_name IN VARCHAR2               DEFAULT NULL,
   backup_type        IN VARCHAR2               DEFAULT NULL,
   from_tag           IN VARCHAR2               DEFAULT
      dbms_ra_int.varchar2null('p1'),
   priority           IN NUMBER                 DEFAULT NULL,
   copies             IN NUMBER                 DEFAULT NULL,
   window             IN DSINTERVAL_UNCONSTRAINED DEFAULT
      dbms_ra_int.intervalnull('p2'))
IS
  l_the                 NUMBER;
  c_attr_name           sbt_attr_set.attr_name%TYPE;
  c_template_name       sbt_job_template.template_name%TYPE;
  c_from_tag            sbt_job_template.from_tag%TYPE;
BEGIN
  dbms_ra_int.canonicalize(template_name, c_template_name, 128);
  IF is_rep_server(c_template_name) THEN
    sys.dbms_sys_error.raise_system_error
       (API_BAD_OBJECT_NUM, 'replication server', 'sbt job template', FALSE);
  END IF;
 
  dbms_ra_int.canonicalize(attribute_set_name, c_attr_name, 128);
  IF is_rep_server(c_attr_name) THEN
    sys.dbms_sys_error.raise_system_error
       (API_BAD_OBJECT_NUM, 'replication server', 'sbt job template', FALSE);
  END IF;
 
  lock_api(LOCKAPI_MODIFY, 'update_sbt_job_template');
 
  l_the := dbms_ra_scheduler.add_to_task_history_table (
                  task_type => dbms_ra_scheduler.TASK_API_UPD_SBT_JOB,
                  param     => 'update_sbt_job_template' ||
                   b_p('template_name', template_name, p_first=>TRUE  ) ||
                   b_p('attribute_set_name', attribute_set_name       ) ||
                   b_p('backup_type',    backup_type                  ) ||
                   b_p('priority',       priority                     ) ||
                   b_p('window',         window                       ) ||
                   b_p('copies',         copies , p_last=>TRUE));
 
  dbms_ra_int.canonicalize(from_tag, c_from_tag, 32);
  update_sbt_job_template_int(
                              c_template_name,
                              c_attr_name,
                              upper(backup_type),
                              c_from_tag,
                              priority,
                              copies,
                              window);
  unlock_api(p_the_num=>l_the, p_results=>TRUE, p_docommit=>TRUE);
EXCEPTION
  WHEN OTHERS THEN
    rollback;
    unlock_api(p_the_num=>l_the, p_results=>FALSE, p_docommit=>TRUE);
    RAISE;
END update_sbt_job_template;
 
 
 
--
PROCEDURE delete_sbt_job_template_int(template_name IN VARCHAR2,
                                      do_commit     IN BOOLEAN DEFAULT TRUE)
IS
  l_cnt                      NUMBER;
BEGIN
  
   SELECT /*+ OPT_PARAM('_optimizer_join_elimination_enabled' 'false') */ 
          COUNT(*) INTO l_cnt
     FROM sbt_job_template a
    WHERE EXISTS (SELECT 1 FROM sbt_job_template b 
                   WHERE b.template_key = a.full_template_key AND 
                         b.template_name = 
                           delete_sbt_job_template_int.template_name);
 
   IF l_cnt > 1 THEN
     RAISE OBJ_IS_REFERENCED;
   END IF;
 
   DELETE FROM sbt_job_template job
    WHERE job.template_name = delete_sbt_job_template_int.template_name;
 
--
   IF (sql%rowcount = 0) THEN
      am_trace('delete_sbt_job: ' || item_not_found(template_name, 
                                                    'sbt job template'));
      sys.dbms_sys_error.raise_system_error
         (OBJ_NOT_FOUND_NUM, template_name, 'Sbt Job Template', FALSE);
   END IF;
 
--
   COMMIT;
 
EXCEPTION
  WHEN OBJ_IS_REFERENCED THEN
     am_trace('Reference INCR/ARCH job template exists for a given' ||
              ' FULL template ' || template_name);
     sys.dbms_sys_error.raise_system_error
        (OBJ_IS_REFERENCED_NUM, 'Sbt Template Job', template_name, FALSE);
    RAISE;
END delete_sbt_job_template_int;
--
PROCEDURE delete_sbt_job_template(template_name IN VARCHAR2)
IS
  l_the             NUMBER;
  c_template_name   sbt_job_template.template_name%TYPE;
  
BEGIN
  dbms_ra_int.canonicalize(template_name, c_template_name, 128);
  IF is_rep_server(c_template_name) THEN
    sys.dbms_sys_error.raise_system_error
       (API_BAD_OBJECT_NUM, 'replication server', 'sbt job template', FALSE);
  END IF;
 
  lock_api(LOCKAPI_DELETE, 'delete_sbt_job');
 
  l_the := dbms_ra_scheduler.add_to_task_history_table (
            task_type => dbms_ra_scheduler.TASK_API_DEL_SBT_JOB,
            param     => 'delete_sbt_job_template' ||
              b_p('template_name', template_name, p_first=>TRUE, p_last=>TRUE));
 
  delete_sbt_job_template_int(c_template_name);
  unlock_api(p_the_num=>l_the, p_results=>TRUE, p_docommit=>TRUE);
  
EXCEPTION
  WHEN OTHERS THEN
    rollback;
    unlock_api(p_the_num=>l_the, p_results=>FALSE, p_docommit=>TRUE);
    RAISE;
END delete_sbt_job_template;
 
--
 
--
--
PROCEDURE queue_sbt_backup_task(template_name IN VARCHAR2) IS
  c_template_name           sbt_job_template.template_name%TYPE;
BEGIN
  dbms_ra_int.canonicalize(template_name, c_template_name, 128);
  IF is_rep_server(c_template_name) THEN
    sys.dbms_sys_error.raise_system_error
       (API_BAD_OBJECT_NUM, 'replication server', 'sbt job template', FALSE);
  END IF;
 
  dbms_ra_scheduler.queue_sbt_backup_task(c_template_name);
END queue_sbt_backup_task;
 
--
--
PROCEDURE abort_sbt_task(task_id IN NUMBER) IS
   l_job_name sessions.job_name%type;
BEGIN
   SELECT s.job_name
     INTO l_job_name
     FROM sessions s
    WHERE s.current_task = abort_sbt_task.task_id
      AND s.current_task_type IN
          (dbms_ra_scheduler.TASK_BACKUP_SBT,
           dbms_ra_scheduler.TASK_RESTORE_SBT,
           dbms_ra_scheduler.TASK_PURGE_SBT);
 
   dbms_scheduler.stop_job(job_name => l_job_name, force => TRUE);
EXCEPTION
   WHEN no_data_found THEN
      sys.dbms_sys_error.raise_system_error(SBT_TASK_NOT_FOUND_NUM,
                                            TO_CHAR(task_id),
                                            FALSE);
END abort_sbt_task;
 
--
FUNCTION extract_host_name(input_url IN varchar2) RETURN varchar2 
IS
   host_name varchar2(512) := regexp_substr(
                input_url, '^(https?://)?([^:/]*)', 1, 1, 'i', 2);
BEGIN
  am_trace('extract_host_name host_name=' || host_name);
  RETURN host_name;
END extract_host_name;
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE grant_network_acl_ace(catalog_user_name  VARCHAR2,
                                wallet_alias       VARCHAR2,
                                wallet_path        VARCHAR2)
IS
  r_avm_server      server%ROWTYPE;
  l_owner           user_users.username%TYPE;
  CURSOR hostlst_c(hostlst IN VARCHAR2) IS
     WITH table_to_parse as
        (select hostlst str from dual)
     SELECT DISTINCT upper(ltrim(rtrim(new_str))) new_str
       FROM table_to_parse,
            xmltable('r/c' passing xmltype('<r><c>' ||
            replace(str,',','</c><c>') || '</c></r>')
            columns new_str varchar2(512) path '.');
BEGIN
  l_owner := SYS.rai_schema(TRUE);
 
  SELECT * INTO r_avm_server
    FROM server
    WHERE wallet_alias = grant_network_acl_ace.wallet_alias
      AND nvl(wallet_path,'') = nvl(grant_network_acl_ace.wallet_path, '')
      AND filter_user  = catalog_user_name;
 
  IF (r_avm_server.wallet_path IS NOT NULL) THEN
    am_trace ('grant_network_acl_ace wallet: ' ||
              r_avm_server.wallet_path ||
              ' catalog_user_name=' || catalog_user_name ||
              ' acl_owner_name=' || l_owner);
    sys.dbms_network_acl_admin.append_wallet_ace(
            wallet_path => r_avm_server.wallet_path,
            ace => xs$ace_type(privilege_list => xs$name_list('use_passwords'),
                               principal_name => l_owner,
                               principal_type => xs_acl.ptype_db));
  END IF;
 
  FOR hostRec IN hostlst_c(r_avm_server.server_host) LOOP
    am_trace ('grant_network_acl_ace host: ' ||
              extract_host_name(hostRec.new_str) ||
              ' server_port=' || r_avm_server.server_port ||
              ' catalog_user_name=' || catalog_user_name ||
              ' acl_owner_name=' || l_owner);
    sys.dbms_network_acl_admin.append_host_ace(
            host => extract_host_name(hostRec.new_str),
            lower_port => r_avm_server.server_port,
            ace => xs$ace_type(privilege_list => xs$name_list('connect'),
                               principal_name => l_owner,
                               principal_type => xs_acl.ptype_db));
  END LOOP;
 
  IF r_avm_server.proxy_url IS NOT NULL THEN
    am_trace ('grant_network_acl_ace proxy: ' ||
              extract_host_name(r_avm_server.proxy_url) ||
              ' port=' || r_avm_server.proxy_port || 
              ' catalog_user_name=' || catalog_user_name ||
              ' acl_owner_name=' || l_owner);
    sys.dbms_network_acl_admin.append_host_ace(
           host => extract_host_name(r_avm_server.proxy_url),
           lower_port => r_avm_server.proxy_port,
           ace => xs$ace_type(privilege_list => xs$name_list('connect'),
                              principal_name => l_owner,
                              principal_type => xs_acl.ptype_db));
  END IF;
  
EXCEPTION
  WHEN OTHERS THEN
    rollback;
    am_trace ('grant_network_acl_ace exception: ' ||
              ' catalog_user_name: ' || catalog_user_name ||
              ' wallet_alias: ' || wallet_alias ||
              ' wallet_path: ' || wallet_path ||
              ' err: ' || SQLERRM);
    revoke_network_acl_ace(catalog_user_name, wallet_alias, wallet_path);
    RAISE;
    
END grant_network_acl_ace;
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
FUNCTION add_repository(catalog_user_name  VARCHAR2,
                        new_server_key     NUMBER,
                        am_server_name     VARCHAR2,
                        wallet_alias       VARCHAR2,
                        wallet_path        VARCHAR2,
                        proxy_url          VARCHAR2   DEFAULT NULL,
                        proxy_port         NUMBER     DEFAULT NULL,
                        http_timeout       NUMBER     DEFAULT NULL
                       ) RETURN NUMBER
IS
  l_server_key         NUMBER;
  l_the                NUMBER;
  l_port               NUMBER;
  l_ssl                BOOLEAN;
  l_hostlst            VARCHAR2(8192);
BEGIN
  
  l_the := dbms_ra_scheduler.add_to_task_history_table (
              task_type => dbms_ra_scheduler.TASK_API_ADD_REPOSITORY,
              param     => 'add_repository' ||
              b_p('catalog_user_name', catalog_user_name, p_first=>TRUE) ||
              b_p('new_server_key',new_server_key            ) ||
              b_p('am_server_name',am_server_name            ) ||
              b_p('wallet_alias', wallet_alias               ) ||
              b_p('wallet_path',  wallet_path                ) ||
              b_p('proxy_url',    proxy_url                  ) ||
              b_p('proxy_port',   proxy_port                 ) ||
              b_p('http_timeout', http_timeout  , p_last=>TRUE));
  
  sys.kbrsi_icd.wallet2hostlst(
     wallet_loc => wallet_path,
     cred_alias => wallet_alias,
     hostlst    => l_hostlst,
     port       => l_port,
     ssl        => l_ssl,
     client     => 'REPLICATION');
 
  IF (l_port IS NULL OR l_port <= 0) THEN
     am_trace('add_repository raising invalid value: ' ||
       'HTTP server not configured at replication host');
     sys.dbms_sys_error.raise_system_error
        (INVALID_VAL_NUM,
         'HTTP server not configured at replication host',
         FALSE);
  END IF;
 
  INSERT INTO server
      (server_key,  filter_user, server_host, server_port,
       wallet_alias,  wallet_path, proxy_url, proxy_port, timeout_secs,
       rep_server_name)
         VALUES (add_repository.new_server_key,
                add_repository.catalog_user_name,
                l_hostlst,
                l_port,
                add_repository.wallet_alias,
                add_repository.wallet_path,
                add_repository.proxy_url,
                add_repository.proxy_port,
                add_repository.http_timeout, 
                add_repository.am_server_name);
  
  grant_network_acl_ace(catalog_user_name, wallet_alias, wallet_path);
 
  RETURN new_server_key;
END add_repository;
 
--
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE revoke_network_acl_ace(catalog_user_name  IN VARCHAR2,
                                 wallet_alias       IN VARCHAR2,
                                 wallet_path        IN VARCHAR2)
IS
  r_avm_server      server%ROWTYPE;
  l_owner           user_users.username%TYPE;
  CURSOR hostlst_c(hostlst IN VARCHAR2) IS
     WITH table_to_parse as
        (select hostlst str from dual)
     SELECT DISTINCT upper(ltrim(rtrim(new_str))) new_str
       FROM table_to_parse,
            xmltable('r/c' passing xmltype('<r><c>' ||
            replace(str,',','</c><c>') || '</c></r>')
            columns new_str varchar2(512) path '.');
  E_COULD_NOT_REVOKE EXCEPTION;
  PRAGMA EXCEPTION_INIT (E_COULD_NOT_REVOKE, -1927);
 
BEGIN
  l_owner := SYS.rai_schema(TRUE);
 
  SELECT * INTO r_avm_server
    FROM server
    WHERE wallet_alias = revoke_network_acl_ace.wallet_alias
      AND nvl(wallet_path,'') = nvl(revoke_network_acl_ace.wallet_path, '')
      AND filter_user  = catalog_user_name;
 
  FOR hostRec IN hostlst_c(r_avm_server.server_host) LOOP
    BEGIN
      dbms_network_acl_admin.remove_host_ace(
            host => extract_host_name(hostRec.new_str),
            lower_port => r_avm_server.server_port,
            ace => xs$ace_type(privilege_list => xs$name_list('connect'),
                               principal_name => l_owner,
                               granted        => true,
                               principal_type => xs_acl.ptype_db));
    EXCEPTION
      WHEN E_COULD_NOT_REVOKE THEN
        am_trace ('revoke_network_acl no_revoke: remove_host_ace: ' ||
                  ' catalog_user_name: ' || catalog_user_name ||
                  ' acl_owner_name=' || l_owner ||
                  ' wallet_alias: ' || wallet_alias ||
                  ' wallet_path: ' || wallet_path ||
                  ' host: ' || extract_host_name(hostRec.new_str) ||
                  ' err: ' || SQLERRM);
      WHEN OTHERS THEN 
        am_trace ('revoke_network_acl exception: ' ||
                  ' catalog_user_name: ' || catalog_user_name ||
                  ' acl_owner_name=' || l_owner ||
                  ' wallet_alias: ' || wallet_alias ||
                  ' wallet_path: ' || wallet_path ||
                  ' host: ' || extract_host_name(hostRec.new_str) ||
                  ' err: ' || SQLERRM);
    END;
  END LOOP;
 
  IF (r_avm_server.wallet_path IS NOT NULL) THEN
    BEGIN
      dbms_network_acl_admin.remove_wallet_ace(
            wallet_path => r_avm_server.wallet_path,
            ace => xs$ace_type(privilege_list => xs$name_list('use_passwords'),
                               principal_name => l_owner,
                               granted        => true,
                               principal_type => xs_acl.ptype_db));
    EXCEPTION
      WHEN OTHERS THEN 
        am_trace ('revoke_network_acl exception: remove_wallet_ace: ' ||
                  ' catalog_user_name: ' || catalog_user_name ||
                  ' acl_owner_name=' || l_owner ||
                  ' wallet_alias: ' || wallet_alias ||
                  ' wallet_path: ' || wallet_path ||
                  ' err: ' || SQLERRM);
    END;
 
  END IF;
                                
  IF r_avm_server.proxy_url IS NOT NULL THEN
    BEGIN
      dbms_network_acl_admin.remove_host_ace(
         host => r_avm_server.proxy_url,
         lower_port => r_avm_server.proxy_port,
         ace => xs$ace_type(privilege_list => xs$name_list('connect'),
                            principal_name => l_owner,
                            granted        => true,
                            principal_type => xs_acl.ptype_db));
    EXCEPTION
      WHEN OTHERS THEN 
        am_trace ('revoke_network_acl exception: remove_host_ace: ' ||
                  ' catalog_user_name: ' || catalog_user_name ||
                  ' acl_owner_name=' || l_owner ||
                  ' wallet_alias: ' || wallet_alias ||
                  ' wallet_path: ' || wallet_path ||
                  ' proxy host: ' || r_avm_server.proxy_url ||
                  ' err: ' || SQLERRM);
    END;
  END IF;
  
END revoke_network_acl_ace;
 
--
--
--
--
--
--
--
--
PROCEDURE delete_repository(catalog_user_name  IN VARCHAR2,
                            wallet_alias       IN VARCHAR2,
                            wallet_path        IN VARCHAR2)
IS 
  l_the            NUMBER;
BEGIN 
 
  l_the := dbms_ra_scheduler.add_to_task_history_table (
              task_type => dbms_ra_scheduler.TASK_API_DEL_REPOSITORY,
              param     => 'delete_repository' ||
              b_p('catalog_user_name', catalog_user_name, p_first=>TRUE) ||
              b_p('wallet_alias', wallet_alias) ||
              b_p('wallet_path',  wallet_path , p_last=>TRUE));
  
  revoke_network_acl_ace(catalog_user_name, wallet_alias, wallet_path);
 
  DELETE server
    WHERE wallet_alias = delete_repository.wallet_alias
      AND wallet_path  = delete_repository.wallet_path
      AND filter_user  = catalog_user_name;
   
END delete_repository;
 
 
 
--
--
--
--
--
--
FUNCTION build_parms_for_rep (p_user_parms   IN VARCHAR2,
                              p_wallet_path  IN VARCHAR2,
                              p_wallet_alias IN VARCHAR2,
                              p_proxy_url    IN VARCHAR2,
                              p_proxy_port   IN NUMBER,
                              p_sbt_so_name  IN VARCHAR2) RETURN VARCHAR2
                              
IS
  l_sbt_parms       sbt_lib_desc.parms%TYPE;
  l_port_str        VARCHAR2(7);
BEGIN
  
  l_sbt_parms := 'SBT_PARMS=(';
  
  IF p_user_parms IS NOT NULL THEN
    l_sbt_parms := l_sbt_parms || p_user_parms || ', ';
  END IF;
  
  l_sbt_parms := l_sbt_parms || 
    'RA_WALLET="';
  IF p_wallet_path IS NOT NULL THEN
     l_sbt_parms := l_sbt_parms || 'LOCATION=' || p_wallet_path || ' ';
  END IF;
  l_sbt_parms := l_sbt_parms || 'CREDENTIAL_ALIAS=' || p_wallet_alias || '"';
  
  IF p_proxy_url IS NOT NULL THEN
    l_port_str := NULL;
    IF p_proxy_port IS NOT NULL THEN
      l_port_str := ':' || p_proxy_port;
    END IF;
 
    l_sbt_parms := l_sbt_parms || 
      ', RA_PROXY=' || p_proxy_url || l_port_str;
  END IF;
    
  l_sbt_parms := l_sbt_parms || ', RA_REPLICATION=TRUE';
 
  l_sbt_parms := l_sbt_parms || ')';
  
  RETURN 'SBT_LIBRARY=' || p_sbt_so_name || ', ' || l_sbt_parms;
  
END build_parms_for_rep;
 
   
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE create_replication_server_int (
                                 replication_server_name IN VARCHAR2,
                                 sbt_so_name          IN VARCHAR2,
                                 sbt_parms            IN VARCHAR2 DEFAULT NULL,
                                 max_streams          IN NUMBER   DEFAULT NULL,
                                 catalog_user_name    IN VARCHAR2,
                                 wallet_alias         IN VARCHAR2,
                                 wallet_path          IN VARCHAR2,
                                 proxy_url            IN VARCHAR2 DEFAULT NULL,
                                 proxy_port           IN NUMBER DEFAULT NULL,
                                 http_timeout         IN NUMBER DEFAULT NULL)
IS
   num_of                NUMBER;
   l_obj_type            VARCHAR2(128);
   l_obj_name            VARCHAR2(128);
   l_server_key          NUMBER;
   l_missing_param       VARCHAR2(128);
   l_sbt_parms           sbt_lib_desc.parms%TYPE;
   l_addrepos_done       BOOLEAN := FALSE;
   l_rep_lib_name        sbt_lib_desc.lib_name%TYPE;
   l_rep_atr_name        sbt_attr_set.attr_name%TYPE;
 
BEGIN
 
--
  IF length(replication_server_name) > 128 THEN
    am_trace('create_replication_server:' ||
             ' replication_server_name too long: ' ||
             TO_CHAR(length(replication_server_name)) ||
             ', "' || replication_server_name || '"');
    sys.dbms_sys_error.raise_system_error(
                                  REP_SRVR_NM_BAD_LEN_NUM,
                                  TO_CHAR(length(replication_server_name)),
                                  FALSE);
  END IF;
 
  IF proxy_port <= 0 THEN
    am_trace('create_replication_server: proxy port <= 0: ' ||
             TO_CHAR(proxy_port));
    sys.dbms_sys_error.raise_system_error(REP_SRVR_BAD_PORT_NUM,
                                          TO_CHAR(proxy_port),
                                          FALSE);
  END IF;
 
  IF (proxy_url IS NOT NULL AND proxy_port IS NULL) THEN
    am_trace('create_replication_server:' ||
             ' Proxy Port: NULL, Proxy URL: ' || proxy_url);
    sys.dbms_sys_error.raise_system_error(REP_SRVR_PORT_NULL_NUM, FALSE);
  END IF;
 
  IF (proxy_url IS NULL AND proxy_port IS NOT NULL) THEN
    am_trace('create_replication_server:' ||
             ' Proxy Port: ' || TO_CHAR(proxy_port) || ', Proxy URL: NULL');
    sys.dbms_sys_error.raise_system_error(REP_SRVR_PROXY_NULL_NUM, FALSE);
  END IF;
  
  IF replication_server_name IS NULL THEN
    l_missing_param := 'replication_server_name';
    RAISE MISSING_PARAM;
  END IF;
  
  IF sbt_so_name IS NULL THEN
    l_missing_param := 'sbt_so_name';
    RAISE MISSING_PARAM;
  END IF;
  
--
--
  SELECT count(*) INTO num_of
    FROM server
    WHERE rep_server_name=replication_server_name;
  IF num_of > 0 THEN
--
    l_obj_type := 'replication server already exists';
    l_obj_name := replication_server_name;
    RAISE DUP_VAL_ON_INDEX;
  END IF;
 
 
--
  l_server_key := rman_seq.nextval;
  l_rep_lib_name := dbms_ra_int.build_rep_lib_name(replication_server_name,
                                                   l_server_key);
  l_rep_atr_name := dbms_ra_int.build_rep_atr_name(replication_server_name,
                                                   l_server_key);
 
--
--
 
--
--
  SELECT count(*) INTO num_of
    FROM sbt_lib_desc
    WHERE sbt_lib_desc.lib_name=l_rep_lib_name;
 
  IF num_of > 0 THEN
--
    l_obj_type := 'replication server has an existing sbt lib description';
    l_obj_name := replication_server_name;
    RAISE DUP_VAL_ON_INDEX;
  END IF;
 
--
--
  SELECT count(*) INTO num_of
    FROM sbt_attr_set
    WHERE sbt_attr_set.attr_name=l_rep_atr_name;
 
  IF num_of > 0 THEN
--
    l_obj_type := 'replication server has an existing sbt attribute set name';
    l_obj_name := replication_server_name;
    RAISE DUP_VAL_ON_INDEX;
  END IF;
 
  am_trace('CREATE_REPLICATION_SERVER: ' ||
           'replication_server_name=' || replication_server_name ||
           'rep_server_lib_name=' || l_rep_lib_name ||
           'rep_server_atr_name=' || l_rep_atr_name ||
           ', sbt_so_name=' || sbt_so_name ||
           ', sbt_parms=' || sbt_parms);
  
--
--
  l_server_key := add_repository(
    catalog_user_name => create_replication_server_int.catalog_user_name,
    new_server_key    => l_server_key,
    am_server_name    => create_replication_server_int.replication_server_name,
    wallet_alias      => create_replication_server_int.wallet_alias,
    wallet_path       => create_replication_server_int.wallet_path,
    proxy_url         => create_replication_server_int.proxy_url,
    proxy_port        => create_replication_server_int.proxy_port,
    http_timeout      => create_replication_server_int.http_timeout);
  l_addrepos_done := TRUE;
 
--
--
  l_sbt_parms := build_parms_for_rep (
                  p_user_parms   => create_replication_server_int.sbt_parms, 
                  p_wallet_path  => create_replication_server_int.wallet_path ,
                  p_wallet_alias => create_replication_server_int.wallet_alias,
                  p_proxy_url    => create_replication_server_int.proxy_url   ,
                  p_proxy_port   => create_replication_server_int.proxy_port  ,
                  p_sbt_so_name  => create_replication_server_int.sbt_so_name);
  
  am_trace('CREATE_REPLICATION_SERVER: l_parms=' || l_sbt_parms);
 
--
--
--
--
--
  create_sbt_library_int(   lib_name        => l_rep_lib_name,
                            drives          => max_streams,
                            parms           => l_sbt_parms,
                            server_key      => l_server_key,
                            p_status        => 'P',
                            do_commit       => FALSE);
 
  create_sbt_attr_set_int(  lib_name        => l_rep_lib_name,
                            attr_name       => l_rep_atr_name,
                            do_commit       => FALSE);
 
  COMMIT;
  
EXCEPTION
 
  WHEN REP_SRVR_NM_BAD_LEN OR REP_SRVR_BAD_PORT OR REP_SRVR_PORT_NULL OR
       REP_SRVR_PROXY_NULL THEN
    IF l_addrepos_done THEN
        delete_repository(create_replication_server_int.catalog_user_name,
                          create_replication_server_int.wallet_alias,
                          create_replication_server_int.wallet_path);
    END IF;
    
    ROLLBACK;
    RAISE;
 
  WHEN DUP_VAL_ON_INDEX THEN
    IF l_addrepos_done THEN
        delete_repository(create_replication_server_int.catalog_user_name,
                          create_replication_server_int.wallet_alias,
                          create_replication_server_int.wallet_path);
    END IF;
 
    ROLLBACK;
    IF l_obj_type IS NOT NULL THEN
      sys.dbms_sys_error.raise_system_error(DUP_NAME_NUM,
                                            l_obj_name,
                                            l_obj_type,
                                            FALSE);
    ELSE
      RAISE;
    END IF;
 
  WHEN MISSING_PARAM THEN
    IF l_addrepos_done THEN
        delete_repository(create_replication_server_int.catalog_user_name,
                          create_replication_server_int.wallet_alias,
                          create_replication_server_int.wallet_path);
    END IF;
 
    ROLLBACK;
    IF l_missing_param IS NOT NULL THEN
      am_trace ('create_replication_server: required parameter missing' ||
                 l_missing_param);
      sys.dbms_sys_error.raise_system_error(MISSING_PARAM_NUM,
                                            l_missing_param,
                                            FALSE);
    ELSE
      RAISE;
    END IF;
    
  WHEN OTHERS THEN
    IF l_addrepos_done THEN
        delete_repository(create_replication_server_int.catalog_user_name,
                          create_replication_server_int.wallet_alias,
                          create_replication_server_int.wallet_path);
    END IF;
 
    ROLLBACK;
    am_trace ('create_replication_server: EXCEPTION: '  || SQLERRM);
    RAISE;
 
END create_replication_server_int;
--
 
PROCEDURE create_replication_server (
                              replication_server_name IN VARCHAR2,
                              sbt_so_name           IN VARCHAR2,
                              sbt_parms             IN VARCHAR2 DEFAULT NULL,
                              max_streams           IN NUMBER DEFAULT NULL,
                              catalog_user_name     IN VARCHAR2,
                              wallet_alias          IN VARCHAR2,
                              wallet_path           IN VARCHAR2,
                              proxy_url             IN VARCHAR2 DEFAULT NULL,
                              proxy_port            IN NUMBER DEFAULT NULL,
                              http_timeout          IN NUMBER DEFAULT NULL)
 
IS
  l_the             NUMBER;
  c_rep_srv_name    server.rep_server_name%TYPE;
  u_catalog_user_name server.filter_user%TYPE;
 
BEGIN
  dbms_ra_int.canonicalize(replication_server_name, c_rep_srv_name, 128);
  IF is_sysgen_obj(c_rep_srv_name) THEN
    sys.dbms_sys_error.raise_system_error
       (API_BAD_OBJECT_NUM, 'replication server', 'system object', FALSE);
  END IF;
 
  lock_api(LOCKAPI_CREATE, 'create_replication_server');
  u_catalog_user_name := upper(catalog_user_name);
 
  l_the := dbms_ra_scheduler.add_to_task_history_table (
              task_type => dbms_ra_scheduler.TASK_API_CRE_REP_SERVER,
              param     => 'create_replication_server' ||
               b_p('replication_server_name', replication_server_name, 
                                p_first=>TRUE) ||
               b_p('sbt_so_name',    sbt_so_name                 ) ||
               b_p('sbt_parms',      sbt_parms                   ) ||
               b_p('max_streams',    max_streams                 ) ||
               b_p('catalog_user_name', u_catalog_user_name      ) ||
               b_p('wallet_alias',   wallet_alias                ) ||
               b_p('wallet_path',    wallet_path                 ) ||
               b_p('proxy_url',      proxy_url                   ) ||
               b_p('proxy_port',     proxy_port                  ) ||
               b_p('http_timeout',   http_timeout , p_last=>TRUE));
 
--
--
--
--
  ctrl_c_check(CCCHK_CREDEL_REP_SERVER);
 
  create_replication_server_int (c_rep_srv_name,
                                 sbt_so_name,
                                 sbt_parms,
                                 max_streams,
                                 u_catalog_user_name,
                                 wallet_alias,
                                 wallet_path,
                                 proxy_url,
                                 proxy_port,
                                 http_timeout);
  unlock_api(p_the_num=>l_the, p_results=>TRUE, p_docommit=>TRUE);
EXCEPTION
  WHEN OTHERS THEN
    rollback;
    unlock_api(p_the_num=>l_the, p_results=>FALSE, p_docommit=>TRUE);
    RAISE;
END create_replication_server;
--
 
 
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE update_replication_server_int (
                                replication_server_name IN VARCHAR2,
                                sbt_so_name          IN VARCHAR2 DEFAULT NULL,
                                sbt_parms            IN VARCHAR2 DEFAULT NULL,
                                max_streams          IN NUMBER   DEFAULT
                                            dbms_ra_int.number2null('p4'),
                                catalog_user_name    IN VARCHAR2 DEFAULT NULL,
                                wallet_alias         IN VARCHAR2 DEFAULT NULL,
                                wallet_path          IN VARCHAR2 DEFAULT
                                            dbms_ra_int.varchar2null('p1'),
                                proxy_url            IN VARCHAR2 DEFAULT
                                            dbms_ra_int.varchar2null('p2'),
                                proxy_port           IN NUMBER   DEFAULT
                                            dbms_ra_int.number2null('p3'),
                                http_timeout         IN NUMBER   DEFAULT NULL)
IS
   num_of                NUMBER;
   l_repsrv_status       VARCHAR2(1);
   l_obj_type            VARCHAR2(128);
   l_obj_name            VARCHAR2(128);
   l_parms               VARCHAR2(2048);
   l_old_parms           VARCHAR2(2048);
   l_lib_name            sbt_lib_desc.lib_name%TYPE;
   l_dynamic_drives      sbt_lib_desc.dynamic_drives%TYPE;
   l_missing_param       VARCHAR2(128);
   l_old_server          server%ROWTYPE;
   l_new_server          server%ROWTYPE;
   l_sbt_parms           sbt_lib_desc.parms%TYPE;
   l_sbt_so_name         sbt_lib_desc.parms%TYPE;
   l_streamsdef          BOOLEAN := dbms_ra_int.isparamdef('p4');
   l_port                NUMBER;
   l_ssl                 BOOLEAN;
   l_hostlst             VARCHAR2(8192);
   l_walpath_def         BOOLEAN := dbms_ra_int.isparamdef('p1');
   l_pxy_def             BOOLEAN := dbms_ra_int.isparamdef('p2');
   l_pxyport_def         BOOLEAN := dbms_ra_int.isparamdef('p3');
   l_grant_network       BOOLEAN := FALSE;
   l_rep_lib_name        sbt_lib_desc.lib_name%TYPE;
   l_wallet_path         server.wallet_path%TYPE;
   l_wallet_alias        server.wallet_alias%TYPE;
BEGIN
  am_trace('UPDATE_REPLICATION_SERVER: replication_server_name=' || 
            replication_server_name ||
           ', sbt_so_name='         || sbt_so_name ||
           ', sbt_parms='           || sbt_parms ||
           ', max_streams='         || max_streams ||
           ', catalog_user_name='   || catalog_user_name ||
           ', wallet_alias='        || wallet_alias ||
           ', wallet_path='         || wallet_path ||
           ', proxy_url='           || proxy_url ||
           ', proxy_port='          || proxy_port ||
           ', http_timeout='        || http_timeout);
 
--
  BEGIN
    SELECT *
      INTO l_old_server
      FROM server
      WHERE server.rep_server_name=replication_server_name;
  EXCEPTION
    WHEN NO_DATA_FOUND THEN
      l_obj_type := 'replication server';
      l_obj_name := replication_server_name;
      RAISE OBJ_NOT_FOUND;
  END;
 
  BEGIN
    SELECT lib_name, status INTO l_lib_name, l_repsrv_status
      FROM sbt_lib_desc
      WHERE server_key = l_old_server.server_key;
  EXCEPTION
    WHEN NO_DATA_FOUND THEN
      l_obj_type := 'replication server has an existing sbt lib description';
      l_obj_name := replication_server_name;
      RAISE OBJ_NOT_FOUND;
  END;
 
--
  IF (NOT l_streamsdef) THEN
     IF (max_streams IS NULL) THEN
        l_dynamic_drives := 'Y';
     ELSE
        l_dynamic_drives := 'N';
     END IF;
 
     update_sbt_library_int(lib_name       => l_lib_name,
                            drives         => max_streams,
                            dynamic_drives => l_dynamic_drives);
  END IF;
  
--
--
  IF l_repsrv_status = 'R' AND
     (sbt_so_name       IS NOT NULL OR
      sbt_parms         IS NOT NULL OR
      catalog_user_name IS NOT NULL OR
      wallet_alias      IS NOT NULL OR
      NOT l_walpath_def             OR
      NOT l_pxy_def                 OR
      NOT l_pxyport_def             OR
      http_timeout      IS NOT NULL)
  THEN
    RAISE REP_SRVR_RUNNING;
  END IF;
 
  l_new_server := l_old_server;
  
--
  IF (NOT l_pxyport_def OR
      NOT l_pxy_def OR NOT l_walpath_def OR wallet_alias IS NOT NULL) THEN
     revoke_network_acl_ace(l_old_server.filter_user,
                            l_old_server.wallet_alias,
                            l_old_server.wallet_path);
     l_grant_network := TRUE;
  END IF;
 
--
  IF wallet_alias IS NOT NULL THEN
    l_wallet_alias := wallet_alias;
  ELSE
    l_wallet_alias := l_old_server.wallet_alias;
  END IF;
  IF wallet_path IS NOT NULL THEN
    l_wallet_path := wallet_path;
  ELSE
    l_wallet_path := l_old_server.wallet_path;
  END IF;
  sys.kbrsi_icd.wallet2hostlst(wallet_loc => l_wallet_path,
                               cred_alias => l_wallet_alias,
                               hostlst    => l_hostlst,
                               port       => l_port,
                               ssl        => l_ssl,
                               client     => 'REPLICATION');
  IF (l_port IS NULL OR l_port <= 0) THEN
    am_trace('update_replication_server_int:' ||
             ' HTTP server not configured at replication host');
    sys.dbms_sys_error.raise_system_error(REP_SRVR_HOST_NOT_CONFIG_NUM,
                                          FALSE);
  END IF;
  l_new_server.server_host := l_hostlst;
  l_new_server.server_port := l_port;
  UPDATE server
    SET server_host = l_new_server.server_host,
    server_port = l_new_server.server_port
    WHERE server_key = l_old_server.server_key;
  
  IF proxy_port <= 0 THEN
    am_trace('update_replication_server: proxy port <= 0: ' ||
             TO_CHAR(proxy_port));
    sys.dbms_sys_error.raise_system_error(REP_SRVR_BAD_PORT_NUM,
                                          TO_CHAR(proxy_port),
                                          FALSE);
  END IF;
 
  IF (proxy_url IS NOT NULL AND proxy_port IS NULL) THEN
    am_trace('update_replication_server:' ||
             ' Proxy Port: NULL, Proxy URL: ' || proxy_url);
    sys.dbms_sys_error.raise_system_error(REP_SRVR_PORT_NULL_NUM, FALSE);
  END IF;
 
  IF (proxy_url IS NULL AND proxy_port IS NOT NULL) THEN
    am_trace('update_replication_server:' ||
             ' Proxy Port: ' || TO_CHAR(proxy_port) || ', Proxy URL: NULL');
    sys.dbms_sys_error.raise_system_error(REP_SRVR_PROXY_NULL_NUM, FALSE);
  END IF;
  
--
  IF NOT l_pxyport_def THEN
    l_new_server.proxy_port := proxy_port;
    UPDATE server SET
      proxy_port = l_new_server.proxy_port
      WHERE server_key = l_old_server.server_key;
  END IF;
 
--
  IF NOT l_pxy_def THEN
    l_new_server.proxy_url := proxy_url;
    UPDATE server SET
      proxy_url = l_new_server.proxy_url
      WHERE server_key = l_old_server.server_key;
  END IF;
 
--
  IF http_timeout IS NOT NULL THEN
    l_new_server.timeout_secs := http_timeout;
    UPDATE server
      SET server.timeout_secs = l_new_server.timeout_secs
      WHERE server_key = l_old_server.server_key;
  END IF;
 
--
  IF wallet_alias IS NOT NULL THEN 
    l_new_server.wallet_alias := wallet_alias;
    UPDATE server  
      SET server.wallet_alias = l_new_server.wallet_alias
      WHERE server_key = l_old_server.server_key;
  END IF;
 
--
  IF NOT l_walpath_def THEN 
    l_new_server.wallet_path := wallet_path;
    UPDATE server  
      SET server.wallet_path = l_new_server.wallet_path
      WHERE server_key = l_old_server.server_key;
  END IF;
  
--
  IF catalog_user_name IS NOT NULL THEN
    l_new_server.filter_user := catalog_user_name;
    UPDATE server  
      SET filter_user = l_new_server.filter_user
      WHERE server_key = l_old_server.server_key;
  END IF;
 
--
--
--
--
  IF sbt_so_name IS NOT NULL THEN
    l_sbt_so_name := sbt_so_name;
  ELSE
    SELECT parms INTO l_old_parms
      FROM sbt_lib_desc
      WHERE server_key = l_old_server.server_key;
 
--
    l_sbt_so_name := regexp_substr(l_old_parms,
                                  '(.*)(SBT_LIBRARY=)([^,]*)',
                                  1, 1, 'i', 3);
  END IF;
 
--
--
  l_parms := build_parms_for_rep(
                 p_user_parms   => sbt_parms,
                 p_wallet_path  => l_new_server.wallet_path,
                 p_wallet_alias => l_new_server.wallet_alias,
                 p_proxy_url    => l_new_server.proxy_url,
                 p_proxy_port   => l_new_server.proxy_port,
                 p_sbt_so_name  => l_sbt_so_name);
  am_trace('UPDATE_REPLICATION_SERVER: replication_server_name=' || 
           replication_server_name ||
           ', sbt_parms=' || l_sbt_parms ||
           ', l_parms=' || l_parms ||
           ', l_sbt_so_name=' || l_sbt_so_name);
 
--
  IF l_parms IS NOT NULL THEN 
    UPDATE sbt_lib_desc SET 
      sbt_lib_desc.parms = l_parms
      WHERE server_key = l_old_server.server_key;
  END IF;
 
  IF l_grant_network THEN
     grant_network_acl_ace(
        l_new_server.filter_user,
        l_new_server.wallet_alias,
        l_new_server.wallet_path);
  END IF;
  COMMIT;
  
EXCEPTION
  WHEN OBJ_NOT_FOUND THEN
    ROLLBACK;
    IF l_obj_type IS NOT NULL THEN
      am_trace('update_replication_server: ' || item_not_found(l_obj_name,
                                                               l_obj_type));
      sys.dbms_sys_error.raise_system_error(OBJ_NOT_FOUND_NUM,
                                              l_obj_name,
                                              l_obj_type,
                                              FALSE);
    ELSE
      RAISE;
    END IF;
 
  WHEN DUP_VAL_ON_INDEX THEN
    IF l_obj_type IS NOT NULL THEN
      sys.dbms_sys_error.raise_system_error(DUP_NAME_NUM,
                                            l_obj_name,
                                            l_obj_type,
                                            FALSE);
    ELSE
      RAISE;
    END IF;
 
  WHEN REP_SRVR_HOST_NOT_CONFIG OR REP_SRVR_BAD_PORT OR
       REP_SRVR_PORT_NULL OR REP_SRVR_PROXY_NULL THEN
    ROLLBACK;
    am_trace ('update_replication_server: Max length of '
              || ' replication_server_name is 128 chars: '
              || replication_server_name);
    RAISE;
    
  WHEN REP_SRVR_RUNNING THEN
    ROLLBACK;
    am_trace('update_replication_server: Attempt to update a non-paused ' || 
             ' replication_server=' || replication_server_name);
    sys.dbms_sys_error.raise_system_error(REP_SRVR_RUNNING_NUM,
                                          replication_server_name,
                                          FALSE);
 
  WHEN OTHERS THEN
    ROLLBACK;
    am_trace ('update_replication_server exception: ' ||
              replication_server_name || ' err:' || SQLERRM);
    IF (l_grant_network) THEN
       grant_network_acl_ace(l_old_server.filter_user,
                             l_old_server.wallet_alias,
                             l_old_server.wallet_path);
    END IF;
    RAISE;
END update_replication_server_int;
--
 
PROCEDURE update_replication_server (
                                replication_server_name IN VARCHAR2,
                                sbt_so_name          IN VARCHAR2 DEFAULT NULL,
                                sbt_parms            IN VARCHAR2 DEFAULT NULL,
                                max_streams          IN NUMBER   DEFAULT
                                                dbms_ra_int.number2null('p4'),
                                catalog_user_name    IN VARCHAR2 DEFAULT NULL,
                                wallet_alias         IN VARCHAR2 DEFAULT NULL,
                                wallet_path          IN VARCHAR2 DEFAULT
                                            dbms_ra_int.varchar2null('p1'),
                                proxy_url            IN VARCHAR2 DEFAULT
                                            dbms_ra_int.varchar2null('p2'),
                                proxy_port           IN NUMBER   DEFAULT
                                            dbms_ra_int.number2null('p3'),
                                http_timeout         IN NUMBER   DEFAULT NULL)
 
IS
  l_the              NUMBER;
  c_rep_srv_name     server.rep_server_name%TYPE;
  u_catalog_user_name server.filter_user%TYPE;
BEGIN
  dbms_ra_int.canonicalize(replication_server_name, c_rep_srv_name, 128);
  IF is_sysgen_obj(c_rep_srv_name) THEN
    sys.dbms_sys_error.raise_system_error
       (API_BAD_OBJECT_NUM, 'replication server', 'system object', FALSE);
  END IF;
 
  u_catalog_user_name := upper(catalog_user_name);
 
  lock_api(LOCKAPI_MODIFY, 'update_replication_server');
 
  l_the := dbms_ra_scheduler.add_to_task_history_table (
              task_type => dbms_ra_scheduler.TASK_API_UPD_REP_SERVER,
              param     => 'update_replication_server' ||
               b_p('replication_server_name', replication_server_name, 
                                p_first=>TRUE) ||
               b_p('sbt_so_name',    sbt_so_name                 ) ||
               b_p('sbt_parms',      sbt_parms                   ) ||
               b_p('max_streams',    max_streams                 ) ||
               b_p('catalog_user_name', u_catalog_user_name      ) ||
               b_p('wallet_alias',   wallet_alias                ) ||
               b_p('wallet_path',    wallet_path                 ) ||
               b_p('proxy_url',      proxy_url                   ) ||
               b_p('proxy_port',     proxy_port                  ) ||
               b_p('http_timeout',   http_timeout , p_last=>TRUE));
 
  update_replication_server_int (c_rep_srv_name,
                                 sbt_so_name,
                                 sbt_parms,
                                 max_streams,
                                 u_catalog_user_name,
                                 wallet_alias,
                                 wallet_path,
                                 proxy_url,
                                 proxy_port,
                                 http_timeout);
  unlock_api(p_the_num=>l_the, p_results=>TRUE, p_docommit=>TRUE);
EXCEPTION
  WHEN OTHERS THEN
    rollback;
    unlock_api(p_the_num=>l_the, p_results=>FALSE, p_docommit=>TRUE);
    RAISE;
END update_replication_server;
--
 
 
 
--
--
--
--
--
--
PROCEDURE delete_replicated_backups(p_db_key      IN NUMBER,
                                    p_sbt_lib_key IN NUMBER,
                                    p_force_del   IN BOOLEAN DEFAULT FALSE)
IS
  l_skip_cnt    NUMBER := 0;
  l_dbid        NUMBER;
  l_currinc     NUMBER;
BEGIN
  IF p_db_key IS NULL OR p_sbt_lib_key IS NULL THEN
--
    SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(E_INTERNAL_ERROR_NUM,
                                          'missing db/sbt_lib key');
  END IF;
 
--
--
  FOR d IN (SELECT bp_key, c.handle, c.pieceinc, bp.db_key
            FROM sbt_catalog c
            LEFT OUTER JOIN bp USING (bp_key)
            WHERE bp.lib_key = p_sbt_lib_key
            AND bp.status NOT in ('D', 'X')
            AND bp.db_key = p_db_key
            AND c.db_key = p_db_key
            ) LOOP
 
--
    SELECT db.db_id, db.curr_dbinc_key
      INTO l_dbid, l_currinc
      FROM db
      WHERE db.db_key = d.db_key;
 
    BEGIN
      DBMS_RA_STORAGE.FREE_BACKUP_PIECE_OPT(
            p_dbkey     => d.db_key,
            p_piecename => d.handle,
            p_db_slkey  => NULL,
            p_dbid      => l_dbid,
            p_currinc   => l_currinc,
            p_bpkey     => d.bp_key,
            p_ftype     => DBMS_RA_INT.KBRSCHKTYPE_TAPE,
            p_libkey    => p_sbt_lib_key,
            p_spawn_job => FALSE,
            p_notasks   => TRUE);
        am_trace ('DELETE_REPLICATED_BACKUPS: Delete replicated bp record ' ||
                  d.handle || ' bpkey ' || d.bp_key);
 
    EXCEPTION
      WHEN dbms_ra_scheduler.e_retry_error THEN
--
--
--
        am_trace ('DELETE_REPLICATED_BACKUPS: Unable to delete locked bp ' ||
                  'record ' ||  d.handle || ' bpkey ' || d.bp_key);
        l_skip_cnt := l_skip_cnt + 1;
    END;
  END LOOP;
 
--
  IF p_force_del AND l_skip_cnt > 0 THEN
    update_bps_for_delete_lib_int(p_db_key, p_sbt_lib_key);
  END IF;
 
END;
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE delete_replication_server_int (p_rep_server_name IN VARCHAR2,
                                         p_force IN BOOLEAN DEFAULT FALSE)
IS
  l_sbt_lib_name     sbt_lib_desc.lib_name%TYPE;
  l_sbt_lib_key      NUMBER;
  l_server_key       NUMBER;
  r_server           server%ROWTYPE;
  r_sbt_lib_desc     sbt_lib_desc%ROWTYPE;
  l_cnt              NUMBER;
  l_restorecnt       NUMBER;
  l_errors           BOOLEAN:=FALSE;
  l_gotlock          BOOLEAN := FALSE;
  l_bpkey            NUMBER;
  l_task_rec         task%ROWTYPE;
  l_sbt_lib_found    BOOLEAN := FALSE;
  l_dbid             NUMBER;
  l_currinc          NUMBER;
  l_rep_lib_name     sbt_lib_desc.lib_name%TYPE;
 
  CURSOR rep_server_cursor IS 
    SELECT prot_name
    FROM prot, rep_server
    WHERE prot.prot_key = rep_server.prot_key
        AND rep_server.server_key = l_server_key;
    
BEGIN
  
  am_trace('DELETE_REPLICATION_SERVER: replication_server_name=' || 
            p_rep_server_name);
  
--
  
--
  SELECT COUNT(*) INTO l_cnt
    FROM server
    WHERE server.rep_server_name=p_rep_server_name;
    
  IF l_cnt = 0 THEN
    am_trace('DELETE_REPLICATION_SERVER: replication_server_name=' || 
             p_rep_server_name || ' was not found.');
    RAISE NO_DATA_FOUND;
  END IF;
  
--
  SELECT s.server_key
    INTO l_server_key
    FROM server s
    WHERE s.rep_server_name = p_rep_server_name;
  
--
  SELECT COUNT(*) INTO l_cnt
    FROM rep_server
    WHERE rep_server.server_key=l_server_key;
  
  IF l_cnt != 0 AND p_force = FALSE THEN
--
    am_trace('DELETE_REPLICATION_SERVER: replication_server_name=' || 
             p_rep_server_name || ' - attempted to delete while ' ||
             'still associated with a protection policy.  Either ' ||
             'remove_replication_server or use force==TRUE option.');
    RAISE OBJ_IS_REFERENCED;
  END IF;
  
--
  
--
--
--
  UPDATE rep_server
    SET status = 'D'
    WHERE server_key = l_server_key;
  IF SQL%ROWCOUNT = 0 THEN
    am_trace ('DELETE_REPLICATION_SERVER: RS ' || p_rep_server_name ||
              ' unable to find associated rep_server entry');
  END IF;
  COMMIT;
 
--
  l_sbt_lib_found := TRUE;
  BEGIN
    SELECT l.lib_key, l.lib_name, s.filter_user, s.wallet_alias, s.wallet_path
      INTO l_sbt_lib_key, l_sbt_lib_name,
      r_server.filter_user, r_server.wallet_alias, r_server.wallet_path
      FROM sbt_lib_desc l, server s
      WHERE s.server_key = l_server_key
        AND l.server_key = s.server_key;
  EXCEPTION
    WHEN NO_DATA_FOUND THEN
      am_trace ('DELETE_REPLICATION_SERVER: RS ' || p_rep_server_name ||
                ' unable to find associated sbt_library');
      l_sbt_lib_found := FALSE;
  END;
 
  am_trace('DELETE_REPLICATION_SERVER: Deleting: replication_server_name=' ||
            p_rep_server_name ||
           ', l_sbt_lib_key =' || l_sbt_lib_key ||
           ', l_server_key=' || l_server_key);
 
--
  IF l_sbt_lib_found THEN
    l_rep_lib_name := dbms_ra_int.build_rep_lib_name(p_rep_server_name);
    pause_sbt_library_int(l_rep_lib_name);
  END IF;
 
--
--
--
--
--
--
  IF l_sbt_lib_found THEN
    SELECT COUNT(*) INTO l_restorecnt
      FROM config c, task t, sbt_task st
      WHERE t.task_type = DBMS_RA_SCHEDULER.TASK_RESTORE_SBT
        AND t.state = DBMS_RA_SCHEDULER.STATE_RUNNING
        AND st.task_id = t.task_id
        AND st.lib_key = l_sbt_lib_key
        AND c.name = '_recovery_appliance_state'
        AND c.value = 'ON';
 
    IF l_restorecnt != 0 THEN
      am_trace('DELETE_REPLICATION_SERVER: Aborting - found ' || l_restorecnt||
               'running restore tasks');
      sys.dbms_sys_error.raise_system_error(REP_SERVER_ACTIVE_NUM, FALSE);
    END IF;
  END IF;
 
 
--
--
--
--
--
--
 
--
--
  IF l_sbt_lib_found THEN
    LOOP
      am_trace('DELETE_REPLICATION_SERVER: Waiting on running reconcile tasks');
      SELECT COUNT(*) INTO l_cnt
        FROM config c, odb o, rep_server r, task t
        WHERE task_type = DBMS_RA_SCHEDULER.TASK_RECONCILE
          AND r.server_key = l_server_key
          AND r.prot_key = o.prot_key
          AND o.db_key = t.db_key
          AND c.name = '_recovery_appliance_state'
          AND c.value = 'ON'
          AND ROWNUM = 1;
      EXIT WHEN l_cnt = 0;
      DBMS_LOCK.SLEEP(10);
    END LOOP;
  END IF;
 
--
--
--
  IF l_sbt_lib_found THEN
    am_trace ('DELETE_REPLICATION_SERVER: Deleting backup piece records ' ||
              'l_server_key = ' || l_server_key);
 
    FOR dbrec IN (SELECT o.db_key
                  FROM odb o, rep_server rs
                  WHERE rs.server_key = l_server_key
                  AND o.prot_key = rs.prot_key
                  ORDER BY db_key) LOOP
      am_trace ('DELETE_REPLICATION_SERVER: Deleting backup piece records' ||
                ' for ' || dbms_ra_int.dbkey2name(dbrec.db_key));
      delete_replicated_backups(p_db_key      => dbrec.db_key,
                                p_sbt_lib_key => l_sbt_lib_key,
                                p_force_del   => FALSE);
    END LOOP;
  END IF;
 
--
  IF l_cnt != 0 AND p_force = TRUE THEN
    FOR f IN rep_server_cursor LOOP
      BEGIN
        am_trace ('DELETE_REPLICATION_SERVER: Removing rep from prot');
        remove_rep_from_prot_int(p_rep_server_name, f.prot_name, FALSE);
      EXCEPTION
        WHEN OBJ_NOT_FOUND THEN
          am_trace ('DELETE_REPLICATION_SERVER: RS ' || p_rep_server_name ||
                    ' rep_server entry not found for protection policy ' ||
                    f.prot_name);
--
          NULL;
      END;
    END LOOP;
  END IF;
 
--
  BEGIN
    delete_repository(r_server.filter_user,
                      r_server.wallet_alias,
                      r_server.wallet_path);
  EXCEPTION
    WHEN NO_DATA_FOUND THEN
--
      am_trace ('DELETE_REPLICATION_SERVER: RS ' || p_rep_server_name ||
                ' delete_repository data not found ');
      NULL;
  END;
 
--
--
--
  COMMIT;
 
  BEGIN
    if l_sbt_lib_key IS NOT NULL THEN
--
     IF NOT DBMS_RA_INT.WRITE_LOCK_WAIT(DBMS_RA_INT.KEY_SY,l_sbt_lib_key) THEN
       am_trace ('DELETE_REPLICATION_SERVER: SBT lib entry no longer exists');
--
--
--
      END IF;
      l_gotlock := TRUE;
    END IF;
 
--
--
    delete_sbt_library_int(l_sbt_lib_name, FALSE);
  EXCEPTION
    WHEN OBJ_NOT_FOUND THEN
--
      am_trace ('DELETE_REPLICATION_SERVER: RS ' || p_rep_server_name ||
                ' delete_sbt_library_int data not found ');
      NULL;
  END;
 
--
  COMMIT;
 
--
  IF l_gotlock THEN
    DBMS_RA_INT.UNLOCK(DBMS_RA_INT.KEY_SY, l_sbt_lib_key);
    l_gotlock := FALSE;
  END IF;
 
EXCEPTION
  WHEN OBJ_IS_REFERENCED THEN
    IF l_gotlock THEN
        DBMS_RA_INT.UNLOCK(DBMS_RA_INT.KEY_SY, l_sbt_lib_key);
    END IF;
    am_trace ('DELETE_REPLICATION_SERVER: RS ' || p_rep_server_name ||
              ' is currently associated with protection policy use force' ||
              ' option or call remove_replication_server' );
    sys.dbms_sys_error.raise_system_error(OBJ_IS_REFERENCED_NUM,
              p_rep_server_name,
              'replication server has an existing protection policy',
              FALSE);
 
  WHEN NO_DATA_FOUND THEN
    IF l_gotlock THEN
        DBMS_RA_INT.UNLOCK(DBMS_RA_INT.KEY_SY, l_sbt_lib_key);
    END IF;
    
    am_trace('DELETE_REPLICATION_SERVER: ' ||
                item_not_found(p_rep_server_name,'replication server name'));
    sys.dbms_sys_error.raise_system_error(OBJ_NOT_FOUND_NUM,
                                          p_rep_server_name,
                                          'replication server name',
                                          FALSE);
 
  WHEN OTHERS THEN
    IF l_gotlock THEN
        DBMS_RA_INT.UNLOCK(DBMS_RA_INT.KEY_SY, l_sbt_lib_key);
    END IF;
    am_trace ('delete_replication_server exception: RS ' || 
              p_rep_server_name || ' err:' || SQLERRM);
    sys.dbms_sys_error.raise_system_error(OBJ_IS_REFERENCED_NUM,
              p_rep_server_name,
              'replication server encountered an exception',
              TRUE);
 
END delete_replication_server_int;
--
 
PROCEDURE delete_replication_server (replication_server_name IN VARCHAR2,
                                     force IN BOOLEAN DEFAULT FALSE)
IS
  l_the              NUMBER;
  c_rep_srv_name     server.rep_server_name%TYPE;
 
BEGIN
  dbms_ra_int.canonicalize(replication_server_name, c_rep_srv_name, 128);
  IF is_sysgen_obj(c_rep_srv_name) THEN
    sys.dbms_sys_error.raise_system_error
       (API_BAD_OBJECT_NUM, 'replication server', 'system object', FALSE);
  END IF;
 
  lock_api(LOCKAPI_DELETE, 'delete_replication_server');
 
  l_the := dbms_ra_scheduler.add_to_task_history_table (
              task_type => dbms_ra_scheduler.TASK_API_DEL_REP_SERVER,
              param     => 'delete_replication_server' ||
              b_p('replication_server_name', replication_server_name, 
                    p_first=>TRUE) ||
              b_p('force', force, p_last=>TRUE));
 
--
--
--
--
  ctrl_c_check(CCCHK_CREDEL_REP_SERVER);
 
  delete_replication_server_int (c_rep_srv_name, force);
  unlock_api(p_the_num=>l_the, p_results=>TRUE, p_docommit=>TRUE);
  
EXCEPTION
  WHEN OTHERS THEN
--
--
--
    COMMIT;
    unlock_api(p_the_num=>l_the, p_results=>FALSE, p_docommit=>TRUE);
    RAISE;
    
END delete_replication_server;
--
 
 
--
--
--
--
--
--
--
--
--
 
--
--
--
--
--
--
PROCEDURE add_rep_to_prot_int (p_replication_server_name IN VARCHAR2,
                               p_protection_policy_name IN VARCHAR2)
IS
  l_repsrv_key              NUMBER := NULL;
  l_prot_key                NUMBER := NULL;
  l_server_key              NUMBER := NULL;
  l_obj_type                VARCHAR2(128);
  l_obj_name                VARCHAR2(128);
  l_cnt                     NUMBER;
  l_lib_key                 NUMBER;
  l_template_name           sbt_job_template.template_name%TYPE;
  l_db_unique_name          node.db_unique_name%TYPE;
  l_all_reconciled          BOOLEAN := TRUE;
  l_invalid_val             VARCHAR2(128);
  l_msg                     VARCHAR2(128);
  l_ckpt                    NUMBER := 0;
  l_success                 BOOLEAN;
  l_num_rec                 NUMBER;
  l_tot_rec                 NUMBER := 0;
  l_last_rec                timestamp;
  l_rep_atr_name            sbt_attr_set.attr_name%TYPE;
 
  CURSOR odbcur IS SELECT db_key
    FROM odb
    WHERE odb.prot_key = l_prot_key
--
      AND odb.db_state IS NULL;
 
BEGIN
--
  BEGIN
    SELECT prot_key
      INTO l_prot_key
      FROM prot
      WHERE prot.prot_name = p_protection_policy_name;
  EXCEPTION
    WHEN NO_DATA_FOUND THEN
      l_obj_type := 'protection policy';
      l_obj_name := p_protection_policy_name;
      RAISE OBJ_NOT_FOUND;
  END;
  
--
  BEGIN
    SELECT server_key
      INTO l_server_key
      FROM server
      WHERE server.rep_server_name = p_replication_server_name;
  EXCEPTION
    WHEN NO_DATA_FOUND THEN
      l_obj_type := 'replication server';
      l_obj_name := p_replication_server_name;
      RAISE OBJ_NOT_FOUND;
  END;
 
--
--
  SELECT COUNT(*) 
    INTO l_cnt 
    FROM rep_server
    WHERE server_key=l_server_key
      AND prot_key=l_prot_key;
 
  IF (l_cnt > 0) THEN
    RETURN;
  END IF;
 
--
  l_repsrv_key := rman_seq.nextval;
  INSERT INTO rep_server (rep_server_key,
                          server_key,
                          prot_key, 
                          status)
    VALUES (l_repsrv_key, l_server_key, l_prot_key, 'C');
  COMMIT;
 
 
--
--
--
--
--
 
--
--
  SELECT lib_key INTO l_lib_key
    FROM sbt_lib_desc
    WHERE server_key = l_server_key;
 
  FOR f IN odbcur LOOP
--
    UPDATE odb
      SET pending_rep_setup = 'Y',
          last_reconcile = NULL,
          next_reconcile = NULL,
          last_replication = NULL
      WHERE db_key = f.db_key;
    COMMIT;
 
--
--
    l_success := dbms_ra_scheduler.reconcile_db (
                               p_db_key          => f.db_key,
                               p_server_key      => l_server_key,
                               p_only_active     => FALSE,
                               p_force_reconcile => TRUE,
                               rec_cnt           => l_num_rec);
    IF NOT l_success OR l_num_rec <> 1 THEN
      l_all_reconciled := FALSE;
      l_msg := 'REP_REC CKPT=' || l_ckpt;
      dbms_ra_scheduler.log_error (p_errno      => REP_SETUP_ERROR_NUM,
                             p_param1     => 'reconcile',
                             p_param2     => p_replication_server_name,
                             p_param3     => dbms_ra_int.dbkey2name(f.db_key),
                             P_keep_stack => FALSE,
                             p_component  => 'REPLICATION_SETUP',
                             p_severity   => dbms_ra_scheduler.SEVERITY_ERROR,
                             p_param_char => l_msg,
                             p_param_num  => f.db_key);
    ELSE
--
--
      dbms_ra_scheduler.fix_error (
                                 p_error_num  => dbms_ra.REP_SETUP_ERROR_NUM,
                                 p_db_key     => f.db_key,
                                 p_param_char => 'RECONCILE');
      l_tot_rec := l_tot_rec + 1;
    END IF;
  END LOOP;
  
--
--
--
--
--
  UPDATE rep_server
    SET status = 'A'
    WHERE rep_server_key = l_repsrv_key;
 
  UPDATE sbt_lib_desc
    SET status = 'R'
    WHERE lib_key = l_lib_key;
 
--
--
  COMMIT;
 
--
  
--
  IF l_tot_rec > 0 THEN
    FOR f IN odbcur LOOP
      BEGIN
        SELECT last_reconcile INTO l_last_rec
          FROM odb
          WHERE db_key = f.db_key;
        IF l_last_rec = 0 OR l_last_rec IS NULL THEN
--
          CONTINUE;
        END IF;
 
        l_ckpt := 1;
        l_db_unique_name := dbms_ra_int.dbkey2name(f.db_key);
 
        l_ckpt := 2;
--
        dbms_ra_scheduler.queue_set_reconcile_timer (f.db_key);
 
        l_ckpt := 3;
--
--
        l_template_name := dbms_ra_int.build_rep_tpl_name (
                                     rep_srv_name => p_replication_server_name,
                                     db_key       => f.db_key,
                                     prot_key     => l_prot_key);
 
        l_ckpt := 4;
        BEGIN
          l_rep_atr_name :=
             dbms_ra_int.build_rep_atr_name(p_replication_server_name);
          dbms_ra_int.create_sbt_job_template_int(
                                    template_name  => l_template_name,
                                    db_unique_name => l_db_unique_name,
                                    attr_name      => l_rep_atr_name,
                                    backup_type    => 'ALL',
                                    do_commit      => TRUE);
        EXCEPTION
          WHEN DUP_NAME THEN
--
            NULL;
        END;
 
        UPDATE odb
          SET pending_rep_setup = 'N'
          WHERE db_key = f.db_key;
        COMMIT;
 
--
        l_ckpt := 5;
        dbms_ra_scheduler.replicate_existing_backups(
                            p_template_name => l_template_name);
 
      EXCEPTION
        WHEN OTHERS THEN
--
--
--
--
          l_msg := 'REP_INIT CKPT=' || l_ckpt;
          dbms_ra_scheduler.log_error (p_errno      => REP_SETUP_ERROR_NUM,
                                   p_param1     => 'initial replication',
                                   p_param2     => p_replication_server_name,
                                   p_param3     => l_db_unique_name,
                                   P_keep_stack => FALSE,
                                   p_component  => 'REPLICATION_INITREP',
                                   p_severity   =>
                                       dbms_ra_scheduler.SEVERITY_ERROR,
                                   p_param_char => l_msg,
                                   p_param_num  => f.db_key);
          ROLLBACK;
 
--
--
          UPDATE sbt_lib_desc
           SET status =
                  (CASE WHEN failure_cnt + 1 <
                             dbms_ra_scheduler.s_max_sbt_failures THEN 'R'
                   ELSE 'E' END),
               failure_cnt = failure_cnt + 1
           WHERE status = 'R'
             AND lib_key = l_lib_key;
 
          COMMIT;
          RAISE;
      END;
    END LOOP;
  END IF;
 
EXCEPTION
  WHEN MISSING_INIT_REP_TYPE THEN
--
    am_trace ('add_replication_server: required intial_replication ' ||
              'parameter not defined');
    RAISE;
 
  WHEN OBJ_NOT_FOUND THEN
--
    IF l_obj_type IS NOT NULL THEN
      am_trace ('add_replication_server: ' || item_not_found(l_obj_name,
                                                             l_obj_type));
      sys.dbms_sys_error.raise_system_error(OBJ_NOT_FOUND_NUM,
                                            l_obj_name,
                                            l_obj_type,
                                            FALSE);
    ELSE
      RAISE;
    END IF;
 
  WHEN OTHERS THEN
    ROLLBACK;
    am_trace ('add_replication_server exception: ' ||
              ' replication_server_name:'   || p_replication_server_name ||
              ', protection_policy_name:'   || p_protection_policy_name ||
              ', err:' || SQLERRM);
    RAISE;
 
END add_rep_to_prot_int;
--
 
PROCEDURE add_replication_server (replication_server_name IN VARCHAR2,
                                  protection_policy_name IN VARCHAR2)
IS
  l_the                     NUMBER;
  c_rep_srv_name            server.rep_server_name%TYPE;
  c_protection_policy_name  prot.prot_name%TYPE;
  
BEGIN
  dbms_ra_int.canonicalize(replication_server_name, c_rep_srv_name, 128);
  IF is_sysgen_obj(c_rep_srv_name) THEN
    sys.dbms_sys_error.raise_system_error
       (API_BAD_OBJECT_NUM, 'replication server', 'system object', FALSE);
  END IF;
 
  lock_api(LOCKAPI_CREATE, 'add_replication_server');
  
  l_the := dbms_ra_scheduler.add_to_task_history_table (
                task_type => dbms_ra_scheduler.TASK_API_ADD_REP_SERVER,
                param     => 'add_replication_server' ||
                  b_p('replication_server_name', replication_server_name,
                         p_first=>TRUE) ||
                  b_p('protection_policy_name', protection_policy_name, 
                         p_last=>TRUE));
 
  dbms_ra_int.canonicalize(protection_policy_name,
                            c_protection_policy_name, 128);
 
  add_rep_to_prot_int (c_rep_srv_name, c_protection_policy_name);
  unlock_api(p_the_num=>l_the, p_results=>TRUE, p_docommit=>TRUE);
  
EXCEPTION
  WHEN OTHERS THEN
    rollback;
    unlock_api(p_the_num=>l_the, p_results=>FALSE, p_docommit=>TRUE);
    RAISE;
END add_replication_server;
--
 
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE remove_rep_from_prot_int (p_replication_server_name IN VARCHAR2,
                                    p_protection_policy_name IN VARCHAR2,
                                    do_commit     IN BOOLEAN DEFAULT TRUE)
IS
  l_repsrv_key              NUMBER := NULL;
  l_prot_key                NUMBER := NULL;
  l_db_key                  NUMBER := NULL;
  l_server_key              NUMBER := NULL;
  l_lib_key                 NUMBER := NULL;
  l_obj_type                VARCHAR2(128);
  l_obj_name                VARCHAR2(128);
  l_cnt                     NUMBER;
  l_template_name           sbt_job_template.template_name%TYPE;
  l_db_unique_name          node.db_unique_name%TYPE;
 
  CURSOR odbcur IS SELECT db_key
    FROM odb
    WHERE odb.prot_key = l_prot_key
--
      AND odb.db_state IS NULL;
 
BEGIN
  
--
  BEGIN
    SELECT prot_key
      INTO l_prot_key
      FROM prot
      WHERE prot.prot_name = p_protection_policy_name;
  EXCEPTION
    WHEN NO_DATA_FOUND THEN
      l_obj_type := 'protection policy';
      l_obj_name := p_protection_policy_name;
      RAISE OBJ_NOT_FOUND;
  END;
 
--
  BEGIN
    SELECT server_key
      INTO l_server_key
      FROM server
      WHERE server.rep_server_name = p_replication_server_name;
  EXCEPTION
    WHEN NO_DATA_FOUND THEN
      l_obj_type := 'replication server';
      l_obj_name := p_replication_server_name;
      RAISE OBJ_NOT_FOUND;
  END;
  
--
--
--
  UPDATE rep_server
    SET status = 'D'
    WHERE server_key = l_server_key
      AND prot_key = l_prot_key;
  COMMIT;
 
--
  FOR f IN odbcur LOOP
    BEGIN
      l_db_unique_name := dbms_ra_int.dbkey2name(f.db_key);
 
      l_template_name := dbms_ra_int.build_rep_tpl_name (
                                     rep_srv_name => p_replication_server_name,
                                     db_key       => f.db_key,
                                     prot_key     => l_prot_key);
 
      remove_rep_tasks(p_db_key => f.db_key, p_template => l_template_name);
 
      delete_sbt_job_template_int(template_name  => l_template_name,
                                  do_commit => FALSE);
    EXCEPTION
      WHEN OBJ_NOT_FOUND THEN
        am_trace ('remove_replication_server: ' ||
                  ' skipping removal of sbt_job_template: ' ||
                  ' replication_server_name:'   || p_replication_server_name ||
                  ', protection_policy_name:'   || p_protection_policy_name);
        NULL;
 
      WHEN OTHERS THEN
        ROLLBACK;
        am_trace ('remove_replication_server: ' || 
                  'unable to remove sbt_job_template' || SQLERRM ||
                  ' replication_server_name:'   || p_replication_server_name ||
                  ', protection_policy_name:'   || p_protection_policy_name);
        RAISE;      
    END;
  END LOOP;
  
--
  DELETE FROM rep_server
    WHERE rep_server.server_key = l_server_key
      AND rep_server.prot_key = l_prot_key;
 
--
--
  SELECT count(*)
    INTO l_cnt
    FROM rep_server
    WHERE prot_key = l_prot_key
    AND status <> 'D';
--
  IF l_cnt = 0 THEN
    UPDATE odb
      SET pending_rep_setup = NULL,
          next_reconcile = NULL,
          last_reconcile = NULL,
          last_replication = NULL
      WHERE prot_key = l_prot_key;
  END IF;
 
  IF do_commit THEN
    COMMIT;
  END IF;
    
EXCEPTION
  WHEN OBJ_NOT_FOUND THEN
--
    IF l_obj_type IS NOT NULL THEN
      am_trace ('remove_replication_server: ' || item_not_found(l_obj_name,
                                                                l_obj_type));
      sys.dbms_sys_error.raise_system_error(OBJ_NOT_FOUND_NUM,
                                            l_obj_name,
                                            l_obj_type,
                                            FALSE);
    ELSE
      RAISE;
    END IF;
 
  WHEN OTHERS THEN
    ROLLBACK;
    am_trace ('remove_replication_server exception: ' ||
              ' replication_server_name:'   || p_replication_server_name ||
              ', protection_policy_name:'   || p_protection_policy_name ||
              ', err:' || SQLERRM);
    RAISE;
 
END remove_rep_from_prot_int;
--
PROCEDURE remove_replication_server (replication_server_name IN VARCHAR2,
                                     protection_policy_name IN VARCHAR2)
IS
  l_the                     NUMBER;
  c_rep_srv_name            server.rep_server_name%TYPE;
  c_protection_policy_name  prot.prot_name%TYPE;
 
BEGIN
  dbms_ra_int.canonicalize(replication_server_name, c_rep_srv_name, 128);
  IF is_sysgen_obj(c_rep_srv_name) THEN
    sys.dbms_sys_error.raise_system_error
       (API_BAD_OBJECT_NUM, 'replication server', 'system object', FALSE);
  END IF;
 
  lock_api(LOCKAPI_DELETE, 'remove_replication_server');
 
  l_the := dbms_ra_scheduler.add_to_task_history_table (
                task_type => dbms_ra_scheduler.TASK_API_REM_REP_SERVER,
                param     => 'remove_replication_server' ||
                  b_p('replication_server_name', replication_server_name,
                         p_first=>TRUE) ||
                  b_p('protection_policy_name', protection_policy_name,
                         p_last=>TRUE));
 
  dbms_ra_int.canonicalize(protection_policy_name, 
                            c_protection_policy_name, 128);
 
  remove_rep_from_prot_int (c_rep_srv_name, c_protection_policy_name, TRUE);
  unlock_api(p_the_num=>l_the, p_results=>TRUE, p_docommit=>TRUE);
  
EXCEPTION
  WHEN OTHERS THEN
    rollback;
    unlock_api(p_the_num=>l_the, p_results=>FALSE, p_docommit=>TRUE);
    RAISE;
END remove_replication_server;
--
 
 
 
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE pause_replication_server  (replication_server_name IN VARCHAR2)
IS
  l_the             NUMBER;
  c_rep_srv_name    server.rep_server_name%TYPE;
  l_rep_lib_name    sbt_lib_desc.lib_name%TYPE;
BEGIN
  dbms_ra_int.canonicalize(replication_server_name, c_rep_srv_name, 128);
  IF is_sysgen_obj(c_rep_srv_name) THEN
    sys.dbms_sys_error.raise_system_error
       (API_BAD_OBJECT_NUM, 'replication server', 'system object', FALSE);
  END IF;
  l_rep_lib_name := dbms_ra_int.build_rep_lib_name(c_rep_srv_name);
 
  lock_api(LOCKAPI_MODIFY, 'pause_replication_server');
 
  l_the := dbms_ra_scheduler.add_to_task_history_table (
             task_type => dbms_ra_scheduler.TASK_API_PAU_REP_SRV,
             param     => 'pause_replication_server' ||
             b_p('replication_server_name', replication_server_name, 
                   p_first=>TRUE, p_last=>TRUE));
 
  pause_sbt_library_int(l_rep_lib_name);
  unlock_api();
 
EXCEPTION
  WHEN OTHERS THEN
    unlock_api();
    RAISE;
END pause_replication_server;
 
 
--
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE resume_replication_server  (replication_server_name IN VARCHAR2)
IS
  l_the             NUMBER;
  c_rep_srv_name    server.rep_server_name%TYPE;
  l_rep_lib_name    sbt_lib_desc.lib_name%TYPE;
 
BEGIN
  dbms_ra_int.canonicalize(replication_server_name, c_rep_srv_name, 128);
  IF is_sysgen_obj(c_rep_srv_name) THEN
    sys.dbms_sys_error.raise_system_error
       (API_BAD_OBJECT_NUM, 'replication server', 'system object', FALSE);
  END IF;
  l_rep_lib_name := dbms_ra_int.build_rep_lib_name(c_rep_srv_name);
 
  lock_api(LOCKAPI_MODIFY, 'resume_replication_server');
 
  l_the := dbms_ra_scheduler.add_to_task_history_table (
             task_type => dbms_ra_scheduler.TASK_API_RES_REP_SRV,
             param     => 'resume_replication_server' ||
             b_p('replication_server_name', replication_server_name, 
                   p_first=>TRUE, p_last=>TRUE));
 
  resume_sbt_library_int(l_rep_lib_name);
  unlock_api();
EXCEPTION
  WHEN OTHERS THEN
    unlock_api();
    RAISE;
END resume_replication_server;
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE manage_user_int
  (create_vpc IN BOOLEAN, username IN VARCHAR2, db_unique_name IN VARCHAR2)
IS
  l_db_key    NUMBER := NULL;
  l_dbid      NUMBER := NULL;
  l_user_id   NUMBER;
BEGIN
  begin
    select db.db_key, db.db_id into l_db_key, l_dbid from node, db
      where db_unique_name = upper(manage_user_int.db_unique_name)
        and node.db_key = db.db_key
--
--
        and not exists (select db_state
                          from odb
                         where odb.db_key = node.db_key
                           and db_state is not null);
  exception
    when no_data_found then
      l_dbid := 0;
  end;
  IF create_vpc THEN
--
    dbms_rcvcat.grant_catalog(username, l_dbid, db_unique_name);
    am_trace('grant_register suceeded for ' || username || ' and db ' ||
             db_unique_name);
  ELSE
--
    dbms_rcvcat.revoke_catalog(username, l_dbid, db_unique_name);
    am_trace('revoke_register suceeded for ' || username || ' and db ' ||
             db_unique_name);
  END IF;
 
END manage_user_int;
   
 
PROCEDURE grant_db_access (username IN VARCHAR2, 
                           db_unique_name IN VARCHAR2)
IS
  canon_username                DBMS_QUOTED_ID;
  l_the                         NUMBER;
  l_db_unique_name              VARCHAR2(128);
  l_db_key                      NUMBER;
  USER_NOT_EXISTS_NATIVE        EXCEPTION; PRAGMA EXCEPTION_INIT (
  USER_NOT_EXISTS_NATIVE,                          -01917        );
 
BEGIN
  IF (upper(username)='SYS') THEN
    RAISE NOT_OAMADMIN;
  END IF;
 
  lock_api(LOCKAPI_CREATE, 'grant_db_access');
  
  l_the := dbms_ra_scheduler.add_to_task_history_table (
                  task_type => dbms_ra_scheduler.TASK_API_GRANT_DB,
                  param     => 'grant_db_access' ||
                   b_p('db_unique_name', db_unique_name, p_first=>TRUE) ||
                   b_p('username',       username,  p_last=>TRUE));
 
  dbms_ra_int.canonicalize(username, canon_username, 130);
 
--
  IF '"' || canon_username || '"' = sys.rai_schema THEN
    RAISE NOT_OAMADMIN;
  END IF;
 
  manage_user_int(TRUE, canon_username, upper(db_unique_name));
  manage_privilege_int(upper(db_unique_name),
                       AM_SEC_OPERATION_GRANT,
                       AM_SEC_PRIVTYPE_ALL,
                       AM_SEC_ACCESSTYPE_ALL,
                       canon_username);
  unlock_api(p_the_num=>l_the, p_results=>TRUE, p_docommit=>TRUE);
   
EXCEPTION
  WHEN USER_NOT_EXISTS_NATIVE THEN
    rollback;
    unlock_api(p_the_num=>l_the, p_results=>FALSE, p_docommit=>TRUE);
    sys.dbms_sys_error.raise_system_error(USER_NOT_EXISTS_NUM,username);
  WHEN OBJ_NOT_FOUND THEN
    rollback;
    unlock_api(p_the_num=>l_the, p_results=>FALSE, p_docommit=>TRUE);
    sys.dbms_sys_error.raise_system_error  (OBJ_NOT_FOUND_NUM,
                                            db_unique_name,
                                            'db unique name',
                                            FALSE);
  WHEN OTHERS THEN
    rollback;
    unlock_api(p_the_num=>l_the, p_results=>FALSE, p_docommit=>TRUE);
    RAISE;
 
END grant_db_access;
--
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE revoke_db_access_int (p_username IN VARCHAR2,
                                p_db_unique_name IN VARCHAR2)
IS
  l_db_unique_name   VARCHAR2(128);
  l_db_key           NUMBER;
 
  CURSOR username_cursor IS 
    SELECT username
    FROM ra_db_access
    WHERE db_unique_name = l_db_unique_name;
 
BEGIN
  l_db_unique_name := upper(p_db_unique_name);
 
  IF p_username IS NOT NULL THEN
--
    am_trace ('revoke_db_access_int: Removing ' || p_username ||
              ' from ' || l_db_unique_name);
    manage_privilege_int(l_db_unique_name,
                         AM_SEC_OPERATION_REVOKE,
                         AM_SEC_PRIVTYPE_ALL,
                         AM_SEC_ACCESSTYPE_ALL,
                         p_username);
    manage_user_int(FALSE, p_username, l_db_unique_name);
  ELSE
--
    FOR u IN username_cursor LOOP
      BEGIN
        am_trace ('revoke_db_access_int: Removing ' || u.username ||
                  ' from ' || l_db_unique_name);
        manage_privilege_int(l_db_unique_name,
                             AM_SEC_OPERATION_REVOKE,
                             AM_SEC_PRIVTYPE_ALL,
                             AM_SEC_ACCESSTYPE_ALL,
                             u.username);
        manage_user_int(FALSE, u.username, l_db_unique_name);
      END;
    END LOOP;
  END IF;
END;
 
--
PROCEDURE revoke_db_access (username IN VARCHAR2,
                            db_unique_name IN VARCHAR2)
IS
  canon_username  DBMS_QUOTED_ID;
  l_the           NUMBER;
BEGIN
  lock_api(LOCKAPI_CREATE, 'revoke_db_access');
  
  l_the := dbms_ra_scheduler.add_to_task_history_table (
                  task_type => dbms_ra_scheduler.TASK_API_REVOKE_DB,
                  param     => 'revoke_db_access' ||
                   b_p('db_unique_name', db_unique_name, p_first=>TRUE) ||
                   b_p('username',       username,  p_last=>TRUE));
 
  dbms_ra_int.canonicalize(username, canon_username, 130);
 
--
  IF '"' || canon_username || '"' = sys.rai_schema THEN
    RAISE NOT_OAMADMIN;
  END IF;
 
  revoke_db_access_int (canon_username, db_unique_name);
  unlock_api(p_the_num=>l_the, p_results=>TRUE, p_docommit=>TRUE);
   
EXCEPTION
  WHEN OBJ_NOT_FOUND THEN
    rollback;
    unlock_api(p_the_num=>l_the, p_results=>FALSE, p_docommit=>TRUE);
    sys.dbms_sys_error.raise_system_error  (OBJ_NOT_FOUND_NUM,
                                            db_unique_name,
                                            'db unique name',
                                            FALSE);
  WHEN OTHERS THEN
    rollback;
    unlock_api(p_the_num=>l_the, p_results=>FALSE, p_docommit=>TRUE);
    RAISE;
 
END revoke_db_access;
--
 
 
--
--
--
--
PROCEDURE populate_backup_piece_int(p_bpkey   IN NUMBER)
 IS
   l_dbkey   NUMBER := NULL;
   l_vbkey   NUMBER := NULL;
   l_slkey   NUMBER;
   l_update  NUMBER := 0;   -- 1 => Disk, 2 => Tape
   l_bskey   NUMBER;
   l_bpkey   NUMBER;
   l_count   NUMBER;
   l_ckpscn  NUMBER;
   l_hasdups BOOLEAN;
   l_nofit   BOOLEAN;
   l_isok    BOOLEAN;
   task_rec  task%ROWTYPE;
BEGIN
   am_trace('Populate_backup_piece - p_bpkey ' || p_bpkey);
 
--
   SELECT MIN(vb_key), MIN(db_key)
     INTO l_vbkey, l_dbkey
     FROM bp
     WHERE status != 'D'
       AND ba_access != 'U'
       AND bp_key = p_bpkey;
   IF l_dbkey IS NULL THEN
     am_trace('Populate_backup_piece: Missing specified backup ' || p_bpkey);
     RAISE UNKNONW_BP;
   END IF;
 
--
   SELECT COUNT(*) INTO l_count
     FROM odb d, bp p
     WHERE d.db_key = p.db_key
       AND d.same_endian = 'U'
       AND p.bp_key = p_bpkey;
   IF l_count > 0 THEN
     am_trace('Populate_backup_piece: Unknown same_endian for db');
     RAISE UNKNOWN_PLATFORM;
   END IF;
 
--
   IF l_vbkey IS NOT NULL THEN
--
     SELECT MAX(ckp_scn) INTO l_ckpscn FROM vbdf WHERE vb_key = l_vbkey;
 
--
     SELECT bp_key INTO l_bpkey
       FROM
         (SELECT bp_key, d.file#, d.incr_scn, d.ckp_scn
           FROM vbdf v, bdf d, bp p
           WHERE v.dbinc_key = d.dbinc_key
             AND v.file# = d.file#
             AND p.bs_key = d.bs_key
             AND p.vb_key IS NULL
             AND p.status != 'D'
             AND p.ba_access != 'U'
             AND d.ckp_scn <= l_ckpscn
           ORDER BY ckp_scn DESC, incr_scn DESC, bp_key)
       WHERE ROWNUM = 1;
 
--
     IF l_bpkey IS NULL THEN
       am_trace('Populate_backup_piece: Can not find useful backup.');
       RAISE NO_FIND_USEFUL_BP;
     END IF;
   ELSE
     l_bpkey := p_bpkey;
   END IF;
 
--
   SELECT bs_key INTO l_bskey FROM bp WHERE bp_key = l_bpkey;
 
--
   dbms_ra_pool.ok4pool(l_dbkey, l_bpkey, TRUE, l_hasdups, l_nofit, l_isok);
   IF l_nofit THEN
     dbms_ra_pool.ok4pool(l_dbkey, l_bpkey, FALSE, l_hasdups, l_nofit, l_isok);
   END IF;
   IF NOT l_isok THEN
     am_trace('Populate_backup_piece: Can not use this backup.');
     RAISE NO_INSERT_BP;
   END IF;
 
--
   SELECT COUNT(*) INTO l_count
     FROM vbdf v, bdf d
     WHERE v.dbinc_key = d.dbinc_key
       AND v.file# = d.file#
       AND bs_key = l_bskey
       AND d.ckp_scn <= v.ckp_scn;
   IF l_count = 0 THEN
     l_update := 0;
   ELSE
     l_update := 1;
   END IF;
 
   am_trace('Populate_backup_piece: Source bpkey ' || l_bpkey ||
            ', bskey -- ' || l_bskey ||
            ', update -- ' || l_update);
 
--
   SELECT sl_key INTO l_slkey FROM odb WHERE db_key = l_dbkey;
 
--
   task_rec.task_type   := dbms_ra_scheduler.TASK_INDEX_BACKUP;
   task_rec.flags       := 1; -- TASKS_RECEIVED_BACKUP
   task_rec.db_key      := l_dbkey;
   task_rec.param_num1  := l_bpkey;
   task_rec.param_num2  := l_update;
 
--
   dbms_ra_scheduler.new_task(task_rec);
 
END populate_backup_piece_int;
 
 
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE populate_backup_piece(backup_piece_key IN NUMBER)
IS
   l_the      NUMBER;
BEGIN
  lock_api(LOCKAPI_MODIFY, 'populate_backup_piece');
 
  l_the := dbms_ra_scheduler.add_to_task_history_table (
              task_type => dbms_ra_scheduler.TASK_API_POPULATE,
              param     => 'populate_backup_piece' ||
              b_p('backup_piece_key', backup_piece_key, 
                    p_first=>TRUE, p_last=>TRUE));
 
  populate_backup_piece_int(backup_piece_key);
  unlock_api(p_the_num=>l_the, p_results=>TRUE, p_docommit=>TRUE);
  
EXCEPTION
  WHEN OTHERS THEN
    rollback;
    unlock_api(p_the_num=>l_the, p_results=>FALSE, p_docommit=>TRUE);
    RAISE;
END populate_backup_piece;
 
 
 
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE copy_move_int(p_tag IN VARCHAR2 DEFAULT NULL,
                        p_bpkey IN NUMBER DEFAULT NULL,
                        p_format IN VARCHAR2 DEFAULT NULL,
                        p_template_name IN VARCHAR2 DEFAULT NULL,
                        p_deleteit IN BOOLEAN DEFAULT FALSE
                       ) 
IS
  CURSOR bps_To_Move(c_tag IN VARCHAR2) IS
  select MIN(bp.bp_key) bp_key
    from bp 
    where tag=c_tag 
      AND status = 'A'
      AND ba_access = 'L'
      AND  bp.bs_key in 
            (select bs_key 
             from bs 
             where keep_options > 0)
    GROUP BY bs_key, piece#; 
  
  CURSOR bps_To_Copy(c_tag IN VARCHAR2) IS
  select MIN(bp.bp_key) bp_key
    from bp 
    where tag=c_tag 
      AND status = 'A'
      AND ba_access = 'L'
      AND  bp.bs_key in 
            (select bs_key 
             from bs)
    GROUP BY bs_key, piece#; 
 
  l_missing_param   VARCHAR2(128);
  l_deletesource    VARCHAR2(1);
  l_template_key    NUMBER DEFAULT NULL; 
  l_keepoptions     NUMBER := 0;
  l_cnt             NUMBER := 0;
  c_template_name   sbt_job_template.template_name%TYPE;
BEGIN
  IF p_format IS NULL THEN
    l_missing_param := 'format';
    RAISE MISSING_PARAM;
  END IF;
  
  IF p_tag IS NULL AND p_bpkey IS NULL THEN
    l_missing_param := 'tag and/or bpkey (neither supplied)';
    RAISE MISSING_PARAM;
  END IF;
  
  IF p_template_name IS NOT NULL THEN
    BEGIN
      dbms_ra_int.canonicalize(p_template_name, c_template_name, 128);
 
      SELECT job.template_key
        INTO l_template_key
        FROM sbt_job_template job
        WHERE job.template_name = c_template_name;
    EXCEPTION
      WHEN NO_DATA_FOUND THEN
        RAISE OBJ_NOT_FOUND;
    END;
  END IF;
  
  IF p_deleteit THEN 
    l_deletesource := 'Y';
  ELSE
    l_deletesource := 'N';
  END IF;
 
  IF p_bpkey IS NULL THEN
    IF p_deleteit THEN 
      FOR b IN bps_To_Move(p_tag) LOOP
        l_cnt := l_cnt + 1;
        am_trace ('copy_move_int: BP_KEY being moved is: ' || b.bp_key);
        dbms_ra_scheduler.copy_one_backuppiece(p_bpkey => b.bp_key,
                                              p_format => p_format,
                                              p_deletesource => l_deletesource,
                                              p_template_key => l_template_key);
--
--
        IF p_template_name IS NULL THEN
          dbms_ra_scheduler.delete_one_backuppiece(b.bp_key);
        END IF;
      END LOOP;
    ELSE
      FOR b IN bps_To_Copy(p_tag) LOOP
        l_cnt := l_cnt + 1;
        am_trace ('copy_move_int: BP_KEY being copied is: ' || b.bp_key);
        dbms_ra_scheduler.copy_one_backuppiece(p_bpkey => b.bp_key,
                                              p_format => p_format,
                                              p_deletesource => l_deletesource,
                                              p_template_key => l_template_key);
      END LOOP;
    END IF;
 
    IF l_cnt = 0 THEN
      am_trace ('copy_move_int: No eligible backup pieces found for tag ' ||
                p_tag);
      RAISE UNKNONW_BP;
    END IF;
      
  ELSE
    
--
    IF p_deleteit THEN 
      SELECT keep_options
        INTO l_keepoptions
        FROM bs 
        WHERE bs_key=(SELECT bs_key FROM bp WHERE bp_key=p_bpkey);
      IF l_keepoptions = 0 THEN
        am_trace('copy_move_int: bp_key ' || TO_CHAR(p_bpkey) ||
                 ' is not part of a KEEP backup');
        sys.dbms_sys_error.raise_system_error(COPY_MOVE_NOT_KEEP_NUM,
                                              TO_CHAR(p_bpkey),
                                              FALSE);
      END IF;
    END IF;
 
    dbms_ra_scheduler.copy_one_backuppiece(p_bpkey          => p_bpkey,
                                           p_format         => p_format,
                                           p_deletesource   => l_deletesource,
                                           p_template_key   => l_template_key);
--
--
    IF p_deleteit=TRUE AND p_template_name IS NULL THEN
      dbms_ra_scheduler.delete_one_backuppiece(p_bpkey);
    END IF;
  END IF;
  
EXCEPTION
  WHEN COPY_MOVE_NOT_KEEP THEN
    RAISE;
 
  WHEN MISSING_PARAM THEN
    IF l_missing_param IS NOT NULL THEN
      am_trace ('copy_move_int: required parameter missing: ' ||
                l_missing_param);
      sys.dbms_sys_error.raise_system_error(MISSING_PARAM_NUM,
                                            l_missing_param,
                                            FALSE);
    ELSE
      RAISE;
    END IF;
 
  WHEN OBJ_NOT_FOUND THEN
    am_trace('copy_move_int: ' ||
                item_not_found(p_template_name,'sbt job template'));
    sys.dbms_sys_error.raise_system_error  (OBJ_NOT_FOUND_NUM,
                                            p_template_name,
                                            'sbt job template',
                                            FALSE);
    
  WHEN OTHERS THEN
    am_trace ('copy_move_int exception: ' || ' err:' || SQLERRM);
    RAISE;
    
END copy_move_int;
--
 
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE move_backup_piece (bp_key            IN NUMBER, 
                             format            IN VARCHAR2,
                             template_name     IN VARCHAR2)
IS
  l_the           NUMBER;
  c_template_name sbt_job_template.template_name%TYPE;
BEGIN
  
  am_trace('move_backup_piece: bp_key=' || bp_key ||
           ' ,format=' || format ||
           ' ,template_name=' || template_name);
  lock_api(LOCKAPI_CREATE, 'move_backup_piece');
  
  l_the := dbms_ra_scheduler.add_to_task_history_table (
              task_type => dbms_ra_scheduler.TASK_API_MOVE_BACKUP_PIECE,
              param     => 'move_backup_piece' ||
                b_p('bp_key', bp_key, p_first=>TRUE) ||
                b_p('format', format) ||
                b_p('template_name', template_name, p_last=>TRUE));
                                                        
  dbms_ra_int.canonicalize(template_name, c_template_name, 128);
 
  copy_move_int(p_tag => NULL,
                p_bpkey => bp_key, 
                p_format => format, 
                p_template_name => c_template_name,
                p_deleteit => TRUE);
  unlock_api(p_the_num=>l_the, p_results=>TRUE, p_docommit=>TRUE);
  
EXCEPTION
  WHEN OTHERS THEN
    rollback;
    unlock_api(p_the_num=>l_the, p_results=>FALSE, p_docommit=>TRUE);
    RAISE;
    
END move_backup_piece;
--
 
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE move_backup (tag               IN VARCHAR2,
                       format            IN VARCHAR2,
                       template_name     IN VARCHAR2)
IS
  l_the             NUMBER;
  c_template_name   sbt_job_template.template_name%TYPE;
 
BEGIN
  
  am_trace('move_backup: tag=' || tag ||
           ' ,format=' || format ||
           ' ,template_name=' || template_name);
  lock_api(LOCKAPI_CREATE, 'move_backup');
  
  l_the := dbms_ra_scheduler.add_to_task_history_table (
              task_type => dbms_ra_scheduler.TASK_API_MOVE_BACKUP,
              param     => 'move_backup' ||
                b_p('tag', tag, p_first=>TRUE) ||
                b_p('format', format) ||
                b_p('template_name', template_name, p_last=>TRUE));
 
  dbms_ra_int.canonicalize(template_name, c_template_name, 128);
  copy_move_int(p_tag => tag,
                p_bpkey => NULL, 
                p_format => format, 
                p_template_name => c_template_name, 
                p_deleteit => TRUE);
  unlock_api(p_the_num=>l_the, p_results=>TRUE, p_docommit=>TRUE);
  
EXCEPTION
  WHEN OTHERS THEN
    rollback;
    unlock_api(p_the_num=>l_the, p_results=>FALSE, p_docommit=>TRUE);
    RAISE;
    
END move_backup;
--
 
 
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE copy_backup_piece (bp_key            IN NUMBER, 
                             format            IN VARCHAR2,
                             template_name     IN VARCHAR2)
IS
  l_the             NUMBER;
  c_template_name   sbt_job_template.template_name%TYPE;
 
BEGIN
  
  am_trace('copy_backup_piece: bp_key=' || bp_key ||
           ' ,format=' || format ||
           ' ,template_name=' || template_name);
  lock_api(LOCKAPI_CREATE, 'copy_backup_piece');
  
  l_the := dbms_ra_scheduler.add_to_task_history_table (
              task_type => dbms_ra_scheduler.TASK_API_COPY_BACKUP_PIECE,
              param     => 'copy_backup_piece' ||
                b_p('bp_key', bp_key, p_first=>TRUE) ||
                b_p('format', format) ||
                b_p('template_name', template_name, p_last=>TRUE));
 
  dbms_ra_int.canonicalize(template_name, c_template_name, 128);
  copy_move_int(p_tag => NULL,
                p_bpkey => bp_key, 
                p_format => format, 
                p_template_name => c_template_name, 
                p_deleteit => FALSE);
  unlock_api(p_the_num=>l_the, p_results=>TRUE, p_docommit=>TRUE);
  
EXCEPTION
  WHEN OTHERS THEN
    rollback;
    unlock_api(p_the_num=>l_the, p_results=>FALSE, p_docommit=>TRUE);
    RAISE;
    
END copy_backup_piece;
--
 
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE copy_backup (tag               IN VARCHAR2,
                       format            IN VARCHAR2,
                       template_name     IN VARCHAR2)
IS
  l_the             NUMBER;
  c_template_name   sbt_job_template.template_name%TYPE;
BEGIN
  
  am_trace('copy_backup: tag=' || tag ||
           ' ,format=' || format ||
           ' ,template_name=' || template_name);
  lock_api(LOCKAPI_CREATE, 'copy_backup');
  
  l_the := dbms_ra_scheduler.add_to_task_history_table (
              task_type => dbms_ra_scheduler.TASK_API_COPY_BACKUP,
              param     => 'copy_backup' ||
                b_p('tag', tag, p_first=>TRUE) ||
                b_p('format', format) ||
                b_p('template_name', template_name, p_last=>TRUE));
  
  dbms_ra_int.canonicalize(template_name, c_template_name, 128);
 
  copy_move_int(p_tag      => tag,
                   p_bpkey    => NULL, 
                   p_format   => format, 
                   p_template_name => c_template_name, 
                   p_deleteit => FALSE);
  
  unlock_api(p_the_num=>l_the, p_results=>TRUE, p_docommit=>TRUE);
 
EXCEPTION
  WHEN OTHERS THEN
    rollback;
    unlock_api(p_the_num=>l_the, p_results=>FALSE, p_docommit=>TRUE);
    RAISE;
    
END copy_backup;
 
--
--
--
--
--
--
 
PROCEDURE migrate_tape_backup_int(
   db_unique_name IN VARCHAR2,
   sbt_lib_name   IN VARCHAR2)
IS
   CURSOR dbuniq_c(db_unique_name IN VARCHAR2) IS
      WITH table_to_parse as
         (select db_unique_name str from dual)
      SELECT DISTINCT ltrim(rtrim(new_str)) new_str
        FROM table_to_parse,
             xmltable('r/c' passing xmltype('<r><c>' ||
             replace(str,',','</c><c>') || '</c></r>')
             columns new_str varchar2(512) path '.');
 
--
--
   CURSOR bp_c(db_key IN NUMBER) IS
      SELECT bp.rowid bp_rowid, bp.bp_key, bp.handle, bp.tag, bp.status,
             bp.piece#, bp.encrypted, bp.compressed,
             bs.bck_type, bs.set_stamp, bs.set_count, bs.block_size,
             bs.controlfile_included, nvl2(bsf.bsf_key, 1, 0) spfile_included
        FROM bp, bs
             LEFT OUTER JOIN bsf
             ON bs.bs_key = bsf.bs_key
       WHERE bp.bs_key = bs.bs_key
         AND bp.db_key = bp_c.db_key
         AND bp.status != 'D'
         AND bp.ba_access = 'U'       -- non-AM backups
         AND bp.device_type != 'DISK' -- tape backups
         AND rownum <= 500            -- limit commit size by 500 rows
         FOR UPDATE OF bp.lib_key, bs.bs_key
       ORDER BY bs.bs_key, bp.bp_key;
 
   dbuniqRec    dbuniq_c%ROWTYPE;
   bpRec        bp_c%ROWTYPE;
   l_db_key     NUMBER;
   l_dbid       NUMBER;
   l_lib_key    NUMBER;
   xmldoc       CLOB;
   eoc          BOOLEAN;
   l_ba_access  VARCHAR2(1);
   l_db_name    dbinc.db_name%TYPE;
   l_bstyp      NUMBER;
BEGIN
--
   BEGIN
      SELECT lib.lib_key, nvl2(lib.server_key, 'R', 'T')
        INTO l_lib_key, l_ba_access
        FROM sbt_lib_desc lib
       WHERE lib.lib_name = migrate_tape_backup_int.sbt_lib_name;
   EXCEPTION
      WHEN NO_DATA_FOUND THEN
         am_trace('migrate_tape_backup: ' ||
                      item_not_found(sbt_lib_name, 'sbt library'));
         sys.dbms_sys_error.raise_system_error
            (OBJ_NOT_FOUND_NUM, sbt_lib_name, 'sbt library', FALSE);
   END;
 
   am_trace ('MIGRATE_TAPE_BACKUP l_lib_key: ' || l_lib_key);
   am_trace ('MIGRATE_TAPE_BACKUP l_ba_access: ' || l_ba_access);
 
   FOR dbuniqRec IN dbuniq_c(db_unique_name) LOOP
      am_trace ('MIGRATE_TAPE_BACKUP for: ' || dbuniqRec.new_str);
 
      BEGIN
         SELECT db.db_key, db.db_id INTO l_db_key, l_dbid
           FROM node, db
          WHERE node.db_unique_name = dbuniqRec.new_str
            AND node.db_key = db.db_key
--
--
            AND NOT EXISTS (SELECT db_state
                              FROM odb
                             WHERE odb.db_key = node.db_key
                               AND db_state IS NOT NULL)
            FOR UPDATE OF db.db_key;
 
         SELECT db_name INTO l_db_name
           FROM dbinc
          WHERE db_key = l_db_key
            AND dbinc_status = 'CURRENT';
      EXCEPTION
         WHEN no_data_found THEN
            am_trace('migrate_tape_backup: ' ||
                         item_not_found(dbuniqRec.new_str, 'db unique name'));
            sys.dbms_sys_error.raise_system_error
               (OBJ_NOT_FOUND_NUM, dbuniqRec.new_str, 'db unique name', FALSE);
      END;
 
      eoc := FALSE;
      WHILE (not eoc) LOOP
         eoc := TRUE;
--
--
         FOR bpRec IN bp_c(l_db_key) LOOP
            am_trace ('MIGRATE_TAPE_BACKUP handle: ' || bpRec.handle);
 
            eoc:= FALSE;
 
--
--
            CASE bpRec.bck_type
               WHEN 'D' THEN l_bstyp := 4;
               WHEN 'I' THEN l_bstyp := 16;
               WHEN 'L' THEN l_bstyp := 8;
            ELSE
               l_bstyp := 0;
            END CASE;
 
            IF (bpRec.controlfile_included != 'NONE') THEN
               l_bstyp := l_bstyp + 1;
            END IF;
 
            IF (bpRec.spfile_included > 0) THEN
               l_bstyp := l_bstyp + 2;
            END IF;
 
            IF bprec.compressed = 'YES' THEN
               l_bstyp := l_bstyp + 32;
            END IF;
 
            IF bprec.encrypted = 'Y' THEN
               l_bstyp := l_bstyp + 64;
            END IF;
 
--
--
            am_trace ('MIGRATE_TAPE_BACKUP adding sbt catalog entry');
            sys.kbrsi_icd.rsAddToSbtCatalog(
               bpkey        => bpRec.bp_key,
               dbver        => 0,
               dbname       => l_db_name,
               dbid         => l_dbid,
               handle       => bpRec.handle,
               setstamp     => bpRec.set_stamp,
               setcount     => bpRec.set_count,
               pieceblksize => bpRec.block_size,
               pieceno      => bpRec.piece#,
               tag          => bpRec.tag,
               bstyp        => l_bstyp);
 
--
            UPDATE bp
               SET status = bpRec.status,
                   ba_access = l_ba_access,
                   lib_key = l_lib_key,
                   purged = 'N'
             WHERE rowid = bpRec.bp_rowid;
            am_trace ('MIGRATE_TAPE_BACKUP updated bp rows ' || SQL%ROWCOUNT);
         END LOOP;
         IF (not eoc) THEN
            COMMIT;
         ELSE
            am_trace ('MIGRATE_TAPE_BACKUP complete: ' || dbuniqRec.new_str);
         END IF;
      END LOOP;
   END LOOP;
END migrate_tape_backup_int;
 
PROCEDURE migrate_tape_backup(
   db_unique_name IN VARCHAR2,
   sbt_lib_name   IN VARCHAR2)
IS
  l_the             NUMBER;
  c_sbt_lib_name    sbt_lib_desc.lib_name%TYPE;
BEGIN
  lock_api(LOCKAPI_CREATE, 'migrate_tape_backup');
  l_the := dbms_ra_scheduler.add_to_task_history_table (
              task_type => dbms_ra_scheduler.TASK_API_MIGRATE_TAPE,
              param     => 'migrate_tape_backup' ||
                b_p('db_unique_name', db_unique_name, p_first=>TRUE) ||
                b_p('sbt_lib_name', sbt_lib_name, p_last=>TRUE));
  dbms_ra_int.canonicalize(sbt_lib_name, c_sbt_lib_name, 128);
  migrate_tape_backup_int(upper(db_unique_name), c_sbt_lib_name);
  unlock_api();
 
EXCEPTION
   WHEN OTHERS THEN
      unlock_api();
      RAISE;
END migrate_tape_backup;
 
--
 
--
--
--
--
--
--
--
PROCEDURE remove_rep_tasks(p_db_key IN NUMBER, p_template in VARCHAR2)
IS
  l_template_key    NUMBER;
 
BEGIN
 
  BEGIN
    SELECT job.template_key
      INTO l_template_key
      FROM sbt_job_template job
      WHERE job.template_name = p_template;
  EXCEPTION
    WHEN NO_DATA_FOUND THEN
--
      am_trace ('rempove_rep_tasks: ' || item_not_found(
                                                    p_template,
                                                    'replication template'));
      sys.dbms_sys_error.raise_system_error(OBJ_NOT_FOUND_NUM,
                                            p_template,
                                            'remreptasks-template',
                                            FALSE);
  END;
 
--
  SYS.KBRSI_ICD.RSSCHEDLOCK (waitforwork => 0);
 
--
--
  UPDATE task t
     SET state = DBMS_RA_SCHEDULER.STATE_CANCEL
   WHERE t.db_key = p_db_key
     AND t.param_num2 = l_template_key
     AND t.state NOT IN (DBMS_RA_SCHEDULER.STATE_RUNNING,
                         DBMS_RA_SCHEDULER.STATE_CANCELING)
     AND t.task_type IN (DBMS_RA_SCHEDULER.TASK_BACKUP_SBT,
                         DBMS_RA_SCHEDULER.TASK_PURGE_SBT,
                         DBMS_RA_SCHEDULER.TASK_OBSOLETE_SBT,
                         DBMS_RA_SCHEDULER.TASK_RESTORE_SBT);
  COMMIT;
 
--
  SYS.KBRSI_ICD.RSSCHEDUNLOCK;
 
EXCEPTION
  WHEN OTHERS THEN
--
    SYS.KBRSI_ICD.RSSCHEDUNLOCK;
    RAISE;
 
END;
--
 
--
--
--
--
--
PROCEDURE ctrl_c_check(check_what IN NUMBER)
IS
BEGIN
--
  IF (check_what = CCCHK_CREDEL_REP_SERVER OR check_what = CCCHK_ALL_APIS) THEN
    FOR x IN (SELECT rep_server_name
              FROM server s, rep_server r
              WHERE s.server_key = r.server_key
              AND status != 'A')
      LOOP
        delete_replication_server_int (x.rep_server_name, TRUE);
      END LOOP;
  END IF;
    
END;
--
 
--
--
--
--
--
FUNCTION is_ba_running RETURN BOOLEAN
IS
  l_count       NUMBER;
BEGIN
--
--
--
  SELECT COUNT(*) INTO l_count
    FROM config
   WHERE config.name = '_recovery_appliance_state'
     AND config.value = 'ON';
  IF l_count <> 0 THEN
    RETURN TRUE;
  ELSE
    RETURN FALSE;
  END IF;
END;
--
 
 
--
--
--
--
--
FUNCTION is_sysgen_obj(name IN VARCHAR2) RETURN BOOLEAN
IS
  l_cnt     NUMBER;
BEGIN
 
--
--
 
--
--
  IF INSTR(name, '$') > 0 THEN
    RETURN TRUE;
  END IF;
 
  RETURN FALSE;
END;
--
 
--
--
--
--
--
FUNCTION is_rep_server(name IN VARCHAR2) RETURN BOOLEAN
IS
  l_cnt     NUMBER;
BEGIN
 
--
--
--
 
  SELECT count(*)
    INTO l_cnt
    FROM server
    WHERE rep_server_name = name;
--
  IF l_cnt > 0 THEN
    RETURN TRUE;
  END IF;
 
--
  IF INSTR(name, 'REP$', 1) > 0 THEN
    RETURN TRUE;
  END IF;
 
  RETURN FALSE;
END;
--
 
 
END dbms_ra;
>>>
 
define prvtrsdmp_plb
<<<
CREATE OR REPLACE PACKAGE BODY dbms_ra_dump IS
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
 
--
s_tracedump       BOOLEAN := TRUE;              -- add dump info to trace file
s_filedump        BOOLEAN := FALSE;             -- add dump info to dir file
s_file            utl_file.file_type;           -- handle for dir dump file
s_datapump        BOOLEAN := TRUE;              -- produce a datapump dump
s_blocks          BOOLEAN := FALSE;             --    including blocks table
s_chunks          BOOLEAN := FALSE;             --    including chunks table
s_start_history   TIMESTAMP;                    -- start of recent history.
s_file_ext        VARCHAR2(4) := '.dat';        -- file extensions for files.
 
--
WIDTH           CONSTANT NUMBER := 132;                       -- page width
SEPARATOR       CONSTANT VARCHAR2(1) := '*';                  -- header char
RECENT_INTERVAL CONSTANT DSINTERVAL_UNCONSTRAINED 
                        := TO_DSINTERVAL('0 0:30:00');        -- recent times
DUMP_DIR        CONSTANT VARCHAR2(8) := 'RA_DUMP';  -- directory object for 
--
 
E_OBJECT_NO_LONGER_EXISTS          EXCEPTION;
PRAGMA EXCEPTION_INIT              (E_OBJECT_NO_LONGER_EXISTS, -8103);
 
--
PROCEDURE dumpOpen (filename VARCHAR2) IS
BEGIN
  IF s_filedump THEN
    s_file := UTL_FILE.FOPEN (DUMP_DIR, filename || s_file_ext, 'A');
  END IF; 
END dumpOpen;
 
--
PROCEDURE dumpClose IS
BEGIN
  IF s_filedump THEN
    UTL_FILE.FCLOSE (s_file);
  END IF; 
END dumpClose;
 
--
PROCEDURE dumpLine (text VARCHAR2) IS
BEGIN
  IF s_tracedump THEN
--
    sys.kbrsi_icd.rsTrace(REPLACE(text,'%','%%'));
  END IF;
 
  IF s_filedump THEN
    UTL_FILE.PUT_LINE (s_file, text);
  END IF;
END dumpLine;
 
--
PROCEDURE dumpHeader (text VARCHAR2) IS
  textpos NUMBER;
BEGIN
  dumpLine(' ');
  dumpLine(LPAD(SEPARATOR, WIDTH, SEPARATOR)); 
--
  textpos := (WIDTH - (LENGTH(text)+2))/ 2;
  dumpLine(RPAD(LPAD(SEPARATOR, textpos-1, SEPARATOR) || ' ' || 
           text || ' ', WIDTH, SEPARATOR));
  dumpLine(LPAD(SEPARATOR, WIDTH, SEPARATOR));
END dumpHeader;
 
--
FUNCTION dumpPad (text VARCHAR2, len NUMBER) RETURN VARCHAR2 IS
BEGIN
  RETURN RPAD(NVL(text, '*NULL*'), len, ' ');
END;
 
--
FUNCTION dumpPad (num NUMBER, len NUMBER) 
  RETURN VARCHAR2 IS
BEGIN
  IF num IS NULL THEN
    RETURN dumpPad (' ', len);
  ELSE
    RETURN SUBSTR(TO_CHAR(num, RPAD('9',len,'9')),2);
  END IF;
END;
 
FUNCTION dumpMB (num NUMBER, len NUMBER) 
  RETURN VARCHAR2 IS
BEGIN
  IF num IS NULL THEN
    RETURN dumpPad (' ', len);
  ELSE
    RETURN 
      SUBSTR(TO_CHAR(num, RPAD('9',len-5,'9') || '.99'),2) || 'MB';
  END IF;
END;
 
FUNCTION dumpGB (num NUMBER, len NUMBER) 
  RETURN VARCHAR2 IS
BEGIN
  IF num IS NULL THEN
    RETURN dumpPad (' ', len);
  ELSE
    RETURN 
      SUBSTR(TO_CHAR(num, RPAD('9',len-5,'9') || '.99'),2) || 'GB';
  END IF;
END;
 
 
FUNCTION dumpPct (num NUMBER) 
  RETURN VARCHAR2 IS
BEGIN
  IF num IS NULL THEN
    RETURN dumpPad (' ', 10);
  ELSE
    RETURN 
      SUBSTR(TO_CHAR(num, '999999.99') || '%',2);
  END IF;
END;
 
FUNCTION dumpPad (ts TIMESTAMP WITH TIME ZONE, len NUMBER) RETURN VARCHAR2 IS
BEGIN
  RETURN dumpPad(TO_CHAR(ts, 'DD-MM-YYYY HH24:MI:SS'), len);
END;
--
FUNCTION dumpPad (ts TIMESTAMP, len NUMBER) RETURN VARCHAR2 IS
BEGIN
  RETURN dumpPad(TO_CHAR(ts, 'DD-MM-YYYY HH24:MI:SS'), len);
END;
 FUNCTION dumpPad (ts DATE, len NUMBER) RETURN VARCHAR2 IS
BEGIN
  RETURN dumpPad(TO_CHAR(ts, 'DD-MM-YYYY HH24:MI:SS'), len);
END;
   
FUNCTION dumpInt (thisint dsinterval_unconstrained, len NUMBER) 
                        RETURN VARCHAR2 IS
temp VARCHAR2(200);
BEGIN
  temp := SUBSTR(TO_CHAR(thisint),2);
  RETURN dumpPad(temp, len);
END;
 
--
PROCEDURE dumpBig (message VARCHAR2) IS
C_NEWLINE CONSTANT CHAR(1) := CHR(10); --linefeed
l_msglen PLS_INTEGER := LENGTH(message);
l_nextbuf VARCHAR2(200);
l_pos PLS_INTEGER := 1;
l_endpos PLS_INTEGER;
BEGIN
  WHILE l_msglen >= l_pos LOOP
    l_nextbuf := SUBSTR(message,l_pos,WIDTH);
 
    IF INSTR(l_nextbuf, C_NEWLINE) > 0 THEN
      l_endpos := INSTR(l_nextbuf,C_NEWLINE) - 1;
    ELSIF l_msglen + 1 - l_pos <= WIDTH THEN
      l_endpos := WIDTH;
    ELSIF INSTR(l_nextbuf, ' ', -1) > 0 THEN 
      l_endpos := INSTR(l_nextbuf, ' ', -1) - 1;
    ELSE
      l_endpos := WIDTH;
    END IF;
 
    IF l_endpos > 0 THEN
      dumpLine (SUBSTR(l_nextbuf, 1, l_endpos));
 
      IF SUBSTR(l_nextbuf,l_endpos,1) IN (C_NEWLINE, ' ') THEN
        l_endpos := l_endpos + 1;
      END IF;
    ELSE
       l_endpos := 1;
    END IF;
 
    l_pos := l_pos + l_endpos;
  END LOOP;
END;
 
 
--
PROCEDURE dumpStatus IS
CURSOR log_entries IS
  SELECT incident#, last_seen, seen_count, status,
         SUBSTR(component,1,10) component, ospid, inst_id, task_id, 
         DECODE(severity,  0, 'INFORMATION',
                           1, 'WARNING',
                          10, 'ERROR',
                          20, 'INTERNAL',
                          TO_CHAR(severity)) severity,
         trace_file,
         error_text,
         DECODE(severity, 20, call_stack, NULL) call_stack
  FROM error_log
  ORDER BY status, severity, last_seen DESC;
   
CURSOR recent_apis IS
  SELECT execute_time, task_type_name, db_key, sl_key, param
    FROM task_history
    LEFT OUTER JOIN tasktypenames USING (task_type)
    WHERE task_type >= dbms_ra_scheduler.task_min_api
    ORDER BY execute_time DESC;
 
CURSOR ba_locks IS
  SELECT l.inst_id, SUBSTR(ras.spid, 1, 12) spid, ttn.task_type_name,
         DECODE(l.ba_type, 5, 'PDB ' || LPAD(l.key, 26-4),
                           6, 'SL '   || LPAD(l.key, 26-3),
                           7, DECODE(l.key, 1, 'TIMER',
                                          2, 'SCHEDULING',
                                          3, 'API EXECUTION',
                                          4, 'QUIESCE RA',
                                             '7 ' || TO_CHAR(l.key)),
                           8, 'PURGE ' || LPAD(l.key, 26-6),
                           9, 'KEY '   || LPAD(l.key, 26-4),
                              TO_CHAR(l.ba_type)) lock_type,
        DECODE(l.lmode, 1, 'NULL',             -- other modes shouldnt be seen
                        2, 'SUB-SHARE',
                        4, 'SHARE',
                        6, 'EXCLUSIVE',
                           TO_CHAR(l.lmode)) lock_mode,
        l.ctime
  FROM TABLE(CAST(dbms_ra_scheduler.s_amlocks AS rai_locks_table_type)) l
       JOIN sys.rai_active_sessions ras ON (l.sid = ras.sid) 
                                      AND (l.inst_id = ras.inst_id)
       LEFT OUTER JOIN sessions s ON (l.sid = s.sid) 
                                 AND (l.inst_id = s.instance_id)
       LEFT OUTER JOIN tasktypenames ttn 
                                      ON (s.current_task_type = ttn.task_type)
  ORDER BY l.inst_id, l.sid;
 
CURSOR configs IS
  SELECT name, value FROM config ORDER BY name;
 
firstrow BOOLEAN := TRUE;
    
BEGIN
  FOR c IN log_entries LOOP
    IF firstrow THEN
      firstrow := FALSE;
      dumpHeader('Error Log Contents');
      dumpLine (dumpPad('Incident#', 22) || 
                dumpPad('Last seen', 22) ||
                dumpPad('Count', 6) ||
                dumpPad('Status', 7) ||
                dumpPad('Component', 12) ||
                dumpPad('OS pid', 13) ||
                dumpPad('Inst id', 8) ||
                dumpPad('Task id', 21) ||
                        'Severity');
 
      dumpLine (RPAD('-', 21, '-') ||
                RPAD(' ', 22, '-') ||
                RPAD(' ', 6, '-') ||
                RPAD(' ', 7, '-') ||
                RPAD(' ', 12, '-') ||
                RPAD(' ', 13, '-') ||
                RPAD(' ', 8, '-') ||
                RPAD(' ', 21, '-') ||
                RPAD(' ', 12, '-'));
 
      dumpLine ('Trace file');
      dumpLine ('Error Message');
      dumpLine ('Backtrace and Call  Stack(s)');
 
    END IF;
 
    dumpLine (dumpPad(c.incident#, 21) || ' ' ||
              dumpPad(c.last_seen, 21) || ' ' ||
              dumpPad(c.seen_count, 5) || ' ' ||
              dumpPad(c.status, 6) || ' ' ||
              dumpPad(c.component, 11) || ' ' ||
              dumpPad(c.ospid,12) || ' ' ||
              dumpPad(c.inst_id,7) || ' ' ||
              dumpPad(c.task_id,20) || ' ' ||
              dumpPad(c.severity,11));
    dumpBig (c.trace_file);
    dumpBig (c.error_text);
    IF c.call_stack IS NOT NULL THEN
      dumpBig (c.call_stack);
    END IF;
  END LOOP;
 
<<RETRY_TASK_HISTORY>>
  BEGIN
    firstrow := TRUE;
    FOR c IN recent_apis LOOP
      IF firstrow THEN
        firstrow := FALSE;
        dumpHeader('Recent APIs');
        dumpLine (dumpPad('Execute Time', 20) ||
                          'Type');
        dumpLine  ('Param');
 
        dumpLine (RPAD('-', 19, '-') ||
                  RPAD(' ', 20, '-'));
      END IF;
 
      dumpLine (dumpPad(c.execute_time, 19) || ' ' ||
                dumpPad(c.task_type_name,19));
 
      dumpBig (c.param);
    END LOOP;
  EXCEPTION 
    WHEN E_OBJECT_NO_LONGER_EXISTS THEN
--
      GOTO RETRY_TASK_HISTORY;
  END;
 
 
<<TRY_TRY_AGAIN>>
  BEGIN
    firstrow := TRUE;
    DBMS_RA_SCHEDULER.MAKE_AMLOCKS();
    FOR c IN ba_locks LOOP
      IF firstrow THEN
        firstrow := FALSE;
        dumpHeader('recovery appliance Locks');
        dumpLine (dumpPad('Instid', 7) ||
                  dumpPad('OS pid', 13) ||
                  dumpPad('Task type', 12) ||
                  dumpPad('Lock type', 27) ||
                  dumpPad('Lock mode', 10) ||
                          'Secs Holding');
 
        dumpLine (RPAD('-', 6, '-') ||
                  RPAD(' ', 13, '-') ||
                  RPAD(' ', 12, '-') ||
                  RPAD(' ', 27, '-') ||
                  RPAD(' ', 10, '-') ||
                  RPAD(' ', 13, '-'));
      END IF;
 
      dumpLine (dumpPad(c.inst_id, 6) || ' ' ||
                dumpPad(c.spid, 12) || ' ' ||
                dumpPad(c.task_type_name,11) || ' ' ||
                dumpPad(c.lock_type,26) || ' ' ||
                dumpPad(c.lock_mode,9) || ' ' ||
                dumpPad(c.ctime,12));
    END LOOP;
  EXCEPTION 
    WHEN DBMS_RA_SCHEDULER.E_PQ_FAILURE THEN
--
    GOTO TRY_TRY_AGAIN;
  END;
 
  firstrow := TRUE;
  FOR c IN configs LOOP
    IF firstrow THEN
      firstrow := FALSE;
      dumpHeader('CONFIG settings');
      dumpLine (dumpPad('Name', 31) || 
                        'Value');
 
      dumpLine (RPAD('-', 30, '-') ||
                RPAD(' ', 100, '-'));
    END IF;
 
    dumpLine (dumpPad(c.name, 30) || ' ' ||
                      c.value);
  END LOOP;
 
END dumpStatus;
 
 
--
PROCEDURE dumpSessions IS
CURSOR active_sessions IS
  SELECT SUBSTR(usj.job_name,1,20) job_name, usj.running_instance, 
         usj.slave_os_process_id, s.audsid, s.current_task, 
         ctt.task_type_name current_task_type, p.task_type_name purpose
    FROM user_scheduler_running_jobs usj 
         LEFT OUTER JOIN sessions s ON (usj.session_id = s.sid AND
                                        usj.running_instance = s.instance_id)
         LEFT OUTER JOIN tasktypenames ctt 
                                    ON (s.current_task_type = ctt.task_type)
         LEFT OUTER JOIN tasktypenames p ON (s.purpose = ctt.task_type)
    WHERE usj.job_name LIKE 'RA$_%'
    ORDER BY usj.job_name, usj.running_instance;
 
CURSOR dead_sessions IS
  SELECT s.instance_id, s.spid, s.audsid, s.current_task,          
         ctt.task_type_name current_task_type, p.task_type_name purpose
    FROM sessions s
         LEFT OUTER JOIN tasktypenames ctt 
                                    ON (s.current_task_type = ctt.task_type)
         LEFT OUTER JOIN tasktypenames p ON (s.purpose = ctt.task_type)
    WHERE NOT EXISTS (SELECT 1 
                       FROM user_scheduler_running_jobs usj
                       WHERE usj.job_name LIKE 'RA$_%'
                         AND usj.session_id = s.sid
                         AND usj.running_instance = 
                                   NVL(s.instance_id,usj.running_instance))
    ORDER BY instance_id, ba_session_id;
 
l_done   BOOLEAN := FALSE;
firstrow BOOLEAN := TRUE;
    
BEGIN
  WHILE NOT l_done LOOP
    BEGIN
      FOR c IN active_sessions LOOP
        IF firstrow THEN
          firstrow := FALSE;
          dumpHeader('Active Sessions');
          dumpLine (dumpPad('Job Name', 21) || 
                    dumpPad('Instid', 7) ||
                    dumpPad('OS pid', 13) ||
                    dumpPad('Audsid', 13) ||
                    dumpPad('Session type', 13) ||
                    dumpPad('Task ID', 21) ||
                            'Task type');
 
          dumpLine (RPAD('-', 20, '-') ||
                    RPAD(' ', 7, '-') ||
                    RPAD(' ', 13, '-') ||
                    RPAD(' ', 13, '-') ||
                    RPAD(' ', 13, '-') ||
                    RPAD(' ', 21, '-') ||
                    RPAD(' ', 13, '-'));
        END IF;
 
        dumpLine (dumpPad(c.job_name, 20) || ' ' ||
                  dumpPad(c.running_instance, 6) || ' ' ||
                  dumpPad(c.slave_os_process_id,12) || ' ' ||
                  dumpPad(c.audsid,12) || ' ' ||
                  dumpPad(c.purpose,12) ||  ' ' ||
                  dumpPad(c.current_task,20) || ' ' ||
                          c.current_task_type);
      END LOOP;
      l_done := TRUE;
    EXCEPTION
      WHEN dbms_ra_scheduler.e_pq_failure THEN
        dbms_lock.sleep(1);
        CONTINUE;
    END;
  END LOOP; 
 
  l_done := FALSE;
  firstrow := TRUE;
  WHILE NOT l_done LOOP
    BEGIN
      FOR c IN dead_sessions LOOP
        IF firstrow THEN
          firstrow := FALSE;
          dumpHeader('Dead Sessions');
          dumpLine (dumpPad('Instid', 7) ||
                    dumpPad('OS pid', 13) ||
                    dumpPad('Audsid', 13) ||
                    dumpPad('Session type', 13) ||
                    dumpPad('CurTask ID', 21) ||
                            'CurTask type');
 
          dumpLine (RPAD('-', 6, '-') ||
                    RPAD(' ', 13, '-') ||
                    RPAD(' ', 13, '-') ||
                    RPAD(' ', 13, '-') ||
                    RPAD(' ', 21, '-') ||
                    RPAD(' ', 13, '-'));
        END IF;
 
        dumpLine (dumpPad(c.instance_id, 6) || ' ' ||
                  dumpPad(c.spid,12) || ' ' ||
                  dumpPad(c.audsid,12) || ' ' ||
                  dumpPad(c.purpose,12) || ' ' ||
                  dumpPad(c.current_task,20) || ' ' ||
                          c.current_task_type);
      END LOOP;
      l_done := TRUE;
    EXCEPTION
      WHEN dbms_ra_scheduler.e_pq_failure THEN
        dbms_lock.sleep(1);
        CONTINUE;
    END;
  END LOOP; 
END dumpSessions;
 
 
--
PROCEDURE dumpTasks IS
CURSOR current_tasks IS
  SELECT task_id, task_type_name, state, 
         interrupt_count, pending_interrupt, savepoint,
         param_num1, db_key, sl_key, elapsed_time, param
    FROM task
         LEFT OUTER JOIN tasktypenames USING (task_type)
    ORDER BY task_id;
 
CURSOR finished_tasks IS
  SELECT * FROM
    (SELECT task_id, task_type_name, param_num1, db_key, sl_key,
            elapsed_time, completion_time, param
      FROM task_history
           LEFT OUTER JOIN tasktypenames USING (task_type)
      WHERE task_type < 200 -- don't include API tasks or session fake tasks
        AND completion_time > s_start_history)
   ORDER BY completion_time desc;
 
CURSOR sbt_tasks IS
  SELECT  task_id, bs_key, attr_key, lib_key, failure_cnt, restore
    FROM sbt_task
    ORDER BY task_id;
 
CURSOR timer_tasks IS
  SELECT DECODE (timer_type, 1, 'VERIFY',
                             2, 'POLLING',
                             3, 'HISTORY PRUNE',
                             4, 'REMOVE INCOMPLETE FILES',
                             5, 'STORAGE HISTOGRAM',
                             6, 'STORAGE MAINTENANCE',
                             7, 'TASK MAINTENANCE',
                             8, 'OBSOLETE SBT',
                             9, 'RECONCILE',
                            10, 'CROSSCHECK',
                            11, 'SPAWN SBT',
                            12, 'SET RECONCILE TIMER',
                            13, 'UNRESERVE DRIVES',
                            14, 'REMOVE UNRESERVE DRIVES',
                            15, 'REMOVE SBT SESSIONS',
                                '***UNKNOWN*** ' || TO_CHAR(timer_type)) type,
        timer_location, next_execute, timer_interval
    FROM timer_task
    ORDER BY next_execute;
  
firstrow BOOLEAN := TRUE;
printint VARCHAR2(200);
    
BEGIN
  FOR c IN current_tasks LOOP
    IF firstrow THEN
      firstrow := FALSE;
      dumpHeader('Current tasks');
      dumpLine (dumpPad('Task Id', 21) || 
                dumpPad('Type', 15) ||
                dumpPad('State', 14) ||
                dumpPad('Interrupts', 11) ||
                dumpPad('Waiting on', 21) ||
                dumpPad('Savepoint', 10) ||
                dumpPad('Param_num1', 21) ||
                dumpPad('Dbkey', 21) ||
                dumpPad('Slkey', 21) ||
                        'Time used');
      dumpLine ('Param');
      dumpLine (RPAD('-', 20, '-') ||
                RPAD(' ', 15, '-') ||
                RPAD(' ', 14, '-') ||
                RPAD(' ', 11, '-') ||
                RPAD(' ', 21, '-') ||
                RPAD(' ', 10, '-') ||
                RPAD(' ', 21, '-') ||
                RPAD(' ', 21, '-') ||
                RPAD(' ', 21, '-') ||
                RPAD(' ', 20, '-'));
    END IF;
 
    dumpLine (dumpPad(c.task_id, 20) || ' ' ||
              dumpPad(c.task_type_name, 14) || ' ' ||
              dumpPad(dbms_ra_scheduler.taskstate2name(c.state, 
                                             c.pending_interrupt),13) || ' ' ||
              dumpPad(c.interrupt_count,10) || ' ' ||
              dumpPad(CASE
                        WHEN c.pending_interrupt < 0 THEN NULL
                        ELSE c.pending_interrupt
                      END,20) || ' ' ||
              dumpPad(c.savepoint,9) || ' ' ||
              dumpPad(c.param_num1,20) || ' ' ||
              dumpPad(c.db_key,20) || ' ' ||
              dumpPad(c.sl_key,20) || ' ' ||
              dumpPad(c.elapsed_time,19));
 
    IF c.param IS NOT NULL THEN
      dumpBig(c.param);
    END IF;
  END LOOP;
 
<<RETRY_TASK_HISTORY>>
  BEGIN
    firstrow := TRUE;
    FOR c IN finished_tasks LOOP
      IF firstrow THEN
        firstrow := FALSE;
        dumpHeader('Completed tasks from last 30 minutes');
        dumpLine (dumpPad('Task Id', 21) || 
                  dumpPad('Type', 15) ||
                  dumpPad('Param_num1', 10) ||
                  dumpPad('Dbkey', 21) ||
                  dumpPad('Slkey', 21) ||
                  dumpPad('Time used', 20) ||
                         'Completion time');
        dumpLine ('Param');
        dumpLine (RPAD('-', 20, '-') ||
                  RPAD(' ', 15, '-') ||
                  RPAD(' ', 10, '-') ||
                  RPAD(' ', 21, '-') ||
                  RPAD(' ', 21, '-') ||
                  RPAD(' ', 20, '-') ||
                  RPAD(' ', 20, '-'));
      END IF;
 
      printint := dumpInt(c.elapsed_time,19);
      dumpLine (dumpPad(c.task_id, 20) || ' ' ||
                dumpPad(c.task_type_name, 14) || ' ' ||
                dumpPad(c.param_num1, 9) || ' ' ||
                dumpPad(c.db_key,20) || ' ' ||
                dumpPad(c.sl_key,20) || ' ' ||
                dumpPad(printint,19) || ' ' ||
                dumpPad(c.completion_time,19));
 
      dumpBig(c.param);
    END LOOP;
  EXCEPTION 
    WHEN E_OBJECT_NO_LONGER_EXISTS THEN
--
--
      dumpLine ('*** EXCEPTION: E_OBJECT_NO_LONGER_EXISTS');
  END;
 
 
  firstrow := TRUE;
  FOR c IN sbt_tasks LOOP
    IF firstrow THEN
      firstrow := FALSE;
      dumpHeader('SBT Tasks');
      dumpLine (dumpPad('Task Id', 21) || 
                dumpPad('BS key', 10) ||
                dumpPad('Attr key', 10) ||
                dumpPad('Lib Key', 10) ||
                dumpPad('Failed', 7) ||
                        'Restore');
 
      dumpLine (RPAD('-', 20, '-') ||
                RPAD(' ', 21, '-') ||
                RPAD(' ', 21, '-') ||
                RPAD(' ', 21, '-') ||
                RPAD(' ', 7, '-') ||
                RPAD(' ', 8, '-'));
    END IF;
 
    dumpLine (dumpPad(c.task_id, 20) || ' ' ||
              dumpPad(c.bs_key,20) || ' ' ||
              dumpPad(c.attr_key,20) || ' ' ||
              dumpPad(c.lib_key,20) || ' ' ||
              dumpPad(c.failure_cnt,20) || ' ' ||
                      c.restore);
  END LOOP;
 
  firstrow := TRUE;
  FOR c IN timer_tasks LOOP
    IF firstrow THEN
      firstrow := FALSE;
      dumpHeader('Timer Tasks');
      dumpLine (dumpPad('Timer type', 25) || 
                dumpPad('Location', 10) ||
                dumpPad('Next Execute', 20) ||
                        'Interval');
 
      dumpLine (RPAD('-', 24, '-') ||
                RPAD(' ', 10, '-') ||
                RPAD(' ', 20, '-') ||
                RPAD(' ', 20, '-'));
    END IF;
 
    printint := dumpInt(c.timer_interval,19);
    dumpLine (dumpPad(c.type, 24) || ' ' ||
              dumpPad(c.timer_location,9) || ' ' ||
              dumpPad(c.next_execute,19) || ' ' ||
              dumpPad(printint,19));
  END LOOP;
 
END dumpTasks;
 
--
--
PROCEDURE dumpSls IS
CURSOR sls IS
  SELECT SUBSTR(name,1,19) name, sl_key, min_alloc, total_space, 
                dbms_ra_storage.freespace(sl_key)/(1024*1024*1024) freespace, 
                freespace_goal, system_purging_space, disk_groups
    FROM ra_storage_location
    WHERE total_space > 0
    ORDER BY name;
 
CURSOR purge_queue IS
  SELECT SUBSTR(sl_name,1, 19) sl_name, sl_key, 
         SUBSTR(db_unique_name,1, 19) db_name, db_key,
         purge_order, TO_CHAR(new_recovery_window) new_recovery, 
         new_pct_recovery, pct_storage
    FROM ra_purging_queue
    ORDER BY sl_name, purge_order;
 
CURSOR polling IS
  SELECT SUBSTR(polling_name,1, 19) polling_name, 
         polling_key, frequency, dest
    FROM ra_polling_policy
    ORDER BY polling_name;
 
firstrow BOOLEAN;
printint VARCHAR2(200);
    
BEGIN
  firstrow := TRUE;
  FOR c IN sls LOOP
    IF firstrow THEN
      firstrow := FALSE;
      dumpHeader('Storage Locations');
      dumpLine (dumpPad('Name', 20) || 
                dumpPad('Sl_key', 21) ||
                dumpPad('Min_alloc', 16) ||
                dumpPad('Total Size', 16) ||
                dumpPad('Freespace', 16) ||
                dumpPad('Freespace goal', 16) ||
                       'SysPurgeSpace');
      dumpLine ('Disk Groups');
      dumpLine (RPAD('-', 19, '-') ||
                RPAD(' ', 21, '-') ||
                RPAD(' ', 16, '-') ||
                RPAD(' ', 16, '-') ||
                RPAD(' ', 16, '-') ||
                RPAD(' ', 16, '-') ||
                RPAD(' ', 16, '-'));
    END IF;
 
    dumpLine (dumpPad(c.name, 19) || ' ' ||
              dumpPad(c.sl_key, 20) ||  ' ' ||
              dumpMB(c.min_alloc*1024, 15) ||  ' ' ||
              dumpGB(c.total_space, 15) || ' ' ||
              dumpGB(c.freespace, 15) || ' ' ||
              dumpGB(c.freespace_goal, 15) || ' ' ||
              dumpGB(c.system_purging_space, 15));
    dumpBig(c.disk_groups);
  END LOOP;
 
  firstrow := TRUE;
  FOR c IN purge_queue LOOP
    IF firstrow THEN
      firstrow := FALSE;
      dumpHeader('Purge queues');
      dumpLine (dumpPad('Sl name', 20) || 
                dumpPad('Sl_key', 21) ||
                dumpPad('Db name', 20) ||
                dumpPad('Db_key', 21) ||
                dumpPad('Purge Order', 12) ||
                dumpPad('New Recovery', 20) ||
                dumpPad('% of Goal', 11) ||
                        '% of Reserve');
      dumpLine (RPAD('-', 19, '-') ||
                RPAD(' ', 21, '-') ||
                RPAD(' ', 20, '-') ||
                RPAD(' ', 21, '-') ||
                RPAD(' ', 12, '-') ||
                RPAD(' ', 20, '-') ||
                RPAD(' ', 11, '-') ||
                RPAD(' ', 11, '-'));
    END IF;
 
    dumpLine (dumpPad(c.sl_name, 19) || ' ' ||
              dumpPad(c.sl_key,20) || ' ' ||
              dumpPad(c.db_name, 19) || ' ' ||
              dumpPad(c.db_key,20) || ' ' ||
              dumpPad(c.purge_order,11) || ' ' ||
--
              dumpPad(c.new_recovery,19) || ' ' ||
              dumpPct(c.new_pct_recovery) || ' ' ||
              dumpPct(c.pct_storage));
  END LOOP;
 
  firstrow := TRUE;
  FOR c IN polling LOOP
    IF firstrow THEN
      firstrow := FALSE;
      dumpHeader('Polling Policies');
      dumpLine (dumpPad('Name', 20) || 
                dumpPad('Poll_key', 21) ||
                        'Frequency');
      dumpLine ('Param');
      dumpLine (RPAD('-', 19, '-') ||
                RPAD(' ', 21, '-') ||
                RPAD(' ', 20, '-'));
    END IF;
 
    printint := dumpInt(c.frequency, 19);
    dumpLine (dumpPad(c.polling_name, 19) || ' ' ||
              dumpPad(c.polling_key, 20) ||  ' ' ||
              dumpPad(printint, 19));
    dumpBig(c.dest);
  END LOOP;
 
END dumpSls;
 
--
--
PROCEDURE dumpPdbs IS
CURSOR pdbs IS
  SELECT SUBSTR(db_unique_name,1,19) name, db_key, deleting, dbid, 
         SUBSTR(storage_location,1, 19) sl_name, space_usage,
         disk_reserved_space, recovery_window_goal, recovery_window_sbt
    FROM ra_database
    ORDER BY db_unique_name;
 
CURSOR pdb_movement IS
  SELECT SUBSTR(db_unique_name,1,19) name, db_key, 
         storage_movement_phase, storage_location_count
    FROM ra_database
    WHERE storage_movement_phase <> 'NOT MOVING'
    ORDER BY db_unique_name;
 
CURSOR db_access IS
  SELECT SUBSTR(db_unique_name,1,19) db_name, db_key,
         SUBSTR(username, 1, 19) username
    FROM ra_db_access
    ORDER BY db_unique_name, username;
 
firstrow BOOLEAN;
printint VARCHAR2(200);
printint2 VARCHAR2(200);
    
BEGIN
  firstrow := TRUE;
  FOR c IN pdbs LOOP
    IF firstrow THEN
      firstrow := FALSE;
      dumpHeader('Protected Databases');
      dumpLine (dumpPad('Name', 20) || 
                dumpPad('Db_key', 21) ||
                dumpPad('Deleting', 9) ||
                dumpPad('Dbid', 11) ||
                dumpPad('SL Name', 20) || 
                dumpPad('Space Usage', 16) ||
                dumpPad('Reserved Space', 16) ||
                dumpPad('Recovery Goal', 20) ||
                       'SBT Recovery Goal');
 
      dumpLine (RPAD('-', 19, '-') ||
                RPAD(' ', 21, '-') ||
                RPAD(' ', 09, '-') ||
                RPAD(' ', 11, '-') ||
                RPAD(' ', 20, '-') ||
                RPAD(' ', 16, '-') ||
                RPAD(' ', 16, '-') ||
                RPAD(' ', 20, '-') ||
                RPAD(' ', 20, '-'));
    END IF;
 
    printint  := dumpInt(c.recovery_window_goal,19);
    printint2 := dumpInt(c.recovery_window_sbt,19);
    dumpLine (dumpPad(c.name, 19) || ' ' ||
              dumpPad(c.db_key, 20) ||  ' ' ||
              dumpPad(c.deleting, 8) ||  ' ' ||
              dumpPad(c.dbid, 10) ||  ' ' ||
              dumpPad(c.sl_name, 19) || ' ' ||
              dumpGB(c.space_usage, 15) || ' ' ||
              dumpGB(c.disk_reserved_space, 15) || ' ' ||
              dumpPad(printint, 19) || ' ' ||
              dumpPad(printint2, 19));
  END LOOP;
 
  firstrow := TRUE;
  FOR c IN db_access LOOP
    IF firstrow THEN
      firstrow := FALSE;
      dumpHeader('Database access');
      dumpLine (dumpPad('Name', 20) || 
                dumpPad('Db_key', 21) ||
                        'Username');
 
      dumpLine (RPAD('-', 19, '-') ||
                RPAD(' ', 21, '-') ||
                RPAD(' ', 20, '-'));
    END IF;
 
    dumpLine (dumpPad(c.db_name, 19) || ' ' ||
              dumpPad(c.db_key, 20) ||  ' ' ||
              dumpPad(c.username, 19));
  END LOOP;
 
  firstrow := TRUE;
  FOR c IN pdb_movement LOOP
    IF firstrow THEN
      firstrow := FALSE;
      dumpHeader('Moving Protected DataBases');
      dumpLine (dumpPad('Name', 20) || 
                dumpPad('Db_key', 21) ||
                dumpPad('Move phase', 19) ||
                       'SL Count');
 
      dumpLine (RPAD('-', 19, '-') ||
                RPAD(' ', 21, '-') ||
                RPAD(' ', 19, '-') ||
                RPAD(' ', 10, '-'));
    END IF;
 
    dumpLine (dumpPad(c.name, 19) || ' ' ||
              dumpPad(c.db_key, 20) ||  ' ' ||
              dumpPad(c.storage_movement_phase, 18) || ' ' ||
              dumpPad(c.storage_location_count, 9));
  END LOOP;
 
END dumpPdbs;
 
--
PROCEDURE dumpBps IS
CURSOR bps IS
  SELECT s.db_key, s.ct_key, s.bp_key, s.sl_key, 
         DECODE(s.ftype, 'F','FILE', 'T','TAPE', 
                         'P','POLL', 'V','VIRT', '????') type, 
         s.endupload, bp.bp_recid, bp.bp_stamp, bp.vb_key, bp.lib_key, 
         s.completed, s.filesize/(1024*1024) filesize, 
         s.cretime, s.last_entry,
         DECODE(s.pieceinc, 'unknown', ' ', s.pieceinc) pieceinc, s.handle
  FROM sbt_catalog s
  LEFT OUTER JOIN bp ON (s.bp_key = bp.bp_key)
  ORDER BY s.db_key, s.cretime;
 
firstrow BOOLEAN;
    
BEGIN
  firstrow := TRUE;
  FOR c IN bps LOOP
    IF firstrow THEN
      firstrow := FALSE;
      dumpHeader('Backup Pieces');
      dumpLine (dumpPad('Db_key', 21) ||
                dumpPad('Ct_key', 21) ||
                dumpPad('Bp_key', 21) ||
                dumpPad('Sl_key', 21) ||
                dumpPad('Type', 5) || 
                dumpPad('EndLoad', 8) ||
                dumpPad('Recid', 10) ||
                        'Stamp');
 
      dumpLine (RPAD('-', 20, '-') ||
                RPAD(' ', 21, '-') ||
                RPAD(' ', 21, '-') ||
                RPAD(' ', 21, '-') ||
                RPAD(' ',  5, '-') ||
                RPAD(' ',  8, '-') ||
                RPAD(' ', 10, '-') ||
                RPAD(' ', 10, '-'));
 
 
      dumpLine (dumpPad('Vb_key', 21) ||
                dumpPad('Lib_key',21) ||
                dumpPad('Done', 5) ||
                dumpPad('Filesize', 16) ||
                dumpPad('Create Time', 20) ||
                dumpPad('Last update', 20) ||
                        'File Incarnation');
 
      dumpLine (RPAD('-', 20, '-') ||
                RPAD(' ', 21, '-') ||
                RPAD(' ',  5, '-') ||
                RPAD(' ', 16, '-') ||
                RPAD(' ', 20, '-') ||
                RPAD(' ', 20, '-') ||
                RPAD(' ', 17, '-'));
 
      dumpLine ('Handle');
 
      dumpLine (RPAD(' ', 120, '-'));
    END IF;
 
    dumpLine (dumpPad(c.db_key, 20) || ' ' ||
              dumpPad(c.ct_key, 20) ||  ' ' ||
              dumpPad(c.bp_key, 20) ||  ' ' ||
              dumpPad(c.sl_key, 20) ||  ' ' ||
              dumpPad(c.type, 4) ||  ' ' ||
              dumpPad(c.endupload, 7) || ' ' ||
              dumpPad(c.bp_recid, 9) || ' ' ||
              dumpPad(c.bp_stamp, 9));
 
    dumpLine (dumpPad(c.vb_key, 20) || ' ' ||
              dumpPad(c.lib_key, 20) || ' ' ||
              dumpPad(NVL(c.completed,'Y'), 4) || ' ' ||
              dumpMB(c.filesize, 15) || ' ' ||
              dumpPad(c.cretime, 19) || ' ' ||
              dumpPad(c.last_entry, 19) || ' ' ||
              dumpPad(c.pieceinc,16));
 
    dumpBig(c.handle);
  END LOOP;
END dumpBps;
 
--
PROCEDURE dumpCFinfo IS
CURSOR grps IS
  SELECT SUBSTR(g.gname,1,30) gname, g.gid gid, g.ausize ausize, 
    to_char(g.gvfld1, 'xxxxxxxx') gvfld1, to_char(g.gvfld2, 'xxxxxxxx') gvfld2
    FROM sys.amgrp$ g
    ORDER BY gid;
  
CURSOR conts IS
  SELECT SUBSTR(g.gname,1,30) gname, g.gid gid, c.cid cid, c.crid crid, 
    to_char(c.cvfld, 'xxxxxxxx') cvfld , c.state state, c.fsize cont_fsize, 
    c.fname cont_fname
    FROM sys.amcont$ c JOIN sys.amgrp$ g ON (c.gid = g.gid)
    ORDER BY cid;
  
CURSOR rvs IS
  SELECT SUBSTR(a.gname,1,30) gname, a.amrv_key amrv_key,
    DECODE(a.opstate, 'R','REBUILD', 'V','VALIDATE', '????') operation,
    DECODE(a.phase, 'I','INIT', 'S','STRUCTURE R/V', 'F','CONTAINED FILE R/V',
           'Z','FINALIZING', 'C','COMPLETED', '????') phase,
    DECODE(a.step, 'B','PHASE_STARTED', 'A','PHASE_ABORTED_FATAL', 
           'E','PHASE_COMPLETED_WITH_ERRORS',
           'C','PHASE_COMPLETED_NO_ERRORS', '????') execution_step,
    DECODE(a.error, 'E','FINSIHED WITH ERRORS', 
           'N','FINSIHED NO ERRORS', 'A','R/V ABORTED', 
           'a','ROW FOUND ABANDONDED', '????') results,
    pct_done, starttime, finishtime, doneid
    FROM sys.amrv$ a ORDER BY amrv_key;
  
CURSOR rvmsgs IS
  SELECT SUBSTR(a.gname,1,30) gname, m.amrv_key amrv_key, 
    m.amrvmsg_key amrvmsg_key, msgtime, msgphase, msgcode, NVL(fname, '') fname,
    NVL(msg, '') msg
    FROM sys.amrv$msg m LEFT OUTER JOIN sys.amrv$ a ON (a.amrv_key = m.amrv_key)
    WHERE msgcode NOT IN (101,102,103)
    ORDER BY m.amrv_key, m.amrvmsg_key;
 
firstrow BOOLEAN;
    
BEGIN
  firstrow := TRUE;
  FOR c IN grps LOOP
    IF firstrow THEN
      firstrow := FALSE;
      dumpHeader('Container Groups');
      dumpLine (dumpPad('Name', 31) || 
                dumpPad('GID', 21) ||
                dumpPad('AU Size', 12) ||
                dumpPad('gvfld1', 11) || 
                dumpPad('gvfld2', 11));
 
      dumpLine (RPAD('-', 30, '-') ||
                RPAD(' ', 21, '-') ||
                RPAD(' ', 12, '-') ||
                RPAD(' ', 11, '-') ||
                RPAD(' ', 11, '-'));
    END IF;
 
    dumpLine (dumpPad(c.gname, 30) || ' ' ||
              dumpPad(c.gid, 20) ||  ' ' ||
              dumpPad(c.ausize, 11) ||  ' ' ||
              dumpPad(c.gvfld1, 10) || ' ' ||
              dumpPad(c.gvfld2, 10));
  END LOOP;
 
  firstrow := TRUE;
  FOR c IN conts LOOP
    IF firstrow THEN
      firstrow := FALSE;
      dumpHeader('Container Files');
      dumpLine (dumpPad('Name', 31) || 
                dumpPad('GID', 21) ||
                dumpPad('CID', 21) ||
                dumpPad('CRID', 21) ||
                dumpPad('cvfld', 11) || 
                dumpPad('state', 10) || 
                dumpPad('fsize', 10)); 
      
      dumpLine (RPAD('-', 30, '-') ||
                RPAD(' ', 21, '-') ||
                RPAD(' ', 21, '-') ||
                RPAD(' ', 21, '-') ||
                RPAD(' ', 11, '-') ||
                RPAD(' ', 10, '-') ||
                RPAD(' ', 10, '-'));
      
      dumpLine ('Container Filename');
      dumpLine (RPAD('-', 127, '-'));
      
    END IF;
 
    dumpLine (dumpPad(c.gname, 30) || ' ' ||
              dumpPad(c.gid, 20) ||  ' ' ||
              dumpPad(c.cid, 20) ||  ' ' ||
              dumpPad(c.crid, 20) ||  ' ' ||
              dumpPad(c.cvfld, 10) ||  ' ' ||
              dumpPad(c.state, 9) || ' ' ||
              dumpGB (c.cont_fsize, 9));
    
    dumpLine(dumpPad(c.cont_fname, 127));
  END LOOP;
  
      
  firstrow := TRUE;
  FOR c IN rvs LOOP
    IF firstrow THEN
      firstrow := FALSE;
      dumpHeader('Rebuild/Validate Executions');
      dumpLine (dumpPad('Name', 31) || 
                dumpPad('amrv_key', 21) ||
                dumpPad('Operation', 10) ||
                dumpPad('Phase', 20) ||
                dumpPad('Execution Step', 27));
      
      dumpLine (RPAD('-', 30, '-') ||
                RPAD(' ', 21, '-') ||
                RPAD(' ', 10, '-') ||
                RPAD(' ', 20, '-') ||
                RPAD(' ', 27, '-'));
      
      dumpLine (dumpPad('Results', 25) ||
                dumpPad('Pct', 6) ||
                dumpPad('Start', 21) || 
                dumpPad('End', 21) || 
                dumpPad('doneid', 10));
      
      dumpLine (RPAD('-', 24, '-') ||
                RPAD(' ', 6, '-') ||
                RPAD(' ', 21, '-') ||
                RPAD(' ', 21, '-') ||
                RPAD(' ', 10, '-'));
    END IF;
                
    dumpLine (dumpPad(c.gname, 30) || ' ' ||
              dumpPad(c.amrv_key, 20) || ' ' ||
              dumpPad(c.operation, 9) || ' ' ||
              dumpPad(c.phase, 19) || ' ' ||
              dumpPad(c.execution_step, 26));
 
    dumpLine( dumpPad(c.results, 24) || ' ' ||
              dumpPad(c.pct_done, 5) || ' ' ||
              dumpPad(c.starttime, 20) || ' ' ||
              dumpPad(c.finishtime, 20) || ' ' || 
              dumpPad(c.doneid, 9));
  END LOOP;
  
  firstrow := TRUE;
  FOR c IN rvmsgs LOOP
    IF firstrow THEN
      firstrow := FALSE;
      dumpHeader('Rebuild/Validate Messages');
      dumpLine (dumpPad('Name', 31) || 
                dumpPad('amrv_key', 21) ||
                dumpPad('amrvmsg_key', 21) ||
                dumpPad('Message Time', 21) ||
                dumpPad('Phase', 6) ||
                dumpPad('Code', 10));
 
      dumpLine (RPAD('-', 30, '-') ||
                RPAD(' ', 21, '-') ||
                RPAD(' ', 21, '-') ||
                RPAD(' ', 21, '-') ||
                RPAD(' ', 6, '-') ||
                RPAD(' ', 10, '-'));
                
      dumpLine('Filename');
      dumpLine (RPAD('-', 127, '-'));
      
      dumpLine('Message');
      dumpLine (RPAD('-', 127, '-'));
      
    END IF;
 
    dumpLine (dumpPad(c.gname, 30) || ' ' ||
              dumpPad(c.amrv_key, 20) || ' ' ||
              dumpPad(c.amrvmsg_key, 20) || ' ' ||
              dumpPad(c.msgtime, 20) || ' ' ||
              dumpPad(c.msgphase, 5) || ' ' ||
              dumpPad(c.msgcode, 9));
                
    dumpBig(c.fname);
    dumpBig(c.msg);
    
  END LOOP;
 
END dumpCFinfo;
 
--
PROCEDURE dumpDataPump (filename VARCHAR2) IS
  l_md_filter VARCHAR2(200); -- tables to exclude
  h1 NUMBER;               -- Data Pump job handle
  job_state VARCHAR2(30);  -- To keep track of job state
  sts ku$_Status;
  ind NUMBER;              -- Loop index
  spos NUMBER;             -- String starting position
  slen NUMBER;             -- String length for output
  le ku$_LogEntry;         -- For WIP and error messages
 
BEGIN
  IF NOT s_filedump THEN
    dumpHeader('No DataPump dump since directory was not found');
  ELSE
    dumpHeader('DataPump dumpfile will be saved at ' ||
               DUMP_DIR || ':' || filename || '_dp' || s_file_ext);
 
--
    h1 := 
     dbms_datapump.open('EXPORT','SCHEMA',NULL,'DUMPJOB' || rai_sq.NEXTVAL);
    
 
--
    dbms_datapump.add_file(h1,filename || '_DATAPUMPlog' || s_file_ext,
                           DUMP_DIR, NULL,
                           dbms_datapump.ku$_file_type_log_file,
                           NULL);
 
--
    dbms_datapump.set_parameter(h1, 'COMPRESSION', 'ALL');
    dbms_datapump.set_parameter(h1, 'COMPRESSION_ALGORITHM', 'MEDIUM');
 
--
    dbms_datapump.add_file(h1,filename || '_DATAPUMP' || s_file_ext,
                              DUMP_DIR, NULL,
                              dbms_datapump.ku$_file_type_dump_file,
                              NULL);
 
--
    IF NOT (s_blocks AND s_chunks) THEN
      IF (NOT s_blocks) AND (NOT s_chunks) THEN
        l_md_filter :=  'IN (''BLOCKS'',''PLANS_DETAILS'',''CHUNKS'')';
      ELSIF (NOT s_blocks) THEN
        l_md_filter :=  'IN (''BLOCKS'',''PLANS_DETAILS'')';
      ELSE
        l_md_filter :=  'IN (''CHUNKS'')';
      END IF;
 
      dbms_datapump.metadata_filter(h1, 'EXCLUDE_NAME_EXPR', 
                                        l_md_filter, 
                                        'TABLE');
    END IF;
 
--
    dbms_datapump.start_job(h1);
 
--
    job_state := 'UNDEFINED';
    WHILE (job_state != 'COMPLETED') AND (job_state != 'COMPLETING') 
          AND (job_state != 'STOPPED') LOOP
--
      dbms_datapump.get_status(h1,0,0,job_state,sts);
      dbms_lock.sleep(2);
    END LOOP;
  END IF;
 
  dumpHeader('DataPump dumpfile has been saved.');
 
--
EXCEPTION
  WHEN OTHERS THEN
    dumpLine('Exception in Data Pump job');
    dumpLine(SQLERRM);
    dumpLine('Data Pump errors:');
 
    dbms_datapump.get_status(h1,dbms_datapump.ku$_status_job_error,0,
                             job_state,sts);
 
    IF (BITAND(sts.mask,dbms_datapump.ku$_status_job_error) != 0) THEN
      le := sts.error;
 
      IF le IS NOT NULL THEN
        ind := le.FIRST;
 
        WHILE ind IS NOT NULL LOOP
          spos := 1;
          slen := LENGTH(le(ind).LogText);
 
          IF slen > 255 THEN
            slen := 255;
          END IF;
 
          WHILE slen > 0 LOOP
            dumpLine(substr(le(ind).LogText,spos,slen));
            spos := spos + 255;
            slen := length(le(ind).LogText) + 1 - spos;
          END LOOP;
 
          ind := le.NEXT(ind);
        END LOOP;
      END IF;
    END IF;
 
END dumpDataPump;
 
--
PROCEDURE dumper (ospid        IN VARCHAR2,
                  quiesce      IN BOOLEAN DEFAULT FALSE,
                  datapumpdump IN BOOLEAN DEFAULT TRUE) IS
 
  l_dumper_params VARCHAR2(512);
  l_pos         NUMBER := 1;
  l_pos2        NUMBER;
  l_keyword     VARCHAR2(100);
  counter       NUMBER;
  l_filename    VARCHAR2(100);
 
  l_backtrace_stack VARCHAR2(4000);
  l_call_stack    VARCHAR2(4000);
  l_error_stack   VARCHAR2(4000);
  l_ospid VARCHAR2(24);
 
BEGIN
 
--
  DBMS_RA_SCHEDULER.ASSERT_OWNER;
 
  IF quiesce THEN
    DBMS_RA_SCHEDULER.QUIESCE_RS();
  END IF;
 
--
  SELECT MAX(DECODE(name, '_dumper_params',   value)) 
       , MAX(DECODE(name, '_dumper_file_ext', LOWER(value)))
    INTO l_dumper_params, s_file_ext
    FROM config
    WHERE name IN ('_dumper_params', '_dumper_file_ext');
 
  LOOP
    l_pos2 := INSTR (l_dumper_params, ',', l_pos);
 
    IF l_pos2 = 0 THEN
      l_keyword := SUBSTR(l_dumper_params, l_pos);
    ELSE
      l_keyword := SUBSTR(l_dumper_params, l_pos, l_pos2-l_pos);
    END IF;
 
    CASE UPPER(l_keyword)
      WHEN 'DATAPUMP'   THEN s_datapump := TRUE;
      WHEN 'NODATAPUMP' THEN s_datapump := FALSE;
      WHEN 'BLOCKS'     THEN s_blocks := TRUE;
      WHEN 'NOBLOCKS'   THEN s_blocks := FALSE;
      WHEN 'CHUNKS'     THEN s_chunks := TRUE;
      WHEN 'NOCHUNKS'   THEN s_chunks := FALSE;
      ELSE NULL;
    END CASE;
    
--
    EXIT WHEN l_pos2 = 0;
 
--
    l_pos := l_pos2 + 1;
  END LOOP;
 
--
  IF l_ospid IS NULL THEN
    SELECT spid INTO l_ospid FROM sys.rai_my_ospid WHERE ROWNUM=1;
  END IF;
 
--
  l_filename := 'radump_time_' || TO_CHAR(SYSTIMESTAMP , 'HH24MISS') ||
                '__ospid_' || TRIM(l_ospid);
 
--
  s_start_history := (SYSTIMESTAMP - RECENT_INTERVAL);
 
--
  SELECT COUNT(*) INTO counter
    FROM all_directories
    WHERE directory_name = DUMP_DIR;
 
  IF counter = 0 THEN
    s_tracedump := TRUE;
    s_filedump := FALSE;
  ELSE
    s_tracedump := FALSE;
    s_filedump := TRUE;
  END IF;
 
 
 
--
  dumpOpen(l_filename || '_RADUMP');
 
  dumpHeader('Recovery Appliance state dump for pid ' || l_ospid || ' at ' || 
             TO_CHAR(SYSTIMESTAMP, 'DD-MM-YYYY HH24:MI:SS'));
 
  dumpStatus;           -- error log, recent apis, and locks
  dumpSessions;         -- active sessions, dead sessions
  dumpTasks;            -- current tasks, recent tasks, sbt tasks, timer tasks
  dumpSls;              -- storage locations, purge queues and polling locs
  dumpPdbs;             -- pdbs, privs
  dumpBps;              -- sbt_catalog table
  dumpCFinfo;           -- container file info, amgrp$, amcont$, amrv$, amrv$msg
 
  IF s_datapump AND datapumpdump THEN
    dumpDataPump (l_filename);         
--
  END IF;
 
  dumpHeader('End of recovery appliance state dump at ' || 
             TO_CHAR(SYSTIMESTAMP, 'DD-MM-YYYY HH24:MI:SS'));
 
--
  dumpClose;
 
  IF quiesce THEN
    DBMS_RA_SCHEDULER.UNQUIESCE_RS();
  END IF;
 
EXCEPTION
WHEN OTHERS THEN
  l_backtrace_stack :=     SYS.DBMS_UTILITY.FORMAT_ERROR_BACKTRACE();
  l_call_stack      :=     SYS.DBMS_UTILITY.FORMAT_CALL_STACK();
  dumpLine (l_call_stack);
  dumpLine (l_backtrace_stack);
  dumpClose;
 
  IF quiesce THEN
    DBMS_RA_SCHEDULER.UNQUIESCE_RS();
  END IF;
 
  RAISE;
 
END dumper;
 
END dbms_ra_dump;
>>>
 
define prvtrspl_plb
<<<
CREATE OR REPLACE PACKAGE BODY dbms_ra_pool IS
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
 
/*---------------------------------------------------------------------------*
 *                   PRIVATE TYPES AND CONSTANTS                             *
 *---------------------------------------------------------------------------*/
 
/*----------------------------------------*
 * Session scoped Package State Variables *
 *----------------------------------------*/
 
--
debug              NUMBER := AM_DEBUG_HIGH; --AM_DEBUG_ON;
debug_outtype      NUMBER := sys.dbms_system.trace_file;
s_safemode         BOOLEAN := FALSE;
 
--
--
--
saved_vbkey        NUMBER;  -- Backup processing: remember the vbkey
saved_krbphdf      NUMBER;  -- Backup processing: remember dfkey for krbph
saved_krbph        NUMBER;  -- Backup processing: remember chunk# for krbph
saved_krbph_name   VARCHAR2(513); -- Name of saved_krbph chunk.
saved_krbph_cfname VARCHAR2(513); -- Name of saved_krbph cf piece file chunk.
saved_krbph_spname VARCHAR2(513); -- Name of saved_krbph sp piece file chunk.
 
--
--
--
s_purge_dbinc      NUMBER;
 
--
s_purgeknows       NUMBER;
 
--
TRUE#         CONSTANT NUMBER := 1;
FALSE#        CONSTANT NUMBER := 0;
SPACING       CONSTANT NUMBER := 10; -- Sequence space, allow for post recs
MAXCHUNKSIZE  CONSTANT NUMBER := (32 * 1024 * 1024);
MAXDELCHUNKS  CONSTANT NUMBER := 100; -- Guestimate: See purge_pool for usage
--
--
--
--
--
TOTBLKPRCHNKS CONSTANT NUMBER := 1000000;
 
MIN_READ_BUFS CONSTANT NUMBER := 10;             -- Minimum read buffers.
DEF_READ_BUFS CONSTANT NUMBER := 128;            -- Default read buffers.
DEF_READ_SIZE CONSTANT NUMBER := 12 * 32 * 1024; -- Default 384k read buf size
 
--
MBLK_SIZE      CONSTANT NUMBER := 84;   /* sizeof(kbrscb) + sizeof(krbpmd) */
 
 
--
--
--
--
--
--
--
--
RESTART_PURGE_OBSOLETEP  CONSTANT NUMBER := 11; -- We Started obsolete plans
RESTART_PURGE_DEL_BLOCKS CONSTANT NUMBER := 12; -- We started deleting blocks
RESTART_PURGE_VBDF       CONSTANT NUMBER := 14; -- We started purge vbdf
RESTART_PURGE_ALL_RETRY1 CONSTANT NUMBER := 15; -- Purge_all needs retry
RESTART_PURGE_ALL_RETRY2 CONSTANT NUMBER := 16; -- Purge_all needs retry
RESTART_PURGE_ALL_RETRY3 CONSTANT NUMBER := 17; -- Purge_all needs retry
 
 
/*--------------------------------------------------*
 * Function/State variables                         *
 * These are config values that do not change value *
 *--------------------------------------------------*/
 
sf_chunksize         NUMBER := NULL;
sf_curr_db           NUMBER := 0;
sf_pooloff           BOOLEAN := NULL;
 
--
FUNCTION f_chunksize(p_dbkey IN NUMBER) RETURN NUMBER IS
BEGIN
--
  IF sf_curr_db != p_dbkey THEN
    SELECT sl_min_alloc INTO sf_chunksize FROM odb WHERE db_key = p_dbkey;
    sf_curr_db := p_dbkey;
  END IF;
 
  RETURN sf_chunksize;
END f_chunksize;
 
--
FUNCTION f_pooloff RETURN BOOLEAN IS
  l_pooloff config.value%TYPE;
BEGIN
  IF sf_pooloff IS NULL THEN
    SELECT NVL(UPPER(MAX(value)), 'NO')
      INTO l_pooloff
      FROM config
     WHERE name = '_pooloff';
 
    sf_pooloff := (l_pooloff = 'YES');
  END IF;
 
  RETURN sf_pooloff;
END f_pooloff;
 
/*---------------------------------------------------------------------------*
 *                   PRIVATE FUNCTION DECLARATIONS                           *
 *---------------------------------------------------------------------------*/
 
PROCEDURE deb(p_line IN varchar2, p_level IN NUMBER DEFAULT AM_DEBUG_ON);
 
PROCEDURE purge_lock(p_key IN NUMBER);
 
PROCEDURE purge_unlock(p_key IN NUMBER);
 
PROCEDURE debugdf(p_dfkey IN NUMBER);
 
PROCEDURE save_error;
 
PROCEDURE clear_error;
 
FUNCTION print (p_value IN BOOLEAN) RETURN VARCHAR2;
 
PROCEDURE raise_bad_metadata(p_dfkey IN NUMBER);
 
PROCEDURE working_ckpid(p_dbkey     IN     NUMBER,
                        p_dfkey     IN     NUMBER,
                        p_vbkey     IN     NUMBER,
                        p_orphans   IN     BOOLEAN, -- orphan backups
                        p_dbinckey  IN OUT NUMBER,  -- in backup dbinc
                        p_ckpid     IN OUT NUMBER,  -- in backup ckpid
                        p_deadinc   OUT    NUMBER,  -- orphan inc we no need
                        p_orphaninc OUT    NUMBER);  -- orphan blocks inc
 
PROCEDURE alloc_plan(p_dbkey     IN NUMBER,
                     p_dfkey     IN NUMBER,
                     p_vbkey     IN NUMBER,
                     p_qtype     IN NUMBER);
 
PROCEDURE dealloc_plan(p_dfkey     IN NUMBER,
                       p_vbkey     IN NUMBER  DEFAULT NULL,
                       p_qtype     IN NUMBER  DEFAULT NULL,
                       p_lock      IN BOOLEAN DEFAULT TRUE);
 
PROCEDURE trim_plan(p_dfkey     IN NUMBER);
 
FUNCTION fragmentation(p_dbkey IN NUMBER,
                       p_dfkey IN NUMBER,
                       p_vbkey IN NUMBER) RETURN NUMBER;
 
PROCEDURE show_plan(p_vbkey       IN  NUMBER, -- Virtual backup id
                    p_dfkey       IN  NUMBER, -- Datafile key
                    p_krbph_dfkey IN  NUMBER, -- Datafile key for krbph
                    p_qtype       IN  NUMBER); -- KBRSPLBLD_ type stored in plan
 
PROCEDURE plan_blocks(p_vbkey       IN  NUMBER, -- Virtual backup id
                      p_dfkey       IN  NUMBER, -- Datafile key
                      p_chunksize   IN  NUMBER, -- size of chunk
                      p_bufsize     IN  NUMBER, -- size of read buffers
                      p_blksize     IN  NUMBER, -- size of each block
                      p_type        IN  NUMBER, -- KBRSPLBLD_ type
                      p_totalsize   OUT NUMBER, -- backup size of df
                      p_totalblocks OUT NUMBER, -- blocks in datafile
                      p_totalchunks OUT NUMBER, -- distinct chunks in plan
                      p_signature   OUT NUMBER, -- signature 4 restore
                      p_maxrank     OUT NUMBER); -- block ranking in plan
 
PROCEDURE restore_plan_blocks(p_type        IN  NUMBER, -- KBRSPLBLD_ type
                              p_dfkey       IN  NUMBER, -- Datafile key
                              p_vbkey       IN  NUMBER, -- Virtual backup id
                              p_blksize     IN  NUMBER);-- size of each block
 
PROCEDURE old_chunks(p_type     IN  NUMBER,
                     p_dfkey    IN  NUMBER,
                     p_vbkey    IN  NUMBER);
 
PROCEDURE restricted_purge(p_dfkey    IN NUMBER, -- Datafile key
                           p_vbkey    IN NUMBER, -- Virtual backup id
                           p_type     IN NUMBER, -- plan type
                           p_dbkey IN NUMBER,
                           p_chunks IN NUMBER);
 
PROCEDURE optimize_blocks(p_dfkey        IN  NUMBER,
                          p_vbkey        IN  NUMBER, -- Virtual backup id
                          p_type         IN  NUMBER, -- plan type
                          p_stored       OUT NUMBER,
                          p_needs        OUT NUMBER);
 
PROCEDURE purge_pool(p_dbkey      IN    NUMBER,
                     p_type       IN    NUMBER,
                     p_qtype      IN    NUMBER,
                     p_dfkey      IN    NUMBER,
                     p_vbkey      IN    NUMBER,
                     p_dflocked   IN    BOOLEAN DEFAULT FALSE);
 
PROCEDURE purge_vbdf(p_dbkey      IN    NUMBER,
                     p_type       IN    NUMBER,
                     p_dfkey      IN    NUMBER,                     
                     p_vbkey      IN    NUMBER);
 
PROCEDURE reorderDF(p_type  IN NUMBER,      -- Type of KBRSPLBLD_% to perform
                    p_dfkey IN NUMBER,
                    p_vbkey IN NUMBER);
 
PROCEDURE purgeRes(p_dfkey      IN  NUMBER,
                   p_vbkey      IN  NUMBER,
                   p_savepoint  IN  NUMBER,
                   p_small      OUT BOOLEAN);
 
PROCEDURE set_next_retention(p_dbkey      IN NUMBER,
                             p_currinc    IN NUMBER,
                             p_outscn    OUT NUMBER);
 
PROCEDURE purgeObsolete(p_slkey      IN    NUMBER,
                        p_dbkey      IN    NUMBER,
                        p_notasks    IN    BOOLEAN);
 
PROCEDURE process_allfiles (p_dbkey    IN  NUMBER,
                            p_bskey    IN  NUMBER,
                            p_bpkey    IN  NUMBER,
                            p_toname   IN  VARCHAR2,
                            p_hasdups  IN  BOOLEAN,
                            p_update   IN  BOOLEAN);
 
PROCEDURE cleanup(p_vbkey IN NUMBER);
 
FUNCTION isTaped(p_dbkey IN NUMBER,
                 p_bpkey IN NUMBER,
                 p_bskey IN NUMBER) RETURN BOOLEAN;
 
PROCEDURE new_plans (p_dbkey    IN  NUMBER,
                     p_dfkey    IN  NUMBER,
                     p_nopurge  IN  BOOLEAN DEFAULT FALSE);
 
FUNCTION orphans (p_dbkey    IN  NUMBER,
                  p_dfkey    IN  NUMBER,
                  p_currinc  IN  NUMBER DEFAULT NULL)
 RETURN BOOLEAN;
 
FUNCTION orphan_bp(p_dbkey    IN  NUMBER,
                   p_dfkey    IN  NUMBER,
                   p_currinc  IN  NUMBER)
 RETURN BOOLEAN;
 
FUNCTION orphan_blocks(p_dbkey    IN  NUMBER,
                       p_dfkey    IN  NUMBER)
 RETURN BOOLEAN;
 
PROCEDURE orphan_safe(p_dbkey    IN  NUMBER,
                      p_dfkey    IN  NUMBER,
                      p_currinc  IN  NUMBER,
                      o_vbkey    OUT NUMBER,
                      o_scn      OUT NUMBER);
 
PROCEDURE orphan_common(p_dbinc_a  IN  NUMBER,
                        p_dbinc_b  IN  NUMBER,
                        p_dfkey    IN  NUMBER,
                        o_ckpid    OUT NUMBER,
                        o_ckpscn   OUT NUMBER);
 
PROCEDURE q_restore_fast(p_type        IN  NUMBER, -- KBRSPLBLD_ type
                         p_dfkey       IN  NUMBER,
                         p_vbkey       IN  NUMBER,
                         p_incrscn     IN  NUMBER,
                         p_ckpscn      IN  NUMBER,
                         p_absscn      IN  NUMBER,
                         p_ckpid       IN  NUMBER,
                         p_minckpid    IN  NUMBER,
                         p_maxckpid    IN  NUMBER,
                         p_dbinc_key   IN  NUMBER,
                         p_firstblk    IN  NUMBER,
                         p_lastblk     IN  NUMBER);
 
PROCEDURE q_restore_incs(p_type        IN  NUMBER, -- KBRSPLBLD_ type
                         p_dfkey       IN  NUMBER,
                         p_vbkey       IN  NUMBER,
                         p_incrscn     IN  NUMBER,
                         p_ckpscn      IN  NUMBER,
                         p_absscn      IN  NUMBER,
                         p_ckpid       IN  NUMBER,
                         p_minckpid    IN  NUMBER,
                         p_maxckpid    IN  NUMBER,
                         p_dbinc_key   IN  NUMBER,
                         p_deadinc     IN  NUMBER,
                         p_orphaninc   IN  NUMBER,
                         p_maxorphscn  IN  NUMBER,
                         p_firstblk    IN  NUMBER,
                         p_lastblk     IN  NUMBER);
 
PROCEDURE q_restore_cdb(p_type        IN  NUMBER, -- KBRSPLBLD_ type
                        p_dfkey       IN  NUMBER,
                        p_vbkey       IN  NUMBER,
                        p_incrscn     IN  NUMBER,
                        p_ckpscn      IN  NUMBER,
                        p_absscn      IN  NUMBER,
                        p_ckpid       IN  NUMBER,
                        p_minckpid    IN  NUMBER,
                        p_maxckpid    IN  NUMBER,
                        p_pdbinc_key  IN  NUMBER,
                        p_dbinc_key   IN  NUMBER,
                        p_deadinc     IN  NUMBER,
                        p_orphaninc   IN  NUMBER,
                        p_maxorphscn  IN  NUMBER,
                        p_firstblk    IN  NUMBER,
                        p_lastblk     IN  NUMBER,
                        p_orphans     IN  BOOLEAN);
 
PROCEDURE q_purge_basic(p_type        IN  NUMBER, -- KBRSPLBLD_ type
                        p_dfkey       IN  NUMBER,
                        p_vbkey       IN  NUMBER,
                        p_dbkey       IN  NUMBER,
                        p_currinc     IN  NUMBER,
                        p_ckpscn      IN  NUMBER,
                        p_absscn      IN  NUMBER,
                        p_ckpid       IN  NUMBER,
                        p_minckpid    IN  NUMBER);
 
PROCEDURE q_purge_orphan(p_type        IN  NUMBER, -- KBRSPLBLD_ type
                         p_dbkey       IN  NUMBER,
                         p_dfkey       IN  NUMBER,
                         p_vbkey       IN  NUMBER,
                         p_ckpscn      IN  NUMBER,
                         p_absscn      IN  NUMBER,
                         p_ckpid       IN  NUMBER,
                         p_minckpid    IN  NUMBER,
                         p_maxckpid    IN  NUMBER,
                         p_dbinc_key   IN  NUMBER,
                         p_deadinc     IN  NUMBER,  -- Orphan inc we no need
                         p_orphaninc   IN  NUMBER); -- Orphan block inc
 
PROCEDURE q_purge_dup(p_type        IN  NUMBER,
                      p_dfkey       IN  NUMBER,
                      p_vbkey       IN  NUMBER,
                      p_dbkey       IN  NUMBER,
                      p_currinc     IN  NUMBER,
                      p_fuzdif      IN  NUMBER,
                      p_minscn      IN  NUMBER);
 
PROCEDURE q_purge_all(p_dfkey       IN  NUMBER,
                      p_vbkey       IN  NUMBER,
                      p_dbkey       IN  NUMBER);
 
/*---------------------------------------------------------------------------*
 *                         EXPORT FUNCTIONS                                  *
 *---------------------------------------------------------------------------*/
 
 
--
--
--
--
--
--
--
--
--
PROCEDURE setDebug(p_level IN NUMBER,
                   p_safemode IN NUMBER,
                   p_outtype IN NUMBER DEFAULT sys.dbms_system.trace_file)
 IS
BEGIN
  debug := p_level;
  s_safemode := (p_safemode = 1);
  debug_outtype := p_outtype;
END setDebug;
 
 
--
--
--
--
--
--
--
--
FUNCTION incrLevel(p_create_scn    IN NUMBER,  -- bdf.create_scn
                   p_incr_scn      IN NUMBER)  -- bdf.incr_scn
  RETURN NUMBER IS
 l_level NUMBER;
BEGIN
--
--
--
--
--
--
--
--
  IF p_incr_scn = 0 OR
     (p_incr_scn <= p_create_scn)
  THEN
    l_level := 0;
  ELSE
    l_level := 1;
  END IF;
 
  RETURN l_level;
END incrLevel;
 
 
--
--
--
--
--
--
--
PROCEDURE prep_piece_read(p_inbpkey     IN  NUMBER,
                          p_loc         OUT VARCHAR2, -- Storage location
                          p_dbkey       OUT NUMBER,
                          p_db_id       OUT NUMBER,
                          p_dfkey       OUT NUMBER,   -- 0 if more than 1 df
                          p_vbkey       OUT NUMBER,
                          p_blksize     OUT NUMBER,
                          p_original    OUT NUMBER,   -- 1 == Virtual copy
                          p_read_bufs   OUT NUMBER,
                          p_read_size   OUT NUMBER,
                          p_read_waste  OUT NUMBER)
 IS
--
  CURSOR fPlans(c_bskey NUMBER, c_vbkey NUMBER, c_type NUMBER) IS
    SELECT df_key
      FROM vbdf v, bdf d
      WHERE v.dbinc_key = d.dbinc_key
        AND v.ckp_scn = d.ckp_scn
        AND v.file# = d.file#
        AND d.bs_key = c_bskey
        AND v.vb_key = c_vbkey
    MINUS
    SELECT /*+ INDEX(p) */
           df_key
      FROM plans p
      WHERE p.type = c_type
        AND p.vb_key = c_vbkey
        AND p.df_key IN (
              SELECT v.df_key
                FROM vbdf v
               WHERE v.vb_key = c_vbkey
            )
        AND p.blksread IS NOT NULL;
 
--
  CURSOR fnos(c_bskey NUMBER, c_vbkey NUMBER) IS
    SELECT v.db_key, v.vb_key, v.df_key, v.vcbp_key
      FROM vbdf v, bdf d
      WHERE v.dbinc_key = d.dbinc_key
        AND v.ckp_scn = d.ckp_scn
        AND v.file# = d.file#
        AND v.vb_key = c_vbkey
        AND d.bs_key = c_bskey;
 
  l_dfkey      NUMBER;
  l_numdf      NUMBER := 0;
  l_vcbpkey    NUMBER;
  l_type       NUMBER := NULL;
  l_bskey      NUMBER;
  l_count      NUMBER;
  l_handle     VARCHAR2(1024);
  l_done       BOOLEAN;
BEGIN
  deb('prep_piece_read: bpkey ' || p_inbpkey ||
      ', ' || systimestamp, AM_DEBUG_MED);
--
 
--
  IF NOT dbms_ra_int.read_lock(dbms_ra_int.KEY_BP, p_inbpkey)
  THEN
--
--
--
    RAISE dbms_ra_scheduler.e_retry_error;
  END IF;
 
--
  SELECT bp.db_key, bp.vb_key, bp.bs_key, bp.handle
    INTO p_dbkey, p_vbkey, l_bskey, l_handle
    FROM bp, bs
    WHERE bp.bs_key = bs.bs_key
      AND bp.status != 'D'
      AND bp.ba_access != 'U'
      AND bp_key = p_inbpkey;
 
--
  FOR f IN fnos(l_bskey, p_vbkey) LOOP
    IF NOT dbms_ra_int.read_lock(dbms_ra_int.KEY_DF, f.df_key)
    THEN
      RAISE dbms_ra_scheduler.e_retry_error; -- Not possible, so give up.
    END IF;
    l_dfkey := f.df_key;     -- Any dfkey will do.
    l_vcbpkey := f.vcbp_key; -- Should all be the same.
    l_numdf := l_numdf + 1;  -- Counting the datafiles.
  END LOOP;
 
--
  IF p_inbpkey = l_vcbpkey THEN
    l_type := KBRSPLBLD_ORIGPIECE;
    p_original := 1;
    IF l_numdf > 1 THEN -- We only provide a dfkey if there is one.
      p_dfkey := 0;
    ELSE
      p_dfkey := l_dfkey;
    END IF;
  ELSE
    l_type := KBRSPLBLD_PIECE;
    p_original := 0;
    p_dfkey := l_dfkey;
  END IF;
 
--
  FOR f IN fPlans(l_bskey, p_vbkey, l_type) LOOP
    l_done := FALSE;
    WHILE NOT l_done LOOP
      BEGIN
        planDF(l_type, f.df_key, p_vbkey, 0, TRUE, TRUE);
        l_done := TRUE;
      EXCEPTION
        WHEN dbms_ra_scheduler.e_snapshot_too_old THEN
          save_error;
--
--
          dbms_lock.sleep(5);
          clear_error;
 
        WHEN dbms_ra_scheduler.e_no_longer_exists THEN
--
--
--
          save_error;
          clear_error;
 
      END;
    END LOOP;
 
--
    BEGIN
      SELECT 1 INTO l_count FROM plans
        WHERE type = l_type AND vb_key = p_vbkey AND df_key = f.df_key
          AND blksread IS NOT NULL;
    EXCEPTION
      WHEN no_data_found THEN
        save_error;
        SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(
                                  DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM,
                                  'Plan broken for bpkey ' || p_inbpkey ||
                                  ', dfkey ' || f.df_key ||
                                  ', vbkey ' || p_vbkey);
    END;
  END LOOP;
 
--
  SELECT db_id INTO p_db_id
  FROM db WHERE db_key = p_dbkey;
 
--
  SELECT sl_cg_name INTO p_loc
    FROM vbdf v, odb o, sl s
    WHERE v.vb_key = p_vbkey
      AND v.relfno = 1
      AND o.db_key = v.db_key
      AND s.sl_key = o.sl_key;
 
--
  prep_read(l_type, l_bskey, p_vbkey, l_dfkey, p_blksize, 
            p_read_bufs, p_read_size, p_read_waste);
END prep_piece_read;
 
 
--
--
--
--
--
--
--
PROCEDURE prep_read(p_type        IN    NUMBER, /* KBRSPLBLD_% */
                    p_bskey       IN    NUMBER, /* optional */
                    p_vbkey       IN    NUMBER,
                    p_dfkey       IN    NUMBER,
                    p_blksize     OUT   NUMBER,
                    p_read_bufs   OUT   NUMBER,
                    p_read_size   OUT   NUMBER,
                    p_read_waste  OUT   NUMBER)
 IS
  l_all   NUMBER;
BEGIN
  deb('prep_read: type ' || p_type ||
      ', dfkey ' || p_dfkey ||
      ', vbkey ' || p_vbkey, AM_DEBUG_MED);
 
--
  SELECT /*+ RESULT_CACHE */
         NVL(MAX(DECODE(name, '_read_bufs',  value)), DEF_READ_BUFS),
         NVL(MAX(DECODE(name, '_read_size',  value)), DEF_READ_SIZE),
         NVL(MAX(DECODE(name, '_read_waste', value)), 0)
  INTO
         p_read_bufs,
         p_read_size,
         p_read_waste
  FROM config
  WHERE name IN ('_read_bufs',
                 '_read_size',
                 '_read_waste'
                );
 
--
  SELECT max(block_size) INTO p_blksize
  FROM df
  WHERE df_key = p_dfkey;
 
--
  IF p_read_bufs IS NULL
  OR p_type IN (KBRSPLBLD_PURGE, KBRSPLBLD_OPTPURGE,
                KBRSPLBLD_SMALLPURGE, KBRSPLBLD_DUPPURGE)
  THEN
--
    IF p_bskey IS NOT NULL THEN
--
--
      SELECT GREATEST(LEAST(MAX(numchunks) + 1,
                            NVL(p_read_bufs, DEF_READ_BUFS)),
                      MIN_READ_BUFS)
        INTO p_read_bufs
        FROM vbdf v, bdf d, plans p
        WHERE v.dbinc_key = d.dbinc_key
          AND v.ckp_scn = d.ckp_scn
          AND v.file# = d.file#
          AND p.type = p_type
          AND v.vb_key = p.vb_key
          AND v.df_key = p.df_key
          AND d.bs_key = p_bskey;
    ELSE
--
      SELECT GREATEST(LEAST(MAX(numchunks) + 1,
                            NVL(p_read_bufs, DEF_READ_BUFS)),
                      MIN_READ_BUFS)
        INTO p_read_bufs
        FROM plans
        WHERE type = p_type
          AND vb_key = p_vbkey
          AND df_key = p_dfkey;
    END IF;
  END IF;
 
--
  IF p_read_bufs IS NULL THEN
    SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(
                                  DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM,
                                  'Maxfiles bad for bskey ' || p_bskey ||
                                  ', dfkey ' || p_dfkey ||
                                  ', vbkey ' || p_vbkey);
  END IF;
END prep_read;
 
--
--
--
--
--
--
--
PROCEDURE dealloc_plan_bp(p_bskey NUMBER)
  IS
  l_count  NUMBER;
  l_rnk    NUMBER;
  l_dflst  NOLST;
  l_vblst  NOLST;
  l_lvlst  NOLST;
  l_type   NUMBER;
BEGIN
  deb('dealloc_plan_bp bskey ' || p_bskey, AM_DEBUG_MED);
 
--
  SELECT COUNT(*) INTO l_count
    FROM sbt_task
    WHERE bs_key = p_bskey
      AND task_id <> dbms_ra_scheduler.s_current_task
      AND ROWNUM = 1;
  IF l_count > 0 THEN
    deb('dealloc_plan_bp in use, bskey ' || p_bskey, AM_DEBUG_MED);
    RETURN;
  END IF;
 
--
--
--
  SELECT df_key, vb_key, incrLevel(create_scn, incr_scn) lvl
         BULK COLLECT
    INTO l_dflst, l_vblst, l_lvlst
    FROM bp JOIN bdf USING (bs_key)
            JOIN df  USING (dbinc_key, create_scn, file#)
    WHERE bs_key = p_bskey
      AND vb_key IS NOT NULL;
 
--
  IF l_dflst.COUNT = 0 THEN
    deb('dealloc_plan_bp not a vb, bskey ' || p_bskey, AM_DEBUG_MED);
    RETURN;
  END IF;
 
--
  IF l_dflst.COUNT > 1 OR l_lvlst(1) > 0 THEN
    l_type := KBRSPLBLD_ORIGPIECE;
  ELSE
    l_type := KBRSPLBLD_PIECE;
 
--
    SELECT rnk INTO l_rnk
      FROM (SELECT vb_key, DENSE_RANK() OVER (ORDER BY vb_key DESC) rnk
            FROM vbdf
            WHERE df_key = l_dflst(1))
      WHERE vb_key = l_vblst(1);
    IF l_rnk <= dbms_ra_scheduler.s_plans_maintained THEN
      RETURN;
    END IF;
  END IF;
 
--
  FOR i IN 1 .. l_dflst.COUNT LOOP
    dealloc_plan(l_dflst(i), l_vblst(i), l_type);
  END LOOP;
END dealloc_plan_bp;
 
--
--
--
--
--
--
--
--
--
--
PROCEDURE obsoletePlans(p_dfkey       IN NUMBER,
                        p_chk_krbph   IN NUMBER DEFAULT 1,
                        p_lock        IN NUMBER DEFAULT 1)
  IS
  l_vbkey  NUMBER;
  l_count  NUMBER;
  l_vblst  NOLST;
  l_typlst NOLST;
BEGIN
--
--
--
--
--
 
--
  IF (p_lock = TRUE#) THEN
    dbms_ra_int.write_lock(dbms_ra_int.KEY_DF, p_dfkey);
  END IF;
 
  deb('obsoletePlans: for dfkey ' || p_dfkey);
  dbms_ra_int.info_start('obsoletePlans', 'dfkey ' || p_dfkey);
 
--
--
  SELECT vb_key, type BULK COLLECT
    INTO l_vblst, l_typlst
    FROM plans
    WHERE df_key = p_dfkey
      AND type != KBRSPLBLD_PURGE;
 
  FOR i IN 1 .. l_vblst.COUNT LOOP
    dealloc_plan(p_dfkey, l_vblst(i), l_typlst(i), FALSE);
  END LOOP;
  deb('obsoletePlans: for dfkey ' || p_dfkey ||
      ' at - ' || TO_CHAR(SYSTIMESTAMP, 'HH:MI:SS.FF3'), AM_DEBUG_MED);
 
--
  IF (p_lock = TRUE#) THEN
    dbms_ra_int.unlock(dbms_ra_int.KEY_DF, p_dfkey);
  END IF;
 
--
  IF p_chk_krbph = TRUE# THEN
    FOR p IN (SELECT df_key, new_krbph
              FROM vbdf
              WHERE krbph_dfkey = p_dfkey
                AND new_krbph IS NOT NULL) LOOP
--
      IF (p_lock = TRUE#) THEN
        dbms_ra_int.write_lock(dbms_ra_int.KEY_DF, p.df_key);
      END IF;
 
--
      UPDATE vbdf
        SET krbph_chunkno = p.new_krbph, new_krbph = NULL
        WHERE df_key = p.df_key
          AND krbph_dfkey = p_dfkey
          AND new_krbph = p.new_krbph
        RETURNING vb_key INTO l_vbkey;
 
--
--
      IF l_vbkey IS NOT NULL THEN
        dealloc_plan(p.df_key, l_vbkey, KBRSPLBLD_ORIGPIECE, FALSE);
        dealloc_plan(p.df_key, l_vbkey, KBRSPLBLD_PIECE, FALSE);
        deb('obsoletePlans: dfkey ' || p.df_key ||
            ', vbkey ' || l_vbkey, AM_DEBUG_MED);
      END IF;
 
--
      IF (p_lock = TRUE#) THEN
        dbms_ra_int.unlock(dbms_ra_int.KEY_DF, p.df_key);
      END IF;
    END LOOP;
 
    IF s_safemode THEN
      SELECT COUNT(*) INTO l_count FROM vbdf
        WHERE vb_key = l_vbkey AND new_krbph IS NOT NULL;
      IF l_count > 0 THEN
        deb('obsoletePlans: not all krbph_chunkno were fixed up for vbkey ' ||
            l_vbkey);
        SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(
                DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM, 'missed krbph_chunkno');
      END IF;
    END IF;
  END IF;
 
  dbms_ra_int.info_end;
END obsoletePlans;
 
--
--
--
--
--
--
--
PROCEDURE build_read_plan(p_dbkey IN NUMBER,     -- Database key
                          p_vbkey IN NUMBER,     -- Virtual backup key
                          p_dfkey IN NUMBER,     -- Datafile key
                          p_bufsize IN NUMBER,   -- size of read buffers
                          p_type IN NUMBER,      -- KBRSPLBLD_ type
                          p_chunks IN NUMBER,    -- Number of chunks to write.
                          p_stored OUT NUMBER)   -- Is 1 if plan was stored
 IS
  l_blksize    NUMBER;
  l_vfound     NUMBER;  -- Virtual backup found
  l_qtype      NUMBER;  -- query type to execute
  l_dfbytes    NUMBER;  -- size of db in bytes
  l_dfblocks   NUMBER;  -- number of blocks in DF
  l_chunks     NUMBER;  -- number of distinct chunks in plan
  l_signature  NUMBER;  -- numeric signature for this restore
  l_maxrank    NUMBER;  -- block ranking used in purges
  l_needs      NUMBER;  -- chunks that are needed
  l_frees      NUMBER;  -- chunks that will be freed in a purge
  l_fno        NUMBER;  -- file# for error reporting
  l_dbname     node.db_unique_name%TYPE; -- db_unique_name for error reporting
BEGIN
--
  IF p_type = KBRSPLBLD_PURGE
  OR p_type = KBRSPLBLD_OPTPURGE
  OR p_type = KBRSPLBLD_SMALLPURGE
  OR p_type = KBRSPLBLD_ALLPURGE
  OR p_type = KBRSPLBLD_DUPPURGE
  THEN
    l_qtype := KBRSPLBLD_PURGE;
  ELSE
    l_qtype := p_type;
  END IF;
 
--
--
  p_stored := NULL;
  BEGIN
    alloc_plan(p_dbkey, p_dfkey, p_vbkey, l_qtype);
  EXCEPTION
    WHEN DUP_VAL_ON_INDEX THEN
      save_error;
      deb('build_read_plan plan already exists', AM_DEBUG_LOW);
      clear_error;
      RETURN;  -- Caller checks to see it was built
  END;
 
--
  p_stored := 1;
 
--
--
  SELECT max(block_size) INTO l_blksize
  FROM df
  WHERE df_key = p_dfkey;
 
--
  plan_blocks(p_vbkey, p_dfkey, f_chunksize(p_dbkey), p_bufsize,
              l_blksize, p_type, l_dfbytes, l_dfblocks, l_chunks,
              l_signature, l_maxrank);
 
  deb('build_read_plan built blocks: ' ||
            ' dfkey ' || p_dfkey ||
            ', vbkey ' || p_vbkey||
            ', dfbytes ' || l_dfbytes ||
            ', dfblocks ' || l_dfblocks ||
            ', signature ' || l_signature, AM_DEBUG_MED);
 
--
  IF p_type = KBRSPLBLD_SMALLPURGE
  THEN
    restricted_purge(p_dfkey, l_qtype, p_vbkey, p_dbkey, p_chunks);
  END IF;
 
--
  IF p_type = KBRSPLBLD_OPTIMIZE
  THEN
    optimize_blocks(p_dfkey, p_vbkey, l_qtype, p_stored, l_needs);
    l_frees := 0;
  END IF;
 
--
  IF p_type = KBRSPLBLD_PIECE
  THEN
    SELECT COUNT(*) INTO l_vfound FROM vbdf
    WHERE df_key    = p_dfkey
      AND vb_key    = p_vbkey
      AND dfblocks  = l_dfblocks
      AND signature = l_signature;
 
--
    IF l_vfound = 0
    THEN
      SELECT nvl(dfbytes, 0) INTO l_vfound FROM vbdf
      WHERE df_key    = p_dfkey
        AND vb_key    = p_vbkey;
 
--
      IF l_vfound = 0
      THEN
        UPDATE vbdf    SET dfbytes = l_dfbytes,
                           dfblocks = l_dfblocks,
                           signature = l_signature
        WHERE df_key = p_dfkey
          AND vb_key = p_vbkey;
      ELSE
--
--
--
        SELECT count(*) INTO l_vfound FROM bp
          WHERE vb_key = p_vbkey AND status != 'D';
        IF l_vfound = 0 THEN
          RAISE dbms_ra_scheduler.e_retry_error;
        END IF;
 
--
--
--
        deb('BUILD_READ_PLAN  NEW BAD METADATA:' ||
            ' dfkey ' || p_dfkey ||
            ', vbkey ' || p_vbkey||
            ', dfbytes ' || l_dfbytes ||
            ', dfblocks ' || l_dfblocks ||
            ', signature ' || l_signature, AM_DEBUG_ON);
 
        FOR i IN (SELECT * FROM vbdf
                  WHERE df_key = p_dfkey AND vb_key = p_vbkey) LOOP
          deb('BUILD_READ_PLAN OLD GOOD METADATA:' ||
              ' dfkey ' || p_dfkey ||
              ', vbkey ' || p_vbkey||
              ', dfbytes ' || i.dfbytes ||
              ', dfblocks ' || i.dfblocks ||
              ', signature ' || i.signature, AM_DEBUG_ON);
          deb('BUILD_READ_PLAN with:' ||
              ' incr_scn ' || i.incr_scn ||
              ', ckp_scn ' || i.ckp_scn ||
              ', min_id ' || i.min_id, AM_DEBUG_ON);
        END LOOP;
        raise_bad_metadata(p_dfkey);
      END IF;
    END IF;
  END IF;
 
--
  IF l_qtype = KBRSPLBLD_PURGE
  THEN
    IF l_dfbytes = 0
    THEN
      l_needs := 0;
    ELSE                 /* Add an extra block, to ensure we do not go over */
      l_needs := trunc((l_dfbytes + l_blksize) / f_chunksize(p_dbkey)) + 1;
    END IF;
 
--
    SELECT COUNT(DISTINCT chunkno) INTO l_frees
      FROM plans_details 
      WHERE df_key = p_dfkey
        AND vb_key = p_vbkey
        AND type = l_qtype;
 
    deb('build_read_plan purge type: ' || p_type ||
        ', dfkey ' || p_dfkey ||
        ', vbkey ' || p_vbkey||
        ', needs ' || l_needs ||
        ', frees ' || l_frees, AM_DEBUG_MED);
 
--
    IF  (l_frees = 0
         OR (p_type = KBRSPLBLD_OPTPURGE AND
             l_frees - l_needs < dbms_ra_scheduler.s_purge_opt_free)
         OR (p_type = KBRSPLBLD_PURGE AND l_frees = l_needs))
    AND (s_purge_dbinc IS NULL)      /* we always want to free orphans */
    THEN
      l_needs := 0;
      l_frees := 0;
      p_stored := 0;
      deb('build_read_plan nothing freed', AM_DEBUG_MED);
    ELSE
--
      IF debug = AM_DEBUG_HIGH THEN
        deb('build_read_plan: chunks to delete');
        FOR x IN (SELECT chunkno,
                         MIN(blockno) blockno
                  FROM plans_details
                  WHERE df_key = p_dfkey
                    AND type = p_type
                    AND vb_key = p_vbkey
                    AND blockno >= 0
                  GROUP BY chunkno
                  ORDER BY chunkno)
        LOOP
          deb('delete plan dfkey ' || p_dfkey ||
              ', chunk ' || x.chunkno ||
              ', minbno ' || x.blockno);
        END LOOP;
      END IF;
    END IF;
  END IF;
 
--
  IF p_stored = 0 THEN
    l_dfblocks := NULL;
  END IF;
  UPDATE plans SET blksread = l_dfblocks,
                   numchunks = l_chunks,
                   maxrank = l_maxrank,
                   needchunk = l_needs,
                   freechunk = l_frees
    WHERE df_key   = p_dfkey
      AND vb_key   = p_vbkey
      AND type     = l_qtype;
  COMMIT;
 
  dbms_ra_scheduler.check_for_interrupt;
 
EXCEPTION
  WHEN dbms_ra_scheduler.e_no_longer_exists THEN
    save_error;
 
--
    IF dbms_ra_scheduler.s_current_task_type = dbms_ra_scheduler.TASK_RESTORE
    THEN
      RAISE;
    ELSE
      RAISE dbms_ra_scheduler.e_retry_error; -- Convert to retry error
    END IF;
END build_read_plan;
 
--
--
--
--
--
--
--
--
--
PROCEDURE ok4pool(p_dbkey    IN  NUMBER,
                  p_bpkey    IN  NUMBER,
                  p_update   IN  BOOLEAN,
                  p_hasdups  OUT BOOLEAN,
                  p_nofityet OUT BOOLEAN,
                  p_isok     OUT BOOLEAN)
 IS
  l_bskey         NUMBER;
  l_currinc       NUMBER;
  l_isnew         NUMBER;
  l_isold         NUMBER;
  l_anynew        NUMBER;
  l_dups          NUMBER;
  l_keep          NUMBER;
  l_isincr        NUMBER;
  l_hasdups       NUMBER;
  l_count         NUMBER;
  l_piececnt      NUMBER;
  l_encrypt       NUMBER;
  l_msection      NUMBER;
  l_pieces        NUMBER;
  l_bdfkey        NUMBER;
  l_incrscn       NUMBER := BIGNUM;
  l_pieceno       NUMBER := 1;
  l_pause         NUMBER;
BEGIN
--
  p_hasdups := FALSE;
  p_nofityet := FALSE;
  p_isok := FALSE;
 
--
  IF f_pooloff THEN
    RETURN;
  END IF;
 
--
  SELECT DECODE(encrypted, 'Y', 1, 0), bs_key
    INTO l_encrypt, l_bskey
    FROM bp WHERE bp_key = p_bpkey;
  IF l_encrypt > 0 THEN
    deb('OK4POOL: bpkey ' || p_bpkey || ', rejected encrypted backup.',
        AM_DEBUG_LOW);
    RETURN;
  END IF;
 
--
--
--
--
--
--
  BEGIN
    SELECT keep_options, DECODE(multi_section, 'Y', 1, 0), pieces
      INTO l_keep, l_msection, l_pieces
      FROM bs WHERE bs_key = l_bskey;
 
    SELECT COUNT(*) INTO l_count
      FROM bdf
      WHERE bs_key = l_bskey
        AND (incr_level IS NOT NULL OR incr_scn > 0);
    IF l_count > 0 THEN
      l_isincr := 1;
    ELSE
      l_isincr := 0;
    END IF;
  EXCEPTION
    WHEN no_data_found THEN
      save_error;
      l_isincr := 0;
      deb('OK4POOL: bpkey ' || p_bpkey || ', missing.', AM_DEBUG_LOW);
      clear_error;
    WHEN OTHERS THEN
      save_error;
      RAISE;
  END;
 
  deb('OK4POOL: bpkey ' || p_bpkey ||
      ', incr ' || l_isincr ||
      ', keep ' || l_keep ||
      ', pieces ' || l_pieces ||
      ', msection ' || l_msection, AM_DEBUG_LOW);
 
--
--
  IF l_isincr = 0 OR l_keep > 0 OR (l_msection = 0 AND l_pieces > 1) THEN
    RETURN;
  END IF;
 
--
--
  SELECT COUNT(*) INTO l_count
    FROM bdf b
    WHERE bs_key = l_bskey
      AND NOT EXISTS (SELECT 1 FROM df
                      WHERE df.dbinc_key = b.dbinc_key AND df.file# = b.file#);
  IF (l_count > 0)
  THEN
--
--
    SELECT COUNT(*) INTO l_count
      FROM bdf b, dbinc i
      WHERE b.bs_key = l_bskey
        AND b.dbinc_key = i.dbinc_key
        AND i.dbinc_status = 'ORPHAN'
        AND i.parent_dbinc_key IS NULL
        AND NOT EXISTS (SELECT 1 FROM dbinc i2
                        WHERE i2.parent_dbinc_key = i.dbinc_key);
    IF (l_count > 0)
    THEN
    deb('OK4POOL: bpkey ' || p_bpkey || ', foreign datafile', AM_DEBUG_MED);
      RETURN;
    END IF;
 
--
--
    SELECT COUNT(*) INTO l_count
      FROM df
      WHERE dbinc_key IN (SELECT dbinc_key FROM bdf WHERE bs_key = l_bskey);
    IF (l_count > 0) THEN
--
      deb('OK4POOL: bpkey ' || p_bpkey || ', no datafile yet, ' ||
          'temporarily rejected', AM_DEBUG_LOW);
      p_nofityet := TRUE;
    ELSE
      deb('OK4POOL: bpkey ' || p_bpkey || ', no datafile is too old, ' ||
          'permantly rejected', AM_DEBUG_LOW);
    END IF;
 
    RETURN;
  END IF;
 
--
  SELECT COUNT(*) INTO l_count
    FROM bdf b
    WHERE bs_key = l_bskey
      AND EXISTS (SELECT 1 FROM vbdf v
                  WHERE v.dbinc_key = b.dbinc_key
                    AND v.file# = b.file#
                    AND v.state NOT IN
                              (VBDF_OBSOLETE, VBDF_COMPLETE, VBDF_REPOPULATE));
  IF (l_count > 0)
  THEN
    deb('OK4POOL: bpkey ' || p_bpkey || ', incomplete prior backup, ' ||
        'temporarily rejected', AM_DEBUG_LOW);
    p_nofityet := TRUE;
    RETURN;
  END IF;
 
--
  SELECT MAX(dbinc_key) INTO l_currinc FROM bdf WHERE bs_key = l_bskey;
 
  IF l_msection = 1 THEN
    SELECT piece# INTO l_pieceno FROM bp WHERE bp_key = p_bpkey;
 
--
--
--
--
--
--
    IF l_pieceno > 1 THEN
      SELECT COUNT(DISTINCT piece#) INTO l_count
        FROM bdf JOIN bp USING (bs_key)
        WHERE (dbinc_key, file#, create_scn, ckp_scn) IN
              (SELECT dbinc_key, file#, create_scn, ckp_scn
               FROM bdf
               WHERE bs_key = l_bskey)
          AND vb_key IS NOT NULL
          AND ba_access = 'L'
          AND (piece# = l_pieceno OR piece# = l_pieceno - 1);
 
--
--
--
--
--
--
      deb('OK4POOL: bpkey ' || p_bpkey || ', l_count, ' ||
          l_count , AM_DEBUG_LOW);
      
      IF l_count = 0 THEN
        deb('OK4POOL: bpkey ' || p_bpkey || ', wrong section, ' ||
            'temporarily rejected', AM_DEBUG_LOW);
        p_nofityet := TRUE;
        RETURN;
      ELSIF l_count = 2 THEN
        deb('OK4POOL: bpkey ' || p_bpkey || ', wrong section, ' ||
            'permanently rejected', AM_DEBUG_LOW);
        RETURN;
      END IF;
 
    ELSE  -- Check prior backup, assumes single datafile.
      BEGIN      
        SELECT piece#, pieces INTO l_pieceno, l_piececnt
          FROM (SELECT ckp_scn, piece#, pieces
                FROM bdf
                JOIN bp USING (bs_key)
                JOIN bs USING (bs_key)
                JOIN (SELECT db_key, dbinc_key, reset_scn, reset_time, db_name,
                             NVL(PRIOR reset_scn, BIGNUM) next_reset_scn
                      FROM dbinc
                      START WITH dbinc_key = l_currinc
                      CONNECT BY PRIOR parent_dbinc_key = dbinc_key) i
                  USING (dbinc_key)
                WHERE bp.ba_access = 'L'
                  AND bp.vb_key IS NOT NULL
                  AND bdf.ckp_scn >= i.reset_scn
                  AND bdf.ckp_scn <  i.next_reset_scn
                  ORDER BY ckp_scn DESC, piece# DESC) f
              WHERE ROWNUM = 1;
      EXCEPTION
        WHEN no_data_found THEN
          save_error;
          l_pieceno  := 1;  
          l_piececnt := 1;
          clear_error;
      END;
    
      IF l_pieceno != l_piececnt THEN
        deb('OK4POOL: bpkey ' || p_bpkey || ', missing section, ' ||
            'temporarily rejected', AM_DEBUG_LOW);
        p_nofityet := TRUE;
        RETURN;
      END IF;
 
      l_pieceno  := 1;  
    END IF; -- l_pieceno == 1
  END IF;   -- l_msection == 1
 
  deb('OK4POOL: bpkey ' || p_bpkey || ', l_pieceno, ' ||
      l_pieceno, AM_DEBUG_LOW);
 
  IF l_pieceno = 1 THEN 
--
--
--
--
    SELECT /* looking for too new */
           /* isnew: 0 - exact fit, < 0 fits with dups, > 0 - too new,  */
           MAX(incr_scn - nvl(pckpscn,
                              /* If no prior backup the following computes: */
                              /* incr_scn for level 0 */
                              /* -ckp_scn for level 1 */
                              incr_scn + (-1 * (incr_scn + ckp_scn) * 
                 dbms_ra_pool.incrLevel(create_scn, incr_scn)))) isnew,
           /* looking for too old */
           /* isold: 0 - old, < 0 - ok new, > 0 too old */
           NVL(MAX(pckpscn - ckp_scn), -1) isold,
           /* looking for any new */
           /* anynew: > 0 some new, no new when <= 0 and isold == 0 */
           NVL(MAX(ckp_scn - pckpscn), 1) anynew,
           /* looking for duplicate blocks */
           /* dups: > 0 dups, <= 0 no dups */
           MAX(NVL(pckpscn, incr_scn) - incr_scn) dups
      INTO l_isnew, l_isold, l_anynew, l_dups
      FROM bdf b 
      LEFT OUTER JOIN
           (SELECT file#,
                   MAX(ckp_scn) pckpscn,
                   MAX(create_scn) create_scn
            FROM bdf
            JOIN bp USING (bs_key)
            JOIN (SELECT db_key, dbinc_key, reset_scn, reset_time, db_name,
                         NVL(PRIOR reset_scn, BIGNUM) next_reset_scn
                  FROM dbinc
                  START WITH dbinc_key = l_currinc
                  CONNECT BY PRIOR parent_dbinc_key = dbinc_key) i
            USING (dbinc_key)
            WHERE bp.ba_access = 'L'
              AND bp.vb_key IS NOT NULL
              AND bp.status != 'D'
              AND bdf.ckp_scn >= i.reset_scn
              AND bdf.ckp_scn <  i.next_reset_scn
            GROUP BY file#) f
        USING (file#, create_scn)
      WHERE b.bs_key = l_bskey;
 
    deb('OK4POOL: bpkey ' || p_bpkey ||
        ', isnew ' || sign(l_isnew) ||
        ', isold ' || sign(l_isold) ||
        ', anynew ' || sign(l_anynew) ||
        ', dups ' || sign(l_dups), AM_DEBUG_MED);
 
--
    IF l_isnew > 0 THEN
      deb('OK4POOL: bpkey ' || p_bpkey || ', future backup, ' ||
          'temporarily rejected', AM_DEBUG_LOW);
 
--
--
--
      BEGIN
        SELECT MAX(incr_scn - mckpscn)  /* A positve value means NOT tile */
        INTO l_isnew
        FROM bdf b
        JOIN (SELECT MAX(ckp_scn) mckpscn, file#
              FROM df
              JOIN (SELECT dbinc_key, file#, create_scn, ckp_scn FROM cdf
                    UNION ALL
                    SELECT dbinc_key, file#, create_scn, ckp_scn FROM xdf) f
              USING (dbinc_key, file#, create_scn)
              JOIN (SELECT db_key, dbinc_key, reset_scn, reset_time, db_name,
                           NVL(PRIOR reset_scn, BIGNUM) next_reset_scn
                    FROM dbinc
                    START WITH dbinc_key = l_currinc
                    CONNECT BY PRIOR parent_dbinc_key = dbinc_key) i
              USING (dbinc_key)
              WHERE f.ckp_scn >= i.reset_scn
                AND f.ckp_scn <  i.next_reset_scn
              GROUP BY file#) d
        USING (file#)
        WHERE b.bs_key = l_bskey;
      EXCEPTION
        WHEN OTHERS THEN
          save_error;
          deb('OK4POOL: bpkey ' || p_bpkey ||
              ', datafile copy query failed with ' || SQLERRM,
              AM_DEBUG_ON);
          RAISE;
      END;
      IF l_isnew > 0 OR l_isnew IS NULL THEN
        p_nofityet := TRUE;
      END IF;
      RETURN;
    END IF;
 
--
    IF NOT p_update AND (l_isold > 0 OR (l_isold = 0 AND l_anynew <= 0)) THEN
      deb('OK4POOL: bpkey ' || p_bpkey ||
          ', will not fit in dbkey ' || p_dbkey ||
          ' and is rejected', AM_DEBUG_MED);
      RETURN;  -- A clean return means file will not be processed again.
    END IF;
  END IF; -- for piece 1
 
--
  deb('OK4POOL: bpkey ' || p_bpkey || ', is good for pool.', AM_DEBUG_MED);
  p_hasdups := (l_dups > 0);
  p_isok := TRUE;
END ok4pool;
 
 
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE process_backup_piece(p_dbkey     IN  NUMBER,    -- Database key
                               p_bpkey     IN  NUMBER,    -- BackupPiece key
                               p_upd       IN  NUMBER DEFAULT 0, -- update oper
                               p_complete  OUT BOOLEAN)
 IS
  l_slkey         NUMBER;
  l_toname        VARCHAR2(512);
  l_dbid          NUMBER;
  l_chunkno       NUMBER;
  l_tag           VARCHAR2(31);
  l_count         NUMBER;
  l_bskey         NUMBER;
  l_vbkey         NUMBER := NULL;
  l_outbpkey      NUMBER;
  l_loop          NUMBER;
  l_hasdups       BOOLEAN;
  l_nofit         BOOLEAN;
  l_isok          BOOLEAN;
 
--
--
--
--
--
  CURSOR vfiles(c_vbkey IN NUMBER) IS
      SELECT v.vb_key, v.dbinc_key, v.df_key, v.file#, v.blocks, v.incr_scn,
             v.dfbytes, f.create_scn
        FROM vbdf v, df f
        WHERE v.vb_key = c_vbkey
          AND v.df_key = f.df_key
          AND v.dbinc_key = f.dbinc_key;
BEGIN
  saved_krbph := NULL;
  saved_krbphdf := NULL;
  saved_krbph_name := NULL;
  saved_krbph_spname := NULL;
  saved_krbph_cfname := NULL;
  p_complete := FALSE;
 
--
  dbms_ra_int.s_bp_save.DELETE;
 
  deb('Process_backup_piece - dbkey ' || p_dbkey || ', bpkey - ' || p_bpkey,
      AM_DEBUG_LOW);
 
--
  IF NOT dbms_ra_int.read_lock(dbms_ra_int.KEY_BP, p_bpkey) THEN
--
--
    deb('Process_backup_piece - bpkey ' || p_bpkey || ' no longer exists.',
        AM_DEBUG_LOW);
 
--
    l_vbkey := dbms_ra_scheduler.get_savepoint;
    IF l_vbkey > 0 THEN
      cleanup(l_vbkey);
    END IF;
 
    RETURN;
  END IF;
 
--
  SELECT bp.bs_key INTO l_bskey
    FROM bp, bs
    WHERE bp.bs_key = bs.bs_key
      AND bp.bp_key = p_bpkey
      AND bp.status != 'D'
      AND bp.ba_access != 'U';
 
--
--
--
  dbms_ra_scheduler.avoid_bs(p_dbkey, l_bskey, p_bpkey);
 
--
  IF p_upd = 0 THEN
     saved_vbkey := 0;
  ELSE
--
    SELECT MIN(vb_key) INTO saved_vbkey
      FROM vbdf v, bdf d
      WHERE v.dbinc_key = d.dbinc_key
        AND v.file# = d.file#
        AND v.ckp_scn = d.ckp_scn
        AND d.bs_key = l_bskey;
 
--
--
--
     UPDATE vbdf v
         SET   state  = VBDF_REPOPULATE
         WHERE vb_key = saved_vbkey
           AND EXISTS (SELECT 1 FROM bdf d
                       WHERE d.bs_key = l_bskey
                         AND d.dbinc_key = v.dbinc_key
                         AND d.file# = v.file#
                         AND d.ckp_scn = v.ckp_scn);
     COMMIT; 
  END IF;
 
  deb('Process_backup_piece - dbkey ' || p_dbkey || '   saved_vbkey - ' || 
      saved_vbkey, AM_DEBUG_MED);
 
--
  SELECT sl_cg_name, sl_key INTO l_toname, l_slkey
  FROM sl join odb using(sl_key)
  WHERE db_key = p_dbkey;
 
  deb('Process_backup_piece - dbkey## After storage location ' 
       || p_dbkey || '   saved_vbkey - ' || 
      saved_vbkey, AM_DEBUG_MED);
 
--
  IF p_upd = 0 THEN
--
--
--
--
    SELECT MIN(vb_key) INTO l_vbkey
      FROM vbdf v, bdf d
      WHERE v.dbinc_key = d.dbinc_key
        AND v.file# = d.file#
        AND d.bs_key = l_bskey
        AND state NOT IN (VBDF_COMPLETE, VBDF_OBSOLETE)
        AND DECODE(d.section_size, 0, 1, (v.lastblk/d.section_size)) = 
            (SELECT piece#
               FROM bp 
               WHERE bp_key = p_bpkey);
 
--
    IF l_vbkey IS NOT NULL THEN
      cleanup(l_vbkey);
    END IF;      
 
--
    SELECT MAX(vb_key) INTO l_vbkey
      FROM vbdf
      WHERE srcbp_key = p_bpkey
        AND state IN (VBDF_COMPLETE, VBDF_OBSOLETE);
 
    IF l_vbkey IS NOT NULL THEN
--
      saved_vbkey := l_vbkey;
      SELECT filename, chunkno, c.df_key
        INTO saved_krbph_name, saved_krbph, saved_krbphdf
        FROM vbdf v, chunks c
        WHERE v.vb_key = l_vbkey
          AND v.df_key = v.krbph_dfkey
          AND v.df_key = c.df_key
          AND v.krbph_chunkno = c.chunkno;
 
      deb('Process_backup_piece - piece already processed', AM_DEBUG_LOW);
      GOTO inspect_vb;
    END IF;
 
--
  ELSE
    deb('Process_backup_piece - repopulate: ' || l_bskey, AM_DEBUG_LOW);
    SELECT v.vb_key, c.filename, c.chunkno, c.df_key
      INTO saved_vbkey, saved_krbph_name, saved_krbph, saved_krbphdf
      FROM bdf b, vbdf v, chunks c
      WHERE b.bs_key = l_bskey
        AND b.dbinc_key = v.dbinc_key
        AND b.file# = v.file#
        AND b.ckp_scn = v.ckp_scn
        AND v.krbph_dfkey = v.df_key  /* Ensure only one record returns */
        AND v.krbph_dfkey = c.df_key
        AND v.krbph_chunkno = c.chunkno;
  END IF;
 
  deb('Process_backup_piece - dbkey## After Cleanup Prior ' 
       || p_dbkey || '   saved_vbkey - ' || 
      saved_vbkey, AM_DEBUG_MED);
 
  IF debug >= AM_DEBUG_MED THEN
    SELECT tag INTO l_tag FROM bp WHERE bp_key = p_bpkey;
    deb('PROCESS_BACKUP_PIECE: checking ' || l_tag, AM_DEBUG_MED);
  END IF;
 
--
--
--
  dbms_ra_scheduler.avoid_sl(DBMS_RA_SCHEDULER.TASK_PURGE, l_slkey);
 
--
  ok4pool(p_dbkey, p_bpkey, (p_upd != 0), l_hasdups, l_nofit, l_isok);
  IF NOT l_isok THEN
--
    IF l_nofit THEN
      RAISE dbms_ra_int.incremental_no_fit;
    END IF;
 
    dbms_ra_int.unlock(dbms_ra_int.KEY_BP, p_bpkey);
    RETURN;  -- A clean return means file will not be processed again.
  END IF;
 
--
--
  IF l_hasdups THEN
    deb('Process_backup_piece duplicate blocks for bpkey ' || p_bpkey,
        AM_DEBUG_MED);
    dbms_ra_scheduler.avoid_sl(DBMS_RA_SCHEDULER.TASK_INDEX_BACKUP, l_slkey);
  END IF;
 
--
--
--
  SELECT COUNT(*) INTO l_count
    FROM vbdf v, bdf d
    WHERE v.dbinc_key = d.dbinc_key
      AND v.file# = d.file#
      AND v.ckp_scn = d.ckp_scn
      AND d.bs_key = l_bskey
      AND v.state NOT IN (VBDF_COMPLETE, VBDF_OBSOLETE, VBDF_REPOPULATE);
  IF l_count > 0 THEN
    deb('PROCESS_BACKUP_PIECE: other vbdf in progress');
    RAISE dbms_ra_int.incremental_no_fit;
  END IF;
 
--
  dbms_ra_int.info_start('process_allfiles', 'bpkey ' || p_bpkey);
  process_allfiles (p_dbkey    => p_dbkey,
                    p_bskey    => l_bskey,
                    p_bpkey    => p_bpkey,
                    p_toname   => l_toname,
                    p_hasdups  => l_hasdups,
                    p_update   => (p_upd != 0));
  dbms_ra_int.info_end;
--
 
<<inspect_vb>>
--
--
  FOR fil IN vfiles(saved_vbkey) LOOP
--
--
    SELECT COUNT(*) INTO l_count
      FROM bp
      WHERE vb_key = fil.vb_key                  /* one 1 datafile */
        AND 1 = (SELECT COUNT(*) FROM bdf WHERE bdf.bs_key = bp.bs_key)
        AND EXISTS (SELECT 1 FROM bdf d          /* a level 0 backup */
                    WHERE d.bs_key = bp.bs_key
                      AND d.file# = fil.file#
                      AND d.dbinc_key = fil.dbinc_key
                      AND 0 = incrLevel(d.create_scn, d.incr_scn));
 
--
    IF l_count = 0 THEN
--
      IF 1 = incrLevel(fil.create_scn, fil.incr_scn) THEN
        dbms_ra_int.saveBPdata(fno => fil.file#, blocks_read => fil.blocks);
      END IF;
 
--
      sys.kbrsi_icd.rsInspectBackupPiece(
                              handle        => saved_krbph_name,
                              vbkey         => saved_vbkey,
                              bpsize        => fil.dfbytes,
                              chktype       => DBMS_RA_INT.KBRSCHKTYPE_VIRTUAL,
                              fno           => fil.file#,
                              lib_key       => null, /* local disk file */
                              ct_key        => null,
                              bpkey         => l_outbpkey,
                              template_key  => null);
      deb('Process_backup_piece: Created bpkey ' || l_outbpkey ||
          ', vbkey ' || saved_vbkey, AM_DEBUG_LOW);
    END IF;
  END LOOP;
 
--
  dbms_ra_int.s_bp_save.DELETE;
 
--
  SELECT COUNT(*) INTO l_count FROM vbdf
    WHERE vb_key = saved_vbkey AND state <> VBDF_COMPLETE;
  IF l_count > 0 THEN
    SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(
                    DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM, 'bad_vbdf_state');
  END IF;
 
--
  p_complete := TRUE;
  deb('Process_backup_piece: completed bpkey ' || p_bpkey ||
      '  vbkey ' || saved_vbkey||
      '  tag ' || l_tag, AM_DEBUG_MED);
 
--
  dbms_ra_int.unlock(dbms_ra_int.KEY_BP, p_bpkey);
 
--
  FOR x IN (SELECT df_key FROM vbdf WHERE vb_key = saved_vbkey) LOOP
    trim_plan(x.df_key);
  END LOOP;
 
EXCEPTION
   WHEN OTHERS THEN
     save_error;
--
     ROLLBACK;
     deb('Process_backup_piece: failed bpkey ' || p_bpkey ||
         ', vbkey ' || saved_vbkey||
         ', SQLCODE ' || SQLCODE ||
         ', tag ' || l_tag, AM_DEBUG_ON);
 
--
     dbms_ra_int.s_bp_save.DELETE;
 
--
     IF p_upd > 0 AND saved_vbkey IS NOT NULL THEN
       UPDATE vbdf 
         SET state = VBDF_COMPLETE
         WHERE vb_key = saved_vbkey;
       COMMIT;
     END IF;
 
     IF p_bpkey IS NOT NULL THEN
       dbms_ra_int.unlock(dbms_ra_int.KEY_BP, p_bpkey);
     END IF;
 
--
--
    IF SQLCODE = dbms_ra_scheduler.e_corrupt_num THEN
      deb('Process_backup_piece: VSOR Corrupt piece #####' || saved_krbph_name,
          AM_DEBUG_ON);
      dbms_ra_scheduler.log_error (
                 p_errno     => dbms_ra_scheduler.e_corrupt_block_num,
                 p_component => 'BACKUP',
                 p_severity  => dbms_ra_scheduler.severity_warning,
                 p_db_key    => p_dbkey,
                 p_param_num => p_bpkey);
--
      clear_error;
    ELSE
      RAISE;
    END IF;
END process_backup_piece;
 
 
--
--
--
--
--
--
--
PROCEDURE purgeDB(p_slkey   IN NUMBER,
                  p_dbkey   IN NUMBER,
                  p_inline  IN BOOLEAN DEFAULT FALSE)
 IS
  l_currinc       NUMBER;
  l_resume        NUMBER;
  l_tmp           NUMBER;
BEGIN
  deb('purgeDB - db_key ' || p_dbkey ||
      '  Start: ' || TO_CHAR(SYSDATE, 'HH24:MI:SS'), AM_DEBUG_MED);
 
--
  purgeObsolete(p_slkey, p_dbkey, p_inline);
END purgeDB;
 
 
--
--
--
--
--
--
--
--
--
PROCEDURE validateDB(p_dbkey IN NUMBER)
 IS
  l_bpkey               NUMBER := 0;
  l_bskey               NUMBER;
  l_dfkey               NUMBER := 0;
  l_vbkey               NUMBER := 0;
  l_type                NUMBER;
  l_resume              NUMBER;
  l_count               NUMBER;
  l_level0              BOOLEAN;
  l_isBPfile            BOOLEAN:= FALSE;
  l_slParams            VARCHAR2(1024);
  l_bpexists            NUMBER;
BEGIN
 
--
--
--
--
--
  l_resume := nvl(dbms_ra_scheduler.get_savepoint, 0);
  deb('validateDB resume is ' || l_resume);
  IF l_resume <= 0 THEN
    l_dfkey := abs(l_resume);
    l_level0 := TRUE;
  ELSE
    l_bpkey := nvl(l_resume, 0);
    SELECT min(vb_key) into l_vbkey 
      FROM bp 
      WHERE bp_key = l_bpkey;
    IF l_vbkey IS NULL THEN
      l_isBPfile := TRUE;
    ELSE
      l_isBPfile := FALSE;
    END IF;
    l_level0 := FALSE;
  END IF;
 
--
--
--
  WHILE l_bpkey IS NOT NULL LOOP
--
    IF l_level0 THEN
--
--
      BEGIN
        SELECT df_key, bp_key, vb_key, bs_key
          INTO l_dfkey, l_bpkey, l_vbkey, l_bskey
          FROM (SELECT v.df_key, p.bp_key, v.vb_key, p.bs_key
                  FROM vbdf v, bp p, bdf d
                  WHERE v.vb_key = p.vb_key
                    AND v.df_key > l_dfkey
                    AND v.file# = d.file#
                    AND v.ckp_scn = d.ckp_scn
                    AND p.db_key = p_dbkey
                    AND v.dbinc_key = d.dbinc_key
                    AND d.bs_key = p.bs_key
                    AND v.state = VBDF_COMPLETE
                    AND v.vcbp_key != p.bp_key
                    AND p.status != 'D'
                  ORDER BY df_key, bp_key)
          WHERE ROWNUM = 1;
          l_level0 := TRUE;
          deb('validateDB by df: bpkey ' || l_bpkey ||
              ', dfkey ' || l_dfkey, AM_DEBUG_MED);
      EXCEPTION
        WHEN no_data_found THEN
          save_error;
          l_level0 := FALSE;
          clear_error;
      END;
    END IF;
 
--
    IF NOT l_level0 AND NOT l_isBPfile THEN
      l_dfkey := NULL;
 
--
      BEGIN
        SELECT vb_key, bp_key, bs_key
          INTO l_vbkey, l_bpkey, l_bskey
          FROM (SELECT p.vb_key, p.bp_key, p.bs_key
                FROM bp p, vbdf v
                WHERE p.vb_key = v.vb_key
                  AND p.db_key = v.db_key
                  AND p.bp_key = v.vcbp_key
                  AND p.bp_key > l_bpkey
                  AND p.db_key = p_dbkey
                GROUP BY p.vb_key, p.bp_key, p.bs_key
                ORDER BY vb_key, bp_key)
          WHERE ROWNUM = 1;
        deb('validateDB by vb: bpkey ' || l_bpkey ||
            ', vbkey ' || l_vbkey, AM_DEBUG_MED);
      EXCEPTION
        WHEN no_data_found THEN
          save_error;
          l_bpkey := 0;
          l_isBPfile := TRUE;
          clear_error;
      END;
    END IF;
 
--
    IF l_isBPfile THEN
      BEGIN
        SELECT min(bp_key) INTO l_bpkey
          FROM bp
          WHERE bp_key > l_bpkey
            AND db_key = p_dbkey
            AND status != 'D'
            AND vb_key  IS NULL
            AND lib_key IS NULL
            AND encrypted = 'N' /* cannot validate encrypted backups */
            AND ba_access != 'U';
        l_bskey := NULL; /* do not need this, better null than wrong */
 
        IF l_bpkey IS NOT NULL THEN
          SELECT sl_cg_name INTO l_slParams 
            FROM sl, sbt_catalog
            WHERE sl.sl_key = sbt_catalog.sl_key 
              AND bp_key=l_bpkey;
        END IF;
 
        deb('validateDB by fc: bpkey ' || l_bpkey
            , AM_DEBUG_MED);
      EXCEPTION
        WHEN no_data_found THEN
          save_error; 
          l_bpkey := NULL;
          clear_error;
        WHEN OTHERS THEN 
          save_error;
          RAISE;
      END;
    END IF;
 
--
    IF l_bpkey IS NOT NULL THEN
      deb('validateDB: bpkey ' || l_bpkey, AM_DEBUG_MED);
      BEGIN
        IF l_isBPfile THEN
--
           IF NOT dbms_ra_int.read_lock(dbms_ra_int.KEY_BP, l_bpkey) THEN
              RAISE dbms_ra_scheduler.e_retry_error;
           END IF;
           dbms_ra_int.info_start('validateDB',
                                  'BP dbkey ' || p_dbkey ||
                                  ', bpkey ' || l_bpkey);
           dbms_ra_int.validateBackupPiece(p_dbkey => p_dbkey,
                                           p_bpkey => l_bpkey);
           dbms_ra_int.info_end;
 
           dbms_ra_int.unlock(dbms_ra_int.KEY_BP, l_bpkey);
        ELSE
--
          IF l_level0 THEN
            l_type := KBRSPLBLD_PIECE;
          ELSE
            l_type := KBRSPLBLD_ORIGPIECE;
          END IF;
 
--
--
          dealloc_plan_bp(l_bskey);
 
--
          dbms_ra_int.info_start('validateDB',
                                  'VB dbkey ' || p_dbkey ||
                                  ', bpkey ' || l_bpkey);
          sys.kbrsi_icd.validateTask(bpkey => l_bpkey);
 
--
          dealloc_plan_bp(l_bskey);
 
          dbms_ra_int.info_end;
        END IF;
      EXCEPTION
        WHEN OTHERS THEN
          save_error;
          ROLLBACK;
 
          IF l_isBPfile THEN
            dbms_ra_int.unlock(dbms_ra_int.KEY_BP, l_bpkey);
            l_bpexists := 1;
          ELSE
--
            SELECT COUNT(*) INTO l_bpexists FROM bp
              WHERE bp_key = l_bpkey AND ba_access != 'U' AND status = 'A';
          END IF;
 
--
          IF l_level0 THEN
            dbms_ra_scheduler.check_for_interrupt(l_dfkey * -1);
          ELSE
            dbms_ra_scheduler.check_for_interrupt(l_bpkey);
          END IF;
 
          deb('validateDB failed: bpkey ' || l_bpkey ||
              ', exists ' || l_bpexists ||
              ', err ' || SQLCODE, AM_DEBUG_MED);
 
--
          IF l_bpexists = 0 THEN
            RAISE dbms_ra_scheduler.e_retry_error;
          END IF;
 
--
          IF SQLCODE = dbms_ra_scheduler.e_corrupt_backup_num
          OR SQLCODE = dbms_ra_scheduler.e_backup_io_error_rman_num
          OR SQLCODE = dbms_ra_scheduler.e_error_id_file_num
          OR SQLCODE = dbms_ra_scheduler.e_corrupt_backuppiece_num
          OR SQLCODE = dbms_ra_int.bad_block_metadata_num
          THEN
--
--
--
            dbms_ra_scheduler.log_error (
                 p_errno     => dbms_ra_scheduler.e_bad_validate_num,
                 p_param1    => to_char(l_bpkey),
                 p_component => 'VALIDATE',
                 p_severity  => dbms_ra_scheduler.severity_error,
                 p_db_key    => p_dbkey);
 
--
            clear_error;
          ELSE
            RAISE;
          END IF;
      END;
    END IF;
 
--
    IF l_level0 THEN
      dbms_ra_scheduler.check_for_interrupt(l_dfkey * -1);
    ELSE
      dbms_ra_scheduler.check_for_interrupt(l_bpkey);
    END IF;
 
  END LOOP;
END validateDB;
 
 
--
--
--
--
--
--
FUNCTION plannedSpace (p_slkey      IN NUMBER,  -- Storage location
                       p_enable_dup IN NUMBER)  -- 0 or 1 = check for dups
         RETURN NUMBER IS
  l_planned   NUMBER;
  l_dups      NUMBER := 0;
BEGIN
--
--
--
  SELECT NVL(SUM(chunks_used), 0) INTO l_planned
    FROM vbdf v,
         (SELECT db_key, param_num1 df_key, MAX(param_num2) vb_key
          FROM task
          WHERE sl_key = p_slkey
            AND task_type IN (dbms_ra_scheduler.TASK_PURGE_DF,
                              dbms_ra_scheduler.TASK_PURGE_DF_NOW)
          GROUP BY db_key, param_num1) t
    WHERE v.db_key = t.db_key
      AND v.df_key = t.df_key
      AND v.vb_key <= t.vb_key
      AND v.state = VBDF_COMPLETE;
 
--
--
--
  IF p_enable_dup = 1 THEN
    SELECT NVL(SUM(chunks_used), 0) + l_planned INTO l_planned
      FROM vbdf v, task t
      WHERE t.sl_key = p_slkey
        AND v.db_key = t.db_key
        AND v.vb_key = t.param_num2
        AND v.df_key = t.param_num1
        AND t.state IN (dbms_ra_scheduler.STATE_RUNNING,
                        dbms_ra_scheduler.STATE_EXECUTABLE)
        AND t.task_type = dbms_ra_scheduler.TASK_PURGE_DUP_DF;
  END IF;
 
  deb('plannedSpace - chunks ' || l_planned ||
      ', enabled_dups '|| p_enable_dup, AM_DEBUG_MED);
 
  RETURN l_planned;
END plannedSpace;
 
 
--
--
--
--
--
--
--
FUNCTION plannedDBSpace (p_db_key IN NUMBER) RETURN NUMBER IS
  l_planned   NUMBER;
BEGIN
--
--
--
--
  SELECT NVL(SUM(chunks_used), 0) INTO l_planned
    FROM vbdf v,
         (SELECT db_key, param_num1 df_key, MAX(param_num2) vb_key
          FROM task
          WHERE db_key = p_db_key
            AND task_type IN (dbms_ra_scheduler.TASK_PURGE_DF,
                              dbms_ra_scheduler.TASK_PURGE_DF_NOW)
          GROUP BY db_key, param_num1) t
    WHERE v.db_key = t.db_key
      AND v.df_key = t.df_key
      AND v.vb_key <= t.vb_key
      AND v.state = VBDF_COMPLETE;
 
  deb('plannedDBSpace - ' || l_planned || ' chunks', AM_DEBUG_MED);
 
  RETURN l_planned;
END plannedDBSpace;
 
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
FUNCTION copied_to_tape(p_dbkey IN NUMBER) RETURN NUMBER IS 
--
  CURSOR allDF(c_dbkey IN NUMBER) IS
    SELECT df.* FROM df, dbinc i
      WHERE df.dbinc_key = i.dbinc_key
        AND db_key = c_dbkey
      ORDER BY df_key;
 
  l_tapedvb         NUMBER;
  l_nottapedvb      NUMBER;
  l_sumbp           NUMBER;
  l_sumvb           NUMBER;
  l_sumtmp          NUMBER;
  l_lastdf          NUMBER;
  l_count           NUMBER;
  l_chunksize       NUMBER := f_chunksize(p_dbkey);
BEGIN
  deb('Copied_to_tape: dbkey ' || p_dbkey, AM_DEBUG_MED);
 
--
--
--
  SELECT NVL(SUM(bytes), 0) INTO l_sumbp
    FROM bp
    WHERE lib_key IS NULL
      AND ba_access != 'U'
      AND status != 'D'
      AND db_key = p_dbkey
      AND vb_key IS NULL
      AND bs_key IN
      /* list of backup sets on tape */
      (SELECT bs_key FROM bp WHERE lib_key IS NOT NULL AND status != 'D'
       UNION
       /* Backup sets at or below the highest df/cf backups */
       SELECT  bs_key
       FROM (SELECT d.bs_key, MIN(x.scn - d.ckp_scn) bigger
             FROM (SELECT bs_key, file#, dbinc_key, ckp_scn FROM bdf
                   UNION
                   SELECT bs_key, 0 file#, dbinc_key, ckp_scn FROM bcf) d,
                  /* Highest backup scns in current inc, but not keep */
                  (SELECT a.dbinc_key, a.file#, MAX(a.ckp_scn) scn
                   FROM bp p, bs s,
                       (SELECT bs_key, file#, dbinc_key, ckp_scn FROM bdf
                        UNION
                        SELECT bs_key, 0 file#, dbinc_key, ckp_scn FROM bcf) a,
                       (SELECT db_key, dbinc_key, reset_scn,
                               NVL(PRIOR reset_scn, BIGNUM) next_reset_scn
                        FROM dbinc
                        START WITH dbinc_key = (SELECT curr_dbinc_key FROM db
                                                WHERE db_key = p_dbkey)
                        CONNECT BY PRIOR parent_dbinc_key = dbinc_key) i
                   WHERE a.bs_key = s.bs_key
                     AND a.bs_key = p.bs_key
                     AND a.dbinc_key = i.dbinc_key
                     AND p.status != 'D'
                     AND p.lib_key IS NOT NULL
                     AND s.keep_options = 0
                   GROUP BY a.dbinc_key, a. file#) x
             WHERE d.file# = x.file#
               AND d.dbinc_key = x.dbinc_key
             GROUP BY d.bs_key)
       WHERE bigger >= 0);
 
--
  SELECT COUNT(*) INTO l_count
    FROM bp
    WHERE db_key = p_dbkey
      AND vb_key IS NOT NULL
      AND lib_key IS NULL
      AND bs_key IN (SELECT bs_key FROM bp
                     WHERE db_key = p_dbkey AND lib_key IS NOT NULL)
      AND ROWNUM = 1;
  IF l_count = 0 THEN
    deb('Copied_to_tape: dbkey ' || p_dbkey ||
        ', bp taped ' || l_sumbp/1024/1024 || 'm', AM_DEBUG_MED);
    RETURN l_sumbp;
  END IF;
 
--
--
--
--
--
--
--
  l_sumvb := 0;
  FOR f IN allDF(p_dbkey) LOOP
--
    CONTINUE WHEN f.df_key = l_lastdf;
    l_lastdf := f.df_key;
 
--
--
    SELECT NVL(MAX(v.vb_key), 0) INTO l_tapedvb
      FROM vbdf v
      WHERE v.df_key = f.df_key
        AND v.db_key = p_dbkey
        AND EXISTS
              (SELECT 1 FROM bdf d, bp p
               WHERE p.bs_key = d.bs_key
                 AND p.lib_key IS NOT NULL
                 AND d.dbinc_key = v.dbinc_key
                 AND d.ckp_scn = v.ckp_scn
                 AND d.file# = v.file#);
 
--
    SELECT MIN(vb_key) INTO l_nottapedvb
      FROM vbdf v
      WHERE v.df_key = f.df_key
        AND v.vb_key > l_tapedvb
        AND v.db_key = p_dbkey
        AND v.state = VBDF_COMPLETE
        AND EXISTS
            (SELECT 1 FROM bdf d, bp p
             WHERE p.bs_key = d.bs_key
               AND p.vb_key = v.vb_key
               AND p.status != 'D'
               AND d.dbinc_key = v.dbinc_key
               AND d.ckp_scn = v.ckp_scn
               AND d.file# = v.file#);
 
--
--
 
--
    IF l_nottapedvb IS NULL THEN
      l_nottapedvb := l_tapedvb;
    END IF;
 
--
    CONTINUE WHEN l_nottapedvb = 0;
 
--
    planDF(KBRSPLBLD_PURGE, f.df_key, l_nottapedvb);
    SELECT (freechunk - needchunk) * l_chunksize INTO l_sumtmp
      FROM plans
      WHERE df_key = f.df_key
        AND vb_key = l_nottapedvb
        AND type = KBRSPLBLD_PURGE;
    l_sumvb := l_sumvb + l_sumtmp;
  END LOOP;
 
  deb('Copied_to_tape: dbkey ' || p_dbkey ||
      ', bp taped ' || l_sumbp/1024/1024 || 'm' ||
      ', vb taped ' || l_sumvb/1024/1024 || 'm', AM_DEBUG_MED);
 
  RETURN (l_sumbp + l_sumvb);
EXCEPTION
  WHEN OTHERS THEN
    save_error;
    deb('Copied_to_tape: failed with sqlcode ' || SQLCODE, AM_DEBUG_ON);
    RAISE;
END copied_to_tape;
 
 
--
--
--
--
--
--
PROCEDURE optimizeDF(p_dbkey IN NUMBER,      -- Database key
                     p_dfkey IN NUMBER,      -- Datafile key
                     p_onlylost IN BOOLEAN DEFAULT FALSE)
IS
  l_hivbkey       NUMBER;
  l_lowvbkey      NUMBER;
  l_next_vbkey    NUMBER;
  l_currinc       NUMBER;
  l_resume        NUMBER;
  l_count         NUMBER;
  l_hichunk       NUMBER;
  l_needspace     BOOLEAN;
  l_current_frag  NUMBER;
  l_orphans       BOOLEAN;
  l_moving        NUMBER;
  task_rec        task%ROWTYPE;
  l_slkey         NUMBER;
BEGIN
  deb('optimizeDF: dfkey ' || p_dfkey, AM_DEBUG_MED);
 
--
  dbms_ra_scheduler.check_for_interrupt(0);
 
--
  BEGIN
    SELECT curr_dbinc_key INTO l_currinc FROM db WHERE db_key = p_dbkey;
  EXCEPTION
    WHEN no_data_found THEN  -- Database has been deleted.  Just go away.
      save_error;
      deb('optimizeDF: database is gone', AM_DEBUG_LOW);
      clear_error;
      RETURN;
  END;
 
--
  BEGIN
--
    purge_lock(p_dfkey);
 
--
--
    dbms_ra_int.info_start('optimizeDF chunk cleanse', 'dfkey ' || p_dfkey);
 
    dealloc_plan(p_dfkey, NULL, KBRSPLBLD_PURGE);
    alloc_plan(p_dbkey, p_dfkey, 0, KBRSPLBLD_PURGE);
 
    INSERT INTO plans_details (type, df_key, vb_key,
                               chunkno, blkrank, blockno, coffset)
    (SELECT /*+ QB_NAME(c)
                INDEX(c@c)
                NO_INDEX_FFS(c@c)
                INDEX(b@b)
                NO_INDEX_FFS(b@b)
                UNNEST(@b)
                LEADING(c@c) 
                USE_HASH(b@b)
                OPT_PARAM('optimizer_dynamic_sampling' 0)
                OPT_PARAM('_optimizer_adaptive_cursor_sharing' 'false')
                OPT_PARAM('_optimizer_extended_cursor_sharing_rel' 'none')
                OPT_PARAM('_optimizer_use_feedback' 'false')
             */
             KBRSPLBLD_PURGE, p_dfkey, 0,
             chunkno, 1 blkrank, -10 blockno, 0 coffset
     FROM chunks c 
     WHERE c.df_key = p_dfkey
       AND c.clean_key <= (SELECT MAX(vb_key) FROM vbdf
                           WHERE df_key = p_dfkey
                             AND state = VBDF_COMPLETE)
       AND NOT EXISTS (SELECT /*+ QB_NAME(b) */
                            NULL
                       FROM blocks b
                      WHERE b.df_key = c.df_key
                        AND b.chunkno = c.chunkno));
    l_count := SQL%ROWCOUNT;
    COMMIT;
 
    dbms_ra_int.info_end;
 
    IF l_count > 0 THEN
--
      deb('optimizeDF: Lost chunks for dfkey ' || p_dfkey, AM_DEBUG_ON);
      purge_pool(p_dbkey, KBRSPLBLD_PURGE, KBRSPLBLD_PURGE, p_dfkey, 0);
    END IF;
 
--
    dealloc_plan(p_dfkey, NULL, KBRSPLBLD_PURGE);
 
--
    purge_unlock(p_dfkey);
  EXCEPTION
    WHEN OTHERS THEN
      save_error;
      purge_unlock(p_dfkey);
      RAISE;
  END;
 
--
--
  IF p_onlylost THEN
    RETURN;
  END IF;
 
--
  SELECT MAX(v.vb_key), MIN(v.vb_key)
    INTO l_hivbkey, l_lowvbkey
    FROM vbdf v, bp p, bdf d
    WHERE v.vb_key = p.vb_key
      AND v.db_key = p.db_key
      AND p.bs_key = d.bs_key
      AND v.dbinc_key = d.dbinc_key
      AND v.file# = d.file#
      AND v.ckp_scn = d.ckp_scn
      AND v.df_key = p_dfkey
      AND p.status != 'D';
 
--
  IF l_lowvbkey IS NULL THEN
    deb('optimizeDF: ALL purge', AM_DEBUG_MED);
 
--
    SELECT COUNT(*) INTO l_count
      FROM dual
      WHERE EXISTS (SELECT 1 FROM chunks
                    WHERE df_key = p_dfkey)
        AND NOT EXISTS (SELECT 1 FROM vbdf
                        WHERE df_key = p_dfkey
                          AND state NOT IN (VBDF_COMPLETE, VBDF_OBSOLETE));
 
--
    IF l_count > 0 THEN
--
      SELECT sl_key INTO l_slkey
        FROM odb
        WHERE db_key = p_dbkey;
 
--
      SELECT MAX(vb_key) INTO l_hivbkey FROM vbdf WHERE df_key = p_dfkey;
 
      task_rec := NULL;
      task_rec.task_type   := dbms_ra_scheduler.TASK_PURGE_DF;
      task_rec.param_num3  := KBRSPLBLD_ALLPURGE;
      task_rec.sl_key      := l_slkey;
      task_rec.db_key      := p_dbkey;
      task_rec.flags       := 0;
      task_rec.param_num2  := l_hivbkey;
      task_rec.param_num1  := p_dfkey;
      dbms_ra_scheduler.new_task(task_rec);
    END IF;
 
    dbms_ra_scheduler.check_for_interrupt(0);
    RETURN;
  END IF;
 
--
--
  DELETE FROM vbdf
    WHERE df_key = p_dfkey
      AND state = VBDF_OBSOLETE
      AND vb_key < (SELECT vb_key FROM (SELECT vb_key, ROWNUM pos
                                        FROM vbdf
                                        WHERE df_key = p_dfkey
                                          AND state = VBDF_OBSOLETE
                                        ORDER BY vb_key DESC)
                    WHERE pos = 100)
      AND ckp_scn < (SELECT MAX(ckp_scn) FROM vbdf
                    WHERE df_key = p_dfkey
                      AND ckp_id = min_id /* means level 0 */
                      AND state = VBDF_OBSOLETE);
  deb('optimizeDF: vbdf deleted are ' || SQL%ROWCOUNT, AM_DEBUG_MED);
 
--
  SELECT move_phase INTO l_moving FROM odb WHERE db_key = p_dbkey;
 
--
--
  IF l_moving IS NOT NULL THEN
    deb('optimizeDF: This was a moving clean up', AM_DEBUG_MED);
    RETURN;
  END IF;
 
--
  l_orphans := orphans(p_dbkey, p_dfkey, l_currinc);
 
--
  IF NOT l_orphans AND l_moving IS NULL THEN
    l_current_frag := fragmentation(p_dbkey, p_dfkey, l_hivbkey);
  END IF;
 
--
--
  deb('optimizeDF: Basic purge', AM_DEBUG_MED);
  reorderDF(KBRSPLBLD_PURGE, p_dfkey, l_lowvbkey);
  IF l_orphans THEN
    purge_vbdf(p_dbkey, KBRSPLBLD_PURGE, p_dfkey, l_lowvbkey);
  END IF;
  dbms_ra_scheduler.check_for_interrupt(0);
  dealloc_plan(p_dfkey, NULL, KBRSPLBLD_PURGE);
 
--
--
  IF l_orphans THEN
    deb('optimizeDF: Orphan incarnation prevents defragmentation',
        AM_DEBUG_MED);
    RETURN;
  END IF;
 
--
--
  IF l_current_frag IS NULL THEN
--
    planDF(KBRSPLBLD_PIECE, p_dfkey, l_hivbkey);
 
    l_current_frag := fragmentation(p_dbkey, p_dfkey, l_hivbkey);
 
    dbms_ra_scheduler.check_for_interrupt(0);  -- Time 2 bail?
  END IF;
 
  deb('optimizeDF: df_key ' || p_dfkey ||
      ', current frag ' || l_current_frag ||
      ', _fragmentation ' || dbms_ra_scheduler.s_fragmentation,
      AM_DEBUG_MED);
  IF l_current_frag <= dbms_ra_scheduler.s_fragmentation THEN
    deb('optimizeDF: dfkey ' || p_dfkey || ' not frag.', AM_DEBUG_MED);
    RETURN;
  END IF;
 
--
  BEGIN
    deb('optimizeDF: Optimize prep', AM_DEBUG_MED);
    reorderDF(KBRSPLBLD_OPTIMIZE, p_dfkey, l_hivbkey);
    dbms_ra_scheduler.check_for_interrupt(0);
  EXCEPTION
    WHEN dbms_ra_scheduler.e_retry_reserve THEN 
      save_error;
      l_needspace := TRUE;
      clear_error;
    WHEN OTHERS THEN 
      save_error;
      RAISE;
  END;
 
--
  deb('optimizeDF: submit duplicate purge', AM_DEBUG_MED);
  task_rec := NULL;
  task_rec.task_type   := dbms_ra_scheduler.TASK_PURGE_DUP_DF;
  task_rec.db_key      := p_dbkey;
  task_rec.param_num1  := p_dfkey;
  task_rec.param_num2  := l_hivbkey;
  dbms_ra_scheduler.new_task(task_rec); -- commit and delay
 
--
  IF l_needspace THEN
    RAISE dbms_ra_scheduler.e_retry_reserve;
  END IF;
END optimizeDF;
 
 
--
--
--
--
--
--
PROCEDURE purgeDupDF(p_dfkey    IN NUMBER,   -- Datafile key
                     p_vbkey    IN NUMBER,   -- Virtual backup key
                     p_bpkey    IN NUMBER,   -- (optional) bp_key for locking
                     p_newplans IN BOOLEAN DEFAULT TRUE)  -- Inhibit new plans
IS
  l_count         NUMBER;
  l_dbkey         NUMBER;
BEGIN
  deb('purgeDupDF: dfkey ' || p_dfkey ||
      ', vbkey ' || p_vbkey, AM_DEBUG_MED);
 
--
  IF p_bpkey > 0 THEN
    SELECT COUNT(*) INTO l_count FROM bp
      WHERE bp_key = p_bpkey AND status != 'D';
    IF l_count > 0 THEN
      dbms_ra_int.write_lock(dbms_ra_int.KEY_BP, p_bpkey);
      dbms_ra_int.unlock(dbms_ra_int.KEY_BP, p_bpkey);
    END IF;
  END IF;
 
--
  SELECT COUNT(*), MAX(db_key) INTO l_count, l_dbkey
    FROM bp WHERE vb_key = p_vbkey AND status != 'D';
  IF l_count = 0 THEN
    RETURN;
  END IF;
 
--
  SELECT COUNT(*) INTO l_count FROM dual
    WHERE EXISTS (SELECT 1
                  FROM task
                  WHERE task_type = dbms_ra_scheduler.TASK_PURGE_DUP_DF
                    AND db_key = l_dbkey
                    AND param_num1 = p_dfkey
                    AND param_num2 > p_vbkey);
  IF l_count > 0 THEN
    deb('purgeDupDF: more recent purge_dup for dfkey ' || p_dfkey,
        AM_DEBUG_MED);
    RETURN;
  END IF;
 
  IF orphans(l_dbkey, p_dfkey) THEN
    deb('purgeDupDF: Orphan backups for dfkey ' || p_dfkey ||
        ' prevent deduplication', AM_DEBUG_MED);
    RETURN;
  END IF;
 
--
--
  reorderDF(KBRSPLBLD_DUPPURGE, p_dfkey, p_vbkey);
 
--
  IF p_newplans THEN
    new_plans(l_dbkey, p_dfkey);
  END IF;
END purgeDupDF;
 
 
--
--
--
--
--
--
PROCEDURE moveDF(p_dbkey IN NUMBER,  -- Database key
                 p_dfkey IN NUMBER)  -- Datafile key
IS
  l_slkey         NUMBER;
  l_sldir         sl.sl_cg_name%type;
  l_dbid          NUMBER;
  l_hivbkey       NUMBER;
  l_lowvbkey      NUMBER;
  l_vbkey         NUMBER;
  l_blksize       NUMBER;
  l_issft         NUMBER;
  l_count         NUMBER;
  l_cmpvsn        NUMBER;
  l_domore        BOOLEAN := TRUE;
  l_dbinckey      NUMBER;
  l_gotlock       NUMBER := 0;
BEGIN
  deb('moveDF: dbkey ' || p_dbkey || ', dfkey ' || p_dfkey, AM_DEBUG_MED);
 
--
  SELECT curr_dbinc_key INTO l_dbinckey FROM db WHERE db_key = p_dbkey;
 
--
  IF dbms_ra_scheduler.get_savepoint = 1 THEN
    BEGIN
      SELECT vb_key INTO l_hivbkey
        FROM (SELECT v.vb_key, i.dbinc_key, i.reset_scn
              FROM vbdf v, bp p,
                   (SELECT db_key, dbinc_key, reset_scn,
                           NVL(PRIOR reset_scn, BIGNUM) next_reset_scn
                    FROM dbinc
                    START WITH dbinc_key = l_dbinckey
                    CONNECT BY PRIOR parent_dbinc_key = dbinc_key) i
              WHERE v.vb_key = p.vb_key
                AND v.db_key = p.db_key
                AND v.df_key = p_dfkey
                AND v.state = VBDF_COMPLETE
                AND v.dbinc_key = i.dbinc_key
                AND v.ckp_scn >= i.reset_scn
                AND v.ckp_scn <  i.next_reset_scn
                AND p.status != 'D'
              ORDER BY reset_scn DESC, vb_key DESC)
        WHERE ROWNUM = 1;
    EXCEPTION
      WHEN no_data_found THEN
        save_error;
        deb('moveDF: no vbkey for dfkey ' || p_dfkey, AM_DEBUG_MED);
 
--
        SELECT MAX(vb_key) INTO l_hivbkey
          FROM vbdf WHERE df_key = p_dfkey AND state = VBDF_OBSOLETE;
        clear_error;
    END;
    purgeDupDF(p_dfkey, l_hivbkey, NULL, FALSE);
  ELSE
--
    deb('moveDF: Basic purge', AM_DEBUG_MED);
    SELECT min(p.vb_key) INTO l_lowvbkey
      FROM vbdf v, bp p, bdf d
      WHERE v.vb_key = p.vb_key
        AND v.db_key = p.db_key
        AND p.bs_key = d.bs_key
        AND v.dbinc_key = d.dbinc_key
        AND v.file# = d.file#
        AND v.ckp_scn = d.ckp_scn
        AND v.df_key = p_dfkey
        AND p.status != 'D';
 
    reorderDF(KBRSPLBLD_PURGE, p_dfkey, l_lowvbkey);
    dbms_ra_scheduler.check_for_interrupt(0);
  END IF;
 
--
  purge_lock(p_dfkey);
 
--
  SELECT sl_key INTO l_slkey FROM odb WHERE db_key = p_dbkey;
  SELECT sl_cg_name INTO l_sldir FROM sl WHERE sl_key = l_slkey;
  SELECT db_id INTO l_dbid FROM db WHERE db_key = p_dbkey;
  SELECT block_size, issft INTO l_blksize, l_issft
    FROM df WHERE df_key = p_dfkey AND dbinc_key = l_dbinckey;
  SELECT MAX(cmpvsn) INTO l_cmpvsn
    FROM vbdf WHERE df_key = p_dfkey;
 
--
--
--
  WHILE l_domore AND l_cmpvsn IS NOT NULL LOOP
    l_domore := FALSE;
    FOR c IN (SELECT chunkno, dbinc_key, filesize
              FROM chunks JOIN blocks USING (dbinc_key, df_key, chunkno)
              WHERE sl_key != l_slkey
                AND df_key = p_dfkey
              GROUP BY chunkno, dbinc_key, filesize)
    LOOP
      dbms_ra_scheduler.check_for_interrupt(1);
 
--
      SELECT MAX(vb_key) INTO l_vbkey
        FROM vbdf
        WHERE db_key = p_dbkey
          AND df_key = p_dfkey
          AND krbph_dfkey = p_dfkey
          AND ckp_id = (SELECT ckp_id
                        FROM blocks
                        WHERE df_key = p_dfkey
                          AND blockno = 0
                          AND chunkno = c.chunkno
                        );
      IF l_vbkey IS NOT NULL THEN
        IF NOT dbms_ra_int.read_lock(dbms_ra_int.KEY_VB, l_vbkey)
        THEN
--
          SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(
                                      DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM, 
                                          'moveDF missing vbkey ' || l_vbkey);
        END IF;
      END IF;
 
      sys.kbrsi_icd.rsMovePoolDF(l_dbid, c.dbinc_key, p_dbkey, p_dfkey,
                                 c.chunkno, l_sldir, c.filesize,
                                 l_blksize, l_issft, l_cmpvsn, 0);
 
      IF l_vbkey IS NOT NULL THEN
        dbms_ra_int.unlock(dbms_ra_int.KEY_VB, l_vbkey);
      END IF;
 
      l_domore := TRUE;
    END LOOP;
  END LOOP;
 
--
  purge_unlock(p_dfkey);
 
--
  optimizeDF(p_dbkey, p_dfkey);
 
  dbms_ra_scheduler.check_for_interrupt(0);
 
EXCEPTION
  WHEN OTHERS THEN
    save_error;
    IF l_vbkey IS NOT NULL THEN
      dbms_ra_int.unlock(dbms_ra_int.KEY_VB, l_vbkey);
    END IF;
    purge_unlock(p_dfkey);
    RAISE;
END moveDF;
 
 
--
--
--
--
--
--
--
PROCEDURE purgeDF(p_type  IN NUMBER,      -- Type of purge to perform
                  p_dfkey IN NUMBER,      -- Datafile key
                  p_vbkey IN NUMBER)      -- Oldest available vbkey
 IS
  l_dbkey         NUMBER;
  l_dbinckey      NUMBER;
  l_vbkey         NUMBER;
  l_doreserve     BOOLEAN;
  l_small         BOOLEAN;
  l_savepoint     NUMBER;
  l_allsavepoint  NUMBER := NULL;
  l_count         NUMBER;
BEGIN
  l_savepoint := NVL(dbms_ra_scheduler.get_savepoint, 0);
  deb('purgeDF: type ' || p_type ||
      ', dfkey ' || p_dfkey ||
      ', vbkey ' || p_vbkey ||
      ', savepoint ' || l_savepoint, AM_DEBUG_MED);
 
--
  IF l_savepoint IN (RESTART_PURGE_ALL_RETRY1,
                     RESTART_PURGE_ALL_RETRY2,
                     RESTART_PURGE_ALL_RETRY3)
  THEN
    l_allsavepoint := l_savepoint;
    l_savepoint := 0;
    dbms_ra_scheduler.check_for_interrupt(0);
  END IF;
 
--
  IF l_savepoint > 0 THEN
    BEGIN
      SELECT dbinc_key, db_key INTO l_dbinckey, l_dbkey
        FROM vbdf
        WHERE df_key = p_dfkey AND vb_key = p_vbkey;
    EXCEPTION
      WHEN no_data_found THEN  -- OK, we lost the plan, start fresh
        save_error;
        l_savepoint := 0;
        clear_error;
    END;
  END IF;
 
--
  IF dbms_ra_scheduler.s_current_task_type =
                                     dbms_ra_scheduler.TASK_PURGE_DF_NOW THEN
    l_doreserve := TRUE;
 
--
--
--
    SELECT MIN(v.vb_key) INTO l_vbkey
      FROM vbdf v,
           (SELECT db_key, dbinc_key, reset_scn,
                   NVL(PRIOR reset_scn, BIGNUM) next_reset_scn
            FROM dbinc
            START WITH dbinc_key = l_dbinckey
            CONNECT BY PRIOR parent_dbinc_key = dbinc_key) i
      WHERE v.df_key = p_dfkey
        AND v.ckp_scn >= i.reset_scn
        AND v.ckp_scn <  i.next_reset_scn
        AND v.dbinc_key = i.dbinc_key
        AND v.state != VBDF_OBSOLETE;
  ELSE
    l_doreserve := FALSE;
    l_vbkey := p_vbkey;
  END IF;
 
--
  IF p_type = KBRSPLBLD_ALLPURGE THEN
--
    BEGIN
      SELECT curr_dbinc_key, db.db_key INTO l_dbinckey, l_dbkey
        FROM db
        WHERE db_key IN (SELECT db_key FROM vbdf WHERE df_key = p_dfkey);
    EXCEPTION
      WHEN no_data_found THEN  -- OK, this is gone already.  Go away.
        save_error;
        clear_error;
        RETURN;
    END;
 
--
    SELECT MAX(vb_key) INTO l_vbkey FROM vbdf WHERE df_key = p_dfkey;
    IF p_vbkey != l_vbkey THEN
      RETURN;  -- Another vb has been added, just let purge dup deal.
    END IF;
  END IF;
 
--
  IF NOT l_doreserve AND p_type <> KBRSPLBLD_ALLPURGE THEN
--
    SELECT MAX(v.dbinc_key), MAX(v.db_key) INTO l_dbinckey, l_dbkey
      FROM bp p, bdf d, vbdf v
      WHERE v.vb_key = p_vbkey
        AND v.df_key = p_dfkey
        AND p.vb_key = p_vbkey
        AND p.db_key = v.db_key
        AND p.status != 'D'
        AND p.bs_key = d.bs_key
        AND d.dbinc_key = v.dbinc_key
        AND d.file# = v.file#
        AND d.ckp_scn = v.ckp_scn
        AND v.state != VBDF_OBSOLETE;
--
    IF l_dbkey IS NULL THEN
      RETURN;
    END IF;
  END IF;
 
--
  IF l_savepoint <> RESTART_PURGE_VBDF THEN
--
    IF NOT l_doreserve THEN
      BEGIN
--
        reorderDF(p_type, p_dfkey, p_vbkey);
      EXCEPTION
        WHEN dbms_ra_scheduler.e_retry_reserve THEN
          save_error;
          l_doreserve := TRUE;
          clear_error;
      END;
    END IF;
 
--
    IF l_doreserve THEN
      l_small := TRUE;
      WHILE l_small LOOP
        purgeRes(p_dfkey, l_vbkey, l_savepoint, l_small);
      END LOOP;
    END IF;
  END IF;
 
--
--
--
--
  IF  p_type = KBRSPLBLD_ALLPURGE
  AND l_allsavepoint <= RESTART_PURGE_ALL_RETRY3
  THEN
--
    FOR x IN (SELECT DISTINCT sl_key FROM chunks WHERE df_key = p_dfkey) LOOP
--
      dbms_ra_scheduler.check_for_interrupt(NVL(l_allsavepoint+1,
                                                RESTART_PURGE_ALL_RETRY1));
 
--
      dbms_ra_scheduler.avoid_sl(DBMS_RA_SCHEDULER.TASK_PURGE, x.sl_key);
 
--
--
      dbms_ra_scheduler.avoid_db(l_dbkey);
    END LOOP;
 
--
  END IF;
 
--
--
--
  IF  NVL(dbms_ra_scheduler.get_savepoint, 0) > 0
  OR s_purge_dbinc IS NOT NULL  /* Orphan purge, we always need to do this */
  THEN
--
    dbms_ra_scheduler.check_for_interrupt(RESTART_PURGE_VBDF);
    purge_vbdf(l_dbkey, p_type, p_dfkey, p_vbkey);
    dbms_ra_scheduler.check_for_interrupt(0);     /* All done */
  END IF;
 
--
  new_plans(l_dbkey, p_dfkey);
END purgeDF;
 
 
--
--
--
--
--
--
PROCEDURE planDF(p_type   IN NUMBER,    -- Type of plan to build
                 p_dfkey  IN NUMBER,    -- Datafile key
                 p_vbkey  IN NUMBER,    -- Vbkey associated with the plan
                 p_res    IN NUMBER DEFAULT 0, -- Chunks to reserve
                 p_locked IN BOOLEAN DEFAULT FALSE, -- Key lock already held
                 p_must   IN BOOLEAN DEFAULT FALSE, -- Guaranteed, no retry
                 p_plock  IN BOOLEAN DEFAULT FALSE) -- Purge lock already held
 
 IS
  l_known         NUMBER;
  l_dbkey         NUMBER;
  l_gotlock       BOOLEAN := FALSE;
BEGIN
  deb('planDF: type ' || p_type ||
      ', dfkey ' || p_dfkey ||
      ', vbkey ' || p_vbkey ||
      ', ' || systimestamp, AM_DEBUG_MED);
 
--
  IF (p_type = KBRSPLBLD_ALLPURGE)
  THEN
    SELECT COUNT(*), MAX(db_key) INTO l_known, l_dbkey
      FROM vbdf
      WHERE vb_key = p_vbkey
        AND df_key = p_dfkey;
  ELSE
    SELECT COUNT(*), MAX(p.db_key) INTO l_known, l_dbkey
      FROM bp p, bdf d, vbdf v
      WHERE v.vb_key = p_vbkey
        AND v.df_key = p_dfkey
        AND p.vb_key = p_vbkey
        AND p.db_key = v.db_key
        AND p.status != 'D'
        AND p.bs_key = d.bs_key
        AND d.dbinc_key = v.dbinc_key
        AND d.file# = v.file#
        AND d.ckp_scn = v.ckp_scn
        AND v.state = VBDF_COMPLETE;
  END IF;
 
--
--
--
--
--
  IF  NOT p_must
  AND p_type IN (KBRSPLBLD_PURGE, KBRSPLBLD_SMALLPURGE, KBRSPLBLD_ALLPURGE,
                 KBRSPLBLD_DUPPURGE, KBRSPLBLD_OPTPURGE, KBRSPLBLD_OPTIMIZE)
  THEN
    BEGIN
--
      IF NOT p_plock THEN
        purge_lock(p_dfkey);
      END IF;
 
--
      dealloc_plan(p_dfkey, NULL, KBRSPLBLD_OPTIMIZE);
      dealloc_plan(p_dfkey, NULL, KBRSPLBLD_PURGE);
 
--
      IF NOT p_plock THEN
        purge_unlock(p_dfkey);
      END IF;
 
    EXCEPTION
      WHEN OTHERS THEN
        save_error;
        IF NOT p_plock THEN
          purge_unlock(p_dfkey);
        END IF;
 
        RAISE;
    END;
 
--
--
--
--
--
--
--
  ELSE
    IF NOT p_plock 
    AND dbms_ra_scheduler.s_current_task_type IN
              (dbms_ra_scheduler.TASK_PLAN_DF, dbms_ra_scheduler.TASK_PLAN_SBT)
    THEN
      purge_lock(p_dfkey);
      purge_unlock(p_dfkey);
    END IF;
  END IF;
 
--
  IF l_known = 0
  THEN
    deb('planDF BP not known');
    RETURN;
  END IF;
 
--
  BEGIN
    SELECT 1 INTO l_known
      FROM plans
      WHERE type = decode(p_type, KBRSPLBLD_OPTPURGE, KBRSPLBLD_PURGE,
                                  KBRSPLBLD_ALLPURGE, KBRSPLBLD_PURGE,
                                  KBRSPLBLD_SMALLPURGE, KBRSPLBLD_PURGE,
                                  KBRSPLBLD_DUPPURGE, KBRSPLBLD_PURGE,
                          p_type)
        AND vb_key = p_vbkey
        AND df_key = p_dfkey
        AND blksread IS NOT NULL;
  EXCEPTION
    WHEN no_data_found THEN 
      save_error;
      l_known := 0;
      clear_error;
    WHEN too_many_rows THEN
      save_error;
      l_known := 1;
      clear_error;
  END;
    
--
  IF l_known > 0
  THEN
    deb('planDF plan is already done');
    RETURN;
  END IF;
 
--
--
--
--
  IF NOT p_locked
  THEN
    l_gotlock := dbms_ra_int.read_lock(dbms_ra_int.KEY_DF, p_dfkey);
  END IF;
 
--
  WHILE l_known = 0 LOOP
    BEGIN
      sys.kbrsi_icd.rsPlan(l_dbkey, p_vbkey, p_dfkey, p_type, p_res);
    EXCEPTION
      WHEN dbms_ra_scheduler.e_retry_error THEN
        save_error;
        IF NOT p_must THEN
          RAISE;
        END IF;
        clear_error;
      WHEN OTHERS THEN 
        save_error;
        RAISE;
    END;
 
--
    IF p_must
    THEN
      SELECT COUNT(*) INTO l_known
        FROM plans
        WHERE type = decode(p_type, KBRSPLBLD_OPTPURGE, KBRSPLBLD_PURGE,
                                    KBRSPLBLD_ALLPURGE, KBRSPLBLD_PURGE,
                                    KBRSPLBLD_SMALLPURGE, KBRSPLBLD_PURGE,
                                    KBRSPLBLD_DUPPURGE, KBRSPLBLD_PURGE,
                          p_type)
          AND vb_key = p_vbkey
          AND df_key = p_dfkey
          AND blksread IS NOT NULL;      -- Null means partial plan
 
      IF l_known = 0 THEN dbms_lock.sleep(3); END IF;
    ELSE
      l_known := 1;   -- We do not care if it worked
    END IF;
  END LOOP;
 
--
  IF l_gotlock
  THEN
    dbms_ra_int.unlock(dbms_ra_int.KEY_DF, p_dfkey);
    l_gotlock := FALSE;
  END IF;
  deb('planDF end: type ' || p_type ||
      ', dfkey ' || p_dfkey ||
      ', vbkey ' || p_vbkey ||
      ', ' || systimestamp, AM_DEBUG_MED);
EXCEPTION
  WHEN OTHERS THEN
    save_error;
 
--
--
    IF l_gotlock
    THEN
      deb('planDF exception: unlocking type ' || p_type ||
          ', dfkey ' || p_dfkey);
      dbms_ra_int.unlock(dbms_ra_int.KEY_DF, p_dfkey);
    END IF;
    RAISE;
 
END planDF;
 
 
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE save_krbph(p_dfkey     IN NUMBER,    -- krbph df_key
                     p_chunkno   IN NUMBER,    -- krbph chunk number
                     p_name      IN VARCHAR2,  -- krbph chunk name
                     p_splittype IN NUMBER )   -- splitting for block pool,
--
--
--
--
 IS
BEGIN
  IF p_splittype = KBRS_SAVE_INFO_CFFILE THEN
     saved_krbph_cfname := p_name;
  ELSIF p_splittype = KBRS_SAVE_INFO_SPFILE THEN
     saved_krbph_spname := p_name;
  ELSE
--
     saved_krbphdf := p_dfkey;
     saved_krbph := p_chunkno;
     saved_krbph_name := p_name;
  END IF;
END save_krbph;
 
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE begin_df(p_vbkey     IN OUT NUMBER,  -- Virtual backup ID
                   p_ckpid     IN OUT NUMBER,  -- ckp_scn --> ckp_id
                   p_dbid      IN     NUMBER,  -- Database ID
                   p_fno       IN     NUMBER,  -- Datafile number
                   p_blocks    IN     NUMBER,  -- (opt) Datafile size in blocks
                   p_incrscn   IN     NUMBER,  -- (opt) Incr_scn for backup
                   p_crescn    IN     NUMBER,  -- (opt) Datafile creation scn
                   p_crestamp  IN     NUMBER,  -- (opt) Datafile creation time
                   p_rstscn    IN     NUMBER,  -- (opt) reset scn
                   p_rststamp  IN     NUMBER,  -- (opt) reset stamp
                   p_dfkey     OUT    NUMBER,  -- Datafile key
                   p_dbkey     OUT    NUMBER,  -- Database key
                   p_dbinckey  OUT    NUMBER,  -- Database incarnation key
                   p_unorderid OUT    NUMBER,  -- (opt) max(unorder_id)
                   p_firstblk  IN     NUMBER,  -- First block
                   p_lastblk   IN     NUMBER)  -- Last  block
 IS
  l_known      NUMBER := NULL;
  l_ckpid      NUMBER;
  l_pdbinc_key NUMBER;
  l_ckpscn     NUMBER := p_ckpid;  -- From here p_ckpid should only be updated.
  l_pdbkey     NUMBER;
  l_level      NUMBER;
  l_count      NUMBER;
BEGIN
--
--
--
  IF p_vbkey IS NULL AND saved_vbkey = 0 THEN
    saved_vbkey := rman_seq.nextval;
    p_vbkey := saved_vbkey;
    deb('begin_df: New vbkey ' || saved_vbkey, AM_DEBUG_MED);
    dbms_ra_scheduler.check_for_interrupt(saved_vbkey);
    l_known := 0;
  END IF;
 
--
  IF p_vbkey IS NULL AND saved_vbkey != 0 THEN
    p_vbkey := saved_vbkey;
    deb('begin_df:FIRSTELSE New vbkey ' || saved_vbkey, AM_DEBUG_MED);
  END IF;
 
--
  IF l_known IS NULL THEN
--
    BEGIN
      SELECT 1, db_key, dbinc_key, df_key, ckp_id
        INTO l_known, p_dbkey, p_dbinckey, p_dfkey, l_ckpid
        FROM vbdf
        WHERE vb_key = p_vbkey
          AND file# = p_fno;
 
--
      IF s_purge_dbinc IS NOT NULL
      AND dbms_ra_scheduler.s_current_task_type = 
                                        dbms_ra_scheduler.TASK_PURGE_DF
      THEN
        p_dbinckey := s_purge_dbinc;
      END IF;
    EXCEPTION
      WHEN no_data_found THEN
        save_error;
        l_known := 0; 
        clear_error;
    END;
  END IF;
 
--
  IF l_known = 0 THEN
--
    SELECT db.db_key, df.dbinc_key, df.df_key, df.pdbinc_key
      INTO p_dbkey, p_dbinckey, p_dfkey, l_pdbinc_key
      FROM df, db, dbinc i
      WHERE db_id = p_dbid
        AND db.db_key = i.db_key
        AND i.dbinc_key = df.dbinc_key
        AND i.reset_scn = p_rstscn
        AND i.reset_time = dbms_ra_int.stamp2date(p_rststamp)
        AND df.file# = p_fno
        AND df.create_scn = p_crescn
        AND df.create_time = dbms_ra_int.stamp2date(p_crestamp);
 
--
    IF p_firstblk > 2  
    THEN
      SELECT MAX(ckp_scn) INTO l_ckpscn
        FROM vbdf
        WHERE dbinc_key = p_dbinckey
          AND df_key    = p_dfkey
          AND firstblk  = 2;
 
      deb('begin_df: dfkey ' || p_dfkey ||
          ', vbkey ' || p_vbkey ||
          ', ckpscn ' || l_ckpscn ||
          ', firstblk ' || p_firstblk ,AM_DEBUG_MED);
    END IF;
 
--
    BEGIN
--
      SELECT 1 INTO l_count
        FROM vbdf
        WHERE df_key = p_dfkey
          AND ckp_id = p_ckpid;
 
--
--
--
--
--
      SELECT MIN(ckp_id) + 1 INTO l_ckpid
        FROM vbdf v1
        WHERE df_key = p_dfkey
          AND ckp_id >= p_ckpid
          AND NOT EXISTS (SELECT 1 FROM vbdf v2
                          WHERE v2.df_key = p_dfkey
                            AND v2.ckp_id = v1.ckp_id + 1);
    EXCEPTION
      WHEN no_data_found THEN
        save_error;
        l_ckpid := p_ckpid;
        clear_error;
    END;
  END IF;
 
  deb ('begin_df: known ' ||  l_known || ', dbkey ' || p_dbkey ||
       ', dbinc_key ' || p_dbinckey || ', dfkey ' || p_dfkey ,AM_DEBUG_MED);
 
--
--
  IF l_known = 0
  THEN
    deb('begin_df unknown: dfkey ' || p_dfkey ||
        ', vbkey ' || p_vbkey ||
        ', ckpid ' || l_ckpid, AM_DEBUG_MED);
 
--
--
--
    SELECT p.pdb_key, p.con_id INTO l_pdbkey, l_count
      FROM pdb p, pdbinc i
      WHERE i.pdb_key = p.pdb_key
        AND i.pdbinc_key = l_pdbinc_key;
 
    IF l_count > 1 THEN  /* con_id > 1 */
--
      SELECT MAX(inccnt) INTO l_count
        FROM (SELECT COUNT(*) inccnt FROM pdbinc
              WHERE pdb_key = l_pdbkey
        GROUP BY born_dbinc_key);
 
      IF l_count > 1 THEN /* we have pluggable activity */
--
--
        SELECT pdbinc_key INTO l_pdbinc_key
          FROM (SELECT pdb_key, pdbinc_key
                FROM pdbinc i
                WHERE pdb_key = l_pdbkey
                  AND born_dbinc_key = p_dbinckey
                  AND begin_reset_scn <= l_ckpscn
                ORDER BY begin_reset_scn DESC)
          WHERE ROWNUM = 1;
      ELSE
--
        l_pdbinc_key := 0;
      END IF;
    ELSE
--
      l_pdbinc_key := 0;
    END IF;
 
--
    INSERT INTO vbdf
           (vb_key, df_key, db_key, dbinc_key, pdbinc_key, file#,
            blocks, firstblk, lastblk, incr_scn, ckp_scn, ckp_id,
            state)
      VALUES
           (p_vbkey, p_dfkey, p_dbkey, p_dbinckey, l_pdbinc_key, p_fno,
            p_blocks, p_firstblk, p_lastblk, p_incrscn, l_ckpscn, l_ckpid,
            VBDF_BUILDING);
    COMMIT;
    p_ckpid := l_ckpid;
  END IF;
 
--
  IF p_incrscn IS NOT NULL THEN
    SELECT incrLevel(create_scn, p_incrscn)
      INTO l_level
      FROM df
      WHERE dbinc_key = p_dbinckey
        AND df_key = p_dfkey;
 
    IF l_level = 1 THEN
      SELECT LEAST(NVL(MAX(unorder_id), p_incrscn), p_incrscn)
        INTO p_unorderid
        FROM vbdf
        WHERE df_key = p_dfkey
          AND ckp_id < l_ckpid;
    ELSE
      p_unorderid := 0;
    END IF;
  ELSE
    p_unorderid := KSCNINV;
  END IF;
 
END begin_df;
 
 
--
--
--
--
--
--
PROCEDURE end_df(p_vbkey     IN NUMBER,    -- Virtual backup ID
                 p_dfkey     IN NUMBER,    -- Datafile key
                 p_relfno    IN NUMBER,    -- Backupset relative file number
                 p_ckpscn    IN NUMBER,    -- Checkpoint scn
                 p_absscn    IN NUMBER,    -- Absolute fuzzy scn
                 p_repair    IN BOOLEAN,   -- True if repair in progress
                 p_cmpvsn    IN NUMBER,    -- backup version#
                 p_issft     IN NUMBER,    -- Lowest gap scn in backup
                 p_unorder   IN NUMBER,    -- 1 if unordered block found
                 p_replev    IN NUMBER DEFAULT NULL) -- Repair incr level
 IS
  l_minid    NUMBER;
  l_level    NUMBER;
  l_count    NUMBER;
  l_priorvb  NUMBER;
  l_ckpid    NUMBER;
  l_tmpscn   NUMBER;
  l_dbinckey NUMBER;
  l_incrscn  NUMBER;
  l_lastunord  NUMBER;
  l_fno      NUMBER;
BEGIN
  deb('end_df vbkey ' || p_vbkey ||
      ', dfkey ' || p_dfkey ||
      ', cmpvsn ' || p_cmpvsn ||
      ', issft ' || p_issft, AM_DEBUG_MED);
 
--
  SELECT incrLevel(d.create_scn, v.incr_scn),
         v.ckp_id, v.dbinc_key, v.incr_scn, v.file#
    INTO l_level, l_ckpid, l_dbinckey, l_incrscn, l_fno
    FROM df d, vbdf v
    WHERE v.vb_key = p_vbkey
      AND v.df_key = p_dfkey
      AND v.dbinc_key = d.dbinc_key
      AND d.df_key = p_dfkey;
 
--
  IF p_repair AND p_replev IS NOT NULL THEN
    l_level := p_replev;
  END IF;
      
  deb('end_df ckpscn ' || p_ckpscn ||
      ', incrLevel ' || l_level, AM_DEBUG_MED);
 
--
  IF l_level = 1 THEN
--
--
    SELECT NVL(MAX(v.min_id), 0), MAX(v.vb_key), MAX(unorder_id)
      INTO l_minid, l_priorvb, l_lastunord
      FROM vbdf v,
           (SELECT db_key, dbinc_key, reset_scn,
                   NVL(PRIOR reset_scn, BIGNUM) next_reset_scn
            FROM dbinc
            START WITH dbinc_key = l_dbinckey
            CONNECT BY PRIOR parent_dbinc_key = dbinc_key) i
      WHERE v.df_key = p_dfkey 
        AND v.vb_key < p_vbkey
        AND v.ckp_scn < p_ckpscn    /* Needed for repop or validate */
        AND v.firstblk <= 2         /* Ensure we use piece# 1  */
        AND v.dbinc_key = i.dbinc_key
        AND v.ckp_scn >= i.reset_scn
        AND v.ckp_scn <  i.next_reset_scn;
 
--
--
--
--
    IF NOT p_repair THEN
      SELECT COUNT(*) INTO l_count
        FROM bp JOIN bdf USING (bs_key)
        WHERE vb_key = l_priorvb
          AND file# = l_fno
          AND status != 'D'
          AND ROWNUM = 1;
 
      IF l_count = 0 THEN
        deb('end_df missing prior level 0.  Expected vbkey ' || l_priorvb,
            AM_DEBUG_ON);
        RAISE dbms_ra_scheduler.e_retry_error;
      END IF;
    END IF;
  ELSE
--
--
    l_minid := l_ckpid;
  END IF;
 
--
  IF p_unorder > 0 THEN
    l_lastunord := l_ckpid;
  END IF;
 
--
--
--
--
  UPDATE vbdf    SET min_id = NVL(min_id, l_minid), -- repop
                     cmpvsn = p_cmpvsn,
                     relfno = nvl(relfno, p_relfno), -- repop 
                     krbph_chunkno = saved_krbph,
                     krbph_dfkey = saved_krbphdf,
                     abs_scn = greatest(p_absscn, l_ckpid),
                     unorder_id = l_lastunord,
                     state = VBDF_FIN_NOBP
  WHERE vb_key = p_vbkey
    AND df_key = p_dfkey
    AND (state = VBDF_BUILDING OR state = VBDF_REPOPULATE);
  IF SQL%ROWCOUNT != 1 THEN /* catches VBDF_ABORT */
    RAISE dbms_ra_scheduler.e_retry_reserve;
  END IF;
 
--
  SELECT COUNT(*) INTO l_count FROM df
    WHERE df_key = p_dfkey AND issft IS NULL;
  IF l_count > 0 THEN
    UPDATE df SET issft = p_issft WHERE df_key = p_dfkey;
  END IF;
  COMMIT;
END end_df;
 
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
 
PROCEDURE repair_df(p_vbkey     IN OUT NUMBER,  -- Virtual backup ID
                    p_newvb     IN OUT NUMBER,  -- NULL, 1 begin_df, 0 repair
                    p_dbid      IN     NUMBER,  -- Database ID
                    p_fno       IN     NUMBER,  -- Datafile number
                    p_blocks    IN     NUMBER,  -- Datafile size in blocks
                    p_relfno    IN     NUMBER,  -- Backupset relative fileno
                    p_crescn    IN     NUMBER,  -- Datafile creation scn
                    p_crestamp  IN     NUMBER,  -- Datafile creation time
                    p_rstscn    IN     NUMBER,  -- reset scn
                    p_rststamp  IN     NUMBER,  -- reset stamp
                    p_startscn  IN     NUMBER,  -- Incremental start scn
                    p_ckpscn    IN     NUMBER,  -- Checkpoint scn
                    p_cmpvsn    IN     NUMBER,  -- backup version#
                    p_issft     IN     NUMBER,  -- Single File Tablespace
                    p_firstblk  IN     NUMBER,  -- First Block
                    p_lastblk   IN     NUMBER,  -- Last Block
                    p_replev    IN     NUMBER)  -- incrLevel if invalid incrscn
 IS
  l_dbkey    NUMBER;
  l_dbinckey NUMBER;
  l_dfkey    NUMBER;
  l_vbkey    NUMBER;
  l_state    NUMBER;
  l_tmp      NUMBER;
  l_count    NUMBER;
  l_scn      NUMBER;
  l_ckpid    NUMBER := p_ckpscn;
  l_absscn   NUMBER;
  l_unorder  NUMBER;
  l_gapid    NUMBER;
BEGIN
--
  BEGIN
    SELECT * INTO l_vbkey, l_dfkey, l_state
      FROM (SELECT v.vb_key, v.df_key, v.state
            FROM vbdf v, db d, dbinc i
            WHERE d.db_key = v.db_key
              AND i.db_key = v.db_key
              AND i.reset_scn = p_rstscn
              AND i.reset_time = dbms_ra_int.stamp2date(p_rststamp)
              AND v.ckp_scn = p_ckpscn
              AND v.cmpvsn = p_cmpvsn
              AND d.db_id = p_dbid
              AND v.file# = p_fno
              AND v.state = VBDF_REPAIR
            ORDER BY vb_key)
      WHERE ROWNUM = 1;
  EXCEPTION
    WHEN no_data_found THEN
      save_error;
      l_state := NULL;
      clear_error;
  END;
 
--
  IF p_newvb IS NULL AND l_state IS NOT NULL THEN
    BEGIN
      SELECT 1 INTO l_tmp
        FROM vbdf v, 
             (SELECT db_key, dbinc_key, reset_scn,
                     NVL(PRIOR reset_scn, BIGNUM) next_reset_scn
              FROM dbinc
              START WITH dbinc_key = l_dbinckey
              CONNECT BY PRIOR parent_dbinc_key = dbinc_key) i
        WHERE v.df_key = l_dfkey
          AND v.vb_key > l_vbkey
          AND v.ckp_scn >= i.reset_scn
          AND v.ckp_scn <  i.next_reset_scn
          AND v.dbinc_key = i.dbinc_key
          AND v.ckp_scn < p_ckpscn
          AND ROWNUM = 1;
 
--
      DELETE FROM vbdf WHERE vb_key = l_vbkey;
      deb('repair_df: Out of order vbkeys at vbkey ' || l_vbkey ||
          ', rows deleted: ' || SQL%ROWCOUNT, AM_DEBUG_MED);
      COMMIT;
      l_state := NULL;
    EXCEPTION
      WHEN no_data_found THEN
        save_error;
        clear_error; /* expected result */
    END;
  END IF;
 
--
  IF p_newvb = 0 AND l_state IS NULL THEN
--
--
--
--
    DELETE FROM vbdf
      WHERE df_key IN (SELECT df_key FROM vbdf WHERE vb_key = p_vbkey)
        AND ckp_scn >= p_ckpscn;
    l_count := SQL%ROWCOUNT;
    IF l_count > 0 THEN
      deb('repair_df: Must restart all, vbdf rows deleted: ' || l_count,
          AM_DEBUG_MED);
      COMMIT;
      RAISE dbms_ra_scheduler.e_retry_error;
    END IF;
    COMMIT;
 
    saved_vbkey := 0; /* Do not want begin_df to reuse this */
    p_newvb := NULL;  /* Tells caller to restart this piece */
    deb('repair_df: Must restart piece', AM_DEBUG_MED);
    RETURN;
  END IF;
 
--
  IF p_newvb = 1 AND l_state IS NOT NULL THEN
--
--
--
--
    DELETE FROM vbdf
      WHERE df_key = l_dfkey
        AND ckp_scn >= p_ckpscn;
    deb('repair_df: Old piece rows deleted: ' || SQL%ROWCOUNT,
        AM_DEBUG_MED);
 
    l_state := NULL;  /* Records are gone, continue to build new ones. */
  END IF;
 
--
  IF l_state IS NOT NULL THEN
    saved_vbkey := l_vbkey;
    p_vbkey := l_vbkey;
    p_newvb := 0;
 
--
--
    IF l_state IN (VBDF_REPAIR, VBDF_FIN_NOBP) THEN 
      UPDATE vbdf
        SET state = VBDF_FIN_NOBP,
            krbph_chunkno = saved_krbph,
            krbph_dfkey = saved_krbphdf,
            incr_scn = p_startscn /* incr_scn may now be invalid */
        WHERE df_key = l_dfkey
          AND vb_key = l_vbkey
          AND incr_scn >= p_startscn; /* cannot go from invalid to valid */
      COMMIT;
    ELSE
--
--
      deb('repair_df: bad state ' || l_state ||
          ', dfkey ' || l_dfkey ||
          ', vbkey ' || l_vbkey, AM_DEBUG_ON);
    END IF;
 
    deb('repair_df: done - vbkey ' || l_vbkey ||
        ', dfkey ' || l_dfkey, AM_DEBUG_MED);
 
--
  ELSE
    p_newvb := 1;
    begin_df(p_vbkey, l_ckpid, p_dbid, p_fno, p_blocks, p_startscn,
             p_crescn, p_crestamp,
             p_rstscn, p_rststamp,
             l_dfkey, l_dbkey, l_dbinckey, l_gapid,
             p_firstblk, p_lastblk);
 
--
--
--
    SELECT MAX(scn),
           SUM(CASE WHEN scn = ckp_id AND blockno > 1 THEN 1 ELSE 0 END)
      INTO l_absscn, l_unorder
      FROM blocks WHERE df_key = l_dfkey AND ckp_id = l_ckpid;
 
    end_df(p_vbkey, l_dfkey, p_relfno, p_ckpscn, l_absscn,
           TRUE, p_cmpvsn, p_issft, sign(l_unorder), p_replev);
 
--
    SELECT MAX(scn), MAX(ckp_id) INTO l_scn, l_ckpid
      FROM blocks
      WHERE df_key = saved_krbphdf
        AND blockno = 0
        AND ckp_id = l_ckpid;
    IF l_scn IS NOT NULL AND l_scn <> l_ckpid THEN
      UPDATE blocks SET scn = ckp_id
      WHERE df_key = saved_krbphdf
        AND blockno = 0
        AND ckp_id = l_ckpid;
      COMMIT;
    END IF;
 
    deb('repair_df: new done - dfkey ' || l_dfkey ||
        ', vbkey ' || p_vbkey ||
        ', firstblk ' || p_firstblk ||
        ', lastblk ' || p_lastblk, AM_DEBUG_MED);
  END IF;
END repair_df;
 
 
--
--
--
--
--
PROCEDURE deleteVB(p_slkey   IN NUMBER,
                   p_dbkey   IN NUMBER,
                   p_currinc IN NUMBER,
                   p_bpkey   IN NUMBER,
                   p_noplans IN BOOLEAN,
                   p_notasks IN BOOLEAN)
 IS
--
 CURSOR allFno(c_bpkey number) IS
   SELECT vb_key, df_key, tag
     FROM bp p, bdf b, df d
     WHERE p.bs_key = b.bs_key
       AND b.dbinc_key = d.dbinc_key
       AND b.file# = d.file#
       AND b.create_scn = d.create_scn
       AND p.bp_key = c_bpkey;
 
  l_purgeType     NUMBER;
  l_count         NUMBER;
  l_loopcount     NUMBER;
  task_rec        task%ROWTYPE;
  l_vbkey         NUMBER;
  l_msection      NUMBER;
BEGIN
--
--
--
  SELECT MAX(vb_key), COUNT(*) + SUM(incrLevel(create_scn, incr_scn))
    INTO l_vbkey, l_count 
    FROM bdf JOIN bp USING (bs_key)
    WHERE bp_key = p_bpkey;
 
  IF l_count = 1 THEN
--
    IF NOT dbms_ra_int.write_lock_wait(dbms_ra_int.KEY_VB, l_vbkey) THEN
      RAISE dbms_ra_scheduler.e_retry_error;
    END IF;
 
--
--
--
--
    BEGIN
      FOR k in (SELECT c.filename, c.chunkno, v.file#, d.block_size,
                       f.df_key, sign(v.ckp_id - v.min_id) ilevel
                FROM bp p, bdf d, df f, chunks c, vbdf v
                WHERE d.dbinc_key = f.dbinc_key
                  AND d.file# = f.file#
                  AND d.create_scn = f.create_scn
                  AND c.chunkno IN (v.krbph_chunkno, v.new_krbph)
                  AND c.df_key = v.krbph_dfkey
                  AND p.bs_key = d.bs_key
                  AND v.vb_key = p.vb_key
                  AND v.file# = d.file#
                  AND p.status != 'D'
                  AND p.bp_key = p_bpkey
                ORDER BY chunkno DESC) LOOP
 
        deb('deleteVB: krbpd - file# ' || k.file# ||
            ', dfkey ' || k.df_key ||
            ', chunk ' || k.chunkno ||
            ', bpkey ' || p_bpkey, AM_DEBUG_MED);
        sys.kbrsi_icd.delete_krbpd(p_dbkey, k.file#, k.filename,
                                   k.ilevel, k.block_size);
        EXIT;
      END LOOP;
 
    EXCEPTION
      WHEN OTHERS THEN
        save_error;
        dbms_ra_int.unlock(dbms_ra_int.KEY_VB, l_vbkey);
        RAISE;
    END;
        
    dbms_ra_int.unlock(dbms_ra_int.KEY_VB, l_vbkey);
  END IF;
 
--
  FOR fil IN allFno(p_bpkey) LOOP
    deb('deleteVB tag ' || fil.tag, AM_DEBUG_HIGH);
 
    SELECT DECODE(multi_section, 'Y', 1, 0)
      INTO l_msection
      FROM bs WHERE bs_key = (select bs_key from bp where bp_key = p_bpkey);
 
--
--
    IF l_msection = 1 THEN
 
      SELECT COUNT(*) INTO l_count
        FROM bp p, bdf b, vbdf v
      WHERE p.bs_key = b.bs_key
        AND b.dbinc_key = v.dbinc_key
        AND b.file# = v.file#
        AND b.ckp_scn = v.ckp_scn
        AND p.vb_key = v.vb_key
        AND p.db_key = v.db_key
        AND p.status != 'D'
        AND v.df_key = fil.df_key;
        deb('deleteVB bpkey msection ' || p_bpkey ||
            ', dfkey ' || fil.df_key || ', vbkey ' || fil.vb_key ||
            ', del ' || l_count ||
            ', npln ' || print(p_noplans) ||
            ', ntsk ' || print(p_notasks), AM_DEBUG_MED);
        CONTINUE WHEN l_count > 1;
    END IF;
 
--
    SELECT COUNT(*) INTO l_count
      FROM bp p, bdf b, vbdf v
      WHERE p.bs_key = b.bs_key
        AND p.vb_key = v.vb_key
        AND p.db_key = v.db_key
        AND b.dbinc_key = v.dbinc_key
        AND b.file# = v.file#
        AND b.ckp_scn = v.ckp_scn
        AND p.status != 'D'
        AND v.df_key = fil.df_key
        AND v.vb_key <= fil.vb_key;
    deb('deleteVB bpkey ' || p_bpkey ||
        ', dfkey ' || fil.df_key || ', vbkey ' || fil.vb_key ||
        ', del ' || l_count ||
        ', npln ' || print(p_noplans) ||
        ', ntsk ' || print(p_notasks), AM_DEBUG_MED);
    CONTINUE WHEN l_count > 1;
 
--
--
--
--
--
    SELECT COUNT(DISTINCT v.vb_key) INTO l_count
      FROM vbdf v, prot p, odb, bp b
      WHERE b.db_key = odb.db_key
        AND p.prot_key = odb.prot_key
        AND v.vb_key = b.vb_key
        AND v.df_key = fil.df_key
        AND b.status != 'D'
        AND b.bp_key != p_bpkey
        AND b.completion_time > (systimestamp - prot_recovery_window_goal)
        AND (not_taped_state IS NULL OR
             EXISTS (SELECT 1 FROM bp
                     WHERE lib_key IS NOT NULL AND bp.bp_key = b.bp_key));
 
--
 
    IF l_count > 2 THEN
      l_purgeType := KBRSPLBLD_OPTPURGE;
      deb('deleteVB dfkey ' || fil.df_key || ' optimized purge', AM_DEBUG_MED);
    ELSE
--
--
      SELECT count(*) INTO l_count
        FROM vbdf v, bp p, bdf d
        WHERE v.vb_key = p.vb_key
          AND v.db_key = p.db_key
          AND v.df_key = fil.df_key
          AND p.status != 'D'
          AND p.bp_key != p_bpkey
          AND d.bs_key = p.bs_key
          AND d.file# = v.file#
          AND d.ckp_scn = v.ckp_scn
          AND d.dbinc_key = v.dbinc_key;
 
--
--
      IF l_count = 0 THEN
        SELECT COUNT(*) INTO l_count FROM vbdf
          WHERE df_key = fil.df_key
            AND state NOT IN (VBDF_COMPLETE, VBDF_OBSOLETE);
      END IF;
 
      IF l_count > 0 THEN
        l_purgeType := KBRSPLBLD_PURGE;
        deb('deleteVB dfkey ' || fil.df_key || ' purging not optimized',
            AM_DEBUG_LOW);
      ELSE
--
        l_purgeType := KBRSPLBLD_ALLPURGE;
        deb('deleteVB dfkey ' || fil.df_key || ' no longer recoverable',
            AM_DEBUG_LOW);
 
--
        IF DBMS_RA_SCHEDULER.S_PURGING_ACTIVE THEN
          dbms_ra_scheduler.log_error (
                     p_errno     => dbms_ra_scheduler.e_incr_lost_num,
                     p_param1    => dbms_ra_int.dbkey2name(p_dbkey),
                     p_component => 'PURGE',
                     p_severity  => dbms_ra_scheduler.severity_warning,
                     p_db_key    => p_dbkey);
        END IF;
--
      END IF;
    END IF;
 
    IF l_purgeType = KBRSPLBLD_ALLPURGE THEN
--
      SELECT MAX(vb_key) INTO l_vbkey FROM vbdf WHERE df_key = fil.df_key;
    ELSE
--
      SELECT MIN(v.vb_key) INTO l_vbkey
        FROM vbdf v, bp p, bdf d,
             (SELECT db_key, dbinc_key, reset_scn,
                     NVL(PRIOR reset_scn, BIGNUM) next_reset_scn
              FROM dbinc
              START WITH dbinc_key = p_currinc
              CONNECT BY PRIOR parent_dbinc_key = dbinc_key) i
        WHERE p.bp_key != p_bpkey
          AND v.vb_key = p.vb_key
          AND v.db_key = p.db_key
          AND v.df_key = fil.df_key
          AND v.ckp_scn >= i.reset_scn
          AND v.ckp_scn <  i.next_reset_scn
          AND v.dbinc_key = i.dbinc_key
          AND p.bs_key = d.bs_key
          AND v.ckp_scn = d.ckp_scn
          AND v.file# = d.file#
          AND v.dbinc_key = d.dbinc_key
          AND p.status != 'D';
    END IF;
 
--
    SELECT COUNT(DISTINCT dbinc_key) INTO l_count
      FROM vbdf
      WHERE df_key = fil.df_key
        AND vb_key <= l_vbkey
        AND state != VBDF_OBSOLETE;
    IF l_count > 1 THEN
      SELECT COUNT(*) INTO l_count
        FROM vbdf v, bp p, bdf d
        WHERE p.vb_key = v.vb_key
          AND p.db_key = v.db_key
          AND p.bs_key = d.bs_key
          AND v.ckp_scn = d.ckp_scn
          AND v.file# = d.file#
          AND v.dbinc_key = d.dbinc_key
          AND p.status != 'D'
          AND p.bp_key != p_bpkey
          AND v.df_key = fil.df_key
          AND v.vb_key < l_vbkey
          AND state != VBDF_OBSOLETE;
      IF l_count > 0 THEN
        deb('deleteVB: orphans preventing a purge', AM_DEBUG_LOW);
        RETURN;
      END IF;
    END IF;
 
--
    IF p_notasks
    THEN
      purgeDF(l_purgeType, fil.df_key, l_vbkey);
 
--
    ELSE
      task_rec := NULL;
 
--
      IF l_vbkey IS NOT NULL THEN
        task_rec.task_type   := dbms_ra_scheduler.TASK_PURGE_DF;
        task_rec.param_num3  := l_purgeType;
        task_rec.sl_key      := p_slkey;
        task_rec.db_key      := p_dbkey;
        task_rec.flags       := 0;
        task_rec.param_num2  := l_vbkey;
        task_rec.param_num1  := fil.df_key;
        dbms_ra_scheduler.new_task(task_rec);
      END IF;
    END IF;
  END LOOP;
 
EXCEPTION
  WHEN no_data_found THEN
    save_error;
--
    deb('deleteVB no_data_found error bp_key ' || p_bpkey, AM_DEBUG_LOW);
    SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(
            DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM, 'deleteVB no_data_found');
END deleteVB;
 
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE repairChunks(p_dbkey  IN NUMBER)      -- database key
 IS
  l_numvb         NUMBER;
  l_numbadvb      NUMBER;
  l_newvb         NUMBER;
  l_level         NUMBER;
  l_resume_cno    NUMBER;
  l_outbpkey      NUMBER;
  l_size          NUMBER;
  l_currinc       NUMBER;
  l_dfkeylst      NOLST; -- Array of number
  l_lowscnlst     NOLST; -- Array of number
  l_dflock        NUMBER := NULL;
  l_fixfin        BOOLEAN := FALSE;
  l_lastdf        NUMBER := 0;
  l_lastckpid     NUMBER := 0;
BEGIN
  deb('repairChunks: dbkey ' || p_dbkey);
 
--
--
--
  sys.kbrsi_icd.repair_chunks(p_dbkey);
 
--
--
--
--
  BEGIN
    SELECT 1 INTO l_numvb FROM chunks c, dbinc i, df f
      WHERE i.db_key = p_dbkey
        AND f.dbinc_key = i.dbinc_key
        AND c.df_key = f.df_key
        AND c.dbinc_key = i.dbinc_key
        AND c.clean_key = -1
        AND ROWNUM = 1;
    deb('WARNING: Block pool files remain not repaired for database ' ||
        dbms_ra_int.dbkey2name(p_dbkey), AM_DEBUG_ON);
  EXCEPTION
    WHEN no_data_found THEN  /* This is what we expect */
      save_error;
      NULL;
      clear_error;
  END;
 
--
--
--
  DELETE vbdf
    WHERE state NOT IN (VBDF_COMPLETE, VBDF_OBSOLETE, VBDF_REPAIR)
      AND db_key = p_dbkey;
  UPDATE vbdf SET state = VBDF_REPAIR
    WHERE db_key = p_dbkey AND state = VBDF_COMPLETE;
--
  UPDATE vbdf SET incr_scn = KSCNINV
    WHERE db_key = p_dbkey AND state = VBDF_OBSOLETE;
 
--
  UPDATE vbdf
    SET krbph_chunkno = new_krbph, new_krbph = NULL
    WHERE db_key = p_dbkey
      AND new_krbph IS NOT NULL;
  COMMIT;
 
--
--
--
--
--
--
--
  l_fixfin := TRUE;
  FOR chnk IN (SELECT c.chunkno, c.filename, f.block_size, c.df_key, b.ckp_id
               FROM blocks b, chunks c, df f, dbinc i
               WHERE i.db_key = p_dbkey
                 AND f.dbinc_key = i.dbinc_key
                 AND b.dbinc_key = i.dbinc_key
                 AND b.df_key = f.df_key
                 AND c.df_key = f.df_key
                 AND c.chunkno = b.chunkno
                 AND c.dbinc_key = i.dbinc_key
                 AND b.blockno = 0
               ORDER BY i.reset_time, b.ckp_id, b.scn, chunkno desc) LOOP
 
--
    IF l_lastdf <> chnk.df_key OR l_lastckpid <> chnk.ckp_id THEN
      saved_vbkey := 0;               /* begin_df needs this */
      saved_krbphdf := chnk.df_key;   /* end_df needs this */
      saved_krbph := chnk.chunkno;    /* end_df needs this */
      sys.kbrsi_icd.repair_vbdf(chnk.df_key, chnk.chunkno);
    END IF;
 
    l_lastdf := chnk.df_key;
    l_lastckpid := chnk.ckp_id;
  END LOOP;
 
--
--
  IF s_safemode THEN
    deb('repairChunks: debug, make sure relfno assigned ok');
    SELECT MAX(vb_key) INTO l_numvb
      FROM vbdf
      WHERE state NOT IN (VBDF_OBSOLETE, VBDF_REPAIR)
        AND vb_key IN
            (SELECT vb_key
             FROM (SELECT vb_key, MAX(relfno) maxr, COUNT(*) cnt
                   FROM vbdf
                   GROUP BY vb_key)
             WHERE cnt != maxr);
    IF l_numvb IS NOT NULL THEN
      deb('repairChunks: messed up relfno in vbkey ' || l_numvb);
      SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(
                        DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM, 'Bad relfno');
    END IF;
  END IF;
 
--
--
--
  UPDATE vbdf
    SET state = DECODE(incr_scn, KSCNINV, VBDF_OBSOLETE, VBDF_COMPLETE)
    WHERE (vb_key, dbinc_key, file#, ckp_scn) IN
          (SELECT vb_key, dbinc_key, file#, ckp_scn
           FROM bdf b, bp p
           WHERE p.bs_key = b.bs_key
             AND p.vb_key IS NOT NULL
             AND p.status != 'D'
             AND p.db_key = p_dbkey)
      AND state = VBDF_FIN_NOBP
      AND db_key = p_dbkey;
  deb('repairChunks: ' || SQL%ROWCOUNT || ' rows repaired.', AM_DEBUG_LOW);
  COMMIT;
 
--
--
--
--
  UPDATE vbdf SET state = VBDF_OBSOLETE, incr_scn = KSCNINV
    WHERE db_key = p_dbkey AND state = VBDF_REPAIR;
  COMMIT;
 
--
--
--
  FOR p IN (SELECT bp.db_key, handle, sl_key, db_id, curr_dbinc_key, bp_key
            FROM bp, db, odb
            WHERE bp.db_key = db.db_key
              AND bp.db_key = odb.db_key
              AND bp.db_key = p_dbkey
              AND vb_key IS NOT NULL
              AND status != 'D'
              AND (bs_key, vb_key) NOT IN
                  (SELECT d.bs_key, v.vb_key
                   FROM bdf d, vbdf v
                   WHERE d.dbinc_key = v.dbinc_key
                     AND d.ckp_scn = v.ckp_scn
                     AND v.state = VBDF_COMPLETE
                     AND v.incr_scn < KSCNINV
                     AND v.db_key = p_dbkey))
  LOOP
    dbms_ra_storage.free_backup_piece_opt(p_dbkey      => p.db_key,
                                          p_piecename  => p.handle,
                                          p_db_slkey   => p.sl_key,
                                          p_dbid       => p.db_id,
                                          p_currinc    => p.curr_dbinc_key,
                                          p_bpkey      => p.bp_key,
                                          p_ftype      => NULL,
                                          p_fincarn    => NULL,
                                          p_libkey     => NULL,
                                          p_spawn_job  => FALSE,
                                          p_notasks    => TRUE,
                                          p_noplans    => TRUE);
  END LOOP;
 
--
  SELECT curr_dbinc_key INTO l_currinc FROM db WHERE db_key = p_dbkey;
 
--
--
--
--
--
--
--
  SELECT * BULK COLLECT INTO l_lowscnlst, l_dfkeylst
    FROM (SELECT MIN(scn) lowscn, b.df_key 
          FROM df f,
               blocks b,
               (SELECT dbinc_key,
                       NVL(PRIOR reset_scn, BIGNUM) next_reset_scn
                FROM dbinc
                START WITH dbinc_key = l_currinc
                CONNECT BY PRIOR parent_dbinc_key = dbinc_key) i
          WHERE f.dbinc_key = l_currinc
            AND b.df_key = f.df_key
            AND (b.dbinc_key = i.dbinc_key OR 
                 b.dbinc_key NOT IN
                             (SELECT dbinc_key FROM dbinc
                              START WITH dbinc_key = l_currinc
                              CONNECT BY PRIOR parent_dbinc_key = dbinc_key))
            AND i.next_reset_scn-1 < b.scn
          GROUP BY b.df_key)
    WHERE lowscn IS NOT NULL;
 
--
--
--
  FOR i IN 1 .. l_dfkeylst.COUNT LOOP
    deb('repairChunks orphan blocks fix dfkey ' || l_dfkeylst(i) ||
        ', below scn ' || l_lowscnlst(i), AM_DEBUG_ON);
    UPDATE vbdf SET state = VBDF_COMPLETE
      WHERE df_key = l_dfkeylst(i)
        AND state = VBDF_OBSOLETE
        AND ckp_scn < l_lowscnlst(i)
        AND incr_scn < KSCNINV;
  END LOOP;
  COMMIT;
 
--
--
--
  FOR piece IN (SELECT c.filename, v.vb_key, c.chunkno
                FROM vbdf v, chunks c, dbinc i
                WHERE i.db_key = p_dbkey
                  AND v.dbinc_key = i.dbinc_key
                  AND v.relfno = 1
                  AND c.df_key = v.df_key
                  AND c.chunkno = v.krbph_chunkno
                  AND c.df_key = v.krbph_dfkey
                  AND c.dbinc_key = i.dbinc_key
                  AND v.state = VBDF_FIN_NOBP
                ORDER BY v.vb_key)
  LOOP
--
    UPDATE vbdf SET state = VBDF_OBSOLETE
      WHERE vb_key = piece.vb_key
        AND incr_scn >= KSCNINV
        AND state = VBDF_FIN_NOBP;
    l_numbadvb := SQL%ROWCOUNT;
 
--
    FOR i IN 1 .. l_dfkeylst.COUNT LOOP
      UPDATE vbdf SET state = VBDF_COMPLETE
        WHERE vb_key = piece.vb_key
          AND df_key = l_dfkeylst(i)
          AND incr_scn >= KSCNINV
          AND ckp_scn < l_lowscnlst(i)
          AND state = VBDF_OBSOLETE;
    END LOOP;
    COMMIT;
 
--
    IF l_numbadvb = 0 THEN
      FOR i IN (SELECT df_key, vb_key FROM vbdf
                WHERE vb_key = piece.vb_key
                  AND dfbytes IS NULL
                  AND incr_scn < KSCNINV) LOOP
        IF dbms_ra_int.read_lock(dbms_ra_int.KEY_DF, i.df_key) THEN
          l_dflock := i.df_key;
          sys.kbrsi_icd.rsPlan(p_dbkey, i.vb_key, i.df_key,
                               KBRSPLBLD_ORIGPIECE, 0);
        ELSE
          SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(
                      DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM, 'no_read_lock');
        END IF;
        dbms_ra_int.unlock(dbms_ra_int.KEY_DF, i.df_key);
      END LOOP;
      l_dflock := NULL;
 
--
      SELECT SUM(p.blksread) * AVG(f.block_size) INTO l_size
        FROM df f, vbdf v, plans p
        WHERE v.vb_key = piece.vb_key
          AND p.type = KBRSPLBLD_ORIGPIECE
          AND p.vb_key = piece.vb_key
          AND p.df_key = v.df_key
          AND f.dbinc_key = v.dbinc_key
          AND f.df_key = p.df_key;
 
--
      deb('repairChunks inspect piece: vbkey ' || piece.vb_key, AM_DEBUG_MED);
      sys.kbrsi_icd.rsInspectBackupPiece(
                               handle        => piece.filename,
                               vbkey         => piece.vb_key,
                               bpsize        => l_size,
                               chktype       => DBMS_RA_INT.KBRSCHKTYPE_VIRTUAL,
                               fno           => null,
                               lib_key       => null, /* local disk file */
                               ct_key        => null,
                               bpkey         => l_outbpkey,
                               template_key  => null);
--
      UPDATE vbdf SET vcbp_key = l_outbpkey WHERE vb_key = piece.vb_key;
      COMMIT;
    ELSE
      deb('repairChunks: no vcbp_key for vbkey ' || piece.vb_key ||
          ' there are ' || l_numbadvb || ' obsolete df in piece',
          AM_DEBUG_MED);
    END IF;
  END LOOP;
 
--
--
--
  FOR piece IN (SELECT c.filename, v.vb_key, v.df_key, v.file#,
                       v.dfbytes, v.ROWID
                FROM vbdf v, chunks c
                WHERE v.krbph_chunkno = c.chunkno
                  AND v.krbph_dfkey = c.df_key
                  AND state IN (VBDF_COMPLETE, VBDF_FIN_NOBP)
                  AND incr_scn < KSCNINV
                  AND db_key = p_dbkey
                  AND NOT EXISTS
                      (SELECT 1
                       FROM bp p, bdf d
                       WHERE p.bs_key = d.bs_key
                         AND p.vb_key = v.vb_key
                         AND p.db_key = p_dbkey
                         AND d.file#  = v.file#
                         AND incrLevel(d.create_scn, d.incr_scn) = 0))
  LOOP
--
    IF dbms_ra_int.read_lock(dbms_ra_int.KEY_DF, piece.df_key) THEN
      l_dflock := piece.df_key;
      BEGIN
        sys.kbrsi_icd.rsPlan(p_dbkey, piece.vb_key, piece.df_key,
                             KBRSPLBLD_PIECE, 0);
      EXCEPTION
        WHEN OTHERS THEN
          save_error;
--
--
          IF SQLCODE = dbms_ra_scheduler.e_corrupt_backup_num
          OR SQLCODE = dbms_ra_scheduler.e_backup_io_error_rman_num
          OR SQLCODE = dbms_ra_scheduler.e_error_id_file_num
          OR SQLCODE = dbms_ra_scheduler.e_corrupt_backuppiece_num
          OR SQLCODE = dbms_ra_int.bad_block_metadata_num
          THEN
            dbms_ra_scheduler.log_error (
                            p_errno     => SQLCODE,
                            p_component => 'REPAIR',
                            p_severity  => dbms_ra_scheduler.severity_error,
                            p_db_key    => p_dbkey);
--
--
--
          ELSE
            RAISE;
          END IF;
          clear_error;
      END;
    ELSE
      SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(
                      DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM, 'no_read_lock2');
    END IF;
    dbms_ra_int.unlock(dbms_ra_int.KEY_DF, piece.df_key);
    l_dflock := NULL;
 
--
    deb('repairChunks inspect piece: dfkey ' || piece.df_key ||
        ', vbkey ' || piece.vb_key, AM_DEBUG_MED);
    sys.kbrsi_icd.rsInspectBackupPiece(
                               handle        => piece.filename,
                               vbkey         => piece.vb_key,
                               bpsize        => piece.dfbytes,
                               chktype       => DBMS_RA_INT.KBRSCHKTYPE_VIRTUAL,
                               fno           => piece.file#,
                               lib_key       => null, /* local disk file */
                               ct_key        => null,
                               bpkey         => l_outbpkey,
                               template_key  => null);
  END LOOP;
 
--
--
--
--
  FOR p IN (SELECT p.db_key, handle, sl_key, db_id, curr_dbinc_key, bp_key
            FROM bp p, db, odb
            WHERE p.db_key = db.db_key
              AND p.db_key = odb.db_key
              AND p.db_key = p_dbkey
              AND vb_key IN (SELECT MAX(vb_key)
                             FROM vbdf
                             WHERE db_key = p_dbkey
                             GROUP BY df_key)
              AND EXISTS (SELECT 1 FROM bp p2
                          WHERE p.bs_key = p2.bs_key AND p2.vb_key IS NULL))
  LOOP
    BEGIN
      sys.kbrsi_icd.validateTask(bpkey => p.bp_key);
    EXCEPTION
      WHEN dbms_ra_scheduler.E_CORRUPT_BACKUP THEN
        save_error;
--
        dbms_ra_storage.free_backup_piece_opt(
                                          p_dbkey      => p.db_key,
                                          p_piecename  => p.handle,
                                          p_db_slkey   => p.sl_key,
                                          p_dbid       => p.db_id,
                                          p_currinc    => p.curr_dbinc_key,
                                          p_bpkey      => p.bp_key,
                                          p_ftype      => NULL,
                                          p_fincarn    => NULL,
                                          p_libkey     => NULL,
                                          p_spawn_job  => FALSE,
                                          p_notasks    => TRUE,
                                          p_noplans    => TRUE);
        clear_error;
    END;
  END LOOP;
 
--
  IF debug = AM_DEBUG_HIGH THEN
    FOR x IN (SELECT * FROM vbdf ORDER BY df_key, vb_key) LOOP
      deb('vbdf df_key ' || x.df_key ||
          ', vb_key ' || x.vb_key ||
          ', ckp_scn ' || x.ckp_scn ||
          ', dbinc_key ' || x.dbinc_key ||
          ', state ' || x.state);
    END LOOP;
  END IF;
 
  EXCEPTION
    WHEN OTHERS THEN
      save_error;
--
--
      IF l_fixfin THEN
        UPDATE vbdf SET state = VBDF_REPAIR
          WHERE state = VBDF_FIN_NOBP AND db_key = p_dbkey;
        COMMIT;
      END IF;
 
      IF l_dflock IS NOT NULL THEN
        dbms_ra_int.unlock(dbms_ra_int.KEY_DF, l_dflock);
      END IF;
      RAISE;
END repairChunks;
 
 
/*---------------------------------------------------------------------------*
 *                        PRIVATE  FUNCTIONS                                 *
 *---------------------------------------------------------------------------*/
 
--
--
--
--
--
--
PROCEDURE deb(p_line IN varchar2, p_level IN NUMBER DEFAULT AM_DEBUG_ON)
 IS
BEGIN
  IF debug >= p_level
  THEN
--
--
--
    sys.kbrsi_icd.rsTrace('RSPL: ' || p_line);
  END IF;
END deb;
 
 
--
--
--
--
--
--
PROCEDURE debugdf(p_dfkey IN NUMBER)
 IS
BEGIN
  IF debug >= AM_DEBUG_HIGH THEN
    deb('DEBUGDF dfkey ' || p_dfkey);
    FOR f IN (SELECT bp_key, df_key, p.vb_key, dbinc_key, ckp_scn
              FROM bp p, vbdf v
              WHERE p.vb_key = v.vb_key
                AND p.db_key = v.db_key
                AND v.df_key = p_dfkey
              ORDER BY dbinc_key, p.vb_key, ckp_scn) LOOP
      deb('DEBUGDF dfkey ' || f.df_key ||
          ', dbinc ' || f.dbinc_key ||
          ', vbkey ' || f.vb_key ||
          ', scn ' || f.ckp_scn ||
          ', bpkey ' || f.bp_key);
    END LOOP;
  END IF;
END debugdf;
 
 
--
--
PROCEDURE save_error IS 
BEGIN
  dbms_ra_int.save_error_int;
END save_error;
 
--
--
PROCEDURE clear_error IS
BEGIN
  dbms_ra_int.clear_error_int;
END clear_error;
 
--
--
--
--
--
FUNCTION print (p_value IN BOOLEAN) RETURN VARCHAR2 IS
BEGIN
  IF p_value THEN
    RETURN 'TRUE';
  ELSIF p_value IS NULL THEN
    RETURN 'NULL';
  ELSE
    RETURN 'FALSE';
  END IF;
END print;
 
 
--
--
--
--
--
PROCEDURE raise_bad_metadata(p_dfkey IN NUMBER)
 IS
  l_fno    NUMBER;
  l_dbkey  NUMBER;
BEGIN
--
 
--
  SELECT MIN(db_key) INTO l_dbkey
    FROM dbinc i, df f
    WHERE i.dbinc_key = f.dbinc_key
      AND df_key = p_dfkey;
 
--
  SELECT max(file#) INTO l_fno
    FROM df WHERE df_key = p_dfkey;
 
  SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(dbms_ra_int.BAD_BLOCK_METADATA_NUM,
                                        dbms_ra_int.dbkey2name(l_dbkey),
                                        l_fno);
END raise_bad_metadata;
 
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE purge_lock(p_key IN NUMBER)
 IS
  l_hash   NUMBER;
  l_count  NUMBER;
BEGIN
--
  SELECT ORA_HASH(p_key, 1023, 0) + 1 INTO l_hash FROM dual;
  dbms_ra_scheduler.get_lock(dbms_ra_scheduler.LOCK_PURGE, l_hash);
 
--
--
  SELECT MIN(task_id) INTO dbms_ra_scheduler.s_pending_interrupt
    FROM task
    WHERE task_type IN (dbms_ra_scheduler.TASK_PURGE_DF,
                        dbms_ra_scheduler.TASK_PURGE_DF_NOW,
                        dbms_ra_scheduler.TASK_PURGE_DUP_DF)
      AND param_num1 = p_key
      AND savepoint = RESTART_PURGE_DEL_BLOCKS
      AND task_id <> dbms_ra_scheduler.s_current_task;
 
  IF dbms_ra_scheduler.s_pending_interrupt IS NOT NULL THEN
    RAISE dbms_ra_scheduler.e_retry_error;
  END IF;
END purge_lock;
 
 
--
--
--
--
--
PROCEDURE purge_unlock(p_key IN NUMBER)
 IS
  l_hash NUMBER;
BEGIN
  SELECT ORA_HASH(p_key, 1023, 0) + 1 INTO l_hash FROM dual;
  dbms_ra_scheduler.unlock(dbms_ra_scheduler.LOCK_PURGE, l_hash);
END purge_unlock;
 
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE lock_vb(p_lock  IN BOOLEAN,
                  p_dbkey IN NUMBER,
                  p_dfkey IN NUMBER,
                  p_vbkey IN NUMBER,
                  p_qtype IN NUMBER)
 IS
BEGIN
--
  FOR b IN (SELECT vb_key
            FROM vbdf
            WHERE db_key = p_dbkey
              AND df_key = p_dfkey
              AND krbph_dfkey = p_dfkey
              AND ckp_id IN
                     (SELECT ckp_id
                      FROM plans_details JOIN blocks
                                         USING (df_key, blockno, chunkno)
                      WHERE df_key = p_dfkey
                        AND vb_key = p_vbkey
                        AND type = p_qtype
                        AND blockno = 0
                     )
           )
  LOOP
    IF p_lock THEN
      IF NOT dbms_ra_int.read_lock(dbms_ra_int.KEY_VB, b.vb_key)
      THEN
--
        SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(
                                      DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM, 
                                        'lock_vb missing vbkey ' || b.vb_key);
      END IF;
    ELSE
      dbms_ra_int.unlock(dbms_ra_int.KEY_VB, b.vb_key);
    END IF;
  END LOOP;
END lock_vb;
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE working_ckpid(p_dbkey     IN     NUMBER,
                        p_dfkey     IN     NUMBER,
                        p_vbkey     IN     NUMBER,
                        p_orphans   IN     BOOLEAN, -- orphan backups
                        p_dbinckey  IN OUT NUMBER,  -- in backup dbinc
                        p_ckpid     IN OUT NUMBER,  -- in backup ckpid
                        p_deadinc   OUT    NUMBER,  -- orphan inc we no need
                        p_orphaninc OUT    NUMBER)  -- orphan blocks inc
IS
  l_vbkey    NUMBER;
  l_dbinckey NUMBER;
  l_ckpscn   NUMBER;
  l_minvbkey NUMBER;
  l_ok       NUMBER;
BEGIN
  p_deadinc := 0; /* zero better than null for later comparisons */
  p_orphaninc := p_dbinckey; /* makes other algorithms work. */
 
--
  IF NOT p_orphans THEN
    SELECT NVL(MAX(ckp_id), p_ckpid) INTO p_ckpid FROM vbdf
      WHERE df_key = p_dfkey
        AND state = VBDF_COMPLETE;
    RETURN;
 
--
  ELSE
--
--
--
--
--
--
--
    l_dbinckey := NULL;
    FOR b IN (SELECT vb_key, ckp_scn, reset_scn, dbinc_key, parent_dbinc_key
              FROM vbdf JOIN dbinc USING (db_key, dbinc_key)
              WHERE df_key = p_dfkey
              ORDER BY vb_key)
    LOOP
--
--
--
--
      l_ok := 1;
      IF NOT (b.dbinc_key = l_dbinckey OR
              (b.parent_dbinc_key = l_dbinckey AND b.reset_scn > l_ckpscn))
      THEN
--
--
        SELECT COUNT(*) INTO l_ok
          FROM vbdf v,
               (SELECT dbinc_key, reset_scn,
                       NVL(PRIOR reset_scn, BIGNUM) next_reset_scn
                FROM dbinc
                START WITH dbinc_key = b.dbinc_key
                CONNECT BY PRIOR parent_dbinc_key = dbinc_key
               ) i
          WHERE v.df_key = p_dfkey
            AND v.dbinc_key = i.dbinc_key
            AND v.ckp_scn < i.next_reset_scn
            AND v.state != VBDF_OBSOLETE
            AND v.vb_key = l_vbkey;
      END IF;
 
--
      IF b.ckp_scn < l_ckpscn THEN
        l_ok := 0;
      END IF;
 
--
      EXIT WHEN l_ok = 0;
 
--
      l_dbinckey := b.dbinc_key;
      l_vbkey := b.vb_key;
      l_ckpscn := b.ckp_scn;
    END LOOP;
    p_orphaninc := l_dbinckey;
 
--
    IF l_ok > 0 THEN
      SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(
                DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM, 'bad orphan compute');
    END IF;
--
 
--
--
    IF p_vbkey >= l_vbkey THEN
--
--
--
      SELECT vb_key INTO l_minvbkey
        FROM vbdf
        WHERE df_key = p_dfkey
          AND ckp_id = (SELECT min_id
                        FROM vbdf
                        WHERE df_key = p_dfkey 
                          AND vb_key = p_vbkey
                        );
      IF l_minvbkey > l_vbkey THEN
        p_deadinc := p_orphaninc;
      END IF;
 
      RETURN;
    END IF;
 
--
--
    p_ckpid    := BIGNUM;
    p_dbinckey := p_orphaninc;
  END IF;
END working_ckpid;
 
--
--
--
--
--
--
--
--
--
PROCEDURE alloc_plan(p_dbkey     IN NUMBER,
                     p_dfkey     IN NUMBER,
                     p_vbkey     IN NUMBER,
                     p_qtype     IN NUMBER)
 IS
  l_task    NUMBER := NULL;
BEGIN
--
--
  IF dbms_ra_scheduler.s_current_task_type NOT IN 
                                        (dbms_ra_scheduler.TASK_INDEX_BACKUP,
                                         dbms_ra_scheduler.TASK_PLAN_DF,
                                         dbms_ra_scheduler.TASK_PLAN_SBT)
  THEN
    l_task := dbms_ra_scheduler.s_current_task;
  END IF;
 
--
--
--
  INSERT INTO plans (type, db_key, vb_key, df_key, task_id)
    VALUES (p_qtype, p_dbkey, p_vbkey, p_dfkey, l_task);
  COMMIT;
 
--
  deb('alloc_plan: type ' || p_qtype ||
      ', dfkey ' || p_dfkey ||
      ', vbkey ' || p_vbkey, AM_DEBUG_LOW);
END alloc_plan;
 
--
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE dealloc_plan(p_dfkey     IN NUMBER,
                       p_vbkey     IN NUMBER  DEFAULT NULL,
                       p_qtype     IN NUMBER  DEFAULT NULL,
                       p_lock      IN BOOLEAN DEFAULT TRUE)
 IS
  l_count   NUMBER;
  l_task    NUMBER := NULL;
  l_locked  BOOLEAN := FALSE;
  l_didit   BOOLEAN := FALSE;
BEGIN
--
  IF NOT p_lock THEN
    l_locked := TRUE;
  END IF;
 
--
--
--
  FOR x IN (SELECT df_key, vb_key, type
            FROM plans
            WHERE df_key = p_dfkey
              AND ((type = p_qtype AND vb_key = p_vbkey) OR
                   (type = p_qtype AND p_vbkey IS NULL)  OR
                   old = 1)
            ORDER BY type)  -- purge plans first
  LOOP
    l_didit := TRUE;
 
--
    IF NOT l_locked AND x.type IN (KBRSPLBLD_ORIGPIECE, KBRSPLBLD_PIECE)
    THEN
      BEGIN
        dbms_ra_int.write_lock(dbms_ra_int.KEY_DF, p_dfkey);
        l_locked := TRUE;
      EXCEPTION
        WHEN dbms_ra_scheduler.e_retry_error THEN
          save_error;
          l_locked := FALSE;
          clear_error;
      END;
    END IF;
 
--
    IF l_locked OR x.type NOT IN (KBRSPLBLD_ORIGPIECE, KBRSPLBLD_PIECE)
    THEN
      DELETE FROM plans_details
        WHERE df_key = x.df_key
          AND vb_key = x.vb_key
          AND type = x.type;
      DELETE FROM plans
        WHERE df_key = x.df_key
          AND vb_key = x.vb_key
          AND type = x.type;
      l_count := SQL%ROWCOUNT;
      COMMIT;
 
      deb('dealloc_plan: type ' || x.type ||
          ', dfkey ' || x.df_key ||
          ', vbkey ' || x.vb_key ||
          ', deleted ' || l_count, AM_DEBUG_LOW);
 
--
    ELSE
      UPDATE plans SET old = 1
        WHERE df_key = x.df_key
          AND vb_key = x.vb_key
          AND type = x.type;
      l_count := SQL%ROWCOUNT;
      COMMIT;
 
      deb('dealloc_plan: type ' || x.type ||
          ', dfkey ' || x.df_key ||
          ', vbkey ' || x.vb_key ||
          ', olded ' || l_count, AM_DEBUG_LOW);
    END IF;
  END LOOP;
 
--
  IF l_locked AND p_lock THEN
    dbms_ra_int.unlock(dbms_ra_int.KEY_DF, p_dfkey);
  END IF;
 
--
  IF NOT l_didit THEN
    deb('dealloc_plan: type ' || p_qtype ||
        ', dfkey ' || p_dfkey ||
        ', vbkey ' || p_vbkey ||
        ', nothing found', AM_DEBUG_LOW);
  END IF;
 
EXCEPTION
  WHEN OTHERS THEN
    save_error;
 
--
    IF l_locked AND p_lock THEN
      dbms_ra_int.unlock(dbms_ra_int.KEY_DF, p_dfkey);
    END IF;
 
    RAISE;
END dealloc_plan;
 
 
--
--
--
--
--
--
--
PROCEDURE trim_plan(p_dfkey     IN NUMBER)
 IS
  l_plans_maintained NUMBER := dbms_ra_scheduler.s_plans_maintained;
  l_loopcnt          NUMBER := 0;
  l_count            NUMBER;
BEGIN
  deb('trim_plan dfkey ' || p_dfkey, AM_DEBUG_LOW);
 
--
  FOR x IN (SELECT vb_key, old, type
            FROM plans p
            WHERE df_key = p_dfkey
              AND type IN (KBRSPLBLD_PIECE, KBRSPLBLD_ORIGPIECE)
            ORDER BY type ASC, vb_key DESC)
  LOOP
    IF l_loopcnt >= l_plans_maintained  /* keep this many plans */
    OR x.old = 1                        /* plan is already old */
    THEN
--
--
      SELECT COUNT(*) INTO l_count
        FROM (SELECT MIN(df_key) mindf, MAX(df_key) maxdf
              FROM sbt_task JOIN bp USING (bs_key)
                            JOIN bdf USING (bs_key)
                            JOIN df USING (dbinc_key, create_scn, file#)
              WHERE vb_key = x.vb_key
              GROUP BY bs_key, df_key
             )
        WHERE mindf = p_dfkey
          AND mindf = maxdf
          AND ROWNUM = 1;
 
      IF l_count = 0 THEN
        dealloc_plan(p_dfkey, x.vb_key, x.type);
      END IF;
    END IF;
    l_loopcnt := l_loopcnt + 1;
  END LOOP;
END trim_plan;
 
--
--
--
--
--
--
--
--
--
--
--
FUNCTION fragmentation(p_dbkey IN NUMBER,
                       p_dfkey IN NUMBER,
                       p_vbkey IN NUMBER) RETURN NUMBER IS
  l_frag      NUMBER := NULL;
  l_cklst     NOLST;
  l_size      NUMBER := 0;
  l_chunksize NUMBER := f_chunksize(p_dbkey);
  l_curfrag   NUMBER := dbms_ra_scheduler.s_fragmentation;
  j           NUMBER;
BEGIN
  deb('fragmentation dfkey ' || p_dfkey || ', vbkey ' || p_vbkey);
  FOR i IN (SELECT chunkno, numbytes FROM plans_details
            WHERE type = KBRSPLBLD_PIECE
              AND df_key = p_dfkey
              AND vb_key = p_vbkey
              AND numbytes > 0
              AND blockno > 1
            ORDER BY blockno) LOOP
--
    j := 0;
    WHILE (j < l_cklst.COUNT AND l_cklst(j) <> i.chunkno) LOOP
      j := j + 1;
    END LOOP;
 
--
    IF j >= l_cklst.COUNT THEN
      l_cklst(j) := i.chunkno;
 
--
      IF j > l_curfrag THEN
        deb('fragmentation fragged dfkey ' || p_dfkey ||
            ', chunk ' || i.chunkno ||
            ', count ' || l_cklst.COUNT, AM_DEBUG_MED);
        RETURN j;
      END IF;
    END IF;
 
--
    l_size := l_size + i.numbytes;
    IF l_size > l_chunksize THEN
      l_frag := GREATEST(l_cklst.COUNT, NVL(l_frag, 0));
      l_size := 0;
      l_cklst.DELETE;
    END IF;
  END LOOP;
 
--
  IF l_frag IS NULL AND l_size > 0 THEN
    l_frag := 1;
  END IF;
 
  RETURN l_frag;
END fragmentation;
 
--
--
--
--
--
--
PROCEDURE show_plan(p_vbkey       IN  NUMBER, -- Virtual backup id
                    p_dfkey       IN  NUMBER, -- Datafile key
                    p_krbph_dfkey IN  NUMBER, -- Datafile key for krbph
                    p_qtype       IN  NUMBER) -- KBRSPLBLD_ type stored in plan
 IS
BEGIN
  IF debug <> AM_DEBUG_HIGH THEN
    RETURN;
  END IF;
 
  deb('show_plan: qtype ' || p_qtype);
 
--
  FOR x IN (SELECT dbinc_key, vb_key, ckp_id, min_id, incr_scn, ckp_scn, state
            FROM vbdf
            WHERE df_key = p_dfkey
            ORDER BY vb_key)
  LOOP
    deb('vbkey ' || x.vb_key ||
        ', dbinc ' || x.dbinc_key ||
        ', incrscn ' || x.incr_scn ||
        ', ckpscn ' || x.ckp_scn ||
        ', minid ' || x.min_id ||
        ', cpi ' || x.ckp_id ||
        ', state ' || x.state);
  END LOOP;
 
--
  FOR x IN (SELECT dbinc_key, parent_dbinc_key, reset_scn
            FROM dbinc
            WHERE db_key = (SELECT MAX(db_key) FROM vbdf
                            WHERE df_key = p_dfkey)
            ORDER BY reset_time)
  LOOP
    deb('dbinc ' || x.dbinc_key ||
        ', parent ' || x.parent_dbinc_key ||
        ', reset_scn ' || x.reset_scn);
  END LOOP;
 
--
--
--
--
  IF p_dfkey <> p_krbph_dfkey THEN
    FOR x IN (SELECT /*+ LEADING(p) USE_HASH(b) */
                     b.blockno, b.ckp_id, b.scn, p_krbph_dfkey dfkey,
                     b.chunkno, b.coffset, p.blkrank
              FROM blocks b, plans_details p
              WHERE b.df_key = p_krbph_dfkey
                AND b.blockno = 0
                AND b.chunkno = p.chunkno
                AND b.coffset = p.coffset
                AND p.blockno = 0
                AND p.df_key = p_dfkey
                AND p.type = p_qtype
                AND p.vb_key = p_vbkey)
      LOOP
        deb('plan bno ' || x.blockno ||
            ', scn ' || x.scn ||
            ', dfkey ' || x.dfkey ||
            ', chunk ' || x.chunkno ||
            ', cpi ' || x.ckp_id ||
            ', o' || x.coffset);
      END LOOP;
  END IF;
 
--
--
  FOR x IN (SELECT /*+ LEADING(p) USE_HASH(b) */
                   DECODE(MIN(b.blockno), 1, BIGNUM,
                          MIN(b.blockno)) blockno,
                   b.ckp_id, b.scn, p_dfkey dfkey,
                   b.chunkno, b.coffset, b.used,
                   NULLIF(MAX(b.blockno), MIN(b.blockno)) endblk, p.blkrank
            FROM blocks b, plans_details p
            WHERE b.df_key = p_dfkey
              AND b.chunkno = p.chunkno
              AND b.coffset BETWEEN p.coffset
                                AND (p.coffset + greatest(p.numbytes-1, 0))
              AND p.blockno > DECODE(p_qtype, KBRSPLBLD_PIECE, 0, -1)
              AND p.df_key = p_dfkey
              AND p.type = p_qtype
              AND p.vb_key = p_vbkey
            GROUP BY b.df_key, p.blkrank, b.ckp_id, b.scn, b.used,
                     b.chunkno, b.coffset
            ORDER BY blkrank, blockno) LOOP
      deb('plan bno ' || x.blockno ||
          ', scn ' || x.scn ||
          ', dfkey ' || x.dfkey ||
          ', chunk ' || x.chunkno ||
          ', cpi ' || x.ckp_id ||
          ', o' || x.coffset ||
          ', s' || x.used ||
          ' -- ' || x.endblk);
    END LOOP;
END show_plan;
 
--
--
--
--
--
--
--
PROCEDURE plan_blocks(p_vbkey       IN  NUMBER, -- Virtual backup id
                      p_dfkey       IN  NUMBER, -- Datafile key
                      p_chunksize   IN  NUMBER, -- size of chunk
                      p_bufsize     IN  NUMBER, -- size of read buffers
                      p_blksize     IN  NUMBER, -- size of each block
                      p_type        IN  NUMBER, -- KBRSPLBLD_ type
                      p_totalsize   OUT NUMBER, -- backup size of df
                      p_totalblocks OUT NUMBER, -- blocks in datafile
                      p_totalchunks OUT NUMBER, -- distinct chunks in plan
                      p_signature   OUT NUMBER, -- signature 4 restore
                      p_maxrank     OUT NUMBER) -- block ranking in plan
 IS
  l_fno         NUMBER;  -- file#
  l_relfno      NUMBER;  -- relative file#
  l_issft       NUMBER;  -- is Single File Tablespace
  l_krbph_dfkey NUMBER;  -- df_key for block 0 data
  l_dbkey       NUMBER;
  l_qtype       NUMBER;
  l_count       NUMBER;
BEGIN
  deb('plan_blocks: type ' || p_type ||
      ', dfkey ' || p_dfkey ||
      ', vbkey ' || p_vbkey ||
      '  At ' || TO_CHAR(SYSDATE, 'HH24:MI:SS'), AM_DEBUG_MED);
 
  dbms_ra_int.info_start('plan_blocks',
                         'dfkey ' || p_dfkey || ', vbkey ' || p_vbkey);
 
  IF p_type IN (KBRSPLBLD_OPTPURGE, KBRSPLBLD_ALLPURGE, KBRSPLBLD_SMALLPURGE,
                KBRSPLBLD_DUPPURGE)
  THEN
    l_qtype := KBRSPLBLD_PURGE;
  ELSE
    l_qtype := p_type;
  END IF;
 
--
  BEGIN
    SELECT f.file#, v.relfno, f.issft, v.krbph_dfkey, db_key
      INTO l_fno, l_relfno, l_issft, l_krbph_dfkey, l_dbkey
      FROM df f, vbdf v
      WHERE v.vb_key = p_vbkey
        AND v.df_key = p_dfkey
        AND f.dbinc_key = v.dbinc_key
        AND f.df_key = p_dfkey;
  EXCEPTION
    WHEN no_data_found THEN
      save_error;
      RAISE dbms_ra_scheduler.e_retry_error;
    WHEN OTHERS THEN
      save_error;
      RAISE;
  END;
 
--
  IF p_type IN (KBRSPLBLD_PIECE, KBRSPLBLD_ORIGPIECE, KBRSPLBLD_OPTIMIZE) THEN
    restore_plan_blocks(p_type, p_dfkey, p_vbkey, p_blksize);
  ELSE
--
    old_chunks(p_type, p_dfkey, p_vbkey);
 
--
    IF p_type <> KBRSPLBLD_ALLPURGE THEN
      SELECT COUNT(*) INTO l_count FROM bp WHERE vb_key = p_vbkey;
      IF l_count = 0 THEN  /* just give up */
        RAISE dbms_ra_scheduler.e_retry_error;
      END IF;
    END IF;
  END IF;
 
  IF p_type <> KBRSPLBLD_ALLPURGE THEN
--
    SELECT NVL(SUM(case numbytes when 0 then MBLK_SIZE else numbytes end), 0), 
           NVL(SUM(case numbytes when 0 then         1 else numblks  end), 0), 
           NVL(SUM(signature), 0),
           COUNT(DISTINCT chunkno),
           MAX(blkrank)
      INTO p_totalsize, p_totalblocks, p_signature, p_totalchunks, p_maxrank
      FROM plans_details
      WHERE df_key = p_dfkey
        AND type = l_qtype
        AND vb_key = p_vbkey
        AND blockno >= 0;
    IF p_totalsize = 0 AND l_qtype = KBRSPLBLD_PURGE THEN
      p_totalsize := p_totalsize + p_totalblocks; /* ensure we count gaps */
    END IF;
 
--
    UPDATE plans_details
      SET blockno = DBMS_RA_INT.UB4MAXVAL
      WHERE df_key = p_dfkey
        AND type = l_qtype
        AND vb_key = p_vbkey
        AND blockno = 1;
 
--
--
    IF SQL%ROWCOUNT = 0 AND p_type IN (KBRSPLBLD_PIECE, KBRSPLBLD_ORIGPIECE)
    THEN
      deb('plan_blocks missing block 1 - type ' || p_type ||
          ', dfkey ' || p_dfkey ||
          ', vbkey ' || p_vbkey,
          AM_DEBUG_ON);
      raise_bad_metadata(p_dfkey);
    END IF;
  ELSE
    p_totalsize := 0;
    p_totalblocks := 0;
    p_signature := 0;
    p_totalchunks := 0;
    deb('plan_blocks: deleting chunks', AM_DEBUG_HIGH);
  END IF;
 
--
--
--
  IF  debug = AM_DEBUG_HIGH 
  AND p_type <> KBRSPLBLD_ALLPURGE THEN
    show_plan(p_vbkey, p_dfkey, l_krbph_dfkey, l_qtype);
 
    deb('plan_blocks - type ' || p_type ||
        ', dfkey ' || p_dfkey ||
        ', vbkey ' || p_vbkey||
        '  Done ' || TO_CHAR(SYSDATE, 'YYYY/MM/DD HH24:MI:SS'));
  END IF;
 
  dbms_ra_int.info_end;
END plan_blocks;
 
--
--
--
--
--
--
--
PROCEDURE restore_plan_blocks(p_type        IN  NUMBER, -- KBRSPLBLD_ type
                              p_dfkey       IN  NUMBER, -- Datafile key
                              p_vbkey       IN  NUMBER, -- Virtual backup id
                              p_blksize     IN  NUMBER) -- size of each block
 IS
  l_dbkey       NUMBER;
  l_pdbinc_key  NUMBER;
  l_dbinckey    NUMBER;
  l_deadinc     NUMBER;
  l_orphaninc   NUMBER;
  l_blocks      NUMBER;
  l_firstblk    NUMBER;
  l_lastblk     NUMBER;
  l_ckpscn      NUMBER;
  l_absscn      NUMBER;
  l_minckpid    NUMBER;
  l_maxckpid    NUMBER;
  l_ckpid       NUMBER;
  l_incrscn     NUMBER;
  l_orphans     BOOLEAN;
  l_maxorphscn  NUMBER;
  l_tmp         NUMBER;
BEGIN
--
  SELECT i.dbinc_key, v.blocks, v.firstblk, v.lastblk,
         v.abs_scn, v.ckp_scn, v.ckp_id, v.pdbinc_key, v.db_key,
         (CASE p_type
            WHEN KBRSPLBLD_OPTIMIZE  THEN 0
            WHEN KBRSPLBLD_PIECE     THEN 0
            WHEN KBRSPLBLD_ORIGPIECE THEN v.incr_scn
            ELSE KSCNINV
         END) incrscn,
         (CASE p_type
            WHEN KBRSPLBLD_OPTIMIZE  THEN v.min_id
            WHEN KBRSPLBLD_PIECE     THEN v.min_id
            WHEN KBRSPLBLD_ORIGPIECE THEN v.ckp_id
            ELSE KSCNINV
          END) minckpid
    INTO l_dbinckey, l_blocks, l_firstblk, l_lastblk,
         l_absscn, l_ckpscn, l_ckpid, l_pdbinc_key, l_dbkey,
         l_incrscn, l_minckpid
    FROM vbdf v, dbinc i
    WHERE v.vb_key = p_vbkey
      AND v.df_key = p_dfkey
      AND v.dbinc_key = i.dbinc_key;
 
--
--
  IF (l_firstblk = 2 AND l_lastblk = l_blocks) THEN
    l_firstblk := 1;
  END IF;
 
--
  l_orphans := orphans(l_dbkey, p_dfkey);
 
--
  l_maxckpid := l_ckpid;
  working_ckpid(l_dbkey, p_dfkey, p_vbkey, l_orphans,
                l_dbinckey, l_maxckpid, l_deadinc, l_orphaninc);
 
--
--
  IF dbms_ra_scheduler.s_current_task_type IN
                                        (dbms_ra_scheduler.TASK_INDEX_BACKUP,
                                         dbms_ra_scheduler.TASK_REPAIR_DB)
  THEN
    l_maxckpid := BIGNUM;
  END IF;
 
  deb('plan: dbinc ' || l_dbinckey ||
      ', pdbinc ' || l_pdbinc_key ||
      ', dfkey ' || p_dfkey ||
      ', ckp_id ' || l_ckpid ||
      ', minckpid ' || l_minckpid ||
      ', maxckpid ' || l_maxckpid, AM_DEBUG_MED);
 
  deb('plan: blksize ' || p_blksize ||
      ', firstblk ' || l_firstblk ||
      ', lastblk ' || l_lastblk, AM_DEBUG_MED);
 
--
  IF l_orphans THEN
--
--
--
--
--
--
--
--
    orphan_common(l_dbinckey, l_orphaninc, p_dfkey, l_tmp, l_maxorphscn);
 
    IF l_pdbinc_key = 0 THEN
      q_restore_incs(p_type, p_dfkey, p_vbkey, l_incrscn, l_ckpscn, l_absscn,
                     l_ckpid, l_minckpid, l_maxckpid, l_dbinckey,
                     l_deadinc, l_orphaninc, l_maxorphscn,
                     l_firstblk, l_lastblk);
    ELSE
      q_restore_cdb(p_type, p_dfkey, p_vbkey, l_incrscn, l_ckpscn, l_absscn,
                    l_ckpid, l_minckpid, l_maxckpid, l_pdbinc_key, l_dbinckey,
                    l_deadinc, l_orphaninc, l_maxorphscn,
                    l_firstblk, l_lastblk, l_orphans);
    END IF;
  ELSE
    IF l_pdbinc_key = 0 THEN
      q_restore_fast(p_type, p_dfkey, p_vbkey, l_incrscn, l_ckpscn, l_absscn,
                     l_ckpid, l_minckpid, l_maxckpid, l_dbinckey,
                     l_firstblk, l_lastblk);
    ELSE
      q_restore_cdb(p_type, p_dfkey, p_vbkey, l_incrscn, l_ckpscn, l_absscn,
                    l_ckpid, l_minckpid, l_maxckpid, l_pdbinc_key, l_dbinckey,
                    0,0,0,
                    l_firstblk, l_lastblk, l_orphans);
    END IF;
  END IF;
 
--
--
  IF (l_firstblk > 1) THEN
    INSERT INTO plans_details (df_key, type, vb_key, blkrank, blockno,
                               chunkno, numblks, coffset, numbytes, signature)
    (SELECT *
     FROM
        (SELECT /*+ INDEX(b) NO_INDEX_FFS(b) */
                p_dfkey, p_type, p_vbkey, 1 blkrank,
                1 blockno,
                chunkno,
                1 numblks,
                coffset,
                used numbytes,
                scn signature
         FROM blocks b
         WHERE b.df_key = p_dfkey
           AND b.blockno = 1
           AND b.ckp_id = l_ckpid
         ORDER BY chunkno DESC
        )
     WHERE ROWNUM = 1
    );
    IF SQL%ROWCOUNT = 0 THEN
      deb('restore_plan_blocks: missing block 1' ||
          ', dfkey ' || p_dfkey ||
          ', vbkey ' || p_vbkey ||
          ', ckp_id ' || l_ckpid, AM_DEBUG_ON);
      SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(
             DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM,
             'missing block 1' ||
             ', dfkey ' || p_dfkey ||
             ', vbkey ' || p_vbkey ||
             ', ckp_id ' || l_ckpid);
    END IF;
  END IF;
 
--
--
--
--
--
  INSERT INTO plans_details (df_key, type, vb_key, blkrank, blockno,
                             chunkno, numblks, coffset, numbytes, signature)
        (SELECT /*+ LEADING(v) USE_NL(b) INDEX(b) NO_INDEX_FFS(b)
                    OPT_PARAM('optimizer_dynamic_sampling' 0)
                    OPT_PARAM('_optimizer_adaptive_cursor_sharing' 'false')
                    OPT_PARAM('_optimizer_extended_cursor_sharing_rel' 'none')
                    OPT_PARAM('_optimizer_use_feedback' 'false')
                    NO_EXPAND
                */
                p_dfkey, p_type, p_vbkey, 1 blkrank,
                0 blockno,
                chunkno,
                1 numblks,           /* only count 1, kbrspl.c expects that */
                p_blksize coffset,
                used numbytes,
                0 signature  /* other check avoids block 0, do not add here */
         FROM blocks b, vbdf v
         WHERE v.vb_key = p_vbkey
           AND b.df_key = v.df_key    
           AND b.chunkno = v.krbph_chunkno
           AND b.df_key = v.krbph_dfkey
           AND b.blockno = 0
           AND (p_type = KBRSPLBLD_PIECE OR     /* chunk can be from any df */
                (p_type = KBRSPLBLD_ORIGPIECE AND b.df_key = p_dfkey)));
  IF SQL%ROWCOUNT = 0 AND p_type = KBRSPLBLD_PIECE THEN
    deb('restore_plan_blocks: missing block 0' ||
        ', dfkey ' || p_dfkey ||
        ', vbkey ' || p_vbkey ||
        ', ckp_id ' || l_ckpid, AM_DEBUG_ON);
    SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(
             DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM,
             'missing block 0' ||
             ', dfkey ' || p_dfkey ||
             ', vbkey ' || p_vbkey ||
             ', ckp_id ' || l_ckpid);
  END IF;
END restore_plan_blocks;
 
--
--
--
--
--
--
PROCEDURE old_chunks(p_type    IN  NUMBER,
                     p_dfkey   IN  NUMBER,
                     p_vbkey   IN  NUMBER)
IS
  l_currinc   NUMBER;
  l_dbinc     NUMBER;
  l_ckpscn    NUMBER;
  l_absscn    NUMBER;
  l_ckpid     NUMBER;
  l_minckpid  NUMBER;
  l_maxckpid  NUMBER;
  l_orphaninc NUMBER;
  l_deadinc   NUMBER;
  l_fuzdif    NUMBER;
  l_minscn    NUMBER;
  l_dbkey     NUMBER;
  l_vbkey     NUMBER;
  l_chunksize NUMBER;
  l_maxrank   NUMBER;
  l_rank      NUMBER;
  l_size      NUMBER;
  l_lastblk   NUMBER;
  l_sumbytes  NUMBER;
BEGIN
  deb('old_chunks: type ' || p_type ||
      ', dfkey ' || p_dfkey ||
      ', vbkey ' || p_vbkey, AM_DEBUG_MED);
 
--
  SELECT db_key, dbinc_key, ckp_scn, abs_scn, ckp_id, min_id
    INTO l_dbkey, l_dbinc, l_ckpscn, l_absscn, l_ckpid, l_minckpid
    FROM vbdf
    WHERE df_key = p_dfkey
      AND vb_key = p_vbkey;
 
--
--
--
--
--
--
--
  IF p_type = KBRSPLBLD_DUPPURGE
  THEN
    SELECT MAX(ckp_id - ckp_scn), MIN(ckp_scn) INTO l_fuzdif, l_minscn
      FROM vbdf
      WHERE df_key = p_dfkey
        AND state = VBDF_COMPLETE;
  END IF;
 
--
  CASE p_type
    WHEN KBRSPLBLD_ALLPURGE  /* Remove all blocks */
    THEN
      q_purge_all(p_dfkey, p_vbkey, l_dbkey);
 
--
      UPDATE vbdf SET state = VBDF_ABORT
        WHERE df_key = p_dfkey
          AND state IN (VBDF_BUILDING, VBDF_FIN_NOBP);
      COMMIT;
 
--
      SELECT MAX(vb_key) INTO l_vbkey
        FROM vbdf
        WHERE df_key = p_dfkey
--
          AND state IN (VBDF_COMPLETE, VBDF_OBSOLETE);
      IF l_vbkey != p_vbkey THEN
        RAISE dbms_ra_scheduler.e_retry_error;
      END IF;
 
    WHEN KBRSPLBLD_DUPPURGE /* Remove duplicate blocks */
    THEN
      q_purge_dup(p_type, p_dfkey, p_vbkey, l_dbkey, l_dbinc,
                  l_fuzdif, l_minscn);
 
    ELSE
--
--
--
--
      SELECT dbinc_key INTO l_currinc
        FROM (SELECT dbinc_key
              FROM vbdf
              WHERE df_key = p_dfkey
              ORDER BY vb_key DESC
              )
        WHERE ROWNUM = 1;
 
--
      IF orphans(l_dbkey, p_dfkey, l_currinc) THEN
--
        IF orphan_bp(l_dbkey, p_dfkey, l_currinc)
        THEN
          deb('old_chunks: had to kill plan', AM_DEBUG_HIGH);
          RETURN;
        END IF;
 
--
        l_maxckpid := l_ckpid;
        working_ckpid(l_dbkey, p_dfkey, p_vbkey, TRUE,
                      l_dbinc, l_maxckpid, l_deadinc, l_orphaninc);
 
--
        q_purge_orphan(p_type, l_dbkey, p_dfkey, p_vbkey, l_ckpscn, l_absscn,
                       l_ckpid, l_minckpid, l_maxckpid, l_dbinc,
                       l_deadinc, l_orphaninc);
      ELSE
        q_purge_basic(p_type, p_dfkey, p_vbkey, l_dbkey, l_dbinc,
                      l_ckpscn, l_absscn, l_ckpid, l_minckpid);
      END IF;
  END CASE;
 
--
--
--
--
  IF p_type <> KBRSPLBLD_ALLPURGE THEN
    SELECT MAX(blkrank), MAX(numbytes) INTO l_maxrank, l_size
      FROM plans_details
      WHERE df_key = p_dfkey
        AND type = KBRSPLBLD_PURGE
        AND vb_key = p_vbkey
        AND blockno = 0;
 
--
--
--
--
    l_rank      := 2;
    l_sumbytes  := 0;
    l_lastblk   := -1;
    l_chunksize := f_chunksize(l_dbkey) - l_size;
    FOR i IN (SELECT blockno, numbytes
              FROM plans_details
              WHERE df_key = p_dfkey
                AND type = KBRSPLBLD_PURGE
                AND vb_key = l_vbkey
                AND blockno > 0
              ORDER BY blkrank, blockno)
    LOOP
      IF l_sumbytes + i.numbytes > l_chunksize THEN
        IF l_lastblk < i.blockno - 1 THEN -- Cannot have dup blockno
          UPDATE plans_details
            SET blockno = i.blockno - 1
              WHERE df_key = p_dfkey
                AND type = KBRSPLBLD_PURGE
                AND vb_key = l_vbkey
                AND blkrank = l_rank
                AND blockno = 0;
          EXIT WHEN SQL%ROWCOUNT = 0 OR l_rank = l_maxrank;
          l_rank := l_rank + 1;
        END IF;
 
        l_sumbytes := 0;
      END IF;
 
      l_lastblk := i.blockno;
      l_sumbytes := l_sumbytes + i.numbytes;
    END LOOP;
 
    COMMIT;
  END IF;
 
  dbms_ra_scheduler.check_for_interrupt;
END old_chunks;
 
 
--
--
--
--
--
--
--
PROCEDURE restricted_purge(p_dfkey    IN NUMBER, -- Datafile key
                           p_vbkey    IN NUMBER, -- Virtual backup id
                           p_type     IN NUMBER, -- plan type
                           p_dbkey IN NUMBER,
                           p_chunks IN NUMBER)
 IS
  l_sum   NUMBER := 0;
  l_count NUMBER := 0;
  l_avail NUMBER := (f_chunksize(p_dbkey) * p_chunks) -
                    (f_chunksize(p_dbkey) * 0.15); /* do not fill last chunk */
BEGIN
--
  DELETE FROM plans_details
    WHERE chunkno IN
          (SELECT chunkno
           FROM plans_details
           WHERE blkrank > 1
             AND blockno = 0);
 
--
--
--
  FOR i IN (SELECT chunkno, SUM(numbytes) used
            FROM plans_details
            WHERE df_key = p_dfkey
              AND type = p_type
              AND vb_key = p_vbkey
              AND blockno >= 0
            GROUP BY chunkno
            ORDER BY used DESC)
  LOOP
    EXIT WHEN l_sum + i.used > l_avail;
 
    l_count := l_count + 1;
    l_sum := l_sum + i.used;
  END LOOP;
 
--
--
  DELETE FROM plans_details
    WHERE chunkno NOT IN
          (SELECT chunkno
           FROM (SELECT chunkno, SUM(numbytes) used
                 FROM plans_details
                 WHERE df_key = p_dfkey
                   AND type = p_type
                   AND vb_key = p_vbkey
                   AND blockno >= 0
                 GROUP BY chunkno
                 ORDER BY used DESC)
           WHERE ROWNUM < l_count)
      AND df_key = p_dfkey
      AND type = p_type
      AND vb_key = p_vbkey
      AND blockno >= 0;
END restricted_purge;
 
 
--
--
--
--
--
--
PROCEDURE optimize_blocks(p_dfkey        IN  NUMBER,
                          p_vbkey        IN  NUMBER, -- Virtual backup id
                          p_type         IN  NUMBER, -- plan type
                          p_stored       OUT NUMBER,
                          p_needs        OUT NUMBER)
 IS
  l_size      NUMBER;
  l_chunk     NUMBER;
  l_count     NUMBER;
  l_krbphs    NUMBER;
  l_dbkey     NUMBER;
BEGIN
--
  deb('optimize_blocks for df_key ' || p_dfkey, AM_DEBUG_MED);
 
--
  SELECT MAX(db_key) INTO l_dbkey
    FROM dbinc i, df f
    WHERE f.dbinc_key = i.dbinc_key
      AND f.df_key = p_dfkey;
 
--
  l_size := f_chunksize(l_dbkey) * 0.80;
  DELETE ( 
    SELECT /*+
             QB_NAME(pd)
             USE_HASH(pdc@pdc)
             LEADING(@pd pd@pd)
             OPT_PARAM('optimizer_dynamic_sampling' 0)
             OPT_PARAM('_optimizer_adaptive_cursor_sharing' 'false')
             OPT_PARAM('_optimizer_extended_cursor_sharing_rel' 'none')
             OPT_PARAM('_optimizer_use_feedback' 'false')
           */
           pd.ROWID
      FROM plans_details pd
         , (
           SELECT /*+ QB_NAME(pdc) */
                  chunkno
             FROM plans_details pdc
            WHERE df_key = p_dfkey
              AND type = p_type
              AND vb_key = p_vbkey
              AND blockno >= 0
            GROUP BY chunkno
           HAVING SUM(numbytes) > l_size
           ) pdc
     WHERE pd.df_key = p_dfkey
       AND pd.type = p_type
       AND pd.vb_key = p_vbkey
       AND pd.blockno >= 0
       AND pd.chunkno = pdc.chunkno
  );
  deb('optimize_blocks deleted ' || SQL%ROWCOUNT);
 
--
  SELECT COUNT(DISTINCT chunkno) INTO l_count
    FROM plans_details
    WHERE df_key = p_dfkey
      AND type = p_type
      AND vb_key = p_vbkey;
 
  deb('optimize_blocks reading ' || l_count || ' chunks', AM_DEBUG_MED);
 
  IF l_count < 2
  THEN
    p_needs := 0;
    p_stored := 0;
  ELSE
    p_needs := l_count;
    p_stored := 1;
  END IF;
END optimize_blocks;
 
--
--
--
--
--
--
--
PROCEDURE purge_pool(p_dbkey      IN    NUMBER,
                     p_type       IN    NUMBER,
                     p_qtype      IN    NUMBER,
                     p_dfkey      IN    NUMBER,
                     p_vbkey      IN    NUMBER,
                     p_dflocked   IN    BOOLEAN DEFAULT FALSE)
 IS
--
  CURSOR debugc (c_type IN NUMBER, c_dfkey IN NUMBER, c_vbkey IN NUMBER)
  IS
  SELECT /*+ 
         QB_NAME(m)
         OPT_PARAM('optimizer_adaptive_plans' 'false')
         OPT_PARAM('optimizer_dynamic_sampling' 0)
         USE_HASH(@m b@m)
         LEADING(@m d@m b@m)
         INDEX(@m b@m blocks_u)
         */  
         b.blockno, b.scn, b.chunkno
    FROM blocks b
       , ( 
         SELECT /*+ NO_MERGE */
                DISTINCT chunkno
           FROM plans_details
          WHERE type = c_type
            AND vb_key = c_vbkey
            AND df_key = c_dfkey
         ) d 
   WHERE b.df_key = c_dfkey
     AND d.chunkno = b.chunkno
   ORDER BY b.blockno, b.scn, b.chunkno;
 
  CURSOR delete_chunks(c_slkey IN NUMBER) IS
    SELECT chunkno, filename
      FROM chunks JOIN
           (SELECT DISTINCT df_key, chunkno
            FROM plans_details
            WHERE type = p_qtype
              AND df_key = p_dfkey
              AND vb_key = p_vbkey
           )
           USING (df_key, chunkno)
      WHERE df_key = p_dfkey
        AND sl_key = c_slkey
      ORDER BY chunkno;
 
  l_chunknolst   dbms_sql.number_table;
  l_chunknamlst  dbms_sql.varchar2_table;
  l_count        NUMBER;
  l_dflocked     BOOLEAN := FALSE;
 
--
--
--
  TYPE chunkptr_t IS TABLE OF BINARY_INTEGER;
  l_chunknoptr   chunkptr_t := chunkptr_t();
  l_ptrfound     BINARY_INTEGER;
BEGIN
  deb('purge_pool: dbkey ' || p_dbkey ||
      ', dfkey ' || p_dfkey || ', vbkey ' || p_vbkey, AM_DEBUG_MED);
 
--
  IF debug = AM_DEBUG_HIGH THEN
    FOR x IN debugc(p_qtype, p_dfkey, p_vbkey) LOOP
      deb('purge_pool bno ' || x.blockno ||
          ', scn ' || x.scn ||
          ', dfkey ' || p_dfkey ||
          ', chunk ' || x.chunkno, AM_DEBUG_HIGH);
    END LOOP;
  END IF;
 
--
--
  IF p_type = KBRSPLBLD_ALLPURGE THEN
--
--
    SELECT count(*) INTO l_count
      FROM vbdf v, bp p, bdf d
      WHERE v.df_key = p_dfkey
        AND v.vb_key = p.vb_key
        AND v.db_key = p.db_key
        AND p.status != 'D'
        AND d.bs_key = p.bs_key
        AND d.file# = v.file#
        AND d.ckp_scn = v.ckp_scn
        AND d.dbinc_key = v.dbinc_key;
--
    IF l_count > 0 THEN
      deb('purge_pool: Live BP during all purge on vbkey ' || p_vbkey,
          AM_DEBUG_LOW);
      RETURN;
    END IF;
  END IF;
 
--
--
--
  IF NOT p_dflocked THEN
    dbms_ra_int.write_lock(dbms_ra_int.KEY_DF, p_dfkey);
    l_dflocked := TRUE;
  END IF;
 
--
--
  dbms_ra_scheduler.check_for_interrupt(RESTART_PURGE_DEL_BLOCKS);
 
  dbms_ra_int.info_start('purge_pool ',
                         'dfkey ' || p_dfkey || ', vbkey ' || p_vbkey);
 
--
--
  FOR s IN (SELECT sl_key FROM odb WHERE db_key = p_dbkey
            UNION ALL
            SELECT sl_key FROM dbsl WHERE db_key = p_dbkey)
  LOOP
    OPEN delete_chunks(s.sl_key);
    LOOP
      FETCH delete_chunks
        BULK COLLECT INTO l_chunknolst, l_chunknamlst
        LIMIT MAXDELCHUNKS;
        EXIT WHEN l_chunknolst.COUNT = 0;
 
--
--
--
--
--
--
--
--
--
--
--
--
 
--
      l_chunknoptr.EXTEND(l_chunknolst.COUNT);
      FOR i IN 1..l_chunknolst.COUNT
      LOOP
        l_chunknoptr(i) := i;
      END LOOP;
 
      WHILE (l_chunknoptr.COUNT > 0)
      LOOP
        l_count := CEIL(TOTBLKPRCHNKS / l_chunknoptr.COUNT);
        deb(
           'purge_pool: dfkey ' || p_dfkey
        || ', deleting ' || l_count
        || ' rows per chunk, for ' || l_chunknoptr.COUNT
        || ' chunks'
        , AM_DEBUG_MED
        );
        FORALL i IN VALUES OF l_chunknoptr
          DELETE /*+
                   DYNAMIC_SAMPLING(b 0)
                   INDEX(b blocks_c)
                   NO_INDEX_FFS(b)
                 */
                 blocks b
           WHERE df_key = p_dfkey
             AND chunkno = l_chunknolst(i)
             AND ROWNUM <= l_count;
        l_ptrfound := 0;
        FOR i IN 1..l_chunknoptr.COUNT
        LOOP
--
--
--
--
--
          IF (SQL%BULK_ROWCOUNT(l_chunknoptr(i)) = l_count)
          THEN
            l_ptrfound := l_ptrfound + 1;
            l_chunknoptr(l_ptrfound) := l_chunknoptr(i);
          END IF;
        END LOOP;
        COMMIT;
        l_chunknoptr.TRIM(l_chunknoptr.COUNT - l_ptrfound);
      END LOOP;
 
--
      FOR i IN 1 .. l_chunknolst.COUNT LOOP
        deb('purge_pool: dfkey ' || p_dfkey ||
            ', chunk ' || l_chunknolst(i), AM_DEBUG_MED);
        IF l_chunknamlst(i) IS NOT NULL THEN
          SYS.KBRSI_ICD.rsDeleteFile(l_chunknamlst(i));
        END IF;
      END LOOP;
 
--
      dbms_ra_storage.free_block_pool_chunks(s.sl_key, p_dbkey,
                                             p_dfkey, l_chunknolst);
 
      EXIT WHEN l_chunknolst.COUNT < MAXDELCHUNKS;
    END LOOP;
    CLOSE delete_chunks;
  END LOOP;
 
  dbms_ra_int.info_end;
 
  IF NOT p_dflocked THEN
    dbms_ra_int.unlock(dbms_ra_int.KEY_DF, p_dfkey);
    l_dflocked := FALSE;
  END IF;
 
EXCEPTION
  WHEN OTHERS THEN
    save_error;
    IF l_dflocked THEN
      dbms_ra_int.unlock(dbms_ra_int.KEY_DF, p_dfkey);
    END IF;
    RAISE;
END purge_pool;
 
 
--
--
--
--
--
--
--
--
PROCEDURE purge_vbdf(p_dbkey      IN    NUMBER,
                     p_type       IN    NUMBER,
                     p_dfkey      IN    NUMBER,                     
                     p_vbkey      IN    NUMBER)
 IS
  l_currinc  NUMBER;
  l_scn      NUMBER := NULL;
  l_safevb   NUMBER;
  l_badvb    NUMBER;
  l_count    NUMBER;
BEGIN
  deb('purge_vbdf: dbkey ' || p_dbkey || ', type ' || p_type ||
      ', dfkey ' || p_dfkey || ', vbkey ' || p_vbkey, AM_DEBUG_MED);
 
--
  purge_lock(p_dfkey);
 
--
--
--
--
  SELECT dbinc_key INTO l_currinc
    FROM (SELECT dbinc_key
          FROM vbdf
          WHERE df_key = p_dfkey
          ORDER BY vb_key DESC
         )
    WHERE ROWNUM = 1;
 
--
--
  IF orphans(p_dbkey, p_dfkey, l_currinc) THEN
--
--
    orphan_safe(p_dbkey, p_dfkey, l_currinc, l_safevb, l_scn);
 
--
    IF NOT orphan_bp(p_dbkey, p_dfkey, l_currinc)
    AND NOT orphan_blocks(p_dbkey, p_dfkey)
    THEN
      l_safevb := p_vbkey;
    END IF;
  ELSE
    l_safevb := p_vbkey;
  END IF;
 
--
--
  IF p_type = KBRSPLBLD_ALLPURGE THEN
--
    SELECT COUNT(*) INTO l_count FROM chunks
      WHERE df_key = p_dfkey AND ROWNUM = 1;
    IF l_count = 0 THEN
      l_safevb := BIGNUM;
    END IF;
  END IF;
 
--
--
  SELECT LEAST(NVL(MAX(vb_key),l_safevb), l_safevb) INTO l_safevb 
     FROM vbdf
     WHERE state NOT IN (VBDF_COMPLETE, VBDF_OBSOLETE);
 
  deb('purge_vbdf: safevb ' || l_safevb, AM_DEBUG_MED);
 
--
--
  dbms_ra_int.write_lock(dbms_ra_int.KEY_DF, p_dfkey);
 
--
  IF debug = AM_DEBUG_HIGH THEN
    FOR i IN (SELECT dbinc_key, df_key, vb_key FROM vbdf
              WHERE df_key = p_dfkey
                AND vb_key NOT IN (SELECT vb_key FROM bp
                                   WHERE vb_key IS NOT NULL AND status != 'D')
                AND vb_key < l_safevb
                AND state = VBDF_COMPLETE) LOOP
      deb('purge_vbdf: obsolete vbdf dbinc ' || i.dbinc_key ||
          ', dfkey ' || i.df_key || ', vbkey ' || i.vb_key, AM_DEBUG_HIGH);
    END LOOP;
  END IF;
 
--
--
--
  UPDATE vbdf SET state = VBDF_OBSOLETE
    WHERE df_key = p_dfkey
      AND vb_key NOT IN (SELECT vb_key FROM bp
                         WHERE vb_key IS NOT NULL AND status != 'D')
      AND vb_key < l_safevb
      AND state = VBDF_COMPLETE;
  deb('purge_vbdf: ' || SQL%ROWCOUNT || ' vbdf rows made obsolete',
      AM_DEBUG_MED);
  COMMIT;
 
--
  dbms_ra_int.unlock(dbms_ra_int.KEY_DF, p_dfkey);
  purge_unlock(p_dfkey);
 
EXCEPTION
  WHEN OTHERS THEN
    save_error;
    dbms_ra_int.unlock(dbms_ra_int.KEY_DF, p_dfkey);
    purge_unlock(p_dfkey);
    RAISE;
END purge_vbdf;
 
 
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE reorderDF(p_type  IN NUMBER,      -- Type of KBRSPLBLD_% to perform
                    p_dfkey IN NUMBER,
                    p_vbkey IN NUMBER)
 IS
  l_dbkey         NUMBER;
  l_resume        NUMBER;
  l_needchunks    NUMBER;
  l_maxrank       NUMBER;
  l_space         NUMBER;
  l_qtype         NUMBER;
  l_count         NUMBER;
  l_complete      NUMBER;
  l_slkey         NUMBER;
  l_vbkey         NUMBER;
  l_savepoint     NUMBER;
  l_state         NUMBER;
BEGIN
  s_purge_dbinc := NULL;  /* Must start out like this. */
  l_savepoint := dbms_ra_scheduler.get_savepoint;
  deb('reorderDF: type ' || p_type ||
      ', dfkey ' || p_dfkey ||
      ', vbkey ' || p_vbkey ||
      ', savepoint ' || l_savepoint, AM_DEBUG_MED);
 
--
  purge_lock(p_dfkey);
 
  IF l_savepoint = RESTART_PURGE_OBSOLETEP THEN
    GOTO obsolete_plans;
  END IF;
 
  IF l_savepoint = RESTART_PURGE_DEL_BLOCKS THEN
    GOTO del_blocks;
  END IF;
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
  IF p_type <> KBRSPLBLD_ALLPURGE THEN
    SELECT state INTO l_state
      FROM (
            SELECT state
              FROM vbdf
             WHERE df_key = p_dfkey
               AND state IN (VBDF_OBSOLETE, VBDF_COMPLETE)
             GROUP BY state
             ORDER BY MAX(ckp_id) DESC
           )
      WHERE ROWNUM = 1;
 
    IF l_state = VBDF_OBSOLETE THEN
      deb('reorderDF: obsolete backup prevent us from purging',
          AM_DEBUG_HIGH);
      purge_unlock(p_dfkey);
      RETURN;
    END IF;
  END IF;
 
--
  planDF(p_type, p_dfkey, p_vbkey, 0, FALSE, FALSE, TRUE);
 
--
  IF p_type = KBRSPLBLD_PURGE
  OR p_type = KBRSPLBLD_OPTPURGE
  OR p_type = KBRSPLBLD_SMALLPURGE
  OR p_type = KBRSPLBLD_ALLPURGE
  OR p_type = KBRSPLBLD_DUPPURGE
  THEN
    l_qtype := KBRSPLBLD_PURGE;
  ELSE
    l_qtype := p_type;
  END IF;
 
--
--
  SELECT MAX(db_key), MAX(needchunk), MAX(numchunks), MAX(maxrank)
    INTO l_dbkey, l_needchunks, l_complete, l_maxrank
    FROM plans
    WHERE type = l_qtype
      AND vb_key = p_vbkey
      AND df_key = p_dfkey
      AND blksread IS NOT NULL;    /* We have a plan */
 
--
--
  IF l_dbkey IS NULL
  THEN
    deb('reorderDF no plan or plan null', AM_DEBUG_MED);
    dealloc_plan(p_dfkey, NULL, KBRSPLBLD_PURGE);
    purge_unlock(p_dfkey);
    RETURN;
  END IF;
 
--
--
  IF l_complete IS NULL THEN
    deb('reorderDF competing plan', AM_DEBUG_ON);
    SELECT sl_key INTO l_slkey FROM odb WHERE db_key = l_dbkey;
    dbms_ra_scheduler.avoid_sl(DBMS_RA_SCHEDULER.TASK_PURGE, l_slkey);
    RAISE dbms_ra_scheduler.e_retry_error;
  END IF;
 
--
  IF debug = AM_DEBUG_HIGH
  THEN
    SELECT used_space INTO l_space FROM odb WHERE db_key = l_dbkey;
    deb('reorderDF: Beginning space usage is ' || l_space, AM_DEBUG_HIGH);
  END IF;
 
--
  IF l_needchunks > 0 THEN
--
    dbms_ra_storage.preallocate_chunks(l_dbkey, l_needchunks, TRUE);
 
--
--
    dbms_ra_int.info_start('reorderDF prep',
                           'dfkey ' || p_dfkey || ', vbkey ' || p_vbkey);
    BEGIN
--
      lock_vb(TRUE, l_dbkey, p_dfkey, p_vbkey, l_qtype);
 
--
      sys.kbrsi_icd.rsPurgePrep(l_qtype, l_dbkey, p_vbkey, p_dfkey);
 
--
      lock_vb(FALSE, l_dbkey, p_dfkey, p_vbkey, l_qtype);
 
    EXCEPTION
      WHEN dbms_ra_scheduler.E_OAM_NOT_RUNNING THEN
        save_error;
--
--
--
--
--
        sys.kbrsi_icd.rsSetTrace(0, 1);
        deb('reorderDF retry the purgePrep: ' ||
            'dfkey ' || p_dfkey || ', vbkey ' || p_vbkey);
 
--
        deb('plan_blocks: type ' || p_type ||
            ', dfkey ' || p_dfkey ||
            ', vbkey ' || p_vbkey ||
            '  At ' || TO_CHAR(SYSDATE, 'HH24:MI:SS'), AM_DEBUG_MED);
 
        show_plan(p_vbkey, p_dfkey, p_dfkey, l_qtype);
 
        BEGIN
          sys.kbrsi_icd.rsPurgePrep(l_qtype, l_dbkey, p_vbkey, p_dfkey);
        EXCEPTION
          WHEN OTHERS THEN
            save_error;
            lock_vb(FALSE, l_dbkey, p_dfkey, p_vbkey, l_qtype);
            clear_error;
        END;
        clear_error;            
      WHEN OTHERS THEN
        save_error;
--
        lock_vb(FALSE, l_dbkey, p_dfkey, p_vbkey, l_qtype);
        RAISE;
    END;
    dbms_ra_int.info_end;
 
--
    IF p_type = KBRSPLBLD_OPTIMIZE
    THEN
      dealloc_plan(p_dfkey, NULL, KBRSPLBLD_OPTIMIZE);
      purge_unlock(p_dfkey);
      dbms_ra_scheduler.check_for_interrupt(0);     /* All done */
      RETURN;
    END IF;
  END IF;
 
--
  dbms_ra_scheduler.check_for_interrupt(RESTART_PURGE_OBSOLETEP);
 
<<obsolete_plans>>
--
  obsoletePlans(p_dfkey);
 
--
--
--
--
--
  IF s_safemode
  AND p_type <> KBRSPLBLD_ALLPURGE
  AND dbms_ra_scheduler.s_current_task <> dbms_ra_scheduler.TASK_GCOPY_COMPUTE
  THEN
    SELECT MAX(vb_key) INTO l_vbkey
      FROM vbdf WHERE df_key = p_dfkey AND state = VBDF_COMPLETE;
 
    WHILE l_vbkey > 0 LOOP
      planDF(KBRSPLBLD_PIECE, p_dfkey, l_vbkey);
 
      SELECT MAX(chunkno) INTO l_needchunks
      FROM plans_details
      WHERE TYPE = KBRSPLBLD_PIECE
        AND df_key = p_dfkey
        AND vb_key = l_vbkey
        AND blockno > 0 /* no block 0 safety check, it may be from other df */
        AND chunkno IN (SELECT chunkno FROM plans_details
                        WHERE TYPE = KBRSPLBLD_PURGE
                          AND df_key = p_dfkey
                          AND vb_key = p_vbkey
                          AND blockno <> 0);
      IF l_needchunks IS NOT NULL THEN
        deb('reorderDF failure: dfkey ' || p_dfkey ||
            ', vbkey ' || l_vbkey ||
            ', type ' || p_type ||
            ', chunk ' || l_needchunks, AM_DEBUG_LOW);
 
--
--
        dbms_ra_scheduler.check_for_interrupt(0);
 
        SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(
             DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM,
                                   'purge check dfkey ' || p_dfkey ||
                                   ', vbkey ' || l_vbkey ||
                                   ', type ' || p_type ||
                                   ', chunk ' || l_needchunks);
      END IF;
 
--
      IF l_vbkey > p_vbkey
      THEN l_vbkey := p_vbkey;
      ELSE l_vbkey := 0;
      END IF;
    END LOOP;
  END IF;
 
<<del_blocks>>
--
  purge_pool(l_dbkey, p_type, l_qtype, p_dfkey, p_vbkey);
 
--
--
  dealloc_plan(p_dfkey, NULL, KBRSPLBLD_PURGE);
 
--
  purge_unlock(p_dfkey);
 
EXCEPTION
  WHEN OTHERS THEN
    save_error;
    purge_unlock(p_dfkey);
    RAISE;
END reorderDF;
 
 
--
--
--
--
--
--
--
--
--
PROCEDURE purgeRes(p_dfkey      IN  NUMBER,
                   p_vbkey      IN  NUMBER,
                   p_savepoint  IN  NUMBER,
                   p_small      OUT BOOLEAN)
 IS
  l_dbkey         NUMBER;
  l_space         NUMBER;
  l_maxchunks     NUMBER;
  l_reserved      NUMBER;
  l_needchunks    NUMBER;
BEGIN
  deb('purgeRes: dfkey ' || p_dfkey ||
      '  vbkey ' || p_vbkey, AM_DEBUG_LOW);
 
--
  purge_lock(p_dfkey);
 
--
  p_small := FALSE;
 
--
  planDF(KBRSPLBLD_PURGE, p_dfkey, p_vbkey, 0, FALSE, FALSE, TRUE);
 
--
  SELECT MAX(db_key), MAX(needchunk)
    INTO l_dbkey, l_needchunks
    FROM plans
    WHERE type = KBRSPLBLD_PURGE
      AND vb_key = p_vbkey
      AND df_key = p_dfkey
      AND blksread IS NOT NULL;
 
--
--
  IF l_dbkey IS NULL OR l_needchunks IS NULL
  THEN
    deb('purgeRes no plan or plan null', AM_DEBUG_LOW);
 
--
    dbms_ra_scheduler.raise_purge_priority(p_dfkey);
 
    purge_unlock(p_dfkey);
    RETURN;
  END IF;
 
--
  IF debug = AM_DEBUG_HIGH
  THEN
    SELECT used_space INTO l_space FROM odb WHERE db_key = l_dbkey;
    deb('purgeRes: Beginning space usage is ' || l_space, AM_DEBUG_HIGH);
  END IF;
 
--
--
  dbms_ra_int.write_lock(dbms_ra_int.KEY_DF, p_dfkey);
 
--
  IF l_needchunks > 0 THEN
    l_reserved := dbms_ra_storage.reserve_block_pool_space(
                                                p_db_key => l_dbkey,
                                                p_chunks => l_needchunks,
                                                p_maxchunks => l_maxchunks);
  END IF;
 
--
--
--
--
  IF (l_reserved < l_needchunks)
  THEN
    deb('purgeRes: Space stress,  ' ||
        '  df_key ' || p_dfkey ||
        '  vbkey ' || p_vbkey ||
        '  reserved ' || l_reserved ||
        '  needchunks ' || l_needchunks,
        AM_DEBUG_LOW);
 
--
    IF dbms_ra_scheduler.set_blocking_purge(l_dbkey) IS NOT NULL THEN
      dbms_ra_storage.finish_block_pool_chunk(p_db_key => l_dbkey);
      dbms_ra_int.unlock(dbms_ra_int.KEY_DF, p_dfkey);
      purge_unlock(p_dfkey);
      RAISE dbms_ra_scheduler.e_retry_error;
    END IF;
 
--
    planDF(p_vbkey, p_dfkey, KBRSPLBLD_SMALLPURGE, l_reserved);
    p_small := TRUE;
  END IF;
 
--
  IF l_needchunks > 0 THEN
    dbms_ra_int.info_start('purgeRes prep',
                           'dfkey ' || p_dfkey || ', vbkey ' || p_vbkey);
    BEGIN
--
      lock_vb(TRUE, l_dbkey, p_dfkey, p_vbkey, KBRSPLBLD_PURGE);
 
--
      sys.kbrsi_icd.rsPurgePrep(KBRSPLBLD_PURGE, l_dbkey, p_vbkey, p_dfkey);
 
--
      lock_vb(FALSE, l_dbkey, p_dfkey, p_vbkey, KBRSPLBLD_PURGE);
 
    EXCEPTION
      WHEN OTHERS THEN
        save_error;
--
        lock_vb(FALSE, l_dbkey, p_dfkey, p_vbkey, KBRSPLBLD_PURGE);
        RAISE;
    END;
    dbms_ra_int.info_end;
  END IF;
 
--
  obsoletePlans(p_dfkey, TRUE#, FALSE#);
 
--
  purge_pool(l_dbkey, KBRSPLBLD_PURGE, KBRSPLBLD_PURGE, p_dfkey, p_vbkey, TRUE);
 
--
  dbms_ra_storage.finish_block_pool_chunk(p_db_key => l_dbkey);
 
--
  dbms_ra_int.unlock(dbms_ra_int.KEY_DF, p_dfkey);
 
--
  purge_unlock(p_dfkey);
 
--
  IF debug = AM_DEBUG_HIGH
  THEN
    SELECT used_space INTO l_space FROM odb WHERE db_key = l_dbkey;
    deb('purgeRes: Ending    space usage is ' || l_space, AM_DEBUG_HIGH);
  END IF;
 
EXCEPTION
  WHEN dbms_ra_scheduler.e_retry_error THEN
    save_error;
    purge_unlock(p_dfkey);
--
--
--
    dbms_lock.sleep(3);
    dbms_ra_scheduler.s_pending_interrupt := 0;
    clear_error;
  WHEN OTHERS THEN
    save_error;
    purge_unlock(p_dfkey);
    RAISE;
END purgeRes;
 
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE set_next_retention(p_dbkey      IN NUMBER,
                             p_currinc    IN NUMBER,
                             p_outscn    OUT NUMBER)
 IS
--
--
--
--
--
--
--
--
--
--
--
  CURSOR rnkdf(c_purgescn NUMBER, c_currinc NUMBER, c_oldtime DATE) IS
    SELECT DISTINCT ckp_scn, ckp_time,
                    DENSE_RANK() OVER (ORDER BY ckp_scn) rnk
      FROM bs, bp, bdf d,
           (SELECT db_key, dbinc_key, reset_scn, reset_time, db_name,
                   NVL(PRIOR reset_scn, BIGNUM) next_reset_scn
            FROM dbinc
            START WITH dbinc_key = c_currinc
            CONNECT BY PRIOR parent_dbinc_key = dbinc_key) i
      WHERE bs.bs_key = d.bs_key
        AND bs.bs_key = bp.bs_key
        AND i.dbinc_key = d.dbinc_key
        AND bp.status != 'D'
        AND bp.ba_access = 'L'    /* Only backups AM wrote */
        AND bp.lib_key IS NULL    /* Only backups on disk */
        AND bs.keep_options = 0   /* Skip keep backups */
        AND d.file# = 1
        AND d.ckp_scn > c_purgescn
        AND d.ckp_time > c_oldtime
        AND d.ckp_scn >= i.reset_scn
        AND d.ckp_scn <  i.next_reset_scn
      ORDER BY rnk;
 
  l_purgescn     NUMBER;
  l_purgeinc     NUMBER;
  l_oldtime      DATE;
  l_goaltime     DATE;
  l_bs2time      odb.bs2_timestamp%type;
  l_unknown      BOOLEAN := FALSE;
  l_ckpscn1      NUMBER;
  l_ckptime1     DATE;
  l_rnk1         NUMBER;
  l_ckpscn2      NUMBER;
  l_ckptime2     DATE;
  l_rnk2         NUMBER;
  l_ckpscn3      NUMBER;
  l_ckptime3     DATE;
  l_rnk3         NUMBER;
BEGIN
--
--
--
  SELECT bs2_timestamp, (sysdate - recovery_window_goal), purge_scn, purge_inc
    INTO l_oldtime, l_goaltime, l_purgescn, l_purgeinc
    FROM odb
    WHERE db_key = p_dbkey;
 
--
--
  IF l_purgeinc != p_currinc THEN
    l_purgescn := 0;
    l_oldtime := NULL;
  END IF;
 
--
  IF l_purgescn = BIGNUM THEN
    l_purgescn := 0;
    l_oldtime := sysdate; /* will force one backup purge */
  END IF;
 
--
--
--
--
--
  IF l_oldtime IS NULL THEN
    l_unknown := TRUE;  /* Input purge values unreliable */
    SELECT MIN(ckp_scn)+1, MIN(ckp_time)
      INTO l_purgescn, l_oldtime
      FROM bs s, bp p, bdf d
      WHERE p.db_key = p_dbkey
        AND s.bs_key = d.bs_key
        AND s.bs_key = p.bs_key
        AND p.status != 'D'
        AND p.ba_access = 'L'    /* Only backups AM wrote */
        AND p.lib_key IS NULL    /* Only backups on disk */
        AND s.keep_options = 0   /* Skip keep backups */
        AND d.file# = 1;
  END IF;
 
--
  IF l_oldtime > l_goaltime THEN
    l_oldtime := to_date('01-1-2012 00:00:00', 'DD-MM-YYYY HH24:MI:SS');
  ELSE
    l_oldtime := l_oldtime + ((l_goaltime - l_oldtime) / 2);
  END IF;
 
--
--
--
  OPEN rnkdf(l_purgescn, p_currinc, l_oldtime);
  FETCH rnkdf INTO l_ckpscn1, l_ckptime1, l_rnk1;
  FETCH rnkdf INTO l_ckpscn2, l_ckptime2, l_rnk2;
  FETCH rnkdf INTO l_ckpscn3, l_ckptime3, l_rnk3;
  CLOSE rnkdf;
 
--
  IF l_ckpscn2 IS NOT NULL THEN
    l_purgescn := trunc(l_ckpscn1 + ((l_ckpscn2 - l_ckpscn1) / 2));
  ELSE
    l_purgescn := BIGNUM;
  END IF;
 
--
--
--
--
--
  IF l_ckptime3 IS NOT NULL THEN
    l_bs2time := l_ckptime2 + ((l_ckptime3 - l_ckptime2) / 2);
  ELSE
    IF l_ckptime1 IS NULL THEN
      l_bs2time := sysdate;
    ELSE
      l_bs2time := l_ckptime1;
    END IF;
  END IF;
 
--
--
--
--
--
--
--
--
  UPDATE odb SET purge_scn = l_purgescn,
                 purge_inc = p_currinc,
                 bs2_timestamp = l_bs2time
    WHERE db_key = p_dbkey;
  COMMIT;
  deb('set_next_retention' ||
      ': Time is ' || to_char(l_bs2time, 'DD-MM-YY HH24:MI:SS') ||
      ', SCN is ' || l_purgescn,
      AM_DEBUG_MED);
  IF l_bs2time IS NULL THEN
    SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(
                                    DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM,
                                    'Bad bs2timestamp');
  END IF;
 
--
--
--
  IF l_bs2time > l_goaltime AND l_unknown THEN
    p_outscn := NULL;
  ELSE
    p_outscn := l_purgescn;
  END IF;
END set_next_retention;
 
 
--
--
--
--
--
--
PROCEDURE purgeObsolete(p_slkey      IN    NUMBER,
                        p_dbkey      IN    NUMBER,
                        p_notasks    IN    BOOLEAN)
 IS
  l_rlgscn      NUMBER;
  l_rlgtime     DATE;
  l_dbname      VARCHAR2(30);
  l_dbid        NUMBER;
  l_dbun        node.db_unique_name%TYPE;
  l_bskey       NUMBER;
  l_currinc     NUMBER;
  l_purgescn    NUMBER;
  l_ret         BOOLEAN;
  l_firstcall   BOOLEAN := TRUE;
  l_stat        VARCHAR(10);
  l_nodelete    BOOLEAN := TRUE;
  l_advance     BOOLEAN := TRUE;
  l_purgeknows  NUMBER;
  l_delkey      NUMBER;
  l_delname     VARCHAR(512);
  l_count       NUMBER;
  l_vbkey       NUMBER;
  lbRec         dbms_rcvman.lbRec_t := NULL;
  lbCursor      dbms_rcvman.lbCursor_t;
--
  l_slkey         NUMBER;
  l_space         NUMBER;
  l_allocated     NUMBER;
  l_usedspace     NUMBER;
  l_freespace     NUMBER;
  l_chunkspace    NUMBER;
  l_chunkcount    NUMBER;
  l_filchunkspace NUMBER;
  l_checktape     NUMBER := 0;
  l_retry         BOOLEAN := FALSE;
 
--
--
--
--
--
--
  CURSOR dieingBP(c_dbkey NUMBER) IS
    SELECT handle, bp_key
      FROM bp JOIN bs USING (db_key, bs_key)
      WHERE ba_access = 'L'
        AND bp.status = 'A'
        AND db_key = c_dbkey
      ORDER BY NVL(keep_options, -1),
               NVL(vb_key, 0),
               bck_type,
               bs.completion_time;
BEGIN
--
  SELECT curr_dbinc_key, db_id, reset_scn, reset_time, db_name
    INTO l_currinc, l_dbid, l_rlgscn, l_rlgtime, l_dbname
    FROM db d, dbinc i
    WHERE d.curr_dbinc_key = i.dbinc_key
      AND i.db_key = p_dbkey
      AND d.db_key = p_dbkey;
 
--
--
--
  set_next_retention(p_dbkey, l_currinc, l_purgescn);
  IF l_purgescn IS NULL THEN
    RETURN;
  END IF;
 
--
--
--
  SELECT DECODE(not_taped_state, 'B', 0, 'C', 0, NULL, 0, 1) INTO l_checktape
    FROM odb WHERE db_key = p_dbkey;
 
--
  deb('purgeObsolete: dbkey ' || p_dbkey ||
      ', setUntilScn ' || to_char(l_purgescn), AM_DEBUG_MED);
 
--
  SELECT  RTRIM(LTRIM(value)) INTO l_dbun
    FROM sys.v_$parameter WHERE LOWER(name)='db_unique_name';
  dbms_rcvman.resetAll;
  dbms_rcvman.setDatabase(db_name        => l_dbname,
                          reset_scn      => l_rlgscn,
                          reset_time     => l_rlgtime,
                          db_id          => l_dbid,
                          db_unique_name => l_dbun,
                          site_aware     => TRUE,
                          dummy_instance => FALSE,
                          ors_instance   => TRUE);
 
  dbms_rcvman.setAllIncarnations(TRUE);
  dbms_rcvman.setArchiveFileScopeAttributes(logs_shared => 1);
  dbms_rcvman.setBackupFileScopeAttributes(disk_backups_shared => 0,
                                           tape_backups_shared => 1);
 
  dbms_rcvman.setUntilScn(l_purgescn);
  dbms_rcvman.setDeviceType('SBT_TAPE');
  dbms_rcvman.setOrsFile(localOnly => TRUE, libKey => NULL);
  dbms_rcvman.setNeedObsoleteData(TRUE);
 
--
 
  l_ret := TRUE;
  WHILE (l_ret)
  LOOP
    l_ret := dbms_rcvman.listBackup(lbRecOut      => lbRec,
                                    firstcall     => l_firstcall,
                                    only_obsolete => TRUE,
                                    redundancy    => 1,
                                    piped_call    => FALSE,
                                    lbCursor      => lbCursor,
                                    lbState       => dbms_rcvman.lbStatePck);
    l_firstcall := FALSE;
 
    IF lbRec.pkey IS NOT NULL AND
       lbRec.file_type = dbms_rcvman.piece_txt AND
       (lbRec.status = dbms_rcvman.available_txt OR
        lbRec.status = dbms_rcvman.expired_txt   OR
        lbRec.status = dbms_rcvman.unavailable_txt) AND
       (l_checktape = 0 OR isTaped(p_dbkey, lbRec.pkey, lbRec.bs_key))
    THEN
--
      SELECT COUNT(*), MAX(vb_key) INTO l_count, l_vbkey
        FROM bp WHERE bp_key = lbRec.pkey AND status != 'D';
 
--
      l_delkey := NULL;
      IF l_vbkey IS NOT NULL THEN
        SELECT MAX(bp_key) INTO l_delkey
          FROM bp
          WHERE bs_key = lbRec.bs_key
            AND ba_access != 'U'
            AND lib_key IS NULL
            AND vb_key IS NULL
            AND status != 'D';
 
--
--
--
        IF l_delkey IS NOT NULL THEN
          SELECT handle INTO l_delname FROM bp WHERE bp_key = l_delkey;
 
          dbms_ra_storage.free_backup_piece_opt(
              p_dbkey     => p_dbkey,
              p_piecename => l_delname,
              p_db_slkey  => p_slkey,
              p_dbid      => l_dbid,
              p_currinc   => l_currinc,
              p_bpkey     => l_delkey,
              p_libkey    => NULL,
              p_notasks   => p_notasks);
          l_nodelete := FALSE; 
          l_advance := FALSE;  -- We will still have vb at this scn
        END IF;
      END IF;
 
--
      IF l_delkey IS NULL AND l_count > 0 THEN
        dbms_ra_storage.free_backup_piece_opt(
            p_dbkey     => p_dbkey,
            p_piecename => lbRec.fname,
            p_db_slkey  => p_slkey,
            p_dbid      => l_dbid,
            p_currinc   => l_currinc,
            p_bpkey     => lbRec.pkey,
            p_libkey    => lbRec.bp_lib_key,
            p_notasks   => p_notasks);
        l_nodelete := FALSE;
      END IF;
      dbms_ra_scheduler.check_for_interrupt;
    END IF;
  END LOOP;
 
  IF l_nodelete THEN
    deb('purgeObsolete: NODELETE IS TRUE, scn ' || l_purgescn, AM_DEBUG_MED);
  ELSE
    deb('purgeObsolete: NODELETE IS FALSE', AM_DEBUG_MED);
  END IF;
 
--
--
--
  IF l_nodelete AND l_purgescn = BIGNUM THEN
--
    IF s_purgeknows IS NULL THEN
      SELECT max(bp_key) INTO s_purgeknows FROM bp WHERE db_key = p_dbkey;
    ELSE
--
      SELECT max(bp_key) INTO l_purgeknows FROM bp WHERE db_key = p_dbkey;
      IF l_purgeknows != s_purgeknows THEN
        s_purgeknows := NULL;
      ELSE
--
--
        deb('purgeObsolete: Not all data can be restored.', AM_DEBUG_ON);
 
--
--
        FOR b IN dieingBP(p_dbkey) LOOP
          BEGIN
            dbms_ra_storage.free_backup_piece_opt(p_dbkey     => p_dbkey,
                                                  p_piecename => b.handle,
                                                  p_db_slkey  => p_slkey,
                                                  p_dbid      => l_dbid,
                                                  p_currinc   => l_currinc,
                                                  p_bpkey     => b.bp_key,
                                                  p_libkey    => null,
                                                  p_notasks   => p_notasks);
            l_retry := FALSE;
            EXIT;
          EXCEPTION
            WHEN dbms_ra_scheduler.e_retry_error THEN
              save_error;
              NULL;  -- Try another backup
              l_retry := TRUE;
              clear_error;
            WHEN OTHERS THEN 
              save_error;
              RAISE;
          END;
        END LOOP;
        IF l_retry THEN
          RAISE dbms_ra_scheduler.e_retry_error;
        END IF;
      END IF;
    END IF;
  END IF;
END purgeObsolete;
 
 
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE process_allfiles (p_dbkey    IN  NUMBER,
                            p_bskey    IN  NUMBER,
                            p_bpkey    IN  NUMBER,
                            p_toname   IN  VARCHAR2,
                            p_hasdups  IN  BOOLEAN,
                            p_update   IN  BOOLEAN)
 IS
  l_state         BINARY_INTEGER;
  l_node          VARCHAR2(255);
  l_devtype       VARCHAR2(512);
  l_params        VARCHAR2(1024);
  l_pieces_done   BINARY_INTEGER;
  l_datafiles     BOOLEAN;
  l_incremental   BOOLEAN;
  l_fromdisk      BOOLEAN;
  l_device        BOOLEAN;
  l_files         BINARY_INTEGER;
  l_check_logical BOOLEAN := FALSE;
  l_handle        VARCHAR2(512);
  l_tmphandle     VARCHAR2(512);
  l_tag           VARCHAR2(31);
  l_recid         NUMBER;
  l_stamp         NUMBER;
  l_size          NUMBER;
  l_count         NUMBER;
  l_done          BOOLEAN;
  l_outhandle     VARCHAR2(512);
  l_outbpcfkey    NUMBER;
  l_outbpspkey    NUMBER;
  l_outtag        VARCHAR2(31);
  l_failover      BOOLEAN := FALSE;
  l_amflags       BINARY_INTEGER := SYS.DBMS_BACKUP_RESTORE.KRBRCB_ORS_POOL;
  l_slkey         NUMBER;
  l_ilevel        NUMBER;
  l_outbpkey      NUMBER;
  l_blksize       NUMBER;
  l_bcfkey        NUMBER := NULL;
  l_bsfkey        NUMBER := NULL;
  l_filnolst      NOLST; -- Array of number
  l_dfkeylst      NOLST; -- Array of number
  l_tsnmlst       NMLST; -- Array of varchar2(30)
  l_levellst      NOLST; -- Array of number
  task_rec        task%ROWTYPE;
  l_lib_key       NUMBER;
  l_ct_key        NUMBER;
  l_sig1          NUMBER; -- safemode signature check
  l_sig2          NUMBER; -- safemode signature check
  l_chunksize     NUMBER := f_chunksize(p_dbkey);
BEGIN
  deb('Process_allfiles - bpkey ' || p_bpkey || ', bskey ' || 
      p_bskey, AM_DEBUG_MED);
 
--
  SELECT max(bcf_key) INTO l_bcfkey
    FROM BCF
    WHERE bs_key = p_bskey;
 
--
  SELECT max(bsf_key) INTO l_bsfkey
    FROM BSF
    WHERE bs_key = p_bskey;
 
--
--
--
--
  SELECT handle, tag, bp_recid, bp_stamp, lib_key,
         bytes / (CASE compressed WHEN 'NO' THEN 2 ELSE 1 END)
    INTO l_handle, l_tag, l_recid, l_stamp, l_count,
         l_size
    FROM bp
    WHERE bp_key = p_bpkey;
  l_fromdisk := (l_count IS NULL);
 
--
  SELECT block_size INTO l_blksize FROM bs WHERE bs_key = p_bskey;
 
--
  IF NOT l_fromdisk
  THEN
--
    SELECT lib.parms, lib.lib_key
      INTO l_params, l_lib_key
      FROM sbt_lib_desc lib, bp
      WHERE lib.lib_key = bp.lib_key
        AND bp.handle = l_handle
        AND bp.db_key = p_dbkey;
  END IF;
 
--
--
  SELECT * BULK COLLECT INTO l_filnolst, l_tsnmlst, l_dfkeylst, l_levellst
    FROM (SELECT d.file# filno, ts.ts_name, f.df_key,
                 incrLevel(d.create_scn, d.incr_scn) ilevel
          FROM bdf d, df f, ts
          WHERE f.file# = d.file#
            AND f.create_scn = d.create_scn
            AND f.dbinc_key = d.dbinc_key
            AND f.dbinc_key = ts.dbinc_key
            AND f.ts# = ts.ts#
            AND f.ts_pdbinc_key = ts.pdbinc_key
            AND d.bs_key = p_bskey
          GROUP BY d.file#, ts.ts_name, f.df_key, 
                   d.create_scn, d.incr_scn)
    ORDER BY ilevel;  /* Level 0, followed by level 1 */
 
--
--
--
--
--
  IF p_update THEN
    SELECT COUNT(*) INTO l_count
      FROM vbdf WHERE vb_key = saved_vbkey;
 
    IF l_count = l_dfkeylst.count THEN
--
--
--
--
      SELECT COUNT(*) INTO l_count
        FROM vbdf v, bp p
        WHERE v.vb_key = saved_vbkey
          AND v.vcbp_key = p.bp_key
          AND p.bs_key = p_bskey
          AND ROWNUM = 1;
      IF l_count > 0 THEN
        l_amflags := l_amflags + SYS.DBMS_BACKUP_RESTORE.KRBRCB_ORS_UPDKRBPH;
      END IF;
    ELSE
      l_amflags := l_amflags + SYS.DBMS_BACKUP_RESTORE.KRBRCB_ORS_NOKRBPH;
--
      SELECT krbph_chunkno, krbph_dfkey INTO saved_krbph, saved_krbphdf
        FROM vbdf
        WHERE vb_key = saved_vbkey
          AND ROWNUM = 1;
    END IF;
 
    deb('Process_allfiles update - bpkey ' || p_bpkey ||
        ', bskey ' || p_bskey ||
        ', vbkey ' || saved_vbkey ||
        ', rsflags ' || l_amflags, AM_DEBUG_MED);
  END IF;
 
--
  dbms_ra_storage.preallocate_chunks(p_dbkey,
                                     CEIL(l_size / l_chunksize),
                                     TRUE);
 
--
--
--
--
  l_ilevel := 0;
  WHILE l_ilevel < 2 LOOP
--
    IF l_bcfkey IS NULL AND l_bsfkey IS NULL AND l_levellst(1) = 1 THEN
      l_ilevel := 1;
    END IF;
 
--
    IF l_fromdisk THEN
      l_devtype := sys.dbms_backup_restore.deviceAllocate(
                         ident    => 'ORA_DISK_1',
                         node     => l_node,
                         type     => null,
                         dupcnt   => 1);
    ELSE
      l_devtype := sys.dbms_backup_restore.deviceAllocate(
                         ident        => 'RA$SBT',
                         node         => l_node,
                         type         => 'SBT_TAPE',
                         params       => l_params,
                         dupcnt       => 1,
                         allowmts     => TRUE,
                         ors_lib_key  => l_lib_key);
    END IF;
 
    sys.dbms_backup_restore.restoreCancel(TRUE);
    sys.dbms_backup_restore.restoreStatus(l_state, l_pieces_done, l_files,
                                          l_datafiles, l_incremental,
                                          l_device);
 
    IF l_state != sys.dbms_backup_restore.restore_no_conversation THEN
      SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(
                                    DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM,
                                    'unknown conversation state');
    END IF;
 
--
    IF l_ilevel = 0 THEN
      sys.dbms_backup_restore.restoreSetDatafile(
                                          check_logical => l_check_logical
                                         ,cleanup       => FALSE
                                         ,service       => NULL
                                         ,chunksize     => l_chunksize
                                         ,rs_flags      => l_amflags);
 
--
    ELSE
      sys.dbms_backup_restore.applySetDatafile(
                                          check_logical => l_check_logical
                                         ,cleanup       => FALSE
                                         ,service       => NULL
                                         ,chunksize     => l_chunksize
                                         ,rs_flags      => l_amflags);
    END IF;
 
--
    IF l_ilevel = 0 AND l_bcfkey IS NOT NULL THEN
      deb('Process_allfiles controlfile bcf_key ' || l_bcfkey ||
          ', bskey ' || p_bskey, AM_DEBUG_MED);
      sys.dbms_backup_restore.restoreControlfileTo(cfname => p_toname,
                                                   isstby => FALSE);
    END IF;
 
--
    IF l_ilevel = 0 AND l_bsfkey IS NOT NULL THEN
      deb('Process_allfiles spfile bsf_key ' || l_bsfkey ||
          ', bskey ' || p_bskey, AM_DEBUG_MED);
      sys.dbms_backup_restore.restoreSpfileTo(pfname => p_toname,
                                              sfname => p_toname);
    END IF;
 
--
    FOR i IN 1 .. l_filnolst.count LOOP
--
--
      IF l_ilevel = 1 AND l_levellst(i) = 1 THEN
        deb('Process_allfiles1 file# ' || l_filnolst(i) ||
            ', bskey ' || p_bskey, AM_DEBUG_MED);
        sys.dbms_backup_restore.applyDataFileTo(dfnumber => l_filnolst(i),
                                                toname => p_toname,
                                                fuzziness_hint => 0,
                                                max_corrupt => 0,
                                                islevel0 => 0,
                                                recid => 0,
                                                stamp => 0);
      END IF;
 
--
      IF l_ilevel = 0 AND l_levellst(i) = 0 THEN
        deb('Process_allfiles2 file# ' || l_filnolst(i) ||
            ', bskey ' || p_bskey, AM_DEBUG_MED);
        sys.dbms_backup_restore.restoreDataFileTo(dfnumber => l_filnolst(i),
                                                  toname => p_toname,
                                                  max_corrupt => 0,
                                                  tsname => l_tsnmlst(i));
      END IF;
    END LOOP;
 
--
 
--
    sys.dbms_backup_restore.restoreSetPiece(handle   => l_handle,
                                            tag      => l_tag,
                                            fromdisk => l_fromdisk,
                                            recid    => l_recid,
                                            stamp    => l_stamp);
    sys.dbms_backup_restore.restoreBackupPiece(done      => l_done,
                                               params    => l_params,
                                               outhandle => l_outhandle,
                                               outtag    => l_outtag,
                                               failover  => l_failover);
 
--
    sys.dbms_backup_restore.restoreCancel(TRUE);
    sys.dbms_backup_restore.cfileUseCurrent;              -- release enqueue
    sys.dbms_backup_restore.deviceDeallocate;
    sys.dbms_backup_restore.set_client_info('');
    sys.dbms_backup_restore.setRmanStatusRowId(rsid=>0, rsts=>0);
 
--
    IF l_ilevel = 0 AND l_bcfkey IS NOT NULL THEN
      SELECT filesize, handle, ct_key
        INTO l_size, l_tmphandle, l_ct_key
        FROM sbt_catalog
       WHERE filename = saved_krbph_cfname
         AND filesize is not null;
      sys.kbrsi_icd.rsInspectBackupPiece(
                            handle        => l_tmphandle,
                            vbkey         => NULL,
                            bpsize        => l_chunksize,
                            chktype       => DBMS_RA_INT.KBRSCHKTYPE_FILE,
                            fno           => 0,
                            lib_key       => null, /* local disk file */
                            ct_key        => l_ct_key,
                            bpkey         => l_outbpcfkey,
                            template_key  => null);
      deb('Process_allfiles controlfile ' ||
          ' handle - ' || saved_krbph_cfname, AM_DEBUG_MED);
    END IF;
 
--
    IF l_ilevel = 0 AND l_bsfkey IS NOT NULL THEN
      SELECT filesize, handle, ct_key
        INTO l_size, l_tmphandle, l_ct_key
        FROM sbt_catalog
       WHERE filename = saved_krbph_spname
         AND filesize is not null;
      sys.kbrsi_icd.rsInspectBackupPiece(
                            handle        => l_tmphandle,
                            vbkey         => NULL,
                            bpsize        => l_chunksize,
                            chktype       => DBMS_RA_INT.KBRSCHKTYPE_FILE,
                            fno           => 0,
                            lib_key       => null, /* local disk file */
                            ct_key        => l_ct_key,
                            bpkey         => l_outbpspkey,
                            template_key  => null);
 
      deb('Process_allfiles spfile ' ||
          ' handle - ' || saved_krbph_spname, AM_DEBUG_MED);
    END IF;
 
    deb('Process_allfiles finished level ' || l_ilevel ||
        ', vbkey ' || saved_vbkey ||
        ' handle - ' || saved_krbph_name, AM_DEBUG_MED);
 
--
    l_ilevel := l_ilevel + 1;
 
--
    EXIT WHEN l_levellst(l_levellst.COUNT) = 0;
  END LOOP;
 
--
--
--
--
  UPDATE vbdf SET srcbp_key = p_bpkey,
                  krbph_dfkey = saved_krbphdf,
                  krbph_chunkno = saved_krbph
    WHERE vb_key = saved_vbkey;
  COMMIT;
 
--
--
  FOR i IN 1 .. l_dfkeylst.COUNT LOOP
--
    IF dbms_ra_int.read_lock(dbms_ra_int.KEY_DF, l_dfkeylst(i))
    THEN
      l_done := FALSE;
      WHILE NOT l_done LOOP
        BEGIN
          sys.kbrsi_icd.rsPlan(p_dbkey, saved_vbkey, l_dfkeylst(i),
                               KBRSPLBLD_PIECE, 0);
          l_done := TRUE;
        EXCEPTION
          WHEN dbms_ra_scheduler.e_snapshot_too_old THEN
            save_error;
--
--
            dbms_ra_int.unlock(dbms_ra_int.KEY_DF, l_dfkeylst(i));
            dbms_lock.sleep(5);
            clear_error;
          WHEN dbms_ra_scheduler.e_retry_error THEN
            save_error;
--
            dbms_ra_int.unlock(dbms_ra_int.KEY_DF, l_dfkeylst(i));
            dbms_lock.sleep(5);
            clear_error;
          WHEN OTHERS THEN
            save_error;
            dbms_ra_int.unlock(dbms_ra_int.KEY_DF, l_dfkeylst(i));
            RAISE;
        END;
      END LOOP;
    ELSE
--
      RAISE dbms_ra_scheduler.e_retry_error;
    END IF;
    dbms_ra_int.unlock(dbms_ra_int.KEY_DF, l_dfkeylst(i));
 
--
    dbms_ra_scheduler.release_blocked_tasks(
                                dbms_ra_scheduler.s_current_task, p_dbkey);
  END LOOP;
 
--
--
  IF p_hasdups THEN
    SELECT sl_key INTO l_slkey FROM odb WHERE db_key = p_dbkey;
 
    FOR i IN 1 .. l_dfkeylst.COUNT LOOP
      task_rec := NULL;
      task_rec.task_type   := dbms_ra_scheduler.TASK_PURGE_DUP_DF;
      task_rec.db_key      := p_dbkey;
      task_rec.sl_key      := l_slkey;
      task_rec.param_num1  := l_dfkeylst(i);
      task_rec.param_num2  := saved_vbkey;
      task_rec.param_num3  := p_bpkey;  -- Ensures this is all done.
      dbms_ra_scheduler.new_task(task_rec, TRUE, TRUE); -- commit and delay
    END LOOP;
  END IF;
 
--
  SELECT COUNT(*) INTO l_count FROM vbdf
    WHERE vb_key = saved_vbkey AND state != VBDF_FIN_NOBP;
  IF l_count > 0 THEN
--
    SELECT COUNT(*) INTO l_count
      FROM vbdf
      WHERE vb_key = saved_vbkey
        AND state NOT IN (VBDF_ABORT, VBDF_FIN_NOBP);
    IF l_count = 0 THEN
      deb('Process_allfiles abort on vbkey ' || saved_vbkey, AM_DEBUG_LOW);
      RAISE dbms_ra_scheduler.e_retry_reserve;
    ELSE
      IF NOT p_update THEN
        deb('Process_allfiles: corruption in vbdf for vbkey ' ||
            saved_vbkey, AM_DEBUG_ON);
        SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(
                      DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM, 'corrupt_vbdf');
      END IF;
    END IF;
  END IF;
 
--
  IF s_safemode THEN
    deb('Process_allfiles: debug, make sure relfno assigned ok');
    SELECT COUNT(*) INTO l_count
      FROM (SELECT vb_key, MAX(relfno) maxr, COUNT(*) cnt
            FROM vbdf
            WHERE vb_key = saved_vbkey
            GROUP BY vb_key)
      WHERE cnt != maxr;
    IF l_count = 1 THEN
      deb('Process_allfiles: messed up relfno in vbkey ' || saved_vbkey);
--
      SYS.DBMS_SYS_ERROR.RAISE_SYSTEM_ERROR(
                        DBMS_RA_SCHEDULER.E_INTERNAL_ERROR_NUM, 'Bad relfno');
    END IF;
  END IF;
 
--
  IF s_safemode AND NOT p_update THEN
    deb('Process_allfiles src bpkey ' || p_bpkey || ' safemode check of orig',
        AM_DEBUG_MED);
    FOR i IN 1 .. l_dfkeylst.COUNT LOOP
--
      IF dbms_ra_int.read_lock(dbms_ra_int.KEY_DF, l_dfkeylst(i))
      THEN
        l_done := FALSE;
        WHILE NOT l_done LOOP
          BEGIN
            deb('Process_allfiles safemode dfkey ' || l_dfkeylst(i) ||
                ', vbkey ' || saved_vbkey, AM_DEBUG_MED);
 
            sys.kbrsi_icd.rsPlan(p_dbkey, saved_vbkey, l_dfkeylst(i),
                                 KBRSPLBLD_ORIGPIECE, 0);
            l_done := TRUE;
          EXCEPTION
            WHEN dbms_ra_scheduler.e_retry_error THEN
              save_error;
--
              dbms_ra_int.unlock(dbms_ra_int.KEY_DF, l_dfkeylst(i));
              dbms_lock.sleep(5);
              clear_error;
            WHEN OTHERS THEN
              save_error;
              dbms_ra_int.unlock(dbms_ra_int.KEY_DF, l_dfkeylst(i));
              RAISE;
          END;
        END LOOP;
      END IF;
 
--
      SELECT SUM(signature) INTO l_sig1
        FROM plans_details
        WHERE df_key = l_dfkeylst(i)
          AND type = KBRSPLBLD_ORIGPIECE
          AND vb_key = saved_vbkey
          AND blockno > 0
          AND numbytes > 0;
 
--
      SELECT SUM(scn) INTO l_sig2
        FROM blocks b, vbdf v
        WHERE b.df_key = l_dfkeylst(i)
          AND v.df_key = l_dfkeylst(i)
          AND v.vb_key = saved_vbkey
          AND v.ckp_id = b.ckp_id
          AND b.blockno > 0
          AND b.used > 0;
 
      deb('Process_allfiles: df_key ' || l_dfkeylst(i) ||
          ', sig1 ' || l_sig1 || ', sig2 ' || l_sig2 ||
          ', safemode check', AM_DEBUG_ON);
      IF l_sig1 != l_sig2 THEN
--
        FOR x IN (SELECT b.blockno, b.scn, b.chunkno, b.coffset, b.df_key
                  FROM blocks b, plans_details p
                  WHERE b.df_key = l_dfkeylst(i)
                    AND b.chunkno = p.chunkno
                    AND b.coffset >= p.coffset
                    AND b.coffset < (p.coffset + p.numbytes)
                    AND b.used > 0
                    AND p.df_key = l_dfkeylst(i)
                    AND p.type = KBRSPLBLD_ORIGPIECE
                    AND p.vb_key = saved_vbkey
                  ORDER BY DECODE(b.blockno, 1, BIGNUM, b.blockno)) LOOP
          deb('bad bno ' || x.blockno ||
              ', scn ' || x.scn ||
              ', dfkey ' || x.df_key ||
              ', chunk ' || x.chunkno, AM_DEBUG_ON);
        END LOOP;
        raise_bad_metadata(l_dfkeylst(i));
      END IF;
 
      dbms_ra_int.unlock(dbms_ra_int.KEY_DF, l_dfkeylst(i));
      dealloc_plan(l_dfkeylst(i), saved_vbkey, KBRSPLBLD_ORIGPIECE);
    END LOOP;
  END IF;
 
--
  SELECT SUM(filesize) INTO l_size
    FROM chunks c, vbdf v
    WHERE c.df_key = v.df_key
      AND v.vb_key = saved_vbkey
      AND c.clean_key = saved_vbkey;
 
--
--
  FOR x IN (SELECT file#, completion_time
            FROM bdf WHERE bs_key = p_bskey) LOOP
    dbms_ra_int.saveBPdata(fno => x.file#,
                           completion_time => x.completion_time);
  END LOOP;
 
--
--
--
  IF NOT p_update THEN
    sys.kbrsi_icd.rsInspectBackupPiece(
                               handle        => saved_krbph_name,
                               vbkey         => saved_vbkey,
                               bpsize        => l_size,
                               chktype       => DBMS_RA_INT.KBRSCHKTYPE_VIRTUAL,
                               fno           => null,
                               lib_key       => null, /* local disk file */
                               ct_key        => null,
                               bpkey         => l_outbpkey,
                               template_key  => null);
    deb('Process_allfiles: Created bpkey ' || l_outbpkey ||
        ', vbkey ' || saved_vbkey, AM_DEBUG_LOW);
 
--
    UPDATE vbdf v
      SET vcbp_key = l_outbpkey,
          chunks_used = (SELECT COUNT(*)
                         FROM chunks c
                         WHERE c.df_key = v.df_key
                           AND c.clean_key = saved_vbkey)
      WHERE vb_key = saved_vbkey;
    COMMIT;
  ELSE
--
    UPDATE vbdf SET state = VBDF_COMPLETE
      WHERE vb_key = saved_vbkey AND state = VBDF_FIN_NOBP;
    COMMIT;
    l_outbpkey := 0;
  END IF;
   
EXCEPTION
  WHEN OTHERS THEN
    save_error;
--
    BEGIN
      deb('Process_allfiles: failed with error ' || SQLCODE, AM_DEBUG_MED);
      sys.dbms_backup_restore.restoreCancel(FALSE);
      sys.dbms_backup_restore.cfileUseCurrent;            -- release enqueue
      sys.dbms_backup_restore.deviceDeallocate;
      sys.dbms_backup_restore.set_client_info('');
      sys.dbms_backup_restore.setRmanStatusRowId(rsid=>0, rsts=>0);
 
--
--
--
      IF debug = AM_DEBUG_HIGH THEN
        SELECT error_count INTO l_count FROM task
          WHERE task_id = dbms_ra_scheduler.s_current_task;
        IF l_count > dbms_ra_scheduler.s_max_task_restarts/2 THEN
          cleanup(saved_vbkey);
        END IF;
      ELSE
        cleanup(saved_vbkey);
      END IF;
 
--
      SELECT MAX(state) INTO l_state FROM vbdf
        WHERE vb_key = saved_vbkey AND state = VBDF_ABORT;
      IF l_state = VBDF_ABORT THEN
        RAISE dbms_ra_scheduler.e_retry_error;
      END IF;
 
    EXCEPTION
      WHEN OTHERS THEN
        save_error;
        deb('Process_allfiles cleanup: failed with error ' || SQLCODE,
            AM_DEBUG_ON);
        RAISE;  -- Must always raise or you loose shutdown error
    END;
  RAISE;
END process_allfiles; 
 
 
--
--
--
--
--
--
--
--
--
--
PROCEDURE cleanup(p_vbkey IN NUMBER)
 IS
  l_bskey  NUMBER;
  l_locked BOOLEAN := FALSE;
  l_hash   NUMBER;
 CURSOR fnos IS
  SELECT v.df_key, v.vb_key, v.dbinc_key, v.db_key
  FROM vbdf v
  WHERE v.vb_key = p_vbkey
  ORDER BY v.df_key;
BEGIN
--
  deb('cleanup from a failed operation with vbkey: ' || p_vbkey, AM_DEBUG_LOW);
 
--
  SELECT MAX(bs_key) INTO l_bskey  -- Use max to avoid no data found
  FROM bp
  WHERE bp.vb_key = p_vbkey AND status != 'D';
  IF l_bskey IS NOT NULL
  THEN
    RETURN;
  END IF;
 
--
  FOR f IN fnos LOOP
    deb('cleanup: dfkey ' || f.df_key ||
        ', vbkey ' || f.vb_key, AM_DEBUG_LOW);
 
--
    SELECT ORA_HASH(f.df_key, 1023, 0) + 1 INTO l_hash FROM dual;
    WHILE NOT l_locked LOOP
      l_locked := sys.kbrsi_icd.rsPurgeLock(l_hash);
      IF NOT l_locked THEN
        dbms_lock.sleep(1);
      END IF;
    END LOOP;
 
--
    dealloc_plan(f.df_key, p_vbkey, KBRSPLBLD_PURGE);
    alloc_plan(f.db_key, f.df_key, p_vbkey, KBRSPLBLD_PURGE);
 
    INSERT INTO plans_details (type, df_key, vb_key,
                               chunkno, blockno, blkrank, numblks, coffset)
      SELECT KBRSPLBLD_PURGE, f.df_key, p_vbkey,
             chunkno, -10 blockno, 0 blkrank, 0 numblks, 0 coffset
        FROM chunks
        WHERE df_key = f.df_key
          AND clean_key = p_vbkey;
 
--
    UPDATE vbdf SET state = VBDF_CLEANUP
      WHERE vb_key = p_vbkey AND df_key = f.df_key;
    COMMIT;
 
--
--
    purge_pool(f.db_key, KBRSPLBLD_PURGE, KBRSPLBLD_PURGE,
               f.df_key, p_vbkey, TRUE);
--
    dbms_ra_scheduler.check_for_interrupt(saved_vbkey);
 
    dealloc_plan(f.df_key, p_vbkey, KBRSPLBLD_PURGE);
 
    dbms_ra_scheduler.unlock(dbms_ra_scheduler.LOCK_PURGE, l_hash);
    l_locked := FALSE;
  END LOOP;
 
--
  DELETE FROM vbdf WHERE vb_key = p_vbkey;
  COMMIT;
 
EXCEPTION
  WHEN OTHERS THEN
    save_error;
--
--
    dbms_ra_scheduler.check_for_interrupt(p_vbkey);
 
    IF l_locked THEN
      dbms_ra_scheduler.unlock(dbms_ra_scheduler.LOCK_PURGE, l_hash);
    END IF;
    RAISE;
END cleanup;
 
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
FUNCTION isTaped(p_dbkey IN NUMBER,
                 p_bpkey IN NUMBER,
                 p_bskey IN NUMBER) RETURN BOOLEAN IS 
  l_count    NUMBER;
  l_vbkey    NUMBER;
  l_dfbck    NUMBER := 0;
  l_startscn NUMBER;
BEGIN
  deb('isTaped bskey ' || p_bskey, AM_DEBUG_MED);
 
--
  SELECT COUNT(*) INTO l_count
    FROM bp
    WHERE bs_key = p_bskey
      AND lib_key IS NOT NULL;
 
--
  IF l_count = 0 THEN
    SELECT COUNT(*) INTO l_dfbck
      FROM bs
      WHERE bs_key = p_bskey
        AND (keep_options = 0 OR BCK_TYPE != 'L');
  END IF;
 
--
--
  IF l_dfbck > 0 THEN
    SELECT SIGN(MIN(x.scn - (y.ckp_scn-1))) INTO l_count
      FROM (SELECT bs_key, dbinc_key, file#, ckp_scn FROM bdf
            UNION
            SELECT bs_key, dbinc_key, 0 file#, ckp_scn FROM bcf) y,
           /* Highest backup scns in current inc, but not keep */
           (SELECT a.dbinc_key, a.file#, MAX(a.ckp_scn) scn
            FROM bp p, bs s,
                 (SELECT bs_key, file#, dbinc_key, ckp_scn FROM bdf
                  UNION
                  SELECT bs_key, 0 file#, dbinc_key, ckp_scn FROM bcf) a,
                 (SELECT db_key, dbinc_key, reset_scn,
                         NVL(PRIOR reset_scn, BIGNUM) next_reset_scn
                  FROM dbinc
                  START WITH dbinc_key = (SELECT curr_dbinc_key FROM db
                                          WHERE db_key = p_dbkey)
                  CONNECT BY PRIOR parent_dbinc_key = dbinc_key) i
            WHERE a.bs_key = s.bs_key
              AND a.bs_key = p.bs_key
              AND a.dbinc_key = i.dbinc_key
              AND p.status != 'D'
              AND p.lib_key IS NOT NULL
              AND s.keep_options = 0
            GROUP BY a.dbinc_key, a. file#) x
    WHERE x.dbinc_key = y.dbinc_key
      AND x.file# = y.file#
      AND y.bs_key = p_bskey;
  END IF;
 
  deb('isTaped count ' || l_count || ', bpkey ' || p_bpkey, AM_DEBUG_MED);
  RETURN (l_count > 0);
END isTaped;
 
--
--
--
--
--
--
PROCEDURE new_plans (p_dbkey    IN  NUMBER,
                     p_dfkey    IN  NUMBER,
                     p_nopurge  IN  BOOLEAN DEFAULT FALSE)
 IS
  task_rec        task%ROWTYPE;
  l_count         NUMBER;
BEGIN
  deb('NEW_PLANS: Submit future plans for df_key ' || p_dfkey,
      AM_DEBUG_MED);
 
--
--
--
--
  FOR x IN (SELECT bs_key, vb_key
            FROM sbt_task JOIN task USING (task_id)
                          JOIN bp USING (db_key, bs_key)
            WHERE db_key = p_dbkey
              AND state NOT IN (dbms_ra_scheduler.STATE_RUNNING,
                                dbms_ra_scheduler.STATE_CANCEL,
                                dbms_ra_scheduler.STATE_CANCELING)
              AND vb_key IS NOT NULL)
  LOOP
--
    task_rec := NULL;
    task_rec.task_type   := dbms_ra_scheduler.TASK_PLAN_SBT;
    task_rec.db_key      := p_dbkey;
    task_rec.param_num2  := x.vb_key;
    task_rec.param       := x.bs_key;
 
--
--
--
--
    SELECT MAX(incrLevel(d.create_scn, d.incr_scn)) + COUNT(*)
      INTO l_count
      FROM bdf d
      WHERE d.bs_key = x.bs_key;
 
--
    IF l_count = 1 THEN
      task_rec.param_num3  := KBRSPLBLD_PIECE;
    ELSE
      task_rec.param_num3  := KBRSPLBLD_ORIGPIECE;
    END IF;
 
--
    FOR y IN (SELECT df_key
              FROM bdf d, df f
              WHERE d.dbinc_key = f.dbinc_key
                AND d.create_scn = f.create_scn
                AND d.file# = f.file#
                AND d.bs_key = x.bs_key)
    LOOP
      task_rec.param_num1  := y.df_key;
      dbms_ra_scheduler.new_task(task_rec, FALSE);  -- Delay commit
    END LOOP;
  END LOOP;
 
--
--
  FOR i IN (SELECT MAX(vb_key) vb_key
            FROM bp JOIN bdf USING (bs_key) JOIN vbdf USING (db_key, vb_key)
            WHERE db_key = p_dbkey
              AND df_key = p_dfkey
              AND status != 'D'
            GROUP BY piece#) LOOP
    task_rec := NULL;
    task_rec.task_type   := dbms_ra_scheduler.TASK_PLAN_DF;
    task_rec.db_key      := p_dbkey;
    task_rec.param_num1  := p_dfkey;
    task_rec.param_num2  := i.vb_key;
    task_rec.param_num3  := KBRSPLBLD_PIECE;
    dbms_ra_scheduler.new_task(task_rec, FALSE);  -- Delay commit
  END LOOP;
  COMMIT;
 
--
  SYS.KBRSI_ICD.RSRUNSCHED;
END new_plans;
 
--
--
--
--
--
--
FUNCTION orphans(p_dbkey    IN  NUMBER,
                 p_dfkey    IN  NUMBER,
                 p_currinc  IN  NUMBER DEFAULT NULL)
RETURN BOOLEAN IS
  l_badvb    NUMBER;
  l_currinc  NUMBER := p_currinc;
BEGIN
  IF l_currinc IS NULL THEN
--
--
--
    SELECT dbinc_key INTO l_currinc
      FROM (SELECT dbinc_key
            FROM vbdf
            WHERE df_key = p_dfkey
            ORDER BY vb_key DESC
           )
      WHERE ROWNUM = 1;
  END IF;
 
--
  SELECT MAX(vb_key) INTO l_badvb
    FROM vbdf
    WHERE df_key = p_dfkey
      AND vb_key NOT IN 
          (SELECT vb_key
           FROM vbdf v,
                (SELECT dbinc_key,
                        NVL(PRIOR reset_scn, BIGNUM) next_reset_scn
                 FROM dbinc
                 START WITH dbinc_key = l_currinc
                 CONNECT BY PRIOR parent_dbinc_key = dbinc_key
                ) i
           WHERE v.df_key = p_dfkey
             AND v.dbinc_key = i.dbinc_key
             AND v.ckp_scn < i.next_reset_scn
             AND v.state != VBDF_OBSOLETE
          )
      AND state != VBDF_OBSOLETE;
 
  IF l_badvb IS NULL THEN
    deb('orphans: dfkey ' || p_dfkey || ', FALSE', AM_DEBUG_HIGH);
    RETURN FALSE;
  ELSE
    deb('orphans: dfkey ' || p_dfkey || ', TRUE', AM_DEBUG_HIGH);
    RETURN TRUE;
  END IF;
END orphans;
 
--
--
--
--
--
--
FUNCTION orphan_bp(p_dbkey    IN  NUMBER,
                   p_dfkey    IN  NUMBER,
                   p_currinc  IN  NUMBER)
RETURN BOOLEAN IS
  l_count    NUMBER;
  l_badvb    NUMBER;
  l_currinc  NUMBER := p_currinc;
BEGIN
--
  SELECT MAX(p.vb_key) INTO l_badvb
    FROM bp p, bdf b, df f
    WHERE f.df_key = p_dfkey
      AND f.dbinc_key = b.dbinc_key
      AND f.file# = b.file#
      AND f.create_scn = b.create_scn
      AND p.bs_key = b.bs_key
      AND p.vb_key IS NOT NULL
      AND p.status != 'D'
      AND p.vb_key NOT IN 
          (SELECT vb_key
           FROM vbdf v,
                (SELECT dbinc_key,
                        NVL(PRIOR reset_scn, BIGNUM) next_reset_scn
                 FROM dbinc
                 START WITH dbinc_key = l_currinc
                 CONNECT BY PRIOR parent_dbinc_key = dbinc_key
                ) i
           WHERE v.df_key = p_dfkey
             AND v.dbinc_key = i.dbinc_key
             AND v.ckp_scn < i.next_reset_scn
             AND v.state != VBDF_OBSOLETE
          );
 
  IF l_badvb IS NULL THEN
    deb('orphan_bp: dfkey ' || p_dfkey || ', FALSE', AM_DEBUG_HIGH);
    RETURN FALSE;
  ELSE
    deb('orphan_bp: dfkey ' || p_dfkey || ', TRUE', AM_DEBUG_HIGH);
    RETURN TRUE;
  END IF;
END orphan_bp;
 
--
--
--
--
--
--
FUNCTION orphan_blocks(p_dbkey    IN  NUMBER,
                       p_dfkey    IN  NUMBER)
RETURN BOOLEAN IS
  l_count       NUMBER;
  l_currinc     NUMBER;
  l_currvb      NUMBER;
  l_maxckpid    NUMBER;
  l_tmp         NUMBER;
  l_orphaninc   NUMBER;
  l_maxorphscn  NUMBER;
BEGIN
--
  SELECT dbinc_key, vb_key, ckp_id INTO l_currinc, l_currvb, l_maxckpid
    FROM (SELECT dbinc_key, vb_key, ckp_id
          FROM vbdf
          WHERE df_key = p_dfkey
          ORDER BY vb_key DESC
         )
    WHERE ROWNUM = 1;
 
--
--
  working_ckpid(p_dbkey, p_dfkey, l_currvb, TRUE,
                l_currinc, l_maxckpid, l_tmp, l_orphaninc);
  orphan_common(l_currinc, l_orphaninc, p_dfkey, l_tmp, l_maxorphscn);
 
--
  dbms_ra_int.info_start('orphan_blocks',
                         'dfkey ' || p_dfkey || 'currvb ' || l_currvb);
 
--
  SELECT COUNT(*) INTO l_count
    FROM dual
    WHERE EXISTS
          (SELECT 1 /*+ QB_NAME(badblks) */
           FROM blocks
           WHERE df_key = p_dfkey
             AND scn    > l_maxorphscn
             AND ckp_id NOT IN
                 (SELECT ckp_id
                  FROM vbdf v,
                       (SELECT dbinc_key,
                               NVL(PRIOR reset_scn, BIGNUM) next_reset_scn
                        FROM dbinc
                        START WITH dbinc_key = l_currinc
                        CONNECT BY PRIOR parent_dbinc_key = dbinc_key
                        ) i
                  WHERE v.dbinc_key = i.dbinc_key
                    AND v.ckp_scn < i.next_reset_scn
                    AND v.df_key = p_dfkey
                    AND v.state != VBDF_OBSOLETE
                 )
          );
  dbms_ra_int.info_end;
 
  IF l_count = 0 THEN
    deb('orphan_blocks: dfkey ' || p_dfkey || ', FALSE', AM_DEBUG_HIGH);
    RETURN FALSE;
  ELSE
    deb('orphan_blocks: dfkey ' || p_dfkey || ', TRUE', AM_DEBUG_HIGH);
    RETURN TRUE;
  END IF;
END orphan_blocks;
 
 
--
--
--
--
--
--
--
--
--
--
PROCEDURE orphan_safe(p_dbkey    IN  NUMBER,
                      p_dfkey    IN  NUMBER,
                      p_currinc  IN  NUMBER,
                      o_vbkey    OUT NUMBER,
                      o_scn      OUT NUMBER)
IS
  l_resetscn  NUMBER;
BEGIN
 
--
  WITH
    vbtree
  AS
  (  /* List of vb_key in current inc tree */
   SELECT /*+ QB_NAME(vbtree)
              MATERIALIZE
          */
          vb_key, reset_scn
   FROM vbdf v,
        (SELECT dbinc_key, reset_scn,
                NVL(PRIOR reset_scn, BIGNUM) next_reset_scn
         FROM dbinc
         START WITH dbinc_key = p_currinc
         CONNECT BY PRIOR parent_dbinc_key = dbinc_key
         ) i
   WHERE v.df_key = p_dfkey
     AND v.dbinc_key = i.dbinc_key
     AND v.ckp_scn < i.next_reset_scn
     AND v.state != VBDF_OBSOLETE
  )
  SELECT MIN(reset_scn) INTO l_resetscn
    FROM vbdf JOIN dbinc USING (dbinc_key, db_key)
    WHERE db_key = p_dbkey
      AND df_key = p_dfkey
      AND reset_scn NOT IN (SELECT reset_scn FROM vbtree)
      AND state != VBDF_OBSOLETE;
 
  BEGIN
    SELECT vb_key, ckp_scn INTO o_vbkey, o_scn
      FROM (
            SELECT vb_key, ckp_scn
            FROM vbdf
            WHERE ckp_scn < l_resetscn
              AND df_key = p_dfkey
              AND state != VBDF_OBSOLETE
            ORDER BY vb_key DESC
           )
      WHERE ROWNUM = 1;
  EXCEPTION
    WHEN no_data_found THEN
      o_vbkey := 0;
      o_scn := 0;
  END;
 
--
 
END orphan_safe;
 
--
--
--
--
--
--
--
PROCEDURE orphan_common(p_dbinc_a  IN  NUMBER,
                        p_dbinc_b  IN  NUMBER,
                        p_dfkey    IN  NUMBER,
                        o_ckpid    OUT NUMBER,
                        o_ckpscn   OUT NUMBER)
IS
BEGIN
    WITH
      vbtree1
    AS
    (/* List of vb_key in incarnation A tree */
     SELECT /*+ QB_NAME(vbtree1)
                MATERIALIZE
            */
            vb_key, ckp_scn, ckp_id
     FROM vbdf v,
          (SELECT dbinc_key,
                  NVL(PRIOR reset_scn, BIGNUM) next_reset_scn
           FROM dbinc
           START WITH dbinc_key = p_dbinc_a
           CONNECT BY PRIOR parent_dbinc_key = dbinc_key
          ) i
     WHERE v.df_key = p_dfkey
       AND v.dbinc_key = i.dbinc_key
       AND v.ckp_scn < i.next_reset_scn
       AND v.state != VBDF_OBSOLETE
    )
    , vbtree2
    AS
    (/* List of vb_key in incarnation B tree */
     SELECT /*+ QB_NAME(vbtree2)
                MATERIALIZE
            */
            vb_key, ckp_scn, ckp_id
     FROM vbdf v,
          (SELECT dbinc_key,
                  NVL(PRIOR reset_scn, BIGNUM) next_reset_scn
           FROM dbinc
           START WITH dbinc_key = p_dbinc_b
           CONNECT BY PRIOR parent_dbinc_key = dbinc_key
          ) i
     WHERE v.df_key = p_dfkey
       AND v.dbinc_key = i.dbinc_key
       AND v.ckp_scn < i.next_reset_scn
       AND v.state != VBDF_OBSOLETE
    )
    , samevb
    AS
    (/* Get the vb which is in both incarnations */
     SELECT ckp_scn, ckp_id
     FROM vbtree1 JOIN vbtree2 USING (vb_key, ckp_scn, ckp_id)
     ORDER BY vb_key desc
    )
    SELECT NVL(MAX(ckp_scn), 0), NVL(MAX(ckp_id), 0) INTO o_ckpid, o_ckpscn
      FROM samevb
      WHERE ROWNUM = 1;
 
    deb('orphan_common ckpid ' || o_ckpid || ', ckpscn ' || o_ckpscn,
        AM_DEBUG_MED);
END orphan_common;
 
 
/************************** BLOCK POOL QUERIES **************************
 
    Following this description are a collection of routines containing
    a single INSERT/SELECT.  For best possible performance we use
    different queries depending on the available data.  So to build a
    backup piece in a CDB environment would use a different query than
    for non-CDB.  Or to build a query that contains orphan backups is
    different than where there are no orphan backups.  Since having
    large DML intermixed with procedural code is difficult to read,
    large DML will live in routines without procedural code.
 
    Failure to get build a plan correctly can mean we deliver corrupt
    virtual backups that are only detected after recovery or some SQL
    on the client discovers the corruption.  Read the following and
    take extreme care when modifying the queries that construct read
    plans for any purpose.  If additional note worthy constructions
    are found, please document them below.
 
    Keep these details in mind when modifying read plan queries.
 
      - CKP_ID: This is either the ckp_scn, or just a little higher if
        this is a read only backup and this was previously backed up.
        The main point is that deduplication will only remove the
        older version of any block, which means the lowest ckp_id you
        should find in a backup is that of the oldest level 0 backup.
        Which is maintained in VBDF.MIN_ID.
 
      - Purging: This is done by making an exact copy (same ckp_id,
        scn) of some blocks, then taking a write lock on the df and
        deleting all plans and releasing the lock, then deleting the
        old versions (with lower ckp_id, chunkno values).  This means
        we might be building a new plan and reading new blocks while
        the old blocks and chunks are being deleted.  This only works
        if we are always sure the blocks and chunks to be deleted are
        no longer needed.  There exists a safemode check after we've
        deleting the plans that actually builds the oldest valid plan
        for the datafile.  We then check that new plan to ensure it
        doesn't reference any of the chunks that are to be deleted.
        This is expensive, that's why it's only done in safemode.
 
      - Fuzzy blocks: These have an SCN greater than the ckp_scn of
        the backup.  However they have a matching ckp_id as the
        backup.  So we include matching ckp_id in the result set.
        Additionally we never deduplicate a fuzzy block as we need to
        know the ckp_id to know it is fuzzy.
        Block 1, Gap blocks, and Corrupt blocks are all fuzzy.  We use
        that fact to ensure correctness.
 
      - Corrupt blocks: Corrupt blocks are written into the metadata
        as a gap block of 1.  We are then able to treat them in the same
        manner as gaps.
 
      - Gap blocks: carry an SCN that matches the ckp_scn of the
        backup.  Additionally filler blocks with the same SCN but
        different block numbers will be put into the blocks table.  A
        filler block has a USED value of 0.  That's how you know it's
        a filler block.  These filler blocks allow us to omit or
        include other blocks based on their SCN.
 
      - Blocks after gap blocks: It's possible to have a gap, then for
        a later backup to provide the original block.  When this
        happens a block with an SCN prior to the GAP SCN and a CKP_ID
        after the GAP CKP_ID is found.  These blocks are marked with a
        flag in the data and then written with an SCN == CKP_ID.  This
        ensures block sequencing is maintained even though true SCN
        order is out of sequence.  Since corrupt blocks are written as
        GAP blocks, the mechanism works the same.
 
      - CDB: Pluggable databases can be individually backed up and
        restored.  The pdbinc table maintains a list of exclusion
        ranges.  These are SCN ranges that must be excluded from the
        backup.  This is based on the pdbinc_key which is stored in
        the vbdf and for normal databases, the pdbinc_key is zero.
 
      - Orphan backups: If a user does a PITR to a time before backups
        already provided, those backups become orphan.  Because of
        deduplication we may still need some blocks from those orphan
        backups.  Thus computing a restore plan when orphan backups
        exists is more complex.  SCN values across incarnations must
        be checked.  Additionally, the order of backup deletion must
        remove the orphan backups before deleting any blocks from that
        last good backup for both incarnations.  Eventually all orphan
        blocks will be deleted, but until that happens the slower more
        complex plan building is needed.
 
      - DLC: Delayed Logging Cleanout - After a transaction commits
        we scan the buffers changed and clean up the ITL values releasing
        locks.  This operation is not logged.  Because of this, when a
        new incarnation is created, the two backups that share a common
        incr_scn, should have a common range of blocks between the 
        incr_scn and the reset_scn, but don't.  They don't because it is
        possible that the original incarnation applied a DLC that was
        unavailable to the new incarnation.  For this reason our
        incarnation query must join with the vbdf table and avoid
        any common block ranges.  This also means we need to preserve
        block 0 of deleted backups until after orphan incarnations are
        resolved, just in case we lose the metadata.
 
      - Tricky possible scenario's.  Look at each and ensure that as each
        line is purged, you still arrive at a correct answer for each 
        remaining ckp_id.  Remember that deduplication will remove older
        copies of a block.  So ensure the effects of dedupe play into
        your computations.
 
        DBINC  CKP_ID  SCN     (Incarnation reset scn 325)
        1      200     190
        1      300     
        1      410     190
        2      350     
        2      400     375
        2      500     
        2      600     375  new level 0
 
        DBINC  CKP_ID  SCN     (Corruption and Incarnation reset scn 325)
        1      200     190
        1      300     
        1      400     190
        1      500     corrupt faked with scn 500
        1      600     190
        1      700     
        2      350     
        2      450
        2      550
 
        DBINC  CKP_ID  SCN     (All backups level 0: try purge min_id=400)
        1      200     190
        1      300     gap block faked with scn 300
        1      400     gap block faked with scn 400
        1      500     190
 
        DBINC  CKP_ID  SCN     (Corruptions: min_id=200 then 500)
        1      200     190
        1      300     corrupt block with scn 300
        1      400     out of order block with scn 400, was repaired on db
        1      500     190 -- Level 0 backup with repaired block
 
        Your query should be able to derive the correct block for all the 
        above scenarios at every ckp_id.  Same is true for purging.  Walk
        through purging at each ckp_id, and ensure you will derive the correct
        value.
        If you have any new interesting scenario's.  Please add them as part
        of your fix to support them.
 
*/
 
--
--
PROCEDURE q_restore_fast(p_type        IN  NUMBER, -- KBRSPLBLD_ type
                         p_dfkey       IN  NUMBER,
                         p_vbkey       IN  NUMBER,
                         p_incrscn     IN  NUMBER,
                         p_ckpscn      IN  NUMBER,
                         p_absscn      IN  NUMBER,
                         p_ckpid       IN  NUMBER,
                         p_minckpid    IN  NUMBER,
                         p_maxckpid    IN  NUMBER,
                         p_dbinc_key   IN  NUMBER,
                         p_firstblk    IN  NUMBER,
                         p_lastblk     IN  NUMBER)
IS
BEGIN
  dbms_ra_int.info_start('q_restore_fast',
                         'dfkey ' || p_dfkey || ', vbkey ' || p_vbkey);
 
  INSERT /*+
           QB_NAME(q_restore_fast)
           OPT_PARAM('optimizer_dynamic_sampling' 0)
           OPT_PARAM('_optimizer_adaptive_cursor_sharing' 'false')
           OPT_PARAM('_optimizer_extended_cursor_sharing_rel' 'none')
           OPT_PARAM('_optimizer_use_feedback' 'false')
         */
  INTO plans_details (df_key, type, vb_key, blkrank, blockno,
                      chunkno, numblks, coffset, numbytes, signature)
  SELECT p_dfkey, p_type, p_vbkey, 1 blkrank, blockno,
         chunkno, numblks, coffset, numbytes, signature
    FROM TABLE(
           collapse(
             CURSOR(
               SELECT /*+
                      QB_NAME(q_rfast_c)
                      INDEX_RS_ASC(@q_rfast_c b@q_rfast_c blocks_u)
                      NO_INDEX_FFS(@q_rfast_c b@q_rfast_c blocks_u)
                      OPT_PARAM('optimizer_dynamic_sampling' 0)
                      OPT_PARAM('_optimizer_adaptive_cursor_sharing' 'false')
                      OPT_PARAM('_optimizer_extended_cursor_sharing_rel' 'none')
                      OPT_PARAM('_optimizer_use_feedback' 'false')
                      */
                      blockno, scn, chunkno, used, coffset
                 FROM blocks b
                WHERE df_key = p_dfkey
                  AND blockno BETWEEN p_firstblk AND p_lastblk
                  AND scn     BETWEEN p_incrscn AND p_absscn
                  AND ckp_id >= p_minckpid
                  AND (ckp_id <= p_maxckpid OR dbinc_key <> p_dbinc_key)
                  AND (scn < p_ckpscn OR ckp_id = p_ckpid)
                ORDER BY
                      blockno, scn DESC, ckp_id DESC, chunkno DESC
             )
           )
         );
  deb('q_restore_fast plan records ' || SQL%ROWCOUNT, AM_DEBUG_MED);
  COMMIT;
  dbms_ra_int.info_end;
END q_restore_fast;
 
 
--
--
PROCEDURE q_restore_incs(p_type        IN  NUMBER, -- KBRSPLBLD_ type
                         p_dfkey       IN  NUMBER,
                         p_vbkey       IN  NUMBER,
                         p_incrscn     IN  NUMBER,
                         p_ckpscn      IN  NUMBER,
                         p_absscn      IN  NUMBER,
                         p_ckpid       IN  NUMBER,
                         p_minckpid    IN  NUMBER,
                         p_maxckpid    IN  NUMBER,
                         p_dbinc_key   IN  NUMBER,
                         p_deadinc     IN  NUMBER,
                         p_orphaninc   IN  NUMBER,
                         p_maxorphscn  IN  NUMBER,
                         p_firstblk    IN  NUMBER,
                         p_lastblk     IN  NUMBER)
IS
  l_safeckpid   NUMBER;
BEGIN
--
--
--
--
--
  SELECT MIN(ckp_scn) INTO l_safeckpid
    FROM vbdf
    WHERE df_key = p_dfkey
      AND state = VBDF_COMPLETE;
 
  deb('q_restore_incs safe_ckpid ' || l_safeckpid ||
      ', max_orphan_scn ' || p_maxorphscn ||
      ', orphan_inc ' || p_orphaninc ||
      ', deadinc ' || p_deadinc, AM_DEBUG_MED);
 
  dbms_ra_int.info_start('q_restore_incs',
                         'dfkey ' || p_dfkey || ', vbkey ' || p_vbkey);
 
  INSERT /*+
           QB_NAME(q_restore_incs)
           OPT_PARAM('optimizer_dynamic_sampling' 0)
           OPT_PARAM('_optimizer_adaptive_cursor_sharing' 'false')
           OPT_PARAM('_optimizer_extended_cursor_sharing_rel' 'none')
           OPT_PARAM('_optimizer_use_feedback' 'false')
         */
  INTO plans_details (df_key, type, vb_key, blkrank, blockno,
                      chunkno, numblks, coffset, numbytes, signature)
  SELECT p_dfkey, p_type, p_vbkey, 1 blkrank, blockno,
         chunkno, numblks, coffset, numbytes, signature
    FROM TABLE(
           collapse(
             CURSOR(
               WITH vi AS
               (
               SELECT /*+ MATERIALIZE */
                      v.dbinc_key
                    , v.ckp_id
                 FROM vbdf v
                    , (
                      SELECT dbinc_key
                           , NVL(PRIOR reset_scn, BIGNUM) next_reset_scn
                        FROM dbinc
                       START WITH dbinc_key = p_dbinc_key
                     CONNECT BY PRIOR parent_dbinc_key = dbinc_key
                      ) i
                WHERE v.dbinc_key = i.dbinc_key
                  AND v.df_key = p_dfkey
                  AND v.ckp_scn < i.next_reset_scn
                  AND v.state <> VBDF_OBSOLETE
               )
               , orphinc
               AS
               (
--
--
--
                SELECT /*+ MATERIALIZE */
                       dbinc_key, reset_scn
                FROM dbinc
                START WITH dbinc_key = p_orphaninc
                CONNECT BY PRIOR parent_dbinc_key = dbinc_key
               )
               SELECT /*+
                      QB_NAME(q_rincs_c)
                      INDEX_RS_ASC(@q_rincs_c b@q_rincs_c blocks_u)
                      NO_INDEX_FFS(@q_rincs_c b@q_rincs_c blocks_u)
                      OPT_PARAM('optimizer_dynamic_sampling' 0)
                      OPT_PARAM('_optimizer_adaptive_cursor_sharing' 'false')
                      OPT_PARAM('_optimizer_extended_cursor_sharing_rel' 'none')
                      OPT_PARAM('_optimizer_use_feedback' 'false')
                      NO_EXPAND
                      */
                      blockno, scn, chunkno, used, coffset
                 FROM blocks b
                WHERE df_key = p_dfkey
                  AND blockno BETWEEN p_firstblk AND p_lastblk
                  AND scn     BETWEEN p_incrscn AND p_absscn
                  AND ckp_id >= p_minckpid
                  AND (ckp_id <= p_maxckpid OR dbinc_key <> p_dbinc_key)
                  AND (scn < p_ckpscn OR ckp_id = p_ckpid)
                  AND dbinc_key <> p_deadinc
--
--
--
--
--
                  AND 'y' = CASE
                       WHEN  /* Blocks older than safe ckpid are always good */
                       ckp_id < l_safeckpid
                       OR  /* Blocks in matching incarnation are good */
                       dbinc_key = p_dbinc_key
                       OR  /* Blocks from current incarnation tree no dedupe */
                       ckp_id IN (SELECT ckp_id FROM vi)
                       OR ( /* Block is in orphan incarnation */
                           p_deadinc = 0    /* only if are using orphan blks */
                           AND
                           scn < p_maxorphscn         /* deduped blocks only */
                           AND
                           dbinc_key IN (SELECT dbinc_key FROM orphinc)
                          )
                       THEN 'y'
                      END
                ORDER BY
                      blockno, scn DESC, ckp_id DESC, chunkno DESC
             )
           )
         );
  deb('q_restore_incs plan records ' || SQL%ROWCOUNT, AM_DEBUG_MED);
  COMMIT;
  dbms_ra_int.info_end;
END q_restore_incs ;
 
 
--
--
 
--
--
--
--
--
--
--
--
--
--
--
--
--
--
PROCEDURE q_restore_cdb(p_type        IN  NUMBER, -- KBRSPLBLD_ type
                        p_dfkey       IN  NUMBER,
                        p_vbkey       IN  NUMBER,
                        p_incrscn     IN  NUMBER,
                        p_ckpscn      IN  NUMBER,
                        p_absscn      IN  NUMBER,
                        p_ckpid       IN  NUMBER,
                        p_minckpid    IN  NUMBER,
                        p_maxckpid    IN  NUMBER,
                        p_pdbinc_key  IN  NUMBER,
                        p_dbinc_key   IN  NUMBER,
                        p_deadinc     IN  NUMBER,
                        p_orphaninc   IN  NUMBER,
                        p_maxorphscn  IN  NUMBER,
                        p_firstblk    IN  NUMBER,
                        p_lastblk     IN  NUMBER,
                        p_orphans     IN  BOOLEAN)
IS
  l_safeckpid   NUMBER;
BEGIN
--
  IF p_orphans THEN
--
    SELECT MIN(ckp_scn) INTO l_safeckpid
      FROM vbdf
      WHERE df_key = p_dfkey
        AND state = VBDF_COMPLETE;
  ELSE
    l_safeckpid := BIGNUM;
  END IF;
 
  deb('q_restore_cdb safe_ckpid ' || l_safeckpid ||
      ', max_orphan_scn ' || p_maxorphscn ||
      ', orphan_inc ' || p_orphaninc ||
      ', deadinc ' || p_deadinc, AM_DEBUG_MED);
 
  dbms_ra_int.info_start('q_restore_cdb',
                         'dfkey ' || p_dfkey || ', vbkey ' || p_vbkey);
 
  INSERT /*+
           QB_NAME(q_restore_cdb)
           OPT_PARAM('optimizer_dynamic_sampling' 0)
           OPT_PARAM('_optimizer_adaptive_cursor_sharing' 'false')
           OPT_PARAM('_optimizer_extended_cursor_sharing_rel' 'none')
           OPT_PARAM('_optimizer_use_feedback' 'false')
         */
  INTO plans_details (df_key, type, vb_key, blkrank, blockno,
                      chunkno, numblks, coffset, numbytes, signature)
  SELECT p_dfkey, p_type, p_vbkey, 1 blkrank, blockno,
         chunkno, numblks, coffset, numbytes, signature
    FROM TABLE(
           collapse(
             CURSOR(
               WITH vi AS
               (
               SELECT /*+ MATERIALIZE */
                      v.dbinc_key
                    , v.ckp_id
                 FROM vbdf v
                    , (
                      SELECT dbinc_key
                           , NVL(PRIOR reset_scn, BIGNUM) next_reset_scn
                        FROM dbinc
                       START WITH dbinc_key = p_dbinc_key
                     CONNECT BY PRIOR parent_dbinc_key = dbinc_key
                      ) i
                WHERE v.dbinc_key = i.dbinc_key
                  AND v.df_key = p_dfkey
                  AND v.ckp_scn < i.next_reset_scn
                  AND v.state <> VBDF_OBSOLETE
               )
               , pdbs AS
               (
                SELECT /*+ MATERIALIZE */
                       inc_scn, begin_reset_scn
                  FROM pdbinc
                 START WITH pdbinc_key = p_pdbinc_key
               CONNECT BY PRIOR parent_pdbinc_key = pdbinc_key
               )
               , orphinc
               AS
               (
--
--
--
                SELECT /*+ MATERIALIZE */
                       dbinc_key, reset_scn
                FROM dbinc
                START WITH dbinc_key = p_orphaninc
                CONNECT BY PRIOR parent_dbinc_key = dbinc_key
               )
               SELECT /*+
                      QB_NAME(q_rcdb_c)
                      INDEX_RS_ASC(@q_rcdb_c b@q_rcdb_c blocks_u)
                      NO_INDEX_FFS(@q_rcdb_c b@q_rcdb_c blocks_u)
                      OPT_PARAM('optimizer_dynamic_sampling' 0)
                      OPT_PARAM('_optimizer_adaptive_cursor_sharing' 'false')
                      OPT_PARAM('_optimizer_extended_cursor_sharing_rel' 'none')
                      OPT_PARAM('_optimizer_use_feedback' 'false')
                      NO_EXPAND
                      */
                      blockno, scn, chunkno, used, coffset
                 FROM blocks b
                WHERE df_key = p_dfkey
                  AND blockno BETWEEN p_firstblk AND p_lastblk
                  AND scn     BETWEEN p_incrscn AND p_absscn
                  AND ckp_id >= p_minckpid
                  AND (ckp_id <= p_maxckpid OR dbinc_key <> p_dbinc_key)
                  AND (scn < p_ckpscn OR ckp_id = p_ckpid)
                  AND dbinc_key <> p_deadinc
--
--
--
--
--
                  AND 'y' = CASE
                       WHEN  /* Blocks older than safe ckpid are always good */
                       ckp_id < l_safeckpid
                       OR  /* Blocks in matching incarnation are good */
                       dbinc_key = p_dbinc_key
                       OR  /* Blocks from current incarnation tree no dedupe */
                       ckp_id IN (SELECT ckp_id FROM vi)
                       OR ( /* Block is in orphan incarnation */
                           p_deadinc = 0    /* only if are using orphan blks */
                           AND
                           scn < p_maxorphscn         /* deduped blocks only */
                           AND
                           dbinc_key IN (SELECT dbinc_key FROM orphinc)
                          )
                       THEN 'y'
                      END
--
--
                  AND NOT EXISTS (
                                  SELECT NULL
                                    FROM pdbs
                                   WHERE b.scn >= inc_scn
                                     AND b.scn < begin_reset_scn
                                 )
                ORDER BY
                      blockno, scn DESC, ckp_id DESC, chunkno DESC
             )
           )
         );
  deb('q_restore_cdb plan records ' || SQL%ROWCOUNT, AM_DEBUG_MED);
  COMMIT;
  dbms_ra_int.info_end;
END q_restore_cdb;
 
--
--
--
PROCEDURE q_purge_basic(p_type        IN  NUMBER, -- KBRSPLBLD_ type
                        p_dfkey       IN  NUMBER,
                        p_vbkey       IN  NUMBER,
                        p_dbkey       IN  NUMBER,
                        p_currinc     IN  NUMBER,
                        p_ckpscn      IN  NUMBER,
                        p_absscn      IN  NUMBER,
                        p_ckpid       IN  NUMBER,
                        p_minckpid    IN  NUMBER)
IS
  l_toobig    NUMBER;
BEGIN
  deb('q_purge_basic ckpid ' || p_ckpid || ', minid ' || p_minckpid,
      AM_DEBUG_MED);
 
--
--
--
--
--
--
  IF p_type = KBRSPLBLD_OPTPURGE THEN
    l_toobig := f_chunksize(p_dbkey) * dbms_ra_scheduler.s_purge_opt_pct;
  ELSE
    l_toobig := BIGNUM;
  END IF;
 
  dbms_ra_int.info_start('q_purge_basic',
                         'dfkey ' || p_dfkey || ', vbkey ' || p_vbkey);
 
  INSERT /*+
           QB_NAME(q_purge_basic)
           OPT_PARAM('optimizer_dynamic_sampling' 0)
           OPT_PARAM('_optimizer_adaptive_cursor_sharing' 'false')
           OPT_PARAM('_optimizer_extended_cursor_sharing_rel' 'none')
           OPT_PARAM('_optimizer_use_feedback' 'false')
         */
  INTO plans_details (df_key, type, vb_key, blkrank, blockno,
                      chunkno, numblks, coffset, numbytes, signature)
  WITH
  deadblks AS (
--
  SELECT --+ QB_NAME(deadblks)
         blockno, chunkno, coffset
    FROM TABLE(skip_last(CURSOR(
           SELECT /*+
                    QB_NAME(q_pbas_c)
                    OPT_PARAM('optimizer_dynamic_sampling' 0)
                    OPT_PARAM('_optimizer_adaptive_cursor_sharing' 'false')
                    OPT_PARAM('_optimizer_extended_cursor_sharing_rel' 'none')
                    OPT_PARAM('_optimizer_use_feedback' 'false')
                    NO_INDEX_FFS(@q_pbas_c b@q_pbas_c blocks_u)
                    INDEX_RS_ASC(@q_pbas_c b@q_pbas_c blocks_u)
                  */
                  blockno, ckp_id, scn, chunkno, used, coffset
             FROM blocks b
            WHERE df_key = p_dfkey /* it is a FULL file scan */
              AND scn    <= p_absscn
              AND ckp_id <= p_ckpid
              AND (scn < p_ckpscn OR ckp_id = p_ckpid)
--
--
--
--
              AND (scn != ckp_id OR scn >= p_minckpid OR blockno <= 1)
              AND CASE
--
--
--
--
                    WHEN blockno > 0
                    THEN NULL
                    WHEN EXISTS (
                           SELECT NULL              /* chunk is level 0 chunk */
                             FROM vbdf
                            WHERE df_key = p_dfkey
                              AND db_key = p_dbkey
                              AND ckp_id = min_id
                              AND krbph_dfkey = p_dfkey
                              AND krbph_chunkno = b.chunkno
                              AND ckp_scn > (
                                    SELECT MAX(ckp_scn)
                                      FROM vbdf
                                     WHERE df_key = p_dfkey
                                       AND ckp_id = min_id     /* means lvl 0 */
                                       AND state = VBDF_OBSOLETE
                                  )
                         ) 
                      OR EXISTS (
                           SELECT krbph_dfkey
                                , krbph_chunkno            /* chunk is in use */
                             FROM vbdf v, bp p
                            WHERE v.vb_key = p.vb_key
                              AND v.db_key = p_dbkey
                              AND p.db_key = p_dbkey
                              AND p.status != 'D'
                              AND krbph_dfkey = p_dfkey
                              AND krbph_chunkno = b.chunkno
                         )
                      OR EXISTS (
                           SELECT NULL                     /* chunk is in use */
                             FROM vbdf v, bp p
                            WHERE v.vb_key = p.vb_key
                              AND v.db_key = p_dbkey
                              AND p.db_key = p_dbkey
                              AND new_krbph IS NOT NULL
                              AND p.status != 'D'
                              AND krbph_dfkey = p_dfkey
                              AND new_krbph = b.chunkno
                         ) 
                    THEN '!' -- this entry must be excluded
                  END IS NULL
            ORDER BY blockno, scn DESC, ckp_id DESC, chunkno DESC
         )))
  )
  , deadchunks AS (
--
  SELECT DISTINCT chunkno FROM deadblks
  )
  , saveblks
  AS
  (
--
   SELECT /*+
            QB_NAME(saveblks)
            NO_INDEX_FFS(@saveblks b@saveblks blocks_c)
            INDEX_RS_ASC(@saveblks b@saveblks blocks_c)
            LEADING(@saveblks b@saveblks d@saveblks d2@deadb b2@dup)
            USE_HASH(@saveblks b@saveblks)
            USE_HASH(@saveblks d@saveblks)
            USE_HASH(@saveblks d2@deadb)
            USE_NL(@saveblks b2@dup)
            SWAP_JOIN_INPUTS(@saveblks d@saveblks)
          */
          b.chunkno, b.blockno, coffset, used, scn,
--
--
          ROW_NUMBER() OVER (
            PARTITION BY b.chunkno, b.coffset
                ORDER BY b.blockno
          ) freq,
--
--
--
          ROW_NUMBER() OVER (
            PARTITION BY blockno
                ORDER BY blockno, scn DESC, ckp_id DESC, b.chunkno DESC
          ) rernk
    FROM blocks b
       , deadchunks d
   WHERE b.df_key = p_dfkey
     AND b.chunkno = d.chunkno
     AND NOT EXISTS (
           SELECT /*+
                    QB_NAME(deadb)
                    HASH_AJ
                  */
                  NULL
             FROM deadblks d2
            WHERE d2.chunkno = d.chunkno
              AND d2.blockno = b.blockno
              AND d2.coffset = b.coffset
         )
     AND NOT EXISTS ( -- avoid copying a block if it is a duplicate
           SELECT /*+
                    QB_NAME(dup)
                    NO_INDEX_FFS(@dup b2@dup blocks_u)
                    INDEX_RS_ASC(@dup b2@dup blocks_u)
                  */
                  NULL
             FROM blocks b2
            WHERE b2.df_key = p_dfkey
              AND b2.blockno = b.blockno
              AND b2.scn = b.scn
              AND b2.ckp_id = b.ckp_id
              AND b2.chunkno > b.chunkno
         )
  )
  , blkgroups
--
--
--
--
--
  AS
  (
   SELECT --+ QB_NAME(bgrp)
          blockno, scn, chunkno, coffset, used, rernk,
          CASE 
            WHEN LAG((rernk * DBMS_RA_INT.UB8MAXVAL) +
                     (chunkno * MAXCHUNKSIZE) +
                     coffset + used)
                     OVER (ORDER BY rernk, blockno)
                  = ((rernk * DBMS_RA_INT.UB8MAXVAL) +
                     (chunkno * MAXCHUNKSIZE) +
                     coffset)
            THEN NULL
            ELSE 1
            END bg
     FROM saveblks
     WHERE freq = 1
  )
  , groups
--
  AS
  (
   SELECT --+ QB_NAME(grp)
          blockno, scn, chunkno, coffset, used, rernk,
          SUM(bg) OVER (PARTITION BY rernk, chunkno ORDER BY blockno) g
     FROM blkgroups
   UNION ALL
   SELECT --+ QB_NAME(deadchunks)
        -10 blockno, 0 scn, chunkno, 0 coffset, 1 used, 0 rernk, 0 g
   FROM deadchunks
  )
  , gsize
--
--
  AS
  (
   SELECT g.*,
          SUM(used) OVER (PARTITION BY chunkno) chunksize
   FROM groups g
  )
  SELECT --+ QB_NAME(ins)
         p_dfkey, KBRSPLBLD_PURGE, p_vbkey, rernk blkrank,
         MIN(blockno) blockno,
         chunkno,
         COUNT(blockno) numblks, 
         MIN(coffset) coffset,
         SUM(used) numbytes,
         null signature
    FROM gsize
    WHERE chunksize < l_toobig
    GROUP BY rernk, chunkno, g
    ORDER BY blkrank, blockno, chunkno;
 
  deb('q_purge_basic plan records ' || SQL%ROWCOUNT, AM_DEBUG_MED);
  COMMIT;
  dbms_ra_int.info_end;
END q_purge_basic;
 
 
--
--
PROCEDURE q_purge_orphan(p_type        IN  NUMBER, -- KBRSPLBLD_ type
                         p_dbkey       IN  NUMBER,
                         p_dfkey       IN  NUMBER,
                         p_vbkey       IN  NUMBER,
                         p_ckpscn      IN  NUMBER,
                         p_absscn      IN  NUMBER,
                         p_ckpid       IN  NUMBER,
                         p_minckpid    IN  NUMBER,
                         p_maxckpid    IN  NUMBER,
                         p_dbinc_key   IN  NUMBER,
                         p_deadinc     IN  NUMBER, -- Orphan inc we no need
                         p_orphaninc   IN  NUMBER) -- Orphan block inc
 IS
  l_maxscn    NUMBER;
  l_maxid     NUMBER;
  l_deadvb    NUMBER;
  l_orph      NUMBER;
  l_currinc   NUMBER;
BEGIN
  dbms_ra_int.info_start('q_purge_orphan_chunk',
                         'dfkey ' || p_dfkey || ', vbkey ' || p_vbkey);
 
  deb('q_purge_orphan dbinc ' || p_dbinc_key ||
      ', deadinc ' || p_deadinc ||
      ', orphaninc ' || p_orphaninc, AM_DEBUG_MED);
 
--
--
  IF p_deadinc > 0 THEN
    SELECT MAX(vb_key) INTO l_deadvb
      FROM vbdf
      WHERE dbinc_key = p_deadinc
        AND df_key = p_dfkey;
    l_orph := 0;  /* we have a dead inc, we do not want to compute the tree */
  ELSE
    l_deadvb := 0;
    l_orph := p_orphaninc; /* We need a tree to avoid */
  END IF;
 
--
--
  SELECT dbinc_key INTO l_currinc
    FROM (SELECT dbinc_key
          FROM vbdf
          WHERE df_key = p_dfkey
          ORDER BY vb_key DESC
         )
    WHERE ROWNUM = 1;
 
--
--
--
--
 
--
--
 
--
--
--
  INSERT /*+
           QB_NAME(q_purge_orphan_chunk)
           OPT_PARAM('optimizer_dynamic_sampling' 0)
           OPT_PARAM('_optimizer_adaptive_cursor_sharing' 'false')
           OPT_PARAM('_optimizer_extended_cursor_sharing_rel' 'none')
           OPT_PARAM('_optimizer_use_feedback' 'false')
         */
  INTO plans_details (df_key, type, vb_key, blkrank, blockno,
                      chunkno, numblks, coffset, numbytes, signature)
  WITH
    vbtree
  AS
  (  /* List of vb_key in current inc tree */
   SELECT /*+ QB_NAME(vbtree)
              MATERIALIZE
          */
          vb_key
   FROM vbdf v,
        (SELECT dbinc_key,
                NVL(PRIOR reset_scn, BIGNUM) next_reset_scn
         FROM dbinc
         START WITH dbinc_key = l_currinc
         CONNECT BY PRIOR parent_dbinc_key = dbinc_key
         ) i
   WHERE v.df_key = p_dfkey
     AND v.dbinc_key = i.dbinc_key
     AND v.ckp_scn < i.next_reset_scn
     AND v.state != VBDF_OBSOLETE
  )
  , deadvb
  AS
  (
   SELECT vb_key
   FROM vbdf
   WHERE vb_key NOT IN (SELECT vb_key FROM vbtree)
     AND df_key = p_dfkey
     AND state != VBDF_OBSOLETE
   ORDER BY vb_key
  )
  , orphinc
  AS
  (
   SELECT /*+ MATERIALIZE */
          dbinc_key
   FROM dbinc
   START WITH dbinc_key = l_orph
   CONNECT BY PRIOR parent_dbinc_key = dbinc_key
  )
  , chunk_inuse
  AS
  (
   SELECT /*+ QB_NAME(chunk_inuse)
              MATERIALIZE
          */
          krbph_chunkno, new_krbph
   FROM vbdf JOIN bp USING (db_key, vb_key)
   WHERE vb_key < p_vbkey
     AND db_key = p_dbkey
     AND status != 'D'
     AND krbph_dfkey = p_dfkey
  )
  SELECT /*+ QB_NAME(ins) */
         p_dfkey, KBRSPLBLD_PURGE, p_vbkey, 0 blkrank, -10 blockno,
         chunkno, 1 numblks, 0 coffset, 1 numbytes, null signature
  FROM chunks
  WHERE df_key = p_dfkey
--
--
    AND (dbinc_key = p_deadinc OR dbinc_key <> p_orphaninc)
--
--
--
--
    AND ((clean_key <= l_deadvb AND clean_key > 0) OR
         clean_key IN (SELECT vb_key FROM deadvb))
    AND dbinc_key NOT IN (SELECT dbinc_key FROM orphinc)
    AND chunkno NOT IN (SELECT krbph_chunkno FROM chunk_inuse)
    AND chunkno NOT IN (SELECT new_krbph     FROM chunk_inuse);
 
  deb('q_purge_orphan dead chunks ' || SQL%ROWCOUNT, AM_DEBUG_MED);
  COMMIT;
  dbms_ra_int.info_end;
 
 
--
--
--
  IF p_deadinc = 0 THEN
    dbms_ra_int.info_start('q_purge_orphan_blk',
                           'dfkey ' || p_dfkey || ', vbkey ' || p_vbkey);
--
--
    orphan_common(p_dbinc_key, p_orphaninc, p_dfkey, l_maxscn, l_maxid);
 
    INSERT /*+
             QB_NAME(q_purge_basic)
             OPT_PARAM('optimizer_dynamic_sampling' 0)
             OPT_PARAM('_optimizer_adaptive_cursor_sharing' 'false')
             OPT_PARAM('_optimizer_extended_cursor_sharing_rel' 'none')
             OPT_PARAM('_optimizer_use_feedback' 'false')
           */
    INTO plans_details (df_key, type, vb_key, blkrank, blockno,
                        chunkno, numblks, coffset, numbytes, signature)
    WITH
    deadblks AS (
--
    SELECT --+ QB_NAME(deadblks)
           blockno, chunkno, coffset
               FROM blocks b
              WHERE df_key = p_dfkey
                AND scn >= l_maxscn
                AND b.ckp_id <> l_maxid
                AND dbinc_key IN
                    (
                     SELECT /*+ MATERIALIZE */
                            dbinc_key
                     FROM dbinc
                     START WITH dbinc_key = p_orphaninc
                     CONNECT BY PRIOR parent_dbinc_key = dbinc_key
                    )
                AND CASE
--
--
--
--
                    WHEN blockno > 0
                    THEN NULL
                    WHEN EXISTS (
                           SELECT NULL            /* chunk is level 0 chunk */
                             FROM vbdf
                            WHERE df_key = p_dfkey
                              AND db_key = p_dbkey
                              AND ckp_id = min_id
                              AND krbph_dfkey = p_dfkey
                              AND krbph_chunkno = b.chunkno
                              AND ckp_scn > (
                                    SELECT MAX(ckp_scn)
                                      FROM vbdf
                                     WHERE df_key = p_dfkey
                                       AND ckp_id = min_id   /* means lvl 0 */
                                       AND state = VBDF_OBSOLETE
                                  )
                         ) 
                      OR EXISTS (
                           SELECT krbph_dfkey
                                , krbph_chunkno          /* chunk is in use */
                             FROM vbdf v, bp p
                            WHERE v.vb_key = p.vb_key
                              AND v.db_key = p_dbkey
                              AND p.db_key = p_dbkey
                              AND p.status != 'D'
                              AND krbph_dfkey = p_dfkey
                              AND krbph_chunkno = b.chunkno
                         )
                      OR EXISTS (
                           SELECT NULL                   /* chunk is in use */
                             FROM vbdf v, bp p
                            WHERE v.vb_key = p.vb_key
                              AND v.db_key = p_dbkey
                              AND p.db_key = p_dbkey
                              AND new_krbph IS NOT NULL
                              AND p.status != 'D'
                              AND krbph_dfkey = p_dfkey
                              AND new_krbph = b.chunkno
                         ) 
                    THEN '!' -- this entry must be excluded
                  END IS NULL
            ORDER BY blockno, scn DESC, ckp_id DESC, chunkno DESC
    )
    , deadchunks AS (
--
    SELECT DISTINCT chunkno FROM deadblks
    )
    , saveblks
    AS
    (
--
     SELECT /*+
              QB_NAME(saveblks)
              NO_INDEX_FFS(@saveblks b@saveblks blocks_c)
              INDEX_RS_ASC(@saveblks b@saveblks blocks_c)
              LEADING(@saveblks b@saveblks d@saveblks d2@deadb b2@dup)
              USE_HASH(@saveblks b@saveblks)
              USE_HASH(@saveblks d@saveblks)
              USE_HASH(@saveblks d2@deadb)
              USE_NL(@saveblks b2@dup)
              SWAP_JOIN_INPUTS(@saveblks d@saveblks)
            */
            b.chunkno, b.blockno, coffset, used, scn,
--
--
            ROW_NUMBER() OVER (
              PARTITION BY b.chunkno, b.coffset
                  ORDER BY b.blockno
            ) freq,
--
--
--
            ROW_NUMBER() OVER (
              PARTITION BY blockno
                  ORDER BY blockno, scn DESC, ckp_id DESC, b.chunkno DESC
            ) rernk
      FROM blocks b
         , deadchunks d
     WHERE b.df_key = p_dfkey
       AND b.chunkno = d.chunkno
       AND NOT EXISTS (
             SELECT /*+
                      QB_NAME(deadb)
                      HASH_AJ
                    */
                    NULL
               FROM deadblks d2
              WHERE d2.chunkno = d.chunkno
                AND d2.blockno = b.blockno
                AND d2.coffset = b.coffset
           )
       AND NOT EXISTS ( -- avoid copying a block if it is a duplicate
             SELECT /*+
                      QB_NAME(dup)
                      NO_INDEX_FFS(@dup b2@dup blocks_u)
                      INDEX_RS_ASC(@dup b2@dup blocks_u)
                    */
                    NULL
               FROM blocks b2
              WHERE b2.df_key = p_dfkey
                AND b2.blockno = b.blockno
                AND b2.scn = b.scn
                AND b2.ckp_id = b.ckp_id
                AND b2.chunkno > b.chunkno
           )
    )
    , blkgroups
--
--
--
--
--
    AS
    (
     SELECT --+ QB_NAME(bgrp)
            blockno, scn, chunkno, coffset, used, rernk,
            CASE 
              WHEN LAG((rernk * DBMS_RA_INT.UB8MAXVAL) +
                       (chunkno * MAXCHUNKSIZE) +
                       coffset + used)
                       OVER (ORDER BY rernk, blockno)
                    = ((rernk * DBMS_RA_INT.UB8MAXVAL) +
                       (chunkno * MAXCHUNKSIZE) +
                       coffset)
              THEN NULL
              ELSE 1
              END bg
       FROM saveblks
       WHERE freq = 1
    )
    , groups
--
    AS
    (
     SELECT --+ QB_NAME(grp)
            blockno, scn, chunkno, coffset, used, rernk,
            SUM(bg) OVER (PARTITION BY rernk, chunkno ORDER BY blockno) g
       FROM blkgroups
     UNION ALL
     SELECT --+ QB_NAME(deadchunks)
          -10 blockno, 0 scn, chunkno, 0 coffset, 1 used, 0 rernk, 0 g
     FROM deadchunks
    )
    SELECT --+ QB_NAME(ins)
           p_dfkey, KBRSPLBLD_PURGE, p_vbkey, rernk blkrank,
           MIN(blockno) blockno,
           chunkno,
           COUNT(blockno) numblks, 
           MIN(coffset) coffset,
           SUM(used) numbytes,
           null signature
      FROM groups
      GROUP BY rernk, chunkno, g
      ORDER BY blkrank, blockno, chunkno;
 
    deb('q_purge_orphan blk records ' || SQL%ROWCOUNT, AM_DEBUG_MED);
    COMMIT;
 
    dbms_ra_int.info_end;
  END IF;
 
--
  s_purge_dbinc := p_orphaninc;
END q_purge_orphan;
 
--
--
--
PROCEDURE q_purge_dup(p_type        IN  NUMBER,
                      p_dfkey       IN  NUMBER,
                      p_vbkey       IN  NUMBER,
                      p_dbkey       IN  NUMBER,
                      p_currinc     IN  NUMBER,
                      p_fuzdif      IN  NUMBER,
                      p_minscn      IN  NUMBER)
 IS
  l_maxckpid  NUMBER;
BEGIN
  SELECT MAX(ckp_id) INTO l_maxckpid FROM vbdf
    WHERE df_key = p_dfkey
      AND state = VBDF_COMPLETE;
 
  dbms_ra_int.info_start('q_purge_dup',
                         'dfkey ' || p_dfkey || ', vbkey ' || p_vbkey);
 
  INSERT /*+
           QB_NAME(q_purge_dup)
         */
  INTO plans_details (df_key, type, vb_key, blkrank, blockno,
                      chunkno, numblks, coffset, numbytes, signature)
  WITH
    rnkblocks
--
--
--
  AS
  (
   SELECT /*+
            QB_NAME(rnkblocks)
          */
          chunkno, blockno, scn, coffset, used,
          ROW_NUMBER() OVER
          (
            PARTITION BY blockno,
                         scn,
                         CASE
                           WHEN ckp_id <= scn + p_fuzdif
                           THEN ckp_id
                           ELSE 0
                         END
               ORDER BY  blockno, scn DESC, ckp_id DESC, chunkno DESC
          ) rn
   FROM blocks
   WHERE df_key = p_dfkey
     AND ckp_id <= l_maxckpid
  )
  , deadblks
--
  AS
  (
   SELECT --+ QB_NAME(deadblks)
          chunkno, blockno, scn, coffset, used
   FROM rnkblocks
   WHERE rn > 1
  )
  , deadchunks
--
  AS
  (
   SELECT DISTINCT chunkno FROM deadblks
  )
  , saveblks
  AS
  (
--
   SELECT --+ QB_NAME(saveblks)
          b.chunkno, b.blockno, coffset, used, scn,
--
--
          ROW_NUMBER() OVER
          (
            PARTITION BY b.chunkno, b.coffset
               ORDER BY  b.blockno, b.chunkno, b.coffset
          ) freq,
--
--
--
          ROW_NUMBER() OVER
          (
               PARTITION BY blockno
               ORDER BY  blockno, scn DESC, ckp_id DESC, b.chunkno DESC
          ) rernk
   FROM blocks b, deadchunks d
   WHERE b.df_key = p_dfkey
     AND b.chunkno = d.chunkno
     AND (b.blockno, b.coffset) NOT IN
         (SELECT blockno, coffset FROM deadblks WHERE chunkno = b.chunkno)
  )
  , blkgroups
--
--
--
--
--
  AS
  (
   SELECT --+ QB_NAME(bgrp)
          blockno, scn, chunkno, coffset, used, rernk,
          CASE 
            WHEN LAG((rernk * DBMS_RA_INT.UB8MAXVAL) +
                     (chunkno * MAXCHUNKSIZE) +
                     coffset + used)
                     OVER (ORDER BY rernk, blockno)
                  = ((rernk * DBMS_RA_INT.UB8MAXVAL) +
                     (chunkno * MAXCHUNKSIZE) +
                     coffset)
            THEN NULL
            ELSE 1
            END bg
     FROM saveblks
      WHERE freq = 1
 )
  , groups
--
  AS
  (
   SELECT --+ QB_NAME(grp)
          blockno, scn, chunkno, coffset, used, rernk,
          SUM(bg) OVER (PARTITION BY rernk, chunkno ORDER BY blockno) g
     FROM blkgroups
   UNION ALL
   SELECT --+ QB_NAME(deadchunks)
        -10 blockno, 0 scn, chunkno, 0 coffset, 1 used, 0 rernk, 0 g
   FROM deadchunks
  )
  SELECT --+ QB_NAME(ins)
         p_dfkey, KBRSPLBLD_PURGE, p_vbkey, rernk blkrank,
         MIN(blockno) blockno,
         chunkno,
         COUNT(blockno) numblks, 
         MIN(coffset) coffset,
         SUM(used) numbytes,
         NULL signature
    FROM groups
    GROUP BY rernk, chunkno, g
    ORDER BY blkrank, blockno, chunkno;
 
  deb('q_purge_dup plan records ' || SQL%ROWCOUNT, AM_DEBUG_MED);
  COMMIT;
  dbms_ra_int.info_end;
END q_purge_dup;
 
--
--
--
--
--
--
PROCEDURE q_purge_all(p_dfkey       IN  NUMBER,
                      p_vbkey       IN  NUMBER,
                      p_dbkey       IN  NUMBER)
 IS
BEGIN
  dbms_ra_int.info_start('q_purge_all',
                         'dfkey ' || p_dfkey || ', vbkey ' || p_vbkey);
 
  INSERT /*+
           QB_NAME(q_purge_all)
         */
  INTO plans_details (df_key, type, vb_key, blkrank, blockno, 
                      chunkno, numblks, coffset)
  SELECT p_dfkey, KBRSPLBLD_PURGE, p_vbkey, 1 blkrank, -10 blockno,
         chunkno, 1 numblks, 0 coffset
    FROM chunks c
    WHERE df_key = p_dfkey
      AND (filesize > 0 OR dbms_ra_scheduler.s_current_task IS NULL)
      AND NOT EXISTS
              (
--
               SELECT /*+ QB_NAME(x1) */
                      NULL
                 FROM vbdf v, bp p
                WHERE v.vb_key = p.vb_key
                  AND v.db_key = p_dbkey
                  AND p.db_key = p_dbkey
                  AND p.status != 'D'
                  AND krbph_chunkno = c.chunkno
                  AND krbph_dfkey = p_dfkey
              )
      AND NOT EXISTS  /* @@RG DO I CARE ABOUT CHUNKS IN FLIGHT? */
              (
--
               SELECT /*+ QB_NAME(x2) */
                      NULL
                 FROM vbdf v
                WHERE v.krbph_dfkey = p_dfkey
                  AND v.new_krbph = c.chunkno
                  AND v.vb_key = p_vbkey
                  AND v.state = VBDF_COMPLETE
              );
  deb('q_purge_all plan records ' || SQL%ROWCOUNT, AM_DEBUG_MED);
  COMMIT;
  dbms_ra_int.info_end;
END q_purge_all;
 
--
FUNCTION collapse (
  i_cur                          IN collapse_blocks_c
)
RETURN collapse_blocks_t
PIPELINED
IS
--
  l_limit                        CONSTANT NUMBER := 10 * 1024;
--
  l_blocknos                     dbms_sql.number_table;
  l_scns                         dbms_sql.number_table;
  l_chunknos                     dbms_sql.number_table;
  l_useds                        dbms_sql.number_table;
  l_coffsets                     dbms_sql.number_table;
--
  l_initialized                  BOOLEAN := FALSE;
  l_pchunkno                     NUMBER := -2;
  l_pblockno                     NUMBER := -2;
  l_pcoffset                     NUMBER := -2;
--
  l_pblockmn                     NUMBER; -- min block for a given range
  l_numblks                      PLS_INTEGER; -- count of blocks in the range
  l_coffset                      NUMBER; -- min offset
  l_used                         NUMBER; -- sum of all used values
  l_signature                    NUMBER; -- sum of all scn values
--
  l_e                            collapse_b_t;
--
  PROCEDURE fill
  IS
  BEGIN
    l_e.blockno   := l_pblockmn;
    l_e.chunkno   := l_pchunkno;
    l_e.numblks   := l_numblks;
    l_e.coffset   := l_coffset;
    l_e.numbytes  := l_used;
    l_e.signature := l_signature;
  END fill;
BEGIN
  LOOP
    FETCH i_cur
     BULK COLLECT INTO
          l_blocknos, l_scns, l_chunknos, l_useds, l_coffsets
    LIMIT l_limit;
    EXIT WHEN l_blocknos.COUNT = 0;
    FOR i IN 1..l_blocknos.COUNT
    LOOP
      CONTINUE WHEN (l_pblockno = l_blocknos(i));
      IF (l_pchunkno <> l_chunknos(i) OR l_pcoffset <> l_coffsets(i))
      THEN
        IF (l_initialized)
        THEN
          fill;
          PIPE ROW(l_e);
        ELSE
          l_initialized := TRUE;
        END IF;
        l_pblockmn  := l_blocknos(i);
        l_pcoffset  := l_coffsets(i);
        l_numblks   := 0;
        l_used      := 0;
        l_coffset   := l_coffsets(i);
        l_signature := 0;
      END IF;
      l_pblockno  := l_blocknos(i);
      l_pcoffset  := l_pcoffset + l_useds(i);
      l_numblks   := l_numblks + 1;
      l_pchunkno  := l_chunknos(i);
      l_used      := l_used + l_useds(i);
      l_signature := l_signature + l_scns(i);
    END LOOP;
  END LOOP;
  IF (i_cur%ISOPEN) THEN CLOSE i_cur; END IF;
  IF (l_initialized)
  THEN
    fill;
    PIPE ROW(l_e);
  END IF;
  RETURN;
EXCEPTION
  WHEN NO_DATA_NEEDED
  THEN IF (i_cur%ISOPEN) THEN CLOSE i_cur; END IF;
       RETURN;
  WHEN OTHERS
  THEN save_error;
       deb (
         'collapse(): ' || sys.dbms_utility.format_error_backtrace
       , AM_DEBUG_MED
       );
       RAISE;
END collapse;
 
--
FUNCTION skip_last (
  i_cur                          IN skip_last_blocks_c
)
RETURN skip_last_blocks_t
PIPELINED
IS
--
  l_limit                        CONSTANT NUMBER := 10 * 1024;
--
  l_blocknos                     dbms_sql.number_table;
  l_ckpids                       dbms_sql.number_table;
  l_scns                         dbms_sql.number_table;
  l_chunknos                     dbms_sql.number_table;
  l_useds                        dbms_sql.number_table;
  l_coffsets                     dbms_sql.number_table;
--
  l_pblockno                     NUMBER := -2;
--
  l_e                            skip_last_bin_t;
BEGIN
  LOOP
    FETCH i_cur
     BULK COLLECT INTO
          l_blocknos, l_ckpids, l_scns, l_chunknos, l_useds, l_coffsets
    LIMIT l_limit;
    EXIT WHEN l_blocknos.COUNT = 0;
    FOR i IN 1..l_blocknos.COUNT
    LOOP
--
--
      IF (l_pblockno <> l_blocknos(i))
      THEN
         l_pblockno := l_blocknos(i);
         CONTINUE;
      END IF;
      l_e.blockno := l_blocknos(i);
      l_e.ckp_id  := l_ckpids(i);
      l_e.scn     := l_scns(i);
      l_e.chunkno := l_chunknos(i);
      l_e.used    := l_useds(i);
      l_e.coffset := l_coffsets(i);
      PIPE ROW(l_e);
    END LOOP;
  END LOOP;
  IF (i_cur%ISOPEN) THEN CLOSE i_cur; END IF;
  RETURN;
EXCEPTION
  WHEN NO_DATA_NEEDED
  THEN IF (i_cur%ISOPEN) THEN CLOSE i_cur; END IF;
       RETURN;
  WHEN OTHERS
  THEN save_error;
       deb (
         'skip_last(): ' || sys.dbms_utility.format_error_backtrace
       , AM_DEBUG_MED
       );
       RAISE;
END skip_last;
 
$IF FALSE
$THEN
--
FUNCTION collapse (
  i_cur                          IN blocks_c
, i_flags                        IN collapse_flags_t DEFAULT collapse_default
)
RETURN collapse_blocks_t
PIPELINED
--
IS
--
  l_limit                        CONSTANT NUMBER := 10 * 1024;
--
  l_blocknos                     dbms_sql.number_table;
  l_scns                         dbms_sql.number_table;
  l_chunknos                     dbms_sql.number_table;
  l_useds                        dbms_sql.number_table;
  l_coffsets                     dbms_sql.number_table;
--
  l_p                            BINARY_INTEGER;
--
  l_lmxv                         b_t;
--
--
--
--
--
--
--
  l_o                            collapse_t;
--
  l_discard_gap_blocks           BOOLEAN :=
    BITAND(i_flags, discard_gap_blocks) = discard_gap_blocks;
BEGIN
--
--
  l_o.chunkno := -1;
  LOOP
--
--
    IF (l_p IS NOT NULL)
    THEN
      l_lmxv.blockno := l_blocknos(l_p);
      l_lmxv.scn     := l_scns(l_p);
      l_lmxv.chunkno := l_chunknos(l_p);
      l_lmxv.coffset := l_coffsets(l_p);
      l_lmxv.used    := l_useds(l_p);
    END IF;
--
    FETCH i_cur
     BULK COLLECT INTO
          l_blocknos, l_scns, l_chunknos, l_useds, l_coffsets
    LIMIT l_limit;
    EXIT WHEN (l_blocknos.COUNT = 0);
--
    IF (l_lmxv.blockno IS NULL)
    THEN
--
      l_p := 0;
    ELSE
      l_blocknos(0) := l_lmxv.blockno;
      l_scns(0)     := l_lmxv.scn;
      l_chunknos(0) := l_lmxv.chunkno;
      l_coffsets(0) := l_lmxv.coffset;
      l_useds(0)    := l_lmxv.used;
--
      l_p := -1;
    END IF;
 
    LOOP
      LOOP
--
--
--
--
--
--
--
--
--
        l_p := l_p + 1;
        EXIT WHEN
          (l_p + 1 > l_blocknos.LAST OR l_blocknos(l_p) <> l_blocknos(l_p + 1));
      END LOOP;
--
      EXIT WHEN l_p = l_blocknos.LAST;
--
      IF (  l_chunknos(l_p) <> l_o.chunkno
         OR l_coffsets(l_p) <> l_o.coffset + l_o.numbytes
         )
      THEN
        IF (l_o.blockno IS NOT NULL)
        THEN
          PIPE ROW(l_o);
        END IF;
--
        l_o.blockno   := l_blocknos(l_p);
        l_o.chunkno   := l_chunknos(l_p);
        l_o.numblks   := 0;
        l_o.coffset   := l_coffsets(l_p);
        l_o.numbytes  := 0;
        l_o.signature := 0;
      END IF;
--
      l_o.numblks   := l_o.numblks + 1;
      l_o.numbytes  := l_o.numbytes + l_useds(l_p);
      l_o.signature := l_o.signature + l_scns(l_p);
    END LOOP;
  END LOOP;
 
--
--
--
--
  IF (l_lmxv.blockno IS NOT NULL)
  THEN -- we have at least something to deal with
    IF (  l_lmxv.chunkno <> l_o.chunkno
       OR l_lmxv.coffset <> l_o.coffset + l_o.numbytes
       )
    THEN
--
      IF (l_o.blockno IS NOT NULL)
      THEN
        PIPE ROW(l_o);
      END IF;
--
      l_o.blockno   := l_lmxv.blockno;
      l_o.chunkno   := l_lmxv.chunkno;
      l_o.numblks   := 0;
      l_o.coffset   := l_lmxv.coffset;
      l_o.numbytes  := 0;
      l_o.signature := 0;
    END IF;
    l_o.numblks   := l_o.numblks + 1;
    l_o.numbytes  := l_o.numbytes + l_lmxv.used;
    l_o.signature := l_o.signature + l_lmxv.scn;
--
    PIPE ROW(l_o);
  END IF;
--
  IF (i_cur%ISOPEN) THEN CLOSE i_cur; END IF;
  RETURN;
EXCEPTION
  WHEN NO_DATA_NEEDED
  THEN IF (i_cur%ISOPEN) THEN CLOSE i_cur; END IF;
       RETURN;
  WHEN OTHERS
  THEN deb (
         'collapse(): ' || sys.dbms_utility.format_error_backtrace
       , AM_DEBUG_MED
       );
       RAISE;
END collapse;
$END
 
END dbms_ra_pool;
>>>
 
 
define revalidate_dg_synonym
<<<
alter synonym sys.rs$dg compile
>>>
 
 
 
define create_instance_startup_job
<<<
begin
  dbms_scheduler.create_job (
    job_name   => 'ra$trigger_job'
  , job_type   => 'plsql_block'
  , job_action => 
         'begin ' ||
           'dbms_ra_scheduler.init (p_instance_only => true, ' ||
                                   'p_repair => false);' ||
           'dbms_scheduler.disable(''ra$trigger_job'', true);' ||
         'end;'
  , enabled    => false
  , auto_drop  => false
  );
end;
>>>
define create_instance_startup_trigger
<<<
create or replace trigger ba_startup after startup on database
  begin
     dbms_scheduler.enable('ra$trigger_job');
  end;
>>>
define create_instance_shutdown_trigger
<<<
create or replace trigger ba_shutdown before shutdown on database
  begin
    dbms_ra_scheduler.stop (p_instance_only => true); 
  end;
>>>
 
define drop_orsownerfn
<<<
drop function dbms_rai_owner
>>>
 
define drop_orsverifierfn
<<<
drop function dbms_rai_verifier
>>>
 
define drop_am_inst_addresses
<<<
drop function dbms_rai_inst_addresses
>>>
 
define drop_am_sbt_parms
<<<
drop procedure dbms_rai_sbt_parms
>>>
 
define drop_am_url
<<<
drop procedure dbms_rai_url
>>>
 
define drop_am_wallet2url
<<<
drop procedure dbms_rai_wallet2url
>>>
 
define drop_avm_throttle_alloc
<<<
drop procedure dbms_rai_throttle_alloc
>>>
 
define drop_dbms_rs_scheduler
<<<
drop package dbms_ra_scheduler
>>>
 
define drop_dbms_rs_storage
<<<
drop package dbms_ra_storage
>>>
 
define drop_dbms_rs_int
<<<
drop package dbms_ra_int
>>>
 
define drop_dbms_rs
<<<
drop package dbms_ra
>>>
 
define drop_dbms_rs_dump
<<<
drop package dbms_ra_dump
>>>
 
define drop_dbms_rs_pool
<<<
drop package dbms_ra_pool
>>>
 
define drop_ba_resync_clear_error
<<<
drop procedure dbms_rai_fix_error
>>>
 
define drop_populate_rsr_key
<<<
drop procedure dbms_rai_populate_rsr_key
>>>
 
 
 
define upgcat_bdf_21057275
<<<
 
declare
  CURSOR pfiles IS
    SELECT df_key, vb_key
      FROM vbdf
     WHERE pdbinc_key <> 0;
  l_value            VARCHAR2(1024) := NULL;
  l_maxfuzzyscn      NUMBER;
  l_maxckpscn        NUMBER;
  l_minckpscn        NUMBER;
begin
  
--
  begin
 
    SELECT value INTO l_value 
      FROM config
     WHERE name = '_build';
 
  exception
    when no_data_found then
      null;     
  end;
 
--
--
  IF (l_value IS NOT NULL AND
      (TO_DATE(substr(l_value, 0, INSTR(l_value, ' ')), 'DD-MM-YYYY') >
       TO_DATE('05-07-2015', 'DD-MM-YYYY'))) THEN
     RETURN;
  END IF;
 
--
 
  FOR bs IN (
    SELECT s.bs_key key
      FROM bs s, bp p
     WHERE s.bs_key = p.bs_key
       AND s.multi_section = 'Y'
       AND p.vb_key IS NOT NULL
       AND p.status <> 'D' 
       AND p.piece# = 1)
  LOOP
   
     SELECT MAX(ckp_scn),
            MIN(ckp_scn),
            MAX(abs_scn)
      INTO l_maxckpscn, l_minckpscn, l_maxfuzzyscn
      FROM vbdf
     WHERE vb_key IN (SELECT vb_key
                        FROM bp
                       WHERE bs_key = bs.key 
                         AND vb_key IS NOT NULL);
 
    IF (l_maxfuzzyscn < l_maxckpscn) THEN
      l_maxfuzzyscn := l_maxckpscn;
    END IF;
 
    UPDATE bdf
      SET ckp_scn       = l_minckpscn,
          abs_fuzzy_scn = CASE 
                            WHEN l_maxfuzzyscn > l_minckpscn
                              THEN l_maxfuzzyscn
                              ELSE 0
                          END
     WHERE bs_key = bs.key;
 
    UPDATE vbdf
      SET ckp_scn = (SELECT ckp_scn
                       FROM bdf 
                      WHERE bs_key = bs.key)
     WHERE vb_key IN (SELECT vb_key
                        FROM bp
                       WHERE bs_key = bs.key
                         AND vb_key IS NOT NULL);
  END LOOP;
 
--
--
 
  FOR x IN pfiles
  LOOP
    DELETE FROM plans_details
     WHERE df_key = x.df_key
       AND vb_key = x.vb_key;
 
    DELETE FROM plans
     WHERE df_key = x.df_key
       AND vb_key = x.vb_key;
  END LOOP;
 
--
--
 
  UPDATE config
    SET value = to_char(greatest(300, to_number(value)))
   WHERE name = '_interrupt_max';
  commit;
 
end;
 
>>>
 
define mark_build
<<<
BEGIN
  MERGE INTO config USING dual ON (name = '_build')
    WHEN MATCHED THEN 
      UPDATE SET value = '18-10-2018 04:33:00  RDBMS_18.4.0.0.0DBRU_LINUX.X64_181017'
    WHEN NOT MATCHED THEN
      INSERT (name, value)
        VALUES ('_build', '18-10-2018 04:33:00  RDBMS_18.4.0.0.0DBRU_LINUX.X64_181017');
  commit;
END;
>>>
 
define upgcat_bdf_21548299
<<<
 
declare
  l_value            VARCHAR2(1024) := NULL;
begin
  
--
--
  begin
 
    SELECT value INTO l_value 
      FROM config
     WHERE name = '_build';
 
  exception
    when no_data_found then
      null;     
  end;
 
--
  IF (l_value IS NOT NULL AND
      (TO_DATE(SUBSTR(l_value, 0, INSTR(l_value, ' ')), 'DD-MM-YYYY') >
       TO_DATE('10-12-2015', 'DD-MM-YYYY'))) THEN
     RETURN;
  END IF;
 
--
--
 
  UPDATE bdf
    SET blocks = LEAST(blocks, datafile_blocks),
        blocks_read = LEAST(blocks_read, datafile_blocks)
   WHERE bs_key IN (SELECT s.bs_key
                      FROM bs s, bp p
                     WHERE s.bs_key = p.bs_key
                       AND s.multi_section = 'Y'
                       AND p.status <> 'D'
                       AND p.piece# = 1)
     AND (blocks > datafile_blocks OR 
          blocks_read > datafile_blocks);
  
  COMMIT;
 
END;
 
>>>

OHA YOOOO