summaryrefslogtreecommitdiff
path: root/storage/mroonga/vendor/groonga/lib/db.c
diff options
context:
space:
mode:
Diffstat (limited to 'storage/mroonga/vendor/groonga/lib/db.c')
-rw-r--r--storage/mroonga/vendor/groonga/lib/db.c439
1 files changed, 362 insertions, 77 deletions
diff --git a/storage/mroonga/vendor/groonga/lib/db.c b/storage/mroonga/vendor/groonga/lib/db.c
index 357df82e314..e213812d926 100644
--- a/storage/mroonga/vendor/groonga/lib/db.c
+++ b/storage/mroonga/vendor/groonga/lib/db.c
@@ -85,6 +85,33 @@ inline static void
grn_obj_get_range_info(grn_ctx *ctx, grn_obj *obj,
grn_id *range_id, grn_obj_flags *range_flags);
+
+static char grn_db_key[GRN_ENV_BUFFER_SIZE];
+static uint64_t grn_index_sparsity = 10;
+
+void
+grn_db_init_from_env(void)
+{
+ grn_getenv("GRN_DB_KEY",
+ grn_db_key,
+ GRN_ENV_BUFFER_SIZE);
+
+ {
+ char grn_index_sparsity_env[GRN_ENV_BUFFER_SIZE];
+ grn_getenv("GRN_INDEX_SPARSITY",
+ grn_index_sparsity_env,
+ GRN_ENV_BUFFER_SIZE);
+ if (grn_index_sparsity_env[0]) {
+ uint64_t sparsity;
+ errno = 0;
+ sparsity = strtoull(grn_index_sparsity_env, NULL, 0);
+ if (errno == 0) {
+ grn_index_sparsity = sparsity;
+ }
+ }
+ }
+}
+
inline static void
gen_pathname(const char *path, char *buffer, int fno)
{
@@ -155,15 +182,11 @@ grn_db_create(grn_ctx *ctx, const char *path, grn_db_create_optarg *optarg)
if ((s = GRN_MALLOC(sizeof(grn_db)))) {
grn_bool use_default_db_key = GRN_TRUE;
grn_bool use_pat_as_db_keys = GRN_FALSE;
- char grn_db_key_env[GRN_ENV_BUFFER_SIZE];
- grn_getenv("GRN_DB_KEY",
- grn_db_key_env,
- GRN_ENV_BUFFER_SIZE);
- if (grn_db_key_env[0]) {
- if (!strcmp(grn_db_key_env, "pat")) {
+ if (grn_db_key[0]) {
+ if (!strcmp(grn_db_key, "pat")) {
use_default_db_key = GRN_FALSE;
use_pat_as_db_keys = GRN_TRUE;
- } else if (!strcmp(grn_db_key_env, "dat")) {
+ } else if (!strcmp(grn_db_key, "dat")) {
use_default_db_key = GRN_FALSE;
}
}
@@ -245,6 +268,10 @@ grn_db_open(grn_ctx *ctx, const char *path)
break;
default :
s->keys = NULL;
+ if (ctx->rc == GRN_SUCCESS) {
+ ERR(GRN_INVALID_ARGUMENT,
+ "[db][open] invalid keys table's type: %#x", type);
+ }
break;
}
if (s->keys) {
@@ -870,6 +897,7 @@ grn_table_create_with_max_n_subrecs(grn_ctx *ctx, const char *name,
path = buffer;
} else {
ERR(GRN_INVALID_ARGUMENT, "path not assigned for persistent table");
+ grn_obj_delete_by_id(ctx, db, id, GRN_TRUE);
return NULL;
}
} else {
@@ -878,10 +906,12 @@ grn_table_create_with_max_n_subrecs(grn_ctx *ctx, const char *name,
} else {
if (path) {
ERR(GRN_INVALID_ARGUMENT, "path assigned for temporary table");
+ grn_obj_delete_by_id(ctx, db, id, GRN_TRUE);
return NULL;
}
if (GRN_DB_PERSISTENT_P(db) && name && name_size) {
ERR(GRN_INVALID_ARGUMENT, "name assigned for temporary table");
+ grn_obj_delete_by_id(ctx, db, id, GRN_TRUE);
return NULL;
}
}
@@ -2758,6 +2788,181 @@ grn_table_next(grn_ctx *ctx, grn_obj *table, grn_id id)
GRN_API_RETURN(r);
}
+static grn_rc
+grn_accessor_resolve_one_index_column(grn_ctx *ctx, grn_accessor *accessor,
+ grn_obj *current_res, grn_obj **next_res,
+ grn_search_optarg *optarg)
+{
+ grn_rc rc = GRN_SUCCESS;
+ grn_obj *column = NULL;
+ grn_id next_res_domain_id = GRN_ID_NIL;
+
+ {
+ grn_obj *index;
+ grn_obj source_ids;
+ unsigned int i, n_ids;
+
+ index = accessor->obj;
+ next_res_domain_id = index->header.domain;
+
+ GRN_UINT32_INIT(&source_ids, GRN_OBJ_VECTOR);
+ grn_obj_get_info(ctx, index, GRN_INFO_SOURCE, &source_ids);
+ n_ids = GRN_BULK_VSIZE(&source_ids) / sizeof(grn_id);
+ for (i = 0; i < n_ids; i++) {
+ grn_id source_id;
+ grn_obj *source;
+
+ source_id = GRN_UINT32_VALUE_AT(&source_ids, i);
+ source = grn_ctx_at(ctx, source_id);
+ if (DB_OBJ(source)->range == next_res_domain_id) {
+ column = source;
+ break;
+ }
+ grn_obj_unlink(ctx, source);
+ }
+
+ if (!column) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ }
+
+ {
+ grn_rc rc;
+ grn_obj *next_res_domain = grn_ctx_at(ctx, next_res_domain_id);
+ *next_res = grn_table_create(ctx, NULL, 0, NULL,
+ GRN_TABLE_HASH_KEY|GRN_OBJ_WITH_SUBREC,
+ next_res_domain, NULL);
+ rc = ctx->rc;
+ grn_obj_unlink(ctx, next_res_domain);
+ if (!*next_res) {
+ return rc;
+ }
+ }
+
+ {
+ grn_obj_flags column_value_flags = 0;
+ grn_obj column_value;
+ grn_ii_posting add_posting;
+ grn_id *tid;
+ grn_rset_recinfo *recinfo;
+
+ if (column->header.type == GRN_COLUMN_VAR_SIZE) {
+ column_value_flags |= GRN_OBJ_VECTOR;
+ }
+ GRN_VALUE_FIX_SIZE_INIT(&column_value,
+ column_value_flags,
+ next_res_domain_id);
+
+ add_posting.sid = 0;
+ add_posting.pos = 0;
+ add_posting.weight = 0;
+
+ GRN_HASH_EACH(ctx, (grn_hash *)current_res, id, &tid, NULL, &recinfo, {
+ int i;
+ int n_elements;
+
+ add_posting.weight = recinfo->score - 1;
+
+ GRN_BULK_REWIND(&column_value);
+ grn_obj_get_value(ctx, column, *tid, &column_value);
+
+ n_elements = GRN_BULK_VSIZE(&column_value) / sizeof(grn_id);
+ for (i = 0; i < n_elements; i++) {
+ add_posting.rid = GRN_RECORD_VALUE_AT(&column_value, i);
+ rc = grn_ii_posting_add(ctx,
+ &add_posting,
+ (grn_hash *)*next_res,
+ GRN_OP_OR);
+ if (rc != GRN_SUCCESS) {
+ break;
+ }
+ }
+ if (rc != GRN_SUCCESS) {
+ break;
+ }
+ });
+
+ GRN_OBJ_FIN(ctx, &column_value);
+ }
+
+ if (rc != GRN_SUCCESS) {
+ grn_obj_unlink(ctx, *next_res);
+ }
+
+ return rc;
+}
+
+static grn_rc
+grn_accessor_resolve_one_data_column(grn_ctx *ctx, grn_accessor *accessor,
+ grn_obj *current_res, grn_obj **next_res,
+ grn_search_optarg *optarg)
+{
+ grn_rc rc = GRN_SUCCESS;
+ grn_obj *index = NULL;
+ grn_operator index_op = GRN_OP_MATCH;
+ grn_id next_res_domain_id = GRN_ID_NIL;
+
+ if (grn_column_index(ctx, accessor->obj, index_op, &index, 1, NULL) == 0) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ next_res_domain_id = DB_OBJ(index)->range;
+
+ {
+ grn_rc rc;
+ grn_obj *next_res_domain = grn_ctx_at(ctx, next_res_domain_id);
+ *next_res = grn_table_create(ctx, NULL, 0, NULL,
+ GRN_TABLE_HASH_KEY|GRN_OBJ_WITH_SUBREC,
+ next_res_domain, NULL);
+ rc = ctx->rc;
+ grn_obj_unlink(ctx, next_res_domain);
+ if (!*next_res) {
+ return rc;
+ }
+ }
+
+ {
+ grn_id *tid;
+ grn_rset_recinfo *recinfo;
+
+ GRN_HASH_EACH(ctx, (grn_hash *)current_res, id, &tid, NULL, &recinfo, {
+ grn_ii *ii = (grn_ii *)index;
+ grn_ii_cursor *ii_cursor;
+ grn_ii_posting *posting;
+
+ ii_cursor = grn_ii_cursor_open(ctx, ii, *tid,
+ GRN_ID_NIL, GRN_ID_MAX,
+ ii->n_elements,
+ 0);
+ if (!ii_cursor) {
+ continue;
+ }
+
+ while ((posting = grn_ii_cursor_next(ctx, ii_cursor))) {
+ grn_ii_posting add_posting = *posting;
+ add_posting.weight += recinfo->score - 1;
+ rc = grn_ii_posting_add(ctx,
+ &add_posting,
+ (grn_hash *)*next_res,
+ GRN_OP_OR);
+ if (rc != GRN_SUCCESS) {
+ break;
+ }
+ }
+ grn_ii_cursor_close(ctx, ii_cursor);
+
+ if (rc != GRN_SUCCESS) {
+ break;
+ }
+ });
+ }
+
+ if (rc != GRN_SUCCESS) {
+ grn_obj_unlink(ctx, *next_res);
+ }
+
+ return rc;
+}
+
grn_rc
grn_accessor_resolve(grn_ctx *ctx, grn_obj *accessor, int deep,
grn_obj *base_res, grn_obj **res,
@@ -2780,69 +2985,28 @@ grn_accessor_resolve(grn_ctx *ctx, grn_obj *accessor, int deep,
}
for (i = n_accessors; i > 0; i--) {
- grn_obj *index;
- grn_operator index_op = GRN_OP_MATCH;
+ grn_obj *next_res = NULL;
a = (grn_accessor *)GRN_PTR_VALUE_AT(&accessor_stack, i - 1);
- if (grn_column_index(ctx, a->obj, index_op, &index, 1, NULL) == 0) {
- rc = GRN_INVALID_ARGUMENT;
- break;
+ if (a->obj->header.type == GRN_COLUMN_INDEX) {
+ rc = grn_accessor_resolve_one_index_column(ctx, a,
+ current_res, &next_res,
+ optarg);
+ } else {
+ rc = grn_accessor_resolve_one_data_column(ctx, a,
+ current_res, &next_res,
+ optarg);
}
- {
- grn_id *tid;
- grn_obj *next_res;
- grn_rset_recinfo *recinfo;
- {
- grn_obj *range = grn_ctx_at(ctx, DB_OBJ(index)->range);
- next_res = grn_table_create(ctx, NULL, 0, NULL,
- GRN_TABLE_HASH_KEY|GRN_OBJ_WITH_SUBREC,
- range, NULL);
- rc = ctx->rc;
- grn_obj_unlink(ctx, range);
- if (!next_res) {
- if (current_res != base_res) {
- grn_obj_unlink(ctx, current_res);
- }
- break;
- }
- }
- GRN_HASH_EACH(ctx, (grn_hash *)current_res, id, &tid, NULL, &recinfo, {
- grn_ii *ii = (grn_ii *)index;
- grn_ii_cursor *ii_cursor;
- grn_ii_posting *posting;
-
- ii_cursor = grn_ii_cursor_open(ctx, ii, *tid,
- GRN_ID_NIL, GRN_ID_MAX,
- ii->n_elements,
- 0);
- if (!ii_cursor) {
- continue;
- }
-
- while ((posting = grn_ii_cursor_next(ctx, ii_cursor))) {
- grn_ii_posting add_posting = *posting;
- add_posting.weight += recinfo->score - 1;
- grn_ii_posting_add(ctx,
- &add_posting,
- (grn_hash *)next_res,
- GRN_OP_OR);
- }
- grn_ii_cursor_close(ctx, ii_cursor);
+ if (current_res != base_res) {
+ grn_obj_unlink(ctx, current_res);
+ }
- if (rc != GRN_SUCCESS) {
- break;
- }
- });
- if (current_res != base_res) {
- grn_obj_unlink(ctx, current_res);
- }
- if (rc != GRN_SUCCESS) {
- grn_obj_unlink(ctx, next_res);
- break;
- }
- current_res = next_res;
+ if (rc != GRN_SUCCESS) {
+ break;
}
+
+ current_res = next_res;
}
if (rc == GRN_SUCCESS && current_res != base_res) {
@@ -6846,7 +7010,7 @@ grn_obj_get_value(grn_ctx *ctx, grn_obj *obj, grn_id id, grn_obj *value)
}
switch (value->header.type) {
case GRN_VOID :
- GRN_TEXT_INIT(value, 0);
+ grn_obj_reinit(ctx, value, GRN_DB_TEXT, 0);
break;
case GRN_BULK :
case GRN_VECTOR :
@@ -7225,18 +7389,7 @@ build_index(grn_ctx *ctx, grn_obj *obj)
}
}
if (use_grn_ii_build) {
- uint64_t sparsity = 10;
- char grn_index_sparsity_env[GRN_ENV_BUFFER_SIZE];
- grn_getenv("GRN_INDEX_SPARSITY",
- grn_index_sparsity_env,
- GRN_ENV_BUFFER_SIZE);
- if (grn_index_sparsity_env[0]) {
- uint64_t v;
- errno = 0;
- v = strtoull(grn_index_sparsity_env, NULL, 0);
- if (!errno) { sparsity = v; }
- }
- grn_ii_build(ctx, ii, sparsity);
+ grn_ii_build(ctx, ii, grn_index_sparsity);
} else {
grn_table_cursor *tc;
if ((tc = grn_table_cursor_open(ctx, target, NULL, 0, NULL, 0,
@@ -9528,6 +9681,7 @@ grn_obj_clear_lock(grn_ctx *ctx, grn_obj *obj)
case GRN_TABLE_DAT_KEY:
case GRN_TABLE_NO_KEY:
grn_obj_clear_lock(ctx, tbl);
+ break;
}
} else {
if (ctx->rc != GRN_SUCCESS) {
@@ -9580,6 +9734,132 @@ grn_obj_is_locked(grn_ctx *ctx, grn_obj *obj)
GRN_API_RETURN(res);
}
+grn_rc
+grn_obj_flush(grn_ctx *ctx, grn_obj *obj)
+{
+ grn_rc rc = GRN_SUCCESS;
+ GRN_API_ENTER;
+ switch (obj->header.type) {
+ case GRN_DB :
+ {
+ grn_db *db = (grn_db *)obj;
+ rc = grn_obj_flush(ctx, db->keys);
+ if (rc == GRN_SUCCESS) {
+ rc = grn_obj_flush(ctx, (grn_obj *)(db->specs));
+ }
+ }
+ break;
+ case GRN_TABLE_DAT_KEY :
+ rc = grn_dat_flush(ctx, (grn_dat *)obj);
+ break;
+ case GRN_COLUMN_INDEX :
+ rc = grn_ii_flush(ctx, (grn_ii *)obj);
+ break;
+ default :
+ rc = grn_io_flush(ctx, grn_obj_io(obj));
+ break;
+ }
+ GRN_API_RETURN(rc);
+}
+
+grn_rc
+grn_obj_flush_recursive(grn_ctx *ctx, grn_obj *obj)
+{
+ grn_rc rc = GRN_SUCCESS;
+
+ GRN_API_ENTER;
+ switch (obj->header.type) {
+ case GRN_DB :
+ {
+ grn_table_cursor *cursor;
+ grn_id id;
+
+ cursor = grn_table_cursor_open(ctx, obj, NULL, 0, NULL, 0, 0, -1, 0);
+ if (!cursor) {
+ GRN_API_RETURN(ctx->rc);
+ }
+
+ while ((id = grn_table_cursor_next_inline(ctx, cursor)) != GRN_ID_NIL) {
+ grn_obj *table = grn_ctx_at(ctx, id);
+ rc = GRN_SUCCESS;
+ if (table) {
+ switch (table->header.type) {
+ case GRN_TABLE_HASH_KEY :
+ case GRN_TABLE_PAT_KEY:
+ case GRN_TABLE_DAT_KEY:
+ case GRN_TABLE_NO_KEY:
+ rc = grn_obj_flush_recursive(ctx, table);
+ break;
+ }
+ } else {
+ if (ctx->rc != GRN_SUCCESS) {
+ ERRCLR(ctx);
+ }
+ }
+ if (rc != GRN_SUCCESS) {
+ break;
+ }
+ }
+ grn_table_cursor_close(ctx, cursor);
+ }
+ if (rc == GRN_SUCCESS) {
+ rc = grn_obj_flush(ctx, obj);
+ }
+ break;
+ case GRN_TABLE_NO_KEY :
+ case GRN_TABLE_HASH_KEY :
+ case GRN_TABLE_PAT_KEY :
+ case GRN_TABLE_DAT_KEY :
+ {
+ grn_hash *columns;
+ columns = grn_hash_create(ctx, NULL, sizeof(grn_id), 0,
+ GRN_OBJ_TABLE_HASH_KEY|GRN_HASH_TINY);
+ if (!columns) {
+ GRN_API_RETURN(ctx->rc);
+ }
+
+ if (grn_table_columns(ctx, obj, "", 0, (grn_obj *)columns) > 0) {
+ grn_id *key;
+ GRN_HASH_EACH(ctx, columns, id, &key, NULL, NULL, {
+ grn_obj *column = grn_ctx_at(ctx, *key);
+ if (column) {
+ rc = grn_obj_flush(ctx, column);
+ if (rc != GRN_SUCCESS) {
+ break;
+ }
+ }
+ });
+ }
+ grn_hash_close(ctx, columns);
+ }
+
+ if (rc == GRN_SUCCESS) {
+ rc = grn_obj_flush(ctx, obj);
+ }
+ break;
+ case GRN_COLUMN_FIX_SIZE :
+ case GRN_COLUMN_VAR_SIZE :
+ case GRN_COLUMN_INDEX :
+ rc = grn_obj_flush(ctx, obj);
+ break;
+ default :
+ {
+ grn_obj inspected;
+ GRN_TEXT_INIT(&inspected, 0);
+ grn_inspect(ctx, &inspected, obj);
+ ERR(GRN_INVALID_ARGUMENT,
+ "[flush] object must be DB, table or column: <%.*s>",
+ (int)GRN_TEXT_LEN(&inspected),
+ GRN_TEXT_VALUE(&inspected));
+ rc = ctx->rc;
+ GRN_OBJ_FIN(ctx, &inspected);
+ }
+ break;
+ }
+
+ GRN_API_RETURN(rc);
+}
+
grn_obj *
grn_obj_db(grn_ctx *ctx, grn_obj *obj)
{
@@ -11181,6 +11461,11 @@ grn_table_sort_key_from_str(grn_ctx *ctx, const char *str, unsigned int str_size
const char *p = str;
const char **tokbuf;
grn_table_sort_key *keys = NULL, *k = NULL;
+
+ if (str_size == 0) {
+ return NULL;
+ }
+
if ((keys = grn_table_sort_key_from_str_geo(ctx, str, str_size, table, nkeys))) {
return keys;
}