/**
 * This system procedure is used to return the list of 
 * column rights for a given table(s) from the database
 * specified.
 */
CREATE PROCEDURE psp_column_rights
(
    in :database_qual   VARCHAR(20) = DATABASE(), -- Name of the database
    in :table_name      VARCHAR(255) , -- Name of the table
    in :column_name     VARCHAR(255) = NULL, -- Name of the column
    in :user_name       VARCHAR(255) = USER() -- Name of the user
)

RETURNS
(
    TABLE_QUALIFIER     VARCHAR (20), -- Name of the database that contains the table
    TABLE_OWNER         VARCHAR (20),  -- owner of the table
    USER_NAME           VARCHAR(255), -- Name of the user
    TABLE_NAME          VARCHAR(255), -- Name of the table 
    COLUMN_NAME         VARCHAR(255), -- Name of the column
    RIGHTS              VARCHAR(12)  -- Column rights 
);

BEGIN
	-- This variable stores the dynamic query
	DECLARE :query              LONGVARCHAR;
    
	-- This variable stores the table name concatenated with 
	-- the database qualifier in the form dbname.tablename
    DECLARE :file_table_name    VARCHAR(30);
    DECLARE :rights_table_name  VARCHAR(30);
    DECLARE :field_table_name   VARCHAR(30);
    DECLARE :user_table_name    VARCHAR(30);

	-- This variable stores the metadata version.
	DECLARE :version    INTEGER;

    -- Check if the table name is null
	if (:table_name is null) then
		SIGNAL 'S1000', 'Table name cannot be null';
	end if;

    -- Check if the table name is a blank string
	if (rtrim(:table_name) = '') then
		SIGNAL 'S1000', 'Table name cannot be blank string';
	end if;		

    -- If the database qualifier is null, then use the current database
	if (:database_qual is null) then
		set :database_qual = DATABASE();
	end if;
	
    -- Check if the database qualifier specified is a blank string
	if (rtrim(:database_qual) = '') then
		SIGNAL 'S1000', 'Please enter a valid database name. Database name cannot be a blank string'; 
	end if;
    
    -- Check if the column name is a blank string
	if (rtrim(:column_name) = '') then
		SIGNAL 'S1000', 'Column name cannot be blank string';
	end if;		
    
    -- Check if the user name is a blank string
	if (rtrim(:user_name) = '') then
		SIGNAL 'S1000', 'User name cannot be a blank string';
	end if;
    
	/*	If column name is null or not supplied, 
	    match all the columns */
	SET :column_name = IFNULL(:column_name,'%');
	
	/*	If user name is null or not supplied, 
	    Set user_name to current user */
	SET :user_name = IFNULL(:user_name, USER());

    SET :field_table_name = '"' + :database_qual + '".X$Field C';
    SET :file_table_name = '"' + :database_qual + '".X$File A';
    SET :rights_table_name = '"' + :database_qual + '".X$Rights B';
    SET :user_table_name = '"' + :database_qual + '".X$User D';
	
    -- call procedure to find the metadata version and store it in a variable
	CALL psp_database_version(:database_qual, :version);

    if (:version = 1) then  
        -- Metadata version is V1

    /*  Enumerate the column rights */
                -- SELECT rights for column
    SET :query = 'SELECT ''' + :database_qual + ''', null,' +	   	
            	 ' D.Xu$Name, A.Xf$Name, C.Xe$Name, ''SELECT'' ' +
            	 ' FROM ' + :file_table_name + ',' + :rights_table_name +
                 ',' + :field_table_name + ',' + :user_table_name +
                 ' WHERE	A.Xf$Name LIKE ''' + :table_name + ''' AND ' +
        		 'D.Xu$Name LIKE ''' + :user_name + ''' AND C.Xe$Name ' +
                 'LIKE ''' + :column_name + ''' AND	' +
                 'b.xr$rights & 64 = 64 AND ' + 
        		 'B.Xr$Column <> 0 AND A.Xf$Id = B.Xr$Table AND ' +
        		 'D.Xu$Id = B.Xr$User and  B.Xr$Column = C.Xe$Id ' +
                 -- UPDATE rights for column
                 'UNION SELECT ''' + :database_qual + ''', null, ' +	   	
        		 'D.Xu$Name, A.Xf$Name, C.Xe$Name, ''UPDATE'' ' +
            	 'FROM ' + :file_table_name + ',' + :rights_table_name +
                 ',' + :field_table_name + ',' + :user_table_name + 
                 ' WHERE A.Xf$Name LIKE ''' + :table_name + 
                 ''' AND D.Xu$Name LIKE ''' +
                 :user_name + ''' AND C.Xe$Name LIKE ''' + :column_name  + 
                 ''' AND b.xr$rights & 130 = 130 AND ' +
        	  	 'B.Xr$Column <> 0 AND A.Xf$Id = B.Xr$Table AND ' +
                 'D.Xu$Id = B.Xr$User and B.Xr$Column = C.Xe$Id ' +
                 -- INSERT rights for column
                 'UNION SELECT ''' + :database_qual + ''', null, ' +
                 'D.Xu$Name, A.Xf$Name, C.Xe$Name, ''INSERT'' ' +
            	 'FROM ' + :file_table_name + ',' + :rights_table_name +
                 ',' + :field_table_name + ',' + :user_table_name +
                 ' WHERE 	A.Xf$Name LIKE ''' + :table_name + ''' AND ' +
              	 ' D.Xu$Name LIKE ''' + :user_name + ''' AND C.Xe$Name ' +
                 'LIKE ''' + :column_name + ''' AND	b.xr$rights & 132 = 132 ' +
                 'AND B.Xr$Column <> 0 AND A.Xf$Id = B.Xr$Table AND ' + 
                 'D.Xu$Id = B.Xr$User and B.Xr$Column = C.Xe$Id';
    else 
        if (:version = 2) then  
            -- Metadata version is V2
            /*  Enumerate the column rights */
                        -- SELECT rights for column
            SET :query = 'SELECT ''' + :database_qual + ''', null,' +	   	
                         ' D.Xu$Name, A.Xf$Name, C.Xe$Name, ''SELECT'' ' +
                         ' FROM ' + :file_table_name + ',' + :rights_table_name +
                         ',' + :field_table_name + ',' + :user_table_name +
                         ' WHERE	A.Xf$Name LIKE ''' + :table_name + ''' AND ' +
                         'D.Xu$Name LIKE ''' + :user_name + ''' AND C.Xe$Name ' +
                         'LIKE ''' + :column_name + ''' AND	' +
                         'b.xr$rights & 64 = 64 AND ' + 
                         'B.Xr$Column <> 0 AND A.Xf$Id = B.Xr$Object AND ' +
                         'D.Xu$Id = B.Xr$User and  B.Xr$Column = C.Xe$Id and B.Xr$Type = 1 ' +
                         -- UPDATE rights for column
                         'UNION SELECT ''' + :database_qual + ''', null, ' +	   	
                         'D.Xu$Name, A.Xf$Name, C.Xe$Name, ''UPDATE'' ' +
                         'FROM ' + :file_table_name + ',' + :rights_table_name +
                         ',' + :field_table_name + ',' + :user_table_name + 
                         ' WHERE A.Xf$Name LIKE ''' + :table_name + 
                         ''' AND D.Xu$Name LIKE ''' +
                         :user_name + ''' AND C.Xe$Name LIKE ''' + :column_name  + 
                         ''' AND b.xr$rights & 130 = 130 AND ' +
                         'B.Xr$Column <> 0 AND A.Xf$Id = B.Xr$Object AND ' +
                         'D.Xu$Id = B.Xr$User and B.Xr$Column = C.Xe$Id and B.Xr$Type = 1 ' +
                         -- INSERT rights for column
                         'UNION SELECT ''' + :database_qual + ''', null, ' +
                         'D.Xu$Name, A.Xf$Name, C.Xe$Name, ''INSERT'' ' +
                         'FROM ' + :file_table_name + ',' + :rights_table_name +
                         ',' + :field_table_name + ',' + :user_table_name +
                         ' WHERE 	A.Xf$Name LIKE ''' + :table_name + ''' AND ' +
                         ' D.Xu$Name LIKE ''' + :user_name + ''' AND C.Xe$Name ' +
                         'LIKE ''' + :column_name + ''' AND	b.xr$rights & 132 = 132 ' +
                         'AND B.Xr$Column <> 0 AND A.Xf$Id = B.Xr$Object AND ' + 
                         'D.Xu$Id = B.Xr$User and B.Xr$Column = C.Xe$Id and B.Xr$Type = 1';            
        end if;                     
    end if;
                     
    exec (:query);

END; -- End of stored procedure.

