void print_tuple( /*========*/ FILE* stream, const ib_tpl_t tpl) { int i; int n_cols = ib_tuple_get_n_cols(tpl); for (i = 0; i < n_cols; ++i) { ib_ulint_t data_len; ib_col_meta_t col_meta; data_len = ib_col_get_meta(tpl, i, &col_meta); /* Skip system columns. */ if (col_meta.type == IB_SYS) { continue; /* Nothing to print. */ } else if (data_len == IB_SQL_NULL) { fprintf(stream, "|"); continue; } else { switch (col_meta.type) { case IB_INT: { print_int_col(stream, tpl, i, &col_meta); break; } case IB_FLOAT: { float v; ib_tuple_read_float(tpl, i, &v); fprintf(stream, "%f", v); break; } case IB_DOUBLE: { double v; ib_tuple_read_double(tpl, i, &v); fprintf(stream, "%lf", v); break; } case IB_BLOB: case IB_VARCHAR: { const char* ptr; ptr = ib_col_get_value(tpl, i); fprintf(stream, "%d:", (int) data_len); print_char_array(stream, ptr, (int) data_len); break; } default: assert(IB_FALSE); break; } } fprintf(stream, "|"); } fprintf(stream, "\n"); }
/********************************************************************* UPDATE T SET score = score + 100 WHERE first = 'a'; */ static ib_err_t update_random_rows( /*===============*/ ib_crsr_t crsr) { ib_err_t err; int l; char* ptr; int res = ~0; ib_tpl_t key_tpl; ib_tpl_t old_tpl = NULL; ib_tpl_t new_tpl = NULL; /* Create a tuple for searching an index. */ key_tpl = ib_sec_search_tuple_create(crsr); assert(key_tpl != NULL); ptr = (char*) malloc(8192); l = gen_rand_text(ptr, 128); /* Set the value to look for. */ err = ib_col_set_value(key_tpl, 0, ptr, l); assert(err == DB_SUCCESS); /* Search for the key using the cluster index (PK) */ err = ib_cursor_moveto(crsr, key_tpl, IB_CUR_GE, &res); assert(err == DB_SUCCESS || err == DB_END_OF_INDEX || err == DB_RECORD_NOT_FOUND); if (key_tpl != NULL) { ib_tuple_delete(key_tpl); } /* Match found */ if (res == 0) { ib_u32_t score; const char* first; ib_ulint_t data_len; ib_ulint_t first_len; ib_col_meta_t col_meta; /* Create the tuple instance that we will use to update the table. old_tpl is used for reading the existing row and new_tpl will contain the update row data. */ old_tpl = ib_clust_read_tuple_create(crsr); assert(old_tpl != NULL); new_tpl = ib_clust_read_tuple_create(crsr); assert(new_tpl != NULL); err = ib_cursor_read_row(crsr, old_tpl); assert(err == DB_SUCCESS); /* Get the first column value. */ first = ib_col_get_value(old_tpl, 0); first_len = ib_col_get_meta(old_tpl, 0, &col_meta); /* There are no SQL_NULL values in our test data. */ assert(first != NULL); /* Copy the old contents to the new tuple. */ err = ib_tuple_copy(new_tpl, old_tpl); /* Update the score column in the new tuple. */ data_len = ib_col_get_meta(old_tpl, 2, &col_meta); assert(data_len != IB_SQL_NULL); err = ib_tuple_read_u32(old_tpl, 2, &score); assert(err == DB_SUCCESS); ++score; /* Get the new text to insert. */ l = gen_rand_text(ptr, 128); /* Set the new key value in the new tuple. */ err = ib_col_set_value(new_tpl, 0, ptr, l); assert(err == DB_SUCCESS); first_len = ib_col_get_len(new_tpl, 0); assert(first_len == IB_SQL_NULL || first_len <= 128); /* Get the new text to insert. */ l = gen_rand_text(ptr, 8192); /* Set the blob value in the new tuple. */ err = ib_col_set_value(new_tpl, 1, ptr, l); assert(err == DB_SUCCESS); /* Set the updated score value in the new tuple. */ err = ib_tuple_write_u32(new_tpl, 2, score); assert(err == DB_SUCCESS); err = ib_cursor_update_row(crsr, old_tpl, new_tpl); assert(err == DB_SUCCESS || err == DB_DUPLICATE_KEY); } if (old_tpl != NULL) { ib_tuple_delete(old_tpl); } if (new_tpl != NULL) { ib_tuple_delete(new_tpl); } free(ptr); return(err); }
/** * Try to get an item from the database * * @param trx the transaction to use * @param key the key to get * @param nkey the lenght of the key * @return a pointer to the item if I found it in the database */ static struct item* do_get_item(ib_trx_t trx, const void* key, size_t nkey) { ib_crsr_t cursor= NULL; ib_tpl_t tuple= NULL; struct item* retval= NULL; if (do_locate_item(trx, key, nkey, &cursor)) { tuple= ib_clust_read_tuple_create(cursor); if (tuple == NULL) { fprintf(stderr, "Failed to create read tuple\n"); goto error_exit; } checked(ib_cursor_read_row(cursor, tuple)); ib_col_meta_t meta; ib_ulint_t datalen= ib_col_get_meta(tuple, data_col_idx, &meta); ib_ulint_t flaglen= ib_col_get_meta(tuple, flags_col_idx, &meta); ib_ulint_t caslen= ib_col_get_meta(tuple, cas_col_idx, &meta); ib_ulint_t explen= ib_col_get_meta(tuple, exp_col_idx, &meta); const void *dataptr= ib_col_get_value(tuple, data_col_idx); retval= create_item(key, nkey, dataptr, datalen, 0, 0); if (retval == NULL) { fprintf(stderr, "Failed to allocate memory\n"); goto error_exit; } if (flaglen != 0) { ib_u32_t val; checked(ib_tuple_read_u32(tuple, flags_col_idx, &val)); retval->flags= (uint32_t)val; } if (caslen != 0) { ib_u64_t val; checked(ib_tuple_read_u64(tuple, cas_col_idx, &val)); retval->cas= (uint64_t)val; } if (explen != 0) { ib_u32_t val; checked(ib_tuple_read_u32(tuple, exp_col_idx, &val)); retval->exp= (time_t)val; } } /* Release resources */ /* FALLTHROUGH */ error_exit: if (tuple != NULL) ib_tuple_delete(tuple); if (cursor != NULL) { ib_err_t cursor_error; cursor_error= ib_cursor_close(cursor); (void) cursor_error; } return retval; }
/********************************************************************* UPDATE T SET c1 = RANDOM(string), c3 = MOD(c3 + 1, 10) WHERE c3 = MOD(RANDOM(INT), 10); */ static ib_err_t update_random_rows( /*===============*/ ib_crsr_t crsr) { ib_i32_t c3; ib_err_t err; ib_i32_t key; int res = ~0; ib_crsr_t index_crsr; ib_tpl_t sec_key_tpl; /* Open the secondary index. */ err = ib_cursor_open_index_using_name(crsr, "c3", &index_crsr); assert(err == DB_SUCCESS); /* Set the record lock mode */ err = ib_cursor_set_lock_mode(index_crsr, IB_LOCK_X); assert(err == DB_SUCCESS); /* Since we will be updating the clustered index record, set the need to access clustered index flag in the cursor. */ ib_cursor_set_cluster_access(index_crsr); /* Create a tuple for searching the secondary index. */ sec_key_tpl = ib_sec_search_tuple_create(index_crsr); assert(sec_key_tpl != NULL); /* Set the value to look for. */ #ifdef __WIN__ key = rand() % 10; #else key = random() % 10; #endif err = ib_tuple_write_i32(sec_key_tpl, 0, key); assert(err == DB_SUCCESS); /* Search for the key using the cluster index (PK) */ err = ib_cursor_moveto(index_crsr, sec_key_tpl, IB_CUR_GE, &res); assert(err == DB_SUCCESS || err == DB_END_OF_INDEX || err == DB_RECORD_NOT_FOUND); ib_tuple_delete(sec_key_tpl); /* Match found */ if (res == 0) { int l; char* ptr; const char* first; ib_ulint_t data_len; ib_col_meta_t col_meta; ib_ulint_t first_len; ib_tpl_t old_tpl = NULL; ib_tpl_t new_tpl = NULL; /* Create the tuple instance that we will use to update the table. old_tpl is used for reading the existing row and new_tpl will contain the update row data. */ old_tpl = ib_clust_read_tuple_create(crsr); assert(old_tpl != NULL); new_tpl = ib_clust_read_tuple_create(crsr); assert(new_tpl != NULL); err = ib_cursor_read_row(index_crsr, old_tpl); assert(err == DB_SUCCESS); /* Get the first column value. */ first = ib_col_get_value(old_tpl, 0); first_len = ib_col_get_meta(old_tpl, 0, &col_meta); /* There are no SQL_NULL values in our test data. */ assert(first != NULL); /* Copy the old contents to the new tuple. */ err = ib_tuple_copy(new_tpl, old_tpl); /* Update the c3 column in the new tuple. */ data_len = ib_col_get_meta(old_tpl, 2, &col_meta); assert(data_len != IB_SQL_NULL); err = ib_tuple_read_i32(old_tpl, 2, &c3); assert(err == DB_SUCCESS); assert(c3 == key); c3 = (c3 + 1) % 10; ptr = (char*) malloc(8192); l = gen_rand_text(ptr, 128); /* Get the new text to insert. */ l = gen_rand_text(ptr, 8192); /* Set the new key value in the new tuple. */ err = ib_col_set_value(new_tpl, 0, ptr, l); assert(err == DB_SUCCESS); /* Get the new text to insert. */ l = gen_rand_text(ptr, 8192); /* Set the c2 value in the new tuple. */ err = ib_col_set_value(new_tpl, 1, ptr, l); assert(err == DB_SUCCESS); /* Set the updated c3 value in the new tuple. */ err = ib_tuple_write_i32(new_tpl, 2, c3); assert(err == DB_SUCCESS); /* NOTE: We are using the secondary index cursor to update the record and not the cluster index cursor. */ err = ib_cursor_update_row(index_crsr, old_tpl, new_tpl); assert(err == DB_SUCCESS || err == DB_DUPLICATE_KEY); /* Reset the old and new tuple instances. */ old_tpl = ib_tuple_clear(old_tpl); assert(old_tpl != NULL); new_tpl = ib_tuple_clear(new_tpl); assert(new_tpl != NULL); free(ptr); ib_tuple_delete(old_tpl); ib_tuple_delete(new_tpl); } err = ib_cursor_close(index_crsr); assert(err == DB_SUCCESS); return(err); }