 ( 
        p_JobID INTEGER,
        p_SCHID 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.withdsn ;
        DROP INDEX SESSION.ncidx12 ;
        DROP INDEX SESSION.ncidx13 ;
        DROP INDEX SESSION.ncidx14 ;
        		
	END;


    BEGIN
       --A. Declare variable/Create temporary objects 

           DECLARE v_JobID, v_SCHID, 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,
					          --path varchar(500),
					          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.withdsn
						( 
						    dsn VARCHAR(255),
						    indsn INTEGER,
						    outdsn INTEGER,
						    pathid INTEGER,
						    src INTEGER,
						    tgt INTEGER,
						    ord INTEGER,
						    ssid INTEGER,
						    tsid INTEGER
						) ON COMMIT PRESERVE ROWS 
						     NOT LOGGED;

  
 --B. Get basic data 

         SET v_JobID     = p_JobID;
         SET v_SCHID     = p_SCHID;
		 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 );


--C. create appropriate indexes

		--select * from CA7_Jobs
		--select * from CA7_SchedulesPerJob
		--select * from CA7_JobsTriggeredByJobs
		--select * from CA7_JobsTriggeredByDatasets


         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.tsid IS NULL
                                                                         OR d.ssid = e.outSCHID
                                                                         OR d.ssid = 0
                                                                         OR e.outSCHID = 0)
                 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.withdsn (dsn, indsn, outdsn, pathid, src, tgt, ord, ssid, tsid)
       SELECT DISTINCT
              jtd.DSN,
              jtd.inSCHID,
              jtd.outSCHID,
              p.pathid,
              p.src,
              p.tgt,
              p.ord,
              p.ssid,
              p.tsid
       FROM SESSION.Path AS p
            LEFT JOIN CA7_JobsTriggeredByDatasets AS jtd ON jtd.JobID = p.src
                                                                AND jtd.inSCHID = v_SCHID
                                                                AND (jtd.outSCHID = ABS(p.ssid)
                                                                     OR jtd.outSCHID = 0
                                                                     OR p.ssid = 0
                                                                     OR p.ssid IS NULL);
    
             BEGIN
          
				     DECLARE crs CURSOR WITH RETURN FOR	 
				     SELECT DISTINCT
						       p.pathid,
						       p.src,
						       p.tgt,
						       p.ord,
						       p.ssid,
						       p.tsid,
						       p.dsn,
						       p.indsn,
						       p.outdsn
						FROM SESSION.withdsn AS p
						WHERE pathid IN
										(
										    SELECT DISTINCT pathid
										    FROM SESSION.withdsn AS pp
										    WHERE ABS(ssid) = v_SCHID
										          OR ABS(tsid) = v_SCHID
										          OR dsn IS NOT NULL
										)
						ORDER BY p.pathid,
						         p.ord DESC;

                   OPEN crs;
                    
              END;  
				  
		END;	
		
END				  