void test_boundary_args() { header(); const int max_update_op_cnt = 4000; printf("# insert tuple\n"); struct tnt_tuple *tuple = tnt_tuple(NULL, "%d%d", 0, 1); insert_tuple(tuple); tnt_tuple_free(tuple); printf("# test: try to do update w/o operations\n"); struct tnt_stream *stream = tnt_buf(NULL); update(0, stream); tnt_stream_free(stream); printf("# test: update w/ maximal allowed opearions count\n"); stream = tnt_buf(NULL); for (int i = 0; i < max_update_op_cnt; ++i) tnt_update_arith_i32(stream, 1, TNT_UPDATE_ADD, 1); update(0, stream); tnt_stream_free(stream); printf("# test: update w/ grater than maximal allowed opearions count\n"); stream = tnt_buf(NULL); for (int i = 0; i < max_update_op_cnt + 1; ++i) tnt_update_arith_i32(stream, 1, TNT_UPDATE_ADD, 1); update(0, stream); tnt_stream_free(stream); footer(); }
void test_long_set() { header(); printf("# insert tuple\n"); struct tnt_tuple *tuple = tnt_tuple(NULL, "%d%s%s%s", 1, "first", "", "third"); insert_tuple(tuple); tnt_tuple_free(tuple); printf("# test set big value in empty field\n"); struct tnt_stream *stream = tnt_buf(NULL); update_set_str(stream, 2, long_string); update(1, stream); tnt_stream_free(stream); printf("# test replace long value to short\n"); stream = tnt_buf(NULL); update_set_str(stream, 2, "short string"); update(1, stream); tnt_stream_free(stream); footer(); }
void test_simple_set() { header(); /* insert tuple */ printf("# insert tuple\n"); struct tnt_tuple *tuple = tnt_tuple(NULL, "%d%d%d%s", 1, 2, 0, ""); insert_tuple(tuple); tnt_tuple_free(tuple); printf("# test simple set field\n"); struct tnt_stream *stream = tnt_buf(NULL); update_set_str(stream, 1, "new field value"); update_set_str(stream, 2, ""); update_set_str(stream, 3, "fLaC"); update(1, stream); tnt_stream_free(stream); printf("# set field\n"); stream = tnt_buf(NULL); update_set_str(stream, 1, "value?"); update_set_str(stream, 1, "very very very very very long field value?"); update_set_str(stream, 1, "field's new value"); update(1, stream); tnt_stream_free(stream); stream = tnt_buf(NULL); printf("# test set primary key\n"); update_set_i32(stream, 0, 2); update(1, stream); tnt_stream_free(stream); footer(); }
void test_append() { header(); /* insert tuple */ printf("# insert tuple\n"); struct tnt_tuple *tuple = tnt_tuple(NULL, "%d%s", 1, "first"); insert_tuple(tuple); tnt_tuple_free(tuple); /* test append field */ struct tnt_stream *stream = tnt_buf(NULL); printf("# test append field\n"); update_set_str(stream, 2, "second"); update(1, stream); tnt_stream_free(stream); /* test multi append field */ stream = tnt_buf(NULL); printf("# test multi append\n"); update_set_str(stream, 3, "3"); update_set_str(stream, 3, "new field value"); update_set_str(stream, 3, "other new field value"); update_set_str(stream, 3, "third"); update(1, stream); tnt_stream_free(stream); /* test append many field */ stream = tnt_buf(NULL); printf("# test append many fields\n"); update_set_str(stream, 4, "fourth"); update_set_str(stream, 5, "fifth"); update_set_str(stream, 6, "sixth"); update_set_str(stream, 7, "seventh"); update_set_str(stream, 8, long_string); update(1, stream); tnt_stream_free(stream); /* test append and change field */ stream = tnt_buf(NULL); printf("# test append and change field\n"); update_set_str(stream, 9, long_string); update_splice_str(stream, 9, 1, 544, "ac"); tnt_update_arith_i32(stream, 9, TNT_UPDATE_XOR, 0x3ffffff); tnt_update_arith_i32(stream, 9, TNT_UPDATE_ADD, 1024); update(1, stream); tnt_stream_free(stream); /* test set to not an exist field */ stream = tnt_buf(NULL); printf("# test set to not an exist field\n"); update_set_str(stream, 0xDEADBEEF, "invalid!"); update(1, stream); tnt_stream_free(stream); footer(); }
void test_splice() { header(); printf("# insert tuple\n"); struct tnt_tuple *tuple = tnt_tuple(NULL, "%d%s%s%s", 1, "first", "hi, this is a test string!", "third"); insert_tuple(tuple); tnt_tuple_free(tuple); struct tnt_stream *stream = tnt_buf(NULL); printf("# test cut from begin\n"); update_splice_str(stream, 2, 0, 4, ""); update(1, stream); tnt_stream_free(stream); printf("# test cut from middle\n"); stream = tnt_buf(NULL); update_splice_str(stream, 2, 9, -8, ""); update(1, stream); tnt_stream_free(stream); printf("# test cut from end\n"); stream = tnt_buf(NULL); update_splice_str(stream, 2, -1, 1, ""); update(1, stream); tnt_stream_free(stream); printf("# test insert before begin\n"); stream = tnt_buf(NULL); update_splice_str(stream, 2, 0, 0, "Bonjour, "); update(1, stream); tnt_stream_free(stream); printf("# test insert after end\n"); stream = tnt_buf(NULL); update_splice_str(stream, 2, 10000, 0, " o_O!?"); update(1, stream); tnt_stream_free(stream); printf("# test replace in begin\n"); stream = tnt_buf(NULL); update_splice_str(stream, 2, 0, 7, "Hello"); update(1, stream); tnt_stream_free(stream); printf("# test replace in middle\n"); stream = tnt_buf(NULL); update_splice_str(stream, 2, 17, -6, "field"); update(1, stream); tnt_stream_free(stream); printf("# test replace in end\n"); stream = tnt_buf(NULL); update_splice_str(stream, 2, -6, 4, "! Is this Sparta"); update(1, stream); tnt_stream_free(stream); footer(); }
/** update fields test case: 64-bit arithmetics operations test */ void test_arith_i64() { header(); printf("# insert tuple\n"); struct tnt_tuple *tuple = tnt_tuple(NULL, "%d%ll%ll%ll", 1, 2, 0, 0, 0); insert_tuple(tuple); tnt_tuple_free(tuple); printf("# test add\n"); struct tnt_stream *stream = tnt_buf(NULL); tnt_update_arith_i64(stream, 1, TNT_UPDATE_ADD, 16); update(1, stream); tnt_stream_free(stream); printf("# test overflow add\n"); stream = tnt_buf(NULL); tnt_update_arith_i64(stream, 1, TNT_UPDATE_ADD, INT64_MAX); update(1, stream); tnt_stream_free(stream); printf("# test underflow add\n"); stream = tnt_buf(NULL); tnt_update_arith_i64(stream, 1, TNT_UPDATE_ADD, INT64_MIN); update(1, stream); tnt_stream_free(stream); printf("# test or\n"); stream = tnt_buf(NULL); tnt_update_arith_i64(stream, 2, TNT_UPDATE_OR, 0xbacfbacfbacfbacf); tnt_update_arith_i64(stream, 3, TNT_UPDATE_OR, 0xfabcfabcfabcfabc); update(1, stream); tnt_stream_free(stream); printf("# test xor\n"); stream = tnt_buf(NULL); tnt_update_arith_i64(stream, 2, TNT_UPDATE_XOR, 0xffffffffffffffff); tnt_update_arith_i64(stream, 3, TNT_UPDATE_XOR, 0xffffffffffffffff); update(1, stream); tnt_stream_free(stream); printf("# test and\n"); stream = tnt_buf(NULL); tnt_update_arith_i64(stream, 2, TNT_UPDATE_AND, 0xf0f0f0f0f0f0f0f0); tnt_update_arith_i64(stream, 3, TNT_UPDATE_AND, 0x0f0f0f0f0f0f0f0f); update(1, stream); tnt_stream_free(stream); printf("# test casting 32-bit operand to 64-bit\n"); stream = tnt_buf(NULL); tnt_update_arith_i32(stream, 1, TNT_UPDATE_ADD, 16); update(1, stream); tnt_stream_free(stream); footer(); }
void test_set_and_splice() { header(); printf("# insert tuple\n"); struct tnt_tuple *tuple = tnt_tuple(NULL, "%d%s%s%s", 1, "first", "hi, this is a test string!", "third"); insert_tuple(tuple); tnt_tuple_free(tuple); printf("# test set long string and splice to short\n"); struct tnt_stream *stream = tnt_buf(NULL); update_set_str(stream, 2, long_string); update_splice_str(stream, 2, 45, 500, " away away away"); update(1, stream); tnt_stream_free(stream); printf("# test set short value and splice to long\n"); stream = tnt_buf(NULL); update_set_str(stream, 2, "test"); update_splice_str(stream, 2, -4, 4, long_string); update(1, stream); tnt_stream_free(stream); printf("# test splice to long and set to short\n"); stream = tnt_buf(NULL); update_splice_str(stream, 3, -5, 5, long_string); update_set_str(stream, 2, "short name"); update(1, stream); tnt_stream_free(stream); footer(); }
void test_multi_arith() { header(); printf("# insert tuple\n"); struct tnt_tuple *tuple = tnt_tuple(NULL, "%d%s%d%s", 1, "first", 128, "third"); insert_tuple(tuple); tnt_tuple_free(tuple); printf("# test simple and\n"); struct tnt_stream *stream = tnt_buf(NULL); update_set_i32(stream, 2, 0); update_set_str(stream, 1, "first field new value"); tnt_update_arith_i32(stream, 2, TNT_UPDATE_XOR, 0xF00F); update_set_str(stream, 3, "third field new value"); tnt_update_arith_i32(stream, 2, TNT_UPDATE_OR, 0xF00F); update(1, stream); tnt_stream_free(stream); footer(); }
static bool tnt_sql_stmt(struct tnt_sql *sql) { struct tnt_tuple tu; struct tnt_list tuples; struct tnt_stream update; tnt_tuple_init(&tu); tnt_list_init(&tuples); tnt_buf(&update); int flags = 0; struct tnt_tk *tk = NULL, *tn = NULL; bool rc = false; switch (tnt_lex(sql->l, &tk)) { /* <INSERT|REPLACE> [INTO] TABLE VALUES ( list ) */ case TNT_TK_INSERT: case TNT_TK_REPLACE: tnt_sqltry(sql, TNT_TK_INTO); if (sql->error) goto error; tnt_expect(tnt_sqltkv(sql, TNT_TK_TABLE, &tn)); tnt_expect(tnt_sqltk(sql, TNT_TK_VALUES)); tnt_expect(tnt_sqltk(sql, '(')); while (1) { tnt_expect(tnt_sql_kv(sql, &tu, false)); if (tnt_sqltry(sql, ',')) continue; if (sql->error) goto error; break; } flags = TNT_FLAG_ADD; if (tk->tk == TNT_TK_REPLACE) flags = TNT_FLAG_REPLACE; tnt_expect(tnt_sqltk(sql, ')')); tnt_expect(tnt_sqltk(sql, TNT_TK_EOF)); if (tnt_insert(sql->s, TNT_TK_I32(tn), flags, &tu) == -1) { tnt_sql_error(sql, tk, "insert failed"); goto error; } break; /* UPDATE TABLE SET operations WHERE predicate */ case TNT_TK_UPDATE: if (!tnt_sql_stmt_update(sql, &tu, &update)) goto error; break; /* DELETE FROM TABLE WHERE predicate */ case TNT_TK_DELETE: tnt_expect(tnt_sqltk(sql, TNT_TK_FROM)); tnt_expect(tnt_sqltkv(sql, TNT_TK_TABLE, &tn)); tnt_expect(tnt_sqltk(sql, TNT_TK_WHERE)); /* predicate */ tnt_expect(tnt_sql_kv(sql, &tu, true)); tnt_expect(tnt_sqltk(sql, TNT_TK_EOF)); if (tnt_delete(sql->s, TNT_TK_I32(tn), 0, &tu) == -1) { tnt_sql_error(sql, tk, "delete failed"); goto error; } break; /* SELECT * FROM TABLE WHERE predicate OR predicate... LIMIT NUM */ case TNT_TK_SELECT: { tnt_expect(tnt_sqltk(sql, '*')); tnt_expect(tnt_sqltk(sql, TNT_TK_FROM)); tnt_expect(tnt_sqltkv(sql, TNT_TK_TABLE, &tn)); tnt_expect(tnt_sqltk(sql, TNT_TK_WHERE)); int32_t index = -1; while (1) { struct tnt_tuple *tup = tnt_list_at(&tuples, NULL); while (1) { tnt_expect(tnt_sql_kv_select(sql, tup, &index)); if (tnt_sqltry(sql, TNT_TK_AND)) continue; if (sql->error) goto error; break; } if (tnt_sqltry(sql, TNT_TK_OR)) continue; if (sql->error) goto error; break; } uint32_t limit = UINT32_MAX; if (tnt_sqltry(sql, TNT_TK_LIMIT)) { struct tnt_tk *ltk; tnt_expect(tnt_sqltkv(sql, TNT_TK_NUM32, <k)); limit = TNT_TK_I32(ltk); } else if (sql->error) goto error; tnt_expect(tnt_sqltk(sql, TNT_TK_EOF)); if (tnt_select(sql->s, TNT_TK_I32(tn), index, 0, limit, &tuples) == -1) { tnt_sql_error(sql, tk, "select failed"); goto error; } break; } /* CALL NAME[{.NAME}+](STRING [{,STRING}+]) */ case TNT_TK_CALL: { char proc[512]; int len = 0; while (1) { struct tnt_tk *name = NULL; tnt_lex_idonly(sql->l, true); tnt_expect(tnt_sqltkv(sql, TNT_TK_ID, &name)); tnt_lex_idonly(sql->l, false); len += snprintf(proc + len, sizeof(proc) - len, "%.*s", (int)TNT_TK_S(name)->size, TNT_TK_S(name)->data); if (!tnt_sqltry(sql, '.')) break; if (sql->error) goto error; len += snprintf(proc + len, sizeof(proc) - len, "%s", "."); } tnt_expect(tnt_sqltk(sql, '(')); if (tnt_sqltry(sql, ')')) goto noargs; if (sql->error) goto error; while (1) { tnt_expect(tnt_sql_kv(sql, &tu, false)); if (tnt_sqltry(sql, ',')) continue; if (sql->error) goto error; break; } tnt_expect(tnt_sqltk(sql, ')')); noargs: tnt_expect(tnt_sqltk(sql, TNT_TK_EOF)); if (tnt_call(sql->s, 0, proc, &tu) == -1) { tnt_sql_error(sql, tk, "call failed"); goto error; } break; } /* PING */ case TNT_TK_PING: tnt_expect(tnt_sqltk(sql, TNT_TK_EOF)); if (tnt_ping(sql->s) == -1) { tnt_sql_error(sql, tk, "ping failed"); goto error; } break; case TNT_TK_EOF: break; case TNT_TK_ERROR: return tnt_sql_error(sql, tk, "%s", sql->l->error); default: return tnt_sql_error(sql, tk, "insert, replace, update, delete, select, call, ping are expected"); } rc = true; error: tnt_tuple_free(&tu); tnt_list_free(&tuples); tnt_stream_free(&update); return rc; }
void test_insert_field() { header(); printf("# insert tuple\n"); struct tnt_tuple *tuple = tnt_tuple(NULL, "%d%s", 9, "eleven"); insert_tuple(tuple); tnt_tuple_free(tuple); printf("# insert new field before primary key\n"); struct tnt_stream *stream = tnt_buf(NULL); update_insert_i32(stream, 0, 7); update_insert_i32(stream, 0, 8); update(9, stream); tnt_stream_free(stream); printf("# insert a new field before last field\n"); stream = tnt_buf(NULL); update_insert_i32(stream, 3, 10); update(7, stream); tnt_stream_free(stream); printf("# double insert at the end\n"); stream = tnt_buf(NULL); update_set_i32(stream, 5, 14); update_insert_i32(stream, 6, 12); update_insert_i32(stream, 5, 13); update(7, stream); tnt_stream_free(stream); printf("# multi insert \n"); stream = tnt_buf(NULL); update_insert_i32(stream, 5, 15); update_insert_i32(stream, 5, 14); update_insert_i32(stream, 5, 13); update_insert_i32(stream, 5, 12); update(7, stream); tnt_stream_free(stream); printf("# insert before next to last field\n"); stream = tnt_buf(NULL); update_insert_i32(stream, 8, 15); update(7, stream); tnt_stream_free(stream); printf("# insert before next to last field\n"); stream = tnt_buf(NULL); update_set_i32(stream, 9, 17); update_insert_i32(stream, 9, 16); update_set_i32(stream, 10, 19); update_insert_i32(stream, 10, 18); update(7, stream); tnt_stream_free(stream); printf("# insert second tuple\n"); tuple = tnt_tuple(NULL, "%d%s%d", 0, "one", 11); insert_tuple(tuple); tnt_tuple_free(tuple); stream = tnt_buf(NULL); printf("# multi insert\n"); update_set_i32(stream, 1, -11); tnt_update_arith(stream, 1, TNT_UPDATE_ADD, 1); update_insert_i32(stream, 1, 1); tnt_update_arith(stream, 1, TNT_UPDATE_ADD, 2); update_insert_i32(stream, 1, 2); update_insert_i32(stream, 1, 3); tnt_update_arith(stream, 1, TNT_UPDATE_ADD, 3); tnt_update_arith(stream, 1, TNT_UPDATE_ADD, 4); tnt_update_arith(stream, 1, TNT_UPDATE_ADD, 5); update_insert_i32(stream, 1, 4); update_insert_i32(stream, 1, 5); tnt_update_arith(stream, 1, TNT_UPDATE_ADD, 6); update_insert_i32(stream, 1, 6); update_insert_i32(stream, 1, 7); update_insert_i32(stream, 1, 8); update_insert_i32(stream, 1, 9); update(0, stream); tnt_stream_free(stream); printf("# insert before invalid field number\n"); stream = tnt_buf(NULL); update_insert_str(stream, 100000, "ooppps!"); update(7, stream); tnt_stream_free(stream); footer(); }
void test_delete_field() { header(); printf("# insert tuple\n"); struct tnt_tuple *tuple = tnt_tuple(NULL, "%d%s%s%s%d%d%d%d%d%d%d%d%d%d", 1, "first", "hi, this is a test string!", "third", 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); insert_tuple(tuple); tnt_tuple_free(tuple); printf("# test simple delete fields\n"); struct tnt_stream *stream = tnt_buf(NULL); update_delete_field(stream, 2); update(1, stream); tnt_stream_free(stream); printf("# test useless operations with delete fields\n"); stream = tnt_buf(NULL); update_set_i32(stream, 1, 0); tnt_update_arith_i32(stream, 1, TNT_UPDATE_ADD, 1); tnt_update_arith_i32(stream, 1, TNT_UPDATE_ADD, 1); tnt_update_arith_i32(stream, 1, TNT_UPDATE_ADD, 1); tnt_update_arith_i32(stream, 1, TNT_UPDATE_ADD, 1); tnt_update_arith_i32(stream, 1, TNT_UPDATE_ADD, 1); tnt_update_arith_i32(stream, 1, TNT_UPDATE_ADD, 1); tnt_update_arith_i32(stream, 1, TNT_UPDATE_ADD, 1); tnt_update_arith_i32(stream, 1, TNT_UPDATE_ADD, 1); update_delete_field(stream, 1); update(1, stream); tnt_stream_free(stream); printf("# test multi delete fields\n"); stream = tnt_buf(NULL); update_delete_field(stream, 2); update_delete_field(stream, 3); update_delete_field(stream, 4); update_delete_field(stream, 5); update_delete_field(stream, 6); update_delete_field(stream, 7); update_delete_field(stream, 8); update_delete_field(stream, 9); update_delete_field(stream, 10); update(1, stream); tnt_stream_free(stream); printf("# test multi delete fields\n"); stream = tnt_buf(NULL); update_delete_field(stream, 1); update_set_i32(stream, 1, 3); tnt_update_arith_i32(stream, 1, TNT_UPDATE_ADD, 1); tnt_update_arith_i32(stream, 1, TNT_UPDATE_ADD, 1); tnt_update_arith_i32(stream, 1, TNT_UPDATE_ADD, 1); tnt_update_arith_i32(stream, 1, TNT_UPDATE_ADD, 1); tnt_update_arith_i32(stream, 1, TNT_UPDATE_ADD, 1); tnt_update_arith_i32(stream, 1, TNT_UPDATE_ADD, 1); update(1, stream); tnt_stream_free(stream); printf("# test append and delete\n"); stream = tnt_buf(NULL); update_set_str(stream, 3, "second"); update_delete_field(stream, 3); update_set_str(stream, 3, "third"); update_set_str(stream, 4, "third"); update_delete_field(stream, 4); update_set_str(stream, 4, "third"); update_set_str(stream, 4, "fourth"); update_set_str(stream, 5, "fifth"); update_set_str(stream, 6, "sixth"); update_set_str(stream, 7, "seventh"); update_set_str(stream, 8, "eighth"); update_set_str(stream, 9, "ninth"); update_delete_field(stream, 7); update_delete_field(stream, 6); update(1, stream); tnt_stream_free(stream); printf("# test double delete\n"); stream = tnt_buf(NULL); update_delete_field(stream, 3); update_delete_field(stream, 3); update(1, stream); tnt_stream_free(stream); select_tuple(1); printf("# test delete not an exist field\n"); stream = tnt_buf(NULL); update_delete_field(stream, 0xDEADBEEF); update(1, stream); tnt_stream_free(stream); select_tuple(1); footer(); }