[Groonga-commit] groonga/groonga at 5539c4a [master] select: deprecate --drilldown[...]

Back to archive index

Kouhei Sutou null+****@clear*****
Fri May 20 10:31:01 JST 2016


Kouhei Sutou	2016-05-20 10:31:01 +0900 (Fri, 20 May 2016)

  New Revision: 5539c4a03511fdecc5b4845430181a5b0b979b91
  https://github.com/groonga/groonga/commit/5539c4a03511fdecc5b4845430181a5b0b979b91

  Message:
    select: deprecate --drilldown[...]
    
    Use --drilldowns[...] instead. --drilldown[...] is still available for
    backward compatibility.

  Added files:
    test/command/suite/select/drilldowns/calc_types/multiple/all.expected
    test/command/suite/select/drilldowns/calc_types/multiple/all.test
    test/command/suite/select/drilldowns/calc_types/multiple/avg.expected
    test/command/suite/select/drilldowns/calc_types/multiple/avg.test
    test/command/suite/select/drilldowns/calc_types/multiple/max.expected
    test/command/suite/select/drilldowns/calc_types/multiple/max.test
    test/command/suite/select/drilldowns/calc_types/multiple/min.expected
    test/command/suite/select/drilldowns/calc_types/multiple/min.test
    test/command/suite/select/drilldowns/calc_types/multiple/sum.expected
    test/command/suite/select/drilldowns/calc_types/multiple/sum.test
    test/command/suite/select/drilldowns/calc_types/single/all.expected
    test/command/suite/select/drilldowns/calc_types/single/all.test
    test/command/suite/select/drilldowns/calc_types/single/avg.expected
    test/command/suite/select/drilldowns/calc_types/single/avg.test
    test/command/suite/select/drilldowns/calc_types/single/max.expected
    test/command/suite/select/drilldowns/calc_types/single/max.test
    test/command/suite/select/drilldowns/calc_types/single/min.expected
    test/command/suite/select/drilldowns/calc_types/single/min.test
    test/command/suite/select/drilldowns/calc_types/single/sum.expected
    test/command/suite/select/drilldowns/calc_types/single/sum.test
    test/command/suite/select/drilldowns/column/stage/initial/drilldown.expected
    test/command/suite/select/drilldowns/column/stage/initial/drilldown.test
    test/command/suite/select/drilldowns/column/stage/initial/output_columns.expected
    test/command/suite/select/drilldowns/column/stage/initial/output_columns.test
    test/command/suite/select/drilldowns/columns/stage/initial/drilldown.expected
    test/command/suite/select/drilldowns/columns/stage/initial/drilldown.test
    test/command/suite/select/drilldowns/columns/stage/initial/output_columns.expected
    test/command/suite/select/drilldowns/columns/stage/initial/output_columns.test
    test/command/suite/select/drilldowns/filter/key.test
    test/command/suite/select/drilldowns/filtered/multiple.expected
    test/command/suite/select/drilldowns/filtered/multiple.test
    test/command/suite/select/drilldowns/keys/empty.expected
    test/command/suite/select/drilldowns/keys/empty.test
    test/command/suite/select/drilldowns/keys/multiple.expected
    test/command/suite/select/drilldowns/keys/multiple.test
    test/command/suite/select/drilldowns/keys/one.test
    test/command/suite/select/drilldowns/keys/reference_vector.expected
    test/command/suite/select/drilldowns/keys/reference_vector.test
    test/command/suite/select/drilldowns/keys/vector.expected
    test/command/suite/select/drilldowns/keys/vector.test
    test/command/suite/select/drilldowns/no_keys/no_calc_target.expected
    test/command/suite/select/drilldowns/no_keys/no_calc_target.test
    test/command/suite/select/drilldowns/no_keys/no_table.expected
    test/command/suite/select/drilldowns/no_keys/no_table.test
    test/command/suite/select/drilldowns/no_keys/sum.test
    test/command/suite/select/drilldowns/sort_keys/sub_record_column/multiple.expected
    test/command/suite/select/drilldowns/sort_keys/sub_record_column/multiple.test
    test/command/suite/select/drilldowns/sortby/sub_record_column/multiple.expected
    test/command/suite/select/drilldowns/sortby/sub_record_column/multiple.test
    test/command/suite/select/drilldowns/table/cyclic.test
    test/command/suite/select/drilldowns/table/empty.test
    test/command/suite/select/drilldowns/table/nonexistent.test
    test/command/suite/select/drilldowns/table/one.test
    test/command/suite/select/drilldowns/table/two.expected
    test/command/suite/select/drilldowns/table/two.test
  Copied files:
    test/command/suite/select/drilldowns/filter/key.expected
      (from test/command/suite/select/drilldown/labeled/table/nonexistent.expected)
    test/command/suite/select/drilldowns/keys/one.expected
      (from test/command/suite/select/drilldown/labeled/table/nonexistent.expected)
    test/command/suite/select/drilldowns/no_keys/sum.expected
      (from test/command/suite/select/drilldown/labeled/table/nonexistent.expected)
    test/command/suite/select/drilldowns/table/cyclic.expected
      (from test/command/suite/select/drilldown/labeled/table/cyclic.expected)
    test/command/suite/select/drilldowns/table/empty.expected
      (from test/command/suite/select/drilldown/labeled/table/nonexistent.expected)
    test/command/suite/select/drilldowns/table/nonexistent.expected
      (from test/command/suite/select/drilldown/labeled/table/nonexistent.expected)
    test/command/suite/select/drilldowns/table/one.expected
      (from test/command/suite/select/drilldown/labeled/table/nonexistent.expected)
  Modified files:
    lib/proc/proc_select.c
    test/command/suite/select/drilldown/labeled/table/cyclic.expected
    test/command/suite/select/drilldown/labeled/table/nonexistent.expected

  Modified: lib/proc/proc_select.c (+84 -39)
