TestSqlStatementExecution.cpp 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618
  1. /*
  2. * Copyright (c) 2021, Jan de Visser <jan@de-visser.net>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include <unistd.h>
  7. #include <AK/ScopeGuard.h>
  8. #include <LibSQL/AST/Parser.h>
  9. #include <LibSQL/Database.h>
  10. #include <LibSQL/Row.h>
  11. #include <LibSQL/SQLResult.h>
  12. #include <LibSQL/Value.h>
  13. #include <LibTest/TestCase.h>
  14. namespace {
  15. constexpr const char* db_name = "/tmp/test.db";
  16. RefPtr<SQL::SQLResult> execute(NonnullRefPtr<SQL::Database> database, String const& sql)
  17. {
  18. auto parser = SQL::AST::Parser(SQL::AST::Lexer(sql));
  19. auto statement = parser.next_statement();
  20. EXPECT(!parser.has_errors());
  21. if (parser.has_errors())
  22. outln("{}", parser.errors()[0].to_string());
  23. auto result = statement->execute(move(database));
  24. if (result->error().code != SQL::SQLErrorCode::NoError)
  25. outln("{}", result->error().to_string());
  26. return result;
  27. }
  28. void create_schema(NonnullRefPtr<SQL::Database> database)
  29. {
  30. auto result = execute(database, "CREATE SCHEMA TestSchema;");
  31. EXPECT(result->error().code == SQL::SQLErrorCode::NoError);
  32. EXPECT(result->inserted() == 1);
  33. }
  34. void create_table(NonnullRefPtr<SQL::Database> database)
  35. {
  36. create_schema(database);
  37. auto result = execute(database, "CREATE TABLE TestSchema.TestTable ( TextColumn text, IntColumn integer );");
  38. EXPECT(result->error().code == SQL::SQLErrorCode::NoError);
  39. EXPECT(result->inserted() == 1);
  40. }
  41. void create_two_tables(NonnullRefPtr<SQL::Database> database)
  42. {
  43. create_schema(database);
  44. auto result = execute(database, "CREATE TABLE TestSchema.TestTable1 ( TextColumn1 text, IntColumn integer );");
  45. EXPECT(result->error().code == SQL::SQLErrorCode::NoError);
  46. EXPECT(result->inserted() == 1);
  47. result = execute(database, "CREATE TABLE TestSchema.TestTable2 ( TextColumn2 text, IntColumn integer );");
  48. EXPECT(result->error().code == SQL::SQLErrorCode::NoError);
  49. EXPECT(result->inserted() == 1);
  50. }
  51. TEST_CASE(create_schema)
  52. {
  53. ScopeGuard guard([]() { unlink(db_name); });
  54. auto database = SQL::Database::construct(db_name);
  55. EXPECT(!database->open().is_error());
  56. create_schema(database);
  57. auto schema_or_error = database->get_schema("TESTSCHEMA");
  58. EXPECT(!schema_or_error.is_error());
  59. EXPECT(schema_or_error.value());
  60. }
  61. TEST_CASE(create_table)
  62. {
  63. ScopeGuard guard([]() { unlink(db_name); });
  64. auto database = SQL::Database::construct(db_name);
  65. EXPECT(!database->open().is_error());
  66. create_table(database);
  67. auto table_or_error = database->get_table("TESTSCHEMA", "TESTTABLE");
  68. EXPECT(!table_or_error.is_error());
  69. EXPECT(table_or_error.value());
  70. }
  71. TEST_CASE(insert_into_table)
  72. {
  73. ScopeGuard guard([]() { unlink(db_name); });
  74. auto database = SQL::Database::construct(db_name);
  75. EXPECT(!database->open().is_error());
  76. create_table(database);
  77. auto result = execute(database, "INSERT INTO TestSchema.TestTable ( TextColumn, IntColumn ) VALUES ( 'Test', 42 );");
  78. EXPECT(result->error().code == SQL::SQLErrorCode::NoError);
  79. EXPECT(result->inserted() == 1);
  80. auto table_or_error = database->get_table("TESTSCHEMA", "TESTTABLE");
  81. EXPECT(!table_or_error.is_error());
  82. auto table = table_or_error.value();
  83. int count = 0;
  84. auto rows_or_error = database->select_all(*table);
  85. EXPECT(!rows_or_error.is_error());
  86. for (auto& row : rows_or_error.value()) {
  87. EXPECT_EQ(row["TEXTCOLUMN"].to_string(), "Test");
  88. EXPECT_EQ(row["INTCOLUMN"].to_int().value(), 42);
  89. count++;
  90. }
  91. EXPECT_EQ(count, 1);
  92. }
  93. TEST_CASE(insert_into_table_wrong_data_types)
  94. {
  95. ScopeGuard guard([]() { unlink(db_name); });
  96. auto database = SQL::Database::construct(db_name);
  97. EXPECT(!database->open().is_error());
  98. create_table(database);
  99. auto result = execute(database, "INSERT INTO TestSchema.TestTable ( TextColumn, IntColumn ) VALUES (43, 'Test_2');");
  100. EXPECT(result->inserted() == 0);
  101. EXPECT(result->error().code == SQL::SQLErrorCode::InvalidValueType);
  102. }
  103. TEST_CASE(insert_into_table_multiple_tuples_wrong_data_types)
  104. {
  105. ScopeGuard guard([]() { unlink(db_name); });
  106. auto database = SQL::Database::construct(db_name);
  107. EXPECT(!database->open().is_error());
  108. create_table(database);
  109. auto result = execute(database, "INSERT INTO TestSchema.TestTable ( TextColumn, IntColumn ) VALUES ('Test_1', 42), (43, 'Test_2');");
  110. EXPECT(result->inserted() == 0);
  111. EXPECT(result->error().code == SQL::SQLErrorCode::InvalidValueType);
  112. }
  113. TEST_CASE(insert_wrong_number_of_values)
  114. {
  115. ScopeGuard guard([]() { unlink(db_name); });
  116. auto database = SQL::Database::construct(db_name);
  117. EXPECT(!database->open().is_error());
  118. create_table(database);
  119. auto result = execute(database, "INSERT INTO TestSchema.TestTable VALUES ( 42 );");
  120. EXPECT(result->error().code == SQL::SQLErrorCode::InvalidNumberOfValues);
  121. EXPECT(result->inserted() == 0);
  122. }
  123. TEST_CASE(insert_identifier_as_value)
  124. {
  125. ScopeGuard guard([]() { unlink(db_name); });
  126. auto database = SQL::Database::construct(db_name);
  127. EXPECT(!database->open().is_error());
  128. create_table(database);
  129. auto result = execute(database, "INSERT INTO TestSchema.TestTable VALUES ( identifier, 42 );");
  130. EXPECT(result->error().code == SQL::SQLErrorCode::SyntaxError);
  131. EXPECT(result->inserted() == 0);
  132. }
  133. TEST_CASE(insert_quoted_identifier_as_value)
  134. {
  135. ScopeGuard guard([]() { unlink(db_name); });
  136. auto database = SQL::Database::construct(db_name);
  137. EXPECT(!database->open().is_error());
  138. create_table(database);
  139. auto result = execute(database, "INSERT INTO TestSchema.TestTable VALUES ( \"QuotedIdentifier\", 42 );");
  140. EXPECT(result->error().code == SQL::SQLErrorCode::SyntaxError);
  141. EXPECT(result->inserted() == 0);
  142. }
  143. TEST_CASE(insert_without_column_names)
  144. {
  145. ScopeGuard guard([]() { unlink(db_name); });
  146. auto database = SQL::Database::construct(db_name);
  147. EXPECT(!database->open().is_error());
  148. create_table(database);
  149. auto result = execute(database, "INSERT INTO TestSchema.TestTable VALUES ('Test_1', 42), ('Test_2', 43);");
  150. EXPECT(result->error().code == SQL::SQLErrorCode::NoError);
  151. EXPECT(result->inserted() == 2);
  152. auto table_or_error = database->get_table("TESTSCHEMA", "TESTTABLE");
  153. EXPECT(!table_or_error.is_error());
  154. auto rows_or_error = database->select_all(*(table_or_error.value()));
  155. EXPECT(!rows_or_error.is_error());
  156. EXPECT_EQ(rows_or_error.value().size(), 2u);
  157. }
  158. TEST_CASE(select_from_table)
  159. {
  160. ScopeGuard guard([]() { unlink(db_name); });
  161. auto database = SQL::Database::construct(db_name);
  162. EXPECT(!database->open().is_error());
  163. create_table(database);
  164. auto result = execute(database,
  165. "INSERT INTO TestSchema.TestTable ( TextColumn, IntColumn ) VALUES "
  166. "( 'Test_1', 42 ), "
  167. "( 'Test_2', 43 ), "
  168. "( 'Test_3', 44 ), "
  169. "( 'Test_4', 45 ), "
  170. "( 'Test_5', 46 );");
  171. EXPECT(result->error().code == SQL::SQLErrorCode::NoError);
  172. EXPECT(result->inserted() == 5);
  173. result = execute(database, "SELECT * FROM TestSchema.TestTable;");
  174. EXPECT(result->error().code == SQL::SQLErrorCode::NoError);
  175. EXPECT(result->has_results());
  176. EXPECT_EQ(result->results().size(), 5u);
  177. }
  178. TEST_CASE(select_with_column_names)
  179. {
  180. ScopeGuard guard([]() { unlink(db_name); });
  181. auto database = SQL::Database::construct(db_name);
  182. EXPECT(!database->open().is_error());
  183. create_table(database);
  184. auto result = execute(database,
  185. "INSERT INTO TestSchema.TestTable ( TextColumn, IntColumn ) VALUES "
  186. "( 'Test_1', 42 ), "
  187. "( 'Test_2', 43 ), "
  188. "( 'Test_3', 44 ), "
  189. "( 'Test_4', 45 ), "
  190. "( 'Test_5', 46 );");
  191. EXPECT(result->error().code == SQL::SQLErrorCode::NoError);
  192. EXPECT(result->inserted() == 5);
  193. result = execute(database, "SELECT TextColumn FROM TestSchema.TestTable;");
  194. EXPECT(result->error().code == SQL::SQLErrorCode::NoError);
  195. EXPECT(result->has_results());
  196. EXPECT_EQ(result->results().size(), 5u);
  197. EXPECT_EQ(result->results()[0].row.size(), 1u);
  198. }
  199. TEST_CASE(select_with_nonexisting_column_name)
  200. {
  201. ScopeGuard guard([]() { unlink(db_name); });
  202. auto database = SQL::Database::construct(db_name);
  203. EXPECT(!database->open().is_error());
  204. create_table(database);
  205. auto result = execute(database,
  206. "INSERT INTO TestSchema.TestTable ( TextColumn, IntColumn ) VALUES "
  207. "( 'Test_1', 42 ), "
  208. "( 'Test_2', 43 ), "
  209. "( 'Test_3', 44 ), "
  210. "( 'Test_4', 45 ), "
  211. "( 'Test_5', 46 );");
  212. EXPECT(result->error().code == SQL::SQLErrorCode::NoError);
  213. EXPECT(result->inserted() == 5);
  214. result = execute(database, "SELECT Bogus FROM TestSchema.TestTable;");
  215. EXPECT(result->error().code == SQL::SQLErrorCode::ColumnDoesNotExist);
  216. }
  217. TEST_CASE(select_with_where)
  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,
  224. "INSERT INTO TestSchema.TestTable ( TextColumn, IntColumn ) VALUES "
  225. "( 'Test_1', 42 ), "
  226. "( 'Test_2', 43 ), "
  227. "( 'Test_3', 44 ), "
  228. "( 'Test_4', 45 ), "
  229. "( 'Test_5', 46 );");
  230. EXPECT(result->error().code == SQL::SQLErrorCode::NoError);
  231. EXPECT(result->inserted() == 5);
  232. result = execute(database, "SELECT TextColumn, IntColumn FROM TestSchema.TestTable WHERE IntColumn > 44;");
  233. EXPECT(result->error().code == SQL::SQLErrorCode::NoError);
  234. EXPECT(result->has_results());
  235. EXPECT_EQ(result->results().size(), 2u);
  236. for (auto& row : result->results()) {
  237. EXPECT(row.row[1].to_int().value() > 44);
  238. }
  239. }
  240. TEST_CASE(select_cross_join)
  241. {
  242. ScopeGuard guard([]() { unlink(db_name); });
  243. auto database = SQL::Database::construct(db_name);
  244. EXPECT(!database->open().is_error());
  245. create_two_tables(database);
  246. auto result = execute(database,
  247. "INSERT INTO TestSchema.TestTable1 ( TextColumn1, IntColumn ) VALUES "
  248. "( 'Test_1', 42 ), "
  249. "( 'Test_2', 43 ), "
  250. "( 'Test_3', 44 ), "
  251. "( 'Test_4', 45 ), "
  252. "( 'Test_5', 46 );");
  253. EXPECT(result->error().code == SQL::SQLErrorCode::NoError);
  254. EXPECT(result->inserted() == 5);
  255. result = execute(database,
  256. "INSERT INTO TestSchema.TestTable2 ( TextColumn2, IntColumn ) VALUES "
  257. "( 'Test_10', 40 ), "
  258. "( 'Test_11', 41 ), "
  259. "( 'Test_12', 42 ), "
  260. "( 'Test_13', 47 ), "
  261. "( 'Test_14', 48 );");
  262. EXPECT(result->error().code == SQL::SQLErrorCode::NoError);
  263. EXPECT(result->inserted() == 5);
  264. result = execute(database, "SELECT * FROM TestSchema.TestTable1, TestSchema.TestTable2;");
  265. EXPECT(result->error().code == SQL::SQLErrorCode::NoError);
  266. EXPECT(result->has_results());
  267. EXPECT_EQ(result->results().size(), 25u);
  268. for (auto& row : result->results()) {
  269. EXPECT(row.row.size() == 4);
  270. EXPECT(row.row[1].to_int().value() >= 42);
  271. EXPECT(row.row[1].to_int().value() <= 46);
  272. EXPECT(row.row[3].to_int().value() >= 40);
  273. EXPECT(row.row[3].to_int().value() <= 48);
  274. }
  275. }
  276. TEST_CASE(select_inner_join)
  277. {
  278. ScopeGuard guard([]() { unlink(db_name); });
  279. auto database = SQL::Database::construct(db_name);
  280. EXPECT(!database->open().is_error());
  281. create_two_tables(database);
  282. auto result = execute(database,
  283. "INSERT INTO TestSchema.TestTable1 ( TextColumn1, IntColumn ) VALUES "
  284. "( 'Test_1', 42 ), "
  285. "( 'Test_2', 43 ), "
  286. "( 'Test_3', 44 ), "
  287. "( 'Test_4', 45 ), "
  288. "( 'Test_5', 46 );");
  289. EXPECT(result->error().code == SQL::SQLErrorCode::NoError);
  290. EXPECT(result->inserted() == 5);
  291. result = execute(database,
  292. "INSERT INTO TestSchema.TestTable2 ( TextColumn2, IntColumn ) VALUES "
  293. "( 'Test_10', 40 ), "
  294. "( 'Test_11', 41 ), "
  295. "( 'Test_12', 42 ), "
  296. "( 'Test_13', 47 ), "
  297. "( 'Test_14', 48 );");
  298. EXPECT(result->error().code == SQL::SQLErrorCode::NoError);
  299. EXPECT(result->inserted() == 5);
  300. result = execute(database,
  301. "SELECT TestTable1.IntColumn, TextColumn1, TextColumn2 "
  302. "FROM TestSchema.TestTable1, TestSchema.TestTable2 "
  303. "WHERE TestTable1.IntColumn = TestTable2.IntColumn;");
  304. EXPECT(result->error().code == SQL::SQLErrorCode::NoError);
  305. EXPECT(result->has_results());
  306. EXPECT_EQ(result->results().size(), 1u);
  307. auto& row = result->results()[0];
  308. EXPECT_EQ(row.row.size(), 3u);
  309. EXPECT_EQ(row.row[0].to_int().value(), 42);
  310. EXPECT_EQ(row.row[1].to_string(), "Test_1");
  311. EXPECT_EQ(row.row[2].to_string(), "Test_12");
  312. }
  313. TEST_CASE(select_with_like)
  314. {
  315. ScopeGuard guard([]() { unlink(db_name); });
  316. auto database = SQL::Database::construct(db_name);
  317. EXPECT(!database->open().is_error());
  318. create_table(database);
  319. auto result = execute(database,
  320. "INSERT INTO TestSchema.TestTable ( TextColumn, IntColumn ) VALUES "
  321. "( 'Test+1', 42 ), "
  322. "( 'Test+2', 43 ), "
  323. "( 'Test+3', 44 ), "
  324. "( 'Test+4', 45 ), "
  325. "( 'Test+5', 46 ), "
  326. "( 'Another+Test_6', 47 );");
  327. EXPECT(result->error().code == SQL::SQLErrorCode::NoError);
  328. EXPECT(result->inserted() == 6);
  329. // Simple match
  330. result = execute(database, "SELECT TextColumn FROM TestSchema.TestTable WHERE TextColumn LIKE 'Test+1';");
  331. EXPECT(result->error().code == SQL::SQLErrorCode::NoError);
  332. EXPECT(result->has_results());
  333. EXPECT_EQ(result->results().size(), 1u);
  334. // Use % to match most rows
  335. result = execute(database, "SELECT TextColumn FROM TestSchema.TestTable WHERE TextColumn LIKE 'T%';");
  336. EXPECT(result->error().code == SQL::SQLErrorCode::NoError);
  337. EXPECT(result->has_results());
  338. EXPECT_EQ(result->results().size(), 5u);
  339. // Same as above but invert the match
  340. result = execute(database, "SELECT TextColumn FROM TestSchema.TestTable WHERE TextColumn NOT LIKE 'T%';");
  341. EXPECT(result->error().code == SQL::SQLErrorCode::NoError);
  342. EXPECT(result->has_results());
  343. EXPECT_EQ(result->results().size(), 1u);
  344. // Use _ and % to match all rows
  345. result = execute(database, "SELECT TextColumn FROM TestSchema.TestTable WHERE TextColumn LIKE '%e_t%';");
  346. EXPECT(result->error().code == SQL::SQLErrorCode::NoError);
  347. EXPECT(result->has_results());
  348. EXPECT_EQ(result->results().size(), 6u);
  349. // Use escape to match a single row. The escape character happens to be a
  350. // Regex metacharacter, let's make sure we don't get confused by that.
  351. result = execute(database, "SELECT TextColumn FROM TestSchema.TestTable WHERE TextColumn LIKE '%Test^_%' ESCAPE '^';");
  352. EXPECT(result->error().code == SQL::SQLErrorCode::NoError);
  353. EXPECT(result->has_results());
  354. EXPECT_EQ(result->results().size(), 1u);
  355. // Same as above but escape the escape character happens to be a SQL
  356. // metacharacter - we want to make sure it's treated as an escape.
  357. result = execute(database, "SELECT TextColumn FROM TestSchema.TestTable WHERE TextColumn LIKE '%Test__%' ESCAPE '_';");
  358. EXPECT(result->error().code == SQL::SQLErrorCode::NoError);
  359. EXPECT(result->has_results());
  360. EXPECT_EQ(result->results().size(), 1u);
  361. // (Unnecessarily) escaping a character that happens to be a Regex
  362. // metacharacter should have no effect.
  363. result = execute(database, "SELECT TextColumn FROM TestSchema.TestTable WHERE TextColumn LIKE 'Test:+_' ESCAPE ':';");
  364. EXPECT(result->error().code == SQL::SQLErrorCode::NoError);
  365. EXPECT(result->has_results());
  366. EXPECT_EQ(result->results().size(), 5u);
  367. // Make sure we error out if the ESCAPE is empty
  368. result = execute(database, "SELECT TextColumn FROM TestSchema.TestTable WHERE TextColumn LIKE '%' ESCAPE '';");
  369. EXPECT(result->error().code == SQL::SQLErrorCode::SyntaxError);
  370. EXPECT(!result->has_results());
  371. // Make sure we error out if the ESCAPE has more than a single character
  372. result = execute(database, "SELECT TextColumn FROM TestSchema.TestTable WHERE TextColumn LIKE '%' ESCAPE 'whf';");
  373. EXPECT(result->error().code == SQL::SQLErrorCode::SyntaxError);
  374. EXPECT(!result->has_results());
  375. }
  376. TEST_CASE(select_with_order)
  377. {
  378. ScopeGuard guard([]() { unlink(db_name); });
  379. auto database = SQL::Database::construct(db_name);
  380. EXPECT(!database->open().is_error());
  381. create_table(database);
  382. auto result = execute(database,
  383. "INSERT INTO TestSchema.TestTable ( TextColumn, IntColumn ) VALUES "
  384. "( 'Test_5', 44 ), "
  385. "( 'Test_2', 42 ), "
  386. "( 'Test_1', 47 ), "
  387. "( 'Test_3', 40 ), "
  388. "( 'Test_4', 41 );");
  389. EXPECT(result->error().code == SQL::SQLErrorCode::NoError);
  390. EXPECT(result->inserted() == 5);
  391. result = execute(database, "SELECT TextColumn, IntColumn FROM TestSchema.TestTable ORDER BY IntColumn;");
  392. EXPECT(result->error().code == SQL::SQLErrorCode::NoError);
  393. EXPECT(result->has_results());
  394. auto rows = result->results();
  395. EXPECT_EQ(rows.size(), 5u);
  396. EXPECT_EQ(rows[0].row[1].to_int().value(), 40);
  397. EXPECT_EQ(rows[1].row[1].to_int().value(), 41);
  398. EXPECT_EQ(rows[2].row[1].to_int().value(), 42);
  399. EXPECT_EQ(rows[3].row[1].to_int().value(), 44);
  400. EXPECT_EQ(rows[4].row[1].to_int().value(), 47);
  401. result = execute(database, "SELECT TextColumn, IntColumn FROM TestSchema.TestTable ORDER BY TextColumn;");
  402. EXPECT(result->error().code == SQL::SQLErrorCode::NoError);
  403. EXPECT(result->has_results());
  404. rows = result->results();
  405. EXPECT_EQ(rows.size(), 5u);
  406. EXPECT_EQ(rows[0].row[0].to_string(), "Test_1");
  407. EXPECT_EQ(rows[1].row[0].to_string(), "Test_2");
  408. EXPECT_EQ(rows[2].row[0].to_string(), "Test_3");
  409. EXPECT_EQ(rows[3].row[0].to_string(), "Test_4");
  410. EXPECT_EQ(rows[4].row[0].to_string(), "Test_5");
  411. }
  412. TEST_CASE(select_with_order_two_columns)
  413. {
  414. ScopeGuard guard([]() { unlink(db_name); });
  415. auto database = SQL::Database::construct(db_name);
  416. EXPECT(!database->open().is_error());
  417. create_table(database);
  418. auto result = execute(database,
  419. "INSERT INTO TestSchema.TestTable ( TextColumn, IntColumn ) VALUES "
  420. "( 'Test_5', 44 ), "
  421. "( 'Test_2', 42 ), "
  422. "( 'Test_1', 47 ), "
  423. "( 'Test_2', 40 ), "
  424. "( 'Test_4', 41 );");
  425. EXPECT(result->error().code == SQL::SQLErrorCode::NoError);
  426. EXPECT(result->inserted() == 5);
  427. result = execute(database, "SELECT TextColumn, IntColumn FROM TestSchema.TestTable ORDER BY TextColumn, IntColumn;");
  428. EXPECT(result->error().code == SQL::SQLErrorCode::NoError);
  429. EXPECT(result->has_results());
  430. auto rows = result->results();
  431. EXPECT_EQ(rows.size(), 5u);
  432. EXPECT_EQ(rows[0].row[0].to_string(), "Test_1");
  433. EXPECT_EQ(rows[0].row[1].to_int().value(), 47);
  434. EXPECT_EQ(rows[1].row[0].to_string(), "Test_2");
  435. EXPECT_EQ(rows[1].row[1].to_int().value(), 40);
  436. EXPECT_EQ(rows[2].row[0].to_string(), "Test_2");
  437. EXPECT_EQ(rows[2].row[1].to_int().value(), 42);
  438. EXPECT_EQ(rows[3].row[0].to_string(), "Test_4");
  439. EXPECT_EQ(rows[3].row[1].to_int().value(), 41);
  440. EXPECT_EQ(rows[4].row[0].to_string(), "Test_5");
  441. EXPECT_EQ(rows[4].row[1].to_int().value(), 44);
  442. }
  443. TEST_CASE(select_with_order_by_column_not_in_result)
  444. {
  445. ScopeGuard guard([]() { unlink(db_name); });
  446. auto database = SQL::Database::construct(db_name);
  447. EXPECT(!database->open().is_error());
  448. create_table(database);
  449. auto result = execute(database,
  450. "INSERT INTO TestSchema.TestTable ( TextColumn, IntColumn ) VALUES "
  451. "( 'Test_5', 44 ), "
  452. "( 'Test_2', 42 ), "
  453. "( 'Test_1', 47 ), "
  454. "( 'Test_3', 40 ), "
  455. "( 'Test_4', 41 );");
  456. EXPECT(result->error().code == SQL::SQLErrorCode::NoError);
  457. EXPECT(result->inserted() == 5);
  458. result = execute(database, "SELECT TextColumn FROM TestSchema.TestTable ORDER BY IntColumn;");
  459. EXPECT(result->error().code == SQL::SQLErrorCode::NoError);
  460. EXPECT(result->has_results());
  461. auto rows = result->results();
  462. EXPECT_EQ(rows.size(), 5u);
  463. EXPECT_EQ(rows[0].row[0].to_string(), "Test_3");
  464. EXPECT_EQ(rows[1].row[0].to_string(), "Test_4");
  465. EXPECT_EQ(rows[2].row[0].to_string(), "Test_2");
  466. EXPECT_EQ(rows[3].row[0].to_string(), "Test_5");
  467. EXPECT_EQ(rows[4].row[0].to_string(), "Test_1");
  468. }
  469. TEST_CASE(select_with_limit)
  470. {
  471. ScopeGuard guard([]() { unlink(db_name); });
  472. auto database = SQL::Database::construct(db_name);
  473. EXPECT(!database->open().is_error());
  474. create_table(database);
  475. for (auto count = 0; count < 100; count++) {
  476. auto result = execute(database,
  477. String::formatted("INSERT INTO TestSchema.TestTable ( TextColumn, IntColumn ) VALUES ( 'Test_{}', {} );", count, count));
  478. EXPECT(result->error().code == SQL::SQLErrorCode::NoError);
  479. EXPECT(result->inserted() == 1);
  480. }
  481. auto result = execute(database, "SELECT TextColumn, IntColumn FROM TestSchema.TestTable LIMIT 10;");
  482. EXPECT(result->error().code == SQL::SQLErrorCode::NoError);
  483. EXPECT(result->has_results());
  484. auto rows = result->results();
  485. EXPECT_EQ(rows.size(), 10u);
  486. }
  487. TEST_CASE(select_with_limit_and_offset)
  488. {
  489. ScopeGuard guard([]() { unlink(db_name); });
  490. auto database = SQL::Database::construct(db_name);
  491. EXPECT(!database->open().is_error());
  492. create_table(database);
  493. for (auto count = 0; count < 100; count++) {
  494. auto result = execute(database,
  495. String::formatted("INSERT INTO TestSchema.TestTable ( TextColumn, IntColumn ) VALUES ( 'Test_{}', {} );", count, count));
  496. EXPECT(result->error().code == SQL::SQLErrorCode::NoError);
  497. EXPECT(result->inserted() == 1);
  498. }
  499. auto result = execute(database, "SELECT TextColumn, IntColumn FROM TestSchema.TestTable LIMIT 10 OFFSET 10;");
  500. EXPECT(result->error().code == SQL::SQLErrorCode::NoError);
  501. EXPECT(result->has_results());
  502. auto rows = result->results();
  503. EXPECT_EQ(rows.size(), 10u);
  504. }
  505. TEST_CASE(select_with_order_limit_and_offset)
  506. {
  507. ScopeGuard guard([]() { unlink(db_name); });
  508. auto database = SQL::Database::construct(db_name);
  509. EXPECT(!database->open().is_error());
  510. create_table(database);
  511. for (auto count = 0; count < 100; count++) {
  512. auto result = execute(database,
  513. String::formatted("INSERT INTO TestSchema.TestTable ( TextColumn, IntColumn ) VALUES ( 'Test_{}', {} );", count, count));
  514. EXPECT(result->error().code == SQL::SQLErrorCode::NoError);
  515. EXPECT(result->inserted() == 1);
  516. }
  517. auto result = execute(database, "SELECT TextColumn, IntColumn FROM TestSchema.TestTable ORDER BY IntColumn LIMIT 10 OFFSET 10;");
  518. EXPECT(result->error().code == SQL::SQLErrorCode::NoError);
  519. EXPECT(result->has_results());
  520. auto rows = result->results();
  521. EXPECT_EQ(rows.size(), 10u);
  522. EXPECT_EQ(rows[0].row[1].to_int().value(), 10);
  523. EXPECT_EQ(rows[1].row[1].to_int().value(), 11);
  524. EXPECT_EQ(rows[2].row[1].to_int().value(), 12);
  525. EXPECT_EQ(rows[3].row[1].to_int().value(), 13);
  526. EXPECT_EQ(rows[4].row[1].to_int().value(), 14);
  527. EXPECT_EQ(rows[5].row[1].to_int().value(), 15);
  528. EXPECT_EQ(rows[6].row[1].to_int().value(), 16);
  529. EXPECT_EQ(rows[7].row[1].to_int().value(), 17);
  530. EXPECT_EQ(rows[8].row[1].to_int().value(), 18);
  531. EXPECT_EQ(rows[9].row[1].to_int().value(), 19);
  532. }
  533. TEST_CASE(select_with_limit_out_of_bounds)
  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. String::formatted("INSERT INTO TestSchema.TestTable ( TextColumn, IntColumn ) VALUES ( 'Test_{}', {} );", count, count));
  542. EXPECT(result->error().code == SQL::SQLErrorCode::NoError);
  543. EXPECT(result->inserted() == 1);
  544. }
  545. auto result = execute(database, "SELECT TextColumn, IntColumn FROM TestSchema.TestTable LIMIT 500;");
  546. EXPECT(result->error().code == SQL::SQLErrorCode::NoError);
  547. EXPECT(result->has_results());
  548. auto rows = result->results();
  549. EXPECT_EQ(rows.size(), 100u);
  550. }
  551. TEST_CASE(select_with_offset_out_of_bounds)
  552. {
  553. ScopeGuard guard([]() { unlink(db_name); });
  554. auto database = SQL::Database::construct(db_name);
  555. EXPECT(!database->open().is_error());
  556. create_table(database);
  557. for (auto count = 0; count < 100; count++) {
  558. auto result = execute(database,
  559. String::formatted("INSERT INTO TestSchema.TestTable ( TextColumn, IntColumn ) VALUES ( 'Test_{}', {} );", count, count));
  560. EXPECT(result->error().code == SQL::SQLErrorCode::NoError);
  561. EXPECT(result->inserted() == 1);
  562. }
  563. auto result = execute(database, "SELECT TextColumn, IntColumn FROM TestSchema.TestTable LIMIT 10 OFFSET 200;");
  564. EXPECT(result->error().code == SQL::SQLErrorCode::NoError);
  565. EXPECT(result->has_results());
  566. auto rows = result->results();
  567. EXPECT_EQ(rows.size(), 0u);
  568. }
  569. }