Given that I cannot commit this right now, here is a patch for the bug
(introduced by yours truly) which causes SQLite3 transactions to go
haywire if prepared statements are used and _pselect/_pquery encounter
BUSY more than RETRY times.
Once ASF machines come back online, I'll commit this. In the meantime,
apologies if you bumped into this one.
PS. The patch also features some trivial simplifications in _pselect.
--
Bojan
Index: dbd/apr_dbd_sqlite3.c
===================================================================
--- dbd/apr_dbd_sqlite3.c (revision 405803)
+++ dbd/apr_dbd_sqlite3.c (working copy)
@@ -381,6 +381,10 @@
}
*nrows = sqlite3_changes(sql->conn);
+
+ if (ret == SQLITE_BUSY) {
+ sqlite3_reset(stmt);
+ }
}
if (dbd_sqlite3_is_success(ret)) {
@@ -457,9 +461,10 @@
(*results)->col_names = apr_pcalloc(pool,
column_count * sizeof(char *));
do {
- ret = sqlite3_step((*results)->stmt);
+ ret = sqlite3_step(stmt);
if (ret == SQLITE_BUSY) {
if (retry_count++ > MAX_RETRY_COUNT) {
+ sqlite3_reset(stmt);
ret = SQLITE_ERROR;
} else {
apr_dbd_mutex_unlock();
@@ -471,7 +476,7 @@
apr_dbd_column_t *col;
row = apr_palloc(pool, sizeof(apr_dbd_row_t));
row->res = *results;
- row->res->stmt = (*results)->stmt;
+ row->res->stmt = stmt;
increment = sizeof(apr_dbd_column_t *);
length = increment * (*results)->sz;
row->columns = apr_palloc(pool, length);
@@ -482,19 +487,18 @@
/* copy column name once only */
if ((*results)->col_names[i] == NULL) {
(*results)->col_names[i] =
- apr_pstrdup(pool,
- sqlite3_column_name((*results)->stmt, i));
+ apr_pstrdup(pool,sqlite3_column_name(stmt, i));
}
column->name = (*results)->col_names[i];
- column->size = sqlite3_column_bytes((*results)->stmt, i);
- column->type = sqlite3_column_type((*results)->stmt, i);
+ column->size = sqlite3_column_bytes(stmt, i);
+ column->type = sqlite3_column_type(stmt, i);
column->value = NULL;
switch (column->type) {
case SQLITE_FLOAT:
case SQLITE_INTEGER:
case SQLITE_TEXT:
hold = NULL;
- hold = (char *) sqlite3_column_text((*results)->stmt, i);
+ hold = (char *) sqlite3_column_text(stmt, i);
if (hold) {
column->value = apr_palloc(pool, column->size + 1);
strncpy(column->value, hold, column->size + 1);