===================================================================
--- lib/proc/proc_select.c    2016-05-20 10:24:11 +0900 (04ce5d5)
+++ lib/proc/proc_select.c    2016-05-20 10:31:01 +0900 (1d981fa)
@@ -1217,7 +1217,7 @@ grn_select_drilldown_execute(grn_ctx *ctx,
                                 NULL);
     if (dependent_id == GRN_ID_NIL) {
       GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
-                       "[select][drilldown][%.*s][table] "
+                       "[select][drilldowns][%.*s][table] "
                        "nonexistent label: <%.*s>",
                        (int)(drilldown->label.length),
                        drilldown->label.value,
@@ -1291,7 +1291,7 @@ grn_select_drilldown_execute(grn_ctx *ctx,
     if (!expression) {
       GRN_PLUGIN_ERROR(ctx,
                        GRN_INVALID_ARGUMENT,
-                       "[select][drilldown]%s%.*s%s[filter] "
+                       "[select][drilldowns]%s%.*s%s[filter] "
                        "failed to create expression for filter: %s",
                        drilldown->label.length > 0 ? "[" : "",
                        (int)(drilldown->label.length),
@@ -1312,7 +1312,7 @@ grn_select_drilldown_execute(grn_ctx *ctx,
       grn_obj_close(ctx, expression);
       GRN_PLUGIN_ERROR(ctx,
                        GRN_INVALID_ARGUMENT,
-                       "[select][drilldown]%s%.*s%s[filter] "
+                       "[select][drilldowns]%s%.*s%s[filter] "
                        "failed to parse filter: <%.*s>: %s",
                        drilldown->label.length > 0 ? "[" : "",
                        (int)(drilldown->label.length),
@@ -1336,7 +1336,7 @@ grn_select_drilldown_execute(grn_ctx *ctx,
       }
       GRN_PLUGIN_ERROR(ctx,
                        GRN_INVALID_ARGUMENT,
-                       "[select][drilldown]%s%.*s%s[filter] "
+                       "[select][drilldowns]%s%.*s%s[filter] "
                        "failed to execute filter: <%.*s>: %s",
                        drilldown->label.length > 0 ? "[" : "",
                        (int)(drilldown->label.length),
@@ -1501,7 +1501,7 @@ drilldown_tsort_visit(grn_ctx *ctx,
                                          dependent_id);
           if (cycled) {
             GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
-                             "[select][drilldown][%.*s][table] "
+                             "[select][drilldowns][%.*s][table] "
                              "cycled dependency: <%.*s>",
                              (int)(drilldown->label.length),
                              drilldown->label.value,
@@ -2365,7 +2365,7 @@ grn_select_data_drilldowns_add(grn_ctx *ctx,
     if (!data->drilldowns) {
       GRN_PLUGIN_ERROR(ctx,
                        GRN_INVALID_ARGUMENT,
-                       "[select][drilldown] "
+                       "[select][drilldowns] "
                        "failed to allocate drilldowns data: %s",
                        ctx->errbuf);
       return NULL;
@@ -2388,11 +2388,11 @@ grn_select_data_drilldowns_add(grn_ctx *ctx,
 static grn_bool
 grn_select_data_fill_drilldown_labels(grn_ctx *ctx,
                                       grn_user_data *user_data,
-                                      grn_select_data *data)
+                                      grn_select_data *data,
+                                      const char *prefix)
 {
   grn_obj *vars;
   grn_table_cursor *cursor;
-  const char *prefix = "drilldown[";
   int prefix_len;
 
   vars = grn_plugin_proc_get_vars(ctx, user_data);
@@ -2432,6 +2432,28 @@ grn_select_data_fill_drilldown_labels(grn_ctx *ctx,
 }
 
 static grn_bool
+grn_select_data_fill_drilldown_columns(grn_ctx *ctx,
+                                       grn_user_data *user_data,
+                                       grn_drilldown_data *drilldown,
+                                       const char *parameter_key)
+{
+  char prefix[GRN_TABLE_MAX_KEY_SIZE];
+
+  grn_snprintf(prefix,
+               GRN_TABLE_MAX_KEY_SIZE,
+               GRN_TABLE_MAX_KEY_SIZE,
+               "%s[%.*s].",
+               parameter_key,
+               (int)(drilldown->label.length),
+               drilldown->label.value);
+  return grn_columns_fill(ctx,
+                          user_data,
+                          &(drilldown->columns),
+                          prefix,
+                          strlen(prefix));
+}
+
+static grn_bool
 grn_select_data_fill_drilldowns(grn_ctx *ctx,
                                 grn_user_data *user_data,
                                 grn_select_data *data)
@@ -2479,57 +2501,78 @@ grn_select_data_fill_drilldowns(grn_ctx *ctx,
                             grn_plugin_proc_get_var(ctx, user_data,
                                                     "drilldown_filter", -1),
                             NULL);
+    return GRN_TRUE;
   } else {
     grn_bool succeeded = GRN_TRUE;
     unsigned int i;
 
-    if (!grn_select_data_fill_drilldown_labels(ctx, user_data, data)) {
+    if (!grn_select_data_fill_drilldown_labels(ctx, user_data, data,
+                                               "drilldowns[")) {
+      return GRN_FALSE;
+    }
+
+    /* For backward compatibility */
+    if (!grn_select_data_fill_drilldown_labels(ctx, user_data, data,
+                                               "drilldown[")) {
       return GRN_FALSE;
     }
 
     GRN_HASH_EACH_BEGIN(ctx, data->drilldowns, cursor, id) {
       grn_drilldown_data *drilldown;
-      char drilldown_label[GRN_TABLE_MAX_KEY_SIZE];
-      char key_name[GRN_TABLE_MAX_KEY_SIZE];
-      grn_obj *keys;
-      grn_obj *sort_keys;
-      grn_obj *output_columns;
-      grn_obj *offset;
-      grn_obj *limit;
-      grn_obj *calc_types;
-      grn_obj *calc_target;
-      grn_obj *filter;
-      grn_obj *table;
+      grn_obj *keys = NULL;
+      grn_obj *sort_keys = NULL;
+      grn_obj *output_columns = NULL;
+      grn_obj *offset = NULL;
+      grn_obj *limit = NULL;
+      grn_obj *calc_types = NULL;
+      grn_obj *calc_target = NULL;
+      grn_obj *filter = NULL;
+      grn_obj *table = NULL;
 
       grn_hash_cursor_get_value(ctx, cursor, (void **)&drilldown);
 
-      grn_snprintf(drilldown_label,
-                   GRN_TABLE_MAX_KEY_SIZE,
-                   GRN_TABLE_MAX_KEY_SIZE,
-                   "drilldown[%.*s].",
-                   (int)(drilldown->label.length),
-                   drilldown->label.value);
-
-      succeeded = grn_columns_fill(ctx,
-                                   user_data,
-                                   &(drilldown->columns),
-                                   drilldown_label,
-                                   strlen(drilldown_label));
+      succeeded = grn_select_data_fill_drilldown_columns(ctx,
+                                                         user_data,
+                                                         drilldown,
+                                                         "drilldowns");
       if (!succeeded) {
         break;
       }
 
-#define GET_VAR(name)                                                   \
-      grn_snprintf(key_name,                                            \
-                   GRN_TABLE_MAX_KEY_SIZE,                              \
-                   GRN_TABLE_MAX_KEY_SIZE,                              \
-                   "%s%s", drilldown_label, #name);                     \
-      name = grn_plugin_proc_get_var(ctx, user_data, key_name, -1);
+      /* For backward compatibility */
+      succeeded = grn_select_data_fill_drilldown_columns(ctx,
+                                                         user_data,
+                                                         drilldown,
+                                                         "drilldown");
+      if (!succeeded) {
+        break;
+      }
+
+#define GET_VAR_RAW(parameter_key, name) do {                           \
+        if (!name) {                                                    \
+          char key_name[GRN_TABLE_MAX_KEY_SIZE];                        \
+          grn_snprintf(key_name,                                        \
+                       GRN_TABLE_MAX_KEY_SIZE,                          \
+                       GRN_TABLE_MAX_KEY_SIZE,                          \
+                       "%s[%.*s].%s",                                   \
+                       (parameter_key),                                 \
+                       (int)(drilldown->label.length),                  \
+                       drilldown->label.value,                          \
+                       #name);                                          \
+          name = grn_plugin_proc_get_var(ctx, user_data, key_name, -1); \
+        }                                                               \
+      } while (GRN_FALSE)
+
+#define GET_VAR(name) do {                                              \
+        GET_VAR_RAW("drilldowns", name);                                \
+        /* For backward compatibility */                                \
+        GET_VAR_RAW("drilldown", name);                                 \
+      } while (GRN_FALSE)
 
       GET_VAR(keys);
       GET_VAR(sort_keys);
       if (!sort_keys) {
-        grn_obj *sortby;
+        grn_obj *sortby = NULL;
         GET_VAR(sortby);
         sort_keys = sortby;
       }
@@ -2543,6 +2586,8 @@ grn_select_data_fill_drilldowns(grn_ctx *ctx,
 
 #undef GET_VAR
 
+#undef GET_VAR_RAW
+
       grn_drilldown_data_fill(ctx,
                               drilldown,
                               keys,

  Modified: test/command/suite/select/drilldown/labeled/table/cyclic.expected (+3 -3)
===================================================================
--- test/command/suite/select/drilldown/labeled/table/cyclic.expected    2016-05-20 10:24:11 +0900 (1acfbb3)
+++ test/command/suite/select/drilldown/labeled/table/cyclic.expected    2016-05-20 10:31:01 +0900 (e2d21be)
@@ -39,7 +39,7 @@ select Memos   --drilldown[category].table sub_category   --drilldown[category].
       0.0,
       0.0
     ],
-    "[select][drilldown][category][table] cycled dependency: <sub_category>"
+    "[select][drilldowns][category][table] cycled dependency: <sub_category>"
   ],
   [
     [
@@ -85,5 +85,5 @@ select Memos   --drilldown[category].table sub_category   --drilldown[category].
     }
   ]
 ]
-#|e| [select][drilldown][sub_category][table] cycled dependency: <category>
-#|e| [select][drilldown][category][table] cycled dependency: <sub_category>
+#|e| [select][drilldowns][sub_category][table] cycled dependency: <category>
+#|e| [select][drilldowns][category][table] cycled dependency: <sub_category>

  Modified: test/command/suite/select/drilldown/labeled/table/nonexistent.expected (+2 -2)
===================================================================
--- test/command/suite/select/drilldown/labeled/table/nonexistent.expected    2016-05-20 10:24:11 +0900 (2237313)
+++ test/command/suite/select/drilldown/labeled/table/nonexistent.expected    2016-05-20 10:31:01 +0900 (ccc23a3)
@@ -29,7 +29,7 @@ select Memos   --drilldown[category].table nonexistent   --drilldown[category].k
       0.0,
       0.0
     ],
-    "[select][drilldown][category][table] nonexistent label: <nonexistent>"
+    "[select][drilldowns][category][table] nonexistent label: <nonexistent>"
   ],
   [
     [
@@ -75,4 +75,4 @@ select Memos   --drilldown[category].table nonexistent   --drilldown[category].k
     }
   ]
 ]
-#|e| [select][drilldown][category][table] nonexistent label: <nonexistent>
+#|e| [select][drilldowns][category][table] nonexistent label: <nonexistent>

  Added: test/command/suite/select/drilldowns/calc_types/multiple/all.expected (+128 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/select/drilldowns/calc_types/multiple/all.expected    2016-05-20 10:31:01 +0900 (4609781)
@@ -0,0 +1,128 @@
+table_create Tags TABLE_PAT_KEY ShortText
+[[0,0.0,0.0],true]
+table_create Memos TABLE_HASH_KEY ShortText
+[[0,0.0,0.0],true]
+column_create Memos tag COLUMN_SCALAR Tags
+[[0,0.0,0.0],true]
+column_create Memos user COLUMN_SCALAR ShortText
+[[0,0.0,0.0],true]
+column_create Memos priority COLUMN_SCALAR Int64
+[[0,0.0,0.0],true]
+load --table Memos
+[
+{"_key": "Groonga1", "tag": "Groonga", "user": "user1", "priority": 10},
+{"_key": "Groonga2", "tag": "Groonga", "user": "user1", "priority": 20},
+{"_key": "Groonga3", "tag": "Groonga", "user": "user1", "priority": 60},
+{"_key": "Groonga4", "tag": "Groonga", "user": "user2", "priority": 61},
+{"_key": "Groonga5", "tag": "Groonga", "user": "user2", "priority": 24},
+{"_key": "Groonga6", "tag": "Groonga", "user": "user2", "priority": 8},
+{"_key": "Mroonga1", "tag": "Mroonga", "user": "user3", "priority": 7},
+{"_key": "Mroonga2", "tag": "Mroonga", "user": "user3", "priority": 3},
+{"_key": "Mroonga3", "tag": "Mroonga", "user": "user3", "priority": -4},
+{"_key": "Mroonga4", "tag": "Mroonga", "user": "user4", "priority": -1},
+{"_key": "Mroonga5", "tag": "Mroonga", "user": "user4", "priority": -2},
+{"_key": "Mroonga6", "tag": "Mroonga", "user": "user4", "priority": -3}
+]
+[[0,0.0,0.0],12]
+select Memos   --limit 0   --drilldowns[tag].keys tag,user   --drilldowns[tag].calc_types 'AVG, MAX, MIN, SUM'   --drilldowns[tag].calc_target priority   --drilldowns[tag].output_columns _value.tag,_value.user,_max,_min,_sum,_avg
+[
+  [
+    0,
+    0.0,
+    0.0
+  ],
+  [
+    [
+      [
+        12
+      ],
+      [
+        [
+          "_id",
+          "UInt32"
+        ],
+        [
+          "_key",
+          "ShortText"
+        ],
+        [
+          "priority",
+          "Int64"
+        ],
+        [
+          "tag",
+          "Tags"
+        ],
+        [
+          "user",
+          "ShortText"
+        ]
+      ]
+    ],
+    {
+      "tag": [
+        [
+          4
+        ],
+        [
+          [
+            "tag",
+            "Tags"
+          ],
+          [
+            "user",
+            "ShortText"
+          ],
+          [
+            "_max",
+            "Int64"
+          ],
+          [
+            "_min",
+            "Int64"
+          ],
+          [
+            "_sum",
+            "Int64"
+          ],
+          [
+            "_avg",
+            "Float"
+          ]
+        ],
+        [
+          "Groonga",
+          "user1",
+          60,
+          10,
+          90,
+          30.0
+        ],
+        [
+          "Groonga",
+          "user2",
+          61,
+          8,
+          93,
+          31.0
+        ],
+        [
+          "Mroonga",
+          "user3",
+          7,
+          -4,
+          6,
+          2.0
+        ],
+        [
+          "Mroonga",
+          "user4",
+          -1,
+          -3,
+          -6,
+          -2.0
+        ]
+      ]
+    }
+  ]
+]

  Added: test/command/suite/select/drilldowns/calc_types/multiple/all.test (+29 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/select/drilldowns/calc_types/multiple/all.test    2016-05-20 10:31:01 +0900 (f3eca0f)
@@ -0,0 +1,29 @@
+table_create Tags TABLE_PAT_KEY ShortText
+
+table_create Memos TABLE_HASH_KEY ShortText
+column_create Memos tag COLUMN_SCALAR Tags
+column_create Memos user COLUMN_SCALAR ShortText
+column_create Memos priority COLUMN_SCALAR Int64
+
+load --table Memos
+[
+{"_key": "Groonga1", "tag": "Groonga", "user": "user1", "priority": 10},
+{"_key": "Groonga2", "tag": "Groonga", "user": "user1", "priority": 20},
+{"_key": "Groonga3", "tag": "Groonga", "user": "user1", "priority": 60},
+{"_key": "Groonga4", "tag": "Groonga", "user": "user2", "priority": 61},
+{"_key": "Groonga5", "tag": "Groonga", "user": "user2", "priority": 24},
+{"_key": "Groonga6", "tag": "Groonga", "user": "user2", "priority": 8},
+{"_key": "Mroonga1", "tag": "Mroonga", "user": "user3", "priority": 7},
+{"_key": "Mroonga2", "tag": "Mroonga", "user": "user3", "priority": 3},
+{"_key": "Mroonga3", "tag": "Mroonga", "user": "user3", "priority": -4},
+{"_key": "Mroonga4", "tag": "Mroonga", "user": "user4", "priority": -1},
+{"_key": "Mroonga5", "tag": "Mroonga", "user": "user4", "priority": -2},
+{"_key": "Mroonga6", "tag": "Mroonga", "user": "user4", "priority": -3}
+]
+
+select Memos \
+  --limit 0 \
+  --drilldowns[tag].keys tag,user \
+  --drilldowns[tag].calc_types 'AVG, MAX, MIN, SUM' \
+  --drilldowns[tag].calc_target priority \
+  --drilldowns[tag].output_columns _value.tag,_value.user,_max,_min,_sum,_avg

  Added: test/command/suite/select/drilldowns/calc_types/multiple/avg.expected (+104 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/select/drilldowns/calc_types/multiple/avg.expected    2016-05-20 10:31:01 +0900 (917d03b)
@@ -0,0 +1,104 @@
+table_create Tags TABLE_PAT_KEY ShortText
+[[0,0.0,0.0],true]
+table_create Memos TABLE_HASH_KEY ShortText
+[[0,0.0,0.0],true]
+column_create Memos tag COLUMN_SCALAR Tags
+[[0,0.0,0.0],true]
+column_create Memos user COLUMN_SCALAR ShortText
+[[0,0.0,0.0],true]
+column_create Memos priority COLUMN_SCALAR Int64
+[[0,0.0,0.0],true]
+load --table Memos
+[
+{"_key": "Groonga1", "tag": "Groonga", "user": "user1", "priority": 10},
+{"_key": "Groonga2", "tag": "Groonga", "user": "user1", "priority": 20},
+{"_key": "Groonga3", "tag": "Groonga", "user": "user1", "priority": 60},
+{"_key": "Groonga4", "tag": "Groonga", "user": "user2", "priority": 61},
+{"_key": "Groonga5", "tag": "Groonga", "user": "user2", "priority": 24},
+{"_key": "Groonga6", "tag": "Groonga", "user": "user2", "priority": 8},
+{"_key": "Mroonga1", "tag": "Mroonga", "user": "user3", "priority": 7},
+{"_key": "Mroonga2", "tag": "Mroonga", "user": "user3", "priority": 3},
+{"_key": "Mroonga3", "tag": "Mroonga", "user": "user3", "priority": -4},
+{"_key": "Mroonga4", "tag": "Mroonga", "user": "user4", "priority": -1},
+{"_key": "Mroonga5", "tag": "Mroonga", "user": "user4", "priority": -2},
+{"_key": "Mroonga6", "tag": "Mroonga", "user": "user4", "priority": -3}
+]
+[[0,0.0,0.0],12]
+select Memos   --limit 0   --drilldowns[tag].keys tag,user   --drilldowns[tag].calc_types AVG   --drilldowns[tag].calc_target priority   --drilldowns[tag].output_columns _value.tag,_value.user,_avg
+[
+  [
+    0,
+    0.0,
+    0.0
+  ],
+  [
+    [
+      [
+        12
+      ],
+      [
+        [
+          "_id",
+          "UInt32"
+        ],
+        [
+          "_key",
+          "ShortText"
+        ],
+        [
+          "priority",
+          "Int64"
+        ],
+        [
+          "tag",
+          "Tags"
+        ],
+        [
+          "user",
+          "ShortText"
+        ]
+      ]
+    ],
+    {
+      "tag": [
+        [
+          4
+        ],
+        [
+          [
+            "tag",
+            "Tags"
+          ],
+          [
+            "user",
+            "ShortText"
+          ],
+          [
+            "_avg",
+            "Float"
+          ]
+        ],
+        [
+          "Groonga",
+          "user1",
+          30.0
+        ],
+        [
+          "Groonga",
+          "user2",
+          31.0
+        ],
+        [
+          "Mroonga",
+          "user3",
+          2.0
+        ],
+        [
+          "Mroonga",
+          "user4",
+          -2.0
+        ]
+      ]
+    }
+  ]
+]

  Added: test/command/suite/select/drilldowns/calc_types/multiple/avg.test (+29 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/select/drilldowns/calc_types/multiple/avg.test    2016-05-20 10:31:01 +0900 (31b6a6f)
@@ -0,0 +1,29 @@
+table_create Tags TABLE_PAT_KEY ShortText
+
+table_create Memos TABLE_HASH_KEY ShortText
+column_create Memos tag COLUMN_SCALAR Tags
+column_create Memos user COLUMN_SCALAR ShortText
+column_create Memos priority COLUMN_SCALAR Int64
+
+load --table Memos
+[
+{"_key": "Groonga1", "tag": "Groonga", "user": "user1", "priority": 10},
+{"_key": "Groonga2", "tag": "Groonga", "user": "user1", "priority": 20},
+{"_key": "Groonga3", "tag": "Groonga", "user": "user1", "priority": 60},
+{"_key": "Groonga4", "tag": "Groonga", "user": "user2", "priority": 61},
+{"_key": "Groonga5", "tag": "Groonga", "user": "user2", "priority": 24},
+{"_key": "Groonga6", "tag": "Groonga", "user": "user2", "priority": 8},
+{"_key": "Mroonga1", "tag": "Mroonga", "user": "user3", "priority": 7},
+{"_key": "Mroonga2", "tag": "Mroonga", "user": "user3", "priority": 3},
+{"_key": "Mroonga3", "tag": "Mroonga", "user": "user3", "priority": -4},
+{"_key": "Mroonga4", "tag": "Mroonga", "user": "user4", "priority": -1},
+{"_key": "Mroonga5", "tag": "Mroonga", "user": "user4", "priority": -2},
+{"_key": "Mroonga6", "tag": "Mroonga", "user": "user4", "priority": -3}
+]
+
+select Memos \
+  --limit 0 \
+  --drilldowns[tag].keys tag,user \
+  --drilldowns[tag].calc_types AVG \
+  --drilldowns[tag].calc_target priority \
+  --drilldowns[tag].output_columns _value.tag,_value.user,_avg

  Added: test/command/suite/select/drilldowns/calc_types/multiple/max.expected (+104 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/select/drilldowns/calc_types/multiple/max.expected    2016-05-20 10:31:01 +0900 (8ae6326)
@@ -0,0 +1,104 @@
+table_create Tags TABLE_PAT_KEY ShortText
+[[0,0.0,0.0],true]
+table_create Memos TABLE_HASH_KEY ShortText
+[[0,0.0,0.0],true]
+column_create Memos tag COLUMN_SCALAR Tags
+[[0,0.0,0.0],true]
+column_create Memos user COLUMN_SCALAR ShortText
+[[0,0.0,0.0],true]
+column_create Memos priority COLUMN_SCALAR Int64
+[[0,0.0,0.0],true]
+load --table Memos
+[
+{"_key": "Groonga1", "tag": "Groonga", "user": "user1", "priority": 10},
+{"_key": "Groonga2", "tag": "Groonga", "user": "user1", "priority": 20},
+{"_key": "Groonga3", "tag": "Groonga", "user": "user1", "priority": 60},
+{"_key": "Groonga4", "tag": "Groonga", "user": "user2", "priority": 61},
+{"_key": "Groonga5", "tag": "Groonga", "user": "user2", "priority": 24},
+{"_key": "Groonga6", "tag": "Groonga", "user": "user2", "priority": 8},
+{"_key": "Mroonga1", "tag": "Mroonga", "user": "user3", "priority": 7},
+{"_key": "Mroonga2", "tag": "Mroonga", "user": "user3", "priority": 3},
+{"_key": "Mroonga3", "tag": "Mroonga", "user": "user3", "priority": -4},
+{"_key": "Mroonga4", "tag": "Mroonga", "user": "user4", "priority": -1},
+{"_key": "Mroonga5", "tag": "Mroonga", "user": "user4", "priority": -2},
+{"_key": "Mroonga6", "tag": "Mroonga", "user": "user4", "priority": -3}
+]
+[[0,0.0,0.0],12]
+select Memos   --limit 0   --drilldowns[tag].keys tag,user   --drilldowns[tag].calc_types MAX   --drilldowns[tag].calc_target priority   --drilldowns[tag].output_columns _value.tag,_value.user,_max
+[
+  [
+    0,
+    0.0,
+    0.0
+  ],
+  [
+    [
+      [
+        12
+      ],
+      [
+        [
+          "_id",
+          "UInt32"
+        ],
+        [
+          "_key",
+          "ShortText"
+        ],
+        [
+          "priority",
+          "Int64"
+        ],
+        [
+          "tag",
+          "Tags"
+        ],
+        [
+          "user",
+          "ShortText"
+        ]
+      ]
+    ],
+    {
+      "tag": [
+        [
+          4
+        ],
+        [
+          [
+            "tag",
+            "Tags"
+          ],
+          [
+            "user",
+            "ShortText"
+          ],
+          [
+            "_max",
+            "Int64"
+          ]
+        ],
+        [
+          "Groonga",
+          "user1",
+          60
+        ],
+        [
+          "Groonga",
+          "user2",
+          61
+        ],
+        [
+          "Mroonga",
+          "user3",
+          7
+        ],
+        [
+          "Mroonga",
+          "user4",
+          -1
+        ]
+      ]
+    }
+  ]
+]

  Added: test/command/suite/select/drilldowns/calc_types/multiple/max.test (+29 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/select/drilldowns/calc_types/multiple/max.test    2016-05-20 10:31:01 +0900 (981d03e)
@@ -0,0 +1,29 @@
+table_create Tags TABLE_PAT_KEY ShortText
+
+table_create Memos TABLE_HASH_KEY ShortText
+column_create Memos tag COLUMN_SCALAR Tags
+column_create Memos user COLUMN_SCALAR ShortText
+column_create Memos priority COLUMN_SCALAR Int64
+
+load --table Memos
+[
+{"_key": "Groonga1", "tag": "Groonga", "user": "user1", "priority": 10},
+{"_key": "Groonga2", "tag": "Groonga", "user": "user1", "priority": 20},
+{"_key": "Groonga3", "tag": "Groonga", "user": "user1", "priority": 60},
+{"_key": "Groonga4", "tag": "Groonga", "user": "user2", "priority": 61},
+{"_key": "Groonga5", "tag": "Groonga", "user": "user2", "priority": 24},
+{"_key": "Groonga6", "tag": "Groonga", "user": "user2", "priority": 8},
+{"_key": "Mroonga1", "tag": "Mroonga", "user": "user3", "priority": 7},
+{"_key": "Mroonga2", "tag": "Mroonga", "user": "user3", "priority": 3},
+{"_key": "Mroonga3", "tag": "Mroonga", "user": "user3", "priority": -4},
+{"_key": "Mroonga4", "tag": "Mroonga", "user": "user4", "priority": -1},
+{"_key": "Mroonga5", "tag": "Mroonga", "user": "user4", "priority": -2},
+{"_key": "Mroonga6", "tag": "Mroonga", "user": "user4", "priority": -3}
+]
+
+select Memos \
+  --limit 0 \
+  --drilldowns[tag].keys tag,user \
+  --drilldowns[tag].calc_types MAX \
+  --drilldowns[tag].calc_target priority \
+  --drilldowns[tag].output_columns _value.tag,_value.user,_max

  Added: test/command/suite/select/drilldowns/calc_types/multiple/min.expected (+104 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/select/drilldowns/calc_types/multiple/min.expected    2016-05-20 10:31:01 +0900 (4277b59)
@@ -0,0 +1,104 @@
+table_create Tags TABLE_PAT_KEY ShortText
+[[0,0.0,0.0],true]
+table_create Memos TABLE_HASH_KEY ShortText
+[[0,0.0,0.0],true]
+column_create Memos tag COLUMN_SCALAR Tags
+[[0,0.0,0.0],true]
+column_create Memos user COLUMN_SCALAR ShortText
+[[0,0.0,0.0],true]
+column_create Memos priority COLUMN_SCALAR Int64
+[[0,0.0,0.0],true]
+load --table Memos
+[
+{"_key": "Groonga1", "tag": "Groonga", "user": "user1", "priority": 10},
+{"_key": "Groonga2", "tag": "Groonga", "user": "user1", "priority": 20},
+{"_key": "Groonga3", "tag": "Groonga", "user": "user1", "priority": 60},
+{"_key": "Groonga4", "tag": "Groonga", "user": "user2", "priority": 61},
+{"_key": "Groonga5", "tag": "Groonga", "user": "user2", "priority": 24},
+{"_key": "Groonga6", "tag": "Groonga", "user": "user2", "priority": 8},
+{"_key": "Mroonga1", "tag": "Mroonga", "user": "user3", "priority": 7},
+{"_key": "Mroonga2", "tag": "Mroonga", "user": "user3", "priority": 3},
+{"_key": "Mroonga3", "tag": "Mroonga", "user": "user3", "priority": -4},
+{"_key": "Mroonga4", "tag": "Mroonga", "user": "user4", "priority": -1},
+{"_key": "Mroonga5", "tag": "Mroonga", "user": "user4", "priority": -2},
+{"_key": "Mroonga6", "tag": "Mroonga", "user": "user4", "priority": -3}
+]
+[[0,0.0,0.0],12]
+select Memos   --limit 0   --drilldowns[tag].keys tag,user   --drilldowns[tag].calc_types MIN   --drilldowns[tag].calc_target priority   --drilldowns[tag].output_columns _value.tag,_value.user,_min
+[
+  [
+    0,
+    0.0,
+    0.0
+  ],
+  [
+    [
+      [
+        12
+      ],
+      [
+        [
+          "_id",
+          "UInt32"
+        ],
+        [
+          "_key",
+          "ShortText"
+        ],
+        [
+          "priority",
+          "Int64"
+        ],
+        [
+          "tag",
+          "Tags"
+        ],
+        [
+          "user",
+          "ShortText"
+        ]
+      ]
+    ],
+    {
+      "tag": [
+        [
+          4
+        ],
+        [
+          [
+            "tag",
+            "Tags"
+          ],
+          [
+            "user",
+            "ShortText"
+          ],
+          [
+            "_min",
+            "Int64"
+          ]
+        ],
+        [
+          "Groonga",
+          "user1",
+          10
+        ],
+        [
+          "Groonga",
+          "user2",
+          8
+        ],
+        [
+          "Mroonga",
+          "user3",
+          -4
+        ],
+        [
+          "Mroonga",
+          "user4",
+          -3
+        ]
+      ]
+    }
+  ]
+]

  Added: test/command/suite/select/drilldowns/calc_types/multiple/min.test (+29 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/select/drilldowns/calc_types/multiple/min.test    2016-05-20 10:31:01 +0900 (54d7aa6)
@@ -0,0 +1,29 @@
+table_create Tags TABLE_PAT_KEY ShortText
+
+table_create Memos TABLE_HASH_KEY ShortText
+column_create Memos tag COLUMN_SCALAR Tags
+column_create Memos user COLUMN_SCALAR ShortText
+column_create Memos priority COLUMN_SCALAR Int64
+
+load --table Memos
+[
+{"_key": "Groonga1", "tag": "Groonga", "user": "user1", "priority": 10},
+{"_key": "Groonga2", "tag": "Groonga", "user": "user1", "priority": 20},
+{"_key": "Groonga3", "tag": "Groonga", "user": "user1", "priority": 60},
+{"_key": "Groonga4", "tag": "Groonga", "user": "user2", "priority": 61},
+{"_key": "Groonga5", "tag": "Groonga", "user": "user2", "priority": 24},
+{"_key": "Groonga6", "tag": "Groonga", "user": "user2", "priority": 8},
+{"_key": "Mroonga1", "tag": "Mroonga", "user": "user3", "priority": 7},
+{"_key": "Mroonga2", "tag": "Mroonga", "user": "user3", "priority": 3},
+{"_key": "Mroonga3", "tag": "Mroonga", "user": "user3", "priority": -4},
+{"_key": "Mroonga4", "tag": "Mroonga", "user": "user4", "priority": -1},
+{"_key": "Mroonga5", "tag": "Mroonga", "user": "user4", "priority": -2},
+{"_key": "Mroonga6", "tag": "Mroonga", "user": "user4", "priority": -3}
+]
+
+select Memos \
+  --limit 0 \
+  --drilldowns[tag].keys tag,user \
+  --drilldowns[tag].calc_types MIN \
+  --drilldowns[tag].calc_target priority \
+  --drilldowns[tag].output_columns _value.tag,_value.user,_min

  Added: test/command/suite/select/drilldowns/calc_types/multiple/sum.expected (+104 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/select/drilldowns/calc_types/multiple/sum.expected    2016-05-20 10:31:01 +0900 (494981f)
@@ -0,0 +1,104 @@
+table_create Tags TABLE_PAT_KEY ShortText
+[[0,0.0,0.0],true]
+table_create Memos TABLE_HASH_KEY ShortText
+[[0,0.0,0.0],true]
+column_create Memos tag COLUMN_SCALAR Tags
+[[0,0.0,0.0],true]
+column_create Memos user COLUMN_SCALAR ShortText
+[[0,0.0,0.0],true]
+column_create Memos priority COLUMN_SCALAR Int64
+[[0,0.0,0.0],true]
+load --table Memos
+[
+{"_key": "Groonga1", "tag": "Groonga", "user": "user1", "priority": 10},
+{"_key": "Groonga2", "tag": "Groonga", "user": "user1", "priority": 20},
+{"_key": "Groonga3", "tag": "Groonga", "user": "user1", "priority": 60},
+{"_key": "Groonga4", "tag": "Groonga", "user": "user2", "priority": 61},
+{"_key": "Groonga5", "tag": "Groonga", "user": "user2", "priority": 24},
+{"_key": "Groonga6", "tag": "Groonga", "user": "user2", "priority": 8},
+{"_key": "Mroonga1", "tag": "Mroonga", "user": "user3", "priority": 7},
+{"_key": "Mroonga2", "tag": "Mroonga", "user": "user3", "priority": 3},
+{"_key": "Mroonga3", "tag": "Mroonga", "user": "user3", "priority": -4},
+{"_key": "Mroonga4", "tag": "Mroonga", "user": "user4", "priority": -1},
+{"_key": "Mroonga5", "tag": "Mroonga", "user": "user4", "priority": -2},
+{"_key": "Mroonga6", "tag": "Mroonga", "user": "user4", "priority": -3}
+]
+[[0,0.0,0.0],12]
+select Memos   --limit 0   --drilldowns[tag].keys tag,user   --drilldowns[tag].calc_types SUM   --drilldowns[tag].calc_target priority   --drilldowns[tag].output_columns _value.tag,_value.user,_sum
+[
+  [
+    0,
+    0.0,
+    0.0
+  ],
+  [
+    [
+      [
+        12
+      ],
+      [
+        [
+          "_id",
+          "UInt32"
+        ],
+        [
+          "_key",
+          "ShortText"
+        ],
+        [
+          "priority",
+          "Int64"
+        ],
+        [
+          "tag",
+          "Tags"
+        ],
+        [
+          "user",
+          "ShortText"
+        ]
+      ]
+    ],
+    {
+      "tag": [
+        [
+          4
+        ],
+        [
+          [
+            "tag",
+            "Tags"
+          ],
+          [
+            "user",
+            "ShortText"
+          ],
+          [
+            "_sum",
+            "Int64"
+          ]
+        ],
+        [
+          "Groonga",
+          "user1",
+          90
+        ],
+        [
+          "Groonga",
+          "user2",
+          93
+        ],
+        [
+          "Mroonga",
+          "user3",
+          6
+        ],
+        [
+          "Mroonga",
+          "user4",
+          -6
+        ]
+      ]
+    }
+  ]
+]

  Added: test/command/suite/select/drilldowns/calc_types/multiple/sum.test (+29 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/select/drilldowns/calc_types/multiple/sum.test    2016-05-20 10:31:01 +0900 (b89d27e)
@@ -0,0 +1,29 @@
+table_create Tags TABLE_PAT_KEY ShortText
+
+table_create Memos TABLE_HASH_KEY ShortText
+column_create Memos tag COLUMN_SCALAR Tags
+column_create Memos user COLUMN_SCALAR ShortText
+column_create Memos priority COLUMN_SCALAR Int64
+
+load --table Memos
+[
+{"_key": "Groonga1", "tag": "Groonga", "user": "user1", "priority": 10},
+{"_key": "Groonga2", "tag": "Groonga", "user": "user1", "priority": 20},
+{"_key": "Groonga3", "tag": "Groonga", "user": "user1", "priority": 60},
+{"_key": "Groonga4", "tag": "Groonga", "user": "user2", "priority": 61},
+{"_key": "Groonga5", "tag": "Groonga", "user": "user2", "priority": 24},
+{"_key": "Groonga6", "tag": "Groonga", "user": "user2", "priority": 8},
+{"_key": "Mroonga1", "tag": "Mroonga", "user": "user3", "priority": 7},
+{"_key": "Mroonga2", "tag": "Mroonga", "user": "user3", "priority": 3},
+{"_key": "Mroonga3", "tag": "Mroonga", "user": "user3", "priority": -4},
+{"_key": "Mroonga4", "tag": "Mroonga", "user": "user4", "priority": -1},
+{"_key": "Mroonga5", "tag": "Mroonga", "user": "user4", "priority": -2},
+{"_key": "Mroonga6", "tag": "Mroonga", "user": "user4", "priority": -3}
+]
+
+select Memos \
+  --limit 0 \
+  --drilldowns[tag].keys tag,user \
+  --drilldowns[tag].calc_types SUM \
+  --drilldowns[tag].calc_target priority \
+  --drilldowns[tag].output_columns _value.tag,_value.user,_sum

  Added: test/command/suite/select/drilldowns/calc_types/single/all.expected (+104 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/select/drilldowns/calc_types/single/all.expected    2016-05-20 10:31:01 +0900 (4f2d521)
@@ -0,0 +1,104 @@
+table_create Tags TABLE_PAT_KEY ShortText
+[[0,0.0,0.0],true]
+table_create Memos TABLE_HASH_KEY ShortText
+[[0,0.0,0.0],true]
+column_create Memos tag COLUMN_SCALAR Tags
+[[0,0.0,0.0],true]
+column_create Memos priority COLUMN_SCALAR Int64
+[[0,0.0,0.0],true]
+load --table Memos
+[
+{"_key": "Groonga1", "tag": "Groonga", "priority": 10},
+{"_key": "Groonga2", "tag": "Groonga", "priority": 20},
+{"_key": "Groonga3", "tag": "Groonga", "priority": 60},
+{"_key": "Mroonga1", "tag": "Mroonga", "priority": 61},
+{"_key": "Mroonga2", "tag": "Mroonga", "priority": 24},
+{"_key": "Mroonga3", "tag": "Mroonga", "priority": 8},
+{"_key": "Rroonga1", "tag": "Rroonga", "priority": 3},
+{"_key": "Rroonga2", "tag": "Rroonga", "priority": -9},
+{"_key": "Rroonga3", "tag": "Rroonga", "priority": 0}
+]
+[[0,0.0,0.0],9]
+select Memos   --limit 0   --drilldowns[tag].keys tag   --drilldowns[tag].calc_types 'AVG, MAX, MIN, SUM'   --drilldowns[tag].calc_target priority   --drilldowns[tag].output_columns _key,_max,_min,_sum,_avg
+[
+  [
+    0,
+    0.0,
+    0.0
+  ],
+  [
+    [
+      [
+        9
+      ],
+      [
+        [
+          "_id",
+          "UInt32"
+        ],
+        [
+          "_key",
+          "ShortText"
+        ],
+        [
+          "priority",
+          "Int64"
+        ],
+        [
+          "tag",
+          "Tags"
+        ]
+      ]
+    ],
+    {
+      "tag": [
+        [
+          3
+        ],
+        [
+          [
+            "_key",
+            "ShortText"
+          ],
+          [
+            "_max",
+            "Int64"
+          ],
+          [
+            "_min",
+            "Int64"
+          ],
+          [
+            "_sum",
+            "Int64"
+          ],
+          [
+            "_avg",
+            "Float"
+          ]
+        ],
+        [
+          "Groonga",
+          60,
+          10,
+          90,
+          30.0
+        ],
+        [
+          "Mroonga",
+          61,
+          8,
+          93,
+          31.0
+        ],
+        [
+          "Rroonga",
+          3,
+          -9,
+          -6,
+          -2.0
+        ]
+      ]
+    }
+  ]
+]

  Added: test/command/suite/select/drilldowns/calc_types/single/all.test (+25 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/select/drilldowns/calc_types/single/all.test    2016-05-20 10:31:01 +0900 (0bf2972)
@@ -0,0 +1,25 @@
+table_create Tags TABLE_PAT_KEY ShortText
+
+table_create Memos TABLE_HASH_KEY ShortText
+column_create Memos tag COLUMN_SCALAR Tags
+column_create Memos priority COLUMN_SCALAR Int64
+
+load --table Memos
+[
+{"_key": "Groonga1", "tag": "Groonga", "priority": 10},
+{"_key": "Groonga2", "tag": "Groonga", "priority": 20},
+{"_key": "Groonga3", "tag": "Groonga", "priority": 60},
+{"_key": "Mroonga1", "tag": "Mroonga", "priority": 61},
+{"_key": "Mroonga2", "tag": "Mroonga", "priority": 24},
+{"_key": "Mroonga3", "tag": "Mroonga", "priority": 8},
+{"_key": "Rroonga1", "tag": "Rroonga", "priority": 3},
+{"_key": "Rroonga2", "tag": "Rroonga", "priority": -9},
+{"_key": "Rroonga3", "tag": "Rroonga", "priority": 0}
+]
+
+select Memos \
+  --limit 0 \
+  --drilldowns[tag].keys tag \
+  --drilldowns[tag].calc_types 'AVG, MAX, MIN, SUM' \
+  --drilldowns[tag].calc_target priority \
+  --drilldowns[tag].output_columns _key,_max,_min,_sum,_avg

  Added: test/command/suite/select/drilldowns/calc_types/single/avg.expected (+83 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/select/drilldowns/calc_types/single/avg.expected    2016-05-20 10:31:01 +0900 (180ce28)
@@ -0,0 +1,83 @@
+table_create Tags TABLE_PAT_KEY ShortText
+[[0,0.0,0.0],true]
+table_create Memos TABLE_HASH_KEY ShortText
+[[0,0.0,0.0],true]
+column_create Memos tag COLUMN_SCALAR Tags
+[[0,0.0,0.0],true]
+column_create Memos priority COLUMN_SCALAR Int64
+[[0,0.0,0.0],true]
+load --table Memos
+[
+{"_key": "Groonga1", "tag": "Groonga", "priority": 10},
+{"_key": "Groonga2", "tag": "Groonga", "priority": 20},
+{"_key": "Groonga3", "tag": "Groonga", "priority": 60},
+{"_key": "Mroonga1", "tag": "Mroonga", "priority": 61},
+{"_key": "Mroonga2", "tag": "Mroonga", "priority": 24},
+{"_key": "Mroonga3", "tag": "Mroonga", "priority": 8},
+{"_key": "Rroonga1", "tag": "Rroonga", "priority": 3},
+{"_key": "Rroonga2", "tag": "Rroonga", "priority": -9},
+{"_key": "Rroonga3", "tag": "Rroonga", "priority": 0}
+]
+[[0,0.0,0.0],9]
+select Memos   --limit 0   --drilldowns[tag].keys tag   --drilldowns[tag].calc_types AVG   --drilldowns[tag].calc_target priority   --drilldowns[tag].output_columns _key,_avg
+[
+  [
+    0,
+    0.0,
+    0.0
+  ],
+  [
+    [
+      [
+        9
+      ],
+      [
+        [
+          "_id",
+          "UInt32"
+        ],
+        [
+          "_key",
+          "ShortText"
+        ],
+        [
+          "priority",
+          "Int64"
+        ],
+        [
+          "tag",
+          "Tags"
+        ]
+      ]
+    ],
+    {
+      "tag": [
+        [
+          3
+        ],
+        [
+          [
+            "_key",
+            "ShortText"
+          ],
+          [
+            "_avg",
+            "Float"
+          ]
+        ],
+        [
+          "Groonga",
+          30.0
+        ],
+        [
+          "Mroonga",
+          31.0
+        ],
+        [
+          "Rroonga",
+          -2.0
+        ]
+      ]
+    }
+  ]
+]

  Added: test/command/suite/select/drilldowns/calc_types/single/avg.test (+25 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/select/drilldowns/calc_types/single/avg.test    2016-05-20 10:31:01 +0900 (6ca556a)
@@ -0,0 +1,25 @@
+table_create Tags TABLE_PAT_KEY ShortText
+
+table_create Memos TABLE_HASH_KEY ShortText
+column_create Memos tag COLUMN_SCALAR Tags
+column_create Memos priority COLUMN_SCALAR Int64
+
+load --table Memos
+[
+{"_key": "Groonga1", "tag": "Groonga", "priority": 10},
+{"_key": "Groonga2", "tag": "Groonga", "priority": 20},
+{"_key": "Groonga3", "tag": "Groonga", "priority": 60},
+{"_key": "Mroonga1", "tag": "Mroonga", "priority": 61},
+{"_key": "Mroonga2", "tag": "Mroonga", "priority": 24},
+{"_key": "Mroonga3", "tag": "Mroonga", "priority": 8},
+{"_key": "Rroonga1", "tag": "Rroonga", "priority": 3},
+{"_key": "Rroonga2", "tag": "Rroonga", "priority": -9},
+{"_key": "Rroonga3", "tag": "Rroonga", "priority": 0}
+]
+
+select Memos \
+  --limit 0 \
+  --drilldowns[tag].keys tag \
+  --drilldowns[tag].calc_types AVG \
+  --drilldowns[tag].calc_target priority \
+  --drilldowns[tag].output_columns _key,_avg

  Added: test/command/suite/select/drilldowns/calc_types/single/max.expected (+83 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/select/drilldowns/calc_types/single/max.expected    2016-05-20 10:31:01 +0900 (16fb4ce)
@@ -0,0 +1,83 @@
+table_create Tags TABLE_PAT_KEY ShortText
+[[0,0.0,0.0],true]
+table_create Memos TABLE_HASH_KEY ShortText
+[[0,0.0,0.0],true]
+column_create Memos tag COLUMN_SCALAR Tags
+[[0,0.0,0.0],true]
+column_create Memos priority COLUMN_SCALAR Int64
+[[0,0.0,0.0],true]
+load --table Memos
+[
+{"_key": "Groonga1", "tag": "Groonga", "priority": 10},
+{"_key": "Groonga2", "tag": "Groonga", "priority": 20},
+{"_key": "Groonga3", "tag": "Groonga", "priority": 40},
+{"_key": "Mroonga1", "tag": "Mroonga", "priority": 50},
+{"_key": "Mroonga2", "tag": "Mroonga", "priority": 25},
+{"_key": "Mroonga3", "tag": "Mroonga", "priority": 10},
+{"_key": "Rroonga1", "tag": "Rroonga", "priority": 25},
+{"_key": "Rroonga2", "tag": "Rroonga", "priority": -25},
+{"_key": "Rroonga3", "tag": "Rroonga", "priority": 0}
+]
+[[0,0.0,0.0],9]
+select Memos   --limit 0   --drilldowns[tag].keys tag   --drilldowns[tag].calc_types MAX   --drilldowns[tag].calc_target priority   --drilldowns[tag].output_columns _key,_max
+[
+  [
+    0,
+    0.0,
+    0.0
+  ],
+  [
+    [
+      [
+        9
+      ],
+      [
+        [
+          "_id",
+          "UInt32"
+        ],
+        [
+          "_key",
+          "ShortText"
+        ],
+        [
+          "priority",
+          "Int64"
+        ],
+        [
+          "tag",
+          "Tags"
+        ]
+      ]
+    ],
+    {
+      "tag": [
+        [
+          3
+        ],
+        [
+          [
+            "_key",
+            "ShortText"
+          ],
+          [
+            "_max",
+            "Int64"
+          ]
+        ],
+        [
+          "Groonga",
+          40
+        ],
+        [
+          "Mroonga",
+          50
+        ],
+        [
+          "Rroonga",
+          25
+        ]
+      ]
+    }
+  ]
+]

  Added: test/command/suite/select/drilldowns/calc_types/single/max.test (+25 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/select/drilldowns/calc_types/single/max.test    2016-05-20 10:31:01 +0900 (0e7f62b)
@@ -0,0 +1,25 @@
+table_create Tags TABLE_PAT_KEY ShortText
+
+table_create Memos TABLE_HASH_KEY ShortText
+column_create Memos tag COLUMN_SCALAR Tags
+column_create Memos priority COLUMN_SCALAR Int64
+
+load --table Memos
+[
+{"_key": "Groonga1", "tag": "Groonga", "priority": 10},
+{"_key": "Groonga2", "tag": "Groonga", "priority": 20},
+{"_key": "Groonga3", "tag": "Groonga", "priority": 40},
+{"_key": "Mroonga1", "tag": "Mroonga", "priority": 50},
+{"_key": "Mroonga2", "tag": "Mroonga", "priority": 25},
+{"_key": "Mroonga3", "tag": "Mroonga", "priority": 10},
+{"_key": "Rroonga1", "tag": "Rroonga", "priority": 25},
+{"_key": "Rroonga2", "tag": "Rroonga", "priority": -25},
+{"_key": "Rroonga3", "tag": "Rroonga", "priority": 0}
+]
+
+select Memos \
+  --limit 0 \
+  --drilldowns[tag].keys tag \
+  --drilldowns[tag].calc_types MAX \
+  --drilldowns[tag].calc_target priority \
+  --drilldowns[tag].output_columns _key,_max

  Added: test/command/suite/select/drilldowns/calc_types/single/min.expected (+83 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/select/drilldowns/calc_types/single/min.expected    2016-05-20 10:31:01 +0900 (ea77d3b)
@@ -0,0 +1,83 @@
+table_create Tags TABLE_PAT_KEY ShortText
+[[0,0.0,0.0],true]
+table_create Memos TABLE_HASH_KEY ShortText
+[[0,0.0,0.0],true]
+column_create Memos tag COLUMN_SCALAR Tags
+[[0,0.0,0.0],true]
+column_create Memos priority COLUMN_SCALAR Int64
+[[0,0.0,0.0],true]
+load --table Memos
+[
+{"_key": "Groonga1", "tag": "Groonga", "priority": 10},
+{"_key": "Groonga2", "tag": "Groonga", "priority": 20},
+{"_key": "Groonga3", "tag": "Groonga", "priority": 40},
+{"_key": "Mroonga1", "tag": "Mroonga", "priority": 50},
+{"_key": "Mroonga2", "tag": "Mroonga", "priority": 25},
+{"_key": "Mroonga3", "tag": "Mroonga", "priority": 5},
+{"_key": "Rroonga1", "tag": "Rroonga", "priority": 25},
+{"_key": "Rroonga2", "tag": "Rroonga", "priority": -25},
+{"_key": "Rroonga3", "tag": "Rroonga", "priority": 0}
+]
+[[0,0.0,0.0],9]
+select Memos   --limit 0   --drilldowns[tag].keys tag   --drilldowns[tag].calc_types MIN   --drilldowns[tag].calc_target priority   --drilldowns[tag].output_columns _key,_min
+[
+  [
+    0,
+    0.0,
+    0.0
+  ],
+  [
+    [
+      [
+        9
+      ],
+      [
+        [
+          "_id",
+          "UInt32"
+        ],
+        [
+          "_key",
+          "ShortText"
+        ],
+        [
+          "priority",
+          "Int64"
+        ],
+        [
+          "tag",
+          "Tags"
+        ]
+      ]
+    ],
+    {
+      "tag": [
+        [
+          3
+        ],
+        [
+          [
+            "_key",
+            "ShortText"
+          ],
+          [
+            "_min",
+            "Int64"
+          ]
+        ],
+        [
+          "Groonga",
+          10
+        ],
+        [
+          "Mroonga",
+          5
+        ],
+        [
+          "Rroonga",
+          -25
+        ]
+      ]
+    }
+  ]
+]

  Added: test/command/suite/select/drilldowns/calc_types/single/min.test (+25 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/select/drilldowns/calc_types/single/min.test    2016-05-20 10:31:01 +0900 (1c0d324)
@@ -0,0 +1,25 @@
+table_create Tags TABLE_PAT_KEY ShortText
+
+table_create Memos TABLE_HASH_KEY ShortText
+column_create Memos tag COLUMN_SCALAR Tags
+column_create Memos priority COLUMN_SCALAR Int64
+
+load --table Memos
+[
+{"_key": "Groonga1", "tag": "Groonga", "priority": 10},
+{"_key": "Groonga2", "tag": "Groonga", "priority": 20},
+{"_key": "Groonga3", "tag": "Groonga", "priority": 40},
+{"_key": "Mroonga1", "tag": "Mroonga", "priority": 50},
+{"_key": "Mroonga2", "tag": "Mroonga", "priority": 25},
+{"_key": "Mroonga3", "tag": "Mroonga", "priority": 5},
+{"_key": "Rroonga1", "tag": "Rroonga", "priority": 25},
+{"_key": "Rroonga2", "tag": "Rroonga", "priority": -25},
+{"_key": "Rroonga3", "tag": "Rroonga", "priority": 0}
+]
+
+select Memos \
+  --limit 0 \
+  --drilldowns[tag].keys tag \
+  --drilldowns[tag].calc_types MIN \
+  --drilldowns[tag].calc_target priority \
+  --drilldowns[tag].output_columns _key,_min

  Added: test/command/suite/select/drilldowns/calc_types/single/sum.expected (+78 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/select/drilldowns/calc_types/single/sum.expected    2016-05-20 10:31:01 +0900 (e9ae87a)
@@ -0,0 +1,78 @@
+table_create Tags TABLE_PAT_KEY ShortText
+[[0,0.0,0.0],true]
+table_create Memos TABLE_HASH_KEY ShortText
+[[0,0.0,0.0],true]
+column_create Memos tag COLUMN_SCALAR Tags
+[[0,0.0,0.0],true]
+column_create Memos value COLUMN_SCALAR Int64
+[[0,0.0,0.0],true]
+load --table Memos
+[
+{"_key": "Groonga is fast!", "tag": "Groonga", "value": 10},
+{"_key": "Mroonga is fast!", "tag": "Mroonga", "value": 20},
+{"_key": "Groonga sticker!", "tag": "Groonga", "value": 40},
+{"_key": "Rroonga is fast!", "tag": "Rroonga", "value": 80}
+]
+[[0,0.0,0.0],4]
+select Memos   --limit 0   --drilldowns[tag].keys tag   --drilldowns[tag].calc_types SUM   --drilldowns[tag].calc_target value   --drilldowns[tag].output_columns _key,_sum
+[
+  [
+    0,
+    0.0,
+    0.0
+  ],
+  [
+    [
+      [
+        4
+      ],
+      [
+        [
+          "_id",
+          "UInt32"
+        ],
+        [
+          "_key",
+          "ShortText"
+        ],
+        [
+          "tag",
+          "Tags"
+        ],
+        [
+          "value",
+          "Int64"
+        ]
+      ]
+    ],
+    {
+      "tag": [
+        [
+          3
+        ],
+        [
+          [
+            "_key",
+            "ShortText"
+          ],
+          [
+            "_sum",
+            "Int64"
+          ]
+        ],
+        [
+          "Groonga",
+          50
+        ],
+        [
+          "Mroonga",
+          20
+        ],
+        [
+          "Rroonga",
+          80
+        ]
+      ]
+    }
+  ]
+]

  Added: test/command/suite/select/drilldowns/calc_types/single/sum.test (+20 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/select/drilldowns/calc_types/single/sum.test    2016-05-20 10:31:01 +0900 (93970e9)
@@ -0,0 +1,20 @@
+table_create Tags TABLE_PAT_KEY ShortText
+
+table_create Memos TABLE_HASH_KEY ShortText
+column_create Memos tag COLUMN_SCALAR Tags
+column_create Memos value COLUMN_SCALAR Int64
+
+load --table Memos
+[
+{"_key": "Groonga is fast!", "tag": "Groonga", "value": 10},
+{"_key": "Mroonga is fast!", "tag": "Mroonga", "value": 20},
+{"_key": "Groonga sticker!", "tag": "Groonga", "value": 40},
+{"_key": "Rroonga is fast!", "tag": "Rroonga", "value": 80}
+]
+
+select Memos \
+  --limit 0 \
+  --drilldowns[tag].keys tag \
+  --drilldowns[tag].calc_types SUM \
+  --drilldowns[tag].calc_target value \
+  --drilldowns[tag].output_columns _key,_sum

  Added: test/command/suite/select/drilldowns/column/stage/initial/drilldown.expected (+171 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/select/drilldowns/column/stage/initial/drilldown.expected    2016-05-20 10:31:01 +0900 (ddd5777)
@@ -0,0 +1,171 @@
+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 Shops TABLE_HASH_KEY ShortText
+[[0,0.0,0.0],true]
+column_create Shops items COLUMN_VECTOR Items
+[[0,0.0,0.0],true]
+load --table Shops
+[
+{"_key": "Stationery store",  "items": ["Book", "Note", "Box", "Pen"]},
+{"_key": "Supermarket",       "items": ["Food", "Drink", "Pen"]},
+{"_key": "Convenience store", "items": ["Pen", "Note","Food", "Drink"]}
+]
+[[0,0.0,0.0],3]
+load --table Items
+[
+{"_key": "Book",  "price": 1000},
+{"_key": "Note",  "price": 1000},
+{"_key": "Box",   "price": 500},
+{"_key": "Pen",   "price": 500},
+{"_key": "Food",  "price": 500},
+{"_key": "Drink", "price": 300}
+]
+[[0,0.0,0.0],6]
+select Shops   --drilldowns[item].keys items   --drilldowns[item].sortby price   --drilldowns[item].output_columns _key,_nsubrecs,price,price_with_tax   --drilldowns[item].column[price_with_tax].stage initial   --drilldowns[item].column[price_with_tax].type UInt32   --drilldowns[item].column[price_with_tax].flags COLUMN_SCALAR   --drilldowns[item].column[price_with_tax].value 'price * 1.08'   --drilldowns[real_price].table item   --drilldowns[real_price].keys price_with_tax
+[
+  [
+    0,
+    0.0,
+    0.0
+  ],
+  [
+    [
+      [
+        3
+      ],
+      [
+        [
+          "_id",
+          "UInt32"
+        ],
+        [
+          "_key",
+          "ShortText"
+        ],
+        [
+          "items",
+          "Items"
+        ]
+      ],
+      [
+        1,
+        "Stationery store",
+        [
+          "Book",
+          "Note",
+          "Box",
+          "Pen"
+        ]
+      ],
+      [
+        2,
+        "Supermarket",
+        [
+          "Food",
+          "Drink",
+          "Pen"
+        ]
+      ],
+      [
+        3,
+        "Convenience store",
+        [
+          "Pen",
+          "Note",
+          "Food",
+          "Drink"
+        ]
+      ]
+    ],
+    {
+      "item": [
+        [
+          6
+        ],
+        [
+          [
+            "_key",
+            "ShortText"
+          ],
+          [
+            "_nsubrecs",
+            "Int32"
+          ],
+          [
+            "price",
+            "UInt32"
+          ],
+          [
+            "price_with_tax",
+            "UInt32"
+          ]
+        ],
+        [
+          "Drink",
+          2,
+          300,
+          324
+        ],
+        [
+          "Food",
+          2,
+          500,
+          540
+        ],
+        [
+          "Pen",
+          3,
+          500,
+          540
+        ],
+        [
+          "Box",
+          1,
+          500,
+          540
+        ],
+        [
+          "Book",
+          1,
+          1000,
+          1080
+        ],
+        [
+          "Note",
+          2,
+          1000,
+          1080
+        ]
+      ],
+      "real_price": [
+        [
+          3
+        ],
+        [
+          [
+            "_key",
+            "UInt32"
+          ],
+          [
+            "_nsubrecs",
+            "Int32"
+          ]
+        ],
+        [
+          1080,
+          2
+        ],
+        [
+          540,
+          3
+        ],
+        [
+          324,
+          1
+        ]
+      ]
+    }
+  ]
+]

  Added: test/command/suite/select/drilldowns/column/stage/initial/drilldown.test (+33 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/select/drilldowns/column/stage/initial/drilldown.test    2016-05-20 10:31:01 +0900 (54513a1)
@@ -0,0 +1,33 @@
+table_create Items TABLE_HASH_KEY ShortText
+column_create Items price COLUMN_SCALAR UInt32
+
+table_create Shops TABLE_HASH_KEY ShortText
+column_create Shops items COLUMN_VECTOR Items
+
+load --table Shops
+[
+{"_key": "Stationery store",  "items": ["Book", "Note", "Box", "Pen"]},
+{"_key": "Supermarket",       "items": ["Food", "Drink", "Pen"]},
+{"_key": "Convenience store", "items": ["Pen", "Note","Food", "Drink"]}
+]
+
+load --table Items
+[
+{"_key": "Book",  "price": 1000},
+{"_key": "Note",  "price": 1000},
+{"_key": "Box",   "price": 500},
+{"_key": "Pen",   "price": 500},
+{"_key": "Food",  "price": 500},
+{"_key": "Drink", "price": 300}
+]
+
+select Shops \
+  --drilldowns[item].keys items \
+  --drilldowns[item].sortby price \
+  --drilldowns[item].output_columns _key,_nsubrecs,price,price_with_tax \
+  --drilldowns[item].column[price_with_tax].stage initial \
+  --drilldowns[item].column[price_with_tax].type UInt32 \
+  --drilldowns[item].column[price_with_tax].flags COLUMN_SCALAR \
+  --drilldowns[item].column[price_with_tax].value 'price * 1.08' \
+  --drilldowns[real_price].table item \
+  --drilldowns[real_price].keys price_with_tax

  Added: test/command/suite/select/drilldowns/column/stage/initial/output_columns.expected (+109 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/select/drilldowns/column/stage/initial/output_columns.expected    2016-05-20 10:31:01 +0900 (0798cab)
@@ -0,0 +1,109 @@
+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": "Book",  "price": 1000},
+{"_key": "Note",  "price": 1000},
+{"_key": "Box",   "price": 500},
+{"_key": "Pen",   "price": 500},
+{"_key": "Food",  "price": 500},
+{"_key": "Drink", "price": 300}
+]
+[[0,0.0,0.0],6]
+select Items   --drilldowns[label].keys price   --drilldowns[label].output_columns _key,_nsubrecs,tax_included   --drilldowns[label].column[tax_included].stage initial   --drilldowns[label].column[tax_included].type UInt32   --drilldowns[label].column[tax_included].flags COLUMN_SCALAR   --drilldowns[label].column[tax_included].value '_key * 1.08'
+[
+  [
+    0,
+    0.0,
+    0.0
+  ],
+  [
+    [
+      [
+        6
+      ],
+      [
+        [
+          "_id",
+          "UInt32"
+        ],
+        [
+          "_key",
+          "ShortText"
+        ],
+        [
+          "price",
+          "UInt32"
+        ]
+      ],
+      [
+        1,
+        "Book",
+        1000
+      ],
+      [
+        2,
+        "Note",
+        1000
+      ],
+      [
+        3,
+        "Box",
+        500
+      ],
+      [
+        4,
+        "Pen",
+        500
+      ],
+      [
+        5,
+        "Food",
+        500
+      ],
+      [
+        6,
+        "Drink",
+        300
+      ]
+    ],
+    {
+      "label": [
+        [
+          3
+        ],
+        [
+          [
+            "_key",
+            "UInt32"
+          ],
+          [
+            "_nsubrecs",
+            "Int32"
+          ],
+          [
+            "tax_included",
+            "UInt32"
+          ]
+        ],
+        [
+          1000,
+          2,
+          1080
+        ],
+        [
+          500,
+          3,
+          540
+        ],
+        [
+          300,
+          1,
+          324
+        ]
+      ]
+    }
+  ]
+]

  Added: test/command/suite/select/drilldowns/column/stage/initial/output_columns.test (+20 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/select/drilldowns/column/stage/initial/output_columns.test    2016-05-20 10:31:01 +0900 (cc1d826)
@@ -0,0 +1,20 @@
+table_create Items TABLE_HASH_KEY ShortText
+column_create Items price COLUMN_SCALAR UInt32
+
+load --table Items
+[
+{"_key": "Book",  "price": 1000},
+{"_key": "Note",  "price": 1000},
+{"_key": "Box",   "price": 500},
+{"_key": "Pen",   "price": 500},
+{"_key": "Food",  "price": 500},
+{"_key": "Drink", "price": 300}
+]
+
+select Items \
+  --drilldowns[label].keys price \
+  --drilldowns[label].output_columns _key,_nsubrecs,tax_included \
+  --drilldowns[label].column[tax_included].stage initial \
+  --drilldowns[label].column[tax_included].type UInt32 \
+  --drilldowns[label].column[tax_included].flags COLUMN_SCALAR \
+  --drilldowns[label].column[tax_included].value '_key * 1.08'

  Added: test/command/suite/select/drilldowns/columns/stage/initial/drilldown.expected (+171 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/select/drilldowns/columns/stage/initial/drilldown.expected    2016-05-20 10:31:01 +0900 (ea092db)
@@ -0,0 +1,171 @@
+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 Shops TABLE_HASH_KEY ShortText
+[[0,0.0,0.0],true]
+column_create Shops items COLUMN_VECTOR Items
+[[0,0.0,0.0],true]
+load --table Shops
+[
+{"_key": "Stationery store",  "items": ["Book", "Note", "Box", "Pen"]},
+{"_key": "Supermarket",       "items": ["Food", "Drink", "Pen"]},
+{"_key": "Convenience store", "items": ["Pen", "Note","Food", "Drink"]}
+]
+[[0,0.0,0.0],3]
+load --table Items
+[
+{"_key": "Book",  "price": 1000},
+{"_key": "Note",  "price": 1000},
+{"_key": "Box",   "price": 500},
+{"_key": "Pen",   "price": 500},
+{"_key": "Food",  "price": 500},
+{"_key": "Drink", "price": 300}
+]
+[[0,0.0,0.0],6]
+select Shops   --drilldowns[item].keys items   --drilldowns[item].sortby price   --drilldowns[item].output_columns _key,_nsubrecs,price,price_with_tax   --drilldowns[item].columns[price_with_tax].stage initial   --drilldowns[item].columns[price_with_tax].type UInt32   --drilldowns[item].columns[price_with_tax].flags COLUMN_SCALAR   --drilldowns[item].columns[price_with_tax].value 'price * 1.08'   --drilldowns[real_price].table item   --drilldowns[real_price].keys price_with_tax
+[
+  [
+    0,
+    0.0,
+    0.0
+  ],
+  [
+    [
+      [
+        3
+      ],
+      [
+        [
+          "_id",
+          "UInt32"
+        ],
+        [
+          "_key",
+          "ShortText"
+        ],
+        [
+          "items",
+          "Items"
+        ]
+      ],
+      [
+        1,
+        "Stationery store",
+        [
+          "Book",
+          "Note",
+          "Box",
+          "Pen"
+        ]
+      ],
+      [
+        2,
+        "Supermarket",
+        [
+          "Food",
+          "Drink",
+          "Pen"
+        ]
+      ],
+      [
+        3,
+        "Convenience store",
+        [
+          "Pen",
+          "Note",
+          "Food",
+          "Drink"
+        ]
+      ]
+    ],
+    {
+      "item": [
+        [
+          6
+        ],
+        [
+          [
+            "_key",
+            "ShortText"
+          ],
+          [
+            "_nsubrecs",
+            "Int32"
+          ],
+          [
+            "price",
+            "UInt32"
+          ],
+          [
+            "price_with_tax",
+            "UInt32"
+          ]
+        ],
+        [
+          "Drink",
+          2,
+          300,
+          324
+        ],
+        [
+          "Food",
+          2,
+          500,
+          540
+        ],
+        [
+          "Pen",
+          3,
+          500,
+          540
+        ],
+        [
+          "Box",
+          1,
+          500,
+          540
+        ],
+        [
+          "Book",
+          1,
+          1000,
+          1080
+        ],
+        [
+          "Note",
+          2,
+          1000,
+          1080
+        ]
+      ],
+      "real_price": [
+        [
+          3
+        ],
+        [
+          [
+            "_key",
+            "UInt32"
+          ],
+          [
+            "_nsubrecs",
+            "Int32"
+          ]
+        ],
+        [
+          1080,
+          2
+        ],
+        [
+          540,
+          3
+        ],
+        [
+          324,
+          1
+        ]
+      ]
+    }
+  ]
+]

  Added: test/command/suite/select/drilldowns/columns/stage/initial/drilldown.test (+33 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/select/drilldowns/columns/stage/initial/drilldown.test    2016-05-20 10:31:01 +0900 (b783d4f)
@@ -0,0 +1,33 @@
+table_create Items TABLE_HASH_KEY ShortText
+column_create Items price COLUMN_SCALAR UInt32
+
+table_create Shops TABLE_HASH_KEY ShortText
+column_create Shops items COLUMN_VECTOR Items
+
+load --table Shops
+[
+{"_key": "Stationery store",  "items": ["Book", "Note", "Box", "Pen"]},
+{"_key": "Supermarket",       "items": ["Food", "Drink", "Pen"]},
+{"_key": "Convenience store", "items": ["Pen", "Note","Food", "Drink"]}
+]
+
+load --table Items
+[
+{"_key": "Book",  "price": 1000},
+{"_key": "Note",  "price": 1000},
+{"_key": "Box",   "price": 500},
+{"_key": "Pen",   "price": 500},
+{"_key": "Food",  "price": 500},
+{"_key": "Drink", "price": 300}
+]
+
+select Shops \
+  --drilldowns[item].keys items \
+  --drilldowns[item].sortby price \
+  --drilldowns[item].output_columns _key,_nsubrecs,price,price_with_tax \
+  --drilldowns[item].columns[price_with_tax].stage initial \
+  --drilldowns[item].columns[price_with_tax].type UInt32 \
+  --drilldowns[item].columns[price_with_tax].flags COLUMN_SCALAR \
+  --drilldowns[item].columns[price_with_tax].value 'price * 1.08' \
+  --drilldowns[real_price].table item \
+  --drilldowns[real_price].keys price_with_tax

  Added: test/command/suite/select/drilldowns/columns/stage/initial/output_columns.expected (+109 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/select/drilldowns/columns/stage/initial/output_columns.expected    2016-05-20 10:31:01 +0900 (2b76472)
@@ -0,0 +1,109 @@
+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": "Book",  "price": 1000},
+{"_key": "Note",  "price": 1000},
+{"_key": "Box",   "price": 500},
+{"_key": "Pen",   "price": 500},
+{"_key": "Food",  "price": 500},
+{"_key": "Drink", "price": 300}
+]
+[[0,0.0,0.0],6]
+select Items   --drilldowns[label].keys price   --drilldowns[label].output_columns _key,_nsubrecs,tax_included   --drilldowns[label].columns[tax_included].stage initial   --drilldowns[label].columns[tax_included].type UInt32   --drilldowns[label].columns[tax_included].flags COLUMN_SCALAR   --drilldowns[label].columns[tax_included].value '_key * 1.08'
+[
+  [
+    0,
+    0.0,
+    0.0
+  ],
+  [
+    [
+      [
+        6
+      ],
+      [
+        [
+          "_id",
+          "UInt32"
+        ],
+        [
+          "_key",
+          "ShortText"
+        ],
+        [
+          "price",
+          "UInt32"
+        ]
+      ],
+      [
+        1,
+        "Book",
+        1000
+      ],
+      [
+        2,
+        "Note",
+        1000
+      ],
+      [
+        3,
+        "Box",
+        500
+      ],
+      [
+        4,
+        "Pen",
+        500
+      ],
+      [
+        5,
+        "Food",
+        500
+      ],
+      [
+        6,
+        "Drink",
+        300
+      ]
+    ],
+    {
+      "label": [
+        [
+          3
+        ],
+        [
+          [
+            "_key",
+            "UInt32"
+          ],
+          [
+            "_nsubrecs",
+            "Int32"
+          ],
+          [
+            "tax_included",
+            "UInt32"
+          ]
+        ],
+        [
+          1000,
+          2,
+          1080
+        ],
+        [
+          500,
+          3,
+          540
+        ],
+        [
+          300,
+          1,
+          324
+        ]
+      ]
+    }
+  ]
+]

  Added: test/command/suite/select/drilldowns/columns/stage/initial/output_columns.test (+20 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/select/drilldowns/columns/stage/initial/output_columns.test    2016-05-20 10:31:01 +0900 (8a790d5)
@@ -0,0 +1,20 @@
+table_create Items TABLE_HASH_KEY ShortText
+column_create Items price COLUMN_SCALAR UInt32
+
+load --table Items
+[
+{"_key": "Book",  "price": 1000},
+{"_key": "Note",  "price": 1000},
+{"_key": "Box",   "price": 500},
+{"_key": "Pen",   "price": 500},
+{"_key": "Food",  "price": 500},
+{"_key": "Drink", "price": 300}
+]
+
+select Items \
+  --drilldowns[label].keys price \
+  --drilldowns[label].output_columns _key,_nsubrecs,tax_included \
+  --drilldowns[label].columns[tax_included].stage initial \
+  --drilldowns[label].columns[tax_included].type UInt32 \
+  --drilldowns[label].columns[tax_included].flags COLUMN_SCALAR \
+  --drilldowns[label].columns[tax_included].value '_key * 1.08'

  Copied: test/command/suite/select/drilldowns/filter/key.expected (+27 -17) 59%
===================================================================
--- test/command/suite/select/drilldown/labeled/table/nonexistent.expected    2016-05-20 10:24:11 +0900 (2237313)
+++ test/command/suite/select/drilldowns/filter/key.expected    2016-05-20 10:31:01 +0900 (7983ddf)
@@ -1,7 +1,5 @@
 table_create Tags TABLE_PAT_KEY ShortText
 [[0,0.0,0.0],true]
-column_create Tags category COLUMN_SCALAR ShortText
-[[0,0.0,0.0],true]
 table_create Memos TABLE_HASH_KEY ShortText
 [[0,0.0,0.0],true]
 column_create Memos tag COLUMN_SCALAR Tags
@@ -14,22 +12,12 @@ load --table Memos
 {"_key": "Rroonga is fast!", "tag": "Rroonga"}
 ]
 [[0,0.0,0.0],4]
-load --table Tags
-[
-{"_key": "Groonga", "category": "C/C++"},
-{"_key": "Mroonga", "category": "C/C++"},
-{"_key": "Rroonga", "category": "Ruby"}
-]
-[[0,0.0,0.0],3]
-select Memos   --drilldown[category].table nonexistent   --drilldown[category].keys category   --drilldown[category].output_columns _key,_nsubrecs   --drilldown[tag].keys tag   --drilldown[tag].output_columns _key,_nsubrecs,category
+select Memos   --drilldowns[tag].keys tag   --drilldowns[tag].filter '_key != "Groonga"'
 [
   [
-    [
-      -22,
-      0.0,
-      0.0
-    ],
-    "[select][drilldown][category][table] nonexistent label: <nonexistent>"
+    0,
+    0.0,
+    0.0
   ],
   [
     [
@@ -72,7 +60,29 @@ select Memos   --drilldown[category].table nonexistent   --drilldown[category].k
       ]
     ],
     {
+      "tag": [
+        [
+          2
+        ],
+        [
+          [
+            "_key",
+            "ShortText"
+          ],
+          [
+            "_nsubrecs",
+            "Int32"
+          ]
+        ],
+        [
+          "Mroonga",
+          1
+        ],
+        [
+          "Rroonga",
+          1
+        ]
+      ]
     }
   ]
 ]
-#|e| [select][drilldown][category][table] nonexistent label: <nonexistent>

  Added: test/command/suite/select/drilldowns/filter/key.test (+16 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/select/drilldowns/filter/key.test    2016-05-20 10:31:01 +0900 (2cb894c)
@@ -0,0 +1,16 @@
+table_create Tags TABLE_PAT_KEY ShortText
+
+table_create Memos TABLE_HASH_KEY ShortText
+column_create Memos tag COLUMN_SCALAR Tags
+
+load --table Memos
+[
+{"_key": "Groonga is fast!", "tag": "Groonga"},
+{"_key": "Mroonga is fast!", "tag": "Mroonga"},
+{"_key": "Groonga sticker!", "tag": "Groonga"},
+{"_key": "Rroonga is fast!", "tag": "Rroonga"}
+]
+
+select Memos \
+  --drilldowns[tag].keys tag \
+  --drilldowns[tag].filter '_key != "Groonga"'

  Added: test/command/suite/select/drilldowns/filtered/multiple.expected (+123 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/select/drilldowns/filtered/multiple.expected    2016-05-20 10:31:01 +0900 (e3b0ce8)
@@ -0,0 +1,123 @@
+table_create Tags TABLE_PAT_KEY ShortText
+[[0,0.0,0.0],true]
+table_create Memos TABLE_HASH_KEY ShortText
+[[0,0.0,0.0],true]
+column_create Memos tag COLUMN_SCALAR Tags
+[[0,0.0,0.0],true]
+column_create Memos date COLUMN_SCALAR Time
+[[0,0.0,0.0],true]
+load --table Memos
+[
+{"_key": "Groonga is fast!", "tag": "Groonga", "date": "2014-11-16 00:00:00"},
+{"_key": "Groonga sticker!", "tag": "Groonga", "date": "2014-11-16 00:00:00"},
+{"_key": "Rroonga is fast!", "tag": "Rroonga", "date": "2014-11-17 00:00:00"},
+{"_key": "Rroonga is good!", "tag": "Rroonga", "date": "2014-11-17 00:00:00"},
+{"_key": "Rroonga!!!!!!!!!", "tag": "Rroonga", "date": "2014-11-17 00:00:00"},
+{"_key": "Groonga is good!", "tag": "Groonga", "date": "2014-11-17 00:00:00"}
+]
+[[0,0.0,0.0],6]
+select Memos   --filter true   --drilldowns[tag].keys tag,date   --drilldowns[tag].output_columns _value.tag,_value.date,_nsubrecs   --drilldowns[tag].sortby _nsubrecs
+[
+  [
+    0,
+    0.0,
+    0.0
+  ],
+  [
+    [
+      [
+        6
+      ],
+      [
+        [
+          "_id",
+          "UInt32"
+        ],
+        [
+          "_key",
+          "ShortText"
+        ],
+        [
+          "date",
+          "Time"
+        ],
+        [
+          "tag",
+          "Tags"
+        ]
+      ],
+      [
+        1,
+        "Groonga is fast!",
+        1416063600.0,
+        "Groonga"
+      ],
+      [
+        2,
+        "Groonga sticker!",
+        1416063600.0,
+        "Groonga"
+      ],
+      [
+        3,
+        "Rroonga is fast!",
+        1416150000.0,
+        "Rroonga"
+      ],
+      [
+        4,
+        "Rroonga is good!",
+        1416150000.0,
+        "Rroonga"
+      ],
+      [
+        5,
+        "Rroonga!!!!!!!!!",
+        1416150000.0,
+        "Rroonga"
+      ],
+      [
+        6,
+        "Groonga is good!",
+        1416150000.0,
+        "Groonga"
+      ]
+    ],
+    {
+      "tag": [
+        [
+          3
+        ],
+        [
+          [
+            "tag",
+            "Tags"
+          ],
+          [
+            "date",
+            "Time"
+          ],
+          [
+            "_nsubrecs",
+            "Int32"
+          ]
+        ],
+        [
+          "Groonga",
+          1416150000.0,
+          1
+        ],
+        [
+          "Groonga",
+          1416063600.0,
+          2
+        ],
+        [
+          "Rroonga",
+          1416150000.0,
+          3
+        ]
+      ]
+    }
+  ]
+]

  Added: test/command/suite/select/drilldowns/filtered/multiple.test (+21 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/select/drilldowns/filtered/multiple.test    2016-05-20 10:31:01 +0900 (810de79)
@@ -0,0 +1,21 @@
+table_create Tags TABLE_PAT_KEY ShortText
+
+table_create Memos TABLE_HASH_KEY ShortText
+column_create Memos tag COLUMN_SCALAR Tags
+column_create Memos date COLUMN_SCALAR Time
+
+load --table Memos
+[
+{"_key": "Groonga is fast!", "tag": "Groonga", "date": "2014-11-16 00:00:00"},
+{"_key": "Groonga sticker!", "tag": "Groonga", "date": "2014-11-16 00:00:00"},
+{"_key": "Rroonga is fast!", "tag": "Rroonga", "date": "2014-11-17 00:00:00"},
+{"_key": "Rroonga is good!", "tag": "Rroonga", "date": "2014-11-17 00:00:00"},
+{"_key": "Rroonga!!!!!!!!!", "tag": "Rroonga", "date": "2014-11-17 00:00:00"},
+{"_key": "Groonga is good!", "tag": "Groonga", "date": "2014-11-17 00:00:00"}
+]
+
+select Memos \
+  --filter true \
+  --drilldowns[tag].keys tag,date \
+  --drilldowns[tag].output_columns _value.tag,_value.date,_nsubrecs \
+  --drilldowns[tag].sortby _nsubrecs

  Added: test/command/suite/select/drilldowns/keys/empty.expected (+64 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/select/drilldowns/keys/empty.expected    2016-05-20 10:31:01 +0900 (bb4c693)
@@ -0,0 +1,64 @@
+table_create Tags TABLE_PAT_KEY ShortText
+[[0,0.0,0.0],true]
+table_create Memos TABLE_HASH_KEY ShortText
+[[0,0.0,0.0],true]
+column_create Memos tag COLUMN_SCALAR Tags
+[[0,0.0,0.0],true]
+load --table Memos
+[
+{"_key": "Groonga is fast!", "tag": "Groonga"},
+{"_key": "Mroonga is fast!", "tag": "Mroonga"},
+{"_key": "Groonga sticker!", "tag": "Groonga"},
+{"_key": "Rroonga is fast!", "tag": "Rroonga"}
+]
+[[0,0.0,0.0],4]
+select Memos --limit 0 --drilldowns[tag].keys ''
+[
+  [
+    0,
+    0.0,
+    0.0
+  ],
+  [
+    [
+      [
+        4
+      ],
+      [
+        [
+          "_id",
+          "UInt32"
+        ],
+        [
+          "_key",
+          "ShortText"
+        ],
+        [
+          "tag",
+          "Tags"
+        ]
+      ]
+    ],
+    {
+      "tag": [
+        [
+          1
+        ],
+        [
+          [
+            "_key",
+            "ShortText"
+          ],
+          [
+            "_nsubrecs",
+            "Int32"
+          ]
+        ],
+        [
+          "_all",
+          4
+        ]
+      ]
+    }
+  ]
+]

  Added: test/command/suite/select/drilldowns/keys/empty.test (+14 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/select/drilldowns/keys/empty.test    2016-05-20 10:31:01 +0900 (901027f)
@@ -0,0 +1,14 @@
+table_create Tags TABLE_PAT_KEY ShortText
+
+table_create Memos TABLE_HASH_KEY ShortText
+column_create Memos tag COLUMN_SCALAR Tags
+
+load --table Memos
+[
+{"_key": "Groonga is fast!", "tag": "Groonga"},
+{"_key": "Mroonga is fast!", "tag": "Mroonga"},
+{"_key": "Groonga sticker!", "tag": "Groonga"},
+{"_key": "Rroonga is fast!", "tag": "Rroonga"}
+]
+
+select Memos --limit 0 --drilldowns[tag].keys ''

  Added: test/command/suite/select/drilldowns/keys/multiple.expected (+121 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/select/drilldowns/keys/multiple.expected    2016-05-20 10:31:01 +0900 (64996b4)
@@ -0,0 +1,121 @@
+table_create Tags TABLE_PAT_KEY ShortText
+[[0,0.0,0.0],true]
+table_create Memos TABLE_HASH_KEY ShortText
+[[0,0.0,0.0],true]
+column_create Memos tag COLUMN_SCALAR Tags
+[[0,0.0,0.0],true]
+column_create Memos date COLUMN_SCALAR Time
+[[0,0.0,0.0],true]
+load --table Memos
+[
+{"_key": "Groonga is fast!", "tag": "Groonga", "date": "2014-11-16 00:00:00"},
+{"_key": "Mroonga is fast!", "tag": "Mroonga", "date": "2014-11-16 00:00:00"},
+{"_key": "Groonga sticker!", "tag": "Groonga", "date": "2014-11-16 00:00:00"},
+{"_key": "Rroonga is fast!", "tag": "Rroonga", "date": "2014-11-17 00:00:00"},
+{"_key": "Groonga is good!", "tag": "Groonga", "date": "2014-11-17 00:00:00"}
+]
+[[0,0.0,0.0],5]
+select Memos   --command_version 2   --drilldowns[tag].keys tag,date   --drilldowns[tag].output_columns _key[0],_key[1],_nsubrecs
+[
+  [
+    0,
+    0.0,
+    0.0
+  ],
+  [
+    [
+      [
+        5
+      ],
+      [
+        [
+          "_id",
+          "UInt32"
+        ],
+        [
+          "_key",
+          "ShortText"
+        ],
+        [
+          "date",
+          "Time"
+        ],
+        [
+          "tag",
+          "Tags"
+        ]
+      ],
+      [
+        1,
+        "Groonga is fast!",
+        1416063600.0,
+        "Groonga"
+      ],
+      [
+        2,
+        "Mroonga is fast!",
+        1416063600.0,
+        "Mroonga"
+      ],
+      [
+        3,
+        "Groonga sticker!",
+        1416063600.0,
+        "Groonga"
+      ],
+      [
+        4,
+        "Rroonga is fast!",
+        1416150000.0,
+        "Rroonga"
+      ],
+      [
+        5,
+        "Groonga is good!",
+        1416150000.0,
+        "Groonga"
+      ]
+    ],
+    {
+      "tag": [
+        [
+          4
+        ],
+        [
+          [
+            "_key[0]",
+            null
+          ],
+          [
+            "_key[1]",
+            null
+          ],
+          [
+            "_nsubrecs",
+            "Int32"
+          ]
+        ],
+        [
+          "Groonga",
+          1416063600.0,
+          2
+        ],
+        [
+          "Mroonga",
+          1416063600.0,
+          1
+        ],
+        [
+          "Rroonga",
+          1416150000.0,
+          1
+        ],
+        [
+          "Groonga",
+          1416150000.0,
+          1
+        ]
+      ]
+    }
+  ]
+]

  Added: test/command/suite/select/drilldowns/keys/multiple.test (+19 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/select/drilldowns/keys/multiple.test    2016-05-20 10:31:01 +0900 (193d99b)
@@ -0,0 +1,19 @@
+table_create Tags TABLE_PAT_KEY ShortText
+
+table_create Memos TABLE_HASH_KEY ShortText
+column_create Memos tag COLUMN_SCALAR Tags
+column_create Memos date COLUMN_SCALAR Time
+
+load --table Memos
+[
+{"_key": "Groonga is fast!", "tag": "Groonga", "date": "2014-11-16 00:00:00"},
+{"_key": "Mroonga is fast!", "tag": "Mroonga", "date": "2014-11-16 00:00:00"},
+{"_key": "Groonga sticker!", "tag": "Groonga", "date": "2014-11-16 00:00:00"},
+{"_key": "Rroonga is fast!", "tag": "Rroonga", "date": "2014-11-17 00:00:00"},
+{"_key": "Groonga is good!", "tag": "Groonga", "date": "2014-11-17 00:00:00"}
+]
+
+select Memos \
+  --command_version 2 \
+  --drilldowns[tag].keys tag,date \
+  --drilldowns[tag].output_columns _key[0],_key[1],_nsubrecs

  Copied: test/command/suite/select/drilldowns/keys/one.expected (+31 -17) 59%
===================================================================
--- test/command/suite/select/drilldown/labeled/table/nonexistent.expected    2016-05-20 10:24:11 +0900 (2237313)
+++ test/command/suite/select/drilldowns/keys/one.expected    2016-05-20 10:31:01 +0900 (01745e8)
@@ -1,7 +1,5 @@
 table_create Tags TABLE_PAT_KEY ShortText
 [[0,0.0,0.0],true]
-column_create Tags category COLUMN_SCALAR ShortText
-[[0,0.0,0.0],true]
 table_create Memos TABLE_HASH_KEY ShortText
 [[0,0.0,0.0],true]
 column_create Memos tag COLUMN_SCALAR Tags
@@ -14,22 +12,12 @@ load --table Memos
 {"_key": "Rroonga is fast!", "tag": "Rroonga"}
 ]
 [[0,0.0,0.0],4]
-load --table Tags
-[
-{"_key": "Groonga", "category": "C/C++"},
-{"_key": "Mroonga", "category": "C/C++"},
-{"_key": "Rroonga", "category": "Ruby"}
-]
-[[0,0.0,0.0],3]
-select Memos   --drilldown[category].table nonexistent   --drilldown[category].keys category   --drilldown[category].output_columns _key,_nsubrecs   --drilldown[tag].keys tag   --drilldown[tag].output_columns _key,_nsubrecs,category
+select Memos --drilldowns[tag].keys tag
 [
   [
-    [
-      -22,
-      0.0,
-      0.0
-    ],
-    "[select][drilldown][category][table] nonexistent label: <nonexistent>"
+    0,
+    0.0,
+    0.0
   ],
   [
     [
@@ -72,7 +60,33 @@ select Memos   --drilldown[category].table nonexistent   --drilldown[category].k
       ]
     ],
     {
+      "tag": [
+        [
+          3
+        ],
+        [
+          [
+            "_key",
+            "ShortText"
+          ],
+          [
+            "_nsubrecs",
+            "Int32"
+          ]
+        ],
+        [
+          "Groonga",
+          2
+        ],
+        [
+          "Mroonga",
+          1
+        ],
+        [
+          "Rroonga",
+          1
+        ]
+      ]
     }
   ]
 ]
-#|e| [select][drilldown][category][table] nonexistent label: <nonexistent>

  Added: test/command/suite/select/drilldowns/keys/one.test (+14 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/select/drilldowns/keys/one.test    2016-05-20 10:31:01 +0900 (d07c459)
@@ -0,0 +1,14 @@
+table_create Tags TABLE_PAT_KEY ShortText
+
+table_create Memos TABLE_HASH_KEY ShortText
+column_create Memos tag COLUMN_SCALAR Tags
+
+load --table Memos
+[
+{"_key": "Groonga is fast!", "tag": "Groonga"},
+{"_key": "Mroonga is fast!", "tag": "Mroonga"},
+{"_key": "Groonga sticker!", "tag": "Groonga"},
+{"_key": "Rroonga is fast!", "tag": "Rroonga"}
+]
+
+select Memos --drilldowns[tag].keys tag

  Added: test/command/suite/select/drilldowns/keys/reference_vector.expected (+84 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/select/drilldowns/keys/reference_vector.expected    2016-05-20 10:31:01 +0900 (8c4e561)
@@ -0,0 +1,84 @@
+table_create Tags TABLE_HASH_KEY ShortText
+[[0,0.0,0.0],true]
+table_create Memos TABLE_HASH_KEY ShortText
+[[0,0.0,0.0],true]
+column_create Memos date COLUMN_SCALAR Time
+[[0,0.0,0.0],true]
+column_create Memos tags COLUMN_VECTOR Tags
+[[0,0.0,0.0],true]
+load --table Memos
+[
+{"_key": "Groonga is fast!", "date": "2014-11-16 00:00:00",
+ "tags": ["Groonga"]},
+{"_key": "Mroonga is fast!", "date": "2014-11-16 00:00:00",
+ "tags": ["Mroonga", "Groonga"]},
+{"_key": "Groonga sticker!", "date": "2014-11-16 00:00:00",
+ "tags": ["Groonga"]},
+{"_key": "Rroonga is fast!", "date": "2014-11-17 00:00:00",
+ "tags": ["Rroonga", "Groonga"]},
+{"_key": "Groonga is good!", "date": "2014-11-17 00:00:00",
+ "tags": ["Groonga"]}
+]
+[[0,0.0,0.0],5]
+select Memos   --limit 0   --output_columns _id   --command_version 2   --drilldowns[vector].keys date,tags   --drilldowns[vector].output_columns _key[0],_key[1],_nsubrecs   --drilldowns[vector].sortby -_nsubrecs,_id
+[
+  [
+    0,
+    0.0,
+    0.0
+  ],
+  [
+    [
+      [
+        5
+      ],
+      [
+        [
+          "_id",
+          "UInt32"
+        ]
+      ]
+    ],
+    {
+      "vector": [
+        [
+          4
+        ],
+        [
+          [
+            "_key[0]",
+            null
+          ],
+          [
+            "_key[1]",
+            null
+          ],
+          [
+            "_nsubrecs",
+            "Int32"
+          ]
+        ],
+        [
+          1416063600.0,
+          "Groonga",
+          3
+        ],
+        [
+          1416150000.0,
+          "Groonga",
+          2
+        ],
+        [
+          1416063600.0,
+          "Mroonga",
+          1
+        ],
+        [
+          1416150000.0,
+          "Rroonga",
+          1
+        ]
+      ]
+    }
+  ]
+]

  Added: test/command/suite/select/drilldowns/keys/reference_vector.test (+27 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/select/drilldowns/keys/reference_vector.test    2016-05-20 10:31:01 +0900 (23abe7f)
@@ -0,0 +1,27 @@
+table_create Tags TABLE_HASH_KEY ShortText
+
+table_create Memos TABLE_HASH_KEY ShortText
+column_create Memos date COLUMN_SCALAR Time
+column_create Memos tags COLUMN_VECTOR Tags
+
+load --table Memos
+[
+{"_key": "Groonga is fast!", "date": "2014-11-16 00:00:00",
+ "tags": ["Groonga"]},
+{"_key": "Mroonga is fast!", "date": "2014-11-16 00:00:00",
+ "tags": ["Mroonga", "Groonga"]},
+{"_key": "Groonga sticker!", "date": "2014-11-16 00:00:00",
+ "tags": ["Groonga"]},
+{"_key": "Rroonga is fast!", "date": "2014-11-17 00:00:00",
+ "tags": ["Rroonga", "Groonga"]},
+{"_key": "Groonga is good!", "date": "2014-11-17 00:00:00",
+ "tags": ["Groonga"]}
+]
+
+select Memos \
+  --limit 0 \
+  --output_columns _id \
+  --command_version 2 \
+  --drilldowns[vector].keys date,tags \
+  --drilldowns[vector].output_columns _key[0],_key[1],_nsubrecs \
+  --drilldowns[vector].sortby -_nsubrecs,_id

  Added: test/command/suite/select/drilldowns/keys/vector.expected (+94 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/select/drilldowns/keys/vector.expected    2016-05-20 10:31:01 +0900 (a65b375)
@@ -0,0 +1,94 @@
+table_create Users TABLE_HASH_KEY ShortText
+[[0,0.0,0.0],true]
+table_create Memos TABLE_HASH_KEY ShortText
+[[0,0.0,0.0],true]
+column_create Memos user COLUMN_SCALAR Users
+[[0,0.0,0.0],true]
+column_create Memos date COLUMN_SCALAR Time
+[[0,0.0,0.0],true]
+column_create Memos tags COLUMN_VECTOR ShortText
+[[0,0.0,0.0],true]
+load --table Memos
+[
+{"_key": "Groonga is fast!", "user": "alice", "date": "2014-11-16 00:00:00",
+ "tags": ["Groonga"]},
+{"_key": "Mroonga is fast!", "user": "alice", "date": "2014-11-16 00:00:00",
+ "tags": ["Mroonga", "Groonga"]},
+{"_key": "Groonga sticker!", "user": "alice", "date": "2014-11-16 00:00:00",
+ "tags": ["Groonga"]},
+{"_key": "Rroonga is fast!", "user": "alice", "date": "2014-11-17 00:00:00",
+ "tags": ["Rroonga", "Groonga"]},
+{"_key": "Groonga is good!", "user": "alice", "date": "2014-11-17 00:00:00",
+ "tags": ["Groonga"]}
+]
+[[0,0.0,0.0],5]
+select Memos   --limit 0   --output_columns _id   --command_version 2   --drilldowns[vector].keys user,tags,date   --drilldowns[vector].output_columns _key[0],_key[1],_key[2],_nsubrecs   --drilldowns[vector].sortby -_nsubrecs,_id
+[
+  [
+    0,
+    0.0,
+    0.0
+  ],
+  [
+    [
+      [
+        5
+      ],
+      [
+        [
+          "_id",
+          "UInt32"
+        ]
+      ]
+    ],
+    {
+      "vector": [
+        [
+          4
+        ],
+        [
+          [
+            "_key[0]",
+            null
+          ],
+          [
+            "_key[1]",
+            null
+          ],
+          [
+            "_key[2]",
+            null
+          ],
+          [
+            "_nsubrecs",
+            "Int32"
+          ]
+        ],
+        [
+          "alice",
+          "Groonga",
+          1416063600.0,
+          3
+        ],
+        [
+          "alice",
+          "Groonga",
+          1416150000.0,
+          2
+        ],
+        [
+          "alice",
+          "Mroonga",
+          1416063600.0,
+          1
+        ],
+        [
+          "alice",
+          "Rroonga",
+          1416150000.0,
+          1
+        ]
+      ]
+    }
+  ]
+]

  Added: test/command/suite/select/drilldowns/keys/vector.test (+28 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/select/drilldowns/keys/vector.test    2016-05-20 10:31:01 +0900 (7f2e93e)
@@ -0,0 +1,28 @@
+table_create Users TABLE_HASH_KEY ShortText
+
+table_create Memos TABLE_HASH_KEY ShortText
+column_create Memos user COLUMN_SCALAR Users
+column_create Memos date COLUMN_SCALAR Time
+column_create Memos tags COLUMN_VECTOR ShortText
+
+load --table Memos
+[
+{"_key": "Groonga is fast!", "user": "alice", "date": "2014-11-16 00:00:00",
+ "tags": ["Groonga"]},
+{"_key": "Mroonga is fast!", "user": "alice", "date": "2014-11-16 00:00:00",
+ "tags": ["Mroonga", "Groonga"]},
+{"_key": "Groonga sticker!", "user": "alice", "date": "2014-11-16 00:00:00",
+ "tags": ["Groonga"]},
+{"_key": "Rroonga is fast!", "user": "alice", "date": "2014-11-17 00:00:00",
+ "tags": ["Rroonga", "Groonga"]},
+{"_key": "Groonga is good!", "user": "alice", "date": "2014-11-17 00:00:00",
+ "tags": ["Groonga"]}
+]
+
+select Memos \
+  --limit 0 \
+  --output_columns _id \
+  --command_version 2 \
+  --drilldowns[vector].keys user,tags,date \
+  --drilldowns[vector].output_columns _key[0],_key[1],_key[2],_nsubrecs \
+  --drilldowns[vector].sortby -_nsubrecs,_id

  Added: test/command/suite/select/drilldowns/no_keys/no_calc_target.expected (+72 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/select/drilldowns/no_keys/no_calc_target.expected    2016-05-20 10:31:01 +0900 (634c688)
@@ -0,0 +1,72 @@
+table_create Memos TABLE_HASH_KEY ShortText
+[[0,0.0,0.0],true]
+load --table Memos
+[
+{"_key": "Groonga is fast!"},
+{"_key": "Mroonga is fast!"},
+{"_key": "Groonga sticker!"},
+{"_key": "Rroonga is fast!"}
+]
+[[0,0.0,0.0],4]
+select Memos   --drilldowns[n_records].output_columns _key,_nsubrecs
+[
+  [
+    0,
+    0.0,
+    0.0
+  ],
+  [
+    [
+      [
+        4
+      ],
+      [
+        [
+          "_id",
+          "UInt32"
+        ],
+        [
+          "_key",
+          "ShortText"
+        ]
+      ],
+      [
+        1,
+        "Groonga is fast!"
+      ],
+      [
+        2,
+        "Mroonga is fast!"
+      ],
+      [
+        3,
+        "Groonga sticker!"
+      ],
+      [
+        4,
+        "Rroonga is fast!"
+      ]
+    ],
+    {
+      "n_records": [
+        [
+          1
+        ],
+        [
+          [
+            "_key",
+            "ShortText"
+          ],
+          [
+            "_nsubrecs",
+            "Int32"
+          ]
+        ],
+        [
+          "_all",
+          4
+        ]
+      ]
+    }
+  ]
+]

  Added: test/command/suite/select/drilldowns/no_keys/no_calc_target.test (+12 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/select/drilldowns/no_keys/no_calc_target.test    2016-05-20 10:31:01 +0900 (8ec114b)
@@ -0,0 +1,12 @@
+table_create Memos TABLE_HASH_KEY ShortText
+
+load --table Memos
+[
+{"_key": "Groonga is fast!"},
+{"_key": "Mroonga is fast!"},
+{"_key": "Groonga sticker!"},
+{"_key": "Rroonga is fast!"}
+]
+
+select Memos \
+  --drilldowns[n_records].output_columns _key,_nsubrecs

  Added: test/command/suite/select/drilldowns/no_keys/no_table.expected (+82 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/select/drilldowns/no_keys/no_table.expected    2016-05-20 10:31:01 +0900 (86b8465)
@@ -0,0 +1,82 @@
+table_create Memos TABLE_HASH_KEY ShortText
+[[0,0.0,0.0],true]
+column_create Memos value COLUMN_SCALAR Int64
+[[0,0.0,0.0],true]
+load --table Memos
+[
+{"_key": "Groonga is fast!", "value": 10},
+{"_key": "Mroonga is fast!", "value": 2},
+{"_key": "Groonga sticker!", "value": 3},
+{"_key": "Rroonga is fast!", "value": 4}
+]
+[[0,0.0,0.0],4]
+select Memos   --drilldowns[sum].calc_types SUM   --drilldowns[sum].calc_target value   --drilldowns[sum].output_columns _key,_sum
+[
+  [
+    0,
+    0.0,
+    0.0
+  ],
+  [
+    [
+      [
+        4
+      ],
+      [
+        [
+          "_id",
+          "UInt32"
+        ],
+        [
+          "_key",
+          "ShortText"
+        ],
+        [
+          "value",
+          "Int64"
+        ]
+      ],
+      [
+        1,
+        "Groonga is fast!",
+        10
+      ],
+      [
+        2,
+        "Mroonga is fast!",
+        2
+      ],
+      [
+        3,
+        "Groonga sticker!",
+        3
+      ],
+      [
+        4,
+        "Rroonga is fast!",
+        4
+      ]
+    ],
+    {
+      "sum": [
+        [
+          1
+        ],
+        [
+          [
+            "_key",
+            "ShortText"
+          ],
+          [
+            "_sum",
+            "Int64"
+          ]
+        ],
+        [
+          "_all",
+          19
+        ]
+      ]
+    }
+  ]
+]

  Added: test/command/suite/select/drilldowns/no_keys/no_table.test (+15 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/select/drilldowns/no_keys/no_table.test    2016-05-20 10:31:01 +0900 (cda4162)
@@ -0,0 +1,15 @@
+table_create Memos TABLE_HASH_KEY ShortText
+column_create Memos value COLUMN_SCALAR Int64
+
+load --table Memos
+[
+{"_key": "Groonga is fast!", "value": 10},
+{"_key": "Mroonga is fast!", "value": 2},
+{"_key": "Groonga sticker!", "value": 3},
+{"_key": "Rroonga is fast!", "value": 4}
+]
+
+select Memos \
+  --drilldowns[sum].calc_types SUM \
+  --drilldowns[sum].calc_target value \
+  --drilldowns[sum].output_columns _key,_sum

  Copied: test/command/suite/select/drilldowns/no_keys/sum.expected (+50 -17) 52%
===================================================================
--- test/command/suite/select/drilldown/labeled/table/nonexistent.expected    2016-05-20 10:24:11 +0900 (2237313)
+++ test/command/suite/select/drilldowns/no_keys/sum.expected    2016-05-20 10:31:01 +0900 (e9b71ce)
@@ -1,7 +1,5 @@
 table_create Tags TABLE_PAT_KEY ShortText
 [[0,0.0,0.0],true]
-column_create Tags category COLUMN_SCALAR ShortText
-[[0,0.0,0.0],true]
 table_create Memos TABLE_HASH_KEY ShortText
 [[0,0.0,0.0],true]
 column_create Memos tag COLUMN_SCALAR Tags
@@ -14,22 +12,12 @@ load --table Memos
 {"_key": "Rroonga is fast!", "tag": "Rroonga"}
 ]
 [[0,0.0,0.0],4]
-load --table Tags
-[
-{"_key": "Groonga", "category": "C/C++"},
-{"_key": "Mroonga", "category": "C/C++"},
-{"_key": "Rroonga", "category": "Ruby"}
-]
-[[0,0.0,0.0],3]
-select Memos   --drilldown[category].table nonexistent   --drilldown[category].keys category   --drilldown[category].output_columns _key,_nsubrecs   --drilldown[tag].keys tag   --drilldown[tag].output_columns _key,_nsubrecs,category
+select Memos   --drilldowns[tag].keys tag   --drilldowns[tag_sum].table tag   --drilldowns[tag_sum].calc_types SUM   --drilldowns[tag_sum].calc_target _nsubrecs   --drilldowns[tag_sum].output_columns _key,_sum
 [
   [
-    [
-      -22,
-      0.0,
-      0.0
-    ],
-    "[select][drilldown][category][table] nonexistent label: <nonexistent>"
+    0,
+    0.0,
+    0.0
   ],
   [
     [
@@ -72,7 +60,52 @@ select Memos   --drilldown[category].table nonexistent   --drilldown[category].k
       ]
     ],
     {
+      "tag": [
+        [
+          3
+        ],
+        [
+          [
+            "_key",
+            "ShortText"
+          ],
+          [
+            "_nsubrecs",
+            "Int32"
+          ]
+        ],
+        [
+          "Groonga",
+          2
+        ],
+        [
+          "Mroonga",
+          1
+        ],
+        [
+          "Rroonga",
+          1
+        ]
+      ],
+      "tag_sum": [
+        [
+          1
+        ],
+        [
+          [
+            "_key",
+            "ShortText"
+          ],
+          [
+            "_sum",
+            "Int64"
+          ]
+        ],
+        [
+          "_all",
+          4
+        ]
+      ]
     }
   ]
 ]
-#|e| [select][drilldown][category][table] nonexistent label: <nonexistent>

  Added: test/command/suite/select/drilldowns/no_keys/sum.test (+19 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/select/drilldowns/no_keys/sum.test    2016-05-20 10:31:01 +0900 (a89aefc)
@@ -0,0 +1,19 @@
+table_create Tags TABLE_PAT_KEY ShortText
+
+table_create Memos TABLE_HASH_KEY ShortText
+column_create Memos tag COLUMN_SCALAR Tags
+
+load --table Memos
+[
+{"_key": "Groonga is fast!", "tag": "Groonga"},
+{"_key": "Mroonga is fast!", "tag": "Mroonga"},
+{"_key": "Groonga sticker!", "tag": "Groonga"},
+{"_key": "Rroonga is fast!", "tag": "Rroonga"}
+]
+
+select Memos \
+  --drilldowns[tag].keys tag \
+  --drilldowns[tag_sum].table tag \
+  --drilldowns[tag_sum].calc_types SUM \
+  --drilldowns[tag_sum].calc_target _nsubrecs \
+  --drilldowns[tag_sum].output_columns _key,_sum

  Added: test/command/suite/select/drilldowns/sort_keys/sub_record_column/multiple.expected (+121 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/select/drilldowns/sort_keys/sub_record_column/multiple.expected    2016-05-20 10:31:01 +0900 (84da118)
@@ -0,0 +1,121 @@
+table_create Tags TABLE_PAT_KEY ShortText
+[[0,0.0,0.0],true]
+table_create Memos TABLE_HASH_KEY ShortText
+[[0,0.0,0.0],true]
+column_create Memos tag COLUMN_SCALAR Tags
+[[0,0.0,0.0],true]
+column_create Memos date COLUMN_SCALAR Time
+[[0,0.0,0.0],true]
+load --table Memos
+[
+{"_key": "Rroonga is fast!", "tag": "Rroonga", "date": "2014-11-17 00:00:00"},
+{"_key": "Mroonga is fast!", "tag": "Mroonga", "date": "2014-11-16 00:00:00"},
+{"_key": "Groonga is fast!", "tag": "Groonga", "date": "2014-11-16 00:00:00"},
+{"_key": "Groonga sticker!", "tag": "Groonga", "date": "2014-11-16 00:00:00"},
+{"_key": "Groonga is good!", "tag": "Groonga", "date": "2014-11-17 00:00:00"}
+]
+[[0,0.0,0.0],5]
+select Memos   --command_version 2   --filter true   --drilldowns[tag].keys tag,date   --drilldowns[tag].output_columns _key[0],_key[1],_nsubrecs   --drilldowns[tag].sort_keys _value.tag._key,_value.date
+[
+  [
+    0,
+    0.0,
+    0.0
+  ],
+  [
+    [
+      [
+        5
+      ],
+      [
+        [
+          "_id",
+          "UInt32"
+        ],
+        [
+          "_key",
+          "ShortText"
+        ],
+        [
+          "date",
+          "Time"
+        ],
+        [
+          "tag",
+          "Tags"
+        ]
+      ],
+      [
+        1,
+        "Rroonga is fast!",
+        1416150000.0,
+        "Rroonga"
+      ],
+      [
+        2,
+        "Mroonga is fast!",
+        1416063600.0,
+        "Mroonga"
+      ],
+      [
+        3,
+        "Groonga is fast!",
+        1416063600.0,
+        "Groonga"
+      ],
+      [
+        4,
+        "Groonga sticker!",
+        1416063600.0,
+        "Groonga"
+      ],
+      [
+        5,
+        "Groonga is good!",
+        1416150000.0,
+        "Groonga"
+      ]
+    ],
+    {
+      "tag": [
+        [
+          4
+        ],
+        [
+          [
+            "_key[0]",
+            null
+          ],
+          [
+            "_key[1]",
+            null
+          ],
+          [
+            "_nsubrecs",
+            "Int32"
+          ]
+        ],
+        [
+          "Groonga",
+          1416063600.0,
+          2
+        ],
+        [
+          "Groonga",
+          1416150000.0,
+          1
+        ],
+        [
+          "Mroonga",
+          1416063600.0,
+          1
+        ],
+        [
+          "Rroonga",
+          1416150000.0,
+          1
+        ]
+      ]
+    }
+  ]
+]

  Added: test/command/suite/select/drilldowns/sort_keys/sub_record_column/multiple.test (+21 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/select/drilldowns/sort_keys/sub_record_column/multiple.test    2016-05-20 10:31:01 +0900 (73d69e3)
@@ -0,0 +1,21 @@
+table_create Tags TABLE_PAT_KEY ShortText
+
+table_create Memos TABLE_HASH_KEY ShortText
+column_create Memos tag COLUMN_SCALAR Tags
+column_create Memos date COLUMN_SCALAR Time
+
+load --table Memos
+[
+{"_key": "Rroonga is fast!", "tag": "Rroonga", "date": "2014-11-17 00:00:00"},
+{"_key": "Mroonga is fast!", "tag": "Mroonga", "date": "2014-11-16 00:00:00"},
+{"_key": "Groonga is fast!", "tag": "Groonga", "date": "2014-11-16 00:00:00"},
+{"_key": "Groonga sticker!", "tag": "Groonga", "date": "2014-11-16 00:00:00"},
+{"_key": "Groonga is good!", "tag": "Groonga", "date": "2014-11-17 00:00:00"}
+]
+
+select Memos \
+  --command_version 2 \
+  --filter true \
+  --drilldowns[tag].keys tag,date \
+  --drilldowns[tag].output_columns _key[0],_key[1],_nsubrecs \
+  --drilldowns[tag].sort_keys _value.tag._key,_value.date

  Added: test/command/suite/select/drilldowns/sortby/sub_record_column/multiple.expected (+121 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/select/drilldowns/sortby/sub_record_column/multiple.expected    2016-05-20 10:31:01 +0900 (c597491)
@@ -0,0 +1,121 @@
+table_create Tags TABLE_PAT_KEY ShortText
+[[0,0.0,0.0],true]
+table_create Memos TABLE_HASH_KEY ShortText
+[[0,0.0,0.0],true]
+column_create Memos tag COLUMN_SCALAR Tags
+[[0,0.0,0.0],true]
+column_create Memos date COLUMN_SCALAR Time
+[[0,0.0,0.0],true]
+load --table Memos
+[
+{"_key": "Rroonga is fast!", "tag": "Rroonga", "date": "2014-11-17 00:00:00"},
+{"_key": "Mroonga is fast!", "tag": "Mroonga", "date": "2014-11-16 00:00:00"},
+{"_key": "Groonga is fast!", "tag": "Groonga", "date": "2014-11-16 00:00:00"},
+{"_key": "Groonga sticker!", "tag": "Groonga", "date": "2014-11-16 00:00:00"},
+{"_key": "Groonga is good!", "tag": "Groonga", "date": "2014-11-17 00:00:00"}
+]
+[[0,0.0,0.0],5]
+select Memos   --command_version 2   --filter true   --drilldowns[tag].keys tag,date   --drilldowns[tag].output_columns _key[0],_key[1],_nsubrecs   --drilldowns[tag].sortby _value.tag._key,_value.date
+[
+  [
+    0,
+    0.0,
+    0.0
+  ],
+  [
+    [
+      [
+        5
+      ],
+      [
+        [
+          "_id",
+          "UInt32"
+        ],
+        [
+          "_key",
+          "ShortText"
+        ],
+        [
+          "date",
+          "Time"
+        ],
+        [
+          "tag",
+          "Tags"
+        ]
+      ],
+      [
+        1,
+        "Rroonga is fast!",
+        1416150000.0,
+        "Rroonga"
+      ],
+      [
+        2,
+        "Mroonga is fast!",
+        1416063600.0,
+        "Mroonga"
+      ],
+      [
+        3,
+        "Groonga is fast!",
+        1416063600.0,
+        "Groonga"
+      ],
+      [
+        4,
+        "Groonga sticker!",
+        1416063600.0,
+        "Groonga"
+      ],
+      [
+        5,
+        "Groonga is good!",
+        1416150000.0,
+        "Groonga"
+      ]
+    ],
+    {
+      "tag": [
+        [
+          4
+        ],
+        [
+          [
+            "_key[0]",
+            null
+          ],
+          [
+            "_key[1]",
+            null
+          ],
+          [
+            "_nsubrecs",
+            "Int32"
+          ]
+        ],
+        [
+          "Groonga",
+          1416063600.0,
+          2
+        ],
+        [
+          "Groonga",
+          1416150000.0,
+          1
+        ],
+        [
+          "Mroonga",
+          1416063600.0,
+          1
+        ],
+        [
+          "Rroonga",
+          1416150000.0,
+          1
+        ]
+      ]
+    }
+  ]
+]

  Added: test/command/suite/select/drilldowns/sortby/sub_record_column/multiple.test (+21 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/select/drilldowns/sortby/sub_record_column/multiple.test    2016-05-20 10:31:01 +0900 (e72e6e4)
@@ -0,0 +1,21 @@
+table_create Tags TABLE_PAT_KEY ShortText
+
+table_create Memos TABLE_HASH_KEY ShortText
+column_create Memos tag COLUMN_SCALAR Tags
+column_create Memos date COLUMN_SCALAR Time
+
+load --table Memos
+[
+{"_key": "Rroonga is fast!", "tag": "Rroonga", "date": "2014-11-17 00:00:00"},
+{"_key": "Mroonga is fast!", "tag": "Mroonga", "date": "2014-11-16 00:00:00"},
+{"_key": "Groonga is fast!", "tag": "Groonga", "date": "2014-11-16 00:00:00"},
+{"_key": "Groonga sticker!", "tag": "Groonga", "date": "2014-11-16 00:00:00"},
+{"_key": "Groonga is good!", "tag": "Groonga", "date": "2014-11-17 00:00:00"}
+]
+
+select Memos \
+  --command_version 2 \
+  --filter true \
+  --drilldowns[tag].keys tag,date \
+  --drilldowns[tag].output_columns _key[0],_key[1],_nsubrecs \
+  --drilldowns[tag].sortby _value.tag._key,_value.date

  Copied: test/command/suite/select/drilldowns/table/cyclic.expected (+4 -4) 71%
===================================================================
--- test/command/suite/select/drilldown/labeled/table/cyclic.expected    2016-05-20 10:24:11 +0900 (1acfbb3)
+++ test/command/suite/select/drilldowns/table/cyclic.expected    2016-05-20 10:31:01 +0900 (fbb76b5)
@@ -31,7 +31,7 @@ load --table Categories
 {"_key": "Ruby", "sub_category": "Programming language"}
 ]
 [[0,0.0,0.0],2]
-select Memos   --drilldown[category].table sub_category   --drilldown[category].keys _key   --drilldown[category].output_columns _key,_nsubrecs   --drilldown[sub_category].table category   --drilldown[sub_category].keys sub_category   --drilldown[sub_category].output_columns _key,_nsubrecs   --drilldown[tag].keys tag   --drilldown[tag].output_columns _key,_nsubrecs,category
+select Memos   --drilldowns[category].table sub_category   --drilldowns[category].keys _key   --drilldowns[category].output_columns _key,_nsubrecs   --drilldowns[sub_category].table category   --drilldowns[sub_category].keys sub_category   --drilldowns[sub_category].output_columns _key,_nsubrecs   --drilldowns[tag].keys tag   --drilldowns[tag].output_columns _key,_nsubrecs,category
 [
   [
     [
@@ -39,7 +39,7 @@ select Memos   --drilldown[category].table sub_category   --drilldown[category].
       0.0,
       0.0
     ],
-    "[select][drilldown][category][table] cycled dependency: <sub_category>"
+    "[select][drilldowns][category][table] cycled dependency: <sub_category>"
   ],
   [
     [
@@ -85,5 +85,5 @@ select Memos   --drilldown[category].table sub_category   --drilldown[category].
     }
   ]
 ]
-#|e| [select][drilldown][sub_category][table] cycled dependency: <category>
-#|e| [select][drilldown][category][table] cycled dependency: <sub_category>
+#|e| [select][drilldowns][sub_category][table] cycled dependency: <category>
+#|e| [select][drilldowns][category][table] cycled dependency: <sub_category>

  Added: test/command/suite/select/drilldowns/table/cyclic.test (+39 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/select/drilldowns/table/cyclic.test    2016-05-20 10:31:01 +0900 (638436d)
@@ -0,0 +1,39 @@
+table_create Categories TABLE_PAT_KEY ShortText
+column_create Categories sub_category COLUMN_SCALAR ShortText
+
+table_create Tags TABLE_PAT_KEY ShortText
+column_create Tags category COLUMN_SCALAR Categories
+
+table_create Memos TABLE_HASH_KEY ShortText
+column_create Memos tag COLUMN_SCALAR Tags
+
+load --table Memos
+[
+{"_key": "Groonga is fast!", "tag": "Groonga"},
+{"_key": "Mroonga is fast!", "tag": "Mroonga"},
+{"_key": "Groonga sticker!", "tag": "Groonga"},
+{"_key": "Rroonga is fast!", "tag": "Rroonga"}
+]
+
+load --table Tags
+[
+{"_key": "Groonga", "category": "C/C++"},
+{"_key": "Mroonga", "category": "C/C++"},
+{"_key": "Rroonga", "category": "Ruby"}
+]
+
+load --table Categories
+[
+{"_key": "C/C++", "sub_category": "Programming language"},
+{"_key": "Ruby", "sub_category": "Programming language"}
+]
+
+select Memos \
+  --drilldowns[category].table sub_category \
+  --drilldowns[category].keys _key \
+  --drilldowns[category].output_columns _key,_nsubrecs \
+  --drilldowns[sub_category].table category \
+  --drilldowns[sub_category].keys sub_category \
+  --drilldowns[sub_category].output_columns _key,_nsubrecs \
+  --drilldowns[tag].keys tag \
+  --drilldowns[tag].output_columns _key,_nsubrecs,category

  Copied: test/command/suite/select/drilldowns/table/empty.expected (+39 -8) 59%
===================================================================
--- test/command/suite/select/drilldown/labeled/table/nonexistent.expected    2016-05-20 10:24:11 +0900 (2237313)
+++ test/command/suite/select/drilldowns/table/empty.expected    2016-05-20 10:31:01 +0900 (856c9d0)
@@ -21,15 +21,12 @@ load --table Tags
 {"_key": "Rroonga", "category": "Ruby"}
 ]
 [[0,0.0,0.0],3]
-select Memos   --drilldown[category].table nonexistent   --drilldown[category].keys category   --drilldown[category].output_columns _key,_nsubrecs   --drilldown[tag].keys tag   --drilldown[tag].output_columns _key,_nsubrecs,category
+select Memos   --drilldowns[category].table ''   --drilldowns[category].keys category   --drilldowns[category].output_columns _key,_nsubrecs   --drilldowns[tag].keys tag   --drilldowns[tag].output_columns _key,_nsubrecs,category
 [
   [
-    [
-      -22,
-      0.0,
-      0.0
-    ],
-    "[select][drilldown][category][table] nonexistent label: <nonexistent>"
+    0,
+    0.0,
+    0.0
   ],
   [
     [
@@ -72,7 +69,41 @@ select Memos   --drilldown[category].table nonexistent   --drilldown[category].k
       ]
     ],
     {
+      "tag": [
+        [
+          3
+        ],
+        [
+          [
+            "_key",
+            "ShortText"
+          ],
+          [
+            "_nsubrecs",
+            "Int32"
+          ],
+          [
+            "category",
+            "ShortText"
+          ]
+        ],
+        [
+          "Groonga",
+          2,
+          "C/C++"
+        ],
+        [
+          "Mroonga",
+          1,
+          "C/C++"
+        ],
+        [
+          "Rroonga",
+          1,
+          "Ruby"
+        ]
+      ]
     }
   ]
 ]
-#|e| [select][drilldown][category][table] nonexistent label: <nonexistent>
+#|w| invalid sort key: <category>: table:<Memos> keys:<category>

  Added: test/command/suite/select/drilldowns/table/empty.test (+27 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/select/drilldowns/table/empty.test    2016-05-20 10:31:01 +0900 (a3ae8af)
@@ -0,0 +1,27 @@
+table_create Tags TABLE_PAT_KEY ShortText
+column_create Tags category COLUMN_SCALAR ShortText
+
+table_create Memos TABLE_HASH_KEY ShortText
+column_create Memos tag COLUMN_SCALAR Tags
+
+load --table Memos
+[
+{"_key": "Groonga is fast!", "tag": "Groonga"},
+{"_key": "Mroonga is fast!", "tag": "Mroonga"},
+{"_key": "Groonga sticker!", "tag": "Groonga"},
+{"_key": "Rroonga is fast!", "tag": "Rroonga"}
+]
+
+load --table Tags
+[
+{"_key": "Groonga", "category": "C/C++"},
+{"_key": "Mroonga", "category": "C/C++"},
+{"_key": "Rroonga", "category": "Ruby"}
+]
+
+select Memos \
+  --drilldowns[category].table '' \
+  --drilldowns[category].keys category \
+  --drilldowns[category].output_columns _key,_nsubrecs \
+  --drilldowns[tag].keys tag \
+  --drilldowns[tag].output_columns _key,_nsubrecs,category

  Copied: test/command/suite/select/drilldowns/table/nonexistent.expected (+3 -3) 76%
===================================================================
--- test/command/suite/select/drilldown/labeled/table/nonexistent.expected    2016-05-20 10:24:11 +0900 (2237313)
+++ test/command/suite/select/drilldowns/table/nonexistent.expected    2016-05-20 10:31:01 +0900 (641d798)
@@ -21,7 +21,7 @@ load --table Tags
 {"_key": "Rroonga", "category": "Ruby"}
 ]
 [[0,0.0,0.0],3]
-select Memos   --drilldown[category].table nonexistent   --drilldown[category].keys category   --drilldown[category].output_columns _key,_nsubrecs   --drilldown[tag].keys tag   --drilldown[tag].output_columns _key,_nsubrecs,category
+select Memos   --drilldowns[category].table nonexistent   --drilldowns[category].keys category   --drilldowns[category].output_columns _key,_nsubrecs   --drilldowns[tag].keys tag   --drilldowns[tag].output_columns _key,_nsubrecs,category
 [
   [
     [
@@ -29,7 +29,7 @@ select Memos   --drilldown[category].table nonexistent   --drilldown[category].k
       0.0,
       0.0
     ],
-    "[select][drilldown][category][table] nonexistent label: <nonexistent>"
+    "[select][drilldowns][category][table] nonexistent label: <nonexistent>"
   ],
   [
     [
@@ -75,4 +75,4 @@ select Memos   --drilldown[category].table nonexistent   --drilldown[category].k
     }
   ]
 ]
-#|e| [select][drilldown][category][table] nonexistent label: <nonexistent>
+#|e| [select][drilldowns][category][table] nonexistent label: <nonexistent>

  Added: test/command/suite/select/drilldowns/table/nonexistent.test (+27 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/select/drilldowns/table/nonexistent.test    2016-05-20 10:31:01 +0900 (4089abe)
@@ -0,0 +1,27 @@
+table_create Tags TABLE_PAT_KEY ShortText
+column_create Tags category COLUMN_SCALAR ShortText
+
+table_create Memos TABLE_HASH_KEY ShortText
+column_create Memos tag COLUMN_SCALAR Tags
+
+load --table Memos
+[
+{"_key": "Groonga is fast!", "tag": "Groonga"},
+{"_key": "Mroonga is fast!", "tag": "Mroonga"},
+{"_key": "Groonga sticker!", "tag": "Groonga"},
+{"_key": "Rroonga is fast!", "tag": "Rroonga"}
+]
+
+load --table Tags
+[
+{"_key": "Groonga", "category": "C/C++"},
+{"_key": "Mroonga", "category": "C/C++"},
+{"_key": "Rroonga", "category": "Ruby"}
+]
+
+select Memos \
+  --drilldowns[category].table nonexistent \
+  --drilldowns[category].keys category \
+  --drilldowns[category].output_columns _key,_nsubrecs \
+  --drilldowns[tag].keys tag \
+  --drilldowns[tag].output_columns _key,_nsubrecs,category

  Copied: test/command/suite/select/drilldowns/table/one.expected (+61 -8) 52%
===================================================================
--- test/command/suite/select/drilldown/labeled/table/nonexistent.expected    2016-05-20 10:24:11 +0900 (2237313)
+++ test/command/suite/select/drilldowns/table/one.expected    2016-05-20 10:31:01 +0900 (441955b)
@@ -21,15 +21,12 @@ load --table Tags
 {"_key": "Rroonga", "category": "Ruby"}
 ]
 [[0,0.0,0.0],3]
-select Memos   --drilldown[category].table nonexistent   --drilldown[category].keys category   --drilldown[category].output_columns _key,_nsubrecs   --drilldown[tag].keys tag   --drilldown[tag].output_columns _key,_nsubrecs,category
+select Memos   --drilldowns[category].table tag   --drilldowns[category].keys category   --drilldowns[category].output_columns _key,_nsubrecs   --drilldowns[tag].keys tag   --drilldowns[tag].output_columns _key,_nsubrecs,category
 [
   [
-    [
-      -22,
-      0.0,
-      0.0
-    ],
-    "[select][drilldown][category][table] nonexistent label: <nonexistent>"
+    0,
+    0.0,
+    0.0
   ],
   [
     [
@@ -72,7 +69,63 @@ select Memos   --drilldown[category].table nonexistent   --drilldown[category].k
       ]
     ],
     {
+      "category": [
+        [
+          2
+        ],
+        [
+          [
+            "_key",
+            "ShortText"
+          ],
+          [
+            "_nsubrecs",
+            "Int32"
+          ]
+        ],
+        [
+          "C/C++",
+          2
+        ],
+        [
+          "Ruby",
+          1
+        ]
+      ],
+      "tag": [
+        [
+          3
+        ],
+        [
+          [
+            "_key",
+            "ShortText"
+          ],
+          [
+            "_nsubrecs",
+            "Int32"
+          ],
+          [
+            "category",
+            "ShortText"
+          ]
+        ],
+        [
+          "Groonga",
+          2,
+          "C/C++"
+        ],
+        [
+          "Mroonga",
+          1,
+          "C/C++"
+        ],
+        [
+          "Rroonga",
+          1,
+          "Ruby"
+        ]
+      ]
     }
   ]
 ]
-#|e| [select][drilldown][category][table] nonexistent label: <nonexistent>

  Added: test/command/suite/select/drilldowns/table/one.test (+27 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/select/drilldowns/table/one.test    2016-05-20 10:31:01 +0900 (031b73a)
@@ -0,0 +1,27 @@
+table_create Tags TABLE_PAT_KEY ShortText
+column_create Tags category COLUMN_SCALAR ShortText
+
+table_create Memos TABLE_HASH_KEY ShortText
+column_create Memos tag COLUMN_SCALAR Tags
+
+load --table Memos
+[
+{"_key": "Groonga is fast!", "tag": "Groonga"},
+{"_key": "Mroonga is fast!", "tag": "Mroonga"},
+{"_key": "Groonga sticker!", "tag": "Groonga"},
+{"_key": "Rroonga is fast!", "tag": "Rroonga"}
+]
+
+load --table Tags
+[
+{"_key": "Groonga", "category": "C/C++"},
+{"_key": "Mroonga", "category": "C/C++"},
+{"_key": "Rroonga", "category": "Ruby"}
+]
+
+select Memos \
+  --drilldowns[category].table tag \
+  --drilldowns[category].keys category \
+  --drilldowns[category].output_columns _key,_nsubrecs \
+  --drilldowns[tag].keys tag \
+  --drilldowns[tag].output_columns _key,_nsubrecs,category

  Added: test/command/suite/select/drilldowns/table/two.expected (+166 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/select/drilldowns/table/two.expected    2016-05-20 10:31:01 +0900 (ac2121f)
@@ -0,0 +1,166 @@
+table_create Categories TABLE_PAT_KEY ShortText
+[[0,0.0,0.0],true]
+column_create Categories sub_category COLUMN_SCALAR ShortText
+[[0,0.0,0.0],true]
+table_create Tags TABLE_PAT_KEY ShortText
+[[0,0.0,0.0],true]
+column_create Tags category COLUMN_SCALAR Categories
+[[0,0.0,0.0],true]
+table_create Memos TABLE_HASH_KEY ShortText
+[[0,0.0,0.0],true]
+column_create Memos tag COLUMN_SCALAR Tags
+[[0,0.0,0.0],true]
+load --table Memos
+[
+{"_key": "Groonga is fast!", "tag": "Groonga"},
+{"_key": "Mroonga is fast!", "tag": "Mroonga"},
+{"_key": "Groonga sticker!", "tag": "Groonga"},
+{"_key": "Rroonga is fast!", "tag": "Rroonga"}
+]
+[[0,0.0,0.0],4]
+load --table Tags
+[
+{"_key": "Groonga", "category": "C/C++"},
+{"_key": "Mroonga", "category": "C/C++"},
+{"_key": "Rroonga", "category": "Ruby"}
+]
+[[0,0.0,0.0],3]
+load --table Categories
+[
+{"_key": "C/C++", "sub_category": "Programming language"},
+{"_key": "Ruby", "sub_category": "Programming language"}
+]
+[[0,0.0,0.0],2]
+select Memos   --drilldowns[category].table tag   --drilldowns[category].keys category   --drilldowns[category].output_columns _key,_nsubrecs,sub_category   --drilldowns[sub_category].table category   --drilldowns[sub_category].keys sub_category   --drilldowns[sub_category].output_columns _key,_nsubrecs   --drilldowns[tag].keys tag   --drilldowns[tag].output_columns _key,_nsubrecs,category
+[
+  [
+    0,
+    0.0,
+    0.0
+  ],
+  [
+    [
+      [
+        4
+      ],
+      [
+        [
+          "_id",
+          "UInt32"
+        ],
+        [
+          "_key",
+          "ShortText"
+        ],
+        [
+          "tag",
+          "Tags"
+        ]
+      ],
+      [
+        1,
+        "Groonga is fast!",
+        "Groonga"
+      ],
+      [
+        2,
+        "Mroonga is fast!",
+        "Mroonga"
+      ],
+      [
+        3,
+        "Groonga sticker!",
+        "Groonga"
+      ],
+      [
+        4,
+        "Rroonga is fast!",
+        "Rroonga"
+      ]
+    ],
+    {
+      "category": [
+        [
+          2
+        ],
+        [
+          [
+            "_key",
+            "ShortText"
+          ],
+          [
+            "_nsubrecs",
+            "Int32"
+          ],
+          [
+            "sub_category",
+            "ShortText"
+          ]
+        ],
+        [
+          "C/C++",
+          2,
+          "Programming language"
+        ],
+        [
+          "Ruby",
+          1,
+          "Programming language"
+        ]
+      ],
+      "sub_category": [
+        [
+          1
+        ],
+        [
+          [
+            "_key",
+            "ShortText"
+          ],
+          [
+            "_nsubrecs",
+            "Int32"
+          ]
+        ],
+        [
+          "Programming language",
+          2
+        ]
+      ],
+      "tag": [
+        [
+          3
+        ],
+        [
+          [
+            "_key",
+            "ShortText"
+          ],
+          [
+            "_nsubrecs",
+            "Int32"
+          ],
+          [
+            "category",
+            "Categories"
+          ]
+        ],
+        [
+          "Groonga",
+          2,
+          "C/C++"
+        ],
+        [
+          "Mroonga",
+          1,
+          "C/C++"
+        ],
+        [
+          "Rroonga",
+          1,
+          "Ruby"
+        ]
+      ]
+    }
+  ]
+]

  Added: test/command/suite/select/drilldowns/table/two.test (+39 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/select/drilldowns/table/two.test    2016-05-20 10:31:01 +0900 (59457ad)
@@ -0,0 +1,39 @@
+table_create Categories TABLE_PAT_KEY ShortText
+column_create Categories sub_category COLUMN_SCALAR ShortText
+
+table_create Tags TABLE_PAT_KEY ShortText
+column_create Tags category COLUMN_SCALAR Categories
+
+table_create Memos TABLE_HASH_KEY ShortText
+column_create Memos tag COLUMN_SCALAR Tags
+
+load --table Memos
+[
+{"_key": "Groonga is fast!", "tag": "Groonga"},
+{"_key": "Mroonga is fast!", "tag": "Mroonga"},
+{"_key": "Groonga sticker!", "tag": "Groonga"},
+{"_key": "Rroonga is fast!", "tag": "Rroonga"}
+]
+
+load --table Tags
+[
+{"_key": "Groonga", "category": "C/C++"},
+{"_key": "Mroonga", "category": "C/C++"},
+{"_key": "Rroonga", "category": "Ruby"}
+]
+
+load --table Categories
+[
+{"_key": "C/C++", "sub_category": "Programming language"},
+{"_key": "Ruby", "sub_category": "Programming language"}
+]
+
+select Memos \
+  --drilldowns[category].table tag \
+  --drilldowns[category].keys category \
+  --drilldowns[category].output_columns _key,_nsubrecs,sub_category \
+  --drilldowns[sub_category].table category \
+  --drilldowns[sub_category].keys sub_category \
+  --drilldowns[sub_category].output_columns _key,_nsubrecs \
+  --drilldowns[tag].keys tag \
+  --drilldowns[tag].output_columns _key,_nsubrecs,category




More information about the Groonga-commit mailing list
Back to archive index