Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NullPointerException when calling getMoreResults() on Statement without a query executed #2833

Closed
monetdb-team opened this issue Nov 30, 2020 · 0 comments
Labels
bug Something isn't working Client interfaces normal

Comments

@monetdb-team
Copy link

Date: 2011-07-07 15:35:47 +0200
From: Simon Brodt <<simon.brodt>>
To: clients devs <>
Version: 11.3.3 (Apr2011-SP1) [obsolete]

Last updated: 2011-07-29 10:52:47 +0200

Comment 15905

Date: 2011-07-07 15:35:47 +0200
From: Simon Brodt <<simon.brodt>>

User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:5.0) Gecko/20100101 Firefox/5.0
Build Identifier:

When the getMoreResults() Method on a java.sql.Statement instance is called and no result is available, then a NullPointerExceptuion is thrown instead of returning false.

Reproducible: Always

Steps to Reproduce:

  1. Start the monetDB SQL Server with database demo and login user=monetdb, password=monetdb (jdbc driver version = 1.20)
  2. execute the first test in JUnit test class provided under Additional Information

Actual Results:

NullPointerException

Expected Results:

false

package monetdb;

import static org.junit.Assert.*;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class MonetDB {

Connection db_connection;

@Before
public void setUp() throws Exception {
	nl.cwi.monetdb.jdbc.MonetDriver.getDriverVersion();
	
	this.db_connection = DriverManager.getConnection("jdbc:monetdb://localhost/demo", "monetdb", "monetdb");
	
	Statement s = this.db_connection.createStatement();
	
}

@Test
public void nullPointerExceptionOnGetMoreResults() throws SQLException{
	
	Statement s = this.db_connection.createStatement();
	
	assertTrue(s.getMoreResults());
	
}

@Test
public void robustnessOfPreparedStatements1() throws SQLException{
	
	Statement s = this.db_connection.createStatement();
	try{ s.execute("DROP SCHEMA \"test\";"); } catch(SQLException e){}
	
	PreparedStatement p = this.db_connection.prepareStatement("SELECT 0;");
	
	ResultSet r;
	
	r = p.executeQuery();
	
	s.execute("CREATE SCHEMA \"test\";");
	
	r = p.executeQuery();
	
}

@Test
public void robustnessOfPreparedStatements2() throws SQLException{
	
	Statement s = this.db_connection.createStatement();
	try{ s.execute("DROP SCHEMA \"test\";"); } catch(SQLException e){}
	
	s.execute("CREATE SCHEMA \"test\";");
	
	PreparedStatement p = this.db_connection.prepareStatement("SELECT 0;");
	
	ResultSet r;
	
	r = p.executeQuery();
	
	s.execute("CREATE TABLE \"test\".\"test\" (\"id\" INT);");
	
	r = p.executeQuery();
	
}

@Test
public void robustnessOfPreparedStatements3() throws SQLException{
	
	Statement s = this.db_connection.createStatement();
	try{ s.execute("DROP SCHEMA \"test\";"); } catch(SQLException e){}
	
	s.execute("CREATE SCHEMA \"test\";");
	s.execute("CREATE TABLE \"test\".\"test\" (\"id\" INT);");
	
	PreparedStatement p = this.db_connection.prepareStatement("INSERT INTO \"test\".\"test\" VALUES ('0');");
	
	int updateCount;
	
	updateCount = p.executeUpdate();		
	assertEquals(1, updateCount);
	
	s.execute("CREATE TABLE \"test\".\"test2\" (\"id\" INT);");
	
	updateCount = p.executeUpdate();
	assertEquals(1, updateCount);
	
}

@Test(expected=SQLException.class)
public void uniquenessConstraint() throws SQLException{
	
	Statement s = this.db_connection.createStatement();
	try{ s.execute("DROP SCHEMA \"test\";"); } catch(SQLException e){}
	
	s.execute("CREATE SCHEMA \"test\";");
	s.execute("CREATE TABLE \"test\".\"test\" (\"id\" INT PRIMARY KEY );");
	s.execute("CREATE TABLE \"test\".\"test2\" (\"ref\" INT REFERENCES \"test\".\"test\" , \"name\" CLOB, CONSTRAINT \"unique\" UNIQUE (\"ref\", \"name\") );");		
	
	int updateCount;
	
	updateCount = s.executeUpdate("INSERT INTO \"test\".\"test\" VALUES ('0');");		
	assertEquals(1, updateCount);
	
	updateCount = s.executeUpdate("INSERT INTO \"test\".\"test2\" VALUES ('0', 'hello');");
	assertEquals(1, updateCount);
	
	updateCount = s.executeUpdate("INSERT INTO \"test\".\"test2\" VALUES ('0', 'hello');");
	
}

@After
public void cleanUp() throws Exception {
	Statement s = this.db_connection.createStatement();
	
	try{ s.execute("DROP SCHEMA \"test\";"); } catch(SQLException e){}
	
	this.db_connection.close();
}

}

