diff options
author | garren smith <garren.smith@gmail.com> | 2018-09-21 13:53:40 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-09-21 13:53:40 +0200 |
commit | 60107992135bc65f69ab8528825a13d36d77b4c9 (patch) | |
tree | bcf3dcd44380bc7d6d25161f7e9fdb04be45fa88 | |
parent | 52ed7fbf48b953c3cd0dd5c058186a6af01dbc64 (diff) | |
download | couchdb-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.erl | 82 |
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. |