Team Ai
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
tests_analyze_loadStat4.c224 linesDownload Raw Back to tests
1#include "sqliteInt.h"2#include "unity.h"3#include <stdlib.h>4#include <string.h>5 6/* Wrapper for the static function under test (provided by module for testing) */7extern int test_loadStat4(sqlite3 *db, const char *zDb);8 9/* Global connection for tests; opened per-test and closed in tearDown */10static sqlite3 *g_db = NULL;11 12/* Helpers */13static void exec_sql(sqlite3 *db, const char *zSql){14  char *zErr = 0;15  int rc = sqlite3_exec(db, zSql, 0, 0, &zErr);16  if( rc!=SQLITE_OK ){17    const char *msg = zErr ? zErr : "exec_sql failed";18    TEST_FAIL_MESSAGE(msg);19  }20  if( zErr ) sqlite3_free(zErr);21}22 23void setUp(void) {24  g_db = NULL;25}26 27void tearDown(void) {28  if( g_db ){29    /* Close DB; this will clean up any allocated schema objects as well */30    sqlite3_close(g_db);31    g_db = NULL;32  }33}34 35/* Test: No sqlite_stat4 table present -> no changes, SQLITE_OK */36void test_loadStat4_no_stat4_table(void){37  int rc;38  Index *pIdx;39 40  TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &g_db));41  /* Disable lookaside as required by loadStat4 assertions */42  g_db->lookaside.bDisable = 1;43 44  exec_sql(g_db, "CREATE TABLE t(a, b, c);");45  exec_sql(g_db, "CREATE INDEX i_ab ON t(a, b);");46 47  rc = test_loadStat4(g_db, "main");48  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);49 50  pIdx = sqlite3FindIndex(g_db, "i_ab", "main");51  TEST_ASSERT_NOT_NULL(pIdx);52  TEST_ASSERT_EQUAL_INT(0, pIdx->nSample);53  TEST_ASSERT_EQUAL_INT(0, pIdx->mxSample);54  TEST_ASSERT_NULL(pIdx->aSample);55}56 57/* Test: Single sample for a rowid table index; verify arrays and blob padding */58void test_loadStat4_single_sample_rowid_index(void){59  int rc;60  Index *pIdx;61 62  TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &g_db));63  g_db->lookaside.bDisable = 1;64 65  /* Schema: rowid table with a 2-column index (implies nColumn==nKeyCol+1) */66  exec_sql(g_db, "CREATE TABLE t(a, b, c);");67  exec_sql(g_db, "CREATE INDEX i_ab ON t(a, b);");68 69  /* Create sqlite_stat4 and insert one row for index i_ab.70     For a rowid table, nSampleCol = pIdx->nColumn = nKeyCol + 1 = 3. */71  exec_sql(g_db, "CREATE TABLE sqlite_stat4(idx TEXT, neq TEXT, nlt TEXT, ndlt TEXT, sample BLOB);");72  exec_sql(g_db,73    "INSERT INTO sqlite_stat4(idx,neq,nlt,ndlt,sample) "74    "VALUES('i_ab','100 10 1','40 20 10','39 19 9',X'11223344');"75  );76 77  rc = test_loadStat4(g_db, "main");78  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);79 80  pIdx = sqlite3FindIndex(g_db, "i_ab", "main");81  TEST_ASSERT_NOT_NULL(pIdx);82 83  /* nSampleCol should equal nColumn (3) for rowid table non-PK index */84  TEST_ASSERT_EQUAL_INT(pIdx->nColumn, pIdx->nSampleCol);85  TEST_ASSERT_EQUAL_INT(3, pIdx->nSampleCol);86 87  TEST_ASSERT_EQUAL_INT(1, pIdx->mxSample);  /* count(*) per idx */88  TEST_ASSERT_EQUAL_INT(1, pIdx->nSample);89  TEST_ASSERT_NOT_NULL(pIdx->aSample);90  TEST_ASSERT_NOT_NULL(pIdx->aAvgEq);91 92  /* Verify decoded integer arrays */93  TEST_ASSERT_EQUAL_INT64(100, pIdx->aSample[0].anEq[0]);94  TEST_ASSERT_EQUAL_INT64(10,  pIdx->aSample[0].anEq[1]);95  TEST_ASSERT_EQUAL_INT64(1,   pIdx->aSample[0].anEq[2]);96 97  TEST_ASSERT_EQUAL_INT64(40,  pIdx->aSample[0].anLt[0]);98  TEST_ASSERT_EQUAL_INT64(20,  pIdx->aSample[0].anLt[1]);99  TEST_ASSERT_EQUAL_INT64(10,  pIdx->aSample[0].anLt[2]);100 101  TEST_ASSERT_EQUAL_INT64(39,  pIdx->aSample[0].anDLt[0]);102  TEST_ASSERT_EQUAL_INT64(19,  pIdx->aSample[0].anDLt[1]);103  TEST_ASSERT_EQUAL_INT64(9,   pIdx->aSample[0].anDLt[2]);104 105  /* Verify sample blob copy and 8 trailing zero bytes */106  {107    const unsigned char *p = (const unsigned char*)pIdx->aSample[0].p;108    int n = pIdx->aSample[0].n;109    TEST_ASSERT_NOT_NULL(p);110    TEST_ASSERT_EQUAL_INT(4, n);111    TEST_ASSERT_EQUAL_UINT8(0x11, p[0]);112    TEST_ASSERT_EQUAL_UINT8(0x22, p[1]);113    TEST_ASSERT_EQUAL_UINT8(0x33, p[2]);114    TEST_ASSERT_EQUAL_UINT8(0x44, p[3]);115    /* Check 8 zero bytes padding */116    TEST_ASSERT_EQUAL_UINT8(0x00, p[n+0]);117    TEST_ASSERT_EQUAL_UINT8(0x00, p[n+1]);118    TEST_ASSERT_EQUAL_UINT8(0x00, p[n+2]);119    TEST_ASSERT_EQUAL_UINT8(0x00, p[n+3]);120    TEST_ASSERT_EQUAL_UINT8(0x00, p[n+4]);121    TEST_ASSERT_EQUAL_UINT8(0x00, p[n+5]);122    TEST_ASSERT_EQUAL_UINT8(0x00, p[n+6]);123    TEST_ASSERT_EQUAL_UINT8(0x00, p[n+7]);124  }125}126 127/* Test: Multiple samples for same index; verify mxSample and nSample */128void test_loadStat4_multiple_samples(void){129  int rc;130  Index *pIdx;131 132  TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &g_db));133  g_db->lookaside.bDisable = 1;134 135  exec_sql(g_db, "CREATE TABLE t(a, b, c);");136  exec_sql(g_db, "CREATE INDEX i_ab ON t(a, b);");137 138  exec_sql(g_db, "CREATE TABLE sqlite_stat4(idx TEXT, neq TEXT, nlt TEXT, ndlt TEXT, sample BLOB);");139  /* Provide two rows; each with 3 integers for rowid table index */140  exec_sql(g_db,141    "INSERT INTO sqlite_stat4 VALUES('i_ab','100 10 1','40 20 10','39 19 9',X'01');"142  );143  exec_sql(g_db,144    "INSERT INTO sqlite_stat4 VALUES('i_ab','200 20 2','80 40 20','79 39 19',X'0203');"145  );146 147  rc = test_loadStat4(g_db, "main");148  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);149 150  pIdx = sqlite3FindIndex(g_db, "i_ab", "main");151  TEST_ASSERT_NOT_NULL(pIdx);152 153  TEST_ASSERT_EQUAL_INT(2, pIdx->mxSample);154  TEST_ASSERT_EQUAL_INT(2, pIdx->nSample);155  TEST_ASSERT_NOT_NULL(pIdx->aSample);156  TEST_ASSERT_NOT_NULL(pIdx->aSample[0].p);157  TEST_ASSERT_NOT_NULL(pIdx->aSample[1].p);158}159 160/* Test: WITHOUT ROWID table primary key: nSampleCol should be nKeyCol */161void test_loadStat4_without_rowid_pk(void){162  int rc;163  Table *pTab;164  Index *pPk;165 166  TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &g_db));167  g_db->lookaside.bDisable = 1;168 169  /* WITHOUT ROWID table with composite primary key (2 cols) */170  exec_sql(g_db, "CREATE TABLE w(a INTEGER, b INTEGER, c TEXT, PRIMARY KEY(a,b)) WITHOUT ROWID;");171 172  /* Insert stat4 row that refers to the PRIMARY KEY by using idx=table-name.173     For WITHOUT ROWID PK index, nSampleCol should be nKeyCol (2). */174  exec_sql(g_db, "CREATE TABLE sqlite_stat4(idx TEXT, neq TEXT, nlt TEXT, ndlt TEXT, sample BLOB);");175  exec_sql(g_db,176    "INSERT INTO sqlite_stat4(idx,neq,nlt,ndlt,sample) "177    "VALUES('w','300 30','90 9','80 8',X'A55A');"178  );179 180  rc = test_loadStat4(g_db, "main");181  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);182 183  pTab = sqlite3FindTable(g_db, "w", "main");184  TEST_ASSERT_NOT_NULL(pTab);185  pPk = sqlite3PrimaryKeyIndex(pTab);186  TEST_ASSERT_NOT_NULL(pPk);187 188  /* Verify nSampleCol equals nKeyCol (2) and arrays populated accordingly */189  TEST_ASSERT_EQUAL_INT(pPk->nKeyCol, pPk->nSampleCol);190  TEST_ASSERT_EQUAL_INT(2, pPk->nSampleCol);191  TEST_ASSERT_EQUAL_INT(1, pPk->mxSample);192  TEST_ASSERT_EQUAL_INT(1, pPk->nSample);193  TEST_ASSERT_NOT_NULL(pPk->aSample);194 195  TEST_ASSERT_EQUAL_INT64(300, pPk->aSample[0].anEq[0]);196  TEST_ASSERT_EQUAL_INT64(30,  pPk->aSample[0].anEq[1]);197 198  TEST_ASSERT_EQUAL_INT64(90,  pPk->aSample[0].anLt[0]);199  TEST_ASSERT_EQUAL_INT64(9,   pPk->aSample[0].anLt[1]);200 201  TEST_ASSERT_EQUAL_INT64(80,  pPk->aSample[0].anDLt[0]);202  TEST_ASSERT_EQUAL_INT64(8,   pPk->aSample[0].anDLt[1]);203 204  /* Verify blob padding */205  {206    const unsigned char *p = (const unsigned char*)pPk->aSample[0].p;207    int n = pPk->aSample[0].n;208    TEST_ASSERT_NOT_NULL(p);209    TEST_ASSERT_EQUAL_INT(2, n);210    TEST_ASSERT_EQUAL_UINT8(0xA5, p[0]);211    TEST_ASSERT_EQUAL_UINT8(0x5A, p[1]);212    TEST_ASSERT_EQUAL_UINT8(0x00, p[n+0]);213    TEST_ASSERT_EQUAL_UINT8(0x00, p[n+7]);214  }215}216 217int main(void){218  UNITY_BEGIN();219  RUN_TEST(test_loadStat4_no_stat4_table);220  RUN_TEST(test_loadStat4_single_sample_rowid_index);221  RUN_TEST(test_loadStat4_multiple_samples);222  RUN_TEST(test_loadStat4_without_rowid_pk);223  return UNITY_END();224}