From 92d55d8ab29001402882e380eff01ab60135f16b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guilherme=20Ara=C3=BAjo?= Date: Fri, 17 Apr 2026 14:18:57 -0300 Subject: [PATCH] sqlite: cache column names in StatementSync::All() and Get() --- src/node_sqlite.cc | 66 ++++++++++++++++------------------------------ src/node_sqlite.h | 6 ++--- 2 files changed, 25 insertions(+), 47 deletions(-) diff --git a/src/node_sqlite.cc b/src/node_sqlite.cc index 4d1a35d753230a..5837027a7c83b3 100644 --- a/src/node_sqlite.cc +++ b/src/node_sqlite.cc @@ -2836,18 +2836,24 @@ Maybe ExtractRowValues(Environment* env, } MaybeLocal StatementExecutionHelper::All(Environment* env, - DatabaseSync* db, - sqlite3_stmt* stmt, + StatementSync* sync_stmt, bool return_arrays, bool use_big_ints) { Isolate* isolate = env->isolate(); EscapableHandleScope scope(isolate); int r; + sqlite3_stmt* stmt = sync_stmt->statement_; int num_cols = sqlite3_column_count(stmt); LocalVector rows(isolate); LocalVector row_values(isolate); LocalVector row_keys(isolate); + if (!return_arrays && num_cols > 0) { + if (!sync_stmt->GetCachedColumnNames(&row_keys)) { + return MaybeLocal(); + } + } + while ((r = sqlite3_step(stmt)) == SQLITE_ROW) { if (ExtractRowValues(env, stmt, num_cols, use_big_ints, &row_values) .IsNothing()) { @@ -2859,16 +2865,6 @@ MaybeLocal StatementExecutionHelper::All(Environment* env, Array::New(isolate, row_values.data(), row_values.size()); rows.emplace_back(row_array); } else { - if (row_keys.size() == 0) { - row_keys.reserve(num_cols); - for (int i = 0; i < num_cols; ++i) { - Local key; - if (!ColumnNameToName(env, stmt, i).ToLocal(&key)) { - return MaybeLocal(); - } - row_keys.emplace_back(key); - } - } DCHECK_EQ(row_keys.size(), row_values.size()); Local row_obj = Object::New( isolate, Null(isolate), row_keys.data(), row_values.data(), num_cols); @@ -2876,7 +2872,8 @@ MaybeLocal StatementExecutionHelper::All(Environment* env, } } - CHECK_ERROR_OR_THROW(isolate, db, r, SQLITE_DONE, MaybeLocal()); + CHECK_ERROR_OR_THROW( + isolate, sync_stmt->db_.get(), r, SQLITE_DONE, MaybeLocal()); return scope.Escape(Array::New(isolate, rows.data(), rows.size())); } @@ -2956,18 +2953,18 @@ BaseObjectPtr StatementExecutionHelper::Iterate( } MaybeLocal StatementExecutionHelper::Get(Environment* env, - DatabaseSync* db, - sqlite3_stmt* stmt, + StatementSync* sync_stmt, bool return_arrays, bool use_big_ints) { Isolate* isolate = env->isolate(); EscapableHandleScope scope(isolate); + sqlite3_stmt* stmt = sync_stmt->statement_; auto reset = OnScopeLeave([&]() { sqlite3_reset(stmt); }); int r = sqlite3_step(stmt); if (r == SQLITE_DONE) return scope.Escape(Undefined(isolate)); if (r != SQLITE_ROW) { - THROW_ERR_SQLITE_ERROR(isolate, db); + THROW_ERR_SQLITE_ERROR(isolate, sync_stmt->db_.get()); return MaybeLocal(); } @@ -2987,13 +2984,8 @@ MaybeLocal StatementExecutionHelper::Get(Environment* env, Array::New(isolate, row_values.data(), row_values.size())); } else { LocalVector keys(isolate); - keys.reserve(num_cols); - for (int i = 0; i < num_cols; ++i) { - Local key; - if (!ColumnNameToName(env, stmt, i).ToLocal(&key)) { - return MaybeLocal(); - } - keys.emplace_back(key); + if (!sync_stmt->GetCachedColumnNames(&keys)) { + return MaybeLocal(); } DCHECK_EQ(keys.size(), row_values.size()); @@ -3019,11 +3011,8 @@ void StatementSync::All(const FunctionCallbackInfo& args) { auto reset = OnScopeLeave([&]() { sqlite3_reset(stmt->statement_); }); Local result; - if (StatementExecutionHelper::All(env, - stmt->db_.get(), - stmt->statement_, - stmt->return_arrays_, - stmt->use_big_ints_) + if (StatementExecutionHelper::All( + env, stmt, stmt->return_arrays_, stmt->use_big_ints_) .ToLocal(&result)) { args.GetReturnValue().Set(result); } @@ -3066,11 +3055,8 @@ void StatementSync::Get(const FunctionCallbackInfo& args) { } Local result; - if (StatementExecutionHelper::Get(env, - stmt->db_.get(), - stmt->statement_, - stmt->return_arrays_, - stmt->use_big_ints_) + if (StatementExecutionHelper::Get( + env, stmt, stmt->return_arrays_, stmt->use_big_ints_) .ToLocal(&result)) { args.GetReturnValue().Set(result); } @@ -3425,11 +3411,8 @@ void SQLTagStore::Get(const FunctionCallbackInfo& args) { } Local result; - if (StatementExecutionHelper::Get(env, - stmt->db_.get(), - stmt->statement_, - stmt->return_arrays_, - stmt->use_big_ints_) + if (StatementExecutionHelper::Get( + env, stmt.get(), stmt->return_arrays_, stmt->use_big_ints_) .ToLocal(&result)) { args.GetReturnValue().Set(result); } @@ -3465,11 +3448,8 @@ void SQLTagStore::All(const FunctionCallbackInfo& args) { auto reset = OnScopeLeave([&]() { sqlite3_reset(stmt->statement_); }); Local result; - if (StatementExecutionHelper::All(env, - stmt->db_.get(), - stmt->statement_, - stmt->return_arrays_, - stmt->use_big_ints_) + if (StatementExecutionHelper::All( + env, stmt.get(), stmt->return_arrays_, stmt->use_big_ints_) .ToLocal(&result)) { args.GetReturnValue().Set(result); } diff --git a/src/node_sqlite.h b/src/node_sqlite.h index e7281ed266af5d..b0c0eff4f9bd9a 100644 --- a/src/node_sqlite.h +++ b/src/node_sqlite.h @@ -137,8 +137,7 @@ class BackupJob; class StatementExecutionHelper { public: static v8::MaybeLocal All(Environment* env, - DatabaseSync* db, - sqlite3_stmt* stmt, + StatementSync* stmt, bool return_arrays, bool use_big_ints); static v8::MaybeLocal Run(Environment* env, @@ -155,8 +154,7 @@ class StatementExecutionHelper { sqlite3_stmt* stmt, const int column); static v8::MaybeLocal Get(Environment* env, - DatabaseSync* db, - sqlite3_stmt* stmt, + StatementSync* stmt, bool return_arrays, bool use_big_ints); };