You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by rn...@apache.org on 2018/08/06 18:52:09 UTC

[couchdb] branch user-partitioned-dbs-4 updated (feeeda4 -> 9e3f4d2)

This is an automated email from the ASF dual-hosted git repository.

rnewson pushed a change to branch user-partitioned-dbs-4
in repository https://gitbox.apache.org/repos/asf/couchdb.git.


 discard feeeda4  expose partitioned flag in GET /dbname info
 discard f5b2e39  Enforce partition:id format in doc ids
 discard c8e9dfb  map documents to shards by their partition
     new f1ee44c  map documents to shards by their partition
     new 172ef10  Enforce partition:id format in doc ids
     new 60f39de  expose partitioned flag in GET /dbname info
     new 842da32  Allow partitioned option in mrviews
     new 79e204b  Select only the shard containing the partition, if specified
     new 9e3f4d2  validate new partition arguments

This update added new revisions after undoing existing revisions.
That is to say, some revisions that were in the old version of the
branch are not in the new version.  This situation occurs
when a user --force pushes a change and generates a repository
containing something like this:

 * -- * -- B -- O -- O -- O   (feeeda4)
            \
             N -- N -- N   refs/heads/user-partitioned-dbs-4 (9e3f4d2)

You should already have received notification emails for all of the O
revisions, and so the following emails describe only the N revisions
from the common base, B.

Any revisions marked "omit" are not gone; other references still
refer to them.  Any revisions marked "discard" are gone forever.

The 6 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 src/chttpd/src/chttpd_db.erl                |  4 ++--
 src/couch/src/couch_doc.erl                 |  2 ++
 src/couch_mrview/src/couch_mrview.erl       |  5 +++++
 src/couch_mrview/src/couch_mrview_http.erl  |  3 +++
 src/couch_mrview/src/couch_mrview_index.erl |  4 +++-
 src/couch_mrview/src/couch_mrview_util.erl  | 22 ++++++++++++++++++++++
 src/fabric/include/fabric.hrl               |  3 ++-
 src/fabric/src/fabric.erl                   | 25 +++++++++++++++++++------
 src/fabric/src/fabric_util.erl              |  1 -
 src/fabric/src/fabric_view.erl              | 27 +++++++++++++++++++++++----
 10 files changed, 81 insertions(+), 15 deletions(-)


[couchdb] 01/06: map documents to shards by their partition

Posted by rn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rnewson pushed a commit to branch user-partitioned-dbs-4
in repository https://gitbox.apache.org/repos/asf/couchdb.git

commit f1ee44c9f506b5166eff7b610510713fbaabb429
Author: Robert Newson <rn...@apache.org>
AuthorDate: Wed Aug 1 18:45:52 2018 +0100

    map documents to shards by their partition
---
 src/mem3/src/mem3.erl        | 41 ++++++++++++++++++++++++++++++++++++-----
 src/mem3/src/mem3_shards.erl | 20 +++++++++++++++++---
 src/mem3/src/mem3_util.erl   | 23 +++++++++++++++++++++++
 3 files changed, 76 insertions(+), 8 deletions(-)

diff --git a/src/mem3/src/mem3.erl b/src/mem3/src/mem3.erl
index 0e5eabf..99c0863 100644
--- a/src/mem3/src/mem3.erl
+++ b/src/mem3/src/mem3.erl
@@ -13,7 +13,7 @@
 -module(mem3).
 
 -export([start/0, stop/0, restart/0, nodes/0, node_info/2, shards/1, shards/2,
-    choose_shards/2, n/1, n/2, dbname/1, ushards/1]).
+    choose_shards/2, n/1, n/2, dbname/1, ushards/1, ushards/2]).
 -export([get_shard/3, local_shards/1, shard_suffix/1, fold_shards/2]).
 -export([sync_security/0, sync_security/1]).
 -export([compare_nodelists/0, compare_shards/1]).
