From: Aki Tuomi Date: Tue, 30 Sep 2025 12:32:12 +0000 (+0300) Subject: lib-sql: driver-sqlite - Stop transaction at first error X-Git-Tag: 2.4.2~47 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ef8a5c9b5707395659edd13f6fcdaea2bc1329c8;p=thirdparty%2Fdovecot%2Fcore.git lib-sql: driver-sqlite - Stop transaction at first error If the transaction has failed, refuse to execute any new queries. This prevents especially situations where BEGIN failed. --- diff --git a/src/lib-sql/driver-sqlite.c b/src/lib-sql/driver-sqlite.c index ef3913bf2e..36fe3ef1b4 100644 --- a/src/lib-sql/driver-sqlite.c +++ b/src/lib-sql/driver-sqlite.c @@ -661,9 +661,14 @@ driver_sqlite_transaction_exec(struct sqlite_transaction_context *ctx, const char *error; int rc; + /* We have already failed */ + if (!SQLITE_IS_OK(ctx->rc)) + return; + rc = driver_sqlite_exec_query(db, query, &error); if (!SQLITE_IS_OK(rc) && SQLITE_IS_OK(ctx->rc)) { /* first error in the transaction */ + i_assert(ctx->error == NULL); ctx->rc = rc; ctx->error = i_strdup(error); } @@ -695,6 +700,8 @@ driver_sqlite_transaction_rollback(struct sql_transaction_context *_ctx) add_str("error", "Rolled back")->event(), "Transaction rolled back"); } + ctx->rc = SQLITE_OK; + i_free(ctx->error); driver_sqlite_transaction_exec(ctx, "ROLLBACK"); event_unref(&_ctx->event); i_free(ctx->error); @@ -749,6 +756,8 @@ driver_sqlite_transaction_commit_s(struct sql_transaction_context *_ctx, return -1; } + ctx->rc = 0; + i_free(ctx->error); driver_sqlite_transaction_exec(ctx, "COMMIT"); if (!SQLITE_IS_OK(ctx->rc)) { e_debug(sql_transaction_finished_event(_ctx)->