go-pg / pg

Golang ORM with focus on PostgreSQL features and performance
https://pg.uptrace.dev/
BSD 2-Clause "Simplified" License
5.67k stars 404 forks source link

Only one of the Columns that have the same name parsed in map[string]interface{} #1959

Open trietphm opened 2 years ago

trietphm commented 2 years ago

When querying an SQL query and parsing the result data into a map[string]interface{}, the columns that have the same name are missing in the query result, only one of them is available.

Steps to Reproduce

Example code:

    db := pg.Connect(&pg.Options{
        User:     "postgres",
        Database: "postgres",
    })

    var data []map[string]interface{}
    _, err := db.Query(&data, "SELECT * FROM a JOIN b ON a.id = b.id")
    if err != nil {
        panic(err)
    }

    fmt.Printf("%+v\n", data)

The database schema and example data

postgres=# \d a
                 Table "public.a"
 Column |  Type   | Collation | Nullable | Default
--------+---------+-----------+----------+---------
 id     | integer |           |          |
 name   | text    |           |          |

postgres=# \d b
                 Table "public.b"
 Column |  Type   | Collation | Nullable | Default
--------+---------+-----------+----------+---------
 id     | integer |           |          |
 name   | text    |           |          |
 code   | integer |           |          |

postgres=# select * from a;
 id | name
----+------
  1 | ax
  2 | ay
(2 rows)

postgres=# select * from b;
 id | name | code
----+------+------
  1 | bx   |   99
  2 | by   |  100
(2 rows)

Query result

postgres=# SELECT * FROM a JOIN b ON a.id = b.id;
 id | name | id | name | code
----+------+----+------+------
  1 | ax   |  1 | bx   |   99
  2 | ay   |  2 | by   |  100
(2 rows)

Expected Behavior

The map should contain all the columns which have the same name

[map[code:99 id:1 name:bx id:1 name:ax] map[code:100 id:2 name:by id:2 name:ay]]

Current Behavior

I think due to the map[column_name], only one of columns is available in the query result

[map[code:99 id:1 name:bx] map[code:100 id:2 name:by]]

Possible Solution

Not really efficient, but I think we should add a postfix to the column name to distinguish between the columns. For example

SQL result

 id | name | id1 | name1 | code
----+------+----+------+------
  1 | ax   |  1 | bx   |   99
  2 | ay   |  2 | by   |  100

parsed map

[map[code:99 id:1 name:bx id1:1 name1:ax] map[code:100 id:2 name:by id1:2 name1:ay]]

Context (Environment)

Just want to run a raw SQL query and expect no missing data

Detailed Description

Possible Implementation

trietphm commented 2 years ago

Columns ambiguous is also a problem with https://github.com/jmoiron/sqlx#issues and they recommend to scan the rows instead. I guess pg would also suggest the same thing.