odbc icon indicating copy to clipboard operation
odbc copied to clipboard

Test fails on RedHat Linux 5.9 with unixODBC 2.3.1 and FreeTDS 0.91RC2

Open GoogleCodeExporter opened this issue 10 years ago • 24 comments

What steps will reproduce the problem?
1. Install freetds package with 'yum install'
2. Compile unixODBC 2.3.1 from source
3. Install the package with "go get code.google.com/p/odbc"
4. Run test with go test -mssrv SERVER -msuser USER -mspass PASSWD -msdb DB

What is the expected output? 

All tests pass

What do you see instead?

I see the following runtime error:

panic: runtime error: slice bounds out of range [recovered]
    panic: runtime error: slice bounds out of range

goroutine 4 [running]:
testing.func·004()
    /usr/local/src/go/src/pkg/testing/testing.go:348 +0xcd
code.google.com/p/odbc.(*BindableColumn).Value(0xc200070e40, 0x6b6c050, 0x6, 
0x4f36c0, 0xc200087cc0, ...)
    /home/oracle/gosrc/src/code.google.com/p/odbc/column.go:239 +0x283
code.google.com/p/odbc.(*Rows).Next(0xc2000004c8, 0xc200054540, 0x7, 0x7, 
0x54ee20, ...)
    /home/oracle/gosrc/src/code.google.com/p/odbc/rows.go:34 +0x137
database/sql.(*Rows).Next(0xc20008a300, 0x3)
    /usr/local/src/go/src/pkg/database/sql/sql.go:1310 +0xc1
code.google.com/p/odbc.TestMSSQLCreateInsertDelete(0xc200098000)
    /home/oracle/gosrc/src/code.google.com/p/odbc/mssql_test.go:270 +0x62f
testing.tRunner(0xc200098000, 0x815780)
    /usr/local/src/go/src/pkg/testing/testing.go:353 +0x8a
created by testing.RunTests
    /usr/local/src/go/src/pkg/testing/testing.go:433 +0x86b

goroutine 1 [chan receive]:
testing.RunTests(0x583330, 0x815780, 0xf, 0xf, 0x1, ...)
    /usr/local/src/go/src/pkg/testing/testing.go:434 +0x88e
testing.Main(0x583330, 0x815780, 0xf, 0xf, 0x824580, ...)
    /usr/local/src/go/src/pkg/testing/testing.go:365 +0x8a
main.main()
    code.google.com/p/odbc/_test/_testmain.go:73 +0x9a

goroutine 2 [syscall]:
exit status 2
FAIL    code.google.com/p/odbc  0.101s

What version of the product are you using? On what operating system?

[oracle@custservices odbc]$ go version
go version go1.1.2 linux/amd64
[oracle@custservices odbc]$ cat /etc/redhat-release
Red Hat Enterprise Linux Server release 5.9 (Tikanga)
[oracle@custservices odbc]$ uname -a
Linux custservices 2.6.18-348.3.1.el5 #1 SMP Tue Mar 5 13:19:32 EST 2013 x86_64 
x86_64 x86_64 GNU/Linux

Please provide any additional information below.

Original issue reported on code.google.com by victor.kryukov on 12 Nov 2013 at 2:54

GoogleCodeExporter avatar Jun 15 '15 05:06 GoogleCodeExporter

Ok, so I did some more digging (trying to access the same database through ODBC 
from R) and it looks like it's may be caused by SQLRowCount returning negative 
numbers. Here is what I see when I do a manual select in the isql tool:

> select * from people
...
SQLRowCount returns -4294966952
344 rows fetched

Original comment by victor.kryukov on 12 Nov 2013 at 3:46

GoogleCodeExporter avatar Jun 15 '15 05:06 GoogleCodeExporter

Cannot reproduce it here.

Please, run test with this extra line:

diff -r 703276ff5038 column.go
--- a/column.go Fri Nov 01 11:01:50 2013 +1100
+++ b/column.go Tue Nov 12 15:37:36 2013 +1100
@@ -236,6 +236,7 @@
    if !c.IsVariableWidth && int(c.Len) != c.Size {
        panic(fmt.Errorf("wrong column #%d length %d returned, %d expected", idx, c.Len, c.Size))
    }
+   fmt.Printf("%d: c=%+v c.Buffer=%+v\n", idx, c, c.Buffer)
    return c.BaseColumn.Value(c.Buffer[:c.Len])
 }

and tell use the output just before it fails.

What is your database server? (version and all)

I don't think SQLRowCount has anything to do with it.

Thank you.

Alex

Original comment by [email protected] on 12 Nov 2013 at 4:40

  • Changed state: Accepted

GoogleCodeExporter avatar Jun 15 '15 05:06 GoogleCodeExporter

Hi Alex, and thanks for the quick response.

Here is the output with the extra line. I'm getting the MS SQL version...

warning: building out-of-date packages:
    code.google.com/p/odbc/api
installing these packages with 'go test -i' will speed future tests.

