Fossil SCM

More reliably work around the problem experienced by the previous commit. Not sure if this is the right long-term solution since we seem to have an architectural problem: at least one of Fossil's custom SQL functions can change the schema (in this case, by creating a temporary table), thereby invalidating a prepared statement while it is running. See the comment in checkin.c for a bit more information. Of course, there are rearrangements that avoid the issue, but it is certainly a trap for the unwary.

andygoth 2016-11-06 20:19 UTC andygoth-changes
Commit 5258a43d78fd433daa4ed36cae21b1d7e46c4efd
2 files changed +6 -13 +2 -2
+6 -13
--- src/checkin.c
+++ src/checkin.c
@@ -173,23 +173,16 @@
173173
flags & C_MTIME ? "datetime(mtime, 'unixepoch', toLocal())" : "''",
174174
flags & C_SIZE ? "size" : "0",
175175
fossil_all_reserved_names(0), blob_sql_text(&where));
176176
}
177177
178
-#if 1
179
- /* SQLITE BUG WORKAROUND??? */
180
- /* If I step the query sans the ORDER BY clause, then I can run the full query
181
- * without incident. But if I delete this workaround and run the query
182
- * normally, I get SQLITE_ABORT due to ROLLBACK, which makes no sense. */
183
- db_prepare(&q, "%s", blob_sql_text(&sql));
184
- if( (flags & C_ALL) && (flags & C_MTIME) ){
185
- db_bind_int(&q, ":vid", db_lget_int("checkout", 0));
186
- }
187
- db_step(&q);
188
- db_finalize(&q);
189
- /* SQLITE BUG WORKAROUND??? */
190
-#endif
178
+ /* Pre-create the "ok" temporary table so the checkin_mtime() SQL function
179
+ * does not lead to SQLITE_ABORT_ROLLBACK during execution of the OP_OpenRead
180
+ * SQLite opcode. checkin_mtime() calls mtime_of_manifest_file() which
181
+ * creates a temporary table if it doesn't already exist, thus invalidating
182
+ * the prepared statement in the middle of its execution. */
183
+ db_multi_exec("CREATE TEMP TABLE IF NOT EXISTS ok(rid INTEGER PRIMARY KEY)");
191184
192185
/* Append an ORDER BY clause then compile the query. */
193186
blob_append_sql(&sql, " ORDER BY pathname");
194187
db_prepare(&q, "%s", blob_sql_text(&sql));
195188
blob_reset(&sql);
196189
--- src/checkin.c
+++ src/checkin.c
@@ -173,23 +173,16 @@
173 flags & C_MTIME ? "datetime(mtime, 'unixepoch', toLocal())" : "''",
174 flags & C_SIZE ? "size" : "0",
175 fossil_all_reserved_names(0), blob_sql_text(&where));
176 }
177
178 #if 1
179 /* SQLITE BUG WORKAROUND??? */
180 /* If I step the query sans the ORDER BY clause, then I can run the full query
181 * without incident. But if I delete this workaround and run the query
182 * normally, I get SQLITE_ABORT due to ROLLBACK, which makes no sense. */
183 db_prepare(&q, "%s", blob_sql_text(&sql));
184 if( (flags & C_ALL) && (flags & C_MTIME) ){
185 db_bind_int(&q, ":vid", db_lget_int("checkout", 0));
186 }
187 db_step(&q);
188 db_finalize(&q);
189 /* SQLITE BUG WORKAROUND??? */
190 #endif
191
192 /* Append an ORDER BY clause then compile the query. */
193 blob_append_sql(&sql, " ORDER BY pathname");
194 db_prepare(&q, "%s", blob_sql_text(&sql));
195 blob_reset(&sql);
196
--- src/checkin.c
+++ src/checkin.c
@@ -173,23 +173,16 @@
173 flags & C_MTIME ? "datetime(mtime, 'unixepoch', toLocal())" : "''",
174 flags & C_SIZE ? "size" : "0",
175 fossil_all_reserved_names(0), blob_sql_text(&where));
176 }
177
178 /* Pre-create the "ok" temporary table so the checkin_mtime() SQL function
179 * does not lead to SQLITE_ABORT_ROLLBACK during execution of the OP_OpenRead
180 * SQLite opcode. checkin_mtime() calls mtime_of_manifest_file() which
181 * creates a temporary table if it doesn't already exist, thus invalidating
182 * the prepared statement in the middle of its execution. */
183 db_multi_exec("CREATE TEMP TABLE IF NOT EXISTS ok(rid INTEGER PRIMARY KEY)");
 
 
 
 
 
 
 
184
185 /* Append an ORDER BY clause then compile the query. */
186 blob_append_sql(&sql, " ORDER BY pathname");
187 db_prepare(&q, "%s", blob_sql_text(&sql));
188 blob_reset(&sql);
189
--- src/descendants.c
+++ src/descendants.c
@@ -216,12 +216,12 @@
216216
static int prevVid = -1;
217217
static Stmt q;
218218
219219
if( prevVid!=vid ){
220220
prevVid = vid;
221
- db_multi_exec("DROP TABLE IF EXISTS temp.ok;"
222
- "CREATE TEMP TABLE ok(x INTEGER PRIMARY KEY);");
221
+ db_multi_exec("CREATE TEMP TABLE IF NOT EXISTS ok(rid INTEGER PRIMARY KEY);"
222
+ "DELETE FROM ok;");
223223
compute_ancestors(vid, 100000000, 1);
224224
}
225225
db_static_prepare(&q,
226226
"SELECT (max(event.mtime)-2440587.5)*86400 FROM mlink, event"
227227
" WHERE mlink.mid=event.objid"
228228
--- src/descendants.c
+++ src/descendants.c
@@ -216,12 +216,12 @@
216 static int prevVid = -1;
217 static Stmt q;
218
219 if( prevVid!=vid ){
220 prevVid = vid;
221 db_multi_exec("DROP TABLE IF EXISTS temp.ok;"
222 "CREATE TEMP TABLE ok(x INTEGER PRIMARY KEY);");
223 compute_ancestors(vid, 100000000, 1);
224 }
225 db_static_prepare(&q,
226 "SELECT (max(event.mtime)-2440587.5)*86400 FROM mlink, event"
227 " WHERE mlink.mid=event.objid"
228
--- src/descendants.c
+++ src/descendants.c
@@ -216,12 +216,12 @@
216 static int prevVid = -1;
217 static Stmt q;
218
219 if( prevVid!=vid ){
220 prevVid = vid;
221 db_multi_exec("CREATE TEMP TABLE IF NOT EXISTS ok(rid INTEGER PRIMARY KEY);"
222 "DELETE FROM ok;");
223 compute_ancestors(vid, 100000000, 1);
224 }
225 db_static_prepare(&q,
226 "SELECT (max(event.mtime)-2440587.5)*86400 FROM mlink, event"
227 " WHERE mlink.mid=event.objid"
228

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button