 ( 
        p_JobID     INTEGER,
        p_MaxLevels INTEGER 
 )
CALLED ON NULL INPUT
DYNAMIC RESULT SETS 100
LANGUAGE SQL
BEGIN

        DECLARE SQLSTATE CHAR(5);
        
-- clean up temp table if exists 
		BEGIN
			DECLARE CONTINUE HANDLER FOR SQLSTATE '42704'
			BEGIN END;
			
			COMMIT;
			DROP TABLE SESSION.Discovered ;
			DROP TABLE SESSION.TempDiscovered ;
			DROP TABLE SESSION.Path ;
			DROP TABLE SESSION.tmpPaths ;
			DROP TABLE SESSION.alljobs ;
			DROP INDEX SESSION.ncidx12 ;
			DROP INDEX SESSION.ncidx13 ;
			DROP INDEX SESSION.ncidx14 ;

		END; 
    
        BEGIN
       --A. Declare variable/Create temporary objects 

           DECLARE v_JobID, v_MaxLevels INTEGER;
           DECLARE v_StartNode INTEGER;
	       DECLARE v_UniqueID, v_forcedSchid INTEGER DEFAULT 0;
	       DECLARE v_Level, v_RC, v_row INTEGER DEFAULT 1;

           DECLARE v_mxrow INTEGER;
           DECLARE v_cpath, v_opath INTEGER DEFAULT -1;
           DECLARE v_cssid INTEGER;
           DECLARE v_ctsid INTEGER;
           DECLARE v_otsid INTEGER;
           DECLARE v_mval  INTEGER;
           DECLARE v_cord  INTEGER;
           
           DECLARE v_Rn INTEGER;
           DECLARE v_JobTrgId INTEGER;
           DECLARE v_OutSchidId INTEGER;
           DECLARE v_Lvl INTEGER;
           DECLARE v_Pathid INTEGER;
           DECLARE v_i INTEGER;
           DECLARE v_JobSrcId INTEGER;
           
           DECLARE GLOBAL TEMPORARY TABLE SESSION.Discovered
						( 
						      src    INTEGER,
					          tgt    INTEGER,
					          ord    INTEGER,
					          ssid   INTEGER,
					          tsid   INTEGER,
					          pathid INTEGER
						) ON COMMIT PRESERVE ROWS 
						     NOT LOGGED;

           CREATE INDEX ncidx12 ON SESSION.Discovered (src ASC, tgt ASC);
           
           
            DECLARE GLOBAL TEMPORARY TABLE SESSION.TempDiscovered
						( 
						      rn     INTEGER,
					          src    INTEGER,
					          tgt    INTEGER,
					          ord    INTEGER,
					          ssid   INTEGER,
					          tsid   INTEGER,
					          pathid INTEGER
						) ON COMMIT PRESERVE ROWS
						     NOT LOGGED;
		
           CREATE INDEX ncidx13 ON SESSION.TempDiscovered (pathid ASC, rn ASC);
           
 
            DECLARE GLOBAL TEMPORARY TABLE SESSION.Path
						( 
						      firstLevel INTEGER,
					          dupsch     INTEGER,
					          pathid     INTEGER,
					          src        INTEGER,
					          tgt        INTEGER,
					          ord        INTEGER,
					          ssid       INTEGER,
					          tsid       INTEGER
						) ON COMMIT PRESERVE ROWS
						     NOT LOGGED;
						     
            CREATE INDEX ncidx14 ON SESSION.Path (PathID ASC, Ord ASC) ; 
 
           
           DECLARE GLOBAL TEMPORARY TABLE SESSION.tmpPaths
						( 
						      Row INTEGER NOT NULL GENERATED ALWAYS AS IDENTITY (START WITH 1, INCREMENT BY 1),
					          pathid     INTEGER,
					          ord        INTEGER,
					          ssid       INTEGER,
					          tsid       INTEGER
						) ON COMMIT PRESERVE ROWS
						     NOT LOGGED;


           DECLARE GLOBAL TEMPORARY TABLE SESSION.alljobs
						( 
						     jobid INTEGER
						) ON COMMIT PRESERVE ROWS 
						     NOT LOGGED;
						     
 --B. Get basic data 

         SET v_JobID     = p_JobID;
		 SET v_MaxLevels = (SELECT (CASE WHEN p_MaxLevels > 1000 THEN 1000 ELSE p_MaxLevels END) FROM SYSIBM.SYSDUMMY1);
         SET v_MaxLevels = COALESCE(v_MaxLevels, 100);
         SET v_StartNode = v_JobID;
        
        
         INSERT INTO SESSION.Discovered (src, tgt, ord,  pathid) VALUES (v_StartNode, CAST(NULL AS INTEGER), 0, v_UniqueID );
         INSERT INTO SESSION.Path       (src, tgt, ord,  pathid) VALUES (v_StartNode, CAST(NULL AS INTEGER), 0, v_UniqueID );


         WHILE  (v_RC > 0 AND v_MaxLevels > v_Level) 
         DO
			     SET v_Level = v_Level + 1;

                 SET v_UniqueID = 1 + (SELECT MAX(pathid) FROM SESSION.Path);

                 INSERT INTO SESSION.TempDiscovered (src, tgt, ord, ssid,  tsid,  pathid, rn )
                 SELECT e.TriggeredBy_JobID,
                        e.JobID,
                        MIN(d.ord) + 1,
                        e.inSCHID,
                        e.outSCHID,
                        d.pathid,
                        ROW_NUMBER() OVER(ORDER BY e.TriggeredBy_JobID)
                 FROM CA7_JobsTriggeredByJobs AS e 
                      INNER JOIN SESSION.Discovered d ON d.src = e.JobID
                                                                    AND ( d.ssid = 0
                                                                         OR e.outSCHID = 0
                                                                         OR d.tsid IS NULL
                                                                         OR d.ssid = e.outSCHID )
                 WHERE NOT EXISTS
								(
								    SELECT 1
								    FROM SESSION.Discovered AS dd
								    WHERE e.TriggeredBy_JobID = dd.src
										AND e.JobID = dd.tgt
								) 
                 GROUP BY e.JobID, e.TriggeredBy_JobID, e.inSCHID, e.outSCHID, d.pathid;

                 BEGIN
                   DECLARE cc3 CURSOR FOR 
                   SELECT rn, src, tgt, tsid, ord, pathid FROM SESSION.TempDiscovered;
                   OPEN cc3;
                   FETCH FROM cc3 INTO v_Rn, v_JobSrcId, v_JobTrgId, v_OutSchidId, v_Lvl, v_Pathid;
                   WHILE (SQLSTATE = '00000')
                   DO
                        SET v_i = 0;
                        BEGIN
                            CALL EZViewer_CA7_Validate_SCHID (v_StartNode, v_JobSrcId, v_JobTrgId, v_OutSchidId, v_Lvl, v_Pathid, v_i);
                        END;
                        IF (v_i = 0) THEN
                        BEGIN
                            DELETE from SESSION.TempDiscovered WHERE rn = v_Rn;
                        END;
                        END IF;
                        FETCH FROM cc3 INTO v_Rn, v_JobSrcId, v_JobTrgId, v_OutSchidId, v_Lvl, v_Pathid;
                   END WHILE;
                   CLOSE cc3;
                 END; 
        
                 SET v_RC = (select count(*) from SESSION.TempDiscovered);
        
			     INSERT INTO SESSION.Path (pathid, src, tgt, ord, ssid, tsid)
                 SELECT t.rn + v_UniqueID,
                               p.src,
                               p.tgt,
                               p.ord,
                               p.ssid,
                               p.tsid
                 FROM SESSION.Path p
                      INNER JOIN SESSION.TempDiscovered t ON p.pathid = t.pathid
                GROUP BY t.rn,  p.src, p.tgt, p.ord, p.ssid, p.tsid
                ;

			    DELETE 
			    FROM SESSION.Path
                WHERE pathid IN (SELECT pathid FROM SESSION.TempDiscovered);

                 INSERT INTO SESSION.Path (pathid, src, tgt, ord, ssid, tsid)
                 SELECT v_UniqueID + td.rn, td.src, td.tgt, td.ord, td.ssid, td.tsid
                 FROM SESSION.TempDiscovered AS td;

                 INSERT INTO SESSION.Discovered(src, tgt, ord, ssid, tsid, pathid)
                 SELECT td.src, td.tgt, td.ord, td.ssid, td.tsid, v_UniqueID + td.rn
                 FROM SESSION.TempDiscovered AS td;

                 TRUNCATE TABLE SESSION.TempDiscovered;   

                 COMMIT; 
         END WHILE;
          

         --select * from #Path order by pathid, ord desc
         UPDATE SESSION.Path pth
               SET firstLevel = ord
         WHERE pth.ord = (
							SELECT MAX(ord)
							FROM SESSION.Path AS p
							WHERE p.pathid = pth.pathid
							GROUP BY p.pathid
						 );


         SET v_UniqueID = 1 + ( SELECT MAX(pathid) FROM SESSION.Path );

        INSERT INTO SESSION.Path (firstLevel, dupsch, pathid, src, tgt, ord, ssid, tsid)
        SELECT td.firstLevel,
               pp.schid,
               v_UniqueID + td.pathid + pp.schid,
               td.src,
               td.tgt,
               td.ord,
               td.ssid,
               td.tsid
        FROM SESSION.Path AS td
                     INNER JOIN
								  (
									 SELECT p.pathid,
										    p.src,
										    spj.schid
									 FROM SESSION.Path AS p
										 INNER JOIN CA7_SchedulesPerJob AS spj ON spj.JobID = p.src
									 WHERE p.firstLevel IS NOT NULL
									 
									 UNION
									 
									 SELECT p.pathid,
										    p.src,
										    CASE
											  WHEN tbd.outSCHID = 0
											  THEN tbd.inSCHID
											  ELSE tbd.outSCHID
										    END AS schid
									 FROM SESSION.Path p
										 INNER JOIN CA7_JobsTriggeredByDatasets AS tbd ON tbd.JobID = p.src
																				AND p.firstLevel IS NOT NULL
																				AND (p.ssid = 0 OR p.ssid IS NULL)
								  ) AS pp ON td.pathid = pp.pathid;

