[Groonga-commit] groonga/groonga [master] don't accept negative offset and limit with GRN_CURSOR_PREFIX. #377

Back to archive index

null+****@clear***** null+****@clear*****
2010年 8月 13日 (金) 16:05:05 JST


Kouhei Sutou	2010-08-13 07:05:05 +0000 (Fri, 13 Aug 2010)

  New Revision: 13b0f4e672695de220af2921900c2d00f8d2d22a

  Log:
    don't accept negative offset and limit with GRN_CURSOR_PREFIX. #377

  Modified files:
    groonga.h
    lib/db.c
    test/unit/core/test-table-patricia-trie-cursor.c

  Modified: groonga.h (+7 -1)
===================================================================
--- groonga.h    2010-08-13 06:32:12 +0000 (a9a65dc)
+++ groonga.h    2010-08-13 07:05:05 +0000 (9417b29)
@@ -726,10 +726,16 @@ typedef grn_obj grn_table_cursor;
  *         GRN_CURSOR_BY_ID/GRN_CURSOR_BY_KEY/GRN_CURSOR_PREFIXの3フラグは、
  *         同時に指定することができない。
  * @offset: 該当する範囲のレコードのうち、
-            (0ベースで)offset番目からレコードを取り出す。
+ *          (0ベースで)offset番目からレコードを取り出す。
+ *
+ *         GRN_CURSOR_PREFIXを指定したときは負の数を指定する
+ *         ことはできない。
  * @limit: 該当する範囲のレコードのうち、limit件のみを取り出す。
  *         -1が指定された場合は、全件が指定されたものとみなす。
  *
+ *         GRN_CURSOR_PREFIXを指定したときは-1より小さい負の
+ *         数を指定することはできない。
+ *
  * tableに登録されているレコードを順番に取り出すためのカーソルを生成して返す。
  **/
 GRN_API grn_table_cursor *grn_table_cursor_open(grn_ctx *ctx, grn_obj *table,

  Modified: lib/db.c (+25 -3)
===================================================================
--- lib/db.c    2010-08-13 06:32:12 +0000 (23638ef)
+++ lib/db.c    2010-08-13 07:05:05 +0000 (e347dd2)
@@ -1776,12 +1776,34 @@ grn_table_cursor_open(grn_ctx *ctx, grn_obj *table,
 {
   grn_rc rc;
   grn_table_cursor *tc = NULL;
+  unsigned int table_size;
   if (!table) { return tc; }
   GRN_API_ENTER;
-  rc = grn_normalize_offset_and_limit(ctx, grn_table_size(ctx, table), &offset, &limit);
-  if (rc) {
-    ERR(rc, "grn_normalize_offset_and_limit failed");
+  table_size = grn_table_size(ctx, table);
+  if (flags & GRN_CURSOR_PREFIX) {
+    if (offset < 0) {
+      ERR(GRN_TOO_SMALL_OFFSET,
+          "can't use negative offset with GRN_CURSOR_PREFIX: %d", offset);
+    } else if (offset != 0 && offset >= table_size) {
+      ERR(GRN_TOO_LARGE_OFFSET,
+          "offset is rather than table size: offset:%d, table_size:%d",
+          offset, table_size);
+    } else {
+      if (limit < -1) {
+        ERR(GRN_TOO_SMALL_LIMIT,
+            "can't use small limit rather than -1 with GRN_CURSOR_PREFIX: %d",
+            limit);
+      } else if (limit == -1) {
+        limit = table_size;
+      }
+    }
   } else {
+    rc = grn_normalize_offset_and_limit(ctx, table_size, &offset, &limit);
+    if (rc) {
+      ERR(rc, "grn_normalize_offset_and_limit failed");
+    }
+  }
+  if (!ctx->rc) {
     switch (table->header.type) {
     case GRN_DB :
       tc = (grn_table_cursor *)grn_pat_cursor_open(ctx, ((grn_db *)table)->keys,

  Modified: test/unit/core/test-table-patricia-trie-cursor.c (+49 -0)
===================================================================
--- test/unit/core/test-table-patricia-trie-cursor.c    2010-08-13 06:32:12 +0000 (f5bb1a5)
+++ test/unit/core/test-table-patricia-trie-cursor.c    2010-08-13 07:05:05 +0000 (32d2562)
@@ -38,6 +38,8 @@
   cut_take_string(POINT(latitude_hours, latitude_minutes, latitude_seconds, \
                         longitude_hours, longitude_minutes, longitude_seconds))
 
+void data_prefix_error(void);
+void test_prefix_error(gpointer data);
 void data_prefix_short_text(void);
 void test_prefix_short_text(gpointer data);
 void data_prefix_geo_point(void);
@@ -179,6 +181,53 @@ create_geo_point_table(const gchar *data)
 }
 
 void
+data_prefix_error(void)
+{
+#define ADD_DATA(label, rc, message, offset, limit)             \
+  gcut_add_datum(label,                                         \
+                 "rc", G_TYPE_UINT, rc,                         \
+                 "message", G_TYPE_STRING, message,             \
+                 "offset", G_TYPE_INT, offset,                  \
+                 "limit", G_TYPE_INT, limit,                    \
+                 NULL)
+
+  ADD_DATA("negative offset",
+           GRN_TOO_SMALL_OFFSET,
+           "can't use negative offset with GRN_CURSOR_PREFIX: -1",
+           -1, -1);
+  ADD_DATA("large offset",
+           GRN_TOO_LARGE_OFFSET,
+           "offset is rather than table size: offset:100, table_size:8",
+           100, -1);
+  ADD_DATA("negative limit",
+           GRN_TOO_SMALL_LIMIT,
+           "can't use small limit rather than -1 with GRN_CURSOR_PREFIX: -2",
+           0, -2);
+
+#undef ADD_DATA
+}
+
+void
+test_prefix_error(gpointer data)
+{
+  const gchar *min = "ab";
+  int offset, limit;
+
+  create_short_text_table();
+
+  offset = gcut_data_get_int(data, "offset");
+  limit = gcut_data_get_int(data, "limit");
+  cursor = grn_table_cursor_open(context, table,
+                                 min, strlen(min),
+                                 NULL, 0,
+                                 offset, limit,
+                                 GRN_CURSOR_PREFIX);
+  grn_test_assert_error(gcut_data_get_uint(data, "rc"),
+                        gcut_data_get_string(data, "message"),
+                        context);
+}
+
+void
 data_prefix_short_text(void)
 {
 #define ADD_DATA(label, expected, min, offset, limit, flags)    \




Groonga-commit メーリングリストの案内
Back to archive index