Exemplo n.º 1
0
Arquivo: main.c Projeto: ajdavis/mongo
int
main(int argc, char *argv[])
{
	TEST_OPTS *opts, _opts;
	WT_CURSOR *balancecur, *flagcur, *joincur, *postcur;
	WT_CURSOR *maincur;
	WT_SESSION *session;
	int balance, count, flag, key, key2, post, ret;
	char balanceuri[256];
	char cfg[128];
	char flaguri[256];
	char joinuri[256];
	char posturi[256];
	const char *tablename;

	opts = &_opts;
	memset(opts, 0, sizeof(*opts));
	testutil_check(testutil_parse_opts(argc, argv, opts));
	testutil_make_work_dir(opts->home);
	testutil_progress(opts, "start");

	testutil_check(wiredtiger_open(opts->home, NULL,
	    "create,cache_size=250M", &opts->conn));
	testutil_progress(opts, "wiredtiger_open");
	testutil_check(
	    opts->conn->open_session(opts->conn, NULL, NULL, &session));
	testutil_progress(opts, "sessions opened");

	/*
	 * Note: repeated primary key 'id' as 'id2'.  This makes
	 * it easier to dump an index and know which record we're
	 * looking at.
	 */
	testutil_check(session->create(session, opts->uri,
	    "key_format=i,value_format=iiii,"
	    "columns=(id,post,balance,flag,id2)"));

	tablename = strchr(opts->uri, ':');
	testutil_assert(tablename != NULL);
	tablename++;
	testutil_check(__wt_snprintf(
	    posturi, sizeof(posturi), "index:%s:post", tablename));
	testutil_check(__wt_snprintf(
	    balanceuri, sizeof(balanceuri), "index:%s:balance", tablename));
	testutil_check(__wt_snprintf(
	    flaguri, sizeof(flaguri), "index:%s:flag", tablename));
	testutil_check(__wt_snprintf(
	    joinuri, sizeof(joinuri), "join:%s", opts->uri));

	testutil_check(session->create(session, posturi, "columns=(post)"));
	testutil_check(session->create(session, balanceuri,
	    "columns=(balance)"));
	testutil_check(session->create(session, flaguri, "columns=(flag)"));
	testutil_progress(opts, "setup complete");

	/*
	 * Insert a single record with all items we are search for,
	 * this makes our logic easier.
	 */
	testutil_check(session->open_cursor(session, opts->uri, NULL, NULL,
	    &maincur));
	maincur->set_key(maincur, N_RECORDS);
	maincur->set_value(maincur, 54321, 0, "", 0, N_RECORDS);
	testutil_check(maincur->insert(maincur));
	testutil_check(maincur->close(maincur));
	testutil_check(session->close(session, NULL));

	testutil_progress(opts, "populate start");
	populate(opts);
	testutil_progress(opts, "populate end");

	testutil_check(opts->conn->open_session(
	    opts->conn, NULL, NULL, &session));

	testutil_check(session->open_cursor(session,
	    posturi, NULL, NULL, &postcur));
	testutil_check(session->open_cursor(session,
	    balanceuri, NULL, NULL, &balancecur));
	testutil_check(session->open_cursor(session,
	    flaguri, NULL, NULL, &flagcur));
	testutil_check(session->open_cursor(session,
	    joinuri, NULL, NULL, &joincur));

	postcur->set_key(postcur, 54321);
	testutil_check(postcur->search(postcur));
	testutil_check(session->join(session, joincur, postcur,
	    "compare=eq"));

	balancecur->set_key(balancecur, 0);
	testutil_check(balancecur->search(balancecur));
	testutil_check(__wt_snprintf(cfg, sizeof(cfg),
	    "compare=lt,strategy=bloom,count=%d", N_RECORDS / 100));
	testutil_check(session->join(session, joincur, balancecur, cfg));

	flagcur->set_key(flagcur, 0);
	testutil_check(flagcur->search(flagcur));
	testutil_check(__wt_snprintf(cfg, sizeof(cfg),
	    "compare=eq,strategy=bloom,count=%d", N_RECORDS / 100));
	testutil_check(session->join(session, joincur, flagcur, cfg));

	/* Expect no values returned */
	count = 0;
	while ((ret = joincur->next(joincur)) == 0) {
		/*
		 * The values may already have been changed, but
		 * print them for informational purposes.
		 */
		testutil_check(joincur->get_key(joincur, &key));
		testutil_check(joincur->get_value(joincur, &post,
		    &balance, &flag, &key2));
		fprintf(stderr, "FAIL: "
		    "key=%d/%d, postal_code=%d, balance=%d, flag=%d\n",
		    key, key2, post, balance, flag);
		count++;
	}
	testutil_assert(ret == WT_NOTFOUND);
	testutil_assert(count == 0);

	testutil_progress(opts, "cleanup starting");
	testutil_cleanup(opts);
	return (EXIT_SUCCESS);
}
Exemplo n.º 2
0
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);
}
Exemplo n.º 3
0
int
main(int argc, char *argv[])
{
	POP_RECORD *p;
	WT_CONNECTION *conn;
	WT_CURSOR *country_cursor, *country_cursor2, *cursor, *join_cursor,
	    *stat_cursor, *subjoin_cursor, *year_cursor;
	WT_SESSION *session;
	const char *country;
	uint64_t recno, population;
	uint16_t year;
	int ret;

	home = example_setup(argc, argv);

	error_check(wiredtiger_open(
	    home, NULL, "create,statistics=(fast)", &conn));

	error_check(conn->open_session(conn, NULL, NULL, &session));

	/*! [Create a table with column groups] */
	/*
	 * Create the population table.
	 * Keys are record numbers, the format for values is (5-byte string,
	 * uint16_t, uint64_t).
	 * See ::wiredtiger_struct_pack for details of the format strings.
	 */
	error_check(session->create(session, "table:poptable",
	    "key_format=r,"
	    "value_format=5sHQ,"
	    "columns=(id,country,year,population),"
	    "colgroups=(main,population)"));

	/*
	 * Create two column groups: a primary column group with the country
	 * code, year and population (named "main"), and a population column
	 * group with the population by itself (named "population").
	 */
	error_check(session->create(session,
	    "colgroup:poptable:main", "columns=(country,year,population)"));
	error_check(session->create(session,
	    "colgroup:poptable:population", "columns=(population)"));
	/*! [Create a table with column groups] */

	/*! [Create an index] */
	/* Create an index with a simple key. */
	error_check(session->create(session,
	    "index:poptable:country", "columns=(country)"));
	/*! [Create an index] */

	/*! [Create an index with a composite key] */
	/* Create an index with a composite key (country,year). */
	error_check(session->create(session,
	    "index:poptable:country_plus_year", "columns=(country,year)"));
	/*! [Create an index with a composite key] */

	/*! [Create an immutable index] */
	/* Create an immutable index. */
	error_check(session->create(session,
	    "index:poptable:immutable_year", "columns=(year),immutable"));
	/*! [Create an immutable index] */

	/* Insert the records into the table. */
	error_check(session->open_cursor(
	    session, "table:poptable", NULL, "append", &cursor));
	for (p = pop_data; p->year != 0; p++) {
		cursor->set_value(cursor, p->country, p->year, p->population);
		error_check(cursor->insert(cursor));
	}
	error_check(cursor->close(cursor));

	/* Update records in the table. */
	error_check(session->open_cursor(session,
	    "table:poptable", NULL, NULL, &cursor));
	while ((ret = cursor->next(cursor)) == 0) {
		error_check(cursor->get_key(cursor, &recno));
		error_check(cursor->get_value(
		    cursor, &country, &year, &population));
		cursor->set_value(cursor, country, year, population + 1);
		error_check(cursor->update(cursor));
	}
	scan_end_check(ret == WT_NOTFOUND);
	error_check(cursor->close(cursor));

	/* List the records in the table. */
	error_check(session->open_cursor(session,
	    "table:poptable", NULL, NULL, &cursor));
	while ((ret = cursor->next(cursor)) == 0) {
		error_check(cursor->get_key(cursor, &recno));
		error_check(cursor->get_value(
		    cursor, &country, &year, &population));
		printf("ID %" PRIu64, recno);
		printf(
		    ": country %s, year %" PRIu16 ", population %" PRIu64 "\n",
		    country, year, population);
	}
	scan_end_check(ret == WT_NOTFOUND);
	error_check(cursor->close(cursor));

	/*! [List the records in the table using raw mode.] */
	/* List the records in the table using raw mode. */
	error_check(session->open_cursor(session,
	    "table:poptable", NULL, "raw", &cursor));
	while ((ret = cursor->next(cursor)) == 0) {
		WT_ITEM key, value;

		error_check(cursor->get_key(cursor, &key));
		error_check(wiredtiger_struct_unpack(
		    session, key.data, key.size, "r", &recno));
		printf("ID %" PRIu64, recno);

		error_check(cursor->get_value(cursor, &value));
		error_check(wiredtiger_struct_unpack(session,
		    value.data, value.size,
		    "5sHQ", &country, &year, &population));
		printf(
		    ": country %s, year %" PRIu16 ", population %" PRIu64 "\n",
		    country, year, population);
	}
	scan_end_check(ret == WT_NOTFOUND);
	/*! [List the records in the table using raw mode.] */
	error_check(cursor->close(cursor));

	/*! [Read population from the primary column group] */
	/*
	 * Open a cursor on the main column group, and return the information
	 * for a particular country.
	 */
	error_check(session->open_cursor(
	    session, "colgroup:poptable:main", NULL, NULL, &cursor));
	cursor->set_key(cursor, 2);
	error_check(cursor->search(cursor));
	error_check(cursor->get_value(cursor, &country, &year, &population));
	printf(
	    "ID 2: country %s, year %" PRIu16 ", population %" PRIu64 "\n",
	    country, year, population);
	/*! [Read population from the primary column group] */
	error_check(cursor->close(cursor));

	/*! [Read population from the standalone column group] */
	/*
	 * Open a cursor on the population column group, and return the
	 * population of a particular country.
	 */
	error_check(session->open_cursor(session,
	    "colgroup:poptable:population", NULL, NULL, &cursor));
	cursor->set_key(cursor, 2);
	error_check(cursor->search(cursor));
	error_check(cursor->get_value(cursor, &population));
	printf("ID 2: population %" PRIu64 "\n", population);
	/*! [Read population from the standalone column group] */
	error_check(cursor->close(cursor));

	/*! [Search in a simple index] */
	/* Search in a simple index. */
	error_check(session->open_cursor(session,
	    "index:poptable:country", NULL, NULL, &cursor));
	cursor->set_key(cursor, "AU\0\0\0");
	error_check(cursor->search(cursor));
	error_check(cursor->get_value(cursor, &country, &year, &population));
	printf("AU: country %s, year %" PRIu16 ", population %" PRIu64 "\n",
	    country, year, population);
	/*! [Search in a simple index] */
	error_check(cursor->close(cursor));

	/*! [Search in a composite index] */
	/* Search in a composite index. */
	error_check(session->open_cursor(session,
	    "index:poptable:country_plus_year", NULL, NULL, &cursor));
	cursor->set_key(cursor, "USA\0\0", (uint16_t)1900);
	error_check(cursor->search(cursor));
	error_check(cursor->get_value(cursor, &country, &year, &population));
	printf(
	    "US 1900: country %s, year %" PRIu16 ", population %" PRIu64 "\n",
	    country, year, population);
	/*! [Search in a composite index] */
	error_check(cursor->close(cursor));

	/*! [Return a subset of values from the table] */
	/*
	 * Use a projection to return just the table's country and year
	 * columns.
	 */
	error_check(session->open_cursor(session,
	    "table:poptable(country,year)", NULL, NULL, &cursor));
	while ((ret = cursor->next(cursor)) == 0) {
		error_check(cursor->get_value(cursor, &country, &year));
		printf("country %s, year %" PRIu16 "\n", country, year);
	}
	/*! [Return a subset of values from the table] */
	scan_end_check(ret == WT_NOTFOUND);
	error_check(cursor->close(cursor));

	/*! [Return a subset of values from the table using raw mode] */
	/*
	 * Use a projection to return just the table's country and year
	 * columns, using raw mode.
	 */
	error_check(session->open_cursor(session,
	    "table:poptable(country,year)", NULL, "raw", &cursor));
	while ((ret = cursor->next(cursor)) == 0) {
		WT_ITEM value;

		error_check(cursor->get_value(cursor, &value));
		error_check(wiredtiger_struct_unpack(
		    session, value.data, value.size, "5sH", &country, &year));
		printf("country %s, year %" PRIu16 "\n", country, year);
	}
	scan_end_check(ret == WT_NOTFOUND);
	/*! [Return a subset of values from the table using raw mode] */
	error_check(cursor->close(cursor));

	/*! [Return the table's record number key using an index] */
	/*
	 * Use a projection to return just the table's record number key
	 * from an index.
	 */
	error_check(session->open_cursor(session,
	    "index:poptable:country_plus_year(id)", NULL, NULL, &cursor));
	while ((ret = cursor->next(cursor)) == 0) {
		error_check(cursor->get_key(cursor, &country, &year));
		error_check(cursor->get_value(cursor, &recno));
		printf("row ID %" PRIu64 ": country %s, year %" PRIu16 "\n",
		    recno, country, year);
	}
	scan_end_check(ret == WT_NOTFOUND);
	/*! [Return the table's record number key using an index] */
	error_check(cursor->close(cursor));

	/*! [Return a subset of the value columns from an index] */
	/*
	 * Use a projection to return just the population column from an
	 * index.
	 */
	error_check(session->open_cursor(session,
	    "index:poptable:country_plus_year(population)",
	    NULL, NULL, &cursor));
	while ((ret = cursor->next(cursor)) == 0) {
		error_check(cursor->get_key(cursor, &country, &year));
		error_check(cursor->get_value(cursor, &population));
		printf("population %" PRIu64 ": country %s, year %" PRIu16 "\n",
		    population, country, year);
	}
	scan_end_check(ret == WT_NOTFOUND);
	/*! [Return a subset of the value columns from an index] */
	error_check(cursor->close(cursor));

	/*! [Access only the index] */
	/*
	 * Use a projection to avoid accessing any other column groups when
	 * using an index: supply an empty list of value columns.
	 */
	error_check(session->open_cursor(session,
	    "index:poptable:country_plus_year()", NULL, NULL, &cursor));
	while ((ret = cursor->next(cursor)) == 0) {
		error_check(cursor->get_key(cursor, &country, &year));
		printf("country %s, year %" PRIu16 "\n", country, year);
	}
	scan_end_check(ret == WT_NOTFOUND);
	/*! [Access only the index] */
	error_check(cursor->close(cursor));

	/*! [Join cursors] */
	/* Open cursors needed by the join. */
	error_check(session->open_cursor(session,
	    "join:table:poptable", NULL, NULL, &join_cursor));
	error_check(session->open_cursor(session,
	    "index:poptable:country", NULL, NULL, &country_cursor));
	error_check(session->open_cursor(session,
	    "index:poptable:immutable_year", NULL, NULL, &year_cursor));

	/* select values WHERE country == "AU" AND year > 1900 */
	country_cursor->set_key(country_cursor, "AU\0\0\0");
	error_check(country_cursor->search(country_cursor));
	error_check(session->join(
	    session, join_cursor, country_cursor, "compare=eq,count=10"));
	year_cursor->set_key(year_cursor, (uint16_t)1900);
	error_check(year_cursor->search(year_cursor));
	error_check(session->join(session,
	    join_cursor, year_cursor, "compare=gt,count=10,strategy=bloom"));

	/* List the values that are joined */
	while ((ret = join_cursor->next(join_cursor)) == 0) {
		error_check(join_cursor->get_key(join_cursor, &recno));
		error_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);
	}
	scan_end_check(ret == WT_NOTFOUND);
	/*! [Join cursors] */

	/*! [Statistics cursor join cursor] */
	error_check(session->open_cursor(session,
	    "statistics:join",
	    join_cursor, NULL, &stat_cursor));
	/*! [Statistics cursor join cursor] */

	error_check(stat_cursor->close(stat_cursor));
	error_check(join_cursor->close(join_cursor));
	error_check(year_cursor->close(year_cursor));
	error_check(country_cursor->close(country_cursor));

	/*! [Complex join cursors] */
	/* Open cursors needed by the join. */
	error_check(session->open_cursor(session,
	    "join:table:poptable", NULL, NULL, &join_cursor));
	error_check(session->open_cursor(session,
	    "join:table:poptable", NULL, NULL, &subjoin_cursor));
	error_check(session->open_cursor(session,
	    "index:poptable:country", NULL, NULL, &country_cursor));
	error_check(session->open_cursor(session,
	    "index:poptable:country", NULL, NULL, &country_cursor2));
	error_check(session->open_cursor(session,
	    "index:poptable:immutable_year", 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");
	error_check(country_cursor->search(country_cursor));
	error_check(session->join(session, subjoin_cursor,
	    country_cursor, "operation=or,compare=eq,count=10"));
	country_cursor2->set_key(country_cursor2, "UK\0\0\0");
	error_check(country_cursor2->search(country_cursor2));
	error_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 */
	error_check(session->join(session, join_cursor, subjoin_cursor, NULL));
	year_cursor->set_key(year_cursor, (uint16_t)1900);
	error_check(year_cursor->search(year_cursor));
	error_check(session->join(session,
	    join_cursor, year_cursor, "compare=gt,count=10,strategy=bloom"));

	/* List the values that are joined */
	while ((ret = join_cursor->next(join_cursor)) == 0) {
		error_check(join_cursor->get_key(join_cursor, &recno));
		error_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);
	}
	scan_end_check(ret == WT_NOTFOUND);
	/*! [Complex join cursors] */

	error_check(join_cursor->close(join_cursor));
	error_check(subjoin_cursor->close(subjoin_cursor));
	error_check(country_cursor->close(country_cursor));
	error_check(country_cursor2->close(country_cursor2));
	error_check(year_cursor->close(year_cursor));

	error_check(conn->close(conn, NULL));

	return (EXIT_SUCCESS);
}
Exemplo n.º 4
0
int
main(void)
{
	POP_RECORD *p;
	WT_CONNECTION *conn;
	WT_CURSOR *cursor, *cursor2, *join_cursor, *stat_cursor;
	WT_SESSION *session;
	const char *country;
	uint64_t recno, population;
	uint16_t year;
	int ret;

	/*
	 * Create a clean test directory for this run of the test program if the
	 * environment variable isn't already set (as is done by make check).
	 */
	if (getenv("WIREDTIGER_HOME") == NULL) {
		home = "WT_HOME";
		ret = system("rm -rf WT_HOME && mkdir WT_HOME");
	} else
		home = NULL;

	if ((ret = wiredtiger_open(
	    home, NULL, "create,statistics=(fast)", &conn)) != 0) {
		fprintf(stderr, "Error connecting to %s: %s\n",
		    home, wiredtiger_strerror(ret));
		return (ret);
	}
	/* Note: error checking omitted for clarity. */

	ret = conn->open_session(conn, NULL, NULL, &session);

	/*! [Create a table with column groups] */
	/*
	 * Create the population table.
	 * Keys are record numbers, the format for values is (5-byte string,
	 * uint16_t, uint64_t).
	 * See ::wiredtiger_struct_pack for details of the format strings.
	 */
	ret = session->create(session, "table:poptable",
	    "key_format=r,"
	    "value_format=5sHQ,"
	    "columns=(id,country,year,population),"
	    "colgroups=(main,population)");

	/*
	 * Create two column groups: a primary column group with the country
	 * code, year and population (named "main"), and a population column
	 * group with the population by itself (named "population").
	 */
	ret = session->create(session,
	    "colgroup:poptable:main", "columns=(country,year,population)");
	ret = session->create(session,
	    "colgroup:poptable:population", "columns=(population)");
	/*! [Create a table with column groups] */

	/*! [Create an index] */
	/* Create an index with a simple key. */
	ret = session->create(session,
	    "index:poptable:country", "columns=(country)");
	/*! [Create an index] */

	/*! [Create an index with a composite key] */
	/* Create an index with a composite key (country,year). */
	ret = session->create(session,
	    "index:poptable:country_plus_year", "columns=(country,year)");
	/*! [Create an index with a composite key] */

	/*! [Create an immutable index] */
	/* Create an immutable index. */
	ret = session->create(session,
	    "index:poptable:immutable_year", "columns=(year),immutable");
	/*! [Create an immutable index] */

	/* Insert the records into the table. */
	ret = session->open_cursor(
	    session, "table:poptable", NULL, "append", &cursor);
	for (p = pop_data; p->year != 0; p++) {
		cursor->set_value(cursor, p->country, p->year, p->population);
		ret = cursor->insert(cursor);
	}
	ret = cursor->close(cursor);

	/* Update records in the table. */
	ret = session->open_cursor(session,
	    "table:poptable", NULL, NULL, &cursor);
	while ((ret = cursor->next(cursor)) == 0) {
		ret = cursor->get_key(cursor, &recno);
		ret = cursor->get_value(cursor, &country, &year, &population);
		cursor->set_value(cursor, country, year, population + 1);
		ret = cursor->update(cursor);
	}
	ret = cursor->close(cursor);

	/* List the records in the table. */
	ret = session->open_cursor(session,
	    "table:poptable", NULL, NULL, &cursor);
	while ((ret = cursor->next(cursor)) == 0) {
		ret = cursor->get_key(cursor, &recno);
		ret = cursor->get_value(cursor, &country, &year, &population);
		printf("ID %" PRIu64, recno);
		printf(
		    ": country %s, year %" PRIu16 ", population %" PRIu64 "\n",
		    country, year, population);
	}
	ret = cursor->close(cursor);

	/*! [List the records in the table using raw mode.] */
	/* List the records in the table using raw mode. */
	ret = session->open_cursor(session,
	    "table:poptable", NULL, "raw", &cursor);
	while ((ret = cursor->next(cursor)) == 0) {
		WT_ITEM key, value;

		ret = cursor->get_key(cursor, &key);
		ret = wiredtiger_struct_unpack(session,
		    key.data, key.size, "r", &recno);
		printf("ID %" PRIu64, recno);

		ret = cursor->get_value(cursor, &value);
		ret = wiredtiger_struct_unpack(session,
		    value.data, value.size,
		    "5sHQ", &country, &year, &population);
		printf(
		    ": country %s, year %" PRIu16 ", population %" PRIu64 "\n",
		    country, year, population);
	}
	/*! [List the records in the table using raw mode.] */
	ret = cursor->close(cursor);

	/*! [Read population from the primary column group] */
	/*
	 * Open a cursor on the main column group, and return the information
	 * for a particular country.
	 */
	ret = session->open_cursor(
	    session, "colgroup:poptable:main", NULL, NULL, &cursor);
	cursor->set_key(cursor, 2);
	if ((ret = cursor->search(cursor)) == 0) {
		ret = cursor->get_value(cursor, &country, &year, &population);
		printf(
		    "ID 2: "
		    "country %s, year %" PRIu16 ", population %" PRIu64 "\n",
		    country, year, population);
	}
	/*! [Read population from the primary column group] */
	ret = cursor->close(cursor);

	/*! [Read population from the standalone column group] */
	/*
	 * Open a cursor on the population column group, and return the
	 * population of a particular country.
	 */
	ret = session->open_cursor(session,
	    "colgroup:poptable:population", NULL, NULL, &cursor);
	cursor->set_key(cursor, 2);
	if ((ret = cursor->search(cursor)) == 0) {
		ret = cursor->get_value(cursor, &population);
		printf("ID 2: population %" PRIu64 "\n", population);
	}
	/*! [Read population from the standalone column group] */
	ret = cursor->close(cursor);

	/*! [Search in a simple index] */
	/* Search in a simple index. */
	ret = session->open_cursor(session,
	    "index:poptable:country", NULL, NULL, &cursor);
	cursor->set_key(cursor, "AU\0\0\0");
	ret = cursor->search(cursor);
	ret = cursor->get_value(cursor, &country, &year, &population);
	printf("AU: country %s, year %" PRIu16 ", population %" PRIu64 "\n",
	    country, year, population);
	/*! [Search in a simple index] */
	ret = cursor->close(cursor);

	/*! [Search in a composite index] */
	/* Search in a composite index. */
	ret = session->open_cursor(session,
	    "index:poptable:country_plus_year", NULL, NULL, &cursor);
	cursor->set_key(cursor, "USA\0\0", (uint16_t)1900);
	ret = cursor->search(cursor);
	ret = cursor->get_value(cursor, &country, &year, &population);
	printf(
	    "US 1900: country %s, year %" PRIu16 ", population %" PRIu64 "\n",
	    country, year, population);
	/*! [Search in a composite index] */
	ret = cursor->close(cursor);

	/*! [Return a subset of values from the table] */
	/*
	 * Use a projection to return just the table's country and year
	 * columns.
	 */
	ret = session->open_cursor(session,
	    "table:poptable(country,year)", NULL, NULL, &cursor);
	while ((ret = cursor->next(cursor)) == 0) {
		ret = cursor->get_value(cursor, &country, &year);
		printf("country %s, year %" PRIu16 "\n", country, year);
	}
	/*! [Return a subset of values from the table] */
	ret = cursor->close(cursor);

	/*! [Return a subset of values from the table using raw mode] */
	/*
	 * Use a projection to return just the table's country and year
	 * columns, using raw mode.
	 */
	ret = session->open_cursor(session,
	    "table:poptable(country,year)", NULL, "raw", &cursor);
	while ((ret = cursor->next(cursor)) == 0) {
		WT_ITEM value;

		ret = cursor->get_value(cursor, &value);
		ret = wiredtiger_struct_unpack(
		    session, value.data, value.size, "5sH", &country, &year);
		printf("country %s, year %" PRIu16 "\n", country, year);
	}
	/*! [Return a subset of values from the table using raw mode] */
	ret = cursor->close(cursor);

	/*! [Return the table's record number key using an index] */
	/*
	 * Use a projection to return just the table's record number key
	 * from an index.
	 */
	ret = session->open_cursor(session,
	    "index:poptable:country_plus_year(id)", NULL, NULL, &cursor);
	while ((ret = cursor->next(cursor)) == 0) {
		ret = cursor->get_key(cursor, &country, &year);
		ret = cursor->get_value(cursor, &recno);
		printf("row ID %" PRIu64 ": country %s, year %" PRIu16 "\n",
		    recno, country, year);
	}
	/*! [Return the table's record number key using an index] */
	ret = cursor->close(cursor);

	/*! [Return a subset of the value columns from an index] */
	/*
	 * Use a projection to return just the population column from an
	 * index.
	 */
	ret = session->open_cursor(session,
	    "index:poptable:country_plus_year(population)",
	    NULL, NULL, &cursor);
	while ((ret = cursor->next(cursor)) == 0) {
		ret = cursor->get_key(cursor, &country, &year);
		ret = cursor->get_value(cursor, &population);
		printf("population %" PRIu64 ": country %s, year %" PRIu16 "\n",
		    population, country, year);
	}
	/*! [Return a subset of the value columns from an index] */
	ret = cursor->close(cursor);

	/*! [Access only the index] */
	/*
	 * Use a projection to avoid accessing any other column groups when
	 * using an index: supply an empty list of value columns.
	 */
	ret = session->open_cursor(session,
	    "index:poptable:country_plus_year()", NULL, NULL, &cursor);
	while ((ret = cursor->next(cursor)) == 0) {
		ret = cursor->get_key(cursor, &country, &year);
		printf("country %s, year %" PRIu16 "\n", country, year);
	}
	/*! [Access only the index] */
	ret = cursor->close(cursor);

	/*! [Join cursors] */
	/* Open cursors needed by the join. */
	ret = session->open_cursor(session,
	    "join:table:poptable", NULL, NULL, &join_cursor);
	ret = session->open_cursor(session,
	    "index:poptable:country", NULL, NULL, &cursor);
	ret = session->open_cursor(session,
	    "index:poptable:immutable_year", NULL, NULL, &cursor2);

	/* select values WHERE country == "AU" AND year > 1900 */
	cursor->set_key(cursor, "AU\0\0\0");
	ret = cursor->search(cursor);
	ret = session->join(session, join_cursor, cursor,
	    "compare=eq,count=10");
	cursor2->set_key(cursor2, (uint16_t)1900);
	ret = cursor2->search(cursor2);
	ret = session->join(session, join_cursor, cursor2,
	    "compare=gt,count=10,strategy=bloom");

	/* List the values that are joined */
	while ((ret = join_cursor->next(join_cursor)) == 0) {
		ret = join_cursor->get_key(join_cursor, &recno);
		ret = join_cursor->get_value(join_cursor, &country, &year,
		    &population);
		printf("ID %" PRIu64, recno);
		printf(
		    ": country %s, year %" PRIu16 ", population %" PRIu64 "\n",
		    country, year, population);
	}
	/*! [Join cursors] */

	/*! [Statistics cursor join cursor] */
	ret = session->open_cursor(session,
	    "statistics:join",
	    join_cursor, NULL, &stat_cursor);
	/*! [Statistics cursor join cursor] */

	ret = stat_cursor->close(stat_cursor);
	ret = join_cursor->close(join_cursor);
	ret = cursor2->close(cursor2);
	ret = cursor->close(cursor);

	ret = conn->close(conn, NULL);

	return (ret);
}