Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Assertion failed: unexpected NULL value #1512

Closed
ahartman opened this issue Mar 18, 2024 · 5 comments
Closed

Assertion failed: unexpected NULL value #1512

ahartman opened this issue Mar 18, 2024 · 5 comments
Labels

Comments

@ahartman
Copy link

Dear Gwendal,

Please find attached my app and the entry in Library/Containers that holds the database.
I commented out everything not necessary for you in the app.
You will see a menu ‘Commands’, bringing you to a button ‘get timeline’; that button will trigger the error in DBModel().getPatientTimeline().

I hope this helps you, let me know if need something else.

Met vriendelijke groeten, Kind regards, Mes meilleures salutations,
André Hartman

Archief.zip

@ahartman
Copy link
Author

ahartman commented Mar 19, 2024

Dear Gwendal,
This morning my app crashes at startup, please find Crash Report attached.
If I take the code and run from Xcode, it will not crash.

This has to do with the same PatientTimeLine function that has the NULL value issues.
Hope this helps.
Regards, André Hartman
Crash Report.txt

@groue
Copy link
Owner

groue commented Mar 20, 2024

🎁 Thank you very much @ahartman,

This sample project and data indeed reveals a bug in GRDB. This bug prevents a normal error to be reported to your app. Next version will fix this.

Until then, I commented out the assertion, and the error is now correctly reported to your app (caught in DBModel.getPatientTimeline()):

could not decode Date from database value NULL
column: "minVisitVisitCreated"
column index: 2
row: [id:2289 patientName:"Aaliyah" minVisitVisitCreated:NULL maxVisitVisitDate:NULL]
sql: SELECT
       "patient"."id", "patient"."patientName",
       MIN("visit"."visitCreated") AS "minVisitVisitCreated",
       MAX("visit"."visitDate") AS "maxVisitVisitDate"
     FROM "patient"
     LEFT JOIN "visit"
       ON ("visit"."patientId" = "patient"."id")
       AND ("visit"."visitCalendar" IN (?, ?)) AND ("visit"."visitCalendar" IN (?, ?))
     GROUP BY "patient"."id"
     ORDER BY "patient"."patientName"
arguments: ["Marieke", "Marieke nieuwe", "Marieke", "Marieke nieuwe"]

So the database contains NULL in the minVisitVisitCreated column. This can happen when MIN("visit"."visitCreated") is NULL (if there is no filtered visit, for example).

This NULL value is decoded into PatientTimelineInfo, which has non-null dates:

struct PatientTimelineInfo: Decodable, FetchableRecord {
    var patient: PatientInfo.Patient
    var minVisitVisitCreated: Date
    var maxVisitVisitDate: Date
}

The fix (in your app) is to modify PatientTimelineInfo so that its dates are optional:

struct PatientTimelineInfo: Decodable, FetchableRecord {
    var patient: PatientInfo.Patient
    var minVisitVisitCreated: Date? // nil when there is no visit
    var maxVisitVisitDate: Date?    // nil when there is no visit
}

I'll take care of the bug in GRDB that prevented the correct error to be reported in the first place. 👍

@ahartman
Copy link
Author

ahartman commented Mar 20, 2024 via email

@groue
Copy link
Owner

groue commented Mar 20, 2024

Oh, yes, thanks for reminding me about this.

So I restored the .having(filteredVisits.isEmpty == false) line.

It runs correctly.

The SQL looks valid, if not ideal (note the repetition of the "visit"."visitCalendar" IN (?, ?) condition, which is superfluous):

SELECT
  "patient"."id", "patient"."patientName",
  MIN("visit"."visitCreated") AS "minVisitVisitCreated",
  MAX("visit"."visitDate") AS "maxVisitVisitDate"
FROM "patient"
LEFT JOIN "visit"
  ON ("visit"."patientId" = "patient"."id")
  AND ("visit"."visitCalendar" IN (?, ?))
  AND ("visit"."visitCalendar" IN (?, ?))
  AND ("visit"."visitCalendar" IN (?, ?))
GROUP BY "patient"."id"
HAVING COUNT(DISTINCT "visit"."rowid") > 0
ORDER BY "patient"."patientName"

Would you please remind me what prevents you from restoring the having clause? Now that I have a running app, it's easier to reproduce!

@ahartman
Copy link
Author

ahartman commented Mar 21, 2024 via email

groue added a commit that referenced this issue Mar 21, 2024
@groue groue closed this as completed in ac8c4ae Mar 23, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants