diff options
-rw-r--r-- | dist/api_data.py | 8 | ||||
-rw-r--r-- | src/config/config_def.c | 12 | ||||
-rw-r--r-- | src/cursor/cur_index.c | 49 | ||||
-rw-r--r-- | src/include/schema.h | 3 | ||||
-rw-r--r-- | src/schema/schema_list.c | 9 | ||||
-rw-r--r-- | src/schema/schema_open.c | 18 |
6 files changed, 83 insertions, 16 deletions
diff --git a/dist/api_data.py b/dist/api_data.py index 9ac313f0292..2a4083183e2 100644 --- a/dist/api_data.py +++ b/dist/api_data.py @@ -20,6 +20,10 @@ class Config: common_meta = [ Config('app_metadata', '', r''' application-owned metadata for this object'''), + Config('collator', 'none', r''' + configure custom collation for keys. Permitted values are + \c "none" or a custom collator name created with + WT_CONNECTION::add_collator'''), Config('columns', '', r''' list of the column names. Comma-separated list of the form <code>(column[,...])</code>. For tables, the number of entries @@ -148,10 +152,6 @@ file_config = format_meta + [ applications which can rely on decompression to fail if a block has been corrupted''', choices=['on', 'off', 'uncompressed']), - Config('collator', 'none', r''' - configure custom collation for keys. Permitted values are - \c "none" or a custom collator name created with - WT_CONNECTION::add_collator'''), Config('dictionary', '0', r''' the maximum number of unique values remembered in the Btree row-store leaf page value dictionary; see diff --git a/src/config/config_def.c b/src/config/config_def.c index fa876495195..26017f4bac1 100644 --- a/src/config/config_def.c +++ b/src/config/config_def.c @@ -4,6 +4,7 @@ static const WT_CONFIG_CHECK confchk_colgroup_meta[] = { { "app_metadata", "string", NULL, NULL }, + { "collator", "string", NULL, NULL }, { "columns", "list", NULL, NULL }, { "source", "string", NULL, NULL }, { "type", "string", NULL, NULL }, @@ -170,6 +171,7 @@ static const WT_CONFIG_CHECK confchk_file_meta[] = { static const WT_CONFIG_CHECK confchk_index_meta[] = { { "app_metadata", "string", NULL, NULL }, + { "collator", "string", NULL, NULL }, { "columns", "list", NULL, NULL }, { "extractor", "string", NULL, NULL }, { "immutable", "boolean", NULL, NULL }, @@ -314,6 +316,7 @@ static const WT_CONFIG_CHECK confchk_session_verify[] = { static const WT_CONFIG_CHECK confchk_table_meta[] = { { "app_metadata", "string", NULL, NULL }, { "colgroups", "list", NULL, NULL }, + { "collator", "string", NULL, NULL }, { "columns", "list", NULL, NULL }, { "key_format", "format", NULL, NULL }, { "value_format", "format", NULL, NULL }, @@ -543,7 +546,7 @@ static const WT_CONFIG_CHECK confchk_wiredtiger_open_usercfg[] = { static const WT_CONFIG_ENTRY config_entries[] = { { "colgroup.meta", - "app_metadata=,columns=,source=,type=file", + "app_metadata=,collator=,columns=,source=,type=file", confchk_colgroup_meta }, { "connection.add_collator", @@ -616,8 +619,8 @@ static const WT_CONFIG_ENTRY config_entries[] = { confchk_file_meta }, { "index.meta", - "app_metadata=,columns=,extractor=,immutable=0,index_key_columns=" - ",key_format=u,source=,type=file,value_format=u", + "app_metadata=,collator=,columns=,extractor=,immutable=0," + "index_key_columns=,key_format=u,source=,type=file,value_format=u", confchk_index_meta }, { "session.begin_transaction", @@ -704,7 +707,8 @@ static const WT_CONFIG_ENTRY config_entries[] = { confchk_session_verify }, { "table.meta", - "app_metadata=,colgroups=,columns=,key_format=u,value_format=u", + "app_metadata=,colgroups=,collator=,columns=,key_format=u," + "value_format=u", confchk_table_meta }, { "wiredtiger_open", diff --git a/src/cursor/cur_index.c b/src/cursor/cur_index.c index bf086bcc813..b6d87e71c4b 100644 --- a/src/cursor/cur_index.c +++ b/src/cursor/cur_index.c @@ -61,6 +61,35 @@ err: cursor->saved_err = ret; } /* + * __curindex_compare -- + * WT_CURSOR->compare method for the index cursor type. + */ +static int +__curindex_compare(WT_CURSOR *a, WT_CURSOR *b, int *cmpp) +{ + WT_CURSOR_INDEX *cindex; + WT_DECL_RET; + WT_SESSION_IMPL *session; + + cindex = (WT_CURSOR_INDEX *)a; + CURSOR_API_CALL(a, session, compare, NULL); + + /* Check both cursors are "index:" type. */ + if (!WT_PREFIX_MATCH(a->uri, "index:") || + !WT_PREFIX_MATCH(b->uri, "index:")) + WT_ERR_MSG(session, EINVAL, + "Cursors must reference the same object"); + + WT_CURSOR_CHECKKEY(a); + WT_CURSOR_CHECKKEY(b); + + ret = __wt_compare( + session, cindex->index->collator, &a->key, &b->key, cmpp); + +err: API_END_RET(session, ret); +} + +/* * __curindex_move -- * When an index cursor changes position, set the primary key in the * associated column groups and update their positions to match. @@ -189,8 +218,9 @@ __curindex_search(WT_CURSOR *cursor) WT_CURSOR *child; WT_CURSOR_INDEX *cindex; WT_DECL_RET; + WT_ITEM found_key; WT_SESSION_IMPL *session; - int exact; + int cmp; cindex = (WT_CURSOR_INDEX *)cursor; child = cindex->child; @@ -201,7 +231,7 @@ __curindex_search(WT_CURSOR *cursor) * matches the prefix. Fail if there is no matching item. */ __wt_cursor_set_raw_key(child, &cursor->key); - WT_ERR(child->search_near(child, &exact)); + WT_ERR(child->search_near(child, &cmp)); /* * We expect partial matches, and want the smallest record with a key @@ -210,11 +240,16 @@ __curindex_search(WT_CURSOR *cursor) * otherwise the primary key columns will be appended to the index key, * but we don't disallow that (odd) case. */ - if (exact < 0) + if (cmp < 0) WT_ERR(child->next(child)); - if (child->key.size < cursor->key.size || - memcmp(child->key.data, cursor->key.data, cursor->key.size) != 0) { + if (child->key.size < cursor->key.size) + WT_ERR(WT_NOTFOUND); + found_key = child->key; + found_key.size = cursor->key.size; + WT_ERR(__wt_compare( + session, cindex->index->collator, &cursor->key, &found_key, &cmp)); + if (cmp != 0) { ret = WT_NOTFOUND; goto err; } @@ -342,8 +377,8 @@ __wt_curindex_open(WT_SESSION_IMPL *session, __curindex_get_value, /* get-value */ __wt_cursor_set_key, /* set-key */ __curindex_set_value, /* set-value */ - __wt_cursor_notsup, /* compare */ - __wt_cursor_notsup, /* equals */ + __curindex_compare, /* compare */ + __wt_cursor_equals, /* equals */ __curindex_next, /* next */ __curindex_prev, /* prev */ __curindex_reset, /* reset */ diff --git a/src/include/schema.h b/src/include/schema.h index 4d722a0068b..25c1baae60f 100644 --- a/src/include/schema.h +++ b/src/include/schema.h @@ -28,6 +28,9 @@ struct __wt_index { WT_CONFIG_ITEM colconf; /* List of columns from config */ + WT_COLLATOR *collator; /* Custom collator */ + int collator_owned; /* Collator is owned by this index */ + WT_EXTRACTOR *extractor; /* Custom key extractor */ int extractor_owned; /* Extractor is owned by this index */ diff --git a/src/schema/schema_list.c b/src/schema/schema_list.c index 9d70e5b943a..57ea3b96647 100644 --- a/src/schema/schema_list.c +++ b/src/schema/schema_list.c @@ -139,6 +139,15 @@ __wt_schema_destroy_index(WT_SESSION_IMPL *session, WT_INDEX *idx) { WT_DECL_RET; + /* If there is a custom collator configured, terminate it. */ + if (idx->collator != NULL && + idx->collator_owned && idx->collator->terminate != NULL) { + WT_TRET(idx->collator->terminate( + idx->collator, &session->iface)); + idx->collator = NULL; + idx->collator_owned = 0; + } + /* If there is a custom extractor configured, terminate it. */ if (idx->extractor != NULL && idx->extractor_owned && idx->extractor->terminate != NULL) { diff --git a/src/schema/schema_open.c b/src/schema/schema_open.c index fa655c7108b..02b64fa9b07 100644 --- a/src/schema/schema_open.c +++ b/src/schema/schema_open.c @@ -130,7 +130,7 @@ static int __open_index(WT_SESSION_IMPL *session, WT_TABLE *table, WT_INDEX *idx) { WT_CONFIG colconf; - WT_CONFIG_ITEM ckey, cval; + WT_CONFIG_ITEM ckey, cval, metadata; WT_DECL_ITEM(buf); WT_DECL_ITEM(plan); WT_DECL_RET; @@ -147,6 +147,22 @@ __open_index(WT_SESSION_IMPL *session, WT_TABLE *table, WT_INDEX *idx) if (cval.val) F_SET(idx, WT_INDEX_IMMUTABLE); + /* + * Compatibility: we didn't always collator info in index metadata. + * Cope if it isn't found. + */ + WT_CLEAR(cval); + WT_ERR_NOTFOUND_OK(__wt_config_getones( + session, idx->config, "collator", &cval)); + if (cval.len != 0) { + WT_CLEAR(metadata); + WT_ERR_NOTFOUND_OK(__wt_config_getones( + session, idx->config, "app_metadata", &metadata)); + WT_ERR(__wt_collator_config( + session, idx->name, &cval, &metadata, + &idx->collator, &idx->collator_owned)); + } + WT_ERR(__wt_extractor_config( session, idx->config, &idx->extractor, &idx->extractor_owned)); |