=== RUN TestMSSQLCreateInsertDelete
0: c=&{BaseColumn:0xc200087a40 IsBound:true IsVariableWidth:true Size:21 Len:6 
Buffer:[103 108 101 110 100 97 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] smallBuf:[0 0 0 0 
0 0 0 0]} c.Buffer=[103 108 101 110 100 97 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
1: c=&{BaseColumn:0xc200087a80 IsBound:true IsVariableWidth:false Size:4 Len:4 
Buffer:[5 0 0 0] smallBuf:[5 0 0 0 0 0 0 0]} c.Buffer=[5 0 0 0]
2: c=&{BaseColumn:0xc200087ac0 IsBound:true IsVariableWidth:false Size:1 Len:1 
Buffer:[1] smallBuf:[1 0 0 0 0 0 0 0]} c.Buffer=[1]
3: c=&{BaseColumn:0xc200087b00 IsBound:true IsVariableWidth:false Size:8 Len:8 
Buffer:[0 0 0 0 0 0 47 64] smallBuf:[0 0 0 0 0 0 47 64]} c.Buffer=[0 0 0 0 0 0 
47 64]
4: c=&{BaseColumn:0xc200087b20 IsBound:true IsVariableWidth:false Size:16 
Len:16 Buffer:[208 7 5 0 10 0 11 0 1 0 1 0 0 0 0 0] smallBuf:[0 0 0 0 0 0 0 0]} 
c.Buffer=[208 7 5 0 10 0 11 0 1 0 1 0 0 0 0 0]
5: c=&{BaseColumn:0xc200087b40 IsBound:true IsVariableWidth:true Size:10 Len:6 
Buffer:[0 0 11 173 192 222 0 0 0 0] smallBuf:[0 0 0 0 0 0 0 0]} c.Buffer=[0 0 
11 173 192 222 0 0 0 0]
6: c=&{BaseColumn:0xc200087b60 IsBound:true IsVariableWidth:true Size:11 Len:2 
Buffer:[97 97 0 0 0 0 0 0 0 0 0] smallBuf:[0 0 0 0 0 0 0 0]} c.Buffer=[97 97 0 
0 0 0 0 0 0 0 0]
0: c=&{BaseColumn:0xc200087a40 IsBound:true IsVariableWidth:true Size:21 Len:6 
Buffer:[103 111 112 104 101 114 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] smallBuf:[0 0 0 
0 0 0 0 0]} c.Buffer=[103 111 112 104 101 114 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
1: c=&{BaseColumn:0xc200087a80 IsBound:true IsVariableWidth:false Size:4 Len:4 
Buffer:[3 0 0 0] smallBuf:[3 0 0 0 0 0 0 0]} c.Buffer=[3 0 0 0]
2: c=&{BaseColumn:0xc200087ac0 IsBound:true IsVariableWidth:false Size:1 Len:1 
Buffer:[0] smallBuf:[0 0 0 0 0 0 0 0]} c.Buffer=[0]
3: c=&{BaseColumn:0xc200087b00 IsBound:true IsVariableWidth:false Size:8 Len:8 
Buffer:[31 133 235 81 184 30 58 64] smallBuf:[31 133 235 81 184 30 58 64]} 
c.Buffer=[31 133 235 81 184 30 58 64]
4: c=&{BaseColumn:0xc200087b20 IsBound:true IsVariableWidth:false Size:16 
Len:16 Buffer:[217 7 5 0 10 0 11 0 1 0 1 0 192 212 84 7] smallBuf:[0 0 0 0 0 0 
0 0]} c.Buffer=[217 7 5 0 10 0 11 0 1 0 1 0 192 212 84 7]
5: c=&{BaseColumn:0xc200087b40 IsBound:true IsVariableWidth:true Size:10 Len:1 
Buffer:[0 0 11 173 192 222 0 0 0 0] smallBuf:[0 0 0 0 0 0 0 0]} c.Buffer=[0 0 
11 173 192 222 0 0 0 0]
6: c=&{BaseColumn:0xc200087b60 IsBound:true IsVariableWidth:true Size:11 Len:3 
Buffer:[98 98 98 0 0 0 0 0 0 0 0] smallBuf:[0 0 0 0 0 0 0 0]} c.Buffer=[98 98 
98 0 0 0 0 0 0 0 0]
0: c=&{BaseColumn:0xc200087a40 IsBound:true IsVariableWidth:true Size:21 Len:5 
Buffer:[99 104 114 105 115 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] smallBuf:[0 0 0 0 0 
0 0 0]} c.Buffer=[99 104 114 105 115 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
1: c=&{BaseColumn:0xc200087a80 IsBound:true IsVariableWidth:false Size:4 Len:4 
Buffer:[25 0 0 0] smallBuf:[25 0 0 0 0 0 0 0]} c.Buffer=[25 0 0 0]
2: c=&{BaseColumn:0xc200087ac0 IsBound:true IsVariableWidth:false Size:1 Len:1 
Buffer:[0] smallBuf:[0 0 0 0 0 0 0 0]} c.Buffer=[0]
3: c=&{BaseColumn:0xc200087b00 IsBound:true IsVariableWidth:false Size:8 Len:8 
Buffer:[0 0 0 0 0 0 73 64] smallBuf:[0 0 0 0 0 0 73 64]} c.Buffer=[0 0 0 0 0 0 
73 64]
4: c=&{BaseColumn:0xc200087b20 IsBound:true IsVariableWidth:false Size:16 
Len:16 Buffer:[223 7 12 0 25 0 0 0 0 0 0 0 0 0 0 0] smallBuf:[0 0 0 0 0 0 0 0]} 
c.Buffer=[223 7 12 0 25 0 0 0 0 0 0 0 0 0 0 0]
5: c=&{BaseColumn:0xc200087b40 IsBound:true IsVariableWidth:true Size:10 Len:3 
Buffer:[99 99 99 173 192 222 0 0 0 0] smallBuf:[0 0 0 0 0 0 0 0]} c.Buffer=[99 
99 99 173 192 222 0 0 0 0]
6: c=&{BaseColumn:0xc200087b60 IsBound:true IsVariableWidth:true Size:11 
Len:4294967295 Buffer:[98 98 98 0 0 0 0 0 0 0 0] smallBuf:[0 0 0 0 0 0 0 0]} 
c.Buffer=[98 98 98 0 0 0 0 0 0 0 0]
--- FAIL: TestMSSQLCreateInsertDelete (0.07 seconds)
panic: runtime error: slice bounds out of range [recovered]
    panic: runtime error: slice bounds out of range

goroutine 4 [running]:
testing.func·004()
    /usr/local/src/go/src/pkg/testing/testing.go:348 +0xcd
code.google.com/p/odbc.(*BindableColumn).Value(0xc200070e40, 0xd449000, 0x6, 
0x4f37a0, 0xc2000b4440, ...)
    /home/oracle/gosrc/src/code.google.com/p/odbc/column.go:240 +0x36a
code.google.com/p/odbc.(*Rows).Next(0xc2000004c8, 0xc200054540, 0x7, 0x7, 
0x54ef00, ...)
    /home/oracle/gosrc/src/code.google.com/p/odbc/rows.go:34 +0x137
database/sql.(*Rows).Next(0xc20008a300, 0x3)
    /usr/local/src/go/src/pkg/database/sql/sql.go:1310 +0xc1
code.google.com/p/odbc.TestMSSQLCreateInsertDelete(0xc200098000)
    /home/oracle/gosrc/src/code.google.com/p/odbc/mssql_test.go:270 +0x62f
testing.tRunner(0xc200098000, 0x815780)
    /usr/local/src/go/src/pkg/testing/testing.go:353 +0x8a
created by testing.RunTests
    /usr/local/src/go/src/pkg/testing/testing.go:433 +0x86b

goroutine 1 [chan receive]:
testing.RunTests(0x583450, 0x815780, 0xf, 0xf, 0x1, ...)
    /usr/local/src/go/src/pkg/testing/testing.go:434 +0x88e
testing.Main(0x583450, 0x815780, 0xf, 0xf, 0x824580, ...)
    /usr/local/src/go/src/pkg/testing/testing.go:365 +0x8a
main.main()
    code.google.com/p/odbc/_test/_testmain.go:73 +0x9a

goroutine 2 [syscall]:
exit status 2
FAIL    code.google.com/p/odbc  0.083s

Original comment by victor.kryukov on 12 Nov 2013 at 5:34

GoogleCodeExporter avatar Jun 15 '15 05:06 GoogleCodeExporter

Here is my MS SQL Version:

Microsoft SQL Server 2008 R2 (RTM) - 10.50.1600.1 (X64) 
    Apr  2 2010 15:48:46 
    Copyright (c) Microsoft Corporation
    Standard Edition (64-bit) on Windows NT 6.1 <X64> (Build 7601: Service Pack 1) (Hypervisor)

Original comment by victor.kryukov on 12 Nov 2013 at 5:38

GoogleCodeExporter avatar Jun 15 '15 05:06 GoogleCodeExporter

Incidentally, 4294967295 is 0xFFFFFFFF. I don't know what MS SQL server is 
trying to say here...

I checked the dbo.temp table that was created at the server, and it looks OK 
with the following 4 records:

glenda  5   1   15.50   2000-05-10 11:01:01.0   00000BADC0DE    aa
gopher  3   0   26.12   2009-05-10 11:01:01.123 00  bbb
chris   25  0   50.00   2015-12-25 00:00:00.0   636363  
null    0   0   0.00    2015-12-25 01:02:03.0       

Original comment by victor.kryukov on 12 Nov 2013 at 5:46

GoogleCodeExporter avatar Jun 15 '15 05:06 GoogleCodeExporter

The following change make the  TestMSSQLCreateInsertDelete pass, but now it 
hands on TestMSSQLTransactions

diff -r 703276ff5038 column.go
--- a/column.go Fri Nov 01 11:01:50 2013 +1100
+++ b/column.go Tue Nov 12 18:05:28 2013 +0000
@@ -229,13 +229,14 @@
            return nil, NewError("SQLGetData", h)
        }
    }
-   if c.Len.IsNull() {
+   if c.Len.IsNull() || c.Len == 0xFFFFFFFF {
        // is NULL
        return nil, nil
    }
    if !c.IsVariableWidth && int(c.Len) != c.Size {
        panic(fmt.Errorf("wrong column #%d length %d returned, %d expected", idx, c.Len, c.Size))
    }
+   fmt.Printf("%d: c=%+v c.Buffer=%+v\n", idx, c, c.Buffer)
    return c.BaseColumn.Value(c.Buffer[:c.Len])
 }

Original comment by victor.kryukov on 12 Nov 2013 at 6:06

GoogleCodeExporter avatar Jun 15 '15 05:06 GoogleCodeExporter

s/hands/hangs/

Original comment by victor.kryukov on 12 Nov 2013 at 6:06

GoogleCodeExporter avatar Jun 15 '15 05:06 GoogleCodeExporter

May be related: 

https://code.google.com/p/pyodbc/issues/detail?id=51

Specifically,

"On Windows, SQLLEN is an int64 and SQL_NULL_DATA is (-1).  Assuming the 64-bit 
driver
is correctly putting a 64-bit -1 in the field, it should work."

Original comment by victor.kryukov on 12 Nov 2013 at 6:09

GoogleCodeExporter avatar Jun 15 '15 05:06 GoogleCodeExporter

I think you are correct, it is something to do with how ODBC types are defined 
on your system. I hate this - that is why I use Go - there is never a question. 
:-)

