Reputation: 5246
In my Golang (1.15) application I use sqlx package to work with the PostgreSQL database (PostgreSQL 12.5).
My SQL request has an array_agg
function that returns the array of strings or null if it's empty.
I am trying to Scan
the results of this SQL request but it raises the next error in my program:
sql: Scan error on column index 3, name "organization_ids": unsupported Scan, storing driver.Value type string into type *[]string
Code snippet:
type Channel struct {
ChannelId *string `db:"channel_id" json:"channelId"`
ChannelName *string `db:"channel_name" json:"channelName"`
OrganizationsIds *[]string `db:"organizations_ids" json:"organizationsIds"`
}
var channel Channel
row := db.QueryRow(`
select
channels.channel_id::text,
channels.channel_name::text,
array_agg(distinct channels_organizations_relationship.organization_id)::text[] organizations_ids
from
channels
left join channels_organizations_relationship on
channels.channel_id = channels_organizations_relationship.channel_id
where
channels.channel_id = $1
group by
channels.channel_id
limit 1;`, *channelId)
if err := row.Scan(&channel.ChannelId, &channel.ChannelName, &channel.OrganizationsIds); err != nil {
fmt.Println(err)
}
return &channel
I also tried to change the data type of the OrganizationsIds
field in the Channel
struct to *pg.StringArray
from the github.com/lib/pq package. In this case, when I Scan
, I get the following error in my program:
sql: Scan error on column index 3, name "organizations_ids": unsupported Scan, storing driver.Value type string into type *[]pq.StringArray
My task is to return a list of strings or null/nil to the client for this column.
Can someone explain how to fix this strange behavior?
Upvotes: 6
Views: 4457
Reputation: 1016
Another way to solve this:
Create a slice:
var userIds []string{}
Use array_remove
and to_json
functions along with array_agg
, like this:
TO_JSON(ARRAY_REMOVE(ARRAY_AGG(table."column"), NULL)) AS "userIds"
Simply scan results into slice, like this :
err := rows.Scan(&userIds)
Upvotes: 1
Reputation: 5246
Well, finally I found the solution of my problem.
I noticed that the array_agg
function returns the [null]
. I changed the SQL request a little bit to return the null
instead of [null]
. I make it with this changes:
array_agg(distinct channels_organizations_relationship.organization_id) filter (where channels_organizations_relationship.organization_id is not null)
In this article (Postgres returns [null] instead of [] for array_agg of join table ), you can find many different solutions to this problem.
Then you can use one of this solutions:
The 1 option
We can use OrganizationsIds pq.StringArray
in the struct, and then when scanning do this row.Scan(..., &channel.OrganizationIds
.
The 2 option
We can use OrganizationsIds []string
in the struct, and then when scanning do this row.Scan(..., (*pq.StringArray)(&channel.OrganizationIds))
.
Upvotes: 1