[Groonga-commit] groonga/groonga at 120cd4e [master] snippet, snippet_html: add an option for changing return value for no match (#931)

Back to archive index
Yasuhiro Horimoto null+****@clear*****
Thu May 16 17:10:02 JST 2019


Yasuhiro Horimoto	2019-05-16 17:10:02 +0900 (Thu, 16 May 2019)

  Revision: 120cd4eca009da58dc2e3dd764289b170c65e011
  https://github.com/groonga/groonga/commit/120cd4eca009da58dc2e3dd764289b170c65e011

  Message:
    snippet, snippet_html: add an option for changing return value for no match (#931)
    
    * snippet, snippet_html: add an option for changing return value for no match
    
    * snippet, snippet_html: use option object
    
    * snippet, snippet_html: don't use "== NULL"
    
    * snippet, snippet_html: remove needless comment
    
    * snippet, snippet_html: remove needless loop
    
    * snippet, snippet_html: use "GRN_HASH_EACH_BEGIN" and "GRN_HASH_EACH_END" macros
    
    * snippet, snippet_html: use "grn_raw_string"
    
    * snippet, snippet_html: add a "snippet_html()" tag in log message
    
    * snippet, snippet_html: use "nargs > 1" instead of "arg[1]"
    
    Because if we use "arg[1]" when "nargs==1", Groonga will crash.
    
    * snippet, snippet_html: use GRN_RAW_STRING_EQUAL_CSTRING
    
    * snippet, snippet_html: add a missing space
    
    * snippet, snippet_html: don't use goto in "GRN_HASH_EACH_BEGIN {}"
    
    * snippet, snippet_html: use GRN_RAW_STRING_EQUAL_CSTRING again
    
    Because the before modification caused error in the tests.
    
    * snippet, snippet_html: remove a needless code
    
    * snippet, snippet_html: remove a wrong if section
    
    * snippet, snippet_html: remove a needless exit
    
    * snippet, snippet_html: add a missing modification file
    
    * Revert "snippet, snippet_html: add a missing modification file"
    
    This reverts commit 0a4419c730c2f0b8093984219dce952e1b96d7ee.
    Because this commit is needless.
    
    * snippet, snippet_html: add a test for setting a invalid option
    
    * snippet, snippet_html: add a test for setting a empty option
    
    * snippet, snippet_html: use more meaningful name
    
    * snippet, snippet_html: fix a wrong expected value
    
    * Pass GRN_TABLE_HASH_KEY for object by GRN_PTR
    
    Because GRN_TABLE_HASH_KEY isn't copy-able.
    
    * Add support for outputting GRN_TABLE_HASH_KEY
    
    GRN_HASH_TINY is only supported for now.

  Copied files:
    test/command/suite/select/function/snippet_html/none/empty_array.expected
      (from test/command/suite/select/function/snippet_html/none.expected)
    test/command/suite/select/function/snippet_html/none/empty_array.test
      (from test/command/suite/select/function/snippet_html/none.test)
    test/command/suite/select/function/snippet_html/none/empty_object.expected
      (from test/command/suite/select/function/snippet_html/none.expected)
    test/command/suite/select/function/snippet_html/none/empty_object.test
      (from test/command/suite/select/function/snippet_html/none.test)
    test/command/suite/select/function/snippet_html/none/empty_string.expected
      (from test/command/suite/select/function/snippet_html/none.expected)
    test/command/suite/select/function/snippet_html/none/empty_string.test
      (from test/command/suite/select/function/snippet_html/none.test)
    test/command/suite/select/function/snippet_html/none/invalid_option.expected
      (from test/command/suite/select/function/snippet_html/none.expected)
    test/command/suite/select/function/snippet_html/none/invalid_option.test
      (from test/command/suite/select/function/snippet_html/none.test)
    test/command/suite/select/function/snippet_html/none/no_option.expected
      (from test/command/suite/select/function/snippet_html/none.expected)
    test/command/suite/select/function/snippet_html/none/no_option.test
      (from test/command/suite/select/function/snippet_html/none.test)
  Modified files:
    lib/grn_ecmascript.c
    lib/grn_ecmascript.lemon
    lib/output.c
    lib/proc/proc_snippet.c
  Renamed files:
    test/command/suite/select/function/snippet_html/none/object.expected
      (from test/command/suite/select/function/snippet_html/none.expected)
    test/command/suite/select/function/snippet_html/none/object.test
      (from test/command/suite/select/function/snippet_html/none.test)

  Modified: lib/grn_ecmascript.c (+179 -174)
===================================================================
--- lib/grn_ecmascript.c    2019-05-16 17:02:04 +0900 (5c2b8f685)
+++ lib/grn_ecmascript.c    2019-05-16 17:10:02 +0900 (4ad6adb97)
@@ -25,13 +25,13 @@
 #include <stdio.h>
 #include <assert.h>
 /************ Begin %include sections from the grammar ************************/
-#line 4 "../../groonga/lib/grn_ecmascript.lemon"
+#line 4 "grn_ecmascript.lemon"
 
 #ifdef assert
 #  undef assert
 #endif
 #define assert GRN_ASSERT
-#line 35 "../../groonga/lib/grn_ecmascript.c"
+#line 35 "grn_ecmascript.c"
 /**************** End of %include directives **********************************/
 /* These constants specify the various numeric values for terminal symbols
 ** in a format understandable to "makeheaders".  This section is blank unless
@@ -1068,11 +1068,11 @@ static void yy_destructor(
 /********* Begin destructor definitions ***************************************/
     case 76: /* suppress_unused_variable_warning */
 {
-#line 14 "../../groonga/lib/grn_ecmascript.lemon"
+#line 14 "grn_ecmascript.lemon"
 
   (void)efsi;
 
-#line 1076 "../../groonga/lib/grn_ecmascript.c"
+#line 1076 "grn_ecmascript.c"
 }
       break;
 /********* End destructor definitions *****************************************/
@@ -1723,63 +1723,63 @@ static YYACTIONTYPE yy_reduce(
 /********** Begin reduce actions **********************************************/
         YYMINORTYPE yylhsminor;
       case 0: /* query ::= query query_element */
-#line 55 "../../groonga/lib/grn_ecmascript.lemon"
+#line 55 "grn_ecmascript.lemon"
 {
   grn_expr_append_op(efsi->ctx, efsi->e, grn_int32_value_at(&efsi->op_stack, -1), 2);
 }
-#line 1731 "../../groonga/lib/grn_ecmascript.c"
+#line 1731 "grn_ecmascript.c"
         break;
       case 1: /* query ::= query LOGICAL_AND query_element */
       case 25: /* logical_and_expression ::= logical_and_expression LOGICAL_AND bitwise_or_expression */ yytestcase(yyruleno==25);
-#line 58 "../../groonga/lib/grn_ecmascript.lemon"
+#line 58 "grn_ecmascript.lemon"
 {
   grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_AND, 2);
 }
-#line 1739 "../../groonga/lib/grn_ecmascript.c"
+#line 1739 "grn_ecmascript.c"
         break;
       case 2: /* query ::= query LOGICAL_AND_NOT query_element */
       case 26: /* logical_and_expression ::= logical_and_expression LOGICAL_AND_NOT bitwise_or_expression */ yytestcase(yyruleno==26);
-#line 61 "../../groonga/lib/grn_ecmascript.lemon"
+#line 61 "grn_ecmascript.lemon"
 {
   grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_AND_NOT, 2);
 }
-#line 1747 "../../groonga/lib/grn_ecmascript.c"
+#line 1747 "grn_ecmascript.c"
         break;
       case 3: /* query ::= query LOGICAL_OR query_element */
       case 24: /* logical_or_expression ::= logical_or_expression LOGICAL_OR logical_and_expression */ yytestcase(yyruleno==24);
-#line 64 "../../groonga/lib/grn_ecmascript.lemon"
+#line 64 "grn_ecmascript.lemon"
 {
   grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_OR, 2);
 }
