AryaWu/sqlite
0
1#include "sqliteInt.h"2#include "unity.h"3#include <string.h>4#include <stdlib.h>5#include <math.h>6 7/* Prototype of the wrapper exposed for testing static function */8void test_codeInteger(Parse *pParse, Expr *pExpr, int negFlag, int iMem);9 10static sqlite3 *gDb = NULL;11 12/* Helpers */13static void setupParseAndVdbe(Parse *pParse, Vdbe **ppVdbe){14 memset(pParse, 0, sizeof(*pParse));15 int rc = sqlite3_open(":memory:", &gDb);16 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);17 pParse->db = gDb;18 Vdbe *v = sqlite3VdbeCreate(pParse);19 TEST_ASSERT_NOT_NULL(v);20 TEST_ASSERT_EQUAL_PTR(v, pParse->pVdbe);21 *ppVdbe = v;22}23 24static void cleanupParseAndVdbe(Parse *pParse){25 if( pParse && pParse->pVdbe ){26 sqlite3VdbeDelete(pParse->pVdbe);27 pParse->pVdbe = 0;28 }29 if( gDb ){30 int rc = sqlite3_close(gDb);31 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);32 gDb = NULL;33 }34}35 36/* Unity required hooks */37void setUp(void) {38 /* Setup is performed per-test via setupParseAndVdbe */39}40void tearDown(void) {41 /* Cleanup is performed per-test via cleanupParseAndVdbe */42}43 44/* Test cases */45 46void test_codeInteger_EP_IntValue_positive_no_negate(void){47 Parse p; Vdbe *v;48 setupParseAndVdbe(&p, &v);49 50 Expr e;51 memset(&e, 0, sizeof(e));52 e.flags = EP_IntValue;53 e.u.iValue = 123; /* must be >= 0 per code assertion */54 55 int before = v->nOp;56 test_codeInteger(&p, &e, 0, 7);57 58 TEST_ASSERT_EQUAL_INT(before+1, v->nOp);59 VdbeOp *op = &v->aOp[v->nOp-1];60 TEST_ASSERT_EQUAL_INT(OP_Integer, op->opcode);61 TEST_ASSERT_EQUAL_INT(123, op->p1);62 TEST_ASSERT_EQUAL_INT(7, op->p2);63 TEST_ASSERT_EQUAL_INT(P4_NOTUSED, op->p4type);64 65 cleanupParseAndVdbe(&p);66}67 68void test_codeInteger_EP_IntValue_with_negate(void){69 Parse p; Vdbe *v;70 setupParseAndVdbe(&p, &v);71 72 Expr e;73 memset(&e, 0, sizeof(e));74 e.flags = EP_IntValue;75 e.u.iValue = 456;76 77 int before = v->nOp;78 test_codeInteger(&p, &e, 1, 3);79 80 TEST_ASSERT_EQUAL_INT(before+1, v->nOp);81 VdbeOp *op = &v->aOp[v->nOp-1];82 TEST_ASSERT_EQUAL_INT(OP_Integer, op->opcode);83 TEST_ASSERT_EQUAL_INT(-456, op->p1);84 TEST_ASSERT_EQUAL_INT(3, op->p2);85 TEST_ASSERT_EQUAL_INT(P4_NOTUSED, op->p4type);86 87 cleanupParseAndVdbe(&p);88}89 90void test_codeInteger_zToken_small_decimal_positive_to_Int64(void){91 Parse p; Vdbe *v;92 setupParseAndVdbe(&p, &v);93 94 Expr e;95 memset(&e, 0, sizeof(e));96 e.u.zToken = "42";97 98 int before = v->nOp;99 test_codeInteger(&p, &e, 0, 5);100 101 TEST_ASSERT_EQUAL_INT(before+1, v->nOp);102 VdbeOp *op = &v->aOp[v->nOp-1];103 TEST_ASSERT_EQUAL_INT(OP_Int64, op->opcode);104 TEST_ASSERT_EQUAL_INT(0, op->p1);105 TEST_ASSERT_EQUAL_INT(5, op->p2);106 TEST_ASSERT_EQUAL_INT(P4_INT64, op->p4type);107 TEST_ASSERT_NOT_NULL(op->p4.pI64);108 TEST_ASSERT_EQUAL_INT64(42, *op->p4.pI64);109 110 cleanupParseAndVdbe(&p);111}112 113void test_codeInteger_zToken_small_decimal_negative_to_Int64(void){114 Parse p; Vdbe *v;115 setupParseAndVdbe(&p, &v);116 117 Expr e;118 memset(&e, 0, sizeof(e));119 e.u.zToken = "42";120 121 int before = v->nOp;122 test_codeInteger(&p, &e, 1, 8);123 124 TEST_ASSERT_EQUAL_INT(before+1, v->nOp);125 VdbeOp *op = &v->aOp[v->nOp-1];126 TEST_ASSERT_EQUAL_INT(OP_Int64, op->opcode);127 TEST_ASSERT_EQUAL_INT(0, op->p1);128 TEST_ASSERT_EQUAL_INT(8, op->p2);129 TEST_ASSERT_EQUAL_INT(P4_INT64, op->p4type);130 TEST_ASSERT_NOT_NULL(op->p4.pI64);131 TEST_ASSERT_EQUAL_INT64(-42, *op->p4.pI64);132 133 cleanupParseAndVdbe(&p);134}135 136void test_codeInteger_zToken_hex_in_range_to_Int64(void){137 Parse p; Vdbe *v;138 setupParseAndVdbe(&p, &v);139 140 Expr e;141 memset(&e, 0, sizeof(e));142 e.u.zToken = "0x7FFFFFFFFFFFFFFF"; /* max positive signed 64-bit */143 144 int before = v->nOp;145 test_codeInteger(&p, &e, 0, 2);146 147 TEST_ASSERT_EQUAL_INT(before+1, v->nOp);148 VdbeOp *op = &v->aOp[v->nOp-1];149 TEST_ASSERT_EQUAL_INT(OP_Int64, op->opcode);150 TEST_ASSERT_EQUAL_INT(0, op->p1);151 TEST_ASSERT_EQUAL_INT(2, op->p2);152 TEST_ASSERT_EQUAL_INT(P4_INT64, op->p4type);153 TEST_ASSERT_NOT_NULL(op->p4.pI64);154 TEST_ASSERT_EQUAL_INT64(9223372036854775807LL, *op->p4.pI64);155 156 cleanupParseAndVdbe(&p);157}158 159void test_codeInteger_zToken_hex_overflow_sets_error_and_no_op(void){160 Parse p; Vdbe *v;161 setupParseAndVdbe(&p, &v);162 163 Expr e;164 memset(&e, 0, sizeof(e));165 e.u.zToken = "0x8000000000000000"; /* 2^63 -> too large for signed */166 167 int before = v->nOp;168 int prevErr = p.nErr;169 test_codeInteger(&p, &e, 0, 4);170 171 /* No new opcode should be emitted on oversized hex literal */172 TEST_ASSERT_EQUAL_INT(before, v->nOp);173 TEST_ASSERT_TRUE(p.nErr > prevErr);174 TEST_ASSERT_NOT_NULL(p.zErrMsg);175 176 cleanupParseAndVdbe(&p);177}178 179void test_codeInteger_zToken_decimal_overflow_to_Real(void){180 Parse p; Vdbe *v;181 setupParseAndVdbe(&p, &v);182 183 Expr e;184 memset(&e, 0, sizeof(e));185 e.u.zToken = "9223372036854775808"; /* one above max signed */186 187 int before = v->nOp;188 test_codeInteger(&p, &e, 0, 9);189 190 TEST_ASSERT_EQUAL_INT(before+1, v->nOp);191 VdbeOp *op = &v->aOp[v->nOp-1];192 TEST_ASSERT_EQUAL_INT(OP_Real, op->opcode);193 TEST_ASSERT_EQUAL_INT(0, op->p1);194 TEST_ASSERT_EQUAL_INT(9, op->p2);195 TEST_ASSERT_EQUAL_INT(P4_REAL, op->p4type);196 TEST_ASSERT_NOT_NULL(op->p4.pReal);197 double got = *op->p4.pReal;198 /* Within a large tolerance due to double precision on huge integers */199 TEST_ASSERT_DOUBLE_WITHIN(1e6, 9223372036854775808.0, got);200 201 cleanupParseAndVdbe(&p);202}203 204void test_codeInteger_zToken_negate_smallest_int64_boundary_to_Real(void){205 Parse p; Vdbe *v;206 setupParseAndVdbe(&p, &v);207 208 Expr e;209 memset(&e, 0, sizeof(e));210 e.u.zToken = "9223372036854775808"; /* SMALLEST_INT64 magnitude */211 212 int before = v->nOp;213 test_codeInteger(&p, &e, 1, 11);214 215 TEST_ASSERT_EQUAL_INT(before+1, v->nOp);216 VdbeOp *op = &v->aOp[v->nOp-1];217 TEST_ASSERT_EQUAL_INT(OP_Real, op->opcode);218 TEST_ASSERT_EQUAL_INT(0, op->p1);219 TEST_ASSERT_EQUAL_INT(11, op->p2);220 TEST_ASSERT_EQUAL_INT(P4_REAL, op->p4type);221 TEST_ASSERT_NOT_NULL(op->p4.pReal);222 double got = *op->p4.pReal;223 TEST_ASSERT_DOUBLE_WITHIN(1e6, -9223372036854775808.0, got);224 225 cleanupParseAndVdbe(&p);226}227 228void test_codeInteger_zToken_invalid_string_routes_to_Real(void){229 Parse p; Vdbe *v;230 setupParseAndVdbe(&p, &v);231 232 Expr e;233 memset(&e, 0, sizeof(e));234 e.u.zToken = "notanumber";235 236 int before = v->nOp;237 test_codeInteger(&p, &e, 0, 13);238 239 TEST_ASSERT_EQUAL_INT(before+1, v->nOp);240 VdbeOp *op = &v->aOp[v->nOp-1];241 TEST_ASSERT_EQUAL_INT(OP_Real, op->opcode);242 TEST_ASSERT_EQUAL_INT(13, op->p2);243 TEST_ASSERT_EQUAL_INT(P4_REAL, op->p4type);244 TEST_ASSERT_NOT_NULL(op->p4.pReal);245 /* sqlite3AtoF("notanumber") yields 0.0 */246 TEST_ASSERT_DOUBLE_IS_WITHIN(1e-12, 0.0, *op->p4.pReal);247 248 cleanupParseAndVdbe(&p);249}250 251int main(void){252 UNITY_BEGIN();253 RUN_TEST(test_codeInteger_EP_IntValue_positive_no_negate);254 RUN_TEST(test_codeInteger_EP_IntValue_with_negate);255 RUN_TEST(test_codeInteger_zToken_small_decimal_positive_to_Int64);256 RUN_TEST(test_codeInteger_zToken_small_decimal_negative_to_Int64);257 RUN_TEST(test_codeInteger_zToken_hex_in_range_to_Int64);258 RUN_TEST(test_codeInteger_zToken_hex_overflow_sets_error_and_no_op);259 RUN_TEST(test_codeInteger_zToken_decimal_overflow_to_Real);260 RUN_TEST(test_codeInteger_zToken_negate_smallest_int64_boundary_to_Real);261 RUN_TEST(test_codeInteger_zToken_invalid_string_routes_to_Real);262 return UNITY_END();263}