@@ -90,6 +90,8 @@ struct registered_func
9090 rarch_query_func func ;
9191};
9292
93+ struct rmsgpack_dom_value intermediate_res ;
94+
9395/* Forward declarations */
9496static struct buffer query_parse_method_call (char * s , size_t len ,
9597 struct buffer buff , struct invocation * invocation , const char * * err );
@@ -254,12 +256,85 @@ static struct rmsgpack_dom_value query_func_glob(
254256 return res ;
255257}
256258
259+ /* Min and max functions will return all entries smaller/larger than previous *
260+ * - in practice, last entry will contain the actual min/max value. *
261+ * Empty result means there is no such field. */
262+ static struct rmsgpack_dom_value query_func_min (
263+ struct rmsgpack_dom_value input ,
264+ unsigned argc , const struct argument * argv )
265+ {
266+ struct rmsgpack_dom_value res ;
267+
268+ res .type = RDT_BOOL ;
269+ res .val .bool_ = 0 ;
270+
271+ switch (input .type )
272+ {
273+ case RDT_INT :
274+ res .val .bool_ = (
275+ (input .val .int_ == 0 )
276+ || (input .val .int_ < intermediate_res .val .int_ )
277+ || (intermediate_res .val .int_ == 0 ));
278+ if (res .val .bool_ || intermediate_res .val .int_ == 0 )
279+ memcpy (& intermediate_res , & input , sizeof (intermediate_res ));
280+ break ;
281+ case RDT_UINT :
282+ res .val .bool_ = (
283+ (input .val .uint_ == 0 )
284+ || (input .val .uint_ < intermediate_res .val .uint_ )
285+ || (intermediate_res .val .uint_ == 0 ));
286+ if (res .val .bool_ || intermediate_res .val .uint_ == 0 )
287+ memcpy (& intermediate_res , & input , sizeof (intermediate_res ));
288+ break ;
289+ default :
290+ break ;
291+ }
292+
293+ return res ;
294+ }
295+
296+ static struct rmsgpack_dom_value query_func_max (
297+ struct rmsgpack_dom_value input ,
298+ unsigned argc , const struct argument * argv )
299+ {
300+ struct rmsgpack_dom_value res ;
301+
302+ res .type = RDT_BOOL ;
303+ res .val .bool_ = 0 ;
304+
305+ switch (input .type )
306+ {
307+ case RDT_INT :
308+ res .val .bool_ = (
309+ (input .val .int_ == 0 )
310+ || (input .val .int_ > intermediate_res .val .int_ )
311+ || (intermediate_res .val .int_ == 0 ));
312+ if (res .val .bool_ || intermediate_res .val .int_ == 0 )
313+ memcpy (& intermediate_res , & input , sizeof (intermediate_res ));
314+ break ;
315+ case RDT_UINT :
316+ res .val .bool_ = (
317+ (input .val .uint_ == 0 )
318+ || (input .val .uint_ > intermediate_res .val .uint_ )
319+ || (intermediate_res .val .uint_ == 0 ));
320+ if (res .val .bool_ || intermediate_res .val .uint_ == 0 )
321+ memcpy (& intermediate_res , & input , sizeof (intermediate_res ));
322+ break ;
323+ default :
324+ break ;
325+ }
326+
327+ return res ;
328+ }
329+
257330struct registered_func registered_functions [100 ] = {
258331 {"is_true" , query_func_is_true },
259332 {"or" , query_func_operator_or },
260333 {"and" , query_func_operator_and },
261334 {"between" , query_func_between },
262335 {"glob" , query_func_glob },
336+ {"min" , query_func_min },
337+ {"max" , query_func_max },
263338 {NULL , NULL }
264339};
265340
@@ -905,6 +980,9 @@ void *libretrodb_query_compile(libretrodb_t *db,
905980 struct query * q = (struct query * )malloc (sizeof (* q ));
906981 size_t err_buff_len = sizeof (tmp_err_buff );
907982
983+ intermediate_res .val .int_ = 0 ;
984+ intermediate_res .val .uint_ = 0 ;
985+
908986 if (!q )
909987 return NULL ;
910988
0 commit comments