summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Newson <rnewson@apache.org>2018-09-10 11:56:56 +0100
committerRobert Newson <rnewson@apache.org>2018-09-17 21:21:16 +0100
commit626a58a0cf0e1045024be7d2937a3ac67548497b (patch)
treef0636bc41ca6fd580145c1fd94e3f95270242ef7
parent56c9c442622eb4fe2960f0157c00367f4b576af7 (diff)
downloadcouchdb-626a58a0cf0e1045024be7d2937a3ac67548497b.tar.gz
allow partitioned:true in _index post. merge somewhere
-rw-r--r--src/mango/src/mango_cursor_view.erl21
-rw-r--r--src/mango/src/mango_httpd.erl4
-rw-r--r--src/mango/src/mango_idx.erl44
-rw-r--r--src/mango/src/mango_idx.hrl1
-rw-r--r--src/mango/src/mango_idx_view.erl16
-rw-r--r--src/mango/src/mango_opts.erl10
6 files changed, 74 insertions, 22 deletions
diff --git a/src/mango/src/mango_cursor_view.erl b/src/mango/src/mango_cursor_view.erl
index 708a73e13..3eedf9931 100644
--- a/src/mango/src/mango_cursor_view.erl
+++ b/src/mango/src/mango_cursor_view.erl
@@ -103,20 +103,15 @@ base_args(#cursor{index = Idx, opts = Opts} = Cursor) ->
end_key = mango_idx:end_key(Idx, Cursor#cursor.ranges),
include_docs = true
},
- Args2 = case mem3:is_partitioned(Idx#idx.dbname) of
- true ->
- Partition = couch_util:get_value(partition, Opts),
- add_partition_opts(Args1, Partition);
- false ->
- Args1
+ Partitioned = couch_util:get_value(partitioned, Idx#idx.design_opts),
+ Args2 = couch_mrview_util:set_extra(Args1, partitioned, Partitioned),
+ Args3 = case couch_util:get_value(partition, Opts) of
+ <<>> ->
+ Args2;
+ Partition ->
+ couch_mrview_util:set_extra(Args2, partition, Partition)
end,
- add_style(Idx, Args2).
-
-add_partition_opts(#mrargs{} = Args, <<>>) ->
- Args;
-add_partition_opts(#mrargs{} = Args, Partition) ->
- Args1 = couch_mrview_util:set_extra(Args, partitioned, true),
- couch_mrview_util:set_extra(Args1, partition, Partition).
+ add_style(Idx, Args3).
add_style(#idx{def = all_docs}, Args) ->
couch_mrview_util:set_extra(Args, style, all_docs);
diff --git a/src/mango/src/mango_httpd.erl b/src/mango/src/mango_httpd.erl
index d9589b3e8..77a73c112 100644
--- a/src/mango/src/mango_httpd.erl
+++ b/src/mango/src/mango_httpd.erl
@@ -104,9 +104,9 @@ handle_index_req(#httpd{method='GET', path_parts=[_, _]}=Req, Db) ->
JsonIdxs = lists:sublist(JsonIdxs0, Skip+1, Limit),
chttpd:send_json(Req, {[{total_rows, TotalRows}, {indexes, JsonIdxs}]});
-handle_index_req(#httpd{method='POST', path_parts=[_, _]}=Req, Db) ->
+handle_index_req(#httpd{method='POST', path_parts=[DbName, _]}=Req, Db) ->
chttpd:validate_ctype(Req, "application/json"),
- {ok, Opts} = mango_opts:validate_idx_create(chttpd:json_body_obj(Req)),
+ {ok, Opts} = mango_opts:validate_idx_create(DbName, chttpd:json_body_obj(Req)),
{ok, Idx0} = mango_idx:new(Db, Opts),
{ok, Idx} = mango_idx:validate_new(Idx0, Db),
DbOpts = [{user_ctx, Req#httpd.user_ctx}, deleted, ejson_body],
diff --git a/src/mango/src/mango_idx.erl b/src/mango/src/mango_idx.erl
index 8af92b946..e051218f4 100644
--- a/src/mango/src/mango_idx.erl
+++ b/src/mango/src/mango_idx.erl
@@ -58,8 +58,9 @@ list(Db) ->
get_usable_indexes(Db, Selector, Opts) ->
- ExistingIndexes = mango_idx:list(Db),
-
+ PQ = is_partitioned_query(Opts),
+ ExistingIndexes = filter_indexes_by_partitioned(
+ mango_idx:list(Db), PQ),
GlobalIndexes = mango_cursor:remove_indexes_with_partial_filter_selector(ExistingIndexes),
UserSpecifiedIndex = mango_cursor:maybe_filter_indexes_by_ddoc(ExistingIndexes, Opts),
UsableIndexes0 = lists:usort(GlobalIndexes ++ UserSpecifiedIndex),
@@ -68,13 +69,36 @@ get_usable_indexes(Db, Selector, Opts) ->
UsableFilter = fun(I) -> is_usable(I, Selector, SortFields) end,
case lists:filter(UsableFilter, UsableIndexes0) of
- [] ->
+ [] ->
?MANGO_ERROR({no_usable_index, missing_sort_index});
- UsableIndexes ->
+ UsableIndexes ->
UsableIndexes
end.
+filter_indexes_by_partitioned(Indexes, PQ) ->
+ filter_indexes_by_partitioned(Indexes, PQ, []).
+
+
+filter_indexes_by_partitioned([], _PQ, Acc) ->
+ lists:reverse(Acc);
+filter_indexes_by_partitioned([Idx | Rest], PQ, Acc) ->
+ {partitioned, PI} = lists:keyfind(partitioned, 1, Idx#idx.design_opts),
+ case {Idx#idx.def, PI, PQ} of
+ {all_docs, _, _} ->
+ % all_docs works both ways.
+ filter_indexes_by_partitioned(Rest, PQ, [Idx | Acc]);
+ {_, Same, Same} ->
+ filter_indexes_by_partitioned(Rest, PQ, [Idx | Acc]);
+ {_, _, _} ->
+ filter_indexes_by_partitioned(Rest, PQ, Acc)
+ end.
+
+
+is_partitioned_query(Opts) ->
+ lists:keyfind(partition, 1, Opts) /= {partition, <<>>}.
+
+
recover(Db) ->
{ok, DDocs0} = mango_util:open_ddocs(Db),
Pred = fun({Props}) ->
@@ -101,6 +125,7 @@ get_sort_fields(Opts) ->
new(Db, Opts) ->
Def = get_idx_def(Opts),
+ DesignOpts = get_idx_design_opts(Db, Opts),
Type = get_idx_type(Opts),
IdxName = get_idx_name(Def, Opts),
DDoc = get_idx_ddoc(Def, Opts),
@@ -110,6 +135,7 @@ new(Db, Opts) ->
name = IdxName,
type = Type,
def = Def,
+ design_opts = DesignOpts,
opts = filter_opts(Opts)
}}.
@@ -182,11 +208,13 @@ from_ddoc(Db, {Props}) ->
special(Db) ->
+ Partitioned = mem3:is_partitioned(Db),
AllDocs = #idx{
dbname = db_to_name(Db),
name = <<"_all_docs">>,
type = <<"special">>,
def = all_docs,
+ design_opts = [{partitioned, Partitioned}],
opts = []
},
% Add one for _update_seq
@@ -285,6 +313,12 @@ get_idx_def(Opts) ->
end.
+get_idx_design_opts(Db, Opts) ->
+ DbPartitioned = mem3:is_partitioned(couch_db:name(Db)),
+ Partitioned = proplists:get_value(partitioned, Opts, DbPartitioned),
+ [{partitioned, Partitioned}].
+
+
get_idx_type(Opts) ->
case proplists:get_value(type, Opts) of
<<"json">> -> <<"json">>;
@@ -341,6 +375,8 @@ filter_opts([{type, _} | Rest]) ->
filter_opts(Rest);
filter_opts([{w, _} | Rest]) ->
filter_opts(Rest);
+filter_opts([{partitioned, _} | Rest]) ->
+ filter_opts(Rest);
filter_opts([Opt | Rest]) ->
[Opt | filter_opts(Rest)].
diff --git a/src/mango/src/mango_idx.hrl b/src/mango/src/mango_idx.hrl
index 712031b75..179911f46 100644
--- a/src/mango/src/mango_idx.hrl
+++ b/src/mango/src/mango_idx.hrl
@@ -16,5 +16,6 @@
name,
type,
def,
+ design_opts,
opts
}).
diff --git a/src/mango/src/mango_idx_view.erl b/src/mango/src/mango_idx_view.erl
index 2d784b638..ef1ca5912 100644
--- a/src/mango/src/mango_idx_view.erl
+++ b/src/mango/src/mango_idx_view.erl
@@ -54,7 +54,8 @@ add(#doc{body={Props0}}=DDoc, Idx) ->
NewView = make_view(Idx),
Views2 = lists:keystore(element(1, NewView), 1, Views1, NewView),
Props1 = lists:keystore(<<"views">>, 1, Props0, {<<"views">>, {Views2}}),
- {ok, DDoc#doc{body={Props1}}}.
+ Props2 = lists:keystore(<<"options">>, 1, Props1, {<<"options">>, {Idx#idx.design_opts}}),
+ {ok, DDoc#doc{body={Props2}}}.
remove(#doc{body={Props0}}=DDoc, Idx) ->
@@ -78,6 +79,7 @@ remove(#doc{body={Props0}}=DDoc, Idx) ->
from_ddoc({Props}) ->
+ DesignOpts = validate_design_opts(Props),
case lists:keyfind(<<"views">>, 1, Props) of
{<<"views">>, {Views}} when is_list(Views) ->
lists:flatmap(fun({Name, {VProps}}) ->
@@ -89,6 +91,7 @@ from_ddoc({Props}) ->
type = <<"json">>,
name = Name,
def = Def,
+ design_opts = DesignOpts,
opts = Opts
},
[I]
@@ -104,6 +107,7 @@ to_json(Idx) ->
{ddoc, Idx#idx.ddoc},
{name, Idx#idx.name},
{type, Idx#idx.type},
+ {design_opts, {Idx#idx.design_opts}},
{def, {def_to_json(Idx#idx.def)}}
]}.
@@ -248,6 +252,16 @@ validate_ddoc(VProps) ->
end.
+validate_design_opts(Props) ->
+ case lists:keyfind(<<"options">>, 1, Props) of
+ {<<"options">>, {[{<<"partitioned">>, P}]}}
+ when is_boolean(P) ->
+ [{partitioned, P}];
+ _ ->
+ []
+ end.
+
+
% This function returns a list of indexes that
% can be used to restrict this query. This works by
% searching the selector looking for field names that
diff --git a/src/mango/src/mango_opts.erl b/src/mango/src/mango_opts.erl
index f1b7b60d0..365e248ec 100644
--- a/src/mango/src/mango_opts.erl
+++ b/src/mango/src/mango_opts.erl
@@ -13,7 +13,7 @@
-module(mango_opts).
-export([
- validate_idx_create/1,
+ validate_idx_create/2,
validate_find/1
]).
@@ -43,11 +43,17 @@
-include("mango.hrl").
-validate_idx_create({Props}) ->
+validate_idx_create(DbName, {Props}) ->
Opts = [
{<<"index">>, [
{tag, def}
]},
+ {<<"partitioned">>, [
+ {tag, partitioned},
+ {optional, true},
+ {default, mem3:is_partitioned(DbName)},
+ {validator, fun is_boolean/1}
+ ]},
{<<"type">>, [
{tag, type},
{optional, true},