[Groonga-commit] groonga/groonga at 532024b [master] io_flush: revert recursive=yes behavior and add recursive=dependent

Back to archive index
Kouhei Sutou null+****@clear*****
Wed Apr 17 10:17:28 JST 2019


Kouhei Sutou	2019-04-17 10:17:28 +0900 (Wed, 17 Apr 2019)

  Revision: 532024b99d4a035444e26a2631a50eebc0b3393f
  https://github.com/groonga/groonga/commit/532024b99d4a035444e26a2631a50eebc0b3393f

  Message:
    io_flush: revert recursive=yes behavior and add recursive=dependent
    
    TODO: more test

  Added files:
    test/command/suite/io_flush/recursive/dependent/data_column/have_index.expected
    test/command/suite/io_flush/recursive/dependent/data_column/have_index.test
    test/command/suite/io_flush/recursive/dependent/data_column/no_index.expected
    test/command/suite/io_flush/recursive/dependent/data_column/no_index.test
    test/command/suite/io_flush/recursive/dependent/data_column/reference.expected
    test/command/suite/io_flush/recursive/dependent/data_column/reference.test
    test/command/suite/io_flush/recursive/dependent/index_column/source_column.expected
    test/command/suite/io_flush/recursive/dependent/index_column/source_column.test
    test/command/suite/io_flush/recursive/dependent/index_column/source_key.expected
    test/command/suite/io_flush/recursive/dependent/index_column/source_key.test
    test/command/suite/io_flush/recursive/dependent/index_column/sources.expected
    test/command/suite/io_flush/recursive/dependent/index_column/sources.test
    test/command/suite/io_flush/recursive/dependent/table/reference.expected
    test/command/suite/io_flush/recursive/dependent/table/reference.test
  Modified files:
    include/groonga/groonga.h
    lib/db.c
    lib/proc.c
    test/command/suite/io_flush/default.expected
    test/command/suite/io_flush/many_data.expected
    test/command/suite/io_flush/target_name/column.expected
    test/command/suite/io_flush/target_name/invalid.expected
    test/command/suite/io_flush/target_name/table.expected

  Modified: include/groonga/groonga.h (+1 -1)
===================================================================
--- include/groonga/groonga.h    2019-04-15 18:00:02 +0900 (7ed36b718)
+++ include/groonga/groonga.h    2019-04-17 10:17:28 +0900 (bf00cc8e5)
@@ -779,7 +779,7 @@ GRN_API grn_rc grn_obj_clear_lock(grn_ctx *ctx, grn_obj *obj);
 GRN_API unsigned int grn_obj_is_locked(grn_ctx *ctx, grn_obj *obj);
 GRN_API grn_rc grn_obj_flush(grn_ctx *ctx, grn_obj *obj);
 GRN_API grn_rc grn_obj_flush_recursive(grn_ctx *ctx, grn_obj *obj);
-GRN_API grn_rc grn_obj_flush_dependent(grn_ctx *ctx, grn_obj *obj);
+GRN_API grn_rc grn_obj_flush_recursive_dependent(grn_ctx *ctx, grn_obj *obj);
 GRN_API int grn_obj_defrag(grn_ctx *ctx, grn_obj *obj, int threshold);
 
 GRN_API grn_obj *grn_obj_db(grn_ctx *ctx, grn_obj *obj);

  Modified: lib/db.c (+321 -113)
===================================================================
--- lib/db.c    2019-04-15 18:00:02 +0900 (019e48263)
+++ lib/db.c    2019-04-17 10:17:28 +0900 (a16d0dfee)
@@ -12375,12 +12375,13 @@ grn_obj_flush(grn_ctx *ctx, grn_obj *obj)
 typedef struct {
   grn_hash *flushed;
   bool is_close_opened_object_mode;
-} flush_recursive_data;
+  bool is_top_level;
+} flush_recursive_dependent_data;
 
 static bool
