Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Correctly handle comparing an INTEGER PRIMARY KEY against a floating point number. Ticket #377. (CVS 1045) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
982aa3356bcc217003cd9e6a82961921 |
User & Date: | drh 2003-07-06 17:22:25.000 |
Context
2003-07-07
| ||
00:10 | Update the NULL-handling document to show current behavior of OCELOT. (CVS 1046) (check-in: 1d4c92c732 user: drh tags: trunk) | |
2003-07-06
| ||
17:22 | Correctly handle comparing an INTEGER PRIMARY KEY against a floating point number. Ticket #377. (CVS 1045) (check-in: 982aa3356b user: drh tags: trunk) | |
2003-07-01
| ||
18:13 | Make sure indices in ATTACH-ed databases are put into the right hash table. Ticket #354. (CVS 1044) (check-in: eb4582831d user: drh tags: trunk) | |
Changes
Changes to src/vdbe.c.
︙ | ︙ | |||
32 33 34 35 36 37 38 | ** ** Various scripts scan this source file in order to generate HTML ** documentation, headers files, or other derived files. The formatting ** of the code in this file is, therefore, important. See other comments ** in this file for details. If in doubt, do not deviate from existing ** commenting and indentation practices when changing or adding code. ** | | | 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | ** ** Various scripts scan this source file in order to generate HTML ** documentation, headers files, or other derived files. The formatting ** of the code in this file is, therefore, important. See other comments ** in this file for details. If in doubt, do not deviate from existing ** commenting and indentation practices when changing or adding code. ** ** $Id: vdbe.c,v 1.232 2003/07/06 17:22:25 drh Exp $ */ #include "sqliteInt.h" #include "os.h" #include <ctype.h> /* ** The makefile scans this source file and creates the following |
︙ | ︙ | |||
2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 | case OP_AddImm: { int tos = p->tos; VERIFY( if( tos<0 ) goto not_enough_stack; ) Integerify(p, tos); aStack[tos].i += pOp->p1; break; } /* Opcode: MustBeInt P1 P2 * ** ** Force the top of the stack to be an integer. If the top of the ** stack is not an integer and cannot be converted into an integer ** with out data loss, then jump immediately to P2, or if P2==0 ** raise an SQLITE_MISMATCH exception. | > > > > > > > > > > > > > > > > > > > > > > > > | 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 | case OP_AddImm: { int tos = p->tos; VERIFY( if( tos<0 ) goto not_enough_stack; ) Integerify(p, tos); aStack[tos].i += pOp->p1; break; } /* Opcode: IsNumeric P1 P2 * ** ** Check the top of the stack to see if it is a numeric value. A numeric ** value is an integer, a real number, or a string that looks like an ** integer or a real number. When P1==0, pop the stack and jump to P2 ** if the value is numeric. Otherwise fall through and leave the stack ** unchanged. The sense of the test is inverted when P1==1. */ case OP_IsNumeric: { int tos = p->tos; int r; VERIFY( if( tos<0 ) goto not_enough_stack; ) r = (aStack[tos].flags & (STK_Int|STK_Real))!=0 || (zStack[tos] && sqliteIsNumber(zStack[tos])); if( pOp->p1 ){ r = !r; } if( r ){ POPSTACK; pc = pOp->p2 - 1; } break; } /* Opcode: MustBeInt P1 P2 * ** ** Force the top of the stack to be an integer. If the top of the ** stack is not an integer and cannot be converted into an integer ** with out data loss, then jump immediately to P2, or if P2==0 ** raise an SQLITE_MISMATCH exception. |
︙ | ︙ | |||
2290 2291 2292 2293 2294 2295 2296 | if( r!=aStack[tos].r ){ goto mismatch; } aStack[tos].i = i; }else if( aStack[tos].flags & STK_Str ){ int v; if( !toInt(zStack[tos], &v) ){ | > > | | > > > > > > > > | | | 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 | if( r!=aStack[tos].r ){ goto mismatch; } aStack[tos].i = i; }else if( aStack[tos].flags & STK_Str ){ int v; if( !toInt(zStack[tos], &v) ){ double r; if( !sqliteIsNumber(zStack[tos]) ){ goto mismatch; } Realify(p, tos); assert( (aStack[tos].flags & STK_Real)!=0 ); v = aStack[tos].r; r = (double)v; if( r!=aStack[tos].r ){ goto mismatch; } } aStack[tos].i = v; }else{ goto mismatch; } Release(p, tos); aStack[tos].flags = STK_Int; break; mismatch: if( pOp->p2==0 ){ rc = SQLITE_MISMATCH; goto abort_due_to_error; }else{ |
︙ | ︙ |
Changes to src/where.c.
︙ | ︙ | |||
8 9 10 11 12 13 14 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This module contains C code that generates VDBE code used to process ** the WHERE clause of SQL statements. ** | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This module contains C code that generates VDBE code used to process ** the WHERE clause of SQL statements. ** ** $Id: where.c,v 1.80 2003/07/06 17:22:25 drh Exp $ */ #include "sqliteInt.h" /* ** The query generator uses an array of instances of this structure to ** help it analyze the subexpressions of the WHERE clause. Each WHERE ** clause subexpression is separated from the others by an AND operator. |
︙ | ︙ | |||
849 850 851 852 853 854 855 | assert( aExpr[k].p!=0 ); assert( aExpr[k].idxLeft==iCur || aExpr[k].idxRight==iCur ); if( aExpr[k].idxLeft==iCur ){ sqliteExprCode(pParse, aExpr[k].p->pRight); }else{ sqliteExprCode(pParse, aExpr[k].p->pLeft); } | | | | 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 | assert( aExpr[k].p!=0 ); assert( aExpr[k].idxLeft==iCur || aExpr[k].idxRight==iCur ); if( aExpr[k].idxLeft==iCur ){ sqliteExprCode(pParse, aExpr[k].p->pRight); }else{ sqliteExprCode(pParse, aExpr[k].p->pLeft); } sqliteVdbeAddOp(v, OP_IsNumeric, 1, brk); if( aExpr[k].p->op==TK_LT || aExpr[k].p->op==TK_GT ){ sqliteVdbeAddOp(v, OP_AddImm, 1, 0); } sqliteVdbeAddOp(v, OP_MoveTo, iCur, brk); aExpr[k].p = 0; }else{ sqliteVdbeAddOp(v, OP_Rewind, iCur, brk); } if( iDirectLt[i]>=0 ){ k = iDirectLt[i]; assert( k<nExpr ); assert( aExpr[k].p!=0 ); assert( aExpr[k].idxLeft==iCur || aExpr[k].idxRight==iCur ); if( aExpr[k].idxLeft==iCur ){ sqliteExprCode(pParse, aExpr[k].p->pRight); }else{ sqliteExprCode(pParse, aExpr[k].p->pLeft); } /* sqliteVdbeAddOp(v, OP_MustBeInt, 0, sqliteVdbeCurrentAddr(v)+1); */ pLevel->iMem = pParse->nMem++; sqliteVdbeAddOp(v, OP_MemStore, pLevel->iMem, 0); if( aExpr[k].p->op==TK_LT || aExpr[k].p->op==TK_GT ){ testOp = OP_Ge; }else{ testOp = OP_Gt; } |
︙ | ︙ |
Changes to test/rowid.test.
︙ | ︙ | |||
8 9 10 11 12 13 14 | # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. The # focus of this file is testing the magic ROWID column that is # found on all tables. # | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. The # focus of this file is testing the magic ROWID column that is # found on all tables. # # $Id: rowid.test,v 1.12 2003/07/06 17:22:25 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl # Basic ROWID functionality tests. # do_test rowid-1.1 { |
︙ | ︙ | |||
412 413 414 415 416 417 418 419 | } } {123 124} do_test rowid-8.8 { execsql { SELECT rowid, * FROM t4; } } {1 1 2 133 3 134} | > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 | } } {123 124} do_test rowid-8.8 { execsql { SELECT rowid, * FROM t4; } } {1 1 2 133 3 134} # ticket #377: Comparison between integer primiary key and floating point # values. # do_test rowid-9.1 { execsql { SELECT * FROM t3 WHERE a<123.5 } } {123} do_test rowid-9.2 { execsql { SELECT * FROM t3 WHERE a<124.5 } } {123 124} do_test rowid-9.3 { execsql { SELECT * FROM t3 WHERE a>123.5 } } {124} do_test rowid-9.4 { execsql { SELECT * FROM t3 WHERE a>122.5 } } {123 124} do_test rowid-9.5 { execsql { SELECT * FROM t3 WHERE a==123.5 } } {} do_test rowid-9.6 { execsql { SELECT * FROM t3 WHERE a==123.000 } } {123} do_test rowid-9.7 { execsql { SELECT * FROM t3 WHERE a>100.5 AND a<200.5 } } {123 124} do_test rowid-9.8 { execsql { SELECT * FROM t3 WHERE a>'xyz'; } } {} do_test rowid-9.9 { execsql { SELECT * FROM t3 WHERE a<'xyz'; } } {123 124} do_test rowid-9.10 { execsql { SELECT * FROM t3 WHERE a>=122.9 AND a<=123.1 } } {123} finish_test |