--select * from SESSION.Path order by pathid, ord desc

--delete from SESSION.Path where dupsch is null and pathid in
--        (select p.pathid from SESSION.Path as p  where p.ssid = 0 and p.firstLevel is not Null)


         UPDATE SESSION.Path pth
           SET pth.ssid = - pth.dupsch
         WHERE pth.dupsch IS NOT NULL
               AND pth.ssid = 0
               AND EXISTS (
                             SELECT 1
							 FROM SESSION.Path AS p
							 WHERE p.firstLevel IS NOT NULL
                                   AND p.pathid = pth.pathid
                                   AND p.ord = pth.ord                      
                          );
               

--select 'a', * from SESSION.Path order by pathid, ord desc


        INSERT INTO SESSION.Path (firstLevel, dupsch, pathid, src, tgt, ord, ssid, tsid)
        SELECT p.firstLevel,
               p.dupsch,
               p.pathid,
               p.src,
               p.tgt,
               p.ord,
               tbj.inSCHID,
               p.tsid
        FROM SESSION.Path p
                     INNER JOIN CA7_JobsTriggeredByJobs AS tbj ON tbj.TriggeredBy_JobID = p.src
                                                                  AND p.firstLevel = 0
                                                                  AND p.ssid IS NULL;

--select 'b',* from SESSION.Path order by pathid, ord desc

         DELETE 
         FROM SESSION.Path
         WHERE firstLevel = 0
               AND ssid IS NULL
               AND dupsch IS NULL;


         UPDATE SESSION.Path
           SET ssid = -dupsch
         WHERE ord = 0
               AND dupsch IS NOT NULL
               AND firstLevel IS NOT NULL;


         INSERT INTO SESSION.tmpPaths (pathid, ord, ssid, tsid)
         SELECT   p.pathid, p.ord, p.ssid, p.tsid
         FROM SESSION.Path p
         GROUP BY p.pathid, p.ord, p.ssid, p.tsid
         ORDER BY p.pathid, p.ord DESC
         ;


         SET v_mxrow = (SELECT MAX(Row) FROM SESSION.tmpPaths);
         SET v_otsid = v_forcedSchid;
         SET v_mval  = v_forcedSchid;

       
       BEGIN
             DECLARE tcrs CURSOR FOR	 
			 SELECT  p.row, p.pathid, p.ord, p.ssid, p.tsid
             FROM SESSION.tmpPaths p
             ORDER BY p.row;
          
             
             OPEN tcrs;
             
             FETCH FROM tcrs INTO v_row, v_cpath,  v_cord, v_cssid, v_ctsid;
             
             WHILE (SQLSTATE = '00000') 
             DO
             
             
			                 IF (v_opath = -1) THEN       
			                         SET v_opath = v_cpath;
			                         SET v_otsid = v_cssid;
			                 END IF;      
			
			                 IF(v_cpath <> v_opath) THEN 
			                         SET v_opath = v_cpath;
			                         SET v_otsid = v_cssid;
			                         SET v_mval  = v_forcedSchid;
			                 END IF;
			
			                 IF(v_cssid = 0) 
			                 THEN
			
			                         UPDATE SESSION.Path
			                           SET  ssid = v_mval
			                         WHERE pathid = v_cpath
			                               AND ord = v_cord;
			                 ELSE
			
			                         IF(ABS(v_cssid) <> ABS(v_otsid))
			                         THEN
			
			                                 DELETE 
			                                 FROM SESSION.Path
			                                 WHERE pathid = v_cpath
			                                       AND ord > v_cord;
			                         ELSE
			                                 SET v_mval = -ABS(v_cssid);
			                         END IF;       
			                 END IF;
			
			
			
			
				                 IF (v_ctsid = 0)
				                 THEN
			
				                         UPDATE SESSION.Path
				                           SET tsid = v_mval
				                         WHERE pathid = v_cpath
				                               AND ord = v_cord;
				                ELSE
				                         SET v_mval = -ABS(v_ctsid);
				                         SET v_otsid = v_ctsid;
				                END IF; 
			  
                 FETCH FROM tcrs INTO v_row, v_cpath,  v_cord, v_cssid, v_ctsid;
                 
             END WHILE;
          
             CLOSE tcrs;
          
       END;   
      
         
