yesodweb / yesodweb/persistent

Marshal error on list of pairs

Open
#1,548 0 comments 3 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Haskell
Stars
486
Forks
306
PR merge metrics
No merged PRs in 30d

Description

Using

stack 2.15.3 x86_64 hpack-0.36.0
GHC 9.4.8
psql (PostgreSQL) 15.6

With a model like

data PersonT = Adults | Students

Booking

PersonType
  type PersonT

BookingPerson
  booking BookingId
  personType PersonTypeId

if I perform an equeleto query like

qFoo :: DB [(Entity Booking, Value [(PersonT, Int)])]
qFoo = do
  select $ do
    booking :& bookingPerson :& personType <-
      from $
        table @Booking
          `leftJoin` table @BookingPerson
            `on` (\(booking :& bookingPerson) -> just booking.id ==. bookingPerson.booking)
          `leftJoin` table @PersonType
            `on` (\(_ :& bookingPerson :& personType) -> bookingPerson.personType ==. personType.id)
    groupBy booking.id
    pure
      ( booking
      , arrayRemoveNull $ arrayAgg (pair (personType ?. #type) bookingPerson.amount)
      )

where pair is an helper function to pass tuples to postgresql defined as

pair :: SqlExpr (Value a) -> SqlExpr (Value b) -> SqlExpr (Value (a, b))
pair (ERaw _ f1) (ERaw _ f2) = ERaw noMeta f
 where
  f p info =
    let (b1, vals1) = f1 Parens info
        (b2, vals2) = f2 Parens info
     in ( parensM p ("(" <> b1 <> ", " <> b2 <> ")")
        , vals1 <> vals2
        )

then the following query is correctly run

SELECT "booking"."id", array_remove(array_agg(("person_type"."type", "booking_person"."amount")), NULL)
FROM "booking"
LEFT OUTER JOIN "booking_person" ON "booking"."id" = "booking_person"."booking"
LEFT OUTER JOIN "person_type" ON  "booking_person"."person_type" = "person_type"."id"
GROUP BY "booking"."id"

but I get the following error

PersistMarshalError "Failed to parse Haskell type `List`; expected list, string, bytestring or null from database, but received: PersistLiteral_ Escaped \"{\\\"(Adults,2)\\\",\\\"(Children,7)\\\"}\". Potential solution: Check that your database schema matches your Persistent model definitions."

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with PersistMarshalError and reproduce the supplied qFoo query using the Booking, BookingPerson, and PersonType definitions. Compare the PostgreSQL array of composite pairs with the expected Haskell [(PersonT, Int)] result. Done means the query decodes successfully without the reported marshal error.

Written by the indexing model from the issue text.

Assessment

Tech stack
haskell, postgresql
Domain
databases
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.