To help us determine what is going on, please change mssql_test.go, like:

diff --git a/mssql_test.go b/mssql_test.go
--- a/mssql_test.go
+++ b/mssql_test.go
@@ -15,6 +15,9 @@
    "sync/atomic"
    "testing"
    "time"
+   "unsafe"
+
+   "code.google.com/p/odbc/api"
 )

 var (
@@ -1210,3 +1213,11 @@

    exec(t, db, "drop table dbo.temp")
 }
+
+func TestALEX(t *testing.T) {
+   fmt.Printf("api.SQL_NULL_DATA=%d\n", api.SQL_NULL_DATA)
+   var l api.SQLLEN
+   fmt.Printf("unsafe.Sizeof(api.SQLLEN)=%d\n", unsafe.Sizeof(l))
+   l = api.SQL_NULL_DATA
+   fmt.Printf("l=%d\n", l)
+}

and run it like

go test -run=ALEX

and show us the output.

That is what I see here on windows/amd64:

c:\go\path\src\code.google.com\p\odbc>go test -v -run=ALEX
=== RUN TestALEX
api.SQL_NULL_DATA=-1
unsafe.Sizeof(api.SQLLEN)=8
l=-1
--- PASS: TestALEX (0.00 seconds)
PASS
ok      code.google.com/p/odbc  0.050s


Thank you.

Alex

Original comment by [email protected] on 13 Nov 2013 at 1:34

GoogleCodeExporter avatar Jun 15 '15 05:06 GoogleCodeExporter

Here you are, Alex:

[oracle@custservices odbc]$ go test -run=ALEX
warning: building out-of-date packages:
    code.google.com/p/odbc/api
installing these packages with 'go test -i' will speed future tests.

api.SQL_NULL_DATA=-1
unsafe.Sizeof(api.SQLLEN)=8
l=-1
PASS
ok      code.google.com/p/odbc  0.016s

Original comment by victor.kryukov on 13 Nov 2013 at 1:38

GoogleCodeExporter avatar Jun 15 '15 05:06 GoogleCodeExporter

Here is another test:

diff -r 703276ff5038 mssql_test.go
--- a/mssql_test.go Fri Nov 01 11:01:50 2013 +1100
+++ b/mssql_test.go Wed Nov 13 01:48:57 2013 +0000
@@ -13,10 +13,14 @@
    "strconv"
    "strings"
    "sync/atomic"
    "testing"
    "time"
+   "reflect"
+   "unsafe"
+
+   "code.google.com/p/odbc/api"
 )

 var (
    mssrv    = flag.String("mssrv", "server", "ms sql server name")
    msdb     = flag.String("msdb", "dbname", "ms sql server database name")
@@ -1208,5 +1212,21 @@
        }
    }

    exec(t, db, "drop table dbo.temp")
 }
+
+func TestALEX(t *testing.T) {
+   fmt.Printf("api.SQL_NULL_DATA=%d\n", api.SQL_NULL_DATA)
+   var l api.SQLLEN
+   fmt.Printf("unsafe.Sizeof(api.SQLLEN)=%d\n", unsafe.Sizeof(l))
+   l = api.SQL_NULL_DATA
+   fmt.Printf("l=%d\n", l)
+}
+
+func TestVICTOR(t *testing.T) {
+   var x api.SQLLEN = 1
+   v := reflect.ValueOf(x)
+   fmt.Println("type:", v.Type())
+   fmt.Println("kind is uint64:", v.Kind() == reflect.Uint64)
+   fmt.Println("kind is int64:", v.Kind() == reflect.Int64)
+}

[oracle@custservices odbc]$ go test -run=VICTOR
warning: building out-of-date packages:
    code.google.com/p/odbc/api
installing these packages with 'go test -i' will speed future tests.

type: api.SQLLEN
kind is uint64: false
kind is int64: true
PASS
ok      code.google.com/p/odbc  0.015s

Original comment by victor.kryukov on 13 Nov 2013 at 1:50

GoogleCodeExporter avatar Jun 15 '15 05:06 GoogleCodeExporter

Well, could it be that in NewVariableWidthColumn, colWidth is api.SQLULEN, not 
api.SQLLEN?

Original comment by victor.kryukov on 13 Nov 2013 at 1:54

GoogleCodeExporter avatar Jun 15 '15 05:06 GoogleCodeExporter

I don't think so. I am thinking - I am a slow thinker.

Alex

Original comment by [email protected] on 13 Nov 2013 at 1:58

GoogleCodeExporter avatar Jun 15 '15 05:06 GoogleCodeExporter

What about if you make this change:

diff --git a/odbcstmt.go b/odbcstmt.go
--- a/odbcstmt.go
+++ b/odbcstmt.go
@@ -130,7 +130,7 @@
    }
    // fetch column descriptions
    s.Cols = make([]Column, n)
