(
	IN p_Project_UUID VARCHAR(255),  
	IN p_VarName VARCHAR(250),
	IN p_StartPosition INTEGER,
	IN p_NumberOfRows INTEGER
)
DYNAMIC RESULT SETS 1
LANGUAGE SQL
BEGIN 


      DECLARE SQLSTATE CHAR(5) DEFAULT '00000';
      DECLARE SQLCODE INTEGER DEFAULT 0;  
      DECLARE v_Project_UUID VARCHAR(255);


      SET v_Project_UUID = COALESCE(LTRIM(RTRIM(p_Project_UUID)), '!');  
      


       --1. CLEAN UP TEMP/SESSION TABLE IF EXISTS
	  BEGIN 
					DECLARE CONTINUE HANDLER FOR SQLSTATE '42704'
					BEGIN END;
					
					COMMIT;
						 DROP TABLE SESSION.varf61;
			             DROP TABLE SESSION.varstmt61; 
			             DROP TABLE SESSION.varrn61;    
	  END;
	  

      --2. CHECK IF THE PROJECT IS OK
	  BEGIN
                    DECLARE v_Project_UUID_real VARCHAR(255);
                    
					DECLARE bad_project CONDITION FOR SQLSTATE '80009';
					DECLARE EXIT HANDLER FOR SQLEXCEPTION RESIGNAL;  
                   
                    SELECT ProjectGUID INTO v_Project_UUID_real
	                FROM  BRD_Status 
			        WHERE BRDID = (SELECT MAX(BRDID) FROM BRD_Status WHERE BRDProcessStatusTypeID = 2) -- last BRD succssfull
			        WITH UR ;	

                    SET v_Project_UUID_real = COALESCE(LTRIM(RTRIM(v_Project_UUID_real)), '?');  
                     
				    IF (UPPER(v_Project_UUID) != UPPER(v_Project_UUID_real)) 
				      THEN
			                             SIGNAL bad_project
			                             SET MESSAGE_TEXT = 'BRD - wrong project!!!';
			                             
			                             RETURN ;	
			                           
			          END IF ;	
			           
	   END;
	   


       --3. MAIN DATA STREAM
       BEGIN

						  --3.0. DECLARATION AREA
					      DECLARE v_StartPosition, v_NumberOfRows INTEGER;
					      DECLARE v_RC ,v_IsStatementTypeFilter INTEGER DEFAULT 0;
						  DECLARE v_VarName VARCHAR(250);  
						  DECLARE v_ResourceTypeID_Prog INTEGER DEFAULT NULL;
		
					
						
					      DECLARE GLOBAL TEMPORARY TABLE SESSION.varf61
										(
										    VarID INTEGER
										)  ON COMMIT PRESERVE ROWS
										   NOT LOGGED; 
										   
					     --CREATE UNIQUE INDEX UNQIDX_varf61_VarID ON SESSION.varf61 (VarID);				   
		         

					      DECLARE GLOBAL TEMPORARY TABLE SESSION.varstmt61
							       (  
							          VarIDConsolidate  INTEGER 
			                         ,VarID             INTEGER
								     ,StatementTypeID   INTEGER
								     ,ProgID            INTEGER
								     ,CopyID            INTEGER
								     ,CopyTypeID        INTEGER
									 ) ON COMMIT PRESERVE ROWS
									   NOT LOGGED;  
			 
 		                    DECLARE GLOBAL TEMPORARY TABLE SESSION.varrn61
					       (
					          VarIDConsolidate       INTEGER
					         ,DefinedInCopy          SMALLINT 
							 ,DefinitionObjectID     INTEGER
							 ,DefinitionObjectTypeID INTEGER
							 ,DefinitionObjectPathID INTEGER 
							 ,VarPositionStartRow    INTEGER 
							 ,VarPositionEndRow      INTEGER
							 ,VarPositionStartCol    INTEGER 
							 ,VarPositionEndCol      INTEGER 
							 ,CountDistProgUsingVar  INTEGER
							 ,CountDistCopyUsingVar  INTEGER
							 ,RN                     INTEGER
							 ) ON COMMIT PRESERVE ROWS
							   NOT LOGGED;
			     
			     


						    --3.1. SET FINAL VALUES FOR WORK VARIABLES

							SET v_StartPosition =  COALESCE(NULLIF(p_StartPosition, -1), 1);
							SET v_NumberOfRows  =  COALESCE(NULLIF(p_NumberOfRows,  -1), 2147480000); 
						
							SET v_VarName    = UPPER(COALESCE(LTRIM(RTRIM(p_VarName)), ''));
					
			                SET v_ResourceTypeID_Prog = (SELECT ResourceID FROM ResourceTypes WHERE UPPER(Name) = 'PROGRAM' FETCH FIRST 1 ROWS ONLY) ;
			
							 -- CHECK if we have to filter by StatementTypeID	  
							IF EXISTS (SELECT 1 FROM SESSION.BRDStatementTypeInput)
							THEN
				                 SET v_IsStatementTypeFilter = 1 ;
				            END IF ;



	                         --3.2. DETERMINE Variable based on filters
							    INSERT INTO SESSION.varf61(VarID)
							    SELECT v.VarID
							    FROM BRD_Variables v
							    WHERE v.VarName  = v_VarName
							          AND EXISTS (SELECT 1 FROM SESSION.BRDVariableHashInput hi WHERE v.VariableHash = hi.VarHash);
	                            COMMIT;

						  
							   
							   --3.3 DETERMINE Statements where variables are involved 
							   
								INSERT INTO SESSION.varstmt61 (VarIDConsolidate ,VarID ,StatementTypeID ,ProgID ,CopyID ,CopyTypeID) 
						        SELECT   v.VarIDConsolidate ,v.VarID ,src1.StatementTypeID ,src1.ProgID ,src1.CopyID ,src1.CopyTypeID
								FROM (
								       
														   SELECT ds.VarID 
																 ,ds.StatementTypeID
																 ,ds.ProgID
																 ,ds.CopyID 
																 ,ds.CopyTypeID
														   FROM BRD_DirectStatements ds 
														   WHERE EXISTS (SELECT 1 FROM SESSION.varf61 v WHERE ds.VarID = v.VarID)
														         AND ( 
															          v_IsStatementTypeFilter = 0
															          OR
																	  EXISTS (SELECT 1 FROM SESSION.BRDStatementTypeInput f WHERE ds.StatementTypeID = f.StatementTypeID)
															         )
															 
														   UNION 
					
														   SELECT vh.ChildVarID AS VarID 
																 ,ds.StatementTypeID
																 ,ds.ProgID
																 ,ds.CopyID 
																 ,ds.CopyTypeID
														   FROM BRD_DirectStatements ds 
															   INNER JOIN ( SELECT  vh1.VarID ,vh1.ChildVarID 
															                FROM BRD_VariableHierarchy vh1
															                WHERE EXISTS (SELECT 1 FROM SESSION.varf61 v WHERE vh1.ChildVarID = v.VarID)
															                GROUP BY vh1.VarID ,vh1.ChildVarID
															              ) vh ON ds.VarID = vh.VarID 
														    WHERE (ds.IsFileIO + ds.IsMQ + ds.IsScreen + ds.Is88VarLvlCondition > 0) 
																  AND ( 
															           v_IsStatementTypeFilter = 0
															           OR
																	   EXISTS (SELECT 1 FROM SESSION.BRDStatementTypeInput f WHERE ds.StatementTypeID = f.StatementTypeID)
															          ) 
									  )src1 
										   INNER JOIN BRD_Variables v ON src1.VarID = v.VarID ; 
                                     COMMIT; 
                                    


					           --3.4 If filtered by STATEMENT TYPE then keep only variables involved in such statements 
								 IF (v_IsStatementTypeFilter = 1)
								 THEN
										DELETE 
										FROM SESSION.varf61 d 
									    WHERE NOT EXISTS (SELECT 1 FROM SESSION.varstmt61 v WHERE d.VarID = v.VarID);
									    COMMIT;
					             END IF ;

						  
							   
							     --3.5 Determine Total Number Of Elements
								INSERT INTO SESSION.varrn61 (VarIDConsolidate, DefinedInCopy ,DefinitionObjectID, DefinitionObjectTypeID, DefinitionObjectPathID 
									                        ,VarPositionStartRow ,VarPositionEndRow ,VarPositionStartCol ,VarPositionEndCol  
									                        ,CountDistProgUsingVar ,CountDistCopyUsingVar ,RN)
								SELECT VarIDConsolidate
								      ,DefinedInCopy ,DefinitionObjectID, DefinitionObjectTypeID, DefinitionObjectPathID 
									  ,VarPositionStartRow ,VarPositionEndRow ,VarPositionStartCol ,VarPositionEndCol 
									  ,CountDistProgUsingVar ,CountDistCopyUsingVar 
									  ,DENSE_RANK() OVER(ORDER BY DefinedInCopy DESC, CountDistProgUsingVar DESC,CountDistCopyUsingVar DESC, VarIDConsolidate) AS RN 
								FROM (
											SELECT   src.VarIDConsolidate ,DefinedInCopy ,DefinitionObjectID, DefinitionObjectTypeID
											        ,DefinitionObjectPathID ,VarPositionStartRow ,VarPositionEndRow ,VarPositionStartCol ,VarPositionEndCol
													,COALESCE(usg.CountDistProgUsingVar, 0)  AS CountDistProgUsingVar
								                    ,COALESCE(usg.CountDistCopyUsingVar, 0)  AS CountDistCopyUsingVar	
											FROM (
														SELECT   DISTINCT 
														          v1.VarIDConsolidate
																, CASE WHEN v1.CopyID IS NOT NULL THEN 1               ELSE 0             END AS DefinedInCopy
																, CASE WHEN v1.CopyID IS NOT NULL THEN v1.CopyID       ELSE v1.ProgID     END AS DefinitionObjectID
																, CASE WHEN v1.CopyID IS NOT NULL THEN v1.CopyTypeID   ELSE v_ResourceTypeID_Prog END AS DefinitionObjectTypeID
																, v1.PathID     AS DefinitionObjectPathID
																, v1.StartRow   AS VarPositionStartRow 
																, v1.EndRow     AS VarPositionEndRow 
																, v1.StartCol   AS VarPositionStartCol 
																, v1.EndCol     AS VarPositionEndCol
																, ROW_NUMBER() OVER(PARTITION BY VarIDConsolidate ORDER BY v1.CopyID, v1.CopyTypeID, v1.ProgID) AS RNflt -- in case there are multiplication due to Program (DefinitionObjectID)
													   FROM BRD_Variables v1
													   WHERE EXISTS (SELECT 1 FROM SESSION.varf61 f WHERE f.VarID = v1.VarID)
												 ) src 
													  LEFT OUTER JOIN 
																	(
																		   SELECT VarIDConsolidate, SUM(CountDistProgUsingVar) AS CountDistProgUsingVar, SUM(CountDistCopyUsingVar) AS CountDistCopyUsingVar
																			FROM ( 
					
																						SELECT VarIDConsolidate
																							,COUNT(DISTINCT ProgID) AS CountDistProgUsingVar
																							,0 AS CountDistCopyUsingVar
																						FROM SESSION.varstmt61
																						WHERE CopyID IS NULL
																						GROUP BY VarIDConsolidate
					
																						UNION ALL
					
																						SELECT x.VarIDConsolidate
																							,0 AS CountDistProgUsingVar
																							,COUNT(x.CopyID) AS CountDistCopyUsingVar
																						FROM (  
																								SELECT VarIDConsolidate, CopyID, CopyTypeID 
																								FROM SESSION.varstmt61 
																								WHERE CopyID IS NOT NULL 
																								GROUP BY VarIDConsolidate, CopyID, CopyTypeID
																								)x 
																						GROUP BY x.VarIDConsolidate
																				  ) y
																			GROUP BY VarIDConsolidate 
																	  ) usg ON src.VarIDConsolidate = usg.VarIDConsolidate	 
												WHERE src.RNflt = 1					  
									)flt ;
									  
								  GET DIAGNOSTICS v_RC = ROW_COUNT; 
								  COMMIT;   
  

                           -- 4 OUTPUT
	                           -- 4.1 Seconday Output	(Statements + Hashes)  
							   -- 4.1.1 CLEAN-UP output tables
							      TRUNCATE TABLE SESSION.BRDStatementTypeOutput ;
								  TRUNCATE TABLE SESSION.BRDVariableHashAggregate ;
					              COMMIT;
					              
					           -- 4.1.2 Output for StatementTypes 
								  INSERT INTO SESSION.BRDStatementTypeOutput (StatementTypeID, StatementTypeDescription)
								  SELECT st.StatementType AS StatementTypeID, st.Description AS StatementTypeDescription
								  FROM Statements st
								  WHERE EXISTS (SELECT 1 FROM SESSION.varstmt61 f WHERE f.StatementTypeID = st.StatementType) ;
					              COMMIT; 
					
					
					
					           -- 4.1.3 Output for Hashes   
					               INSERT INTO SESSION.BRDVariableHashAggregate (RN, VarHash)
								   SELECT x.RN  ,v1.VariableHash
								   FROM BRD_Variables v1
									    INNER JOIN ( 
									              SELECT  DISTINCT VarIDConsolidate , RN
												  FROM SESSION.varrn61
												  WHERE RN BETWEEN  v_StartPosition AND (v_StartPosition + v_NumberOfRows - 1)
												 ) x ON v1.VarIDConsolidate = x.VarIDConsolidate
								  WHERE EXISTS (SELECT 1 FROM SESSION.varf61 f WHERE f.VarID = v1.VarID) ;
	                              COMMIT;
	                           
	                           


				             --4.2. Main OUTPUT 
				             BEGIN
					             DECLARE crs CURSOR WITH RETURN FOR
						         SELECT   s11.DefinedInCopy 
										  --,s11.DefinitionObjectID 
										  --,s11.DefinitionObjectTypeID 
										  ,rd.ResourceHash AS DefinitionObjectHash  
										  ,rd.ResourceName AS DefinitionObjectName  
										  --,s11.DefinitionObjectPathID 
										  ,pth1.PathStr AS DefinitionObjectPath 
										  ,s11.VarIDConsolidate 
										  ,s11.VarPositionStartRow 
										  ,s11.VarPositionEndRow 
										  ,s11.VarPositionStartCol 
										  ,s11.VarPositionEndCol
										  ,COALESCE(cp.NrResUsingCopy, 0) AS CountDistResUsingCopy 
										  ,s11.CountDistProgUsingVar  
						                  ,s11.CountDistCopyUsingVar
										  ,s11.RN 
										  ,v_RC AS NR 
								 FROM 
								     (			 
											SELECT  DISTINCT
											        DefinedInCopy ,DefinitionObjectID, DefinitionObjectTypeID, DefinitionObjectPathID 
											       ,VarIDConsolidate ,VarPositionStartRow ,VarPositionEndRow ,VarPositionStartCol ,VarPositionEndCol 
											       ,CountDistProgUsingVar ,CountDistCopyUsingVar
											       ,RN 
											FROM SESSION.varrn61
											WHERE RN BETWEEN  v_StartPosition AND (v_StartPosition + v_NumberOfRows - 1) 
									  ) s11
									    INNER JOIN BRD_Paths pth1 ON s11.DefinitionObjectPathID = pth1.PathID
									    INNER JOIN BRD_ResourceDetails rd ON rd.ResourceID = s11.DefinitionObjectID AND rd.ResourceTypeID = s11.DefinitionObjectTypeID  
									    LEFT OUTER JOIN 
									                (
													   SELECT CopyID, CopyTypeID, COUNT(*) AS NrResUsingCopy
													   FROM(
															SELECT cr.CopyID, cr.CopyTypeID, cr.ResourceID, cr.ResourceTypeID
															FROM BRD_CopyToResources cr
																 INNER JOIN SESSION.varrn61 f ON cr.CopyID = f.DefinitionObjectID AND cr.CopyTypeID = f.DefinitionObjectTypeID
															GROUP BY cr.CopyID, cr.CopyTypeID, cr.ResourceID, cr.ResourceTypeID
														   ) f1 
				                                       GROUP BY CopyID, CopyTypeID
													  ) cp ON s11.DefinitionObjectID = cp.CopyID  AND s11.DefinitionObjectTypeID = cp.CopyTypeID	 			
								  ORDER BY s11.RN
						          OPTIMIZE FOR 500 ROWS;

								  OPEN crs;
				
                             END;


             END;


	  
END