--select * from SESSION.Path order by pathid, ord desc

       INSERT INTO SESSION.alljobs
       SELECT *
       FROM (
                SELECT  src AS jobid
                FROM SESSION.Path
                
                UNION
                
                SELECT  tgt AS jobid
                FROM SESSION.Path
             )src ;


                 BEGIN
              
					     DECLARE crs CURSOR WITH RETURN FOR	 
					     SELECT t.schid
				         FROM
								 (
									SELECT  ABS(ssid) AS schid
									FROM SESSION.Path
									WHERE ssid <> 0
									
									UNION
									
									SELECT ABS(tsid) AS schid
									FROM SESSION.Path
									WHERE tsid <> 0
									
									UNION
									
									SELECT jtd.inSCHID AS schid
									FROM SESSION.alljobs AS j
										INNER JOIN CA7_JobsTriggeredByDatasets AS jtd ON jtd.JobId = j.jobid
										
									UNION
									
									SELECT jtd.outSCHID AS schid
									FROM SESSION.alljobs AS j
										INNER JOIN CA7_JobsTriggeredByDatasets AS jtd ON jtd.JobId = j.jobid
										
									UNION
									
									SELECT SCHID AS schid
									FROM CA7_SchedulesPerJob jsp
									WHERE jsp.JobID = v_JobID
								 ) t
				         WHERE t.schid IS NOT NULL
				               AND t.schid <> 0
				         ORDER BY t.schid;
					    

                        OPEN crs;
                        
                  END;  
                  
        END;
                      
END 