-grn_obj_flush_recursive_need_flush(grn_ctx *ctx,
-                                   flush_recursive_data *data,
-                                   grn_id id)
+grn_obj_flush_recursive_dependent_need_flush(grn_ctx *ctx,
+                                             flush_recursive_dependent_data *data,
+                                             grn_id id)
 {
   int added = 0;
   grn_id flushed_id = grn_hash_add(ctx,
@@ -12396,7 +12397,8 @@ grn_obj_flush_recursive_need_flush(grn_ctx *ctx,
     char message[GRN_CTX_MSGSIZE];
     grn_strcpy(message, GRN_CTX_MSGSIZE, ctx->errbuf);
     ERR(rc,
-        "[io_flush] failed to register flushed ID: <%u>: %s",
+        "[io][flush][recursive][dependent] "
+        "failed to register flushed ID: <%u>: %s",
         id,
         message);
     return false;
@@ -12405,17 +12407,17 @@ grn_obj_flush_recursive_need_flush(grn_ctx *ctx,
 }
 
 static void
-grn_obj_flush_recursive_internal(grn_ctx *ctx,
-                                 grn_obj *obj,
-                                 flush_recursive_data *data);
+grn_obj_flush_recursive_dependent_internal(grn_ctx *ctx,
+                                           grn_obj *obj,
+                                           flush_recursive_dependent_data *data);
 
 static void
-grn_obj_flush_recursive_internal_db(grn_ctx *ctx,
-                                    grn_obj *db,
-                                    flush_recursive_data *data)
+grn_obj_flush_recursive_dependent_internal_db(grn_ctx *ctx,
+                                              grn_obj *db,
+                                              flush_recursive_dependent_data *data)
 {
   GRN_TABLE_EACH_BEGIN(ctx, db, cursor, id) {
-    if (!grn_obj_flush_recursive_need_flush(ctx, data, id)) {
+    if (!grn_obj_flush_recursive_dependent_need_flush(ctx, data, id)) {
       if (ctx->rc == GRN_SUCCESS) {
         continue;
       } else {
@@ -12429,7 +12431,8 @@ grn_obj_flush_recursive_internal_db(grn_ctx *ctx,
 
     grn_obj *object = grn_ctx_at(ctx, id);
     if (grn_obj_is_table(ctx, object)) {
-      grn_obj_flush_recursive_internal(ctx, object, data);
+      data->is_top_level = true;
+      grn_obj_flush_recursive_dependent_internal(ctx, object, data);
     } else {
       if (ctx->rc != GRN_SUCCESS) {
         ERRCLR(ctx);
@@ -12452,19 +12455,22 @@ grn_obj_flush_recursive_internal_db(grn_ctx *ctx,
 }
 
 static void
-grn_obj_flush_recursive_internal_table(grn_ctx *ctx,
-                                       grn_obj *table,
-                                       flush_recursive_data *data)
+grn_obj_flush_recursive_dependent_internal_table(grn_ctx *ctx,
+                                                 grn_obj *table,
+                                                 flush_recursive_dependent_data *data)
 {
+  const bool is_top_level = data->is_top_level;
+  data->is_top_level = false;
+
   if (grn_obj_is_lexicon(ctx, table)) {
     grn_id domain_id = table->header.domain;
-    if (grn_obj_flush_recursive_need_flush(ctx, data, domain_id)) {
+    if (grn_obj_flush_recursive_dependent_need_flush(ctx, data, domain_id)) {
       if (data->is_close_opened_object_mode) {
         grn_ctx_push_temporary_open_space(ctx);
       }
       grn_obj *domain = grn_ctx_at(ctx, domain_id);
       if (grn_obj_is_table(ctx, domain)) {
-        grn_obj_flush_recursive_internal(ctx, domain, data);
+        grn_obj_flush_recursive_dependent_internal(ctx, domain, data);
       }
       if (data->is_close_opened_object_mode) {
         grn_ctx_pop_temporary_open_space(ctx);
@@ -12473,104 +12479,136 @@ grn_obj_flush_recursive_internal_table(grn_ctx *ctx,
     if (ctx->rc != GRN_SUCCESS) {
       return;
     }
-  }
 
-  grn_hash *columns = grn_hash_create(ctx,
-                                      NULL,
-                                      sizeof(grn_id),
-                                      0,
-                                      GRN_OBJ_TABLE_HASH_KEY | GRN_HASH_TINY);
-  if (!columns) {
-    grn_rc rc = ctx->rc;
-    if (rc == GRN_SUCCESS) {
-      rc = GRN_NO_MEMORY_AVAILABLE;
+    for (grn_hook *hooks = DB_OBJ(table)->hooks[GRN_HOOK_INSERT];
+         hooks;
+         hooks = hooks->next) {
+      grn_obj_default_set_value_hook_data *hook_data =
+        (grn_obj_default_set_value_hook_data *)GRN_NEXT_ADDR(hooks);
+      if (grn_obj_flush_recursive_dependent_need_flush(ctx,
+                                                       data,
+                                                       hook_data->target)) {
+        if (data->is_close_opened_object_mode) {
+          grn_ctx_push_temporary_open_space(ctx);
+        }
+        grn_obj *index = grn_ctx_at(ctx, hook_data->target);
+        if (index) {
+          grn_obj_flush_recursive_dependent_internal(ctx, index, data);
+        }
+        if (data->is_close_opened_object_mode) {
+          grn_ctx_pop_temporary_open_space(ctx);
+        }
+        if (ctx->rc != GRN_SUCCESS) {
+          return;
+        }
+      }
     }
-    char message[GRN_CTX_MSGSIZE];
-    grn_strcpy(message, GRN_CTX_MSGSIZE, ctx->errbuf);
-    char table_name[GRN_TABLE_MAX_KEY_SIZE];
-    int table_name_size;
-    table_name_size = grn_obj_name(ctx,
-                                   table,
-                                   table_name,
-                                   GRN_TABLE_MAX_KEY_SIZE);
-    ERR(rc,
-        "[io_flush] failed to create internal hash table "
-        "to store columns: <%.*s>: %s",
-        table_name_size, table_name,
-        message);
-    return;
   }
 
-  if (grn_table_columns(ctx, table, "", 0, (grn_obj *)columns) > 0) {
-    GRN_HASH_EACH_BEGIN(ctx, columns, cursor, id) {
-      void *key;
-      if (grn_hash_cursor_get_key(ctx, cursor, &key) == 0) {
-        continue;
+  if (is_top_level) {
+    grn_hash *columns = grn_hash_create(ctx,
+                                        NULL,
+                                        sizeof(grn_id),
+                                        0,
+                                        GRN_OBJ_TABLE_HASH_KEY | GRN_HASH_TINY);
+    if (!columns) {
+      grn_rc rc = ctx->rc;
+      if (rc == GRN_SUCCESS) {
+        rc = GRN_NO_MEMORY_AVAILABLE;
       }
+      char message[GRN_CTX_MSGSIZE];
+      grn_strcpy(message, GRN_CTX_MSGSIZE, ctx->errbuf);
+      char table_name[GRN_TABLE_MAX_KEY_SIZE];
+      int table_name_size;
+      table_name_size = grn_obj_name(ctx,
+                                     table,
+                                     table_name,
+                                     GRN_TABLE_MAX_KEY_SIZE);
+      ERR(rc,
+          "[io][flush][recursive][dependent] "
+          "failed to create internal hash table "
+          "to store columns: <%.*s>: %s",
+          table_name_size, table_name,
+          message);
+      return;
+    }
 
-      grn_id *column_id = key;
-      if (!grn_obj_flush_recursive_need_flush(ctx, data, *column_id)) {
-        if (ctx->rc == GRN_SUCCESS) {
+    if (grn_table_columns(ctx, table, "", 0, (grn_obj *)columns) > 0) {
+      GRN_HASH_EACH_BEGIN(ctx, columns, cursor, id) {
+        void *key;
+        if (grn_hash_cursor_get_key(ctx, cursor, &key) == 0) {
           continue;
-        } else {
-          break;
         }
-      }
 
-      if (data->is_close_opened_object_mode) {
-        grn_ctx_push_temporary_open_space(ctx);
-      }
-      grn_obj *column = grn_ctx_at(ctx, *column_id);
-      if (column) {
-        grn_obj_flush_recursive_internal(ctx, column, data);
-      }
-      if (data->is_close_opened_object_mode) {
-        grn_ctx_pop_temporary_open_space(ctx);
-      }
+        grn_id *column_id = key;
+        if (!grn_obj_flush_recursive_dependent_need_flush(ctx, data, *column_id)) {
+          if (ctx->rc == GRN_SUCCESS) {
+            continue;
+          } else {
+            break;
+          }
+        }
 
-      if (ctx->rc != GRN_SUCCESS) {
-        break;
-      }
-    } GRN_HASH_EACH_END(ctx, cursor);
-  }
-  grn_hash_close(ctx, columns);
-  if (ctx->rc != GRN_SUCCESS) {
-    return;
+        if (data->is_close_opened_object_mode) {
+          grn_ctx_push_temporary_open_space(ctx);
+        }
+        grn_obj *column = grn_ctx_at(ctx, *column_id);
+        if (column) {
+          grn_obj_flush_recursive_dependent_internal(ctx, column, data);
+        }
+        if (data->is_close_opened_object_mode) {
+          grn_ctx_pop_temporary_open_space(ctx);
+        }
+
+        if (ctx->rc != GRN_SUCCESS) {
+          break;
+        }
+      } GRN_HASH_EACH_END(ctx, cursor);
+    }
+    grn_hash_close(ctx, columns);
+    if (ctx->rc != GRN_SUCCESS) {
+      return;
+    }
   }
 
   grn_obj_flush(ctx, table);
 }
 
 static void
-grn_obj_flush_recursive_internal_column_data(grn_ctx *ctx,
-                                             grn_obj *column,
-                                             flush_recursive_data *data)
+grn_obj_flush_recursive_dependent_internal_column_data(grn_ctx *ctx,
+                                                       grn_obj *column,
+                                                       flush_recursive_dependent_data *data)
 {
-  grn_id table_id = column->header.domain;
-  if (grn_obj_flush_recursive_need_flush(ctx, data, table_id)) {
-    if (data->is_close_opened_object_mode) {
-      grn_ctx_push_temporary_open_space(ctx);
-    }
-    grn_obj *table = grn_ctx_at(ctx, table_id);
-    if (table) {
-      grn_obj_flush_recursive_internal(ctx, table, data);
+  const bool is_top_level = data->is_top_level;
+  data->is_top_level = false;
+
+  if (is_top_level) {
+    const grn_id table_id = column->header.domain;
+    if (grn_obj_flush_recursive_dependent_need_flush(ctx, data, table_id)) {
+      if (data->is_close_opened_object_mode) {
+        grn_ctx_push_temporary_open_space(ctx);
+      }
+      grn_obj *table = grn_ctx_at(ctx, table_id);
+      if (table) {
+        grn_obj_flush_recursive_dependent_internal(ctx, table, data);
+      }
+      if (data->is_close_opened_object_mode) {
+        grn_ctx_pop_temporary_open_space(ctx);
+      }
     }
-    if (data->is_close_opened_object_mode) {
-      grn_ctx_pop_temporary_open_space(ctx);
+    if (ctx->rc != GRN_SUCCESS) {
+      return;
     }
   }
-  if (ctx->rc != GRN_SUCCESS) {
-    return;
-  }
 
-  grn_id range_id = grn_obj_get_range(ctx, column);
-  if (grn_obj_flush_recursive_need_flush(ctx, data, range_id)) {
+  const grn_id range_id = grn_obj_get_range(ctx, column);
+  if (grn_obj_flush_recursive_dependent_need_flush(ctx, data, range_id)) {
     if (data->is_close_opened_object_mode) {
       grn_ctx_push_temporary_open_space(ctx);
     }
     grn_obj *range = grn_ctx_at(ctx, range_id);
     if (grn_obj_is_table(ctx, range)) {
-      grn_obj_flush_recursive_internal(ctx, range, data);
+      grn_obj_flush_recursive_dependent_internal(ctx, range, data);
     }
     if (data->is_close_opened_object_mode) {
       grn_ctx_pop_temporary_open_space(ctx);
@@ -12585,13 +12623,15 @@ grn_obj_flush_recursive_internal_column_data(grn_ctx *ctx,
        hooks = hooks->next) {
     grn_obj_default_set_value_hook_data *hook_data =
       (grn_obj_default_set_value_hook_data *)GRN_NEXT_ADDR(hooks);
-    if (grn_obj_flush_recursive_need_flush(ctx, data, hook_data->target)) {
+    if (grn_obj_flush_recursive_dependent_need_flush(ctx,
+                                                     data,
+                                                     hook_data->target)) {
       if (data->is_close_opened_object_mode) {
         grn_ctx_push_temporary_open_space(ctx);
       }
       grn_obj *index = grn_ctx_at(ctx, hook_data->target);
       if (index) {
-        grn_obj_flush_recursive_internal(ctx, index, data);
+        grn_obj_flush_recursive_dependent_internal(ctx, index, data);
       }
       if (data->is_close_opened_object_mode) {
         grn_ctx_pop_temporary_open_space(ctx);
@@ -12606,18 +12646,20 @@ grn_obj_flush_recursive_internal_column_data(grn_ctx *ctx,
 }
 
 static void
-grn_obj_flush_recursive_internal_column_index(grn_ctx *ctx,
-                                              grn_obj *column,
-                                              flush_recursive_data *data)
+grn_obj_flush_recursive_dependent_internal_column_index(grn_ctx *ctx,
+                                                        grn_obj *column,
+                                                        flush_recursive_dependent_data *data)
 {
+  data->is_top_level = false;
+
   grn_id lexicon_id = column->header.domain;
-  if (grn_obj_flush_recursive_need_flush(ctx, data, lexicon_id)) {
+  if (grn_obj_flush_recursive_dependent_need_flush(ctx, data, lexicon_id)) {
     if (data->is_close_opened_object_mode) {
       grn_ctx_push_temporary_open_space(ctx);
     }
     grn_obj *lexicon = grn_ctx_at(ctx, lexicon_id);
     if (lexicon) {
-      grn_obj_flush_recursive_internal(ctx, lexicon, data);
+      grn_obj_flush_recursive_dependent_internal(ctx, lexicon, data);
     }
     if (data->is_close_opened_object_mode) {
       grn_ctx_pop_temporary_open_space(ctx);
@@ -12630,10 +12672,10 @@ grn_obj_flush_recursive_internal_column_index(grn_ctx *ctx,
   grn_obj source_ids;
   GRN_UINT32_INIT(&source_ids, GRN_OBJ_VECTOR);
   grn_obj_get_info(ctx, column, GRN_INFO_SOURCE, &source_ids);
-  size_t n = GRN_UINT32_VECTOR_SIZE(&source_ids);
+  const size_t n = GRN_UINT32_VECTOR_SIZE(&source_ids);
   for (size_t i = 0; i < n; i++) {
     grn_id source_id = GRN_UINT32_VALUE_AT(&source_ids, i);
-    if (!grn_obj_flush_recursive_need_flush(ctx, data, source_id)) {
+    if (!grn_obj_flush_recursive_dependent_need_flush(ctx, data, source_id)) {
       if (ctx->rc == GRN_SUCCESS) {
         continue;
       } else {
@@ -12645,7 +12687,7 @@ grn_obj_flush_recursive_internal_column_index(grn_ctx *ctx,
     }
     grn_obj *source = grn_ctx_at(ctx, source_id);
     if (source) {
-      grn_obj_flush_recursive_internal(ctx, source, data);
+      grn_obj_flush_recursive_dependent_internal(ctx, source, data);
     }
     if (data->is_close_opened_object_mode) {
       grn_ctx_pop_temporary_open_space(ctx);
@@ -12663,26 +12705,26 @@ grn_obj_flush_recursive_internal_column_index(grn_ctx *ctx,
 }
 
 static void
-grn_obj_flush_recursive_internal(grn_ctx *ctx,
-                                 grn_obj *obj,
-                                 flush_recursive_data *data)
+grn_obj_flush_recursive_dependent_internal(grn_ctx *ctx,
+                                           grn_obj *obj,
+                                           flush_recursive_dependent_data *data)
 {
   switch (obj->header.type) {
   case GRN_DB :
-    grn_obj_flush_recursive_internal_db(ctx, obj, data);
+    grn_obj_flush_recursive_dependent_internal_db(ctx, obj, data);
     break;
   case GRN_TABLE_NO_KEY :
   case GRN_TABLE_HASH_KEY :
   case GRN_TABLE_PAT_KEY :
   case GRN_TABLE_DAT_KEY :
-    grn_obj_flush_recursive_internal_table(ctx, obj, data);
+    grn_obj_flush_recursive_dependent_internal_table(ctx, obj, data);
     break;
   case GRN_COLUMN_FIX_SIZE :
   case GRN_COLUMN_VAR_SIZE :
-    grn_obj_flush_recursive_internal_column_data(ctx, obj, data);
+    grn_obj_flush_recursive_dependent_internal_column_data(ctx, obj, data);
     break;
   case GRN_COLUMN_INDEX :
-    grn_obj_flush_recursive_internal_column_index(ctx, obj, data);
+    grn_obj_flush_recursive_dependent_internal_column_index(ctx, obj, data);
     break;
   default :
     {
@@ -12690,7 +12732,8 @@ grn_obj_flush_recursive_internal(grn_ctx *ctx,
       GRN_TEXT_INIT(&inspected, 0);
       grn_inspect(ctx, &inspected, obj);
       ERR(GRN_INVALID_ARGUMENT,
-          "[flush] object must be DB, table or column: <%.*s>",
+          "[io][flush][recursive][dependent] "
+          "object must be DB, table or column: <%.*s>",
           (int)GRN_TEXT_LEN(&inspected),
           GRN_TEXT_VALUE(&inspected));
       GRN_OBJ_FIN(ctx, &inspected);
@@ -12700,11 +12743,11 @@ grn_obj_flush_recursive_internal(grn_ctx *ctx,
 }
 
 grn_rc
-grn_obj_flush_recursive(grn_ctx *ctx, grn_obj *obj)
+grn_obj_flush_recursive_dependent(grn_ctx *ctx, grn_obj *obj)
 {
   GRN_API_ENTER;
 
-  flush_recursive_data data;
+  flush_recursive_dependent_data data;
   data.flushed = grn_hash_create(ctx, NULL, sizeof(grn_id), 0,
                                  GRN_OBJ_TABLE_HASH_KEY|GRN_HASH_TINY);
   if (!data.flushed) {
@@ -12718,7 +12761,8 @@ grn_obj_flush_recursive(grn_ctx *ctx, grn_obj *obj)
     int name_size;
     name_size = grn_obj_name(ctx, obj, name, GRN_TABLE_MAX_KEY_SIZE);
     ERR(rc,
-        "[flush][recursive] failed to create an internal hash table "
+        "[io][flush][recursive][dependent] "
+        "failed to create an internal hash table "
         "to manage flushed objects: <%.*s>: %s",
         name_size, name,
         message);
@@ -12728,8 +12772,9 @@ grn_obj_flush_recursive(grn_ctx *ctx, grn_obj *obj)
   data.is_close_opened_object_mode = (grn_thread_get_limit() == 1);
 
   grn_id id = grn_obj_id(ctx, obj);
-  if (grn_obj_flush_recursive_need_flush(ctx, &data, id)) {
-    grn_obj_flush_recursive_internal(ctx, obj, &data);
+  if (grn_obj_flush_recursive_dependent_need_flush(ctx, &data, id)) {
+    data.is_top_level = true;
+    grn_obj_flush_recursive_dependent_internal(ctx, obj, &data);
   }
 
   grn_hash_close(ctx, data.flushed);
@@ -12737,6 +12782,169 @@ grn_obj_flush_recursive(grn_ctx *ctx, grn_obj *obj)
   GRN_API_RETURN(ctx->rc);
 }
 
+typedef struct {
+  bool is_close_opened_object_mode;
+} flush_recursive_data;
+
+static void
+grn_obj_flush_recursive_internal(grn_ctx *ctx,
+                                 grn_obj *obj,
+                                 flush_recursive_data *data);
+
+static void
+grn_obj_flush_recursive_internal_db(grn_ctx *ctx,
+                                    grn_obj *db,
+                                    flush_recursive_data *data)
+{
+  GRN_TABLE_EACH_BEGIN(ctx, db, cursor, id) {
+    if (data->is_close_opened_object_mode) {
+      grn_ctx_push_temporary_open_space(ctx);
+    }
+
+    grn_obj *object = grn_ctx_at(ctx, id);
+    if (grn_obj_is_table(ctx, object)) {
+      grn_obj_flush_recursive_internal(ctx, object, data);
+    } else {
+      if (ctx->rc != GRN_SUCCESS) {
+        ERRCLR(ctx);
+      }
+    }
+
+    if (data->is_close_opened_object_mode) {
+      grn_ctx_pop_temporary_open_space(ctx);
+    }
+
+    if (ctx->rc != GRN_SUCCESS) {
+      break;
+    }
+  } GRN_TABLE_EACH_END(ctx, cursor);
+  if (ctx->rc != GRN_SUCCESS) {
+    return;
+  }
+
+  grn_obj_flush(ctx, db);
+}
+
+static void
+grn_obj_flush_recursive_internal_table(grn_ctx *ctx,
+                                       grn_obj *table,
+                                       flush_recursive_data *data)
+{
+  grn_hash *columns = grn_hash_create(ctx,
+                                      NULL,
+                                      sizeof(grn_id),
+                                      0,
+                                      GRN_OBJ_TABLE_HASH_KEY | GRN_HASH_TINY);
+  if (!columns) {
+    grn_rc rc = ctx->rc;
+    if (rc == GRN_SUCCESS) {
+      rc = GRN_NO_MEMORY_AVAILABLE;
+    }
+    char message[GRN_CTX_MSGSIZE];
+    grn_strcpy(message, GRN_CTX_MSGSIZE, ctx->errbuf);
+    char table_name[GRN_TABLE_MAX_KEY_SIZE];
+    int table_name_size;
+    table_name_size = grn_obj_name(ctx,
+                                   table,
+                                   table_name,
+                                   GRN_TABLE_MAX_KEY_SIZE);
+    ERR(rc,
+        "[io][flush][recursive] "
+        "failed to create internal hash table "
+        "to store columns: <%.*s>: %s",
+        table_name_size, table_name,
+        message);
+    return;
+  }
+
+  if (grn_table_columns(ctx, table, "", 0, (grn_obj *)columns) > 0) {
+    GRN_HASH_EACH_BEGIN(ctx, columns, cursor, id) {
+      void *key;
+      if (grn_hash_cursor_get_key(ctx, cursor, &key) == 0) {
+        continue;
+      }
+
+      if (data->is_close_opened_object_mode) {
+        grn_ctx_push_temporary_open_space(ctx);
+      }
+      grn_id *column_id = key;
+      grn_obj *column = grn_ctx_at(ctx, *column_id);
+      if (column) {
+        grn_obj_flush_recursive_internal(ctx, column, data);
+      }
+      if (data->is_close_opened_object_mode) {
+        grn_ctx_pop_temporary_open_space(ctx);
+      }
+
+      if (ctx->rc != GRN_SUCCESS) {
+        break;
+      }
+    } GRN_HASH_EACH_END(ctx, cursor);
+  }
+  grn_hash_close(ctx, columns);
+  if (ctx->rc != GRN_SUCCESS) {
+    return;
+  }
+
+  grn_obj_flush(ctx, table);
+}
+
+static void
+grn_obj_flush_recursive_internal_column(grn_ctx *ctx,
+                                        grn_obj *column,
+                                        flush_recursive_data *data)
+{
+  grn_obj_flush(ctx, column);
+}
+
+static void
+grn_obj_flush_recursive_internal(grn_ctx *ctx,
+                                 grn_obj *obj,
+                                 flush_recursive_data *data)
+{
+  switch (obj->header.type) {
+  case GRN_DB :
+    grn_obj_flush_recursive_internal_db(ctx, obj, data);
+    break;
+  case GRN_TABLE_NO_KEY :
+  case GRN_TABLE_HASH_KEY :
+  case GRN_TABLE_PAT_KEY :
+  case GRN_TABLE_DAT_KEY :
+    grn_obj_flush_recursive_internal_table(ctx, obj, data);
+    break;
+  case GRN_COLUMN_FIX_SIZE :
+  case GRN_COLUMN_VAR_SIZE :
+  case GRN_COLUMN_INDEX :
+    grn_obj_flush_recursive_internal_column(ctx, obj, data);
+    break;
+  default :
+    {
+      grn_obj inspected;
+      GRN_TEXT_INIT(&inspected, 0);
+      grn_inspect(ctx, &inspected, obj);
+      ERR(GRN_INVALID_ARGUMENT,
+          "[io][flush][recursive] "
+          "object must be DB, table or column: <%.*s>",
+          (int)GRN_TEXT_LEN(&inspected),
+          GRN_TEXT_VALUE(&inspected));
+      GRN_OBJ_FIN(ctx, &inspected);
+    }
+    break;
+  }
+}
+
+grn_rc
+grn_obj_flush_recursive(grn_ctx *ctx, grn_obj *obj)
+{
+  GRN_API_ENTER;
+
+  flush_recursive_data data;
+  data.is_close_opened_object_mode = (grn_thread_get_limit() == 1);
+  grn_obj_flush_recursive_internal(ctx, obj, &data);
+
+  GRN_API_RETURN(ctx->rc);
+}
+
 grn_obj *
 grn_obj_db(grn_ctx *ctx, grn_obj *obj)
 {

  Modified: lib/proc.c (+8 -5)
===================================================================
--- lib/proc.c    2019-04-15 18:00:02 +0900 (776f39848)
+++ lib/proc.c    2019-04-17 10:17:28 +0900 (3ce11d68f)
@@ -3741,9 +3741,10 @@ proc_io_flush(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
     return NULL;
   }
 
-  bool is_recursive = grn_plugin_proc_get_var_bool(ctx, user_data,
+  grn_raw_string recursive;
+  recursive.value = grn_plugin_proc_get_var_string(ctx, user_data,
                                                    "recursive", -1,
-                                                   GRN_TRUE);
+                                                   &(recursive.length));
   bool is_only_opened = grn_plugin_proc_get_var_bool(ctx, user_data,
                                                      "only_opened", -1,
                                                      GRN_FALSE);
@@ -3767,10 +3768,12 @@ proc_io_flush(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
       rc = grn_obj_flush(ctx, target);
     }
   } else {
-    if (is_recursive) {
-      rc = grn_obj_flush_recursive(ctx, target);
-    } else {
+    if (GRN_RAW_STRING_EQUAL_CSTRING(recursive, "dependent")) {
+      rc = grn_obj_flush_recursive_dependent(ctx, target);
+    } else if (GRN_RAW_STRING_EQUAL_CSTRING(recursive, "no")) {
       rc = grn_obj_flush(ctx, target);
+    } else {
+      rc = grn_obj_flush_recursive(ctx, target);
     }
   }
 

  Modified: test/command/suite/io_flush/default.expected (+2 -2)
===================================================================
--- test/command/suite/io_flush/default.expected    2019-04-15 18:00:02 +0900 (74e09674f)
+++ test/command/suite/io_flush/default.expected    2019-04-17 10:17:28 +0900 (8a9630647)
@@ -9,10 +9,10 @@ column_create Terms users_name COLUMN_INDEX|WITH_POSITION Users name
 io_flush
 [[0,0.0,0.0],true]
 #>io_flush
-#:000000000000000 flush[Users]
-#:000000000000000 flush[Users.name]
 #:000000000000000 flush[Terms.users_name]
 #:000000000000000 flush[Terms]
+#:000000000000000 flush[Users.name]
+#:000000000000000 flush[Users]
 #:000000000000000 flush[(anonymous:table:dat_key)]
 #:000000000000000 flush[(anonymous:column:var_size)]
 #:000000000000000 flush[(anonymous:table:hash_key)]

  Modified: test/command/suite/io_flush/many_data.expected (+0 -3)
===================================================================
--- test/command/suite/io_flush/many_data.expected    2019-04-15 18:00:02 +0900 (f6296aa7a)
+++ test/command/suite/io_flush/many_data.expected    2019-04-17 10:17:28 +0900 (609ed0ac0)
@@ -9,9 +9,6 @@ column_create Lexicon sources_value COLUMN_INDEX Sources value
 io_flush Lexicon.sources_value
 [[0,0.0,0.0],true]
 #>io_flush --target_name "Lexicon.sources_value"
-#:000000000000000 flush[Lexicon]
-#:000000000000000 flush[Sources]
-#:000000000000000 flush[Sources.value]
 #:000000000000000 flush[Lexicon.sources_value]
 #:000000000000000 flush[(anonymous:table:dat_key)]
 #:000000000000000 flush[(anonymous:column:var_size)]

  Added: test/command/suite/io_flush/recursive/dependent/data_column/have_index.expected (+25 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/io_flush/recursive/dependent/data_column/have_index.expected    2019-04-17 10:17:28 +0900 (f279133a0)
@@ -0,0 +1,25 @@
+table_create Memos TABLE_NO_KEY
+[[0,0.0,0.0],true]
+column_create Memos content COLUMN_SCALAR Text
+[[0,0.0,0.0],true]
+column_create Memos timestamp COLUMN_SCALAR Time
+[[0,0.0,0.0],true]
+table_create Terms TABLE_PAT_KEY ShortText   --default_tokenizer TokenBigram   --default_normalizer NormalizerNFKC100
+[[0,0.0,0.0],true]
+column_create Terms memos_key_index COLUMN_INDEX|WITH_POSITION Memos content
+[[0,0.0,0.0],true]
+column_create Terms is_stop_word COLUMN_SCALAR Bool
+[[0,0.0,0.0],true]
+io_flush Memos.content --recursive dependent
+[[0,0.0,0.0],true]
+#>io_flush --recursive "dependent" --target_name "Memos.content"
+#:000000000000000 flush[Memos]
+#:000000000000000 flush[Terms]
+#:000000000000000 flush[Terms.memos_key_index]
+#:000000000000000 flush[Memos.content]
+#:000000000000000 flush[(anonymous:table:dat_key)]
+#:000000000000000 flush[(anonymous:column:var_size)]
+#:000000000000000 flush[(anonymous:table:hash_key)]
+#:000000000000000 flush[(anonymous:column:var_size)]
+#:000000000000000 flush[(DB)]
+#<000000000000000 rc=0

  Added: test/command/suite/io_flush/recursive/dependent/data_column/have_index.test (+13 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/io_flush/recursive/dependent/data_column/have_index.test    2019-04-17 10:17:28 +0900 (44c112202)
@@ -0,0 +1,13 @@
+table_create Memos TABLE_NO_KEY
+column_create Memos content COLUMN_SCALAR Text
+column_create Memos timestamp COLUMN_SCALAR Time
+
+table_create Terms TABLE_PAT_KEY ShortText \
+  --default_tokenizer TokenBigram \
+  --default_normalizer NormalizerNFKC100
+column_create Terms memos_key_index COLUMN_INDEX|WITH_POSITION Memos content
+column_create Terms is_stop_word COLUMN_SCALAR Bool
+
+#@collect-query-log true
+io_flush Memos.content --recursive dependent
+#@collect-query-log false

  Added: test/command/suite/io_flush/recursive/dependent/data_column/no_index.expected (+25 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/io_flush/recursive/dependent/data_column/no_index.expected    2019-04-17 10:17:28 +0900 (3f5393323)
@@ -0,0 +1,25 @@
+table_create Memos TABLE_HASH_KEY ShortText
+[[0,0.0,0.0],true]
+column_create Memos content COLUMN_SCALAR Text
+[[0,0.0,0.0],true]
+column_create Memos timestamp COLUMN_SCALAR Time
+[[0,0.0,0.0],true]
+table_create Terms TABLE_PAT_KEY ShortText   --default_tokenizer TokenBigram   --default_normalizer NormalizerNFKC100
+[[0,0.0,0.0],true]
+column_create Terms memos_key_index COLUMN_INDEX|WITH_POSITION Memos _key
+[[0,0.0,0.0],true]
+column_create Terms is_stop_word COLUMN_SCALAR Bool
+[[0,0.0,0.0],true]
+io_flush Memos.content --recursive dependent
+[[0,0.0,0.0],true]
+#>io_flush --recursive "dependent" --target_name "Memos.content"
+#:000000000000000 flush[Terms]
+#:000000000000000 flush[Terms.memos_key_index]
+#:000000000000000 flush[Memos]
+#:000000000000000 flush[Memos.content]
+#:000000000000000 flush[(anonymous:table:dat_key)]
+#:000000000000000 flush[(anonymous:column:var_size)]
+#:000000000000000 flush[(anonymous:table:hash_key)]
+#:000000000000000 flush[(anonymous:column:var_size)]
+#:000000000000000 flush[(DB)]
+#<000000000000000 rc=0

  Added: test/command/suite/io_flush/recursive/dependent/data_column/no_index.test (+13 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/io_flush/recursive/dependent/data_column/no_index.test    2019-04-17 10:17:28 +0900 (7077ee8ab)
@@ -0,0 +1,13 @@
+table_create Memos TABLE_HASH_KEY ShortText
+column_create Memos content COLUMN_SCALAR Text
+column_create Memos timestamp COLUMN_SCALAR Time
+
+table_create Terms TABLE_PAT_KEY ShortText \
+  --default_tokenizer TokenBigram \
+  --default_normalizer NormalizerNFKC100
+column_create Terms memos_key_index COLUMN_INDEX|WITH_POSITION Memos _key
+column_create Terms is_stop_word COLUMN_SCALAR Bool
+
+#@collect-query-log true
+io_flush Memos.content --recursive dependent
+#@collect-query-log false

  Added: test/command/suite/io_flush/recursive/dependent/data_column/reference.expected (+39 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/io_flush/recursive/dependent/data_column/reference.expected    2019-04-17 10:17:28 +0900 (680a1a4ae)
@@ -0,0 +1,39 @@
+table_create Users TABLE_HASH_KEY ShortText
+[[0,0.0,0.0],true]
+table_create Labels TABLE_HASH_KEY ShortText
+[[0,0.0,0.0],true]
+column_create Labels owner COLUMN_SCALR Users
+[[[-22,0.0,0.0],"[column][create][flags] unknown flag: <COLUMN_SCALR>"],false]
+#|e| [column][create][flags] unknown flag: <COLUMN_SCALR>
+table_create Tags TABLE_HASH_KEY ShortText
+[[0,0.0,0.0],true]
+column_create Tags label COLUMN_SCALAR Labels
+[[0,0.0,0.0],true]
+table_create Memos TABLE_NO_KEY
+[[0,0.0,0.0],true]
+column_create Memos tags COLUMN_VECTOR Tags
+[[0,0.0,0.0],true]
+column_create Memos timestamp COLUMN_SCALAR Time
+[[0,0.0,0.0],true]
+table_create Terms TABLE_PAT_KEY ShortText   --default_tokenizer TokenBigram   --default_normalizer NormalizerNFKC100
+[[0,0.0,0.0],true]
+column_create Terms tags_index   COLUMN_INDEX|WITH_POSITION|WITH_SECTION Tags _key,label
+[[0,0.0,0.0],true]
+column_create Terms is_stop_word COLUMN_SCALAR Bool
+[[0,0.0,0.0],true]
+io_flush Memos.tags --recursive dependent
+[[0,0.0,0.0],true]
+#>io_flush --recursive "dependent" --target_name "Memos.tags"
+#:000000000000000 flush[Memos]
+#:000000000000000 flush[Terms]
+#:000000000000000 flush[Labels]
+#:000000000000000 flush[Tags.label]
+#:000000000000000 flush[Terms.tags_index]
+#:000000000000000 flush[Tags]
+#:000000000000000 flush[Memos.tags]
+#:000000000000000 flush[(anonymous:table:dat_key)]
+#:000000000000000 flush[(anonymous:column:var_size)]
+#:000000000000000 flush[(anonymous:table:hash_key)]
+#:000000000000000 flush[(anonymous:column:var_size)]
+#:000000000000000 flush[(DB)]
+#<000000000000000 rc=0

  Added: test/command/suite/io_flush/recursive/dependent/data_column/reference.test (+22 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/io_flush/recursive/dependent/data_column/reference.test    2019-04-17 10:17:28 +0900 (45f35fa0e)
@@ -0,0 +1,22 @@
+table_create Users TABLE_HASH_KEY ShortText
+
+table_create Labels TABLE_HASH_KEY ShortText
+column_create Labels owner COLUMN_SCALR Users
+
+table_create Tags TABLE_HASH_KEY ShortText
+column_create Tags label COLUMN_SCALAR Labels
+
+table_create Memos TABLE_NO_KEY
+column_create Memos tags COLUMN_VECTOR Tags
+column_create Memos timestamp COLUMN_SCALAR Time
+
+table_create Terms TABLE_PAT_KEY ShortText \
+  --default_tokenizer TokenBigram \
+  --default_normalizer NormalizerNFKC100
+column_create Terms tags_index \
+  COLUMN_INDEX|WITH_POSITION|WITH_SECTION Tags _key,label
+column_create Terms is_stop_word COLUMN_SCALAR Bool
+
+#@collect-query-log true
+io_flush Memos.tags --recursive dependent
+#@collect-query-log false

  Added: test/command/suite/io_flush/recursive/dependent/index_column/source_column.expected (+22 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/io_flush/recursive/dependent/index_column/source_column.expected    2019-04-17 10:17:28 +0900 (356d281ba)
@@ -0,0 +1,22 @@
+table_create Memos TABLE_HASH_KEY ShortText
+[[0,0.0,0.0],true]
+column_create Memos timestamp COLUMN_SCALAR Time
+[[0,0.0,0.0],true]
+table_create Timestamps TABLE_PAT_KEY Time
+[[0,0.0,0.0],true]
+column_create Timestamps memos_timestamp_index COLUMN_INDEX Memos timestamp
+[[0,0.0,0.0],true]
+column_create Timestamps is_special COLUMN_SCALAR Bool
+[[0,0.0,0.0],true]
+io_flush Timestamps.memos_timestamp_index --recursive dependent
+[[0,0.0,0.0],true]
+#>io_flush --recursive "dependent" --target_name "Timestamps.memos_timestamp_index"
+#:000000000000000 flush[Timestamps]
+#:000000000000000 flush[Memos.timestamp]
+#:000000000000000 flush[Timestamps.memos_timestamp_index]
+#:000000000000000 flush[(anonymous:table:dat_key)]
+#:000000000000000 flush[(anonymous:column:var_size)]
+#:000000000000000 flush[(anonymous:table:hash_key)]
+#:000000000000000 flush[(anonymous:column:var_size)]
+#:000000000000000 flush[(DB)]
+#<000000000000000 rc=0

  Added: test/command/suite/io_flush/recursive/dependent/index_column/source_column.test (+10 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/io_flush/recursive/dependent/index_column/source_column.test    2019-04-17 10:17:28 +0900 (940dd2010)
@@ -0,0 +1,10 @@
+table_create Memos TABLE_HASH_KEY ShortText
+column_create Memos timestamp COLUMN_SCALAR Time
+
+table_create Timestamps TABLE_PAT_KEY Time
+column_create Timestamps memos_timestamp_index COLUMN_INDEX Memos timestamp
+column_create Timestamps is_special COLUMN_SCALAR Bool
+
+#@collect-query-log true
+io_flush Timestamps.memos_timestamp_index --recursive dependent
+#@collect-query-log false

  Added: test/command/suite/io_flush/recursive/dependent/index_column/source_key.expected (+22 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/io_flush/recursive/dependent/index_column/source_key.expected    2019-04-17 10:17:28 +0900 (bfabfd088)
@@ -0,0 +1,22 @@
+table_create Memos TABLE_HASH_KEY ShortText
+[[0,0.0,0.0],true]
+column_create Memos timestamp COLUMN_SCALAR Time
+[[0,0.0,0.0],true]
+table_create Terms TABLE_PAT_KEY ShortText   --default_tokenizer TokenBigram   --default_normalizer NormalizerNFKC100
+[[0,0.0,0.0],true]
+column_create Terms memos_key_index COLUMN_INDEX|WITH_POSITION Memos _key
+[[0,0.0,0.0],true]
+column_create Terms is_stop_word COLUMN_SCALAR Bool
+[[0,0.0,0.0],true]
+io_flush Terms.memos_key_index --recursive dependent
+[[0,0.0,0.0],true]
+#>io_flush --recursive "dependent" --target_name "Terms.memos_key_index"
+#:000000000000000 flush[Terms]
+#:000000000000000 flush[Memos]
+#:000000000000000 flush[Terms.memos_key_index]
+#:000000000000000 flush[(anonymous:table:dat_key)]
+#:000000000000000 flush[(anonymous:column:var_size)]
+#:000000000000000 flush[(anonymous:table:hash_key)]
+#:000000000000000 flush[(anonymous:column:var_size)]
+#:000000000000000 flush[(DB)]
+#<000000000000000 rc=0

  Added: test/command/suite/io_flush/recursive/dependent/index_column/source_key.test (+12 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/io_flush/recursive/dependent/index_column/source_key.test    2019-04-17 10:17:28 +0900 (d8d40c7f6)
@@ -0,0 +1,12 @@
+table_create Memos TABLE_HASH_KEY ShortText
+column_create Memos timestamp COLUMN_SCALAR Time
+
+table_create Terms TABLE_PAT_KEY ShortText \
+  --default_tokenizer TokenBigram \
+  --default_normalizer NormalizerNFKC100
+column_create Terms memos_key_index COLUMN_INDEX|WITH_POSITION Memos _key
+column_create Terms is_stop_word COLUMN_SCALAR Bool
+
+#@collect-query-log true
+io_flush Terms.memos_key_index --recursive dependent
+#@collect-query-log false

  Added: test/command/suite/io_flush/recursive/dependent/index_column/sources.expected (+28 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/io_flush/recursive/dependent/index_column/sources.expected    2019-04-17 10:17:28 +0900 (cbf21249f)
@@ -0,0 +1,28 @@
+table_create Memos TABLE_HASH_KEY ShortText
+[[0,0.0,0.0],true]
+column_create Memos title COLUMN_SCALAR ShortText
+[[0,0.0,0.0],true]
+column_create Memos content COLUMN_SCALAR Text
+[[0,0.0,0.0],true]
+column_create Memos timestamp COLUMN_SCALAR Time
+[[0,0.0,0.0],true]
+table_create Terms TABLE_PAT_KEY ShortText   --default_tokenizer TokenBigram   --default_normalizer NormalizerNFKC100
+[[0,0.0,0.0],true]
+column_create Terms memos_index   COLUMN_INDEX|WITH_POSITION|WITH_SECTION Memos _key,title,content
+[[0,0.0,0.0],true]
+column_create Terms is_stop_word COLUMN_SCALAR Bool
+[[0,0.0,0.0],true]
+io_flush Terms.memos_index --recursive dependent
+[[0,0.0,0.0],true]
+#>io_flush --recursive "dependent" --target_name "Terms.memos_index"
+#:000000000000000 flush[Terms]
+#:000000000000000 flush[Memos]
+#:000000000000000 flush[Memos.title]
+#:000000000000000 flush[Memos.content]
+#:000000000000000 flush[Terms.memos_index]
+#:000000000000000 flush[(anonymous:table:dat_key)]
+#:000000000000000 flush[(anonymous:column:var_size)]
+#:000000000000000 flush[(anonymous:table:hash_key)]
+#:000000000000000 flush[(anonymous:column:var_size)]
+#:000000000000000 flush[(DB)]
+#<000000000000000 rc=0

  Added: test/command/suite/io_flush/recursive/dependent/index_column/sources.test (+15 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/io_flush/recursive/dependent/index_column/sources.test    2019-04-17 10:17:28 +0900 (d65f0db34)
@@ -0,0 +1,15 @@
+table_create Memos TABLE_HASH_KEY ShortText
+column_create Memos title COLUMN_SCALAR ShortText
+column_create Memos content COLUMN_SCALAR Text
+column_create Memos timestamp COLUMN_SCALAR Time
+
+table_create Terms TABLE_PAT_KEY ShortText \
+  --default_tokenizer TokenBigram \
+  --default_normalizer NormalizerNFKC100
+column_create Terms memos_index \
+  COLUMN_INDEX|WITH_POSITION|WITH_SECTION Memos _key,title,content
+column_create Terms is_stop_word COLUMN_SCALAR Bool
+
+#@collect-query-log true
+io_flush Terms.memos_index --recursive dependent
+#@collect-query-log false

  Added: test/command/suite/io_flush/recursive/dependent/table/reference.expected (+27 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/io_flush/recursive/dependent/table/reference.expected    2019-04-17 10:17:28 +0900 (707cbd7be)
@@ -0,0 +1,27 @@
+table_create Tags TABLE_HASH_KEY ShortText
+[[0,0.0,0.0],true]
+column_create Tags label COLUMN_SCALAR ShortText
+[[0,0.0,0.0],true]
+table_create Titles TABLE_HASH_KEY ShortText
+[[0,0.0,0.0],true]
+column_create Titles tag COLUMN_SCALAR Tags
+[[0,0.0,0.0],true]
+table_create Memos TABLE_HASH_KEY Titles
+[[0,0.0,0.0],true]
+column_create Memos content COLUMN_SCALAR Text
+[[0,0.0,0.0],true]
+column_create Memos timestamp COLUMN_SCALAR Time
+[[0,0.0,0.0],true]
+io_flush Memos --recursive dependent
+[[0,0.0,0.0],true]
+#>io_flush --recursive "dependent" --target_name "Memos"
+#:000000000000000 flush[Titles]
+#:000000000000000 flush[Memos.content]
+#:000000000000000 flush[Memos.timestamp]
+#:000000000000000 flush[Memos]
+#:000000000000000 flush[(anonymous:table:dat_key)]
+#:000000000000000 flush[(anonymous:column:var_size)]
+#:000000000000000 flush[(anonymous:table:hash_key)]
+#:000000000000000 flush[(anonymous:column:var_size)]
+#:000000000000000 flush[(DB)]
+#<000000000000000 rc=0

  Added: test/command/suite/io_flush/recursive/dependent/table/reference.test (+13 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/io_flush/recursive/dependent/table/reference.test    2019-04-17 10:17:28 +0900 (0a975a078)
@@ -0,0 +1,13 @@
+table_create Tags TABLE_HASH_KEY ShortText
+column_create Tags label COLUMN_SCALAR ShortText
+
+table_create Titles TABLE_HASH_KEY ShortText
+column_create Titles tag COLUMN_SCALAR Tags
+
+table_create Memos TABLE_HASH_KEY Titles
+column_create Memos content COLUMN_SCALAR Text
+column_create Memos timestamp COLUMN_SCALAR Time
+
+#@collect-query-log true
+io_flush Memos --recursive dependent
+#@collect-query-log false

  Modified: test/command/suite/io_flush/target_name/column.expected (+0 -3)
===================================================================
--- test/command/suite/io_flush/target_name/column.expected    2019-04-15 18:00:02 +0900 (cf57c25a2)
+++ test/command/suite/io_flush/target_name/column.expected    2019-04-17 10:17:28 +0900 (4fab3e62e)
@@ -9,9 +9,6 @@ column_create Terms users_name COLUMN_INDEX|WITH_POSITION Users name
 io_flush Users.name
 [[0,0.0,0.0],true]
 #>io_flush --target_name "Users.name"
-#:000000000000000 flush[Users]
-#:000000000000000 flush[Terms]
-#:000000000000000 flush[Terms.users_name]
 #:000000000000000 flush[Users.name]
 #:000000000000000 flush[(anonymous:table:dat_key)]
 #:000000000000000 flush[(anonymous:column:var_size)]

  Modified: test/command/suite/io_flush/target_name/invalid.expected (+2 -2)
===================================================================
--- test/command/suite/io_flush/target_name/invalid.expected    2019-04-15 18:00:02 +0900 (ed4fab584)
+++ test/command/suite/io_flush/target_name/invalid.expected    2019-04-17 10:17:28 +0900 (760da6af6)
@@ -6,8 +6,8 @@ io_flush TokenBigram
       0.0,
       0.0
     ],
-    "[flush] object must be DB, table or column: <#<proc:tokenizer TokenBigram arguments:[$1, $2, $3]>>"
+    "[io][flush][recursive] object must be DB, table or column: <#<proc:tokenizer TokenBigram arguments:[$1, $2, $3]>>"
   ],
   false
 ]
-#|e| [flush] object must be DB, table or column: <#<proc:tokenizer TokenBigram arguments:[$1, $2, $3]>>
+#|e| [io][flush][recursive] object must be DB, table or column: <#<proc:tokenizer TokenBigram arguments:[$1, $2, $3]>>

  Modified: test/command/suite/io_flush/target_name/table.expected (+0 -2)
===================================================================
--- test/command/suite/io_flush/target_name/table.expected    2019-04-15 18:00:02 +0900 (69109a1a5)
+++ test/command/suite/io_flush/target_name/table.expected    2019-04-17 10:17:28 +0900 (c8e7db378)
@@ -9,8 +9,6 @@ column_create Terms users_name COLUMN_INDEX|WITH_POSITION Users name
 io_flush Users
 [[0,0.0,0.0],true]
 #>io_flush --target_name "Users"
-#:000000000000000 flush[Terms]
-#:000000000000000 flush[Terms.users_name]
 #:000000000000000 flush[Users.name]
 #:000000000000000 flush[Users]
 #:000000000000000 flush[(anonymous:table:dat_key)]
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.osdn.me/mailman/archives/groonga-commit/attachments/20190417/d65b7b3b/attachment-0001.html>


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