Database/sql pg postgres driver problem

2,388 views
Skip to first unread message

Nigel Vickers

unread,
Apr 18, 2013, 5:51:52 AM4/18/13
to golan...@googlegroups.com
This programm worked last time it was tested (aprox 5 weeks ago )

package main
import (
        "database/sql"
        "fmt"
        "time"
        )
const connectString string =  "user=postgres password=changed dbname=Rhedile sslmode=disable host=localhost"
var debug bool = true
var resultSet = make(map[string]*result)
type result struct {
        fnr  int
        fname string
}
func main() {
        rhediledb, err := sql.Open("postgres", connectString )
        if err != nil {
        //panic (err)
        if debug {fmt.Println("sql.Open failed", err)}
        }
        if debug {fmt.Println("sql.Open returns no err", rhediledb)}
        defer rhediledb.Close()
        rows, qerr := rhediledb.Query("SELECT 'fnr','fname' FROM firmen limit 10")
        //time.Sleep(10 * 1e9)
        if qerr !=  nil {
        if debug {fmt.Println("dbQuery failed", qerr)}
        }
        if debug {fmt.Println("select returned rows", rows)}

        time.Sleep(10 * 1e9)

}

It returns this: 

nigel@fossil:~/go$ go run testpsql.go 
sql.Open returns no err &{0x18700218 user=postgres password=changed dbname=Rhedile sslmode=disable host=localhost {0 0} [] false}
select returned rows &{0x1872f150 0x18744410 0x18730c00 0x187004d0 false [] <nil> 0x1872ec80}
nigel@fossil:~/go$ 

This is incorrect, it should produce 10 rows or an error... it does neither. 

The database records this:

2013-04-18 11:36:25 CEST LOG:  connection received: host=127.0.0.1 port=60805
2013-04-18 11:36:25 CEST LOG:  connection authorized: user=postgres database=Rhedile
2013-04-18 11:36:35 CEST LOG:  unexpected EOF on client connection
2013-04-18 11:36:35 CEST LOG:  disconnection: session time: 0:00:10.003 user=postgres database=Rhedile host=127.0.0.1 port=60805

Something is generating a io.EOF

It doesn't appear to be an elapsed time problem or a connection timeout.  

ubuntu 12.04 , go from apt-get reports v1, postgres 9.1.9

Any pointers in the right direction, be they subtle or savage would be gratefully received,

Nigel Vickers

Daniel Farina

unread,
Apr 18, 2013, 5:02:02 PM4/18/13
to Nigel Vickers, golang-nuts
Interesting. You should probably submit this to
http://github.com/lib/pq (the new location of the same driver). The
odds of me seeing a pq problem from skimming golang-nuts and acting on
it are not that high.

Seems like something that would be found well via git bisect; not much
has happened in the last couple of months of pq that I know of.

Carlos Castillo

unread,
Apr 18, 2013, 7:58:40 PM4/18/13
to golan...@googlegroups.com
database/sql was updated at tip to not actually close the connection until all *sql.Stmt, and *sql.Rows are closed. The EOF happens because your program ends (socket disconnects) before closing the connection because the *sql.Rows was not closed.

Also, your query seems to be returning constant strings, not the contents of the table.

Carlos Castillo

unread,
Apr 18, 2013, 8:06:43 PM4/18/13
to golan...@googlegroups.com
Also, you call neither rows.Next() nor rows.Scan() at all in the code, so I don't see why you should be expecting row data when you never asked for any. The only thing you do the rows object in the provided code is to print it in a debug statement. So the code appears to be working as expected, but not necessarily as you intended.

Dougx

unread,
Apr 18, 2013, 10:37:37 PM4/18/13
to golan...@googlegroups.com
There isn't any way to 'flush' the sql connection without either 1) closing the database connection, or 2) closing the rows returned (and in some implementations, calling Scan() too; but I believe that's broken drivers), which is why you're seeing this behavior.

~
Doug.

Nigel Vickers

