1414
1515-export ([try_compile /4 ]).
1616-export ([start_doc_map /3 , map_doc_raw /2 , stop_doc_map /1 , raw_to_ejson /1 ]).
17- -export ([reduce /3 , rereduce /3 , validate_doc_update /6 ]).
17+ -export ([reduce /3 , reduce / 4 , rereduce /3 , rereduce / 4 , validate_doc_update /6 ]).
1818-export ([filter_docs /5 ]).
1919-export ([filter_view /4 ]).
2020-export ([finalize /2 ]).
@@ -108,35 +108,43 @@ finalize(<<"_last", _/binary>>, {_K, _Id, V}) ->
108108finalize (_RedSrc , Reduction ) ->
109109 {ok , Reduction }.
110110
111- rereduce (_Lang , [], _ReducedValues ) ->
111+ rereduce (Lang , RedSrcs , _ReducedValues ) ->
112+ rereduce (Lang , RedSrcs , _ReducedValues , <<>>).
113+
114+ rereduce (_Lang , [], _ReducedValues , _Ctx ) ->
112115 {ok , []};
113- rereduce (Lang , RedSrcs , ReducedValues ) ->
116+ rereduce (Lang , RedSrcs , ReducedValues , Ctx ) ->
114117 Grouped = group_reductions_results (ReducedValues ),
115118 Results = lists :zipwith (
116119 fun
117120 (<<" _" , _ /binary >> = FunSrc , Values ) ->
118- {ok , [Result ]} = builtin_reduce (rereduce , [FunSrc ], [[[], V ] || V <- Values ], []),
121+ {ok , [Result ]} = builtin_reduce (
122+ rereduce , [FunSrc ], [[[], V ] || V <- Values ], [], Ctx
123+ ),
119124 Result ;
120125 (FunSrc , Values ) ->
121- os_rereduce (Lang , [FunSrc ], Values )
126+ os_rereduce (Lang , [FunSrc ], Values , Ctx )
122127 end ,
123128 RedSrcs ,
124129 Grouped
125130 ),
126131 {ok , Results }.
127132
128- reduce (_Lang , [], _KVs ) ->
133+ reduce (Lang , RedSrcs , _KVs ) ->
134+ reduce (Lang , RedSrcs , _KVs , <<>>).
135+
136+ reduce (_Lang , [], _KVs , _Ctx ) ->
129137 {ok , []};
130- reduce (Lang , RedSrcs , KVs ) ->
138+ reduce (Lang , RedSrcs , KVs , Ctx ) ->
131139 {OsRedSrcs , BuiltinReds } = lists :partition (
132140 fun
133141 (<<" _" , _ /binary >>) -> false ;
134142 (_OsFun ) -> true
135143 end ,
136144 RedSrcs
137145 ),
138- {ok , OsResults } = os_reduce (Lang , OsRedSrcs , KVs ),
139- {ok , BuiltinResults } = builtin_reduce (reduce , BuiltinReds , KVs , []),
146+ {ok , OsResults } = os_reduce (Lang , OsRedSrcs , KVs , Ctx ),
147+ {ok , BuiltinResults } = builtin_reduce (reduce , BuiltinReds , KVs , [], Ctx ),
140148 recombine_reduce_results (RedSrcs , OsResults , BuiltinResults , []).
141149
142150recombine_reduce_results ([], [], [], Acc ) ->
@@ -146,12 +154,12 @@ recombine_reduce_results([<<"_", _/binary>> | RedSrcs], OsResults, [BRes | Built
146154recombine_reduce_results ([_OsFun | RedSrcs ], [OsR | OsResults ], BuiltinResults , Acc ) ->
147155 recombine_reduce_results (RedSrcs , OsResults , BuiltinResults , [OsR | Acc ]).
148156
149- os_reduce (_Lang , [], _KVs ) ->
157+ os_reduce (_Lang , [], _KVs , _Ctx ) ->
150158 {ok , []};
151- os_reduce (Lang , OsRedSrcs , KVs ) ->
159+ os_reduce (Lang , OsRedSrcs , KVs , Ctx ) ->
152160 Proc = get_os_process (Lang ),
153161 OsResults =
154- try proc_prompt (Proc , [<<" reduce" >>, OsRedSrcs , KVs ]) of
162+ try proc_prompt (Proc , [<<" reduce" >>, OsRedSrcs , KVs , Ctx ]) of
155163 [true , Reductions ] -> Reductions
156164 catch
157165 throw :{reduce_overflow_error , Msg } ->
@@ -161,11 +169,11 @@ os_reduce(Lang, OsRedSrcs, KVs) ->
161169 end ,
162170 {ok , OsResults }.
163171
164- os_rereduce (Lang , OsRedSrcs , KVs ) ->
172+ os_rereduce (Lang , OsRedSrcs , KVs , Ctx ) ->
165173 case get_overflow_error (KVs ) of
166174 undefined ->
167175 Proc = get_os_process (Lang ),
168- try proc_prompt (Proc , [<<" rereduce" >>, OsRedSrcs , KVs ]) of
176+ try proc_prompt (Proc , [<<" rereduce" >>, OsRedSrcs , KVs , Ctx ]) of
169177 [true , [Reduction ]] -> Reduction
170178 catch
171179 throw :{reduce_overflow_error , Msg } ->
@@ -184,36 +192,36 @@ get_overflow_error([{[{reduce_overflow_error, _}]} = Error | _]) ->
184192get_overflow_error ([_ | Rest ]) ->
185193 get_overflow_error (Rest ).
186194
187- builtin_reduce (_Re , [], _KVs , Acc ) ->
195+ builtin_reduce (_Re , [], _KVs , Acc , _Ctx ) ->
188196 {ok , lists :reverse (Acc )};
189- builtin_reduce (Re , [<<" _sum" , _ /binary >> | BuiltinReds ], KVs , Acc ) ->
197+ builtin_reduce (Re , [<<" _sum" , _ /binary >> | BuiltinReds ], KVs , Acc , Ctx ) ->
190198 Sum = builtin_sum_rows (KVs , 0 ),
191- Red = check_sum_overflow (? term_size (KVs ), ? term_size (Sum ), Sum ),
192- builtin_reduce (Re , BuiltinReds , KVs , [Red | Acc ]);
193- builtin_reduce (reduce , [<<" _count" , _ /binary >> | BuiltinReds ], KVs , Acc ) ->
199+ Red = check_sum_overflow (? term_size (KVs ), ? term_size (Sum ), Sum , Ctx ),
200+ builtin_reduce (Re , BuiltinReds , KVs , [Red | Acc ], Ctx );
201+ builtin_reduce (reduce , [<<" _count" , _ /binary >> | BuiltinReds ], KVs , Acc , Ctx ) ->
194202 Count = length (KVs ),
195- builtin_reduce (reduce , BuiltinReds , KVs , [Count | Acc ]);
196- builtin_reduce (rereduce , [<<" _count" , _ /binary >> | BuiltinReds ], KVs , Acc ) ->
203+ builtin_reduce (reduce , BuiltinReds , KVs , [Count | Acc ], Ctx );
204+ builtin_reduce (rereduce , [<<" _count" , _ /binary >> | BuiltinReds ], KVs , Acc , Ctx ) ->
197205 Count = builtin_sum_rows (KVs , 0 ),
198- builtin_reduce (rereduce , BuiltinReds , KVs , [Count | Acc ]);
199- builtin_reduce (Re , [<<" _stats" , _ /binary >> | BuiltinReds ], KVs , Acc ) ->
206+ builtin_reduce (rereduce , BuiltinReds , KVs , [Count | Acc ], Ctx );
207+ builtin_reduce (Re , [<<" _stats" , _ /binary >> | BuiltinReds ], KVs , Acc , Ctx ) ->
200208 Stats = builtin_stats (Re , KVs ),
201- builtin_reduce (Re , BuiltinReds , KVs , [Stats | Acc ]);
202- builtin_reduce (Re , [<<" _approx_count_distinct" , _ /binary >> | BuiltinReds ], KVs , Acc ) ->
209+ builtin_reduce (Re , BuiltinReds , KVs , [Stats | Acc ], Ctx );
210+ builtin_reduce (Re , [<<" _approx_count_distinct" , _ /binary >> | BuiltinReds ], KVs , Acc , Ctx ) ->
203211 Distinct = approx_count_distinct (Re , KVs ),
204- builtin_reduce (Re , BuiltinReds , KVs , [Distinct | Acc ]);
205- builtin_reduce (Re , [<<" _top_" , N /binary >> | BuiltinReds ], KVs , Acc ) ->
212+ builtin_reduce (Re , BuiltinReds , KVs , [Distinct | Acc ], Ctx );
213+ builtin_reduce (Re , [<<" _top_" , N /binary >> | BuiltinReds ], KVs , Acc , Ctx ) ->
206214 Top = builtin_rank_n (Re , fun rank_fun_top /2 , binary_to_integer (N ), KVs ),
207- builtin_reduce (Re , BuiltinReds , KVs , [Top | Acc ]);
208- builtin_reduce (Re , [<<" _bottom_" , N /binary >> | BuiltinReds ], KVs , Acc ) ->
215+ builtin_reduce (Re , BuiltinReds , KVs , [Top | Acc ], Ctx );
216+ builtin_reduce (Re , [<<" _bottom_" , N /binary >> | BuiltinReds ], KVs , Acc , Ctx ) ->
209217 Bottom = builtin_rank_n (Re , fun rank_fun_bottom /2 , binary_to_integer (N ), KVs ),
210- builtin_reduce (Re , BuiltinReds , KVs , [Bottom | Acc ]);
211- builtin_reduce (Re , [<<" _first" , _ /binary >> | BuiltinReds ], KVs , Acc ) ->
218+ builtin_reduce (Re , BuiltinReds , KVs , [Bottom | Acc ], Ctx );
219+ builtin_reduce (Re , [<<" _first" , _ /binary >> | BuiltinReds ], KVs , Acc , Ctx ) ->
212220 First = builtin_first_last (Re , fun builtin_cmp_first /2 , KVs ),
213- builtin_reduce (Re , BuiltinReds , KVs , [First | Acc ]);
214- builtin_reduce (Re , [<<" _last" , _ /binary >> | BuiltinReds ], KVs , Acc ) ->
221+ builtin_reduce (Re , BuiltinReds , KVs , [First | Acc ], Ctx );
222+ builtin_reduce (Re , [<<" _last" , _ /binary >> | BuiltinReds ], KVs , Acc , Ctx ) ->
215223 Last = builtin_first_last (Re , fun builtin_cmp_last /2 , KVs ),
216- builtin_reduce (Re , BuiltinReds , KVs , [Last | Acc ]).
224+ builtin_reduce (Re , BuiltinReds , KVs , [Last | Acc ], Ctx ).
217225
218226builtin_sum_rows ([], Acc ) ->
219227 Acc ;
@@ -278,28 +286,29 @@ sum_arrays([X | Xs], [Y | Ys]) when is_number(X), is_number(Y) ->
278286sum_arrays (Else , _ ) ->
279287 throw_sum_error (Else ).
280288
281- check_sum_overflow (InSize , OutSize , Sum ) ->
289+ check_sum_overflow (InSize , OutSize , Sum , Ctx ) ->
282290 Overflowed = OutSize > reduce_limit_threshold () andalso OutSize * reduce_limit_ratio () > InSize ,
283291 case config :get (" query_server_config" , " reduce_limit" , " true" ) of
284292 " true" when Overflowed ->
285- Msg = log_sum_overflow (InSize , OutSize ),
293+ Msg = log_sum_overflow (InSize , OutSize , Ctx ),
286294 {[
287295 {<<" error" >>, <<" builtin_reduce_error" >>},
288296 {<<" reason" >>, Msg }
289297 ]};
290298 " log" when Overflowed ->
291- log_sum_overflow (InSize , OutSize ),
299+ log_sum_overflow (InSize , OutSize , Ctx ),
292300 Sum ;
293301 _ ->
294302 Sum
295303 end .
296304
297- log_sum_overflow (InSize , OutSize ) ->
305+ log_sum_overflow (InSize , OutSize , Ctx ) ->
298306 Fmt =
299307 " Reduce output must shrink more rapidly: "
300308 " input size: ~b "
301- " output size: ~b " ,
302- Msg = iolist_to_binary (io_lib :format (Fmt , [InSize , OutSize ])),
309+ " output size: ~b "
310+ " context: ~s " ,
311+ Msg = iolist_to_binary (io_lib :format (Fmt , [InSize , OutSize , Ctx ])),
303312 couch_log :error (Msg , []),
304313 Msg .
305314
0 commit comments