Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Merge changes from trunk, especially the SQLITE_DEFAULT_SYNCHRONOUS enhancements. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | apple-osx |
Files: | files | file ages | folders |
SHA1: |
29741941238643dc0e41660d98b176d8 |
User & Date: | drh 2016-03-08 16:35:17.731 |
Context
2016-03-15
| ||
12:45 | Merge updates from trunk - FTS5 fixes and enhancemenets to the tests scripts so that they work with SEE. (check-in: f41a7361a1 user: drh tags: apple-osx) | |
2016-03-08
| ||
16:35 | Merge changes from trunk, especially the SQLITE_DEFAULT_SYNCHRONOUS enhancements. (check-in: 2974194123 user: drh tags: apple-osx) | |
16:07 | Drop support for SQLITE_EXTRA_DURABLE. The new SQLITE_DEFAULT_SYNCHRONOUS compile-time option is a more general replacement. (check-in: f6d3156ba9 user: drh tags: trunk) | |
14:01 | Merge coverage improvements and comment fixes from trunk. (check-in: 58023bfccc user: drh tags: apple-osx) | |
Changes
Changes to ext/fts3/fts3_write.c.
︙ | ︙ | |||
4836 4837 4838 4839 4840 4841 4842 | ** nSeg to nMin. If no level with at least nMin segments can be found, ** set nSeg to -1. */ rc = fts3SqlStmt(p, SQL_FIND_MERGE_LEVEL, &pFindLevel, 0); sqlite3_bind_int(pFindLevel, 1, MAX(2, nMin)); if( sqlite3_step(pFindLevel)==SQLITE_ROW ){ iAbsLevel = sqlite3_column_int64(pFindLevel, 0); | < | < | < | 4836 4837 4838 4839 4840 4841 4842 4843 4844 4845 4846 4847 4848 4849 4850 4851 | ** nSeg to nMin. If no level with at least nMin segments can be found, ** set nSeg to -1. */ rc = fts3SqlStmt(p, SQL_FIND_MERGE_LEVEL, &pFindLevel, 0); sqlite3_bind_int(pFindLevel, 1, MAX(2, nMin)); if( sqlite3_step(pFindLevel)==SQLITE_ROW ){ iAbsLevel = sqlite3_column_int64(pFindLevel, 0); nSeg = sqlite3_column_int(pFindLevel, 1); assert( nSeg>=2 ); }else{ nSeg = -1; } rc = sqlite3_reset(pFindLevel); /* If the hint read from the %_stat table is not empty, check if the ** last entry in it specifies a relative level smaller than or equal |
︙ | ︙ | |||
4992 4993 4994 4995 4996 4997 4998 | /* If the first integer value is followed by a ',', read the second ** integer value. */ if( z[0]==',' && z[1]!='\0' ){ z++; nMin = fts3Getint(&z); } | | | 4989 4990 4991 4992 4993 4994 4995 4996 4997 4998 4999 5000 5001 5002 5003 | /* If the first integer value is followed by a ',', read the second ** integer value. */ if( z[0]==',' && z[1]!='\0' ){ z++; nMin = fts3Getint(&z); } if( z[0]!='\0' || nMin<2 ){ rc = SQLITE_ERROR; }else{ rc = SQLITE_OK; if( !p->bHasStat ){ assert( p->bFts4==0 ); sqlite3Fts3CreateStatTable(&rc, p); } |
︙ | ︙ |
Added ext/rbu/rbuC.test.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 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 | # 2016 March 7 # # 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. # #*********************************************************************** # Tests for RBU focused on the REPLACE operation (rbu_control column # contains integer value 2). # source [file join [file dirname [info script]] rbu_common.tcl] set ::testprefix rbuC #------------------------------------------------------------------------- # This test is actually of an UPDATE directive. Just to establish that # these work with UNIQUE indexes before preceding to REPLACE. # do_execsql_test 1.0 { CREATE TABLE t1(i INTEGER PRIMARY KEY, a, b, c UNIQUE); INSERT INTO t1 VALUES(1, 'a', 'b', 'c'); } forcedelete rbu.db do_execsql_test 1.1 { ATTACH 'rbu.db' AS rbu; CREATE TABLE rbu.data_t1(i, a, b, c, rbu_control); INSERT INTO data_t1 VALUES(1, 'a', 'b', 'c', '.xxx'); } do_test 1.2 { step_rbu test.db rbu.db } {SQLITE_DONE} do_execsql_test 1.3 { SELECT * FROM t1 } { 1 a b c } #------------------------------------------------------------------------- # foreach {tn schema} { 1 { CREATE TABLE t1(i INTEGER PRIMARY KEY, a, b, c UNIQUE); CREATE INDEX t1a ON t1(a); } 2 { CREATE TABLE t1(i PRIMARY KEY, a, b, c UNIQUE); CREATE INDEX t1a ON t1(a); } 3 { CREATE TABLE t1(i PRIMARY KEY, a, b, c UNIQUE) WITHOUT ROWID; CREATE INDEX t1a ON t1(a); } } { reset_db forcedelete rbu.db execsql $schema do_execsql_test 2.$tn.0 { INSERT INTO t1 VALUES(1, 'a', 'b', 'c'); INSERT INTO t1 VALUES(2, 'b', 'c', 'd'); INSERT INTO t1 VALUES(3, 'c', 'd', 'e'); } do_execsql_test 2.$tn.1 { ATTACH 'rbu.db' AS rbu; CREATE TABLE rbu.data_t1(i, a, b, c, rbu_control); INSERT INTO data_t1 VALUES(1, 1, 2, 3, 2); INSERT INTO data_t1 VALUES(3, 'c', 'd', 'e', 2); INSERT INTO data_t1 VALUES(4, 'd', 'e', 'f', 2); } do_test 2.$tn.2 { step_rbu test.db rbu.db } {SQLITE_DONE} do_execsql_test 2.$tn.3 { SELECT * FROM t1 ORDER BY i } { 1 1 2 3 2 b c d 3 c d e 4 d e f } integrity_check 2.$tn.4 } foreach {tn schema} { 1 { CREATE TABLE t1(a, b, c UNIQUE); CREATE INDEX t1a ON t1(a); } 2 { CREATE VIRTUAL TABLE t1 USING fts5(a, b, c); } } { if {$tn==2} { ifcapable !fts5 break } reset_db forcedelete rbu.db execsql $schema do_execsql_test 3.$tn.0 { INSERT INTO t1 VALUES('a', 'b', 'c'); INSERT INTO t1 VALUES('b', 'c', 'd'); INSERT INTO t1 VALUES('c', 'd', 'e'); } do_execsql_test 3.$tn.1 { ATTACH 'rbu.db' AS rbu; CREATE TABLE rbu.data_t1(rbu_rowid, a, b, c, rbu_control); INSERT INTO data_t1 VALUES(1, 1, 2, 3, 2); INSERT INTO data_t1 VALUES(3, 'c', 'd', 'e', 2); INSERT INTO data_t1 VALUES(4, 'd', 'e', 'f', 2); } do_test 3.$tn.2 { step_rbu test.db rbu.db } {SQLITE_DONE} do_execsql_test 3.$tn.3 { SELECT rowid, * FROM t1 ORDER BY 1 } { 1 1 2 3 2 b c d 3 c d e 4 d e f } integrity_check 3.$tn.4 } finish_test |
Changes to ext/rbu/sqlite3rbu.c.
︙ | ︙ | |||
276 277 278 279 280 281 282 | /* ** Within the RBU_STAGE_OAL stage, each call to sqlite3rbu_step() performs ** one of the following operations. */ #define RBU_INSERT 1 /* Insert on a main table b-tree */ #define RBU_DELETE 2 /* Delete a row from a main table b-tree */ | > | | < > | 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 | /* ** Within the RBU_STAGE_OAL stage, each call to sqlite3rbu_step() performs ** one of the following operations. */ #define RBU_INSERT 1 /* Insert on a main table b-tree */ #define RBU_DELETE 2 /* Delete a row from a main table b-tree */ #define RBU_REPLACE 3 /* Delete and then insert a row */ #define RBU_IDX_DELETE 4 /* Delete a row from an aux. index b-tree */ #define RBU_IDX_INSERT 5 /* Insert on an aux. index b-tree */ #define RBU_UPDATE 6 /* Update a row in a main table b-tree */ /* ** A single step of an incremental checkpoint - frame iWalFrame of the wal ** file should be copied to page iDbPage of the database file. */ struct RbuFrame { u32 iDbPage; |
︙ | ︙ | |||
1905 1906 1907 1908 1909 1910 1911 | zSql = sqlite3_mprintf( "SELECT %s, rbu_control FROM %s.'rbu_tmp_%q' ORDER BY %s%s", zCollist, p->zStateDb, pIter->zDataTbl, zCollist, zLimit ); }else{ zSql = sqlite3_mprintf( | | < | > < > | 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 | zSql = sqlite3_mprintf( "SELECT %s, rbu_control FROM %s.'rbu_tmp_%q' ORDER BY %s%s", zCollist, p->zStateDb, pIter->zDataTbl, zCollist, zLimit ); }else{ zSql = sqlite3_mprintf( "SELECT %s, rbu_control FROM %s.'rbu_tmp_%q' " "UNION ALL " "SELECT %s, rbu_control FROM '%q' " "WHERE typeof(rbu_control)='integer' AND rbu_control!=1 " "ORDER BY %s%s", zCollist, p->zStateDb, pIter->zDataTbl, zCollist, pIter->zDataTbl, zCollist, zLimit ); } p->rc = prepareFreeAndCollectError(p->dbRbu, &pIter->pSelect, pz, zSql); } sqlite3_free(zImposterCols); |
︙ | ︙ | |||
1977 1978 1979 1980 1981 1982 1983 | , (pIter->eType==RBU_PK_EXTERNAL ? ", 0 AS rbu_rowid" : "") , pIter->zDataTbl ); rbuMPrintfExec(p, p->dbMain, "CREATE TEMP TRIGGER rbu_delete_tr BEFORE DELETE ON \"%s%w\" " "BEGIN " | | | | | 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 | , (pIter->eType==RBU_PK_EXTERNAL ? ", 0 AS rbu_rowid" : "") , pIter->zDataTbl ); rbuMPrintfExec(p, p->dbMain, "CREATE TEMP TRIGGER rbu_delete_tr BEFORE DELETE ON \"%s%w\" " "BEGIN " " SELECT rbu_tmp_insert(3, %s);" "END;" "CREATE TEMP TRIGGER rbu_update1_tr BEFORE UPDATE ON \"%s%w\" " "BEGIN " " SELECT rbu_tmp_insert(3, %s);" "END;" "CREATE TEMP TRIGGER rbu_update2_tr AFTER UPDATE ON \"%s%w\" " "BEGIN " " SELECT rbu_tmp_insert(4, %s);" "END;", zWrite, zTbl, zOldlist, zWrite, zTbl, zOldlist, zWrite, zTbl, zNewlist ); if( pIter->eType==RBU_PK_EXTERNAL || pIter->eType==RBU_PK_NONE ){ |
︙ | ︙ | |||
2505 2506 2507 2508 2509 2510 2511 | static int rbuStepType(sqlite3rbu *p, const char **pzMask){ int iCol = p->objiter.nCol; /* Index of rbu_control column */ int res = 0; /* Return value */ switch( sqlite3_column_type(p->objiter.pSelect, iCol) ){ case SQLITE_INTEGER: { int iVal = sqlite3_column_int(p->objiter.pSelect, iCol); | | | < | | | < | | 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 | static int rbuStepType(sqlite3rbu *p, const char **pzMask){ int iCol = p->objiter.nCol; /* Index of rbu_control column */ int res = 0; /* Return value */ switch( sqlite3_column_type(p->objiter.pSelect, iCol) ){ case SQLITE_INTEGER: { int iVal = sqlite3_column_int(p->objiter.pSelect, iCol); switch( iVal ){ case 0: res = RBU_INSERT; break; case 1: res = RBU_DELETE; break; case 2: res = RBU_REPLACE; break; case 3: res = RBU_IDX_DELETE; break; case 4: res = RBU_IDX_INSERT; break; } break; } case SQLITE_TEXT: { const unsigned char *z = sqlite3_column_text(p->objiter.pSelect, iCol); if( z==0 ){ |
︙ | ︙ | |||
2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 | static void assertColumnName(sqlite3_stmt *pStmt, int iCol, const char *zName){ const char *zCol = sqlite3_column_name(pStmt, iCol); assert( 0==sqlite3_stricmp(zName, zCol) ); } #else # define assertColumnName(x,y,z) #endif /* ** This function does the work for an sqlite3rbu_step() call. ** ** The object-iterator (p->objiter) currently points to a valid object, ** and the input cursor (p->objiter.pSelect) currently points to a valid ** input row. Perform whatever processing is required and return. ** ** If no error occurs, SQLITE_OK is returned. Otherwise, an error code ** and message is left in the RBU handle and a copy of the error code ** returned. */ static int rbuStep(sqlite3rbu *p){ RbuObjIter *pIter = &p->objiter; const char *zMask = 0; | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > < < < < < < < < | | | | < < < | < | < < < < | < < < < < < < < < < < | < | < < < < < < < | < < < < < < < < < < < < > | | | < | | > | 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 | static void assertColumnName(sqlite3_stmt *pStmt, int iCol, const char *zName){ const char *zCol = sqlite3_column_name(pStmt, iCol); assert( 0==sqlite3_stricmp(zName, zCol) ); } #else # define assertColumnName(x,y,z) #endif /* ** Argument eType must be one of RBU_INSERT, RBU_DELETE, RBU_IDX_INSERT or ** RBU_IDX_DELETE. This function performs the work of a single ** sqlite3rbu_step() call for the type of operation specified by eType. */ static void rbuStepOneOp(sqlite3rbu *p, int eType){ RbuObjIter *pIter = &p->objiter; sqlite3_value *pVal; sqlite3_stmt *pWriter; int i; assert( p->rc==SQLITE_OK ); assert( eType!=RBU_DELETE || pIter->zIdx==0 ); if( eType==RBU_IDX_DELETE || eType==RBU_DELETE ){ pWriter = pIter->pDelete; }else{ pWriter = pIter->pInsert; } for(i=0; i<pIter->nCol; i++){ /* If this is an INSERT into a table b-tree and the table has an ** explicit INTEGER PRIMARY KEY, check that this is not an attempt ** to write a NULL into the IPK column. That is not permitted. */ if( eType==RBU_INSERT && pIter->zIdx==0 && pIter->eType==RBU_PK_IPK && pIter->abTblPk[i] && sqlite3_column_type(pIter->pSelect, i)==SQLITE_NULL ){ p->rc = SQLITE_MISMATCH; p->zErrmsg = sqlite3_mprintf("datatype mismatch"); return; } if( eType==RBU_DELETE && pIter->abTblPk[i]==0 ){ continue; } pVal = sqlite3_column_value(pIter->pSelect, i); p->rc = sqlite3_bind_value(pWriter, i+1, pVal); if( p->rc ) return; } if( pIter->zIdx==0 && (pIter->eType==RBU_PK_VTAB || pIter->eType==RBU_PK_NONE) ){ /* For a virtual table, or a table with no primary key, the ** SELECT statement is: ** ** SELECT <cols>, rbu_control, rbu_rowid FROM .... ** ** Hence column_value(pIter->nCol+1). */ assertColumnName(pIter->pSelect, pIter->nCol+1, "rbu_rowid"); pVal = sqlite3_column_value(pIter->pSelect, pIter->nCol+1); p->rc = sqlite3_bind_value(pWriter, pIter->nCol+1, pVal); } if( p->rc==SQLITE_OK ){ sqlite3_step(pWriter); p->rc = resetAndCollectError(pWriter, &p->zErrmsg); } } /* ** This function does the work for an sqlite3rbu_step() call. ** ** The object-iterator (p->objiter) currently points to a valid object, ** and the input cursor (p->objiter.pSelect) currently points to a valid ** input row. Perform whatever processing is required and return. ** ** If no error occurs, SQLITE_OK is returned. Otherwise, an error code ** and message is left in the RBU handle and a copy of the error code ** returned. */ static int rbuStep(sqlite3rbu *p){ RbuObjIter *pIter = &p->objiter; const char *zMask = 0; int eType = rbuStepType(p, &zMask); if( eType ){ assert( eType==RBU_INSERT || eType==RBU_DELETE || eType==RBU_REPLACE || eType==RBU_IDX_DELETE || eType==RBU_IDX_INSERT || eType==RBU_UPDATE ); assert( eType!=RBU_UPDATE || pIter->zIdx==0 ); if( pIter->zIdx==0 && eType==RBU_IDX_DELETE ){ rbuBadControlError(p); } else if( eType==RBU_REPLACE ){ if( pIter->zIdx==0 ) rbuStepOneOp(p, RBU_DELETE); if( p->rc==SQLITE_OK ) rbuStepOneOp(p, RBU_INSERT); } else if( eType!=RBU_UPDATE ){ rbuStepOneOp(p, eType); } else{ sqlite3_value *pVal; sqlite3_stmt *pUpdate = 0; assert( eType==RBU_UPDATE ); rbuGetUpdateStmt(p, pIter, zMask, &pUpdate); if( pUpdate ){ int i; for(i=0; p->rc==SQLITE_OK && i<pIter->nCol; i++){ char c = zMask[pIter->aiSrcOrder[i]]; pVal = sqlite3_column_value(pIter->pSelect, i); if( pIter->abTblPk[i] || c!='.' ){ p->rc = sqlite3_bind_value(pUpdate, i+1, pVal); } } |
︙ | ︙ | |||
2659 2660 2661 2662 2663 2664 2665 | if( p->rc==SQLITE_OK ){ sqlite3_step(pUpdate); p->rc = resetAndCollectError(pUpdate, &p->zErrmsg); } } } } | < < | 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 | if( p->rc==SQLITE_OK ){ sqlite3_step(pUpdate); p->rc = resetAndCollectError(pUpdate, &p->zErrmsg); } } } } return p->rc; } /* ** Increment the schema cookie of the main database opened by p->dbMain. */ static void rbuIncrSchemaCookie(sqlite3rbu *p){ |
︙ | ︙ |
Changes to src/attach.c.
︙ | ︙ | |||
157 158 159 160 161 162 163 | sqlite3BtreeSecureDelete(db->aDb[0].pBt,-1) ); #ifndef SQLITE_OMIT_PAGER_PRAGMAS sqlite3BtreeSetPagerFlags(aNew->pBt, PAGER_SYNCHRONOUS_FULL | (db->flags & PAGER_FLAGS_MASK)); #endif sqlite3BtreeLeave(aNew->pBt); } | | | 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 | sqlite3BtreeSecureDelete(db->aDb[0].pBt,-1) ); #ifndef SQLITE_OMIT_PAGER_PRAGMAS sqlite3BtreeSetPagerFlags(aNew->pBt, PAGER_SYNCHRONOUS_FULL | (db->flags & PAGER_FLAGS_MASK)); #endif sqlite3BtreeLeave(aNew->pBt); } aNew->safety_level = SQLITE_DEFAULT_SYNCHRONOUS+1; aNew->zName = sqlite3DbStrDup(db, zName); if( rc==SQLITE_OK && aNew->zName==0 ){ rc = SQLITE_NOMEM_BKPT; } #ifdef SQLITE_HAS_CODEC |
︙ | ︙ |
Changes to src/btree.c.
︙ | ︙ | |||
2866 2867 2868 2869 2870 2871 2872 | ** file. */ if( page1[19]==2 && (pBt->btsFlags & BTS_NO_WAL)==0 ){ int isOpen = 0; rc = sqlite3PagerOpenWal(pBt->pPager, &isOpen); if( rc!=SQLITE_OK ){ goto page1_init_failed; | | | < < < | | < < > | < | | < < > | | | < > | | > | 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 | ** file. */ if( page1[19]==2 && (pBt->btsFlags & BTS_NO_WAL)==0 ){ int isOpen = 0; rc = sqlite3PagerOpenWal(pBt->pPager, &isOpen); if( rc!=SQLITE_OK ){ goto page1_init_failed; }else{ #if SQLITE_DEFAULT_SYNCHRONOUS!=SQLITE_DEFAULT_WAL_SYNCHRONOUS sqlite3 *db; Db *pDb; if( (db=pBt->db)!=0 && (pDb=db->aDb)!=0 ){ while( pDb->pBt==0 || pDb->pBt->pBt!=pBt ){ pDb++; } if( pDb->bSyncSet==0 && pDb->safety_level==SQLITE_DEFAULT_SYNCHRONOUS+1 ){ pDb->safety_level = SQLITE_DEFAULT_WAL_SYNCHRONOUS+1; sqlite3PagerSetFlags(pBt->pPager, pDb->safety_level | (db->flags & PAGER_FLAGS_MASK)); } } #endif if( isOpen==0 ){ releasePage(pPage1); return SQLITE_OK; } } rc = SQLITE_NOTADB; } #endif /* EVIDENCE-OF: R-15465-20813 The maximum and minimum embedded payload ** fractions and the leaf payload fraction values must be 64, 32, and 32. |
︙ | ︙ |
Changes to src/main.c.
︙ | ︙ | |||
2970 2971 2972 2973 2974 2975 2976 | sqlite3BtreeLeave(db->aDb[0].pBt); db->aDb[1].pSchema = sqlite3SchemaGet(db, 0); /* The default safety_level for the main database is FULL; for the temp ** database it is OFF. This matches the pager layer defaults. */ db->aDb[0].zName = "main"; | | | 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 | sqlite3BtreeLeave(db->aDb[0].pBt); db->aDb[1].pSchema = sqlite3SchemaGet(db, 0); /* The default safety_level for the main database is FULL; for the temp ** database it is OFF. This matches the pager layer defaults. */ db->aDb[0].zName = "main"; db->aDb[0].safety_level = SQLITE_DEFAULT_SYNCHRONOUS+1; db->aDb[1].zName = "temp"; db->aDb[1].safety_level = PAGER_SYNCHRONOUS_OFF; db->magic = SQLITE_MAGIC_OPEN; if( db->mallocFailed ){ goto opendb_out; } |
︙ | ︙ |
Changes to src/pager.c.
︙ | ︙ | |||
424 425 426 427 428 429 430 | ** The maximum allowed sector size. 64KiB. If the xSectorsize() method ** returns a value larger than this, then MAX_SECTOR_SIZE is used instead. ** This could conceivably cause corruption following a power failure on ** such a system. This is currently an undocumented limit. */ #define MAX_SECTOR_SIZE 0x10000 | < < < < < < < < < < < < < | 424 425 426 427 428 429 430 431 432 433 434 435 436 437 | ** The maximum allowed sector size. 64KiB. If the xSectorsize() method ** returns a value larger than this, then MAX_SECTOR_SIZE is used instead. ** This could conceivably cause corruption following a power failure on ** such a system. This is currently an undocumented limit. */ #define MAX_SECTOR_SIZE 0x10000 /* ** An instance of the following structure is allocated for each active ** savepoint and statement transaction in the system. All such structures ** are stored in the Pager.aSavepoint[] array, which is allocated and ** resized using sqlite3Realloc(). ** |
︙ | ︙ | |||
4834 4835 4836 4837 4838 4839 4840 | assert( pPager->fullSync==0 ); assert( pPager->extraSync==0 ); assert( pPager->syncFlags==0 ); assert( pPager->walSyncFlags==0 ); assert( pPager->ckptSyncFlags==0 ); }else{ pPager->fullSync = 1; | < < < < | 4821 4822 4823 4824 4825 4826 4827 4828 4829 4830 4831 4832 4833 4834 4835 | assert( pPager->fullSync==0 ); assert( pPager->extraSync==0 ); assert( pPager->syncFlags==0 ); assert( pPager->walSyncFlags==0 ); assert( pPager->ckptSyncFlags==0 ); }else{ pPager->fullSync = 1; pPager->extraSync = 0; pPager->syncFlags = SQLITE_SYNC_NORMAL; pPager->walSyncFlags = SQLITE_SYNC_NORMAL | WAL_SYNC_TRANSACTIONS; pPager->ckptSyncFlags = SQLITE_SYNC_NORMAL; } /* pPager->pFirst = 0; */ /* pPager->pFirstSynced = 0; */ /* pPager->pLast = 0; */ |
︙ | ︙ |
Changes to src/pcache1.c.
︙ | ︙ | |||
344 345 346 347 348 349 350 | return p; } /* ** Free an allocated buffer obtained from pcache1Alloc(). */ static void pcache1Free(void *p){ | < > | | | | > | 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 | return p; } /* ** Free an allocated buffer obtained from pcache1Alloc(). */ static void pcache1Free(void *p){ if( p==0 ) return; if( SQLITE_WITHIN(p, pcache1.pStart, pcache1.pEnd) ){ PgFreeslot *pSlot; sqlite3_mutex_enter(pcache1.mutex); sqlite3StatusDown(SQLITE_STATUS_PAGECACHE_USED, 1); pSlot = (PgFreeslot*)p; pSlot->pNext = pcache1.pFree; pcache1.pFree = pSlot; pcache1.nFreeSlot++; pcache1.bUnderPressure = pcache1.nFreeSlot<pcache1.nReserve; assert( pcache1.nFreeSlot<=pcache1.nSlot ); sqlite3_mutex_leave(pcache1.mutex); }else{ assert( sqlite3MemdebugHasType(p, MEMTYPE_PCACHE) ); sqlite3MemdebugSetType(p, MEMTYPE_HEAP); #ifndef SQLITE_DISABLE_PAGECACHE_OVERFLOW_STATS { int nFreed = sqlite3MallocSize(p); sqlite3_mutex_enter(pcache1.mutex); sqlite3StatusDown(SQLITE_STATUS_PAGECACHE_OVERFLOW, nFreed); sqlite3_mutex_leave(pcache1.mutex); } #endif sqlite3_free(p); } } #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT /* |
︙ | ︙ |
Changes to src/pragma.c.
︙ | ︙ | |||
616 617 618 619 620 621 622 | } } if( eMode==PAGER_JOURNALMODE_QUERY && pId2->n==0 ){ /* Convert "PRAGMA journal_mode" into "PRAGMA main.journal_mode" */ iDb = 0; pId2->n = 1; } | < < < < < < < < < < < < < < | 616 617 618 619 620 621 622 623 624 625 626 627 628 629 | } } if( eMode==PAGER_JOURNALMODE_QUERY && pId2->n==0 ){ /* Convert "PRAGMA journal_mode" into "PRAGMA main.journal_mode" */ iDb = 0; pId2->n = 1; } for(ii=db->nDb-1; ii>=0; ii--){ if( db->aDb[ii].pBt && (ii==iDb || pId2->n==0) ){ sqlite3VdbeUsesBtree(v, ii); sqlite3VdbeAddOp3(v, OP_JournalMode, ii, 1, eMode); } } sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1); |
︙ | ︙ | |||
994 995 996 997 998 999 1000 | ** Return or set the local value of the synchronous flag. Changing ** the local value does not make changes to the disk file and the ** default value will be restored the next time the database is ** opened. */ case PragTyp_SYNCHRONOUS: { if( !zRight ){ | | < | < < > | 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 | ** Return or set the local value of the synchronous flag. Changing ** the local value does not make changes to the disk file and the ** default value will be restored the next time the database is ** opened. */ case PragTyp_SYNCHRONOUS: { if( !zRight ){ returnSingleInt(v, "synchronous", pDb->safety_level-1); }else{ if( !db->autoCommit ){ sqlite3ErrorMsg(pParse, "Safety level may not be changed inside a transaction"); }else{ int iLevel = (getSafetyLevel(zRight,0,1)+1) & PAGER_SYNCHRONOUS_MASK; if( iLevel==0 ) iLevel = 1; pDb->safety_level = iLevel; pDb->bSyncSet = 1; setAllPagerFlags(db); } } break; } #endif /* SQLITE_OMIT_PAGER_PRAGMAS */ |
︙ | ︙ |
Changes to src/sqliteInt.h.
︙ | ︙ | |||
998 999 1000 1001 1002 1003 1004 | ** "BusyHandler" typedefs. vdbe.h also requires a few of the opaque ** pointer types (i.e. FuncDef) defined above. */ #include "btree.h" #include "vdbe.h" #include "pager.h" #include "pcache.h" | < | > > > > > > | > | > > | > > > > > > > | > > | | > | | > > | 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 | ** "BusyHandler" typedefs. vdbe.h also requires a few of the opaque ** pointer types (i.e. FuncDef) defined above. */ #include "btree.h" #include "vdbe.h" #include "pager.h" #include "pcache.h" #include "os.h" #include "mutex.h" /* The SQLITE_EXTRA_DURABLE compile-time option used to set the default ** synchronous setting to EXTRA. It is no longer supported. */ #ifdef SQLITE_EXTRA_DURABLE # warning Use SQLITE_DEFAULT_SYNCHRONOUS=3 instead of SQLITE_EXTRA_DURABLE # define SQLITE_DEFAULT_SYNCHRONOUS 3 #endif /* ** Default synchronous levels. ** ** Note that (for historcal reasons) the PAGER_SYNCHRONOUS_* macros differ ** from the SQLITE_DEFAULT_SYNCHRONOUS value by 1. ** ** PAGER_SYNCHRONOUS DEFAULT_SYNCHRONOUS ** OFF 1 0 ** NORMAL 2 1 ** FULL 3 2 ** EXTRA 4 3 ** ** The "PRAGMA synchronous" statement also uses the zero-based numbers. ** In other words, the zero-based numbers are used for all external interfaces ** and the one-based values are used internally. */ #ifndef SQLITE_DEFAULT_SYNCHRONOUS # define SQLITE_DEFAULT_SYNCHRONOUS (PAGER_SYNCHRONOUS_FULL-1) #endif #ifndef SQLITE_DEFAULT_WAL_SYNCHRONOUS # define SQLITE_DEFAULT_WAL_SYNCHRONOUS SQLITE_DEFAULT_SYNCHRONOUS #endif /* ** Each database file to be accessed by the system is an instance ** of the following structure. There are normally two of these structures ** in the sqlite.aDb[] array. aDb[0] is the main database file and ** aDb[1] is the database file used to hold temporary tables. Additional ** databases may be attached. */ struct Db { char *zName; /* Name of this database */ Btree *pBt; /* The B*Tree structure for this database file */ u8 safety_level; /* How aggressive at syncing data to disk */ u8 bSyncSet; /* True if "PRAGMA synchronous=N" has been run */ Schema *pSchema; /* Pointer to database schema (possibly shared) */ }; /* ** An instance of the following structure stores a database schema. ** ** Most Schema objects are associated with a Btree. The exception is |
︙ | ︙ |
Changes to src/test1.c.
︙ | ︙ | |||
1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 | int objc, /* Number of arguments */ Tcl_Obj *CONST objv[] /* Command arguments */ ){ Tcl_CmdInfo cmdInfo; sqlite3 *db; int rc; char *zDb; char *zFile; char *zProc = 0; char *zErr = 0; if( objc!=4 && objc!=3 ){ Tcl_WrongNumArgs(interp, 1, objv, "DB-HANDLE FILE ?PROC?"); return TCL_ERROR; } zDb = Tcl_GetString(objv[1]); zFile = Tcl_GetString(objv[2]); if( objc==4 ){ zProc = Tcl_GetString(objv[3]); } /* Extract the C database handle from the Tcl command name */ if( !Tcl_GetCommandInfo(interp, zDb, &cmdInfo) ){ Tcl_AppendResult(interp, "command not found: ", zDb, (char*)0); return TCL_ERROR; } db = ((struct SqliteDb*)cmdInfo.objClientData)->db; | > > > > | 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 | int objc, /* Number of arguments */ Tcl_Obj *CONST objv[] /* Command arguments */ ){ Tcl_CmdInfo cmdInfo; sqlite3 *db; int rc; char *zDb; #ifndef SQLITE_OMIT_LOAD_EXTENSION char *zFile; char *zProc = 0; #endif char *zErr = 0; if( objc!=4 && objc!=3 ){ Tcl_WrongNumArgs(interp, 1, objv, "DB-HANDLE FILE ?PROC?"); return TCL_ERROR; } zDb = Tcl_GetString(objv[1]); #ifndef SQLITE_OMIT_LOAD_EXTENSION zFile = Tcl_GetString(objv[2]); if( objc==4 ){ zProc = Tcl_GetString(objv[3]); } #endif /* Extract the C database handle from the Tcl command name */ if( !Tcl_GetCommandInfo(interp, zDb, &cmdInfo) ){ Tcl_AppendResult(interp, "command not found: ", zDb, (char*)0); return TCL_ERROR; } db = ((struct SqliteDb*)cmdInfo.objClientData)->db; |
︙ | ︙ |
Changes to src/test_config.c.
︙ | ︙ | |||
561 562 563 564 565 566 567 | Tcl_SetVar2(interp,"sqlite_options","enable_purgeable_pcache","0",TCL_GLOBAL_ONLY); #endif #if SQLITE_DEFAULT_CKPTFULLFSYNC Tcl_SetVar2(interp,"sqlite_options","default_ckptfullfsync","1",TCL_GLOBAL_ONLY); #else Tcl_SetVar2(interp,"sqlite_options","default_ckptfullfsync","0",TCL_GLOBAL_ONLY); #endif | < < < < < < | 561 562 563 564 565 566 567 568 569 570 571 572 573 574 | Tcl_SetVar2(interp,"sqlite_options","enable_purgeable_pcache","0",TCL_GLOBAL_ONLY); #endif #if SQLITE_DEFAULT_CKPTFULLFSYNC Tcl_SetVar2(interp,"sqlite_options","default_ckptfullfsync","1",TCL_GLOBAL_ONLY); #else Tcl_SetVar2(interp,"sqlite_options","default_ckptfullfsync","0",TCL_GLOBAL_ONLY); #endif #if SQLITE_ENABLE_PERSIST_WAL Tcl_SetVar2(interp,"sqlite_options","enable_persist_wal","1",TCL_GLOBAL_ONLY); #else Tcl_SetVar2(interp,"sqlite_options","enable_persist_wal","0",TCL_GLOBAL_ONLY); #endif #ifdef SQLITE_OMIT_SHARED_CACHE |
︙ | ︙ |
Changes to src/wal.c.
︙ | ︙ | |||
2886 2887 2888 2889 2890 2891 2892 | PgHdr *pPage, /* The page of the frame to be written */ int nTruncate, /* The commit flag. Usually 0. >0 for commit */ sqlite3_int64 iOffset /* Byte offset at which to write */ ){ int rc; /* Result code from subfunctions */ void *pData; /* Data actually written */ #if defined(SQLITE_WRITE_WALFRAME_PREBUFFERED) | < < | | 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 | PgHdr *pPage, /* The page of the frame to be written */ int nTruncate, /* The commit flag. Usually 0. >0 for commit */ sqlite3_int64 iOffset /* Byte offset at which to write */ ){ int rc; /* Result code from subfunctions */ void *pData; /* Data actually written */ #if defined(SQLITE_WRITE_WALFRAME_PREBUFFERED) u8 *aFrame = p->aFrameBuf; #else u8 aFrame[WAL_FRAME_HDRSIZE]; /* Buffer to assemble frame-header in */ #endif #if defined(SQLITE_HAS_CODEC) if( (pData = sqlite3PagerCodec(pPage))==0 ) return SQLITE_NOMEM_BKPT; #else |
︙ | ︙ |
Changes to test/backcompat.test.
︙ | ︙ | |||
59 60 61 62 63 64 65 | code2 { sqlite3 db test.db } foreach c {code1 code2} { $c { set v [split [db version] .] if {[llength $v]==3} {lappend v 0} set ::sqlite_libversion [format \ | | | 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | code2 { sqlite3 db test.db } foreach c {code1 code2} { $c { set v [split [db version] .] if {[llength $v]==3} {lappend v 0} set ::sqlite_libversion [format \ "%d%.2d%.2d%.2d" [lindex $v 0] [lindex $v 1] [lindex $v 2] [lindex $v 3] ] } } uplevel $script catch { code1 { db close } } |
︙ | ︙ | |||
416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 | SELECT level, group_concat(idx, ' ') FROM t2_segdir GROUP BY level; } } {0 {0 1 2 3 4 5}} if {[code1 { set ::sqlite_libversion }] >=3071200 && [code2 { set ::sqlite_libversion }] >=3071200 } { do_test backcompat-3.9 { sql1 { INSERT INTO t2(t2) VALUES('merge=100,4'); } sql2 { INSERT INTO t2(t2) VALUES('merge=100,4'); } sql1 { INSERT INTO t2(t2) VALUES('merge=100,4'); } sql2 { INSERT INTO t2(t2) VALUES('merge=2500,4'); } sql2 { SELECT level, group_concat(idx, ' ') FROM t2_segdir GROUP BY level; } | > > > > > > | | 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 | SELECT level, group_concat(idx, ' ') FROM t2_segdir GROUP BY level; } } {0 {0 1 2 3 4 5}} if {[code1 { set ::sqlite_libversion }] >=3071200 && [code2 { set ::sqlite_libversion }] >=3071200 } { if {[code1 { set ::sqlite_libversion }]<3120000} { set res {0 {0 1} 1 0} } else { set res {1 0} } do_test backcompat-3.9 { sql1 { INSERT INTO t2(t2) VALUES('merge=100,4'); } sql2 { INSERT INTO t2(t2) VALUES('merge=100,4'); } sql1 { INSERT INTO t2(t2) VALUES('merge=100,4'); } sql2 { INSERT INTO t2(t2) VALUES('merge=2500,4'); } sql2 { SELECT level, group_concat(idx, ' ') FROM t2_segdir GROUP BY level; } } $res do_test backcompat-3.10 { sql1 { INSERT INTO t2(t2) VALUES('integrity-check') } sql2 { INSERT INTO t2(t2) VALUES('integrity-check') } } {} } } |
︙ | ︙ |
Changes to test/fts4growth.test.
︙ | ︙ | |||
55 56 57 58 59 60 61 | } { execsql { INSERT INTO x1 VALUES($L) } } execsql { INSERT INTO x1(x1) VALUES('merge=4,4'); SELECT level, end_block, length(root) FROM x1_segdir; } | | | > > > > > > | | | | 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 | } { execsql { INSERT INTO x1 VALUES($L) } } execsql { INSERT INTO x1(x1) VALUES('merge=4,4'); SELECT level, end_block, length(root) FROM x1_segdir; } } {1 {224 921} 2} do_execsql_test 1.5 { SELECT length(block) FROM x1_segments; } {921 {}} do_test 1.6 { foreach L { {'Twas Mulga Bill, from Eaglehawk, that sought his own abode,} {That perched above Dead Man's Creek, beside the mountain road.} {He turned the cycle down the hill and mounted for the fray,} {But 'ere he'd gone a dozen yards it bolted clean away.} {It left the track, and through the trees, just like a silver steak,} {It whistled down the awful slope towards the Dead Man's Creek.} {It shaved a stump by half an inch, it dodged a big white-box:} {The very wallaroos in fright went scrambling up the rocks,} {The wombats hiding in their caves dug deeper underground,} {As Mulga Bill, as white as chalk, sat tight to every bound.} {It struck a stone and gave a spring that cleared a fallen tree,} {It raced beside a precipice as close as close could be;} {And then as Mulga Bill let out one last despairing shriek} {It made a leap of twenty feet into the Dead Man's Creek.} {It shaved a stump by half an inch, it dodged a big white-box:} {The very wallaroos in fright went scrambling up the rocks,} {The wombats hiding in their caves dug deeper underground,} } { execsql { INSERT INTO x1 VALUES($L) } } execsql { SELECT level, end_block, length(root) FROM x1_segdir; } } {1 {224 921} 2 1 {226 1230} 7 0 {0 98} 98} do_execsql_test 1.7 { SELECT sum(length(block)) FROM x1_segments WHERE blockid IN (224,225,226) } {1230} #------------------------------------------------------------------------- # do_execsql_test 2.1 { CREATE TABLE t1(docid, words); CREATE VIRTUAL TABLE x2 USING fts4; } |
︙ | ︙ | |||
127 128 129 130 131 132 133 | do_execsql_test 2.5 { SELECT end_block FROM x2_segdir WHERE level=3; INSERT INTO x2(x2) VALUES('merge=4,4'); SELECT end_block FROM x2_segdir WHERE level=3; INSERT INTO x2(x2) VALUES('merge=4,4'); SELECT end_block FROM x2_segdir WHERE level=3; | | | | | | 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 | do_execsql_test 2.5 { SELECT end_block FROM x2_segdir WHERE level=3; INSERT INTO x2(x2) VALUES('merge=4,4'); SELECT end_block FROM x2_segdir WHERE level=3; INSERT INTO x2(x2) VALUES('merge=4,4'); SELECT end_block FROM x2_segdir WHERE level=3; } {{5588 -3950} {5588 -11766} {5588 -15541}} do_execsql_test 2.6 { SELECT sum(length(block)) FROM x2_segdir, x2_segments WHERE blockid BETWEEN start_block AND leaves_end_block AND level=3 } {15541} do_execsql_test 2.7 { INSERT INTO x2(x2) VALUES('merge=1000,4'); SELECT end_block FROM x2_segdir WHERE level=3; } {{5588 127563}} do_execsql_test 2.8 { SELECT sum(length(block)) FROM x2_segdir, x2_segments WHERE blockid BETWEEN start_block AND leaves_end_block AND level=3 } {127563} #-------------------------------------------------------------------------- # Test that delete markers are removed from FTS segments when possible. # It is only possible to remove delete markers when the output of the # merge operation will become the oldest segment in the index. # # 3.1 - when the oldest segment is created by an 'optimize'. |
︙ | ︙ | |||
387 388 389 390 391 392 393 | do_execsql_test 7.2 { INSERT INTO x6(x6) VALUES('merge=25,4'); SELECT level, idx, end_block FROM x6_segdir; } { 0 0 {118 117483} 0 1 {238 118006} 0 2 {358 118006} 0 3 {478 118006} 0 4 {598 118006} 0 5 {718 118006} | | | | | | | < | < | 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 | do_execsql_test 7.2 { INSERT INTO x6(x6) VALUES('merge=25,4'); SELECT level, idx, end_block FROM x6_segdir; } { 0 0 {118 117483} 0 1 {238 118006} 0 2 {358 118006} 0 3 {478 118006} 0 4 {598 118006} 0 5 {718 118006} 1 0 {23694 -69477} } do_execsql_test 7.3 { UPDATE x6_segdir SET end_block = first(end_block) WHERE level=1; SELECT level, idx, end_block FROM x6_segdir; } { 0 0 {118 117483} 0 1 {238 118006} 0 2 {358 118006} 0 3 {478 118006} 0 4 {598 118006} 0 5 {718 118006} 1 0 23694 } do_execsql_test 7.4 { INSERT INTO x6(x6) VALUES('merge=25,4'); SELECT level, idx, end_block FROM x6_segdir; } { 0 0 {118 117483} 0 1 {238 118006} 0 2 {358 118006} 0 3 {478 118006} 0 4 {598 118006} 0 5 {718 118006} 1 0 23694 } do_execsql_test 7.5 { INSERT INTO x6(x6) VALUES('merge=2500,4'); SELECT level, idx, start_block, leaves_end_block, end_block FROM x6_segdir; } { 1 0 719 1171 23694 } do_execsql_test 7.6 { INSERT INTO x6(x6) VALUES('merge=2500,2'); SELECT level, idx, start_block, leaves_end_block, end_block FROM x6_segdir; } { 1 0 719 1171 23694 } do_execsql_test 7.7 { SELECT sum(length(block)) FROM x6_segments } {635247} finish_test |
Changes to test/fts4langid.test.
︙ | ︙ | |||
477 478 479 480 481 482 483 | 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; | | | 477 478 479 480 481 482 483 484 485 486 | 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; } {1 2} } finish_test |
Changes to test/fts4merge.test.
︙ | ︙ | |||
51 52 53 54 55 56 57 | SELECT docid FROM t1 WHERE t1 MATCH 'zero one two three' } {123 132 213 231 312 321} } do_execsql_test 1.3 { SELECT level, group_concat(idx, ' ') FROM t1_segdir GROUP BY level } { | < < < | 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | SELECT docid FROM t1 WHERE t1 MATCH 'zero one two three' } {123 132 213 231 312 321} } do_execsql_test 1.3 { SELECT level, group_concat(idx, ' ') FROM t1_segdir GROUP BY level } { 2 {0 1 2 3} } for {set i 0} {$i<100} {incr i} { do_execsql_test 1.4.$i { INSERT INTO t1(t1) VALUES('merge=1,4') } do_test 1.4.$i.2 { fts3_integrity_check t1 } ok do_execsql_test 1.4.$i.3 { SELECT docid FROM t1 WHERE t1 MATCH 'zero one two three' } {123 132 213 231 312 321} } do_execsql_test 1.5 { SELECT level, group_concat(idx, ' ') FROM t1_segdir GROUP BY level } { 3 0 } #------------------------------------------------------------------------- # Test cases 2.* test that errors in the xxx part of the 'merge=xxx' are # handled correctly. # |
︙ | ︙ | |||
114 115 116 117 118 119 120 | 3 {0 1 2 3 4 5 6} } do_execsql_test 3.3 { INSERT INTO t2(t2) VALUES('merge=1000000,2'); SELECT level, group_concat(idx, ' ') FROM t2_segdir GROUP BY level } { | < < < < | 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 | 3 {0 1 2 3 4 5 6} } do_execsql_test 3.3 { INSERT INTO t2(t2) VALUES('merge=1000000,2'); SELECT level, group_concat(idx, ' ') FROM t2_segdir GROUP BY level } { 4 0 } #------------------------------------------------------------------------- # Test cases 4.* # reset_db do_execsql_test 4.1 " |
︙ | ︙ | |||
198 199 200 201 202 203 204 | } do_execsql_test 5.3 { INSERT INTO t1(t1) VALUES('merge=1,5'); INSERT INTO t1(t1) VALUES('merge=1,5'); SELECT level, group_concat(idx, ' ') FROM t1_segdir GROUP BY level; } { | < | | | | | < | | | | 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 | } do_execsql_test 5.3 { INSERT INTO t1(t1) VALUES('merge=1,5'); INSERT INTO t1(t1) VALUES('merge=1,5'); SELECT level, group_concat(idx, ' ') FROM t1_segdir GROUP BY level; } { 1 {0 1 2 3 4 5 6 7 8 9 10 11 12 13 14} 2 {0 1 2 3} } do_execsql_test 5.4 {SELECT quote(value) from t1_stat WHERE rowid=1} {X'010F'} do_test 5.5 { foreach docid [execsql {SELECT docid FROM t1}] { execsql {INSERT INTO t1 SELECT * FROM t1 WHERE docid=$docid} } } {} do_execsql_test 5.6 {SELECT quote(value) from t1_stat WHERE rowid=1} {X'010F'} do_execsql_test 5.7 { SELECT level, group_concat(idx, ' ') FROM t1_segdir GROUP BY level; SELECT quote(value) from t1_stat WHERE rowid=1; } { 0 {0 1 2 3 4 5 6 7} 1 {0 1 2 3 4 5 6 7 8 9 10 11 12} 2 {0 1 2 3 4 5 6 7} X'010F' } do_execsql_test 5.8 { INSERT INTO t1(t1) VALUES('merge=1,6'); INSERT INTO t1(t1) VALUES('merge=1,6'); SELECT level, group_concat(idx, ' ') FROM t1_segdir GROUP BY level; SELECT quote(value) from t1_stat WHERE rowid=1; } { 1 {0 1 2 3 4 5 6 7 8 9 10 11 12 13} 2 {0 1 2 3 4 5 6 7 8} X'010E' } do_test 5.8.1 { fts3_integrity_check t1 } ok do_test 5.9 { set L [expr 16*16*7 + 16*3 + 12] foreach docid [execsql { SELECT docid FROM t1 UNION ALL SELECT docid FROM t1 LIMIT $L }] { execsql {INSERT INTO t1 SELECT * FROM t1 WHERE docid=$docid} } } {} do_execsql_test 5.10 { SELECT level, group_concat(idx, ' ') FROM t1_segdir GROUP BY level; SELECT quote(value) from t1_stat WHERE rowid=1; } { 0 {0 1 2 3 4 5 6 7 8 9 10 11} 1 0 2 0 3 0 X'010E' } do_execsql_test 5.11 { INSERT INTO t1(t1) VALUES('merge=1,6'); SELECT level, group_concat(idx, ' ') FROM t1_segdir GROUP BY level; SELECT quote(value) from t1_stat WHERE rowid=1; } { 1 {0 1} 2 0 3 0 X'010E' } #------------------------------------------------------------------------- # Test cases 6.* # # At one point the following test caused an assert() to fail (because the # second 'merge=1,2' operation below actually "merges" a single input |
︙ | ︙ |
Changes to test/fts4merge3.test.
︙ | ︙ | |||
58 59 60 61 62 63 64 | do_test 1.6.$i.2 { sql2 "SELECT docid FROM t2 WHERE t2 MATCH 'abc'" } {1485} } do_test 1.7 { sql2 { SELECT level, count(*) FROM t2_segdir GROUP BY level ORDER BY 1 | | | | 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | do_test 1.6.$i.2 { sql2 "SELECT docid FROM t2 WHERE t2 MATCH 'abc'" } {1485} } do_test 1.7 { sql2 { SELECT level, count(*) FROM t2_segdir GROUP BY level ORDER BY 1 } } {2 15 3 5} # Using the old connection, insert many rows. do_test 1.8 { for {set i 0} {$i < 1500} {incr i} { sql2 "INSERT INTO t2 SELECT content FROM t2 WHERE docid = $i" } } {} do_test 1.9 { sql2 { SELECT level, count(*) FROM t2_segdir GROUP BY level ORDER BY 1 } } [list 0 12 1 13 2 4 3 6] # Run a big incr-merge operation on the db. do_test 1.10 { sql1 { INSERT INTO t2(t2) VALUES('merge=2000,2') } } {} do_test 1.11 { sql2 "SELECT docid FROM t2 WHERE t2 MATCH 'abc'" } {1485 21485} |
︙ | ︙ | |||
93 94 95 96 97 98 99 | do_test 1.14 { sql2 "INSERT INTO t2(t2) VALUES('optimize')" sql2 "SELECT docid FROM t2 WHERE t2 MATCH 'abc'" } {1485 21485 22985} do_test 1.15 { sql2 { SELECT level, count(*) FROM t2_segdir GROUP BY level ORDER BY 1 | | | 93 94 95 96 97 98 99 100 101 102 103 104 105 | do_test 1.14 { sql2 "INSERT INTO t2(t2) VALUES('optimize')" sql2 "SELECT docid FROM t2 WHERE t2 MATCH 'abc'" } {1485 21485 22985} do_test 1.15 { sql2 { SELECT level, count(*) FROM t2_segdir GROUP BY level ORDER BY 1 } } {4 1} } } finish_test |
Changes to test/fts4opt.test.
︙ | ︙ | |||
88 89 90 91 92 93 94 | 2080 33 3104 33 } do_test 1.6 { while 1 { set tc1 [db total_changes] | | | 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | 2080 33 3104 33 } do_test 1.6 { while 1 { set tc1 [db total_changes] execsql { INSERT INTO t2(t2) VALUES('merge=5,2') } set tc2 [db total_changes] if {($tc2 - $tc1) < 2} break } execsql { SELECT level, count(*) FROM t2_segdir GROUP BY level } } {33 1 1057 1 2081 1 3105 1} do_execsql_test 1.7 { INSERT INTO t2(t2) VALUES('integrity-check') } |
︙ | ︙ | |||
149 150 151 152 153 154 155 | 2080 37 3104 37 } do_test 2.6 { while 1 { set tc1 [db total_changes] | | | 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 | 2080 37 3104 37 } do_test 2.6 { while 1 { set tc1 [db total_changes] execsql { INSERT INTO t2(t2) VALUES('merge=5,2') } set tc2 [db total_changes] if {($tc2 - $tc1) < 2} break } execsql { SELECT level, count(*) FROM t2_segdir GROUP BY level } } {33 1 1057 1 2081 1 3105 1} do_execsql_test 2.7 { INSERT INTO t2(t2) VALUES('integrity-check') } do_execsql_test 2.8 { INSERT INTO t2(words) SELECT words FROM t1; SELECT level, count(*) FROM t2_segdir GROUP BY level; } {0 2 1024 2 2048 2 3072 2} finish_test |
Changes to test/unixexcl.test.
︙ | ︙ | |||
83 84 85 86 87 88 89 90 91 92 93 94 95 96 | do_multiclient_test tn { do_test unixexcl-3.$tn.1 { code1 { db close; sqlite3 db file:test.db?psow=0 -vfs unix-excl -uri 1 } code2 { db2 close; sqlite3 db2 file:test.db?psow=0 -vfs unix-excl -uri 1 } sql1 { PRAGMA auto_vacuum = 0; PRAGMA journal_mode = WAL; CREATE TABLE t1(a, b); INSERT INTO t1 VALUES(1, 2); } } {wal} if {$tn==1} { do_test unixexcl-3.$tn.1.multiproc { | > | 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 | do_multiclient_test tn { do_test unixexcl-3.$tn.1 { code1 { db close; sqlite3 db file:test.db?psow=0 -vfs unix-excl -uri 1 } code2 { db2 close; sqlite3 db2 file:test.db?psow=0 -vfs unix-excl -uri 1 } sql1 { PRAGMA auto_vacuum = 0; PRAGMA journal_mode = WAL; PRAGMA synchronous = FULL; CREATE TABLE t1(a, b); INSERT INTO t1 VALUES(1, 2); } } {wal} if {$tn==1} { do_test unixexcl-3.$tn.1.multiproc { |
︙ | ︙ |
Changes to test/wal2.test.
︙ | ︙ | |||
1222 1223 1224 1225 1226 1227 1228 | catch { db close } } } #------------------------------------------------------------------------- # Test that "PRAGMA checkpoint_fullsync" appears to be working. # | | | | | | < < < | 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 | catch { db close } } } #------------------------------------------------------------------------- # Test that "PRAGMA checkpoint_fullsync" appears to be working. # foreach {tn sql reslist} { 1 { } {10 0 4 0 6 0} 2 { PRAGMA checkpoint_fullfsync = 1 } {10 4 4 2 6 2} 3 { PRAGMA checkpoint_fullfsync = 0 } {10 0 4 0 6 0} } { faultsim_delete_and_reopen execsql {PRAGMA auto_vacuum = 0; PRAGMA synchronous = FULL;} execsql $sql do_execsql_test wal2-14.$tn.0 { PRAGMA page_size = 4096 } {} do_execsql_test wal2-14.$tn.1 { PRAGMA journal_mode = WAL } {wal} set sqlite_sync_count 0 set sqlite_fullsync_count 0 set useres $reslist do_execsql_test wal2-14.$tn.2 { PRAGMA wal_autocheckpoint = 10; CREATE TABLE t1(a, b); -- 2 wal syncs INSERT INTO t1 VALUES(1, 2); -- 2 wal sync PRAGMA wal_checkpoint; -- 1 wal sync, 1 db sync BEGIN; |
︙ | ︙ |
Changes to test/wal3.test.
︙ | ︙ | |||
195 196 197 198 199 200 201 | # CREATE TABLE x(y); # INSERT INTO x VALUES('z'); # PRAGMA wal_checkpoint; # # in WAL mode the xSync method is invoked as expected for each of # synchronous=off, synchronous=normal and synchronous=full. # | | < < < < < < | 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 | # CREATE TABLE x(y); # INSERT INTO x VALUES('z'); # PRAGMA wal_checkpoint; # # in WAL mode the xSync method is invoked as expected for each of # synchronous=off, synchronous=normal and synchronous=full. # foreach {tn syncmode synccount} { 1 off {} 2 normal {test.db-wal normal test.db normal} 3 full {test.db-wal normal test.db-wal normal test.db-wal normal test.db normal} } { proc sync_counter {args} { foreach {method filename id flags} $args break lappend ::syncs [file tail $filename] $flags } set usecount $synccount do_test wal3-3.$tn { forcedelete test.db test.db-wal test.db-journal testvfs T T filter {} T script sync_counter |
︙ | ︙ |
Changes to test/zerodamage.test.
︙ | ︙ | |||
108 109 110 111 112 113 114 115 116 117 118 119 120 121 | # Repeat the previous with POWERSAFE_OVERWRITE off. Verify that the WAL file # is padded. # do_test zerodamage-3.1 { db close sqlite3 db file:test.db?psow=FALSE -uri 1 db eval { UPDATE t1 SET y=randomblob(50) WHERE x=124; } file size test.db-wal } {16800} } finish_test | > | 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 | # Repeat the previous with POWERSAFE_OVERWRITE off. Verify that the WAL file # is padded. # do_test zerodamage-3.1 { db close sqlite3 db file:test.db?psow=FALSE -uri 1 db eval { PRAGMA synchronous=FULL; UPDATE t1 SET y=randomblob(50) WHERE x=124; } file size test.db-wal } {16800} } finish_test |