-#line 1755 "../../groonga/lib/grn_ecmascript.c"
+#line 1755 "grn_ecmascript.c"
         break;
       case 4: /* query ::= query NEGATIVE query_element */
-#line 67 "../../groonga/lib/grn_ecmascript.lemon"
+#line 67 "grn_ecmascript.lemon"
 {
   int weight;
   GRN_INT32_POP(&efsi->weight_stack, weight);
   grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_ADJUST, 2);
 }
-#line 1764 "../../groonga/lib/grn_ecmascript.c"
+#line 1764 "grn_ecmascript.c"
         break;
       case 5: /* query_element ::= ADJUST query_element */
-#line 76 "../../groonga/lib/grn_ecmascript.lemon"
+#line 76 "grn_ecmascript.lemon"
 {
   int weight;
   GRN_INT32_POP(&efsi->weight_stack, weight);
 }
-#line 1772 "../../groonga/lib/grn_ecmascript.c"
+#line 1772 "grn_ecmascript.c"
         break;
       case 6: /* query_element ::= RELATIVE_OP query_element */
-#line 80 "../../groonga/lib/grn_ecmascript.lemon"
+#line 80 "grn_ecmascript.lemon"
 {
   int mode;
   GRN_INT32_POP(&efsi->mode_stack, mode);
 }
-#line 1780 "../../groonga/lib/grn_ecmascript.c"
+#line 1780 "grn_ecmascript.c"
         break;
       case 7: /* query_element ::= IDENTIFIER RELATIVE_OP query_element */
-#line 84 "../../groonga/lib/grn_ecmascript.lemon"
+#line 84 "grn_ecmascript.lemon"
 {
   int mode;
   grn_obj *c;
@@ -1809,196 +1809,196 @@ static YYACTIONTYPE yy_reduce(
     break;
   }
 }
-#line 1813 "../../groonga/lib/grn_ecmascript.c"
+#line 1813 "grn_ecmascript.c"
         break;
       case 8: /* query_element ::= BRACEL expression BRACER */
       case 9: /* query_element ::= EVAL primary_expression */ yytestcase(yyruleno==9);
-#line 113 "../../groonga/lib/grn_ecmascript.lemon"
+#line 113 "grn_ecmascript.lemon"
 {
   efsi->flags = efsi->default_flags;
 }
-#line 1821 "../../groonga/lib/grn_ecmascript.c"
+#line 1821 "grn_ecmascript.c"
         break;
       case 10: /* expression ::= expression COMMA assignment_expression */
-#line 121 "../../groonga/lib/grn_ecmascript.lemon"
+#line 121 "grn_ecmascript.lemon"
 {
   grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_COMMA, 2);
 }
-#line 1828 "../../groonga/lib/grn_ecmascript.c"
+#line 1828 "grn_ecmascript.c"
         break;
       case 11: /* assignment_expression ::= lefthand_side_expression ASSIGN assignment_expression */
-#line 126 "../../groonga/lib/grn_ecmascript.lemon"
+#line 126 "grn_ecmascript.lemon"
 {
   grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_ASSIGN, 2);
 }
-#line 1835 "../../groonga/lib/grn_ecmascript.c"
+#line 1835 "grn_ecmascript.c"
         break;
       case 12: /* assignment_expression ::= lefthand_side_expression STAR_ASSIGN assignment_expression */
-#line 129 "../../groonga/lib/grn_ecmascript.lemon"
+#line 129 "grn_ecmascript.lemon"
 {
   grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_STAR_ASSIGN, 2);
 }
-#line 1842 "../../groonga/lib/grn_ecmascript.c"
+#line 1842 "grn_ecmascript.c"
         break;
       case 13: /* assignment_expression ::= lefthand_side_expression SLASH_ASSIGN assignment_expression */
-#line 132 "../../groonga/lib/grn_ecmascript.lemon"
+#line 132 "grn_ecmascript.lemon"
 {
   grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_SLASH_ASSIGN, 2);
 }
-#line 1849 "../../groonga/lib/grn_ecmascript.c"
+#line 1849 "grn_ecmascript.c"
         break;
       case 14: /* assignment_expression ::= lefthand_side_expression MOD_ASSIGN assignment_expression */
-#line 135 "../../groonga/lib/grn_ecmascript.lemon"
+#line 135 "grn_ecmascript.lemon"
 {
   grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_MOD_ASSIGN, 2);
 }
-#line 1856 "../../groonga/lib/grn_ecmascript.c"
+#line 1856 "grn_ecmascript.c"
         break;
       case 15: /* assignment_expression ::= lefthand_side_expression PLUS_ASSIGN assignment_expression */
-#line 138 "../../groonga/lib/grn_ecmascript.lemon"
+#line 138 "grn_ecmascript.lemon"
 {
   grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_PLUS_ASSIGN, 2);
 }
-#line 1863 "../../groonga/lib/grn_ecmascript.c"
+#line 1863 "grn_ecmascript.c"
         break;
       case 16: /* assignment_expression ::= lefthand_side_expression MINUS_ASSIGN assignment_expression */
-#line 141 "../../groonga/lib/grn_ecmascript.lemon"
+#line 141 "grn_ecmascript.lemon"
 {
   grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_MINUS_ASSIGN, 2);
 }
-#line 1870 "../../groonga/lib/grn_ecmascript.c"
+#line 1870 "grn_ecmascript.c"
         break;
       case 17: /* assignment_expression ::= lefthand_side_expression SHIFTL_ASSIGN assignment_expression */
-#line 144 "../../groonga/lib/grn_ecmascript.lemon"
+#line 144 "grn_ecmascript.lemon"
 {
   grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_SHIFTL_ASSIGN, 2);
 }
-#line 1877 "../../groonga/lib/grn_ecmascript.c"
+#line 1877 "grn_ecmascript.c"
         break;
       case 18: /* assignment_expression ::= lefthand_side_expression SHIFTR_ASSIGN assignment_expression */
-#line 147 "../../groonga/lib/grn_ecmascript.lemon"
+#line 147 "grn_ecmascript.lemon"
 {
   grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_SHIFTR_ASSIGN, 2);
 }
-#line 1884 "../../groonga/lib/grn_ecmascript.c"
+#line 1884 "grn_ecmascript.c"
         break;
       case 19: /* assignment_expression ::= lefthand_side_expression SHIFTRR_ASSIGN assignment_expression */
-#line 150 "../../groonga/lib/grn_ecmascript.lemon"
+#line 150 "grn_ecmascript.lemon"
 {
   grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_SHIFTRR_ASSIGN, 2);
 }
-#line 1891 "../../groonga/lib/grn_ecmascript.c"
+#line 1891 "grn_ecmascript.c"
         break;
       case 20: /* assignment_expression ::= lefthand_side_expression AND_ASSIGN assignment_expression */
-#line 153 "../../groonga/lib/grn_ecmascript.lemon"
+#line 153 "grn_ecmascript.lemon"
 {
   grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_AND_ASSIGN, 2);
 }
-#line 1898 "../../groonga/lib/grn_ecmascript.c"
+#line 1898 "grn_ecmascript.c"
         break;
       case 21: /* assignment_expression ::= lefthand_side_expression XOR_ASSIGN assignment_expression */
-#line 156 "../../groonga/lib/grn_ecmascript.lemon"
+#line 156 "grn_ecmascript.lemon"
 {
   grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_XOR_ASSIGN, 2);
 }
-#line 1905 "../../groonga/lib/grn_ecmascript.c"
+#line 1905 "grn_ecmascript.c"
         break;
       case 22: /* assignment_expression ::= lefthand_side_expression OR_ASSIGN assignment_expression */
-#line 159 "../../groonga/lib/grn_ecmascript.lemon"
+#line 159 "grn_ecmascript.lemon"
 {
   grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_OR_ASSIGN, 2);
 }
-#line 1912 "../../groonga/lib/grn_ecmascript.c"
+#line 1912 "grn_ecmascript.c"
         break;
       case 23: /* conditional_expression ::= logical_or_expression QUESTION assignment_expression COLON assignment_expression */
