[Groonga-commit] groonga/groonga at 7791684 [master] select: support object based output in command version 3

Back to archive index

Kouhei Sutou null+****@clear*****
Tue May 24 23:29:34 JST 2016


Kouhei Sutou	2016-05-24 23:29:34 +0900 (Tue, 24 May 2016)

  New Revision: 779168442b394b93c3fb40d30791db092756dfe7
  https://github.com/groonga/groonga/commit/779168442b394b93c3fb40d30791db092756dfe7

  Message:
    select: support object based output in command version 3

  Added files:
    test/command/suite/select/slices/command_version_3.expected
    test/command/suite/select/slices/command_version_3.test
  Modified files:
    include/groonga/output.h
    lib/ctx.c
    lib/grn_output.h
    lib/output.c
    lib/proc/proc_select.c

  Modified: include/groonga/output.h (+3 -0)
===================================================================
--- include/groonga/output.h    2016-05-24 17:04:38 +0900 (738fefd)
+++ include/groonga/output.h    2016-05-24 23:29:34 +0900 (ef3c82d)
@@ -93,6 +93,9 @@ GRN_API void grn_ctx_output_str(grn_ctx *ctx,
 GRN_API void grn_ctx_output_bool(grn_ctx *ctx, grn_bool value);
 GRN_API void grn_ctx_output_obj(grn_ctx *ctx,
                                 grn_obj *value, grn_obj_format *format);
+GRN_API void grn_ctx_output_result_set(grn_ctx *ctx,
+                                       grn_obj *result_set,
+                                       grn_obj_format *format);
 GRN_API void grn_ctx_output_table_columns(grn_ctx *ctx,
                                           grn_obj *table,
                                           grn_obj_format *format);

  Modified: lib/ctx.c (+12 -0)
===================================================================
--- lib/ctx.c    2016-05-24 17:04:38 +0900 (f9946db)
+++ lib/ctx.c    2016-05-24 23:29:34 +0900 (9bf66f3)
@@ -1772,6 +1772,18 @@ grn_ctx_output_obj(grn_ctx *ctx, grn_obj *value, grn_obj_format *format)
 }
 
 void
