alexbrainman / odbc

odbc driver written in go
BSD 3-Clause "New" or "Revised" License
353 stars 140 forks source link

mssql: weird errors when inserting data #5

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
I'm using similar code with multiple databases to test insert speed with 
different styles and today I tried odbc. See 
http://play.golang.org/p/dDXXXHmbt5.

For some reason I sometimes see very strange errors with odbc, e.g.:

i=36127: SQLExecute: {23000} [Microsoft][ODBC SQL Server Driver][SQL 
Server]Violation of PRIMARY KEY constraint 'PK__data__3213E83FE4DDA2C7'. Cannot 
insert duplicate key in object 'dbo.data'. The duplicate key value is (36202).
{01000} [Microsoft][ODBC SQL Server Driver][SQL Server]The statement has been 
terminated.

i=60976: SQLExecute: {23000} [Microsoft][ODBC SQL Server Driver][SQL 
Server]Violation of PRIMARY KEY constraint 'PK__data__3213E83FE4DDA2C7'. Cannot 
insert duplicate key in object 'dbo.data'. The duplicate key value is (1).
{01000} [Microsoft][ODBC SQL Server Driver][SQL Server]The statement has been 
terminated.

Notice that the value sql server complains does not match the value my program 
is using. Another common error is:

i=28339: SQLExecute: {22003} [Microsoft][SQL Server Native Client 11.0]Numeric 
value out of range

i=36229: SQLExecute: {22003} [Microsoft][ODBC SQL Server 
Driver]Числовое значение выходит за пределы 
допустимого диапазона

Russian text also means "The number value is out of range". It seems like maybe 
there's a race in odbc somewhere? Looks almost like underlying ODBC statements 
are sometimes used from another goroutine entirely...

Original issue reported on code.google.com by sna...@gmail.com on 26 Apr 2013 at 4:47

GoogleCodeExporter commented 9 years ago
OK, I found the problem! In param.go, BindValue assigns values to Data to keep 
it from being GCed, but it doesn't assign values it actually should. For 
example in int64 case it assigns p.Data = d (a copy of int64) when buf is 
pointing to the address of int64. Because of this nothing stops GC from garbage 
collecting the heap int64, so by the time SQLExecute is called all sorts of 
garbage may happen to be there.

Original comment by sna...@gmail.com on 26 Apr 2013 at 5:15

GoogleCodeExporter commented 9 years ago
I am surprised it worked before! Thank you. Do you want to send the fix?

Alex

Original comment by alex.bra...@gmail.com on 26 Apr 2013 at 5:36

GoogleCodeExporter commented 9 years ago
https://codereview.appspot.com/9010043/

Original comment by alex.bra...@gmail.com on 29 Apr 2013 at 7:27

GoogleCodeExporter commented 9 years ago
This issue was closed by revision 62682477fd4e.

Original comment by alex.bra...@gmail.com on 3 May 2013 at 1:58