-#line 164 "../../groonga/lib/grn_ecmascript.lemon"
+#line 164 "grn_ecmascript.lemon"
 {
   grn_expr *e = (grn_expr *)efsi->e;
   e->codes[yymsp[-3].minor.yy0].nargs = yymsp[-1].minor.yy0 - yymsp[-3].minor.yy0;
   e->codes[yymsp[-1].minor.yy0].nargs = e->codes_curr - yymsp[-1].minor.yy0 - 1;
 }
-#line 1921 "../../groonga/lib/grn_ecmascript.c"
+#line 1921 "grn_ecmascript.c"
         break;
       case 27: /* bitwise_or_expression ::= bitwise_or_expression BITWISE_OR bitwise_xor_expression */
-#line 184 "../../groonga/lib/grn_ecmascript.lemon"
+#line 184 "grn_ecmascript.lemon"
 {
   grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_BITWISE_OR, 2);
 }
-#line 1928 "../../groonga/lib/grn_ecmascript.c"
+#line 1928 "grn_ecmascript.c"
         break;
       case 28: /* bitwise_xor_expression ::= bitwise_xor_expression BITWISE_XOR bitwise_and_expression */
-#line 189 "../../groonga/lib/grn_ecmascript.lemon"
+#line 189 "grn_ecmascript.lemon"
 {
   grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_BITWISE_XOR, 2);
 }
-#line 1935 "../../groonga/lib/grn_ecmascript.c"
+#line 1935 "grn_ecmascript.c"
         break;
       case 29: /* bitwise_and_expression ::= bitwise_and_expression BITWISE_AND equality_expression */
-#line 194 "../../groonga/lib/grn_ecmascript.lemon"
+#line 194 "grn_ecmascript.lemon"
 {
   grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_BITWISE_AND, 2);
 }
-#line 1942 "../../groonga/lib/grn_ecmascript.c"
+#line 1942 "grn_ecmascript.c"
         break;
       case 30: /* equality_expression ::= equality_expression EQUAL relational_expression */
-#line 199 "../../groonga/lib/grn_ecmascript.lemon"
+#line 199 "grn_ecmascript.lemon"
 {
   grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_EQUAL, 2);
 }
-#line 1949 "../../groonga/lib/grn_ecmascript.c"
+#line 1949 "grn_ecmascript.c"
         break;
       case 31: /* equality_expression ::= equality_expression NOT_EQUAL relational_expression */
-#line 202 "../../groonga/lib/grn_ecmascript.lemon"
+#line 202 "grn_ecmascript.lemon"
 {
   grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_NOT_EQUAL, 2);
 }
-#line 1956 "../../groonga/lib/grn_ecmascript.c"
+#line 1956 "grn_ecmascript.c"
         break;
       case 32: /* relational_expression ::= relational_expression LESS shift_expression */
-#line 207 "../../groonga/lib/grn_ecmascript.lemon"
+#line 207 "grn_ecmascript.lemon"
 {
   grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_LESS, 2);
 }
-#line 1963 "../../groonga/lib/grn_ecmascript.c"
+#line 1963 "grn_ecmascript.c"
         break;
       case 33: /* relational_expression ::= relational_expression GREATER shift_expression */
-#line 210 "../../groonga/lib/grn_ecmascript.lemon"
+#line 210 "grn_ecmascript.lemon"
 {
   grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_GREATER, 2);
 }
-#line 1970 "../../groonga/lib/grn_ecmascript.c"
+#line 1970 "grn_ecmascript.c"
         break;
       case 34: /* relational_expression ::= relational_expression LESS_EQUAL shift_expression */
-#line 213 "../../groonga/lib/grn_ecmascript.lemon"
+#line 213 "grn_ecmascript.lemon"
 {
   grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_LESS_EQUAL, 2);
 }
-#line 1977 "../../groonga/lib/grn_ecmascript.c"
+#line 1977 "grn_ecmascript.c"
         break;
       case 35: /* relational_expression ::= relational_expression GREATER_EQUAL shift_expression */
-#line 216 "../../groonga/lib/grn_ecmascript.lemon"
+#line 216 "grn_ecmascript.lemon"
 {
   grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_GREATER_EQUAL, 2);
 }
-#line 1984 "../../groonga/lib/grn_ecmascript.c"
+#line 1984 "grn_ecmascript.c"
         break;
       case 36: /* relational_expression ::= relational_expression IN shift_expression */
-#line 219 "../../groonga/lib/grn_ecmascript.lemon"
+#line 219 "grn_ecmascript.lemon"
 {
   grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_IN, 2);
 }
-#line 1991 "../../groonga/lib/grn_ecmascript.c"
+#line 1991 "grn_ecmascript.c"
         break;
       case 37: /* relational_expression ::= relational_expression MATCH shift_expression */
       case 89: /* adjust_match_expression ::= IDENTIFIER MATCH STRING */ yytestcase(yyruleno==89);
-#line 222 "../../groonga/lib/grn_ecmascript.lemon"
+#line 222 "grn_ecmascript.lemon"
 {
   grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_MATCH, 2);
 }
-#line 1999 "../../groonga/lib/grn_ecmascript.c"
+#line 1999 "grn_ecmascript.c"
         break;
       case 38: /* relational_expression ::= relational_expression NEAR shift_expression */
-#line 225 "../../groonga/lib/grn_ecmascript.lemon"
+#line 225 "grn_ecmascript.lemon"
 {
   {
     int max_interval;
@@ -2008,17 +2008,17 @@ static YYACTIONTYPE yy_reduce(
   }
   grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_NEAR, 3);
 }
-#line 2012 "../../groonga/lib/grn_ecmascript.c"
+#line 2012 "grn_ecmascript.c"
         break;
       case 39: /* relational_expression ::= relational_expression NEAR2 shift_expression */
-#line 234 "../../groonga/lib/grn_ecmascript.lemon"
+#line 234 "grn_ecmascript.lemon"
 {
   grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_NEAR2, 2);
 }
-#line 2019 "../../groonga/lib/grn_ecmascript.c"
+#line 2019 "grn_ecmascript.c"
         break;
       case 40: /* relational_expression ::= relational_expression SIMILAR shift_expression */
-#line 237 "../../groonga/lib/grn_ecmascript.lemon"
+#line 237 "grn_ecmascript.lemon"
 {
   {
     int similarity_threshold;
@@ -2028,17 +2028,17 @@ static YYACTIONTYPE yy_reduce(
   }
   grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_SIMILAR, 3);
 }
-#line 2032 "../../groonga/lib/grn_ecmascript.c"
+#line 2032 "grn_ecmascript.c"
         break;
       case 41: /* relational_expression ::= relational_expression TERM_EXTRACT shift_expression */
-#line 246 "../../groonga/lib/grn_ecmascript.lemon"
+#line 246 "grn_ecmascript.lemon"
 {
   grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_TERM_EXTRACT, 2);
 }
-#line 2039 "../../groonga/lib/grn_ecmascript.c"
+#line 2039 "grn_ecmascript.c"
         break;
       case 42: /* relational_expression ::= relational_expression QUORUM shift_expression */
-#line 249 "../../groonga/lib/grn_ecmascript.lemon"
+#line 249 "grn_ecmascript.lemon"
 {
   {
     int quorum_threshold;
@@ -2048,103 +2048,103 @@ static YYACTIONTYPE yy_reduce(
   }
   grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_QUORUM, 3);
 }
-#line 2052 "../../groonga/lib/grn_ecmascript.c"
+#line 2052 "grn_ecmascript.c"
         break;
       case 43: /* relational_expression ::= relational_expression LCP shift_expression */
-#line 258 "../../groonga/lib/grn_ecmascript.lemon"
+#line 258 "grn_ecmascript.lemon"
 {
   grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_LCP, 2);
 }
-#line 2059 "../../groonga/lib/grn_ecmascript.c"
+#line 2059 "grn_ecmascript.c"
         break;
       case 44: /* relational_expression ::= relational_expression PREFIX shift_expression */
