[Groonga-commit] groonga/groonga at 08b4d7c [master] select drilldown: support dynamic column creation as initial stage

Back to archive index

Naoya Murakami null+****@clear*****
Mon May 9 21:27:06 JST 2016


Naoya Murakami	2016-05-09 21:27:06 +0900 (Mon, 09 May 2016)

  New Revision: 08b4d7c88a0914d33e7af7b33c5724cab9a1b772
  https://github.com/groonga/groonga/commit/08b4d7c88a0914d33e7af7b33c5724cab9a1b772

  Merged 95aeba5: Merge pull request #542 from naoa/drilldown-dynamic-column

  Message:
    select drilldown: support dynamic column creation as initial stage

  Added files:
    test/command/suite/select/drilldown/labeled/column/stage/initial/output_columns.expected
    test/command/suite/select/drilldown/labeled/column/stage/initial/output_columns.test
  Modified files:
    lib/proc/proc_select.c

  Modified: lib/proc/proc_select.c (+126 -4)
===================================================================
--- lib/proc/proc_select.c    2016-05-09 18:47:55 +0900 (65c009e)
+++ lib/proc/proc_select.c    2016-05-09 21:27:06 +0900 (81ccbdc)
@@ -61,9 +61,13 @@ typedef struct {
   grn_table_group_flags calc_types;
   grn_select_string calc_target_name;
   grn_select_string table_name;
+  struct {
+    grn_hash *initial;
+  } columns;
 } grn_drilldown_data;
 
 typedef enum {
+  GRN_COLUMN_STAGE_INITIAL,
   GRN_COLUMN_STAGE_FILTERED
 } grn_column_stage;
 
