@@ -38,7 +38,7 @@ normalize(Selector) ->
3838 ],
3939 {NProps } = lists :foldl (fun (Step , Sel ) -> Step (Sel ) end , Selector , Steps ),
4040 FieldNames = [Name || {Name , _ } <- NProps ],
41- case lists :member (<<>> , FieldNames ) of
41+ case lists :member ([] , FieldNames ) of
4242 true ->
4343 ? MANGO_ERROR ({invalid_selector , missing_field_name });
4444 false ->
@@ -210,7 +210,7 @@ norm_ops(Value) ->
210210norm_fields ({[]}) ->
211211 {[]};
212212norm_fields (Selector ) ->
213- norm_fields (Selector , <<>> ).
213+ norm_fields (Selector , [] ).
214214
215215% Operators where we can push the field names further
216216% down the operator tree
@@ -237,7 +237,7 @@ norm_fields({[{<<"$keyMapMatch">>, Arg}]}, Path) ->
237237% $default field. This also asserts that the $default
238238% field is at the root as well as that it only has
239239% a $text operator applied.
240- norm_fields ({[{<<" $default" >>, {[{<<" $text" >>, _Arg }]}}]} = Sel , <<>> ) ->
240+ norm_fields ({[{<<" $default" >>, {[{<<" $text" >>, _Arg }]}}]} = Sel , [] ) ->
241241 Sel ;
242242norm_fields ({[{<<" $default" >>, _ }]} = Selector , _ ) ->
243243 ? MANGO_ERROR ({bad_field , Selector });
@@ -249,12 +249,11 @@ norm_fields({[{<<"$", _/binary>>, _}]} = Cond, Path) ->
249249% We've found a field name. Append it to the path
250250% and skip this node as we unroll the stack as
251251% the full path will be further down the branch.
252- norm_fields ({[{Field , Cond }]}, <<>>) ->
253- % Don't include the '.' for the first element of
254- % the path.
255- norm_fields (Cond , Field );
256- norm_fields ({[{Field , Cond }]}, Path ) ->
257- norm_fields (Cond , <<Path /binary , " ." , Field /binary >>);
252+ norm_fields ({[{Field , Cond }]}, Path ) when is_binary (Field ) ->
253+ {ok , F } = mango_util :parse_field (Field ),
254+ norm_fields ({[{F , Cond }]}, Path );
255+ norm_fields ({[{Field , Cond }]}, Path ) when is_list (Field ) ->
256+ norm_fields (Cond , Path ++ Field );
258257% An empty selector
259258norm_fields ({[]}, Path ) ->
260259 {Path , {[]}};
@@ -575,7 +574,14 @@ match({[_, _ | _] = _Props} = Sel, _Value, _Cmp) ->
575574% match against.
576575
577576has_required_fields (Selector , RequiredFields ) ->
578- Remainder = has_required_fields_int (Selector , RequiredFields ),
577+ Paths = lists :map (
578+ fun (Field ) ->
579+ {ok , Path } = mango_util :parse_field (Field ),
580+ Path
581+ end ,
582+ RequiredFields
583+ ),
584+ Remainder = has_required_fields_int (Selector , Paths ),
579585 Remainder == [].
580586
581587% Empty selector
@@ -634,6 +640,9 @@ has_required_fields_int([{[{Field, Cond}]} | Rest], RequiredFields) ->
634640 end .
635641
636642% Returns true if a field in the selector is a constant value e.g. {a: {$eq: 1}}
643+ is_constant_field (Selector , Field ) when not is_list (Field ) ->
644+ {ok , Path } = mango_util :parse_field (Field ),
645+ is_constant_field (Selector , Path );
637646is_constant_field ({[]}, _Field ) ->
638647 false ;
639648is_constant_field (Selector , Field ) when not is_list (Selector ) ->
@@ -653,7 +662,7 @@ is_constant_field([{[{_UnMatched, _}]} | Rest], Field) ->
653662fields ({[{<<" $" , _ /binary >>, Args }]}) when is_list (Args ) ->
654663 lists :flatmap (fun fields /1 , Args );
655664fields ({[{Field , _Cond }]}) ->
656- [Field ];
665+ [mango_util : join_field ( Field ) ];
657666fields ({[]}) ->
658667 [].
659668
@@ -1516,7 +1525,7 @@ match_object_test() ->
15161525
15171526 % an inner empty object selector matches only empty objects
15181527 SelEmptyField = normalize ({[{<<" x" >>, {[]}}]}),
1519- ? assertEqual ({[{<<" x" >>, {[{<<" $eq" >>, {[]}}]}}]}, SelEmptyField ),
1528+ ? assertEqual ({[{[ <<" x" >>] , {[{<<" $eq" >>, {[]}}]}}]}, SelEmptyField ),
15201529 ? assertEqual (false , match_int (SelEmptyField , Doc1 )),
15211530 ? assertEqual (true , match_int (SelEmptyField , Doc2 )),
15221531 ? assertEqual (false , match_int (SelEmptyField , Doc3 )),
@@ -1525,7 +1534,7 @@ match_object_test() ->
15251534
15261535 % negated empty object selector matches a value which is present and is not the empty object
15271536 SelNotEmptyField = normalize ({[{<<" $not" >>, {[{<<" x" >>, {[]}}]}}]}),
1528- ? assertEqual ({[{<<" x" >>, {[{<<" $ne" >>, {[]}}]}}]}, SelNotEmptyField ),
1537+ ? assertEqual ({[{[ <<" x" >>] , {[{<<" $ne" >>, {[]}}]}}]}, SelNotEmptyField ),
15291538 ? assertEqual (false , match_int (SelNotEmptyField , Doc1 )),
15301539 ? assertEqual (false , match_int (SelNotEmptyField , Doc2 )),
15311540 ? assertEqual (true , match_int (SelNotEmptyField , Doc3 )),
@@ -1534,7 +1543,7 @@ match_object_test() ->
15341543
15351544 % inner object selectors with fields match objects with at least those fields
15361545 Sel1Field = normalize ({[{<<" x" >>, {[{<<" a" >>, 1 }]}}]}),
1537- ? assertEqual ({[{<<" x. a" >>, {[{<<" $eq" >>, 1 }]}}]}, Sel1Field ),
1546+ ? assertEqual ({[{[ <<" x" >>, << " a" >>] , {[{<<" $eq" >>, 1 }]}}]}, Sel1Field ),
15381547 ? assertEqual (false , match_int (Sel1Field , Doc1 )),
15391548 ? assertEqual (false , match_int (Sel1Field , Doc2 )),
15401549 ? assertEqual (true , match_int (Sel1Field , Doc3 )),
@@ -1546,8 +1555,8 @@ match_object_test() ->
15461555 ? assertEqual (
15471556 {[
15481557 {<<" $and" >>, [
1549- {[{<<" x. a" >>, {[{<<" $eq" >>, 1 }]}}]},
1550- {[{<<" x. b" >>, {[{<<" $eq" >>, 2 }]}}]}
1558+ {[{[ <<" x" >>, << " a" >>] , {[{<<" $eq" >>, 1 }]}}]},
1559+ {[{[ <<" x" >>, << " b" >>] , {[{<<" $eq" >>, 2 }]}}]}
15511560 ]}
15521561 ]},
15531562 Sel2Field
@@ -1560,7 +1569,7 @@ match_object_test() ->
15601569
15611570 % check shorthand syntax
15621571 SelShort = normalize ({[{<<" x.b" >>, 2 }]}),
1563- ? assertEqual ({[{<<" x. b" >>, {[{<<" $eq" >>, 2 }]}}]}, SelShort ),
1572+ ? assertEqual ({[{[ <<" x" >>, << " b" >>] , {[{<<" $eq" >>, 2 }]}}]}, SelShort ),
15641573 ? assertEqual (false , match_int (SelShort , Doc1 )),
15651574 ? assertEqual (false , match_int (SelShort , Doc2 )),
15661575 ? assertEqual (false , match_int (SelShort , Doc3 )),
0 commit comments