You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by ja...@apache.org on 2011/07/21 10:41:49 UTC

svn commit: r1149077 - in /couchdb/trunk: share/www/script/test/view_collation_raw.js src/couchdb/couch_httpd_view.erl src/couchdb/couch_view.erl src/couchdb/couch_view_group.erl

Author: jan
Date: Thu Jul 21 08:41:46 2011
New Revision: 1149077

URL: http://svn.apache.org/viewvc?rev=1149077&view=rev
Log:
Don't falsly warn about empty result ranges with raw collation views.

In the process of fixing 1228, couch_view:less_raw/2 and
couch_view:get_less_fun/1 are introduced to give access to the
respective data inside the couch_httpd_view  where the warning occurs
as well as couch_view_group where the actual view updating is defined.

Closes COUCHDB-1228.

Modified:
    couchdb/trunk/share/www/script/test/view_collation_raw.js
    couchdb/trunk/src/couchdb/couch_httpd_view.erl
    couchdb/trunk/src/couchdb/couch_view.erl
    couchdb/trunk/src/couchdb/couch_view_group.erl

Modified: couchdb/trunk/share/www/script/test/view_collation_raw.js
URL: http://svn.apache.org/viewvc/couchdb/trunk/share/www/script/test/view_collation_raw.js?rev=1149077&r1=1149076&r2=1149077&view=diff
==============================================================================
--- couchdb/trunk/share/www/script/test/view_collation_raw.js (original)
+++ couchdb/trunk/share/www/script/test/view_collation_raw.js Thu Jul 21 08:41:46 2011
@@ -120,4 +120,38 @@ couchTests.view_collation_raw = function
     endkey : "b", endkey_docid: "11",
     inclusive_end:false}).rows;
   T(rows[rows.length-1].key == "aa");
+
+  // result empty warning behaves different on raw collation
+  // COUCHDB-1228
+  var docs = [
+    {"x":"A"},
+    {"x":"C"},
+    {"x":"b"}
+  ];
+
+  db.bulkSave(docs);
+
+  var ddoc = {
+    _id: "_design/t",
+    views: {
+      foo: {
+        options: {
+          collation: "raw"
+        },
+        map: stringFun(function(doc) { emit(doc.x);})
+      }
+    }
+  };
+
+  db.save(ddoc);
+
+  var res = db.view("t/foo");
+  TEquals("A", res.rows[0].key);
+  TEquals("C", res.rows[1].key);
+  TEquals("b", res.rows[2].key);
+
+  var res = db.view("t/foo", {startkey: "B", endkey: "a"});
+  TEquals("C", res.rows[0].key, "Should return 'C'");
+  // 1228 end
+
 };

Modified: couchdb/trunk/src/couchdb/couch_httpd_view.erl
URL: http://svn.apache.org/viewvc/couchdb/trunk/src/couchdb/couch_httpd_view.erl?rev=1149077&r1=1149076&r2=1149077&view=diff
==============================================================================
--- couchdb/trunk/src/couchdb/couch_httpd_view.erl (original)
+++ couchdb/trunk/src/couchdb/couch_httpd_view.erl Thu Jul 21 08:41:46 2011
@@ -15,7 +15,7 @@
 
 -export([handle_view_req/3,handle_temp_view_req/2]).
 
--export([parse_view_params/3]).
+-export([parse_view_params/4]).
 -export([make_view_fold_fun/7, finish_view_fold/4, finish_view_fold/5, view_row_obj/4]).
 -export([view_etag/5, make_reduce_fold_funs/6]).
 -export([design_doc_view/5, parse_bool_param/1, doc_member/3]).
