(
IN p_BRDComputeType SMALLINT 
)
CALLED ON NULL INPUT
DYNAMIC RESULT SETS 0
LANGUAGE SQL
BEGIN 
       
       --CALL EZAT5010.BRD_PrepareCache(0) ;
       

      DECLARE SQLSTATE, v_sqlstate_test CHAR(5) DEFAULT '00000';
      DECLARE SQLCODE,  v_sqlcode_test INTEGER DEFAULT 0;  
      DECLARE v_BRDStatus_Check, v_BRDComputeType SMALLINT DEFAULT 0;
      DECLARE v_CurrentSchema, v_CurrentObject  VARCHAR(200) DEFAULT ''; 
      DECLARE v_dynSQL VARCHAR(8000) DEFAULT '';
      DECLARE v_stmt STATEMENT;
 
      SET v_BRDComputeType = COALESCE(p_BRDComputeType, 0); /* 0 FULL , 1 PARTIAL*/
      
      SET v_BRDComputeType = 0; -- we have to compute  VarIDConsolidate for all variables all the time ... so FULL is faster than PARTIAL + UPDATE on variable table
      
      SELECT CURRENT_SCHEMA INTO v_CurrentSchema FROM SYSIBM.SYSDUMMY1;	

	 
	  -- CHECK IF WE CAN COMPUTE BRD
	  BEGIN

					DECLARE brd_agg_in_progress CONDITION FOR SQLSTATE '80007';
					DECLARE EXIT HANDLER FOR SQLEXCEPTION RESIGNAL;  
                   
                   
                    SELECT 1 INTO v_BRDStatus_Check
			        FROM  BRD_Status 
			        WHERE  BRDProcessStatusTypeID = 1  /*0 prepare; 1 computation;  2 success; 3 error */
			              AND BRDID = (SELECT MAX(BRDID) FROM BRD_Status)
			        WITH UR ;				
                  
                    SET v_BRDStatus_Check = COALESCE(v_BRDStatus_Check, 0);
			
				    IF (v_BRDStatus_Check > 0) 
				      THEN
			                             SIGNAL brd_agg_in_progress
			                             SET MESSAGE_TEXT = 'BRD Prepare Cache is already in progress.';
			                             
			                             RETURN ;	
			                           
			          END IF ;	
			          

	   END;
	
   
       -- MAIN COMPUTATION
       BEGIN
 
		    DECLARE v_BRDID, v_BRDCurrentVersion, v_ProjVersion, v_BRDVariableCount, v_BRDVariableDistinctCount INTEGER DEFAULT NULL;
		    DECLARE v_date TIMESTAMP;
		    DECLARE v_ProjGUID, v_ProjectName, v_Msg VARCHAR(255) DEFAULT '';
            DECLARE v_NrProg , v_MaxProgID INTEGER DEFAULT 0;  
            DECLARE v_rc, v_i, v_j INTEGER;
            
            DECLARE v_VarID, v_ChildVarID, v_ChildLevel INTEGER DEFAULT 0;
            DECLARE v_ResourceTypeID_Prog, v_ResourceTypeID_Var INTEGER DEFAULT NULL;
            

	        DECLARE EXIT HANDLER FOR SQLEXCEPTION RESIGNAL;  


            DECLARE GLOBAL TEMPORARY TABLE SESSION.pgmtype
					( 
		                ProgramTypeID INTEGER
					)
					   WITH REPLACE 
                       ON COMMIT PRESERVE ROWS
					   NOT LOGGED;

			CREATE UNIQUE INDEX unqidx0 ON SESSION.pgmtype (ProgramTypeID);						   
				   
            
            DECLARE GLOBAL TEMPORARY TABLE SESSION.pgmflt
					(
					  ProgID INTEGER NOT NULL
					)  
					   WITH REPLACE 
                       ON COMMIT PRESERVE ROWS
					   NOT LOGGED;  
					     
			CREATE UNIQUE INDEX unqidx1 ON SESSION.pgmflt (ProgID);	
					

			 DECLARE GLOBAL TEMPORARY TABLE SESSION.varout
					(
					  VarID INTEGER 
					)  
					   WITH REPLACE 
                       ON COMMIT PRESERVE ROWS
					   NOT LOGGED;  
								
		
			 DECLARE GLOBAL TEMPORARY TABLE SESSION.varflt
					(
					  VarID INTEGER NOT NULL
					)  
					   WITH REPLACE 
                       ON COMMIT PRESERVE ROWS
					   NOT LOGGED;  
					
						
			  DECLARE GLOBAL TEMPORARY TABLE SESSION.varflttmp
					(
					  VarID INTEGER NOT NULL, 
					  VarILevel INTEGER ,
					  Test SMALLINT NOT NULL
					)  
					   WITH REPLACE 
                       ON COMMIT PRESERVE ROWS
					   NOT LOGGED;  
				
				
			DECLARE GLOBAL TEMPORARY TABLE SESSION.stmt
					(
					    VarID INTEGER NOT NULL,
					    VarILevel INTEGER,
						StatementTypeID INTEGER,
						ProgID INTEGER,
						CopyID INTEGER,
						CopyTypeID INTEGER ,
						OccurID INTEGER,
						PathID INTEGER,
						StartRow INTEGER,
						EndRow INTEGER,
						StartCol INTEGER,
						EndCol INTEGER,
						IsCalculation       SMALLINT,
						IsCondition         SMALLINT,
						IsDBIO              SMALLINT,
						IsFileIO            SMALLINT,
						IsMQ                SMALLINT,
						IsScreen            SMALLINT,
						IsAssignment        SMALLINT,
						Is88VarLvlCondition SMALLINT
					)  
					   WITH REPLACE 
                       ON COMMIT PRESERVE ROWS
					   NOT LOGGED;  							 


               DECLARE GLOBAL TEMPORARY TABLE SESSION.categ
					(
					    StatementTypeID INTEGER,
						A1 INTEGER,
						A2 INTEGER,
						A3 INTEGER,
						A4 INTEGER,
						A5 INTEGER,
						A6 INTEGER,
						A7 INTEGER,
						A8 INTEGER
					)  WITH REPLACE 
                       ON COMMIT PRESERVE ROWS
					   NOT LOGGED;  		


                DECLARE GLOBAL TEMPORARY TABLE SESSION.copyb
					(
						ResourceID INTEGER NOT NULL,
                        ResourceTypeID INTEGER NOT NULL,
						ResourceName VARCHAR(250) NOT NULL, 
						ResourceHash VARCHAR(32) NOT NULL,
						ResourcePathID INTEGER NOT NULL
					)  
					   WITH REPLACE 
                       ON COMMIT PRESERVE ROWS
					   NOT LOGGED;  		

                CREATE UNIQUE INDEX unqidx2 ON SESSION.copyb (ResourceID, ResourceTypeID);	
                
                
                DECLARE GLOBAL TEMPORARY TABLE SESSION.var
					(
						 VarID INTEGER NOT NULL,
						 VarName VARCHAR(250) NOT NULL,
						 VariableHash VARCHAR(32) NOT NULL,
						 VarIDConsolidate INTEGER NOT NULL,
						 CopyID INTEGER,
						 CopyTypeID INTEGER,
						 CopyName VARCHAR(250),   
						 RootVarID INTEGER ,
						 RecordName VARCHAR(250),
						 ProgID INTEGER ,
						 ProgName VARCHAR(250),
						 PathID INTEGER,
						 StartRow INTEGER,
						 EndRow INTEGER,
						 StartCol INTEGER,
						 EndCol INTEGER
                     ) 
                       WITH REPLACE 
                       ON COMMIT PRESERVE ROWS
					   NOT LOGGED;  


                  DECLARE GLOBAL TEMPORARY TABLE SESSION.varhierarchy
					(
						 VarID INTEGER NOT NULL,
						 ChildVarID INTEGER NOT NULL,
						 ChildLevel SMALLINT NOT NULL
				     ) 
				       WITH REPLACE 
                       ON COMMIT PRESERVE ROWS
					   NOT LOGGED; 


                       
                    SET v_date = CURRENT_TIMESTAMP;
                       
				    SELECT ProjectVersion INTO v_BRDCurrentVersion
				    FROM  BRD_Status 
				    WHERE  BRDID = (SELECT MAX(BRDID) FROM BRD_Status WHERE BRDProcessStatusTypeID = 2) 
				    WITH UR ;
					   
					SET v_BRDCurrentVersion = COALESCE(v_BRDCurrentVersion, 0);

					SET v_ProjVersion = (SELECT Version FROM VC_Version);	
                    SET v_ProjGUID    = (SELECT PropValue FROM Pj_ProjectProp WHERE ID_PropType = 64); -- ProjectGUID
					SET v_ProjectName = (SELECT PropValue FROM Pj_ProjectProp WHERE ID_PropType = 65); -- ProjectName

			   		SET v_ResourceTypeID_Prog = (SELECT ResourceID FROM ResourceTypes WHERE Name = 'PROGRAM' FETCH FIRST 1 ROWS ONLY) ;
					SET v_ResourceTypeID_Var  = (SELECT ResourceID FROM ResourceTypes WHERE Name = 'VARIABLES' FETCH FIRST 1 ROWS ONLY) ;
						
											
				BEGIN 

                            
                        DECLARE EXIT HANDLER FOR SQLEXCEPTION 
                          BEGIN
                                SELECT SQLSTATE, SQLCODE INTO v_sqlstate_test ,v_sqlcode_test FROM SYSIBM.SYSDUMMY1;
                                
        					    SET v_date = CURRENT_TIMESTAMP;
                                UPDATE BRD_Status
						        SET  	BRDProcessStatusTypeID = 3, -- error 
								        BRDVariableCount = 0,
										BRDVariableDistinctCount = 0,
						                eTimeStamp = v_date,
										Notes = COALESCE(Notes, '') || '##3 - '|| CAST(v_date AS VARCHAR(23)) ||' SQLSTATE='|| COALESCE(v_sqlstate_test, '') || ' SQLCODE='|| COALESCE(CAST(v_sqlcode_test AS VARCHAR(30)), '') ||'##'   -- error							   
			                    WHERE  BRDID = v_BRDID;
			                    
                                RESIGNAL;
                                RETURN;
                                
		                    END;
                        
                         
						     --0. LOACAL CONFIGURATION AREA
						     INSERT INTO SESSION.pgmtype(ProgramTypeID) VALUES(1) ; /*COBOL*/
					
						     --1. BRD FULL
		                     -- GET PROGRAMS TO DEAL WITH
							 INSERT INTO SESSION.pgmflt (ProgID)
							 SELECT pgm.ProgramID 
							 FROM Programs pgm
							 WHERE EXISTS (SELECT 1 FROM SESSION.pgmtype pgmtp WHERE pgm.ProgramTypeID = pgmtp.ProgramTypeID)
								   AND pgm.OccurID > 0
							 GROUP BY pgm.ProgramID ;
								       
	                         COMMIT;
					        --SELECT * FROM SESSION.pgmflt

							    
			
			                  -- 2. GET SOME INFO FOR LOG PURPOSE
		                      SELECT  COUNT(ProgID), MAX(ProgID) INTO v_NrProg, v_MaxProgID FROM SESSION.pgmflt;
		                      SET v_Msg = '##ProgNr=' || CAST(COALESCE(v_NrProg, 0) AS VARCHAR(20)) || '; MaxProgID=' || CAST(COALESCE(v_MaxProgID, 0) AS VARCHAR(20)) || '##';


                               -- PUT A FLAG SINCE WE HAVE STARTED COMPUTATION 
		                      INSERT INTO BRD_Status(ProjectName, ProjectGUID, ProjectVersion, BRDProcessStatusTypeID, BRDProcessType, BRDVariableCount, BRDVariableDistinctCount, eTimeStamp, Notes)
							  VALUES( v_ProjectName, 
								     v_ProjGUID, 
								     v_ProjVersion,
								     0, -- prepare
								     CASE v_BRDcomputetype WHEN 0 THEN 'FULL' ELSE 'PARTIAL' END, 
								     COALESCE(v_BRDVariableCount, 0),
								     COALESCE(v_BRDVariableDistinctCount, 0),
								     v_date,  
								     v_Msg || '##0 - ' || CAST(v_date AS VARCHAR(23)) || '##'    
				                    );
				                    
				               VALUES IDENTITY_VAL_LOCAL() INTO v_BRDID;



		                  -- 3. GET AUXILIARY DATA
				       

					      -- 3.1  data from configuration area ( category <-> statementtype)
					      --  a statement type could be in many categories so we have to do a pivote
			                INSERT INTO SESSION.categ 
			                       (StatementTypeID, A1, A2, A3, A4, A5, A6, A7, A8)
							SELECT  StatementTypeID 
							       ,NULLIF(MAX(A1), 0) AS A1, NULLIF(MAX(A2), 0) AS A2, NULLIF(MAX(A3), 0) AS A3, NULLIF(MAX(A4), 0) AS A4
							       ,NULLIF(MAX(A5), 0) AS A5, NULLIF(MAX(A6), 0) AS A6, NULLIF(MAX(A7), 0) AS A7, NULLIF(MAX(A8), 0) AS A8
							FROM (     
										SELECT bwcd.StatementTypeID, 
										       CASE bwc.CategoryID WHEN 1 THEN 1 ELSE 0 END AS A1,
										       CASE bwc.CategoryID WHEN 2 THEN 1 ELSE 0 END AS A2,
										       CASE bwc.CategoryID WHEN 3 THEN 1 ELSE 0 END AS A3,
										       CASE bwc.CategoryID WHEN 4 THEN 1 ELSE 0 END AS A4,
										       CASE bwc.CategoryID WHEN 5 THEN 1 ELSE 0 END AS A5,
										       CASE bwc.CategoryID WHEN 6 THEN 1 ELSE 0 END AS A6,     
										       CASE bwc.CategoryID WHEN 7 THEN 1 ELSE 0 END AS A7,
										       CASE bwc.CategoryID WHEN 8 THEN 1 ELSE 0 END AS A8
										FROM BRD_Category bwc
										   LEFT OUTER JOIN BRD_CategoryDetails bwcd ON bwc.CategoryID = bwcd.CategoryID AND bwcd.IsActive = 1 
										WHERE bwc.IsActive = 1
										   AND bwcd.StatementTypeID IS NOT NULL
									)src
							GROUP BY StatementTypeID;						
                            COMMIT;           



					      -- 3.2  get info related to copybooks
			                INSERT INTO SESSION.copyb
                                             (ResourceID, ResourceTypeID, ResourceName, ResourceHash,  ResourcePathID)
							SELECT DISTINCT r.ResourceID, r.ResourceType, r.Name AS ResourceName, h.SemanticUID AS ResourceHash, occ.PathID
							FROM Resources r
								   INNER JOIN Occurrences occ ON r.OccurID = occ.OccurID
								   INNER JOIN SemanticUIDContainer h On r.ResourceID = h.ResourceID AND r.ResourceType = h.ResourceType
							WHERE r.ResourceType = 13 ; --IN (13 /*COPY*/, 67 /*PL1_COPY*/, 99 /*ASSEMBLER_COPY*/)
								
                            COMMIT;           
                            CREATE INDEX ncidx_copy_res ON SESSION.copyb (ResourcePathID, ResourceID, ResourceTypeID, ResourceName);



              -- 4. GET MAIN DATA 
              
                     --4.1' technical variables .... so we will have to remove them
                             INSERT INTO SESSION.varout (VarID)
							 SELECT VarID
							 FROM Variables 
							 WHERE isFiller = -1
							       OR
							       VarName LIKE 'DFHCOMMAREA'
								   OR
								   VarName LIKE 'SQLCODE'
								 -- OR
								 -- VarName LIKE 'RETURN-CODE'
								 -- OR
								 -- VarName LIKE 'SQLSTATE%'
								 -- OR
								 -- VarName LIKE 'SQLWARN%'
								;
								COMMIT;

         
                     -- 4.1 GET STATEMENTS 
				          INSERT INTO SESSION.stmt
					            (VarID, VarILevel, StatementTypeID, ProgID, CopyID, CopyTypeID, OccurID
							     ,PathID,  StartRow, EndRow,  StartCol, EndCol
								 ,IsCalculation, IsCondition, IsDBIO, IsFileIO, IsMQ, IsScreen, IsAssignment ,Is88VarLvlCondition)
							SELECT 
							      VarID, VarILevel, StatementTypeID, ProgID, CopyID, CopyTypeID, OccurID,
							      PathID,  StartRow, EndRow,  StartCol, EndCol, 
								  MAX(IsCalculation) AS IsCalculation, 
								  MAX(IsCondition) AS IsCondition,  
								  MAX(IsDBIO) AS IsDBIO, 
								  MAX(IsFileIO) AS IsFileIO,
								  MAX(IsMQ) AS IsMQ, 
								  MAX(IsScreen) AS IsScreen, 
								  MAX(IsAssignment) AS IsAssignment,
								  MAX(Is88VarLvlCondition) AS Is88VarLvlCondition
							FROM (
										SELECT 
											  sr.ResourceID AS VarID
											 ,v.iLevel AS VarILevel
											 ,sr.StatementType AS StatementTypeID
											 ,os.ProgID 
											 ,cpy.ResourceID AS CopyID
										     ,cpy.ResourceTypeID AS CopyTypeID
											 ,os.OccurID
											 ,os.PathID
											 ,os.StartRow
											 ,os.EndRow
											 ,os.StartCol
											 ,os.EndCol
											 -- categories
											 ,CASE WHEN ctg.A1 IS NOT NULL AND sr.bRead IN (1, 2)                            THEN 1 ELSE 0 END IsCalculation
											 ,CASE WHEN sr.bRead > 3                                                         THEN 1 ELSE 0 END IsCondition
											 ,CASE WHEN ctg.A3 IS NOT NULL AND sr.bRead IN (1, 2) AND db.OccurID IS NOT NULL THEN 1 ELSE 0 END IsDBIO
											 ,CASE WHEN ctg.A4 IS NOT NULL AND sr.bRead IN (1, 2)                            THEN 1 ELSE 0 END IsFileIO
											 ,CASE WHEN ctg.A5 IS NOT NULL AND sr.bRead IN (1, 2)                            THEN 1 ELSE 0 END IsMQ
											  -- screen
										     ,CASE WHEN ctg.A6 IS NOT NULL AND sr.bRead IN (1, 2) AND sr.StatementType IN (694, 698) /* IMS: GU, ISRT*/ AND scrn.OccurID IS NOT NULL THEN 1
											       WHEN ctg.A6 IS NOT NULL AND sr.bRead IN (1, 2) AND sr.StatementType NOT IN (694, 698) THEN 1 ELSE 0 END IsScreen	
										      -- screen
											 ,CASE WHEN ctg.A7 IS NOT NULL AND sr.bRead IN (1, 2)                            THEN 1 ELSE 0 END IsAssignment
											 ,CASE WHEN sr.bRead > 3       AND v.iLevel = 88                                 THEN 1 ELSE 0 END Is88VarLvlCondition
										FROM StatementReference sr
										    INNER JOIN OccurrencesStmt os ON sr.OccurID = os.OccurID
										    INNER JOIN Variables v ON sr.ResourceID = v.VarID 
										    LEFT OUTER JOIN SESSION.varout vo ON v.VarID = vo.VarID -- remove technical variables
										    LEFT OUTER JOIN SESSION.categ ctg ON ctg.StatementTypeID = sr.StatementType
										    LEFT OUTER JOIN 
															(
															   SELECT sr2.OccurID
															   FROM StatementReference sr2
																   INNER JOIN OccurrencesStmt os2 ON os2.OccurID = sr2.OccurID
															   WHERE sr2.ResourceType IN (1, 56, 77, 78, 182, 209)
																    AND sr2.bread in (1, 2) -- involved in READ, WRITE 
																    GROUP BY sr2.OccurID
															) db ON db.OccurID = sr.OccurID
											 LEFT OUTER JOIN 
															(
															   SELECT sr2.OccurID
															   FROM StatementReference sr2
																   INNER JOIN OccurrencesStmt os2 ON os2.OccurID = sr2.OccurID
															   WHERE sr2.ResourceType IN (212) -- IMS Message Descriptor
																    AND sr2.bread in (1, 2) -- involved in READ, WRITE 
															   GROUP BY sr2.OccurID
															) scrn ON scrn.OccurID = sr.OccurID			
											LEFT OUTER JOIN SESSION.copyb cpy ON cpy.ResourcePathID = os.PathID  -- if statement is from copy
										 WHERE sr.ResourceType = v_ResourceTypeID_Var /*VARIALES*/    
											  AND sr.ResourceID > 0
											  AND vo.VarID IS NULL
											  AND EXISTS (SELECT 1 FROM SESSION.pgmflt f WHERE os.ProgID = f.ProgID) 
					      ) src
	                   GROUP BY  VarID, VarILevel, StatementTypeID, ProgID, CopyID, CopyTypeID, OccurID,
				           PathID, StartRow, EndRow,  StartCol, EndCol ;   							                 
                       COMMIT; 
									        
									        
								           
					  INSERT INTO SESSION.varflttmp(VarID, VarILevel, Test)
                      SELECT DISTINCT VarID, VarILevel, IsFileIO + IsMQ + IsScreen AS Test
		    		  FROM  SESSION.stmt;					    		  
                      COMMIT;
             
 
             
                       --4.2  determine variable hierarchy (Parent -> Child) only for specific variable not for all (IsFileIO + IsMQ + IsScreen + IsDB)
					   -- level 0 

                        INSERT INTO SESSION.varhierarchy (VarID, ChildVarID, ChildLevel)
                        SELECT DISTINCT VarID, VarID AS ChildVarID, 0 AS ChildLevel
				        FROM SESSION.varflttmp
				        WHERE Test > 0  -- only variable that are in screen, mq, file
				              AND VarID > 0 
				              AND VarILevel != 88;			              
					    COMMIT;      
					         
					         
			         

                      
					    VALUES(0, 1, 2001) INTO v_rc, v_i, v_j; -- level 1-> 2000 (2000 levels of imbrication)  
					    WHILE (v_i < v_j)
						DO


								    --down direction
									INSERT INTO SESSION.varhierarchy(VarID, ChildVarID, ChildLevel)
								    SELECT f1.VarID, x.VarID, v_i
								    FROM Variables x
										INNER JOIN SESSION.varhierarchy f1 ON f1.ChildLevel = v_i - 1 AND f1.ChildVarID = x.Father
										LEFT OUTER JOIN SESSION.varout vo ON x.VarID = vo.VarID  -- remove technical variables
										--LEFT OUTER JOIN SESSION.varhierarchy f2 ON f1.VarID = f2.VarID AND x.VarID = f2.ChildVarID					  
									WHERE x.iLevel != 88
									      AND vo.VarID IS NULL
									      -- f2.VarID IS NULL
									;
									
					   
								    GET DIAGNOSTICS v_rc = ROW_COUNT; 
                                    COMMIT; 


								    IF (v_rc = 0 )
								    THEN
									    SET v_i = v_j;
								    ELSE 
									    SET v_i = v_i + 1;
									 END IF;
						END WHILE;
                        COMMIT;
            
        
			             --4.3 variable hierarchy step 2 (Child -> Parent) only for Level 88 variable hierarchy (up direction)
						-- only father must me be in hierarchy but is inserted as child for compatibility with already implemented logic 
						-- Lvl = 10088 since we rely further on it
							INSERT INTO SESSION.varhierarchy(VarID, ChildVarID, ChildLevel)
							SELECT v.VarId, v.Father AS ChildVarID, 10088 AS ChildLevel
							FROM Variables v
								 INNER JOIN (   SELECT VarID
												FROM SESSION.stmt 
												WHERE Is88VarLvlCondition = 1 
												GROUP BY VarID 
												) f ON v.VarId = f.VarID 
							WHERE v.VarId != v.Father AND v.Father > 0;		              
					        COMMIT; 				
    					
    					     --4.3 GET VARIABLE FOR FILTERING PURPOSE
	                       INSERT INTO SESSION.varflt(VarID)
						   SELECT VarID
						   FROM (  
						         SELECT ChildVarID AS VarID FROM SESSION.varhierarchy WHERE ChildLevel > 0
	
								 UNION
	
								 SELECT VarID FROM SESSION.varflttmp
	
								 UNION
	
								 SELECT v.VarID
						         FROM Variables v 
						                LEFT OUTER JOIN SESSION.varout vo ON v.VarID = vo.VarID -- remove technical variables
						         WHERE vo.VarID IS NULL
						                AND EXISTS (SELECT 1 FROM SESSION.pgmflt f WHERE v.ProgIDReference = f.ProgID)
							    )src 
						  WHERE src.VarID > 0 ;
  
 
                         COMMIT;
                         CREATE INDEX NCIDX_VARFLT_VarID ON SESSION.varflt (VarID);        


			                  -- 4.4 GET VARIABLE header
		                       INSERT INTO SESSION.var
                                   (VarID, VarName, VariableHash, VarIDConsolidate, CopyID, CopyTypeID, CopyName, RootVarID, RecordName, ProgID, ProgName
                                    ,PathID, StartRow, EndRow, StartCol, EndCol)
							   SELECT  
									 v1.VarID 
									,v1.VarName AS VarName
									,h.SemanticUID AS VariableHash 
									,DENSE_RANK() OVER (ORDER BY v1.PathID, v1.StartRow, v1.EndRow, v1.StartCol, v1.EndCol, v1.VarName) AS VarIDConsolidate
								    ,v1.CopyID
							        ,v1.CopyTypeID
							        ,v1.CopyName
									,v1.RootVarID
									,rec.VarName AS RecordName
									,v1.ProgID
									,pgm.ProgramName AS ProgName
									,v1.PathID ,v1.StartRow ,v1.EndRow ,v1.StartCol ,v1.EndCol
								FROM	(
										SELECT  
										    v.VarID 
										   ,v.VarName AS VarName
										   ,v.Ancestor AS RootVarID
										   ,v.ProgIDReference  AS ProgID
										   ,occ.PathID 
										   ,occ.StartRow 
										   ,occ.EndRow 
										   ,occ.StartCol 
										   ,occ.EndCol
										   ,cpy.ResourceID AS CopyID
									       ,cpy.ResourceTypeID AS CopyTypeID
									       ,cpy.ResourceName AS CopyName 
										FROM  Variables v
										      INNER JOIN Occurrences occ ON v.OccurID = occ.OccurID
									          LEFT OUTER JOIN SESSION.copyb cpy ON occ.PathID = cpy.ResourcePathID
										WHERE v.VarID IN (SELECT VarID FROM SESSION.varflt)  
										      AND v.IsCopy = CASE WHEN cpy.ResourceID IS NOT NULL THEN -1  
									                              ELSE 0 
									                          END -- if a variable is defined in copy then must exist a copyID
									  )v1
								      INNER JOIN SemanticUIDContainer h ON  v1.VarID = h.ResourceID AND h.ResourceType = v_ResourceTypeID_Var
									  LEFT OUTER JOIN Variables rec ON v1.RootVarID = rec.VarID
									  LEFT OUTER JOIN Programs pgm ON v1.ProgID = pgm.ProgramID ;									  
                                      COMMIT;

 	
		        
                         BEGIN 
 
                          DECLARE EXIT HANDLER FOR SQLEXCEPTION 
                          BEGIN
                                ROLLBACK WORK TO SAVEPOINT BRDSVPOINT;
                                RESIGNAL;
                                RETURN;
		                    END;
                
                
                
			                     -- SET A SAVEPOINT TO BE ABLE TO ROLLBACK
			                     SAVEPOINT BRDSVPOINT ON ROLLBACK RETAIN CURSORS;

                                     
	                             SET v_date = CURRENT_TIMESTAMP;
							     UPDATE BRD_Status
							     SET  	BRDProcessStatusTypeID = 1, -- start
									        eTimeStamp = v_date,
											Notes = COALESCE(Notes, '') || '##1 - ' || CAST(v_date AS VARCHAR(23)) || '##'      -- start							   
						         WHERE  BRDID = v_BRDID;
			             

                        
                        
                        
                        		 -- A. BRD_DirectStatements
							     DELETE FROM BRD_DirectStatements WHERE 1 = 1;  


							     INSERT INTO BRD_DirectStatements
									   (VarID, StatementTypeID, ProgID, CopyID, CopyTypeID, OccurID, 
										PathID, StartRow, EndRow, StartCol, EndCol, 
										IsCalculation, IsCondition, IsDBIO, IsFileIO, IsMQ, IsScreen, IsAssignment, Is88VarLvlCondition,
										BRDID)
							     SELECT s.VarID, s.StatementTypeID, s.ProgID, s.CopyID, s.CopyTypeID, s.OccurID,  
									    s.PathID, s.StartRow, s.EndRow, s.StartCol, s.EndCol,
									    s.IsCalculation, s.IsCondition, s.IsDBIO, s.IsFileIO, s.IsMQ, s.IsScreen, s.IsAssignment, s.Is88VarLvlCondition,
									    v_BRDID AS BRDID
							      FROM SESSION.stmt s
							      WHERE s.VarID IN (SELECT v.VarID FROM SESSION.var v) ;

			 


                                  -- B. BRD_Variables
                    		        DELETE FROM BRD_Variables WHERE 1 = 1; 
					            
					            
								    INSERT INTO BRD_Variables
									       (VarID, VarName, VariableHash, VarIDConsolidate, 
											CopyID, CopyTypeID, CopyName, RootVarID, RecordName, ProgID, ProgName, 
											PathID, StartRow, EndRow, StartCol, EndCol, DirectIndirectDistProgNr
										   ,BRDID)
								    SELECT  v.VarID ,v.VarName ,v.VariableHash ,v.VarIDConsolidate
										   ,v.CopyID, v.CopyTypeID, v.CopyName, v.RootVarID, v.RecordName, v.ProgID, v.ProgName 
										   ,v.PathID, v.StartRow, v.EndRow, v.StartCol, v.EndCol 
										   ,COALESCE(pnr.DirectIndirectDistProgNr, 0) AS DirectIndirectDistProgNr
									       ,v_BRDID AS BRDID
									 FROM SESSION.var v
										   LEFT OUTER JOIN
								               ( -- number of distinct programs 
											        SELECT VarID, COUNT(DISTINCT ProgID) AS DirectIndirectDistProgNr
						                            FROM (				 
														    SELECT VarID, ProgID 
														    FROM  SESSION.stmt
													    
													        UNION	
													    	
														    SELECT vh.ChildVarID AS VarID, s.ProgID
												            FROM SESSION.varhierarchy  vh
														         INNER JOIN SESSION.stmt s ON s.VarID = vh.VarID 
															WHERE vh.ChildLevel > 0              
													                 AND s.IsFileIO + s.IsMQ + s.IsScreen + s.Is88VarLvlCondition > 0
													      )src
												    GROUP BY VarID
								                ) pnr ON pnr.VarID = v.VarID;
									 
									 

              
					                 SELECT COUNT(VarID),  COUNT(DISTINCT VarName) INTO v_BRDVariableCount, v_BRDVariableDistinctCount FROM BRD_Variables; 
					              
         
					                 
					                 
					                 -- C. BRD_VariableHierarchy
					                  DELETE FROM BRD_VariableHierarchy WHERE 1 = 1;   
							         

								      INSERT INTO BRD_VariableHierarchy
									        (VarID, ChildVarID, ChildLevel, BRDID)
									  SELECT VarID, ChildVarID, ChildLevel, v_BRDID AS BRDID
									  FROM SESSION.varhierarchy
									  WHERE ChildLevel > 0
									        AND VarID IN (SELECT v.VarID FROM SESSION.var v) ;



                    
					                   -- D. BRD_VariableUsageStatistics
					                   DELETE FROM BRD_VariableUsageStatistics WHERE 1 = 1; 
								            
									   INSERT INTO BRD_VariableUsageStatistics
												  ( VarID
												   ,DNrStmtCalc
												   ,DNrStmtCond ,INrStmtCond 
												   ,DNrStmtDB
												   ,DNrStmtFile, INrStmtFile 
												   ,DNrStmtMQ, INrStmtMQ 
												   ,DNrStmtScreen, INrStmtScreen
												   ,IsFromCopy
												   ,BRDID)
										    SELECT    v.VarID
										             ,COALESCE(dstat.NrStmtCalc, 0) AS DNrStmtCalc
										             ,COALESCE(dstat.NrStmtCond, 0) AS DNrStmtCond     ,COALESCE(istat.NrStmtCond, 0) AS INrStmtCond
													 ,COALESCE(dstat.NrStmtDB, 0) AS DNrStmtDB
													 ,COALESCE(dstat.NrStmtFile, 0) AS DNrStmtFile     ,COALESCE(istat.NrStmtFile, 0) AS INrStmtFile 
													 ,COALESCE(dstat.NrStmtMQ, 0) AS DNrStmtMQ         ,COALESCE(istat.NrStmtMQ, 0) AS INrStmtMQ 
													 ,COALESCE(dstat.NrStmtScreen, 0) AS DNrStmtScreen ,COALESCE(istat.NrStmtScreen, 0) AS INrStmtScreen 
												     ,v.IsFromCopy AS IsFromCopy 
												     ,v_BRDID AS BRDID 
										    FROM (
												   SELECT  v1.VarID, c.IsFromCopy
												   FROM  SESSION.var v1
													     CROSS JOIN (
																    SELECT 1 AS IsFromCopy FROM SYSIBM.SYSDUMMY1-- from copy
																    UNION
																    SELECT 0 AS IsFromCopy FROM SYSIBM.SYSDUMMY1 -- from program
																    ) c  
												 )v 
											      LEFT OUTER JOIN (  -- direct statistics
																   SELECT VarID, CASE WHEN CopyID IS NULL THEN 0 ELSE 1 END AS IsFromCopy
																         ,SUM(IsCalculation) AS NrStmtCalc , SUM(IsCondition) AS NrStmtCond, SUM(IsDBIO) AS NrStmtDB 
																		 ,SUM(IsFileIO) AS NrStmtFile , SUM(IsMQ) AS NrStmtMQ, SUM(IsScreen) AS NrStmtScreen
																 FROM SESSION.stmt
																 GROUP BY VarID, CASE WHEN CopyID IS NULL THEN 0 ELSE 1 END
															  ) dstat ON v.VarID = dstat.VarID  AND  v.IsFromCopy = dstat.IsFromCopy
												 LEFT OUTER JOIN ( -- indirect statistics
															   -- propagate statements to child level
															   SELECT vh.ChildVarID, src11.IsFromCopy 
																	--,vh.VarID, 
																	 ,SUM(src11.NrStmtCond) AS NrStmtCond
																	 ,SUM(src11.NrStmtFile) AS NrStmtFile
																	 ,SUM(src11.NrStmtMQ) AS NrStmtMQ
																	 ,SUM(src11.NrStmtScreen) AS NrStmtScreen
															   FROM SESSION.varhierarchy  vh
																    INNER JOIN 
																			  (  -- count statistics
																			    SELECT VarID, CASE WHEN CopyID IS NULL THEN 0 ELSE 1 END AS IsFromCopy
																			    ,SUM(Is88VarLvlCondition) AS NrStmtCond 
																			    ,SUM(IsFileIO) AS NrStmtFile , SUM(IsMQ) AS NrStmtMQ, SUM(IsScreen) AS NrStmtScreen
																			    FROM SESSION.stmt
																			    GROUP BY VarID, CASE WHEN CopyID IS NULL THEN 0 ELSE 1 END
																			    HAVING SUM(Is88VarLvlCondition) + SUM(IsFileIO) + SUM(IsMQ) + SUM(IsScreen) > 0
																			  )src11 ON src11.VarID = vh.VarID 
															   WHERE vh.ChildLevel > 0
															   GROUP BY vh.ChildVarID, src11.IsFromCopy
															   ) istat ON v.VarID = istat.ChildVarID AND v.IsFromCopy = istat.IsFromCopy
										     WHERE      COALESCE(dstat.NrStmtCalc,   0) + COALESCE(dstat.NrStmtCond,   0)  + COALESCE(istat.NrStmtCond, 0) + COALESCE(dstat.NrStmtDB, 0) 
											          + COALESCE(dstat.NrStmtFile,   0) + COALESCE(istat.NrStmtFile,   0)  + COALESCE(dstat.NrStmtMQ  , 0) + COALESCE(istat.NrStmtMQ, 0) 
												      + COALESCE(dstat.NrStmtScreen, 0) + COALESCE(istat.NrStmtScreen, 0)  > 0 
												;                    
						                    
						                    
						                    
						                    
						                 -- E. BRD_ResourceDetail
						                 DELETE FROM BRD_ResourceDetails WHERE 1 = 1;
					

										  INSERT INTO BRD_ResourceDetails (ResourceID, ResourceTypeID, ResourceName, ResourceHash, ResourcePathID, BRDID)
										  SELECT ResourceID, ResourceTypeID, ResourceName, ResourceHash, ResourcePathID 
												,v_BRDID AS BRDID
										  FROM (
												SELECT ResourceID, ResourceTypeID, ResourceName, ResourceHash,  ResourcePathID  
												FROM SESSION.copyb
			
												UNION 
			
												SELECT r.ProgramID AS ResourceID, v_ResourceTypeID_Prog AS ResourceTypeID, 
												       r.ProgramName AS ResourceName, h.SemanticUID AS ResourceHash, occ.PathID AS ResourcePathID
												FROM Programs r
													INNER JOIN Occurrences occ ON r.OccurID = occ.OccurID
													INNER JOIN SemanticUIDContainer h ON r.ProgramID = h.ResourceID AND v_ResourceTypeID_Prog = h.ResourceType
												WHERE EXISTS (SELECT 1 FROM SESSION.pgmflt f WHERE r.ProgramID = f.ProgID)
												) res ;






				                          -- F. BRD_CopyToResource
								          DELETE FROM BRD_CopyToResources WHERE 1 = 1;


										  INSERT INTO BRD_CopyToResources(CopyID, CopyTypeID, ResourceID, ResourceTypeID, ResourcePathID, StartRow, EndRow, StartCol, EndCol, BRDID)
										  SELECT  DISTINCT
													 sr.ResourceID AS CopyID
													,sr.ResourceType AS CopyTypeID
													,CASE WHEN cpy.ResourcePathID IS NOT NULL THEN cpy.ResourceID 
														  ELSE os.ProgID
													 END AS ResourceID
													,CASE WHEN cpy.ResourcePathID IS NOT NULL THEN cpy.ResourceTypeID 
														  ELSE v_ResourceTypeID_Prog
													 END AS ResourcePathID
													,os.PathID AS ResourcePathID
													,os.StartRow
													,os.EndRow
													,os.StartCol
													,os.EndCol
													,v_BRDID AS BRDID	
											FROM  ( 
														SELECT rx.ResourceID, rx.ResourceType, rx.OccurID
														FROM StatementReference rx
														WHERE rx.StatementType = 44
															  AND EXISTS (SELECT 1 FROM  SESSION.copyb s2 WHERE rx.ResourceID = s2.ResourceID AND rx.ResourceType = s2.ResourceTypeID)
													)sr
													INNER JOIN OccurrencesStmt os ON sr.OccurID = os.OccurID AND os.StatementType = 44 
													LEFT OUTER JOIN SESSION.copyb cpy ON os.PathID = cpy.ResourcePathID ; 
						                    



			                                 -- G. BRD_Paths
			
			     							DELETE FROM BRD_Paths WHERE 1 = 1;
			
			
											INSERT INTO BRD_Paths(PathID, PathStr, BRDID)
											SELECT   pth.PathID 
											        ,pth.PathStr
													,v_BRDID AS BRDID	
											FROM Paths pth
											WHERE pth.PathID IN   ( SELECT pf.PathID 
											                        FROM (  
														                   SELECT PathID AS PathID FROM SESSION.stmt 
																		   UNION 
																		   SELECT PathID AS PathID FROM SESSION.var 
																		   UNION 
																		   SELECT ResourcePathID AS PathID FROM BRD_CopyToResources
					                                                       UNION 
																		   SELECT ResourcePathID AS PathID FROM BRD_ResourceDetails 
											                             ) pf 
			                                                       ) ;





			                                SET v_date = CURRENT_TIMESTAMP;
				                            UPDATE BRD_Status
									        SET  	BRDProcessStatusTypeID = 2, -- success 
											        BRDVariableCount = COALESCE(v_BRDVariableCount, 0),
													BRDVariableDistinctCount = COALESCE(v_BRDVariableDistinctCount, 0),
									                eTimeStamp = v_date,
													Notes = COALESCE(Notes, '') || '##2 - '|| CAST(v_date AS VARCHAR(23)) || '##'   -- success							   
						                    WHERE  BRDID = v_BRDID;
					                    
			
					                    
					                        RELEASE SAVEPOINT BRDSVPOINT;
			                                COMMIT; 

                              END;
                       
                  END;
             



/*

   -- see values -- debug purpose
             BEGIN
					             DECLARE crs CURSOR WITH RETURN FOR						       
						         SELECT   v_CurrentSchema, v_CurrentObject, 
						                  v_BRDcomputetype AS BRDcomputetype,
						                  v_BRDCurrentVersion AS BRDCurrentVersion,
						                  v_ProjVersion AS ProjVersion,
						                  v_ProjGUID AS ProjGUID,
						                  v_ProjectName AS v_ProjectName,
						                  v_BRDStatus_Check AS BRDStatus_Check
						         FROM SYSIBM.SYSDUMMY1;

								 OPEN crs;
				
              END;
*/


        END;

END 
