Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | Sync with trunk. |
|---|---|
| Downloads: | Tarball | ZIP archive |
| Timelines: | family | ancestors | descendants | both | standard-cli-colors |
| Files: | files | file ages | folders |
| SHA3-256: |
e17d35e79627a0ab5294a5d69d9b0b2c |
| User & Date: | florian 2025-07-21 12:23:00.000 |
Context
|
2025-08-21
| ||
| 12:08 | Sync with trunk. ... (check-in: 286a900699 user: florian tags: standard-cli-colors) | |
|
2025-07-21
| ||
| 12:23 | Sync with trunk. ... (check-in: e17d35e796 user: florian tags: standard-cli-colors) | |
|
2025-07-15
| ||
| 20:11 | Update the built-in SQLite to the latest trunk version, for testing. ... (check-in: 01855974c9 user: drh tags: trunk) | |
|
2025-04-25
| ||
| 16:22 | Optimized validation of the FOSSIL_COLOR environment variable. ... (check-in: c5f1e0daea user: florian tags: standard-cli-colors) | |
Changes
Changes to VERSION.
|
| | | 1 | 2.27 |
Changes to extsrc/shell.c.
| ︙ | ︙ | |||
1264 1265 1266 1267 1268 1269 1270 |
const char *z2 = z;
while( *z2 ){ z2++; }
return 0x3fffffff & (int)(z2 - z);
}
/*
** Return the length of a string in characters. Multibyte UTF8 characters
| | > | > > > > > > > > | 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 |
const char *z2 = z;
while( *z2 ){ z2++; }
return 0x3fffffff & (int)(z2 - z);
}
/*
** Return the length of a string in characters. Multibyte UTF8 characters
** count as a single character for single-width characters, or as two
** characters for double-width characters.
*/
static int strlenChar(const char *z){
int n = 0;
while( *z ){
if( (0x80&z[0])==0 ){
n++;
z++;
}else{
int u = 0;
int len = decodeUtf8((const u8*)z, &u);
z += len;
n += cli_wcwidth(u);
}
}
return n;
}
/*
** Return open FILE * if zFile exists, can be opened for read
** and is an ordinary file or a character stream source.
|
| ︙ | ︙ | |||
1620 1621 1622 1623 1624 1625 1626 | char z[400]; if( n<1 ) n = 1; if( n>350 ) n = 350; sqlite3_snprintf(sizeof(z), z, "%#+.*e", n, r); sqlite3_result_text(pCtx, z, -1, SQLITE_TRANSIENT); } | < < < < < < < < < < < < < < < < < < < < < < < < | 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 | char z[400]; if( n<1 ) n = 1; if( n>350 ) n = 350; sqlite3_snprintf(sizeof(z), z, "%#+.*e", n, r); sqlite3_result_text(pCtx, z, -1, SQLITE_TRANSIENT); } /* ** SQL function: shell_add_schema(S,X) ** ** Add the schema name X to the CREATE statement in S and return the result. ** Examples: ** ** CREATE TABLE t1(x) -> CREATE TABLE xyz.t1(x); |
| ︙ | ︙ | |||
1726 1727 1728 1729 1730 1731 1732 | ** below by the ../tool/mkshellc.tcl script. Before processing that included ** code, we need to override some macros to make the included program code ** work here in the middle of this regular program. */ #define SQLITE_EXTENSION_INIT1 #define SQLITE_EXTENSION_INIT2(X) (void)(X) | < | | > > > > > > | | > < < < < < | | < < < < < < < < < < < < | < < < < | | < | | < | | < < < < < < < < < < < < < < < < < < < < < < < | < < < | < | < < < < < < | < < < | < < < < < < < | | | | < | < > < | | < < < < < < < < | | | < < < < < < < < < < < < < < < < < < < < < < | < < < < < < < < < < < > > > > | < < > > | < < < < < < | < < | | | < < | < < > > | > | < | > > < < < < | < | < < < | < < < | | | > > > | < | < > > > > > > | < > | < < > | < | | | < < < < | | | | < < < | | | < | | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | < < | | > | > > | < < < < | < | | < < < < < < < < < < | | < < | | < | | | < < < < | | < | < | < < < < < < < < < < < < < < < < < < | | < < | 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 |
** below by the ../tool/mkshellc.tcl script. Before processing that included
** code, we need to override some macros to make the included program code
** work here in the middle of this regular program.
*/
#define SQLITE_EXTENSION_INIT1
#define SQLITE_EXTENSION_INIT2(X) (void)(X)
/************************* Begin ../ext/misc/windirent.h ******************/
/*
** 2025-06-05
**
** 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.
**
*************************************************************************
**
** An implementation of opendir(), readdir(), and closedir() for Windows,
** based on the FindFirstFile(), FindNextFile(), and FindClose() APIs
** of Win32.
**
** #include this file inside any C-code module that needs to use
** opendir()/readdir()/closedir(). This file is a no-op on non-Windows
** machines. On Windows, static functions are defined that implement
** those standard interfaces.
*/
#if defined(_WIN32) && defined(_MSC_VER) && !defined(SQLITE_WINDIRENT_H)
#define SQLITE_WINDIRENT_H
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h>
#include <io.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <limits.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#ifndef FILENAME_MAX
# define FILENAME_MAX (260)
#endif
#ifndef S_ISREG
#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
#endif
#ifndef S_ISDIR
#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
#endif
#ifndef S_ISLNK
#define S_ISLNK(m) (0)
#endif
typedef unsigned short mode_t;
/* The dirent object for Windows is abbreviated. The only field really
** usable by applications is d_name[].
*/
struct dirent {
int d_ino; /* Inode number (synthesized) */
unsigned d_attributes; /* File attributes */
char d_name[FILENAME_MAX]; /* Null-terminated filename */
};
/* The internals of DIR are opaque according to standards. So it
** does not matter what we put here. */
typedef struct DIR DIR;
struct DIR {
intptr_t d_handle; /* Handle for findfirst()/findnext() */
struct dirent cur; /* Current entry */
};
/* Ignore hidden and system files */
#define WindowsFileToIgnore(a) \
((((a).attrib)&_A_HIDDEN) || (((a).attrib)&_A_SYSTEM))
/*
** Close a previously opened directory
*/
static int closedir(DIR *pDir){
int rc = 0;
if( pDir==0 ){
return EINVAL;
}
if( pDir->d_handle!=0 && pDir->d_handle!=(-1) ){
rc = _findclose(pDir->d_handle);
}
sqlite3_free(pDir);
return rc;
}
/*
** Open a new directory. The directory name should be UTF-8 encoded.
** appropriate translations happen automatically.
*/
static DIR *opendir(const char *zDirName){
DIR *pDir;
wchar_t *b1;
sqlite3_int64 sz;
struct _wfinddata_t data;
pDir = sqlite3_malloc64( sizeof(DIR) );
if( pDir==0 ) return 0;
memset(pDir, 0, sizeof(DIR));
memset(&data, 0, sizeof(data));
sz = strlen(zDirName);
b1 = sqlite3_malloc64( (sz+3)*sizeof(b1[0]) );
if( b1==0 ){
closedir(pDir);
return NULL;
}
sz = MultiByteToWideChar(CP_UTF8, 0, zDirName, sz, b1, sz);
b1[sz++] = '\\';
b1[sz++] = '*';
b1[sz] = 0;
if( sz+1>sizeof(data.name)/sizeof(data.name[0]) ){
closedir(pDir);
sqlite3_free(b1);
return NULL;
}
memcpy(data.name, b1, (sz+1)*sizeof(b1[0]));
sqlite3_free(b1);
pDir->d_handle = _wfindfirst(data.name, &data);
if( pDir->d_handle<0 ){
closedir(pDir);
return NULL;
}
while( WindowsFileToIgnore(data) ){
memset(&data, 0, sizeof(data));
if( _wfindnext(pDir->d_handle, &data)==-1 ){
closedir(pDir);
return NULL;
}
}
pDir->cur.d_ino = 0;
pDir->cur.d_attributes = data.attrib;
WideCharToMultiByte(CP_UTF8, 0, data.name, -1,
pDir->cur.d_name, FILENAME_MAX, 0, 0);
return pDir;
}
/*
** Read the next entry from a directory.
**
** The returned struct-dirent object is managed by DIR. It is only
** valid until the next readdir() or closedir() call. Only the
** d_name[] field is meaningful. The d_name[] value has been
** translated into UTF8.
*/
static struct dirent *readdir(DIR *pDir){
struct _wfinddata_t data;
if( pDir==0 ) return 0;
if( (pDir->cur.d_ino++)==0 ){
return &pDir->cur;
}
do{
memset(&data, 0, sizeof(data));
if( _wfindnext(pDir->d_handle, &data)==-1 ){
return NULL;
}
}while( WindowsFileToIgnore(data) );
pDir->cur.d_attributes = data.attrib;
WideCharToMultiByte(CP_UTF8, 0, data.name, -1,
pDir->cur.d_name, FILENAME_MAX, 0, 0);
return &pDir->cur;
}
#endif /* defined(_WIN32) && defined(_MSC_VER) */
/************************* End ../ext/misc/windirent.h ********************/
/************************* Begin ../ext/misc/memtrace.c ******************/
/*
** 2019-01-21
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**
|
| ︙ | ︙ | |||
8052 8053 8054 8055 8056 8057 8058 8059 8060 8061 8062 8063 8064 8065 | ** ** name: Path to file or directory (text value). ** mode: Value of stat.st_mode for directory entry (an integer). ** mtime: Value of stat.st_mtime for directory entry (an integer). ** data: For a regular file, a blob containing the file data. For a ** symlink, a text value containing the text of the link. For a ** directory, NULL. ** ** If a non-NULL value is specified for the optional $dir parameter and ** $path is a relative path, then $path is interpreted relative to $dir. ** And the paths returned in the "name" column of the table are also ** relative to directory $dir. ** ** Notes on building this extension for Windows: | > | 7844 7845 7846 7847 7848 7849 7850 7851 7852 7853 7854 7855 7856 7857 7858 | ** ** name: Path to file or directory (text value). ** mode: Value of stat.st_mode for directory entry (an integer). ** mtime: Value of stat.st_mtime for directory entry (an integer). ** data: For a regular file, a blob containing the file data. For a ** symlink, a text value containing the text of the link. For a ** directory, NULL. ** level: Directory hierarchy level. Topmost is 1. ** ** If a non-NULL value is specified for the optional $dir parameter and ** $path is a relative path, then $path is interpreted relative to $dir. ** And the paths returned in the "name" column of the table are also ** relative to directory $dir. ** ** Notes on building this extension for Windows: |
| ︙ | ︙ | |||
8077 8078 8079 8080 8081 8082 8083 8084 | #include <sys/stat.h> #include <fcntl.h> #if !defined(_WIN32) && !defined(WIN32) # include <unistd.h> # include <dirent.h> # include <utime.h> # include <sys/time.h> #else | > | < < | < | < < < < | < | | > > | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 7870 7871 7872 7873 7874 7875 7876 7877 7878 7879 7880 7881 7882 7883 7884 7885 7886 7887 7888 7889 7890 7891 7892 7893 7894 7895 7896 7897 7898 7899 7900 7901 7902 7903 7904 7905 7906 7907 7908 7909 7910 7911 7912 7913 7914 7915 7916 7917 7918 7919 7920 7921 7922 7923 7924 7925 7926 7927 7928 7929 7930 7931 7932 7933 7934 7935 7936 7937 7938 7939 7940 7941 7942 7943 7944 7945 7946 7947 7948 7949 |
#include <sys/stat.h>
#include <fcntl.h>
#if !defined(_WIN32) && !defined(WIN32)
# include <unistd.h>
# include <dirent.h>
# include <utime.h>
# include <sys/time.h>
# define STRUCT_STAT struct stat
#else
/* # include "windirent.h" */
# include <direct.h>
# define STRUCT_STAT struct _stat
# define chmod(path,mode) fileio_chmod(path,mode)
# define mkdir(path,mode) fileio_mkdir(path)
#endif
#include <time.h>
#include <errno.h>
/* When used as part of the CLI, the sqlite3_stdio.h module will have
** been included before this one. In that case use the sqlite3_stdio.h
** #defines. If not, create our own for fopen().
*/
#ifndef _SQLITE3_STDIO_H_
# define sqlite3_fopen fopen
#endif
/*
** Structure of the fsdir() table-valued function
*/
/* 0 1 2 3 4 5 6 */
#define FSDIR_SCHEMA "(name,mode,mtime,data,level,path HIDDEN,dir HIDDEN)"
#define FSDIR_COLUMN_NAME 0 /* Name of the file */
#define FSDIR_COLUMN_MODE 1 /* Access mode */
#define FSDIR_COLUMN_MTIME 2 /* Last modification time */
#define FSDIR_COLUMN_DATA 3 /* File content */
#define FSDIR_COLUMN_LEVEL 4 /* Level. Topmost is 1 */
#define FSDIR_COLUMN_PATH 5 /* Path to top of search */
#define FSDIR_COLUMN_DIR 6 /* Path is relative to this directory */
/*
** UTF8 chmod() function for Windows
*/
#if defined(_WIN32) || defined(WIN32)
static int fileio_chmod(const char *zPath, int pmode){
sqlite3_int64 sz = strlen(zPath);
wchar_t *b1 = sqlite3_malloc64( (sz+1)*sizeof(b1[0]) );
int rc;
if( b1==0 ) return -1;
sz = MultiByteToWideChar(CP_UTF8, 0, zPath, sz, b1, sz);
b1[sz] = 0;
rc = _wchmod(b1, pmode);
sqlite3_free(b1);
return rc;
}
#endif
/*
** UTF8 mkdir() function for Windows
*/
#if defined(_WIN32) || defined(WIN32)
static int fileio_mkdir(const char *zPath){
sqlite3_int64 sz = strlen(zPath);
wchar_t *b1 = sqlite3_malloc64( (sz+1)*sizeof(b1[0]) );
int rc;
if( b1==0 ) return -1;
sz = MultiByteToWideChar(CP_UTF8, 0, zPath, sz, b1, sz);
b1[sz] = 0;
rc = _wmkdir(b1);
sqlite3_free(b1);
return rc;
}
#endif
/*
** Set the result stored by context ctx to a blob containing the
** contents of file zName. Or, leave the result unchanged (NULL)
** if the file does not exist or is unreadable.
**
|
| ︙ | ︙ | |||
8245 8246 8247 8248 8249 8250 8251 | /* ** This function attempts to normalize the time values found in the stat() ** buffer to UTC. This is necessary on Win32, where the runtime library ** appears to return these values as local times. */ static void statTimesToUtc( const char *zPath, | | | 8067 8068 8069 8070 8071 8072 8073 8074 8075 8076 8077 8078 8079 8080 8081 |
/*
** This function attempts to normalize the time values found in the stat()
** buffer to UTC. This is necessary on Win32, where the runtime library
** appears to return these values as local times.
*/
static void statTimesToUtc(
const char *zPath,
STRUCT_STAT *pStatBuf
){
HANDLE hFindFile;
WIN32_FIND_DATAW fd;
LPWSTR zUnicodeName;
extern LPWSTR sqlite3_win32_utf8_to_unicode(const char*);
zUnicodeName = sqlite3_win32_utf8_to_unicode(zPath);
if( zUnicodeName ){
|
| ︙ | ︙ | |||
8273 8274 8275 8276 8277 8278 8279 | /* ** This function is used in place of stat(). On Windows, special handling ** is required in order for the included time to be returned as UTC. On all ** other systems, this function simply calls stat(). */ static int fileStat( const char *zPath, | | > > | > > > > | | < < | 8095 8096 8097 8098 8099 8100 8101 8102 8103 8104 8105 8106 8107 8108 8109 8110 8111 8112 8113 8114 8115 8116 8117 8118 8119 8120 8121 8122 8123 8124 8125 8126 8127 8128 8129 8130 8131 8132 8133 8134 8135 8136 |
/*
** This function is used in place of stat(). On Windows, special handling
** is required in order for the included time to be returned as UTC. On all
** other systems, this function simply calls stat().
*/
static int fileStat(
const char *zPath,
STRUCT_STAT *pStatBuf
){
#if defined(_WIN32)
sqlite3_int64 sz = strlen(zPath);
wchar_t *b1 = sqlite3_malloc64( (sz+1)*sizeof(b1[0]) );
int rc;
if( b1==0 ) return 1;
sz = MultiByteToWideChar(CP_UTF8, 0, zPath, sz, b1, sz);
b1[sz] = 0;
rc = _wstat(b1, pStatBuf);
if( rc==0 ) statTimesToUtc(zPath, pStatBuf);
return rc;
#else
return stat(zPath, pStatBuf);
#endif
}
/*
** This function is used in place of lstat(). On Windows, special handling
** is required in order for the included time to be returned as UTC. On all
** other systems, this function simply calls lstat().
*/
static int fileLinkStat(
const char *zPath,
STRUCT_STAT *pStatBuf
){
#if defined(_WIN32)
return fileStat(zPath, pStatBuf);
#else
return lstat(zPath, pStatBuf);
#endif
}
/*
** Argument zFile is the name of a file that will be created and/or written
|
| ︙ | ︙ | |||
8326 8327 8328 8329 8330 8331 8332 |
if( zCopy==0 ){
rc = SQLITE_NOMEM;
}else{
int nCopy = (int)strlen(zCopy);
int i = 1;
while( rc==SQLITE_OK ){
| | | 8152 8153 8154 8155 8156 8157 8158 8159 8160 8161 8162 8163 8164 8165 8166 |
if( zCopy==0 ){
rc = SQLITE_NOMEM;
}else{
int nCopy = (int)strlen(zCopy);
int i = 1;
while( rc==SQLITE_OK ){
STRUCT_STAT sStat;
int rc2;
for(; zCopy[i]!='/' && i<nCopy; i++);
if( i==nCopy ) break;
zCopy[i] = '\0';
rc2 = fileStat(zCopy, &sStat);
|
| ︙ | ︙ | |||
8376 8377 8378 8379 8380 8381 8382 |
{
if( S_ISDIR(mode) ){
if( mkdir(zFile, mode) ){
/* The mkdir() call to create the directory failed. This might not
** be an error though - if there is already a directory at the same
** path and either the permissions already match or can be changed
** to do so using chmod(), it is not an error. */
| | | 8202 8203 8204 8205 8206 8207 8208 8209 8210 8211 8212 8213 8214 8215 8216 |
{
if( S_ISDIR(mode) ){
if( mkdir(zFile, mode) ){
/* The mkdir() call to create the directory failed. This might not
** be an error though - if there is already a directory at the same
** path and either the permissions already match or can be changed
** to do so using chmod(), it is not an error. */
STRUCT_STAT sStat;
if( errno!=EEXIST
|| 0!=fileStat(zFile, &sStat)
|| !S_ISDIR(sStat.st_mode)
|| ((sStat.st_mode&0777)!=(mode&0777) && 0!=chmod(zFile, mode&0777))
){
return 1;
}
|
| ︙ | ︙ | |||
8572 8573 8574 8575 8576 8577 8578 8579 8580 8581 8582 8583 8584 |
char *zDir; /* Name of directory (nul-terminated) */
};
struct fsdir_cursor {
sqlite3_vtab_cursor base; /* Base class - must be first */
int nLvl; /* Number of entries in aLvl[] array */
int iLvl; /* Index of current entry */
FsdirLevel *aLvl; /* Hierarchy of directories being traversed */
const char *zBase;
int nBase;
| > | | 8398 8399 8400 8401 8402 8403 8404 8405 8406 8407 8408 8409 8410 8411 8412 8413 8414 8415 8416 8417 8418 8419 |
char *zDir; /* Name of directory (nul-terminated) */
};
struct fsdir_cursor {
sqlite3_vtab_cursor base; /* Base class - must be first */
int nLvl; /* Number of entries in aLvl[] array */
int mxLvl; /* Maximum level */
int iLvl; /* Index of current entry */
FsdirLevel *aLvl; /* Hierarchy of directories being traversed */
const char *zBase;
int nBase;
STRUCT_STAT sStat; /* Current lstat() results */
char *zPath; /* Path to current entry */
sqlite3_int64 iRowid; /* Current rowid */
};
typedef struct fsdir_tab fsdir_tab;
struct fsdir_tab {
sqlite3_vtab base; /* Base class - must be first */
|
| ︙ | ︙ | |||
8690 8691 8692 8693 8694 8695 8696 |
** Advance an fsdir_cursor to its next row of output.
*/
static int fsdirNext(sqlite3_vtab_cursor *cur){
fsdir_cursor *pCur = (fsdir_cursor*)cur;
mode_t m = pCur->sStat.st_mode;
pCur->iRowid++;
| | | 8517 8518 8519 8520 8521 8522 8523 8524 8525 8526 8527 8528 8529 8530 8531 |
** Advance an fsdir_cursor to its next row of output.
*/
static int fsdirNext(sqlite3_vtab_cursor *cur){
fsdir_cursor *pCur = (fsdir_cursor*)cur;
mode_t m = pCur->sStat.st_mode;
pCur->iRowid++;
if( S_ISDIR(m) && pCur->iLvl+3<pCur->mxLvl ){
/* Descend into this directory */
int iNew = pCur->iLvl + 1;
FsdirLevel *pLvl;
if( iNew>=pCur->nLvl ){
int nNew = iNew+1;
sqlite3_int64 nByte = nNew*sizeof(FsdirLevel);
FsdirLevel *aNew = (FsdirLevel*)sqlite3_realloc64(pCur->aLvl, nByte);
|
| ︙ | ︙ | |||
8798 8799 8800 8801 8802 8803 8804 8805 8806 8807 8808 8809 8810 8811 8812 |
sqlite3_result_text(ctx, aBuf, n, SQLITE_TRANSIENT);
if( aBuf!=aStatic ) sqlite3_free(aBuf);
#endif
}else{
readFileContents(ctx, pCur->zPath);
}
}
case FSDIR_COLUMN_PATH:
default: {
/* The FSDIR_COLUMN_PATH and FSDIR_COLUMN_DIR are input parameters.
** always return their values as NULL */
break;
}
}
| > > > > | 8625 8626 8627 8628 8629 8630 8631 8632 8633 8634 8635 8636 8637 8638 8639 8640 8641 8642 8643 |
sqlite3_result_text(ctx, aBuf, n, SQLITE_TRANSIENT);
if( aBuf!=aStatic ) sqlite3_free(aBuf);
#endif
}else{
readFileContents(ctx, pCur->zPath);
}
break;
}
case FSDIR_COLUMN_LEVEL:
sqlite3_result_int(ctx, pCur->iLvl+2);
break;
case FSDIR_COLUMN_PATH:
default: {
/* The FSDIR_COLUMN_PATH and FSDIR_COLUMN_DIR are input parameters.
** always return their values as NULL */
break;
}
}
|
| ︙ | ︙ | |||
8832 8833 8834 8835 8836 8837 8838 | fsdir_cursor *pCur = (fsdir_cursor*)cur; return (pCur->zPath==0); } /* ** xFilter callback. ** | | | > > > > | > > | | > > > > > > > > | 8663 8664 8665 8666 8667 8668 8669 8670 8671 8672 8673 8674 8675 8676 8677 8678 8679 8680 8681 8682 8683 8684 8685 8686 8687 8688 8689 8690 8691 8692 8693 8694 8695 8696 8697 8698 8699 8700 8701 8702 8703 8704 8705 8706 8707 8708 8709 8710 8711 8712 8713 8714 8715 8716 |
fsdir_cursor *pCur = (fsdir_cursor*)cur;
return (pCur->zPath==0);
}
/*
** xFilter callback.
**
** idxNum bit Meaning
** 0x01 PATH=N
** 0x02 DIR=N
** 0x04 LEVEL<N
** 0x08 LEVEL<=N
*/
static int fsdirFilter(
sqlite3_vtab_cursor *cur,
int idxNum, const char *idxStr,
int argc, sqlite3_value **argv
){
const char *zDir = 0;
fsdir_cursor *pCur = (fsdir_cursor*)cur;
int i;
(void)idxStr;
fsdirResetCursor(pCur);
if( idxNum==0 ){
fsdirSetErrmsg(pCur, "table function fsdir requires an argument");
return SQLITE_ERROR;
}
assert( (idxNum & 0x01)!=0 && argc>0 );
zDir = (const char*)sqlite3_value_text(argv[0]);
if( zDir==0 ){
fsdirSetErrmsg(pCur, "table function fsdir requires a non-NULL argument");
return SQLITE_ERROR;
}
i = 1;
if( (idxNum & 0x02)!=0 ){
assert( argc>i );
pCur->zBase = (const char*)sqlite3_value_text(argv[i++]);
}
if( (idxNum & 0x0c)!=0 ){
assert( argc>i );
pCur->mxLvl = sqlite3_value_int(argv[i++]);
if( idxNum & 0x08 ) pCur->mxLvl++;
if( pCur->mxLvl<=0 ) pCur->mxLvl = 1000000000;
}else{
pCur->mxLvl = 1000000000;
}
if( pCur->zBase ){
pCur->nBase = (int)strlen(pCur->zBase)+1;
pCur->zPath = sqlite3_mprintf("%s/%s", pCur->zBase, zDir);
}else{
pCur->zPath = sqlite3_mprintf("%s", zDir);
}
|
| ︙ | ︙ | |||
8886 8887 8888 8889 8890 8891 8892 | ** that uses the generate_series virtual table. This routine needs to create ** a query plan for each invocation and compute an estimated cost for that ** plan. ** ** In this implementation idxNum is used to represent the ** query plan. idxStr is unused. ** | | | | > > > > | | | | | | | | | | | | | | | | | | | > > > > > > > > > > > > > > > > > > > > > > > > > > | | | > | > > | | | 8731 8732 8733 8734 8735 8736 8737 8738 8739 8740 8741 8742 8743 8744 8745 8746 8747 8748 8749 8750 8751 8752 8753 8754 8755 8756 8757 8758 8759 8760 8761 8762 8763 8764 8765 8766 8767 8768 8769 8770 8771 8772 8773 8774 8775 8776 8777 8778 8779 8780 8781 8782 8783 8784 8785 8786 8787 8788 8789 8790 8791 8792 8793 8794 8795 8796 8797 8798 8799 8800 8801 8802 8803 8804 8805 8806 8807 8808 8809 8810 8811 8812 8813 8814 8815 8816 8817 8818 8819 8820 8821 8822 8823 8824 8825 8826 8827 8828 8829 8830 8831 8832 8833 8834 8835 8836 8837 8838 8839 |
** that uses the generate_series virtual table. This routine needs to create
** a query plan for each invocation and compute an estimated cost for that
** plan.
**
** In this implementation idxNum is used to represent the
** query plan. idxStr is unused.
**
** The query plan is represented by bits in idxNum:
**
** 0x01 The path value is supplied by argv[0]
** 0x02 dir is in argv[1]
** 0x04 maxdepth is in argv[1] or [2]
*/
static int fsdirBestIndex(
sqlite3_vtab *tab,
sqlite3_index_info *pIdxInfo
){
int i; /* Loop over constraints */
int idxPath = -1; /* Index in pIdxInfo->aConstraint of PATH= */
int idxDir = -1; /* Index in pIdxInfo->aConstraint of DIR= */
int idxLevel = -1; /* Index in pIdxInfo->aConstraint of LEVEL< or <= */
int idxLevelEQ = 0; /* 0x08 for LEVEL<= or LEVEL=. 0x04 for LEVEL< */
int omitLevel = 0; /* omit the LEVEL constraint */
int seenPath = 0; /* True if an unusable PATH= constraint is seen */
int seenDir = 0; /* True if an unusable DIR= constraint is seen */
const struct sqlite3_index_constraint *pConstraint;
(void)tab;
pConstraint = pIdxInfo->aConstraint;
for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
if( pConstraint->op==SQLITE_INDEX_CONSTRAINT_EQ ){
switch( pConstraint->iColumn ){
case FSDIR_COLUMN_PATH: {
if( pConstraint->usable ){
idxPath = i;
seenPath = 0;
}else if( idxPath<0 ){
seenPath = 1;
}
break;
}
case FSDIR_COLUMN_DIR: {
if( pConstraint->usable ){
idxDir = i;
seenDir = 0;
}else if( idxDir<0 ){
seenDir = 1;
}
break;
}
case FSDIR_COLUMN_LEVEL: {
if( pConstraint->usable && idxLevel<0 ){
idxLevel = i;
idxLevelEQ = 0x08;
omitLevel = 0;
}
break;
}
}
}else
if( pConstraint->iColumn==FSDIR_COLUMN_LEVEL
&& pConstraint->usable
&& idxLevel<0
){
if( pConstraint->op==SQLITE_INDEX_CONSTRAINT_LE ){
idxLevel = i;
idxLevelEQ = 0x08;
omitLevel = 1;
}else if( pConstraint->op==SQLITE_INDEX_CONSTRAINT_LT ){
idxLevel = i;
idxLevelEQ = 0x04;
omitLevel = 1;
}
}
}
if( seenPath || seenDir ){
/* If input parameters are unusable, disallow this plan */
return SQLITE_CONSTRAINT;
}
if( idxPath<0 ){
pIdxInfo->idxNum = 0;
/* The pIdxInfo->estimatedCost should have been initialized to a huge
** number. Leave it unchanged. */
pIdxInfo->estimatedRows = 0x7fffffff;
}else{
pIdxInfo->aConstraintUsage[idxPath].omit = 1;
pIdxInfo->aConstraintUsage[idxPath].argvIndex = 1;
pIdxInfo->idxNum = 0x01;
pIdxInfo->estimatedCost = 1.0e9;
i = 2;
if( idxDir>=0 ){
pIdxInfo->aConstraintUsage[idxDir].omit = 1;
pIdxInfo->aConstraintUsage[idxDir].argvIndex = i++;
pIdxInfo->idxNum |= 0x02;
pIdxInfo->estimatedCost /= 1.0e4;
}
if( idxLevel>=0 ){
pIdxInfo->aConstraintUsage[idxLevel].omit = omitLevel;
pIdxInfo->aConstraintUsage[idxLevel].argvIndex = i++;
pIdxInfo->idxNum |= idxLevelEQ;
pIdxInfo->estimatedCost /= 1.0e4;
}
}
return SQLITE_OK;
}
/*
|
| ︙ | ︙ | |||
16806 16807 16808 16809 16810 16811 16812 |
case SQLITE_FCNTL_OVERWRITE: zOp = "OVERWRITE"; break;
case SQLITE_FCNTL_VFSNAME: zOp = "VFSNAME"; break;
case SQLITE_FCNTL_POWERSAFE_OVERWRITE: zOp = "POWERSAFE_OVERWRITE"; break;
case SQLITE_FCNTL_PRAGMA: {
const char *const* a = (const char*const*)pArg;
if( a[1] && strcmp(a[1],"vfstrace")==0 && a[2] ){
const u8 *zArg = (const u8*)a[2];
| | | 16684 16685 16686 16687 16688 16689 16690 16691 16692 16693 16694 16695 16696 16697 16698 |
case SQLITE_FCNTL_OVERWRITE: zOp = "OVERWRITE"; break;
case SQLITE_FCNTL_VFSNAME: zOp = "VFSNAME"; break;
case SQLITE_FCNTL_POWERSAFE_OVERWRITE: zOp = "POWERSAFE_OVERWRITE"; break;
case SQLITE_FCNTL_PRAGMA: {
const char *const* a = (const char*const*)pArg;
if( a[1] && strcmp(a[1],"vfstrace")==0 && a[2] ){
const u8 *zArg = (const u8*)a[2];
if( zArg[0]>='0' && zArg[0]<='9' ){
pInfo->mTrace = (sqlite3_uint64)strtoll(a[2], 0, 0);
}else{
static const struct {
const char *z;
unsigned int m;
} aKw[] = {
{ "all", 0xffffffff },
|
| ︙ | ︙ | |||
18707 18708 18709 18710 18711 18712 18713 18714 18715 18716 18717 18718 18719 18720 |
int rc = sqlite3_create_module(db, "sqlite_dbdata", &dbdata_module, 0);
if( rc==SQLITE_OK ){
rc = sqlite3_create_module(db, "sqlite_dbptr", &dbdata_module, (void*)1);
}
return rc;
}
int sqlite3_dbdata_init(
sqlite3 *db,
char **pzErrMsg,
const sqlite3_api_routines *pApi
){
(void)pzErrMsg;
return sqlite3DbdataRegister(db);
| > > > | 18585 18586 18587 18588 18589 18590 18591 18592 18593 18594 18595 18596 18597 18598 18599 18600 18601 |
int rc = sqlite3_create_module(db, "sqlite_dbdata", &dbdata_module, 0);
if( rc==SQLITE_OK ){
rc = sqlite3_create_module(db, "sqlite_dbptr", &dbdata_module, (void*)1);
}
return rc;
}
#ifdef _WIN32
#endif
int sqlite3_dbdata_init(
sqlite3 *db,
char **pzErrMsg,
const sqlite3_api_routines *pApi
){
(void)pzErrMsg;
return sqlite3DbdataRegister(db);
|
| ︙ | ︙ | |||
25590 25591 25592 25593 25594 25595 25596 | #ifndef SQLITE_SHELL_FIDDLE ".www Display output of the next command in web browser", " --plain Show results as text/plain, not as HTML", #endif }; /* | | < | | > > > > > > > > > > > > > > > > | | > | | | | < < < | | > | < | < < < < | < | < | | < < < < < < < | | | | | | > | | | | | | | | | | | | | | | | | | | | | | | | > | | | | | | | | | | | | | | | | | | | | | < | 25471 25472 25473 25474 25475 25476 25477 25478 25479 25480 25481 25482 25483 25484 25485 25486 25487 25488 25489 25490 25491 25492 25493 25494 25495 25496 25497 25498 25499 25500 25501 25502 25503 25504 25505 25506 25507 25508 25509 25510 25511 25512 25513 25514 25515 25516 25517 25518 25519 25520 25521 25522 25523 25524 25525 25526 25527 25528 25529 25530 25531 25532 25533 25534 25535 25536 25537 25538 25539 25540 25541 25542 25543 25544 25545 25546 25547 25548 25549 25550 25551 25552 25553 25554 25555 25556 25557 25558 25559 25560 25561 25562 25563 25564 25565 25566 25567 25568 25569 25570 25571 25572 25573 25574 25575 25576 25577 25578 25579 25580 25581 25582 |
#ifndef SQLITE_SHELL_FIDDLE
".www Display output of the next command in web browser",
" --plain Show results as text/plain, not as HTML",
#endif
};
/*
** Output help text for commands that match zPattern.
**
** * If zPattern is NULL, then show all documented commands, but
** only give a one-line summary of each.
**
** * If zPattern is "-a" or "-all" or "--all" then show all help text
** for all commands except undocumented commands.
**
** * If zPattern is "0" then show all help for undocumented commands.
** Undocumented commands begin with "," instead of "." in the azHelp[]
** array.
**
** * If zPattern is a prefix for one or more documented commands, then
** show help for those commands. If only a single command matches the
** prefix, show the full text of the help. If multiple commands match,
** Only show just the first line of each.
**
** * Otherwise, show the complete text of any documented command for which
** zPattern is a LIKE match for any text within that command help
** text.
**
** Return the number commands that match zPattern.
*/
static int showHelp(FILE *out, const char *zPattern){
int i = 0;
int j = 0;
int n = 0;
char *zPat;
if( zPattern==0 ){
/* Show just the first line for all help topics */
zPattern = "[a-z]";
}else if( cli_strcmp(zPattern,"-a")==0
|| cli_strcmp(zPattern,"-all")==0
|| cli_strcmp(zPattern,"--all")==0
){
/* Show everything except undocumented commands */
zPattern = ".";
}else if( cli_strcmp(zPattern,"0")==0 ){
/* Show complete help text of undocumented commands */
int show = 0;
for(i=0; i<ArraySize(azHelp); i++){
if( azHelp[i][0]=='.' ){
show = 0;
}else if( azHelp[i][0]==',' ){
show = 1;
sqlite3_fprintf(out, ".%s\n", &azHelp[i][1]);
n++;
}else if( show ){
sqlite3_fprintf(out, "%s\n", azHelp[i]);
}
}
return n;
}
/* Seek documented commands for which zPattern is an exact prefix */
zPat = sqlite3_mprintf(".%s*", zPattern);
shell_check_oom(zPat);
for(i=0; i<ArraySize(azHelp); i++){
if( sqlite3_strglob(zPat, azHelp[i])==0 ){
sqlite3_fprintf(out, "%s\n", azHelp[i]);
j = i+1;
n++;
}
}
sqlite3_free(zPat);
if( n ){
if( n==1 ){
/* when zPattern is a prefix of exactly one command, then include
** the details of that command, which should begin at offset j */
while( j<ArraySize(azHelp)-1 && azHelp[j][0]==' ' ){
sqlite3_fprintf(out, "%s\n", azHelp[j]);
j++;
}
}
return n;
}
/* Look for documented commands that contain zPattern anywhere.
** Show complete text of all documented commands that match. */
zPat = sqlite3_mprintf("%%%s%%", zPattern);
shell_check_oom(zPat);
for(i=0; i<ArraySize(azHelp); i++){
if( azHelp[i][0]==',' ){
while( i<ArraySize(azHelp)-1 && azHelp[i+1][0]==' ' ) ++i;
continue;
}
if( azHelp[i][0]=='.' ) j = i;
if( sqlite3_strlike(zPat, azHelp[i], 0)==0 ){
sqlite3_fprintf(out, "%s\n", azHelp[j]);
while( j<ArraySize(azHelp)-1 && azHelp[j+1][0]==' ' ){
j++;
sqlite3_fprintf(out, "%s\n", azHelp[j]);
}
i = j;
n++;
}
}
sqlite3_free(zPat);
return n;
}
/* Forward reference */
static int process_input(ShellState *p);
/*
|
| ︙ | ︙ | |||
25935 25936 25937 25938 25939 25940 25941 25942 25943 25944 25945 25946 25947 25948 |
sqlite3_value **argv
){
int sleep = sqlite3_value_int(argv[0]);
(void)argcUnused;
sqlite3_sleep(sleep/1000);
sqlite3_result_int(context, sleep);
}
/* Flags for open_db().
**
** The default behavior of open_db() is to exit(1) if the database fails to
** open. The OPEN_DB_KEEPALIVE flag changes that so that it prints an error
** but still returns without calling exit.
**
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 25817 25818 25819 25820 25821 25822 25823 25824 25825 25826 25827 25828 25829 25830 25831 25832 25833 25834 25835 25836 25837 25838 25839 25840 25841 25842 25843 25844 25845 25846 25847 25848 25849 25850 25851 25852 25853 25854 25855 25856 25857 25858 25859 25860 25861 25862 25863 |
sqlite3_value **argv
){
int sleep = sqlite3_value_int(argv[0]);
(void)argcUnused;
sqlite3_sleep(sleep/1000);
sqlite3_result_int(context, sleep);
}
/*
** SQL function: shell_module_schema(X)
**
** Return a fake schema for the table-valued function or eponymous virtual
** table X.
*/
static void shellModuleSchema(
sqlite3_context *pCtx,
int nVal,
sqlite3_value **apVal
){
const char *zName;
char *zFake;
ShellState *p = (ShellState*)sqlite3_user_data(pCtx);
FILE *pSavedLog = p->pLog;
UNUSED_PARAMETER(nVal);
zName = (const char*)sqlite3_value_text(apVal[0]);
/* Temporarily disable the ".log" when calling shellFakeSchema() because
** shellFakeSchema() might generate failures for some ephemeral virtual
** tables due to missing arguments. Example: fts4aux.
** https://sqlite.org/forum/forumpost/42fe6520b803be51 */
p->pLog = 0;
zFake = zName? shellFakeSchema(sqlite3_context_db_handle(pCtx), 0, zName) : 0;
p->pLog = pSavedLog;
if( zFake ){
sqlite3_result_text(pCtx, sqlite3_mprintf("/* %s */", zFake),
-1, sqlite3_free);
free(zFake);
}
}
/* Flags for open_db().
**
** The default behavior of open_db() is to exit(1) if the database fails to
** open. The OPEN_DB_KEEPALIVE flag changes that so that it prints an error
** but still returns without calling exit.
**
|
| ︙ | ︙ | |||
26079 26080 26081 26082 26083 26084 26085 |
shellStrtod, 0, 0);
sqlite3_create_function(p->db, "dtostr", 1, SQLITE_UTF8, 0,
shellDtostr, 0, 0);
sqlite3_create_function(p->db, "dtostr", 2, SQLITE_UTF8, 0,
shellDtostr, 0, 0);
sqlite3_create_function(p->db, "shell_add_schema", 3, SQLITE_UTF8, 0,
shellAddSchemaName, 0, 0);
| | | 25994 25995 25996 25997 25998 25999 26000 26001 26002 26003 26004 26005 26006 26007 26008 |
shellStrtod, 0, 0);
sqlite3_create_function(p->db, "dtostr", 1, SQLITE_UTF8, 0,
shellDtostr, 0, 0);
sqlite3_create_function(p->db, "dtostr", 2, SQLITE_UTF8, 0,
shellDtostr, 0, 0);
sqlite3_create_function(p->db, "shell_add_schema", 3, SQLITE_UTF8, 0,
shellAddSchemaName, 0, 0);
sqlite3_create_function(p->db, "shell_module_schema", 1, SQLITE_UTF8, p,
shellModuleSchema, 0, 0);
sqlite3_create_function(p->db, "shell_putsnl", 1, SQLITE_UTF8, p,
shellPutsFunc, 0, 0);
sqlite3_create_function(p->db, "usleep",1,SQLITE_UTF8,0,
shellUSleepFunc, 0, 0);
#ifndef SQLITE_NOHAVE_SYSTEM
sqlite3_create_function(p->db, "edit", 1, SQLITE_UTF8, 0,
|
| ︙ | ︙ | |||
29539 29540 29541 29542 29543 29544 29545 |
}
open_db(p, 0);
rc = sqlite3_exec(p->db,
"SELECT sql FROM"
" (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
" FROM sqlite_schema UNION ALL"
" SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_schema) "
| | > | 29454 29455 29456 29457 29458 29459 29460 29461 29462 29463 29464 29465 29466 29467 29468 29469 |
}
open_db(p, 0);
rc = sqlite3_exec(p->db,
"SELECT sql FROM"
" (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
" FROM sqlite_schema UNION ALL"
" SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_schema) "
"WHERE type!='meta' AND sql NOTNULL"
" AND name NOT LIKE 'sqlite__%' ESCAPE '_' "
"ORDER BY x",
callback, &data, 0
);
if( rc==SQLITE_OK ){
sqlite3_stmt *pStmt;
rc = sqlite3_prepare_v2(p->db,
"SELECT rowid FROM sqlite_schema"
|
| ︙ | ︙ | |||
31015 31016 31017 31018 31019 31020 31021 |
if( !bGlob ){
appendText(&sSelect, " ESCAPE '\\' ", 0);
}
appendText(&sSelect, " AND ", 0);
sqlite3_free(zQarg);
}
if( bNoSystemTabs ){
| | | 30931 30932 30933 30934 30935 30936 30937 30938 30939 30940 30941 30942 30943 30944 30945 |
if( !bGlob ){
appendText(&sSelect, " ESCAPE '\\' ", 0);
}
appendText(&sSelect, " AND ", 0);
sqlite3_free(zQarg);
}
if( bNoSystemTabs ){
appendText(&sSelect, "name NOT LIKE 'sqlite__%%' ESCAPE '_' AND ", 0);
}
appendText(&sSelect, "sql IS NOT NULL"
" ORDER BY snum, rowid", 0);
if( bDebug ){
sqlite3_fprintf(p->out, "SQL: %s;\n", sSelect.z);
}else{
rc = sqlite3_exec(p->db, sSelect.z, callback, &data, &zErrMsg);
|
| ︙ | ︙ | |||
31446 31447 31448 31449 31450 31451 31452 |
zSql = "SELECT lower(name) as tname FROM sqlite_schema"
" WHERE type='table' AND coalesce(rootpage,0)>1"
" UNION ALL SELECT 'sqlite_schema'"
" ORDER BY 1 collate nocase";
}else{
zSql = "SELECT lower(name) as tname FROM sqlite_schema"
" WHERE type='table' AND coalesce(rootpage,0)>1"
| | | 31362 31363 31364 31365 31366 31367 31368 31369 31370 31371 31372 31373 31374 31375 31376 |
zSql = "SELECT lower(name) as tname FROM sqlite_schema"
" WHERE type='table' AND coalesce(rootpage,0)>1"
" UNION ALL SELECT 'sqlite_schema'"
" ORDER BY 1 collate nocase";
}else{
zSql = "SELECT lower(name) as tname FROM sqlite_schema"
" WHERE type='table' AND coalesce(rootpage,0)>1"
" AND name NOT LIKE 'sqlite__%' ESCAPE '_'"
" ORDER BY 1 collate nocase";
}
sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
initText(&sQuery);
initText(&sSql);
appendText(&sSql, "WITH [sha3sum$query](a,b) AS(",0);
zSep = "VALUES(";
|
| ︙ | ︙ | |||
31511 31512 31513 31514 31515 31516 31517 |
}
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) && !defined(SQLITE_OMIT_VIRTUALTABLE)
{
int lrc;
char *zRevText = /* Query for reversible to-blob-to-text check */
"SELECT lower(name) as tname FROM sqlite_schema\n"
"WHERE type='table' AND coalesce(rootpage,0)>1\n"
| | | 31427 31428 31429 31430 31431 31432 31433 31434 31435 31436 31437 31438 31439 31440 31441 |
}
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) && !defined(SQLITE_OMIT_VIRTUALTABLE)
{
int lrc;
char *zRevText = /* Query for reversible to-blob-to-text check */
"SELECT lower(name) as tname FROM sqlite_schema\n"
"WHERE type='table' AND coalesce(rootpage,0)>1\n"
"AND name NOT LIKE 'sqlite__%%' ESCAPE '_'%s\n"
"ORDER BY 1 collate nocase";
zRevText = sqlite3_mprintf(zRevText, zLike? " AND name LIKE $tspec" : "");
zRevText = sqlite3_mprintf(
/* lower-case query is first run, producing upper-case query. */
"with tabcols as materialized(\n"
"select tname, cname\n"
"from ("
|
| ︙ | ︙ | |||
31707 31708 31709 31710 31711 31712 31713 |
appendText(&s, zDbName, '\'');
appendText(&s, "||'.'||name FROM ", 0);
}
appendText(&s, zDbName, '"');
appendText(&s, ".sqlite_schema ", 0);
if( c=='t' ){
appendText(&s," WHERE type IN ('table','view')"
| | | 31623 31624 31625 31626 31627 31628 31629 31630 31631 31632 31633 31634 31635 31636 31637 |
appendText(&s, zDbName, '\'');
appendText(&s, "||'.'||name FROM ", 0);
}
appendText(&s, zDbName, '"');
appendText(&s, ".sqlite_schema ", 0);
if( c=='t' ){
appendText(&s," WHERE type IN ('table','view')"
" AND name NOT LIKE 'sqlite__%' ESCAPE '_'"
" AND name LIKE ?1", 0);
}else{
appendText(&s," WHERE type='index'"
" AND tbl_name LIKE ?1", 0);
}
}
rc = sqlite3_finalize(pStmt);
|
| ︙ | ︙ | |||
31801 31802 31803 31804 31805 31806 31807 |
int ctrlCode; /* Integer code for that option */
int unSafe; /* Not valid unless --unsafe-testing */
const char *zUsage; /* Usage notes */
} aCtrl[] = {
{"always", SQLITE_TESTCTRL_ALWAYS, 1, "BOOLEAN" },
{"assert", SQLITE_TESTCTRL_ASSERT, 1, "BOOLEAN" },
/*{"benign_malloc_hooks",SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS,1, "" },*/
| | | 31717 31718 31719 31720 31721 31722 31723 31724 31725 31726 31727 31728 31729 31730 31731 |
int ctrlCode; /* Integer code for that option */
int unSafe; /* Not valid unless --unsafe-testing */
const char *zUsage; /* Usage notes */
} aCtrl[] = {
{"always", SQLITE_TESTCTRL_ALWAYS, 1, "BOOLEAN" },
{"assert", SQLITE_TESTCTRL_ASSERT, 1, "BOOLEAN" },
/*{"benign_malloc_hooks",SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS,1, "" },*/
{"bitvec_test", SQLITE_TESTCTRL_BITVEC_TEST, 1, "SIZE INT-ARRAY"},
{"byteorder", SQLITE_TESTCTRL_BYTEORDER, 0, "" },
{"extra_schema_checks",SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS,0,"BOOLEAN" },
{"fault_install", SQLITE_TESTCTRL_FAULT_INSTALL, 1,"args..." },
{"fk_no_action", SQLITE_TESTCTRL_FK_NO_ACTION, 0, "BOOLEAN" },
{"imposter", SQLITE_TESTCTRL_IMPOSTER,1,"SCHEMA ON/OFF ROOTPAGE"},
{"internal_functions", SQLITE_TESTCTRL_INTERNAL_FUNCTIONS,0,"" },
{"json_selfcheck", SQLITE_TESTCTRL_JSON_SELFCHECK ,0,"BOOLEAN" },
|
| ︙ | ︙ | |||
31920 31921 31922 31923 31924 31925 31926 31927 31928 31929 31930 31931 31932 31933 |
{ 0x00800000, 1, "FlttnUnionAll" },
{ 0x01000000, 1, "IndexedEXpr" },
{ 0x02000000, 1, "Coroutines" },
{ 0x04000000, 1, "NullUnusedCols" },
{ 0x08000000, 1, "OnePass" },
{ 0x10000000, 1, "OrderBySubq" },
{ 0x20000000, 1, "StarQuery" },
{ 0xffffffff, 0, "All" },
};
unsigned int curOpt;
unsigned int newOpt;
unsigned int m;
int ii;
int nOff;
| > | 31836 31837 31838 31839 31840 31841 31842 31843 31844 31845 31846 31847 31848 31849 31850 |
{ 0x00800000, 1, "FlttnUnionAll" },
{ 0x01000000, 1, "IndexedEXpr" },
{ 0x02000000, 1, "Coroutines" },
{ 0x04000000, 1, "NullUnusedCols" },
{ 0x08000000, 1, "OnePass" },
{ 0x10000000, 1, "OrderBySubq" },
{ 0x20000000, 1, "StarQuery" },
{ 0x40000000, 1, "ExistsToJoin" },
{ 0xffffffff, 0, "All" },
};
unsigned int curOpt;
unsigned int newOpt;
unsigned int m;
int ii;
int nOff;
|
| ︙ | ︙ | |||
32139 32140 32141 32142 32143 32144 32145 32146 32147 32148 32149 32150 32151 32152 |
isOk = 1;
}else{
rc2 = booleanValue(azArg[2]);
isOk = 3;
}
sqlite3_test_control(testctrl, &rc2);
break;
case SQLITE_TESTCTRL_FAULT_INSTALL: {
int kk;
int bShowHelp = nArg<=2;
isOk = 3;
for(kk=2; kk<nArg; kk++){
const char *z = azArg[kk];
if( z[0]=='-' && z[1]=='-' ) z++;
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 32056 32057 32058 32059 32060 32061 32062 32063 32064 32065 32066 32067 32068 32069 32070 32071 32072 32073 32074 32075 32076 32077 32078 32079 32080 32081 32082 32083 32084 32085 32086 32087 32088 32089 32090 32091 32092 32093 32094 32095 32096 32097 32098 32099 32100 32101 32102 32103 32104 32105 32106 32107 32108 32109 32110 32111 32112 |
isOk = 1;
}else{
rc2 = booleanValue(azArg[2]);
isOk = 3;
}
sqlite3_test_control(testctrl, &rc2);
break;
case SQLITE_TESTCTRL_BITVEC_TEST: {
/* Examples:
** .testctrl bitvec_test 100 6,1 -- Show BITVEC constants
** .testctrl bitvec_test 1000 1,12,7,3 -- Simple test
** ---- --------
** size of Bitvec -----^ ^--- aOp array. 0 added at end.
**
** See comments on sqlite3BitvecBuiltinTest() for more information
** about the aOp[] array.
*/
int iSize;
const char *zTestArg;
int nOp;
int ii, jj, x;
int *aOp;
if( nArg!=4 ){
sqlite3_fprintf(stderr,
"ERROR - should be: \".testctrl bitvec_test SIZE INT-ARRAY\"\n"
);
rc = 1;
goto meta_command_exit;
}
isOk = 3;
iSize = (int)integerValue(azArg[2]);
zTestArg = azArg[3];
nOp = (int)strlen(zTestArg)+1;
aOp = malloc( sizeof(int)*(nOp+1) );
shell_check_oom(aOp);
memset(aOp, 0, sizeof(int)*(nOp+1) );
for(ii = jj = x = 0; zTestArg[ii]!=0; ii++){
if( IsDigit(zTestArg[ii]) ){
x = x*10 + zTestArg[ii] - '0';
}else{
aOp[jj++] = x;
x = 0;
}
}
aOp[jj] = x;
x = sqlite3_test_control(testctrl, iSize, aOp);
sqlite3_fprintf(p->out, "result: %d\n", x);
free(aOp);
break;
}
case SQLITE_TESTCTRL_FAULT_INSTALL: {
int kk;
int bShowHelp = nArg<=2;
isOk = 3;
for(kk=2; kk<nArg; kk++){
const char *z = azArg[kk];
if( z[0]=='-' && z[1]=='-' ) z++;
|
| ︙ | ︙ |
Changes to extsrc/sqlite3.c.
1 2 | /****************************************************************************** ** This file is an amalgamation of many separate C source files from SQLite | | | | 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 | /****************************************************************************** ** This file is an amalgamation of many separate C source files from SQLite ** version 3.51.0. By combining all the individual C code files into this ** single large file, the entire code can be compiled as a single translation ** unit. This allows many compilers to do optimizations that would not be ** possible if the files were compiled separately. Performance improvements ** of 5% or more are commonly seen when SQLite is compiled as a single ** translation unit. ** ** This file is all you need to compile SQLite. To use SQLite in other ** programs, you need this file and the "sqlite3.h" header file that defines ** the programming interface to the SQLite library. (If you do not have ** the "sqlite3.h" header file at hand, you will find a copy embedded within ** the text of this file. Search for "Begin file sqlite3.h" to find the start ** of the embedded sqlite3.h header file.) Additional code files may be needed ** if you want a wrapper to interface SQLite with your choice of programming ** language. The code for the "sqlite3" command-line shell is also in a ** separate file. This file contains only code for the core SQLite library. ** ** The content in this amalgamation comes from Fossil check-in ** 9f184f8dfa5ef6d57e10376adc30e0060ced with changes in files: ** ** */ #ifndef SQLITE_AMALGAMATION #define SQLITE_CORE 1 #define SQLITE_AMALGAMATION 1 #ifndef SQLITE_PRIVATE |
| ︙ | ︙ | |||
461 462 463 464 465 466 467 | ** been edited in any way since it was last checked in, then the last ** four hexadecimal digits of the hash may be modified. ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ | | | | | | | | 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 | ** been edited in any way since it was last checked in, then the last ** four hexadecimal digits of the hash may be modified. ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ #define SQLITE_VERSION "3.51.0" #define SQLITE_VERSION_NUMBER 3051000 #define SQLITE_SOURCE_ID "2025-07-15 19:00:01 9f184f8dfa5ef6d57e10376adc30e0060ceda07d283c23dfdfe3dbdd6608f839" /* ** CAPI3REF: Run-Time Library Version Numbers ** KEYWORDS: sqlite3_version sqlite3_sourceid ** ** These interfaces provide the same information as the [SQLITE_VERSION], ** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros ** but are associated with the library instead of the header file. ^(Cautious ** programmers might include assert() statements in their application to ** verify that values returned by these interfaces match the macros in ** the header, and thus ensure that the application is ** compiled with matching library and header files. ** ** <blockquote><pre> ** assert( sqlite3_libversion_number()==SQLITE_VERSION_NUMBER ); ** assert( strncmp(sqlite3_sourceid(),SQLITE_SOURCE_ID,80)==0 ); ** assert( strcmp(sqlite3_libversion(),SQLITE_VERSION)==0 ); ** </pre></blockquote>)^ ** ** ^The sqlite3_version[] string constant contains the text of the ** [SQLITE_VERSION] macro. ^The sqlite3_libversion() function returns a ** pointer to the sqlite3_version[] string constant. The sqlite3_libversion() ** function is provided for use in DLLs since DLL users usually do not have ** direct access to string constants within the DLL. ^The ** sqlite3_libversion_number() function returns an integer equal to ** [SQLITE_VERSION_NUMBER]. ^(The sqlite3_sourceid() function returns ** a pointer to a string constant whose value is the same as the ** [SQLITE_SOURCE_ID] C preprocessor macro. Except if SQLite is built ** using an edited copy of [the amalgamation], then the last four characters |
| ︙ | ︙ | |||
685 686 687 688 689 690 691 | ** ** The sqlite3_exec() interface is a convenience wrapper around ** [sqlite3_prepare_v2()], [sqlite3_step()], and [sqlite3_finalize()], ** that allows an application to run multiple statements of SQL ** without having to use a lot of C code. ** ** ^The sqlite3_exec() interface runs zero or more UTF-8 encoded, | | | 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 | ** ** The sqlite3_exec() interface is a convenience wrapper around ** [sqlite3_prepare_v2()], [sqlite3_step()], and [sqlite3_finalize()], ** that allows an application to run multiple statements of SQL ** without having to use a lot of C code. ** ** ^The sqlite3_exec() interface runs zero or more UTF-8 encoded, ** semicolon-separated SQL statements passed into its 2nd argument, ** in the context of the [database connection] passed in as its 1st ** argument. ^If the callback function of the 3rd argument to ** sqlite3_exec() is not NULL, then it is invoked for each result row ** coming out of the evaluated SQL statements. ^The 4th argument to ** sqlite3_exec() is relayed through to the 1st argument of each ** callback invocation. ^If the callback pointer to sqlite3_exec() ** is NULL, then no callback is ever invoked and result rows are |
| ︙ | ︙ | |||
718 719 720 721 722 723 724 | ** ^The 2nd argument to the sqlite3_exec() callback function is the ** number of columns in the result. ^The 3rd argument to the sqlite3_exec() ** callback is an array of pointers to strings obtained as if from ** [sqlite3_column_text()], one for each column. ^If an element of a ** result row is NULL then the corresponding string pointer for the ** sqlite3_exec() callback is a NULL pointer. ^The 4th argument to the ** sqlite3_exec() callback is an array of pointers to strings where each | | | 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 | ** ^The 2nd argument to the sqlite3_exec() callback function is the ** number of columns in the result. ^The 3rd argument to the sqlite3_exec() ** callback is an array of pointers to strings obtained as if from ** [sqlite3_column_text()], one for each column. ^If an element of a ** result row is NULL then the corresponding string pointer for the ** sqlite3_exec() callback is a NULL pointer. ^The 4th argument to the ** sqlite3_exec() callback is an array of pointers to strings where each ** entry represents the name of a corresponding result column as obtained ** from [sqlite3_column_name()]. ** ** ^If the 2nd parameter to sqlite3_exec() is a NULL pointer, a pointer ** to an empty string, or a pointer that contains only whitespace and/or ** SQL comments, then no SQL statements are evaluated and the database ** is not changed. ** |
| ︙ | ︙ | |||
904 905 906 907 908 909 910 | ** though future versions of SQLite might change so that an error is ** raised if any of the disallowed bits are passed into sqlite3_open_v2(). ** Applications should not depend on the historical behavior. ** ** Note in particular that passing the SQLITE_OPEN_EXCLUSIVE flag into ** [sqlite3_open_v2()] does *not* cause the underlying database file ** to be opened using O_EXCL. Passing SQLITE_OPEN_EXCLUSIVE into | | | 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 | ** though future versions of SQLite might change so that an error is ** raised if any of the disallowed bits are passed into sqlite3_open_v2(). ** Applications should not depend on the historical behavior. ** ** Note in particular that passing the SQLITE_OPEN_EXCLUSIVE flag into ** [sqlite3_open_v2()] does *not* cause the underlying database file ** to be opened using O_EXCL. Passing SQLITE_OPEN_EXCLUSIVE into ** [sqlite3_open_v2()] has historically been a no-op and might become an ** error in future versions of SQLite. */ #define SQLITE_OPEN_READONLY 0x00000001 /* Ok for sqlite3_open_v2() */ #define SQLITE_OPEN_READWRITE 0x00000002 /* Ok for sqlite3_open_v2() */ #define SQLITE_OPEN_CREATE 0x00000004 /* Ok for sqlite3_open_v2() */ #define SQLITE_OPEN_DELETEONCLOSE 0x00000008 /* VFS only */ #define SQLITE_OPEN_EXCLUSIVE 0x00000010 /* VFS only */ |
| ︙ | ︙ | |||
998 999 1000 1001 1002 1003 1004 | /* ** CAPI3REF: File Locking Levels ** ** SQLite uses one of these integer values as the second ** argument to calls it makes to the xLock() and xUnlock() methods ** of an [sqlite3_io_methods] object. These values are ordered from | | | 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 | /* ** CAPI3REF: File Locking Levels ** ** SQLite uses one of these integer values as the second ** argument to calls it makes to the xLock() and xUnlock() methods ** of an [sqlite3_io_methods] object. These values are ordered from ** least restrictive to most restrictive. ** ** The argument to xLock() is always SHARED or higher. The argument to ** xUnlock is either SHARED or NONE. */ #define SQLITE_LOCK_NONE 0 /* xUnlock() only */ #define SQLITE_LOCK_SHARED 1 /* xLock() or xUnlock() */ #define SQLITE_LOCK_RESERVED 2 /* xLock() only */ |
| ︙ | ︙ | |||
1314 1315 1316 1317 1318 1319 1320 | ** ^The [SQLITE_FCNTL_OVERWRITE] opcode is invoked by SQLite after opening ** a write transaction to indicate that, unless it is rolled back for some ** reason, the entire database file will be overwritten by the current ** transaction. This is used by VACUUM operations. ** ** <li>[[SQLITE_FCNTL_VFSNAME]] ** ^The [SQLITE_FCNTL_VFSNAME] opcode can be used to obtain the names of | | | | 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 | ** ^The [SQLITE_FCNTL_OVERWRITE] opcode is invoked by SQLite after opening ** a write transaction to indicate that, unless it is rolled back for some ** reason, the entire database file will be overwritten by the current ** transaction. This is used by VACUUM operations. ** ** <li>[[SQLITE_FCNTL_VFSNAME]] ** ^The [SQLITE_FCNTL_VFSNAME] opcode can be used to obtain the names of ** all [VFSes] in the VFS stack. The names of all VFS shims and the ** final bottom-level VFS are written into memory obtained from ** [sqlite3_malloc()] and the result is stored in the char* variable ** that the fourth parameter of [sqlite3_file_control()] points to. ** The caller is responsible for freeing the memory when done. As with ** all file-control actions, there is no guarantee that this will actually ** do anything. Callers should initialize the char* variable to a NULL ** pointer in case this file-control is not implemented. This file-control ** is intended for diagnostic use only. ** ** <li>[[SQLITE_FCNTL_VFS_POINTER]] ** ^The [SQLITE_FCNTL_VFS_POINTER] opcode finds a pointer to the top-level ** [VFSes] currently in use. ^(The argument X in ** sqlite3_file_control(db,SQLITE_FCNTL_VFS_POINTER,X) must be ** of type "[sqlite3_vfs] **". This opcode will set *X ** to a pointer to the top-level VFS.)^ ** ^When there are multiple VFS shims in the stack, this opcode finds the ** upper-most shim only. ** ** <li>[[SQLITE_FCNTL_PRAGMA]] ** ^Whenever a [PRAGMA] statement is parsed, an [SQLITE_FCNTL_PRAGMA] ** file control is sent to the open [sqlite3_file] object corresponding |
| ︙ | ︙ | |||
1518 1519 1520 1521 1522 1523 1524 | ** in wal mode after the client has finished copying pages from the wal ** file to the database file, but before the *-shm file is updated to ** record the fact that the pages have been checkpointed. ** ** <li>[[SQLITE_FCNTL_EXTERNAL_READER]] ** The EXPERIMENTAL [SQLITE_FCNTL_EXTERNAL_READER] opcode is used to detect ** whether or not there is a database client in another process with a wal-mode | | | 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 | ** in wal mode after the client has finished copying pages from the wal ** file to the database file, but before the *-shm file is updated to ** record the fact that the pages have been checkpointed. ** ** <li>[[SQLITE_FCNTL_EXTERNAL_READER]] ** The EXPERIMENTAL [SQLITE_FCNTL_EXTERNAL_READER] opcode is used to detect ** whether or not there is a database client in another process with a wal-mode ** transaction open on the database or not. It is only available on unix. The ** (void*) argument passed with this file-control should be a pointer to a ** value of type (int). The integer value is set to 1 if the database is a wal ** mode database and there exists at least one client in another process that ** currently has an SQL transaction open on the database. It is set to 0 if ** the database is not a wal-mode db, or if there is no such connection in any ** other process. This opcode cannot be used to detect transactions opened ** by clients within the current process, only within other processes. |
| ︙ | ︙ | |||
1943 1944 1945 1946 1947 1948 1949 | ** the library (perhaps it is unable to allocate a needed resource such ** as a mutex) it returns an [error code] other than [SQLITE_OK]. ** ** ^The sqlite3_initialize() routine is called internally by many other ** SQLite interfaces so that an application usually does not need to ** invoke sqlite3_initialize() directly. For example, [sqlite3_open()] ** calls sqlite3_initialize() so the SQLite library will be automatically | | | 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 | ** the library (perhaps it is unable to allocate a needed resource such ** as a mutex) it returns an [error code] other than [SQLITE_OK]. ** ** ^The sqlite3_initialize() routine is called internally by many other ** SQLite interfaces so that an application usually does not need to ** invoke sqlite3_initialize() directly. For example, [sqlite3_open()] ** calls sqlite3_initialize() so the SQLite library will be automatically ** initialized when [sqlite3_open()] is called if it has not been initialized ** already. ^However, if SQLite is compiled with the [SQLITE_OMIT_AUTOINIT] ** compile-time option, then the automatic calls to sqlite3_initialize() ** are omitted and the application must call sqlite3_initialize() directly ** prior to using any other SQLite interface. For maximum portability, ** it is recommended that applications always invoke sqlite3_initialize() ** directly prior to using any other SQLite interface. Future releases ** of SQLite may require this. In other words, the behavior exhibited |
| ︙ | ︙ | |||
2200 2201 2202 2203 2204 2205 2206 | ** ** [[SQLITE_CONFIG_GETMALLOC]] <dt>SQLITE_CONFIG_GETMALLOC</dt> ** <dd> ^(The SQLITE_CONFIG_GETMALLOC option takes a single argument which ** is a pointer to an instance of the [sqlite3_mem_methods] structure. ** The [sqlite3_mem_methods] ** structure is filled with the currently defined memory allocation routines.)^ ** This option can be used to overload the default memory allocation | | | | | | 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 | ** ** [[SQLITE_CONFIG_GETMALLOC]] <dt>SQLITE_CONFIG_GETMALLOC</dt> ** <dd> ^(The SQLITE_CONFIG_GETMALLOC option takes a single argument which ** is a pointer to an instance of the [sqlite3_mem_methods] structure. ** The [sqlite3_mem_methods] ** structure is filled with the currently defined memory allocation routines.)^ ** This option can be used to overload the default memory allocation ** routines with a wrapper that simulates memory allocation failure or ** tracks memory usage, for example. </dd> ** ** [[SQLITE_CONFIG_SMALL_MALLOC]] <dt>SQLITE_CONFIG_SMALL_MALLOC</dt> ** <dd> ^The SQLITE_CONFIG_SMALL_MALLOC option takes a single argument of ** type int, interpreted as a boolean, which if true provides a hint to ** SQLite that it should avoid large memory allocations if possible. ** SQLite will run faster if it is free to make large memory allocations, ** but some applications might prefer to run slower in exchange for ** guarantees about memory fragmentation that are possible if large ** allocations are avoided. This hint is normally off. ** </dd> ** ** [[SQLITE_CONFIG_MEMSTATUS]] <dt>SQLITE_CONFIG_MEMSTATUS</dt> ** <dd> ^The SQLITE_CONFIG_MEMSTATUS option takes a single argument of type int, ** interpreted as a boolean, which enables or disables the collection of ** memory allocation statistics. ^(When memory allocation statistics are ** disabled, the following SQLite interfaces become non-operational: ** <ul> ** <li> [sqlite3_hard_heap_limit64()] ** <li> [sqlite3_memory_used()] ** <li> [sqlite3_memory_highwater()] |
| ︙ | ︙ | |||
2259 2260 2261 2262 2263 2264 2265 | ** ^When pMem is not NULL, SQLite will strive to use the memory provided ** to satisfy page cache needs, falling back to [sqlite3_malloc()] if ** a page cache line is larger than sz bytes or if all of the pMem buffer ** is exhausted. ** ^If pMem is NULL and N is non-zero, then each database connection ** does an initial bulk allocation for page cache memory ** from [sqlite3_malloc()] sufficient for N cache lines if N is positive or | | | 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 | ** ^When pMem is not NULL, SQLite will strive to use the memory provided ** to satisfy page cache needs, falling back to [sqlite3_malloc()] if ** a page cache line is larger than sz bytes or if all of the pMem buffer ** is exhausted. ** ^If pMem is NULL and N is non-zero, then each database connection ** does an initial bulk allocation for page cache memory ** from [sqlite3_malloc()] sufficient for N cache lines if N is positive or ** of -1024*N bytes if N is negative. ^If additional ** page cache memory is needed beyond what is provided by the initial ** allocation, then SQLite goes to [sqlite3_malloc()] separately for each ** additional cache line. </dd> ** ** [[SQLITE_CONFIG_HEAP]] <dt>SQLITE_CONFIG_HEAP</dt> ** <dd> ^The SQLITE_CONFIG_HEAP option specifies a static memory buffer ** that SQLite will use for all of its dynamic memory allocation needs |
| ︙ | ︙ | |||
2288 2289 2290 2291 2292 2293 2294 | ** The minimum allocation size is capped at 2**12. Reasonable values ** for the minimum allocation size are 2**5 through 2**8.</dd> ** ** [[SQLITE_CONFIG_MUTEX]] <dt>SQLITE_CONFIG_MUTEX</dt> ** <dd> ^(The SQLITE_CONFIG_MUTEX option takes a single argument which is a ** pointer to an instance of the [sqlite3_mutex_methods] structure. ** The argument specifies alternative low-level mutex routines to be used | | | 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 | ** The minimum allocation size is capped at 2**12. Reasonable values ** for the minimum allocation size are 2**5 through 2**8.</dd> ** ** [[SQLITE_CONFIG_MUTEX]] <dt>SQLITE_CONFIG_MUTEX</dt> ** <dd> ^(The SQLITE_CONFIG_MUTEX option takes a single argument which is a ** pointer to an instance of the [sqlite3_mutex_methods] structure. ** The argument specifies alternative low-level mutex routines to be used ** in place of the mutex routines built into SQLite.)^ ^SQLite makes a copy of ** the content of the [sqlite3_mutex_methods] structure before the call to ** [sqlite3_config()] returns. ^If SQLite is compiled with ** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then ** the entire mutexing subsystem is omitted from the build and hence calls to ** [sqlite3_config()] with the SQLITE_CONFIG_MUTEX configuration option will ** return [SQLITE_ERROR].</dd> ** |
| ︙ | ︙ | |||
2330 2331 2332 2333 2334 2335 2336 | ** <dd> ^(The SQLITE_CONFIG_PCACHE2 option takes a single argument which is ** a pointer to an [sqlite3_pcache_methods2] object. This object specifies ** the interface to a custom page cache implementation.)^ ** ^SQLite makes a copy of the [sqlite3_pcache_methods2] object.</dd> ** ** [[SQLITE_CONFIG_GETPCACHE2]] <dt>SQLITE_CONFIG_GETPCACHE2</dt> ** <dd> ^(The SQLITE_CONFIG_GETPCACHE2 option takes a single argument which | | | | 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 | ** <dd> ^(The SQLITE_CONFIG_PCACHE2 option takes a single argument which is ** a pointer to an [sqlite3_pcache_methods2] object. This object specifies ** the interface to a custom page cache implementation.)^ ** ^SQLite makes a copy of the [sqlite3_pcache_methods2] object.</dd> ** ** [[SQLITE_CONFIG_GETPCACHE2]] <dt>SQLITE_CONFIG_GETPCACHE2</dt> ** <dd> ^(The SQLITE_CONFIG_GETPCACHE2 option takes a single argument which ** is a pointer to an [sqlite3_pcache_methods2] object. SQLite copies off ** the current page cache implementation into that object.)^ </dd> ** ** [[SQLITE_CONFIG_LOG]] <dt>SQLITE_CONFIG_LOG</dt> ** <dd> The SQLITE_CONFIG_LOG option is used to configure the SQLite ** global [error log]. ** (^The SQLITE_CONFIG_LOG option takes two arguments: a pointer to a ** function with a call signature of void(*)(void*,int,const char*), ** and a pointer to void. ^If the function pointer is not NULL, it is ** invoked by [sqlite3_log()] to process each logging event. ^If the ** function pointer is NULL, the [sqlite3_log()] interface becomes a no-op. ** ^The void pointer that is the second argument to SQLITE_CONFIG_LOG is ** passed through as the first parameter to the application-defined logger ** function whenever that function is invoked. ^The second parameter to ** the logger function is a copy of the first parameter to the corresponding ** [sqlite3_log()] call and is intended to be a [result code] or an ** [extended result code]. ^The third parameter passed to the logger is ** a 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> ** ** [[SQLITE_CONFIG_URI]] <dt>SQLITE_CONFIG_URI ** <dd>^(The SQLITE_CONFIG_URI option takes a single argument of type int. |
| ︙ | ︙ | |||
2538 2539 2540 2541 2542 2543 2544 | /* ** CAPI3REF: Database Connection Configuration Options ** ** These constants are the available integer configuration options that ** can be passed as the second parameter to the [sqlite3_db_config()] interface. ** | | | 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 | /* ** CAPI3REF: Database Connection Configuration Options ** ** These constants are the available integer configuration options that ** can be passed as the second parameter to the [sqlite3_db_config()] interface. ** ** The [sqlite3_db_config()] interface is a var-args function. It takes a ** variable number of parameters, though always at least two. The number of ** parameters passed into sqlite3_db_config() depends on which of these ** constants is given as the second parameter. This documentation page ** refers to parameters beyond the second as "arguments". Thus, when this ** page says "the N-th argument" it means "the N-th parameter past the ** configuration option" or "the (N+2)-th parameter to sqlite3_db_config()". ** |
| ︙ | ︙ | |||
2672 2673 2674 2675 2676 2677 2678 | ** interface independently of the [load_extension()] SQL function. ** The [sqlite3_enable_load_extension()] API enables or disables both the ** C-API [sqlite3_load_extension()] and the SQL function [load_extension()]. ** There must be two additional arguments. ** When the first argument to this interface is 1, then only the C-API is ** enabled and the SQL function remains disabled. If the first argument to ** this interface is 0, then both the C-API and the SQL function are disabled. | | | | 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 | ** interface independently of the [load_extension()] SQL function. ** The [sqlite3_enable_load_extension()] API enables or disables both the ** C-API [sqlite3_load_extension()] and the SQL function [load_extension()]. ** There must be two additional arguments. ** When the first argument to this interface is 1, then only the C-API is ** enabled and the SQL function remains disabled. If the first argument to ** this interface is 0, then both the C-API and the SQL function are disabled. ** If the first argument is -1, then no changes are made to the state of either ** the C-API or the SQL function. ** The second parameter is a pointer to an integer into which ** is written 0 or 1 to indicate whether [sqlite3_load_extension()] interface ** is disabled or enabled following this call. The second parameter may ** be a NULL pointer, in which case the new setting is not reported back. ** </dd> ** ** [[SQLITE_DBCONFIG_MAINDBNAME]] <dt>SQLITE_DBCONFIG_MAINDBNAME</dt> |
| ︙ | ︙ | |||
2791 2792 2793 2794 2795 2796 2797 | ** integer into which is written 0 or 1 to indicate whether the writable_schema ** is enabled or disabled following this call. ** </dd> ** ** [[SQLITE_DBCONFIG_LEGACY_ALTER_TABLE]] ** <dt>SQLITE_DBCONFIG_LEGACY_ALTER_TABLE</dt> ** <dd>The SQLITE_DBCONFIG_LEGACY_ALTER_TABLE option activates or deactivates | | | 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 | ** integer into which is written 0 or 1 to indicate whether the writable_schema ** is enabled or disabled following this call. ** </dd> ** ** [[SQLITE_DBCONFIG_LEGACY_ALTER_TABLE]] ** <dt>SQLITE_DBCONFIG_LEGACY_ALTER_TABLE</dt> ** <dd>The SQLITE_DBCONFIG_LEGACY_ALTER_TABLE option activates or deactivates ** the legacy behavior of the [ALTER TABLE RENAME] command such that it ** behaves as it did prior to [version 3.24.0] (2018-06-04). See the ** "Compatibility Notice" on the [ALTER TABLE RENAME documentation] for ** additional information. This feature can also be turned on and off ** using the [PRAGMA legacy_alter_table] statement. ** </dd> ** ** [[SQLITE_DBCONFIG_DQS_DML]] |
| ︙ | ︙ | |||
2840 2841 2842 2843 2844 2845 2846 | ** can also be controlled using the [PRAGMA trusted_schema] statement. ** </dd> ** ** [[SQLITE_DBCONFIG_LEGACY_FILE_FORMAT]] ** <dt>SQLITE_DBCONFIG_LEGACY_FILE_FORMAT</dt> ** <dd>The SQLITE_DBCONFIG_LEGACY_FILE_FORMAT option activates or deactivates ** the legacy file format flag. When activated, this flag causes all newly | | | 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 | ** can also be controlled using the [PRAGMA trusted_schema] statement. ** </dd> ** ** [[SQLITE_DBCONFIG_LEGACY_FILE_FORMAT]] ** <dt>SQLITE_DBCONFIG_LEGACY_FILE_FORMAT</dt> ** <dd>The SQLITE_DBCONFIG_LEGACY_FILE_FORMAT option activates or deactivates ** the legacy file format flag. When activated, this flag causes all newly ** created database files to have a schema format version number (the 4-byte ** integer found at offset 44 into the database header) of 1. This in turn ** means that the resulting database file will be readable and writable by ** any SQLite version back to 3.0.0 ([dateof:3.0.0]). Without this setting, ** newly created databases are generally not understandable by SQLite versions ** prior to 3.3.0 ([dateof:3.3.0]). As these words are written, there ** is now scarcely any need to generate database files that are compatible ** all the way back to version 3.0.0, and so this setting is of little |
| ︙ | ︙ | |||
2867 2868 2869 2870 2871 2872 2873 | ** <dd>The SQLITE_DBCONFIG_STMT_SCANSTATUS option is only useful in ** SQLITE_ENABLE_STMT_SCANSTATUS builds. In this case, it sets or clears ** a flag that enables collection of the sqlite3_stmt_scanstatus_v2() ** statistics. For statistics to be collected, the flag must be set on ** the database handle both when the SQL statement is prepared and when it ** is stepped. The flag is set (collection of statistics is enabled) ** by default. <p>This option takes two arguments: an integer and a pointer to | | | 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 | ** <dd>The SQLITE_DBCONFIG_STMT_SCANSTATUS option is only useful in ** SQLITE_ENABLE_STMT_SCANSTATUS builds. In this case, it sets or clears ** a flag that enables collection of the sqlite3_stmt_scanstatus_v2() ** statistics. For statistics to be collected, the flag must be set on ** the database handle both when the SQL statement is prepared and when it ** is stepped. The flag is set (collection of statistics is enabled) ** by default. <p>This option takes two arguments: an integer and a pointer to ** an integer. The first argument is 1, 0, or -1 to enable, disable, or ** leave unchanged the statement scanstatus option. If the second argument ** is not NULL, then the value of the statement scanstatus setting after ** processing the first argument is written into the integer that the second ** argument points to. ** </dd> ** ** [[SQLITE_DBCONFIG_REVERSE_SCANORDER]] |
| ︙ | ︙ | |||
2910 2911 2912 2913 2914 2915 2916 | ** </dd> ** ** [[SQLITE_DBCONFIG_ENABLE_ATTACH_WRITE]] ** <dt>SQLITE_DBCONFIG_ENABLE_ATTACH_WRITE</dt> ** <dd>The SQLITE_DBCONFIG_ENABLE_ATTACH_WRITE option enables or disables the ** ability of the [ATTACH DATABASE] SQL command to open a database for writing. ** This capability is enabled by default. Applications can disable or | | | | 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 | ** </dd> ** ** [[SQLITE_DBCONFIG_ENABLE_ATTACH_WRITE]] ** <dt>SQLITE_DBCONFIG_ENABLE_ATTACH_WRITE</dt> ** <dd>The SQLITE_DBCONFIG_ENABLE_ATTACH_WRITE option enables or disables the ** ability of the [ATTACH DATABASE] SQL command to open a database for writing. ** This capability is enabled by default. Applications can disable or ** reenable this capability using the current DBCONFIG option. If ** this capability is disabled, the [ATTACH] command will still work, ** but the database will be opened read-only. If this option is disabled, ** then the ability to create a new database using [ATTACH] is also disabled, ** regardless of the value of the [SQLITE_DBCONFIG_ENABLE_ATTACH_CREATE] ** option.<p> ** This option takes two arguments which are an integer and a pointer ** to an integer. The first argument is 1, 0, or -1 to enable, disable, or ** leave unchanged the ability to ATTACH another database for writing, |
| ︙ | ︙ | |||
2945 2946 2947 2948 2949 2950 2951 | ** ** </dl> ** ** [[DBCONFIG arguments]] <h3>Arguments To SQLITE_DBCONFIG Options</h3> ** ** <p>Most of the SQLITE_DBCONFIG options take two arguments, so that the ** overall call to [sqlite3_db_config()] has a total of four parameters. | | | 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 | ** ** </dl> ** ** [[DBCONFIG arguments]] <h3>Arguments To SQLITE_DBCONFIG Options</h3> ** ** <p>Most of the SQLITE_DBCONFIG options take two arguments, so that the ** overall call to [sqlite3_db_config()] has a total of four parameters. ** The first argument (the third parameter to sqlite3_db_config()) is an integer. ** The second argument is a pointer to an integer. If the first argument is 1, ** then the option becomes enabled. If the first integer argument is 0, then the ** option is disabled. If the first argument is -1, then the option setting ** is unchanged. The second argument, the pointer to an integer, may be NULL. ** If the second argument is not NULL, then a value of 0 or 1 is written into ** the integer to which the second argument points, depending on whether the ** setting is disabled or enabled after applying any changes specified by |
| ︙ | ︙ | |||
3235 3236 3237 3238 3239 3240 3241 | ** independent tokens (they are part of the token in which they are ** embedded) and thus do not count as a statement terminator. ^Whitespace ** and comments that follow the final semicolon are ignored. ** ** ^These routines return 0 if the statement is incomplete. ^If a ** memory allocation fails, then SQLITE_NOMEM is returned. ** | | | 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 3247 3248 3249 | ** independent tokens (they are part of the token in which they are ** embedded) and thus do not count as a statement terminator. ^Whitespace ** and comments that follow the final semicolon are ignored. ** ** ^These routines return 0 if the statement is incomplete. ^If a ** memory allocation fails, then SQLITE_NOMEM is returned. ** ** ^These routines do not parse the SQL statements and thus ** will not detect syntactically incorrect SQL. ** ** ^(If SQLite has not been initialized using [sqlite3_initialize()] prior ** to invoking sqlite3_complete16() then sqlite3_initialize() is invoked ** automatically by sqlite3_complete16(). If that initialization fails, ** then the return value from sqlite3_complete16() will be non-zero ** regardless of whether or not the input SQL is complete.)^ |
| ︙ | ︙ | |||
3352 3353 3354 3355 3356 3357 3358 | ** not support blocking locks, this function is a no-op. ** ** Passing 0 to this function disables blocking locks altogether. Passing ** -1 to this function requests that the VFS blocks for a long time - ** indefinitely if possible. The results of passing any other negative value ** are undefined. ** | | | 3352 3353 3354 3355 3356 3357 3358 3359 3360 3361 3362 3363 3364 3365 3366 | ** not support blocking locks, this function is a no-op. ** ** Passing 0 to this function disables blocking locks altogether. Passing ** -1 to this function requests that the VFS blocks for a long time - ** indefinitely if possible. The results of passing any other negative value ** are undefined. ** ** Internally, each SQLite database handle stores two timeout values - the ** busy-timeout (used for rollback mode databases, or if the VFS does not ** support blocking locks) and the setlk-timeout (used for blocking locks ** on wal-mode databases). The sqlite3_busy_timeout() method sets both ** values, this function sets only the setlk-timeout value. Therefore, ** to configure separate busy-timeout and setlk-timeout values for a single ** database handle, call sqlite3_busy_timeout() followed by this function. ** |
| ︙ | ︙ | |||
3382 3383 3384 3385 3386 3387 3388 | /* ** CAPI3REF: Convenience Routines For Running Queries ** METHOD: sqlite3 ** ** This is a legacy interface that is preserved for backwards compatibility. ** Use of this interface is not recommended. ** | | | 3382 3383 3384 3385 3386 3387 3388 3389 3390 3391 3392 3393 3394 3395 3396 | /* ** CAPI3REF: Convenience Routines For Running Queries ** METHOD: sqlite3 ** ** This is a legacy interface that is preserved for backwards compatibility. ** Use of this interface is not recommended. ** ** Definition: A <b>result table</b> is a memory data structure created by the ** [sqlite3_get_table()] interface. A result table records the ** complete query results from one or more queries. ** ** The table conceptually has a number of rows and columns. But ** these numbers are not part of the result table itself. These ** numbers are obtained separately. Let N be the number of rows ** and M be the number of columns. |
| ︙ | ︙ | |||
3525 3526 3527 3528 3529 3530 3531 | ** ^The sqlite3_malloc64(N) routine works just like ** sqlite3_malloc(N) except that N is an unsigned 64-bit integer instead ** of a signed 32-bit integer. ** ** ^Calling sqlite3_free() with a pointer previously returned ** by sqlite3_malloc() or sqlite3_realloc() releases that memory so ** that it might be reused. ^The sqlite3_free() routine is | | | | | | 3525 3526 3527 3528 3529 3530 3531 3532 3533 3534 3535 3536 3537 3538 3539 3540 3541 3542 3543 3544 3545 3546 3547 3548 3549 3550 3551 3552 3553 3554 3555 3556 3557 3558 3559 3560 3561 3562 3563 | ** ^The sqlite3_malloc64(N) routine works just like ** sqlite3_malloc(N) except that N is an unsigned 64-bit integer instead ** of a signed 32-bit integer. ** ** ^Calling sqlite3_free() with a pointer previously returned ** by sqlite3_malloc() or sqlite3_realloc() releases that memory so ** that it might be reused. ^The sqlite3_free() routine is ** a no-op if it is called with a NULL pointer. Passing a NULL pointer ** to sqlite3_free() is harmless. After being freed, memory ** should neither be read nor written. Even reading previously freed ** memory might result in a segmentation fault or other severe error. ** Memory corruption, a segmentation fault, or other severe error ** might result if sqlite3_free() is called with a non-NULL pointer that ** was not obtained from sqlite3_malloc() or sqlite3_realloc(). ** ** ^The sqlite3_realloc(X,N) interface attempts to resize a ** prior memory allocation X to be at least N bytes. ** ^If the X parameter to sqlite3_realloc(X,N) ** is a NULL pointer then its behavior is identical to calling ** sqlite3_malloc(N). ** ^If the N parameter to sqlite3_realloc(X,N) is zero or ** negative then the behavior is exactly the same as calling ** sqlite3_free(X). ** ^sqlite3_realloc(X,N) returns a pointer to a memory allocation ** of at least N bytes in size or NULL if insufficient memory is available. ** ^If M is the size of the prior allocation, then min(N,M) bytes of the ** prior allocation are copied into the beginning of the buffer returned ** by sqlite3_realloc(X,N) and the prior allocation is freed. ** ^If sqlite3_realloc(X,N) returns NULL and N is positive, then the ** prior allocation is not freed. ** ** ^The sqlite3_realloc64(X,N) interface works the same as ** sqlite3_realloc(X,N) except that N is a 64-bit unsigned integer instead ** of a 32-bit signed integer. ** ** ^If X is a memory allocation previously obtained from sqlite3_malloc(), ** sqlite3_malloc64(), sqlite3_realloc(), or sqlite3_realloc64(), then ** sqlite3_msize(X) returns the size of that memory allocation in bytes. ** ^The value returned by sqlite3_msize(X) might be larger than the number |
| ︙ | ︙ | |||
3599 3600 3601 3602 3603 3604 3605 | ** ^The [sqlite3_memory_used()] routine returns the number of bytes ** of memory currently outstanding (malloced but not freed). ** ^The [sqlite3_memory_highwater()] routine returns the maximum ** value of [sqlite3_memory_used()] since the high-water mark ** was last reset. ^The values returned by [sqlite3_memory_used()] and ** [sqlite3_memory_highwater()] include any overhead ** added by SQLite in its implementation of [sqlite3_malloc()], | | | 3599 3600 3601 3602 3603 3604 3605 3606 3607 3608 3609 3610 3611 3612 3613 | ** ^The [sqlite3_memory_used()] routine returns the number of bytes ** of memory currently outstanding (malloced but not freed). ** ^The [sqlite3_memory_highwater()] routine returns the maximum ** value of [sqlite3_memory_used()] since the high-water mark ** was last reset. ^The values returned by [sqlite3_memory_used()] and ** [sqlite3_memory_highwater()] include any overhead ** added by SQLite in its implementation of [sqlite3_malloc()], ** but not overhead added by any underlying system library ** routines that [sqlite3_malloc()] may call. ** ** ^The memory high-water mark is reset to the current value of ** [sqlite3_memory_used()] if and only if the parameter to ** [sqlite3_memory_highwater()] is true. ^The value returned ** by [sqlite3_memory_highwater(1)] is the high-water mark ** prior to the reset. |
| ︙ | ︙ | |||
4051 4052 4053 4054 4055 4056 4057 | ** <dd>The new database connection will use the "serialized" ** [threading mode].)^ This means the multiple threads can safely ** attempt to use the same database connection at the same time. ** (Mutexes will block any actual concurrency, but in this mode ** there is no harm in trying.) ** ** ^(<dt>[SQLITE_OPEN_SHAREDCACHE]</dt> | | | | 4051 4052 4053 4054 4055 4056 4057 4058 4059 4060 4061 4062 4063 4064 4065 4066 4067 4068 4069 4070 4071 4072 4073 | ** <dd>The new database connection will use the "serialized" ** [threading mode].)^ This means the multiple threads can safely ** attempt to use the same database connection at the same time. ** (Mutexes will block any actual concurrency, but in this mode ** there is no harm in trying.) ** ** ^(<dt>[SQLITE_OPEN_SHAREDCACHE]</dt> ** <dd>The database is opened with [shared cache] enabled, overriding ** the default shared cache setting provided by ** [sqlite3_enable_shared_cache()].)^ ** The [use of shared cache mode is discouraged] and hence shared cache ** capabilities may be omitted from many builds of SQLite. In such cases, ** this option is a no-op. ** ** ^(<dt>[SQLITE_OPEN_PRIVATECACHE]</dt> ** <dd>The database is opened with [shared cache] disabled, overriding ** the default shared cache setting provided by ** [sqlite3_enable_shared_cache()].)^ ** ** [[OPEN_EXRESCODE]] ^(<dt>[SQLITE_OPEN_EXRESCODE]</dt> ** <dd>The database connection comes up in "extended result code mode". ** In other words, the database behaves as if ** [sqlite3_extended_result_codes(db,1)] were called on the database |
| ︙ | ︙ | |||
4394 4395 4396 4397 4398 4399 4400 | ** CAPI3REF: Create and Destroy VFS Filenames ** ** These interfaces are provided for use by [VFS shim] implementations and ** are not useful outside of that context. ** ** The sqlite3_create_filename(D,J,W,N,P) allocates memory to hold a version of ** database filename D with corresponding journal file J and WAL file W and | | | 4394 4395 4396 4397 4398 4399 4400 4401 4402 4403 4404 4405 4406 4407 4408 | ** CAPI3REF: Create and Destroy VFS Filenames ** ** These interfaces are provided for use by [VFS shim] implementations and ** are not useful outside of that context. ** ** The sqlite3_create_filename(D,J,W,N,P) allocates memory to hold a version of ** database filename D with corresponding journal file J and WAL file W and ** an array P of N URI Key/Value pairs. The result from ** sqlite3_create_filename(D,J,W,N,P) is a pointer to a database filename that ** is safe to pass to routines like: ** <ul> ** <li> [sqlite3_uri_parameter()], ** <li> [sqlite3_uri_boolean()], ** <li> [sqlite3_uri_int64()], ** <li> [sqlite3_uri_key()], |
| ︙ | ︙ | |||
4477 4478 4479 4480 4481 4482 4483 | ** (See how SQLite handles [invalid UTF] for exceptions to this rule.) ** ^(Memory to hold the error message string is managed internally. ** The application does not need to worry about freeing the result. ** However, the error string might be overwritten or deallocated by ** subsequent calls to other SQLite interface functions.)^ ** ** ^The sqlite3_errstr(E) interface returns the English-language text | | | | 4477 4478 4479 4480 4481 4482 4483 4484 4485 4486 4487 4488 4489 4490 4491 4492 4493 4494 4495 4496 4497 4498 4499 | ** (See how SQLite handles [invalid UTF] for exceptions to this rule.) ** ^(Memory to hold the error message string is managed internally. ** The application does not need to worry about freeing the result. ** However, the error string might be overwritten or deallocated by ** subsequent calls to other SQLite interface functions.)^ ** ** ^The sqlite3_errstr(E) interface returns the English-language text ** that describes the [result code] E, as UTF-8, or NULL if E is not a ** result code for which a text error message is available. ** ^(Memory to hold the error message string is managed internally ** and must not be freed by the application)^. ** ** ^If the most recent error references a specific token in the input ** SQL, the sqlite3_error_offset() interface returns the byte offset ** of the start of that token. ^The byte offset returned by ** sqlite3_error_offset() assumes that the input SQL is UTF-8. ** ^If the most recent error does not reference a specific token in the input ** SQL, then the sqlite3_error_offset() function returns -1. ** ** When the serialized [threading mode] is in use, it might be the ** case that a second error occurs on a separate thread in between ** the time of the first error and the call to these interfaces. ** When that happens, the second error will be reported since these |
| ︙ | ︙ | |||
4584 4585 4586 4587 4588 4589 4590 |
/*
** CAPI3REF: Run-Time Limit Categories
** KEYWORDS: {limit category} {*limit categories}
**
** These constants define various performance limits
** that can be lowered at run-time using [sqlite3_limit()].
| | | | 4584 4585 4586 4587 4588 4589 4590 4591 4592 4593 4594 4595 4596 4597 4598 4599 |
/*
** CAPI3REF: Run-Time Limit Categories
** KEYWORDS: {limit category} {*limit categories}
**
** These constants define various performance limits
** that can be lowered at run-time using [sqlite3_limit()].
** A concise description of these limits follows, and additional information
** is available at [limits | Limits in SQLite].
**
** <dl>
** [[SQLITE_LIMIT_LENGTH]] ^(<dt>SQLITE_LIMIT_LENGTH</dt>
** <dd>The maximum size of any string or BLOB or table row, in bytes.<dd>)^
**
** [[SQLITE_LIMIT_SQL_LENGTH]] ^(<dt>SQLITE_LIMIT_SQL_LENGTH</dt>
** <dd>The maximum length of an SQL statement, in bytes.</dd>)^
|
| ︙ | ︙ | |||
4650 4651 4652 4653 4654 4655 4656 | #define SQLITE_LIMIT_VARIABLE_NUMBER 9 #define SQLITE_LIMIT_TRIGGER_DEPTH 10 #define SQLITE_LIMIT_WORKER_THREADS 11 /* ** CAPI3REF: Prepare Flags ** | | | 4650 4651 4652 4653 4654 4655 4656 4657 4658 4659 4660 4661 4662 4663 4664 | #define SQLITE_LIMIT_VARIABLE_NUMBER 9 #define SQLITE_LIMIT_TRIGGER_DEPTH 10 #define SQLITE_LIMIT_WORKER_THREADS 11 /* ** CAPI3REF: Prepare Flags ** ** These constants define various flags that can be passed into the ** "prepFlags" parameter of the [sqlite3_prepare_v3()] and ** [sqlite3_prepare16_v3()] interfaces. ** ** New flags may be added in future releases of SQLite. ** ** <dl> ** [[SQLITE_PREPARE_PERSISTENT]] ^(<dt>SQLITE_PREPARE_PERSISTENT</dt> |
| ︙ | ︙ | |||
4737 4738 4739 4740 4741 4742 4743 | ** up to the first zero terminator or until the nByte bytes have been read, ** whichever comes first. ^If nByte is zero, then no prepared ** statement is generated. ** If the caller knows that the supplied string is nul-terminated, then ** there is a small performance advantage to passing an nByte parameter that ** is the number of bytes in the input string <i>including</i> ** the nul-terminator. | | | 4737 4738 4739 4740 4741 4742 4743 4744 4745 4746 4747 4748 4749 4750 4751 | ** up to the first zero terminator or until the nByte bytes have been read, ** whichever comes first. ^If nByte is zero, then no prepared ** statement is generated. ** If the caller knows that the supplied string is nul-terminated, then ** there is a small performance advantage to passing an nByte parameter that ** is the number of bytes in the input string <i>including</i> ** the nul-terminator. ** Note that nByte measures the length of the input in bytes, not ** characters, even for the UTF-16 interfaces. ** ** ^If pzTail is not NULL then *pzTail is made to point to the first byte ** past the end of the first SQL statement in zSql. These routines only ** compile the first statement in zSql, so *pzTail is left pointing to ** what remains uncompiled. ** |
| ︙ | ︙ | |||
4871 4872 4873 4874 4875 4876 4877 | ** text "SELECT $abc,:xyz" and if parameter $abc is bound to integer 2345 ** and parameter :xyz is unbound, then sqlite3_sql() will return ** the original string, "SELECT $abc,:xyz" but sqlite3_expanded_sql() ** will return "SELECT 2345,NULL".)^ ** ** ^The sqlite3_expanded_sql() interface returns NULL if insufficient memory ** is available to hold the result, or if the result would exceed the | | | 4871 4872 4873 4874 4875 4876 4877 4878 4879 4880 4881 4882 4883 4884 4885 | ** text "SELECT $abc,:xyz" and if parameter $abc is bound to integer 2345 ** and parameter :xyz is unbound, then sqlite3_sql() will return ** the original string, "SELECT $abc,:xyz" but sqlite3_expanded_sql() ** will return "SELECT 2345,NULL".)^ ** ** ^The sqlite3_expanded_sql() interface returns NULL if insufficient memory ** is available to hold the result, or if the result would exceed the ** maximum string length determined by the [SQLITE_LIMIT_LENGTH]. ** ** ^The [SQLITE_TRACE_SIZE_LIMIT] compile-time option limits the size of ** bound parameter expansions. ^The [SQLITE_OMIT_TRACE] compile-time ** option causes sqlite3_expanded_sql() to always return NULL. ** ** ^The strings returned by sqlite3_sql(P) and sqlite3_normalized_sql(P) ** are managed by SQLite and are automatically freed when the prepared |
| ︙ | ︙ | |||
5059 5060 5061 5062 5063 5064 5065 | typedef struct sqlite3_value sqlite3_value; /* ** CAPI3REF: SQL Function Context Object ** ** The context in which an SQL function executes is stored in an ** sqlite3_context object. ^A pointer to an sqlite3_context object | | | | 5059 5060 5061 5062 5063 5064 5065 5066 5067 5068 5069 5070 5071 5072 5073 5074 5075 5076 5077 5078 5079 5080 5081 5082 5083 5084 5085 5086 5087 5088 5089 |
typedef struct sqlite3_value sqlite3_value;
/*
** CAPI3REF: SQL Function Context Object
**
** The context in which an SQL function executes is stored in an
** sqlite3_context object. ^A pointer to an sqlite3_context object
** is always the first parameter to [application-defined SQL functions].
** The application-defined SQL function implementation will pass this
** pointer through into calls to [sqlite3_result_int | sqlite3_result()],
** [sqlite3_aggregate_context()], [sqlite3_user_data()],
** [sqlite3_context_db_handle()], [sqlite3_get_auxdata()],
** and/or [sqlite3_set_auxdata()].
*/
typedef struct sqlite3_context sqlite3_context;
/*
** CAPI3REF: Binding Values To Prepared Statements
** KEYWORDS: {host parameter} {host parameters} {host parameter name}
** KEYWORDS: {SQL parameter} {SQL parameters} {parameter binding}
** METHOD: sqlite3_stmt
**
** ^(In the SQL statement text input to [sqlite3_prepare_v2()] and its variants,
** literals may be replaced by a [parameter] that matches one of the following
** templates:
**
** <ul>
** <li> ?
** <li> ?NNN
** <li> :VVV
** <li> @VVV
|
| ︙ | ︙ | |||
5120 5121 5122 5123 5124 5125 5126 | ** ^If the third parameter to sqlite3_bind_text64() is not NULL, then ** it should be a pointer to a well-formed unicode string that is ** either UTF8 if the sixth parameter is SQLITE_UTF8, or UTF16 ** otherwise. ** ** [[byte-order determination rules]] ^The byte-order of ** UTF16 input text is determined by the byte-order mark (BOM, U+FEFF) | | | | 5120 5121 5122 5123 5124 5125 5126 5127 5128 5129 5130 5131 5132 5133 5134 5135 5136 5137 5138 5139 5140 5141 5142 5143 5144 5145 5146 5147 5148 5149 5150 5151 5152 5153 5154 | ** ^If the third parameter to sqlite3_bind_text64() is not NULL, then ** it should be a pointer to a well-formed unicode string that is ** either UTF8 if the sixth parameter is SQLITE_UTF8, or UTF16 ** otherwise. ** ** [[byte-order determination rules]] ^The byte-order of ** UTF16 input text is determined by the byte-order mark (BOM, U+FEFF) ** found in the first character, which is removed, or in the absence of a BOM ** the byte order is the native byte order of the host ** machine for sqlite3_bind_text16() or the byte order specified in ** the 6th parameter for sqlite3_bind_text64().)^ ** ^If UTF16 input text contains invalid unicode ** characters, then SQLite might change those invalid characters ** into the unicode replacement character: U+FFFD. ** ** ^(In those routines that have a fourth argument, its value is the ** number of bytes in the parameter. To be clear: the value is the ** number of <u>bytes</u> in the value, not the number of characters.)^ ** ^If the fourth parameter to sqlite3_bind_text() or sqlite3_bind_text16() ** is negative, then the length of the string is ** the number of bytes up to the first zero terminator. ** If the fourth parameter to sqlite3_bind_blob() is negative, then ** the behavior is undefined. ** If a non-negative fourth parameter is provided to sqlite3_bind_text() ** or sqlite3_bind_text16() or sqlite3_bind_text64() then ** that parameter must be the byte offset ** where the NUL terminator would occur assuming the string were NUL ** terminated. If any NUL characters occur at byte offsets less than ** the value of the fourth parameter then the resulting string value will ** contain embedded NULs. The result of expressions involving strings ** with embedded NULs is undefined. ** ** ^The fifth argument to the BLOB and string binding interfaces controls ** or indicates the lifetime of the object referenced by the third parameter. ** These three options exist: |
| ︙ | ︙ | |||
5352 5353 5354 5355 5356 5357 5358 | SQLITE_API const void *sqlite3_column_name16(sqlite3_stmt*, int N); /* ** CAPI3REF: Source Of Data In A Query Result ** METHOD: sqlite3_stmt ** ** ^These routines provide a means to determine the database, table, and | | | 5352 5353 5354 5355 5356 5357 5358 5359 5360 5361 5362 5363 5364 5365 5366 | SQLITE_API const void *sqlite3_column_name16(sqlite3_stmt*, int N); /* ** CAPI3REF: Source Of Data In A Query Result ** METHOD: sqlite3_stmt ** ** ^These routines provide a means to determine the database, table, and ** table column that is the origin of a particular result column in a ** [SELECT] statement. ** ^The name of the database or table or column can be returned as ** either a UTF-8 or UTF-16 string. ^The _database_ routines return ** the database name, the _table_ routines return the table name, and ** the origin_ routines return the column name. ** ^The returned string is valid until the [prepared statement] is destroyed ** using [sqlite3_finalize()] or until the statement is automatically |
| ︙ | ︙ | |||
5796 5797 5798 5799 5800 5801 5802 | /* ** CAPI3REF: Destroy A Prepared Statement Object ** DESTRUCTOR: sqlite3_stmt ** ** ^The sqlite3_finalize() function is called to delete a [prepared statement]. ** ^If the most recent evaluation of the statement encountered no errors | | | 5796 5797 5798 5799 5800 5801 5802 5803 5804 5805 5806 5807 5808 5809 5810 | /* ** CAPI3REF: Destroy A Prepared Statement Object ** DESTRUCTOR: sqlite3_stmt ** ** ^The sqlite3_finalize() function is called to delete a [prepared statement]. ** ^If the most recent evaluation of the statement encountered no errors ** or if the statement has never been evaluated, then sqlite3_finalize() returns ** SQLITE_OK. ^If the most recent evaluation of statement S failed, then ** sqlite3_finalize(S) returns the appropriate [error code] or ** [extended error code]. ** ** ^The sqlite3_finalize(S) routine can be called at any point during ** the life cycle of [prepared statement] S: ** before statement S is ever evaluated, after |
| ︙ | ︙ | |||
5921 5922 5923 5924 5925 5926 5927 | ** ^The fourth parameter may also optionally include the [SQLITE_DIRECTONLY] ** flag, which if present prevents the function from being invoked from ** within VIEWs, TRIGGERs, CHECK constraints, generated column expressions, ** index expressions, or the WHERE clause of partial indexes. ** ** For best security, the [SQLITE_DIRECTONLY] flag is recommended for ** all application-defined SQL functions that do not need to be | | | | 5921 5922 5923 5924 5925 5926 5927 5928 5929 5930 5931 5932 5933 5934 5935 5936 | ** ^The fourth parameter may also optionally include the [SQLITE_DIRECTONLY] ** flag, which if present prevents the function from being invoked from ** within VIEWs, TRIGGERs, CHECK constraints, generated column expressions, ** index expressions, or the WHERE clause of partial indexes. ** ** For best security, the [SQLITE_DIRECTONLY] flag is recommended for ** all application-defined SQL functions that do not need to be ** used inside of triggers, views, CHECK constraints, or other elements of ** the database schema. This flag is especially recommended for SQL ** functions that have side effects or reveal internal application state. ** Without this flag, an attacker might be able to modify the schema of ** a database file to include invocations of the function with parameters ** chosen by the attacker, which the application will then execute when ** the database file is opened and read. ** ** ^(The fifth parameter is an arbitrary pointer. The implementation of the |
| ︙ | ︙ | |||
5953 5954 5955 5956 5957 5958 5959 | ** which case a regular aggregate function is created, or must both be ** non-NULL, in which case the new function may be used as either an aggregate ** or aggregate window function. More details regarding the implementation ** of aggregate window functions are ** [user-defined window functions|available here]. ** ** ^(If the final parameter to sqlite3_create_function_v2() or | | | 5953 5954 5955 5956 5957 5958 5959 5960 5961 5962 5963 5964 5965 5966 5967 | ** which case a regular aggregate function is created, or must both be ** non-NULL, in which case the new function may be used as either an aggregate ** or aggregate window function. More details regarding the implementation ** of aggregate window functions are ** [user-defined window functions|available here]. ** ** ^(If the final parameter to sqlite3_create_function_v2() or ** sqlite3_create_window_function() is not NULL, then it is the destructor for ** the application data pointer. The destructor is invoked when the function ** is deleted, either by being overloaded or when the database connection ** closes.)^ ^The destructor is also invoked if the call to ** sqlite3_create_function_v2() fails. ^When the destructor callback is ** invoked, it is passed a single argument which is a copy of the application ** data pointer which was the fifth parameter to sqlite3_create_function_v2(). ** |
| ︙ | ︙ | |||
6028 6029 6030 6031 6032 6033 6034 | void (*xInverse)(sqlite3_context*,int,sqlite3_value**), void(*xDestroy)(void*) ); /* ** CAPI3REF: Text Encodings ** | | | 6028 6029 6030 6031 6032 6033 6034 6035 6036 6037 6038 6039 6040 6041 6042 | void (*xInverse)(sqlite3_context*,int,sqlite3_value**), void(*xDestroy)(void*) ); /* ** CAPI3REF: Text Encodings ** ** These constants define integer codes that represent the various ** text encodings supported by SQLite. */ #define SQLITE_UTF8 1 /* IMP: R-37514-35566 */ #define SQLITE_UTF16LE 2 /* IMP: R-03371-37637 */ #define SQLITE_UTF16BE 3 /* IMP: R-51971-34154 */ #define SQLITE_UTF16 4 /* Use native byte order */ #define SQLITE_ANY 5 /* Deprecated */ |
| ︙ | ︙ | |||
6120 6121 6122 6123 6124 6125 6126 | ** ** [[SQLITE_RESULT_SUBTYPE]] <dt>SQLITE_RESULT_SUBTYPE</dt><dd> ** The SQLITE_RESULT_SUBTYPE flag indicates to SQLite that a function might call ** [sqlite3_result_subtype()] to cause a sub-type to be associated with its ** result. ** Every function that invokes [sqlite3_result_subtype()] should have this ** property. If it does not, then the call to [sqlite3_result_subtype()] | | | 6120 6121 6122 6123 6124 6125 6126 6127 6128 6129 6130 6131 6132 6133 6134 | ** ** [[SQLITE_RESULT_SUBTYPE]] <dt>SQLITE_RESULT_SUBTYPE</dt><dd> ** The SQLITE_RESULT_SUBTYPE flag indicates to SQLite that a function might call ** [sqlite3_result_subtype()] to cause a sub-type to be associated with its ** result. ** Every function that invokes [sqlite3_result_subtype()] should have this ** property. If it does not, then the call to [sqlite3_result_subtype()] ** might become a no-op if the function is used as a term in an ** [expression index]. On the other hand, SQL functions that never invoke ** [sqlite3_result_subtype()] should avoid setting this property, as the ** purpose of this property is to disable certain optimizations that are ** incompatible with subtypes. ** ** [[SQLITE_SELFORDER1]] <dt>SQLITE_SELFORDER1</dt><dd> ** The SQLITE_SELFORDER1 flag indicates that the function is an aggregate |
| ︙ | ︙ | |||
6247 6248 6249 6250 6251 6252 6253 | ** then the conversion is performed. Otherwise no conversion occurs. ** The [SQLITE_INTEGER | datatype] after conversion is returned.)^ ** ** ^Within the [xUpdate] method of a [virtual table], the ** sqlite3_value_nochange(X) interface returns true if and only if ** the column corresponding to X is unchanged by the UPDATE operation ** that the xUpdate method call was invoked to implement and if | | | 6247 6248 6249 6250 6251 6252 6253 6254 6255 6256 6257 6258 6259 6260 6261 | ** then the conversion is performed. Otherwise no conversion occurs. ** The [SQLITE_INTEGER | datatype] after conversion is returned.)^ ** ** ^Within the [xUpdate] method of a [virtual table], the ** sqlite3_value_nochange(X) interface returns true if and only if ** the column corresponding to X is unchanged by the UPDATE operation ** that the xUpdate method call was invoked to implement and if ** the prior [xColumn] method call that was invoked to extract ** the value for that column returned without setting a result (probably ** because it queried [sqlite3_vtab_nochange()] and found that the column ** was unchanging). ^Within an [xUpdate] method, any value for which ** sqlite3_value_nochange(X) is true will in all other respects appear ** to be a NULL value. If sqlite3_value_nochange(X) is invoked anywhere other ** than within an [xUpdate] method call for an UPDATE statement, then ** the return value is arbitrary and meaningless. |
| ︙ | ︙ | |||
6353 6354 6355 6356 6357 6358 6359 | SQLITE_API unsigned int sqlite3_value_subtype(sqlite3_value*); /* ** CAPI3REF: Copy And Free SQL Values ** METHOD: sqlite3_value ** ** ^The sqlite3_value_dup(V) interface makes a copy of the [sqlite3_value] | | | 6353 6354 6355 6356 6357 6358 6359 6360 6361 6362 6363 6364 6365 6366 6367 | SQLITE_API unsigned int sqlite3_value_subtype(sqlite3_value*); /* ** CAPI3REF: Copy And Free SQL Values ** METHOD: sqlite3_value ** ** ^The sqlite3_value_dup(V) interface makes a copy of the [sqlite3_value] ** object V and returns a pointer to that copy. ^The [sqlite3_value] returned ** is a [protected sqlite3_value] object even if the input is not. ** ^The sqlite3_value_dup(V) interface returns NULL if V is NULL or if a ** memory allocation fails. ^If V is a [pointer value], then the result ** of sqlite3_value_dup(V) is a NULL value. ** ** ^The sqlite3_value_free(V) interface frees an [sqlite3_value] object ** previously obtained from [sqlite3_value_dup()]. ^If V is a NULL pointer |
| ︙ | ︙ | |||
6391 6392 6393 6394 6395 6396 6397 | ** first time from within xFinal().)^ ** ** ^The sqlite3_aggregate_context(C,N) routine returns a NULL pointer ** when first called if N is less than or equal to zero or if a memory ** allocation error occurs. ** ** ^(The amount of space allocated by sqlite3_aggregate_context(C,N) is | | | 6391 6392 6393 6394 6395 6396 6397 6398 6399 6400 6401 6402 6403 6404 6405 | ** first time from within xFinal().)^ ** ** ^The sqlite3_aggregate_context(C,N) routine returns a NULL pointer ** when first called if N is less than or equal to zero or if a memory ** allocation error occurs. ** ** ^(The amount of space allocated by sqlite3_aggregate_context(C,N) is ** determined by the N parameter on the first successful call. Changing the ** value of N in any subsequent call to sqlite3_aggregate_context() within ** the same aggregate function instance will not resize the memory ** allocation.)^ Within the xFinal callback, it is customary to set ** N=0 in calls to sqlite3_aggregate_context(C,N) so that no ** pointless memory allocations occur. ** ** ^SQLite automatically frees the memory allocated by |
| ︙ | ︙ | |||
6553 6554 6555 6556 6557 6558 6559 | ** There is no way to enumerate the client data pointers ** associated with a database connection. The N parameter can be thought ** of as a secret key such that only code that knows the secret key is able ** to access the associated data. ** ** Security Warning: These interfaces should not be exposed in scripting ** languages or in other circumstances where it might be possible for an | | | 6553 6554 6555 6556 6557 6558 6559 6560 6561 6562 6563 6564 6565 6566 6567 | ** There is no way to enumerate the client data pointers ** associated with a database connection. The N parameter can be thought ** of as a secret key such that only code that knows the secret key is able ** to access the associated data. ** ** Security Warning: These interfaces should not be exposed in scripting ** languages or in other circumstances where it might be possible for an ** attacker to invoke them. Any agent that can invoke these interfaces ** can probably also take control of the process. ** ** Database connection client data is only available for SQLite ** version 3.44.0 ([dateof:3.44.0]) and later. ** ** See also: [sqlite3_set_auxdata()] and [sqlite3_get_auxdata()]. */ |
| ︙ | ︙ | |||
6667 6668 6669 6670 6671 6672 6673 | ** the string length itself by searching the 2nd parameter for the first ** zero character. ** ^If the 3rd parameter to the sqlite3_result_text* interfaces ** is non-negative, then as many bytes (not characters) of the text ** pointed to by the 2nd parameter are taken as the application-defined ** function result. If the 3rd parameter is non-negative, then it ** must be the byte offset into the string where the NUL terminator would | | | 6667 6668 6669 6670 6671 6672 6673 6674 6675 6676 6677 6678 6679 6680 6681 | ** the string length itself by searching the 2nd parameter for the first ** zero character. ** ^If the 3rd parameter to the sqlite3_result_text* interfaces ** is non-negative, then as many bytes (not characters) of the text ** pointed to by the 2nd parameter are taken as the application-defined ** function result. If the 3rd parameter is non-negative, then it ** must be the byte offset into the string where the NUL terminator would ** appear if the string were NUL terminated. If any NUL characters occur ** in the string at a byte offset that is less than the value of the 3rd ** parameter, then the resulting string will contain embedded NULs and the ** result of expressions operating on strings with embedded NULs is undefined. ** ^If the 4th parameter to the sqlite3_result_text* interfaces ** or sqlite3_result_blob is a non-NULL pointer, then SQLite calls that ** function as the destructor on the text or BLOB result when it has ** finished using that result. |
| ︙ | ︙ | |||
6725 6726 6727 6728 6729 6730 6731 | ** [application-defined SQL function] using [sqlite3_value_pointer()]. ** ^If the D parameter is not NULL, then it is a pointer to a destructor ** for the P parameter. ^SQLite invokes D with P as its only argument ** when SQLite is finished with P. The T parameter should be a static ** string and preferably a string literal. The sqlite3_result_pointer() ** routine is part of the [pointer passing interface] added for SQLite 3.20.0. ** | | | 6725 6726 6727 6728 6729 6730 6731 6732 6733 6734 6735 6736 6737 6738 6739 |
** [application-defined SQL function] using [sqlite3_value_pointer()].
** ^If the D parameter is not NULL, then it is a pointer to a destructor
** for the P parameter. ^SQLite invokes D with P as its only argument
** when SQLite is finished with P. The T parameter should be a static
** string and preferably a string literal. The sqlite3_result_pointer()
** routine is part of the [pointer passing interface] added for SQLite 3.20.0.
**
** If these routines are called from within a different thread
** than the one containing the application-defined function that received
** the [sqlite3_context] pointer, the results are undefined.
*/
SQLITE_API void sqlite3_result_blob(sqlite3_context*, const void*, int, void(*)(void*));
SQLITE_API void sqlite3_result_blob64(sqlite3_context*,const void*,
sqlite3_uint64,void(*)(void*));
SQLITE_API void sqlite3_result_double(sqlite3_context*, double);
|
| ︙ | ︙ | |||
7131 7132 7133 7134 7135 7136 7137 | SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt*); /* ** CAPI3REF: Return The Schema Name For A Database Connection ** METHOD: sqlite3 ** ** ^The sqlite3_db_name(D,N) interface returns a pointer to the schema name | | | 7131 7132 7133 7134 7135 7136 7137 7138 7139 7140 7141 7142 7143 7144 7145 | SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt*); /* ** CAPI3REF: Return The Schema Name For A Database Connection ** METHOD: sqlite3 ** ** ^The sqlite3_db_name(D,N) interface returns a pointer to the schema name ** for the N-th database on database connection D, or a NULL pointer if N is ** out of range. An N value of 0 means the main database file. An N of 1 is ** the "temp" schema. Larger values of N correspond to various ATTACH-ed ** databases. ** ** Space to hold the string that is returned by sqlite3_db_name() is managed ** by SQLite itself. The string might be deallocated by any operation that ** changes the schema, including [ATTACH] or [DETACH] or calls to |
| ︙ | ︙ | |||
7226 7227 7228 7229 7230 7231 7232 | ** <dd>The SQLITE_TXN_NONE state means that no transaction is currently ** pending.</dd> ** ** [[SQLITE_TXN_READ]] <dt>SQLITE_TXN_READ</dt> ** <dd>The SQLITE_TXN_READ state means that the database is currently ** in a read transaction. Content has been read from the database file ** but nothing in the database file has changed. The transaction state | | | | 7226 7227 7228 7229 7230 7231 7232 7233 7234 7235 7236 7237 7238 7239 7240 7241 7242 7243 7244 7245 7246 7247 7248 7249 | ** <dd>The SQLITE_TXN_NONE state means that no transaction is currently ** pending.</dd> ** ** [[SQLITE_TXN_READ]] <dt>SQLITE_TXN_READ</dt> ** <dd>The SQLITE_TXN_READ state means that the database is currently ** in a read transaction. Content has been read from the database file ** but nothing in the database file has changed. The transaction state ** will be advanced to SQLITE_TXN_WRITE if any changes occur and there are ** no other conflicting concurrent write transactions. The transaction ** state will revert to SQLITE_TXN_NONE following a [ROLLBACK] or ** [COMMIT].</dd> ** ** [[SQLITE_TXN_WRITE]] <dt>SQLITE_TXN_WRITE</dt> ** <dd>The SQLITE_TXN_WRITE state means that the database is currently ** in a write transaction. Content has been written to the database file ** but has not yet committed. The transaction state will change to ** SQLITE_TXN_NONE at the next [ROLLBACK] or [COMMIT].</dd> */ #define SQLITE_TXN_NONE 0 #define SQLITE_TXN_READ 1 #define SQLITE_TXN_WRITE 2 /* ** CAPI3REF: Find the next prepared statement |
| ︙ | ︙ | |||
7516 7517 7518 7519 7520 7521 7522 | */ SQLITE_API int sqlite3_db_release_memory(sqlite3*); /* ** CAPI3REF: Impose A Limit On Heap Size ** ** These interfaces impose limits on the amount of heap memory that will be | | | 7516 7517 7518 7519 7520 7521 7522 7523 7524 7525 7526 7527 7528 7529 7530 | */ SQLITE_API int sqlite3_db_release_memory(sqlite3*); /* ** CAPI3REF: Impose A Limit On Heap Size ** ** These interfaces impose limits on the amount of heap memory that will be ** used by all database connections within a single process. ** ** ^The sqlite3_soft_heap_limit64() interface sets and/or queries the ** soft limit on the amount of heap memory that may be allocated by SQLite. ** ^SQLite strives to keep heap memory utilization below the soft heap ** limit by reducing the number of pages held in the page cache ** as heap memory usages approaches the limit. ** ^The soft heap limit is "soft" because even though SQLite strives to stay |
| ︙ | ︙ | |||
7574 7575 7576 7577 7578 7579 7580 | ** [sqlite3_config]([SQLITE_CONFIG_PCACHE2],...). ** <li> The page cache allocates from its own memory pool supplied ** by [sqlite3_config]([SQLITE_CONFIG_PAGECACHE],...) rather than ** from the heap. ** </ul>)^ ** ** The circumstances under which SQLite will enforce the heap limits may | | | 7574 7575 7576 7577 7578 7579 7580 7581 7582 7583 7584 7585 7586 7587 7588 | ** [sqlite3_config]([SQLITE_CONFIG_PCACHE2],...). ** <li> The page cache allocates from its own memory pool supplied ** by [sqlite3_config]([SQLITE_CONFIG_PAGECACHE],...) rather than ** from the heap. ** </ul>)^ ** ** The circumstances under which SQLite will enforce the heap limits may ** change in future releases of SQLite. */ SQLITE_API sqlite3_int64 sqlite3_soft_heap_limit64(sqlite3_int64 N); SQLITE_API sqlite3_int64 sqlite3_hard_heap_limit64(sqlite3_int64 N); /* ** CAPI3REF: Deprecated Soft Heap Limit Interface ** DEPRECATED |
| ︙ | ︙ | |||
7689 7690 7691 7692 7693 7694 7695 | ** So for example, if "samplelib" cannot be loaded, then names like ** "samplelib.so" or "samplelib.dylib" or "samplelib.dll" might ** be tried also. ** ** ^The entry point is zProc. ** ^(zProc may be 0, in which case SQLite will try to come up with an ** entry point name on its own. It first tries "sqlite3_extension_init". | | | | 7689 7690 7691 7692 7693 7694 7695 7696 7697 7698 7699 7700 7701 7702 7703 7704 | ** So for example, if "samplelib" cannot be loaded, then names like ** "samplelib.so" or "samplelib.dylib" or "samplelib.dll" might ** be tried also. ** ** ^The entry point is zProc. ** ^(zProc may be 0, in which case SQLite will try to come up with an ** entry point name on its own. It first tries "sqlite3_extension_init". ** If that does not work, it constructs a name "sqlite3_X_init" where ** X consists of the lower-case equivalent of all ASCII alphabetic ** characters in the filename from the last "/" to the first following ** "." and omitting any initial "lib".)^ ** ^The sqlite3_load_extension() interface returns ** [SQLITE_OK] on success and [SQLITE_ERROR] if something goes wrong. ** ^If an error occurs and pzErrMsg is not 0, then the ** [sqlite3_load_extension()] interface shall attempt to ** fill *pzErrMsg with error message text stored in memory |
| ︙ | ︙ | |||
7761 7762 7763 7764 7765 7766 7767 | ** each new [database connection] that is created. The idea here is that ** xEntryPoint() is the entry point for a statically linked [SQLite extension] ** that is to be automatically loaded into all new database connections. ** ** ^(Even though the function prototype shows that xEntryPoint() takes ** no arguments and returns void, SQLite invokes xEntryPoint() with three ** arguments and expects an integer result as if the signature of the | | | 7761 7762 7763 7764 7765 7766 7767 7768 7769 7770 7771 7772 7773 7774 7775 | ** each new [database connection] that is created. The idea here is that ** xEntryPoint() is the entry point for a statically linked [SQLite extension] ** that is to be automatically loaded into all new database connections. ** ** ^(Even though the function prototype shows that xEntryPoint() takes ** no arguments and returns void, SQLite invokes xEntryPoint() with three ** arguments and expects an integer result as if the signature of the ** entry point were as follows: ** ** <blockquote><pre> ** int xEntryPoint( ** sqlite3 *db, ** const char **pzErrMsg, ** const struct sqlite3_api_routines *pThunk ** ); |
| ︙ | ︙ | |||
7925 7926 7927 7928 7929 7930 7931 | ** about what parameters to pass to xFilter. ^If argvIndex>0 then ** the right-hand side of the corresponding aConstraint[] is evaluated ** and becomes the argvIndex-th entry in argv. ^(If aConstraintUsage[].omit ** is true, then the constraint is assumed to be fully handled by the ** virtual table and might not be checked again by the byte code.)^ ^(The ** aConstraintUsage[].omit flag is an optimization hint. When the omit flag ** is left in its default setting of false, the constraint will always be | | | 7925 7926 7927 7928 7929 7930 7931 7932 7933 7934 7935 7936 7937 7938 7939 | ** about what parameters to pass to xFilter. ^If argvIndex>0 then ** the right-hand side of the corresponding aConstraint[] is evaluated ** and becomes the argvIndex-th entry in argv. ^(If aConstraintUsage[].omit ** is true, then the constraint is assumed to be fully handled by the ** virtual table and might not be checked again by the byte code.)^ ^(The ** aConstraintUsage[].omit flag is an optimization hint. When the omit flag ** is left in its default setting of false, the constraint will always be ** checked separately in byte code. If the omit flag is changed to true, then ** the constraint may or may not be checked in byte code. In other words, ** when the omit flag is true there is no guarantee that the constraint will ** not be checked again using byte code.)^ ** ** ^The idxNum and idxStr values are recorded and passed into the ** [xFilter] method. ** ^[sqlite3_free()] is used to free idxStr if and only if |
| ︙ | ︙ | |||
7951 7952 7953 7954 7955 7956 7957 | ** ** ^The estimatedRows value is an estimate of the number of rows that ** will be returned by the strategy. ** ** The xBestIndex method may optionally populate the idxFlags field with a ** mask of SQLITE_INDEX_SCAN_* flags. One such flag is ** [SQLITE_INDEX_SCAN_HEX], which if set causes the [EXPLAIN QUERY PLAN] | | | 7951 7952 7953 7954 7955 7956 7957 7958 7959 7960 7961 7962 7963 7964 7965 | ** ** ^The estimatedRows value is an estimate of the number of rows that ** will be returned by the strategy. ** ** The xBestIndex method may optionally populate the idxFlags field with a ** mask of SQLITE_INDEX_SCAN_* flags. One such flag is ** [SQLITE_INDEX_SCAN_HEX], which if set causes the [EXPLAIN QUERY PLAN] ** output to show the idxNum as hex instead of as decimal. Another flag is ** SQLITE_INDEX_SCAN_UNIQUE, which if set indicates that the query plan will ** return at most one row. ** ** Additionally, if xBestIndex sets the SQLITE_INDEX_SCAN_UNIQUE flag, then ** SQLite also assumes that if a call to the xUpdate() method is made as ** part of the same statement to delete or update a virtual table row and the ** implementation returns SQLITE_CONSTRAINT, then there is no need to rollback |
| ︙ | ︙ | |||
8092 8093 8094 8095 8096 8097 8098 | ** ** ^The module name is registered on the [database connection] specified ** by the first parameter. ^The name of the module is given by the ** second parameter. ^The third parameter is a pointer to ** the implementation of the [virtual table module]. ^The fourth ** parameter is an arbitrary client data pointer that is passed through ** into the [xCreate] and [xConnect] methods of the virtual table module | | | 8092 8093 8094 8095 8096 8097 8098 8099 8100 8101 8102 8103 8104 8105 8106 | ** ** ^The module name is registered on the [database connection] specified ** by the first parameter. ^The name of the module is given by the ** second parameter. ^The third parameter is a pointer to ** the implementation of the [virtual table module]. ^The fourth ** parameter is an arbitrary client data pointer that is passed through ** into the [xCreate] and [xConnect] methods of the virtual table module ** when a new virtual table is being created or reinitialized. ** ** ^The sqlite3_create_module_v2() interface has a fifth parameter which ** is a pointer to a destructor for the pClientData. ^SQLite will ** invoke the destructor function (if it is not NULL) when SQLite ** no longer needs the pClientData pointer. ^The destructor will also ** be invoked if the call to sqlite3_create_module_v2() fails. ** ^The sqlite3_create_module() |
| ︙ | ︙ | |||
8257 8258 8259 8260 8261 8262 8263 | ** and write access. ^If the flags parameter is zero, the BLOB is opened for ** read-only access. ** ** ^(On success, [SQLITE_OK] is returned and the new [BLOB handle] is stored ** in *ppBlob. Otherwise an [error code] is returned and, unless the error ** code is SQLITE_MISUSE, *ppBlob is set to NULL.)^ ^This means that, provided ** the API is not misused, it is always safe to call [sqlite3_blob_close()] | | | 8257 8258 8259 8260 8261 8262 8263 8264 8265 8266 8267 8268 8269 8270 8271 | ** and write access. ^If the flags parameter is zero, the BLOB is opened for ** read-only access. ** ** ^(On success, [SQLITE_OK] is returned and the new [BLOB handle] is stored ** in *ppBlob. Otherwise an [error code] is returned and, unless the error ** code is SQLITE_MISUSE, *ppBlob is set to NULL.)^ ^This means that, provided ** the API is not misused, it is always safe to call [sqlite3_blob_close()] ** on *ppBlob after this function returns. ** ** This function fails with SQLITE_ERROR if any of the following are true: ** <ul> ** <li> ^(Database zDb does not exist)^, ** <li> ^(Table zTable does not exist within database zDb)^, ** <li> ^(Table zTable is a WITHOUT ROWID table)^, ** <li> ^(Column zColumn does not exist)^, |
| ︙ | ︙ | |||
8377 8378 8379 8380 8381 8382 8383 | /* ** CAPI3REF: Return The Size Of An Open BLOB ** METHOD: sqlite3_blob ** ** ^Returns the size in bytes of the BLOB accessible via the ** successfully opened [BLOB handle] in its only argument. ^The | | | 8377 8378 8379 8380 8381 8382 8383 8384 8385 8386 8387 8388 8389 8390 8391 | /* ** CAPI3REF: Return The Size Of An Open BLOB ** METHOD: sqlite3_blob ** ** ^Returns the size in bytes of the BLOB accessible via the ** successfully opened [BLOB handle] in its only argument. ^The ** incremental blob I/O routines can only read or overwrite existing ** blob content; they cannot change the size of a blob. ** ** This routine only works on a [BLOB handle] which has been created ** by a prior successful call to [sqlite3_blob_open()] and which has not ** been closed by [sqlite3_blob_close()]. Passing any other pointer in ** to this routine results in undefined and probably undesirable behavior. */ |
| ︙ | ︙ | |||
8527 8528 8529 8530 8531 8532 8533 | ** [SQLITE_CONFIG_MUTEX] option of the sqlite3_config() function ** before calling sqlite3_initialize() or any other public sqlite3_ ** function that calls sqlite3_initialize(). ** ** ^The sqlite3_mutex_alloc() routine allocates a new ** mutex and returns a pointer to it. ^The sqlite3_mutex_alloc() ** routine returns NULL if it is unable to allocate the requested | | | 8527 8528 8529 8530 8531 8532 8533 8534 8535 8536 8537 8538 8539 8540 8541 | ** [SQLITE_CONFIG_MUTEX] option of the sqlite3_config() function ** before calling sqlite3_initialize() or any other public sqlite3_ ** function that calls sqlite3_initialize(). ** ** ^The sqlite3_mutex_alloc() routine allocates a new ** mutex and returns a pointer to it. ^The sqlite3_mutex_alloc() ** routine returns NULL if it is unable to allocate the requested ** mutex. The argument to sqlite3_mutex_alloc() must be one of these ** integer constants: ** ** <ul> ** <li> SQLITE_MUTEX_FAST ** <li> SQLITE_MUTEX_RECURSIVE ** <li> SQLITE_MUTEX_STATIC_MAIN ** <li> SQLITE_MUTEX_STATIC_MEM |
| ︙ | ︙ | |||
8760 8761 8762 8763 8764 8765 8766 | #define SQLITE_MUTEX_STATIC_MASTER 2 /* ** CAPI3REF: Retrieve the mutex for a database connection ** METHOD: sqlite3 ** | | | 8760 8761 8762 8763 8764 8765 8766 8767 8768 8769 8770 8771 8772 8773 8774 | #define SQLITE_MUTEX_STATIC_MASTER 2 /* ** CAPI3REF: Retrieve the mutex for a database connection ** METHOD: sqlite3 ** ** ^This interface returns a pointer to the [sqlite3_mutex] object that ** serializes access to the [database connection] given in the argument ** when the [threading mode] is Serialized. ** ^If the [threading mode] is Single-thread or Multi-thread then this ** routine returns a NULL pointer. */ SQLITE_API sqlite3_mutex *sqlite3_db_mutex(sqlite3*); |
| ︙ | ︙ | |||
8883 8884 8885 8886 8887 8888 8889 | #define SQLITE_TESTCTRL_USELONGDOUBLE 34 /* NOT USED */ #define SQLITE_TESTCTRL_LAST 34 /* Largest TESTCTRL */ /* ** CAPI3REF: SQL Keyword Checking ** ** These routines provide access to the set of SQL language keywords | | | 8883 8884 8885 8886 8887 8888 8889 8890 8891 8892 8893 8894 8895 8896 8897 | #define SQLITE_TESTCTRL_USELONGDOUBLE 34 /* NOT USED */ #define SQLITE_TESTCTRL_LAST 34 /* Largest TESTCTRL */ /* ** CAPI3REF: SQL Keyword Checking ** ** These routines provide access to the set of SQL language keywords ** recognized by SQLite. Applications can use these routines to determine ** whether or not a specific identifier needs to be escaped (for example, ** by enclosing in double-quotes) so as not to confuse the parser. ** ** The sqlite3_keyword_count() interface returns the number of distinct ** keywords understood by SQLite. ** ** The sqlite3_keyword_name(N,Z,L) interface finds the 0-based N-th keyword and |
| ︙ | ︙ | |||
9051 9052 9053 9054 9055 9056 9057 | ** ^The length returned by [sqlite3_str_length(X)] does not include the ** zero-termination byte. ** ** ^The [sqlite3_str_value(X)] method returns a pointer to the current ** content of the dynamic string under construction in X. The value ** returned by [sqlite3_str_value(X)] is managed by the sqlite3_str object X ** and might be freed or altered by any subsequent method on the same | | | 9051 9052 9053 9054 9055 9056 9057 9058 9059 9060 9061 9062 9063 9064 9065 | ** ^The length returned by [sqlite3_str_length(X)] does not include the ** zero-termination byte. ** ** ^The [sqlite3_str_value(X)] method returns a pointer to the current ** content of the dynamic string under construction in X. The value ** returned by [sqlite3_str_value(X)] is managed by the sqlite3_str object X ** and might be freed or altered by any subsequent method on the same ** [sqlite3_str] object. Applications must not use the pointer returned by ** [sqlite3_str_value(X)] after any subsequent method call on the same ** object. ^Applications may change the content of the string returned ** by [sqlite3_str_value(X)] as long as they do not write into any bytes ** outside the range of 0 to [sqlite3_str_length(X)] and do not read or ** write any byte after any subsequent sqlite3_str method call. */ SQLITE_API int sqlite3_str_errcode(sqlite3_str*); |
| ︙ | ︙ | |||
9137 9138 9139 9140 9141 9142 9143 | ** ** [[SQLITE_STATUS_PAGECACHE_OVERFLOW]] ** ^(<dt>SQLITE_STATUS_PAGECACHE_OVERFLOW</dt> ** <dd>This parameter returns the number of bytes of page cache ** allocation which could not be satisfied by the [SQLITE_CONFIG_PAGECACHE] ** buffer and where forced to overflow to [sqlite3_malloc()]. The ** returned value includes allocations that overflowed because they | | | 9137 9138 9139 9140 9141 9142 9143 9144 9145 9146 9147 9148 9149 9150 9151 | ** ** [[SQLITE_STATUS_PAGECACHE_OVERFLOW]] ** ^(<dt>SQLITE_STATUS_PAGECACHE_OVERFLOW</dt> ** <dd>This parameter returns the number of bytes of page cache ** allocation which could not be satisfied by the [SQLITE_CONFIG_PAGECACHE] ** buffer and where forced to overflow to [sqlite3_malloc()]. The ** returned value includes allocations that overflowed because they ** were too large (they were larger than the "sz" parameter to ** [SQLITE_CONFIG_PAGECACHE]) and allocations that overflowed because ** no space was left in the page cache.</dd>)^ ** ** [[SQLITE_STATUS_PAGECACHE_SIZE]] ^(<dt>SQLITE_STATUS_PAGECACHE_SIZE</dt> ** <dd>This parameter records the largest memory allocation request ** handed to the [pagecache memory allocator]. Only the value returned in the ** *pHighwater parameter to [sqlite3_status()] is of interest. |
| ︙ | ︙ | |||
9221 9222 9223 9224 9225 9226 9227 | ** [[SQLITE_DBSTATUS_LOOKASIDE_USED]] ^(<dt>SQLITE_DBSTATUS_LOOKASIDE_USED</dt> ** <dd>This parameter returns the number of lookaside memory slots currently ** checked out.</dd>)^ ** ** [[SQLITE_DBSTATUS_LOOKASIDE_HIT]] ^(<dt>SQLITE_DBSTATUS_LOOKASIDE_HIT</dt> ** <dd>This parameter returns the number of malloc attempts that were ** satisfied using lookaside memory. Only the high-water value is meaningful; | | | | | | > | | > | 9221 9222 9223 9224 9225 9226 9227 9228 9229 9230 9231 9232 9233 9234 9235 9236 9237 9238 9239 9240 9241 9242 9243 9244 9245 9246 9247 9248 9249 9250 9251 9252 9253 9254 9255 9256 9257 9258 9259 9260 9261 9262 9263 9264 9265 9266 9267 9268 9269 9270 9271 9272 9273 9274 9275 9276 9277 9278 9279 | ** [[SQLITE_DBSTATUS_LOOKASIDE_USED]] ^(<dt>SQLITE_DBSTATUS_LOOKASIDE_USED</dt> ** <dd>This parameter returns the number of lookaside memory slots currently ** checked out.</dd>)^ ** ** [[SQLITE_DBSTATUS_LOOKASIDE_HIT]] ^(<dt>SQLITE_DBSTATUS_LOOKASIDE_HIT</dt> ** <dd>This parameter returns the number of malloc attempts that were ** satisfied using lookaside memory. Only the high-water value is meaningful; ** the current value is always zero.</dd>)^ ** ** [[SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE]] ** ^(<dt>SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE</dt> ** <dd>This parameter returns the number of malloc attempts that might have ** been satisfied using lookaside memory but failed due to the amount of ** memory requested being larger than the lookaside slot size. ** Only the high-water value is meaningful; ** the current value is always zero.</dd>)^ ** ** [[SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL]] ** ^(<dt>SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL</dt> ** <dd>This parameter returns the number of malloc attempts that might have ** been satisfied using lookaside memory but failed due to all lookaside ** memory already being in use. ** Only the high-water value is meaningful; ** the current value is always zero.</dd>)^ ** ** [[SQLITE_DBSTATUS_CACHE_USED]] ^(<dt>SQLITE_DBSTATUS_CACHE_USED</dt> ** <dd>This parameter returns the approximate number of bytes of heap ** memory used by all pager caches associated with the database connection.)^ ** ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_USED is always 0. ** </dd> ** ** [[SQLITE_DBSTATUS_CACHE_USED_SHARED]] ** ^(<dt>SQLITE_DBSTATUS_CACHE_USED_SHARED</dt> ** <dd>This parameter is similar to DBSTATUS_CACHE_USED, except that if a ** pager cache is shared between two or more connections the bytes of heap ** memory used by that pager cache is divided evenly between the attached ** connections.)^ In other words, if none of the pager caches associated ** with the database connection are shared, this request returns the same ** value as DBSTATUS_CACHE_USED. Or, if one or more of the pager caches are ** shared, the value returned by this call will be smaller than that returned ** by DBSTATUS_CACHE_USED. ^The highwater mark associated with ** SQLITE_DBSTATUS_CACHE_USED_SHARED is always 0.</dd> ** ** [[SQLITE_DBSTATUS_SCHEMA_USED]] ^(<dt>SQLITE_DBSTATUS_SCHEMA_USED</dt> ** <dd>This parameter returns the approximate number of bytes of heap ** memory used to store the schema for all databases associated ** with the connection - main, temp, and any [ATTACH]-ed databases.)^ ** ^The full amount of memory used by the schemas is reported, even if the ** schema memory is shared with other database connections due to ** [shared cache mode] being enabled. ** ^The highwater mark associated with SQLITE_DBSTATUS_SCHEMA_USED is always 0. ** </dd> ** ** [[SQLITE_DBSTATUS_STMT_USED]] ^(<dt>SQLITE_DBSTATUS_STMT_USED</dt> ** <dd>This parameter returns the approximate number of bytes of heap ** and lookaside memory used by all prepared statements associated with ** the database connection.)^ ** ^The highwater mark associated with SQLITE_DBSTATUS_STMT_USED is always 0. ** </dd> |
| ︙ | ︙ | |||
9300 9301 9302 9303 9304 9305 9306 | ** </dd> ** ** [[SQLITE_DBSTATUS_CACHE_SPILL]] ^(<dt>SQLITE_DBSTATUS_CACHE_SPILL</dt> ** <dd>This parameter returns the number of dirty cache entries that have ** been written to disk in the middle of a transaction due to the page ** cache overflowing. Transactions are more efficient if they are written ** to disk all at once. When pages spill mid-transaction, that introduces | | | 9302 9303 9304 9305 9306 9307 9308 9309 9310 9311 9312 9313 9314 9315 9316 | ** </dd> ** ** [[SQLITE_DBSTATUS_CACHE_SPILL]] ^(<dt>SQLITE_DBSTATUS_CACHE_SPILL</dt> ** <dd>This parameter returns the number of dirty cache entries that have ** been written to disk in the middle of a transaction due to the page ** cache overflowing. Transactions are more efficient if they are written ** to disk all at once. When pages spill mid-transaction, that introduces ** additional overhead. This parameter can be used to help identify ** inefficiencies that can be resolved by increasing the cache size. ** </dd> ** ** [[SQLITE_DBSTATUS_DEFERRED_FKS]] ^(<dt>SQLITE_DBSTATUS_DEFERRED_FKS</dt> ** <dd>This parameter returns zero for the current value if and only if ** all foreign key constraints (deferred or immediate) have been ** resolved.)^ ^The highwater mark is always 0. |
| ︙ | ︙ | |||
9371 9372 9373 9374 9375 9376 9377 | ** a table as part of a full table scan. Large numbers for this counter ** may indicate opportunities for performance improvement through ** careful use of indices.</dd> ** ** [[SQLITE_STMTSTATUS_SORT]] <dt>SQLITE_STMTSTATUS_SORT</dt> ** <dd>^This is the number of sort operations that have occurred. ** A non-zero value in this counter may indicate an opportunity to | | | | | | | | 9373 9374 9375 9376 9377 9378 9379 9380 9381 9382 9383 9384 9385 9386 9387 9388 9389 9390 9391 9392 9393 9394 9395 9396 9397 9398 9399 9400 9401 9402 9403 9404 9405 9406 9407 9408 9409 9410 9411 9412 9413 9414 9415 9416 9417 9418 9419 9420 9421 9422 9423 9424 | ** a table as part of a full table scan. Large numbers for this counter ** may indicate opportunities for performance improvement through ** careful use of indices.</dd> ** ** [[SQLITE_STMTSTATUS_SORT]] <dt>SQLITE_STMTSTATUS_SORT</dt> ** <dd>^This is the number of sort operations that have occurred. ** A non-zero value in this counter may indicate an opportunity to ** improve performance through careful use of indices.</dd> ** ** [[SQLITE_STMTSTATUS_AUTOINDEX]] <dt>SQLITE_STMTSTATUS_AUTOINDEX</dt> ** <dd>^This is the number of rows inserted into transient indices that ** were created automatically in order to help joins run faster. ** A non-zero value in this counter may indicate an opportunity to ** improve performance by adding permanent indices that do not ** need to be reinitialized each time the statement is run.</dd> ** ** [[SQLITE_STMTSTATUS_VM_STEP]] <dt>SQLITE_STMTSTATUS_VM_STEP</dt> ** <dd>^This is the number of virtual machine operations executed ** by the prepared statement if that number is less than or equal ** to 2147483647. The number of virtual machine operations can be ** used as a proxy for the total work done by the prepared statement. ** If the number of virtual machine operations exceeds 2147483647 ** then the value returned by this statement status code is undefined.</dd> ** ** [[SQLITE_STMTSTATUS_REPREPARE]] <dt>SQLITE_STMTSTATUS_REPREPARE</dt> ** <dd>^This is the number of times that the prepare statement has been ** automatically regenerated due to schema changes or changes to ** [bound parameters] that might affect the query plan.</dd> ** ** [[SQLITE_STMTSTATUS_RUN]] <dt>SQLITE_STMTSTATUS_RUN</dt> ** <dd>^This is the number of times that the prepared statement has ** been run. A single "run" for the purposes of this counter is one ** or more calls to [sqlite3_step()] followed by a call to [sqlite3_reset()]. ** The counter is incremented on the first [sqlite3_step()] call of each ** cycle.</dd> ** ** [[SQLITE_STMTSTATUS_FILTER_MISS]] ** [[SQLITE_STMTSTATUS_FILTER HIT]] ** <dt>SQLITE_STMTSTATUS_FILTER_HIT<br> ** SQLITE_STMTSTATUS_FILTER_MISS</dt> ** <dd>^SQLITE_STMTSTATUS_FILTER_HIT is the number of times that a join ** step was bypassed because a Bloom filter returned not-found. The ** corresponding SQLITE_STMTSTATUS_FILTER_MISS value is the number of ** times that the Bloom filter returned a find, and thus the join step ** had to be processed as normal.</dd> ** ** [[SQLITE_STMTSTATUS_MEMUSED]] <dt>SQLITE_STMTSTATUS_MEMUSED</dt> ** <dd>^This is the approximate number of bytes of heap memory ** used to store the prepared statement. ^This value is not actually ** a counter, and so the resetFlg parameter to sqlite3_stmt_status() ** is ignored when the opcode is SQLITE_STMTSTATUS_MEMUSED. ** </dd> |
| ︙ | ︙ | |||
9513 9514 9515 9516 9517 9518 9519 | ** call to xShutdown(). ** ** [[the xCreate() page cache methods]] ** ^SQLite invokes the xCreate() method to construct a new cache instance. ** SQLite will typically create one cache instance for each open database file, ** though this is not guaranteed. ^The ** first parameter, szPage, is the size in bytes of the pages that must | | | | | | | 9515 9516 9517 9518 9519 9520 9521 9522 9523 9524 9525 9526 9527 9528 9529 9530 9531 9532 9533 9534 9535 9536 9537 9538 9539 9540 9541 9542 9543 9544 9545 9546 9547 9548 9549 | ** call to xShutdown(). ** ** [[the xCreate() page cache methods]] ** ^SQLite invokes the xCreate() method to construct a new cache instance. ** SQLite will typically create one cache instance for each open database file, ** though this is not guaranteed. ^The ** first parameter, szPage, is the size in bytes of the pages that must ** be allocated by the cache. ^szPage will always be a power of two. ^The ** second parameter szExtra is a number of bytes of extra storage ** associated with each page cache entry. ^The szExtra parameter will be ** a number less than 250. SQLite will use the ** extra szExtra bytes on each page to store metadata about the underlying ** database page on disk. The value passed into szExtra depends ** on the SQLite version, the target platform, and how SQLite was compiled. ** ^The third argument to xCreate(), bPurgeable, is true if the cache being ** created will be used to cache database pages of a file stored on disk, or ** false if it is used for an in-memory database. The cache implementation ** does not have to do anything special based upon the value of bPurgeable; ** it is purely advisory. ^On a cache where bPurgeable is false, SQLite will ** never invoke xUnpin() except to deliberately delete a page. ** ^In other words, calls to xUnpin() on a cache with bPurgeable set to ** false will always have the "discard" flag set to true. ** ^Hence, a cache created with bPurgeable set to false will ** never contain any unpinned pages. ** ** [[the xCachesize() page cache method]] ** ^(The xCachesize() method may be called at any time by SQLite to set the ** suggested maximum cache-size (number of pages stored) for the cache ** instance passed as the first argument. This is the value configured using ** the SQLite "[PRAGMA cache_size]" command.)^ As with the bPurgeable ** parameter, the implementation is not required to do anything with this ** value; it is advisory only. ** ** [[the xPagecount() page cache methods]] ** The xPagecount() method must return the number of pages currently |
| ︙ | ︙ | |||
9560 9561 9562 9563 9564 9565 9566 | ** is 1. After it has been retrieved using xFetch, the page is considered ** to be "pinned". ** ** If the requested page is already in the page cache, then the page cache ** implementation must return a pointer to the page buffer with its content ** intact. If the requested page is not already in the cache, then the ** cache implementation should use the value of the createFlag | | | | | | 9562 9563 9564 9565 9566 9567 9568 9569 9570 9571 9572 9573 9574 9575 9576 9577 9578 9579 9580 9581 9582 9583 9584 9585 9586 9587 9588 9589 9590 9591 9592 9593 9594 9595 9596 9597 9598 9599 9600 9601 9602 9603 9604 9605 9606 9607 9608 9609 9610 9611 9612 9613 9614 9615 9616 | ** is 1. After it has been retrieved using xFetch, the page is considered ** to be "pinned". ** ** If the requested page is already in the page cache, then the page cache ** implementation must return a pointer to the page buffer with its content ** intact. If the requested page is not already in the cache, then the ** cache implementation should use the value of the createFlag ** parameter to help it determine what action to take: ** ** <table border=1 width=85% align=center> ** <tr><th> createFlag <th> Behavior when page is not already in cache ** <tr><td> 0 <td> Do not allocate a new page. Return NULL. ** <tr><td> 1 <td> Allocate a new page if it is easy and convenient to do so. ** Otherwise return NULL. ** <tr><td> 2 <td> Make every effort to allocate a new page. Only return ** NULL if allocating a new page is effectively impossible. ** </table> ** ** ^(SQLite will normally invoke xFetch() with a createFlag of 0 or 1. SQLite ** will only use a createFlag of 2 after a prior call with a createFlag of 1 ** failed.)^ In between the xFetch() calls, SQLite may ** attempt to unpin one or more cache pages by spilling the content of ** pinned pages to disk and synching the operating system disk cache. ** ** [[the xUnpin() page cache method]] ** ^xUnpin() is called by SQLite with a pointer to a currently pinned page ** as its second argument. If the third parameter, discard, is non-zero, ** then the page must be evicted from the cache. ** ^If the discard parameter is ** zero, then the page may be discarded or retained at the discretion of the ** page cache implementation. ^The page cache implementation ** may choose to evict unpinned pages at any time. ** ** The cache must not perform any reference counting. A single ** call to xUnpin() unpins the page regardless of the number of prior calls ** to xFetch(). ** ** [[the xRekey() page cache methods]] ** The xRekey() method is used to change the key value associated with the ** page passed as the second argument. If the cache ** previously contains an entry associated with newKey, it must be ** discarded. ^Any prior cache entry associated with newKey is guaranteed not ** to be pinned. ** ** When SQLite calls the xTruncate() method, the cache must discard all ** existing cache entries with page numbers (keys) greater than or equal ** to the value of the iLimit parameter passed to xTruncate(). If any ** of these pages are pinned, they become implicitly unpinned, meaning that ** they can be safely discarded. ** ** [[the xDestroy() page cache method]] ** ^The xDestroy() method is used to delete a cache allocated by xCreate(). ** All resources associated with the specified cache should be freed. ^After ** calling the xDestroy() method, SQLite considers the [sqlite3_pcache*] ** handle invalid, and will not use it with any other sqlite3_pcache_methods2 |
| ︙ | ︙ | |||
9780 9781 9782 9783 9784 9785 9786 | ** lasts for the duration of the sqlite3_backup_step() call. ** ^Because the source database is not locked between calls to ** sqlite3_backup_step(), the source database may be modified mid-way ** through the backup process. ^If the source database is modified by an ** external process or via a database connection other than the one being ** used by the backup operation, then the backup will be automatically ** restarted by the next call to sqlite3_backup_step(). ^If the source | | | | 9782 9783 9784 9785 9786 9787 9788 9789 9790 9791 9792 9793 9794 9795 9796 9797 9798 9799 9800 9801 9802 9803 9804 9805 9806 9807 9808 9809 9810 9811 9812 9813 | ** lasts for the duration of the sqlite3_backup_step() call. ** ^Because the source database is not locked between calls to ** sqlite3_backup_step(), the source database may be modified mid-way ** through the backup process. ^If the source database is modified by an ** external process or via a database connection other than the one being ** used by the backup operation, then the backup will be automatically ** restarted by the next call to sqlite3_backup_step(). ^If the source ** database is modified by using the same database connection as is used ** by the backup operation, then the backup database is automatically ** updated at the same time. ** ** [[sqlite3_backup_finish()]] <b>sqlite3_backup_finish()</b> ** ** When sqlite3_backup_step() has returned [SQLITE_DONE], or when the ** application wishes to abandon the backup operation, the application ** should destroy the [sqlite3_backup] by passing it to sqlite3_backup_finish(). ** ^The sqlite3_backup_finish() interfaces releases all ** resources associated with the [sqlite3_backup] object. ** ^If sqlite3_backup_step() has not yet returned [SQLITE_DONE], then any ** active write-transaction on the destination database is rolled back. ** The [sqlite3_backup] object is invalid ** and may not be used following a call to sqlite3_backup_finish(). ** ** ^The value returned by sqlite3_backup_finish is [SQLITE_OK] if no ** sqlite3_backup_step() errors occurred, regardless of whether or not ** sqlite3_backup_step() completed. ** ^If an out-of-memory condition or IO error occurred during any prior ** sqlite3_backup_step() call on the same [sqlite3_backup] object, then ** sqlite3_backup_finish() returns the corresponding [error code]. ** ** ^A return of [SQLITE_BUSY] or [SQLITE_LOCKED] from sqlite3_backup_step() ** is not a permanent error and does not affect the return value of |
| ︙ | ︙ | |||
9899 9900 9901 9902 9903 9904 9905 | ** ^When a connection (known as the blocked connection) fails to obtain a ** shared-cache lock and SQLITE_LOCKED is returned to the caller, the ** identity of the database connection (the blocking connection) that ** has locked the required resource is stored internally. ^After an ** application receives an SQLITE_LOCKED error, it may call the ** sqlite3_unlock_notify() method with the blocked connection handle as ** the first argument to register for a callback that will be invoked | | | | 9901 9902 9903 9904 9905 9906 9907 9908 9909 9910 9911 9912 9913 9914 9915 9916 9917 9918 9919 9920 9921 9922 9923 9924 9925 9926 9927 9928 9929 9930 9931 9932 9933 9934 9935 | ** ^When a connection (known as the blocked connection) fails to obtain a ** shared-cache lock and SQLITE_LOCKED is returned to the caller, the ** identity of the database connection (the blocking connection) that ** has locked the required resource is stored internally. ^After an ** application receives an SQLITE_LOCKED error, it may call the ** sqlite3_unlock_notify() method with the blocked connection handle as ** the first argument to register for a callback that will be invoked ** when the blocking connection's current transaction is concluded. ^The ** callback is invoked from within the [sqlite3_step] or [sqlite3_close] ** call that concludes the blocking connection's transaction. ** ** ^(If sqlite3_unlock_notify() is called in a multi-threaded application, ** there is a chance that the blocking connection will have already ** concluded its transaction by the time sqlite3_unlock_notify() is invoked. ** If this happens, then the specified callback is invoked immediately, ** from within the call to sqlite3_unlock_notify().)^ ** ** ^If the blocked connection is attempting to obtain a write-lock on a ** shared-cache table, and more than one other connection currently holds ** a read-lock on the same table, then SQLite arbitrarily selects one of ** the other connections to use as the blocking connection. ** ** ^(There may be at most one unlock-notify callback registered by a ** blocked connection. If sqlite3_unlock_notify() is called when the ** blocked connection already has a registered unlock-notify callback, ** then the new callback replaces the old.)^ ^If sqlite3_unlock_notify() is ** called with a NULL pointer as its second argument, then any existing ** unlock-notify callback is canceled. ^The blocked connection's ** unlock-notify callback may also be canceled by closing the blocked ** connection using [sqlite3_close()]. ** ** The unlock-notify callback is not reentrant. If an application invokes ** any sqlite3_xxx API functions from within an unlock-notify callback, a ** crash or deadlock may be the result. ** |
| ︙ | ︙ | |||
10317 10318 10319 10320 10321 10322 10323 | ** <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 | | | 10319 10320 10321 10322 10323 10324 10325 10326 10327 10328 10329 10330 10331 10332 10333 | ** <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 user's 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 |
| ︙ | ︙ | |||
10351 10352 10353 10354 10355 10356 10357 | ** prohibits that virtual table from being used from within triggers and ** views. ** </dd> ** ** [[SQLITE_VTAB_INNOCUOUS]]<dt>SQLITE_VTAB_INNOCUOUS</dt> ** <dd>Calls of the form ** [sqlite3_vtab_config](db,SQLITE_VTAB_INNOCUOUS) from within the | | | 10353 10354 10355 10356 10357 10358 10359 10360 10361 10362 10363 10364 10365 10366 10367 | ** prohibits that virtual table from being used from within triggers and ** views. ** </dd> ** ** [[SQLITE_VTAB_INNOCUOUS]]<dt>SQLITE_VTAB_INNOCUOUS</dt> ** <dd>Calls of the form ** [sqlite3_vtab_config](db,SQLITE_VTAB_INNOCUOUS) from within the ** [xConnect] or [xCreate] methods of a [virtual table] implementation ** identify that virtual table as being safe to use from within triggers ** and views. Conceptually, the SQLITE_VTAB_INNOCUOUS tag means that the ** virtual table can do no serious harm even if it is controlled by a ** malicious hacker. Developers should avoid setting the SQLITE_VTAB_INNOCUOUS ** flag unless absolutely necessary. ** </dd> ** |
| ︙ | ︙ | |||
10519 10520 10521 10522 10523 10524 10525 | ** <tr><td>0<td>yes<td>yes<td>no ** <tr><td>1<td>no<td>yes<td>no ** <tr><td>2<td>no<td>yes<td>yes ** <tr><td>3<td>yes<td>yes<td>yes ** </table> ** ** ^For the purposes of comparing virtual table output values to see if the | | | | 10521 10522 10523 10524 10525 10526 10527 10528 10529 10530 10531 10532 10533 10534 10535 10536 10537 10538 10539 10540 10541 10542 10543 10544 10545 | ** <tr><td>0<td>yes<td>yes<td>no ** <tr><td>1<td>no<td>yes<td>no ** <tr><td>2<td>no<td>yes<td>yes ** <tr><td>3<td>yes<td>yes<td>yes ** </table> ** ** ^For the purposes of comparing virtual table output values to see if the ** values are the same value for sorting purposes, two NULL values are considered ** to be the same. In other words, the comparison operator is "IS" ** (or "IS NOT DISTINCT FROM") and not "==". ** ** If a virtual table implementation is unable to meet the requirements ** specified above, then it must not set the "orderByConsumed" flag in the ** [sqlite3_index_info] object or an incorrect answer may result. ** ** ^A virtual table implementation is always free to return rows in any order ** it wants, as long as the "orderByConsumed" flag is not set. ^When the ** "orderByConsumed" flag is unset, the query planner will add extra ** [bytecode] to ensure that the final results returned by the SQL query are ** ordered correctly. The use of the "orderByConsumed" flag and the ** sqlite3_vtab_distinct() interface is merely an optimization. ^Careful ** use of the sqlite3_vtab_distinct() interface and the "orderByConsumed" ** flag might help queries against a virtual table to run faster. Being ** overly aggressive and setting the "orderByConsumed" flag when it is not ** valid to do so, on the other hand, might cause SQLite to return incorrect |
| ︙ | ︙ | |||
10626 10627 10628 10629 10630 10631 10632 | ** The result of invoking these interfaces from any other context ** is undefined and probably harmful. ** ** The X parameter in a call to sqlite3_vtab_in_first(X,P) or ** sqlite3_vtab_in_next(X,P) should be one of the parameters to the ** xFilter method which invokes these routines, and specifically ** a parameter that was previously selected for all-at-once IN constraint | | | 10628 10629 10630 10631 10632 10633 10634 10635 10636 10637 10638 10639 10640 10641 10642 | ** The result of invoking these interfaces from any other context ** is undefined and probably harmful. ** ** The X parameter in a call to sqlite3_vtab_in_first(X,P) or ** sqlite3_vtab_in_next(X,P) should be one of the parameters to the ** xFilter method which invokes these routines, and specifically ** a parameter that was previously selected for all-at-once IN constraint ** processing using the [sqlite3_vtab_in()] interface in the ** [xBestIndex|xBestIndex method]. ^(If the X parameter is not ** an xFilter argument that was selected for all-at-once IN constraint ** processing, then these routines return [SQLITE_ERROR].)^ ** ** ^(Use these routines to access all values on the right-hand side ** of the IN constraint using code like the following: ** |
| ︙ | ︙ | |||
10681 10682 10683 10684 10685 10686 10687 | ** attempts to set *V to the value of the right-hand operand of ** that constraint if the right-hand operand is known. ^If the ** right-hand operand is not known, then *V is set to a NULL pointer. ** ^The sqlite3_vtab_rhs_value(P,J,V) interface returns SQLITE_OK if ** and only if *V is set to a value. ^The sqlite3_vtab_rhs_value(P,J,V) ** inteface returns SQLITE_NOTFOUND if the right-hand side of the J-th ** constraint is not available. ^The sqlite3_vtab_rhs_value() interface | | | 10683 10684 10685 10686 10687 10688 10689 10690 10691 10692 10693 10694 10695 10696 10697 | ** attempts to set *V to the value of the right-hand operand of ** that constraint if the right-hand operand is known. ^If the ** right-hand operand is not known, then *V is set to a NULL pointer. ** ^The sqlite3_vtab_rhs_value(P,J,V) interface returns SQLITE_OK if ** and only if *V is set to a value. ^The sqlite3_vtab_rhs_value(P,J,V) ** inteface returns SQLITE_NOTFOUND if the right-hand side of the J-th ** constraint is not available. ^The sqlite3_vtab_rhs_value() interface ** can return a result code other than SQLITE_OK or SQLITE_NOTFOUND if ** something goes wrong. ** ** The sqlite3_vtab_rhs_value() interface is usually only successful if ** the right-hand operand of a constraint is a literal value in the original ** SQL statement. If the right-hand operand is an expression or a reference ** to some other column or a [host parameter], then sqlite3_vtab_rhs_value() ** will probably return [SQLITE_NOTFOUND]. |
| ︙ | ︙ | |||
10709 10710 10711 10712 10713 10714 10715 |
SQLITE_API int sqlite3_vtab_rhs_value(sqlite3_index_info*, int, sqlite3_value **ppVal);
/*
** CAPI3REF: Conflict resolution modes
** KEYWORDS: {conflict resolution mode}
**
** These constants are returned by [sqlite3_vtab_on_conflict()] to
| | | | 10711 10712 10713 10714 10715 10716 10717 10718 10719 10720 10721 10722 10723 10724 10725 10726 |
SQLITE_API int sqlite3_vtab_rhs_value(sqlite3_index_info*, int, sqlite3_value **ppVal);
/*
** CAPI3REF: Conflict resolution modes
** KEYWORDS: {conflict resolution mode}
**
** These constants are returned by [sqlite3_vtab_on_conflict()] to
** inform a [virtual table] implementation of the [ON CONFLICT] mode
** for the SQL statement being evaluated.
**
** Note that the [SQLITE_IGNORE] constant is also used as a potential
** return value from the [sqlite3_set_authorizer()] callback and that
** [SQLITE_ABORT] is also a [result code].
*/
#define SQLITE_ROLLBACK 1
/* #define SQLITE_IGNORE 2 // Also used by sqlite3_authorizer() callback */
|
| ︙ | ︙ | |||
10750 10751 10752 10753 10754 10755 10756 | ** [[SQLITE_SCANSTAT_NVISIT]] <dt>SQLITE_SCANSTAT_NVISIT</dt> ** <dd>^The [sqlite3_int64] variable pointed to by the V parameter will be set ** to the total number of rows examined by all iterations of the X-th loop.</dd> ** ** [[SQLITE_SCANSTAT_EST]] <dt>SQLITE_SCANSTAT_EST</dt> ** <dd>^The "double" variable pointed to by the V parameter will be set to the ** query planner's estimate for the average number of rows output from each | | | | | | | | | | 10752 10753 10754 10755 10756 10757 10758 10759 10760 10761 10762 10763 10764 10765 10766 10767 10768 10769 10770 10771 10772 10773 10774 10775 10776 10777 10778 10779 10780 10781 10782 10783 10784 10785 10786 10787 10788 10789 10790 10791 10792 10793 10794 10795 10796 10797 10798 | ** [[SQLITE_SCANSTAT_NVISIT]] <dt>SQLITE_SCANSTAT_NVISIT</dt> ** <dd>^The [sqlite3_int64] variable pointed to by the V parameter will be set ** to the total number of rows examined by all iterations of the X-th loop.</dd> ** ** [[SQLITE_SCANSTAT_EST]] <dt>SQLITE_SCANSTAT_EST</dt> ** <dd>^The "double" variable pointed to by the V parameter will be set to the ** query planner's estimate for the average number of rows output from each ** iteration of the X-th loop. If the query planner's estimate was accurate, ** then this value will approximate the quotient NVISIT/NLOOP and the ** product of this value for all prior loops with the same SELECTID will ** be the NLOOP value for the current loop.</dd> ** ** [[SQLITE_SCANSTAT_NAME]] <dt>SQLITE_SCANSTAT_NAME</dt> ** <dd>^The "const char *" variable pointed to by the V parameter will be set ** to a zero-terminated UTF-8 string containing the name of the index or table ** used for the X-th loop.</dd> ** ** [[SQLITE_SCANSTAT_EXPLAIN]] <dt>SQLITE_SCANSTAT_EXPLAIN</dt> ** <dd>^The "const char *" variable pointed to by the V parameter will be set ** to a zero-terminated UTF-8 string containing the [EXPLAIN QUERY PLAN] ** description for the X-th loop.</dd> ** ** [[SQLITE_SCANSTAT_SELECTID]] <dt>SQLITE_SCANSTAT_SELECTID</dt> ** <dd>^The "int" variable pointed to by the V parameter will be set to the ** id for the X-th query plan element. The id value is unique within the ** statement. The select-id is the same value as is output in the first ** column of an [EXPLAIN QUERY PLAN] query.</dd> ** ** [[SQLITE_SCANSTAT_PARENTID]] <dt>SQLITE_SCANSTAT_PARENTID</dt> ** <dd>The "int" variable pointed to by the V parameter will be set to the ** id of the parent of the current query element, if applicable, or ** to zero if the query element has no parent. This is the same value as ** returned in the second column of an [EXPLAIN QUERY PLAN] query.</dd> ** ** [[SQLITE_SCANSTAT_NCYCLE]] <dt>SQLITE_SCANSTAT_NCYCLE</dt> ** <dd>The sqlite3_int64 output value is set to the number of cycles, ** according to the processor time-stamp counter, that elapsed while the ** query element was being processed. This value is not available for ** all query elements - if it is unavailable the output variable is ** set to -1.</dd> ** </dl> */ #define SQLITE_SCANSTAT_NLOOP 0 #define SQLITE_SCANSTAT_NVISIT 1 #define SQLITE_SCANSTAT_EST 2 #define SQLITE_SCANSTAT_NAME 3 #define SQLITE_SCANSTAT_EXPLAIN 4 |
| ︙ | ︙ | |||
10823 10824 10825 10826 10827 10828 10829 | ** SQLITE_SCANSTAT_COMPLEX is not specified, then only query plan elements ** that correspond to query loops (the "SCAN..." and "SEARCH..." elements of ** the EXPLAIN QUERY PLAN output) are available. Invoking API ** sqlite3_stmt_scanstatus() is equivalent to calling ** sqlite3_stmt_scanstatus_v2() with a zeroed flags parameter. ** ** Parameter "idx" identifies the specific query element to retrieve statistics | | | | 10825 10826 10827 10828 10829 10830 10831 10832 10833 10834 10835 10836 10837 10838 10839 10840 | ** SQLITE_SCANSTAT_COMPLEX is not specified, then only query plan elements ** that correspond to query loops (the "SCAN..." and "SEARCH..." elements of ** the EXPLAIN QUERY PLAN output) are available. Invoking API ** sqlite3_stmt_scanstatus() is equivalent to calling ** sqlite3_stmt_scanstatus_v2() with a zeroed flags parameter. ** ** Parameter "idx" identifies the specific query element to retrieve statistics ** for. Query elements are numbered starting from zero. A value of -1 may ** retrieve statistics for the entire query. ^If idx is out of range ** - less than -1 or greater than or equal to the total number of query ** elements used to implement the statement - a non-zero value is returned and ** the variable that pOut points to is unchanged. ** ** See also: [sqlite3_stmt_scanstatus_reset()] */ SQLITE_API int sqlite3_stmt_scanstatus( |
| ︙ | ︙ | |||
10867 10868 10869 10870 10871 10872 10873 | SQLITE_API void sqlite3_stmt_scanstatus_reset(sqlite3_stmt*); /* ** CAPI3REF: Flush caches to disk mid-transaction ** METHOD: sqlite3 ** ** ^If a write-transaction is open on [database connection] D when the | | | 10869 10870 10871 10872 10873 10874 10875 10876 10877 10878 10879 10880 10881 10882 10883 | SQLITE_API void sqlite3_stmt_scanstatus_reset(sqlite3_stmt*); /* ** CAPI3REF: Flush caches to disk mid-transaction ** METHOD: sqlite3 ** ** ^If a write-transaction is open on [database connection] D when the ** [sqlite3_db_cacheflush(D)] interface is invoked, any dirty ** pages in the pager-cache that are not currently in use are written out ** to disk. A dirty page may be in use if a database cursor created by an ** active SQL statement is reading from it, or if it is page 1 of a database ** file (page 1 is always "in use"). ^The [sqlite3_db_cacheflush(D)] ** interface flushes caches for all schemas - "main", "temp", and ** any [attached] databases. ** |
| ︙ | ︙ | |||
10981 10982 10983 10984 10985 10986 10987 | ** ^The [sqlite3_preupdate_depth(D)] interface returns 0 if the preupdate ** callback was invoked as a result of a direct insert, update, or delete ** operation; or 1 for inserts, updates, or deletes invoked by top-level ** triggers; or 2 for changes resulting from triggers called by top-level ** triggers; and so forth. ** ** When the [sqlite3_blob_write()] API is used to update a blob column, | | | | 10983 10984 10985 10986 10987 10988 10989 10990 10991 10992 10993 10994 10995 10996 10997 10998 | ** ^The [sqlite3_preupdate_depth(D)] interface returns 0 if the preupdate ** callback was invoked as a result of a direct insert, update, or delete ** operation; or 1 for inserts, updates, or deletes invoked by top-level ** triggers; or 2 for changes resulting from triggers called by top-level ** triggers; and so forth. ** ** When the [sqlite3_blob_write()] API is used to update a blob column, ** the pre-update hook is invoked with SQLITE_DELETE, because ** the new values are not yet available. In this case, when a ** callback made with op==SQLITE_DELETE is actually a write using the ** sqlite3_blob_write() API, the [sqlite3_preupdate_blobwrite()] returns ** the index of the column being written. In other cases, where the ** pre-update hook is being invoked for some other reason, including a ** regular DELETE, sqlite3_preupdate_blobwrite() returns -1. ** ** See also: [sqlite3_update_hook()] |
| ︙ | ︙ | |||
11235 11236 11237 11238 11239 11240 11241 | ** [database connection] D. If S is a NULL pointer, the main database is used. ** If P is not a NULL pointer, then the size of the database in bytes ** is written into *P. ** ** For an ordinary on-disk database file, the serialization is just a ** copy of the disk file. For an in-memory database or a "TEMP" database, ** the serialization is the same sequence of bytes which would be written | | | | 11237 11238 11239 11240 11241 11242 11243 11244 11245 11246 11247 11248 11249 11250 11251 11252 11253 11254 11255 11256 11257 11258 11259 11260 | ** [database connection] D. If S is a NULL pointer, the main database is used. ** If P is not a NULL pointer, then the size of the database in bytes ** is written into *P. ** ** For an ordinary on-disk database file, the serialization is just a ** copy of the disk file. For an in-memory database or a "TEMP" database, ** the serialization is the same sequence of bytes which would be written ** to disk if that database were backed up to disk. ** ** The usual case is that sqlite3_serialize() copies the serialization of ** the database into memory obtained from [sqlite3_malloc64()] and returns ** a pointer to that memory. The caller is responsible for freeing the ** returned value to avoid a memory leak. However, if the F argument ** contains the SQLITE_SERIALIZE_NOCOPY bit, then no memory allocations ** are made, and the sqlite3_serialize() function will return a pointer ** to the contiguous memory representation of the database that SQLite ** is currently using for that database, or NULL if no such contiguous ** memory representation of the database exists. A contiguous memory ** representation of the database will usually only exist if there has ** been a prior call to [sqlite3_deserialize(D,S,...)] with the same ** values of D and S. ** The size of the database is written into *P even if the ** SQLITE_SERIALIZE_NOCOPY bit is set but no contiguous copy ** of the database exists. |
| ︙ | ︙ | |||
11315 11316 11317 11318 11319 11320 11321 | ** Applications must not modify the buffer P or invalidate it before ** the database connection D is closed. ** ** The sqlite3_deserialize() interface will fail with SQLITE_BUSY if the ** database is currently in a read transaction or is involved in a backup ** operation. ** | | | 11317 11318 11319 11320 11321 11322 11323 11324 11325 11326 11327 11328 11329 11330 11331 | ** Applications must not modify the buffer P or invalidate it before ** the database connection D is closed. ** ** The sqlite3_deserialize() interface will fail with SQLITE_BUSY if the ** database is currently in a read transaction or is involved in a backup ** operation. ** ** It is not possible to deserialize into the TEMP database. If the ** S argument to sqlite3_deserialize(D,S,P,N,M,F) is "temp" then the ** function returns SQLITE_ERROR. ** ** The deserialized database should not be in [WAL mode]. If the database ** is in WAL mode, then any attempt to use the database file will result ** in an [SQLITE_CANTOPEN] error. The application can set the ** [file format version numbers] (bytes 18 and 19) of the input database P |
| ︙ | ︙ | |||
11337 11338 11339 11340 11341 11342 11343 | ** This interface is omitted if SQLite is compiled with the ** [SQLITE_OMIT_DESERIALIZE] option. */ SQLITE_API int sqlite3_deserialize( sqlite3 *db, /* The database connection */ const char *zSchema, /* Which DB to reopen with the deserialization */ unsigned char *pData, /* The serialized database content */ | | | | 11339 11340 11341 11342 11343 11344 11345 11346 11347 11348 11349 11350 11351 11352 11353 11354 11355 11356 11357 11358 11359 11360 11361 | ** This interface is omitted if SQLite is compiled with the ** [SQLITE_OMIT_DESERIALIZE] option. */ SQLITE_API int sqlite3_deserialize( sqlite3 *db, /* The database connection */ const char *zSchema, /* Which DB to reopen with the deserialization */ unsigned char *pData, /* The serialized database content */ sqlite3_int64 szDb, /* Number of bytes in the deserialization */ sqlite3_int64 szBuf, /* Total size of buffer pData[] */ unsigned mFlags /* Zero or more SQLITE_DESERIALIZE_* flags */ ); /* ** CAPI3REF: Flags for sqlite3_deserialize() ** ** The following are allowed values for the 6th argument (the F argument) to ** the [sqlite3_deserialize(D,S,P,N,M,F)] interface. ** ** The SQLITE_DESERIALIZE_FREEONCLOSE means that the database serialization ** in the P argument is held in memory obtained from [sqlite3_malloc64()] ** and that SQLite should take ownership of this memory and automatically ** free it when it has finished using it. Without this flag, the caller ** is responsible for freeing any dynamically allocated memory. |
| ︙ | ︙ | |||
11870 11871 11872 11873 11874 11875 11876 | ** When a session object is disabled (see the [sqlite3session_enable()] API), ** it does not accumulate records when rows are inserted, updated or deleted. ** This may appear to have some counter-intuitive effects if a single row ** is written to more than once during a session. For example, if a row ** is inserted while a session object is enabled, then later deleted while ** the same session object is disabled, no INSERT record will appear in the ** changeset, even though the delete took place while the session was disabled. | | | | > | 11872 11873 11874 11875 11876 11877 11878 11879 11880 11881 11882 11883 11884 11885 11886 11887 11888 11889 | ** When a session object is disabled (see the [sqlite3session_enable()] API), ** it does not accumulate records when rows are inserted, updated or deleted. ** This may appear to have some counter-intuitive effects if a single row ** is written to more than once during a session. For example, if a row ** is inserted while a session object is enabled, then later deleted while ** the same session object is disabled, no INSERT record will appear in the ** changeset, even though the delete took place while the session was disabled. ** Or, if one field of a row is updated while a session is enabled, and ** then another field of the same row is updated while the session is disabled, ** the resulting changeset will contain an UPDATE change that updates both ** fields. */ SQLITE_API int sqlite3session_changeset( sqlite3_session *pSession, /* Session object */ int *pnChangeset, /* OUT: Size of buffer at *ppChangeset */ void **ppChangeset /* OUT: Buffer containing changeset */ ); |
| ︙ | ︙ | |||
12081 12082 12083 12084 12085 12086 12087 | /* ** CAPI3REF: Flags for sqlite3changeset_start_v2 ** ** The following flags may passed via the 4th parameter to ** [sqlite3changeset_start_v2] and [sqlite3changeset_start_v2_strm]: ** | | | 12084 12085 12086 12087 12088 12089 12090 12091 12092 12093 12094 12095 12096 12097 12098 | /* ** CAPI3REF: Flags for sqlite3changeset_start_v2 ** ** The following flags may passed via the 4th parameter to ** [sqlite3changeset_start_v2] and [sqlite3changeset_start_v2_strm]: ** ** <dt>SQLITE_CHANGESETSTART_INVERT <dd> ** Invert the changeset while iterating through it. This is equivalent to ** inverting a changeset using sqlite3changeset_invert() before applying it. ** It is an error to specify this flag with a patchset. */ #define SQLITE_CHANGESETSTART_INVERT 0x0002 |
| ︙ | ︙ | |||
12626 12627 12628 12629 12630 12631 12632 | ** CAPI3REF: Apply A Changeset To A Database ** ** Apply a changeset or patchset to a database. These functions attempt to ** update the "main" database attached to handle db with the changes found in ** the changeset passed via the second and third arguments. ** ** The fourth argument (xFilter) passed to these functions is the "filter | > > | | | | | | | > > > > > > > | | | | | | 12629 12630 12631 12632 12633 12634 12635 12636 12637 12638 12639 12640 12641 12642 12643 12644 12645 12646 12647 12648 12649 12650 12651 12652 12653 12654 12655 12656 12657 12658 12659 12660 12661 12662 12663 12664 12665 12666 12667 12668 12669 12670 12671 12672 12673 12674 12675 12676 12677 12678 12679 12680 12681 12682 12683 | ** CAPI3REF: Apply A Changeset To A Database ** ** Apply a changeset or patchset to a database. These functions attempt to ** update the "main" database attached to handle db with the changes found in ** the changeset passed via the second and third arguments. ** ** The fourth argument (xFilter) passed to these functions is the "filter ** callback". This may be passed NULL, in which case all changes in the ** changeset are applied to the database. For sqlite3changeset_apply() and ** sqlite3_changeset_apply_v2(), if it is not NULL, then it is invoked once ** for each table affected by at least one change in the changeset. In this ** case the table name is passed as the second argument, and a copy of ** the context pointer passed as the sixth argument to apply() or apply_v2() ** as the first. If the "filter callback" returns zero, then no attempt is ** made to apply any changes to the table. Otherwise, if the return value is ** non-zero, all changes related to the table are attempted. ** ** For sqlite3_changeset_apply_v3(), the xFilter callback is invoked once ** per change. The second argument in this case is an sqlite3_changeset_iter ** that may be queried using the usual APIs for the details of the current ** change. If the "filter callback" returns zero in this case, then no attempt ** is made to apply the current change. If it returns non-zero, the change ** is applied. ** ** For each table that is not excluded by the filter callback, this function ** tests that the target database contains a compatible table. A table is ** considered compatible if all of the following are true: ** ** <ul> ** <li> The table has the same name as the name recorded in the ** changeset, and ** <li> The table has at least as many columns as recorded in the ** changeset, and ** <li> The table has primary key columns in the same position as ** recorded in the changeset. ** </ul> ** ** If there is no compatible table, it is not an error, but none of the ** changes associated with the table are applied. A warning message is issued ** via the sqlite3_log() mechanism with the error code SQLITE_SCHEMA. At most ** one such warning is issued for each table in the changeset. ** ** For each change for which there is a compatible table, an attempt is made ** to modify the table contents according to each UPDATE, INSERT or DELETE ** change that is not excluded by a filter callback. If a change cannot be ** applied cleanly, the conflict handler function passed as the fifth argument ** to sqlite3changeset_apply() may be invoked. A description of exactly when ** the conflict handler is invoked for each type of change is below. ** ** Unlike the xFilter argument, xConflict may not be passed NULL. The results ** of passing anything other than a valid function pointer as the xConflict ** argument are undefined. ** ** Each time the conflict handler function is invoked, it must return one ** of [SQLITE_CHANGESET_OMIT], [SQLITE_CHANGESET_ABORT] or |
| ︙ | ︙ | |||
12799 12800 12801 12802 12803 12804 12805 12806 12807 12808 12809 12810 12811 12812 |
sqlite3 *db, /* Apply change to "main" db of this handle */
int nChangeset, /* Size of changeset in bytes */
void *pChangeset, /* Changeset blob */
int(*xFilter)(
void *pCtx, /* Copy of sixth arg to _apply() */
const char *zTab /* Table name */
),
int(*xConflict)(
void *pCtx, /* Copy of sixth arg to _apply() */
int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */
sqlite3_changeset_iter *p /* Handle describing change and conflict */
),
void *pCtx, /* First argument passed to xConflict */
void **ppRebase, int *pnRebase, /* OUT: Rebase data */
| > > > > > > > > > > > > > > > > > | 12811 12812 12813 12814 12815 12816 12817 12818 12819 12820 12821 12822 12823 12824 12825 12826 12827 12828 12829 12830 12831 12832 12833 12834 12835 12836 12837 12838 12839 12840 12841 |
sqlite3 *db, /* Apply change to "main" db of this handle */
int nChangeset, /* Size of changeset in bytes */
void *pChangeset, /* Changeset blob */
int(*xFilter)(
void *pCtx, /* Copy of sixth arg to _apply() */
const char *zTab /* Table name */
),
int(*xConflict)(
void *pCtx, /* Copy of sixth arg to _apply() */
int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */
sqlite3_changeset_iter *p /* Handle describing change and conflict */
),
void *pCtx, /* First argument passed to xConflict */
void **ppRebase, int *pnRebase, /* OUT: Rebase data */
int flags /* SESSION_CHANGESETAPPLY_* flags */
);
SQLITE_API int sqlite3changeset_apply_v3(
sqlite3 *db, /* Apply change to "main" db of this handle */
int nChangeset, /* Size of changeset in bytes */
void *pChangeset, /* Changeset blob */
int(*xFilter)(
void *pCtx, /* Copy of sixth arg to _apply() */
sqlite3_changeset_iter *p /* Handle describing change */
),
int(*xConflict)(
void *pCtx, /* Copy of sixth arg to _apply() */
int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */
sqlite3_changeset_iter *p /* Handle describing change and conflict */
),
void *pCtx, /* First argument passed to xConflict */
void **ppRebase, int *pnRebase, /* OUT: Rebase data */
|
| ︙ | ︙ | |||
13218 13219 13220 13221 13222 13223 13224 13225 13226 13227 13228 13229 13230 13231 |
sqlite3 *db, /* Apply change to "main" db of this handle */
int (*xInput)(void *pIn, void *pData, int *pnData), /* Input function */
void *pIn, /* First arg for xInput */
int(*xFilter)(
void *pCtx, /* Copy of sixth arg to _apply() */
const char *zTab /* Table name */
),
int(*xConflict)(
void *pCtx, /* Copy of sixth arg to _apply() */
int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */
sqlite3_changeset_iter *p /* Handle describing change and conflict */
),
void *pCtx, /* First argument passed to xConflict */
void **ppRebase, int *pnRebase,
| > > > > > > > > > > > > > > > > > | 13247 13248 13249 13250 13251 13252 13253 13254 13255 13256 13257 13258 13259 13260 13261 13262 13263 13264 13265 13266 13267 13268 13269 13270 13271 13272 13273 13274 13275 13276 13277 |
sqlite3 *db, /* Apply change to "main" db of this handle */
int (*xInput)(void *pIn, void *pData, int *pnData), /* Input function */
void *pIn, /* First arg for xInput */
int(*xFilter)(
void *pCtx, /* Copy of sixth arg to _apply() */
const char *zTab /* Table name */
),
int(*xConflict)(
void *pCtx, /* Copy of sixth arg to _apply() */
int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */
sqlite3_changeset_iter *p /* Handle describing change and conflict */
),
void *pCtx, /* First argument passed to xConflict */
void **ppRebase, int *pnRebase,
int flags
);
SQLITE_API int sqlite3changeset_apply_v3_strm(
sqlite3 *db, /* Apply change to "main" db of this handle */
int (*xInput)(void *pIn, void *pData, int *pnData), /* Input function */
void *pIn, /* First arg for xInput */
int(*xFilter)(
void *pCtx, /* Copy of sixth arg to _apply() */
sqlite3_changeset_iter *p
),
int(*xConflict)(
void *pCtx, /* Copy of sixth arg to _apply() */
int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */
sqlite3_changeset_iter *p /* Handle describing change and conflict */
),
void *pCtx, /* First argument passed to xConflict */
void **ppRebase, int *pnRebase,
|
| ︙ | ︙ | |||
15171 15172 15173 15174 15175 15176 15177 | #endif /* ** GCC does not define the offsetof() macro so we'll have to do it ** ourselves. */ #ifndef offsetof | | | 15217 15218 15219 15220 15221 15222 15223 15224 15225 15226 15227 15228 15229 15230 15231 | #endif /* ** GCC does not define the offsetof() macro so we'll have to do it ** ourselves. */ #ifndef offsetof # define offsetof(ST,M) ((size_t)((char*)&((ST*)0)->M - (char*)0)) #endif /* ** Work around C99 "flex-array" syntax for pre-C99 compilers, so as ** to avoid complaints from -fsanitize=strict-bounds. */ #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) |
| ︙ | ︙ | |||
15437 15438 15439 15440 15441 15442 15443 | #define SMALLEST_INT64 (((i64)-1) - LARGEST_INT64) /* ** Macro SMXV(n) return the maximum value that can be held in variable n, ** assuming n is a signed integer type. UMXV(n) is similar for unsigned ** integer types. */ | | | | 15483 15484 15485 15486 15487 15488 15489 15490 15491 15492 15493 15494 15495 15496 15497 15498 | #define SMALLEST_INT64 (((i64)-1) - LARGEST_INT64) /* ** Macro SMXV(n) return the maximum value that can be held in variable n, ** assuming n is a signed integer type. UMXV(n) is similar for unsigned ** integer types. */ #define SMXV(n) ((((i64)1)<<(sizeof(n)*8-1))-1) #define UMXV(n) ((((i64)1)<<(sizeof(n)*8))-1) /* ** Round up a number to the next larger multiple of 8. This is used ** to force 8-byte alignment on 64-bit architectures. ** ** ROUND8() always does the rounding, for any argument. ** |
| ︙ | ︙ | |||
15559 15560 15561 15562 15563 15564 15565 15566 15567 15568 15569 15570 15571 15572 | ** 0x00002000 Constant propagation ** 0x00004000 Push-down optimization ** 0x00008000 After all FROM-clause analysis ** 0x00010000 Beginning of DELETE/INSERT/UPDATE processing ** 0x00020000 Transform DISTINCT into GROUP BY ** 0x00040000 SELECT tree dump after all code has been generated ** 0x00080000 NOT NULL strength reduction */ /* ** Macros for "wheretrace" */ SQLITE_PRIVATE u32 sqlite3WhereTrace; #if defined(SQLITE_DEBUG) \ | > > | 15605 15606 15607 15608 15609 15610 15611 15612 15613 15614 15615 15616 15617 15618 15619 15620 | ** 0x00002000 Constant propagation ** 0x00004000 Push-down optimization ** 0x00008000 After all FROM-clause analysis ** 0x00010000 Beginning of DELETE/INSERT/UPDATE processing ** 0x00020000 Transform DISTINCT into GROUP BY ** 0x00040000 SELECT tree dump after all code has been generated ** 0x00080000 NOT NULL strength reduction ** 0x00100000 Pointers are all shown as zero ** 0x00200000 EXISTS-to-JOIN optimization */ /* ** Macros for "wheretrace" */ SQLITE_PRIVATE u32 sqlite3WhereTrace; #if defined(SQLITE_DEBUG) \ |
| ︙ | ︙ | |||
15603 15604 15605 15606 15607 15608 15609 15610 15611 15612 15613 15614 15615 15616 | ** 0x00004000 Show all WHERE terms at key points ** 0x00008000 Show the full SELECT statement at key places ** ** 0x00010000 Show more detail when printing WHERE terms ** 0x00020000 Show WHERE terms returned from whereScanNext() ** 0x00040000 Solver overview messages ** 0x00080000 Star-query heuristic */ /* ** An instance of the following structure is used to store the busy-handler ** callback for a given sqlite handle. ** | > | 15651 15652 15653 15654 15655 15656 15657 15658 15659 15660 15661 15662 15663 15664 15665 | ** 0x00004000 Show all WHERE terms at key points ** 0x00008000 Show the full SELECT statement at key places ** ** 0x00010000 Show more detail when printing WHERE terms ** 0x00020000 Show WHERE terms returned from whereScanNext() ** 0x00040000 Solver overview messages ** 0x00080000 Star-query heuristic ** 0x00100000 Pointers are all shown as zero */ /* ** An instance of the following structure is used to store the busy-handler ** callback for a given sqlite handle. ** |
| ︙ | ︙ | |||
15675 15676 15677 15678 15679 15680 15681 | ** The following value as a destructor means to use sqlite3DbFree(). ** The sqlite3DbFree() routine requires two parameters instead of the ** one parameter that destructors normally want. So we have to introduce ** this magic value that the code knows to handle differently. Any ** pointer will work here as long as it is distinct from SQLITE_STATIC ** and SQLITE_TRANSIENT. */ | | | 15724 15725 15726 15727 15728 15729 15730 15731 15732 15733 15734 15735 15736 15737 15738 | ** The following value as a destructor means to use sqlite3DbFree(). ** The sqlite3DbFree() routine requires two parameters instead of the ** one parameter that destructors normally want. So we have to introduce ** this magic value that the code knows to handle differently. Any ** pointer will work here as long as it is distinct from SQLITE_STATIC ** and SQLITE_TRANSIENT. */ #define SQLITE_DYNAMIC ((sqlite3_destructor_type)sqlite3RowSetClear) /* ** When SQLITE_OMIT_WSD is defined, it means that the target platform does ** not support Writable Static Data (WSD) such as global and static variables. ** All variables must either be on the stack or dynamically allocated from ** the heap. When WSD is unsupported, the variable declarations scattered ** throughout the SQLite code must become constants instead. The SQLITE_WSD |
| ︙ | ︙ | |||
16743 16744 16745 16746 16747 16748 16749 16750 16751 16752 16753 16754 16755 16756 |
int nData; /* Size of pData. 0 if none. */
int nZero; /* Extra zero data appended after pData,nData */
};
SQLITE_PRIVATE int sqlite3BtreeInsert(BtCursor*, const BtreePayload *pPayload,
int flags, int seekResult);
SQLITE_PRIVATE int sqlite3BtreeFirst(BtCursor*, int *pRes);
SQLITE_PRIVATE int sqlite3BtreeLast(BtCursor*, int *pRes);
SQLITE_PRIVATE int sqlite3BtreeNext(BtCursor*, int flags);
SQLITE_PRIVATE int sqlite3BtreeEof(BtCursor*);
SQLITE_PRIVATE int sqlite3BtreePrevious(BtCursor*, int flags);
SQLITE_PRIVATE i64 sqlite3BtreeIntegerKey(BtCursor*);
SQLITE_PRIVATE void sqlite3BtreeCursorPin(BtCursor*);
SQLITE_PRIVATE void sqlite3BtreeCursorUnpin(BtCursor*);
| > | 16792 16793 16794 16795 16796 16797 16798 16799 16800 16801 16802 16803 16804 16805 16806 |
int nData; /* Size of pData. 0 if none. */
int nZero; /* Extra zero data appended after pData,nData */
};
SQLITE_PRIVATE int sqlite3BtreeInsert(BtCursor*, const BtreePayload *pPayload,
int flags, int seekResult);
SQLITE_PRIVATE int sqlite3BtreeFirst(BtCursor*, int *pRes);
SQLITE_PRIVATE int sqlite3BtreeIsEmpty(BtCursor *pCur, int *pRes);
SQLITE_PRIVATE int sqlite3BtreeLast(BtCursor*, int *pRes);
SQLITE_PRIVATE int sqlite3BtreeNext(BtCursor*, int flags);
SQLITE_PRIVATE int sqlite3BtreeEof(BtCursor*);
SQLITE_PRIVATE int sqlite3BtreePrevious(BtCursor*, int flags);
SQLITE_PRIVATE i64 sqlite3BtreeIntegerKey(BtCursor*);
SQLITE_PRIVATE void sqlite3BtreeCursorPin(BtCursor*);
SQLITE_PRIVATE void sqlite3BtreeCursorUnpin(BtCursor*);
|
| ︙ | ︙ | |||
17076 17077 17078 17079 17080 17081 17082 | #define OP_SeekRowid 30 /* jump0, synopsis: intkey=r[P3] */ #define OP_NotExists 31 /* jump, synopsis: intkey=r[P3] */ #define OP_Last 32 /* jump0 */ #define OP_IfSizeBetween 33 /* jump */ #define OP_SorterSort 34 /* jump */ #define OP_Sort 35 /* jump */ #define OP_Rewind 36 /* jump0 */ | > | | | < | | | > | | | | < > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | < | | | | | > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | < > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 17126 17127 17128 17129 17130 17131 17132 17133 17134 17135 17136 17137 17138 17139 17140 17141 17142 17143 17144 17145 17146 17147 17148 17149 17150 17151 17152 17153 17154 17155 17156 17157 17158 17159 17160 17161 17162 17163 17164 17165 17166 17167 17168 17169 17170 17171 17172 17173 17174 17175 17176 17177 17178 17179 17180 17181 17182 17183 17184 17185 17186 17187 17188 17189 17190 17191 17192 17193 17194 17195 17196 17197 17198 17199 17200 17201 17202 17203 17204 17205 17206 17207 17208 17209 17210 17211 17212 17213 17214 17215 17216 17217 17218 17219 17220 17221 17222 17223 17224 17225 17226 17227 17228 17229 17230 17231 17232 17233 17234 17235 17236 17237 17238 17239 17240 17241 17242 17243 17244 17245 17246 17247 17248 17249 17250 17251 17252 17253 17254 17255 17256 17257 17258 17259 17260 17261 17262 17263 17264 17265 17266 17267 17268 17269 17270 17271 17272 17273 17274 17275 17276 17277 17278 17279 17280 17281 17282 17283 17284 17285 17286 17287 17288 17289 17290 17291 17292 17293 17294 17295 17296 17297 17298 17299 17300 17301 17302 17303 17304 17305 17306 17307 17308 17309 17310 17311 17312 17313 17314 17315 17316 17317 17318 17319 17320 17321 17322 17323 17324 17325 17326 17327 17328 17329 17330 17331 17332 17333 17334 17335 17336 17337 17338 17339 |
#define OP_SeekRowid 30 /* jump0, synopsis: intkey=r[P3] */
#define OP_NotExists 31 /* jump, synopsis: intkey=r[P3] */
#define OP_Last 32 /* jump0 */
#define OP_IfSizeBetween 33 /* jump */
#define OP_SorterSort 34 /* jump */
#define OP_Sort 35 /* jump */
#define OP_Rewind 36 /* jump0 */
#define OP_IfEmpty 37 /* jump, synopsis: if( empty(P1) ) goto P2 */
#define OP_SorterNext 38 /* jump */
#define OP_Prev 39 /* jump */
#define OP_Next 40 /* jump */
#define OP_IdxLE 41 /* jump, synopsis: key=r[P3@P4] */
#define OP_IdxGT 42 /* jump, synopsis: key=r[P3@P4] */
#define OP_Or 43 /* same as TK_OR, synopsis: r[P3]=(r[P1] || r[P2]) */
#define OP_And 44 /* same as TK_AND, synopsis: r[P3]=(r[P1] && r[P2]) */
#define OP_IdxLT 45 /* jump, synopsis: key=r[P3@P4] */
#define OP_IdxGE 46 /* jump, synopsis: key=r[P3@P4] */
#define OP_RowSetRead 47 /* jump, synopsis: r[P3]=rowset(P1) */
#define OP_RowSetTest 48 /* jump, synopsis: if r[P3] in rowset(P1) goto P2 */
#define OP_Program 49 /* jump0 */
#define OP_FkIfZero 50 /* jump, synopsis: if fkctr[P1]==0 goto P2 */
#define OP_IsNull 51 /* jump, same as TK_ISNULL, synopsis: if r[P1]==NULL goto P2 */
#define OP_NotNull 52 /* jump, same as TK_NOTNULL, synopsis: if r[P1]!=NULL goto P2 */
#define OP_Ne 53 /* jump, same as TK_NE, synopsis: IF r[P3]!=r[P1] */
#define OP_Eq 54 /* jump, same as TK_EQ, synopsis: IF r[P3]==r[P1] */
#define OP_Gt 55 /* jump, same as TK_GT, synopsis: IF r[P3]>r[P1] */
#define OP_Le 56 /* jump, same as TK_LE, synopsis: IF r[P3]<=r[P1] */
#define OP_Lt 57 /* jump, same as TK_LT, synopsis: IF r[P3]<r[P1] */
#define OP_Ge 58 /* jump, same as TK_GE, synopsis: IF r[P3]>=r[P1] */
#define OP_ElseEq 59 /* jump, same as TK_ESCAPE */
#define OP_IfPos 60 /* jump, synopsis: if r[P1]>0 then r[P1]-=P3, goto P2 */
#define OP_IfNotZero 61 /* jump, synopsis: if r[P1]!=0 then r[P1]--, goto P2 */
#define OP_DecrJumpZero 62 /* jump, synopsis: if (--r[P1])==0 goto P2 */
#define OP_IncrVacuum 63 /* jump */
#define OP_VNext 64 /* jump */
#define OP_Filter 65 /* jump, synopsis: if key(P3@P4) not in filter(P1) goto P2 */
#define OP_PureFunc 66 /* synopsis: r[P3]=func(r[P2@NP]) */
#define OP_Function 67 /* synopsis: r[P3]=func(r[P2@NP]) */
#define OP_Return 68
#define OP_EndCoroutine 69
#define OP_HaltIfNull 70 /* synopsis: if r[P3]=null halt */
#define OP_Halt 71
#define OP_Integer 72 /* synopsis: r[P2]=P1 */
#define OP_Int64 73 /* synopsis: r[P2]=P4 */
#define OP_String 74 /* synopsis: r[P2]='P4' (len=P1) */
#define OP_BeginSubrtn 75 /* synopsis: r[P2]=NULL */
#define OP_Null 76 /* synopsis: r[P2..P3]=NULL */
#define OP_SoftNull 77 /* synopsis: r[P1]=NULL */
#define OP_Blob 78 /* synopsis: r[P2]=P4 (len=P1) */
#define OP_Variable 79 /* synopsis: r[P2]=parameter(P1) */
#define OP_Move 80 /* synopsis: r[P2@P3]=r[P1@P3] */
#define OP_Copy 81 /* synopsis: r[P2@P3+1]=r[P1@P3+1] */
#define OP_SCopy 82 /* synopsis: r[P2]=r[P1] */
#define OP_IntCopy 83 /* synopsis: r[P2]=r[P1] */
#define OP_FkCheck 84
#define OP_ResultRow 85 /* synopsis: output=r[P1@P2] */
#define OP_CollSeq 86
#define OP_AddImm 87 /* synopsis: r[P1]=r[P1]+P2 */
#define OP_RealAffinity 88
#define OP_Cast 89 /* synopsis: affinity(r[P1]) */
#define OP_Permutation 90
#define OP_Compare 91 /* synopsis: r[P1@P3] <-> r[P2@P3] */
#define OP_IsTrue 92 /* synopsis: r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4 */
#define OP_ZeroOrNull 93 /* synopsis: r[P2] = 0 OR NULL */
#define OP_Offset 94 /* synopsis: r[P3] = sqlite_offset(P1) */
#define OP_Column 95 /* synopsis: r[P3]=PX cursor P1 column P2 */
#define OP_TypeCheck 96 /* synopsis: typecheck(r[P1@P2]) */
#define OP_Affinity 97 /* synopsis: affinity(r[P1@P2]) */
#define OP_MakeRecord 98 /* synopsis: r[P3]=mkrec(r[P1@P2]) */
#define OP_Count 99 /* synopsis: r[P2]=count() */
#define OP_ReadCookie 100
#define OP_SetCookie 101
#define OP_ReopenIdx 102 /* synopsis: root=P2 iDb=P3 */
#define OP_BitAnd 103 /* same as TK_BITAND, synopsis: r[P3]=r[P1]&r[P2] */
#define OP_BitOr 104 /* same as TK_BITOR, synopsis: r[P3]=r[P1]|r[P2] */
#define OP_ShiftLeft 105 /* same as TK_LSHIFT, synopsis: r[P3]=r[P2]<<r[P1] */
#define OP_ShiftRight 106 /* same as TK_RSHIFT, synopsis: r[P3]=r[P2]>>r[P1] */
#define OP_Add 107 /* same as TK_PLUS, synopsis: r[P3]=r[P1]+r[P2] */
#define OP_Subtract 108 /* same as TK_MINUS, synopsis: r[P3]=r[P2]-r[P1] */
#define OP_Multiply 109 /* same as TK_STAR, synopsis: r[P3]=r[P1]*r[P2] */
#define OP_Divide 110 /* same as TK_SLASH, synopsis: r[P3]=r[P2]/r[P1] */
#define OP_Remainder 111 /* same as TK_REM, synopsis: r[P3]=r[P2]%r[P1] */
#define OP_Concat 112 /* same as TK_CONCAT, synopsis: r[P3]=r[P2]+r[P1] */
#define OP_OpenRead 113 /* synopsis: root=P2 iDb=P3 */
#define OP_OpenWrite 114 /* synopsis: root=P2 iDb=P3 */
#define OP_BitNot 115 /* same as TK_BITNOT, synopsis: r[P2]= ~r[P1] */
#define OP_OpenDup 116
#define OP_OpenAutoindex 117 /* synopsis: nColumn=P2 */
#define OP_String8 118 /* same as TK_STRING, synopsis: r[P2]='P4' */
#define OP_OpenEphemeral 119 /* synopsis: nColumn=P2 */
#define OP_SorterOpen 120
#define OP_SequenceTest 121 /* synopsis: if( cursor[P1].ctr++ ) pc = P2 */
#define OP_OpenPseudo 122 /* synopsis: P3 columns in r[P2] */
#define OP_Close 123
#define OP_ColumnsUsed 124
#define OP_SeekScan 125 /* synopsis: Scan-ahead up to P1 rows */
#define OP_SeekHit 126 /* synopsis: set P2<=seekHit<=P3 */
#define OP_Sequence 127 /* synopsis: r[P2]=cursor[P1].ctr++ */
#define OP_NewRowid 128 /* synopsis: r[P2]=rowid */
#define OP_Insert 129 /* synopsis: intkey=r[P3] data=r[P2] */
#define OP_RowCell 130
#define OP_Delete 131
#define OP_ResetCount 132
#define OP_SorterCompare 133 /* synopsis: if key(P1)!=trim(r[P3],P4) goto P2 */
#define OP_SorterData 134 /* synopsis: r[P2]=data */
#define OP_RowData 135 /* synopsis: r[P2]=data */
#define OP_Rowid 136 /* synopsis: r[P2]=PX rowid of P1 */
#define OP_NullRow 137
#define OP_SeekEnd 138
#define OP_IdxInsert 139 /* synopsis: key=r[P2] */
#define OP_SorterInsert 140 /* synopsis: key=r[P2] */
#define OP_IdxDelete 141 /* synopsis: key=r[P2@P3] */
#define OP_DeferredSeek 142 /* synopsis: Move P3 to P1.rowid if needed */
#define OP_IdxRowid 143 /* synopsis: r[P2]=rowid */
#define OP_FinishSeek 144
#define OP_Destroy 145
#define OP_Clear 146
#define OP_ResetSorter 147
#define OP_CreateBtree 148 /* synopsis: r[P2]=root iDb=P1 flags=P3 */
#define OP_SqlExec 149
#define OP_ParseSchema 150
#define OP_LoadAnalysis 151
#define OP_DropTable 152
#define OP_DropIndex 153
#define OP_Real 154 /* same as TK_FLOAT, synopsis: r[P2]=P4 */
#define OP_DropTrigger 155
#define OP_IntegrityCk 156
#define OP_RowSetAdd 157 /* synopsis: rowset(P1)=r[P2] */
#define OP_Param 158
#define OP_FkCounter 159 /* synopsis: fkctr[P1]+=P2 */
#define OP_MemMax 160 /* synopsis: r[P1]=max(r[P1],r[P2]) */
#define OP_OffsetLimit 161 /* synopsis: if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1) */
#define OP_AggInverse 162 /* synopsis: accum=r[P3] inverse(r[P2@P5]) */
#define OP_AggStep 163 /* synopsis: accum=r[P3] step(r[P2@P5]) */
#define OP_AggStep1 164 /* synopsis: accum=r[P3] step(r[P2@P5]) */
#define OP_AggValue 165 /* synopsis: r[P3]=value N=P2 */
#define OP_AggFinal 166 /* synopsis: accum=r[P1] N=P2 */
#define OP_Expire 167
#define OP_CursorLock 168
#define OP_CursorUnlock 169
#define OP_TableLock 170 /* synopsis: iDb=P1 root=P2 write=P3 */
#define OP_VBegin 171
#define OP_VCreate 172
#define OP_VDestroy 173
#define OP_VOpen 174
#define OP_VCheck 175
#define OP_VInitIn 176 /* synopsis: r[P2]=ValueList(P1,P3) */
#define OP_VColumn 177 /* synopsis: r[P3]=vcolumn(P2) */
#define OP_VRename 178
#define OP_Pagecount 179
#define OP_MaxPgcnt 180
#define OP_ClrSubtype 181 /* synopsis: r[P1].subtype = 0 */
#define OP_GetSubtype 182 /* synopsis: r[P2] = r[P1].subtype */
#define OP_SetSubtype 183 /* synopsis: r[P2].subtype = r[P1] */
#define OP_FilterAdd 184 /* synopsis: filter(P1) += key(P3@P4) */
#define OP_Trace 185
#define OP_CursorHint 186
#define OP_ReleaseReg 187 /* synopsis: release r[P1@P2] mask P3 */
#define OP_Noop 188
#define OP_Explain 189
#define OP_Abortable 190
/* Properties such as "out2" or "jump" that are specified in
** comments following the "case" for each opcode in the vdbe.c
** are encoded into bitvectors as follows:
*/
#define OPFLG_JUMP 0x01 /* jump: P2 holds jmp target */
#define OPFLG_IN1 0x02 /* in1: P1 is an input */
#define OPFLG_IN2 0x04 /* in2: P2 is an input */
#define OPFLG_IN3 0x08 /* in3: P3 is an input */
#define OPFLG_OUT2 0x10 /* out2: P2 is an output */
#define OPFLG_OUT3 0x20 /* out3: P3 is an output */
#define OPFLG_NCYCLE 0x40 /* ncycle:Cycles count against P1 */
#define OPFLG_JUMP0 0x80 /* jump0: P2 might be zero */
#define OPFLG_INITIALIZER {\
/* 0 */ 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x41, 0x00,\
/* 8 */ 0x81, 0x01, 0x01, 0x81, 0x83, 0x83, 0x01, 0x01,\
/* 16 */ 0x03, 0x03, 0x01, 0x12, 0x01, 0xc9, 0xc9, 0xc9,\
/* 24 */ 0xc9, 0x01, 0x49, 0x49, 0x49, 0x49, 0xc9, 0x49,\
/* 32 */ 0xc1, 0x01, 0x41, 0x41, 0xc1, 0x01, 0x01, 0x41,\
/* 40 */ 0x41, 0x41, 0x41, 0x26, 0x26, 0x41, 0x41, 0x23,\
/* 48 */ 0x0b, 0x81, 0x01, 0x03, 0x03, 0x0b, 0x0b, 0x0b,\
/* 56 */ 0x0b, 0x0b, 0x0b, 0x01, 0x03, 0x03, 0x03, 0x01,\
/* 64 */ 0x41, 0x01, 0x00, 0x00, 0x02, 0x02, 0x08, 0x00,\
/* 72 */ 0x10, 0x10, 0x10, 0x00, 0x10, 0x00, 0x10, 0x10,\
/* 80 */ 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x02,\
/* 88 */ 0x02, 0x02, 0x00, 0x00, 0x12, 0x1e, 0x20, 0x40,\
/* 96 */ 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x40, 0x26,\
/* 104 */ 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,\
/* 112 */ 0x26, 0x40, 0x00, 0x12, 0x40, 0x40, 0x10, 0x40,\
/* 120 */ 0x00, 0x00, 0x00, 0x40, 0x00, 0x40, 0x40, 0x10,\
/* 128 */ 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00,\
/* 136 */ 0x50, 0x00, 0x40, 0x04, 0x04, 0x00, 0x40, 0x50,\
/* 144 */ 0x40, 0x10, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,\
/* 152 */ 0x00, 0x00, 0x10, 0x00, 0x00, 0x06, 0x10, 0x00,\
/* 160 */ 0x04, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
/* 168 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10,\
/* 176 */ 0x50, 0x40, 0x00, 0x10, 0x10, 0x02, 0x12, 0x12,\
/* 184 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,}
/* The resolve3P2Values() routine is able to run faster if it knows
** the value of the largest JUMP opcode. The smaller the maximum
** JUMP opcode the better, so the mkopcodeh.tcl script that
** generated this include file strives to group all JUMP opcodes
** together near the beginning of the list.
*/
#define SQLITE_MX_JUMP_OPCODE 65 /* Maximum JUMP opcode */
/************** End of opcodes.h *********************************************/
/************** Continuing where we left off in vdbe.h ***********************/
/*
** Additional non-public SQLITE_PREPARE_* flags
*/
|
| ︙ | ︙ | |||
17398 17399 17400 17401 17402 17403 17404 | SQLITE_PRIVATE void sqlite3VdbeSetVarmask(Vdbe*, int); #ifndef SQLITE_OMIT_TRACE SQLITE_PRIVATE char *sqlite3VdbeExpandSql(Vdbe*, const char*); #endif SQLITE_PRIVATE int sqlite3MemCompare(const Mem*, const Mem*, const CollSeq*); SQLITE_PRIVATE int sqlite3BlobCompare(const Mem*, const Mem*); | | > > | 17449 17450 17451 17452 17453 17454 17455 17456 17457 17458 17459 17460 17461 17462 17463 17464 17465 17466 17467 17468 17469 17470 17471 17472 17473 17474 17475 17476 17477 17478 | SQLITE_PRIVATE void sqlite3VdbeSetVarmask(Vdbe*, int); #ifndef SQLITE_OMIT_TRACE SQLITE_PRIVATE char *sqlite3VdbeExpandSql(Vdbe*, const char*); #endif SQLITE_PRIVATE int sqlite3MemCompare(const Mem*, const Mem*, const CollSeq*); SQLITE_PRIVATE int sqlite3BlobCompare(const Mem*, const Mem*); SQLITE_PRIVATE void sqlite3VdbeRecordUnpack(int,const void*,UnpackedRecord*); SQLITE_PRIVATE int sqlite3VdbeRecordCompare(int,const void*,UnpackedRecord*); SQLITE_PRIVATE int sqlite3VdbeRecordCompareWithSkip(int, const void *, UnpackedRecord *, int); SQLITE_PRIVATE UnpackedRecord *sqlite3VdbeAllocUnpackedRecord(KeyInfo*); typedef int (*RecordCompare)(int,const void*,UnpackedRecord*); SQLITE_PRIVATE RecordCompare sqlite3VdbeFindCompare(UnpackedRecord*); SQLITE_PRIVATE void sqlite3VdbeLinkSubProgram(Vdbe *, SubProgram *); SQLITE_PRIVATE int sqlite3VdbeHasSubProgram(Vdbe*); SQLITE_PRIVATE void sqlite3MemSetArrayInt64(sqlite3_value *aMem, int iIdx, i64 val); #ifndef SQLITE_OMIT_DATETIME_FUNCS SQLITE_PRIVATE int sqlite3NotPureFunc(sqlite3_context*); #endif #ifdef SQLITE_ENABLE_BYTECODE_VTAB SQLITE_PRIVATE int sqlite3VdbeBytecodeVtabInit(sqlite3*); #endif /* Use SQLITE_ENABLE_EXPLAIN_COMMENTS to enable generation of extra ** comments on each VDBE opcode. ** |
| ︙ | ︙ | |||
18293 18294 18295 18296 18297 18298 18299 18300 18301 18302 18303 18304 18305 18306 | /* TH3 expects this value ^^^^^^^^^^ See flatten04.test */ #define SQLITE_IndexedExpr 0x01000000 /* Pull exprs from index when able */ #define SQLITE_Coroutines 0x02000000 /* Co-routines for subqueries */ #define SQLITE_NullUnusedCols 0x04000000 /* NULL unused columns in subqueries */ #define SQLITE_OnePass 0x08000000 /* Single-pass DELETE and UPDATE */ #define SQLITE_OrderBySubq 0x10000000 /* ORDER BY in subquery helps outer */ #define SQLITE_StarQuery 0x20000000 /* Heurists for star queries */ #define SQLITE_AllOpts 0xffffffff /* All optimizations */ /* ** Macros for testing whether or not optimizations are enabled or disabled. */ #define OptimizationDisabled(db, mask) (((db)->dbOptFlags&(mask))!=0) #define OptimizationEnabled(db, mask) (((db)->dbOptFlags&(mask))==0) | > | 18346 18347 18348 18349 18350 18351 18352 18353 18354 18355 18356 18357 18358 18359 18360 | /* TH3 expects this value ^^^^^^^^^^ See flatten04.test */ #define SQLITE_IndexedExpr 0x01000000 /* Pull exprs from index when able */ #define SQLITE_Coroutines 0x02000000 /* Co-routines for subqueries */ #define SQLITE_NullUnusedCols 0x04000000 /* NULL unused columns in subqueries */ #define SQLITE_OnePass 0x08000000 /* Single-pass DELETE and UPDATE */ #define SQLITE_OrderBySubq 0x10000000 /* ORDER BY in subquery helps outer */ #define SQLITE_StarQuery 0x20000000 /* Heurists for star queries */ #define SQLITE_ExistsToJoin 0x40000000 /* The EXISTS-to-JOIN optimization */ #define SQLITE_AllOpts 0xffffffff /* All optimizations */ /* ** Macros for testing whether or not optimizations are enabled or disabled. */ #define OptimizationDisabled(db, mask) (((db)->dbOptFlags&(mask))!=0) #define OptimizationEnabled(db, mask) (((db)->dbOptFlags&(mask))==0) |
| ︙ | ︙ | |||
18531 18532 18533 18534 18535 18536 18537 |
#define FUNCTION2(zName, nArg, iArg, bNC, xFunc, extraFlags) \
{nArg, SQLITE_FUNC_BUILTIN|\
SQLITE_FUNC_CONSTANT|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL)|extraFlags,\
SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 0, #zName, {0} }
#define STR_FUNCTION(zName, nArg, pArg, bNC, xFunc) \
{nArg, SQLITE_FUNC_BUILTIN|\
SQLITE_FUNC_SLOCHNG|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \
| | | 18585 18586 18587 18588 18589 18590 18591 18592 18593 18594 18595 18596 18597 18598 18599 |
#define FUNCTION2(zName, nArg, iArg, bNC, xFunc, extraFlags) \
{nArg, SQLITE_FUNC_BUILTIN|\
SQLITE_FUNC_CONSTANT|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL)|extraFlags,\
SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 0, #zName, {0} }
#define STR_FUNCTION(zName, nArg, pArg, bNC, xFunc) \
{nArg, SQLITE_FUNC_BUILTIN|\
SQLITE_FUNC_SLOCHNG|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \
pArg, 0, xFunc, 0, 0, 0, #zName, {0} }
#define LIKEFUNC(zName, nArg, arg, flags) \
{nArg, SQLITE_FUNC_BUILTIN|SQLITE_FUNC_CONSTANT|SQLITE_UTF8|flags, \
(void *)arg, 0, likeFunc, 0, 0, 0, #zName, {0} }
#define WAGGREGATE(zName, nArg, arg, nc, xStep, xFinal, xValue, xInverse, f) \
{nArg, SQLITE_FUNC_BUILTIN|SQLITE_UTF8|(nc*SQLITE_FUNC_NEEDCOLL)|f, \
SQLITE_INT_TO_PTR(arg), 0, xStep,xFinal,xValue,xInverse,#zName, {0}}
#define INTERNAL_FUNCTION(zName, nArg, xFunc) \
|
| ︙ | ︙ | |||
18698 18699 18700 18701 18702 18703 18704 18705 18706 18707 18708 18709 18710 18711 | #define SQLITE_AFF_NONE 0x40 /* '@' */ #define SQLITE_AFF_BLOB 0x41 /* 'A' */ #define SQLITE_AFF_TEXT 0x42 /* 'B' */ #define SQLITE_AFF_NUMERIC 0x43 /* 'C' */ #define SQLITE_AFF_INTEGER 0x44 /* 'D' */ #define SQLITE_AFF_REAL 0x45 /* 'E' */ #define SQLITE_AFF_FLEXNUM 0x46 /* 'F' */ #define sqlite3IsNumericAffinity(X) ((X)>=SQLITE_AFF_NUMERIC) /* ** The SQLITE_AFF_MASK values masks off the significant bits of an ** affinity value. */ | > | 18752 18753 18754 18755 18756 18757 18758 18759 18760 18761 18762 18763 18764 18765 18766 | #define SQLITE_AFF_NONE 0x40 /* '@' */ #define SQLITE_AFF_BLOB 0x41 /* 'A' */ #define SQLITE_AFF_TEXT 0x42 /* 'B' */ #define SQLITE_AFF_NUMERIC 0x43 /* 'C' */ #define SQLITE_AFF_INTEGER 0x44 /* 'D' */ #define SQLITE_AFF_REAL 0x45 /* 'E' */ #define SQLITE_AFF_FLEXNUM 0x46 /* 'F' */ #define SQLITE_AFF_DEFER 0x58 /* 'X' - defer computation until later */ #define sqlite3IsNumericAffinity(X) ((X)>=SQLITE_AFF_NUMERIC) /* ** The SQLITE_AFF_MASK values masks off the significant bits of an ** affinity value. */ |
| ︙ | ︙ | |||
19013 19014 19015 19016 19017 19018 19019 | /* ** An instance of the following structure is passed as the first ** argument to sqlite3VdbeKeyCompare and is used to control the ** comparison of the two index keys. ** | | | | > > > > > > | > > > > > > > > > | | < | | | | 19068 19069 19070 19071 19072 19073 19074 19075 19076 19077 19078 19079 19080 19081 19082 19083 19084 19085 19086 19087 19088 19089 19090 19091 19092 19093 19094 19095 19096 19097 19098 19099 19100 19101 19102 19103 19104 19105 19106 19107 19108 19109 19110 19111 19112 19113 19114 19115 19116 19117 19118 19119 19120 19121 19122 19123 19124 19125 19126 19127 19128 19129 19130 19131 19132 19133 19134 19135 19136 19137 19138 19139 19140 19141 19142 19143 19144 19145 19146 19147 19148 19149 19150 19151 19152 19153 19154 19155 19156 |
/*
** An instance of the following structure is passed as the first
** argument to sqlite3VdbeKeyCompare and is used to control the
** comparison of the two index keys.
**
** The aSortOrder[] and aColl[] arrays have nAllField slots each. There
** are nKeyField slots for the columns of an index then extra slots
** for the rowid or key at the end. The aSortOrder array is located after
** the aColl[] array.
**
** If SQLITE_ENABLE_PREUPDATE_HOOK is defined, then aSortFlags might be NULL
** to indicate that this object is for use by a preupdate hook. When aSortFlags
** is NULL, then nAllField is uninitialized and no space is allocated for
** aColl[], so those fields may not be used.
*/
struct KeyInfo {
u32 nRef; /* Number of references to this KeyInfo object */
u8 enc; /* Text encoding - one of the SQLITE_UTF* values */
u16 nKeyField; /* Number of key columns in the index */
u16 nAllField; /* Total columns, including key plus others */
sqlite3 *db; /* The database connection */
u8 *aSortFlags; /* Sort order for each column. */
CollSeq *aColl[FLEXARRAY]; /* Collating sequence for each term of the key */
};
/* The size (in bytes) of a KeyInfo object with up to N fields. This includes
** the main body of the KeyInfo object and the aColl[] array of N elements,
** but does not count the memory used to hold aSortFlags[]. */
#define SZ_KEYINFO(N) (offsetof(KeyInfo,aColl) + (N)*sizeof(CollSeq*))
/* The size of a bare KeyInfo with no aColl[] entries */
#if FLEXARRAY+1 > 1
# define SZ_KEYINFO_0 offsetof(KeyInfo,aColl)
#else
# define SZ_KEYINFO_0 sizeof(KeyInfo)
#endif
/*
** Allowed bit values for entries in the KeyInfo.aSortFlags[] array.
*/
#define KEYINFO_ORDER_DESC 0x01 /* DESC sort order */
#define KEYINFO_ORDER_BIGNULL 0x02 /* NULL is larger than any other value */
/*
** This object holds a record which has been parsed out into individual
** fields, for the purposes of doing a comparison.
**
** A record is an object that contains one or more fields of data.
** Records are used to store the content of a table row and to store
** the key of an index. A blob encoding of a record is created by
** the OP_MakeRecord opcode of the VDBE and is disassembled by the
** OP_Column opcode.
**
** An instance of this object serves as a "key" for doing a search on
** an index b+tree. The goal of the search is to find the entry that
** is closest to the key described by this object. This object might hold
** just a prefix of the key. The number of fields is given by nField.
**
** The r1 and r2 fields are the values to return if this key is less than
** or greater than a key in the btree, respectively. These are normally
** -1 and +1 respectively, but might be inverted to +1 and -1 if the b-tree
** is in DESC order.
**
** The key comparison functions actually return default_rc when they find
** an equals comparison. default_rc can be -1, 0, or +1. If there are
** multiple entries in the b-tree with the same key (when only looking
** at the first nField elements) then default_rc can be set to -1 to
** cause the search to find the last match, or +1 to cause the search to
** find the first match.
**
** The key comparison functions will set eqSeen to true if they ever
** get and equal results when comparing this structure to a b-tree record.
** When default_rc!=0, the search might end up on the record immediately
** before the first match or immediately after the last match. The
** eqSeen field will indicate whether or not an exact match exists in the
** b-tree.
*/
struct UnpackedRecord {
KeyInfo *pKeyInfo; /* Comparison info for the index that is unpacked */
Mem *aMem; /* Values for columns of the index */
union {
char *z; /* Cache of aMem[0].z for vdbeRecordCompareString() */
i64 i; /* Cache of aMem[0].u.i for vdbeRecordCompareInt() */
} u;
int n; /* Cache of aMem[0].n used by vdbeRecordCompareString() */
u16 nField; /* Number of entries in apMem[] */
i8 default_rc; /* Comparison result if keys are equal */
|
| ︙ | ︙ | |||
19158 19159 19160 19161 19162 19163 19164 | unsigned idxType:2; /* 0:Normal 1:UNIQUE, 2:PRIMARY KEY, 3:IPK */ unsigned bUnordered:1; /* Use this index for == or IN queries only */ unsigned uniqNotNull:1; /* True if UNIQUE and NOT NULL for all columns */ unsigned isResized:1; /* True if resizeIndexObject() has been called */ unsigned isCovering:1; /* True if this is a covering index */ unsigned noSkipScan:1; /* Do not try to use skip-scan if true */ unsigned hasStat1:1; /* aiRowLogEst values come from sqlite_stat1 */ | < < | 19227 19228 19229 19230 19231 19232 19233 19234 19235 19236 19237 19238 19239 19240 19241 19242 |
unsigned idxType:2; /* 0:Normal 1:UNIQUE, 2:PRIMARY KEY, 3:IPK */
unsigned bUnordered:1; /* Use this index for == or IN queries only */
unsigned uniqNotNull:1; /* True if UNIQUE and NOT NULL for all columns */
unsigned isResized:1; /* True if resizeIndexObject() has been called */
unsigned isCovering:1; /* True if this is a covering index */
unsigned noSkipScan:1; /* Do not try to use skip-scan if true */
unsigned hasStat1:1; /* aiRowLogEst values come from sqlite_stat1 */
unsigned bNoQuery:1; /* Do not use this index to optimize queries */
unsigned bAscKeyBug:1; /* True if the bba7b69f9849b5bf bug applies */
unsigned bHasVCol:1; /* Index references one or more VIRTUAL columns */
unsigned bHasExpr:1; /* Index contains an expression, either a literal
** expression, or a reference to a VIRTUAL column */
#ifdef SQLITE_ENABLE_STAT4
int nSample; /* Number of elements in aSample[] */
int mxSample; /* Number of slots allocated to aSample[] */
int nSampleCol; /* Size of IndexSample.anEq[] and so on */
|
| ︙ | ︙ | |||
19249 19250 19251 19252 19253 19254 19255 |
** fields do not need to be freed when deallocating the AggInfo structure.
*/
struct AggInfo {
u8 directMode; /* Direct rendering mode means take data directly
** from source tables rather than from accumulators */
u8 useSortingIdx; /* In direct mode, reference the sorting index rather
** than the source table */
| | | | | 19316 19317 19318 19319 19320 19321 19322 19323 19324 19325 19326 19327 19328 19329 19330 19331 19332 19333 19334 19335 19336 19337 19338 19339 19340 |
** fields do not need to be freed when deallocating the AggInfo structure.
*/
struct AggInfo {
u8 directMode; /* Direct rendering mode means take data directly
** from source tables rather than from accumulators */
u8 useSortingIdx; /* In direct mode, reference the sorting index rather
** than the source table */
u32 nSortingColumn; /* Number of columns in the sorting index */
int sortingIdx; /* Cursor number of the sorting index */
int sortingIdxPTab; /* Cursor number of pseudo-table */
int iFirstReg; /* First register in range for aCol[] and aFunc[] */
ExprList *pGroupBy; /* The group by clause */
struct AggInfo_col { /* For each column used in source tables */
Table *pTab; /* Source table */
Expr *pCExpr; /* The original expression */
int iTable; /* Cursor number of the source table */
int iColumn; /* Column number within the source table */
int iSorterColumn; /* Column number in the sorting index */
} *aCol;
int nColumn; /* Number of used entries in aCol[] */
int nAccumulator; /* Number of columns that show through to the output.
** Additional columns are used only as parameters to
** aggregate functions */
struct AggInfo_func { /* For each aggregate function */
Expr *pFExpr; /* Expression encoding the function */
|
| ︙ | ︙ | |||
19723 19724 19725 19726 19727 19728 19729 19730 19731 19732 19733 19734 19735 19736 |
unsigned isUsing :1; /* u3.pUsing is valid */
unsigned isOn :1; /* u3.pOn was once valid and non-NULL */
unsigned isSynthUsing :1; /* u3.pUsing is synthesized from NATURAL */
unsigned isNestedFrom :1; /* pSelect is a SF_NestedFrom subquery */
unsigned rowidUsed :1; /* The ROWID of this table is referenced */
unsigned fixedSchema :1; /* Uses u4.pSchema, not u4.zDatabase */
unsigned hadSchema :1; /* Had u4.zDatabase before u4.pSchema */
} fg;
int iCursor; /* The VDBE cursor number used to access this table */
Bitmask colUsed; /* Bit N set if column N used. Details above for N>62 */
union {
char *zIndexedBy; /* Identifier from "INDEXED BY <zIndex>" clause */
ExprList *pFuncArg; /* Arguments to table-valued-function */
u32 nRow; /* Number of rows in a VALUES clause */
| > | 19790 19791 19792 19793 19794 19795 19796 19797 19798 19799 19800 19801 19802 19803 19804 |
unsigned isUsing :1; /* u3.pUsing is valid */
unsigned isOn :1; /* u3.pOn was once valid and non-NULL */
unsigned isSynthUsing :1; /* u3.pUsing is synthesized from NATURAL */
unsigned isNestedFrom :1; /* pSelect is a SF_NestedFrom subquery */
unsigned rowidUsed :1; /* The ROWID of this table is referenced */
unsigned fixedSchema :1; /* Uses u4.pSchema, not u4.zDatabase */
unsigned hadSchema :1; /* Had u4.zDatabase before u4.pSchema */
unsigned fromExists :1; /* Comes from WHERE EXISTS(...) */
} fg;
int iCursor; /* The VDBE cursor number used to access this table */
Bitmask colUsed; /* Bit N set if column N used. Details above for N>62 */
union {
char *zIndexedBy; /* Identifier from "INDEXED BY <zIndex>" clause */
ExprList *pFuncArg; /* Arguments to table-valued-function */
u32 nRow; /* Number of rows in a VALUES clause */
|
| ︙ | ︙ | |||
20253 20254 20255 20256 20257 20258 20259 20260 20261 20262 20263 20264 20265 20266 | u8 nTempReg; /* Number of temporary registers in aTempReg[] */ u8 isMultiWrite; /* True if statement may modify/insert multiple rows */ u8 mayAbort; /* True if statement may throw an ABORT exception */ u8 hasCompound; /* Need to invoke convertCompoundSelectToSubquery() */ u8 disableLookaside; /* Number of times lookaside has been disabled */ u8 prepFlags; /* SQLITE_PREPARE_* flags */ u8 withinRJSubrtn; /* Nesting level for RIGHT JOIN body subroutines */ u8 mSubrtnSig; /* mini Bloom filter on available SubrtnSig.selId */ u8 eTriggerOp; /* TK_UPDATE, TK_INSERT or TK_DELETE */ u8 bReturning; /* Coding a RETURNING trigger */ u8 eOrconf; /* Default ON CONFLICT policy for trigger steps */ u8 disableTriggers; /* True to disable triggers */ #if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST) u8 earlyCleanup; /* OOM inside sqlite3ParserAddCleanup() */ | > | 20321 20322 20323 20324 20325 20326 20327 20328 20329 20330 20331 20332 20333 20334 20335 | u8 nTempReg; /* Number of temporary registers in aTempReg[] */ u8 isMultiWrite; /* True if statement may modify/insert multiple rows */ u8 mayAbort; /* True if statement may throw an ABORT exception */ u8 hasCompound; /* Need to invoke convertCompoundSelectToSubquery() */ u8 disableLookaside; /* Number of times lookaside has been disabled */ u8 prepFlags; /* SQLITE_PREPARE_* flags */ u8 withinRJSubrtn; /* Nesting level for RIGHT JOIN body subroutines */ u8 bHasExists; /* Has a correlated "EXISTS (SELECT ....)" expression */ u8 mSubrtnSig; /* mini Bloom filter on available SubrtnSig.selId */ u8 eTriggerOp; /* TK_UPDATE, TK_INSERT or TK_DELETE */ u8 bReturning; /* Coding a RETURNING trigger */ u8 eOrconf; /* Default ON CONFLICT policy for trigger steps */ u8 disableTriggers; /* True to disable triggers */ #if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST) u8 earlyCleanup; /* OOM inside sqlite3ParserAddCleanup() */ |
| ︙ | ︙ | |||
21249 21250 21251 21252 21253 21254 21255 21256 21257 21258 21259 21260 21261 21262 | SQLITE_PRIVATE void sqlite3ShowTrigger(const Trigger*); SQLITE_PRIVATE void sqlite3ShowTriggerList(const Trigger*); #endif #ifndef SQLITE_OMIT_WINDOWFUNC SQLITE_PRIVATE void sqlite3ShowWindow(const Window*); SQLITE_PRIVATE void sqlite3ShowWinFunc(const Window*); #endif #endif SQLITE_PRIVATE void sqlite3SetString(char **, sqlite3*, const char*); SQLITE_PRIVATE void sqlite3ProgressCheck(Parse*); SQLITE_PRIVATE void sqlite3ErrorMsg(Parse*, const char*, ...); SQLITE_PRIVATE int sqlite3ErrorToParser(sqlite3*,int); SQLITE_PRIVATE void sqlite3Dequote(char*); | > | 21318 21319 21320 21321 21322 21323 21324 21325 21326 21327 21328 21329 21330 21331 21332 | SQLITE_PRIVATE void sqlite3ShowTrigger(const Trigger*); SQLITE_PRIVATE void sqlite3ShowTriggerList(const Trigger*); #endif #ifndef SQLITE_OMIT_WINDOWFUNC SQLITE_PRIVATE void sqlite3ShowWindow(const Window*); SQLITE_PRIVATE void sqlite3ShowWinFunc(const Window*); #endif SQLITE_PRIVATE void sqlite3ShowBitvec(Bitvec*); #endif SQLITE_PRIVATE void sqlite3SetString(char **, sqlite3*, const char*); SQLITE_PRIVATE void sqlite3ProgressCheck(Parse*); SQLITE_PRIVATE void sqlite3ErrorMsg(Parse*, const char*, ...); SQLITE_PRIVATE int sqlite3ErrorToParser(sqlite3*,int); SQLITE_PRIVATE void sqlite3Dequote(char*); |
| ︙ | ︙ | |||
22422 22423 22424 22425 22426 22427 22428 22429 22430 22431 22432 22433 22434 22435 | "ATOMIC_INTRINSICS=" CTIMEOPT_VAL(SQLITE_ATOMIC_INTRINSICS), #endif #ifdef SQLITE_BITMASK_TYPE "BITMASK_TYPE=" CTIMEOPT_VAL(SQLITE_BITMASK_TYPE), #endif #ifdef SQLITE_BUG_COMPATIBLE_20160819 "BUG_COMPATIBLE_20160819", #endif #ifdef SQLITE_CASE_SENSITIVE_LIKE "CASE_SENSITIVE_LIKE", #endif #ifdef SQLITE_CHECK_PAGES "CHECK_PAGES", #endif | > > > | 22492 22493 22494 22495 22496 22497 22498 22499 22500 22501 22502 22503 22504 22505 22506 22507 22508 | "ATOMIC_INTRINSICS=" CTIMEOPT_VAL(SQLITE_ATOMIC_INTRINSICS), #endif #ifdef SQLITE_BITMASK_TYPE "BITMASK_TYPE=" CTIMEOPT_VAL(SQLITE_BITMASK_TYPE), #endif #ifdef SQLITE_BUG_COMPATIBLE_20160819 "BUG_COMPATIBLE_20160819", #endif #ifdef SQLITE_BUG_COMPATIBLE_20250510 "BUG_COMPATIBLE_20250510", #endif #ifdef SQLITE_CASE_SENSITIVE_LIKE "CASE_SENSITIVE_LIKE", #endif #ifdef SQLITE_CHECK_PAGES "CHECK_PAGES", #endif |
| ︙ | ︙ | |||
23858 23859 23860 23861 23862 23863 23864 | ** MEM_Real, and MEM_IntReal. ** ** * MEM_Blob A blob, stored in Mem.z length Mem.n. ** Incompatible with MEM_Str, MEM_Null, ** MEM_Int, MEM_Real, and MEM_IntReal. ** ** * MEM_Blob|MEM_Zero A blob in Mem.z of length Mem.n plus | | | 23931 23932 23933 23934 23935 23936 23937 23938 23939 23940 23941 23942 23943 23944 23945 | ** MEM_Real, and MEM_IntReal. ** ** * MEM_Blob A blob, stored in Mem.z length Mem.n. ** Incompatible with MEM_Str, MEM_Null, ** MEM_Int, MEM_Real, and MEM_IntReal. ** ** * MEM_Blob|MEM_Zero A blob in Mem.z of length Mem.n plus ** Mem.u.nZero extra 0x00 bytes at the end. ** ** * MEM_Int Integer stored in Mem.u.i. ** ** * MEM_Real Real stored in Mem.u.r. ** ** * MEM_IntReal Real stored as an integer in Mem.u.i. ** |
| ︙ | ︙ | |||
24127 24128 24129 24130 24131 24132 24133 | i64 iKey1; /* First key value passed to hook */ i64 iKey2; /* Second key value passed to hook */ Mem oldipk; /* Memory cell holding "old" IPK value */ Mem *aNew; /* Array of new.* values */ Table *pTab; /* Schema object being updated */ Index *pPk; /* PK index if pTab is WITHOUT ROWID */ sqlite3_value **apDflt; /* Array of default values, if required */ | | | 24200 24201 24202 24203 24204 24205 24206 24207 24208 24209 24210 24211 24212 24213 24214 | i64 iKey1; /* First key value passed to hook */ i64 iKey2; /* Second key value passed to hook */ Mem oldipk; /* Memory cell holding "old" IPK value */ Mem *aNew; /* Array of new.* values */ Table *pTab; /* Schema object being updated */ Index *pPk; /* PK index if pTab is WITHOUT ROWID */ sqlite3_value **apDflt; /* Array of default values, if required */ u8 keyinfoSpace[SZ_KEYINFO_0]; /* Space to hold pKeyinfo[0] content */ }; /* ** An instance of this object is used to pass an vector of values into ** OP_VFilter, the xFilter method of a virtual table. The vector is the ** set of values on the right-hand side of an IN constraint. ** |
| ︙ | ︙ | |||
32057 32058 32059 32060 32061 32062 32063 32064 32065 32066 32067 32068 32069 32070 |
longvalue = va_arg(ap,unsigned long int);
}
}else{
longvalue = va_arg(ap,unsigned int);
}
prefix = 0;
}
if( longvalue==0 ) flag_alternateform = 0;
if( flag_zeropad && precision<width-(prefix!=0) ){
precision = width-(prefix!=0);
}
if( precision<etBUFSIZE-10-etBUFSIZE/3 ){
nOut = etBUFSIZE;
zOut = buf;
| > > > > > > > > | 32130 32131 32132 32133 32134 32135 32136 32137 32138 32139 32140 32141 32142 32143 32144 32145 32146 32147 32148 32149 32150 32151 |
longvalue = va_arg(ap,unsigned long int);
}
}else{
longvalue = va_arg(ap,unsigned int);
}
prefix = 0;
}
#if WHERETRACE_ENABLED
if( xtype==etPOINTER && sqlite3WhereTrace & 0x100000 ) longvalue = 0;
#endif
#if TREETRACE_ENABLED
if( xtype==etPOINTER && sqlite3TreeTrace & 0x100000 ) longvalue = 0;
#endif
if( longvalue==0 ) flag_alternateform = 0;
if( flag_zeropad && precision<width-(prefix!=0) ){
precision = width-(prefix!=0);
}
if( precision<etBUFSIZE-10-etBUFSIZE/3 ){
nOut = etBUFSIZE;
zOut = buf;
|
| ︙ | ︙ | |||
32985 32986 32987 32988 32989 32990 32991 32992 32993 32994 32995 32996 32997 32998 32999 33000 33001 33002 33003 33004 33005 33006 33007 |
va_start(ap,zFormat);
sqlite3_str_vappendf(&acc, zFormat, ap);
va_end(ap);
zBuf[acc.nChar] = 0;
return zBuf;
}
/*
** This is the routine that actually formats the sqlite3_log() message.
** We house it in a separate routine from sqlite3_log() to avoid using
** stack space on small-stack systems when logging is disabled.
**
** sqlite3_log() must render into a static buffer. It cannot dynamically
** allocate memory because it might be called while the memory allocator
** mutex is held.
**
** sqlite3_str_vappendf() might ask for *temporary* memory allocations for
** certain format characters (%q) or for very large precisions or widths.
** Care must be taken that any sqlite3_log() calls that occur while the
** memory mutex is held do not use these mechanisms.
*/
static void renderLogMsg(int iErrCode, const char *zFormat, va_list ap){
StrAccum acc; /* String accumulator */
| > > > > > > > > > | | 33066 33067 33068 33069 33070 33071 33072 33073 33074 33075 33076 33077 33078 33079 33080 33081 33082 33083 33084 33085 33086 33087 33088 33089 33090 33091 33092 33093 33094 33095 33096 33097 33098 33099 33100 33101 33102 33103 33104 33105 |
va_start(ap,zFormat);
sqlite3_str_vappendf(&acc, zFormat, ap);
va_end(ap);
zBuf[acc.nChar] = 0;
return zBuf;
}
/* Maximum size of an sqlite3_log() message. */
#if defined(SQLITE_MAX_LOG_MESSAGE)
/* Leave the definition as supplied */
#elif SQLITE_PRINT_BUF_SIZE*10>10000
# define SQLITE_MAX_LOG_MESSAGE 10000
#else
# define SQLITE_MAX_LOG_MESSAGE (SQLITE_PRINT_BUF_SIZE*10)
#endif
/*
** This is the routine that actually formats the sqlite3_log() message.
** We house it in a separate routine from sqlite3_log() to avoid using
** stack space on small-stack systems when logging is disabled.
**
** sqlite3_log() must render into a static buffer. It cannot dynamically
** allocate memory because it might be called while the memory allocator
** mutex is held.
**
** sqlite3_str_vappendf() might ask for *temporary* memory allocations for
** certain format characters (%q) or for very large precisions or widths.
** Care must be taken that any sqlite3_log() calls that occur while the
** memory mutex is held do not use these mechanisms.
*/
static void renderLogMsg(int iErrCode, const char *zFormat, va_list ap){
StrAccum acc; /* String accumulator */
char zMsg[SQLITE_MAX_LOG_MESSAGE]; /* Complete log message */
sqlite3StrAccumInit(&acc, 0, zMsg, sizeof(zMsg), 0);
sqlite3_str_vappendf(&acc, zFormat, ap);
sqlite3GlobalConfig.xLog(sqlite3GlobalConfig.pLogArg, iErrCode,
sqlite3StrAccumFinish(&acc));
}
|
| ︙ | ︙ | |||
34999 35000 35001 35002 35003 35004 35005 |
*zOut++ = (u8)(c&0x00FF); \
} \
}
/*
** Write a single UTF8 character whose value is v into the
** buffer starting at zOut. zOut must be sized to hold at
| | | 35089 35090 35091 35092 35093 35094 35095 35096 35097 35098 35099 35100 35101 35102 35103 |
*zOut++ = (u8)(c&0x00FF); \
} \
}
/*
** Write a single UTF8 character whose value is v into the
** buffer starting at zOut. zOut must be sized to hold at
** least four bytes. Return the number of bytes needed
** to encode the new character.
*/
SQLITE_PRIVATE int sqlite3AppendOneUtf8Character(char *zOut, u32 v){
if( v<0x00080 ){
zOut[0] = (u8)(v & 0xff);
return 1;
}
|
| ︙ | ︙ | |||
37679 37680 37681 37682 37683 37684 37685 |
/* 30 */ "SeekRowid" OpHelp("intkey=r[P3]"),
/* 31 */ "NotExists" OpHelp("intkey=r[P3]"),
/* 32 */ "Last" OpHelp(""),
/* 33 */ "IfSizeBetween" OpHelp(""),
/* 34 */ "SorterSort" OpHelp(""),
/* 35 */ "Sort" OpHelp(""),
/* 36 */ "Rewind" OpHelp(""),
| > | | | | | < > | | | | | < > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | < > | < > | < > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | < > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 37769 37770 37771 37772 37773 37774 37775 37776 37777 37778 37779 37780 37781 37782 37783 37784 37785 37786 37787 37788 37789 37790 37791 37792 37793 37794 37795 37796 37797 37798 37799 37800 37801 37802 37803 37804 37805 37806 37807 37808 37809 37810 37811 37812 37813 37814 37815 37816 37817 37818 37819 37820 37821 37822 37823 37824 37825 37826 37827 37828 37829 37830 37831 37832 37833 37834 37835 37836 37837 37838 37839 37840 37841 37842 37843 37844 37845 37846 37847 37848 37849 37850 37851 37852 37853 37854 37855 37856 37857 37858 37859 37860 37861 37862 37863 37864 37865 37866 37867 37868 37869 37870 37871 37872 37873 37874 37875 37876 37877 37878 37879 37880 37881 37882 37883 37884 37885 37886 37887 37888 37889 37890 37891 37892 37893 37894 37895 37896 37897 37898 37899 37900 37901 37902 37903 37904 37905 37906 37907 37908 37909 37910 37911 37912 37913 37914 37915 37916 37917 37918 37919 37920 37921 37922 37923 37924 37925 37926 37927 37928 37929 37930 37931 37932 37933 37934 37935 37936 |
/* 30 */ "SeekRowid" OpHelp("intkey=r[P3]"),
/* 31 */ "NotExists" OpHelp("intkey=r[P3]"),
/* 32 */ "Last" OpHelp(""),
/* 33 */ "IfSizeBetween" OpHelp(""),
/* 34 */ "SorterSort" OpHelp(""),
/* 35 */ "Sort" OpHelp(""),
/* 36 */ "Rewind" OpHelp(""),
/* 37 */ "IfEmpty" OpHelp("if( empty(P1) ) goto P2"),
/* 38 */ "SorterNext" OpHelp(""),
/* 39 */ "Prev" OpHelp(""),
/* 40 */ "Next" OpHelp(""),
/* 41 */ "IdxLE" OpHelp("key=r[P3@P4]"),
/* 42 */ "IdxGT" OpHelp("key=r[P3@P4]"),
/* 43 */ "Or" OpHelp("r[P3]=(r[P1] || r[P2])"),
/* 44 */ "And" OpHelp("r[P3]=(r[P1] && r[P2])"),
/* 45 */ "IdxLT" OpHelp("key=r[P3@P4]"),
/* 46 */ "IdxGE" OpHelp("key=r[P3@P4]"),
/* 47 */ "RowSetRead" OpHelp("r[P3]=rowset(P1)"),
/* 48 */ "RowSetTest" OpHelp("if r[P3] in rowset(P1) goto P2"),
/* 49 */ "Program" OpHelp(""),
/* 50 */ "FkIfZero" OpHelp("if fkctr[P1]==0 goto P2"),
/* 51 */ "IsNull" OpHelp("if r[P1]==NULL goto P2"),
/* 52 */ "NotNull" OpHelp("if r[P1]!=NULL goto P2"),
/* 53 */ "Ne" OpHelp("IF r[P3]!=r[P1]"),
/* 54 */ "Eq" OpHelp("IF r[P3]==r[P1]"),
/* 55 */ "Gt" OpHelp("IF r[P3]>r[P1]"),
/* 56 */ "Le" OpHelp("IF r[P3]<=r[P1]"),
/* 57 */ "Lt" OpHelp("IF r[P3]<r[P1]"),
/* 58 */ "Ge" OpHelp("IF r[P3]>=r[P1]"),
/* 59 */ "ElseEq" OpHelp(""),
/* 60 */ "IfPos" OpHelp("if r[P1]>0 then r[P1]-=P3, goto P2"),
/* 61 */ "IfNotZero" OpHelp("if r[P1]!=0 then r[P1]--, goto P2"),
/* 62 */ "DecrJumpZero" OpHelp("if (--r[P1])==0 goto P2"),
/* 63 */ "IncrVacuum" OpHelp(""),
/* 64 */ "VNext" OpHelp(""),
/* 65 */ "Filter" OpHelp("if key(P3@P4) not in filter(P1) goto P2"),
/* 66 */ "PureFunc" OpHelp("r[P3]=func(r[P2@NP])"),
/* 67 */ "Function" OpHelp("r[P3]=func(r[P2@NP])"),
/* 68 */ "Return" OpHelp(""),
/* 69 */ "EndCoroutine" OpHelp(""),
/* 70 */ "HaltIfNull" OpHelp("if r[P3]=null halt"),
/* 71 */ "Halt" OpHelp(""),
/* 72 */ "Integer" OpHelp("r[P2]=P1"),
/* 73 */ "Int64" OpHelp("r[P2]=P4"),
/* 74 */ "String" OpHelp("r[P2]='P4' (len=P1)"),
/* 75 */ "BeginSubrtn" OpHelp("r[P2]=NULL"),
/* 76 */ "Null" OpHelp("r[P2..P3]=NULL"),
/* 77 */ "SoftNull" OpHelp("r[P1]=NULL"),
/* 78 */ "Blob" OpHelp("r[P2]=P4 (len=P1)"),
/* 79 */ "Variable" OpHelp("r[P2]=parameter(P1)"),
/* 80 */ "Move" OpHelp("r[P2@P3]=r[P1@P3]"),
/* 81 */ "Copy" OpHelp("r[P2@P3+1]=r[P1@P3+1]"),
/* 82 */ "SCopy" OpHelp("r[P2]=r[P1]"),
/* 83 */ "IntCopy" OpHelp("r[P2]=r[P1]"),
/* 84 */ "FkCheck" OpHelp(""),
/* 85 */ "ResultRow" OpHelp("output=r[P1@P2]"),
/* 86 */ "CollSeq" OpHelp(""),
/* 87 */ "AddImm" OpHelp("r[P1]=r[P1]+P2"),
/* 88 */ "RealAffinity" OpHelp(""),
/* 89 */ "Cast" OpHelp("affinity(r[P1])"),
/* 90 */ "Permutation" OpHelp(""),
/* 91 */ "Compare" OpHelp("r[P1@P3] <-> r[P2@P3]"),
/* 92 */ "IsTrue" OpHelp("r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4"),
/* 93 */ "ZeroOrNull" OpHelp("r[P2] = 0 OR NULL"),
/* 94 */ "Offset" OpHelp("r[P3] = sqlite_offset(P1)"),
/* 95 */ "Column" OpHelp("r[P3]=PX cursor P1 column P2"),
/* 96 */ "TypeCheck" OpHelp("typecheck(r[P1@P2])"),
/* 97 */ "Affinity" OpHelp("affinity(r[P1@P2])"),
/* 98 */ "MakeRecord" OpHelp("r[P3]=mkrec(r[P1@P2])"),
/* 99 */ "Count" OpHelp("r[P2]=count()"),
/* 100 */ "ReadCookie" OpHelp(""),
/* 101 */ "SetCookie" OpHelp(""),
/* 102 */ "ReopenIdx" OpHelp("root=P2 iDb=P3"),
/* 103 */ "BitAnd" OpHelp("r[P3]=r[P1]&r[P2]"),
/* 104 */ "BitOr" OpHelp("r[P3]=r[P1]|r[P2]"),
/* 105 */ "ShiftLeft" OpHelp("r[P3]=r[P2]<<r[P1]"),
/* 106 */ "ShiftRight" OpHelp("r[P3]=r[P2]>>r[P1]"),
/* 107 */ "Add" OpHelp("r[P3]=r[P1]+r[P2]"),
/* 108 */ "Subtract" OpHelp("r[P3]=r[P2]-r[P1]"),
/* 109 */ "Multiply" OpHelp("r[P3]=r[P1]*r[P2]"),
/* 110 */ "Divide" OpHelp("r[P3]=r[P2]/r[P1]"),
/* 111 */ "Remainder" OpHelp("r[P3]=r[P2]%r[P1]"),
/* 112 */ "Concat" OpHelp("r[P3]=r[P2]+r[P1]"),
/* 113 */ "OpenRead" OpHelp("root=P2 iDb=P3"),
/* 114 */ "OpenWrite" OpHelp("root=P2 iDb=P3"),
/* 115 */ "BitNot" OpHelp("r[P2]= ~r[P1]"),
/* 116 */ "OpenDup" OpHelp(""),
/* 117 */ "OpenAutoindex" OpHelp("nColumn=P2"),
/* 118 */ "String8" OpHelp("r[P2]='P4'"),
/* 119 */ "OpenEphemeral" OpHelp("nColumn=P2"),
/* 120 */ "SorterOpen" OpHelp(""),
/* 121 */ "SequenceTest" OpHelp("if( cursor[P1].ctr++ ) pc = P2"),
/* 122 */ "OpenPseudo" OpHelp("P3 columns in r[P2]"),
/* 123 */ "Close" OpHelp(""),
/* 124 */ "ColumnsUsed" OpHelp(""),
/* 125 */ "SeekScan" OpHelp("Scan-ahead up to P1 rows"),
/* 126 */ "SeekHit" OpHelp("set P2<=seekHit<=P3"),
/* 127 */ "Sequence" OpHelp("r[P2]=cursor[P1].ctr++"),
/* 128 */ "NewRowid" OpHelp("r[P2]=rowid"),
/* 129 */ "Insert" OpHelp("intkey=r[P3] data=r[P2]"),
/* 130 */ "RowCell" OpHelp(""),
/* 131 */ "Delete" OpHelp(""),
/* 132 */ "ResetCount" OpHelp(""),
/* 133 */ "SorterCompare" OpHelp("if key(P1)!=trim(r[P3],P4) goto P2"),
/* 134 */ "SorterData" OpHelp("r[P2]=data"),
/* 135 */ "RowData" OpHelp("r[P2]=data"),
/* 136 */ "Rowid" OpHelp("r[P2]=PX rowid of P1"),
/* 137 */ "NullRow" OpHelp(""),
/* 138 */ "SeekEnd" OpHelp(""),
/* 139 */ "IdxInsert" OpHelp("key=r[P2]"),
/* 140 */ "SorterInsert" OpHelp("key=r[P2]"),
/* 141 */ "IdxDelete" OpHelp("key=r[P2@P3]"),
/* 142 */ "DeferredSeek" OpHelp("Move P3 to P1.rowid if needed"),
/* 143 */ "IdxRowid" OpHelp("r[P2]=rowid"),
/* 144 */ "FinishSeek" OpHelp(""),
/* 145 */ "Destroy" OpHelp(""),
/* 146 */ "Clear" OpHelp(""),
/* 147 */ "ResetSorter" OpHelp(""),
/* 148 */ "CreateBtree" OpHelp("r[P2]=root iDb=P1 flags=P3"),
/* 149 */ "SqlExec" OpHelp(""),
/* 150 */ "ParseSchema" OpHelp(""),
/* 151 */ "LoadAnalysis" OpHelp(""),
/* 152 */ "DropTable" OpHelp(""),
/* 153 */ "DropIndex" OpHelp(""),
/* 154 */ "Real" OpHelp("r[P2]=P4"),
/* 155 */ "DropTrigger" OpHelp(""),
/* 156 */ "IntegrityCk" OpHelp(""),
/* 157 */ "RowSetAdd" OpHelp("rowset(P1)=r[P2]"),
/* 158 */ "Param" OpHelp(""),
/* 159 */ "FkCounter" OpHelp("fkctr[P1]+=P2"),
/* 160 */ "MemMax" OpHelp("r[P1]=max(r[P1],r[P2])"),
/* 161 */ "OffsetLimit" OpHelp("if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1)"),
/* 162 */ "AggInverse" OpHelp("accum=r[P3] inverse(r[P2@P5])"),
/* 163 */ "AggStep" OpHelp("accum=r[P3] step(r[P2@P5])"),
/* 164 */ "AggStep1" OpHelp("accum=r[P3] step(r[P2@P5])"),
/* 165 */ "AggValue" OpHelp("r[P3]=value N=P2"),
/* 166 */ "AggFinal" OpHelp("accum=r[P1] N=P2"),
/* 167 */ "Expire" OpHelp(""),
/* 168 */ "CursorLock" OpHelp(""),
/* 169 */ "CursorUnlock" OpHelp(""),
/* 170 */ "TableLock" OpHelp("iDb=P1 root=P2 write=P3"),
/* 171 */ "VBegin" OpHelp(""),
/* 172 */ "VCreate" OpHelp(""),
/* 173 */ "VDestroy" OpHelp(""),
/* 174 */ "VOpen" OpHelp(""),
/* 175 */ "VCheck" OpHelp(""),
/* 176 */ "VInitIn" OpHelp("r[P2]=ValueList(P1,P3)"),
/* 177 */ "VColumn" OpHelp("r[P3]=vcolumn(P2)"),
/* 178 */ "VRename" OpHelp(""),
/* 179 */ "Pagecount" OpHelp(""),
/* 180 */ "MaxPgcnt" OpHelp(""),
/* 181 */ "ClrSubtype" OpHelp("r[P1].subtype = 0"),
/* 182 */ "GetSubtype" OpHelp("r[P2] = r[P1].subtype"),
/* 183 */ "SetSubtype" OpHelp("r[P2].subtype = r[P1]"),
/* 184 */ "FilterAdd" OpHelp("filter(P1) += key(P3@P4)"),
/* 185 */ "Trace" OpHelp(""),
/* 186 */ "CursorHint" OpHelp(""),
/* 187 */ "ReleaseReg" OpHelp("release r[P1@P2] mask P3"),
/* 188 */ "Noop" OpHelp(""),
/* 189 */ "Explain" OpHelp(""),
/* 190 */ "Abortable" OpHelp(""),
};
return azName[i];
}
#endif
/************** End of opcodes.c *********************************************/
/************** Begin file os_kv.c *******************************************/
|
| ︙ | ︙ | |||
43858 43859 43860 43861 43862 43863 43864 | assert( n==1 || (flags & SQLITE_SHM_EXCLUSIVE)!=0 ); assert( pShmNode->hShm>=0 || pDbFd->pInode->bProcessLock==1 ); assert( pShmNode->hShm<0 || pDbFd->pInode->bProcessLock==0 ); /* Check that, if this to be a blocking lock, no locks that occur later ** in the following list than the lock being obtained are already held: ** | > | | | < < | | 43949 43950 43951 43952 43953 43954 43955 43956 43957 43958 43959 43960 43961 43962 43963 43964 43965 43966 43967 43968 43969 43970 43971 43972 43973 43974 43975 43976 |
assert( n==1 || (flags & SQLITE_SHM_EXCLUSIVE)!=0 );
assert( pShmNode->hShm>=0 || pDbFd->pInode->bProcessLock==1 );
assert( pShmNode->hShm<0 || pDbFd->pInode->bProcessLock==0 );
/* Check that, if this to be a blocking lock, no locks that occur later
** in the following list than the lock being obtained are already held:
**
** 1. Recovery lock (ofst==2).
** 2. Checkpointer lock (ofst==1).
** 3. Write lock (ofst==0).
** 4. Read locks (ofst>=3 && ofst<SQLITE_SHM_NLOCK).
**
** In other words, if this is a blocking lock, none of the locks that
** occur later in the above list than the lock being obtained may be
** held.
*/
#if defined(SQLITE_ENABLE_SETLK_TIMEOUT) && defined(SQLITE_DEBUG)
{
u16 lockMask = (p->exclMask|p->sharedMask);
assert( (flags & SQLITE_SHM_UNLOCK) || pDbFd->iBusyTimeout==0 || (
(ofst!=2 || lockMask==0)
&& (ofst!=1 || lockMask==0 || lockMask==2)
&& (ofst!=0 || lockMask<3)
&& (ofst<3 || lockMask<(1<<ofst))
));
}
#endif
|
| ︙ | ︙ | |||
49833 49834 49835 49836 49837 49838 49839 49840 49841 49842 49843 49844 49845 49846 49847 |
*/
if( !ret && GetLastError()==ERROR_IO_PENDING ){
DWORD nDelay = (nMs==0 ? INFINITE : nMs);
DWORD res = osWaitForSingleObject(ovlp.hEvent, nDelay);
if( res==WAIT_OBJECT_0 ){
ret = TRUE;
}else if( res==WAIT_TIMEOUT ){
rc = SQLITE_BUSY_TIMEOUT;
}else{
/* Some other error has occurred */
rc = SQLITE_IOERR_LOCK;
}
/* If it is still pending, cancel the LockFileEx() call. */
osCancelIo(hFile);
| > > > > | 49923 49924 49925 49926 49927 49928 49929 49930 49931 49932 49933 49934 49935 49936 49937 49938 49939 49940 49941 |
*/
if( !ret && GetLastError()==ERROR_IO_PENDING ){
DWORD nDelay = (nMs==0 ? INFINITE : nMs);
DWORD res = osWaitForSingleObject(ovlp.hEvent, nDelay);
if( res==WAIT_OBJECT_0 ){
ret = TRUE;
}else if( res==WAIT_TIMEOUT ){
#if SQLITE_ENABLE_SETLK_TIMEOUT==1
rc = SQLITE_BUSY_TIMEOUT;
#else
rc = SQLITE_BUSY;
#endif
}else{
/* Some other error has occurred */
rc = SQLITE_IOERR_LOCK;
}
/* If it is still pending, cancel the LockFileEx() call. */
osCancelIo(hFile);
|
| ︙ | ︙ | |||
51319 51320 51321 51322 51323 51324 51325 |
if( osIsNT() ){
#ifdef __CYGWIN__
int nChar;
LPWSTR zWideFilename;
if( osCygwin_conv_path && !(winIsDriveLetterAndColon(zFilename)
&& winIsDirSep(zFilename[2])) ){
| | | | | 51413 51414 51415 51416 51417 51418 51419 51420 51421 51422 51423 51424 51425 51426 51427 51428 51429 51430 51431 51432 51433 |
if( osIsNT() ){
#ifdef __CYGWIN__
int nChar;
LPWSTR zWideFilename;
if( osCygwin_conv_path && !(winIsDriveLetterAndColon(zFilename)
&& winIsDirSep(zFilename[2])) ){
i64 nByte;
int convertflag = CCP_POSIX_TO_WIN_W;
if( !strchr(zFilename, '/') ) convertflag |= CCP_RELATIVE;
nByte = (i64)osCygwin_conv_path(convertflag,
zFilename, 0, 0);
if( nByte>0 ){
zConverted = sqlite3MallocZero(12+(u64)nByte);
if ( zConverted==0 ){
return zConverted;
}
zWideFilename = zConverted;
/* Filenames should be prefixed, except when converted
* full path already starts with "\\?\". */
if( osCygwin_conv_path(convertflag, zFilename,
|
| ︙ | ︙ | |||
51644 51645 51646 51647 51648 51649 51650 |
|| flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED)
|| flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE) );
assert( n==1 || (flags & SQLITE_SHM_EXCLUSIVE)!=0 );
/* Check that, if this to be a blocking lock, no locks that occur later
** in the following list than the lock being obtained are already held:
**
| > | | | < < | | 51738 51739 51740 51741 51742 51743 51744 51745 51746 51747 51748 51749 51750 51751 51752 51753 51754 51755 51756 51757 51758 51759 51760 51761 51762 51763 51764 51765 |
|| flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED)
|| flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE) );
assert( n==1 || (flags & SQLITE_SHM_EXCLUSIVE)!=0 );
/* Check that, if this to be a blocking lock, no locks that occur later
** in the following list than the lock being obtained are already held:
**
** 1. Recovery lock (ofst==2).
** 2. Checkpointer lock (ofst==1).
** 3. Write lock (ofst==0).
** 4. Read locks (ofst>=3 && ofst<SQLITE_SHM_NLOCK).
**
** In other words, if this is a blocking lock, none of the locks that
** occur later in the above list than the lock being obtained may be
** held.
*/
#if defined(SQLITE_ENABLE_SETLK_TIMEOUT) && defined(SQLITE_DEBUG)
{
u16 lockMask = (p->exclMask|p->sharedMask);
assert( (flags & SQLITE_SHM_UNLOCK) || pDbFd->iBusyTimeout==0 || (
(ofst!=2 || lockMask==0)
&& (ofst!=1 || lockMask==0 || lockMask==2)
&& (ofst!=0 || lockMask<3)
&& (ofst<3 || lockMask<(1<<ofst))
));
}
#endif
|
| ︙ | ︙ | |||
52208 52209 52210 52211 52212 52213 52214 | /**************************************************************************** **************************** sqlite3_vfs methods **************************** ** ** This division contains the implementation of methods on the ** sqlite3_vfs object. */ | < < < < < < < < < < < < < < < < < < < < < | 52301 52302 52303 52304 52305 52306 52307 52308 52309 52310 52311 52312 52313 52314 |
/****************************************************************************
**************************** sqlite3_vfs methods ****************************
**
** This division contains the implementation of methods on the
** sqlite3_vfs object.
*/
/*
** This function returns non-zero if the specified UTF-8 string buffer
** ends with a directory separator character or one was successfully
** added to it.
*/
static int winMakeEndInDirSep(int nBuf, char *zBuf){
if( zBuf ){
|
| ︙ | ︙ | |||
52368 52369 52370 52371 52372 52373 52374 |
}
if( winIsDir(zConverted) ){
sqlite3_snprintf(nMax, zBuf, "%s", zDir);
sqlite3_free(zConverted);
break;
}
sqlite3_free(zConverted);
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 52440 52441 52442 52443 52444 52445 52446 52447 52448 52449 52450 52451 52452 52453 |
}
if( winIsDir(zConverted) ){
sqlite3_snprintf(nMax, zBuf, "%s", zDir);
sqlite3_free(zConverted);
break;
}
sqlite3_free(zConverted);
}
}
}
#endif
#if !SQLITE_OS_WINRT && defined(_WIN32)
else if( osIsNT() ){
|
| ︙ | ︙ | |||
53302 53303 53304 53305 53306 53307 53308 |
sqlite3_free(zDel);
winSimplifyName(zFull);
return rc;
}
}
#endif /* __CYGWIN__ */
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 53338 53339 53340 53341 53342 53343 53344 53345 53346 53347 53348 53349 53350 53351 |
sqlite3_free(zDel);
winSimplifyName(zFull);
return rc;
}
}
#endif /* __CYGWIN__ */
#if (SQLITE_OS_WINCE || SQLITE_OS_WINRT) && defined(_WIN32)
SimulateIOError( return SQLITE_ERROR );
/* WinCE has no concept of a relative pathname, or so I am told. */
/* WinRT has no way to convert a relative path to an absolute one. */
if ( sqlite3_data_directory && !winIsVerbatimPathname(zRelative) ){
/*
|
| ︙ | ︙ | |||
53475 53476 53477 53478 53479 53480 53481 |
#ifndef SQLITE_OMIT_LOAD_EXTENSION
/*
** Interfaces for opening a shared library, finding entry points
** within the shared library, and closing the shared library.
*/
static void *winDlOpen(sqlite3_vfs *pVfs, const char *zFilename){
HANDLE h;
| < < < < < < < < < < < < < < < < < < < | 53483 53484 53485 53486 53487 53488 53489 53490 53491 53492 53493 53494 53495 53496 53497 53498 |
#ifndef SQLITE_OMIT_LOAD_EXTENSION
/*
** Interfaces for opening a shared library, finding entry points
** within the shared library, and closing the shared library.
*/
static void *winDlOpen(sqlite3_vfs *pVfs, const char *zFilename){
HANDLE h;
void *zConverted = winConvertFromUtf8Filename(zFilename);
UNUSED_PARAMETER(pVfs);
if( zConverted==0 ){
OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)0));
return 0;
}
if( osIsNT() ){
#if SQLITE_OS_WINRT
h = osLoadPackagedLibrary((LPCWSTR)zConverted, 0);
|
| ︙ | ︙ | |||
54941 54942 54943 54944 54945 54946 54947 54948 54949 54950 54951 54952 54953 54954 |
/* For a BITVEC_SZ of 512, this would be 34,359,739. */
union {
BITVEC_TELEM aBitmap[BITVEC_NELEM]; /* Bitmap representation */
u32 aHash[BITVEC_NINT]; /* Hash table representation */
Bitvec *apSub[BITVEC_NPTR]; /* Recursive representation */
} u;
};
/*
** Create a new bitmap object able to handle bits between 0 and iSize,
** inclusive. Return a pointer to the new object. Return NULL if
** malloc fails.
*/
SQLITE_PRIVATE Bitvec *sqlite3BitvecCreate(u32 iSize){
| > | 54930 54931 54932 54933 54934 54935 54936 54937 54938 54939 54940 54941 54942 54943 54944 |
/* For a BITVEC_SZ of 512, this would be 34,359,739. */
union {
BITVEC_TELEM aBitmap[BITVEC_NELEM]; /* Bitmap representation */
u32 aHash[BITVEC_NINT]; /* Hash table representation */
Bitvec *apSub[BITVEC_NPTR]; /* Recursive representation */
} u;
};
/*
** Create a new bitmap object able to handle bits between 0 and iSize,
** inclusive. Return a pointer to the new object. Return NULL if
** malloc fails.
*/
SQLITE_PRIVATE Bitvec *sqlite3BitvecCreate(u32 iSize){
|
| ︙ | ︙ | |||
55051 55052 55053 55054 55055 55056 55057 |
int rc;
u32 *aiValues = sqlite3StackAllocRaw(0, sizeof(p->u.aHash));
if( aiValues==0 ){
return SQLITE_NOMEM_BKPT;
}else{
memcpy(aiValues, p->u.aHash, sizeof(p->u.aHash));
memset(p->u.apSub, 0, sizeof(p->u.apSub));
| | > > | 55041 55042 55043 55044 55045 55046 55047 55048 55049 55050 55051 55052 55053 55054 55055 55056 55057 |
int rc;
u32 *aiValues = sqlite3StackAllocRaw(0, sizeof(p->u.aHash));
if( aiValues==0 ){
return SQLITE_NOMEM_BKPT;
}else{
memcpy(aiValues, p->u.aHash, sizeof(p->u.aHash));
memset(p->u.apSub, 0, sizeof(p->u.apSub));
p->iDivisor = p->iSize/BITVEC_NPTR;
if( (p->iSize%BITVEC_NPTR)!=0 ) p->iDivisor++;
if( p->iDivisor<BITVEC_NBIT ) p->iDivisor = BITVEC_NBIT;
rc = sqlite3BitvecSet(p, i);
for(j=0; j<BITVEC_NINT; j++){
if( aiValues[j] ) rc |= sqlite3BitvecSet(p, aiValues[j]);
}
sqlite3StackFree(0, aiValues);
return rc;
}
|
| ︙ | ︙ | |||
55127 55128 55129 55130 55131 55132 55133 55134 55135 55136 55137 55138 55139 55140 55141 55142 55143 55144 55145 55146 55147 55148 55149 55150 55151 55152 55153 |
/*
** Return the value of the iSize parameter specified when Bitvec *p
** was created.
*/
SQLITE_PRIVATE u32 sqlite3BitvecSize(Bitvec *p){
return p->iSize;
}
#ifndef SQLITE_UNTESTABLE
/*
** Let V[] be an array of unsigned characters sufficient to hold
** up to N bits. Let I be an integer between 0 and N. 0<=I<N.
** Then the following macros can be used to set, clear, or test
** individual bits within V.
*/
#define SETBIT(V,I) V[I>>3] |= (1<<(I&7))
#define CLEARBIT(V,I) V[I>>3] &= ~(BITVEC_TELEM)(1<<(I&7))
#define TESTBIT(V,I) (V[I>>3]&(1<<(I&7)))!=0
/*
** This routine runs an extensive test of the Bitvec code.
**
** The input is an array of integers that acts as a program
** to test the Bitvec. The integers are opcodes followed
** by 0, 1, or 3 operands, depending on the opcode. Another
** opcode follows immediately after the last operand.
**
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > | > > > > > > > > > | | > | > > > > > > > > > > > > > > > > > > | 55119 55120 55121 55122 55123 55124 55125 55126 55127 55128 55129 55130 55131 55132 55133 55134 55135 55136 55137 55138 55139 55140 55141 55142 55143 55144 55145 55146 55147 55148 55149 55150 55151 55152 55153 55154 55155 55156 55157 55158 55159 55160 55161 55162 55163 55164 55165 55166 55167 55168 55169 55170 55171 55172 55173 55174 55175 55176 55177 55178 55179 55180 55181 55182 55183 55184 55185 55186 55187 55188 55189 55190 55191 55192 55193 55194 55195 55196 55197 55198 55199 55200 55201 55202 55203 55204 55205 55206 55207 55208 55209 55210 55211 55212 55213 55214 55215 55216 55217 55218 55219 55220 55221 55222 55223 55224 55225 55226 55227 55228 55229 55230 55231 55232 55233 55234 55235 55236 55237 55238 55239 55240 55241 55242 55243 55244 55245 55246 55247 55248 55249 55250 55251 55252 55253 55254 55255 55256 55257 55258 55259 55260 55261 55262 55263 55264 55265 55266 55267 55268 55269 55270 55271 55272 |
/*
** Return the value of the iSize parameter specified when Bitvec *p
** was created.
*/
SQLITE_PRIVATE u32 sqlite3BitvecSize(Bitvec *p){
return p->iSize;
}
#ifdef SQLITE_DEBUG
/*
** Show the content of a Bitvec option and its children. Indent
** everything by n spaces. Add x to each bitvec value.
**
** From a debugger such as gdb, one can type:
**
** call sqlite3ShowBitvec(p)
**
** For some Bitvec p and see a recursive view of the Bitvec's content.
*/
static void showBitvec(Bitvec *p, int n, unsigned x){
int i;
if( p==0 ){
printf("NULL\n");
return;
}
printf("Bitvec 0x%p iSize=%u", p, p->iSize);
if( p->iSize<=BITVEC_NBIT ){
printf(" bitmap\n");
printf("%*s bits:", n, "");
for(i=1; i<=BITVEC_NBIT; i++){
if( sqlite3BitvecTest(p,i) ) printf(" %u", x+(unsigned)i);
}
printf("\n");
}else if( p->iDivisor==0 ){
printf(" hash with %u entries\n", p->nSet);
printf("%*s bits:", n, "");
for(i=0; i<BITVEC_NINT; i++){
if( p->u.aHash[i] ) printf(" %u", x+(unsigned)p->u.aHash[i]);
}
printf("\n");
}else{
printf(" sub-bitvec with iDivisor=%u\n", p->iDivisor);
for(i=0; i<BITVEC_NPTR; i++){
if( p->u.apSub[i]==0 ) continue;
printf("%*s apSub[%d]=", n, "", i);
showBitvec(p->u.apSub[i], n+4, i*p->iDivisor);
}
}
}
SQLITE_PRIVATE void sqlite3ShowBitvec(Bitvec *p){
showBitvec(p, 0, 0);
}
#endif
#ifndef SQLITE_UNTESTABLE
/*
** Let V[] be an array of unsigned characters sufficient to hold
** up to N bits. Let I be an integer between 0 and N. 0<=I<N.
** Then the following macros can be used to set, clear, or test
** individual bits within V.
*/
#define SETBIT(V,I) V[I>>3] |= (1<<(I&7))
#define CLEARBIT(V,I) V[I>>3] &= ~(BITVEC_TELEM)(1<<(I&7))
#define TESTBIT(V,I) (V[I>>3]&(1<<(I&7)))!=0
/*
** This routine runs an extensive test of the Bitvec code.
**
** The input is an array of integers that acts as a program
** to test the Bitvec. The integers are opcodes followed
** by 0, 1, or 3 operands, depending on the opcode. Another
** opcode follows immediately after the last operand.
**
** There are opcodes numbered starting with 0. 0 is the
** "halt" opcode and causes the test to end.
**
** 0 Halt and return the number of errors
** 1 N S X Set N bits beginning with S and incrementing by X
** 2 N S X Clear N bits beginning with S and incrementing by X
** 3 N Set N randomly chosen bits
** 4 N Clear N randomly chosen bits
** 5 N S X Set N bits from S increment X in array only, not in bitvec
** 6 Invoice sqlite3ShowBitvec() on the Bitvec object so far
** 7 X Show compile-time parameters and the hash of X
**
** The opcodes 1 through 4 perform set and clear operations are performed
** on both a Bitvec object and on a linear array of bits obtained from malloc.
** Opcode 5 works on the linear array only, not on the Bitvec.
** Opcode 5 is used to deliberately induce a fault in order to
** confirm that error detection works. Opcodes 6 and greater are
** state output opcodes. Opcodes 6 and greater are no-ops unless
** SQLite has been compiled with SQLITE_DEBUG.
**
** At the conclusion of the test the linear array is compared
** against the Bitvec object. If there are any differences,
** an error is returned. If they are the same, zero is returned.
**
** If a memory allocation error occurs, return -1.
**
** sz is the size of the Bitvec. Or if sz is negative, make the size
** 2*(unsigned)(-sz) and disabled the linear vector check.
*/
SQLITE_PRIVATE int sqlite3BitvecBuiltinTest(int sz, int *aOp){
Bitvec *pBitvec = 0;
unsigned char *pV = 0;
int rc = -1;
int i, nx, pc, op;
void *pTmpSpace;
/* Allocate the Bitvec to be tested and a linear array of
** bits to act as the reference */
if( sz<=0 ){
pBitvec = sqlite3BitvecCreate( 2*(unsigned)(-sz) );
pV = 0;
}else{
pBitvec = sqlite3BitvecCreate( sz );
pV = sqlite3MallocZero( (7+(i64)sz)/8 + 1 );
}
pTmpSpace = sqlite3_malloc64(BITVEC_SZ);
if( pBitvec==0 || pTmpSpace==0 || (pV==0 && sz>0) ) goto bitvec_end;
/* NULL pBitvec tests */
sqlite3BitvecSet(0, 1);
sqlite3BitvecClear(0, 1, pTmpSpace);
/* Run the program */
pc = i = 0;
while( (op = aOp[pc])!=0 ){
if( op>=6 ){
#ifdef SQLITE_DEBUG
if( op==6 ){
sqlite3ShowBitvec(pBitvec);
}else if( op==7 ){
printf("BITVEC_SZ = %d (%d by sizeof)\n",
BITVEC_SZ, (int)sizeof(Bitvec));
printf("BITVEC_USIZE = %d\n", (int)BITVEC_USIZE);
printf("BITVEC_NELEM = %d\n", (int)BITVEC_NELEM);
printf("BITVEC_NBIT = %d\n", (int)BITVEC_NBIT);
printf("BITVEC_NINT = %d\n", (int)BITVEC_NINT);
printf("BITVEC_MXHASH = %d\n", (int)BITVEC_MXHASH);
printf("BITVEC_NPTR = %d\n", (int)BITVEC_NPTR);
}
#endif
pc++;
continue;
}
switch( op ){
case 1:
case 2:
case 5: {
nx = 4;
i = aOp[pc+2] - 1;
aOp[pc+2] += aOp[pc+3];
|
| ︙ | ︙ | |||
55211 55212 55213 55214 55215 55216 55217 |
break;
}
}
if( (--aOp[pc+1]) > 0 ) nx = 0;
pc += nx;
i = (i & 0x7fffffff)%sz;
if( (op & 1)!=0 ){
| | | > | | | | | | | | > > > | 55280 55281 55282 55283 55284 55285 55286 55287 55288 55289 55290 55291 55292 55293 55294 55295 55296 55297 55298 55299 55300 55301 55302 55303 55304 55305 55306 55307 55308 55309 55310 55311 55312 55313 55314 55315 55316 55317 55318 55319 55320 |
break;
}
}
if( (--aOp[pc+1]) > 0 ) nx = 0;
pc += nx;
i = (i & 0x7fffffff)%sz;
if( (op & 1)!=0 ){
if( pV ) SETBIT(pV, (i+1));
if( op!=5 ){
if( sqlite3BitvecSet(pBitvec, i+1) ) goto bitvec_end;
}
}else{
if( pV ) CLEARBIT(pV, (i+1));
sqlite3BitvecClear(pBitvec, i+1, pTmpSpace);
}
}
/* Test to make sure the linear array exactly matches the
** Bitvec object. Start with the assumption that they do
** match (rc==0). Change rc to non-zero if a discrepancy
** is found.
*/
if( pV ){
rc = sqlite3BitvecTest(0,0) + sqlite3BitvecTest(pBitvec, sz+1)
+ sqlite3BitvecTest(pBitvec, 0)
+ (sqlite3BitvecSize(pBitvec) - sz);
for(i=1; i<=sz; i++){
if( (TESTBIT(pV,i))!=sqlite3BitvecTest(pBitvec,i) ){
rc = i;
break;
}
}
}else{
rc = 0;
}
/* Free allocated structure */
bitvec_end:
sqlite3_free(pTmpSpace);
sqlite3_free(pV);
sqlite3BitvecDestroy(pBitvec);
|
| ︙ | ︙ | |||
58837 58838 58839 58840 58841 58842 58843 58844 58845 58846 58847 58848 58849 58850 | void (*xReiniter)(DbPage*); /* Call this routine when reloading pages */ int (*xGet)(Pager*,Pgno,DbPage**,int); /* Routine to fetch a patch */ char *pTmpSpace; /* Pager.pageSize bytes of space for tmp use */ PCache *pPCache; /* Pointer to page cache object */ #ifndef SQLITE_OMIT_WAL Wal *pWal; /* Write-ahead log used by "journal_mode=wal" */ char *zWal; /* File name for write-ahead log */ #endif }; /* ** Indexes for use with Pager.aStat[]. The Pager.aStat[] array contains ** the values accessed by passing SQLITE_DBSTATUS_CACHE_HIT, CACHE_MISS ** or CACHE_WRITE to sqlite3_db_status(). | > > > | 58910 58911 58912 58913 58914 58915 58916 58917 58918 58919 58920 58921 58922 58923 58924 58925 58926 | void (*xReiniter)(DbPage*); /* Call this routine when reloading pages */ int (*xGet)(Pager*,Pgno,DbPage**,int); /* Routine to fetch a patch */ char *pTmpSpace; /* Pager.pageSize bytes of space for tmp use */ PCache *pPCache; /* Pointer to page cache object */ #ifndef SQLITE_OMIT_WAL Wal *pWal; /* Write-ahead log used by "journal_mode=wal" */ char *zWal; /* File name for write-ahead log */ #endif #ifdef SQLITE_ENABLE_SETLK_TIMEOUT sqlite3 *dbWal; #endif }; /* ** Indexes for use with Pager.aStat[]. The Pager.aStat[] array contains ** the values accessed by passing SQLITE_DBSTATUS_CACHE_HIT, CACHE_MISS ** or CACHE_WRITE to sqlite3_db_status(). |
| ︙ | ︙ | |||
65719 65720 65721 65722 65723 65724 65725 65726 65727 65728 65729 65730 65731 65732 |
** (e.g. due to malloc() failure), return an error code.
*/
if( rc==SQLITE_OK ){
rc = sqlite3WalOpen(pPager->pVfs,
pPager->fd, pPager->zWal, pPager->exclusiveMode,
pPager->journalSizeLimit, &pPager->pWal
);
}
pagerFixMaplimit(pPager);
return rc;
}
| > > > > > | 65795 65796 65797 65798 65799 65800 65801 65802 65803 65804 65805 65806 65807 65808 65809 65810 65811 65812 65813 |
** (e.g. due to malloc() failure), return an error code.
*/
if( rc==SQLITE_OK ){
rc = sqlite3WalOpen(pPager->pVfs,
pPager->fd, pPager->zWal, pPager->exclusiveMode,
pPager->journalSizeLimit, &pPager->pWal
);
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
if( rc==SQLITE_OK ){
sqlite3WalDb(pPager->pWal, pPager->dbWal);
}
#endif
}
pagerFixMaplimit(pPager);
return rc;
}
|
| ︙ | ︙ | |||
65838 65839 65840 65841 65842 65843 65844 65845 65846 65847 65848 65849 65850 65851 |
}
/*
** Set the database handle used by the wal layer to determine if
** blocking locks are required.
*/
SQLITE_PRIVATE void sqlite3PagerWalDb(Pager *pPager, sqlite3 *db){
if( pagerUseWal(pPager) ){
sqlite3WalDb(pPager->pWal, db);
}
}
#endif
#ifdef SQLITE_ENABLE_SNAPSHOT
| > | 65919 65920 65921 65922 65923 65924 65925 65926 65927 65928 65929 65930 65931 65932 65933 |
}
/*
** Set the database handle used by the wal layer to determine if
** blocking locks are required.
*/
SQLITE_PRIVATE void sqlite3PagerWalDb(Pager *pPager, sqlite3 *db){
pPager->dbWal = db;
if( pagerUseWal(pPager) ){
sqlite3WalDb(pPager->pWal, db);
}
}
#endif
#ifdef SQLITE_ENABLE_SNAPSHOT
|
| ︙ | ︙ | |||
69011 69012 69013 69014 69015 69016 69017 |
if( !useWal ){
assert( rc==SQLITE_OK );
if( pWal->bShmUnreliable==0 ){
rc = walIndexReadHdr(pWal, pChanged);
}
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
| < > > | 69093 69094 69095 69096 69097 69098 69099 69100 69101 69102 69103 69104 69105 69106 69107 69108 69109 69110 69111 69112 69113 69114 69115 69116 69117 69118 69119 69120 69121 69122 69123 69124 69125 69126 69127 69128 69129 69130 69131 69132 69133 69134 69135 69136 69137 69138 |
if( !useWal ){
assert( rc==SQLITE_OK );
if( pWal->bShmUnreliable==0 ){
rc = walIndexReadHdr(pWal, pChanged);
}
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
if( rc==SQLITE_BUSY_TIMEOUT ){
rc = SQLITE_BUSY;
*pCnt |= WAL_RETRY_BLOCKED_MASK;
}
#endif
if( rc==SQLITE_BUSY ){
/* If there is not a recovery running in another thread or process
** then convert BUSY errors to WAL_RETRY. If recovery is known to
** be running, convert BUSY to BUSY_RECOVERY. There is a race here
** which might cause WAL_RETRY to be returned even if BUSY_RECOVERY
** would be technically correct. But the race is benign since with
** WAL_RETRY this routine will be called again and will probably be
** right on the second iteration.
*/
(void)walEnableBlocking(pWal);
if( pWal->apWiData[0]==0 ){
/* This branch is taken when the xShmMap() method returns SQLITE_BUSY.
** We assume this is a transient condition, so return WAL_RETRY. The
** xShmMap() implementation used by the default unix and win32 VFS
** modules may return SQLITE_BUSY due to a race condition in the
** code that determines whether or not the shared-memory region
** must be zeroed before the requested page is returned.
*/
rc = WAL_RETRY;
}else if( SQLITE_OK==(rc = walLockShared(pWal, WAL_RECOVER_LOCK)) ){
walUnlockShared(pWal, WAL_RECOVER_LOCK);
rc = WAL_RETRY;
}else if( rc==SQLITE_BUSY ){
rc = SQLITE_BUSY_RECOVERY;
}
}
walDisableBlocking(pWal);
if( rc!=SQLITE_OK ){
return rc;
}
else if( pWal->bShmUnreliable ){
return walBeginShmUnreliable(pWal, pChanged);
}
}
|
| ︙ | ︙ | |||
69729 69730 69731 69732 69733 69734 69735 69736 69737 69738 69739 69740 69741 69742 |
*/
assert( walFramePgno(pWal, iFrame)!=1 );
rc = xUndo(pUndoCtx, walFramePgno(pWal, iFrame));
}
if( iMax!=pWal->hdr.mxFrame ) walCleanupHash(pWal);
}
SEH_EXCEPT( rc = SQLITE_IOERR_IN_PAGE; )
}
return rc;
}
/*
** Argument aWalData must point to an array of WAL_SAVEPOINT_NDATA u32
** values. This function populates the array with values required to
| > | 69812 69813 69814 69815 69816 69817 69818 69819 69820 69821 69822 69823 69824 69825 69826 |
*/
assert( walFramePgno(pWal, iFrame)!=1 );
rc = xUndo(pUndoCtx, walFramePgno(pWal, iFrame));
}
if( iMax!=pWal->hdr.mxFrame ) walCleanupHash(pWal);
}
SEH_EXCEPT( rc = SQLITE_IOERR_IN_PAGE; )
pWal->iReCksum = 0;
}
return rc;
}
/*
** Argument aWalData must point to an array of WAL_SAVEPOINT_NDATA u32
** values. This function populates the array with values required to
|
| ︙ | ︙ | |||
69776 69777 69778 69779 69780 69781 69782 69783 69784 69785 69786 69787 69788 69789 |
pWal->hdr.mxFrame = aWalData[0];
pWal->hdr.aFrameCksum[0] = aWalData[1];
pWal->hdr.aFrameCksum[1] = aWalData[2];
SEH_TRY {
walCleanupHash(pWal);
}
SEH_EXCEPT( rc = SQLITE_IOERR_IN_PAGE; )
}
return rc;
}
/*
** This function is called just before writing a set of frames to the log
| > > > | 69860 69861 69862 69863 69864 69865 69866 69867 69868 69869 69870 69871 69872 69873 69874 69875 69876 |
pWal->hdr.mxFrame = aWalData[0];
pWal->hdr.aFrameCksum[0] = aWalData[1];
pWal->hdr.aFrameCksum[1] = aWalData[2];
SEH_TRY {
walCleanupHash(pWal);
}
SEH_EXCEPT( rc = SQLITE_IOERR_IN_PAGE; )
if( pWal->iReCksum>pWal->hdr.mxFrame ){
pWal->iReCksum = 0;
}
}
return rc;
}
/*
** This function is called just before writing a set of frames to the log
|
| ︙ | ︙ | |||
72491 72492 72493 72494 72495 72496 72497 |
UnpackedRecord *pIdxKey; /* Unpacked index key */
if( pKey ){
KeyInfo *pKeyInfo = pCur->pKeyInfo;
assert( nKey==(i64)(int)nKey );
pIdxKey = sqlite3VdbeAllocUnpackedRecord(pKeyInfo);
if( pIdxKey==0 ) return SQLITE_NOMEM_BKPT;
| | | 72578 72579 72580 72581 72582 72583 72584 72585 72586 72587 72588 72589 72590 72591 72592 |
UnpackedRecord *pIdxKey; /* Unpacked index key */
if( pKey ){
KeyInfo *pKeyInfo = pCur->pKeyInfo;
assert( nKey==(i64)(int)nKey );
pIdxKey = sqlite3VdbeAllocUnpackedRecord(pKeyInfo);
if( pIdxKey==0 ) return SQLITE_NOMEM_BKPT;
sqlite3VdbeRecordUnpack((int)nKey, pKey, pIdxKey);
if( pIdxKey->nField==0 || pIdxKey->nField>pKeyInfo->nAllField ){
rc = SQLITE_CORRUPT_BKPT;
}else{
rc = sqlite3BtreeIndexMoveto(pCur, pIdxKey, pRes);
}
sqlite3DbFree(pCur->pKeyInfo->db, pIdxKey);
}else{
|
| ︙ | ︙ | |||
73548 73549 73550 73551 73552 73553 73554 | int iEnd = iStart + iSize; /* First byte past the iStart buffer */ unsigned char *data = pPage->aData; /* Page content */ u8 *pTmp; /* Temporary ptr into data[] */ assert( pPage->pBt!=0 ); assert( sqlite3PagerIswriteable(pPage->pDbPage) ); assert( CORRUPT_DB || iStart>=pPage->hdrOffset+6+pPage->childPtrSize ); | | | | 73635 73636 73637 73638 73639 73640 73641 73642 73643 73644 73645 73646 73647 73648 73649 73650 73651 73652 |
int iEnd = iStart + iSize; /* First byte past the iStart buffer */
unsigned char *data = pPage->aData; /* Page content */
u8 *pTmp; /* Temporary ptr into data[] */
assert( pPage->pBt!=0 );
assert( sqlite3PagerIswriteable(pPage->pDbPage) );
assert( CORRUPT_DB || iStart>=pPage->hdrOffset+6+pPage->childPtrSize );
assert( CORRUPT_DB || iEnd <= (int)pPage->pBt->usableSize );
assert( sqlite3_mutex_held(pPage->pBt->mutex) );
assert( iSize>=4 ); /* Minimum cell size is 4 */
assert( CORRUPT_DB || iStart<=(int)pPage->pBt->usableSize-4 );
/* The list of freeblocks must be in ascending order. Find the
** spot on the list where iStart should be inserted.
*/
hdr = pPage->hdrOffset;
iPtr = hdr + 1;
if( data[iPtr+1]==0 && data[iPtr]==0 ){
|
| ︙ | ︙ | |||
74475 74476 74477 74478 74479 74480 74481 74482 74483 74484 74485 74486 74487 74488 |
sqlite3_mutex_free(pBt->mutex);
}
removed = 1;
}
sqlite3_mutex_leave(pMainMtx);
return removed;
#else
return 1;
#endif
}
/*
** Make sure pBt->pTmpSpace points to an allocation of
** MX_CELL_SIZE(pBt) bytes with a 4-byte prefix for a left-child
| > | 74562 74563 74564 74565 74566 74567 74568 74569 74570 74571 74572 74573 74574 74575 74576 |
sqlite3_mutex_free(pBt->mutex);
}
removed = 1;
}
sqlite3_mutex_leave(pMainMtx);
return removed;
#else
UNUSED_PARAMETER( pBt );
return 1;
#endif
}
/*
** Make sure pBt->pTmpSpace points to an allocation of
** MX_CELL_SIZE(pBt) bytes with a 4-byte prefix for a left-child
|
| ︙ | ︙ | |||
74692 74693 74694 74695 74696 74697 74698 74699 74700 74701 74702 74703 74704 74705 |
int rc = SQLITE_OK;
int x;
BtShared *pBt = p->pBt;
assert( nReserve>=0 && nReserve<=255 );
sqlite3BtreeEnter(p);
pBt->nReserveWanted = (u8)nReserve;
x = pBt->pageSize - pBt->usableSize;
if( nReserve<x ) nReserve = x;
if( pBt->btsFlags & BTS_PAGESIZE_FIXED ){
sqlite3BtreeLeave(p);
return SQLITE_READONLY;
}
assert( nReserve>=0 && nReserve<=255 );
if( pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE &&
| > > > > | 74780 74781 74782 74783 74784 74785 74786 74787 74788 74789 74790 74791 74792 74793 74794 74795 74796 74797 |
int rc = SQLITE_OK;
int x;
BtShared *pBt = p->pBt;
assert( nReserve>=0 && nReserve<=255 );
sqlite3BtreeEnter(p);
pBt->nReserveWanted = (u8)nReserve;
x = pBt->pageSize - pBt->usableSize;
if( x==nReserve && (pageSize==0 || (u32)pageSize==pBt->pageSize) ){
sqlite3BtreeLeave(p);
return SQLITE_OK;
}
if( nReserve<x ) nReserve = x;
if( pBt->btsFlags & BTS_PAGESIZE_FIXED ){
sqlite3BtreeLeave(p);
return SQLITE_READONLY;
}
assert( nReserve>=0 && nReserve<=255 );
if( pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE &&
|
| ︙ | ︙ | |||
75316 75317 75318 75319 75320 75321 75322 75323 75324 75325 75326 75327 75328 75329 |
}
}
if( rc!=SQLITE_OK ){
(void)sqlite3PagerWalWriteLock(pPager, 0);
unlockBtreeIfUnused(pBt);
}
}while( (rc&0xFF)==SQLITE_BUSY && pBt->inTransaction==TRANS_NONE &&
btreeInvokeBusyHandler(pBt) );
sqlite3PagerWalDb(pPager, 0);
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
if( rc==SQLITE_BUSY_TIMEOUT ) rc = SQLITE_BUSY;
#endif
| > > > > > > > | 75408 75409 75410 75411 75412 75413 75414 75415 75416 75417 75418 75419 75420 75421 75422 75423 75424 75425 75426 75427 75428 |
}
}
if( rc!=SQLITE_OK ){
(void)sqlite3PagerWalWriteLock(pPager, 0);
unlockBtreeIfUnused(pBt);
}
#if defined(SQLITE_ENABLE_SETLK_TIMEOUT)
if( rc==SQLITE_BUSY_TIMEOUT ){
/* If a blocking lock timed out, break out of the loop here so that
** the busy-handler is not invoked. */
break;
}
#endif
}while( (rc&0xFF)==SQLITE_BUSY && pBt->inTransaction==TRANS_NONE &&
btreeInvokeBusyHandler(pBt) );
sqlite3PagerWalDb(pPager, 0);
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
if( rc==SQLITE_BUSY_TIMEOUT ) rc = SQLITE_BUSY;
#endif
|
| ︙ | ︙ | |||
77273 77274 77275 77276 77277 77278 77279 77280 77281 77282 77283 77284 77285 77286 |
}else if( rc==SQLITE_EMPTY ){
assert( pCur->pgnoRoot==0 || (pCur->pPage!=0 && pCur->pPage->nCell==0) );
*pRes = 1;
rc = SQLITE_OK;
}
return rc;
}
#ifdef SQLITE_DEBUG
/* The cursors is CURSOR_VALID and has BTCF_AtLast set. Verify that
** this flags are true for a consistent database.
**
** This routine is is called from within assert() statements only.
** It is an internal verification routine and does not appear in production
| > > > > > > > > > > > > > > > > > > > > > > > > | 77372 77373 77374 77375 77376 77377 77378 77379 77380 77381 77382 77383 77384 77385 77386 77387 77388 77389 77390 77391 77392 77393 77394 77395 77396 77397 77398 77399 77400 77401 77402 77403 77404 77405 77406 77407 77408 77409 |
}else if( rc==SQLITE_EMPTY ){
assert( pCur->pgnoRoot==0 || (pCur->pPage!=0 && pCur->pPage->nCell==0) );
*pRes = 1;
rc = SQLITE_OK;
}
return rc;
}
/* Set *pRes to 1 (true) if the BTree pointed to by cursor pCur contains zero
** rows of content. Set *pRes to 0 (false) if the table contains content.
** Return SQLITE_OK on success or some error code (ex: SQLITE_NOMEM) if
** something goes wrong.
*/
SQLITE_PRIVATE int sqlite3BtreeIsEmpty(BtCursor *pCur, int *pRes){
int rc;
assert( cursorOwnsBtShared(pCur) );
assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
if( pCur->eState==CURSOR_VALID ){
*pRes = 0;
return SQLITE_OK;
}
rc = moveToRoot(pCur);
if( rc==SQLITE_EMPTY ){
*pRes = 1;
rc = SQLITE_OK;
}else{
*pRes = 0;
}
return rc;
}
#ifdef SQLITE_DEBUG
/* The cursors is CURSOR_VALID and has BTCF_AtLast set. Verify that
** this flags are true for a consistent database.
**
** This routine is is called from within assert() statements only.
** It is an internal verification routine and does not appear in production
|
| ︙ | ︙ | |||
77493 77494 77495 77496 77497 77498 77499 | moveto_table_finish: pCur->info.nSize = 0; assert( (pCur->curFlags & BTCF_ValidOvfl)==0 ); return rc; } /* | | | | < | 77616 77617 77618 77619 77620 77621 77622 77623 77624 77625 77626 77627 77628 77629 77630 77631 77632 77633 77634 77635 77636 77637 77638 77639 77640 77641 77642 77643 77644 77645 77646 77647 77648 77649 77650 |
moveto_table_finish:
pCur->info.nSize = 0;
assert( (pCur->curFlags & BTCF_ValidOvfl)==0 );
return rc;
}
/*
** Compare the "idx"-th cell on the page pPage against the key
** pointing to by pIdxKey using xRecordCompare. Return negative or
** zero if the cell is less than or equal pIdxKey. Return positive
** if unknown.
**
** Return value negative: Cell at pCur[idx] less than pIdxKey
**
** Return value is zero: Cell at pCur[idx] equals pIdxKey
**
** Return value positive: Nothing is known about the relationship
** of the cell at pCur[idx] and pIdxKey.
**
** This routine is part of an optimization. It is always safe to return
** a positive value as that will cause the optimization to be skipped.
*/
static int indexCellCompare(
MemPage *pPage,
int idx,
UnpackedRecord *pIdxKey,
RecordCompare xRecordCompare
){
int c;
int nCell; /* Size of the pCell cell in bytes */
u8 *pCell = findCellPastPtr(pPage, idx);
nCell = pCell[0];
if( nCell<=pPage->max1bytePayload ){
/* This branch runs if the record-size field of the cell is a
|
| ︙ | ︙ | |||
77623 77624 77625 77626 77627 77628 77629 |
*/
if( pCur->eState==CURSOR_VALID
&& pCur->pPage->leaf
&& cursorOnLastPage(pCur)
){
int c;
if( pCur->ix==pCur->pPage->nCell-1
| | | | 77745 77746 77747 77748 77749 77750 77751 77752 77753 77754 77755 77756 77757 77758 77759 77760 77761 77762 77763 77764 77765 77766 |
*/
if( pCur->eState==CURSOR_VALID
&& pCur->pPage->leaf
&& cursorOnLastPage(pCur)
){
int c;
if( pCur->ix==pCur->pPage->nCell-1
&& (c = indexCellCompare(pCur->pPage,pCur->ix,pIdxKey,xRecordCompare))<=0
&& pIdxKey->errCode==SQLITE_OK
){
*pRes = c;
return SQLITE_OK; /* Cursor already pointing at the correct spot */
}
if( pCur->iPage>0
&& indexCellCompare(pCur->pPage, 0, pIdxKey, xRecordCompare)<=0
&& pIdxKey->errCode==SQLITE_OK
){
pCur->curFlags &= ~(BTCF_ValidOvfl|BTCF_AtLast);
if( !pCur->pPage->isInit ){
return SQLITE_CORRUPT_BKPT;
}
goto bypass_moveto_root; /* Start search on the current page */
|
| ︙ | ︙ | |||
77847 77848 77849 77850 77851 77852 77853 |
** opcode and the OP_Count opcode with P3=1. In either case,
** the cursor will always be valid unless the btree is empty. */
if( pCur->eState!=CURSOR_VALID ) return 0;
if( NEVER(pCur->pPage->leaf==0) ) return -1;
n = pCur->pPage->nCell;
for(i=0; i<pCur->iPage; i++){
| | | 77969 77970 77971 77972 77973 77974 77975 77976 77977 77978 77979 77980 77981 77982 77983 |
** opcode and the OP_Count opcode with P3=1. In either case,
** the cursor will always be valid unless the btree is empty. */
if( pCur->eState!=CURSOR_VALID ) return 0;
if( NEVER(pCur->pPage->leaf==0) ) return -1;
n = pCur->pPage->nCell;
for(i=0; i<pCur->iPage; i++){
n *= pCur->apPage[i]->nCell+1;
}
return n;
}
/*
** Advance the cursor to the next entry in the database.
** Return value:
|
| ︙ | ︙ | |||
80304 80305 80306 80307 80308 80309 80310 |
assert( apNew[nNew-1]!=0 );
put4byte(pRight, apNew[nNew-1]->pgno);
/* If the sibling pages are not leaves, ensure that the right-child pointer
** of the right-most new sibling page is set to the value that was
** originally in the same field of the right-most old sibling page. */
if( (pageFlags & PTF_LEAF)==0 && nOld!=nNew ){
| | > > > > > | 80426 80427 80428 80429 80430 80431 80432 80433 80434 80435 80436 80437 80438 80439 80440 80441 80442 80443 80444 80445 |
assert( apNew[nNew-1]!=0 );
put4byte(pRight, apNew[nNew-1]->pgno);
/* If the sibling pages are not leaves, ensure that the right-child pointer
** of the right-most new sibling page is set to the value that was
** originally in the same field of the right-most old sibling page. */
if( (pageFlags & PTF_LEAF)==0 && nOld!=nNew ){
MemPage *pOld;
if( nNew>nOld ){
pOld = apNew[nOld-1];
}else{
pOld = apOld[nOld-1];
}
memcpy(&apNew[nNew-1]->aData[8], &pOld->aData[8], 4);
}
/* Make any required updates to pointer map entries associated with
** cells stored on sibling pages following the balance operation. Pointer
** map entries associated with divider cells are set by the insertCell()
** routine. The associated pointer map entries are:
|
| ︙ | ︙ | |||
82936 82937 82938 82939 82940 82941 82942 82943 82944 82945 82946 82947 82948 82949 |
/*
** Return SQLITE_LOCKED_SHAREDCACHE if another user of the same shared
** btree as the argument handle holds an exclusive lock on the
** sqlite_schema table. Otherwise SQLITE_OK.
*/
SQLITE_PRIVATE int sqlite3BtreeSchemaLocked(Btree *p){
int rc;
assert( sqlite3_mutex_held(p->db->mutex) );
sqlite3BtreeEnter(p);
rc = querySharedCacheTableLock(p, SCHEMA_ROOT, READ_LOCK);
assert( rc==SQLITE_OK || rc==SQLITE_LOCKED_SHAREDCACHE );
sqlite3BtreeLeave(p);
return rc;
}
| > | 83063 83064 83065 83066 83067 83068 83069 83070 83071 83072 83073 83074 83075 83076 83077 |
/*
** Return SQLITE_LOCKED_SHAREDCACHE if another user of the same shared
** btree as the argument handle holds an exclusive lock on the
** sqlite_schema table. Otherwise SQLITE_OK.
*/
SQLITE_PRIVATE int sqlite3BtreeSchemaLocked(Btree *p){
int rc;
UNUSED_PARAMETER(p); /* only used in DEBUG builds */
assert( sqlite3_mutex_held(p->db->mutex) );
sqlite3BtreeEnter(p);
rc = querySharedCacheTableLock(p, SCHEMA_ROOT, READ_LOCK);
assert( rc==SQLITE_OK || rc==SQLITE_LOCKED_SHAREDCACHE );
sqlite3BtreeLeave(p);
return rc;
}
|
| ︙ | ︙ | |||
87260 87261 87262 87263 87264 87265 87266 87267 87268 87269 87270 87271 87272 87273 |
/*
** If the previous opcode is an OP_Column that delivers results
** into register iDest, then add the OPFLAG_TYPEOFARG flag to that
** opcode.
*/
SQLITE_PRIVATE void sqlite3VdbeTypeofColumn(Vdbe *p, int iDest){
VdbeOp *pOp = sqlite3VdbeGetLastOp(p);
if( pOp->p3==iDest && pOp->opcode==OP_Column ){
pOp->p5 |= OPFLAG_TYPEOFARG;
}
}
/*
** Change the P2 operand of instruction addr so that it points to
| > > > | 87388 87389 87390 87391 87392 87393 87394 87395 87396 87397 87398 87399 87400 87401 87402 87403 87404 |
/*
** If the previous opcode is an OP_Column that delivers results
** into register iDest, then add the OPFLAG_TYPEOFARG flag to that
** opcode.
*/
SQLITE_PRIVATE void sqlite3VdbeTypeofColumn(Vdbe *p, int iDest){
VdbeOp *pOp = sqlite3VdbeGetLastOp(p);
#ifdef SQLITE_DEBUG
while( pOp->opcode==OP_ReleaseReg ) pOp--;
#endif
if( pOp->p3==iDest && pOp->opcode==OP_Column ){
pOp->p5 |= OPFLAG_TYPEOFARG;
}
}
/*
** Change the P2 operand of instruction addr so that it points to
|
| ︙ | ︙ | |||
90153 90154 90155 90156 90157 90158 90159 |
pMem->flags = aFlag[serial_type&1];
return;
}
}
return;
}
/*
| | < | | < < < < < < | | < < > | 90284 90285 90286 90287 90288 90289 90290 90291 90292 90293 90294 90295 90296 90297 90298 90299 90300 90301 90302 90303 90304 90305 90306 90307 90308 90309 90310 90311 90312 90313 90314 90315 90316 90317 90318 90319 90320 90321 90322 90323 90324 90325 90326 90327 90328 90329 90330 90331 90332 90333 90334 90335 |
pMem->flags = aFlag[serial_type&1];
return;
}
}
return;
}
/*
** Allocate sufficient space for an UnpackedRecord structure large enough
** to hold a decoded index record for pKeyInfo.
**
** The space is allocated using sqlite3DbMallocRaw(). If an OOM error
** occurs, NULL is returned.
*/
SQLITE_PRIVATE UnpackedRecord *sqlite3VdbeAllocUnpackedRecord(
KeyInfo *pKeyInfo /* Description of the record */
){
UnpackedRecord *p; /* Unpacked record to return */
u64 nByte; /* Number of bytes required for *p */
assert( sizeof(UnpackedRecord) + sizeof(Mem)*65536 < 0x7fffffff );
nByte = ROUND8P(sizeof(UnpackedRecord)) + sizeof(Mem)*(pKeyInfo->nKeyField+1);
p = (UnpackedRecord *)sqlite3DbMallocRaw(pKeyInfo->db, nByte);
if( !p ) return 0;
p->aMem = (Mem*)&((char*)p)[ROUND8P(sizeof(UnpackedRecord))];
p->pKeyInfo = pKeyInfo;
p->nField = pKeyInfo->nKeyField + 1;
return p;
}
/*
** Given the nKey-byte encoding of a record in pKey[], populate the
** UnpackedRecord structure indicated by the fourth argument with the
** contents of the decoded record.
*/
SQLITE_PRIVATE void sqlite3VdbeRecordUnpack(
int nKey, /* Size of the binary record */
const void *pKey, /* The binary record */
UnpackedRecord *p /* Populate this structure before returning. */
){
const unsigned char *aKey = (const unsigned char *)pKey;
u32 d;
u32 idx; /* Offset in aKey[] to read from */
u16 u; /* Unsigned loop counter */
u32 szHdr;
Mem *pMem = p->aMem;
KeyInfo *pKeyInfo = p->pKeyInfo;
p->default_rc = 0;
assert( EIGHT_BYTE_ALIGNMENT(pMem) );
idx = getVarint32(aKey, szHdr);
d = szHdr;
u = 0;
while( idx<szHdr && d<=(u32)nKey ){
|
| ︙ | ︙ | |||
90226 90227 90228 90229 90230 90231 90232 90233 90234 90235 90236 90237 90238 90239 |
if( d>(u32)nKey && u ){
assert( CORRUPT_DB );
/* In a corrupt record entry, the last pMem might have been set up using
** uninitialized memory. Overwrite its value with NULL, to prevent
** warnings from MSAN. */
sqlite3VdbeMemSetNull(pMem-1);
}
assert( u<=pKeyInfo->nKeyField + 1 );
p->nField = u;
}
#ifdef SQLITE_DEBUG
/*
** This function compares two index or table record keys in the same way
| > > | 90349 90350 90351 90352 90353 90354 90355 90356 90357 90358 90359 90360 90361 90362 90363 90364 |
if( d>(u32)nKey && u ){
assert( CORRUPT_DB );
/* In a corrupt record entry, the last pMem might have been set up using
** uninitialized memory. Overwrite its value with NULL, to prevent
** warnings from MSAN. */
sqlite3VdbeMemSetNull(pMem-1);
}
testcase( u == pKeyInfo->nKeyField + 1 );
testcase( u < pKeyInfo->nKeyField + 1 );
assert( u<=pKeyInfo->nKeyField + 1 );
p->nField = u;
}
#ifdef SQLITE_DEBUG
/*
** This function compares two index or table record keys in the same way
|
| ︙ | ︙ | |||
91085 91086 91087 91088 91089 91090 91091 91092 91093 91094 91095 91096 91097 91098 |
** buffer passed to varintRecordCompareInt() this makes it convenient to
** limit the size of the header to 64 bytes in cases where the first field
** is an integer.
**
** The easiest way to enforce this limit is to consider only records with
** 13 fields or less. If the first field is an integer, the maximum legal
** header size is (12*5 + 1 + 1) bytes. */
if( p->pKeyInfo->nAllField<=13 ){
int flags = p->aMem[0].flags;
if( p->pKeyInfo->aSortFlags[0] ){
if( p->pKeyInfo->aSortFlags[0] & KEYINFO_ORDER_BIGNULL ){
return sqlite3VdbeRecordCompare;
}
p->r1 = 1;
| > | 91210 91211 91212 91213 91214 91215 91216 91217 91218 91219 91220 91221 91222 91223 91224 |
** buffer passed to varintRecordCompareInt() this makes it convenient to
** limit the size of the header to 64 bytes in cases where the first field
** is an integer.
**
** The easiest way to enforce this limit is to consider only records with
** 13 fields or less. If the first field is an integer, the maximum legal
** header size is (12*5 + 1 + 1) bytes. */
assert( p->pKeyInfo->aSortFlags!=0 );
if( p->pKeyInfo->nAllField<=13 ){
int flags = p->aMem[0].flags;
if( p->pKeyInfo->aSortFlags[0] ){
if( p->pKeyInfo->aSortFlags[0] & KEYINFO_ORDER_BIGNULL ){
return sqlite3VdbeRecordCompare;
}
p->r1 = 1;
|
| ︙ | ︙ | |||
91334 91335 91336 91337 91338 91339 91340 91341 91342 91343 91344 91345 91346 91347 |
if( iVar>=32 ){
v->expmask |= 0x80000000;
}else{
v->expmask |= ((u32)1 << (iVar-1));
}
}
/*
** Cause a function to throw an error if it was call from OP_PureFunc
** rather than OP_Function.
**
** OP_PureFunc means that the function must be deterministic, and should
** throw an error if it is given inputs that would make it non-deterministic.
** This routine is invoked by date/time functions that use non-deterministic
| > | 91460 91461 91462 91463 91464 91465 91466 91467 91468 91469 91470 91471 91472 91473 91474 |
if( iVar>=32 ){
v->expmask |= 0x80000000;
}else{
v->expmask |= ((u32)1 << (iVar-1));
}
}
#ifndef SQLITE_OMIT_DATETIME_FUNCS
/*
** Cause a function to throw an error if it was call from OP_PureFunc
** rather than OP_Function.
**
** OP_PureFunc means that the function must be deterministic, and should
** throw an error if it is given inputs that would make it non-deterministic.
** This routine is invoked by date/time functions that use non-deterministic
|
| ︙ | ︙ | |||
91367 91368 91369 91370 91371 91372 91373 91374 91375 91376 91377 91378 91379 91380 |
pCtx->pFunc->zName, zContext);
sqlite3_result_error(pCtx, zMsg, -1);
sqlite3_free(zMsg);
return 0;
}
return 1;
}
#if defined(SQLITE_ENABLE_CURSOR_HINTS) && defined(SQLITE_DEBUG)
/*
** This Walker callback is used to help verify that calls to
** sqlite3BtreeCursorHint() with opcode BTREE_HINT_RANGE have
** byte-code register values correctly initialized.
*/
| > | 91494 91495 91496 91497 91498 91499 91500 91501 91502 91503 91504 91505 91506 91507 91508 |
pCtx->pFunc->zName, zContext);
sqlite3_result_error(pCtx, zMsg, -1);
sqlite3_free(zMsg);
return 0;
}
return 1;
}
#endif /* SQLITE_OMIT_DATETIME_FUNCS */
#if defined(SQLITE_ENABLE_CURSOR_HINTS) && defined(SQLITE_DEBUG)
/*
** This Walker callback is used to help verify that calls to
** sqlite3BtreeCursorHint() with opcode BTREE_HINT_RANGE have
** byte-code register values correctly initialized.
*/
|
| ︙ | ︙ | |||
91443 91444 91445 91446 91447 91448 91449 |
int iReg, /* Register for new.* record */
int iBlobWrite
){
sqlite3 *db = v->db;
i64 iKey2;
PreUpdate preupdate;
const char *zTbl = pTab->zName;
| < | 91571 91572 91573 91574 91575 91576 91577 91578 91579 91580 91581 91582 91583 91584 |
int iReg, /* Register for new.* record */
int iBlobWrite
){
sqlite3 *db = v->db;
i64 iKey2;
PreUpdate preupdate;
const char *zTbl = pTab->zName;
#ifdef SQLITE_DEBUG
int nRealCol;
if( pTab->tabFlags & TF_WithoutRowid ){
nRealCol = sqlite3PrimaryKeyIndex(pTab)->nColumn;
}else if( pTab->tabFlags & TF_HasVirtual ){
nRealCol = pTab->nNVCol;
}else{
|
| ︙ | ︙ | |||
91482 91483 91484 91485 91486 91487 91488 | preupdate.pCsr = pCsr; preupdate.op = op; preupdate.iNewReg = iReg; preupdate.pKeyinfo = (KeyInfo*)&preupdate.keyinfoSpace; preupdate.pKeyinfo->db = db; preupdate.pKeyinfo->enc = ENC(db); preupdate.pKeyinfo->nKeyField = pTab->nCol; | | | 91609 91610 91611 91612 91613 91614 91615 91616 91617 91618 91619 91620 91621 91622 91623 | preupdate.pCsr = pCsr; preupdate.op = op; preupdate.iNewReg = iReg; preupdate.pKeyinfo = (KeyInfo*)&preupdate.keyinfoSpace; preupdate.pKeyinfo->db = db; preupdate.pKeyinfo->enc = ENC(db); preupdate.pKeyinfo->nKeyField = pTab->nCol; preupdate.pKeyinfo->aSortFlags = 0; /* Indicate .aColl, .nAllField uninit */ preupdate.iKey1 = iKey1; preupdate.iKey2 = iKey2; preupdate.pTab = pTab; preupdate.iBlobWrite = iBlobWrite; db->pPreUpdate = &preupdate; db->xPreUpdateCallback(db->pPreUpdateArg, db, op, zDb, zTbl, iKey1, iKey2); |
| ︙ | ︙ | |||
93679 93680 93681 93682 93683 93684 93685 |
const void *pKey
){
UnpackedRecord *pRet; /* Return value */
pRet = sqlite3VdbeAllocUnpackedRecord(pKeyInfo);
if( pRet ){
memset(pRet->aMem, 0, sizeof(Mem)*(pKeyInfo->nKeyField+1));
| | | 93806 93807 93808 93809 93810 93811 93812 93813 93814 93815 93816 93817 93818 93819 93820 |
const void *pKey
){
UnpackedRecord *pRet; /* Return value */
pRet = sqlite3VdbeAllocUnpackedRecord(pKeyInfo);
if( pRet ){
memset(pRet->aMem, 0, sizeof(Mem)*(pKeyInfo->nKeyField+1));
sqlite3VdbeRecordUnpack(nKey, pKey, pRet);
}
return pRet;
}
/*
** This function is called from within a pre-update callback to retrieve
** a field of the row currently being updated or deleted.
|
| ︙ | ︙ | |||
93708 93709 93710 93711 93712 93713 93714 93715 93716 93717 93718 93719 93720 93721 |
** SQLITE_UPDATE pre-update callback, and that iIdx is within range. */
if( !p || p->op==SQLITE_INSERT ){
rc = SQLITE_MISUSE_BKPT;
goto preupdate_old_out;
}
if( p->pPk ){
iStore = sqlite3TableColumnToIndex(p->pPk, iIdx);
}else{
iStore = sqlite3TableColumnToStorage(p->pTab, iIdx);
}
if( iStore>=p->pCsr->nField || iStore<0 ){
rc = SQLITE_RANGE;
goto preupdate_old_out;
}
| > > > | 93835 93836 93837 93838 93839 93840 93841 93842 93843 93844 93845 93846 93847 93848 93849 93850 93851 |
** SQLITE_UPDATE pre-update callback, and that iIdx is within range. */
if( !p || p->op==SQLITE_INSERT ){
rc = SQLITE_MISUSE_BKPT;
goto preupdate_old_out;
}
if( p->pPk ){
iStore = sqlite3TableColumnToIndex(p->pPk, iIdx);
}else if( iIdx >= p->pTab->nCol ){
rc = SQLITE_MISUSE_BKPT;
goto preupdate_old_out;
}else{
iStore = sqlite3TableColumnToStorage(p->pTab, iIdx);
}
if( iStore>=p->pCsr->nField || iStore<0 ){
rc = SQLITE_RANGE;
goto preupdate_old_out;
}
|
| ︙ | ︙ | |||
93863 93864 93865 93866 93867 93868 93869 93870 93871 93872 93873 93874 93875 93876 |
p = db->pPreUpdate;
if( !p || p->op==SQLITE_DELETE ){
rc = SQLITE_MISUSE_BKPT;
goto preupdate_new_out;
}
if( p->pPk && p->op!=SQLITE_UPDATE ){
iStore = sqlite3TableColumnToIndex(p->pPk, iIdx);
}else{
iStore = sqlite3TableColumnToStorage(p->pTab, iIdx);
}
if( iStore>=p->pCsr->nField || iStore<0 ){
rc = SQLITE_RANGE;
goto preupdate_new_out;
| > > | 93993 93994 93995 93996 93997 93998 93999 94000 94001 94002 94003 94004 94005 94006 94007 94008 |
p = db->pPreUpdate;
if( !p || p->op==SQLITE_DELETE ){
rc = SQLITE_MISUSE_BKPT;
goto preupdate_new_out;
}
if( p->pPk && p->op!=SQLITE_UPDATE ){
iStore = sqlite3TableColumnToIndex(p->pPk, iIdx);
}else if( iIdx >= p->pTab->nCol ){
return SQLITE_MISUSE_BKPT;
}else{
iStore = sqlite3TableColumnToStorage(p->pTab, iIdx);
}
if( iStore>=p->pCsr->nField || iStore<0 ){
rc = SQLITE_RANGE;
goto preupdate_new_out;
|
| ︙ | ︙ | |||
95188 95189 95190 95191 95192 95193 95194 95195 95196 95197 95198 95199 95200 95201 |
pDest->flags |= MEM_Term;
}
}
pDest->flags &= ~MEM_Ephem;
return rc;
}
/*
** Return the symbolic name for the data type of a pMem
*/
static const char *vdbeMemTypeName(Mem *pMem){
static const char *azTypes[] = {
/* SQLITE_INTEGER */ "INT",
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 95320 95321 95322 95323 95324 95325 95326 95327 95328 95329 95330 95331 95332 95333 95334 95335 95336 95337 95338 95339 95340 95341 95342 95343 95344 95345 95346 95347 95348 95349 95350 95351 95352 95353 95354 95355 95356 95357 95358 95359 95360 95361 95362 95363 |
pDest->flags |= MEM_Term;
}
}
pDest->flags &= ~MEM_Ephem;
return rc;
}
/*
** Send a "statement aborts" message to the error log.
*/
static SQLITE_NOINLINE void sqlite3VdbeLogAbort(
Vdbe *p, /* The statement that is running at the time of failure */
int rc, /* Error code */
Op *pOp, /* Opcode that filed */
Op *aOp /* All opcodes */
){
const char *zSql = p->zSql; /* Original SQL text */
const char *zPrefix = ""; /* Prefix added to SQL text */
int pc; /* Opcode address */
char zXtra[100]; /* Buffer space to store zPrefix */
if( p->pFrame ){
assert( aOp[0].opcode==OP_Init );
if( aOp[0].p4.z!=0 ){
assert( aOp[0].p4.z[0]=='-'
&& aOp[0].p4.z[1]=='-'
&& aOp[0].p4.z[2]==' ' );
sqlite3_snprintf(sizeof(zXtra), zXtra,"/* %s */ ",aOp[0].p4.z+3);
zPrefix = zXtra;
}else{
zPrefix = "/* unknown trigger */ ";
}
}
pc = (int)(pOp - aOp);
sqlite3_log(rc, "statement aborts at %d: %s; [%s%s]",
pc, p->zErrMsg, zPrefix, zSql);
}
/*
** Return the symbolic name for the data type of a pMem
*/
static const char *vdbeMemTypeName(Mem *pMem){
static const char *azTypes[] = {
/* SQLITE_INTEGER */ "INT",
|
| ︙ | ︙ | |||
95713 95714 95715 95716 95717 95718 95719 |
sqlite3VdbeError(p, "%s constraint failed", azType[pOp->p5-1]);
if( pOp->p4.z ){
p->zErrMsg = sqlite3MPrintf(db, "%z: %s", p->zErrMsg, pOp->p4.z);
}
}else{
sqlite3VdbeError(p, "%s", pOp->p4.z);
}
| | < | 95875 95876 95877 95878 95879 95880 95881 95882 95883 95884 95885 95886 95887 95888 95889 |
sqlite3VdbeError(p, "%s constraint failed", azType[pOp->p5-1]);
if( pOp->p4.z ){
p->zErrMsg = sqlite3MPrintf(db, "%z: %s", p->zErrMsg, pOp->p4.z);
}
}else{
sqlite3VdbeError(p, "%s", pOp->p4.z);
}
sqlite3VdbeLogAbort(p, pOp->p1, pOp, aOp);
}
rc = sqlite3VdbeHalt(p);
assert( rc==SQLITE_BUSY || rc==SQLITE_OK || rc==SQLITE_ERROR );
if( rc==SQLITE_BUSY ){
p->rc = SQLITE_BUSY;
}else{
assert( rc==SQLITE_OK || (p->rc&0xff)==SQLITE_CONSTRAINT );
|
| ︙ | ︙ | |||
96872 96873 96874 96875 96876 96877 96878 96879 96880 96881 96882 96883 96884 96885 |
aPermute = pOp[-1].p4.ai + 1;
assert( aPermute!=0 );
}
n = pOp->p3;
pKeyInfo = pOp->p4.pKeyInfo;
assert( n>0 );
assert( pKeyInfo!=0 );
p1 = pOp->p1;
p2 = pOp->p2;
#ifdef SQLITE_DEBUG
if( aPermute ){
int k, mx = 0;
for(k=0; k<n; k++) if( aPermute[k]>(u32)mx ) mx = aPermute[k];
assert( p1>0 && p1+mx<=(p->nMem+1 - p->nCursor)+1 );
| > | 97033 97034 97035 97036 97037 97038 97039 97040 97041 97042 97043 97044 97045 97046 97047 |
aPermute = pOp[-1].p4.ai + 1;
assert( aPermute!=0 );
}
n = pOp->p3;
pKeyInfo = pOp->p4.pKeyInfo;
assert( n>0 );
assert( pKeyInfo!=0 );
assert( pKeyInfo->aSortFlags!=0 );
p1 = pOp->p1;
p2 = pOp->p2;
#ifdef SQLITE_DEBUG
if( aPermute ){
int k, mx = 0;
for(k=0; k<n; k++) if( aPermute[k]>(u32)mx ) mx = aPermute[k];
assert( p1>0 && p1+mx<=(p->nMem+1 - p->nCursor)+1 );
|
| ︙ | ︙ | |||
97040 97041 97042 97043 97044 97045 97046 |
if( (pIn1->flags & MEM_Null)==0 ){
pOut->flags = MEM_Int;
pOut->u.i = ~sqlite3VdbeIntValue(pIn1);
}
break;
}
| | > > > > > > | 97202 97203 97204 97205 97206 97207 97208 97209 97210 97211 97212 97213 97214 97215 97216 97217 97218 97219 97220 97221 97222 97223 97224 97225 97226 97227 97228 97229 97230 97231 97232 97233 97234 97235 97236 97237 |
if( (pIn1->flags & MEM_Null)==0 ){
pOut->flags = MEM_Int;
pOut->u.i = ~sqlite3VdbeIntValue(pIn1);
}
break;
}
/* Opcode: Once P1 P2 P3 * *
**
** Fall through to the next instruction the first time this opcode is
** encountered on each invocation of the byte-code program. Jump to P2
** on the second and all subsequent encounters during the same invocation.
**
** Top-level programs determine first invocation by comparing the P1
** operand against the P1 operand on the OP_Init opcode at the beginning
** of the program. If the P1 values differ, then fall through and make
** the P1 of this opcode equal to the P1 of OP_Init. If P1 values are
** the same then take the jump.
**
** For subprograms, there is a bitmask in the VdbeFrame that determines
** whether or not the jump should be taken. The bitmask is necessary
** because the self-altering code trick does not work for recursive
** triggers.
**
** The P3 operand is not used directly by this opcode. However P3 is
** used by the code generator as follows: If this opcode is the start
** of a subroutine and that subroutine uses a Bloom filter, then P3 will
** be the register that holds that Bloom filter. See tag-202407032019
** in the source code for implementation details.
*/
case OP_Once: { /* jump */
u32 iAddr; /* Address of this instruction */
assert( p->aOp[0].opcode==OP_Init );
if( p->pFrame ){
iAddr = (int)(pOp - p->aOp);
if( (p->pFrame->aOnce[iAddr/8] & (1<<(iAddr & 7)))!=0 ){
|
| ︙ | ︙ | |||
97627 97628 97629 97630 97631 97632 97633 97634 97635 97636 97637 97638 97639 97640 97641 97642 97643 97644 97645 97646 97647 | /* Opcode: TypeCheck P1 P2 P3 P4 * ** Synopsis: typecheck(r[P1@P2]) ** ** Apply affinities to the range of P2 registers beginning with P1. ** Take the affinities from the Table object in P4. If any value ** cannot be coerced into the correct type, then raise an error. ** ** This opcode is similar to OP_Affinity except that this opcode ** forces the register type to the Table column type. This is used ** to implement "strict affinity". ** ** GENERATED ALWAYS AS ... STATIC columns are only checked if P3 ** is zero. When P3 is non-zero, no type checking occurs for ** static generated columns. Virtual columns are computed at query time ** and so they are never checked. ** ** Preconditions: ** ** <ul> ** <li> P2 should be the number of non-virtual columns in the | > > > > > > > > > | | > | > > > > > > > | > > > > | | | 97795 97796 97797 97798 97799 97800 97801 97802 97803 97804 97805 97806 97807 97808 97809 97810 97811 97812 97813 97814 97815 97816 97817 97818 97819 97820 97821 97822 97823 97824 97825 97826 97827 97828 97829 97830 97831 97832 97833 97834 97835 97836 97837 97838 97839 97840 97841 97842 97843 97844 97845 97846 97847 97848 97849 97850 97851 97852 97853 97854 97855 97856 97857 97858 97859 97860 97861 97862 97863 |
/* Opcode: TypeCheck P1 P2 P3 P4 *
** Synopsis: typecheck(r[P1@P2])
**
** Apply affinities to the range of P2 registers beginning with P1.
** Take the affinities from the Table object in P4. If any value
** cannot be coerced into the correct type, then raise an error.
**
** If P3==0, then omit checking of VIRTUAL columns.
**
** If P3==1, then omit checking of all generated column, both VIRTUAL
** and STORED.
**
** If P3>=2, then only check column number P3-2 in the table (which will
** be a VIRTUAL column) against the value in reg[P1]. In this case,
** P2 will be 1.
**
** This opcode is similar to OP_Affinity except that this opcode
** forces the register type to the Table column type. This is used
** to implement "strict affinity".
**
** GENERATED ALWAYS AS ... STATIC columns are only checked if P3
** is zero. When P3 is non-zero, no type checking occurs for
** static generated columns. Virtual columns are computed at query time
** and so they are never checked.
**
** Preconditions:
**
** <ul>
** <li> P2 should be the number of non-virtual columns in the
** table of P4 unless P3>1, in which case P2 will be 1.
** <li> Table P4 is a STRICT table.
** </ul>
**
** If any precondition is false, an assertion fault occurs.
*/
case OP_TypeCheck: {
Table *pTab;
Column *aCol;
int i;
int nCol;
assert( pOp->p4type==P4_TABLE );
pTab = pOp->p4.pTab;
assert( pTab->tabFlags & TF_Strict );
assert( pOp->p3>=0 && pOp->p3<pTab->nCol+2 );
aCol = pTab->aCol;
pIn1 = &aMem[pOp->p1];
if( pOp->p3<2 ){
assert( pTab->nNVCol==pOp->p2 );
i = 0;
nCol = pTab->nCol;
}else{
i = pOp->p3-2;
nCol = i+1;
assert( i<pTab->nCol );
assert( aCol[i].colFlags & COLFLAG_VIRTUAL );
assert( pOp->p2==1 );
}
for(; i<nCol; i++){
if( (aCol[i].colFlags & COLFLAG_GENERATED)!=0 && pOp->p3<2 ){
if( (aCol[i].colFlags & COLFLAG_VIRTUAL)!=0 ) continue;
if( pOp->p3 ){ pIn1++; continue; }
}
assert( pIn1 < &aMem[pOp->p1+pOp->p2] );
applyAffinity(pIn1, aCol[i].affinity, encoding);
if( (pIn1->flags & MEM_Null)==0 ){
switch( aCol[i].eCType ){
case COLTYPE_BLOB: {
|
| ︙ | ︙ | |||
98101 98102 98103 98104 98105 98106 98107 98108 98109 98110 98111 98112 98113 98114 |
memcpy(zPayload, pRec->z, pRec->n);
zPayload += pRec->n;
}
}else{
zHdr += sqlite3PutVarint(zHdr, serial_type);
if( pRec->n ){
assert( pRec->z!=0 );
memcpy(zPayload, pRec->z, pRec->n);
zPayload += pRec->n;
}
}
if( pRec==pLast ) break;
pRec++;
}
| > | 98290 98291 98292 98293 98294 98295 98296 98297 98298 98299 98300 98301 98302 98303 98304 |
memcpy(zPayload, pRec->z, pRec->n);
zPayload += pRec->n;
}
}else{
zHdr += sqlite3PutVarint(zHdr, serial_type);
if( pRec->n ){
assert( pRec->z!=0 );
assert( pRec->z!=(const char*)sqlite3CtypeMap );
memcpy(zPayload, pRec->z, pRec->n);
zPayload += pRec->n;
}
}
if( pRec==pLast ) break;
pRec++;
}
|
| ︙ | ︙ | |||
99738 99739 99740 99741 99742 99743 99744 |
assert( r.aMem->flags & MEM_Blob );
assert( pOp->opcode!=OP_NoConflict );
rc = ExpandBlob(r.aMem);
assert( rc==SQLITE_OK || rc==SQLITE_NOMEM );
if( rc ) goto no_mem;
pIdxKey = sqlite3VdbeAllocUnpackedRecord(pC->pKeyInfo);
if( pIdxKey==0 ) goto no_mem;
| | | 99928 99929 99930 99931 99932 99933 99934 99935 99936 99937 99938 99939 99940 99941 99942 |
assert( r.aMem->flags & MEM_Blob );
assert( pOp->opcode!=OP_NoConflict );
rc = ExpandBlob(r.aMem);
assert( rc==SQLITE_OK || rc==SQLITE_NOMEM );
if( rc ) goto no_mem;
pIdxKey = sqlite3VdbeAllocUnpackedRecord(pC->pKeyInfo);
if( pIdxKey==0 ) goto no_mem;
sqlite3VdbeRecordUnpack(r.aMem->n, r.aMem->z, pIdxKey);
pIdxKey->default_rc = 0;
rc = sqlite3BtreeIndexMoveto(pC->uc.pCursor, pIdxKey, &pC->seekResult);
sqlite3DbFreeNN(db, pIdxKey);
}
if( rc!=SQLITE_OK ){
goto abort_due_to_error;
}
|
| ︙ | ︙ | |||
100735 100736 100737 100738 100739 100740 100741 100742 100743 100744 100745 100746 100747 100748 |
pC->nullRow = (u8)res;
if( pOp->p2>0 ){
VdbeBranchTaken(res!=0,2);
if( res ) goto jump_to_p2;
}
break;
}
/* Opcode: Next P1 P2 P3 * P5
**
** Advance cursor P1 so that it points to the next key/data pair in its
** table or index. If there are no more key/value pairs then fall through
** to the following instruction. But if the cursor advance was successful,
** jump immediately to P2.
| > > > > > > > > > > > > > > > > > > > > > > > > > > | 100925 100926 100927 100928 100929 100930 100931 100932 100933 100934 100935 100936 100937 100938 100939 100940 100941 100942 100943 100944 100945 100946 100947 100948 100949 100950 100951 100952 100953 100954 100955 100956 100957 100958 100959 100960 100961 100962 100963 100964 |
pC->nullRow = (u8)res;
if( pOp->p2>0 ){
VdbeBranchTaken(res!=0,2);
if( res ) goto jump_to_p2;
}
break;
}
/* Opcode: IfEmpty P1 P2 * * *
** Synopsis: if( empty(P1) ) goto P2
**
** Check to see if the b-tree table that cursor P1 references is empty
** and jump to P2 if it is.
*/
case OP_IfEmpty: { /* jump */
VdbeCursor *pC;
BtCursor *pCrsr;
int res;
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
assert( pOp->p2>=0 && pOp->p2<p->nOp );
pC = p->apCsr[pOp->p1];
assert( pC!=0 );
assert( pC->eCurType==CURTYPE_BTREE );
pCrsr = pC->uc.pCursor;
assert( pCrsr );
rc = sqlite3BtreeIsEmpty(pCrsr, &res);
if( rc ) goto abort_due_to_error;
VdbeBranchTaken(res!=0,2);
if( res ) goto jump_to_p2;
break;
}
/* Opcode: Next P1 P2 P3 * P5
**
** Advance cursor P1 so that it points to the next key/data pair in its
** table or index. If there are no more key/value pairs then fall through
** to the following instruction. But if the cursor advance was successful,
** jump immediately to P2.
|
| ︙ | ︙ | |||
102607 102608 102609 102610 102611 102612 102613 |
case OP_VOpen: { /* ncycle */
VdbeCursor *pCur;
sqlite3_vtab_cursor *pVCur;
sqlite3_vtab *pVtab;
const sqlite3_module *pModule;
assert( p->bIsReader );
| | > > > > > > > | 102823 102824 102825 102826 102827 102828 102829 102830 102831 102832 102833 102834 102835 102836 102837 102838 102839 102840 102841 102842 102843 102844 |
case OP_VOpen: { /* ncycle */
VdbeCursor *pCur;
sqlite3_vtab_cursor *pVCur;
sqlite3_vtab *pVtab;
const sqlite3_module *pModule;
assert( p->bIsReader );
pCur = p->apCsr[pOp->p1];
if( pCur!=0
&& ALWAYS( pCur->eCurType==CURTYPE_VTAB )
&& ALWAYS( pCur->uc.pVCur->pVtab==pOp->p4.pVtab->pVtab )
){
/* This opcode is a no-op if the cursor is already open */
break;
}
pVCur = 0;
pVtab = pOp->p4.pVtab->pVtab;
if( pVtab==0 || NEVER(pVtab->pModule==0) ){
rc = SQLITE_LOCKED;
goto abort_due_to_error;
}
pModule = pVtab->pModule;
|
| ︙ | ︙ | |||
103549 103550 103551 103552 103553 103554 103555 |
#endif
if( p->zErrMsg==0 && rc!=SQLITE_IOERR_NOMEM ){
sqlite3VdbeError(p, "%s", sqlite3ErrStr(rc));
}
p->rc = rc;
sqlite3SystemError(db, rc);
testcase( sqlite3GlobalConfig.xLog!=0 );
| | < | 103772 103773 103774 103775 103776 103777 103778 103779 103780 103781 103782 103783 103784 103785 103786 |
#endif
if( p->zErrMsg==0 && rc!=SQLITE_IOERR_NOMEM ){
sqlite3VdbeError(p, "%s", sqlite3ErrStr(rc));
}
p->rc = rc;
sqlite3SystemError(db, rc);
testcase( sqlite3GlobalConfig.xLog!=0 );
sqlite3VdbeLogAbort(p, rc, pOp, aOp);
if( p->eVdbeState==VDBE_RUN_STATE ) sqlite3VdbeHalt(p);
if( rc==SQLITE_IOERR_NOMEM ) sqlite3OomFault(db);
if( rc==SQLITE_CORRUPT && db->autoCommit==0 ){
db->flags |= SQLITE_CorruptRdOnly;
}
rc = SQLITE_ERROR;
if( resetSchemaOnFault>0 ){
|
| ︙ | ︙ | |||
104011 104012 104013 104014 104015 104016 104017 |
static int blobReadWrite(
sqlite3_blob *pBlob,
void *z,
int n,
int iOffset,
int (*xCall)(BtCursor*, u32, u32, void*)
){
| | | 104233 104234 104235 104236 104237 104238 104239 104240 104241 104242 104243 104244 104245 104246 104247 |
static int blobReadWrite(
sqlite3_blob *pBlob,
void *z,
int n,
int iOffset,
int (*xCall)(BtCursor*, u32, u32, void*)
){
int rc = SQLITE_OK;
Incrblob *p = (Incrblob *)pBlob;
Vdbe *v;
sqlite3 *db;
if( p==0 ) return SQLITE_MISUSE_BKPT;
db = p->db;
sqlite3_mutex_enter(db->mutex);
|
| ︙ | ︙ | |||
104051 104052 104053 104054 104055 104056 104057 |
** are not easily obtainable. And for the sessions module, an
** SQLITE_UPDATE where the PK columns do not change is handled in the
** same way as an SQLITE_DELETE (the SQLITE_DELETE code is actually
** slightly more efficient). Since you cannot write to a PK column
** using the incremental-blob API, this works. For the sessions module
** anyhow.
*/
| > > > > > > > > > > | | | | | | | | > | > | > > > | 104273 104274 104275 104276 104277 104278 104279 104280 104281 104282 104283 104284 104285 104286 104287 104288 104289 104290 104291 104292 104293 104294 104295 104296 104297 104298 104299 104300 104301 104302 104303 104304 104305 104306 104307 104308 104309 104310 104311 104312 |
** are not easily obtainable. And for the sessions module, an
** SQLITE_UPDATE where the PK columns do not change is handled in the
** same way as an SQLITE_DELETE (the SQLITE_DELETE code is actually
** slightly more efficient). Since you cannot write to a PK column
** using the incremental-blob API, this works. For the sessions module
** anyhow.
*/
if( sqlite3BtreeCursorIsValidNN(p->pCsr)==0 ){
/* If the cursor is not currently valid, try to reseek it. This
** always either fails or finds the correct row - the cursor will
** have been marked permanently CURSOR_INVALID if the open row has
** been deleted. */
int bDiff = 0;
rc = sqlite3BtreeCursorRestore(p->pCsr, &bDiff);
assert( bDiff==0 || sqlite3BtreeCursorIsValidNN(p->pCsr)==0 );
}
if( sqlite3BtreeCursorIsValidNN(p->pCsr) ){
sqlite3_int64 iKey;
iKey = sqlite3BtreeIntegerKey(p->pCsr);
assert( v->apCsr[0]!=0 );
assert( v->apCsr[0]->eCurType==CURTYPE_BTREE );
sqlite3VdbePreUpdateHook(
v, v->apCsr[0], SQLITE_DELETE, p->zDb, p->pTab, iKey, -1, p->iCol
);
}
}
if( rc==SQLITE_OK ){
rc = xCall(p->pCsr, iOffset+p->iOffset, n, z);
}
#else
rc = xCall(p->pCsr, iOffset+p->iOffset, n, z);
#endif
sqlite3BtreeLeaveCursor(p->pCsr);
if( rc==SQLITE_ABORT ){
sqlite3VdbeFinalize(v);
p->pStmt = 0;
}else{
v->rc = rc;
}
|
| ︙ | ︙ | |||
104914 104915 104916 104917 104918 104919 104920 |
SortSubtask *pTask, /* Subtask context (for pKeyInfo) */
int *pbKey2Cached, /* True if pTask->pUnpacked is pKey2 */
const void *pKey1, int nKey1, /* Left side of comparison */
const void *pKey2, int nKey2 /* Right side of comparison */
){
UnpackedRecord *r2 = pTask->pUnpacked;
if( *pbKey2Cached==0 ){
| | | 105151 105152 105153 105154 105155 105156 105157 105158 105159 105160 105161 105162 105163 105164 105165 |
SortSubtask *pTask, /* Subtask context (for pKeyInfo) */
int *pbKey2Cached, /* True if pTask->pUnpacked is pKey2 */
const void *pKey1, int nKey1, /* Left side of comparison */
const void *pKey2, int nKey2 /* Right side of comparison */
){
UnpackedRecord *r2 = pTask->pUnpacked;
if( *pbKey2Cached==0 ){
sqlite3VdbeRecordUnpack(nKey2, pKey2, r2);
*pbKey2Cached = 1;
}
return sqlite3VdbeRecordCompareWithSkip(nKey1, pKey1, r2, 1);
}
/*
** Compare key1 (buffer pKey1, size nKey1 bytes) with key2 (buffer pKey2,
|
| ︙ | ︙ | |||
104941 104942 104943 104944 104945 104946 104947 |
SortSubtask *pTask, /* Subtask context (for pKeyInfo) */
int *pbKey2Cached, /* True if pTask->pUnpacked is pKey2 */
const void *pKey1, int nKey1, /* Left side of comparison */
const void *pKey2, int nKey2 /* Right side of comparison */
){
UnpackedRecord *r2 = pTask->pUnpacked;
if( !*pbKey2Cached ){
| | | 105178 105179 105180 105181 105182 105183 105184 105185 105186 105187 105188 105189 105190 105191 105192 |
SortSubtask *pTask, /* Subtask context (for pKeyInfo) */
int *pbKey2Cached, /* True if pTask->pUnpacked is pKey2 */
const void *pKey1, int nKey1, /* Left side of comparison */
const void *pKey2, int nKey2 /* Right side of comparison */
){
UnpackedRecord *r2 = pTask->pUnpacked;
if( !*pbKey2Cached ){
sqlite3VdbeRecordUnpack(nKey2, pKey2, r2);
*pbKey2Cached = 1;
}
return sqlite3VdbeRecordCompare(nKey1, pKey1, r2);
}
/*
** A specially optimized version of vdbeSorterCompare() that assumes that
|
| ︙ | ︙ | |||
104981 104982 104983 104984 104985 104986 104987 104988 104989 104990 104991 104992 104993 104994 |
if( res==0 ){
if( pTask->pSorter->pKeyInfo->nKeyField>1 ){
res = vdbeSorterCompareTail(
pTask, pbKey2Cached, pKey1, nKey1, pKey2, nKey2
);
}
}else{
assert( !(pTask->pSorter->pKeyInfo->aSortFlags[0]&KEYINFO_ORDER_BIGNULL) );
if( pTask->pSorter->pKeyInfo->aSortFlags[0] ){
res = res * -1;
}
}
return res;
| > | 105218 105219 105220 105221 105222 105223 105224 105225 105226 105227 105228 105229 105230 105231 105232 |
if( res==0 ){
if( pTask->pSorter->pKeyInfo->nKeyField>1 ){
res = vdbeSorterCompareTail(
pTask, pbKey2Cached, pKey1, nKey1, pKey2, nKey2
);
}
}else{
assert( pTask->pSorter->pKeyInfo->aSortFlags!=0 );
assert( !(pTask->pSorter->pKeyInfo->aSortFlags[0]&KEYINFO_ORDER_BIGNULL) );
if( pTask->pSorter->pKeyInfo->aSortFlags[0] ){
res = res * -1;
}
}
return res;
|
| ︙ | ︙ | |||
105044 105045 105046 105047 105048 105049 105050 105051 105052 105053 105054 105055 105056 105057 |
if( res>0 ){
if( *v1 & 0x80 ) res = -1;
}else{
if( *v2 & 0x80 ) res = +1;
}
}
if( res==0 ){
if( pTask->pSorter->pKeyInfo->nKeyField>1 ){
res = vdbeSorterCompareTail(
pTask, pbKey2Cached, pKey1, nKey1, pKey2, nKey2
);
}
}else if( pTask->pSorter->pKeyInfo->aSortFlags[0] ){
| > | 105282 105283 105284 105285 105286 105287 105288 105289 105290 105291 105292 105293 105294 105295 105296 |
if( res>0 ){
if( *v1 & 0x80 ) res = -1;
}else{
if( *v2 & 0x80 ) res = +1;
}
}
assert( pTask->pSorter->pKeyInfo->aSortFlags!=0 );
if( res==0 ){
if( pTask->pSorter->pKeyInfo->nKeyField>1 ){
res = vdbeSorterCompareTail(
pTask, pbKey2Cached, pKey1, nKey1, pKey2, nKey2
);
}
}else if( pTask->pSorter->pKeyInfo->aSortFlags[0] ){
|
| ︙ | ︙ | |||
105117 105118 105119 105120 105121 105122 105123 |
#endif
assert( pCsr->pKeyInfo );
assert( !pCsr->isEphemeral );
assert( pCsr->eCurType==CURTYPE_SORTER );
assert( sizeof(KeyInfo) + UMXV(pCsr->pKeyInfo->nKeyField)*sizeof(CollSeq*)
< 0x7fffffff );
| > | > > > > > | 105356 105357 105358 105359 105360 105361 105362 105363 105364 105365 105366 105367 105368 105369 105370 105371 105372 105373 105374 105375 105376 105377 105378 105379 105380 105381 105382 105383 105384 105385 105386 105387 105388 105389 105390 |
#endif
assert( pCsr->pKeyInfo );
assert( !pCsr->isEphemeral );
assert( pCsr->eCurType==CURTYPE_SORTER );
assert( sizeof(KeyInfo) + UMXV(pCsr->pKeyInfo->nKeyField)*sizeof(CollSeq*)
< 0x7fffffff );
assert( pCsr->pKeyInfo->nKeyField<=pCsr->pKeyInfo->nAllField );
szKeyInfo = SZ_KEYINFO(pCsr->pKeyInfo->nAllField);
sz = SZ_VDBESORTER(nWorker+1);
pSorter = (VdbeSorter*)sqlite3DbMallocZero(db, sz + szKeyInfo);
pCsr->uc.pSorter = pSorter;
if( pSorter==0 ){
rc = SQLITE_NOMEM_BKPT;
}else{
Btree *pBt = db->aDb[0].pBt;
pSorter->pKeyInfo = pKeyInfo = (KeyInfo*)((u8*)pSorter + sz);
memcpy(pKeyInfo, pCsr->pKeyInfo, szKeyInfo);
pKeyInfo->db = 0;
if( nField && nWorker==0 ){
pKeyInfo->nKeyField = nField;
assert( nField<=pCsr->pKeyInfo->nAllField );
}
/* It is OK that pKeyInfo reuses the aSortFlags field from pCsr->pKeyInfo,
** since the pCsr->pKeyInfo->aSortFlags[] array is invariant and lives
** longer that pSorter. */
assert( pKeyInfo->aSortFlags==pCsr->pKeyInfo->aSortFlags );
sqlite3BtreeEnter(pBt);
pSorter->pgsz = pgsz = sqlite3BtreeGetPageSize(pBt);
sqlite3BtreeLeave(pBt);
pSorter->nTask = nWorker + 1;
pSorter->iPrev = (u8)(nWorker - 1);
pSorter->bUseThreads = (pSorter->nTask>1);
pSorter->db = db;
|
| ︙ | ︙ | |||
106911 106912 106913 106914 106915 106916 106917 |
r2 = pSorter->pUnpacked = sqlite3VdbeAllocUnpackedRecord(pKeyInfo);
if( r2==0 ) return SQLITE_NOMEM_BKPT;
r2->nField = nKeyCol;
}
assert( r2->nField==nKeyCol );
pKey = vdbeSorterRowkey(pSorter, &nKey);
| | | 107156 107157 107158 107159 107160 107161 107162 107163 107164 107165 107166 107167 107168 107169 107170 |
r2 = pSorter->pUnpacked = sqlite3VdbeAllocUnpackedRecord(pKeyInfo);
if( r2==0 ) return SQLITE_NOMEM_BKPT;
r2->nField = nKeyCol;
}
assert( r2->nField==nKeyCol );
pKey = vdbeSorterRowkey(pSorter, &nKey);
sqlite3VdbeRecordUnpack(nKey, pKey, r2);
for(i=0; i<nKeyCol; i++){
if( r2->aMem[i].flags & MEM_Null ){
*pRes = -1;
return SQLITE_OK;
}
}
|
| ︙ | ︙ | |||
109285 109286 109287 109288 109289 109290 109291 |
}
if( (pDef->funcFlags & SQLITE_FUNC_CONSTANT)==0 ){
/* Clearly non-deterministic functions like random(), but also
** date/time functions that use 'now', and other functions like
** sqlite_version() that might change over time cannot be used
** in an index or generated column. Curiously, they can be used
** in a CHECK constraint. SQLServer, MySQL, and PostgreSQL all
| | < > | 109530 109531 109532 109533 109534 109535 109536 109537 109538 109539 109540 109541 109542 109543 109544 109545 109546 109547 109548 109549 109550 109551 109552 109553 109554 109555 109556 109557 109558 109559 109560 109561 109562 109563 109564 109565 |
}
if( (pDef->funcFlags & SQLITE_FUNC_CONSTANT)==0 ){
/* Clearly non-deterministic functions like random(), but also
** date/time functions that use 'now', and other functions like
** sqlite_version() that might change over time cannot be used
** in an index or generated column. Curiously, they can be used
** in a CHECK constraint. SQLServer, MySQL, and PostgreSQL all
** allow this. */
sqlite3ResolveNotValid(pParse, pNC, "non-deterministic functions",
NC_IdxExpr|NC_PartIdx|NC_GenCol, 0, pExpr);
}else{
assert( (NC_SelfRef & 0xff)==NC_SelfRef ); /* Must fit in 8 bits */
pExpr->op2 = pNC->ncFlags & NC_SelfRef;
}
if( (pDef->funcFlags & SQLITE_FUNC_INTERNAL)!=0
&& pParse->nested==0
&& (pParse->db->mDbFlags & DBFLAG_InternalFunc)==0
){
/* Internal-use-only functions are disallowed unless the
** SQL is being compiled using sqlite3NestedParse() or
** the SQLITE_TESTCTRL_INTERNAL_FUNCTIONS test-control has be
** used to activate internal functions for testing purposes */
no_such_func = 1;
pDef = 0;
}else
if( (pDef->funcFlags & (SQLITE_FUNC_DIRECT|SQLITE_FUNC_UNSAFE))!=0
&& !IN_RENAME_OBJECT
){
if( pNC->ncFlags & NC_FromDDL ) ExprSetProperty(pExpr, EP_FromDDL);
sqlite3ExprFunctionUsable(pParse, pExpr, pDef);
}
}
if( 0==IN_RENAME_OBJECT ){
#ifndef SQLITE_OMIT_WINDOWFUNC
assert( is_agg==0 || (pDef->funcFlags & SQLITE_FUNC_MINMAX)
|
| ︙ | ︙ | |||
109441 109442 109443 109444 109445 109446 109447 |
}
/* FIX ME: Compute pExpr->affinity based on the expected return
** type of the function
*/
return WRC_Prune;
}
#ifndef SQLITE_OMIT_SUBQUERY
| | | > > > | 109686 109687 109688 109689 109690 109691 109692 109693 109694 109695 109696 109697 109698 109699 109700 109701 109702 109703 109704 109705 109706 109707 109708 109709 109710 109711 109712 109713 109714 |
}
/* FIX ME: Compute pExpr->affinity based on the expected return
** type of the function
*/
return WRC_Prune;
}
#ifndef SQLITE_OMIT_SUBQUERY
case TK_EXISTS:
case TK_SELECT:
#endif
case TK_IN: {
testcase( pExpr->op==TK_IN );
testcase( pExpr->op==TK_EXISTS );
testcase( pExpr->op==TK_SELECT );
if( ExprUseXSelect(pExpr) ){
int nRef = pNC->nRef;
testcase( pNC->ncFlags & NC_IsCheck );
testcase( pNC->ncFlags & NC_PartIdx );
testcase( pNC->ncFlags & NC_IdxExpr );
testcase( pNC->ncFlags & NC_GenCol );
assert( pExpr->x.pSelect );
if( pExpr->op==TK_EXISTS ) pParse->bHasExists = 1;
if( pNC->ncFlags & NC_SelfRef ){
notValidImpl(pParse, pNC, "subqueries", pExpr, pExpr);
}else{
sqlite3WalkSelect(pWalker, pExpr->x.pSelect);
}
assert( pNC->nRef>=nRef );
if( nRef!=pNC->nRef ){
|
| ︙ | ︙ | |||
110467 110468 110469 110470 110471 110472 110473 |
assert( pExpr->iColumn < pExpr->iTable );
assert( pExpr->iColumn >= 0 );
assert( pExpr->iTable==pExpr->pLeft->x.pSelect->pEList->nExpr );
return sqlite3ExprAffinity(
pExpr->pLeft->x.pSelect->pEList->a[pExpr->iColumn].pExpr
);
}
| | > > | 110715 110716 110717 110718 110719 110720 110721 110722 110723 110724 110725 110726 110727 110728 110729 110730 110731 |
assert( pExpr->iColumn < pExpr->iTable );
assert( pExpr->iColumn >= 0 );
assert( pExpr->iTable==pExpr->pLeft->x.pSelect->pEList->nExpr );
return sqlite3ExprAffinity(
pExpr->pLeft->x.pSelect->pEList->a[pExpr->iColumn].pExpr
);
}
if( op==TK_VECTOR
|| (op==TK_FUNCTION && pExpr->affExpr==SQLITE_AFF_DEFER)
){
assert( ExprUseXList(pExpr) );
return sqlite3ExprAffinity(pExpr->x.pList->a[0].pExpr);
}
if( ExprHasProperty(pExpr, EP_Skip|EP_IfNullRow) ){
assert( pExpr->op==TK_COLLATE
|| pExpr->op==TK_IF_NULL_ROW
|| (pExpr->op==TK_REGISTER && pExpr->op2==TK_IF_NULL_ROW) );
|
| ︙ | ︙ | |||
110660 110661 110662 110663 110664 110665 110666 |
}
break;
}
if( op==TK_CAST || op==TK_UPLUS ){
p = p->pLeft;
continue;
}
| | > > | 110910 110911 110912 110913 110914 110915 110916 110917 110918 110919 110920 110921 110922 110923 110924 110925 110926 |
}
break;
}
if( op==TK_CAST || op==TK_UPLUS ){
p = p->pLeft;
continue;
}
if( op==TK_VECTOR
|| (op==TK_FUNCTION && p->affExpr==SQLITE_AFF_DEFER)
){
assert( ExprUseXList(p) );
p = p->x.pList->a[0].pExpr;
continue;
}
if( op==TK_COLLATE ){
assert( !ExprHasProperty(p, EP_IntValue) );
pColl = sqlite3GetCollSeq(pParse, ENC(db), 0, p->u.zToken);
|
| ︙ | ︙ | |||
111534 111535 111536 111537 111538 111539 111540 |
sqlite3 *db = pParse->db;
if( pLeft==0 ){
return pRight;
}else if( pRight==0 ){
return pLeft;
}else{
u32 f = pLeft->flags | pRight->flags;
| | | 111786 111787 111788 111789 111790 111791 111792 111793 111794 111795 111796 111797 111798 111799 111800 |
sqlite3 *db = pParse->db;
if( pLeft==0 ){
return pRight;
}else if( pRight==0 ){
return pLeft;
}else{
u32 f = pLeft->flags | pRight->flags;
if( (f&(EP_OuterON|EP_InnerON|EP_IsFalse|EP_HasFunc))==EP_IsFalse
&& !IN_RENAME_OBJECT
){
sqlite3ExprDeferredDelete(pParse, pLeft);
sqlite3ExprDeferredDelete(pParse, pRight);
return sqlite3Expr(db, TK_INTEGER, "0");
}else{
return sqlite3PExpr(pParse, TK_AND, pLeft, pRight);
|
| ︙ | ︙ | |||
112762 112763 112764 112765 112766 112767 112768 112769 112770 112771 112772 112773 112774 112775 |
pExpr = pExpr->op==TK_AND ? pRight : pLeft;
}else if( ExprAlwaysTrue(pRight) || ExprAlwaysFalse(pLeft) ){
pExpr = pExpr->op==TK_AND ? pLeft : pRight;
}
}
return pExpr;
}
/*
** pExpr is a TK_FUNCTION node. Try to determine whether or not the
** function is a constant function. A function is constant if all of
** the following are true:
**
** (1) It is a scalar function (not an aggregate or window function)
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 113014 113015 113016 113017 113018 113019 113020 113021 113022 113023 113024 113025 113026 113027 113028 113029 113030 113031 113032 113033 113034 113035 113036 113037 113038 113039 113040 113041 113042 113043 113044 113045 113046 113047 113048 113049 113050 113051 113052 113053 113054 113055 113056 113057 113058 113059 113060 113061 113062 113063 113064 113065 113066 113067 113068 113069 113070 113071 113072 113073 113074 113075 113076 113077 113078 113079 113080 113081 113082 113083 113084 113085 113086 113087 113088 113089 113090 113091 113092 113093 113094 113095 113096 113097 113098 113099 113100 113101 113102 113103 113104 113105 113106 113107 |
pExpr = pExpr->op==TK_AND ? pRight : pLeft;
}else if( ExprAlwaysTrue(pRight) || ExprAlwaysFalse(pLeft) ){
pExpr = pExpr->op==TK_AND ? pLeft : pRight;
}
}
return pExpr;
}
/*
** Return true if it might be advantageous to compute the right operand
** of expression pExpr first, before the left operand.
**
** Normally the left operand is computed before the right operand. But if
** the left operand contains a subquery and the right does not, then it
** might be more efficient to compute the right operand first.
*/
static int exprEvalRhsFirst(Expr *pExpr){
if( ExprHasProperty(pExpr->pLeft, EP_Subquery)
&& !ExprHasProperty(pExpr->pRight, EP_Subquery)
){
return 1;
}else{
return 0;
}
}
/*
** Compute the two operands of a binary operator.
**
** If either operand contains a subquery, then the code strives to
** compute the operand containing the subquery second. If the other
** operand evalutes to NULL, then a jump is made. The address of the
** IsNull operand that does this jump is returned. The caller can use
** this to optimize the computation so as to avoid doing the potentially
** expensive subquery.
**
** If no optimization opportunities exist, return 0.
*/
static int exprComputeOperands(
Parse *pParse, /* Parsing context */
Expr *pExpr, /* The comparison expression */
int *pR1, /* OUT: Register holding the left operand */
int *pR2, /* OUT: Register holding the right operand */
int *pFree1, /* OUT: Temp register to free if not zero */
int *pFree2 /* OUT: Another temp register to free if not zero */
){
int addrIsNull;
int r1, r2;
Vdbe *v = pParse->pVdbe;
assert( v!=0 );
/*
** If the left operand contains a (possibly expensive) subquery and the
** right operand does not and the right operation might be NULL,
** then compute the right operand first and do an IsNull jump if the
** right operand evalutes to NULL.
*/
if( exprEvalRhsFirst(pExpr) && sqlite3ExprCanBeNull(pExpr->pRight) ){
r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, pFree2);
addrIsNull = sqlite3VdbeAddOp1(v, OP_IsNull, r2);
VdbeComment((v, "skip left operand"));
VdbeCoverage(v);
}else{
r2 = 0; /* Silence a false-positive uninit-var warning in MSVC */
addrIsNull = 0;
}
r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, pFree1);
if( addrIsNull==0 ){
/*
** If the right operand contains a subquery and the left operand does not
** and the left operand might be NULL, then check the left operand do
** an IsNull check on the left operand before computing the right
** operand.
*/
if( ExprHasProperty(pExpr->pRight, EP_Subquery)
&& sqlite3ExprCanBeNull(pExpr->pLeft)
){
addrIsNull = sqlite3VdbeAddOp1(v, OP_IsNull, r1);
VdbeComment((v, "skip right operand"));
VdbeCoverage(v);
}
r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, pFree2);
}
*pR1 = r1;
*pR2 = r2;
return addrIsNull;
}
/*
** pExpr is a TK_FUNCTION node. Try to determine whether or not the
** function is a constant function. A function is constant if all of
** the following are true:
**
** (1) It is a scalar function (not an aggregate or window function)
|
| ︙ | ︙ | |||
114020 114021 114022 114023 114024 114025 114026 114027 114028 |
testcase( pSelect->selFlags & SF_Distinct );
testcase( pKeyInfo==0 ); /* Caused by OOM in sqlite3KeyInfoAlloc() */
pCopy = sqlite3SelectDup(pParse->db, pSelect, 0);
rc = pParse->db->mallocFailed ? 1 :sqlite3Select(pParse, pCopy, &dest);
sqlite3SelectDelete(pParse->db, pCopy);
sqlite3DbFree(pParse->db, dest.zAffSdst);
if( addrBloom ){
sqlite3VdbeGetOp(v, addrOnce)->p3 = dest.iSDParm2;
if( dest.iSDParm2==0 ){
| > > | < | | 114352 114353 114354 114355 114356 114357 114358 114359 114360 114361 114362 114363 114364 114365 114366 114367 114368 114369 114370 114371 |
testcase( pSelect->selFlags & SF_Distinct );
testcase( pKeyInfo==0 ); /* Caused by OOM in sqlite3KeyInfoAlloc() */
pCopy = sqlite3SelectDup(pParse->db, pSelect, 0);
rc = pParse->db->mallocFailed ? 1 :sqlite3Select(pParse, pCopy, &dest);
sqlite3SelectDelete(pParse->db, pCopy);
sqlite3DbFree(pParse->db, dest.zAffSdst);
if( addrBloom ){
/* Remember that location of the Bloom filter in the P3 operand
** of the OP_Once that began this subroutine. tag-202407032019 */
sqlite3VdbeGetOp(v, addrOnce)->p3 = dest.iSDParm2;
if( dest.iSDParm2==0 ){
/* If the Bloom filter won't actually be used, keep it small */
sqlite3VdbeGetOp(v, addrBloom)->p1 = 10;
}
}
if( rc ){
sqlite3KeyInfoUnref(pKeyInfo);
return;
}
assert( pKeyInfo!=0 ); /* OOM will cause exit after sqlite3Select() */
|
| ︙ | ︙ | |||
114206 114207 114208 114209 114210 114211 114212 |
VdbeComment((v, "Init subquery result"));
}else{
dest.eDest = SRT_Exists;
sqlite3VdbeAddOp2(v, OP_Integer, 0, dest.iSDParm);
VdbeComment((v, "Init EXISTS result"));
}
if( pSel->pLimit ){
| | > | > > > > | | | | | | | | | > | 114539 114540 114541 114542 114543 114544 114545 114546 114547 114548 114549 114550 114551 114552 114553 114554 114555 114556 114557 114558 114559 114560 114561 114562 114563 114564 114565 114566 114567 114568 114569 |
VdbeComment((v, "Init subquery result"));
}else{
dest.eDest = SRT_Exists;
sqlite3VdbeAddOp2(v, OP_Integer, 0, dest.iSDParm);
VdbeComment((v, "Init EXISTS result"));
}
if( pSel->pLimit ){
/* The subquery already has a limit. If the pre-existing limit X is
** not already integer value 1 or 0, then make the new limit X<>0 so that
** the new limit is either 1 or 0 */
Expr *pLeft = pSel->pLimit->pLeft;
if( ExprHasProperty(pLeft, EP_IntValue)==0
|| (pLeft->u.iValue!=1 && pLeft->u.iValue!=0)
){
sqlite3 *db = pParse->db;
pLimit = sqlite3Expr(db, TK_INTEGER, "0");
if( pLimit ){
pLimit->affExpr = SQLITE_AFF_NUMERIC;
pLimit = sqlite3PExpr(pParse, TK_NE,
sqlite3ExprDup(db, pLeft, 0), pLimit);
}
sqlite3ExprDeferredDelete(pParse, pLeft);
pSel->pLimit->pLeft = pLimit;
}
}else{
/* If there is no pre-existing limit add a limit of 1 */
pLimit = sqlite3Expr(pParse->db, TK_INTEGER, "1");
pSel->pLimit = sqlite3PExpr(pParse, TK_LIMIT, pLimit, 0);
}
pSel->iLimit = 0;
if( sqlite3Select(pParse, pSel, &dest) ){
|
| ︙ | ︙ | |||
114471 114472 114473 114474 114475 114476 114477 |
}else{
sqlite3VdbeAddOp4(v, OP_Affinity, rLhs, nVector, 0, zAff, nVector);
if( destIfFalse==destIfNull ){
/* Combine Step 3 and Step 5 into a single opcode */
if( ExprHasProperty(pExpr, EP_Subrtn) ){
const VdbeOp *pOp = sqlite3VdbeGetOp(v, pExpr->y.sub.iAddr);
assert( pOp->opcode==OP_Once || pParse->nErr );
| | | 114810 114811 114812 114813 114814 114815 114816 114817 114818 114819 114820 114821 114822 114823 114824 |
}else{
sqlite3VdbeAddOp4(v, OP_Affinity, rLhs, nVector, 0, zAff, nVector);
if( destIfFalse==destIfNull ){
/* Combine Step 3 and Step 5 into a single opcode */
if( ExprHasProperty(pExpr, EP_Subrtn) ){
const VdbeOp *pOp = sqlite3VdbeGetOp(v, pExpr->y.sub.iAddr);
assert( pOp->opcode==OP_Once || pParse->nErr );
if( pOp->opcode==OP_Once && pOp->p3>0 ){ /* tag-202407032019 */
assert( OptimizationEnabled(pParse->db, SQLITE_BloomFilter) );
sqlite3VdbeAddOp4Int(v, OP_Filter, pOp->p3, destIfFalse,
rLhs, nVector); VdbeCoverage(v);
}
}
sqlite3VdbeAddOp4Int(v, OP_NotFound, iTab, destIfFalse,
rLhs, nVector); VdbeCoverage(v);
|
| ︙ | ︙ | |||
114658 114659 114660 114661 114662 114663 114664 |
assert( pParse->iSelfTab!=0 );
if( pParse->iSelfTab>0 ){
iAddr = sqlite3VdbeAddOp3(v, OP_IfNullRow, pParse->iSelfTab-1, 0, regOut);
}else{
iAddr = 0;
}
sqlite3ExprCodeCopy(pParse, sqlite3ColumnExpr(pTab,pCol), regOut);
| > > > > > | | 114997 114998 114999 115000 115001 115002 115003 115004 115005 115006 115007 115008 115009 115010 115011 115012 115013 115014 115015 115016 |
assert( pParse->iSelfTab!=0 );
if( pParse->iSelfTab>0 ){
iAddr = sqlite3VdbeAddOp3(v, OP_IfNullRow, pParse->iSelfTab-1, 0, regOut);
}else{
iAddr = 0;
}
sqlite3ExprCodeCopy(pParse, sqlite3ColumnExpr(pTab,pCol), regOut);
if( (pCol->colFlags & COLFLAG_VIRTUAL)!=0
&& (pTab->tabFlags & TF_Strict)!=0
){
int p3 = 2+(int)(pCol - pTab->aCol);
sqlite3VdbeAddOp4(v, OP_TypeCheck, regOut, 1, p3, (char*)pTab, P4_TABLE);
}else if( pCol->affinity>=SQLITE_AFF_TEXT ){
sqlite3VdbeAddOp4(v, OP_Affinity, regOut, 1, 0, &pCol->affinity, 1);
}
if( iAddr ) sqlite3VdbeJumpHere(v, iAddr);
if( pParse->nErr>nErr ) pParse->db->errByteOffset = -1;
}
#endif /* SQLITE_OMIT_GENERATED_COLUMNS */
|
| ︙ | ︙ | |||
115345 115346 115347 115348 115349 115350 115351 115352 115353 115354 |
case TK_LT:
case TK_LE:
case TK_GT:
case TK_GE:
case TK_NE:
case TK_EQ: {
Expr *pLeft = pExpr->pLeft;
if( sqlite3ExprIsVector(pLeft) ){
codeVectorCompare(pParse, pExpr, target, op, p5);
}else{
| > > > > > | | > > > > > > > > > > > > | | > > > > > > > > | 115689 115690 115691 115692 115693 115694 115695 115696 115697 115698 115699 115700 115701 115702 115703 115704 115705 115706 115707 115708 115709 115710 115711 115712 115713 115714 115715 115716 115717 115718 115719 115720 115721 115722 115723 115724 115725 115726 115727 115728 115729 115730 115731 115732 115733 115734 115735 115736 115737 115738 115739 115740 115741 115742 115743 115744 115745 115746 115747 115748 115749 115750 115751 115752 115753 115754 115755 115756 115757 115758 115759 115760 115761 115762 115763 115764 115765 115766 115767 115768 115769 115770 115771 115772 115773 115774 115775 115776 115777 115778 115779 115780 |
case TK_LT:
case TK_LE:
case TK_GT:
case TK_GE:
case TK_NE:
case TK_EQ: {
Expr *pLeft = pExpr->pLeft;
int addrIsNull = 0;
if( sqlite3ExprIsVector(pLeft) ){
codeVectorCompare(pParse, pExpr, target, op, p5);
}else{
if( ExprHasProperty(pExpr, EP_Subquery) && p5!=SQLITE_NULLEQ ){
addrIsNull = exprComputeOperands(pParse, pExpr,
&r1, &r2, ®Free1, ®Free2);
}else{
r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1);
r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2);
}
sqlite3VdbeAddOp2(v, OP_Integer, 1, inReg);
codeCompare(pParse, pLeft, pExpr->pRight, op, r1, r2,
sqlite3VdbeCurrentAddr(v)+2, p5,
ExprHasProperty(pExpr,EP_Commuted));
assert(TK_LT==OP_Lt); testcase(op==OP_Lt); VdbeCoverageIf(v,op==OP_Lt);
assert(TK_LE==OP_Le); testcase(op==OP_Le); VdbeCoverageIf(v,op==OP_Le);
assert(TK_GT==OP_Gt); testcase(op==OP_Gt); VdbeCoverageIf(v,op==OP_Gt);
assert(TK_GE==OP_Ge); testcase(op==OP_Ge); VdbeCoverageIf(v,op==OP_Ge);
assert(TK_EQ==OP_Eq); testcase(op==OP_Eq); VdbeCoverageIf(v,op==OP_Eq);
assert(TK_NE==OP_Ne); testcase(op==OP_Ne); VdbeCoverageIf(v,op==OP_Ne);
if( p5==SQLITE_NULLEQ ){
sqlite3VdbeAddOp2(v, OP_Integer, 0, inReg);
}else{
sqlite3VdbeAddOp3(v, OP_ZeroOrNull, r1, inReg, r2);
if( addrIsNull ){
sqlite3VdbeAddOp2(v, OP_Goto, 0, sqlite3VdbeCurrentAddr(v)+2);
sqlite3VdbeJumpHere(v, addrIsNull);
sqlite3VdbeAddOp2(v, OP_Null, 0, inReg);
}
}
testcase( regFree1==0 );
testcase( regFree2==0 );
}
break;
}
case TK_AND:
case TK_OR:
case TK_PLUS:
case TK_STAR:
case TK_MINUS:
case TK_REM:
case TK_BITAND:
case TK_BITOR:
case TK_SLASH:
case TK_LSHIFT:
case TK_RSHIFT:
case TK_CONCAT: {
int addrIsNull;
assert( TK_AND==OP_And ); testcase( op==TK_AND );
assert( TK_OR==OP_Or ); testcase( op==TK_OR );
assert( TK_PLUS==OP_Add ); testcase( op==TK_PLUS );
assert( TK_MINUS==OP_Subtract ); testcase( op==TK_MINUS );
assert( TK_REM==OP_Remainder ); testcase( op==TK_REM );
assert( TK_BITAND==OP_BitAnd ); testcase( op==TK_BITAND );
assert( TK_BITOR==OP_BitOr ); testcase( op==TK_BITOR );
assert( TK_SLASH==OP_Divide ); testcase( op==TK_SLASH );
assert( TK_LSHIFT==OP_ShiftLeft ); testcase( op==TK_LSHIFT );
assert( TK_RSHIFT==OP_ShiftRight ); testcase( op==TK_RSHIFT );
assert( TK_CONCAT==OP_Concat ); testcase( op==TK_CONCAT );
if( ExprHasProperty(pExpr, EP_Subquery) ){
addrIsNull = exprComputeOperands(pParse, pExpr,
&r1, &r2, ®Free1, ®Free2);
}else{
r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1);
r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2);
addrIsNull = 0;
}
sqlite3VdbeAddOp3(v, op, r2, r1, target);
testcase( regFree1==0 );
testcase( regFree2==0 );
if( addrIsNull ){
sqlite3VdbeAddOp2(v, OP_Goto, 0, sqlite3VdbeCurrentAddr(v)+2);
sqlite3VdbeJumpHere(v, addrIsNull);
sqlite3VdbeAddOp2(v, OP_Null, 0, target);
VdbeComment((v, "short-circut value"));
}
break;
}
case TK_UMINUS: {
Expr *pLeft = pExpr->pLeft;
assert( pLeft );
if( pLeft->op==TK_INTEGER ){
codeInteger(pParse, pLeft, 1, target);
|
| ︙ | ︙ | |||
116246 116247 116248 116249 116250 116251 116252 |
op = pExpr->op;
switch( op ){
case TK_AND:
case TK_OR: {
Expr *pAlt = sqlite3ExprSimplifiedAndOr(pExpr);
if( pAlt!=pExpr ){
sqlite3ExprIfTrue(pParse, pAlt, dest, jumpIfNull);
| > > > > > > > > > | | | | | | | | | | | > | 116615 116616 116617 116618 116619 116620 116621 116622 116623 116624 116625 116626 116627 116628 116629 116630 116631 116632 116633 116634 116635 116636 116637 116638 116639 116640 116641 116642 116643 116644 116645 116646 116647 116648 116649 |
op = pExpr->op;
switch( op ){
case TK_AND:
case TK_OR: {
Expr *pAlt = sqlite3ExprSimplifiedAndOr(pExpr);
if( pAlt!=pExpr ){
sqlite3ExprIfTrue(pParse, pAlt, dest, jumpIfNull);
}else{
Expr *pFirst, *pSecond;
if( exprEvalRhsFirst(pExpr) ){
pFirst = pExpr->pRight;
pSecond = pExpr->pLeft;
}else{
pFirst = pExpr->pLeft;
pSecond = pExpr->pRight;
}
if( op==TK_AND ){
int d2 = sqlite3VdbeMakeLabel(pParse);
testcase( jumpIfNull==0 );
sqlite3ExprIfFalse(pParse, pFirst, d2,
jumpIfNull^SQLITE_JUMPIFNULL);
sqlite3ExprIfTrue(pParse, pSecond, dest, jumpIfNull);
sqlite3VdbeResolveLabel(v, d2);
}else{
testcase( jumpIfNull==0 );
sqlite3ExprIfTrue(pParse, pFirst, dest, jumpIfNull);
sqlite3ExprIfTrue(pParse, pSecond, dest, jumpIfNull);
}
}
break;
}
case TK_NOT: {
testcase( jumpIfNull==0 );
sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull);
break;
|
| ︙ | ︙ | |||
116295 116296 116297 116298 116299 116300 116301 116302 |
/* no break */ deliberate_fall_through
case TK_LT:
case TK_LE:
case TK_GT:
case TK_GE:
case TK_NE:
case TK_EQ: {
if( sqlite3ExprIsVector(pExpr->pLeft) ) goto default_expr;
| > | > > > | | > > > > > > > > > > | < | 116674 116675 116676 116677 116678 116679 116680 116681 116682 116683 116684 116685 116686 116687 116688 116689 116690 116691 116692 116693 116694 116695 116696 116697 116698 116699 116700 116701 116702 116703 116704 116705 116706 116707 116708 116709 116710 116711 116712 116713 116714 116715 116716 116717 116718 116719 116720 116721 116722 116723 116724 116725 116726 116727 116728 116729 116730 |
/* no break */ deliberate_fall_through
case TK_LT:
case TK_LE:
case TK_GT:
case TK_GE:
case TK_NE:
case TK_EQ: {
int addrIsNull;
if( sqlite3ExprIsVector(pExpr->pLeft) ) goto default_expr;
if( ExprHasProperty(pExpr, EP_Subquery) && jumpIfNull!=SQLITE_NULLEQ ){
addrIsNull = exprComputeOperands(pParse, pExpr,
&r1, &r2, ®Free1, ®Free2);
}else{
r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1);
r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2);
addrIsNull = 0;
}
codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op,
r1, r2, dest, jumpIfNull, ExprHasProperty(pExpr,EP_Commuted));
assert(TK_LT==OP_Lt); testcase(op==OP_Lt); VdbeCoverageIf(v,op==OP_Lt);
assert(TK_LE==OP_Le); testcase(op==OP_Le); VdbeCoverageIf(v,op==OP_Le);
assert(TK_GT==OP_Gt); testcase(op==OP_Gt); VdbeCoverageIf(v,op==OP_Gt);
assert(TK_GE==OP_Ge); testcase(op==OP_Ge); VdbeCoverageIf(v,op==OP_Ge);
assert(TK_EQ==OP_Eq); testcase(op==OP_Eq);
VdbeCoverageIf(v, op==OP_Eq && jumpIfNull==SQLITE_NULLEQ);
VdbeCoverageIf(v, op==OP_Eq && jumpIfNull!=SQLITE_NULLEQ);
assert(TK_NE==OP_Ne); testcase(op==OP_Ne);
VdbeCoverageIf(v, op==OP_Ne && jumpIfNull==SQLITE_NULLEQ);
VdbeCoverageIf(v, op==OP_Ne && jumpIfNull!=SQLITE_NULLEQ);
testcase( regFree1==0 );
testcase( regFree2==0 );
if( addrIsNull ){
if( jumpIfNull ){
sqlite3VdbeChangeP2(v, addrIsNull, dest);
}else{
sqlite3VdbeJumpHere(v, addrIsNull);
}
}
break;
}
case TK_ISNULL:
case TK_NOTNULL: {
assert( TK_ISNULL==OP_IsNull ); testcase( op==TK_ISNULL );
assert( TK_NOTNULL==OP_NotNull ); testcase( op==TK_NOTNULL );
r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1);
assert( regFree1==0 || regFree1==r1 );
if( regFree1 ) sqlite3VdbeTypeofColumn(v, r1);
sqlite3VdbeAddOp2(v, op, r1, dest);
VdbeCoverageIf(v, op==TK_ISNULL);
VdbeCoverageIf(v, op==TK_NOTNULL);
break;
}
case TK_BETWEEN: {
testcase( jumpIfNull==0 );
exprCodeBetween(pParse, pExpr, dest, sqlite3ExprIfTrue, jumpIfNull);
break;
}
|
| ︙ | ︙ | |||
116420 116421 116422 116423 116424 116425 116426 |
switch( pExpr->op ){
case TK_AND:
case TK_OR: {
Expr *pAlt = sqlite3ExprSimplifiedAndOr(pExpr);
if( pAlt!=pExpr ){
sqlite3ExprIfFalse(pParse, pAlt, dest, jumpIfNull);
| > > > > > > > > > | | | | | | | | | | | > | 116812 116813 116814 116815 116816 116817 116818 116819 116820 116821 116822 116823 116824 116825 116826 116827 116828 116829 116830 116831 116832 116833 116834 116835 116836 116837 116838 116839 116840 116841 116842 116843 116844 116845 116846 |
switch( pExpr->op ){
case TK_AND:
case TK_OR: {
Expr *pAlt = sqlite3ExprSimplifiedAndOr(pExpr);
if( pAlt!=pExpr ){
sqlite3ExprIfFalse(pParse, pAlt, dest, jumpIfNull);
}else{
Expr *pFirst, *pSecond;
if( exprEvalRhsFirst(pExpr) ){
pFirst = pExpr->pRight;
pSecond = pExpr->pLeft;
}else{
pFirst = pExpr->pLeft;
pSecond = pExpr->pRight;
}
if( pExpr->op==TK_AND ){
testcase( jumpIfNull==0 );
sqlite3ExprIfFalse(pParse, pFirst, dest, jumpIfNull);
sqlite3ExprIfFalse(pParse, pSecond, dest, jumpIfNull);
}else{
int d2 = sqlite3VdbeMakeLabel(pParse);
testcase( jumpIfNull==0 );
sqlite3ExprIfTrue(pParse, pFirst, d2,
jumpIfNull^SQLITE_JUMPIFNULL);
sqlite3ExprIfFalse(pParse, pSecond, dest, jumpIfNull);
sqlite3VdbeResolveLabel(v, d2);
}
}
break;
}
case TK_NOT: {
testcase( jumpIfNull==0 );
sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, jumpIfNull);
break;
|
| ︙ | ︙ | |||
116472 116473 116474 116475 116476 116477 116478 116479 |
/* no break */ deliberate_fall_through
case TK_LT:
case TK_LE:
case TK_GT:
case TK_GE:
case TK_NE:
case TK_EQ: {
if( sqlite3ExprIsVector(pExpr->pLeft) ) goto default_expr;
| > | > > > | | > > > > > > > > > > | < | 116874 116875 116876 116877 116878 116879 116880 116881 116882 116883 116884 116885 116886 116887 116888 116889 116890 116891 116892 116893 116894 116895 116896 116897 116898 116899 116900 116901 116902 116903 116904 116905 116906 116907 116908 116909 116910 116911 116912 116913 116914 116915 116916 116917 116918 116919 116920 116921 116922 116923 116924 116925 116926 116927 116928 |
/* no break */ deliberate_fall_through
case TK_LT:
case TK_LE:
case TK_GT:
case TK_GE:
case TK_NE:
case TK_EQ: {
int addrIsNull;
if( sqlite3ExprIsVector(pExpr->pLeft) ) goto default_expr;
if( ExprHasProperty(pExpr, EP_Subquery) && jumpIfNull!=SQLITE_NULLEQ ){
addrIsNull = exprComputeOperands(pParse, pExpr,
&r1, &r2, ®Free1, ®Free2);
}else{
r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1);
r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2);
addrIsNull = 0;
}
codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op,
r1, r2, dest, jumpIfNull,ExprHasProperty(pExpr,EP_Commuted));
assert(TK_LT==OP_Lt); testcase(op==OP_Lt); VdbeCoverageIf(v,op==OP_Lt);
assert(TK_LE==OP_Le); testcase(op==OP_Le); VdbeCoverageIf(v,op==OP_Le);
assert(TK_GT==OP_Gt); testcase(op==OP_Gt); VdbeCoverageIf(v,op==OP_Gt);
assert(TK_GE==OP_Ge); testcase(op==OP_Ge); VdbeCoverageIf(v,op==OP_Ge);
assert(TK_EQ==OP_Eq); testcase(op==OP_Eq);
VdbeCoverageIf(v, op==OP_Eq && jumpIfNull!=SQLITE_NULLEQ);
VdbeCoverageIf(v, op==OP_Eq && jumpIfNull==SQLITE_NULLEQ);
assert(TK_NE==OP_Ne); testcase(op==OP_Ne);
VdbeCoverageIf(v, op==OP_Ne && jumpIfNull!=SQLITE_NULLEQ);
VdbeCoverageIf(v, op==OP_Ne && jumpIfNull==SQLITE_NULLEQ);
testcase( regFree1==0 );
testcase( regFree2==0 );
if( addrIsNull ){
if( jumpIfNull ){
sqlite3VdbeChangeP2(v, addrIsNull, dest);
}else{
sqlite3VdbeJumpHere(v, addrIsNull);
}
}
break;
}
case TK_ISNULL:
case TK_NOTNULL: {
r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1);
assert( regFree1==0 || regFree1==r1 );
if( regFree1 ) sqlite3VdbeTypeofColumn(v, r1);
sqlite3VdbeAddOp2(v, op, r1, dest);
testcase( op==TK_ISNULL ); VdbeCoverageIf(v, op==TK_ISNULL);
testcase( op==TK_NOTNULL ); VdbeCoverageIf(v, op==TK_NOTNULL);
break;
}
case TK_BETWEEN: {
testcase( jumpIfNull==0 );
exprCodeBetween(pParse, pExpr, dest, sqlite3ExprIfFalse, jumpIfNull);
break;
}
|
| ︙ | ︙ | |||
117399 117400 117401 117402 117403 117404 117405 117406 117407 117408 117409 117410 117411 117412 117413 117414 117415 117416 117417 117418 117419 117420 117421 117422 117423 117424 117425 117426 117427 117428 117429 |
static void findOrCreateAggInfoColumn(
Parse *pParse, /* Parsing context */
AggInfo *pAggInfo, /* The AggInfo object to search and/or modify */
Expr *pExpr /* Expr describing the column to find or insert */
){
struct AggInfo_col *pCol;
int k;
assert( pAggInfo->iFirstReg==0 );
pCol = pAggInfo->aCol;
for(k=0; k<pAggInfo->nColumn; k++, pCol++){
if( pCol->pCExpr==pExpr ) return;
if( pCol->iTable==pExpr->iTable
&& pCol->iColumn==pExpr->iColumn
&& pExpr->op!=TK_IF_NULL_ROW
){
goto fix_up_expr;
}
}
k = addAggInfoColumn(pParse->db, pAggInfo);
if( k<0 ){
/* OOM on resize */
assert( pParse->db->mallocFailed );
return;
}
pCol = &pAggInfo->aCol[k];
assert( ExprUseYTab(pExpr) );
pCol->pTab = pExpr->y.pTab;
pCol->iTable = pExpr->iTable;
pCol->iColumn = pExpr->iColumn;
pCol->iSorterColumn = -1;
| > > > > > > | 117814 117815 117816 117817 117818 117819 117820 117821 117822 117823 117824 117825 117826 117827 117828 117829 117830 117831 117832 117833 117834 117835 117836 117837 117838 117839 117840 117841 117842 117843 117844 117845 117846 117847 117848 117849 117850 |
static void findOrCreateAggInfoColumn(
Parse *pParse, /* Parsing context */
AggInfo *pAggInfo, /* The AggInfo object to search and/or modify */
Expr *pExpr /* Expr describing the column to find or insert */
){
struct AggInfo_col *pCol;
int k;
int mxTerm = pParse->db->aLimit[SQLITE_LIMIT_COLUMN];
assert( mxTerm <= SMXV(i16) );
assert( pAggInfo->iFirstReg==0 );
pCol = pAggInfo->aCol;
for(k=0; k<pAggInfo->nColumn; k++, pCol++){
if( pCol->pCExpr==pExpr ) return;
if( pCol->iTable==pExpr->iTable
&& pCol->iColumn==pExpr->iColumn
&& pExpr->op!=TK_IF_NULL_ROW
){
goto fix_up_expr;
}
}
k = addAggInfoColumn(pParse->db, pAggInfo);
if( k<0 ){
/* OOM on resize */
assert( pParse->db->mallocFailed );
return;
}
if( k>mxTerm ){
sqlite3ErrorMsg(pParse, "more than %d aggregate terms", mxTerm);
k = mxTerm;
}
pCol = &pAggInfo->aCol[k];
assert( ExprUseYTab(pExpr) );
pCol->pTab = pExpr->y.pTab;
pCol->iTable = pExpr->iTable;
pCol->iColumn = pExpr->iColumn;
pCol->iSorterColumn = -1;
|
| ︙ | ︙ | |||
117450 117451 117452 117453 117454 117455 117456 117457 117458 117459 117460 117461 117462 117463 |
fix_up_expr:
ExprSetVVAProperty(pExpr, EP_NoReduce);
assert( pExpr->pAggInfo==0 || pExpr->pAggInfo==pAggInfo );
pExpr->pAggInfo = pAggInfo;
if( pExpr->op==TK_COLUMN ){
pExpr->op = TK_AGG_COLUMN;
}
pExpr->iAgg = (i16)k;
}
/*
** This is the xExprCallback for a tree walker. It is used to
** implement sqlite3ExprAnalyzeAggregates(). See sqlite3ExprAnalyzeAggregates
** for additional information.
| > | 117871 117872 117873 117874 117875 117876 117877 117878 117879 117880 117881 117882 117883 117884 117885 |
fix_up_expr:
ExprSetVVAProperty(pExpr, EP_NoReduce);
assert( pExpr->pAggInfo==0 || pExpr->pAggInfo==pAggInfo );
pExpr->pAggInfo = pAggInfo;
if( pExpr->op==TK_COLUMN ){
pExpr->op = TK_AGG_COLUMN;
}
assert( k <= SMXV(pExpr->iAgg) );
pExpr->iAgg = (i16)k;
}
/*
** This is the xExprCallback for a tree walker. It is used to
** implement sqlite3ExprAnalyzeAggregates(). See sqlite3ExprAnalyzeAggregates
** for additional information.
|
| ︙ | ︙ | |||
117534 117535 117536 117537 117538 117539 117540 117541 117542 117543 117544 117545 117546 |
&& pWalker->walkerDepth==pExpr->op2
&& pExpr->pAggInfo==0
){
/* Check to see if pExpr is a duplicate of another aggregate
** function that is already in the pAggInfo structure
*/
struct AggInfo_func *pItem = pAggInfo->aFunc;
for(i=0; i<pAggInfo->nFunc; i++, pItem++){
if( NEVER(pItem->pFExpr==pExpr) ) break;
if( sqlite3ExprCompare(0, pItem->pFExpr, pExpr, -1)==0 ){
break;
}
}
| > > > > > > | | 117956 117957 117958 117959 117960 117961 117962 117963 117964 117965 117966 117967 117968 117969 117970 117971 117972 117973 117974 117975 117976 117977 117978 117979 117980 117981 117982 |
&& pWalker->walkerDepth==pExpr->op2
&& pExpr->pAggInfo==0
){
/* Check to see if pExpr is a duplicate of another aggregate
** function that is already in the pAggInfo structure
*/
struct AggInfo_func *pItem = pAggInfo->aFunc;
int mxTerm = pParse->db->aLimit[SQLITE_LIMIT_COLUMN];
assert( mxTerm <= SMXV(i16) );
for(i=0; i<pAggInfo->nFunc; i++, pItem++){
if( NEVER(pItem->pFExpr==pExpr) ) break;
if( sqlite3ExprCompare(0, pItem->pFExpr, pExpr, -1)==0 ){
break;
}
}
if( i>mxTerm ){
sqlite3ErrorMsg(pParse, "more than %d aggregate terms", mxTerm);
i = mxTerm;
assert( i<pAggInfo->nFunc );
}else if( i>=pAggInfo->nFunc ){
/* pExpr is original. Make a new entry in pAggInfo->aFunc[]
*/
u8 enc = ENC(pParse->db);
i = addAggInfoFunc(pParse->db, pAggInfo);
if( i>=0 ){
int nArg;
assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
|
| ︙ | ︙ | |||
117594 117595 117596 117597 117598 117599 117600 117601 117602 117603 117604 117605 117606 117607 |
}
}
}
/* Make pExpr point to the appropriate pAggInfo->aFunc[] entry
*/
assert( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) );
ExprSetVVAProperty(pExpr, EP_NoReduce);
pExpr->iAgg = (i16)i;
pExpr->pAggInfo = pAggInfo;
return WRC_Prune;
}else{
return WRC_Continue;
}
}
| > | 118022 118023 118024 118025 118026 118027 118028 118029 118030 118031 118032 118033 118034 118035 118036 |
}
}
}
/* Make pExpr point to the appropriate pAggInfo->aFunc[] entry
*/
assert( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) );
ExprSetVVAProperty(pExpr, EP_NoReduce);
assert( i <= SMXV(pExpr->iAgg) );
pExpr->iAgg = (i16)i;
pExpr->pAggInfo = pAggInfo;
return WRC_Prune;
}else{
return WRC_Continue;
}
}
|
| ︙ | ︙ | |||
118996 118997 118998 118999 119000 119001 119002 |
if( zQuot==0 ){
return SQLITE_NOMEM;
}else{
nQuot = sqlite3Strlen30(zQuot)-1;
}
assert( nQuot>=nNew && nSql>=0 && nNew>=0 );
| | | | 119425 119426 119427 119428 119429 119430 119431 119432 119433 119434 119435 119436 119437 119438 119439 119440 119441 119442 |
if( zQuot==0 ){
return SQLITE_NOMEM;
}else{
nQuot = sqlite3Strlen30(zQuot)-1;
}
assert( nQuot>=nNew && nSql>=0 && nNew>=0 );
zOut = sqlite3DbMallocZero(db, (u64)nSql + pRename->nList*(u64)nQuot + 1);
}else{
assert( nSql>0 );
zOut = (char*)sqlite3DbMallocZero(db, (2*(u64)nSql + 1) * 3);
if( zOut ){
zBuf1 = &zOut[nSql*2+1];
zBuf2 = &zOut[nSql*4+2];
}
}
/* At this point pRename->pList contains a list of RenameToken objects
|
| ︙ | ︙ | |||
121681 121682 121683 121684 121685 121686 121687 |
else if( sqlite3_strglob("costmult=[0-9]*",z)==0 ){
pIndex->pTable->costMult = sqlite3LogEst(sqlite3Atoi(z+9));
}
#endif
while( z[0]!=0 && z[0]!=' ' ) z++;
while( z[0]==' ' ) z++;
}
| < < < < < < < < < < | 122110 122111 122112 122113 122114 122115 122116 122117 122118 122119 122120 122121 122122 122123 |
else if( sqlite3_strglob("costmult=[0-9]*",z)==0 ){
pIndex->pTable->costMult = sqlite3LogEst(sqlite3Atoi(z+9));
}
#endif
while( z[0]!=0 && z[0]!=' ' ) z++;
while( z[0]==' ' ) z++;
}
}
}
/*
** This callback is invoked once for each index when reading the
** sqlite_stat1 table.
**
|
| ︙ | ︙ | |||
124089 124090 124091 124092 124093 124094 124095 |
** find the (first) offset of that column in index pIdx. Or return -1
** if column iCol is not used in index pIdx.
*/
SQLITE_PRIVATE int sqlite3TableColumnToIndex(Index *pIdx, int iCol){
int i;
i16 iCol16;
assert( iCol>=(-1) && iCol<=SQLITE_MAX_COLUMN );
| | | 124508 124509 124510 124511 124512 124513 124514 124515 124516 124517 124518 124519 124520 124521 124522 |
** find the (first) offset of that column in index pIdx. Or return -1
** if column iCol is not used in index pIdx.
*/
SQLITE_PRIVATE int sqlite3TableColumnToIndex(Index *pIdx, int iCol){
int i;
i16 iCol16;
assert( iCol>=(-1) && iCol<=SQLITE_MAX_COLUMN );
assert( pIdx->nColumn<=SQLITE_MAX_COLUMN+1 );
iCol16 = iCol;
for(i=0; i<pIdx->nColumn; i++){
if( iCol16==pIdx->aiColumn[i] ){
return i;
}
}
return -1;
|
| ︙ | ︙ | |||
127237 127238 127239 127240 127241 127242 127243 |
pIndex->uniqNotNull = 0;
pIndex->bHasExpr = 1;
}else{
j = pCExpr->iColumn;
assert( j<=0x7fff );
if( j<0 ){
j = pTab->iPKey;
| < | 127656 127657 127658 127659 127660 127661 127662 127663 127664 127665 127666 127667 127668 127669 |
pIndex->uniqNotNull = 0;
pIndex->bHasExpr = 1;
}else{
j = pCExpr->iColumn;
assert( j<=0x7fff );
if( j<0 ){
j = pTab->iPKey;
}else{
if( pTab->aCol[j].notNull==0 ){
pIndex->uniqNotNull = 0;
}
if( pTab->aCol[j].colFlags & COLFLAG_VIRTUAL ){
pIndex->bHasVCol = 1;
pIndex->bHasExpr = 1;
|
| ︙ | ︙ | |||
128156 128157 128158 128159 128160 128161 128162 |
/*
** Append the contents of SrcList p2 to SrcList p1 and return the resulting
** SrcList. Or, if an error occurs, return NULL. In all cases, p1 and p2
** are deleted by this function.
*/
SQLITE_PRIVATE SrcList *sqlite3SrcListAppendList(Parse *pParse, SrcList *p1, SrcList *p2){
| | > > > > | | > > > < | 128574 128575 128576 128577 128578 128579 128580 128581 128582 128583 128584 128585 128586 128587 128588 128589 128590 128591 128592 128593 128594 128595 128596 128597 128598 128599 128600 128601 128602 128603 |
/*
** Append the contents of SrcList p2 to SrcList p1 and return the resulting
** SrcList. Or, if an error occurs, return NULL. In all cases, p1 and p2
** are deleted by this function.
*/
SQLITE_PRIVATE SrcList *sqlite3SrcListAppendList(Parse *pParse, SrcList *p1, SrcList *p2){
assert( p1 );
assert( p2 || pParse->nErr );
assert( p2==0 || p2->nSrc>=1 );
testcase( p1->nSrc==0 );
if( p2 ){
int nOld = p1->nSrc;
SrcList *pNew = sqlite3SrcListEnlarge(pParse, p1, p2->nSrc, nOld);
if( pNew==0 ){
sqlite3SrcListDelete(pParse->db, p2);
}else{
p1 = pNew;
memcpy(&p1->a[nOld], p2->a, p2->nSrc*sizeof(SrcItem));
assert( nOld==1 || (p2->a[0].fg.jointype & JT_LTORJ)==0 );
assert( p1->nSrc>=1 );
p1->a[0].fg.jointype |= (JT_LTORJ & p2->a[0].fg.jointype);
sqlite3DbFree(pParse->db, p2);
}
}
return p1;
}
/*
** Add the list of function arguments to the SrcList entry for a
|
| ︙ | ︙ | |||
132062 132063 132064 132065 132066 132067 132068 |
static void concatFuncCore(
sqlite3_context *context,
int argc,
sqlite3_value **argv,
int nSep,
const char *zSep
){
| | > | < | 132486 132487 132488 132489 132490 132491 132492 132493 132494 132495 132496 132497 132498 132499 132500 132501 132502 132503 132504 132505 132506 132507 132508 132509 132510 132511 132512 132513 132514 132515 |
static void concatFuncCore(
sqlite3_context *context,
int argc,
sqlite3_value **argv,
int nSep,
const char *zSep
){
i64 j, n = 0;
int i;
char *z;
for(i=0; i<argc; i++){
n += sqlite3_value_bytes(argv[i]);
}
n += (argc-1)*(i64)nSep;
z = sqlite3_malloc64(n+1);
if( z==0 ){
sqlite3_result_error_nomem(context);
return;
}
j = 0;
for(i=0; i<argc; i++){
if( sqlite3_value_type(argv[i])!=SQLITE_NULL ){
int k = sqlite3_value_bytes(argv[i]);
const char *v = (const char*)sqlite3_value_text(argv[i]);
if( v!=0 ){
if( j>0 && nSep>0 ){
memcpy(&z[j], zSep, nSep);
j += nSep;
}
memcpy(&z[j], v, k);
|
| ︙ | ︙ | |||
135015 135016 135017 135018 135019 135020 135021 135022 135023 135024 135025 135026 |
char *zColAff;
if( pTab->tabFlags & TF_Strict ){
if( iReg==0 ){
/* Move the previous opcode (which should be OP_MakeRecord) forward
** by one slot and insert a new OP_TypeCheck where the current
** OP_MakeRecord is found */
VdbeOp *pPrev;
sqlite3VdbeAppendP4(v, pTab, P4_TABLE);
pPrev = sqlite3VdbeGetLastOp(v);
assert( pPrev!=0 );
assert( pPrev->opcode==OP_MakeRecord || sqlite3VdbeDb(v)->mallocFailed );
pPrev->opcode = OP_TypeCheck;
| > > > | | 135439 135440 135441 135442 135443 135444 135445 135446 135447 135448 135449 135450 135451 135452 135453 135454 135455 135456 135457 135458 135459 135460 135461 |
char *zColAff;
if( pTab->tabFlags & TF_Strict ){
if( iReg==0 ){
/* Move the previous opcode (which should be OP_MakeRecord) forward
** by one slot and insert a new OP_TypeCheck where the current
** OP_MakeRecord is found */
VdbeOp *pPrev;
int p3;
sqlite3VdbeAppendP4(v, pTab, P4_TABLE);
pPrev = sqlite3VdbeGetLastOp(v);
assert( pPrev!=0 );
assert( pPrev->opcode==OP_MakeRecord || sqlite3VdbeDb(v)->mallocFailed );
pPrev->opcode = OP_TypeCheck;
p3 = pPrev->p3;
pPrev->p3 = 0;
sqlite3VdbeAddOp3(v, OP_MakeRecord, pPrev->p1, pPrev->p2, p3);
}else{
/* Insert an isolated OP_Typecheck */
sqlite3VdbeAddOp2(v, OP_TypeCheck, iReg, pTab->nNVCol);
sqlite3VdbeAppendP4(v, pTab, P4_TABLE);
}
return;
}
|
| ︙ | ︙ | |||
138753 138754 138755 138756 138757 138758 138759 138760 138761 138762 138763 138764 138765 138766 | /* Version 3.41.0 and later */ int (*is_interrupted)(sqlite3*); /* Version 3.43.0 and later */ int (*stmt_explain)(sqlite3_stmt*,int); /* Version 3.44.0 and later */ void *(*get_clientdata)(sqlite3*,const char*); int (*set_clientdata)(sqlite3*, const char*, void*, void(*)(void*)); }; /* ** This is the function signature used for all extension entry points. It ** is also defined in the file "loadext.c". */ typedef int (*sqlite3_loadext_entry)( | > > | 139180 139181 139182 139183 139184 139185 139186 139187 139188 139189 139190 139191 139192 139193 139194 139195 | /* Version 3.41.0 and later */ int (*is_interrupted)(sqlite3*); /* Version 3.43.0 and later */ int (*stmt_explain)(sqlite3_stmt*,int); /* Version 3.44.0 and later */ void *(*get_clientdata)(sqlite3*,const char*); int (*set_clientdata)(sqlite3*, const char*, void*, void(*)(void*)); /* Version 3.50.0 and later */ int (*setlk_timeout)(sqlite3*,int,int); }; /* ** This is the function signature used for all extension entry points. It ** is also defined in the file "loadext.c". */ typedef int (*sqlite3_loadext_entry)( |
| ︙ | ︙ | |||
139086 139087 139088 139089 139090 139091 139092 139093 139094 139095 139096 139097 139098 139099 | /* Version 3.41.0 and later */ #define sqlite3_is_interrupted sqlite3_api->is_interrupted /* Version 3.43.0 and later */ #define sqlite3_stmt_explain sqlite3_api->stmt_explain /* Version 3.44.0 and later */ #define sqlite3_get_clientdata sqlite3_api->get_clientdata #define sqlite3_set_clientdata sqlite3_api->set_clientdata #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */ #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) /* This case when the file really is being compiled as a loadable ** extension */ # define SQLITE_EXTENSION_INIT1 const sqlite3_api_routines *sqlite3_api=0; # define SQLITE_EXTENSION_INIT2(v) sqlite3_api=v; | > > | 139515 139516 139517 139518 139519 139520 139521 139522 139523 139524 139525 139526 139527 139528 139529 139530 | /* Version 3.41.0 and later */ #define sqlite3_is_interrupted sqlite3_api->is_interrupted /* Version 3.43.0 and later */ #define sqlite3_stmt_explain sqlite3_api->stmt_explain /* Version 3.44.0 and later */ #define sqlite3_get_clientdata sqlite3_api->get_clientdata #define sqlite3_set_clientdata sqlite3_api->set_clientdata /* Version 3.50.0 and later */ #define sqlite3_setlk_timeout sqlite3_api->setlk_timeout #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */ #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) /* This case when the file really is being compiled as a loadable ** extension */ # define SQLITE_EXTENSION_INIT1 const sqlite3_api_routines *sqlite3_api=0; # define SQLITE_EXTENSION_INIT2(v) sqlite3_api=v; |
| ︙ | ︙ | |||
139607 139608 139609 139610 139611 139612 139613 | sqlite3_value_encoding, /* Version 3.41.0 and later */ sqlite3_is_interrupted, /* Version 3.43.0 and later */ sqlite3_stmt_explain, /* Version 3.44.0 and later */ sqlite3_get_clientdata, | | > > | 140038 140039 140040 140041 140042 140043 140044 140045 140046 140047 140048 140049 140050 140051 140052 140053 140054 | sqlite3_value_encoding, /* Version 3.41.0 and later */ sqlite3_is_interrupted, /* Version 3.43.0 and later */ sqlite3_stmt_explain, /* Version 3.44.0 and later */ sqlite3_get_clientdata, sqlite3_set_clientdata, /* Version 3.50.0 and later */ sqlite3_setlk_timeout }; /* True if x is the directory separator character */ #if SQLITE_OS_WIN # define DirSep(X) ((X)=='/'||(X)=='\\') #else |
| ︙ | ︙ | |||
145233 145234 145235 145236 145237 145238 145239 | */ static int tableAndColumnIndex( SrcList *pSrc, /* Array of tables to search */ int iStart, /* First member of pSrc->a[] to check */ int iEnd, /* Last member of pSrc->a[] to check */ const char *zCol, /* Name of the column we are looking for */ int *piTab, /* Write index of pSrc->a[] here */ | | | 145666 145667 145668 145669 145670 145671 145672 145673 145674 145675 145676 145677 145678 145679 145680 |
*/
static int tableAndColumnIndex(
SrcList *pSrc, /* Array of tables to search */
int iStart, /* First member of pSrc->a[] to check */
int iEnd, /* Last member of pSrc->a[] to check */
const char *zCol, /* Name of the column we are looking for */
int *piTab, /* Write index of pSrc->a[] here */
int *piCol, /* Write index of pSrc->a[*piTab].pSTab->aCol[] here */
int bIgnoreHidden /* Ignore hidden columns */
){
int i; /* For looping over tables in pSrc */
int iCol; /* Index of column matching zCol */
assert( iEnd<pSrc->nSrc );
assert( iStart>=0 );
|
| ︙ | ︙ | |||
145445 145446 145447 145448 145449 145450 145451 |
){
sqlite3ErrorMsg(pParse, "cannot join using column %s - column "
"not present in both tables", zName);
return 1;
}
pE1 = sqlite3CreateColumnExpr(db, pSrc, iLeft, iLeftCol);
sqlite3SrcItemColumnUsed(&pSrc->a[iLeft], iLeftCol);
| | > > > > | > > > > | 145878 145879 145880 145881 145882 145883 145884 145885 145886 145887 145888 145889 145890 145891 145892 145893 145894 145895 145896 145897 145898 145899 145900 145901 145902 145903 145904 145905 145906 145907 145908 145909 145910 145911 145912 145913 145914 145915 145916 145917 145918 145919 145920 145921 145922 145923 145924 145925 145926 145927 145928 145929 145930 145931 145932 |
){
sqlite3ErrorMsg(pParse, "cannot join using column %s - column "
"not present in both tables", zName);
return 1;
}
pE1 = sqlite3CreateColumnExpr(db, pSrc, iLeft, iLeftCol);
sqlite3SrcItemColumnUsed(&pSrc->a[iLeft], iLeftCol);
if( (pSrc->a[0].fg.jointype & JT_LTORJ)!=0 && pParse->nErr==0 ){
/* This branch runs if the query contains one or more RIGHT or FULL
** JOINs. If only a single table on the left side of this join
** contains the zName column, then this branch is a no-op.
** But if there are two or more tables on the left side
** of the join, construct a coalesce() function that gathers all
** such tables. Raise an error if more than one of those references
** to zName is not also within a prior USING clause.
**
** We really ought to raise an error if there are two or more
** non-USING references to zName on the left of an INNER or LEFT
** JOIN. But older versions of SQLite do not do that, so we avoid
** adding a new error so as to not break legacy applications.
*/
ExprList *pFuncArgs = 0; /* Arguments to the coalesce() */
static const Token tkCoalesce = { "coalesce", 8 };
assert( pE1!=0 );
ExprSetProperty(pE1, EP_CanBeNull);
while( tableAndColumnIndex(pSrc, iLeft+1, i, zName, &iLeft, &iLeftCol,
pRight->fg.isSynthUsing)!=0 ){
if( pSrc->a[iLeft].fg.isUsing==0
|| sqlite3IdListIndex(pSrc->a[iLeft].u3.pUsing, zName)<0
){
sqlite3ErrorMsg(pParse, "ambiguous reference to %s in USING()",
zName);
break;
}
pFuncArgs = sqlite3ExprListAppend(pParse, pFuncArgs, pE1);
pE1 = sqlite3CreateColumnExpr(db, pSrc, iLeft, iLeftCol);
sqlite3SrcItemColumnUsed(&pSrc->a[iLeft], iLeftCol);
}
if( pFuncArgs ){
pFuncArgs = sqlite3ExprListAppend(pParse, pFuncArgs, pE1);
pE1 = sqlite3ExprFunction(pParse, pFuncArgs, &tkCoalesce, 0);
if( pE1 ){
pE1->affExpr = SQLITE_AFF_DEFER;
}
}
}else if( (pSrc->a[i+1].fg.jointype & JT_LEFT)!=0 && pParse->nErr==0 ){
assert( pE1!=0 );
ExprSetProperty(pE1, EP_CanBeNull);
}
pE2 = sqlite3CreateColumnExpr(db, pSrc, i+1, iRightCol);
sqlite3SrcItemColumnUsed(pRight, iRightCol);
pEq = sqlite3PExpr(pParse, TK_EQ, pE1, pE2);
assert( pE2!=0 || pEq==0 );
if( pEq ){
ExprSetProperty(pEq, joinType);
|
| ︙ | ︙ | |||
146954 146955 146956 146957 146958 146959 146960 146961 146962 146963 146964 146965 146966 146967 |
sqlite3VdbeSetColName(v, i, COLNAME_TABLE, zOrigTab, SQLITE_TRANSIENT);
sqlite3VdbeSetColName(v, i, COLNAME_COLUMN, zOrigCol, SQLITE_TRANSIENT);
#else
zType = columnType(&sNC, p, 0, 0, 0);
#endif
sqlite3VdbeSetColName(v, i, COLNAME_DECLTYPE, zType, SQLITE_TRANSIENT);
}
#endif /* !defined(SQLITE_OMIT_DECLTYPE) */
}
/*
** Compute the column names for a SELECT statement.
**
| > > > > | 147395 147396 147397 147398 147399 147400 147401 147402 147403 147404 147405 147406 147407 147408 147409 147410 147411 147412 |
sqlite3VdbeSetColName(v, i, COLNAME_TABLE, zOrigTab, SQLITE_TRANSIENT);
sqlite3VdbeSetColName(v, i, COLNAME_COLUMN, zOrigCol, SQLITE_TRANSIENT);
#else
zType = columnType(&sNC, p, 0, 0, 0);
#endif
sqlite3VdbeSetColName(v, i, COLNAME_DECLTYPE, zType, SQLITE_TRANSIENT);
}
#else
UNUSED_PARAMETER(pParse);
UNUSED_PARAMETER(pTabList);
UNUSED_PARAMETER(pEList);
#endif /* !defined(SQLITE_OMIT_DECLTYPE) */
}
/*
** Compute the column names for a SELECT statement.
**
|
| ︙ | ︙ | |||
147873 147874 147875 147876 147877 147878 147879 147880 147881 147882 147883 147884 147885 147886 147887 |
case TK_EXCEPT:
case TK_UNION: {
int unionTab; /* Cursor number of the temp table holding result */
u8 op = 0; /* One of the SRT_ operations to apply to self */
int priorOp; /* The SRT_ operation to apply to prior selects */
Expr *pLimit; /* Saved values of p->nLimit */
int addr;
SelectDest uniondest;
testcase( p->op==TK_EXCEPT );
testcase( p->op==TK_UNION );
priorOp = SRT_Union;
if( dest.eDest==priorOp ){
/* We can reuse a temporary table generated by a SELECT to our
** right.
| > > | 148318 148319 148320 148321 148322 148323 148324 148325 148326 148327 148328 148329 148330 148331 148332 148333 148334 |
case TK_EXCEPT:
case TK_UNION: {
int unionTab; /* Cursor number of the temp table holding result */
u8 op = 0; /* One of the SRT_ operations to apply to self */
int priorOp; /* The SRT_ operation to apply to prior selects */
Expr *pLimit; /* Saved values of p->nLimit */
int addr;
int emptyBypass = 0; /* IfEmpty opcode to bypass RHS */
SelectDest uniondest;
testcase( p->op==TK_EXCEPT );
testcase( p->op==TK_UNION );
priorOp = SRT_Union;
if( dest.eDest==priorOp ){
/* We can reuse a temporary table generated by a SELECT to our
** right.
|
| ︙ | ︙ | |||
147912 147913 147914 147915 147916 147917 147918 147919 147920 147921 147922 147923 147924 147925 147926 147927 147928 147929 147930 147931 147932 147933 147934 147935 147936 147937 147938 147939 147940 147941 147942 147943 147944 147945 |
goto multi_select_end;
}
/* Code the current SELECT statement
*/
if( p->op==TK_EXCEPT ){
op = SRT_Except;
}else{
assert( p->op==TK_UNION );
op = SRT_Union;
}
p->pPrior = 0;
pLimit = p->pLimit;
p->pLimit = 0;
uniondest.eDest = op;
ExplainQueryPlan((pParse, 1, "%s USING TEMP B-TREE",
sqlite3SelectOpName(p->op)));
TREETRACE(0x200, pParse, p, ("multiSelect EXCEPT/UNION right...\n"));
rc = sqlite3Select(pParse, p, &uniondest);
testcase( rc!=SQLITE_OK );
assert( p->pOrderBy==0 );
pDelete = p->pPrior;
p->pPrior = pPrior;
p->pOrderBy = 0;
if( p->op==TK_UNION ){
p->nSelectRow = sqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow);
}
sqlite3ExprDelete(db, p->pLimit);
p->pLimit = pLimit;
p->iLimit = 0;
p->iOffset = 0;
/* Convert the data in the temporary table into whatever form
** it is that we currently need.
| > > > | 148359 148360 148361 148362 148363 148364 148365 148366 148367 148368 148369 148370 148371 148372 148373 148374 148375 148376 148377 148378 148379 148380 148381 148382 148383 148384 148385 148386 148387 148388 148389 148390 148391 148392 148393 148394 148395 |
goto multi_select_end;
}
/* Code the current SELECT statement
*/
if( p->op==TK_EXCEPT ){
op = SRT_Except;
emptyBypass = sqlite3VdbeAddOp1(v, OP_IfEmpty, unionTab);
VdbeCoverage(v);
}else{
assert( p->op==TK_UNION );
op = SRT_Union;
}
p->pPrior = 0;
pLimit = p->pLimit;
p->pLimit = 0;
uniondest.eDest = op;
ExplainQueryPlan((pParse, 1, "%s USING TEMP B-TREE",
sqlite3SelectOpName(p->op)));
TREETRACE(0x200, pParse, p, ("multiSelect EXCEPT/UNION right...\n"));
rc = sqlite3Select(pParse, p, &uniondest);
testcase( rc!=SQLITE_OK );
assert( p->pOrderBy==0 );
pDelete = p->pPrior;
p->pPrior = pPrior;
p->pOrderBy = 0;
if( p->op==TK_UNION ){
p->nSelectRow = sqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow);
}
if( emptyBypass ) sqlite3VdbeJumpHere(v, emptyBypass);
sqlite3ExprDelete(db, p->pLimit);
p->pLimit = pLimit;
p->iLimit = 0;
p->iOffset = 0;
/* Convert the data in the temporary table into whatever form
** it is that we currently need.
|
| ︙ | ︙ | |||
147962 147963 147964 147965 147966 147967 147968 |
}
break;
}
default: assert( p->op==TK_INTERSECT ); {
int tab1, tab2;
int iCont, iBreak, iStart;
Expr *pLimit;
| | > | 148412 148413 148414 148415 148416 148417 148418 148419 148420 148421 148422 148423 148424 148425 148426 148427 148428 148429 |
}
break;
}
default: assert( p->op==TK_INTERSECT ); {
int tab1, tab2;
int iCont, iBreak, iStart;
Expr *pLimit;
int addr, iLimit, iOffset;
SelectDest intersectdest;
int r1;
int emptyBypass;
/* INTERSECT is different from the others since it requires
** two temporary tables. Hence it has its own case. Begin
** by allocating the tables we will need.
*/
tab1 = pParse->nTab++;
tab2 = pParse->nTab++;
|
| ︙ | ︙ | |||
147989 147990 147991 147992 147993 147994 147995 147996 147997 147998 147999 148000 |
sqlite3SelectDestInit(&intersectdest, SRT_Union, tab1);
TREETRACE(0x400, pParse, p, ("multiSelect INTERSECT left...\n"));
rc = sqlite3Select(pParse, pPrior, &intersectdest);
if( rc ){
goto multi_select_end;
}
/* Code the current SELECT into temporary table "tab2"
*/
addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, tab2, 0);
assert( p->addrOpenEphm[1] == -1 );
p->addrOpenEphm[1] = addr;
| > > > > > > | > > > > > > > > > > > > < < < | > > | 148440 148441 148442 148443 148444 148445 148446 148447 148448 148449 148450 148451 148452 148453 148454 148455 148456 148457 148458 148459 148460 148461 148462 148463 148464 148465 148466 148467 148468 148469 148470 148471 148472 148473 148474 148475 148476 148477 148478 148479 148480 148481 148482 148483 148484 148485 148486 148487 148488 148489 148490 148491 148492 148493 148494 148495 148496 148497 148498 148499 148500 148501 148502 148503 148504 148505 148506 148507 148508 148509 148510 148511 148512 |
sqlite3SelectDestInit(&intersectdest, SRT_Union, tab1);
TREETRACE(0x400, pParse, p, ("multiSelect INTERSECT left...\n"));
rc = sqlite3Select(pParse, pPrior, &intersectdest);
if( rc ){
goto multi_select_end;
}
/* Initialize LIMIT counters before checking to see if the LHS
** is empty, in case the jump is taken */
iBreak = sqlite3VdbeMakeLabel(pParse);
computeLimitRegisters(pParse, p, iBreak);
emptyBypass = sqlite3VdbeAddOp1(v, OP_IfEmpty, tab1); VdbeCoverage(v);
/* Code the current SELECT into temporary table "tab2"
*/
addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, tab2, 0);
assert( p->addrOpenEphm[1] == -1 );
p->addrOpenEphm[1] = addr;
/* Disable prior SELECTs and the LIMIT counters during the computation
** of the RHS select */
pLimit = p->pLimit;
iLimit = p->iLimit;
iOffset = p->iOffset;
p->pPrior = 0;
p->pLimit = 0;
p->iLimit = 0;
p->iOffset = 0;
intersectdest.iSDParm = tab2;
ExplainQueryPlan((pParse, 1, "%s USING TEMP B-TREE",
sqlite3SelectOpName(p->op)));
TREETRACE(0x400, pParse, p, ("multiSelect INTERSECT right...\n"));
rc = sqlite3Select(pParse, p, &intersectdest);
testcase( rc!=SQLITE_OK );
pDelete = p->pPrior;
p->pPrior = pPrior;
if( p->nSelectRow>pPrior->nSelectRow ){
p->nSelectRow = pPrior->nSelectRow;
}
sqlite3ExprDelete(db, p->pLimit);
/* Reinstate the LIMIT counters prior to running the final intersect */
p->pLimit = pLimit;
p->iLimit = iLimit;
p->iOffset = iOffset;
/* Generate code to take the intersection of the two temporary
** tables.
*/
if( rc ) break;
assert( p->pEList );
sqlite3VdbeAddOp1(v, OP_Rewind, tab1);
r1 = sqlite3GetTempReg(pParse);
iStart = sqlite3VdbeAddOp2(v, OP_RowData, tab1, r1);
iCont = sqlite3VdbeMakeLabel(pParse);
sqlite3VdbeAddOp4Int(v, OP_NotFound, tab2, iCont, r1, 0);
VdbeCoverage(v);
sqlite3ReleaseTempReg(pParse, r1);
selectInnerLoop(pParse, p, tab1,
0, 0, &dest, iCont, iBreak);
sqlite3VdbeResolveLabel(v, iCont);
sqlite3VdbeAddOp2(v, OP_Next, tab1, iStart); VdbeCoverage(v);
sqlite3VdbeResolveLabel(v, iBreak);
sqlite3VdbeAddOp2(v, OP_Close, tab2, 0);
sqlite3VdbeJumpHere(v, emptyBypass);
sqlite3VdbeAddOp2(v, OP_Close, tab1, 0);
break;
}
}
#ifndef SQLITE_OMIT_EXPLAIN
if( p->pNext==0 ){
|
| ︙ | ︙ | |||
148709 148710 148711 148712 148713 148714 148715 148716 148717 148718 148719 148720 148721 148722 |
** when processing a non-matched row of the left.
*/
typedef struct SubstContext {
Parse *pParse; /* The parsing context */
int iTable; /* Replace references to this table */
int iNewTable; /* New table number */
int isOuterJoin; /* Add TK_IF_NULL_ROW opcodes on each replacement */
ExprList *pEList; /* Replacement expressions */
ExprList *pCList; /* Collation sequences for replacement expr */
} SubstContext;
/* Forward Declarations */
static void substExprList(SubstContext*, ExprList*);
static void substSelect(SubstContext*, Select*, int);
| > | 149177 149178 149179 149180 149181 149182 149183 149184 149185 149186 149187 149188 149189 149190 149191 |
** when processing a non-matched row of the left.
*/
typedef struct SubstContext {
Parse *pParse; /* The parsing context */
int iTable; /* Replace references to this table */
int iNewTable; /* New table number */
int isOuterJoin; /* Add TK_IF_NULL_ROW opcodes on each replacement */
int nSelDepth; /* Depth of sub-query recursion. Top==1 */
ExprList *pEList; /* Replacement expressions */
ExprList *pCList; /* Collation sequences for replacement expr */
} SubstContext;
/* Forward Declarations */
static void substExprList(SubstContext*, ExprList*);
static void substSelect(SubstContext*, Select*, int);
|
| ︙ | ︙ | |||
148815 148816 148817 148818 148819 148820 148821 148822 148823 148824 148825 148826 148827 148828 |
sqlite3ExprDelete(db, pExpr);
pExpr = pNew;
}
}
}else{
if( pExpr->op==TK_IF_NULL_ROW && pExpr->iTable==pSubst->iTable ){
pExpr->iTable = pSubst->iNewTable;
}
pExpr->pLeft = substExpr(pSubst, pExpr->pLeft);
pExpr->pRight = substExpr(pSubst, pExpr->pRight);
if( ExprUseXSelect(pExpr) ){
substSelect(pSubst, pExpr->x.pSelect, 1);
}else{
substExprList(pSubst, pExpr->x.pList);
| > > > | 149284 149285 149286 149287 149288 149289 149290 149291 149292 149293 149294 149295 149296 149297 149298 149299 149300 |
sqlite3ExprDelete(db, pExpr);
pExpr = pNew;
}
}
}else{
if( pExpr->op==TK_IF_NULL_ROW && pExpr->iTable==pSubst->iTable ){
pExpr->iTable = pSubst->iNewTable;
}
if( pExpr->op==TK_AGG_FUNCTION && pExpr->op2>=pSubst->nSelDepth ){
pExpr->op2--;
}
pExpr->pLeft = substExpr(pSubst, pExpr->pLeft);
pExpr->pRight = substExpr(pSubst, pExpr->pRight);
if( ExprUseXSelect(pExpr) ){
substSelect(pSubst, pExpr->x.pSelect, 1);
}else{
substExprList(pSubst, pExpr->x.pList);
|
| ︙ | ︙ | |||
148853 148854 148855 148856 148857 148858 148859 148860 148861 148862 148863 148864 148865 148866 148867 148868 148869 148870 148871 148872 148873 148874 148875 148876 148877 148878 148879 148880 148881 148882 148883 |
Select *p, /* SELECT statement in which to make substitutions */
int doPrior /* Do substitutes on p->pPrior too */
){
SrcList *pSrc;
SrcItem *pItem;
int i;
if( !p ) return;
do{
substExprList(pSubst, p->pEList);
substExprList(pSubst, p->pGroupBy);
substExprList(pSubst, p->pOrderBy);
p->pHaving = substExpr(pSubst, p->pHaving);
p->pWhere = substExpr(pSubst, p->pWhere);
pSrc = p->pSrc;
assert( pSrc!=0 );
for(i=pSrc->nSrc, pItem=pSrc->a; i>0; i--, pItem++){
if( pItem->fg.isSubquery ){
substSelect(pSubst, pItem->u4.pSubq->pSelect, 1);
}
if( pItem->fg.isTabFunc ){
substExprList(pSubst, pItem->u1.pFuncArg);
}
}
}while( doPrior && (p = p->pPrior)!=0 );
}
#endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */
#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
/*
** pSelect is a SELECT statement and pSrcItem is one item in the FROM
** clause of that SELECT.
| > > | 149325 149326 149327 149328 149329 149330 149331 149332 149333 149334 149335 149336 149337 149338 149339 149340 149341 149342 149343 149344 149345 149346 149347 149348 149349 149350 149351 149352 149353 149354 149355 149356 149357 |
Select *p, /* SELECT statement in which to make substitutions */
int doPrior /* Do substitutes on p->pPrior too */
){
SrcList *pSrc;
SrcItem *pItem;
int i;
if( !p ) return;
pSubst->nSelDepth++;
do{
substExprList(pSubst, p->pEList);
substExprList(pSubst, p->pGroupBy);
substExprList(pSubst, p->pOrderBy);
p->pHaving = substExpr(pSubst, p->pHaving);
p->pWhere = substExpr(pSubst, p->pWhere);
pSrc = p->pSrc;
assert( pSrc!=0 );
for(i=pSrc->nSrc, pItem=pSrc->a; i>0; i--, pItem++){
if( pItem->fg.isSubquery ){
substSelect(pSubst, pItem->u4.pSubq->pSelect, 1);
}
if( pItem->fg.isTabFunc ){
substExprList(pSubst, pItem->u1.pFuncArg);
}
}
}while( doPrior && (p = p->pPrior)!=0 );
pSubst->nSelDepth--;
}
#endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */
#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
/*
** pSelect is a SELECT statement and pSrcItem is one item in the FROM
** clause of that SELECT.
|
| ︙ | ︙ | |||
149085 149086 149087 149088 149089 149090 149091 | ** (2a) the outer query must not be a join and ** (2b) the outer query must not use subqueries ** other than the one FROM-clause subquery that is a candidate ** for flattening. (This is due to ticket [2f7170d73bf9abf80] ** from 2015-02-09.) ** ** (3) If the subquery is the right operand of a LEFT JOIN then | | | | | 149559 149560 149561 149562 149563 149564 149565 149566 149567 149568 149569 149570 149571 149572 149573 149574 149575 | ** (2a) the outer query must not be a join and ** (2b) the outer query must not use subqueries ** other than the one FROM-clause subquery that is a candidate ** for flattening. (This is due to ticket [2f7170d73bf9abf80] ** from 2015-02-09.) ** ** (3) If the subquery is the right operand of a LEFT JOIN then ** (3a) the subquery may not be a join ** (**) Was (3b): "the FROM clause of the subquery may not contain ** a virtual table" ** (**) Was: "The outer query may not have a GROUP BY." This case ** is now managed correctly ** (3d) the outer query may not be DISTINCT. ** See also (26) for restrictions on RIGHT JOIN. ** ** (4) The subquery can not be DISTINCT. ** |
| ︙ | ︙ | |||
149303 149304 149305 149306 149307 149308 149309 |
**
** which is not at all the same thing.
**
** See also tickets #306, #350, and #3300.
*/
if( (pSubitem->fg.jointype & (JT_OUTER|JT_LTORJ))!=0 ){
if( pSubSrc->nSrc>1 /* (3a) */
| | | 149777 149778 149779 149780 149781 149782 149783 149784 149785 149786 149787 149788 149789 149790 149791 |
**
** which is not at all the same thing.
**
** See also tickets #306, #350, and #3300.
*/
if( (pSubitem->fg.jointype & (JT_OUTER|JT_LTORJ))!=0 ){
if( pSubSrc->nSrc>1 /* (3a) */
/**** || IsVirtual(pSubSrc->a[0].pSTab) (3b)-omitted */
|| (p->selFlags & SF_Distinct)!=0 /* (3d) */
|| (pSubitem->fg.jointype & JT_RIGHT)!=0 /* (26) */
){
return 0;
}
isOuterJoin = 1;
}
|
| ︙ | ︙ | |||
149481 149482 149483 149484 149485 149486 149487 | } /* Defer deleting the Table object associated with the ** subquery until code generation is ** complete, since there may still exist Expr.pTab entries that ** refer to the subquery even after flattening. Ticket #3346. ** | | | 149955 149956 149957 149958 149959 149960 149961 149962 149963 149964 149965 149966 149967 149968 149969 |
}
/* Defer deleting the Table object associated with the
** subquery until code generation is
** complete, since there may still exist Expr.pTab entries that
** refer to the subquery even after flattening. Ticket #3346.
**
** pSubitem->pSTab is always non-NULL by test restrictions and tests above.
*/
if( ALWAYS(pSubitem->pSTab!=0) ){
Table *pTabToDel = pSubitem->pSTab;
if( pTabToDel->nTabRef==1 ){
Parse *pToplevel = sqlite3ParseToplevel(pParse);
sqlite3ParserAddCleanup(pToplevel, sqlite3DeleteTableGeneric, pTabToDel);
testcase( pToplevel->earlyCleanup );
|
| ︙ | ︙ | |||
149611 149612 149613 149614 149615 149616 149617 149618 149619 149620 149621 149622 149623 149624 |
}
if( db->mallocFailed==0 ){
SubstContext x;
x.pParse = pParse;
x.iTable = iParent;
x.iNewTable = iNewParent;
x.isOuterJoin = isOuterJoin;
x.pEList = pSub->pEList;
x.pCList = findLeftmostExprlist(pSub);
substSelect(&x, pParent, 0);
}
/* The flattened query is a compound if either the inner or the
** outer query is a compound. */
| > | 150085 150086 150087 150088 150089 150090 150091 150092 150093 150094 150095 150096 150097 150098 150099 |
}
if( db->mallocFailed==0 ){
SubstContext x;
x.pParse = pParse;
x.iTable = iParent;
x.iNewTable = iNewParent;
x.isOuterJoin = isOuterJoin;
x.nSelDepth = 0;
x.pEList = pSub->pEList;
x.pCList = findLeftmostExprlist(pSub);
substSelect(&x, pParent, 0);
}
/* The flattened query is a compound if either the inner or the
** outer query is a compound. */
|
| ︙ | ︙ | |||
150196 150197 150198 150199 150200 150201 150202 150203 150204 150205 150206 150207 150208 150209 |
SubstContext x;
pNew = sqlite3ExprDup(pParse->db, pWhere, 0);
unsetJoinExpr(pNew, -1, 1);
x.pParse = pParse;
x.iTable = pSrc->iCursor;
x.iNewTable = pSrc->iCursor;
x.isOuterJoin = 0;
x.pEList = pSubq->pEList;
x.pCList = findLeftmostExprlist(pSubq);
pNew = substExpr(&x, pNew);
#ifndef SQLITE_OMIT_WINDOWFUNC
if( pSubq->pWin && 0==pushDownWindowCheck(pParse, pSubq, pNew) ){
/* Restriction 6c has prevented push-down in this case */
sqlite3ExprDelete(pParse->db, pNew);
| > | 150671 150672 150673 150674 150675 150676 150677 150678 150679 150680 150681 150682 150683 150684 150685 |
SubstContext x;
pNew = sqlite3ExprDup(pParse->db, pWhere, 0);
unsetJoinExpr(pNew, -1, 1);
x.pParse = pParse;
x.iTable = pSrc->iCursor;
x.iNewTable = pSrc->iCursor;
x.isOuterJoin = 0;
x.nSelDepth = 0;
x.pEList = pSubq->pEList;
x.pCList = findLeftmostExprlist(pSubq);
pNew = substExpr(&x, pNew);
#ifndef SQLITE_OMIT_WINDOWFUNC
if( pSubq->pWin && 0==pushDownWindowCheck(pParse, pSubq, pNew) ){
/* Restriction 6c has prevented push-down in this case */
sqlite3ExprDelete(pParse->db, pNew);
|
| ︙ | ︙ | |||
150593 150594 150595 150596 150597 150598 150599 | /* ** This function checks if argument pFrom refers to a CTE declared by ** a WITH clause on the stack currently maintained by the parser (on the ** pParse->pWith linked list). And if currently processing a CTE ** CTE expression, through routine checks to see if the reference is ** a recursive reference to the CTE. ** | | | 151069 151070 151071 151072 151073 151074 151075 151076 151077 151078 151079 151080 151081 151082 151083 | /* ** This function checks if argument pFrom refers to a CTE declared by ** a WITH clause on the stack currently maintained by the parser (on the ** pParse->pWith linked list). And if currently processing a CTE ** CTE expression, through routine checks to see if the reference is ** a recursive reference to the CTE. ** ** If pFrom matches a CTE according to either of these two above, pFrom->pSTab ** and other fields are populated accordingly. ** ** Return 0 if no match is found. ** Return 1 if a match is found. ** Return 2 if an error condition is detected. */ static int resolveFromTermToCte( |
| ︙ | ︙ | |||
152219 152220 152221 152222 152223 152224 152225 152226 152227 152228 152229 152230 152231 152232 |
if( i==0 ) break;
i--;
pItem--;
if( pItem->fg.isSubquery ) return 0; /* (1c-i) */
}
return 1;
}
/*
** Generate byte-code for the SELECT statement given in the p argument.
**
** The results are returned according to the SelectDest structure.
** See comments in sqliteInt.h for further information.
**
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 152695 152696 152697 152698 152699 152700 152701 152702 152703 152704 152705 152706 152707 152708 152709 152710 152711 152712 152713 152714 152715 152716 152717 152718 152719 152720 152721 152722 152723 152724 152725 152726 152727 152728 152729 152730 152731 152732 152733 152734 152735 152736 152737 152738 152739 152740 152741 152742 152743 152744 152745 152746 152747 152748 152749 152750 152751 152752 152753 152754 152755 152756 152757 152758 152759 152760 152761 152762 152763 152764 152765 152766 152767 152768 152769 152770 152771 152772 152773 152774 152775 152776 152777 152778 152779 152780 152781 152782 152783 152784 152785 |
if( i==0 ) break;
i--;
pItem--;
if( pItem->fg.isSubquery ) return 0; /* (1c-i) */
}
return 1;
}
/*
** Argument pWhere is the WHERE clause belonging to SELECT statement p. This
** function attempts to transform expressions of the form:
**
** EXISTS (SELECT ...)
**
** into joins. For example, given
**
** CREATE TABLE sailors(sid INTEGER PRIMARY KEY, name TEXT);
** CREATE TABLE reserves(sid INT, day DATE, PRIMARY KEY(sid, day));
**
** SELECT name FROM sailors AS S WHERE EXISTS (
** SELECT * FROM reserves AS R WHERE S.sid = R.sid AND R.day = '2022-10-25'
** );
**
** the SELECT statement may be transformed as follows:
**
** SELECT name FROM sailors AS S, reserves AS R
** WHERE S.sid = R.sid AND R.day = '2022-10-25';
**
** **Approximately**. Really, we have to ensure that the FROM-clause term
** that was formerly inside the EXISTS is only executed once. This is handled
** by setting the SrcItem.fg.fromExists flag, which then causes code in
** the where.c file to exit the corresponding loop after the first successful
** match (if any).
*/
static SQLITE_NOINLINE void existsToJoin(
Parse *pParse, /* Parsing context */
Select *p, /* The SELECT statement being optimized */
Expr *pWhere /* part of the WHERE clause currently being examined */
){
if( pParse->nErr==0
&& pWhere!=0
&& !ExprHasProperty(pWhere, EP_OuterON|EP_InnerON)
&& ALWAYS(p->pSrc!=0)
&& p->pSrc->nSrc<BMS
){
if( pWhere->op==TK_AND ){
Expr *pRight = pWhere->pRight;
existsToJoin(pParse, p, pWhere->pLeft);
existsToJoin(pParse, p, pRight);
}
else if( pWhere->op==TK_EXISTS ){
Select *pSub = pWhere->x.pSelect;
Expr *pSubWhere = pSub->pWhere;
if( pSub->pSrc->nSrc==1
&& (pSub->selFlags & SF_Aggregate)==0
&& !pSub->pSrc->a[0].fg.isSubquery
){
memset(pWhere, 0, sizeof(*pWhere));
pWhere->op = TK_INTEGER;
pWhere->u.iValue = 1;
ExprSetProperty(pWhere, EP_IntValue);
assert( p->pWhere!=0 );
pSub->pSrc->a[0].fg.fromExists = 1;
pSub->pSrc->a[0].fg.jointype |= JT_CROSS;
p->pSrc = sqlite3SrcListAppendList(pParse, p->pSrc, pSub->pSrc);
if( pSubWhere ){
p->pWhere = sqlite3PExpr(pParse, TK_AND, p->pWhere, pSubWhere);
pSub->pWhere = 0;
}
pSub->pSrc = 0;
sqlite3ParserAddCleanup(pParse, sqlite3SelectDeleteGeneric, pSub);
#if TREETRACE_ENABLED
if( sqlite3TreeTrace & 0x100000 ){
TREETRACE(0x100000,pParse,p,
("After EXISTS-to-JOIN optimization:\n"));
sqlite3TreeViewSelect(0, p, 0);
}
#endif
existsToJoin(pParse, p, pSubWhere);
}
}
}
}
/*
** Generate byte-code for the SELECT statement given in the p argument.
**
** The results are returned according to the SelectDest structure.
** See comments in sqliteInt.h for further information.
**
|
| ︙ | ︙ | |||
152587 152588 152589 152590 152591 152592 152593 152594 152595 152596 152597 152598 152599 152600 |
sqlite3TreeViewSelect(0, p, 0);
}
#endif
if( p->pNext==0 ) ExplainQueryPlanPop(pParse);
return rc;
}
#endif
/* Do the WHERE-clause constant propagation optimization if this is
** a join. No need to spend time on this operation for non-join queries
** as the equivalent optimization will be handled by query planner in
** sqlite3WhereBegin(). tag-select-0330
*/
if( p->pWhere!=0
| > > > > > > > | 153140 153141 153142 153143 153144 153145 153146 153147 153148 153149 153150 153151 153152 153153 153154 153155 153156 153157 153158 153159 153160 |
sqlite3TreeViewSelect(0, p, 0);
}
#endif
if( p->pNext==0 ) ExplainQueryPlanPop(pParse);
return rc;
}
#endif
/* If there may be an "EXISTS (SELECT ...)" in the WHERE clause, attempt
** to change it into a join. */
if( pParse->bHasExists && OptimizationEnabled(db,SQLITE_ExistsToJoin) ){
existsToJoin(pParse, p, p->pWhere);
pTabList = p->pSrc;
}
/* Do the WHERE-clause constant propagation optimization if this is
** a join. No need to spend time on this operation for non-join queries
** as the equivalent optimization will be handled by query planner in
** sqlite3WhereBegin(). tag-select-0330
*/
if( p->pWhere!=0
|
| ︙ | ︙ | |||
153347 153348 153349 153350 153351 153352 153353 153354 153355 153356 153357 153358 153359 153360 |
pAggInfo->directMode = 1;
sqlite3ExprCode(pParse, pGroupBy->a[j].pExpr, iBMem+j);
}
if( iOrderByCol ){
Expr *pX = p->pEList->a[iOrderByCol-1].pExpr;
Expr *pBase = sqlite3ExprSkipCollateAndLikely(pX);
if( ALWAYS(pBase!=0)
&& pBase->op!=TK_AGG_COLUMN
&& pBase->op!=TK_REGISTER
){
sqlite3ExprToRegister(pX, iAMem+j);
}
}
| > > > > | 153907 153908 153909 153910 153911 153912 153913 153914 153915 153916 153917 153918 153919 153920 153921 153922 153923 153924 |
pAggInfo->directMode = 1;
sqlite3ExprCode(pParse, pGroupBy->a[j].pExpr, iBMem+j);
}
if( iOrderByCol ){
Expr *pX = p->pEList->a[iOrderByCol-1].pExpr;
Expr *pBase = sqlite3ExprSkipCollateAndLikely(pX);
while( ALWAYS(pBase!=0) && pBase->op==TK_IF_NULL_ROW ){
pX = pBase->pLeft;
pBase = sqlite3ExprSkipCollateAndLikely(pX);
}
if( ALWAYS(pBase!=0)
&& pBase->op!=TK_AGG_COLUMN
&& pBase->op!=TK_REGISTER
){
sqlite3ExprToRegister(pX, iAMem+j);
}
}
|
| ︙ | ︙ | |||
153370 153371 153372 153373 153374 153375 153376 |
**
** This code copies current group by terms in b0,b1,b2,...
** over to a0,a1,a2. It then calls the output subroutine
** and resets the aggregate accumulator registers in preparation
** for the next GROUP BY batch.
*/
sqlite3VdbeAddOp2(v, OP_Gosub, regOutputRow, addrOutputRow);
| | | | | | | | | 153934 153935 153936 153937 153938 153939 153940 153941 153942 153943 153944 153945 153946 153947 153948 153949 153950 153951 153952 153953 153954 153955 153956 153957 153958 153959 153960 153961 153962 153963 153964 153965 153966 153967 153968 153969 153970 153971 153972 153973 153974 153975 153976 153977 153978 153979 153980 153981 153982 153983 153984 153985 153986 153987 153988 153989 153990 153991 153992 153993 153994 153995 153996 153997 153998 153999 154000 154001 154002 154003 154004 154005 154006 154007 154008 154009 154010 154011 154012 154013 154014 |
**
** This code copies current group by terms in b0,b1,b2,...
** over to a0,a1,a2. It then calls the output subroutine
** and resets the aggregate accumulator registers in preparation
** for the next GROUP BY batch.
*/
sqlite3VdbeAddOp2(v, OP_Gosub, regOutputRow, addrOutputRow);
VdbeComment((v, "output one row of %d", p->selId));
sqlite3ExprCodeMove(pParse, iBMem, iAMem, pGroupBy->nExpr);
sqlite3VdbeAddOp2(v, OP_IfPos, iAbortFlag, addrEnd); VdbeCoverage(v);
VdbeComment((v, "check abort flag"));
sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset);
VdbeComment((v, "reset accumulator %d", p->selId));
/* Update the aggregate accumulators based on the content of
** the current row
*/
sqlite3VdbeJumpHere(v, addr1);
updateAccumulator(pParse, iUseFlag, pAggInfo, eDist);
sqlite3VdbeAddOp2(v, OP_Integer, 1, iUseFlag);
VdbeComment((v, "indicate data in accumulator %d", p->selId));
/* End of the loop
*/
if( groupBySort ){
sqlite3VdbeAddOp2(v, OP_SorterNext, pAggInfo->sortingIdx,addrTopOfLoop);
VdbeCoverage(v);
}else{
TREETRACE(0x2,pParse,p,("WhereEnd\n"));
sqlite3WhereEnd(pWInfo);
sqlite3VdbeChangeToNoop(v, addrSortingIdx);
}
sqlite3ExprListDelete(db, pDistinct);
/* Output the final row of result
*/
sqlite3VdbeAddOp2(v, OP_Gosub, regOutputRow, addrOutputRow);
VdbeComment((v, "output final row of %d", p->selId));
/* Jump over the subroutines
*/
sqlite3VdbeGoto(v, addrEnd);
/* Generate a subroutine that outputs a single row of the result
** set. This subroutine first looks at the iUseFlag. If iUseFlag
** is less than or equal to zero, the subroutine is a no-op. If
** the processing calls for the query to abort, this subroutine
** increments the iAbortFlag memory location before returning in
** order to signal the caller to abort.
*/
addrSetAbort = sqlite3VdbeCurrentAddr(v);
sqlite3VdbeAddOp2(v, OP_Integer, 1, iAbortFlag);
VdbeComment((v, "set abort flag"));
sqlite3VdbeAddOp1(v, OP_Return, regOutputRow);
sqlite3VdbeResolveLabel(v, addrOutputRow);
addrOutputRow = sqlite3VdbeCurrentAddr(v);
sqlite3VdbeAddOp2(v, OP_IfPos, iUseFlag, addrOutputRow+2);
VdbeCoverage(v);
VdbeComment((v, "Groupby result generator entry point %d", p->selId));
sqlite3VdbeAddOp1(v, OP_Return, regOutputRow);
finalizeAggFunctions(pParse, pAggInfo);
sqlite3ExprIfFalse(pParse, pHaving, addrOutputRow+1, SQLITE_JUMPIFNULL);
selectInnerLoop(pParse, p, -1, &sSort,
&sDistinct, pDest,
addrOutputRow+1, addrSetAbort);
sqlite3VdbeAddOp1(v, OP_Return, regOutputRow);
VdbeComment((v, "end groupby result generator %d", p->selId));
/* Generate a subroutine that will reset the group-by accumulator
*/
sqlite3VdbeResolveLabel(v, addrReset);
resetAccumulator(pParse, pAggInfo);
sqlite3VdbeAddOp2(v, OP_Integer, 0, iUseFlag);
VdbeComment((v, "indicate accumulator %d empty", p->selId));
sqlite3VdbeAddOp1(v, OP_Return, regReset);
if( distFlag!=0 && eDist!=WHERE_DISTINCT_NOOP ){
struct AggInfo_func *pF = &pAggInfo->aFunc[0];
fixDistinctOpenEph(pParse, eDist, pF->iDistinct, pF->iDistAddr);
}
} /* endif pGroupBy. Begin aggregate queries without GROUP BY: */
|
| ︙ | ︙ | |||
157324 157325 157326 157327 157328 157329 157330 | ** restored before returning. Then set the writable-schema flag, and ** disable CHECK and foreign key constraints. */ saved_flags = db->flags; saved_mDbFlags = db->mDbFlags; saved_nChange = db->nChange; saved_nTotalChange = db->nTotalChange; saved_mTrace = db->mTrace; | | > | 157888 157889 157890 157891 157892 157893 157894 157895 157896 157897 157898 157899 157900 157901 157902 157903 |
** restored before returning. Then set the writable-schema flag, and
** disable CHECK and foreign key constraints. */
saved_flags = db->flags;
saved_mDbFlags = db->mDbFlags;
saved_nChange = db->nChange;
saved_nTotalChange = db->nTotalChange;
saved_mTrace = db->mTrace;
db->flags |= SQLITE_WriteSchema | SQLITE_IgnoreChecks | SQLITE_Comments
| SQLITE_AttachCreate | SQLITE_AttachWrite;
db->mDbFlags |= DBFLAG_PreferBuiltin | DBFLAG_Vacuum;
db->flags &= ~(u64)(SQLITE_ForeignKeys | SQLITE_ReverseOrder
| SQLITE_Defensive | SQLITE_CountRows);
db->mTrace = 0;
zDbMain = db->aDb[iDb].zDbSName;
pMain = db->aDb[iDb].pBt;
|
| ︙ | ︙ | |||
159027 159028 159029 159030 159031 159032 159033 159034 159035 159036 159037 159038 159039 159040 |
** WhereInfo.a[WhereInfo.nLevel-1] being the inner loop.
*/
struct WhereLevel {
int iLeftJoin; /* Memory cell used to implement LEFT OUTER JOIN */
int iTabCur; /* The VDBE cursor used to access the table */
int iIdxCur; /* The VDBE cursor used to access pIdx */
int addrBrk; /* Jump here to break out of the loop */
int addrNxt; /* Jump here to start the next IN combination */
int addrSkip; /* Jump here for next iteration of skip-scan */
int addrCont; /* Jump here to continue with the next loop cycle */
int addrFirst; /* First instruction of interior of the loop */
int addrBody; /* Beginning of the body of this loop */
int regBignull; /* big-null flag reg. True if a NULL-scan is needed */
int addrBignull; /* Jump here for next part of big-null scan */
| > | 159592 159593 159594 159595 159596 159597 159598 159599 159600 159601 159602 159603 159604 159605 159606 |
** WhereInfo.a[WhereInfo.nLevel-1] being the inner loop.
*/
struct WhereLevel {
int iLeftJoin; /* Memory cell used to implement LEFT OUTER JOIN */
int iTabCur; /* The VDBE cursor used to access the table */
int iIdxCur; /* The VDBE cursor used to access pIdx */
int addrBrk; /* Jump here to break out of the loop */
int addrHalt; /* Abort the query due to empty table or similar */
int addrNxt; /* Jump here to start the next IN combination */
int addrSkip; /* Jump here for next iteration of skip-scan */
int addrCont; /* Jump here to continue with the next loop cycle */
int addrFirst; /* First instruction of interior of the loop */
int addrBody; /* Beginning of the body of this loop */
int regBignull; /* big-null flag reg. True if a NULL-scan is needed */
int addrBignull; /* Jump here for next part of big-null scan */
|
| ︙ | ︙ | |||
159232 159233 159234 159235 159236 159237 159238 159239 159240 159241 159242 159243 159244 159245 |
LogEst truthProb; /* Probability of truth for this expression */
u16 wtFlags; /* TERM_xxx bit flags. See below */
u16 eOperator; /* A WO_xx value describing <op> */
u8 nChild; /* Number of children that must disable us */
u8 eMatchOp; /* Op for vtab MATCH/LIKE/GLOB/REGEXP terms */
int iParent; /* Disable pWC->a[iParent] when this term disabled */
int leftCursor; /* Cursor number of X in "X <op> <expr>" */
union {
struct {
int leftColumn; /* Column number of X in "X <op> <expr>" */
int iField; /* Field in (?,?,?) IN (SELECT...) vector */
} x; /* Opcode other than OP_OR or OP_AND */
WhereOrInfo *pOrInfo; /* Extra information if (eOperator & WO_OR)!=0 */
WhereAndInfo *pAndInfo; /* Extra information if (eOperator& WO_AND)!=0 */
| > > > | 159798 159799 159800 159801 159802 159803 159804 159805 159806 159807 159808 159809 159810 159811 159812 159813 159814 |
LogEst truthProb; /* Probability of truth for this expression */
u16 wtFlags; /* TERM_xxx bit flags. See below */
u16 eOperator; /* A WO_xx value describing <op> */
u8 nChild; /* Number of children that must disable us */
u8 eMatchOp; /* Op for vtab MATCH/LIKE/GLOB/REGEXP terms */
int iParent; /* Disable pWC->a[iParent] when this term disabled */
int leftCursor; /* Cursor number of X in "X <op> <expr>" */
#ifdef SQLITE_DEBUG
int iTerm; /* Which WhereTerm is this, for debug purposes */
#endif
union {
struct {
int leftColumn; /* Column number of X in "X <op> <expr>" */
int iField; /* Field in (?,?,?) IN (SELECT...) vector */
} x; /* Opcode other than OP_OR or OP_AND */
WhereOrInfo *pOrInfo; /* Extra information if (eOperator & WO_OR)!=0 */
WhereAndInfo *pAndInfo; /* Extra information if (eOperator& WO_AND)!=0 */
|
| ︙ | ︙ | |||
159724 159725 159726 159727 159728 159729 159730 |
u16 wctrlFlags /* Flags passed to sqlite3WhereBegin() */
){
#if !defined(SQLITE_DEBUG)
if( sqlite3ParseToplevel(pParse)->explain==2 || IS_STMT_SCANSTATUS(pParse->db) )
#endif
{
VdbeOp *pOp = sqlite3VdbeGetOp(pParse->pVdbe, addr);
| < | 160293 160294 160295 160296 160297 160298 160299 160300 160301 160302 160303 160304 160305 160306 |
u16 wctrlFlags /* Flags passed to sqlite3WhereBegin() */
){
#if !defined(SQLITE_DEBUG)
if( sqlite3ParseToplevel(pParse)->explain==2 || IS_STMT_SCANSTATUS(pParse->db) )
#endif
{
VdbeOp *pOp = sqlite3VdbeGetOp(pParse->pVdbe, addr);
SrcItem *pItem = &pTabList->a[pLevel->iFrom];
sqlite3 *db = pParse->db; /* Database handle */
int isSearch; /* True for a SEARCH. False for SCAN. */
WhereLoop *pLoop; /* The controlling WhereLoop object */
u32 flags; /* Flags that describe this loop */
#if defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_EXPLAIN)
char *zMsg; /* Text to add to EQP output */
|
| ︙ | ︙ | |||
159747 159748 159749 159750 159751 159752 159753 |
isSearch = (flags&(WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))!=0
|| ((flags&WHERE_VIRTUALTABLE)==0 && (pLoop->u.btree.nEq>0))
|| (wctrlFlags&(WHERE_ORDERBY_MIN|WHERE_ORDERBY_MAX));
sqlite3StrAccumInit(&str, db, zBuf, sizeof(zBuf), SQLITE_MAX_LENGTH);
str.printfFlags = SQLITE_PRINTF_INTERNAL;
| | > > > | 160315 160316 160317 160318 160319 160320 160321 160322 160323 160324 160325 160326 160327 160328 160329 160330 160331 160332 |
isSearch = (flags&(WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))!=0
|| ((flags&WHERE_VIRTUALTABLE)==0 && (pLoop->u.btree.nEq>0))
|| (wctrlFlags&(WHERE_ORDERBY_MIN|WHERE_ORDERBY_MAX));
sqlite3StrAccumInit(&str, db, zBuf, sizeof(zBuf), SQLITE_MAX_LENGTH);
str.printfFlags = SQLITE_PRINTF_INTERNAL;
sqlite3_str_appendf(&str, "%s %S%s",
isSearch ? "SEARCH" : "SCAN",
pItem,
pItem->fg.fromExists ? " EXISTS" : "");
if( (flags & (WHERE_IPK|WHERE_VIRTUALTABLE))==0 ){
const char *zFmt = 0;
Index *pIdx;
assert( pLoop->u.btree.pIndex!=0 );
pIdx = pLoop->u.btree.pIndex;
assert( !(flags&WHERE_AUTO_INDEX) || (flags&WHERE_IDX_ONLY) );
|
| ︙ | ︙ | |||
160196 160197 160198 160199 160200 160201 160202 |
pOrigLhs = pNew->pLeft->x.pList;
}
for(i=iEq; i<pLoop->nLTerm; i++){
if( pLoop->aLTerm[i]->pExpr==pX ){
int iField;
assert( (pLoop->aLTerm[i]->eOperator & (WO_OR|WO_AND))==0 );
iField = pLoop->aLTerm[i]->u.x.iField - 1;
| > | > | 160767 160768 160769 160770 160771 160772 160773 160774 160775 160776 160777 160778 160779 160780 160781 160782 160783 |
pOrigLhs = pNew->pLeft->x.pList;
}
for(i=iEq; i<pLoop->nLTerm; i++){
if( pLoop->aLTerm[i]->pExpr==pX ){
int iField;
assert( (pLoop->aLTerm[i]->eOperator & (WO_OR|WO_AND))==0 );
iField = pLoop->aLTerm[i]->u.x.iField - 1;
if( NEVER(pOrigRhs->a[iField].pExpr==0) ){
continue; /* Duplicate PK column */
}
pRhs = sqlite3ExprListAppend(pParse, pRhs, pOrigRhs->a[iField].pExpr);
pOrigRhs->a[iField].pExpr = 0;
if( pRhs ) pRhs->a[pRhs->nExpr-1].u.x.iOrderByCol = iField+1;
if( pOrigLhs ){
assert( pOrigLhs->a[iField].pExpr!=0 );
pLhs = sqlite3ExprListAppend(pParse,pLhs,pOrigLhs->a[iField].pExpr);
pOrigLhs->a[iField].pExpr = 0;
|
| ︙ | ︙ | |||
160293 160294 160295 160296 160297 160298 160299 |
for(i=0; i<iEq; i++){
if( pLoop->aLTerm[i] && pLoop->aLTerm[i]->pExpr==pX ){
disableTerm(pLevel, pTerm);
return;
}
}
| | < < | | | | | < | | < < < < < < | 160866 160867 160868 160869 160870 160871 160872 160873 160874 160875 160876 160877 160878 160879 160880 160881 160882 160883 160884 160885 160886 160887 160888 160889 160890 160891 160892 160893 160894 160895 |
for(i=0; i<iEq; i++){
if( pLoop->aLTerm[i] && pLoop->aLTerm[i]->pExpr==pX ){
disableTerm(pLevel, pTerm);
return;
}
}
for(i=iEq; i<pLoop->nLTerm; i++){
assert( pLoop->aLTerm[i]!=0 );
if( pLoop->aLTerm[i]->pExpr==pX ) nEq++;
}
iTab = 0;
if( !ExprUseXSelect(pX) || pX->x.pSelect->pEList->nExpr==1 ){
eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, 0, &iTab);
}else{
sqlite3 *db = pParse->db;
Expr *pXMod = removeUnindexableInClauseTerms(pParse, iEq, pLoop, pX);
if( !db->mallocFailed ){
aiMap = (int*)sqlite3DbMallocZero(db, sizeof(int)*nEq);
eType = sqlite3FindInIndex(pParse, pXMod, IN_INDEX_LOOP, 0, aiMap, &iTab);
}
sqlite3ExprDelete(db, pXMod);
}
if( eType==IN_INDEX_INDEX_DESC ){
testcase( bRev );
bRev = !bRev;
}
sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iTab, 0);
|
| ︙ | ︙ | |||
160347 160348 160349 160350 160351 160352 160353 |
sqlite3WhereRealloc(pTerm->pWC->pWInfo,
pLevel->u.in.aInLoop,
sizeof(pLevel->u.in.aInLoop[0])*pLevel->u.in.nIn);
pIn = pLevel->u.in.aInLoop;
if( pIn ){
int iMap = 0; /* Index in aiMap[] */
pIn += i;
| | | 160911 160912 160913 160914 160915 160916 160917 160918 160919 160920 160921 160922 160923 160924 160925 |
sqlite3WhereRealloc(pTerm->pWC->pWInfo,
pLevel->u.in.aInLoop,
sizeof(pLevel->u.in.aInLoop[0])*pLevel->u.in.nIn);
pIn = pLevel->u.in.aInLoop;
if( pIn ){
int iMap = 0; /* Index in aiMap[] */
pIn += i;
for(i=iEq; i<pLoop->nLTerm; i++){
if( pLoop->aLTerm[i]->pExpr==pX ){
int iOut = iTarget + i - iEq;
if( eType==IN_INDEX_ROWID ){
pIn->addrInTop = sqlite3VdbeAddOp2(v, OP_Rowid, iTab, iOut);
}else{
int iCol = aiMap ? aiMap[iMap++] : 0;
pIn->addrInTop = sqlite3VdbeAddOp3(v,OP_Column,iTab, iCol, iOut);
|
| ︙ | ︙ | |||
160998 160999 161000 161001 161002 161003 161004 161005 161006 161007 161008 161009 161010 161011 161012 |
static SQLITE_NOINLINE void filterPullDown(
Parse *pParse, /* Parsing context */
WhereInfo *pWInfo, /* Complete information about the WHERE clause */
int iLevel, /* Which level of pWInfo->a[] should be coded */
int addrNxt, /* Jump here to bypass inner loops */
Bitmask notReady /* Loops that are not ready */
){
while( ++iLevel < pWInfo->nLevel ){
WhereLevel *pLevel = &pWInfo->a[iLevel];
WhereLoop *pLoop = pLevel->pWLoop;
if( pLevel->regFilter==0 ) continue;
if( pLevel->pWLoop->nSkip ) continue;
/* ,--- Because sqlite3ConstructBloomFilter() has will not have set
** vvvvv--' pLevel->regFilter if this were true. */
if( NEVER(pLoop->prereq & notReady) ) continue;
| > | | 161562 161563 161564 161565 161566 161567 161568 161569 161570 161571 161572 161573 161574 161575 161576 161577 161578 161579 161580 161581 161582 161583 161584 161585 |
static SQLITE_NOINLINE void filterPullDown(
Parse *pParse, /* Parsing context */
WhereInfo *pWInfo, /* Complete information about the WHERE clause */
int iLevel, /* Which level of pWInfo->a[] should be coded */
int addrNxt, /* Jump here to bypass inner loops */
Bitmask notReady /* Loops that are not ready */
){
int saved_addrBrk;
while( ++iLevel < pWInfo->nLevel ){
WhereLevel *pLevel = &pWInfo->a[iLevel];
WhereLoop *pLoop = pLevel->pWLoop;
if( pLevel->regFilter==0 ) continue;
if( pLevel->pWLoop->nSkip ) continue;
/* ,--- Because sqlite3ConstructBloomFilter() has will not have set
** vvvvv--' pLevel->regFilter if this were true. */
if( NEVER(pLoop->prereq & notReady) ) continue;
saved_addrBrk = pLevel->addrBrk;
pLevel->addrBrk = addrNxt;
if( pLoop->wsFlags & WHERE_IPK ){
WhereTerm *pTerm = pLoop->aLTerm[0];
int regRowid;
assert( pTerm!=0 );
assert( pTerm->pExpr!=0 );
testcase( pTerm->wtFlags & TERM_VIRTUAL );
|
| ︙ | ︙ | |||
161036 161037 161038 161039 161040 161041 161042 |
codeApplyAffinity(pParse, r1, nEq, zStartAff);
sqlite3DbFree(pParse->db, zStartAff);
sqlite3VdbeAddOp4Int(pParse->pVdbe, OP_Filter, pLevel->regFilter,
addrNxt, r1, nEq);
VdbeCoverage(pParse->pVdbe);
}
pLevel->regFilter = 0;
| | | 161601 161602 161603 161604 161605 161606 161607 161608 161609 161610 161611 161612 161613 161614 161615 |
codeApplyAffinity(pParse, r1, nEq, zStartAff);
sqlite3DbFree(pParse->db, zStartAff);
sqlite3VdbeAddOp4Int(pParse->pVdbe, OP_Filter, pLevel->regFilter,
addrNxt, r1, nEq);
VdbeCoverage(pParse->pVdbe);
}
pLevel->regFilter = 0;
pLevel->addrBrk = saved_addrBrk;
}
}
/*
** Loop pLoop is a WHERE_INDEXED level that uses at least one IN(...)
** operator. Return true if level pLoop is guaranteed to visit only one
** row for each key generated for the index.
|
| ︙ | ︙ | |||
161083 161084 161085 161086 161087 161088 161089 | int bRev; /* True if we need to scan in reverse order */ WhereLoop *pLoop; /* The WhereLoop object being coded */ WhereClause *pWC; /* Decomposition of the entire WHERE clause */ WhereTerm *pTerm; /* A WHERE clause term */ sqlite3 *db; /* Database connection */ SrcItem *pTabItem; /* FROM clause term being coded */ int addrBrk; /* Jump here to break out of the loop */ | < | 161648 161649 161650 161651 161652 161653 161654 161655 161656 161657 161658 161659 161660 161661 | int bRev; /* True if we need to scan in reverse order */ WhereLoop *pLoop; /* The WhereLoop object being coded */ WhereClause *pWC; /* Decomposition of the entire WHERE clause */ WhereTerm *pTerm; /* A WHERE clause term */ sqlite3 *db; /* Database connection */ SrcItem *pTabItem; /* FROM clause term being coded */ int addrBrk; /* Jump here to break out of the loop */ int addrCont; /* Jump here to continue with next cycle */ int iRowidReg = 0; /* Rowid is stored in this register, if not zero */ int iReleaseReg = 0; /* Temp register to free before returning */ Index *pIdx = 0; /* Index used by loop (if any) */ int iLoop; /* Iteration of constraint generator loop */ pWC = &pWInfo->sWC; |
| ︙ | ︙ | |||
161127 161128 161129 161130 161131 161132 161133 | ** loop. ** ** When there is an IN operator, we also have a "addrNxt" label that ** means to continue with the next IN value combination. When ** there are no IN operators in the constraints, the "addrNxt" label ** is the same as "addrBrk". */ | | < < < < < < < < | 161691 161692 161693 161694 161695 161696 161697 161698 161699 161700 161701 161702 161703 161704 161705 161706 161707 161708 161709 161710 161711 161712 161713 161714 161715 161716 161717 161718 161719 161720 |
** loop.
**
** When there is an IN operator, we also have a "addrNxt" label that
** means to continue with the next IN value combination. When
** there are no IN operators in the constraints, the "addrNxt" label
** is the same as "addrBrk".
*/
addrBrk = pLevel->addrNxt = pLevel->addrBrk;
addrCont = pLevel->addrCont = sqlite3VdbeMakeLabel(pParse);
/* If this is the right table of a LEFT OUTER JOIN, allocate and
** initialize a memory cell that records if this table matches any
** row of the left table of the join.
*/
assert( (pWInfo->wctrlFlags & (WHERE_OR_SUBCLAUSE|WHERE_RIGHT_JOIN))
|| pLevel->iFrom>0 || (pTabItem[0].fg.jointype & JT_LEFT)==0
);
if( pLevel->iFrom>0 && (pTabItem[0].fg.jointype & JT_LEFT)!=0 ){
pLevel->iLeftJoin = ++pParse->nMem;
sqlite3VdbeAddOp2(v, OP_Integer, 0, pLevel->iLeftJoin);
VdbeComment((v, "init LEFT JOIN match flag"));
}
/* Special case of a FROM clause subquery implemented as a co-routine */
if( pTabItem->fg.viaCoroutine ){
int regYield;
Subquery *pSubq;
assert( pTabItem->fg.isSubquery && pTabItem->u4.pSubq!=0 );
pSubq = pTabItem->u4.pSubq;
regYield = pSubq->regReturn;
|
| ︙ | ︙ | |||
161389 161390 161391 161392 161393 161394 161395 |
VdbeComment((v, "pk"));
VdbeCoverageIf(v, pX->op==TK_GT);
VdbeCoverageIf(v, pX->op==TK_LE);
VdbeCoverageIf(v, pX->op==TK_LT);
VdbeCoverageIf(v, pX->op==TK_GE);
sqlite3ReleaseTempReg(pParse, rTemp);
}else{
| | | 161945 161946 161947 161948 161949 161950 161951 161952 161953 161954 161955 161956 161957 161958 161959 |
VdbeComment((v, "pk"));
VdbeCoverageIf(v, pX->op==TK_GT);
VdbeCoverageIf(v, pX->op==TK_LE);
VdbeCoverageIf(v, pX->op==TK_LT);
VdbeCoverageIf(v, pX->op==TK_GE);
sqlite3ReleaseTempReg(pParse, rTemp);
}else{
sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iCur, pLevel->addrHalt);
VdbeCoverageIf(v, bRev==0);
VdbeCoverageIf(v, bRev!=0);
}
if( pEnd ){
Expr *pX;
pX = pEnd->pExpr;
assert( pX!=0 );
|
| ︙ | ︙ | |||
161429 161430 161431 161432 161433 161434 161435 |
VdbeCoverageIf(v, testOp==OP_Le);
VdbeCoverageIf(v, testOp==OP_Lt);
VdbeCoverageIf(v, testOp==OP_Ge);
VdbeCoverageIf(v, testOp==OP_Gt);
sqlite3VdbeChangeP5(v, SQLITE_AFF_NUMERIC | SQLITE_JUMPIFNULL);
}
}else if( pLoop->wsFlags & WHERE_INDEXED ){
| | | | | | | | | | | | | | | | | | | | | | | | | | 161985 161986 161987 161988 161989 161990 161991 161992 161993 161994 161995 161996 161997 161998 161999 162000 162001 162002 162003 162004 162005 162006 162007 162008 162009 162010 162011 162012 162013 162014 162015 162016 162017 162018 162019 162020 162021 162022 162023 162024 162025 162026 162027 162028 |
VdbeCoverageIf(v, testOp==OP_Le);
VdbeCoverageIf(v, testOp==OP_Lt);
VdbeCoverageIf(v, testOp==OP_Ge);
VdbeCoverageIf(v, testOp==OP_Gt);
sqlite3VdbeChangeP5(v, SQLITE_AFF_NUMERIC | SQLITE_JUMPIFNULL);
}
}else if( pLoop->wsFlags & WHERE_INDEXED ){
/* Case 4: Search using an index.
**
** The WHERE clause may contain zero or more equality
** terms ("==" or "IN" or "IS" operators) that refer to the N
** left-most columns of the index. It may also contain
** inequality constraints (>, <, >= or <=) on the indexed
** column that immediately follows the N equalities. Only
** the right-most column can be an inequality - the rest must
** use the "==", "IN", or "IS" operators. For example, if the
** index is on (x,y,z), then the following clauses are all
** optimized:
**
** x=5
** x=5 AND y=10
** x=5 AND y<10
** x=5 AND y>5 AND y<10
** x=5 AND y=5 AND z<=10
**
** The z<10 term of the following cannot be used, only
** the x=5 term:
**
** x=5 AND z<10
**
** N may be zero if there are inequality constraints.
** If there are no inequality constraints, then N is at
** least one.
**
** This case is also used when there are no WHERE clause
** constraints but an index is selected anyway, in order
** to force the output order to conform to an ORDER BY.
*/
static const u8 aStartOp[] = {
0,
0,
OP_Rewind, /* 2: (!start_constraints && startEq && !bRev) */
OP_Last, /* 3: (!start_constraints && startEq && bRev) */
OP_SeekGT, /* 4: (start_constraints && !startEq && !bRev) */
|
| ︙ | ︙ | |||
161799 161800 161801 161802 161803 161804 161805 |
sqlite3VdbeAddOp4Int(v, OP_NotFound, iCur, addrCont,
iRowidReg, pPk->nKeyCol); VdbeCoverage(v);
}
if( pLevel->iLeftJoin==0 ){
/* If a partial index is driving the loop, try to eliminate WHERE clause
** terms from the query that must be true due to the WHERE clause of
| | > | | | | 162355 162356 162357 162358 162359 162360 162361 162362 162363 162364 162365 162366 162367 162368 162369 162370 162371 162372 162373 162374 162375 |
sqlite3VdbeAddOp4Int(v, OP_NotFound, iCur, addrCont,
iRowidReg, pPk->nKeyCol); VdbeCoverage(v);
}
if( pLevel->iLeftJoin==0 ){
/* If a partial index is driving the loop, try to eliminate WHERE clause
** terms from the query that must be true due to the WHERE clause of
** the partial index. This optimization does not work on an outer join,
** as shown by:
**
** 2019-11-02 ticket 623eff57e76d45f6 (LEFT JOIN)
** 2025-05-29 forum post 7dee41d32506c4ae (RIGHT JOIN)
*/
if( pIdx->pPartIdxWhere && pLevel->pRJ==0 ){
whereApplyPartialIndexConstraints(pIdx->pPartIdxWhere, iCur, pWC);
}
}else{
testcase( pIdx->pPartIdxWhere );
/* The following assert() is not a requirement, merely an observation:
** The OR-optimization doesn't work for the right hand table of
** a LEFT JOIN: */
|
| ︙ | ︙ | |||
162183 162184 162185 162186 162187 162188 162189 |
/* Tables marked isRecursive have only a single row that is stored in
** a pseudo-cursor. No need to Rewind or Next such cursors. */
pLevel->op = OP_Noop;
}else{
codeCursorHint(pTabItem, pWInfo, pLevel, 0);
pLevel->op = aStep[bRev];
pLevel->p1 = iCur;
| | | 162740 162741 162742 162743 162744 162745 162746 162747 162748 162749 162750 162751 162752 162753 162754 |
/* Tables marked isRecursive have only a single row that is stored in
** a pseudo-cursor. No need to Rewind or Next such cursors. */
pLevel->op = OP_Noop;
}else{
codeCursorHint(pTabItem, pWInfo, pLevel, 0);
pLevel->op = aStep[bRev];
pLevel->p1 = iCur;
pLevel->p2 = 1 + sqlite3VdbeAddOp2(v, aStart[bRev],iCur,pLevel->addrHalt);
VdbeCoverageIf(v, bRev==0);
VdbeCoverageIf(v, bRev!=0);
pLevel->p5 = SQLITE_STMTSTATUS_FULLSCAN_STEP;
}
}
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
|
| ︙ | ︙ | |||
163477 163478 163479 163480 163481 163482 163483 | /* ** We already know that pExpr is a binary operator where both operands are ** column references. This routine checks to see if pExpr is an equivalence ** relation: ** 1. The SQLITE_Transitive optimization must be enabled ** 2. Must be either an == or an IS operator ** 3. Not originating in the ON clause of an OUTER JOIN | > | | | | | | | > > > > > > > | | | > > > > | 164034 164035 164036 164037 164038 164039 164040 164041 164042 164043 164044 164045 164046 164047 164048 164049 164050 164051 164052 164053 164054 164055 164056 164057 164058 164059 164060 164061 164062 164063 164064 164065 164066 164067 164068 164069 164070 164071 164072 164073 164074 164075 164076 164077 164078 164079 164080 164081 164082 164083 |
/*
** We already know that pExpr is a binary operator where both operands are
** column references. This routine checks to see if pExpr is an equivalence
** relation:
** 1. The SQLITE_Transitive optimization must be enabled
** 2. Must be either an == or an IS operator
** 3. Not originating in the ON clause of an OUTER JOIN
** 4. The operator is not IS or else the query does not contain RIGHT JOIN
** 5. The affinities of A and B must be compatible
** 6a. Both operands use the same collating sequence OR
** 6b. The overall collating sequence is BINARY
** If this routine returns TRUE, that means that the RHS can be substituted
** for the LHS anyplace else in the WHERE clause where the LHS column occurs.
** This is an optimization. No harm comes from returning 0. But if 1 is
** returned when it should not be, then incorrect answers might result.
*/
static int termIsEquivalence(Parse *pParse, Expr *pExpr, SrcList *pSrc){
char aff1, aff2;
CollSeq *pColl;
if( !OptimizationEnabled(pParse->db, SQLITE_Transitive) ) return 0; /* (1) */
if( pExpr->op!=TK_EQ && pExpr->op!=TK_IS ) return 0; /* (2) */
if( ExprHasProperty(pExpr, EP_OuterON) ) return 0; /* (3) */
assert( pSrc!=0 );
if( pExpr->op==TK_IS
&& pSrc->nSrc>=2
&& (pSrc->a[0].fg.jointype & JT_LTORJ)!=0
){
return 0; /* (4) */
}
aff1 = sqlite3ExprAffinity(pExpr->pLeft);
aff2 = sqlite3ExprAffinity(pExpr->pRight);
if( aff1!=aff2
&& (!sqlite3IsNumericAffinity(aff1) || !sqlite3IsNumericAffinity(aff2))
){
return 0; /* (5) */
}
pColl = sqlite3ExprCompareCollSeq(pParse, pExpr);
if( !sqlite3IsBinary(pColl)
&& !sqlite3ExprCollSeqMatch(pParse, pExpr->pLeft, pExpr->pRight)
){
return 0; /* (6) */
}
return 1;
}
/*
** Recursively walk the expressions of a SELECT statement and generate
** a bitmask indicating which tables are used in that expression
** tree.
*/
|
| ︙ | ︙ | |||
163658 163659 163660 163661 163662 163663 163664 163665 163666 163667 163668 163669 163670 163671 |
int nLeft; /* Number of elements on left side vector */
if( db->mallocFailed ){
return;
}
assert( pWC->nTerm > idxTerm );
pTerm = &pWC->a[idxTerm];
pMaskSet = &pWInfo->sMaskSet;
pExpr = pTerm->pExpr;
assert( pExpr!=0 ); /* Because malloc() has not failed */
assert( pExpr->op!=TK_AS && pExpr->op!=TK_COLLATE );
pMaskSet->bVarSelect = 0;
prereqLeft = sqlite3WhereExprUsage(pMaskSet, pExpr->pLeft);
op = pExpr->op;
| > > > | 164227 164228 164229 164230 164231 164232 164233 164234 164235 164236 164237 164238 164239 164240 164241 164242 164243 |
int nLeft; /* Number of elements on left side vector */
if( db->mallocFailed ){
return;
}
assert( pWC->nTerm > idxTerm );
pTerm = &pWC->a[idxTerm];
#ifdef SQLITE_DEBUG
pTerm->iTerm = idxTerm;
#endif
pMaskSet = &pWInfo->sMaskSet;
pExpr = pTerm->pExpr;
assert( pExpr!=0 ); /* Because malloc() has not failed */
assert( pExpr->op!=TK_AS && pExpr->op!=TK_COLLATE );
pMaskSet->bVarSelect = 0;
prereqLeft = sqlite3WhereExprUsage(pMaskSet, pExpr->pLeft);
op = pExpr->op;
|
| ︙ | ︙ | |||
163765 163766 163767 163768 163769 163770 163771 |
idxNew = whereClauseInsert(pWC, pDup, TERM_VIRTUAL|TERM_DYNAMIC);
if( idxNew==0 ) return;
pNew = &pWC->a[idxNew];
markTermAsChild(pWC, idxNew, idxTerm);
if( op==TK_IS ) pNew->wtFlags |= TERM_IS;
pTerm = &pWC->a[idxTerm];
pTerm->wtFlags |= TERM_COPIED;
| | | | 164337 164338 164339 164340 164341 164342 164343 164344 164345 164346 164347 164348 164349 164350 164351 164352 |
idxNew = whereClauseInsert(pWC, pDup, TERM_VIRTUAL|TERM_DYNAMIC);
if( idxNew==0 ) return;
pNew = &pWC->a[idxNew];
markTermAsChild(pWC, idxNew, idxTerm);
if( op==TK_IS ) pNew->wtFlags |= TERM_IS;
pTerm = &pWC->a[idxTerm];
pTerm->wtFlags |= TERM_COPIED;
assert( pWInfo->pTabList!=0 );
if( termIsEquivalence(pParse, pDup, pWInfo->pTabList) ){
pTerm->eOperator |= WO_EQUIV;
eExtraOp = WO_EQUIV;
}
}else{
pDup = pExpr;
pNew = pTerm;
}
|
| ︙ | ︙ | |||
164072 164073 164074 164075 164076 164077 164078 |
if( ExprHasProperty(pExpr, EP_OuterON) && pNewExpr ){
ExprSetProperty(pNewExpr, EP_OuterON);
pNewExpr->w.iJoin = pExpr->w.iJoin;
}
idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC);
testcase( idxNew==0 );
pNewTerm = &pWC->a[idxNew];
| | | 164644 164645 164646 164647 164648 164649 164650 164651 164652 164653 164654 164655 164656 164657 164658 |
if( ExprHasProperty(pExpr, EP_OuterON) && pNewExpr ){
ExprSetProperty(pNewExpr, EP_OuterON);
pNewExpr->w.iJoin = pExpr->w.iJoin;
}
idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC);
testcase( idxNew==0 );
pNewTerm = &pWC->a[idxNew];
pNewTerm->prereqRight = prereqExpr | extraRight;
pNewTerm->leftCursor = pLeft->iTable;
pNewTerm->u.x.leftColumn = pLeft->iColumn;
pNewTerm->eOperator = WO_AUX;
pNewTerm->eMatchOp = eOp2;
markTermAsChild(pWC, idxNew, idxTerm);
pTerm = &pWC->a[idxTerm];
pTerm->wtFlags |= TERM_COPIED;
|
| ︙ | ︙ | |||
164183 164184 164185 164186 164187 164188 164189 | /* ** Possibly add terms corresponding to the LIMIT and OFFSET clauses of the ** SELECT statement passed as the second argument. These terms are only ** added if: ** ** 1. The SELECT statement has a LIMIT clause, and ** 2. The SELECT statement is not an aggregate or DISTINCT query, and | | | 164755 164756 164757 164758 164759 164760 164761 164762 164763 164764 164765 164766 164767 164768 164769 | /* ** Possibly add terms corresponding to the LIMIT and OFFSET clauses of the ** SELECT statement passed as the second argument. These terms are only ** added if: ** ** 1. The SELECT statement has a LIMIT clause, and ** 2. The SELECT statement is not an aggregate or DISTINCT query, and ** 3. The SELECT statement has exactly one object in its FROM clause, and ** that object is a virtual table, and ** 4. There are no terms in the WHERE clause that will not be passed ** to the virtual table xBestIndex method. ** 5. The ORDER BY clause, if any, will be made available to the xBestIndex ** method. ** ** LIMIT and OFFSET terms are ignored by most of the planner code. They |
| ︙ | ︙ | |||
164220 164221 164222 164223 164224 164225 164226 |
if( pWC->a[ii].nChild ){
/* If this term has child terms, then they are also part of the
** pWC->a[] array. So this term can be ignored, as a LIMIT clause
** will only be added if each of the child terms passes the
** (leftCursor==iCsr) test below. */
continue;
}
| | > > > | > > > > > > > > > > > | 164792 164793 164794 164795 164796 164797 164798 164799 164800 164801 164802 164803 164804 164805 164806 164807 164808 164809 164810 164811 164812 164813 164814 164815 164816 164817 164818 164819 164820 164821 |
if( pWC->a[ii].nChild ){
/* If this term has child terms, then they are also part of the
** pWC->a[] array. So this term can be ignored, as a LIMIT clause
** will only be added if each of the child terms passes the
** (leftCursor==iCsr) test below. */
continue;
}
if( pWC->a[ii].leftCursor==iCsr && pWC->a[ii].prereqRight==0 ) continue;
/* If this term has a parent with exactly one child, and the parent will
** be passed through to xBestIndex, then this term can be ignored. */
if( pWC->a[ii].iParent>=0 ){
WhereTerm *pParent = &pWC->a[ pWC->a[ii].iParent ];
if( pParent->leftCursor==iCsr
&& pParent->prereqRight==0
&& pParent->nChild==1
){
continue;
}
}
/* This term will not be passed through. Do not add a LIMIT clause. */
return;
}
/* Check condition (5). Return early if it is not met. */
if( pOrderBy ){
for(ii=0; ii<pOrderBy->nExpr; ii++){
Expr *pExpr = pOrderBy->a[ii].pExpr;
if( pExpr->op!=TK_COLUMN ) return;
|
| ︙ | ︙ | |||
164885 164886 164887 164888 164889 164890 164891 |
){
testcase( pTerm->eOperator & WO_IS );
continue;
}
pScan->pWC = pWC;
pScan->k = k+1;
#ifdef WHERETRACE_ENABLED
| | | | | | 165471 165472 165473 165474 165475 165476 165477 165478 165479 165480 165481 165482 165483 165484 165485 165486 165487 165488 165489 |
){
testcase( pTerm->eOperator & WO_IS );
continue;
}
pScan->pWC = pWC;
pScan->k = k+1;
#ifdef WHERETRACE_ENABLED
if( (sqlite3WhereTrace & 0x20000)!=0 && pScan->nEquiv>1 ){
int ii;
sqlite3DebugPrintf("EQUIVALENT TO {%d:%d} (due to TERM-%d):",
pScan->aiCur[0], pScan->aiColumn[0], pTerm->iTerm);
for(ii=1; ii<pScan->nEquiv; ii++){
sqlite3DebugPrintf(" {%d:%d}",
pScan->aiCur[ii], pScan->aiColumn[ii]);
}
sqlite3DebugPrintf("\n");
}
#endif
return pTerm;
|
| ︙ | ︙ | |||
165660 165661 165662 165663 165664 165665 165666 |
regYield = pSubq->regReturn;
addrCounter = sqlite3VdbeAddOp2(v, OP_Integer, 0, 0);
sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, pSubq->addrFillSub);
addrTop = sqlite3VdbeAddOp1(v, OP_Yield, regYield);
VdbeCoverage(v);
VdbeComment((v, "next row of %s", pSrc->pSTab->zName));
}else{
| > > | | 166246 166247 166248 166249 166250 166251 166252 166253 166254 166255 166256 166257 166258 166259 166260 166261 166262 |
regYield = pSubq->regReturn;
addrCounter = sqlite3VdbeAddOp2(v, OP_Integer, 0, 0);
sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, pSubq->addrFillSub);
addrTop = sqlite3VdbeAddOp1(v, OP_Yield, regYield);
VdbeCoverage(v);
VdbeComment((v, "next row of %s", pSrc->pSTab->zName));
}else{
assert( pLevel->addrHalt );
addrTop = sqlite3VdbeAddOp2(v, OP_Rewind,pLevel->iTabCur,pLevel->addrHalt);
VdbeCoverage(v);
}
if( pPartial ){
iContinue = sqlite3VdbeMakeLabel(pParse);
sqlite3ExprIfFalse(pParse, pPartial, iContinue, SQLITE_JUMPIFNULL);
pLoop->wsFlags |= WHERE_PARTIALIDX;
}
regRecord = sqlite3GetTempReg(pParse);
|
| ︙ | ︙ | |||
165688 165689 165690 165691 165692 165693 165694 165695 165696 165697 |
sqlite3VdbeChangeP2(v, addrCounter, regBase+n);
testcase( pParse->db->mallocFailed );
assert( pLevel->iIdxCur>0 );
translateColumnToCopy(pParse, addrTop, pLevel->iTabCur,
pSrc->u4.pSubq->regResult, pLevel->iIdxCur);
sqlite3VdbeGoto(v, addrTop);
pSrc->fg.viaCoroutine = 0;
}else{
sqlite3VdbeAddOp2(v, OP_Next, pLevel->iTabCur, addrTop+1); VdbeCoverage(v);
sqlite3VdbeChangeP5(v, SQLITE_STMTSTATUS_AUTOINDEX);
| > < > | > > | 166276 166277 166278 166279 166280 166281 166282 166283 166284 166285 166286 166287 166288 166289 166290 166291 166292 166293 166294 166295 166296 166297 |
sqlite3VdbeChangeP2(v, addrCounter, regBase+n);
testcase( pParse->db->mallocFailed );
assert( pLevel->iIdxCur>0 );
translateColumnToCopy(pParse, addrTop, pLevel->iTabCur,
pSrc->u4.pSubq->regResult, pLevel->iIdxCur);
sqlite3VdbeGoto(v, addrTop);
pSrc->fg.viaCoroutine = 0;
sqlite3VdbeJumpHere(v, addrTop);
}else{
sqlite3VdbeAddOp2(v, OP_Next, pLevel->iTabCur, addrTop+1); VdbeCoverage(v);
sqlite3VdbeChangeP5(v, SQLITE_STMTSTATUS_AUTOINDEX);
if( (pSrc->fg.jointype & JT_LEFT)!=0 ){
sqlite3VdbeJumpHere(v, addrTop);
}
}
sqlite3ReleaseTempReg(pParse, regRecord);
/* Jump here when skipping the initialization */
sqlite3VdbeJumpHere(v, addrInit);
sqlite3VdbeScanStatusRange(v, addrExp, addrExp, -1);
end_auto_index_create:
|
| ︙ | ︙ | |||
166844 166845 166846 166847 166848 166849 166850 166851 166852 166853 166854 166855 166856 166857 |
pTerm->leftCursor, pTerm->u.x.leftColumn);
}else if( (pTerm->eOperator & WO_OR)!=0 && pTerm->u.pOrInfo!=0 ){
sqlite3_snprintf(sizeof(zLeft),zLeft,"indexable=0x%llx",
pTerm->u.pOrInfo->indexable);
}else{
sqlite3_snprintf(sizeof(zLeft),zLeft,"left=%d", pTerm->leftCursor);
}
sqlite3DebugPrintf(
"TERM-%-3d %p %s %-12s op=%03x wtFlags=%04x",
iTerm, pTerm, zType, zLeft, pTerm->eOperator, pTerm->wtFlags);
/* The 0x10000 .wheretrace flag causes extra information to be
** shown about each Term */
if( sqlite3WhereTrace & 0x10000 ){
sqlite3DebugPrintf(" prob=%-3d prereq=%llx,%llx",
| > | 167435 167436 167437 167438 167439 167440 167441 167442 167443 167444 167445 167446 167447 167448 167449 |
pTerm->leftCursor, pTerm->u.x.leftColumn);
}else if( (pTerm->eOperator & WO_OR)!=0 && pTerm->u.pOrInfo!=0 ){
sqlite3_snprintf(sizeof(zLeft),zLeft,"indexable=0x%llx",
pTerm->u.pOrInfo->indexable);
}else{
sqlite3_snprintf(sizeof(zLeft),zLeft,"left=%d", pTerm->leftCursor);
}
iTerm = pTerm->iTerm = MAX(iTerm,pTerm->iTerm);
sqlite3DebugPrintf(
"TERM-%-3d %p %s %-12s op=%03x wtFlags=%04x",
iTerm, pTerm, zType, zLeft, pTerm->eOperator, pTerm->wtFlags);
/* The 0x10000 .wheretrace flag causes extra information to be
** shown about each Term */
if( sqlite3WhereTrace & 0x10000 ){
sqlite3DebugPrintf(" prob=%-3d prereq=%llx,%llx",
|
| ︙ | ︙ | |||
167618 167619 167620 167621 167622 167623 167624 |
assert( (pNew->wsFlags & WHERE_TOP_LIMIT)==0 );
if( pNew->wsFlags & WHERE_BTM_LIMIT ){
opMask = WO_LT|WO_LE;
}else{
assert( pNew->u.btree.nBtm==0 );
opMask = WO_EQ|WO_IN|WO_GT|WO_GE|WO_LT|WO_LE|WO_ISNULL|WO_IS;
}
| | | < < < | 168210 168211 168212 168213 168214 168215 168216 168217 168218 168219 168220 168221 168222 168223 168224 168225 |
assert( (pNew->wsFlags & WHERE_TOP_LIMIT)==0 );
if( pNew->wsFlags & WHERE_BTM_LIMIT ){
opMask = WO_LT|WO_LE;
}else{
assert( pNew->u.btree.nBtm==0 );
opMask = WO_EQ|WO_IN|WO_GT|WO_GE|WO_LT|WO_LE|WO_ISNULL|WO_IS;
}
if( pProbe->bUnordered ){
opMask &= ~(WO_GT|WO_GE|WO_LT|WO_LE);
}
assert( pNew->u.btree.nEq<pProbe->nColumn );
assert( pNew->u.btree.nEq<pProbe->nKeyCol
|| pProbe->idxType!=SQLITE_IDXTYPE_PRIMARYKEY );
saved_nEq = pNew->u.btree.nEq;
|
| ︙ | ︙ | |||
167695 167696 167697 167698 167699 167700 167701 167702 167703 167704 167705 167706 167707 167708 167709 |
);
if( eOp & WO_IN ){
Expr *pExpr = pTerm->pExpr;
if( ExprUseXSelect(pExpr) ){
/* "x IN (SELECT ...)": TUNING: the SELECT returns 25 rows */
int i;
nIn = 46; assert( 46==sqlite3LogEst(25) );
/* The expression may actually be of the form (x, y) IN (SELECT...).
** In this case there is a separate term for each of (x) and (y).
** However, the nIn multiplier should only be applied once, not once
** for each such term. The following loop checks that pTerm is the
** first such term in use, and sets nIn back to 0 if it is not. */
for(i=0; i<pNew->nLTerm-1; i++){
| > | > > > > > > > > > > > > > | 168284 168285 168286 168287 168288 168289 168290 168291 168292 168293 168294 168295 168296 168297 168298 168299 168300 168301 168302 168303 168304 168305 168306 168307 168308 168309 168310 168311 168312 168313 168314 168315 168316 168317 168318 168319 168320 |
);
if( eOp & WO_IN ){
Expr *pExpr = pTerm->pExpr;
if( ExprUseXSelect(pExpr) ){
/* "x IN (SELECT ...)": TUNING: the SELECT returns 25 rows */
int i;
int bRedundant = 0;
nIn = 46; assert( 46==sqlite3LogEst(25) );
/* The expression may actually be of the form (x, y) IN (SELECT...).
** In this case there is a separate term for each of (x) and (y).
** However, the nIn multiplier should only be applied once, not once
** for each such term. The following loop checks that pTerm is the
** first such term in use, and sets nIn back to 0 if it is not. */
for(i=0; i<pNew->nLTerm-1; i++){
if( pNew->aLTerm[i] && pNew->aLTerm[i]->pExpr==pExpr ){
nIn = 0;
if( pNew->aLTerm[i]->u.x.iField == pTerm->u.x.iField ){
/* Detect when two or more columns of an index match the same
** column of a vector IN operater, and avoid adding the column
** to the WhereLoop more than once. See tag-20250707-01
** in test/rowvalue.test */
bRedundant = 1;
}
}
}
if( bRedundant ){
pNew->nLTerm--;
continue;
}
}else if( ALWAYS(pExpr->x.pList && pExpr->x.pList->nExpr) ){
/* "x IN (value, value, ...)" */
nIn = sqlite3LogEst(pExpr->x.pList->nExpr);
}
if( pProbe->hasStat1 && rLogSize>=10 ){
LogEst M, logK, x;
|
| ︙ | ︙ | |||
167935 167936 167937 167938 167939 167940 167941 |
}else{
pNew->nOut = nOutUnadjusted;
}
if( (pNew->wsFlags & WHERE_TOP_LIMIT)==0
&& pNew->u.btree.nEq<pProbe->nColumn
&& (pNew->u.btree.nEq<pProbe->nKeyCol ||
| | | 168538 168539 168540 168541 168542 168543 168544 168545 168546 168547 168548 168549 168550 168551 168552 |
}else{
pNew->nOut = nOutUnadjusted;
}
if( (pNew->wsFlags & WHERE_TOP_LIMIT)==0
&& pNew->u.btree.nEq<pProbe->nColumn
&& (pNew->u.btree.nEq<pProbe->nKeyCol ||
pProbe->idxType!=SQLITE_IDXTYPE_PRIMARYKEY)
){
if( pNew->u.btree.nEq>3 ){
sqlite3ProgressCheck(pParse);
}
whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, nInMul+nIn);
}
pNew->nOut = saved_nOut;
|
| ︙ | ︙ | |||
167974 167975 167976 167977 167978 167979 167980 167981 167982 167983 167984 167985 167986 167987 |
if( saved_nEq==saved_nSkip
&& saved_nEq+1<pProbe->nKeyCol
&& saved_nEq==pNew->nLTerm
&& pProbe->noSkipScan==0
&& pProbe->hasStat1!=0
&& OptimizationEnabled(db, SQLITE_SkipScan)
&& pProbe->aiRowLogEst[saved_nEq+1]>=42 /* TUNING: Minimum for skip-scan */
&& (rc = whereLoopResize(db, pNew, pNew->nLTerm+1))==SQLITE_OK
){
LogEst nIter;
pNew->u.btree.nEq++;
pNew->nSkip++;
pNew->aLTerm[pNew->nLTerm++] = 0;
pNew->wsFlags |= WHERE_SKIPSCAN;
| > | 168577 168578 168579 168580 168581 168582 168583 168584 168585 168586 168587 168588 168589 168590 168591 |
if( saved_nEq==saved_nSkip
&& saved_nEq+1<pProbe->nKeyCol
&& saved_nEq==pNew->nLTerm
&& pProbe->noSkipScan==0
&& pProbe->hasStat1!=0
&& OptimizationEnabled(db, SQLITE_SkipScan)
&& pProbe->aiRowLogEst[saved_nEq+1]>=42 /* TUNING: Minimum for skip-scan */
&& pSrc->fg.fromExists==0
&& (rc = whereLoopResize(db, pNew, pNew->nLTerm+1))==SQLITE_OK
){
LogEst nIter;
pNew->u.btree.nEq++;
pNew->nSkip++;
pNew->aLTerm[pNew->nLTerm++] = 0;
pNew->wsFlags |= WHERE_SKIPSCAN;
|
| ︙ | ︙ | |||
168064 168065 168066 168067 168068 168069 168070 168071 168072 168073 168074 168075 168076 168077 |
}
for(i=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){
Expr *pExpr;
pExpr = pTerm->pExpr;
if( (!ExprHasProperty(pExpr, EP_OuterON) || pExpr->w.iJoin==iTab)
&& ((jointype & JT_OUTER)==0 || ExprHasProperty(pExpr, EP_OuterON))
&& sqlite3ExprImpliesExpr(pParse, pExpr, pWhere, iTab)
&& (pTerm->wtFlags & TERM_VNULL)==0
){
return 1;
}
}
return 0;
}
| > | 168668 168669 168670 168671 168672 168673 168674 168675 168676 168677 168678 168679 168680 168681 168682 |
}
for(i=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){
Expr *pExpr;
pExpr = pTerm->pExpr;
if( (!ExprHasProperty(pExpr, EP_OuterON) || pExpr->w.iJoin==iTab)
&& ((jointype & JT_OUTER)==0 || ExprHasProperty(pExpr, EP_OuterON))
&& sqlite3ExprImpliesExpr(pParse, pExpr, pWhere, iTab)
&& !sqlite3ExprImpliesExpr(pParse, pExpr, pWhere, -1)
&& (pTerm->wtFlags & TERM_VNULL)==0
){
return 1;
}
}
return 0;
}
|
| ︙ | ︙ | |||
168559 168560 168561 168562 168563 168564 168565 |
" according to whereIsCoveringIndex()\n", pProbe->zName));
}
}
}else if( m==0
&& (HasRowid(pTab) || pWInfo->pSelect!=0 || sqlite3FaultSim(700))
){
WHERETRACE(0x200,
| | | 169164 169165 169166 169167 169168 169169 169170 169171 169172 169173 169174 169175 169176 169177 169178 |
" according to whereIsCoveringIndex()\n", pProbe->zName));
}
}
}else if( m==0
&& (HasRowid(pTab) || pWInfo->pSelect!=0 || sqlite3FaultSim(700))
){
WHERETRACE(0x200,
("-> %s is a covering index according to bitmasks\n",
pProbe->zName, m==0 ? "is" : "is not"));
pNew->wsFlags = WHERE_IDX_ONLY | WHERE_INDEXED;
}
}
/* Full scan via index */
if( b
|
| ︙ | ︙ | |||
171530 171531 171532 171533 171534 171535 171536 171537 171538 171539 171540 171541 171542 171543 |
int iDb; /* Index of database containing table/index */
SrcItem *pTabItem;
pTabItem = &pTabList->a[pLevel->iFrom];
pTab = pTabItem->pSTab;
iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
pLoop = pLevel->pWLoop;
if( (pTab->tabFlags & TF_Ephemeral)!=0 || IsView(pTab) ){
/* Do nothing */
}else
#ifndef SQLITE_OMIT_VIRTUALTABLE
if( (pLoop->wsFlags & WHERE_VIRTUALTABLE)!=0 ){
const char *pVTab = (const char *)sqlite3GetVTable(db, pTab);
int iCur = pTabItem->iCursor;
| > > > > > > > > | 172135 172136 172137 172138 172139 172140 172141 172142 172143 172144 172145 172146 172147 172148 172149 172150 172151 172152 172153 172154 172155 172156 |
int iDb; /* Index of database containing table/index */
SrcItem *pTabItem;
pTabItem = &pTabList->a[pLevel->iFrom];
pTab = pTabItem->pSTab;
iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
pLoop = pLevel->pWLoop;
pLevel->addrBrk = sqlite3VdbeMakeLabel(pParse);
if( ii==0 || (pTabItem[0].fg.jointype & JT_LEFT)!=0 ){
pLevel->addrHalt = pLevel->addrBrk;
}else if( pWInfo->a[ii-1].pRJ ){
pLevel->addrHalt = pWInfo->a[ii-1].addrBrk;
}else{
pLevel->addrHalt = pWInfo->a[ii-1].addrHalt;
}
if( (pTab->tabFlags & TF_Ephemeral)!=0 || IsView(pTab) ){
/* Do nothing */
}else
#ifndef SQLITE_OMIT_VIRTUALTABLE
if( (pLoop->wsFlags & WHERE_VIRTUALTABLE)!=0 ){
const char *pVTab = (const char *)sqlite3GetVTable(db, pTab);
int iCur = pTabItem->iCursor;
|
| ︙ | ︙ | |||
171581 171582 171583 171584 171585 171586 171587 171588 171589 171590 171591 171592 171593 171594 |
{
sqlite3VdbeChangeP5(v, bFordelete);
}
#ifdef SQLITE_ENABLE_COLUMN_USED_MASK
sqlite3VdbeAddOp4Dup8(v, OP_ColumnsUsed, pTabItem->iCursor, 0, 0,
(const u8*)&pTabItem->colUsed, P4_INT64);
#endif
}else{
sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);
}
if( pLoop->wsFlags & WHERE_INDEXED ){
Index *pIx = pLoop->u.btree.pIndex;
int iIndexCur;
int op = OP_OpenRead;
| > > > > > > > | 172194 172195 172196 172197 172198 172199 172200 172201 172202 172203 172204 172205 172206 172207 172208 172209 172210 172211 172212 172213 172214 |
{
sqlite3VdbeChangeP5(v, bFordelete);
}
#ifdef SQLITE_ENABLE_COLUMN_USED_MASK
sqlite3VdbeAddOp4Dup8(v, OP_ColumnsUsed, pTabItem->iCursor, 0, 0,
(const u8*)&pTabItem->colUsed, P4_INT64);
#endif
if( ii>=2
&& (pTabItem[0].fg.jointype & (JT_LTORJ|JT_LEFT))==0
&& pLevel->addrHalt==pWInfo->a[0].addrHalt
){
sqlite3VdbeAddOp2(v, OP_IfEmpty, pTabItem->iCursor, pWInfo->iBreak);
VdbeCoverage(v);
}
}else{
sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);
}
if( pLoop->wsFlags & WHERE_INDEXED ){
Index *pIx = pLoop->u.btree.pIndex;
int iIndexCur;
int op = OP_OpenRead;
|
| ︙ | ︙ | |||
171837 171838 171839 171840 171841 171842 171843 171844 171845 171846 171847 171848 171849 171850 |
op = pLevel->op==OP_Prev ? OP_SeekLT : OP_SeekGT;
addrSeek = sqlite3VdbeAddOp4Int(v, op, pLevel->iIdxCur, 0, r1, n);
VdbeCoverageIf(v, op==OP_SeekLT);
VdbeCoverageIf(v, op==OP_SeekGT);
sqlite3VdbeAddOp2(v, OP_Goto, 1, pLevel->p2);
}
#endif /* SQLITE_DISABLE_SKIPAHEAD_DISTINCT */
/* The common case: Advance to the next row */
if( pLevel->addrCont ) sqlite3VdbeResolveLabel(v, pLevel->addrCont);
sqlite3VdbeAddOp3(v, pLevel->op, pLevel->p1, pLevel->p2, pLevel->p3);
sqlite3VdbeChangeP5(v, pLevel->p5);
VdbeCoverage(v);
VdbeCoverageIf(v, pLevel->op==OP_Next);
VdbeCoverageIf(v, pLevel->op==OP_Prev);
| > > > | 172457 172458 172459 172460 172461 172462 172463 172464 172465 172466 172467 172468 172469 172470 172471 172472 172473 |
op = pLevel->op==OP_Prev ? OP_SeekLT : OP_SeekGT;
addrSeek = sqlite3VdbeAddOp4Int(v, op, pLevel->iIdxCur, 0, r1, n);
VdbeCoverageIf(v, op==OP_SeekLT);
VdbeCoverageIf(v, op==OP_SeekGT);
sqlite3VdbeAddOp2(v, OP_Goto, 1, pLevel->p2);
}
#endif /* SQLITE_DISABLE_SKIPAHEAD_DISTINCT */
if( pTabList->a[pLevel->iFrom].fg.fromExists ){
sqlite3VdbeAddOp2(v, OP_Goto, 0, sqlite3VdbeCurrentAddr(v)+2);
}
/* The common case: Advance to the next row */
if( pLevel->addrCont ) sqlite3VdbeResolveLabel(v, pLevel->addrCont);
sqlite3VdbeAddOp3(v, pLevel->op, pLevel->p1, pLevel->p2, pLevel->p3);
sqlite3VdbeChangeP5(v, pLevel->p5);
VdbeCoverage(v);
VdbeCoverageIf(v, pLevel->op==OP_Next);
VdbeCoverageIf(v, pLevel->op==OP_Prev);
|
| ︙ | ︙ | |||
179909 179910 179911 179912 179913 179914 179915 |
{
if( yymsp[-1].minor.yy402==0 ){
/* Expressions of the form
**
** expr1 IN ()
** expr1 NOT IN ()
**
| | > > > > | > > > | | > | > | 180532 180533 180534 180535 180536 180537 180538 180539 180540 180541 180542 180543 180544 180545 180546 180547 180548 180549 180550 180551 180552 180553 180554 180555 180556 180557 180558 180559 180560 |
{
if( yymsp[-1].minor.yy402==0 ){
/* Expressions of the form
**
** expr1 IN ()
** expr1 NOT IN ()
**
** simplify to constants 0 (false) and 1 (true), respectively.
**
** Except, do not apply this optimization if expr1 contains a function
** because that function might be an aggregate (we don't know yet whether
** it is or not) and if it is an aggregate, that could change the meaning
** of the whole query.
*/
Expr *pB = sqlite3Expr(pParse->db, TK_STRING, yymsp[-3].minor.yy502 ? "true" : "false");
if( pB ) sqlite3ExprIdToTrueFalse(pB);
if( !ExprHasProperty(yymsp[-4].minor.yy590, EP_HasFunc) ){
sqlite3ExprUnmapAndDelete(pParse, yymsp[-4].minor.yy590);
yymsp[-4].minor.yy590 = pB;
}else{
yymsp[-4].minor.yy590 = sqlite3PExpr(pParse, yymsp[-3].minor.yy502 ? TK_OR : TK_AND, pB, yymsp[-4].minor.yy590);
}
}else{
Expr *pRHS = yymsp[-1].minor.yy402->a[0].pExpr;
if( yymsp[-1].minor.yy402->nExpr==1 && sqlite3ExprIsConstant(pParse,pRHS) && yymsp[-4].minor.yy590->op!=TK_VECTOR ){
yymsp[-1].minor.yy402->a[0].pExpr = 0;
sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy402);
pRHS = sqlite3PExpr(pParse, TK_UPLUS, pRHS, 0);
yymsp[-4].minor.yy590 = sqlite3PExpr(pParse, TK_EQ, yymsp[-4].minor.yy590, pRHS);
|
| ︙ | ︙ | |||
181520 181521 181522 181523 181524 181525 181526 |
** (*pz) to point to the byte following the parsed token.
*/
static int getToken(const unsigned char **pz){
const unsigned char *z = *pz;
int t; /* Token type to return */
do {
z += sqlite3GetToken(z, &t);
| | | 182152 182153 182154 182155 182156 182157 182158 182159 182160 182161 182162 182163 182164 182165 182166 |
** (*pz) to point to the byte following the parsed token.
*/
static int getToken(const unsigned char **pz){
const unsigned char *z = *pz;
int t; /* Token type to return */
do {
z += sqlite3GetToken(z, &t);
}while( t==TK_SPACE || t==TK_COMMENT );
if( t==TK_ID
|| t==TK_STRING
|| t==TK_JOIN_KW
|| t==TK_WINDOW
|| t==TK_OVER
|| sqlite3ParserFallback(t)==TK_ID
){
|
| ︙ | ︙ | |||
184470 184471 184472 184473 184474 184475 184476 184477 184478 184479 184480 184481 184482 184483 184484 184485 184486 184487 184488 184489 184490 184491 184492 184493 184494 |
int bBOC = ((flags & SQLITE_SETLK_BLOCK_ON_CONNECT) ? 1 : 0);
#endif
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
#endif
if( ms<-1 ) return SQLITE_RANGE;
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
db->setlkTimeout = ms;
db->setlkFlags = flags;
sqlite3BtreeEnterAll(db);
for(iDb=0; iDb<db->nDb; iDb++){
Btree *pBt = db->aDb[iDb].pBt;
if( pBt ){
sqlite3_file *fd = sqlite3PagerFile(sqlite3BtreePager(pBt));
sqlite3OsFileControlHint(fd, SQLITE_FCNTL_BLOCK_ON_CONNECT, (void*)&bBOC);
}
}
sqlite3BtreeLeaveAll(db);
#endif
#if !defined(SQLITE_ENABLE_API_ARMOR) && !defined(SQLITE_ENABLE_SETLK_TIMEOUT)
UNUSED_PARAMETER(db);
UNUSED_PARAMETER(flags);
#endif
return SQLITE_OK;
}
| > > | 185102 185103 185104 185105 185106 185107 185108 185109 185110 185111 185112 185113 185114 185115 185116 185117 185118 185119 185120 185121 185122 185123 185124 185125 185126 185127 185128 |
int bBOC = ((flags & SQLITE_SETLK_BLOCK_ON_CONNECT) ? 1 : 0);
#endif
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
#endif
if( ms<-1 ) return SQLITE_RANGE;
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
sqlite3_mutex_enter(db->mutex);
db->setlkTimeout = ms;
db->setlkFlags = flags;
sqlite3BtreeEnterAll(db);
for(iDb=0; iDb<db->nDb; iDb++){
Btree *pBt = db->aDb[iDb].pBt;
if( pBt ){
sqlite3_file *fd = sqlite3PagerFile(sqlite3BtreePager(pBt));
sqlite3OsFileControlHint(fd, SQLITE_FCNTL_BLOCK_ON_CONNECT, (void*)&bBOC);
}
}
sqlite3BtreeLeaveAll(db);
sqlite3_mutex_leave(db->mutex);
#endif
#if !defined(SQLITE_ENABLE_API_ARMOR) && !defined(SQLITE_ENABLE_SETLK_TIMEOUT)
UNUSED_PARAMETER(db);
UNUSED_PARAMETER(flags);
#endif
return SQLITE_OK;
}
|
| ︙ | ︙ | |||
188867 188868 188869 188870 188871 188872 188873 | #define deliberate_fall_through /* ** Macros needed to provide flexible arrays in a portable way */ #ifndef offsetof | | | 189501 189502 189503 189504 189505 189506 189507 189508 189509 189510 189511 189512 189513 189514 189515 | #define deliberate_fall_through /* ** Macros needed to provide flexible arrays in a portable way */ #ifndef offsetof # define offsetof(ST,M) ((size_t)((char*)&((ST*)0)->M - (char*)0)) #endif #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) # define FLEXARRAY #else # define FLEXARRAY 1 #endif |
| ︙ | ︙ | |||
207966 207967 207968 207969 207970 207971 207972 |
/*
** Growing our own isspace() routine this way is twice as fast as
** the library isspace() function, resulting in a 7% overall performance
** increase for the text-JSON parser. (Ubuntu14.10 gcc 4.8.4 x64 with -Os).
*/
static const char jsonIsSpace[] = {
| > > | | | | | | | | | | | | | | | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | | | | | | | | | | | | | | | > > > > > > > > > > > > > > > > > > > > > | 208600 208601 208602 208603 208604 208605 208606 208607 208608 208609 208610 208611 208612 208613 208614 208615 208616 208617 208618 208619 208620 208621 208622 208623 208624 208625 208626 208627 208628 208629 208630 208631 208632 208633 208634 208635 208636 208637 208638 208639 208640 208641 208642 208643 208644 208645 208646 208647 208648 208649 208650 208651 208652 208653 208654 208655 208656 208657 208658 208659 208660 208661 208662 208663 208664 208665 208666 208667 208668 208669 208670 208671 208672 208673 208674 208675 208676 208677 208678 208679 208680 208681 208682 208683 208684 208685 208686 208687 208688 208689 208690 208691 208692 208693 208694 208695 208696 208697 208698 208699 208700 208701 208702 208703 208704 208705 208706 208707 208708 208709 208710 208711 208712 208713 208714 208715 208716 |
/*
** Growing our own isspace() routine this way is twice as fast as
** the library isspace() function, resulting in a 7% overall performance
** increase for the text-JSON parser. (Ubuntu14.10 gcc 4.8.4 x64 with -Os).
*/
static const char jsonIsSpace[] = {
#ifdef SQLITE_ASCII
/*0 1 2 3 4 5 6 7 8 9 a b c d e f */
0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, /* 0 */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 1 */
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 2 */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 3 */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 4 */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 5 */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 6 */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 7 */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 8 */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 9 */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* a */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* b */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* c */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* d */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* e */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* f */
#endif
#ifdef SQLITE_EBCDIC
/*0 1 2 3 4 5 6 7 8 9 a b c d e f */
0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, /* 0 */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 1 */
0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 2 */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 3 */
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 4 */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 5 */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 6 */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 7 */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 8 */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 9 */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* a */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* b */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* c */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* d */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* e */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* f */
#endif
};
#define jsonIsspace(x) (jsonIsSpace[(unsigned char)x])
/*
** The set of all space characters recognized by jsonIsspace().
** Useful as the second argument to strspn().
*/
#ifdef SQLITE_ASCII
static const char jsonSpaces[] = "\011\012\015\040";
#endif
#ifdef SQLITE_EBCDIC
static const char jsonSpaces[] = "\005\045\015\100";
#endif
/*
** Characters that are special to JSON. Control characters,
** '"' and '\\' and '\''. Actually, '\'' is not special to
** canonical JSON, but it is special in JSON-5, so we include
** it in the set of special characters.
*/
static const char jsonIsOk[256] = {
#ifdef SQLITE_ASCII
/*0 1 2 3 4 5 6 7 8 9 a b c d e f */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0 */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 1 */
1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, /* 2 */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 3 */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 4 */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, /* 5 */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 6 */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 7 */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 8 */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 9 */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* a */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* b */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* c */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* d */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* e */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 /* f */
#endif
#ifdef SQLITE_EBCDIC
/*0 1 2 3 4 5 6 7 8 9 a b c d e f */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0 */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 1 */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 2 */
1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, /* 3 */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 4 */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 5 */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 6 */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, /* 7 */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 8 */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 9 */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* a */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* b */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* c */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* d */
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* e */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 /* f */
#endif
};
/* Objects */
typedef struct JsonCache JsonCache;
typedef struct JsonString JsonString;
typedef struct JsonParse JsonParse;
|
| ︙ | ︙ | |||
208160 208161 208162 208163 208164 208165 208166 | #define JSON_EDITABLE 0x01 /* Generate a writable JsonParse object */ #define JSON_KEEPERROR 0x02 /* Return non-NULL even if there is an error */ /************************************************************************** ** Forward references **************************************************************************/ static void jsonReturnStringAsBlob(JsonString*); | | | 208847 208848 208849 208850 208851 208852 208853 208854 208855 208856 208857 208858 208859 208860 208861 | #define JSON_EDITABLE 0x01 /* Generate a writable JsonParse object */ #define JSON_KEEPERROR 0x02 /* Return non-NULL even if there is an error */ /************************************************************************** ** Forward references **************************************************************************/ static void jsonReturnStringAsBlob(JsonString*); static int jsonArgIsJsonb(sqlite3_value *pJson, JsonParse *p); static u32 jsonTranslateBlobToText(const JsonParse*,u32,JsonString*); static void jsonReturnParse(sqlite3_context*,JsonParse*); static JsonParse *jsonParseFuncArg(sqlite3_context*,sqlite3_value*,u32); static void jsonParseFree(JsonParse*); static u32 jsonbPayloadSize(const JsonParse*, u32, u32*); static u32 jsonUnescapeOneChar(const char*, u32, u32*); |
| ︙ | ︙ | |||
208578 208579 208580 208581 208582 208583 208584 |
jsonAppendRaw(p, z, n);
}else{
jsonAppendString(p, z, n);
}
break;
}
default: {
| < | | | < | 209265 209266 209267 209268 209269 209270 209271 209272 209273 209274 209275 209276 209277 209278 209279 209280 209281 |
jsonAppendRaw(p, z, n);
}else{
jsonAppendString(p, z, n);
}
break;
}
default: {
JsonParse px;
memset(&px, 0, sizeof(px));
if( jsonArgIsJsonb(pValue, &px) ){
jsonTranslateBlobToText(&px, 0, p);
}else if( p->eErr==0 ){
sqlite3_result_error(p->pCtx, "JSON cannot hold BLOB values", -1);
p->eErr = JSTRING_ERR;
jsonStringReset(p);
}
break;
|
| ︙ | ︙ | |||
209049 209050 209051 209052 209053 209054 209055 209056 |
szType = a[0]>>4;
if( szType<=11 ){
nExtra = 0;
}else if( szType==12 ){
nExtra = 1;
}else if( szType==13 ){
nExtra = 2;
}else{
| > > | | 209734 209735 209736 209737 209738 209739 209740 209741 209742 209743 209744 209745 209746 209747 209748 209749 209750 209751 |
szType = a[0]>>4;
if( szType<=11 ){
nExtra = 0;
}else if( szType==12 ){
nExtra = 1;
}else if( szType==13 ){
nExtra = 2;
}else if( szType==14 ){
nExtra = 4;
}else{
nExtra = 8;
}
if( szPayload<=11 ){
nNeeded = 0;
}else if( szPayload<=0xff ){
nNeeded = 1;
}else if( szPayload<=0xffff ){
nNeeded = 2;
|
| ︙ | ︙ | |||
209520 209521 209522 209523 209524 209525 209526 |
break;
}else if( c=='\\' ){
c = z[++j];
if( c=='"' || c=='\\' || c=='/' || c=='b' || c=='f'
|| c=='n' || c=='r' || c=='t'
|| (c=='u' && jsonIs4Hex(&z[j+1])) ){
if( opcode==JSONB_TEXT ) opcode = JSONB_TEXTJ;
| | > > > > > | 210207 210208 210209 210210 210211 210212 210213 210214 210215 210216 210217 210218 210219 210220 210221 210222 210223 210224 210225 210226 |
break;
}else if( c=='\\' ){
c = z[++j];
if( c=='"' || c=='\\' || c=='/' || c=='b' || c=='f'
|| c=='n' || c=='r' || c=='t'
|| (c=='u' && jsonIs4Hex(&z[j+1])) ){
if( opcode==JSONB_TEXT ) opcode = JSONB_TEXTJ;
}else if( c=='\'' || c=='v' || c=='\n'
#ifdef SQLITE_BUG_COMPATIBLE_20250510
|| (c=='0') /* Legacy bug compatible */
#else
|| (c=='0' && !sqlite3Isdigit(z[j+1])) /* Correct implementation */
#endif
|| (0xe2==(u8)c && 0x80==(u8)z[j+1]
&& (0xa8==(u8)z[j+2] || 0xa9==(u8)z[j+2]))
|| (c=='x' && jsonIs2Hex(&z[j+1])) ){
opcode = JSONB_TEXT5;
pParse->hasNonstd = 1;
}else if( c=='\r' ){
if( z[j+1]=='\n' ) j++;
|
| ︙ | ︙ | |||
209907 209908 209909 209910 209911 209912 209913 |
|| pParse->aBlob[i+2]!=0
|| pParse->aBlob[i+3]!=0
|| pParse->aBlob[i+4]!=0
){
*pSz = 0;
return 0;
}
| | | 210599 210600 210601 210602 210603 210604 210605 210606 210607 210608 210609 210610 210611 210612 210613 |
|| pParse->aBlob[i+2]!=0
|| pParse->aBlob[i+3]!=0
|| pParse->aBlob[i+4]!=0
){
*pSz = 0;
return 0;
}
sz = ((u32)pParse->aBlob[i+5]<<24) + (pParse->aBlob[i+6]<<16) +
(pParse->aBlob[i+7]<<8) + pParse->aBlob[i+8];
n = 9;
}
if( (i64)i+sz+n > pParse->nBlob
&& (i64)i+sz+n > pParse->nBlob-pParse->delta
){
*pSz = 0;
|
| ︙ | ︙ | |||
210256 210257 210258 210259 210260 210261 210262 |
i = jsonTranslateBlobToText(pParse, i, pOut);
break;
}
}
return i;
}
| < < < < < < < < < < < < < < < < < < < < < < < < < < < | 210948 210949 210950 210951 210952 210953 210954 210955 210956 210957 210958 210959 210960 210961 |
i = jsonTranslateBlobToText(pParse, i, pOut);
break;
}
}
return i;
}
/*
** Given that a JSONB_ARRAY object starts at offset i, return
** the number of entries in that array.
*/
static u32 jsonbArrayCount(JsonParse *pParse, u32 iRoot){
u32 n, sz, i, iEnd;
u32 k = 0;
|
| ︙ | ︙ | |||
210515 210516 210517 210518 210519 210520 210521 |
}
case 'b': { *piOut = '\b'; return 2; }
case 'f': { *piOut = '\f'; return 2; }
case 'n': { *piOut = '\n'; return 2; }
case 'r': { *piOut = '\r'; return 2; }
case 't': { *piOut = '\t'; return 2; }
case 'v': { *piOut = '\v'; return 2; }
| | > > > > > > > > > > > > > > | 211180 211181 211182 211183 211184 211185 211186 211187 211188 211189 211190 211191 211192 211193 211194 211195 211196 211197 211198 211199 211200 211201 211202 211203 211204 211205 211206 211207 211208 |
}
case 'b': { *piOut = '\b'; return 2; }
case 'f': { *piOut = '\f'; return 2; }
case 'n': { *piOut = '\n'; return 2; }
case 'r': { *piOut = '\r'; return 2; }
case 't': { *piOut = '\t'; return 2; }
case 'v': { *piOut = '\v'; return 2; }
case '0': {
/* JSON5 requires that the \0 escape not be followed by a digit.
** But SQLite did not enforce this restriction in versions 3.42.0
** through 3.49.2. That was a bug. But some applications might have
** come to depend on that bug. Use the SQLITE_BUG_COMPATIBLE_20250510
** option to restore the old buggy behavior. */
#ifdef SQLITE_BUG_COMPATIBLE_20250510
/* Legacy bug-compatible behavior */
*piOut = 0;
#else
/* Correct behavior */
*piOut = (n>2 && sqlite3Isdigit(z[2])) ? JSON_INVALID_CHAR : 0;
#endif
return 2;
}
case '\'':
case '"':
case '/':
case '\\':{ *piOut = z[1]; return 2; }
case 'x': {
if( n<4 ){
*piOut = JSON_INVALID_CHAR;
|
| ︙ | ︙ | |||
211110 211111 211112 211113 211114 211115 211116 |
switch( eType ){
default: {
pParse->aBlob = aNull;
pParse->nBlob = 1;
return 0;
}
case SQLITE_BLOB: {
| < < | < | 211789 211790 211791 211792 211793 211794 211795 211796 211797 211798 211799 211800 211801 211802 211803 |
switch( eType ){
default: {
pParse->aBlob = aNull;
pParse->nBlob = 1;
return 0;
}
case SQLITE_BLOB: {
if( !jsonArgIsJsonb(pArg, pParse) ){
sqlite3_result_error(ctx, "JSON cannot hold BLOB values", -1);
return 1;
}
break;
}
case SQLITE_TEXT: {
const char *zJson = (const char*)sqlite3_value_text(pArg);
|
| ︙ | ︙ | |||
211264 211265 211266 211267 211268 211269 211270 | } return; } /* ** If pArg is a blob that seems like a JSONB blob, then initialize ** p to point to that JSONB and return TRUE. If pArg does not seem like | | | > > > > > | > > > > > > > > > > > > > > | > > | | < < < < < | | > > > | 211940 211941 211942 211943 211944 211945 211946 211947 211948 211949 211950 211951 211952 211953 211954 211955 211956 211957 211958 211959 211960 211961 211962 211963 211964 211965 211966 211967 211968 211969 211970 211971 211972 211973 211974 211975 211976 211977 211978 211979 211980 211981 211982 211983 211984 211985 211986 211987 211988 211989 211990 211991 211992 211993 |
}
return;
}
/*
** If pArg is a blob that seems like a JSONB blob, then initialize
** p to point to that JSONB and return TRUE. If pArg does not seem like
** a JSONB blob, then return FALSE.
**
** For small BLOBs (having no more than 7 bytes of payload) a full
** validity check is done. So for small BLOBs this routine only returns
** true if the value is guaranteed to be a valid JSONB. For larger BLOBs
** (8 byte or more of payload) only the size of the outermost element is
** checked to verify that the BLOB is superficially valid JSONB.
**
** A full JSONB validation is done on smaller BLOBs because those BLOBs might
** also be text JSON that has been incorrectly cast into a BLOB.
** (See tag-20240123-a and https://sqlite.org/forum/forumpost/012136abd5)
** If the BLOB is 9 bytes are larger, then it is not possible for the
** superficial size check done here to pass if the input is really text
** JSON so we do not need to look deeper in that case.
**
** Why we only need to do full JSONB validation for smaller BLOBs:
**
** The first byte of valid JSON text must be one of: '{', '[', '"', ' ', '\n',
** '\r', '\t', '-', or a digit '0' through '9'. Of these, only a subset
** can also be the first byte of JSONB: '{', '[', and digits '3'
** through '9'. In every one of those cases, the payload size is 7 bytes
** or less. So if we do full JSONB validation for every BLOB where the
** payload is less than 7 bytes, we will never get a false positive for
** JSONB on an input that is really text JSON.
*/
static int jsonArgIsJsonb(sqlite3_value *pArg, JsonParse *p){
u32 n, sz = 0;
u8 c;
if( sqlite3_value_type(pArg)!=SQLITE_BLOB ) return 0;
p->aBlob = (u8*)sqlite3_value_blob(pArg);
p->nBlob = (u32)sqlite3_value_bytes(pArg);
if( p->nBlob>0
&& ALWAYS(p->aBlob!=0)
&& ((c = p->aBlob[0]) & 0x0f)<=JSONB_OBJECT
&& (n = jsonbPayloadSize(p, 0, &sz))>0
&& sz+n==p->nBlob
&& ((c & 0x0f)>JSONB_FALSE || sz==0)
&& (sz>7
|| (c!=0x7b && c!=0x5b && !sqlite3Isdigit(c))
|| jsonbValidityCheck(p, 0, p->nBlob, 1)==0)
){
return 1;
}
p->aBlob = 0;
p->nBlob = 0;
return 0;
}
|
| ︙ | ︙ | |||
212377 212378 212379 212380 212381 212382 212383 |
#ifdef SQLITE_LEGACY_JSON_VALID
/* Incorrect legacy behavior was to return FALSE for a NULL input */
sqlite3_result_int(ctx, 0);
#endif
return;
}
case SQLITE_BLOB: {
| > > | | < < < < < | < | 213072 213073 213074 213075 213076 213077 213078 213079 213080 213081 213082 213083 213084 213085 213086 213087 213088 213089 213090 213091 213092 213093 213094 213095 213096 |
#ifdef SQLITE_LEGACY_JSON_VALID
/* Incorrect legacy behavior was to return FALSE for a NULL input */
sqlite3_result_int(ctx, 0);
#endif
return;
}
case SQLITE_BLOB: {
JsonParse py;
memset(&py, 0, sizeof(py));
if( jsonArgIsJsonb(argv[0], &py) ){
if( flags & 0x04 ){
/* Superficial checking only - accomplished by the
** jsonArgIsJsonb() call above. */
res = 1;
}else if( flags & 0x08 ){
/* Strict checking. Check by translating BLOB->TEXT->BLOB. If
** no errors occur, call that a "strict check". */
res = 0==jsonbValidityCheck(&py, 0, py.nBlob, 1);
}
break;
}
/* Fall through into interpreting the input as text. See note
** above at tag-20240123-a. */
/* no break */ deliberate_fall_through
}
|
| ︙ | ︙ | |||
212449 212450 212451 212452 212453 212454 212455 | i64 iErrPos = 0; /* Error position to be returned */ JsonParse s; assert( argc==1 ); UNUSED_PARAMETER(argc); memset(&s, 0, sizeof(s)); s.db = sqlite3_context_db_handle(ctx); | < | < | 213140 213141 213142 213143 213144 213145 213146 213147 213148 213149 213150 213151 213152 213153 213154 |
i64 iErrPos = 0; /* Error position to be returned */
JsonParse s;
assert( argc==1 );
UNUSED_PARAMETER(argc);
memset(&s, 0, sizeof(s));
s.db = sqlite3_context_db_handle(ctx);
if( jsonArgIsJsonb(argv[0], &s) ){
iErrPos = (i64)jsonbValidityCheck(&s, 0, s.nBlob, 1);
}else{
s.zJson = (char*)sqlite3_value_text(argv[0]);
if( s.zJson==0 ) return; /* NULL input or OOM */
s.nJson = sqlite3_value_bytes(argv[0]);
if( jsonConvertTextToBlob(&s,0) ){
if( s.oom ){
|
| ︙ | ︙ | |||
212612 212613 212614 212615 212616 212617 212618 212619 212620 212621 |
){
JsonString *pStr;
const char *z;
u32 n;
UNUSED_PARAMETER(argc);
pStr = (JsonString*)sqlite3_aggregate_context(ctx, sizeof(*pStr));
if( pStr ){
if( pStr->zBuf==0 ){
jsonStringInit(pStr, ctx);
jsonAppendChar(pStr, '{');
| > > | | < | | | > | 213301 213302 213303 213304 213305 213306 213307 213308 213309 213310 213311 213312 213313 213314 213315 213316 213317 213318 213319 213320 213321 213322 213323 213324 213325 213326 213327 213328 |
){
JsonString *pStr;
const char *z;
u32 n;
UNUSED_PARAMETER(argc);
pStr = (JsonString*)sqlite3_aggregate_context(ctx, sizeof(*pStr));
if( pStr ){
z = (const char*)sqlite3_value_text(argv[0]);
n = sqlite3Strlen30(z);
if( pStr->zBuf==0 ){
jsonStringInit(pStr, ctx);
jsonAppendChar(pStr, '{');
}else if( pStr->nUsed>1 && z!=0 ){
jsonAppendChar(pStr, ',');
}
pStr->pCtx = ctx;
if( z!=0 ){
jsonAppendString(pStr, z, n);
jsonAppendChar(pStr, ':');
jsonAppendSqlValue(pStr, argv[1]);
}
}
}
static void jsonObjectCompute(sqlite3_context *ctx, int isFinal){
JsonString *pStr;
pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0);
if( pStr ){
int flags;
|
| ︙ | ︙ | |||
213136 213137 213138 213139 213140 213141 213142 | UNUSED_PARAMETER(idxStr); UNUSED_PARAMETER(argc); jsonEachCursorReset(p); if( idxNum==0 ) return SQLITE_OK; memset(&p->sParse, 0, sizeof(p->sParse)); p->sParse.nJPRef = 1; p->sParse.db = p->db; | | | < | 213827 213828 213829 213830 213831 213832 213833 213834 213835 213836 213837 213838 213839 213840 213841 213842 |
UNUSED_PARAMETER(idxStr);
UNUSED_PARAMETER(argc);
jsonEachCursorReset(p);
if( idxNum==0 ) return SQLITE_OK;
memset(&p->sParse, 0, sizeof(p->sParse));
p->sParse.nJPRef = 1;
p->sParse.db = p->db;
if( jsonArgIsJsonb(argv[0], &p->sParse) ){
/* We have JSONB */
}else{
p->sParse.zJson = (char*)sqlite3_value_text(argv[0]);
p->sParse.nJson = sqlite3_value_bytes(argv[0]);
if( p->sParse.zJson==0 ){
p->i = p->iEnd = 0;
return SQLITE_OK;
}
|
| ︙ | ︙ | |||
213432 213433 213434 213435 213436 213437 213438 213439 213440 213441 213442 213443 213444 213445 | /* #include "sqlite3ext.h" */ SQLITE_EXTENSION_INIT1 #else /* #include "sqlite3.h" */ #endif SQLITE_PRIVATE int sqlite3GetToken(const unsigned char*,int*); /* In the SQLite core */ /* ** If building separately, we will need some setup that is normally ** found in sqliteInt.h */ #if !defined(SQLITE_AMALGAMATION) #include "sqlite3rtree.h" typedef sqlite3_int64 i64; | > > | 214122 214123 214124 214125 214126 214127 214128 214129 214130 214131 214132 214133 214134 214135 214136 214137 | /* #include "sqlite3ext.h" */ SQLITE_EXTENSION_INIT1 #else /* #include "sqlite3.h" */ #endif SQLITE_PRIVATE int sqlite3GetToken(const unsigned char*,int*); /* In the SQLite core */ /* #include <stddef.h> */ /* ** If building separately, we will need some setup that is normally ** found in sqliteInt.h */ #if !defined(SQLITE_AMALGAMATION) #include "sqlite3rtree.h" typedef sqlite3_int64 i64; |
| ︙ | ︙ | |||
213463 213464 213465 213466 213467 213468 213469 | # define ALWAYS(X) ((X)?1:(assert(0),0)) # define NEVER(X) ((X)?(assert(0),1):0) #else # define ALWAYS(X) (X) # define NEVER(X) (X) #endif #ifndef offsetof | | | 214155 214156 214157 214158 214159 214160 214161 214162 214163 214164 214165 214166 214167 214168 214169 | # define ALWAYS(X) ((X)?1:(assert(0),0)) # define NEVER(X) ((X)?(assert(0),1):0) #else # define ALWAYS(X) (X) # define NEVER(X) (X) #endif #ifndef offsetof # define offsetof(ST,M) ((size_t)((char*)&((ST*)0)->M - (char*)0)) #endif #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) # define FLEXARRAY #else # define FLEXARRAY 1 #endif #endif /* !defined(SQLITE_AMALGAMATION) */ |
| ︙ | ︙ | |||
214501 214502 214503 214504 214505 214506 214507 214508 214509 214510 214511 214512 214513 214514 |
for(ii=0; ii<RTREE_CACHE_SZ; ii++) nodeRelease(pRtree, pCsr->aNode[ii]);
sqlite3_free(pCsr->aPoint);
pStmt = pCsr->pReadAux;
memset(pCsr, 0, sizeof(RtreeCursor));
pCsr->base.pVtab = (sqlite3_vtab*)pRtree;
pCsr->pReadAux = pStmt;
}
/*
** Rtree virtual table module xClose method.
*/
static int rtreeClose(sqlite3_vtab_cursor *cur){
Rtree *pRtree = (Rtree *)(cur->pVtab);
| > > > > > > | 215193 215194 215195 215196 215197 215198 215199 215200 215201 215202 215203 215204 215205 215206 215207 215208 215209 215210 215211 215212 |
for(ii=0; ii<RTREE_CACHE_SZ; ii++) nodeRelease(pRtree, pCsr->aNode[ii]);
sqlite3_free(pCsr->aPoint);
pStmt = pCsr->pReadAux;
memset(pCsr, 0, sizeof(RtreeCursor));
pCsr->base.pVtab = (sqlite3_vtab*)pRtree;
pCsr->pReadAux = pStmt;
/* The following will only fail if the previous sqlite3_step() call failed,
** in which case the error has already been caught. This statement never
** encounters an error within an sqlite3_column_xxx() function, as it
** calls sqlite3_column_value(), which does not use malloc(). So it is safe
** to ignore the error code here. */
sqlite3_reset(pStmt);
}
/*
** Rtree virtual table module xClose method.
*/
static int rtreeClose(sqlite3_vtab_cursor *cur){
Rtree *pRtree = (Rtree *)(cur->pVtab);
|
| ︙ | ︙ | |||
227780 227781 227782 227783 227784 227785 227786 |
){
DbpageCursor *pCsr = (DbpageCursor *)pCursor;
DbpageTable *pTab = (DbpageTable *)pCursor->pVtab;
int rc;
sqlite3 *db = pTab->db;
Btree *pBt;
| | > | 228478 228479 228480 228481 228482 228483 228484 228485 228486 228487 228488 228489 228490 228491 228492 228493 |
){
DbpageCursor *pCsr = (DbpageCursor *)pCursor;
DbpageTable *pTab = (DbpageTable *)pCursor->pVtab;
int rc;
sqlite3 *db = pTab->db;
Btree *pBt;
UNUSED_PARAMETER(idxStr);
UNUSED_PARAMETER(argc);
/* Default setting is no rows of result */
pCsr->pgno = 1;
pCsr->mxPgno = 0;
if( idxNum & 2 ){
const char *zSchema;
|
| ︙ | ︙ | |||
231442 231443 231444 231445 231446 231447 231448 |
}
/*
** If the SessionInput object passed as the only argument is a streaming
** object and the buffer is full, discard some data to free up space.
*/
static void sessionDiscardData(SessionInput *pIn){
| | | | | | > | 232141 232142 232143 232144 232145 232146 232147 232148 232149 232150 232151 232152 232153 232154 232155 232156 232157 232158 232159 232160 232161 232162 232163 |
}
/*
** If the SessionInput object passed as the only argument is a streaming
** object and the buffer is full, discard some data to free up space.
*/
static void sessionDiscardData(SessionInput *pIn){
if( pIn->xInput && pIn->iCurrent>=sessions_strm_chunk_size ){
int nMove = pIn->buf.nBuf - pIn->iCurrent;
assert( nMove>=0 );
if( nMove>0 ){
memmove(pIn->buf.aBuf, &pIn->buf.aBuf[pIn->iCurrent], nMove);
}
pIn->buf.nBuf -= pIn->iCurrent;
pIn->iNext -= pIn->iCurrent;
pIn->iCurrent = 0;
pIn->nData = pIn->buf.nBuf;
}
}
/*
** Ensure that there are at least nByte bytes available in the buffer. Or,
** if there are not nByte bytes remaining in the input, that all available
|
| ︙ | ︙ | |||
231803 231804 231805 231806 231807 231808 231809 | /* Make sure the buffer contains at least 10 bytes of input data, or all ** remaining data if there are less than 10 bytes available. This is ** sufficient either for the 'T' or 'P' byte and the varint that follows ** it, or for the two single byte values otherwise. */ p->rc = sessionInputBuffer(&p->in, 2); if( p->rc!=SQLITE_OK ) return p->rc; | < > | 232503 232504 232505 232506 232507 232508 232509 232510 232511 232512 232513 232514 232515 232516 232517 232518 |
/* Make sure the buffer contains at least 10 bytes of input data, or all
** remaining data if there are less than 10 bytes available. This is
** sufficient either for the 'T' or 'P' byte and the varint that follows
** it, or for the two single byte values otherwise. */
p->rc = sessionInputBuffer(&p->in, 2);
if( p->rc!=SQLITE_OK ) return p->rc;
p->in.iCurrent = p->in.iNext;
sessionDiscardData(&p->in);
/* If the iterator is already at the end of the changeset, return DONE. */
if( p->in.iNext>=p->in.nData ){
return SQLITE_DONE;
}
op = p->in.aData[p->in.iNext++];
|
| ︙ | ︙ | |||
233227 233228 233229 233230 233231 233232 233233 233234 233235 233236 233237 233238 233239 233240 |
static int sessionChangesetApply(
sqlite3 *db, /* Apply change to "main" db of this handle */
sqlite3_changeset_iter *pIter, /* Changeset to apply */
int(*xFilter)(
void *pCtx, /* Copy of sixth arg to _apply() */
const char *zTab /* Table name */
),
int(*xConflict)(
void *pCtx, /* Copy of fifth arg to _apply() */
int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */
sqlite3_changeset_iter *p /* Handle describing change and conflict */
),
void *pCtx, /* First argument passed to xConflict */
void **ppRebase, int *pnRebase, /* OUT: Rebase information */
| > > > > | 233927 233928 233929 233930 233931 233932 233933 233934 233935 233936 233937 233938 233939 233940 233941 233942 233943 233944 |
static int sessionChangesetApply(
sqlite3 *db, /* Apply change to "main" db of this handle */
sqlite3_changeset_iter *pIter, /* Changeset to apply */
int(*xFilter)(
void *pCtx, /* Copy of sixth arg to _apply() */
const char *zTab /* Table name */
),
int(*xFilterIter)(
void *pCtx, /* Copy of sixth arg to _apply() */
sqlite3_changeset_iter *p
),
int(*xConflict)(
void *pCtx, /* Copy of fifth arg to _apply() */
int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */
sqlite3_changeset_iter *p /* Handle describing change and conflict */
),
void *pCtx, /* First argument passed to xConflict */
void **ppRebase, int *pnRebase, /* OUT: Rebase information */
|
| ︙ | ︙ | |||
233366 233367 233368 233369 233370 233371 233372 233373 233374 233375 233376 233377 233378 233379 |
nTab = sqlite3Strlen30(zTab);
}
}
/* If there is a schema mismatch on the current table, proceed to the
** next change. A log message has already been issued. */
if( schemaMismatch ) continue;
rc = sessionApplyOneWithRetry(db, pIter, &sApply, xConflict, pCtx);
}
bPatchset = pIter->bPatchset;
if( rc==SQLITE_OK ){
rc = sqlite3changeset_finalize(pIter);
| > > > | 234070 234071 234072 234073 234074 234075 234076 234077 234078 234079 234080 234081 234082 234083 234084 234085 234086 |
nTab = sqlite3Strlen30(zTab);
}
}
/* If there is a schema mismatch on the current table, proceed to the
** next change. A log message has already been issued. */
if( schemaMismatch ) continue;
/* If this is a call to apply_v3(), invoke xFilterIter here. */
if( xFilterIter && 0==xFilterIter(pCtx, pIter) ) continue;
rc = sessionApplyOneWithRetry(db, pIter, &sApply, xConflict, pCtx);
}
bPatchset = pIter->bPatchset;
if( rc==SQLITE_OK ){
rc = sqlite3changeset_finalize(pIter);
|
| ︙ | ︙ | |||
233433 233434 233435 233436 233437 233438 233439 233440 233441 233442 233443 233444 233445 233446 |
assert( db->flags & SQLITE_FkNoAction );
db->flags &= ~((u64)SQLITE_FkNoAction);
db->aDb[0].pSchema->schema_cookie -= 32;
}
sqlite3_mutex_leave(sqlite3_db_mutex(db));
return rc;
}
/*
** Apply the changeset passed via pChangeset/nChangeset to the main
** database attached to handle "db".
*/
SQLITE_API int sqlite3changeset_apply_v2(
sqlite3 *db, /* Apply change to "main" db of this handle */
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 234140 234141 234142 234143 234144 234145 234146 234147 234148 234149 234150 234151 234152 234153 234154 234155 234156 234157 234158 234159 234160 234161 234162 234163 234164 234165 234166 234167 234168 234169 234170 234171 234172 234173 234174 234175 234176 234177 234178 234179 234180 234181 234182 234183 234184 234185 234186 234187 234188 234189 234190 234191 234192 234193 234194 234195 234196 234197 234198 234199 234200 234201 234202 234203 234204 234205 234206 234207 234208 234209 234210 234211 234212 234213 234214 234215 234216 234217 234218 234219 234220 234221 234222 234223 234224 234225 234226 234227 234228 234229 234230 234231 234232 234233 234234 |
assert( db->flags & SQLITE_FkNoAction );
db->flags &= ~((u64)SQLITE_FkNoAction);
db->aDb[0].pSchema->schema_cookie -= 32;
}
sqlite3_mutex_leave(sqlite3_db_mutex(db));
return rc;
}
/*
** This function is called by all six sqlite3changeset_apply() variants:
**
** + sqlite3changeset_apply()
** + sqlite3changeset_apply_v2()
** + sqlite3changeset_apply_v3()
** + sqlite3changeset_apply_strm()
** + sqlite3changeset_apply_strm_v2()
** + sqlite3changeset_apply_strm_v3()
**
** Arguments passed to this function are as follows:
**
** db:
** Database handle to apply changeset to main database of.
**
** nChangeset/pChangeset:
** These are both passed zero for the streaming variants. For the normal
** apply() functions, these are passed the size of and the buffer containing
** the changeset, respectively.
**
** xInput/pIn:
** These are both passed zero for the normal variants. For the streaming
** apply() functions, these are passed the input callback and context
** pointer, respectively.
**
** xFilter:
** The filter function as passed to apply() or apply_v2() (to filter by
** table name), if any. This is always NULL for apply_v3() calls.
**
** xFilterIter:
** The filter function as passed to apply_v3(), if any.
**
** xConflict:
** The conflict handler callback (must not be NULL).
**
** pCtx:
** The context pointer passed to the xFilter and xConflict handler callbacks.
**
** ppRebase, pnRebase:
** Zero for apply(). The rebase changeset output pointers, if any, for
** apply_v2() and apply_v3().
**
** flags:
** Zero for apply(). The flags parameter for apply_v2() and apply_v3().
*/
static int sessionChangesetApplyV23(
sqlite3 *db, /* Apply change to "main" db of this handle */
int nChangeset, /* Size of changeset in bytes */
void *pChangeset, /* Changeset blob */
int (*xInput)(void *pIn, void *pData, int *pnData), /* Input function */
void *pIn, /* First arg for xInput */
int(*xFilter)(
void *pCtx, /* Copy of sixth arg to _apply() */
const char *zTab /* Table name */
),
int(*xFilterIter)(
void *pCtx, /* Copy of sixth arg to _apply() */
sqlite3_changeset_iter *p /* Handle describing current change */
),
int(*xConflict)(
void *pCtx, /* Copy of sixth arg to _apply() */
int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */
sqlite3_changeset_iter *p /* Handle describing change and conflict */
),
void *pCtx, /* First argument passed to xConflict */
void **ppRebase, int *pnRebase,
int flags
){
sqlite3_changeset_iter *pIter; /* Iterator to skip through changeset */
int bInverse = !!(flags & SQLITE_CHANGESETAPPLY_INVERT);
int rc = sessionChangesetStart(
&pIter, xInput, pIn, nChangeset, pChangeset, bInverse, 1
);
if( rc==SQLITE_OK ){
rc = sessionChangesetApply(db, pIter,
xFilter, xFilterIter, xConflict, pCtx, ppRebase, pnRebase, flags
);
}
return rc;
}
/*
** Apply the changeset passed via pChangeset/nChangeset to the main
** database attached to handle "db".
*/
SQLITE_API int sqlite3changeset_apply_v2(
sqlite3 *db, /* Apply change to "main" db of this handle */
|
| ︙ | ︙ | |||
233455 233456 233457 233458 233459 233460 233461 |
int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */
sqlite3_changeset_iter *p /* Handle describing change and conflict */
),
void *pCtx, /* First argument passed to xConflict */
void **ppRebase, int *pnRebase,
int flags
){
| | < | | < < | | | > > > > > > > > > > > > > > > > > > > > > | > > > > | 234243 234244 234245 234246 234247 234248 234249 234250 234251 234252 234253 234254 234255 234256 234257 234258 234259 234260 234261 234262 234263 234264 234265 234266 234267 234268 234269 234270 234271 234272 234273 234274 234275 234276 234277 234278 234279 234280 234281 234282 234283 234284 234285 234286 234287 234288 234289 |
int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */
sqlite3_changeset_iter *p /* Handle describing change and conflict */
),
void *pCtx, /* First argument passed to xConflict */
void **ppRebase, int *pnRebase,
int flags
){
return sessionChangesetApplyV23(db,
nChangeset, pChangeset, 0, 0,
xFilter, 0, xConflict, pCtx,
ppRebase, pnRebase, flags
);
}
/*
** Apply the changeset passed via pChangeset/nChangeset to the main
** database attached to handle "db".
*/
SQLITE_API int sqlite3changeset_apply_v3(
sqlite3 *db, /* Apply change to "main" db of this handle */
int nChangeset, /* Size of changeset in bytes */
void *pChangeset, /* Changeset blob */
int(*xFilter)(
void *pCtx, /* Copy of sixth arg to _apply() */
sqlite3_changeset_iter *p /* Handle describing current change */
),
int(*xConflict)(
void *pCtx, /* Copy of sixth arg to _apply() */
int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */
sqlite3_changeset_iter *p /* Handle describing change and conflict */
),
void *pCtx, /* First argument passed to xConflict */
void **ppRebase, int *pnRebase,
int flags
){
return sessionChangesetApplyV23(db,
nChangeset, pChangeset, 0, 0,
0, xFilter, xConflict, pCtx,
ppRebase, pnRebase, flags
);
}
/*
** Apply the changeset passed via pChangeset/nChangeset to the main database
** attached to handle "db". Invoke the supplied conflict handler callback
** to resolve any conflicts encountered while applying the change.
*/
|
| ︙ | ︙ | |||
233488 233489 233490 233491 233492 233493 233494 |
int(*xConflict)(
void *pCtx, /* Copy of fifth arg to _apply() */
int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */
sqlite3_changeset_iter *p /* Handle describing change and conflict */
),
void *pCtx /* First argument passed to xConflict */
){
| | | > > > > > > > > > > > > > > > > > > > > > > > > > < < < < | > > | | < < | | > > | 234298 234299 234300 234301 234302 234303 234304 234305 234306 234307 234308 234309 234310 234311 234312 234313 234314 234315 234316 234317 234318 234319 234320 234321 234322 234323 234324 234325 234326 234327 234328 234329 234330 234331 234332 234333 234334 234335 234336 234337 234338 234339 234340 234341 234342 234343 234344 234345 234346 234347 234348 234349 234350 234351 234352 234353 234354 234355 234356 234357 234358 234359 234360 234361 234362 234363 234364 234365 234366 234367 234368 234369 234370 234371 234372 234373 234374 234375 234376 234377 234378 234379 234380 234381 234382 234383 234384 234385 234386 234387 234388 |
int(*xConflict)(
void *pCtx, /* Copy of fifth arg to _apply() */
int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */
sqlite3_changeset_iter *p /* Handle describing change and conflict */
),
void *pCtx /* First argument passed to xConflict */
){
return sessionChangesetApplyV23(db,
nChangeset, pChangeset, 0, 0,
xFilter, 0, xConflict, pCtx,
0, 0, 0
);
}
/*
** Apply the changeset passed via xInput/pIn to the main database
** attached to handle "db". Invoke the supplied conflict handler callback
** to resolve any conflicts encountered while applying the change.
*/
SQLITE_API int sqlite3changeset_apply_v3_strm(
sqlite3 *db, /* Apply change to "main" db of this handle */
int (*xInput)(void *pIn, void *pData, int *pnData), /* Input function */
void *pIn, /* First arg for xInput */
int(*xFilter)(
void *pCtx, /* Copy of sixth arg to _apply() */
sqlite3_changeset_iter *p
),
int(*xConflict)(
void *pCtx, /* Copy of sixth arg to _apply() */
int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */
sqlite3_changeset_iter *p /* Handle describing change and conflict */
),
void *pCtx, /* First argument passed to xConflict */
void **ppRebase, int *pnRebase,
int flags
){
return sessionChangesetApplyV23(db,
0, 0, xInput, pIn,
0, xFilter, xConflict, pCtx,
ppRebase, pnRebase, flags
);
}
SQLITE_API int sqlite3changeset_apply_v2_strm(
sqlite3 *db, /* Apply change to "main" db of this handle */
int (*xInput)(void *pIn, void *pData, int *pnData), /* Input function */
void *pIn, /* First arg for xInput */
int(*xFilter)(
void *pCtx, /* Copy of sixth arg to _apply() */
const char *zTab /* Table name */
),
int(*xConflict)(
void *pCtx, /* Copy of sixth arg to _apply() */
int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */
sqlite3_changeset_iter *p /* Handle describing change and conflict */
),
void *pCtx, /* First argument passed to xConflict */
void **ppRebase, int *pnRebase,
int flags
){
return sessionChangesetApplyV23(db,
0, 0, xInput, pIn,
xFilter, 0, xConflict, pCtx,
ppRebase, pnRebase, flags
);
}
SQLITE_API int sqlite3changeset_apply_strm(
sqlite3 *db, /* Apply change to "main" db of this handle */
int (*xInput)(void *pIn, void *pData, int *pnData), /* Input function */
void *pIn, /* First arg for xInput */
int(*xFilter)(
void *pCtx, /* Copy of sixth arg to _apply() */
const char *zTab /* Table name */
),
int(*xConflict)(
void *pCtx, /* Copy of sixth arg to _apply() */
int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */
sqlite3_changeset_iter *p /* Handle describing change and conflict */
),
void *pCtx /* First argument passed to xConflict */
){
return sessionChangesetApplyV23(db,
0, 0, xInput, pIn,
xFilter, 0, xConflict, pCtx,
0, 0, 0
);
}
/*
** sqlite3_changegroup handle.
*/
struct sqlite3_changegroup {
|
| ︙ | ︙ | |||
234163 234164 234165 234166 234167 234168 234169 234170 234171 234172 234173 234174 |
/*
** Add a single change to a changeset-group.
*/
SQLITE_API int sqlite3changegroup_add_change(
sqlite3_changegroup *pGrp,
sqlite3_changeset_iter *pIter
){
if( pIter->in.iCurrent==pIter->in.iNext
|| pIter->rc!=SQLITE_OK
|| pIter->bInvert
){
/* Iterator does not point to any valid entry or is an INVERT iterator. */
| > > | > > > | | 234996 234997 234998 234999 235000 235001 235002 235003 235004 235005 235006 235007 235008 235009 235010 235011 235012 235013 235014 235015 235016 235017 235018 235019 235020 235021 235022 |
/*
** Add a single change to a changeset-group.
*/
SQLITE_API int sqlite3changegroup_add_change(
sqlite3_changegroup *pGrp,
sqlite3_changeset_iter *pIter
){
int rc = SQLITE_OK;
if( pIter->in.iCurrent==pIter->in.iNext
|| pIter->rc!=SQLITE_OK
|| pIter->bInvert
){
/* Iterator does not point to any valid entry or is an INVERT iterator. */
rc = SQLITE_ERROR;
}else{
pIter->in.bNoDiscard = 1;
rc = sessionOneChangeToHash(pGrp, pIter, 0);
}
return rc;
}
/*
** Obtain a buffer containing a changeset representing the concatenation
** of all changesets added to the group so far.
*/
SQLITE_API int sqlite3changegroup_output(
|
| ︙ | ︙ | |||
235468 235469 235470 235471 235472 235473 235474 235475 235476 235477 235478 235479 235480 235481 | /* #include "fts5.h" */ /* #include "sqlite3ext.h" */ SQLITE_EXTENSION_INIT1 /* #include <string.h> */ /* #include <assert.h> */ #ifndef SQLITE_AMALGAMATION typedef unsigned char u8; typedef unsigned int u32; typedef unsigned short u16; typedef short i16; | > | 236306 236307 236308 236309 236310 236311 236312 236313 236314 236315 236316 236317 236318 236319 236320 | /* #include "fts5.h" */ /* #include "sqlite3ext.h" */ SQLITE_EXTENSION_INIT1 /* #include <string.h> */ /* #include <assert.h> */ /* #include <stddef.h> */ #ifndef SQLITE_AMALGAMATION typedef unsigned char u8; typedef unsigned int u32; typedef unsigned short u16; typedef short i16; |
| ︙ | ︙ | |||
235527 235528 235529 235530 235531 235532 235533 | # define EIGHT_BYTE_ALIGNMENT(X) ((((uptr)(X) - (uptr)0)&7)==0) #endif /* ** Macros needed to provide flexible arrays in a portable way */ #ifndef offsetof | | | 236366 236367 236368 236369 236370 236371 236372 236373 236374 236375 236376 236377 236378 236379 236380 | # define EIGHT_BYTE_ALIGNMENT(X) ((((uptr)(X) - (uptr)0)&7)==0) #endif /* ** Macros needed to provide flexible arrays in a portable way */ #ifndef offsetof # define offsetof(ST,M) ((size_t)((char*)&((ST*)0)->M - (char*)0)) #endif #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) # define FLEXARRAY #else # define FLEXARRAY 1 #endif |
| ︙ | ︙ | |||
244711 244712 244713 244714 244715 244716 244717 244718 244719 244720 244721 244722 244723 244724 |
/* Variables populated based on current entry. */
Fts5Buffer term; /* Current term */
i64 iRowid; /* Current rowid */
int nPos; /* Number of bytes in current position list */
u8 bDel; /* True if the delete flag is set */
};
/*
** Array of tombstone pages. Reference counted.
*/
struct Fts5TombstoneArray {
int nRef; /* Number of pointers to this object */
int nTombstone;
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 245550 245551 245552 245553 245554 245555 245556 245557 245558 245559 245560 245561 245562 245563 245564 245565 245566 245567 245568 245569 245570 245571 245572 245573 245574 245575 245576 245577 245578 245579 245580 245581 245582 245583 245584 245585 245586 245587 245588 245589 245590 245591 245592 245593 |
/* Variables populated based on current entry. */
Fts5Buffer term; /* Current term */
i64 iRowid; /* Current rowid */
int nPos; /* Number of bytes in current position list */
u8 bDel; /* True if the delete flag is set */
};
static int fts5IndexCorruptRowid(Fts5Index *pIdx, i64 iRowid){
pIdx->rc = FTS5_CORRUPT;
sqlite3Fts5ConfigErrmsg(pIdx->pConfig,
"fts5: corruption found reading blob %lld from table \"%s\"",
iRowid, pIdx->pConfig->zName
);
return SQLITE_CORRUPT_VTAB;
}
#define FTS5_CORRUPT_ROWID(pIdx, iRowid) fts5IndexCorruptRowid(pIdx, iRowid)
static int fts5IndexCorruptIter(Fts5Index *pIdx, Fts5SegIter *pIter){
pIdx->rc = FTS5_CORRUPT;
sqlite3Fts5ConfigErrmsg(pIdx->pConfig,
"fts5: corruption on page %d, segment %d, table \"%s\"",
pIter->iLeafPgno, pIter->pSeg->iSegid, pIdx->pConfig->zName
);
return SQLITE_CORRUPT_VTAB;
}
#define FTS5_CORRUPT_ITER(pIdx, pIter) fts5IndexCorruptIter(pIdx, pIter)
static int fts5IndexCorruptIdx(Fts5Index *pIdx){
pIdx->rc = FTS5_CORRUPT;
sqlite3Fts5ConfigErrmsg(pIdx->pConfig,
"fts5: corruption in table \"%s\"", pIdx->pConfig->zName
);
return SQLITE_CORRUPT_VTAB;
}
#define FTS5_CORRUPT_IDX(pIdx) fts5IndexCorruptIdx(pIdx)
/*
** Array of tombstone pages. Reference counted.
*/
struct Fts5TombstoneArray {
int nRef; /* Number of pointers to this object */
int nTombstone;
|
| ︙ | ︙ | |||
245001 245002 245003 245004 245005 245006 245007 |
}
/* If either of the sqlite3_blob_open() or sqlite3_blob_reopen() calls
** above returned SQLITE_ERROR, return SQLITE_CORRUPT_VTAB instead.
** All the reasons those functions might return SQLITE_ERROR - missing
** table, missing row, non-blob/text in block column - indicate
** backing store corruption. */
| | | 245870 245871 245872 245873 245874 245875 245876 245877 245878 245879 245880 245881 245882 245883 245884 |
}
/* If either of the sqlite3_blob_open() or sqlite3_blob_reopen() calls
** above returned SQLITE_ERROR, return SQLITE_CORRUPT_VTAB instead.
** All the reasons those functions might return SQLITE_ERROR - missing
** table, missing row, non-blob/text in block column - indicate
** backing store corruption. */
if( rc==SQLITE_ERROR ) rc = FTS5_CORRUPT_ROWID(p, iRowid);
if( rc==SQLITE_OK ){
u8 *aOut = 0; /* Read blob data into this buffer */
int nByte = sqlite3_blob_bytes(p->pReader);
int szData = (sizeof(Fts5Data) + 7) & ~7;
sqlite3_int64 nAlloc = szData + nByte + FTS5_DATA_PADDING;
pRet = (Fts5Data*)sqlite3_malloc64(nAlloc);
|
| ︙ | ︙ | |||
245051 245052 245053 245054 245055 245056 245057 |
sqlite3_free(pData);
}
static Fts5Data *fts5LeafRead(Fts5Index *p, i64 iRowid){
Fts5Data *pRet = fts5DataRead(p, iRowid);
if( pRet ){
if( pRet->nn<4 || pRet->szLeaf>pRet->nn ){
| | | 245920 245921 245922 245923 245924 245925 245926 245927 245928 245929 245930 245931 245932 245933 245934 |
sqlite3_free(pData);
}
static Fts5Data *fts5LeafRead(Fts5Index *p, i64 iRowid){
Fts5Data *pRet = fts5DataRead(p, iRowid);
if( pRet ){
if( pRet->nn<4 || pRet->szLeaf>pRet->nn ){
FTS5_CORRUPT_ROWID(p, iRowid);
fts5DataRelease(pRet);
pRet = 0;
}
}
return pRet;
}
|
| ︙ | ︙ | |||
245410 245411 245412 245413 245414 245415 245416 |
Fts5Data *pData;
pData = fts5DataRead(p, FTS5_STRUCTURE_ROWID);
if( p->rc==SQLITE_OK ){
/* TODO: Do we need this if the leaf-index is appended? Probably... */
memset(&pData->p[pData->nn], 0, FTS5_DATA_PADDING);
p->rc = fts5StructureDecode(pData->p, pData->nn, &iCookie, &pRet);
| > | | > > > > > | 246279 246280 246281 246282 246283 246284 246285 246286 246287 246288 246289 246290 246291 246292 246293 246294 246295 246296 246297 246298 246299 246300 |
Fts5Data *pData;
pData = fts5DataRead(p, FTS5_STRUCTURE_ROWID);
if( p->rc==SQLITE_OK ){
/* TODO: Do we need this if the leaf-index is appended? Probably... */
memset(&pData->p[pData->nn], 0, FTS5_DATA_PADDING);
p->rc = fts5StructureDecode(pData->p, pData->nn, &iCookie, &pRet);
if( p->rc==SQLITE_OK ){
if( (pConfig->pgsz==0 || pConfig->iCookie!=iCookie) ){
p->rc = sqlite3Fts5ConfigLoad(pConfig, iCookie);
}
}else if( p->rc==SQLITE_CORRUPT_VTAB ){
sqlite3Fts5ConfigErrmsg(p->pConfig,
"fts5: corrupt structure record for table \"%s\"", p->pConfig->zName
);
}
fts5DataRelease(pData);
if( p->rc!=SQLITE_OK ){
fts5StructureRelease(pRet);
pRet = 0;
}
}
|
| ︙ | ︙ | |||
246034 246035 246036 246037 246038 246039 246040 |
u8 *a = pIter->pLeaf->p; /* Buffer to read data from */
i64 iOff = pIter->iLeafOffset;
ASSERT_SZLEAF_OK(pIter->pLeaf);
while( iOff>=pIter->pLeaf->szLeaf ){
fts5SegIterNextPage(p, pIter);
if( pIter->pLeaf==0 ){
| | | 246909 246910 246911 246912 246913 246914 246915 246916 246917 246918 246919 246920 246921 246922 246923 |
u8 *a = pIter->pLeaf->p; /* Buffer to read data from */
i64 iOff = pIter->iLeafOffset;
ASSERT_SZLEAF_OK(pIter->pLeaf);
while( iOff>=pIter->pLeaf->szLeaf ){
fts5SegIterNextPage(p, pIter);
if( pIter->pLeaf==0 ){
if( p->rc==SQLITE_OK ) FTS5_CORRUPT_ITER(p, pIter);
return;
}
iOff = 4;
a = pIter->pLeaf->p;
}
iOff += sqlite3Fts5GetVarint(&a[iOff], (u64*)&pIter->iRowid);
pIter->iLeafOffset = iOff;
|
| ︙ | ︙ | |||
246066 246067 246068 246069 246070 246071 246072 |
static void fts5SegIterLoadTerm(Fts5Index *p, Fts5SegIter *pIter, int nKeep){
u8 *a = pIter->pLeaf->p; /* Buffer to read data from */
i64 iOff = pIter->iLeafOffset; /* Offset to read at */
int nNew; /* Bytes of new data */
iOff += fts5GetVarint32(&a[iOff], nNew);
if( iOff+nNew>pIter->pLeaf->szLeaf || nKeep>pIter->term.n || nNew==0 ){
| | | 246941 246942 246943 246944 246945 246946 246947 246948 246949 246950 246951 246952 246953 246954 246955 |
static void fts5SegIterLoadTerm(Fts5Index *p, Fts5SegIter *pIter, int nKeep){
u8 *a = pIter->pLeaf->p; /* Buffer to read data from */
i64 iOff = pIter->iLeafOffset; /* Offset to read at */
int nNew; /* Bytes of new data */
iOff += fts5GetVarint32(&a[iOff], nNew);
if( iOff+nNew>pIter->pLeaf->szLeaf || nKeep>pIter->term.n || nNew==0 ){
FTS5_CORRUPT_ITER(p, pIter);
return;
}
pIter->term.n = nKeep;
fts5BufferAppendBlob(&p->rc, &pIter->term, nNew, &a[iOff]);
assert( pIter->term.n<=pIter->term.nSpace );
iOff += nNew;
pIter->iTermLeafOffset = iOff;
|
| ︙ | ︙ | |||
246108 246109 246110 246111 246112 246113 246114 |
/*
** Allocate a tombstone hash page array object (pIter->pTombArray) for
** the iterator passed as the second argument. If an OOM error occurs,
** leave an error in the Fts5Index object.
*/
static void fts5SegIterAllocTombstone(Fts5Index *p, Fts5SegIter *pIter){
| | | | 246983 246984 246985 246986 246987 246988 246989 246990 246991 246992 246993 246994 246995 246996 246997 246998 246999 |
/*
** Allocate a tombstone hash page array object (pIter->pTombArray) for
** the iterator passed as the second argument. If an OOM error occurs,
** leave an error in the Fts5Index object.
*/
static void fts5SegIterAllocTombstone(Fts5Index *p, Fts5SegIter *pIter){
const i64 nTomb = (i64)pIter->pSeg->nPgTombstone;
if( nTomb>0 ){
i64 nByte = SZ_FTS5TOMBSTONEARRAY(nTomb+1);
Fts5TombstoneArray *pNew;
pNew = (Fts5TombstoneArray*)sqlite3Fts5MallocZero(&p->rc, nByte);
if( pNew ){
pNew->nTombstone = nTomb;
pNew->nRef = 1;
pIter->pTombArray = pNew;
}
|
| ︙ | ︙ | |||
246261 246262 246263 246264 246265 246266 246267 |
pIter->iLeafOffset = pIter->iTermLeafOffset;
}
}else{
int iRowidOff;
iRowidOff = fts5LeafFirstRowidOff(pNew);
if( iRowidOff ){
if( iRowidOff>=pNew->szLeaf ){
| | | 247136 247137 247138 247139 247140 247141 247142 247143 247144 247145 247146 247147 247148 247149 247150 |
pIter->iLeafOffset = pIter->iTermLeafOffset;
}
}else{
int iRowidOff;
iRowidOff = fts5LeafFirstRowidOff(pNew);
if( iRowidOff ){
if( iRowidOff>=pNew->szLeaf ){
FTS5_CORRUPT_ITER(p, pIter);
}else{
pIter->pLeaf = pNew;
pIter->iLeafOffset = iRowidOff;
}
}
}
|
| ︙ | ︙ | |||
246495 246496 246497 246498 246499 246500 246501 |
);
pIter->iLeafOffset = iOff;
pIter->iEndofDoclist = iOff;
bNewTerm = 1;
}
assert_nc( iOff<pLeaf->szLeaf );
if( iOff>pLeaf->szLeaf ){
| | | 247370 247371 247372 247373 247374 247375 247376 247377 247378 247379 247380 247381 247382 247383 247384 |
);
pIter->iLeafOffset = iOff;
pIter->iEndofDoclist = iOff;
bNewTerm = 1;
}
assert_nc( iOff<pLeaf->szLeaf );
if( iOff>pLeaf->szLeaf ){
FTS5_CORRUPT_ITER(p, pIter);
return;
}
}
}
/* Check if the iterator is now at EOF. If so, return early. */
if( pIter->pLeaf ){
|
| ︙ | ︙ | |||
246603 246604 246605 246606 246607 246608 246609 |
** first rowid on this page.
*/
if( pLast ){
int iOff;
fts5DataRelease(pIter->pLeaf);
pIter->pLeaf = pLast;
pIter->iLeafPgno = pgnoLast;
| > | | | | | | | | | | | > | 247478 247479 247480 247481 247482 247483 247484 247485 247486 247487 247488 247489 247490 247491 247492 247493 247494 247495 247496 247497 247498 247499 247500 247501 247502 247503 247504 247505 |
** first rowid on this page.
*/
if( pLast ){
int iOff;
fts5DataRelease(pIter->pLeaf);
pIter->pLeaf = pLast;
pIter->iLeafPgno = pgnoLast;
if( p->rc==SQLITE_OK ){
iOff = fts5LeafFirstRowidOff(pLast);
if( iOff>pLast->szLeaf ){
FTS5_CORRUPT_ITER(p, pIter);
return;
}
iOff += fts5GetVarint(&pLast->p[iOff], (u64*)&pIter->iRowid);
pIter->iLeafOffset = iOff;
if( fts5LeafIsTermless(pLast) ){
pIter->iEndofDoclist = pLast->nn+1;
}else{
pIter->iEndofDoclist = fts5LeafFirstTermOff(pLast);
}
}
}
fts5SegIterReverseInitPage(p, pIter);
}
/*
|
| ︙ | ︙ | |||
246684 246685 246686 246687 246688 246689 246690 |
assert( p->rc==SQLITE_OK );
iPgidx = (u32)pIter->pLeaf->szLeaf;
iPgidx += fts5GetVarint32(&a[iPgidx], iTermOff);
iOff = iTermOff;
if( iOff>n ){
| | | 247561 247562 247563 247564 247565 247566 247567 247568 247569 247570 247571 247572 247573 247574 247575 |
assert( p->rc==SQLITE_OK );
iPgidx = (u32)pIter->pLeaf->szLeaf;
iPgidx += fts5GetVarint32(&a[iPgidx], iTermOff);
iOff = iTermOff;
if( iOff>n ){
FTS5_CORRUPT_ITER(p, pIter);
return;
}
while( 1 ){
/* Figure out how many new bytes are in this term */
fts5FastGetVarint32(a, iOff, nNew);
|
| ︙ | ︙ | |||
246727 246728 246729 246730 246731 246732 246733 |
}
iPgidx += fts5GetVarint32(&a[iPgidx], nKeep);
iTermOff += nKeep;
iOff = iTermOff;
if( iOff>=n ){
| | | 247604 247605 247606 247607 247608 247609 247610 247611 247612 247613 247614 247615 247616 247617 247618 |
}
iPgidx += fts5GetVarint32(&a[iPgidx], nKeep);
iTermOff += nKeep;
iOff = iTermOff;
if( iOff>=n ){
FTS5_CORRUPT_ITER(p, pIter);
return;
}
/* Read the nKeep field of the next term. */
fts5FastGetVarint32(a, iOff, nKeep);
}
|
| ︙ | ︙ | |||
246749 246750 246751 246752 246753 246754 246755 |
fts5SegIterNextPage(p, pIter);
if( pIter->pLeaf==0 ) return;
a = pIter->pLeaf->p;
if( fts5LeafIsTermless(pIter->pLeaf)==0 ){
iPgidx = (u32)pIter->pLeaf->szLeaf;
iPgidx += fts5GetVarint32(&pIter->pLeaf->p[iPgidx], iOff);
if( iOff<4 || (i64)iOff>=pIter->pLeaf->szLeaf ){
| | | | 247626 247627 247628 247629 247630 247631 247632 247633 247634 247635 247636 247637 247638 247639 247640 247641 247642 247643 247644 247645 247646 247647 247648 247649 247650 247651 247652 247653 247654 247655 |
fts5SegIterNextPage(p, pIter);
if( pIter->pLeaf==0 ) return;
a = pIter->pLeaf->p;
if( fts5LeafIsTermless(pIter->pLeaf)==0 ){
iPgidx = (u32)pIter->pLeaf->szLeaf;
iPgidx += fts5GetVarint32(&pIter->pLeaf->p[iPgidx], iOff);
if( iOff<4 || (i64)iOff>=pIter->pLeaf->szLeaf ){
FTS5_CORRUPT_ITER(p, pIter);
return;
}else{
nKeep = 0;
iTermOff = iOff;
n = (u32)pIter->pLeaf->nn;
iOff += fts5GetVarint32(&a[iOff], nNew);
break;
}
}
}while( 1 );
}
search_success:
if( (i64)iOff+nNew>n || nNew<1 ){
FTS5_CORRUPT_ITER(p, pIter);
return;
}
pIter->iLeafOffset = iOff + nNew;
pIter->iTermLeafOffset = pIter->iLeafOffset;
pIter->iTermLeafPgno = pIter->iLeafPgno;
fts5BufferSet(&p->rc, &pIter->term, nKeep, pTerm);
|
| ︙ | ︙ | |||
247229 247230 247231 247232 247233 247234 247235 |
Fts5Index *p, /* FTS5 backend object */
Fts5SegIter *pIter, /* Iterator to advance */
int iLeafPgno
){
assert( iLeafPgno>pIter->iLeafPgno );
if( iLeafPgno>pIter->pSeg->pgnoLast ){
| | | | 248106 248107 248108 248109 248110 248111 248112 248113 248114 248115 248116 248117 248118 248119 248120 248121 248122 248123 248124 248125 248126 248127 248128 248129 248130 248131 248132 248133 248134 248135 |
Fts5Index *p, /* FTS5 backend object */
Fts5SegIter *pIter, /* Iterator to advance */
int iLeafPgno
){
assert( iLeafPgno>pIter->iLeafPgno );
if( iLeafPgno>pIter->pSeg->pgnoLast ){
FTS5_CORRUPT_IDX(p);
}else{
fts5DataRelease(pIter->pNextLeaf);
pIter->pNextLeaf = 0;
pIter->iLeafPgno = iLeafPgno-1;
while( p->rc==SQLITE_OK ){
int iOff;
fts5SegIterNextPage(p, pIter);
if( pIter->pLeaf==0 ) break;
iOff = fts5LeafFirstRowidOff(pIter->pLeaf);
if( iOff>0 ){
u8 *a = pIter->pLeaf->p;
int n = pIter->pLeaf->szLeaf;
if( iOff<4 || iOff>=n ){
FTS5_CORRUPT_IDX(p);
}else{
iOff += fts5GetVarint(&a[iOff], (u64*)&pIter->iRowid);
pIter->iLeafOffset = iOff;
fts5SegIterLoadNPos(p, pIter);
}
break;
}
|
| ︙ | ︙ | |||
247723 247724 247725 247726 247727 247728 247729 |
while( 1 ){
xChunk(p, pCtx, pChunk, nChunk);
nRem -= nChunk;
fts5DataRelease(pData);
if( nRem<=0 ){
break;
}else if( pSeg->pSeg==0 ){
| | | 248600 248601 248602 248603 248604 248605 248606 248607 248608 248609 248610 248611 248612 248613 248614 |
while( 1 ){
xChunk(p, pCtx, pChunk, nChunk);
nRem -= nChunk;
fts5DataRelease(pData);
if( nRem<=0 ){
break;
}else if( pSeg->pSeg==0 ){
FTS5_CORRUPT_IDX(p);
return;
}else{
pgno++;
pData = fts5LeafRead(p, FTS5_SEGMENT_ROWID(pSeg->pSeg->iSegid, pgno));
if( pData==0 ) break;
pChunk = &pData->p[4];
nChunk = MIN(nRem, pData->szLeaf - 4);
|
| ︙ | ︙ | |||
248826 248827 248828 248829 248830 248831 248832 |
pData = fts5LeafRead(p, iLeafRowid);
if( pData ){
if( iOff>pData->szLeaf ){
/* This can occur if the pages that the segments occupy overlap - if
** a single page has been assigned to more than one segment. In
** this case a prior iteration of this loop may have corrupted the
** segment currently being trimmed. */
| | | 249703 249704 249705 249706 249707 249708 249709 249710 249711 249712 249713 249714 249715 249716 249717 |
pData = fts5LeafRead(p, iLeafRowid);
if( pData ){
if( iOff>pData->szLeaf ){
/* This can occur if the pages that the segments occupy overlap - if
** a single page has been assigned to more than one segment. In
** this case a prior iteration of this loop may have corrupted the
** segment currently being trimmed. */
FTS5_CORRUPT_ROWID(p, iLeafRowid);
}else{
fts5BufferZero(&buf);
fts5BufferGrow(&p->rc, &buf, pData->nn);
fts5BufferAppendBlob(&p->rc, &buf, sizeof(aHdr), aHdr);
fts5BufferAppendVarint(&p->rc, &buf, pSeg->term.n);
fts5BufferAppendBlob(&p->rc, &buf, pSeg->term.n, pSeg->term.p);
fts5BufferAppendBlob(&p->rc, &buf,pData->szLeaf-iOff,&pData->p[iOff]);
|
| ︙ | ︙ | |||
249293 249294 249295 249296 249297 249298 249299 |
assert_nc( bDetailNone==0 || pLeaf->nn==4 );
if( bDetailNone==0 ) fts5DataWrite(p, iRowid, aEmpty, sizeof(aEmpty));
fts5DataRelease(pLeaf);
pLeaf = 0;
}else if( bDetailNone ){
break;
}else if( iNext>=pLeaf->szLeaf || pLeaf->nn<pLeaf->szLeaf || iNext<4 ){
| | | | 250170 250171 250172 250173 250174 250175 250176 250177 250178 250179 250180 250181 250182 250183 250184 250185 250186 250187 250188 250189 250190 250191 250192 250193 250194 250195 250196 250197 250198 250199 250200 250201 250202 250203 250204 |
assert_nc( bDetailNone==0 || pLeaf->nn==4 );
if( bDetailNone==0 ) fts5DataWrite(p, iRowid, aEmpty, sizeof(aEmpty));
fts5DataRelease(pLeaf);
pLeaf = 0;
}else if( bDetailNone ){
break;
}else if( iNext>=pLeaf->szLeaf || pLeaf->nn<pLeaf->szLeaf || iNext<4 ){
FTS5_CORRUPT_ROWID(p, iRowid);
break;
}else{
int nShift = iNext - 4;
int nPg;
int nIdx = 0;
u8 *aIdx = 0;
/* Unless the current page footer is 0 bytes in size (in which case
** the new page footer will be as well), allocate and populate a
** buffer containing the new page footer. Set stack variables aIdx
** and nIdx accordingly. */
if( pLeaf->nn>pLeaf->szLeaf ){
int iFirst = 0;
int i1 = pLeaf->szLeaf;
int i2 = 0;
i1 += fts5GetVarint32(&aPg[i1], iFirst);
if( iFirst<iNext ){
FTS5_CORRUPT_ROWID(p, iRowid);
break;
}
aIdx = sqlite3Fts5MallocZero(&p->rc, (pLeaf->nn-pLeaf->szLeaf)+2);
if( aIdx==0 ) break;
i2 = sqlite3Fts5PutVarint(aIdx, iFirst-nShift);
if( i1<pLeaf->nn ){
memcpy(&aIdx[i2], &aPg[i1], pLeaf->nn-i1);
|
| ︙ | ︙ | |||
249536 249537 249538 249539 249540 249541 249542 |
}
iKeyOff += fts5GetVarint32(&aPg[iKeyOff], nSuffix);
nPrefix = MIN(nPrefix, nPrefix2);
nSuffix = (nPrefix2 + nSuffix2) - nPrefix;
if( (iKeyOff+nSuffix)>iPgIdx || (iNextOff+nSuffix2)>iPgIdx ){
| | | | 250413 250414 250415 250416 250417 250418 250419 250420 250421 250422 250423 250424 250425 250426 250427 250428 250429 250430 250431 250432 250433 250434 |
}
iKeyOff += fts5GetVarint32(&aPg[iKeyOff], nSuffix);
nPrefix = MIN(nPrefix, nPrefix2);
nSuffix = (nPrefix2 + nSuffix2) - nPrefix;
if( (iKeyOff+nSuffix)>iPgIdx || (iNextOff+nSuffix2)>iPgIdx ){
FTS5_CORRUPT_IDX(p);
}else{
if( iKey!=1 ){
iOff += sqlite3Fts5PutVarint(&aPg[iOff], nPrefix);
}
iOff += sqlite3Fts5PutVarint(&aPg[iOff], nSuffix);
if( nPrefix2>pSeg->term.n ){
FTS5_CORRUPT_IDX(p);
}else if( nPrefix2>nPrefix ){
memcpy(&aPg[iOff], &pSeg->term.p[nPrefix], nPrefix2-nPrefix);
iOff += (nPrefix2-nPrefix);
}
memmove(&aPg[iOff], &aPg[iNextOff], nSuffix2);
iOff += nSuffix2;
iNextOff += nSuffix2;
|
| ︙ | ︙ | |||
249967 249968 249969 249970 249971 249972 249973 |
fts5StructureRef(pStruct);
return pStruct;
}
assert( pStruct->aLevel[i].nMerge<=nThis );
}
nByte += (((i64)pStruct->nLevel)+1) * sizeof(Fts5StructureLevel);
| | | 250844 250845 250846 250847 250848 250849 250850 250851 250852 250853 250854 250855 250856 250857 250858 |
fts5StructureRef(pStruct);
return pStruct;
}
assert( pStruct->aLevel[i].nMerge<=nThis );
}
nByte += (((i64)pStruct->nLevel)+1) * sizeof(Fts5StructureLevel);
assert( nByte==(i64)SZ_FTS5STRUCTURE(pStruct->nLevel+2) );
pNew = (Fts5Structure*)sqlite3Fts5MallocZero(&p->rc, nByte);
if( pNew ){
Fts5StructureLevel *pLvl;
nByte = nSeg * sizeof(Fts5StructureSegment);
pNew->nLevel = MIN(pStruct->nLevel+1, FTS5_MAX_LEVEL);
pNew->nRef = 1;
|
| ︙ | ︙ | |||
250336 250337 250338 250339 250340 250341 250342 |
nTmp += pSave->iter.nPoslist + 10;
nMerge++;
fts5PrefixMergerInsertByPosition(&pHead, pSave);
pSave = pNext;
}
if( pHead==0 || pHead->pNext==0 ){
| | | 251213 251214 251215 251216 251217 251218 251219 251220 251221 251222 251223 251224 251225 251226 251227 |
nTmp += pSave->iter.nPoslist + 10;
nMerge++;
fts5PrefixMergerInsertByPosition(&pHead, pSave);
pSave = pNext;
}
if( pHead==0 || pHead->pNext==0 ){
FTS5_CORRUPT_IDX(p);
break;
}
/* See the earlier comment in this function for an explanation of why
** corrupt input position lists might cause the output to consume
** at most nMerge*10 bytes of unexpected space. */
if( sqlite3Fts5BufferSize(&p->rc, &tmp, nTmp+nMerge*10) ){
|
| ︙ | ︙ | |||
250373 250374 250375 250376 250377 250378 250379 |
}
nTail = pHead->iter.nPoslist - pHead->iOff;
/* WRITEPOSLISTSIZE */
assert_nc( tmp.n+nTail<=nTmp );
assert( tmp.n+nTail<=nTmp+nMerge*10 );
if( tmp.n+nTail>nTmp-FTS5_DATA_ZERO_PADDING ){
| | | 251250 251251 251252 251253 251254 251255 251256 251257 251258 251259 251260 251261 251262 251263 251264 |
}
nTail = pHead->iter.nPoslist - pHead->iOff;
/* WRITEPOSLISTSIZE */
assert_nc( tmp.n+nTail<=nTmp );
assert( tmp.n+nTail<=nTmp+nMerge*10 );
if( tmp.n+nTail>nTmp-FTS5_DATA_ZERO_PADDING ){
if( p->rc==SQLITE_OK ) FTS5_CORRUPT_IDX(p);
break;
}
fts5BufferSafeAppendVarint(&out, (tmp.n+nTail) * 2);
fts5BufferSafeAppendBlob(&out, tmp.p, tmp.n);
if( nTail>0 ){
fts5BufferSafeAppendBlob(&out, &pHead->aPos[pHead->iOff], nTail);
}
|
| ︙ | ︙ | |||
252406 252407 252408 252409 252410 252411 252412 252413 252414 252415 252416 252417 252418 | return 0; } /* ** This function is also purely an internal test. It does not contribute to ** FTS functionality, or even the integrity-check, in any way. */ static void fts5TestTerm( Fts5Index *p, Fts5Buffer *pPrev, /* Previous term */ const char *z, int n, /* Possibly new term to test */ u64 expected, | > > > | > > > | > > | 253283 253284 253285 253286 253287 253288 253289 253290 253291 253292 253293 253294 253295 253296 253297 253298 253299 253300 253301 253302 253303 253304 253305 253306 253307 253308 253309 253310 253311 253312 253313 253314 253315 253316 253317 |
return 0;
}
/*
** This function is also purely an internal test. It does not contribute to
** FTS functionality, or even the integrity-check, in any way.
**
** This function sets output variable (*pbFail) to true if the test fails. Or
** leaves it unchanged if the test succeeds.
*/
static void fts5TestTerm(
Fts5Index *p,
Fts5Buffer *pPrev, /* Previous term */
const char *z, int n, /* Possibly new term to test */
u64 expected,
u64 *pCksum,
int *pbFail
){
int rc = p->rc;
if( pPrev->n==0 ){
fts5BufferSet(&rc, pPrev, n, (const u8*)z);
}else
if( *pbFail==0
&& rc==SQLITE_OK
&& (pPrev->n!=n || memcmp(pPrev->p, z, n))
&& (p->pHash==0 || p->pHash->nEntry==0)
){
u64 cksum3 = *pCksum;
const char *zTerm = (const char*)&pPrev->p[1]; /* term sans prefix-byte */
int nTerm = pPrev->n-1; /* Size of zTerm in bytes */
int iIdx = (pPrev->p[0] - FTS5_MAIN_PREFIX);
int flags = (iIdx==0 ? 0 : FTS5INDEX_QUERY_PREFIX);
u64 ck1 = 0;
u64 ck2 = 0;
|
| ︙ | ︙ | |||
252468 252469 252470 252471 252472 252473 252474 |
}
}
cksum3 ^= ck1;
fts5BufferSet(&rc, pPrev, n, (const u8*)z);
if( rc==SQLITE_OK && cksum3!=expected ){
| | | | 253353 253354 253355 253356 253357 253358 253359 253360 253361 253362 253363 253364 253365 253366 253367 253368 253369 253370 253371 253372 253373 253374 253375 253376 |
}
}
cksum3 ^= ck1;
fts5BufferSet(&rc, pPrev, n, (const u8*)z);
if( rc==SQLITE_OK && cksum3!=expected ){
*pbFail = 1;
}
*pCksum = cksum3;
}
p->rc = rc;
}
#else
# define fts5TestDlidxReverse(x,y,z)
# define fts5TestTerm(t,u,v,w,x,y,z)
#endif
/*
** Check that:
**
** 1) All leaves of pSeg between iFirst and iLast (inclusive) exist and
** contain zero terms.
|
| ︙ | ︙ | |||
252502 252503 252504 252505 252506 252507 252508 |
int i;
/* Now check that the iter.nEmpty leaves following the current leaf
** (a) exist and (b) contain no terms. */
for(i=iFirst; p->rc==SQLITE_OK && i<=iLast; i++){
Fts5Data *pLeaf = fts5DataRead(p, FTS5_SEGMENT_ROWID(pSeg->iSegid, i));
if( pLeaf ){
| | | > > > | | | | | | 253387 253388 253389 253390 253391 253392 253393 253394 253395 253396 253397 253398 253399 253400 253401 253402 253403 253404 253405 253406 253407 253408 253409 253410 253411 253412 253413 253414 253415 253416 253417 253418 253419 253420 253421 253422 253423 253424 253425 253426 253427 253428 253429 253430 253431 253432 253433 253434 253435 253436 253437 253438 253439 253440 253441 253442 253443 253444 253445 253446 253447 253448 253449 253450 253451 |
int i;
/* Now check that the iter.nEmpty leaves following the current leaf
** (a) exist and (b) contain no terms. */
for(i=iFirst; p->rc==SQLITE_OK && i<=iLast; i++){
Fts5Data *pLeaf = fts5DataRead(p, FTS5_SEGMENT_ROWID(pSeg->iSegid, i));
if( pLeaf ){
if( !fts5LeafIsTermless(pLeaf)
|| (i>=iNoRowid && 0!=fts5LeafFirstRowidOff(pLeaf))
){
FTS5_CORRUPT_ROWID(p, FTS5_SEGMENT_ROWID(pSeg->iSegid, i));
}
}
fts5DataRelease(pLeaf);
}
}
static void fts5IntegrityCheckPgidx(Fts5Index *p, i64 iRowid, Fts5Data *pLeaf){
i64 iTermOff = 0;
int ii;
Fts5Buffer buf1 = {0,0,0};
Fts5Buffer buf2 = {0,0,0};
ii = pLeaf->szLeaf;
while( ii<pLeaf->nn && p->rc==SQLITE_OK ){
int res;
i64 iOff;
int nIncr;
ii += fts5GetVarint32(&pLeaf->p[ii], nIncr);
iTermOff += nIncr;
iOff = iTermOff;
if( iOff>=pLeaf->szLeaf ){
FTS5_CORRUPT_ROWID(p, iRowid);
}else if( iTermOff==nIncr ){
int nByte;
iOff += fts5GetVarint32(&pLeaf->p[iOff], nByte);
if( (iOff+nByte)>pLeaf->szLeaf ){
FTS5_CORRUPT_ROWID(p, iRowid);
}else{
fts5BufferSet(&p->rc, &buf1, nByte, &pLeaf->p[iOff]);
}
}else{
int nKeep, nByte;
iOff += fts5GetVarint32(&pLeaf->p[iOff], nKeep);
iOff += fts5GetVarint32(&pLeaf->p[iOff], nByte);
if( nKeep>buf1.n || (iOff+nByte)>pLeaf->szLeaf ){
FTS5_CORRUPT_ROWID(p, iRowid);
}else{
buf1.n = nKeep;
fts5BufferAppendBlob(&p->rc, &buf1, nByte, &pLeaf->p[iOff]);
}
if( p->rc==SQLITE_OK ){
res = fts5BufferCompare(&buf1, &buf2);
if( res<=0 ) FTS5_CORRUPT_ROWID(p, iRowid);
}
}
fts5BufferSet(&p->rc, &buf2, buf1.n, buf1.p);
}
fts5BufferFree(&buf1);
fts5BufferFree(&buf2);
|
| ︙ | ︙ | |||
252610 252611 252612 252613 252614 252615 252616 |
&& pLeaf->nn==pLeaf->szLeaf
&& pLeaf->nn==4
){
/* special case - the very first page in a segment keeps its %_idx
** entry even if all the terms are removed from it by secure-delete
** operations. */
}else{
| | | | | | 253498 253499 253500 253501 253502 253503 253504 253505 253506 253507 253508 253509 253510 253511 253512 253513 253514 253515 253516 253517 253518 253519 253520 253521 253522 253523 253524 253525 253526 253527 253528 253529 253530 253531 253532 |
&& pLeaf->nn==pLeaf->szLeaf
&& pLeaf->nn==4
){
/* special case - the very first page in a segment keeps its %_idx
** entry even if all the terms are removed from it by secure-delete
** operations. */
}else{
FTS5_CORRUPT_ROWID(p, iRow);
}
}else{
int iOff; /* Offset of first term on leaf */
int iRowidOff; /* Offset of first rowid on leaf */
int nTerm; /* Size of term on leaf in bytes */
int res; /* Comparison of term and split-key */
iOff = fts5LeafFirstTermOff(pLeaf);
iRowidOff = fts5LeafFirstRowidOff(pLeaf);
if( iRowidOff>=iOff || iOff>=pLeaf->szLeaf ){
FTS5_CORRUPT_ROWID(p, iRow);
}else{
iOff += fts5GetVarint32(&pLeaf->p[iOff], nTerm);
res = fts5Memcmp(&pLeaf->p[iOff], zIdxTerm, MIN(nTerm, nIdxTerm));
if( res==0 ) res = nTerm - nIdxTerm;
if( res<0 ) FTS5_CORRUPT_ROWID(p, iRow);
}
fts5IntegrityCheckPgidx(p, iRow, pLeaf);
}
fts5DataRelease(pLeaf);
if( p->rc ) break;
/* Now check that the iter.nEmpty leaves following the current leaf
** (a) exist and (b) contain no terms. */
fts5IndexIntegrityCheckEmpty(
|
| ︙ | ︙ | |||
252660 252661 252662 252663 252664 252665 252666 |
){
/* Check any rowid-less pages that occur before the current leaf. */
for(iPg=iPrevLeaf+1; iPg<fts5DlidxIterPgno(pDlidx); iPg++){
iKey = FTS5_SEGMENT_ROWID(iSegid, iPg);
pLeaf = fts5DataRead(p, iKey);
if( pLeaf ){
| | | | | 253548 253549 253550 253551 253552 253553 253554 253555 253556 253557 253558 253559 253560 253561 253562 253563 253564 253565 253566 253567 253568 253569 253570 253571 253572 253573 253574 253575 253576 253577 253578 253579 253580 253581 253582 |
){
/* Check any rowid-less pages that occur before the current leaf. */
for(iPg=iPrevLeaf+1; iPg<fts5DlidxIterPgno(pDlidx); iPg++){
iKey = FTS5_SEGMENT_ROWID(iSegid, iPg);
pLeaf = fts5DataRead(p, iKey);
if( pLeaf ){
if( fts5LeafFirstRowidOff(pLeaf)!=0 ) FTS5_CORRUPT_ROWID(p, iKey);
fts5DataRelease(pLeaf);
}
}
iPrevLeaf = fts5DlidxIterPgno(pDlidx);
/* Check that the leaf page indicated by the iterator really does
** contain the rowid suggested by the same. */
iKey = FTS5_SEGMENT_ROWID(iSegid, iPrevLeaf);
pLeaf = fts5DataRead(p, iKey);
if( pLeaf ){
i64 iRowid;
int iRowidOff = fts5LeafFirstRowidOff(pLeaf);
ASSERT_SZLEAF_OK(pLeaf);
if( iRowidOff>=pLeaf->szLeaf ){
FTS5_CORRUPT_ROWID(p, iKey);
}else if( bSecureDelete==0 || iRowidOff>0 ){
i64 iDlRowid = fts5DlidxIterRowid(pDlidx);
fts5GetVarint(&pLeaf->p[iRowidOff], (u64*)&iRowid);
if( iRowid<iDlRowid || (bSecureDelete==0 && iRowid!=iDlRowid) ){
FTS5_CORRUPT_ROWID(p, iKey);
}
}
fts5DataRelease(pLeaf);
}
}
iDlidxPrevLeaf = iPg;
|
| ︙ | ︙ | |||
252732 252733 252734 252735 252736 252737 252738 252739 252740 252741 252742 252743 252744 252745 |
Fts5Structure *pStruct; /* Index structure */
int iLvl, iSeg;
#ifdef SQLITE_DEBUG
/* Used by extra internal tests only run if NDEBUG is not defined */
u64 cksum3 = 0; /* Checksum based on contents of indexes */
Fts5Buffer term = {0,0,0}; /* Buffer used to hold most recent term */
#endif
const int flags = FTS5INDEX_QUERY_NOOUTPUT;
/* Load the FTS index structure */
pStruct = fts5StructureRead(p);
if( pStruct==0 ){
assert( p->rc!=SQLITE_OK );
| > | 253620 253621 253622 253623 253624 253625 253626 253627 253628 253629 253630 253631 253632 253633 253634 |
Fts5Structure *pStruct; /* Index structure */
int iLvl, iSeg;
#ifdef SQLITE_DEBUG
/* Used by extra internal tests only run if NDEBUG is not defined */
u64 cksum3 = 0; /* Checksum based on contents of indexes */
Fts5Buffer term = {0,0,0}; /* Buffer used to hold most recent term */
int bTestFail = 0;
#endif
const int flags = FTS5INDEX_QUERY_NOOUTPUT;
/* Load the FTS index structure */
pStruct = fts5StructureRead(p);
if( pStruct==0 ){
assert( p->rc!=SQLITE_OK );
|
| ︙ | ︙ | |||
252774 252775 252776 252777 252778 252779 252780 |
int n; /* Size of term in bytes */
i64 iPos = 0; /* Position read from poslist */
int iOff = 0; /* Offset within poslist */
i64 iRowid = fts5MultiIterRowid(pIter);
char *z = (char*)fts5MultiIterTerm(pIter, &n);
/* If this is a new term, query for it. Update cksum3 with the results. */
| | | | > > > > | < > > > > > > > > | 253663 253664 253665 253666 253667 253668 253669 253670 253671 253672 253673 253674 253675 253676 253677 253678 253679 253680 253681 253682 253683 253684 253685 253686 253687 253688 253689 253690 253691 253692 253693 253694 253695 253696 253697 253698 253699 253700 253701 253702 253703 253704 253705 253706 253707 253708 253709 253710 253711 253712 253713 253714 |
int n; /* Size of term in bytes */
i64 iPos = 0; /* Position read from poslist */
int iOff = 0; /* Offset within poslist */
i64 iRowid = fts5MultiIterRowid(pIter);
char *z = (char*)fts5MultiIterTerm(pIter, &n);
/* If this is a new term, query for it. Update cksum3 with the results. */
fts5TestTerm(p, &term, z, n, cksum2, &cksum3, &bTestFail);
if( p->rc ) break;
if( eDetail==FTS5_DETAIL_NONE ){
if( 0==fts5MultiIterIsEmpty(p, pIter) ){
cksum2 ^= sqlite3Fts5IndexEntryCksum(iRowid, 0, 0, -1, z, n);
}
}else{
poslist.n = 0;
fts5SegiterPoslist(p, &pIter->aSeg[pIter->aFirst[1].iFirst], 0, &poslist);
fts5BufferAppendBlob(&p->rc, &poslist, 4, (const u8*)"\0\0\0\0");
while( 0==sqlite3Fts5PoslistNext64(poslist.p, poslist.n, &iOff, &iPos) ){
int iCol = FTS5_POS2COLUMN(iPos);
int iTokOff = FTS5_POS2OFFSET(iPos);
cksum2 ^= sqlite3Fts5IndexEntryCksum(iRowid, iCol, iTokOff, -1, z, n);
}
}
}
fts5TestTerm(p, &term, 0, 0, cksum2, &cksum3, &bTestFail);
fts5MultiIterFree(pIter);
if( p->rc==SQLITE_OK && bUseCksum && cksum!=cksum2 ){
p->rc = FTS5_CORRUPT;
sqlite3Fts5ConfigErrmsg(p->pConfig,
"fts5: checksum mismatch for table \"%s\"", p->pConfig->zName
);
}
#ifdef SQLITE_DEBUG
/* In SQLITE_DEBUG builds, expensive extra checks were run as part of
** the integrity-check above. If no other errors were detected, but one
** of these tests failed, set the result to SQLITE_CORRUPT_VTAB here. */
if( p->rc==SQLITE_OK && bTestFail ){
p->rc = FTS5_CORRUPT;
}
fts5BufferFree(&term);
#endif
fts5StructureRelease(pStruct);
fts5BufferFree(&poslist);
return fts5IndexReturn(p);
}
/*************************************************************************
**************************************************************************
** Below this point is the implementation of the fts5_decode() scalar
|
| ︙ | ︙ | |||
257211 257212 257213 257214 257215 257216 257217 |
static void fts5SourceIdFunc(
sqlite3_context *pCtx, /* Function call context */
int nArg, /* Number of args */
sqlite3_value **apUnused /* Function arguments */
){
assert( nArg==0 );
UNUSED_PARAM2(nArg, apUnused);
| | | 258111 258112 258113 258114 258115 258116 258117 258118 258119 258120 258121 258122 258123 258124 258125 |
static void fts5SourceIdFunc(
sqlite3_context *pCtx, /* Function call context */
int nArg, /* Number of args */
sqlite3_value **apUnused /* Function arguments */
){
assert( nArg==0 );
UNUSED_PARAM2(nArg, apUnused);
sqlite3_result_text(pCtx, "fts5: 2025-07-15 19:00:01 9f184f8dfa5ef6d57e10376adc30e0060ceda07d283c23dfdfe3dbdd6608f839", -1, SQLITE_TRANSIENT);
}
/*
** Implementation of fts5_locale(LOCALE, TEXT) function.
**
** If parameter LOCALE is NULL, or a zero-length string, then a copy of
** TEXT is returned. Otherwise, both LOCALE and TEXT are interpreted as
|
| ︙ | ︙ | |||
257334 257335 257336 257337 257338 257339 257340 |
zSchema, zTabname);
rc = (*pzErr) ? SQLITE_OK : SQLITE_NOMEM;
}else{
*pzErr = sqlite3_mprintf("unable to validate the inverted index for"
" FTS5 table %s.%s: %s",
zSchema, zTabname, sqlite3_errstr(rc));
}
| | > | | 258234 258235 258236 258237 258238 258239 258240 258241 258242 258243 258244 258245 258246 258247 258248 258249 258250 |
zSchema, zTabname);
rc = (*pzErr) ? SQLITE_OK : SQLITE_NOMEM;
}else{
*pzErr = sqlite3_mprintf("unable to validate the inverted index for"
" FTS5 table %s.%s: %s",
zSchema, zTabname, sqlite3_errstr(rc));
}
}else if( (rc&0xff)==SQLITE_CORRUPT ){
rc = SQLITE_OK;
}
sqlite3Fts5IndexCloseReader(pTab->p.pIndex);
pTab->p.pConfig->pzErrmsg = 0;
return rc;
}
static int fts5Init(sqlite3 *db){
|
| ︙ | ︙ | |||
258026 258027 258028 258029 258030 258031 258032 258033 258034 258035 258036 258037 258038 258039 258040 258041 258042 258043 258044 258045 258046 258047 258048 |
}
ctx.pStorage = p;
ctx.iCol = -1;
for(iCol=1; rc==SQLITE_OK && iCol<=pConfig->nCol; iCol++){
if( pConfig->abUnindexed[iCol-1]==0 ){
sqlite3_value *pVal = 0;
const char *pText = 0;
int nText = 0;
const char *pLoc = 0;
int nLoc = 0;
assert( pSeek==0 || apVal==0 );
assert( pSeek!=0 || apVal!=0 );
if( pSeek ){
pVal = sqlite3_column_value(pSeek, iCol);
}else{
pVal = apVal[iCol-1];
}
if( pConfig->bLocale && sqlite3Fts5IsLocaleValue(pConfig, pVal) ){
rc = sqlite3Fts5DecodeLocaleValue(pVal, &pText, &nText, &pLoc, &nLoc);
}else{
| > > > > > > > > > > > | | | | | > > | 258927 258928 258929 258930 258931 258932 258933 258934 258935 258936 258937 258938 258939 258940 258941 258942 258943 258944 258945 258946 258947 258948 258949 258950 258951 258952 258953 258954 258955 258956 258957 258958 258959 258960 258961 258962 258963 258964 258965 258966 258967 258968 258969 258970 258971 258972 258973 258974 258975 258976 258977 258978 258979 258980 258981 258982 258983 258984 258985 258986 258987 258988 258989 |
}
ctx.pStorage = p;
ctx.iCol = -1;
for(iCol=1; rc==SQLITE_OK && iCol<=pConfig->nCol; iCol++){
if( pConfig->abUnindexed[iCol-1]==0 ){
sqlite3_value *pVal = 0;
sqlite3_value *pFree = 0;
const char *pText = 0;
int nText = 0;
const char *pLoc = 0;
int nLoc = 0;
assert( pSeek==0 || apVal==0 );
assert( pSeek!=0 || apVal!=0 );
if( pSeek ){
pVal = sqlite3_column_value(pSeek, iCol);
}else{
pVal = apVal[iCol-1];
}
if( pConfig->bLocale && sqlite3Fts5IsLocaleValue(pConfig, pVal) ){
rc = sqlite3Fts5DecodeLocaleValue(pVal, &pText, &nText, &pLoc, &nLoc);
}else{
if( sqlite3_value_type(pVal)!=SQLITE_TEXT ){
/* Make a copy of the value to work with. This is because the call
** to sqlite3_value_text() below forces the type of the value to
** SQLITE_TEXT, and we may need to use it again later. */
pFree = pVal = sqlite3_value_dup(pVal);
if( pVal==0 ){
rc = SQLITE_NOMEM;
}
}
if( rc==SQLITE_OK ){
pText = (const char*)sqlite3_value_text(pVal);
nText = sqlite3_value_bytes(pVal);
if( pConfig->bLocale && pSeek ){
pLoc = (const char*)sqlite3_column_text(pSeek, iCol+pConfig->nCol);
nLoc = sqlite3_column_bytes(pSeek, iCol + pConfig->nCol);
}
}
}
if( rc==SQLITE_OK ){
sqlite3Fts5SetLocale(pConfig, pLoc, nLoc);
ctx.szCol = 0;
rc = sqlite3Fts5Tokenize(pConfig, FTS5_TOKENIZE_DOCUMENT,
pText, nText, (void*)&ctx, fts5StorageInsertCallback
);
p->aTotalSize[iCol-1] -= (i64)ctx.szCol;
if( rc==SQLITE_OK && p->aTotalSize[iCol-1]<0 ){
rc = FTS5_CORRUPT;
}
sqlite3Fts5ClearLocale(pConfig);
}
sqlite3_value_free(pFree);
}
}
if( rc==SQLITE_OK && p->nTotalRow<1 ){
rc = FTS5_CORRUPT;
}else{
p->nTotalRow--;
}
|
| ︙ | ︙ |
Changes to extsrc/sqlite3.h.
| ︙ | ︙ | |||
142 143 144 145 146 147 148 | ** been edited in any way since it was last checked in, then the last ** four hexadecimal digits of the hash may be modified. ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ | | | | | | | | 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 | ** been edited in any way since it was last checked in, then the last ** four hexadecimal digits of the hash may be modified. ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ #define SQLITE_VERSION "3.51.0" #define SQLITE_VERSION_NUMBER 3051000 #define SQLITE_SOURCE_ID "2025-07-15 19:00:01 9f184f8dfa5ef6d57e10376adc30e0060ceda07d283c23dfdfe3dbdd6608f839" /* ** CAPI3REF: Run-Time Library Version Numbers ** KEYWORDS: sqlite3_version sqlite3_sourceid ** ** These interfaces provide the same information as the [SQLITE_VERSION], ** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros ** but are associated with the library instead of the header file. ^(Cautious ** programmers might include assert() statements in their application to ** verify that values returned by these interfaces match the macros in ** the header, and thus ensure that the application is ** compiled with matching library and header files. ** ** <blockquote><pre> ** assert( sqlite3_libversion_number()==SQLITE_VERSION_NUMBER ); ** assert( strncmp(sqlite3_sourceid(),SQLITE_SOURCE_ID,80)==0 ); ** assert( strcmp(sqlite3_libversion(),SQLITE_VERSION)==0 ); ** </pre></blockquote>)^ ** ** ^The sqlite3_version[] string constant contains the text of the ** [SQLITE_VERSION] macro. ^The sqlite3_libversion() function returns a ** pointer to the sqlite3_version[] string constant. The sqlite3_libversion() ** function is provided for use in DLLs since DLL users usually do not have ** direct access to string constants within the DLL. ^The ** sqlite3_libversion_number() function returns an integer equal to ** [SQLITE_VERSION_NUMBER]. ^(The sqlite3_sourceid() function returns ** a pointer to a string constant whose value is the same as the ** [SQLITE_SOURCE_ID] C preprocessor macro. Except if SQLite is built ** using an edited copy of [the amalgamation], then the last four characters |
| ︙ | ︙ | |||
366 367 368 369 370 371 372 | ** ** The sqlite3_exec() interface is a convenience wrapper around ** [sqlite3_prepare_v2()], [sqlite3_step()], and [sqlite3_finalize()], ** that allows an application to run multiple statements of SQL ** without having to use a lot of C code. ** ** ^The sqlite3_exec() interface runs zero or more UTF-8 encoded, | | | 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 | ** ** The sqlite3_exec() interface is a convenience wrapper around ** [sqlite3_prepare_v2()], [sqlite3_step()], and [sqlite3_finalize()], ** that allows an application to run multiple statements of SQL ** without having to use a lot of C code. ** ** ^The sqlite3_exec() interface runs zero or more UTF-8 encoded, ** semicolon-separated SQL statements passed into its 2nd argument, ** in the context of the [database connection] passed in as its 1st ** argument. ^If the callback function of the 3rd argument to ** sqlite3_exec() is not NULL, then it is invoked for each result row ** coming out of the evaluated SQL statements. ^The 4th argument to ** sqlite3_exec() is relayed through to the 1st argument of each ** callback invocation. ^If the callback pointer to sqlite3_exec() ** is NULL, then no callback is ever invoked and result rows are |
| ︙ | ︙ | |||
399 400 401 402 403 404 405 | ** ^The 2nd argument to the sqlite3_exec() callback function is the ** number of columns in the result. ^The 3rd argument to the sqlite3_exec() ** callback is an array of pointers to strings obtained as if from ** [sqlite3_column_text()], one for each column. ^If an element of a ** result row is NULL then the corresponding string pointer for the ** sqlite3_exec() callback is a NULL pointer. ^The 4th argument to the ** sqlite3_exec() callback is an array of pointers to strings where each | | | 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 | ** ^The 2nd argument to the sqlite3_exec() callback function is the ** number of columns in the result. ^The 3rd argument to the sqlite3_exec() ** callback is an array of pointers to strings obtained as if from ** [sqlite3_column_text()], one for each column. ^If an element of a ** result row is NULL then the corresponding string pointer for the ** sqlite3_exec() callback is a NULL pointer. ^The 4th argument to the ** sqlite3_exec() callback is an array of pointers to strings where each ** entry represents the name of a corresponding result column as obtained ** from [sqlite3_column_name()]. ** ** ^If the 2nd parameter to sqlite3_exec() is a NULL pointer, a pointer ** to an empty string, or a pointer that contains only whitespace and/or ** SQL comments, then no SQL statements are evaluated and the database ** is not changed. ** |
| ︙ | ︙ | |||
585 586 587 588 589 590 591 | ** though future versions of SQLite might change so that an error is ** raised if any of the disallowed bits are passed into sqlite3_open_v2(). ** Applications should not depend on the historical behavior. ** ** Note in particular that passing the SQLITE_OPEN_EXCLUSIVE flag into ** [sqlite3_open_v2()] does *not* cause the underlying database file ** to be opened using O_EXCL. Passing SQLITE_OPEN_EXCLUSIVE into | | | 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 | ** though future versions of SQLite might change so that an error is ** raised if any of the disallowed bits are passed into sqlite3_open_v2(). ** Applications should not depend on the historical behavior. ** ** Note in particular that passing the SQLITE_OPEN_EXCLUSIVE flag into ** [sqlite3_open_v2()] does *not* cause the underlying database file ** to be opened using O_EXCL. Passing SQLITE_OPEN_EXCLUSIVE into ** [sqlite3_open_v2()] has historically been a no-op and might become an ** error in future versions of SQLite. */ #define SQLITE_OPEN_READONLY 0x00000001 /* Ok for sqlite3_open_v2() */ #define SQLITE_OPEN_READWRITE 0x00000002 /* Ok for sqlite3_open_v2() */ #define SQLITE_OPEN_CREATE 0x00000004 /* Ok for sqlite3_open_v2() */ #define SQLITE_OPEN_DELETEONCLOSE 0x00000008 /* VFS only */ #define SQLITE_OPEN_EXCLUSIVE 0x00000010 /* VFS only */ |
| ︙ | ︙ | |||
679 680 681 682 683 684 685 | /* ** CAPI3REF: File Locking Levels ** ** SQLite uses one of these integer values as the second ** argument to calls it makes to the xLock() and xUnlock() methods ** of an [sqlite3_io_methods] object. These values are ordered from | | | 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 | /* ** CAPI3REF: File Locking Levels ** ** SQLite uses one of these integer values as the second ** argument to calls it makes to the xLock() and xUnlock() methods ** of an [sqlite3_io_methods] object. These values are ordered from ** least restrictive to most restrictive. ** ** The argument to xLock() is always SHARED or higher. The argument to ** xUnlock is either SHARED or NONE. */ #define SQLITE_LOCK_NONE 0 /* xUnlock() only */ #define SQLITE_LOCK_SHARED 1 /* xLock() or xUnlock() */ #define SQLITE_LOCK_RESERVED 2 /* xLock() only */ |
| ︙ | ︙ | |||
995 996 997 998 999 1000 1001 | ** ^The [SQLITE_FCNTL_OVERWRITE] opcode is invoked by SQLite after opening ** a write transaction to indicate that, unless it is rolled back for some ** reason, the entire database file will be overwritten by the current ** transaction. This is used by VACUUM operations. ** ** <li>[[SQLITE_FCNTL_VFSNAME]] ** ^The [SQLITE_FCNTL_VFSNAME] opcode can be used to obtain the names of | | | | 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 | ** ^The [SQLITE_FCNTL_OVERWRITE] opcode is invoked by SQLite after opening ** a write transaction to indicate that, unless it is rolled back for some ** reason, the entire database file will be overwritten by the current ** transaction. This is used by VACUUM operations. ** ** <li>[[SQLITE_FCNTL_VFSNAME]] ** ^The [SQLITE_FCNTL_VFSNAME] opcode can be used to obtain the names of ** all [VFSes] in the VFS stack. The names of all VFS shims and the ** final bottom-level VFS are written into memory obtained from ** [sqlite3_malloc()] and the result is stored in the char* variable ** that the fourth parameter of [sqlite3_file_control()] points to. ** The caller is responsible for freeing the memory when done. As with ** all file-control actions, there is no guarantee that this will actually ** do anything. Callers should initialize the char* variable to a NULL ** pointer in case this file-control is not implemented. This file-control ** is intended for diagnostic use only. ** ** <li>[[SQLITE_FCNTL_VFS_POINTER]] ** ^The [SQLITE_FCNTL_VFS_POINTER] opcode finds a pointer to the top-level ** [VFSes] currently in use. ^(The argument X in ** sqlite3_file_control(db,SQLITE_FCNTL_VFS_POINTER,X) must be ** of type "[sqlite3_vfs] **". This opcode will set *X ** to a pointer to the top-level VFS.)^ ** ^When there are multiple VFS shims in the stack, this opcode finds the ** upper-most shim only. ** ** <li>[[SQLITE_FCNTL_PRAGMA]] ** ^Whenever a [PRAGMA] statement is parsed, an [SQLITE_FCNTL_PRAGMA] ** file control is sent to the open [sqlite3_file] object corresponding |
| ︙ | ︙ | |||
1199 1200 1201 1202 1203 1204 1205 | ** in wal mode after the client has finished copying pages from the wal ** file to the database file, but before the *-shm file is updated to ** record the fact that the pages have been checkpointed. ** ** <li>[[SQLITE_FCNTL_EXTERNAL_READER]] ** The EXPERIMENTAL [SQLITE_FCNTL_EXTERNAL_READER] opcode is used to detect ** whether or not there is a database client in another process with a wal-mode | | | 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 | ** in wal mode after the client has finished copying pages from the wal ** file to the database file, but before the *-shm file is updated to ** record the fact that the pages have been checkpointed. ** ** <li>[[SQLITE_FCNTL_EXTERNAL_READER]] ** The EXPERIMENTAL [SQLITE_FCNTL_EXTERNAL_READER] opcode is used to detect ** whether or not there is a database client in another process with a wal-mode ** transaction open on the database or not. It is only available on unix. The ** (void*) argument passed with this file-control should be a pointer to a ** value of type (int). The integer value is set to 1 if the database is a wal ** mode database and there exists at least one client in another process that ** currently has an SQL transaction open on the database. It is set to 0 if ** the database is not a wal-mode db, or if there is no such connection in any ** other process. This opcode cannot be used to detect transactions opened ** by clients within the current process, only within other processes. |
| ︙ | ︙ | |||
1624 1625 1626 1627 1628 1629 1630 | ** the library (perhaps it is unable to allocate a needed resource such ** as a mutex) it returns an [error code] other than [SQLITE_OK]. ** ** ^The sqlite3_initialize() routine is called internally by many other ** SQLite interfaces so that an application usually does not need to ** invoke sqlite3_initialize() directly. For example, [sqlite3_open()] ** calls sqlite3_initialize() so the SQLite library will be automatically | | | 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 | ** the library (perhaps it is unable to allocate a needed resource such ** as a mutex) it returns an [error code] other than [SQLITE_OK]. ** ** ^The sqlite3_initialize() routine is called internally by many other ** SQLite interfaces so that an application usually does not need to ** invoke sqlite3_initialize() directly. For example, [sqlite3_open()] ** calls sqlite3_initialize() so the SQLite library will be automatically ** initialized when [sqlite3_open()] is called if it has not been initialized ** already. ^However, if SQLite is compiled with the [SQLITE_OMIT_AUTOINIT] ** compile-time option, then the automatic calls to sqlite3_initialize() ** are omitted and the application must call sqlite3_initialize() directly ** prior to using any other SQLite interface. For maximum portability, ** it is recommended that applications always invoke sqlite3_initialize() ** directly prior to using any other SQLite interface. Future releases ** of SQLite may require this. In other words, the behavior exhibited |
| ︙ | ︙ | |||
1881 1882 1883 1884 1885 1886 1887 | ** ** [[SQLITE_CONFIG_GETMALLOC]] <dt>SQLITE_CONFIG_GETMALLOC</dt> ** <dd> ^(The SQLITE_CONFIG_GETMALLOC option takes a single argument which ** is a pointer to an instance of the [sqlite3_mem_methods] structure. ** The [sqlite3_mem_methods] ** structure is filled with the currently defined memory allocation routines.)^ ** This option can be used to overload the default memory allocation | | | | | | 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 | ** ** [[SQLITE_CONFIG_GETMALLOC]] <dt>SQLITE_CONFIG_GETMALLOC</dt> ** <dd> ^(The SQLITE_CONFIG_GETMALLOC option takes a single argument which ** is a pointer to an instance of the [sqlite3_mem_methods] structure. ** The [sqlite3_mem_methods] ** structure is filled with the currently defined memory allocation routines.)^ ** This option can be used to overload the default memory allocation ** routines with a wrapper that simulates memory allocation failure or ** tracks memory usage, for example. </dd> ** ** [[SQLITE_CONFIG_SMALL_MALLOC]] <dt>SQLITE_CONFIG_SMALL_MALLOC</dt> ** <dd> ^The SQLITE_CONFIG_SMALL_MALLOC option takes a single argument of ** type int, interpreted as a boolean, which if true provides a hint to ** SQLite that it should avoid large memory allocations if possible. ** SQLite will run faster if it is free to make large memory allocations, ** but some applications might prefer to run slower in exchange for ** guarantees about memory fragmentation that are possible if large ** allocations are avoided. This hint is normally off. ** </dd> ** ** [[SQLITE_CONFIG_MEMSTATUS]] <dt>SQLITE_CONFIG_MEMSTATUS</dt> ** <dd> ^The SQLITE_CONFIG_MEMSTATUS option takes a single argument of type int, ** interpreted as a boolean, which enables or disables the collection of ** memory allocation statistics. ^(When memory allocation statistics are ** disabled, the following SQLite interfaces become non-operational: ** <ul> ** <li> [sqlite3_hard_heap_limit64()] ** <li> [sqlite3_memory_used()] ** <li> [sqlite3_memory_highwater()] |
| ︙ | ︙ | |||
1940 1941 1942 1943 1944 1945 1946 | ** ^When pMem is not NULL, SQLite will strive to use the memory provided ** to satisfy page cache needs, falling back to [sqlite3_malloc()] if ** a page cache line is larger than sz bytes or if all of the pMem buffer ** is exhausted. ** ^If pMem is NULL and N is non-zero, then each database connection ** does an initial bulk allocation for page cache memory ** from [sqlite3_malloc()] sufficient for N cache lines if N is positive or | | | 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 | ** ^When pMem is not NULL, SQLite will strive to use the memory provided ** to satisfy page cache needs, falling back to [sqlite3_malloc()] if ** a page cache line is larger than sz bytes or if all of the pMem buffer ** is exhausted. ** ^If pMem is NULL and N is non-zero, then each database connection ** does an initial bulk allocation for page cache memory ** from [sqlite3_malloc()] sufficient for N cache lines if N is positive or ** of -1024*N bytes if N is negative. ^If additional ** page cache memory is needed beyond what is provided by the initial ** allocation, then SQLite goes to [sqlite3_malloc()] separately for each ** additional cache line. </dd> ** ** [[SQLITE_CONFIG_HEAP]] <dt>SQLITE_CONFIG_HEAP</dt> ** <dd> ^The SQLITE_CONFIG_HEAP option specifies a static memory buffer ** that SQLite will use for all of its dynamic memory allocation needs |
| ︙ | ︙ | |||
1969 1970 1971 1972 1973 1974 1975 | ** The minimum allocation size is capped at 2**12. Reasonable values ** for the minimum allocation size are 2**5 through 2**8.</dd> ** ** [[SQLITE_CONFIG_MUTEX]] <dt>SQLITE_CONFIG_MUTEX</dt> ** <dd> ^(The SQLITE_CONFIG_MUTEX option takes a single argument which is a ** pointer to an instance of the [sqlite3_mutex_methods] structure. ** The argument specifies alternative low-level mutex routines to be used | | | 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 | ** The minimum allocation size is capped at 2**12. Reasonable values ** for the minimum allocation size are 2**5 through 2**8.</dd> ** ** [[SQLITE_CONFIG_MUTEX]] <dt>SQLITE_CONFIG_MUTEX</dt> ** <dd> ^(The SQLITE_CONFIG_MUTEX option takes a single argument which is a ** pointer to an instance of the [sqlite3_mutex_methods] structure. ** The argument specifies alternative low-level mutex routines to be used ** in place of the mutex routines built into SQLite.)^ ^SQLite makes a copy of ** the content of the [sqlite3_mutex_methods] structure before the call to ** [sqlite3_config()] returns. ^If SQLite is compiled with ** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then ** the entire mutexing subsystem is omitted from the build and hence calls to ** [sqlite3_config()] with the SQLITE_CONFIG_MUTEX configuration option will ** return [SQLITE_ERROR].</dd> ** |
| ︙ | ︙ | |||
2011 2012 2013 2014 2015 2016 2017 | ** <dd> ^(The SQLITE_CONFIG_PCACHE2 option takes a single argument which is ** a pointer to an [sqlite3_pcache_methods2] object. This object specifies ** the interface to a custom page cache implementation.)^ ** ^SQLite makes a copy of the [sqlite3_pcache_methods2] object.</dd> ** ** [[SQLITE_CONFIG_GETPCACHE2]] <dt>SQLITE_CONFIG_GETPCACHE2</dt> ** <dd> ^(The SQLITE_CONFIG_GETPCACHE2 option takes a single argument which | | | | 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 | ** <dd> ^(The SQLITE_CONFIG_PCACHE2 option takes a single argument which is ** a pointer to an [sqlite3_pcache_methods2] object. This object specifies ** the interface to a custom page cache implementation.)^ ** ^SQLite makes a copy of the [sqlite3_pcache_methods2] object.</dd> ** ** [[SQLITE_CONFIG_GETPCACHE2]] <dt>SQLITE_CONFIG_GETPCACHE2</dt> ** <dd> ^(The SQLITE_CONFIG_GETPCACHE2 option takes a single argument which ** is a pointer to an [sqlite3_pcache_methods2] object. SQLite copies off ** the current page cache implementation into that object.)^ </dd> ** ** [[SQLITE_CONFIG_LOG]] <dt>SQLITE_CONFIG_LOG</dt> ** <dd> The SQLITE_CONFIG_LOG option is used to configure the SQLite ** global [error log]. ** (^The SQLITE_CONFIG_LOG option takes two arguments: a pointer to a ** function with a call signature of void(*)(void*,int,const char*), ** and a pointer to void. ^If the function pointer is not NULL, it is ** invoked by [sqlite3_log()] to process each logging event. ^If the ** function pointer is NULL, the [sqlite3_log()] interface becomes a no-op. ** ^The void pointer that is the second argument to SQLITE_CONFIG_LOG is ** passed through as the first parameter to the application-defined logger ** function whenever that function is invoked. ^The second parameter to ** the logger function is a copy of the first parameter to the corresponding ** [sqlite3_log()] call and is intended to be a [result code] or an ** [extended result code]. ^The third parameter passed to the logger is ** a 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> ** ** [[SQLITE_CONFIG_URI]] <dt>SQLITE_CONFIG_URI ** <dd>^(The SQLITE_CONFIG_URI option takes a single argument of type int. |
| ︙ | ︙ | |||
2219 2220 2221 2222 2223 2224 2225 | /* ** CAPI3REF: Database Connection Configuration Options ** ** These constants are the available integer configuration options that ** can be passed as the second parameter to the [sqlite3_db_config()] interface. ** | | | 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 | /* ** CAPI3REF: Database Connection Configuration Options ** ** These constants are the available integer configuration options that ** can be passed as the second parameter to the [sqlite3_db_config()] interface. ** ** The [sqlite3_db_config()] interface is a var-args function. It takes a ** variable number of parameters, though always at least two. The number of ** parameters passed into sqlite3_db_config() depends on which of these ** constants is given as the second parameter. This documentation page ** refers to parameters beyond the second as "arguments". Thus, when this ** page says "the N-th argument" it means "the N-th parameter past the ** configuration option" or "the (N+2)-th parameter to sqlite3_db_config()". ** |
| ︙ | ︙ | |||
2353 2354 2355 2356 2357 2358 2359 | ** interface independently of the [load_extension()] SQL function. ** The [sqlite3_enable_load_extension()] API enables or disables both the ** C-API [sqlite3_load_extension()] and the SQL function [load_extension()]. ** There must be two additional arguments. ** When the first argument to this interface is 1, then only the C-API is ** enabled and the SQL function remains disabled. If the first argument to ** this interface is 0, then both the C-API and the SQL function are disabled. | | | | 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 | ** interface independently of the [load_extension()] SQL function. ** The [sqlite3_enable_load_extension()] API enables or disables both the ** C-API [sqlite3_load_extension()] and the SQL function [load_extension()]. ** There must be two additional arguments. ** When the first argument to this interface is 1, then only the C-API is ** enabled and the SQL function remains disabled. If the first argument to ** this interface is 0, then both the C-API and the SQL function are disabled. ** If the first argument is -1, then no changes are made to the state of either ** the C-API or the SQL function. ** The second parameter is a pointer to an integer into which ** is written 0 or 1 to indicate whether [sqlite3_load_extension()] interface ** is disabled or enabled following this call. The second parameter may ** be a NULL pointer, in which case the new setting is not reported back. ** </dd> ** ** [[SQLITE_DBCONFIG_MAINDBNAME]] <dt>SQLITE_DBCONFIG_MAINDBNAME</dt> |
| ︙ | ︙ | |||
2472 2473 2474 2475 2476 2477 2478 | ** integer into which is written 0 or 1 to indicate whether the writable_schema ** is enabled or disabled following this call. ** </dd> ** ** [[SQLITE_DBCONFIG_LEGACY_ALTER_TABLE]] ** <dt>SQLITE_DBCONFIG_LEGACY_ALTER_TABLE</dt> ** <dd>The SQLITE_DBCONFIG_LEGACY_ALTER_TABLE option activates or deactivates | | | 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 | ** integer into which is written 0 or 1 to indicate whether the writable_schema ** is enabled or disabled following this call. ** </dd> ** ** [[SQLITE_DBCONFIG_LEGACY_ALTER_TABLE]] ** <dt>SQLITE_DBCONFIG_LEGACY_ALTER_TABLE</dt> ** <dd>The SQLITE_DBCONFIG_LEGACY_ALTER_TABLE option activates or deactivates ** the legacy behavior of the [ALTER TABLE RENAME] command such that it ** behaves as it did prior to [version 3.24.0] (2018-06-04). See the ** "Compatibility Notice" on the [ALTER TABLE RENAME documentation] for ** additional information. This feature can also be turned on and off ** using the [PRAGMA legacy_alter_table] statement. ** </dd> ** ** [[SQLITE_DBCONFIG_DQS_DML]] |
| ︙ | ︙ | |||
2521 2522 2523 2524 2525 2526 2527 | ** can also be controlled using the [PRAGMA trusted_schema] statement. ** </dd> ** ** [[SQLITE_DBCONFIG_LEGACY_FILE_FORMAT]] ** <dt>SQLITE_DBCONFIG_LEGACY_FILE_FORMAT</dt> ** <dd>The SQLITE_DBCONFIG_LEGACY_FILE_FORMAT option activates or deactivates ** the legacy file format flag. When activated, this flag causes all newly | | | 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 | ** can also be controlled using the [PRAGMA trusted_schema] statement. ** </dd> ** ** [[SQLITE_DBCONFIG_LEGACY_FILE_FORMAT]] ** <dt>SQLITE_DBCONFIG_LEGACY_FILE_FORMAT</dt> ** <dd>The SQLITE_DBCONFIG_LEGACY_FILE_FORMAT option activates or deactivates ** the legacy file format flag. When activated, this flag causes all newly ** created database files to have a schema format version number (the 4-byte ** integer found at offset 44 into the database header) of 1. This in turn ** means that the resulting database file will be readable and writable by ** any SQLite version back to 3.0.0 ([dateof:3.0.0]). Without this setting, ** newly created databases are generally not understandable by SQLite versions ** prior to 3.3.0 ([dateof:3.3.0]). As these words are written, there ** is now scarcely any need to generate database files that are compatible ** all the way back to version 3.0.0, and so this setting is of little |
| ︙ | ︙ | |||
2548 2549 2550 2551 2552 2553 2554 | ** <dd>The SQLITE_DBCONFIG_STMT_SCANSTATUS option is only useful in ** SQLITE_ENABLE_STMT_SCANSTATUS builds. In this case, it sets or clears ** a flag that enables collection of the sqlite3_stmt_scanstatus_v2() ** statistics. For statistics to be collected, the flag must be set on ** the database handle both when the SQL statement is prepared and when it ** is stepped. The flag is set (collection of statistics is enabled) ** by default. <p>This option takes two arguments: an integer and a pointer to | | | 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 | ** <dd>The SQLITE_DBCONFIG_STMT_SCANSTATUS option is only useful in ** SQLITE_ENABLE_STMT_SCANSTATUS builds. In this case, it sets or clears ** a flag that enables collection of the sqlite3_stmt_scanstatus_v2() ** statistics. For statistics to be collected, the flag must be set on ** the database handle both when the SQL statement is prepared and when it ** is stepped. The flag is set (collection of statistics is enabled) ** by default. <p>This option takes two arguments: an integer and a pointer to ** an integer. The first argument is 1, 0, or -1 to enable, disable, or ** leave unchanged the statement scanstatus option. If the second argument ** is not NULL, then the value of the statement scanstatus setting after ** processing the first argument is written into the integer that the second ** argument points to. ** </dd> ** ** [[SQLITE_DBCONFIG_REVERSE_SCANORDER]] |
| ︙ | ︙ | |||
2591 2592 2593 2594 2595 2596 2597 | ** </dd> ** ** [[SQLITE_DBCONFIG_ENABLE_ATTACH_WRITE]] ** <dt>SQLITE_DBCONFIG_ENABLE_ATTACH_WRITE</dt> ** <dd>The SQLITE_DBCONFIG_ENABLE_ATTACH_WRITE option enables or disables the ** ability of the [ATTACH DATABASE] SQL command to open a database for writing. ** This capability is enabled by default. Applications can disable or | | | | 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 | ** </dd> ** ** [[SQLITE_DBCONFIG_ENABLE_ATTACH_WRITE]] ** <dt>SQLITE_DBCONFIG_ENABLE_ATTACH_WRITE</dt> ** <dd>The SQLITE_DBCONFIG_ENABLE_ATTACH_WRITE option enables or disables the ** ability of the [ATTACH DATABASE] SQL command to open a database for writing. ** This capability is enabled by default. Applications can disable or ** reenable this capability using the current DBCONFIG option. If ** this capability is disabled, the [ATTACH] command will still work, ** but the database will be opened read-only. If this option is disabled, ** then the ability to create a new database using [ATTACH] is also disabled, ** regardless of the value of the [SQLITE_DBCONFIG_ENABLE_ATTACH_CREATE] ** option.<p> ** This option takes two arguments which are an integer and a pointer ** to an integer. The first argument is 1, 0, or -1 to enable, disable, or ** leave unchanged the ability to ATTACH another database for writing, |
| ︙ | ︙ | |||
2626 2627 2628 2629 2630 2631 2632 | ** ** </dl> ** ** [[DBCONFIG arguments]] <h3>Arguments To SQLITE_DBCONFIG Options</h3> ** ** <p>Most of the SQLITE_DBCONFIG options take two arguments, so that the ** overall call to [sqlite3_db_config()] has a total of four parameters. | | | 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 | ** ** </dl> ** ** [[DBCONFIG arguments]] <h3>Arguments To SQLITE_DBCONFIG Options</h3> ** ** <p>Most of the SQLITE_DBCONFIG options take two arguments, so that the ** overall call to [sqlite3_db_config()] has a total of four parameters. ** The first argument (the third parameter to sqlite3_db_config()) is an integer. ** The second argument is a pointer to an integer. If the first argument is 1, ** then the option becomes enabled. If the first integer argument is 0, then the ** option is disabled. If the first argument is -1, then the option setting ** is unchanged. The second argument, the pointer to an integer, may be NULL. ** If the second argument is not NULL, then a value of 0 or 1 is written into ** the integer to which the second argument points, depending on whether the ** setting is disabled or enabled after applying any changes specified by |
| ︙ | ︙ | |||
2916 2917 2918 2919 2920 2921 2922 | ** independent tokens (they are part of the token in which they are ** embedded) and thus do not count as a statement terminator. ^Whitespace ** and comments that follow the final semicolon are ignored. ** ** ^These routines return 0 if the statement is incomplete. ^If a ** memory allocation fails, then SQLITE_NOMEM is returned. ** | | | 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 | ** independent tokens (they are part of the token in which they are ** embedded) and thus do not count as a statement terminator. ^Whitespace ** and comments that follow the final semicolon are ignored. ** ** ^These routines return 0 if the statement is incomplete. ^If a ** memory allocation fails, then SQLITE_NOMEM is returned. ** ** ^These routines do not parse the SQL statements and thus ** will not detect syntactically incorrect SQL. ** ** ^(If SQLite has not been initialized using [sqlite3_initialize()] prior ** to invoking sqlite3_complete16() then sqlite3_initialize() is invoked ** automatically by sqlite3_complete16(). If that initialization fails, ** then the return value from sqlite3_complete16() will be non-zero ** regardless of whether or not the input SQL is complete.)^ |
| ︙ | ︙ | |||
3033 3034 3035 3036 3037 3038 3039 | ** not support blocking locks, this function is a no-op. ** ** Passing 0 to this function disables blocking locks altogether. Passing ** -1 to this function requests that the VFS blocks for a long time - ** indefinitely if possible. The results of passing any other negative value ** are undefined. ** | | | 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047 | ** not support blocking locks, this function is a no-op. ** ** Passing 0 to this function disables blocking locks altogether. Passing ** -1 to this function requests that the VFS blocks for a long time - ** indefinitely if possible. The results of passing any other negative value ** are undefined. ** ** Internally, each SQLite database handle stores two timeout values - the ** busy-timeout (used for rollback mode databases, or if the VFS does not ** support blocking locks) and the setlk-timeout (used for blocking locks ** on wal-mode databases). The sqlite3_busy_timeout() method sets both ** values, this function sets only the setlk-timeout value. Therefore, ** to configure separate busy-timeout and setlk-timeout values for a single ** database handle, call sqlite3_busy_timeout() followed by this function. ** |
| ︙ | ︙ | |||
3063 3064 3065 3066 3067 3068 3069 | /* ** CAPI3REF: Convenience Routines For Running Queries ** METHOD: sqlite3 ** ** This is a legacy interface that is preserved for backwards compatibility. ** Use of this interface is not recommended. ** | | | 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 | /* ** CAPI3REF: Convenience Routines For Running Queries ** METHOD: sqlite3 ** ** This is a legacy interface that is preserved for backwards compatibility. ** Use of this interface is not recommended. ** ** Definition: A <b>result table</b> is a memory data structure created by the ** [sqlite3_get_table()] interface. A result table records the ** complete query results from one or more queries. ** ** The table conceptually has a number of rows and columns. But ** these numbers are not part of the result table itself. These ** numbers are obtained separately. Let N be the number of rows ** and M be the number of columns. |
| ︙ | ︙ | |||
3206 3207 3208 3209 3210 3211 3212 | ** ^The sqlite3_malloc64(N) routine works just like ** sqlite3_malloc(N) except that N is an unsigned 64-bit integer instead ** of a signed 32-bit integer. ** ** ^Calling sqlite3_free() with a pointer previously returned ** by sqlite3_malloc() or sqlite3_realloc() releases that memory so ** that it might be reused. ^The sqlite3_free() routine is | | | | | | 3206 3207 3208 3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 3221 3222 3223 3224 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 | ** ^The sqlite3_malloc64(N) routine works just like ** sqlite3_malloc(N) except that N is an unsigned 64-bit integer instead ** of a signed 32-bit integer. ** ** ^Calling sqlite3_free() with a pointer previously returned ** by sqlite3_malloc() or sqlite3_realloc() releases that memory so ** that it might be reused. ^The sqlite3_free() routine is ** a no-op if it is called with a NULL pointer. Passing a NULL pointer ** to sqlite3_free() is harmless. After being freed, memory ** should neither be read nor written. Even reading previously freed ** memory might result in a segmentation fault or other severe error. ** Memory corruption, a segmentation fault, or other severe error ** might result if sqlite3_free() is called with a non-NULL pointer that ** was not obtained from sqlite3_malloc() or sqlite3_realloc(). ** ** ^The sqlite3_realloc(X,N) interface attempts to resize a ** prior memory allocation X to be at least N bytes. ** ^If the X parameter to sqlite3_realloc(X,N) ** is a NULL pointer then its behavior is identical to calling ** sqlite3_malloc(N). ** ^If the N parameter to sqlite3_realloc(X,N) is zero or ** negative then the behavior is exactly the same as calling ** sqlite3_free(X). ** ^sqlite3_realloc(X,N) returns a pointer to a memory allocation ** of at least N bytes in size or NULL if insufficient memory is available. ** ^If M is the size of the prior allocation, then min(N,M) bytes of the ** prior allocation are copied into the beginning of the buffer returned ** by sqlite3_realloc(X,N) and the prior allocation is freed. ** ^If sqlite3_realloc(X,N) returns NULL and N is positive, then the ** prior allocation is not freed. ** ** ^The sqlite3_realloc64(X,N) interface works the same as ** sqlite3_realloc(X,N) except that N is a 64-bit unsigned integer instead ** of a 32-bit signed integer. ** ** ^If X is a memory allocation previously obtained from sqlite3_malloc(), ** sqlite3_malloc64(), sqlite3_realloc(), or sqlite3_realloc64(), then ** sqlite3_msize(X) returns the size of that memory allocation in bytes. ** ^The value returned by sqlite3_msize(X) might be larger than the number |
| ︙ | ︙ | |||
3280 3281 3282 3283 3284 3285 3286 | ** ^The [sqlite3_memory_used()] routine returns the number of bytes ** of memory currently outstanding (malloced but not freed). ** ^The [sqlite3_memory_highwater()] routine returns the maximum ** value of [sqlite3_memory_used()] since the high-water mark ** was last reset. ^The values returned by [sqlite3_memory_used()] and ** [sqlite3_memory_highwater()] include any overhead ** added by SQLite in its implementation of [sqlite3_malloc()], | | | 3280 3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293 3294 | ** ^The [sqlite3_memory_used()] routine returns the number of bytes ** of memory currently outstanding (malloced but not freed). ** ^The [sqlite3_memory_highwater()] routine returns the maximum ** value of [sqlite3_memory_used()] since the high-water mark ** was last reset. ^The values returned by [sqlite3_memory_used()] and ** [sqlite3_memory_highwater()] include any overhead ** added by SQLite in its implementation of [sqlite3_malloc()], ** but not overhead added by any underlying system library ** routines that [sqlite3_malloc()] may call. ** ** ^The memory high-water mark is reset to the current value of ** [sqlite3_memory_used()] if and only if the parameter to ** [sqlite3_memory_highwater()] is true. ^The value returned ** by [sqlite3_memory_highwater(1)] is the high-water mark ** prior to the reset. |
| ︙ | ︙ | |||
3732 3733 3734 3735 3736 3737 3738 | ** <dd>The new database connection will use the "serialized" ** [threading mode].)^ This means the multiple threads can safely ** attempt to use the same database connection at the same time. ** (Mutexes will block any actual concurrency, but in this mode ** there is no harm in trying.) ** ** ^(<dt>[SQLITE_OPEN_SHAREDCACHE]</dt> | | | | 3732 3733 3734 3735 3736 3737 3738 3739 3740 3741 3742 3743 3744 3745 3746 3747 3748 3749 3750 3751 3752 3753 3754 | ** <dd>The new database connection will use the "serialized" ** [threading mode].)^ This means the multiple threads can safely ** attempt to use the same database connection at the same time. ** (Mutexes will block any actual concurrency, but in this mode ** there is no harm in trying.) ** ** ^(<dt>[SQLITE_OPEN_SHAREDCACHE]</dt> ** <dd>The database is opened with [shared cache] enabled, overriding ** the default shared cache setting provided by ** [sqlite3_enable_shared_cache()].)^ ** The [use of shared cache mode is discouraged] and hence shared cache ** capabilities may be omitted from many builds of SQLite. In such cases, ** this option is a no-op. ** ** ^(<dt>[SQLITE_OPEN_PRIVATECACHE]</dt> ** <dd>The database is opened with [shared cache] disabled, overriding ** the default shared cache setting provided by ** [sqlite3_enable_shared_cache()].)^ ** ** [[OPEN_EXRESCODE]] ^(<dt>[SQLITE_OPEN_EXRESCODE]</dt> ** <dd>The database connection comes up in "extended result code mode". ** In other words, the database behaves as if ** [sqlite3_extended_result_codes(db,1)] were called on the database |
| ︙ | ︙ | |||
4075 4076 4077 4078 4079 4080 4081 | ** CAPI3REF: Create and Destroy VFS Filenames ** ** These interfaces are provided for use by [VFS shim] implementations and ** are not useful outside of that context. ** ** The sqlite3_create_filename(D,J,W,N,P) allocates memory to hold a version of ** database filename D with corresponding journal file J and WAL file W and | | | 4075 4076 4077 4078 4079 4080 4081 4082 4083 4084 4085 4086 4087 4088 4089 | ** CAPI3REF: Create and Destroy VFS Filenames ** ** These interfaces are provided for use by [VFS shim] implementations and ** are not useful outside of that context. ** ** The sqlite3_create_filename(D,J,W,N,P) allocates memory to hold a version of ** database filename D with corresponding journal file J and WAL file W and ** an array P of N URI Key/Value pairs. The result from ** sqlite3_create_filename(D,J,W,N,P) is a pointer to a database filename that ** is safe to pass to routines like: ** <ul> ** <li> [sqlite3_uri_parameter()], ** <li> [sqlite3_uri_boolean()], ** <li> [sqlite3_uri_int64()], ** <li> [sqlite3_uri_key()], |
| ︙ | ︙ | |||
4158 4159 4160 4161 4162 4163 4164 | ** (See how SQLite handles [invalid UTF] for exceptions to this rule.) ** ^(Memory to hold the error message string is managed internally. ** The application does not need to worry about freeing the result. ** However, the error string might be overwritten or deallocated by ** subsequent calls to other SQLite interface functions.)^ ** ** ^The sqlite3_errstr(E) interface returns the English-language text | | | | 4158 4159 4160 4161 4162 4163 4164 4165 4166 4167 4168 4169 4170 4171 4172 4173 4174 4175 4176 4177 4178 4179 4180 | ** (See how SQLite handles [invalid UTF] for exceptions to this rule.) ** ^(Memory to hold the error message string is managed internally. ** The application does not need to worry about freeing the result. ** However, the error string might be overwritten or deallocated by ** subsequent calls to other SQLite interface functions.)^ ** ** ^The sqlite3_errstr(E) interface returns the English-language text ** that describes the [result code] E, as UTF-8, or NULL if E is not a ** result code for which a text error message is available. ** ^(Memory to hold the error message string is managed internally ** and must not be freed by the application)^. ** ** ^If the most recent error references a specific token in the input ** SQL, the sqlite3_error_offset() interface returns the byte offset ** of the start of that token. ^The byte offset returned by ** sqlite3_error_offset() assumes that the input SQL is UTF-8. ** ^If the most recent error does not reference a specific token in the input ** SQL, then the sqlite3_error_offset() function returns -1. ** ** When the serialized [threading mode] is in use, it might be the ** case that a second error occurs on a separate thread in between ** the time of the first error and the call to these interfaces. ** When that happens, the second error will be reported since these |
| ︙ | ︙ | |||
4265 4266 4267 4268 4269 4270 4271 |
/*
** CAPI3REF: Run-Time Limit Categories
** KEYWORDS: {limit category} {*limit categories}
**
** These constants define various performance limits
** that can be lowered at run-time using [sqlite3_limit()].
| | | | 4265 4266 4267 4268 4269 4270 4271 4272 4273 4274 4275 4276 4277 4278 4279 4280 |
/*
** CAPI3REF: Run-Time Limit Categories
** KEYWORDS: {limit category} {*limit categories}
**
** These constants define various performance limits
** that can be lowered at run-time using [sqlite3_limit()].
** A concise description of these limits follows, and additional information
** is available at [limits | Limits in SQLite].
**
** <dl>
** [[SQLITE_LIMIT_LENGTH]] ^(<dt>SQLITE_LIMIT_LENGTH</dt>
** <dd>The maximum size of any string or BLOB or table row, in bytes.<dd>)^
**
** [[SQLITE_LIMIT_SQL_LENGTH]] ^(<dt>SQLITE_LIMIT_SQL_LENGTH</dt>
** <dd>The maximum length of an SQL statement, in bytes.</dd>)^
|
| ︙ | ︙ | |||
4331 4332 4333 4334 4335 4336 4337 | #define SQLITE_LIMIT_VARIABLE_NUMBER 9 #define SQLITE_LIMIT_TRIGGER_DEPTH 10 #define SQLITE_LIMIT_WORKER_THREADS 11 /* ** CAPI3REF: Prepare Flags ** | | | 4331 4332 4333 4334 4335 4336 4337 4338 4339 4340 4341 4342 4343 4344 4345 | #define SQLITE_LIMIT_VARIABLE_NUMBER 9 #define SQLITE_LIMIT_TRIGGER_DEPTH 10 #define SQLITE_LIMIT_WORKER_THREADS 11 /* ** CAPI3REF: Prepare Flags ** ** These constants define various flags that can be passed into the ** "prepFlags" parameter of the [sqlite3_prepare_v3()] and ** [sqlite3_prepare16_v3()] interfaces. ** ** New flags may be added in future releases of SQLite. ** ** <dl> ** [[SQLITE_PREPARE_PERSISTENT]] ^(<dt>SQLITE_PREPARE_PERSISTENT</dt> |
| ︙ | ︙ | |||
4418 4419 4420 4421 4422 4423 4424 | ** up to the first zero terminator or until the nByte bytes have been read, ** whichever comes first. ^If nByte is zero, then no prepared ** statement is generated. ** If the caller knows that the supplied string is nul-terminated, then ** there is a small performance advantage to passing an nByte parameter that ** is the number of bytes in the input string <i>including</i> ** the nul-terminator. | | | 4418 4419 4420 4421 4422 4423 4424 4425 4426 4427 4428 4429 4430 4431 4432 | ** up to the first zero terminator or until the nByte bytes have been read, ** whichever comes first. ^If nByte is zero, then no prepared ** statement is generated. ** If the caller knows that the supplied string is nul-terminated, then ** there is a small performance advantage to passing an nByte parameter that ** is the number of bytes in the input string <i>including</i> ** the nul-terminator. ** Note that nByte measures the length of the input in bytes, not ** characters, even for the UTF-16 interfaces. ** ** ^If pzTail is not NULL then *pzTail is made to point to the first byte ** past the end of the first SQL statement in zSql. These routines only ** compile the first statement in zSql, so *pzTail is left pointing to ** what remains uncompiled. ** |
| ︙ | ︙ | |||
4552 4553 4554 4555 4556 4557 4558 | ** text "SELECT $abc,:xyz" and if parameter $abc is bound to integer 2345 ** and parameter :xyz is unbound, then sqlite3_sql() will return ** the original string, "SELECT $abc,:xyz" but sqlite3_expanded_sql() ** will return "SELECT 2345,NULL".)^ ** ** ^The sqlite3_expanded_sql() interface returns NULL if insufficient memory ** is available to hold the result, or if the result would exceed the | | | 4552 4553 4554 4555 4556 4557 4558 4559 4560 4561 4562 4563 4564 4565 4566 | ** text "SELECT $abc,:xyz" and if parameter $abc is bound to integer 2345 ** and parameter :xyz is unbound, then sqlite3_sql() will return ** the original string, "SELECT $abc,:xyz" but sqlite3_expanded_sql() ** will return "SELECT 2345,NULL".)^ ** ** ^The sqlite3_expanded_sql() interface returns NULL if insufficient memory ** is available to hold the result, or if the result would exceed the ** maximum string length determined by the [SQLITE_LIMIT_LENGTH]. ** ** ^The [SQLITE_TRACE_SIZE_LIMIT] compile-time option limits the size of ** bound parameter expansions. ^The [SQLITE_OMIT_TRACE] compile-time ** option causes sqlite3_expanded_sql() to always return NULL. ** ** ^The strings returned by sqlite3_sql(P) and sqlite3_normalized_sql(P) ** are managed by SQLite and are automatically freed when the prepared |
| ︙ | ︙ | |||
4740 4741 4742 4743 4744 4745 4746 | typedef struct sqlite3_value sqlite3_value; /* ** CAPI3REF: SQL Function Context Object ** ** The context in which an SQL function executes is stored in an ** sqlite3_context object. ^A pointer to an sqlite3_context object | | | | 4740 4741 4742 4743 4744 4745 4746 4747 4748 4749 4750 4751 4752 4753 4754 4755 4756 4757 4758 4759 4760 4761 4762 4763 4764 4765 4766 4767 4768 4769 4770 |
typedef struct sqlite3_value sqlite3_value;
/*
** CAPI3REF: SQL Function Context Object
**
** The context in which an SQL function executes is stored in an
** sqlite3_context object. ^A pointer to an sqlite3_context object
** is always the first parameter to [application-defined SQL functions].
** The application-defined SQL function implementation will pass this
** pointer through into calls to [sqlite3_result_int | sqlite3_result()],
** [sqlite3_aggregate_context()], [sqlite3_user_data()],
** [sqlite3_context_db_handle()], [sqlite3_get_auxdata()],
** and/or [sqlite3_set_auxdata()].
*/
typedef struct sqlite3_context sqlite3_context;
/*
** CAPI3REF: Binding Values To Prepared Statements
** KEYWORDS: {host parameter} {host parameters} {host parameter name}
** KEYWORDS: {SQL parameter} {SQL parameters} {parameter binding}
** METHOD: sqlite3_stmt
**
** ^(In the SQL statement text input to [sqlite3_prepare_v2()] and its variants,
** literals may be replaced by a [parameter] that matches one of the following
** templates:
**
** <ul>
** <li> ?
** <li> ?NNN
** <li> :VVV
** <li> @VVV
|
| ︙ | ︙ | |||
4801 4802 4803 4804 4805 4806 4807 | ** ^If the third parameter to sqlite3_bind_text64() is not NULL, then ** it should be a pointer to a well-formed unicode string that is ** either UTF8 if the sixth parameter is SQLITE_UTF8, or UTF16 ** otherwise. ** ** [[byte-order determination rules]] ^The byte-order of ** UTF16 input text is determined by the byte-order mark (BOM, U+FEFF) | | | | 4801 4802 4803 4804 4805 4806 4807 4808 4809 4810 4811 4812 4813 4814 4815 4816 4817 4818 4819 4820 4821 4822 4823 4824 4825 4826 4827 4828 4829 4830 4831 4832 4833 4834 4835 | ** ^If the third parameter to sqlite3_bind_text64() is not NULL, then ** it should be a pointer to a well-formed unicode string that is ** either UTF8 if the sixth parameter is SQLITE_UTF8, or UTF16 ** otherwise. ** ** [[byte-order determination rules]] ^The byte-order of ** UTF16 input text is determined by the byte-order mark (BOM, U+FEFF) ** found in the first character, which is removed, or in the absence of a BOM ** the byte order is the native byte order of the host ** machine for sqlite3_bind_text16() or the byte order specified in ** the 6th parameter for sqlite3_bind_text64().)^ ** ^If UTF16 input text contains invalid unicode ** characters, then SQLite might change those invalid characters ** into the unicode replacement character: U+FFFD. ** ** ^(In those routines that have a fourth argument, its value is the ** number of bytes in the parameter. To be clear: the value is the ** number of <u>bytes</u> in the value, not the number of characters.)^ ** ^If the fourth parameter to sqlite3_bind_text() or sqlite3_bind_text16() ** is negative, then the length of the string is ** the number of bytes up to the first zero terminator. ** If the fourth parameter to sqlite3_bind_blob() is negative, then ** the behavior is undefined. ** If a non-negative fourth parameter is provided to sqlite3_bind_text() ** or sqlite3_bind_text16() or sqlite3_bind_text64() then ** that parameter must be the byte offset ** where the NUL terminator would occur assuming the string were NUL ** terminated. If any NUL characters occur at byte offsets less than ** the value of the fourth parameter then the resulting string value will ** contain embedded NULs. The result of expressions involving strings ** with embedded NULs is undefined. ** ** ^The fifth argument to the BLOB and string binding interfaces controls ** or indicates the lifetime of the object referenced by the third parameter. ** These three options exist: |
| ︙ | ︙ | |||
5033 5034 5035 5036 5037 5038 5039 | SQLITE_API const void *sqlite3_column_name16(sqlite3_stmt*, int N); /* ** CAPI3REF: Source Of Data In A Query Result ** METHOD: sqlite3_stmt ** ** ^These routines provide a means to determine the database, table, and | | | 5033 5034 5035 5036 5037 5038 5039 5040 5041 5042 5043 5044 5045 5046 5047 | SQLITE_API const void *sqlite3_column_name16(sqlite3_stmt*, int N); /* ** CAPI3REF: Source Of Data In A Query Result ** METHOD: sqlite3_stmt ** ** ^These routines provide a means to determine the database, table, and ** table column that is the origin of a particular result column in a ** [SELECT] statement. ** ^The name of the database or table or column can be returned as ** either a UTF-8 or UTF-16 string. ^The _database_ routines return ** the database name, the _table_ routines return the table name, and ** the origin_ routines return the column name. ** ^The returned string is valid until the [prepared statement] is destroyed ** using [sqlite3_finalize()] or until the statement is automatically |
| ︙ | ︙ | |||
5477 5478 5479 5480 5481 5482 5483 | /* ** CAPI3REF: Destroy A Prepared Statement Object ** DESTRUCTOR: sqlite3_stmt ** ** ^The sqlite3_finalize() function is called to delete a [prepared statement]. ** ^If the most recent evaluation of the statement encountered no errors | | | 5477 5478 5479 5480 5481 5482 5483 5484 5485 5486 5487 5488 5489 5490 5491 | /* ** CAPI3REF: Destroy A Prepared Statement Object ** DESTRUCTOR: sqlite3_stmt ** ** ^The sqlite3_finalize() function is called to delete a [prepared statement]. ** ^If the most recent evaluation of the statement encountered no errors ** or if the statement has never been evaluated, then sqlite3_finalize() returns ** SQLITE_OK. ^If the most recent evaluation of statement S failed, then ** sqlite3_finalize(S) returns the appropriate [error code] or ** [extended error code]. ** ** ^The sqlite3_finalize(S) routine can be called at any point during ** the life cycle of [prepared statement] S: ** before statement S is ever evaluated, after |
| ︙ | ︙ | |||
5602 5603 5604 5605 5606 5607 5608 | ** ^The fourth parameter may also optionally include the [SQLITE_DIRECTONLY] ** flag, which if present prevents the function from being invoked from ** within VIEWs, TRIGGERs, CHECK constraints, generated column expressions, ** index expressions, or the WHERE clause of partial indexes. ** ** For best security, the [SQLITE_DIRECTONLY] flag is recommended for ** all application-defined SQL functions that do not need to be | | | | 5602 5603 5604 5605 5606 5607 5608 5609 5610 5611 5612 5613 5614 5615 5616 5617 | ** ^The fourth parameter may also optionally include the [SQLITE_DIRECTONLY] ** flag, which if present prevents the function from being invoked from ** within VIEWs, TRIGGERs, CHECK constraints, generated column expressions, ** index expressions, or the WHERE clause of partial indexes. ** ** For best security, the [SQLITE_DIRECTONLY] flag is recommended for ** all application-defined SQL functions that do not need to be ** used inside of triggers, views, CHECK constraints, or other elements of ** the database schema. This flag is especially recommended for SQL ** functions that have side effects or reveal internal application state. ** Without this flag, an attacker might be able to modify the schema of ** a database file to include invocations of the function with parameters ** chosen by the attacker, which the application will then execute when ** the database file is opened and read. ** ** ^(The fifth parameter is an arbitrary pointer. The implementation of the |
| ︙ | ︙ | |||
5634 5635 5636 5637 5638 5639 5640 | ** which case a regular aggregate function is created, or must both be ** non-NULL, in which case the new function may be used as either an aggregate ** or aggregate window function. More details regarding the implementation ** of aggregate window functions are ** [user-defined window functions|available here]. ** ** ^(If the final parameter to sqlite3_create_function_v2() or | | | 5634 5635 5636 5637 5638 5639 5640 5641 5642 5643 5644 5645 5646 5647 5648 | ** which case a regular aggregate function is created, or must both be ** non-NULL, in which case the new function may be used as either an aggregate ** or aggregate window function. More details regarding the implementation ** of aggregate window functions are ** [user-defined window functions|available here]. ** ** ^(If the final parameter to sqlite3_create_function_v2() or ** sqlite3_create_window_function() is not NULL, then it is the destructor for ** the application data pointer. The destructor is invoked when the function ** is deleted, either by being overloaded or when the database connection ** closes.)^ ^The destructor is also invoked if the call to ** sqlite3_create_function_v2() fails. ^When the destructor callback is ** invoked, it is passed a single argument which is a copy of the application ** data pointer which was the fifth parameter to sqlite3_create_function_v2(). ** |
| ︙ | ︙ | |||
5709 5710 5711 5712 5713 5714 5715 | void (*xInverse)(sqlite3_context*,int,sqlite3_value**), void(*xDestroy)(void*) ); /* ** CAPI3REF: Text Encodings ** | | | 5709 5710 5711 5712 5713 5714 5715 5716 5717 5718 5719 5720 5721 5722 5723 | void (*xInverse)(sqlite3_context*,int,sqlite3_value**), void(*xDestroy)(void*) ); /* ** CAPI3REF: Text Encodings ** ** These constants define integer codes that represent the various ** text encodings supported by SQLite. */ #define SQLITE_UTF8 1 /* IMP: R-37514-35566 */ #define SQLITE_UTF16LE 2 /* IMP: R-03371-37637 */ #define SQLITE_UTF16BE 3 /* IMP: R-51971-34154 */ #define SQLITE_UTF16 4 /* Use native byte order */ #define SQLITE_ANY 5 /* Deprecated */ |
| ︙ | ︙ | |||
5801 5802 5803 5804 5805 5806 5807 | ** ** [[SQLITE_RESULT_SUBTYPE]] <dt>SQLITE_RESULT_SUBTYPE</dt><dd> ** The SQLITE_RESULT_SUBTYPE flag indicates to SQLite that a function might call ** [sqlite3_result_subtype()] to cause a sub-type to be associated with its ** result. ** Every function that invokes [sqlite3_result_subtype()] should have this ** property. If it does not, then the call to [sqlite3_result_subtype()] | | | 5801 5802 5803 5804 5805 5806 5807 5808 5809 5810 5811 5812 5813 5814 5815 | ** ** [[SQLITE_RESULT_SUBTYPE]] <dt>SQLITE_RESULT_SUBTYPE</dt><dd> ** The SQLITE_RESULT_SUBTYPE flag indicates to SQLite that a function might call ** [sqlite3_result_subtype()] to cause a sub-type to be associated with its ** result. ** Every function that invokes [sqlite3_result_subtype()] should have this ** property. If it does not, then the call to [sqlite3_result_subtype()] ** might become a no-op if the function is used as a term in an ** [expression index]. On the other hand, SQL functions that never invoke ** [sqlite3_result_subtype()] should avoid setting this property, as the ** purpose of this property is to disable certain optimizations that are ** incompatible with subtypes. ** ** [[SQLITE_SELFORDER1]] <dt>SQLITE_SELFORDER1</dt><dd> ** The SQLITE_SELFORDER1 flag indicates that the function is an aggregate |
| ︙ | ︙ | |||
5928 5929 5930 5931 5932 5933 5934 | ** then the conversion is performed. Otherwise no conversion occurs. ** The [SQLITE_INTEGER | datatype] after conversion is returned.)^ ** ** ^Within the [xUpdate] method of a [virtual table], the ** sqlite3_value_nochange(X) interface returns true if and only if ** the column corresponding to X is unchanged by the UPDATE operation ** that the xUpdate method call was invoked to implement and if | | | 5928 5929 5930 5931 5932 5933 5934 5935 5936 5937 5938 5939 5940 5941 5942 | ** then the conversion is performed. Otherwise no conversion occurs. ** The [SQLITE_INTEGER | datatype] after conversion is returned.)^ ** ** ^Within the [xUpdate] method of a [virtual table], the ** sqlite3_value_nochange(X) interface returns true if and only if ** the column corresponding to X is unchanged by the UPDATE operation ** that the xUpdate method call was invoked to implement and if ** the prior [xColumn] method call that was invoked to extract ** the value for that column returned without setting a result (probably ** because it queried [sqlite3_vtab_nochange()] and found that the column ** was unchanging). ^Within an [xUpdate] method, any value for which ** sqlite3_value_nochange(X) is true will in all other respects appear ** to be a NULL value. If sqlite3_value_nochange(X) is invoked anywhere other ** than within an [xUpdate] method call for an UPDATE statement, then ** the return value is arbitrary and meaningless. |
| ︙ | ︙ | |||
6034 6035 6036 6037 6038 6039 6040 | SQLITE_API unsigned int sqlite3_value_subtype(sqlite3_value*); /* ** CAPI3REF: Copy And Free SQL Values ** METHOD: sqlite3_value ** ** ^The sqlite3_value_dup(V) interface makes a copy of the [sqlite3_value] | | | 6034 6035 6036 6037 6038 6039 6040 6041 6042 6043 6044 6045 6046 6047 6048 | SQLITE_API unsigned int sqlite3_value_subtype(sqlite3_value*); /* ** CAPI3REF: Copy And Free SQL Values ** METHOD: sqlite3_value ** ** ^The sqlite3_value_dup(V) interface makes a copy of the [sqlite3_value] ** object V and returns a pointer to that copy. ^The [sqlite3_value] returned ** is a [protected sqlite3_value] object even if the input is not. ** ^The sqlite3_value_dup(V) interface returns NULL if V is NULL or if a ** memory allocation fails. ^If V is a [pointer value], then the result ** of sqlite3_value_dup(V) is a NULL value. ** ** ^The sqlite3_value_free(V) interface frees an [sqlite3_value] object ** previously obtained from [sqlite3_value_dup()]. ^If V is a NULL pointer |
| ︙ | ︙ | |||
6072 6073 6074 6075 6076 6077 6078 | ** first time from within xFinal().)^ ** ** ^The sqlite3_aggregate_context(C,N) routine returns a NULL pointer ** when first called if N is less than or equal to zero or if a memory ** allocation error occurs. ** ** ^(The amount of space allocated by sqlite3_aggregate_context(C,N) is | | | 6072 6073 6074 6075 6076 6077 6078 6079 6080 6081 6082 6083 6084 6085 6086 | ** first time from within xFinal().)^ ** ** ^The sqlite3_aggregate_context(C,N) routine returns a NULL pointer ** when first called if N is less than or equal to zero or if a memory ** allocation error occurs. ** ** ^(The amount of space allocated by sqlite3_aggregate_context(C,N) is ** determined by the N parameter on the first successful call. Changing the ** value of N in any subsequent call to sqlite3_aggregate_context() within ** the same aggregate function instance will not resize the memory ** allocation.)^ Within the xFinal callback, it is customary to set ** N=0 in calls to sqlite3_aggregate_context(C,N) so that no ** pointless memory allocations occur. ** ** ^SQLite automatically frees the memory allocated by |
| ︙ | ︙ | |||
6234 6235 6236 6237 6238 6239 6240 | ** There is no way to enumerate the client data pointers ** associated with a database connection. The N parameter can be thought ** of as a secret key such that only code that knows the secret key is able ** to access the associated data. ** ** Security Warning: These interfaces should not be exposed in scripting ** languages or in other circumstances where it might be possible for an | | | 6234 6235 6236 6237 6238 6239 6240 6241 6242 6243 6244 6245 6246 6247 6248 | ** There is no way to enumerate the client data pointers ** associated with a database connection. The N parameter can be thought ** of as a secret key such that only code that knows the secret key is able ** to access the associated data. ** ** Security Warning: These interfaces should not be exposed in scripting ** languages or in other circumstances where it might be possible for an ** attacker to invoke them. Any agent that can invoke these interfaces ** can probably also take control of the process. ** ** Database connection client data is only available for SQLite ** version 3.44.0 ([dateof:3.44.0]) and later. ** ** See also: [sqlite3_set_auxdata()] and [sqlite3_get_auxdata()]. */ |
| ︙ | ︙ | |||
6348 6349 6350 6351 6352 6353 6354 | ** the string length itself by searching the 2nd parameter for the first ** zero character. ** ^If the 3rd parameter to the sqlite3_result_text* interfaces ** is non-negative, then as many bytes (not characters) of the text ** pointed to by the 2nd parameter are taken as the application-defined ** function result. If the 3rd parameter is non-negative, then it ** must be the byte offset into the string where the NUL terminator would | | | 6348 6349 6350 6351 6352 6353 6354 6355 6356 6357 6358 6359 6360 6361 6362 | ** the string length itself by searching the 2nd parameter for the first ** zero character. ** ^If the 3rd parameter to the sqlite3_result_text* interfaces ** is non-negative, then as many bytes (not characters) of the text ** pointed to by the 2nd parameter are taken as the application-defined ** function result. If the 3rd parameter is non-negative, then it ** must be the byte offset into the string where the NUL terminator would ** appear if the string were NUL terminated. If any NUL characters occur ** in the string at a byte offset that is less than the value of the 3rd ** parameter, then the resulting string will contain embedded NULs and the ** result of expressions operating on strings with embedded NULs is undefined. ** ^If the 4th parameter to the sqlite3_result_text* interfaces ** or sqlite3_result_blob is a non-NULL pointer, then SQLite calls that ** function as the destructor on the text or BLOB result when it has ** finished using that result. |
| ︙ | ︙ | |||
6406 6407 6408 6409 6410 6411 6412 | ** [application-defined SQL function] using [sqlite3_value_pointer()]. ** ^If the D parameter is not NULL, then it is a pointer to a destructor ** for the P parameter. ^SQLite invokes D with P as its only argument ** when SQLite is finished with P. The T parameter should be a static ** string and preferably a string literal. The sqlite3_result_pointer() ** routine is part of the [pointer passing interface] added for SQLite 3.20.0. ** | | | 6406 6407 6408 6409 6410 6411 6412 6413 6414 6415 6416 6417 6418 6419 6420 |
** [application-defined SQL function] using [sqlite3_value_pointer()].
** ^If the D parameter is not NULL, then it is a pointer to a destructor
** for the P parameter. ^SQLite invokes D with P as its only argument
** when SQLite is finished with P. The T parameter should be a static
** string and preferably a string literal. The sqlite3_result_pointer()
** routine is part of the [pointer passing interface] added for SQLite 3.20.0.
**
** If these routines are called from within a different thread
** than the one containing the application-defined function that received
** the [sqlite3_context] pointer, the results are undefined.
*/
SQLITE_API void sqlite3_result_blob(sqlite3_context*, const void*, int, void(*)(void*));
SQLITE_API void sqlite3_result_blob64(sqlite3_context*,const void*,
sqlite3_uint64,void(*)(void*));
SQLITE_API void sqlite3_result_double(sqlite3_context*, double);
|
| ︙ | ︙ | |||
6812 6813 6814 6815 6816 6817 6818 | SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt*); /* ** CAPI3REF: Return The Schema Name For A Database Connection ** METHOD: sqlite3 ** ** ^The sqlite3_db_name(D,N) interface returns a pointer to the schema name | | | 6812 6813 6814 6815 6816 6817 6818 6819 6820 6821 6822 6823 6824 6825 6826 | SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt*); /* ** CAPI3REF: Return The Schema Name For A Database Connection ** METHOD: sqlite3 ** ** ^The sqlite3_db_name(D,N) interface returns a pointer to the schema name ** for the N-th database on database connection D, or a NULL pointer if N is ** out of range. An N value of 0 means the main database file. An N of 1 is ** the "temp" schema. Larger values of N correspond to various ATTACH-ed ** databases. ** ** Space to hold the string that is returned by sqlite3_db_name() is managed ** by SQLite itself. The string might be deallocated by any operation that ** changes the schema, including [ATTACH] or [DETACH] or calls to |
| ︙ | ︙ | |||
6907 6908 6909 6910 6911 6912 6913 | ** <dd>The SQLITE_TXN_NONE state means that no transaction is currently ** pending.</dd> ** ** [[SQLITE_TXN_READ]] <dt>SQLITE_TXN_READ</dt> ** <dd>The SQLITE_TXN_READ state means that the database is currently ** in a read transaction. Content has been read from the database file ** but nothing in the database file has changed. The transaction state | | | | 6907 6908 6909 6910 6911 6912 6913 6914 6915 6916 6917 6918 6919 6920 6921 6922 6923 6924 6925 6926 6927 6928 6929 6930 | ** <dd>The SQLITE_TXN_NONE state means that no transaction is currently ** pending.</dd> ** ** [[SQLITE_TXN_READ]] <dt>SQLITE_TXN_READ</dt> ** <dd>The SQLITE_TXN_READ state means that the database is currently ** in a read transaction. Content has been read from the database file ** but nothing in the database file has changed. The transaction state ** will be advanced to SQLITE_TXN_WRITE if any changes occur and there are ** no other conflicting concurrent write transactions. The transaction ** state will revert to SQLITE_TXN_NONE following a [ROLLBACK] or ** [COMMIT].</dd> ** ** [[SQLITE_TXN_WRITE]] <dt>SQLITE_TXN_WRITE</dt> ** <dd>The SQLITE_TXN_WRITE state means that the database is currently ** in a write transaction. Content has been written to the database file ** but has not yet committed. The transaction state will change to ** SQLITE_TXN_NONE at the next [ROLLBACK] or [COMMIT].</dd> */ #define SQLITE_TXN_NONE 0 #define SQLITE_TXN_READ 1 #define SQLITE_TXN_WRITE 2 /* ** CAPI3REF: Find the next prepared statement |
| ︙ | ︙ | |||
7197 7198 7199 7200 7201 7202 7203 | */ SQLITE_API int sqlite3_db_release_memory(sqlite3*); /* ** CAPI3REF: Impose A Limit On Heap Size ** ** These interfaces impose limits on the amount of heap memory that will be | | | 7197 7198 7199 7200 7201 7202 7203 7204 7205 7206 7207 7208 7209 7210 7211 | */ SQLITE_API int sqlite3_db_release_memory(sqlite3*); /* ** CAPI3REF: Impose A Limit On Heap Size ** ** These interfaces impose limits on the amount of heap memory that will be ** used by all database connections within a single process. ** ** ^The sqlite3_soft_heap_limit64() interface sets and/or queries the ** soft limit on the amount of heap memory that may be allocated by SQLite. ** ^SQLite strives to keep heap memory utilization below the soft heap ** limit by reducing the number of pages held in the page cache ** as heap memory usages approaches the limit. ** ^The soft heap limit is "soft" because even though SQLite strives to stay |
| ︙ | ︙ | |||
7255 7256 7257 7258 7259 7260 7261 | ** [sqlite3_config]([SQLITE_CONFIG_PCACHE2],...). ** <li> The page cache allocates from its own memory pool supplied ** by [sqlite3_config]([SQLITE_CONFIG_PAGECACHE],...) rather than ** from the heap. ** </ul>)^ ** ** The circumstances under which SQLite will enforce the heap limits may | | | 7255 7256 7257 7258 7259 7260 7261 7262 7263 7264 7265 7266 7267 7268 7269 | ** [sqlite3_config]([SQLITE_CONFIG_PCACHE2],...). ** <li> The page cache allocates from its own memory pool supplied ** by [sqlite3_config]([SQLITE_CONFIG_PAGECACHE],...) rather than ** from the heap. ** </ul>)^ ** ** The circumstances under which SQLite will enforce the heap limits may ** change in future releases of SQLite. */ SQLITE_API sqlite3_int64 sqlite3_soft_heap_limit64(sqlite3_int64 N); SQLITE_API sqlite3_int64 sqlite3_hard_heap_limit64(sqlite3_int64 N); /* ** CAPI3REF: Deprecated Soft Heap Limit Interface ** DEPRECATED |
| ︙ | ︙ | |||
7370 7371 7372 7373 7374 7375 7376 | ** So for example, if "samplelib" cannot be loaded, then names like ** "samplelib.so" or "samplelib.dylib" or "samplelib.dll" might ** be tried also. ** ** ^The entry point is zProc. ** ^(zProc may be 0, in which case SQLite will try to come up with an ** entry point name on its own. It first tries "sqlite3_extension_init". | | | | 7370 7371 7372 7373 7374 7375 7376 7377 7378 7379 7380 7381 7382 7383 7384 7385 | ** So for example, if "samplelib" cannot be loaded, then names like ** "samplelib.so" or "samplelib.dylib" or "samplelib.dll" might ** be tried also. ** ** ^The entry point is zProc. ** ^(zProc may be 0, in which case SQLite will try to come up with an ** entry point name on its own. It first tries "sqlite3_extension_init". ** If that does not work, it constructs a name "sqlite3_X_init" where ** X consists of the lower-case equivalent of all ASCII alphabetic ** characters in the filename from the last "/" to the first following ** "." and omitting any initial "lib".)^ ** ^The sqlite3_load_extension() interface returns ** [SQLITE_OK] on success and [SQLITE_ERROR] if something goes wrong. ** ^If an error occurs and pzErrMsg is not 0, then the ** [sqlite3_load_extension()] interface shall attempt to ** fill *pzErrMsg with error message text stored in memory |
| ︙ | ︙ | |||
7442 7443 7444 7445 7446 7447 7448 | ** each new [database connection] that is created. The idea here is that ** xEntryPoint() is the entry point for a statically linked [SQLite extension] ** that is to be automatically loaded into all new database connections. ** ** ^(Even though the function prototype shows that xEntryPoint() takes ** no arguments and returns void, SQLite invokes xEntryPoint() with three ** arguments and expects an integer result as if the signature of the | | | 7442 7443 7444 7445 7446 7447 7448 7449 7450 7451 7452 7453 7454 7455 7456 | ** each new [database connection] that is created. The idea here is that ** xEntryPoint() is the entry point for a statically linked [SQLite extension] ** that is to be automatically loaded into all new database connections. ** ** ^(Even though the function prototype shows that xEntryPoint() takes ** no arguments and returns void, SQLite invokes xEntryPoint() with three ** arguments and expects an integer result as if the signature of the ** entry point were as follows: ** ** <blockquote><pre> ** int xEntryPoint( ** sqlite3 *db, ** const char **pzErrMsg, ** const struct sqlite3_api_routines *pThunk ** ); |
| ︙ | ︙ | |||
7606 7607 7608 7609 7610 7611 7612 | ** about what parameters to pass to xFilter. ^If argvIndex>0 then ** the right-hand side of the corresponding aConstraint[] is evaluated ** and becomes the argvIndex-th entry in argv. ^(If aConstraintUsage[].omit ** is true, then the constraint is assumed to be fully handled by the ** virtual table and might not be checked again by the byte code.)^ ^(The ** aConstraintUsage[].omit flag is an optimization hint. When the omit flag ** is left in its default setting of false, the constraint will always be | | | 7606 7607 7608 7609 7610 7611 7612 7613 7614 7615 7616 7617 7618 7619 7620 | ** about what parameters to pass to xFilter. ^If argvIndex>0 then ** the right-hand side of the corresponding aConstraint[] is evaluated ** and becomes the argvIndex-th entry in argv. ^(If aConstraintUsage[].omit ** is true, then the constraint is assumed to be fully handled by the ** virtual table and might not be checked again by the byte code.)^ ^(The ** aConstraintUsage[].omit flag is an optimization hint. When the omit flag ** is left in its default setting of false, the constraint will always be ** checked separately in byte code. If the omit flag is changed to true, then ** the constraint may or may not be checked in byte code. In other words, ** when the omit flag is true there is no guarantee that the constraint will ** not be checked again using byte code.)^ ** ** ^The idxNum and idxStr values are recorded and passed into the ** [xFilter] method. ** ^[sqlite3_free()] is used to free idxStr if and only if |
| ︙ | ︙ | |||
7632 7633 7634 7635 7636 7637 7638 | ** ** ^The estimatedRows value is an estimate of the number of rows that ** will be returned by the strategy. ** ** The xBestIndex method may optionally populate the idxFlags field with a ** mask of SQLITE_INDEX_SCAN_* flags. One such flag is ** [SQLITE_INDEX_SCAN_HEX], which if set causes the [EXPLAIN QUERY PLAN] | | | 7632 7633 7634 7635 7636 7637 7638 7639 7640 7641 7642 7643 7644 7645 7646 | ** ** ^The estimatedRows value is an estimate of the number of rows that ** will be returned by the strategy. ** ** The xBestIndex method may optionally populate the idxFlags field with a ** mask of SQLITE_INDEX_SCAN_* flags. One such flag is ** [SQLITE_INDEX_SCAN_HEX], which if set causes the [EXPLAIN QUERY PLAN] ** output to show the idxNum as hex instead of as decimal. Another flag is ** SQLITE_INDEX_SCAN_UNIQUE, which if set indicates that the query plan will ** return at most one row. ** ** Additionally, if xBestIndex sets the SQLITE_INDEX_SCAN_UNIQUE flag, then ** SQLite also assumes that if a call to the xUpdate() method is made as ** part of the same statement to delete or update a virtual table row and the ** implementation returns SQLITE_CONSTRAINT, then there is no need to rollback |
| ︙ | ︙ | |||
7773 7774 7775 7776 7777 7778 7779 | ** ** ^The module name is registered on the [database connection] specified ** by the first parameter. ^The name of the module is given by the ** second parameter. ^The third parameter is a pointer to ** the implementation of the [virtual table module]. ^The fourth ** parameter is an arbitrary client data pointer that is passed through ** into the [xCreate] and [xConnect] methods of the virtual table module | | | 7773 7774 7775 7776 7777 7778 7779 7780 7781 7782 7783 7784 7785 7786 7787 | ** ** ^The module name is registered on the [database connection] specified ** by the first parameter. ^The name of the module is given by the ** second parameter. ^The third parameter is a pointer to ** the implementation of the [virtual table module]. ^The fourth ** parameter is an arbitrary client data pointer that is passed through ** into the [xCreate] and [xConnect] methods of the virtual table module ** when a new virtual table is being created or reinitialized. ** ** ^The sqlite3_create_module_v2() interface has a fifth parameter which ** is a pointer to a destructor for the pClientData. ^SQLite will ** invoke the destructor function (if it is not NULL) when SQLite ** no longer needs the pClientData pointer. ^The destructor will also ** be invoked if the call to sqlite3_create_module_v2() fails. ** ^The sqlite3_create_module() |
| ︙ | ︙ | |||
7938 7939 7940 7941 7942 7943 7944 | ** and write access. ^If the flags parameter is zero, the BLOB is opened for ** read-only access. ** ** ^(On success, [SQLITE_OK] is returned and the new [BLOB handle] is stored ** in *ppBlob. Otherwise an [error code] is returned and, unless the error ** code is SQLITE_MISUSE, *ppBlob is set to NULL.)^ ^This means that, provided ** the API is not misused, it is always safe to call [sqlite3_blob_close()] | | | 7938 7939 7940 7941 7942 7943 7944 7945 7946 7947 7948 7949 7950 7951 7952 | ** and write access. ^If the flags parameter is zero, the BLOB is opened for ** read-only access. ** ** ^(On success, [SQLITE_OK] is returned and the new [BLOB handle] is stored ** in *ppBlob. Otherwise an [error code] is returned and, unless the error ** code is SQLITE_MISUSE, *ppBlob is set to NULL.)^ ^This means that, provided ** the API is not misused, it is always safe to call [sqlite3_blob_close()] ** on *ppBlob after this function returns. ** ** This function fails with SQLITE_ERROR if any of the following are true: ** <ul> ** <li> ^(Database zDb does not exist)^, ** <li> ^(Table zTable does not exist within database zDb)^, ** <li> ^(Table zTable is a WITHOUT ROWID table)^, ** <li> ^(Column zColumn does not exist)^, |
| ︙ | ︙ | |||
8058 8059 8060 8061 8062 8063 8064 | /* ** CAPI3REF: Return The Size Of An Open BLOB ** METHOD: sqlite3_blob ** ** ^Returns the size in bytes of the BLOB accessible via the ** successfully opened [BLOB handle] in its only argument. ^The | | | 8058 8059 8060 8061 8062 8063 8064 8065 8066 8067 8068 8069 8070 8071 8072 | /* ** CAPI3REF: Return The Size Of An Open BLOB ** METHOD: sqlite3_blob ** ** ^Returns the size in bytes of the BLOB accessible via the ** successfully opened [BLOB handle] in its only argument. ^The ** incremental blob I/O routines can only read or overwrite existing ** blob content; they cannot change the size of a blob. ** ** This routine only works on a [BLOB handle] which has been created ** by a prior successful call to [sqlite3_blob_open()] and which has not ** been closed by [sqlite3_blob_close()]. Passing any other pointer in ** to this routine results in undefined and probably undesirable behavior. */ |
| ︙ | ︙ | |||
8208 8209 8210 8211 8212 8213 8214 | ** [SQLITE_CONFIG_MUTEX] option of the sqlite3_config() function ** before calling sqlite3_initialize() or any other public sqlite3_ ** function that calls sqlite3_initialize(). ** ** ^The sqlite3_mutex_alloc() routine allocates a new ** mutex and returns a pointer to it. ^The sqlite3_mutex_alloc() ** routine returns NULL if it is unable to allocate the requested | | | 8208 8209 8210 8211 8212 8213 8214 8215 8216 8217 8218 8219 8220 8221 8222 | ** [SQLITE_CONFIG_MUTEX] option of the sqlite3_config() function ** before calling sqlite3_initialize() or any other public sqlite3_ ** function that calls sqlite3_initialize(). ** ** ^The sqlite3_mutex_alloc() routine allocates a new ** mutex and returns a pointer to it. ^The sqlite3_mutex_alloc() ** routine returns NULL if it is unable to allocate the requested ** mutex. The argument to sqlite3_mutex_alloc() must be one of these ** integer constants: ** ** <ul> ** <li> SQLITE_MUTEX_FAST ** <li> SQLITE_MUTEX_RECURSIVE ** <li> SQLITE_MUTEX_STATIC_MAIN ** <li> SQLITE_MUTEX_STATIC_MEM |
| ︙ | ︙ | |||
8441 8442 8443 8444 8445 8446 8447 | #define SQLITE_MUTEX_STATIC_MASTER 2 /* ** CAPI3REF: Retrieve the mutex for a database connection ** METHOD: sqlite3 ** | | | 8441 8442 8443 8444 8445 8446 8447 8448 8449 8450 8451 8452 8453 8454 8455 | #define SQLITE_MUTEX_STATIC_MASTER 2 /* ** CAPI3REF: Retrieve the mutex for a database connection ** METHOD: sqlite3 ** ** ^This interface returns a pointer to the [sqlite3_mutex] object that ** serializes access to the [database connection] given in the argument ** when the [threading mode] is Serialized. ** ^If the [threading mode] is Single-thread or Multi-thread then this ** routine returns a NULL pointer. */ SQLITE_API sqlite3_mutex *sqlite3_db_mutex(sqlite3*); |
| ︙ | ︙ | |||
8564 8565 8566 8567 8568 8569 8570 | #define SQLITE_TESTCTRL_USELONGDOUBLE 34 /* NOT USED */ #define SQLITE_TESTCTRL_LAST 34 /* Largest TESTCTRL */ /* ** CAPI3REF: SQL Keyword Checking ** ** These routines provide access to the set of SQL language keywords | | | 8564 8565 8566 8567 8568 8569 8570 8571 8572 8573 8574 8575 8576 8577 8578 | #define SQLITE_TESTCTRL_USELONGDOUBLE 34 /* NOT USED */ #define SQLITE_TESTCTRL_LAST 34 /* Largest TESTCTRL */ /* ** CAPI3REF: SQL Keyword Checking ** ** These routines provide access to the set of SQL language keywords ** recognized by SQLite. Applications can use these routines to determine ** whether or not a specific identifier needs to be escaped (for example, ** by enclosing in double-quotes) so as not to confuse the parser. ** ** The sqlite3_keyword_count() interface returns the number of distinct ** keywords understood by SQLite. ** ** The sqlite3_keyword_name(N,Z,L) interface finds the 0-based N-th keyword and |
| ︙ | ︙ | |||
8732 8733 8734 8735 8736 8737 8738 | ** ^The length returned by [sqlite3_str_length(X)] does not include the ** zero-termination byte. ** ** ^The [sqlite3_str_value(X)] method returns a pointer to the current ** content of the dynamic string under construction in X. The value ** returned by [sqlite3_str_value(X)] is managed by the sqlite3_str object X ** and might be freed or altered by any subsequent method on the same | | | 8732 8733 8734 8735 8736 8737 8738 8739 8740 8741 8742 8743 8744 8745 8746 | ** ^The length returned by [sqlite3_str_length(X)] does not include the ** zero-termination byte. ** ** ^The [sqlite3_str_value(X)] method returns a pointer to the current ** content of the dynamic string under construction in X. The value ** returned by [sqlite3_str_value(X)] is managed by the sqlite3_str object X ** and might be freed or altered by any subsequent method on the same ** [sqlite3_str] object. Applications must not use the pointer returned by ** [sqlite3_str_value(X)] after any subsequent method call on the same ** object. ^Applications may change the content of the string returned ** by [sqlite3_str_value(X)] as long as they do not write into any bytes ** outside the range of 0 to [sqlite3_str_length(X)] and do not read or ** write any byte after any subsequent sqlite3_str method call. */ SQLITE_API int sqlite3_str_errcode(sqlite3_str*); |
| ︙ | ︙ | |||
8818 8819 8820 8821 8822 8823 8824 | ** ** [[SQLITE_STATUS_PAGECACHE_OVERFLOW]] ** ^(<dt>SQLITE_STATUS_PAGECACHE_OVERFLOW</dt> ** <dd>This parameter returns the number of bytes of page cache ** allocation which could not be satisfied by the [SQLITE_CONFIG_PAGECACHE] ** buffer and where forced to overflow to [sqlite3_malloc()]. The ** returned value includes allocations that overflowed because they | | | 8818 8819 8820 8821 8822 8823 8824 8825 8826 8827 8828 8829 8830 8831 8832 | ** ** [[SQLITE_STATUS_PAGECACHE_OVERFLOW]] ** ^(<dt>SQLITE_STATUS_PAGECACHE_OVERFLOW</dt> ** <dd>This parameter returns the number of bytes of page cache ** allocation which could not be satisfied by the [SQLITE_CONFIG_PAGECACHE] ** buffer and where forced to overflow to [sqlite3_malloc()]. The ** returned value includes allocations that overflowed because they ** were too large (they were larger than the "sz" parameter to ** [SQLITE_CONFIG_PAGECACHE]) and allocations that overflowed because ** no space was left in the page cache.</dd>)^ ** ** [[SQLITE_STATUS_PAGECACHE_SIZE]] ^(<dt>SQLITE_STATUS_PAGECACHE_SIZE</dt> ** <dd>This parameter records the largest memory allocation request ** handed to the [pagecache memory allocator]. Only the value returned in the ** *pHighwater parameter to [sqlite3_status()] is of interest. |
| ︙ | ︙ | |||
8902 8903 8904 8905 8906 8907 8908 | ** [[SQLITE_DBSTATUS_LOOKASIDE_USED]] ^(<dt>SQLITE_DBSTATUS_LOOKASIDE_USED</dt> ** <dd>This parameter returns the number of lookaside memory slots currently ** checked out.</dd>)^ ** ** [[SQLITE_DBSTATUS_LOOKASIDE_HIT]] ^(<dt>SQLITE_DBSTATUS_LOOKASIDE_HIT</dt> ** <dd>This parameter returns the number of malloc attempts that were ** satisfied using lookaside memory. Only the high-water value is meaningful; | | | | | | > | | > | 8902 8903 8904 8905 8906 8907 8908 8909 8910 8911 8912 8913 8914 8915 8916 8917 8918 8919 8920 8921 8922 8923 8924 8925 8926 8927 8928 8929 8930 8931 8932 8933 8934 8935 8936 8937 8938 8939 8940 8941 8942 8943 8944 8945 8946 8947 8948 8949 8950 8951 8952 8953 8954 8955 8956 8957 8958 8959 8960 | ** [[SQLITE_DBSTATUS_LOOKASIDE_USED]] ^(<dt>SQLITE_DBSTATUS_LOOKASIDE_USED</dt> ** <dd>This parameter returns the number of lookaside memory slots currently ** checked out.</dd>)^ ** ** [[SQLITE_DBSTATUS_LOOKASIDE_HIT]] ^(<dt>SQLITE_DBSTATUS_LOOKASIDE_HIT</dt> ** <dd>This parameter returns the number of malloc attempts that were ** satisfied using lookaside memory. Only the high-water value is meaningful; ** the current value is always zero.</dd>)^ ** ** [[SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE]] ** ^(<dt>SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE</dt> ** <dd>This parameter returns the number of malloc attempts that might have ** been satisfied using lookaside memory but failed due to the amount of ** memory requested being larger than the lookaside slot size. ** Only the high-water value is meaningful; ** the current value is always zero.</dd>)^ ** ** [[SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL]] ** ^(<dt>SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL</dt> ** <dd>This parameter returns the number of malloc attempts that might have ** been satisfied using lookaside memory but failed due to all lookaside ** memory already being in use. ** Only the high-water value is meaningful; ** the current value is always zero.</dd>)^ ** ** [[SQLITE_DBSTATUS_CACHE_USED]] ^(<dt>SQLITE_DBSTATUS_CACHE_USED</dt> ** <dd>This parameter returns the approximate number of bytes of heap ** memory used by all pager caches associated with the database connection.)^ ** ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_USED is always 0. ** </dd> ** ** [[SQLITE_DBSTATUS_CACHE_USED_SHARED]] ** ^(<dt>SQLITE_DBSTATUS_CACHE_USED_SHARED</dt> ** <dd>This parameter is similar to DBSTATUS_CACHE_USED, except that if a ** pager cache is shared between two or more connections the bytes of heap ** memory used by that pager cache is divided evenly between the attached ** connections.)^ In other words, if none of the pager caches associated ** with the database connection are shared, this request returns the same ** value as DBSTATUS_CACHE_USED. Or, if one or more of the pager caches are ** shared, the value returned by this call will be smaller than that returned ** by DBSTATUS_CACHE_USED. ^The highwater mark associated with ** SQLITE_DBSTATUS_CACHE_USED_SHARED is always 0.</dd> ** ** [[SQLITE_DBSTATUS_SCHEMA_USED]] ^(<dt>SQLITE_DBSTATUS_SCHEMA_USED</dt> ** <dd>This parameter returns the approximate number of bytes of heap ** memory used to store the schema for all databases associated ** with the connection - main, temp, and any [ATTACH]-ed databases.)^ ** ^The full amount of memory used by the schemas is reported, even if the ** schema memory is shared with other database connections due to ** [shared cache mode] being enabled. ** ^The highwater mark associated with SQLITE_DBSTATUS_SCHEMA_USED is always 0. ** </dd> ** ** [[SQLITE_DBSTATUS_STMT_USED]] ^(<dt>SQLITE_DBSTATUS_STMT_USED</dt> ** <dd>This parameter returns the approximate number of bytes of heap ** and lookaside memory used by all prepared statements associated with ** the database connection.)^ ** ^The highwater mark associated with SQLITE_DBSTATUS_STMT_USED is always 0. ** </dd> |
| ︙ | ︙ | |||
8981 8982 8983 8984 8985 8986 8987 | ** </dd> ** ** [[SQLITE_DBSTATUS_CACHE_SPILL]] ^(<dt>SQLITE_DBSTATUS_CACHE_SPILL</dt> ** <dd>This parameter returns the number of dirty cache entries that have ** been written to disk in the middle of a transaction due to the page ** cache overflowing. Transactions are more efficient if they are written ** to disk all at once. When pages spill mid-transaction, that introduces | | | 8983 8984 8985 8986 8987 8988 8989 8990 8991 8992 8993 8994 8995 8996 8997 | ** </dd> ** ** [[SQLITE_DBSTATUS_CACHE_SPILL]] ^(<dt>SQLITE_DBSTATUS_CACHE_SPILL</dt> ** <dd>This parameter returns the number of dirty cache entries that have ** been written to disk in the middle of a transaction due to the page ** cache overflowing. Transactions are more efficient if they are written ** to disk all at once. When pages spill mid-transaction, that introduces ** additional overhead. This parameter can be used to help identify ** inefficiencies that can be resolved by increasing the cache size. ** </dd> ** ** [[SQLITE_DBSTATUS_DEFERRED_FKS]] ^(<dt>SQLITE_DBSTATUS_DEFERRED_FKS</dt> ** <dd>This parameter returns zero for the current value if and only if ** all foreign key constraints (deferred or immediate) have been ** resolved.)^ ^The highwater mark is always 0. |
| ︙ | ︙ | |||
9052 9053 9054 9055 9056 9057 9058 | ** a table as part of a full table scan. Large numbers for this counter ** may indicate opportunities for performance improvement through ** careful use of indices.</dd> ** ** [[SQLITE_STMTSTATUS_SORT]] <dt>SQLITE_STMTSTATUS_SORT</dt> ** <dd>^This is the number of sort operations that have occurred. ** A non-zero value in this counter may indicate an opportunity to | | | | | | | | 9054 9055 9056 9057 9058 9059 9060 9061 9062 9063 9064 9065 9066 9067 9068 9069 9070 9071 9072 9073 9074 9075 9076 9077 9078 9079 9080 9081 9082 9083 9084 9085 9086 9087 9088 9089 9090 9091 9092 9093 9094 9095 9096 9097 9098 9099 9100 9101 9102 9103 9104 9105 | ** a table as part of a full table scan. Large numbers for this counter ** may indicate opportunities for performance improvement through ** careful use of indices.</dd> ** ** [[SQLITE_STMTSTATUS_SORT]] <dt>SQLITE_STMTSTATUS_SORT</dt> ** <dd>^This is the number of sort operations that have occurred. ** A non-zero value in this counter may indicate an opportunity to ** improve performance through careful use of indices.</dd> ** ** [[SQLITE_STMTSTATUS_AUTOINDEX]] <dt>SQLITE_STMTSTATUS_AUTOINDEX</dt> ** <dd>^This is the number of rows inserted into transient indices that ** were created automatically in order to help joins run faster. ** A non-zero value in this counter may indicate an opportunity to ** improve performance by adding permanent indices that do not ** need to be reinitialized each time the statement is run.</dd> ** ** [[SQLITE_STMTSTATUS_VM_STEP]] <dt>SQLITE_STMTSTATUS_VM_STEP</dt> ** <dd>^This is the number of virtual machine operations executed ** by the prepared statement if that number is less than or equal ** to 2147483647. The number of virtual machine operations can be ** used as a proxy for the total work done by the prepared statement. ** If the number of virtual machine operations exceeds 2147483647 ** then the value returned by this statement status code is undefined.</dd> ** ** [[SQLITE_STMTSTATUS_REPREPARE]] <dt>SQLITE_STMTSTATUS_REPREPARE</dt> ** <dd>^This is the number of times that the prepare statement has been ** automatically regenerated due to schema changes or changes to ** [bound parameters] that might affect the query plan.</dd> ** ** [[SQLITE_STMTSTATUS_RUN]] <dt>SQLITE_STMTSTATUS_RUN</dt> ** <dd>^This is the number of times that the prepared statement has ** been run. A single "run" for the purposes of this counter is one ** or more calls to [sqlite3_step()] followed by a call to [sqlite3_reset()]. ** The counter is incremented on the first [sqlite3_step()] call of each ** cycle.</dd> ** ** [[SQLITE_STMTSTATUS_FILTER_MISS]] ** [[SQLITE_STMTSTATUS_FILTER HIT]] ** <dt>SQLITE_STMTSTATUS_FILTER_HIT<br> ** SQLITE_STMTSTATUS_FILTER_MISS</dt> ** <dd>^SQLITE_STMTSTATUS_FILTER_HIT is the number of times that a join ** step was bypassed because a Bloom filter returned not-found. The ** corresponding SQLITE_STMTSTATUS_FILTER_MISS value is the number of ** times that the Bloom filter returned a find, and thus the join step ** had to be processed as normal.</dd> ** ** [[SQLITE_STMTSTATUS_MEMUSED]] <dt>SQLITE_STMTSTATUS_MEMUSED</dt> ** <dd>^This is the approximate number of bytes of heap memory ** used to store the prepared statement. ^This value is not actually ** a counter, and so the resetFlg parameter to sqlite3_stmt_status() ** is ignored when the opcode is SQLITE_STMTSTATUS_MEMUSED. ** </dd> |
| ︙ | ︙ | |||
9194 9195 9196 9197 9198 9199 9200 | ** call to xShutdown(). ** ** [[the xCreate() page cache methods]] ** ^SQLite invokes the xCreate() method to construct a new cache instance. ** SQLite will typically create one cache instance for each open database file, ** though this is not guaranteed. ^The ** first parameter, szPage, is the size in bytes of the pages that must | | | | | | | 9196 9197 9198 9199 9200 9201 9202 9203 9204 9205 9206 9207 9208 9209 9210 9211 9212 9213 9214 9215 9216 9217 9218 9219 9220 9221 9222 9223 9224 9225 9226 9227 9228 9229 9230 | ** call to xShutdown(). ** ** [[the xCreate() page cache methods]] ** ^SQLite invokes the xCreate() method to construct a new cache instance. ** SQLite will typically create one cache instance for each open database file, ** though this is not guaranteed. ^The ** first parameter, szPage, is the size in bytes of the pages that must ** be allocated by the cache. ^szPage will always be a power of two. ^The ** second parameter szExtra is a number of bytes of extra storage ** associated with each page cache entry. ^The szExtra parameter will be ** a number less than 250. SQLite will use the ** extra szExtra bytes on each page to store metadata about the underlying ** database page on disk. The value passed into szExtra depends ** on the SQLite version, the target platform, and how SQLite was compiled. ** ^The third argument to xCreate(), bPurgeable, is true if the cache being ** created will be used to cache database pages of a file stored on disk, or ** false if it is used for an in-memory database. The cache implementation ** does not have to do anything special based upon the value of bPurgeable; ** it is purely advisory. ^On a cache where bPurgeable is false, SQLite will ** never invoke xUnpin() except to deliberately delete a page. ** ^In other words, calls to xUnpin() on a cache with bPurgeable set to ** false will always have the "discard" flag set to true. ** ^Hence, a cache created with bPurgeable set to false will ** never contain any unpinned pages. ** ** [[the xCachesize() page cache method]] ** ^(The xCachesize() method may be called at any time by SQLite to set the ** suggested maximum cache-size (number of pages stored) for the cache ** instance passed as the first argument. This is the value configured using ** the SQLite "[PRAGMA cache_size]" command.)^ As with the bPurgeable ** parameter, the implementation is not required to do anything with this ** value; it is advisory only. ** ** [[the xPagecount() page cache methods]] ** The xPagecount() method must return the number of pages currently |
| ︙ | ︙ | |||
9241 9242 9243 9244 9245 9246 9247 | ** is 1. After it has been retrieved using xFetch, the page is considered ** to be "pinned". ** ** If the requested page is already in the page cache, then the page cache ** implementation must return a pointer to the page buffer with its content ** intact. If the requested page is not already in the cache, then the ** cache implementation should use the value of the createFlag | | | | | | 9243 9244 9245 9246 9247 9248 9249 9250 9251 9252 9253 9254 9255 9256 9257 9258 9259 9260 9261 9262 9263 9264 9265 9266 9267 9268 9269 9270 9271 9272 9273 9274 9275 9276 9277 9278 9279 9280 9281 9282 9283 9284 9285 9286 9287 9288 9289 9290 9291 9292 9293 9294 9295 9296 9297 | ** is 1. After it has been retrieved using xFetch, the page is considered ** to be "pinned". ** ** If the requested page is already in the page cache, then the page cache ** implementation must return a pointer to the page buffer with its content ** intact. If the requested page is not already in the cache, then the ** cache implementation should use the value of the createFlag ** parameter to help it determine what action to take: ** ** <table border=1 width=85% align=center> ** <tr><th> createFlag <th> Behavior when page is not already in cache ** <tr><td> 0 <td> Do not allocate a new page. Return NULL. ** <tr><td> 1 <td> Allocate a new page if it is easy and convenient to do so. ** Otherwise return NULL. ** <tr><td> 2 <td> Make every effort to allocate a new page. Only return ** NULL if allocating a new page is effectively impossible. ** </table> ** ** ^(SQLite will normally invoke xFetch() with a createFlag of 0 or 1. SQLite ** will only use a createFlag of 2 after a prior call with a createFlag of 1 ** failed.)^ In between the xFetch() calls, SQLite may ** attempt to unpin one or more cache pages by spilling the content of ** pinned pages to disk and synching the operating system disk cache. ** ** [[the xUnpin() page cache method]] ** ^xUnpin() is called by SQLite with a pointer to a currently pinned page ** as its second argument. If the third parameter, discard, is non-zero, ** then the page must be evicted from the cache. ** ^If the discard parameter is ** zero, then the page may be discarded or retained at the discretion of the ** page cache implementation. ^The page cache implementation ** may choose to evict unpinned pages at any time. ** ** The cache must not perform any reference counting. A single ** call to xUnpin() unpins the page regardless of the number of prior calls ** to xFetch(). ** ** [[the xRekey() page cache methods]] ** The xRekey() method is used to change the key value associated with the ** page passed as the second argument. If the cache ** previously contains an entry associated with newKey, it must be ** discarded. ^Any prior cache entry associated with newKey is guaranteed not ** to be pinned. ** ** When SQLite calls the xTruncate() method, the cache must discard all ** existing cache entries with page numbers (keys) greater than or equal ** to the value of the iLimit parameter passed to xTruncate(). If any ** of these pages are pinned, they become implicitly unpinned, meaning that ** they can be safely discarded. ** ** [[the xDestroy() page cache method]] ** ^The xDestroy() method is used to delete a cache allocated by xCreate(). ** All resources associated with the specified cache should be freed. ^After ** calling the xDestroy() method, SQLite considers the [sqlite3_pcache*] ** handle invalid, and will not use it with any other sqlite3_pcache_methods2 |
| ︙ | ︙ | |||
9461 9462 9463 9464 9465 9466 9467 | ** lasts for the duration of the sqlite3_backup_step() call. ** ^Because the source database is not locked between calls to ** sqlite3_backup_step(), the source database may be modified mid-way ** through the backup process. ^If the source database is modified by an ** external process or via a database connection other than the one being ** used by the backup operation, then the backup will be automatically ** restarted by the next call to sqlite3_backup_step(). ^If the source | | | | 9463 9464 9465 9466 9467 9468 9469 9470 9471 9472 9473 9474 9475 9476 9477 9478 9479 9480 9481 9482 9483 9484 9485 9486 9487 9488 9489 9490 9491 9492 9493 9494 | ** lasts for the duration of the sqlite3_backup_step() call. ** ^Because the source database is not locked between calls to ** sqlite3_backup_step(), the source database may be modified mid-way ** through the backup process. ^If the source database is modified by an ** external process or via a database connection other than the one being ** used by the backup operation, then the backup will be automatically ** restarted by the next call to sqlite3_backup_step(). ^If the source ** database is modified by using the same database connection as is used ** by the backup operation, then the backup database is automatically ** updated at the same time. ** ** [[sqlite3_backup_finish()]] <b>sqlite3_backup_finish()</b> ** ** When sqlite3_backup_step() has returned [SQLITE_DONE], or when the ** application wishes to abandon the backup operation, the application ** should destroy the [sqlite3_backup] by passing it to sqlite3_backup_finish(). ** ^The sqlite3_backup_finish() interfaces releases all ** resources associated with the [sqlite3_backup] object. ** ^If sqlite3_backup_step() has not yet returned [SQLITE_DONE], then any ** active write-transaction on the destination database is rolled back. ** The [sqlite3_backup] object is invalid ** and may not be used following a call to sqlite3_backup_finish(). ** ** ^The value returned by sqlite3_backup_finish is [SQLITE_OK] if no ** sqlite3_backup_step() errors occurred, regardless of whether or not ** sqlite3_backup_step() completed. ** ^If an out-of-memory condition or IO error occurred during any prior ** sqlite3_backup_step() call on the same [sqlite3_backup] object, then ** sqlite3_backup_finish() returns the corresponding [error code]. ** ** ^A return of [SQLITE_BUSY] or [SQLITE_LOCKED] from sqlite3_backup_step() ** is not a permanent error and does not affect the return value of |
| ︙ | ︙ | |||
9580 9581 9582 9583 9584 9585 9586 | ** ^When a connection (known as the blocked connection) fails to obtain a ** shared-cache lock and SQLITE_LOCKED is returned to the caller, the ** identity of the database connection (the blocking connection) that ** has locked the required resource is stored internally. ^After an ** application receives an SQLITE_LOCKED error, it may call the ** sqlite3_unlock_notify() method with the blocked connection handle as ** the first argument to register for a callback that will be invoked | | | | 9582 9583 9584 9585 9586 9587 9588 9589 9590 9591 9592 9593 9594 9595 9596 9597 9598 9599 9600 9601 9602 9603 9604 9605 9606 9607 9608 9609 9610 9611 9612 9613 9614 9615 9616 | ** ^When a connection (known as the blocked connection) fails to obtain a ** shared-cache lock and SQLITE_LOCKED is returned to the caller, the ** identity of the database connection (the blocking connection) that ** has locked the required resource is stored internally. ^After an ** application receives an SQLITE_LOCKED error, it may call the ** sqlite3_unlock_notify() method with the blocked connection handle as ** the first argument to register for a callback that will be invoked ** when the blocking connection's current transaction is concluded. ^The ** callback is invoked from within the [sqlite3_step] or [sqlite3_close] ** call that concludes the blocking connection's transaction. ** ** ^(If sqlite3_unlock_notify() is called in a multi-threaded application, ** there is a chance that the blocking connection will have already ** concluded its transaction by the time sqlite3_unlock_notify() is invoked. ** If this happens, then the specified callback is invoked immediately, ** from within the call to sqlite3_unlock_notify().)^ ** ** ^If the blocked connection is attempting to obtain a write-lock on a ** shared-cache table, and more than one other connection currently holds ** a read-lock on the same table, then SQLite arbitrarily selects one of ** the other connections to use as the blocking connection. ** ** ^(There may be at most one unlock-notify callback registered by a ** blocked connection. If sqlite3_unlock_notify() is called when the ** blocked connection already has a registered unlock-notify callback, ** then the new callback replaces the old.)^ ^If sqlite3_unlock_notify() is ** called with a NULL pointer as its second argument, then any existing ** unlock-notify callback is canceled. ^The blocked connection's ** unlock-notify callback may also be canceled by closing the blocked ** connection using [sqlite3_close()]. ** ** The unlock-notify callback is not reentrant. If an application invokes ** any sqlite3_xxx API functions from within an unlock-notify callback, a ** crash or deadlock may be the result. ** |
| ︙ | ︙ | |||
9998 9999 10000 10001 10002 10003 10004 | ** <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 | | | 10000 10001 10002 10003 10004 10005 10006 10007 10008 10009 10010 10011 10012 10013 10014 | ** <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 user's 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 |
| ︙ | ︙ | |||
10032 10033 10034 10035 10036 10037 10038 | ** prohibits that virtual table from being used from within triggers and ** views. ** </dd> ** ** [[SQLITE_VTAB_INNOCUOUS]]<dt>SQLITE_VTAB_INNOCUOUS</dt> ** <dd>Calls of the form ** [sqlite3_vtab_config](db,SQLITE_VTAB_INNOCUOUS) from within the | | | 10034 10035 10036 10037 10038 10039 10040 10041 10042 10043 10044 10045 10046 10047 10048 | ** prohibits that virtual table from being used from within triggers and ** views. ** </dd> ** ** [[SQLITE_VTAB_INNOCUOUS]]<dt>SQLITE_VTAB_INNOCUOUS</dt> ** <dd>Calls of the form ** [sqlite3_vtab_config](db,SQLITE_VTAB_INNOCUOUS) from within the ** [xConnect] or [xCreate] methods of a [virtual table] implementation ** identify that virtual table as being safe to use from within triggers ** and views. Conceptually, the SQLITE_VTAB_INNOCUOUS tag means that the ** virtual table can do no serious harm even if it is controlled by a ** malicious hacker. Developers should avoid setting the SQLITE_VTAB_INNOCUOUS ** flag unless absolutely necessary. ** </dd> ** |
| ︙ | ︙ | |||
10200 10201 10202 10203 10204 10205 10206 | ** <tr><td>0<td>yes<td>yes<td>no ** <tr><td>1<td>no<td>yes<td>no ** <tr><td>2<td>no<td>yes<td>yes ** <tr><td>3<td>yes<td>yes<td>yes ** </table> ** ** ^For the purposes of comparing virtual table output values to see if the | | | | 10202 10203 10204 10205 10206 10207 10208 10209 10210 10211 10212 10213 10214 10215 10216 10217 10218 10219 10220 10221 10222 10223 10224 10225 10226 | ** <tr><td>0<td>yes<td>yes<td>no ** <tr><td>1<td>no<td>yes<td>no ** <tr><td>2<td>no<td>yes<td>yes ** <tr><td>3<td>yes<td>yes<td>yes ** </table> ** ** ^For the purposes of comparing virtual table output values to see if the ** values are the same value for sorting purposes, two NULL values are considered ** to be the same. In other words, the comparison operator is "IS" ** (or "IS NOT DISTINCT FROM") and not "==". ** ** If a virtual table implementation is unable to meet the requirements ** specified above, then it must not set the "orderByConsumed" flag in the ** [sqlite3_index_info] object or an incorrect answer may result. ** ** ^A virtual table implementation is always free to return rows in any order ** it wants, as long as the "orderByConsumed" flag is not set. ^When the ** "orderByConsumed" flag is unset, the query planner will add extra ** [bytecode] to ensure that the final results returned by the SQL query are ** ordered correctly. The use of the "orderByConsumed" flag and the ** sqlite3_vtab_distinct() interface is merely an optimization. ^Careful ** use of the sqlite3_vtab_distinct() interface and the "orderByConsumed" ** flag might help queries against a virtual table to run faster. Being ** overly aggressive and setting the "orderByConsumed" flag when it is not ** valid to do so, on the other hand, might cause SQLite to return incorrect |
| ︙ | ︙ | |||
10307 10308 10309 10310 10311 10312 10313 | ** The result of invoking these interfaces from any other context ** is undefined and probably harmful. ** ** The X parameter in a call to sqlite3_vtab_in_first(X,P) or ** sqlite3_vtab_in_next(X,P) should be one of the parameters to the ** xFilter method which invokes these routines, and specifically ** a parameter that was previously selected for all-at-once IN constraint | | | 10309 10310 10311 10312 10313 10314 10315 10316 10317 10318 10319 10320 10321 10322 10323 | ** The result of invoking these interfaces from any other context ** is undefined and probably harmful. ** ** The X parameter in a call to sqlite3_vtab_in_first(X,P) or ** sqlite3_vtab_in_next(X,P) should be one of the parameters to the ** xFilter method which invokes these routines, and specifically ** a parameter that was previously selected for all-at-once IN constraint ** processing using the [sqlite3_vtab_in()] interface in the ** [xBestIndex|xBestIndex method]. ^(If the X parameter is not ** an xFilter argument that was selected for all-at-once IN constraint ** processing, then these routines return [SQLITE_ERROR].)^ ** ** ^(Use these routines to access all values on the right-hand side ** of the IN constraint using code like the following: ** |
| ︙ | ︙ | |||
10362 10363 10364 10365 10366 10367 10368 | ** attempts to set *V to the value of the right-hand operand of ** that constraint if the right-hand operand is known. ^If the ** right-hand operand is not known, then *V is set to a NULL pointer. ** ^The sqlite3_vtab_rhs_value(P,J,V) interface returns SQLITE_OK if ** and only if *V is set to a value. ^The sqlite3_vtab_rhs_value(P,J,V) ** inteface returns SQLITE_NOTFOUND if the right-hand side of the J-th ** constraint is not available. ^The sqlite3_vtab_rhs_value() interface | | | 10364 10365 10366 10367 10368 10369 10370 10371 10372 10373 10374 10375 10376 10377 10378 | ** attempts to set *V to the value of the right-hand operand of ** that constraint if the right-hand operand is known. ^If the ** right-hand operand is not known, then *V is set to a NULL pointer. ** ^The sqlite3_vtab_rhs_value(P,J,V) interface returns SQLITE_OK if ** and only if *V is set to a value. ^The sqlite3_vtab_rhs_value(P,J,V) ** inteface returns SQLITE_NOTFOUND if the right-hand side of the J-th ** constraint is not available. ^The sqlite3_vtab_rhs_value() interface ** can return a result code other than SQLITE_OK or SQLITE_NOTFOUND if ** something goes wrong. ** ** The sqlite3_vtab_rhs_value() interface is usually only successful if ** the right-hand operand of a constraint is a literal value in the original ** SQL statement. If the right-hand operand is an expression or a reference ** to some other column or a [host parameter], then sqlite3_vtab_rhs_value() ** will probably return [SQLITE_NOTFOUND]. |
| ︙ | ︙ | |||
10390 10391 10392 10393 10394 10395 10396 |
SQLITE_API int sqlite3_vtab_rhs_value(sqlite3_index_info*, int, sqlite3_value **ppVal);
/*
** CAPI3REF: Conflict resolution modes
** KEYWORDS: {conflict resolution mode}
**
** These constants are returned by [sqlite3_vtab_on_conflict()] to
| | | | 10392 10393 10394 10395 10396 10397 10398 10399 10400 10401 10402 10403 10404 10405 10406 10407 |
SQLITE_API int sqlite3_vtab_rhs_value(sqlite3_index_info*, int, sqlite3_value **ppVal);
/*
** CAPI3REF: Conflict resolution modes
** KEYWORDS: {conflict resolution mode}
**
** These constants are returned by [sqlite3_vtab_on_conflict()] to
** inform a [virtual table] implementation of the [ON CONFLICT] mode
** for the SQL statement being evaluated.
**
** Note that the [SQLITE_IGNORE] constant is also used as a potential
** return value from the [sqlite3_set_authorizer()] callback and that
** [SQLITE_ABORT] is also a [result code].
*/
#define SQLITE_ROLLBACK 1
/* #define SQLITE_IGNORE 2 // Also used by sqlite3_authorizer() callback */
|
| ︙ | ︙ | |||
10431 10432 10433 10434 10435 10436 10437 | ** [[SQLITE_SCANSTAT_NVISIT]] <dt>SQLITE_SCANSTAT_NVISIT</dt> ** <dd>^The [sqlite3_int64] variable pointed to by the V parameter will be set ** to the total number of rows examined by all iterations of the X-th loop.</dd> ** ** [[SQLITE_SCANSTAT_EST]] <dt>SQLITE_SCANSTAT_EST</dt> ** <dd>^The "double" variable pointed to by the V parameter will be set to the ** query planner's estimate for the average number of rows output from each | | | | | | | | | | 10433 10434 10435 10436 10437 10438 10439 10440 10441 10442 10443 10444 10445 10446 10447 10448 10449 10450 10451 10452 10453 10454 10455 10456 10457 10458 10459 10460 10461 10462 10463 10464 10465 10466 10467 10468 10469 10470 10471 10472 10473 10474 10475 10476 10477 10478 10479 | ** [[SQLITE_SCANSTAT_NVISIT]] <dt>SQLITE_SCANSTAT_NVISIT</dt> ** <dd>^The [sqlite3_int64] variable pointed to by the V parameter will be set ** to the total number of rows examined by all iterations of the X-th loop.</dd> ** ** [[SQLITE_SCANSTAT_EST]] <dt>SQLITE_SCANSTAT_EST</dt> ** <dd>^The "double" variable pointed to by the V parameter will be set to the ** query planner's estimate for the average number of rows output from each ** iteration of the X-th loop. If the query planner's estimate was accurate, ** then this value will approximate the quotient NVISIT/NLOOP and the ** product of this value for all prior loops with the same SELECTID will ** be the NLOOP value for the current loop.</dd> ** ** [[SQLITE_SCANSTAT_NAME]] <dt>SQLITE_SCANSTAT_NAME</dt> ** <dd>^The "const char *" variable pointed to by the V parameter will be set ** to a zero-terminated UTF-8 string containing the name of the index or table ** used for the X-th loop.</dd> ** ** [[SQLITE_SCANSTAT_EXPLAIN]] <dt>SQLITE_SCANSTAT_EXPLAIN</dt> ** <dd>^The "const char *" variable pointed to by the V parameter will be set ** to a zero-terminated UTF-8 string containing the [EXPLAIN QUERY PLAN] ** description for the X-th loop.</dd> ** ** [[SQLITE_SCANSTAT_SELECTID]] <dt>SQLITE_SCANSTAT_SELECTID</dt> ** <dd>^The "int" variable pointed to by the V parameter will be set to the ** id for the X-th query plan element. The id value is unique within the ** statement. The select-id is the same value as is output in the first ** column of an [EXPLAIN QUERY PLAN] query.</dd> ** ** [[SQLITE_SCANSTAT_PARENTID]] <dt>SQLITE_SCANSTAT_PARENTID</dt> ** <dd>The "int" variable pointed to by the V parameter will be set to the ** id of the parent of the current query element, if applicable, or ** to zero if the query element has no parent. This is the same value as ** returned in the second column of an [EXPLAIN QUERY PLAN] query.</dd> ** ** [[SQLITE_SCANSTAT_NCYCLE]] <dt>SQLITE_SCANSTAT_NCYCLE</dt> ** <dd>The sqlite3_int64 output value is set to the number of cycles, ** according to the processor time-stamp counter, that elapsed while the ** query element was being processed. This value is not available for ** all query elements - if it is unavailable the output variable is ** set to -1.</dd> ** </dl> */ #define SQLITE_SCANSTAT_NLOOP 0 #define SQLITE_SCANSTAT_NVISIT 1 #define SQLITE_SCANSTAT_EST 2 #define SQLITE_SCANSTAT_NAME 3 #define SQLITE_SCANSTAT_EXPLAIN 4 |
| ︙ | ︙ | |||
10504 10505 10506 10507 10508 10509 10510 | ** SQLITE_SCANSTAT_COMPLEX is not specified, then only query plan elements ** that correspond to query loops (the "SCAN..." and "SEARCH..." elements of ** the EXPLAIN QUERY PLAN output) are available. Invoking API ** sqlite3_stmt_scanstatus() is equivalent to calling ** sqlite3_stmt_scanstatus_v2() with a zeroed flags parameter. ** ** Parameter "idx" identifies the specific query element to retrieve statistics | | | | 10506 10507 10508 10509 10510 10511 10512 10513 10514 10515 10516 10517 10518 10519 10520 10521 | ** SQLITE_SCANSTAT_COMPLEX is not specified, then only query plan elements ** that correspond to query loops (the "SCAN..." and "SEARCH..." elements of ** the EXPLAIN QUERY PLAN output) are available. Invoking API ** sqlite3_stmt_scanstatus() is equivalent to calling ** sqlite3_stmt_scanstatus_v2() with a zeroed flags parameter. ** ** Parameter "idx" identifies the specific query element to retrieve statistics ** for. Query elements are numbered starting from zero. A value of -1 may ** retrieve statistics for the entire query. ^If idx is out of range ** - less than -1 or greater than or equal to the total number of query ** elements used to implement the statement - a non-zero value is returned and ** the variable that pOut points to is unchanged. ** ** See also: [sqlite3_stmt_scanstatus_reset()] */ SQLITE_API int sqlite3_stmt_scanstatus( |
| ︙ | ︙ | |||
10548 10549 10550 10551 10552 10553 10554 | SQLITE_API void sqlite3_stmt_scanstatus_reset(sqlite3_stmt*); /* ** CAPI3REF: Flush caches to disk mid-transaction ** METHOD: sqlite3 ** ** ^If a write-transaction is open on [database connection] D when the | | | 10550 10551 10552 10553 10554 10555 10556 10557 10558 10559 10560 10561 10562 10563 10564 | SQLITE_API void sqlite3_stmt_scanstatus_reset(sqlite3_stmt*); /* ** CAPI3REF: Flush caches to disk mid-transaction ** METHOD: sqlite3 ** ** ^If a write-transaction is open on [database connection] D when the ** [sqlite3_db_cacheflush(D)] interface is invoked, any dirty ** pages in the pager-cache that are not currently in use are written out ** to disk. A dirty page may be in use if a database cursor created by an ** active SQL statement is reading from it, or if it is page 1 of a database ** file (page 1 is always "in use"). ^The [sqlite3_db_cacheflush(D)] ** interface flushes caches for all schemas - "main", "temp", and ** any [attached] databases. ** |
| ︙ | ︙ | |||
10662 10663 10664 10665 10666 10667 10668 | ** ^The [sqlite3_preupdate_depth(D)] interface returns 0 if the preupdate ** callback was invoked as a result of a direct insert, update, or delete ** operation; or 1 for inserts, updates, or deletes invoked by top-level ** triggers; or 2 for changes resulting from triggers called by top-level ** triggers; and so forth. ** ** When the [sqlite3_blob_write()] API is used to update a blob column, | | | | 10664 10665 10666 10667 10668 10669 10670 10671 10672 10673 10674 10675 10676 10677 10678 10679 | ** ^The [sqlite3_preupdate_depth(D)] interface returns 0 if the preupdate ** callback was invoked as a result of a direct insert, update, or delete ** operation; or 1 for inserts, updates, or deletes invoked by top-level ** triggers; or 2 for changes resulting from triggers called by top-level ** triggers; and so forth. ** ** When the [sqlite3_blob_write()] API is used to update a blob column, ** the pre-update hook is invoked with SQLITE_DELETE, because ** the new values are not yet available. In this case, when a ** callback made with op==SQLITE_DELETE is actually a write using the ** sqlite3_blob_write() API, the [sqlite3_preupdate_blobwrite()] returns ** the index of the column being written. In other cases, where the ** pre-update hook is being invoked for some other reason, including a ** regular DELETE, sqlite3_preupdate_blobwrite() returns -1. ** ** See also: [sqlite3_update_hook()] |
| ︙ | ︙ | |||
10916 10917 10918 10919 10920 10921 10922 | ** [database connection] D. If S is a NULL pointer, the main database is used. ** If P is not a NULL pointer, then the size of the database in bytes ** is written into *P. ** ** For an ordinary on-disk database file, the serialization is just a ** copy of the disk file. For an in-memory database or a "TEMP" database, ** the serialization is the same sequence of bytes which would be written | | | | 10918 10919 10920 10921 10922 10923 10924 10925 10926 10927 10928 10929 10930 10931 10932 10933 10934 10935 10936 10937 10938 10939 10940 10941 | ** [database connection] D. If S is a NULL pointer, the main database is used. ** If P is not a NULL pointer, then the size of the database in bytes ** is written into *P. ** ** For an ordinary on-disk database file, the serialization is just a ** copy of the disk file. For an in-memory database or a "TEMP" database, ** the serialization is the same sequence of bytes which would be written ** to disk if that database were backed up to disk. ** ** The usual case is that sqlite3_serialize() copies the serialization of ** the database into memory obtained from [sqlite3_malloc64()] and returns ** a pointer to that memory. The caller is responsible for freeing the ** returned value to avoid a memory leak. However, if the F argument ** contains the SQLITE_SERIALIZE_NOCOPY bit, then no memory allocations ** are made, and the sqlite3_serialize() function will return a pointer ** to the contiguous memory representation of the database that SQLite ** is currently using for that database, or NULL if no such contiguous ** memory representation of the database exists. A contiguous memory ** representation of the database will usually only exist if there has ** been a prior call to [sqlite3_deserialize(D,S,...)] with the same ** values of D and S. ** The size of the database is written into *P even if the ** SQLITE_SERIALIZE_NOCOPY bit is set but no contiguous copy ** of the database exists. |
| ︙ | ︙ | |||
10996 10997 10998 10999 11000 11001 11002 | ** Applications must not modify the buffer P or invalidate it before ** the database connection D is closed. ** ** The sqlite3_deserialize() interface will fail with SQLITE_BUSY if the ** database is currently in a read transaction or is involved in a backup ** operation. ** | | | 10998 10999 11000 11001 11002 11003 11004 11005 11006 11007 11008 11009 11010 11011 11012 | ** Applications must not modify the buffer P or invalidate it before ** the database connection D is closed. ** ** The sqlite3_deserialize() interface will fail with SQLITE_BUSY if the ** database is currently in a read transaction or is involved in a backup ** operation. ** ** It is not possible to deserialize into the TEMP database. If the ** S argument to sqlite3_deserialize(D,S,P,N,M,F) is "temp" then the ** function returns SQLITE_ERROR. ** ** The deserialized database should not be in [WAL mode]. If the database ** is in WAL mode, then any attempt to use the database file will result ** in an [SQLITE_CANTOPEN] error. The application can set the ** [file format version numbers] (bytes 18 and 19) of the input database P |
| ︙ | ︙ | |||
11018 11019 11020 11021 11022 11023 11024 | ** This interface is omitted if SQLite is compiled with the ** [SQLITE_OMIT_DESERIALIZE] option. */ SQLITE_API int sqlite3_deserialize( sqlite3 *db, /* The database connection */ const char *zSchema, /* Which DB to reopen with the deserialization */ unsigned char *pData, /* The serialized database content */ | | | | 11020 11021 11022 11023 11024 11025 11026 11027 11028 11029 11030 11031 11032 11033 11034 11035 11036 11037 11038 11039 11040 11041 11042 | ** This interface is omitted if SQLite is compiled with the ** [SQLITE_OMIT_DESERIALIZE] option. */ SQLITE_API int sqlite3_deserialize( sqlite3 *db, /* The database connection */ const char *zSchema, /* Which DB to reopen with the deserialization */ unsigned char *pData, /* The serialized database content */ sqlite3_int64 szDb, /* Number of bytes in the deserialization */ sqlite3_int64 szBuf, /* Total size of buffer pData[] */ unsigned mFlags /* Zero or more SQLITE_DESERIALIZE_* flags */ ); /* ** CAPI3REF: Flags for sqlite3_deserialize() ** ** The following are allowed values for the 6th argument (the F argument) to ** the [sqlite3_deserialize(D,S,P,N,M,F)] interface. ** ** The SQLITE_DESERIALIZE_FREEONCLOSE means that the database serialization ** in the P argument is held in memory obtained from [sqlite3_malloc64()] ** and that SQLite should take ownership of this memory and automatically ** free it when it has finished using it. Without this flag, the caller ** is responsible for freeing any dynamically allocated memory. |
| ︙ | ︙ | |||
11551 11552 11553 11554 11555 11556 11557 | ** When a session object is disabled (see the [sqlite3session_enable()] API), ** it does not accumulate records when rows are inserted, updated or deleted. ** This may appear to have some counter-intuitive effects if a single row ** is written to more than once during a session. For example, if a row ** is inserted while a session object is enabled, then later deleted while ** the same session object is disabled, no INSERT record will appear in the ** changeset, even though the delete took place while the session was disabled. | | | | > | 11553 11554 11555 11556 11557 11558 11559 11560 11561 11562 11563 11564 11565 11566 11567 11568 11569 11570 | ** When a session object is disabled (see the [sqlite3session_enable()] API), ** it does not accumulate records when rows are inserted, updated or deleted. ** This may appear to have some counter-intuitive effects if a single row ** is written to more than once during a session. For example, if a row ** is inserted while a session object is enabled, then later deleted while ** the same session object is disabled, no INSERT record will appear in the ** changeset, even though the delete took place while the session was disabled. ** Or, if one field of a row is updated while a session is enabled, and ** then another field of the same row is updated while the session is disabled, ** the resulting changeset will contain an UPDATE change that updates both ** fields. */ SQLITE_API int sqlite3session_changeset( sqlite3_session *pSession, /* Session object */ int *pnChangeset, /* OUT: Size of buffer at *ppChangeset */ void **ppChangeset /* OUT: Buffer containing changeset */ ); |
| ︙ | ︙ | |||
11762 11763 11764 11765 11766 11767 11768 | /* ** CAPI3REF: Flags for sqlite3changeset_start_v2 ** ** The following flags may passed via the 4th parameter to ** [sqlite3changeset_start_v2] and [sqlite3changeset_start_v2_strm]: ** | | | 11765 11766 11767 11768 11769 11770 11771 11772 11773 11774 11775 11776 11777 11778 11779 | /* ** CAPI3REF: Flags for sqlite3changeset_start_v2 ** ** The following flags may passed via the 4th parameter to ** [sqlite3changeset_start_v2] and [sqlite3changeset_start_v2_strm]: ** ** <dt>SQLITE_CHANGESETSTART_INVERT <dd> ** Invert the changeset while iterating through it. This is equivalent to ** inverting a changeset using sqlite3changeset_invert() before applying it. ** It is an error to specify this flag with a patchset. */ #define SQLITE_CHANGESETSTART_INVERT 0x0002 |
| ︙ | ︙ | |||
12307 12308 12309 12310 12311 12312 12313 | ** CAPI3REF: Apply A Changeset To A Database ** ** Apply a changeset or patchset to a database. These functions attempt to ** update the "main" database attached to handle db with the changes found in ** the changeset passed via the second and third arguments. ** ** The fourth argument (xFilter) passed to these functions is the "filter | > > | | | | | | | > > > > > > > | | | | | | 12310 12311 12312 12313 12314 12315 12316 12317 12318 12319 12320 12321 12322 12323 12324 12325 12326 12327 12328 12329 12330 12331 12332 12333 12334 12335 12336 12337 12338 12339 12340 12341 12342 12343 12344 12345 12346 12347 12348 12349 12350 12351 12352 12353 12354 12355 12356 12357 12358 12359 12360 12361 12362 12363 12364 | ** CAPI3REF: Apply A Changeset To A Database ** ** Apply a changeset or patchset to a database. These functions attempt to ** update the "main" database attached to handle db with the changes found in ** the changeset passed via the second and third arguments. ** ** The fourth argument (xFilter) passed to these functions is the "filter ** callback". This may be passed NULL, in which case all changes in the ** changeset are applied to the database. For sqlite3changeset_apply() and ** sqlite3_changeset_apply_v2(), if it is not NULL, then it is invoked once ** for each table affected by at least one change in the changeset. In this ** case the table name is passed as the second argument, and a copy of ** the context pointer passed as the sixth argument to apply() or apply_v2() ** as the first. If the "filter callback" returns zero, then no attempt is ** made to apply any changes to the table. Otherwise, if the return value is ** non-zero, all changes related to the table are attempted. ** ** For sqlite3_changeset_apply_v3(), the xFilter callback is invoked once ** per change. The second argument in this case is an sqlite3_changeset_iter ** that may be queried using the usual APIs for the details of the current ** change. If the "filter callback" returns zero in this case, then no attempt ** is made to apply the current change. If it returns non-zero, the change ** is applied. ** ** For each table that is not excluded by the filter callback, this function ** tests that the target database contains a compatible table. A table is ** considered compatible if all of the following are true: ** ** <ul> ** <li> The table has the same name as the name recorded in the ** changeset, and ** <li> The table has at least as many columns as recorded in the ** changeset, and ** <li> The table has primary key columns in the same position as ** recorded in the changeset. ** </ul> ** ** If there is no compatible table, it is not an error, but none of the ** changes associated with the table are applied. A warning message is issued ** via the sqlite3_log() mechanism with the error code SQLITE_SCHEMA. At most ** one such warning is issued for each table in the changeset. ** ** For each change for which there is a compatible table, an attempt is made ** to modify the table contents according to each UPDATE, INSERT or DELETE ** change that is not excluded by a filter callback. If a change cannot be ** applied cleanly, the conflict handler function passed as the fifth argument ** to sqlite3changeset_apply() may be invoked. A description of exactly when ** the conflict handler is invoked for each type of change is below. ** ** Unlike the xFilter argument, xConflict may not be passed NULL. The results ** of passing anything other than a valid function pointer as the xConflict ** argument are undefined. ** ** Each time the conflict handler function is invoked, it must return one ** of [SQLITE_CHANGESET_OMIT], [SQLITE_CHANGESET_ABORT] or |
| ︙ | ︙ | |||
12480 12481 12482 12483 12484 12485 12486 12487 12488 12489 12490 12491 12492 12493 |
sqlite3 *db, /* Apply change to "main" db of this handle */
int nChangeset, /* Size of changeset in bytes */
void *pChangeset, /* Changeset blob */
int(*xFilter)(
void *pCtx, /* Copy of sixth arg to _apply() */
const char *zTab /* Table name */
),
int(*xConflict)(
void *pCtx, /* Copy of sixth arg to _apply() */
int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */
sqlite3_changeset_iter *p /* Handle describing change and conflict */
),
void *pCtx, /* First argument passed to xConflict */
void **ppRebase, int *pnRebase, /* OUT: Rebase data */
| > > > > > > > > > > > > > > > > > | 12492 12493 12494 12495 12496 12497 12498 12499 12500 12501 12502 12503 12504 12505 12506 12507 12508 12509 12510 12511 12512 12513 12514 12515 12516 12517 12518 12519 12520 12521 12522 |
sqlite3 *db, /* Apply change to "main" db of this handle */
int nChangeset, /* Size of changeset in bytes */
void *pChangeset, /* Changeset blob */
int(*xFilter)(
void *pCtx, /* Copy of sixth arg to _apply() */
const char *zTab /* Table name */
),
int(*xConflict)(
void *pCtx, /* Copy of sixth arg to _apply() */
int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */
sqlite3_changeset_iter *p /* Handle describing change and conflict */
),
void *pCtx, /* First argument passed to xConflict */
void **ppRebase, int *pnRebase, /* OUT: Rebase data */
int flags /* SESSION_CHANGESETAPPLY_* flags */
);
SQLITE_API int sqlite3changeset_apply_v3(
sqlite3 *db, /* Apply change to "main" db of this handle */
int nChangeset, /* Size of changeset in bytes */
void *pChangeset, /* Changeset blob */
int(*xFilter)(
void *pCtx, /* Copy of sixth arg to _apply() */
sqlite3_changeset_iter *p /* Handle describing change */
),
int(*xConflict)(
void *pCtx, /* Copy of sixth arg to _apply() */
int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */
sqlite3_changeset_iter *p /* Handle describing change and conflict */
),
void *pCtx, /* First argument passed to xConflict */
void **ppRebase, int *pnRebase, /* OUT: Rebase data */
|
| ︙ | ︙ | |||
12899 12900 12901 12902 12903 12904 12905 12906 12907 12908 12909 12910 12911 12912 |
sqlite3 *db, /* Apply change to "main" db of this handle */
int (*xInput)(void *pIn, void *pData, int *pnData), /* Input function */
void *pIn, /* First arg for xInput */
int(*xFilter)(
void *pCtx, /* Copy of sixth arg to _apply() */
const char *zTab /* Table name */
),
int(*xConflict)(
void *pCtx, /* Copy of sixth arg to _apply() */
int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */
sqlite3_changeset_iter *p /* Handle describing change and conflict */
),
void *pCtx, /* First argument passed to xConflict */
void **ppRebase, int *pnRebase,
| > > > > > > > > > > > > > > > > > | 12928 12929 12930 12931 12932 12933 12934 12935 12936 12937 12938 12939 12940 12941 12942 12943 12944 12945 12946 12947 12948 12949 12950 12951 12952 12953 12954 12955 12956 12957 12958 |
sqlite3 *db, /* Apply change to "main" db of this handle */
int (*xInput)(void *pIn, void *pData, int *pnData), /* Input function */
void *pIn, /* First arg for xInput */
int(*xFilter)(
void *pCtx, /* Copy of sixth arg to _apply() */
const char *zTab /* Table name */
),
int(*xConflict)(
void *pCtx, /* Copy of sixth arg to _apply() */
int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */
sqlite3_changeset_iter *p /* Handle describing change and conflict */
),
void *pCtx, /* First argument passed to xConflict */
void **ppRebase, int *pnRebase,
int flags
);
SQLITE_API int sqlite3changeset_apply_v3_strm(
sqlite3 *db, /* Apply change to "main" db of this handle */
int (*xInput)(void *pIn, void *pData, int *pnData), /* Input function */
void *pIn, /* First arg for xInput */
int(*xFilter)(
void *pCtx, /* Copy of sixth arg to _apply() */
sqlite3_changeset_iter *p
),
int(*xConflict)(
void *pCtx, /* Copy of sixth arg to _apply() */
int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */
sqlite3_changeset_iter *p /* Handle describing change and conflict */
),
void *pCtx, /* First argument passed to xConflict */
void **ppRebase, int *pnRebase,
|
| ︙ | ︙ |
Changes to src/ajax.c.
| ︙ | ︙ | |||
305 306 307 308 309 310 311 |
int ln = atoi(PD("ln","0"));
int iframeHeight = atoi(PD("iframe_height","40"));
Blob content = empty_blob;
const char * zRenderMode = 0;
ajax_get_fnci_args( &zFilename, 0 );
| | | 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 |
int ln = atoi(PD("ln","0"));
int iframeHeight = atoi(PD("iframe_height","40"));
Blob content = empty_blob;
const char * zRenderMode = 0;
ajax_get_fnci_args( &zFilename, 0 );
if(!ajax_route_bootstrap(0,1)){
return;
}
if(zFilename==0){
/* The filename is only used for mimetype determination,
** so we can default it... */
zFilename = "foo.txt";
}
|
| ︙ | ︙ |
Changes to src/cgi.c.
| ︙ | ︙ | |||
503 504 505 506 507 508 509 |
if( etag_tag()[0]!=0
&& iReplyStatus==200
&& strcmp(zContentType,"text/html")!=0
){
/* Do not cache HTML replies as those will have been generated and
** will likely, therefore, contains a nonce and we want that nonce to
** be different every time. */
| | | 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 |
if( etag_tag()[0]!=0
&& iReplyStatus==200
&& strcmp(zContentType,"text/html")!=0
){
/* Do not cache HTML replies as those will have been generated and
** will likely, therefore, contains a nonce and we want that nonce to
** be different every time. */
blob_appendf(&hdr, "ETag: \"%s\"\r\n", etag_tag());
blob_appendf(&hdr, "Cache-Control: max-age=%d\r\n", etag_maxage());
if( etag_mtime()>0 ){
blob_appendf(&hdr, "Last-Modified: %s\r\n",
cgi_rfc822_datestamp(etag_mtime()));
}
}else if( g.isConst ){
/* isConst means that the reply is guaranteed to be invariant, even
|
| ︙ | ︙ | |||
2136 2137 2138 2139 2140 2141 2142 |
if( zToken==0 ){
malformed_request("malformed HTTP header");
}
if( fossil_strcmp(zToken,"GET")!=0
&& fossil_strcmp(zToken,"POST")!=0
&& fossil_strcmp(zToken,"HEAD")!=0
){
| | | 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 |
if( zToken==0 ){
malformed_request("malformed HTTP header");
}
if( fossil_strcmp(zToken,"GET")!=0
&& fossil_strcmp(zToken,"POST")!=0
&& fossil_strcmp(zToken,"HEAD")!=0
){
malformed_request("unsupported HTTP method: \"%s\" - Fossil only supports "
"GET, POST, and HEAD", zToken);
}
cgi_setenv("GATEWAY_INTERFACE","CGI/1.0");
cgi_setenv("REQUEST_METHOD",zToken);
zToken = extract_token(z, &z);
if( zToken==0 ){
malformed_request("malformed URI in the HTTP header");
|
| ︙ | ︙ | |||
2659 2660 2661 2662 2663 2664 2665 |
fossil_fatal("not a valid IPv4 address: %s", zIpAddr);
}
listen4 = socket(AF_INET, SOCK_STREAM, 0);
if( listen4>0 ){
setsockopt(listen4, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
rc = bind(listen4, (struct sockaddr*)&inaddr4, sizeof(inaddr4));
if( rc<0 ){
| | | 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 |
fossil_fatal("not a valid IPv4 address: %s", zIpAddr);
}
listen4 = socket(AF_INET, SOCK_STREAM, 0);
if( listen4>0 ){
setsockopt(listen4, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
rc = bind(listen4, (struct sockaddr*)&inaddr4, sizeof(inaddr4));
if( rc<0 ){
close(listen4);
listen4 = -1;
}
}
if( listen4<0 ){
fossil_fatal("cannot open a listening socket on %s:%d",
zIpAddr, mnPort);
}
|
| ︙ | ︙ |
Changes to src/clone.c.
| ︙ | ︙ | |||
428 429 430 431 432 433 434 |
}else{
const char *zDLTag = db_get("download-tag","trunk");
const char *zNm = db_get("short-project-name","download");
char *zUrl = href("%R/zip/%t/%t.zip", zDLTag, zNm);
@ <p>ZIP Archive: %z(zUrl)%h(zNm).zip</a>
zUrl = href("%R/tarball/%t/%t.tar.gz", zDLTag, zNm);
@ <p>Tarball: %z(zUrl)%h(zNm).tar.gz</a>
| > | | > | 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 |
}else{
const char *zDLTag = db_get("download-tag","trunk");
const char *zNm = db_get("short-project-name","download");
char *zUrl = href("%R/zip/%t/%t.zip", zDLTag, zNm);
@ <p>ZIP Archive: %z(zUrl)%h(zNm).zip</a>
zUrl = href("%R/tarball/%t/%t.tar.gz", zDLTag, zNm);
@ <p>Tarball: %z(zUrl)%h(zNm).tar.gz</a>
if( g.zLogin!=0 ){
zUrl = href("%R/sqlar/%t/%t.sqlar", zDLTag, zNm);
@ <p>SQLite Archive: %z(zUrl)%h(zNm).sqlar</a>
}
}
if( !g.perm.Clone ){
@ <p>You are not authorized to clone this repository.
if( g.zLogin==0 || g.zLogin[0]==0 ){
@ Maybe you would be able to clone if you
@ %z(href("%R/login"))logged in</a>.
}else{
|
| ︙ | ︙ |
Changes to src/configure.c.
| ︙ | ︙ | |||
368 369 370 371 372 373 374 375 376 377 378 379 380 381 |
** ------- -----------------------------------------------------------
** /config $MTIME $NAME value $VALUE
** /user $MTIME $LOGIN pw $VALUE cap $VALUE info $VALUE photo $VALUE
** /shun $MTIME $UUID scom $VALUE
** /reportfmt $MTIME $TITLE owner $VALUE cols $VALUE sqlcode $VALUE jx $JSON
** /concealed $MTIME $HASH content $VALUE
** /subscriber $SMTIME $SEMAIL suname $V ...
*/
void configure_receive(const char *zName, Blob *pContent, int groupMask){
int checkMask; /* Masks for which we must first check existance of tables */
checkMask = CONFIGSET_SCRIBER;
if( zName[0]=='/' ){
/* The new format */
| > > > > | 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 |
** ------- -----------------------------------------------------------
** /config $MTIME $NAME value $VALUE
** /user $MTIME $LOGIN pw $VALUE cap $VALUE info $VALUE photo $VALUE
** /shun $MTIME $UUID scom $VALUE
** /reportfmt $MTIME $TITLE owner $VALUE cols $VALUE sqlcode $VALUE jx $JSON
** /concealed $MTIME $HASH content $VALUE
** /subscriber $SMTIME $SEMAIL suname $V ...
**
** NAME-specific notes:
**
** - /reportftm's $MTIME is in Julian, not the Unix epoch.
*/
void configure_receive(const char *zName, Blob *pContent, int groupMask){
int checkMask; /* Masks for which we must first check existance of tables */
checkMask = CONFIGSET_SCRIBER;
if( zName[0]=='/' ){
/* The new format */
|
| ︙ | ︙ |
Changes to src/db.c.
| ︙ | ︙ | |||
4756 4757 4758 4759 4760 4761 4762 | */ /* ** SETTING: comment-format width=16 default=1 ** Set the algorithm for printing timeline comments to the console. ** ** Possible values are: ** 1 Use the original comment printing algorithm: | | | 4756 4757 4758 4759 4760 4761 4762 4763 4764 4765 4766 4767 4768 4769 4770 | */ /* ** SETTING: comment-format width=16 default=1 ** Set the algorithm for printing timeline comments to the console. ** ** Possible values are: ** 1 Use the original comment printing algorithm: ** * Leading and trailing whitespace is removed ** * Internal whitespace is converted into a single space (0x20) ** * Line breaks occurs at whitespace or hyphens if possible ** This is the recommended value and the default. ** ** Or a bitwise combination of the following flags: ** 2 Trim leading and trailing CR and LF characters. ** 4 Trim leading and trailing white space characters. |
| ︙ | ︙ |
Changes to src/diff.c.
| ︙ | ︙ | |||
3779 3780 3781 3782 3783 3784 3785 | HQuery url; struct AnnVers *p; unsigned clr1, clr2, clr; int bBlame = g.zPath[0]!='a';/* True for BLAME output. False for ANNOTATE. */ /* Gather query parameters */ login_check_credentials(); | | | 3779 3780 3781 3782 3783 3784 3785 3786 3787 3788 3789 3790 3791 3792 3793 |
HQuery url;
struct AnnVers *p;
unsigned clr1, clr2, clr;
int bBlame = g.zPath[0]!='a';/* True for BLAME output. False for ANNOTATE. */
/* Gather query parameters */
login_check_credentials();
if( !g.perm.Read || g.zLogin==0 ){ login_needed(g.anon.Read); return; }
if( exclude_spiders(0) ) return;
fossil_nice_default();
zFilename = P("filename");
zRevision = PD("checkin",0);
zOrigin = P("origin");
zLimit = P("limit");
showLog = PB("log");
|
| ︙ | ︙ |
Changes to src/diff.tcl.
| ︙ | ︙ | |||
498 499 500 501 502 503 504 505 506 507 508 509 510 511 |
proc saveDiff {} {
set fn [tk_getSaveFile]
if {$fn==""} return
set out [open $fn wb]
puts $out "#!/usr/bin/tclsh\n#\n# Run this script using 'tclsh' or 'wish'"
puts $out "# to see the graphical diff.\n#"
puts $out "set fossilcmd {}"
puts $out "set prog [list $::prog]"
puts $out "set difftxt \173"
foreach e $::difftxt {puts $out [list $e]}
puts $out "\175"
puts $out "eval \$prog"
close $out
}
| > > | 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 |
proc saveDiff {} {
set fn [tk_getSaveFile]
if {$fn==""} return
set out [open $fn wb]
puts $out "#!/usr/bin/tclsh\n#\n# Run this script using 'tclsh' or 'wish'"
puts $out "# to see the graphical diff.\n#"
puts $out "set fossilcmd {}"
puts $out "set darkmode $::darkmode"
puts $out "set debug $::debug"
puts $out "set prog [list $::prog]"
puts $out "set difftxt \173"
foreach e $::difftxt {puts $out [list $e]}
puts $out "\175"
puts $out "eval \$prog"
close $out
}
|
| ︙ | ︙ | |||
604 605 606 607 608 609 610 |
set ::search $w
}
::ttk::button .bb.quit -text {Quit} -command exit
::ttk::button .bb.reload -text {Reload} -command reloadDiff
::ttk::button .bb.invert -text {Invert} -command invertDiff
::ttk::button .bb.save -text {Save As...} -command saveDiff
::ttk::button .bb.search -text {Search} -command searchOnOff
| > > > > | | 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 |
set ::search $w
}
::ttk::button .bb.quit -text {Quit} -command exit
::ttk::button .bb.reload -text {Reload} -command reloadDiff
::ttk::button .bb.invert -text {Invert} -command invertDiff
::ttk::button .bb.save -text {Save As...} -command saveDiff
::ttk::button .bb.search -text {Search} -command searchOnOff
pack .bb.quit -side left
if {$fossilcmd ne ""} {
pack .bb.reload -side left
}
pack .bb.invert -side left
if {$fossilcmd!=""} {pack .bb.save -side left}
pack .bb.files .bb.search -side left
grid rowconfigure . 1 -weight 1
grid columnconfigure . 1 -weight 1
grid columnconfigure . 4 -weight 1
grid .bb -row 0 -columnspan 6
eval grid [cols] -row 1 -sticky nsew
|
| ︙ | ︙ |
Changes to src/diffcmd.c.
| ︙ | ︙ | |||
665 666 667 668 669 670 671 |
blob_append_escaped_arg(&cmd, blob_str(&nameFile1), 1);
}else{
blob_append_escaped_arg(&cmd, blob_str(&nameFile1), 1);
blob_append_escaped_arg(&cmd, zFile2, 1);
}
/* Run the external diff command */
| | < < < < < | 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 |
blob_append_escaped_arg(&cmd, blob_str(&nameFile1), 1);
}else{
blob_append_escaped_arg(&cmd, blob_str(&nameFile1), 1);
blob_append_escaped_arg(&cmd, zFile2, 1);
}
/* Run the external diff command */
fossil_system(blob_str(&cmd));
/* Delete the temporary file and clean up memory used */
if( useTempfile ) file_delete(blob_str(&nameFile1));
blob_reset(&nameFile1);
blob_reset(&cmd);
}
}
|
| ︙ | ︙ | |||
1293 1294 1295 1296 1297 1298 1299 | ** ** Usage: %fossil diff|gdiff ?OPTIONS? ?FILE1? ?FILE2 ...? ** ** Show the difference between the current version of each of the FILEs ** specified (as they exist on disk) and that same file as it was checked- ** out. Or if the FILE arguments are omitted, show all unsaved changes ** currently in the working check-out. The "gdiff" variant means to | | | 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 | ** ** Usage: %fossil diff|gdiff ?OPTIONS? ?FILE1? ?FILE2 ...? ** ** Show the difference between the current version of each of the FILEs ** specified (as they exist on disk) and that same file as it was checked- ** out. Or if the FILE arguments are omitted, show all unsaved changes ** currently in the working check-out. The "gdiff" variant means to ** use a GUI diff. ** ** The default output format is a "unified patch" (the same as the ** output of "diff -u" on most unix systems). Many alternative formats ** are available. A few of the more useful alternatives: ** ** --tk Pop up a Tcl/Tk-based GUI to show the diff ** --by Show a side-by-side diff in the default web browser |
| ︙ | ︙ |
Changes to src/etag.c.
| ︙ | ︙ | |||
92 93 94 95 96 97 98 99 100 101 102 103 104 105 |
/*
** Generate an ETag
*/
void etag_check(unsigned eFlags, const char *zHash){
const char *zIfNoneMatch;
char zBuf[50];
assert( zETag[0]==0 ); /* Only call this routine once! */
if( etagCancelled ) return;
/* By default, ETagged URLs never expire since the ETag will change
* when the content changes. Approximate this policy as 10 years. */
iMaxAge = 10 * 365 * 24 * 60 * 60;
| > > | 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
/*
** Generate an ETag
*/
void etag_check(unsigned eFlags, const char *zHash){
const char *zIfNoneMatch;
char zBuf[50];
const int cchETag = 32; /* Not including NULL terminator. */
int cch; /* Length of zIfNoneMatch header. */
assert( zETag[0]==0 ); /* Only call this routine once! */
if( etagCancelled ) return;
/* By default, ETagged URLs never expire since the ETag will change
* when the content changes. Approximate this policy as 10 years. */
iMaxAge = 10 * 365 * 24 * 60 * 60;
|
| ︙ | ︙ | |||
155 156 157 158 159 160 161 |
md5sum_step_text("login: ", -1);
md5sum_step_text(g.zLogin, -1);
md5sum_step_text("\n", 1);
}
}
/* Generate the ETag */
| | | > > > > > | > | 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 |
md5sum_step_text("login: ", -1);
md5sum_step_text(g.zLogin, -1);
md5sum_step_text("\n", 1);
}
}
/* Generate the ETag */
memcpy(zETag, md5sum_finish(0), cchETag+1);
/* Check to see if the generated ETag matches If-None-Match and
** generate a 304 reply if it does. Test both with and without
** double quotes. */
zIfNoneMatch = P("HTTP_IF_NONE_MATCH");
if( zIfNoneMatch==0 ) return;
cch = strlen(zIfNoneMatch);
if( cch==cchETag+2 && zIfNoneMatch[0]=='"' && zIfNoneMatch[cch-1]=='"' ){
if( memcmp(&zIfNoneMatch[1],zETag,cchETag)!=0 ) return;
}else{
if( strcmp(zIfNoneMatch,zETag)!=0 ) return;
}
/* If we get this far, it means that the content has
** not changed and we can do a 304 reply */
cgi_reset_content();
cgi_set_status(304, "Not Modified");
cgi_reply();
db_close(0);
|
| ︙ | ︙ |
Changes to src/forum.c.
| ︙ | ︙ | |||
931 932 933 934 935 936 937 |
if( bSelect && forumpost_may_close() && iClosed>=0 ){
int iHead = forumpost_head_rid(p->fpid);
@ <form method="post" \
@ action='%R/forumpost_%s(iClosed > 0 ? "reopen" : "close")'>
login_insert_csrf_secret();
@ <input type="hidden" name="fpid" value="%z(rid_to_uuid(iHead))" />
if( moderation_pending(p->fpid)==0 ){
| | > | 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 |
if( bSelect && forumpost_may_close() && iClosed>=0 ){
int iHead = forumpost_head_rid(p->fpid);
@ <form method="post" \
@ action='%R/forumpost_%s(iClosed > 0 ? "reopen" : "close")'>
login_insert_csrf_secret();
@ <input type="hidden" name="fpid" value="%z(rid_to_uuid(iHead))" />
if( moderation_pending(p->fpid)==0 ){
@ <input type="button" value='%s(iClosed ? "Re-open" : "Close")' \
@ class='%s(iClosed ? "action-reopen" : "action-close")'/>
}
@ </form>
}
@ </div>
}
@ </div>
}
|
| ︙ | ︙ | |||
1112 1113 1114 1115 1116 1117 1118 |
/*
** Emit Forum Javascript which applies (or optionally can apply)
** to all forum-related pages. It does not include page-specific
** code (e.g. "forum.js").
*/
static void forum_emit_js(void){
| | > | 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 |
/*
** Emit Forum Javascript which applies (or optionally can apply)
** to all forum-related pages. It does not include page-specific
** code (e.g. "forum.js").
*/
static void forum_emit_js(void){
builtin_fossil_js_bundle_or("copybutton", "pikchr", "confirmer",
NULL);
builtin_request_js("fossil.page.forumpost.js");
}
/*
** WEBPAGE: forumpost
**
** Show a single forum posting. The posting is shown in context with
|
| ︙ | ︙ |
Changes to src/fossil.numbered-lines.js.
| ︙ | ︙ | |||
19 20 21 22 23 24 25 |
if(!tbl) return /* no matching elements */;
const F = window.fossil, D = F.dom;
const tdLn = tbl.querySelector('td.line-numbers');
const urlArgsRaw = (window.location.search||'?')
.replace(/&?\budc=[^&]*/,'') /* "update display prefs cookie" */
.replace(/&?\bln=[^&]*/,'') /* inbound line number/range */
.replace('?&','?');
| < < < | | 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
if(!tbl) return /* no matching elements */;
const F = window.fossil, D = F.dom;
const tdLn = tbl.querySelector('td.line-numbers');
const urlArgsRaw = (window.location.search||'?')
.replace(/&?\budc=[^&]*/,'') /* "update display prefs cookie" */
.replace(/&?\bln=[^&]*/,'') /* inbound line number/range */
.replace('?&','?');
const lineState = { urlArgs: urlArgsRaw, start: 0, end: 0 };
const lineTip = new F.PopupWidget({
style: {
cursor: 'pointer'
},
refresh: function(){
const link = this.state.link;
D.clearElement(link);
|
| ︙ | ︙ |
Changes to src/fossil.page.forumpost.js.
| ︙ | ︙ | |||
115 116 117 118 119 120 121 |
browser's cancel button while waiting, they'll be stuck with
an unsubmittable form. */
setTimeout(()=>{delete form.dataset.submitted}, 7000);
return;
};
document.querySelectorAll("form").forEach(function(form){
form.addEventListener('submit',formSubmitted);
| > > > > > > > > | > > > | 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 |
browser's cancel button while waiting, they'll be stuck with
an unsubmittable form. */
setTimeout(()=>{delete form.dataset.submitted}, 7000);
return;
};
document.querySelectorAll("form").forEach(function(form){
form.addEventListener('submit',formSubmitted);
form
.querySelectorAll("input.action-close, input.action-reopen")
.forEach(function(e){
F.confirmer(e, {
confirmText: (e.classList.contains('action-reopen')
? "Confirm re-open"
: "Confirm close"),
onconfirm: ()=>form.submit()
});
});
});
})/*F.onPageLoad callback*/;
})(window.fossil);
|
Changes to src/http.c.
| ︙ | ︙ | |||
50 51 52 53 54 55 56 | /* ** Construct the "login" card with the client credentials. ** ** login LOGIN NONCE SIGNATURE ** ** The LOGIN is the user id of the client. NONCE is the sha1 checksum | | > | 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
/*
** Construct the "login" card with the client credentials.
**
** login LOGIN NONCE SIGNATURE
**
** The LOGIN is the user id of the client. NONCE is the sha1 checksum
** of all payload that follows the login card. Randomness for the NONCE
** must be provided in the payload (in xfer.c). SIGNATURE is the sha1
** checksum of the nonce followed by the user password.
**
** Write the constructed login card into pLogin. pLogin is initialized
** by this routine.
*/
static void http_build_login_card(Blob *pPayload, Blob *pLogin){
Blob nonce; /* The nonce */
|
| ︙ | ︙ | |||
762 763 764 765 766 767 768 | /* ** COMMAND: test-httpmsg ** ** Usage: %fossil test-httpmsg ?OPTIONS? URL ?PAYLOAD? ?OUTPUT? ** ** Send an HTTP message to URL and get the reply. PAYLOAD is a file containing | | | 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 | /* ** COMMAND: test-httpmsg ** ** Usage: %fossil test-httpmsg ?OPTIONS? URL ?PAYLOAD? ?OUTPUT? ** ** Send an HTTP message to URL and get the reply. PAYLOAD is a file containing ** the payload, or "-" to read payload from standard input. A POST message ** is sent if PAYLOAD is specified and is non-empty. If PAYLOAD is omitted ** or is an empty file, then a GET message is sent. ** ** If a second filename (OUTPUT) is given after PAYLOAD, then the reply ** is written into that second file instead of being written on standard ** output. Use the "--out OUTPUT" option to specify an output file for ** a GET request where there is no PAYLOAD. |
| ︙ | ︙ |
Changes to src/info.c.
| ︙ | ︙ | |||
991 992 993 994 995 996 997 |
zPJ[jj] = '_';
}
}
zUrl = mprintf("%R/tarball/%S/%t-%S.tar.gz", zUuid, zPJ, zUuid);
@ <tr><th>Downloads:</th><td>
@ %z(href("%s",zUrl))Tarball</a>
@ | %z(href("%R/zip/%S/%t-%S.zip",zUuid, zPJ,zUuid))ZIP archive</a>
| > | | > | 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 |
zPJ[jj] = '_';
}
}
zUrl = mprintf("%R/tarball/%S/%t-%S.tar.gz", zUuid, zPJ, zUuid);
@ <tr><th>Downloads:</th><td>
@ %z(href("%s",zUrl))Tarball</a>
@ | %z(href("%R/zip/%S/%t-%S.zip",zUuid, zPJ,zUuid))ZIP archive</a>
if( g.zLogin!=0 ){
@ | %z(href("%R/sqlar/%S/%t-%S.sqlar",zUuid,zPJ,zUuid))\
@ SQL archive</a></td></tr>
}
fossil_free(zUrl);
blob_reset(&projName);
}
@ <tr><th>Timelines:</th><td>
@ %z(href("%R/timeline?f=%!S&unhide",zUuid))family</a>
if( zParent ){
|
| ︙ | ︙ | |||
3928 3929 3930 3931 3932 3933 3934 3935 3936 3937 3938 3939 3940 3941 | ** --branch NAME Rename branch of check-in to NAME ** --branchcolor COLOR Apply and propagate COLOR to the branch ** --cancel TAG Cancel TAG from this check-in ** --close Mark this "leaf" as closed ** --date DATETIME Make DATETIME the check-in time ** --date-override DATETIME Set the change time on the control artifact ** -e|--edit-comment Launch editor to revise comment ** --hide Hide branch starting from this check-in ** -m|--comment COMMENT Make COMMENT the check-in comment ** -M|--message-file FILE Read the amended comment from FILE ** -n|--dry-run Print control artifact, but make no changes ** --no-verify-comment Do not validate the check-in comment ** --tag TAG Add new TAG to this check-in ** --user-override USER Set the user name on the control artifact | > | 3930 3931 3932 3933 3934 3935 3936 3937 3938 3939 3940 3941 3942 3943 3944 | ** --branch NAME Rename branch of check-in to NAME ** --branchcolor COLOR Apply and propagate COLOR to the branch ** --cancel TAG Cancel TAG from this check-in ** --close Mark this "leaf" as closed ** --date DATETIME Make DATETIME the check-in time ** --date-override DATETIME Set the change time on the control artifact ** -e|--edit-comment Launch editor to revise comment ** --editor NAME Text editor to use for check-in comment ** --hide Hide branch starting from this check-in ** -m|--comment COMMENT Make COMMENT the check-in comment ** -M|--message-file FILE Read the amended comment from FILE ** -n|--dry-run Print control artifact, but make no changes ** --no-verify-comment Do not validate the check-in comment ** --tag TAG Add new TAG to this check-in ** --user-override USER Set the user name on the control artifact |
| ︙ | ︙ | |||
4001 4002 4003 4004 4005 4006 4007 4008 4009 4010 4011 4012 4013 4014 |
fDryRun = find_option("dry-run","n",0)!=0;
zChngTime = find_option("date-override",0,1);
if( zChngTime==0 ) zChngTime = find_option("chngtime",0,1);
zUserOvrd = find_option("user-override",0,1);
noVerifyCom = find_option("no-verify-comment",0,0)!=0;
db_find_and_open_repository(0,0);
user_select();
verify_all_options();
if( g.argc<3 || g.argc>=4 ) usage(AMEND_USAGE_STMT);
rid = name_to_typed_rid(g.argv[2], "ci");
if( rid==0 && !is_a_version(rid) ) fossil_fatal("no such check-in");
zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
if( zUuid==0 ) fossil_fatal("Unable to find artifact hash");
zComment = db_text(0, "SELECT coalesce(ecomment,comment)"
| > | 4004 4005 4006 4007 4008 4009 4010 4011 4012 4013 4014 4015 4016 4017 4018 |
fDryRun = find_option("dry-run","n",0)!=0;
zChngTime = find_option("date-override",0,1);
if( zChngTime==0 ) zChngTime = find_option("chngtime",0,1);
zUserOvrd = find_option("user-override",0,1);
noVerifyCom = find_option("no-verify-comment",0,0)!=0;
db_find_and_open_repository(0,0);
user_select();
(void)fossil_text_editor();
verify_all_options();
if( g.argc<3 || g.argc>=4 ) usage(AMEND_USAGE_STMT);
rid = name_to_typed_rid(g.argv[2], "ci");
if( rid==0 && !is_a_version(rid) ) fossil_fatal("no such check-in");
zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
if( zUuid==0 ) fossil_fatal("Unable to find artifact hash");
zComment = db_text(0, "SELECT coalesce(ecomment,comment)"
|
| ︙ | ︙ |
Changes to src/main.c.
| ︙ | ︙ | |||
3111 3112 3113 3114 3115 3116 3117 | ** This command can used for interactive debugging of web pages. For ** example, one can put a simple HTTP request in a file like this: ** ** echo 'GET /timeline' >request.txt ** ** Then run (in a debugger) a command like this: ** | | | 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 | ** This command can used for interactive debugging of web pages. For ** example, one can put a simple HTTP request in a file like this: ** ** echo 'GET /timeline' >request.txt ** ** Then run (in a debugger) a command like this: ** ** fossil test-http <request.txt ** ** This command is also used internally by the "ssh" sync protocol. Some ** special processing to support sync happens when this command is run ** and the SSH_CONNECTION environment variable is set. Use the --test ** option on interactive sessions to avoid that special processing when ** using this command interactively over SSH. A better solution would be ** to use a different command for "ssh" sync, but we cannot do that without |
| ︙ | ︙ |
Changes to src/main.mk.
| ︙ | ︙ | |||
576 577 578 579 580 581 582 | $(OBJDIR)/wiki.o \ $(OBJDIR)/wikiformat.o \ $(OBJDIR)/winfile.o \ $(OBJDIR)/winhttp.o \ $(OBJDIR)/xfer.o \ $(OBJDIR)/xfersetup.o \ $(OBJDIR)/zip.o | | < < < > > > > > | | 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 | $(OBJDIR)/wiki.o \ $(OBJDIR)/wikiformat.o \ $(OBJDIR)/winfile.o \ $(OBJDIR)/winhttp.o \ $(OBJDIR)/xfer.o \ $(OBJDIR)/xfersetup.o \ $(OBJDIR)/zip.o all: $(APPNAME) install: all mkdir -p $(INSTALLDIR) cp $(APPNAME) $(INSTALLDIR) codecheck: $(TRANS_SRC) $(OBJDIR)/codecheck1 $(OBJDIR)/codecheck1 $(TRANS_SRC) $(OBJDIR)/translate: $(SRCDIR_tools)/translate.c -mkdir -p $(OBJDIR) $(XBCC) -o $(OBJDIR)/translate $(SRCDIR_tools)/translate.c $(OBJDIR)/makeheaders: $(SRCDIR_tools)/makeheaders.c -mkdir -p $(OBJDIR) $(XBCC) -o $(OBJDIR)/makeheaders $(SRCDIR_tools)/makeheaders.c $(OBJDIR)/mkindex: $(SRCDIR_tools)/mkindex.c -mkdir -p $(OBJDIR) $(XBCC) -o $(OBJDIR)/mkindex $(SRCDIR_tools)/mkindex.c $(OBJDIR)/mkbuiltin: $(SRCDIR_tools)/mkbuiltin.c -mkdir -p $(OBJDIR) $(XBCC) -o $(OBJDIR)/mkbuiltin $(SRCDIR_tools)/mkbuiltin.c $(OBJDIR)/mkversion: $(SRCDIR_tools)/mkversion.c -mkdir -p $(OBJDIR) $(XBCC) -o $(OBJDIR)/mkversion $(SRCDIR_tools)/mkversion.c $(OBJDIR)/codecheck1: $(SRCDIR_tools)/codecheck1.c -mkdir -p $(OBJDIR) $(XBCC) -o $(OBJDIR)/codecheck1 $(SRCDIR_tools)/codecheck1.c # Run the test suite. # Other flags that can be included in TESTFLAGS are: # # -halt Stop testing after the first failed test # -keep Keep the temporary workspace for debugging # -prot Write a detailed log of the tests to the file ./prot # -verbose Include even more details in the output # -quiet Hide most output from the terminal # -strict Treat known bugs as failures # # TESTFLAGS can also include names of specific test files to limit # the run to just those test cases. # test: $(APPNAME) $(TCLSH) $(SRCDIR)/../test/tester.tcl $(APPNAME) $(TESTFLAGS) $(OBJDIR)/VERSION.h: $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(SRCDIR)/../VERSION $(OBJDIR)/mkversion $(OBJDIR)/phony.h $(OBJDIR)/mkversion $(SRCDIR)/../manifest.uuid \ $(SRCDIR)/../manifest \ $(SRCDIR)/../VERSION >$(OBJDIR)/VERSION.h |
| ︙ | ︙ | |||
651 652 653 654 655 656 657 658 659 660 661 662 663 664 |
-DSQLITE_ENABLE_LOCKING_STYLE=0 \
-DSQLITE_DEFAULT_FILE_FORMAT=4 \
-DSQLITE_ENABLE_DBSTAT_VTAB \
-DSQLITE_ENABLE_EXPLAIN_COMMENTS \
-DSQLITE_ENABLE_FTS4 \
-DSQLITE_ENABLE_FTS5 \
-DSQLITE_ENABLE_MATH_FUNCTIONS \
-DSQLITE_ENABLE_STMTVTAB \
-DSQLITE_HAVE_ZLIB \
-DSQLITE_ENABLE_DBPAGE_VTAB \
-DSQLITE_TRUSTED_SCHEMA=0 \
-DHAVE_USLEEP
# Setup the options used to compile the included SQLite shell.
| > | 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 |
-DSQLITE_ENABLE_LOCKING_STYLE=0 \
-DSQLITE_DEFAULT_FILE_FORMAT=4 \
-DSQLITE_ENABLE_DBSTAT_VTAB \
-DSQLITE_ENABLE_EXPLAIN_COMMENTS \
-DSQLITE_ENABLE_FTS4 \
-DSQLITE_ENABLE_FTS5 \
-DSQLITE_ENABLE_MATH_FUNCTIONS \
-DSQLITE_ENABLE_SETLK_TIMEOUT \
-DSQLITE_ENABLE_STMTVTAB \
-DSQLITE_HAVE_ZLIB \
-DSQLITE_ENABLE_DBPAGE_VTAB \
-DSQLITE_TRUSTED_SCHEMA=0 \
-DHAVE_USLEEP
# Setup the options used to compile the included SQLite shell.
|
| ︙ | ︙ | |||
677 678 679 680 681 682 683 684 685 686 687 688 689 690 |
-DSQLITE_ENABLE_LOCKING_STYLE=0 \
-DSQLITE_DEFAULT_FILE_FORMAT=4 \
-DSQLITE_ENABLE_DBSTAT_VTAB \
-DSQLITE_ENABLE_EXPLAIN_COMMENTS \
-DSQLITE_ENABLE_FTS4 \
-DSQLITE_ENABLE_FTS5 \
-DSQLITE_ENABLE_MATH_FUNCTIONS \
-DSQLITE_ENABLE_STMTVTAB \
-DSQLITE_HAVE_ZLIB \
-DSQLITE_ENABLE_DBPAGE_VTAB \
-DSQLITE_TRUSTED_SCHEMA=0 \
-DHAVE_USLEEP \
-Dmain=sqlite3_shell \
-DSQLITE_SHELL_IS_UTF8=1 \
| > | 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 |
-DSQLITE_ENABLE_LOCKING_STYLE=0 \
-DSQLITE_DEFAULT_FILE_FORMAT=4 \
-DSQLITE_ENABLE_DBSTAT_VTAB \
-DSQLITE_ENABLE_EXPLAIN_COMMENTS \
-DSQLITE_ENABLE_FTS4 \
-DSQLITE_ENABLE_FTS5 \
-DSQLITE_ENABLE_MATH_FUNCTIONS \
-DSQLITE_ENABLE_SETLK_TIMEOUT \
-DSQLITE_ENABLE_STMTVTAB \
-DSQLITE_HAVE_ZLIB \
-DSQLITE_ENABLE_DBPAGE_VTAB \
-DSQLITE_TRUSTED_SCHEMA=0 \
-DHAVE_USLEEP \
-Dmain=sqlite3_shell \
-DSQLITE_SHELL_IS_UTF8=1 \
|
| ︙ | ︙ | |||
2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 | $(OBJDIR)/shell.o: $(SQLITE3_SHELL_SRC) $(SRCDIR_extsrc)/sqlite3.h $(XTCC) $(SHELL_OPTIONS) $(SHELL_CFLAGS) $(SEE_FLAGS) $(LINENOISE_DEF.$(USE_LINENOISE)) -c $(SQLITE3_SHELL_SRC) -o $@ $(OBJDIR)/linenoise.o: $(SRCDIR_extsrc)/linenoise.c $(SRCDIR_extsrc)/linenoise.h $(XTCC) -c $(SRCDIR_extsrc)/linenoise.c -o $@ $(OBJDIR)/th.o: $(SRCDIR)/th.c $(XTCC) -c $(SRCDIR)/th.c -o $@ $(OBJDIR)/th_lang.o: $(SRCDIR)/th_lang.c $(XTCC) -c $(SRCDIR)/th_lang.c -o $@ $(OBJDIR)/th_tcl.o: $(SRCDIR)/th_tcl.c $(XTCC) -c $(SRCDIR)/th_tcl.c -o $@ | > > > > > > | | | 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 |
$(OBJDIR)/shell.o: $(SQLITE3_SHELL_SRC) $(SRCDIR_extsrc)/sqlite3.h
$(XTCC) $(SHELL_OPTIONS) $(SHELL_CFLAGS) $(SEE_FLAGS) $(LINENOISE_DEF.$(USE_LINENOISE)) -c $(SQLITE3_SHELL_SRC) -o $@
$(OBJDIR)/linenoise.o: $(SRCDIR_extsrc)/linenoise.c $(SRCDIR_extsrc)/linenoise.h
$(XTCC) -c $(SRCDIR_extsrc)/linenoise.c -o $@
$(OBJDIR)/th.o: $(SRCDIR)/th.c
-mkdir -p $(OBJDIR)
$(XTCC) -c $(SRCDIR)/th.c -o $@
$(OBJDIR)/th_lang.o: $(SRCDIR)/th_lang.c
-mkdir -p $(OBJDIR)
$(XTCC) -c $(SRCDIR)/th_lang.c -o $@
$(OBJDIR)/th_tcl.o: $(SRCDIR)/th_tcl.c
-mkdir -p $(OBJDIR)
$(XTCC) -c $(SRCDIR)/th_tcl.c -o $@
$(OBJDIR)/pikchr.o: $(SRCDIR_extsrc)/pikchr.c $(OBJDIR)/mkversion
$(XTCC) $(PIKCHR_OPTIONS) -c $(SRCDIR_extsrc)/pikchr.c -o $@
$(OBJDIR)/cson_amalgamation.o: $(SRCDIR_extsrc)/cson_amalgamation.c $(OBJDIR)/mkversion
$(XTCC) -c $(SRCDIR_extsrc)/cson_amalgamation.c -o $@
$(SRCDIR_extsrc)/pikchr.js: $(SRCDIR_extsrc)/pikchr.c $(MAKEFILE_LIST)
$(EMCC_WRAPPER) -o $@ $(EMCC_OPT) --no-entry \
-sEXPORTED_RUNTIME_METHODS=cwrap,ccall,setValue,getValue,stackSave,stackAlloc,stackRestore \
-sEXPORTED_FUNCTIONS=_pikchr,_pikchr_version $(SRCDIR_extsrc)/pikchr.c \
-sENVIRONMENT=web \
|
| ︙ | ︙ |
Changes to src/manifest.c.
| ︙ | ︙ | |||
3022 3023 3024 3025 3026 3027 3028 |
blob_append_char(b, ']');
}
CARD_STR2(K, p->zTicketUuid);
CARD_STR2(L, p->zWikiTitle);
ISA( CFTYPE_CLUSTER ){
CARD_LETTER(M);
blob_append_char(b, '[');
| | | 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 |
blob_append_char(b, ']');
}
CARD_STR2(K, p->zTicketUuid);
CARD_STR2(L, p->zWikiTitle);
ISA( CFTYPE_CLUSTER ){
CARD_LETTER(M);
blob_append_char(b, '[');
for( i = 0; i < p->nCChild; ++i ){
if( i>0 ) blob_append_char(b, ',');
blob_appendf(b, "%!j", p->azCChild[i]);
}
blob_append_char(b, ']');
}
CARD_STR2(N, p->zMimetype);
ISA( CFTYPE_MANIFEST || p->nParent>0 ){
|
| ︙ | ︙ | |||
3057 3058 3059 3060 3061 3062 3063 |
}
blob_append_char(b, ']');
}
CARD_STR2(R, p->zRepoCksum);
if( p->nTag ){
CARD_LETTER(T);
blob_append_char(b, '[');
| | | 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 |
}
blob_append_char(b, ']');
}
CARD_STR2(R, p->zRepoCksum);
if( p->nTag ){
CARD_LETTER(T);
blob_append_char(b, '[');
for( i = 0; i < p->nTag; ++i ){
const char *zName = p->aTag[i].zName;
if( i>0 ) blob_append_char(b, ',');
blob_append_char(b, '{');
blob_appendf(b, "\"type\":\"%c\"", *zName);
KVP_STR(1, name, &zName[1]);
KVP_STR(1, target, p->aTag[i].zUuid ? p->aTag[i].zUuid : "*")
/* We could arguably resolve the "*" as null or p's uuid. */;
|
| ︙ | ︙ |
Changes to src/markdown_html.c.
| ︙ | ︙ | |||
276 277 278 279 280 281 282 |
static void html_table(
struct Blob *ob,
struct Blob *head_row,
struct Blob *rows,
void *opaque
){
INTER_BLOCK(ob);
| | | 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 |
static void html_table(
struct Blob *ob,
struct Blob *head_row,
struct Blob *rows,
void *opaque
){
INTER_BLOCK(ob);
blob_append_literal(ob, "<table class='md-table'>\n");
if( head_row && blob_size(head_row)>0 ){
blob_append_literal(ob, "<thead>\n");
blob_appendb(ob, head_row);
blob_append_literal(ob, "</thead>\n<tbody>\n");
}
if( rows ){
blob_appendb(ob, rows);
|
| ︙ | ︙ |
Changes to src/name.c.
| ︙ | ︙ | |||
1221 1222 1223 1224 1225 1226 1227 |
cnt++;
}
db_finalize(&q);
/* Check to see if this object is used as a file in a check-in */
db_prepare(&q,
"SELECT filename.name, blob.uuid, datetime(event.mtime,toLocal()),"
| | > > | | > | 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 |
cnt++;
}
db_finalize(&q);
/* Check to see if this object is used as a file in a check-in */
db_prepare(&q,
"SELECT filename.name, blob.uuid, datetime(event.mtime,toLocal()),"
" coalesce(euser,user), coalesce(ecomment,comment),"
" coalesce((SELECT value FROM tagxref"
" WHERE tagid=%d AND tagtype>0 AND rid=mlink.mid),'trunk')"
" FROM mlink, filename, blob, event"
" WHERE mlink.fid=%d"
" AND filename.fnid=mlink.fnid"
" AND event.objid=mlink.mid"
" AND blob.rid=mlink.mid"
" ORDER BY event.mtime %s /*sort*/",
TAG_BRANCH, rid,
(flags & WHATIS_BRIEF) ? "LIMIT 1" : "DESC");
while( db_step(&q)==SQLITE_ROW ){
if( flags & WHATIS_BRIEF ){
fossil_print("mtime: %s\n", db_column_text(&q,2));
}
fossil_print("file: %s\n", db_column_text(&q,0));
fossil_print(" part of [%S] on branch %s by %s on %s\n",
db_column_text(&q, 1),
db_column_text(&q, 5),
db_column_text(&q, 3),
db_column_text(&q, 2));
fossil_print(" ");
comment_print(db_column_text(&q,4), 0, 12, -1, get_comment_format());
cnt++;
}
db_finalize(&q);
|
| ︙ | ︙ |
Changes to src/printf.c.
| ︙ | ︙ | |||
772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 |
int needQuote;
int limit = flag_alternateform ? va_arg(ap,int) : -1;
char q = ((xtype==etSQLESCAPE3)?'"':'\''); /* Quote characters */
char *escarg = va_arg(ap,char*);
isnull = escarg==0;
if( isnull ) escarg = (xtype==etSQLESCAPE2 ? "NULL" : "(NULL)");
if( limit<0 ) limit = strlen(escarg);
for(i=n=0; i<limit; i++){
if( escarg[i]==q ) n++;
}
needQuote = !isnull && xtype==etSQLESCAPE2;
n += i + 1 + needQuote*2;
if( n>etBUFSIZE ){
bufpt = zExtra = fossil_malloc( n );
}else{
bufpt = buf;
}
j = 0;
if( needQuote ) bufpt[j++] = q;
for(i=0; i<limit; i++){
bufpt[j++] = ch = escarg[i];
if( ch==q ) bufpt[j++] = ch;
}
if( needQuote ) bufpt[j++] = q;
bufpt[j] = 0;
length = j;
| > < | 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 |
int needQuote;
int limit = flag_alternateform ? va_arg(ap,int) : -1;
char q = ((xtype==etSQLESCAPE3)?'"':'\''); /* Quote characters */
char *escarg = va_arg(ap,char*);
isnull = escarg==0;
if( isnull ) escarg = (xtype==etSQLESCAPE2 ? "NULL" : "(NULL)");
if( limit<0 ) limit = strlen(escarg);
if( precision>=0 && precision<limit ) limit = precision;
for(i=n=0; i<limit; i++){
if( escarg[i]==q ) n++;
}
needQuote = !isnull && xtype==etSQLESCAPE2;
n += i + 1 + needQuote*2;
if( n>etBUFSIZE ){
bufpt = zExtra = fossil_malloc( n );
}else{
bufpt = buf;
}
j = 0;
if( needQuote ) bufpt[j++] = q;
for(i=0; i<limit; i++){
bufpt[j++] = ch = escarg[i];
if( ch==q ) bufpt[j++] = ch;
}
if( needQuote ) bufpt[j++] = q;
bufpt[j] = 0;
length = j;
break;
}
case etHTMLIZE: {
int limit = flag_alternateform ? va_arg(ap,int) : -1;
char *zMem = va_arg(ap,char*);
if( zMem==0 ) zMem = "";
zExtra = bufpt = htmlize(zMem, limit);
|
| ︙ | ︙ | |||
1156 1157 1158 1159 1160 1161 1162 |
}
else
#endif
if( g.cgiOutput==1 && g.db ){
g.cgiOutput = 2;
cgi_reset_content();
cgi_set_content_type("text/html");
| > | > > > > > > | | > | 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 |
}
else
#endif
if( g.cgiOutput==1 && g.db ){
g.cgiOutput = 2;
cgi_reset_content();
cgi_set_content_type("text/html");
if( g.zLogin!=0 ){
style_set_current_feature("error");
}
style_header("Bad Request");
etag_cancel();
if( g.zLogin==0 ){
/* Do not give unnecessary clues about a malfunction to robots */
@ <p>Something did not work right.</p>
@ <p>%h(z)</p>
}else{
@ <p class="generalError">%h(z)</p>
cgi_set_status(400, "Bad Request");
}
style_finish_page();
cgi_reply();
}else if( !g.fQuiet ){
fossil_force_newline();
fossil_trace("%s\n", z);
}
return rc;
|
| ︙ | ︙ |
Changes to src/repolist.c.
| ︙ | ︙ | |||
155 156 157 158 159 160 161 162 163 164 165 166 167 |
" WHERE name GLOB 'repo:*'"
);
allRepo = 1;
}else{
/* The default case: All repositories under the g.zRepositoryName
** directory.
*/
blob_init(&base, g.zRepositoryName, -1);
db_close(0);
assert( g.db==0 );
sqlite3_open(":memory:", &g.db);
db_multi_exec("CREATE TABLE sfile(pathname TEXT);");
db_multi_exec("CREATE TABLE vfile(pathname);");
| > > | > | 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 |
" WHERE name GLOB 'repo:*'"
);
allRepo = 1;
}else{
/* The default case: All repositories under the g.zRepositoryName
** directory.
*/
Glob *pExclude;
blob_init(&base, g.zRepositoryName, -1);
db_close(0);
assert( g.db==0 );
sqlite3_open(":memory:", &g.db);
db_multi_exec("CREATE TABLE sfile(pathname TEXT);");
db_multi_exec("CREATE TABLE vfile(pathname);");
pExclude = glob_create("*/proc,proc");
vfile_scan(&base, blob_size(&base), 0, pExclude, 0, ExtFILE);
glob_free(pExclude);
db_multi_exec("DELETE FROM sfile WHERE pathname NOT GLOB '*[^/].fossil'"
#if USE_SEE
" AND pathname NOT GLOB '*[^/].efossil'"
#endif
);
allRepo = 0;
}
|
| ︙ | ︙ |
Changes to src/security_audit.c.
| ︙ | ︙ | |||
828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 |
** y=0x001 Show only hack attempts
** y=0x002 Show only panics and assertion faults
** y=0x004 Show hung backoffice processes
** y=0x008 Show POST requests from a different origin
** y=0x010 Show SQLITE_AUTH and similar
** y=0x020 Show SMTP error reports
** y=0x040 Show TH1 vulnerability reports
** y=0x800 Show other uncategorized messages
**
** If y is omitted or is zero, a count of the various message types is
** shown.
*/
void errorlog_page(void){
i64 szFile;
FILE *in;
char *zLog;
const char *zType = P("y");
| > | > | 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 |
** y=0x001 Show only hack attempts
** y=0x002 Show only panics and assertion faults
** y=0x004 Show hung backoffice processes
** y=0x008 Show POST requests from a different origin
** y=0x010 Show SQLITE_AUTH and similar
** y=0x020 Show SMTP error reports
** y=0x040 Show TH1 vulnerability reports
** y=0x080 Show SQL errors
** y=0x800 Show other uncategorized messages
**
** If y is omitted or is zero, a count of the various message types is
** shown.
*/
void errorlog_page(void){
i64 szFile;
FILE *in;
char *zLog;
const char *zType = P("y");
static const int eAllTypes = 0x8ff;
long eType = 0;
int bOutput = 0;
int prevWasTime = 0;
int nHack = 0;
int nPanic = 0;
int nOther = 0;
int nHang = 0;
int nXPost = 0;
int nAuth = 0;
int nSmtp = 0;
int nVuln = 0;
int nSqlErr = 0;
char z[10000];
char zTime[10000];
login_check_credentials();
if( !g.perm.Admin ){
login_needed(0);
return;
|
| ︙ | ︙ | |||
931 932 933 934 935 936 937 938 939 940 941 942 943 944 |
@ <li>SQLITE_AUTH and similar errors
}
if( eType & 0x20 ){
@ <li>SMTP malfunctions
}
if( eType & 0x40 ){
@ <li>TH1 vulnerabilities
}
if( eType & 0x800 ){
@ <li>Other uncategorized messages
}
@ </ul>
}
@ <hr>
| > > > | 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 |
@ <li>SQLITE_AUTH and similar errors
}
if( eType & 0x20 ){
@ <li>SMTP malfunctions
}
if( eType & 0x40 ){
@ <li>TH1 vulnerabilities
}
if( eType & 0x80 ){
@ <li>SQL errors
}
if( eType & 0x800 ){
@ <li>Other uncategorized messages
}
@ </ul>
}
@ <hr>
|
| ︙ | ︙ | |||
973 974 975 976 977 978 979 980 981 982 983 984 985 986 |
bOutput = (eType & 0x10)!=0;
nAuth++;
}else
if( strncmp(z,"possible", 8)==0 && strstr(z,"tainted")!=0 ){
bOutput = (eType & 0x40)!=0;
nVuln++;
}else
{
bOutput = (eType & 0x800)!=0;
nOther++;
}
if( bOutput ){
@ %h(zTime)\
}
| > > > > | 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 |
bOutput = (eType & 0x10)!=0;
nAuth++;
}else
if( strncmp(z,"possible", 8)==0 && strstr(z,"tainted")!=0 ){
bOutput = (eType & 0x40)!=0;
nVuln++;
}else
if( strstr(z,"statement aborts at ") ){
bOutput = (eType & 0x80)!=0;
nSqlErr++;
}else
{
bOutput = (eType & 0x800)!=0;
nOther++;
}
if( bOutput ){
@ %h(zTime)\
}
|
| ︙ | ︙ | |||
998 999 1000 1001 1002 1003 1004 |
}
}
fclose(in);
if( eType ){
@ </pre>
}
if( eType==0 ){
| | > > > > | 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 |
}
}
fclose(in);
if( eType ){
@ </pre>
}
if( eType==0 ){
int nNonHack = nPanic + nHang + nAuth + nSmtp + nVuln + nOther + nSqlErr;
int nTotal = nNonHack + nHack + nXPost;
@ <p><table border="a" cellspacing="0" cellpadding="5">
if( nPanic>0 ){
@ <tr><td align="right">%d(nPanic)</td>
@ <td><a href="./errorlog?y=2">Panics</a></td>
}
if( nVuln>0 ){
@ <tr><td align="right">%d(nVuln)</td>
@ <td><a href="./errorlog?y=64">TH1 Vulnerabilities</a></td>
}
if( nHack>0 ){
@ <tr><td align="right">%d(nHack)</td>
@ <td><a href="./errorlog?y=1">Hack Attempts</a></td>
}
if( nSqlErr>0 ){
@ <tr><td align="right">%d(nSqlErr)</td>
@ <td><a href="./errorlog?y=128">SQL Errors</a></td>
}
if( nHang>0 ){
@ <tr><td align="right">%d(nHang)</td>
@ <td><a href="./errorlog?y=4">Hung Backoffice</a></td>
}
if( nXPost>0 ){
@ <tr><td align="right">%d(nXPost)</td>
@ <td><a href="./errorlog?y=8">POSTs from different origin</a></td>
|
| ︙ | ︙ |
Changes to src/setupuser.c.
| ︙ | ︙ | |||
406 407 408 409 410 411 412 |
zLogin, zNewCaps, g.zLogin);
} else {
blob_appendf(&body, "Permissions for user [%q] where changed "
"from [%q] to [%q] by user [%q].\n",
zLogin, zOrigCaps, zNewCaps, g.zLogin);
}
if( zURL ){
| | | 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 |
zLogin, zNewCaps, g.zLogin);
} else {
blob_appendf(&body, "Permissions for user [%q] where changed "
"from [%q] to [%q] by user [%q].\n",
zLogin, zOrigCaps, zNewCaps, g.zLogin);
}
if( zURL ){
blob_appendf(&body, "\nUser editor: %s/setup_uedit?id=%d\n", zURL, uid);
}
nBody = blob_size(&body);
pSender = alert_sender_new(0, 0);
db_prepare(&q,
"SELECT semail, hex(subscriberCode)"
" FROM subscriber, user "
" WHERE sverified AND NOT sdonotcall"
|
| ︙ | ︙ |
Changes to src/stat.c.
| ︙ | ︙ | |||
266 267 268 269 270 271 272 |
}
}
}
@ <tr><th>Project Age:</th><td>
z = db_text(0, "SELECT timediff('now',(SELECT min(mtime) FROM event));");
sscanf(z, "+%d-%d-%d", &Y, &M, &D);
if( Y>0 ){
| | | > | > | 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 |
}
}
}
@ <tr><th>Project Age:</th><td>
z = db_text(0, "SELECT timediff('now',(SELECT min(mtime) FROM event));");
sscanf(z, "+%d-%d-%d", &Y, &M, &D);
if( Y>0 ){
@ %d(Y) year%s(Y==1?"":"s") \
}
if( M>0 ){
@ %d(M) month%s(M==1?"":"s") \
}
if( D>0 || (Y==0 && M==0) ){
@ %d(D) day%s(D==1?"":"s")
}
@ </td></tr>
p = db_get("project-code", 0);
if( p ){
@ <tr><th>Project ID:</th>
@ <td>%h(p) %h(db_get("project-name",""))</td></tr>
}
p = db_get("parent-project-code", 0);
|
| ︙ | ︙ |
Changes to src/tag.c.
| ︙ | ︙ | |||
410 411 412 413 414 415 416 | ** --propagate Propagating tag ** --raw Raw tag name. Ignored for ** non-CHECK-IN artifacts. ** --user-override USER Name USER when adding the tag ** ** The --date-override and --user-override options support ** importing history from other SCM systems. DATETIME has | | | 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 | ** --propagate Propagating tag ** --raw Raw tag name. Ignored for ** non-CHECK-IN artifacts. ** --user-override USER Name USER when adding the tag ** ** The --date-override and --user-override options support ** importing history from other SCM systems. DATETIME has ** the form 'YYYY-MM-DD HH:MM:SS'. ** ** Note that fossil uses some tag prefixes internally and this ** command will reject tags with these prefixes to avoid ** causing problems or confusion: "wiki-", "tkt-", "event-". ** ** > fossil tag cancel ?--raw? TAGNAME ARTIFACT-ID ** |
| ︙ | ︙ |
Changes to src/th_tcl.c.
| ︙ | ︙ | |||
22 23 24 25 26 27 28 29 30 31 32 33 34 35 | #ifdef FOSSIL_ENABLE_TCL #include "sqlite3.h" #include "th.h" #include "tcl.h" /* ** This macro is used to verify that the header version of Tcl meets some ** minimum requirement. */ #define MINIMUM_TCL_VERSION(major, minor) \ ((TCL_MAJOR_VERSION > (major)) || \ ((TCL_MAJOR_VERSION == (major)) && (TCL_MINOR_VERSION >= (minor)))) | > > > > | 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | #ifdef FOSSIL_ENABLE_TCL #include "sqlite3.h" #include "th.h" #include "tcl.h" #if TCL_MAJOR_VERSION<9 && !defined(Tcl_Size) # define Tcl_Size int #endif /* ** This macro is used to verify that the header version of Tcl meets some ** minimum requirement. */ #define MINIMUM_TCL_VERSION(major, minor) \ ((TCL_MAJOR_VERSION > (major)) || \ ((TCL_MAJOR_VERSION == (major)) && (TCL_MINOR_VERSION >= (minor)))) |
| ︙ | ︙ | |||
181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 | ** when the Tcl library is being loaded dynamically by a stubs-enabled ** application (i.e. the inverse of using a stubs-enabled package). These are ** the only Tcl API functions that MUST be called prior to being able to call ** Tcl_InitStubs (i.e. because it requires a Tcl interpreter). For complete ** cleanup if the Tcl stubs initialization fails somehow, the Tcl_DeleteInterp ** and Tcl_Finalize function types are also required. */ typedef const char *(tcl_FindExecutableProc) (const char *); typedef Tcl_Interp *(tcl_CreateInterpProc) (void); typedef void (tcl_DeleteInterpProc) (Tcl_Interp *); typedef void (tcl_FinalizeProc) (void); /* ** The function types for the "hook" functions to be called before and after a ** TH1 command makes a call to evaluate a Tcl script. If the "pre" function | > > > > | 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 | ** when the Tcl library is being loaded dynamically by a stubs-enabled ** application (i.e. the inverse of using a stubs-enabled package). These are ** the only Tcl API functions that MUST be called prior to being able to call ** Tcl_InitStubs (i.e. because it requires a Tcl interpreter). For complete ** cleanup if the Tcl stubs initialization fails somehow, the Tcl_DeleteInterp ** and Tcl_Finalize function types are also required. */ #if TCL_MAJOR_VERSION>=9 typedef const char *(tcl_FindExecutableProc) (const char *); #else typedef void (tcl_FindExecutableProc) (const char *); #endif typedef Tcl_Interp *(tcl_CreateInterpProc) (void); typedef void (tcl_DeleteInterpProc) (Tcl_Interp *); typedef void (tcl_FinalizeProc) (void); /* ** The function types for the "hook" functions to be called before and after a ** TH1 command makes a call to evaluate a Tcl script. If the "pre" function |
| ︙ | ︙ |
Changes to src/timeline.c.
| ︙ | ︙ | |||
1271 1272 1273 1274 1275 1276 1277 |
** for the SQL statement under construction that excludes any check-in that
** does not modify one or more files matching the globs.
*/
static void addFileGlobExclusion(
const char *zChng, /* The filename GLOB list */
Blob *pSql /* The SELECT statement under construction */
){
| | | > > > > > > > > > > > > > > > > > > > | 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 |
** for the SQL statement under construction that excludes any check-in that
** does not modify one or more files matching the globs.
*/
static void addFileGlobExclusion(
const char *zChng, /* The filename GLOB list */
Blob *pSql /* The SELECT statement under construction */
){
if( zChng==0 ) return;
blob_append_sql(pSql," AND event.objid IN ("
"SELECT mlink.mid FROM mlink, filename\n"
" WHERE mlink.fnid=filename.fnid\n"
" AND %s)",
glob_expr("filename.name", mprintf("\"%s\"", zChng)));
}
static void addFileGlobDescription(
const char *zChng, /* The filename GLOB list */
Blob *pDescription /* Result description */
){
if( zChng==0 ) return;
blob_appendf(pDescription, " that include changes to files matching '%h'",
zChng);
}
/*
** If zChng is not NULL, then use it as a comma-separated list of
** glob patterns for filenames, and remove from the "ok" table any
** check-ins that do not modify one or more of the files identified
** by zChng.
*/
static void removeFileGlobFromOk(
const char *zChng /* The filename GLOB list */
){
if( zChng==0 ) return;
db_multi_exec(
"DELETE FROM ok WHERE rid NOT IN (\n"
" SELECT mlink.mid FROM mlink, filename\n"
" WHERE mlink.fnid=filename.fnid\n"
" AND %z);\n",
glob_expr("filename.name", zChng)
);
}
/*
** Similar to fossil_expand_datetime()
**
** Add missing "-" characters into a date/time. Examples:
**
** 20190419 => 2019-04-19
|
| ︙ | ︙ | |||
1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 |
z = P("df");
if( z && (d_rid = name_to_typed_rid(z,"ci"))!=0 ){
nEntry = 0;
useDividers = 0;
cgi_replace_query_parameter("d",fossil_strdup(z));
zDPNameD = zDPNameP = z;
}
/* Undocumented query parameter to set JS mode */
builtin_set_js_delivery_mode(P("jsmode"),1);
secondaryRid = name_to_typed_rid(P("sel2"),"ci");
selectedRid = name_to_typed_rid(P("sel1"),"ci");
if( from_rid!=0 && to_rid!=0 ){
| > | 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 |
z = P("df");
if( z && (d_rid = name_to_typed_rid(z,"ci"))!=0 ){
nEntry = 0;
useDividers = 0;
cgi_replace_query_parameter("d",fossil_strdup(z));
zDPNameD = zDPNameP = z;
}
if( zChng && zChng[0]==0 ) zChng = 0;
/* Undocumented query parameter to set JS mode */
builtin_set_js_delivery_mode(P("jsmode"),1);
secondaryRid = name_to_typed_rid(P("sel2"),"ci");
selectedRid = name_to_typed_rid(P("sel1"),"ci");
if( from_rid!=0 && to_rid!=0 ){
|
| ︙ | ︙ | |||
2172 2173 2174 2175 2176 2177 2178 2179 |
db_multi_exec(
"DELETE FROM related WHERE x NOT IN ok;"
);
}
db_multi_exec("INSERT OR IGNORE INTO pathnode SELECT x FROM related");
}
add_extra_rids("pathnode",P("x"));
blob_append_sql(&sql, " AND event.objid IN pathnode");
| > > | | 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 |
db_multi_exec(
"DELETE FROM related WHERE x NOT IN ok;"
);
}
db_multi_exec("INSERT OR IGNORE INTO pathnode SELECT x FROM related");
}
add_extra_rids("pathnode",P("x"));
add_extra_rids("pathnode",P("sel1"));
add_extra_rids("pathnode",P("sel2"));
blob_append_sql(&sql, " AND event.objid IN pathnode");
if( zChng ){
db_multi_exec(
"DELETE FROM pathnode\n"
" WHERE NOT EXISTS(SELECT 1 FROM mlink, filename\n"
" WHERE mlink.mid=x\n"
" AND mlink.fnid=filename.fnid\n"
" AND %s)",
glob_expr("filename.name", zChng)
|
| ︙ | ︙ | |||
2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 |
}else{
zBaseName = p_rid ? zDPNameP : zDPNameD;
}
db_multi_exec(
"CREATE TEMP TABLE IF NOT EXISTS ok(rid INTEGER PRIMARY KEY)"
);
add_extra_rids("ok", P("x"));
blob_append_sql(&sql, " AND event.objid IN ok");
nd = 0;
if( d_rid ){
double rStopTime = 9e99;
zFwdTo = P("ft");
if( zFwdTo && bSeparateDandP ){
if( zError==0 ){
| > > | 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 |
}else{
zBaseName = p_rid ? zDPNameP : zDPNameD;
}
db_multi_exec(
"CREATE TEMP TABLE IF NOT EXISTS ok(rid INTEGER PRIMARY KEY)"
);
add_extra_rids("ok", P("x"));
add_extra_rids("ok", P("sel1"));
add_extra_rids("ok", P("sel2"));
blob_append_sql(&sql, " AND event.objid IN ok");
nd = 0;
if( d_rid ){
double rStopTime = 9e99;
zFwdTo = P("ft");
if( zFwdTo && bSeparateDandP ){
if( zError==0 ){
|
| ︙ | ︙ | |||
2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 |
}
if( bSeparateDandP ){
db_multi_exec(
"INSERT INTO ok_d SELECT rid FROM ok;"
"DELETE FROM ok;"
);
}else{
nd = db_int(0, "SELECT count(*)-1 FROM ok");
if( nd>=0 ) db_multi_exec("%s", blob_sql_text(&sql));
if( nd>0 || p_rid==0 ){
| > | > | 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 |
}
if( bSeparateDandP ){
db_multi_exec(
"INSERT INTO ok_d SELECT rid FROM ok;"
"DELETE FROM ok;"
);
}else{
removeFileGlobFromOk(zChng);
nd = db_int(0, "SELECT count(*)-1 FROM ok");
if( nd>=0 ) db_multi_exec("%s", blob_sql_text(&sql));
if( nd>0 || p_rid==0 ){
blob_appendf(&desc, "%d descendant%s",
nd>=0 ? nd : 0,(1==nd)?"":"s");
}
if( useDividers && !selectedRid ) selectedRid = d_rid;
db_multi_exec("DELETE FROM ok");
}
}
if( p_rid ){
zBackTo = P("bt");
|
| ︙ | ︙ | |||
2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 |
compute_ancestors(p_rid, nEntry==0 ? 0 : nEntry+1, 0, ridBackTo);
if( ridBackTo && !db_exists("SELECT 1 FROM ok WHERE rid=%d",ridBackTo) ){
db_multi_exec("INSERT OR IGNORE INTO ok VALUES(%d)", ridBackTo);
bBackAdded = 1;
}
if( bSeparateDandP ){
db_multi_exec("DELETE FROM ok WHERE rid NOT IN ok_d;");
db_multi_exec("%s", blob_sql_text(&sql));
}else{
np = db_int(0, "SELECT count(*)-1 FROM ok");
if( np>0 || nd==0 ){
if( nd>0 ) blob_appendf(&desc, " and ");
| > > | > > | | | | | 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 |
compute_ancestors(p_rid, nEntry==0 ? 0 : nEntry+1, 0, ridBackTo);
if( ridBackTo && !db_exists("SELECT 1 FROM ok WHERE rid=%d",ridBackTo) ){
db_multi_exec("INSERT OR IGNORE INTO ok VALUES(%d)", ridBackTo);
bBackAdded = 1;
}
if( bSeparateDandP ){
db_multi_exec("DELETE FROM ok WHERE rid NOT IN ok_d;");
removeFileGlobFromOk(zChng);
db_multi_exec("%s", blob_sql_text(&sql));
}else{
removeFileGlobFromOk(zChng);
np = db_int(0, "SELECT count(*)-1 FROM ok");
if( np>0 || nd==0 ){
if( nd>0 ) blob_appendf(&desc, " and ");
blob_appendf(&desc, "%d ancestor%s",
np>=0 ? np : 0, (1==np)?"":"s");
db_multi_exec("%s", blob_sql_text(&sql));
}
if( useDividers && !selectedRid ) selectedRid = p_rid;
}
}
if( bSeparateDandP ){
int n = db_int(0, "SELECT count(*) FROM ok");
blob_reset(&desc);
blob_appendf(&desc,
"%d check-ins that are derived from %z%h</a>"
" and contribute to %z%h</a>",
n,
href("%R/info?name=%h",zDPNameD),zDPNameD,
href("%R/info?name=%h",zDPNameP),zDPNameP
);
ridBackTo = 0;
ridFwdTo = 0;
}else{
blob_appendf(&desc, " of %z%h</a>",
href("%R/info?name=%h", zBaseName), zBaseName);
}
|
| ︙ | ︙ | |||
2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 |
href("%R/info?name=%h",zFwdTo), zFwdTo);
}else{
blob_appendf(&desc, " up to %z%h</a>%s",
href("%R/info?name=%h",zFwdTo), zFwdTo,
bFwdAdded ? " (not a direct descendant)":"");
}
}
if( advancedMenu ){
style_submenu_checkbox("v", "Files", (zType[0]!='a' && zType[0]!='c'),0);
}
style_submenu_entry("n","Max:",4,0);
timeline_y_submenu(1);
}else if( f_rid && g.perm.Read ){
/* If f= is present, ignore all other parameters other than n= */
| > > > > | 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 |
href("%R/info?name=%h",zFwdTo), zFwdTo);
}else{
blob_appendf(&desc, " up to %z%h</a>%s",
href("%R/info?name=%h",zFwdTo), zFwdTo,
bFwdAdded ? " (not a direct descendant)":"");
}
}
if( zChng ){
if( strstr(blob_str(&desc)," that ") ) blob_appendf(&desc, " and");
blob_appendf(&desc, " that make changes to files matching \"%h\"", zChng);
}
if( advancedMenu ){
style_submenu_checkbox("v", "Files", (zType[0]!='a' && zType[0]!='c'),0);
}
style_submenu_entry("n","Max:",4,0);
timeline_y_submenu(1);
}else if( f_rid && g.perm.Read ){
/* If f= is present, ignore all other parameters other than n= */
|
| ︙ | ︙ | |||
2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 |
/* If the t=release option is used with m=UUID, then also
** include the UUID check-in in the display list */
int ridMark = name_to_rid(zMark);
db_multi_exec(
"INSERT OR IGNORE INTO selected_nodes(rid) VALUES(%d)", ridMark);
}
add_extra_rids("selected_nodes",P("x"));
if( related==0 ){
blob_append_sql(&cond, " AND blob.rid IN selected_nodes");
}else{
db_multi_exec(
"CREATE TEMP TABLE related_nodes(rid INTEGER PRIMARY KEY);"
"INSERT INTO related_nodes SELECT rid FROM selected_nodes;"
);
| > > | 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 |
/* If the t=release option is used with m=UUID, then also
** include the UUID check-in in the display list */
int ridMark = name_to_rid(zMark);
db_multi_exec(
"INSERT OR IGNORE INTO selected_nodes(rid) VALUES(%d)", ridMark);
}
add_extra_rids("selected_nodes",P("x"));
add_extra_rids("selected_nodes",P("sel1"));
add_extra_rids("selected_nodes",P("sel2"));
if( related==0 ){
blob_append_sql(&cond, " AND blob.rid IN selected_nodes");
}else{
db_multi_exec(
"CREATE TEMP TABLE related_nodes(rid INTEGER PRIMARY KEY);"
"INSERT INTO related_nodes SELECT rid FROM selected_nodes;"
);
|
| ︙ | ︙ | |||
3814 3815 3816 3817 3818 3819 3820 3821 3822 |
" WHERE tx.value='%q'\n"
")\n" /* No merge closures */
" AND (tagxref.value IS NULL OR tagxref.value='%q')",
zBr, zBr, zBr, TAG_BRANCH, zBr, zBr);
}
if( mode==TIMELINE_MODE_AFTER ){
/* Complete the above outer select. */
blob_append_sql(&sql,
| > > > > > > | | 3850 3851 3852 3853 3854 3855 3856 3857 3858 3859 3860 3861 3862 3863 3864 3865 3866 3867 3868 3869 3870 3871 3872 |
" WHERE tx.value='%q'\n"
")\n" /* No merge closures */
" AND (tagxref.value IS NULL OR tagxref.value='%q')",
zBr, zBr, zBr, TAG_BRANCH, zBr, zBr);
}
if( mode==TIMELINE_MODE_AFTER ){
int lim = n;
if( n == 0 ){
lim = -1; /* 0 means no limit */
}else if( n < 0 ){
lim = -n;
}
/* Complete the above outer select. */
blob_append_sql(&sql,
"\nORDER BY event.mtime LIMIT %d) t ORDER BY t.mDateTime DESC;", lim);
}else{
blob_append_sql(&sql, "\nORDER BY event.mtime DESC");
}
if( iOffset>0 ){
/* Don't handle LIMIT here, otherwise print_timeline()
* will not determine the end-marker correctly! */
blob_append_sql(&sql, "\n LIMIT -1 OFFSET %d", iOffset);
|
| ︙ | ︙ | |||
3845 3846 3847 3848 3849 3850 3851 |
** day of the year for various years in the history of the project.
**
** Query parameters:
**
** today=DATE Use DATE as today's date
*/
void thisdayinhistory_page(void){
| | | 3887 3888 3889 3890 3891 3892 3893 3894 3895 3896 3897 3898 3899 3900 3901 |
** day of the year for various years in the history of the project.
**
** Query parameters:
**
** today=DATE Use DATE as today's date
*/
void thisdayinhistory_page(void){
static int aYearsAgo[] = { 1,2,3,4,5,10,15,20,25,30,40,50,75,100 };
const char *zToday;
char *zStartOfProject;
int i;
Stmt q;
char *z;
int bZulu = 0;
|
| ︙ | ︙ |
Changes to src/tkt.c.
| ︙ | ︙ | |||
774 775 776 777 778 779 780 |
}
if( !showTimeline && g.perm.Hyperlink ){
style_submenu_element("Timeline", "%R/info/%T", zUuid);
}
zFullName = db_text(0,
"SELECT tkt_uuid FROM ticket"
" WHERE tkt_uuid GLOB '%q*'", zUuid);
| < < < < | 774 775 776 777 778 779 780 781 782 783 784 785 786 787 |
}
if( !showTimeline && g.perm.Hyperlink ){
style_submenu_element("Timeline", "%R/info/%T", zUuid);
}
zFullName = db_text(0,
"SELECT tkt_uuid FROM ticket"
" WHERE tkt_uuid GLOB '%q*'", zUuid);
if( g.thTrace ) Th_Trace("BEGIN_TKTVIEW<br>\n", -1);
ticket_init();
initializeVariablesFromCGI();
getAllTicketFields();
initializeVariablesFromDb();
zScript = ticket_viewpage_code();
if( P("showfields")!=0 ) showAllFields();
|
| ︙ | ︙ |
Changes to src/tktsetup.c.
| ︙ | ︙ | |||
494 495 496 497 498 499 500 501 502 503 504 505 506 507 |
@ html "<td class='tktDspValue' colspan='3'>Deleted</td></tr>\n"
@ }
@ }
@
@ if {[capexpr {n}]} {
@ submenu link "Copy Ticket" /tktnew/$tkt_uuid
@ }
@ </th1>
@ <tr><td class="tktDspLabel">Title:</td>
@ <td class="tktDspValue" colspan="3">
@ $<title>
@ </td></tr>
@ <tr><td class="tktDspLabel">Status:</td><td class="tktDspValue">
@ $<status>
| > > > | 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 |
@ html "<td class='tktDspValue' colspan='3'>Deleted</td></tr>\n"
@ }
@ }
@
@ if {[capexpr {n}]} {
@ submenu link "Copy Ticket" /tktnew/$tkt_uuid
@ }
@ if {[capexpr {nk}]} {
@ submenu link "Edit Wiki" /wikiedit?name=ticket/$tkt_uuid
@ }
@ </th1>
@ <tr><td class="tktDspLabel">Title:</td>
@ <td class="tktDspValue" colspan="3">
@ $<title>
@ </td></tr>
@ <tr><td class="tktDspLabel">Status:</td><td class="tktDspValue">
@ $<status>
|
| ︙ | ︙ |
Changes to src/wiki.c.
| ︙ | ︙ | |||
2581 2582 2583 2584 2585 2586 2587 |
** Add an "Wiki" button in a submenu that links to the read-wiki page.
*/
static void wiki_submenu_to_read_wiki(
const char *zPrefix, /* "branch", "tag", or "checkin" */
const char *zName, /* Name of the object */
unsigned int mFlags /* Zero or more WIKIASSOC_* flags */
){
| | > > > | 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 |
** Add an "Wiki" button in a submenu that links to the read-wiki page.
*/
static void wiki_submenu_to_read_wiki(
const char *zPrefix, /* "branch", "tag", or "checkin" */
const char *zName, /* Name of the object */
unsigned int mFlags /* Zero or more WIKIASSOC_* flags */
){
if( g.perm.RdWiki && (mFlags & WIKIASSOC_MENU_READ)!=0
&& 0!=fossil_strcmp("branch", zPrefix)
/* ^^^ https://fossil-scm.org/forum/forumpost/ff453de2f30791dd */
){
style_submenu_element("Wiki", "%R/wiki?name=%s/%t", zPrefix, zName);
}
}
/*
** Add an "Edit Wiki" button in a submenu that links to the edit-wiki page.
*/
|
| ︙ | ︙ |
Changes to src/winfile.c.
| ︙ | ︙ | |||
302 303 304 305 306 307 308 |
** undesirable in file name comparison, so lstrcmpiW() is only invoked in cases
** that are technically impossible and contradicting all known laws of physics.
*/
int win32_filenames_equal_nocase(
const wchar_t *fn1,
const wchar_t *fn2
){
| > > > > > > > > > > > > | | | | | | < < < < | | | 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 |
** undesirable in file name comparison, so lstrcmpiW() is only invoked in cases
** that are technically impossible and contradicting all known laws of physics.
*/
int win32_filenames_equal_nocase(
const wchar_t *fn1,
const wchar_t *fn2
){
/* ---- Data types used by dynamically loaded API functions. -------------- */
typedef struct { /* UNICODE_STRING from <ntdef.h> */
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} MY_UNICODE_STRING;
/* ---- Prototypes for dynamically loaded API functions. ------------------ */
typedef int (WINAPI *FNCOMPARESTRINGORDINAL)(LPCWCH,int,LPCWCH,int,BOOL);
typedef VOID (NTAPI *FNRTLINITUNICODESTRING)(MY_UNICODE_STRING*,PCWSTR);
typedef BOOLEAN (NTAPI *FNRTLEQUALUNICODESTRING)
(MY_UNICODE_STRING*,MY_UNICODE_STRING*,BOOLEAN);
/* ------------------------------------------------------------------------ */
static FNCOMPARESTRINGORDINAL fnCompareStringOrdinal;
static FNRTLINITUNICODESTRING fnRtlInitUnicodeString;
static FNRTLEQUALUNICODESTRING fnRtlEqualUnicodeString;
static int loaded_CompareStringOrdinal;
static int loaded_RtlUnicodeStringAPIs;
if( !loaded_CompareStringOrdinal ){
fnCompareStringOrdinal = (FNCOMPARESTRINGORDINAL)
GetProcAddress(GetModuleHandleA("kernel32"),"CompareStringOrdinal");
loaded_CompareStringOrdinal = 1;
}
if( fnCompareStringOrdinal ){
return fnCompareStringOrdinal(fn1,-1,fn2,-1,1)-2==0;
}
if( !loaded_RtlUnicodeStringAPIs ){
fnRtlInitUnicodeString = (FNRTLINITUNICODESTRING)
GetProcAddress(GetModuleHandleA("ntdll"),"RtlInitUnicodeString");
fnRtlEqualUnicodeString = (FNRTLEQUALUNICODESTRING)
GetProcAddress(GetModuleHandleA("ntdll"),"RtlEqualUnicodeString");
loaded_RtlUnicodeStringAPIs = 1;
}
if( fnRtlInitUnicodeString && fnRtlEqualUnicodeString ){
MY_UNICODE_STRING u1, u2;
fnRtlInitUnicodeString(&u1,fn1);
fnRtlInitUnicodeString(&u2,fn2);
return (BOOLEAN/*unsigned char*/)fnRtlEqualUnicodeString(&u1,&u2,1);
}
/* In what kind of strange parallel universe are we? */
return lstrcmpiW(fn1,fn2)==0;
}
/* Helper macros to deal with directory separators. */
#define IS_DIRSEP(s,i) ( s[i]=='/' || s[i]=='\\' )
|
| ︙ | ︙ | |||
459 460 461 462 463 464 465 |
** Call the GetFileInformationByHandleEx() function on Windows Vista, and resort
** to the GetFileInformationByHandle() function on Windows XP. The result string
** is allocated by mprintf(), or NULL on failure.
*/
char *win32_file_id(
const char *zFileName
){
| > > > > > > > > > | | < < < | > | | 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 |
** Call the GetFileInformationByHandleEx() function on Windows Vista, and resort
** to the GetFileInformationByHandle() function on Windows XP. The result string
** is allocated by mprintf(), or NULL on failure.
*/
char *win32_file_id(
const char *zFileName
){
/* ---- Data types used by dynamically loaded API functions. -------------- */
typedef struct { /* FILE_ID_INFO from <winbase.h> */
ULONGLONG VolumeSerialNumber;
BYTE FileId[16];
} MY_FILE_ID_INFO;
/* ---- Prototypes for dynamically loaded API functions. ------------------ */
typedef int (WINAPI *FNGETFILEINFORMATIONBYHANDLEEX)
(HANDLE,int/*enum*/,MY_FILE_ID_INFO*,DWORD);
/* ------------------------------------------------------------------------ */
static FNGETFILEINFORMATIONBYHANDLEEX fnGetFileInformationByHandleEx;
static int loaded_fnGetFileInformationByHandleEx;
wchar_t *wzFileName = fossil_utf8_to_path(zFileName,0);
HANDLE hFile;
char *zFileId = 0;
hFile = CreateFileW(
wzFileName,
0,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL,
OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS,
NULL);
if( hFile!=INVALID_HANDLE_VALUE ){
BY_HANDLE_FILE_INFORMATION fi;
MY_FILE_ID_INFO fi2;
if( !loaded_fnGetFileInformationByHandleEx ){
fnGetFileInformationByHandleEx = (FNGETFILEINFORMATIONBYHANDLEEX)
GetProcAddress(
GetModuleHandleA("kernel32"),"GetFileInformationByHandleEx");
loaded_fnGetFileInformationByHandleEx = 1;
}
if( fnGetFileInformationByHandleEx ){
if( fnGetFileInformationByHandleEx(
hFile,/*FileIdInfo*/0x12,&fi2,sizeof(fi2)) ){
zFileId = mprintf(
"%016llx/"
|
| ︙ | ︙ |
Changes to src/xfer.c.
| ︙ | ︙ | |||
1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 |
int seqno, max;
if( iVers>=3 ){
cgi_set_content_type("application/x-fossil-uncompressed");
}
blob_is_int(&xfer.aToken[2], &seqno);
if( seqno<=0 ){
xfer_fatal_error("invalid clone sequence number");
return;
}
max = db_int(0, "SELECT max(rid) FROM blob");
while( xfer.mxSend>(int)blob_size(xfer.pOut) && seqno<=max){
if( time(NULL) >= xfer.maxTime ) break;
if( iVers>=3 ){
send_compressed_file(&xfer, seqno);
| > | 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 |
int seqno, max;
if( iVers>=3 ){
cgi_set_content_type("application/x-fossil-uncompressed");
}
blob_is_int(&xfer.aToken[2], &seqno);
if( seqno<=0 ){
xfer_fatal_error("invalid clone sequence number");
db_rollback_transaction();
return;
}
max = db_int(0, "SELECT max(rid) FROM blob");
while( xfer.mxSend>(int)blob_size(xfer.pOut) && seqno<=max){
if( time(NULL) >= xfer.maxTime ) break;
if( iVers>=3 ){
send_compressed_file(&xfer, seqno);
|
| ︙ | ︙ | |||
1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 |
*/
if( blob_eq(&xfer.aToken[0],"config") && xfer.nToken==3
&& blob_is_int(&xfer.aToken[2], &size) ){
const char *zName = blob_str(&xfer.aToken[1]);
Blob content;
if( size<0 ){
xfer_fatal_error("invalid config record");
return;
}
blob_zero(&content);
blob_extract(xfer.pIn, size, &content);
if( !g.perm.Admin ){
cgi_reset_content();
@ error not\sauthorized\sto\spush\sconfiguration%s(whyNotAuth())
| > | 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 |
*/
if( blob_eq(&xfer.aToken[0],"config") && xfer.nToken==3
&& blob_is_int(&xfer.aToken[2], &size) ){
const char *zName = blob_str(&xfer.aToken[1]);
Blob content;
if( size<0 ){
xfer_fatal_error("invalid config record");
db_rollback_transaction();
return;
}
blob_zero(&content);
blob_extract(xfer.pIn, size, &content);
if( !g.perm.Admin ){
cgi_reset_content();
@ error not\sauthorized\sto\spush\sconfiguration%s(whyNotAuth())
|
| ︙ | ︙ | |||
2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 |
/* Remember the URL of the sync target in the config file on the
** first successful round-trip */
if( nCycle==0 && db_is_writeable("repository") ){
xfer_syncwith(g.url.canonical, 0);
}
/* Output current stats */
if( syncFlags & SYNC_VERBOSE ){
fossil_print(zValueFormat /*works-like:"%s%d%d%d%d"*/, "Sent:",
blob_size(&send), nCardSent+xfer.nGimmeSent+xfer.nIGotSent,
xfer.nFileSent, xfer.nDeltaSent);
}else{
| > > < < | 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 |
/* Remember the URL of the sync target in the config file on the
** first successful round-trip */
if( nCycle==0 && db_is_writeable("repository") ){
xfer_syncwith(g.url.canonical, 0);
}
/* Output current stats */
nRoundtrip++;
nArtifactSent += xfer.nFileSent + xfer.nDeltaSent;
if( syncFlags & SYNC_VERBOSE ){
fossil_print(zValueFormat /*works-like:"%s%d%d%d%d"*/, "Sent:",
blob_size(&send), nCardSent+xfer.nGimmeSent+xfer.nIGotSent,
xfer.nFileSent, xfer.nDeltaSent);
}else{
if( bOutIsTty!=0 ){
fossil_print(zBriefFormat /*works-like:"%d%d%d"*/,
nRoundtrip, nArtifactSent, nArtifactRcvd);
}
}
nCardSent = 0;
nCardRcvd = 0;
|
| ︙ | ︙ |
Changes to src/zip.c.
| ︙ | ︙ | |||
560 561 562 563 564 565 566 567 568 569 |
fossil_free(azDir[i]);
}
fossil_free(azDir);
nDir = 0;
azDir = 0;
}
/*
** COMMAND: test-filezip
**
| > > > > > > > > | | > > > > > > > > > > > > > < < < < < | > | < < < > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | > > | | > > > | | | | | > | 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 |
fossil_free(azDir[i]);
}
fossil_free(azDir);
nDir = 0;
azDir = 0;
}
/* Functions found in shell.c */
extern int sqlite3_fileio_init(sqlite3*,char**,const sqlite3_api_routines*);
extern int sqlite3_zipfile_init(sqlite3*,char**,const sqlite3_api_routines*);
/*
** COMMAND: test-filezip
**
** Usage: %fossil test-filezip [OPTIONS] ZIPFILE [FILENAME...]
**
** This command uses Fossil infrastructure or read or create a ZIP
** archive named by the ZIPFILE argument. With no options, a new
** ZIP archive is created and there must be at least one FILENAME
** argument. If the -l option is used, the contents of the named ZIP
** archive are listed on standard output. With the -x argument, the
** contents of the ZIP archive are extracted.
**
** There are two purposes for this command: (1) To server as a test
** platform for the Fossil ZIP archive generator, and (2) to provide
** rudimentary ZIP archive creation capabilities on platforms that do
** not have the "zip" command installed.
**
** Options:
**
** -h|--dereference Follow symlinks
** -l|--list List the contents of the ZIP archive
** -x|--extract Extract files from a ZIP archive
*/
void filezip_cmd(void){
int eFType = SymFILE;
int doList = 0;
int doExtract = 0;
char *zArchiveName;
if( find_option("dereference","h",0)!=0 ){
eFType = ExtFILE;
}
if( find_option("list","l",0)!=0 ){
doList = 1;
}
if( find_option("extract","x",0)!=0 ){
if( doList ){
fossil_fatal("incompatible options: -l and -x");
}
doExtract = 1;
}
if( g.argc<3 ){
usage("ARCHIVE FILES...");
}
zArchiveName = g.argv[2];
sqlite3_open(":memory:", &g.db);
if( doList ){
/* Do a content listing of a ZIP archive */
Stmt q;
int nRow = 0;
i64 szTotal = 0;
if( file_size(zArchiveName, eFType)<0 ){
fossil_fatal("No such ZIP archive: %s", zArchiveName);
}
if( g.argc>3 ){
fossil_fatal("extra arguments after \"fossil test-filezip -l ARCHIVE\"");
}
sqlite3_zipfile_init(g.db, 0, 0);
db_multi_exec("CREATE VIRTUAL TABLE z1 USING zipfile(%Q)", zArchiveName);
db_prepare(&q, "SELECT sz, datetime(mtime,'unixepoch'), name FROM z1");
while( db_step(&q)==SQLITE_ROW ){
int sz = db_column_int(&q, 0);
szTotal += sz;
if( nRow==0 ){
fossil_print(" Length Date Time Name\n");
fossil_print("--------- ---------- ----- ----\n");
}
nRow++;
fossil_print("%9d %.16s %s\n", sz, db_column_text(&q,1),
db_column_text(&q,2));
}
if( nRow ){
fossil_print("--------- --------\n");
fossil_print("%9lld %16s %d files\n", szTotal, "", nRow);
}
db_finalize(&q);
}else if( doExtract ){
/* Extract files from an existing ZIP archive */
if( file_size(zArchiveName, eFType)<0 ){
fossil_fatal("No such ZIP archive: %s", zArchiveName);
}
if( g.argc>3 ){
fossil_fatal("extra arguments after \"fossil test-filezip -x ARCHIVE\"");
}
sqlite3_zipfile_init(g.db, 0, 0);
sqlite3_fileio_init(g.db, 0, 0);
db_multi_exec("CREATE VIRTUAL TABLE z1 USING zipfile(%Q)", zArchiveName);
db_multi_exec("SELECT writefile(name,data) FROM z1");
}else{
/* Without the -x or -l options, construct a new ZIP archive */
int i;
Blob zip;
Blob file;
Archive sArchive;
memset(&sArchive, 0, sizeof(Archive));
sArchive.eType = ARCHIVE_ZIP;
sArchive.pBlob = &zip;
if( file_size(zArchiveName, eFType)>0 ){
fossil_fatal("ZIP archive %s already exists", zArchiveName);
}
zip_open();
for(i=3; i<g.argc; i++){
double rDate;
i64 iDate;
blob_zero(&file);
blob_read_from_file(&file, g.argv[i], eFType);
iDate = file_mtime(g.argv[i], eFType);
rDate = ((double)iDate)/86400.0 + 2440587.5;
zip_set_timedate(rDate);
zip_add_file(&sArchive, g.argv[i], &file, file_perm(0,eFType));
blob_reset(&file);
}
zip_close(&sArchive);
blob_write_to_file(&zip, g.argv[2]);
}
}
/*
** Given the RID for a manifest, construct a ZIP archive containing
** all files in the corresponding baseline.
**
** If RID is for an object that is not a real manifest, then the
|
| ︙ | ︙ | |||
925 926 927 928 929 930 931 932 933 934 935 936 937 938 |
char *zType; /* Human-readable archive type */
login_check_credentials();
if( !g.perm.Zip ){ login_needed(g.anon.Zip); return; }
if( fossil_strcmp(g.zPath, "sqlar")==0 ){
eType = ARCHIVE_SQLAR;
zType = "SQL";
}else{
eType = ARCHIVE_ZIP;
zType = "ZIP";
}
fossil_nice_default();
zName = fossil_strdup(PD("name",""));
z = P("r");
| > > > | 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 |
char *zType; /* Human-readable archive type */
login_check_credentials();
if( !g.perm.Zip ){ login_needed(g.anon.Zip); return; }
if( fossil_strcmp(g.zPath, "sqlar")==0 ){
eType = ARCHIVE_SQLAR;
zType = "SQL";
/* For some reason, SQL-archives are like catnip for robots. So
** don't allow them to be downloaded by user "nobody" */
if( g.zLogin==0 ){ login_needed(g.anon.Zip); return; }
}else{
eType = ARCHIVE_ZIP;
zType = "ZIP";
}
fossil_nice_default();
zName = fossil_strdup(PD("name",""));
z = P("r");
|
| ︙ | ︙ |
Added test/link-tester.html.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 |
<!DOCTYPE html>
<head><!--
This file is intended to be loaded from a fossil
repository, either using:
fossil ui --extpage test/link-tester.html
or by adding test/link-tester.* to uv and then:
fossil ui -page uv/link-tester.html
--></head>
<style>
body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
display: flex;
flex-direction: column;
}
header {
margin: 0.5em 0 0 0;
padding: 0 1em 0 1em;
z-index: 1;
}
#controlWrapper {
display: flex;
flex-direction: row;
border-bottom: 2px dotted;
padding-bottom: 0.5em;
}
#controlWrapper > button {
flex-grow: 1;
margin: 0.5em;
}
#selectWrapper {
display: flex;
flex-direction: column;
flex-grow: 8;
}
#selectPage {
flex-grow: 1;
margin: 1em;
padding: 1em;
}
#currentUrl {
font-family: monospace;
text-align: center;
}
#iframe {
flex-grow: 1; border: none; margin: 0; padding: 0;
display: block;
/* Absolute positioning is apparently the only way to get
the iframe to stretch to fill the page, but we have to
set its Y coordinate to something a bit below #controls. */
width: 100%;
height: calc(100% - 5em);
position: absolute;
top: 4em;
}
</style>
<body>
<header>
Fossil link test app. Select links from the list below to load
them. Use the arrow keys to cycle through the list. The links are
loaded within an iframe, so navigation within it will stay within
that frame.
</header>
<header id='controlWrapper'>
<button id='btn-prev'>←</button>
<div id='selectWrapper'>
<select id='selectPage'>
<option>/timeline</option>
<option>/dir</option>
</select>
<a target='_blank' id='currentUrl'></a>
</div>
<button id='btn-next'>→</button>
</header>
<iframe id='iframe'><!--populated via the UI--></iframe>
<script src='link-tester.js'></script>
<body>
|
Added test/link-tester.js.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 |
/**
JS code for link-tester.html. We cannot host this JS inline in that
file because fossil's default Content Security Policy won't let it
run that way.
*/
window.addEventListener("DOMContentLoaded", function(){
const E = function(s){
const e = document.querySelector(s);
if( !e ) throw new Error("Missing element: "+s);
return e;
};
const EAll = function(s){
const e = document.querySelectorAll(s);
if( !e || !e.length ) throw new Error("Missing elements: "+s);
return e;
};
const eIframe = E('#iframe');
const eSelect = E('#selectPage');
const eCurrentUrl = E('#currentUrl');
/*
Prepend the fossil instance's URL to each link. We have to guess
which part of the URL is the fossil CGI/server instance. The
following works when run (A) from under /uv or /ext and (B) from
/doc/branchname/test/link-tester.html.
*/
let urlTop;
let loc = (''+window.location);
let aLoc = loc.split('/')
aLoc.pop(); /* file name */
const thisDir = aLoc.join('/');
const rxDoc = /.*\/doc\/[^/]+\/.*/;
//console.log(rxDoc, loc, aLoc);
if( loc.match(rxDoc) ){
/* We're hopefully now at the top-most fossil-served
URL. */
aLoc.pop(); aLoc.pop(); /* /doc/foo */
aLoc.pop(); /* current dir name */
}else{
aLoc.pop(); /* current dir name */
}
urlTop = aLoc.join('/');
//console.log(urlTop, aLoc);
for( const o of eSelect.options ){
o.value = urlTop + (o.value || o.innerText);
}
const updateUrl = function(opt){
if( opt ){
let url = (opt.value || opt.innerText);
eCurrentUrl.innerText = url.replace(urlTop,'');
eCurrentUrl.setAttribute('href', url);
}else{
eCurrentUrl.innerText = '';
}
};
eSelect.addEventListener('change',function(ev){
const so = ev.target.options[ev.target.selectedIndex];
if( so ){
eIframe.setAttribute('src', so.value || so.innerText);
updateUrl(so);
}
});
/** Select the entry at the given ndx and fire a change event. */
const selectEntry = function(ndx){
if( ndx>=0 ){
eSelect.selectedIndex = ndx;
eSelect.dispatchEvent(new Event('change',{target:eSelect}));
}
};
/* Cycle to the next link in the list, accounting for separators and
wrapping around at either end. */
const cycleLink = function(dir/*<0 = prev, >0 = next*/){
let n = eSelect.selectedIndex + dir;
if( n < 0 ) n = eSelect.options.length-1;
else if( n>=eSelect.options.length ){
n = 0;
}
const opt = eSelect.options[n];
if( opt && opt.disabled ){
/* If that OPTION element is disabled, skip over it. */
eSelect.selectedIndex = n;
cycleLink(dir);
}else{
selectEntry(n);
}
};
E('#btn-prev').addEventListener('click', ()=>cycleLink(-1), false);
E('#btn-next').addEventListener('click', ()=>cycleLink(1), false);
/**
We have to adjust the iframe's size dynamically to account for
other widgets around it. iframes don't simply like to fill up all
available space without some help. If #controlWrapper only
contained the one SELECT element, CSS would be sufficient, but
once we add text around it, #controlWrapper's size becomes
unpredictable and we need JS to calculate it. We do this every
time the window size changes.
*/
const effectiveHeight = function f(e){
// Copied from fossil.dom.js
if(!e) return 0;
if(!f.measure){
f.measure = function callee(e, depth){
if(!e) return;
const m = e.getBoundingClientRect();
if(0===depth){
callee.top = m.top;
callee.bottom = m.bottom;
}else{
callee.top = m.top ? Math.min(callee.top, m.top) : callee.top;
callee.bottom = Math.max(callee.bottom, m.bottom);
}
Array.prototype.forEach.call(e.children,(e)=>callee(e,depth+1));
if(0===depth){
//console.debug("measure() height:",e.className, callee.top, callee.bottom, (callee.bottom - callee.top));
f.extra += callee.bottom - callee.top;
}
return f.extra;
};
}
f.extra = 0;
f.measure(e,0);
return f.extra;
};
/* Helper for the window-resized event handler below, to avoid
handling the resize until after it's finished. */
const debounce = function f(func, waitMs, immediate) {
// Copied from fossil.bootstrap.js
var timeoutId;
if(!waitMs) waitMs = f.$defaultDelay;
return function() {
const context = this, args = Array.prototype.slice.call(arguments);
const later = function() {
timeoutId = undefined;
if(!immediate) func.apply(context, args);
};
const callNow = immediate && !timeoutId;
clearTimeout(timeoutId);
timeoutId = setTimeout(later, waitMs);
if(callNow) func.apply(context, args);
};
};
/**
Resize eConstrained (the ifame element) so that it fits within
the page space not occupied by the list of elements eToAvoid.
*/
const ForceResizeKludge = (function(eToAvoid, eConstrained){
const resized = function f(){
if( f.$disabled ) return;
const wh = window.innerHeight;
let ht;
let extra = 0;
eToAvoid.forEach((e)=>e ? extra += effectiveHeight(e) : false);
ht = wh - extra;
if( ht < 100 ) ht = 100;
eConstrained.style.top = 'calc('+extra+'px + 2em)';
eConstrained.style.height =
eConstrained.style.maxHeight = "calc("+ ht+ "px - 2em)";
};
resized.$disabled = true/* gets deleted later */;
window.addEventListener('resize', debounce(resized, 250), false);
return resized;
})(
EAll('body > *:not(iframe)'),
eIframe
);
delete ForceResizeKludge.$disabled;
ForceResizeKludge();
selectEntry(0);
/**
Read link-tester.json, which should live in the same directory
as this file. It's expected to be an array with entries
in one of the following forms:
- "string" = Separator label (disabled)
- ["/path"] = path with itself as a label
- ["label", "/path"] = path with the given label
All paths are expected to have a "/" prefix and this script
accounts for mapping that to the fossil part of this script's
URL.
*/
window.fetch(thisDir+'/link-tester.json').then((r)=>r.json()).then(j=>{
//console.log("fetched",j);
eSelect.innerHTML = '';
const opt = function(arg){
const o = document.createElement('option');
//console.warn(arguments);
let rc = true;
if( 'string' === typeof arg ){
/* Grouping separator */
o.innerText = "--- " + arg + " ---";
o.setAttribute('disabled','');
rc = false;
}else if( 1===arg.length ){
o.innerText = arg[0];
o.value = urlTop + arg[0];
}else if( 2==arg.length ){
o.innerText = arg[0];
o.value = urlTop + arg[1];
}
eSelect.appendChild(o);
return rc;
};
let ndx = -1/*index of first non-disabled entry*/, i = 0;
for(const e of j){
if( opt(e) && ndx<0 ){
ndx = i;
}
++i;
}
selectEntry(ndx);
});
});
|
Added test/link-tester.json.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 |
[
"Timelines",
["Default", "/timeline"],
["anonymous", "/timeline?u=anonymous&y=a"],
["after date/time", "/timeline?n=12&y=ci&a=2024-12-31T20:29Z"],
["after hash", "/timeline?n=12&y=ci&a=3cb092c0e2f0ff26"],
["before date/time", "/timeline?n=12&y=ci&b=2024-12-31T20:30Z"],
["before hash", "/timeline?n=12&y=ci&b=3cb092c0e2f0ff26"],
["circa date/time", "/timeline?n=12&y=ci&c=2024-12-31T20:29Z"],
["circa hash", "/timeline?n=12&y=ci&c=3cb092c0e2f0ff26"],
["d=,p=", "/timeline?d=version-2.25&p=version-2.26"],
["from=,ft=", "/timeline?from=2765f04694d36e68&ft=release"],
["from=,ft=,min", "/timeline?from=2765f04694d36e68&ft=release&min"],
["from=,to=", "/timeline?from=version-2.25&to=version-2.26"],
["from=,to=,min", "/timeline?from=version-2.25&to=version-2.26&min"],
["omit-cr branch", "/timeline?r=omit-cr&m&c=7e97f4999b16ab75"],
["diff-eolws branch", "/timeline?r=diff-eolws&n=50"],
["Shortest path (from=,to=)",
"/timeline?from=e663bac6f7&to=a298a0e2f9&shortest"],
["Common Ancestor (me=,you=)",
"/timeline?me=e663bac6f7&you=a298a0e2f9"],
"Diff",
["Multiple edits on a single line", "/info/030035345c#chunk73"],
["Tricky alignment, multiple edits per line",
"/fdiff?v1=6da016415dc52d61&v2=af6df3466e3c4a88"],
["Column alignment with multibyte characters",
"/fdiff?v1=d1c60722e0b9d775&v2=58d1a8991bacb113"],
["Large diff of sqlite3.c - was once very slow",
"/fdiff?v1=57b0d8183cab0e3d&v2=37b3ef49d73cdfe6"],
["A difficult indentation change", "/info/bda00cbada#chunk49"],
["Inverse of the previous",
"/fdiff?v1=bc8100c9ee01b8c2&v2=1d2acc1a2a65c2bf#chunk42"],
["Another tricky indentation",
"/fdiff?v1=955cc67ace8fb622&v2=e2e1c87b86664b45#chunk13"],
["Inverse of the previous",
"/fdiff?v2=955cc67ace8fb622&v1=e2e1c87b86664b45#chunk13"],
["A tricky alignment",
"/fdiff?v1=955cc67ace8fb622&v2=e2e1c87b86664b45#chunk24"],
["sqlite3.c changes that are difficult to align",
"/fdiff?v1=21f9a00fe2fa4a17&v2=d5c4ff0532bd89c3#chunk5"],
["Lorem Ipsum in Greek", "/fdiff?v1=4f70c682e44f&v2=55659c6e062994f"],
["Inverted Greek Lorem Ipsum", "/fdiff?v2=4f70c682e44f&v1=55659c6e062994f"],
"Infos",
["Merge riser coalescing #1", "/info/eed3946bd92a499?diff=0"],
["Merge riser coalescing #2", "/info/ef6979eac9abded?diff=0"],
["Merge riser coalescing #3", "/info/9e1fa626e47f147?diff=0"],
["Merge riser coalescing #4", "/info/68bd2e7bedb8d05?diff=0"],
["Merge riser coalescing #5", "/info/7766e689926c703?diff=0"],
["Merge riser coalescing #6", "/info/3ea66260b5555d2?diff=0"],
["Merge riser coalescing #7", "/info/66ae70a54b20656?diff=0"],
["Context graph #1", "/info/b0f2a0ac53926c9?diff=0"],
["Context graph #2", "/info/303e7af7c31866c?diff=0"],
["Context graph #3", "/info/b31afcc2cab1dc4?diff=0"],
["Context graph #4", "/info/1a164e5fb76a46b?diff=0"],
["Context graph #5", "/info/2d75e87b760c0a9?diff=0"],
["Context graph #6", "/info/76442af7e13267bd?diff=0"],
["Info about the tip", "/info/tip"],
["/info/tip"],
"Admin",
["Users", "/setup_ulist"],
"Misc.",
["/skins"],
["/chat"]
]
|
Changes to tools/makemake.tcl.
| ︙ | ︙ | |||
243 244 245 246 247 248 249 250 251 252 253 254 255 256 | -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS5 -DSQLITE_ENABLE_MATH_FUNCTIONS -DSQLITE_ENABLE_STMTVTAB -DSQLITE_HAVE_ZLIB -DSQLITE_ENABLE_DBPAGE_VTAB -DSQLITE_TRUSTED_SCHEMA=0 -DHAVE_USLEEP } #lappend SQLITE_OPTIONS -DSQLITE_ENABLE_FTS3=1 | > | 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 | -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS5 -DSQLITE_ENABLE_MATH_FUNCTIONS -DSQLITE_ENABLE_SETLK_TIMEOUT -DSQLITE_ENABLE_STMTVTAB -DSQLITE_HAVE_ZLIB -DSQLITE_ENABLE_DBPAGE_VTAB -DSQLITE_TRUSTED_SCHEMA=0 -DHAVE_USLEEP } #lappend SQLITE_OPTIONS -DSQLITE_ENABLE_FTS3=1 |
| ︙ | ︙ | |||
366 367 368 369 370 371 372 |
}
writeln [string map [list \
<<<SQLITE_OPTIONS>>> [join $SQLITE_OPTIONS " \\\n "] \
<<<SHELL_OPTIONS>>> [join $SHELL_OPTIONS " \\\n "] \
<<<PIKCHR_OPTIONS>>> [join $PIKCHR_OPTIONS " \\\n "] \
<<<NEXT_LINE>>> \\] {
| | < < < > > > > > | | 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 |
}
writeln [string map [list \
<<<SQLITE_OPTIONS>>> [join $SQLITE_OPTIONS " \\\n "] \
<<<SHELL_OPTIONS>>> [join $SHELL_OPTIONS " \\\n "] \
<<<PIKCHR_OPTIONS>>> [join $PIKCHR_OPTIONS " \\\n "] \
<<<NEXT_LINE>>> \\] {
all: $(APPNAME)
install: all
mkdir -p $(INSTALLDIR)
cp $(APPNAME) $(INSTALLDIR)
codecheck: $(TRANS_SRC) $(OBJDIR)/codecheck1
$(OBJDIR)/codecheck1 $(TRANS_SRC)
$(OBJDIR)/translate: $(SRCDIR_tools)/translate.c
-mkdir -p $(OBJDIR)
$(XBCC) -o $(OBJDIR)/translate $(SRCDIR_tools)/translate.c
$(OBJDIR)/makeheaders: $(SRCDIR_tools)/makeheaders.c
-mkdir -p $(OBJDIR)
$(XBCC) -o $(OBJDIR)/makeheaders $(SRCDIR_tools)/makeheaders.c
$(OBJDIR)/mkindex: $(SRCDIR_tools)/mkindex.c
-mkdir -p $(OBJDIR)
$(XBCC) -o $(OBJDIR)/mkindex $(SRCDIR_tools)/mkindex.c
$(OBJDIR)/mkbuiltin: $(SRCDIR_tools)/mkbuiltin.c
-mkdir -p $(OBJDIR)
$(XBCC) -o $(OBJDIR)/mkbuiltin $(SRCDIR_tools)/mkbuiltin.c
$(OBJDIR)/mkversion: $(SRCDIR_tools)/mkversion.c
-mkdir -p $(OBJDIR)
$(XBCC) -o $(OBJDIR)/mkversion $(SRCDIR_tools)/mkversion.c
$(OBJDIR)/codecheck1: $(SRCDIR_tools)/codecheck1.c
-mkdir -p $(OBJDIR)
$(XBCC) -o $(OBJDIR)/codecheck1 $(SRCDIR_tools)/codecheck1.c
# Run the test suite.
# Other flags that can be included in TESTFLAGS are:
#
# -halt Stop testing after the first failed test
# -keep Keep the temporary workspace for debugging
# -prot Write a detailed log of the tests to the file ./prot
# -verbose Include even more details in the output
# -quiet Hide most output from the terminal
# -strict Treat known bugs as failures
#
# TESTFLAGS can also include names of specific test files to limit
# the run to just those test cases.
#
test: $(APPNAME)
$(TCLSH) $(SRCDIR)/../test/tester.tcl $(APPNAME) $(TESTFLAGS)
$(OBJDIR)/VERSION.h: $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(SRCDIR)/../VERSION $(OBJDIR)/mkversion $(OBJDIR)/phony.h
$(OBJDIR)/mkversion $(SRCDIR)/../manifest.uuid <<<NEXT_LINE>>>
$(SRCDIR)/../manifest <<<NEXT_LINE>>>
$(SRCDIR)/../VERSION >$(OBJDIR)/VERSION.h
|
| ︙ | ︙ | |||
550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 |
writeln "\$(OBJDIR)/shell.o:\t\$(SQLITE3_SHELL_SRC) \$(SRCDIR_extsrc)/sqlite3.h"
writeln "\t\$(XTCC) \$(SHELL_OPTIONS) \$(SHELL_CFLAGS) \$(SEE_FLAGS) \$(LINENOISE_DEF.\$(USE_LINENOISE)) -c \$(SQLITE3_SHELL_SRC) -o \$@\n"
writeln "\$(OBJDIR)/linenoise.o:\t\$(SRCDIR_extsrc)/linenoise.c \$(SRCDIR_extsrc)/linenoise.h"
writeln "\t\$(XTCC) -c \$(SRCDIR_extsrc)/linenoise.c -o \$@\n"
writeln "\$(OBJDIR)/th.o:\t\$(SRCDIR)/th.c"
writeln "\t\$(XTCC) -c \$(SRCDIR)/th.c -o \$@\n"
writeln "\$(OBJDIR)/th_lang.o:\t\$(SRCDIR)/th_lang.c"
writeln "\t\$(XTCC) -c \$(SRCDIR)/th_lang.c -o \$@\n"
writeln "\$(OBJDIR)/th_tcl.o:\t\$(SRCDIR)/th_tcl.c"
writeln "\t\$(XTCC) -c \$(SRCDIR)/th_tcl.c -o \$@\n"
writeln [string map [list <<<NEXT_LINE>>> \\] {
| > > > | | | 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 578 579 580 581 582 |
writeln "\$(OBJDIR)/shell.o:\t\$(SQLITE3_SHELL_SRC) \$(SRCDIR_extsrc)/sqlite3.h"
writeln "\t\$(XTCC) \$(SHELL_OPTIONS) \$(SHELL_CFLAGS) \$(SEE_FLAGS) \$(LINENOISE_DEF.\$(USE_LINENOISE)) -c \$(SQLITE3_SHELL_SRC) -o \$@\n"
writeln "\$(OBJDIR)/linenoise.o:\t\$(SRCDIR_extsrc)/linenoise.c \$(SRCDIR_extsrc)/linenoise.h"
writeln "\t\$(XTCC) -c \$(SRCDIR_extsrc)/linenoise.c -o \$@\n"
writeln "\$(OBJDIR)/th.o:\t\$(SRCDIR)/th.c"
writeln "\t-mkdir -p \$(OBJDIR)\n"
writeln "\t\$(XTCC) -c \$(SRCDIR)/th.c -o \$@\n"
writeln "\$(OBJDIR)/th_lang.o:\t\$(SRCDIR)/th_lang.c"
writeln "\t-mkdir -p \$(OBJDIR)\n"
writeln "\t\$(XTCC) -c \$(SRCDIR)/th_lang.c -o \$@\n"
writeln "\$(OBJDIR)/th_tcl.o:\t\$(SRCDIR)/th_tcl.c"
writeln "\t-mkdir -p \$(OBJDIR)\n"
writeln "\t\$(XTCC) -c \$(SRCDIR)/th_tcl.c -o \$@\n"
writeln [string map [list <<<NEXT_LINE>>> \\] {
$(OBJDIR)/pikchr.o: $(SRCDIR_extsrc)/pikchr.c $(OBJDIR)/mkversion
$(XTCC) $(PIKCHR_OPTIONS) -c $(SRCDIR_extsrc)/pikchr.c -o $@
$(OBJDIR)/cson_amalgamation.o: $(SRCDIR_extsrc)/cson_amalgamation.c $(OBJDIR)/mkversion
$(XTCC) -c $(SRCDIR_extsrc)/cson_amalgamation.c -o $@
$(SRCDIR_extsrc)/pikchr.js: $(SRCDIR_extsrc)/pikchr.c $(MAKEFILE_LIST)
$(EMCC_WRAPPER) -o $@ $(EMCC_OPT) --no-entry <<<NEXT_LINE>>>
-sEXPORTED_RUNTIME_METHODS=cwrap,ccall,setValue,getValue,stackSave,stackAlloc,stackRestore <<<NEXT_LINE>>>
-sEXPORTED_FUNCTIONS=_pikchr,_pikchr_version $(SRCDIR_extsrc)/pikchr.c <<<NEXT_LINE>>>
-sENVIRONMENT=web <<<NEXT_LINE>>>
|
| ︙ | ︙ |
Changes to win/Makefile.dmc.
| ︙ | ︙ | |||
24 25 26 27 28 29 30 | SSL = CFLAGS = -o BCC = $(DMDIR)\bin\dmc $(CFLAGS) TCC = $(DMDIR)\bin\dmc $(CFLAGS) $(DMCDEF) $(SSL) $(INCL) LIBS = $(DMDIR)\extra\lib\ zlib wsock32 advapi32 dnsapi | | | | 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | SSL = CFLAGS = -o BCC = $(DMDIR)\bin\dmc $(CFLAGS) TCC = $(DMDIR)\bin\dmc $(CFLAGS) $(DMCDEF) $(SSL) $(INCL) LIBS = $(DMDIR)\extra\lib\ zlib wsock32 advapi32 dnsapi SQLITE_OPTIONS = -DNDEBUG=1 -DSQLITE_DQS=0 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS -DSQLITE_OMIT_DECLTYPE -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_PROGRESS_CALLBACK -DSQLITE_OMIT_SHARED_CACHE -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_MAX_EXPR_DEPTH=0 -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS5 -DSQLITE_ENABLE_MATH_FUNCTIONS -DSQLITE_ENABLE_SETLK_TIMEOUT -DSQLITE_ENABLE_STMTVTAB -DSQLITE_HAVE_ZLIB -DSQLITE_ENABLE_DBPAGE_VTAB -DSQLITE_TRUSTED_SCHEMA=0 -DHAVE_USLEEP SHELL_OPTIONS = -DNDEBUG=1 -DSQLITE_DQS=0 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS -DSQLITE_OMIT_DECLTYPE -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_PROGRESS_CALLBACK -DSQLITE_OMIT_SHARED_CACHE -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_MAX_EXPR_DEPTH=0 -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS5 -DSQLITE_ENABLE_MATH_FUNCTIONS -DSQLITE_ENABLE_SETLK_TIMEOUT -DSQLITE_ENABLE_STMTVTAB -DSQLITE_HAVE_ZLIB -DSQLITE_ENABLE_DBPAGE_VTAB -DSQLITE_TRUSTED_SCHEMA=0 -DHAVE_USLEEP -Dmain=sqlite3_shell -DSQLITE_SHELL_IS_UTF8=1 -DSQLITE_OMIT_LOAD_EXTENSION=1 -DUSE_SYSTEM_SQLITE=$(USE_SYSTEM_SQLITE) -DSQLITE_SHELL_DBNAME_PROC=sqlcmd_get_dbname -DSQLITE_SHELL_INIT_PROC=sqlcmd_init_proc -Daccess=file_access -Dsystem=fossil_system -Dgetenv=fossil_getenv -Dfopen=fossil_fopen PIKCHR_OPTIONS = -DPIKCHR_TOKEN_LIMIT=10000 SRC = add_.c ajax_.c alerts_.c allrepo_.c attach_.c backlink_.c backoffice_.c bag_.c bisect_.c blob_.c branch_.c browse_.c builtin_.c bundle_.c cache_.c capabilities_.c captcha_.c cgi_.c chat_.c checkin_.c checkout_.c clearsign_.c clone_.c color_.c comformat_.c configure_.c content_.c cookies_.c db_.c delta_.c deltacmd_.c deltafunc_.c descendants_.c diff_.c diffcmd_.c dispatch_.c doc_.c encode_.c etag_.c event_.c export_.c extcgi_.c file_.c fileedit_.c finfo_.c foci_.c forum_.c fshell_.c fusefs_.c fuzz_.c glob_.c graph_.c gzip_.c hname_.c hook_.c http_.c http_socket_.c http_ssl_.c http_transport_.c import_.c info_.c interwiki_.c json_.c json_artifact_.c json_branch_.c json_config_.c json_diff_.c json_dir_.c json_finfo_.c json_login_.c json_query_.c json_report_.c json_status_.c json_tag_.c json_timeline_.c json_user_.c json_wiki_.c leaf_.c loadctrl_.c login_.c lookslike_.c main_.c manifest_.c markdown_.c markdown_html_.c match_.c md5_.c merge_.c merge3_.c moderate_.c name_.c patch_.c path_.c piechart_.c pikchrshow_.c pivot_.c popen_.c pqueue_.c printf_.c publish_.c purge_.c rebuild_.c regexp_.c repolist_.c report_.c rss_.c schema_.c search_.c security_audit_.c setup_.c setupuser_.c sha1_.c sha1hard_.c sha3_.c shun_.c sitemap_.c skins_.c smtp_.c sqlcmd_.c stash_.c stat_.c statrep_.c style_.c sync_.c tag_.c tar_.c terminal_.c th_main_.c timeline_.c tkt_.c tktsetup_.c undo_.c unicode_.c unversioned_.c update_.c url_.c user_.c utf8_.c util_.c verify_.c vfile_.c wiki_.c wikiformat_.c winfile_.c winhttp_.c xfer_.c xfersetup_.c zip_.c OBJ = $(OBJDIR)\add$O $(OBJDIR)\ajax$O $(OBJDIR)\alerts$O $(OBJDIR)\allrepo$O $(OBJDIR)\attach$O $(OBJDIR)\backlink$O $(OBJDIR)\backoffice$O $(OBJDIR)\bag$O $(OBJDIR)\bisect$O $(OBJDIR)\blob$O $(OBJDIR)\branch$O $(OBJDIR)\browse$O $(OBJDIR)\builtin$O $(OBJDIR)\bundle$O $(OBJDIR)\cache$O $(OBJDIR)\capabilities$O $(OBJDIR)\captcha$O $(OBJDIR)\cgi$O $(OBJDIR)\chat$O $(OBJDIR)\checkin$O $(OBJDIR)\checkout$O $(OBJDIR)\clearsign$O $(OBJDIR)\clone$O $(OBJDIR)\color$O $(OBJDIR)\comformat$O $(OBJDIR)\configure$O $(OBJDIR)\content$O $(OBJDIR)\cookies$O $(OBJDIR)\db$O $(OBJDIR)\delta$O $(OBJDIR)\deltacmd$O $(OBJDIR)\deltafunc$O $(OBJDIR)\descendants$O $(OBJDIR)\diff$O $(OBJDIR)\diffcmd$O $(OBJDIR)\dispatch$O $(OBJDIR)\doc$O $(OBJDIR)\encode$O $(OBJDIR)\etag$O $(OBJDIR)\event$O $(OBJDIR)\export$O $(OBJDIR)\extcgi$O $(OBJDIR)\file$O $(OBJDIR)\fileedit$O $(OBJDIR)\finfo$O $(OBJDIR)\foci$O $(OBJDIR)\forum$O $(OBJDIR)\fshell$O $(OBJDIR)\fusefs$O $(OBJDIR)\fuzz$O $(OBJDIR)\glob$O $(OBJDIR)\graph$O $(OBJDIR)\gzip$O $(OBJDIR)\hname$O $(OBJDIR)\hook$O $(OBJDIR)\http$O $(OBJDIR)\http_socket$O $(OBJDIR)\http_ssl$O $(OBJDIR)\http_transport$O $(OBJDIR)\import$O $(OBJDIR)\info$O $(OBJDIR)\interwiki$O $(OBJDIR)\json$O $(OBJDIR)\json_artifact$O $(OBJDIR)\json_branch$O $(OBJDIR)\json_config$O $(OBJDIR)\json_diff$O $(OBJDIR)\json_dir$O $(OBJDIR)\json_finfo$O $(OBJDIR)\json_login$O $(OBJDIR)\json_query$O $(OBJDIR)\json_report$O $(OBJDIR)\json_status$O $(OBJDIR)\json_tag$O $(OBJDIR)\json_timeline$O $(OBJDIR)\json_user$O $(OBJDIR)\json_wiki$O $(OBJDIR)\leaf$O $(OBJDIR)\loadctrl$O $(OBJDIR)\login$O $(OBJDIR)\lookslike$O $(OBJDIR)\main$O $(OBJDIR)\manifest$O $(OBJDIR)\markdown$O $(OBJDIR)\markdown_html$O $(OBJDIR)\match$O $(OBJDIR)\md5$O $(OBJDIR)\merge$O $(OBJDIR)\merge3$O $(OBJDIR)\moderate$O $(OBJDIR)\name$O $(OBJDIR)\patch$O $(OBJDIR)\path$O $(OBJDIR)\piechart$O $(OBJDIR)\pikchrshow$O $(OBJDIR)\pivot$O $(OBJDIR)\popen$O $(OBJDIR)\pqueue$O $(OBJDIR)\printf$O $(OBJDIR)\publish$O $(OBJDIR)\purge$O $(OBJDIR)\rebuild$O $(OBJDIR)\regexp$O $(OBJDIR)\repolist$O $(OBJDIR)\report$O $(OBJDIR)\rss$O $(OBJDIR)\schema$O $(OBJDIR)\search$O $(OBJDIR)\security_audit$O $(OBJDIR)\setup$O $(OBJDIR)\setupuser$O $(OBJDIR)\sha1$O $(OBJDIR)\sha1hard$O $(OBJDIR)\sha3$O $(OBJDIR)\shun$O $(OBJDIR)\sitemap$O $(OBJDIR)\skins$O $(OBJDIR)\smtp$O $(OBJDIR)\sqlcmd$O $(OBJDIR)\stash$O $(OBJDIR)\stat$O $(OBJDIR)\statrep$O $(OBJDIR)\style$O $(OBJDIR)\sync$O $(OBJDIR)\tag$O $(OBJDIR)\tar$O $(OBJDIR)\terminal$O $(OBJDIR)\th_main$O $(OBJDIR)\timeline$O $(OBJDIR)\tkt$O $(OBJDIR)\tktsetup$O $(OBJDIR)\undo$O $(OBJDIR)\unicode$O $(OBJDIR)\unversioned$O $(OBJDIR)\update$O $(OBJDIR)\url$O $(OBJDIR)\user$O $(OBJDIR)\utf8$O $(OBJDIR)\util$O $(OBJDIR)\verify$O $(OBJDIR)\vfile$O $(OBJDIR)\wiki$O $(OBJDIR)\wikiformat$O $(OBJDIR)\winfile$O $(OBJDIR)\winhttp$O $(OBJDIR)\xfer$O $(OBJDIR)\xfersetup$O $(OBJDIR)\zip$O $(OBJDIR)\shell$O $(OBJDIR)\sqlite3$O $(OBJDIR)\th$O $(OBJDIR)\th_lang$O |
| ︙ | ︙ |
Changes to win/Makefile.mingw.
| ︙ | ︙ | |||
2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 |
-DSQLITE_ENABLE_LOCKING_STYLE=0 \
-DSQLITE_DEFAULT_FILE_FORMAT=4 \
-DSQLITE_ENABLE_DBSTAT_VTAB \
-DSQLITE_ENABLE_EXPLAIN_COMMENTS \
-DSQLITE_ENABLE_FTS4 \
-DSQLITE_ENABLE_FTS5 \
-DSQLITE_ENABLE_MATH_FUNCTIONS \
-DSQLITE_ENABLE_STMTVTAB \
-DSQLITE_HAVE_ZLIB \
-DSQLITE_ENABLE_DBPAGE_VTAB \
-DSQLITE_TRUSTED_SCHEMA=0 \
-DHAVE_USLEEP \
-DSQLITE_WIN32_NO_ANSI \
$(MINGW_OPTIONS) \
| > | 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 |
-DSQLITE_ENABLE_LOCKING_STYLE=0 \
-DSQLITE_DEFAULT_FILE_FORMAT=4 \
-DSQLITE_ENABLE_DBSTAT_VTAB \
-DSQLITE_ENABLE_EXPLAIN_COMMENTS \
-DSQLITE_ENABLE_FTS4 \
-DSQLITE_ENABLE_FTS5 \
-DSQLITE_ENABLE_MATH_FUNCTIONS \
-DSQLITE_ENABLE_SETLK_TIMEOUT \
-DSQLITE_ENABLE_STMTVTAB \
-DSQLITE_HAVE_ZLIB \
-DSQLITE_ENABLE_DBPAGE_VTAB \
-DSQLITE_TRUSTED_SCHEMA=0 \
-DHAVE_USLEEP \
-DSQLITE_WIN32_NO_ANSI \
$(MINGW_OPTIONS) \
|
| ︙ | ︙ | |||
2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 |
-DSQLITE_ENABLE_LOCKING_STYLE=0 \
-DSQLITE_DEFAULT_FILE_FORMAT=4 \
-DSQLITE_ENABLE_DBSTAT_VTAB \
-DSQLITE_ENABLE_EXPLAIN_COMMENTS \
-DSQLITE_ENABLE_FTS4 \
-DSQLITE_ENABLE_FTS5 \
-DSQLITE_ENABLE_MATH_FUNCTIONS \
-DSQLITE_ENABLE_STMTVTAB \
-DSQLITE_HAVE_ZLIB \
-DSQLITE_ENABLE_DBPAGE_VTAB \
-DSQLITE_TRUSTED_SCHEMA=0 \
-DHAVE_USLEEP \
-Dmain=sqlite3_shell \
-DSQLITE_SHELL_IS_UTF8=1 \
| > | 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 |
-DSQLITE_ENABLE_LOCKING_STYLE=0 \
-DSQLITE_DEFAULT_FILE_FORMAT=4 \
-DSQLITE_ENABLE_DBSTAT_VTAB \
-DSQLITE_ENABLE_EXPLAIN_COMMENTS \
-DSQLITE_ENABLE_FTS4 \
-DSQLITE_ENABLE_FTS5 \
-DSQLITE_ENABLE_MATH_FUNCTIONS \
-DSQLITE_ENABLE_SETLK_TIMEOUT \
-DSQLITE_ENABLE_STMTVTAB \
-DSQLITE_HAVE_ZLIB \
-DSQLITE_ENABLE_DBPAGE_VTAB \
-DSQLITE_TRUSTED_SCHEMA=0 \
-DHAVE_USLEEP \
-Dmain=sqlite3_shell \
-DSQLITE_SHELL_IS_UTF8=1 \
|
| ︙ | ︙ |
Changes to win/Makefile.msc.
| ︙ | ︙ | |||
314 315 316 317 318 319 320 321 322 323 324 325 326 327 |
/DSQLITE_ENABLE_LOCKING_STYLE=0 \
/DSQLITE_DEFAULT_FILE_FORMAT=4 \
/DSQLITE_ENABLE_DBSTAT_VTAB \
/DSQLITE_ENABLE_EXPLAIN_COMMENTS \
/DSQLITE_ENABLE_FTS4 \
/DSQLITE_ENABLE_FTS5 \
/DSQLITE_ENABLE_MATH_FUNCTIONS \
/DSQLITE_ENABLE_STMTVTAB \
/DSQLITE_HAVE_ZLIB \
/DSQLITE_ENABLE_DBPAGE_VTAB \
/DSQLITE_TRUSTED_SCHEMA=0 \
/DHAVE_USLEEP \
/DSQLITE_WIN32_NO_ANSI
| > | 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 |
/DSQLITE_ENABLE_LOCKING_STYLE=0 \
/DSQLITE_DEFAULT_FILE_FORMAT=4 \
/DSQLITE_ENABLE_DBSTAT_VTAB \
/DSQLITE_ENABLE_EXPLAIN_COMMENTS \
/DSQLITE_ENABLE_FTS4 \
/DSQLITE_ENABLE_FTS5 \
/DSQLITE_ENABLE_MATH_FUNCTIONS \
/DSQLITE_ENABLE_SETLK_TIMEOUT \
/DSQLITE_ENABLE_STMTVTAB \
/DSQLITE_HAVE_ZLIB \
/DSQLITE_ENABLE_DBPAGE_VTAB \
/DSQLITE_TRUSTED_SCHEMA=0 \
/DHAVE_USLEEP \
/DSQLITE_WIN32_NO_ANSI
|
| ︙ | ︙ | |||
340 341 342 343 344 345 346 347 348 349 350 351 352 353 |
/DSQLITE_ENABLE_LOCKING_STYLE=0 \
/DSQLITE_DEFAULT_FILE_FORMAT=4 \
/DSQLITE_ENABLE_DBSTAT_VTAB \
/DSQLITE_ENABLE_EXPLAIN_COMMENTS \
/DSQLITE_ENABLE_FTS4 \
/DSQLITE_ENABLE_FTS5 \
/DSQLITE_ENABLE_MATH_FUNCTIONS \
/DSQLITE_ENABLE_STMTVTAB \
/DSQLITE_HAVE_ZLIB \
/DSQLITE_ENABLE_DBPAGE_VTAB \
/DSQLITE_TRUSTED_SCHEMA=0 \
/DHAVE_USLEEP \
/Dmain=sqlite3_shell \
/DSQLITE_SHELL_IS_UTF8=1 \
| > | 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 |
/DSQLITE_ENABLE_LOCKING_STYLE=0 \
/DSQLITE_DEFAULT_FILE_FORMAT=4 \
/DSQLITE_ENABLE_DBSTAT_VTAB \
/DSQLITE_ENABLE_EXPLAIN_COMMENTS \
/DSQLITE_ENABLE_FTS4 \
/DSQLITE_ENABLE_FTS5 \
/DSQLITE_ENABLE_MATH_FUNCTIONS \
/DSQLITE_ENABLE_SETLK_TIMEOUT \
/DSQLITE_ENABLE_STMTVTAB \
/DSQLITE_HAVE_ZLIB \
/DSQLITE_ENABLE_DBPAGE_VTAB \
/DSQLITE_TRUSTED_SCHEMA=0 \
/DHAVE_USLEEP \
/Dmain=sqlite3_shell \
/DSQLITE_SHELL_IS_UTF8=1 \
|
| ︙ | ︙ |
Changes to www/changes.wiki.
1 2 | <title>Change Log</title> | > > > > > > > > > > > > > > > > > | | | | 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 |
<title>Change Log</title>
<h2 id='v2_27'>Changes for version 2.27 (pending)</h2><ol>
<li> Fix a SQL injection on the [/help?cmd=/file|/file page]. Thanks to
additional defenses built into Fossil, as well as good luck, this injection
is not exploitable for either data exfiltration or privilege escalation. The
only possible result of invoking the injection is a harmless SQL syntax error.
(The [https://en.wikipedia.org/wiki/Swiss_cheese_model|holes in the Swiss cheese]
did not line up!)
<li> Enhance the chng= query parameter on the [/help?cmd=/timeline|timeline page]
so that it works with other query parameters like p=, d=, from=, and to=.
<li> Always include nodes identify by sel1= and sel2= in the /timeline display.
<li> Enable the --editor option on the [/help?cmd=amend|fossil amend] command.
<li> Require at least an anonymous login to access the /blame page and similar,
to help prevent robots from soaking up excess CPU time on such pages.
<li> When walking the filesystem looking for Fossil repositories, avoid descending
into directories named "/proc".
</ol>
<h2 id='v2_26'>Changes for version 2.26 (2025-04-30)</h2><ol>
<li>Enhancements to [/help?cmd=diff|fossil diff] and similar:
<ol type="a">
<li> The argument to the --from option can be a directory name, causing
Fossil to use files under that directory as the baseline for the diff.
<li> For "gdiff", if no [/help?cmd=gdiff-command|gdiff-command setting]
is defined, Fossil tries to do a --tk diff if "tclsh" and "wish"
are available, or a --by diff if not.
<li> The "Reload" button is added to --tk diffs, to bring the displayed
diff up to date with the latest changes on disk.
<li> Add the "Hide diffs/Show diffs" toggle to web-UI diff pages that show
diffs of multiple files.
|
| ︙ | ︙ | |||
42 43 44 45 46 47 48 |
<li> If Fossil sees potential formatting mistakes (ex: bad hyperlinks)
in the check-in comment, it will alert the developer and give
him or her the opportunity to edit the comment before continuing.
This feature is controllable by the
[/help?cmd=verify-comments|verify-comments setting].
<li> The new "--if-changes" option causes the commit to become
a quiet no-op if there are no pending changes.
| | > > | 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
<li> If Fossil sees potential formatting mistakes (ex: bad hyperlinks)
in the check-in comment, it will alert the developer and give
him or her the opportunity to edit the comment before continuing.
This feature is controllable by the
[/help?cmd=verify-comments|verify-comments setting].
<li> The new "--if-changes" option causes the commit to become
a quiet no-op if there are no pending changes.
<li> Added the ability to sign check-ins with SSH keys. Artifacts signed
this way are ignored by all previous fossil versions, as if they
were plain-text file content instead of Fossil artifacts.
<li> Issue a warning if a user tries to commit on a check-in where the
branch has been changed.
<li> The interactive checkin comment prompt shows the formatting rules
set for that repository.
<li> Add the "--editor" option.
</ol>
<li>Deprecate the --comfmtflags and --comment-format global options and
|
| ︙ | ︙ | |||
82 83 84 85 86 87 88 |
"ymd=YYYYMMDD-YYYYMMDD" it shows all events in the range of
dates specified.
<li> Accept the "Z" (Zulu-time) suffix on date arguments for the
"ymd" and "yw" query parameters.
<li> The new "min" query parameter, when added to a from=,to= query,
collapses long runs of check-ins on the same branch into just
end-points.
| | | | | 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
"ymd=YYYYMMDD-YYYYMMDD" it shows all events in the range of
dates specified.
<li> Accept the "Z" (Zulu-time) suffix on date arguments for the
"ymd" and "yw" query parameters.
<li> The new "min" query parameter, when added to a from=,to= query,
collapses long runs of check-ins on the same branch into just
end-points.
<li> The p= and d= parameters can now reference different check-ins,
in which case the timeline shows those check-ins that are both
ancestors of p= and descendants of d=.
<li> The saturation and intensity of user-specified checkin and branch
background colors are automatically adjusted to keep the colors
compatible with the current skin, unless the
[/help?cmd=raw-bgcolor|raw-bgcolor setting] is turned on.
</ol>
<li>The [/help?cmd=/docfile|/docfile webpage] was added. It works like
/doc but keeps the title of markdown documents with the document rather
|
| ︙ | ︙ | |||
117 118 119 120 121 122 123 |
(using the "[/help?cmd=search|fossil search -h PATTERN]" command.)
<li> Accepts an optional SUBCOMMAND argument following the
COMMAND argument and only shows results for the specified
subcommand, not the entire command.
<li> The -u (--usage) option shows only the command-line syntax
<li> The -o (--options) option shows only the command-line options
</ol>
| | > | < | | > > > > > > > > | 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 |
(using the "[/help?cmd=search|fossil search -h PATTERN]" command.)
<li> Accepts an optional SUBCOMMAND argument following the
COMMAND argument and only shows results for the specified
subcommand, not the entire command.
<li> The -u (--usage) option shows only the command-line syntax
<li> The -o (--options) option shows only the command-line options
</ol>
<li>Enhancements to the [./tickets.wiki|ticket system]:
<ol type="a">
<li> Added the ability to attach wiki pages to a ticket for extended
descriptions.
<li> Added submenu to the 'View Ticket' page, to use it as
template for a new ticket.
<li> Added button 'Submit and New' to create multiple tickets
in a row.
<li> Link the version field in ticket view to a matching checkin or tag.
<li> Show creation time in report and ticket view.
<li> Show previous comments in edit ticket as reference.
</ol>
<li>Added the "hash" query parameter to the
[/help?cmd=/whatis|/whatis webpage].
<li>Add a "user permissions changes" [/doc/trunk/www/alerts.md|subscription]
which alerts subscribers when an admin creates a new user or
when a user's permissions change.
<li>If the FOSSIL_REPOLIST_SHOW environment variable exists and contains
the substring "description", then the project description for each repository
is shown on the repository list page. The login-group for each project is
now only shown if the FOSSIL_REPOLIST_SHOW environment variable exists and
contains the substring "login-group". ([./cgi.wiki#repolist|More information])
<li>The [/doc/trunk/www/th1.md|TH1 script language] is enhanced for improved
security:
<ol type="a">
<li> TH1 now makes a distinction between
[/doc/trunk/www/th1.md#taint|tainted and untainted string values].
This makes it more difficult to write custom TH1 scripts that
contain XSS or SQL-injection bugs. The
[/help?cmd=vuln-report|vuln-report] setting was added to control
what Fossil does when it encounters a potential TH1
security problem.
<li> The "--th" option was removed from the [/help?cmd=pikchr|fossil pikchr]
command.
<li> The "enable_htmlify" TH1 command was removed.
</ol>
<li>Make [/help?cmd=/chat|/chat] better-behaved during server outages, reducing
the frequency of reconnection attempts over time and providing feedback
to the user when the connection is down.
<li>The [/help?cmd=/sqlar|/sqlar] page does not work for users who are not logged
in, nor are links to that page displayed to users who are not logged in. Being
logged in as "anonymous" is sufficient to overcome this restriction, assuming
that "anonymous" can download tarballs and ZIP archives.
<li>Many other minor fixes and additions.
</ol>
<h2 id='v2_25'>Changes for version 2.25 (2024-11-06)</h2>
* The "[/help?cmd=ui|fossil ui /]" command now works even for repositories
that have non-ASCII filenames
|
| ︙ | ︙ | |||
1174 1175 1176 1177 1178 1179 1180 |
"Columnar" view options on timelines.
* Common display settings (such as the "view" option and the number
of rows in a timeline) are held in a cookie and thus persist
across multiple pages.
* Rework the skin editing process so that changes are implemented
on one of nine /draft pages, evaluated, then merged back to the
default.
| | < | 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 |
"Columnar" view options on timelines.
* Common display settings (such as the "view" option and the number
of rows in a timeline) are held in a cookie and thus persist
across multiple pages.
* Rework the skin editing process so that changes are implemented
on one of nine /draft pages, evaluated, then merged back to the
default.
* Added the [/timeline?skin=ardoise&once|Ardoise] skin.
* Fix the "fossil server" command on Unix to be much more responsive
to multiple simultaneous web requests.
* Use the IPv6 stack for the "fossil ui" and "fossil server"
commands on Windows.
* Support for [https://sqlite.org/sqlar|SQL Archives] as a download
option.
* Fossil now automatically generates the
|
| ︙ | ︙ |
Changes to www/containers.md.
| ︙ | ︙ | |||
668 669 670 671 672 673 674 |
localhost/fossil
$ podman start fossil
[pmmac]: https://podman.io/getting-started/installation.html#macos
[pmwin]: https://github.com/containers/podman/blob/main/docs/tutorials/podman-for-windows.md
[Podman]: https://podman.io/
[rl]: https://github.com/containers/podman/blob/main/docs/tutorials/rootless_tutorial.md
| | | 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 |
localhost/fossil
$ podman start fossil
[pmmac]: https://podman.io/getting-started/installation.html#macos
[pmwin]: https://github.com/containers/podman/blob/main/docs/tutorials/podman-for-windows.md
[Podman]: https://podman.io/
[rl]: https://github.com/containers/podman/blob/main/docs/tutorials/rootless_tutorial.md
[whatis]: https://docs.podman.io/en/latest/index.html
### 6.3 <a id="nspawn"></a>`systemd-container`
If even the Podman stack is too big for you, the next-best option I’m
aware of is the `systemd-container` infrastructure on modern Linuxes,
available since version 239 or so. Its runtime tooling requires only
|
| ︙ | ︙ |
Changes to www/customskin.md.
| ︙ | ︙ | |||
308 309 310 311 312 313 314 315 316 317 318 319 320 321 | baseline skin into a temporary working directory (here called "./newskin") and then launch the [fossil ui](/help?cmd=ui) command with the "--skin ./newskin" option. If the argument to the --skin option contains a "/" character, then the five control files are read out of the directory named. You can then edit the control files in the ./newskin folder using you favorite text editor, and press "Reload" on your browser to see the effects. ### Disabling The Web Browser Cache During Development Fossil is aggressive about asking the web browser to cache resources. While developing a new skin, it is often helpful to put your web browser into developer mode and disable the cache. If you fail to do this, then you might make some change to your skin | > | 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 | baseline skin into a temporary working directory (here called "./newskin") and then launch the [fossil ui](/help?cmd=ui) command with the "--skin ./newskin" option. If the argument to the --skin option contains a "/" character, then the five control files are read out of the directory named. You can then edit the control files in the ./newskin folder using you favorite text editor, and press "Reload" on your browser to see the effects. ### Disabling The Web Browser Cache During Development Fossil is aggressive about asking the web browser to cache resources. While developing a new skin, it is often helpful to put your web browser into developer mode and disable the cache. If you fail to do this, then you might make some change to your skin |
| ︙ | ︙ | |||
524 525 526 527 528 529 530 |
3. Edit the *.txt files in SKINDIR. After making each small change,
press Reload on the web browser to see the effect of that change.
Iterate until the desired look is achieved.
4. Copy/paste the resulting css.txt, details.txt,
header.txt, and footer.txt files
into the CSS, details, header, and footer configuration screens
| | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 525 526 527 528 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 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 |
3. Edit the *.txt files in SKINDIR. After making each small change,
press Reload on the web browser to see the effect of that change.
Iterate until the desired look is achieved.
4. Copy/paste the resulting css.txt, details.txt,
header.txt, and footer.txt files
into the CSS, details, header, and footer configuration screens
under the Admin/Skins menu. Alternately, import them using the
process described below.
An alternative to step 4 is to convert the skin files into a form
which can be imported into a repository using `fossil config import`.
It requires compiling [a small tool from the fossil source
tree](/file/tools/skintxt2config.c):
>
```
$ cc -o s2c /path/to/fossil/checkout/tools/skintxt2config.c
```
With that in place, the custom skin files can be converted with:
>
```
$ ./s2c yourskin/*.txt > skin.config
```
It can be imported into an arbitrary fossil repository with:
>
```
$ fossil config import skin.config
```
And it can be pushed to a remote repository with:
>
```
$ fossil config push skin
```
That approach has proven to be an effective way to locally develop
skin changes then push them to a "live" site.
## See Also
* [Customizing the Timeline Graph](customgraph.md)
|
Changes to www/fossil-v-git.wiki.
| ︙ | ︙ | |||
272 273 274 275 276 277 278 | It is common in Fossil to ask to see [/timeline?df=release&y=ci|all check-ins since the last release]. Git lets you see "what came before". Fossil makes it just as easy to also see "what came after". Leaf check-ins in Git that lack a "ref" become "detached," making them difficult to locate and subject to garbage collection. This | | | 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 | It is common in Fossil to ask to see [/timeline?df=release&y=ci|all check-ins since the last release]. Git lets you see "what came before". Fossil makes it just as easy to also see "what came after". Leaf check-ins in Git that lack a "ref" become "detached," making them difficult to locate and subject to garbage collection. This [https://stackoverflow.com/q/3965676 | detached head state] problem has caused grief for [https://www.google.com/search?q=git+detached+head+state | many Git users]. With Fossil, detached heads are simply impossible because we can always find our way back into the Merkle tree using one or more of the relations in the SQL database. |
| ︙ | ︙ | |||
340 341 342 343 344 345 346 | Fossil's user-visible functionality. Fossil isn't entirely C and SQL code. Its web UI [./javascript.md | uses JavaScript where necessary]. The server-side UI scripting uses a custom minimal [https://en.wikipedia.org/wiki/Tcl|Tcl] dialect called | | | 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 | Fossil's user-visible functionality. Fossil isn't entirely C and SQL code. Its web UI [./javascript.md | uses JavaScript where necessary]. The server-side UI scripting uses a custom minimal [https://en.wikipedia.org/wiki/Tcl|Tcl] dialect called [./th1.md|TH1], which is embedded into Fossil itself. Fossil's build system and test suite are largely based on Tcl.⁵ All of this is quite portable. About half of Git's code is POSIX C, and about a third is POSIX shell code. This is largely why the so-called "Git for Windows" distributions (both [https://git-scm.com/download/win|first-party] and [https://gitforwindows.org/|third-party]) are actually an |
| ︙ | ︙ |
Changes to www/gsoc-ideas.md.
| ︙ | ︙ | |||
22 23 24 25 26 27 28 | features to work on in the UI. # UI, Look and Feel Tasks for those interested in graphic/web design: * Add a quote button to the Forum, such as [discussed in this thread](https://fossil-scm.org/forum/forumpost/7ad03cd73d) | | | 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | features to work on in the UI. # UI, Look and Feel Tasks for those interested in graphic/web design: * Add a quote button to the Forum, such as [discussed in this thread](https://fossil-scm.org/forum/forumpost/7ad03cd73d) * Improve the documentation history-browsing page to enable selection of 2 arbitrary versions to diff, similar to the [Mediawiki history feature enabled on Wikipedia](https://en.wikipedia.org/w/index.php?title=Fossil_\(software\)&action=history) * Allow diffing of Forum posts * General touch-ups in the existing skins. This may, depending on how deep one cares to dig, require digging into C code to find, and potentially modify, how the HTML is generated. * Creation of one or more new skins. This does not specifically require any C know-how. * Complete per-feature CSS facilities in [the Inskinerator](https://tangentsoft.com/inskinerator/dir) and add features to the Inskinerator |
| ︙ | ︙ |
Changes to www/index.wiki.
| ︙ | ︙ | |||
82 83 84 85 86 87 88 |
atomic even if interrupted by a power loss or system crash.
Automatic [./selfcheck.wiki | self-checks] verify that all aspects of
the repository are consistent prior to each commit.
8. <b>Free and Open-Source</b> — [../COPYRIGHT-BSD2.txt|2-clause BSD license].
<hr>
| | | | | | 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 |
atomic even if interrupted by a power loss or system crash.
Automatic [./selfcheck.wiki | self-checks] verify that all aspects of
the repository are consistent prior to each commit.
8. <b>Free and Open-Source</b> — [../COPYRIGHT-BSD2.txt|2-clause BSD license].
<hr>
<h3>Latest Release: 2.26 ([/timeline?c=version-2.26|2025-04-30])</h3>
* [/uv/download.html|Download]
* [./changes.wiki#v2_26|Change Summary]
* [/timeline?p=version-2.26&d=version-2.25&y=ci|Check-ins in version 2.26]
* [/timeline?df=version-2.26&y=ci|Check-ins derived from the 2.26 release]
* [/timeline?t=release|Timeline of all past releases]
<hr>
<h3>Quick Start</h3>
1. [/uv/download.html|Download] or install using a package manager or
[./build.wiki|compile from sources].
|
| ︙ | ︙ |
Changes to www/quickstart.wiki.
| ︙ | ︙ | |||
194 195 196 197 198 199 200 | Note that Fossil allows you to make multiple check-outs in separate directories from the same repository. This enables you, for example, to do builds from multiple branches or versions at the same time without having to generate extra clones. To switch a checkout between different versions and branches, | | | 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 | Note that Fossil allows you to make multiple check-outs in separate directories from the same repository. This enables you, for example, to do builds from multiple branches or versions at the same time without having to generate extra clones. To switch a checkout between different versions and branches, use: <pre> <b>[/help/update | fossil update]</b> <b>[/help/checkout | fossil checkout]</b> </pre> [/help/update | update] honors the "autosync" option and |
| ︙ | ︙ |
Changes to www/reviews.wiki.
| ︙ | ︙ | |||
33 34 35 36 37 38 39 | another branch after the fact and shared-by-default branches are good features. Also not having a misanthropic command line interface. </div> <b>Stephan Beal writes on 2009-01-11:</b> <div class="indent"> | | | | | | | < < | | | | | | | < | > | | 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 | another branch after the fact and shared-by-default branches are good features. Also not having a misanthropic command line interface. </div> <b>Stephan Beal writes on 2009-01-11:</b> <div class="indent"> Sometime in late 2007 I came across a link to fossil on <a href="https://sqlite.org/">sqlite.org</a>. It was a good thing I bookmarked it, because I was never able to find the link again (it might have been in a bug report or something). The reasons I first took a close look at it were (A) it stemmed from the sqlite project, which I've held in high regards for years (e.g. I wrote bindings for it for Mozilla's SpiderMonkey JavaScript engine), and (B) it could run as a CGI. That second point might seem a bit archaic, but in practice CGI is the only way most hosted sites can set up a shared source repository with multiple user IDs. (i'm not about to give out my only account password or SSH key for my hosted sites, no matter how much I trust the other developers, and none of my hosters allow me to run standalone servers or add Apache modules.) So I tried it out. The thing which bugged me most about it was having to type "commit" or "com" instead of "ci" for checking in (as is custom in all other systems I've used), despite the fact that fossil uses "ci" as a filter in things like the timeline view. Looking back now, I have used fossil for about about 95% of my work in the past year, in over 15 source trees, and I now get tripped up when I have to use svn or cvs. So, having got over typing "fossil com -m ...", here's why I love it so much... Point #1: CGI Again, this sounds archaic, but fossil has allowed me to share source trees which I cannot justifiably host in other projects I work on (they don't belong to those projects), which I cannot host in google code (because google code doesn't allow/recognize Public Domain as a license, and I refuse to relicense just to accommodate them), and for which SourceForge is overkill (and way too slow). With fossil I can create a new repo, have it installed on my hoster (https://fossil.wanderinghorse.net), and be commiting code to it within 5 minutes. Point #2: Wiki I hate wikis. I really do. Always have. They all have a different syntax and the content tends to get really disorganized really quickly. Their nature makes it difficult to reorganize them without |
| ︙ | ︙ |
Changes to www/signing.md.
| ︙ | ︙ | |||
49 50 51 52 53 54 55 56 57 58 59 | for Windows, changing as appropriate `-f` to the path of the private key to be used. The value for `-n` (the _namespace_) can be changed at will, but care has to be taken to use the same value when verifying the signature. ## Verifying a signature Fossil does not provide an internal method for verifying signatures and | > > > > | | 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | for Windows, changing as appropriate `-f` to the path of the private key to be used. The value for `-n` (the _namespace_) can be changed at will, but care has to be taken to use the same value when verifying the signature. Fossil versions prior to 2.26 do not understand SSH signatures and will treat artifacts signed this way as opaque blobs, not Fossil artifacts. ## Verifying a signature Fossil does not provide an internal method for verifying signatures and relies – like it does for signing – on external tools. ### GnuPG Assuming you used the default GPG command for signing, one can verify the signature using ``` |
| ︙ | ︙ |
Changes to www/sync.wiki.
| ︙ | ︙ | |||
56 57 58 59 60 61 62 | The server is listening for incoming HTTP requests. The client issues one or more HTTP requests and receives replies for each request. The server might be running as an independent server using the [/help?cmd=server|"fossil server" command], or it might be launched from inetd or xinetd using the | | | | 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | The server is listening for incoming HTTP requests. The client issues one or more HTTP requests and receives replies for each request. The server might be running as an independent server using the [/help?cmd=server|"fossil server" command], or it might be launched from inetd or xinetd using the [/help?cmd=http|"fossil http" command]. Or the server might be [./server/any/cgi.md|launched from CGI] or from [./server/any/scgi.md|SCGI]. (See "[./server/|How To Configure A Fossil Server]" for details.) The specifics of how the server listens for incoming HTTP requests is immaterial to this protocol. The important point is that the server is listening for requests and the client is the issuer of the requests. A single [/help?cmd=push|push], [/help?cmd=pull|pull], or [/help?cmd=sync|sync] might involve multiple HTTP requests. The client maintains state between all requests. But on the server side, each request is independent. The server does not preserve any information about the client from one request to the next. Note: Throughout this article, we use the terms "server" and "client" |
| ︙ | ︙ | |||
148 149 150 151 152 153 154 | typing in the common case where the client does multiple syncs to the same server.) The client modifies the URL by appending the method name "<b>/xfer</b>" to the end. For example, if the URL specified on the client command line is | | | | | 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 | typing in the common case where the client does multiple syncs to the same server.) The client modifies the URL by appending the method name "<b>/xfer</b>" to the end. For example, if the URL specified on the client command line is <pre>https://fossil-scm.org/home</pre> Then the URL that is really used to do the synchronization will be: <pre>https://fossil-scm.org/home/xfer</pre> <h3 id="req-format">2.2 HTTP Request Format</h3> The client always sends a POST request to the server. The general format of the POST request is as follows: <pre> POST /home/xfer HTTP/1.0 Host: fossil-scm.hwaci.com:80 Content-Type: application/x-fossil Content-Length: 4216 </pre> <i><pre>content...</pre></i> |
| ︙ | ︙ | |||
248 249 250 251 252 253 254 | The "cfile" name is an abbreviation for "compressed file". The "uvfile" name is an abbreviation for "unversioned file". <h4 id="ordinary-fc">3.3.1 Ordinary File Cards</h4> For sync protocols, artifacts are transferred using "file" cards. File cards come in two different formats depending | | | 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 | The "cfile" name is an abbreviation for "compressed file". The "uvfile" name is an abbreviation for "unversioned file". <h4 id="ordinary-fc">3.3.1 Ordinary File Cards</h4> For sync protocols, artifacts are transferred using "file" cards. File cards come in two different formats depending on whether the artifact is sent directly or as a [./delta_format.wiki|delta] from some other artifact. <pre> <b>file</b> <i>artifact-id size</i> <b>\n</b> <i>content</i> <b>file</b> <i>artifact-id delta-artifact-id size</i> <b>\n</b> <i>content</i> </pre> |
| ︙ | ︙ | |||
271 272 273 274 275 276 277 | The first argument of a file card is the ID of the artifact that is being transferred. The artifact ID is the lower-case hexadecimal representation of the name hash for the artifact. The last argument of the file card is the number of bytes of payload that immediately follow the file card. If the file card has only two arguments, that means the payload is the complete content of the artifact. If the file card has three | | | | > > > > | 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 | The first argument of a file card is the ID of the artifact that is being transferred. The artifact ID is the lower-case hexadecimal representation of the name hash for the artifact. The last argument of the file card is the number of bytes of payload that immediately follow the file card. If the file card has only two arguments, that means the payload is the complete content of the artifact. If the file card has three arguments, then the payload is a [./delta_format.wiki|delta] and the second argument is the ID of another artifact that is the source of the delta. File cards are sent in both directions: client to server and server to client. A delta might be sent before the source of the delta, so both client and server should remember deltas and be able to apply them when their source arrives. <h4 id="compressed-fc">3.3.2 Compressed File Cards</h4> A client that sends a clone protocol version "3" or greater will receive artifacts as "cfile" cards while cloning. This card was introduced to improve the speed of the transfer of content by sending the compressed artifact directly from the server database to the client. In this case, the containing response body is <em>not</em> compressed separately because the vast majority of the response is already compressed in cfile cards. In practice, version "3" is significantly faster than version "2". Compressed File cards are similar to File cards, sharing the same in-line "payload" data characteristics and also the same treatment of direct content or delta content. Cfile cards come in two different formats depending on whether the artifact is sent directly or as a delta from some other artifact. |
| ︙ | ︙ | |||
409 410 411 412 413 414 415 | operations. Instead of sending "file" cards, the server will send "cfile" cards <h4>3.5.2 Protocol 2</h4> The sequence-number sent is the number of artifacts received so far. For the first clone message, the | | | 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 | operations. Instead of sending "file" cards, the server will send "cfile" cards <h4>3.5.2 Protocol 2</h4> The sequence-number sent is the number of artifacts received so far. For the first clone message, the sequence number is 1. The server will respond by sending file cards for some number of artifacts up to the maximum message size. The server will also send a single "clone_seqno" card to the client so that the client can know where the server left off. <pre> <b>clone_seqno</b> <i>sequence-number</i> |
| ︙ | ︙ | |||
1036 1037 1038 1039 1040 1041 1042 |
card per line.
<li>Card formats are:
<ul>
<li> <b>login</b> <i>userid nonce signature</i>
<li> <b>push</b> <i>servercode projectcode</i>
<li> <b>pull</b> <i>servercode projectcode</i>
<li> <b>clone</b>
| | | 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 |
card per line.
<li>Card formats are:
<ul>
<li> <b>login</b> <i>userid nonce signature</i>
<li> <b>push</b> <i>servercode projectcode</i>
<li> <b>pull</b> <i>servercode projectcode</i>
<li> <b>clone</b>
<li> <b>clone</b> <i>protocol-version sequence-number</i>
<li> <b>file</b> <i>artifact-id size</i> <b>\n</b> <i>content</i>
<li> <b>file</b> <i>artifact-id delta-artifact-id size</i> <b>\n</b> <i>content</i>
<li> <b>cfile</b> <i>artifact-id size</i> <b>\n</b> <i>content</i>
<li> <b>cfile</b> <i>artifact-id delta-artifact-id size</i> <b>\n</b> <i>content</i>
<li> <b>uvfile</b> <i>name mtime hash size flags</i> <b>\n</b> <i>content</i>
<li> <b>private</b>
<li> <b>igot</b> <i>artifact-id</i> ?<i>flag</i>?
|
| ︙ | ︙ |
Changes to www/th1.md.
| ︙ | ︙ | |||
10 11 12 13 14 15 16 | TH1 began as a minimalist re-implementation of the Tcl scripting language. There was a need to test the SQLite library on Symbian phones, but at that time all of the test cases for SQLite were written in Tcl and Tcl could not be easily compiled on the SymbianOS. So TH1 was developed as a cut-down version of Tcl that would facilitate running the SQLite test scripts on SymbianOS. | | < | > > > > > > > > > > > > > > > | | | | 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 |
TH1 began as a minimalist re-implementation of the Tcl scripting language.
There was a need to test the SQLite library on Symbian phones, but at that
time all of the test cases for SQLite were written in Tcl and Tcl could not
be easily compiled on the SymbianOS. So TH1 was developed as a cut-down
version of Tcl that would facilitate running the SQLite test scripts on
SymbianOS.
Fossil was first being designed at about the same time.
Early prototypes of Fossil were written in pure Tcl. But as the development
shifted toward the use of C-code, the need arose to have a Tcl-like
scripting language to help with code generation. TH1 was small and
light-weight and used minimal resources and seemed ideally suited for the
task.
The name "TH1" stands for "Test Harness 1",
since its original purpose was to serve as testing harness
for SQLite.
Where TH1 Is Used In Fossil
---------------------------
* In the header and footer for [skins](./customskin.md)
text within `<th1>...</th1>` is run as a TH1 script.
([example](/builtin/skins/default/header.txt))
* This display of [tickets](./bugtheory.wiki) is controlled by TH1
scripts, so that the ticket format can be customized for each
project. Administrators can visit the <b>/tktsetup</b> page in
their repositories to view and customize these scripts.
([example usage](./custom_ticket.wiki))
Overview Of The Tcl/TH1 Language
--------------------------------
TH1 is a string-processing language. All values are strings. Any numerical
operations are accomplished by converting from string to numeric, performing
the computation, then converting the result back into a string. (This might
seem inefficient, but it is faster than people imagine, and numeric
computations do not come up very often for the kinds of work that TH1 does,
so it has never been an issue.)
A TH1 script consists of a sequence of commands.
Each command is terminated by the first *unescaped* newline or ";" character.
The text of the command (excluding the newline or semicolon terminator)
is broken into space-separated tokens. The first token is the command
name and subsequent tokens are the arguments. In this sense, TH1 syntax
is similar to the familiar command-line shell syntax.
|
| ︙ | ︙ | |||
124 125 126 127 128 129 130 | attacks. This feature helps to ensure that XSS and SQL-injection vulnerabilities are not *accidentally* added to Fossil when custom TH1 scripts for headers or footers or tickets are added to a repository. Note that the tainted/untainted distinction in strings does not make it impossible to introduce XSS and SQL-injections vulnerabilities using poorly-written TH1 scripts; it just makes it more difficult and less likely to happen by accident. Developers must still consider the | | | 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 | attacks. This feature helps to ensure that XSS and SQL-injection vulnerabilities are not *accidentally* added to Fossil when custom TH1 scripts for headers or footers or tickets are added to a repository. Note that the tainted/untainted distinction in strings does not make it impossible to introduce XSS and SQL-injections vulnerabilities using poorly-written TH1 scripts; it just makes it more difficult and less likely to happen by accident. Developers must still consider the security implications of TH1 customizations they add to Fossil, and take appropriate precautions when writing custom TH1. Peer review of TH1 script changes is encouraged. In Fossil version 2.26, if the vuln-report setting is set to "block" or "fatal", the [html](#html) and [query](#query) TH1 commands will fail with an error if their argument is a tainted string. This helps to prevent XSS and SQL-injection attacks, respectively. Note that |
| ︙ | ︙ |