TestSqlStatementExecution.cpp 41 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085
  1. /*
  2. * Copyright (c) 2021, Jan de Visser <jan@de-visser.net>
  3. * Copyright (c) 2021, Mahmoud Mandour <ma.mandourr@gmail.com>
  4. *
  5. * SPDX-License-Identifier: BSD-2-Clause
  6. */
  7. #include <unistd.h>
  8. #include <AK/QuickSort.h>
  9. #include <AK/ScopeGuard.h>
  10. #include <LibSQL/AST/Parser.h>
  11. #include <LibSQL/Database.h>
  12. #include <LibSQL/Result.h>
  13. #include <LibSQL/ResultSet.h>
  14. #include <LibSQL/Row.h>
  15. #include <LibSQL/Value.h>
  16. #include <LibTest/TestCase.h>
  17. namespace {
  18. constexpr char const* db_name = "/tmp/test.db";
  19. SQL::ResultOr<SQL::ResultSet> try_execute(NonnullRefPtr<SQL::Database> database, DeprecatedString const& sql, Vector<SQL::Value> placeholder_values = {})
  20. {
  21. auto parser = SQL::AST::Parser(SQL::AST::Lexer(sql));
  22. auto statement = parser.next_statement();
  23. EXPECT(!parser.has_errors());
  24. if (parser.has_errors())
  25. outln("{}", parser.errors()[0].to_deprecated_string());
  26. return statement->execute(move(database), placeholder_values);
  27. }
  28. SQL::ResultSet execute(NonnullRefPtr<SQL::Database> database, DeprecatedString const& sql, Vector<SQL::Value> placeholder_values = {})
  29. {
  30. auto result = try_execute(move(database), sql, move(placeholder_values));
  31. if (result.is_error()) {
  32. outln("{}", result.release_error().error_string());
  33. VERIFY_NOT_REACHED();
  34. }
  35. return result.release_value();
  36. }
  37. template<typename... Args>
  38. Vector<SQL::Value> placeholders(Args&&... args)
  39. {
  40. return { SQL::Value(forward<Args>(args))... };
  41. }
  42. void create_schema(NonnullRefPtr<SQL::Database> database)
  43. {
  44. auto result = execute(database, "CREATE SCHEMA TestSchema;");
  45. EXPECT_EQ(result.command(), SQL::SQLCommand::Create);
  46. }
  47. void create_table(NonnullRefPtr<SQL::Database> database)
  48. {
  49. create_schema(database);
  50. auto result = execute(database, "CREATE TABLE TestSchema.TestTable ( TextColumn text, IntColumn integer );");
  51. EXPECT_EQ(result.command(), SQL::SQLCommand::Create);
  52. }
  53. void create_two_tables(NonnullRefPtr<SQL::Database> database)
  54. {
  55. create_schema(database);
  56. auto result = execute(database, "CREATE TABLE TestSchema.TestTable1 ( TextColumn1 text, IntColumn integer );");
  57. EXPECT_EQ(result.command(), SQL::SQLCommand::Create);
  58. result = execute(database, "CREATE TABLE TestSchema.TestTable2 ( TextColumn2 text, IntColumn integer );");
  59. EXPECT_EQ(result.command(), SQL::SQLCommand::Create);
  60. }
  61. TEST_CASE(create_schema)
  62. {
  63. ScopeGuard guard([]() { unlink(db_name); });
  64. auto database = SQL::Database::construct(db_name);
  65. EXPECT(!database->open().is_error());
  66. create_schema(database);
  67. auto schema_or_error = database->get_schema("TESTSCHEMA");
  68. EXPECT(!schema_or_error.is_error());
  69. }
  70. TEST_CASE(create_table)
  71. {
  72. ScopeGuard guard([]() { unlink(db_name); });
  73. auto database = SQL::Database::construct(db_name);
  74. EXPECT(!database->open().is_error());
  75. create_table(database);
  76. auto table_or_error = database->get_table("TESTSCHEMA", "TESTTABLE");
  77. EXPECT(!table_or_error.is_error());
  78. }
  79. TEST_CASE(insert_into_table)
  80. {
  81. ScopeGuard guard([]() { unlink(db_name); });
  82. auto database = SQL::Database::construct(db_name);
  83. EXPECT(!database->open().is_error());
  84. create_table(database);
  85. auto result = execute(database, "INSERT INTO TestSchema.TestTable ( TextColumn, IntColumn ) VALUES ( 'Test', 42 );");
  86. EXPECT(result.size() == 1);
  87. auto table = MUST(database->get_table("TESTSCHEMA", "TESTTABLE"));
  88. int count = 0;
  89. auto rows_or_error = database->select_all(*table);
  90. EXPECT(!rows_or_error.is_error());
  91. for (auto& row : rows_or_error.value()) {
  92. EXPECT_EQ(row["TEXTCOLUMN"].to_deprecated_string(), "Test");
  93. EXPECT_EQ(row["INTCOLUMN"].to_int<i32>(), 42);
  94. count++;
  95. }
  96. EXPECT_EQ(count, 1);
  97. }
  98. TEST_CASE(insert_into_table_wrong_data_types)
  99. {
  100. ScopeGuard guard([]() { unlink(db_name); });
  101. auto database = SQL::Database::construct(db_name);
  102. EXPECT(!database->open().is_error());
  103. create_table(database);
  104. auto result = try_execute(database, "INSERT INTO TestSchema.TestTable ( TextColumn, IntColumn ) VALUES (43, 'Test_2');");
  105. EXPECT(result.is_error());
  106. EXPECT(result.release_error().error() == SQL::SQLErrorCode::InvalidValueType);
  107. }
  108. TEST_CASE(insert_into_table_multiple_tuples_wrong_data_types)
  109. {
  110. ScopeGuard guard([]() { unlink(db_name); });
  111. auto database = SQL::Database::construct(db_name);
  112. EXPECT(!database->open().is_error());
  113. create_table(database);
  114. auto result = try_execute(database, "INSERT INTO TestSchema.TestTable ( TextColumn, IntColumn ) VALUES ('Test_1', 42), (43, 'Test_2');");
  115. EXPECT(result.is_error());
  116. EXPECT(result.release_error().error() == SQL::SQLErrorCode::InvalidValueType);
  117. }
  118. TEST_CASE(insert_wrong_number_of_values)
  119. {
  120. ScopeGuard guard([]() { unlink(db_name); });
  121. auto database = SQL::Database::construct(db_name);
  122. EXPECT(!database->open().is_error());
  123. create_table(database);
  124. auto result = try_execute(database, "INSERT INTO TestSchema.TestTable VALUES ( 42 );");
  125. EXPECT(result.is_error());
  126. EXPECT(result.release_error().error() == SQL::SQLErrorCode::InvalidNumberOfValues);
  127. }
  128. TEST_CASE(insert_identifier_as_value)
  129. {
  130. ScopeGuard guard([]() { unlink(db_name); });
  131. auto database = SQL::Database::construct(db_name);
  132. EXPECT(!database->open().is_error());
  133. create_table(database);
  134. auto result = try_execute(database, "INSERT INTO TestSchema.TestTable VALUES ( identifier, 42 );");
  135. EXPECT(result.is_error());
  136. EXPECT(result.release_error().error() == SQL::SQLErrorCode::SyntaxError);
  137. }
  138. TEST_CASE(insert_quoted_identifier_as_value)
  139. {
  140. ScopeGuard guard([]() { unlink(db_name); });
  141. auto database = SQL::Database::construct(db_name);
  142. EXPECT(!database->open().is_error());
  143. create_table(database);
  144. auto result = try_execute(database, "INSERT INTO TestSchema.TestTable VALUES ( \"QuotedIdentifier\", 42 );");
  145. EXPECT(result.is_error());
  146. EXPECT(result.release_error().error() == SQL::SQLErrorCode::SyntaxError);
  147. }
  148. TEST_CASE(insert_without_column_names)
  149. {
  150. ScopeGuard guard([]() { unlink(db_name); });
  151. auto database = SQL::Database::construct(db_name);
  152. EXPECT(!database->open().is_error());
  153. create_table(database);
  154. auto result = execute(database, "INSERT INTO TestSchema.TestTable VALUES ('Test_1', 42), ('Test_2', 43);");
  155. EXPECT(result.size() == 2);
  156. auto table = MUST(database->get_table("TESTSCHEMA", "TESTTABLE"));
  157. auto rows_or_error = database->select_all(*table);
  158. EXPECT(!rows_or_error.is_error());
  159. EXPECT_EQ(rows_or_error.value().size(), 2u);
  160. }
  161. TEST_CASE(insert_with_placeholders)
  162. {
  163. ScopeGuard guard([]() { unlink(db_name); });
  164. auto database = SQL::Database::construct(db_name);
  165. EXPECT(!database->open().is_error());
  166. create_table(database);
  167. {
  168. auto result = try_execute(database, "INSERT INTO TestSchema.TestTable VALUES (?, ?);");
  169. EXPECT(result.is_error());
  170. EXPECT_EQ(result.error().error(), SQL::SQLErrorCode::InvalidNumberOfPlaceholderValues);
  171. result = try_execute(database, "INSERT INTO TestSchema.TestTable VALUES (?, ?);", placeholders("Test_1"sv));
  172. EXPECT(result.is_error());
  173. EXPECT_EQ(result.error().error(), SQL::SQLErrorCode::InvalidNumberOfPlaceholderValues);
  174. result = try_execute(database, "INSERT INTO TestSchema.TestTable VALUES (?, ?);", placeholders(42, 42));
  175. EXPECT(result.is_error());
  176. EXPECT_EQ(result.error().error(), SQL::SQLErrorCode::InvalidValueType);
  177. result = try_execute(database, "INSERT INTO TestSchema.TestTable VALUES (?, ?);", placeholders("Test_1"sv, "Test_2"sv));
  178. EXPECT(result.is_error());
  179. EXPECT_EQ(result.error().error(), SQL::SQLErrorCode::InvalidValueType);
  180. }
  181. {
  182. auto result = execute(database, "INSERT INTO TestSchema.TestTable VALUES (?, ?);", placeholders("Test_1"sv, 42));
  183. EXPECT_EQ(result.size(), 1u);
  184. result = execute(database, "SELECT TextColumn, IntColumn FROM TestSchema.TestTable ORDER BY TextColumn;");
  185. EXPECT_EQ(result.size(), 1u);
  186. EXPECT_EQ(result[0].row[0], "Test_1"sv);
  187. EXPECT_EQ(result[0].row[1], 42);
  188. }
  189. {
  190. auto result = execute(database, "INSERT INTO TestSchema.TestTable VALUES (?, ?), (?, ?);", placeholders("Test_2"sv, 43, "Test_3"sv, 44));
  191. EXPECT_EQ(result.size(), 2u);
  192. result = execute(database, "SELECT TextColumn, IntColumn FROM TestSchema.TestTable ORDER BY TextColumn;");
  193. EXPECT_EQ(result.size(), 3u);
  194. EXPECT_EQ(result[0].row[0], "Test_1"sv);
  195. EXPECT_EQ(result[0].row[1], 42);
  196. EXPECT_EQ(result[1].row[0], "Test_2"sv);
  197. EXPECT_EQ(result[1].row[1], 43);
  198. EXPECT_EQ(result[2].row[0], "Test_3"sv);
  199. EXPECT_EQ(result[2].row[1], 44);
  200. }
  201. }
  202. TEST_CASE(insert_and_retrieve_long_text_value)
  203. {
  204. ScopeGuard guard([]() { unlink(db_name); });
  205. auto database = SQL::Database::construct(db_name);
  206. EXPECT(!database->open().is_error());
  207. create_table(database);
  208. StringBuilder sb;
  209. MUST(sb.try_append_repeated('x', 8192));
  210. auto long_string = sb.string_view();
  211. auto result = execute(database, DeprecatedString::formatted("INSERT INTO TestSchema.TestTable VALUES ('{}', 0);", long_string));
  212. EXPECT(result.size() == 1);
  213. result = execute(database, "SELECT TextColumn FROM TestSchema.TestTable;");
  214. EXPECT_EQ(result.size(), 1u);
  215. EXPECT_EQ(result[0].row[0], long_string);
  216. }
  217. TEST_CASE(select_from_empty_table)
  218. {
  219. ScopeGuard guard([]() { unlink(db_name); });
  220. auto database = SQL::Database::construct(db_name);
  221. EXPECT(!database->open().is_error());
  222. create_table(database);
  223. auto result = execute(database, "SELECT * FROM TestSchema.TestTable;");
  224. EXPECT(result.is_empty());
  225. }
  226. TEST_CASE(select_from_table)
  227. {
  228. ScopeGuard guard([]() { unlink(db_name); });
  229. auto database = SQL::Database::construct(db_name);
  230. EXPECT(!database->open().is_error());
  231. create_table(database);
  232. auto result = execute(database,
  233. "INSERT INTO TestSchema.TestTable ( TextColumn, IntColumn ) VALUES "
  234. "( 'Test_1', 42 ), "
  235. "( 'Test_2', 43 ), "
  236. "( 'Test_3', 44 ), "
  237. "( 'Test_4', 45 ), "
  238. "( 'Test_5', 46 );");
  239. EXPECT(result.size() == 5);
  240. result = execute(database, "SELECT * FROM TestSchema.TestTable;");
  241. EXPECT_EQ(result.size(), 5u);
  242. }
  243. TEST_CASE(select_with_column_names)
  244. {
  245. ScopeGuard guard([]() { unlink(db_name); });
  246. auto database = SQL::Database::construct(db_name);
  247. EXPECT(!database->open().is_error());
  248. create_table(database);
  249. auto result = execute(database,
  250. "INSERT INTO TestSchema.TestTable ( TextColumn, IntColumn ) VALUES "
  251. "( 'Test_1', 42 ), "
  252. "( 'Test_2', 43 ), "
  253. "( 'Test_3', 44 ), "
  254. "( 'Test_4', 45 ), "
  255. "( 'Test_5', 46 );");
  256. EXPECT(result.size() == 5);
  257. result = execute(database, "SELECT TextColumn FROM TestSchema.TestTable;");
  258. EXPECT_EQ(result.size(), 5u);
  259. EXPECT_EQ(result[0].row.size(), 1u);
  260. }
  261. TEST_CASE(select_with_nonexisting_column_name)
  262. {
  263. ScopeGuard guard([]() { unlink(db_name); });
  264. auto database = SQL::Database::construct(db_name);
  265. EXPECT(!database->open().is_error());
  266. create_table(database);
  267. auto result = execute(database,
  268. "INSERT INTO TestSchema.TestTable ( TextColumn, IntColumn ) VALUES "
  269. "( 'Test_1', 42 ), "
  270. "( 'Test_2', 43 ), "
  271. "( 'Test_3', 44 ), "
  272. "( 'Test_4', 45 ), "
  273. "( 'Test_5', 46 );");
  274. EXPECT(result.size() == 5);
  275. auto insert_result = try_execute(database, "SELECT Bogus FROM TestSchema.TestTable;");
  276. EXPECT(insert_result.is_error());
  277. EXPECT(insert_result.release_error().error() == SQL::SQLErrorCode::ColumnDoesNotExist);
  278. }
  279. TEST_CASE(select_with_where)
  280. {
  281. ScopeGuard guard([]() { unlink(db_name); });
  282. auto database = SQL::Database::construct(db_name);
  283. EXPECT(!database->open().is_error());
  284. create_table(database);
  285. auto result = execute(database,
  286. "INSERT INTO TestSchema.TestTable ( TextColumn, IntColumn ) VALUES "
  287. "( 'Test_1', 42 ), "
  288. "( 'Test_2', 43 ), "
  289. "( 'Test_3', 44 ), "
  290. "( 'Test_4', 45 ), "
  291. "( 'Test_5', 46 );");
  292. EXPECT(result.size() == 5);
  293. result = execute(database, "SELECT TextColumn, IntColumn FROM TestSchema.TestTable WHERE IntColumn > 44;");
  294. EXPECT_EQ(result.size(), 2u);
  295. for (auto& row : result) {
  296. EXPECT(row.row[1].to_int<i32>().value() > 44);
  297. }
  298. }
  299. TEST_CASE(select_cross_join)
  300. {
  301. ScopeGuard guard([]() { unlink(db_name); });
  302. auto database = SQL::Database::construct(db_name);
  303. EXPECT(!database->open().is_error());
  304. create_two_tables(database);
  305. auto result = execute(database,
  306. "INSERT INTO TestSchema.TestTable1 ( TextColumn1, IntColumn ) VALUES "
  307. "( 'Test_1', 42 ), "
  308. "( 'Test_2', 43 ), "
  309. "( 'Test_3', 44 ), "
  310. "( 'Test_4', 45 ), "
  311. "( 'Test_5', 46 );");
  312. EXPECT(result.size() == 5);
  313. result = execute(database,
  314. "INSERT INTO TestSchema.TestTable2 ( TextColumn2, IntColumn ) VALUES "
  315. "( 'Test_10', 40 ), "
  316. "( 'Test_11', 41 ), "
  317. "( 'Test_12', 42 ), "
  318. "( 'Test_13', 47 ), "
  319. "( 'Test_14', 48 );");
  320. EXPECT(result.size() == 5);
  321. result = execute(database, "SELECT * FROM TestSchema.TestTable1, TestSchema.TestTable2;");
  322. EXPECT_EQ(result.size(), 25u);
  323. for (auto& row : result) {
  324. EXPECT(row.row.size() == 4);
  325. EXPECT(row.row[1].to_int<i32>().value() >= 42);
  326. EXPECT(row.row[1].to_int<i32>().value() <= 46);
  327. EXPECT(row.row[3].to_int<i32>().value() >= 40);
  328. EXPECT(row.row[3].to_int<i32>().value() <= 48);
  329. }
  330. }
  331. TEST_CASE(select_inner_join)
  332. {
  333. ScopeGuard guard([]() { unlink(db_name); });
  334. auto database = SQL::Database::construct(db_name);
  335. EXPECT(!database->open().is_error());
  336. create_two_tables(database);
  337. auto result = execute(database,
  338. "INSERT INTO TestSchema.TestTable1 ( TextColumn1, IntColumn ) VALUES "
  339. "( 'Test_1', 42 ), "
  340. "( 'Test_2', 43 ), "
  341. "( 'Test_3', 44 ), "
  342. "( 'Test_4', 45 ), "
  343. "( 'Test_5', 46 );");
  344. EXPECT(result.size() == 5);
  345. result = execute(database,
  346. "INSERT INTO TestSchema.TestTable2 ( TextColumn2, IntColumn ) VALUES "
  347. "( 'Test_10', 40 ), "
  348. "( 'Test_11', 41 ), "
  349. "( 'Test_12', 42 ), "
  350. "( 'Test_13', 47 ), "
  351. "( 'Test_14', 48 );");
  352. EXPECT(result.size() == 5);
  353. result = execute(database,
  354. "SELECT TestTable1.IntColumn, TextColumn1, TextColumn2 "
  355. "FROM TestSchema.TestTable1, TestSchema.TestTable2 "
  356. "WHERE TestTable1.IntColumn = TestTable2.IntColumn;");
  357. EXPECT_EQ(result.size(), 1u);
  358. EXPECT_EQ(result[0].row.size(), 3u);
  359. EXPECT_EQ(result[0].row[0].to_int<i32>(), 42);
  360. EXPECT_EQ(result[0].row[1].to_deprecated_string(), "Test_1");
  361. EXPECT_EQ(result[0].row[2].to_deprecated_string(), "Test_12");
  362. }
  363. TEST_CASE(select_with_like)
  364. {
  365. ScopeGuard guard([]() { unlink(db_name); });
  366. auto database = SQL::Database::construct(db_name);
  367. EXPECT(!database->open().is_error());
  368. create_table(database);
  369. auto result = execute(database,
  370. "INSERT INTO TestSchema.TestTable ( TextColumn, IntColumn ) VALUES "
  371. "( 'Test+1', 42 ), "
  372. "( 'Test+2', 43 ), "
  373. "( 'Test+3', 44 ), "
  374. "( 'Test+4', 45 ), "
  375. "( 'Test+5', 46 ), "
  376. "( 'Another+Test_6', 47 );");
  377. EXPECT(result.size() == 6);
  378. // Simple match
  379. result = execute(database, "SELECT TextColumn FROM TestSchema.TestTable WHERE TextColumn LIKE 'Test+1';");
  380. EXPECT_EQ(result.size(), 1u);
  381. // Use % to match most rows
  382. result = execute(database, "SELECT TextColumn FROM TestSchema.TestTable WHERE TextColumn LIKE 'T%';");
  383. EXPECT_EQ(result.size(), 5u);
  384. // Same as above but invert the match
  385. result = execute(database, "SELECT TextColumn FROM TestSchema.TestTable WHERE TextColumn NOT LIKE 'T%';");
  386. EXPECT_EQ(result.size(), 1u);
  387. // Use _ and % to match all rows
  388. result = execute(database, "SELECT TextColumn FROM TestSchema.TestTable WHERE TextColumn LIKE '%e_t%';");
  389. EXPECT_EQ(result.size(), 6u);
  390. // Use escape to match a single row. The escape character happens to be a
  391. // Regex metacharacter, let's make sure we don't get confused by that.
  392. result = execute(database, "SELECT TextColumn FROM TestSchema.TestTable WHERE TextColumn LIKE '%Test^_%' ESCAPE '^';");
  393. EXPECT_EQ(result.size(), 1u);
  394. // Same as above but escape the escape character happens to be a SQL
  395. // metacharacter - we want to make sure it's treated as an escape.
  396. result = execute(database, "SELECT TextColumn FROM TestSchema.TestTable WHERE TextColumn LIKE '%Test__%' ESCAPE '_';");
  397. EXPECT_EQ(result.size(), 1u);
  398. // (Unnecessarily) escaping a character that happens to be a Regex
  399. // metacharacter should have no effect.
  400. result = execute(database, "SELECT TextColumn FROM TestSchema.TestTable WHERE TextColumn LIKE 'Test:+_' ESCAPE ':';");
  401. EXPECT_EQ(result.size(), 5u);
  402. // Make sure we error out if the ESCAPE is empty
  403. auto select_result = try_execute(database, "SELECT TextColumn FROM TestSchema.TestTable WHERE TextColumn LIKE '%' ESCAPE '';");
  404. EXPECT(select_result.is_error());
  405. EXPECT(select_result.release_error().error() == SQL::SQLErrorCode::SyntaxError);
  406. // Make sure we error out if the ESCAPE has more than a single character
  407. select_result = try_execute(database, "SELECT TextColumn FROM TestSchema.TestTable WHERE TextColumn LIKE '%' ESCAPE 'whf';");
  408. EXPECT(select_result.is_error());
  409. EXPECT(select_result.release_error().error() == SQL::SQLErrorCode::SyntaxError);
  410. }
  411. TEST_CASE(select_with_order)
  412. {
  413. ScopeGuard guard([]() { unlink(db_name); });
  414. auto database = SQL::Database::construct(db_name);
  415. EXPECT(!database->open().is_error());
  416. create_table(database);
  417. auto result = execute(database,
  418. "INSERT INTO TestSchema.TestTable ( TextColumn, IntColumn ) VALUES "
  419. "( 'Test_5', 44 ), "
  420. "( 'Test_2', 42 ), "
  421. "( 'Test_1', 47 ), "
  422. "( 'Test_3', 40 ), "
  423. "( 'Test_4', 41 );");
  424. EXPECT(result.size() == 5);
  425. result = execute(database, "SELECT TextColumn, IntColumn FROM TestSchema.TestTable ORDER BY IntColumn;");
  426. EXPECT_EQ(result.size(), 5u);
  427. EXPECT_EQ(result[0].row[1].to_int<i32>(), 40);
  428. EXPECT_EQ(result[1].row[1].to_int<i32>(), 41);
  429. EXPECT_EQ(result[2].row[1].to_int<i32>(), 42);
  430. EXPECT_EQ(result[3].row[1].to_int<i32>(), 44);
  431. EXPECT_EQ(result[4].row[1].to_int<i32>(), 47);
  432. result = execute(database, "SELECT TextColumn, IntColumn FROM TestSchema.TestTable ORDER BY TextColumn;");
  433. EXPECT_EQ(result.size(), 5u);
  434. EXPECT_EQ(result[0].row[0].to_deprecated_string(), "Test_1");
  435. EXPECT_EQ(result[1].row[0].to_deprecated_string(), "Test_2");
  436. EXPECT_EQ(result[2].row[0].to_deprecated_string(), "Test_3");
  437. EXPECT_EQ(result[3].row[0].to_deprecated_string(), "Test_4");
  438. EXPECT_EQ(result[4].row[0].to_deprecated_string(), "Test_5");
  439. }
  440. TEST_CASE(select_with_regexp)
  441. {
  442. ScopeGuard guard([]() { unlink(db_name); });
  443. auto database = SQL::Database::construct(db_name);
  444. EXPECT(!database->open().is_error());
  445. create_table(database);
  446. auto result = execute(database,
  447. "INSERT INTO TestSchema.TestTable ( TextColumn, IntColumn ) VALUES "
  448. "( 'Test+1', 42 ), "
  449. "( 'Pröv+2', 43 ), "
  450. "( 'Test(3)', 44 ), "
  451. "( 'Test[4]', 45 ), "
  452. "( 'Test+5', 46 ), "
  453. "( 'Another-Test_6', 47 );");
  454. EXPECT(result.size() == 6);
  455. // Simple match
  456. result = execute(database, "SELECT TextColumn FROM TestSchema.TestTable WHERE TextColumn REGEXP 'Test\\+1';");
  457. EXPECT_EQ(result.size(), 1u);
  458. // Match all
  459. result = execute(database, "SELECT TextColumn FROM TestSchema.TestTable WHERE TextColumn REGEXP '.*';");
  460. EXPECT_EQ(result.size(), 6u);
  461. // Match with wildcards
  462. result = execute(database, "SELECT TextColumn FROM TestSchema.TestTable WHERE TextColumn REGEXP '^Test.+';");
  463. EXPECT_EQ(result.size(), 4u);
  464. // Match with case insensitive basic Latin and case sensitive Swedish ö
  465. // FIXME: If LibRegex is changed to support case insensitive matches of Unicode characters
  466. // This test should be updated and changed to match 'PRÖV'.
  467. result = execute(database, "SELECT TextColumn FROM TestSchema.TestTable WHERE TextColumn REGEXP 'PRöV.*';");
  468. EXPECT_EQ(result.size(), 1u);
  469. }
  470. TEST_CASE(handle_regexp_errors)
  471. {
  472. ScopeGuard guard([]() { unlink(db_name); });
  473. auto database = SQL::Database::construct(db_name);
  474. EXPECT(!database->open().is_error());
  475. create_table(database);
  476. auto result = execute(database,
  477. "INSERT INTO TestSchema.TestTable ( TextColumn, IntColumn ) VALUES "
  478. "( 'Test', 0 );");
  479. EXPECT(result.size() == 1);
  480. // Malformed regex, unmatched square bracket
  481. auto select_result = try_execute(database, "SELECT TextColumn FROM TestSchema.TestTable WHERE TextColumn REGEXP 'Test\\+[0-9.*';");
  482. EXPECT(select_result.is_error());
  483. }
  484. TEST_CASE(select_with_order_two_columns)
  485. {
  486. ScopeGuard guard([]() { unlink(db_name); });
  487. auto database = SQL::Database::construct(db_name);
  488. EXPECT(!database->open().is_error());
  489. create_table(database);
  490. auto result = execute(database,
  491. "INSERT INTO TestSchema.TestTable ( TextColumn, IntColumn ) VALUES "
  492. "( 'Test_5', 44 ), "
  493. "( 'Test_2', 42 ), "
  494. "( 'Test_1', 47 ), "
  495. "( 'Test_2', 40 ), "
  496. "( 'Test_4', 41 );");
  497. EXPECT(result.size() == 5);
  498. result = execute(database, "SELECT TextColumn, IntColumn FROM TestSchema.TestTable ORDER BY TextColumn, IntColumn;");
  499. EXPECT_EQ(result.size(), 5u);
  500. EXPECT_EQ(result[0].row[0].to_deprecated_string(), "Test_1");
  501. EXPECT_EQ(result[0].row[1].to_int<i32>(), 47);
  502. EXPECT_EQ(result[1].row[0].to_deprecated_string(), "Test_2");
  503. EXPECT_EQ(result[1].row[1].to_int<i32>(), 40);
  504. EXPECT_EQ(result[2].row[0].to_deprecated_string(), "Test_2");
  505. EXPECT_EQ(result[2].row[1].to_int<i32>(), 42);
  506. EXPECT_EQ(result[3].row[0].to_deprecated_string(), "Test_4");
  507. EXPECT_EQ(result[3].row[1].to_int<i32>(), 41);
  508. EXPECT_EQ(result[4].row[0].to_deprecated_string(), "Test_5");
  509. EXPECT_EQ(result[4].row[1].to_int<i32>(), 44);
  510. }
  511. TEST_CASE(select_with_order_by_column_not_in_result)
  512. {
  513. ScopeGuard guard([]() { unlink(db_name); });
  514. auto database = SQL::Database::construct(db_name);
  515. EXPECT(!database->open().is_error());
  516. create_table(database);
  517. auto result = execute(database,
  518. "INSERT INTO TestSchema.TestTable ( TextColumn, IntColumn ) VALUES "
  519. "( 'Test_5', 44 ), "
  520. "( 'Test_2', 42 ), "
  521. "( 'Test_1', 47 ), "
  522. "( 'Test_3', 40 ), "
  523. "( 'Test_4', 41 );");
  524. EXPECT(result.size() == 5);
  525. result = execute(database, "SELECT TextColumn FROM TestSchema.TestTable ORDER BY IntColumn;");
  526. EXPECT_EQ(result.size(), 5u);
  527. EXPECT_EQ(result[0].row[0].to_deprecated_string(), "Test_3");
  528. EXPECT_EQ(result[1].row[0].to_deprecated_string(), "Test_4");
  529. EXPECT_EQ(result[2].row[0].to_deprecated_string(), "Test_2");
  530. EXPECT_EQ(result[3].row[0].to_deprecated_string(), "Test_5");
  531. EXPECT_EQ(result[4].row[0].to_deprecated_string(), "Test_1");
  532. }
  533. TEST_CASE(select_with_limit)
  534. {
  535. ScopeGuard guard([]() { unlink(db_name); });
  536. auto database = SQL::Database::construct(db_name);
  537. EXPECT(!database->open().is_error());
  538. create_table(database);
  539. for (auto count = 0; count < 100; count++) {
  540. auto result = execute(database,
  541. DeprecatedString::formatted("INSERT INTO TestSchema.TestTable ( TextColumn, IntColumn ) VALUES ( 'Test_{}', {} );", count, count));
  542. EXPECT(result.size() == 1);
  543. }
  544. auto result = execute(database, "SELECT TextColumn, IntColumn FROM TestSchema.TestTable LIMIT 10;");
  545. auto rows = result;
  546. EXPECT_EQ(rows.size(), 10u);
  547. }
  548. TEST_CASE(select_with_limit_and_offset)
  549. {
  550. ScopeGuard guard([]() { unlink(db_name); });
  551. auto database = SQL::Database::construct(db_name);
  552. EXPECT(!database->open().is_error());
  553. create_table(database);
  554. for (auto count = 0; count < 100; count++) {
  555. auto result = execute(database,
  556. DeprecatedString::formatted("INSERT INTO TestSchema.TestTable ( TextColumn, IntColumn ) VALUES ( 'Test_{}', {} );", count, count));
  557. EXPECT(result.size() == 1);
  558. }
  559. auto result = execute(database, "SELECT TextColumn, IntColumn FROM TestSchema.TestTable LIMIT 10 OFFSET 10;");
  560. EXPECT_EQ(result.size(), 10u);
  561. }
  562. TEST_CASE(select_with_order_limit_and_offset)
  563. {
  564. ScopeGuard guard([]() { unlink(db_name); });
  565. auto database = SQL::Database::construct(db_name);
  566. EXPECT(!database->open().is_error());
  567. create_table(database);
  568. for (auto count = 0; count < 100; count++) {
  569. auto result = execute(database,
  570. DeprecatedString::formatted("INSERT INTO TestSchema.TestTable ( TextColumn, IntColumn ) VALUES ( 'Test_{}', {} );", count, count));
  571. EXPECT(result.size() == 1);
  572. }
  573. auto result = execute(database, "SELECT TextColumn, IntColumn FROM TestSchema.TestTable ORDER BY IntColumn LIMIT 10 OFFSET 10;");
  574. EXPECT_EQ(result.size(), 10u);
  575. EXPECT_EQ(result[0].row[1].to_int<i32>(), 10);
  576. EXPECT_EQ(result[1].row[1].to_int<i32>(), 11);
  577. EXPECT_EQ(result[2].row[1].to_int<i32>(), 12);
  578. EXPECT_EQ(result[3].row[1].to_int<i32>(), 13);
  579. EXPECT_EQ(result[4].row[1].to_int<i32>(), 14);
  580. EXPECT_EQ(result[5].row[1].to_int<i32>(), 15);
  581. EXPECT_EQ(result[6].row[1].to_int<i32>(), 16);
  582. EXPECT_EQ(result[7].row[1].to_int<i32>(), 17);
  583. EXPECT_EQ(result[8].row[1].to_int<i32>(), 18);
  584. EXPECT_EQ(result[9].row[1].to_int<i32>(), 19);
  585. }
  586. TEST_CASE(select_with_limit_out_of_bounds)
  587. {
  588. ScopeGuard guard([]() { unlink(db_name); });
  589. auto database = SQL::Database::construct(db_name);
  590. EXPECT(!database->open().is_error());
  591. create_table(database);
  592. for (auto count = 0; count < 100; count++) {
  593. auto result = execute(database,
  594. DeprecatedString::formatted("INSERT INTO TestSchema.TestTable ( TextColumn, IntColumn ) VALUES ( 'Test_{}', {} );", count, count));
  595. EXPECT(result.size() == 1);
  596. }
  597. auto result = execute(database, "SELECT TextColumn, IntColumn FROM TestSchema.TestTable LIMIT 500;");
  598. EXPECT_EQ(result.size(), 100u);
  599. }
  600. TEST_CASE(select_with_offset_out_of_bounds)
  601. {
  602. ScopeGuard guard([]() { unlink(db_name); });
  603. auto database = SQL::Database::construct(db_name);
  604. EXPECT(!database->open().is_error());
  605. create_table(database);
  606. for (auto count = 0; count < 100; count++) {
  607. auto result = execute(database,
  608. DeprecatedString::formatted("INSERT INTO TestSchema.TestTable ( TextColumn, IntColumn ) VALUES ( 'Test_{}', {} );", count, count));
  609. EXPECT(result.size() == 1);
  610. }
  611. auto result = execute(database, "SELECT TextColumn, IntColumn FROM TestSchema.TestTable LIMIT 10 OFFSET 200;");
  612. EXPECT_EQ(result.size(), 0u);
  613. }
  614. TEST_CASE(describe_table)
  615. {
  616. ScopeGuard guard([]() { unlink(db_name); });
  617. auto database = SQL::Database::construct(db_name);
  618. EXPECT(!database->open().is_error());
  619. create_table(database);
  620. auto result = execute(database, "DESCRIBE TABLE TestSchema.TestTable;");
  621. EXPECT_EQ(result.size(), 2u);
  622. EXPECT_EQ(result[0].row[0].to_deprecated_string(), "TEXTCOLUMN");
  623. EXPECT_EQ(result[0].row[1].to_deprecated_string(), "text");
  624. EXPECT_EQ(result[1].row[0].to_deprecated_string(), "INTCOLUMN");
  625. EXPECT_EQ(result[1].row[1].to_deprecated_string(), "int");
  626. }
  627. TEST_CASE(binary_operator_execution)
  628. {
  629. ScopeGuard guard([]() { unlink(db_name); });
  630. auto database = SQL::Database::construct(db_name);
  631. EXPECT(!database->open().is_error());
  632. create_table(database);
  633. for (auto count = 0; count < 10; ++count) {
  634. auto result = execute(database, DeprecatedString::formatted("INSERT INTO TestSchema.TestTable VALUES ( 'T{}', {} );", count, count));
  635. EXPECT_EQ(result.size(), 1u);
  636. }
  637. auto compare_result = [](SQL::ResultSet const& result, Vector<int> const& expected) {
  638. EXPECT_EQ(result.command(), SQL::SQLCommand::Select);
  639. EXPECT_EQ(result.size(), expected.size());
  640. Vector<int> result_values;
  641. result_values.ensure_capacity(result.size());
  642. for (size_t i = 0; i < result.size(); ++i) {
  643. auto const& result_row = result.at(i).row;
  644. EXPECT_EQ(result_row.size(), 1u);
  645. auto result_column = result_row[0].to_int<i32>();
  646. result_values.append(result_column.value());
  647. }
  648. quick_sort(result_values);
  649. EXPECT_EQ(result_values, expected);
  650. };
  651. auto result = execute(database, "SELECT IntColumn FROM TestSchema.TestTable WHERE ((IntColumn + 1) < 5);");
  652. compare_result(result, { 0, 1, 2, 3 });
  653. result = execute(database, "SELECT IntColumn FROM TestSchema.TestTable WHERE ((IntColumn + 1) <= 5);");
  654. compare_result(result, { 0, 1, 2, 3, 4 });
  655. result = execute(database, "SELECT IntColumn FROM TestSchema.TestTable WHERE ((IntColumn - 1) > 4);");
  656. compare_result(result, { 6, 7, 8, 9 });
  657. result = execute(database, "SELECT IntColumn FROM TestSchema.TestTable WHERE ((IntColumn - 1) >= 4);");
  658. compare_result(result, { 5, 6, 7, 8, 9 });
  659. result = execute(database, "SELECT IntColumn FROM TestSchema.TestTable WHERE ((IntColumn * 2) < 10);");
  660. compare_result(result, { 0, 1, 2, 3, 4 });
  661. result = execute(database, "SELECT IntColumn FROM TestSchema.TestTable WHERE ((IntColumn * 2) <= 10);");
  662. compare_result(result, { 0, 1, 2, 3, 4, 5 });
  663. result = execute(database, "SELECT IntColumn FROM TestSchema.TestTable WHERE ((IntColumn / 3) > 2);");
  664. compare_result(result, { 7, 8, 9 });
  665. result = execute(database, "SELECT IntColumn FROM TestSchema.TestTable WHERE ((IntColumn / 3) >= 2);");
  666. compare_result(result, { 6, 7, 8, 9 });
  667. result = execute(database, "SELECT IntColumn FROM TestSchema.TestTable WHERE ((IntColumn % 2) = 0);");
  668. compare_result(result, { 0, 2, 4, 6, 8 });
  669. result = execute(database, "SELECT IntColumn FROM TestSchema.TestTable WHERE ((IntColumn % 2) = 1);");
  670. compare_result(result, { 1, 3, 5, 7, 9 });
  671. result = execute(database, "SELECT IntColumn FROM TestSchema.TestTable WHERE ((1 << IntColumn) <= 32);");
  672. compare_result(result, { 0, 1, 2, 3, 4, 5 });
  673. result = execute(database, "SELECT IntColumn FROM TestSchema.TestTable WHERE ((1024 >> IntColumn) >= 32);");
  674. compare_result(result, { 0, 1, 2, 3, 4, 5 });
  675. result = execute(database, "SELECT IntColumn FROM TestSchema.TestTable WHERE ((IntColumn | 1) != IntColumn);");
  676. compare_result(result, { 0, 2, 4, 6, 8 });
  677. result = execute(database, "SELECT IntColumn FROM TestSchema.TestTable WHERE ((IntColumn & 1) = 1);");
  678. compare_result(result, { 1, 3, 5, 7, 9 });
  679. }
  680. TEST_CASE(binary_operator_failure)
  681. {
  682. ScopeGuard guard([]() { unlink(db_name); });
  683. auto database = SQL::Database::construct(db_name);
  684. EXPECT(!database->open().is_error());
  685. create_table(database);
  686. for (auto count = 0; count < 10; ++count) {
  687. auto result = execute(database, DeprecatedString::formatted("INSERT INTO TestSchema.TestTable VALUES ( 'T{}', {} );", count, count));
  688. EXPECT_EQ(result.size(), 1u);
  689. }
  690. auto expect_failure = [](auto result, auto op) {
  691. EXPECT(result.is_error());
  692. auto error = result.release_error();
  693. EXPECT_EQ(error.error(), SQL::SQLErrorCode::NumericOperatorTypeMismatch);
  694. auto message = DeprecatedString::formatted("NumericOperatorTypeMismatch: Cannot apply '{}' operator to non-numeric operands", op);
  695. EXPECT_EQ(error.error_string(), message);
  696. };
  697. auto result = try_execute(database, "SELECT * FROM TestSchema.TestTable WHERE ((IntColumn + TextColumn) < 5);");
  698. expect_failure(move(result), '+');
  699. result = try_execute(database, "SELECT * FROM TestSchema.TestTable WHERE ((IntColumn - TextColumn) < 5);");
  700. expect_failure(move(result), '-');
  701. result = try_execute(database, "SELECT * FROM TestSchema.TestTable WHERE ((IntColumn * TextColumn) < 5);");
  702. expect_failure(move(result), '*');
  703. result = try_execute(database, "SELECT * FROM TestSchema.TestTable WHERE ((IntColumn / TextColumn) < 5);");
  704. expect_failure(move(result), '/');
  705. result = try_execute(database, "SELECT * FROM TestSchema.TestTable WHERE ((IntColumn % TextColumn) < 5);");
  706. expect_failure(move(result), '%');
  707. result = try_execute(database, "SELECT * FROM TestSchema.TestTable WHERE ((IntColumn << TextColumn) < 5);");
  708. expect_failure(move(result), "<<"sv);
  709. result = try_execute(database, "SELECT * FROM TestSchema.TestTable WHERE ((IntColumn >> TextColumn) < 5);");
  710. expect_failure(move(result), ">>"sv);
  711. result = try_execute(database, "SELECT * FROM TestSchema.TestTable WHERE ((IntColumn | TextColumn) < 5);");
  712. expect_failure(move(result), '|');
  713. result = try_execute(database, "SELECT * FROM TestSchema.TestTable WHERE ((IntColumn & TextColumn) < 5);");
  714. expect_failure(move(result), '&');
  715. }
  716. TEST_CASE(describe_large_table_after_persist)
  717. {
  718. ScopeGuard guard([]() { unlink(db_name); });
  719. {
  720. auto database = SQL::Database::construct(db_name);
  721. EXPECT(!database->open().is_error());
  722. auto result = execute(database, "CREATE TABLE Cookies ( name TEXT, value TEXT, same_site INTEGER, creation_time INTEGER, last_access_time INTEGER, expiry_time INTEGER, domain TEXT, path TEXT, secure INTEGER, http_only INTEGER, host_only INTEGER, persistent INTEGER );");
  723. EXPECT_EQ(result.command(), SQL::SQLCommand::Create);
  724. }
  725. {
  726. auto database = SQL::Database::construct(db_name);
  727. EXPECT(!database->open().is_error());
  728. auto result = execute(database, "DESCRIBE TABLE Cookies;");
  729. EXPECT_EQ(result.size(), 12u);
  730. }
  731. }
  732. TEST_CASE(delete_single_row)
  733. {
  734. ScopeGuard guard([]() { unlink(db_name); });
  735. {
  736. auto database = SQL::Database::construct(db_name);
  737. EXPECT(!database->open().is_error());
  738. create_table(database);
  739. for (auto count = 0; count < 10; ++count) {
  740. auto result = execute(database, DeprecatedString::formatted("INSERT INTO TestSchema.TestTable VALUES ( 'T{}', {} );", count, count));
  741. EXPECT_EQ(result.size(), 1u);
  742. }
  743. auto result = execute(database, "SELECT * FROM TestSchema.TestTable;");
  744. EXPECT_EQ(result.size(), 10u);
  745. }
  746. {
  747. auto database = SQL::Database::construct(db_name);
  748. EXPECT(!database->open().is_error());
  749. execute(database, "DELETE FROM TestSchema.TestTable WHERE (IntColumn = 4);");
  750. auto result = execute(database, "SELECT IntColumn FROM TestSchema.TestTable ORDER BY IntColumn;");
  751. EXPECT_EQ(result.size(), 9u);
  752. for (auto i = 0u; i < 4; ++i)
  753. EXPECT_EQ(result[i].row[0], i);
  754. for (auto i = 5u; i < 9; ++i)
  755. EXPECT_EQ(result[i].row[0], i + 1);
  756. }
  757. {
  758. auto database = SQL::Database::construct(db_name);
  759. EXPECT(!database->open().is_error());
  760. auto result = execute(database, "SELECT IntColumn FROM TestSchema.TestTable ORDER BY IntColumn;");
  761. EXPECT_EQ(result.size(), 9u);
  762. for (auto i = 0u; i < 4; ++i)
  763. EXPECT_EQ(result[i].row[0], i);
  764. for (auto i = 5u; i < 9; ++i)
  765. EXPECT_EQ(result[i].row[0], i + 1);
  766. }
  767. }
  768. TEST_CASE(delete_multiple_rows)
  769. {
  770. ScopeGuard guard([]() { unlink(db_name); });
  771. {
  772. auto database = SQL::Database::construct(db_name);
  773. EXPECT(!database->open().is_error());
  774. create_table(database);
  775. for (auto count = 0; count < 10; ++count) {
  776. auto result = execute(database, DeprecatedString::formatted("INSERT INTO TestSchema.TestTable VALUES ( 'T{}', {} );", count, count));
  777. EXPECT_EQ(result.size(), 1u);
  778. }
  779. auto result = execute(database, "SELECT * FROM TestSchema.TestTable;");
  780. EXPECT_EQ(result.size(), 10u);
  781. }
  782. {
  783. auto database = SQL::Database::construct(db_name);
  784. EXPECT(!database->open().is_error());
  785. execute(database, "DELETE FROM TestSchema.TestTable WHERE (IntColumn >= 4);");
  786. auto result = execute(database, "SELECT IntColumn FROM TestSchema.TestTable ORDER BY IntColumn;");
  787. EXPECT_EQ(result.size(), 4u);
  788. for (auto i = 0u; i < result.size(); ++i)
  789. EXPECT_EQ(result[i].row[0], i);
  790. }
  791. {
  792. auto database = SQL::Database::construct(db_name);
  793. EXPECT(!database->open().is_error());
  794. auto result = execute(database, "SELECT IntColumn FROM TestSchema.TestTable ORDER BY IntColumn;");
  795. EXPECT_EQ(result.size(), 4u);
  796. for (auto i = 0u; i < result.size(); ++i)
  797. EXPECT_EQ(result[i].row[0], i);
  798. }
  799. }
  800. TEST_CASE(delete_all_rows)
  801. {
  802. ScopeGuard guard([]() { unlink(db_name); });
  803. {
  804. auto database = SQL::Database::construct(db_name);
  805. EXPECT(!database->open().is_error());
  806. create_table(database);
  807. for (auto count = 0; count < 10; ++count) {
  808. auto result = execute(database, DeprecatedString::formatted("INSERT INTO TestSchema.TestTable VALUES ( 'T{}', {} );", count, count));
  809. EXPECT_EQ(result.size(), 1u);
  810. }
  811. auto result = execute(database, "SELECT * FROM TestSchema.TestTable;");
  812. EXPECT_EQ(result.size(), 10u);
  813. }
  814. {
  815. auto database = SQL::Database::construct(db_name);
  816. EXPECT(!database->open().is_error());
  817. execute(database, "DELETE FROM TestSchema.TestTable;");
  818. auto result = execute(database, "SELECT * FROM TestSchema.TestTable;");
  819. EXPECT(result.is_empty());
  820. }
  821. {
  822. auto database = SQL::Database::construct(db_name);
  823. EXPECT(!database->open().is_error());
  824. auto result = execute(database, "SELECT * FROM TestSchema.TestTable;");
  825. EXPECT(result.is_empty());
  826. }
  827. }
  828. TEST_CASE(update_single_row)
  829. {
  830. ScopeGuard guard([]() { unlink(db_name); });
  831. {
  832. auto database = SQL::Database::construct(db_name);
  833. EXPECT(!database->open().is_error());
  834. create_table(database);
  835. for (auto count = 0; count < 10; ++count) {
  836. auto result = execute(database, DeprecatedString::formatted("INSERT INTO TestSchema.TestTable VALUES ( 'T{}', {} );", count, count));
  837. EXPECT_EQ(result.size(), 1u);
  838. }
  839. execute(database, "UPDATE TestSchema.TestTable SET IntColumn=123456 WHERE (TextColumn = 'T3');");
  840. auto result = execute(database, "SELECT IntColumn FROM TestSchema.TestTable ORDER BY IntColumn;");
  841. EXPECT_EQ(result.size(), 10u);
  842. for (auto i = 0u; i < 10; ++i) {
  843. if (i < 3)
  844. EXPECT_EQ(result[i].row[0], i);
  845. else if (i < 9)
  846. EXPECT_EQ(result[i].row[0], i + 1);
  847. else
  848. EXPECT_EQ(result[i].row[0], 123456);
  849. }
  850. }
  851. {
  852. auto database = SQL::Database::construct(db_name);
  853. EXPECT(!database->open().is_error());
  854. auto result = execute(database, "SELECT IntColumn FROM TestSchema.TestTable ORDER BY IntColumn;");
  855. EXPECT_EQ(result.size(), 10u);
  856. for (auto i = 0u; i < 10; ++i) {
  857. if (i < 3)
  858. EXPECT_EQ(result[i].row[0], i);
  859. else if (i < 9)
  860. EXPECT_EQ(result[i].row[0], i + 1);
  861. else
  862. EXPECT_EQ(result[i].row[0], 123456);
  863. }
  864. }
  865. }
  866. TEST_CASE(update_multiple_rows)
  867. {
  868. ScopeGuard guard([]() { unlink(db_name); });
  869. {
  870. auto database = SQL::Database::construct(db_name);
  871. EXPECT(!database->open().is_error());
  872. create_table(database);
  873. for (auto count = 0; count < 10; ++count) {
  874. auto result = execute(database, DeprecatedString::formatted("INSERT INTO TestSchema.TestTable VALUES ( 'T{}', {} );", count, count));
  875. EXPECT_EQ(result.size(), 1u);
  876. }
  877. execute(database, "UPDATE TestSchema.TestTable SET IntColumn=123456 WHERE (IntColumn > 4);");
  878. auto result = execute(database, "SELECT IntColumn FROM TestSchema.TestTable ORDER BY IntColumn;");
  879. EXPECT_EQ(result.size(), 10u);
  880. for (auto i = 0u; i < 10; ++i) {
  881. if (i < 5)
  882. EXPECT_EQ(result[i].row[0], i);
  883. else
  884. EXPECT_EQ(result[i].row[0], 123456);
  885. }
  886. }
  887. {
  888. auto database = SQL::Database::construct(db_name);
  889. EXPECT(!database->open().is_error());
  890. auto result = execute(database, "SELECT IntColumn FROM TestSchema.TestTable ORDER BY IntColumn;");
  891. EXPECT_EQ(result.size(), 10u);
  892. for (auto i = 0u; i < 10; ++i) {
  893. if (i < 5)
  894. EXPECT_EQ(result[i].row[0], i);
  895. else
  896. EXPECT_EQ(result[i].row[0], 123456);
  897. }
  898. }
  899. }
  900. TEST_CASE(update_all_rows)
  901. {
  902. ScopeGuard guard([]() { unlink(db_name); });
  903. {
  904. auto database = SQL::Database::construct(db_name);
  905. EXPECT(!database->open().is_error());
  906. create_table(database);
  907. for (auto count = 0; count < 10; ++count) {
  908. auto result = execute(database, DeprecatedString::formatted("INSERT INTO TestSchema.TestTable VALUES ( 'T{}', {} );", count, count));
  909. EXPECT_EQ(result.size(), 1u);
  910. }
  911. execute(database, "UPDATE TestSchema.TestTable SET IntColumn=123456;");
  912. auto result = execute(database, "SELECT IntColumn FROM TestSchema.TestTable ORDER BY IntColumn;");
  913. EXPECT_EQ(result.size(), 10u);
  914. for (auto i = 0u; i < 10; ++i)
  915. EXPECT_EQ(result[i].row[0], 123456);
  916. }
  917. {
  918. auto database = SQL::Database::construct(db_name);
  919. EXPECT(!database->open().is_error());
  920. auto result = execute(database, "SELECT IntColumn FROM TestSchema.TestTable ORDER BY IntColumn;");
  921. EXPECT_EQ(result.size(), 10u);
  922. for (auto i = 0u; i < 10; ++i)
  923. EXPECT_EQ(result[i].row[0], 123456);
  924. }
  925. }
  926. }