@@ -309,6 +313,8 @@ static const char *
 grn_column_stage_name(grn_column_stage stage)
 {
   switch (stage) {
+  case GRN_COLUMN_STAGE_INITIAL :
+    return "initial";
   case GRN_COLUMN_STAGE_FILTERED :
     return "filtered";
   default :
@@ -839,6 +845,10 @@ grn_select_drilldowns_execute(grn_ctx *ctx,
     if (keys) {
       grn_table_sort_key_close(ctx, keys, n_keys);
     }
+    if (drilldown->columns.initial) {
+      grn_select_apply_columns(ctx, result->table, drilldown->columns.initial,
+                               condition);
+    }
   }
 
 exit :
@@ -1504,7 +1514,9 @@ grn_column_data_fill(grn_ctx *ctx,
 static grn_bool
 grn_column_data_collect(grn_ctx *ctx,
                         grn_user_data *user_data,
-                        grn_hash *columns)
+                        grn_hash *columns,
+                        const char *prefix_label,
+                        size_t prefix_label_len)
 {
   grn_hash_cursor *cursor = NULL;
   cursor = grn_hash_cursor_open(ctx, columns,
@@ -1526,7 +1538,9 @@ grn_column_data_collect(grn_ctx *ctx,
     grn_snprintf(key_name,                                              \
                  GRN_TABLE_MAX_KEY_SIZE,                                \
                  GRN_TABLE_MAX_KEY_SIZE,                                \
-                 "column[%.*s]." # name,                                \
+                 "%.*scolumn[%.*s]." # name,                            \
+                 (int)prefix_label_len,                                 \
+                 prefix_label,                                          \
                  (int)(column->label.length),                           \
                  column->label.value);                                  \
     name = grn_plugin_proc_get_var(ctx, user_data, key_name, -1);
@@ -1621,7 +1635,8 @@ grn_select_data_fill_columns(grn_ctx *ctx,
     return GRN_TRUE;
   }
 
-  if (!grn_column_data_collect(ctx, user_data, data->columns.filtered)) {
+  if (!grn_column_data_collect(ctx, user_data, data->columns.filtered,
+                               NULL, 0)) {
     return GRN_FALSE;
   }
 
@@ -1629,6 +1644,98 @@ grn_select_data_fill_columns(grn_ctx *ctx,
 }
 
 static grn_bool
+grn_drilldown_data_fill_columns_collect(grn_ctx *ctx,
+                                        grn_user_data *user_data,
+                                        grn_drilldown_data *data,
+                                        const char *drilldown_label)
+{
+  grn_obj *vars;
+  grn_table_cursor *cursor;
+  const char *prefix = "column[";
+  size_t prefix_len;
+  const char *suffix = "].stage";
+  size_t suffix_len;
+  size_t drilldown_label_len = strlen(drilldown_label);
+
+  vars = grn_plugin_proc_get_vars(ctx, user_data);
+  cursor = grn_table_cursor_open(ctx, vars, NULL, 0, NULL, 0, 0, -1, 0);
+  if (!cursor) {
+    return GRN_FALSE;
+  }
+
+  prefix_len = strlen(prefix);
+  suffix_len = strlen(suffix);
+  while (grn_table_cursor_next(ctx, cursor)) {
+    void *key;
+    char *name;
+    int name_len;
+    void *value_raw;
+    grn_obj *value;
+    grn_column_stage stage;
+
+    name_len = grn_table_cursor_get_key(ctx, cursor, &key);
+    name = key;
+
+    name += drilldown_label_len;
+    name_len -= drilldown_label_len;
+
+    if (name_len < prefix_len + suffix_len + 1) {
+      continue;
+    }
+
+    if (memcmp(prefix, name, prefix_len) != 0) {
+      continue;
+    }
+
+    if (memcmp(suffix, name + (name_len - suffix_len), suffix_len) != 0) {
+      continue;
+    }
+
+    grn_table_cursor_get_value(ctx, cursor, &value_raw);
+    value = value_raw;
+    if (GRN_BULK_EQUAL_STRING(value, "initial")) {
+      stage = GRN_COLUMN_STAGE_INITIAL;
+    } else {
+      continue;
+    }
+
+    if (!grn_column_data_init(ctx,
+                              name + prefix_len,
+                              name_len - prefix_len - suffix_len,
+                              stage,
+                              &(data->columns.initial))) {
+      grn_table_cursor_close(ctx, cursor);
+      return GRN_FALSE;
+    }
+  }
+  grn_table_cursor_close(ctx, cursor);
+
+  return GRN_TRUE;
+}
+
+static grn_bool
+grn_drilldown_data_fill_columns(grn_ctx *ctx,
+                                grn_user_data *user_data,
+                                grn_drilldown_data *data,
+                                const char *drilldown_label)
+{
+  if (!grn_drilldown_data_fill_columns_collect(ctx, user_data, data,
+                                               drilldown_label)) {
+    return GRN_FALSE;
+  }
+
+  if (!data->columns.initial) {
+    return GRN_TRUE;
+  }
+
+  if (!grn_column_data_collect(ctx, user_data, data->columns.initial,
+                               drilldown_label, strlen(drilldown_label))) {
+    return GRN_FALSE;
+  }
+  return GRN_TRUE;
+}
+
+static grn_bool
 grn_select_data_fill_drilldown_labels(grn_ctx *ctx,
                                       grn_user_data *user_data,
                                       grn_select_data *data)
@@ -1702,6 +1809,7 @@ grn_select_data_fill_drilldowns(grn_ctx *ctx,
     drilldown_data = &(data->drilldowns[0]);
     drilldown_data->label.value = NULL;
     drilldown_data->label.length = 0;
+    drilldown_data->columns.initial = NULL;
     grn_drilldown_data_fill(ctx,
                             drilldown_data,
                             drilldown,
@@ -1746,6 +1854,7 @@ grn_select_data_fill_drilldowns(grn_ctx *ctx,
       grn_drilldown_data *drilldown = &(data->drilldowns[i]);
         const char *label;
         int label_len;
+        char drilldown_label[GRN_TABLE_MAX_KEY_SIZE];
         char key_name[GRN_TABLE_MAX_KEY_SIZE];
         grn_obj *keys;
         grn_obj *sortby;
@@ -1759,12 +1868,16 @@ grn_select_data_fill_drilldowns(grn_ctx *ctx,
         label_len = grn_table_cursor_get_key(ctx, cursor, (void **)&label);
         drilldown->label.value = label;
         drilldown->label.length = label_len;
+        grn_snprintf(drilldown_label,
+                     GRN_TABLE_MAX_KEY_SIZE,
+                     GRN_TABLE_MAX_KEY_SIZE,
+                     "drilldown[%.*s].", label_len, label);
 
 #define GET_VAR(name)                                                   \
         grn_snprintf(key_name,                                          \
                      GRN_TABLE_MAX_KEY_SIZE,                            \
                      GRN_TABLE_MAX_KEY_SIZE,                            \
-                     "drilldown[%.*s]." # name, label_len, label);      \
+                     "%s" # name, drilldown_label);                     \
         name = grn_plugin_proc_get_var(ctx, user_data, key_name, -1);
 
         GET_VAR(keys);
@@ -1778,6 +1891,8 @@ grn_select_data_fill_drilldowns(grn_ctx *ctx,
 
 #undef GET_VAR
 
+        grn_drilldown_data_fill_columns(ctx, user_data, drilldown,
+                                        drilldown_label);
         grn_drilldown_data_fill(ctx, drilldown,
                                 keys, sortby, output_columns, offset, limit,
                                 calc_types, calc_target, table);
@@ -1881,6 +1996,13 @@ exit :
   }
 
   if (data.drilldowns) {
+    int i;
+    for (i = 0; i < data.n_drilldowns; i++) {
+      grn_drilldown_data *drilldown = &(data.drilldowns[i]);
+      if (drilldown->columns.initial) {
+        grn_hash_close(ctx, drilldown->columns.initial);
+      }
+    }
     GRN_PLUGIN_FREE(ctx, data.drilldowns);
   }
   if (data.drilldown_labels) {

  Added: test/command/suite/select/drilldown/labeled/column/stage/initial/output_columns.expected (+109 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/select/drilldown/labeled/column/stage/initial/output_columns.expected    2016-05-09 21:27:06 +0900 (2ccba59)
@@ -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   --drilldown[label].keys price   --drilldown[label].output_columns _key,_nsubrecs,tax_included   --drilldown[label].column[tax_included].stage initial   --drilldown[label].column[tax_included].type UInt32   --drilldown[label].column[tax_included].flags COLUMN_SCALAR   --drilldown[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/drilldown/labeled/column/stage/initial/output_columns.test (+20 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/select/drilldown/labeled/column/stage/initial/output_columns.test    2016-05-09 21:27:06 +0900 (1f23c41)
@@ -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 \
+  --drilldown[label].keys price \
+  --drilldown[label].output_columns _key,_nsubrecs,tax_included \
+  --drilldown[label].column[tax_included].stage initial \
+  --drilldown[label].column[tax_included].type UInt32 \
+  --drilldown[label].column[tax_included].flags COLUMN_SCALAR \
+  --drilldown[label].column[tax_included].value '_key * 1.08'
-------------- next part --------------
HTML����������������������������...
Download 



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