diff --git a/src/bind.c b/src/bind.c index d32e20cdc..ecc2d7282 100644 --- a/src/bind.c +++ b/src/bind.c @@ -87,7 +87,8 @@ int parseParams(struct cursor *cursor, int format, struct value **out) prev = prev->next; } - *out = head; + *out = head->next; + sqlite3_free(head); return 0; err_after_alloc_head: diff --git a/src/gateway.c b/src/gateway.c index dfe2108e6..5555f9462 100644 --- a/src/gateway.c +++ b/src/gateway.c @@ -467,7 +467,7 @@ static int handle_exec(struct gateway *g, struct handle *req) struct request_exec request = {0}; int tuple_format; uint64_t req_id; - struct value *params; + struct value *params = NULL; int rv; switch (req->schema) { @@ -501,13 +501,12 @@ static int handle_exec(struct gateway *g, struct handle *req) return 0; } rv = bindParams(stmt->stmt, params); + freeParams(params); if (rv != 0) { tracef("handle exec bind failed %d", rv); - freeParams(params); failure(req, rv, "bind parameters"); return 0; } - freeParams(params); req->stmt_id = stmt->id; g->req = req; req_id = idNext(&g->random_state); @@ -606,7 +605,7 @@ static int handle_query(struct gateway *g, struct handle *req) int tuple_format; bool is_readonly; uint64_t req_id; - struct value *params; + struct value *params = NULL; int rv; switch (req->schema) { @@ -640,13 +639,12 @@ static int handle_query(struct gateway *g, struct handle *req) return 0; } rv = bindParams(stmt->stmt, params); + freeParams(params); if (rv != 0) { tracef("handle query bind failed %d", rv); - freeParams(params); failure(req, rv, "bind parameters"); return 0; } - freeParams(params); req->stmt_id = stmt->id; g->req = req; @@ -717,7 +715,7 @@ static void handle_exec_sql_next(struct gateway *g, const char *tail; int tuple_format; uint64_t req_id; - struct value *params; + struct value *params = NULL; int rv; if (req->sql == NULL || strcmp(req->sql, "") == 0) { @@ -755,8 +753,8 @@ static void handle_exec_sql_next(struct gateway *g, goto done_after_prepare; } rv = bindParams(stmt, params); + freeParams(params); if (rv != 0) { - freeParams(params); failure(req, rv, "bind parameters"); goto done_after_prepare; } @@ -874,7 +872,7 @@ static void querySqlBarrierCb(struct barrier *barrier, int status) int tuple_format; bool is_readonly; uint64_t req_id; - struct value *params; + struct value *params = NULL; int rv; if (status != 0) { @@ -922,9 +920,9 @@ static void querySqlBarrierCb(struct barrier *barrier, int status) return; } rv = bindParams(stmt, params); + freeParams(params); if (rv != 0) { tracef("handle query sql bind failed %d", rv); - freeParams(params); sqlite3_finalize(stmt); failure(req, rv, "bind parameters"); return; diff --git a/src/tuple.c b/src/tuple.c index 2d4537e82..5876dcbbe 100644 --- a/src/tuple.c +++ b/src/tuple.c @@ -150,6 +150,7 @@ int tuple_decoder__next(struct tuple_decoder *d, struct value *value) rc = DQLITE_PARSE; break; }; + value->next = NULL; if (rc != 0) { return rc; } diff --git a/test/unit/test_concurrency.c b/test/unit/test_concurrency.c index f1887d45e..a6b31dea5 100644 --- a/test/unit/test_concurrency.c +++ b/test/unit/test_concurrency.c @@ -5,6 +5,7 @@ #include "../../src/protocol.h" #include "../../src/request.h" #include "../../src/response.h" +#include "../../src/revamp.h" TEST_MODULE(concurrency); @@ -33,36 +34,39 @@ struct connection struct buffer response; /* Response payload */ struct handle handle; /* Async handle request */ struct context context; + struct db_context *db_ctx; }; #define FIXTURE \ FIXTURE_CLUSTER; \ struct connection connections[N_GATEWAYS] -#define SETUP \ - unsigned i; \ - int rc; \ - SETUP_CLUSTER(V2); \ - CLUSTER_ELECT(0); \ - for (i = 0; i < N_GATEWAYS; i++) { \ - struct connection *c = &f->connections[i]; \ - struct request_open open; \ - struct response_db db; \ - struct id_state seed = {{1}}; \ - gateway__init(&c->gateway, CLUSTER_CONFIG(0), \ - CLUSTER_REGISTRY(0), CLUSTER_RAFT(0), seed); \ - c->handle.data = &c->context; \ - rc = buffer__init(&c->request); \ - munit_assert_int(rc, ==, 0); \ - rc = buffer__init(&c->response); \ - munit_assert_int(rc, ==, 0); \ - open.filename = "test"; \ - open.vfs = ""; \ - ENCODE(c, &open, open); \ - HANDLE(c, OPEN); \ - ASSERT_CALLBACK(c, 0, DB); \ - DECODE(c, &db, db); \ - munit_assert_int(db.id, ==, 0); \ +#define SETUP \ + unsigned i; \ + int rc; \ + SETUP_CLUSTER(V2); \ + CLUSTER_ELECT(0); \ + for (i = 0; i < N_GATEWAYS; i++) { \ + struct connection *c = &f->connections[i]; \ + struct request_open open; \ + struct response_db db; \ + struct id_state seed = {{1}}; \ + c->db_ctx = munit_malloc(sizeof *c->db_ctx); \ + gateway__init(&c->gateway, CLUSTER_CONFIG(0), \ + CLUSTER_REGISTRY(0), CLUSTER_RAFT(0), seed, \ + c->db_ctx); \ + c->handle.data = &c->context; \ + rc = buffer__init(&c->request); \ + munit_assert_int(rc, ==, 0); \ + rc = buffer__init(&c->response); \ + munit_assert_int(rc, ==, 0); \ + open.filename = "test"; \ + open.vfs = ""; \ + ENCODE(c, &open, open); \ + HANDLE(c, OPEN); \ + ASSERT_CALLBACK(c, 0, DB); \ + DECODE(c, &db, db); \ + munit_assert_int(db.id, ==, 0); \ } #define TEAR_DOWN \ @@ -72,6 +76,7 @@ struct connection buffer__close(&c->request); \ buffer__close(&c->response); \ gateway__close(&c->gateway); \ + free(c->db_ctx); \ } \ TEAR_DOWN_CLUSTER; diff --git a/test/unit/test_conn.c b/test/unit/test_conn.c index 93e4a475c..c643c1b6a 100644 --- a/test/unit/test_conn.c +++ b/test/unit/test_conn.c @@ -17,6 +17,7 @@ #include "../../src/conn.h" #include "../../src/gateway.h" #include "../../src/lib/transport.h" +#include "../../src/revamp.h" #include "../../src/transport.h" TEST_MODULE(conn); @@ -41,7 +42,8 @@ static void connCloseCb(struct conn *conn) FIXTURE_RAFT; \ FIXTURE_CLIENT; \ struct conn conn; \ - bool closed; + bool closed; \ + struct db_context *db_ctx; #define SETUP \ struct uv_stream_s *stream; \ @@ -60,13 +62,15 @@ static void connCloseCb(struct conn *conn) rv = transport__stream(&f->loop, f->server, &stream); \ munit_assert_int(rv, ==, 0); \ f->closed = false; \ + f->db_ctx = munit_malloc(sizeof *f->db_ctx); \ f->conn.queue[0] = &f->closed; \ rv = conn__start(&f->conn, &f->config, &f->loop, &f->registry, \ &f->raft, stream, &f->raft_transport, seed, \ - connCloseCb); \ + connCloseCb, f->db_ctx); \ munit_assert_int(rv, ==, 0) #define TEAR_DOWN \ + free(f->db_ctx); \ conn__stop(&f->conn); \ while (!f->closed) { \ test_uv_run(&f->loop, 1); \ diff --git a/test/unit/test_gateway.c b/test/unit/test_gateway.c index 64c051f3c..a72a9cb16 100644 --- a/test/unit/test_gateway.c +++ b/test/unit/test_gateway.c @@ -2,6 +2,7 @@ #include "../../src/gateway.h" #include "../../src/request.h" #include "../../src/response.h" +#include "../../src/revamp.h" #include "../../src/tuple.h" #include "../lib/cluster.h" #include "../lib/raft_heap.h" @@ -34,6 +35,7 @@ struct connection struct cursor cursor; /* Response read cursor */ struct handle handle; /* Async handle request */ struct context context; + struct db_context *db_ctx; }; #define FIXTURE \ @@ -56,8 +58,9 @@ struct connection struct id_state seed = {{1}}; \ config = CLUSTER_CONFIG(i); \ config->page_size = 512; \ + c->db_ctx = munit_malloc(sizeof *c->db_ctx); \ gateway__init(&c->gateway, config, CLUSTER_REGISTRY(i), \ - CLUSTER_RAFT(i), seed); \ + CLUSTER_RAFT(i), seed, c->db_ctx); \ c->handle.data = &c->context; \ rc = buffer__init(&c->buf1); \ munit_assert_int(rc, ==, 0); \ @@ -75,6 +78,7 @@ struct connection gateway__close(&c->gateway); \ buffer__close(&c->buf1); \ buffer__close(&c->buf2); \ + free(c->db_ctx); \ } \ TEAR_DOWN_CLUSTER;