couchdb-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From dav...@apache.org
Subject svn commit: r1156509 - in /couchdb/trunk: share/www/script/test/all_docs.js share/www/script/test/view_collation_raw.js src/couchdb/couch_httpd_db.erl src/couchdb/couch_httpd_view.erl
Date Thu, 11 Aug 2011 06:41:47 GMT
Author: davisp
Date: Thu Aug 11 06:41:47 2011
New Revision: 1156509

URL: http://svn.apache.org/viewvc?rev=1156509&view=rev
Log:
Fix empty range check for raw collation.

The check for empty ranges was not taking into account the
view option for raw collation. This fixes that by passing
the couch_btree:less/2 function into the check.

Patch by: Jason Smith
Re: COUCHDB-1228 4/4


Modified:
    couchdb/trunk/share/www/script/test/all_docs.js
    couchdb/trunk/share/www/script/test/view_collation_raw.js
    couchdb/trunk/src/couchdb/couch_httpd_db.erl
    couchdb/trunk/src/couchdb/couch_httpd_view.erl

Modified: couchdb/trunk/share/www/script/test/all_docs.js
URL: http://svn.apache.org/viewvc/couchdb/trunk/share/www/script/test/all_docs.js?rev=1156509&r1=1156508&r2=1156509&view=diff
==============================================================================
--- couchdb/trunk/share/www/script/test/all_docs.js (original)
+++ couchdb/trunk/share/www/script/test/all_docs.js Thu Aug 11 06:41:47 2011
@@ -41,6 +41,12 @@ couchTests.all_docs = function(debug) {
   var all = db.allDocs({startkey:"2"});
   T(all.offset == 2);
 
+  // Confirm that queries may assume raw collation.
+  var raw = db.allDocs({ startkey: "org.couchdb.user:"
+                       , endkey  : "org.couchdb.user;"
+                       });
+  TEquals(0, raw.rows.length);
+
   // check that the docs show up in the seq view in the order they were created
   var changes = db.changes();
   var ids = ["0","3","1","2"];

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=1156509&r1=1156508&r2=1156509&view=diff
==============================================================================
--- couchdb/trunk/share/www/script/test/view_collation_raw.js (original)
+++ couchdb/trunk/share/www/script/test/view_collation_raw.js Thu Aug 11 06:41:47 2011
@@ -83,6 +83,11 @@ couchTests.view_collation_raw = function
     T(equals(rows[i].key, values[i]));
   }
 
+  // Confirm that couch allows raw semantics in key ranges.
+  rows = db.view("test/test", {startkey:"Z", endkey:"a"}).rows;
+  TEquals(1, rows.length);
+  TEquals("a", rows[0].key);
+
   // Check the descending output.
   rows = db.view("test/test", {descending: true}).rows;
   for (i=0; i<values.length; i++) {

Modified: couchdb/trunk/src/couchdb/couch_httpd_db.erl
URL: http://svn.apache.org/viewvc/couchdb/trunk/src/couchdb/couch_httpd_db.erl?rev=1156509&r1=1156508&r2=1156509&view=diff
==============================================================================
--- couchdb/trunk/src/couchdb/couch_httpd_db.erl (original)
+++ couchdb/trunk/src/couchdb/couch_httpd_db.erl Thu Aug 11 06:41:47 2011
@@ -481,6 +481,7 @@ db_req(#httpd{path_parts=[_, DocId | Fil
     db_attachment_req(Req, Db, DocId, FileNameParts).
 
 all_docs_view(Req, Db, Keys) ->
+    RawCollator = fun(A, B) -> A < B end,
     #view_query_args{
         start_key = StartKey,
         start_docid = StartDocId,
@@ -490,7 +491,8 @@ all_docs_view(Req, Db, Keys) ->
         skip = SkipCount,
         direction = Dir,
         inclusive_end = Inclusive
-    } = QueryArgs = couch_httpd_view:parse_view_params(Req, Keys, map),
+    } = QueryArgs
+      = couch_httpd_view:parse_view_params(Req, Keys, map, RawCollator),
     {ok, Info} = couch_db:get_db_info(Db),
     CurrentEtag = couch_httpd:make_etag(Info),
     couch_httpd:etag_respond(Req, CurrentEtag, fun() ->

Modified: couchdb/trunk/src/couchdb/couch_httpd_view.erl
URL: http://svn.apache.org/viewvc/couchdb/trunk/src/couchdb/couch_httpd_view.erl?rev=1156509&r1=1156508&r2=1156509&view=diff
==============================================================================
--- couchdb/trunk/src/couchdb/couch_httpd_view.erl (original)
+++ couchdb/trunk/src/couchdb/couch_httpd_view.erl Thu Aug 11 06:41:47 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,19 @@ 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, Keys, map, view_collator(View)),
         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} ->