+grn_ctx_output_result_set(grn_ctx *ctx,
+                          grn_obj *result_set,
+                          grn_obj_format *format)
+{
+  grn_output_result_set(ctx,
+                        ctx->impl->output.buf,
+                        ctx->impl->output.type,
+                        result_set,
+                        format);
+}
+
+void
 grn_ctx_output_table_columns(grn_ctx *ctx, grn_obj *table,
                              grn_obj_format *format)
 {

  Modified: lib/grn_output.h (+5 -0)
===================================================================
--- lib/grn_output.h    2016-05-24 17:04:38 +0900 (758443a)
+++ lib/grn_output.h    2016-05-24 23:29:34 +0900 (a1972c0)
@@ -54,6 +54,11 @@ GRN_API void grn_output_bool(grn_ctx *ctx, grn_obj *outbuf,
                              grn_content_type output_type,
                              grn_bool value);
 
+GRN_API void grn_output_result_set(grn_ctx *ctx,
+                                   grn_obj *outbuf,
+                                   grn_content_type output_type,
+                                   grn_obj *result_set,
+                                   grn_obj_format *format);
 GRN_API void grn_output_table_columns(grn_ctx *ctx,
                                       grn_obj *outbuf,
                                       grn_content_type output_type,

  Modified: lib/output.c (+282 -66)
===================================================================
--- lib/output.c    2016-05-24 17:04:38 +0900 (20266cd)
+++ lib/output.c    2016-05-24 23:29:34 +0900 (44542b2)
@@ -1226,18 +1226,82 @@ grn_output_pvector(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type,
 }
 
 static inline void
-grn_output_table_header(grn_ctx *ctx, grn_obj *outbuf,
-                        grn_content_type output_type,
-                        grn_obj *table, grn_obj_format *format)
+grn_output_result_set_n_hits_v1(grn_ctx *ctx,
+                                grn_obj *outbuf,
+                                grn_content_type output_type,
+                                grn_obj_format *format)
+{
+  grn_output_array_open(ctx, outbuf, output_type, "NHITS", 1);
+  if (output_type == GRN_CONTENT_XML) {
+    grn_text_itoa(ctx, outbuf, format->nhits);
+  } else {
+    grn_output_int32(ctx, outbuf, output_type, format->nhits);
+  }
+  grn_output_array_close(ctx, outbuf, output_type);
+}
+
+static inline void
+grn_output_result_set_n_hits_v3(grn_ctx *ctx,
+                                grn_obj *outbuf,
+                                grn_content_type output_type,
+                                grn_obj_format *format)
 {
-  if (format->nhits != -1) {
-    grn_output_array_open(ctx, outbuf, output_type, "NHITS", 1);
-    if (output_type == GRN_CONTENT_XML) {
-      grn_text_itoa(ctx, outbuf, format->nhits);
+  grn_output_cstr(ctx, outbuf, output_type, "n_hits");
+  grn_output_int32(ctx, outbuf, output_type, format->nhits);
+}
+
+static inline void
+grn_output_result_set_n_hits(grn_ctx *ctx,
+                             grn_obj *outbuf,
+                             grn_content_type output_type,
+                             grn_obj_format *format)
+{
+  if (format->nhits == -1) {
+    return;
+  }
+
+  if (grn_ctx_get_command_version(ctx) < GRN_COMMAND_VERSION_3) {
+    grn_output_result_set_n_hits_v1(ctx, outbuf, output_type, format);
+  } else {
+    grn_output_result_set_n_hits_v3(ctx, outbuf, output_type, format);
+  }
+}
+
+static inline void
+grn_output_table_column_info(grn_ctx *ctx,
+                             grn_obj *outbuf,
+                             grn_content_type output_type,
+                             const char *name,
+                             const char *type)
+{
+  if (grn_ctx_get_command_version(ctx) < GRN_COMMAND_VERSION_3) {
+    grn_output_array_open(ctx, outbuf, output_type, "COLUMN", 2);
+    if (name) {
+      grn_output_cstr(ctx, outbuf, output_type, name);
     } else {
-      grn_output_int32(ctx, outbuf, output_type, format->nhits);
+      grn_output_null(ctx, outbuf, output_type);
+    }
+    if (type) {
+      grn_output_cstr(ctx, outbuf, output_type, type);
+    } else {
+      grn_output_null(ctx, outbuf, output_type);
     }
     grn_output_array_close(ctx, outbuf, output_type);
+  } else {
+    grn_output_map_open(ctx, outbuf, output_type, "column", 2);
+    grn_output_cstr(ctx, outbuf, output_type, "name");
+    if (name) {
+      grn_output_cstr(ctx, outbuf, output_type, name);
+    } else {
+      grn_output_null(ctx, outbuf, output_type);
+    }
+    grn_output_cstr(ctx, outbuf, output_type, "type");
+    if (type) {
+      grn_output_cstr(ctx, outbuf, output_type, type);
+    } else {
+      grn_output_null(ctx, outbuf, output_type);
+    }
+    grn_output_map_close(ctx, outbuf, output_type);
   }
 }
 
@@ -1282,43 +1346,52 @@ grn_output_table_column(grn_ctx *ctx, grn_obj *outbuf,
                         grn_content_type output_type,
                         grn_obj *column, grn_obj *buf)
 {
-  grn_output_array_open(ctx, outbuf, output_type, "COLUMN", 2);
-  if (column) {
-    grn_id range_id = GRN_ID_NIL;
-    GRN_BULK_REWIND(buf);
-    grn_column_name_(ctx, column, buf);
-    grn_output_obj(ctx, outbuf, output_type, buf, NULL);
-    if (column->header.type == GRN_COLUMN_INDEX) {
-      range_id = GRN_DB_UINT32;
-    } else if (is_score_accessor(ctx, column)) {
-      if (grn_ctx_get_command_version(ctx) == GRN_COMMAND_VERSION_1) {
-        range_id = GRN_DB_INT32;
-      } else {
-        range_id = GRN_DB_FLOAT;
-      }
-    }
-    if (range_id == GRN_ID_NIL) {
-      range_id = grn_obj_get_range(ctx, column);
-    }
-    if (range_id == GRN_ID_NIL) {
-      grn_output_cstr(ctx, outbuf, output_type, "null");
-    } else {
-      int name_len;
-      grn_obj *range_obj;
-      char name_buf[GRN_TABLE_MAX_KEY_SIZE];
+  grn_id range_id = GRN_ID_NIL;
 
-      range_obj = grn_ctx_at(ctx, range_id);
-      name_len = grn_obj_name(ctx, range_obj, name_buf,
-                              GRN_TABLE_MAX_KEY_SIZE);
-      GRN_BULK_REWIND(buf);
-      GRN_TEXT_PUT(ctx, buf, name_buf, name_len);
-      grn_output_obj(ctx, outbuf, output_type, buf, NULL);
+  if (!column) {
+    grn_output_table_column_info(ctx, outbuf, output_type, NULL, NULL);
+    return;
+  }
+
+  GRN_BULK_REWIND(buf);
+  grn_column_name_(ctx, column, buf);
+  GRN_TEXT_PUTC(ctx, buf, '\0');
+
+  if (column->header.type == GRN_COLUMN_INDEX) {
+    range_id = GRN_DB_UINT32;
+  } else if (is_score_accessor(ctx, column)) {
+    if (grn_ctx_get_command_version(ctx) == GRN_COMMAND_VERSION_1) {
+      range_id = GRN_DB_INT32;
+    } else {
+      range_id = GRN_DB_FLOAT;
     }
+  }
+  if (range_id == GRN_ID_NIL) {
+    range_id = grn_obj_get_range(ctx, column);
+  }
+  if (range_id == GRN_ID_NIL) {
+    grn_output_table_column_info(ctx,
+                                 outbuf,
+                                 output_type,
+                                 GRN_TEXT_VALUE(buf),
+                                 "null");
   } else {
-    grn_output_cstr(ctx, outbuf, output_type, "");
-    grn_output_cstr(ctx, outbuf, output_type, "");
+    grn_obj *range_obj;
+    char type_name[GRN_TABLE_MAX_KEY_SIZE];
+    int type_name_len;
+
+    range_obj = grn_ctx_at(ctx, range_id);
+    type_name_len = grn_obj_name(ctx,
+                                 range_obj,
+                                 type_name,
+                                 GRN_TABLE_MAX_KEY_SIZE);
+    type_name[type_name_len] = '\0';
+    grn_output_table_column_info(ctx,
+                                 outbuf,
+                                 output_type,
+                                 GRN_TEXT_VALUE(buf),
+                                 type_name);
   }
-  grn_output_array_close(ctx, outbuf, output_type);
 }
 
 static inline void
@@ -1329,28 +1402,29 @@ grn_output_table_column_by_expression(grn_ctx *ctx, grn_obj *outbuf,
                                       grn_obj *buf)
 {
   if (code_end <= code) {
-    grn_output_array_open(ctx, outbuf, output_type, "COLUMN", 2);
-    grn_output_null(ctx, outbuf, output_type);
-    grn_output_null(ctx, outbuf, output_type);
-    grn_output_array_close(ctx, outbuf, output_type);
+    grn_output_table_column_info(ctx,
+                                 outbuf,
+                                 output_type,
+                                 NULL,
+                                 NULL);
     return;
   }
 
   switch (code_end[-1].op) {
   case GRN_OP_GET_MEMBER :
     if ((code_end - code) == 3) {
-      grn_output_array_open(ctx, outbuf, output_type, "COLUMN", 2);
-
       GRN_BULK_REWIND(buf);
       grn_column_name_(ctx, code[0].value, buf);
       GRN_TEXT_PUTC(ctx, buf, '[');
       grn_inspect(ctx, buf, code[1].value);
       GRN_TEXT_PUTC(ctx, buf, ']');
+      GRN_TEXT_PUTC(ctx, buf, '\0');
 
-      grn_output_obj(ctx, outbuf, output_type, buf, NULL);
-      grn_output_null(ctx, outbuf, output_type);
-
-      grn_output_array_close(ctx, outbuf, output_type);
+      grn_output_table_column_info(ctx,
+                                   outbuf,
+                                   output_type,
+                                   GRN_TEXT_VALUE(buf),
+                                   NULL);
     } else {
       grn_output_table_column(ctx, outbuf, output_type, code->value, buf);
     }
@@ -1362,6 +1436,32 @@ grn_output_table_column_by_expression(grn_ctx *ctx, grn_obj *outbuf,
 }
 
 static inline void
+grn_output_table_columns_open(grn_ctx *ctx,
+                              grn_obj *outbuf,
+                              grn_content_type output_type,
+                              int n_columns)
+{
+  if (grn_ctx_get_command_version(ctx) < GRN_COMMAND_VERSION_3) {
+    grn_output_array_open(ctx, outbuf, output_type, "COLUMNS", n_columns);
+  } else {
+    grn_output_cstr(ctx, outbuf, output_type, "columns");
+    grn_output_array_open(ctx, outbuf, output_type, "columns", n_columns);
+  }
+}
+
+static inline void
+grn_output_table_columns_close(grn_ctx *ctx,
+                               grn_obj *outbuf,
+                               grn_content_type output_type)
+{
+  if (grn_ctx_get_command_version(ctx) < GRN_COMMAND_VERSION_3) {
+    grn_output_array_close(ctx, outbuf, output_type);
+  } else {
+    grn_output_array_close(ctx, outbuf, output_type);
+  }
+}
+
+static inline void
 grn_output_table_columns_by_expression(grn_ctx *ctx, grn_obj *outbuf,
                                        grn_content_type output_type,
                                        grn_obj *table, grn_obj_format *format,
@@ -1377,7 +1477,8 @@ grn_output_table_columns_by_expression(grn_ctx *ctx, grn_obj *outbuf,
 
   n_elements = count_n_elements_in_expression(ctx, format->expression);
 
-  grn_output_array_open(ctx, outbuf, output_type, "COLUMNS", n_elements);
+  grn_output_table_columns_open(ctx, outbuf, output_type, n_elements);
+
   for (code = expr->codes; code < code_end; code++) {
     int code_start_offset;
 
@@ -1417,7 +1518,7 @@ grn_output_table_columns_by_expression(grn_ctx *ctx, grn_obj *outbuf,
                                           buf);
   }
 
-  grn_output_array_close(ctx, outbuf, output_type);
+  grn_output_table_columns_close(ctx, outbuf, output_type);
 }
 
 static inline void
@@ -1430,11 +1531,11 @@ grn_output_table_columns_by_columns(grn_ctx *ctx, grn_obj *outbuf,
   int ncolumns = GRN_BULK_VSIZE(&format->columns)/sizeof(grn_obj *);
   grn_obj **columns = (grn_obj **)GRN_BULK_HEAD(&format->columns);
 
-  grn_output_array_open(ctx, outbuf, output_type, "COLUMNS", ncolumns);
+  grn_output_table_columns_open(ctx, outbuf, output_type, ncolumns);
   for (i = 0; i < ncolumns; i++) {
     grn_output_table_column(ctx, outbuf, output_type, columns[i], buf);
   }
-  grn_output_array_close(ctx, outbuf, output_type);
+  grn_output_table_columns_close(ctx, outbuf, output_type);
 }
 
 void
@@ -1456,6 +1557,31 @@ grn_output_table_columns(grn_ctx *ctx, grn_obj *outbuf,
 }
 
 static inline void
+grn_output_table_record_open(grn_ctx *ctx,
+                              grn_obj *outbuf,
+                              grn_content_type output_type,
+                              int n_columns)
+{
+  if (grn_ctx_get_command_version(ctx) < GRN_COMMAND_VERSION_3) {
+    grn_output_array_open(ctx, outbuf, output_type, "HIT", n_columns);
+  } else {
+    grn_output_array_open(ctx, outbuf, output_type, "record", n_columns);
+  }
+}
+
+static inline void
+grn_output_table_record_close(grn_ctx *ctx,
+                               grn_obj *outbuf,
+                               grn_content_type output_type)
+{
+  if (grn_ctx_get_command_version(ctx) < GRN_COMMAND_VERSION_3) {
+    grn_output_array_close(ctx, outbuf, output_type);
+  } else {
+    grn_output_array_close(ctx, outbuf, output_type);
+  }
+}
+
+static inline void
 grn_output_table_record_by_column(grn_ctx *ctx,
                                   grn_obj *outbuf,
                                   grn_content_type output_type,
@@ -1512,7 +1638,7 @@ grn_output_table_records_by_expression(grn_ctx *ctx, grn_obj *outbuf,
     grn_bool is_first_comma = GRN_TRUE;
     grn_bool have_comma = GRN_FALSE;
     GRN_RECORD_SET(ctx, record, id);
-    grn_output_array_open(ctx, outbuf, output_type, "HIT", n_elements);
+    grn_output_table_record_open(ctx, outbuf, output_type, n_elements);
     for (code = expr->codes; code < code_end; code++) {
       if (code->op == GRN_OP_COMMA) {
         int code_start_offset = previous_comma_offset + 1;
@@ -1559,7 +1685,7 @@ grn_output_table_records_by_expression(grn_ctx *ctx, grn_obj *outbuf,
                                             record);
     }
 
-    grn_output_array_close(ctx, outbuf, output_type);
+    grn_output_table_record_close(ctx, outbuf, output_type);
   }
 }
 
@@ -1574,7 +1700,7 @@ grn_output_table_records_by_columns(grn_ctx *ctx, grn_obj *outbuf,
   int ncolumns = GRN_BULK_VSIZE(&format->columns)/sizeof(grn_obj *);
   grn_obj **columns = (grn_obj **)GRN_BULK_HEAD(&format->columns);
   while ((id = grn_table_cursor_next(ctx, tc)) != GRN_ID_NIL) {
-    grn_output_array_open(ctx, outbuf, output_type, "HIT", ncolumns);
+    grn_output_table_record_open(ctx, outbuf, output_type, ncolumns);
     for (i = 0; i < ncolumns; i++) {
       grn_output_table_record_by_column(ctx,
                                         outbuf,
@@ -1582,6 +1708,28 @@ grn_output_table_records_by_columns(grn_ctx *ctx, grn_obj *outbuf,
                                         columns[i],
                                         id);
     }
+    grn_output_table_record_close(ctx, outbuf, output_type);
+  }
+}
+
+static inline void
+grn_output_table_records_open(grn_ctx *ctx,
+                              grn_obj *outbuf,
+                              grn_content_type output_type,
+                              int n_records)
+{
+  if (grn_ctx_get_command_version(ctx) >= GRN_COMMAND_VERSION_3) {
+    grn_output_cstr(ctx, outbuf, output_type, "records");
+    grn_output_array_open(ctx, outbuf, output_type, "records", n_records);
+  }
+}
+
+static inline void
+grn_output_table_records_close(grn_ctx *ctx,
+                               grn_obj *outbuf,
+                               grn_content_type output_type)
+{
+  if (grn_ctx_get_command_version(ctx) >= GRN_COMMAND_VERSION_3) {
     grn_output_array_close(ctx, outbuf, output_type);
   }
 }
@@ -1591,9 +1739,12 @@ grn_output_table_records(grn_ctx *ctx, grn_obj *outbuf,
                          grn_content_type output_type,
                          grn_obj *table, grn_obj_format *format)
 {
-  grn_table_cursor *tc = grn_table_cursor_open(ctx, table, NULL, 0, NULL, 0,
-                                               format->offset, format->limit,
-                                               GRN_CURSOR_ASCENDING);
+  grn_table_cursor *tc;
+
+  grn_output_table_records_open(ctx, outbuf, output_type, format->limit);
+  tc = grn_table_cursor_open(ctx, table, NULL, 0, NULL, 0,
+                             format->offset, format->limit,
+                             GRN_CURSOR_ASCENDING);
   if (tc) {
     if (format->expression) {
       grn_output_table_records_by_expression(ctx, outbuf, output_type,
@@ -1606,11 +1757,15 @@ grn_output_table_records(grn_ctx *ctx, grn_obj *outbuf,
   } else {
     ERRCLR(ctx);
   }
+  grn_output_table_records_close(ctx, outbuf, output_type);
 }
 
-static inline void
-grn_output_table(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type,
-                 grn_obj *table, grn_obj_format *format)
+static void
+grn_output_result_set_v1(grn_ctx *ctx,
+                         grn_obj *outbuf,
+                         grn_content_type output_type,
+                         grn_obj *table,
+                         grn_obj_format *format)
 {
   grn_obj buf;
   GRN_TEXT_INIT(&buf, 0);
@@ -1622,7 +1777,7 @@ grn_output_table(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type,
     }
     resultset_size += format->limit;
     grn_output_array_open(ctx, outbuf, output_type, "RESULTSET", resultset_size);
-    grn_output_table_header(ctx, outbuf, output_type, table, format);
+    grn_output_result_set_n_hits(ctx, outbuf, output_type, format);
     if (format->flags & GRN_OBJ_FORMAT_WITH_COLUMN_NAMES) {
       grn_output_table_columns(ctx, outbuf, output_type, table, format);
     }
@@ -1651,6 +1806,66 @@ grn_output_table(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type,
   GRN_OBJ_FIN(ctx, &buf);
 }
 
+static void
+grn_output_result_set_v3(grn_ctx *ctx,
+                         grn_obj *outbuf,
+                         grn_content_type output_type,
+                         grn_obj *result_set,
+                         grn_obj_format *format)
+{
+  grn_obj buf;
+  GRN_TEXT_INIT(&buf, 0);
+  if (format) {
+    int n_elements = 2;
+    /* result_set: {"n_hits": N, ("columns": COLUMNS,) "records": records} */
+    if (format->flags & GRN_OBJ_FORMAT_WITH_COLUMN_NAMES) {
+      n_elements++;
+    }
+    grn_output_map_open(ctx, outbuf, output_type, "result_set", n_elements);
+    grn_output_result_set_n_hits(ctx, outbuf, output_type, format);
+    if (format->flags & GRN_OBJ_FORMAT_WITH_COLUMN_NAMES) {
+      grn_output_table_columns(ctx, outbuf, output_type, result_set, format);
+    }
+    grn_output_table_records(ctx, outbuf, output_type, result_set, format);
+    grn_output_map_close(ctx, outbuf, output_type);
+  } else {
+    grn_obj *column;
+    int n_records;
+
+    column = grn_obj_column(ctx,
+                            result_set,
+                            GRN_COLUMN_NAME_KEY,
+                            GRN_COLUMN_NAME_KEY_LEN);
+    grn_output_map_open(ctx, outbuf, output_type, "result_set", 1);
+    n_records = grn_table_size(ctx, result_set);
+    grn_output_cstr(ctx, outbuf, output_type, "keys");
+    grn_output_array_open(ctx, outbuf, output_type, "keys", n_records);
+    GRN_TABLE_EACH_BEGIN(ctx, result_set, cursor, id) {
+      GRN_BULK_REWIND(&buf);
+      grn_obj_get_value(ctx, column, id, &buf);
+      grn_text_esc(ctx, outbuf, GRN_BULK_HEAD(&buf), GRN_BULK_VSIZE(&buf));
+    } GRN_TABLE_EACH_END(ctx, cursor);
+    grn_output_array_close(ctx, outbuf, output_type);
+    grn_output_map_close(ctx, outbuf, output_type);
+    grn_obj_unlink(ctx, column);
+  }
+  GRN_OBJ_FIN(ctx, &buf);
+}
+
+void
+grn_output_result_set(grn_ctx *ctx,
+                      grn_obj *outbuf,
+                      grn_content_type output_type,
+                      grn_obj *result_set,
+                      grn_obj_format *format)
+{
+  if (grn_ctx_get_command_version(ctx) < GRN_COMMAND_VERSION_3) {
+    grn_output_result_set_v1(ctx, outbuf, output_type, result_set, format);
+  } else {
+    grn_output_result_set_v3(ctx, outbuf, output_type, result_set, format);
+  }
+}
+
 void
 grn_output_obj(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type,
                grn_obj *obj, grn_obj_format *format)
@@ -1677,7 +1892,8 @@ grn_output_obj(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type,
   case GRN_TABLE_PAT_KEY :
   case GRN_TABLE_DAT_KEY :
   case GRN_TABLE_NO_KEY :
-    grn_output_table(ctx, outbuf, output_type, obj, format);
+    /* Deprecated. Use grn_output_result_set() directly. */
+    grn_output_result_set(ctx, outbuf, output_type, obj, format);
     break;
   }
   GRN_OBJ_FIN(ctx, &buf);

  Modified: lib/proc/proc_select.c (+266 -15)
===================================================================
--- lib/proc/proc_select.c    2016-05-24 17:04:38 +0900 (36fff15)
+++ lib/proc/proc_select.c    2016-05-24 23:29:34 +0900 (c032ca9)
@@ -102,6 +102,8 @@ typedef struct {
   grn_obj *filtered_result;
 } grn_drilldown_data;
 
+typedef struct _grn_select_output_formatter grn_select_output_formatter;
+
 typedef struct {
   /* inputs */
   grn_select_string table;
@@ -138,9 +140,51 @@ typedef struct {
   uint16_t taintable;
   struct {
     int n_elements;
+    grn_select_output_formatter *formatter;
   } output;
 } grn_select_data;
 
+typedef void grn_select_output_result_sets_open_func(grn_ctx *ctx,
+                                                     grn_select_data *data);
+typedef void grn_select_output_result_sets_close_func(grn_ctx *ctx,
+                                                      grn_select_data *data);
+typedef void grn_select_output_match_label_func(grn_ctx *ctx,
+                                                grn_select_data *data);
+typedef void grn_select_output_slices_label_func(grn_ctx *ctx,
+                                                 grn_select_data *data);
+typedef void grn_select_output_slices_open_func(grn_ctx *ctx,
+                                                grn_select_data *data,
+                                                unsigned int n_result_sets);
+typedef void grn_select_output_slices_close_func(grn_ctx *ctx,
+                                                 grn_select_data *data);
+typedef void grn_select_output_slice_label_func(grn_ctx *ctx,
+                                                grn_select_data *data,
+                                                grn_slice_data *slice);
+typedef void grn_select_output_drilldowns_label_func(grn_ctx *ctx,
+                                                     grn_select_data *data);
+typedef void grn_select_output_drilldowns_open_func(grn_ctx *ctx,
+                                                    grn_select_data *data,
+                                                    unsigned int n_result_sets);
+typedef void grn_select_output_drilldowns_close_func(grn_ctx *ctx,
+                                                     grn_select_data *data);
+typedef void grn_select_output_drilldown_label_func(grn_ctx *ctx,
+                                                    grn_select_data *data,
+                                                    grn_drilldown_data *drilldown);
+
+struct _grn_select_output_formatter {
+  grn_select_output_result_sets_open_func  *result_sets_open;
+  grn_select_output_result_sets_close_func *result_sets_close;
+  grn_select_output_match_label_func       *match_label;
+  grn_select_output_slices_label_func      *slices_label;
+  grn_select_output_slices_open_func       *slices_open;
+  grn_select_output_slices_close_func      *slices_close;
+  grn_select_output_slice_label_func       *slice_label;
+  grn_select_output_drilldowns_label_func  *drilldowns_label;
+  grn_select_output_drilldowns_open_func   *drilldowns_open;
+  grn_select_output_drilldowns_close_func  *drilldowns_close;
+  grn_select_output_drilldown_label_func   *drilldown_label;
+};
+
 grn_rc
 grn_proc_syntax_expand_query(grn_ctx *ctx,
                              const char *query,
@@ -1441,12 +1485,14 @@ grn_select_sort(grn_ctx *ctx,
 }
 
 static grn_bool
-grn_select_output_records(grn_ctx *ctx,
-                          grn_select_data *data)
+grn_select_output_match(grn_ctx *ctx,
+                        grn_select_data *data)
 {
   int offset;
   grn_obj *output_table;
 
+  data->output.formatter->match_label(ctx, data);
+
   if (data->tables.sorted) {
     offset = 0;
     output_table = data->tables.sorted;
@@ -1586,6 +1632,8 @@ grn_select_output_slices(grn_ctx *ctx,
     return GRN_TRUE;
   }
 
+  data->output.formatter->slices_label(ctx, data);
+
   GRN_HASH_EACH_BEGIN(ctx, data->slices, cursor, id) {
     grn_slice_data *slice;
 
@@ -1595,7 +1643,8 @@ grn_select_output_slices(grn_ctx *ctx,
     }
   } GRN_HASH_EACH_END(ctx, cursor);
 
-  GRN_OUTPUT_MAP_OPEN("SLICES", n_available_results);
+  data->output.formatter->slices_open(ctx, data, n_available_results);
+
   GRN_HASH_EACH_BEGIN(ctx, data->slices, cursor, id) {
     grn_slice_data *slice;
     uint32_t n_hits;
@@ -1607,7 +1656,7 @@ grn_select_output_slices(grn_ctx *ctx,
       continue;
     }
 
-    GRN_OUTPUT_STR(slice->label.value, slice->label.length);
+    data->output.formatter->slice_label(ctx, data, slice);
 
     n_hits = grn_table_size(ctx, slice->table);
 
@@ -1666,7 +1715,8 @@ grn_select_output_slices(grn_ctx *ctx,
                   (int)(slice->label.length),
                   slice->label.value);
   } GRN_HASH_EACH_END(ctx, cursor);
-  GRN_OUTPUT_MAP_CLOSE();
+
+  data->output.formatter->slices_close(ctx, data);
 
   return succeeded;
 }
@@ -2137,6 +2187,8 @@ grn_select_output_drilldowns(grn_ctx *ctx,
     return GRN_TRUE;
   }
 
+  data->output.formatter->drilldowns_label(ctx, data);
+
   GRN_HASH_EACH_BEGIN(ctx, data->drilldowns, cursor, id) {
     grn_drilldown_data *drilldown;
     grn_table_group_result *result;
@@ -2150,7 +2202,7 @@ grn_select_output_drilldowns(grn_ctx *ctx,
 
   is_labeled = (data->drilldown.keys.length == 0);
   if (is_labeled) {
-    GRN_OUTPUT_MAP_OPEN("DRILLDOWNS", n_available_results);
+    data->output.formatter->drilldowns_open(ctx, data, n_available_results);
   }
 
   GRN_HASH_EACH_BEGIN(ctx, data->drilldowns, cursor, id) {
@@ -2174,9 +2226,7 @@ grn_select_output_drilldowns(grn_ctx *ctx,
       target_table = result->table;
     }
 
-    if (is_labeled) {
-      GRN_OUTPUT_STR(drilldown->label.value, drilldown->label.length);
-    }
+    data->output.formatter->drilldown_label(ctx, data, drilldown);
 
     n_hits = grn_table_size(ctx, target_table);
 
@@ -2241,9 +2291,7 @@ grn_select_output_drilldowns(grn_ctx *ctx,
     }
   } GRN_HASH_EACH_END(ctx, cursor);
 
-  if (is_labeled) {
-    GRN_OUTPUT_MAP_CLOSE();
-  }
+  data->output.formatter->drilldowns_close(ctx, data);
 
   return succeeded;
 }
@@ -2251,7 +2299,7 @@ grn_select_output_drilldowns(grn_ctx *ctx,
 static grn_bool
 grn_select_output(grn_ctx *ctx, grn_select_data *data)
 {
-  if (!grn_select_output_records(ctx, data)) {
+  if (!grn_select_output_match(ctx, data)) {
     return GRN_FALSE;
   }
 
@@ -2266,6 +2314,203 @@ grn_select_output(grn_ctx *ctx, grn_select_data *data)
   return GRN_TRUE;
 }
 
+static void
+grn_select_output_result_sets_open_v1(grn_ctx *ctx, grn_select_data *data)
+{
+  GRN_OUTPUT_ARRAY_OPEN("RESULT", data->output.n_elements);
+}
+
+static void
+grn_select_output_result_sets_close_v1(grn_ctx *ctx, grn_select_data *data)
+{
+  GRN_OUTPUT_ARRAY_CLOSE();
+}
+
+static void
+grn_select_output_match_label_v1(grn_ctx *ctx, grn_select_data *data)
+{
+}
+
+static void
+grn_select_output_slices_label_v1(grn_ctx *ctx, grn_select_data *data)
+{
+}
+
+static void
+grn_select_output_slices_open_v1(grn_ctx *ctx,
+                                 grn_select_data *data,
+                                 unsigned int n_result_sets)
+{
+  GRN_OUTPUT_MAP_OPEN("SLICES", n_result_sets);
+}
+
+static void
+grn_select_output_slices_close_v1(grn_ctx *ctx, grn_select_data *data)
+{
+  GRN_OUTPUT_MAP_CLOSE();
+}
+
+static void
+grn_select_output_slice_label_v1(grn_ctx *ctx,
+                                 grn_select_data *data,
+                                 grn_slice_data *slice)
+{
+  GRN_OUTPUT_STR(slice->label.value, slice->label.length);
+}
+
+static void
+grn_select_output_drilldowns_label_v1(grn_ctx *ctx, grn_select_data *data)
+{
+}
+
+static void
+grn_select_output_drilldowns_open_v1(grn_ctx *ctx,
+                                     grn_select_data *data,
+                                     unsigned int n_result_sets)
+{
+  if (data->drilldown.keys.length == 0) {
+    GRN_OUTPUT_MAP_OPEN("DRILLDOWNS", n_result_sets);
+  }
+}
+
+static void
+grn_select_output_drilldowns_close_v1(grn_ctx *ctx, grn_select_data *data)
+{
+  if (data->drilldown.keys.length == 0) {
+    GRN_OUTPUT_MAP_CLOSE();
+  }
+}
+
+static void
+grn_select_output_drilldown_label_v1(grn_ctx *ctx,
+                                     grn_select_data *data,
+                                     grn_drilldown_data *drilldown)
+{
+  if (data->drilldown.keys.length == 0) {
+    GRN_OUTPUT_STR(drilldown->label.value, drilldown->label.length);
+  }
+}
+
+static grn_select_output_formatter grn_select_output_formatter_v1 = {
+  grn_select_output_result_sets_open_v1,
+  grn_select_output_result_sets_close_v1,
+  grn_select_output_match_label_v1,
+  grn_select_output_slices_label_v1,
+  grn_select_output_slices_open_v1,
+  grn_select_output_slices_close_v1,
+  grn_select_output_slice_label_v1,
+  grn_select_output_drilldowns_label_v1,
+  grn_select_output_drilldowns_open_v1,
+  grn_select_output_drilldowns_close_v1,
+  grn_select_output_drilldown_label_v1
+};
+
+static void
+grn_select_output_result_sets_open_v3(grn_ctx *ctx, grn_select_data *data)
+{
+  int n_elements = 1;
+  if (data->slices) {
+    n_elements++;
+  }
+  if (data->drilldowns) {
+    n_elements++;
+  }
+  GRN_OUTPUT_MAP_OPEN("result_sets", n_elements);
+}
+
+static void
+grn_select_output_result_sets_close_v3(grn_ctx *ctx, grn_select_data *data)
+{
+  GRN_OUTPUT_MAP_CLOSE();
+}
+
+static void
+grn_select_output_match_label_v3(grn_ctx *ctx, grn_select_data *data)
+{
+  GRN_OUTPUT_CSTR("match");
+}
+
+static void
+grn_select_output_slices_label_v3(grn_ctx *ctx, grn_select_data *data)
+{
+  GRN_OUTPUT_CSTR("slices");
+}
+
+static void
+grn_select_output_slices_open_v3(grn_ctx *ctx,
+                                 grn_select_data *data,
+                                 unsigned int n_result_sets)
+{
+  GRN_OUTPUT_MAP_OPEN("slices", n_result_sets);
+}
+
+static void
+grn_select_output_slices_close_v3(grn_ctx *ctx, grn_select_data *data)
+{
+  GRN_OUTPUT_MAP_CLOSE();
+}
+
+static void
+grn_select_output_slice_label_v3(grn_ctx *ctx,
+                                 grn_select_data *data,
+                                 grn_slice_data *slice)
+{
+  GRN_OUTPUT_STR(slice->label.value, slice->label.length);
+}
+
+static void
+grn_select_output_drilldowns_label_v3(grn_ctx *ctx, grn_select_data *data)
+{
+  GRN_OUTPUT_CSTR("drilldowns");
+}
+
+static void
+grn_select_output_drilldowns_open_v3(grn_ctx *ctx,
+                                     grn_select_data *data,
+                                     unsigned int n_result_sets)
+{
+  GRN_OUTPUT_MAP_OPEN("drilldowns", n_result_sets);
+}
+
+static void
+grn_select_output_drilldowns_close_v3(grn_ctx *ctx, grn_select_data *data)
+{
+  GRN_OUTPUT_MAP_CLOSE();
+}
+
+static void
+grn_select_output_drilldown_label_v3(grn_ctx *ctx,
+                                     grn_select_data *data,
+                                     grn_drilldown_data *drilldown)
+{
+  if (data->drilldown.keys.length == 0) {
+    GRN_OUTPUT_STR(drilldown->label.value, drilldown->label.length);
+  } else {
+    char name[GRN_TABLE_MAX_KEY_SIZE];
+    int name_len;
+
+    name_len = grn_obj_name(ctx,
+                            drilldown->parsed_keys[0].key,
+                            name,
+                            GRN_TABLE_MAX_KEY_SIZE);
+    GRN_OUTPUT_STR(name, name_len);
+  }
+}
+
+static grn_select_output_formatter grn_select_output_formatter_v3 = {
+  grn_select_output_result_sets_open_v3,
+  grn_select_output_result_sets_close_v3,
+  grn_select_output_match_label_v3,
+  grn_select_output_slices_label_v3,
+  grn_select_output_slices_open_v3,
+  grn_select_output_slices_close_v3,
+  grn_select_output_slice_label_v3,
+  grn_select_output_drilldowns_label_v3,
+  grn_select_output_drilldowns_open_v3,
+  grn_select_output_drilldowns_close_v3,
+  grn_select_output_drilldown_label_v3
+};
+
 static grn_rc
 grn_select(grn_ctx *ctx, grn_select_data *data)
 {
@@ -2277,6 +2522,12 @@ grn_select(grn_ctx *ctx, grn_select_data *data)
   long long int threshold, original_threshold = 0;
   grn_cache *cache_obj = grn_cache_current_get(ctx);
 
+  if (grn_ctx_get_command_version(ctx) < GRN_COMMAND_VERSION_3) {
+    data->output.formatter = &grn_select_output_formatter_v1;
+  } else {
+    data->output.formatter = &grn_select_output_formatter_v3;
+  }
+
   data->tables.target = NULL;
   data->tables.initial = NULL;
   data->tables.result = NULL;
@@ -2520,9 +2771,9 @@ grn_select(grn_ctx *ctx, grn_select_data *data)
         goto exit;
       }
 
-      GRN_OUTPUT_ARRAY_OPEN("RESULT", data->output.n_elements);
+      data->output.formatter->result_sets_open(ctx, data);
       succeeded = grn_select_output(ctx, data);
-      GRN_OUTPUT_ARRAY_CLOSE();
+      data->output.formatter->result_sets_close(ctx, data);
       if (!succeeded) {
         goto exit;
       }

  Added: test/command/suite/select/slices/command_version_3.expected (+98 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/select/slices/command_version_3.expected    2016-05-24 23:29:34 +0900 (f449326)
@@ -0,0 +1,98 @@
+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 date COLUMN_SCALAR Time
+[[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!", "date": "2016-05-19 12:00:00", "tag": "Groonga"},
+{"_key": "Mroonga is fast!", "date": "2016-05-19 12:00:01", "tag": "Mroonga"},
+{"_key": "Groonga sticker!", "date": "2016-05-19 12:00:02", "tag": "Groonga"},
+{"_key": "Rroonga is fast!", "date": "2016-05-19 12:00:03", "tag": "Rroonga"}
+]
+[[0,0.0,0.0],4]
+select Memos   --slices[groonga].filter 'tag == "Groonga"'   --slices[groonga].sort_keys 'date'   --slices[groonga].output_columns '_key, date'   --command_version 3
+{
+  "header": {
+    "return_code": 0,
+    "start_time": 0.0,
+    "elapsed_time": 0.0
+  },
+  "body": {
+    "match": {
+      "n_hits": 4,
+      "columns": [
+        {
+          "name": "_id",
+          "type": "UInt32"
+        },
+        {
+          "name": "_key",
+          "type": "ShortText"
+        },
+        {
+          "name": "date",
+          "type": "Time"
+        },
+        {
+          "name": "tag",
+          "type": "Tags"
+        }
+      ],
+      "records": [
+        [
+          1,
+          "Groonga is fast!",
+          1463626800.0,
+          "Groonga"
+        ],
+        [
+          2,
+          "Mroonga is fast!",
+          1463626801.0,
+          "Mroonga"
+        ],
+        [
+          3,
+          "Groonga sticker!",
+          1463626802.0,
+          "Groonga"
+        ],
+        [
+          4,
+          "Rroonga is fast!",
+          1463626803.0,
+          "Rroonga"
+        ]
+      ]
+    },
+    "slices": {
+      "groonga": {
+        "n_hits": 2,
+        "columns": [
+          {
+            "name": "_key",
+            "type": "ShortText"
+          },
+          {
+            "name": "date",
+            "type": "Time"
+          }
+        ],
+        "records": [
+          [
+            "Groonga is fast!",
+            1463626800.0
+          ],
+          [
+            "Groonga sticker!",
+            1463626802.0
+          ]
+        ]
+      }
+    }
+  }
+}

  Added: test/command/suite/select/slices/command_version_3.test (+19 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/select/slices/command_version_3.test    2016-05-24 23:29:34 +0900 (9d625c5)
@@ -0,0 +1,19 @@
+table_create Tags TABLE_PAT_KEY ShortText
+
+table_create Memos TABLE_HASH_KEY ShortText
+column_create Memos date COLUMN_SCALAR Time
+column_create Memos tag COLUMN_SCALAR Tags
+
+load --table Memos
+[
+{"_key": "Groonga is fast!", "date": "2016-05-19 12:00:00", "tag": "Groonga"},
+{"_key": "Mroonga is fast!", "date": "2016-05-19 12:00:01", "tag": "Mroonga"},
+{"_key": "Groonga sticker!", "date": "2016-05-19 12:00:02", "tag": "Groonga"},
+{"_key": "Rroonga is fast!", "date": "2016-05-19 12:00:03", "tag": "Rroonga"}
+]
+
+select Memos \
+  --slices[groonga].filter 'tag == "Groonga"' \
+  --slices[groonga].sort_keys 'date' \
+  --slices[groonga].output_columns '_key, date' \
+  --command_version 3
-------------- next part --------------
HTML����������������������������...
다운로드 



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