Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error while doing a MapScan or SliceScan time.Time with PostgreSQL #59

Closed
frankbb opened this issue May 1, 2014 · 7 comments
Closed

Comments

@frankbb
Copy link

frankbb commented May 1, 2014

Not really sure if it's a sqlx issue. When i use a MapScan or a SliceScan in combination with a Postgresql timestamp field it will result in a scan error, or did i miss something?

rows, err := db.NamedQuery(query, where)
[...] -> err
for rows.Next() {
        results := make(map[string]interface{})
        err = rows.MapScan(results)
        [...] -> err

        fmt.Println(fmt.Sprintf("%v", results)))
}

Error:

sql: Scan error on column index 3: unsupported driver -> Scan pair: time.Time -> *string

Database Postgresql column:

\d users
  Column  |            Type             |                     Modifiers
----------+-----------------------------+----------------------------------------------------
 id       | integer                     | not null default nextval('users_id_seq'::regclass)
 added    | timestamp without time zone | not null default now()
@freeeve
Copy link

freeeve commented May 1, 2014

MapScan tries to scan everything out as a string. You should really be using a time.Time datatype to pull out timestamps--but if you want to do this with MapScan, you can convert to a string in the query with to_char or something.

@jmoiron
Copy link
Owner

jmoiron commented May 1, 2014

Yes, this is a bug. The way lib/pq supports time natively, sql.RawBytes/[]byte/string/NullString aren't a safe destination for it. I have to change this code to use *interface{} instead, but that will probably be a breaking change. The way I did it wasn't good though; I learned this when writing the Unsafe() methods.

edit:

The map[string]*string interface is a lot more convenient than map[string]interface{} for most cases where MapScan is actually a good API, because you won't have a good idea of what the types are and a string representation is probably good enough. Still it's probably good enough to let fmt.Sprint do that work for you.

@frankbb
Copy link
Author

frankbb commented May 2, 2014

Do you have a suggestion for a workaround? Maybe you can also add this to the documentation for now.

In case of a SELECT * FROM A you don't know what type you are selecting so as far as i know there is no place for a to_char.

@jmoiron
Copy link
Owner

jmoiron commented May 2, 2014

@frankbb Fixing this is ironically a breaking change. I will create a branch for you to use which fixes this while I gather a bunch of planned breaking changes together for a single release + announcement.

Even though the current behavior is convenient, I think it is wrong. It's also unnecessarily opinionated to coerce everything to string or nil in the first place; if that's what someone desires, they could surely just fmt.Sprint the results for themselves.

@jmoiron
Copy link
Owner

jmoiron commented May 2, 2014

@frankbb
Copy link
Author

frankbb commented May 6, 2014

Great, thanks i will try that branch, if i run into bugs i will let you know.

@jmoiron
Copy link
Owner

jmoiron commented Jun 7, 2014

This has been integrated into master now, along with many other fixes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants