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

     DECLARE SQLSTATE CHAR(5);


    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
						) WITH REPLACE 
						     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
						) WITH REPLACE 
						     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
						) WITH REPLACE 
						     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
						) WITH REPLACE 
						     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
						) WITH REPLACE 
						     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;


                 DELETE FROM 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;

/*
         WHILE(v_row <= v_mxrow)
         DO

                 SELECT t.pathid, t.ord, t.ssid, t.tsid
                   INTO v_cpath,  v_cord, v_cssid, v_ctsid
                 FROM SESSION.tmpPaths AS t
                 WHERE Row = v_row;

			
			  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;



               SET v_row = v_row + 1;

               COMMIT;

       END WHILE;

   */

--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	
