AryaWu/sqlite
0
1#include "sqliteInt.h"2#include "unity.h"3#include "vdbeInt.h"4 5#include <string.h>6#include <stdlib.h>7 8/* The target under test is static; use the provided wrapper. */9extern void test_destroyTable(Parse *pParse, Table *pTab);10 11static Table* makeTableWithIndexes(sqlite3 *db, Pgno tnum, const Pgno *idxNums, int nIdx){12 Table *pTab = (Table*)sqlite3DbMallocZero(db, sizeof(Table));13 TEST_ASSERT_NOT_NULL(pTab);14 pTab->tnum = tnum;15 pTab->pSchema = db->aDb[0].pSchema; /* main schema */16 17 Index *pHead = NULL;18 for(int i=0; i<nIdx; i++){19 Index *pIdx = (Index*)sqlite3DbMallocZero(db, sizeof(Index));20 TEST_ASSERT_NOT_NULL(pIdx);21 pIdx->tnum = idxNums[i];22 pIdx->pSchema = pTab->pSchema;23 pIdx->pNext = pHead;24 pHead = pIdx;25 }26 pTab->pIndex = pHead;27 return pTab;28}29 30static void freeTableAndIndexes(sqlite3 *db, Table *pTab){31 if( !pTab ) return;32 Index *p = pTab->pIndex;33 while(p){34 Index *pNext = p->pNext;35 sqlite3DbFree(db, p);36 p = pNext;37 }38 sqlite3DbFree(db, pTab);39}40 41static void collectDestroyOps(Parse *pParse, int *pCount, Pgno *p1Out, int *p3Out, int maxOut){42 Vdbe *v = sqlite3GetVdbe(pParse);43 TEST_ASSERT_NOT_NULL(v);44 int cnt = 0;45 for(int i=0; i<v->nOp; i++){46 Op *op = &v->aOp[i];47 if( op->opcode == OP_Destroy ){48 if( cnt < maxOut ){49 p1Out[cnt] = (Pgno)op->p1;50 p3Out[cnt] = op->p3;51 }52 cnt++;53 }54 }55 *pCount = cnt;56}57 58void setUp(void) {59 /* no-op */60}61void tearDown(void) {62 /* no-op */63}64 65static void initParse(sqlite3 *db, Parse *pParse){66 memset(pParse, 0, sizeof(Parse));67 pParse->db = db;68}69 70void test_destroyTable_single_no_indexes(void){71 sqlite3 *db = NULL;72 int rc = sqlite3_open(":memory:", &db);73 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);74 TEST_ASSERT_NOT_NULL(db);75 76 Parse parse;77 initParse(db, &parse);78 79 Pgno tnum = 5; /* >=2 to avoid "corrupt schema" path */80 Table *pTab = makeTableWithIndexes(db, tnum, NULL, 0);81 82 test_destroyTable(&parse, pTab);83 84 Pgno p1[8] = {0};85 int p3[8] = {0};86 int n = 0;87 collectDestroyOps(&parse, &n, p1, p3, 8);88 89 TEST_ASSERT_EQUAL_INT(1, n);90 TEST_ASSERT_EQUAL_UINT32(tnum, p1[0]);91 TEST_ASSERT_EQUAL_INT(0, p3[0]); /* main db index */92 93 freeTableAndIndexes(db, pTab);94 sqlite3_close(db);95}96 97void test_destroyTable_multiple_indexes_descending_order(void){98 sqlite3 *db = NULL;99 int rc = sqlite3_open(":memory:", &db);100 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);101 TEST_ASSERT_NOT_NULL(db);102 103 Parse parse;104 initParse(db, &parse);105 106 Pgno tnum = 10;107 Pgno idxs[] = {7, 15, 3};108 Table *pTab = makeTableWithIndexes(db, tnum, idxs, 3);109 110 test_destroyTable(&parse, pTab);111 112 Pgno p1[16] = {0};113 int p3[16] = {0};114 int n = 0;115 collectDestroyOps(&parse, &n, p1, p3, 16);116 117 /* Expect four OP_Destroy in order: 15, 10, 7, 3 */118 TEST_ASSERT_EQUAL_INT(4, n);119 TEST_ASSERT_EQUAL_UINT32(15, p1[0]);120 TEST_ASSERT_EQUAL_UINT32(10, p1[1]);121 TEST_ASSERT_EQUAL_UINT32(7, p1[2]);122 TEST_ASSERT_EQUAL_UINT32(3, p1[3]);123 124 for(int i=0; i<n; i++){125 TEST_ASSERT_EQUAL_INT(0, p3[i]); /* main db index per sqlite3SchemaToIndex */126 }127 128 freeTableAndIndexes(db, pTab);129 sqlite3_close(db);130}131 132void test_destroyTable_table_is_largest_then_indexes_descending(void){133 sqlite3 *db = NULL;134 int rc = sqlite3_open(":memory:", &db);135 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);136 TEST_ASSERT_NOT_NULL(db);137 138 Parse parse;139 initParse(db, &parse);140 141 Pgno tnum = 99;142 Pgno idxs[] = {33, 7, 50};143 Table *pTab = makeTableWithIndexes(db, tnum, idxs, 3);144 145 test_destroyTable(&parse, pTab);146 147 Pgno p1[16] = {0};148 int p3[16] = {0};149 int n = 0;150 collectDestroyOps(&parse, &n, p1, p3, 16);151 152 /* Expect: 99, 50, 33, 7 */153 TEST_ASSERT_EQUAL_INT(4, n);154 TEST_ASSERT_EQUAL_UINT32(99, p1[0]);155 TEST_ASSERT_EQUAL_UINT32(50, p1[1]);156 TEST_ASSERT_EQUAL_UINT32(33, p1[2]);157 TEST_ASSERT_EQUAL_UINT32(7, p1[3]);158 159 for(int i=0; i<n; i++){160 TEST_ASSERT_EQUAL_INT(0, p3[i]); /* main db */161 }162 163 freeTableAndIndexes(db, pTab);164 sqlite3_close(db);165}166 167int main(void){168 UNITY_BEGIN();169 RUN_TEST(test_destroyTable_single_no_indexes);170 RUN_TEST(test_destroyTable_multiple_indexes_descending_order);171 RUN_TEST(test_destroyTable_table_is_largest_then_indexes_descending);172 return UNITY_END();173}