0

I am trying to perform a mnesia table transform for purposes of a schema upgrade. In my new schema, I have deleted one field from my previous definition of the record. The rest of the schema remains unchanged. Here is some code-

XformFun = fun(OldRecord) ->
    NewRecord = #bdm_employee{id=element(2, OldRecord), name=element(3, OldRecord),
                                address=element(4, OldRecord),
                                job_type=element(6, OldRecord),
                                ...
                                description=element(34, OldRecord)},
    NewRecord
end,
mnesia:transform_table(bdm_employee, XformFun, record_info(fields, bdm_employee))

My original record had 34 fields. After removing the 5th field, dialyzer complains about trying to access an index outside the record's range for element #34. However, I find this strange since the 'mnesia:transform_table' could be performed on any record, size of which could be 34, 33 or anything else. Why should the dialyzer complain? Appreciate some guidance for fixing this...

Dialyzer error-

dialyzer: Analysis failed with error:
{function_clause,[{lists,nth,2,[]},
                  {dialyzer_typesig,find_element,2,[]},
                  {dialyzer_typesig,get_bif_constr,4,[]},
                  {dialyzer_typesig,handle_call,3,[]},
                  {dialyzer_typesig,traverse,3,[]},
                  {dialyzer_typesig,handle_clauses_1,7,...},
                  {dialyzer_typesig,handle_clauses,...},
                  {dialyzer_typesig,...}]}
Yashesh
  • 91
  • 8
  • 1
    Do you have a `-spec` for your transform? I'm guessing that dialyzer is confused about the type of OldRecord. – Nathaniel Waisbrot Jan 07 '15 at 01:02
  • I dont have a spec for the transform but I found a couple of statements at the beginning of the transform that were treating the OldRecord as record type bdm_employee. That throws dialyzer off when you try to access the extra element. – Yashesh Jan 08 '15 at 05:28

1 Answers1

0

(Copying from comments)

The error from Dialyzer is from it trying to get the type of the 34th element when there aren't 34 elements in the record. This, in turn, is because Dialyzer has gotten the wrong type for OldRecord.

Finding exactly where the type got inferred to something you didn't expect can be tricky. The simplest (though still not easy) solution is to annotate types in more places. For example, if you factored fun (OldRecord) out and gave it a -spec, Dialyzer would give you a more helpful error message.

Nathaniel Waisbrot
  • 23,261
  • 7
  • 71
  • 99