diff options
author | iilyak <iilyak@ca.ibm.com> | 2018-06-29 12:37:48 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-06-29 12:37:48 -0700 |
commit | d36149ec3a0d071d067589c8f3fe7d263626948d (patch) | |
tree | 30d7c425f5a54633fc0b76e84441aca2d9ffa790 | |
parent | 120903698e0689f0f021411fb4bdbb164a7ae77a (diff) | |
parent | 0377e53ce82c758fe5ee16aa105639fc813a5c77 (diff) | |
download | couchdb-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.erl | 12 | ||||
-rw-r--r-- | src/couch/test/couch_changes_tests.erl | 38 |
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, []), |