Code Monkey home page Code Monkey logo

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

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.

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.

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

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.

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)

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.

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

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.

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?

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.

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?

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".

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.

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?

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!

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 ?

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.

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 ?

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?

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.

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? :(

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.

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.

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.

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

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

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() {

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 : )

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.

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?

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.

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

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.

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.

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.