nakagami / firebirdsql

Firebird RDBMS sql driver for Go (golang)
MIT License
224 stars 60 forks source link

Select INT128 always returns 0 Firebird 4.0 #129

Closed xhit closed 3 years ago

xhit commented 3 years ago

Example code:

package main

import (
    "database/sql"
    "fmt"
    "net/url"

    _ "github.com/nakagami/firebirdsql"
)

func main() {

    //connecto to Firebird
    db, err := connectFirebird("localhost", "firebird/data/testdb", "usr", "password", 3052)
    if err != nil {
        panic(err)
    }

    defer db.Close()

    issue129(db)

}

func issue129(db *sql.DB) {

    tableName := "ISSUE129"

    queryDrop := `drop table "` + tableName + `";`

    db.Exec(queryDrop)

    queryCreate := `CREATE TABLE ` + tableName + ` ("a" INT128);`

    _, err := db.Exec(queryCreate)
    if err != nil {
        panic(err)
    }

    defer db.Exec(queryDrop)

    queryInsert := "insert into " + tableName + " (\"a\") values (?)"

    _, err = db.Exec(queryInsert, 129)
    if err != nil {
        panic(err)
    }

    var t int

    if err := db.QueryRow(`SELECT "a" FROM ` + tableName).Scan(&t); err != nil {
        panic(err)
    }

    fmt.Println(t)
}

//connectFirebird : Conectar a la base de datos Firebird
func connectFirebird(host, database, username, password string, port int) (*sql.DB, error) {

    // default port
    if port == 0 {
        port = 3050
    }

    //Password in firebird dsn not accept spaces, so escape with url.QueryEscape

    // in form user:pass@host:port/database
    dsn := fmt.Sprintf("%s:%s@%s:%d/%s", username, url.QueryEscape(password), host, port, database)

    db, err := sql.Open("firebirdsql", dsn)

    if err != nil {
        return nil, err
    }

    err = db.Ping()

    if err != nil {
        return nil, err
    }

    return db, nil
}
nakagami commented 3 years ago

thanks! I could probably fix it.

I've added a simple test, but I'm not sure if it's good enough yet. I'll see how it goes for a while longer.

xhit commented 3 years ago

Well, your implementation returns incorrect value for really big numbers like 99999999999999999999999999 and the max int128 170141183460469231731687303715884105727

Maybe I can fix that.

nakagami commented 3 years ago

I think it's OK to get each 8 bytes at a time and add them up, but the result is definitely wrong. Thanks, I'll merge the pull request.

If there's a better way, I'll fix it later.