/*
 * This system procedure is used to return the list
 * of users and the corresponding information from the
 * database specified.
 */
CREATE PROCEDURE psp_users
(
    in :database_qual   VARCHAR(20) = DATABASE(), -- Name of the database
    in :group_name      VARCHAR(254) = NULL, -- Name of the group
    in :user_name       VARCHAR(254) = NULL  -- Name of the user
)
RETURNS
(
    DATABASE_QUALIFIER  VARCHAR(20), -- Database Name
    GROUP_ID            USMALLINT, -- Group ID 
    GROUP_NAME          VARCHAR(254),  -- Name of the group
    USER_ID             USMALLINT, -- User ID
    USER_NAME           VARCHAR(254)   -- Name of the user
);

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 :table_name VARCHAR(30);

    -- Check if the database qualifier 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 user name is a blank string
	IF (rtrim(:user_name) = '') THEN
        SIGNAL 'S1000', 'Please enter a valid user name. User name cannot be a  blank string';
    END IF;
    
    -- Check if the group name is a blank string
    IF (rtrim(:group_name) = '') THEN
        SIGNAL 'S1000', 'Please enter a valid group name. Group name cannot be a blank string';
    END IF;
    
	set :database_qual = IFNULL(:database_qual,DATABASE());

	/*	If user name is null or not supplied, 
	    match all the users */
	set :user_name  = IFNULL(:user_name,'%');

    set :table_name = '"' + :database_qual + '".X$User';
  	
	/* Enumerate all the users information */
	if :group_name like 'PUBLIC' THEN
	         SET :query = 'SELECT ''' + :database_qual + ''', A.Xu$Id, A.Xu$Name, ' +
                     ' B.Xu$Id, B.Xu$Name ' +
                     ' FROM ' + :table_name + ' A, ' + :table_name + 
                     ' B WHERE A.Xu$Flags & 64 = 64 AND ' + 
                     ' A.Xu$Name LIKE ''' + :group_name + ''' AND ' +
                     ' B.Xu$Name LIKE ''' + :user_name  +
                     ''' AND B.Xu$Flags & 64 = 0 AND B.Xu$Id > 0' ;
	 else
    IF( (:group_name IS NOT NULL) AND (:group_name not like 'PUBLIC'))THEN
    SET :query = 'SELECT ''' + :database_qual + ''', A.Xu$Id, A.Xu$Name, ' +
                     ' B.Xu$Id, B.Xu$Name ' +
                     ' FROM ' + :table_name + ' A, ' + :table_name + 
                     ' B WHERE A.Xu$Flags & 64 = 64 AND ' + 
                     ' A.Xu$Name LIKE ''' + :group_name + ''' AND ' +
                     ' B.Xu$Id = A.Xu$Id AND B.Xu$Name LIKE ''' + :user_name  +
                     ''' AND B.Xu$Flags & 64 = 0 ' ;
    ELSE
          SET :query = 'SELECT ''' + :database_qual + 
          ''', if(B.xu$name LIKE ' + '''Master''' + ', NULL, A.xu$id),' + 
          'if(B.xu$name LIKE ' + '''Master''' + ', NULL, A.xu$name), ' + 
                     'B.Xu$Id, B.Xu$Name FROM ' + :table_name + 
                     ' A , ' + :table_name + 
                     ' B WHERE B.Xu$Name LIKE ''' + :user_name + 
                     ''' AND A.Xu$Flags & 64 = 64 AND' + ' B.Xu$Flags & 64 = 0 AND ' + 
                     'A.xu$id = 1' + ' AND b.xu$name' + ' not IN ' + '(select B.xu$name from' + 
                     :table_name + ' A , ' + :table_name + 
                     ' B WHERE B.xu$flags & 64 =0 AND A.xu$flags & 64 =64 AND A.xu$id = B.xu$id) union ' + 
                     ' (select ''' + :database_qual + ''' , AA.xu$id, AA.xu$name, BB.xu$id, BB.xu$name from ' + :table_name + ' AA, ' + 
                     :table_name + ' BB where ' + ' BB.Xu$Name LIKE ''' + :user_name  + '''AND BB.xu$flags & 64 =0 AND AA.xu$flags & 64=64 AND AA.xu$id = BB.xu$id)';
    END IF;
        END IF;
        exec (:query);

END; -- End of stored procedure.

