Kouhei Sutou
null+****@clear*****
Sun Jan 29 23:29:17 JST 2017
Kouhei Sutou 2017-01-29 23:29:17 +0900 (Sun, 29 Jan 2017) New Revision: a7c7ac8d49d86aa880e232df027e9e817aee2576 https://github.com/groonga/groonga/commit/a7c7ac8d49d86aa880e232df027e9e817aee2576 Message: Add "window_sum" window function TODO: Document me Added files: test/command/suite/select/columns/window_function/window_sum/ascending.expected test/command/suite/select/columns/window_function/window_sum/ascending.test test/command/suite/select/columns/window_function/window_sum/descending.expected test/command/suite/select/columns/window_function/window_sum/descending.test Modified files: lib/window_functions.c Modified: lib/window_functions.c (+169 -1) =================================================================== --- lib/window_functions.c 2017-01-29 23:22:58 +0900 (2f5b219) +++ lib/window_functions.c 2017-01-29 23:29:17 +0900 (ad778c2) @@ -1,6 +1,6 @@ /* -*- c-basic-offset: 2 -*- */ /* - Copyright(C) 2016 Brazil + Copyright(C) 2016-2017 Brazil This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -41,6 +41,169 @@ window_record_number(grn_ctx *ctx, return GRN_SUCCESS; } +static grn_rc +window_sum(grn_ctx *ctx, + grn_obj *output_column, + grn_window *window, + grn_obj **args, + int n_args) +{ + grn_id id; + grn_obj *target; + + if (n_args != 1) { + GRN_PLUGIN_ERROR(ctx, + GRN_INVALID_ARGUMENT, + "window_sum(): wrong number of arguments (%d for 1)", + n_args); + return ctx->rc; + } + + target = args[0]; + if (target->header.type != GRN_ACCESSOR) { + grn_obj inspected; + GRN_TEXT_INIT(&inspected, 0); + grn_inspect(ctx, &inspected, target); + GRN_PLUGIN_ERROR(ctx, + GRN_INVALID_ARGUMENT, + "window_sum(): " + "the target column must be accessor: <%.*s>", + (int)GRN_TEXT_LEN(&inspected), + GRN_TEXT_VALUE(&inspected)); + GRN_OBJ_FIN(ctx, &inspected); + return ctx->rc; + } + + { + const grn_id output_column_range_id = grn_obj_get_range(ctx, output_column); + const grn_id target_range_id = grn_obj_get_range(ctx, target); + grn_obj sum; + grn_obj value; + + switch (target_range_id) { + case GRN_DB_INT8 : + case GRN_DB_INT16 : + case GRN_DB_INT32 : + case GRN_DB_INT64 : + case GRN_DB_UINT8 : + case GRN_DB_UINT16 : + case GRN_DB_UINT32 : + case GRN_DB_UINT64 : + case GRN_DB_FLOAT : + break; + default : + { + grn_obj inspected; + GRN_TEXT_INIT(&inspected, 0); + grn_inspect(ctx, &inspected, target); + GRN_PLUGIN_ERROR(ctx, + GRN_INVALID_ARGUMENT, + "window_sum(): " + "the target column must be number column: <%.*s>", + (int)GRN_TEXT_LEN(&inspected), + GRN_TEXT_VALUE(&inspected)); + GRN_OBJ_FIN(ctx, &inspected); + return ctx->rc; + } + break; + } + + switch (output_column_range_id) { + case GRN_DB_INT8 : + case GRN_DB_INT16 : + case GRN_DB_INT32 : + case GRN_DB_INT64 : + GRN_INT64_INIT(&sum, 0); + break; + case GRN_DB_UINT8 : + case GRN_DB_UINT16 : + case GRN_DB_UINT32 : + case GRN_DB_UINT64 : + GRN_UINT64_INIT(&sum, 0); + break; + case GRN_DB_FLOAT : + GRN_FLOAT_INIT(&sum, 0); + break; + default : + { + grn_obj inspected; + GRN_TEXT_INIT(&inspected, 0); + grn_inspect(ctx, &inspected, output_column); + GRN_PLUGIN_ERROR(ctx, + GRN_INVALID_ARGUMENT, + "window_sum(): " + "the output column must be number column: <%.*s>", + (int)GRN_TEXT_LEN(&inspected), + GRN_TEXT_VALUE(&inspected)); + GRN_OBJ_FIN(ctx, &inspected); + return ctx->rc; + } + break; + } + GRN_VOID_INIT(&value); + + while ((id = grn_window_next(ctx, window))) { + GRN_BULK_REWIND(&value); + grn_obj_get_value(ctx, target, id, &value); + switch (target_range_id) { + case GRN_DB_INT8 : + GRN_INT64_SET(ctx, + &sum, + GRN_INT64_VALUE(&sum) + GRN_INT8_VALUE(&value)); + break; + case GRN_DB_INT16 : + GRN_INT64_SET(ctx, + &sum, + GRN_INT64_VALUE(&sum) + GRN_INT16_VALUE(&value)); + break; + case GRN_DB_INT32 : + GRN_INT64_SET(ctx, + &sum, + GRN_INT64_VALUE(&sum) + GRN_INT32_VALUE(&value)); + break; + case GRN_DB_INT64 : + GRN_INT64_SET(ctx, + &sum, + GRN_INT64_VALUE(&sum) + GRN_INT64_VALUE(&value)); + break; + case GRN_DB_UINT8 : + GRN_UINT64_SET(ctx, + &sum, + GRN_UINT64_VALUE(&sum) + GRN_UINT8_VALUE(&value)); + break; + case GRN_DB_UINT16 : + GRN_UINT64_SET(ctx, + &sum, + GRN_UINT64_VALUE(&sum) + GRN_UINT16_VALUE(&value)); + break; + case GRN_DB_UINT32 : + GRN_UINT64_SET(ctx, + &sum, + GRN_UINT64_VALUE(&sum) + GRN_UINT32_VALUE(&value)); + break; + case GRN_DB_UINT64 : + GRN_UINT64_SET(ctx, + &sum, + GRN_UINT64_VALUE(&sum) + GRN_UINT64_VALUE(&value)); + break; + case GRN_DB_FLOAT : + GRN_FLOAT_SET(ctx, + &sum, + GRN_FLOAT_VALUE(&sum) + GRN_FLOAT_VALUE(&value)); + break; + default : + break; + } + grn_obj_set_value(ctx, output_column, id, &sum, GRN_OBJ_SET); + } + + GRN_OBJ_FIN(ctx, &value); + GRN_OBJ_FIN(ctx, &sum); + } + + return GRN_SUCCESS; +} + grn_rc grn_db_init_builtin_window_functions(grn_ctx *ctx) { @@ -51,5 +214,10 @@ grn_db_init_builtin_window_functions(grn_ctx *ctx) grn_window_function_create(ctx, "window_record_number", -1, window_record_number); + + grn_window_function_create(ctx, + "window_sum", -1, + window_sum); + return GRN_SUCCESS; } Added: test/command/suite/select/columns/window_function/window_sum/ascending.expected (+73 -0) 100644 =================================================================== --- /dev/null +++ test/command/suite/select/columns/window_function/window_sum/ascending.expected 2017-01-29 23:29:17 +0900 (23cce63) @@ -0,0 +1,73 @@ +table_create Items TABLE_HASH_KEY ShortText +[[0,0.0,0.0],true] +column_create Items price COLUMN_SCALAR UInt32 +[[0,0.0,0.0],true] +load --table Items +[ +{"_key": "item1", "price": 666}, +{"_key": "item2", "price": 999}, +{"_key": "item3", "price": 777}, +{"_key": "item4", "price": 111}, +{"_key": "item5", "price": 333}, +{"_key": "item6", "price": 222} +] +[[0,0.0,0.0],6] +select Items --columns[sum].stage initial --columns[sum].value 'window_sum(price)' --columns[sum].type UInt32 --columns[sum].window.sort_keys price --output_columns '_key, price, sum' --sort_keys price +[ + [ + 0, + 0.0, + 0.0 + ], + [ + [ + [ + 6 + ], + [ + [ + "_key", + "ShortText" + ], + [ + "price", + "UInt32" + ], + [ + "sum", + "UInt32" + ] + ], + [ + "item4", + 111, + 111 + ], + [ + "item6", + 222, + 333 + ], + [ + "item5", + 333, + 666 + ], + [ + "item1", + 666, + 1332 + ], + [ + "item3", + 777, + 2109 + ], + [ + "item2", + 999, + 3108 + ] + ] + ] +] Added: test/command/suite/select/columns/window_function/window_sum/ascending.test (+20 -0) 100644 =================================================================== --- /dev/null +++ test/command/suite/select/columns/window_function/window_sum/ascending.test 2017-01-29 23:29:17 +0900 (83eb1aa) @@ -0,0 +1,20 @@ +table_create Items TABLE_HASH_KEY ShortText +column_create Items price COLUMN_SCALAR UInt32 + +load --table Items +[ +{"_key": "item1", "price": 666}, +{"_key": "item2", "price": 999}, +{"_key": "item3", "price": 777}, +{"_key": "item4", "price": 111}, +{"_key": "item5", "price": 333}, +{"_key": "item6", "price": 222} +] + +select Items \ + --columns[sum].stage initial \ + --columns[sum].value 'window_sum(price)' \ + --columns[sum].type UInt32 \ + --columns[sum].window.sort_keys price \ + --output_columns '_key, price, sum' \ + --sort_keys price Added: test/command/suite/select/columns/window_function/window_sum/descending.expected (+73 -0) 100644 =================================================================== --- /dev/null +++ test/command/suite/select/columns/window_function/window_sum/descending.expected 2017-01-29 23:29:17 +0900 (100cc53) @@ -0,0 +1,73 @@ +table_create Items TABLE_HASH_KEY ShortText +[[0,0.0,0.0],true] +column_create Items price COLUMN_SCALAR UInt32 +[[0,0.0,0.0],true] +load --table Items +[ +{"_key": "item1", "price": 666}, +{"_key": "item2", "price": 999}, +{"_key": "item3", "price": 777}, +{"_key": "item4", "price": 111}, +{"_key": "item5", "price": 333}, +{"_key": "item6", "price": 222} +] +[[0,0.0,0.0],6] +select Items --columns[sum].stage initial --columns[sum].value 'window_sum(price)' --columns[sum].type UInt32 --columns[sum].window.sort_keys -price --output_columns '_key, price, sum' --sort_keys -price +[ + [ + 0, + 0.0, + 0.0 + ], + [ + [ + [ + 6 + ], + [ + [ + "_key", + "ShortText" + ], + [ + "price", + "UInt32" + ], + [ + "sum", + "UInt32" + ] + ], + [ + "item2", + 999, + 999 + ], + [ + "item3", + 777, + 1776 + ], + [ + "item1", + 666, + 2442 + ], + [ + "item5", + 333, + 2775 + ], + [ + "item6", + 222, + 2997 + ], + [ + "item4", + 111, + 3108 + ] + ] + ] +] Added: test/command/suite/select/columns/window_function/window_sum/descending.test (+20 -0) 100644 =================================================================== --- /dev/null +++ test/command/suite/select/columns/window_function/window_sum/descending.test 2017-01-29 23:29:17 +0900 (153951b) @@ -0,0 +1,20 @@ +table_create Items TABLE_HASH_KEY ShortText +column_create Items price COLUMN_SCALAR UInt32 + +load --table Items +[ +{"_key": "item1", "price": 666}, +{"_key": "item2", "price": 999}, +{"_key": "item3", "price": 777}, +{"_key": "item4", "price": 111}, +{"_key": "item5", "price": 333}, +{"_key": "item6", "price": 222} +] + +select Items \ + --columns[sum].stage initial \ + --columns[sum].value 'window_sum(price)' \ + --columns[sum].type UInt32 \ + --columns[sum].window.sort_keys -price \ + --output_columns '_key, price, sum' \ + --sort_keys -price -------------- next part -------------- HTML����������������������������... 下载