AryaWu/sqlite
0
1#include "sqliteInt.h"2#include "unity.h"3#include <string.h>4#include <stdlib.h>5 6/* Globals for test */7static sqlite3 *gDb = NULL;8static Parse gParse;9 10/* Helper: add a RenameToken to gParse.pRename pointing at p */11static RenameToken* addRenameToken(void *p){12 RenameToken *r = (RenameToken*)sqlite3_malloc(sizeof(RenameToken));13 TEST_ASSERT_NOT_NULL(r);14 memset(r, 0, sizeof(*r));15 r->p = p;16 r->pNext = gParse.pRename;17 gParse.pRename = r;18 return r;19}20 21/* Helper: free all RenameToken nodes in gParse.pRename */22static void freeAllRenameTokens(void){23 RenameToken *p = gParse.pRename;24 while( p ){25 RenameToken *pNext = p->pNext;26 sqlite3_free(p);27 p = pNext;28 }29 gParse.pRename = NULL;30}31 32void setUp(void) {33 int rc = sqlite3_open(":memory:", &gDb);34 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);35 memset(&gParse, 0, sizeof(gParse));36 gParse.db = gDb;37 gParse.pRename = NULL;38}39 40void tearDown(void) {41 freeAllRenameTokens();42 if( gDb ){43 int rc = sqlite3_close(gDb);44 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);45 gDb = NULL;46 }47}48 49/* Utility: create an ExprList with a single integer expression and assign alias */50static ExprList* makeExprListWithAlias(Parse *pParse, int val, const char *alias){51 char buf[32];52 sqlite3_snprintf(sizeof(buf), buf, "%d", val);53 Expr *pExpr = sqlite3Expr(pParse->db, TK_INTEGER, buf);54 TEST_ASSERT_NOT_NULL(pExpr);55 ExprList *pList = sqlite3ExprListAppend(pParse, NULL, pExpr);56 TEST_ASSERT_NOT_NULL(pList);57 Token t;58 t.z = (char*)alias;59 t.n = (int)strlen(alias);60 sqlite3ExprListSetName(pParse, pList, &t, 1);61 return pList;62}63 64/* Utility: append another integer expression with alias to an existing list */65static void appendExprWithAlias(Parse *pParse, ExprList **ppList, int val, const char *alias){66 char buf[32];67 sqlite3_snprintf(sizeof(buf), buf, "%d", val);68 Expr *pExpr = sqlite3Expr(pParse->db, TK_INTEGER, buf);69 TEST_ASSERT_NOT_NULL(pExpr);70 *ppList = sqlite3ExprListAppend(pParse, *ppList, pExpr);71 TEST_ASSERT_NOT_NULL(*ppList);72 Token t;73 t.z = (char*)alias;74 t.n = (int)strlen(alias);75 sqlite3ExprListSetName(pParse, *ppList, &t, 1);76}77 78/* Test: passing NULL pEList is a no-op (tokens unchanged) */79void test_sqlite3RenameExprlistUnmap_null_list_noop(void){80 int dummy1 = 0x11;81 int dummy2 = 0x22;82 RenameToken *rt1 = addRenameToken(&dummy1);83 RenameToken *rt2 = addRenameToken(&dummy2);84 85 sqlite3RenameExprlistUnmap(&gParse, NULL);86 87 TEST_ASSERT_EQUAL_PTR(&dummy1, rt1->p);88 TEST_ASSERT_EQUAL_PTR(&dummy2, rt2->p);89}90 91/* Test: unmaps tokens for expression nodes and zEName aliases in the list */92void test_sqlite3RenameExprlistUnmap_unmaps_expr_nodes_and_aliases(void){93 /* Build ExprList with two items: 1 AS a, 2 AS b */94 ExprList *pList = makeExprListWithAlias(&gParse, 1, "a");95 appendExprWithAlias(&gParse, &pList, 2, "b");96 97 /* Capture pointers to alias names and one expression node */98 TEST_ASSERT_TRUE(pList->nExpr >= 2);99 char *zName0 = pList->a[0].zEName;100 char *zName1 = pList->a[1].zEName;101 TEST_ASSERT_NOT_NULL(zName0);102 TEST_ASSERT_NOT_NULL(zName1);103 Expr *pExpr0 = pList->a[0].pExpr;104 TEST_ASSERT_NOT_NULL(pExpr0);105 106 /* Create RenameToken entries for:107 ** - The first expression node pointer (should be unmapped by walker)108 ** - Both alias zEName pointers (should be unmapped by explicit remap)109 ** - An unrelated pointer (should remain unchanged)110 */111 int unrelatedDummy = 0xABCD;112 RenameToken *rtExpr = addRenameToken((void*)pExpr0);113 RenameToken *rtName0 = addRenameToken((void*)zName0);114 RenameToken *rtName1 = addRenameToken((void*)zName1);115 RenameToken *rtUnrelated = addRenameToken(&unrelatedDummy);116 117 /* Call function under test */118 sqlite3RenameExprlistUnmap(&gParse, pList);119 120 /* Validate: mapped tokens for expr and names are cleared; unrelated unchanged */121 TEST_ASSERT_NULL(rtExpr->p);122 TEST_ASSERT_NULL(rtName0->p);123 TEST_ASSERT_NULL(rtName1->p);124 TEST_ASSERT_EQUAL_PTR(&unrelatedDummy, rtUnrelated->p);125 126 sqlite3ExprListDelete(gDb, pList);127}128 129/* Test: when there are no matching tokens (neither expr nodes nor zEName),130** the rename list remains unchanged. */131void test_sqlite3RenameExprlistUnmap_no_matching_tokens(void){132 ExprList *pList = makeExprListWithAlias(&gParse, 3, "c");133 /* Create a token that does not correspond to any node or alias in pList */134 int other = 123;135 RenameToken *rtOther = addRenameToken(&other);136 137 /* Sanity: ensure we did NOT add tokens pointing to pList's nodes or zEName */138 TEST_ASSERT_NOT_NULL(pList->a[0].pExpr);139 TEST_ASSERT_NOT_NULL(pList->a[0].zEName);140 TEST_ASSERT_NOT_EQUAL_PTR(pList->a[0].pExpr, rtOther->p);141 TEST_ASSERT_NOT_EQUAL_PTR(pList->a[0].zEName, rtOther->p);142 143 sqlite3RenameExprlistUnmap(&gParse, pList);144 145 /* No changes expected */146 TEST_ASSERT_EQUAL_PTR(&other, rtOther->p);147 148 sqlite3ExprListDelete(gDb, pList);149}150 151int main(void) {152 UNITY_BEGIN();153 RUN_TEST(test_sqlite3RenameExprlistUnmap_null_list_noop);154 RUN_TEST(test_sqlite3RenameExprlistUnmap_unmaps_expr_nodes_and_aliases);155 RUN_TEST(test_sqlite3RenameExprlistUnmap_no_matching_tokens);156 return UNITY_END();157}