+            Collator = view_collator(ReduceView),
             case Reduce of
             false ->
-                QueryArgs = parse_view_params(Req, Keys, red_map),
+                QueryArgs = parse_view_params(Req, Keys, red_map, Collator),
                 MapView = couch_view:extract_map_view(ReduceView),
                 output_map_view(Req, MapView, Group, Db, QueryArgs, Keys);
             _ ->
-                QueryArgs = parse_view_params(Req, Keys, reduce),
+                QueryArgs = parse_view_params(Req, Keys, reduce, Collator),
                 output_reduce_view(Req, Db, ReduceView, Group, QueryArgs, Keys)
             end;
         _ ->
@@ -92,17 +93,17 @@ handle_temp_view_req(#httpd{method='POST
     null ->
         {ok, View, Group} = couch_view:get_temp_map_view(Db, Language,
             DesignOptions, MapSrc),
-        QueryArgs = parse_view_params(Req, Keys, map),
+        QueryArgs = parse_view_params(Req, Keys, map, view_collator(View)),
         output_map_view(Req, View, Group, Db, QueryArgs, Keys);
     _ when Reduce =:= false ->
         {ok, View, Group} = couch_view:get_temp_map_view(Db, Language,
             DesignOptions, MapSrc),
-        QueryArgs = parse_view_params(Req, Keys, red_map),
+        QueryArgs = parse_view_params(Req, Keys, red_map, view_collator(View)),
         output_map_view(Req, View, Group, Db, QueryArgs, Keys);
     RedSrc ->
         {ok, View, Group} = couch_view:get_temp_reduce_view(Db, Language,
             DesignOptions, MapSrc, RedSrc),
-        QueryArgs = parse_view_params(Req, Keys, reduce),
+        QueryArgs = parse_view_params(Req, Keys, reduce, view_collator(View)),
         output_reduce_view(Req, Db, View, Group, QueryArgs, Keys)
     end;
 
@@ -209,18 +210,19 @@ 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, Keys, map, view_collator(View)),
         {map, View, Group, QueryArgs};
     {not_found, _Reason} ->
         case couch_view:get_reduce_view(Db, ViewDesignId, ViewName, Stale) of
         {ok, ReduceView, Group} ->
+            Collator = view_collator(ReduceView),
             case Reduce of
             false ->
-                QueryArgs = parse_view_params(Req, Keys, map_red),
+                QueryArgs = parse_view_params(Req, Keys, map_red, Collator),
                 MapView = couch_view:extract_map_view(ReduceView),
                 {map, MapView, Group, QueryArgs};
             _ ->
-                QueryArgs = parse_view_params(Req, Keys, reduce),
+                QueryArgs = parse_view_params(Req, Keys, reduce, Collator),
                 {reduce, ReduceView, Group, QueryArgs}
             end;
         {not_found, Reason} ->
@@ -228,12 +230,30 @@ load_view(Req, Db, {ViewDesignId, ViewNa
         end
     end.
 
+view_collator({reduce, _N, _Lang, View}) ->
+    view_collator(View);
+
+view_collator({temp_reduce, View}) ->
+    view_collator(View);
+
+view_collator(#view{btree=Btree}) ->
+    % Return an "is-less-than" predicate by calling into the btree's
+    % collator. For raw collation, couch_btree compares arbitrary
+    % Erlang terms, but for normal (ICU) collation, it expects
+    % {Json, Id} tuples.
+    fun
+        ({_JsonA, _IdA}=A, {_JsonB, _IdB}=B) ->
+            couch_btree:less(Btree, A, B);
+        (JsonA, JsonB) ->
+            couch_btree:less(Btree, {JsonA, null}, {JsonB, null})
+    end.
+
 % query_parse_error could be removed
 % we wouldn't need to pass the view type, it'd just parse params.
 % 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, Keys, ViewType, LessThan) ->
     QueryList = couch_httpd:qs(Req),
     QueryParams =
     lists:foldl(fun({K, V}, Acc) ->
@@ -247,7 +267,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, LessThan),
     GroupLevel = QueryArgs#view_query_args.group_level,
     case {ViewType, GroupLevel, IsMultiGet} of
     {reduce, exact, true} ->
@@ -328,15 +348,15 @@ 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}, _Lt) ->
     ok;
-warn_on_empty_key_range(#view_query_args{end_key=undefined}) ->
+warn_on_empty_key_range(#view_query_args{end_key=undefined}, _Lt) ->
     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}, _Lt) ->
     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}, LessThan) ->
+    case {Dir, LessThan(StartKey, EndKey)} of
         {fwd, false} ->
             throw({query_parse_error,
             <<"No rows can match your key range, reverse your ",



Mime
View raw message