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