void update_set_str(struct tnt_stream *stream, int32_t field, char *str) { int result = tnt_update_assign(stream, field, str, strlen(str)); if (result < 0) fail_tnt_error("tnt_update_assign", result); }
void update_set_i32(struct tnt_stream *stream, int32_t field, int32_t value) { int result = tnt_update_assign(stream, field, (char *)&value, sizeof(value)); if (result < 0) fail_tnt_error("tnt_update_assign", result); }
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; }