summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--dist/api_data.py8
-rw-r--r--src/config/config_def.c12
-rw-r--r--src/cursor/cur_index.c49
-rw-r--r--src/include/schema.h3
-rw-r--r--src/schema/schema_list.c9
-rw-r--r--src/schema/schema_open.c18
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));