buggins / ddbc

DDBC is DB Connector for D language (similar to JDBC)

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Prepared Statement throws a segfault.

vra5107 opened this issue · comments

I get a SegFault with the main method below which uses HibernateD . The second main method which uses ddbc just works fine. I think there is a bug with PreparedStatement class in HibernateD. ddbc fails when I use a PreparedStatement. The code below shows that.

This method uses HibernateD and it fails.

int main() {
	// setup DB connection
	string url = MySQLDriver.generateUrl("localhost", 3306, "test");
	string[string] params = MySQLDriver.setUserAndPassword("test", "test");
	DataSource ds = new ConnectionPoolDataSourceImpl(new MySQLDriver(), url, params);

	// create metadata from annotations
	EntityMetaData schema = new SchemaInfoImpl!(Preferences);

	// create session factory
	Dialect dialect = new MySQLDialect();
	SessionFactory factory = new SessionFactoryImpl(schema, dialect, ds);
	scope(exit) factory.close();
	
	auto conn = ds.getConnection();
	scope(exit) conn.close();
	
	// create session
	Session sess = factory.openSession();
	scope(exit) sess.close();

	Query q = sess.createQuery("select p from Preferences p");
	Preferences[] list = q.list!Preferences();

	return 0;
}

The code below uses ddbc. It works.

int main(string[] args) {

    string url = "mysql://localhost:3306/test?user=test,password=test";

    // creating Connection
    auto conn = createConnection(url);
    scope(exit) conn.close();

    // creating Statement
    auto stmt = conn.createStatement();
    scope(exit) stmt.close();

    // reading DB
    auto rs = stmt.executeQuery("SELECT * FROM preferences_wm ORDER BY id");
    writeln(rs.getFetchSize());
    return 0;
}

The code below uses ddbc and prepared statement. This throws SegFault just like the first piece of code.

int main(string[] args) {

    string url = "mysql://localhost:3306/webmarx?user=webmarx_dev,password=webm@rx";

    // creating Connection
    auto conn = createConnection(url);
    scope(exit) conn.close();

    // creating Statement
    auto stmt = conn.createStatement();
    scope(exit) stmt.close();

     PreparedStatement prepStatement = conn.prepareStatement("SELECT * FROM preferences_wm ORDER BY id");
     scope(exit) prepStatement.close();
     ResultSet rs = prepStatement.executeQuery();

    writeln(rs.getFetchSize());
    return 0;
}

MySQLPreparedStatement is deferencing a null cmd object. When MySQLPreparedStatement is instantiated, the cmd attribute from the super class MySQLStatement is never instantiated. This is what is causing the problem I think.

I tried to fix it by adding the following lines to MySQLPreparedStatement constructor, but it throws another SegFault error.

Command command = Command(conn.getConnection(), query);
this.cmd = &command;

I replicated this issue with 0.3.7:

Performing "debug" build using /usr/bin/dmd for x86_64.
derelict-util 2.0.6: target for configuration "library" is up to date.
derelict-pq 2.2.0: target for configuration "library" is up to date.
taggedalgebraic 0.11.4: target for configuration "library" is up to date.
eventcore 0.8.47: target for configuration "epoll" is up to date.
stdx-allocator 2.77.5: target for configuration "library" is up to date.
vibe-core 1.7.0: target for configuration "epoll" is up to date.
vibe-d:utils 0.8.6: target for configuration "library" is up to date.
vibe-d:data 0.8.6: target for configuration "library" is up to date.
mysql-native 1.1.4: target for configuration "library" is up to date.
ddbc 0.3.7: target for configuration "full" is up to date.
test-ddbc ~master: building configuration "application"...
Linking...
To force a rebuild of up-to-date targets, run again with --force.
Running ./test-ddbc 
Program exited with code -11

in 0.3.8 and above there's no longer a segfault, although there is another issue: #81