Movatterモバイル変換


[0]ホーム

URL:


Google Git
Sign in
chromium /chromium /src /refs/heads/main /. /sql /statement_unittest.cc
blob: 795a9241757b90ff44c93f31045866b2e8b04fdb [file] [log] [blame]
Avi Drissman69b874f2022-09-15 19:11:14[diff] [blame]1// Copyright 2012 The Chromium Authors
brettw@chromium.orge5ffd0e42009-09-11 21:30:56[diff] [blame]2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Takuto Ikuta2eb61342024-05-10 09:05:35[diff] [blame]5#include"sql/statement.h"
6
7#include<cstdint>
Victor Costanc5c5fb02022-02-22 22:18:08[diff] [blame]8#include<limits>
cpu@chromium.orgfaa604e2009-09-25 22:38:59[diff] [blame]9#include<string>
Md Hasibul Hasan52ffeca62024-03-26 18:23:18[diff] [blame]10#include<string_view>
Takuto Ikuta2eb61342024-05-10 09:05:35[diff] [blame]11#include<vector>
cpu@chromium.orgfaa604e2009-09-25 22:38:59[diff] [blame]12
Ho Cheung47524352023-08-08 03:41:10[diff] [blame]13#include"base/containers/contains.h"
brettw@chromium.orgea1a3f62012-11-16 20:34:23[diff] [blame]14#include"base/files/scoped_temp_dir.h"
Evan Stade9728e5a2025-06-05 18:51:27[diff] [blame]15#include"base/strings/strcat.h"
16#include"base/strings/string_number_conversions.h"
17#include"base/strings/string_util.h"
Victor Costan87156832022-03-10 22:08:35[diff] [blame]18#include"base/test/bind.h"
Etienne Bergeronf969727a2023-12-15 19:40:34[diff] [blame]19#include"base/test/metrics/histogram_tester.h"
Victor Costancfbfa602018-08-01 23:24:46[diff] [blame]20#include"sql/database.h"
shess976814402016-06-21 06:56:25[diff] [blame]21#include"sql/test/scoped_error_expecter.h"
Anthony Vallée-Duboise3c94912024-12-12 16:47:47[diff] [blame]22#include"sql/test/test_helpers.h"
brettw@chromium.orge5ffd0e42009-09-11 21:30:56[diff] [blame]23#include"testing/gtest/include/gtest/gtest.h"
phajdan.jr@chromium.orge33cba42010-08-18 23:37:03[diff] [blame]24#include"third_party/sqlite/sqlite3.h"
brettw@chromium.orge5ffd0e42009-09-11 21:30:56[diff] [blame]25
Victor Costan49a903a2021-05-07 22:21:00[diff] [blame]26namespace sql{
pkotwicz@chromium.org49dc4f22012-10-17 17:41:16[diff] [blame]27namespace{
28
Victor Costane52ae372022-02-23 00:20:56[diff] [blame]29classStatementTest:public testing::Test{
Victor Costan49a903a2021-05-07 22:21:00[diff] [blame]30public:
Victor Costan49a903a2021-05-07 22:21:00[diff] [blame]31voidSetUp() override{
32 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
33 ASSERT_TRUE(
34 db_.Open(temp_dir_.GetPath().AppendASCII("statement_test.sqlite")));
35}
36
37protected:
38 base::ScopedTempDir temp_dir_;
Anthony Vallée-Duboise3c94912024-12-12 16:47:47[diff] [blame]39Database db_{test::kTestTag};
Victor Costan49a903a2021-05-07 22:21:00[diff] [blame]40};
pkotwicz@chromium.org49dc4f22012-10-17 17:41:16[diff] [blame]41
Victor Costane52ae372022-02-23 00:20:56[diff] [blame]42TEST_F(StatementTest,Assign){
43Statement create;
44 EXPECT_FALSE(create.is_valid());
brettw@chromium.orge5ffd0e42009-09-11 21:30:56[diff] [blame]45
Victor Costane52ae372022-02-23 00:20:56[diff] [blame]46 create.Assign(db_.GetUniqueStatement(
47"CREATE TABLE rows(a INTEGER PRIMARY KEY NOT NULL, b INTEGER NOT NULL)"));
48 EXPECT_TRUE(create.is_valid());
brettw@chromium.orge5ffd0e42009-09-11 21:30:56[diff] [blame]49}
50
Victor Costane52ae372022-02-23 00:20:56[diff] [blame]51TEST_F(StatementTest,Run){
52 ASSERT_TRUE(db_.Execute(
53"CREATE TABLE rows(a INTEGER PRIMARY KEY NOT NULL, b INTEGER NOT NULL)"));
54 ASSERT_TRUE(db_.Execute("INSERT INTO rows(a, b) VALUES(3, 12)"));
brettw@chromium.orge5ffd0e42009-09-11 21:30:56[diff] [blame]55
Victor Costane52ae372022-02-23 00:20:56[diff] [blame]56Statement select(db_.GetUniqueStatement("SELECT b FROM rows WHERE a=?"));
57 EXPECT_FALSE(select.Succeeded());
brettw@chromium.orge5ffd0e42009-09-11 21:30:56[diff] [blame]58
59// Stepping it won't work since we haven't bound the value.
Victor Costane52ae372022-02-23 00:20:56[diff] [blame]60 EXPECT_FALSE(select.Step());
brettw@chromium.orge5ffd0e42009-09-11 21:30:56[diff] [blame]61
62// Run should fail since this produces output, and we should use Step(). This
63// gets a bit wonky since sqlite says this is OK so succeeded is set.
Victor Costane52ae372022-02-23 00:20:56[diff] [blame]64 select.Reset(/*clear_bound_vars=*/true);
65 select.BindInt64(0,3);
66 EXPECT_FALSE(select.Run());
Victor Costan49a903a2021-05-07 22:21:00[diff] [blame]67 EXPECT_EQ(SQLITE_ROW, db_.GetErrorCode());
Victor Costane52ae372022-02-23 00:20:56[diff] [blame]68 EXPECT_TRUE(select.Succeeded());
brettw@chromium.orge5ffd0e42009-09-11 21:30:56[diff] [blame]69
70// Resetting it should put it back to the previous state (not runnable).
Victor Costane52ae372022-02-23 00:20:56[diff] [blame]71 select.Reset(/*clear_bound_vars=*/true);
72 EXPECT_FALSE(select.Succeeded());
brettw@chromium.orge5ffd0e42009-09-11 21:30:56[diff] [blame]73
74// Binding and stepping should produce one row.
Victor Costane52ae372022-02-23 00:20:56[diff] [blame]75 select.BindInt64(0,3);
76 EXPECT_TRUE(select.Step());
77 EXPECT_TRUE(select.Succeeded());
78 EXPECT_EQ(12, select.ColumnInt64(0));
79 EXPECT_FALSE(select.Step());
80 EXPECT_TRUE(select.Succeeded());
brettw@chromium.orge5ffd0e42009-09-11 21:30:56[diff] [blame]81}
cpu@chromium.orgfaa604e2009-09-25 22:38:59[diff] [blame]82
shess@chromium.org98cf3002013-07-12 01:38:56[diff] [blame]83// Error callback called for error running a statement.
Victor Costan87156832022-03-10 22:08:35[diff] [blame]84TEST_F(StatementTest,DatabaseErrorCallbackCalledOnError){
Victor Costane52ae372022-02-23 00:20:56[diff] [blame]85 ASSERT_TRUE(db_.Execute(
86"CREATE TABLE rows(a INTEGER PRIMARY KEY NOT NULL, b INTEGER NOT NULL)"));
shess@chromium.org98cf3002013-07-12 01:38:56[diff] [blame]87
Victor Costan87156832022-03-10 22:08:35[diff] [blame]88bool error_callback_called=false;
shess@chromium.org98cf3002013-07-12 01:38:56[diff] [blame]89int error= SQLITE_OK;
Victor Costan87156832022-03-10 22:08:35[diff] [blame]90 db_.set_error_callback(base::BindLambdaForTesting(
91[&](int sqlite_error, sql::Statement* statement){
92 error_callback_called=true;
93 error= sqlite_error;
94}));
shess@chromium.org98cf3002013-07-12 01:38:56[diff] [blame]95
Victor Costane52ae372022-02-23 00:20:56[diff] [blame]96// `rows` is a table with ROWID. https://www.sqlite.org/rowidtable.html
97// Since `a` is declared as INTEGER PRIMARY KEY, it is an alias for SQLITE's
98// rowid. This means `a` can only take on integer values. Attempting to insert
99// anything else causes the error callback handler to be called with
100// SQLITE_MISMATCH as error code.
101Statement insert(db_.GetUniqueStatement("INSERT INTO rows(a) VALUES(?)"));
Victor Costan87156832022-03-10 22:08:35[diff] [blame]102 ASSERT_TRUE(insert.is_valid());
Victor Costane52ae372022-02-23 00:20:56[diff] [blame]103 insert.BindString(0,"not an integer, not suitable as primary key value");
Victor Costan87156832022-03-10 22:08:35[diff] [blame]104 EXPECT_FALSE(insert.Run())
105<<"Invalid statement should not Run() successfully";
106 EXPECT_TRUE(error_callback_called)
107<<"Statement::Run() should report errors to the database error callback";
108 EXPECT_EQ(SQLITE_MISMATCH, error)
109<<"Statement::Run() should report errors to the database error callback";
shess@chromium.org98cf3002013-07-12 01:38:56[diff] [blame]110}
111
shess976814402016-06-21 06:56:25[diff] [blame]112// Error expecter works for error running a statement.
Victor Costane52ae372022-02-23 00:20:56[diff] [blame]113TEST_F(StatementTest,ScopedIgnoreError){
114 ASSERT_TRUE(db_.Execute(
115"CREATE TABLE rows(a INTEGER PRIMARY KEY NOT NULL, b INTEGER NOT NULL)"));
shess@chromium.org98cf3002013-07-12 01:38:56[diff] [blame]116
Victor Costane52ae372022-02-23 00:20:56[diff] [blame]117Statement insert(db_.GetUniqueStatement("INSERT INTO rows(a) VALUES(?)"));
118 EXPECT_TRUE(insert.is_valid());
119 insert.BindString(0,"not an integer, not suitable as primary key value");
shess@chromium.org98cf3002013-07-12 01:38:56[diff] [blame]120
shess976814402016-06-21 06:56:25[diff] [blame]121{
122 sql::test::ScopedErrorExpecter expecter;
123 expecter.ExpectError(SQLITE_MISMATCH);
Victor Costane52ae372022-02-23 00:20:56[diff] [blame]124 EXPECT_FALSE(insert.Run());
125 EXPECT_TRUE(expecter.SawExpectedErrors());
shess976814402016-06-21 06:56:25[diff] [blame]126}
cpu@chromium.orgfaa604e2009-09-25 22:38:59[diff] [blame]127}
michaelbai@chromium.org389e0a42012-04-25 21:36:41[diff] [blame]128
Victor Costane52ae372022-02-23 00:20:56[diff] [blame]129TEST_F(StatementTest,Reset){
130 ASSERT_TRUE(db_.Execute(
131"CREATE TABLE rows(a INTEGER PRIMARY KEY NOT NULL, b INTEGER NOT NULL)"));
132 ASSERT_TRUE(db_.Execute("INSERT INTO rows(a, b) VALUES(3, 12)"));
133 ASSERT_TRUE(db_.Execute("INSERT INTO rows(a, b) VALUES(4, 13)"));
michaelbai@chromium.org389e0a42012-04-25 21:36:41[diff] [blame]134
Victor Costane52ae372022-02-23 00:20:56[diff] [blame]135Statement insert(db_.GetUniqueStatement("SELECT b FROM rows WHERE a=?"));
136 insert.BindInt64(0,3);
137 ASSERT_TRUE(insert.Step());
138 EXPECT_EQ(12, insert.ColumnInt64(0));
139 ASSERT_FALSE(insert.Step());
michaelbai@chromium.org389e0a42012-04-25 21:36:41[diff] [blame]140
Victor Costane52ae372022-02-23 00:20:56[diff] [blame]141 insert.Reset(/*clear_bound_vars=*/false);
michaelbai@chromium.org389e0a42012-04-25 21:36:41[diff] [blame]142// Verify that we can get all rows again.
Victor Costane52ae372022-02-23 00:20:56[diff] [blame]143 ASSERT_TRUE(insert.Step());
144 EXPECT_EQ(12, insert.ColumnInt64(0));
145 EXPECT_FALSE(insert.Step());
michaelbai@chromium.org389e0a42012-04-25 21:36:41[diff] [blame]146
Victor Costane52ae372022-02-23 00:20:56[diff] [blame]147 insert.Reset(/*clear_bound_vars=*/true);
148 ASSERT_FALSE(insert.Step());
michaelbai@chromium.org389e0a42012-04-25 21:36:41[diff] [blame]149}
Victor Costan49a903a2021-05-07 22:21:00[diff] [blame]150
Victor Costane52ae372022-02-23 00:20:56[diff] [blame]151TEST_F(StatementTest,BindInt64){
Victor Costanc5c5fb02022-02-22 22:18:08[diff] [blame]152// `id` makes SQLite's rowid mechanism explicit. We rely on it to retrieve
153// the rows in the same order that they were inserted.
154 ASSERT_TRUE(db_.Execute(
155"CREATE TABLE ints(id INTEGER PRIMARY KEY, i INTEGER NOT NULL)"));
156
157const std::vector<int64_t> values={
158// Small positive values.
1590,
1601,
1612,
16210,
163101,
1641002,
165
166// Small negative values.
167-1,
168-2,
169-3,
170-10,
171-101,
172-1002,
173
174// Large values.
175 std::numeric_limits<int64_t>::max(),
176 std::numeric_limits<int64_t>::min(),
177};
178
179Statement insert(db_.GetUniqueStatement("INSERT INTO ints(i) VALUES(?)"));
180for(int64_t value: values){
181 insert.BindInt64(0, value);
182 ASSERT_TRUE(insert.Run());
Victor Costane52ae372022-02-23 00:20:56[diff] [blame]183 insert.Reset(/*clear_bound_vars=*/true);
Victor Costanc5c5fb02022-02-22 22:18:08[diff] [blame]184}
185
186Statement select(db_.GetUniqueStatement("SELECT i FROM ints ORDER BY id"));
187for(int64_t value: values){
188 ASSERT_TRUE(select.Step());
189int64_t column_value= select.ColumnInt64(0);
190 EXPECT_EQ(value, column_value);
191}
192}
193
194// Chrome features rely on being able to use uint64_t with ColumnInt64().
195// This is supported, because (starting in C++20) casting between signed and
196// unsigned integers is well-defined in both directions. This test ensures that
197// the casting works as expected.
Victor Costane52ae372022-02-23 00:20:56[diff] [blame]198TEST_F(StatementTest,BindInt64_FromUint64t){
Victor Costanc5c5fb02022-02-22 22:18:08[diff] [blame]199// `id` makes SQLite's rowid mechanism explicit. We rely on it to retrieve
200// the rows in the same order that they were inserted.
Victor Costane52ae372022-02-23 00:20:56[diff] [blame]201staticconstexprchar kSql[]=
202"CREATE TABLE ints(id INTEGER PRIMARY KEY NOT NULL, i INTEGER NOT NULL)";
203 ASSERT_TRUE(db_.Execute(kSql));
Victor Costanc5c5fb02022-02-22 22:18:08[diff] [blame]204
205const std::vector<uint64_t> values={
206// Small positive values.
2070,
2081,
2092,
21010,
211101,
2121002,
213
214// Large values.
215 std::numeric_limits<int64_t>::max()-1,
216 std::numeric_limits<int64_t>::max(),
217 std::numeric_limits<uint64_t>::max()-1,
218 std::numeric_limits<uint64_t>::max(),
219};
220
221Statement insert(db_.GetUniqueStatement("INSERT INTO ints(i) VALUES(?)"));
222for(uint64_t value: values){
223 insert.BindInt64(0,static_cast<int64_t>(value));
224 ASSERT_TRUE(insert.Run());
Victor Costane52ae372022-02-23 00:20:56[diff] [blame]225 insert.Reset(/*clear_bound_vars=*/true);
Victor Costanc5c5fb02022-02-22 22:18:08[diff] [blame]226}
227
228Statement select(db_.GetUniqueStatement("SELECT i FROM ints ORDER BY id"));
229for(uint64_t value: values){
230 ASSERT_TRUE(select.Step());
231int64_t column_value= select.ColumnInt64(0);
232uint64_t cast_column_value=static_cast<uint64_t>(column_value);
233 EXPECT_EQ(value, cast_column_value)<<" column_value: "<< column_value;
234}
235}
236
Victor Costane52ae372022-02-23 00:20:56[diff] [blame]237TEST_F(StatementTest,BindBlob){
238// `id` makes SQLite's rowid mechanism explicit. We rely on it to retrieve
239// the rows in the same order that they were inserted.
240 ASSERT_TRUE(db_.Execute(
241"CREATE TABLE blobs(id INTEGER PRIMARY KEY NOT NULL, b BLOB NOT NULL)"));
Victor Costan698ae04502021-07-08 07:31:09[diff] [blame]242
243const std::vector<std::vector<uint8_t>> values={
244{},
245{0x01},
246{0x41,0x42,0x43,0x44},
247};
248
Victor Costane52ae372022-02-23 00:20:56[diff] [blame]249Statement insert(db_.GetUniqueStatement("INSERT INTO blobs(b) VALUES(?)"));
Victor Costan698ae04502021-07-08 07:31:09[diff] [blame]250for(const std::vector<uint8_t>& value: values){
251 insert.BindBlob(0, value);
252 ASSERT_TRUE(insert.Run());
Victor Costane52ae372022-02-23 00:20:56[diff] [blame]253 insert.Reset(/*clear_bound_vars=*/true);
Victor Costan698ae04502021-07-08 07:31:09[diff] [blame]254}
255
Victor Costane52ae372022-02-23 00:20:56[diff] [blame]256Statement select(db_.GetUniqueStatement("SELECT b FROM blobs ORDER BY id"));
Victor Costan698ae04502021-07-08 07:31:09[diff] [blame]257for(const std::vector<uint8_t>& value: values){
258 ASSERT_TRUE(select.Step());
259 std::vector<uint8_t> column_value;
260 EXPECT_TRUE(select.ColumnBlobAsVector(0,&column_value));
261 EXPECT_EQ(value, column_value);
262}
263 EXPECT_FALSE(select.Step());
264}
265
Camillia Smith Barnesc39fce9a2023-04-24 21:00:39[diff] [blame]266TEST_F(StatementTest,BindBlob_String16Overload){
267// `id` makes SQLite's rowid mechanism explicit. We rely on it to retrieve
268// the rows in the same order that they were inserted.
269 ASSERT_TRUE(db_.Execute(
270"CREATE TABLE blobs(id INTEGER PRIMARY KEY NOT NULL, b BLOB NOT NULL)"));
271
272const std::vector<std::u16string> values={
273 std::u16string(), std::u16string(u"hello\n"), std::u16string(u"😀🍩🎉"),
274 std::u16string(u"\xd800\xdc00text"),// surrogate pair with text
275 std::u16string(u"\xd8ff"),// unpaired high surrogate
276 std::u16string(u"\xdddd"),// unpaired low surrogate
277 std::u16string(u"\xdc00\xd800text"),// lone low followed by lone high
278// surrogate and text
279 std::u16string(1024,0xdb23),// long invalid UTF-16
280};
281
282Statement insert(db_.GetUniqueStatement("INSERT INTO blobs(b) VALUES(?)"));
283for(const std::u16string& value: values){
284 insert.BindBlob(0, value);
285 ASSERT_TRUE(insert.Run());
286 insert.Reset(/*clear_bound_vars=*/true);
287}
288
289Statement select(db_.GetUniqueStatement("SELECT b FROM blobs ORDER BY id"));
290for(const std::u16string& value: values){
291 ASSERT_TRUE(select.Step());
292 std::u16string column_value;
293 EXPECT_TRUE(select.ColumnBlobAsString16(0,&column_value));
294 EXPECT_EQ(value, column_value);
295}
296 EXPECT_FALSE(select.Step());
297}
298
Evan Stade9728e5a2025-06-05 18:51:27[diff] [blame]299TEST_F(StatementTest,BlobStressTest){
300// Create a table that holds a whole lot of blobs. This could tickle
301// pointer-stability related bugs in the container that stores blob data
302// before it's being written.
303constint kMany=200;
304 std::string create_table_sql(
305"CREATE TABLE blobs(id INTEGER PRIMARY KEY NOT NULL ");
306for(int i=0; i< kMany;++i){
307 base::StrAppend(&create_table_sql,
308{", a", base::NumberToString(i)," BLOB NOT NULL"});
309}
310 create_table_sql.append(")");
311
312 ASSERT_TRUE(db_.Execute(create_table_sql));
313
314 std::vector<std::string> param_markers(kMany+1,"?");
315const std::string insert_sql=
316 base::StrCat({"INSERT INTO blobs VALUES(",
317 base::JoinString(param_markers,", "),")"});
318 sql::StatementID kInsertStatementId= SQL_FROM_HERE;
319{
320Statement insert(db_.GetCachedStatement(kInsertStatementId, insert_sql));
321// ID row.
322 insert.BindInt64(0,1);
323for(int i=0; i< kMany;++i){
324 insert.BindBlob(i+1, std::string(100,'a'+ i%26));
325}
326
327// Make sure overwriting a blob works as expected.
328 insert.BindBlob(50, std::string("overwrite"));
329 ASSERT_TRUE(insert.Run());
330}
331
332// Verify the blobs read out as expected.
333{
334Statement select(db_.GetUniqueStatement("SELECT * FROM blobs"));
335 ASSERT_TRUE(select.Step());
336 std::string output50, output51;
337 EXPECT_TRUE(select.ColumnBlobAsString(50,&output50));
338 EXPECT_EQ("overwrite", output50);
339 EXPECT_TRUE(select.ColumnBlobAsString(51,&output51));
340 EXPECT_EQ(std::string(100,'y'), output51);
341}
342
343// Make sure the underlying statement is reset i.e. the old bindings don't
344// persist across different invocations of `GetCachedStatement`.
345{
346Statement insert(db_.GetCachedStatement(kInsertStatementId,
347 base::cstring_view(insert_sql)));
348// ID row.
349 insert.BindInt64(0,2);
350 ASSERT_FALSE(insert.Run());
351}
352}
353
Victor Costane52ae372022-02-23 00:20:56[diff] [blame]354TEST_F(StatementTest,BindString){
355// `id` makes SQLite's rowid mechanism explicit. We rely on it to retrieve
356// the rows in the same order that they were inserted.
357 ASSERT_TRUE(db_.Execute(
358"CREATE TABLE texts(id INTEGER PRIMARY KEY NOT NULL, t TEXT NOT NULL)"));
Victor Costan543d1022021-07-08 16:23:16[diff] [blame]359
360const std::vector<std::string> values={
361"",
362"a",
363"\x01",
364 std::string("\x00",1),
365"abcd",
366"\x01\x02\x03\x04",
367 std::string("\x01Test",5),
368 std::string("\x00Test",5),
369};
370
Victor Costane52ae372022-02-23 00:20:56[diff] [blame]371Statement insert(db_.GetUniqueStatement("INSERT INTO texts(t) VALUES(?)"));
Victor Costan543d1022021-07-08 16:23:16[diff] [blame]372for(const std::string& value: values){
373 insert.BindString(0, value);
374 ASSERT_TRUE(insert.Run());
Victor Costane52ae372022-02-23 00:20:56[diff] [blame]375 insert.Reset(/*clear_bound_vars=*/true);
Victor Costan543d1022021-07-08 16:23:16[diff] [blame]376}
377
Andrew Paseltiner84724d92024-09-11 18:52:18[diff] [blame]378{
379Statement select(db_.GetUniqueStatement("SELECT t FROM texts ORDER BY id"));
380for(const std::string& value: values){
381 ASSERT_TRUE(select.Step());
382 EXPECT_EQ(value, select.ColumnString(0));
383}
384 EXPECT_FALSE(select.Step());
Victor Costan543d1022021-07-08 16:23:16[diff] [blame]385}
Andrew Paseltiner84724d92024-09-11 18:52:18[diff] [blame]386
387{
388Statement select(db_.GetUniqueStatement("SELECT t FROM texts ORDER BY id"));
389for(const std::string& value: values){
390 ASSERT_TRUE(select.Step());
391 EXPECT_EQ(value, select.ColumnStringView(0));
392}
393 EXPECT_FALSE(select.Step());
394}
Victor Costan543d1022021-07-08 16:23:16[diff] [blame]395}
396
Victor Costane52ae372022-02-23 00:20:56[diff] [blame]397TEST_F(StatementTest,BindString_NullData){
398// `id` makes SQLite's rowid mechanism explicit. We rely on it to retrieve
399// the rows in the same order that they were inserted.
400 ASSERT_TRUE(db_.Execute(
401"CREATE TABLE texts(id INTEGER PRIMARY KEY NOT NULL, t TEXT NOT NULL)"));
Victor Costan827a1412021-07-08 20:53:45[diff] [blame]402
Victor Costane52ae372022-02-23 00:20:56[diff] [blame]403Statement insert(db_.GetUniqueStatement("INSERT INTO texts(t) VALUES(?)"));
Md Hasibul Hasan52ffeca62024-03-26 18:23:18[diff] [blame]404 insert.BindString(0, std::string_view(nullptr,0));
Victor Costan827a1412021-07-08 20:53:45[diff] [blame]405 ASSERT_TRUE(insert.Run());
406
Victor Costane52ae372022-02-23 00:20:56[diff] [blame]407Statement select(db_.GetUniqueStatement("SELECT t FROM texts ORDER BY id"));
Victor Costan827a1412021-07-08 20:53:45[diff] [blame]408 ASSERT_TRUE(select.Step());
409 EXPECT_EQ(std::string(), select.ColumnString(0));
410
411 EXPECT_FALSE(select.Step());
412}
413
Tommy C. Li7803636c2022-07-27 21:47:22[diff] [blame]414TEST_F(StatementTest,GetSQLStatementExcludesBoundValues){
415 ASSERT_TRUE(db_.Execute(
416"CREATE TABLE texts(id INTEGER PRIMARY KEY NOT NULL, t TEXT NOT NULL)"));
417
418Statement insert(db_.GetUniqueStatement("INSERT INTO texts(t) VALUES(?)"));
419 insert.BindString(0,"John Doe");
420 ASSERT_TRUE(insert.Run());
421
422// Verify that GetSQLStatement doesn't leak any bound values that may be PII.
Ho Cheung47524352023-08-08 03:41:10[diff] [blame]423 std::string sql_statement= insert.GetSQLStatement();
424 EXPECT_TRUE(base::Contains(sql_statement,"INSERT INTO texts(t) VALUES(?)"));
425 EXPECT_TRUE(base::Contains(sql_statement,"VALUES"));
426 EXPECT_FALSE(base::Contains(sql_statement,"Doe"));
Tommy C. Li7803636c2022-07-27 21:47:22[diff] [blame]427
428// Sanity check that the name was actually committed.
429Statement select(db_.GetUniqueStatement("SELECT t FROM texts ORDER BY id"));
430 ASSERT_TRUE(select.Step());
431 EXPECT_EQ(select.ColumnString(0),"John Doe");
432}
433
Etienne Bergeronf969727a2023-12-15 19:40:34[diff] [blame]434TEST_F(StatementTest,RunReportsPerformanceMetrics){
435 base::HistogramTester histogram_tester;
436
437 ASSERT_TRUE(db_.Execute(
438"CREATE TABLE rows(a INTEGER PRIMARY KEY NOT NULL, b INTEGER NOT NULL)"));
439 ASSERT_TRUE(db_.Execute("INSERT INTO rows(a, b) VALUES(12, 42)"));
440
441 histogram_tester.ExpectTotalCount("Sql.Statement.Test.VMSteps",0);
442
443{
444Statement select(db_.GetUniqueStatement("SELECT b FROM rows WHERE a=?"));
445 select.BindInt64(0,12);
446 ASSERT_TRUE(select.Step());
447 EXPECT_EQ(select.ColumnInt64(0),42);
448}
449
450 histogram_tester.ExpectTotalCount("Sql.Statement.Test.VMSteps",1);
451}
452
Victor Costan49a903a2021-05-07 22:21:00[diff] [blame]453}// namespace
454}// namespace sql

[8]ページ先頭

©2009-2025 Movatter.jp