(
 p_ProgramID INTEGER
)
RETURNS TABLE (
                 ProgramID     INTEGER,
                 ProgramName   VARCHAR(256),
                 ProgramTypeID INTEGER,
                 OccurID       INTEGER,
                 AncestorID    INTEGER,
                 AncestorName  VARCHAR(256)
               )
LANGUAGE SQL
CALLED ON NULL INPUT
BEGIN ATOMIC
RETURN

     WITH cte (ProgramID, ProgramName, ProgramNameU, ProgramTypeID, OccurID, AncestorU, AliasType ,IsParentFlag ,IsPairFlag ,RN)
		AS
		 (
		  SELECT p.ProgramID
			     ,pa.AliasName AS ProgramName
			     ,UPPER(pa.AliasName) AS ProgramNameU
			     ,p.ProgramTypeID
				 ,p.OccurID
				 ,UPPER(p.Ancestor) AS AncestorU
				 ,pa.AliasType
			     ,CASE WHEN ProgramTypeID IN (15, 16, 19) THEN 2
                      ELSE 1
                 END IsParentFlag
                ,CASE WHEN ProgramTypeID IN (8 ,15 ,16) THEN 1
                      WHEN ProgramTypeID IN (13 ,19)    THEN 2
                      ELSE 3
                  END IsPairFlag
                 ,ROW_NUMBER() OVER(PARTITION BY pa.AliasType ,pa.AliasName ,CASE WHEN p.ProgramTypeID IN (8, 13) THEN 1 WHEN p.ProgramTypeID IN (15, 16, 19) THEN 2 ELSE 3 END ORDER BY p.ProgramTypeID) AS RN
  FROM Programs p
		       LEFT OUTER JOIN ProgramAliases pa ON pa.AliasType = 0 AND pa.ProgramID = p.ProgramID

		    )

       SELECT  c1.ProgramID,
			   c1.ProgramName,
			   c1.ProgramTypeID,
			   c1.OccurID,
			   c2.ProgramID AS AncestorID,
			   COALESCE(c2.ProgramName, '') AS AncestorName
       FROM cte c1
            LEFT OUTER JOIN cte c2 ON c2.AliasType = 0 AND c2.IsParentFlag = 1 AND c2.RN = 1 AND c1.IsPairFlag = c2.IsPairFlag AND c2.ProgramNameU = c1.AncestorU
       WHERE p_ProgramID IS NULL OR  p_ProgramID = c1.ProgramID ;

		
END