-#line 261 "../../groonga/lib/grn_ecmascript.lemon"
+#line 261 "grn_ecmascript.lemon"
 {
   grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_PREFIX, 2);
 }
-#line 2066 "../../groonga/lib/grn_ecmascript.c"
+#line 2066 "grn_ecmascript.c"
         break;
       case 45: /* relational_expression ::= relational_expression SUFFIX shift_expression */
-#line 264 "../../groonga/lib/grn_ecmascript.lemon"
+#line 264 "grn_ecmascript.lemon"
 {
   grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_SUFFIX, 2);
 }
-#line 2073 "../../groonga/lib/grn_ecmascript.c"
+#line 2073 "grn_ecmascript.c"
         break;
       case 46: /* relational_expression ::= relational_expression REGEXP shift_expression */
-#line 267 "../../groonga/lib/grn_ecmascript.lemon"
+#line 267 "grn_ecmascript.lemon"
 {
   grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_REGEXP, 2);
 }
-#line 2080 "../../groonga/lib/grn_ecmascript.c"
+#line 2080 "grn_ecmascript.c"
         break;
       case 47: /* shift_expression ::= shift_expression SHIFTL additive_expression */
-#line 272 "../../groonga/lib/grn_ecmascript.lemon"
+#line 272 "grn_ecmascript.lemon"
 {
   grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_SHIFTL, 2);
 }
-#line 2087 "../../groonga/lib/grn_ecmascript.c"
+#line 2087 "grn_ecmascript.c"
         break;
       case 48: /* shift_expression ::= shift_expression SHIFTR additive_expression */
-#line 275 "../../groonga/lib/grn_ecmascript.lemon"
+#line 275 "grn_ecmascript.lemon"
 {
   grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_SHIFTR, 2);
 }
-#line 2094 "../../groonga/lib/grn_ecmascript.c"
+#line 2094 "grn_ecmascript.c"
         break;
       case 49: /* shift_expression ::= shift_expression SHIFTRR additive_expression */
-#line 278 "../../groonga/lib/grn_ecmascript.lemon"
+#line 278 "grn_ecmascript.lemon"
 {
   grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_SHIFTRR, 2);
 }
-#line 2101 "../../groonga/lib/grn_ecmascript.c"
+#line 2101 "grn_ecmascript.c"
         break;
       case 50: /* additive_expression ::= additive_expression PLUS multiplicative_expression */
       case 87: /* adjuster ::= adjuster PLUS adjust_expression */ yytestcase(yyruleno==87);
-#line 283 "../../groonga/lib/grn_ecmascript.lemon"
+#line 283 "grn_ecmascript.lemon"
 {
   grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_PLUS, 2);
 }
-#line 2109 "../../groonga/lib/grn_ecmascript.c"
+#line 2109 "grn_ecmascript.c"
         break;
       case 51: /* additive_expression ::= additive_expression MINUS multiplicative_expression */
-#line 286 "../../groonga/lib/grn_ecmascript.lemon"
+#line 286 "grn_ecmascript.lemon"
 {
   grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_MINUS, 2);
 }
-#line 2116 "../../groonga/lib/grn_ecmascript.c"
+#line 2116 "grn_ecmascript.c"
         break;
       case 52: /* multiplicative_expression ::= multiplicative_expression STAR unary_expression */
       case 88: /* adjust_expression ::= adjust_match_expression STAR DECIMAL */ yytestcase(yyruleno==88);
-#line 291 "../../groonga/lib/grn_ecmascript.lemon"
+#line 291 "grn_ecmascript.lemon"
 {
   grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_STAR, 2);
 }
-#line 2124 "../../groonga/lib/grn_ecmascript.c"
+#line 2124 "grn_ecmascript.c"
         break;
       case 53: /* multiplicative_expression ::= multiplicative_expression SLASH unary_expression */
-#line 294 "../../groonga/lib/grn_ecmascript.lemon"
+#line 294 "grn_ecmascript.lemon"
 {
   grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_SLASH, 2);
 }
-#line 2131 "../../groonga/lib/grn_ecmascript.c"
+#line 2131 "grn_ecmascript.c"
         break;
       case 54: /* multiplicative_expression ::= multiplicative_expression MOD unary_expression */
-#line 297 "../../groonga/lib/grn_ecmascript.lemon"
+#line 297 "grn_ecmascript.lemon"
 {
   grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_MOD, 2);
 }
-#line 2138 "../../groonga/lib/grn_ecmascript.c"
+#line 2138 "grn_ecmascript.c"
         break;
       case 55: /* unary_expression ::= DELETE unary_expression */
-#line 302 "../../groonga/lib/grn_ecmascript.lemon"
+#line 302 "grn_ecmascript.lemon"
 {
   grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_DELETE, 1);
 }
-#line 2145 "../../groonga/lib/grn_ecmascript.c"
+#line 2145 "grn_ecmascript.c"
         break;
       case 56: /* unary_expression ::= INCR unary_expression */
-#line 305 "../../groonga/lib/grn_ecmascript.lemon"
+#line 305 "grn_ecmascript.lemon"
 {
   grn_ctx *ctx = efsi->ctx;
   grn_expr *e = (grn_expr *)(efsi->e);
@@ -2162,10 +2162,10 @@ static YYACTIONTYPE yy_reduce(
     grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_INCR, 1);
   }
 }
-#line 2166 "../../groonga/lib/grn_ecmascript.c"
+#line 2166 "grn_ecmascript.c"
         break;
       case 57: /* unary_expression ::= DECR unary_expression */
-#line 322 "../../groonga/lib/grn_ecmascript.lemon"
+#line 322 "grn_ecmascript.lemon"
 {
   grn_ctx *ctx = efsi->ctx;
   grn_expr *e = (grn_expr *)(efsi->e);
@@ -2183,66 +2183,66 @@ static YYACTIONTYPE yy_reduce(
     grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_DECR, 1);
   }
 }
-#line 2187 "../../groonga/lib/grn_ecmascript.c"
+#line 2187 "grn_ecmascript.c"
         break;
       case 58: /* unary_expression ::= PLUS unary_expression */
-#line 339 "../../groonga/lib/grn_ecmascript.lemon"
+#line 339 "grn_ecmascript.lemon"
 {
   grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_PLUS, 1);
 }
-#line 2194 "../../groonga/lib/grn_ecmascript.c"
+#line 2194 "grn_ecmascript.c"
         break;
       case 59: /* unary_expression ::= MINUS unary_expression */
-#line 342 "../../groonga/lib/grn_ecmascript.lemon"
+#line 342 "grn_ecmascript.lemon"
 {
   grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_MINUS, 1);
 }
-#line 2201 "../../groonga/lib/grn_ecmascript.c"
+#line 2201 "grn_ecmascript.c"
         break;
       case 60: /* unary_expression ::= NOT unary_expression */
-#line 345 "../../groonga/lib/grn_ecmascript.lemon"
+#line 345 "grn_ecmascript.lemon"
 {
   grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_NOT, 1);
 }
-#line 2208 "../../groonga/lib/grn_ecmascript.c"
+#line 2208 "grn_ecmascript.c"
         break;
       case 61: /* unary_expression ::= BITWISE_NOT unary_expression */
-#line 348 "../../groonga/lib/grn_ecmascript.lemon"
+#line 348 "grn_ecmascript.lemon"
 {
   grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_BITWISE_NOT, 1);
 }
-#line 2215 "../../groonga/lib/grn_ecmascript.c"
+#line 2215 "grn_ecmascript.c"
         break;
       case 62: /* unary_expression ::= ADJUST unary_expression */
-#line 351 "../../groonga/lib/grn_ecmascript.lemon"
+#line 351 "grn_ecmascript.lemon"
 {
   grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_ADJUST, 1);
 }
-#line 2222 "../../groonga/lib/grn_ecmascript.c"
+#line 2222 "grn_ecmascript.c"
         break;
       case 63: /* unary_expression ::= EXACT unary_expression */
