2

I am using Go with the pgx library to query from a Postgres database with the PostGIS plugin but I am not able to determine the type of Point from PostGIS, or better said, into what type does it fit in Golang.

Code:

    rows, err := db.conn.Query(context.Background(), "select * from point")
    if err != nil {
        return err
    }
    defer rows.Close()

    for rows.Next() {
        var uuid string
        var coordinate []float32
        err = rows.Scan(&uuid, &coordinate)
        if err != nil {
            log.Println(uuid)
            log.Println(coordinate)
        }
    }

    return rows.Err()

As expected, I am getting the following error:

can't scan into dest[1]: cannot assign &{{2 2} 2} to *[]float32

The error occurs because coordinate is a PostGIS Point, not an array of float32. What kind of type can it be attributed to in Go?

dclipca
  • 1,739
  • 1
  • 16
  • 51
  • I don't know for sure, but I don't see GIS support listed anywhere on pgx (nor pq or go-pg), so it may not be usable with `Scan`. I hope someone here has an answer for you but you might also try reaching out to the author or filing an issue on their GitHub. – Adrian Aug 13 '20 at 18:51
  • Or try custom types, as mentioned in their docs (with the example being a Point): https://github.com/jackc/pgx/blob/master/example_custom_type_test.go. Or try this: https://github.com/cridenour/go-postgis, first Google search result. It helps to do some research before posting a question. – Marc Aug 13 '20 at 18:53
  • Print out the full type and structure and see what it is. It may be defined somewhere already. – JimB Aug 13 '20 at 18:54
  • I am using Go for two days so I do no know it very much. What data type is &{{2 2} 2}? – dclipca Aug 13 '20 at 19:18
  • I have used both postgis.Point type from cridenour/go-postgis and the Point from pgx docs but it doesn't work. In the case of the type from the documentation, it says "can't scan into dest[1]: cannot assign &{{2 2} 2} to *main.Point" – dclipca Aug 13 '20 at 19:19
  • We can't tell what data type `&{{2 2} 2}` is, which is why you need to take that value and print it out yourself. The format verb `%#v` will print as much of the structure as possible (provided it doesn't implement `GoStringer`, in which case you could at least get the type with `%T`) – JimB Aug 13 '20 at 19:25
  • I thought {{2 2} 2} is the value. My first coordinate in the database is Point(2, 2). How can I print it out? The error occurs when I assign that value to my coordinate variable and it seems I cannot do anything with it before I assign it. – dclipca Aug 13 '20 at 19:28
  • I changed my Point to (1, 1) and now I get {{1 1} 2}. – dclipca Aug 13 '20 at 19:32
  • My guess is that you probably have to scan the point into a [`*pgtype.Point`](https://godoc.org/github.com/jackc/pgtype#Point) instance. Or if you want to scan it into `[]float32`, or even `[2]float32`, you have to declare named versions of those types and have them implement the `sql.Scanner` interface, or, instead of declaring named versions declare a wrapper type that implements the interface. – mkopriva Aug 13 '20 at 19:52
  • ... in case you're interested to write something to scan directly into the slice, you could do something like this: https://play.golang.org/p/cEkmtA2iRM0 – mkopriva Aug 13 '20 at 20:14
  • mkoprikova, thank you for you help. Your type is working! – dclipca Aug 14 '20 at 12:41

0 Answers0