groonga 0.0.6 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. data/AUTHORS +4 -0
  2. data/NEWS.ja.rdoc +10 -0
  3. data/NEWS.rdoc +10 -0
  4. data/README.ja.rdoc +9 -3
  5. data/README.rdoc +10 -4
  6. data/Rakefile +1 -1
  7. data/TUTORIAL.ja.rdoc +3 -6
  8. data/example/bookmark.rb +1 -1
  9. data/example/search/config.ru +52 -28
  10. data/ext/rb-grn-column.c +24 -18
  11. data/ext/rb-grn-context.c +165 -17
  12. data/ext/rb-grn-encoding.c +37 -0
  13. data/ext/rb-grn-expression.c +286 -51
  14. data/ext/rb-grn-object.c +27 -8
  15. data/ext/rb-grn-operation.c +128 -22
  16. data/ext/rb-grn-patricia-trie.c +62 -0
  17. data/ext/rb-grn-snippet.c +7 -17
  18. data/ext/rb-grn-table.c +101 -31
  19. data/ext/rb-grn-utils.c +87 -22
  20. data/ext/rb-grn-variable-size-column.c +1 -1
  21. data/ext/rb-grn.h +27 -4
  22. data/ext/rb-groonga.c +12 -2
  23. data/extconf.rb +2 -1
  24. data/html/index.html +2 -2
  25. data/lib/groonga.rb +1 -0
  26. data/lib/groonga/expression-builder.rb +47 -12
  27. data/lib/groonga/patricia-trie.rb +40 -0
  28. data/lib/groonga/record.rb +17 -13
  29. data/misc/grnop2ruby.rb +49 -0
  30. data/pkg-config.rb +1 -1
  31. data/test-unit/lib/test/unit/assertions.rb +5 -2
  32. data/test-unit/lib/test/unit/autorunner.rb +19 -4
  33. data/test-unit/lib/test/unit/collector/load.rb +3 -1
  34. data/test-unit/lib/test/unit/color-scheme.rb +5 -1
  35. data/test-unit/lib/test/unit/error.rb +7 -5
  36. data/test-unit/lib/test/unit/runner/tap.rb +8 -0
  37. data/test-unit/lib/test/unit/ui/console/testrunner.rb +63 -8
  38. data/test-unit/lib/test/unit/ui/tap/testrunner.rb +92 -0
  39. data/test-unit/test/collector/test-load.rb +1 -5
  40. data/test-unit/test/test-color-scheme.rb +4 -0
  41. data/test/groonga-test-utils.rb +10 -0
  42. data/test/run-test.rb +5 -1
  43. data/test/test-column.rb +58 -0
  44. data/test/test-database.rb +8 -1
  45. data/test/test-expression.rb +48 -6
  46. data/test/test-hash.rb +7 -0
  47. data/test/test-patricia-trie.rb +39 -0
  48. data/test/test-record.rb +2 -2
  49. data/test/test-remote.rb +52 -0
  50. data/test/test-schema.rb +1 -1
  51. data/test/test-table-select-normalize.rb +48 -0
  52. data/test/test-table-select.rb +101 -0
  53. data/test/test-table.rb +0 -9
  54. data/test/test-variable-size-column.rb +28 -0
  55. metadata +16 -5