@@ -34,18 +34,18 @@ design_doc_view(Req, Db, DName, ViewName
     Reduce = get_reduce_type(Req),
     Result = case couch_view:get_map_view(Db, DesignId, ViewName, Stale) of
     {ok, View, Group} ->
-        QueryArgs = parse_view_params(Req, Keys, map),
+        QueryArgs = parse_view_params(Req, View, Keys, map),
         output_map_view(Req, View, Group, Db, QueryArgs, Keys);
     {not_found, Reason} ->
         case couch_view:get_reduce_view(Db, DesignId, ViewName, Stale) of
         {ok, ReduceView, Group} ->
             case Reduce of
             false ->
-                QueryArgs = parse_view_params(Req, Keys, red_map),
                 MapView = couch_view:extract_map_view(ReduceView),
+                QueryArgs = parse_view_params(Req, MapView, Keys, red_map),
                 output_map_view(Req, MapView, Group, Db, QueryArgs, Keys);
             _ ->
-                QueryArgs = parse_view_params(Req, Keys, reduce),
+                QueryArgs = parse_view_params(Req, ReduceView, Keys, reduce),
                 output_reduce_view(Req, Db, ReduceView, Group, QueryArgs, Keys)
             end;
         _ ->
@@ -90,19 +90,19 @@ handle_temp_view_req(#httpd{method='POST
     Reduce = get_reduce_type(Req),
     case couch_util:get_value(<<"reduce">>, Props, null) of
     null ->
-        QueryArgs = parse_view_params(Req, Keys, map),
         {ok, View, Group} = couch_view:get_temp_map_view(Db, Language,
             DesignOptions, MapSrc),
+        QueryArgs = parse_view_params(Req, View, Keys, map),
         output_map_view(Req, View, Group, Db, QueryArgs, Keys);
     _ when Reduce =:= false ->
-        QueryArgs = parse_view_params(Req, Keys, red_map),
         {ok, View, Group} = couch_view:get_temp_map_view(Db, Language,
             DesignOptions, MapSrc),
+        QueryArgs = parse_view_params(Req, View, Keys, red_map),
         output_map_view(Req, View, Group, Db, QueryArgs, Keys);
     RedSrc ->
-        QueryArgs = parse_view_params(Req, Keys, reduce),
         {ok, View, Group} = couch_view:get_temp_reduce_view(Db, Language,
             DesignOptions, MapSrc, RedSrc),
+        QueryArgs = parse_view_params(Req, View, Keys, reduce),
         output_reduce_view(Req, Db, View, Group, QueryArgs, Keys)
     end;
 
@@ -209,18 +209,18 @@ load_view(Req, Db, {ViewDesignId, ViewNa
     Reduce = get_reduce_type(Req),
     case couch_view:get_map_view(Db, ViewDesignId, ViewName, Stale) of
     {ok, View, Group} ->
-        QueryArgs = parse_view_params(Req, Keys, map),
+        QueryArgs = parse_view_params(Req, View, Keys, map),
         {map, View, Group, QueryArgs};
     {not_found, _Reason} ->
         case couch_view:get_reduce_view(Db, ViewDesignId, ViewName, Stale) of
         {ok, ReduceView, Group} ->
             case Reduce of
             false ->
-                QueryArgs = parse_view_params(Req, Keys, map_red),
                 MapView = couch_view:extract_map_view(ReduceView),
+                QueryArgs = parse_view_params(Req, MapView, Keys, map_red),
                 {map, MapView, Group, QueryArgs};
             _ ->
-                QueryArgs = parse_view_params(Req, Keys, reduce),
+                QueryArgs = parse_view_params(Req, ReduceView, Keys, reduce),
                 {reduce, ReduceView, Group, QueryArgs}
             end;
         {not_found, Reason} ->
@@ -233,7 +233,7 @@ load_view(Req, Db, {ViewDesignId, ViewNa
 % I'm not sure what to do about the error handling, but
 % it might simplify things to have a parse_view_params function
 % that doesn't throw().
-parse_view_params(Req, Keys, ViewType) ->
+parse_view_params(Req, View, Keys, ViewType) ->
     QueryList = couch_httpd:qs(Req),
     QueryParams =
     lists:foldl(fun({K, V}, Acc) ->
@@ -247,7 +247,7 @@ parse_view_params(Req, Keys, ViewType) -
     QueryArgs = lists:foldl(fun({K, V}, Args2) ->
         validate_view_query(K, V, Args2)
     end, Args, lists:reverse(QueryParams)), % Reverse to match QS order.
-    warn_on_empty_key_range(QueryArgs),
+    warn_on_empty_key_range(QueryArgs, View),
     GroupLevel = QueryArgs#view_query_args.group_level,
     case {ViewType, GroupLevel, IsMultiGet} of
     {reduce, exact, true} ->
@@ -328,15 +328,16 @@ parse_view_param("callback", _) ->
 parse_view_param(Key, Value) ->
     [{extra, {Key, Value}}].
 
-warn_on_empty_key_range(#view_query_args{start_key=undefined}) ->
+warn_on_empty_key_range(#view_query_args{start_key=undefined}, _View) ->
     ok;
-warn_on_empty_key_range(#view_query_args{end_key=undefined}) ->
+warn_on_empty_key_range(#view_query_args{end_key=undefined}, _View) ->
     ok;
-warn_on_empty_key_range(#view_query_args{start_key=A, end_key=A}) ->
+warn_on_empty_key_range(#view_query_args{start_key=A, end_key=A}, _View) ->
     ok;
 warn_on_empty_key_range(#view_query_args{
-    start_key=StartKey, end_key=EndKey, direction=Dir}) ->
-    case {Dir, couch_view:less_json(StartKey, EndKey)} of
+    start_key=StartKey, end_key=EndKey, direction=Dir}, #view{options=Options}) ->
+    Less = couch_view:get_less_fun(Options),
+    case {Dir, Less(StartKey, EndKey)} of
         {fwd, false} ->
             throw({query_parse_error,
             <<"No rows can match your key range, reverse your ",

Modified: couchdb/trunk/src/couchdb/couch_view.erl
URL: http://svn.apache.org/viewvc/couchdb/trunk/src/couchdb/couch_view.erl?rev=1149077&r1=1149076&r2=1149077&view=diff
==============================================================================
--- couchdb/trunk/src/couchdb/couch_view.erl (original)
+++ couchdb/trunk/src/couchdb/couch_view.erl Thu Jul 21 08:41:46 2011
@@ -13,10 +13,10 @@
 -module(couch_view).
 -behaviour(gen_server).
 
--export([start_link/0,fold/4,less_json/2,less_json_ids/2,expand_dups/2,
+-export([start_link/0,fold/4,less_json/2,less_json_ids/2,less_raw/2,expand_dups/2,
     detuple_kvs/2,init/1,terminate/2,handle_call/3,handle_cast/2,handle_info/2,
     code_change/3,get_reduce_view/4,get_temp_reduce_view/5,get_temp_map_view/4,
-    get_map_view/4,get_row_count/1,reduce_to_count/1,fold_reduce/4,
+    get_map_view/4,get_row_count/1,reduce_to_count/1,fold_reduce/4,get_less_fun/1,
     extract_map_view/1,get_group_server/2,get_group_info/2,cleanup_index_files/1]).
 
 -include("couch_db.hrl").
@@ -408,3 +408,13 @@ less_json_ids({JsonA, IdA}, {JsonB, IdB}
 
 less_json(A,B) ->
     couch_ejson_compare:less(A, B) < 0.
+
+less_raw(A,B) -> A < B.
+
+get_less_fun(ViewOptions) ->
+    case couch_util:get_value(<<"collation">>, ViewOptions, <<"default">>) of
+    <<"default">> ->
+        fun couch_view:less_json_ids/2;
+    <<"raw">> ->
+        fun couch_view:less_raw/2
+    end.

Modified: couchdb/trunk/src/couchdb/couch_view_group.erl
URL: http://svn.apache.org/viewvc/couchdb/trunk/src/couchdb/couch_view_group.erl?rev=1149077&r1=1149076&r2=1149077&view=diff
==============================================================================
--- couchdb/trunk/src/couchdb/couch_view_group.erl (original)
+++ couchdb/trunk/src/couchdb/couch_view_group.erl Thu Jul 21 08:41:46 2011
@@ -630,13 +630,8 @@ init_group(Db, Fd, #group{def_lang=Lang,
                         UserReds),
                     {Count, Reduced}
                 end,
-            
-            case couch_util:get_value(<<"collation">>, Options, <<"default">>) of
-            <<"default">> ->
-                Less = fun couch_view:less_json_ids/2;
-            <<"raw">> ->
-                Less = fun(A,B) -> A < B end
-            end,
+
+            Less = couch_view:get_less_fun(Options),
             {ok, Btree} = couch_btree:open(BTState, Fd,
                     [{less, Less}, {reduce, ReduceFun},
                         {compression, Db#db.compression}]