Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

database/sql: sqlite corruption #2622

Closed
bradfitz opened this issue Dec 26, 2011 · 7 comments
Closed

database/sql: sqlite corruption #2622

bradfitz opened this issue Dec 26, 2011 · 7 comments
Assignees
Milestone

Comments

@bradfitz
Copy link
Contributor

@bradfitz bradfitz commented Dec 26, 2011

For investigation later:

--------

From: Vadik Vygonets
to: golang-nuts 

Merry solstice, List!

Linux, amd64.  When reading a blob from sqlite3 using (*Row)Scan(),
the first 8 bytes get damaged in transit.  (*Rows)Scan() works
though.  I didn't test other drivers.

Test program:

package main

import (
       "exp/sql"
       "fmt"
       _ "github.com/mattn/go-sqlite3"
)

var blob = []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15}

func main() {
       db, _ := sql.Open("sqlite3", "foo.db")
       db.Exec("create table foo (id integer primary key, bar
blob[16])")
       db.Exec("insert or replace into foo (id, bar) values(?,?)", 0,
blob)
       b := make([]byte, 16)
       db.QueryRow("select bar from foo where id = ?", 0).Scan(&b)
       fmt.Printf("%x\n", b)
}

Output looks something like this (somewhat different number every
time):
b09c7a030000000008090a0b0c0d0e0f

Long story short, (*Row)Scan() calls (*Rows /*sic*/ )Close(), which
results in C.sqlite3_finalize(), which is where the damage happens (I
didn't look inside).  It seems like the bug is in the definition of
exp/sql API, but I don't know enough about promises the driver should
make to tell for sure.

But don't let it distract you from drinking gluhwein, ok?
@gopherbot
Copy link

@gopherbot gopherbot commented Dec 26, 2011

Comment 1 by unixdj:

default branch, btw.
@adg
Copy link
Contributor

@adg adg commented Jan 4, 2012

Comment 2:

Labels changed: added priority-go1.

@bradfitz
Copy link
Contributor Author

@bradfitz bradfitz commented Jan 11, 2012

Comment 3:

Yeah, I can reproduce this.
The issue is that the gosqlite3 driver uses unsafe and in its Next(dest []interface{})
method, populates []byte pointing into memory that will go away when the Rows are closed.
So far, that's fine.
But then the Scan function, when scanning from a driver-owned []byte to a pointer to a
client-owned []byte doesn't do a copy.
That's the bug, I believe.
I verified that scanning to a string is fine.
@bradfitz
Copy link
Contributor Author

@bradfitz bradfitz commented Jan 11, 2012

@gopherbot
Copy link

@gopherbot gopherbot commented Jan 11, 2012

Comment 5 by unixdj:

> But then the Scan function, when scanning from a driver-owned []byte to a pointer to a
client-owned []byte doesn't do a copy.
Which is consistent with the documentation for Row.Scan().  Doesn't mean it's not a bug,
of course.
(BTW, the make() call in my/your example code is probably superfluous.)
@bradfitz
Copy link
Contributor Author

@bradfitz bradfitz commented Jan 12, 2012

Comment 6:

Fix in review here:
http://golang.org/cl/5533077/
Verified that it fixes this issue.
@bradfitz
Copy link
Contributor Author

@bradfitz bradfitz commented Jan 12, 2012

Comment 7:

This issue was closed by revision 701f70a.

Status changed to Fixed.

@bradfitz bradfitz added fixed labels Jan 12, 2012
@bradfitz bradfitz self-assigned this Jan 12, 2012
@mikioh mikioh changed the title sqlite exp/sql corruption database/sql: sqlite corruption Feb 18, 2015
@rsc rsc added this to the Go1 milestone Apr 10, 2015
@rsc rsc removed the priority-go1 label Apr 10, 2015
@golang golang locked and limited conversation to collaborators Jun 24, 2016
This issue was closed.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
4 participants
You can’t perform that action at this time.