Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Changes In Branch cf8f1552-commit-instr Excluding Merge-Ins
This is equivalent to a diff from cf8f155280 to b0cd8dfcf9
2025-01-10
| ||
18:03 | Update log messages on this branch to say "v=22". Also add log message to slow calls to sqlite3_schema_copy(). (Leaf check-in: b0cd8dfcf9 user: dan tags: cf8f1552-commit-instr) | |
17:36 | Add the experimental sqlite3_schema_copy() API, for copying schemas between database handles. (check-in: 04ea435d24 user: dan tags: cf8f1552-commit-instr) | |
2024-10-07
| ||
16:11 | Add logging to help analyze commit performance. (check-in: c5391f2cc9 user: dan tags: cf8f1552-commit-instr) | |
2024-09-06
| ||
15:45 | Update the bedrock branch to include all the latest enhancements from trunk. (check-in: 4a3386ccb8 user: drh tags: bedrock) | |
2024-09-04
| ||
16:54 | Update the bedrock branch to include all of the latest trunk enhancements. (check-in: cf8f155280 user: drh tags: bedrock) | |
16:46 | Merge all the latest trunk enhancements into the wal2 branch. (check-in: 9f53034371 user: drh tags: wal2) | |
2024-08-29
| ||
23:43 | Merge the latest trunk enhancement into the bedrock branch through the wal2 intermediary. (check-in: ff94464cec user: drh tags: bedrock) | |
Changes to ext/fts5/fts5_index.c.
︙ | ︙ | |||
4877 4878 4879 4880 4881 4882 4883 | i64 nEntry = 0; i64 nTomb = 0; int iSeg; for(iSeg=0; iSeg<pLvl->nSeg; iSeg++){ nEntry += pLvl->aSeg[iSeg].nEntry; nTomb += pLvl->aSeg[iSeg].nEntryTombstone; } | < | 4877 4878 4879 4880 4881 4882 4883 4884 4885 4886 4887 4888 4889 4890 | i64 nEntry = 0; i64 nTomb = 0; int iSeg; for(iSeg=0; iSeg<pLvl->nSeg; iSeg++){ nEntry += pLvl->aSeg[iSeg].nEntry; nTomb += pLvl->aSeg[iSeg].nEntryTombstone; } if( nEntry>0 ){ int nPercent = (nTomb * 100) / nEntry; if( nPercent>=pConfig->nDeleteMerge && nPercent>nBest ){ iRet = ii; nBest = nPercent; } } |
︙ | ︙ |
Changes to src/alter.c.
︙ | ︙ | |||
1412 1413 1414 1415 1416 1417 1418 | return rc; } /* ** Invoke sqlite3WalkExpr() or sqlite3WalkSelect() on all Select or Expr ** objects that are part of the trigger passed as the second argument. */ | | | 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 | return rc; } /* ** Invoke sqlite3WalkExpr() or sqlite3WalkSelect() on all Select or Expr ** objects that are part of the trigger passed as the second argument. */ void sqlite3WalkTrigger(Walker *pWalker, Trigger *pTrigger){ TriggerStep *pStep; /* Find tokens to edit in WHEN clause */ sqlite3WalkExpr(pWalker, pTrigger->pWhen); /* Find tokens to edit in trigger steps */ for(pStep=pTrigger->step_list; pStep; pStep=pStep->pNext){ |
︙ | ︙ | |||
1627 1628 1629 1630 1631 1632 1633 | /* Find tokens to edit in UPDATE OF clause */ if( sParse.pTriggerTab==pTab ){ renameColumnIdlistNames(&sParse, &sCtx,sParse.pNewTrigger->pColumns,zOld); } /* Find tokens to edit in various expressions and selects */ | | | 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 | /* Find tokens to edit in UPDATE OF clause */ if( sParse.pTriggerTab==pTab ){ renameColumnIdlistNames(&sParse, &sCtx,sParse.pNewTrigger->pColumns,zOld); } /* Find tokens to edit in various expressions and selects */ sqlite3WalkTrigger(&sWalker, sParse.pNewTrigger); } assert( rc==SQLITE_OK ); rc = renameEditSql(context, &sCtx, zSql, zNew, bQuote); renameColumnFunc_done: if( rc!=SQLITE_OK ){ |
︙ | ︙ | |||
1820 1821 1822 1823 1824 1825 1826 | ){ renameTokenFind(&sParse, &sCtx, sParse.pNewTrigger->table); } if( isLegacy==0 ){ rc = renameResolveTrigger(&sParse); if( rc==SQLITE_OK ){ | | | 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 | ){ renameTokenFind(&sParse, &sCtx, sParse.pNewTrigger->table); } if( isLegacy==0 ){ rc = renameResolveTrigger(&sParse); if( rc==SQLITE_OK ){ sqlite3WalkTrigger(&sWalker, pTrigger); for(pStep=pTrigger->step_list; pStep; pStep=pStep->pNext){ if( pStep->zTarget && 0==sqlite3_stricmp(pStep->zTarget, zOld) ){ renameTokenFind(&sParse, &sCtx, pStep->zTarget); } if( pStep->pFrom ){ int i; for(i=0; i<pStep->pFrom->nSrc; i++){ |
︙ | ︙ | |||
1961 1962 1963 1964 1965 1966 1967 | }else if( sParse.pNewIndex ){ sqlite3WalkExprList(&sWalker, sParse.pNewIndex->aColExpr); sqlite3WalkExpr(&sWalker, sParse.pNewIndex->pPartIdxWhere); }else{ #ifndef SQLITE_OMIT_TRIGGER rc = renameResolveTrigger(&sParse); if( rc==SQLITE_OK ){ | | | 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 | }else if( sParse.pNewIndex ){ sqlite3WalkExprList(&sWalker, sParse.pNewIndex->aColExpr); sqlite3WalkExpr(&sWalker, sParse.pNewIndex->pPartIdxWhere); }else{ #ifndef SQLITE_OMIT_TRIGGER rc = renameResolveTrigger(&sParse); if( rc==SQLITE_OK ){ sqlite3WalkTrigger(&sWalker, sParse.pNewTrigger); } #endif /* SQLITE_OMIT_TRIGGER */ } if( rc==SQLITE_OK ){ rc = renameEditSql(context, &sCtx, zInput, 0, 0); } |
︙ | ︙ |
Changes to src/analyze.c.
︙ | ︙ | |||
252 253 254 255 256 257 258 259 260 261 262 263 264 265 | /* ** Recommended number of samples for sqlite_stat4 */ #ifndef SQLITE_STAT4_SAMPLES # define SQLITE_STAT4_SAMPLES 24 #endif /* ** Three SQL functions - stat_init(), stat_push(), and stat_get() - ** share an instance of the following structure to hold their state ** information. */ typedef struct StatAccum StatAccum; typedef struct StatSample StatSample; | > > > > > > > | 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 | /* ** Recommended number of samples for sqlite_stat4 */ #ifndef SQLITE_STAT4_SAMPLES # define SQLITE_STAT4_SAMPLES 24 #endif /* ** Assumed number of of samples when loading sqlite_stat4 data. It doesn't ** matter if there are more or fewer samples than this, but is more efficient ** if this estimate turns out to be true. */ #define SQLITE_STAT4_EST_SAMPLES SQLITE_STAT4_SAMPLES /* ** Three SQL functions - stat_init(), stat_push(), and stat_get() - ** share an instance of the following structure to hold their state ** information. */ typedef struct StatAccum StatAccum; typedef struct StatSample StatSample; |
︙ | ︙ | |||
1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 | assert( aOut==0 ); UNUSED_PARAMETER(aOut); assert( aLog!=0 ); aLog[i] = sqlite3LogEst(v); #endif if( *z==' ' ) z++; } #ifndef SQLITE_ENABLE_STAT4 assert( pIndex!=0 ); { #else if( pIndex ){ #endif pIndex->bUnordered = 0; pIndex->noSkipScan = 0; | > > > | 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 | assert( aOut==0 ); UNUSED_PARAMETER(aOut); assert( aLog!=0 ); aLog[i] = sqlite3LogEst(v); #endif if( *z==' ' ) z++; } if( aOut ){ for(/* no-op */; i<nOut; i++){ aOut[i] = 0; } } #ifndef SQLITE_ENABLE_STAT4 assert( pIndex!=0 ); { #else if( pIndex ){ #endif pIndex->bUnordered = 0; pIndex->noSkipScan = 0; |
︙ | ︙ | |||
1668 1669 1670 1671 1672 1673 1674 | #ifdef SQLITE_ENABLE_STAT4 if( pIdx->aSample ){ int j; for(j=0; j<pIdx->nSample; j++){ IndexSample *p = &pIdx->aSample[j]; sqlite3DbFree(db, p->p); } | > | > > | 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 | #ifdef SQLITE_ENABLE_STAT4 if( pIdx->aSample ){ int j; for(j=0; j<pIdx->nSample; j++){ IndexSample *p = &pIdx->aSample[j]; sqlite3DbFree(db, p->p); } if( pIdx->nSampleAlloc!=SQLITE_STAT4_EST_SAMPLES ){ sqlite3DbFree(db, pIdx->aSample); } } if( db->pnBytesFreed==0 ){ pIdx->nSample = 0; pIdx->aSample = 0; pIdx->nSampleAlloc = 0; } #else UNUSED_PARAMETER(db); UNUSED_PARAMETER(pIdx); #endif /* SQLITE_ENABLE_STAT4 */ } |
︙ | ︙ | |||
1758 1759 1760 1761 1762 1763 1764 | Table *pTab = sqlite3FindTable(db, zName, zDb); if( pTab && !HasRowid(pTab) ) pIdx = sqlite3PrimaryKeyIndex(pTab); } return pIdx; } /* | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | | 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 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 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 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 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 | Table *pTab = sqlite3FindTable(db, zName, zDb); if( pTab && !HasRowid(pTab) ) pIdx = sqlite3PrimaryKeyIndex(pTab); } return pIdx; } /* ** Grow the pIdx->aSample[] array. Return SQLITE_OK if successful, or ** SQLITE_NOMEM otherwise. ** ** Space for the pIdx->aSample[] array and its contents may come either ** directly from sqlite3DbMallocRaw(), or from buffer Schema.pStat4Space. ** Schema.pStat4Space is only used when the aSample[] array is resized ** to exactly SQLITE_STAT4_EST_SAMPLES entries. ** ** If parameter nReq is non-zero, then it is the exact number of samples ** to which the array should be sized. Or, if nReq is 0, then the array ** is set to either SQLITE_STAT4_EST_SAMPLES (if pIdx->nSample==0), or ** to pIdx->nSample*2 (if pIdx->nSample!=0). */ static int growSampleArray(sqlite3 *db, Index *pIdx, int nReq){ int nIdxCol = pIdx->nSampleCol; int nNew = 0; IndexSample *aNew = 0; int nByte = 0; tRowcnt *pSpace; /* Available allocated memory space */ u8 *pPtr; /* Available memory as a u8 for easier manipulation */ int i; assert( pIdx->nSample==pIdx->nSampleAlloc ); if( nReq==0 ){ nNew = SQLITE_STAT4_EST_SAMPLES; if( pIdx->nSample ){ nNew = pIdx->nSample*2; } }else{ nNew = nReq; } /* Set nByte to the required amount of space */ nByte = ROUND8(sizeof(IndexSample) * nNew); nByte += sizeof(tRowcnt) * nIdxCol * 3 * nNew; nByte += nIdxCol * sizeof(tRowcnt); /* Space for Index.aAvgEq[] */ if( nNew==SQLITE_STAT4_EST_SAMPLES ){ Schema *pSchema = pIdx->pSchema; aNew = (IndexSample*)&((u8*)pSchema->pStat4Space)[pSchema->nStat4Space]; pSchema->nStat4Space += nByte; assert( pSchema->nStat4Space<=sqlite3_msize(pSchema->pStat4Space) ); }else{ aNew = (IndexSample*)sqlite3DbMallocRaw(db, nByte); if( aNew==0 ) return SQLITE_NOMEM_BKPT; } pPtr = (u8*)aNew; pPtr += ROUND8(nNew*sizeof(pIdx->aSample[0])); pSpace = (tRowcnt*)pPtr; pIdx->aAvgEq = pSpace; pSpace += nIdxCol; assert( EIGHT_BYTE_ALIGNMENT( pSpace ) ); if( pIdx->nSample ){ /* Copy the contents of the anEq[], anLt[], anDLt[] arrays for all ** extant samples to the new location. */ int nByte = nIdxCol * 3 * sizeof(tRowcnt) * pIdx->nSample; memcpy(pSpace, pIdx->aSample[0].anEq, nByte); } for(i=0; i<nNew; i++){ aNew[i].anEq = pSpace; pSpace += nIdxCol; aNew[i].anLt = pSpace; pSpace += nIdxCol; aNew[i].anDLt = pSpace; pSpace += nIdxCol; if( i<pIdx->nSample ){ aNew[i].p = pIdx->aSample[i].p; aNew[i].n = pIdx->aSample[i].n; } } assert( ((u8*)pSpace)-nByte==(u8*)aNew ); if( pIdx->nSample!=SQLITE_STAT4_EST_SAMPLES ){ sqlite3DbFree(db, pIdx->aSample); } pIdx->aSample = aNew; pIdx->nSampleAlloc = nNew; return SQLITE_OK; } /* ** Copy stat4 related data from index pFrom to index pTo. This is part ** of the sqlite3_schema_copy() implementation. Return SQLITE_OK if ** successful, or SQLITE_NOMEM if an OOM error is encountered. */ int sqlite3AnalyzeCopyStat4( sqlite3 *db, /* Database handle */ Index *pTo, /* Target index (must belong to db) */ Index *pFrom /* Source index */ ){ if( pFrom->nSample>0 ){ int ii; pTo->nSample = pTo->nSampleAlloc = 0; if( growSampleArray(db, pTo, pFrom->nSample) ){ return SQLITE_NOMEM; } pTo->nSample = pFrom->nSample; memcpy(pTo->aAvgEq, pFrom->aAvgEq, pFrom->nSampleCol * sizeof(tRowcnt)); memcpy(pTo->aSample[0].anEq, pFrom->aSample[0].anEq, pTo->nSampleCol * 3 * sizeof(tRowcnt) * pTo->nSample ); for(ii=0; ii<pTo->nSample; ii++){ int nByte = pFrom->aSample[ii].n; void *p = sqlite3DbMallocZero(db, nByte+8); if( p ){ memcpy(p, pFrom->aSample[ii].p, nByte); } pTo->aSample[ii].p = p; pTo->aSample[ii].n = nByte; } } return SQLITE_OK; } /* ** Allocate the space that will likely be required for the Index.aSample[] ** arrays populated by loading data from the sqlite_stat4 table. Return ** SQLITE_OK if successful, or SQLITE_NOMEM otherwise. */ static int stat4AllocSpace(sqlite3 *db, const char *zDb){ int iDb = sqlite3FindDbName(db, zDb); Schema *pSchema = db->aDb[iDb].pSchema; int nByte = 0; HashElem *k; assert( iDb>=0 ); assert( pSchema->pStat4Space==0 ); for(k=sqliteHashFirst(&pSchema->idxHash); k; k=sqliteHashNext(k)){ Index *pIdx = sqliteHashData(k); int nIdxCol; if( !HasRowid(pIdx->pTable) && IsPrimaryKeyIndex(pIdx) ){ nIdxCol = pIdx->nKeyCol; }else{ nIdxCol = pIdx->nColumn; } nByte += ROUND8(sizeof(IndexSample) * SQLITE_STAT4_EST_SAMPLES); nByte += sizeof(tRowcnt) * nIdxCol * 3 * SQLITE_STAT4_EST_SAMPLES; nByte += nIdxCol * sizeof(tRowcnt); /* Space for Index.aAvgEq[] */ } if( nByte>0 ){ pSchema->pStat4Space = sqlite3_malloc(nByte); pSchema->nStat4Space = 0; if( pSchema->pStat4Space==0 ){ return SQLITE_NOMEM_BKPT; } } return SQLITE_OK; } /* ** Load the content from the sqlite_stat4 into the relevant Index.aSample[] ** arrays. ** ** Arguments zSql1 and zSql2 must point to SQL statements that return ** data equivalent to the following: ** ** zSql1: SELECT idx,count(*) FROM %Q.sqlite_stat4 GROUP BY idx ** zSql2: SELECT idx,neq,nlt,ndlt,sample FROM %Q.sqlite_stat4 ** |
︙ | ︙ | |||
1782 1783 1784 1785 1786 1787 1788 | int rc; /* Result codes from subroutines */ sqlite3_stmt *pStmt = 0; /* An SQL statement being run */ char *zSql; /* Text of the SQL statement */ Index *pPrevIdx = 0; /* Previous index in the loop */ IndexSample *pSample; /* A slot in pIdx->aSample[] */ assert( db->lookaside.bDisable ); | < < < | < < < | < < | < < < < < < < | < | < < < < < < < | < < < < < < < < < < < | < < < < < < < < < < < < < < < < < < < < > > > > | < > | > > > | > | < | > > > > > | > > | 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 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 2003 2004 2005 2006 2007 2008 2009 2010 2011 | int rc; /* Result codes from subroutines */ sqlite3_stmt *pStmt = 0; /* An SQL statement being run */ char *zSql; /* Text of the SQL statement */ Index *pPrevIdx = 0; /* Previous index in the loop */ IndexSample *pSample; /* A slot in pIdx->aSample[] */ assert( db->lookaside.bDisable ); /* Allocate the Schema.pStat4Space block that will be used for the ** Index.aSample[] arrays populated by this call. */ rc = stat4AllocSpace(db, zDb); if( rc!=SQLITE_OK ) return rc; sqlite3PrepareTimeSet(db->aSchemaTime, SCHEMA_TIME_AFTER_STAT4_SPACE); zSql = sqlite3MPrintf(db, zSql2, zDb); if( !zSql ){ return SQLITE_NOMEM_BKPT; } rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0); sqlite3DbFree(db, zSql); if( rc ) return rc; sqlite3PrepareTimeSet(db->aSchemaTime, SCHEMA_TIME_AFTER_STAT4_PREPARE); while( sqlite3_step(pStmt)==SQLITE_ROW ){ char *zIndex; /* Index name */ Index *pIdx; /* Pointer to the index object */ int nCol = 1; /* Number of columns in index */ u64 t = sqlite3STimeNow(); zIndex = (char *)sqlite3_column_text(pStmt, 0); if( zIndex==0 ) continue; pIdx = findIndexOrPrimaryKey(db, zIndex, zDb); if( pIdx==0 ) continue; if( pIdx->nSample==pIdx->nSampleAlloc ){ u64 t2; pIdx->pTable->tabFlags |= TF_HasStat4; assert( !HasRowid(pIdx->pTable) || pIdx->nColumn==pIdx->nKeyCol+1 ); if( !HasRowid(pIdx->pTable) && IsPrimaryKeyIndex(pIdx) ){ pIdx->nSampleCol = pIdx->nKeyCol; }else{ pIdx->nSampleCol = pIdx->nColumn; } t2 = sqlite3STimeNow(); if( growSampleArray(db, pIdx, 0) ) break; if( db->aSchemaTime ){ db->aSchemaTime[SCHEMA_TIME_STAT4_GROWUS] += (sqlite3STimeNow() - t2); } } if( pIdx!=pPrevIdx ){ initAvgEq(pPrevIdx); pPrevIdx = pIdx; } nCol = pIdx->nSampleCol; pSample = &pIdx->aSample[pIdx->nSample]; decodeIntArray((char*)sqlite3_column_text(pStmt,1),nCol,pSample->anEq,0,0); decodeIntArray((char*)sqlite3_column_text(pStmt,2),nCol,pSample->anLt,0,0); decodeIntArray((char*)sqlite3_column_text(pStmt,3),nCol,pSample->anDLt,0,0); /* Take a copy of the sample. Add 8 extra 0x00 bytes the end of the buffer. ** This is in case the sample record is corrupted. In that case, the |
︙ | ︙ | |||
1895 1896 1897 1898 1899 1900 1901 | sqlite3_finalize(pStmt); return SQLITE_NOMEM_BKPT; } if( pSample->n ){ memcpy(pSample->p, sqlite3_column_blob(pStmt, 4), pSample->n); } pIdx->nSample++; | | > > > > > | 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 | sqlite3_finalize(pStmt); return SQLITE_NOMEM_BKPT; } if( pSample->n ){ memcpy(pSample->p, sqlite3_column_blob(pStmt, 4), pSample->n); } pIdx->nSample++; if( db->aSchemaTime ){ db->aSchemaTime[SCHEMA_TIME_STAT4_Q2_BODYUS] += (sqlite3STimeNow() - t); } } rc = sqlite3_finalize(pStmt); sqlite3PrepareTimeSet(db->aSchemaTime, SCHEMA_TIME_AFTER_STAT4_Q2); if( rc==SQLITE_OK ) initAvgEq(pPrevIdx); return rc; } /* ** Load content from the sqlite_stat4 table into ** the Index.aSample[] arrays of all indices. |
︙ | ︙ | |||
1969 1970 1971 1972 1973 1974 1975 1976 1977 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 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 | Index *pIdx = sqliteHashData(i); pIdx->hasStat1 = 0; #ifdef SQLITE_ENABLE_STAT4 sqlite3DeleteIndexSamples(db, pIdx); pIdx->aSample = 0; #endif } /* Load new statistics out of the sqlite_stat1 table */ sInfo.db = db; sInfo.zDatabase = db->aDb[iDb].zDbSName; if( (pStat1 = sqlite3FindTable(db, "sqlite_stat1", sInfo.zDatabase)) && IsOrdinaryTable(pStat1) ){ zSql = sqlite3MPrintf(db, "SELECT tbl,idx,stat FROM %Q.sqlite_stat1", sInfo.zDatabase); if( zSql==0 ){ rc = SQLITE_NOMEM_BKPT; }else{ rc = sqlite3_exec(db, zSql, analysisLoader, &sInfo, 0); sqlite3DbFree(db, zSql); } } /* Set appropriate defaults on all indexes not in the sqlite_stat1 table */ assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); for(i=sqliteHashFirst(&pSchema->idxHash); i; i=sqliteHashNext(i)){ Index *pIdx = sqliteHashData(i); if( !pIdx->hasStat1 ) sqlite3DefaultRowEst(pIdx); } /* Load the statistics from the sqlite_stat4 table. */ #ifdef SQLITE_ENABLE_STAT4 if( rc==SQLITE_OK ){ DisableLookaside; rc = loadStat4(db, sInfo.zDatabase); EnableLookaside; } for(i=sqliteHashFirst(&pSchema->idxHash); i; i=sqliteHashNext(i)){ Index *pIdx = sqliteHashData(i); sqlite3_free(pIdx->aiRowEst); pIdx->aiRowEst = 0; } #endif if( rc==SQLITE_NOMEM ){ sqlite3OomFault(db); } return rc; } #endif /* SQLITE_OMIT_ANALYZE */ | > > > > > > > > > > > > | 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 | Index *pIdx = sqliteHashData(i); pIdx->hasStat1 = 0; #ifdef SQLITE_ENABLE_STAT4 sqlite3DeleteIndexSamples(db, pIdx); pIdx->aSample = 0; #endif } #ifdef SQLITE_ENABLE_STAT4 sqlite3_free(pSchema->pStat4Space); pSchema->pStat4Space = 0; #endif sqlite3PrepareTimeSet(db->aSchemaTime, SCHEMA_TIME_AFTER_CLEAR_STATS); /* Load new statistics out of the sqlite_stat1 table */ sInfo.db = db; sInfo.zDatabase = db->aDb[iDb].zDbSName; if( (pStat1 = sqlite3FindTable(db, "sqlite_stat1", sInfo.zDatabase)) && IsOrdinaryTable(pStat1) ){ zSql = sqlite3MPrintf(db, "SELECT tbl,idx,stat FROM %Q.sqlite_stat1", sInfo.zDatabase); if( zSql==0 ){ rc = SQLITE_NOMEM_BKPT; }else{ rc = sqlite3_exec(db, zSql, analysisLoader, &sInfo, 0); sqlite3DbFree(db, zSql); } } sqlite3PrepareTimeSet(db->aSchemaTime, SCHEMA_TIME_AFTER_STAT1); /* Set appropriate defaults on all indexes not in the sqlite_stat1 table */ assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); for(i=sqliteHashFirst(&pSchema->idxHash); i; i=sqliteHashNext(i)){ Index *pIdx = sqliteHashData(i); if( !pIdx->hasStat1 ) sqlite3DefaultRowEst(pIdx); } sqlite3PrepareTimeSet(db->aSchemaTime, SCHEMA_TIME_AFTER_DEFAULTS); /* Load the statistics from the sqlite_stat4 table. */ #ifdef SQLITE_ENABLE_STAT4 if( rc==SQLITE_OK ){ DisableLookaside; rc = loadStat4(db, sInfo.zDatabase); EnableLookaside; } for(i=sqliteHashFirst(&pSchema->idxHash); i; i=sqliteHashNext(i)){ Index *pIdx = sqliteHashData(i); sqlite3_free(pIdx->aiRowEst); pIdx->aiRowEst = 0; } #endif sqlite3PrepareTimeSet(db->aSchemaTime, SCHEMA_TIME_AFTER_STAT4); if( rc==SQLITE_NOMEM ){ sqlite3OomFault(db); } return rc; } #endif /* SQLITE_OMIT_ANALYZE */ |
Changes to src/btree.c.
︙ | ︙ | |||
3224 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 | ** cache is allowed to grow larger than this limit if it contains ** dirty pages or pages still in active use. */ int sqlite3BtreeSetCacheSize(Btree *p, int mxPage){ BtShared *pBt = p->pBt; assert( sqlite3_mutex_held(p->db->mutex) ); sqlite3BtreeEnter(p); sqlite3PagerSetCachesize(pBt->pPager, mxPage); sqlite3BtreeLeave(p); return SQLITE_OK; } /* ** Change the "spill" limit on the number of pages in the cache. ** If the number of pages exceeds this limit during a write transaction, | > > | 3224 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 | ** cache is allowed to grow larger than this limit if it contains ** dirty pages or pages still in active use. */ int sqlite3BtreeSetCacheSize(Btree *p, int mxPage){ BtShared *pBt = p->pBt; assert( sqlite3_mutex_held(p->db->mutex) ); sqlite3BtreeEnter(p); sqlite3PrepareTimeSet(p->db->aPrepareTime, PREPARE_TIME_BEGINSETCACHESIZE); sqlite3PagerSetCachesize(pBt->pPager, mxPage); sqlite3PrepareTimeSet(p->db->aPrepareTime, PREPARE_TIME_ENDSETCACHESIZE); sqlite3BtreeLeave(p); return SQLITE_OK; } /* ** Change the "spill" limit on the number of pages in the cache. ** If the number of pages exceeds this limit during a write transaction, |
︙ | ︙ | |||
4551 4552 4553 4554 4555 4556 4557 4558 4559 4560 4561 4562 4563 4564 4565 4566 4567 4568 4569 4570 4571 | PtrmapEntry *pEntry; /* Pointer map entry for page iPg */ if( iPg==PENDING_BYTE_PAGE(pBt) ) continue; pEntry = &pMap->aPtr[iPg - pMap->iFirst]; if( pEntry->eType==PTRMAP_FREEPAGE ){ Pgno dummy; rc = allocateBtreePage(pBt, &pFree, &dummy, iPg, BTALLOC_EXACT); if( pFree ){ assert( sqlite3PagerPageRefcount(pFree->pDbPage)==1 ); sqlite3PcacheDrop(pFree->pDbPage); } assert( rc!=SQLITE_OK || dummy==iPg ); }else if( pnCurrent ){ btreeGetPage(pBt, iPg, &pPg, 0); assert( sqlite3PagerIswriteable(pPg->pDbPage) ); assert( sqlite3PagerPageRefcount(pPg->pDbPage)==1 ); iNew = ++(*pnCurrent); if( iNew==PENDING_BYTE_PAGE(pBt) ) iNew = ++(*pnCurrent); rc = relocatePage(pBt, pPg, pEntry->eType, pEntry->parent, iNew, 1); releasePageNotNull(pPg); | > > > > > > > > > > > > > | > > > > | > > > > > > > > > > > > > > > > | 4553 4554 4555 4556 4557 4558 4559 4560 4561 4562 4563 4564 4565 4566 4567 4568 4569 4570 4571 4572 4573 4574 4575 4576 4577 4578 4579 4580 4581 4582 4583 4584 4585 4586 4587 4588 4589 4590 4591 4592 4593 4594 4595 4596 4597 4598 4599 4600 4601 4602 4603 4604 4605 4606 4607 4608 4609 4610 4611 4612 4613 4614 4615 4616 4617 4618 4619 4620 | PtrmapEntry *pEntry; /* Pointer map entry for page iPg */ if( iPg==PENDING_BYTE_PAGE(pBt) ) continue; pEntry = &pMap->aPtr[iPg - pMap->iFirst]; if( pEntry->eType==PTRMAP_FREEPAGE ){ Pgno dummy; u64 t1; if( pBt->aCommitTime ) t1 = sqlite3STimeNow(); rc = allocateBtreePage(pBt, &pFree, &dummy, iPg, BTALLOC_EXACT); if( pBt->aCommitTime ){ pBt->aCommitTime[COMMIT_TIME_RELOCATE2_EXACTUS] += (sqlite3STimeNow() - t1); } if( pFree ){ assert( sqlite3PagerPageRefcount(pFree->pDbPage)==1 ); sqlite3PcacheDrop(pFree->pDbPage); } assert( rc!=SQLITE_OK || dummy==iPg ); }else if( pnCurrent ){ u64 t1; btreeGetPage(pBt, iPg, &pPg, 0); assert( sqlite3PagerIswriteable(pPg->pDbPage) ); assert( sqlite3PagerPageRefcount(pPg->pDbPage)==1 ); iNew = ++(*pnCurrent); if( iNew==PENDING_BYTE_PAGE(pBt) ) iNew = ++(*pnCurrent); if( pBt->aCommitTime ) t1 = sqlite3STimeNow(); rc = relocatePage(pBt, pPg, pEntry->eType, pEntry->parent, iNew, 1); if( pBt->aCommitTime ){ pBt->aCommitTime[COMMIT_TIME_RELOCATE2_RELOCATEUS] += (sqlite3STimeNow() - t1); } releasePageNotNull(pPg); }else if( pEntry->eType!=0 ){ u64 t1; if( pBt->aCommitTime ) t1 = sqlite3STimeNow(); /* Allocate a new page from the free-list to move page iPg to. ** Except - if the page allocated is within the range being relocated ** (i.e. pgno>=iFirst), then discard it and allocate another. */ do { rc = allocateBtreePage(pBt, &pFree, &iNew, 0, 0); if( iNew>=iFirst ){ assert( sqlite3PagerPageRefcount(pFree->pDbPage)==1 ); assert( iNew>iPg ); sqlite3PcacheDrop(pFree->pDbPage); pMap->aPtr[iNew - pMap->iFirst].eType = 0; pFree = 0; } }while( pFree==0 ); if( pBt->aCommitTime ){ pBt->aCommitTime[COMMIT_TIME_RELOCATE2_ALLOCATEUS] += (sqlite3STimeNow() - t1); } assert( rc!=SQLITE_OK || iNew<iFirst ); if( rc==SQLITE_OK ){ releasePage(pFree); btreeGetPage(pBt, iPg, &pPg, 0); if( pBt->aCommitTime ) t1 = sqlite3STimeNow(); rc = relocatePage(pBt, pPg, pEntry->eType, pEntry->parent,iNew,1); if( pBt->aCommitTime ){ pBt->aCommitTime[COMMIT_TIME_RELOCATE2_RELOCATEUS] += (sqlite3STimeNow() - t1); } releasePage(pPg); } } } return rc; } |
︙ | ︙ | |||
4600 4601 4602 4603 4604 4605 4606 4607 4608 4609 4610 4611 4612 4613 | /* If page 1 of the database is not writable, then no pages were allocated ** or freed by this transaction. In this case no special handling is ** required. Otherwise, if page 1 is dirty, proceed. */ BtreePtrmap *pMap = pBt->pMap; Pgno iTrunk = get4byte(&p1[32]); Pgno nPage = btreePagecount(pBt); u32 nFree = get4byte(&p1[36]); assert( pBt->pMap ); rc = sqlite3PagerUpgradeSnapshot(pPager, pPage1->pDbPage); assert( p1==pPage1->aData ); if( rc==SQLITE_OK ){ Pgno nHPage = get4byte(&p1[28]); | > > | 4635 4636 4637 4638 4639 4640 4641 4642 4643 4644 4645 4646 4647 4648 4649 4650 | /* If page 1 of the database is not writable, then no pages were allocated ** or freed by this transaction. In this case no special handling is ** required. Otherwise, if page 1 is dirty, proceed. */ BtreePtrmap *pMap = pBt->pMap; Pgno iTrunk = get4byte(&p1[32]); Pgno nPage = btreePagecount(pBt); u32 nFree = get4byte(&p1[36]); sqlite3CommitTimeSet(p->pBt->aCommitTime, COMMIT_TIME_START_FIXUNLOCKED); assert( pBt->pMap ); rc = sqlite3PagerUpgradeSnapshot(pPager, pPage1->pDbPage); assert( p1==pPage1->aData ); if( rc==SQLITE_OK ){ Pgno nHPage = get4byte(&p1[28]); |
︙ | ︙ | |||
4647 4648 4649 4650 4651 4652 4653 4654 4655 4656 4657 4658 4659 4660 4661 4662 4663 4664 4665 4666 4667 4668 4669 4670 4671 4672 4673 4674 4675 4676 4677 | ** other transactions have allocated (iFirst..nHPage). So move ** pages (iFirst..MIN(nPage,nHPage)) to (MAX(nPage,nHPage)+1). */ Pgno iLast = MIN(nPage, nHPage); /* Last page to move */ Pgno nCurrent; /* Current size of db */ nCurrent = MAX(nPage, nHPage); pBt->nPage = nCurrent; rc = btreeRelocateRange(pBt, pMap->iFirst, iLast, &nCurrent); /* There are now no collisions with the snapshot at the head of the ** database file. So at this point it would be possible to write ** the transaction out to disk. Before doing so though, attempt to ** relocate some of the new pages to free locations within the body ** of the database file (i.e. free-list entries). */ if( rc==SQLITE_OK ){ assert( nCurrent!=PENDING_BYTE_PAGE(pBt) ); sqlite3PagerSetDbsize(pBt->pPager, nCurrent); nFree = get4byte(&p1[36]); nFin = nCurrent-nFree; if( nCurrent>PENDING_BYTE_PAGE(pBt) && nFin<=PENDING_BYTE_PAGE(pBt) ){ nFin--; } nFin = MAX(nFin, nHPage); rc = btreeRelocateRange(pBt, nFin+1, nCurrent, 0); } put4byte(&p1[28], nFin); } } sqlite3PagerSetDbsize(pPager, nFin); } | > > > > > > > > > > > | 4684 4685 4686 4687 4688 4689 4690 4691 4692 4693 4694 4695 4696 4697 4698 4699 4700 4701 4702 4703 4704 4705 4706 4707 4708 4709 4710 4711 4712 4713 4714 4715 4716 4717 4718 4719 4720 4721 4722 4723 4724 4725 | ** other transactions have allocated (iFirst..nHPage). So move ** pages (iFirst..MIN(nPage,nHPage)) to (MAX(nPage,nHPage)+1). */ Pgno iLast = MIN(nPage, nHPage); /* Last page to move */ Pgno nCurrent; /* Current size of db */ nCurrent = MAX(nPage, nHPage); pBt->nPage = nCurrent; sqlite3CommitTimeSet(p->pBt->aCommitTime, COMMIT_TIME_START_RELOCATE1); rc = btreeRelocateRange(pBt, pMap->iFirst, iLast, &nCurrent); /* There are now no collisions with the snapshot at the head of the ** database file. So at this point it would be possible to write ** the transaction out to disk. Before doing so though, attempt to ** relocate some of the new pages to free locations within the body ** of the database file (i.e. free-list entries). */ if( rc==SQLITE_OK ){ assert( nCurrent!=PENDING_BYTE_PAGE(pBt) ); sqlite3PagerSetDbsize(pBt->pPager, nCurrent); nFree = get4byte(&p1[36]); nFin = nCurrent-nFree; if( nCurrent>PENDING_BYTE_PAGE(pBt) && nFin<=PENDING_BYTE_PAGE(pBt) ){ nFin--; } nFin = MAX(nFin, nHPage); if( p->pBt->aCommitTime ){ p->pBt->aCommitTime[COMMIT_TIME_OTHERWRITERS] = (1+nHPage-pMap->iFirst); p->pBt->aCommitTime[COMMIT_TIME_RELOCATE1COUNT] = (1+iLast-pMap->iFirst); p->pBt->aCommitTime[COMMIT_TIME_RELOCATE2COUNT] = (nCurrent - nFin); } sqlite3CommitTimeSet( p->pBt->aCommitTime, COMMIT_TIME_START_RELOCATE2 ); sqlite3PagerSetCommitTime(pBt->pPager, pBt->aCommitTime); rc = btreeRelocateRange(pBt, nFin+1, nCurrent, 0); sqlite3PagerSetCommitTime(pBt->pPager, 0); } put4byte(&p1[28], nFin); } } sqlite3PagerSetDbsize(pPager, nFin); } |
︙ | ︙ | |||
4728 4729 4730 4731 4732 4733 4734 4735 4736 4737 4738 4739 4740 4741 4742 4743 4744 | } if( pBt->bDoTruncate ){ sqlite3PagerTruncateImage(pBt->pPager, pBt->nPage); } #endif if( rc==SQLITE_OK && ISCONCURRENT && p->db->eConcurrent==CONCURRENT_OPEN ){ rc = btreeFixUnlocked(p); } if( rc==SQLITE_OK ){ rc = sqlite3PagerCommitPhaseOne(pBt->pPager, zSuperJrnl, 0); } #ifndef SQLITE_OMIT_CONCURRENT if( rc==SQLITE_OK ){ u32 iPrev = 0; u32 iCurrent = 0; sqlite3PagerWalInfo(pBt->pPager, &iPrev, &iCurrent); if( (iPrev&0x80000000)!=(iCurrent&0x80000000) ){ | > > > | 4776 4777 4778 4779 4780 4781 4782 4783 4784 4785 4786 4787 4788 4789 4790 4791 4792 4793 4794 4795 | } if( pBt->bDoTruncate ){ sqlite3PagerTruncateImage(pBt->pPager, pBt->nPage); } #endif if( rc==SQLITE_OK && ISCONCURRENT && p->db->eConcurrent==CONCURRENT_OPEN ){ rc = btreeFixUnlocked(p); sqlite3CommitTimeSet(p->pBt->aCommitTime, COMMIT_TIME_AFTER_FIXUNLOCKED); } if( rc==SQLITE_OK ){ sqlite3PagerSetCommitTime(pBt->pPager, p->pBt->aCommitTime); rc = sqlite3PagerCommitPhaseOne(pBt->pPager, zSuperJrnl, 0); sqlite3PagerSetCommitTime(pBt->pPager, 0); } #ifndef SQLITE_OMIT_CONCURRENT if( rc==SQLITE_OK ){ u32 iPrev = 0; u32 iCurrent = 0; sqlite3PagerWalInfo(pBt->pPager, &iPrev, &iCurrent); if( (iPrev&0x80000000)!=(iCurrent&0x80000000) ){ |
︙ | ︙ | |||
4835 4836 4837 4838 4839 4840 4841 4842 4843 4844 4845 4846 4847 4848 4849 | ** transaction and set the shared state to TRANS_READ. */ if( p->inTrans==TRANS_WRITE ){ int rc; BtShared *pBt = p->pBt; assert( pBt->inTransaction==TRANS_WRITE ); assert( pBt->nTransaction>0 ); rc = sqlite3PagerCommitPhaseTwo(pBt->pPager); if( rc!=SQLITE_OK && bCleanup==0 ){ sqlite3BtreeLeave(p); return rc; } p->iBDataVersion--; /* Compensate for pPager->iDataVersion++; */ pBt->inTransaction = TRANS_READ; btreeClearHasContent(pBt); | > > | 4886 4887 4888 4889 4890 4891 4892 4893 4894 4895 4896 4897 4898 4899 4900 4901 4902 | ** transaction and set the shared state to TRANS_READ. */ if( p->inTrans==TRANS_WRITE ){ int rc; BtShared *pBt = p->pBt; assert( pBt->inTransaction==TRANS_WRITE ); assert( pBt->nTransaction>0 ); sqlite3PagerSetCommitTime(pBt->pPager, p->pBt->aCommitTime); rc = sqlite3PagerCommitPhaseTwo(pBt->pPager); sqlite3PagerSetCommitTime(pBt->pPager, 0); if( rc!=SQLITE_OK && bCleanup==0 ){ sqlite3BtreeLeave(p); return rc; } p->iBDataVersion--; /* Compensate for pPager->iDataVersion++; */ pBt->inTransaction = TRANS_READ; btreeClearHasContent(pBt); |
︙ | ︙ |
Changes to src/btreeInt.h.
︙ | ︙ | |||
466 467 468 469 470 471 472 473 474 475 476 477 478 479 | Btree *pWriter; /* Btree with currently open write transaction */ #endif u8 *pTmpSpace; /* Temp space sufficient to hold a single cell */ #ifndef SQLITE_OMIT_CONCURRENT BtreePtrmap *pMap; #endif int nPreformatSize; /* Size of last cell written by TransferRow() */ }; /* ** Allowed values for BtShared.btsFlags */ #define BTS_READ_ONLY 0x0001 /* Underlying file is readonly */ #define BTS_PAGESIZE_FIXED 0x0002 /* Page size can no longer be changed */ | > > | 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 | Btree *pWriter; /* Btree with currently open write transaction */ #endif u8 *pTmpSpace; /* Temp space sufficient to hold a single cell */ #ifndef SQLITE_OMIT_CONCURRENT BtreePtrmap *pMap; #endif int nPreformatSize; /* Size of last cell written by TransferRow() */ u64 *aCommitTime; }; /* ** Allowed values for BtShared.btsFlags */ #define BTS_READ_ONLY 0x0001 /* Underlying file is readonly */ #define BTS_PAGESIZE_FIXED 0x0002 /* Page size can no longer be changed */ |
︙ | ︙ |
Changes to src/build.c.
︙ | ︙ | |||
5791 5792 5793 5794 5795 5796 5797 5798 | } sqlite3DbFree(db, pWith); } } void sqlite3WithDeleteGeneric(sqlite3 *db, void *pWith){ sqlite3WithDelete(db, (With*)pWith); } #endif /* !defined(SQLITE_OMIT_CTE) */ | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 5791 5792 5793 5794 5795 5796 5797 5798 5799 5800 5801 5802 5803 5804 5805 5806 5807 5808 5809 5810 5811 5812 5813 5814 5815 5816 5817 5818 5819 5820 5821 5822 5823 5824 5825 5826 5827 5828 5829 5830 5831 5832 5833 5834 5835 5836 5837 5838 5839 5840 5841 5842 5843 5844 5845 5846 5847 5848 5849 5850 5851 5852 5853 5854 5855 5856 5857 5858 5859 5860 5861 5862 5863 5864 5865 5866 5867 5868 5869 5870 5871 5872 5873 5874 5875 5876 5877 5878 5879 5880 5881 5882 5883 5884 5885 5886 5887 5888 5889 5890 5891 5892 5893 5894 5895 5896 5897 5898 5899 5900 5901 5902 5903 5904 5905 5906 5907 5908 5909 5910 5911 5912 5913 5914 5915 5916 5917 5918 5919 5920 5921 5922 5923 5924 5925 5926 5927 5928 5929 5930 5931 5932 5933 5934 5935 5936 5937 5938 5939 5940 5941 5942 5943 5944 5945 5946 5947 5948 5949 5950 5951 5952 5953 5954 5955 5956 5957 5958 5959 5960 5961 5962 5963 5964 5965 5966 5967 5968 5969 5970 5971 5972 5973 5974 5975 5976 5977 5978 5979 5980 5981 5982 5983 5984 5985 5986 5987 5988 5989 5990 5991 5992 5993 5994 5995 5996 5997 5998 5999 6000 6001 6002 6003 6004 6005 6006 6007 6008 6009 6010 6011 6012 6013 6014 6015 6016 6017 6018 6019 6020 6021 6022 6023 6024 6025 6026 6027 6028 6029 6030 6031 6032 6033 6034 6035 6036 6037 6038 6039 6040 6041 6042 6043 6044 6045 6046 6047 6048 6049 6050 6051 6052 6053 6054 6055 6056 6057 6058 6059 6060 6061 6062 6063 6064 6065 6066 6067 6068 6069 6070 6071 6072 6073 6074 6075 6076 6077 6078 6079 6080 6081 6082 6083 6084 6085 6086 6087 6088 6089 6090 6091 6092 6093 6094 6095 6096 6097 6098 6099 6100 6101 6102 6103 6104 6105 6106 6107 6108 6109 6110 6111 6112 6113 6114 6115 6116 6117 6118 6119 6120 6121 6122 6123 6124 6125 6126 6127 6128 6129 6130 6131 6132 6133 6134 6135 6136 6137 6138 6139 6140 6141 6142 6143 6144 6145 6146 6147 6148 6149 6150 6151 6152 6153 6154 6155 6156 6157 6158 6159 6160 6161 6162 6163 6164 6165 6166 6167 6168 6169 6170 6171 6172 6173 6174 6175 6176 6177 6178 6179 6180 6181 6182 6183 6184 6185 6186 6187 6188 6189 6190 6191 6192 6193 6194 6195 6196 6197 6198 6199 6200 6201 6202 6203 6204 6205 6206 6207 6208 6209 6210 6211 6212 6213 6214 6215 6216 6217 6218 6219 6220 6221 6222 6223 6224 6225 6226 6227 6228 6229 6230 6231 6232 6233 6234 6235 6236 6237 6238 6239 6240 6241 6242 6243 6244 6245 6246 6247 6248 6249 6250 6251 6252 6253 6254 6255 6256 6257 6258 6259 6260 6261 6262 6263 6264 6265 6266 6267 6268 6269 6270 6271 6272 6273 6274 6275 6276 6277 6278 6279 6280 6281 6282 6283 6284 6285 6286 6287 6288 6289 | } sqlite3DbFree(db, pWith); } } void sqlite3WithDeleteGeneric(sqlite3 *db, void *pWith){ sqlite3WithDelete(db, (With*)pWith); } /* ** Type passed as context to expression walker callback schemaCopyExprCb(). */ struct TwoTable { Table *pNew; Table *pOld; }; /* ** This is used as an expression walker callback. It takes a TwoTable ** structure as context. Any TK_COLUMN node that points to TwoTable.pOld ** is adjusted to point to TwoTable.pNew. */ static int schemaCopyExprCb(Walker *p, Expr *pExpr){ struct TwoTable *pT = (struct TwoTable*)p->u.pSchema; if( pExpr->op==TK_COLUMN && pExpr->y.pTab==pT->pOld ){ pExpr->y.pTab = pT->pNew; } return WRC_Continue; } /* ** Set up the Walker passed as the first argument to call schemaCopyExprCb() ** with the TwoTable object indicated by the second argument as context. This ** configuration will modify all TK_COLUMN nodes that point to pT->pOld ** to point to pT->pNew instead. */ static void schemaCopyExprWalker(Walker *p, struct TwoTable *pT){ memset(p, 0, sizeof(*p)); p->xExprCallback = schemaCopyExprCb; p->xSelectCallback = sqlite3SelectWalkNoop; p->u.pSchema = (Schema*)pT; } /* ** Argument pList points to a list of Index object linked by Index.pNext. ** This function returns a copy of this list. ** ** All elements of the returned list have Index.pTable set to pTab, and ** are set to be part of the same schema as pTab. Additionally, an entry ** is inserted into pTab->pSchema->idxHash for each index in the returned ** list. ** ** db->mallocFailed is left set if an OOM error is encountered. */ static Index *schemaCopyIndexList(sqlite3 *db, Table *pTab, Index *pList){ Schema *pSchema = pTab->pSchema; Index *pRet = 0; Index *p = 0; Index **ppNew = &pRet; for(p=pList; p; p=p->pNext){ Index *pNew = 0; int nName = sqlite3Strlen30(p->zName) + 1; int nExtra = 0; char *zExtra = 0; int ii; for(ii=0; ii<p->nColumn; ii++){ if( p->azColl[ii]!=sqlite3StrBINARY ){ nExtra += sqlite3Strlen30(p->azColl[ii]) + 1; } } pNew = sqlite3AllocateIndexObject(db, p->nColumn, nName+nExtra, &zExtra); if( pNew ){ struct TwoTable twotable; Walker sExprWalker; pNew->zName = zExtra; memcpy(pNew->zName, p->zName, nName); zExtra += nName; memcpy(pNew->aiColumn, p->aiColumn, sizeof(i16) * p->nColumn); memcpy(pNew->aiRowLogEst, p->aiRowLogEst, sizeof(LogEst)*(p->nColumn+1)); pNew->pTable = pTab; pNew->zColAff = 0; pNew->pSchema = pSchema; memcpy(pNew->aSortOrder, p->aSortOrder, p->nColumn); for(ii=0; ii<p->nColumn; ii++){ char *zColl = 0; if( p->azColl[ii]!=sqlite3StrBINARY ){ int nColl = sqlite3Strlen30(p->azColl[ii]) + 1; memcpy(zExtra, p->azColl[ii], nColl); zColl = zExtra; zExtra += nColl; }else{ zColl = (char*)sqlite3StrBINARY; } pNew->azColl[ii] = zColl; } pNew->pPartIdxWhere = sqlite3ExprDup(db, p->pPartIdxWhere, 0); twotable.pNew = pTab; twotable.pOld = p->pTable; schemaCopyExprWalker(&sExprWalker, &twotable); sqlite3WalkExpr(&sExprWalker, pNew->pPartIdxWhere); pNew->aColExpr = sqlite3ExprListDup(db, p->aColExpr, 0); sqlite3WalkExprList(&sExprWalker, pNew->aColExpr); pNew->tnum = p->tnum; pNew->szIdxRow = p->szIdxRow; memcpy(&pNew->nKeyCol,&p->nKeyCol,sizeof(Index)-offsetof(Index, nKeyCol)); pNew->isResized = 0; #ifdef SQLITE_ENABLE_STAT4 assert( pNew->aiRowEst==0 && p->aiRowEst==0 ); pNew->aAvgEq = 0; pNew->aSample = 0; pNew->nSample = 0; pNew->nSampleAlloc = 0; sqlite3AnalyzeCopyStat4(db, pNew, p); #endif if( sqlite3HashInsert(&pSchema->idxHash, pNew->zName, pNew) ){ sqlite3OomFault(db); } *ppNew = pNew; ppNew = &pNew->pNext; } } return pRet; } /* ** Update any elements of pSrc with the fixedSchema flag set to use ** schema pSchema. */ static void schemaCopyRefixSrclist(Schema *pSchema, SrcList *pSrc){ if( pSrc ){ int ii; for(ii=0; ii<pSrc->nSrc; ii++){ if( pSrc->a[ii].fg.fixedSchema ){ pSrc->a[ii].u4.pSchema = pSchema; } } } } /* ** Walker callback to call schemaCopyRefixSrclist(). */ static int schemaCopySelectCb(Walker *pWalker, Select *pSelect){ schemaCopyRefixSrclist(pWalker->u.pSchema, pSelect->pSrc); return WRC_Continue; } /* ** Set up the walker object passed as the first argument so that it ** calls schemaCopyRefixSrclist() on any SrcList it visits with pSchema ** as the first argument. */ static void schemaRefixWalker(Walker *pWalker, Schema *pSchema){ memset(pWalker, 0, sizeof(Walker)); pWalker->xSelectCallback = schemaCopySelectCb; pWalker->xExprCallback = sqlite3ExprWalkNoop; pWalker->u.pSchema = pSchema; } /* ** Make a copy of the list of trigger-steps in pList and return a pointer ** to it. Set each trigger-step in the returned list to belong to trigger ** pTrig, and also fix any embedded SrcList objects to schema pTrig->pSchema. ** ** db->mallocFailed is left set if an OOM error is encountered. */ static TriggerStep *schemaCopyTriggerStepList( sqlite3 *db, /* Database handle */ Trigger *pTrig, /* Trigger that will own returned list */ TriggerStep *pList /* List of trigger steps to copy */ ){ TriggerStep *pRet = 0; TriggerStep *p = 0; TriggerStep **ppNew = &pRet; for(p=pList; p; p=p->pNext){ int nTarget = sqlite3Strlen30(p->zTarget) + 1; int nAlloc = sizeof(TriggerStep) + nTarget; TriggerStep *pNew = (TriggerStep*)sqlite3DbMallocZero(db, nAlloc); if( pNew ){ pNew->op = p->op; pNew->orconf = p->orconf; pNew->pTrig = pTrig; pNew->pSelect = sqlite3SelectDup(db, p->pSelect, 0); if( p->zTarget ){ pNew->zTarget = (char*)&pNew[1]; memcpy(pNew->zTarget, p->zTarget, nTarget); } pNew->pFrom = sqlite3SrcListDup(db, p->pFrom, 0); schemaCopyRefixSrclist(pTrig->pSchema, pNew->pFrom); pNew->pWhere = sqlite3ExprDup(db, p->pWhere, 0); pNew->pExprList = sqlite3ExprListDup(db, p->pExprList, 0); pNew->pIdList = sqlite3IdListDup(db, p->pIdList); pNew->pUpsert = sqlite3UpsertDup(db, p->pUpsert); assert( pNew->pUpsert==0 || pNew->pUpsert->pUpsertSrc==0 ); pNew->zSpan = sqlite3DbStrDup(db, p->zSpan); *ppNew = pNew; ppNew = &pNew->pNext; if( pRet ){ pRet->pLast = pNew; } } } return pRet; } /* ** Make a copy of the list of triggers in pList and return a pointer ** to it. Set each of the triggers in the returned list to belong to table ** pTab, and also fix any embedded SrcList objects to schema pTab->pSchema. ** ** An entry is added to hash table pTab->pSchema->trigHash for each trigger ** in the returned list. ** ** db->mallocFailed is left set if an OOM error is encountered. */ static Trigger *schemaCopyTriggerList(sqlite3 *db, Table *pTab, Trigger *pList){ Walker sWalker; Schema *pSchema = pTab->pSchema; Trigger *pRet = 0; Trigger *p = 0; Trigger **ppNew = &pRet; schemaRefixWalker(&sWalker, pSchema); for(p=pList; p; p=p->pNext){ Trigger *pNew = sqlite3DbMallocZero(db, sizeof(Trigger)); if( pNew ){ memcpy(pNew, p, sizeof(Trigger)); pNew->zName = sqlite3DbStrDup(db, pNew->zName); pNew->table = sqlite3DbStrDup(db, pNew->table); pNew->pWhen = sqlite3ExprDup(db, pNew->pWhen, 0); pNew->pColumns = sqlite3IdListDup(db, pNew->pColumns); pNew->pSchema = pTab->pSchema; pNew->pTabSchema = pTab->pSchema; pNew->step_list = schemaCopyTriggerStepList(db, pNew, pNew->step_list); if( sqlite3HashInsert(&pSchema->trigHash, pNew->zName, pNew) ){ sqlite3OomFault(db); } sqlite3WalkTrigger(&sWalker, pNew); *ppNew = pNew; ppNew = &pNew->pNext; } } return pRet; } /* ** Make a copy of the list of FKey objects in pList and return a pointer ** to it. Set each of the FKey objects in the returned list to belong to ** table pTab. ** ** An entry is added to hash table pTab->pSchema->fkeyHash for each trigger ** in the returned list. ** ** db->mallocFailed is left set if an OOM error is encountered. */ static FKey *schemaCopyFKeyList(sqlite3 *db, Table *pTab, FKey *pList){ Schema *pSchema = pTab->pSchema; FKey *pRet = 0; FKey *p = 0; FKey **ppNew = &pRet; for(p=pList; p; p=p->pNextFrom){ FKey *pNew = 0; int nByte = sizeof(FKey) + ((p->nCol - 1) * sizeof(struct sColMap)); int ii; nByte += sqlite3Strlen30(p->zTo) + 1; for(ii=0; ii<p->nCol; ii++){ nByte += sqlite3Strlen30(p->aCol[ii].zCol) + 1; } pNew = (FKey*)sqlite3DbMallocZero(db, nByte); if( pNew ){ FKey *pNextTo = 0; char *z = (char*)&pNew->aCol[p->nCol]; int n = 0; pNew->pFrom = pTab; n = sqlite3Strlen30(p->zTo) + 1; pNew->zTo = z; memcpy(pNew->zTo, p->zTo, n); z += n; pNew->nCol = p->nCol; pNew->isDeferred = p->isDeferred; pNew->aAction[0] = p->aAction[0]; pNew->aAction[1] = p->aAction[1]; for(ii=0; ii<p->nCol; ii++){ pNew->aCol[ii].iFrom = p->aCol[ii].iFrom; if( p->aCol[ii].zCol ){ n = sqlite3Strlen30(p->aCol[ii].zCol) + 1; pNew->aCol[ii].zCol = z; memcpy(z, p->aCol[ii].zCol, n); z += n; } } pNextTo = (FKey*)sqlite3HashInsert(&pSchema->fkeyHash, pNew->zTo, pNew); if( pNextTo==pNew ){ sqlite3OomFault(db); }else if( pNextTo ){ assert( pNextTo->pPrevTo==0 ); pNew->pNextTo = pNextTo; pNextTo->pPrevTo = pNew; } *ppNew = pNew; ppNew = &pNew->pNextFrom; } } return pRet; } /* ** Make a copy of the table object passed as the 3rd argument. The copy ** should be made part of schema pTo. The new table object is added to hash ** table pTo->tblHash before returning. ** ** db->mallocFailed is left set if an OOM error is encountered. */ static void schemaCopyTable(sqlite3 *db, Schema *pTo, Table *pTab){ Table *pNew = 0; pNew = (Table*)sqlite3DbMallocRawNN(db, sizeof(Table)); if( pNew ){ Walker sExprWalker; struct TwoTable twotable; memcpy(pNew, pTab, sizeof(Table)); pNew->zName = sqlite3DbStrDup(db, pNew->zName); assert( pNew->nCol>0 || pNew->eTabType!=TABTYP_NORM ); if( pNew->nCol>0 ){ pNew->aCol = sqlite3DbMallocRawNN(db, pNew->nCol*sizeof(Column)); } pNew->nTabRef = 1; if( pNew->aCol ){ int ii; memcpy(pNew->aCol, pTab->aCol, pNew->nCol*sizeof(Column)); for(ii=0; ii<pNew->nCol; ii++){ Column *pCol = &pNew->aCol[ii]; const char *zCopy = pCol->zCnName; int nCopy = sqlite3Strlen30(zCopy); if( pCol->colFlags & COLFLAG_HASTYPE ){ nCopy++; nCopy += sqlite3Strlen30(&zCopy[nCopy]); } if( pCol->colFlags & COLFLAG_HASCOLL ){ nCopy++; nCopy += sqlite3Strlen30(&zCopy[nCopy]); } pCol->zCnName = sqlite3DbStrNDup(db, zCopy, nCopy); } } pNew->pSchema = pTo; pNew->pIndex = schemaCopyIndexList(db, pNew, pNew->pIndex); pNew->zColAff = 0; pNew->pCheck = sqlite3ExprListDup(db, pTab->pCheck, 0); twotable.pNew = pNew; twotable.pOld = pTab; schemaCopyExprWalker(&sExprWalker, &twotable); sqlite3WalkExprList(&sExprWalker, pNew->pCheck); if( IsView(pNew) ){ Walker sWalker; pNew->u.view.pSelect = sqlite3SelectDup(db, pNew->u.view.pSelect, 0); schemaRefixWalker(&sWalker, pTo); sqlite3WalkSelect(&sWalker, pNew->u.view.pSelect); }else if( IsVirtual(pNew) ){ int nAlloc = pNew->u.vtab.nArg * sizeof(char*); pNew->u.vtab.p = 0; pNew->u.vtab.azArg = (char**)sqlite3DbMallocRaw(db, nAlloc); if( pNew->u.vtab.azArg ){ int ii; for(ii=0; ii<pNew->u.vtab.nArg; ii++){ pNew->u.vtab.azArg[ii] = sqlite3DbStrDup(db, pTab->u.vtab.azArg[ii]); } } }else{ pNew->u.tab.pDfltList = sqlite3ExprListDup(db, pNew->u.tab.pDfltList, 0); sqlite3WalkExprList(&sExprWalker, pNew->u.tab.pDfltList); pNew->u.tab.pFKey = schemaCopyFKeyList(db, pNew, pNew->u.tab.pFKey); } pNew->pTrigger = schemaCopyTriggerList(db, pNew, pNew->pTrigger); } if( db->mallocFailed==0 ){ if( sqlite3HashInsert(&pTo->tblHash, pNew->zName, pNew) ){ sqlite3OomFault(db); } #ifndef SQLITE_OMIT_AUTOINCREMENT if( pTab->pSchema->pSeqTab==pTab ){ pTo->pSeqTab = pNew; } #endif } if( db->mallocFailed ){ sqlite3DeleteTable(db, pNew); } } /* ** Copy the contents of schema object pFrom to schema object pTo. ** ** db->mallocFailed is left set if an OOM error is encountered. */ void sqlite3SchemaCopy(sqlite3 *db, Schema *pTo, Schema *pFrom){ HashElem *k = 0; DisableLookaside; pTo->schema_cookie = pFrom->schema_cookie; pTo->iGeneration = pFrom->iGeneration; pTo->file_format = pFrom->file_format; pTo->enc = pFrom->enc; pTo->cache_size = pFrom->cache_size; pTo->schemaFlags = pFrom->schemaFlags; #ifdef SQLITE_ENABLE_STAT4 if( pFrom->pStat4Space && pFrom->nStat4Space>0 ){ pTo->pStat4Space = sqlite3_malloc(pFrom->nStat4Space); if( pTo->pStat4Space==0 ){ sqlite3OomFault(db); } pTo->nStat4Space = 0; } #endif /* Iterate through the tables in the pFrom schema in reverse order. This ** ensures that they end up stored in the pTo hash table in the same order ** as in pFrom. Which make the results of some test cases more consistent. */ k = sqliteHashFirst(&pFrom->tblHash); if( k ){ while( k->next ) k = k->next; for(/* no-op */; k; k=k->prev){ Table *pTab = (Table*)sqliteHashData(k); schemaCopyTable(db, pTo, pTab); } } EnableLookaside; } /* ** Copy the contents of the schema from database handle db, database zTo, ** to database zFrom of handle dbFrom. ** ** Return SQLITE_OK if successful, or SQLITE_NOMEM if an OOM error is ** encountered. */ int sqlite3_schema_copy( sqlite3 *db, const char *zTo, /* Target schema */ sqlite3 *dbFrom, const char *zFrom /* Source schema */ ){ int iTo = 0; int iFrom = 0; Schema *pTo = 0; Schema *pFrom = 0; int rc = SQLITE_OK; u64 t = sqlite3STimeNow(); sqlite3_mutex_enter(db->mutex); sqlite3BtreeEnterAll(db); if( zTo ) iTo = sqlite3FindDbName(db, zTo); if( zFrom ) iFrom = sqlite3FindDbName(dbFrom, zFrom); if( iFrom<0 || iTo<0 ){ rc = SQLITE_ERROR; goto schema_copy_done; } if( !DbHasProperty(dbFrom, iFrom, DB_SchemaLoaded) || DbHasProperty(db, iTo, DB_SchemaLoaded) ){ goto schema_copy_done; } pTo = db->aDb[iTo].pSchema; pFrom = dbFrom->aDb[iFrom].pSchema; assert( pTo && pFrom ); sqlite3SchemaCopy(db, pTo, pFrom); t = sqlite3STimeNow() - t; if( t>500000 ){ sqlite3_log(SQLITE_WARNING, "slow schemacopy (v=22): (%lld)", t); } schema_copy_done: sqlite3BtreeLeaveAll(db); rc = sqlite3ApiExit(db, rc); sqlite3_mutex_leave(db->mutex); return rc; } #endif /* !defined(SQLITE_OMIT_CTE) */ |
Changes to src/callback.c.
︙ | ︙ | |||
510 511 512 513 514 515 516 517 518 519 520 521 522 523 | sqlite3HashClear(&temp1); sqlite3HashClear(&pSchema->fkeyHash); pSchema->pSeqTab = 0; if( pSchema->schemaFlags & DB_SchemaLoaded ){ pSchema->iGeneration++; } pSchema->schemaFlags &= ~(DB_SchemaLoaded|DB_ResetWanted); } /* ** Find and return the schema associated with a BTree. Create ** a new one if necessary. */ Schema *sqlite3SchemaGet(sqlite3 *db, Btree *pBt){ | > > > > | 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 | sqlite3HashClear(&temp1); sqlite3HashClear(&pSchema->fkeyHash); pSchema->pSeqTab = 0; if( pSchema->schemaFlags & DB_SchemaLoaded ){ pSchema->iGeneration++; } pSchema->schemaFlags &= ~(DB_SchemaLoaded|DB_ResetWanted); #ifdef SQLITE_ENABLE_STAT4 sqlite3_free(pSchema->pStat4Space); pSchema->pStat4Space = 0; #endif } /* ** Find and return the schema associated with a BTree. Create ** a new one if necessary. */ Schema *sqlite3SchemaGet(sqlite3 *db, Btree *pBt){ |
︙ | ︙ |
Changes to src/expr.c.
︙ | ︙ | |||
475 476 477 478 479 480 481 | p4 = sqlite3BinaryCompareCollSeq(pParse, pRight, pLeft); }else{ p4 = sqlite3BinaryCompareCollSeq(pParse, pLeft, pRight); } p5 = binaryCompareP5(pLeft, pRight, jumpIfNull); addr = sqlite3VdbeAddOp4(pParse->pVdbe, opcode, in2, dest, in1, (void*)p4, P4_COLLSEQ); | | | 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 | p4 = sqlite3BinaryCompareCollSeq(pParse, pRight, pLeft); }else{ p4 = sqlite3BinaryCompareCollSeq(pParse, pLeft, pRight); } p5 = binaryCompareP5(pLeft, pRight, jumpIfNull); addr = sqlite3VdbeAddOp4(pParse->pVdbe, opcode, in2, dest, in1, (void*)p4, P4_COLLSEQ); sqlite3VdbeChangeP5(pParse->pVdbe, (u16)p5); return addr; } /* ** Return true if expression pExpr is a vector, or false otherwise. ** ** A vector is defined as any expression that results in two or more |
︙ | ︙ |
Changes to src/global.c.
︙ | ︙ | |||
293 294 295 296 297 298 299 300 301 302 303 304 305 306 | 0, /* mNoVisibleRowid. 0 == allow rowid-in-view */ #endif 0, /* bLocaltimeFault */ 0, /* xAltLocaltime */ 0x7ffffffe, /* iOnceResetThreshold */ SQLITE_DEFAULT_SORTERREF_SIZE, /* szSorterRef */ 0, /* iPrngSeed */ #ifdef SQLITE_DEBUG {0,0,0,0,0,0}, /* aTune */ #endif }; /* ** Hash table for global functions - functions common to all | > | 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 | 0, /* mNoVisibleRowid. 0 == allow rowid-in-view */ #endif 0, /* bLocaltimeFault */ 0, /* xAltLocaltime */ 0x7ffffffe, /* iOnceResetThreshold */ SQLITE_DEFAULT_SORTERREF_SIZE, /* szSorterRef */ 0, /* iPrngSeed */ 0, /* bTestSchemaCopy */ #ifdef SQLITE_DEBUG {0,0,0,0,0,0}, /* aTune */ #endif }; /* ** Hash table for global functions - functions common to all |
︙ | ︙ |
Changes to src/legacy.c.
︙ | ︙ | |||
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 | sqlite3_mutex_enter(db->mutex); sqlite3Error(db, SQLITE_OK); while( rc==SQLITE_OK && zSql[0] ){ int nCol = 0; char **azVals = 0; pStmt = 0; rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover); assert( rc==SQLITE_OK || pStmt==0 ); if( rc!=SQLITE_OK ){ continue; } if( !pStmt ){ /* this happens for a comment or white-space */ zSql = zLeftover; continue; } callbackIsInit = 0; while( 1 ){ int i; rc = sqlite3_step(pStmt); /* Invoke the callback function if required */ if( xCallback && (SQLITE_ROW==rc || (SQLITE_DONE==rc && !callbackIsInit | > > | 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 | sqlite3_mutex_enter(db->mutex); sqlite3Error(db, SQLITE_OK); while( rc==SQLITE_OK && zSql[0] ){ int nCol = 0; char **azVals = 0; sqlite3PrepareTimeSet(db->aSchemaTime, SCHEMA_TIME_BEFORE_PREPARE); pStmt = 0; rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover); assert( rc==SQLITE_OK || pStmt==0 ); if( rc!=SQLITE_OK ){ continue; } if( !pStmt ){ /* this happens for a comment or white-space */ zSql = zLeftover; continue; } callbackIsInit = 0; sqlite3PrepareTimeSet(db->aSchemaTime, SCHEMA_TIME_BEFORE_STEP); while( 1 ){ int i; rc = sqlite3_step(pStmt); /* Invoke the callback function if required */ if( xCallback && (SQLITE_ROW==rc || (SQLITE_DONE==rc && !callbackIsInit |
︙ | ︙ | |||
103 104 105 106 107 108 109 110 111 112 113 114 115 116 | sqlite3VdbeFinalize((Vdbe *)pStmt); pStmt = 0; sqlite3Error(db, SQLITE_ABORT); goto exec_out; } } if( rc!=SQLITE_ROW ){ rc = sqlite3VdbeFinalize((Vdbe *)pStmt); pStmt = 0; zSql = zLeftover; while( sqlite3Isspace(zSql[0]) ) zSql++; break; } | > | 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 | sqlite3VdbeFinalize((Vdbe *)pStmt); pStmt = 0; sqlite3Error(db, SQLITE_ABORT); goto exec_out; } } sqlite3PrepareTimeSet(db->aSchemaTime, SCHEMA_TIME_BEFORE_FINALIZE); if( rc!=SQLITE_ROW ){ rc = sqlite3VdbeFinalize((Vdbe *)pStmt); pStmt = 0; zSql = zLeftover; while( sqlite3Isspace(zSql[0]) ) zSql++; break; } |
︙ | ︙ |
Changes to src/main.c.
︙ | ︙ | |||
2890 2891 2892 2893 2894 2895 2896 | #endif #if SQLITE_MAX_COMPOUND_SELECT<2 # error SQLITE_MAX_COMPOUND_SELECT must be at least 2 #endif #if SQLITE_MAX_VDBE_OP<40 # error SQLITE_MAX_VDBE_OP must be at least 40 #endif | | | | 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 | #endif #if SQLITE_MAX_COMPOUND_SELECT<2 # error SQLITE_MAX_COMPOUND_SELECT must be at least 2 #endif #if SQLITE_MAX_VDBE_OP<40 # error SQLITE_MAX_VDBE_OP must be at least 40 #endif #if SQLITE_MAX_FUNCTION_ARG<0 || SQLITE_MAX_FUNCTION_ARG>32767 # error SQLITE_MAX_FUNCTION_ARG must be between 0 and 32767 #endif #if SQLITE_MAX_ATTACHED<0 || SQLITE_MAX_ATTACHED>125 # error SQLITE_MAX_ATTACHED must be between 0 and 125 #endif #if SQLITE_MAX_LIKE_PATTERN_LENGTH<1 # error SQLITE_MAX_LIKE_PATTERN_LENGTH must be at least 1 #endif |
︙ | ︙ | |||
4632 4633 4634 4635 4636 4637 4638 4639 4640 4641 4642 4643 4644 4645 | u64 *pU64 = va_arg(ap,u64*); int *pI2 = va_arg(ap,int*); *pI1 = rLogEst; *pU64 = sqlite3LogEstToInt(rLogEst); *pI2 = sqlite3LogEst(*pU64); break; } #if !defined(SQLITE_OMIT_WSD) /* sqlite3_test_control(SQLITE_TESTCTRL_USELONGDOUBLE, int X); ** ** X<0 Make no changes to the bUseLongDouble. Just report value. ** X==0 Disable bUseLongDouble ** X==1 Enable bUseLongDouble | > > > > > > > > > > > > | 4632 4633 4634 4635 4636 4637 4638 4639 4640 4641 4642 4643 4644 4645 4646 4647 4648 4649 4650 4651 4652 4653 4654 4655 4656 4657 | u64 *pU64 = va_arg(ap,u64*); int *pI2 = va_arg(ap,int*); *pI1 = rLogEst; *pU64 = sqlite3LogEstToInt(rLogEst); *pI2 = sqlite3LogEst(*pU64); break; } /* sqlite3_test_control(SQLITE_TESTCTRL_SCHEMACOPY, int X); ** ** X==0 Disable test sqlite3_schema_copy() ** X==1 Enable test sqlite3_schema_copy() */ case SQLITE_TESTCTRL_SCHEMACOPY: { int b = va_arg(ap, int); if( b>=0 ) sqlite3Config.bTestSchemaCopy = b>0; rc = sqlite3Config.bTestSchemaCopy!=0; break; } #if !defined(SQLITE_OMIT_WSD) /* sqlite3_test_control(SQLITE_TESTCTRL_USELONGDOUBLE, int X); ** ** X<0 Make no changes to the bUseLongDouble. Just report value. ** X==0 Disable bUseLongDouble ** X==1 Enable bUseLongDouble |
︙ | ︙ |
Changes to src/pager.c.
︙ | ︙ | |||
699 700 701 702 703 704 705 706 707 708 709 710 711 712 | int (*xGet)(Pager*,Pgno,DbPage**,int); /* Routine to fetch a patch */ char *pTmpSpace; /* Pager.pageSize bytes of space for tmp use */ PCache *pPCache; /* Pointer to page cache object */ #ifndef SQLITE_OMIT_WAL Wal *pWal; /* Write-ahead log used by "journal_mode=wal" */ char *zWal; /* File name for write-ahead log */ #endif }; /* ** Indexes for use with Pager.aStat[]. The Pager.aStat[] array contains ** the values accessed by passing SQLITE_DBSTATUS_CACHE_HIT, CACHE_MISS ** or CACHE_WRITE to sqlite3_db_status(). */ | > | 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 | int (*xGet)(Pager*,Pgno,DbPage**,int); /* Routine to fetch a patch */ char *pTmpSpace; /* Pager.pageSize bytes of space for tmp use */ PCache *pPCache; /* Pointer to page cache object */ #ifndef SQLITE_OMIT_WAL Wal *pWal; /* Write-ahead log used by "journal_mode=wal" */ char *zWal; /* File name for write-ahead log */ #endif u64 *aCommitTime; }; /* ** Indexes for use with Pager.aStat[]. The Pager.aStat[] array contains ** the values accessed by passing SQLITE_DBSTATUS_CACHE_HIT, CACHE_MISS ** or CACHE_WRITE to sqlite3_db_status(). */ |
︙ | ︙ | |||
3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 | ** ** If an IO error occurs, then the IO error is returned to the caller. ** Otherwise, SQLITE_OK is returned. */ static int readDbPage(PgHdr *pPg){ Pager *pPager = pPg->pPager; /* Pager object associated with page pPg */ int rc = SQLITE_OK; /* Return code */ #ifndef SQLITE_OMIT_WAL u32 iFrame = 0; /* Frame of WAL containing pgno */ assert( pPager->eState>=PAGER_READER && !MEMDB ); assert( isOpen(pPager->fd) ); if( pagerUseWal(pPager) ){ rc = sqlite3WalFindFrame(pPager->pWal, pPg->pgno, &iFrame); if( rc ) return rc; } if( iFrame ){ rc = sqlite3WalReadFrame(pPager->pWal, iFrame,pPager->pageSize,pPg->pData); }else #endif { i64 iOffset = (pPg->pgno-1)*(i64)pPager->pageSize; rc = sqlite3OsRead(pPager->fd, pPg->pData, pPager->pageSize, iOffset); if( rc==SQLITE_IOERR_SHORT_READ ){ rc = SQLITE_OK; } } if( pPg->pgno==1 ){ if( rc ){ /* If the read is unsuccessful, set the dbFileVers[] to something ** that will never be a valid file version. dbFileVers[] is a copy ** of bytes 24..39 of the database. Bytes 28..31 should always be ** zero or the size of the database in page. Bytes 32..35 and 35..39 | > > > > > > > > | 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 | ** ** If an IO error occurs, then the IO error is returned to the caller. ** Otherwise, SQLITE_OK is returned. */ static int readDbPage(PgHdr *pPg){ Pager *pPager = pPg->pPager; /* Pager object associated with page pPg */ int rc = SQLITE_OK; /* Return code */ u64 t1 = 0; #ifndef SQLITE_OMIT_WAL u32 iFrame = 0; /* Frame of WAL containing pgno */ assert( pPager->eState>=PAGER_READER && !MEMDB ); assert( isOpen(pPager->fd) ); if( pagerUseWal(pPager) ){ rc = sqlite3WalFindFrame(pPager->pWal, pPg->pgno, &iFrame); if( rc ) return rc; } if( pPager->aCommitTime ){ t1 = sqlite3STimeNow(); } if( iFrame ){ rc = sqlite3WalReadFrame(pPager->pWal, iFrame,pPager->pageSize,pPg->pData); }else #endif { i64 iOffset = (pPg->pgno-1)*(i64)pPager->pageSize; rc = sqlite3OsRead(pPager->fd, pPg->pData, pPager->pageSize, iOffset); if( rc==SQLITE_IOERR_SHORT_READ ){ rc = SQLITE_OK; } } if( pPager->aCommitTime ){ pPager->aCommitTime[COMMIT_TIME_RELOCATE2_READUS] += (sqlite3STimeNow() - t1); pPager->aCommitTime[COMMIT_TIME_RELOCATE2_READCOUNT]++; } if( pPg->pgno==1 ){ if( rc ){ /* If the read is unsuccessful, set the dbFileVers[] to something ** that will never be a valid file version. dbFileVers[] is a copy ** of bytes 24..39 of the database. Bytes 28..31 should always be ** zero or the size of the database in page. Bytes 32..35 and 35..39 |
︙ | ︙ | |||
3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270 3271 3272 | assert( pList ); }else{ nList = 1; } pPager->aStat[PAGER_STAT_WRITE] += nList; if( pList->pgno==1 ) pager_write_changecounter(pList); rc = sqlite3WalFrames(pPager->pWal, pPager->pageSize, pList, nTruncate, isCommit, pPager->walSyncFlags ); if( rc==SQLITE_OK && pPager->pBackup ){ for(p=pList; p; p=p->pDirty){ sqlite3BackupUpdate(pPager->pBackup, p->pgno, (u8 *)p->pData); } | > | 3268 3269 3270 3271 3272 3273 3274 3275 3276 3277 3278 3279 3280 3281 3282 | assert( pList ); }else{ nList = 1; } pPager->aStat[PAGER_STAT_WRITE] += nList; if( pList->pgno==1 ) pager_write_changecounter(pList); sqlite3CommitTimeSet(pPager->aCommitTime, COMMIT_TIME_AFTER_CHANGECOUNTER); rc = sqlite3WalFrames(pPager->pWal, pPager->pageSize, pList, nTruncate, isCommit, pPager->walSyncFlags ); if( rc==SQLITE_OK && pPager->pBackup ){ for(p=pList; p; p=p->pDirty){ sqlite3BackupUpdate(pPager->pBackup, p->pgno, (u8 *)p->pData); } |
︙ | ︙ | |||
6649 6650 6651 6652 6653 6654 6655 6656 6657 6658 6659 6660 6661 6662 6663 | ** Ticket [2d1a5c67dfc2363e44f29d9bbd57f] 2011-05-18 */ rc = sqlite3PagerGet(pPager, 1, &pPageOne, 0); pList = pPageOne; pList->pDirty = 0; } assert( rc==SQLITE_OK ); if( ALWAYS(pList) ){ rc = pagerWalFrames(pPager, pList, pPager->dbSize, 1); } sqlite3PagerUnref(pPageOne); if( rc==SQLITE_OK ){ sqlite3PcacheCleanAll(pPager->pPCache); } }else{ /* The bBatch boolean is true if the batch-atomic-write commit method | > > | 6659 6660 6661 6662 6663 6664 6665 6666 6667 6668 6669 6670 6671 6672 6673 6674 6675 | ** Ticket [2d1a5c67dfc2363e44f29d9bbd57f] 2011-05-18 */ rc = sqlite3PagerGet(pPager, 1, &pPageOne, 0); pList = pPageOne; pList->pDirty = 0; } assert( rc==SQLITE_OK ); if( ALWAYS(pList) ){ sqlite3CommitTimeSet(pPager->aCommitTime, COMMIT_TIME_BEFORE_WALFRAMES); rc = pagerWalFrames(pPager, pList, pPager->dbSize, 1); sqlite3CommitTimeSet(pPager->aCommitTime, COMMIT_TIME_AFTER_WALFRAMES); } sqlite3PagerUnref(pPageOne); if( rc==SQLITE_OK ){ sqlite3PcacheCleanAll(pPager->pPCache); } }else{ /* The bBatch boolean is true if the batch-atomic-write commit method |
︙ | ︙ | |||
6823 6824 6825 6826 6827 6828 6829 6830 6831 6832 6833 6834 6835 6836 | commit_phase_one_exit: if( rc==SQLITE_OK && !pagerUseWal(pPager) ){ pPager->eState = PAGER_WRITER_FINISHED; } return rc; } /* ** When this function is called, the database file has been completely ** updated to reflect the changes made by the current transaction and ** synced to disk. The journal file still exists in the file-system ** though, and if a failure occurs at this point it will eventually ** be used as a hot-journal and the current transaction rolled back. | > > > > | 6835 6836 6837 6838 6839 6840 6841 6842 6843 6844 6845 6846 6847 6848 6849 6850 6851 6852 | commit_phase_one_exit: if( rc==SQLITE_OK && !pagerUseWal(pPager) ){ pPager->eState = PAGER_WRITER_FINISHED; } return rc; } void sqlite3PagerSetCommitTime(Pager *pPager, u64 *aCommitTime){ pPager->aCommitTime = aCommitTime; sqlite3WalSetCommitTime(pPager->pWal, aCommitTime); } /* ** When this function is called, the database file has been completely ** updated to reflect the changes made by the current transaction and ** synced to disk. The journal file still exists in the file-system ** though, and if a failure occurs at this point it will eventually ** be used as a hot-journal and the current transaction rolled back. |
︙ | ︙ |
Changes to src/pager.h.
︙ | ︙ | |||
275 276 277 278 279 280 281 282 283 | # define disable_simulated_io_errors() # define enable_simulated_io_errors() #endif #if defined(SQLITE_USE_SEH) && !defined(SQLITE_OMIT_WAL) int sqlite3PagerWalSystemErrno(Pager*); #endif #endif /* SQLITE_PAGER_H */ | > > | 275 276 277 278 279 280 281 282 283 284 285 | # define disable_simulated_io_errors() # define enable_simulated_io_errors() #endif #if defined(SQLITE_USE_SEH) && !defined(SQLITE_OMIT_WAL) int sqlite3PagerWalSystemErrno(Pager*); #endif void sqlite3PagerSetCommitTime(Pager *pPager, u64 *aCommitTime); #endif /* SQLITE_PAGER_H */ |
Changes to src/pcache1.c.
︙ | ︙ | |||
1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 | /* It is an error to call this function if the page is already ** part of the PGroup LRU list. */ assert( pPage->pLruNext==0 ); assert( PAGE_IS_PINNED(pPage) ); if( reuseUnlikely || pGroup->nPurgeable>pGroup->nMaxPage ){ pcache1RemoveFromHash(pPage, 1); }else{ /* Add the page to the PGroup LRU list. */ PgHdr1 **ppFirst = &pGroup->lru.pLruNext; pPage->pLruPrev = &pGroup->lru; (pPage->pLruNext = *ppFirst)->pLruPrev = pPage; *ppFirst = pPage; pCache->nRecyclable++; | > > > > > > | 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 | /* It is an error to call this function if the page is already ** part of the PGroup LRU list. */ assert( pPage->pLruNext==0 ); assert( PAGE_IS_PINNED(pPage) ); if( reuseUnlikely || pGroup->nPurgeable>pGroup->nMaxPage ){ /* If pcache1.separateCache is set, temporarily set the isBulkLocal flag ** so that pcache1RemoveFromHash() moves the page buffer to the pFree ** list instead of sqlite3_free()ing it. */ u16 isBulkLocal = pPage->isBulkLocal; pPage->isBulkLocal = (u16)pcache1.separateCache; pcache1RemoveFromHash(pPage, 1); pPage->isBulkLocal = isBulkLocal; }else{ /* Add the page to the PGroup LRU list. */ PgHdr1 **ppFirst = &pGroup->lru.pLruNext; pPage->pLruPrev = &pGroup->lru; (pPage->pLruNext = *ppFirst)->pLruPrev = pPage; *ppFirst = pPage; pCache->nRecyclable++; |
︙ | ︙ |
Changes to src/pragma.c.
︙ | ︙ | |||
422 423 424 425 426 427 428 429 430 431 432 433 434 435 | int iDb; /* Database index for <database> */ int rc; /* return value form SQLITE_FCNTL_PRAGMA */ sqlite3 *db = pParse->db; /* The database connection */ Db *pDb; /* The specific database being pragmaed */ Vdbe *v = sqlite3GetVdbe(pParse); /* Prepared statement */ const PragmaName *pPragma; /* The pragma */ if( v==0 ) return; sqlite3VdbeRunOnlyOnce(v); pParse->nMem = 2; /* Interpret the [schema.] part of the pragma statement. iDb is the ** index of the database this pragma is being applied to in db.aDb[]. */ iDb = sqlite3TwoPartName(pParse, pId1, pId2, &pId); | > | 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 | int iDb; /* Database index for <database> */ int rc; /* return value form SQLITE_FCNTL_PRAGMA */ sqlite3 *db = pParse->db; /* The database connection */ Db *pDb; /* The specific database being pragmaed */ Vdbe *v = sqlite3GetVdbe(pParse); /* Prepared statement */ const PragmaName *pPragma; /* The pragma */ sqlite3PrepareTimeSet(db->aPrepareTime, PREPARE_TIME_BEGINPRAGMA); if( v==0 ) return; sqlite3VdbeRunOnlyOnce(v); pParse->nMem = 2; /* Interpret the [schema.] part of the pragma statement. iDb is the ** index of the database this pragma is being applied to in db.aDb[]. */ iDb = sqlite3TwoPartName(pParse, pId1, pId2, &pId); |
︙ | ︙ | |||
447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 | if( !zLeft ) return; if( minusFlag ){ zRight = sqlite3MPrintf(db, "-%T", pValue); }else{ zRight = sqlite3NameFromToken(db, pValue); } assert( pId2 ); zDb = pId2->n>0 ? pDb->zDbSName : 0; if( sqlite3AuthCheck(pParse, SQLITE_PRAGMA, zLeft, zRight, zDb) ){ goto pragma_out; } /* Send an SQLITE_FCNTL_PRAGMA file-control to the underlying VFS ** connection. If it returns SQLITE_OK, then assume that the VFS ** handled the pragma and generate a no-op prepared statement. ** ** IMPLEMENTATION-OF: R-12238-55120 Whenever a PRAGMA statement is parsed, ** an SQLITE_FCNTL_PRAGMA file control is sent to the open sqlite3_file | > > | 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 | if( !zLeft ) return; if( minusFlag ){ zRight = sqlite3MPrintf(db, "-%T", pValue); }else{ zRight = sqlite3NameFromToken(db, pValue); } sqlite3PrepareTimeSet(db->aPrepareTime, PREPARE_TIME_BEGINAUTHCHECK); assert( pId2 ); zDb = pId2->n>0 ? pDb->zDbSName : 0; if( sqlite3AuthCheck(pParse, SQLITE_PRAGMA, zLeft, zRight, zDb) ){ goto pragma_out; } sqlite3PrepareTimeSet(db->aPrepareTime, PREPARE_TIME_ENDAUTHCHECK); /* Send an SQLITE_FCNTL_PRAGMA file-control to the underlying VFS ** connection. If it returns SQLITE_OK, then assume that the VFS ** handled the pragma and generate a no-op prepared statement. ** ** IMPLEMENTATION-OF: R-12238-55120 Whenever a PRAGMA statement is parsed, ** an SQLITE_FCNTL_PRAGMA file control is sent to the open sqlite3_file |
︙ | ︙ | |||
499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 | pPragma = pragmaLocate(zLeft); if( pPragma==0 ){ /* IMP: R-43042-22504 No error messages are generated if an ** unknown pragma is issued. */ goto pragma_out; } /* Make sure the database schema is loaded if the pragma requires that */ if( (pPragma->mPragFlg & PragFlg_NeedSchema)!=0 ){ if( sqlite3ReadSchema(pParse) ) goto pragma_out; } /* Register the result column names for pragmas that return results */ if( (pPragma->mPragFlg & PragFlg_NoColumns)==0 && ((pPragma->mPragFlg & PragFlg_NoColumns1)==0 || zRight==0) ){ setPragmaResultColumnNames(v, pPragma); } | > > | 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 | pPragma = pragmaLocate(zLeft); if( pPragma==0 ){ /* IMP: R-43042-22504 No error messages are generated if an ** unknown pragma is issued. */ goto pragma_out; } sqlite3PrepareTimeSet(db->aPrepareTime, PREPARE_TIME_BEGINLOADSCHEMA); /* Make sure the database schema is loaded if the pragma requires that */ if( (pPragma->mPragFlg & PragFlg_NeedSchema)!=0 ){ if( sqlite3ReadSchema(pParse) ) goto pragma_out; } sqlite3PrepareTimeSet(db->aPrepareTime, PREPARE_TIME_ENDLOADSCHEMA); /* Register the result column names for pragmas that return results */ if( (pPragma->mPragFlg & PragFlg_NoColumns)==0 && ((pPragma->mPragFlg & PragFlg_NoColumns1)==0 || zRight==0) ){ setPragmaResultColumnNames(v, pPragma); } |
︙ | ︙ | |||
862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 | ** page cache size value. If N is positive then that is the ** number of pages in the cache. If N is negative, then the ** number of pages is adjusted so that the cache uses -N kibibytes ** of memory. */ case PragTyp_CACHE_SIZE: { assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); if( !zRight ){ returnSingleInt(v, pDb->pSchema->cache_size); }else{ int size = sqlite3Atoi(zRight); pDb->pSchema->cache_size = size; sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size); } break; } /* ** PRAGMA [schema.]cache_spill ** PRAGMA cache_spill=BOOLEAN ** PRAGMA [schema.]cache_spill=N | > > | 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 | ** page cache size value. If N is positive then that is the ** number of pages in the cache. If N is negative, then the ** number of pages is adjusted so that the cache uses -N kibibytes ** of memory. */ case PragTyp_CACHE_SIZE: { assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); sqlite3PrepareTimeSet(db->aPrepareTime, PREPARE_TIME_BEGINCACHESIZE); if( !zRight ){ returnSingleInt(v, pDb->pSchema->cache_size); }else{ int size = sqlite3Atoi(zRight); pDb->pSchema->cache_size = size; sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size); } sqlite3PrepareTimeSet(db->aPrepareTime, PREPARE_TIME_ENDCACHESIZE); break; } /* ** PRAGMA [schema.]cache_spill ** PRAGMA cache_spill=BOOLEAN ** PRAGMA [schema.]cache_spill=N |
︙ | ︙ | |||
1762 1763 1764 1765 1766 1767 1768 | /* Make sure sufficient number of registers have been allocated */ sqlite3TouchRegister(pParse, 8+cnt); sqlite3ClearTempRegCache(pParse); /* Do the b-tree integrity checks */ sqlite3VdbeAddOp4(v, OP_IntegrityCk, 1, cnt, 8, (char*)aRoot,P4_INTARRAY); | | | 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 | /* Make sure sufficient number of registers have been allocated */ sqlite3TouchRegister(pParse, 8+cnt); sqlite3ClearTempRegCache(pParse); /* Do the b-tree integrity checks */ sqlite3VdbeAddOp4(v, OP_IntegrityCk, 1, cnt, 8, (char*)aRoot,P4_INTARRAY); sqlite3VdbeChangeP5(v, (u16)i); addr = sqlite3VdbeAddOp1(v, OP_IsNull, 2); VdbeCoverage(v); sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, sqlite3MPrintf(db, "*** in database %s ***\n", db->aDb[i].zDbSName), P4_DYNAMIC); sqlite3VdbeAddOp3(v, OP_Concat, 2, 3, 3); integrityCheckResultRow(v); sqlite3VdbeJumpHere(v, addr); |
︙ | ︙ | |||
2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 | if( (pPragma->mPragFlg & PragFlg_NoColumns1) && zRight ){ sqlite3VdbeVerifyNoResultRow(v); } pragma_out: sqlite3DbFree(db, zLeft); sqlite3DbFree(db, zRight); } #ifndef SQLITE_OMIT_VIRTUALTABLE /***************************************************************************** ** Implementation of an eponymous virtual table that runs a pragma. ** */ typedef struct PragmaVtab PragmaVtab; | > | 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 | if( (pPragma->mPragFlg & PragFlg_NoColumns1) && zRight ){ sqlite3VdbeVerifyNoResultRow(v); } pragma_out: sqlite3DbFree(db, zLeft); sqlite3DbFree(db, zRight); sqlite3PrepareTimeSet(db->aPrepareTime, PREPARE_TIME_ENDPRAGMA); } #ifndef SQLITE_OMIT_VIRTUALTABLE /***************************************************************************** ** Implementation of an eponymous virtual table that runs a pragma. ** */ typedef struct PragmaVtab PragmaVtab; |
︙ | ︙ |
Changes to src/prepare.c.
︙ | ︙ | |||
205 206 207 208 209 210 211 212 213 214 215 216 217 218 | char const *azArg[6]; int meta[5]; InitData initData; const char *zSchemaTabName; int openedTransaction = 0; int mask = ((db->mDbFlags & DBFLAG_EncodingFixed) | ~DBFLAG_EncodingFixed); assert( (db->mDbFlags & DBFLAG_SchemaKnownOk)==0 ); assert( iDb>=0 && iDb<db->nDb ); assert( db->aDb[iDb].pSchema ); assert( sqlite3_mutex_held(db->mutex) ); assert( iDb==1 || sqlite3BtreeHoldsMutex(db->aDb[iDb].pBt) ); db->init.busy = 1; | > > > > > | 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 | char const *azArg[6]; int meta[5]; InitData initData; const char *zSchemaTabName; int openedTransaction = 0; int mask = ((db->mDbFlags & DBFLAG_EncodingFixed) | ~DBFLAG_EncodingFixed); u64 aSchemaTime[SCHEMA_TIME_N]; memset(aSchemaTime, 0, sizeof(aSchemaTime)); db->aSchemaTime = aSchemaTime; sqlite3PrepareTimeSet(aSchemaTime, SCHEMA_TIME_START); assert( (db->mDbFlags & DBFLAG_SchemaKnownOk)==0 ); assert( iDb>=0 && iDb<db->nDb ); assert( db->aDb[iDb].pSchema ); assert( sqlite3_mutex_held(db->mutex) ); assert( iDb==1 || sqlite3BtreeHoldsMutex(db->aDb[iDb].pBt) ); db->init.busy = 1; |
︙ | ︙ | |||
239 240 241 242 243 244 245 246 247 248 249 250 251 252 | sqlite3InitCallback(&initData, 5, (char **)azArg, 0); db->mDbFlags &= mask; if( initData.rc ){ rc = initData.rc; goto error_out; } /* Create a cursor to hold the database open */ pDb = &db->aDb[iDb]; if( pDb->pBt==0 ){ assert( iDb==1 ); DbSetProperty(db, 1, DB_SchemaLoaded); rc = SQLITE_OK; | > > | 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 | sqlite3InitCallback(&initData, 5, (char **)azArg, 0); db->mDbFlags &= mask; if( initData.rc ){ rc = initData.rc; goto error_out; } sqlite3PrepareTimeSet(aSchemaTime, SCHEMA_TIME_AFTER_CREATE_1); /* Create a cursor to hold the database open */ pDb = &db->aDb[iDb]; if( pDb->pBt==0 ){ assert( iDb==1 ); DbSetProperty(db, 1, DB_SchemaLoaded); rc = SQLITE_OK; |
︙ | ︙ | |||
261 262 263 264 265 266 267 268 269 270 271 272 273 274 | rc = sqlite3BtreeBeginTrans(pDb->pBt, 0, 0); if( rc!=SQLITE_OK ){ sqlite3SetString(pzErrMsg, db, sqlite3ErrStr(rc)); goto initone_error_out; } openedTransaction = 1; } /* Get the database meta information. ** ** Meta values are as follows: ** meta[0] Schema cookie. Changes with each schema change. ** meta[1] File format of schema layer. ** meta[2] Size of the page cache. | > > | 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 | rc = sqlite3BtreeBeginTrans(pDb->pBt, 0, 0); if( rc!=SQLITE_OK ){ sqlite3SetString(pzErrMsg, db, sqlite3ErrStr(rc)); goto initone_error_out; } openedTransaction = 1; } sqlite3PrepareTimeSet(aSchemaTime, SCHEMA_TIME_AFTER_OPEN_TRANS); /* Get the database meta information. ** ** Meta values are as follows: ** meta[0] Schema cookie. Changes with each schema change. ** meta[1] File format of schema layer. ** meta[2] Size of the page cache. |
︙ | ︙ | |||
286 287 288 289 290 291 292 293 294 295 296 297 298 299 | for(i=0; i<ArraySize(meta); i++){ sqlite3BtreeGetMeta(pDb->pBt, i+1, (u32 *)&meta[i]); } if( (db->flags & SQLITE_ResetDatabase)!=0 ){ memset(meta, 0, sizeof(meta)); } pDb->pSchema->schema_cookie = meta[BTREE_SCHEMA_VERSION-1]; /* If opening a non-empty database, check the text encoding. For the ** main database, set sqlite3.enc to the encoding of the main database. ** For an attached db, it is an error if the encoding is not the same ** as sqlite3.enc. */ if( meta[BTREE_TEXT_ENCODING-1] ){ /* text encoding */ | > > | 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 | for(i=0; i<ArraySize(meta); i++){ sqlite3BtreeGetMeta(pDb->pBt, i+1, (u32 *)&meta[i]); } if( (db->flags & SQLITE_ResetDatabase)!=0 ){ memset(meta, 0, sizeof(meta)); } pDb->pSchema->schema_cookie = meta[BTREE_SCHEMA_VERSION-1]; sqlite3PrepareTimeSet(aSchemaTime, SCHEMA_TIME_AFTER_GET_META); /* If opening a non-empty database, check the text encoding. For the ** main database, set sqlite3.enc to the encoding of the main database. ** For an attached db, it is an error if the encoding is not the same ** as sqlite3.enc. */ if( meta[BTREE_TEXT_ENCODING-1] ){ /* text encoding */ |
︙ | ︙ | |||
322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 | rc = SQLITE_ERROR; goto initone_error_out; } } } pDb->pSchema->enc = ENC(db); if( pDb->pSchema->cache_size==0 ){ #ifndef SQLITE_OMIT_DEPRECATED size = sqlite3AbsInt32(meta[BTREE_DEFAULT_CACHE_SIZE-1]); if( size==0 ){ size = SQLITE_DEFAULT_CACHE_SIZE; } pDb->pSchema->cache_size = size; #else pDb->pSchema->cache_size = SQLITE_DEFAULT_CACHE_SIZE; #endif sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size); } /* ** file_format==1 Version 3.0.0. ** file_format==2 Version 3.1.3. // ALTER TABLE ADD COLUMN ** file_format==3 Version 3.1.4. // ditto but with non-NULL defaults ** file_format==4 Version 3.3.0. // DESC indices. Boolean constants */ | > > > > | 333 334 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 | rc = SQLITE_ERROR; goto initone_error_out; } } } pDb->pSchema->enc = ENC(db); sqlite3PrepareTimeSet(aSchemaTime, SCHEMA_TIME_AFTER_FIX_ENCODING); if( pDb->pSchema->cache_size==0 ){ #ifndef SQLITE_OMIT_DEPRECATED size = sqlite3AbsInt32(meta[BTREE_DEFAULT_CACHE_SIZE-1]); if( size==0 ){ size = SQLITE_DEFAULT_CACHE_SIZE; } pDb->pSchema->cache_size = size; #else pDb->pSchema->cache_size = SQLITE_DEFAULT_CACHE_SIZE; #endif sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size); } sqlite3PrepareTimeSet(aSchemaTime, SCHEMA_TIME_AFTER_SETCACHESIZE); /* ** file_format==1 Version 3.0.0. ** file_format==2 Version 3.1.3. // ALTER TABLE ADD COLUMN ** file_format==3 Version 3.1.4. // ditto but with non-NULL defaults ** file_format==4 Version 3.3.0. // DESC indices. Boolean constants */ |
︙ | ︙ | |||
373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 | db->aDb[iDb].zDbSName, zSchemaTabName); #ifndef SQLITE_OMIT_AUTHORIZATION { sqlite3_xauth xAuth; xAuth = db->xAuth; db->xAuth = 0; #endif rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0); #ifndef SQLITE_OMIT_AUTHORIZATION db->xAuth = xAuth; } #endif if( rc==SQLITE_OK ) rc = initData.rc; sqlite3DbFree(db, zSql); #ifndef SQLITE_OMIT_ANALYZE if( rc==SQLITE_OK ){ sqlite3AnalysisLoad(db, iDb); } #endif } assert( pDb == &(db->aDb[iDb]) ); if( db->mallocFailed ){ rc = SQLITE_NOMEM_BKPT; sqlite3ResetAllSchemasOfConnection(db); pDb = &db->aDb[iDb]; }else | > > > | 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 | db->aDb[iDb].zDbSName, zSchemaTabName); #ifndef SQLITE_OMIT_AUTHORIZATION { sqlite3_xauth xAuth; xAuth = db->xAuth; db->xAuth = 0; #endif sqlite3PrepareTimeSet(aSchemaTime, SCHEMA_TIME_BEGIN_EXEC); rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0); #ifndef SQLITE_OMIT_AUTHORIZATION db->xAuth = xAuth; } #endif if( rc==SQLITE_OK ) rc = initData.rc; sqlite3DbFree(db, zSql); sqlite3PrepareTimeSet(aSchemaTime, SCHEMA_TIME_BEGIN_ANALYZE_LOAD); #ifndef SQLITE_OMIT_ANALYZE if( rc==SQLITE_OK ){ sqlite3AnalysisLoad(db, iDb); } #endif sqlite3PrepareTimeSet(aSchemaTime, SCHEMA_TIME_END_ANALYZE_LOAD); } assert( pDb == &(db->aDb[iDb]) ); if( db->mallocFailed ){ rc = SQLITE_NOMEM_BKPT; sqlite3ResetAllSchemasOfConnection(db); pDb = &db->aDb[iDb]; }else |
︙ | ︙ | |||
418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 | initone_error_out: if( openedTransaction ){ sqlite3BtreeCommit(pDb->pBt); } sqlite3BtreeLeave(pDb->pBt); error_out: if( rc ){ if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){ sqlite3OomFault(db); } sqlite3ResetOneSchema(db, iDb); } db->init.busy = 0; return rc; } /* ** Initialize all database files - the main database file, the file ** used to store temporary tables, and any additional database files ** created using ATTACH statements. Return a success code. If an ** error occurs, write an error message into *pzErrMsg. ** | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 | initone_error_out: if( openedTransaction ){ sqlite3BtreeCommit(pDb->pBt); } sqlite3BtreeLeave(pDb->pBt); error_out: db->aSchemaTime = 0; sqlite3PrepareTimeSet(aSchemaTime, SCHEMA_TIME_FINISH); if( rc==SQLITE_OK && iDb==0 ){ const char *zFile = sqlite3BtreeGetFilename(pDb->pBt); sqlite3SchemaTimeLog(aSchemaTime, zFile); } if( rc ){ if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){ sqlite3OomFault(db); } sqlite3ResetOneSchema(db, iDb); } db->init.busy = 0; return rc; } /* ** Calling this function is equivalent to calling: ** ** sqlite3InitOne(db, iDb, pzErrMsg, 0); ** ** except that if SQLITE_TESTCTRL_SCHEMACOPY has been configured, then ** the schema is first loaded into space allocated on the heap, and then ** copied into the database schema object using sqlite3SchemaCopy(). This ** is done to help test the internals of the sqlite3_schema_copy() API. */ static int initOneWithCopy(sqlite3 *db, int iDb, char **pzErrMsg){ int rc; #ifndef SQLITE_UNTESTABLE Schema *pNew = 0; Schema *pOld = 0; if( iDb!=1 && sqlite3Config.bTestSchemaCopy ){ pNew = sqlite3DbMallocZero(db, sizeof(Schema)); if( !pNew ) return SQLITE_NOMEM; pOld = db->aDb[iDb].pSchema; memcpy(pNew, pOld, sizeof(Schema)); db->aDb[iDb].pSchema = pNew; } #endif rc = sqlite3InitOne(db, iDb, pzErrMsg, 0); #ifndef SQLITE_UNTESTABLE if( iDb!=1 && sqlite3Config.bTestSchemaCopy ){ sqlite3SchemaCopy(db, pOld, pNew); if( db->mallocFailed ) rc = SQLITE_NOMEM; db->aDb[iDb].pSchema = pOld; sqlite3SchemaClear(pNew); sqlite3DbFree(db, pNew); } #endif return rc; } /* ** Initialize all database files - the main database file, the file ** used to store temporary tables, and any additional database files ** created using ATTACH statements. Return a success code. If an ** error occurs, write an error message into *pzErrMsg. ** |
︙ | ︙ | |||
448 449 450 451 452 453 454 | assert( sqlite3_mutex_held(db->mutex) ); assert( sqlite3BtreeHoldsMutex(db->aDb[0].pBt) ); assert( db->init.busy==0 ); ENC(db) = SCHEMA_ENC(db); assert( db->nDb>0 ); /* Do the main schema first */ if( !DbHasProperty(db, 0, DB_SchemaLoaded) ){ | | | | 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 | assert( sqlite3_mutex_held(db->mutex) ); assert( sqlite3BtreeHoldsMutex(db->aDb[0].pBt) ); assert( db->init.busy==0 ); ENC(db) = SCHEMA_ENC(db); assert( db->nDb>0 ); /* Do the main schema first */ if( !DbHasProperty(db, 0, DB_SchemaLoaded) ){ rc = initOneWithCopy(db, 0, pzErrMsg); if( rc ) return rc; } /* All other schemas after the main schema. The "temp" schema must be last */ for(i=db->nDb-1; i>0; i--){ assert( i==1 || sqlite3BtreeHoldsMutex(db->aDb[i].pBt) ); if( !DbHasProperty(db, i, DB_SchemaLoaded) ){ rc = initOneWithCopy(db, i, pzErrMsg); if( rc ) return rc; } } if( commit_internal ){ sqlite3CommitInternalChanges(db); } return SQLITE_OK; |
︙ | ︙ | |||
778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 | if( nBytes>mxLen ){ sqlite3ErrorWithMsg(db, SQLITE_TOOBIG, "statement too long"); rc = sqlite3ApiExit(db, SQLITE_TOOBIG); goto end_prepare; } zSqlCopy = sqlite3DbStrNDup(db, zSql, nBytes); if( zSqlCopy ){ sqlite3RunParser(&sParse, zSqlCopy); sParse.zTail = &zSql[sParse.zTail-zSqlCopy]; sqlite3DbFree(db, zSqlCopy); }else{ sParse.zTail = &zSql[nBytes]; } }else{ sqlite3RunParser(&sParse, zSql); } assert( 0==sParse.nQueryLoop ); if( pzTail ){ *pzTail = sParse.zTail; } | > > > > | 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 | if( nBytes>mxLen ){ sqlite3ErrorWithMsg(db, SQLITE_TOOBIG, "statement too long"); rc = sqlite3ApiExit(db, SQLITE_TOOBIG); goto end_prepare; } zSqlCopy = sqlite3DbStrNDup(db, zSql, nBytes); if( zSqlCopy ){ sqlite3PrepareTimeSet(db->aPrepareTime, PREPARE_TIME_BEGINPARSE); sqlite3RunParser(&sParse, zSqlCopy); sqlite3PrepareTimeSet(db->aPrepareTime, PREPARE_TIME_ENDPARSE); sParse.zTail = &zSql[sParse.zTail-zSqlCopy]; sqlite3DbFree(db, zSqlCopy); }else{ sParse.zTail = &zSql[nBytes]; } }else{ sqlite3PrepareTimeSet(db->aPrepareTime, PREPARE_TIME_BEGINPARSE); sqlite3RunParser(&sParse, zSql); sqlite3PrepareTimeSet(db->aPrepareTime, PREPARE_TIME_ENDPARSE); } assert( 0==sParse.nQueryLoop ); if( pzTail ){ *pzTail = sParse.zTail; } |
︙ | ︙ | |||
846 847 848 849 850 851 852 853 854 855 856 857 858 859 | u32 prepFlags, /* Zero or more SQLITE_PREPARE_* flags */ Vdbe *pOld, /* VM being reprepared */ sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ const char **pzTail /* OUT: End of parsed string */ ){ int rc; int cnt = 0; #ifdef SQLITE_ENABLE_API_ARMOR if( ppStmt==0 ) return SQLITE_MISUSE_BKPT; #endif *ppStmt = 0; if( !sqlite3SafetyCheckOk(db)||zSql==0 ){ return SQLITE_MISUSE_BKPT; | > > > > > > | 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 | u32 prepFlags, /* Zero or more SQLITE_PREPARE_* flags */ Vdbe *pOld, /* VM being reprepared */ sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ const char **pzTail /* OUT: End of parsed string */ ){ int rc; int cnt = 0; u64 *aPrepareSave = db->aPrepareTime; u64 aPrepareTime[PREPARE_TIME_N]; memset(aPrepareTime, 0, sizeof(aPrepareTime)); sqlite3PrepareTimeSet(aPrepareTime, PREPARE_TIME_START); db->aPrepareTime = aPrepareTime; #ifdef SQLITE_ENABLE_API_ARMOR if( ppStmt==0 ) return SQLITE_MISUSE_BKPT; #endif *ppStmt = 0; if( !sqlite3SafetyCheckOk(db)||zSql==0 ){ return SQLITE_MISUSE_BKPT; |
︙ | ︙ | |||
871 872 873 874 875 876 877 878 879 880 881 882 883 884 | || (rc==SQLITE_SCHEMA && (sqlite3ResetOneSchema(db,-1), cnt++)==0) ); sqlite3BtreeLeaveAll(db); rc = sqlite3ApiExit(db, rc); assert( (rc&db->errMask)==rc ); db->busyHandler.nBusy = 0; sqlite3_mutex_leave(db->mutex); assert( rc==SQLITE_OK || (*ppStmt)==0 ); return rc; } /* ** Rerun the compilation of a statement after a schema change. ** | > > > > > | 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 | || (rc==SQLITE_SCHEMA && (sqlite3ResetOneSchema(db,-1), cnt++)==0) ); sqlite3BtreeLeaveAll(db); rc = sqlite3ApiExit(db, rc); assert( (rc&db->errMask)==rc ); db->busyHandler.nBusy = 0; sqlite3_mutex_leave(db->mutex); assert( rc==SQLITE_OK || (*ppStmt)==0 ); db->aPrepareTime = aPrepareSave; sqlite3PrepareTimeSet(aPrepareTime, PREPARE_TIME_FINISH); sqlite3PrepareTimeLog(zSql, nBytes, aPrepareTime); return rc; } /* ** Rerun the compilation of a statement after a schema change. ** |
︙ | ︙ |
Changes to src/printf.c.
︙ | ︙ | |||
1313 1314 1315 1316 1317 1318 1319 | ** sqlite3_str_vappendf() might ask for *temporary* memory allocations for ** certain format characters (%q) or for very large precisions or widths. ** Care must be taken that any sqlite3_log() calls that occur while the ** memory mutex is held do not use these mechanisms. */ static void renderLogMsg(int iErrCode, const char *zFormat, va_list ap){ StrAccum acc; /* String accumulator */ | | | 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 | ** sqlite3_str_vappendf() might ask for *temporary* memory allocations for ** certain format characters (%q) or for very large precisions or widths. ** Care must be taken that any sqlite3_log() calls that occur while the ** memory mutex is held do not use these mechanisms. */ static void renderLogMsg(int iErrCode, const char *zFormat, va_list ap){ StrAccum acc; /* String accumulator */ char zMsg[SQLITE_PRINT_BUF_SIZE*10]; /* Complete log message */ sqlite3StrAccumInit(&acc, 0, zMsg, sizeof(zMsg), 0); sqlite3_str_vappendf(&acc, zFormat, ap); sqlite3GlobalConfig.xLog(sqlite3GlobalConfig.pLogArg, iErrCode, sqlite3StrAccumFinish(&acc)); } |
︙ | ︙ |
Changes to src/select.c.
︙ | ︙ | |||
6821 6822 6823 6824 6825 6826 6827 | sqlite3VdbeAddOp3(v, OP_Column, pF->iOBTab, iBaseCol+j, regSubtype); sqlite3VdbeAddOp2(v, OP_SetSubtype, regSubtype, regAgg+j); } sqlite3ReleaseTempReg(pParse, regSubtype); } sqlite3VdbeAddOp3(v, OP_AggStep, 0, regAgg, AggInfoFuncReg(pAggInfo,i)); sqlite3VdbeAppendP4(v, pF->pFunc, P4_FUNCDEF); | | | 6821 6822 6823 6824 6825 6826 6827 6828 6829 6830 6831 6832 6833 6834 6835 | sqlite3VdbeAddOp3(v, OP_Column, pF->iOBTab, iBaseCol+j, regSubtype); sqlite3VdbeAddOp2(v, OP_SetSubtype, regSubtype, regAgg+j); } sqlite3ReleaseTempReg(pParse, regSubtype); } sqlite3VdbeAddOp3(v, OP_AggStep, 0, regAgg, AggInfoFuncReg(pAggInfo,i)); sqlite3VdbeAppendP4(v, pF->pFunc, P4_FUNCDEF); sqlite3VdbeChangeP5(v, (u16)nArg); sqlite3VdbeAddOp2(v, OP_Next, pF->iOBTab, iTop+1); VdbeCoverage(v); sqlite3VdbeJumpHere(v, iTop); sqlite3ReleaseTempRange(pParse, regAgg, nArg); } sqlite3VdbeAddOp2(v, OP_AggFinal, AggInfoFuncReg(pAggInfo,i), pList ? pList->nExpr : 0); sqlite3VdbeAppendP4(v, pF->pFunc, P4_FUNCDEF); |
︙ | ︙ | |||
6984 6985 6986 6987 6988 6989 6990 | } if( regHit==0 && pAggInfo->nAccumulator ) regHit = ++pParse->nMem; sqlite3VdbeAddOp4(v, OP_CollSeq, regHit, 0, 0, (char *)pColl, P4_COLLSEQ); } sqlite3VdbeAddOp3(v, OP_AggStep, 0, regAgg, AggInfoFuncReg(pAggInfo,i)); sqlite3VdbeAppendP4(v, pF->pFunc, P4_FUNCDEF); | | | 6984 6985 6986 6987 6988 6989 6990 6991 6992 6993 6994 6995 6996 6997 6998 | } if( regHit==0 && pAggInfo->nAccumulator ) regHit = ++pParse->nMem; sqlite3VdbeAddOp4(v, OP_CollSeq, regHit, 0, 0, (char *)pColl, P4_COLLSEQ); } sqlite3VdbeAddOp3(v, OP_AggStep, 0, regAgg, AggInfoFuncReg(pAggInfo,i)); sqlite3VdbeAppendP4(v, pF->pFunc, P4_FUNCDEF); sqlite3VdbeChangeP5(v, (u16)nArg); sqlite3ReleaseTempRange(pParse, regAgg, nArg); } if( addrNext ){ sqlite3VdbeResolveLabel(v, addrNext); } if( pParse->nErr ) return; } |
︙ | ︙ |
Changes to src/shell.c.in.
︙ | ︙ | |||
10945 10946 10947 10948 10949 10950 10951 10952 10953 10954 10955 10956 10957 10958 | {"prng_restore", SQLITE_TESTCTRL_PRNG_RESTORE,0, "" }, {"prng_save", SQLITE_TESTCTRL_PRNG_SAVE, 0, "" }, {"prng_seed", SQLITE_TESTCTRL_PRNG_SEED, 0, "SEED ?db?" }, {"seek_count", SQLITE_TESTCTRL_SEEK_COUNT, 0, "" }, {"sorter_mmap", SQLITE_TESTCTRL_SORTER_MMAP, 0, "NMAX" }, {"tune", SQLITE_TESTCTRL_TUNE, 1, "ID VALUE" }, {"uselongdouble", SQLITE_TESTCTRL_USELONGDOUBLE,0,"?BOOLEAN|\"default\"?"}, }; int testctrl = -1; int iCtrl = -1; int rc2 = 0; /* 0: usage. 1: %d 2: %x 3: no-output */ int isOk = 0; int i, n2; const char *zCmd = 0; | > | 10945 10946 10947 10948 10949 10950 10951 10952 10953 10954 10955 10956 10957 10958 10959 | {"prng_restore", SQLITE_TESTCTRL_PRNG_RESTORE,0, "" }, {"prng_save", SQLITE_TESTCTRL_PRNG_SAVE, 0, "" }, {"prng_seed", SQLITE_TESTCTRL_PRNG_SEED, 0, "SEED ?db?" }, {"seek_count", SQLITE_TESTCTRL_SEEK_COUNT, 0, "" }, {"sorter_mmap", SQLITE_TESTCTRL_SORTER_MMAP, 0, "NMAX" }, {"tune", SQLITE_TESTCTRL_TUNE, 1, "ID VALUE" }, {"uselongdouble", SQLITE_TESTCTRL_USELONGDOUBLE,0,"?BOOLEAN|\"default\"?"}, {"schemacopy", SQLITE_TESTCTRL_SCHEMACOPY,0,"?BOOLEAN|\"default\"?"}, }; int testctrl = -1; int iCtrl = -1; int rc2 = 0; /* 0: usage. 1: %d 2: %x 3: no-output */ int isOk = 0; int i, n2; const char *zCmd = 0; |
︙ | ︙ | |||
11178 11179 11180 11181 11182 11183 11184 11185 11186 11187 11188 11189 11190 11191 | int opt = booleanValue(azArg[2]); rc2 = sqlite3_test_control(testctrl, opt); isOk = 3; } break; /* sqlite3_test_control(int, int) */ case SQLITE_TESTCTRL_USELONGDOUBLE: { int opt = -1; if( nArg==3 ){ if( cli_strcmp(azArg[2],"default")==0 ){ opt = 2; }else{ opt = booleanValue(azArg[2]); | > | 11179 11180 11181 11182 11183 11184 11185 11186 11187 11188 11189 11190 11191 11192 11193 | int opt = booleanValue(azArg[2]); rc2 = sqlite3_test_control(testctrl, opt); isOk = 3; } break; /* sqlite3_test_control(int, int) */ case SQLITE_TESTCTRL_SCHEMACOPY: case SQLITE_TESTCTRL_USELONGDOUBLE: { int opt = -1; if( nArg==3 ){ if( cli_strcmp(azArg[2],"default")==0 ){ opt = 2; }else{ opt = booleanValue(azArg[2]); |
︙ | ︙ |
Changes to src/sqlite.h.in.
︙ | ︙ | |||
8361 8362 8363 8364 8365 8366 8367 | #define SQLITE_TESTCTRL_PRNG_SEED 28 #define SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS 29 #define SQLITE_TESTCTRL_SEEK_COUNT 30 #define SQLITE_TESTCTRL_TRACEFLAGS 31 #define SQLITE_TESTCTRL_TUNE 32 #define SQLITE_TESTCTRL_LOGEST 33 #define SQLITE_TESTCTRL_USELONGDOUBLE 34 | > | | 8361 8362 8363 8364 8365 8366 8367 8368 8369 8370 8371 8372 8373 8374 8375 8376 | #define SQLITE_TESTCTRL_PRNG_SEED 28 #define SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS 29 #define SQLITE_TESTCTRL_SEEK_COUNT 30 #define SQLITE_TESTCTRL_TRACEFLAGS 31 #define SQLITE_TESTCTRL_TUNE 32 #define SQLITE_TESTCTRL_LOGEST 33 #define SQLITE_TESTCTRL_USELONGDOUBLE 34 #define SQLITE_TESTCTRL_SCHEMACOPY 35 #define SQLITE_TESTCTRL_LAST 35 /* Largest TESTCTRL */ /* ** CAPI3REF: SQL Keyword Checking ** ** These routines provide access to the set of SQL language keywords ** recognized by SQLite. Applications can uses these routines to determine ** whether or not a specific identifier needs to be escaped (for example, |
︙ | ︙ | |||
10948 10949 10950 10951 10952 10953 10954 10955 10956 10957 10958 10959 10960 10961 | */ #define SQLITE_COMMIT_FIRSTFRAME 0 #define SQLITE_COMMIT_NFRAME 1 #define SQLITE_COMMIT_CONFLICT_DB 2 #define SQLITE_COMMIT_CONFLICT_FRAME 3 #define SQLITE_COMMIT_CONFLICT_PGNO 4 /* ** Undo the hack that converts floating point types to integer for ** builds on processors without floating point support. */ #ifdef SQLITE_OMIT_FLOATING_POINT # undef double | > > > > > > > > > > > > > > > > > > > > > | 10949 10950 10951 10952 10953 10954 10955 10956 10957 10958 10959 10960 10961 10962 10963 10964 10965 10966 10967 10968 10969 10970 10971 10972 10973 10974 10975 10976 10977 10978 10979 10980 10981 10982 10983 | */ #define SQLITE_COMMIT_FIRSTFRAME 0 #define SQLITE_COMMIT_NFRAME 1 #define SQLITE_COMMIT_CONFLICT_DB 2 #define SQLITE_COMMIT_CONFLICT_FRAME 3 #define SQLITE_COMMIT_CONFLICT_PGNO 4 /* ** This function is used to copy an in-memory schema from one database ** connection to another. Under some circumstances this may be faster than ** loading it from the database. ** ** The target database is identified by parameters pTo and zTo, which must ** be "main" or the name of an attached database. The source database is ** identified by pFrom and zFrom. It is the responsibility of the caller ** to ensure that these two database connections really access the same ** underlying database file. ** ** This function is a no-op if either the database schema has already been ** loaded for pTo/zTo, or if it has not yet been loaded for pFrom/zFrom. In ** these cases SQLITE_OK is returned. Otherwise, the database schema from ** pFrom/zFrom is copied into pTo/zTo. SQLITE_OK is returned if successful, ** or SQLITE_NOMEM if an OOM error occurs. */ int sqlite3_schema_copy( sqlite3 *pTo, const char *zTo, sqlite3 *pFrom, const char *zFrom ); /* ** Undo the hack that converts floating point types to integer for ** builds on processors without floating point support. */ #ifdef SQLITE_OMIT_FLOATING_POINT # undef double |
︙ | ︙ |
Changes to src/sqliteInt.h.
︙ | ︙ | |||
1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 | Hash trigHash; /* All triggers indexed by name */ Hash fkeyHash; /* All foreign keys by referenced table name */ Table *pSeqTab; /* The sqlite_sequence table used by AUTOINCREMENT */ u8 file_format; /* Schema format version for this file */ u8 enc; /* Text encoding used by this database */ u16 schemaFlags; /* Flags associated with this schema */ int cache_size; /* Number of pages to use in the cache */ }; /* ** These macros can be used to test, set, or clear bits in the ** Db.pSchema->flags field. */ #define DbHasProperty(D,I,P) (((D)->aDb[I].pSchema->schemaFlags&(P))==(P)) | > > > > | 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 | Hash trigHash; /* All triggers indexed by name */ Hash fkeyHash; /* All foreign keys by referenced table name */ Table *pSeqTab; /* The sqlite_sequence table used by AUTOINCREMENT */ u8 file_format; /* Schema format version for this file */ u8 enc; /* Text encoding used by this database */ u16 schemaFlags; /* Flags associated with this schema */ int cache_size; /* Number of pages to use in the cache */ #ifdef SQLITE_ENABLE_STAT4 void *pStat4Space; /* Memory for stat4 Index.aSample[] arrays */ int nStat4Space; /* Size of pStat4Space allocation in bytes */ #endif }; /* ** These macros can be used to test, set, or clear bits in the ** Db.pSchema->flags field. */ #define DbHasProperty(D,I,P) (((D)->aDb[I].pSchema->schemaFlags&(P))==(P)) |
︙ | ︙ | |||
1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 | #endif #ifndef SQLITE_OMIT_CONCURRENT /* Return values for sqlite3_commit_status() requests: ** SQLITE_COMMIT_CONFLICT_DB, CONFLICT_FRAME and CONFLICT_PGNO. */ u32 aCommit[5]; #endif }; /* ** Candidate values for sqlite3.eConcurrent */ #define CONCURRENT_NONE 0 #define CONCURRENT_OPEN 1 #define CONCURRENT_SCHEMA 2 | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 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 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 | #endif #ifndef SQLITE_OMIT_CONCURRENT /* Return values for sqlite3_commit_status() requests: ** SQLITE_COMMIT_CONFLICT_DB, CONFLICT_FRAME and CONFLICT_PGNO. */ u32 aCommit[5]; #endif u64 *aPrepareTime; u64 *aSchemaTime; }; #define PREPARE_TIME_START 0 #define PREPARE_TIME_BEGINPARSE 1 #define PREPARE_TIME_BEGINPRAGMA 2 #define PREPARE_TIME_BEGINAUTHCHECK 3 #define PREPARE_TIME_ENDAUTHCHECK 4 #define PREPARE_TIME_BEGINLOADSCHEMA 5 #define PREPARE_TIME_ENDLOADSCHEMA 6 #define PREPARE_TIME_BEGINCACHESIZE 7 #define PREPARE_TIME_BEGINSETCACHESIZE 8 #define PREPARE_TIME_ENDSETCACHESIZE 9 #define PREPARE_TIME_ENDCACHESIZE 10 #define PREPARE_TIME_ENDPRAGMA 11 #define PREPARE_TIME_ENDPARSE 12 #define PREPARE_TIME_FINISH 13 #define PREPARE_TIME_N 14 #define SCHEMA_TIME_START 0 #define SCHEMA_TIME_AFTER_CREATE_1 1 #define SCHEMA_TIME_AFTER_OPEN_TRANS 2 #define SCHEMA_TIME_AFTER_GET_META 3 #define SCHEMA_TIME_AFTER_FIX_ENCODING 4 #define SCHEMA_TIME_AFTER_SETCACHESIZE 5 #define SCHEMA_TIME_BEGIN_EXEC 6 #define SCHEMA_TIME_BEFORE_STEP 7 #define SCHEMA_TIME_BEFORE_PREPARE 8 #define SCHEMA_TIME_BEFORE_FINALIZE 9 #define SCHEMA_TIME_BEGIN_ANALYZE_LOAD 10 #define SCHEMA_TIME_AFTER_CLEAR_STATS 11 #define SCHEMA_TIME_AFTER_STAT1 12 #define SCHEMA_TIME_AFTER_DEFAULTS 13 #define SCHEMA_TIME_AFTER_STAT4_SPACE 14 #define SCHEMA_TIME_AFTER_STAT4_PREPARE 15 #define SCHEMA_TIME_STAT4_GROWUS 16 #define SCHEMA_TIME_STAT4_Q2_BODYUS 17 #define SCHEMA_TIME_AFTER_STAT4_Q2 18 #define SCHEMA_TIME_AFTER_STAT4 19 #define SCHEMA_TIME_END_ANALYZE_LOAD 20 #define SCHEMA_TIME_FINISH 21 #define SCHEMA_TIME_N 22 #define SCHEMA_TIME_TIMEOUT (500 * 1000) #define sqlite3PrepareTimeSet(x,y) sqlite3CommitTimeSet(x,y) void sqlite3PrepareTimeLog(const char *zSql, int nSql, u64 *aPrepareTime); void sqlite3SchemaTimeLog(u64 *aSchemaTime, const char *zFile); #define PREPARE_TIME_TIMEOUT (2 * 1000 * 1000) /* 2 second timeout */ /* ** Candidate values for sqlite3.eConcurrent */ #define CONCURRENT_NONE 0 #define CONCURRENT_OPEN 1 #define CONCURRENT_SCHEMA 2 |
︙ | ︙ | |||
1988 1989 1990 1991 1992 1993 1994 | ** For per-connection application-defined functions, a pointer to this ** structure is held in the db->aHash hash table. ** ** The u.pHash field is used by the global built-ins. The u.pDestructor ** field is used by per-connection app-def functions. */ struct FuncDef { | | | 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 | ** For per-connection application-defined functions, a pointer to this ** structure is held in the db->aHash hash table. ** ** The u.pHash field is used by the global built-ins. The u.pDestructor ** field is used by per-connection app-def functions. */ struct FuncDef { i16 nArg; /* Number of arguments. -1 means unlimited */ u32 funcFlags; /* Some combination of SQLITE_FUNC_* */ void *pUserData; /* User data parameter */ FuncDef *pNext; /* Next function with same name */ void (*xSFunc)(sqlite3_context*,int,sqlite3_value**); /* func or agg-step */ void (*xFinalize)(sqlite3_context*); /* Agg finalizer */ void (*xValue)(sqlite3_context*); /* Current agg value */ void (*xInverse)(sqlite3_context*,int,sqlite3_value**); /* inverse agg-step */ |
︙ | ︙ | |||
2817 2818 2819 2820 2821 2822 2823 | unsigned bNoQuery:1; /* Do not use this index to optimize queries */ unsigned bAscKeyBug:1; /* True if the bba7b69f9849b5bf bug applies */ unsigned bHasVCol:1; /* Index references one or more VIRTUAL columns */ unsigned bHasExpr:1; /* Index contains an expression, either a literal ** expression, or a reference to a VIRTUAL column */ #ifdef SQLITE_ENABLE_STAT4 int nSample; /* Number of elements in aSample[] */ | | | 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 | unsigned bNoQuery:1; /* Do not use this index to optimize queries */ unsigned bAscKeyBug:1; /* True if the bba7b69f9849b5bf bug applies */ unsigned bHasVCol:1; /* Index references one or more VIRTUAL columns */ unsigned bHasExpr:1; /* Index contains an expression, either a literal ** expression, or a reference to a VIRTUAL column */ #ifdef SQLITE_ENABLE_STAT4 int nSample; /* Number of elements in aSample[] */ int nSampleAlloc; /* Number of slots allocated to aSample[] */ int nSampleCol; /* Size of IndexSample.anEq[] and so on */ tRowcnt *aAvgEq; /* Average nEq values for keys not in aSample */ IndexSample *aSample; /* Samples of the left-most key */ tRowcnt *aiRowEst; /* Non-logarithmic stat1 data for this index */ tRowcnt nRowEst0; /* Non-logarithmic number of rows in the index */ #endif Bitmask colNotIdxed; /* Unindexed columns in pTab */ |
︙ | ︙ | |||
4344 4345 4346 4347 4348 4349 4350 4351 4352 4353 4354 4355 4356 4357 | ** occur in views. */ #endif int bLocaltimeFault; /* True to fail localtime() calls */ int (*xAltLocaltime)(const void*,void*); /* Alternative localtime() routine */ int iOnceResetThreshold; /* When to reset OP_Once counters */ u32 szSorterRef; /* Min size in bytes to use sorter-refs */ unsigned int iPrngSeed; /* Alternative fixed seed for the PRNG */ /* vvvv--- must be last ---vvv */ #ifdef SQLITE_DEBUG sqlite3_int64 aTune[SQLITE_NTUNE]; /* Tuning parameters */ #endif }; /* | > | 4413 4414 4415 4416 4417 4418 4419 4420 4421 4422 4423 4424 4425 4426 4427 | ** occur in views. */ #endif int bLocaltimeFault; /* True to fail localtime() calls */ int (*xAltLocaltime)(const void*,void*); /* Alternative localtime() routine */ int iOnceResetThreshold; /* When to reset OP_Once counters */ u32 szSorterRef; /* Min size in bytes to use sorter-refs */ unsigned int iPrngSeed; /* Alternative fixed seed for the PRNG */ int bTestSchemaCopy; /* True to test schema copies internally */ /* vvvv--- must be last ---vvv */ #ifdef SQLITE_DEBUG sqlite3_int64 aTune[SQLITE_NTUNE]; /* Tuning parameters */ #endif }; /* |
︙ | ︙ | |||
4398 4399 4400 4401 4402 4403 4404 4405 4406 4407 4408 4409 4410 4411 | struct WhereConst *pConst; /* WHERE clause constants */ struct RenameCtx *pRename; /* RENAME COLUMN context */ struct Table *pTab; /* Table of generated column */ struct CoveringIndexCheck *pCovIdxCk; /* Check for covering index */ SrcItem *pSrcItem; /* A single FROM clause item */ DbFixer *pFix; /* See sqlite3FixSelect() */ Mem *aMem; /* See sqlite3BtreeCursorHint() */ } u; }; /* ** The following structure contains information used by the sqliteFix... ** routines as they walk the parse tree to make database references ** explicit. | > | 4468 4469 4470 4471 4472 4473 4474 4475 4476 4477 4478 4479 4480 4481 4482 | struct WhereConst *pConst; /* WHERE clause constants */ struct RenameCtx *pRename; /* RENAME COLUMN context */ struct Table *pTab; /* Table of generated column */ struct CoveringIndexCheck *pCovIdxCk; /* Check for covering index */ SrcItem *pSrcItem; /* A single FROM clause item */ DbFixer *pFix; /* See sqlite3FixSelect() */ Mem *aMem; /* See sqlite3BtreeCursorHint() */ Schema *pSchema; } u; }; /* ** The following structure contains information used by the sqliteFix... ** routines as they walk the parse tree to make database references ** explicit. |
︙ | ︙ | |||
4881 4882 4883 4884 4885 4886 4887 4888 4889 4890 4891 4892 4893 4894 | void sqlite3ShowWith(const With*); void sqlite3ShowUpsert(const Upsert*); #ifndef SQLITE_OMIT_TRIGGER void sqlite3ShowTriggerStep(const TriggerStep*); void sqlite3ShowTriggerStepList(const TriggerStep*); void sqlite3ShowTrigger(const Trigger*); void sqlite3ShowTriggerList(const Trigger*); #endif #ifndef SQLITE_OMIT_WINDOWFUNC void sqlite3ShowWindow(const Window*); void sqlite3ShowWinFunc(const Window*); #endif #endif | > | 4952 4953 4954 4955 4956 4957 4958 4959 4960 4961 4962 4963 4964 4965 4966 | void sqlite3ShowWith(const With*); void sqlite3ShowUpsert(const Upsert*); #ifndef SQLITE_OMIT_TRIGGER void sqlite3ShowTriggerStep(const TriggerStep*); void sqlite3ShowTriggerStepList(const TriggerStep*); void sqlite3ShowTrigger(const Trigger*); void sqlite3ShowTriggerList(const Trigger*); void sqlite3WalkTrigger(Walker *pWalker, Trigger *pTrigger); #endif #ifndef SQLITE_OMIT_WINDOWFUNC void sqlite3ShowWindow(const Window*); void sqlite3ShowWinFunc(const Window*); #endif #endif |
︙ | ︙ | |||
5529 5530 5531 5532 5533 5534 5535 5536 5537 5538 5539 5540 5541 5542 5543 | #ifdef SQLITE_ENABLE_STAT4 int sqlite3Stat4ProbeSetValue( Parse*,Index*,UnpackedRecord**,Expr*,int,int,int*); int sqlite3Stat4ValueFromExpr(Parse*, Expr*, u8, sqlite3_value**); void sqlite3Stat4ProbeFree(UnpackedRecord*); int sqlite3Stat4Column(sqlite3*, const void*, int, int, sqlite3_value**); char sqlite3IndexColumnAffinity(sqlite3*, Index*, int); #endif /* ** The interface to the LEMON-generated parser */ #ifndef SQLITE_AMALGAMATION void *sqlite3ParserAlloc(void*(*)(u64), Parse*); void sqlite3ParserFree(void*, void(*)(void*)); | > > > | 5601 5602 5603 5604 5605 5606 5607 5608 5609 5610 5611 5612 5613 5614 5615 5616 5617 5618 | #ifdef SQLITE_ENABLE_STAT4 int sqlite3Stat4ProbeSetValue( Parse*,Index*,UnpackedRecord**,Expr*,int,int,int*); int sqlite3Stat4ValueFromExpr(Parse*, Expr*, u8, sqlite3_value**); void sqlite3Stat4ProbeFree(UnpackedRecord*); int sqlite3Stat4Column(sqlite3*, const void*, int, int, sqlite3_value**); char sqlite3IndexColumnAffinity(sqlite3*, Index*, int); int sqlite3AnalyzeCopyStat4(sqlite3*, Index*, Index *pFrom); #endif void sqlite3SchemaCopy(sqlite3 *db, Schema*, Schema*); /* ** The interface to the LEMON-generated parser */ #ifndef SQLITE_AMALGAMATION void *sqlite3ParserAlloc(void*(*)(u64), Parse*); void sqlite3ParserFree(void*, void(*)(void*)); |
︙ | ︙ |
Changes to src/sqliteLimit.h.
︙ | ︙ | |||
84 85 86 87 88 89 90 91 92 | */ #ifndef SQLITE_MAX_VDBE_OP # define SQLITE_MAX_VDBE_OP 250000000 #endif /* ** The maximum number of arguments to an SQL function. */ #ifndef SQLITE_MAX_FUNCTION_ARG | > > > > | | 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 | */ #ifndef SQLITE_MAX_VDBE_OP # define SQLITE_MAX_VDBE_OP 250000000 #endif /* ** The maximum number of arguments to an SQL function. ** ** This value has a hard upper limit of 32767 due to storage ** constraints (it needs to fit inside a i16). We keep it ** lower than that to prevent abuse. */ #ifndef SQLITE_MAX_FUNCTION_ARG # define SQLITE_MAX_FUNCTION_ARG 1000 #endif /* ** The suggested maximum number of in-memory pages to use for ** the main database table and for temporary tables. ** ** IMPLEMENTATION-OF: R-30185-15359 The default suggested cache size is -2000, |
︙ | ︙ |
Changes to src/test1.c.
︙ | ︙ | |||
2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 | aBuf = ckalloc(nByte); sqlite3_randomness(nByte, aBuf); Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(aBuf, nByte)); ckfree(aBuf); return TCL_OK; } /* ** tclcmd: sqlite3_commit_status db DBNAME OP */ static int SQLITE_TCLAPI test_commit_status( ClientData clientData, /* Unused */ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 | aBuf = ckalloc(nByte); sqlite3_randomness(nByte, aBuf); Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(aBuf, nByte)); ckfree(aBuf); return TCL_OK; } /* ** Usage: sqlite3_schema_copy DBTO DBNAMETO DBFROM DBNAMEFROM ** ** DBTO and DBFROM must be database handles created using the [sqlite3] ** command. DBNAMETO and DBNAMEFROM are database names - "main", "temp" ** or the name of an attached database. */ static int SQLITE_TCLAPI test_schema_copy( void * clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ sqlite3 *dbTo = 0; sqlite3 *dbFrom = 0; const char *zTo = 0; const char *zFrom = 0; int rc = SQLITE_OK; if( objc!=5 ){ Tcl_WrongNumArgs(interp, 1, objv, "DBTO DBNAMETO DBFROM DBFROMNAME"); return TCL_ERROR; } if( getDbPointer(interp, Tcl_GetString(objv[1]), &dbTo) ) return TCL_ERROR; if( getDbPointer(interp, Tcl_GetString(objv[3]), &dbFrom) ) return TCL_ERROR; zTo = Tcl_GetString(objv[2]); zFrom = Tcl_GetString(objv[4]); rc = sqlite3_schema_copy(dbTo, zTo, dbFrom, zFrom); Tcl_ResetResult(interp); Tcl_AppendResult(interp, sqlite3ErrName(rc), 0); return TCL_OK; } /* ** tclcmd: sqlite3_commit_status db DBNAME OP */ static int SQLITE_TCLAPI test_commit_status( ClientData clientData, /* Unused */ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ |
︙ | ︙ | |||
7912 7913 7914 7915 7916 7917 7918 7919 7920 7921 7922 7923 7924 7925 | int i; } aVerb[] = { { "SQLITE_TESTCTRL_LOCALTIME_FAULT", SQLITE_TESTCTRL_LOCALTIME_FAULT }, { "SQLITE_TESTCTRL_SORTER_MMAP", SQLITE_TESTCTRL_SORTER_MMAP }, { "SQLITE_TESTCTRL_IMPOSTER", SQLITE_TESTCTRL_IMPOSTER }, { "SQLITE_TESTCTRL_INTERNAL_FUNCTIONS", SQLITE_TESTCTRL_INTERNAL_FUNCTIONS}, { "SQLITE_TESTCTRL_FK_NO_ACTION", SQLITE_TESTCTRL_FK_NO_ACTION}, { 0, 0 } }; int iVerb; int iFlag; int rc; if( objc<2 ){ | > | 7947 7948 7949 7950 7951 7952 7953 7954 7955 7956 7957 7958 7959 7960 7961 | int i; } aVerb[] = { { "SQLITE_TESTCTRL_LOCALTIME_FAULT", SQLITE_TESTCTRL_LOCALTIME_FAULT }, { "SQLITE_TESTCTRL_SORTER_MMAP", SQLITE_TESTCTRL_SORTER_MMAP }, { "SQLITE_TESTCTRL_IMPOSTER", SQLITE_TESTCTRL_IMPOSTER }, { "SQLITE_TESTCTRL_INTERNAL_FUNCTIONS", SQLITE_TESTCTRL_INTERNAL_FUNCTIONS}, { "SQLITE_TESTCTRL_FK_NO_ACTION", SQLITE_TESTCTRL_FK_NO_ACTION}, { "SQLITE_TESTCTRL_SCHEMACOPY", SQLITE_TESTCTRL_SCHEMACOPY}, { 0, 0 } }; int iVerb; int iFlag; int rc; if( objc<2 ){ |
︙ | ︙ | |||
7993 7994 7995 7996 7997 7998 7999 8000 8001 8002 8003 8004 8005 8006 | if( getDbPointer(interp, Tcl_GetString(objv[2]), &db) ) return TCL_ERROR; zDbName = Tcl_GetString(objv[3]); if( Tcl_GetIntFromObj(interp, objv[4], &onOff) ) return TCL_ERROR; if( Tcl_GetIntFromObj(interp, objv[5], &tnum) ) return TCL_ERROR; sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, db, zDbName, onOff, tnum); break; } } Tcl_ResetResult(interp); return TCL_OK; } #if SQLITE_OS_UNIX | > > > > > > > > > > > > | 8029 8030 8031 8032 8033 8034 8035 8036 8037 8038 8039 8040 8041 8042 8043 8044 8045 8046 8047 8048 8049 8050 8051 8052 8053 8054 | if( getDbPointer(interp, Tcl_GetString(objv[2]), &db) ) return TCL_ERROR; zDbName = Tcl_GetString(objv[3]); if( Tcl_GetIntFromObj(interp, objv[4], &onOff) ) return TCL_ERROR; if( Tcl_GetIntFromObj(interp, objv[5], &tnum) ) return TCL_ERROR; sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, db, zDbName, onOff, tnum); break; } case SQLITE_TESTCTRL_SCHEMACOPY: { int val = 0; sqlite3 *db = 0; if( objc!=3 ){ Tcl_WrongNumArgs(interp, 2, objv, "BOOLEAN"); return TCL_ERROR; } if( Tcl_GetBooleanFromObj(interp, objv[2], &val) ) return TCL_ERROR; sqlite3_test_control(SQLITE_TESTCTRL_SCHEMACOPY, val); break; } } Tcl_ResetResult(interp); return TCL_OK; } #if SQLITE_OS_UNIX |
︙ | ︙ | |||
9408 9409 9410 9411 9412 9413 9414 9415 9416 9417 9418 9419 9420 9421 | { "sqlite3_unregister_cksumvfs", test_unregister_cksumvfs, 0 }, { "number_of_cores", guess_number_of_cores, 0 }, #ifndef SQLITE_OMIT_VIRTUALTABLE { "create_null_module", test_create_null_module, 0 }, #endif { "sqlite3_commit_status", test_commit_status, 0 }, { "sqlite3_randomness", test_sqlite3_randomness, 0 }, }; static int bitmask_size = sizeof(Bitmask)*8; static int longdouble_size = sizeof(LONGDOUBLE_TYPE); int i; extern int sqlite3_sync_count, sqlite3_fullsync_count; extern int sqlite3_opentemp_count; extern int sqlite3_like_count; | > | 9456 9457 9458 9459 9460 9461 9462 9463 9464 9465 9466 9467 9468 9469 9470 | { "sqlite3_unregister_cksumvfs", test_unregister_cksumvfs, 0 }, { "number_of_cores", guess_number_of_cores, 0 }, #ifndef SQLITE_OMIT_VIRTUALTABLE { "create_null_module", test_create_null_module, 0 }, #endif { "sqlite3_commit_status", test_commit_status, 0 }, { "sqlite3_randomness", test_sqlite3_randomness, 0 }, { "sqlite3_schema_copy", test_schema_copy, 0 }, }; static int bitmask_size = sizeof(Bitmask)*8; static int longdouble_size = sizeof(LONGDOUBLE_TYPE); int i; extern int sqlite3_sync_count, sqlite3_fullsync_count; extern int sqlite3_opentemp_count; extern int sqlite3_like_count; |
︙ | ︙ |
Changes to src/test_func.c.
︙ | ︙ | |||
769 770 771 772 773 774 775 | rc = sqlite3_create_function(db, "tx", 1, SQLITE_UTF8, 0, 0, tStep, 0); if( rc!=SQLITE_MISUSE ) goto abuse_err; rc = sqlite3_create_function(db, "tx", -2, SQLITE_UTF8, 0, tStep, 0, 0); if( rc!=SQLITE_MISUSE ) goto abuse_err; | | | | 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 | rc = sqlite3_create_function(db, "tx", 1, SQLITE_UTF8, 0, 0, tStep, 0); if( rc!=SQLITE_MISUSE ) goto abuse_err; rc = sqlite3_create_function(db, "tx", -2, SQLITE_UTF8, 0, tStep, 0, 0); if( rc!=SQLITE_MISUSE ) goto abuse_err; rc = sqlite3_create_function(db, "tx", 32768, SQLITE_UTF8, 0, tStep, 0, 0); if( rc!=SQLITE_MISUSE ) goto abuse_err; rc = sqlite3_create_function(db, "funcxx" "_123456789_123456789_123456789_123456789_123456789" "_123456789_123456789_123456789_123456789_123456789" "_123456789_123456789_123456789_123456789_123456789" "_123456789_123456789_123456789_123456789_123456789" "_123456789_123456789_123456789_123456789_123456789", 1, SQLITE_UTF8, 0, tStep, 0, 0); if( rc!=SQLITE_MISUSE ) goto abuse_err; /* This last function registration should actually work. Generate ** a no-op function (that always returns NULL) and which has the ** maximum-length function name and the maximum number of parameters. */ sqlite3_limit(db, SQLITE_LIMIT_FUNCTION_ARG, 1000000); mxArg = sqlite3_limit(db, SQLITE_LIMIT_FUNCTION_ARG, -1); rc = sqlite3_create_function(db, "nullx" "_123456789_123456789_123456789_123456789_123456789" "_123456789_123456789_123456789_123456789_123456789" "_123456789_123456789_123456789_123456789_123456789" "_123456789_123456789_123456789_123456789_123456789" "_123456789_123456789_123456789_123456789_123456789", |
︙ | ︙ |
Changes to src/trigger.c.
︙ | ︙ | |||
1405 1406 1407 1408 1409 1410 1411 | (v, "Call: %s.%s", (p->zName?p->zName:"fkey"), onErrorText(orconf))); /* Set the P5 operand of the OP_Program instruction to non-zero if ** recursive invocation of this trigger program is disallowed. Recursive ** invocation is disallowed if (a) the sub-program is really a trigger, ** not a foreign key action, and (b) the flag to enable recursive triggers ** is clear. */ | | | 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 | (v, "Call: %s.%s", (p->zName?p->zName:"fkey"), onErrorText(orconf))); /* Set the P5 operand of the OP_Program instruction to non-zero if ** recursive invocation of this trigger program is disallowed. Recursive ** invocation is disallowed if (a) the sub-program is really a trigger, ** not a foreign key action, and (b) the flag to enable recursive triggers ** is clear. */ sqlite3VdbeChangeP5(v, (u16)bRecursive); } } /* ** This is called to code the required FOR EACH ROW triggers for an operation ** on table pTab. The operation to code triggers for (INSERT, UPDATE or DELETE) ** is given by the op parameter. The tr_tm parameter determines whether the |
︙ | ︙ |
Changes to src/vdbe.c.
︙ | ︙ | |||
3951 3952 3953 3954 3955 3956 3957 3958 3959 3960 3961 3962 3963 3964 | assert( desiredAutoCommit==1 || iRollback==0 ); assert( desiredAutoCommit==0 || bConcurrent==0 ); assert( db->autoCommit==0 || db->eConcurrent==CONCURRENT_NONE ); assert( db->nVdbeActive>0 ); /* At least this one VM is active */ assert( p->bIsReader ); if( desiredAutoCommit!=db->autoCommit ){ if( iRollback ){ assert( desiredAutoCommit==1 ); sqlite3RollbackAll(db, SQLITE_ABORT_ROLLBACK); db->autoCommit = 1; db->eConcurrent = CONCURRENT_NONE; }else if( desiredAutoCommit && (db->nVdbeWrite>0 || (db->eConcurrent && db->nVdbeActive>1)) ){ | > > > > > > > | 3951 3952 3953 3954 3955 3956 3957 3958 3959 3960 3961 3962 3963 3964 3965 3966 3967 3968 3969 3970 3971 | assert( desiredAutoCommit==1 || iRollback==0 ); assert( desiredAutoCommit==0 || bConcurrent==0 ); assert( db->autoCommit==0 || db->eConcurrent==CONCURRENT_NONE ); assert( db->nVdbeActive>0 ); /* At least this one VM is active */ assert( p->bIsReader ); if( desiredAutoCommit!=db->autoCommit ){ u64 aCommit[COMMIT_TIME_N]; memset(aCommit, 0, sizeof(aCommit)); if( iRollback==0 ){ sqlite3CommitTimeSet(aCommit, COMMIT_TIME_START); } if( iRollback ){ assert( desiredAutoCommit==1 ); sqlite3RollbackAll(db, SQLITE_ABORT_ROLLBACK); db->autoCommit = 1; db->eConcurrent = CONCURRENT_NONE; }else if( desiredAutoCommit && (db->nVdbeWrite>0 || (db->eConcurrent && db->nVdbeActive>1)) ){ |
︙ | ︙ | |||
3975 3976 3977 3978 3979 3980 3981 3982 3983 3984 3985 3986 3987 3988 3989 3990 3991 3992 3993 3994 3995 3996 3997 3998 3999 4000 4001 4002 4003 4004 | rc = SQLITE_BUSY; goto abort_due_to_error; }else if( (rc = sqlite3VdbeCheckFk(p, 1))!=SQLITE_OK ){ goto vdbe_return; }else{ db->autoCommit = (u8)desiredAutoCommit; } hrc = sqlite3VdbeHalt(p); if( (hrc & 0xFF)==SQLITE_BUSY ){ p->pc = (int)(pOp - aOp); db->autoCommit = (u8)(1-desiredAutoCommit); p->rc = hrc; rc = SQLITE_BUSY; goto vdbe_return; } assert( bConcurrent==CONCURRENT_NONE || bConcurrent==CONCURRENT_OPEN ); db->eConcurrent = (u8)bConcurrent; sqlite3CloseSavepoints(db); if( p->rc==SQLITE_OK ){ rc = SQLITE_DONE; }else{ rc = SQLITE_ERROR; } goto vdbe_return; }else{ sqlite3VdbeError(p, (!desiredAutoCommit)?"cannot start a transaction within a transaction":( (iRollback)?"cannot rollback - no transaction is active": "cannot commit - no transaction is active")); | > > > > > > | 3982 3983 3984 3985 3986 3987 3988 3989 3990 3991 3992 3993 3994 3995 3996 3997 3998 3999 4000 4001 4002 4003 4004 4005 4006 4007 4008 4009 4010 4011 4012 4013 4014 4015 4016 4017 | rc = SQLITE_BUSY; goto abort_due_to_error; }else if( (rc = sqlite3VdbeCheckFk(p, 1))!=SQLITE_OK ){ goto vdbe_return; }else{ db->autoCommit = (u8)desiredAutoCommit; } sqlite3CommitTimeSet(aCommit, COMMIT_TIME_BEFORE_HALT); p->aCommitTime = aCommit; hrc = sqlite3VdbeHalt(p); p->aCommitTime = 0; sqlite3CommitTimeSet(aCommit, COMMIT_TIME_AFTER_HALT); if( (hrc & 0xFF)==SQLITE_BUSY ){ p->pc = (int)(pOp - aOp); db->autoCommit = (u8)(1-desiredAutoCommit); p->rc = hrc; rc = SQLITE_BUSY; goto vdbe_return; } assert( bConcurrent==CONCURRENT_NONE || bConcurrent==CONCURRENT_OPEN ); db->eConcurrent = (u8)bConcurrent; sqlite3CloseSavepoints(db); if( p->rc==SQLITE_OK ){ rc = SQLITE_DONE; }else{ rc = SQLITE_ERROR; } sqlite3CommitTimeSet(aCommit, COMMIT_TIME_FINISH); if( desiredAutoCommit && !iRollback ) sqlite3CommitTimeLog(aCommit); goto vdbe_return; }else{ sqlite3VdbeError(p, (!desiredAutoCommit)?"cannot start a transaction within a transaction":( (iRollback)?"cannot rollback - no transaction is active": "cannot commit - no transaction is active")); |
︙ | ︙ |
Changes to src/vdbe.h.
︙ | ︙ | |||
421 422 423 424 425 426 427 428 | void sqlite3VdbePrintOp(FILE*, int, VdbeOp*); #endif #if defined(SQLITE_ENABLE_CURSOR_HINTS) && defined(SQLITE_DEBUG) int sqlite3CursorRangeHintExprCheck(Walker *pWalker, Expr *pExpr); #endif #endif /* SQLITE_VDBE_H */ | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 488 489 | void sqlite3VdbePrintOp(FILE*, int, VdbeOp*); #endif #if defined(SQLITE_ENABLE_CURSOR_HINTS) && defined(SQLITE_DEBUG) int sqlite3CursorRangeHintExprCheck(Walker *pWalker, Expr *pExpr); #endif #define COMMIT_TIME_START 0 #define COMMIT_TIME_BEFORE_HALT 1 #define COMMIT_TIME_BEFORE_VDBECOMMIT 2 #define COMMIT_TIME_BEFORE_PHASEONE 3 #define COMMIT_TIME_START_FIXUNLOCKED 4 #define COMMIT_TIME_START_RELOCATE1 5 #define COMMIT_TIME_START_RELOCATE2 6 #define COMMIT_TIME_OTHERWRITERS 7 #define COMMIT_TIME_RELOCATE1COUNT 8 #define COMMIT_TIME_RELOCATE2COUNT 9 #define COMMIT_TIME_RELOCATE2_READUS 10 #define COMMIT_TIME_RELOCATE2_READCOUNT 11 #define COMMIT_TIME_RELOCATE2_EXACTUS 12 #define COMMIT_TIME_RELOCATE2_ALLOCATEUS 13 #define COMMIT_TIME_RELOCATE2_RELOCATEUS 14 #define COMMIT_TIME_AFTER_FIXUNLOCKED 15 #define COMMIT_TIME_BEFORE_WALFRAMES 16 #define COMMIT_TIME_AFTER_CHANGECOUNTER 17 #define COMMIT_TIME_AFTER_RESTARTLOG 18 #define COMMIT_TIME_AFTER_WRITEHDR 19 #define COMMIT_TIME_OSWRITE 20 #define COMMIT_TIME_AFTER_WRITEFRAMES 21 #define COMMIT_TIME_NFRAME 22 #define COMMIT_TIME_HASHMAPUS 23 #define COMMIT_TIME_BEFORE_WALINDEX 24 #define COMMIT_TIME_WALINDEX_HASHGETUS 25 #define COMMIT_TIME_WALINDEX_MEMSETUS 26 #define COMMIT_TIME_WALINDEX_CLEANUPUS 27 #define COMMIT_TIME_WALINDEX_ENTRYUS 28 #define COMMIT_TIME_AFTER_WALINDEX 29 #define COMMIT_TIME_AFTER_WALINDEXHDR 30 #define COMMIT_TIME_WALFRAMESFLAGS 31 #define COMMIT_TIME_AFTER_WALFRAMES 32 #define COMMIT_TIME_BEFORE_PHASETWO 33 #define COMMIT_TIME_AFTER_PHASETWO 34 #define COMMIT_TIME_AFTER_VDBECOMMIT 35 #define COMMIT_TIME_AFTER_HALT 36 #define COMMIT_TIME_FINISH 37 #define COMMIT_TIME_N 38 /* #define COMMIT_TIME_TIMEOUT (2*1000*1000) */ #define COMMIT_TIME_TIMEOUT (10*1000) /* 10ms threshold */ void sqlite3CommitTimeLog(u64*); u64 sqlite3STimeNow(); void sqlite3CommitTimeSet(u64*, int); #endif /* SQLITE_VDBE_H */ |
Changes to src/vdbeInt.h.
︙ | ︙ | |||
389 390 391 392 393 394 395 | FuncDef *pFunc; /* Pointer to function information */ Mem *pMem; /* Memory cell used to store aggregate context */ Vdbe *pVdbe; /* The VM that owns this context */ int iOp; /* Instruction number of OP_Function */ int isError; /* Error code returned by the function. */ u8 enc; /* Encoding to use for results */ u8 skipFlag; /* Skip accumulator loading if true */ | | | 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 | FuncDef *pFunc; /* Pointer to function information */ Mem *pMem; /* Memory cell used to store aggregate context */ Vdbe *pVdbe; /* The VM that owns this context */ int iOp; /* Instruction number of OP_Function */ int isError; /* Error code returned by the function. */ u8 enc; /* Encoding to use for results */ u8 skipFlag; /* Skip accumulator loading if true */ u16 argc; /* Number of arguments */ sqlite3_value *argv[1]; /* Argument set */ }; /* A bitfield type for use inside of structures. Always follow with :N where ** N is the number of bits. */ typedef unsigned bft; /* Bit Field Type */ |
︙ | ︙ | |||
510 511 512 513 514 515 516 517 518 519 520 521 522 523 | u32 expmask; /* Binding to these vars invalidates VM */ SubProgram *pProgram; /* Linked list of all sub-programs used by VM */ AuxData *pAuxData; /* Linked list of auxdata allocations */ #ifdef SQLITE_ENABLE_STMT_SCANSTATUS int nScan; /* Entries in aScan[] */ ScanStatus *aScan; /* Scan definitions for sqlite3_stmt_scanstatus() */ #endif }; /* ** The following are allowed values for Vdbe.eVdbeState */ #define VDBE_INIT_STATE 0 /* Prepared statement under construction */ #define VDBE_READY_STATE 1 /* Ready to run but not yet started */ | > | 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 | u32 expmask; /* Binding to these vars invalidates VM */ SubProgram *pProgram; /* Linked list of all sub-programs used by VM */ AuxData *pAuxData; /* Linked list of auxdata allocations */ #ifdef SQLITE_ENABLE_STMT_SCANSTATUS int nScan; /* Entries in aScan[] */ ScanStatus *aScan; /* Scan definitions for sqlite3_stmt_scanstatus() */ #endif u64 *aCommitTime; }; /* ** The following are allowed values for Vdbe.eVdbeState */ #define VDBE_INIT_STATE 0 /* Prepared statement under construction */ #define VDBE_READY_STATE 1 /* Ready to run but not yet started */ |
︙ | ︙ |
Changes to src/vdbeaux.c.
︙ | ︙ | |||
10 11 12 13 14 15 16 17 18 19 20 21 22 23 | ** ************************************************************************* ** This file contains code used for creating, destroying, and populating ** a VDBE (or an "sqlite3_stmt" as it is known to the outside world.) */ #include "sqliteInt.h" #include "vdbeInt.h" /* Forward references */ static void freeEphemeralFunction(sqlite3 *db, FuncDef *pDef); static void vdbeFreeOpArray(sqlite3 *, Op *, int); /* ** Create a new virtual database engine. | > > | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | ** ************************************************************************* ** This file contains code used for creating, destroying, and populating ** a VDBE (or an "sqlite3_stmt" as it is known to the outside world.) */ #include "sqliteInt.h" #include "vdbeInt.h" #include "btreeInt.h" /* Forward references */ static void freeEphemeralFunction(sqlite3 *db, FuncDef *pDef); static void vdbeFreeOpArray(sqlite3 *, Op *, int); /* ** Create a new virtual database engine. |
︙ | ︙ | |||
2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 | ** string, it means the main database is :memory: or a temp file. In ** that case we do not support atomic multi-file commits, so use the ** simple case then too. */ if( 0==sqlite3Strlen30(sqlite3BtreeGetFilename(db->aDb[0].pBt)) || nTrans<=1 ){ for(i=0; rc==SQLITE_OK && i<db->nDb; i++){ Btree *pBt = db->aDb[i].pBt; if( pBt ){ rc = sqlite3BtreeCommitPhaseOne(pBt, 0); } } /* Do the commit only if all databases successfully complete phase 1. ** If one of the BtreeCommitPhaseOne() calls fails, this indicates an ** IO error while deleting or truncating a journal file. It is unlikely, ** but could happen. In this case abandon processing and return the error. */ for(i=0; rc==SQLITE_OK && i<db->nDb; i++){ Btree *pBt = db->aDb[i].pBt; if( pBt ){ rc = sqlite3BtreeCommitPhaseTwo(pBt, 0); } } if( rc==SQLITE_OK ){ sqlite3VtabCommit(db); } } /* The complex case - There is a multi-file write-transaction active. ** This requires a super-journal file to ensure the transaction is | > > > > > > > > > | 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 | ** string, it means the main database is :memory: or a temp file. In ** that case we do not support atomic multi-file commits, so use the ** simple case then too. */ if( 0==sqlite3Strlen30(sqlite3BtreeGetFilename(db->aDb[0].pBt)) || nTrans<=1 ){ sqlite3CommitTimeSet(p->aCommitTime, COMMIT_TIME_BEFORE_PHASEONE); for(i=0; rc==SQLITE_OK && i<db->nDb; i++){ Btree *pBt = db->aDb[i].pBt; if( pBt ){ pBt->pBt->aCommitTime = p->aCommitTime; rc = sqlite3BtreeCommitPhaseOne(pBt, 0); pBt->pBt->aCommitTime = 0; } } sqlite3CommitTimeSet(p->aCommitTime, COMMIT_TIME_BEFORE_PHASETWO); /* Do the commit only if all databases successfully complete phase 1. ** If one of the BtreeCommitPhaseOne() calls fails, this indicates an ** IO error while deleting or truncating a journal file. It is unlikely, ** but could happen. In this case abandon processing and return the error. */ for(i=0; rc==SQLITE_OK && i<db->nDb; i++){ Btree *pBt = db->aDb[i].pBt; if( pBt ){ pBt->pBt->aCommitTime = p->aCommitTime; rc = sqlite3BtreeCommitPhaseTwo(pBt, 0); pBt->pBt->aCommitTime = 0; } } sqlite3CommitTimeSet(p->aCommitTime, COMMIT_TIME_AFTER_PHASETWO); if( rc==SQLITE_OK ){ sqlite3VtabCommit(db); } } /* The complex case - There is a multi-file write-transaction active. ** This requires a super-journal file to ensure the transaction is |
︙ | ︙ | |||
3410 3411 3412 3413 3414 3415 3416 3417 3418 3419 3420 3421 3422 3423 3424 | rc = SQLITE_CORRUPT; db->flags &= ~SQLITE_CorruptRdOnly; }else{ /* The auto-commit flag is true, the vdbe program was successful ** or hit an 'OR FAIL' constraint and there are no deferred foreign ** key constraints to hold up the transaction. This means a commit ** is required. */ rc = vdbeCommit(db, p); } if( (rc & 0xFF)==SQLITE_BUSY && p->readOnly ){ sqlite3VdbeLeave(p); return rc; }else if( rc!=SQLITE_OK ){ sqlite3SystemError(db, rc); p->rc = rc; | > > | 3421 3422 3423 3424 3425 3426 3427 3428 3429 3430 3431 3432 3433 3434 3435 3436 3437 | rc = SQLITE_CORRUPT; db->flags &= ~SQLITE_CorruptRdOnly; }else{ /* The auto-commit flag is true, the vdbe program was successful ** or hit an 'OR FAIL' constraint and there are no deferred foreign ** key constraints to hold up the transaction. This means a commit ** is required. */ sqlite3CommitTimeSet(p->aCommitTime, COMMIT_TIME_BEFORE_VDBECOMMIT); rc = vdbeCommit(db, p); sqlite3CommitTimeSet(p->aCommitTime, COMMIT_TIME_AFTER_VDBECOMMIT); } if( (rc & 0xFF)==SQLITE_BUSY && p->readOnly ){ sqlite3VdbeLeave(p); return rc; }else if( rc!=SQLITE_OK ){ sqlite3SystemError(db, rc); p->rc = rc; |
︙ | ︙ | |||
5441 5442 5443 5444 5445 5446 5447 5448 5449 5450 5451 5452 5453 5454 | int sqlite3CursorRangeHintExprCheck(Walker *pWalker, Expr *pExpr){ if( pExpr->op==TK_REGISTER ){ assert( (pWalker->u.aMem[pExpr->iTable].flags & MEM_Undefined)==0 ); } return WRC_Continue; } #endif /* SQLITE_ENABLE_CURSOR_HINTS && SQLITE_DEBUG */ #ifndef SQLITE_OMIT_VIRTUALTABLE /* ** Transfer error message text from an sqlite3_vtab.zErrMsg (text stored ** in memory obtained from sqlite3_malloc) into a Vdbe.zErrMsg (text stored ** in memory obtained from sqlite3DbMalloc). */ | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 5454 5455 5456 5457 5458 5459 5460 5461 5462 5463 5464 5465 5466 5467 5468 5469 5470 5471 5472 5473 5474 5475 5476 5477 5478 5479 5480 5481 5482 5483 5484 5485 5486 5487 5488 5489 5490 5491 5492 5493 5494 5495 5496 5497 5498 5499 5500 5501 5502 5503 5504 5505 5506 5507 5508 5509 5510 5511 5512 5513 5514 5515 5516 5517 5518 5519 5520 5521 5522 5523 5524 5525 5526 5527 5528 5529 5530 5531 5532 5533 5534 5535 5536 5537 5538 5539 5540 5541 5542 5543 5544 5545 5546 5547 5548 5549 5550 5551 5552 5553 5554 5555 5556 5557 5558 5559 5560 5561 5562 | int sqlite3CursorRangeHintExprCheck(Walker *pWalker, Expr *pExpr){ if( pExpr->op==TK_REGISTER ){ assert( (pWalker->u.aMem[pExpr->iTable].flags & MEM_Undefined)==0 ); } return WRC_Continue; } #endif /* SQLITE_ENABLE_CURSOR_HINTS && SQLITE_DEBUG */ #include <sys/time.h> void sqlite3CommitTimeLog(u64 *aCommit){ u64 i1 = aCommit[COMMIT_TIME_START]; assert( COMMIT_TIME_START==0 && COMMIT_TIME_FINISH==COMMIT_TIME_N-1 ); if( aCommit[COMMIT_TIME_FINISH]>(i1+COMMIT_TIME_TIMEOUT) ){ char *zStr = 0; int ii; for(ii=1; ii<COMMIT_TIME_N; ii++){ int iVal; const char *zHash = ""; const char *zU = ""; if( ii==COMMIT_TIME_RELOCATE1COUNT || ii==COMMIT_TIME_RELOCATE2COUNT || ii==COMMIT_TIME_OTHERWRITERS || ii==COMMIT_TIME_NFRAME || ii==COMMIT_TIME_RELOCATE2_READCOUNT ){ iVal = (int)aCommit[ii]; zHash = "#"; }else if( ii==COMMIT_TIME_OSWRITE || ii==COMMIT_TIME_RELOCATE2_READUS || ii==COMMIT_TIME_RELOCATE2_ALLOCATEUS || ii==COMMIT_TIME_RELOCATE2_RELOCATEUS || ii==COMMIT_TIME_HASHMAPUS || ii==COMMIT_TIME_RELOCATE2_EXACTUS || ii==COMMIT_TIME_WALINDEX_HASHGETUS || ii==COMMIT_TIME_WALINDEX_CLEANUPUS || ii==COMMIT_TIME_WALINDEX_ENTRYUS || ii==COMMIT_TIME_WALINDEX_MEMSETUS ){ iVal = (int)aCommit[ii]; zU = "us"; }else if( ii==COMMIT_TIME_WALFRAMESFLAGS ){ iVal = (int)aCommit[ii]; zHash = "flags="; }else{ iVal = (aCommit[ii]==0 ? 0 : (int)(aCommit[ii] - i1)); } zStr = sqlite3_mprintf("%z%s%s%d%s", zStr, (zStr?", ":""),zHash,iVal,zU); } sqlite3_log(SQLITE_WARNING, "slow commit (v=22): (%s)", zStr); sqlite3_free(zStr); } } u64 sqlite3STimeNow(){ struct timeval time; gettimeofday(&time, 0); return ((u64)time.tv_sec * 1000000 + (u64)time.tv_usec); } void sqlite3CommitTimeSet(u64 *aCommit, int iCommit){ if( aCommit && aCommit[iCommit]==0 ){ aCommit[iCommit] = sqlite3STimeNow(); } } void sqlite3PrepareTimeLog(const char *zSql, int nSql, u64 *aPrepare){ u64 i1 = aPrepare[PREPARE_TIME_START]; assert( PREPARE_TIME_START==0 && PREPARE_TIME_FINISH==PREPARE_TIME_N-1 ); if( aPrepare[PREPARE_TIME_FINISH]>(i1+PREPARE_TIME_TIMEOUT) ){ int nByte = nSql; char *zStr = 0; int ii; for(ii=1; ii<PREPARE_TIME_N; ii++){ zStr = sqlite3_mprintf("%z%s%d", zStr, (zStr?", ":""), (aPrepare[ii]==0 ? 0 : (int)(aPrepare[ii] - i1)) ); } if( nByte<0 ){ nByte = sqlite3Strlen30(zSql); } sqlite3_log(SQLITE_WARNING, "slow prepare (v=22): (%s) [%.*s]", zStr, nByte, zSql ); sqlite3_free(zStr); } } void sqlite3SchemaTimeLog(u64 *aSchema, const char *zFile){ u64 i1 = aSchema[SCHEMA_TIME_START]; assert( SCHEMA_TIME_START==0 && SCHEMA_TIME_FINISH==SCHEMA_TIME_N-1 ); if( aSchema[SCHEMA_TIME_FINISH]>(i1+SCHEMA_TIME_TIMEOUT) ){ char *zStr = 0; int ii; for(ii=1; ii<SCHEMA_TIME_N; ii++){ int val = aSchema[ii]; if( val!=0 && ii!=SCHEMA_TIME_STAT4_Q2_BODYUS && ii!=SCHEMA_TIME_STAT4_GROWUS ){ val -= i1; } zStr = sqlite3_mprintf("%z%s%d", zStr, (zStr?", ":""), val); } sqlite3_log(SQLITE_WARNING, "slow schema (%s) (v=22): (%s)", zFile, zStr); sqlite3_free(zStr); } } #ifndef SQLITE_OMIT_VIRTUALTABLE /* ** Transfer error message text from an sqlite3_vtab.zErrMsg (text stored ** in memory obtained from sqlite3_malloc) into a Vdbe.zErrMsg (text stored ** in memory obtained from sqlite3DbMalloc). */ |
︙ | ︙ |
Changes to src/wal.c.
︙ | ︙ | |||
454 455 456 457 458 459 460 | ** header checksum is correct but (b) the version field is not ** recognized, the operation fails with SQLITE_CANTOPEN. ** ** Currently, clients support both version-1 ("journal_mode=wal") and ** version-2 ("journal_mode=wal2"). Legacy clients may support version-1 ** only. */ | > > > > | | > > > > > > > > > > > > > > | 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 | ** header checksum is correct but (b) the version field is not ** recognized, the operation fails with SQLITE_CANTOPEN. ** ** Currently, clients support both version-1 ("journal_mode=wal") and ** version-2 ("journal_mode=wal2"). Legacy clients may support version-1 ** only. */ #ifdef SQLITE_WAL_BIGHASH # define WAL_VERSION1 3007001 /* For "journal_mode=wal" */ # define WAL_VERSION2 3021001 /* For "journal_mode=wal2" */ #else # define WAL_VERSION1 3007000 /* For "journal_mode=wal" */ # define WAL_VERSION2 3021000 /* For "journal_mode=wal2" */ #endif #define SQLITE_ENABLE_WAL2NOCKSUM 1 #ifdef SQLITE_ENABLE_WAL2NOCKSUM # undef WAL_VERSION2 # define WAL_VERSION2 3048000 /* For "journal_mode=wal2" sans checksums */ # define isNocksum(pWal) isWalMode2(pWal) #else # define isNocksum(pWal) 0 #endif /* ** Index numbers for various locking bytes. WAL_NREADER is the number ** of available reader locks and should be at least 3. The default ** is SQLITE_SHM_NLOCK==8 and WAL_NREADER==5. ** |
︙ | ︙ | |||
806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 | WalIndexHdr *pSnapshot; /* Start transaction here if not NULL */ #endif int bClosing; /* Set to true at start of sqlite3WalClose() */ int bWal2; /* bWal2 flag passed to WalOpen() */ #ifdef SQLITE_ENABLE_SETLK_TIMEOUT sqlite3 *db; #endif }; /* ** Candidate values for Wal.exclusiveMode. */ #define WAL_NORMAL_MODE 0 #define WAL_EXCLUSIVE_MODE 1 #define WAL_HEAPMEMORY_MODE 2 /* ** Possible values for WAL.readOnly */ #define WAL_RDWR 0 /* Normal read/write connection */ #define WAL_RDONLY 1 /* The WAL file is readonly */ #define WAL_SHM_RDONLY 2 /* The SHM file is readonly */ /* ** Each page of the wal-index mapping contains a hash-table made up of ** an array of HASHTABLE_NSLOT elements of the following type. */ | > > > > | > | 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 | WalIndexHdr *pSnapshot; /* Start transaction here if not NULL */ #endif int bClosing; /* Set to true at start of sqlite3WalClose() */ int bWal2; /* bWal2 flag passed to WalOpen() */ #ifdef SQLITE_ENABLE_SETLK_TIMEOUT sqlite3 *db; #endif u64 *aCommitTime; }; /* ** Candidate values for Wal.exclusiveMode. */ #define WAL_NORMAL_MODE 0 #define WAL_EXCLUSIVE_MODE 1 #define WAL_HEAPMEMORY_MODE 2 /* ** Possible values for WAL.readOnly */ #define WAL_RDWR 0 /* Normal read/write connection */ #define WAL_RDONLY 1 /* The WAL file is readonly */ #define WAL_SHM_RDONLY 2 /* The SHM file is readonly */ /* ** Each page of the wal-index mapping contains a hash-table made up of ** an array of HASHTABLE_NSLOT elements of the following type. */ #ifdef SQLITE_WAL_BIGHASH typedef u32 ht_slot; #else typedef u16 ht_slot; #endif /* ** This structure is used to implement an iterator that loops through ** all frames in the WAL in database page order. Where two or more frames ** correspond to the same database page, the iterator visits only the ** frame most recently written to the WAL (in other words, the frame with ** the largest index). |
︙ | ︙ | |||
863 864 865 866 867 868 869 | ** Define the parameters of the hash tables in the wal-index file. There ** is a hash-table following every HASHTABLE_NPAGE page numbers in the ** wal-index. ** ** Changing any of these constants will alter the wal-index format and ** create incompatibilities. */ | > > > > > | | | | 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 | ** Define the parameters of the hash tables in the wal-index file. There ** is a hash-table following every HASHTABLE_NPAGE page numbers in the ** wal-index. ** ** Changing any of these constants will alter the wal-index format and ** create incompatibilities. */ #ifdef SQLITE_WAL_BIGHASH # define HASHTABLE_BITS 17 /* 128K frames per hash */ #else # define HASHTABLE_BITS 12 /* 4K frames per hash */ #endif # define HASHTABLE_NPAGE (1<<HASHTABLE_BITS) /* Must be power of 2 */ # define HASHTABLE_HASH_1 383 /* Should be prime */ # define HASHTABLE_NSLOT (HASHTABLE_NPAGE*2) /* Must be a power of 2 */ /* ** The block of page numbers associated with the first hash-table in a ** wal-index is smaller than usual. This is so that there is a complete ** hash-table on each aligned 32KB page of the wal-index. */ #define HASHTABLE_NPAGE_ONE (HASHTABLE_NPAGE - (WALINDEX_HDR_SIZE/sizeof(u32))) |
︙ | ︙ | |||
1060 1061 1062 1063 1064 1065 1066 | static int walIndexPage( Wal *pWal, /* The WAL context */ int iPage, /* The page we seek */ volatile u32 **ppPage /* Write the page pointer here */ ){ SEH_INJECT_FAULT; if( pWal->nWiData<=iPage || (*ppPage = pWal->apWiData[iPage])==0 ){ | > > > | > > > > | 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 | static int walIndexPage( Wal *pWal, /* The WAL context */ int iPage, /* The page we seek */ volatile u32 **ppPage /* Write the page pointer here */ ){ SEH_INJECT_FAULT; if( pWal->nWiData<=iPage || (*ppPage = pWal->apWiData[iPage])==0 ){ int rc; u64 t1; if( pWal->aCommitTime ) t1 = sqlite3STimeNow(); rc = walIndexPageRealloc(pWal, iPage, ppPage); if( pWal->aCommitTime ){ pWal->aCommitTime[COMMIT_TIME_HASHMAPUS] += sqlite3STimeNow() - t1; } return rc; } return SQLITE_OK; } /* ** Return a pointer to the WalCkptInfo structure in the wal-index. */ |
︙ | ︙ | |||
1233 1234 1235 1236 1237 1238 1239 | u32 *aCksum = pWal->hdr.aFrameCksum; assert( WAL_FRAME_HDRSIZE==24 ); sqlite3Put4byte(&aFrame[0], iPage); sqlite3Put4byte(&aFrame[4], nTruncate); if( pWal->iReCksum==0 ){ memcpy(&aFrame[8], pWal->hdr.aSalt, 8); | > | | | > > | 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 | u32 *aCksum = pWal->hdr.aFrameCksum; assert( WAL_FRAME_HDRSIZE==24 ); sqlite3Put4byte(&aFrame[0], iPage); sqlite3Put4byte(&aFrame[4], nTruncate); if( pWal->iReCksum==0 ){ memcpy(&aFrame[8], pWal->hdr.aSalt, 8); if( isNocksum(pWal)==0 ){ nativeCksum = (pWal->hdr.bigEndCksum==SQLITE_BIGENDIAN); walChecksumBytes(nativeCksum, aFrame, 8, aCksum, aCksum); walChecksumBytes(nativeCksum, aData, pWal->szPage, aCksum, aCksum); } sqlite3Put4byte(&aFrame[16], aCksum[0]); sqlite3Put4byte(&aFrame[20], aCksum[1]); }else{ memset(&aFrame[8], 0, 16); } } /* ** Check to see if the frame with header in aFrame[] and content |
︙ | ︙ | |||
1280 1281 1282 1283 1284 1285 1286 | } /* A frame is only valid if a checksum of the WAL header, ** all prior frames, the first 16 bytes of this frame-header, ** and the frame-data matches the checksum in the last 8 ** bytes of this frame-header. */ | > | | | | | | | | > | 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 | } /* A frame is only valid if a checksum of the WAL header, ** all prior frames, the first 16 bytes of this frame-header, ** and the frame-data matches the checksum in the last 8 ** bytes of this frame-header. */ if( isNocksum(pWal)==0 ){ nativeCksum = (pWal->hdr.bigEndCksum==SQLITE_BIGENDIAN); walChecksumBytes(nativeCksum, aFrame, 8, aCksum, aCksum); walChecksumBytes(nativeCksum, aData, pWal->szPage, aCksum, aCksum); if( aCksum[0]!=sqlite3Get4byte(&aFrame[16]) || aCksum[1]!=sqlite3Get4byte(&aFrame[20]) ){ /* Checksum failed. */ return 0; } } /* If we reach this point, the frame is valid. Return the page number ** and the new database size. */ *piPage = pgno; *pnTruncate = sqlite3Get4byte(&aFrame[4]); |
︙ | ︙ | |||
1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 | if( sLoc.aHash[iKey]==j+1 ) break; } assert( sLoc.aHash[iKey]==j+1 ); } } #endif /* SQLITE_ENABLE_EXPENSIVE_ASSERT */ } /* ** Set an entry in the wal-index that will map database page number ** pPage into WAL frame iFrame. */ static int walIndexAppend(Wal *pWal, int iWal, u32 iFrame, u32 iPage){ int rc; /* Return code */ WalHashLoc sLoc; /* Wal-index hash table location */ u32 iExternal; if( isWalMode2(pWal) ){ iExternal = walExternalEncode(iWal, iFrame); }else{ assert( iWal==0 ); iExternal = iFrame; } rc = walHashGet(pWal, walFramePage(iExternal), &sLoc); /* Assuming the wal-index file was successfully mapped, populate the ** page number array and hash table entry. */ if( rc==SQLITE_OK ){ int iKey; /* Hash table key */ int idx; /* Value to write to hash-table slot */ int nCollide; /* Number of hash collisions */ idx = iExternal - sLoc.iZero; assert( idx <= HASHTABLE_NSLOT/2 + 1 ); /* If this is the first entry to be added to this hash-table, zero the ** entire hash table and aPgno[] array before proceeding. */ | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > | < | > > > | > > > > > > > | > > > > | < | > | > > > > > > > > | > > | 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 | if( sLoc.aHash[iKey]==j+1 ) break; } assert( sLoc.aHash[iKey]==j+1 ); } } #endif /* SQLITE_ENABLE_EXPENSIVE_ASSERT */ } /* ** Zero the n byte block indicated by pointer p. n Must be a multiple of ** 8, and p must be aligned to an 8-byte boundary. */ static void zero64(void *p, int n){ #if defined(__x86_64__) size_t c = n / sizeof(u64); void *d = p; assert( (n & 0x7)==0 ); assert( EIGHT_BYTE_ALIGNMENT(p) ); __asm__ volatile ( "rep stosq" : "+D" (d), "+c" (c) : "a" (0) : "memory" ); #else memset(p, 0, n); #endif } /* ** Set an entry in the wal-index that will map database page number ** pPage into WAL frame iFrame. */ static int walIndexAppend(Wal *pWal, int iWal, u32 iFrame, u32 iPage){ int rc; /* Return code */ WalHashLoc sLoc; /* Wal-index hash table location */ u32 iExternal; u64 t; if( isWalMode2(pWal) ){ iExternal = walExternalEncode(iWal, iFrame); }else{ assert( iWal==0 ); iExternal = iFrame; } if( pWal->aCommitTime ) t = sqlite3STimeNow(); rc = walHashGet(pWal, walFramePage(iExternal), &sLoc); if( pWal->aCommitTime ){ pWal->aCommitTime[COMMIT_TIME_WALINDEX_HASHGETUS] += sqlite3STimeNow()-t; } /* Assuming the wal-index file was successfully mapped, populate the ** page number array and hash table entry. */ if( rc==SQLITE_OK ){ int iKey; /* Hash table key */ int idx; /* Value to write to hash-table slot */ int nCollide; /* Number of hash collisions */ idx = iExternal - sLoc.iZero; assert( idx <= HASHTABLE_NSLOT/2 + 1 ); /* If this is the first entry to be added to this hash-table, zero the ** entire hash table and aPgno[] array before proceeding. */ if( pWal->aCommitTime ) t = sqlite3STimeNow(); if( idx==1 && sLoc.aPgno[0]!=0 ){ /* Special for BEDROCK branch: Zero only the aHash[] part. Not the ** aPgno[] part of the page. */ zero64((void*)sLoc.aHash, HASHTABLE_NSLOT * sizeof(sLoc.aHash[0])); } if( pWal->aCommitTime ){ pWal->aCommitTime[COMMIT_TIME_WALINDEX_MEMSETUS]+=sqlite3STimeNow()-t; } /* If the entry in aPgno[] is already set, then the previous writer ** must have exited unexpectedly in the middle of a transaction (after ** writing one or more dirty pages to the WAL to free up memory). ** Remove the remnants of that writers uncommitted transaction from ** the hash-table before writing any new entries. ** ** Special for BEDROCK branch: On this branch we do not assume that ** the aPgno[] part of each hash-table has been zeroed. Therefore, we ** only need to clear out the remnants of an old writer's transaction if ** the hash table matches the aPgno[] entry (as it would if a write ** transaction was interrupted). And, because this makes the test more ** expensive, we only do the check for the first frame written by each ** transaction. */ if( sLoc.aPgno[idx-1] && iFrame-1==walidxGetMxFrame(&pWal->hdr, iWal) ){ if( pWal->aCommitTime ) t = sqlite3STimeNow(); nCollide = idx; for(iKey=walHash(iPage); sLoc.aHash[iKey]; iKey=walNextHash(iKey)){ if( sLoc.aHash[iKey]==idx ){ walCleanupHash(pWal); } if( (nCollide--)==0 ) return SQLITE_CORRUPT_BKPT; } if( pWal->aCommitTime ){ pWal->aCommitTime[COMMIT_TIME_WALINDEX_CLEANUPUS]+=sqlite3STimeNow()-t; } } /* Write the aPgno[] array entry and the hash-table slot. */ if( pWal->aCommitTime ) t = sqlite3STimeNow(); nCollide = idx; for(iKey=walHash(iPage); sLoc.aHash[iKey]; iKey=walNextHash(iKey)){ if( (nCollide--)==0 ) return SQLITE_CORRUPT_BKPT; } sLoc.aPgno[idx-1] = iPage; AtomicStore(&sLoc.aHash[iKey], (ht_slot)idx); if( pWal->aCommitTime ){ pWal->aCommitTime[COMMIT_TIME_WALINDEX_ENTRYUS]+=sqlite3STimeNow()-t; } #ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT assert( this_should_not_be_enabled ); /* Verify that the number of entries in the hash table exactly equals ** the number of entries in the mapping region. */ { int i; /* Loop counter */ int nEntry = 0; /* Number of entries in the hash table */ for(i=0; i<HASHTABLE_NSLOT; i++){ if( sLoc.aHash[i] ) nEntry++; } |
︙ | ︙ | |||
1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 | int nHdr, nHdr32; rc = walIndexPage(pWal, iPg, (volatile u32**)&aShare); assert( aShare!=0 || rc!=SQLITE_OK ); if( aShare==0 ) break; SEH_SET_ON_ERROR(iPg, aShare); pWal->apWiData[iPg] = aPrivate; if( iWal ){ assert( version==WAL_VERSION2 ); iFirst = 1 + (iPg/2)*HASHTABLE_NPAGE; iLast = iFirst + HASHTABLE_NPAGE - 1; }else{ int i2 = (version==WAL_VERSION2) ? (iPg/2) : iPg; | > | 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 | int nHdr, nHdr32; rc = walIndexPage(pWal, iPg, (volatile u32**)&aShare); assert( aShare!=0 || rc!=SQLITE_OK ); if( aShare==0 ) break; SEH_SET_ON_ERROR(iPg, aShare); pWal->apWiData[iPg] = aPrivate; memset(aPrivate, 0, WALINDEX_PGSZ); if( iWal ){ assert( version==WAL_VERSION2 ); iFirst = 1 + (iPg/2)*HASHTABLE_NPAGE; iLast = iFirst + HASHTABLE_NPAGE - 1; }else{ int i2 = (version==WAL_VERSION2) ? (iPg/2) : iPg; |
︙ | ︙ | |||
2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 | ** This table also serves as a helpful cross-reference when trying to ** interpret hex dumps of the -shm file. */ assert( 48 == sizeof(WalIndexHdr) ); assert( 40 == sizeof(WalCkptInfo) ); assert( 120 == WALINDEX_LOCK_OFFSET ); assert( 136 == WALINDEX_HDR_SIZE ); assert( 4096 == HASHTABLE_NPAGE ); assert( 4062 == HASHTABLE_NPAGE_ONE ); assert( 8192 == HASHTABLE_NSLOT ); assert( 383 == HASHTABLE_HASH_1 ); assert( 32768 == WALINDEX_PGSZ ); assert( 8 == SQLITE_SHM_NLOCK ); assert( 5 == WAL_NREADER ); assert( 24 == WAL_FRAME_HDRSIZE ); assert( 32 == WAL_HDRSIZE ); assert( 120 == WALINDEX_LOCK_OFFSET + WAL_WRITE_LOCK ); assert( 121 == WALINDEX_LOCK_OFFSET + WAL_CKPT_LOCK ); assert( 122 == WALINDEX_LOCK_OFFSET + WAL_RECOVER_LOCK ); | > > | 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 | ** This table also serves as a helpful cross-reference when trying to ** interpret hex dumps of the -shm file. */ assert( 48 == sizeof(WalIndexHdr) ); assert( 40 == sizeof(WalCkptInfo) ); assert( 120 == WALINDEX_LOCK_OFFSET ); assert( 136 == WALINDEX_HDR_SIZE ); #ifndef SQLITE_WAL_BIGHASH assert( 4096 == HASHTABLE_NPAGE ); assert( 4062 == HASHTABLE_NPAGE_ONE ); assert( 8192 == HASHTABLE_NSLOT ); assert( 383 == HASHTABLE_HASH_1 ); assert( 32768 == WALINDEX_PGSZ ); #endif assert( 8 == SQLITE_SHM_NLOCK ); assert( 5 == WAL_NREADER ); assert( 24 == WAL_FRAME_HDRSIZE ); assert( 32 == WAL_HDRSIZE ); assert( 120 == WALINDEX_LOCK_OFFSET + WAL_WRITE_LOCK ); assert( 121 == WALINDEX_LOCK_OFFSET + WAL_CKPT_LOCK ); assert( 122 == WALINDEX_LOCK_OFFSET + WAL_RECOVER_LOCK ); |
︙ | ︙ | |||
2359 2360 2361 2362 2363 2364 2365 | }; const int nList = *pnList; /* Size of input list */ int nMerge = 0; /* Number of elements in list aMerge */ ht_slot *aMerge = 0; /* List to be merged */ int iList; /* Index into input list */ u32 iSub = 0; /* Index into aSub array */ | | | 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 | }; const int nList = *pnList; /* Size of input list */ int nMerge = 0; /* Number of elements in list aMerge */ ht_slot *aMerge = 0; /* List to be merged */ int iList; /* Index into input list */ u32 iSub = 0; /* Index into aSub array */ struct Sublist aSub[HASHTABLE_BITS+1]; /* Array of sub-lists */ memset(aSub, 0, sizeof(aSub)); assert( nList<=HASHTABLE_NPAGE && nList>0 ); assert( HASHTABLE_NPAGE==(1<<(ArraySize(aSub)-1)) ); for(iList=0; iList<nList; iList++){ nMerge = 1; |
︙ | ︙ | |||
2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 | } /* Release the reader lock held while backfilling */ if( bWal2==0 ){ walUnlockExclusive(pWal, WAL_READ_LOCK(0), 1); } } if( rc==SQLITE_BUSY ){ /* Reset the return code so as not to report a checkpoint failure ** just because there are active readers. */ rc = SQLITE_OK; } if( bWal2 ) wal2CheckpointFinished(pWal, iCkpt); | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 3061 3062 3063 | } /* Release the reader lock held while backfilling */ if( bWal2==0 ){ walUnlockExclusive(pWal, WAL_READ_LOCK(0), 1); } } if( bWal2 && rc==SQLITE_OK && eMode!=SQLITE_CHECKPOINT_PASSIVE ){ /* In wal2 mode, a non-passive checkpoint waits for all readers of ** the wal file just checkpointed to finish, then zeroes the hash ** tables associated with that wal file. This is because in some ** deployments, zeroing the hash tables as they are overwritten within ** COMMIT commands is a significant performance hit. ** ** Currently, both of the "PART" locks are held for the wal file ** being checkpointed. i.e. if iCkpt==0, then we already hold both ** WAL_LOCK_PART1 and WAL_LOCK_PART1_FULL2. If we now also take an ** exclusive lock on WAL_LOCK_PART2_FULL1, then it is guaranteed that ** there are no remaining readers of the (iCkpt==0) wal file. Similar ** logic, with different locks, is used for (iCkpt==1). */ int lockIdx = WAL_READ_LOCK( iCkpt==0 ? WAL_LOCK_PART2_FULL1 : WAL_LOCK_PART1_FULL2 ); assert( iCkpt==0 || iCkpt==1 ); rc = walBusyLock(pWal, xBusy, pBusyArg, lockIdx, 1); if( rc==SQLITE_OK ){ int iHash; for(iHash = walFramePage2(iCkpt, mxSafeFrame); iHash>=0; iHash-=2){ WalHashLoc sLoc; int nByte; memset(&sLoc, 0, sizeof(sLoc)); walHashGet(pWal, iHash, &sLoc); nByte = (int)((u8*)&sLoc.aHash[HASHTABLE_NSLOT] - (u8*)sLoc.aPgno); memset((void*)sLoc.aPgno, 0, nByte); } walUnlockExclusive(pWal, lockIdx, 1); } } if( rc==SQLITE_BUSY ){ /* Reset the return code so as not to report a checkpoint failure ** just because there are active readers. */ rc = SQLITE_OK; } if( bWal2 ) wal2CheckpointFinished(pWal, iCkpt); |
︙ | ︙ | |||
5043 5044 5045 5046 5047 5048 5049 5050 5051 5052 5053 5054 5055 5056 5057 5058 5059 5060 5061 5062 5063 5064 5065 5066 5067 5068 | static int walWriteToLog( WalWriter *p, /* WAL to write to */ void *pContent, /* Content to be written */ int iAmt, /* Number of bytes to write */ sqlite3_int64 iOffset /* Start writing at this offset */ ){ int rc; if( iOffset<p->iSyncPoint && iOffset+iAmt>=p->iSyncPoint ){ int iFirstAmt = (int)(p->iSyncPoint - iOffset); rc = sqlite3OsWrite(p->pFd, pContent, iFirstAmt, iOffset); if( rc ) return rc; iOffset += iFirstAmt; iAmt -= iFirstAmt; pContent = (void*)(iFirstAmt + (char*)pContent); assert( WAL_SYNC_FLAGS(p->syncFlags)!=0 ); rc = sqlite3OsSync(p->pFd, WAL_SYNC_FLAGS(p->syncFlags)); if( iAmt==0 || rc ) return rc; } rc = sqlite3OsWrite(p->pFd, pContent, iAmt, iOffset); return rc; } /* ** Write out a single frame of the WAL */ static int walWriteOneFrame( | > > > > > > > | 5172 5173 5174 5175 5176 5177 5178 5179 5180 5181 5182 5183 5184 5185 5186 5187 5188 5189 5190 5191 5192 5193 5194 5195 5196 5197 5198 5199 5200 5201 5202 5203 5204 | static int walWriteToLog( WalWriter *p, /* WAL to write to */ void *pContent, /* Content to be written */ int iAmt, /* Number of bytes to write */ sqlite3_int64 iOffset /* Start writing at this offset */ ){ int rc; u64 t; if( iOffset<p->iSyncPoint && iOffset+iAmt>=p->iSyncPoint ){ int iFirstAmt = (int)(p->iSyncPoint - iOffset); rc = sqlite3OsWrite(p->pFd, pContent, iFirstAmt, iOffset); if( rc ) return rc; iOffset += iFirstAmt; iAmt -= iFirstAmt; pContent = (void*)(iFirstAmt + (char*)pContent); assert( WAL_SYNC_FLAGS(p->syncFlags)!=0 ); rc = sqlite3OsSync(p->pFd, WAL_SYNC_FLAGS(p->syncFlags)); if( iAmt==0 || rc ) return rc; } if( p->pWal->aCommitTime ){ t = sqlite3STimeNow(); } rc = sqlite3OsWrite(p->pFd, pContent, iAmt, iOffset); if( p->pWal->aCommitTime ){ p->pWal->aCommitTime[COMMIT_TIME_OSWRITE] += (sqlite3STimeNow() - t); } return rc; } /* ** Write out a single frame of the WAL */ static int walWriteOneFrame( |
︙ | ︙ | |||
5084 5085 5086 5087 5088 5089 5090 | p->pWal, (int)pPage->pgno, iFrame, iWal )); } #endif pData = pPage->pData; walEncodeFrame(p->pWal, pPage->pgno, nTruncate, pData, aFrame); | > > > | | > > > > > > > > | 5220 5221 5222 5223 5224 5225 5226 5227 5228 5229 5230 5231 5232 5233 5234 5235 5236 5237 5238 5239 5240 5241 5242 5243 5244 5245 5246 5247 5248 | p->pWal, (int)pPage->pgno, iFrame, iWal )); } #endif pData = pPage->pData; walEncodeFrame(p->pWal, pPage->pgno, nTruncate, pData, aFrame); if( isNocksum(p->pWal)==0 ){ /* Write the header in normal mode */ rc = walWriteToLog(p, aFrame, sizeof(aFrame), iOffset); if( rc ) return rc; } /* Write the page data */ rc = walWriteToLog(p, pData, p->szPage, iOffset+sizeof(aFrame)); if( isNocksum(p->pWal) ){ /* Write the header in no-checksum mode */ if( rc ) return rc; rc = walWriteToLog(p, aFrame, sizeof(aFrame), iOffset); } return rc; } /* ** This function is called as part of committing a transaction within which ** one or more frames have been overwritten. It updates the checksums for ** all frames written to the wal file by the current transaction starting |
︙ | ︙ | |||
5169 5170 5171 5172 5173 5174 5175 5176 5177 5178 5179 5180 5181 5182 | int szFrame; /* The size of a single frame */ i64 iOffset; /* Next byte to write in WAL file */ WalWriter w; /* The writer */ u32 iFirst = 0; /* First frame that may be overwritten */ WalIndexHdr *pLive; /* Pointer to shared header */ int iApp; int bWal2 = isWalMode2(pWal); assert( pList ); assert( pWal->writeLock ); /* If this frame set completes a transaction, then nTruncate>0. If ** nTruncate==0 then this frame set does not complete the transaction. */ assert( (isCommit!=0)==(nTruncate!=0) ); | > > > | 5316 5317 5318 5319 5320 5321 5322 5323 5324 5325 5326 5327 5328 5329 5330 5331 5332 | int szFrame; /* The size of a single frame */ i64 iOffset; /* Next byte to write in WAL file */ WalWriter w; /* The writer */ u32 iFirst = 0; /* First frame that may be overwritten */ WalIndexHdr *pLive; /* Pointer to shared header */ int iApp; int bWal2 = isWalMode2(pWal); int nFrame = 0; int logFlags = 0; assert( pList ); assert( pWal->writeLock ); /* If this frame set completes a transaction, then nTruncate>0. If ** nTruncate==0 then this frame set does not complete the transaction. */ assert( (isCommit!=0)==(nTruncate!=0) ); |
︙ | ︙ | |||
5190 5191 5192 5193 5194 5195 5196 5197 5198 5199 5200 5201 5202 5203 5204 5205 5206 5207 5208 5209 5210 5211 5212 5213 5214 5215 5216 5217 5218 | /* See if it is possible to write these frames into the start of the ** log file, instead of appending to it at pWal->hdr.mxFrame. */ else if( SQLITE_OK!=(rc = walRestartLog(pWal)) ){ return rc; } /* If this is the first frame written into the log, write the WAL ** header to the start of the WAL file. See comments at the top of ** this source file for a description of the WAL header format. */ iApp = walidxGetFile(&pWal->hdr); iFrame = walidxGetMxFrame(&pWal->hdr, iApp); assert( iApp==0 || bWal2 ); #if defined(SQLITE_TEST) && defined(SQLITE_DEBUG) { int cnt; for(cnt=0, p=pList; p; p=p->pDirty, cnt++){} WALTRACE(("WAL%p: frame write begin. %d frames. iWal=%d. mxFrame=%d. %s\n", pWal, cnt, iApp, iFrame, isCommit ? "Commit" : "Spill")); } #endif if( iFrame==0 ){ u32 iCkpt = 0; u8 aWalHdr[WAL_HDRSIZE]; /* Buffer to assemble wal-header in */ u32 aCksum[2]; /* Checksum for wal-header */ sqlite3Put4byte(&aWalHdr[0], (WAL_MAGIC | SQLITE_BIGENDIAN)); sqlite3Put4byte(&aWalHdr[4], pWal->hdr.iVersion); | > > > | 5340 5341 5342 5343 5344 5345 5346 5347 5348 5349 5350 5351 5352 5353 5354 5355 5356 5357 5358 5359 5360 5361 5362 5363 5364 5365 5366 5367 5368 5369 5370 5371 | /* See if it is possible to write these frames into the start of the ** log file, instead of appending to it at pWal->hdr.mxFrame. */ else if( SQLITE_OK!=(rc = walRestartLog(pWal)) ){ return rc; } sqlite3CommitTimeSet(pWal->aCommitTime, COMMIT_TIME_AFTER_RESTARTLOG); /* If this is the first frame written into the log, write the WAL ** header to the start of the WAL file. See comments at the top of ** this source file for a description of the WAL header format. */ iApp = walidxGetFile(&pWal->hdr); iFrame = walidxGetMxFrame(&pWal->hdr, iApp); assert( iApp==0 || bWal2 ); #if defined(SQLITE_TEST) && defined(SQLITE_DEBUG) { int cnt; for(cnt=0, p=pList; p; p=p->pDirty, cnt++){} WALTRACE(("WAL%p: frame write begin. %d frames. iWal=%d. mxFrame=%d. %s\n", pWal, cnt, iApp, iFrame, isCommit ? "Commit" : "Spill")); } #endif logFlags |= (iFrame==0 ? 0x01 : 0x00); if( iFrame==0 ){ u32 iCkpt = 0; u8 aWalHdr[WAL_HDRSIZE]; /* Buffer to assemble wal-header in */ u32 aCksum[2]; /* Checksum for wal-header */ sqlite3Put4byte(&aWalHdr[0], (WAL_MAGIC | SQLITE_BIGENDIAN)); sqlite3Put4byte(&aWalHdr[4], pWal->hdr.iVersion); |
︙ | ︙ | |||
5258 5259 5260 5261 5262 5263 5264 5265 5266 5267 5268 5269 5270 5271 5272 5273 5274 5275 5276 5277 5278 5279 5280 5281 5282 | rc = sqlite3OsSync(pWal->apWalFd[iApp], CKPT_SYNC_FLAGS(sync_flags)); if( rc ) return rc; } } if( (int)pWal->szPage!=szPage ){ return SQLITE_CORRUPT_BKPT; /* TH3 test case: cov1/corrupt155.test */ } /* Setup information needed to write frames into the WAL */ w.pWal = pWal; w.pFd = pWal->apWalFd[iApp]; w.iSyncPoint = 0; w.syncFlags = sync_flags; w.szPage = szPage; iOffset = walFrameOffset(iFrame+1, szPage); szFrame = szPage + WAL_FRAME_HDRSIZE; /* Write all frames into the log file exactly once */ for(p=pList; p; p=p->pDirty){ int nDbSize; /* 0 normally. Positive == commit flag */ /* Check if this page has already been written into the wal file by ** the current transaction. If so, overwrite the existing frame and ** set Wal.writeLock to WAL_WRITELOCK_RECKSUM - indicating that ** checksums must be recomputed when the transaction is committed. */ | > > | 5411 5412 5413 5414 5415 5416 5417 5418 5419 5420 5421 5422 5423 5424 5425 5426 5427 5428 5429 5430 5431 5432 5433 5434 5435 5436 5437 | rc = sqlite3OsSync(pWal->apWalFd[iApp], CKPT_SYNC_FLAGS(sync_flags)); if( rc ) return rc; } } if( (int)pWal->szPage!=szPage ){ return SQLITE_CORRUPT_BKPT; /* TH3 test case: cov1/corrupt155.test */ } sqlite3CommitTimeSet(pWal->aCommitTime, COMMIT_TIME_AFTER_WRITEHDR); /* Setup information needed to write frames into the WAL */ w.pWal = pWal; w.pFd = pWal->apWalFd[iApp]; w.iSyncPoint = 0; w.syncFlags = sync_flags; w.szPage = szPage; iOffset = walFrameOffset(iFrame+1, szPage); szFrame = szPage + WAL_FRAME_HDRSIZE; /* Write all frames into the log file exactly once */ logFlags |= (iFirst==0 ? 0x00 : 0x02); for(p=pList; p; p=p->pDirty){ int nDbSize; /* 0 normally. Positive == commit flag */ /* Check if this page has already been written into the wal file by ** the current transaction. If so, overwrite the existing frame and ** set Wal.writeLock to WAL_WRITELOCK_RECKSUM - indicating that ** checksums must be recomputed when the transaction is committed. */ |
︙ | ︙ | |||
5307 5308 5309 5310 5311 5312 5313 5314 5315 5316 5317 5318 5319 5320 5321 5322 5323 5324 5325 5326 5327 5328 5329 5330 5331 5332 5333 5334 5335 5336 5337 5338 5339 5340 5341 | rc = walWriteOneFrame(&w, p, nDbSize, iOffset); if( rc ) return rc; pLast = p; iOffset += szFrame; p->flags |= PGHDR_WAL_APPEND; } /* Recalculate checksums within the wal file if required. */ if( isCommit && pWal->iReCksum ){ rc = walRewriteChecksums(pWal, iFrame); if( rc ) return rc; } /* If this is the end of a transaction, then we might need to pad ** the transaction and/or sync the WAL file. ** ** Padding and syncing only occur if this set of frames complete a ** transaction and if PRAGMA synchronous=FULL. If synchronous==NORMAL ** or synchronous==OFF, then no padding or syncing are needed. ** ** If SQLITE_IOCAP_POWERSAFE_OVERWRITE is defined, then padding is not ** needed and only the sync is done. If padding is needed, then the ** final frame is repeated (with its commit mark) until the next sector ** boundary is crossed. Only the part of the WAL prior to the last ** sector boundary is synced; the part of the last frame that extends ** past the sector boundary is written after the sync. */ if( isCommit && WAL_SYNC_FLAGS(sync_flags)!=0 ){ int bSync = 1; if( pWal->padToSectorBoundary ){ int sectorSize = sqlite3SectorSize(w.pFd); w.iSyncPoint = ((iOffset+sectorSize-1)/sectorSize)*sectorSize; bSync = (w.iSyncPoint==iOffset); testcase( bSync ); | > > > | 5462 5463 5464 5465 5466 5467 5468 5469 5470 5471 5472 5473 5474 5475 5476 5477 5478 5479 5480 5481 5482 5483 5484 5485 5486 5487 5488 5489 5490 5491 5492 5493 5494 5495 5496 5497 5498 5499 | rc = walWriteOneFrame(&w, p, nDbSize, iOffset); if( rc ) return rc; pLast = p; iOffset += szFrame; p->flags |= PGHDR_WAL_APPEND; } sqlite3CommitTimeSet(pWal->aCommitTime, COMMIT_TIME_AFTER_WRITEFRAMES); /* Recalculate checksums within the wal file if required. */ logFlags |= (pWal->iReCksum==0 ? 0x00 : 0x04); if( isCommit && pWal->iReCksum ){ rc = walRewriteChecksums(pWal, iFrame); if( rc ) return rc; } /* If this is the end of a transaction, then we might need to pad ** the transaction and/or sync the WAL file. ** ** Padding and syncing only occur if this set of frames complete a ** transaction and if PRAGMA synchronous=FULL. If synchronous==NORMAL ** or synchronous==OFF, then no padding or syncing are needed. ** ** If SQLITE_IOCAP_POWERSAFE_OVERWRITE is defined, then padding is not ** needed and only the sync is done. If padding is needed, then the ** final frame is repeated (with its commit mark) until the next sector ** boundary is crossed. Only the part of the WAL prior to the last ** sector boundary is synced; the part of the last frame that extends ** past the sector boundary is written after the sync. */ logFlags |= (WAL_SYNC_FLAGS(sync_flags)==0 ? 0x00 : 0x08); if( isCommit && WAL_SYNC_FLAGS(sync_flags)!=0 ){ int bSync = 1; if( pWal->padToSectorBoundary ){ int sectorSize = sqlite3SectorSize(w.pFd); w.iSyncPoint = ((iOffset+sectorSize-1)/sectorSize)*sectorSize; bSync = (w.iSyncPoint==iOffset); testcase( bSync ); |
︙ | ︙ | |||
5362 5363 5364 5365 5366 5367 5368 5369 5370 5371 5372 5373 5374 5375 5376 5377 5378 5379 5380 5381 5382 5383 5384 5385 5386 5387 5388 5389 5390 5391 5392 | if( walFrameOffset(iFrame+nExtra+1, szPage)>pWal->mxWalSize ){ sz = walFrameOffset(iFrame+nExtra+1, szPage); } walLimitSize(pWal, sz); pWal->truncateOnCommit = 0; } /* Append data to the wal-index. It is not necessary to lock the ** wal-index to do this as the SQLITE_SHM_WRITE lock held on the wal-index ** guarantees that there are no other writers, and no data that may ** be in use by existing readers is being overwritten. */ iFrame = walidxGetMxFrame(&pWal->hdr, iApp); for(p=pList; p && rc==SQLITE_OK; p=p->pDirty){ if( (p->flags & PGHDR_WAL_APPEND)==0 ) continue; iFrame++; rc = walIndexAppend(pWal, iApp, iFrame, p->pgno); } assert( pLast!=0 || nExtra==0 ); while( rc==SQLITE_OK && nExtra>0 ){ iFrame++; nExtra--; rc = walIndexAppend(pWal, iApp, iFrame, pLast->pgno); } if( rc==SQLITE_OK ){ /* Update the private copy of the header. */ pWal->hdr.szPage = (u16)((szPage&0xff00) | (szPage>>16)); testcase( szPage<=32768 ); testcase( szPage>=65536 ); walidxSetMxFrame(&pWal->hdr, iApp, iFrame); | > > > > > > | 5520 5521 5522 5523 5524 5525 5526 5527 5528 5529 5530 5531 5532 5533 5534 5535 5536 5537 5538 5539 5540 5541 5542 5543 5544 5545 5546 5547 5548 5549 5550 5551 5552 5553 5554 5555 5556 | if( walFrameOffset(iFrame+nExtra+1, szPage)>pWal->mxWalSize ){ sz = walFrameOffset(iFrame+nExtra+1, szPage); } walLimitSize(pWal, sz); pWal->truncateOnCommit = 0; } sqlite3CommitTimeSet(pWal->aCommitTime, COMMIT_TIME_BEFORE_WALINDEX); /* Append data to the wal-index. It is not necessary to lock the ** wal-index to do this as the SQLITE_SHM_WRITE lock held on the wal-index ** guarantees that there are no other writers, and no data that may ** be in use by existing readers is being overwritten. */ iFrame = walidxGetMxFrame(&pWal->hdr, iApp); for(p=pList; p && rc==SQLITE_OK; p=p->pDirty){ if( (p->flags & PGHDR_WAL_APPEND)==0 ) continue; iFrame++; rc = walIndexAppend(pWal, iApp, iFrame, p->pgno); nFrame++; } assert( pLast!=0 || nExtra==0 ); while( rc==SQLITE_OK && nExtra>0 ){ iFrame++; nExtra--; rc = walIndexAppend(pWal, iApp, iFrame, pLast->pgno); } if( pWal->aCommitTime ) pWal->aCommitTime[COMMIT_TIME_NFRAME] = nFrame; sqlite3CommitTimeSet(pWal->aCommitTime, COMMIT_TIME_AFTER_WALINDEX); if( rc==SQLITE_OK ){ /* Update the private copy of the header. */ pWal->hdr.szPage = (u16)((szPage&0xff00) | (szPage>>16)); testcase( szPage<=32768 ); testcase( szPage>=65536 ); walidxSetMxFrame(&pWal->hdr, iApp, iFrame); |
︙ | ︙ | |||
5406 5407 5408 5409 5410 5411 5412 5413 5414 5415 5416 5417 5418 5419 | pWal->iCallback += walidxGetMxFrame(&pWal->hdr, 1); } }else{ pWal->iCallback = iFrame; } } } WALTRACE(("WAL%p: frame write %s\n", pWal, rc ? "failed" : "ok")); return rc; } /* | > > > > > | 5570 5571 5572 5573 5574 5575 5576 5577 5578 5579 5580 5581 5582 5583 5584 5585 5586 5587 5588 | pWal->iCallback += walidxGetMxFrame(&pWal->hdr, 1); } }else{ pWal->iCallback = iFrame; } } } sqlite3CommitTimeSet(pWal->aCommitTime, COMMIT_TIME_AFTER_WALINDEXHDR); if( pWal->aCommitTime ){ pWal->aCommitTime[COMMIT_TIME_WALFRAMESFLAGS] = logFlags; } WALTRACE(("WAL%p: frame write %s\n", pWal, rc ? "failed" : "ok")); return rc; } /* |
︙ | ︙ | |||
5499 5500 5501 5502 5503 5504 5505 | ** file. ** ** EVIDENCE-OF: R-60642-04082 If the writer lock cannot be obtained ** immediately, and a busy-handler is configured, it is invoked and the ** writer lock retried until either the busy-handler returns 0 or the ** lock is successfully obtained. */ | | | 5668 5669 5670 5671 5672 5673 5674 5675 5676 5677 5678 5679 5680 5681 5682 | ** file. ** ** EVIDENCE-OF: R-60642-04082 If the writer lock cannot be obtained ** immediately, and a busy-handler is configured, it is invoked and the ** writer lock retried until either the busy-handler returns 0 or the ** lock is successfully obtained. */ if( eMode!=SQLITE_CHECKPOINT_PASSIVE && isWalMode2(pWal)==0 ){ rc = walBusyLock(pWal, xBusy2, pBusyArg, WAL_WRITE_LOCK, 1); if( rc==SQLITE_OK ){ pWal->writeLock = 1; }else if( rc==SQLITE_BUSY ){ eMode2 = SQLITE_CHECKPOINT_PASSIVE; xBusy2 = 0; rc = SQLITE_OK; |
︙ | ︙ | |||
5817 5818 5819 5820 5821 5822 5823 5824 5825 | /* ** Return the journal mode used by this Wal object. */ int sqlite3WalJournalMode(Wal *pWal){ assert( pWal ); return (isWalMode2(pWal) ? PAGER_JOURNALMODE_WAL2 : PAGER_JOURNALMODE_WAL); } #endif /* #ifndef SQLITE_OMIT_WAL */ | > > > > > > | 5986 5987 5988 5989 5990 5991 5992 5993 5994 5995 5996 5997 5998 5999 6000 | /* ** Return the journal mode used by this Wal object. */ int sqlite3WalJournalMode(Wal *pWal){ assert( pWal ); return (isWalMode2(pWal) ? PAGER_JOURNALMODE_WAL2 : PAGER_JOURNALMODE_WAL); } void sqlite3WalSetCommitTime(Wal *pWal, u64 *aCommitTime){ if( pWal ){ pWal->aCommitTime = aCommitTime; } } #endif /* #ifndef SQLITE_OMIT_WAL */ |
Changes to src/wal.h.
︙ | ︙ | |||
170 171 172 173 174 175 176 177 178 179 | #endif /* sqlite3_wal_info() data */ int sqlite3WalInfo(Wal *pWal, u32 *pnPrior, u32 *pnFrame); /* sqlite3_wal_info() data */ int sqlite3WalInfo(Wal *pWal, u32 *pnPrior, u32 *pnFrame); #endif /* ifndef SQLITE_OMIT_WAL */ #endif /* SQLITE_WAL_H */ | > > | 170 171 172 173 174 175 176 177 178 179 180 181 | #endif /* sqlite3_wal_info() data */ int sqlite3WalInfo(Wal *pWal, u32 *pnPrior, u32 *pnFrame); /* sqlite3_wal_info() data */ int sqlite3WalInfo(Wal *pWal, u32 *pnPrior, u32 *pnFrame); void sqlite3WalSetCommitTime(Wal *pWal, u64 *aCommitTime); #endif /* ifndef SQLITE_OMIT_WAL */ #endif /* SQLITE_WAL_H */ |
Changes to src/window.c.
︙ | ︙ | |||
1746 1747 1748 1749 1750 1751 1752 | assert( ExprUseXList(pWin->pOwner) ); pColl = sqlite3ExprNNCollSeq(pParse, pWin->pOwner->x.pList->a[0].pExpr); sqlite3VdbeAddOp4(v, OP_CollSeq, 0,0,0, (const char*)pColl, P4_COLLSEQ); } sqlite3VdbeAddOp3(v, bInverse? OP_AggInverse : OP_AggStep, bInverse, regArg, pWin->regAccum); sqlite3VdbeAppendP4(v, pFunc, P4_FUNCDEF); | | | 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 | assert( ExprUseXList(pWin->pOwner) ); pColl = sqlite3ExprNNCollSeq(pParse, pWin->pOwner->x.pList->a[0].pExpr); sqlite3VdbeAddOp4(v, OP_CollSeq, 0,0,0, (const char*)pColl, P4_COLLSEQ); } sqlite3VdbeAddOp3(v, bInverse? OP_AggInverse : OP_AggStep, bInverse, regArg, pWin->regAccum); sqlite3VdbeAppendP4(v, pFunc, P4_FUNCDEF); sqlite3VdbeChangeP5(v, (u16)nArg); if( pWin->bExprArgs ){ sqlite3ReleaseTempRange(pParse, regArg, nArg); } if( addrIf ) sqlite3VdbeJumpHere(v, addrIf); } } } |
︙ | ︙ |
Changes to test/concurrent9.test.
︙ | ︙ | |||
46 47 48 49 50 51 52 53 54 55 | COMMIT; } do_execsql_test -db db2 1.4 { SELECT * FROM t1; SELECT * FROM t2; } {1 2 3 a b c} finish_test | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 | COMMIT; } do_execsql_test -db db2 1.4 { SELECT * FROM t1; SELECT * FROM t2; } {1 2 3 a b c} db2 close #------------------------------------------------------------------------- reset_db do_execsql_test 2.1 { CREATE TABLE t1(a INTEGER PRIMARY KEY, b); PRAGMA journal_mode = wal; WITH s(i) AS ( SELECT 1 UNION SELECT i+1 FROM s WHERE i<500 ) INSERT INTO t1(b) SELECT hex(randomblob(200)) FROM s; PRAGMA page_count; } {wal 255} sqlite3 db2 test.db do_execsql_test -db db2 2.2 { DELETE FROM t1 WHERE a<100; PRAGMA freelist_count; } {49} do_execsql_test 2.3 { BEGIN CONCURRENT; WITH s(i) AS ( SELECT 1 UNION SELECT i+1 FROM s WHERE i<100 ) INSERT INTO t1(b) SELECT hex(randomblob(200)) FROM s; } sqlite3_db_status db CACHE_MISS 1 do_execsql_test 2.4.1 { COMMIT; } do_test 2.4.2 { lindex [sqlite3_db_status db CACHE_MISS 0] 1 } {1} do_execsql_test -db db2 2.5 { DELETE FROM t1 WHERE a<200; PRAGMA freelist_count; } {50} do_execsql_test 2.6 { BEGIN CONCURRENT; WITH s(i) AS ( SELECT 1 UNION SELECT i+1 FROM s WHERE i<100 ) INSERT INTO t1(b) SELECT hex(randomblob(200)) FROM s; DELETE FROM t1 WHERE rowid BETWEEN 600 AND 680; } sqlite3_db_status db CACHE_MISS 1 do_execsql_test 2.7.1 { COMMIT; } do_test 2.7.2 { lindex [sqlite3_db_status db CACHE_MISS 0] 1 } {1} do_execsql_test 2.8 { PRAGMA integrity_check; } {ok} finish_test |
Changes to test/func.test.
︙ | ︙ | |||
1182 1183 1184 1185 1186 1187 1188 | # test extensions. # unset -nocomplain midargs set midargs {} unset -nocomplain midres set midres {} unset -nocomplain result | | > > | 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 | # test extensions. # unset -nocomplain midargs set midargs {} unset -nocomplain midres set midres {} unset -nocomplain result set limit [sqlite3_limit db SQLITE_LIMIT_FUNCTION_ARG -1] if {$limit>400} {set limit 400} for {set i 1} {$i<$limit} {incr i} { append midargs ,'/$i' append midres /$i set result [md5 \ "this${midres}program${midres}is${midres}free${midres}software${midres}"] set sql "SELECT md5sum(t1$midargs) FROM tbl1" do_test func-24.7.$i { db eval $::sql |
︙ | ︙ | |||
1260 1261 1262 1263 1264 1265 1266 | # The previous test (func-26.1) registered a function with a very long # function name that takes many arguments and always returns NULL. Verify # that this function works correctly. # do_test func-26.2 { set a {} | > | > | | 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 | # The previous test (func-26.1) registered a function with a very long # function name that takes many arguments and always returns NULL. Verify # that this function works correctly. # do_test func-26.2 { set a {} set limit $::SQLITE_MAX_FUNCTION_ARG for {set i 1} {$i<=$limit} {incr i} { lappend a $i } db eval " SELECT nullx_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789([join $a ,]); " } {{}} do_test func-26.3 { set a {} for {set i 1} {$i<=$::SQLITE_MAX_FUNCTION_ARG+1} {incr i} { lappend a $i } catchsql " SELECT nullx_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789([join $a ,]); " } {1 {too many arguments on function nullx_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789}} do_test func-26.4 { set a {} set limit [expr {$::SQLITE_MAX_FUNCTION_ARG-1}] for {set i 1} {$i<=$limit} {incr i} { lappend a $i } catchsql " SELECT nullx_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789([join $a ,]); " } {1 {wrong number of arguments to function nullx_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789()}} do_test func-26.5 { |
︙ | ︙ |
Changes to test/permutations.test.
︙ | ︙ | |||
192 193 194 195 196 197 198 199 200 201 202 203 204 205 | "Very" quick test suite. Runs in minutes on a workstation. This test suite is the same as the "quick" tests, except that some files that test malloc and IO errors are omitted. } -files [ test_set $allquicktests -exclude *malloc* *ioerr* *fault* *bigfile* *_err* \ *fts5corrupt* *fts5big* *fts5aj* *rbucrash* ] test_suite "shell" -prefix "" -description { Run tests of the command-line shell } -files [ test_set [glob $testdir/shell*.test] ] | > > > > > > > > > > > | 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 | "Very" quick test suite. Runs in minutes on a workstation. This test suite is the same as the "quick" tests, except that some files that test malloc and IO errors are omitted. } -files [ test_set $allquicktests -exclude *malloc* *ioerr* *fault* *bigfile* *_err* \ *fts5corrupt* *fts5big* *fts5aj* *rbucrash* ] test_suite "schemacopytest" -prefix "schemacopytest-" -description { "Very" quick test suite. Runs in minutes on a workstation. This test suite is the same as the "quick" tests, except that some files that test malloc and IO errors are omitted. } -files [ test_set $allquicktests -exclude *malloc* *ioerr* *fault* *bigfile* *_err* \ *fts5corrupt* *fts5big* *fts5aj* *rbucrash* ] -initialize { sqlite3_test_control SQLITE_TESTCTRL_SCHEMACOPY 1 } test_suite "shell" -prefix "" -description { Run tests of the command-line shell } -files [ test_set [glob $testdir/shell*.test] ] |
︙ | ︙ |
Added test/schemacopy.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 143 144 145 146 147 | # 2025 January 4 # # 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. # #*********************************************************************** # This file implements regression tests for SQLite library. # set testdir [file dirname $argv0] source $testdir/tester.tcl set testprefix schemacopy do_execsql_test 1.0 { CREATE TABLE t1(a, b); INSERT INTO t1 VALUES(1, 2), (3, 4); } do_test 1.1 { sqlite3 db2 test.db sqlite3_schema_copy db2 main db main } SQLITE_OK db close do_execsql_test -db db2 1.2 { SELECT * FROM t1 } {1 2 3 4} #------------------------------------------------------------------------- reset_db do_execsql_test 2.0 { CREATE TABLE t1(a INTEGER PRIMARY KEY, b UNIQUE, c INTEGER, d); CREATE INDEX i1 ON t1( (c+d) ); CREATE INDEX i2 ON t1( (c+d) DESC, (d-c) ASC); CREATE INDEX i3 ON t1( c, d ) WHERE b<3; CREATE INDEX i4 ON t1( d COLLATE nocase); CREATE INDEX i5 ON t1( c ); CREATE TABLE t2(x, y PRIMARY KEY, z) WITHOUT ROWID; CREATE TABLE t3(x COLLATE nocase, y, z, PRIMARY KEY(x, y)) WITHOUT ROWID; CREATE UNIQUE INDEX t3i1 ON t3(z); CREATE TABLE t4(a, b, c); CREATE TABLE log(x); CREATE TRIGGER t4ai AFTER INSERT ON t4 WHEN new.a!='value' BEGIN INSERT INTO log VALUES(new.a ||','|| new.b ||','|| new.c); UPDATE log SET x = new.rowid || ':' || x WHERE rowid = ( SELECT max(rowid) FROM log ); END; CREATE TABLE x1(a INTEGER PRIMARY KEY, b); CREATE TABLE x2(a INTEGER PRIMARY KEY, b); CREATE TABLE x3(a INTEGER PRIMARY KEY, b); CREATE VIEW xx AS SELECT a, b FROM x1 UNION ALL SELECT a, b FROM x2 UNION ALL SELECT a, b FROM x3; SELECT * FROM xx; } do_test 2.1 { sqlite3 db2 test.db sqlite3_schema_copy db2 main db main } SQLITE_OK do_execsql_test -db db2 2.2 { INSERT INTO t1 VALUES(1, 2, 3, 4); INSERT INTO t1 VALUES(4, 3, 2, 1); INSERT INTO t1 VALUES(NULL, 4, NULL, 'abc'); INSERT INTO t1 VALUES(NULL, 5, NULL, 'AbC'); INSERT INTO t1 VALUES(NULL, 6, NULL, 'DEF'); INSERT INTO t1 VALUES(NULL, 7, NULL, 'def'); INSERT INTO t1 VALUES(NULL, 8, '456', 11); INSERT INTO t1 VALUES(NULL, 9, '016', 11); INSERT INTO t2 VALUES('a', 'b', 'c'); INSERT INTO t3 VALUES('abc', 'b', '1'); INSERT INTO t3 VALUES('abc', 'c', '2'); INSERT INTO t3 VALUES('def', 'a', '3'); INSERT INTO t3 VALUES('DEF', 'b', '4'); INSERT INTO t3 VALUES('aBc', 'd', '5'); INSERT INTO t3 VALUES('ABC', 'e', '6'); } do_execsql_test -db db2 2.3 { SELECT * FROM t1 WHERE c='000016' } {10 9 16 11} do_eqp_test 2.4 { SELECT * FROM t1 WHERE c='000016' } {i5} do_execsql_test -db db2 2.5.1 { INSERT INTO t4 VALUES('a', 'b', 'c'); } do_execsql_test -db db2 2.5.2 { INSERT INTO t4 VALUES(1, 2, 3); } do_execsql_test -db db2 2.5.3 { SELECT * FROM log; } { 1:a,b,c 2:1,2,3 } do_test 2.5.4 { sqlite3 db3 test.db sqlite3_schema_copy db3 main db2 main } SQLITE_OK db2 close do_execsql_test -db db3 2.5.5 { INSERT INTO t4 VALUES(11,22,33); } do_execsql_test -db db3 2.5.3 { SELECT * FROM log; } { 1:a,b,c 2:1,2,3 3:11,22,33 } do_execsql_test -db db3 2.6.1 { INSERT INTO x1 VALUES(1, 'ii'); INSERT INTO x2 VALUES(3, 'iv'); INSERT INTO x3 VALUES(5, 'vi'); SELECT * FROM xx; } { 1 ii 3 iv 5 vi } do_execsql_test 2.integrity { PRAGMA integrity_check } {ok} finish_test |
Changes to test/tester.tcl.
︙ | ︙ | |||
96 97 98 99 100 101 102 | # configure SQLite to take database file locks on the page that begins # 64KB into the database file instead of the one 1GB in. This means # the code that handles that special case can be tested without creating # very large database files. # set tcl_precision 15 sqlite3_test_control_pending_byte 0x0010000 | < | 96 97 98 99 100 101 102 103 104 105 106 107 108 109 | # configure SQLite to take database file locks on the page that begins # 64KB into the database file instead of the one 1GB in. This means # the code that handles that special case can be tested without creating # very large database files. # set tcl_precision 15 sqlite3_test_control_pending_byte 0x0010000 # If the pager codec is available, create a wrapper for the [sqlite3] # command that appends "-key {xyzzy}" to the command line. i.e. this: # # sqlite3 db test.db # # becomes |
︙ | ︙ |
Changes to test/testrunner.tcl.
︙ | ︙ | |||
1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 | # proc add_devtest_jobs {lBld patternlist} { global TRG foreach b $lBld { set bld [add_build_job $b $TRG(testfixture)] add_tcl_jobs $bld veryquick $patternlist SHELL if {$patternlist==""} { add_fuzztest_jobs $b } if {[trdb one "SELECT EXISTS (SELECT 1 FROM jobs WHERE depid='SHELL')"]} { set sbld [add_shell_build_job $b [lindex $bld 1] [lindex $bld 0]] set sbldid [lindex $sbld 0] | > | 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 | # proc add_devtest_jobs {lBld patternlist} { global TRG foreach b $lBld { set bld [add_build_job $b $TRG(testfixture)] add_tcl_jobs $bld veryquick $patternlist SHELL add_tcl_jobs $bld schemacopytest $patternlist if {$patternlist==""} { add_fuzztest_jobs $b } if {[trdb one "SELECT EXISTS (SELECT 1 FROM jobs WHERE depid='SHELL')"]} { set sbld [add_shell_build_job $b [lindex $bld 1] [lindex $bld 0]] set sbldid [lindex $sbld 0] |
︙ | ︙ |
Added test/wal2big2.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 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 | # 2024 November 28 # # 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. # #*********************************************************************** # TESTRUNNER: slow # set testdir [file dirname $argv0] source $testdir/tester.tcl source $testdir/lock_common.tcl source $testdir/malloc_common.tcl source $testdir/wal_common.tcl set testprefix wal2big2 ifcapable !wal {finish_test ; return } do_execsql_test 1.0 { PRAGMA journal_mode = wal2; CREATE TABLE t1(a INTEGER PRIMARY KEY, b); CREATE INDEX i1 ON t1(b); PRAGMA wal_autocheckpoint = 0; PRAGMA journal_size_limit = 100000; PRAGMA synchronous = off; } {wal2 0 100000} do_execsql_test 1.1 { INSERT INTO t1 VALUES(1, 'one'); } do_test 1.2 { list [file size test.db-wal] [file size test.db-wal2] } {6320 0} do_execsql_test 1.3 { PRAGMA wal_checkpoint; INSERT INTO t1 VALUES(2, 'two'); } {0 6 0} do_test 1.4 { list [file size test.db-wal] [file size test.db-wal2] } {8416 0} proc hexrandomblob {n} { for {set j 0} {$j < $n} {incr j 2} { append ret [format "%02X" [expr {int(rand() * 256)}]] } return $ret } db func hexrandomblob hexrandomblob expr srand(0) do_test 1.5 { for {set ii 3} {$ii < 100} {incr ii} { execsql { INSERT INTO t1 VALUES($ii, hexrandomblob(80)); } } list [file size test.db-wal] [file size test.db-wal2] } {101688 224304} do_execsql_test 1.6 { PRAGMA integrity_check; } {ok} do_execsql_test 1.7 { PRAGMA wal_checkpoint = RESTART; } {0 311 97} do_execsql_test 1.8 { PRAGMA integrity_check; } {ok} sqlite3 db2 test.db do_execsql_test -db db2 1.9 { PRAGMA integrity_check; } {ok} do_execsql_test 1.10 { PRAGMA journal_size_limit = 10000000; } {10000000} do_test 1.11 { for {set ii 0} {$ii < 8000} {incr ii} { execsql { INSERT INTO t1 VALUES(nULL, hex(randomblob(40))); } } list [expr [file size test.db-wal]>10000000] \ [expr [file size test.db-wal2]>10000000] \ } {1 1} do_execsql_test -db db2 1.12 { PRAGMA integrity_check; } {ok} do_test 1.13 { db eval { PRAGMA wal_checkpoint = RESTART } set {} {} } {} do_execsql_test -db db2 1.14 { PRAGMA integrity_check; } {ok} do_execsql_test 1.15 { INSERT INTO t1 VALUES(nULL, hex(randomblob(40))); } #------------------------------------------------------------------------- do_multiclient_test tn { do_test 1.$tn.0 { sql1 { CREATE TABLE t1(a, b); INSERT INTO t1 VALUES('A', 'B'); CREATE INDEX i1 ON t1(a, b); PRAGMA journal_mode = wal2; PRAGMA journal_size_limit = 100000; } } {wal2 100000} do_test 1.$tn.1 { sql2 { PRAGMA cache_size = 5; } } {} do_test 1.$tn.2 { for {set ii 0} {$ii < 500} {incr ii} { sql1 { INSERT INTO t1 VALUES(hex(randomblob(20)), hex(randomblob(20))); } } } {} do_test 1.$tn.3 { list [expr [file size test.db-wal]>100000] \ [expr [file size test.db-wal2]>100000] } {1 1} do_test 1.$tn.4 { sql2 { BEGIN; PRAGMA integrity_check; } } {ok} do_test 1.$tn.5 { sql1 { PRAGMA wal_checkpoint = RESTART; } set {} {} } {} do_test 1.$tn.6 { sql2 { PRAGMA integrity_check; COMMIT; } } {ok} do_test 1.$tn.7 { sql1 { INSERT INTO t1 VALUES(hex(randomblob(20)), hex(randomblob(20))); } code1 { set ::n_handler 0 proc handler {nTry} { incr ::n_handler if {$nTry>10} { sql2 { COMMIT; BEGIN; PRAGMA integrity_check; } } return 0 } db busy handler } } {} do_test 1.$tn.8 { sql2 { BEGIN; PRAGMA integrity_check; } } {ok} do_test 1.$tn.9 { sql1 { PRAGMA wal_checkpoint = RESTART; } code1 { set ::n_handler } } {12} do_test 1.$tn.10 { sql2 COMMIT } {} } finish_test |
Changes to test/wal2simple.test.
︙ | ︙ | |||
465 466 467 468 469 470 471 472 473 474 475 | list [file size test.db-wal] [file size test.db-wal2] [file size test.db] } {22040 12608 87040} do_test 7.5.4 { execsql END db2 execsql { INSERT INTO t1 VALUES(randomblob(5000)) } list [file size test.db-wal] [file size test.db-wal2] [file size test.db] } {22040 12608 87040} finish_test | > > > > > > > > > > > > > > > > > > > > > > > > > > > | 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 | list [file size test.db-wal] [file size test.db-wal2] [file size test.db] } {22040 12608 87040} do_test 7.5.4 { execsql END db2 execsql { INSERT INTO t1 VALUES(randomblob(5000)) } list [file size test.db-wal] [file size test.db-wal2] [file size test.db] } {22040 12608 87040} #------------------------------------------------------------------------- # Check that it is possible to do a non-PASSIVE checkpoint on a wal2 # db without blocking writers. # reset_db do_execsql_test 8.0 { PRAGMA journal_size_limit = 10000; PRAGMA journal_mode = wal2; CREATE TABLE t1(x); INSERT INTO t1 VALUES( hex( randomblob(5000) ) ); INSERT INTO t1 VALUES( hex( randomblob(5000) ) ); INSERT INTO t1 VALUES( hex( randomblob(5000) ) ); INSERT INTO t1 VALUES( hex( randomblob(5000) ) ); BEGIN; INSERT INTO t1 VALUES( hex( randomblob(5000) ) ); } {10000 wal2} sqlite3 db2 test.db do_execsql_test -db db2 8.1 { PRAGMA wal_checkpoint = FULL; } {0 50 13} do_execsql_test 8.2 { COMMIT; } finish_test |