AryaWu/sqlite
0
1#include "sqliteInt.h"2#include "unity.h"3#include <string.h>4#include <stdlib.h>5 6/* Wrapper prototype provided in the source module */7int test_resolveOrderByTermToExprList(Parse *pParse, Select *pSelect, Expr *pE);8 9static sqlite3 *gDb = NULL;10static Parse gParse;11 12/* Helper: Make integer literal expression from C-string number */13static Expr* makeInt(sqlite3 *db, const char *zNum){14 Token t;15 t.z = (char*)zNum;16 t.n = (int)strlen(zNum);17 return sqlite3ExprAlloc(db, TK_INTEGER, &t, 0);18}19 20/* Helper: Make a bare identifier expression (for unresolved name tests) */21static Expr* makeId(sqlite3 *db, const char *zId){22 Token t;23 t.z = (char*)zId;24 t.n = (int)strlen(zId);25 return sqlite3ExprAlloc(db, TK_ID, &t, 0);26}27 28/* Helper: Make a binary expression (left op right) */29static Expr* makeBinary(Parse *pParse, int op, Expr *pLeft, Expr *pRight){30 return sqlite3PExpr(pParse, op, pLeft, pRight);31}32 33/* Helper: Make a unary function call with one argument (e.g., abs(x)) */34static Expr* makeFunc1(Parse *pParse, const char *zFunc, Expr *pArg){35 Token t;36 ExprList *pArgs = 0;37 t.z = (char*)zFunc;38 t.n = (int)strlen(zFunc);39 pArgs = sqlite3ExprListAppend(pParse, 0, pArg);40 return sqlite3ExprFunction(pParse, pArgs, &t);41}42 43/* Helper: Build a Select with only an ExprList (no FROM clause) */44static Select* makeSelect(sqlite3 *db, ExprList *pList){45 Select *pSel = (Select*)sqlite3DbMallocZero(db, sizeof(Select));46 if( pSel ){47 pSel->pEList = pList;48 pSel->pSrc = 0;49 }50 return pSel;51}52 53void setUp(void) {54 int rc = sqlite3_open(":memory:", &gDb);55 TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_OK, rc, "sqlite3_open failed");56 memset(&gParse, 0, sizeof(gParse));57 gParse.db = gDb;58}59 60void tearDown(void) {61 if( gDb ){62 sqlite3_close(gDb);63 gDb = NULL;64 }65}66 67/* Test: Matching identical arithmetic expression in single-column result set */68void test_resolveOrderByTermToExprList_match_simple_arith(void) {69 /* Result set: (1+0) */70 Expr *e10 = makeBinary(&gParse, TK_PLUS, makeInt(gDb, "1"), makeInt(gDb, "0"));71 ExprList *pList = sqlite3ExprListAppend(&gParse, 0, e10);72 Select *pSel = makeSelect(gDb, pList);73 74 /* ORDER BY: (1+0) */75 Expr *pOrder = makeBinary(&gParse, TK_PLUS, makeInt(gDb, "1"), makeInt(gDb, "0"));76 77 int idx = test_resolveOrderByTermToExprList(&gParse, pSel, pOrder);78 TEST_ASSERT_EQUAL_INT(1, idx);79 80 sqlite3ExprDelete(gDb, pOrder);81 sqlite3ExprListDelete(gDb, pList);82 sqlite3DbFree(gDb, pSel);83}84 85/* Test: Non-matching arithmetic expression should return 0 */86void test_resolveOrderByTermToExprList_nonmatch_arith(void) {87 /* Result set: (1+0) */88 Expr *e10 = makeBinary(&gParse, TK_PLUS, makeInt(gDb, "1"), makeInt(gDb, "0"));89 ExprList *pList = sqlite3ExprListAppend(&gParse, 0, e10);90 Select *pSel = makeSelect(gDb, pList);91 92 /* ORDER BY: (2+0) */93 Expr *pOrder = makeBinary(&gParse, TK_PLUS, makeInt(gDb, "2"), makeInt(gDb, "0"));94 95 int idx = test_resolveOrderByTermToExprList(&gParse, pSel, pOrder);96 TEST_ASSERT_EQUAL_INT(0, idx);97 98 sqlite3ExprDelete(gDb, pOrder);99 sqlite3ExprListDelete(gDb, pList);100 sqlite3DbFree(gDb, pSel);101}102 103/* Test: Matching second entry in a multi-column result set */104void test_resolveOrderByTermToExprList_match_second_entry(void) {105 /* Result set: [ (5*2), (3-1) ] */106 ExprList *pList = 0;107 Expr *e0 = makeBinary(&gParse, TK_STAR, makeInt(gDb, "5"), makeInt(gDb, "2"));108 Expr *e1 = makeBinary(&gParse, TK_MINUS, makeInt(gDb, "3"), makeInt(gDb, "1"));109 pList = sqlite3ExprListAppend(&gParse, pList, e0);110 pList = sqlite3ExprListAppend(&gParse, pList, e1);111 Select *pSel = makeSelect(gDb, pList);112 113 /* ORDER BY: (3-1) */114 Expr *pOrder = makeBinary(&gParse, TK_MINUS, makeInt(gDb, "3"), makeInt(gDb, "1"));115 116 int idx = test_resolveOrderByTermToExprList(&gParse, pSel, pOrder);117 TEST_ASSERT_EQUAL_INT(2, idx);118 119 sqlite3ExprDelete(gDb, pOrder);120 sqlite3ExprListDelete(gDb, pList);121 sqlite3DbFree(gDb, pSel);122}123 124/* Test: Matching a simple function expression (built-in function) */125void test_resolveOrderByTermToExprList_match_function_expr(void) {126 /* Result set: [ abs(1-3) ] */127 Expr *arg = makeBinary(&gParse, TK_MINUS, makeInt(gDb, "1"), makeInt(gDb, "3"));128 Expr *eAbs = makeFunc1(&gParse, "abs", arg);129 ExprList *pList = sqlite3ExprListAppend(&gParse, 0, eAbs);130 Select *pSel = makeSelect(gDb, pList);131 132 /* ORDER BY: abs(1-3) */133 Expr *arg2 = makeBinary(&gParse, TK_MINUS, makeInt(gDb, "1"), makeInt(gDb, "3"));134 Expr *pOrder = makeFunc1(&gParse, "abs", arg2);135 136 int idx = test_resolveOrderByTermToExprList(&gParse, pSel, pOrder);137 TEST_ASSERT_EQUAL_INT(1, idx);138 139 sqlite3ExprDelete(gDb, pOrder);140 sqlite3ExprListDelete(gDb, pList);141 sqlite3DbFree(gDb, pSel);142}143 144/* Test: Name resolution error (unresolved identifier) should return 0 */145void test_resolveOrderByTermToExprList_resolution_error_returns_zero(void) {146 /* Result set: [ (1+0) ] - no FROM clause, no aliases */147 Expr *e10 = makeBinary(&gParse, TK_PLUS, makeInt(gDb, "1"), makeInt(gDb, "0"));148 ExprList *pList = sqlite3ExprListAppend(&gParse, 0, e10);149 Select *pSel = makeSelect(gDb, pList);150 151 /* ORDER BY: an unresolved identifier "no_such_col" -> resolution error suppressed -> return 0 */152 Expr *pOrder = makeId(gDb, "no_such_col");153 154 int idx = test_resolveOrderByTermToExprList(&gParse, pSel, pOrder);155 TEST_ASSERT_EQUAL_INT(0, idx);156 157 sqlite3ExprDelete(gDb, pOrder);158 sqlite3ExprListDelete(gDb, pList);159 sqlite3DbFree(gDb, pSel);160}161 162/* Test: Parenthesized expression equality (should still match) */163void test_resolveOrderByTermToExprList_match_with_parentheses(void) {164 /* Result set: [ (1+2) ] */165 Expr *e12 = makeBinary(&gParse, TK_PLUS, makeInt(gDb, "1"), makeInt(gDb, "2"));166 ExprList *pList = sqlite3ExprListAppend(&gParse, 0, e12);167 Select *pSel = makeSelect(gDb, pList);168 169 /* ORDER BY: (1+2) again (structurally identical) */170 Expr *pOrder = makeBinary(&gParse, TK_PLUS, makeInt(gDb, "1"), makeInt(gDb, "2"));171 172 int idx = test_resolveOrderByTermToExprList(&gParse, pSel, pOrder);173 TEST_ASSERT_EQUAL_INT(1, idx);174 175 sqlite3ExprDelete(gDb, pOrder);176 sqlite3ExprListDelete(gDb, pList);177 sqlite3DbFree(gDb, pSel);178}179 180int main(void) {181 UNITY_BEGIN();182 RUN_TEST(test_resolveOrderByTermToExprList_match_simple_arith);183 RUN_TEST(test_resolveOrderByTermToExprList_nonmatch_arith);184 RUN_TEST(test_resolveOrderByTermToExprList_match_second_entry);185 RUN_TEST(test_resolveOrderByTermToExprList_match_function_expr);186 RUN_TEST(test_resolveOrderByTermToExprList_resolution_error_returns_zero);187 RUN_TEST(test_resolveOrderByTermToExprList_match_with_parentheses);188 return UNITY_END();189}