You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by va...@apache.org on 2016/07/22 07:36:28 UTC

chttpd commit: updated refs/heads/couchdb-3070-fix-multi-query-view-type to cca0df5 [Forced Update!]

Repository: couchdb-chttpd
Updated Branches:
  refs/heads/couchdb-3070-fix-multi-query-view-type 12af1697b -> cca0df5dd (forced update)


In a multi-query view request, set view type for each query

Namely, a default `reduce` view type can be overridden to behave like a `map`,
if user explicitly sets `reduce=false`.

Previously this didn't happen. For example, a query like this:

```
{
  "queries": [{
    "include_docs": true,
    "reduce": false
  }]
}
```

 would fail with:

```
{"error":"query_parse_error","reason":"`include_docs` is invalid for reduce"}
```

 but it shouldn't, because user explicitly disabled `reduce` and now
`include_docs` is valid for a map view.

To fix, make sure to call `set_view_type` for each query's args.

Jira: COUCHDB-3070


Project: http://git-wip-us.apache.org/repos/asf/couchdb-chttpd/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb-chttpd/commit/cca0df5d
Tree: http://git-wip-us.apache.org/repos/asf/couchdb-chttpd/tree/cca0df5d
Diff: http://git-wip-us.apache.org/repos/asf/couchdb-chttpd/diff/cca0df5d

Branch: refs/heads/couchdb-3070-fix-multi-query-view-type
Commit: cca0df5dd0a2f7adfd4ac8cc0a363bdc5a563c2c
Parents: 21be898
Author: Nick Vatamaniuc <va...@gmail.com>
Authored: Thu Jul 21 17:48:15 2016 -0400
Committer: Nick Vatamaniuc <va...@gmail.com>
Committed: Fri Jul 22 03:27:39 2016 -0400

----------------------------------------------------------------------
 src/chttpd_view.erl | 55 +++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 54 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-chttpd/blob/cca0df5d/src/chttpd_view.erl
----------------------------------------------------------------------
diff --git a/src/chttpd_view.erl b/src/chttpd_view.erl
index 4889b65..32b6469 100644
--- a/src/chttpd_view.erl
+++ b/src/chttpd_view.erl
@@ -23,7 +23,8 @@ multi_query_view(Req, Db, DDoc, ViewName, Queries) ->
     ArgQueries = lists:map(fun({Query}) ->
         QueryArg = couch_mrview_http:parse_params(Query, undefined,
             Args1, [decoded]),
-        couch_mrview_util:validate_args(QueryArg)
+        QueryArg1 = couch_mrview_util:set_view_type(QueryArg, ViewName, Views),
+        couch_mrview_util:validate_args(QueryArg1)
     end, Queries),
     VAcc0 = #vacc{db=Db, req=Req, prepend="\r\n"},
     FirstChunk = "{\"results\":[",
@@ -78,3 +79,55 @@ handle_view_req(Req, _Db, _DDoc) ->
 handle_temp_view_req(Req, _Db) ->
     Msg = <<"Temporary views are not supported in CouchDB">>,
     chttpd:send_error(Req, 403, forbidden, Msg).
+
+
+
+-ifdef(TEST).
+
+-include_lib("eunit/include/eunit.hrl").
+
+
+check_multi_query_reduce_view_overrides_test_() ->
+    {
+        foreach,
+        fun setup/0,
+        fun teardown/1,
+        [
+            t_check_include_docs_throw_validation_error(),
+            t_check_user_can_override_individual_query_type()
+        ]
+    }.
+
+
+t_check_include_docs_throw_validation_error() ->
+    ?_test(begin
+        Req = #httpd{qs = []},
+        Query = {[{<<"include_docs">>, true}]},
+        Throw = {query_parse_error, <<"`include_docs` is invalid for reduce">>},
+        ?assertThrow(Throw, multi_query_view(Req, db, ddoc, <<"v">>, [Query]))
+    end).
+
+
+t_check_user_can_override_individual_query_type() ->
+    ?_test(begin
+        Req = #httpd{qs = []},
+        Query = {[{<<"include_docs">>, true}, {<<"reduce">>, false}]},
+        multi_query_view(Req, db, ddoc, <<"v">>, [Query]),
+        ?assertEqual(1, meck:num_calls(chttpd, start_delayed_json_response, '_'))
+    end).
+
+
+setup() ->
+    Views = [#mrview{reduce_funs = [{<<"v">>, <<"_count">>}]}],
+    meck:expect(couch_mrview_util, ddoc_to_mrst, 2, {ok, #mrst{views = Views}}),
+    meck:expect(chttpd, start_delayed_json_response, 4, {ok, resp}),
+    meck:expect(fabric, query_view, 6, {ok, #vacc{}}),
+    meck:expect(chttpd, send_delayed_chunk, 2, {ok, resp}),
+    meck:expect(chttpd, end_delayed_json_response, 1, ok).
+
+
+teardown(_) ->
+    meck:unload().
+
+
+-endif.