-#line 354 "../../groonga/lib/grn_ecmascript.lemon"
+#line 354 "grn_ecmascript.lemon"
 {
   grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_EXACT, 1);
 }
-#line 2229 "../../groonga/lib/grn_ecmascript.c"
+#line 2229 "grn_ecmascript.c"
         break;
       case 64: /* unary_expression ::= PARTIAL unary_expression */
-#line 357 "../../groonga/lib/grn_ecmascript.lemon"
+#line 357 "grn_ecmascript.lemon"
 {
   grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_PARTIAL, 1);
 }
-#line 2236 "../../groonga/lib/grn_ecmascript.c"
+#line 2236 "grn_ecmascript.c"
         break;
       case 65: /* unary_expression ::= UNSPLIT unary_expression */
-#line 360 "../../groonga/lib/grn_ecmascript.lemon"
+#line 360 "grn_ecmascript.lemon"
 {
   grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_UNSPLIT, 1);
 }
-#line 2243 "../../groonga/lib/grn_ecmascript.c"
+#line 2243 "grn_ecmascript.c"
         break;
       case 66: /* postfix_expression ::= lefthand_side_expression INCR */
-#line 365 "../../groonga/lib/grn_ecmascript.lemon"
+#line 365 "grn_ecmascript.lemon"
 {
   grn_ctx *ctx = efsi->ctx;
   grn_expr *e = (grn_expr *)(efsi->e);
@@ -2260,10 +2260,10 @@ static YYACTIONTYPE yy_reduce(
     grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_INCR_POST, 1);
   }
 }
-#line 2264 "../../groonga/lib/grn_ecmascript.c"
+#line 2264 "grn_ecmascript.c"
         break;
       case 67: /* postfix_expression ::= lefthand_side_expression DECR */
-#line 382 "../../groonga/lib/grn_ecmascript.lemon"
+#line 382 "grn_ecmascript.lemon"
 {
   grn_ctx *ctx = efsi->ctx;
   grn_expr *e = (grn_expr *)(efsi->e);
@@ -2281,17 +2281,17 @@ static YYACTIONTYPE yy_reduce(
     grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_DECR_POST, 1);
   }
 }
-#line 2285 "../../groonga/lib/grn_ecmascript.c"
+#line 2285 "grn_ecmascript.c"
         break;
       case 68: /* call_expression ::= member_expression arguments */
-#line 403 "../../groonga/lib/grn_ecmascript.lemon"
+#line 403 "grn_ecmascript.lemon"
 {
   grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_CALL, yymsp[0].minor.yy0);
 }
-#line 2292 "../../groonga/lib/grn_ecmascript.c"
+#line 2292 "grn_ecmascript.c"
         break;
       case 69: /* array_literal ::= BRACKETL element_list BRACKETR */
-#line 420 "../../groonga/lib/grn_ecmascript.lemon"
+#line 420 "grn_ecmascript.lemon"
 {
   grn_ctx *ctx = efsi->ctx;
   if (efsi->array_literal) {
@@ -2301,10 +2301,10 @@ static YYACTIONTYPE yy_reduce(
     efsi->array_literal = NULL;
   }
 }
-#line 2305 "../../groonga/lib/grn_ecmascript.c"
+#line 2305 "grn_ecmascript.c"
         break;
       case 70: /* element_list ::= */
-#line 430 "../../groonga/lib/grn_ecmascript.lemon"
+#line 430 "grn_ecmascript.lemon"
 {
   grn_ctx *ctx = efsi->ctx;
 
@@ -2315,10 +2315,10 @@ static YYACTIONTYPE yy_reduce(
         (int)(efsi->str_end - efsi->str), efsi->str);
   }
 }
-#line 2319 "../../groonga/lib/grn_ecmascript.c"
+#line 2319 "grn_ecmascript.c"
         break;
       case 71: /* element_list ::= assignment_expression */
-#line 440 "../../groonga/lib/grn_ecmascript.lemon"
+#line 440 "grn_ecmascript.lemon"
 {
   grn_ctx *ctx = efsi->ctx;
   grn_expr *e = (grn_expr *)(efsi->e);
@@ -2358,10 +2358,10 @@ static YYACTIONTYPE yy_reduce(
     }
   }
 }
-#line 2362 "../../groonga/lib/grn_ecmascript.c"
+#line 2362 "grn_ecmascript.c"
         break;
       case 72: /* object_literal ::= BRACEL property_name_and_value_list BRACER */
-#line 481 "../../groonga/lib/grn_ecmascript.lemon"
+#line 481 "grn_ecmascript.lemon"
 {
   grn_ctx *ctx = efsi->ctx;
   grn_expr_take_obj(ctx, efsi->e, (grn_obj *)(efsi->object_literal));
@@ -2369,10 +2369,10 @@ static YYACTIONTYPE yy_reduce(
                       GRN_OP_PUSH, 1);
   efsi->object_literal = NULL;
 }
-#line 2373 "../../groonga/lib/grn_ecmascript.c"
+#line 2373 "grn_ecmascript.c"
         break;
       case 73: /* property_name_and_value_list ::= */
-#line 489 "../../groonga/lib/grn_ecmascript.lemon"
+#line 489 "grn_ecmascript.lemon"
 {
   grn_ctx *ctx = efsi->ctx;
 
@@ -2385,10 +2385,10 @@ static YYACTIONTYPE yy_reduce(
         (int)(efsi->str_end - efsi->str), efsi->str);
   }
 }
-#line 2389 "../../groonga/lib/grn_ecmascript.c"
+#line 2389 "grn_ecmascript.c"
         break;
       case 74: /* property_name_and_value ::= property_name COLON assignment_expression */
-#line 504 "../../groonga/lib/grn_ecmascript.lemon"
+#line 504 "grn_ecmascript.lemon"
 {
   grn_ctx *ctx = efsi->ctx;
   grn_expr *e = (grn_expr *)(efsi->e);
@@ -2412,8 +2412,13 @@ static YYACTIONTYPE yy_reduce(
                      GRN_TEXT_VALUE(property), GRN_TEXT_LEN(property),
                      (void **)&buf, &added)) {
       if (added) {
-        GRN_OBJ_INIT(buf, value->header.type, 0, value->header.domain);
-        GRN_TEXT_PUT(ctx, buf, GRN_TEXT_VALUE(value), GRN_TEXT_LEN(value));
+        if (value->header.type == GRN_TABLE_HASH_KEY) {
+          GRN_OBJ_INIT(buf, GRN_PTR, 0, GRN_ID_NIL);
+          GRN_PTR_SET(ctx, buf, value);
+        } else {
+          GRN_OBJ_INIT(buf, value->header.type, 0, value->header.domain);
+          GRN_TEXT_PUT(ctx, buf, GRN_TEXT_VALUE(value), GRN_TEXT_LEN(value));
+        }
         grn_expr_dfi_pop(e);
         e->codes_curr -= 3;
       } else {
@@ -2430,61 +2435,61 @@ static YYACTIONTYPE yy_reduce(
     }
   }
 }
-#line 2434 "../../groonga/lib/grn_ecmascript.c"
+#line 2439 "grn_ecmascript.c"
         break;
       case 75: /* member_expression_part ::= BRACKETL expression BRACKETR */
-#line 548 "../../groonga/lib/grn_ecmascript.lemon"
+#line 553 "grn_ecmascript.lemon"
 {
   grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_GET_MEMBER, 2);
 }
-#line 2441 "../../groonga/lib/grn_ecmascript.c"
+#line 2446 "grn_ecmascript.c"
         break;
       case 76: /* arguments ::= PARENL argument_list PARENR */
-#line 553 "../../groonga/lib/grn_ecmascript.lemon"
+#line 558 "grn_ecmascript.lemon"
 { yymsp[-2].minor.yy0 = yymsp[-1].minor.yy0; }
-#line 2446 "../../groonga/lib/grn_ecmascript.c"
+#line 2451 "grn_ecmascript.c"
         break;
       case 77: /* argument_list ::= */
-#line 554 "../../groonga/lib/grn_ecmascript.lemon"
+#line 559 "grn_ecmascript.lemon"
 { yymsp[1].minor.yy0 = 0; }
