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