The following bug has been logged online:

Bug reference:      5511
Logged by:          Brett Sutton
Email address:      bsut...@noojee.com.au
PostgreSQL version: 8.4.4
Operating system:   Ubuntu 10.04
Description:        Handling of case in Username and database names are
inconsistant.
Details: 

When using jdbc and a username or database is created using mixed case you
cannot then access either with mixed case.

Essentially if you peform:
create user Abc;
Postgres creates a user abc (as expected).

The problem is that you cannot the use mixed case name in a jdbc url.import
java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;


public class PostgresCaseBug
{
        static public void main(String args[])
        {
                String adminUsername = "postgres";
                
                // NOTE: change this password to match your local db.
                String adminPassword = "adminPasswordGoesHere";  

                // Assumes that you have postgres running on localhost.
                String server = "localhost";
                
                String databaseName = "testdb";
                String username = "testUser";  // Note the username is mixed 
case.
                String password = "password";

                String adminURL = "jdbc:postgresql://" + server + 
"/postgres?user=" +
adminUsername //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
                                + "&password=" + adminPassword;//$NON-NLS-1$ 


                Connection con = null;
                PreparedStatement stmt = null;

                try
                {
                        Class.forName("org.postgresql.Driver");
                        con = DriverManager.getConnection(adminURL);
                        String sql = "create user " + username + " with 
password '" + password +
"'"; //$NON-NLS-1$ //$NON-NLS-2$//$NON-NLS-3$
                        stmt = con.prepareStatement(sql);
                        stmt.execute();
                        stmt.close();
                        System.out.println("User " + username + " created"); 
//$NON-NLS-1$
//$NON-NLS-2$

                        // Now create the database and make the new user the 
owner.
                        stmt = con.prepareStatement("create database " + 
databaseName + " with
owner " + username); //$NON-NLS-1$ //$NON-NLS-2$
                        stmt.execute();
                        System.out.println("Database " + databaseName + " 
created");
//$NON-NLS-1$//$NON-NLS-2$
                        con.close();

                        // First prove we can connect if we artificially force 
the username to 
                        // all lower case
                        String url = "jdbc:postgresql://" + server + "/" + 
databaseName +
"?user=" + username.toLowerCase() //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
                        + "&password=" + password;//$NON-NLS-1$ 
                        
                        // we can connect without a problem.
                        con = DriverManager.getConnection(url);
                        System.out.println("Connected with url=" + url); 
//$NON-NLS-1$
                        con.close();

                        
                        // Now attempt to connect with the user we just created 
without force the
username
                        // to lower case.
                        url = "jdbc:postgresql://" + server + "/" + 
databaseName + "?user=" +
username //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
                        + "&password=" + password;//$NON-NLS-1$ 

                        
                        // Throws exception: password authentication failed for 
user "testUser"
                        // Even though we just created the user. If we attempt 
the connection
                        // using an all lower case version of the account then 
the authentication
succeeds.
                        con = DriverManager.getConnection(url); // throws an 
exception even
though we just created the user. 

                }
                catch (SQLException e)
                {
                        System.out.println(e.getMessage());
                }
                catch (ClassNotFoundException e)
                {
                        e.printStackTrace();
                }
                finally
                {
                        try
                        {
                                if (stmt != null && stmt.isClosed() == false)
                                        stmt.close();
                                if (con != null && con.isClosed() == false)
                                        con.close();
                        }
                        catch (SQLException e)
                        {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                        }
                }
                

                // Now we do it all again to prove that the same problem exists 
for the
database name.
                databaseName = "testDB2"; //Note the mixed case. This will 
cause problems.
//$NON-NLS-1$
                username = "testuser2"; //$NON-NLS-1$
                try
                {
                        Class.forName("org.postgresql.Driver"); //$NON-NLS-1$
                        con = DriverManager.getConnection(adminURL);
                        String sql = "create user " + username + " with 
password '" + password +
"'"; //$NON-NLS-1$ //$NON-NLS-2$//$NON-NLS-3$
                        stmt = con.prepareStatement(sql);
                        stmt.execute();
                        stmt.close();
                        System.out.println("User " + username + " created"); 
//$NON-NLS-1$
//$NON-NLS-2$

                        // Now create the database and make the new user the 
owner.
                        stmt = con.prepareStatement("create database " + 
databaseName + " with
owner " + username); //$NON-NLS-1$ //$NON-NLS-2$
                        stmt.execute();
                        System.out.println("Database " + databaseName + " 
created");
//$NON-NLS-1$//$NON-NLS-2$
                        con.close();

                        // First prove we can connect if we artificially force 
the database name
to 
                        // all lower casewe just created without force the 
username
                        // to lower case.
                        String url = "jdbc:postgresql://" + server + "/" +
databaseName.toLowerCase() + "?user=" + username //$NON-NLS-1$ //$NON-NLS-2$
//$NON-NLS-3$
                        + "&password=" + password;//$NON-NLS-1$ 
                        
                        // we can connect without a problem.
                        con = DriverManager.getConnection(url);
                        System.out.println("Connected with url=" + url); 
//$NON-NLS-1$
                        con.close();

                        
                        // Now attempt to connect with the database using its 
original camel
case.
                        url = "jdbc:postgresql://" + server + "/" + 
databaseName + "?user=" +
username //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
                        + "&password=" + password;//$NON-NLS-1$ 

                        
                        // Throws exception: password authentication failed for 
user "testUser"
                        // Even though we just created the user. If we attempt 
the connection
                        // using an all lower case version of the account then 
the authentication
succeeds.
                        con = DriverManager.getConnection(url); // throws an 
exception even
though we just created the user. 

                }
                catch (SQLException e)
                {
                        System.out.println(e.getMessage());
                }
                catch (ClassNotFoundException e)
                {
                        e.printStackTrace();
                }
                finally
                {
                        try
                        {
                                if (stmt != null && stmt.isClosed() == false)
                                        stmt.close();
                                if (con != null && con.isClosed() == false)
                                        con.close();
                        }
                        catch (SQLException e)
                        {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                        }
                }

        }

}

e.g.
jdbc:posgresql://localhost/database?user=Abc&password=xx

will fail with a message 'password authentication failed for user "Abc"

The same problem exist when creating a database and then attempting to
connect to it via a url using mixed case.

The following java program reproduces both issues:

-- 
Sent via pgsql-bugs mailing list (pgsql-bugs@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-bugs

Reply via email to