summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgarren smith <garren.smith@gmail.com>2018-09-21 13:53:40 +0200
committerGitHub <noreply@github.com>2018-09-21 13:53:40 +0200
commit60107992135bc65f69ab8528825a13d36d77b4c9 (patch)
treebcf3dcd44380bc7d6d25161f7e9fdb04be45fa88
parent52ed7fbf48b953c3cd0dd5c058186a6af01dbc64 (diff)
downloadcouchdb-60107992135bc65f69ab8528825a13d36d77b4c9.tar.gz
Mango match doc on co-ordinating node (#1609)
* Mango match doc on co-ordinating node This fixes an issue when doing a rolling upgrade of a CouchDB cluster and adding commit a6bc72e the nodes that were not upgraded yet would send through all the docs in the index and those would be passed through to the user because the co-oridnator would assume it was matched at the node level. This adds in a check to see if it has been matched at the node level or not. And then performs a match if required.
-rw-r--r--src/mango/src/mango_cursor_view.erl82
1 files changed, 72 insertions, 10 deletions
diff --git a/src/mango/src/mango_cursor_view.erl b/src/mango/src/mango_cursor_view.erl
index 51ec68c45..174381e4a 100644
--- a/src/mango/src/mango_cursor_view.erl
+++ b/src/mango/src/mango_cursor_view.erl
@@ -405,31 +405,41 @@ doc_member(Cursor, RowProps) ->
Opts = Cursor#cursor.opts,
ExecutionStats = Cursor#cursor.execution_stats,
Selector = Cursor#cursor.selector,
- Incr = case couch_util:get_value(value, RowProps) of
- N when is_integer(N) -> N;
- _ -> 1
+ {Matched, Incr} = case couch_util:get_value(value, RowProps) of
+ N when is_integer(N) -> {true, N};
+ _ -> {false, 1}
end,
case couch_util:get_value(doc, RowProps) of
{DocProps} ->
ExecutionStats1 = mango_execution_stats:incr_docs_examined(ExecutionStats, Incr),
- {ok, {DocProps}, {execution_stats, ExecutionStats1}};
+ case Matched of
+ true ->
+ {ok, {DocProps}, {execution_stats, ExecutionStats1}};
+ false ->
+ match_doc(Selector, {DocProps}, ExecutionStats1)
+ end;
undefined ->
ExecutionStats1 = mango_execution_stats:incr_quorum_docs_examined(ExecutionStats),
Id = couch_util:get_value(id, RowProps),
case mango_util:defer(fabric, open_doc, [Db, Id, Opts]) of
{ok, #doc{}=DocProps} ->
Doc = couch_doc:to_json_obj(DocProps, []),
- case mango_selector:match(Selector, Doc) of
- true ->
- {ok, Doc, {execution_stats, ExecutionStats1}};
- false ->
- {no_match, Doc, {execution_stats, ExecutionStats1}}
- end;
+ match_doc(Selector, Doc, ExecutionStats1);
Else ->
Else
end
end.
+
+match_doc(Selector, Doc, ExecutionStats) ->
+ case mango_selector:match(Selector, Doc) of
+ true ->
+ {ok, Doc, {execution_stats, ExecutionStats}};
+ false ->
+ {no_match, Doc, {execution_stats, ExecutionStats}}
+ end.
+
+
is_design_doc(RowProps) ->
case couch_util:get_value(id, RowProps) of
<<"_design/", _/binary>> -> true;
@@ -446,3 +456,55 @@ update_bookmark_keys(#cursor{limit = Limit} = Cursor, Props) when Limit > 0 ->
};
update_bookmark_keys(Cursor, _Props) ->
Cursor.
+
+
+%%%%%%%% module tests below %%%%%%%%
+
+-ifdef(TEST).
+-include_lib("eunit/include/eunit.hrl").
+
+runs_match_on_doc_with_no_value_test() ->
+ Cursor = #cursor {
+ db = <<"db">>,
+ opts = [],
+ execution_stats = #execution_stats{},
+ selector = mango_selector:normalize({[{<<"user_id">>, <<"1234">>}]})
+ },
+ RowProps = [
+ {id,<<"b06aadcf-cd0f-4ca6-9f7e-2c993e48d4c4">>},
+ {key,<<"b06aadcf-cd0f-4ca6-9f7e-2c993e48d4c4">>},
+ {doc,{
+ [
+ {<<"_id">>,<<"b06aadcf-cd0f-4ca6-9f7e-2c993e48d4c4">>},
+ {<<"_rev">>,<<"1-a954fe2308f14307756067b0e18c2968">>},
+ {<<"user_id">>,11}
+ ]
+ }}
+ ],
+ {Match, _, _} = doc_member(Cursor, RowProps),
+ ?assertEqual(Match, no_match).
+
+does_not_run_match_on_doc_with_value_test() ->
+ Cursor = #cursor {
+ db = <<"db">>,
+ opts = [],
+ execution_stats = #execution_stats{},
+ selector = mango_selector:normalize({[{<<"user_id">>, <<"1234">>}]})
+ },
+ RowProps = [
+ {id,<<"b06aadcf-cd0f-4ca6-9f7e-2c993e48d4c4">>},
+ {key,<<"b06aadcf-cd0f-4ca6-9f7e-2c993e48d4c4">>},
+ {value,1},
+ {doc,{
+ [
+ {<<"_id">>,<<"b06aadcf-cd0f-4ca6-9f7e-2c993e48d4c4">>},
+ {<<"_rev">>,<<"1-a954fe2308f14307756067b0e18c2968">>},
+ {<<"user_id">>,11}
+ ]
+ }}
+ ],
+ {Match, _, _} = doc_member(Cursor, RowProps),
+ ?assertEqual(Match, ok).
+
+
+-endif.