示例#1
0
static bool
tnt_sql_stmt_update(struct tnt_sql *sql, struct tnt_tuple *tu, struct tnt_stream *u)
{
	/* UPDATE TABLE SET operations WHERE predicate */
	bool rc = false;
	struct tnt_tk *tn = NULL;
	tnt_expect(tnt_sqltkv(sql, TNT_TK_TABLE, &tn));
	tnt_expect(tnt_sqltk(sql, TNT_TK_SET));
	while (1) {
		struct tnt_tk *k = NULL;
		tnt_expect(tnt_sqltkv(sql, TNT_TK_KEY, &k));
		tnt_expect(tnt_sqltk(sql, '='));
		struct tnt_tk *v;
		switch (tnt_lex(sql->l, &v)) {
		/* k = k op v */
		case TNT_TK_KEY:
			if (TNT_TK_I32(k) != TNT_TK_I32(v)) {
				tnt_sql_error(sql, k, "can't update on different keys");
				goto error;
			}
			int ut;
			switch (tnt_lex(sql->l, &v)) {
			case TNT_TK_ERROR:
				tnt_sql_error(sql, k, "%s", sql->l->error);
				goto error;
			case '+': ut = TNT_UPDATE_ADD;
				break;
			case '&': ut = TNT_UPDATE_AND;
				break;
			case '^': ut = TNT_UPDATE_XOR;
				break;
			case '|': ut = TNT_UPDATE_OR;
				break;
			default:
				tnt_sql_error(sql, k, "bad update operation");
				goto error;
			}
			tnt_expect(tnt_sqltkv(sql, TNT_TK_NUM32, &v));
			tnt_update_arith(u, TNT_TK_I32(k), ut, TNT_TK_I32(v));
			break;
		/* k = string */
		case TNT_TK_STRING:
			tnt_update_assign(u, TNT_TK_I32(k), (char*)TNT_TK_S(v)->data,
					  TNT_TK_S(v)->size);
			break;
		/* k = num32 */
		case TNT_TK_NUM32:
			tnt_update_assign(u, TNT_TK_I32(k), (char*)&TNT_TK_I32(v), 4);
			break;
		/* k = num64 */
		case TNT_TK_NUM64:
			tnt_update_assign(u, TNT_TK_I64(k), (char*)&TNT_TK_I64(v), 8);
			break;
		/* k = splice(k, a, b) */
		case TNT_TK_SPLICE: {
			struct tnt_tk *field = NULL, *off = NULL,
				      *len = NULL, *list = NULL;
			tnt_expect(tnt_sqltk(sql, '('));
			tnt_expect(tnt_sqltkv(sql, TNT_TK_KEY, &field));
			if (TNT_TK_I32(k) != TNT_TK_I32(field)) {
				tnt_sql_error(sql, k, "can't update on different keys");
				goto error;
			}
			tnt_expect(tnt_sqltk(sql, ','));
			tnt_expect(tnt_sqltkv(sql, TNT_TK_NUM32, &off));
			tnt_expect(tnt_sqltk(sql, ','));
			tnt_expect(tnt_sqltkv(sql, TNT_TK_NUM32, &len));
			tnt_expect(tnt_sqltk(sql, ','));
			tnt_expect(tnt_sqltkv(sql, TNT_TK_STRING, &list));
			tnt_expect(tnt_sqltk(sql, ')'));
			tnt_update_splice(u, TNT_TK_I32(k), TNT_TK_I32(off), TNT_TK_I32(len),
					  (char*)TNT_TK_S(list)->data,
					  TNT_TK_S(list)->size);
			break;
		}
		case TNT_TK_ERROR:
			tnt_sql_error(sql, k, "%s", sql->l->error);
			goto error;
		}
		if (tnt_sqltry(sql, ','))
			continue;
		if (sql->error)
			goto error;
		break;
	}
	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_update(sql->s, TNT_TK_I32(tn), 0, tu, u) == -1) {
		tnt_sql_error(sql, tn, "update failed");
		goto error;
	}
	rc = true;
error:
	return rc;
}
示例#2
0
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();
}