Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Remove uses of type 'double' from the vdbe. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | sqlite4-num |
Files: | files | file ages | folders |
SHA1: |
e0188231625fd452f0985d3f7e98476d |
User & Date: | dan 2013-05-31 19:19:01.946 |
Context
2013-05-31
| ||
19:34 | Remove OP_Int64 and OP_Real. OP_Num is now used instead. Leaf check-in: 860695f9be user: dan tags: sqlite4-num | |
19:19 | Remove uses of type 'double' from the vdbe. check-in: e018823162 user: dan tags: sqlite4-num | |
17:13 | Use decimal arithmetic in affinity routines. check-in: ae34cd8492 user: dan tags: sqlite4-num | |
Changes
Changes to src/math.c.
︙ | ︙ | |||
502 503 504 505 506 507 508 | return x; } /* ** TODO: This is a placeholder implementation only. */ int sqlite4_num_to_int32(sqlite4_num num, int *piOut){ | < | < > > > > > > | > | > > > > | | | 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 | return x; } /* ** TODO: This is a placeholder implementation only. */ int sqlite4_num_to_int32(sqlite4_num num, int *piOut){ *piOut = sqlite4_num_to_int64(num, 0); return SQLITE4_OK; } int sqlite4_num_to_double(sqlite4_num num, double *pr){ double rRet; int i; rRet = num.m; if( num.sign ) rRet = rRet*-1; for(i=0; i<num.e; i++){ rRet = rRet * 10.0; } for(i=num.e; i<0; i++){ rRet = rRet / 10.0; } *pr = rRet; return SQLITE4_OK; } /* ** Convert the number passed as the first argument to a signed 64-bit ** integer and return the value. If the second argument is not NULL, ** then set the value that it points to 1 if data was lost as part ** of the conversion, or 0 otherwise. */ sqlite4_int64 sqlite4_num_to_int64(sqlite4_num num, int *pbLossy){ static const i64 L10 = (LARGEST_INT64 / 10); i64 iRet; int i; iRet = num.m; if( pbLossy ) *pbLossy = 0; for(i=0; i<num.e; i++){ if( pbLossy && iRet>L10 ) *pbLossy = 1; iRet = iRet * 10; } for(i=num.e; i<0; i++){ if( pbLossy && (iRet % 10) ) *pbLossy = 1; iRet = iRet / 10; } if( num.sign ) iRet = iRet*-1; return iRet; } /* ** Convert an integer into text in the buffer supplied. The ** text is zero-terminated and right-justified in the buffer. ** A pointer to the first character of text is returned. |
︙ | ︙ |
Changes to src/sqlite.h.in.
︙ | ︙ | |||
4112 4113 4114 4115 4116 4117 4118 | int sqlite4_num_isnan(sqlite4_num); sqlite4_num sqlite4_num_round(sqlite4_num, int iDigit); int sqlite4_num_compare(sqlite4_num, sqlite4_num); sqlite4_num sqlite4_num_from_text(const char*, int n, unsigned flags, int*); sqlite4_num sqlite4_num_from_int64(sqlite4_int64); sqlite4_num sqlite4_num_from_double(double); int sqlite4_num_to_int32(sqlite4_num, int*); | | | 4112 4113 4114 4115 4116 4117 4118 4119 4120 4121 4122 4123 4124 4125 4126 | int sqlite4_num_isnan(sqlite4_num); sqlite4_num sqlite4_num_round(sqlite4_num, int iDigit); int sqlite4_num_compare(sqlite4_num, sqlite4_num); sqlite4_num sqlite4_num_from_text(const char*, int n, unsigned flags, int*); sqlite4_num sqlite4_num_from_int64(sqlite4_int64); sqlite4_num sqlite4_num_from_double(double); int sqlite4_num_to_int32(sqlite4_num, int*); sqlite4_int64 sqlite4_num_to_int64(sqlite4_num, int *); int sqlite4_num_to_double(sqlite4_num, double *); int sqlite4_num_to_text(sqlite4_num, char*, int); /* ** CAPI4REF: Flags For Text-To-Numeric Conversion */ #define SQLITE4_PREFIX_ONLY 0x10 |
︙ | ︙ |
Changes to src/vdbe.c.
︙ | ︙ | |||
1233 1234 1235 1236 1237 1238 1239 | pIn2 = &aMem[pOp->p2]; applyNumericAffinity(pIn2); pOut = &aMem[pOp->p3]; flags = pIn1->flags | pIn2->flags; if( (flags & MEM_Null)!=0 ) goto arithmetic_result_is_null; if( (pIn1->flags&MEM_Int) && (pIn2->flags&MEM_Int) ){ | | | | 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 | pIn2 = &aMem[pOp->p2]; applyNumericAffinity(pIn2); pOut = &aMem[pOp->p3]; flags = pIn1->flags | pIn2->flags; if( (flags & MEM_Null)!=0 ) goto arithmetic_result_is_null; if( (pIn1->flags&MEM_Int) && (pIn2->flags&MEM_Int) ){ iA = sqlite4_num_to_int64(pIn1->u.num, 0); iB = sqlite4_num_to_int64(pIn2->u.num, 0); switch( pOp->opcode ){ case OP_Add: if( sqlite4AddInt64(&iB,iA) ) goto fp_math; break; case OP_Subtract: if( sqlite4SubInt64(&iB,iA) ) goto fp_math; break; case OP_Multiply: if( sqlite4MulInt64(&iB,iA) ) goto fp_math; break; case OP_Divide: { if( iA==0 ) goto arithmetic_result_is_null; |
︙ | ︙ | |||
1272 1273 1274 1275 1276 1277 1278 | case OP_Subtract: pOut->u.num = sqlite4_num_sub(num2, num1); break; case OP_Multiply: pOut->u.num = sqlite4_num_mul(num1, num2); break; case OP_Divide: pOut->u.num = sqlite4_num_div(num2, num1); break; default: { | | | | 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 | case OP_Subtract: pOut->u.num = sqlite4_num_sub(num2, num1); break; case OP_Multiply: pOut->u.num = sqlite4_num_mul(num1, num2); break; case OP_Divide: pOut->u.num = sqlite4_num_div(num2, num1); break; default: { iA = sqlite4_num_to_int64(num1, 0); iB = sqlite4_num_to_int64(num2, 0); if( iA==0 ) goto arithmetic_result_is_null; pOut->u.num = sqlite4_num_from_int64(iB % iA); break; } } if( sqlite4_num_isnan(pOut->u.num) ){ |
︙ | ︙ | |||
2573 2574 2575 2576 2577 2578 2579 | Db *pDb; i64 v; assert( pOp->p1>=0 && pOp->p1<db->nDb ); pDb = &db->aDb[pOp->p1]; pIn3 = &aMem[pOp->p3]; sqlite4VdbeMemIntegerify(pIn3); | | | 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 | Db *pDb; i64 v; assert( pOp->p1>=0 && pOp->p1<db->nDb ); pDb = &db->aDb[pOp->p1]; pIn3 = &aMem[pOp->p3]; sqlite4VdbeMemIntegerify(pIn3); v = sqlite4_num_to_int64(pIn3->u.num, 0); rc = sqlite4KVStorePutSchema(pDb->pKV, (u32)v); pDb->pSchema->schema_cookie = (int)v; db->flags |= SQLITE4_InternChanges; if( pOp->p1==1 ){ /* Invalidate all prepared statements whenever the TEMP database ** schema is changed. Ticket #1644 */ sqlite4ExpirePreparedStatements(db); |
︙ | ︙ | |||
3327 3328 3329 3330 3331 3332 3333 | #ifndef SQLITE_OMIT_AUTOINCREMENT if( pOp->p3 && rc==SQLITE4_OK ){ pIn3 = sqlite4RegisterInRootFrame(p, pOp->p3); assert( memIsValid(pIn3) ); REGISTER_TRACE(pOp->p3, pIn3); sqlite4VdbeMemIntegerify(pIn3); assert( (pIn3->flags & MEM_Int)!=0 ); /* mem(P3) holds an integer */ | | | 3327 3328 3329 3330 3331 3332 3333 3334 3335 3336 3337 3338 3339 3340 3341 | #ifndef SQLITE_OMIT_AUTOINCREMENT if( pOp->p3 && rc==SQLITE4_OK ){ pIn3 = sqlite4RegisterInRootFrame(p, pOp->p3); assert( memIsValid(pIn3) ); REGISTER_TRACE(pOp->p3, pIn3); sqlite4VdbeMemIntegerify(pIn3); assert( (pIn3->flags & MEM_Int)!=0 ); /* mem(P3) holds an integer */ i3 = sqlite4_num_to_int64(pIn3->u.num, 0); if( i3==MAX_ROWID ){ rc = SQLITE4_FULL; } if( v<i3 ) v = i3; } #endif pOut->flags = MEM_Int; |
︙ | ︙ | |||
3377 3378 3379 3380 3381 3382 3383 | } }else if( rc==SQLITE4_NOTFOUND ){ rc = SQLITE4_OK; } sqlite4KVCursorClose(pCsr); } | | | 3377 3378 3379 3380 3381 3382 3383 3384 3385 3386 3387 3388 3389 3390 3391 | } }else if( rc==SQLITE4_NOTFOUND ){ rc = SQLITE4_OK; } sqlite4KVCursorClose(pCsr); } i1 = sqlite4_num_to_int64(pIn1->u.num, 0); if( i1>=(i64)iMax ){ i1++; }else{ i1 = iMax+1; } pIn1->u.num = sqlite4_num_from_int64(i1); |
︙ | ︙ | |||
3445 3446 3447 3448 3449 3450 3451 | REGISTER_TRACE(pOp->p2, pData); if( pOp->opcode==OP_Insert ){ pKey = &aMem[pOp->p3]; assert( pKey->flags & MEM_Int ); assert( memIsValid(pKey) ); REGISTER_TRACE(pOp->p3, pKey); | | | 3445 3446 3447 3448 3449 3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 | REGISTER_TRACE(pOp->p2, pData); if( pOp->opcode==OP_Insert ){ pKey = &aMem[pOp->p3]; assert( pKey->flags & MEM_Int ); assert( memIsValid(pKey) ); REGISTER_TRACE(pOp->p3, pKey); iKey = sqlite4_num_to_int64(pKey->u.num, 0); }else{ /* assert( pOp->opcode==OP_InsertInt ); */ iKey = pOp->p3; } if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++; if( pData->flags & MEM_Null ){ |
︙ | ︙ | |||
4308 4309 4310 4311 4312 4313 4314 | Mem *pIn1; pIn1 = sqlite4RegisterInRootFrame(p, pOp->p1); assert( memIsValid(pIn1) ); sqlite4VdbeMemIntegerify(pIn1); pIn2 = &aMem[pOp->p2]; REGISTER_TRACE(pOp->p1, pIn1); sqlite4VdbeMemIntegerify(pIn2); | | | | | | | 4308 4309 4310 4311 4312 4313 4314 4315 4316 4317 4318 4319 4320 4321 4322 4323 4324 4325 4326 4327 4328 4329 4330 4331 4332 4333 4334 4335 4336 4337 4338 4339 4340 4341 4342 4343 4344 4345 4346 4347 4348 4349 4350 4351 4352 4353 4354 4355 4356 4357 4358 4359 4360 4361 4362 4363 4364 4365 4366 4367 4368 4369 4370 4371 4372 4373 4374 4375 4376 4377 4378 4379 4380 | Mem *pIn1; pIn1 = sqlite4RegisterInRootFrame(p, pOp->p1); assert( memIsValid(pIn1) ); sqlite4VdbeMemIntegerify(pIn1); pIn2 = &aMem[pOp->p2]; REGISTER_TRACE(pOp->p1, pIn1); sqlite4VdbeMemIntegerify(pIn2); i1 = sqlite4_num_to_int64(pIn1->u.num, 0); i2 = sqlite4_num_to_int64(pIn2->u.num, 0); if( i1<i2 ){ pIn1->u.num = sqlite4_num_from_int64(i2); } REGISTER_TRACE(pOp->p1, pIn1); break; } #endif /* SQLITE4_OMIT_AUTOINCREMENT */ /* Opcode: IfPos P1 P2 * * * ** ** If the value of register P1 is 1 or greater, jump to P2. ** ** It is illegal to use this instruction on a register that does ** not contain an integer. An assertion fault will result if you try. */ case OP_IfPos: { /* jump, in1 */ i64 i1; pIn1 = &aMem[pOp->p1]; assert( pIn1->flags&MEM_Int ); i1 = sqlite4_num_to_int64(pIn1->u.num, 0); if( i1>0 ){ pc = pOp->p2 - 1; } break; } /* Opcode: IfNeg P1 P2 * * * ** ** If the value of register P1 is less than zero, jump to P2. ** ** It is illegal to use this instruction on a register that does ** not contain an integer. An assertion fault will result if you try. */ case OP_IfNeg: { /* jump, in1 */ i64 i1; pIn1 = &aMem[pOp->p1]; assert( pIn1->flags&MEM_Int ); i1 = sqlite4_num_to_int64(pIn1->u.num, 0); if( i1<0 ){ pc = pOp->p2 - 1; } break; } /* Opcode: IfZero P1 P2 P3 * * ** ** The register P1 must contain an integer. Add literal P3 to the ** value in register P1. If the result is exactly 0, jump to P2. ** ** It is illegal to use this instruction on a register that does ** not contain an integer. An assertion fault will result if you try. */ case OP_IfZero: { /* jump, in1 */ i64 i1; pIn1 = &aMem[pOp->p1]; assert( pIn1->flags&MEM_Int ); i1 = sqlite4_num_to_int64(pIn1->u.num, 0); i1 += pOp->p3; pIn1->u.num = sqlite4_num_from_int64(i1); if( i1==0 ){ pc = pOp->p2 - 1; } break; } |
︙ | ︙ | |||
4954 4955 4956 4957 4958 4959 4960 | cksum = 0; if( pOp->p5 ){ sqlite4Fts5EntryCksum(db, pInfo, pKey, aArg, &cksum); }else{ sqlite4Fts5RowCksum(db, pInfo, pKey, aArg, &cksum); } | | | 4954 4955 4956 4957 4958 4959 4960 4961 4962 4963 4964 4965 4966 4967 4968 | cksum = 0; if( pOp->p5 ){ sqlite4Fts5EntryCksum(db, pInfo, pKey, aArg, &cksum); }else{ sqlite4Fts5RowCksum(db, pInfo, pKey, aArg, &cksum); } i1 = sqlite4_num_to_int64(pOut->u.num, 0); pOut->u.num = sqlite4_num_from_int64(i1 ^ cksum); break; } /* Opcode: FtsOpen P1 P2 P3 P4 P5 ** |
︙ | ︙ |
Changes to src/vdbeapi.c.
︙ | ︙ | |||
1086 1087 1088 1089 1090 1091 1092 | ){ return bindText(pStmt, i, zData, nData, xDel, pDelArg, SQLITE4_UTF16NATIVE); } #endif /* SQLITE4_OMIT_UTF16 */ int sqlite4_bind_value(sqlite4_stmt *pStmt, int i, const sqlite4_value *pValue){ int rc; switch( pValue->type ){ | | < < < < < > | > > > | | | 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 | ){ return bindText(pStmt, i, zData, nData, xDel, pDelArg, SQLITE4_UTF16NATIVE); } #endif /* SQLITE4_OMIT_UTF16 */ int sqlite4_bind_value(sqlite4_stmt *pStmt, int i, const sqlite4_value *pValue){ int rc; switch( pValue->type ){ case SQLITE4_INTEGER: case SQLITE4_FLOAT: { Mem *p = (Mem *)pValue; Vdbe *v = (Vdbe *)pStmt; vdbeUnbind(v, i); v->aVar[i-1].u.num = p->u.num; MemSetTypeFlag(&v->aVar[i-1], (pValue->type==SQLITE4_FLOAT ? MEM_Real : MEM_Int) ); break; } case SQLITE4_BLOB: { rc = sqlite4_bind_blob(pStmt, i, pValue->z, pValue->n, SQLITE4_TRANSIENT, 0); break; } |
︙ | ︙ |
Changes to src/vdbecodec.c.
︙ | ︙ | |||
219 220 221 222 223 224 225 | nOut = 9; for(i=0; i<nIn; i++){ int flags = aIn[i].flags; if( flags & MEM_Null ){ aOut[nOut++] = 0; }else if( flags & MEM_Int ){ i64 i1; | | | 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 | nOut = 9; for(i=0; i<nIn; i++){ int flags = aIn[i].flags; if( flags & MEM_Null ){ aOut[nOut++] = 0; }else if( flags & MEM_Int ){ i64 i1; i1 = sqlite4_num_to_int64(aIn[i].u.num, 0); n = significantBytes(i1); aOut[nOut++] = n+2; nPayload += n; aAux[i].n = n; }else if( flags & MEM_Real ){ sqlite4_num *p = &aIn[i].u.num; int e; |
︙ | ︙ | |||
262 263 264 265 266 267 268 | if( aOut==0 ){ rc = SQLITE4_NOMEM; goto vdbeEncodeData_error; } for(i=0; i<nIn; i++){ int flags = aIn[i].flags; if( flags & MEM_Null ){ /* No content */ }else if( flags & MEM_Int ){ sqlite4_int64 v; | | | 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 | if( aOut==0 ){ rc = SQLITE4_NOMEM; goto vdbeEncodeData_error; } for(i=0; i<nIn; i++){ int flags = aIn[i].flags; if( flags & MEM_Null ){ /* No content */ }else if( flags & MEM_Int ){ sqlite4_int64 v; v = sqlite4_num_to_int64(aIn[i].u.num, 0); n = aAux[i].n; aOut[nOut+(--n)] = v & 0xff; while( n ){ v >>= 8; aOut[nOut+(--n)] = v & 0xff; } nOut += aAux[i].n; |
︙ | ︙ |
Changes to src/vdbemem.c.
︙ | ︙ | |||
308 309 310 311 312 313 314 | ** If pMem is a string or blob, then we make an attempt to convert ** it into a integer and return that. If pMem represents an ** an SQL-NULL value, return 0. ** ** If pMem represents a string value, its encoding might be changed. */ i64 sqlite4VdbeIntValue(Mem *pMem){ | < < < < | < < < < < < < < < < | 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 | ** If pMem is a string or blob, then we make an attempt to convert ** it into a integer and return that. If pMem represents an ** an SQL-NULL value, return 0. ** ** If pMem represents a string value, its encoding might be changed. */ i64 sqlite4VdbeIntValue(Mem *pMem){ assert( pMem->db==0 || sqlite4_mutex_held(pMem->db->mutex) ); assert( EIGHT_BYTE_ALIGNMENT(pMem) ); return sqlite4_num_to_int64(sqlite4VdbeNumValue(pMem), 0); } /* ** Return the best representation of pMem that we can get into a ** double. If pMem is already a double or an integer, return its ** value. If it is a string or blob, try to convert it to a double. ** If it is a NULL, return 0.0. |
︙ | ︙ | |||
349 350 351 352 353 354 355 | ** Extract and return a numeric value from memory cell pMem. This call ** does not modify the contents or flags of *pMem in any way. */ sqlite4_num sqlite4VdbeNumValue(Mem *pMem){ if( pMem->flags & (MEM_Real|MEM_Int) ){ return pMem->u.num; }else if( pMem->flags & (MEM_Str|MEM_Blob) ){ | | | | | | < < < < < < < < < < < < < < < < < < < < | < | | < < < | 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 | ** Extract and return a numeric value from memory cell pMem. This call ** does not modify the contents or flags of *pMem in any way. */ sqlite4_num sqlite4VdbeNumValue(Mem *pMem){ if( pMem->flags & (MEM_Real|MEM_Int) ){ return pMem->u.num; }else if( pMem->flags & (MEM_Str|MEM_Blob) ){ int flags = SQLITE4_PREFIX_ONLY | SQLITE4_IGNORE_WHITESPACE | pMem->enc; return sqlite4_num_from_text(pMem->z, pMem->n, flags, 0); }else{ sqlite4_num zero = {0,0,0,0}; return zero; } } /* ** The MEM structure is already a MEM_Real. Try to also make it a ** MEM_Int if we can. */ void sqlite4VdbeIntegerAffinity(Mem *pMem){ i64 i; int bLossy; assert( pMem->flags & MEM_Real ); assert( (pMem->flags & MEM_RowSet)==0 ); assert( pMem->db==0 || sqlite4_mutex_held(pMem->db->mutex) ); assert( EIGHT_BYTE_ALIGNMENT(pMem) ); i = sqlite4_num_to_int64(pMem->u.num, &bLossy); if( bLossy==0 ){ MemSetTypeFlag(pMem, MEM_Int); pMem->u.num = sqlite4_num_from_int64(i); } } /* ** Convert pMem to type integer. Invalidate any prior representations. */ int sqlite4VdbeMemIntegerify(Mem *pMem){ assert( pMem->db==0 || sqlite4_mutex_held(pMem->db->mutex) ); assert( (pMem->flags & MEM_RowSet)==0 ); assert( EIGHT_BYTE_ALIGNMENT(pMem) ); if( (pMem->flags & MEM_Int)==0 ){ pMem->u.num = sqlite4_num_from_int64(sqlite4VdbeIntValue(pMem)); MemSetTypeFlag(pMem, MEM_Int); } return SQLITE4_OK; } /* ** Convert pMem so that it has types MEM_Real or MEM_Int or both. ** Invalidate any prior representations. ** |
︙ | ︙ | |||
728 729 730 731 732 733 734 | } /* If one value is a number and the other is not, the number is less. ** If both are numbers, compare as reals if one is a real, or as integers ** if both values are integers. */ if( combined_flags&(MEM_Int|MEM_Real) ){ | | < < | | < < < < < < < < < < < < < < < < < < | 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 | } /* If one value is a number and the other is not, the number is less. ** If both are numbers, compare as reals if one is a real, or as integers ** if both values are integers. */ if( combined_flags&(MEM_Int|MEM_Real) ){ if( !(f1&(MEM_Int|MEM_Real)) ) return 1; if( !(f2&(MEM_Int|MEM_Real)) ) return -1; return (sqlite4_num_compare(pMem1->u.num, pMem2->u.num) - 2); } /* If one value is a string and the other is a blob, the string is less. ** If both are strings, compare using the collating functions. */ if( combined_flags&MEM_Str ){ if( (f1 & MEM_Str)==0 ){ |
︙ | ︙ |