summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoriilyak <iilyak@ca.ibm.com>2018-06-29 12:37:48 -0700
committerGitHub <noreply@github.com>2018-06-29 12:37:48 -0700
commitd36149ec3a0d071d067589c8f3fe7d263626948d (patch)
tree30d7c425f5a54633fc0b76e84441aca2d9ffa790
parent120903698e0689f0f021411fb4bdbb164a7ae77a (diff)
parent0377e53ce82c758fe5ee16aa105639fc813a5c77 (diff)
downloadcouchdb-d36149ec3a0d071d067589c8f3fe7d263626948d.tar.gz
Merge pull request #1401 from Spotme/spotme/fix/couch-native-process
Fix for a function_clause crash in the couch_native_process for Erlang views
-rw-r--r--src/couch/src/couch_native_process.erl12
-rw-r--r--src/couch/test/couch_changes_tests.erl38
2 files changed, 49 insertions, 1 deletions
diff --git a/src/couch/src/couch_native_process.erl b/src/couch/src/couch_native_process.erl
index 6d66c936b..8f8ce8b1d 100644
--- a/src/couch/src/couch_native_process.erl
+++ b/src/couch/src/couch_native_process.erl
@@ -226,6 +226,18 @@ ddoc(State, {_, Fun}, [<<"filters">>|_], [Docs, Req]) ->
end,
Resp = lists:map(FilterFunWrapper, Docs),
{State, [true, Resp]};
+ddoc(State, {_, Fun}, [<<"views">>|_], [Docs]) ->
+ MapFunWrapper = fun(Doc) ->
+ case catch Fun(Doc) of
+ undefined -> true;
+ ok -> false;
+ false -> false;
+ [_|_] -> true;
+ {'EXIT', Error} -> couch_log:error("~p", [Error])
+ end
+ end,
+ Resp = lists:map(MapFunWrapper, Docs),
+ {State, [true, Resp]};
ddoc(State, {_, Fun}, [<<"shows">>|_], Args) ->
Resp = case (catch apply(Fun, Args)) of
FunResp when is_list(FunResp) ->
diff --git a/src/couch/test/couch_changes_tests.erl b/src/couch/test/couch_changes_tests.erl
index 673f2faad..e4ea76167 100644
--- a/src/couch/test/couch_changes_tests.erl
+++ b/src/couch/test/couch_changes_tests.erl
@@ -47,9 +47,11 @@ setup() ->
save_doc(Db1, {[{<<"_id">>, <<"doc7">>}]}),
save_doc(Db1, {[{<<"_id">>, <<"doc8">>}]})
]],
+ config:set("native_query_servers", "erlang", "{couch_native_process, start_link, []}", _Persist=false),
{DbName, list_to_tuple(Revs2)}.
teardown({DbName, _}) ->
+ config:delete("native_query_servers", "erlang", _Persist=false),
delete_db(DbName),
ok.
@@ -153,7 +155,8 @@ filter_by_view() ->
fun setup/0, fun teardown/1,
[
fun should_filter_by_view/1,
- fun should_filter_by_fast_view/1
+ fun should_filter_by_fast_view/1,
+ fun should_filter_by_erlang_view/1
]
}
}.
@@ -733,6 +736,39 @@ should_filter_by_fast_view({DbName, _}) ->
?assertEqual(UpSeq, ViewUpSeq)
end).
+should_filter_by_erlang_view({DbName, _}) ->
+ ?_test(
+ begin
+ DDocId = <<"_design/app">>,
+ DDoc = couch_doc:from_json_obj({[
+ {<<"_id">>, DDocId},
+ {<<"language">>, <<"erlang">>},
+ {<<"views">>, {[
+ {<<"valid">>, {[
+ {<<"map">>, <<"fun({Doc}) ->"
+ " case lists:keyfind(<<\"_id\">>, 1, Doc) of"
+ " {<<\"_id\">>, <<\"doc3\">>} -> Emit(Doc, null); "
+ " false -> ok"
+ " end "
+ "end.">>}
+ ]}}
+ ]}}
+ ]}),
+ ChArgs = #changes_args{filter = "_view"},
+ Req = {json_req, {[{
+ <<"query">>, {[
+ {<<"view">>, <<"app/valid">>}
+ ]}
+ }]}},
+ ok = update_ddoc(DbName, DDoc),
+ {Rows, LastSeq, UpSeq} = run_changes_query(DbName, ChArgs, Req),
+ ?assertEqual(1, length(Rows)),
+ [#row{seq = Seq, id = Id}] = Rows,
+ ?assertEqual(<<"doc3">>, Id),
+ ?assertEqual(6, Seq),
+ ?assertEqual(UpSeq, LastSeq)
+ end).
+
update_ddoc(DbName, DDoc) ->
{ok, Db} = couch_db:open_int(DbName, [?ADMIN_CTX]),
{ok, _} = couch_db:update_doc(Db, DDoc, []),