unread,
Apr 19, 2013, 9:16:17 AM4/19/13
to golan...@googlegroups.com, Nigel Vickers
Daniel,
Thank you for your information. I changed the driver but the behaviour is unchanged. I will do as you advise and post this to /lib/pg . At the moment it appears that sql.go is returning no error when one exists .

Nigel Vickers

unread,
Apr 19, 2013, 9:32:12 AM4/19/13
to golan...@googlegroups.com
Hallo Carlos,
Thank you for taking the time to reply


On Friday, 19 April 2013 01:58:40 UTC+2, Carlos Castillo wrote:
database/sql was updated at tip to not actually close the connection until all *sql.Stmt, and *sql.Rows are closed. The EOF happens because your program ends (socket disconnects) before closing the connection because the *sql.Rows was not closed.

I am not using tip and I don't think this is the case. Tcpdump says the Query is being correctly passed to the Database and the Database replies but the socket is closed. The  Database say unexpectedly. Something  should return a connection error.
 
Also, your query seems to be returning constant strings, not the contents of the table.
 
 a rows.Columns is returning   "columns [?column? ?column?] <nil>". This is the correct interface but its empty.

Nigel Vickers

Nigel Vickers

unread,
Apr 19, 2013, 10:03:16 AM4/19/13
to golan...@googlegroups.com
Hallo Doug,


On Friday, 19 April 2013 04:37:37 UTC+2, Dougx wrote:
There isn't any way to 'flush' the sql connection without either 1) closing the database connection, or 2) closing the rows returned (and in some implementations, calling Scan() too; but I believe that's broken drivers), which is why you're seeing this behavior.


I have the feeling  I am dealing with "catch 22" . The Query is returning an empty result when it should report an error . The driver is not reporting an error because its being told to close the socket. The database is doing what it should but has nobody to talk to. I can't identify which of the 10 calls sql.Query makes to Prepare() / prepare() that is returning success when it should fail. I have to admit I am probably out of my depth but "something ain't right"

NIgel Vickers

Nigel Vickers

unread,
Apr 20, 2013, 1:29:55 PM4/20/13
to golan...@googlegroups.com
Thanks everybody for the pointers.
I have identified the  problem, 

rows, qerr := rhediledb.Query("SELECT 'fnr','fname' FROM firmen limit 10")

is not accepted by the scanner  but does not return an error only an empty *rows

rows, qerr := rhediledb.Query("SELECT fnr , fname  FROM firmen limit 10")

is correct and functions as expected

I do think it would be helpful if the scanner rejects the "SELECT" syntax that an error is raised.

regards,
Nigel Vickers

Carlos Castillo

unread,
Apr 20, 2013, 4:26:54 PM4/20/13
to Nigel Vickers, golang-nuts
As I mentioned earlier your query just returns the strings 'fnr', and 'fname' for each result row, it is valid syntax, however. I thought it was just a typo, considering most of your example did nothing useful anyway as it looked like extracted code from a larger example.

You could use this feature it as follows:

SELECT 'Manager' AS title, name, dept FROM employees WHERE level > 4
UNION
SELECT 'Grunt' AS title, name, dept FROM employees WHERE level <= 4;

This will produce a result set where the first column is named title, and is either the string 'Manager', or the string 'Grunt', without needing a join on another table, or application logic to do the mapping. It's not terribly useful, but perfectly valid syntax. SQL lets you use a constant, or an expression in lieu of a table column (you don't even need a table). eg, in databases that have an md5 function:

SELECT md5('apples'); => daeccf0ad3c1fc8c8015205c332f5b42

There's nothing the error detection code can do for valid code.


--
You received this message because you are subscribed to a topic in the Google Groups "golang-nuts" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/golang-nuts/z9y8CBxfvSc/unsubscribe?hl=en-US.
To unsubscribe from this group and all its topics, send an email to golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 



--
Carlos Castillo
Reply all
Reply to author
Forward
0 new messages