Search code examples
erlangmnesia

Mnesia Errors case_clause in QLC query without a case clause


I have the following function for a hacky project:

% The Record variable is some known record with an associated table.
Query = qlc:q([Existing ||
  Existing <- mnesia:table(Table),
  ExistingFields = record_to_fields(Existing),
  RecordFields = record_to_fields(Record),
  ExistingFields == RecordFields
]).

The function record_to_fields/1 simply drops the record name and ID from the tuple so that I can compare the fields themselves. If anyone wants context, it's because I pre-generate a unique ID for a record before attempting to insert it into Mnesia, and I want to make sure that a record with identical fields (but different ID) does not exist.

This results in the following (redacted for clarity) stack trace:

{aborted, {{case_clause, {stuff}},
      [{db, '-my_func/2-fun-1-',8, ...

Which points to the line where I declare Query, however there is no case clause in sight. What is causing this error?

(Will answer myself, but I appreciate a comment that could explain how I could achieve what I want)

EDIT: this wouldn't be necessary if I could simply mark certain fields as unique, and Mnesia had a dedicated insert/1 or create/1 function.


Solution

  • For your example, I think your solution is clearer anyway (although it seems you can pull the record_to_fields(Record) portion outside the comprehension so it isn't getting calculated over and over.)

    Yes, list comprehensions can only have generators and assignments. But you can cheat a little by writing an assignment as a one-element generator. For instance, you can re-write your expression as this:

    RecordFields = record_to_fields(Record),
    Query = qlc:q([Existing ||
      Existing <- mnesia:table(Table),
      ExistingFields <- [record_to_fields(Existing)],
      ExistingFields == RecordFields
    ]).