Git Product home page Git Product logo

gofreetds's Introduction

gofreetds

Go FreeTDS wrapper. Native Sql Server database driver.

Features:

  • can be used as database/sql driver
  • handles calling stored procedures
  • handles multiple resultsets
  • supports database mirroring
  • connection pooling
  • scaning resultsets into structs

Get started

Install dependencines

FreeTDS libraries must be installed on the system.

Mac

brew install freetds

Ubuntu, Debian...

sudo apt-get install freetds-dev

Go get

go get github.com/minus5/gofreetds

Docs

http://godoc.org/github.com/minus5/gofreetds

Using as database/sql driver

Name of the driver is mssql.

db, err := sql.Open("mssql", connStr)
...
row := db.QueryRow("SELECT au_fname, au_lname name FROM authors WHERE au_id = ?", "172-32-1176")
..
var firstName, lastName string
err = row.Scan(&firstName, &lastName)

Full example in example/mssql.

Stored Procedures

What I'm missing in database/sql is calling stored procedures, handling return values and output params. And especially handling multiple result sets. Which is all supported by FreeTDS and of course by gofreetds.

Connect:

pool, err := freetds.NewConnPool("user=ianic;pwd=ianic;database=pubs;host=iow")
defer pool.Close()
...
//get connection
conn, err := pool.Get()
defer conn.Close()

Execute stored procedure:

rst, err := conn.ExecSp("sp_help", "authors")  

Read sp return value, and output params:

returnValue := rst.Status()
var param1, param2 int
rst.ParamScan(&param1, &param2)

Read sp resultset (fill the struct):

author := &Author{}
rst.Scan(author)

Read next resultset:

if rst.NextResult() {
    for rst.Next() {
        var v1, v2 string
        rst.Scan(&v1, &v2)
    }
}

Full example in example/stored_procedure

Other usage

Executing arbitrary sql is supported with Exec or ExecuteSql.

Execute query:

rst, err := conn.Exec("select au_id, au_lname, au_fname from authors")

Rst is array of results. Each result has Columns and Rows array. Each row is array of values. Each column is array of ResultColumn objects.

Full example in example/exec.

Execute query with params:

rst, err := conn.ExecuteSql("select au_id, au_lname, au_fname from authors where au_id = ?", "998-72-3567")

Sybase Compatibility Mode

Gofreetds now supports Sybase ASE 16.0 through the driver. In order to support this, this post is very helpful: Connect to MS SQL Server and Sybase ASE from Mac OS X and Linux with unixODBC and FreeTDS (from Internet Archive)

To use a Sybase ASE server with Gofreetds, you simply need to set a compatibility mode on your connection string after you've configured your .odbc.ini file and .freetds.conf file.

This mode uses TDS Version 5.

Connection String Parameter

You can set your connection string up for Sybase by using the 'compatibility_mode' Parameter. The parameter can be named 'compatibility', 'compatibility mode', 'compatibility_mode' or 'Compatibility Mode'. Currently this mode only supports Sybase. To specify you can use 'sybase' or 'Sybase'.

Server=myServerAddress;Database=myDatabase;User Id=myUsername;Password=myPassword;Failover Partner=myMirror;Max Pool Size=200;Compatibility Mode=Sybase

Testing

Tests depend on the pubs database.

Pubs sample database install script could be downloaded. After installing that package you will find instpubs.sql on the disk (C:\SQL Server 2000 Sample Databases). Execute that script to create pubs database.

Tests and examples are using environment variable GOFREETDS_CONN_STR to connect to the pubs database.

export GOFREETDS_CONN_STR="user=ianic;pwd=ianic;database=pubs;host=iow"
export GOFREETDS_MIRROR_HOST="iow-mirror"

If you don't want to setup and test database mirroring than don't define GOFREETDS_MIRROR_HOST. Mirroring tests will be skipped.

gofreetds's People

Contributors

daliborfilus avatar foobarmeow avatar gljubojevic avatar grahamking avatar gregtzar avatar ianic avatar jpop32 avatar marksonghurst avatar mprcela avatar patko avatar thatguystone avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

gofreetds's Issues

TestExecuteSqlNullString prints the message "unknown dataType *string"

Although the test completes as a PASS, TestExecuteSqlNullString in conn_test.go prints the message "unknown dataType *string".

Changing the variable declaration on line 458 of conn_test.go to
var str string
suppresses the message, but it's not clear whether this is the expected behaviour. Should the object under test accept a string pointer, or is the test in error?

ConnPool.Get blocked by slow connections

I'm connecting to a server that is taking ~10 seconds to connect to. Using the connection pool, I'm observing an odd behavior where even if there are free connections available, ConnPool.Get is blocking until the other connection completes. Once established, everything seems to work as expected, but cold starts are painfully slow, particularly when a large pool is used (I believe the default is 100 connections).

On a cursory look, the pooling implementation's use of both poolGuard and poolMutex looks a bit suspect, but I haven't thought about it too much. If this isn't by design, perhaps we can figure out a way to handle this case?

Upgrade to FreeTDS 0.95-19 introduced gofreetds issues with nvarchar trailing spaces

Hello.
Platform: CentOS 7 x86_64, Go 1.5.1

I've been reliably using gofreetds with FreeTDS 0.91 (from epel RPM freetds-0.91-12.git0a42888.el7.x86_64) which was recently upgraded to FreeTDS 0.95.19 (freetds-0.95.19-1.el7.x86_64).
Once I performed the update, I cleaned built and installed gofreetds (having also installed the 0.95.19 freetds-devel RPM) but found my Go daemon's database unit tests were failing against both my SQL Server 2014 and 2008 servers, with the same issue.

Upon inspection I could see that trailing spaces were appearing in the data returned from columns of the nvarchar type. So where a returned column was correctly empty (from me pushing up an empty Go string) when using FreeTDS 0.91, when using FreeTDS 0.95 I am now getting a " " (single space) returned. The data within the tables also shows the trailing spaces present.

You can probably guess what I've changed to resolve this :-)
convert_sql_buf.go
/*
if datatype == XSYBNVARCHAR || datatype == XSYBNCHAR {
//FIXME - adding len bytes to the end of the buf
// realy don't understand why this is necessary
// come to this solution by try and error
l := len(data)
for i := 0; i < l; i++ {
data = append(data, byte(0))
}
}
*/

Commenting out that block of code removes the trailing spaces and resolves my issue on 0.95
However, without it, gofreetds will break on 0.91, with the following error being reported:

dbutil.c:86:msgno 8016: "The incoming tabular data stream (TDS) remote procedure call (RPC) protocol stream is incorrect. Parameter 5 ("@nvcFirstname"): Data type 0xE7 has an invalid data length or metadata length."

It appears to me that the FIXME is no longer required in 0.95 but is still required in 0.91
Perhaps the FreeTDS version can be detected at connection time (?) and then the FIXME logic applied as necessary? Or maybe time to draw a line in the sand and say only 0.95 is supported?
Any advice on how to proceed would be welcome. I'm new to GitHub and contributing, so I'm not sure what the etiquette is :-)

My /etc/freetds.conf file is as per initially installed by the FreeTDS RPM, which has no client charset setting in it. Everything in the freetds.log file generated suggests the data is being converted from UTF-8 okay.

Driver corrupts byte slices

I've got a couple of issues reading and writing []byte arrays to MSSQL via the gofreetds driver. I'm attaching a small example which truncates data. When I write []byte{1, 2, 3, 4, 5}, reading it back gets []byte{1, 2, 3, 4}.

What I have not been able to reproduce in this small program is that sometimes, when reading back the result set, the byte buffer returned is huge, with only the first few items populated. In this case, []byte{1, 2, 3, 4, 5, 0...]. It's zero padded up to a length of 64512, which smells awfully close to a 64k read buffer size - so maybe we're getting back some whole buffer instead of the bytes actually read?

In any case, I always get one of the two results - the truncated version missing the last byte, or the huge buffer which contains the desired bytes at the beginning.

main.txt

Unable to use the SQL Server Maximum DateTime

Hello.
My SQL Server database is refusing to accept the SQL Maximum Datetime of "9999-12-31 23:59:59.997" as a stored procedure parameter with the following error:

Msg 20018, Level 16\nGeneral SQL Server error: Check messages from the SQL Server\n\n\nMsg 8023, Level 16, State 1\nServer 'MUSTANG', Line 1\n\tThe incoming tabular data stream (TDS) remote procedure call (RPC) protocol stream is incorrect. Parameter 16 (\"@dtOwnershipEndDate\"): The supplied value is not a valid instance of data type datetime. Check the source data for invalid values. An example of an invalid value is data of numeric type with scale greater than precision.\n"

I am assigning the "9999-12-31 23:59:59.997" value to a Go time.Time (which appears ok), and FreeTDS/gofreetds is correctly recognising that the stored procedure parameter should be a SYBDATETIME.

Some logging I added to convert_sql_buf.go within function typeToSqlBuf showed that the Go Time value is broken down into these components:

diff -2643127431936722624 days -30591 secs 4275457715

I'll try and do so more research to help assist with this, but if you can see any immediate issues with using the SQL Maximum datetime from within gofreetds, I would be very grateful if you could let me know and I can work around it by using a lower datetime.

I'm using SQL Server 2014 and FreeTDS 0.95

Thanks.

Possible resource leak on dead pooled connection

From testing with a SQL Server I could reboot on-demand, I noticed the pool statistics were appearing incorrect. I believe there is a possible resource leak in the ConnPool.addToPool function called by ConnPool.Release

func (p *ConnPool) addToPool(conn *Conn) {
    p.poolMutex.Lock()
    defer p.poolMutex.Unlock()
    if !conn.isDead() {
        conn.expiresFromPool = time.Now().Add(poolExpiresInterval)
        //release to the top of the pool
        newPool := []*Conn{}
        newPool = append(newPool, conn)
        newPool = append(newPool, p.pool...)
        p.pool = newPool
    }
}

If conn.isDead() is true, then I the connection is not being closed and p.connCount is not being decremented. There are some FreeTDS calls in Conn.close() which I suspect if not called, could result in a resource leak.

Spelling error.

executesql.go:

    return nil, errors.New(fmt.Sprintf("Incorect number of params, expecting %d got %d", 

Incorrect

But +1 for this spelling error, helped me track down where the problem was coming from!

how to fix it

vendor\github.com\minus5\gofreetds\conn_pool.go:33:19: undefined: Conn
vendor\github.com\minus5\gofreetds\params_cache.go:8:22: undefined: spParam

ExecuteSql Sybase - No sp_executesql in Sybase

Greetings,

I would like to propose making the below line that checks for sybase 12.5, should be
if conn.sybaseMode125() || conn.sybaseMode() {

Due to Sybase ASE not having stored procedure sp_executesql like MS SQL Server does. Without that, one must avoid using methods that hit ExecuteSql method if using Sybase ASE.

Thanks.

if conn.sybaseMode125() {

Installing GoFreeTds in Windows 7 Error

I have Already install MinGW gcc is working ok, when I go get -u github.com/minus5/gofreetds I receive this error:

D:\GoLib\src\github.com\minus5\gofreetds\callbacks.go:8:22: fatal error: sybfront.h: No such file or directory
#include <sybfront.h>
^
compilation terminated.

Can you help me?

Setting DB for DbUse?

Hello,

I'm a little confused about the usage of DbUse(). I was imagining it accepting a string that then attempts to change the connection to the database passed in. But it seems to be checking an un-exported variable. Am I missing something?

Thanks.

Data type 0x2B is unknown. FreeTDS version?

I am attempting to execute a stored procedure on my database, and I'm getting the following error:

2014/08/07 15:30:04 Msg 8009, Level 16
General SQL Server error: Check messages from the SQL Server

Msg 8009, Level 16, State 1
Server 'server', Line 1
The incoming tabular data stream (TDS) remote procedure call (RPC) protocol stream is incorrect. Parameter 1 ("@Parameter1"): Data type 0x2B is unknown.
/home/jackman/code/edge-api/src/rolist/ro.go:34 (rolist.ROList)

Why is this data type unknown? Is the database responding to a reference of data type 0x2B by FreeTDS? I know that my server supports this data type (DateTimeOffset) because that's the expected type of the parameter.

This post mentions/verifies the data type in question:
http://lists.ibiblio.org/pipermail/freetds/2011q2/026938.html

Code snippet:

nullDate := "3/10/1997 12:00:00 AM"                                                                 
rst, err := conn.ExecSp("Procedure", nullDate, nullDate, 1, 291, 1)     
if err != nil {                                                                                     
        return rolist, errors.Stack(err)                                                            
}  

I can successfully perform select statements and other things on the DB.

I thought perhaps my version of FreeTDS is outdated, so I built the latest version locally, and then executed with the following:

jackman@debian:~/code/edge-api$ LD_LIBRARY_PATH=$HOME/opt/lib GOPATH=$PWD:$GOPATH go run ./src/main.go
panic: dbopen error

goroutine 16 [running]:
runtime.panic(0x5010a0, 0xc2080002b0)
        /home/jackman/code/go/src/pkg/runtime/panic.c:279 +0xf5
core.connect(0x7cb160)
        /home/jackman/code/edge-api/src/core/db.go:21 +0x85
core.init·1()
        /home/jackman/code/edge-api/src/core/db.go:14 +0x1e
core.init()
        /home/jackman/code/edge-api/src/core/db.go:28 +0x4b
rolist.init()
        /home/jackman/code/edge-api/src/rolist/ro.go:40 +0x50
main.init()
        /home/jackman/code/edge-api/src/main.go:33 +0x46

goroutine 19 [finalizer wait]:
runtime.park(0x415520, 0x7db678, 0x7cf289)
        /home/jackman/code/go/src/pkg/runtime/proc.c:1369 +0x89
runtime.parkunlock(0x7db678, 0x7cf289)
        /home/jackman/code/go/src/pkg/runtime/proc.c:1385 +0x3b
runfinq()
        /home/jackman/code/go/src/pkg/runtime/mgc0.c:2644 +0xcf
runtime.goexit()
        /home/jackman/code/go/src/pkg/runtime/proc.c:1445

goroutine 17 [syscall]:
runtime.goexit()
        /home/jackman/code/go/src/pkg/runtime/proc.c:1445
exit status 2

Without more specific output from gofreetds, I don't know how to proceed. Please help. Thank you.

Unit Tests depend on a table created in TestCreateTable

When running the unit tests against a freshly setup DB, the tests will fail at conn_sp_test:318, since the TestCreateTable hasn't been run. The solution would be to have table created in some sort of setup function or something. I might be able to submit a PR for this, but I wanted to open an issue in case I am unable to.

Column type XML causes error: dbbind failed: no such column or no such conversion possible, or target buffer too small

I must work with a few tables with column type defined as "XML". Trying to run conn.Exec() which selects such columns results in the following error: dbbind failed: no such column or no such conversion possible, or target buffer too small

I think the XML column type should be marked as "canvary" and that would solve the problem?
When I used my fork of this repo which didn't have your (@ianic) changes mentioned in pull request #28 which limits the canvary only to SYBCHAR and SYBBINARY, it worked. So maybe adding another condition for the XML column type should be enough...

I will try to fix this (with tests) in a few hours.

Recent breaking changes

Recent pull requests merged in to this repo have caused a regression.

Change 1: dc2777a
Change 2: b2a5891

Change 1 (@Myself) was introduced to solve an issue with empty strings breaking the db. Change 2 (@thatguystone) was introduced 3 months later to solve the same issue. Both pull requests were then merged at the same time. Both changes address the same issue using different methods, but change 2 seems to have caused a regression in my code, causing errors in a codebase that was not erroring out before the change. Example error is included below. I apologize for not having better information to reproduce this at the moment. I actually like the way change 2 solved the issue better than change 1, and I'm not yet sure how change 2 is causing the issue, I just know that if I roll back to before it got pulled in then I no longer get this error.

Server Error: Msg 1001, Level 15 General SQL Server error: Check messages from the SQL Server Msg 137, Level 15 General SQL Server error: Check messages from the SQL Server Msg 1001, Level 15, State 1 Server 'LUR-SRV-01\SQLEXPRESS', Line 1 Line 1: Length or precision specification 0 is invalid. Msg 137, Level 15, State 2 Server 'LUR-SRV-01\SQLEXPRESS', Line 2 Must declare the scalar variable "@p1".

OUTPUT parameter handling is broken by PR#47

I believe the change to OUTPUT parameter handling introduced in PR#47 is incorrect and should be reverted.

My understanding of the issue is based on the stored procedure used in the test case added as part of the patch. In pure T-SQL, the code to create this stored procedure is:

create proc test_sp_bit_type_null_output
(
	@shouldReturn bit,
	@bitValue bit=1 output
) as
	if 1 = @shouldReturn
	begin
    	set @bitValue = 1
		return 0
	end
	return -1

The patch seems to be based on the premise that the default value for the OUTPUT parameter @bitValue should be used if an input value for the parameter is not explicitly provided. The test case calls the procedure in this way, only providing a value for the first input parameter @shouldReturn:

rst, err := conn.ExecSp(spName, false)

(conn_sp_test.go line 428)

However, I believe this is a misapprehension about how OUTPUT parameters work in T-SQL. To call this procedure from T-SQL and collect the value of the OUTPUT parameter, it is always necessary to provide an input value. This can be seen when calling the procedure with @shouldReturn set to 0, which does not modify the values of @bitValue

declare @out bit --@out is created with the value NULL
exec test_sp_bit_type_null_output @shouldReturn = 0, @bitValue = @out OUTPUT
select @out AS out

The result is:

out
-----
NULL

(1 row(s) affected)

The default value for @bitValue will only be used when the parameter is not referenced in the call - in which case, the value of the OUTPUT parameter cannot be collected:

exec test_sp_bit_type_null_output @shouldReturn = 0

On this basis, I believe the patch is misguided and should be rolled back.

README Connection Pool Incorrect

Hi, regarding connection pooling the Readme says:

//create connection pool (for max. 100 connections)
pool, err := freetds.NewConnPool("user=ianic;pwd=ianic;database=pubs;host=iow", 100)

But NewConnPool() takes only a connection string, not a pool size.

Support for sql server 2000?

Could I use this driver to connect sql server 2000?When I did this, I got an error:

Cannot connect: dbopen error
Msg 20002, Level 9
Adaptive Server connection failed (my sql server host)

I used the correct connect information, host, user name, password, database name...
but it dose not work, could anyone help me? :(

ExecuteSql() does not support any kind of nil/null values.

Using sql.NullString (or custom NullTime which implements driver.Valuer interface (methods Value, Scan)) as a parameter to ExecuteSql results in SQL error. Using *time.Time, *string, etc. results in the same error:

Server 'xxx', Line 1
        Conversion failed when converting date and/or time from character string.

This happens when I try to use datetime passed by user in the query. The query looks like this:

-- ....
(@DateFrom IS NULL OR CAST(o.CreatedAt AS Date) >= CAST(@DateFrom AS Date))

Which my custom QueryWithNamedParameters will conver to this:

(? IS NULL OR CAST(o.CreatedAt AS Date) >= CAST(? AS Date))

and then I pass my NullTime type to the query, expecting it to behave like this:

(NULL IS NULL OR CAST(o.CreatedAt AS Date) >= CAST(NULL AS Date))

but it doesn't and results in the error above.

I'm currently trying to work around this issue by patching executesql.go, function "go2SqlDataType" like this, which works:

    default:
        log.Printf("unknown dataType %T", t)
        // support for sql.NullString, sql.NullWhatever...
        // TODO: return correct type for parameter? we don't know it, the Valuer interface will not tell us.
        // Maybe we can go deeper and pass the value again to go2SqlDataType
        if val, ok := value.(driver.Valuer); ok {
            log.Printf("...but it implements Valuer, using that")
            val2, err := val.Value()
            if err != nil {
                log.Printf("value(): %+v, err: %+v", val2, err)
            } else {
                if val2 != nil {
                    // Value() is something, let's go deeper to get what it is
                    log.Printf("go2SqlDataType: Valuer.Value(): %+v, recursing", val2)
                    return go2SqlDataType(val2)
                } else {
                    log.Printf("go2SqlDataType: Valuer.Value(): returning VARCHAR NULL")
                    return fmt.Sprintf("nvarchar (%d)", 4), "NULL"
                }
            }
        } else {
            log.Printf("and it does not implement Valuer")
        }
    }

... but I don't know if passing "nvarchar(4), NULL" is a good idea. Does the type of the parameter matter if the value is NULL?

errors that occur while reading resultsets not handled properly

I had an issue where a program got stuck while executing its query, constantly accruing RAM and CPU without moving forward. From the stack trace and code inspection and sybase logs, here's what I think happened. While I was consuming a large resultset, Sybase got killed. As a result fetchResults got stuck busylooping (because it never saw REG_ROW or NO_MORE_ROWS), and errHandler kept appending the same error to conn.Error. Looking at http://www.freetds.org/userguide/samplecode.htm it would appear that the cases BUF_FULL and FAIL should also be handled in fetchResults.

Stack trace:

runtime.memmove(0xc8293ce000, 0xc82d6e0000, 0x43117ba)
        /opt/intelerad/lib/golang/src/runtime/memmove_amd64.s:83 +0x91 fp=0xc824dc8ea0 sp=0xc824dc8e98
runtime.concatstrings(0x0, 0xc824dc9030, 0x2, 0x2, 0x0, 0x0)
        /opt/intelerad/lib/golang/src/runtime/string.go:52 +0x30b fp=0xc824dc8fd8 sp=0xc824dc8ea0
runtime.concatstring2(0x0, 0xc82d6e0000, 0x43117ba, 0xc82509afc0, 0x35, 0x0, 0x0)
        /opt/intelerad/lib/golang/src/runtime/string.go:59 +0x67 fp=0xc824dc9028 sp=0xc824dc8fd8
github.com/minus5/gofreetds.errHandler(0xf046b0, 0x4e4f00000001, 0xc800000000, 0x7ffff7bbcf30, 0x7ffff770bf87, 0xc824dc9188)
        /builddir/build/BUILD/dbms_exporter-5d72ad0436a4f4b4b31a3d952e52cd7a3b7c139f/src/github.com/minus5/gofreetds/callbacks.go:39 +0x6b9 fp=0xc824dc9140 sp=0xc824dc9028
github.com/minus5/gofreetds._cgoexpwrap_7ce7804be3a3_errHandler(0xf046b0, 0x4e4f00000001, 0x0, 0x7ffff7bbcf30, 0x7ffff770bf87, 0x4312000)
        github.com/minus5/gofreetds/_obj/_cgo_gotypes.go:603 +0x4d fp=0xc824dc9178 sp=0xc824dc9140
runtime.call64(0x0, 0x7fffffffe7a8, 0x7fffffffe830, 0x30)
        /opt/intelerad/lib/golang/src/runtime/asm_amd64.s:473 +0x3e fp=0xc824dc91c0 sp=0xc824dc9178
runtime.cgocallbackg1()
        /opt/intelerad/lib/golang/src/runtime/cgocall.go:267 +0x10c fp=0xc824dc91f8 sp=0xc824dc91c0
runtime.cgocallbackg()
        /opt/intelerad/lib/golang/src/runtime/cgocall.go:180 +0xd7 fp=0xc824dc9258 sp=0xc824dc91f8
runtime.cgocallback_gofunc(0x40aaa3, 0x831190, 0xc824dc92d8)
        /opt/intelerad/lib/golang/src/runtime/asm_amd64.s:716 +0x60 fp=0xc824dc9268 sp=0xc824dc9258
runtime.asmcgocall(0x831190, 0xc824dc92d8)
        /opt/intelerad/lib/golang/src/runtime/asm_amd64.s:567 +0x42 fp=0xc824dc9270 sp=0xc824dc9268
runtime.cgocall(0x831190, 0xc824dc92d8, 0x100000000000000)
        /opt/intelerad/lib/golang/src/runtime/cgocall.go:124 +0x133 fp=0xc824dc92a0 sp=0xc824dc9270
github.com/minus5/gofreetds._Cfunc_dbnextrow(0xf046b0, 0x0)
        github.com/minus5/gofreetds/_obj/_cgo_gotypes.go:304 +0x3d fp=0xc824dc92d8 sp=0xc824dc92a0
github.com/minus5/gofreetds.(*Conn).fetchResults(0xc8200dd400, 0x0, 0x0, 0x0, 0x0, 0x0)
        /builddir/build/BUILD/dbms_exporter-5d72ad0436a4f4b4b31a3d952e52cd7a3b7c139f/src/github.com/minus5/gofreetds/fetch.go:72 +0xd45 fp=0xc824dc9528 sp=0xc824dc92d8

Cross compilation failed?

VSCode mac -> windows

➜  Sendsms CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build main.go
# github.com/minus5/gofreetds
../../../../go/pkg/mod/github.com/minus5/[email protected]/conn_pool.go:33:19: undefined: Conn
../../../../go/pkg/mod/github.com/minus5/[email protected]/params_cache.go:8:22: undefined: spParam

Truncated strings from Stored Procedure with varchar(max) output parameters

Is anyone having issues with receiving stored procedure output parameters that are varchar(max) when using gofreetds?
For me they get truncated to 255 characters. However, if my DBA changes the type of the parameter to varchar(4000) (for example), I get up to the full 4000 characters returned.

According to FreeTDS, varchar(max) support should be in TDS protocol version 7.2:
http://www.freetds.org/userguide/choosingtdsprotocol.htm
(gofreetds forces use of TDS 7.2)

Yet I can’t get varchar(max) to work in gofreetds.
We're using SQL Server 2012, FreeTDS 0.95.19 CentOS 7 x86_64

Please can anyone offer any assistance?
Many thanks in advance.

Connection pool is only cleaned once

The connection pool's cleanupTicker channel is only received from once and so cleanup doesn't occur after the initial tick. Looks like a simple issue introduced by #64 — the cleanup select is no longer in an infinite for loop.

I'll try to put up a PR shortly.

How to connect to DB not on default port?

FreeTDS allows setting of TDSVER and TDSPORT environment variables but according to TDSDUMP logs setting these has no effect on gofreetds and there is also no way of changing the port or TDS version in code that I can see.

I want to connect to a SQL Server 2008 R2 (TDSVER 7.2) Database on port 1435 (not 1433)

Is it possible?

Reg: Setup in Windows

Hi,
Can you please help me setup FreeTDS in Windows machine.
I got gcc x64 setup but not sure how to setup Free TDS

I am getting below error
github.com\minus5\gofreetds\conn.go: In function 'err_handler':
github.com\minus5\gofreetds\conn.go:32:22: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
return errHandler((long)dbproc, severity, dberr, oserr, dberrstr, oserrstr);
^
github.com\minus5\gofreetds\conn.go: In function 'msg_handler':
github.com\minus5\gofreetds\conn.go:38:22: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
return msgHandler((long)dbproc, msgno, msgstate, severity, msgtext, srvname, procname, line);
^
github.com\minus5\gofreetds\conn.go: In function 'dbproc_addr':
github.com\minus5\gofreetds\conn.go:59:10: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
return (long) dbproc;

thanks
Vimal

Truncated binary data while scanning image types

Hi, I'm using SQL Server 2017, I have issues while reading image types. Sometimes I get full data, sometimes partial data or no data at all. I have tried denisenkom/go-mssqldb and works fine. I'm using freetds 1.00.38-5.fc28.x86_64 (Fedora 28)

varchar(max) panics on makeslice: len out of range

Hello,

I love this library. But I have a little issue with varchar(max). When I try to execute a statement on a table that has varchar(MAX) defined column, gofreetds crashes with this stacktrace:

panic: runtime error: makeslice: len out of range

goroutine 35 [running]:
github.com/minus5/gofreetds.(*Conn).fetchResults(0xc8200dc0d0, 0x0, 0x0, 0x0, 0x0, 0x0)
        [...]/Godeps/_workspace/src/github.com/minus5/gofreetds/fetch.go:50 +0x6a5
github.com/minus5/gofreetds.(*Conn).exec(0xc8200dc0d0, 0xc82017a000, 0x597, 0x0, 0x0, 0x0, 0x0, 0x0)
        [...]/Godeps/_workspace/src/github.com/minus5/gofreetds/conn.go:276 +0x1be
github.com/minus5/gofreetds.(*Conn).Exec(0xc8200dc0d0, 0xc82017a000, 0x597, 0x0, 0x0, 0x0, 0x0, 0x0)
        [...]/Godeps/_workspace/src/github.com/minus5/gofreetds/conn.go:214 +0x6e
github.com/minus5/gofreetds.(*Conn).ExecuteSql(0xc8200dc0d0, 0xc820168000, 0x2ce, 0xc8200e2200, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, ...)
        [...]/Godeps/_workspace/src/github.com/minus5/gofreetds/executesql.go:30 +0x679
// ...

Which is caused by the last line of this:

// fetch.go line 
            col := &columns[i]
// ...
            col.size = int(size)
// ...
            col.buffer = make([]byte, size+1)

Why is there that "+1" and why we need to preallocate the memory before the data are read from the connection? I don't know how freetds works, but doesn't it know the data size in advance?
I tried to avoid this issue by not using varchar(max), but now I have to use database which I cannot change.

Tested on latest rev. (0594db1), go 1.5.1 darwin/amd64.

Maybe it has something in common with #25 ?

Recovering from SQL Server deadlocks

On occasion I encounter a deadlock error whilst calling a stored procedure on my SQL Server:

Msg 20018, Level 13
General SQL Server error: Check messages from the SQL Server

Msg 20018, Level 16
General SQL Server error: Check messages from the SQL Server

Msg 50000, Level 13, State 51
Server 'MUSTANG', Line 506
    Msg 1205,Line 449: **>> ERROR(UP_IDAlpha_BetaCreate):Transaction (Process ID 69) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction.

Msg 266, Level 16, State 2
Server 'MUSTANG', 
    Transaction count after EXECUTE indicates a mismatching number of BEGIN and COMMIT statements. Previous count = 0, current count = 1.

Following this error all consequent proc calls (to other procs, or this same one) fail with error messages such as:

Msg 20019, Level 7
Attempt to initiate a new Adaptive Server operation with results pending
dbrpcinit failed

As the initial deadlock error is the cause of all consequent failures, is there a way to recover from it?
Maybe we should mark the connection as isDead within conn_sp.go ?
Or is this a non-recoverable situation that would require a complete draining of the connection pool and then reconnecting to the database?

My DBA is working on a proc which will deliberately deadlock so I can develop against it, but if anyone knows how to handle this issue I would be grateful for their advice.

I'm only using stored proc calls, so I don't think using the gofreetds transaction functions (Begin, Rollback) would help me - or would they?

Thanks in advance for any help.

pool.Get() does not return

We encountered a rare situation where a pool.Get() did not return.
This could be because of earlier connections were not released.
That could be because of hung queries.

So, because the pool.Get() did not return (blocked on p.poolGuard <- true , conn_pool.go:103), the operations timed out without errors.

A timeout logic or context is needed so that if getting a connection is hung, some kind of timeout brings the control back.

Assigning Version Numbers?

With Go's Vendor Packaging now approaching maturity do you think there is any value in using Git to assign a Version Number to gofreetds ?

For my work projects I am introducing the use of Glide, which let's me pin a build dependency to a specific Go package version (be it a Git tag, a commit checksum, etc). This let's me generate reproducible builds over different machines and eases CI.

Time for a gofreetds 1.0.0 ? :-)

Alternatively, could gofreetds start using gopkg.in ?

Incorrect SQL Syntax - Unclosed quotation mark after the character string

Hi, everyone.
I encountered a strange problem.When I run the same code on test platform using the same conf, it work well. Once I run the same code on production platform, I got the following error:

General SQL Server error: Check messages from the SQL Server

Msg 170, Level 15
General SQL Server error: Check messages from the SQL Server

Msg 105, Level 15, State 1
Server 'SERVER', Line 24
        Unclosed quotation mark before the character string '<E5><90>?'.

Msg 170, Level 15, State 1
Server 'SERVER', Line 24
        Line 24: Incorrect syntax near '<E5><90>?'.

My code is :

_, err := db.Exec(`
		INSERT INTO Table (
			field1
			, field2
			, field3
			, field4
			, field5
			, field6
			, field7
			, field8
			, field9) 
			VALUES (
				?
				,?
				,?
				,?
				,?
				,?
				,?
				,?
				,?)`, info.TopMarketId, Info.MarketId, Info.GoodsId, Info.GoodsAttribute, Info.TrackDate, Info.Value, Info.TimeCreated, Info.TimeLastUpdated, Info.Type)
	if err != nil {
		log.Println("DB Exec failed: ", err.Error())
		return err
	}

Anyone can help?Thank you very much : )

sudo apt-get install freetds: fails on Ubuntu 14.04

It looks like there is no freetds package in the repository. This is probably happening on other versions of Ubuntu Desktop as well, I'm not sure about Server. Users that run into this can install the freetds-dev package instead to satisfy the dependency.

Executing stored procedure doesn't return data

I have the following code

rst, err := conn.ExecSp("sp_help", "ABS")
if err != nil {
    panic(err)
}


if rst.NextResult() {
    for rst.Next() {
    var v1, v2, v3, v4, v5, v6 string
    rst.Scan(&v1, &v2, &v3, &v4, &v5, &v6)
    fmt.Printf("%s, %s, %s, %s, %s, %s", v1, v2, v3, v4, v5, v6)
    }
}

Running exec sp_help ABS; in the management studio work it returns data, but whenever I do this it never returns data.

Also running sp_fkeys crashes with an error

Msg 8009, Level 16, State 1
Server 'EGL-IRV-ASP07', Line 1
    The incoming tabular data stream (TDS) remote procedure call (RPC) protocol stream is incorrect. Parameter 1 ("@pktable_name"): Data type 0x00 is unknown.

Executing regular SQLs work and data is returned, and all the stored procedure work if executed from the Management Studio.

ftds.NewConnPool does not return, once in a long while

Last few months, two times we have seen in a live system that after some network event, ftds.NewConnPool does not return. I was expecting that if it could not connect, it would return within some time, but somehow it just does not.

I still can not determine the cause of this happening but could at least see from logs this symptom - as this is a prod system.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.