Comment 15906

Date: 2011-07-07 15:37:46 +0200
From: Simon Brodt <<simon.brodt>>

Created attachment 64
JUnit Test for reproducing the bug

Attached file: MonetDB.java (application/octet-stream, 3547 bytes)
Description: JUnit Test for reproducing the bug

Comment 15907

Date: 2011-07-07 15:56:31 +0200
From: @grobian

do you have a stacktrace at hand, perhaps?

Comment 15912

Date: 2011-07-07 19:41:30 +0200
From: Simon Brodt <<simon.brodt>>

(In reply to comment 2)

do you have a stacktrace at hand, perhaps?

I added the following main method to the class:

public static void main(final String[] args) throws Exception{
	MonetDB monetDB = new MonetDB();
	monetDB.setUp();
	monetDB.nullPointerExceptionOnGetMoreResults();
}

The produced Exception has the following stacktrace

Exception in thread "main" java.lang.NullPointerException
at nl.cwi.monetdb.jdbc.MonetStatement.getMoreResults(MonetStatement.java:772)
at nl.cwi.monetdb.jdbc.MonetStatement.getMoreResults(MonetStatement.java:749)
at monetdb.MonetDB.nullPointerExceptionOnGetMoreResults(MonetDB.java:36)
at monetdb.MonetDB.main(MonetDB.java:135)

Is this what you need?

Comment 15915

Date: 2011-07-08 11:12:45 +0200
From: @grobian

Yes, thanks. The problem here is that you call getMoreResults() while you didn't ever run any query. The API docs don't give me any hint on to what to do in this case, but it feels like this is more of an error than it is "there are no results" to me.

Comment 15916

Date: 2011-07-08 11:21:19 +0200
From: Simon Brodt <<simon.brodt>>

(In reply to comment 4)

Yes, thanks. The problem here is that you call getMoreResults() while you
didn't ever run any query. The API docs don't give me any hint on to what to
do in this case, but it feels like this is more of an error than it is "there
are no results" to me.

The error also occurs if you execute a statement and then call the method twice.
The JDBC API says that:

There are no more results when the following is true:

  // stmt is a Statement object
  ((stmt.getMoreResults(current) == false) && (stmt.getUpdateCount() == -1))

Returns:
true if the next result is a ResultSet object; false if it is an update count or >>there are no more results<<

If the statement was never executed there just are no more reults, i.e. the Method should return false.
A NullointerExcetion should defnitly be wrong.
One could consider a SQLException but Im quite sure this is not in accordance with the API specification.

Comment 15918

Date: 2011-07-08 11:26:23 +0200
From: @grobian

(In reply to comment 5)

The error also occurs if you execute a statement and then call the method
twice.

Odd, this is the primary use-case of this function, and e.g. JdbcClient works that way. Are you calling it unconditional, after the conditional you quoted below evaluated to true?

If the statement was never executed there just are no more reults, i.e. the
Method should return false.

You could consider it that way, yes.

A NullointerExcetion should defnitly be wrong.

Fully agree.

One could consider a SQLException but Im quite sure this is not in accordance
with the API specification.

the API doesn't suggest this is the way to go, indeed

Comment 15919

Date: 2011-07-08 11:34:03 +0200
From: Simon Brodt <<simon.brodt>>

The error also occurs if you execute a statement and then call the method
twice.

Sorry, seems that this is not correct. Thought I had tested this.

Comment 15920

Date: 2011-07-08 11:47:02 +0200
From: @grobian

I created a testcase here to call getMoreResults() on an empty statement, but it doesn't crash at all here :/

Comment 15921

Date: 2011-07-08 11:49:40 +0200
From: @grobian

Sorry, I can. Logic error here while testing.

Comment 15922

Date: 2011-07-08 11:52:37 +0200
From: @grobian

Changeset bac87d4ed683 made by Fabian Groffen fabian@cwi.nl in the MonetDB repo, refers to this bug.

For complete details, see http//devmonetdborg/hg/MonetDB?cmd=changeset;node=bac87d4ed683

Changeset description:

Statement: fix getMoreResults() NullPointerException on unitialised Statement

Return false from Statement.getMoreResults() instead of a
NullPointerException when no query has been performed on the Statement
yet, bug #2833

Comment 16015

Date: 2011-07-29 10:52:47 +0200
From: @sjoerdmullender

The Apr2011-SP2 bugfix release is out.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working Client interfaces normal
Projects
None yet
Development

No branches or pull requests

2 participants