diff options
Diffstat (limited to 'test/csuite/wt2592_join_schema/main.c')
-rw-r--r-- | test/csuite/wt2592_join_schema/main.c | 222 |
1 files changed, 222 insertions, 0 deletions
diff --git a/test/csuite/wt2592_join_schema/main.c b/test/csuite/wt2592_join_schema/main.c new file mode 100644 index 00000000000..4ffc9194646 --- /dev/null +++ b/test/csuite/wt2592_join_schema/main.c @@ -0,0 +1,222 @@ +/*- + * Public Domain 2014-2016 MongoDB, Inc. + * Public Domain 2008-2014 WiredTiger, Inc. + * + * This is free and unencumbered software released into the public domain. + * + * Anyone is free to copy, modify, publish, use, compile, sell, or + * distribute this software, either in source code form or as a compiled + * binary, for any purpose, commercial or non-commercial, and by any + * means. + * + * In jurisdictions that recognize copyright laws, the author or authors + * of this software dedicate any and all copyright interest in the + * software to the public domain. We make this dedication for the benefit + * of the public at large and to the detriment of our heirs and + * successors. We intend this dedication to be an overt act of + * relinquishment in perpetuity of all present and future rights to this + * software under copyright law. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ +#include "test_util.h" + +/* + * JIRA ticket reference: WT-2592 + * Test case description: This is an adaptation of the join parts of + * ex_schema.c, but written as a test. Though we have join tests in the + * Python test suite, the Python API uses raw mode for cursors, so errors + * that are specific to non-raw mode are undetected in Python. + * Failure mode: The failure seen in WT-2592 was that no items were returned + * by a join. + */ +#include <inttypes.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <wiredtiger.h> + +/* The C struct for the data we are storing in a WiredTiger table. */ +typedef struct { + char country[5]; + uint16_t year; + uint64_t population; +} POP_RECORD; + +static POP_RECORD pop_data[] = { + { "AU", 1900, 4000000 }, + { "AU", 1950, 8267337 }, + { "AU", 2000, 19053186 }, + { "CAN", 1900, 5500000 }, + { "CAN", 1950, 14011422 }, + { "CAN", 2000, 31099561 }, + { "UK", 1900, 369000000 }, + { "UK", 1950, 50127000 }, + { "UK", 2000, 59522468 }, + { "USA", 1900, 76212168 }, + { "USA", 1950, 150697361 }, + { "USA", 2000, 301279593 }, + { "", 0, 0 } +}; + +void (*custom_die)(void) = NULL; + +int +main(int argc, char *argv[]) +{ + POP_RECORD *p; + TEST_OPTS *opts, _opts; + WT_CURSOR *country_cursor, *country_cursor2, *cursor, *join_cursor, + *subjoin_cursor, *year_cursor; + WT_SESSION *session; + const char *country, *tablename; + char countryuri[256], joinuri[256], yearuri[256]; + uint64_t recno, population; + uint16_t year; + int count, ret; + + opts = &_opts; + memset(opts, 0, sizeof(*opts)); + testutil_check(testutil_parse_opts(argc, argv, opts)); + testutil_make_work_dir(opts->home); + + tablename = strchr(opts->uri, ':'); + testutil_assert(tablename != NULL); + tablename++; + snprintf(countryuri, sizeof(countryuri), "index:%s:country", tablename); + snprintf(yearuri, sizeof(yearuri), "index:%s:year", tablename); + snprintf(joinuri, sizeof(joinuri), "join:%s", opts->uri); + + testutil_check(wiredtiger_open(opts->home, NULL, + "create,cache_size=200M", &opts->conn)); + testutil_check( + opts->conn->open_session(opts->conn, NULL, NULL, &session)); + testutil_check(session->create(session, opts->uri, + "key_format=r," + "value_format=5sHQ," + "columns=(id,country,year,population)")); + + /* Create an index with a simple key. */ + testutil_check(session->create(session, + countryuri, "columns=(country)")); + + /* Create an immutable index. */ + testutil_check(session->create(session, + yearuri, "columns=(year),immutable")); + + /* Insert the records into the table. */ + testutil_check(session->open_cursor( + session, opts->uri, NULL, "append", &cursor)); + count = 1; + for (p = pop_data; p->year != 0; p++) { + cursor->set_key(cursor, count); + cursor->set_value(cursor, p->country, p->year, p->population); + testutil_check(cursor->insert(cursor)); + count++; + } + testutil_check(cursor->close(cursor)); + + /* Open cursors needed by the join. */ + testutil_check(session->open_cursor(session, + joinuri, NULL, NULL, &join_cursor)); + testutil_check(session->open_cursor(session, + countryuri, NULL, NULL, &country_cursor)); + testutil_check(session->open_cursor(session, + yearuri, NULL, NULL, &year_cursor)); + + /* select values WHERE country == "AU" AND year > 1900 */ + country_cursor->set_key(country_cursor, "AU\0\0\0"); + testutil_check(country_cursor->search(country_cursor)); + testutil_check(session->join(session, join_cursor, country_cursor, + "compare=eq,count=10")); + year_cursor->set_key(year_cursor, (uint16_t)1900); + testutil_check(year_cursor->search(year_cursor)); + testutil_check(session->join(session, join_cursor, year_cursor, + "compare=gt,count=10,strategy=bloom")); + + count = 0; + /* List the values that are joined */ + while ((ret = join_cursor->next(join_cursor)) == 0) { + testutil_check(join_cursor->get_key(join_cursor, &recno)); + testutil_check(join_cursor->get_value(join_cursor, &country, + &year, &population)); + printf("ID %" PRIu64, recno); + printf( + ": country %s, year %" PRIu16 ", population %" PRIu64 "\n", + country, year, population); + count++; + } + testutil_assert(ret == WT_NOTFOUND); + testutil_assert(count == 2); + + testutil_check(join_cursor->close(join_cursor)); + testutil_check(year_cursor->close(year_cursor)); + testutil_check(country_cursor->close(country_cursor)); + + /* Open cursors needed by the join. */ + testutil_check(session->open_cursor(session, + joinuri, NULL, NULL, &join_cursor)); + testutil_check(session->open_cursor(session, + joinuri, NULL, NULL, &subjoin_cursor)); + testutil_check(session->open_cursor(session, + countryuri, NULL, NULL, &country_cursor)); + testutil_check(session->open_cursor(session, + countryuri, NULL, NULL, &country_cursor2)); + testutil_check(session->open_cursor(session, + yearuri, NULL, NULL, &year_cursor)); + + /* + * select values WHERE (country == "AU" OR country == "UK") + * AND year > 1900 + * + * First, set up the join representing the country clause. + */ + country_cursor->set_key(country_cursor, "AU\0\0\0"); + testutil_check(country_cursor->search(country_cursor)); + testutil_check(session->join(session, subjoin_cursor, country_cursor, + "operation=or,compare=eq,count=10")); + country_cursor2->set_key(country_cursor2, "UK\0\0\0"); + testutil_check(country_cursor2->search(country_cursor2)); + testutil_check(session->join(session, subjoin_cursor, country_cursor2, + "operation=or,compare=eq,count=10")); + + /* Join that to the top join, and add the year clause */ + testutil_check(session->join(session, join_cursor, subjoin_cursor, + NULL)); + year_cursor->set_key(year_cursor, (uint16_t)1900); + testutil_check(year_cursor->search(year_cursor)); + testutil_check(session->join(session, join_cursor, year_cursor, + "compare=gt,count=10,strategy=bloom")); + + count = 0; + /* List the values that are joined */ + while ((ret = join_cursor->next(join_cursor)) == 0) { + testutil_check(join_cursor->get_key(join_cursor, &recno)); + testutil_check(join_cursor->get_value(join_cursor, &country, + &year, &population)); + printf("ID %" PRIu64, recno); + printf( + ": country %s, year %" PRIu16 ", population %" PRIu64 "\n", + country, year, population); + count++; + } + testutil_assert(ret == WT_NOTFOUND); + testutil_assert(count == 4); + + testutil_check(join_cursor->close(join_cursor)); + testutil_check(subjoin_cursor->close(subjoin_cursor)); + testutil_check(country_cursor->close(country_cursor)); + testutil_check(country_cursor2->close(country_cursor2)); + testutil_check(year_cursor->close(year_cursor)); + testutil_check(session->close(session, NULL)); + + testutil_cleanup(opts); + return (EXIT_SUCCESS); +} |