mnesia qlc error

Hans Bolinder hasse@REDACTED
Fri Dec 23 13:19:15 CET 2005


> Using erl R10B-8 (5.4.10), I have a table defined by:
> 
>     mnesia:create_table(target,
>                         [{attributes, record_info(fields, target)},
>                          {disc_copies, [node()]},
> 			 {type, set}])
> where target is:
> 
> -record(target, {id,		% string
>             	name,		% string
> 		actions}).	% List if action id
> 
> I have a function:
> 
> targetMgr:findTarget/1:
> 
> findTarget(TargetName) ->
> 	F = fun() ->
>                 Q = qlc:q([Target || Target <- mnesia:table(target),
>                                               Target#target.name == TargetName]),
>                 qlc:e(Q)
>         end,
>     mnesia:transaction(F).
> 
> In an erlang shell, a call of targetMgr:findTarget("hello") yields an error:
> 
> 17> targetMgr:findTarget("hello").
> {aborted,{function_clause,[{targetMgr,'-findTarget/1-lc$^0/1-0-',
1>                                       [{qlc_handle,
>                                            {qlc_table,
>                                                #Fun<mnesia.16.73285684>,
>                                                true,
>                                                #Fun<mnesia.17.24889472>,
>                                                #Fun<mnesia.18.119385189>,
>                                                #Fun<mnesia.19.123232999>,
>                                                #Fun<mnesia.22.105141785>,
>                                                #Fun<mnesia.21.51189828>,
>                                                #Fun<mnesia.20.62027733>,
>                                                undefined,
>                                                undefined,
>                                                no_match_spec}},
>                                        "hello"]},
>                            {targetMgr,'-findTarget/1-fun-0-',1},
>                            {mnesia_tm,apply_fun,3},
>                            {mnesia_tm,execute_transaction,5},
>                            {erl_eval,do_apply,5},
>                            {shell,exprs,6},
>                            {shell,eval_loop,3}]}}

You should add the line

  -include_lib("stdlib/include/qlc.hrl").

to the source file.

> If I rewrite this call as:
> 
> findTarget(TargetName) ->
>      Target = #target{name = TargetName, _ = '_'},
>      F = fun() -> mnesia:match_object(Target) end,
>      mnesia:transaction(F).
> 
> It works...

A side note: this is not exactly the same as the QLC query since
mnesia:match_object uses matching (=:=/2) rather than comparison
(==/2).

Assuming that 'name' is not the key and that there is no index on
'name' it is OK to use ==/2 in this case since the whole table is
traversed anyway. But otherwise =:=/2 is to be preferred since it
makes it possible for QLC to look up the value (possibly using an
index).

Note however that =:=/2 cannot be used if either operand could be a
floating point number F such that round(F) == F since matching with
the integer round(F) would fail.

Best regards

Hans Bolinder, Erlang/OTP



More information about the erlang-questions mailing list