Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Pull in the patches to support read-only WAL databases into a new branch off of the apple-osx branch. This also pulls in all the other pending 3.7.7 changes such as URI support. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | apple-wal-readonly |
Files: | files | file ages | folders |
SHA1: |
97b980107676b2ea45a07c9c1a7de2e1 |
User & Date: | drh 2011-05-12 15:32:51.588 |
Context
2011-05-19
| ||
02:34 | Bring the apple-wal-readonly branch up to date with the latest changes in apple-osx, and especially the fix for disappearing WAL transactions. (Leaf check-in: 5791232778 user: drh tags: apple-wal-readonly) | |
2011-05-12
| ||
15:32 | Pull in the patches to support read-only WAL databases into a new branch off of the apple-osx branch. This also pulls in all the other pending 3.7.7 changes such as URI support. (check-in: 97b9801076 user: drh tags: apple-wal-readonly) | |
2011-05-11
| ||
17:36 | Add missing comments associated with readonly shm changes. (check-in: 6a2ea52e6c user: dan tags: wal-readonly) | |
2011-05-05
| ||
15:52 | Merge the latest trunk changes into the apple-osx branch. (check-in: f9b149e538 user: drh tags: apple-osx) | |
Changes
Changes to ext/fts3/fts3.c.
︙ | ︙ | |||
3657 3658 3659 3660 3661 3662 3663 | } static int fts3RollbackToMethod(sqlite3_vtab *pVtab, int iSavepoint){ sqlite3Fts3PendingTermsClear((Fts3Table *)pVtab); return SQLITE_OK; } static const sqlite3_module fts3Module = { | | | 3657 3658 3659 3660 3661 3662 3663 3664 3665 3666 3667 3668 3669 3670 3671 | } static int fts3RollbackToMethod(sqlite3_vtab *pVtab, int iSavepoint){ sqlite3Fts3PendingTermsClear((Fts3Table *)pVtab); return SQLITE_OK; } static const sqlite3_module fts3Module = { /* iVersion */ 2, /* xCreate */ fts3CreateMethod, /* xConnect */ fts3ConnectMethod, /* xBestIndex */ fts3BestIndexMethod, /* xDisconnect */ fts3DisconnectMethod, /* xDestroy */ fts3DestroyMethod, /* xOpen */ fts3OpenMethod, /* xClose */ fts3CloseMethod, |
︙ | ︙ |
Changes to src/attach.c.
︙ | ︙ | |||
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 | sqlite3_value **argv ){ int i; int rc = 0; sqlite3 *db = sqlite3_context_db_handle(context); const char *zName; const char *zFile; Db *aNew; char *zErrDyn = 0; UNUSED_PARAMETER(NotUsed); zFile = (const char *)sqlite3_value_text(argv[0]); zName = (const char *)sqlite3_value_text(argv[1]); if( zFile==0 ) zFile = ""; if( zName==0 ) zName = ""; | > > > > > > | 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | sqlite3_value **argv ){ int i; int rc = 0; sqlite3 *db = sqlite3_context_db_handle(context); const char *zName; const char *zFile; char *zPath = 0; char *zErr = 0; unsigned int flags; Db *aNew; char *zErrDyn = 0; sqlite3_vfs *pVfs; const char *zVfs = db->pVfs->zName; /* Name of default (main) VFS */ int btflags = 0; UNUSED_PARAMETER(NotUsed); zFile = (const char *)sqlite3_value_text(argv[0]); zName = (const char *)sqlite3_value_text(argv[1]); if( zFile==0 ) zFile = ""; if( zName==0 ) zName = ""; |
︙ | ︙ | |||
120 121 122 123 124 125 126 | aNew = &db->aDb[db->nDb]; memset(aNew, 0, sizeof(*aNew)); /* Open the database file. If the btree is successfully opened, use ** it to obtain the database schema. At this point the schema may ** or may not be initialised. */ | > > > > > | > > > | > > | 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 | aNew = &db->aDb[db->nDb]; memset(aNew, 0, sizeof(*aNew)); /* Open the database file. If the btree is successfully opened, use ** it to obtain the database schema. At this point the schema may ** or may not be initialised. */ flags = db->openFlags; rc = sqlite3ParseUri(zVfs, zFile, &flags, &btflags, &pVfs, &zPath, &zErr); if( rc!=SQLITE_OK ){ if( rc==SQLITE_NOMEM ) db->mallocFailed = 1; sqlite3_result_error(context, zErr, -1); sqlite3_free(zErr); return; } assert( pVfs ); flags |= SQLITE_OPEN_MAIN_DB; rc = sqlite3BtreeOpen(pVfs, zPath, db, &aNew->pBt, btflags, flags); sqlite3_free( zPath ); db->nDb++; if( rc==SQLITE_CONSTRAINT ){ rc = SQLITE_ERROR; zErrDyn = sqlite3MPrintf(db, "database is already attached"); }else if( rc==SQLITE_OK ){ Pager *pPager; aNew->pSchema = sqlite3SchemaGet(db, aNew->pBt); |
︙ | ︙ |
Changes to src/btree.c.
︙ | ︙ | |||
1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 | ** If the database is already opened in the same database connection ** and we are in shared cache mode, then the open will fail with an ** SQLITE_CONSTRAINT error. We cannot allow two or more BtShared ** objects in the same database connection since doing so will lead ** to problems with locking. */ int sqlite3BtreeOpen( const char *zFilename, /* Name of the file containing the BTree database */ sqlite3 *db, /* Associated database handle */ Btree **ppBtree, /* Pointer to new Btree object written here */ int flags, /* Options */ int vfsFlags /* Flags passed through to sqlite3_vfs.xOpen() */ ){ | > < | 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 | ** If the database is already opened in the same database connection ** and we are in shared cache mode, then the open will fail with an ** SQLITE_CONSTRAINT error. We cannot allow two or more BtShared ** objects in the same database connection since doing so will lead ** to problems with locking. */ int sqlite3BtreeOpen( sqlite3_vfs *pVfs, /* VFS to use for this b-tree */ const char *zFilename, /* Name of the file containing the BTree database */ sqlite3 *db, /* Associated database handle */ Btree **ppBtree, /* Pointer to new Btree object written here */ int flags, /* Options */ int vfsFlags /* Flags passed through to sqlite3_vfs.xOpen() */ ){ BtShared *pBt = 0; /* Shared part of btree structure */ Btree *p; /* Handle to return */ sqlite3_mutex *mutexOpen = 0; /* Prevents a race condition. Ticket #3537 */ int rc = SQLITE_OK; /* Result code from this function */ u8 nReserve; /* Byte of unused space on each page */ unsigned char zDbHeader[100]; /* Database header content */ |
︙ | ︙ | |||
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 | const int isMemdb = 0; #else const int isMemdb = (zFilename && strcmp(zFilename, ":memory:")==0) || (isTempDb && sqlite3TempInMemory(db)); #endif assert( db!=0 ); assert( sqlite3_mutex_held(db->mutex) ); assert( (flags&0xff)==flags ); /* flags fit in 8 bits */ /* Only a BTREE_SINGLE database can be BTREE_UNORDERED */ assert( (flags & BTREE_UNORDERED)==0 || (flags & BTREE_SINGLE)!=0 ); /* A BTREE_SINGLE database is always a temporary and/or ephemeral */ assert( (flags & BTREE_SINGLE)==0 || isTempDb ); if( db->flags & SQLITE_NoReadlock ){ flags |= BTREE_NO_READLOCK; } if( isMemdb ){ flags |= BTREE_MEMORY; } if( (vfsFlags & SQLITE_OPEN_MAIN_DB)!=0 && (isMemdb || isTempDb) ){ vfsFlags = (vfsFlags & ~SQLITE_OPEN_MAIN_DB) | SQLITE_OPEN_TEMP_DB; } | > < | 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 | const int isMemdb = 0; #else const int isMemdb = (zFilename && strcmp(zFilename, ":memory:")==0) || (isTempDb && sqlite3TempInMemory(db)); #endif assert( db!=0 ); assert( pVfs!=0 ); assert( sqlite3_mutex_held(db->mutex) ); assert( (flags&0xff)==flags ); /* flags fit in 8 bits */ /* Only a BTREE_SINGLE database can be BTREE_UNORDERED */ assert( (flags & BTREE_UNORDERED)==0 || (flags & BTREE_SINGLE)!=0 ); /* A BTREE_SINGLE database is always a temporary and/or ephemeral */ assert( (flags & BTREE_SINGLE)==0 || isTempDb ); if( db->flags & SQLITE_NoReadlock ){ flags |= BTREE_NO_READLOCK; } if( isMemdb ){ flags |= BTREE_MEMORY; } if( (vfsFlags & SQLITE_OPEN_MAIN_DB)!=0 && (isMemdb || isTempDb) ){ vfsFlags = (vfsFlags & ~SQLITE_OPEN_MAIN_DB) | SQLITE_OPEN_TEMP_DB; } p = sqlite3MallocZero(sizeof(Btree)); if( !p ){ return SQLITE_NOMEM; } p->inTrans = TRANS_NONE; p->db = db; #ifndef SQLITE_OMIT_SHARED_CACHE |
︙ | ︙ |
Changes to src/btree.h.
︙ | ︙ | |||
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 | */ typedef struct Btree Btree; typedef struct BtCursor BtCursor; typedef struct BtShared BtShared; int sqlite3BtreeOpen( const char *zFilename, /* Name of database file to open */ sqlite3 *db, /* Associated database connection */ Btree **ppBtree, /* Return open Btree* here */ int flags, /* Flags */ int vfsFlags /* Flags passed through to VFS open */ ); /* The flags parameter to sqlite3BtreeOpen can be the bitwise or of the ** following values. ** ** NOTE: These values must match the corresponding PAGER_ values in ** pager.h. */ #define BTREE_OMIT_JOURNAL 1 /* Do not create or use a rollback journal */ #define BTREE_NO_READLOCK 2 /* Omit readlocks on readonly files */ #define BTREE_MEMORY 4 /* This is an in-memory DB */ #define BTREE_SINGLE 8 /* The file contains at most 1 b-tree */ #define BTREE_UNORDERED 16 /* Use of a hash implementation is OK */ int sqlite3BtreeClose(Btree*); int sqlite3BtreeSetCacheSize(Btree*,int); int sqlite3BtreeSetSafetyLevel(Btree*,int,int,int); int sqlite3BtreeSyncDisabled(Btree*); int sqlite3BtreeSetPageSize(Btree *p, int nPagesize, int nReserve, int eFix); int sqlite3BtreeGetPageSize(Btree*); | > > | 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 | */ typedef struct Btree Btree; typedef struct BtCursor BtCursor; typedef struct BtShared BtShared; int sqlite3BtreeOpen( sqlite3_vfs *pVfs, /* VFS to use with this b-tree */ const char *zFilename, /* Name of database file to open */ sqlite3 *db, /* Associated database connection */ Btree **ppBtree, /* Return open Btree* here */ int flags, /* Flags */ int vfsFlags /* Flags passed through to VFS open */ ); /* The flags parameter to sqlite3BtreeOpen can be the bitwise or of the ** following values. ** ** NOTE: These values must match the corresponding PAGER_ values in ** pager.h. */ #define BTREE_OMIT_JOURNAL 1 /* Do not create or use a rollback journal */ #define BTREE_NO_READLOCK 2 /* Omit readlocks on readonly files */ #define BTREE_MEMORY 4 /* This is an in-memory DB */ #define BTREE_SINGLE 8 /* The file contains at most 1 b-tree */ #define BTREE_UNORDERED 16 /* Use of a hash implementation is OK */ #define BTREE_READONLYSHM 32 /* Read-only SHM access is acceptable */ int sqlite3BtreeClose(Btree*); int sqlite3BtreeSetCacheSize(Btree*,int); int sqlite3BtreeSetSafetyLevel(Btree*,int,int,int); int sqlite3BtreeSyncDisabled(Btree*); int sqlite3BtreeSetPageSize(Btree *p, int nPagesize, int nReserve, int eFix); int sqlite3BtreeGetPageSize(Btree*); |
︙ | ︙ |
Changes to src/build.c.
︙ | ︙ | |||
3439 3440 3441 3442 3443 3444 3445 | static const int flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_EXCLUSIVE | SQLITE_OPEN_DELETEONCLOSE | SQLITE_OPEN_TEMP_DB; | | | 3439 3440 3441 3442 3443 3444 3445 3446 3447 3448 3449 3450 3451 3452 3453 | static const int flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_EXCLUSIVE | SQLITE_OPEN_DELETEONCLOSE | SQLITE_OPEN_TEMP_DB; rc = sqlite3BtreeOpen(db->pVfs, 0, db, &pBt, 0, flags); if( rc!=SQLITE_OK ){ sqlite3ErrorMsg(pParse, "unable to open a temporary database " "file for storing temporary tables"); pParse->rc = rc; return 1; } db->aDb[1].pBt = pBt; |
︙ | ︙ |
Changes to src/global.c.
︙ | ︙ | |||
125 126 127 128 129 130 131 | 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* e0..e7 ........ */ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* e8..ef ........ */ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* f0..f7 ........ */ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40 /* f8..ff ........ */ }; #endif | | > > > | 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 | 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* e0..e7 ........ */ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* e8..ef ........ */ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* f0..f7 ........ */ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40 /* f8..ff ........ */ }; #endif #ifndef SQLITE_USE_URI # define SQLITE_USE_URI 0 #endif /* ** The following singleton contains the global configuration for ** the SQLite library. */ SQLITE_WSD struct Sqlite3Config sqlite3Config = { SQLITE_DEFAULT_MEMSTATUS, /* bMemstat */ 1, /* bCoreMutex */ SQLITE_THREADSAFE==1, /* bFullMutex */ SQLITE_USE_URI, /* bOpenUri */ 0x7ffffffe, /* mxStrlen */ 100, /* szLookaside */ 500, /* nLookaside */ {0,0,0,0,0,0,0,0}, /* m */ {0,0,0,0,0,0,0,0,0}, /* mutex */ {0,0,0,0,0,0,0,0,0,0,0}, /* pcache */ (void*)0, /* pHeap */ |
︙ | ︙ |
Changes to src/main.c.
︙ | ︙ | |||
424 425 426 427 428 429 430 431 432 433 434 435 436 437 | ** sqlite3GlobalConfig.xLog = va_arg(ap, void(*)(void*,int,const char*)); */ typedef void(*LOGFUNC_t)(void*,int,const char*); sqlite3GlobalConfig.xLog = va_arg(ap, LOGFUNC_t); sqlite3GlobalConfig.pLogArg = va_arg(ap, void*); break; } default: { rc = SQLITE_ERROR; break; } } va_end(ap); | > > > > > | 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 | ** sqlite3GlobalConfig.xLog = va_arg(ap, void(*)(void*,int,const char*)); */ typedef void(*LOGFUNC_t)(void*,int,const char*); sqlite3GlobalConfig.xLog = va_arg(ap, LOGFUNC_t); sqlite3GlobalConfig.pLogArg = va_arg(ap, void*); break; } case SQLITE_CONFIG_URI: { sqlite3GlobalConfig.bOpenUri = va_arg(ap, int); break; } default: { rc = SQLITE_ERROR; break; } } va_end(ap); |
︙ | ︙ | |||
1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 | } #if defined(SQLITE_ENABLE_AUTO_PROFILE) static void profile_sql(void *aux, const char *sql, u64 ns) { #pragma unused(aux) fprintf(stderr, "Query: %s\n Execution Time: %llu ms\n", sql, ns / 1000000); } #endif /* ** This routine does the work of opening a database on behalf of ** sqlite3_open() and sqlite3_open16(). The database filename "zFilename" ** is UTF-8 encoded. */ static int openDatabase( const char *zFilename, /* Database filename UTF-8 encoded */ sqlite3 **ppDb, /* OUT: Returned database handle */ | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | | | > > > | 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 1939 1940 1941 1942 1943 1944 1945 1946 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 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 | } #if defined(SQLITE_ENABLE_AUTO_PROFILE) static void profile_sql(void *aux, const char *sql, u64 ns) { #pragma unused(aux) fprintf(stderr, "Query: %s\n Execution Time: %llu ms\n", sql, ns / 1000000); } #endif /* ** This function is used to parse both URIs and non-URI filenames passed by the ** user to API functions sqlite3_open() or sqlite3_open_v2(), and for database ** URIs specified as part of ATTACH statements. ** ** The first argument to this function is the name of the VFS to use (or ** a NULL to signify the default VFS) if the URI does not contain a "vfs=xxx" ** query parameter. The second argument contains the URI (or non-URI filename) ** itself. When this function is called the *pFlags variable should contain ** the default flags to open the database handle with. The value stored in ** *pFlags may be updated before returning if the URI filename contains ** "cache=xxx" or "mode=xxx" query parameters. ** ** The third argument, pBtflags, points to an integer containing the flags ** that will be passed as the 5th argument to sqlite3BtreeOpen (BTREE_XXX ** flags). This value will be edited if the URI filename contains a ** "readonly_shm=1" or "readonly_shm=0" query parameter. ** ** If successful, SQLITE_OK is returned. In this case *ppVfs is set to point to ** the VFS that should be used to open the database file. *pzFile is set to ** point to a buffer containing the name of the file to open. It is the ** responsibility of the caller to eventually call sqlite3_free() to release ** this buffer. ** ** If an error occurs, then an SQLite error code is returned and *pzErrMsg ** may be set to point to a buffer containing an English language error ** message. It is the responsibility of the caller to eventually release ** this buffer by calling sqlite3_free(). */ int sqlite3ParseUri( const char *zDefaultVfs, /* VFS to use if no "vfs=xxx" query option */ const char *zUri, /* Nul-terminated URI to parse */ unsigned int *pFlags, /* IN/OUT: SQLITE_OPEN_XXX flags */ int *pBtflags, /* IN/OUT: BTREE_XXX flags */ sqlite3_vfs **ppVfs, /* OUT: VFS to use */ char **pzFile, /* OUT: Filename component of URI */ char **pzErrMsg /* OUT: Error message (if rc!=SQLITE_OK) */ ){ int rc = SQLITE_OK; unsigned int flags = *pFlags; const char *zVfs = zDefaultVfs; char *zFile; char c; int nUri = sqlite3Strlen30(zUri); assert( *pzErrMsg==0 ); if( ((flags & SQLITE_OPEN_URI) || sqlite3GlobalConfig.bOpenUri) && nUri>=5 && memcmp(zUri, "file:", 5)==0 ){ char *zOpt; int eState; /* Parser state when parsing URI */ int iIn; /* Input character index */ int iOut = 0; /* Output character index */ int nByte = nUri+2; /* Bytes of space to allocate */ /* Make sure the SQLITE_OPEN_URI flag is set to indicate to the VFS xOpen ** method that there may be extra parameters following the file-name. */ flags |= SQLITE_OPEN_URI; for(iIn=0; iIn<nUri; iIn++) nByte += (zUri[iIn]=='&'); zFile = sqlite3_malloc(nByte); if( !zFile ) return SQLITE_NOMEM; /* Discard the scheme and authority segments of the URI. */ if( zUri[5]=='/' && zUri[6]=='/' ){ iIn = 7; while( zUri[iIn] && zUri[iIn]!='/' ) iIn++; if( iIn!=7 && (iIn!=16 || memcmp("localhost", &zUri[7], 9)) ){ *pzErrMsg = sqlite3_mprintf("invalid uri authority: %.*s", iIn-7, &zUri[7]); rc = SQLITE_ERROR; goto parse_uri_out; } }else{ iIn = 5; } /* Copy the filename and any query parameters into the zFile buffer. ** Decode %HH escape codes along the way. ** ** Within this loop, variable eState may be set to 0, 1 or 2, depending ** on the parsing context. As follows: ** ** 0: Parsing file-name. ** 1: Parsing name section of a name=value query parameter. ** 2: Parsing value section of a name=value query parameter. */ eState = 0; while( (c = zUri[iIn])!=0 && c!='#' ){ iIn++; if( c=='%' && sqlite3Isxdigit(zUri[iIn]) && sqlite3Isxdigit(zUri[iIn+1]) ){ int octet = (sqlite3HexToInt(zUri[iIn++]) << 4); octet += sqlite3HexToInt(zUri[iIn++]); assert( octet>=0 && octet<256 ); if( octet==0 ){ /* This branch is taken when "%00" appears within the URI. In this ** case we ignore all text in the remainder of the path, name or ** value currently being parsed. So ignore the current character ** and skip to the next "?", "=" or "&", as appropriate. */ while( (c = zUri[iIn])!=0 && c!='#' && (eState!=0 || c!='?') && (eState!=1 || (c!='=' && c!='&')) && (eState!=2 || c!='&') ){ iIn++; } continue; } c = octet; }else if( eState==1 && (c=='&' || c=='=') ){ if( zFile[iOut-1]==0 ){ /* An empty option name. Ignore this option altogether. */ while( zUri[iIn] && zUri[iIn]!='#' && zUri[iIn-1]!='&' ) iIn++; continue; } if( c=='&' ){ zFile[iOut++] = '\0'; }else{ eState = 2; } c = 0; }else if( (eState==0 && c=='?') || (eState==2 && c=='&') ){ c = 0; eState = 1; } zFile[iOut++] = c; } if( eState==1 ) zFile[iOut++] = '\0'; zFile[iOut++] = '\0'; zFile[iOut++] = '\0'; /* Check if there were any options specified that should be interpreted ** here. Options that are interpreted here include "vfs" and those that ** correspond to flags that may be passed to the sqlite3_open_v2() ** method. */ zOpt = &zFile[sqlite3Strlen30(zFile)+1]; while( zOpt[0] ){ int nOpt = sqlite3Strlen30(zOpt); char *zVal = &zOpt[nOpt+1]; int nVal = sqlite3Strlen30(zVal); if( nOpt==3 && memcmp("vfs", zOpt, 3)==0 ){ zVfs = zVal; }else if( nOpt==12 && memcmp("readonly_shm", zOpt, 12)==0 ){ if( sqlite3Atoi(zVal) ){ *pBtflags |= BTREE_READONLYSHM; }else{ *pBtflags &= ~BTREE_READONLYSHM; } }else{ struct OpenMode { const char *z; int mode; } *aMode = 0; char *zModeType; int mask; int limit; if( nOpt==5 && memcmp("cache", zOpt, 5)==0 ){ static struct OpenMode aCacheMode[] = { { "shared", SQLITE_OPEN_SHAREDCACHE }, { "private", SQLITE_OPEN_PRIVATECACHE }, { 0, 0 } }; mask = SQLITE_OPEN_SHAREDCACHE|SQLITE_OPEN_PRIVATECACHE; aMode = aCacheMode; limit = mask; zModeType = "cache"; } if( nOpt==4 && memcmp("mode", zOpt, 4)==0 ){ static struct OpenMode aOpenMode[] = { { "ro", SQLITE_OPEN_READONLY }, { "rw", SQLITE_OPEN_READWRITE }, { "rwc", SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE }, { 0, 0 } }; mask = SQLITE_OPEN_READONLY|SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE; aMode = aOpenMode; limit = mask & flags; zModeType = "access"; } if( aMode ){ int i; int mode = 0; for(i=0; aMode[i].z; i++){ const char *z = aMode[i].z; if( nVal==sqlite3Strlen30(z) && 0==memcmp(zVal, z, nVal) ){ mode = aMode[i].mode; break; } } if( mode==0 ){ *pzErrMsg = sqlite3_mprintf("no such %s mode: %s", zModeType, zVal); rc = SQLITE_ERROR; goto parse_uri_out; } if( mode>limit ){ *pzErrMsg = sqlite3_mprintf("%s mode not allowed: %s", zModeType, zVal); rc = SQLITE_PERM; goto parse_uri_out; } flags = (flags & ~mask) | mode; } } zOpt = &zVal[nVal+1]; } }else{ zFile = sqlite3_malloc(nUri+2); if( !zFile ) return SQLITE_NOMEM; memcpy(zFile, zUri, nUri); zFile[nUri] = '\0'; zFile[nUri+1] = '\0'; } *ppVfs = sqlite3_vfs_find(zVfs); if( *ppVfs==0 ){ *pzErrMsg = sqlite3_mprintf("no such vfs: %s", zVfs); rc = SQLITE_ERROR; } parse_uri_out: if( rc!=SQLITE_OK ){ sqlite3_free(zFile); zFile = 0; } *pFlags = flags; *pzFile = zFile; return rc; } /* ** This routine does the work of opening a database on behalf of ** sqlite3_open() and sqlite3_open16(). The database filename "zFilename" ** is UTF-8 encoded. */ static int openDatabase( const char *zFilename, /* Database filename UTF-8 encoded */ sqlite3 **ppDb, /* OUT: Returned database handle */ unsigned int flags, /* Operational flags */ const char *zVfs /* Name of the VFS to use */ ){ sqlite3 *db; /* Store allocated handle here */ int rc; /* Return code */ int isThreadsafe; /* True for threadsafe connections */ char *zOpen = 0; /* Filename argument to pass to BtreeOpen() */ char *zErrMsg = 0; /* Error message from sqlite3ParseUri() */ int btflags = 0; /* Mask of BTREE_XXX flags */ *ppDb = 0; #ifndef SQLITE_OMIT_AUTOINIT rc = sqlite3_initialize(); if( rc ) return rc; #endif |
︙ | ︙ | |||
1831 1832 1833 1834 1835 1836 1837 | */ assert( SQLITE_OPEN_READONLY == 0x01 ); assert( SQLITE_OPEN_READWRITE == 0x02 ); assert( SQLITE_OPEN_CREATE == 0x04 ); testcase( (1<<(flags&7))==0x02 ); /* READONLY */ testcase( (1<<(flags&7))==0x04 ); /* READWRITE */ testcase( (1<<(flags&7))==0x40 ); /* READWRITE | CREATE */ | | | 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 | */ assert( SQLITE_OPEN_READONLY == 0x01 ); assert( SQLITE_OPEN_READWRITE == 0x02 ); assert( SQLITE_OPEN_CREATE == 0x04 ); testcase( (1<<(flags&7))==0x02 ); /* READONLY */ testcase( (1<<(flags&7))==0x04 ); /* READWRITE */ testcase( (1<<(flags&7))==0x40 ); /* READWRITE | CREATE */ if( ((1<<(flags&7)) & 0x46)==0 ) return SQLITE_MISUSE_BKPT; if( sqlite3GlobalConfig.bCoreMutex==0 ){ isThreadsafe = 0; }else if( flags & SQLITE_OPEN_NOMUTEX ){ isThreadsafe = 0; }else if( flags & SQLITE_OPEN_FULLMUTEX ){ isThreadsafe = 1; |
︙ | ︙ | |||
1912 1913 1914 1915 1916 1917 1918 | #endif ; sqlite3HashInit(&db->aCollSeq); #ifndef SQLITE_OMIT_VIRTUALTABLE sqlite3HashInit(&db->aModule); #endif | < < < < < < < | 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 | #endif ; sqlite3HashInit(&db->aCollSeq); #ifndef SQLITE_OMIT_VIRTUALTABLE sqlite3HashInit(&db->aModule); #endif /* Add the default collation sequence BINARY. BINARY works for both UTF-8 ** and UTF-16, so add a version for each to avoid any unnecessary ** conversions. The only error that can occur here is a malloc() failure. */ createCollation(db, "BINARY", SQLITE_UTF8, SQLITE_COLL_BINARY, 0, binCollFunc, 0); createCollation(db, "BINARY", SQLITE_UTF16BE, SQLITE_COLL_BINARY, 0, |
︙ | ︙ | |||
1941 1942 1943 1944 1945 1946 1947 | db->pDfltColl = sqlite3FindCollSeq(db, SQLITE_UTF8, "BINARY", 0); assert( db->pDfltColl!=0 ); /* Also add a UTF-8 case-insensitive collation sequence. */ createCollation(db, "NOCASE", SQLITE_UTF8, SQLITE_COLL_NOCASE, 0, nocaseCollatingFunc, 0); | | | > > > > > > > > > > | 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 | db->pDfltColl = sqlite3FindCollSeq(db, SQLITE_UTF8, "BINARY", 0); assert( db->pDfltColl!=0 ); /* Also add a UTF-8 case-insensitive collation sequence. */ createCollation(db, "NOCASE", SQLITE_UTF8, SQLITE_COLL_NOCASE, 0, nocaseCollatingFunc, 0); /* Parse the filename/URI argument. */ db->openFlags = flags; rc = sqlite3ParseUri( zVfs, zFilename, &flags, &btflags, &db->pVfs, &zOpen, &zErrMsg); if( rc!=SQLITE_OK ){ if( rc==SQLITE_NOMEM ) db->mallocFailed = 1; sqlite3Error(db, rc, zErrMsg ? "%s" : 0, zErrMsg); sqlite3_free(zErrMsg); goto opendb_out; } /* Open the backend database driver */ rc = sqlite3BtreeOpen(db->pVfs, zOpen, db, &db->aDb[0].pBt, btflags, flags | SQLITE_OPEN_MAIN_DB); if( rc!=SQLITE_OK ){ if( rc==SQLITE_IOERR_NOMEM ){ rc = SQLITE_NOMEM; } sqlite3Error(db, rc, 0); goto opendb_out; |
︙ | ︙ | |||
2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 | /* Enable the lookaside-malloc subsystem */ setupLookaside(db, 0, sqlite3GlobalConfig.szLookaside, sqlite3GlobalConfig.nLookaside); sqlite3_wal_autocheckpoint(db, SQLITE_DEFAULT_WAL_AUTOCHECKPOINT); opendb_out: if( db ){ assert( db->mutex!=0 || isThreadsafe==0 || sqlite3GlobalConfig.bFullMutex==0 ); sqlite3_mutex_leave(db->mutex); } rc = sqlite3_errcode(db); if( rc==SQLITE_NOMEM ){ sqlite3_close(db); | > | 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 | /* Enable the lookaside-malloc subsystem */ setupLookaside(db, 0, sqlite3GlobalConfig.szLookaside, sqlite3GlobalConfig.nLookaside); sqlite3_wal_autocheckpoint(db, SQLITE_DEFAULT_WAL_AUTOCHECKPOINT); opendb_out: sqlite3_free(zOpen); if( db ){ assert( db->mutex!=0 || isThreadsafe==0 || sqlite3GlobalConfig.bFullMutex==0 ); sqlite3_mutex_leave(db->mutex); } rc = sqlite3_errcode(db); if( rc==SQLITE_NOMEM ){ sqlite3_close(db); |
︙ | ︙ | |||
2079 2080 2081 2082 2083 2084 2085 | } int sqlite3_open_v2( const char *filename, /* Database filename (UTF-8) */ sqlite3 **ppDb, /* OUT: SQLite db handle */ int flags, /* Flags */ const char *zVfs /* Name of VFS module to use */ ){ | | | 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 | } int sqlite3_open_v2( const char *filename, /* Database filename (UTF-8) */ sqlite3 **ppDb, /* OUT: SQLite db handle */ int flags, /* Flags */ const char *zVfs /* Name of VFS module to use */ ){ return openDatabase(filename, ppDb, (unsigned int)flags, zVfs); } #ifndef SQLITE_OMIT_UTF16 /* ** Open a new database handle. */ int sqlite3_open16( |
︙ | ︙ |
Changes to src/malloc.c.
︙ | ︙ | |||
529 530 531 532 533 534 535 | pNew = pOld; }else if( sqlite3GlobalConfig.bMemstat ){ sqlite3_mutex_enter(mem0.mutex); sqlite3StatusSet(SQLITE_STATUS_MALLOC_SIZE, nBytes); nDiff = nNew - nOld; if( sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED) >= mem0.alarmThreshold-nDiff ){ | | | | 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 | pNew = pOld; }else if( sqlite3GlobalConfig.bMemstat ){ sqlite3_mutex_enter(mem0.mutex); sqlite3StatusSet(SQLITE_STATUS_MALLOC_SIZE, nBytes); nDiff = nNew - nOld; if( sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED) >= mem0.alarmThreshold-nDiff ){ sqlite3MallocAlarm(nDiff); } assert( sqlite3MemdebugHasType(pOld, MEMTYPE_HEAP) ); assert( sqlite3MemdebugNoType(pOld, ~MEMTYPE_HEAP) ); pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew); if( pNew==0 && mem0.alarmCallback ){ sqlite3MallocAlarm(nBytes); pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew); } if( pNew ){ nNew = sqlite3MallocSize(pNew); sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, nNew-nOld); } sqlite3_mutex_leave(mem0.mutex); }else{ pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew); } assert( EIGHT_BYTE_ALIGNMENT(pNew) ); /* IMP: R-04675-44850 */ return pNew; |
︙ | ︙ |
Changes to src/os_unix.c.
︙ | ︙ | |||
208 209 210 211 212 213 214 215 216 217 218 219 220 221 | unsigned char eFileLock; /* The type of lock held on this fd */ unsigned char ctrlFlags; /* Behavioral bits. UNIXFILE_* flags */ int lastErrno; /* The unix errno from last I/O error */ void *lockingContext; /* Locking style specific state */ UnixUnusedFd *pUnused; /* Pre-allocated UnixUnusedFd */ const char *zPath; /* Name of the file */ unixShm *pShm; /* Shared memory segment information */ int szChunk; /* Configured by FCNTL_CHUNK_SIZE */ #if SQLITE_ENABLE_LOCKING_STYLE int openFlags; /* The flags specified at open() */ #endif #if SQLITE_ENABLE_LOCKING_STYLE || defined(__APPLE__) unsigned fsFlags; /* cached details from statfs() */ #endif | > | 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 | unsigned char eFileLock; /* The type of lock held on this fd */ unsigned char ctrlFlags; /* Behavioral bits. UNIXFILE_* flags */ int lastErrno; /* The unix errno from last I/O error */ void *lockingContext; /* Locking style specific state */ UnixUnusedFd *pUnused; /* Pre-allocated UnixUnusedFd */ const char *zPath; /* Name of the file */ unixShm *pShm; /* Shared memory segment information */ int readOnlyShm; /* True to open shared-memory read-only */ int szChunk; /* Configured by FCNTL_CHUNK_SIZE */ #if SQLITE_ENABLE_LOCKING_STYLE int openFlags; /* The flags specified at open() */ #endif #if SQLITE_ENABLE_LOCKING_STYLE || defined(__APPLE__) unsigned fsFlags; /* cached details from statfs() */ #endif |
︙ | ︙ | |||
3469 3470 3471 3472 3473 3474 3475 3476 3477 3478 3479 3480 3481 3482 | case SQLITE_FCNTL_CHUNK_SIZE: { ((unixFile*)id)->szChunk = *(int *)pArg; return SQLITE_OK; } case SQLITE_FCNTL_SIZE_HINT: { return fcntlSizeHint((unixFile *)id, *(i64 *)pArg); } #ifndef NDEBUG /* The pager calls this method to signal that it has done ** a rollback and that the database is therefore unchanged and ** it hence it is OK for the transaction change counter to be ** unchanged. */ case SQLITE_FCNTL_DB_UNCHANGED: { | > > > > | 3470 3471 3472 3473 3474 3475 3476 3477 3478 3479 3480 3481 3482 3483 3484 3485 3486 3487 | case SQLITE_FCNTL_CHUNK_SIZE: { ((unixFile*)id)->szChunk = *(int *)pArg; return SQLITE_OK; } case SQLITE_FCNTL_SIZE_HINT: { return fcntlSizeHint((unixFile *)id, *(i64 *)pArg); } case SQLITE_FCNTL_READONLY_SHM: { ((unixFile*)id)->readOnlyShm = (pArg!=0); return SQLITE_OK; } #ifndef NDEBUG /* The pager calls this method to signal that it has done ** a rollback and that the database is therefore unchanged and ** it hence it is OK for the transaction change counter to be ** unchanged. */ case SQLITE_FCNTL_DB_UNCHANGED: { |
︙ | ︙ | |||
3771 3772 3773 3774 3775 3776 3777 3778 3779 3780 3781 3782 3783 3784 | char *zFilename; /* Name of the mmapped file */ int h; /* Open file descriptor */ int szRegion; /* Size of shared-memory regions */ int nRegion; /* Size of array apRegion */ char **apRegion; /* Array of mapped shared-memory regions */ int nRef; /* Number of unixShm objects pointing to this */ unixShm *pFirst; /* All unixShm objects pointing to this */ #ifdef SQLITE_DEBUG u8 exclMask; /* Mask of exclusive locks held */ u8 sharedMask; /* Mask of shared locks held */ u8 nextShmId; /* Next available unixShm.id value */ #endif }; | > | 3776 3777 3778 3779 3780 3781 3782 3783 3784 3785 3786 3787 3788 3789 3790 | char *zFilename; /* Name of the mmapped file */ int h; /* Open file descriptor */ int szRegion; /* Size of shared-memory regions */ int nRegion; /* Size of array apRegion */ char **apRegion; /* Array of mapped shared-memory regions */ int nRef; /* Number of unixShm objects pointing to this */ unixShm *pFirst; /* All unixShm objects pointing to this */ u8 readOnly; /* True if this is a read-only mapping */ #ifdef SQLITE_DEBUG u8 exclMask; /* Mask of exclusive locks held */ u8 sharedMask; /* Mask of shared locks held */ u8 nextShmId; /* Next available unixShm.id value */ #endif }; |
︙ | ︙ | |||
4027 4028 4029 4030 4031 4032 4033 | pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST); if( pShmNode->mutex==0 ){ rc = SQLITE_NOMEM; goto shm_open_err; } if( pInode->bProcessLock==0 ){ | > | < > | < > > > > > > > | | > > | | | | | | | | | > > > > > > > > > > | 4033 4034 4035 4036 4037 4038 4039 4040 4041 4042 4043 4044 4045 4046 4047 4048 4049 4050 4051 4052 4053 4054 4055 4056 4057 4058 4059 4060 4061 4062 4063 4064 4065 4066 4067 4068 4069 4070 4071 4072 4073 4074 4075 4076 4077 4078 4079 4080 4081 4082 4083 4084 4085 4086 | pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST); if( pShmNode->mutex==0 ){ rc = SQLITE_NOMEM; goto shm_open_err; } if( pInode->bProcessLock==0 ){ int flags = (pDbFd->readOnlyShm ? O_RDONLY : O_RDWR|O_CREAT); pShmNode->h = robust_open(zShmFilename, flags, (sStat.st_mode & 0777)); if( pShmNode->h<0 ){ rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zShmFilename); goto shm_open_err; } pShmNode->readOnly = pDbFd->readOnlyShm; /* Check to see if another process is holding the dead-man switch. ** If not, zero the first few bytes of the shared-memory file to make ** sure it is not mistaken for valid by code in wal.c. Except, if this ** is a read-only connection to the shared-memory then it is not possible ** to check check if another process is holding a read-lock on the DMS ** byte, as we cannot attempt a write-lock via a read-only file ** descriptor. So in this case, we just assume the shared-memory ** contents are Ok and proceed. */ if( pShmNode->readOnly==0 ){ rc = SQLITE_OK; if( unixShmSystemLock(pShmNode, F_WRLCK, UNIX_SHM_DMS, 1)==SQLITE_OK ){ if( pDbFd->readOnlyShm ){ rc = SQLITE_IOERR_SHMOPEN; }else if( 4!=osWrite(pShmNode->h, "\00\00\00\00", 4) ){ rc = unixLogError(SQLITE_IOERR_SHMOPEN, "ftruncate", zShmFilename); } } if( rc==SQLITE_OK ){ rc = unixShmSystemLock(pShmNode, F_RDLCK, UNIX_SHM_DMS, 1); } if( rc ) goto shm_open_err; } } } /* If the unixShmNode is read-only, but SQLITE_FCNTL_READONLY_SHM has not ** been set for file-descriptor pDbFd, return an error. The wal.c module ** will then call this function again with SQLITE_FCNTL_READONLY_SHM set. */ else if( pShmNode->readOnly && !pDbFd->readOnlyShm ){ rc = SQLITE_IOERR_SHMOPEN; goto shm_open_err; } /* Make the new connection a child of the unixShmNode */ p->pShmNode = pShmNode; #ifdef SQLITE_DEBUG p->id = pShmNode->nextShmId++; #endif |
︙ | ︙ | |||
4170 4171 4172 4173 4174 4175 4176 | rc = SQLITE_IOERR_NOMEM; goto shmpage_out; } pShmNode->apRegion = apNew; while(pShmNode->nRegion<=iRegion){ void *pMem; if( pShmNode->h>=0 ){ | | | 4195 4196 4197 4198 4199 4200 4201 4202 4203 4204 4205 4206 4207 4208 4209 | rc = SQLITE_IOERR_NOMEM; goto shmpage_out; } pShmNode->apRegion = apNew; while(pShmNode->nRegion<=iRegion){ void *pMem; if( pShmNode->h>=0 ){ pMem = mmap(0, szRegion, PROT_READ|(!pShmNode->readOnly?PROT_WRITE:0), MAP_SHARED, pShmNode->h, pShmNode->nRegion*szRegion ); if( pMem==MAP_FAILED ){ rc = unixLogError(SQLITE_IOERR_SHMMAP, "mmap", pShmNode->zFilename); goto shmpage_out; } }else{ |
︙ | ︙ |
Changes to src/os_win.c.
︙ | ︙ | |||
2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 | return SQLITE_OK; #endif #if !SQLITE_OS_WINCE && !defined(__CYGWIN__) int nByte; void *zConverted; char *zOut; /* It's odd to simulate an io-error here, but really this is just ** using the io-error infrastructure to test that SQLite handles this ** function failing. This function could fail if, for example, the ** current working directory has been unlinked. */ SimulateIOError( return SQLITE_ERROR ); | > > > > > > > | 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 | return SQLITE_OK; #endif #if !SQLITE_OS_WINCE && !defined(__CYGWIN__) int nByte; void *zConverted; char *zOut; /* If this path name begins with "/X:", where "X" is any alphabetic ** character, discard the initial "/" from the pathname. */ if( zRelative[0]=='/' && sqlite3Isalpha(zRelative[1]) && zRelative[2]==':' ){ zRelative++; } /* It's odd to simulate an io-error here, but really this is just ** using the io-error infrastructure to test that SQLite handles this ** function failing. This function could fail if, for example, the ** current working directory has been unlinked. */ SimulateIOError( return SQLITE_ERROR ); |
︙ | ︙ |
Changes to src/pager.c.
︙ | ︙ | |||
616 617 618 619 620 621 622 623 624 625 626 627 628 629 | u8 noSync; /* Do not sync the journal if true */ u8 fullSync; /* Do extra syncs of the journal for robustness */ u8 ckptSyncFlags; /* SYNC_NORMAL or SYNC_FULL for checkpoint */ u8 syncFlags; /* SYNC_NORMAL or SYNC_FULL otherwise */ u8 tempFile; /* zFilename is a temporary file */ u8 readOnly; /* True for a read-only database */ u8 memDb; /* True to inhibit all file I/O */ /************************************************************************** ** The following block contains those class members that change during ** routine opertion. Class members not in this block are either fixed ** when the pager is first created or else only change when there is a ** significant mode change (such as changing the page_size, locking_mode, ** or the journal_mode). From another view, these class members describe | > | 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 | u8 noSync; /* Do not sync the journal if true */ u8 fullSync; /* Do extra syncs of the journal for robustness */ u8 ckptSyncFlags; /* SYNC_NORMAL or SYNC_FULL for checkpoint */ u8 syncFlags; /* SYNC_NORMAL or SYNC_FULL otherwise */ u8 tempFile; /* zFilename is a temporary file */ u8 readOnly; /* True for a read-only database */ u8 memDb; /* True to inhibit all file I/O */ u8 readOnlyShm; /* True if read-only shm access is Ok */ /************************************************************************** ** The following block contains those class members that change during ** routine opertion. Class members not in this block are either fixed ** when the pager is first created or else only change when there is a ** significant mode change (such as changing the page_size, locking_mode, ** or the journal_mode). From another view, these class members describe |
︙ | ︙ | |||
3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 | ** makes a snapshot of the database at the current point in time and preserves ** that snapshot for use by the reader in spite of concurrently changes by ** other writers or checkpointers. */ static int pagerBeginReadTransaction(Pager *pPager){ int rc; /* Return code */ int changed = 0; /* True if cache must be reset */ assert( pagerUseWal(pPager) ); assert( pPager->eState==PAGER_OPEN || pPager->eState==PAGER_READER ); /* sqlite3WalEndReadTransaction() was not called for the previous ** transaction in locking_mode=EXCLUSIVE. So call it now. If we ** are in locking_mode=NORMAL and EndRead() was previously called, ** the duplicate call is harmless. */ | > | | | 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 3039 3040 | ** makes a snapshot of the database at the current point in time and preserves ** that snapshot for use by the reader in spite of concurrently changes by ** other writers or checkpointers. */ static int pagerBeginReadTransaction(Pager *pPager){ int rc; /* Return code */ int changed = 0; /* True if cache must be reset */ Wal *pWal = pPager->pWal; assert( pagerUseWal(pPager) ); assert( pPager->eState==PAGER_OPEN || pPager->eState==PAGER_READER ); /* sqlite3WalEndReadTransaction() was not called for the previous ** transaction in locking_mode=EXCLUSIVE. So call it now. If we ** are in locking_mode=NORMAL and EndRead() was previously called, ** the duplicate call is harmless. */ sqlite3WalEndReadTransaction(pWal); rc = sqlite3WalBeginReadTransaction(pWal, pPager->readOnlyShm, &changed); if( rc!=SQLITE_OK || changed ){ pager_reset(pPager); } return rc; } #endif |
︙ | ︙ | |||
4295 4296 4297 4298 4299 4300 4301 4302 4303 4304 4305 4306 4307 4308 | int journalFileSize; /* Bytes to allocate for each journal fd */ char *zPathname = 0; /* Full path to database file */ int nPathname = 0; /* Number of bytes in zPathname */ int useJournal = (flags & PAGER_OMIT_JOURNAL)==0; /* False to omit journal */ int noReadlock = (flags & PAGER_NO_READLOCK)!=0; /* True to omit read-lock */ int pcacheSize = sqlite3PcacheSize(); /* Bytes to allocate for PCache */ u32 szPageDflt = SQLITE_DEFAULT_PAGE_SIZE; /* Default page size */ /* Figure out how much space is required for each journal file-handle ** (there are two of them, the main journal and the sub-journal). This ** is the maximum space required for an in-memory journal file handle ** and a regular journal file-handle. Note that a "regular journal-handle" ** may be a wrapper capable of caching the first portion of the journal ** file in memory to implement the atomic-write optimization (see | > > | 4297 4298 4299 4300 4301 4302 4303 4304 4305 4306 4307 4308 4309 4310 4311 4312 | int journalFileSize; /* Bytes to allocate for each journal fd */ char *zPathname = 0; /* Full path to database file */ int nPathname = 0; /* Number of bytes in zPathname */ int useJournal = (flags & PAGER_OMIT_JOURNAL)==0; /* False to omit journal */ int noReadlock = (flags & PAGER_NO_READLOCK)!=0; /* True to omit read-lock */ int pcacheSize = sqlite3PcacheSize(); /* Bytes to allocate for PCache */ u32 szPageDflt = SQLITE_DEFAULT_PAGE_SIZE; /* Default page size */ const char *zUri = 0; /* URI args to copy */ int nUri = 0; /* Number of bytes of URI args at *zUri */ /* Figure out how much space is required for each journal file-handle ** (there are two of them, the main journal and the sub-journal). This ** is the maximum space required for an in-memory journal file handle ** and a regular journal file-handle. Note that a "regular journal-handle" ** may be a wrapper capable of caching the first portion of the journal ** file in memory to implement the atomic-write optimization (see |
︙ | ︙ | |||
4325 4326 4327 4328 4329 4330 4331 4332 4333 4334 4335 4336 4337 4338 4339 4340 4341 4342 4343 4344 4345 4346 | #endif /* Compute and store the full pathname in an allocated buffer pointed ** to by zPathname, length nPathname. Or, if this is a temporary file, ** leave both nPathname and zPathname set to 0. */ if( zFilename && zFilename[0] ){ nPathname = pVfs->mxPathname+1; zPathname = sqlite3Malloc(nPathname*2); if( zPathname==0 ){ return SQLITE_NOMEM; } zPathname[0] = 0; /* Make sure initialized even if FullPathname() fails */ rc = sqlite3OsFullPathname(pVfs, zFilename, nPathname, zPathname); nPathname = sqlite3Strlen30(zPathname); if( rc==SQLITE_OK && nPathname+8>pVfs->mxPathname ){ /* This branch is taken when the journal path required by ** the database being opened will be more than pVfs->mxPathname ** bytes in length. This means the database cannot be opened, ** as it will not be possible to open the journal file or even ** check for a hot-journal before reading. */ | > > > > > > > | 4329 4330 4331 4332 4333 4334 4335 4336 4337 4338 4339 4340 4341 4342 4343 4344 4345 4346 4347 4348 4349 4350 4351 4352 4353 4354 4355 4356 4357 | #endif /* Compute and store the full pathname in an allocated buffer pointed ** to by zPathname, length nPathname. Or, if this is a temporary file, ** leave both nPathname and zPathname set to 0. */ if( zFilename && zFilename[0] ){ const char *z; nPathname = pVfs->mxPathname+1; zPathname = sqlite3Malloc(nPathname*2); if( zPathname==0 ){ return SQLITE_NOMEM; } zPathname[0] = 0; /* Make sure initialized even if FullPathname() fails */ rc = sqlite3OsFullPathname(pVfs, zFilename, nPathname, zPathname); nPathname = sqlite3Strlen30(zPathname); z = zUri = &zFilename[sqlite3Strlen30(zFilename)+1]; while( *z ){ z += sqlite3Strlen30(z)+1; z += sqlite3Strlen30(z)+1; } nUri = &z[1] - zUri; if( rc==SQLITE_OK && nPathname+8>pVfs->mxPathname ){ /* This branch is taken when the journal path required by ** the database being opened will be more than pVfs->mxPathname ** bytes in length. This means the database cannot be opened, ** as it will not be possible to open the journal file or even ** check for a hot-journal before reading. */ |
︙ | ︙ | |||
4365 4366 4367 4368 4369 4370 4371 | ** Journal file name (nPathname+8+1 bytes) */ pPtr = (u8 *)sqlite3MallocZero( ROUND8(sizeof(*pPager)) + /* Pager structure */ ROUND8(pcacheSize) + /* PCache object */ ROUND8(pVfs->szOsFile) + /* The main db file */ journalFileSize * 2 + /* The two journal files */ | | | 4376 4377 4378 4379 4380 4381 4382 4383 4384 4385 4386 4387 4388 4389 4390 | ** Journal file name (nPathname+8+1 bytes) */ pPtr = (u8 *)sqlite3MallocZero( ROUND8(sizeof(*pPager)) + /* Pager structure */ ROUND8(pcacheSize) + /* PCache object */ ROUND8(pVfs->szOsFile) + /* The main db file */ journalFileSize * 2 + /* The two journal files */ nPathname + 1 + nUri + /* zFilename */ nPathname + 8 + 1 /* zJournal */ #ifndef SQLITE_OMIT_WAL + nPathname + 4 + 1 /* zWal */ #endif ); assert( EIGHT_BYTE_ALIGNMENT(SQLITE_INT_TO_PTR(journalFileSize)) ); if( !pPtr ){ |
︙ | ︙ | |||
4387 4388 4389 4390 4391 4392 4393 | pPager->jfd = (sqlite3_file*)(pPtr += journalFileSize); pPager->zFilename = (char*)(pPtr += journalFileSize); assert( EIGHT_BYTE_ALIGNMENT(pPager->jfd) ); /* Fill in the Pager.zFilename and Pager.zJournal buffers, if required. */ if( zPathname ){ assert( nPathname>0 ); | | > > | 4398 4399 4400 4401 4402 4403 4404 4405 4406 4407 4408 4409 4410 4411 4412 4413 4414 4415 4416 4417 4418 4419 4420 4421 4422 4423 4424 4425 4426 | pPager->jfd = (sqlite3_file*)(pPtr += journalFileSize); pPager->zFilename = (char*)(pPtr += journalFileSize); assert( EIGHT_BYTE_ALIGNMENT(pPager->jfd) ); /* Fill in the Pager.zFilename and Pager.zJournal buffers, if required. */ if( zPathname ){ assert( nPathname>0 ); pPager->zJournal = (char*)(pPtr += nPathname + 1 + nUri); memcpy(pPager->zFilename, zPathname, nPathname); memcpy(&pPager->zFilename[nPathname+1], zUri, nUri); memcpy(pPager->zJournal, zPathname, nPathname); memcpy(&pPager->zJournal[nPathname], "-journal", 8); #ifndef SQLITE_OMIT_WAL pPager->zWal = &pPager->zJournal[nPathname+8+1]; memcpy(pPager->zWal, zPathname, nPathname); memcpy(&pPager->zWal[nPathname], "-wal", 4); #endif sqlite3_free(zPathname); } pPager->pVfs = pVfs; pPager->vfsFlags = vfsFlags; pPager->readOnlyShm = (flags & PAGER_READONLYSHM)!=0; /* Open the pager file. */ if( zFilename && zFilename[0] ){ int fout = 0; /* VFS flags returned by xOpen() */ rc = sqlite3OsOpen(pVfs, pPager->zFilename, pPager->fd, vfsFlags, &fout); assert( !memDb ); |
︙ | ︙ |
Changes to src/pager.h.
︙ | ︙ | |||
56 57 58 59 60 61 62 63 64 65 66 67 68 69 | ** Allowed values for the flags parameter to sqlite3PagerOpen(). ** ** NOTE: These values must match the corresponding BTREE_ values in btree.h. */ #define PAGER_OMIT_JOURNAL 0x0001 /* Do not use a rollback journal */ #define PAGER_NO_READLOCK 0x0002 /* Omit readlocks on readonly files */ #define PAGER_MEMORY 0x0004 /* In-memory database */ /* ** Valid values for the second argument to sqlite3PagerLockingMode(). */ #define PAGER_LOCKINGMODE_QUERY -1 #define PAGER_LOCKINGMODE_NORMAL 0 #define PAGER_LOCKINGMODE_EXCLUSIVE 1 | > | 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | ** Allowed values for the flags parameter to sqlite3PagerOpen(). ** ** NOTE: These values must match the corresponding BTREE_ values in btree.h. */ #define PAGER_OMIT_JOURNAL 0x0001 /* Do not use a rollback journal */ #define PAGER_NO_READLOCK 0x0002 /* Omit readlocks on readonly files */ #define PAGER_MEMORY 0x0004 /* In-memory database */ #define PAGER_READONLYSHM 0x0020 /* Read-only SHM access is acceptable */ /* ** Valid values for the second argument to sqlite3PagerLockingMode(). */ #define PAGER_LOCKINGMODE_QUERY -1 #define PAGER_LOCKINGMODE_NORMAL 0 #define PAGER_LOCKINGMODE_EXCLUSIVE 1 |
︙ | ︙ |
Changes to src/sqlite.h.in.
︙ | ︙ | |||
450 451 452 453 454 455 456 457 458 459 460 461 462 463 | #define SQLITE_IOERR_SHMLOCK (SQLITE_IOERR | (20<<8)) #define SQLITE_IOERR_SHMMAP (SQLITE_IOERR | (21<<8)) #define SQLITE_IOERR_SEEK (SQLITE_IOERR | (22<<8)) #define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8)) #define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8)) #define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8)) /* ** CAPI3REF: Flags For File Open Operations ** ** These bit values are intended for use in the ** 3rd parameter to the [sqlite3_open_v2()] interface and ** in the 4th parameter to the xOpen method of the ** [sqlite3_vfs] object. | > > > | 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 | #define SQLITE_IOERR_SHMLOCK (SQLITE_IOERR | (20<<8)) #define SQLITE_IOERR_SHMMAP (SQLITE_IOERR | (21<<8)) #define SQLITE_IOERR_SEEK (SQLITE_IOERR | (22<<8)) #define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8)) #define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8)) #define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8)) #define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8)) #define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8)) /* ** CAPI3REF: Flags For File Open Operations ** ** These bit values are intended for use in the ** 3rd parameter to the [sqlite3_open_v2()] interface and ** in the 4th parameter to the xOpen method of the ** [sqlite3_vfs] object. |
︙ | ︙ | |||
476 477 478 479 480 481 482 483 484 485 486 487 488 489 | #define SQLITE_OPEN_SUBJOURNAL 0x00002000 /* VFS only */ #define SQLITE_OPEN_MASTER_JOURNAL 0x00004000 /* VFS only */ #define SQLITE_OPEN_NOMUTEX 0x00008000 /* Ok for sqlite3_open_v2() */ #define SQLITE_OPEN_FULLMUTEX 0x00010000 /* Ok for sqlite3_open_v2() */ #define SQLITE_OPEN_SHAREDCACHE 0x00020000 /* Ok for sqlite3_open_v2() */ #define SQLITE_OPEN_PRIVATECACHE 0x00040000 /* Ok for sqlite3_open_v2() */ #define SQLITE_OPEN_WAL 0x00080000 /* VFS only */ /* Reserved: 0x00F00000 */ /* ** CAPI3REF: Device Characteristics ** ** The xDeviceCharacteristics method of the [sqlite3_io_methods] | > | 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 | #define SQLITE_OPEN_SUBJOURNAL 0x00002000 /* VFS only */ #define SQLITE_OPEN_MASTER_JOURNAL 0x00004000 /* VFS only */ #define SQLITE_OPEN_NOMUTEX 0x00008000 /* Ok for sqlite3_open_v2() */ #define SQLITE_OPEN_FULLMUTEX 0x00010000 /* Ok for sqlite3_open_v2() */ #define SQLITE_OPEN_SHAREDCACHE 0x00020000 /* Ok for sqlite3_open_v2() */ #define SQLITE_OPEN_PRIVATECACHE 0x00040000 /* Ok for sqlite3_open_v2() */ #define SQLITE_OPEN_WAL 0x00080000 /* VFS only */ #define SQLITE_OPEN_URI 0x00100000 /* Ok for sqlite3_open_v2() */ /* Reserved: 0x00F00000 */ /* ** CAPI3REF: Device Characteristics ** ** The xDeviceCharacteristics method of the [sqlite3_io_methods] |
︙ | ︙ | |||
728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 | ** when the database connection has [PRAGMA synchronous] set to OFF.)^ ** Some specialized VFSes need this signal in order to operate correctly ** when [PRAGMA synchronous | PRAGMA synchronous=OFF] is set, but most ** VFSes do not need this signal and should silently ignore this opcode. ** Applications should not call [sqlite3_file_control()] with this ** opcode as doing so may disrupt the operation of the specialized VFSes ** that do require it. */ #define SQLITE_FCNTL_LOCKSTATE 1 #define SQLITE_GET_LOCKPROXYFILE 2 #define SQLITE_SET_LOCKPROXYFILE 3 #define SQLITE_LAST_ERRNO 4 #define SQLITE_FCNTL_SIZE_HINT 5 #define SQLITE_FCNTL_CHUNK_SIZE 6 #define SQLITE_FCNTL_FILE_POINTER 7 #define SQLITE_FCNTL_SYNC_OMITTED 8 /* ** CAPI3REF: Mutex Handle ** ** The mutex module within SQLite defines [sqlite3_mutex] to be an ** abstract type for a mutex object. The SQLite core never looks ** at the internal representation of an [sqlite3_mutex]. It only ** deals with pointers to the [sqlite3_mutex] object. ** ** Mutexes are created using [sqlite3_mutex_alloc()]. */ typedef struct sqlite3_mutex sqlite3_mutex; /* ** CAPI3REF: OS Interface Object ** ** An instance of the sqlite3_vfs object defines the interface between ** the SQLite core and the underlying operating system. The "vfs" ** in the name of the object stands for "virtual file system". ** ** The value of the iVersion field is initially 1 but may be larger in ** future versions of SQLite. Additional fields may be appended to this | > > > > > > > > > > > > > > > > > > > > > > > | 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 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 | ** when the database connection has [PRAGMA synchronous] set to OFF.)^ ** Some specialized VFSes need this signal in order to operate correctly ** when [PRAGMA synchronous | PRAGMA synchronous=OFF] is set, but most ** VFSes do not need this signal and should silently ignore this opcode. ** Applications should not call [sqlite3_file_control()] with this ** opcode as doing so may disrupt the operation of the specialized VFSes ** that do require it. ** ** The [SQLITE_FCNTL_READONLY_SHM] may be generated internally by SQLite if ** the "readonly_shm=1" URI option is specified when the database is opened. ** The fourth argument passed to the VFS xFileControl methods is a pointer ** to a variable of type "int" containing the value 1 or 0. If the variable ** contains the value 1, then this indicates to the VFS that a read-only ** mapping of the shared-memory region is acceptable. If it is set to 0, then ** this indicates that a read-write mapping is required (as normal). If ** a read-only mapping is returned, then the VFS may also return read-only ** mappings for any subsequent requests via the same file-descriptor - ** regardless of the value most recently configured using ** SQLITE_FCNTL_READONLY_SHM. ** ** In practice, if "readonly_shm=1" is specified and the first attempt to ** map a shared-memory region fails, then this file-control is invoked with ** the argument variable set to 1 and a second attempt to map the shared-memory ** region is made. If this mapping succeeds, then the connection continues ** with the read-only mapping. Otherwise, if it fails, SQLITE_CANTOPEN is ** returned to the caller. Whether or not the second (read-only) mapping ** attempt succeeds, the file-control is invoked again with the argument ** variable set to 0. */ #define SQLITE_FCNTL_LOCKSTATE 1 #define SQLITE_GET_LOCKPROXYFILE 2 #define SQLITE_SET_LOCKPROXYFILE 3 #define SQLITE_LAST_ERRNO 4 #define SQLITE_FCNTL_SIZE_HINT 5 #define SQLITE_FCNTL_CHUNK_SIZE 6 #define SQLITE_FCNTL_FILE_POINTER 7 #define SQLITE_FCNTL_SYNC_OMITTED 8 #define SQLITE_FCNTL_READONLY_SHM 9 /* ** CAPI3REF: Mutex Handle ** ** The mutex module within SQLite defines [sqlite3_mutex] to be an ** abstract type for a mutex object. The SQLite core never looks ** at the internal representation of an [sqlite3_mutex]. It only ** deals with pointers to the [sqlite3_mutex] object. ** ** Mutexes are created using [sqlite3_mutex_alloc()]. */ typedef struct sqlite3_mutex sqlite3_mutex; /* ** CAPI3REF: OS Interface Object ** KEYWORDS: VFS VFSes ** ** An instance of the sqlite3_vfs object defines the interface between ** the SQLite core and the underlying operating system. The "vfs" ** in the name of the object stands for "virtual file system". ** ** The value of the iVersion field is initially 1 but may be larger in ** future versions of SQLite. Additional fields may be appended to this |
︙ | ︙ | |||
1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 | ** [extended result code]. ^The third parameter passed to the logger is ** log message after formatting via [sqlite3_snprintf()]. ** The SQLite logging interface is not reentrant; the logger function ** supplied by the application must not invoke any SQLite interface. ** In a multi-threaded application, the application-defined logger ** function must be threadsafe. </dd> ** ** </dl> */ #define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */ #define SQLITE_CONFIG_MULTITHREAD 2 /* nil */ #define SQLITE_CONFIG_SERIALIZED 3 /* nil */ #define SQLITE_CONFIG_MALLOC 4 /* sqlite3_mem_methods* */ #define SQLITE_CONFIG_GETMALLOC 5 /* sqlite3_mem_methods* */ #define SQLITE_CONFIG_SCRATCH 6 /* void*, int sz, int N */ #define SQLITE_CONFIG_PAGECACHE 7 /* void*, int sz, int N */ #define SQLITE_CONFIG_HEAP 8 /* void*, int nByte, int min */ #define SQLITE_CONFIG_MEMSTATUS 9 /* boolean */ #define SQLITE_CONFIG_MUTEX 10 /* sqlite3_mutex_methods* */ #define SQLITE_CONFIG_GETMUTEX 11 /* sqlite3_mutex_methods* */ /* previously SQLITE_CONFIG_CHUNKALLOC 12 which is now unused. */ #define SQLITE_CONFIG_LOOKASIDE 13 /* int int */ #define SQLITE_CONFIG_PCACHE 14 /* sqlite3_pcache_methods* */ #define SQLITE_CONFIG_GETPCACHE 15 /* sqlite3_pcache_methods* */ #define SQLITE_CONFIG_LOG 16 /* xFunc, void* */ /* ** CAPI3REF: Database Connection Configuration Options ** ** These constants are the available integer configuration options that ** can be passed as the second argument to the [sqlite3_db_config()] interface. ** | > > > > > > > > > > > > > | 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 | ** [extended result code]. ^The third parameter passed to the logger is ** log message after formatting via [sqlite3_snprintf()]. ** The SQLite logging interface is not reentrant; the logger function ** supplied by the application must not invoke any SQLite interface. ** In a multi-threaded application, the application-defined logger ** function must be threadsafe. </dd> ** ** <dt>SQLITE_CONFIG_URI ** <dd> This option takes a single argument of type int. If non-zero, then ** URI handling is globally enabled. If the parameter is zero, then URI handling ** is globally disabled. If URI handling is globally enabled, all filenames ** passed to [sqlite3_open()], [sqlite3_open_v2()], [sqlite3_open16()] or ** specified as part of [ATTACH] commands are interpreted as URIs, regardless ** of whether or not the [SQLITE_OPEN_URI] flag is set when the database ** connection is opened. If it is globally disabled, filenames are ** only interpreted as URIs if the SQLITE_OPEN_URI flag is set when the ** database connection is opened. By default, URI handling is globally ** disabled. The default value may be changed by compiling with the ** [SQLITE_USE_URI] symbol defined. ** </dl> */ #define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */ #define SQLITE_CONFIG_MULTITHREAD 2 /* nil */ #define SQLITE_CONFIG_SERIALIZED 3 /* nil */ #define SQLITE_CONFIG_MALLOC 4 /* sqlite3_mem_methods* */ #define SQLITE_CONFIG_GETMALLOC 5 /* sqlite3_mem_methods* */ #define SQLITE_CONFIG_SCRATCH 6 /* void*, int sz, int N */ #define SQLITE_CONFIG_PAGECACHE 7 /* void*, int sz, int N */ #define SQLITE_CONFIG_HEAP 8 /* void*, int nByte, int min */ #define SQLITE_CONFIG_MEMSTATUS 9 /* boolean */ #define SQLITE_CONFIG_MUTEX 10 /* sqlite3_mutex_methods* */ #define SQLITE_CONFIG_GETMUTEX 11 /* sqlite3_mutex_methods* */ /* previously SQLITE_CONFIG_CHUNKALLOC 12 which is now unused. */ #define SQLITE_CONFIG_LOOKASIDE 13 /* int int */ #define SQLITE_CONFIG_PCACHE 14 /* sqlite3_pcache_methods* */ #define SQLITE_CONFIG_GETPCACHE 15 /* sqlite3_pcache_methods* */ #define SQLITE_CONFIG_LOG 16 /* xFunc, void* */ #define SQLITE_CONFIG_URI 17 /* int */ /* ** CAPI3REF: Database Connection Configuration Options ** ** These constants are the available integer configuration options that ** can be passed as the second argument to the [sqlite3_db_config()] interface. ** |
︙ | ︙ | |||
2320 2321 2322 2323 2324 2325 2326 | ** */ void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); /* ** CAPI3REF: Opening A New Database Connection ** | | | 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 | ** */ void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); /* ** CAPI3REF: Opening A New Database Connection ** ** ^These routines open an SQLite database file as specified by the ** filename argument. ^The filename argument is interpreted as UTF-8 for ** sqlite3_open() and sqlite3_open_v2() and as UTF-16 in the native byte ** order for sqlite3_open16(). ^(A [database connection] handle is usually ** returned in *ppDb, even if an error occurs. The only exception is that ** if SQLite is unable to allocate memory to hold the [sqlite3] object, ** a NULL will be written into *ppDb instead of a pointer to the [sqlite3] ** object.)^ ^(If the database is opened (and/or created) successfully, then |
︙ | ︙ | |||
2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 | ** in the serialized [threading mode] unless single-thread was ** previously selected at compile-time or start-time. ** ^The [SQLITE_OPEN_SHAREDCACHE] flag causes the database connection to be ** eligible to use [shared cache mode], regardless of whether or not shared ** cache is enabled using [sqlite3_enable_shared_cache()]. ^The ** [SQLITE_OPEN_PRIVATECACHE] flag causes the database connection to not ** participate in [shared cache mode] even if it is enabled. ** ** ^If the filename is ":memory:", then a private, temporary in-memory database ** is created for the connection. ^This in-memory database will vanish when ** the database connection is closed. Future versions of SQLite might ** make use of additional special filenames that begin with the ":" character. ** It is recommended that when a database filename actually does begin with ** a ":" character you should prefix the filename with a pathname such as ** "./" to avoid ambiguity. ** ** ^If the filename is an empty string, then a private, temporary ** on-disk database will be created. ^This private database will be ** automatically deleted as soon as the database connection is closed. ** | > > > > > > > > | > > > > > > > > > > > > > > > > > > > > > | > > > > | > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 | ** in the serialized [threading mode] unless single-thread was ** previously selected at compile-time or start-time. ** ^The [SQLITE_OPEN_SHAREDCACHE] flag causes the database connection to be ** eligible to use [shared cache mode], regardless of whether or not shared ** cache is enabled using [sqlite3_enable_shared_cache()]. ^The ** [SQLITE_OPEN_PRIVATECACHE] flag causes the database connection to not ** participate in [shared cache mode] even if it is enabled. ** ** ^The fourth parameter to sqlite3_open_v2() is the name of the ** [sqlite3_vfs] object that defines the operating system interface that ** the new database connection should use. ^If the fourth parameter is ** a NULL pointer then the default [sqlite3_vfs] object is used. ** ** ^If the filename is ":memory:", then a private, temporary in-memory database ** is created for the connection. ^This in-memory database will vanish when ** the database connection is closed. Future versions of SQLite might ** make use of additional special filenames that begin with the ":" character. ** It is recommended that when a database filename actually does begin with ** a ":" character you should prefix the filename with a pathname such as ** "./" to avoid ambiguity. ** ** ^If the filename is an empty string, then a private, temporary ** on-disk database will be created. ^This private database will be ** automatically deleted as soon as the database connection is closed. ** ** ^If URI filename interpretation is enabled, and the filename argument ** begins with "file:", then the filename is interpreted as a URI. ^URI ** filename interpretation is enabled if the [SQLITE_OPEN_URI] flag is ** is set in the fourth argument to sqlite3_open_v2(), or if it has ** been enabled globally using the [SQLITE_CONFIG_URI] option with the ** [sqlite3_config()] method. ** ** URI filenames are parsed according to RFC 1738. If the URI contains an ** 'authority', then it must be either an empty string or the string ** "localhost". ^If the authority is not an empty string or "localhost", an ** error is returned to the caller. ^The 'fragment' component of a URI, if ** present, is always ignored. ** ** ^SQLite uses the 'path' component of the URI as the path to the database file ** to open. ^If the path begins with a '/' character, then it is interpreted as ** an absolute path. ^If it does not begin with a '/', it is interpreted as a ** relative path. ^On windows, the first component of an absolute path ** is a drive specification (e.g. "C:"). ** ** The query component of a URI may contain parameters that are interpreted ** either by SQLite itself, or by a [sqlite3_vfs | custom VFS implementation]. ** SQLite interprets the following four query parameters: ** ** <ul> ** <li> <b>vfs</b>: ^The "vfs" parameter may be used to specify the name of ** a VFS object that provides the operating system interface that should ** be used to access the database file on disk. ^If this option is set to ** an empty string the default VFS object is used. ^Specifying an unknown ** VFS is an error. ^If sqlite3_open_v2() is used and the vfs option is ** present, then the VFS specified by the option takes precedence over ** the value passed as the fourth parameter to sqlite3_open_v2(). ** ** <li> <b>mode</b>: ^(The mode parameter may be set to either "ro", "rw" or ** "rwc". Attempting to set it to any other value is an error)^. ** ^If "ro" is specified, then the database is opened for read-only ** access, just as if the [SQLITE_OPEN_READONLY] flag had been set in the ** third argument to sqlite3_prepare_v2(). ^If the mode option is set to ** "rw", then the database is opened for read-write (but not create) ** access, as if SQLITE_OPEN_READWRITE (but not SQLITE_OPEN_CREATE) had ** been set. ^Value "rwc" is equivalent to setting both ** SQLITE_OPEN_READWRITE and SQLITE_OPEN_CREATE. ^If sqlite3_open_v2() is ** used, it is an error to specify a value for the mode parameter that is ** less restrictive than that specified by the flags passed as the third ** parameter. ** ** <li> <b>cache</b>: ^The cache parameter may be set to either "shared" or ** "private". ^Setting it to "shared" is equivalent to setting the ** SQLITE_OPEN_SHAREDCACHE bit in the flags argument passed to ** sqlite3_open_v2(). ^Setting the cache parameter to "private" is ** equivalent to setting the SQLITE_OPEN_PRIVATECACHE bit. ** ^If sqlite3_open_v2() is used and the "cache" parameter is present in ** a URI filename, its value overrides any behaviour requested by setting ** SQLITE_OPEN_PRIVATECACHE or SQLITE_OPEN_SHAREDCACHE flag. ** ** <li> <b>readonly_shm</b>: ^The readonly_shm parameter may be set to ** either "1" or "0". Setting it to "1" indicates that if the database ** is in WAL mode and read-write access to the associated shared ** memory region cannot be obtained, then an attempt should be made to open ** the shared-memory in read-only mode instead. If there exist one or ** more other database clients that have read-write connections to the ** database shared-memory, then a read-only shared-memory connection works ** fine. However, if there exist no clients with read-write connections ** to the shared-memory and the most recent such crashed or was interrupted ** by a power failure, then it is possible for a database client using a ** read-only connection to return incorrect data, incorrectly report ** database corruption, or return an SQLITE_READONLY error. Or if the ** most recent read-write connection shut down cleanly, it may not be ** possible to open the shared-memory in read-only mode at all, and SQLite ** will return SQLITE_CANTOPEN. ** </ul> ** ** ^Specifying an unknown parameter in the query component of a URI is not an ** error. ** ** URI filename examples: ** ** <table border="1" align=center cellpadding=5> ** <tr><th> URI filenames <th> Results ** <tr><td> file:data.db <td> ** Open the file "data.db" in the current directory. ** <tr><td> file:/home/fred/data.db<br> ** file:///home/fred/data.db <br> ** file://localhost/home/fred/data.db <br> <td> ** Open the database file "/home/fred/data.db". ** <tr><td> file://darkstar/home/fred/data.db <td> ** An error. "darkstar" is not a recognized authority. ** <tr><td style="white-space:nowrap"> ** file:///C:/Documents%20and%20Settings/fred/Desktop/data.db ** <td> Windows only: Open the file "data.db" on fred's desktop on drive ** C:. Note that the %20 escaping in this example is not strictly ** necessary - space characters can be used literally ** in URI filenames. ** <tr><td> file:data.db?mode=ro&cache=private <td> ** Open file "data.db" in the current directory for read-only access. ** Regardless of whether or not shared-cache mode is enabled by ** default, use a private cache. ** <tr><td> file:/home/fred/data.db?vfs=unix-nolock <td> ** Open file "/home/fred/data.db". Use the special VFS "unix-nolock". ** <tr><td> file:data.db?mode=readonly <td> ** An error. "readonly" is not a valid option for the "mode" parameter. ** </table> ** ** ^URI hexadecimal escape sequences (%HH) are supported within the path and ** query components of a URI. A hexadecimal escape sequence consists of a ** percent sign - "%" - followed by exactly two hexadecimal digits ** specifying an octet value. ^Before the path or query components of a ** URI filename are interpreted, they are encoded using UTF-8 and all ** hexadecimal escape sequences replaced by a single byte containing the ** corresponding octet. If this process generates an invalid UTF-8 encoding, ** the results are undefined. ** ** <b>Note to Windows users:</b> The encoding used for the filename argument ** of sqlite3_open() and sqlite3_open_v2() must be UTF-8, not whatever ** codepage is currently defined. Filenames containing international ** characters must be converted to UTF-8 prior to passing them into ** sqlite3_open() or sqlite3_open_v2(). */ |
︙ | ︙ | |||
4607 4608 4609 4610 4611 4612 4613 | int (*xSync)(sqlite3_vtab *pVTab); int (*xCommit)(sqlite3_vtab *pVTab); int (*xRollback)(sqlite3_vtab *pVTab); int (*xFindFunction)(sqlite3_vtab *pVtab, int nArg, const char *zName, void (**pxFunc)(sqlite3_context*,int,sqlite3_value**), void **ppArg); int (*xRename)(sqlite3_vtab *pVtab, const char *zNew); | | | | 4758 4759 4760 4761 4762 4763 4764 4765 4766 4767 4768 4769 4770 4771 4772 4773 | int (*xSync)(sqlite3_vtab *pVTab); int (*xCommit)(sqlite3_vtab *pVTab); int (*xRollback)(sqlite3_vtab *pVTab); int (*xFindFunction)(sqlite3_vtab *pVtab, int nArg, const char *zName, void (**pxFunc)(sqlite3_context*,int,sqlite3_value**), void **ppArg); int (*xRename)(sqlite3_vtab *pVtab, const char *zNew); /* The methods above are in version 1 of the sqlite_module object. Those ** below are for version 2 and greater. */ int (*xSavepoint)(sqlite3_vtab *pVTab, int); int (*xRelease)(sqlite3_vtab *pVTab, int); int (*xRollbackTo)(sqlite3_vtab *pVTab, int); }; /* ** CAPI3REF: Virtual Table Indexing Information |
︙ | ︙ | |||
6421 6422 6423 6424 6425 6426 6427 | ** CAPI3REF: Virtual Table Configuration Options ** ** These macros define the various options to the ** [sqlite3_vtab_config()] interface that [virtual table] implementations ** can use to customize and optimize their behavior. ** ** <dl> | | | | < | > | | | | | | | < | | | | | | > | | | | | | | | < | 6572 6573 6574 6575 6576 6577 6578 6579 6580 6581 6582 6583 6584 6585 6586 6587 6588 6589 6590 6591 6592 6593 6594 6595 6596 6597 6598 6599 6600 6601 6602 6603 6604 6605 6606 6607 6608 6609 6610 6611 6612 6613 6614 6615 | ** CAPI3REF: Virtual Table Configuration Options ** ** These macros define the various options to the ** [sqlite3_vtab_config()] interface that [virtual table] implementations ** can use to customize and optimize their behavior. ** ** <dl> ** <dt>SQLITE_VTAB_CONSTRAINT_SUPPORT ** <dd>Calls of the form ** [sqlite3_vtab_config](db,SQLITE_VTAB_CONSTRAINT_SUPPORT,X) are supported, ** where X is an integer. If X is zero, then the [virtual table] whose ** [xCreate] or [xConnect] method invoked [sqlite3_vtab_config()] does not ** support constraints. In this configuration (which is the default) if ** a call to the [xUpdate] method returns [SQLITE_CONSTRAINT], then the entire ** statement is rolled back as if [ON CONFLICT | OR ABORT] had been ** specified as part of the users SQL statement, regardless of the actual ** ON CONFLICT mode specified. ** ** If X is non-zero, then the virtual table implementation guarantees ** that if [xUpdate] returns [SQLITE_CONSTRAINT], it will do so before ** any modifications to internal or persistent data structures have been made. ** If the [ON CONFLICT] mode is ABORT, FAIL, IGNORE or ROLLBACK, SQLite ** is able to roll back a statement or database transaction, and abandon ** or continue processing the current SQL statement as appropriate. ** If the ON CONFLICT mode is REPLACE and the [xUpdate] method returns ** [SQLITE_CONSTRAINT], SQLite handles this as if the ON CONFLICT mode ** had been ABORT. ** ** Virtual table implementations that are required to handle OR REPLACE ** must do so within the [xUpdate] method. If a call to the ** [sqlite3_vtab_on_conflict()] function indicates that the current ON ** CONFLICT policy is REPLACE, the virtual table implementation should ** silently replace the appropriate rows within the xUpdate callback and ** return SQLITE_OK. Or, if this is not possible, it may return ** SQLITE_CONSTRAINT, in which case SQLite falls back to OR ABORT ** constraint handling. ** </dl> */ #define SQLITE_VTAB_CONSTRAINT_SUPPORT 1 /* ** CAPI3REF: Determine The Virtual Table Conflict Policy ** ** This function may only be called from within a call to the [xUpdate] method |
︙ | ︙ |
Changes to src/sqliteInt.h.
︙ | ︙ | |||
799 800 801 802 803 804 805 | ** consistently. */ struct sqlite3 { sqlite3_vfs *pVfs; /* OS Interface */ int nDb; /* Number of backends currently in use */ Db *aDb; /* All backends */ int flags; /* Miscellaneous flags. See below */ | | | 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 | ** consistently. */ struct sqlite3 { sqlite3_vfs *pVfs; /* OS Interface */ int nDb; /* Number of backends currently in use */ Db *aDb; /* All backends */ int flags; /* Miscellaneous flags. See below */ unsigned int openFlags; /* Flags passed to sqlite3_vfs.xOpen() */ int errCode; /* Most recent error code (SQLITE_*) */ int errMask; /* & result codes with this before returning */ u8 autoCommit; /* The auto-commit flag. */ u8 temp_store; /* 1: file 2: memory 0: default */ u8 mallocFailed; /* True if we have seen a malloc failure */ u8 dfltLockMode; /* Default locking-mode for attached dbs */ signed char nextAutovac; /* Autovac setting after VACUUM if >=0 */ |
︙ | ︙ | |||
2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 | ** ** This structure also contains some state information. */ struct Sqlite3Config { int bMemstat; /* True to enable memory status */ int bCoreMutex; /* True to enable core mutexing */ int bFullMutex; /* True to enable full mutexing */ int mxStrlen; /* Maximum string length */ int szLookaside; /* Default lookaside buffer size */ int nLookaside; /* Default lookaside buffer count */ sqlite3_mem_methods m; /* Low-level memory allocation interface */ sqlite3_mutex_methods mutex; /* Low-level mutex interface */ sqlite3_pcache_methods pcache; /* Low-level page-cache interface */ void *pHeap; /* Heap storage space */ | > | 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 | ** ** This structure also contains some state information. */ struct Sqlite3Config { int bMemstat; /* True to enable memory status */ int bCoreMutex; /* True to enable core mutexing */ int bFullMutex; /* True to enable full mutexing */ int bOpenUri; /* True to interpret filenames as URIs */ int mxStrlen; /* Maximum string length */ int szLookaside; /* Default lookaside buffer size */ int nLookaside; /* Default lookaside buffer count */ sqlite3_mem_methods m; /* Low-level memory allocation interface */ sqlite3_mutex_methods mutex; /* Low-level mutex interface */ sqlite3_pcache_methods pcache; /* Low-level page-cache interface */ void *pHeap; /* Heap storage space */ |
︙ | ︙ | |||
2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 | void sqlite3AddNotNull(Parse*, int); void sqlite3AddPrimaryKey(Parse*, ExprList*, int, int, int); void sqlite3AddCheckConstraint(Parse*, Expr*); void sqlite3AddColumnType(Parse*,Token*); void sqlite3AddDefaultValue(Parse*,ExprSpan*); void sqlite3AddCollateType(Parse*, Token*); void sqlite3EndTable(Parse*,Token*,Token*,Select*); Bitvec *sqlite3BitvecCreate(u32); int sqlite3BitvecTest(Bitvec*, u32); int sqlite3BitvecSet(Bitvec*, u32); void sqlite3BitvecClear(Bitvec*, u32, void*); void sqlite3BitvecDestroy(Bitvec*); u32 sqlite3BitvecSize(Bitvec*); | > > | 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 | void sqlite3AddNotNull(Parse*, int); void sqlite3AddPrimaryKey(Parse*, ExprList*, int, int, int); void sqlite3AddCheckConstraint(Parse*, Expr*); void sqlite3AddColumnType(Parse*,Token*); void sqlite3AddDefaultValue(Parse*,ExprSpan*); void sqlite3AddCollateType(Parse*, Token*); void sqlite3EndTable(Parse*,Token*,Token*,Select*); int sqlite3ParseUri(const char*,const char*,unsigned int*,int*, sqlite3_vfs**,char**,char **); Bitvec *sqlite3BitvecCreate(u32); int sqlite3BitvecTest(Bitvec*, u32); int sqlite3BitvecSet(Bitvec*, u32); void sqlite3BitvecClear(Bitvec*, u32, void*); void sqlite3BitvecDestroy(Bitvec*); u32 sqlite3BitvecSize(Bitvec*); |
︙ | ︙ | |||
2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 | void sqlite3TableAffinityStr(Vdbe *, Table *); char sqlite3CompareAffinity(Expr *pExpr, char aff2); int sqlite3IndexAffinityOk(Expr *pExpr, char idx_affinity); char sqlite3ExprAffinity(Expr *pExpr); int sqlite3Atoi64(const char*, i64*, int, u8); void sqlite3Error(sqlite3*, int, const char*,...); void *sqlite3HexToBlob(sqlite3*, const char *z, int n); int sqlite3TwoPartName(Parse *, Token *, Token *, Token **); const char *sqlite3ErrStr(int); int sqlite3ReadSchema(Parse *pParse); CollSeq *sqlite3FindCollSeq(sqlite3*,u8 enc, const char*,int); CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char*zName); CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr); Expr *sqlite3ExprSetColl(Expr*, CollSeq*); | > | 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 | void sqlite3TableAffinityStr(Vdbe *, Table *); char sqlite3CompareAffinity(Expr *pExpr, char aff2); int sqlite3IndexAffinityOk(Expr *pExpr, char idx_affinity); char sqlite3ExprAffinity(Expr *pExpr); int sqlite3Atoi64(const char*, i64*, int, u8); void sqlite3Error(sqlite3*, int, const char*,...); void *sqlite3HexToBlob(sqlite3*, const char *z, int n); u8 sqlite3HexToInt(int h); int sqlite3TwoPartName(Parse *, Token *, Token *, Token **); const char *sqlite3ErrStr(int); int sqlite3ReadSchema(Parse *pParse); CollSeq *sqlite3FindCollSeq(sqlite3*,u8 enc, const char*,int); CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char*zName); CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr); Expr *sqlite3ExprSetColl(Expr*, CollSeq*); |
︙ | ︙ |
Changes to src/test1.c.
︙ | ︙ | |||
159 160 161 162 163 164 165 166 167 168 169 170 171 172 | case SQLITE_IOERR_DELETE: zName = "SQLITE_IOERR_DELETE"; break; case SQLITE_IOERR_BLOCKED: zName = "SQLITE_IOERR_BLOCKED"; break; case SQLITE_IOERR_NOMEM: zName = "SQLITE_IOERR_NOMEM"; break; case SQLITE_IOERR_ACCESS: zName = "SQLITE_IOERR_ACCESS"; break; case SQLITE_IOERR_CHECKRESERVEDLOCK: zName = "SQLITE_IOERR_CHECKRESERVEDLOCK"; break; case SQLITE_IOERR_LOCK: zName = "SQLITE_IOERR_LOCK"; break; default: zName = "SQLITE_Unknown"; break; } return zName; } #define t1ErrorName sqlite3TestErrorName /* | > > > | 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 | case SQLITE_IOERR_DELETE: zName = "SQLITE_IOERR_DELETE"; break; case SQLITE_IOERR_BLOCKED: zName = "SQLITE_IOERR_BLOCKED"; break; case SQLITE_IOERR_NOMEM: zName = "SQLITE_IOERR_NOMEM"; break; case SQLITE_IOERR_ACCESS: zName = "SQLITE_IOERR_ACCESS"; break; case SQLITE_IOERR_CHECKRESERVEDLOCK: zName = "SQLITE_IOERR_CHECKRESERVEDLOCK"; break; case SQLITE_IOERR_LOCK: zName = "SQLITE_IOERR_LOCK"; break; case SQLITE_READONLY_RECOVERY: zName = "SQLITE_READONLY_RECOVERY"; break; case SQLITE_READONLY_CANTLOCK: zName = "SQLITE_READONLY_CANTLOCK"; break; default: zName = "SQLITE_Unknown"; break; } return zName; } #define t1ErrorName sqlite3TestErrorName /* |
︙ | ︙ | |||
3858 3859 3860 3861 3862 3863 3864 3865 3866 3867 3868 3869 3870 3871 | zFilename = objc>1 ? Tcl_GetString(objv[1]) : 0; rc = sqlite3_open(zFilename, &db); if( sqlite3TestMakePointerStr(interp, zBuf, db) ) return TCL_ERROR; Tcl_AppendResult(interp, zBuf, 0); return TCL_OK; } /* ** Usage: sqlite3_open16 filename options */ static int test_open16( void * clientData, Tcl_Interp *interp, | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 3861 3862 3863 3864 3865 3866 3867 3868 3869 3870 3871 3872 3873 3874 3875 3876 3877 3878 3879 3880 3881 3882 3883 3884 3885 3886 3887 3888 3889 3890 3891 3892 3893 3894 3895 3896 3897 3898 3899 3900 3901 3902 3903 3904 3905 3906 3907 3908 3909 3910 3911 3912 3913 3914 3915 3916 3917 3918 3919 3920 3921 3922 3923 3924 3925 3926 3927 3928 3929 3930 3931 3932 3933 3934 3935 3936 3937 3938 3939 3940 3941 3942 3943 3944 | zFilename = objc>1 ? Tcl_GetString(objv[1]) : 0; rc = sqlite3_open(zFilename, &db); if( sqlite3TestMakePointerStr(interp, zBuf, db) ) return TCL_ERROR; Tcl_AppendResult(interp, zBuf, 0); return TCL_OK; } /* ** Usage: sqlite3_open_v2 FILENAME FLAGS VFS */ static int test_open_v2( void * clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ const char *zFilename; const char *zVfs; int flags = 0; sqlite3 *db; int rc; char zBuf[100]; int nFlag; Tcl_Obj **apFlag; int i; if( objc!=4 ){ Tcl_WrongNumArgs(interp, 1, objv, "FILENAME FLAGS VFS"); return TCL_ERROR; } zFilename = Tcl_GetString(objv[1]); zVfs = Tcl_GetString(objv[3]); if( zVfs[0]==0x00 ) zVfs = 0; rc = Tcl_ListObjGetElements(interp, objv[2], &nFlag, &apFlag); if( rc!=TCL_OK ) return rc; for(i=0; i<nFlag; i++){ int iFlag; struct OpenFlag { const char *zFlag; int flag; } aFlag[] = { { "SQLITE_OPEN_READONLY", SQLITE_OPEN_READONLY }, { "SQLITE_OPEN_READWRITE", SQLITE_OPEN_READWRITE }, { "SQLITE_OPEN_CREATE", SQLITE_OPEN_CREATE }, { "SQLITE_OPEN_DELETEONCLOSE", SQLITE_OPEN_DELETEONCLOSE }, { "SQLITE_OPEN_EXCLUSIVE", SQLITE_OPEN_EXCLUSIVE }, { "SQLITE_OPEN_AUTOPROXY", SQLITE_OPEN_AUTOPROXY }, { "SQLITE_OPEN_MAIN_DB", SQLITE_OPEN_MAIN_DB }, { "SQLITE_OPEN_TEMP_DB", SQLITE_OPEN_TEMP_DB }, { "SQLITE_OPEN_TRANSIENT_DB", SQLITE_OPEN_TRANSIENT_DB }, { "SQLITE_OPEN_MAIN_JOURNAL", SQLITE_OPEN_MAIN_JOURNAL }, { "SQLITE_OPEN_TEMP_JOURNAL", SQLITE_OPEN_TEMP_JOURNAL }, { "SQLITE_OPEN_SUBJOURNAL", SQLITE_OPEN_SUBJOURNAL }, { "SQLITE_OPEN_MASTER_JOURNAL", SQLITE_OPEN_MASTER_JOURNAL }, { "SQLITE_OPEN_NOMUTEX", SQLITE_OPEN_NOMUTEX }, { "SQLITE_OPEN_FULLMUTEX", SQLITE_OPEN_FULLMUTEX }, { "SQLITE_OPEN_SHAREDCACHE", SQLITE_OPEN_SHAREDCACHE }, { "SQLITE_OPEN_PRIVATECACHE", SQLITE_OPEN_PRIVATECACHE }, { "SQLITE_OPEN_WAL", SQLITE_OPEN_WAL }, { "SQLITE_OPEN_URI", SQLITE_OPEN_URI }, { 0, 0 } }; rc = Tcl_GetIndexFromObjStruct(interp, apFlag[i], aFlag, sizeof(aFlag[0]), "flag", 0, &iFlag ); if( rc!=TCL_OK ) return rc; flags |= aFlag[iFlag].flag; } rc = sqlite3_open_v2(zFilename, &db, flags, zVfs); if( sqlite3TestMakePointerStr(interp, zBuf, db) ) return TCL_ERROR; Tcl_AppendResult(interp, zBuf, 0); return TCL_OK; } /* ** Usage: sqlite3_open16 filename options */ static int test_open16( void * clientData, Tcl_Interp *interp, |
︙ | ︙ | |||
5699 5700 5701 5702 5703 5704 5705 5706 5707 5708 5709 5710 5711 5712 | { "sqlite3_sleep", test_sleep, 0}, { "sqlite3_errcode", test_errcode ,0 }, { "sqlite3_extended_errcode", test_ex_errcode ,0 }, { "sqlite3_errmsg", test_errmsg ,0 }, { "sqlite3_errmsg16", test_errmsg16 ,0 }, { "sqlite3_open", test_open ,0 }, { "sqlite3_open16", test_open16 ,0 }, { "sqlite3_complete16", test_complete16 ,0 }, { "sqlite3_prepare", test_prepare ,0 }, { "sqlite3_prepare16", test_prepare16 ,0 }, { "sqlite3_prepare_v2", test_prepare_v2 ,0 }, { "sqlite3_prepare_tkt3134", test_prepare_tkt3134, 0}, { "sqlite3_prepare16_v2", test_prepare16_v2 ,0 }, | > | 5772 5773 5774 5775 5776 5777 5778 5779 5780 5781 5782 5783 5784 5785 5786 | { "sqlite3_sleep", test_sleep, 0}, { "sqlite3_errcode", test_errcode ,0 }, { "sqlite3_extended_errcode", test_ex_errcode ,0 }, { "sqlite3_errmsg", test_errmsg ,0 }, { "sqlite3_errmsg16", test_errmsg16 ,0 }, { "sqlite3_open", test_open ,0 }, { "sqlite3_open16", test_open16 ,0 }, { "sqlite3_open_v2", test_open_v2 ,0 }, { "sqlite3_complete16", test_complete16 ,0 }, { "sqlite3_prepare", test_prepare ,0 }, { "sqlite3_prepare16", test_prepare16 ,0 }, { "sqlite3_prepare_v2", test_prepare_v2 ,0 }, { "sqlite3_prepare_tkt3134", test_prepare_tkt3134, 0}, { "sqlite3_prepare16_v2", test_prepare16_v2 ,0 }, |
︙ | ︙ |
Changes to src/test3.c.
︙ | ︙ | |||
74 75 76 77 78 79 80 | if( Tcl_GetInt(interp, argv[2], &nCache) ) return TCL_ERROR; nRefSqlite3++; if( nRefSqlite3==1 ){ sDb.pVfs = sqlite3_vfs_find(0); sDb.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_RECURSIVE); sqlite3_mutex_enter(sDb.mutex); } | | | 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 | if( Tcl_GetInt(interp, argv[2], &nCache) ) return TCL_ERROR; nRefSqlite3++; if( nRefSqlite3==1 ){ sDb.pVfs = sqlite3_vfs_find(0); sDb.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_RECURSIVE); sqlite3_mutex_enter(sDb.mutex); } rc = sqlite3BtreeOpen(sDb.pVfs, argv[1], &sDb, &pBt, 0, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_MAIN_DB); if( rc!=SQLITE_OK ){ Tcl_AppendResult(interp, errorName(rc), 0); return TCL_ERROR; } sqlite3BtreeSetCacheSize(pBt, nCache); sqlite3_snprintf(sizeof(zBuf), zBuf,"%p", pBt); |
︙ | ︙ |
Changes to src/test_malloc.c.
︙ | ︙ | |||
1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 | "sqlite3_config(99999) does not return SQLITE_ERROR", (char*)0); return TCL_ERROR; } } return TCL_OK; } /* ** Usage: ** ** sqlite3_dump_memsys3 FILENAME ** sqlite3_dump_memsys5 FILENAME ** | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 | "sqlite3_config(99999) does not return SQLITE_ERROR", (char*)0); return TCL_ERROR; } } return TCL_OK; } /* ** tclcmd: sqlite3_config_uri BOOLEAN ** ** Invoke sqlite3_config() or sqlite3_db_config() with invalid ** opcodes and verify that they return errors. */ static int test_config_uri( void * clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ int rc; int bOpenUri; if( objc!=2 ){ Tcl_WrongNumArgs(interp, 1, objv, "BOOL"); return TCL_ERROR; } if( Tcl_GetBooleanFromObj(interp, objv[1], &bOpenUri) ){ return TCL_ERROR; } rc = sqlite3_config(SQLITE_CONFIG_URI, bOpenUri); Tcl_SetResult(interp, (char *)sqlite3TestErrorName(rc), TCL_VOLATILE); return TCL_OK; } /* ** Usage: ** ** sqlite3_dump_memsys3 FILENAME ** sqlite3_dump_memsys5 FILENAME ** |
︙ | ︙ | |||
1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 | { "sqlite3_status", test_status ,0 }, { "sqlite3_db_status", test_db_status ,0 }, { "install_malloc_faultsim", test_install_malloc_faultsim ,0 }, { "sqlite3_config_heap", test_config_heap ,0 }, { "sqlite3_config_memstatus", test_config_memstatus ,0 }, { "sqlite3_config_lookaside", test_config_lookaside ,0 }, { "sqlite3_config_error", test_config_error ,0 }, { "sqlite3_db_config_lookaside",test_db_config_lookaside ,0 }, { "sqlite3_dump_memsys3", test_dump_memsys3 ,3 }, { "sqlite3_dump_memsys5", test_dump_memsys3 ,5 }, { "sqlite3_install_memsys3", test_install_memsys3 ,0 }, { "sqlite3_memdebug_vfs_oom_test", test_vfs_oom_test ,0 }, }; int i; | > | 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 | { "sqlite3_status", test_status ,0 }, { "sqlite3_db_status", test_db_status ,0 }, { "install_malloc_faultsim", test_install_malloc_faultsim ,0 }, { "sqlite3_config_heap", test_config_heap ,0 }, { "sqlite3_config_memstatus", test_config_memstatus ,0 }, { "sqlite3_config_lookaside", test_config_lookaside ,0 }, { "sqlite3_config_error", test_config_error ,0 }, { "sqlite3_config_uri", test_config_uri ,0 }, { "sqlite3_db_config_lookaside",test_db_config_lookaside ,0 }, { "sqlite3_dump_memsys3", test_dump_memsys3 ,3 }, { "sqlite3_dump_memsys5", test_dump_memsys3 ,5 }, { "sqlite3_install_memsys3", test_install_memsys3 ,0 }, { "sqlite3_memdebug_vfs_oom_test", test_vfs_oom_test ,0 }, }; int i; |
︙ | ︙ |
Changes to src/test_vfs.c.
︙ | ︙ | |||
110 111 112 113 114 115 116 | ** The Testvfs.mask variable is set to a combination of the following. ** If a bit is clear in Testvfs.mask, then calls made by SQLite to the ** corresponding VFS method is ignored for purposes of: ** ** + Simulating IO errors, and ** + Invoking the Tcl callback script. */ | | | | | | | | | | | | | > | | 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 | ** The Testvfs.mask variable is set to a combination of the following. ** If a bit is clear in Testvfs.mask, then calls made by SQLite to the ** corresponding VFS method is ignored for purposes of: ** ** + Simulating IO errors, and ** + Invoking the Tcl callback script. */ #define TESTVFS_SHMOPEN_MASK 0x00000001 #define TESTVFS_SHMLOCK_MASK 0x00000010 #define TESTVFS_SHMMAP_MASK 0x00000020 #define TESTVFS_SHMBARRIER_MASK 0x00000040 #define TESTVFS_SHMCLOSE_MASK 0x00000080 #define TESTVFS_OPEN_MASK 0x00000100 #define TESTVFS_SYNC_MASK 0x00000200 #define TESTVFS_DELETE_MASK 0x00000400 #define TESTVFS_CLOSE_MASK 0x00000800 #define TESTVFS_WRITE_MASK 0x00001000 #define TESTVFS_TRUNCATE_MASK 0x00002000 #define TESTVFS_ACCESS_MASK 0x00004000 #define TESTVFS_FULLPATHNAME_MASK 0x00008000 #define TESTVFS_ALL_MASK 0x0001FFFF #define TESTVFS_MAX_PAGES 1024 /* ** A shared-memory buffer. There is one of these objects for each shared ** memory region opened by clients. If two clients open the same file, |
︙ | ︙ | |||
541 542 543 544 545 546 547 | pFd->pVfs = pVfs; pFd->pReal = (sqlite3_file *)&pFd[1]; memset(pTestfile, 0, sizeof(TestvfsFile)); pTestfile->pFd = pFd; /* Evaluate the Tcl script: ** | | > > > > > > > > > > > | > | 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 | pFd->pVfs = pVfs; pFd->pReal = (sqlite3_file *)&pFd[1]; memset(pTestfile, 0, sizeof(TestvfsFile)); pTestfile->pFd = pFd; /* Evaluate the Tcl script: ** ** SCRIPT xOpen FILENAME KEY-VALUE-ARGS ** ** If the script returns an SQLite error code other than SQLITE_OK, an ** error is returned to the caller. If it returns SQLITE_OK, the new ** connection is named "anon". Otherwise, the value returned by the ** script is used as the connection name. */ Tcl_ResetResult(p->interp); if( p->pScript && p->mask&TESTVFS_OPEN_MASK ){ Tcl_Obj *pArg = Tcl_NewObj(); Tcl_IncrRefCount(pArg); if( flags&SQLITE_OPEN_MAIN_DB ){ const char *z = &zName[strlen(zName)+1]; while( *z ){ Tcl_ListObjAppendElement(0, pArg, Tcl_NewStringObj(z, -1)); z += strlen(z) + 1; Tcl_ListObjAppendElement(0, pArg, Tcl_NewStringObj(z, -1)); z += strlen(z) + 1; } } tvfsExecTcl(p, "xOpen", Tcl_NewStringObj(pFd->zFilename, -1), pArg, 0); Tcl_DecrRefCount(pArg); if( tvfsResultCode(p, &rc) ){ if( rc!=SQLITE_OK ) return rc; }else{ pId = Tcl_GetObjResult(p->interp); } } |
︙ | ︙ | |||
659 660 661 662 663 664 665 666 667 668 669 670 671 672 | */ static int tvfsFullPathname( sqlite3_vfs *pVfs, const char *zPath, int nOut, char *zOut ){ return sqlite3OsFullPathname(PARENTVFS(pVfs), zPath, nOut, zOut); } #ifndef SQLITE_OMIT_LOAD_EXTENSION /* ** Open the dynamic library located at zPath and return a handle. */ | > > > > > > > > | 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 | */ static int tvfsFullPathname( sqlite3_vfs *pVfs, const char *zPath, int nOut, char *zOut ){ Testvfs *p = (Testvfs *)pVfs->pAppData; if( p->pScript && p->mask&TESTVFS_FULLPATHNAME_MASK ){ int rc; tvfsExecTcl(p, "xFullPathname", Tcl_NewStringObj(zPath, -1), 0, 0); if( tvfsResultCode(p, &rc) ){ if( rc!=SQLITE_OK ) return rc; } } return sqlite3OsFullPathname(PARENTVFS(pVfs), zPath, nOut, zOut); } #ifndef SQLITE_OMIT_LOAD_EXTENSION /* ** Open the dynamic library located at zPath and return a handle. */ |
︙ | ︙ | |||
1024 1025 1026 1027 1028 1029 1030 | } case CMD_FILTER: { static struct VfsMethod { char *zName; int mask; } vfsmethod [] = { | | | | | | | | | | | | | > | 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 | } case CMD_FILTER: { static struct VfsMethod { char *zName; int mask; } vfsmethod [] = { { "xShmOpen", TESTVFS_SHMOPEN_MASK }, { "xShmLock", TESTVFS_SHMLOCK_MASK }, { "xShmBarrier", TESTVFS_SHMBARRIER_MASK }, { "xShmUnmap", TESTVFS_SHMCLOSE_MASK }, { "xShmMap", TESTVFS_SHMMAP_MASK }, { "xSync", TESTVFS_SYNC_MASK }, { "xDelete", TESTVFS_DELETE_MASK }, { "xWrite", TESTVFS_WRITE_MASK }, { "xTruncate", TESTVFS_TRUNCATE_MASK }, { "xOpen", TESTVFS_OPEN_MASK }, { "xClose", TESTVFS_CLOSE_MASK }, { "xAccess", TESTVFS_ACCESS_MASK }, { "xFullPathname", TESTVFS_FULLPATHNAME_MASK }, }; Tcl_Obj **apElem = 0; int nElem = 0; int i; int mask = 0; if( objc!=3 ){ Tcl_WrongNumArgs(interp, 2, objv, "LIST"); |
︙ | ︙ |
Changes to src/util.c.
︙ | ︙ | |||
979 980 981 982 983 984 985 | p[1] = (u8)(v>>16); p[2] = (u8)(v>>8); p[3] = (u8)v; } | < | < | | 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 | p[1] = (u8)(v>>16); p[2] = (u8)(v>>8); p[3] = (u8)v; } /* ** Translate a single byte of Hex into an integer. ** This routine only works if h really is a valid hexadecimal ** character: 0..9a..fA..F */ u8 sqlite3HexToInt(int h){ assert( (h>='0' && h<='9') || (h>='a' && h<='f') || (h>='A' && h<='F') ); #ifdef SQLITE_ASCII h += 9*(1&(h>>6)); #endif #ifdef SQLITE_EBCDIC h += 9*(1&~(h>>4)); #endif return (u8)(h & 0xf); } #if !defined(SQLITE_OMIT_BLOB_LITERAL) || defined(SQLITE_HAS_CODEC) /* ** Convert a BLOB literal of the form "x'hhhhhh'" into its binary ** value. Return a pointer to its binary value. Space to hold the ** binary value has been obtained from malloc and must be freed by ** the calling routine. */ void *sqlite3HexToBlob(sqlite3 *db, const char *z, int n){ char *zBlob; int i; zBlob = (char *)sqlite3DbMallocRaw(db, n/2 + 1); n--; if( zBlob ){ for(i=0; i<n; i+=2){ zBlob[i/2] = (sqlite3HexToInt(z[i])<<4) | sqlite3HexToInt(z[i+1]); } zBlob[i/2] = 0; } return zBlob; } #endif /* !SQLITE_OMIT_BLOB_LITERAL || SQLITE_HAS_CODEC */ |
︙ | ︙ |
Changes to src/vdbe.c.
︙ | ︙ | |||
3145 3146 3147 3148 3149 3150 3151 | SQLITE_OPEN_DELETEONCLOSE | SQLITE_OPEN_TRANSIENT_DB; assert( pOp->p1>=0 ); pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, 1); if( pCx==0 ) goto no_mem; pCx->nullRow = 1; | | | 3145 3146 3147 3148 3149 3150 3151 3152 3153 3154 3155 3156 3157 3158 3159 | SQLITE_OPEN_DELETEONCLOSE | SQLITE_OPEN_TRANSIENT_DB; assert( pOp->p1>=0 ); pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, 1); if( pCx==0 ) goto no_mem; pCx->nullRow = 1; rc = sqlite3BtreeOpen(db->pVfs, 0, db, &pCx->pBt, BTREE_OMIT_JOURNAL | BTREE_SINGLE | pOp->p5, vfsFlags); if( rc==SQLITE_OK ){ rc = sqlite3BtreeBeginTrans(pCx->pBt, 1); } if( rc==SQLITE_OK ){ /* If a transient index is required, create it by calling ** sqlite3BtreeCreateTable() with the BTREE_BLOBKEY flag before |
︙ | ︙ |
Changes to src/vtab.c.
︙ | ︙ | |||
870 871 872 873 874 875 876 | int rc = SQLITE_OK; assert( op==SAVEPOINT_RELEASE||op==SAVEPOINT_ROLLBACK||op==SAVEPOINT_BEGIN ); if( db->aVTrans ){ int i; for(i=0; rc==SQLITE_OK && i<db->nVTrans; i++){ const sqlite3_module *pMod = db->aVTrans[i]->pMod->pModule; | | | 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 | int rc = SQLITE_OK; assert( op==SAVEPOINT_RELEASE||op==SAVEPOINT_ROLLBACK||op==SAVEPOINT_BEGIN ); if( db->aVTrans ){ int i; for(i=0; rc==SQLITE_OK && i<db->nVTrans; i++){ const sqlite3_module *pMod = db->aVTrans[i]->pMod->pModule; if( pMod->iVersion>=2 ){ int (*xMethod)(sqlite3_vtab *, int); switch( op ){ case SAVEPOINT_BEGIN: xMethod = pMod->xSavepoint; break; case SAVEPOINT_ROLLBACK: xMethod = pMod->xRollbackTo; |
︙ | ︙ | |||
997 998 999 1000 1001 1002 1003 | ** table update operation currently in progress. ** ** The results of this routine are undefined unless it is called from ** within an xUpdate method. */ int sqlite3_vtab_on_conflict(sqlite3 *db){ static const unsigned char aMap[] = { | | | 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 | ** table update operation currently in progress. ** ** The results of this routine are undefined unless it is called from ** within an xUpdate method. */ int sqlite3_vtab_on_conflict(sqlite3 *db){ static const unsigned char aMap[] = { SQLITE_ROLLBACK, SQLITE_ABORT, SQLITE_FAIL, SQLITE_IGNORE, SQLITE_REPLACE }; assert( OE_Rollback==1 && OE_Abort==2 && OE_Fail==3 ); assert( OE_Ignore==4 && OE_Replace==5 ); assert( db->vtabOnConflict>=1 && db->vtabOnConflict<=5 ); return (int)aMap[db->vtabOnConflict-1]; } |
︙ | ︙ | |||
1023 1024 1025 1026 1027 1028 1029 | va_start(ap, op); switch( op ){ case SQLITE_VTAB_CONSTRAINT_SUPPORT: { VtabCtx *p = db->pVtabCtx; if( !p ){ rc = SQLITE_MISUSE_BKPT; }else{ | | | 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 | va_start(ap, op); switch( op ){ case SQLITE_VTAB_CONSTRAINT_SUPPORT: { VtabCtx *p = db->pVtabCtx; if( !p ){ rc = SQLITE_MISUSE_BKPT; }else{ assert( p->pTab==0 || (p->pTab->tabFlags & TF_Virtual)!=0 ); p->pVTable->bConstraint = (u8)va_arg(ap, int); } break; } default: rc = SQLITE_MISUSE_BKPT; break; |
︙ | ︙ |
Changes to src/wal.c.
︙ | ︙ | |||
402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 | #define walFrameOffset(iFrame, szPage) ( \ WAL_HDRSIZE + ((iFrame)-1)*(i64)((szPage)+WAL_FRAME_HDRSIZE) \ ) /* ** An open write-ahead log file is represented by an instance of the ** following object. */ struct Wal { sqlite3_vfs *pVfs; /* The VFS used to create pDbFd */ sqlite3_file *pDbFd; /* File handle for the database file */ sqlite3_file *pWalFd; /* File handle for WAL file */ u32 iCallback; /* Value to pass to log callback (or 0) */ int nWiData; /* Size of array apWiData */ volatile u32 **apWiData; /* Pointer to wal-index content in memory */ u32 szPage; /* Database page size */ i16 readLock; /* Which read lock is being held. -1 for none */ u8 exclusiveMode; /* Non-zero if connection is in exclusive mode */ u8 writeLock; /* True if in a write transaction */ u8 ckptLock; /* True if holding a checkpoint lock */ u8 readOnly; /* True if the WAL file is open read-only */ WalIndexHdr hdr; /* Wal-index header for current transaction */ const char *zWalName; /* Name of WAL file */ u32 nCkpt; /* Checkpoint sequence counter in the wal-header */ #ifdef SQLITE_DEBUG u8 lockError; /* True if a locking error has occurred */ #endif }; | > > > > > > > > > | 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 | #define walFrameOffset(iFrame, szPage) ( \ WAL_HDRSIZE + ((iFrame)-1)*(i64)((szPage)+WAL_FRAME_HDRSIZE) \ ) /* ** An open write-ahead log file is represented by an instance of the ** following object. ** ** The readOnlyShm variable is normally set to 0. If it is set to 1, then ** the connection to shared-memory is read-only. This means it cannot ** be written at all (even when read-locking the database). If it is set ** to 2, then the shared-memory region is not yet open, but a read-only ** connection is acceptable. In this case when the shared-memory is opened ** (see function walIndexPage()), readOnlyShm is set to either 0 or 1 as ** appropriate. */ struct Wal { sqlite3_vfs *pVfs; /* The VFS used to create pDbFd */ sqlite3_file *pDbFd; /* File handle for the database file */ sqlite3_file *pWalFd; /* File handle for WAL file */ u32 iCallback; /* Value to pass to log callback (or 0) */ int nWiData; /* Size of array apWiData */ volatile u32 **apWiData; /* Pointer to wal-index content in memory */ u32 szPage; /* Database page size */ i16 readLock; /* Which read lock is being held. -1 for none */ u8 exclusiveMode; /* Non-zero if connection is in exclusive mode */ u8 writeLock; /* True if in a write transaction */ u8 ckptLock; /* True if holding a checkpoint lock */ u8 readOnly; /* True if the WAL file is open read-only */ u8 readOnlyShm; /* True if the SHM file is open read-only */ WalIndexHdr hdr; /* Wal-index header for current transaction */ const char *zWalName; /* Name of WAL file */ u32 nCkpt; /* Checkpoint sequence counter in the wal-header */ #ifdef SQLITE_DEBUG u8 lockError; /* True if a locking error has occurred */ #endif }; |
︙ | ︙ | |||
524 525 526 527 528 529 530 | if( pWal->exclusiveMode==WAL_HEAPMEMORY_MODE ){ pWal->apWiData[iPage] = (u32 volatile *)sqlite3MallocZero(WALINDEX_PGSZ); if( !pWal->apWiData[iPage] ) rc = SQLITE_NOMEM; }else{ rc = sqlite3OsShmMap(pWal->pDbFd, iPage, WALINDEX_PGSZ, pWal->writeLock, (void volatile **)&pWal->apWiData[iPage] ); | > > > > > > > > | > | | > > > | 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 | if( pWal->exclusiveMode==WAL_HEAPMEMORY_MODE ){ pWal->apWiData[iPage] = (u32 volatile *)sqlite3MallocZero(WALINDEX_PGSZ); if( !pWal->apWiData[iPage] ) rc = SQLITE_NOMEM; }else{ rc = sqlite3OsShmMap(pWal->pDbFd, iPage, WALINDEX_PGSZ, pWal->writeLock, (void volatile **)&pWal->apWiData[iPage] ); if( rc==SQLITE_CANTOPEN && pWal->readOnlyShm>1 ){ assert( iPage==0 ); sqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_READONLY_SHM, (void*)1); rc = sqlite3OsShmMap(pWal->pDbFd, iPage, WALINDEX_PGSZ, pWal->writeLock, (void volatile **)&pWal->apWiData[iPage] ); if( rc==SQLITE_OK ){ pWal->readOnly = pWal->readOnlyShm = 1; } sqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_READONLY_SHM, (void*)0); } } } *ppPage = pWal->apWiData[iPage]; assert( iPage==0 || *ppPage || rc!=SQLITE_OK ); if( pWal->readOnlyShm>1 ) pWal->readOnlyShm = 0; return rc; } /* ** Return a pointer to the WalCkptInfo structure in the wal-index. */ static volatile WalCkptInfo *walCkptInfo(Wal *pWal){ |
︙ | ︙ | |||
768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 | if( pWal->exclusiveMode ) return; (void)sqlite3OsShmLock(pWal->pDbFd, lockIdx, 1, SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED); WALTRACE(("WAL%p: release SHARED-%s\n", pWal, walLockName(lockIdx))); } static int walLockExclusive(Wal *pWal, int lockIdx, int n){ int rc; if( pWal->exclusiveMode ) return SQLITE_OK; rc = sqlite3OsShmLock(pWal->pDbFd, lockIdx, n, SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE); WALTRACE(("WAL%p: acquire EXCLUSIVE-%s cnt=%d %s\n", pWal, walLockName(lockIdx), n, rc ? "failed" : "ok")); VVA_ONLY( pWal->lockError = (u8)(rc!=SQLITE_OK && rc!=SQLITE_BUSY); ) return rc; } static void walUnlockExclusive(Wal *pWal, int lockIdx, int n){ if( pWal->exclusiveMode ) return; (void)sqlite3OsShmLock(pWal->pDbFd, lockIdx, n, SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE); WALTRACE(("WAL%p: release EXCLUSIVE-%s cnt=%d\n", pWal, walLockName(lockIdx), n)); } | > > | 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 | if( pWal->exclusiveMode ) return; (void)sqlite3OsShmLock(pWal->pDbFd, lockIdx, 1, SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED); WALTRACE(("WAL%p: release SHARED-%s\n", pWal, walLockName(lockIdx))); } static int walLockExclusive(Wal *pWal, int lockIdx, int n){ int rc; assert( pWal->readOnlyShm==0 ); if( pWal->exclusiveMode ) return SQLITE_OK; rc = sqlite3OsShmLock(pWal->pDbFd, lockIdx, n, SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE); WALTRACE(("WAL%p: acquire EXCLUSIVE-%s cnt=%d %s\n", pWal, walLockName(lockIdx), n, rc ? "failed" : "ok")); VVA_ONLY( pWal->lockError = (u8)(rc!=SQLITE_OK && rc!=SQLITE_BUSY); ) return rc; } static void walUnlockExclusive(Wal *pWal, int lockIdx, int n){ assert( pWal->readOnlyShm==0 ); if( pWal->exclusiveMode ) return; (void)sqlite3OsShmLock(pWal->pDbFd, lockIdx, n, SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE); WALTRACE(("WAL%p: release EXCLUSIVE-%s cnt=%d\n", pWal, walLockName(lockIdx), n)); } |
︙ | ︙ | |||
1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 | ** If successful, the same bytes that are locked here are unlocked before ** this function returns. */ assert( pWal->ckptLock==1 || pWal->ckptLock==0 ); assert( WAL_ALL_BUT_WRITE==WAL_WRITE_LOCK+1 ); assert( WAL_CKPT_LOCK==WAL_ALL_BUT_WRITE ); assert( pWal->writeLock ); iLock = WAL_ALL_BUT_WRITE + pWal->ckptLock; nLock = SQLITE_SHM_NLOCK - iLock; rc = walLockExclusive(pWal, iLock, nLock); if( rc ){ return rc; } WALTRACE(("WAL%p: recovery begin...\n", pWal)); | > | 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 | ** If successful, the same bytes that are locked here are unlocked before ** this function returns. */ assert( pWal->ckptLock==1 || pWal->ckptLock==0 ); assert( WAL_ALL_BUT_WRITE==WAL_WRITE_LOCK+1 ); assert( WAL_CKPT_LOCK==WAL_ALL_BUT_WRITE ); assert( pWal->writeLock ); assert( pWal->readOnlyShm==0 ); iLock = WAL_ALL_BUT_WRITE + pWal->ckptLock; nLock = SQLITE_SHM_NLOCK - iLock; rc = walLockExclusive(pWal, iLock, nLock); if( rc ){ return rc; } WALTRACE(("WAL%p: recovery begin...\n", pWal)); |
︙ | ︙ | |||
1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 | */ assert( pChanged ); rc = walIndexPage(pWal, 0, &page0); if( rc!=SQLITE_OK ){ return rc; }; assert( page0 || pWal->writeLock==0 ); /* If the first page of the wal-index has been mapped, try to read the ** wal-index header immediately, without holding any lock. This usually ** works, but may fail if the wal-index header is corrupt or currently ** being modified by another thread or process. */ badHdr = (page0 ? walIndexTryHdr(pWal, pChanged) : 1); /* If the first attempt failed, it might have been due to a race | > | > > > > > > | | | | | | | | | | | | | | | > | 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 | */ assert( pChanged ); rc = walIndexPage(pWal, 0, &page0); if( rc!=SQLITE_OK ){ return rc; }; assert( page0 || pWal->writeLock==0 ); assert( pWal->readOnlyShm==0 || pWal->readOnlyShm==1 ); /* If the first page of the wal-index has been mapped, try to read the ** wal-index header immediately, without holding any lock. This usually ** works, but may fail if the wal-index header is corrupt or currently ** being modified by another thread or process. */ badHdr = (page0 ? walIndexTryHdr(pWal, pChanged) : 1); /* If the first attempt failed, it might have been due to a race ** with a writer. So lock the WAL_WRITE_LOCK byte and try again. */ assert( badHdr==0 || pWal->writeLock==0 ); if( badHdr ){ if( pWal->readOnlyShm ){ if( SQLITE_OK==(rc = walLockShared(pWal, WAL_WRITE_LOCK)) ){ walUnlockShared(pWal, WAL_WRITE_LOCK); rc = SQLITE_READONLY_RECOVERY; } }else if( SQLITE_OK==(rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1)) ){ pWal->writeLock = 1; if( SQLITE_OK==(rc = walIndexPage(pWal, 0, &page0)) ){ badHdr = walIndexTryHdr(pWal, pChanged); if( badHdr ){ /* If the wal-index header is still malformed even while holding ** a WRITE lock, it can only mean that the header is corrupted and ** needs to be reconstructed. So run recovery to do exactly that. */ rc = walIndexRecover(pWal); *pChanged = 1; } } pWal->writeLock = 0; walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1); } } /* If the header is read successfully, check the version number to make ** sure the wal-index was not constructed with some future format that ** this version of SQLite cannot understand. */ if( badHdr==0 && pWal->hdr.iVersion!=WALINDEX_MAX_VERSION ){ |
︙ | ︙ | |||
2104 2105 2106 2107 2108 2109 2110 | assert( thisMark!=READMARK_NOT_USED ); mxReadMark = thisMark; mxI = i; } } /* There was once an "if" here. The extra "{" is to preserve indentation. */ { | | > | | 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 2164 2165 2166 | assert( thisMark!=READMARK_NOT_USED ); mxReadMark = thisMark; mxI = i; } } /* There was once an "if" here. The extra "{" is to preserve indentation. */ { if( pWal->readOnlyShm==0 && (mxReadMark < pWal->hdr.mxFrame || mxI==0) ){ for(i=1; i<WAL_NREADER; i++){ rc = walLockExclusive(pWal, WAL_READ_LOCK(i), 1); if( rc==SQLITE_OK ){ mxReadMark = pInfo->aReadMark[i] = pWal->hdr.mxFrame; mxI = i; walUnlockExclusive(pWal, WAL_READ_LOCK(i), 1); break; }else if( rc!=SQLITE_BUSY ){ return rc; } } } if( mxI==0 ){ assert( rc==SQLITE_BUSY ); assert( rc==SQLITE_BUSY || (pWal->readOnlyShm && rc==SQLITE_OK) ); return rc==SQLITE_BUSY ? WAL_RETRY : SQLITE_READONLY_CANTLOCK; } rc = walLockShared(pWal, WAL_READ_LOCK(mxI)); if( rc ){ return rc==SQLITE_BUSY ? WAL_RETRY : rc; } /* Now that the read-lock has been obtained, check that neither the |
︙ | ︙ | |||
2174 2175 2176 2177 2178 2179 2180 | ** that extra content is ignored by the current thread. ** ** If the database contents have changes since the previous read ** transaction, then *pChanged is set to 1 before returning. The ** Pager layer will use this to know that is cache is stale and ** needs to be flushed. */ | | > > > > > | 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 | ** that extra content is ignored by the current thread. ** ** If the database contents have changes since the previous read ** transaction, then *pChanged is set to 1 before returning. The ** Pager layer will use this to know that is cache is stale and ** needs to be flushed. */ int sqlite3WalBeginReadTransaction(Wal *pWal, int readOnlyShm, int *pChanged){ int rc; /* Return code */ int cnt = 0; /* Number of TryBeginRead attempts */ if( pWal->nWiData==0 || pWal->apWiData[0]==0 ){ assert( readOnlyShm==0 || readOnlyShm==1 ); pWal->readOnlyShm = readOnlyShm*2; } do{ rc = walTryBeginRead(pWal, pChanged, 0, ++cnt); }while( rc==WAL_RETRY ); assert( rc || pWal->readOnlyShm==0 || (readOnlyShm && pWal->readOnlyShm==1) ); testcase( (rc&0xff)==SQLITE_BUSY ); testcase( (rc&0xff)==SQLITE_IOERR ); testcase( rc==SQLITE_PROTOCOL ); testcase( rc==SQLITE_OK ); return rc; } |
︙ | ︙ | |||
2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 | /* Cannot start a write transaction without first holding a read ** transaction. */ assert( pWal->readLock>=0 ); if( pWal->readOnly ){ return SQLITE_READONLY; } /* Only one writer allowed at a time. Get the write lock. Return ** SQLITE_BUSY if unable. */ rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1); if( rc ){ return rc; | > | 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 | /* Cannot start a write transaction without first holding a read ** transaction. */ assert( pWal->readLock>=0 ); if( pWal->readOnly ){ return SQLITE_READONLY; } assert( pWal->readOnlyShm==0 ); /* Only one writer allowed at a time. Get the write lock. Return ** SQLITE_BUSY if unable. */ rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1); if( rc ){ return rc; |
︙ | ︙ | |||
2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 | int isChanged = 0; /* True if a new wal-index header is loaded */ int eMode2 = eMode; /* Mode to pass to walCheckpoint() */ assert( pWal->ckptLock==0 ); assert( pWal->writeLock==0 ); WALTRACE(("WAL%p: checkpoint begins\n", pWal)); rc = walLockExclusive(pWal, WAL_CKPT_LOCK, 1); if( rc ){ /* Usually this is SQLITE_BUSY meaning that another thread or process ** is already running a checkpoint, or maybe a recovery. But it might ** also be SQLITE_IOERR. */ return rc; } | > > > > | 2783 2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 | int isChanged = 0; /* True if a new wal-index header is loaded */ int eMode2 = eMode; /* Mode to pass to walCheckpoint() */ assert( pWal->ckptLock==0 ); assert( pWal->writeLock==0 ); WALTRACE(("WAL%p: checkpoint begins\n", pWal)); if( pWal->readOnlyShm ){ return SQLITE_READONLY; } rc = walLockExclusive(pWal, WAL_CKPT_LOCK, 1); if( rc ){ /* Usually this is SQLITE_BUSY meaning that another thread or process ** is already running a checkpoint, or maybe a recovery. But it might ** also be SQLITE_IOERR. */ return rc; } |
︙ | ︙ |
Changes to src/wal.h.
︙ | ︙ | |||
18 19 20 21 22 23 24 | #define _WAL_H_ #include "sqliteInt.h" #ifdef SQLITE_OMIT_WAL # define sqlite3WalOpen(x,y,z) 0 # define sqlite3WalClose(w,x,y,z) 0 | | | 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | #define _WAL_H_ #include "sqliteInt.h" #ifdef SQLITE_OMIT_WAL # define sqlite3WalOpen(x,y,z) 0 # define sqlite3WalClose(w,x,y,z) 0 # define sqlite3WalBeginReadTransaction(x,y,z) 0 # define sqlite3WalEndReadTransaction(z) # define sqlite3WalRead(v,w,x,y,z) 0 # define sqlite3WalDbsize(y) 0 # define sqlite3WalBeginWriteTransaction(y) 0 # define sqlite3WalEndWriteTransaction(x) 0 # define sqlite3WalUndo(x,y,z) 0 # define sqlite3WalSavepoint(y,z) |
︙ | ︙ | |||
52 53 54 55 56 57 58 | /* Used by readers to open (lock) and close (unlock) a snapshot. A ** snapshot is like a read-transaction. It is the state of the database ** at an instant in time. sqlite3WalOpenSnapshot gets a read lock and ** preserves the current state even if the other threads or processes ** write to or checkpoint the WAL. sqlite3WalCloseSnapshot() closes the ** transaction and releases the lock. */ | | | 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | /* Used by readers to open (lock) and close (unlock) a snapshot. A ** snapshot is like a read-transaction. It is the state of the database ** at an instant in time. sqlite3WalOpenSnapshot gets a read lock and ** preserves the current state even if the other threads or processes ** write to or checkpoint the WAL. sqlite3WalCloseSnapshot() closes the ** transaction and releases the lock. */ int sqlite3WalBeginReadTransaction(Wal *pWal, int, int *); void sqlite3WalEndReadTransaction(Wal *pWal); /* Read a page from the write-ahead log, if it is present. */ int sqlite3WalRead(Wal *pWal, Pgno pgno, int *pInWal, int nOut, u8 *pOut); /* If the WAL is not empty, return the size of the database. */ Pgno sqlite3WalDbsize(Wal *pWal); |
︙ | ︙ |
Changes to test/alter.test.
︙ | ︙ | |||
646 647 648 649 650 651 652 | SELECT $::col_name, $::col_name2 FROM $::tbl_name; " } {4 5} # Ticket #1665: Make sure ALTER TABLE ADD COLUMN works on a table # that includes a COLLATE clause. # | | | 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 | SELECT $::col_name, $::col_name2 FROM $::tbl_name; " } {4 5} # Ticket #1665: Make sure ALTER TABLE ADD COLUMN works on a table # that includes a COLLATE clause. # do_realnum_test alter-7.1 { execsql { CREATE TABLE t1(a TEXT COLLATE BINARY); ALTER TABLE t1 ADD COLUMN b INTEGER COLLATE NOCASE; INSERT INTO t1 VALUES(1,'-2'); INSERT INTO t1 VALUES(5.4e-08,'5.4e-08'); SELECT typeof(a), a, typeof(b), b FROM t1; } |
︙ | ︙ |
Changes to test/cast.test.
︙ | ︙ | |||
230 231 232 233 234 235 236 | # do_test cast-3.1 { execsql {SELECT CAST(9223372036854774800 AS integer)} } 9223372036854774800 do_test cast-3.2 { execsql {SELECT CAST(9223372036854774800 AS numeric)} } 9223372036854774800 | | | | | | | 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 | # do_test cast-3.1 { execsql {SELECT CAST(9223372036854774800 AS integer)} } 9223372036854774800 do_test cast-3.2 { execsql {SELECT CAST(9223372036854774800 AS numeric)} } 9223372036854774800 do_realnum_test cast-3.3 { execsql {SELECT CAST(9223372036854774800 AS real)} } 9.22337203685477e+18 do_test cast-3.4 { execsql {SELECT CAST(CAST(9223372036854774800 AS real) AS integer)} } 9223372036854774784 do_test cast-3.5 { execsql {SELECT CAST(-9223372036854774800 AS integer)} } -9223372036854774800 do_test cast-3.6 { execsql {SELECT CAST(-9223372036854774800 AS numeric)} } -9223372036854774800 do_realnum_test cast-3.7 { execsql {SELECT CAST(-9223372036854774800 AS real)} } -9.22337203685477e+18 do_test cast-3.8 { execsql {SELECT CAST(CAST(-9223372036854774800 AS real) AS integer)} } -9223372036854774784 do_test cast-3.11 { execsql {SELECT CAST('9223372036854774800' AS integer)} } 9223372036854774800 do_test cast-3.12 { execsql {SELECT CAST('9223372036854774800' AS numeric)} } 9223372036854774800 do_realnum_test cast-3.13 { execsql {SELECT CAST('9223372036854774800' AS real)} } 9.22337203685477e+18 ifcapable long_double { do_test cast-3.14 { execsql {SELECT CAST(CAST('9223372036854774800' AS real) AS integer)} } 9223372036854774784 } do_test cast-3.15 { execsql {SELECT CAST('-9223372036854774800' AS integer)} } -9223372036854774800 do_test cast-3.16 { execsql {SELECT CAST('-9223372036854774800' AS numeric)} } -9223372036854774800 do_realnum_test cast-3.17 { execsql {SELECT CAST('-9223372036854774800' AS real)} } -9.22337203685477e+18 ifcapable long_double { do_test cast-3.18 { execsql {SELECT CAST(CAST('-9223372036854774800' AS real) AS integer)} } -9223372036854774784 } if {[db eval {PRAGMA encoding}]=="UTF-8"} { do_test cast-3.21 { execsql {SELECT CAST(x'39323233333732303336383534373734383030' AS integer)} } 9223372036854774800 do_test cast-3.22 { execsql {SELECT CAST(x'39323233333732303336383534373734383030' AS numeric)} } 9223372036854774800 do_realnum_test cast-3.23 { execsql {SELECT CAST(x'39323233333732303336383534373734383030' AS real)} } 9.22337203685477e+18 ifcapable long_double { do_test cast-3.24 { execsql { SELECT CAST(CAST(x'39323233333732303336383534373734383030' AS real) AS integer) |
︙ | ︙ |
Added test/e_uri.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 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 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 361 362 363 364 365 366 367 368 369 370 371 372 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 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 | # 2011 May 06 # # 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. # #*********************************************************************** # set testdir [file dirname $argv0] source $testdir/tester.tcl set testprefix e_uri db close proc parse_uri {uri} { testvfs tvfs2 testvfs tvfs tvfs filter xOpen tvfs script parse_uri_open_cb set ::uri_open [list] set DB [sqlite3_open_v2 $uri { SQLITE_OPEN_READWRITE SQLITE_OPEN_CREATE SQLITE_OPEN_WAL } tvfs] sqlite3_close $DB tvfs delete tvfs2 delete set ::uri_open } proc parse_uri_open_cb {method file arglist} { set ::uri_open [list $file $arglist] } proc open_uri_error {uri} { set flags {SQLITE_OPEN_READWRITE SQLITE_OPEN_CREATE SQLITE_OPEN_WAL} set DB [sqlite3_open_v2 $uri $flags ""] set e [sqlite3_errmsg $DB] sqlite3_close $DB set e } # EVIDENCE-OF: R-35840-33204 If URI filename interpretation is enabled, # and the filename argument begins with "file:", then the filename is # interpreted as a URI. # # EVIDENCE-OF: R-00067-59538 URI filename interpretation is enabled if # the SQLITE_OPEN_URI flag is is set in the fourth argument to # sqlite3_open_v2(), or if it has been enabled globally using the # SQLITE_CONFIG_URI option with the sqlite3_config() method. # if {$tcl_platform(platform) == "unix"} { set flags [list SQLITE_OPEN_READWRITE SQLITE_OPEN_CREATE] # Tests with SQLITE_CONFIG_URI configured to false. URI intepretation is # only enabled if the SQLITE_OPEN_URI flag is specified. sqlite3_shutdown sqlite3_config_uri 0 do_test 1.1 { forcedelete file:test.db test.db set DB [sqlite3_open_v2 file:test.db [concat $flags SQLITE_OPEN_URI] ""] list [file exists file:test.db] [file exists test.db] } {0 1} do_test 1.2 { forcedelete file:test.db2 test.db2 set STMT [sqlite3_prepare $DB "ATTACH 'file:test.db2' AS aux" -1 dummy] sqlite3_step $STMT sqlite3_finalize $STMT list [file exists file:test.db2] [file exists test.db2] } {0 1} sqlite3_close $DB do_test 1.3 { forcedelete file:test.db test.db set DB [sqlite3_open_v2 file:test.db [concat $flags] ""] list [file exists file:test.db] [file exists test.db] } {1 0} do_test 1.4 { forcedelete file:test.db2 test.db2 set STMT [sqlite3_prepare $DB "ATTACH 'file:test.db2' AS aux" -1 dummy] sqlite3_step $STMT sqlite3_finalize $STMT list [file exists file:test.db2] [file exists test.db2] } {1 0} sqlite3_close $DB # Tests with SQLITE_CONFIG_URI configured to true. URI intepretation is # enabled with or without SQLITE_OPEN_URI. # sqlite3_shutdown sqlite3_config_uri 1 do_test 1.5 { forcedelete file:test.db test.db set DB [sqlite3_open_v2 file:test.db [concat $flags SQLITE_OPEN_URI] ""] list [file exists file:test.db] [file exists test.db] } {0 1} do_test 1.6 { forcedelete file:test.db2 test.db2 set STMT [sqlite3_prepare $DB "ATTACH 'file:test.db2' AS aux" -1 dummy] sqlite3_step $STMT sqlite3_finalize $STMT list [file exists file:test.db2] [file exists test.db2] } {0 1} sqlite3_close $DB do_test 1.7 { forcedelete file:test.db test.db set DB [sqlite3_open_v2 file:test.db [concat $flags] ""] list [file exists file:test.db] [file exists test.db] } {0 1} do_test 1.8 { forcedelete file:test.db2 test.db2 set STMT [sqlite3_prepare $DB "ATTACH 'file:test.db2' AS aux" -1 dummy] sqlite3_step $STMT sqlite3_finalize $STMT list [file exists file:test.db2] [file exists test.db2] } {0 1} sqlite3_close $DB } # EVIDENCE-OF: R-17482-00398 If the authority is not an empty string or # "localhost", an error is returned to the caller. # if {$tcl_platform(platform) == "unix"} { set flags [list SQLITE_OPEN_READWRITE SQLITE_OPEN_CREATE SQLITE_OPEN_URI] foreach {tn uri error} " 1 {file://localhost[pwd]/test.db} {not an error} 2 {file://[pwd]/test.db} {not an error} 3 {file://x[pwd]/test.db} {invalid uri authority: x} 4 {file://invalid[pwd]/test.db} {invalid uri authority: invalid} " { do_test 2.$tn { set DB [sqlite3_open_v2 $uri $flags ""] set e [sqlite3_errmsg $DB] sqlite3_close $DB set e } $error } } # EVIDENCE-OF: R-43804-65312 The 'fragment' component of a URI, if # present, is always ignored. # # It is difficult to test that something is ignore correctly. So these tests # just show that adding a fragment does not interfere with the pathname or # parameters passed through to the VFS xOpen() methods. # if {$tcl_platform(platform) == "unix"} { foreach {tn uri parse} " 1 {file:test.db#abc} {[pwd]/test.db {}} 2 {file:test.db?a=b#abc} {[pwd]/test.db {a b}} 3 {file:test.db?a=b#?c=d} {[pwd]/test.db {a b}} " { do_test 3.$tn { parse_uri $uri } $parse } } # EVIDENCE-OF: R-00273-20588 SQLite uses the 'path' component of the URI # as the path to the database file to open. # # EVIDENCE-OF: R-28659-11035 If the path begins with a '/' character, # then it is interpreted as an absolute path. # # EVIDENCE-OF: R-39349-47203 If it does not begin with a '/', it is # interpreted as a relative path. # if {$tcl_platform(platform) == "unix"} { foreach {tn uri parse} " 1 {file:test.db} {[pwd]/test.db {}} 2 {file:/test.db} {/test.db {}} 3 {file:///test.db} {/test.db {}} 4 {file://localhost/test.db} {/test.db {}} 5 {file:/a/b/c/test.db} {/a/b/c/test.db {}} " { do_test 4.$tn { parse_uri $uri } $parse } } # EVIDENCE-OF: R-01612-30877 The "vfs" parameter may be used to specify # the name of a VFS object that provides the operating system interface # that should be used to access the database file on disk. # # The above is tested by cases 1.* below. # # EVIDENCE-OF: R-52293-58497 If this option is set to an empty string # the default VFS object is used. # # The above is tested by cases 2.* below. # # EVIDENCE-OF: R-31855-18665 If sqlite3_open_v2() is used and the vfs # option is present, then the VFS specified by the option takes # precedence over the value passed as the fourth parameter to # sqlite3_open_v2(). # # The above is tested by cases 3.* below. # proc vfs_open_cb {name args} { set ::vfs $name } foreach {name default} {vfs1 0 vfs2 0 vfs3 1} { testvfs $name -default $default $name filter xOpen $name script [list vfs_open_cb $name] } foreach {tn uri defvfs vfs} { 1.1 "file:test.db?vfs=vfs1" "" vfs1 1.2 "file:test.db?vfs=vfs2" "" vfs2 2.1 "file:test.db" vfs1 vfs1 2.2 "file:test.db?vfs=" vfs1 vfs3 3.1 "file:test.db?vfs=vfs1" vfs2 vfs1 3.2 "file:test.db?vfs=vfs2" vfs1 vfs2 3.3 "file:test.db?xvfs=vfs1" vfs2 vfs2 3.4 "file:test.db?xvfs=vfs2" vfs1 vfs1 } { do_test 5.$tn { set flags [list SQLITE_OPEN_READWRITE SQLITE_OPEN_CREATE SQLITE_OPEN_URI] sqlite3_close [ sqlite3_open_v2 $uri $flags $defvfs ] set ::vfs } $vfs } vfs1 delete vfs2 delete vfs3 delete # EVIDENCE-OF: R-48365-36308 Specifying an unknown VFS is an error. # set flags [list SQLITE_OPEN_READWRITE SQLITE_OPEN_CREATE SQLITE_OPEN_URI] do_test 6.1 { set DB [sqlite3_open_v2 file:test.db?vfs=nosuchvfs $flags ""] set errmsg [sqlite3_errmsg $DB] sqlite3_close $DB set errmsg } {no such vfs: nosuchvfs} # EVIDENCE-OF: R-60479-64270 The mode parameter may be set to either # "ro", "rw" or "rwc". Attempting to set it to any other value is an # error # sqlite3 db test.db db close foreach {tn uri error} " 1 {file:test.db?mode=ro} {not an error} 2 {file:test.db?mode=rw} {not an error} 3 {file:test.db?mode=rwc} {not an error} 4 {file:test.db?mode=Ro} {no such access mode: Ro} 5 {file:test.db?mode=Rw} {no such access mode: Rw} 6 {file:test.db?mode=Rwc} {no such access mode: Rwc} " { do_test 7.$tn { open_uri_error $uri } $error } # EVIDENCE-OF: R-09651-31805 If "ro" is specified, then the database is # opened for read-only access, just as if the SQLITE_OPEN_READONLY flag # had been set in the third argument to sqlite3_prepare_v2(). # # EVIDENCE-OF: R-40137-26050 If the mode option is set to "rw", then the # database is opened for read-write (but not create) access, as if # SQLITE_OPEN_READWRITE (but not SQLITE_OPEN_CREATE) had been set. # # EVIDENCE-OF: R-26845-32976 Value "rwc" is equivalent to setting both # SQLITE_OPEN_READWRITE and SQLITE_OPEN_CREATE. # sqlite3_shutdown sqlite3_config_uri 1 foreach {tn uri read write create} { 1 {file:test.db?mode=ro} 1 0 0 2 {file:test.db?mode=rw} 1 1 0 3 {file:test.db?mode=rwc} 1 1 1 } { set RES(c,0) {1 {unable to open database file}} set RES(c,1) {0 {}} set RES(w,0) {1 {attempt to write a readonly database}} set RES(w,1) {0 {}} set RES(r,0) {1 {this never happens}} set RES(r,1) {0 {a b}} # Test CREATE access: forcedelete test.db do_test 8.$tn.c { list [catch { sqlite3 db $uri } msg] $msg } $RES(c,$create) catch { db close } sqlite3 db test.db db eval { CREATE TABLE t1(a, b) ; INSERT INTO t1 VALUES('a', 'b') ;} db close # Test READ access: do_test 8.$tn.r { sqlite3 db $uri catchsql { SELECT * FROM t1 } } $RES(r,$read) # Test WRITE access: do_test 8.$tn.w { sqlite3 db $uri catchsql { INSERT INTO t1 VALUES(1, 2) } } $RES(w,$write) catch {db close} } # EVIDENCE-OF: R-56032-32287 If sqlite3_open_v2() is used, it is an # error to specify a value for the mode parameter that is less # restrictive than that specified by the flags passed as the third # parameter. # forcedelete test.db sqlite3 db test.db db close foreach {tn uri flags error} { 1 {file:test.db?mode=ro} ro {not an error} 2 {file:test.db?mode=ro} rw {not an error} 3 {file:test.db?mode=ro} rwc {not an error} 4 {file:test.db?mode=rw} ro {access mode not allowed: rw} 5 {file:test.db?mode=rw} rw {not an error} 6 {file:test.db?mode=rw} rwc {not an error} 7 {file:test.db?mode=rwc} ro {access mode not allowed: rwc} 8 {file:test.db?mode=rwc} rw {access mode not allowed: rwc} 9 {file:test.db?mode=rwc} rwc {not an error} } { set f(ro) [list SQLITE_OPEN_READONLY SQLITE_OPEN_URI] set f(rw) [list SQLITE_OPEN_READWRITE SQLITE_OPEN_URI] set f(rwc) [list SQLITE_OPEN_READWRITE SQLITE_OPEN_CREATE SQLITE_OPEN_URI] set DB [sqlite3_open_v2 $uri $f($flags) ""] set e [sqlite3_errmsg $DB] sqlite3_close $DB do_test 9.$tn { set e } $error } # EVIDENCE-OF: R-23182-54295 The cache parameter may be set to either # "shared" or "private". sqlite3 db test.db db close foreach {tn uri error} " 1 {file:test.db?cache=private} {not an error} 2 {file:test.db?cache=shared} {not an error} 3 {file:test.db?cache=yes} {no such cache mode: yes} 4 {file:test.db?cache=} {no such cache mode: } " { do_test 10.$tn { open_uri_error $uri } $error } # EVIDENCE-OF: R-23027-03515 Setting it to "shared" is equivalent to # setting the SQLITE_OPEN_SHAREDCACHE bit in the flags argument passed # to sqlite3_open_v2(). # # EVIDENCE-OF: R-49793-28525 Setting the cache parameter to "private" is # equivalent to setting the SQLITE_OPEN_PRIVATECACHE bit. # # EVIDENCE-OF: R-19510-48080 If sqlite3_open_v2() is used and the # "cache" parameter is present in a URI filename, its value overrides # any behaviour requested by setting SQLITE_OPEN_PRIVATECACHE or # SQLITE_OPEN_SHAREDCACHE flag. # set orig [sqlite3_enable_shared_cache] foreach {tn uri flags shared_default isshared} { 1.1 "file:test.db" "" 0 0 1.2 "file:test.db" "" 1 1 1.3 "file:test.db" private 0 0 1.4 "file:test.db" private 1 0 1.5 "file:test.db" shared 0 1 1.6 "file:test.db" shared 1 1 2.1 "file:test.db?cache=private" "" 0 0 2.2 "file:test.db?cache=private" "" 1 0 2.3 "file:test.db?cache=private" private 0 0 2.4 "file:test.db?cache=private" private 1 0 2.5 "file:test.db?cache=private" shared 0 0 2.6 "file:test.db?cache=private" shared 1 0 3.1 "file:test.db?cache=shared" "" 0 1 3.2 "file:test.db?cache=shared" "" 1 1 3.3 "file:test.db?cache=shared" private 0 1 3.4 "file:test.db?cache=shared" private 1 1 3.5 "file:test.db?cache=shared" shared 0 1 3.6 "file:test.db?cache=shared" shared 1 1 } { forcedelete test.db sqlite3_enable_shared_cache 1 sqlite3 db test.db sqlite3_enable_shared_cache 0 db eval { CREATE TABLE t1(x); INSERT INTO t1 VALUES('ok'); } unset -nocomplain f set f() {SQLITE_OPEN_READWRITE SQLITE_OPEN_CREATE SQLITE_OPEN_URI} set f(shared) [concat $f() SQLITE_OPEN_SHAREDCACHE] set f(private) [concat $f() SQLITE_OPEN_PRIVATECACHE] sqlite3_enable_shared_cache $shared_default set DB [sqlite3_open_v2 $uri $f($flags) ""] set STMT [sqlite3_prepare $DB "SELECT * FROM t1" -1 dummy] db eval { BEGIN; INSERT INTO t1 VALUES('ko'); } sqlite3_step $STMT sqlite3_finalize $STMT set RES(0) {not an error} set RES(1) {database table is locked: t1} do_test 11.$tn { sqlite3_errmsg $DB } $RES($isshared) sqlite3_close $DB db close } sqlite3_enable_shared_cache $orig # EVIDENCE-OF: R-63472-46769 Specifying an unknown parameter in the # query component of a URI is not an error. # do_test 12.1 { parse_uri file://localhost/test.db?an=unknown¶meter=is&ok= } {/test.db {an unknown parameter is ok {}}} do_test 12.2 { parse_uri file://localhost/test.db?an&unknown¶meter&is&ok } {/test.db {an {} unknown {} parameter {} is {} ok {}}} # EVIDENCE-OF: R-27458-04043 URI hexadecimal escape sequences (%HH) are # supported within the path and query components of a URI. # # EVIDENCE-OF: R-52765-50368 Before the path or query components of a # URI filename are interpreted, they are encoded using UTF-8 and all # hexadecimal escape sequences replaced by a single byte containing the # corresponding octet. # # The second of the two statements above is tested by creating a # multi-byte utf-8 character using a sequence of %HH escapes. # foreach {tn uri parse} " 1 {file:/test.%64%62} {/test.db {}} 2 {file:/test.db?%68%65%6c%6c%6f=%77%6f%72%6c%64} {/test.db {hello world}} 3 {file:/%C3%BF.db} {/\xFF.db {}} " { do_test 13.$tn { parse_uri $uri } $parse } finish_test |
Changes to test/expr.test.
︙ | ︙ | |||
28 29 30 31 32 33 34 35 36 37 38 39 40 41 | } proc test_expr {name settings expr result} { do_test $name [format { execsql {BEGIN; UPDATE test1 SET %s; SELECT %s FROM test1; ROLLBACK;} } $settings $expr] $result } test_expr expr-1.1 {i1=10, i2=20} {i1+i2} 30 test_expr expr-1.2 {i1=10, i2=20} {i1-i2} -10 test_expr expr-1.3 {i1=10, i2=20} {i1*i2} 200 test_expr expr-1.4 {i1=10, i2=20} {i1/i2} 0 test_expr expr-1.5 {i1=10, i2=20} {i2/i1} 2 test_expr expr-1.6 {i1=10, i2=20} {i2<i1} 0 | > > > > > | 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | } proc test_expr {name settings expr result} { do_test $name [format { execsql {BEGIN; UPDATE test1 SET %s; SELECT %s FROM test1; ROLLBACK;} } $settings $expr] $result } proc test_realnum_expr {name settings expr result} { do_realnum_test $name [format { execsql {BEGIN; UPDATE test1 SET %s; SELECT %s FROM test1; ROLLBACK;} } $settings $expr] $result } test_expr expr-1.1 {i1=10, i2=20} {i1+i2} 30 test_expr expr-1.2 {i1=10, i2=20} {i1-i2} -10 test_expr expr-1.3 {i1=10, i2=20} {i1*i2} 200 test_expr expr-1.4 {i1=10, i2=20} {i1/i2} 0 test_expr expr-1.5 {i1=10, i2=20} {i2/i1} 2 test_expr expr-1.6 {i1=10, i2=20} {i2<i1} 0 |
︙ | ︙ | |||
160 161 162 163 164 165 166 | ifcapable floatingpoint { test_expr expr-1.103 {i1=0} {(-2147483648.0 % -1)} 0.0 test_expr expr-1.104 {i1=0} {(-9223372036854775808.0 % -1)} 0.0 test_expr expr-1.105 {i1=0} {(-9223372036854775808.0 / -1)>1} 1 } if {[working_64bit_int]} { | | | 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 | ifcapable floatingpoint { test_expr expr-1.103 {i1=0} {(-2147483648.0 % -1)} 0.0 test_expr expr-1.104 {i1=0} {(-9223372036854775808.0 % -1)} 0.0 test_expr expr-1.105 {i1=0} {(-9223372036854775808.0 / -1)>1} 1 } if {[working_64bit_int]} { test_realnum_expr expr-1.106 {i1=0} {-9223372036854775808/-1} 9.22337203685478e+18 } test_expr expr-1.107 {i1=0} {-9223372036854775808%-1} 0 test_expr expr-1.108 {i1=0} {1%0} {{}} test_expr expr-1.109 {i1=0} {1/0} {{}} if {[working_64bit_int]} { |
︙ | ︙ | |||
199 200 201 202 203 204 205 | {CASE WHEN i1 IS NOT i2 THEN 'yes' ELSE 'no' END} yes test_expr expr-1.126 {i1=8, i2=8} \ {CASE WHEN i1 IS NOT i2 THEN 'yes' ELSE 'no' END} no ifcapable floatingpoint {if {[working_64bit_int]} { test_expr expr-1.200\ {i1=9223372036854775806, i2=1} {i1+i2} 9223372036854775807 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 | {CASE WHEN i1 IS NOT i2 THEN 'yes' ELSE 'no' END} yes test_expr expr-1.126 {i1=8, i2=8} \ {CASE WHEN i1 IS NOT i2 THEN 'yes' ELSE 'no' END} no ifcapable floatingpoint {if {[working_64bit_int]} { test_expr expr-1.200\ {i1=9223372036854775806, i2=1} {i1+i2} 9223372036854775807 test_realnum_expr expr-1.201\ {i1=9223372036854775806, i2=2} {i1+i2} 9.22337203685478e+18 test_realnum_expr expr-1.202\ {i1=9223372036854775806, i2=100000} {i1+i2} 9.22337203685488e+18 test_realnum_expr expr-1.203\ {i1=9223372036854775807, i2=0} {i1+i2} 9223372036854775807 test_realnum_expr expr-1.204\ {i1=9223372036854775807, i2=1} {i1+i2} 9.22337203685478e+18 test_realnum_expr expr-1.205\ {i2=9223372036854775806, i1=1} {i1+i2} 9223372036854775807 test_realnum_expr expr-1.206\ {i2=9223372036854775806, i1=2} {i1+i2} 9.22337203685478e+18 test_realnum_expr expr-1.207\ {i2=9223372036854775806, i1=100000} {i1+i2} 9.22337203685488e+18 test_realnum_expr expr-1.208\ {i2=9223372036854775807, i1=0} {i1+i2} 9223372036854775807 test_realnum_expr expr-1.209\ {i2=9223372036854775807, i1=1} {i1+i2} 9.22337203685478e+18 test_realnum_expr expr-1.210\ {i1=-9223372036854775807, i2=-1} {i1+i2} -9223372036854775808 test_realnum_expr expr-1.211\ {i1=-9223372036854775807, i2=-2} {i1+i2} -9.22337203685478e+18 test_realnum_expr expr-1.212\ {i1=-9223372036854775807, i2=-100000} {i1+i2} -9.22337203685488e+18 test_realnum_expr expr-1.213\ {i1=-9223372036854775808, i2=0} {i1+i2} -9223372036854775808 test_realnum_expr expr-1.214\ {i1=-9223372036854775808, i2=-1} {i1+i2} -9.22337203685478e+18 test_realnum_expr expr-1.215\ {i2=-9223372036854775807, i1=-1} {i1+i2} -9223372036854775808 test_realnum_expr expr-1.216\ {i2=-9223372036854775807, i1=-2} {i1+i2} -9.22337203685478e+18 test_realnum_expr expr-1.217\ {i2=-9223372036854775807, i1=-100000} {i1+i2} -9.22337203685488e+18 test_realnum_expr expr-1.218\ {i2=-9223372036854775808, i1=0} {i1+i2} -9223372036854775808 test_realnum_expr expr-1.219\ {i2=-9223372036854775808, i1=-1} {i1+i2} -9.22337203685478e+18 test_realnum_expr expr-1.220\ {i1=9223372036854775806, i2=-1} {i1-i2} 9223372036854775807 test_realnum_expr expr-1.221\ {i1=9223372036854775806, i2=-2} {i1-i2} 9.22337203685478e+18 test_realnum_expr expr-1.222\ {i1=9223372036854775806, i2=-100000} {i1-i2} 9.22337203685488e+18 test_realnum_expr expr-1.223\ {i1=9223372036854775807, i2=0} {i1-i2} 9223372036854775807 test_realnum_expr expr-1.224\ {i1=9223372036854775807, i2=-1} {i1-i2} 9.22337203685478e+18 test_realnum_expr expr-1.225\ {i2=-9223372036854775806, i1=1} {i1-i2} 9223372036854775807 test_realnum_expr expr-1.226\ {i2=-9223372036854775806, i1=2} {i1-i2} 9.22337203685478e+18 test_realnum_expr expr-1.227\ {i2=-9223372036854775806, i1=100000} {i1-i2} 9.22337203685488e+18 test_realnum_expr expr-1.228\ {i2=-9223372036854775807, i1=0} {i1-i2} 9223372036854775807 test_realnum_expr expr-1.229\ {i2=-9223372036854775807, i1=1} {i1-i2} 9.22337203685478e+18 test_realnum_expr expr-1.230\ {i1=-9223372036854775807, i2=1} {i1-i2} -9223372036854775808 test_realnum_expr expr-1.231\ {i1=-9223372036854775807, i2=2} {i1-i2} -9.22337203685478e+18 test_realnum_expr expr-1.232\ {i1=-9223372036854775807, i2=100000} {i1-i2} -9.22337203685488e+18 test_realnum_expr expr-1.233\ {i1=-9223372036854775808, i2=0} {i1-i2} -9223372036854775808 test_realnum_expr expr-1.234\ {i1=-9223372036854775808, i2=1} {i1-i2} -9.22337203685478e+18 test_realnum_expr expr-1.235\ {i2=9223372036854775807, i1=-1} {i1-i2} -9223372036854775808 test_realnum_expr expr-1.236\ {i2=9223372036854775807, i1=-2} {i1-i2} -9.22337203685478e+18 test_realnum_expr expr-1.237\ {i2=9223372036854775807, i1=-100000} {i1-i2} -9.22337203685488e+18 test_realnum_expr expr-1.238\ {i2=9223372036854775807, i1=0} {i1-i2} -9223372036854775807 test_realnum_expr expr-1.239\ {i2=9223372036854775807, i1=-1} {i1-i2} -9223372036854775808 test_realnum_expr expr-1.250\ {i1=4294967296, i2=2147483648} {i1*i2} 9.22337203685478e+18 test_realnum_expr expr-1.251\ {i1=4294967296, i2=2147483647} {i1*i2} 9223372032559808512 test_realnum_expr expr-1.252\ {i1=-4294967296, i2=2147483648} {i1*i2} -9223372036854775808 test_realnum_expr expr-1.253\ {i1=-4294967296, i2=2147483647} {i1*i2} -9223372032559808512 test_realnum_expr expr-1.254\ {i1=4294967296, i2=-2147483648} {i1*i2} -9223372036854775808 test_realnum_expr expr-1.255\ {i1=4294967296, i2=-2147483647} {i1*i2} -9223372032559808512 test_realnum_expr expr-1.256\ {i1=-4294967296, i2=-2147483648} {i1*i2} 9.22337203685478e+18 test_realnum_expr expr-1.257\ {i1=-4294967296, i2=-2147483647} {i1*i2} 9223372032559808512 }} ifcapable floatingpoint { test_expr expr-2.1 {r1=1.23, r2=2.34} {r1+r2} 3.57 test_expr expr-2.2 {r1=1.23, r2=2.34} {r1-r2} -1.11 |
︙ | ︙ | |||
879 880 881 882 883 884 885 | do_test expr-12.2 { catchsql { SELECT (CASE WHEN a>4 THEN 1 ELSE 0) FROM test1; } } {1 {near ")": syntax error}} ifcapable floatingpoint { | | | 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 | do_test expr-12.2 { catchsql { SELECT (CASE WHEN a>4 THEN 1 ELSE 0) FROM test1; } } {1 {near ")": syntax error}} ifcapable floatingpoint { do_realnum_test expr-13.1 { execsql { SELECT 12345678901234567890; } } {1.23456789012346e+19} } # Implicit String->Integer conversion is used when possible. |
︙ | ︙ | |||
904 905 906 907 908 909 910 | } } {9223372036854775807} } # If the value is too large, use String->Float conversion. # ifcapable floatingpoint { | | | | | | 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 | } } {9223372036854775807} } # If the value is too large, use String->Float conversion. # ifcapable floatingpoint { do_realnum_test expr-13.4 { execsql { SELECT 0+'9223372036854775808' } } {9.22337203685478e+18} do_realnum_test expr-13.5 { execsql { SELECT '9223372036854775808'+0 } } {9.22337203685478e+18} } # Use String->float conversion if the value is explicitly a floating # point value. # do_realnum_test expr-13.6 { execsql { SELECT 0+'9223372036854775807.0' } } {9.22337203685478e+18} do_realnum_test expr-13.7 { execsql { SELECT '9223372036854775807.0'+0 } } {9.22337203685478e+18} finish_test |
Changes to test/lock_common.tcl.
︙ | ︙ | |||
51 52 53 54 55 56 57 | proc csql1 {sql} { list [catch { sql1 $sql } msg] $msg } proc csql2 {sql} { list [catch { sql2 $sql } msg] $msg } proc csql3 {sql} { list [catch { sql3 $sql } msg] $msg } uplevel set $varname $tn uplevel $script | | | | 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | proc csql1 {sql} { list [catch { sql1 $sql } msg] $msg } proc csql2 {sql} { list [catch { sql2 $sql } msg] $msg } proc csql3 {sql} { list [catch { sql3 $sql } msg] $msg } uplevel set $varname $tn uplevel $script catch { code2 { db2 close } } catch { code3 { db3 close } } catch { close $::code2_chan } catch { close $::code3_chan } catch { db close } } } # Launch another testfixture process to be controlled by this one. A |
︙ | ︙ |
Changes to test/nan.test.
︙ | ︙ | |||
38 39 40 41 42 43 44 | set ::STMT [sqlite3_prepare db "INSERT INTO t1 VALUES(?)" -1 TAIL] sqlite3_bind_double $::STMT 1 NaN sqlite3_step $::STMT sqlite3_reset $::STMT db eval {SELECT x, typeof(x) FROM t1} } {{} null} if {$tcl_platform(platform) != "symbian"} { | | | | | | | 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 | set ::STMT [sqlite3_prepare db "INSERT INTO t1 VALUES(?)" -1 TAIL] sqlite3_bind_double $::STMT 1 NaN sqlite3_step $::STMT sqlite3_reset $::STMT db eval {SELECT x, typeof(x) FROM t1} } {{} null} if {$tcl_platform(platform) != "symbian"} { do_realnum_test nan-1.1.2 { sqlite3_bind_double $::STMT 1 +Inf sqlite3_step $::STMT sqlite3_reset $::STMT db eval {SELECT x, typeof(x) FROM t1} } {{} null inf real} do_realnum_test nan-1.1.3 { sqlite3_bind_double $::STMT 1 -Inf sqlite3_step $::STMT sqlite3_reset $::STMT db eval {SELECT x, typeof(x) FROM t1} } {{} null inf real -inf real} do_realnum_test nan-1.1.4 { sqlite3_bind_double $::STMT 1 -NaN sqlite3_step $::STMT sqlite3_reset $::STMT db eval {SELECT x, typeof(x) FROM t1} } {{} null inf real -inf real {} null} do_realnum_test nan-1.1.5 { sqlite3_bind_double $::STMT 1 NaN0 sqlite3_step $::STMT sqlite3_reset $::STMT db eval {SELECT x, typeof(x) FROM t1} } {{} null inf real -inf real {} null {} null} do_realnum_test nan-1.1.6 { sqlite3_bind_double $::STMT 1 -NaN0 sqlite3_step $::STMT sqlite3_reset $::STMT db eval {SELECT x, typeof(x) FROM t1} } {{} null inf real -inf real {} null {} null {} null} do_test nan-1.1.7 { db eval { |
︙ | ︙ | |||
227 228 229 230 231 232 233 | db eval {SELECT x, typeof(x) FROM t1} } {1e+308 real} if {$tcl_platform(platform) != "symbian"} { # Do not run these tests on Symbian, as the Tcl port doesn't like to # convert from floating point value "-inf" to a string. # | | | | 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 | db eval {SELECT x, typeof(x) FROM t1} } {1e+308 real} if {$tcl_platform(platform) != "symbian"} { # Do not run these tests on Symbian, as the Tcl port doesn't like to # convert from floating point value "-inf" to a string. # do_realnum_test nan-4.7 { db eval {DELETE FROM t1} db eval "INSERT INTO t1 VALUES([string repeat 9 309].0)" db eval {SELECT x, typeof(x) FROM t1} } {inf real} do_realnum_test nan-4.8 { db eval {DELETE FROM t1} db eval "INSERT INTO t1 VALUES(-[string repeat 9 309].0)" db eval {SELECT x, typeof(x) FROM t1} } {-inf real} } do_test nan-4.9 { db eval {DELETE FROM t1} |
︙ | ︙ | |||
309 310 311 312 313 314 315 | db eval {DELETE FROM t1} set small \ -[string repeat 0 10000].[string repeat 0 323][string repeat 9 10000] db eval "INSERT INTO t1 VALUES($small)" db eval {SELECT CAST(x AS text), typeof(x) FROM t1} } {-9.88131291682493e-324 real} | | | 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 | db eval {DELETE FROM t1} set small \ -[string repeat 0 10000].[string repeat 0 323][string repeat 9 10000] db eval "INSERT INTO t1 VALUES($small)" db eval {SELECT CAST(x AS text), typeof(x) FROM t1} } {-9.88131291682493e-324 real} do_realnum_test nan-4.20 { db eval {DELETE FROM t1} set big [string repeat 9 10000].0e-9000 db eval "INSERT INTO t1 VALUES($big)" db eval {SELECT x, typeof(x) FROM t1} } {inf real} finish_test |
Changes to test/pager1.test.
︙ | ︙ | |||
1649 1650 1651 1652 1653 1654 1655 | #------------------------------------------------------------------------- # Check that it is not possible to open a database file if the full path # to the associated journal file will be longer than sqlite3_vfs.mxPathname. # testvfs tv -default 1 tv script xOpenCb tv filter xOpen | | | 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 | #------------------------------------------------------------------------- # Check that it is not possible to open a database file if the full path # to the associated journal file will be longer than sqlite3_vfs.mxPathname. # testvfs tv -default 1 tv script xOpenCb tv filter xOpen proc xOpenCb {method filename args} { set ::file_len [string length $filename] } sqlite3 db test.db db close tv delete for {set ii [expr $::file_len-5]} {$ii < [expr $::file_len+20]} {incr ii} { |
︙ | ︙ | |||
2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 | } {exclusive 0 main reserved temp closed} #------------------------------------------------------------------------- # Test that if the "page-size" field in a journal-header is 0, the journal # file can still be rolled back. This is required for backward compatibility - # versions of SQLite prior to 3.5.8 always set this field to zero. # do_test pager1-31.1 { faultsim_delete_and_reopen execsql { PRAGMA cache_size = 10; PRAGMA page_size = 1024; CREATE TABLE t1(x, y, UNIQUE(x, y)); INSERT INTO t1 VALUES(randomblob(1500), randomblob(1500)); | > | 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 | } {exclusive 0 main reserved temp closed} #------------------------------------------------------------------------- # Test that if the "page-size" field in a journal-header is 0, the journal # file can still be rolled back. This is required for backward compatibility - # versions of SQLite prior to 3.5.8 always set this field to zero. # if {$tcl_platform(platform)=="unix"} { do_test pager1-31.1 { faultsim_delete_and_reopen execsql { PRAGMA cache_size = 10; PRAGMA page_size = 1024; CREATE TABLE t1(x, y, UNIQUE(x, y)); INSERT INTO t1 VALUES(randomblob(1500), randomblob(1500)); |
︙ | ︙ | |||
2404 2405 2406 2407 2408 2409 2410 | file copy test.db test.db2 file copy test.db-journal test.db2-journal hexio_write test.db2-journal 24 00000000 sqlite3 db2 test.db2 execsql { PRAGMA integrity_check } db2 } {ok} | | | 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 | file copy test.db test.db2 file copy test.db-journal test.db2-journal hexio_write test.db2-journal 24 00000000 sqlite3 db2 test.db2 execsql { PRAGMA integrity_check } db2 } {ok} } finish_test |
Changes to test/tester.tcl.
︙ | ︙ | |||
349 350 351 352 353 354 355 356 357 358 359 360 361 362 | puts "\nExpected: \[$expected\]\n Got: \[$result\]" fail_test $name } else { puts " Ok" } flush stdout } proc fix_testname {varname} { upvar $varname testname if {[info exists ::testprefix] && [string is digit [string range $testname 0 0]] } { set testname "${::testprefix}-$testname" | > > > > > > > > > | 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 | puts "\nExpected: \[$expected\]\n Got: \[$result\]" fail_test $name } else { puts " Ok" } flush stdout } proc realnum_normalize {r} { string map {1.#INF inf} [regsub -all {(e[+-])0+} $r {\1}] } proc do_realnum_test {name cmd expected} { uplevel [list do_test $name [ subst -nocommands { realnum_normalize [ $cmd ] } ] [realnum_normalize $expected]] } proc fix_testname {varname} { upvar $varname testname if {[info exists ::testprefix] && [string is digit [string range $testname 0 0]] } { set testname "${::testprefix}-$testname" |
︙ | ︙ |
Changes to test/tkt3838.test.
︙ | ︙ | |||
21 22 23 24 25 26 27 | source $testdir/tester.tcl ifcapable !altertable { finish_test return } | | | 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | source $testdir/tester.tcl ifcapable !altertable { finish_test return } do_realnum_test tkt3838-1.1 { db eval { PRAGMA encoding=UTF16; CREATE TABLE t1(x); INSERT INTO t1 VALUES(1); ALTER TABLE t1 ADD COLUMN b INTEGER DEFAULT '999'; ALTER TABLE t1 ADD COLUMN c REAL DEFAULT '9e99'; ALTER TABLE t1 ADD COLUMN d TEXT DEFAULT 'xyzzy'; |
︙ | ︙ |
Changes to test/tkt3922.test.
︙ | ︙ | |||
32 33 34 35 36 37 38 | execsql { CREATE TABLE t1(a NUMBER); INSERT INTO t1 VALUES('-1'); SELECT a, typeof(a) FROM t1; } } {-1 integer} } | | | | | 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 | execsql { CREATE TABLE t1(a NUMBER); INSERT INTO t1 VALUES('-1'); SELECT a, typeof(a) FROM t1; } } {-1 integer} } do_realnum_test tkt3922.2 { execsql { DELETE FROM t1; INSERT INTO t1 VALUES('-9223372036854775809'); SELECT a, typeof(a) FROM t1; } } {-9.22337203685478e+18 real} do_realnum_test tkt3922.3 { execsql { DELETE FROM t1; INSERT INTO t1 VALUES('-9223372036854776832'); SELECT a, typeof(a) FROM t1; } } {-9.22337203685478e+18 real} do_realnum_test tkt3922.4 { execsql { DELETE FROM t1; INSERT INTO t1 VALUES('-9223372036854776833'); SELECT a, typeof(a) FROM t1; } } {-9.22337203685478e+18 real} if {[working_64bit_int]} { |
︙ | ︙ | |||
74 75 76 77 78 79 80 | execsql { DELETE FROM t1; INSERT INTO t1 VALUES('1'); SELECT a, typeof(a) FROM t1; } } {1 integer} } | | | 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 | execsql { DELETE FROM t1; INSERT INTO t1 VALUES('1'); SELECT a, typeof(a) FROM t1; } } {1 integer} } do_realnum_test tkt3922.6 { execsql { DELETE FROM t1; INSERT INTO t1 VALUES('9223372036854775808'); SELECT a, typeof(a) FROM t1; } } {9.22337203685478e+18 real} finish_test |
Added test/uri.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 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 | # 2011 April 22 # # 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. # #*********************************************************************** # set testdir [file dirname $argv0] source $testdir/tester.tcl # Test organization: # # 1.*: That file names are correctly extracted from URIs. # 2.*: That URI options (query parameters) are correctly extracted from URIs. # 3.*: That specifying an unknown VFS causes an error. # 4.*: Tests for specifying other options (other than "vfs"). # 5.*: Test using a different VFS with an attached database. # 6.*: Test that authorities other than "" and localhost cause errors. # 7.*: Test that a read-write db can be attached to a read-only connection. # set testprefix uri db close sqlite3_shutdown sqlite3_config_uri 1 #------------------------------------------------------------------------- # Test that file names are correctly extracted from URIs. # foreach {tn uri file} { 1 test.db test.db 2 file:test.db test.db 3 file://PWD/test.db test.db 4 file:PWD/test.db test.db 5 file:test.db?mork=1 test.db 6 file:test.db?mork=1&tonglor=2 test.db 7 file:test.db?mork=1#boris test.db 8 file:test.db#boris test.db 9 test.db#boris test.db#boris 10 file:test%2Edb test.db 11 file file 12 http:test.db http:test.db 13 file:test.db%00extra test.db 14 file:test%00.db%00extra test 15 test.db?mork=1#boris test.db?mork=1#boris 16 file://localhostPWD/test.db%3Fhello test.db?hello } { if {$tcl_platform(platform)=="windows"} { if {$tn>14} break set uri [string map [list PWD /[pwd]] $uri] } else { set uri [string map [list PWD [pwd]] $uri] } forcedelete $file do_test 1.$tn.1 { file exists $file } 0 set DB [sqlite3_open $uri] do_test 1.$tn.2 { file exists $file } 1 sqlite3_close $DB forcedelete $file do_test 1.$tn.3 { file exists $file } 0 sqlite3 db xxx.db catchsql { ATTACH $uri AS aux } do_test 1.$tn.4 { file exists $file } 1 db close } #------------------------------------------------------------------------- # Test that URI query parameters are passed through to the VFS layer # correctly. # testvfs tvfs2 testvfs tvfs -default 1 tvfs filter xOpen tvfs script open_method proc open_method {method file arglist} { set ::arglist $arglist } foreach {tn uri kvlist} { 1 file:test.db?hello=world {hello world} 2 file:test.db?hello&world {hello {} world {}} 3 file:test.db?hello=1&world=2&vfs=tvfs {hello 1 world 2 vfs tvfs} 4 file:test.db?hello=1&world=2&vfs=tvfs2 {} 5 file:test.db?%68%65%6C%6C%6F=%77%6F%72%6C%64 {hello world} 6 file:test%00.db?hello%00extra=world%00ex {hello world} 7 file:test%00.db?hello%00=world%00 {hello world} 8 file:test%00.db?=world&xyz=abc {xyz abc} 9 file:test.db?%00hello=world&xyz=abc {xyz abc} 10 file:test.db?hello=%00world&xyz= {hello {} xyz {}} 11 file:test.db?=#ravada {} 12 file:test.db?&&&&&&&&hello=world&&&&&&& {hello world} 13 test.db?&&&&&&&&hello=world&&&&&&& {} 14 http:test.db?hello&world {} } { if {$tcl_platform(platform) == "windows" && $tn>12} { continue } set ::arglist "" set DB [sqlite3_open $uri] do_test 2.$tn.1 { set ::arglist } $kvlist sqlite3_close $DB sqlite3 db xxx.db set ::arglist "" execsql { ATTACH $uri AS aux } do_test 2.$tn.2 { set ::arglist } $kvlist db close } tvfs delete tvfs2 delete #------------------------------------------------------------------------- # Test that specifying a non-existent VFS raises an error. # do_test 3.1 { list [catch { sqlite3 db "file:test.db?vfs=nosuchvfs" } msg] $msg } {1 {no such vfs: nosuchvfs}} #------------------------------------------------------------------------- # Test some of the other options (other than "vfs"). # foreach {tn mode create_ok write_ok readonly_ok} { 1 ro 0 0 1 2 rw 0 1 0 3 rwc 1 1 0 } { catch { db close } forcedelete test.db set A(1) {0 {}} set A(0) {1 {unable to open database file}} do_test 4.1.$tn.1 { list [catch {sqlite3 db "file:test.db?mode=$mode"} msg] $msg } $A($create_ok) catch { db close } forcedelete test.db sqlite3 db test.db db eval { CREATE TABLE t1(a, b) } db close set A(1) {0 {}} set A(0) {1 {attempt to write a readonly database}} do_test 4.1.$tn.2 { sqlite3 db "file:test.db?mode=$mode" catchsql { INSERT INTO t1 VALUES(1, 2) } } $A($write_ok) set A(1) {0 {}} set A(0) [list 1 "access mode not allowed: $mode"] do_test 4.1.$tn.3 { list [catch {sqlite3 db "file:test.db?mode=$mode" -readonly 1} msg] $msg } $A($readonly_ok) } set orig [sqlite3_enable_shared_cache] foreach {tn options sc_default is_shared} { 1 "" 1 1 2 "cache=private" 1 0 3 "cache=shared" 1 1 4 "" 0 0 5 "cache=private" 0 0 6 "cache=shared" 0 1 } { catch { db close } forcedelete test.db sqlite3_enable_shared_cache 1 sqlite3 db2 test.db db2 eval {CREATE TABLE t1(a, b)} sqlite3_enable_shared_cache $sc_default sqlite3 db "file:test.db?$options" db eval {SELECT * FROM t1} set A(1) {1 {database table is locked: t1}} set A(0) {0 {}} do_test 4.2.$tn { db2 eval {BEGIN; INSERT INTO t1 VALUES(1, 2);} catchsql { SELECT * FROM t1 } } $A($is_shared) db2 close } do_test 4.3.1 { list [catch {sqlite3 db "file:test.db?mode=rc"} msg] $msg } {1 {no such access mode: rc}} do_test 4.3.2 { list [catch {sqlite3 db "file:test.db?cache=public"} msg] $msg } {1 {no such cache mode: public}} #------------------------------------------------------------------------- # Test that things work if an ATTACHed database uses a different VFS than # the main database. The important point is that for all operations # involving the ATTACHed database, the correct versions of the following # VFS are used for all operations involving the attached database. # # xOpen # xDelete # xAccess # xFullPathname # # This block of code creates two VFS - "tvfs1" and "tvfs2". Each time one # of the above methods is called using "tvfs1", global variable ::T1(X) is # set, where X is the file-name the method is called on. Calls to the above # methods using "tvfs2" set entries in the global T2 array. # testvfs tvfs1 tvfs1 filter {xOpen xDelete xAccess xFullPathname} tvfs1 script tvfs1_callback proc tvfs1_callback {method filename args} { set ::T1([file tail $filename]) 1 } testvfs tvfs2 tvfs2 filter {xOpen xDelete xAccess xFullPathname} tvfs2 script tvfs2_callback proc tvfs2_callback {method filename args} { set ::T2([file tail $filename]) 1 } catch {db close} eval forcedelete [glob test.db*] do_test 5.1.1 { sqlite3 db file:test.db1?vfs=tvfs1 execsql { ATTACH 'file:test.db2?vfs=tvfs2' AS aux; PRAGMA main.journal_mode = PERSIST; PRAGMA aux.journal_mode = PERSIST; CREATE TABLE t1(a, b); CREATE TABLE aux.t2(a, b); PRAGMA main.journal_mode = WAL; PRAGMA aux.journal_mode = WAL; INSERT INTO t1 VALUES('x', 'y'); INSERT INTO t2 VALUES('x', 'y'); } lsort [array names ::T1] } {test.db1 test.db1-journal test.db1-wal} do_test 5.1.2 { lsort [array names ::T2] } {test.db2 test.db2-journal test.db2-wal} db close tvfs1 delete tvfs2 delete #------------------------------------------------------------------------- # Check that only "" and "localhost" are acceptable as authorities. # catch {db close} foreach {tn uri res} { 1 "file://localhost/PWD/test.db" {not an error} 2 "file:///PWD/test.db" {not an error} 3 "file:/PWD/test.db" {not an error} 4 "file://l%6Fcalhost/PWD/test.db" {invalid uri authority: l%6Fcalhost} 5 "file://lbcalhost/PWD/test.db" {invalid uri authority: lbcalhost} 6 "file://x/PWD/test.db" {invalid uri authority: x} } { if {$tcl_platform(platform)=="windows"} { set uri [string map [list PWD [string range [pwd] 3 end]] $uri] } else { set uri [string map [list PWD [string range [pwd] 1 end]] $uri] } do_test 6.$tn { set DB [sqlite3_open $uri] sqlite3_errmsg $DB } $res catch { sqlite3_close $DB } } forcedelete test.db test.db2 do_test 7.1 { sqlite3 db test.db execsql { CREATE TABLE t1(a, b); INSERT INTO t1 VALUES(1, 2); ATTACH 'test.db2' AS aux; CREATE TABLE aux.t2(a, b); INSERT INTO t1 VALUES('a', 'b'); } db close } {} do_test 7.2 { sqlite3 db file:test.db?mode=ro execsql { ATTACH 'file:test.db2?mode=rw' AS aux } } {} do_execsql_test 7.3 { INSERT INTO t2 VALUES('c', 'd') } {} do_catchsql_test 7.4 { INSERT INTO t1 VALUES(3, 4) } {1 {attempt to write a readonly database}} finish_test |
Added test/walro.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 | # 2011 May 09 # # 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 contains tests for using WAL databases in read-only mode. # set testdir [file dirname $argv0] source $testdir/tester.tcl source $testdir/lock_common.tcl set ::testprefix walro do_multiclient_test tn { # These tests are only going to work on unix. # if {$tcl_platform(platform) != "unix"} continue # Do not run tests with the connections in the same process. # if {$tn==2} continue # Close all connections and delete the database. # code1 { db close } code2 { db2 close } code3 { db3 close } forcedelete test.db forcedelete walro foreach c {code1 code2 code3} { $c { sqlite3_shutdown sqlite3_config_uri 1 } } file mkdir walro do_test 1.1.1 { code2 { sqlite3 db2 test.db } sql2 { PRAGMA journal_mode = WAL; CREATE TABLE t1(x, y); INSERT INTO t1 VALUES('a', 'b'); } file exists test.db-shm } {1} do_test 1.1.2 { file attributes test.db-shm -permissions r--r--r-- code1 { sqlite3 db file:test.db?readonly_shm=1 } } {} do_test 1.1.3 { sql1 "SELECT * FROM t1" } {a b} do_test 1.1.4 { sql2 "INSERT INTO t1 VALUES('c', 'd')" } {} do_test 1.1.5 { sql1 "SELECT * FROM t1" } {a b c d} # Check that the read-only connection cannot write or checkpoint the db. # do_test 1.1.6 { csql1 "INSERT INTO t1 VALUES('e', 'f')" } {1 {attempt to write a readonly database}} do_test 1.1.7 { csql1 "PRAGMA wal_checkpoint" } {1 {attempt to write a readonly database}} do_test 1.1.9 { sql2 "INSERT INTO t1 VALUES('e', 'f')" } {} do_test 1.1.10 { sql1 "SELECT * FROM t1" } {a b c d e f} do_test 1.1.11 { sql2 { INSERT INTO t1 VALUES('g', 'h'); PRAGMA wal_checkpoint; } set {} {} } {} do_test 1.1.12 { sql1 "SELECT * FROM t1" } {a b c d e f g h} do_test 1.1.13 { sql2 "INSERT INTO t1 VALUES('i', 'j')" } {} do_test 1.2.1 { code2 { db2 close } code1 { db close } list [file exists test.db-wal] [file exists test.db-shm] } {1 1} do_test 1.2.2 { code1 { sqlite3 db file:test.db?readonly_shm=1 } sql1 { SELECT * FROM t1 } } {a b c d e f g h i j} do_test 1.2.3 { code1 { db close } file attributes test.db-shm -permissions rw-r--r-- hexio_write test.db-shm 0 01020304 file attributes test.db-shm -permissions r--r--r-- code1 { sqlite3 db file:test.db?readonly_shm=1 } csql1 { SELECT * FROM t1 } } {1 {attempt to write a readonly database}} do_test 1.2.4 { code1 { sqlite3_extended_errcode db } } {SQLITE_READONLY_RECOVERY} do_test 1.2.5 { file attributes test.db-shm -permissions rw-r--r-- code2 { sqlite3 db2 test.db } sql2 "SELECT * FROM t1" } {a b c d e f g h i j} file attributes test.db-shm -permissions r--r--r-- do_test 1.2.6 { sql1 "SELECT * FROM t1" } {a b c d e f g h i j} do_test 1.2.7 { sql2 { PRAGMA wal_checkpoint; INSERT INTO t1 VALUES('k', 'l'); } set {} {} } {} do_test 1.2.8 { sql1 "SELECT * FROM t1" } {a b c d e f g h i j k l} # Now check that if the readonly_shm option is not supplied, or if it # is set to zero, it is not possible to connect to the database without # read-write access to the shm. do_test 1.3.1 { code1 { db close } code1 { sqlite3 db test.db } csql1 { SELECT * FROM t1 } } {1 {unable to open database file}} # Also test that if the -shm file can be opened for read/write access, # it is, even if readonly_shm=1 is present in the URI. do_test 1.3.2.1 { code1 { db close } code2 { db2 close } file exists test.db-shm } {0} do_test 1.3.2.2 { code1 { sqlite3 db file:test.db?readonly_shm=1 } sql1 { SELECT * FROM t1 } } {a b c d e f g h i j k l} do_test 1.3.2.3 { code1 { db close } close [open test.db-shm w] file attributes test.db-shm -permissions r--r--r-- code1 { sqlite3 db file:test.db?readonly_shm=1 } csql1 { SELECT * FROM t1 } } {1 {attempt to write a readonly database}} do_test 1.3.2.4 { code1 { sqlite3_extended_errcode db } } {SQLITE_READONLY_RECOVERY} } finish_test |