will/crystal-pg

Support for Array of hash as a result type

rishavs opened this issue · 2 comments

Hi guys

I have a query which uses the json_object_agg function and returns an array of hashes. Howeveer, on Crystal side, I am not able to map it with any data structure.
My query and mapping which I need are;

post= DB.query_one? "SELECT posts.unqid, posts.title, posts.content, posts.user_id, 
                      json_object_agg(tags.name, tags.voted) as tagsdata,
                      json_object_agg(comments.unqid, comments.content) as commentsdata
                    FROM posts
                    LEFT JOIN tags
                        ON posts.unqid = tags.post_id
                    LEFT JOIN comments
                        ON posts.unqid = comments.post_id
                    WHERE posts.unqid = '#{post_id}'
                    GROUP BY posts.unqid, posts.title, posts.content, posts.user_id", 
                    as: {unqid: String, title: String, content: String, user_id: String,
                        tagsdata: Array({name: String, voted: String}), 
                        commentsdata: Array({unqid: String, content: String})}

currently if I try to run this, I get;

in lib/pg/src/pg/decoders/array_decoder.cr:66: no overload matches 'PG::Decoders.decode_array_element' with types IO+, NamedTuple(name: String, voted: String).class, Array(NamedTuple(dim: Int32, lbound: Int32))
Overloads are:
 - PG::Decoders.decode_array_element(io, t : Array(T).class, dim_info)
 - PG::Decoders.decode_array_element(io, t : Bool.class, dim_info)
 - PG::Decoders.decode_array_element(io, t : Bool | ::Nil.class, dim_info)
 - PG::Decoders.decode_array_element(io, t : Char.class, dim_info)
 - PG::Decoders.decode_array_element(io, t : Char | ::Nil.class, dim_info)
 - PG::Decoders.decode_array_element(io, t : Int16.class, dim_info)
 - PG::Decoders.decode_array_element(io, t : Int16 | ::Nil.class, dim_info)
 - PG::Decoders.decode_array_element(io, t : Int32.class, dim_info)
 - PG::Decoders.decode_array_element(io, t : Int32 | ::Nil.class, dim_info)
 - PG::Decoders.decode_array_element(io, t : String.class, dim_info)
 - PG::Decoders.decode_array_element(io, t : String | ::Nil.class, dim_info)
 - PG::Decoders.decode_array_element(io, t : Int64.class, dim_info)
 - PG::Decoders.decode_array_element(io, t : Int64 | ::Nil.class, dim_info)
 - PG::Decoders.decode_array_element(io, t : Float32.class, dim_info)
 - PG::Decoders.decode_array_element(io, t : Float32 | ::Nil.class, dim_info)
 - PG::Decoders.decode_array_element(io, t : Float64.class, dim_info)
 - PG::Decoders.decode_array_element(io, t : Float64 | ::Nil.class, dim_info)

      Array(T).new(size) { decode_array_element(io, T, rest) }
RX14 commented

@rishavs json_object_agg returns json, so you need to map it as JSON.

woops. forgot that i had raised this issue. Mapping to JSON::Any fixed my problem.