@@ -21,6 +21,7 @@
 -export([live_shards/2]).
 -export([belongs/2, owner/3]).
 -export([get_placement/1]).
+-export([is_partitioned/1]).
 
 %% For mem3 use only.
 -export([name/1, node/1, range/1, engine/1]).
@@ -68,7 +69,7 @@ compare_shards(DbName) ->
 
 -spec n(DbName::iodata()) -> integer().
 n(DbName) ->
-    n(DbName, <<"foo">>).
+    n(DbName, <<"_design/foo">>).
 
 n(DbName, DocId) ->
     length(mem3:shards(DbName, DocId)).
@@ -133,6 +134,12 @@ ushards(DbName) ->
     Shards = ushards(DbName, live_shards(DbName, Nodes, [ordered]), ZoneMap),
     mem3_util:downcast(Shards).
 
+-spec ushards(DbName::iodata(), DocId::binary()) -> [#shard{}].
+ushards(DbName, DocId) ->
+    Shards = shards_int(DbName, DocId, [ordered]),
+    Shard = hd(Shards),
+    mem3_util:downcast([Shard]).
+
 ushards(DbName, Shards0, ZoneMap) ->
     {L,S,D} = group_by_proximity(Shards0, ZoneMap),
     % Prefer shards in the local zone over shards in a different zone,
@@ -229,13 +236,14 @@ dbname(_) ->
     erlang:error(badarg).
 
 %% @doc Determine if DocId belongs in shard (identified by record or filename)
-belongs(#shard{}=Shard, DocId) when is_binary(DocId) ->
+%% NOTE: only supported for design documents
+belongs(#shard{}=Shard, <<"_design/", _/binary>> = DocId) ->
     [Begin, End] = range(Shard),
     belongs(Begin, End, DocId);
-belongs(<<"shards/", _/binary>> = ShardName, DocId) when is_binary(DocId) ->
+belongs(<<"shards/", _/binary>> = ShardName, <<"_design/", _/binary>> = DocId) ->
     [Begin, End] = range(ShardName),
     belongs(Begin, End, DocId);
-belongs(DbName, DocId) when is_binary(DbName), is_binary(DocId) ->
+belongs(DbName, <<"_design/", _/binary>>) when is_binary(DbName) ->
     true.
 
 belongs(Begin, End, DocId) ->
@@ -331,6 +339,29 @@ engine(Opts) when is_list(Opts) ->
             []
     end.
 
+is_partitioned(DbName0) when is_binary(DbName0) ->
+    DbName = dbname(DbName0),
+    ShardsDbName = ?l2b(config:get("mem3", "shards_db", "_dbs")),
+    NodesDbName = ?l2b(config:get("mem3", "nodes_db", "_nodes")),
+    case DbName of
+        ShardsDbName ->
+            false;
+        NodesDbName ->
+            false;
+        _ ->
+            is_partitioned(mem3:shards(DbName))
+    end;
+
+is_partitioned(Shards) when is_list(Shards) ->
+    lists:all(fun is_partitioned/1, Shards);
+
+is_partitioned(#shard{opts=Opts}) ->
+    couch_util:get_value(partitioned, Opts) == true;
+
+is_partitioned(#ordered_shard{opts=Opts}) ->
+    couch_util:get_value(partitioned, Opts) == true.
+
+
 -ifdef(TEST).
 
 -include_lib("eunit/include/eunit.hrl").
diff --git a/src/mem3/src/mem3_shards.erl b/src/mem3/src/mem3_shards.erl
index da3b69a..c798512 100644
--- a/src/mem3/src/mem3_shards.erl
+++ b/src/mem3/src/mem3_shards.erl
@@ -66,8 +66,22 @@ for_db(DbName, Options) ->
 for_docid(DbName, DocId) ->
     for_docid(DbName, DocId, []).
 
+%% This function performs one or two lookups now as it is not known
+%% ahead of time if the database is partitioned We first ask for the
+%% shards as if the database is not partitioned and then test the
+%% returned shards for a counter-indication that it was.  If so, we
+%% run the function again with the docid hash option enabled.
 for_docid(DbName, DocId, Options) ->
-    HashKey = mem3_util:hash(DocId),
+    Shards = for_docid(DbName, DocId, Options, []),
+    case mem3:is_partitioned(Shards) of
+        true ->
+            for_docid(DbName, DocId, Options, [partitioned]);
+        false ->
+            Shards
+    end.
+
+for_docid(DbName, DocId, Options, HashOptions) ->
+    HashKey = mem3_util:docid_hash(DocId, HashOptions),
     ShardHead = #shard{
         dbname = DbName,
         range = ['$1', '$2'],
@@ -397,7 +411,8 @@ load_shards_from_db(ShardDb, DbName) ->
 
 load_shards_from_disk(DbName, DocId)->
     Shards = load_shards_from_disk(DbName),
-    HashKey = mem3_util:hash(DocId),
+    Options = [{partitioned, mem3:is_partitioned(Shards)}],
+    HashKey = mem3_util:docid_hash(DocId, Options),
     [S || S <- Shards, in_range(S, HashKey)].
 
 in_range(Shard, HashKey) ->
@@ -521,7 +536,6 @@ filter_shards_by_name(Name, Matches, [#shard{name=Name}=S|Ss]) ->
 filter_shards_by_name(Name, Matches, [_|Ss]) ->
     filter_shards_by_name(Name, Matches, Ss).
 
-
 -ifdef(TEST).
 
 -include_lib("eunit/include/eunit.hrl").
diff --git a/src/mem3/src/mem3_util.erl b/src/mem3/src/mem3_util.erl
index e08d375..6832454 100644
--- a/src/mem3/src/mem3_util.erl
+++ b/src/mem3/src/mem3_util.erl
@@ -16,6 +16,7 @@
     n_val/2, to_atom/1, to_integer/1, write_db_doc/1, delete_db_doc/1,
     shard_info/1, ensure_exists/1, open_db_doc/1]).
 -export([is_deleted/1, rotate_list/2]).
+-export([docid_hash/1, docid_hash/2]).
 
 %% do not use outside mem3.
 -export([build_ordered_shards/2, downcast/1]).
@@ -34,6 +35,28 @@ hash(Item) when is_binary(Item) ->
 hash(Item) ->
     erlang:crc32(term_to_binary(Item)).
 
+
+docid_hash(DocId) when is_binary(DocId) ->
+    docid_hash(DocId, []).
+
+docid_hash(<<"_design/", _/binary>> = DocId, _Options) ->
+    erlang:crc32(DocId); % design docs are never placed by partition
+
+docid_hash(DocId, Options) when is_binary(DocId), is_list(Options) ->
+    Data = case lists:member(partitioned, Options) of
+        true ->
+            case binary:split(DocId, <<":">>) of
+                [Partition, _Rest] ->
+                    Partition;
+                _ ->
+                    throw({illegal_docid, <<"doc id must be of form partition:id">>})
+            end;
+        false ->
+            DocId
+    end,
+    erlang:crc32(Data).
+
+
 name_shard(Shard) ->
     name_shard(Shard, "").
 


[couchdb] 06/06: validate new partition arguments

Posted by rn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rnewson pushed a commit to branch user-partitioned-dbs-4
in repository https://gitbox.apache.org/repos/asf/couchdb.git

commit 9e3f4d202436edbafed2cf9015841a9088aef743
Author: Robert Newson <rn...@apache.org>
AuthorDate: Mon Aug 6 19:21:49 2018 +0100

    validate new partition arguments
---
 src/couch_mrview/src/couch_mrview_util.erl | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/src/couch_mrview/src/couch_mrview_util.erl b/src/couch_mrview/src/couch_mrview_util.erl
index 5a94941..092e123 100644
--- a/src/couch_mrview/src/couch_mrview_util.erl
+++ b/src/couch_mrview/src/couch_mrview_util.erl
@@ -574,6 +574,17 @@ validate_args(Args) ->
         _ -> mrverror(<<"Invalid value for `sorted`.">>)
     end,
 
+    case {true == get_extra(Args, partitioned), get_extra(Args, partition)} of
+        {true, undefined} ->
+            mrverror(<<"`partition` parameter is mandatory for queries to this view.">>);
+        {true, _Partition} ->
+            ok;
+        {false, undefined} ->
+            ok;
+        {false, _Partition} ->
+            mrverror(<<"`partition` parameter is not supported in this view.">>)
+    end,
+
     Args#mrargs{
         start_key_docid=SKDocId,
         end_key_docid=EKDocId,


[couchdb] 02/06: Enforce partition:id format in doc ids

Posted by rn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rnewson pushed a commit to branch user-partitioned-dbs-4
in repository https://gitbox.apache.org/repos/asf/couchdb.git

commit 172ef1099ad17d14ea2228461526f94a10634959
Author: Robert Newson <rn...@apache.org>
AuthorDate: Thu Aug 2 14:41:03 2018 +0100

    Enforce partition:id format in doc ids
---
 src/couch/src/couch_doc.erl        |  26 ++++++++++++++++++++++----
 src/couch/test/fixtures/test.couch | Bin 16482 -> 0 bytes
 2 files changed, 22 insertions(+), 4 deletions(-)

diff --git a/src/couch/src/couch_doc.erl b/src/couch/src/couch_doc.erl
index f960ec5..9caa5ee 100644
--- a/src/couch/src/couch_doc.erl
+++ b/src/couch/src/couch_doc.erl
@@ -133,6 +133,12 @@ from_json_obj_validate(EJson) ->
 from_json_obj_validate(EJson, DbName) ->
     MaxSize = config:get_integer("couchdb", "max_document_size", 4294967296),
     Doc = from_json_obj(EJson, DbName),
+    case is_binary(DbName) andalso mem3:is_partitioned(DbName) of
+        true ->
+            couch_doc:validate_docid(Doc#doc.id, DbName);
+        false ->
+            ok
+    end,
     case couch_ejson_size:encoded_size(Doc#doc.body) =< MaxSize of
         true ->
              validate_attachment_sizes(Doc#doc.atts),
@@ -199,11 +205,23 @@ parse_revs(_) ->
 
 
 validate_docid(DocId, DbName) ->
-    case DbName =:= ?l2b(config:get("mem3", "shards_db", "_dbs")) andalso
-        lists:member(DocId, ?SYSTEM_DATABASES) of
-        true ->
+    SystemId = DbName =:= ?l2b(config:get("mem3", "shards_db", "_dbs")) andalso
+        lists:member(DocId, ?SYSTEM_DATABASES),
+    Partitioned = is_binary(DbName) andalso mem3:is_partitioned(DbName),
+    case {SystemId, Partitioned} of
+        {true, _} ->
             ok;
-        false ->
+        {false, true} ->
+            case binary:split(DocId, <<":">>) of
+                [<<"_design/", _/binary>> | _Rest] ->
+                    validate_docid(DocId);
+                [Partition, Rest] ->
+                    ok = validate_docid(Partition),
+                    validate_docid(Rest);
+                _ ->
+                    throw({illegal_docid, <<"doc id must be of form partition:id">>})
+            end;
+        {false, false} ->
             validate_docid(DocId)
     end.
 
diff --git a/src/couch/test/fixtures/test.couch b/src/couch/test/fixtures/test.couch
deleted file mode 100644
index 32c79af..0000000
Binary files a/src/couch/test/fixtures/test.couch and /dev/null differ


[couchdb] 05/06: Select only the shard containing the partition, if specified

Posted by rn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rnewson pushed a commit to branch user-partitioned-dbs-4
in repository https://gitbox.apache.org/repos/asf/couchdb.git

commit 79e204b356522329e8739da3a70cc4dc5b3764c3
Author: Robert Newson <rn...@apache.org>
AuthorDate: Mon Aug 6 19:16:09 2018 +0100

    Select only the shard containing the partition, if specified
---
 src/fabric/src/fabric_util.erl |  1 -
 src/fabric/src/fabric_view.erl | 27 +++++++++++++++++++++++----
 2 files changed, 23 insertions(+), 5 deletions(-)

diff --git a/src/fabric/src/fabric_util.erl b/src/fabric/src/fabric_util.erl
index dd4b80d..4d2f2c7 100644
--- a/src/fabric/src/fabric_util.erl
+++ b/src/fabric/src/fabric_util.erl
@@ -64,7 +64,6 @@ stream_start(Workers0, Keypos, StartFun, Replacements) ->
     Timeout = request_timeout(),
     case rexi_utils:recv(Workers0, Keypos, Fun, Acc, Timeout, infinity) of
         {ok, #stream_acc{workers=Workers}} ->
-            true = fabric_view:is_progress_possible(Workers),
             AckedWorkers = fabric_dict:fold(fun(Worker, From, WorkerAcc) ->
                 rexi:stream_start(From),
                 [Worker | WorkerAcc]
diff --git a/src/fabric/src/fabric_view.erl b/src/fabric/src/fabric_view.erl
index 69f4290..eae4cd6 100644
--- a/src/fabric/src/fabric_view.erl
+++ b/src/fabric/src/fabric_view.erl
@@ -309,10 +309,29 @@ index_of(X, [X|_Rest], I) ->
 index_of(X, [_|Rest], I) ->
     index_of(X, Rest, I+1).
 
-get_shards(DbName, #mrargs{stable=true}) ->
-    mem3:ushards(DbName);
-get_shards(DbName, #mrargs{stable=false}) ->
-    mem3:shards(DbName).
+
+get_shards(DbName, #mrargs{} = Args) ->
+    Partitioned = couch_mrview_util:get_extra(Args, partitioned),
+    case {Args#mrargs.stable, Partitioned} of
+        {true, false} ->
+            mem3:ushards(DbName);
+        {true, true} ->
+            mem3:ushards(DbName, partition_docid(Args));
+        {false, false} ->
+            mem3:shards(DbName);
+        {false, true} ->
+            mem3:shards(DbName, partition_docid(Args))
+    end.
+
+% create a fake docid within the specified partition.
+partition_docid(Args) ->
+    case couch_mrview_util:get_extra(Args, partition) of
+        undefined ->
+            undefined;
+        Partition when is_binary(Partition) ->
+            <<Partition/binary, ":foo">>
+    end.
+
 
 maybe_update_others(DbName, DDoc, ShardsInvolved, ViewName,
     #mrargs{update=lazy} = Args) ->


[couchdb] 04/06: Allow partitioned option in mrviews

Posted by rn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rnewson pushed a commit to branch user-partitioned-dbs-4
in repository https://gitbox.apache.org/repos/asf/couchdb.git

commit 842da324d838b458155dde408c2fe526352a0dfc
Author: Robert Newson <rn...@apache.org>
AuthorDate: Mon Aug 6 18:18:33 2018 +0100

    Allow partitioned option in mrviews
    
    Default to database's partitioned setting if not present in ddoc.
---
 src/chttpd/src/chttpd_db.erl                |  4 ++--
 src/couch_mrview/src/couch_mrview.erl       |  5 +++++
 src/couch_mrview/src/couch_mrview_http.erl  |  3 +++
 src/couch_mrview/src/couch_mrview_index.erl |  4 +++-
 src/couch_mrview/src/couch_mrview_util.erl  | 11 +++++++++++
 src/fabric/include/fabric.hrl               |  3 ++-
 src/fabric/src/fabric.erl                   | 25 +++++++++++++++++++------
 7 files changed, 45 insertions(+), 10 deletions(-)

diff --git a/src/chttpd/src/chttpd_db.erl b/src/chttpd/src/chttpd_db.erl
index 0905559..57d85e1 100644
--- a/src/chttpd/src/chttpd_db.erl
+++ b/src/chttpd/src/chttpd_db.erl
@@ -1607,8 +1607,8 @@ set_namespace(<<"_local_docs">>, Args) ->
     set_namespace(<<"_local">>, Args);
 set_namespace(<<"_design_docs">>, Args) ->
     set_namespace(<<"_design">>, Args);
-set_namespace(NS, #mrargs{extra = Extra} = Args) ->
-    Args#mrargs{extra = [{namespace, NS} | Extra]}.
+set_namespace(NS, #mrargs{} = Args) ->
+    couch_mrview_util:set_extra(Args, namespace, NS).
 
 
 %% /db/_bulk_get stuff
diff --git a/src/couch_mrview/src/couch_mrview.erl b/src/couch_mrview/src/couch_mrview.erl
index 533dd2d..db467f0 100644
--- a/src/couch_mrview/src/couch_mrview.erl
+++ b/src/couch_mrview/src/couch_mrview.erl
@@ -57,6 +57,9 @@ validate_ddoc_fields(DDoc) ->
         [{<<"language">>, string}],
         [{<<"lists">>, object}, {any, [object, string]}],
         [{<<"options">>, object}],
+        [{<<"options">>, object}, {<<"include_design">>, boolean}],
+        [{<<"options">>, object}, {<<"partitioned">>, boolean}],
+        [{<<"options">>, object}, {<<"local_seq">>, boolean}],
         [{<<"rewrites">>, [string, array]}],
         [{<<"shows">>, object}, {any, [object, string]}],
         [{<<"updates">>, object}, {any, [object, string]}],
@@ -133,6 +136,8 @@ validate_ddoc_field(Value, array) when is_list(Value) ->
     ok;
 validate_ddoc_field({Value}, object) when is_list(Value) ->
     ok;
+validate_ddoc_field(Value, boolean) when is_boolean(Value) ->
+    ok;
 validate_ddoc_field({Props}, {any, Type}) ->
     validate_ddoc_field1(Props, Type);
 validate_ddoc_field({Props}, {Key, Type}) ->
diff --git a/src/couch_mrview/src/couch_mrview_http.erl b/src/couch_mrview/src/couch_mrview_http.erl
index 004caef..86df796 100644
--- a/src/couch_mrview/src/couch_mrview_http.erl
+++ b/src/couch_mrview/src/couch_mrview_http.erl
@@ -582,6 +582,9 @@ parse_param(Key, Val, Args, IsDecoded) ->
             Args#mrargs{callback=couch_util:to_binary(Val)};
         "sorted" ->
             Args#mrargs{sorted=parse_boolean(Val)};
+        "partition" ->
+            Partition = couch_util:to_binary(Val),
+            couch_mrview_util:set_extra(Args, partition, Partition);
         _ ->
             BKey = couch_util:to_binary(Key),
             BVal = couch_util:to_binary(Val),
diff --git a/src/couch_mrview/src/couch_mrview_index.erl b/src/couch_mrview/src/couch_mrview_index.erl
index 5d285d6..2d462d9 100644
--- a/src/couch_mrview/src/couch_mrview_index.erl
+++ b/src/couch_mrview/src/couch_mrview_index.erl
@@ -38,10 +38,12 @@ get(update_options, #mrst{design_opts = Opts}) ->
     LocalSeq = couch_util:get_value(<<"local_seq">>, Opts, false),
     SeqIndexed = couch_util:get_value(<<"seq_indexed">>, Opts, false),
     KeySeqIndexed = couch_util:get_value(<<"keyseq_indexed">>, Opts, false),
+    Partitioned = couch_util:get_value(<<"partitioned">>, Opts, false),
     if IncDesign -> [include_design]; true -> [] end
         ++ if LocalSeq -> [local_seq]; true -> [] end
         ++ if KeySeqIndexed -> [keyseq_indexed]; true -> [] end
-        ++ if SeqIndexed -> [seq_indexed]; true -> [] end;
+        ++ if SeqIndexed -> [seq_indexed]; true -> [] end
+        ++ if Partitioned -> [partitioned]; true -> [] end;
 get(fd, #mrst{fd = Fd}) ->
     Fd;
 get(language, #mrst{language = Language}) ->
diff --git a/src/couch_mrview/src/couch_mrview_util.erl b/src/couch_mrview/src/couch_mrview_util.erl
index 120a9b8..5a94941 100644
--- a/src/couch_mrview/src/couch_mrview_util.erl
+++ b/src/couch_mrview/src/couch_mrview_util.erl
@@ -30,6 +30,7 @@
 -export([extract_view/4, extract_view_reduce/1]).
 -export([get_view_keys/1, get_view_queries/1]).
 -export([set_view_type/3]).
+-export([set_extra/3, get_extra/2]).
 -export([changes_key_opts/2]).
 -export([fold_changes/4]).
 -export([to_key_seq/1]).
@@ -178,6 +179,16 @@ set_view_type(Args, ViewName, [View | Rest]) ->
     end.
 
 
+set_extra(#mrargs{} = Args, Key, Value) ->
+    Extra0 = Args#mrargs.extra,
+    Extra1 = lists:ukeysort(1, [{Key, Value} | Extra0]),
+    Args#mrargs{extra = Extra1}.
+
+
+get_extra(#mrargs{} = Args, Key) ->
+    couch_util:get_value(Key, Args#mrargs.extra).
+
+
 extract_view(_Lang, _Args, _ViewName, []) ->
     throw({not_found, missing_named_view});
 extract_view(Lang, #mrargs{view_type=map}=Args, Name, [View | Rest]) ->
diff --git a/src/fabric/include/fabric.hrl b/src/fabric/include/fabric.hrl
index be1d639..d3e34e1 100644
--- a/src/fabric/include/fabric.hrl
+++ b/src/fabric/include/fabric.hrl
@@ -31,7 +31,8 @@
     lang,
     sorted,
     user_acc,
-    update_seq
+    update_seq,
+    extra=[]
 }).
 
 -record(stream_acc, {
diff --git a/src/fabric/src/fabric.erl b/src/fabric/src/fabric.erl
index f5c7937..98f9280 100644
--- a/src/fabric/src/fabric.erl
+++ b/src/fabric/src/fabric.erl
@@ -353,18 +353,31 @@ query_view(DbName, Options, DDoc, ViewName, Callback, Acc0, QueryArgs0) ->
     false ->
         ok
     end,
-    {ok, #mrst{views=Views, language=Lang}} =
+    {ok, #mrst{views=Views, language=Lang, design_opts=DesignOpts}} =
         couch_mrview_util:ddoc_to_mrst(Db, DDoc),
+
+    DbPartitioned = mem3:is_partitioned(Db),
+    ViewPartitioned = couch_util:get_value(<<"partitioned">>, DesignOpts),
+    Partitioned = if
+        not DbPartitioned ->
+            false;
+        is_boolean(ViewPartitioned) ->
+            ViewPartitioned;
+        true ->
+            DbPartitioned
+    end,
+
     QueryArgs1 = couch_mrview_util:set_view_type(QueryArgs0, View, Views),
-    QueryArgs2 = couch_mrview_util:validate_args(QueryArgs1),
-    VInfo = couch_mrview_util:extract_view(Lang, QueryArgs2, View, Views),
-    case is_reduce_view(QueryArgs2) of
+    QueryArgs2 = couch_mrview_util:set_extra(QueryArgs1, partitioned, Partitioned),
+    QueryArgs3 = couch_mrview_util:validate_args(QueryArgs2),
+    VInfo = couch_mrview_util:extract_view(Lang, QueryArgs3, View, Views),
+    case is_reduce_view(QueryArgs3) of
         true ->
             fabric_view_reduce:go(
                 Db,
                 DDoc,
                 View,
-                QueryArgs2,
+                QueryArgs3,
                 Callback,
                 Acc0,
                 VInfo
@@ -375,7 +388,7 @@ query_view(DbName, Options, DDoc, ViewName, Callback, Acc0, QueryArgs0) ->
                 Options,
                 DDoc,
                 View,
-                QueryArgs2,
+                QueryArgs3,
                 Callback,
                 Acc0,
                 VInfo


[couchdb] 03/06: expose partitioned flag in GET /dbname info

Posted by rn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rnewson pushed a commit to branch user-partitioned-dbs-4
in repository https://gitbox.apache.org/repos/asf/couchdb.git

commit 60f39de11c5b9f914ca90af2eb2ccf8c06a00333
Author: Robert Newson <rn...@apache.org>
AuthorDate: Mon Aug 6 14:45:54 2018 +0100

    expose partitioned flag in GET /dbname info
---
 src/couch/src/couch_db.erl        |  5 +++++
 src/fabric/src/fabric_db_info.erl | 13 +++++++++++--
 2 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/src/couch/src/couch_db.erl b/src/couch/src/couch_db.erl
index 9bb68f8..a5c71d7 100644
--- a/src/couch/src/couch_db.erl
+++ b/src/couch/src/couch_db.erl
@@ -445,6 +445,10 @@ get_db_info(Db) ->
         undefined -> null;
         Else1 -> Else1
     end,
+    Props = case get_props(Db) of
+        undefined -> null;
+        Else2 -> Else2
+    end,
     InfoList = [
         {db_name, Name},
         {engine, couch_db_engine:get_engine(Db)},
@@ -466,6 +470,7 @@ get_db_info(Db) ->
         {disk_format_version, DiskVersion},
         {committed_update_seq, CommittedUpdateSeq},
         {compacted_seq, CompactedSeq},
+        {props, {Props}},
         {uuid, Uuid}
     ],
     {ok, InfoList}.
diff --git a/src/fabric/src/fabric_db_info.erl b/src/fabric/src/fabric_db_info.erl
index 98e8e52..86947fd 100644
--- a/src/fabric/src/fabric_db_info.erl
+++ b/src/fabric/src/fabric_db_info.erl
@@ -107,6 +107,8 @@ merge_results(Info) ->
             [{disk_format_version, lists:max(X)} | Acc];
         (cluster, [X], Acc) ->
             [{cluster, {X}} | Acc];
+        (props, X, Acc) ->
+            [{props, {merge_object(X)}} | Acc];
         (_, _, Acc) ->
             Acc
     end, [{instance_start_time, <<"0">>}], Dict).
@@ -127,10 +129,17 @@ merge_object(Objects) ->
         lists:foldl(fun({K,V},D0) -> orddict:append(K,V,D0) end, D, Props)
     end, orddict:new(), Objects),
     orddict:fold(fun
-        (Key, X, Acc) ->
-            [{Key, lists:sum(X)} | Acc]
+        (Key, [X | _] = Xs, Acc) when is_integer(X) ->
+            [{Key, lists:sum(Xs)} | Acc];
+        (Key, [X | _] = Xs, Acc) when is_boolean(X) ->
+            [{Key, lists:all(fun all_true/1, Xs)} | Acc];
+        (_Key, _X, Acc) ->
+            Acc
     end, [], Dict).
 
+all_true(true) -> true;
+all_true(_)    -> false.
+
 get_cluster_info(Shards) ->
     Dict = lists:foldl(fun(#shard{range = R}, Acc) ->
         dict:update_counter(R, 1, Acc)