Skip to content

Commit dff49f9

Browse files
authored
Merge branch 'mattn:master' into master
2 parents 79df247 + da62659 commit dff49f9

File tree

3 files changed

+42
-3
lines changed

3 files changed

+42
-3
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ go build --tags "icu json1 fts5 secure_delete"
181181

182182
# Compilation
183183

184-
This package requires the `CGO_ENABLED=1` ennvironment variable if not set by default, and the presence of the `gcc` compiler.
184+
This package requires the `CGO_ENABLED=1` environment variable if not set by default, and the presence of the `gcc` compiler.
185185

186186
If you need to add additional CFLAGS or LDFLAGS to the build command, and do not want to modify this package, then this can be achieved by using the `CGO_CFLAGS` and `CGO_LDFLAGS` environment variables.
187187

sqlite3.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -494,10 +494,12 @@ func (ai *aggInfo) Done(ctx *C.sqlite3_context) {
494494
// Commit transaction.
495495
func (tx *SQLiteTx) Commit() error {
496496
_, err := tx.c.exec(context.Background(), "COMMIT", nil)
497-
if err != nil && err.(Error).Code == C.SQLITE_BUSY {
498-
// sqlite3 will leave the transaction open in this scenario.
497+
if err != nil {
498+
// sqlite3 may leave the transaction open in this scenario.
499499
// However, database/sql considers the transaction complete once we
500500
// return from Commit() - we must clean up to honour its semantics.
501+
// We don't know if the ROLLBACK is strictly necessary, but according
502+
// to sqlite's docs, there is no harm in calling ROLLBACK unnecessarily.
501503
tx.c.exec(context.Background(), "ROLLBACK", nil)
502504
}
503505
return err

sqlite3_test.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,43 @@ func TestForeignKeys(t *testing.T) {
248248
}
249249
}
250250

251+
func TestDeferredForeignKey(t *testing.T) {
252+
fname := TempFilename(t)
253+
uri := "file:" + fname + "?_foreign_keys=1"
254+
db, err := sql.Open("sqlite3", uri)
255+
if err != nil {
256+
os.Remove(fname)
257+
t.Errorf("sql.Open(\"sqlite3\", %q): %v", uri, err)
258+
}
259+
_, err = db.Exec("CREATE TABLE bar (id INTEGER PRIMARY KEY)")
260+
if err != nil {
261+
t.Errorf("failed creating tables: %v", err)
262+
}
263+
_, err = db.Exec("CREATE TABLE foo (bar_id INTEGER, FOREIGN KEY(bar_id) REFERENCES bar(id) DEFERRABLE INITIALLY DEFERRED)")
264+
if err != nil {
265+
t.Errorf("failed creating tables: %v", err)
266+
}
267+
tx, err := db.Begin()
268+
if err != nil {
269+
t.Errorf("Failed to begin transaction: %v", err)
270+
}
271+
_, err = tx.Exec("INSERT INTO foo (bar_id) VALUES (123)")
272+
if err != nil {
273+
t.Errorf("Failed to insert row: %v", err)
274+
}
275+
err = tx.Commit()
276+
if err == nil {
277+
t.Errorf("Expected an error: %v", err)
278+
}
279+
_, err = db.Begin()
280+
if err != nil {
281+
t.Errorf("Failed to begin transaction: %v", err)
282+
}
283+
284+
db.Close()
285+
os.Remove(fname)
286+
}
287+
251288
func TestRecursiveTriggers(t *testing.T) {
252289
cases := map[string]bool{
253290
"?_recursive_triggers=1": true,

0 commit comments

Comments
 (0)