From 91c17baf6b7a7df2baaafea36c3f956a15ceaa10 Mon Sep 17 00:00:00 2001 From: All Asmaul Husnain <2263081025@uttarauniversity.edu.bd> Date: Wed, 4 Nov 2026 03:17:54 +0600 Subject: [PATCH 1/5] refactor: distinguish B-tree lookup misses --- include/btree.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/btree.h b/include/btree.h index 3e02583..cdcb1c9 100644 --- a/include/btree.h +++ b/include/btree.h @@ -12,7 +12,8 @@ typedef enum { BTREE_IO_ERROR, BTREE_DUPLICATE_KEY, BTREE_TABLE_FULL, - BTREE_CORRUPT + BTREE_CORRUPT, + BTREE_ROW_NOT_FOUND } BTreeResult; typedef struct BTree BTree; From c66aa73aa55e9a673533fe3fac71e591ac11b4e9 Mon Sep 17 00:00:00 2001 From: All Asmaul Husnain <2263081025@uttarauniversity.edu.bd> Date: Wed, 4 Nov 2026 03:17:59 +0600 Subject: [PATCH 2/5] fix: preserve B-tree lookup result semantics --- src/btree.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/btree.c b/src/btree.c index bec39d2..8a1f144 100644 --- a/src/btree.c +++ b/src/btree.c @@ -779,7 +779,7 @@ BTreeResult btree_find(const BTree *tree, int id, Row *row) deserialize_row(row, const_leaf_cell(page, index)); return BTREE_OK; } - return BTREE_INVALID_ARGUMENT; + return BTREE_ROW_NOT_FOUND; } page_number = child_page_at(page, internal_child_index(page, id)); @@ -899,6 +899,8 @@ const char *btree_result_string(BTreeResult result) return "database capacity reached"; case BTREE_CORRUPT: return "database file is corrupt"; + case BTREE_ROW_NOT_FOUND: + return "row not found"; default: return "unknown error"; } From aa4e4503fb3b89da932adcdb660d29f67bb857b5 Mon Sep 17 00:00:00 2001 From: All Asmaul Husnain <2263081025@uttarauniversity.edu.bd> Date: Wed, 4 Nov 2026 03:18:03 +0600 Subject: [PATCH 3/5] fix: propagate B-tree open read errors --- src/database.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/src/database.c b/src/database.c index e4319a6..701dcf6 100644 --- a/src/database.c +++ b/src/database.c @@ -93,7 +93,18 @@ Table *table_open(const char *filename, SqliteResult *result) btree_read_all(tree, table->rows, TABLE_ROW_CAPACITY, &table->size); if (read_result != BTREE_OK) { table_destroy(table); - *result = SQLITE_IO_ERROR; + table_destroy(table); + switch (read_result) { + case BTREE_CORRUPT: + *result = SQLITE_CORRUPT; + break; + case BTREE_TABLE_FULL: + *result = SQLITE_TABLE_FULL; + break; + default: + *result = SQLITE_IO_ERROR; + break; + } return NULL; } @@ -222,11 +233,16 @@ SqliteResult table_find(const Table *table, int id, Row *row) return SQLITE_OK; } - if (result == BTREE_INVALID_ARGUMENT) { + switch (result) { + case BTREE_ROW_NOT_FOUND: return SQLITE_ROW_NOT_FOUND; + case BTREE_CORRUPT: + return SQLITE_CORRUPT; + case BTREE_TABLE_FULL: + return SQLITE_TABLE_FULL; + default: + return SQLITE_IO_ERROR; } - - return SQLITE_IO_ERROR; } const char *sqlite_result_string(SqliteResult result) From aeef3962612d20a9b2774715e907a7d28425dbff Mon Sep 17 00:00:00 2001 From: All Asmaul Husnain <2263081025@uttarauniversity.edu.bd> Date: Wed, 4 Nov 2026 03:18:07 +0600 Subject: [PATCH 4/5] test: assert exact missing-row result --- tests/test_database.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_database.c b/tests/test_database.c index 04c5103..7b35f14 100644 --- a/tests/test_database.c +++ b/tests/test_database.c @@ -143,7 +143,7 @@ static void test_lookup(void) assert(found.id == 23); assert(strcmp(found.username, "user23") == 0); - assert(table_find(table, 99, &found) != SQLITE_OK); + assert(table_find(table, 99, &found) == SQLITE_ROW_NOT_FOUND); table_destroy(table); remove(filename); From e94d350821f5f08928087340745713fc567b8948 Mon Sep 17 00:00:00 2001 From: All Asmaul Husnain <2263081025@uttarauniversity.edu.bd> Date: Wed, 4 Nov 2026 03:18:33 +0600 Subject: [PATCH 5/5] fix: avoid duplicate table cleanup on open failure --- src/database.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/database.c b/src/database.c index 701dcf6..81eb884 100644 --- a/src/database.c +++ b/src/database.c @@ -92,7 +92,6 @@ Table *table_open(const char *filename, SqliteResult *result) BTreeResult read_result = btree_read_all(tree, table->rows, TABLE_ROW_CAPACITY, &table->size); if (read_result != BTREE_OK) { - table_destroy(table); table_destroy(table); switch (read_result) { case BTREE_CORRUPT: