Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Fix bug in the premutation testing that was causing many permutations from begin skipped. There are now 16 errors reported by the permutation test. (CVS 5610) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
4ad096bda1fc5c7b66f71ff5b32a4085 |
User & Date: | drh 2008-08-25 17:23:29.000 |
Context
2008-08-25
| ||
19:09 | Fix obscure permutation test problems. (CVS 5611) (check-in: aa92a1bec3 user: drh tags: trunk) | |
17:23 | Fix bug in the premutation testing that was causing many permutations from begin skipped. There are now 16 errors reported by the permutation test. (CVS 5610) (check-in: 4ad096bda1 user: drh tags: trunk) | |
14:49 | Pick up a small performance increase by eliminating the pcacheRef() function. (CVS 5609) (check-in: e3840fbf0a user: danielk1977 tags: trunk) | |
Changes
Changes to src/pager.c.
︙ | ︙ | |||
14 15 16 17 18 19 20 | ** The pager is used to access a database disk file. It implements ** atomic commit and rollback through the use of a journal file that ** is separate from the database file. The pager also implements file ** locking to prevent two processes from writing the same database ** file simultaneously, or one process from reading the database while ** another is writing. ** | | | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | ** The pager is used to access a database disk file. It implements ** atomic commit and rollback through the use of a journal file that ** is separate from the database file. The pager also implements file ** locking to prevent two processes from writing the same database ** file simultaneously, or one process from reading the database while ** another is writing. ** ** @(#) $Id: pager.c,v 1.479 2008/08/25 17:23:29 drh Exp $ */ #ifndef SQLITE_OMIT_DISKIO #include "sqliteInt.h" /* ** Macros for troubleshooting. Normally turned off */ |
︙ | ︙ | |||
2491 2492 2493 2494 2495 2496 2497 | ** journal file exists and is not empty this routine assumes it ** is hot. The pager_playback() routine will discover that the ** journal file is not really hot and will no-op. */ static int hasHotJournal(Pager *pPager, int *pExists){ sqlite3_vfs *pVfs = pPager->pVfs; int rc = SQLITE_OK; | < < | | | > > > | | | | < | | | | | | | | | | | < < | 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 | ** journal file exists and is not empty this routine assumes it ** is hot. The pager_playback() routine will discover that the ** journal file is not really hot and will no-op. */ static int hasHotJournal(Pager *pPager, int *pExists){ sqlite3_vfs *pVfs = pPager->pVfs; int rc = SQLITE_OK; int exists; int locked; assert( pPager!=0 ); assert( pPager->useJournal ); assert( pPager->fd->pMethods ); *pExists = 0; rc = sqlite3OsAccess(pVfs, pPager->zJournal, SQLITE_ACCESS_EXISTS, &exists); if( rc==SQLITE_OK && exists ){ rc = sqlite3OsCheckReservedLock(pPager->fd, &locked); } if( rc==SQLITE_OK && exists && !locked ){ int nPage; rc = sqlite3PagerPagecount(pPager, &nPage); if( rc==SQLITE_OK ){ if( nPage==0 ){ sqlite3OsDelete(pVfs, pPager->zJournal, 0); }else{ *pExists = 1; } } } return rc; } /* ** Read the content of page pPg out of the database file. */ static int readDbPage(Pager *pPager, PgHdr *pPg, Pgno pgno){ |
︙ | ︙ |
Changes to src/resolve.c.
︙ | ︙ | |||
10 11 12 13 14 15 16 | ** ************************************************************************* ** ** This file contains routines used for walking the parser tree and ** resolve all identifiers by associating them with a particular ** table and column. ** | | | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | ** ************************************************************************* ** ** This file contains routines used for walking the parser tree and ** resolve all identifiers by associating them with a particular ** table and column. ** ** $Id: resolve.c,v 1.4 2008/08/25 17:23:29 drh Exp $ */ #include "sqliteInt.h" #include <stdlib.h> #include <string.h> /* ** Given the name of a column of the form X.Y.Z or Y.Z or just Z, look up |
︙ | ︙ | |||
643 644 645 646 647 648 649 | pSelect->pPrior->pNext = pSelect; pSelect = pSelect->pPrior; } while( pSelect && moreToDo ){ struct ExprList_item *pItem; moreToDo = 0; pEList = pSelect->pEList; | | < < | 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 | pSelect->pPrior->pNext = pSelect; pSelect = pSelect->pPrior; } while( pSelect && moreToDo ){ struct ExprList_item *pItem; moreToDo = 0; pEList = pSelect->pEList; assert( pEList!=0 ); for(i=0, pItem=pOrderBy->a; i<pOrderBy->nExpr; i++, pItem++){ int iCol = -1; Expr *pE, *pDup; if( pItem->done ) continue; pE = pItem->pExpr; if( sqlite3ExprIsInteger(pE, &iCol) ){ if( iCol<0 || iCol>pEList->nExpr ){ |
︙ | ︙ | |||
726 727 728 729 730 731 732 | #if SQLITE_MAX_COLUMN if( pOrderBy->nExpr>db->aLimit[SQLITE_LIMIT_COLUMN] ){ sqlite3ErrorMsg(pParse, "too many terms in %s BY clause", zType); return 1; } #endif pEList = pSelect->pEList; | | < < | | 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 | #if SQLITE_MAX_COLUMN if( pOrderBy->nExpr>db->aLimit[SQLITE_LIMIT_COLUMN] ){ sqlite3ErrorMsg(pParse, "too many terms in %s BY clause", zType); return 1; } #endif pEList = pSelect->pEList; assert( pEList!=0 ); /* sqlite3SelectNew() guarantees this */ for(i=0, pItem=pOrderBy->a; i<pOrderBy->nExpr; i++, pItem++){ if( pItem->iCol ){ Expr *pE; CollSeq *pColl; int flags; if( pItem->iCol>pEList->nExpr ){ resolveOutOfRangeError(pParse, zType, i+1, pEList->nExpr); return 1; } pE = pItem->pExpr; pColl = pE->pColl; flags = pE->flags & EP_ExpCollate; sqlite3ExprDelete(db, pE); pE = sqlite3ExprDup(db, pEList->a[pItem->iCol-1].pExpr); pItem->pExpr = pE; if( pE && flags ){ pE->pColl = pColl; pE->flags |= flags; } } } return 0; } |
︙ | ︙ | |||
805 806 807 808 809 810 811 | pItem->iCol = iCol; continue; } if( sqlite3ExprIsInteger(pE, &iCol) ){ /* The ORDER BY term is an integer constant. Again, set the column ** number so that sqlite3ResolveOrderGroupBy() will convert the ** order-by term to a copy of the result-set expression */ | | | 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 | pItem->iCol = iCol; continue; } if( sqlite3ExprIsInteger(pE, &iCol) ){ /* The ORDER BY term is an integer constant. Again, set the column ** number so that sqlite3ResolveOrderGroupBy() will convert the ** order-by term to a copy of the result-set expression */ if( iCol<1 ){ resolveOutOfRangeError(pParse, zType, i+1, nResult); return 1; } pItem->iCol = iCol; continue; } |
︙ | ︙ | |||
838 839 840 841 842 843 844 | ExprList *pEList; /* Result set expression list */ int i; /* Loop counter */ ExprList *pGroupBy; /* The GROUP BY clause */ Select *pLeftmost; /* Left-most of SELECT of a compound */ sqlite3 *db; /* Database connection */ | | | 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 | ExprList *pEList; /* Result set expression list */ int i; /* Loop counter */ ExprList *pGroupBy; /* The GROUP BY clause */ Select *pLeftmost; /* Left-most of SELECT of a compound */ sqlite3 *db; /* Database connection */ assert( p!=0 ); if( p->selFlags & SF_Resolved ){ return WRC_Prune; } pOuterNC = pWalker->u.pNC; pParse = pWalker->pParse; db = pParse->db; |
︙ | ︙ | |||
886 887 888 889 890 891 892 | */ sNC.allowAgg = 1; sNC.pSrcList = p->pSrc; sNC.pNext = pOuterNC; /* Resolve names in the result set. */ pEList = p->pEList; | | | 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 | */ sNC.allowAgg = 1; sNC.pSrcList = p->pSrc; sNC.pNext = pOuterNC; /* Resolve names in the result set. */ pEList = p->pEList; assert( pEList!=0 ); for(i=0; i<pEList->nExpr; i++){ Expr *pX = pEList->a[i].pExpr; if( sqlite3ResolveExprNames(&sNC, pX) ){ return WRC_Abort; } } |
︙ | ︙ | |||
1098 1099 1100 1101 1102 1103 1104 | void sqlite3ResolveSelectNames( Parse *pParse, /* The parser context */ Select *p, /* The SELECT statement being coded. */ NameContext *pOuterNC /* Name context for parent SELECT statement */ ){ Walker w; | | | | | | | | < | 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 | void sqlite3ResolveSelectNames( Parse *pParse, /* The parser context */ Select *p, /* The SELECT statement being coded. */ NameContext *pOuterNC /* Name context for parent SELECT statement */ ){ Walker w; assert( p!=0 ); w.xExprCallback = resolveExprStep; w.xSelectCallback = resolveSelectStep; w.pParse = pParse; w.u.pNC = pOuterNC; sqlite3WalkSelect(&w, p); } |
Changes to src/select.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 file contains C code routines that are called by the parser ** to handle SELECT statements in SQLite. ** | | | 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 file contains C code routines that are called by the parser ** to handle SELECT statements in SQLite. ** ** $Id: select.c,v 1.470 2008/08/25 17:23:29 drh Exp $ */ #include "sqliteInt.h" /* ** Delete all the content of a Select structure but do not deallocate ** the select structure itself. |
︙ | ︙ | |||
83 84 85 86 87 88 89 | pNew->op = TK_SELECT; assert( pOffset==0 || pLimit!=0 ); pNew->pLimit = pLimit; pNew->pOffset = pOffset; pNew->addrOpenEphm[0] = -1; pNew->addrOpenEphm[1] = -1; pNew->addrOpenEphm[2] = -1; | | > | 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 | pNew->op = TK_SELECT; assert( pOffset==0 || pLimit!=0 ); pNew->pLimit = pLimit; pNew->pOffset = pOffset; pNew->addrOpenEphm[0] = -1; pNew->addrOpenEphm[1] = -1; pNew->addrOpenEphm[2] = -1; if( db->mallocFailed ) { clearSelect(db, pNew); if( pNew!=&standin ) sqlite3DbFree(db, pNew); pNew = 0; } return pNew; } /* ** Delete the given Select structure and all of its substructures. |
︙ | ︙ |
Changes to test/permutations.test.
1 2 3 4 5 6 7 8 9 10 11 | # 2008 June 21 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # | | > > | | > > | | | | | | | > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | # 2008 June 21 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # # $Id: permutations.test,v 1.22 2008/08/25 17:23:29 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl # Argument processing. # #puts "PERM-DEBUG: argv=$argv" namespace eval ::perm { set testmode [lindex $::argv 0] set testfile [lindex $::argv 1] } set argv [lrange $argv 2 end] #puts "PERM-DEBUG: testmode=$::perm::testmode" set ::permutations_presql "" set ::permutations_test_prefix "" if {$::perm::testmode eq "veryquick"} { set ::perm::testmode [list persistent_journal no_journal] set ISQUICK 1 } if {$::perm::testmode eq "quick"} { set ::perm::testmode [list persistent_journal no_journal autovacuum_ioerr] set ISQUICK 1 } if {$::perm::testmode eq "all"} { set ::perm::testmode { memsubsys1 memsubsys2 singlethread multithread onefile utf16 exclusive persistent_journal persistent_journal_error no_journal no_journal_error autovacuum_ioerr no_mutex_try } } if {$::perm::testmode eq "targets"} { puts "" puts -nonewline "veryquick " puts "Same as persistent_journal and no_journal" puts -nonewline "quick " puts "Same as persistent_journal, no_journal and autovacuum_ioerr" puts -nonewline "all " puts "Everything except autovacuum_crash" } puts "PERM-DEBUG: testmode=$::perm::testmode" set EXCLUDE { all.test in2.test onefile.test async2.test incrvacuum_ioerr.test permutations.test async.test jrnlmode2.test quick.test autovacuum_crash.test jrnlmode3.test shared_err.test autovacuum_ioerr.test jrnlmode4.test soak.test |
︙ | ︙ | |||
109 110 111 112 113 114 115 116 | set options(-shutdown) "" set options(-initialize) "" set options(-exclude) "" set options(-include) $::ALLTESTS set options(-presql) "" set options(-description) "no description supplied (fixme)" array set options $args | > > | | > > > | > > | | > > | 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 | set options(-shutdown) "" set options(-initialize) "" set options(-exclude) "" set options(-include) $::ALLTESTS set options(-presql) "" set options(-description) "no description supplied (fixme)" array set options $args #puts "PERM-DEBUG: name=$name testfile=$::perm::testfile" #puts "PERM-DEBUG: [array get options]" if {$::perm::testmode eq "targets"} { puts [format "% -20s %s" $name [string trim $options(-description)]] return } if {$::perm::testmode ne "" && [lsearch $::perm::testmode $name]<0} { puts "skipping permutation test $name..." return } uplevel $options(-initialize) set ::permutations_presql $options(-presql) foreach file $options(-include) { if {[lsearch $options(-exclude) $file] < 0 && ( $::perm::testfile eq "" || $::perm::testfile eq $file || "$::perm::testfile.test" eq $file ) } { uplevel source $::testdir/$file } else { # puts "skipping file $file" } } uplevel $options(-shutdown) } ############################################################################# |
︙ | ︙ | |||
467 468 469 470 471 472 473 | sqlite3_initialize } } ifcapable threadsafe { run_tests "no_mutex_try" -description { The sqlite3_mutex_try() interface always fails | > | | 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 | sqlite3_initialize } } ifcapable threadsafe { run_tests "no_mutex_try" -description { The sqlite3_mutex_try() interface always fails } -exclude [concat $EXCLUDE mutex1.test mutex2.test] \ -initialize { catch {db close} sqlite3_shutdown install_mutex_counters 1 set ::disable_mutex_try 1 } -shutdown { catch {db close} sqlite3_shutdown |
︙ | ︙ | |||
526 527 528 529 530 531 532 | # rename sa_crashsql crashsql # } -include crash.test # End of tests ############################################################################# | | | 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 | # rename sa_crashsql crashsql # } -include crash.test # End of tests ############################################################################# if {$::perm::testmode eq "targets"} { puts "" ; exit } # Restore the [sqlite3] command. # rename sqlite3 {} rename really_sqlite3 sqlite3 # Restore the [finish_test] command. |
︙ | ︙ |