Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Fix some integer overflow problems that can occur when using large langauge id values. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | fts4-incr-merge |
Files: | files | file ages | folders |
SHA1: |
3475092cff862080a020d386076d739f |
User & Date: | dan 2012-03-16 15:54:19.453 |
References
2012-03-16
| ||
16:52 | Cherrypick the [3475092cff] fix for 32-bit overflow with large language-ids into trunk. (check-in: 2755edc7f1 user: drh tags: trunk) | |
Context
2012-03-17
| ||
16:56 | Fix various incorrect and missing comments and other style issues in and around the FTS incremental merge code. (check-in: 7aabb62c8c user: dan tags: fts4-incr-merge) | |
2012-03-16
| ||
15:54 | Fix some integer overflow problems that can occur when using large langauge id values. (check-in: 3475092cff user: dan tags: fts4-incr-merge) | |
14:54 | Add a comment to the FTS getAbsoluteLevel() function. No actual code changes. (check-in: 7e0f861bed user: dan tags: fts4-incr-merge) | |
Changes
Changes to ext/fts3/fts3_write.c.
︙ | |||
506 507 508 509 510 511 512 513 514 515 | 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 | + + - + + | */ static sqlite3_int64 getAbsoluteLevel( Fts3Table *p, /* FTS3 table handle */ int iLangid, /* Language id */ int iIndex, /* Index in p->aIndex[] */ int iLevel /* Level of segments */ ){ sqlite3_int64 iBase; /* First absolute level for iLangid/iIndex */ assert( iLangid>=0 ); assert( p->nIndex>0 ); assert( iIndex>=0 && iIndex<p->nIndex ); |
︙ | |||
552 553 554 555 556 557 558 | 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 | - + - + - + | ** 3: end_block ** 4: root */ int sqlite3Fts3AllSegdirs( Fts3Table *p, /* FTS3 table */ int iLangid, /* Language being queried */ int iIndex, /* Index for p->aIndex[] */ |
︙ | |||
1850 1851 1852 1853 1854 1855 1856 | 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 | - + - + | } /* ** Insert a record into the %_segdir table. */ static int fts3WriteSegdir( Fts3Table *p, /* Virtual table handle */ |
︙ | |||
2244 2245 2246 2247 2248 2249 2250 | 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 | - + | ** database. This function must be called after all terms have been added ** to the segment using fts3SegWriterAdd(). If successful, SQLITE_OK is ** returned. Otherwise, an SQLite error code. */ static int fts3SegWriterFlush( Fts3Table *p, /* Virtual table handle */ SegmentWriter *pWriter, /* SegmentWriter to flush to the db */ |
︙ | |||
2326 2327 2328 2329 2330 2331 2332 | 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 | - + - - + + - + | ** ** Return SQLITE_OK if successful, or an SQLite error code if not. */ static int fts3SegmentMaxLevel( Fts3Table *p, int iLangid, int iIndex, |
︙ | |||
2410 2411 2412 2413 2414 2415 2416 | 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 | - - + + + - + + | return rc; } assert( iLevel>=0 || iLevel==FTS3_SEGCURSOR_ALL ); if( iLevel==FTS3_SEGCURSOR_ALL ){ rc = fts3SqlStmt(p, SQL_DELETE_SEGDIR_RANGE, &pDelete, 0); if( rc==SQLITE_OK ){ |
︙ | |||
2895 2896 2897 2898 2899 2900 2901 | 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 | - + | Fts3Table *p, int iLangid, /* Language id to merge */ int iIndex, /* Index in p->aIndex[] to merge */ int iLevel /* Level to merge */ ){ int rc; /* Return code */ int iIdx = 0; /* Index of new segment */ |
︙ | |||
3860 3861 3862 3863 3864 3865 3866 | 3865 3866 3867 3868 3869 3870 3871 3872 3873 3874 3875 3876 3877 3878 3879 | - + | sqlite3_stmt *pFirstBlock = 0; /* SQL used to determine first block */ sqlite3_stmt *pOutputIdx = 0; /* SQL used to find output index */ const char *zKey = pCsr->zTerm; int nKey = pCsr->nTerm; rc = fts3SqlStmt(p, SQL_NEXT_SEGMENT_INDEX, &pOutputIdx, 0); if( rc==SQLITE_OK ){ |
︙ |
Changes to test/fts4langid.test.
︙ | |||
377 378 379 380 381 382 383 384 385 | 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 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 476 477 478 479 480 481 482 483 484 485 486 487 | + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + | do_execsql_test 4.1.4.$i { SELECT count(*) FROM t4 WHERE t4 MATCH 'fox' AND lid=$i; } [expr 0==($i%2)] } do_catchsql_test 4.1.5 { INSERT INTO t4(content, lid) VALUES('hello world', 101) } {1 {SQL logic error or missing database}} #------------------------------------------------------------------------- # Test cases 5.* # # The following test cases are designed to detect a 32-bit overflow bug # that existed at one point. # proc build_multilingual_db_3 {db} { $db eval { CREATE VIRTUAL TABLE t5 USING fts4(languageid=lid); } set languages [list 0 1 2 [expr 1<<30]] foreach lid $languages { execsql { INSERT INTO t5(docid, content, lid) VALUES( $lid, 'My language is ' || $lid, $lid ) } } } do_test 5.1.0 { reset_db build_multilingual_db_3 db } {} do_execsql_test 5.1.1 { SELECT level FROM t5_segdir; } [list 0 1024 2048 [expr 1<<40]] do_execsql_test 5.1.2 {SELECT docid FROM t5 WHERE t5 MATCH 'language'} 0 foreach langid [list 0 1 2 [expr 1<<30]] { do_execsql_test 5.2.$langid { SELECT docid FROM t5 WHERE t5 MATCH 'language' AND lid = $langid } $langid } set lid [expr 1<<30] do_execsql_test 5.3.1 { CREATE VIRTUAL TABLE t6 USING fts4(languageid=lid); INSERT INTO t6 VALUES('I belong to language 0!'); } do_test 5.3.2 { for {set i 0} {$i < 20} {incr i} { execsql { INSERT INTO t6(content, lid) VALUES( 'I (row '||$i||') belong to langauge N!', $lid ); } } execsql { SELECT docid FROM t6 WHERE t6 MATCH 'belong' } } {1} do_test 5.3.3 { execsql { SELECT docid FROM t6 WHERE t6 MATCH 'belong' AND lid=$lid} } {2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21} do_execsql_test 5.3.4 { INSERT INTO t6(t6) VALUES('optimize') } {} do_execsql_test 5.3.5 { SELECT docid FROM t6 WHERE t6 MATCH 'belong' } {1} do_execsql_test 5.3.6 { SELECT docid FROM t6 WHERE t6 MATCH 'belong' AND lid=$lid } {2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21} set lid [expr 1<<30] foreach lid [list 4 [expr 1<<30]] { do_execsql_test 5.4.$lid.1 { DELETE FROM t6; SELECT count(*) FROM t6_segdir; SELECT count(*) FROM t6_segments; } {0 0} do_execsql_test 5.4.$lid.2 { INSERT INTO t6(content, lid) VALUES('zero zero zero', $lid); INSERT INTO t6(content, lid) VALUES('zero zero one', $lid); INSERT INTO t6(content, lid) VALUES('zero one zero', $lid); INSERT INTO t6(content, lid) VALUES('zero one one', $lid); INSERT INTO t6(content, lid) VALUES('one zero zero', $lid); INSERT INTO t6(content, lid) VALUES('one zero one', $lid); INSERT INTO t6(content, lid) VALUES('one one zero', $lid); INSERT INTO t6(content, lid) VALUES('one one one', $lid); SELECT docid FROM t6 WHERE t6 MATCH '"zero zero"' AND lid=$lid; } {1 2 5} do_execsql_test 5.4.$lid.3 { SELECT count(*) FROM t6_segdir; SELECT count(*) FROM t6_segments; } {8 0} do_execsql_test 5.4.$lid.4 { INSERT INTO t6(t6) VALUES('merge=100,3'); INSERT INTO t6(t6) VALUES('merge=100,3'); SELECT docid FROM t6 WHERE t6 MATCH '"zero zero"' AND lid=$lid; } {1 2 5} do_execsql_test 5.4.$lid.5 { SELECT count(*) FROM t6_segdir; SELECT count(*) FROM t6_segments; } {4 4} } finish_test |