-#line 2451 "../../groonga/lib/grn_ecmascript.c"
+#line 2456 "grn_ecmascript.c"
         break;
       case 78: /* argument_list ::= assignment_expression */
-#line 555 "../../groonga/lib/grn_ecmascript.lemon"
+#line 560 "grn_ecmascript.lemon"
 { yymsp[0].minor.yy0 = 1; }
-#line 2456 "../../groonga/lib/grn_ecmascript.c"
+#line 2461 "grn_ecmascript.c"
         break;
       case 79: /* argument_list ::= argument_list COMMA assignment_expression */
-#line 556 "../../groonga/lib/grn_ecmascript.lemon"
+#line 561 "grn_ecmascript.lemon"
 { yylhsminor.yy0 = yymsp[-2].minor.yy0 + 1; }
-#line 2461 "../../groonga/lib/grn_ecmascript.c"
+#line 2466 "grn_ecmascript.c"
   yymsp[-2].minor.yy0 = yylhsminor.yy0;
         break;
       case 80: /* output_columns ::= */
-#line 558 "../../groonga/lib/grn_ecmascript.lemon"
+#line 563 "grn_ecmascript.lemon"
 {
   yymsp[1].minor.yy0 = 0;
 }
-#line 2469 "../../groonga/lib/grn_ecmascript.c"
+#line 2474 "grn_ecmascript.c"
         break;
       case 81: /* output_columns ::= output_column */
-#line 561 "../../groonga/lib/grn_ecmascript.lemon"
+#line 566 "grn_ecmascript.lemon"
 {
   yylhsminor.yy0 = yymsp[0].minor.yy0;
 }
-#line 2476 "../../groonga/lib/grn_ecmascript.c"
+#line 2481 "grn_ecmascript.c"
   yymsp[0].minor.yy0 = yylhsminor.yy0;
         break;
       case 82: /* output_columns ::= output_columns COMMA */
-#line 566 "../../groonga/lib/grn_ecmascript.lemon"
+#line 571 "grn_ecmascript.lemon"
 {
   yylhsminor.yy0 = yymsp[-1].minor.yy0;
 }
-#line 2484 "../../groonga/lib/grn_ecmascript.c"
+#line 2489 "grn_ecmascript.c"
   yymsp[-1].minor.yy0 = yylhsminor.yy0;
         break;
       case 83: /* output_columns ::= output_columns COMMA output_column */
