Kouhei Sutou
null+****@clear*****
Tue Mar 21 19:48:01 JST 2017
Kouhei Sutou 2017-03-21 19:48:01 +0900 (Tue, 21 Mar 2017) New Revision: c3a9cbfa7e19ed84ad25a131ff41264fad66816b https://github.com/groonga/groonga/commit/c3a9cbfa7e19ed84ad25a131ff41264fad66816b Message: logical_select: support window function in dynamic column Added files: test/command/suite/sharding/logical_select/drilldowns/columns/window_function/window_record_number/ascending.expected test/command/suite/sharding/logical_select/drilldowns/columns/window_function/window_record_number/ascending.test test/command/suite/sharding/logical_select/drilldowns/columns/window_function/window_record_number/descending.expected test/command/suite/sharding/logical_select/drilldowns/columns/window_function/window_record_number/descending.test Modified files: lib/mrb/mrb_table.c lib/mrb/scripts/table.rb plugins/sharding/logical_select.rb Modified: lib/mrb/mrb_table.c (+33 -0) =================================================================== --- lib/mrb/mrb_table.c 2017-03-21 19:47:06 +0900 (aede797) +++ lib/mrb/mrb_table.c 2017-03-21 19:48:01 +0900 (f7bfb6f) @@ -396,6 +396,37 @@ mrb_grn_table_apply_expression(mrb_state *mrb, mrb_value self) return mrb_nil_value(); } +static mrb_value +mrb_grn_table_apply_window_function_raw(mrb_state *mrb, mrb_value self) +{ + grn_ctx *ctx = (grn_ctx *)mrb->ud; + mrb_value mrb_output_column; + mrb_value mrb_window_definition; + mrb_value mrb_window_function_call; + grn_obj *table; + grn_obj *output_column = NULL; + grn_window_definition *window_definition = NULL; + grn_obj *window_function_call = NULL; + + mrb_get_args(mrb, "ooo", + &mrb_output_column, + &mrb_window_definition, + &mrb_window_function_call); + + table = DATA_PTR(self); + output_column = GRN_MRB_DATA_PTR(mrb_output_column); + window_definition = GRN_MRB_DATA_PTR(mrb_window_definition); + window_function_call = GRN_MRB_DATA_PTR(mrb_window_function_call); + grn_table_apply_window_function(ctx, + table, + output_column, + window_definition, + window_function_call); + grn_mrb_ctx_check(mrb); + + return mrb_nil_value(); +} + void grn_mrb_table_init(grn_ctx *ctx) { @@ -441,5 +472,7 @@ grn_mrb_table_init(grn_ctx *ctx) mrb_define_method(mrb, klass, "apply_expression", mrb_grn_table_apply_expression, MRB_ARGS_REQ(2)); + mrb_define_method(mrb, klass, "apply_window_function_raw", + mrb_grn_table_apply_window_function_raw, MRB_ARGS_REQ(4)); } #endif Modified: lib/mrb/scripts/table.rb (+25 -0) =================================================================== --- lib/mrb/scripts/table.rb 2017-03-21 19:47:06 +0900 (25a8c7a) +++ lib/mrb/scripts/table.rb 2017-03-21 19:48:01 +0900 (75c9189) @@ -42,7 +42,32 @@ module Groonga end end + def apply_window_function(output_column, + window_function_call, + options={}) + ensure_sort_keys_accept_nil(options[:sort_keys]) do |sort_keys| + ensure_sort_keys_accept_nil(options[:group_keys]) do |group_keys| + window_definition = WindowDefinition.new + begin + window_definition.sort_keys = sort_keys + window_definition.group_keys = group_keys + apply_window_function_raw(output_column, + window_definition, + window_function_call) + ensure + window_definition.close + end + end + end + end + private + def ensure_sort_keys_accept_nil(keys, &block) + return yield(nil) if keys.nil? + + ensure_sort_keys(keys, &block) + end + def ensure_sort_keys(keys) if keys.is_a?(::Array) and keys.all? {|key| key.is_a?(TableSortKey)} return yield(keys) Modified: plugins/sharding/logical_select.rb (+10 -2) =================================================================== --- plugins/sharding/logical_select.rb 2017-03-21 19:47:06 +0900 (40c1f42) +++ plugins/sharding/logical_select.rb 2017-03-21 19:48:01 +0900 (3eea6a2) @@ -411,12 +411,14 @@ module Groonga attr_reader :type attr_reader :flags attr_reader :value + attr_reader :window_sort_keys def initialize(label, parameters) @label = label @stage = parameters["stage"] @type = parse_type(parameters["type"]) @flags = parse_flags(parameters["flags"] || "COLUMN_SCALAR") @value = parameters["value"] + @window_sort_keys = parameters["window.sort_keys"] end def close @@ -427,8 +429,14 @@ module Groonga expression = Expression.create(table) begin expression.parse(@value) - expression.condition = condition if condition - table.apply_expression(column, expression) + if @window_sort_keys + table.apply_window_function(column, expression, + :sort_keys => @window_sort_keys, + :group_keys => @window_group_keys) + else + expression.condition = condition if condition + table.apply_expression(column, expression) + end ensure expression.close end Added: test/command/suite/sharding/logical_select/drilldowns/columns/window_function/window_record_number/ascending.expected (+124 -0) 100644 =================================================================== --- /dev/null +++ test/command/suite/sharding/logical_select/drilldowns/columns/window_function/window_record_number/ascending.expected 2017-03-21 19:48:01 +0900 (0f82494) @@ -0,0 +1,124 @@ +plugin_register sharding +[[0,0.0,0.0],true] +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] +table_create Logs_20170315 TABLE_NO_KEY +[[0,0.0,0.0],true] +column_create Logs_20170315 timestamp COLUMN_SCALAR Time +[[0,0.0,0.0],true] +column_create Logs_20170315 item COLUMN_SCALAR Items +[[0,0.0,0.0],true] +table_create Logs_20170316 TABLE_NO_KEY +[[0,0.0,0.0],true] +column_create Logs_20170316 timestamp COLUMN_SCALAR Time +[[0,0.0,0.0],true] +column_create Logs_20170316 item COLUMN_SCALAR Items +[[0,0.0,0.0],true] +table_create Logs_20170317 TABLE_NO_KEY +[[0,0.0,0.0],true] +column_create Logs_20170317 timestamp COLUMN_SCALAR Time +[[0,0.0,0.0],true] +column_create Logs_20170317 item COLUMN_SCALAR Items +[[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] +load --table Logs_20170315 +[ +{"timestamp": "2017/03/15 00:00:00", "item": "item1"}, +{"timestamp": "2017/03/15 01:00:00", "item": "item2"} +] +[[0,0.0,0.0],2] +load --table Logs_20170316 +[ +{"timestamp": "2017/03/16 10:00:00", "item": "item3"}, +{"timestamp": "2017/03/16 11:00:00", "item": "item4"} +] +[[0,0.0,0.0],2] +load --table Logs_20170317 +[ +{"timestamp": "2017/03/17 20:00:00", "item": "item5"}, +{"timestamp": "2017/03/17 20:00:00", "item": "item6"} +] +[[0,0.0,0.0],2] +logical_select Logs --shard_key timestamp --output_columns _id --limit 0 --drilldowns[item].keys item --drilldowns[item].columns[nth_record].stage initial --drilldowns[item].columns[nth_record].type UInt32 --drilldowns[item].columns[nth_record].flags COLUMN_SCALAR --drilldowns[item].columns[nth_record].value 'window_record_number()' --drilldowns[item].columns[nth_record].window.sort_keys price --drilldowns[item].sort_keys 'nth_record' --drilldowns[item].output_columns 'nth_record, _key, price' +[ + [ + 0, + 0.0, + 0.0 + ], + [ + [ + [ + 6 + ], + [ + [ + "_id", + "UInt32" + ] + ] + ], + { + "item": [ + [ + 6 + ], + [ + [ + "nth_record", + "UInt32" + ], + [ + "_key", + "ShortText" + ], + [ + "price", + "UInt32" + ] + ], + [ + 1, + "item4", + 111 + ], + [ + 2, + "item6", + 222 + ], + [ + 3, + "item5", + 333 + ], + [ + 4, + "item1", + 666 + ], + [ + 5, + "item3", + 777 + ], + [ + 6, + "item2", + 999 + ] + ] + } + ] +] Added: test/command/suite/sharding/logical_select/drilldowns/columns/window_function/window_record_number/ascending.test (+59 -0) 100644 =================================================================== --- /dev/null +++ test/command/suite/sharding/logical_select/drilldowns/columns/window_function/window_record_number/ascending.test 2017-03-21 19:48:01 +0900 (769f4dc) @@ -0,0 +1,59 @@ +#@on-error omit +plugin_register sharding +#@on-error default + +table_create Items TABLE_HASH_KEY ShortText +column_create Items price COLUMN_SCALAR UInt32 + +table_create Logs_20170315 TABLE_NO_KEY +column_create Logs_20170315 timestamp COLUMN_SCALAR Time +column_create Logs_20170315 item COLUMN_SCALAR Items + +table_create Logs_20170316 TABLE_NO_KEY +column_create Logs_20170316 timestamp COLUMN_SCALAR Time +column_create Logs_20170316 item COLUMN_SCALAR Items + +table_create Logs_20170317 TABLE_NO_KEY +column_create Logs_20170317 timestamp COLUMN_SCALAR Time +column_create Logs_20170317 item COLUMN_SCALAR Items + +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} +] + +load --table Logs_20170315 +[ +{"timestamp": "2017/03/15 00:00:00", "item": "item1"}, +{"timestamp": "2017/03/15 01:00:00", "item": "item2"} +] + +load --table Logs_20170316 +[ +{"timestamp": "2017/03/16 10:00:00", "item": "item3"}, +{"timestamp": "2017/03/16 11:00:00", "item": "item4"} +] + +load --table Logs_20170317 +[ +{"timestamp": "2017/03/17 20:00:00", "item": "item5"}, +{"timestamp": "2017/03/17 20:00:00", "item": "item6"} +] + +logical_select Logs \ + --shard_key timestamp \ + --output_columns _id \ + --limit 0 \ + --drilldowns[item].keys item \ + --drilldowns[item].columns[nth_record].stage initial \ + --drilldowns[item].columns[nth_record].type UInt32 \ + --drilldowns[item].columns[nth_record].flags COLUMN_SCALAR \ + --drilldowns[item].columns[nth_record].value 'window_record_number()' \ + --drilldowns[item].columns[nth_record].window.sort_keys price \ + --drilldowns[item].sort_keys 'nth_record' \ + --drilldowns[item].output_columns 'nth_record, _key, price' Added: test/command/suite/sharding/logical_select/drilldowns/columns/window_function/window_record_number/descending.expected (+124 -0) 100644 =================================================================== --- /dev/null +++ test/command/suite/sharding/logical_select/drilldowns/columns/window_function/window_record_number/descending.expected 2017-03-21 19:48:01 +0900 (afd7b40) @@ -0,0 +1,124 @@ +plugin_register sharding +[[0,0.0,0.0],true] +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] +table_create Logs_20170315 TABLE_NO_KEY +[[0,0.0,0.0],true] +column_create Logs_20170315 timestamp COLUMN_SCALAR Time +[[0,0.0,0.0],true] +column_create Logs_20170315 item COLUMN_SCALAR Items +[[0,0.0,0.0],true] +table_create Logs_20170316 TABLE_NO_KEY +[[0,0.0,0.0],true] +column_create Logs_20170316 timestamp COLUMN_SCALAR Time +[[0,0.0,0.0],true] +column_create Logs_20170316 item COLUMN_SCALAR Items +[[0,0.0,0.0],true] +table_create Logs_20170317 TABLE_NO_KEY +[[0,0.0,0.0],true] +column_create Logs_20170317 timestamp COLUMN_SCALAR Time +[[0,0.0,0.0],true] +column_create Logs_20170317 item COLUMN_SCALAR Items +[[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] +load --table Logs_20170315 +[ +{"timestamp": "2017/03/15 00:00:00", "item": "item1"}, +{"timestamp": "2017/03/15 01:00:00", "item": "item2"} +] +[[0,0.0,0.0],2] +load --table Logs_20170316 +[ +{"timestamp": "2017/03/16 10:00:00", "item": "item3"}, +{"timestamp": "2017/03/16 11:00:00", "item": "item4"} +] +[[0,0.0,0.0],2] +load --table Logs_20170317 +[ +{"timestamp": "2017/03/17 20:00:00", "item": "item5"}, +{"timestamp": "2017/03/17 20:00:00", "item": "item6"} +] +[[0,0.0,0.0],2] +logical_select Logs --shard_key timestamp --output_columns _id --limit 0 --drilldowns[item].keys item --drilldowns[item].columns[nth_record].stage initial --drilldowns[item].columns[nth_record].type UInt32 --drilldowns[item].columns[nth_record].flags COLUMN_SCALAR --drilldowns[item].columns[nth_record].value 'window_record_number()' --drilldowns[item].columns[nth_record].window.sort_keys -price --drilldowns[item].sort_keys 'nth_record' --drilldowns[item].output_columns 'nth_record, _key, price' +[ + [ + 0, + 0.0, + 0.0 + ], + [ + [ + [ + 6 + ], + [ + [ + "_id", + "UInt32" + ] + ] + ], + { + "item": [ + [ + 6 + ], + [ + [ + "nth_record", + "UInt32" + ], + [ + "_key", + "ShortText" + ], + [ + "price", + "UInt32" + ] + ], + [ + 1, + "item2", + 999 + ], + [ + 2, + "item3", + 777 + ], + [ + 3, + "item1", + 666 + ], + [ + 4, + "item5", + 333 + ], + [ + 5, + "item6", + 222 + ], + [ + 6, + "item4", + 111 + ] + ] + } + ] +] Added: test/command/suite/sharding/logical_select/drilldowns/columns/window_function/window_record_number/descending.test (+59 -0) 100644 =================================================================== --- /dev/null +++ test/command/suite/sharding/logical_select/drilldowns/columns/window_function/window_record_number/descending.test 2017-03-21 19:48:01 +0900 (3c5ef9b) @@ -0,0 +1,59 @@ +#@on-error omit +plugin_register sharding +#@on-error default + +table_create Items TABLE_HASH_KEY ShortText +column_create Items price COLUMN_SCALAR UInt32 + +table_create Logs_20170315 TABLE_NO_KEY +column_create Logs_20170315 timestamp COLUMN_SCALAR Time +column_create Logs_20170315 item COLUMN_SCALAR Items + +table_create Logs_20170316 TABLE_NO_KEY +column_create Logs_20170316 timestamp COLUMN_SCALAR Time +column_create Logs_20170316 item COLUMN_SCALAR Items + +table_create Logs_20170317 TABLE_NO_KEY +column_create Logs_20170317 timestamp COLUMN_SCALAR Time +column_create Logs_20170317 item COLUMN_SCALAR Items + +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} +] + +load --table Logs_20170315 +[ +{"timestamp": "2017/03/15 00:00:00", "item": "item1"}, +{"timestamp": "2017/03/15 01:00:00", "item": "item2"} +] + +load --table Logs_20170316 +[ +{"timestamp": "2017/03/16 10:00:00", "item": "item3"}, +{"timestamp": "2017/03/16 11:00:00", "item": "item4"} +] + +load --table Logs_20170317 +[ +{"timestamp": "2017/03/17 20:00:00", "item": "item5"}, +{"timestamp": "2017/03/17 20:00:00", "item": "item6"} +] + +logical_select Logs \ + --shard_key timestamp \ + --output_columns _id \ + --limit 0 \ + --drilldowns[item].keys item \ + --drilldowns[item].columns[nth_record].stage initial \ + --drilldowns[item].columns[nth_record].type UInt32 \ + --drilldowns[item].columns[nth_record].flags COLUMN_SCALAR \ + --drilldowns[item].columns[nth_record].value 'window_record_number()' \ + --drilldowns[item].columns[nth_record].window.sort_keys -price \ + --drilldowns[item].sort_keys 'nth_record' \ + --drilldowns[item].output_columns 'nth_record, _key, price' -------------- next part -------------- HTML����������������������������...Download