-   binding := true
+   binding := false
    for i := range s.Cols {
        c, err := NewColumn(s.h, i)
        if err != nil {

Do tests run OK?

Alex

Original comment by [email protected] on 13 Nov 2013 at 6:37

GoogleCodeExporter avatar Jun 15 '15 05:06 GoogleCodeExporter

[deleted comment]

GoogleCodeExporter avatar Jun 15 '15 05:06 GoogleCodeExporter

No, same problem: 

=== RUN TestMSSQLCreateInsertDelete
--- FAIL: TestMSSQLCreateInsertDelete (0.03 seconds)
panic: runtime error: slice bounds out of range [recovered]
    panic: runtime error: slice bounds out of range

goroutine 4 [running]:
testing.func·004()
    /usr/local/src/go/src/pkg/testing/testing.go:348 +0xcd
code.google.com/p/odbc.(*BindableColumn).Value(0xc200070e40, 0xbaedfd0, 0x6, 
0x4f36c0, 0xc200087cc0, ...)
    /home/oracle/gosrc/src/code.google.com/p/odbc/column.go:239 +0x283
code.google.com/p/odbc.(*Rows).Next(0xc2000004c8, 0xc200054540, 0x7, 0x7, 
0x54ee20, ...)
    /home/oracle/gosrc/src/code.google.com/p/odbc/rows.go:34 +0x137
database/sql.(*Rows).Next(0xc20008a300, 0x3)
    /usr/local/src/go/src/pkg/database/sql/sql.go:1310 +0xc1
code.google.com/p/odbc.TestMSSQLCreateInsertDelete(0xc200098000)
    /home/oracle/gosrc/src/code.google.com/p/odbc/mssql_test.go:270 +0x62f
testing.tRunner(0xc200098000, 0x815780)
    /usr/local/src/go/src/pkg/testing/testing.go:353 +0x8a
created by testing.RunTests
    /usr/local/src/go/src/pkg/testing/testing.go:433 +0x86b

goroutine 1 [chan receive]:
testing.RunTests(0x583330, 0x815780, 0xf, 0xf, 0x1, ...)
    /usr/local/src/go/src/pkg/testing/testing.go:434 +0x88e
testing.Main(0x583330, 0x815780, 0xf, 0xf, 0x824580, ...)
    /usr/local/src/go/src/pkg/testing/testing.go:365 +0x8a
main.main()
    code.google.com/p/odbc/_test/_testmain.go:73 +0x9a

goroutine 2 [syscall]:
exit status 2
FAIL    code.google.com/p/odbc  0.056s

Original comment by victor.kryukov on 13 Nov 2013 at 4:56

GoogleCodeExporter avatar Jun 15 '15 05:06 GoogleCodeExporter

I am still puzzled. I suspect your SQLBindCol and SQLGetData return unexpected 
(maybe invalid) values. Can you apply this patch:

diff --git a/column.go b/column.go
--- a/column.go
+++ b/column.go
@@ -13,22 +13,31 @@
    "unsafe"
 )

-type BufferLen api.SQLLEN
+type BufferLen struct {
+   Pre   int64
+   Value api.SQLLEN
+   Post  int64
+}

 func (l *BufferLen) IsNull() bool {
-   return *l == api.SQL_NULL_DATA
+   return l.Value == api.SQL_NULL_DATA
 }

 func (l *BufferLen) GetData(h api.SQLHSTMT, idx int, ctype api.SQLSMALLINT, buf []byte) api.SQLRETURN {
    return api.SQLGetData(h, api.SQLUSMALLINT(idx+1), ctype,
        api.SQLPOINTER(unsafe.Pointer(&buf[0])), api.SQLLEN(len(buf)),
-       (*api.SQLLEN)(l))
+       &l.Value)
 }

 func (l *BufferLen) Bind(h api.SQLHSTMT, idx int, ctype api.SQLSMALLINT, buf []byte) api.SQLRETURN {
    return api.SQLBindCol(h, api.SQLUSMALLINT(idx+1), ctype,
        api.SQLPOINTER(unsafe.Pointer(&buf[0])), api.SQLLEN(len(buf)),
-       (*api.SQLLEN)(l))
+       &l.Value)
+}
+
+func (l *BufferLen) ValueBytes() []byte {
+   n := unsafe.Sizeof(l.Value)
+   return (*[100]byte)(unsafe.Pointer(&l.Value))[:n]
 }

 // Column provides access to row columns.
@@ -224,7 +233,9 @@

 func (c *BindableColumn) Value(h api.SQLHSTMT, idx int) (driver.Value, error) {
    if !c.IsBound {
+       fmt.Printf("before GetData: c=%+v c.Len.ValueBytes=%+v\n", c, 
c.Len.ValueBytes())
        ret := c.Len.GetData(h, idx, c.CType, c.Buffer)
+       fmt.Printf("after GetData: c=%+v c.Len.ValueBytes=%+v\n", c, 
c.Len.ValueBytes())
        if IsError(ret) {
            return nil, NewError("SQLGetData", h)
        }
@@ -233,10 +244,10 @@
        // is NULL
        return nil, nil
    }
-   if !c.IsVariableWidth && int(c.Len) != c.Size {
+   if !c.IsVariableWidth && int(c.Len.Value) != c.Size {
        panic(fmt.Errorf("wrong column #%d length %d returned, %d expected", idx, c.Len, c.Size))
    }
-   return c.BaseColumn.Value(c.Buffer[:c.Len])
+   return c.BaseColumn.Value(c.Buffer[:c.Len.Value])
 }

 // NonBindableColumn provide access to columns, that can't be bound.
@@ -263,7 +274,7 @@
                // is NULL
                return nil, nil
            }
-           total = append(total, b[:l]...)
+           total = append(total, b[:l.Value]...)
            break loop
        case api.SQL_SUCCESS_WITH_INFO:
            err := NewError("SQLGetData", h).(*Error)
@@ -278,12 +289,12 @@
                i-- // remove null-termination character
            }
            total = append(total, b[:i]...)
-           if l != api.SQL_NO_TOTAL {
+           if l.Value != api.SQL_NO_TOTAL {
                // odbc gives us a hint about remaining data,
                // lets get it in one go.
-               n := int(l) // total bytes for our data
-               n -= i      // subtract already received
-               n += 2      // room for biggest (wchar) null-terminator
+               n := int(l.Value) // total bytes for our data
+               n -= i            // subtract already received
+               n += 2            // room for biggest (wchar) null-terminator
                if len(b) < n {
                    b = make([]byte, n)
                }
diff --git a/mssql_test.go b/mssql_test.go
--- a/mssql_test.go
+++ b/mssql_test.go
@@ -1220,3 +1220,20 @@
        t.Fatal("comparison fails")
    }
 }
+
+func TestMSSQLALEX(t *testing.T) {
+   db, sc, err := mssqlConnect()
+   if err != nil {
+       t.Fatal(err)
+   }
+   defer closeDB(t, db, sc, sc)
+
+   var s sql.NullString
+   err = db.QueryRow("select cast(null as varchar(10))").Scan(&s)
+   if err != nil {
+       t.Fatal(err)
+   }
+   if s.Valid {
+       t.Errorf("expected NULL string, but received %v", s)
+   }
+}
diff --git a/odbcstmt.go b/odbcstmt.go
--- a/odbcstmt.go
+++ b/odbcstmt.go
@@ -130,7 +130,7 @@
    }
    // fetch column descriptions
    s.Cols = make([]Column, n)