@@ -94,32 +94,39 @@ rb_grn_bulk_to_ruby_object_by_range_id (grn_ctx *context, grn_obj *bulk,
94
94
 
95
95
  switch (range_id) {
96
96
  case GRN_DB_VOID:
97
- *rb_value = rb_str_new(GRN_BULK_HEAD(bulk), GRN_BULK_VSIZE(bulk));
97
+ *rb_value = rb_str_new(GRN_TEXT_VALUE(bulk), GRN_TEXT_LEN(bulk));
98
98
  break;
99
99
  case GRN_DB_INT32:
100
- *rb_value = INT2NUM(*((int *)GRN_BULK_HEAD(bulk)));
100
+ *rb_value = INT2NUM(GRN_INT32_VALUE(bulk));
101
101
  break;
102
102
  case GRN_DB_UINT32:
103
- *rb_value = UINT2NUM(*((int *)GRN_BULK_HEAD(bulk)));
103
+ *rb_value = UINT2NUM(GRN_UINT32_VALUE(bulk));
104
104
  break;
105
105
  case GRN_DB_INT64:
106
- *rb_value = LL2NUM(*((long long *)GRN_BULK_HEAD(bulk)));
106
+ *rb_value = LL2NUM(GRN_INT64_VALUE(bulk));
107
+ break;
108
+ case GRN_DB_UINT64:
109
+ *rb_value = ULL2NUM(GRN_UINT64_VALUE(bulk));
107
110
  break;
108
111
  case GRN_DB_FLOAT:
109
- *rb_value = rb_float_new(*((double *)GRN_BULK_HEAD(bulk)));
112
+ *rb_value = rb_float_new(GRN_FLOAT_VALUE(bulk));
110
113
  break;
111
114
  case GRN_DB_TIME:
112
115
  {
113
- int64_t time_value = GRN_TIME_VALUE(bulk);
116
+ int64_t time_value, sec, usec;
117
+
118
+ time_value = GRN_TIME_VALUE(bulk);
119
+ GRN_TIME_UNPACK(time_value, sec, usec);
114
120
  *rb_value = rb_funcall(rb_cTime, rb_intern("at"), 2,
115
- LL2NUM(time_value / RB_GRN_USEC_PER_SEC),
116
- LL2NUM(time_value % RB_GRN_USEC_PER_SEC));
121
+ LL2NUM(sec), LL2NUM(usec));
117
122
  }
118
123
  break;
119
124
  case GRN_DB_SHORT_TEXT:
120
125
  case GRN_DB_TEXT:
121
126
  case GRN_DB_LONG_TEXT:
122
- *rb_value = rb_str_new(GRN_BULK_HEAD(bulk), GRN_BULK_VSIZE(bulk));
127
+ *rb_value = rb_grn_context_rb_string_new(context,
128
+ GRN_TEXT_VALUE(bulk),
129
+ GRN_TEXT_LEN(bulk));
123
130
  break;
124
131
  default:
125
132
  success = RB_GRN_FALSE;
@@ -185,7 +192,9 @@ rb_grn_bulk_to_ruby_object (grn_ctx *context, grn_obj *bulk,
185
192
  related_object, &rb_value))
186
193
  return rb_value;
187
194
 
188
- return rb_str_new(GRN_BULK_HEAD(bulk), GRN_BULK_VSIZE(bulk));
195
+ return rb_grn_context_rb_string_new(context,
196
+ GRN_BULK_HEAD(bulk),
197
+ GRN_BULK_VSIZE(bulk));
189
198
  }
190
199
 
191
200
  grn_obj *
@@ -200,6 +209,11 @@ rb_grn_bulk_from_ruby_object (VALUE object, grn_ctx *context, grn_obj *bulk)
200
209
  grn_id id_value;
201
210
  grn_obj_flags flags = 0;
202
211
 