-#line 571 "../../groonga/lib/grn_ecmascript.lemon"
+#line 576 "grn_ecmascript.lemon"
 {
   if (yymsp[-2].minor.yy0 == 0) {
     yylhsminor.yy0 = yymsp[0].minor.yy0;
@@ -2497,11 +2502,11 @@ static YYACTIONTYPE yy_reduce(
     yylhsminor.yy0 = 1;
   }
 }
-#line 2501 "../../groonga/lib/grn_ecmascript.c"
+#line 2506 "grn_ecmascript.c"
   yymsp[-2].minor.yy0 = yylhsminor.yy0;
         break;
       case 84: /* output_column ::= STAR */
-#line 584 "../../groonga/lib/grn_ecmascript.lemon"
+#line 589 "grn_ecmascript.lemon"
 {
   grn_ctx *ctx = efsi->ctx;
   grn_obj *expr = efsi->e;
@@ -2552,21 +2557,21 @@ static YYACTIONTYPE yy_reduce(
     yymsp[0].minor.yy0 = 0;
   }
 }
-#line 2556 "../../groonga/lib/grn_ecmascript.c"
+#line 2561 "grn_ecmascript.c"
         break;
       case 85: /* output_column ::= NONEXISTENT_COLUMN */
-#line 634 "../../groonga/lib/grn_ecmascript.lemon"
+#line 639 "grn_ecmascript.lemon"
 {
   yymsp[0].minor.yy0 = 0;
 }
-#line 2563 "../../groonga/lib/grn_ecmascript.c"
+#line 2568 "grn_ecmascript.c"
         break;
       case 86: /* output_column ::= assignment_expression */
-#line 637 "../../groonga/lib/grn_ecmascript.lemon"
+#line 642 "grn_ecmascript.lemon"
 {
   yymsp[0].minor.yy0 = 1;
 }
-#line 2570 "../../groonga/lib/grn_ecmascript.c"
+#line 2575 "grn_ecmascript.c"
         break;
       default:
       /* (90) input ::= query */ yytestcase(yyruleno==90);
@@ -2671,7 +2676,7 @@ static void yy_syntax_error(
   grn_expr_parserCTX_FETCH
 #define TOKEN yyminor
 /************ Begin %syntax_error code ****************************************/
-#line 20 "../../groonga/lib/grn_ecmascript.lemon"
+#line 20 "grn_ecmascript.lemon"
 
   {
     grn_ctx *ctx = efsi->ctx;
@@ -2699,7 +2704,7 @@ static void yy_syntax_error(
     }
     GRN_OBJ_FIN(ctx, &message);
   }
-#line 2703 "../../groonga/lib/grn_ecmascript.c"
+#line 2708 "grn_ecmascript.c"
 /************ End %syntax_error code ******************************************/
   grn_expr_parserARG_STORE /* Suppress warning about unused %extra_argument variable */
   grn_expr_parserCTX_STORE

  Modified: lib/grn_ecmascript.lemon (+7 -2)
===================================================================
--- lib/grn_ecmascript.lemon    2019-05-16 17:02:04 +0900 (285113135)
+++ lib/grn_ecmascript.lemon    2019-05-16 17:10:02 +0900 (4dae33480)
@@ -524,8 +524,13 @@ property_name_and_value ::= property_name COLON assignment_expression. {
                      GRN_TEXT_VALUE(property), GRN_TEXT_LEN(property),
                      (void **)&buf, &added)) {
       if (added) {
-        GRN_OBJ_INIT(buf, value->header.type, 0, value->header.domain);
-        GRN_TEXT_PUT(ctx, buf, GRN_TEXT_VALUE(value), GRN_TEXT_LEN(value));
+        if (value->header.type == GRN_TABLE_HASH_KEY) {
+          GRN_OBJ_INIT(buf, GRN_PTR, 0, GRN_ID_NIL);
+          GRN_PTR_SET(ctx, buf, value);
+        } else {
+          GRN_OBJ_INIT(buf, value->header.type, 0, value->header.domain);
+          GRN_TEXT_PUT(ctx, buf, GRN_TEXT_VALUE(value), GRN_TEXT_LEN(value));
+        }
         grn_expr_dfi_pop(e);
         e->codes_curr -= 3;
       } else {

  Modified: lib/output.c (+35 -0)
===================================================================
--- lib/output.c    2019-05-16 17:02:04 +0900 (e4c482644)
+++ lib/output.c    2019-05-16 17:10:02 +0900 (907106eaa)
@@ -1897,6 +1897,34 @@ grn_output_result_set(grn_ctx *ctx,
   grn_output_result_set_close(ctx, outbuf, output_type, result_set, format);
 }
 
+static void
+grn_output_table_hash_key(grn_ctx *ctx,
+                          grn_obj *outbuf,
+                          grn_content_type output_type,
+                          grn_obj *obj,
+                          grn_obj_format *format)
+{
+  const unsigned int n_elements = grn_table_size(ctx, obj);
+  grn_obj key;
+  GRN_OBJ_INIT(&key, GRN_BULK, GRN_OBJ_DO_SHALLOW_COPY, obj->header.domain);
+  grn_output_map_open(ctx, outbuf, output_type, "object", n_elements);
+  GRN_TABLE_EACH_BEGIN(ctx, obj, cursor, id) {
+    void *raw_key;
+    const int key_size = grn_table_cursor_get_key(ctx, cursor, &raw_key);
+    GRN_TEXT_SET(ctx, &key, raw_key, key_size);
+    grn_output_obj(ctx, outbuf, output_type, &key, format);
+    void *raw_value;
+    const int value_size = grn_table_cursor_get_value(ctx, cursor, &raw_value);
+    if (value_size == 0) {
+      grn_output_null(ctx, outbuf, output_type);
+    } else {
+      grn_obj *value = raw_value;
+      grn_output_obj(ctx, outbuf, output_type, value, format);
+    }
+  } GRN_TABLE_EACH_END(ctx, cursor);
+  grn_output_map_close(ctx, outbuf, output_type);
+}
+
 void
 grn_output_obj(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type,
                grn_obj *obj, grn_obj_format *format)
@@ -1920,6 +1948,13 @@ grn_output_obj(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type,
     grn_output_pvector(ctx, outbuf, output_type, obj, format);
     break;
   case GRN_TABLE_HASH_KEY :
+    if (obj->header.flags & GRN_HASH_TINY) {
+      grn_output_table_hash_key(ctx, outbuf, output_type, obj, format);
+    } else {
+      /* Deprecated. Use grn_output_result_set() directly. */
+      grn_output_result_set(ctx, outbuf, output_type, obj, format);
+    }
+    break;
   case GRN_TABLE_PAT_KEY :
   case GRN_TABLE_DAT_KEY :
   case GRN_TABLE_NO_KEY :

  Modified: lib/proc/proc_snippet.c (+57 -8)
===================================================================
--- lib/proc/proc_snippet.c    2019-05-16 17:02:04 +0900 (10052b39b)
+++ lib/proc/proc_snippet.c    2019-05-16 17:10:02 +0900 (75ad44fe9)
@@ -27,6 +27,7 @@
 
 static grn_obj *
 snippet_exec(grn_ctx *ctx, grn_obj *snip, grn_obj *text,
+             grn_obj *default_return_value,
              grn_user_data *user_data,
              const char *prefix, int prefix_length,
              const char *suffix, int suffix_length)
@@ -47,15 +48,19 @@ snippet_exec(grn_ctx *ctx, grn_obj *snip, grn_obj *text,
     return NULL;
   }
 
+  if (n_results == 0) {
+    if (default_return_value) {
+      return default_return_value;
+    } else {
+      return grn_plugin_proc_alloc(ctx, user_data, GRN_DB_VOID, 0);
+    }
+  }
+
   snippets = grn_plugin_proc_alloc(ctx, user_data, GRN_DB_SHORT_TEXT, GRN_OBJ_VECTOR);
   if (!snippets) {
     return NULL;
   }
 
-  if (n_results == 0) {
-    return snippets;
-  }
-
   GRN_TEXT_INIT(&snippet_buffer, 0);
   grn_bulk_space(ctx, &snippet_buffer,
                  prefix_length + max_tagged_length + suffix_length);
@@ -112,6 +117,7 @@ func_snippet(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
     const char *default_close_tag = NULL;
     int default_close_tag_length = 0;
     int n_args_without_option = nargs;
+    grn_obj *default_return_value = NULL;
 
     if (end_arg->header.type == GRN_TABLE_HASH_KEY) {
       grn_obj *options = end_arg;
@@ -160,6 +166,12 @@ func_snippet(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
         } else if (key_size == 17 && !memcmp(key, "default_close_tag", 17)) {
           default_close_tag = GRN_TEXT_VALUE(value);
           default_close_tag_length = GRN_TEXT_LEN(value);
+        } else if (key_size == 7 && !memcmp(key, "default", 7)) {
+          if (value->header.type == GRN_PTR) {
+            default_return_value = GRN_PTR_VALUE(value);
+          } else {
+            default_return_value = value;
+          }
         } else {
           GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
                            "invalid option name: <%.*s>",
@@ -221,7 +233,9 @@ func_snippet(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
                                  NULL, 0);
         }
       }
-      snippets = snippet_exec(ctx, snip, text, user_data,
+      snippets = snippet_exec(ctx, snip, text,
+                              default_return_value,
+                              user_data,
                               prefix, prefix_length,
                               suffix, suffix_length);
     }
@@ -250,13 +264,13 @@ func_snippet_html(grn_ctx *ctx, int nargs, grn_obj **args,
 {
   grn_obj *snippets = NULL;
 
-  /* TODO: support parameters */
-  if (nargs == 1) {
+  if (nargs > 0) {
     grn_obj *text = args[0];
     grn_obj *expression = NULL;
     grn_obj *condition_ptr = NULL;
     grn_obj *condition = NULL;
     grn_obj *snip = NULL;
+    grn_obj *default_return_value = NULL;
     int flags = GRN_SNIP_SKIP_LEADING_SPACES;
     unsigned int width = 200;
     unsigned int max_n_results = 3;
@@ -264,6 +278,38 @@ func_snippet_html(grn_ctx *ctx, int nargs, grn_obj **args,
     const char *close_tag = "</span>";
     grn_snip_mapping *mapping = GRN_SNIP_MAPPING_HTML_ESCAPE;
 
+    if (nargs > 1 && args[1]->header.type == GRN_TABLE_HASH_KEY) {
+      grn_obj *options = args[1];
+      void *key;
+      uint32_t key_size;
+      grn_obj *value;
+
+      GRN_HASH_EACH_BEGIN(ctx, (grn_hash *)options, cursor, id) {
+        grn_raw_string option_name;
+
+        grn_hash_cursor_get_key_value(ctx, cursor,
+                                      &key, &key_size,
+                                      (void **)&value);
+        option_name.value = key;
+        option_name.length = key_size;
+        if (GRN_RAW_STRING_EQUAL_CSTRING(option_name, "default")) {
+          if (value->header.type == GRN_PTR) {
+            default_return_value = GRN_PTR_VALUE(value);
+          } else {
+            default_return_value = value;
+          }
+        } else {
+          GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
+                           "snippet_html(): invalid option name: <%.*s>",
+                           key_size, (char *)key);
+          break;
+        }
+      } GRN_HASH_EACH_END(ctx, cursor);
+      if (ctx->rc != GRN_SUCCESS) {
+        goto exit;
+      }
+    }
+
     grn_proc_get_info(ctx, user_data, NULL, NULL, &expression);
     condition_ptr = grn_expr_get_var(ctx, expression,
                                      GRN_SELECT_INTERNAL_VAR_CONDITION,
@@ -301,10 +347,13 @@ func_snippet_html(grn_ctx *ctx, int nargs, grn_obj **args,
     }
 
     if (snip) {
-      snippets = snippet_exec(ctx, snip, text, user_data, NULL, 0, NULL, 0);
+      snippets = snippet_exec(ctx, snip, text,
+                              default_return_value,
+                              user_data, NULL, 0, NULL, 0);
     }
   }
 
+exit :
   if (!snippets) {
     snippets = grn_plugin_proc_alloc(ctx, user_data, GRN_DB_VOID, 0);
   }

  Copied: test/command/suite/select/function/snippet_html/none/empty_array.expected (+1 -1) 93%
===================================================================
--- test/command/suite/select/function/snippet_html/none.expected    2019-05-16 17:02:04 +0900 (721e507cf)
+++ test/command/suite/select/function/snippet_html/none/empty_array.expected    2019-05-16 17:10:02 +0900 (3be1ae6bd)
@@ -12,7 +12,7 @@ load --table Documents
 ["Groonga", "Groonga can be used with MySQL."]
 ]
 [[0,0.0,0.0],1]
-select Documents   --match_columns content --query 'MySQL'   --output_columns '_key, snippet_html(_key)'
+select Documents   --match_columns content --query 'MySQL'   --output_columns '_key, snippet_html(_key, {"default": []})'
 [
   [
     0,

  Copied: test/command/suite/select/function/snippet_html/none/empty_array.test (+1 -1) 87%
===================================================================
--- test/command/suite/select/function/snippet_html/none.test    2019-05-16 17:02:04 +0900 (721ec73a4)
+++ test/command/suite/select/function/snippet_html/none/empty_array.test    2019-05-16 17:10:02 +0900 (90f7e68aa)
@@ -12,4 +12,4 @@ load --table Documents
 
 select Documents \
   --match_columns content --query 'MySQL' \
-  --output_columns '_key, snippet_html(_key)'
+  --output_columns '_key, snippet_html(_key, {"default": []})'

  Copied: test/command/suite/select/function/snippet_html/none/empty_object.expected (+3 -4) 90%
===================================================================
--- test/command/suite/select/function/snippet_html/none.expected    2019-05-16 17:02:04 +0900 (721e507cf)
+++ test/command/suite/select/function/snippet_html/none/empty_object.expected    2019-05-16 17:10:02 +0900 (d7cc37608)
@@ -12,7 +12,7 @@ load --table Documents
 ["Groonga", "Groonga can be used with MySQL."]
 ]
 [[0,0.0,0.0],1]
-select Documents   --match_columns content --query 'MySQL'   --output_columns '_key, snippet_html(_key)'
+select Documents   --match_columns content --query 'MySQL'   --output_columns '_key, snippet_html(_key, {"default": {}})'
 [
   [
     0,
@@ -36,9 +36,8 @@ select Documents   --match_columns content --query 'MySQL'   --output_columns '_
       ],
       [
         "Groonga",
-        [
-
-        ]
+        {
+        }
       ]
     ]
   ]

  Copied: test/command/suite/select/function/snippet_html/none/empty_object.test (+1 -1) 87%
===================================================================
--- test/command/suite/select/function/snippet_html/none.test    2019-05-16 17:02:04 +0900 (721ec73a4)
+++ test/command/suite/select/function/snippet_html/none/empty_object.test    2019-05-16 17:10:02 +0900 (560d9e786)
@@ -12,4 +12,4 @@ load --table Documents
 
 select Documents \
   --match_columns content --query 'MySQL' \
-  --output_columns '_key, snippet_html(_key)'
+  --output_columns '_key, snippet_html(_key, {"default": {}})'

  Copied: test/command/suite/select/function/snippet_html/none/empty_string.expected (+2 -4) 84%
===================================================================
--- test/command/suite/select/function/snippet_html/none.expected    2019-05-16 17:02:04 +0900 (721e507cf)
+++ test/command/suite/select/function/snippet_html/none/empty_string.expected    2019-05-16 17:10:02 +0900 (62fc5c8b1)
@@ -12,7 +12,7 @@ load --table Documents
 ["Groonga", "Groonga can be used with MySQL."]
 ]
 [[0,0.0,0.0],1]
-select Documents   --match_columns content --query 'MySQL'   --output_columns '_key, snippet_html(_key)'
+select Documents   --match_columns content   --query 'MySQL'   --output_columns '_key, snippet_html(_key, {"default": ""})'
 [
   [
     0,
@@ -36,9 +36,7 @@ select Documents   --match_columns content --query 'MySQL'   --output_columns '_
       ],
       [
         "Groonga",
-        [
-
-        ]
+        ""
       ]
     ]
   ]

  Copied: test/command/suite/select/function/snippet_html/none/empty_string.test (+3 -2) 77%
===================================================================
--- test/command/suite/select/function/snippet_html/none.test    2019-05-16 17:02:04 +0900 (721ec73a4)
+++ test/command/suite/select/function/snippet_html/none/empty_string.test    2019-05-16 17:10:02 +0900 (213fe493c)
@@ -11,5 +11,6 @@ load --table Documents
 ]
 
 select Documents \
-  --match_columns content --query 'MySQL' \
-  --output_columns '_key, snippet_html(_key)'
+  --match_columns content \
+  --query 'MySQL' \
+  --output_columns '_key, snippet_html(_key, {"default": ""})'

  Copied: test/command/suite/select/function/snippet_html/none/invalid_option.expected (+9 -7) 72%
===================================================================
--- test/command/suite/select/function/snippet_html/none.expected    2019-05-16 17:02:04 +0900 (721e507cf)
+++ test/command/suite/select/function/snippet_html/none/invalid_option.expected    2019-05-16 17:10:02 +0900 (bbd233f27)
@@ -12,12 +12,15 @@ load --table Documents
 ["Groonga", "Groonga can be used with MySQL."]
 ]
 [[0,0.0,0.0],1]
-select Documents   --match_columns content --query 'MySQL'   --output_columns '_key, snippet_html(_key)'
+select Documents   --match_columns content --query 'MySQL'   --output_columns '_key, snippet_html(_key, {"nonexistent": {}})'
 [
   [
-    0,
-    0.0,
-    0.0
+    [
+      -22,
+      0.0,
+      0.0
+    ],
+    "snippet_html(): invalid option name: <nonexistent>"
   ],
   [
     [
@@ -36,10 +39,9 @@ select Documents   --match_columns content --query 'MySQL'   --output_columns '_
       ],
       [
         "Groonga",
-        [
-
-        ]
+        "snippet_html(): invalid option name: <nonexistent>"
       ]
     ]
   ]
 ]
+#|e| snippet_html(): invalid option name: <nonexistent>

  Copied: test/command/suite/select/function/snippet_html/none/invalid_option.test (+1 -1) 86%
===================================================================
--- test/command/suite/select/function/snippet_html/none.test    2019-05-16 17:02:04 +0900 (721ec73a4)
+++ test/command/suite/select/function/snippet_html/none/invalid_option.test    2019-05-16 17:10:02 +0900 (5f8ffb9fc)
@@ -12,4 +12,4 @@ load --table Documents
 
 select Documents \
   --match_columns content --query 'MySQL' \
-  --output_columns '_key, snippet_html(_key)'
+  --output_columns '_key, snippet_html(_key, {"nonexistent": {}})'

  Copied: test/command/suite/select/function/snippet_html/none/no_option.expected (+1 -3) 97%
===================================================================
--- test/command/suite/select/function/snippet_html/none.expected    2019-05-16 17:02:04 +0900 (721e507cf)
+++ test/command/suite/select/function/snippet_html/none/no_option.expected    2019-05-16 17:10:02 +0900 (7654328bb)
@@ -36,9 +36,7 @@ select Documents   --match_columns content --query 'MySQL'   --output_columns '_
       ],
       [
         "Groonga",
-        [
-
-        ]
+        null
       ]
     ]
   ]

  Copied: test/command/suite/select/function/snippet_html/none/no_option.test (+0 -0) 100%