-   binding := true
+   binding := false
    for i := range s.Cols {
        c, err := NewColumn(s.h, i)
        if err != nil {


and run TestMSSQLALEX test and provide output here.

Thank you.

Alex

Original comment by [email protected] on 15 Nov 2013 at 4:33

GoogleCodeExporter avatar Jun 15 '15 05:06 GoogleCodeExporter

Here you are:

=== RUN TestMSSQLALEX
before GetData: c=&{BaseColumn:0xc200087580 IsBound:false IsVariableWidth:true 
Size:11 Len:{Pre:0 Value:0 Post:0} Buffer:[0 0 0 0 0 0 0 0 0 0 0] smallBuf:[0 0 
0 0 0 0 0 0]} c.Len.ValueBytes=[0 0 0 0 0 0 0 0]
after GetData: c=&{BaseColumn:0xc200087580 IsBound:false IsVariableWidth:true 
Size:11 Len:{Pre:0 Value:4294967295 Post:0} Buffer:[0 0 0 0 0 0 0 0 0 0 0] 
smallBuf:[0 0 0 0 0 0 0 0]} c.Len.ValueBytes=[255 255 255 255 0 0 0 0]
--- FAIL: TestMSSQLALEX (0.01 seconds)
panic: runtime error: slice bounds out of range [recovered]
    panic: runtime error: slice bounds out of range

goroutine 4 [running]:
testing.func·004()
    /usr/local/src/go/src/pkg/testing/testing.go:348 +0xcd
code.google.com/p/odbc.(*BindableColumn).Value(0xc200074230, 0x1d170910, 0x0, 
0x1, 0x41ad2a, ...)
    /home/oracle/gosrc/src/code.google.com/p/odbc/column.go:250 +0x53e
code.google.com/p/odbc.(*Rows).Next(0xc2000001f0, 0xc200077ff0, 0x1, 0x1, 0x1, 
...)
    /home/oracle/gosrc/src/code.google.com/p/odbc/rows.go:34 +0x137
database/sql.(*Rows).Next(0xc20008a300, 0x52bce0)
    /usr/local/src/go/src/pkg/database/sql/sql.go:1310 +0xc1
database/sql.(*Row).Scan(0xc2000875a0, 0x2abe22b91f50, 0x1, 0x1, 0x0, ...)
    /usr/local/src/go/src/pkg/database/sql/sql.go:1424 +0x1ae
code.google.com/p/odbc.TestMSSQLALEX(0xc20009b000)
    /home/oracle/gosrc/src/code.google.com/p/odbc/mssql_test.go:1222 +0x1e1
testing.tRunner(0xc20009b000, 0x8168d0)
    /usr/local/src/go/src/pkg/testing/testing.go:353 +0x8a
created by testing.RunTests
    /usr/local/src/go/src/pkg/testing/testing.go:433 +0x86b

goroutine 1 [chan receive]:
testing.RunTests(0x583e38, 0x816780, 0x10, 0x10, 0x1, ...)
    /usr/local/src/go/src/pkg/testing/testing.go:434 +0x88e
testing.Main(0x583e38, 0x816780, 0x10, 0x10, 0x825580, ...)
    /usr/local/src/go/src/pkg/testing/testing.go:365 +0x8a
main.main()
    code.google.com/p/odbc/_test/_testmain.go:75 +0x9a

goroutine 2 [syscall]:
exit status 2
FAIL    code.google.com/p/odbc  0.035s

Original comment by victor.kryukov on 15 Nov 2013 at 4:39

GoogleCodeExporter avatar Jun 15 '15 05:06 GoogleCodeExporter

Please, run this

diff --git a/column.go b/column.go
--- a/column.go
+++ b/column.go
@@ -16,7 +16,7 @@
 type BufferLen api.SQLLEN

 func (l *BufferLen) IsNull() bool {
-   return *l == api.SQL_NULL_DATA
+   return *l == 4294967295
 }

 func (l *BufferLen) GetData(h api.SQLHSTMT, idx int, ctype api.SQLSMALLINT, buf []byte) api.SQLRETURN {
@@ -224,7 +224,9 @@

 func (c *BindableColumn) Value(h api.SQLHSTMT, idx int) (driver.Value, error) {
    if !c.IsBound {
+       fmt.Printf("before GetData: c=%+v\n", c)
        ret := c.Len.GetData(h, idx, c.CType, c.Buffer)
+       fmt.Printf("after GetData: c=%+v\n", c)
        if IsError(ret) {
            return nil, NewError("SQLGetData", h)
        }
diff --git a/mssql_test.go b/mssql_test.go
--- a/mssql_test.go
+++ b/mssql_test.go
@@ -1220,3 +1220,20 @@
        t.Fatal("comparison fails")
    }
 }
+
+func TestMSSQLALEX(t *testing.T) {
+   db, sc, err := mssqlConnect()
+   if err != nil {
+       t.Fatal(err)
+   }
+   defer closeDB(t, db, sc, sc)
+
+   var s sql.NullString
+   err = db.QueryRow("select cast(null as varchar(10))").Scan(&s)
+   if err != nil {
+       t.Fatal(err)
+   }
+   if s.Valid {
+       t.Errorf("expected NULL string, but received %v", s)
+   }
+}
diff --git a/odbcstmt.go b/odbcstmt.go
--- a/odbcstmt.go
+++ b/odbcstmt.go
@@ -130,7 +130,7 @@
    }
    // fetch column descriptions
    s.Cols = make([]Column, n)
-   binding := true
+   binding := false
    for i := range s.Cols {
        c, err := NewColumn(s.h, i)
        if err != nil {
diff --git a/param.go b/param.go
--- a/param.go
+++ b/param.go
@@ -47,7 +47,7 @@
        buf = nil
        size = 1
        buflen = 0
-       plen = p.StoreStrLen_or_IndPtr(api.SQL_NULL_DATA)
+       plen = p.StoreStrLen_or_IndPtr(4294967295)
        sqltype = api.SQL_WCHAR
    case string:
        ctype = api.SQL_C_WCHAR

Thank you.

Alex

Original comment by [email protected] on 15 Nov 2013 at 4:59

GoogleCodeExporter avatar Jun 15 '15 05:06 GoogleCodeExporter

Hi Alex, sorry for the long silence. Now everything passes:

=== RUN TestMSSQLALEX
before GetData: c=&{BaseColumn:0xc200087580 IsBound:false IsVariableWidth:true 
Size:11 Len:0 Buffer:[0 0 0 0 0 0 0 0 0 0 0] smallBuf:[0 0 0 0 0 0 0 0]}
after GetData: c=&{BaseColumn:0xc200087580 IsBound:false IsVariableWidth:true 
Size:11 Len:4294967295 Buffer:[0 0 0 0 0 0 0 0 0 0 0] smallBuf:[0 0 0 0 0 0 0 
0]}
--- PASS: TestMSSQLALEX (0.01 seconds)
PASS
ok      code.google.com/p/odbc  0.020s

Original comment by victor.kryukov on 7 Dec 2013 at 9:17

GoogleCodeExporter avatar Jun 15 '15 05:06 GoogleCodeExporter

When I run the full test suite, though, it hangs at TestMSSQLTransactions:

=== RUN TestMSSQLCreateInsertDelete
before GetData: c=&{BaseColumn:0xc200088a20 IsBound:false IsVariableWidth:true 
Size:21 Len:0 Buffer:[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] smallBuf:[0 0 
0 0 0 0 0 0]}
after GetData: c=&{BaseColumn:0xc200088a20 IsBound:false IsVariableWidth:true 
Size:21 Len:6 Buffer:[103 108 101 110 100 97 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] 
smallBuf:[0 0 0 0 0 0 0 0]}
before GetData: c=&{BaseColumn:0xc200088a60 IsBound:false IsVariableWidth:false 
Size:4 Len:0 Buffer:[0 0 0 0] smallBuf:[0 0 0 0 0 0 0 0]}
after GetData: c=&{BaseColumn:0xc200088a60 IsBound:false IsVariableWidth:false 
Size:4 Len:4 Buffer:[5 0 0 0] smallBuf:[5 0 0 0 0 0 0 0]}
before GetData: c=&{BaseColumn:0xc200088aa0 IsBound:false IsVariableWidth:false 
Size:1 Len:0 Buffer:[0] smallBuf:[0 0 0 0 0 0 0 0]}
after GetData: c=&{BaseColumn:0xc200088aa0 IsBound:false IsVariableWidth:false 
Size:1 Len:1 Buffer:[1] smallBuf:[1 0 0 0 0 0 0 0]}
before GetData: c=&{BaseColumn:0xc200088ae0 IsBound:false IsVariableWidth:false 
Size:8 Len:0 Buffer:[0 0 0 0 0 0 0 0] smallBuf:[0 0 0 0 0 0 0 0]}
after GetData: c=&{BaseColumn:0xc200088ae0 IsBound:false IsVariableWidth:false 
Size:8 Len:8 Buffer:[0 0 0 0 0 0 47 64] smallBuf:[0 0 0 0 0 0 47 64]}
before GetData: c=&{BaseColumn:0xc200088b00 IsBound:false IsVariableWidth:false 
Size:16 Len:0 Buffer:[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] smallBuf:[0 0 0 0 0 0 0 
0]}
after GetData: c=&{BaseColumn:0xc200088b00 IsBound:false IsVariableWidth:false 
Size:16 Len:16 Buffer:[208 7 5 0 10 0 11 0 1 0 1 0 0 0 0 0] smallBuf:[0 0 0 0 0 
0 0 0]}
before GetData: c=&{BaseColumn:0xc200088b20 IsBound:false IsVariableWidth:true 
Size:10 Len:0 Buffer:[0 0 0 0 0 0 0 0 0 0] smallBuf:[0 0 0 0 0 0 0 0]}
after GetData: c=&{BaseColumn:0xc200088b20 IsBound:false IsVariableWidth:true 
Size:10 Len:6 Buffer:[0 0 11 173 192 222 0 0 0 0] smallBuf:[0 0 0 0 0 0 0 0]}
before GetData: c=&{BaseColumn:0xc200088b40 IsBound:false IsVariableWidth:true 
Size:11 Len:0 Buffer:[0 0 0 0 0 0 0 0 0 0 0] smallBuf:[0 0 0 0 0 0 0 0]}
after GetData: c=&{BaseColumn:0xc200088b40 IsBound:false IsVariableWidth:true 
Size:11 Len:2 Buffer:[97 97 0 0 0 0 0 0 0 0 0] smallBuf:[0 0 0 0 0 0 0 0]}
before GetData: c=&{BaseColumn:0xc200088a20 IsBound:false IsVariableWidth:true 
Size:21 Len:6 Buffer:[103 108 101 110 100 97 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] 
smallBuf:[0 0 0 0 0 0 0 0]}
after GetData: c=&{BaseColumn:0xc200088a20 IsBound:false IsVariableWidth:true 
Size:21 Len:6 Buffer:[103 111 112 104 101 114 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] 
smallBuf:[0 0 0 0 0 0 0 0]}
before GetData: c=&{BaseColumn:0xc200088a60 IsBound:false IsVariableWidth:false 
Size:4 Len:4 Buffer:[5 0 0 0] smallBuf:[5 0 0 0 0 0 0 0]}
after GetData: c=&{BaseColumn:0xc200088a60 IsBound:false IsVariableWidth:false 
Size:4 Len:4 Buffer:[3 0 0 0] smallBuf:[3 0 0 0 0 0 0 0]}
before GetData: c=&{BaseColumn:0xc200088aa0 IsBound:false IsVariableWidth:false 
Size:1 Len:1 Buffer:[1] smallBuf:[1 0 0 0 0 0 0 0]}
after GetData: c=&{BaseColumn:0xc200088aa0 IsBound:false IsVariableWidth:false 
Size:1 Len:1 Buffer:[0] smallBuf:[0 0 0 0 0 0 0 0]}
before GetData: c=&{BaseColumn:0xc200088ae0 IsBound:false IsVariableWidth:false 
Size:8 Len:8 Buffer:[0 0 0 0 0 0 47 64] smallBuf:[0 0 0 0 0 0 47 64]}
after GetData: c=&{BaseColumn:0xc200088ae0 IsBound:false IsVariableWidth:false 
Size:8 Len:8 Buffer:[31 133 235 81 184 30 58 64] smallBuf:[31 133 235 81 184 30 
58 64]}
before GetData: c=&{BaseColumn:0xc200088b00 IsBound:false IsVariableWidth:false 
Size:16 Len:16 Buffer:[208 7 5 0 10 0 11 0 1 0 1 0 0 0 0 0] smallBuf:[0 0 0 0 0 
0 0 0]}
after GetData: c=&{BaseColumn:0xc200088b00 IsBound:false IsVariableWidth:false 
Size:16 Len:16 Buffer:[217 7 5 0 10 0 11 0 1 0 1 0 192 212 84 7] smallBuf:[0 0 
0 0 0 0 0 0]}
before GetData: c=&{BaseColumn:0xc200088b20 IsBound:false IsVariableWidth:true 
Size:10 Len:6 Buffer:[0 0 11 173 192 222 0 0 0 0] smallBuf:[0 0 0 0 0 0 0 0]}
after GetData: c=&{BaseColumn:0xc200088b20 IsBound:false IsVariableWidth:true 
Size:10 Len:1 Buffer:[0 0 11 173 192 222 0 0 0 0] smallBuf:[0 0 0 0 0 0 0 0]}
before GetData: c=&{BaseColumn:0xc200088b40 IsBound:false IsVariableWidth:true 
Size:11 Len:2 Buffer:[97 97 0 0 0 0 0 0 0 0 0] smallBuf:[0 0 0 0 0 0 0 0]}
after GetData: c=&{BaseColumn:0xc200088b40 IsBound:false IsVariableWidth:true 
Size:11 Len:3 Buffer:[98 98 98 0 0 0 0 0 0 0 0] smallBuf:[0 0 0 0 0 0 0 0]}
before GetData: c=&{BaseColumn:0xc200088a20 IsBound:false IsVariableWidth:true 
Size:21 Len:6 Buffer:[103 111 112 104 101 114 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] 
smallBuf:[0 0 0 0 0 0 0 0]}
after GetData: c=&{BaseColumn:0xc200088a20 IsBound:false IsVariableWidth:true 
Size:21 Len:5 Buffer:[99 104 114 105 115 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] 
smallBuf:[0 0 0 0 0 0 0 0]}
before GetData: c=&{BaseColumn:0xc200088a60 IsBound:false IsVariableWidth:false 
Size:4 Len:4 Buffer:[3 0 0 0] smallBuf:[3 0 0 0 0 0 0 0]}
after GetData: c=&{BaseColumn:0xc200088a60 IsBound:false IsVariableWidth:false 
Size:4 Len:4 Buffer:[25 0 0 0] smallBuf:[25 0 0 0 0 0 0 0]}
before GetData: c=&{BaseColumn:0xc200088aa0 IsBound:false IsVariableWidth:false 
Size:1 Len:1 Buffer:[0] smallBuf:[0 0 0 0 0 0 0 0]}
after GetData: c=&{BaseColumn:0xc200088aa0 IsBound:false IsVariableWidth:false 
Size:1 Len:1 Buffer:[0] smallBuf:[0 0 0 0 0 0 0 0]}
before GetData: c=&{BaseColumn:0xc200088ae0 IsBound:false IsVariableWidth:false 
Size:8 Len:8 Buffer:[31 133 235 81 184 30 58 64] smallBuf:[31 133 235 81 184 30 
58 64]}
after GetData: c=&{BaseColumn:0xc200088ae0 IsBound:false IsVariableWidth:false 
Size:8 Len:8 Buffer:[0 0 0 0 0 0 73 64] smallBuf:[0 0 0 0 0 0 73 64]}
before GetData: c=&{BaseColumn:0xc200088b00 IsBound:false IsVariableWidth:false 
Size:16 Len:16 Buffer:[217 7 5 0 10 0 11 0 1 0 1 0 192 212 84 7] smallBuf:[0 0 
0 0 0 0 0 0]}
after GetData: c=&{BaseColumn:0xc200088b00 IsBound:false IsVariableWidth:false 
Size:16 Len:16 Buffer:[223 7 12 0 25 0 0 0 0 0 0 0 0 0 0 0] smallBuf:[0 0 0 0 0 
0 0 0]}
before GetData: c=&{BaseColumn:0xc200088b20 IsBound:false IsVariableWidth:true 
Size:10 Len:1 Buffer:[0 0 11 173 192 222 0 0 0 0] smallBuf:[0 0 0 0 0 0 0 0]}
after GetData: c=&{BaseColumn:0xc200088b20 IsBound:false IsVariableWidth:true 
Size:10 Len:3 Buffer:[99 99 99 173 192 222 0 0 0 0] smallBuf:[0 0 0 0 0 0 0 0]}
before GetData: c=&{BaseColumn:0xc200088b40 IsBound:false IsVariableWidth:true 
Size:11 Len:3 Buffer:[98 98 98 0 0 0 0 0 0 0 0] smallBuf:[0 0 0 0 0 0 0 0]}
after GetData: c=&{BaseColumn:0xc200088b40 IsBound:false IsVariableWidth:true 
Size:11 Len:4294967295 Buffer:[98 98 98 0 0 0 0 0 0 0 0] smallBuf:[0 0 0 0 0 0 
0 0]}
before GetData: c=&{BaseColumn:0xc200088a20 IsBound:false IsVariableWidth:true 
Size:21 Len:5 Buffer:[99 104 114 105 115 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] 
smallBuf:[0 0 0 0 0 0 0 0]}
after GetData: c=&{BaseColumn:0xc200088a20 IsBound:false IsVariableWidth:true 
Size:21 Len:4 Buffer:[110 117 108 108 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] 
smallBuf:[0 0 0 0 0 0 0 0]}
before GetData: c=&{BaseColumn:0xc200088a60 IsBound:false IsVariableWidth:false 
Size:4 Len:4 Buffer:[25 0 0 0] smallBuf:[25 0 0 0 0 0 0 0]}
after GetData: c=&{BaseColumn:0xc200088a60 IsBound:false IsVariableWidth:false 
Size:4 Len:4 Buffer:[0 0 0 0] smallBuf:[0 0 0 0 0 0 0 0]}
before GetData: c=&{BaseColumn:0xc200088aa0 IsBound:false IsVariableWidth:false 
Size:1 Len:1 Buffer:[0] smallBuf:[0 0 0 0 0 0 0 0]}
after GetData: c=&{BaseColumn:0xc200088aa0 IsBound:false IsVariableWidth:false 
Size:1 Len:1 Buffer:[0] smallBuf:[0 0 0 0 0 0 0 0]}
before GetData: c=&{BaseColumn:0xc200088ae0 IsBound:false IsVariableWidth:false 
Size:8 Len:8 Buffer:[0 0 0 0 0 0 73 64] smallBuf:[0 0 0 0 0 0 73 64]}
after GetData: c=&{BaseColumn:0xc200088ae0 IsBound:false IsVariableWidth:false 
Size:8 Len:8 Buffer:[0 0 0 0 0 0 0 0] smallBuf:[0 0 0 0 0 0 0 0]}
before GetData: c=&{BaseColumn:0xc200088b00 IsBound:false IsVariableWidth:false 
Size:16 Len:16 Buffer:[223 7 12 0 25 0 0 0 0 0 0 0 0 0 0 0] smallBuf:[0 0 0 0 0 
0 0 0]}
after GetData: c=&{BaseColumn:0xc200088b00 IsBound:false IsVariableWidth:false 
Size:16 Len:16 Buffer:[223 7 12 0 25 0 1 0 2 0 3 0 0 0 0 0] smallBuf:[0 0 0 0 0 
0 0 0]}
before GetData: c=&{BaseColumn:0xc200088b20 IsBound:false IsVariableWidth:true 
Size:10 Len:3 Buffer:[99 99 99 173 192 222 0 0 0 0] smallBuf:[0 0 0 0 0 0 0 0]}
after GetData: c=&{BaseColumn:0xc200088b20 IsBound:false IsVariableWidth:true 
Size:10 Len:4294967295 Buffer:[99 99 99 173 192 222 0 0 0 0] smallBuf:[0 0 0 0 
0 0 0 0]}
before GetData: c=&{BaseColumn:0xc200088b40 IsBound:false IsVariableWidth:true 
Size:11 Len:4294967295 Buffer:[98 98 98 0 0 0 0 0 0 0 0] smallBuf:[0 0 0 0 0 0 
0 0]}
after GetData: c=&{BaseColumn:0xc200088b40 IsBound:false IsVariableWidth:true 
Size:11 Len:4294967295 Buffer:[98 98 98 0 0 0 0 0 0 0 0] smallBuf:[0 0 0 0 0 0 
0 0]}
--- PASS: TestMSSQLCreateInsertDelete (0.13 seconds)
=== RUN TestMSSQLTransactions
before GetData: c=&{BaseColumn:0xc2000b4d40 IsBound:false IsVariableWidth:false 
Size:4 Len:0 Buffer:[0 0 0 0] smallBuf:[0 0 0 0 0 0 0 0]}
after GetData: c=&{BaseColumn:0xc2000b4d40 IsBound:false IsVariableWidth:false 
Size:4 Len:4 Buffer:[0 0 0 0] smallBuf:[0 0 0 0 0 0 0 0]}
before GetData: c=&{BaseColumn:0xc2000b4e80 IsBound:false IsVariableWidth:false 
Size:4 Len:0 Buffer:[0 0 0 0] smallBuf:[0 0 0 0 0 0 0 0]}
after GetData: c=&{BaseColumn:0xc2000b4e80 IsBound:false IsVariableWidth:false 
Size:4 Len:4 Buffer:[1 0 0 0] smallBuf:[1 0 0 0 0 0 0 0]}

Original comment by victor.kryukov on 7 Dec 2013 at 9:19

GoogleCodeExporter avatar Jun 15 '15 05:06 GoogleCodeExporter

victor,

I googled again, and as you pointed yourself earlier 
(https://code.google.com/p/pyodbc/issues/detail?id=51), I think there is a 
mismatch here somewhere. I suspect your unixODBC is compiled as 64-bit, while 
freetds is 32-bit. This http://bugs.mysql.com/bug.php?id=68185 describes 
situation similar to yours, but with a different language and different driver. 
I don't think I can help you any here. I am no good with Linux, you have to 
work out how to rebuild / reinstall your libs.

I don't think we should start investigating TestMSSQLTransactions until you 
sore previous problem. Sorry.

Alex

Original comment by [email protected] on 9 Dec 2013 at 12:44

GoogleCodeExporter avatar Jun 15 '15 05:06 GoogleCodeExporter

I see a similar panic. Note that c.Len is no ware near -1 or MAXINT and my environment is 64 bit.

ALAN 259 len buffer 256 len 324
2018/11/02 11:13:36 http2: panic serving 172.26.0.1:57406: runtime error: slice bounds out of range
goroutine 54 [running]:
net/http.(*http2serverConn).runHandler.func1(0xc4202da000, 0xc4203b5faf, 0xc420020380)
	/usr/lib/go-1.10/src/net/http/h2_bundle.go:5753 +0x190
panic(0x7f7e20, 0xc8eec0)
	/usr/lib/go-1.10/src/runtime/panic.go:502 +0x229
bitbucket.eng.zebrium.com/zsw/zwsd/vendor/github.com/alexbrainman/odbc.(*BindableColumn).Value(0xc4205afa80, 0x7f76c00008c0, 0x61, 0x7cf2e0, 0xc4204031e8, 0x0, 0x0)
	/home/alan-y/go/src/bitbucket.eng.zebrium.com/zsw/zwsd/vendor/github.com/alexbrainman/odbc/column.go:260 +0x3e7
bitbucket.eng.zebrium.com/zsw/zwsd/vendor/github.com/alexbrainman/odbc.(*Rows).Next(0xc4202da018, 0xc4200a9800, 0x62, 0x62, 0x0, 0xc4203b4408)
	/home/alan-y/go/src/bitbucket.eng.zebrium.com/zsw/zwsd/vendor/github.com/alexbrainman/odbc/rows.go:35 +0xbf
database/sql.(*Rows).nextLocked(0xc4202ece00, 0xc420320000)
	/usr/lib/go-1.10/src/database/sql/sql.go:2622 +0xc4
database/sql.(*Rows).Next.func1()
	/usr/lib/go-1.10/src/database/sql/sql.go:2600 +0x3c
database/sql.withLock(0x8c8a00, 0xc4202ece30, 0xc4203b4458)
	/usr/lib/go-1.10/src/database/sql/sql.go:3032 +0x63
database/sql.(*Rows).Next(0xc4202ece00, 0xc4202da130)
	/usr/lib/go-1.10/src/database/sql/sql.go:2599 +0x7a
bitbucket.eng.zebrium.com/zsw/zwsd/link.EventMapAction(0xc42016e630, 0xc4205a6900, 0xc4202ce5c0, 0x873877, 0x10)
	/home/alan-y/go/src/bitbucket.eng.zebrium.com/zsw/zwsd/link/event_map.go:179 +0x3069
bitbucket.eng.zebrium.com/zsw/zwsd/zwsd/handlers/eventmap.EventMapAPI.Post(0xc42016e630)
	/home/alan-y/go/src/bitbucket.eng.zebrium.com/zsw/zwsd/zwsd/handlers/eventmap/eventmap_api_Map.go:37 +0x234
main.(EventMapInterface).Post-fm(0xc42016e630)
	/home/alan-y/go/src/bitbucket.eng.zebrium.com/zsw/zwsd/zwsd/eventmap_if.go:19 +0x39
bitbucket.eng.zebrium.com/zsw/zwsd/link.TokenAuthHandler.ServeHTTP(0xc420162620, 0x8c9b40, 0xc4202da000, 0xc420142700)
	/home/alan-y/go/src/bitbucket.eng.zebrium.com/zsw/zwsd/link/auth.go:145 +0x8f9
bitbucket.eng.zebrium.com/zsw/zwsd/vendor/github.com/gorilla/mux.(*Router).ServeHTTP(0xc4201607e0, 0x8c9b40, 0xc4202da000, 0xc420142700)
	/home/alan-y/go/src/bitbucket.eng.zebrium.com/zsw/zwsd/vendor/github.com/gorilla/mux/mux.go:162 +0xed
bitbucket.eng.zebrium.com/zsw/zwsd/vendor/github.com/watercraft/handlers.(*cors).ServeHTTP(0xc4201d6120, 0x8c9b40, 0xc4202da000, 0xc420364100)
	/home/alan-y/go/src/bitbucket.eng.zebrium.com/zsw/zwsd/vendor/github.com/watercraft/handlers/cors.go:51 +0xa04
net/http.serverHandler.ServeHTTP(0xc4201de000, 0x8c9b40, 0xc4202da000, 0xc420364100)
	/usr/lib/go-1.10/src/net/http/server.go:2694 +0xbc
net/http.initNPNRequest.ServeHTTP(0xc4200f8a80, 0xc4201de000, 0x8c9b40, 0xc4202da000, 0xc420364100)
	/usr/lib/go-1.10/src/net/http/server.go:3260 +0x9a
net/http.(Handler).ServeHTTP-fm(0x8c9b40, 0xc4202da000, 0xc420364100)
	/usr/lib/go-1.10/src/net/http/h2_bundle.go:5475 +0x4d
net/http.(*http2serverConn).runHandler(0xc420020380, 0xc4202da000, 0xc420364100, 0xc42000c080)
	/usr/lib/go-1.10/src/net/http/h2_bundle.go:5760 +0x89
created by net/http.(*http2serverConn).processHeaders
	/usr/lib/go-1.10/src/net/http/h2_bundle.go:5494 +0x46b

watercraft avatar Nov 02 '18 18:11 watercraft

bitbucket.eng.zebrium.com/zsw/zwsd/vendor/github.com/alexbrainman/odbc.(*BindableColumn).Value(0xc4205afa80, 0x7f76c00008c0, 0x61, 0x7cf2e0, 0xc4204031e8, 0x0, 0x0) /home/alan-y/go/src/bitbucket.eng.zebrium.com/zsw/zwsd/vendor/github.com/alexbrainman/odbc/column.go:260 +0x3e7

Current version of column.go line 260 https://github.com/alexbrainman/odbc/blob/2d7d0e45c7870320611501683ca6073a0d9dfeed/column.go#L260 does not have panic. And you did not say how do I reproduce the problem.

Alex

alexbrainman avatar Nov 03 '18 05:11 alexbrainman