212
+ if (bulk && bulk->header.domain == GRN_DB_TIME)
213
+ return rb_grn_bulk_from_ruby_object_with_type(
214
+ object, context, bulk, bulk->header.domain,
215
+ grn_ctx_at(context, bulk->header.domain));
216
+
203
217
  switch (TYPE(object)) {
204
218
  case T_NIL:
205
219
  string = NULL;
@@ -217,8 +231,14 @@ rb_grn_bulk_from_ruby_object (VALUE object, grn_ctx *context, grn_obj *bulk)
217
231
  break;
218
232
  case T_BIGNUM:
219
233
  int64_value = NUM2LL(object);
220
- string = (const char *)&int64_value;
221
- size = sizeof(int64_value);
234
+ if (int64_value <= INT32_MAX) {
235
+ int32_value = int64_value;
236
+ string = (const char *)&int32_value;
237
+ size = sizeof(int32_value);
238
+ } else {
239
+ string = (const char *)&int64_value;
240
+ size = sizeof(int64_value);
241
+ }
222
242
  break;
223
243
  case T_FLOAT:
224
244
  double_value = NUM2DBL(object);
@@ -231,7 +251,7 @@ rb_grn_bulk_from_ruby_object (VALUE object, grn_ctx *context, grn_obj *bulk)
231
251
 
232
252
  sec = rb_funcall(object, rb_intern("to_i"), 0);
233
253
  usec = rb_funcall(object, rb_intern("usec"), 0);
234
- time_value = NUM2LL(sec) * RB_GRN_USEC_PER_SEC + NUM2LL(usec);
254
+ time_value = GRN_TIME_PACK(NUM2LL(sec), NUM2LL(usec));
235
255
  string = (const char *)&time_value;
236
256
  size = sizeof(time_value);
237
257
  } else if (RVAL2CBOOL(rb_obj_is_kind_of(object, rb_cGrnObject))) {
@@ -273,10 +293,11 @@ rb_grn_bulk_from_ruby_object_with_type (VALUE object, grn_ctx *context,
273
293
  int32_t int32_value;
274
294
  uint32_t uint32_value;
275
295
  int64_t int64_value;
296
+ uint64_t uint64_value;
276
297
  int64_t time_value;
277
298
  double double_value;
278
299
  grn_id range;
279
- VALUE rb_type;
300
+ VALUE rb_type_object;
280
301
  grn_obj_flags flags = 0;
281
302
 
282
303
  switch (type_id) {
@@ -295,6 +316,11 @@ rb_grn_bulk_from_ruby_object_with_type (VALUE object, grn_ctx *context,
295
316
  string = (const char *)&int64_value;
296
317
  size = sizeof(int64_value);
297
318
  break;
319
+ case GRN_DB_UINT64:
320
+ uint64_value = NUM2ULL(object);
321
+ string = (const char *)&uint64_value;
322
+ size = sizeof(uint64_value);
323
+ break;
298
324
  case GRN_DB_FLOAT:
299
325
  double_value = NUM2DBL(object);
300
326
  string = (const char *)&double_value;
@@ -302,11 +328,31 @@ rb_grn_bulk_from_ruby_object_with_type (VALUE object, grn_ctx *context,
302
328
  break;
303
329
  case GRN_DB_TIME:
304
330
  {
305
- VALUE sec, usec;
306
-
307
- sec = rb_funcall(object, rb_intern("to_i"), 0);
308
- usec = rb_funcall(object, rb_intern("usec"), 0);
309
- time_value = NUM2LL(sec) * RB_GRN_USEC_PER_SEC + NUM2LL(usec);
331
+ VALUE rb_sec, rb_usec;
332
+ int64_t sec;
333
+ int32_t usec;
334
+
335
+ switch (TYPE(object)) {
336
+ case T_FIXNUM:
337
+ case T_BIGNUM:
338
+ sec = NUM2LL(object);
339
+ usec = 0;
340
+ break;
341
+ case T_FLOAT:
342
+ rb_sec = rb_funcall(object, rb_intern("to_i"), 0);
343
+ rb_usec = rb_funcall(object, rb_intern("remainder"), 1,
344
+ INT2NUM(1));
345
+
346
+ sec = NUM2LL(rb_sec);
347
+ usec = (int32_t)(NUM2DBL(rb_usec) * 1000000);
348
+ break;
349
+ default:
350
+ sec = NUM2LL(rb_funcall(object, rb_intern("to_i"), 0));
351
+ usec = NUM2INT(rb_funcall(object, rb_intern("usec"), 0));
352
+ break;
353
+ }
354
+
355
+ time_value = GRN_TIME_PACK(sec, usec);
310
356
  }
311
357
  string = (const char *)&time_value;
312
358
  size = sizeof(time_value);
@@ -329,10 +375,10 @@ rb_grn_bulk_from_ruby_object_with_type (VALUE object, grn_ctx *context,
329
375
  case GRN_DB_BIGRAM:
330
376
  case GRN_DB_TRIGRAM:
331
377
  case GRN_DB_MECAB:
332
- rb_type = GRNOBJECT2RVAL(Qnil, context, type, RB_GRN_FALSE);
378
+ rb_type_object = GRNOBJECT2RVAL(Qnil, context, type, RB_GRN_FALSE);
333
379
  rb_raise(rb_eArgError,
334
380
  "unbulkable type: %s",
335
- rb_grn_inspect(rb_type));
381
+ rb_grn_inspect(rb_type_object));
336
382
  break;
337
383
  default:
338
384
  return RVAL2GRNBULK(object, context, bulk);
@@ -479,6 +525,25 @@ rb_grn_value_to_ruby_object (grn_ctx *context,
479
525
  value->header.domain = grn_obj_id(context, range);
480
526
  return GRNBULK2RVAL(context, value, related_object);
481
527
  break;
528
+ case GRN_UVECTOR:
529
+ {
530
+ VALUE rb_value, rb_range = Qnil;
531
+ grn_id *uvector, *uvector_end;
532
+
533
+ rb_value = rb_ary_new();
534
+ if (range)
535
+ rb_range = GRNTABLE2RVAL(context, range, RB_GRN_FALSE);
536
+ uvector = (grn_id *)GRN_BULK_HEAD(value);
537
+ uvector_end = (grn_id *)GRN_BULK_CURR(value);
538
+ for (; uvector < uvector_end; uvector++) {
539
+ VALUE record = Qnil;
540
+ if (*uvector != GRN_ID_NIL)
541
+ record = rb_grn_record_new(rb_range, *uvector, Qnil);
542
+ rb_ary_push(rb_value, record);
543
+ }
544
+ return rb_value;
545
+ }
546
+ break;
482
547
  default:
483
548
  rb_raise(rb_eGrnError,
484
549
  "unsupported value type: 0x%0x: %s",
@@ -616,7 +681,7 @@ rb_grn_obj_from_ruby_object (VALUE rb_object, grn_ctx *context, grn_obj **_obj)
616
681
 
617
682
  sec = rb_funcall(rb_object, rb_intern("to_i"), 0);
618
683
  usec = rb_funcall(rb_object, rb_intern("usec"), 0);
619
- time_value = NUM2LL(sec) * RB_GRN_USEC_PER_SEC + NUM2LL(usec);
684
+ time_value = GRN_TIME_PACK(NUM2LL(sec), NUM2LL(usec));
620
685
  grn_obj_reinit(context, obj, GRN_DB_TIME, 0);
621
686
  GRN_TIME_SET(context, obj, time_value);
622
687
  } else if (RVAL2CBOOL(rb_obj_is_kind_of(rb_object, rb_cGrnObject))) {
@@ -23,7 +23,7 @@
23
23
  VALUE rb_cGrnVariableSizeColumn;
24
24
 
25
25
  /*
26
- * Document-class: Groonga::FixSizeColumn < Groonga::Column
26
+ * Document-class: Groonga::VariableSizeColumn < Groonga::Column
27
27
  *
28
28
  * 可変長データ用のカラム。
29
29
  */
@@ -21,6 +21,10 @@
21
21
 
22
22
  #include <ruby.h>
23
23
 
24
+ #ifdef HAVE_RUBY_ENCODING_H
25
+ # include <ruby/encoding.h>
26
+ #endif
27
+
24
28
  #include <groonga.h>
25
29
 
26
30
  #if defined(__cplusplus)
@@ -65,7 +69,7 @@ RB_GRN_BEGIN_DECLS
65
69
 
66
70
  #define RB_GRN_MAJOR_VERSION 0
67
71
  #define RB_GRN_MINOR_VERSION 0
68
- #define RB_GRN_MICRO_VERSION 6
72
+ #define RB_GRN_MICRO_VERSION 7
69
73
 
70
74
  typedef int rb_grn_boolean;
71
75
  #define RB_GRN_FALSE (0)
@@ -75,8 +79,6 @@ typedef int rb_grn_boolean;
75
79
 
76
80
  #include <stdint.h>
77
81
 
78
- #define RB_GRN_USEC_PER_SEC 1000000
79
-
80
82
  #define RB_GRN_OBJECT(object) ((RbGrnObject *)(object))
81
83
  #define RB_GRN_TABLE(object) ((RbGrnTable *)(object))
82
84
  #define RB_GRN_TABLE_KEY_SUPPORT(object) ((RbGrnTableKeySupport *)(object))
@@ -91,7 +93,7 @@ typedef void (*RbGrnUnbindFunction) (void *object);
91
93
  typedef struct _RbGrnContext RbGrnContext;
92
94
  struct _RbGrnContext
93
95
  {
94
- grn_ctx context;
96
+ grn_ctx *context;
95
97
  };
96
98
 
97
99
  typedef struct _RbGrnObject RbGrnObject;
@@ -156,6 +158,8 @@ struct _RbGrnExpression
156
158
  grn_obj *value;
157
159
  };
158
160
 
161
+ RB_GRN_VAR rb_grn_boolean rb_grn_exited;
162
+
159
163
  RB_GRN_VAR VALUE rb_eGrnError;
160
164
  RB_GRN_VAR VALUE rb_cGrnObject;
161
165
  RB_GRN_VAR VALUE rb_mGrnEncodingSupport;
@@ -225,6 +229,7 @@ const char *rb_grn_rc_to_message (grn_rc rc);
225
229
  void rb_grn_rc_check (grn_rc rc,
226
230
  VALUE related_object);
227
231
 
232
+ void rb_grn_context_fin (grn_ctx *context);
228
233
  grn_ctx *rb_grn_context_ensure (VALUE *context);
229
234
  VALUE rb_grn_context_get_default (void);
230
235
  VALUE rb_grn_context_to_exception (grn_ctx *context,
@@ -475,13 +480,26 @@ VALUE rb_grn_column_expression_builder_build
475
480
  #define RVAL2GRNVARIABLE(object, context) \
476
481
  (rb_grn_variable_from_ruby_object(object, context))
477
482
 
483
+ #define GRNSNIPPET2RVAL(context, snippet, owner) \
484
+ (rb_grn_snippet_to_ruby_object(context, snippet, owner))
485
+ #define RVAL2GRNSNIPPET(snippet) \
486
+ (rb_grn_snippet_from_ruby_object(snippet))
487
+
478
488
 
479
489
  grn_encoding rb_grn_encoding_from_ruby_object (VALUE object,
480
490
  grn_ctx *context);
481
491
  VALUE rb_grn_encoding_to_ruby_object (grn_encoding encoding);
492
+ #ifdef HAVE_RUBY_ENCODING_H
493
+ rb_encoding *rb_grn_encoding_to_ruby_encoding (grn_encoding encoding);
494
+ #endif
482
495
 
483
496
  grn_ctx *rb_grn_context_from_ruby_object (VALUE object);
484
497
  VALUE rb_grn_context_to_ruby_object (grn_ctx *context);
498
+ VALUE rb_grn_context_rb_string_new (grn_ctx *context,
499
+ const char *string,
500
+ long length);
501
+ VALUE rb_grn_context_rb_string_encode (grn_ctx *context,
502
+ VALUE rb_string);
485
503
 
486
504
  grn_obj *rb_grn_object_from_ruby_object (VALUE object,
487
505
  grn_ctx **context);
@@ -592,6 +610,11 @@ VALUE rb_grn_obj_to_ruby_object (VALUE klass,
592
610
  grn_obj *obj,
593
611
  VALUE related_object);
594
612
 
613
+ grn_snip *rb_grn_snippet_from_ruby_object (VALUE rb_snippet);
614
+ VALUE rb_grn_snippet_to_ruby_object (grn_ctx *context,
615
+ grn_snip *snippet,
616
+ rb_grn_boolean owner);
617
+
595
618
  RB_GRN_END_DECLS
596
619
 
597
620
  #endif
@@ -18,12 +18,22 @@
18
18
 
19
19
  #include "rb-grn.h"
20
20
 
21
+ rb_grn_boolean rb_grn_exited = RB_GRN_FALSE;
21
22
  extern grn_ctx grn_gctx;
22
23
 
23
24
  static void
24
- finish_groonga (void)
25
+ finish_groonga (VALUE data)
25
26
  {
27
+ grn_ctx *context = grn_gctx.next;
28
+
29
+ debug("finish\n");
30
+ while (context && context != &grn_gctx) {
31
+ rb_grn_context_fin(context);
32
+ context = context->next;
33
+ }
26
34
  grn_fin();
35
+ debug("finish: done\n");
36
+ rb_grn_exited = RB_GRN_TRUE;
27
37
  }
28
38
 
29
39
  void
@@ -68,7 +78,7 @@ Init_groonga (void)
68
78
  rb_grn_init_exception(mGrn);
69
79
 
70
80
  rb_grn_rc_check(grn_init(), Qnil);
71
- atexit(finish_groonga);
81
+ rb_set_end_proc(finish_groonga, Qnil);
72
82
 
73
83
  rb_grn_init_utils(mGrn);
74
84
  rb_grn_init_encoding(mGrn);
data/extconf.rb CHANGED
@@ -36,7 +36,7 @@ package_name = "groonga"
36
36
  module_name = "groonga"
37
37
  ext_dir_name = "ext"
38
38
  src_dir = File.join(File.expand_path(File.dirname(__FILE__)), ext_dir_name)
39
- major, minor, micro = 0, 1, 1
39
+ major, minor, micro = 0, 1, 4
40
40
 
41
41
  def local_groonga_base_dir
42
42
  File.join(File.dirname(__FILE__), "vendor")
@@ -143,6 +143,7 @@ have_header("ruby/st.h") unless have_macro("HAVE_RUBY_ST_H", "ruby.h")
143
143
  have_func("rb_errinfo", "ruby.h")
144
144
  have_type("enum ruby_value_type", "ruby.h")
145
145
 
146
+ $INSTALLFILES ||= []
146
147
  $INSTALLFILES << ["../lib/**/*.rb", "$(RUBYLIBDIR)", "../lib"]
147
148
 
148
149
  create_makefile(module_name, src_dir)
@@ -42,7 +42,7 @@
42
42
 
43
43
  <h3>Ruby/groongaの最新リリース</h3>
44
44
  <p>
45
- 2009-07-31にリリースされた0.0.6が最新です。
45
+ 2009-10-02にリリースされた0.0.7が最新です。
46
46
  </p>
47
47
 
48
48
  <h3 id="install-ruby-groonga">Ruby/groongaのインストール</h3>
@@ -79,7 +79,7 @@
79
79
 
80
80
  <h3>ActiveGroongaの最新リリース</h3>
81
81
  <p>
82
- 2009-07-31にリリースされた0.0.6が最新です。
82
+ 2009-10-02にリリースされた0.0.7が最新です。
83
83
  </p>
84
84
 
85
85
  <h3 id="install-active-groonga">ActiveGroongaのインストール</h3>
@@ -69,4 +69,5 @@ module Groonga
69
69
  end
70
70
  end
71
71
 
72
+ require 'groonga/patricia-trie'
72
73
  require 'groonga/schema'
@@ -18,6 +18,8 @@
18
18
  module Groonga
19
19
  module ExpressionBuildable
20
20
  attr_reader :table
21
+ attr_accessor :query
22
+
21
23
  def initialize(*args)
22
24
  @table = nil
23
25
  @name = nil
@@ -26,14 +28,18 @@ module Groonga
26
28
  end
27
29
 
28
30
  def build
29
- expression = Expression.new(:table => @table,
30
- :name => @name,
31
- :query => @query,
32
- :default_column => @default_column)
31
+ expression = Expression.new(:name => @name)
33
32
  variable = expression.define_variable(:domain => @table)
34
33
 
35
34
  builder = nil
36
- builder = yield(self) if block_given?
35
+ builder = match(@query) if @query
36
+ if block_given?
37
+ if builder
38
+ builder &= yield(self)
39
+ else
40
+ builder = yield(self)
41
+ end
42
+ end
37
43
  if builder.nil? or builder == self
38
44
  expression.append_constant(1)
39
45
  expression.append_constant(1)
@@ -99,7 +105,7 @@ module Groonga
99
105
  def build(expression, variable)
100
106
  expression.append_object(variable)
101
107
  expression.append_constant(@column_name)
102
- expression.append_operation(Groonga::Operation::OBJECT_GET_VALUE, 2)
108
+ expression.append_operation(Groonga::Operation::GET_VALUE, 2)
103
109
  expression.append_constant(@value)
104
110
  expression.append_operation(@operation, 2)
105
111
  end
@@ -140,6 +146,18 @@ module Groonga
140
146
  super(Groonga::Operation::GREATER_EQUAL, column_name, value)
141
147
  end
142
148
  end
149
+
150
+ class SubExpressionBuilder < ExpressionBuilder
151
+ def initialize(query, options)
152
+ super()
153
+ @query = query
154
+ @options = options
155
+ end
156
+
157
+ def build(expression, variable)
158
+ expression.parse(@query, @options)
159
+ end
160
+ end
143
161
  end
144
162
 
145
163
  class RecordExpressionBuilder
@@ -160,6 +178,16 @@ module Groonga
160
178
  end
161
179
  ColumnExpressionBuilder.new(column, nil, nil)
162
180
  end
181
+
182
+ def match(query, options_or_default_column={})
183
+ if options_or_default_column.is_a?(String)
184
+ options = {:default_column => options_or_default_column}
185
+ else
186
+ options = options_or_default_column
187
+ end
188
+ default_options = {:parser => :table}
189
+ SubExpressionBuilder.new(query, default_options.merge(options))
190
+ end
163
191
  end
164
192
 
165
193
  class ColumnExpressionBuilder
@@ -176,27 +204,34 @@ module Groonga
176
204
  end
177
205
 
178
206
  def ==(other)
179
- EqualExpressionBuilder.new(@column.local_name, normalize(other))
207
+ EqualExpressionBuilder.new(@default_column, normalize(other))
180
208
  end
181
209
 
182
210
  def =~(other)
183
- MatchExpressionBuilder.new(@column.local_name, normalize(other))
211
+ MatchExpressionBuilder.new(@default_column, normalize(other))
184
212
  end
185
213
 
186
214
  def <(other)
187
- LessExpressionBuilder.new(@column.local_name, normalize(other))
215
+ LessExpressionBuilder.new(@default_column, normalize(other))
188
216
  end
189
217
 
190
218
  def <=(other)
191
- LessEqualExpressionBuilder.new(@column.local_name, normalize(other))
219
+ LessEqualExpressionBuilder.new(@default_column, normalize(other))
192
220
  end
193
221
 
194
222
  def >(other)
195
- GreaterExpressionBuilder.new(@column.local_name, normalize(other))
223
+ GreaterExpressionBuilder.new(@default_column, normalize(other))
196
224
  end
197
225
 
198
226
  def >=(other)
199
- GreaterEqualExpressionBuilder.new(@column.local_name, normalize(other))
227
+ GreaterEqualExpressionBuilder.new(@default_column, normalize(other))
228
+ end
229
+
230
+ def match(query, options={})
231
+ default_options = {:parser => :table}
232
+ ensure_options = {:default_column => @default_column}
233
+ options = default_options.merge(options).merge(ensure_options)
234
+ SubExpressionBuilder.new(query, options)
200
235
  end
201
236
 
202
237
  private