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