===================================================================

  Renamed: test/command/suite/select/function/snippet_html/none/object.expected (+5 -4) 83%
===================================================================
--- test/command/suite/select/function/snippet_html/none.expected    2019-05-16 17:02:04 +0900 (721e507cf)
+++ test/command/suite/select/function/snippet_html/none/object.expected    2019-05-16 17:10:02 +0900 (0497ff938)
@@ -12,7 +12,7 @@ load --table Documents
 ["Groonga", "Groonga can be used with MySQL."]
 ]
 [[0,0.0,0.0],1]
-select Documents   --match_columns content --query 'MySQL'   --output_columns '_key, snippet_html(_key)'
+select Documents   --match_columns content --query 'MySQL'   --output_columns '_key, snippet_html(_key, {"default": {"number": 29, "string": "meat"}})'
 [
   [
     0,
@@ -36,9 +36,10 @@ select Documents   --match_columns content --query 'MySQL'   --output_columns '_
       ],
       [
         "Groonga",
-        [
-
-        ]
+        {
+          "number": 29,
+          "string": "meat"
+        }
       ]
     ]
   ]

  Renamed: test/command/suite/select/function/snippet_html/none/object.test (+1 -1) 82%
===================================================================
--- test/command/suite/select/function/snippet_html/none.test    2019-05-16 17:02:04 +0900 (721ec73a4)
+++ test/command/suite/select/function/snippet_html/none/object.test    2019-05-16 17:10:02 +0900 (2fe2e4c59)
@@ -12,4 +12,4 @@ load --table Documents
 
 select Documents \
   --match_columns content --query 'MySQL' \
-  --output_columns '_key, snippet_html(_key)'
+  --output_columns '_key, snippet_html(_key, {"default": {"number": 29, "string": "meat"}})'
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.osdn.me/mailman/archives/groonga-commit/attachments/20190516/0b522af9/attachment-0001.html>


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