AryaWu/sqlite
0
1#include "sqliteInt.h"2#include "unity.h"3#include <string.h>4#include <stdlib.h>5 6/* Prototype of the auto-generated test wrapper for the static function */7int test_exprNodeIsConstantOrGroupBy(Walker *pWalker, Expr *pExpr);8 9static sqlite3 *gDb = NULL;10static Parse gParse;11 12/* Helpers */13 14static Expr* make_int_expr(Parse *pParse, const char *zNum){15 Token t;16 t.z = zNum;17 t.n = (int)strlen(zNum);18 return sqlite3ExprAlloc(pParse, TK_INTEGER, &t, 0);19}20 21static Expr* make_collate_expr(Parse *pParse, Expr *pLeft, const char *zColl){22 Token t;23 t.z = zColl;24 t.n = (int)strlen(zColl);25 Expr *p = sqlite3ExprAlloc(pParse, TK_COLLATE, &t, 1);26 if( p ){27 p->pLeft = pLeft;28 }29 return p;30}31 32static Expr* make_column_expr(Parse *pParse){33 (void)pParse;34 Expr *p = sqlite3DbMallocZero(gDb, sizeof(Expr));35 if( p ){36 p->op = TK_COLUMN;37 }38 return p;39}40 41static Expr* make_select_expr(Parse *pParse){42 (void)pParse;43 Expr *p = sqlite3DbMallocZero(gDb, sizeof(Expr));44 if( p ){45 p->op = TK_SELECT;46 p->flags |= EP_xIsSelect;47 /* Minimal non-NULL Select object to satisfy ExprUseXSelect() and any deref guards */48 p->x.pSelect = (Select*)sqlite3DbMallocZero(gDb, sizeof(Select));49 }50 return p;51}52 53static ExprList* make_empty_exprlist(sqlite3 *db){54 ExprList *p = (ExprList*)sqlite3DbMallocZero(db, sizeof(ExprList));55 return p; /* nExpr==0, a==NULL */56}57 58static ExprList* make_exprlist_1(Parse *pParse, Expr *pExpr){59 return sqlite3ExprListAppend(pParse, 0, pExpr);60}61 62void setUp(void) {63 memset(&gParse, 0, sizeof(gParse));64 TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &gDb));65 gParse.db = gDb;66}67 68void tearDown(void) {69 if( gDb ){70 sqlite3_close(gDb);71 gDb = NULL;72 }73}74 75/* Test: GROUP BY match with default (binary) collation -> WRC_Prune */76void test_exprNodeIsConstantOrGroupBy_GroupByMatchReturnsPrune(void){77 Expr *pExpr = make_int_expr(&gParse, "1");78 TEST_ASSERT_NOT_NULL(pExpr);79 80 Expr *pGbTerm = make_int_expr(&gParse, "1");81 TEST_ASSERT_NOT_NULL(pGbTerm);82 83 ExprList *pGroupBy = make_exprlist_1(&gParse, pGbTerm);84 TEST_ASSERT_NOT_NULL(pGroupBy);85 86 Walker w;87 memset(&w, 0, sizeof(w));88 w.u.pGroupBy = pGroupBy;89 w.pParse = &gParse;90 w.eCode = 1;91 92 int rc = test_exprNodeIsConstantOrGroupBy(&w, pExpr);93 TEST_ASSERT_EQUAL_INT(WRC_Prune, rc);94}95 96/* Test: pExpr is a sub-select -> sets eCode=0 and returns WRC_Abort */97void test_exprNodeIsConstantOrGroupBy_SubSelectAbort(void){98 Expr *pExpr = make_select_expr(&gParse);99 TEST_ASSERT_NOT_NULL(pExpr);100 TEST_ASSERT_NOT_NULL(pExpr->x.pSelect);101 102 ExprList *pGroupBy = make_empty_exprlist(gDb);103 TEST_ASSERT_NOT_NULL(pGroupBy);104 105 Walker w;106 memset(&w, 0, sizeof(w));107 w.u.pGroupBy = pGroupBy;108 w.pParse = &gParse;109 w.eCode = 123; /* non-zero initial */110 111 int rc = test_exprNodeIsConstantOrGroupBy(&w, pExpr);112 TEST_ASSERT_EQUAL_INT(WRC_Abort, rc);113 TEST_ASSERT_EQUAL_INT(0, w.eCode);114}115 116/* Test: No GROUP BY match, constant literal -> delegates and returns WRC_Continue */117void test_exprNodeIsConstantOrGroupBy_FallbackConstantContinue(void){118 Expr *pExpr = make_int_expr(&gParse, "1");119 TEST_ASSERT_NOT_NULL(pExpr);120 121 ExprList *pGroupBy = make_empty_exprlist(gDb);122 TEST_ASSERT_NOT_NULL(pGroupBy);123 124 Walker w;125 memset(&w, 0, sizeof(w));126 w.u.pGroupBy = pGroupBy;127 w.pParse = &gParse;128 w.eCode = 1; /* looking for constant */129 130 int rc = test_exprNodeIsConstantOrGroupBy(&w, pExpr);131 TEST_ASSERT_EQUAL_INT(WRC_Continue, rc);132 TEST_ASSERT_NOT_EQUAL(0, w.eCode); /* should remain non-zero */133}134 135/* Test: No GROUP BY match, non-constant column -> delegates and returns WRC_Abort with eCode==0 */136void test_exprNodeIsConstantOrGroupBy_FallbackNonConstantAbort(void){137 Expr *pExpr = make_column_expr(&gParse);138 TEST_ASSERT_NOT_NULL(pExpr);139 140 ExprList *pGroupBy = make_empty_exprlist(gDb);141 TEST_ASSERT_NOT_NULL(pGroupBy);142 143 Walker w;144 memset(&w, 0, sizeof(w));145 w.u.pGroupBy = pGroupBy;146 w.pParse = &gParse;147 w.eCode = 1;148 149 int rc = test_exprNodeIsConstantOrGroupBy(&w, pExpr);150 TEST_ASSERT_EQUAL_INT(WRC_Abort, rc);151 TEST_ASSERT_EQUAL_INT(0, w.eCode);152}153 154/* Test: GROUP BY match with non-binary collation (NOCASE) -> do not prune, fallback to constant (WRC_Continue) */155void test_exprNodeIsConstantOrGroupBy_GroupByMatchNonBinaryCollationDoesNotPrune(void){156 Expr *pExpr = make_int_expr(&gParse, "1");157 TEST_ASSERT_NOT_NULL(pExpr);158 159 Expr *pLeft = make_int_expr(&gParse, "1");160 TEST_ASSERT_NOT_NULL(pLeft);161 Expr *pGbTerm = make_collate_expr(&gParse, pLeft, "nocase");162 TEST_ASSERT_NOT_NULL(pGbTerm);163 164 ExprList *pGroupBy = make_exprlist_1(&gParse, pGbTerm);165 TEST_ASSERT_NOT_NULL(pGroupBy);166 167 Walker w;168 memset(&w, 0, sizeof(w));169 w.u.pGroupBy = pGroupBy;170 w.pParse = &gParse;171 w.eCode = 1;172 173 int rc = test_exprNodeIsConstantOrGroupBy(&w, pExpr);174 /* Not pruned; should continue as constant literal */175 TEST_ASSERT_EQUAL_INT(WRC_Continue, rc);176}177 178/* Test: GROUP BY match with explicit COLLATE BINARY -> prune */179void test_exprNodeIsConstantOrGroupBy_GroupByMatchExplicitBinaryCollationPrune(void){180 Expr *pExpr = make_int_expr(&gParse, "1");181 TEST_ASSERT_NOT_NULL(pExpr);182 183 Expr *pLeft = make_int_expr(&gParse, "1");184 TEST_ASSERT_NOT_NULL(pLeft);185 Expr *pGbTerm = make_collate_expr(&gParse, pLeft, "BINARY");186 TEST_ASSERT_NOT_NULL(pGbTerm);187 188 ExprList *pGroupBy = make_exprlist_1(&gParse, pGbTerm);189 TEST_ASSERT_NOT_NULL(pGroupBy);190 191 Walker w;192 memset(&w, 0, sizeof(w));193 w.u.pGroupBy = pGroupBy;194 w.pParse = &gParse;195 w.eCode = 42;196 197 int rc = test_exprNodeIsConstantOrGroupBy(&w, pExpr);198 TEST_ASSERT_EQUAL_INT(WRC_Prune, rc);199}200 201int main(void){202 UNITY_BEGIN();203 RUN_TEST(test_exprNodeIsConstantOrGroupBy_GroupByMatchReturnsPrune);204 RUN_TEST(test_exprNodeIsConstantOrGroupBy_SubSelectAbort);205 RUN_TEST(test_exprNodeIsConstantOrGroupBy_FallbackConstantContinue);206 RUN_TEST(test_exprNodeIsConstantOrGroupBy_FallbackNonConstantAbort);207 RUN_TEST(test_exprNodeIsConstantOrGroupBy_GroupByMatchNonBinaryCollationDoesNotPrune);208 RUN_TEST(test_exprNodeIsConstantOrGroupBy_GroupByMatchExplicitBinaryCollationPrune);209 return UNITY_END();210}