Kouhei Sutou 2019-04-26 15:43:03 +0900 (Fri, 26 Apr 2019) Revision: 9cdb44cb2f940d9eb68f78f6e081026e9ceeacdf https://github.com/groonga/groonga/commit/9cdb44cb2f940d9eb68f78f6e081026e9ceeacdf Message: window function: add support for context tables Modified files: include/groonga/window_function.h include/groonga/window_function_executor.h lib/grn_window_function.h lib/grn_window_function_executor.h lib/mrb/mrb_window_function_executor.c lib/window_function.c lib/window_function_executor.c lib/window_functions.c Modified: include/groonga/window_function.h (+3 -2) =================================================================== --- include/groonga/window_function.h 2019-04-26 14:43:53 +0900 (fa8068557) +++ include/groonga/window_function.h 2019-04-26 15:43:03 +0900 (ff6423b69) @@ -4,8 +4,7 @@ This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. + License version 2.1 as published by the Free Software Foundation. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -39,6 +38,8 @@ GRN_API grn_rc grn_window_set_direction(grn_ctx *ctx, grn_window_direction direction); GRN_API grn_obj *grn_window_get_table(grn_ctx *ctx, grn_window *window); +GRN_API bool grn_window_is_context_table(grn_ctx *ctx, + grn_window *window); GRN_API grn_obj *grn_window_get_output_column(grn_ctx *ctx, grn_window *window); GRN_API size_t grn_window_get_n_arguments(grn_ctx *ctx, Modified: include/groonga/window_function_executor.h (+4 -0) =================================================================== --- include/groonga/window_function_executor.h 2019-04-26 14:43:53 +0900 (2612b73ef) +++ include/groonga/window_function_executor.h 2019-04-26 15:43:03 +0900 (f7c37c36f) @@ -34,6 +34,10 @@ grn_window_function_executor_add_table(grn_ctx *ctx, grn_window_function_executor *executor, grn_obj *table); GRN_API grn_rc +grn_window_function_executor_add_context_table(grn_ctx *ctx, + grn_window_function_executor *executor, + grn_obj *table); +GRN_API grn_rc grn_window_function_executor_set_source(grn_ctx *ctx, grn_window_function_executor *executor, const char *source, Modified: lib/grn_window_function.h (+3 -2) =================================================================== --- lib/grn_window_function.h 2019-04-26 14:43:53 +0900 (799202f1d) +++ lib/grn_window_function.h 2019-04-26 15:43:03 +0900 (cea1e2abb) @@ -5,8 +5,7 @@ This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. + License version 2.1 as published by the Free Software Foundation. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -24,6 +23,7 @@ typedef struct { grn_obj *table; + bool is_context_table; grn_obj *window_function_call; grn_proc *window_function; grn_obj *arguments; @@ -47,6 +47,7 @@ grn_rc grn_window_reset(grn_ctx *ctx, grn_window *window); grn_rc grn_window_add_record(grn_ctx *ctx, grn_window *window, grn_obj *table, + bool is_context_table, grn_id record_id, grn_obj *window_function_call, grn_obj *output_column); Modified: lib/grn_window_function_executor.h (+1 -0) =================================================================== --- lib/grn_window_function_executor.h 2019-04-26 14:43:53 +0900 (cf14f2fb8) +++ lib/grn_window_function_executor.h 2019-04-26 15:43:03 +0900 (2f7782e02) @@ -26,6 +26,7 @@ extern "C" { struct _grn_window_function_executor { grn_obj tables; + grn_obj is_context_tables; grn_obj source; grn_obj sort_keys; grn_obj group_keys; Modified: lib/mrb/mrb_window_function_executor.c (+18 -0) =================================================================== --- lib/mrb/mrb_window_function_executor.c 2019-04-26 14:43:53 +0900 (44532e25a) +++ lib/mrb/mrb_window_function_executor.c 2019-04-26 15:43:03 +0900 (6900f70d1) @@ -102,6 +102,21 @@ mrb_grn_window_function_executor_add_table(mrb_state *mrb, mrb_value self) } static mrb_value +mrb_grn_window_function_executor_add_context_table(mrb_state *mrb, mrb_value self) +{ + mrb_value mrb_table; + mrb_get_args(mrb, "o", &mrb_table); + + grn_ctx *ctx = (grn_ctx *)mrb->ud; + grn_window_function_executor *executor = DATA_PTR(self); + grn_obj *table = GRN_MRB_DATA_PTR(mrb_table); + grn_window_function_executor_add_context_table(ctx, executor, table); + grn_mrb_ctx_check(mrb); + + return mrb_nil_value(); +} + +static mrb_value mrb_grn_window_function_executor_set_sort_keys(mrb_state *mrb, mrb_value self) { char *keys; @@ -183,6 +198,9 @@ grn_mrb_window_function_executor_init(grn_ctx *ctx) mrb_define_method(mrb, klass, "add_table", mrb_grn_window_function_executor_add_table, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, klass, "add_context_table", + mrb_grn_window_function_executor_add_context_table, + MRB_ARGS_REQ(1)); mrb_define_method(mrb, klass, "source=", mrb_grn_window_function_executor_set_source, MRB_ARGS_REQ(1)); Modified: lib/window_function.c (+30 -1) =================================================================== --- lib/window_function.c 2019-04-26 14:43:53 +0900 (b291f1319) +++ lib/window_function.c 2019-04-26 15:43:03 +0900 (211a4c729) @@ -28,10 +28,12 @@ static void grn_window_shard_init(grn_ctx *ctx, grn_window_shard *shard, grn_obj *table, + bool is_context_table, grn_obj *window_function_call, grn_obj *output_column) { shard->table = table; + shard->is_context_table = is_context_table; shard->window_function_call = window_function_call; grn_expr *expr = (grn_expr *)(window_function_call); shard->window_function = (grn_proc *)(expr->codes[0].value); @@ -167,6 +169,24 @@ grn_window_get_table(grn_ctx *ctx, grn_window *window) GRN_API_RETURN(shard->table); } +bool +grn_window_is_context_table(grn_ctx *ctx, grn_window *window) +{ + GRN_API_ENTER; + + if (!window) { + ERR(GRN_INVALID_ARGUMENT, "[window][is-context-table] window is NULL"); + GRN_API_RETURN(false); + } + + if (window->current_shard < 0) { + GRN_API_RETURN(false); + } + + grn_window_shard *shard = &(window->shards[window->current_shard]); + GRN_API_RETURN(shard->is_context_table); +} + grn_obj * grn_window_get_output_column(grn_ctx *ctx, grn_window *window) { @@ -182,7 +202,11 @@ grn_window_get_output_column(grn_ctx *ctx, grn_window *window) } grn_window_shard *shard = &(window->shards[window->current_shard]); - GRN_API_RETURN(shard->output_column); + if (shard->is_context_table) { + GRN_API_RETURN(NULL); + } else { + GRN_API_RETURN(shard->output_column); + } } size_t @@ -346,6 +370,7 @@ grn_rc grn_window_add_record(grn_ctx *ctx, grn_window *window, grn_obj *table, + bool is_context_table, grn_id record_id, grn_obj *window_function_call, grn_obj *output_column) @@ -365,6 +390,7 @@ grn_window_add_record(grn_ctx *ctx, grn_window_shard_init(ctx, &(window->shards[0]), table, + is_context_table, window_function_call, output_column); window->current_shard = 0; @@ -399,6 +425,7 @@ grn_window_add_record(grn_ctx *ctx, grn_window_shard_init(ctx, &(window->shards[window->n_shards - 1]), table, + is_context_table, window_function_call, output_column); } @@ -644,6 +671,7 @@ grn_table_apply_window_function(grn_ctx *ctx, grn_window_add_record(ctx, &window, table, + false, record_id, window_function_call, output_column); @@ -665,6 +693,7 @@ grn_table_apply_window_function(grn_ctx *ctx, grn_window_add_record(ctx, &window, table, + false, record_id, window_function_call, output_column); Modified: lib/window_function_executor.c (+47 -3) =================================================================== --- lib/window_function_executor.c 2019-04-26 14:43:53 +0900 (f4fba2221) +++ lib/window_function_executor.c 2019-04-26 15:43:03 +0900 (bf3d44398) @@ -26,6 +26,7 @@ grn_window_function_executor_init(grn_ctx *ctx, GRN_API_ENTER; GRN_PTR_INIT(&(executor->tables), GRN_OBJ_VECTOR, GRN_ID_NIL); + GRN_BOOL_INIT(&(executor->is_context_tables), 0); GRN_TEXT_INIT(&(executor->source), 0); GRN_TEXT_INIT(&(executor->sort_keys), 0); GRN_TEXT_INIT(&(executor->group_keys), 0); @@ -118,6 +119,7 @@ grn_window_function_executor_fin(grn_ctx *ctx, GRN_OBJ_FIN(ctx, &(executor->group_keys)); GRN_OBJ_FIN(ctx, &(executor->sort_keys)); GRN_OBJ_FIN(ctx, &(executor->source)); + GRN_OBJ_FIN(ctx, &(executor->is_context_tables)); GRN_OBJ_FIN(ctx, &(executor->tables)); GRN_API_RETURN(GRN_SUCCESS); @@ -182,6 +184,28 @@ grn_window_function_executor_add_table(grn_ctx *ctx, grn_window_function_executor_rewind(ctx, executor); GRN_PTR_PUT(ctx, &(executor->tables), table); + GRN_BOOL_PUT(ctx, &(executor->is_context_tables), false); + + GRN_API_RETURN(ctx->rc); +} + +grn_rc +grn_window_function_executor_add_context_table(grn_ctx *ctx, + grn_window_function_executor *executor, + grn_obj *table) +{ + GRN_API_ENTER; + + if (!executor) { + ERR(GRN_INVALID_ARGUMENT, + "[window-function-executor][context-table][add] executor is NULL"); + GRN_API_RETURN(ctx->rc); + } + + grn_window_function_executor_rewind(ctx, executor); + + GRN_PTR_PUT(ctx, &(executor->tables), table); + GRN_BOOL_PUT(ctx, &(executor->is_context_tables), true); GRN_API_RETURN(ctx->rc); } @@ -326,9 +350,22 @@ grn_window_function_executor_execute(grn_ctx *ctx, const bool is_ascending = grn_window_function_executor_is_ascending(ctx, executor); + bool in_before_context = true; + bool in_after_context = false; for (size_t i = 0; i < n_tables; i++) { size_t nth_table = (is_ascending ? i : (n_tables - i - 1)); grn_obj *table = GRN_PTR_VALUE_AT(&(executor->tables), nth_table); + const bool is_context_table = + GRN_BOOL_VALUE_AT(&(executor->is_context_tables), nth_table); + if (in_before_context) { + if (!is_context_table) { + in_before_context = false; + } + } else if (!in_after_context) { + if (is_context_table) { + in_after_context = true; + } + } grn_obj *output_column = grn_obj_column(ctx, table, @@ -556,15 +593,21 @@ grn_window_function_executor_execute(grn_ctx *ctx, if (is_group_key_changed && !grn_window_is_empty(ctx, &(executor->window))) { - grn_window_execute(ctx, &(executor->window)); - if (ctx->rc != GRN_SUCCESS) { - break; + if (!in_before_context) { + grn_window_execute(ctx, &(executor->window)); + if (ctx->rc != GRN_SUCCESS) { + break; + } } grn_window_reset(ctx, &(executor->window)); + if (in_after_context) { + break; + } } grn_window_add_record(ctx, &(executor->window), table, + is_context_table, record_id, window_function_call, output_column); @@ -582,6 +625,7 @@ grn_window_function_executor_execute(grn_ctx *ctx, grn_window_add_record(ctx, &(executor->window), table, + is_context_table, record_id, window_function_call, output_column); Modified: lib/window_functions.c (+15 -5) =================================================================== --- lib/window_functions.c 2019-04-26 14:43:53 +0900 (9d23bde81) +++ lib/window_functions.c 2019-04-26 15:43:03 +0900 (79ca24b94) @@ -35,7 +35,9 @@ window_record_number(grn_ctx *ctx, while ((id = grn_window_next(ctx, window))) { GRN_UINT32_SET(ctx, &value, nth_record); grn_obj *output_column = grn_window_get_output_column(ctx, window); - grn_obj_set_value(ctx, output_column, id, &value, GRN_OBJ_SET); + if (output_column) { + grn_obj_set_value(ctx, output_column, id, &value, GRN_OBJ_SET); + } nth_record++; } GRN_OBJ_FIN(ctx, &value); @@ -200,7 +202,9 @@ window_sum(grn_ctx *ctx, break; } grn_obj *output_column = grn_window_get_output_column(ctx, window); - grn_obj_set_value(ctx, output_column, id, &sum, GRN_OBJ_SET); + if (output_column) { + grn_obj_set_value(ctx, output_column, id, &sum, GRN_OBJ_SET); + } } } else { int64_t sum_raw_int64 = 0; @@ -266,7 +270,9 @@ window_sum(grn_ctx *ctx, grn_window_rewind(ctx, window); while ((id = grn_window_next(ctx, window))) { grn_obj *output_column = grn_window_get_output_column(ctx, window); - grn_obj_set_value(ctx, output_column, id, &sum, GRN_OBJ_SET); + if (output_column) { + grn_obj_set_value(ctx, output_column, id, &sum, GRN_OBJ_SET); + } } } @@ -352,7 +358,9 @@ window_count(grn_ctx *ctx, break; } grn_obj *output_column = grn_window_get_output_column(ctx, window); - grn_obj_set_value(ctx, output_column, id, &n_records, GRN_OBJ_SET); + if (output_column) { + grn_obj_set_value(ctx, output_column, id, &n_records, GRN_OBJ_SET); + } } } else { uint32_t n_records_raw = 0; @@ -382,7 +390,9 @@ window_count(grn_ctx *ctx, grn_window_rewind(ctx, window); while ((id = grn_window_next(ctx, window))) { grn_obj *output_column = grn_window_get_output_column(ctx, window); - grn_obj_set_value(ctx, output_column, id, &n_records, GRN_OBJ_SET); + if (output_column) { + grn_obj_set_value(ctx, output_column, id, &n_records, GRN_OBJ_SET); + } } } -------------- next part -------------- An HTML attachment was scrubbed... URL: <https://lists.osdn.me/mailman/archives/groonga-commit/attachments/20190426/2f63b6c4/attachment-0001.html>