alexbrainman / odbc

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

panic: too much data returned: 4294967295 bytes returned, but buffer size is 1024 #100

Closed ghost closed 6 years ago

ghost commented 6 years ago

Hi,

I'm trying to implement and use CLOBs with DB2. If you look at https://github.com/alexbrainman/odbc/compare/master...rbastic:master you can see the changes I was able to make to get the code to a point where it .... seems to almost work. I'm sort of lost now though. Maybe you've seen this problem before.

To reproduce the stacktrace, you can load up dyndao (github.com/rbastic/dyndao) and check out the 'dev' branch, with the DB2 sample database:

$ cd src/src/github.com/rbastic/dyndao/adapters/db2

DB2_DSN='DRIVER=DB2; DATABASE=SAMPLE;HOSTNAME=127.0.0.1;PORT=50000;PROTOCOL=TCPIP;UID=db2inst1;PWD=dyndaoPassword;' go test -v 

If you don't feel like doing this, I completely understand -- but any pointers on how the string types work and how to get CLOBs working with DB2 would be awesome!

disclaimer: I'm an ODBC newbie, sadly, and I'm generally working an abstraction level higher (building an ORM) with these sorts of things, so I'm not particularly great at driver-level work. Really appreciate any time you can give me.

Thanks in advance, Ryan

alexbrainman commented 6 years ago

I will probably confuse you even more.

I tried to understand what happened here. I searched for the error message: too much data returned. And I can see this error is returned from NonBindableColumn.Value. But just before the error is returned, we check for l.IsNull() - this expression returns false for you. I wonder why - the l is 4294967295 and api.SQL_NULL_DATA is -1. But 4294967295 is 0xffff, which is -1 for int32. Type of l is api.SQLLEN, which is equivalent to C.SQLLEN. And C.SQLLEN is int64 on my computer, but if I look in /usr/include/sqltypes.h, I can see that it is possible for SQLLEN to be int not long - search for SIZEOF_LONG_INT. But that all should just work regardless. That is of course if your C libs match your C header files. I wonder if your C libs do not match your C header files. I could not really tell you how to check that.

Does this

diff --git a/mssql_test.go b/mssql_test.go
index fd3f6c9..db551ff 100644
--- a/mssql_test.go
+++ b/mssql_test.go
@@ -1726,3 +1726,10 @@ func TestMSSQLMarkBeginBadConn(t *testing.T) {
        testFn(next.label, next.fn)
    }
 }
+
+func TestALEX(t *testing.T) {
+   type BufferLen api.SQLLEN
+   var l BufferLen
+   l = 4294967295
+   t.Logf("%v", l)
+}

builds?

Alex

ghost commented 6 years ago

Re: "I will probably confuse you more."

Haha! Thanks for the good laugh first thing in the morning. We're all trying to do our best to infer meaning from code, I suppose.

Philosophy aside, I appreciate you taking the time to debug this - going to investigate further on my end and I'll see what I can find. It seems possible that I messed something up when installing ODBC based on the information you sent.

ghost commented 6 years ago

Reinvestigated this and wasn't able to find anything. I will close this now and if I get more time at some point, with more information, I will file another issue.

Niosop commented 6 years ago

Also getting this when accessing Informix on Linux. Only seems to happen when executing a query that pulls data from a text column that has null values. Same query works fine under Windows.

type Restriction struct {
        ID          string         `db:"secreq"`
        Text        sql.NullString `db:"txt"`
        Description sql.NullString `db:"comm"`
}

Following works:

err := s.SISdb.Select(&restrictions, "SELECT secreq, txt, comm  FROM secreq_table WHERE secreq != \"\" and comm IS NOT NULL")

This gives the error message:

err := s.SISdb.Select(&restrictions, "SELECT secreq, txt, comm  FROM secreq_table WHERE secreq != \"\"")
alexbrainman commented 6 years ago

@Niosop I could try and debug this, if you provide me with reproducible example.

I have small Linux computer. Do you think I can run https://hub.docker.com/r/ibmcom/informix-developer-database/ as a database?

What client software do I need to install? How?

Also you would have to provide an example code to demonstrate the problem. The code would have to include table creation and all insert statements required.

Alex

Niosop commented 6 years ago

Thanks for the offer. I've worked around the problem for now, so it's not critical, but I will attempt to try the docker option you posted to see if I can come up w/ instructions for a simple reproducible setup. It's entirely possible it's due to the particular versions of Informix SDK/unixodbc/Informix Server in use.

If I get a working test case I'll post instructions and could even give you access to the test VM to save you some time getting it set up.

alexbrainman commented 6 years ago

@rbastic and @Niosop you might be interested to read #113.

Alex