Team Ai
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
tests_analyze_sqlite3Analyze.c192 linesDownload Raw Back to tests
1#include "sqliteInt.h"2#include "unity.h"3 4#include <stdio.h>5#include <string.h>6 7/* Global DB handle for tests */8static sqlite3 *gDb = NULL;9 10/* Unity fixtures */11void setUp(void) {12  int rc = sqlite3_open(":memory:", &gDb);13  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);14}15 16void tearDown(void) {17  if (gDb) {18    sqlite3_close(gDb);19    gDb = NULL;20  }21}22 23/* Helper: run arbitrary SQL and assert success */24static void exec_ok(const char *zSql){25  char *zErr = 0;26  int rc = sqlite3_exec(gDb, zSql, 0, 0, &zErr);27  if( zErr ){28    /* Provide context on failure */29    fprintf(stderr, "sqlite3_exec error: %s\n", zErr);30    sqlite3_free(zErr);31  }32  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);33}34 35/* Helper: construct a Token from a C-string literal */36static Token makeToken(const char *z){37  Token t;38  t.z = (char*)z;39  t.n = (int)strlen(z);40  return t;41}42 43/* Helper: constructs an empty/zero-length token (non-NULL pointer, n==0) */44static Token makeEmptyToken(void){45  Token t;46  t.z = (char*)"";47  t.n = 0;48  return t;49}50 51/* Helper: invoke sqlite3Analyze directly and return a copy of the Parse struct.52   Caller must delete pOut->pVdbe (if non-NULL) after use. */53static void call_analyze(Token *p1, Token *p2, Parse *pOut){54  Parse p;55  memset(&p, 0, sizeof(p));56  p.db = gDb;57 58  /* Ensure the assertion in sqlite3Analyze about Btree mutexes holds */59  sqlite3BtreeEnterAll(gDb);60  sqlite3Analyze(&p, p1, p2);61  sqlite3BtreeLeaveAll(gDb);62 63  *pOut = p;64}65 66/* Assert that a parse resulted in a non-empty VDBE program and no parse errors */67static void assert_codegen_success(Parse *p){68  TEST_ASSERT_NOT_NULL(p->pVdbe);69  TEST_ASSERT_TRUE(p->pVdbe->nOp > 0);70  TEST_ASSERT_EQUAL_INT(0, p->nErr);71}72 73/* Cleanup helper: delete VDBE if created */74static void cleanup_parse(Parse *p){75  if( p->pVdbe ){76    sqlite3VdbeDelete(p->pVdbe);77    p->pVdbe = NULL;78  }79}80 81/* Test 1: ANALYZE (form 1) with NULL tokens should generate code for all dbs */82static void test_sqlite3Analyze_analyze_all_generates_vdbe(void){83  /* Create some schema to analyze */84  exec_ok("CREATE TABLE t1(a INTEGER, b TEXT);");85  exec_ok("CREATE INDEX i1 ON t1(a);");86  exec_ok("INSERT INTO t1 VALUES (1,'x'),(2,'y'),(3,'z');");87 88  Parse p;89  call_analyze(NULL, NULL, &p);90  assert_codegen_success(&p);91  cleanup_parse(&p);92}93 94/* Test 2: ANALYZE <database> (form 2) using 'main' */95static void test_sqlite3Analyze_analyze_main_db_generates_vdbe(void){96  exec_ok("CREATE TABLE t2(x);");97 98  Token tDb = makeToken("main");99  Token tEmpty = makeEmptyToken(); /* pName2 must be non-NULL with n==0 */100 101  Parse p;102  call_analyze(&tDb, &tEmpty, &p);103  assert_codegen_success(&p);104  cleanup_parse(&p);105}106 107/* Test 3: ANALYZE <table> (form 3) unqualified table name */108static void test_sqlite3Analyze_analyze_table_unqualified(void){109  exec_ok("CREATE TABLE t3(a, b);");110  exec_ok("CREATE INDEX i3 ON t3(b);");111  exec_ok("INSERT INTO t3 VALUES (10, 'aa'), (20, 'bb');");112 113  Token tTbl = makeToken("t3");114  Token tEmpty = makeEmptyToken();115 116  Parse p;117  call_analyze(&tTbl, &tEmpty, &p);118  assert_codegen_success(&p);119  cleanup_parse(&p);120}121 122/* Test 4: ANALYZE <index> (form 3) by index name */123static void test_sqlite3Analyze_analyze_index_by_name(void){124  exec_ok("CREATE TABLE t4(a, b);");125  exec_ok("CREATE INDEX i4 ON t4(a, b);");126 127  Token tIdx = makeToken("i4");128  Token tEmpty = makeEmptyToken();129 130  Parse p;131  call_analyze(&tIdx, &tEmpty, &p);132  assert_codegen_success(&p);133  cleanup_parse(&p);134}135 136/* Test 5: ANALYZE <schema>.<table> (form 3) qualified name */137static void test_sqlite3Analyze_analyze_table_qualified(void){138  exec_ok("CREATE TABLE t5(a, b);");139  exec_ok("CREATE INDEX i5 ON t5(a);");140 141  Token tDb = makeToken("main");142  Token tTbl = makeToken("t5");143 144  Parse p;145  call_analyze(&tDb, &tTbl, &p);146  assert_codegen_success(&p);147  cleanup_parse(&p);148}149 150/* Test 6: Non-existent table should set parse error (nErr>0) */151static void test_sqlite3Analyze_nonexistent_table_sets_error(void){152  Token tTbl = makeToken("no_such_table");153  Token tEmpty = makeEmptyToken();154 155  Parse p;156  call_analyze(&tTbl, &tEmpty, &p);157 158  /* Expect a parse error due to sqlite3LocateTable() failure */159  TEST_ASSERT_TRUE(p.nErr > 0);160  /* A VDBE object may or may not be present; if present it should be valid */161  if( p.pVdbe ){162    TEST_ASSERT_TRUE(p.pVdbe->nOp >= 0);163  }164  cleanup_parse(&p);165}166 167/* Test 7: ANALYZE temp database explicitly (form 2) */168static void test_sqlite3Analyze_analyze_temp_db(void){169  exec_ok("CREATE TEMP TABLE tt(x);");170  exec_ok("CREATE INDEX temp.ti ON tt(x);");171  exec_ok("INSERT INTO tt VALUES (1),(2),(3);");172 173  Token tDb = makeToken("temp");174  Token tEmpty = makeEmptyToken();175 176  Parse p;177  call_analyze(&tDb, &tEmpty, &p);178  assert_codegen_success(&p);179  cleanup_parse(&p);180}181 182int main(void) {183  UNITY_BEGIN();184  RUN_TEST(test_sqlite3Analyze_analyze_all_generates_vdbe);185  RUN_TEST(test_sqlite3Analyze_analyze_main_db_generates_vdbe);186  RUN_TEST(test_sqlite3Analyze_analyze_table_unqualified);187  RUN_TEST(test_sqlite3Analyze_analyze_index_by_name);188  RUN_TEST(test_sqlite3Analyze_analyze_table_qualified);189  RUN_TEST(test_sqlite3Analyze_nonexistent_table_sets_error);190  RUN_TEST(test_sqlite3Analyze_analyze_temp_db);191  return UNITY_END();192}