Fossil SCM
Merge trunk
Commit
b7cbf3772a42936956c59e351c5d487dfb15e2c676dced00c0a5dfa9e8918f9a
Parent
37a48b6b92fcdfa…
11 files changed
+268
-335
+265
-104
+265
-104
+16
-16
+4
+4
-1
+4
-1
+82
+224
+68
+1
-1
+268
-335
| --- extsrc/shell.c | ||
| +++ extsrc/shell.c | ||
| @@ -1713,339 +1713,176 @@ | ||
| 1713 | 1713 | ** work here in the middle of this regular program. |
| 1714 | 1714 | */ |
| 1715 | 1715 | #define SQLITE_EXTENSION_INIT1 |
| 1716 | 1716 | #define SQLITE_EXTENSION_INIT2(X) (void)(X) |
| 1717 | 1717 | |
| 1718 | -#if defined(_WIN32) && defined(_MSC_VER) | |
| 1719 | -/************************* Begin test_windirent.h ******************/ | |
| 1718 | +/************************* Begin ../ext/misc/windirent.h ******************/ | |
| 1720 | 1719 | /* |
| 1721 | -** 2015 November 30 | |
| 1720 | +** 2025-06-05 | |
| 1722 | 1721 | ** |
| 1723 | 1722 | ** The author disclaims copyright to this source code. In place of |
| 1724 | 1723 | ** a legal notice, here is a blessing: |
| 1725 | 1724 | ** |
| 1726 | 1725 | ** May you do good and not evil. |
| 1727 | 1726 | ** May you find forgiveness for yourself and forgive others. |
| 1728 | 1727 | ** May you share freely, never taking more than you give. |
| 1729 | 1728 | ** |
| 1730 | 1729 | ************************************************************************* |
| 1731 | -** This file contains declarations for most of the opendir() family of | |
| 1732 | -** POSIX functions on Win32 using the MSVCRT. | |
| 1730 | +** | |
| 1731 | +** An implementation of opendir(), readdir(), and closedir() for Windows, | |
| 1732 | +** based on the FindFirstFile(), FindNextFile(), and FindClose() APIs | |
| 1733 | +** of Win32. | |
| 1734 | +** | |
| 1735 | +** #include this file inside any C-code module that needs to use | |
| 1736 | +** opendir()/readdir()/closedir(). This file is a no-op on non-Windows | |
| 1737 | +** machines. On Windows, static functions are defined that implement | |
| 1738 | +** those standard interfaces. | |
| 1733 | 1739 | */ |
| 1734 | - | |
| 1735 | 1740 | #if defined(_WIN32) && defined(_MSC_VER) && !defined(SQLITE_WINDIRENT_H) |
| 1736 | 1741 | #define SQLITE_WINDIRENT_H |
| 1737 | 1742 | |
| 1738 | -/* | |
| 1739 | -** We need several data types from the Windows SDK header. | |
| 1740 | -*/ | |
| 1741 | - | |
| 1742 | 1743 | #ifndef WIN32_LEAN_AND_MEAN |
| 1743 | 1744 | #define WIN32_LEAN_AND_MEAN |
| 1744 | 1745 | #endif |
| 1745 | - | |
| 1746 | -#include "windows.h" | |
| 1747 | - | |
| 1748 | -/* | |
| 1749 | -** We need several support functions from the SQLite core. | |
| 1750 | -*/ | |
| 1751 | - | |
| 1752 | -/* #include "sqlite3.h" */ | |
| 1753 | - | |
| 1754 | -/* | |
| 1755 | -** We need several things from the ANSI and MSVCRT headers. | |
| 1756 | -*/ | |
| 1757 | - | |
| 1746 | +#include <windows.h> | |
| 1747 | +#include <io.h> | |
| 1758 | 1748 | #include <stdio.h> |
| 1759 | 1749 | #include <stdlib.h> |
| 1760 | 1750 | #include <errno.h> |
| 1761 | -#include <io.h> | |
| 1762 | 1751 | #include <limits.h> |
| 1763 | 1752 | #include <sys/types.h> |
| 1764 | 1753 | #include <sys/stat.h> |
| 1765 | - | |
| 1766 | -/* | |
| 1767 | -** We may need several defines that should have been in "sys/stat.h". | |
| 1768 | -*/ | |
| 1769 | - | |
| 1754 | +#include <string.h> | |
| 1755 | +#ifndef FILENAME_MAX | |
| 1756 | +# define FILENAME_MAX (260) | |
| 1757 | +#endif | |
| 1770 | 1758 | #ifndef S_ISREG |
| 1771 | -#define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG) | |
| 1759 | +#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) | |
| 1772 | 1760 | #endif |
| 1773 | - | |
| 1774 | 1761 | #ifndef S_ISDIR |
| 1775 | -#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR) | |
| 1762 | +#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) | |
| 1776 | 1763 | #endif |
| 1777 | - | |
| 1778 | 1764 | #ifndef S_ISLNK |
| 1779 | -#define S_ISLNK(mode) (0) | |
| 1780 | -#endif | |
| 1781 | - | |
| 1782 | -/* | |
| 1783 | -** We may need to provide the "mode_t" type. | |
| 1784 | -*/ | |
| 1785 | - | |
| 1786 | -#ifndef MODE_T_DEFINED | |
| 1787 | - #define MODE_T_DEFINED | |
| 1788 | - typedef unsigned short mode_t; | |
| 1789 | -#endif | |
| 1790 | - | |
| 1791 | -/* | |
| 1792 | -** We may need to provide the "ino_t" type. | |
| 1793 | -*/ | |
| 1794 | - | |
| 1795 | -#ifndef INO_T_DEFINED | |
| 1796 | - #define INO_T_DEFINED | |
| 1797 | - typedef unsigned short ino_t; | |
| 1798 | -#endif | |
| 1799 | - | |
| 1800 | -/* | |
| 1801 | -** We need to define "NAME_MAX" if it was not present in "limits.h". | |
| 1802 | -*/ | |
| 1803 | - | |
| 1804 | -#ifndef NAME_MAX | |
| 1805 | -# ifdef FILENAME_MAX | |
| 1806 | -# define NAME_MAX (FILENAME_MAX) | |
| 1807 | -# else | |
| 1808 | -# define NAME_MAX (260) | |
| 1809 | -# endif | |
| 1810 | -# define DIRENT_NAME_MAX (NAME_MAX) | |
| 1811 | -#endif | |
| 1812 | - | |
| 1813 | -/* | |
| 1814 | -** We need to define "NULL_INTPTR_T" and "BAD_INTPTR_T". | |
| 1815 | -*/ | |
| 1816 | - | |
| 1817 | -#ifndef NULL_INTPTR_T | |
| 1818 | -# define NULL_INTPTR_T ((intptr_t)(0)) | |
| 1819 | -#endif | |
| 1820 | - | |
| 1821 | -#ifndef BAD_INTPTR_T | |
| 1822 | -# define BAD_INTPTR_T ((intptr_t)(-1)) | |
| 1823 | -#endif | |
| 1824 | - | |
| 1825 | -/* | |
| 1826 | -** We need to provide the necessary structures and related types. | |
| 1827 | -*/ | |
| 1828 | - | |
| 1829 | -#ifndef DIRENT_DEFINED | |
| 1830 | -#define DIRENT_DEFINED | |
| 1831 | -typedef struct DIRENT DIRENT; | |
| 1832 | -typedef DIRENT *LPDIRENT; | |
| 1833 | -struct DIRENT { | |
| 1834 | - ino_t d_ino; /* Sequence number, do not use. */ | |
| 1835 | - unsigned d_attributes; /* Win32 file attributes. */ | |
| 1836 | - char d_name[NAME_MAX + 1]; /* Name within the directory. */ | |
| 1837 | -}; | |
| 1838 | -#endif | |
| 1839 | - | |
| 1840 | -#ifndef DIR_DEFINED | |
| 1841 | -#define DIR_DEFINED | |
| 1842 | -typedef struct DIR DIR; | |
| 1843 | -typedef DIR *LPDIR; | |
| 1765 | +#define S_ISLNK(m) (0) | |
| 1766 | +#endif | |
| 1767 | +typedef unsigned short mode_t; | |
| 1768 | + | |
| 1769 | +/* The dirent object for Windows is abbreviated. The only field really | |
| 1770 | +** usable by applications is d_name[]. | |
| 1771 | +*/ | |
| 1772 | +struct dirent { | |
| 1773 | + int d_ino; /* Inode number (synthesized) */ | |
| 1774 | + unsigned d_attributes; /* File attributes */ | |
| 1775 | + char d_name[FILENAME_MAX]; /* Null-terminated filename */ | |
| 1776 | +}; | |
| 1777 | + | |
| 1778 | +/* The internals of DIR are opaque according to standards. So it | |
| 1779 | +** does not matter what we put here. */ | |
| 1780 | +typedef struct DIR DIR; | |
| 1844 | 1781 | struct DIR { |
| 1845 | - intptr_t d_handle; /* Value returned by "_findfirst". */ | |
| 1846 | - DIRENT d_first; /* DIRENT constructed based on "_findfirst". */ | |
| 1847 | - DIRENT d_next; /* DIRENT constructed based on "_findnext". */ | |
| 1848 | -}; | |
| 1849 | -#endif | |
| 1850 | - | |
| 1851 | -/* | |
| 1852 | -** Provide a macro, for use by the implementation, to determine if a | |
| 1853 | -** particular directory entry should be skipped over when searching for | |
| 1854 | -** the next directory entry that should be returned by the readdir(). | |
| 1855 | -*/ | |
| 1856 | - | |
| 1857 | -#ifndef is_filtered | |
| 1858 | -# define is_filtered(a) ((((a).attrib)&_A_HIDDEN) || (((a).attrib)&_A_SYSTEM)) | |
| 1859 | -#endif | |
| 1860 | - | |
| 1861 | -/* | |
| 1862 | -** Provide the function prototype for the POSIX compatible getenv() | |
| 1863 | -** function. This function is not thread-safe. | |
| 1864 | -*/ | |
| 1865 | - | |
| 1866 | -extern const char *windirent_getenv(const char *name); | |
| 1867 | - | |
| 1868 | -/* | |
| 1869 | -** Finally, we can provide the function prototypes for the opendir(), | |
| 1870 | -** readdir(), and closedir() POSIX functions. | |
| 1871 | -*/ | |
| 1872 | - | |
| 1873 | -extern LPDIR opendir(const char *dirname); | |
| 1874 | -extern LPDIRENT readdir(LPDIR dirp); | |
| 1875 | -extern INT closedir(LPDIR dirp); | |
| 1876 | - | |
| 1877 | -#endif /* defined(WIN32) && defined(_MSC_VER) */ | |
| 1878 | - | |
| 1879 | -/************************* End test_windirent.h ********************/ | |
| 1880 | -/************************* Begin test_windirent.c ******************/ | |
| 1881 | -/* | |
| 1882 | -** 2015 November 30 | |
| 1883 | -** | |
| 1884 | -** The author disclaims copyright to this source code. In place of | |
| 1885 | -** a legal notice, here is a blessing: | |
| 1886 | -** | |
| 1887 | -** May you do good and not evil. | |
| 1888 | -** May you find forgiveness for yourself and forgive others. | |
| 1889 | -** May you share freely, never taking more than you give. | |
| 1890 | -** | |
| 1891 | -************************************************************************* | |
| 1892 | -** This file contains code to implement most of the opendir() family of | |
| 1893 | -** POSIX functions on Win32 using the MSVCRT. | |
| 1894 | -*/ | |
| 1895 | - | |
| 1896 | -#if defined(_WIN32) && defined(_MSC_VER) | |
| 1897 | -/* #include "test_windirent.h" */ | |
| 1898 | - | |
| 1899 | -/* | |
| 1900 | -** Implementation of the POSIX getenv() function using the Win32 API. | |
| 1901 | -** This function is not thread-safe. | |
| 1902 | -*/ | |
| 1903 | -const char *windirent_getenv( | |
| 1904 | - const char *name | |
| 1905 | -){ | |
| 1906 | - static char value[32768]; /* Maximum length, per MSDN */ | |
| 1907 | - DWORD dwSize = sizeof(value) / sizeof(char); /* Size in chars */ | |
| 1908 | - DWORD dwRet; /* Value returned by GetEnvironmentVariableA() */ | |
| 1909 | - | |
| 1910 | - memset(value, 0, sizeof(value)); | |
| 1911 | - dwRet = GetEnvironmentVariableA(name, value, dwSize); | |
| 1912 | - if( dwRet==0 || dwRet>dwSize ){ | |
| 1913 | - /* | |
| 1914 | - ** The function call to GetEnvironmentVariableA() failed -OR- | |
| 1915 | - ** the buffer is not large enough. Either way, return NULL. | |
| 1916 | - */ | |
| 1917 | - return 0; | |
| 1918 | - }else{ | |
| 1919 | - /* | |
| 1920 | - ** The function call to GetEnvironmentVariableA() succeeded | |
| 1921 | - ** -AND- the buffer contains the entire value. | |
| 1922 | - */ | |
| 1923 | - return value; | |
| 1924 | - } | |
| 1925 | -} | |
| 1926 | - | |
| 1927 | -/* | |
| 1928 | -** Implementation of the POSIX opendir() function using the MSVCRT. | |
| 1929 | -*/ | |
| 1930 | -LPDIR opendir( | |
| 1931 | - const char *dirname /* Directory name, UTF8 encoding */ | |
| 1932 | -){ | |
| 1933 | - struct _wfinddata_t data; | |
| 1934 | - LPDIR dirp = (LPDIR)sqlite3_malloc(sizeof(DIR)); | |
| 1935 | - SIZE_T namesize = sizeof(data.name) / sizeof(data.name[0]); | |
| 1782 | + intptr_t d_handle; /* Handle for findfirst()/findnext() */ | |
| 1783 | + struct dirent cur; /* Current entry */ | |
| 1784 | +}; | |
| 1785 | + | |
| 1786 | +/* Ignore hidden and system files */ | |
| 1787 | +#define WindowsFileToIgnore(a) \ | |
| 1788 | + ((((a).attrib)&_A_HIDDEN) || (((a).attrib)&_A_SYSTEM)) | |
| 1789 | + | |
| 1790 | +/* | |
| 1791 | +** Close a previously opened directory | |
| 1792 | +*/ | |
| 1793 | +static int closedir(DIR *pDir){ | |
| 1794 | + int rc = 0; | |
| 1795 | + if( pDir==0 ){ | |
| 1796 | + return EINVAL; | |
| 1797 | + } | |
| 1798 | + if( pDir->d_handle!=0 && pDir->d_handle!=(-1) ){ | |
| 1799 | + rc = _findclose(pDir->d_handle); | |
| 1800 | + } | |
| 1801 | + sqlite3_free(pDir); | |
| 1802 | + return rc; | |
| 1803 | +} | |
| 1804 | + | |
| 1805 | +/* | |
| 1806 | +** Open a new directory. The directory name should be UTF-8 encoded. | |
| 1807 | +** appropriate translations happen automatically. | |
| 1808 | +*/ | |
| 1809 | +static DIR *opendir(const char *zDirName){ | |
| 1810 | + DIR *pDir; | |
| 1936 | 1811 | wchar_t *b1; |
| 1937 | 1812 | sqlite3_int64 sz; |
| 1938 | - | |
| 1939 | - if( dirp==NULL ) return NULL; | |
| 1940 | - memset(dirp, 0, sizeof(DIR)); | |
| 1941 | - | |
| 1942 | - /* TODO: Remove this if Unix-style root paths are not used. */ | |
| 1943 | - if( sqlite3_stricmp(dirname, "/")==0 ){ | |
| 1944 | - dirname = windirent_getenv("SystemDrive"); | |
| 1945 | - } | |
| 1946 | - | |
| 1813 | + struct _wfinddata_t data; | |
| 1814 | + | |
| 1815 | + pDir = sqlite3_malloc64( sizeof(DIR) ); | |
| 1816 | + if( pDir==0 ) return 0; | |
| 1817 | + memset(pDir, 0, sizeof(DIR)); | |
| 1947 | 1818 | memset(&data, 0, sizeof(data)); |
| 1948 | - sz = strlen(dirname); | |
| 1819 | + sz = strlen(zDirName); | |
| 1949 | 1820 | b1 = sqlite3_malloc64( (sz+3)*sizeof(b1[0]) ); |
| 1950 | 1821 | if( b1==0 ){ |
| 1951 | - closedir(dirp); | |
| 1822 | + closedir(pDir); | |
| 1952 | 1823 | return NULL; |
| 1953 | 1824 | } |
| 1954 | - sz = MultiByteToWideChar(CP_UTF8, 0, dirname, sz, b1, sz); | |
| 1825 | + sz = MultiByteToWideChar(CP_UTF8, 0, zDirName, sz, b1, sz); | |
| 1955 | 1826 | b1[sz++] = '\\'; |
| 1956 | 1827 | b1[sz++] = '*'; |
| 1957 | 1828 | b1[sz] = 0; |
| 1958 | - if( sz+1>(sqlite3_int64)namesize ){ | |
| 1959 | - closedir(dirp); | |
| 1829 | + if( sz+1>sizeof(data.name)/sizeof(data.name[0]) ){ | |
| 1830 | + closedir(pDir); | |
| 1960 | 1831 | sqlite3_free(b1); |
| 1961 | 1832 | return NULL; |
| 1962 | 1833 | } |
| 1963 | 1834 | memcpy(data.name, b1, (sz+1)*sizeof(b1[0])); |
| 1964 | 1835 | sqlite3_free(b1); |
| 1965 | - dirp->d_handle = _wfindfirst(data.name, &data); | |
| 1966 | - | |
| 1967 | - if( dirp->d_handle==BAD_INTPTR_T ){ | |
| 1968 | - closedir(dirp); | |
| 1969 | - return NULL; | |
| 1970 | - } | |
| 1971 | - | |
| 1972 | - /* TODO: Remove this block to allow hidden and/or system files. */ | |
| 1973 | - if( is_filtered(data) ){ | |
| 1974 | -next: | |
| 1975 | - | |
| 1976 | - memset(&data, 0, sizeof(data)); | |
| 1977 | - if( _wfindnext(dirp->d_handle, &data)==-1 ){ | |
| 1978 | - closedir(dirp); | |
| 1979 | - return NULL; | |
| 1980 | - } | |
| 1981 | - | |
| 1982 | - /* TODO: Remove this block to allow hidden and/or system files. */ | |
| 1983 | - if( is_filtered(data) ) goto next; | |
| 1984 | - } | |
| 1985 | - | |
| 1986 | - dirp->d_first.d_attributes = data.attrib; | |
| 1987 | - WideCharToMultiByte(CP_UTF8, 0, data.name, -1, | |
| 1988 | - dirp->d_first.d_name, DIRENT_NAME_MAX, 0, 0); | |
| 1989 | - return dirp; | |
| 1990 | -} | |
| 1991 | - | |
| 1992 | -/* | |
| 1993 | -** Implementation of the POSIX readdir() function using the MSVCRT. | |
| 1994 | -*/ | |
| 1995 | -LPDIRENT readdir( | |
| 1996 | - LPDIR dirp | |
| 1997 | -){ | |
| 1998 | - struct _wfinddata_t data; | |
| 1999 | - | |
| 2000 | - if( dirp==NULL ) return NULL; | |
| 2001 | - | |
| 2002 | - if( dirp->d_first.d_ino==0 ){ | |
| 2003 | - dirp->d_first.d_ino++; | |
| 2004 | - dirp->d_next.d_ino++; | |
| 2005 | - | |
| 2006 | - return &dirp->d_first; | |
| 2007 | - } | |
| 2008 | - | |
| 2009 | -next: | |
| 2010 | - | |
| 2011 | - memset(&data, 0, sizeof(data)); | |
| 2012 | - if( _wfindnext(dirp->d_handle, &data)==-1 ) return NULL; | |
| 2013 | - | |
| 2014 | - /* TODO: Remove this block to allow hidden and/or system files. */ | |
| 2015 | - if( is_filtered(data) ) goto next; | |
| 2016 | - | |
| 2017 | - dirp->d_next.d_ino++; | |
| 2018 | - dirp->d_next.d_attributes = data.attrib; | |
| 2019 | - WideCharToMultiByte(CP_UTF8, 0, data.name, -1, | |
| 2020 | - dirp->d_next.d_name, DIRENT_NAME_MAX, 0, 0); | |
| 2021 | - return &dirp->d_next; | |
| 2022 | -} | |
| 2023 | - | |
| 2024 | -/* | |
| 2025 | -** Implementation of the POSIX closedir() function using the MSVCRT. | |
| 2026 | -*/ | |
| 2027 | -INT closedir( | |
| 2028 | - LPDIR dirp | |
| 2029 | -){ | |
| 2030 | - INT result = 0; | |
| 2031 | - | |
| 2032 | - if( dirp==NULL ) return EINVAL; | |
| 2033 | - | |
| 2034 | - if( dirp->d_handle!=NULL_INTPTR_T && dirp->d_handle!=BAD_INTPTR_T ){ | |
| 2035 | - result = _findclose(dirp->d_handle); | |
| 2036 | - } | |
| 2037 | - | |
| 2038 | - sqlite3_free(dirp); | |
| 2039 | - return result; | |
| 2040 | -} | |
| 2041 | - | |
| 2042 | -#endif /* defined(WIN32) && defined(_MSC_VER) */ | |
| 2043 | - | |
| 2044 | -/************************* End test_windirent.c ********************/ | |
| 2045 | -#define dirent DIRENT | |
| 2046 | -#endif | |
| 1836 | + pDir->d_handle = _wfindfirst(data.name, &data); | |
| 1837 | + if( pDir->d_handle<0 ){ | |
| 1838 | + closedir(pDir); | |
| 1839 | + return NULL; | |
| 1840 | + } | |
| 1841 | + while( WindowsFileToIgnore(data) ){ | |
| 1842 | + memset(&data, 0, sizeof(data)); | |
| 1843 | + if( _wfindnext(pDir->d_handle, &data)==-1 ){ | |
| 1844 | + closedir(pDir); | |
| 1845 | + return NULL; | |
| 1846 | + } | |
| 1847 | + } | |
| 1848 | + pDir->cur.d_ino = 0; | |
| 1849 | + pDir->cur.d_attributes = data.attrib; | |
| 1850 | + WideCharToMultiByte(CP_UTF8, 0, data.name, -1, | |
| 1851 | + pDir->cur.d_name, FILENAME_MAX, 0, 0); | |
| 1852 | + return pDir; | |
| 1853 | +} | |
| 1854 | + | |
| 1855 | +/* | |
| 1856 | +** Read the next entry from a directory. | |
| 1857 | +** | |
| 1858 | +** The returned struct-dirent object is managed by DIR. It is only | |
| 1859 | +** valid until the next readdir() or closedir() call. Only the | |
| 1860 | +** d_name[] field is meaningful. The d_name[] value has been | |
| 1861 | +** translated into UTF8. | |
| 1862 | +*/ | |
| 1863 | +static struct dirent *readdir(DIR *pDir){ | |
| 1864 | + struct _wfinddata_t data; | |
| 1865 | + if( pDir==0 ) return 0; | |
| 1866 | + if( (pDir->cur.d_ino++)==0 ){ | |
| 1867 | + return &pDir->cur; | |
| 1868 | + } | |
| 1869 | + do{ | |
| 1870 | + memset(&data, 0, sizeof(data)); | |
| 1871 | + if( _wfindnext(pDir->d_handle, &data)==-1 ){ | |
| 1872 | + return NULL; | |
| 1873 | + } | |
| 1874 | + }while( WindowsFileToIgnore(data) ); | |
| 1875 | + pDir->cur.d_attributes = data.attrib; | |
| 1876 | + WideCharToMultiByte(CP_UTF8, 0, data.name, -1, | |
| 1877 | + pDir->cur.d_name, FILENAME_MAX, 0, 0); | |
| 1878 | + return &pDir->cur; | |
| 1879 | +} | |
| 1880 | + | |
| 1881 | +#endif /* defined(_WIN32) && defined(_MSC_VER) */ | |
| 1882 | + | |
| 1883 | +/************************* End ../ext/misc/windirent.h ********************/ | |
| 2047 | 1884 | /************************* Begin ../ext/misc/memtrace.c ******************/ |
| 2048 | 1885 | /* |
| 2049 | 1886 | ** 2019-01-21 |
| 2050 | 1887 | ** |
| 2051 | 1888 | ** The author disclaims copyright to this source code. In place of |
| @@ -8009,10 +7846,11 @@ | ||
| 8009 | 7846 | ** mode: Value of stat.st_mode for directory entry (an integer). |
| 8010 | 7847 | ** mtime: Value of stat.st_mtime for directory entry (an integer). |
| 8011 | 7848 | ** data: For a regular file, a blob containing the file data. For a |
| 8012 | 7849 | ** symlink, a text value containing the text of the link. For a |
| 8013 | 7850 | ** directory, NULL. |
| 7851 | +** level: Directory hierarchy level. Topmost is 1. | |
| 8014 | 7852 | ** |
| 8015 | 7853 | ** If a non-NULL value is specified for the optional $dir parameter and |
| 8016 | 7854 | ** $path is a relative path, then $path is interpreted relative to $dir. |
| 8017 | 7855 | ** And the paths returned in the "name" column of the table are also |
| 8018 | 7856 | ** relative to directory $dir. |
| @@ -8034,17 +7872,15 @@ | ||
| 8034 | 7872 | #if !defined(_WIN32) && !defined(WIN32) |
| 8035 | 7873 | # include <unistd.h> |
| 8036 | 7874 | # include <dirent.h> |
| 8037 | 7875 | # include <utime.h> |
| 8038 | 7876 | # include <sys/time.h> |
| 7877 | +# define STRUCT_STAT struct stat | |
| 8039 | 7878 | #else |
| 8040 | -# include "windows.h" | |
| 8041 | -# include <io.h> | |
| 7879 | +/* # include "windirent.h" */ | |
| 8042 | 7880 | # include <direct.h> |
| 8043 | -/* # include "test_windirent.h" */ | |
| 8044 | -# define dirent DIRENT | |
| 8045 | -# define stat _stat | |
| 7881 | +# define STRUCT_STAT struct _stat | |
| 8046 | 7882 | # define chmod(path,mode) fileio_chmod(path,mode) |
| 8047 | 7883 | # define mkdir(path,mode) fileio_mkdir(path) |
| 8048 | 7884 | #endif |
| 8049 | 7885 | #include <time.h> |
| 8050 | 7886 | #include <errno.h> |
| @@ -8058,18 +7894,20 @@ | ||
| 8058 | 7894 | #endif |
| 8059 | 7895 | |
| 8060 | 7896 | /* |
| 8061 | 7897 | ** Structure of the fsdir() table-valued function |
| 8062 | 7898 | */ |
| 8063 | - /* 0 1 2 3 4 5 */ | |
| 8064 | -#define FSDIR_SCHEMA "(name,mode,mtime,data,path HIDDEN,dir HIDDEN)" | |
| 7899 | + /* 0 1 2 3 4 5 6 */ | |
| 7900 | +#define FSDIR_SCHEMA "(name,mode,mtime,data,level,path HIDDEN,dir HIDDEN)" | |
| 7901 | + | |
| 8065 | 7902 | #define FSDIR_COLUMN_NAME 0 /* Name of the file */ |
| 8066 | 7903 | #define FSDIR_COLUMN_MODE 1 /* Access mode */ |
| 8067 | 7904 | #define FSDIR_COLUMN_MTIME 2 /* Last modification time */ |
| 8068 | 7905 | #define FSDIR_COLUMN_DATA 3 /* File content */ |
| 8069 | -#define FSDIR_COLUMN_PATH 4 /* Path to top of search */ | |
| 8070 | -#define FSDIR_COLUMN_DIR 5 /* Path is relative to this directory */ | |
| 7906 | +#define FSDIR_COLUMN_LEVEL 4 /* Level. Topmost is 1 */ | |
| 7907 | +#define FSDIR_COLUMN_PATH 5 /* Path to top of search */ | |
| 7908 | +#define FSDIR_COLUMN_DIR 6 /* Path is relative to this directory */ | |
| 8071 | 7909 | |
| 8072 | 7910 | /* |
| 8073 | 7911 | ** UTF8 chmod() function for Windows |
| 8074 | 7912 | */ |
| 8075 | 7913 | #if defined(_WIN32) || defined(WIN32) |
| @@ -8231,11 +8069,11 @@ | ||
| 8231 | 8069 | ** buffer to UTC. This is necessary on Win32, where the runtime library |
| 8232 | 8070 | ** appears to return these values as local times. |
| 8233 | 8071 | */ |
| 8234 | 8072 | static void statTimesToUtc( |
| 8235 | 8073 | const char *zPath, |
| 8236 | - struct stat *pStatBuf | |
| 8074 | + STRUCT_STAT *pStatBuf | |
| 8237 | 8075 | ){ |
| 8238 | 8076 | HANDLE hFindFile; |
| 8239 | 8077 | WIN32_FIND_DATAW fd; |
| 8240 | 8078 | LPWSTR zUnicodeName; |
| 8241 | 8079 | extern LPWSTR sqlite3_win32_utf8_to_unicode(const char*); |
| @@ -8259,11 +8097,11 @@ | ||
| 8259 | 8097 | ** is required in order for the included time to be returned as UTC. On all |
| 8260 | 8098 | ** other systems, this function simply calls stat(). |
| 8261 | 8099 | */ |
| 8262 | 8100 | static int fileStat( |
| 8263 | 8101 | const char *zPath, |
| 8264 | - struct stat *pStatBuf | |
| 8102 | + STRUCT_STAT *pStatBuf | |
| 8265 | 8103 | ){ |
| 8266 | 8104 | #if defined(_WIN32) |
| 8267 | 8105 | sqlite3_int64 sz = strlen(zPath); |
| 8268 | 8106 | wchar_t *b1 = sqlite3_malloc64( (sz+1)*sizeof(b1[0]) ); |
| 8269 | 8107 | int rc; |
| @@ -8283,11 +8121,11 @@ | ||
| 8283 | 8121 | ** is required in order for the included time to be returned as UTC. On all |
| 8284 | 8122 | ** other systems, this function simply calls lstat(). |
| 8285 | 8123 | */ |
| 8286 | 8124 | static int fileLinkStat( |
| 8287 | 8125 | const char *zPath, |
| 8288 | - struct stat *pStatBuf | |
| 8126 | + STRUCT_STAT *pStatBuf | |
| 8289 | 8127 | ){ |
| 8290 | 8128 | #if defined(_WIN32) |
| 8291 | 8129 | return fileStat(zPath, pStatBuf); |
| 8292 | 8130 | #else |
| 8293 | 8131 | return lstat(zPath, pStatBuf); |
| @@ -8316,11 +8154,11 @@ | ||
| 8316 | 8154 | }else{ |
| 8317 | 8155 | int nCopy = (int)strlen(zCopy); |
| 8318 | 8156 | int i = 1; |
| 8319 | 8157 | |
| 8320 | 8158 | while( rc==SQLITE_OK ){ |
| 8321 | - struct stat sStat; | |
| 8159 | + STRUCT_STAT sStat; | |
| 8322 | 8160 | int rc2; |
| 8323 | 8161 | |
| 8324 | 8162 | for(; zCopy[i]!='/' && i<nCopy; i++); |
| 8325 | 8163 | if( i==nCopy ) break; |
| 8326 | 8164 | zCopy[i] = '\0'; |
| @@ -8366,11 +8204,11 @@ | ||
| 8366 | 8204 | if( mkdir(zFile, mode) ){ |
| 8367 | 8205 | /* The mkdir() call to create the directory failed. This might not |
| 8368 | 8206 | ** be an error though - if there is already a directory at the same |
| 8369 | 8207 | ** path and either the permissions already match or can be changed |
| 8370 | 8208 | ** to do so using chmod(), it is not an error. */ |
| 8371 | - struct stat sStat; | |
| 8209 | + STRUCT_STAT sStat; | |
| 8372 | 8210 | if( errno!=EEXIST |
| 8373 | 8211 | || 0!=fileStat(zFile, &sStat) |
| 8374 | 8212 | || !S_ISDIR(sStat.st_mode) |
| 8375 | 8213 | || ((sStat.st_mode&0777)!=(mode&0777) && 0!=chmod(zFile, mode&0777)) |
| 8376 | 8214 | ){ |
| @@ -8562,17 +8400,18 @@ | ||
| 8562 | 8400 | |
| 8563 | 8401 | struct fsdir_cursor { |
| 8564 | 8402 | sqlite3_vtab_cursor base; /* Base class - must be first */ |
| 8565 | 8403 | |
| 8566 | 8404 | int nLvl; /* Number of entries in aLvl[] array */ |
| 8405 | + int mxLvl; /* Maximum level */ | |
| 8567 | 8406 | int iLvl; /* Index of current entry */ |
| 8568 | 8407 | FsdirLevel *aLvl; /* Hierarchy of directories being traversed */ |
| 8569 | 8408 | |
| 8570 | 8409 | const char *zBase; |
| 8571 | 8410 | int nBase; |
| 8572 | 8411 | |
| 8573 | - struct stat sStat; /* Current lstat() results */ | |
| 8412 | + STRUCT_STAT sStat; /* Current lstat() results */ | |
| 8574 | 8413 | char *zPath; /* Path to current entry */ |
| 8575 | 8414 | sqlite3_int64 iRowid; /* Current rowid */ |
| 8576 | 8415 | }; |
| 8577 | 8416 | |
| 8578 | 8417 | typedef struct fsdir_tab fsdir_tab; |
| @@ -8680,11 +8519,11 @@ | ||
| 8680 | 8519 | static int fsdirNext(sqlite3_vtab_cursor *cur){ |
| 8681 | 8520 | fsdir_cursor *pCur = (fsdir_cursor*)cur; |
| 8682 | 8521 | mode_t m = pCur->sStat.st_mode; |
| 8683 | 8522 | |
| 8684 | 8523 | pCur->iRowid++; |
| 8685 | - if( S_ISDIR(m) ){ | |
| 8524 | + if( S_ISDIR(m) && pCur->iLvl+3<pCur->mxLvl ){ | |
| 8686 | 8525 | /* Descend into this directory */ |
| 8687 | 8526 | int iNew = pCur->iLvl + 1; |
| 8688 | 8527 | FsdirLevel *pLvl; |
| 8689 | 8528 | if( iNew>=pCur->nLvl ){ |
| 8690 | 8529 | int nNew = iNew+1; |
| @@ -8788,11 +8627,15 @@ | ||
| 8788 | 8627 | if( aBuf!=aStatic ) sqlite3_free(aBuf); |
| 8789 | 8628 | #endif |
| 8790 | 8629 | }else{ |
| 8791 | 8630 | readFileContents(ctx, pCur->zPath); |
| 8792 | 8631 | } |
| 8632 | + break; | |
| 8793 | 8633 | } |
| 8634 | + case FSDIR_COLUMN_LEVEL: | |
| 8635 | + sqlite3_result_int(ctx, pCur->iLvl+2); | |
| 8636 | + break; | |
| 8794 | 8637 | case FSDIR_COLUMN_PATH: |
| 8795 | 8638 | default: { |
| 8796 | 8639 | /* The FSDIR_COLUMN_PATH and FSDIR_COLUMN_DIR are input parameters. |
| 8797 | 8640 | ** always return their values as NULL */ |
| 8798 | 8641 | break; |
| @@ -8822,36 +8665,50 @@ | ||
| 8822 | 8665 | } |
| 8823 | 8666 | |
| 8824 | 8667 | /* |
| 8825 | 8668 | ** xFilter callback. |
| 8826 | 8669 | ** |
| 8827 | -** idxNum==1 PATH parameter only | |
| 8828 | -** idxNum==2 Both PATH and DIR supplied | |
| 8670 | +** idxNum bit Meaning | |
| 8671 | +** 0x01 PATH=N | |
| 8672 | +** 0x02 DIR=N | |
| 8673 | +** 0x04 LEVEL<N | |
| 8674 | +** 0x08 LEVEL<=N | |
| 8829 | 8675 | */ |
| 8830 | 8676 | static int fsdirFilter( |
| 8831 | 8677 | sqlite3_vtab_cursor *cur, |
| 8832 | 8678 | int idxNum, const char *idxStr, |
| 8833 | 8679 | int argc, sqlite3_value **argv |
| 8834 | 8680 | ){ |
| 8835 | 8681 | const char *zDir = 0; |
| 8836 | 8682 | fsdir_cursor *pCur = (fsdir_cursor*)cur; |
| 8683 | + int i; | |
| 8837 | 8684 | (void)idxStr; |
| 8838 | 8685 | fsdirResetCursor(pCur); |
| 8839 | 8686 | |
| 8840 | 8687 | if( idxNum==0 ){ |
| 8841 | 8688 | fsdirSetErrmsg(pCur, "table function fsdir requires an argument"); |
| 8842 | 8689 | return SQLITE_ERROR; |
| 8843 | 8690 | } |
| 8844 | 8691 | |
| 8845 | - assert( argc==idxNum && (argc==1 || argc==2) ); | |
| 8692 | + assert( (idxNum & 0x01)!=0 && argc>0 ); | |
| 8846 | 8693 | zDir = (const char*)sqlite3_value_text(argv[0]); |
| 8847 | 8694 | if( zDir==0 ){ |
| 8848 | 8695 | fsdirSetErrmsg(pCur, "table function fsdir requires a non-NULL argument"); |
| 8849 | 8696 | return SQLITE_ERROR; |
| 8850 | 8697 | } |
| 8851 | - if( argc==2 ){ | |
| 8852 | - pCur->zBase = (const char*)sqlite3_value_text(argv[1]); | |
| 8698 | + i = 1; | |
| 8699 | + if( (idxNum & 0x02)!=0 ){ | |
| 8700 | + assert( argc>i ); | |
| 8701 | + pCur->zBase = (const char*)sqlite3_value_text(argv[i++]); | |
| 8702 | + } | |
| 8703 | + if( (idxNum & 0x0c)!=0 ){ | |
| 8704 | + assert( argc>i ); | |
| 8705 | + pCur->mxLvl = sqlite3_value_int(argv[i++]); | |
| 8706 | + if( idxNum & 0x08 ) pCur->mxLvl++; | |
| 8707 | + if( pCur->mxLvl<=0 ) pCur->mxLvl = 1000000000; | |
| 8708 | + }else{ | |
| 8709 | + pCur->mxLvl = 1000000000; | |
| 8853 | 8710 | } |
| 8854 | 8711 | if( pCur->zBase ){ |
| 8855 | 8712 | pCur->nBase = (int)strlen(pCur->zBase)+1; |
| 8856 | 8713 | pCur->zPath = sqlite3_mprintf("%s/%s", pCur->zBase, zDir); |
| 8857 | 8714 | }else{ |
| @@ -8876,48 +8733,75 @@ | ||
| 8876 | 8733 | ** plan. |
| 8877 | 8734 | ** |
| 8878 | 8735 | ** In this implementation idxNum is used to represent the |
| 8879 | 8736 | ** query plan. idxStr is unused. |
| 8880 | 8737 | ** |
| 8881 | -** The query plan is represented by values of idxNum: | |
| 8738 | +** The query plan is represented by bits in idxNum: | |
| 8882 | 8739 | ** |
| 8883 | -** (1) The path value is supplied by argv[0] | |
| 8884 | -** (2) Path is in argv[0] and dir is in argv[1] | |
| 8740 | +** 0x01 The path value is supplied by argv[0] | |
| 8741 | +** 0x02 dir is in argv[1] | |
| 8742 | +** 0x04 maxdepth is in argv[1] or [2] | |
| 8885 | 8743 | */ |
| 8886 | 8744 | static int fsdirBestIndex( |
| 8887 | 8745 | sqlite3_vtab *tab, |
| 8888 | 8746 | sqlite3_index_info *pIdxInfo |
| 8889 | 8747 | ){ |
| 8890 | 8748 | int i; /* Loop over constraints */ |
| 8891 | 8749 | int idxPath = -1; /* Index in pIdxInfo->aConstraint of PATH= */ |
| 8892 | 8750 | int idxDir = -1; /* Index in pIdxInfo->aConstraint of DIR= */ |
| 8751 | + int idxLevel = -1; /* Index in pIdxInfo->aConstraint of LEVEL< or <= */ | |
| 8752 | + int idxLevelEQ = 0; /* 0x08 for LEVEL<= or LEVEL=. 0x04 for LEVEL< */ | |
| 8753 | + int omitLevel = 0; /* omit the LEVEL constraint */ | |
| 8893 | 8754 | int seenPath = 0; /* True if an unusable PATH= constraint is seen */ |
| 8894 | 8755 | int seenDir = 0; /* True if an unusable DIR= constraint is seen */ |
| 8895 | 8756 | const struct sqlite3_index_constraint *pConstraint; |
| 8896 | 8757 | |
| 8897 | 8758 | (void)tab; |
| 8898 | 8759 | pConstraint = pIdxInfo->aConstraint; |
| 8899 | 8760 | for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){ |
| 8900 | - if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue; | |
| 8901 | - switch( pConstraint->iColumn ){ | |
| 8902 | - case FSDIR_COLUMN_PATH: { | |
| 8903 | - if( pConstraint->usable ){ | |
| 8904 | - idxPath = i; | |
| 8905 | - seenPath = 0; | |
| 8906 | - }else if( idxPath<0 ){ | |
| 8907 | - seenPath = 1; | |
| 8908 | - } | |
| 8909 | - break; | |
| 8910 | - } | |
| 8911 | - case FSDIR_COLUMN_DIR: { | |
| 8912 | - if( pConstraint->usable ){ | |
| 8913 | - idxDir = i; | |
| 8914 | - seenDir = 0; | |
| 8915 | - }else if( idxDir<0 ){ | |
| 8916 | - seenDir = 1; | |
| 8917 | - } | |
| 8918 | - break; | |
| 8761 | + if( pConstraint->op==SQLITE_INDEX_CONSTRAINT_EQ ){ | |
| 8762 | + switch( pConstraint->iColumn ){ | |
| 8763 | + case FSDIR_COLUMN_PATH: { | |
| 8764 | + if( pConstraint->usable ){ | |
| 8765 | + idxPath = i; | |
| 8766 | + seenPath = 0; | |
| 8767 | + }else if( idxPath<0 ){ | |
| 8768 | + seenPath = 1; | |
| 8769 | + } | |
| 8770 | + break; | |
| 8771 | + } | |
| 8772 | + case FSDIR_COLUMN_DIR: { | |
| 8773 | + if( pConstraint->usable ){ | |
| 8774 | + idxDir = i; | |
| 8775 | + seenDir = 0; | |
| 8776 | + }else if( idxDir<0 ){ | |
| 8777 | + seenDir = 1; | |
| 8778 | + } | |
| 8779 | + break; | |
| 8780 | + } | |
| 8781 | + case FSDIR_COLUMN_LEVEL: { | |
| 8782 | + if( pConstraint->usable && idxLevel<0 ){ | |
| 8783 | + idxLevel = i; | |
| 8784 | + idxLevelEQ = 0x08; | |
| 8785 | + omitLevel = 0; | |
| 8786 | + } | |
| 8787 | + break; | |
| 8788 | + } | |
| 8789 | + } | |
| 8790 | + }else | |
| 8791 | + if( pConstraint->iColumn==FSDIR_COLUMN_LEVEL | |
| 8792 | + && pConstraint->usable | |
| 8793 | + && idxLevel<0 | |
| 8794 | + ){ | |
| 8795 | + if( pConstraint->op==SQLITE_INDEX_CONSTRAINT_LE ){ | |
| 8796 | + idxLevel = i; | |
| 8797 | + idxLevelEQ = 0x08; | |
| 8798 | + omitLevel = 1; | |
| 8799 | + }else if( pConstraint->op==SQLITE_INDEX_CONSTRAINT_LT ){ | |
| 8800 | + idxLevel = i; | |
| 8801 | + idxLevelEQ = 0x04; | |
| 8802 | + omitLevel = 1; | |
| 8919 | 8803 | } |
| 8920 | 8804 | } |
| 8921 | 8805 | } |
| 8922 | 8806 | if( seenPath || seenDir ){ |
| 8923 | 8807 | /* If input parameters are unusable, disallow this plan */ |
| @@ -8930,18 +8814,24 @@ | ||
| 8930 | 8814 | ** number. Leave it unchanged. */ |
| 8931 | 8815 | pIdxInfo->estimatedRows = 0x7fffffff; |
| 8932 | 8816 | }else{ |
| 8933 | 8817 | pIdxInfo->aConstraintUsage[idxPath].omit = 1; |
| 8934 | 8818 | pIdxInfo->aConstraintUsage[idxPath].argvIndex = 1; |
| 8819 | + pIdxInfo->idxNum = 0x01; | |
| 8820 | + pIdxInfo->estimatedCost = 1.0e9; | |
| 8821 | + i = 2; | |
| 8935 | 8822 | if( idxDir>=0 ){ |
| 8936 | 8823 | pIdxInfo->aConstraintUsage[idxDir].omit = 1; |
| 8937 | - pIdxInfo->aConstraintUsage[idxDir].argvIndex = 2; | |
| 8938 | - pIdxInfo->idxNum = 2; | |
| 8939 | - pIdxInfo->estimatedCost = 10.0; | |
| 8940 | - }else{ | |
| 8941 | - pIdxInfo->idxNum = 1; | |
| 8942 | - pIdxInfo->estimatedCost = 100.0; | |
| 8824 | + pIdxInfo->aConstraintUsage[idxDir].argvIndex = i++; | |
| 8825 | + pIdxInfo->idxNum |= 0x02; | |
| 8826 | + pIdxInfo->estimatedCost /= 1.0e4; | |
| 8827 | + } | |
| 8828 | + if( idxLevel>=0 ){ | |
| 8829 | + pIdxInfo->aConstraintUsage[idxLevel].omit = omitLevel; | |
| 8830 | + pIdxInfo->aConstraintUsage[idxLevel].argvIndex = i++; | |
| 8831 | + pIdxInfo->idxNum |= idxLevelEQ; | |
| 8832 | + pIdxInfo->estimatedCost /= 1.0e4; | |
| 8943 | 8833 | } |
| 8944 | 8834 | } |
| 8945 | 8835 | |
| 8946 | 8836 | return SQLITE_OK; |
| 8947 | 8837 | } |
| @@ -31828,11 +31718,11 @@ | ||
| 31828 | 31718 | const char *zUsage; /* Usage notes */ |
| 31829 | 31719 | } aCtrl[] = { |
| 31830 | 31720 | {"always", SQLITE_TESTCTRL_ALWAYS, 1, "BOOLEAN" }, |
| 31831 | 31721 | {"assert", SQLITE_TESTCTRL_ASSERT, 1, "BOOLEAN" }, |
| 31832 | 31722 | /*{"benign_malloc_hooks",SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS,1, "" },*/ |
| 31833 | - /*{"bitvec_test", SQLITE_TESTCTRL_BITVEC_TEST, 1, "" },*/ | |
| 31723 | + {"bitvec_test", SQLITE_TESTCTRL_BITVEC_TEST, 1, "SIZE INT-ARRAY"}, | |
| 31834 | 31724 | {"byteorder", SQLITE_TESTCTRL_BYTEORDER, 0, "" }, |
| 31835 | 31725 | {"extra_schema_checks",SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS,0,"BOOLEAN" }, |
| 31836 | 31726 | {"fault_install", SQLITE_TESTCTRL_FAULT_INSTALL, 1,"args..." }, |
| 31837 | 31727 | {"fk_no_action", SQLITE_TESTCTRL_FK_NO_ACTION, 0, "BOOLEAN" }, |
| 31838 | 31728 | {"imposter", SQLITE_TESTCTRL_IMPOSTER,1,"SCHEMA ON/OFF ROOTPAGE"}, |
| @@ -32166,10 +32056,53 @@ | ||
| 32166 | 32056 | rc2 = booleanValue(azArg[2]); |
| 32167 | 32057 | isOk = 3; |
| 32168 | 32058 | } |
| 32169 | 32059 | sqlite3_test_control(testctrl, &rc2); |
| 32170 | 32060 | break; |
| 32061 | + case SQLITE_TESTCTRL_BITVEC_TEST: { | |
| 32062 | + /* Examples: | |
| 32063 | + ** .testctrl bitvec_test 100 6,1 -- Show BITVEC constants | |
| 32064 | + ** .testctrl bitvec_test 1000 1,12,7,3 -- Simple test | |
| 32065 | + ** ---- -------- | |
| 32066 | + ** size of Bitvec -----^ ^--- aOp array. 0 added at end. | |
| 32067 | + ** | |
| 32068 | + ** See comments on sqlite3BitvecBuiltinTest() for more information | |
| 32069 | + ** about the aOp[] array. | |
| 32070 | + */ | |
| 32071 | + int iSize; | |
| 32072 | + const char *zTestArg; | |
| 32073 | + int nOp; | |
| 32074 | + int ii, jj, x; | |
| 32075 | + int *aOp; | |
| 32076 | + if( nArg!=4 ){ | |
| 32077 | + sqlite3_fprintf(stderr, | |
| 32078 | + "ERROR - should be: \".testctrl bitvec_test SIZE INT-ARRAY\"\n" | |
| 32079 | + ); | |
| 32080 | + rc = 1; | |
| 32081 | + goto meta_command_exit; | |
| 32082 | + } | |
| 32083 | + isOk = 3; | |
| 32084 | + iSize = (int)integerValue(azArg[2]); | |
| 32085 | + zTestArg = azArg[3]; | |
| 32086 | + nOp = (int)strlen(zTestArg)+1; | |
| 32087 | + aOp = malloc( sizeof(int)*(nOp+1) ); | |
| 32088 | + shell_check_oom(aOp); | |
| 32089 | + memset(aOp, 0, sizeof(int)*(nOp+1) ); | |
| 32090 | + for(ii = jj = x = 0; zTestArg[ii]!=0; ii++){ | |
| 32091 | + if( IsDigit(zTestArg[ii]) ){ | |
| 32092 | + x = x*10 + zTestArg[ii] - '0'; | |
| 32093 | + }else{ | |
| 32094 | + aOp[jj++] = x; | |
| 32095 | + x = 0; | |
| 32096 | + } | |
| 32097 | + } | |
| 32098 | + aOp[jj] = x; | |
| 32099 | + x = sqlite3_test_control(testctrl, iSize, aOp); | |
| 32100 | + sqlite3_fprintf(p->out, "result: %d\n", x); | |
| 32101 | + free(aOp); | |
| 32102 | + break; | |
| 32103 | + } | |
| 32171 | 32104 | case SQLITE_TESTCTRL_FAULT_INSTALL: { |
| 32172 | 32105 | int kk; |
| 32173 | 32106 | int bShowHelp = nArg<=2; |
| 32174 | 32107 | isOk = 3; |
| 32175 | 32108 | for(kk=2; kk<nArg; kk++){ |
| 32176 | 32109 |
| --- extsrc/shell.c | |
| +++ extsrc/shell.c | |
| @@ -1713,339 +1713,176 @@ | |
| 1713 | ** work here in the middle of this regular program. |
| 1714 | */ |
| 1715 | #define SQLITE_EXTENSION_INIT1 |
| 1716 | #define SQLITE_EXTENSION_INIT2(X) (void)(X) |
| 1717 | |
| 1718 | #if defined(_WIN32) && defined(_MSC_VER) |
| 1719 | /************************* Begin test_windirent.h ******************/ |
| 1720 | /* |
| 1721 | ** 2015 November 30 |
| 1722 | ** |
| 1723 | ** The author disclaims copyright to this source code. In place of |
| 1724 | ** a legal notice, here is a blessing: |
| 1725 | ** |
| 1726 | ** May you do good and not evil. |
| 1727 | ** May you find forgiveness for yourself and forgive others. |
| 1728 | ** May you share freely, never taking more than you give. |
| 1729 | ** |
| 1730 | ************************************************************************* |
| 1731 | ** This file contains declarations for most of the opendir() family of |
| 1732 | ** POSIX functions on Win32 using the MSVCRT. |
| 1733 | */ |
| 1734 | |
| 1735 | #if defined(_WIN32) && defined(_MSC_VER) && !defined(SQLITE_WINDIRENT_H) |
| 1736 | #define SQLITE_WINDIRENT_H |
| 1737 | |
| 1738 | /* |
| 1739 | ** We need several data types from the Windows SDK header. |
| 1740 | */ |
| 1741 | |
| 1742 | #ifndef WIN32_LEAN_AND_MEAN |
| 1743 | #define WIN32_LEAN_AND_MEAN |
| 1744 | #endif |
| 1745 | |
| 1746 | #include "windows.h" |
| 1747 | |
| 1748 | /* |
| 1749 | ** We need several support functions from the SQLite core. |
| 1750 | */ |
| 1751 | |
| 1752 | /* #include "sqlite3.h" */ |
| 1753 | |
| 1754 | /* |
| 1755 | ** We need several things from the ANSI and MSVCRT headers. |
| 1756 | */ |
| 1757 | |
| 1758 | #include <stdio.h> |
| 1759 | #include <stdlib.h> |
| 1760 | #include <errno.h> |
| 1761 | #include <io.h> |
| 1762 | #include <limits.h> |
| 1763 | #include <sys/types.h> |
| 1764 | #include <sys/stat.h> |
| 1765 | |
| 1766 | /* |
| 1767 | ** We may need several defines that should have been in "sys/stat.h". |
| 1768 | */ |
| 1769 | |
| 1770 | #ifndef S_ISREG |
| 1771 | #define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG) |
| 1772 | #endif |
| 1773 | |
| 1774 | #ifndef S_ISDIR |
| 1775 | #define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR) |
| 1776 | #endif |
| 1777 | |
| 1778 | #ifndef S_ISLNK |
| 1779 | #define S_ISLNK(mode) (0) |
| 1780 | #endif |
| 1781 | |
| 1782 | /* |
| 1783 | ** We may need to provide the "mode_t" type. |
| 1784 | */ |
| 1785 | |
| 1786 | #ifndef MODE_T_DEFINED |
| 1787 | #define MODE_T_DEFINED |
| 1788 | typedef unsigned short mode_t; |
| 1789 | #endif |
| 1790 | |
| 1791 | /* |
| 1792 | ** We may need to provide the "ino_t" type. |
| 1793 | */ |
| 1794 | |
| 1795 | #ifndef INO_T_DEFINED |
| 1796 | #define INO_T_DEFINED |
| 1797 | typedef unsigned short ino_t; |
| 1798 | #endif |
| 1799 | |
| 1800 | /* |
| 1801 | ** We need to define "NAME_MAX" if it was not present in "limits.h". |
| 1802 | */ |
| 1803 | |
| 1804 | #ifndef NAME_MAX |
| 1805 | # ifdef FILENAME_MAX |
| 1806 | # define NAME_MAX (FILENAME_MAX) |
| 1807 | # else |
| 1808 | # define NAME_MAX (260) |
| 1809 | # endif |
| 1810 | # define DIRENT_NAME_MAX (NAME_MAX) |
| 1811 | #endif |
| 1812 | |
| 1813 | /* |
| 1814 | ** We need to define "NULL_INTPTR_T" and "BAD_INTPTR_T". |
| 1815 | */ |
| 1816 | |
| 1817 | #ifndef NULL_INTPTR_T |
| 1818 | # define NULL_INTPTR_T ((intptr_t)(0)) |
| 1819 | #endif |
| 1820 | |
| 1821 | #ifndef BAD_INTPTR_T |
| 1822 | # define BAD_INTPTR_T ((intptr_t)(-1)) |
| 1823 | #endif |
| 1824 | |
| 1825 | /* |
| 1826 | ** We need to provide the necessary structures and related types. |
| 1827 | */ |
| 1828 | |
| 1829 | #ifndef DIRENT_DEFINED |
| 1830 | #define DIRENT_DEFINED |
| 1831 | typedef struct DIRENT DIRENT; |
| 1832 | typedef DIRENT *LPDIRENT; |
| 1833 | struct DIRENT { |
| 1834 | ino_t d_ino; /* Sequence number, do not use. */ |
| 1835 | unsigned d_attributes; /* Win32 file attributes. */ |
| 1836 | char d_name[NAME_MAX + 1]; /* Name within the directory. */ |
| 1837 | }; |
| 1838 | #endif |
| 1839 | |
| 1840 | #ifndef DIR_DEFINED |
| 1841 | #define DIR_DEFINED |
| 1842 | typedef struct DIR DIR; |
| 1843 | typedef DIR *LPDIR; |
| 1844 | struct DIR { |
| 1845 | intptr_t d_handle; /* Value returned by "_findfirst". */ |
| 1846 | DIRENT d_first; /* DIRENT constructed based on "_findfirst". */ |
| 1847 | DIRENT d_next; /* DIRENT constructed based on "_findnext". */ |
| 1848 | }; |
| 1849 | #endif |
| 1850 | |
| 1851 | /* |
| 1852 | ** Provide a macro, for use by the implementation, to determine if a |
| 1853 | ** particular directory entry should be skipped over when searching for |
| 1854 | ** the next directory entry that should be returned by the readdir(). |
| 1855 | */ |
| 1856 | |
| 1857 | #ifndef is_filtered |
| 1858 | # define is_filtered(a) ((((a).attrib)&_A_HIDDEN) || (((a).attrib)&_A_SYSTEM)) |
| 1859 | #endif |
| 1860 | |
| 1861 | /* |
| 1862 | ** Provide the function prototype for the POSIX compatible getenv() |
| 1863 | ** function. This function is not thread-safe. |
| 1864 | */ |
| 1865 | |
| 1866 | extern const char *windirent_getenv(const char *name); |
| 1867 | |
| 1868 | /* |
| 1869 | ** Finally, we can provide the function prototypes for the opendir(), |
| 1870 | ** readdir(), and closedir() POSIX functions. |
| 1871 | */ |
| 1872 | |
| 1873 | extern LPDIR opendir(const char *dirname); |
| 1874 | extern LPDIRENT readdir(LPDIR dirp); |
| 1875 | extern INT closedir(LPDIR dirp); |
| 1876 | |
| 1877 | #endif /* defined(WIN32) && defined(_MSC_VER) */ |
| 1878 | |
| 1879 | /************************* End test_windirent.h ********************/ |
| 1880 | /************************* Begin test_windirent.c ******************/ |
| 1881 | /* |
| 1882 | ** 2015 November 30 |
| 1883 | ** |
| 1884 | ** The author disclaims copyright to this source code. In place of |
| 1885 | ** a legal notice, here is a blessing: |
| 1886 | ** |
| 1887 | ** May you do good and not evil. |
| 1888 | ** May you find forgiveness for yourself and forgive others. |
| 1889 | ** May you share freely, never taking more than you give. |
| 1890 | ** |
| 1891 | ************************************************************************* |
| 1892 | ** This file contains code to implement most of the opendir() family of |
| 1893 | ** POSIX functions on Win32 using the MSVCRT. |
| 1894 | */ |
| 1895 | |
| 1896 | #if defined(_WIN32) && defined(_MSC_VER) |
| 1897 | /* #include "test_windirent.h" */ |
| 1898 | |
| 1899 | /* |
| 1900 | ** Implementation of the POSIX getenv() function using the Win32 API. |
| 1901 | ** This function is not thread-safe. |
| 1902 | */ |
| 1903 | const char *windirent_getenv( |
| 1904 | const char *name |
| 1905 | ){ |
| 1906 | static char value[32768]; /* Maximum length, per MSDN */ |
| 1907 | DWORD dwSize = sizeof(value) / sizeof(char); /* Size in chars */ |
| 1908 | DWORD dwRet; /* Value returned by GetEnvironmentVariableA() */ |
| 1909 | |
| 1910 | memset(value, 0, sizeof(value)); |
| 1911 | dwRet = GetEnvironmentVariableA(name, value, dwSize); |
| 1912 | if( dwRet==0 || dwRet>dwSize ){ |
| 1913 | /* |
| 1914 | ** The function call to GetEnvironmentVariableA() failed -OR- |
| 1915 | ** the buffer is not large enough. Either way, return NULL. |
| 1916 | */ |
| 1917 | return 0; |
| 1918 | }else{ |
| 1919 | /* |
| 1920 | ** The function call to GetEnvironmentVariableA() succeeded |
| 1921 | ** -AND- the buffer contains the entire value. |
| 1922 | */ |
| 1923 | return value; |
| 1924 | } |
| 1925 | } |
| 1926 | |
| 1927 | /* |
| 1928 | ** Implementation of the POSIX opendir() function using the MSVCRT. |
| 1929 | */ |
| 1930 | LPDIR opendir( |
| 1931 | const char *dirname /* Directory name, UTF8 encoding */ |
| 1932 | ){ |
| 1933 | struct _wfinddata_t data; |
| 1934 | LPDIR dirp = (LPDIR)sqlite3_malloc(sizeof(DIR)); |
| 1935 | SIZE_T namesize = sizeof(data.name) / sizeof(data.name[0]); |
| 1936 | wchar_t *b1; |
| 1937 | sqlite3_int64 sz; |
| 1938 | |
| 1939 | if( dirp==NULL ) return NULL; |
| 1940 | memset(dirp, 0, sizeof(DIR)); |
| 1941 | |
| 1942 | /* TODO: Remove this if Unix-style root paths are not used. */ |
| 1943 | if( sqlite3_stricmp(dirname, "/")==0 ){ |
| 1944 | dirname = windirent_getenv("SystemDrive"); |
| 1945 | } |
| 1946 | |
| 1947 | memset(&data, 0, sizeof(data)); |
| 1948 | sz = strlen(dirname); |
| 1949 | b1 = sqlite3_malloc64( (sz+3)*sizeof(b1[0]) ); |
| 1950 | if( b1==0 ){ |
| 1951 | closedir(dirp); |
| 1952 | return NULL; |
| 1953 | } |
| 1954 | sz = MultiByteToWideChar(CP_UTF8, 0, dirname, sz, b1, sz); |
| 1955 | b1[sz++] = '\\'; |
| 1956 | b1[sz++] = '*'; |
| 1957 | b1[sz] = 0; |
| 1958 | if( sz+1>(sqlite3_int64)namesize ){ |
| 1959 | closedir(dirp); |
| 1960 | sqlite3_free(b1); |
| 1961 | return NULL; |
| 1962 | } |
| 1963 | memcpy(data.name, b1, (sz+1)*sizeof(b1[0])); |
| 1964 | sqlite3_free(b1); |
| 1965 | dirp->d_handle = _wfindfirst(data.name, &data); |
| 1966 | |
| 1967 | if( dirp->d_handle==BAD_INTPTR_T ){ |
| 1968 | closedir(dirp); |
| 1969 | return NULL; |
| 1970 | } |
| 1971 | |
| 1972 | /* TODO: Remove this block to allow hidden and/or system files. */ |
| 1973 | if( is_filtered(data) ){ |
| 1974 | next: |
| 1975 | |
| 1976 | memset(&data, 0, sizeof(data)); |
| 1977 | if( _wfindnext(dirp->d_handle, &data)==-1 ){ |
| 1978 | closedir(dirp); |
| 1979 | return NULL; |
| 1980 | } |
| 1981 | |
| 1982 | /* TODO: Remove this block to allow hidden and/or system files. */ |
| 1983 | if( is_filtered(data) ) goto next; |
| 1984 | } |
| 1985 | |
| 1986 | dirp->d_first.d_attributes = data.attrib; |
| 1987 | WideCharToMultiByte(CP_UTF8, 0, data.name, -1, |
| 1988 | dirp->d_first.d_name, DIRENT_NAME_MAX, 0, 0); |
| 1989 | return dirp; |
| 1990 | } |
| 1991 | |
| 1992 | /* |
| 1993 | ** Implementation of the POSIX readdir() function using the MSVCRT. |
| 1994 | */ |
| 1995 | LPDIRENT readdir( |
| 1996 | LPDIR dirp |
| 1997 | ){ |
| 1998 | struct _wfinddata_t data; |
| 1999 | |
| 2000 | if( dirp==NULL ) return NULL; |
| 2001 | |
| 2002 | if( dirp->d_first.d_ino==0 ){ |
| 2003 | dirp->d_first.d_ino++; |
| 2004 | dirp->d_next.d_ino++; |
| 2005 | |
| 2006 | return &dirp->d_first; |
| 2007 | } |
| 2008 | |
| 2009 | next: |
| 2010 | |
| 2011 | memset(&data, 0, sizeof(data)); |
| 2012 | if( _wfindnext(dirp->d_handle, &data)==-1 ) return NULL; |
| 2013 | |
| 2014 | /* TODO: Remove this block to allow hidden and/or system files. */ |
| 2015 | if( is_filtered(data) ) goto next; |
| 2016 | |
| 2017 | dirp->d_next.d_ino++; |
| 2018 | dirp->d_next.d_attributes = data.attrib; |
| 2019 | WideCharToMultiByte(CP_UTF8, 0, data.name, -1, |
| 2020 | dirp->d_next.d_name, DIRENT_NAME_MAX, 0, 0); |
| 2021 | return &dirp->d_next; |
| 2022 | } |
| 2023 | |
| 2024 | /* |
| 2025 | ** Implementation of the POSIX closedir() function using the MSVCRT. |
| 2026 | */ |
| 2027 | INT closedir( |
| 2028 | LPDIR dirp |
| 2029 | ){ |
| 2030 | INT result = 0; |
| 2031 | |
| 2032 | if( dirp==NULL ) return EINVAL; |
| 2033 | |
| 2034 | if( dirp->d_handle!=NULL_INTPTR_T && dirp->d_handle!=BAD_INTPTR_T ){ |
| 2035 | result = _findclose(dirp->d_handle); |
| 2036 | } |
| 2037 | |
| 2038 | sqlite3_free(dirp); |
| 2039 | return result; |
| 2040 | } |
| 2041 | |
| 2042 | #endif /* defined(WIN32) && defined(_MSC_VER) */ |
| 2043 | |
| 2044 | /************************* End test_windirent.c ********************/ |
| 2045 | #define dirent DIRENT |
| 2046 | #endif |
| 2047 | /************************* Begin ../ext/misc/memtrace.c ******************/ |
| 2048 | /* |
| 2049 | ** 2019-01-21 |
| 2050 | ** |
| 2051 | ** The author disclaims copyright to this source code. In place of |
| @@ -8009,10 +7846,11 @@ | |
| 8009 | ** mode: Value of stat.st_mode for directory entry (an integer). |
| 8010 | ** mtime: Value of stat.st_mtime for directory entry (an integer). |
| 8011 | ** data: For a regular file, a blob containing the file data. For a |
| 8012 | ** symlink, a text value containing the text of the link. For a |
| 8013 | ** directory, NULL. |
| 8014 | ** |
| 8015 | ** If a non-NULL value is specified for the optional $dir parameter and |
| 8016 | ** $path is a relative path, then $path is interpreted relative to $dir. |
| 8017 | ** And the paths returned in the "name" column of the table are also |
| 8018 | ** relative to directory $dir. |
| @@ -8034,17 +7872,15 @@ | |
| 8034 | #if !defined(_WIN32) && !defined(WIN32) |
| 8035 | # include <unistd.h> |
| 8036 | # include <dirent.h> |
| 8037 | # include <utime.h> |
| 8038 | # include <sys/time.h> |
| 8039 | #else |
| 8040 | # include "windows.h" |
| 8041 | # include <io.h> |
| 8042 | # include <direct.h> |
| 8043 | /* # include "test_windirent.h" */ |
| 8044 | # define dirent DIRENT |
| 8045 | # define stat _stat |
| 8046 | # define chmod(path,mode) fileio_chmod(path,mode) |
| 8047 | # define mkdir(path,mode) fileio_mkdir(path) |
| 8048 | #endif |
| 8049 | #include <time.h> |
| 8050 | #include <errno.h> |
| @@ -8058,18 +7894,20 @@ | |
| 8058 | #endif |
| 8059 | |
| 8060 | /* |
| 8061 | ** Structure of the fsdir() table-valued function |
| 8062 | */ |
| 8063 | /* 0 1 2 3 4 5 */ |
| 8064 | #define FSDIR_SCHEMA "(name,mode,mtime,data,path HIDDEN,dir HIDDEN)" |
| 8065 | #define FSDIR_COLUMN_NAME 0 /* Name of the file */ |
| 8066 | #define FSDIR_COLUMN_MODE 1 /* Access mode */ |
| 8067 | #define FSDIR_COLUMN_MTIME 2 /* Last modification time */ |
| 8068 | #define FSDIR_COLUMN_DATA 3 /* File content */ |
| 8069 | #define FSDIR_COLUMN_PATH 4 /* Path to top of search */ |
| 8070 | #define FSDIR_COLUMN_DIR 5 /* Path is relative to this directory */ |
| 8071 | |
| 8072 | /* |
| 8073 | ** UTF8 chmod() function for Windows |
| 8074 | */ |
| 8075 | #if defined(_WIN32) || defined(WIN32) |
| @@ -8231,11 +8069,11 @@ | |
| 8231 | ** buffer to UTC. This is necessary on Win32, where the runtime library |
| 8232 | ** appears to return these values as local times. |
| 8233 | */ |
| 8234 | static void statTimesToUtc( |
| 8235 | const char *zPath, |
| 8236 | struct stat *pStatBuf |
| 8237 | ){ |
| 8238 | HANDLE hFindFile; |
| 8239 | WIN32_FIND_DATAW fd; |
| 8240 | LPWSTR zUnicodeName; |
| 8241 | extern LPWSTR sqlite3_win32_utf8_to_unicode(const char*); |
| @@ -8259,11 +8097,11 @@ | |
| 8259 | ** is required in order for the included time to be returned as UTC. On all |
| 8260 | ** other systems, this function simply calls stat(). |
| 8261 | */ |
| 8262 | static int fileStat( |
| 8263 | const char *zPath, |
| 8264 | struct stat *pStatBuf |
| 8265 | ){ |
| 8266 | #if defined(_WIN32) |
| 8267 | sqlite3_int64 sz = strlen(zPath); |
| 8268 | wchar_t *b1 = sqlite3_malloc64( (sz+1)*sizeof(b1[0]) ); |
| 8269 | int rc; |
| @@ -8283,11 +8121,11 @@ | |
| 8283 | ** is required in order for the included time to be returned as UTC. On all |
| 8284 | ** other systems, this function simply calls lstat(). |
| 8285 | */ |
| 8286 | static int fileLinkStat( |
| 8287 | const char *zPath, |
| 8288 | struct stat *pStatBuf |
| 8289 | ){ |
| 8290 | #if defined(_WIN32) |
| 8291 | return fileStat(zPath, pStatBuf); |
| 8292 | #else |
| 8293 | return lstat(zPath, pStatBuf); |
| @@ -8316,11 +8154,11 @@ | |
| 8316 | }else{ |
| 8317 | int nCopy = (int)strlen(zCopy); |
| 8318 | int i = 1; |
| 8319 | |
| 8320 | while( rc==SQLITE_OK ){ |
| 8321 | struct stat sStat; |
| 8322 | int rc2; |
| 8323 | |
| 8324 | for(; zCopy[i]!='/' && i<nCopy; i++); |
| 8325 | if( i==nCopy ) break; |
| 8326 | zCopy[i] = '\0'; |
| @@ -8366,11 +8204,11 @@ | |
| 8366 | if( mkdir(zFile, mode) ){ |
| 8367 | /* The mkdir() call to create the directory failed. This might not |
| 8368 | ** be an error though - if there is already a directory at the same |
| 8369 | ** path and either the permissions already match or can be changed |
| 8370 | ** to do so using chmod(), it is not an error. */ |
| 8371 | struct stat sStat; |
| 8372 | if( errno!=EEXIST |
| 8373 | || 0!=fileStat(zFile, &sStat) |
| 8374 | || !S_ISDIR(sStat.st_mode) |
| 8375 | || ((sStat.st_mode&0777)!=(mode&0777) && 0!=chmod(zFile, mode&0777)) |
| 8376 | ){ |
| @@ -8562,17 +8400,18 @@ | |
| 8562 | |
| 8563 | struct fsdir_cursor { |
| 8564 | sqlite3_vtab_cursor base; /* Base class - must be first */ |
| 8565 | |
| 8566 | int nLvl; /* Number of entries in aLvl[] array */ |
| 8567 | int iLvl; /* Index of current entry */ |
| 8568 | FsdirLevel *aLvl; /* Hierarchy of directories being traversed */ |
| 8569 | |
| 8570 | const char *zBase; |
| 8571 | int nBase; |
| 8572 | |
| 8573 | struct stat sStat; /* Current lstat() results */ |
| 8574 | char *zPath; /* Path to current entry */ |
| 8575 | sqlite3_int64 iRowid; /* Current rowid */ |
| 8576 | }; |
| 8577 | |
| 8578 | typedef struct fsdir_tab fsdir_tab; |
| @@ -8680,11 +8519,11 @@ | |
| 8680 | static int fsdirNext(sqlite3_vtab_cursor *cur){ |
| 8681 | fsdir_cursor *pCur = (fsdir_cursor*)cur; |
| 8682 | mode_t m = pCur->sStat.st_mode; |
| 8683 | |
| 8684 | pCur->iRowid++; |
| 8685 | if( S_ISDIR(m) ){ |
| 8686 | /* Descend into this directory */ |
| 8687 | int iNew = pCur->iLvl + 1; |
| 8688 | FsdirLevel *pLvl; |
| 8689 | if( iNew>=pCur->nLvl ){ |
| 8690 | int nNew = iNew+1; |
| @@ -8788,11 +8627,15 @@ | |
| 8788 | if( aBuf!=aStatic ) sqlite3_free(aBuf); |
| 8789 | #endif |
| 8790 | }else{ |
| 8791 | readFileContents(ctx, pCur->zPath); |
| 8792 | } |
| 8793 | } |
| 8794 | case FSDIR_COLUMN_PATH: |
| 8795 | default: { |
| 8796 | /* The FSDIR_COLUMN_PATH and FSDIR_COLUMN_DIR are input parameters. |
| 8797 | ** always return their values as NULL */ |
| 8798 | break; |
| @@ -8822,36 +8665,50 @@ | |
| 8822 | } |
| 8823 | |
| 8824 | /* |
| 8825 | ** xFilter callback. |
| 8826 | ** |
| 8827 | ** idxNum==1 PATH parameter only |
| 8828 | ** idxNum==2 Both PATH and DIR supplied |
| 8829 | */ |
| 8830 | static int fsdirFilter( |
| 8831 | sqlite3_vtab_cursor *cur, |
| 8832 | int idxNum, const char *idxStr, |
| 8833 | int argc, sqlite3_value **argv |
| 8834 | ){ |
| 8835 | const char *zDir = 0; |
| 8836 | fsdir_cursor *pCur = (fsdir_cursor*)cur; |
| 8837 | (void)idxStr; |
| 8838 | fsdirResetCursor(pCur); |
| 8839 | |
| 8840 | if( idxNum==0 ){ |
| 8841 | fsdirSetErrmsg(pCur, "table function fsdir requires an argument"); |
| 8842 | return SQLITE_ERROR; |
| 8843 | } |
| 8844 | |
| 8845 | assert( argc==idxNum && (argc==1 || argc==2) ); |
| 8846 | zDir = (const char*)sqlite3_value_text(argv[0]); |
| 8847 | if( zDir==0 ){ |
| 8848 | fsdirSetErrmsg(pCur, "table function fsdir requires a non-NULL argument"); |
| 8849 | return SQLITE_ERROR; |
| 8850 | } |
| 8851 | if( argc==2 ){ |
| 8852 | pCur->zBase = (const char*)sqlite3_value_text(argv[1]); |
| 8853 | } |
| 8854 | if( pCur->zBase ){ |
| 8855 | pCur->nBase = (int)strlen(pCur->zBase)+1; |
| 8856 | pCur->zPath = sqlite3_mprintf("%s/%s", pCur->zBase, zDir); |
| 8857 | }else{ |
| @@ -8876,48 +8733,75 @@ | |
| 8876 | ** plan. |
| 8877 | ** |
| 8878 | ** In this implementation idxNum is used to represent the |
| 8879 | ** query plan. idxStr is unused. |
| 8880 | ** |
| 8881 | ** The query plan is represented by values of idxNum: |
| 8882 | ** |
| 8883 | ** (1) The path value is supplied by argv[0] |
| 8884 | ** (2) Path is in argv[0] and dir is in argv[1] |
| 8885 | */ |
| 8886 | static int fsdirBestIndex( |
| 8887 | sqlite3_vtab *tab, |
| 8888 | sqlite3_index_info *pIdxInfo |
| 8889 | ){ |
| 8890 | int i; /* Loop over constraints */ |
| 8891 | int idxPath = -1; /* Index in pIdxInfo->aConstraint of PATH= */ |
| 8892 | int idxDir = -1; /* Index in pIdxInfo->aConstraint of DIR= */ |
| 8893 | int seenPath = 0; /* True if an unusable PATH= constraint is seen */ |
| 8894 | int seenDir = 0; /* True if an unusable DIR= constraint is seen */ |
| 8895 | const struct sqlite3_index_constraint *pConstraint; |
| 8896 | |
| 8897 | (void)tab; |
| 8898 | pConstraint = pIdxInfo->aConstraint; |
| 8899 | for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){ |
| 8900 | if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue; |
| 8901 | switch( pConstraint->iColumn ){ |
| 8902 | case FSDIR_COLUMN_PATH: { |
| 8903 | if( pConstraint->usable ){ |
| 8904 | idxPath = i; |
| 8905 | seenPath = 0; |
| 8906 | }else if( idxPath<0 ){ |
| 8907 | seenPath = 1; |
| 8908 | } |
| 8909 | break; |
| 8910 | } |
| 8911 | case FSDIR_COLUMN_DIR: { |
| 8912 | if( pConstraint->usable ){ |
| 8913 | idxDir = i; |
| 8914 | seenDir = 0; |
| 8915 | }else if( idxDir<0 ){ |
| 8916 | seenDir = 1; |
| 8917 | } |
| 8918 | break; |
| 8919 | } |
| 8920 | } |
| 8921 | } |
| 8922 | if( seenPath || seenDir ){ |
| 8923 | /* If input parameters are unusable, disallow this plan */ |
| @@ -8930,18 +8814,24 @@ | |
| 8930 | ** number. Leave it unchanged. */ |
| 8931 | pIdxInfo->estimatedRows = 0x7fffffff; |
| 8932 | }else{ |
| 8933 | pIdxInfo->aConstraintUsage[idxPath].omit = 1; |
| 8934 | pIdxInfo->aConstraintUsage[idxPath].argvIndex = 1; |
| 8935 | if( idxDir>=0 ){ |
| 8936 | pIdxInfo->aConstraintUsage[idxDir].omit = 1; |
| 8937 | pIdxInfo->aConstraintUsage[idxDir].argvIndex = 2; |
| 8938 | pIdxInfo->idxNum = 2; |
| 8939 | pIdxInfo->estimatedCost = 10.0; |
| 8940 | }else{ |
| 8941 | pIdxInfo->idxNum = 1; |
| 8942 | pIdxInfo->estimatedCost = 100.0; |
| 8943 | } |
| 8944 | } |
| 8945 | |
| 8946 | return SQLITE_OK; |
| 8947 | } |
| @@ -31828,11 +31718,11 @@ | |
| 31828 | const char *zUsage; /* Usage notes */ |
| 31829 | } aCtrl[] = { |
| 31830 | {"always", SQLITE_TESTCTRL_ALWAYS, 1, "BOOLEAN" }, |
| 31831 | {"assert", SQLITE_TESTCTRL_ASSERT, 1, "BOOLEAN" }, |
| 31832 | /*{"benign_malloc_hooks",SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS,1, "" },*/ |
| 31833 | /*{"bitvec_test", SQLITE_TESTCTRL_BITVEC_TEST, 1, "" },*/ |
| 31834 | {"byteorder", SQLITE_TESTCTRL_BYTEORDER, 0, "" }, |
| 31835 | {"extra_schema_checks",SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS,0,"BOOLEAN" }, |
| 31836 | {"fault_install", SQLITE_TESTCTRL_FAULT_INSTALL, 1,"args..." }, |
| 31837 | {"fk_no_action", SQLITE_TESTCTRL_FK_NO_ACTION, 0, "BOOLEAN" }, |
| 31838 | {"imposter", SQLITE_TESTCTRL_IMPOSTER,1,"SCHEMA ON/OFF ROOTPAGE"}, |
| @@ -32166,10 +32056,53 @@ | |
| 32166 | rc2 = booleanValue(azArg[2]); |
| 32167 | isOk = 3; |
| 32168 | } |
| 32169 | sqlite3_test_control(testctrl, &rc2); |
| 32170 | break; |
| 32171 | case SQLITE_TESTCTRL_FAULT_INSTALL: { |
| 32172 | int kk; |
| 32173 | int bShowHelp = nArg<=2; |
| 32174 | isOk = 3; |
| 32175 | for(kk=2; kk<nArg; kk++){ |
| 32176 |
| --- extsrc/shell.c | |
| +++ extsrc/shell.c | |
| @@ -1713,339 +1713,176 @@ | |
| 1713 | ** work here in the middle of this regular program. |
| 1714 | */ |
| 1715 | #define SQLITE_EXTENSION_INIT1 |
| 1716 | #define SQLITE_EXTENSION_INIT2(X) (void)(X) |
| 1717 | |
| 1718 | /************************* Begin ../ext/misc/windirent.h ******************/ |
| 1719 | /* |
| 1720 | ** 2025-06-05 |
| 1721 | ** |
| 1722 | ** The author disclaims copyright to this source code. In place of |
| 1723 | ** a legal notice, here is a blessing: |
| 1724 | ** |
| 1725 | ** May you do good and not evil. |
| 1726 | ** May you find forgiveness for yourself and forgive others. |
| 1727 | ** May you share freely, never taking more than you give. |
| 1728 | ** |
| 1729 | ************************************************************************* |
| 1730 | ** |
| 1731 | ** An implementation of opendir(), readdir(), and closedir() for Windows, |
| 1732 | ** based on the FindFirstFile(), FindNextFile(), and FindClose() APIs |
| 1733 | ** of Win32. |
| 1734 | ** |
| 1735 | ** #include this file inside any C-code module that needs to use |
| 1736 | ** opendir()/readdir()/closedir(). This file is a no-op on non-Windows |
| 1737 | ** machines. On Windows, static functions are defined that implement |
| 1738 | ** those standard interfaces. |
| 1739 | */ |
| 1740 | #if defined(_WIN32) && defined(_MSC_VER) && !defined(SQLITE_WINDIRENT_H) |
| 1741 | #define SQLITE_WINDIRENT_H |
| 1742 | |
| 1743 | #ifndef WIN32_LEAN_AND_MEAN |
| 1744 | #define WIN32_LEAN_AND_MEAN |
| 1745 | #endif |
| 1746 | #include <windows.h> |
| 1747 | #include <io.h> |
| 1748 | #include <stdio.h> |
| 1749 | #include <stdlib.h> |
| 1750 | #include <errno.h> |
| 1751 | #include <limits.h> |
| 1752 | #include <sys/types.h> |
| 1753 | #include <sys/stat.h> |
| 1754 | #include <string.h> |
| 1755 | #ifndef FILENAME_MAX |
| 1756 | # define FILENAME_MAX (260) |
| 1757 | #endif |
| 1758 | #ifndef S_ISREG |
| 1759 | #define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) |
| 1760 | #endif |
| 1761 | #ifndef S_ISDIR |
| 1762 | #define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) |
| 1763 | #endif |
| 1764 | #ifndef S_ISLNK |
| 1765 | #define S_ISLNK(m) (0) |
| 1766 | #endif |
| 1767 | typedef unsigned short mode_t; |
| 1768 | |
| 1769 | /* The dirent object for Windows is abbreviated. The only field really |
| 1770 | ** usable by applications is d_name[]. |
| 1771 | */ |
| 1772 | struct dirent { |
| 1773 | int d_ino; /* Inode number (synthesized) */ |
| 1774 | unsigned d_attributes; /* File attributes */ |
| 1775 | char d_name[FILENAME_MAX]; /* Null-terminated filename */ |
| 1776 | }; |
| 1777 | |
| 1778 | /* The internals of DIR are opaque according to standards. So it |
| 1779 | ** does not matter what we put here. */ |
| 1780 | typedef struct DIR DIR; |
| 1781 | struct DIR { |
| 1782 | intptr_t d_handle; /* Handle for findfirst()/findnext() */ |
| 1783 | struct dirent cur; /* Current entry */ |
| 1784 | }; |
| 1785 | |
| 1786 | /* Ignore hidden and system files */ |
| 1787 | #define WindowsFileToIgnore(a) \ |
| 1788 | ((((a).attrib)&_A_HIDDEN) || (((a).attrib)&_A_SYSTEM)) |
| 1789 | |
| 1790 | /* |
| 1791 | ** Close a previously opened directory |
| 1792 | */ |
| 1793 | static int closedir(DIR *pDir){ |
| 1794 | int rc = 0; |
| 1795 | if( pDir==0 ){ |
| 1796 | return EINVAL; |
| 1797 | } |
| 1798 | if( pDir->d_handle!=0 && pDir->d_handle!=(-1) ){ |
| 1799 | rc = _findclose(pDir->d_handle); |
| 1800 | } |
| 1801 | sqlite3_free(pDir); |
| 1802 | return rc; |
| 1803 | } |
| 1804 | |
| 1805 | /* |
| 1806 | ** Open a new directory. The directory name should be UTF-8 encoded. |
| 1807 | ** appropriate translations happen automatically. |
| 1808 | */ |
| 1809 | static DIR *opendir(const char *zDirName){ |
| 1810 | DIR *pDir; |
| 1811 | wchar_t *b1; |
| 1812 | sqlite3_int64 sz; |
| 1813 | struct _wfinddata_t data; |
| 1814 | |
| 1815 | pDir = sqlite3_malloc64( sizeof(DIR) ); |
| 1816 | if( pDir==0 ) return 0; |
| 1817 | memset(pDir, 0, sizeof(DIR)); |
| 1818 | memset(&data, 0, sizeof(data)); |
| 1819 | sz = strlen(zDirName); |
| 1820 | b1 = sqlite3_malloc64( (sz+3)*sizeof(b1[0]) ); |
| 1821 | if( b1==0 ){ |
| 1822 | closedir(pDir); |
| 1823 | return NULL; |
| 1824 | } |
| 1825 | sz = MultiByteToWideChar(CP_UTF8, 0, zDirName, sz, b1, sz); |
| 1826 | b1[sz++] = '\\'; |
| 1827 | b1[sz++] = '*'; |
| 1828 | b1[sz] = 0; |
| 1829 | if( sz+1>sizeof(data.name)/sizeof(data.name[0]) ){ |
| 1830 | closedir(pDir); |
| 1831 | sqlite3_free(b1); |
| 1832 | return NULL; |
| 1833 | } |
| 1834 | memcpy(data.name, b1, (sz+1)*sizeof(b1[0])); |
| 1835 | sqlite3_free(b1); |
| 1836 | pDir->d_handle = _wfindfirst(data.name, &data); |
| 1837 | if( pDir->d_handle<0 ){ |
| 1838 | closedir(pDir); |
| 1839 | return NULL; |
| 1840 | } |
| 1841 | while( WindowsFileToIgnore(data) ){ |
| 1842 | memset(&data, 0, sizeof(data)); |
| 1843 | if( _wfindnext(pDir->d_handle, &data)==-1 ){ |
| 1844 | closedir(pDir); |
| 1845 | return NULL; |
| 1846 | } |
| 1847 | } |
| 1848 | pDir->cur.d_ino = 0; |
| 1849 | pDir->cur.d_attributes = data.attrib; |
| 1850 | WideCharToMultiByte(CP_UTF8, 0, data.name, -1, |
| 1851 | pDir->cur.d_name, FILENAME_MAX, 0, 0); |
| 1852 | return pDir; |
| 1853 | } |
| 1854 | |
| 1855 | /* |
| 1856 | ** Read the next entry from a directory. |
| 1857 | ** |
| 1858 | ** The returned struct-dirent object is managed by DIR. It is only |
| 1859 | ** valid until the next readdir() or closedir() call. Only the |
| 1860 | ** d_name[] field is meaningful. The d_name[] value has been |
| 1861 | ** translated into UTF8. |
| 1862 | */ |
| 1863 | static struct dirent *readdir(DIR *pDir){ |
| 1864 | struct _wfinddata_t data; |
| 1865 | if( pDir==0 ) return 0; |
| 1866 | if( (pDir->cur.d_ino++)==0 ){ |
| 1867 | return &pDir->cur; |
| 1868 | } |
| 1869 | do{ |
| 1870 | memset(&data, 0, sizeof(data)); |
| 1871 | if( _wfindnext(pDir->d_handle, &data)==-1 ){ |
| 1872 | return NULL; |
| 1873 | } |
| 1874 | }while( WindowsFileToIgnore(data) ); |
| 1875 | pDir->cur.d_attributes = data.attrib; |
| 1876 | WideCharToMultiByte(CP_UTF8, 0, data.name, -1, |
| 1877 | pDir->cur.d_name, FILENAME_MAX, 0, 0); |
| 1878 | return &pDir->cur; |
| 1879 | } |
| 1880 | |
| 1881 | #endif /* defined(_WIN32) && defined(_MSC_VER) */ |
| 1882 | |
| 1883 | /************************* End ../ext/misc/windirent.h ********************/ |
| 1884 | /************************* Begin ../ext/misc/memtrace.c ******************/ |
| 1885 | /* |
| 1886 | ** 2019-01-21 |
| 1887 | ** |
| 1888 | ** The author disclaims copyright to this source code. In place of |
| @@ -8009,10 +7846,11 @@ | |
| 7846 | ** mode: Value of stat.st_mode for directory entry (an integer). |
| 7847 | ** mtime: Value of stat.st_mtime for directory entry (an integer). |
| 7848 | ** data: For a regular file, a blob containing the file data. For a |
| 7849 | ** symlink, a text value containing the text of the link. For a |
| 7850 | ** directory, NULL. |
| 7851 | ** level: Directory hierarchy level. Topmost is 1. |
| 7852 | ** |
| 7853 | ** If a non-NULL value is specified for the optional $dir parameter and |
| 7854 | ** $path is a relative path, then $path is interpreted relative to $dir. |
| 7855 | ** And the paths returned in the "name" column of the table are also |
| 7856 | ** relative to directory $dir. |
| @@ -8034,17 +7872,15 @@ | |
| 7872 | #if !defined(_WIN32) && !defined(WIN32) |
| 7873 | # include <unistd.h> |
| 7874 | # include <dirent.h> |
| 7875 | # include <utime.h> |
| 7876 | # include <sys/time.h> |
| 7877 | # define STRUCT_STAT struct stat |
| 7878 | #else |
| 7879 | /* # include "windirent.h" */ |
| 7880 | # include <direct.h> |
| 7881 | # define STRUCT_STAT struct _stat |
| 7882 | # define chmod(path,mode) fileio_chmod(path,mode) |
| 7883 | # define mkdir(path,mode) fileio_mkdir(path) |
| 7884 | #endif |
| 7885 | #include <time.h> |
| 7886 | #include <errno.h> |
| @@ -8058,18 +7894,20 @@ | |
| 7894 | #endif |
| 7895 | |
| 7896 | /* |
| 7897 | ** Structure of the fsdir() table-valued function |
| 7898 | */ |
| 7899 | /* 0 1 2 3 4 5 6 */ |
| 7900 | #define FSDIR_SCHEMA "(name,mode,mtime,data,level,path HIDDEN,dir HIDDEN)" |
| 7901 | |
| 7902 | #define FSDIR_COLUMN_NAME 0 /* Name of the file */ |
| 7903 | #define FSDIR_COLUMN_MODE 1 /* Access mode */ |
| 7904 | #define FSDIR_COLUMN_MTIME 2 /* Last modification time */ |
| 7905 | #define FSDIR_COLUMN_DATA 3 /* File content */ |
| 7906 | #define FSDIR_COLUMN_LEVEL 4 /* Level. Topmost is 1 */ |
| 7907 | #define FSDIR_COLUMN_PATH 5 /* Path to top of search */ |
| 7908 | #define FSDIR_COLUMN_DIR 6 /* Path is relative to this directory */ |
| 7909 | |
| 7910 | /* |
| 7911 | ** UTF8 chmod() function for Windows |
| 7912 | */ |
| 7913 | #if defined(_WIN32) || defined(WIN32) |
| @@ -8231,11 +8069,11 @@ | |
| 8069 | ** buffer to UTC. This is necessary on Win32, where the runtime library |
| 8070 | ** appears to return these values as local times. |
| 8071 | */ |
| 8072 | static void statTimesToUtc( |
| 8073 | const char *zPath, |
| 8074 | STRUCT_STAT *pStatBuf |
| 8075 | ){ |
| 8076 | HANDLE hFindFile; |
| 8077 | WIN32_FIND_DATAW fd; |
| 8078 | LPWSTR zUnicodeName; |
| 8079 | extern LPWSTR sqlite3_win32_utf8_to_unicode(const char*); |
| @@ -8259,11 +8097,11 @@ | |
| 8097 | ** is required in order for the included time to be returned as UTC. On all |
| 8098 | ** other systems, this function simply calls stat(). |
| 8099 | */ |
| 8100 | static int fileStat( |
| 8101 | const char *zPath, |
| 8102 | STRUCT_STAT *pStatBuf |
| 8103 | ){ |
| 8104 | #if defined(_WIN32) |
| 8105 | sqlite3_int64 sz = strlen(zPath); |
| 8106 | wchar_t *b1 = sqlite3_malloc64( (sz+1)*sizeof(b1[0]) ); |
| 8107 | int rc; |
| @@ -8283,11 +8121,11 @@ | |
| 8121 | ** is required in order for the included time to be returned as UTC. On all |
| 8122 | ** other systems, this function simply calls lstat(). |
| 8123 | */ |
| 8124 | static int fileLinkStat( |
| 8125 | const char *zPath, |
| 8126 | STRUCT_STAT *pStatBuf |
| 8127 | ){ |
| 8128 | #if defined(_WIN32) |
| 8129 | return fileStat(zPath, pStatBuf); |
| 8130 | #else |
| 8131 | return lstat(zPath, pStatBuf); |
| @@ -8316,11 +8154,11 @@ | |
| 8154 | }else{ |
| 8155 | int nCopy = (int)strlen(zCopy); |
| 8156 | int i = 1; |
| 8157 | |
| 8158 | while( rc==SQLITE_OK ){ |
| 8159 | STRUCT_STAT sStat; |
| 8160 | int rc2; |
| 8161 | |
| 8162 | for(; zCopy[i]!='/' && i<nCopy; i++); |
| 8163 | if( i==nCopy ) break; |
| 8164 | zCopy[i] = '\0'; |
| @@ -8366,11 +8204,11 @@ | |
| 8204 | if( mkdir(zFile, mode) ){ |
| 8205 | /* The mkdir() call to create the directory failed. This might not |
| 8206 | ** be an error though - if there is already a directory at the same |
| 8207 | ** path and either the permissions already match or can be changed |
| 8208 | ** to do so using chmod(), it is not an error. */ |
| 8209 | STRUCT_STAT sStat; |
| 8210 | if( errno!=EEXIST |
| 8211 | || 0!=fileStat(zFile, &sStat) |
| 8212 | || !S_ISDIR(sStat.st_mode) |
| 8213 | || ((sStat.st_mode&0777)!=(mode&0777) && 0!=chmod(zFile, mode&0777)) |
| 8214 | ){ |
| @@ -8562,17 +8400,18 @@ | |
| 8400 | |
| 8401 | struct fsdir_cursor { |
| 8402 | sqlite3_vtab_cursor base; /* Base class - must be first */ |
| 8403 | |
| 8404 | int nLvl; /* Number of entries in aLvl[] array */ |
| 8405 | int mxLvl; /* Maximum level */ |
| 8406 | int iLvl; /* Index of current entry */ |
| 8407 | FsdirLevel *aLvl; /* Hierarchy of directories being traversed */ |
| 8408 | |
| 8409 | const char *zBase; |
| 8410 | int nBase; |
| 8411 | |
| 8412 | STRUCT_STAT sStat; /* Current lstat() results */ |
| 8413 | char *zPath; /* Path to current entry */ |
| 8414 | sqlite3_int64 iRowid; /* Current rowid */ |
| 8415 | }; |
| 8416 | |
| 8417 | typedef struct fsdir_tab fsdir_tab; |
| @@ -8680,11 +8519,11 @@ | |
| 8519 | static int fsdirNext(sqlite3_vtab_cursor *cur){ |
| 8520 | fsdir_cursor *pCur = (fsdir_cursor*)cur; |
| 8521 | mode_t m = pCur->sStat.st_mode; |
| 8522 | |
| 8523 | pCur->iRowid++; |
| 8524 | if( S_ISDIR(m) && pCur->iLvl+3<pCur->mxLvl ){ |
| 8525 | /* Descend into this directory */ |
| 8526 | int iNew = pCur->iLvl + 1; |
| 8527 | FsdirLevel *pLvl; |
| 8528 | if( iNew>=pCur->nLvl ){ |
| 8529 | int nNew = iNew+1; |
| @@ -8788,11 +8627,15 @@ | |
| 8627 | if( aBuf!=aStatic ) sqlite3_free(aBuf); |
| 8628 | #endif |
| 8629 | }else{ |
| 8630 | readFileContents(ctx, pCur->zPath); |
| 8631 | } |
| 8632 | break; |
| 8633 | } |
| 8634 | case FSDIR_COLUMN_LEVEL: |
| 8635 | sqlite3_result_int(ctx, pCur->iLvl+2); |
| 8636 | break; |
| 8637 | case FSDIR_COLUMN_PATH: |
| 8638 | default: { |
| 8639 | /* The FSDIR_COLUMN_PATH and FSDIR_COLUMN_DIR are input parameters. |
| 8640 | ** always return their values as NULL */ |
| 8641 | break; |
| @@ -8822,36 +8665,50 @@ | |
| 8665 | } |
| 8666 | |
| 8667 | /* |
| 8668 | ** xFilter callback. |
| 8669 | ** |
| 8670 | ** idxNum bit Meaning |
| 8671 | ** 0x01 PATH=N |
| 8672 | ** 0x02 DIR=N |
| 8673 | ** 0x04 LEVEL<N |
| 8674 | ** 0x08 LEVEL<=N |
| 8675 | */ |
| 8676 | static int fsdirFilter( |
| 8677 | sqlite3_vtab_cursor *cur, |
| 8678 | int idxNum, const char *idxStr, |
| 8679 | int argc, sqlite3_value **argv |
| 8680 | ){ |
| 8681 | const char *zDir = 0; |
| 8682 | fsdir_cursor *pCur = (fsdir_cursor*)cur; |
| 8683 | int i; |
| 8684 | (void)idxStr; |
| 8685 | fsdirResetCursor(pCur); |
| 8686 | |
| 8687 | if( idxNum==0 ){ |
| 8688 | fsdirSetErrmsg(pCur, "table function fsdir requires an argument"); |
| 8689 | return SQLITE_ERROR; |
| 8690 | } |
| 8691 | |
| 8692 | assert( (idxNum & 0x01)!=0 && argc>0 ); |
| 8693 | zDir = (const char*)sqlite3_value_text(argv[0]); |
| 8694 | if( zDir==0 ){ |
| 8695 | fsdirSetErrmsg(pCur, "table function fsdir requires a non-NULL argument"); |
| 8696 | return SQLITE_ERROR; |
| 8697 | } |
| 8698 | i = 1; |
| 8699 | if( (idxNum & 0x02)!=0 ){ |
| 8700 | assert( argc>i ); |
| 8701 | pCur->zBase = (const char*)sqlite3_value_text(argv[i++]); |
| 8702 | } |
| 8703 | if( (idxNum & 0x0c)!=0 ){ |
| 8704 | assert( argc>i ); |
| 8705 | pCur->mxLvl = sqlite3_value_int(argv[i++]); |
| 8706 | if( idxNum & 0x08 ) pCur->mxLvl++; |
| 8707 | if( pCur->mxLvl<=0 ) pCur->mxLvl = 1000000000; |
| 8708 | }else{ |
| 8709 | pCur->mxLvl = 1000000000; |
| 8710 | } |
| 8711 | if( pCur->zBase ){ |
| 8712 | pCur->nBase = (int)strlen(pCur->zBase)+1; |
| 8713 | pCur->zPath = sqlite3_mprintf("%s/%s", pCur->zBase, zDir); |
| 8714 | }else{ |
| @@ -8876,48 +8733,75 @@ | |
| 8733 | ** plan. |
| 8734 | ** |
| 8735 | ** In this implementation idxNum is used to represent the |
| 8736 | ** query plan. idxStr is unused. |
| 8737 | ** |
| 8738 | ** The query plan is represented by bits in idxNum: |
| 8739 | ** |
| 8740 | ** 0x01 The path value is supplied by argv[0] |
| 8741 | ** 0x02 dir is in argv[1] |
| 8742 | ** 0x04 maxdepth is in argv[1] or [2] |
| 8743 | */ |
| 8744 | static int fsdirBestIndex( |
| 8745 | sqlite3_vtab *tab, |
| 8746 | sqlite3_index_info *pIdxInfo |
| 8747 | ){ |
| 8748 | int i; /* Loop over constraints */ |
| 8749 | int idxPath = -1; /* Index in pIdxInfo->aConstraint of PATH= */ |
| 8750 | int idxDir = -1; /* Index in pIdxInfo->aConstraint of DIR= */ |
| 8751 | int idxLevel = -1; /* Index in pIdxInfo->aConstraint of LEVEL< or <= */ |
| 8752 | int idxLevelEQ = 0; /* 0x08 for LEVEL<= or LEVEL=. 0x04 for LEVEL< */ |
| 8753 | int omitLevel = 0; /* omit the LEVEL constraint */ |
| 8754 | int seenPath = 0; /* True if an unusable PATH= constraint is seen */ |
| 8755 | int seenDir = 0; /* True if an unusable DIR= constraint is seen */ |
| 8756 | const struct sqlite3_index_constraint *pConstraint; |
| 8757 | |
| 8758 | (void)tab; |
| 8759 | pConstraint = pIdxInfo->aConstraint; |
| 8760 | for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){ |
| 8761 | if( pConstraint->op==SQLITE_INDEX_CONSTRAINT_EQ ){ |
| 8762 | switch( pConstraint->iColumn ){ |
| 8763 | case FSDIR_COLUMN_PATH: { |
| 8764 | if( pConstraint->usable ){ |
| 8765 | idxPath = i; |
| 8766 | seenPath = 0; |
| 8767 | }else if( idxPath<0 ){ |
| 8768 | seenPath = 1; |
| 8769 | } |
| 8770 | break; |
| 8771 | } |
| 8772 | case FSDIR_COLUMN_DIR: { |
| 8773 | if( pConstraint->usable ){ |
| 8774 | idxDir = i; |
| 8775 | seenDir = 0; |
| 8776 | }else if( idxDir<0 ){ |
| 8777 | seenDir = 1; |
| 8778 | } |
| 8779 | break; |
| 8780 | } |
| 8781 | case FSDIR_COLUMN_LEVEL: { |
| 8782 | if( pConstraint->usable && idxLevel<0 ){ |
| 8783 | idxLevel = i; |
| 8784 | idxLevelEQ = 0x08; |
| 8785 | omitLevel = 0; |
| 8786 | } |
| 8787 | break; |
| 8788 | } |
| 8789 | } |
| 8790 | }else |
| 8791 | if( pConstraint->iColumn==FSDIR_COLUMN_LEVEL |
| 8792 | && pConstraint->usable |
| 8793 | && idxLevel<0 |
| 8794 | ){ |
| 8795 | if( pConstraint->op==SQLITE_INDEX_CONSTRAINT_LE ){ |
| 8796 | idxLevel = i; |
| 8797 | idxLevelEQ = 0x08; |
| 8798 | omitLevel = 1; |
| 8799 | }else if( pConstraint->op==SQLITE_INDEX_CONSTRAINT_LT ){ |
| 8800 | idxLevel = i; |
| 8801 | idxLevelEQ = 0x04; |
| 8802 | omitLevel = 1; |
| 8803 | } |
| 8804 | } |
| 8805 | } |
| 8806 | if( seenPath || seenDir ){ |
| 8807 | /* If input parameters are unusable, disallow this plan */ |
| @@ -8930,18 +8814,24 @@ | |
| 8814 | ** number. Leave it unchanged. */ |
| 8815 | pIdxInfo->estimatedRows = 0x7fffffff; |
| 8816 | }else{ |
| 8817 | pIdxInfo->aConstraintUsage[idxPath].omit = 1; |
| 8818 | pIdxInfo->aConstraintUsage[idxPath].argvIndex = 1; |
| 8819 | pIdxInfo->idxNum = 0x01; |
| 8820 | pIdxInfo->estimatedCost = 1.0e9; |
| 8821 | i = 2; |
| 8822 | if( idxDir>=0 ){ |
| 8823 | pIdxInfo->aConstraintUsage[idxDir].omit = 1; |
| 8824 | pIdxInfo->aConstraintUsage[idxDir].argvIndex = i++; |
| 8825 | pIdxInfo->idxNum |= 0x02; |
| 8826 | pIdxInfo->estimatedCost /= 1.0e4; |
| 8827 | } |
| 8828 | if( idxLevel>=0 ){ |
| 8829 | pIdxInfo->aConstraintUsage[idxLevel].omit = omitLevel; |
| 8830 | pIdxInfo->aConstraintUsage[idxLevel].argvIndex = i++; |
| 8831 | pIdxInfo->idxNum |= idxLevelEQ; |
| 8832 | pIdxInfo->estimatedCost /= 1.0e4; |
| 8833 | } |
| 8834 | } |
| 8835 | |
| 8836 | return SQLITE_OK; |
| 8837 | } |
| @@ -31828,11 +31718,11 @@ | |
| 31718 | const char *zUsage; /* Usage notes */ |
| 31719 | } aCtrl[] = { |
| 31720 | {"always", SQLITE_TESTCTRL_ALWAYS, 1, "BOOLEAN" }, |
| 31721 | {"assert", SQLITE_TESTCTRL_ASSERT, 1, "BOOLEAN" }, |
| 31722 | /*{"benign_malloc_hooks",SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS,1, "" },*/ |
| 31723 | {"bitvec_test", SQLITE_TESTCTRL_BITVEC_TEST, 1, "SIZE INT-ARRAY"}, |
| 31724 | {"byteorder", SQLITE_TESTCTRL_BYTEORDER, 0, "" }, |
| 31725 | {"extra_schema_checks",SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS,0,"BOOLEAN" }, |
| 31726 | {"fault_install", SQLITE_TESTCTRL_FAULT_INSTALL, 1,"args..." }, |
| 31727 | {"fk_no_action", SQLITE_TESTCTRL_FK_NO_ACTION, 0, "BOOLEAN" }, |
| 31728 | {"imposter", SQLITE_TESTCTRL_IMPOSTER,1,"SCHEMA ON/OFF ROOTPAGE"}, |
| @@ -32166,10 +32056,53 @@ | |
| 32056 | rc2 = booleanValue(azArg[2]); |
| 32057 | isOk = 3; |
| 32058 | } |
| 32059 | sqlite3_test_control(testctrl, &rc2); |
| 32060 | break; |
| 32061 | case SQLITE_TESTCTRL_BITVEC_TEST: { |
| 32062 | /* Examples: |
| 32063 | ** .testctrl bitvec_test 100 6,1 -- Show BITVEC constants |
| 32064 | ** .testctrl bitvec_test 1000 1,12,7,3 -- Simple test |
| 32065 | ** ---- -------- |
| 32066 | ** size of Bitvec -----^ ^--- aOp array. 0 added at end. |
| 32067 | ** |
| 32068 | ** See comments on sqlite3BitvecBuiltinTest() for more information |
| 32069 | ** about the aOp[] array. |
| 32070 | */ |
| 32071 | int iSize; |
| 32072 | const char *zTestArg; |
| 32073 | int nOp; |
| 32074 | int ii, jj, x; |
| 32075 | int *aOp; |
| 32076 | if( nArg!=4 ){ |
| 32077 | sqlite3_fprintf(stderr, |
| 32078 | "ERROR - should be: \".testctrl bitvec_test SIZE INT-ARRAY\"\n" |
| 32079 | ); |
| 32080 | rc = 1; |
| 32081 | goto meta_command_exit; |
| 32082 | } |
| 32083 | isOk = 3; |
| 32084 | iSize = (int)integerValue(azArg[2]); |
| 32085 | zTestArg = azArg[3]; |
| 32086 | nOp = (int)strlen(zTestArg)+1; |
| 32087 | aOp = malloc( sizeof(int)*(nOp+1) ); |
| 32088 | shell_check_oom(aOp); |
| 32089 | memset(aOp, 0, sizeof(int)*(nOp+1) ); |
| 32090 | for(ii = jj = x = 0; zTestArg[ii]!=0; ii++){ |
| 32091 | if( IsDigit(zTestArg[ii]) ){ |
| 32092 | x = x*10 + zTestArg[ii] - '0'; |
| 32093 | }else{ |
| 32094 | aOp[jj++] = x; |
| 32095 | x = 0; |
| 32096 | } |
| 32097 | } |
| 32098 | aOp[jj] = x; |
| 32099 | x = sqlite3_test_control(testctrl, iSize, aOp); |
| 32100 | sqlite3_fprintf(p->out, "result: %d\n", x); |
| 32101 | free(aOp); |
| 32102 | break; |
| 32103 | } |
| 32104 | case SQLITE_TESTCTRL_FAULT_INSTALL: { |
| 32105 | int kk; |
| 32106 | int bShowHelp = nArg<=2; |
| 32107 | isOk = 3; |
| 32108 | for(kk=2; kk<nArg; kk++){ |
| 32109 |
+265
-104
| --- extsrc/sqlite3.c | ||
| +++ extsrc/sqlite3.c | ||
| @@ -16,11 +16,11 @@ | ||
| 16 | 16 | ** if you want a wrapper to interface SQLite with your choice of programming |
| 17 | 17 | ** language. The code for the "sqlite3" command-line shell is also in a |
| 18 | 18 | ** separate file. This file contains only code for the core SQLite library. |
| 19 | 19 | ** |
| 20 | 20 | ** The content in this amalgamation comes from Fossil check-in |
| 21 | -** ea1754f7d8a770477a1b19b606b27724fdc0 with changes in files: | |
| 21 | +** a88bb75288a06492a04ab1278e8a2101a74f with changes in files: | |
| 22 | 22 | ** |
| 23 | 23 | ** |
| 24 | 24 | */ |
| 25 | 25 | #ifndef SQLITE_AMALGAMATION |
| 26 | 26 | #define SQLITE_CORE 1 |
| @@ -465,11 +465,11 @@ | ||
| 465 | 465 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 466 | 466 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 467 | 467 | */ |
| 468 | 468 | #define SQLITE_VERSION "3.51.0" |
| 469 | 469 | #define SQLITE_VERSION_NUMBER 3051000 |
| 470 | -#define SQLITE_SOURCE_ID "2025-06-03 10:49:51 ea1754f7d8a770477a1b19b606b27724fdc0b733e51fef32c1ef834f972c3cc5" | |
| 470 | +#define SQLITE_SOURCE_ID "2025-06-19 20:19:12 a88bb75288a06492a04ab1278e8a2101a74f4ba712d328b4c73e86ac01cb946d" | |
| 471 | 471 | |
| 472 | 472 | /* |
| 473 | 473 | ** CAPI3REF: Run-Time Library Version Numbers |
| 474 | 474 | ** KEYWORDS: sqlite3_version sqlite3_sourceid |
| 475 | 475 | ** |
| @@ -4396,11 +4396,11 @@ | ||
| 4396 | 4396 | ** These interfaces are provided for use by [VFS shim] implementations and |
| 4397 | 4397 | ** are not useful outside of that context. |
| 4398 | 4398 | ** |
| 4399 | 4399 | ** The sqlite3_create_filename(D,J,W,N,P) allocates memory to hold a version of |
| 4400 | 4400 | ** database filename D with corresponding journal file J and WAL file W and |
| 4401 | -** with N URI parameters key/values pairs in the array P. The result from | |
| 4401 | +** an array P of N URI Key/Value pairs. The result from | |
| 4402 | 4402 | ** sqlite3_create_filename(D,J,W,N,P) is a pointer to a database filename that |
| 4403 | 4403 | ** is safe to pass to routines like: |
| 4404 | 4404 | ** <ul> |
| 4405 | 4405 | ** <li> [sqlite3_uri_parameter()], |
| 4406 | 4406 | ** <li> [sqlite3_uri_boolean()], |
| @@ -5077,11 +5077,11 @@ | ||
| 5077 | 5077 | ** KEYWORDS: {host parameter} {host parameters} {host parameter name} |
| 5078 | 5078 | ** KEYWORDS: {SQL parameter} {SQL parameters} {parameter binding} |
| 5079 | 5079 | ** METHOD: sqlite3_stmt |
| 5080 | 5080 | ** |
| 5081 | 5081 | ** ^(In the SQL statement text input to [sqlite3_prepare_v2()] and its variants, |
| 5082 | -** literals may be replaced by a [parameter] that matches one of following | |
| 5082 | +** literals may be replaced by a [parameter] that matches one of the following | |
| 5083 | 5083 | ** templates: |
| 5084 | 5084 | ** |
| 5085 | 5085 | ** <ul> |
| 5086 | 5086 | ** <li> ? |
| 5087 | 5087 | ** <li> ?NNN |
| @@ -5122,11 +5122,11 @@ | ||
| 5122 | 5122 | ** either UTF8 if the sixth parameter is SQLITE_UTF8, or UTF16 |
| 5123 | 5123 | ** otherwise. |
| 5124 | 5124 | ** |
| 5125 | 5125 | ** [[byte-order determination rules]] ^The byte-order of |
| 5126 | 5126 | ** UTF16 input text is determined by the byte-order mark (BOM, U+FEFF) |
| 5127 | -** found in first character, which is removed, or in the absence of a BOM | |
| 5127 | +** found in the first character, which is removed, or in the absence of a BOM | |
| 5128 | 5128 | ** the byte order is the native byte order of the host |
| 5129 | 5129 | ** machine for sqlite3_bind_text16() or the byte order specified in |
| 5130 | 5130 | ** the 6th parameter for sqlite3_bind_text64().)^ |
| 5131 | 5131 | ** ^If UTF16 input text contains invalid unicode |
| 5132 | 5132 | ** characters, then SQLite might change those invalid characters |
| @@ -5142,11 +5142,11 @@ | ||
| 5142 | 5142 | ** the behavior is undefined. |
| 5143 | 5143 | ** If a non-negative fourth parameter is provided to sqlite3_bind_text() |
| 5144 | 5144 | ** or sqlite3_bind_text16() or sqlite3_bind_text64() then |
| 5145 | 5145 | ** that parameter must be the byte offset |
| 5146 | 5146 | ** where the NUL terminator would occur assuming the string were NUL |
| 5147 | -** terminated. If any NUL characters occurs at byte offsets less than | |
| 5147 | +** terminated. If any NUL characters occur at byte offsets less than | |
| 5148 | 5148 | ** the value of the fourth parameter then the resulting string value will |
| 5149 | 5149 | ** contain embedded NULs. The result of expressions involving strings |
| 5150 | 5150 | ** with embedded NULs is undefined. |
| 5151 | 5151 | ** |
| 5152 | 5152 | ** ^The fifth argument to the BLOB and string binding interfaces controls |
| @@ -5354,11 +5354,11 @@ | ||
| 5354 | 5354 | /* |
| 5355 | 5355 | ** CAPI3REF: Source Of Data In A Query Result |
| 5356 | 5356 | ** METHOD: sqlite3_stmt |
| 5357 | 5357 | ** |
| 5358 | 5358 | ** ^These routines provide a means to determine the database, table, and |
| 5359 | -** table column that is the origin of a particular result column in | |
| 5359 | +** table column that is the origin of a particular result column in a | |
| 5360 | 5360 | ** [SELECT] statement. |
| 5361 | 5361 | ** ^The name of the database or table or column can be returned as |
| 5362 | 5362 | ** either a UTF-8 or UTF-16 string. ^The _database_ routines return |
| 5363 | 5363 | ** the database name, the _table_ routines return the table name, and |
| 5364 | 5364 | ** the origin_ routines return the column name. |
| @@ -5923,12 +5923,12 @@ | ||
| 5923 | 5923 | ** within VIEWs, TRIGGERs, CHECK constraints, generated column expressions, |
| 5924 | 5924 | ** index expressions, or the WHERE clause of partial indexes. |
| 5925 | 5925 | ** |
| 5926 | 5926 | ** For best security, the [SQLITE_DIRECTONLY] flag is recommended for |
| 5927 | 5927 | ** all application-defined SQL functions that do not need to be |
| 5928 | -** used inside of triggers, view, CHECK constraints, or other elements of | |
| 5929 | -** the database schema. This flags is especially recommended for SQL | |
| 5928 | +** used inside of triggers, views, CHECK constraints, or other elements of | |
| 5929 | +** the database schema. This flag is especially recommended for SQL | |
| 5930 | 5930 | ** functions that have side effects or reveal internal application state. |
| 5931 | 5931 | ** Without this flag, an attacker might be able to modify the schema of |
| 5932 | 5932 | ** a database file to include invocations of the function with parameters |
| 5933 | 5933 | ** chosen by the attacker, which the application will then execute when |
| 5934 | 5934 | ** the database file is opened and read. |
| @@ -5955,11 +5955,11 @@ | ||
| 5955 | 5955 | ** or aggregate window function. More details regarding the implementation |
| 5956 | 5956 | ** of aggregate window functions are |
| 5957 | 5957 | ** [user-defined window functions|available here]. |
| 5958 | 5958 | ** |
| 5959 | 5959 | ** ^(If the final parameter to sqlite3_create_function_v2() or |
| 5960 | -** sqlite3_create_window_function() is not NULL, then it is destructor for | |
| 5960 | +** sqlite3_create_window_function() is not NULL, then it is the destructor for | |
| 5961 | 5961 | ** the application data pointer. The destructor is invoked when the function |
| 5962 | 5962 | ** is deleted, either by being overloaded or when the database connection |
| 5963 | 5963 | ** closes.)^ ^The destructor is also invoked if the call to |
| 5964 | 5964 | ** sqlite3_create_function_v2() fails. ^When the destructor callback is |
| 5965 | 5965 | ** invoked, it is passed a single argument which is a copy of the application |
| @@ -7763,11 +7763,11 @@ | ||
| 7763 | 7763 | ** that is to be automatically loaded into all new database connections. |
| 7764 | 7764 | ** |
| 7765 | 7765 | ** ^(Even though the function prototype shows that xEntryPoint() takes |
| 7766 | 7766 | ** no arguments and returns void, SQLite invokes xEntryPoint() with three |
| 7767 | 7767 | ** arguments and expects an integer result as if the signature of the |
| 7768 | -** entry point where as follows: | |
| 7768 | +** entry point were as follows: | |
| 7769 | 7769 | ** |
| 7770 | 7770 | ** <blockquote><pre> |
| 7771 | 7771 | ** int xEntryPoint( |
| 7772 | 7772 | ** sqlite3 *db, |
| 7773 | 7773 | ** const char **pzErrMsg, |
| @@ -8094,11 +8094,11 @@ | ||
| 8094 | 8094 | ** by the first parameter. ^The name of the module is given by the |
| 8095 | 8095 | ** second parameter. ^The third parameter is a pointer to |
| 8096 | 8096 | ** the implementation of the [virtual table module]. ^The fourth |
| 8097 | 8097 | ** parameter is an arbitrary client data pointer that is passed through |
| 8098 | 8098 | ** into the [xCreate] and [xConnect] methods of the virtual table module |
| 8099 | -** when a new virtual table is be being created or reinitialized. | |
| 8099 | +** when a new virtual table is being created or reinitialized. | |
| 8100 | 8100 | ** |
| 8101 | 8101 | ** ^The sqlite3_create_module_v2() interface has a fifth parameter which |
| 8102 | 8102 | ** is a pointer to a destructor for the pClientData. ^SQLite will |
| 8103 | 8103 | ** invoke the destructor function (if it is not NULL) when SQLite |
| 8104 | 8104 | ** no longer needs the pClientData pointer. ^The destructor will also |
| @@ -8259,11 +8259,11 @@ | ||
| 8259 | 8259 | ** |
| 8260 | 8260 | ** ^(On success, [SQLITE_OK] is returned and the new [BLOB handle] is stored |
| 8261 | 8261 | ** in *ppBlob. Otherwise an [error code] is returned and, unless the error |
| 8262 | 8262 | ** code is SQLITE_MISUSE, *ppBlob is set to NULL.)^ ^This means that, provided |
| 8263 | 8263 | ** the API is not misused, it is always safe to call [sqlite3_blob_close()] |
| 8264 | -** on *ppBlob after this function it returns. | |
| 8264 | +** on *ppBlob after this function returns. | |
| 8265 | 8265 | ** |
| 8266 | 8266 | ** This function fails with SQLITE_ERROR if any of the following are true: |
| 8267 | 8267 | ** <ul> |
| 8268 | 8268 | ** <li> ^(Database zDb does not exist)^, |
| 8269 | 8269 | ** <li> ^(Table zTable does not exist within database zDb)^, |
| @@ -8379,11 +8379,11 @@ | ||
| 8379 | 8379 | ** CAPI3REF: Return The Size Of An Open BLOB |
| 8380 | 8380 | ** METHOD: sqlite3_blob |
| 8381 | 8381 | ** |
| 8382 | 8382 | ** ^Returns the size in bytes of the BLOB accessible via the |
| 8383 | 8383 | ** successfully opened [BLOB handle] in its only argument. ^The |
| 8384 | -** incremental blob I/O routines can only read or overwriting existing | |
| 8384 | +** incremental blob I/O routines can only read or overwrite existing | |
| 8385 | 8385 | ** blob content; they cannot change the size of a blob. |
| 8386 | 8386 | ** |
| 8387 | 8387 | ** This routine only works on a [BLOB handle] which has been created |
| 8388 | 8388 | ** by a prior successful call to [sqlite3_blob_open()] and which has not |
| 8389 | 8389 | ** been closed by [sqlite3_blob_close()]. Passing any other pointer in |
| @@ -9782,11 +9782,11 @@ | ||
| 9782 | 9782 | ** sqlite3_backup_step(), the source database may be modified mid-way |
| 9783 | 9783 | ** through the backup process. ^If the source database is modified by an |
| 9784 | 9784 | ** external process or via a database connection other than the one being |
| 9785 | 9785 | ** used by the backup operation, then the backup will be automatically |
| 9786 | 9786 | ** restarted by the next call to sqlite3_backup_step(). ^If the source |
| 9787 | -** database is modified by the using the same database connection as is used | |
| 9787 | +** database is modified by using the same database connection as is used | |
| 9788 | 9788 | ** by the backup operation, then the backup database is automatically |
| 9789 | 9789 | ** updated at the same time. |
| 9790 | 9790 | ** |
| 9791 | 9791 | ** [[sqlite3_backup_finish()]] <b>sqlite3_backup_finish()</b> |
| 9792 | 9792 | ** |
| @@ -9799,11 +9799,11 @@ | ||
| 9799 | 9799 | ** active write-transaction on the destination database is rolled back. |
| 9800 | 9800 | ** The [sqlite3_backup] object is invalid |
| 9801 | 9801 | ** and may not be used following a call to sqlite3_backup_finish(). |
| 9802 | 9802 | ** |
| 9803 | 9803 | ** ^The value returned by sqlite3_backup_finish is [SQLITE_OK] if no |
| 9804 | -** sqlite3_backup_step() errors occurred, regardless or whether or not | |
| 9804 | +** sqlite3_backup_step() errors occurred, regardless of whether or not | |
| 9805 | 9805 | ** sqlite3_backup_step() completed. |
| 9806 | 9806 | ** ^If an out-of-memory condition or IO error occurred during any prior |
| 9807 | 9807 | ** sqlite3_backup_step() call on the same [sqlite3_backup] object, then |
| 9808 | 9808 | ** sqlite3_backup_finish() returns the corresponding [error code]. |
| 9809 | 9809 | ** |
| @@ -10869,11 +10869,11 @@ | ||
| 10869 | 10869 | /* |
| 10870 | 10870 | ** CAPI3REF: Flush caches to disk mid-transaction |
| 10871 | 10871 | ** METHOD: sqlite3 |
| 10872 | 10872 | ** |
| 10873 | 10873 | ** ^If a write-transaction is open on [database connection] D when the |
| 10874 | -** [sqlite3_db_cacheflush(D)] interface invoked, any dirty | |
| 10874 | +** [sqlite3_db_cacheflush(D)] interface is invoked, any dirty | |
| 10875 | 10875 | ** pages in the pager-cache that are not currently in use are written out |
| 10876 | 10876 | ** to disk. A dirty page may be in use if a database cursor created by an |
| 10877 | 10877 | ** active SQL statement is reading from it, or if it is page 1 of a database |
| 10878 | 10878 | ** file (page 1 is always "in use"). ^The [sqlite3_db_cacheflush(D)] |
| 10879 | 10879 | ** interface flushes caches for all schemas - "main", "temp", and |
| @@ -15562,10 +15562,11 @@ | ||
| 15562 | 15562 | ** 0x00008000 After all FROM-clause analysis |
| 15563 | 15563 | ** 0x00010000 Beginning of DELETE/INSERT/UPDATE processing |
| 15564 | 15564 | ** 0x00020000 Transform DISTINCT into GROUP BY |
| 15565 | 15565 | ** 0x00040000 SELECT tree dump after all code has been generated |
| 15566 | 15566 | ** 0x00080000 NOT NULL strength reduction |
| 15567 | +** 0x00100000 Pointers are all shown as zero | |
| 15567 | 15568 | */ |
| 15568 | 15569 | |
| 15569 | 15570 | /* |
| 15570 | 15571 | ** Macros for "wheretrace" |
| 15571 | 15572 | */ |
| @@ -15606,10 +15607,11 @@ | ||
| 15606 | 15607 | ** |
| 15607 | 15608 | ** 0x00010000 Show more detail when printing WHERE terms |
| 15608 | 15609 | ** 0x00020000 Show WHERE terms returned from whereScanNext() |
| 15609 | 15610 | ** 0x00040000 Solver overview messages |
| 15610 | 15611 | ** 0x00080000 Star-query heuristic |
| 15612 | +** 0x00100000 Pointers are all shown as zero | |
| 15611 | 15613 | */ |
| 15612 | 15614 | |
| 15613 | 15615 | |
| 15614 | 15616 | /* |
| 15615 | 15617 | ** An instance of the following structure is used to store the busy-handler |
| @@ -15678,11 +15680,11 @@ | ||
| 15678 | 15680 | ** one parameter that destructors normally want. So we have to introduce |
| 15679 | 15681 | ** this magic value that the code knows to handle differently. Any |
| 15680 | 15682 | ** pointer will work here as long as it is distinct from SQLITE_STATIC |
| 15681 | 15683 | ** and SQLITE_TRANSIENT. |
| 15682 | 15684 | */ |
| 15683 | -#define SQLITE_DYNAMIC ((sqlite3_destructor_type)sqlite3OomClear) | |
| 15685 | +#define SQLITE_DYNAMIC ((sqlite3_destructor_type)sqlite3RowSetClear) | |
| 15684 | 15686 | |
| 15685 | 15687 | /* |
| 15686 | 15688 | ** When SQLITE_OMIT_WSD is defined, it means that the target platform does |
| 15687 | 15689 | ** not support Writable Static Data (WSD) such as global and static variables. |
| 15688 | 15690 | ** All variables must either be on the stack or dynamically allocated from |
| @@ -21266,10 +21268,11 @@ | ||
| 21266 | 21268 | #endif |
| 21267 | 21269 | #ifndef SQLITE_OMIT_WINDOWFUNC |
| 21268 | 21270 | SQLITE_PRIVATE void sqlite3ShowWindow(const Window*); |
| 21269 | 21271 | SQLITE_PRIVATE void sqlite3ShowWinFunc(const Window*); |
| 21270 | 21272 | #endif |
| 21273 | +SQLITE_PRIVATE void sqlite3ShowBitvec(Bitvec*); | |
| 21271 | 21274 | #endif |
| 21272 | 21275 | |
| 21273 | 21276 | SQLITE_PRIVATE void sqlite3SetString(char **, sqlite3*, const char*); |
| 21274 | 21277 | SQLITE_PRIVATE void sqlite3ProgressCheck(Parse*); |
| 21275 | 21278 | SQLITE_PRIVATE void sqlite3ErrorMsg(Parse*, const char*, ...); |
| @@ -32077,10 +32080,18 @@ | ||
| 32077 | 32080 | }else{ |
| 32078 | 32081 | longvalue = va_arg(ap,unsigned int); |
| 32079 | 32082 | } |
| 32080 | 32083 | prefix = 0; |
| 32081 | 32084 | } |
| 32085 | + | |
| 32086 | +#if WHERETRACE_ENABLED | |
| 32087 | + if( xtype==etPOINTER && sqlite3WhereTrace & 0x100000 ) longvalue = 0; | |
| 32088 | +#endif | |
| 32089 | +#if TREETRACE_ENABLED | |
| 32090 | + if( xtype==etPOINTER && sqlite3TreeTrace & 0x100000 ) longvalue = 0; | |
| 32091 | +#endif | |
| 32092 | + | |
| 32082 | 32093 | if( longvalue==0 ) flag_alternateform = 0; |
| 32083 | 32094 | if( flag_zeropad && precision<width-(prefix!=0) ){ |
| 32084 | 32095 | precision = width-(prefix!=0); |
| 32085 | 32096 | } |
| 32086 | 32097 | if( precision<etBUFSIZE-10-etBUFSIZE/3 ){ |
| @@ -54872,10 +54883,11 @@ | ||
| 54872 | 54883 | BITVEC_TELEM aBitmap[BITVEC_NELEM]; /* Bitmap representation */ |
| 54873 | 54884 | u32 aHash[BITVEC_NINT]; /* Hash table representation */ |
| 54874 | 54885 | Bitvec *apSub[BITVEC_NPTR]; /* Recursive representation */ |
| 54875 | 54886 | } u; |
| 54876 | 54887 | }; |
| 54888 | + | |
| 54877 | 54889 | |
| 54878 | 54890 | /* |
| 54879 | 54891 | ** Create a new bitmap object able to handle bits between 0 and iSize, |
| 54880 | 54892 | ** inclusive. Return a pointer to the new object. Return NULL if |
| 54881 | 54893 | ** malloc fails. |
| @@ -54982,11 +54994,13 @@ | ||
| 54982 | 54994 | if( aiValues==0 ){ |
| 54983 | 54995 | return SQLITE_NOMEM_BKPT; |
| 54984 | 54996 | }else{ |
| 54985 | 54997 | memcpy(aiValues, p->u.aHash, sizeof(p->u.aHash)); |
| 54986 | 54998 | memset(p->u.apSub, 0, sizeof(p->u.apSub)); |
| 54987 | - p->iDivisor = (p->iSize + BITVEC_NPTR - 1)/BITVEC_NPTR; | |
| 54999 | + p->iDivisor = p->iSize/BITVEC_NPTR; | |
| 55000 | + if( (p->iSize%BITVEC_NPTR)!=0 ) p->iDivisor++; | |
| 55001 | + if( p->iDivisor<BITVEC_NBIT ) p->iDivisor = BITVEC_NBIT; | |
| 54988 | 55002 | rc = sqlite3BitvecSet(p, i); |
| 54989 | 55003 | for(j=0; j<BITVEC_NINT; j++){ |
| 54990 | 55004 | if( aiValues[j] ) rc |= sqlite3BitvecSet(p, aiValues[j]); |
| 54991 | 55005 | } |
| 54992 | 55006 | sqlite3StackFree(0, aiValues); |
| @@ -55058,10 +55072,56 @@ | ||
| 55058 | 55072 | ** was created. |
| 55059 | 55073 | */ |
| 55060 | 55074 | SQLITE_PRIVATE u32 sqlite3BitvecSize(Bitvec *p){ |
| 55061 | 55075 | return p->iSize; |
| 55062 | 55076 | } |
| 55077 | + | |
| 55078 | +#ifdef SQLITE_DEBUG | |
| 55079 | +/* | |
| 55080 | +** Show the content of a Bitvec option and its children. Indent | |
| 55081 | +** everything by n spaces. Add x to each bitvec value. | |
| 55082 | +** | |
| 55083 | +** From a debugger such as gdb, one can type: | |
| 55084 | +** | |
| 55085 | +** call sqlite3ShowBitvec(p) | |
| 55086 | +** | |
| 55087 | +** For some Bitvec p and see a recursive view of the Bitvec's content. | |
| 55088 | +*/ | |
| 55089 | +static void showBitvec(Bitvec *p, int n, unsigned x){ | |
| 55090 | + int i; | |
| 55091 | + if( p==0 ){ | |
| 55092 | + printf("NULL\n"); | |
| 55093 | + return; | |
| 55094 | + } | |
| 55095 | + printf("Bitvec 0x%p iSize=%u", p, p->iSize); | |
| 55096 | + if( p->iSize<=BITVEC_NBIT ){ | |
| 55097 | + printf(" bitmap\n"); | |
| 55098 | + printf("%*s bits:", n, ""); | |
| 55099 | + for(i=1; i<=BITVEC_NBIT; i++){ | |
| 55100 | + if( sqlite3BitvecTest(p,i) ) printf(" %u", x+(unsigned)i); | |
| 55101 | + } | |
| 55102 | + printf("\n"); | |
| 55103 | + }else if( p->iDivisor==0 ){ | |
| 55104 | + printf(" hash with %u entries\n", p->nSet); | |
| 55105 | + printf("%*s bits:", n, ""); | |
| 55106 | + for(i=0; i<BITVEC_NINT; i++){ | |
| 55107 | + if( p->u.aHash[i] ) printf(" %u", x+(unsigned)p->u.aHash[i]); | |
| 55108 | + } | |
| 55109 | + printf("\n"); | |
| 55110 | + }else{ | |
| 55111 | + printf(" sub-bitvec with iDivisor=%u\n", p->iDivisor); | |
| 55112 | + for(i=0; i<BITVEC_NPTR; i++){ | |
| 55113 | + if( p->u.apSub[i]==0 ) continue; | |
| 55114 | + printf("%*s apSub[%d]=", n, "", i); | |
| 55115 | + showBitvec(p->u.apSub[i], n+4, i*p->iDivisor); | |
| 55116 | + } | |
| 55117 | + } | |
| 55118 | +} | |
| 55119 | +SQLITE_PRIVATE void sqlite3ShowBitvec(Bitvec *p){ | |
| 55120 | + showBitvec(p, 0, 0); | |
| 55121 | +} | |
| 55122 | +#endif | |
| 55063 | 55123 | |
| 55064 | 55124 | #ifndef SQLITE_UNTESTABLE |
| 55065 | 55125 | /* |
| 55066 | 55126 | ** Let V[] be an array of unsigned characters sufficient to hold |
| 55067 | 55127 | ** up to N bits. Let I be an integer between 0 and N. 0<=I<N. |
| @@ -55069,40 +55129,48 @@ | ||
| 55069 | 55129 | ** individual bits within V. |
| 55070 | 55130 | */ |
| 55071 | 55131 | #define SETBIT(V,I) V[I>>3] |= (1<<(I&7)) |
| 55072 | 55132 | #define CLEARBIT(V,I) V[I>>3] &= ~(BITVEC_TELEM)(1<<(I&7)) |
| 55073 | 55133 | #define TESTBIT(V,I) (V[I>>3]&(1<<(I&7)))!=0 |
| 55134 | + | |
| 55074 | 55135 | |
| 55075 | 55136 | /* |
| 55076 | 55137 | ** This routine runs an extensive test of the Bitvec code. |
| 55077 | 55138 | ** |
| 55078 | 55139 | ** The input is an array of integers that acts as a program |
| 55079 | 55140 | ** to test the Bitvec. The integers are opcodes followed |
| 55080 | 55141 | ** by 0, 1, or 3 operands, depending on the opcode. Another |
| 55081 | 55142 | ** opcode follows immediately after the last operand. |
| 55082 | 55143 | ** |
| 55083 | -** There are 6 opcodes numbered from 0 through 5. 0 is the | |
| 55144 | +** There are opcodes numbered starting with 0. 0 is the | |
| 55084 | 55145 | ** "halt" opcode and causes the test to end. |
| 55085 | 55146 | ** |
| 55086 | 55147 | ** 0 Halt and return the number of errors |
| 55087 | 55148 | ** 1 N S X Set N bits beginning with S and incrementing by X |
| 55088 | 55149 | ** 2 N S X Clear N bits beginning with S and incrementing by X |
| 55089 | 55150 | ** 3 N Set N randomly chosen bits |
| 55090 | 55151 | ** 4 N Clear N randomly chosen bits |
| 55091 | 55152 | ** 5 N S X Set N bits from S increment X in array only, not in bitvec |
| 55153 | +** 6 Invoice sqlite3ShowBitvec() on the Bitvec object so far | |
| 55154 | +** 7 X Show compile-time parameters and the hash of X | |
| 55092 | 55155 | ** |
| 55093 | 55156 | ** The opcodes 1 through 4 perform set and clear operations are performed |
| 55094 | 55157 | ** on both a Bitvec object and on a linear array of bits obtained from malloc. |
| 55095 | 55158 | ** Opcode 5 works on the linear array only, not on the Bitvec. |
| 55096 | 55159 | ** Opcode 5 is used to deliberately induce a fault in order to |
| 55097 | -** confirm that error detection works. | |
| 55160 | +** confirm that error detection works. Opcodes 6 and greater are | |
| 55161 | +** state output opcodes. Opcodes 6 and greater are no-ops unless | |
| 55162 | +** SQLite has been compiled with SQLITE_DEBUG. | |
| 55098 | 55163 | ** |
| 55099 | 55164 | ** At the conclusion of the test the linear array is compared |
| 55100 | 55165 | ** against the Bitvec object. If there are any differences, |
| 55101 | 55166 | ** an error is returned. If they are the same, zero is returned. |
| 55102 | 55167 | ** |
| 55103 | 55168 | ** If a memory allocation error occurs, return -1. |
| 55169 | +** | |
| 55170 | +** sz is the size of the Bitvec. Or if sz is negative, make the size | |
| 55171 | +** 2*(unsigned)(-sz) and disabled the linear vector check. | |
| 55104 | 55172 | */ |
| 55105 | 55173 | SQLITE_PRIVATE int sqlite3BitvecBuiltinTest(int sz, int *aOp){ |
| 55106 | 55174 | Bitvec *pBitvec = 0; |
| 55107 | 55175 | unsigned char *pV = 0; |
| 55108 | 55176 | int rc = -1; |
| @@ -55109,22 +55177,45 @@ | ||
| 55109 | 55177 | int i, nx, pc, op; |
| 55110 | 55178 | void *pTmpSpace; |
| 55111 | 55179 | |
| 55112 | 55180 | /* Allocate the Bitvec to be tested and a linear array of |
| 55113 | 55181 | ** bits to act as the reference */ |
| 55114 | - pBitvec = sqlite3BitvecCreate( sz ); | |
| 55115 | - pV = sqlite3MallocZero( (7+(i64)sz)/8 + 1 ); | |
| 55182 | + if( sz<=0 ){ | |
| 55183 | + pBitvec = sqlite3BitvecCreate( 2*(unsigned)(-sz) ); | |
| 55184 | + pV = 0; | |
| 55185 | + }else{ | |
| 55186 | + pBitvec = sqlite3BitvecCreate( sz ); | |
| 55187 | + pV = sqlite3MallocZero( (7+(i64)sz)/8 + 1 ); | |
| 55188 | + } | |
| 55116 | 55189 | pTmpSpace = sqlite3_malloc64(BITVEC_SZ); |
| 55117 | - if( pBitvec==0 || pV==0 || pTmpSpace==0 ) goto bitvec_end; | |
| 55190 | + if( pBitvec==0 || pTmpSpace==0 || (pV==0 && sz>0) ) goto bitvec_end; | |
| 55118 | 55191 | |
| 55119 | 55192 | /* NULL pBitvec tests */ |
| 55120 | 55193 | sqlite3BitvecSet(0, 1); |
| 55121 | 55194 | sqlite3BitvecClear(0, 1, pTmpSpace); |
| 55122 | 55195 | |
| 55123 | 55196 | /* Run the program */ |
| 55124 | 55197 | pc = i = 0; |
| 55125 | 55198 | while( (op = aOp[pc])!=0 ){ |
| 55199 | + if( op>=6 ){ | |
| 55200 | +#ifdef SQLITE_DEBUG | |
| 55201 | + if( op==6 ){ | |
| 55202 | + sqlite3ShowBitvec(pBitvec); | |
| 55203 | + }else if( op==7 ){ | |
| 55204 | + printf("BITVEC_SZ = %d (%d by sizeof)\n", | |
| 55205 | + BITVEC_SZ, (int)sizeof(Bitvec)); | |
| 55206 | + printf("BITVEC_USIZE = %d\n", (int)BITVEC_USIZE); | |
| 55207 | + printf("BITVEC_NELEM = %d\n", (int)BITVEC_NELEM); | |
| 55208 | + printf("BITVEC_NBIT = %d\n", (int)BITVEC_NBIT); | |
| 55209 | + printf("BITVEC_NINT = %d\n", (int)BITVEC_NINT); | |
| 55210 | + printf("BITVEC_MXHASH = %d\n", (int)BITVEC_MXHASH); | |
| 55211 | + printf("BITVEC_NPTR = %d\n", (int)BITVEC_NPTR); | |
| 55212 | + } | |
| 55213 | +#endif | |
| 55214 | + pc++; | |
| 55215 | + continue; | |
| 55216 | + } | |
| 55126 | 55217 | switch( op ){ |
| 55127 | 55218 | case 1: |
| 55128 | 55219 | case 2: |
| 55129 | 55220 | case 5: { |
| 55130 | 55221 | nx = 4; |
| @@ -55142,33 +55233,37 @@ | ||
| 55142 | 55233 | } |
| 55143 | 55234 | if( (--aOp[pc+1]) > 0 ) nx = 0; |
| 55144 | 55235 | pc += nx; |
| 55145 | 55236 | i = (i & 0x7fffffff)%sz; |
| 55146 | 55237 | if( (op & 1)!=0 ){ |
| 55147 | - SETBIT(pV, (i+1)); | |
| 55238 | + if( pV ) SETBIT(pV, (i+1)); | |
| 55148 | 55239 | if( op!=5 ){ |
| 55149 | 55240 | if( sqlite3BitvecSet(pBitvec, i+1) ) goto bitvec_end; |
| 55150 | 55241 | } |
| 55151 | 55242 | }else{ |
| 55152 | - CLEARBIT(pV, (i+1)); | |
| 55243 | + if( pV ) CLEARBIT(pV, (i+1)); | |
| 55153 | 55244 | sqlite3BitvecClear(pBitvec, i+1, pTmpSpace); |
| 55154 | 55245 | } |
| 55155 | 55246 | } |
| 55156 | 55247 | |
| 55157 | 55248 | /* Test to make sure the linear array exactly matches the |
| 55158 | 55249 | ** Bitvec object. Start with the assumption that they do |
| 55159 | 55250 | ** match (rc==0). Change rc to non-zero if a discrepancy |
| 55160 | 55251 | ** is found. |
| 55161 | 55252 | */ |
| 55162 | - rc = sqlite3BitvecTest(0,0) + sqlite3BitvecTest(pBitvec, sz+1) | |
| 55163 | - + sqlite3BitvecTest(pBitvec, 0) | |
| 55164 | - + (sqlite3BitvecSize(pBitvec) - sz); | |
| 55165 | - for(i=1; i<=sz; i++){ | |
| 55166 | - if( (TESTBIT(pV,i))!=sqlite3BitvecTest(pBitvec,i) ){ | |
| 55167 | - rc = i; | |
| 55168 | - break; | |
| 55169 | - } | |
| 55253 | + if( pV ){ | |
| 55254 | + rc = sqlite3BitvecTest(0,0) + sqlite3BitvecTest(pBitvec, sz+1) | |
| 55255 | + + sqlite3BitvecTest(pBitvec, 0) | |
| 55256 | + + (sqlite3BitvecSize(pBitvec) - sz); | |
| 55257 | + for(i=1; i<=sz; i++){ | |
| 55258 | + if( (TESTBIT(pV,i))!=sqlite3BitvecTest(pBitvec,i) ){ | |
| 55259 | + rc = i; | |
| 55260 | + break; | |
| 55261 | + } | |
| 55262 | + } | |
| 55263 | + }else{ | |
| 55264 | + rc = 0; | |
| 55170 | 55265 | } |
| 55171 | 55266 | |
| 55172 | 55267 | /* Free allocated structure */ |
| 55173 | 55268 | bitvec_end: |
| 55174 | 55269 | sqlite3_free(pTmpSpace); |
| @@ -69670,10 +69765,11 @@ | ||
| 69670 | 69765 | rc = xUndo(pUndoCtx, walFramePgno(pWal, iFrame)); |
| 69671 | 69766 | } |
| 69672 | 69767 | if( iMax!=pWal->hdr.mxFrame ) walCleanupHash(pWal); |
| 69673 | 69768 | } |
| 69674 | 69769 | SEH_EXCEPT( rc = SQLITE_IOERR_IN_PAGE; ) |
| 69770 | + pWal->iReCksum = 0; | |
| 69675 | 69771 | } |
| 69676 | 69772 | return rc; |
| 69677 | 69773 | } |
| 69678 | 69774 | |
| 69679 | 69775 | /* |
| @@ -69717,10 +69813,13 @@ | ||
| 69717 | 69813 | pWal->hdr.aFrameCksum[1] = aWalData[2]; |
| 69718 | 69814 | SEH_TRY { |
| 69719 | 69815 | walCleanupHash(pWal); |
| 69720 | 69816 | } |
| 69721 | 69817 | SEH_EXCEPT( rc = SQLITE_IOERR_IN_PAGE; ) |
| 69818 | + if( pWal->iReCksum>pWal->hdr.mxFrame ){ | |
| 69819 | + pWal->iReCksum = 0; | |
| 69820 | + } | |
| 69722 | 69821 | } |
| 69723 | 69822 | |
| 69724 | 69823 | return rc; |
| 69725 | 69824 | } |
| 69726 | 69825 | |
| @@ -77442,12 +77541,12 @@ | ||
| 77442 | 77541 | assert( (pCur->curFlags & BTCF_ValidOvfl)==0 ); |
| 77443 | 77542 | return rc; |
| 77444 | 77543 | } |
| 77445 | 77544 | |
| 77446 | 77545 | /* |
| 77447 | -** Compare the "idx"-th cell on the page the cursor pCur is currently | |
| 77448 | -** pointing to to pIdxKey using xRecordCompare. Return negative or | |
| 77546 | +** Compare the "idx"-th cell on the page pPage against the key | |
| 77547 | +** pointing to by pIdxKey using xRecordCompare. Return negative or | |
| 77449 | 77548 | ** zero if the cell is less than or equal pIdxKey. Return positive |
| 77450 | 77549 | ** if unknown. |
| 77451 | 77550 | ** |
| 77452 | 77551 | ** Return value negative: Cell at pCur[idx] less than pIdxKey |
| 77453 | 77552 | ** |
| @@ -77458,16 +77557,15 @@ | ||
| 77458 | 77557 | ** |
| 77459 | 77558 | ** This routine is part of an optimization. It is always safe to return |
| 77460 | 77559 | ** a positive value as that will cause the optimization to be skipped. |
| 77461 | 77560 | */ |
| 77462 | 77561 | static int indexCellCompare( |
| 77463 | - BtCursor *pCur, | |
| 77562 | + MemPage *pPage, | |
| 77464 | 77563 | int idx, |
| 77465 | 77564 | UnpackedRecord *pIdxKey, |
| 77466 | 77565 | RecordCompare xRecordCompare |
| 77467 | 77566 | ){ |
| 77468 | - MemPage *pPage = pCur->pPage; | |
| 77469 | 77567 | int c; |
| 77470 | 77568 | int nCell; /* Size of the pCell cell in bytes */ |
| 77471 | 77569 | u8 *pCell = findCellPastPtr(pPage, idx); |
| 77472 | 77570 | |
| 77473 | 77571 | nCell = pCell[0]; |
| @@ -77572,18 +77670,18 @@ | ||
| 77572 | 77670 | && pCur->pPage->leaf |
| 77573 | 77671 | && cursorOnLastPage(pCur) |
| 77574 | 77672 | ){ |
| 77575 | 77673 | int c; |
| 77576 | 77674 | if( pCur->ix==pCur->pPage->nCell-1 |
| 77577 | - && (c = indexCellCompare(pCur, pCur->ix, pIdxKey, xRecordCompare))<=0 | |
| 77675 | + && (c = indexCellCompare(pCur->pPage,pCur->ix,pIdxKey,xRecordCompare))<=0 | |
| 77578 | 77676 | && pIdxKey->errCode==SQLITE_OK |
| 77579 | 77677 | ){ |
| 77580 | 77678 | *pRes = c; |
| 77581 | 77679 | return SQLITE_OK; /* Cursor already pointing at the correct spot */ |
| 77582 | 77680 | } |
| 77583 | 77681 | if( pCur->iPage>0 |
| 77584 | - && indexCellCompare(pCur, 0, pIdxKey, xRecordCompare)<=0 | |
| 77682 | + && indexCellCompare(pCur->pPage, 0, pIdxKey, xRecordCompare)<=0 | |
| 77585 | 77683 | && pIdxKey->errCode==SQLITE_OK |
| 77586 | 77684 | ){ |
| 77587 | 77685 | pCur->curFlags &= ~(BTCF_ValidOvfl|BTCF_AtLast); |
| 77588 | 77686 | if( !pCur->pPage->isInit ){ |
| 77589 | 77687 | return SQLITE_CORRUPT_BKPT; |
| @@ -77796,11 +77894,11 @@ | ||
| 77796 | 77894 | if( pCur->eState!=CURSOR_VALID ) return 0; |
| 77797 | 77895 | if( NEVER(pCur->pPage->leaf==0) ) return -1; |
| 77798 | 77896 | |
| 77799 | 77897 | n = pCur->pPage->nCell; |
| 77800 | 77898 | for(i=0; i<pCur->iPage; i++){ |
| 77801 | - n *= pCur->apPage[i]->nCell; | |
| 77899 | + n *= pCur->apPage[i]->nCell+1; | |
| 77802 | 77900 | } |
| 77803 | 77901 | return n; |
| 77804 | 77902 | } |
| 77805 | 77903 | |
| 77806 | 77904 | /* |
| @@ -97581,10 +97679,19 @@ | ||
| 97581 | 97679 | ** Synopsis: typecheck(r[P1@P2]) |
| 97582 | 97680 | ** |
| 97583 | 97681 | ** Apply affinities to the range of P2 registers beginning with P1. |
| 97584 | 97682 | ** Take the affinities from the Table object in P4. If any value |
| 97585 | 97683 | ** cannot be coerced into the correct type, then raise an error. |
| 97684 | +** | |
| 97685 | +** If P3==0, then omit checking of VIRTUAL columns. | |
| 97686 | +** | |
| 97687 | +** If P3==1, then omit checking of all generated column, both VIRTUAL | |
| 97688 | +** and STORED. | |
| 97689 | +** | |
| 97690 | +** If P3>=2, then only check column number P3-2 in the table (which will | |
| 97691 | +** be a VIRTUAL column) against the value in reg[P1]. In this case, | |
| 97692 | +** P2 will be 1. | |
| 97586 | 97693 | ** |
| 97587 | 97694 | ** This opcode is similar to OP_Affinity except that this opcode |
| 97588 | 97695 | ** forces the register type to the Table column type. This is used |
| 97589 | 97696 | ** to implement "strict affinity". |
| 97590 | 97697 | ** |
| @@ -97595,30 +97702,42 @@ | ||
| 97595 | 97702 | ** |
| 97596 | 97703 | ** Preconditions: |
| 97597 | 97704 | ** |
| 97598 | 97705 | ** <ul> |
| 97599 | 97706 | ** <li> P2 should be the number of non-virtual columns in the |
| 97600 | -** table of P4. | |
| 97601 | -** <li> Table P4 should be a STRICT table. | |
| 97707 | +** table of P4 unless P3>1, in which case P2 will be 1. | |
| 97708 | +** <li> Table P4 is a STRICT table. | |
| 97602 | 97709 | ** </ul> |
| 97603 | 97710 | ** |
| 97604 | 97711 | ** If any precondition is false, an assertion fault occurs. |
| 97605 | 97712 | */ |
| 97606 | 97713 | case OP_TypeCheck: { |
| 97607 | 97714 | Table *pTab; |
| 97608 | 97715 | Column *aCol; |
| 97609 | 97716 | int i; |
| 97717 | + int nCol; | |
| 97610 | 97718 | |
| 97611 | 97719 | assert( pOp->p4type==P4_TABLE ); |
| 97612 | 97720 | pTab = pOp->p4.pTab; |
| 97613 | 97721 | assert( pTab->tabFlags & TF_Strict ); |
| 97614 | - assert( pTab->nNVCol==pOp->p2 ); | |
| 97722 | + assert( pOp->p3>=0 && pOp->p3<pTab->nCol+2 ); | |
| 97615 | 97723 | aCol = pTab->aCol; |
| 97616 | 97724 | pIn1 = &aMem[pOp->p1]; |
| 97617 | - for(i=0; i<pTab->nCol; i++){ | |
| 97618 | - if( aCol[i].colFlags & COLFLAG_GENERATED ){ | |
| 97619 | - if( aCol[i].colFlags & COLFLAG_VIRTUAL ) continue; | |
| 97725 | + if( pOp->p3<2 ){ | |
| 97726 | + assert( pTab->nNVCol==pOp->p2 ); | |
| 97727 | + i = 0; | |
| 97728 | + nCol = pTab->nCol; | |
| 97729 | + }else{ | |
| 97730 | + i = pOp->p3-2; | |
| 97731 | + nCol = i+1; | |
| 97732 | + assert( i<pTab->nCol ); | |
| 97733 | + assert( aCol[i].colFlags & COLFLAG_VIRTUAL ); | |
| 97734 | + assert( pOp->p2==1 ); | |
| 97735 | + } | |
| 97736 | + for(; i<nCol; i++){ | |
| 97737 | + if( (aCol[i].colFlags & COLFLAG_GENERATED)!=0 && pOp->p3<2 ){ | |
| 97738 | + if( (aCol[i].colFlags & COLFLAG_VIRTUAL)!=0 ) continue; | |
| 97620 | 97739 | if( pOp->p3 ){ pIn1++; continue; } |
| 97621 | 97740 | } |
| 97622 | 97741 | assert( pIn1 < &aMem[pOp->p1+pOp->p2] ); |
| 97623 | 97742 | applyAffinity(pIn1, aCol[i].affinity, encoding); |
| 97624 | 97743 | if( (pIn1->flags & MEM_Null)==0 ){ |
| @@ -114626,11 +114745,16 @@ | ||
| 114626 | 114745 | iAddr = sqlite3VdbeAddOp3(v, OP_IfNullRow, pParse->iSelfTab-1, 0, regOut); |
| 114627 | 114746 | }else{ |
| 114628 | 114747 | iAddr = 0; |
| 114629 | 114748 | } |
| 114630 | 114749 | sqlite3ExprCodeCopy(pParse, sqlite3ColumnExpr(pTab,pCol), regOut); |
| 114631 | - if( pCol->affinity>=SQLITE_AFF_TEXT ){ | |
| 114750 | + if( (pCol->colFlags & COLFLAG_VIRTUAL)!=0 | |
| 114751 | + && (pTab->tabFlags & TF_Strict)!=0 | |
| 114752 | + ){ | |
| 114753 | + int p3 = 2+(int)(pCol - pTab->aCol); | |
| 114754 | + sqlite3VdbeAddOp4(v, OP_TypeCheck, regOut, 1, p3, (char*)pTab, P4_TABLE); | |
| 114755 | + }else if( pCol->affinity>=SQLITE_AFF_TEXT ){ | |
| 114632 | 114756 | sqlite3VdbeAddOp4(v, OP_Affinity, regOut, 1, 0, &pCol->affinity, 1); |
| 114633 | 114757 | } |
| 114634 | 114758 | if( iAddr ) sqlite3VdbeJumpHere(v, iAddr); |
| 114635 | 114759 | if( pParse->nErr>nErr ) pParse->db->errByteOffset = -1; |
| 114636 | 114760 | } |
| @@ -132020,11 +132144,11 @@ | ||
| 132020 | 132144 | int argc, |
| 132021 | 132145 | sqlite3_value **argv, |
| 132022 | 132146 | int nSep, |
| 132023 | 132147 | const char *zSep |
| 132024 | 132148 | ){ |
| 132025 | - i64 j, k, n = 0; | |
| 132149 | + i64 j, n = 0; | |
| 132026 | 132150 | int i; |
| 132027 | 132151 | char *z; |
| 132028 | 132152 | for(i=0; i<argc; i++){ |
| 132029 | 132153 | n += sqlite3_value_bytes(argv[i]); |
| 132030 | 132154 | } |
| @@ -132034,12 +132158,12 @@ | ||
| 132034 | 132158 | sqlite3_result_error_nomem(context); |
| 132035 | 132159 | return; |
| 132036 | 132160 | } |
| 132037 | 132161 | j = 0; |
| 132038 | 132162 | for(i=0; i<argc; i++){ |
| 132039 | - k = sqlite3_value_bytes(argv[i]); | |
| 132040 | - if( k>0 ){ | |
| 132163 | + if( sqlite3_value_type(argv[i])!=SQLITE_NULL ){ | |
| 132164 | + int k = sqlite3_value_bytes(argv[i]); | |
| 132041 | 132165 | const char *v = (const char*)sqlite3_value_text(argv[i]); |
| 132042 | 132166 | if( v!=0 ){ |
| 132043 | 132167 | if( j>0 && nSep>0 ){ |
| 132044 | 132168 | memcpy(&z[j], zSep, nSep); |
| 132045 | 132169 | j += nSep; |
| @@ -134973,16 +135097,19 @@ | ||
| 134973 | 135097 | if( iReg==0 ){ |
| 134974 | 135098 | /* Move the previous opcode (which should be OP_MakeRecord) forward |
| 134975 | 135099 | ** by one slot and insert a new OP_TypeCheck where the current |
| 134976 | 135100 | ** OP_MakeRecord is found */ |
| 134977 | 135101 | VdbeOp *pPrev; |
| 135102 | + int p3; | |
| 134978 | 135103 | sqlite3VdbeAppendP4(v, pTab, P4_TABLE); |
| 134979 | 135104 | pPrev = sqlite3VdbeGetLastOp(v); |
| 134980 | 135105 | assert( pPrev!=0 ); |
| 134981 | 135106 | assert( pPrev->opcode==OP_MakeRecord || sqlite3VdbeDb(v)->mallocFailed ); |
| 134982 | 135107 | pPrev->opcode = OP_TypeCheck; |
| 134983 | - sqlite3VdbeAddOp3(v, OP_MakeRecord, pPrev->p1, pPrev->p2, pPrev->p3); | |
| 135108 | + p3 = pPrev->p3; | |
| 135109 | + pPrev->p3 = 0; | |
| 135110 | + sqlite3VdbeAddOp3(v, OP_MakeRecord, pPrev->p1, pPrev->p2, p3); | |
| 134984 | 135111 | }else{ |
| 134985 | 135112 | /* Insert an isolated OP_Typecheck */ |
| 134986 | 135113 | sqlite3VdbeAddOp2(v, OP_TypeCheck, iReg, pTab->nNVCol); |
| 134987 | 135114 | sqlite3VdbeAppendP4(v, pTab, P4_TABLE); |
| 134988 | 135115 | } |
| @@ -159213,10 +159340,13 @@ | ||
| 159213 | 159340 | u16 eOperator; /* A WO_xx value describing <op> */ |
| 159214 | 159341 | u8 nChild; /* Number of children that must disable us */ |
| 159215 | 159342 | u8 eMatchOp; /* Op for vtab MATCH/LIKE/GLOB/REGEXP terms */ |
| 159216 | 159343 | int iParent; /* Disable pWC->a[iParent] when this term disabled */ |
| 159217 | 159344 | int leftCursor; /* Cursor number of X in "X <op> <expr>" */ |
| 159345 | +#ifdef SQLITE_DEBUG | |
| 159346 | + int iTerm; /* Which WhereTerm is this, for debug purposes */ | |
| 159347 | +#endif | |
| 159218 | 159348 | union { |
| 159219 | 159349 | struct { |
| 159220 | 159350 | int leftColumn; /* Column number of X in "X <op> <expr>" */ |
| 159221 | 159351 | int iField; /* Field in (?,?,?) IN (SELECT...) vector */ |
| 159222 | 159352 | } x; /* Opcode other than OP_OR or OP_AND */ |
| @@ -161410,40 +161540,40 @@ | ||
| 161410 | 161540 | VdbeCoverageIf(v, testOp==OP_Ge); |
| 161411 | 161541 | VdbeCoverageIf(v, testOp==OP_Gt); |
| 161412 | 161542 | sqlite3VdbeChangeP5(v, SQLITE_AFF_NUMERIC | SQLITE_JUMPIFNULL); |
| 161413 | 161543 | } |
| 161414 | 161544 | }else if( pLoop->wsFlags & WHERE_INDEXED ){ |
| 161415 | - /* Case 4: A scan using an index. | |
| 161416 | - ** | |
| 161417 | - ** The WHERE clause may contain zero or more equality | |
| 161418 | - ** terms ("==" or "IN" operators) that refer to the N | |
| 161419 | - ** left-most columns of the index. It may also contain | |
| 161420 | - ** inequality constraints (>, <, >= or <=) on the indexed | |
| 161421 | - ** column that immediately follows the N equalities. Only | |
| 161422 | - ** the right-most column can be an inequality - the rest must | |
| 161423 | - ** use the "==" and "IN" operators. For example, if the | |
| 161424 | - ** index is on (x,y,z), then the following clauses are all | |
| 161425 | - ** optimized: | |
| 161426 | - ** | |
| 161427 | - ** x=5 | |
| 161428 | - ** x=5 AND y=10 | |
| 161429 | - ** x=5 AND y<10 | |
| 161430 | - ** x=5 AND y>5 AND y<10 | |
| 161431 | - ** x=5 AND y=5 AND z<=10 | |
| 161432 | - ** | |
| 161433 | - ** The z<10 term of the following cannot be used, only | |
| 161434 | - ** the x=5 term: | |
| 161435 | - ** | |
| 161436 | - ** x=5 AND z<10 | |
| 161437 | - ** | |
| 161438 | - ** N may be zero if there are inequality constraints. | |
| 161439 | - ** If there are no inequality constraints, then N is at | |
| 161440 | - ** least one. | |
| 161441 | - ** | |
| 161442 | - ** This case is also used when there are no WHERE clause | |
| 161443 | - ** constraints but an index is selected anyway, in order | |
| 161444 | - ** to force the output order to conform to an ORDER BY. | |
| 161545 | + /* Case 4: Search using an index. | |
| 161546 | + ** | |
| 161547 | + ** The WHERE clause may contain zero or more equality | |
| 161548 | + ** terms ("==" or "IN" or "IS" operators) that refer to the N | |
| 161549 | + ** left-most columns of the index. It may also contain | |
| 161550 | + ** inequality constraints (>, <, >= or <=) on the indexed | |
| 161551 | + ** column that immediately follows the N equalities. Only | |
| 161552 | + ** the right-most column can be an inequality - the rest must | |
| 161553 | + ** use the "==", "IN", or "IS" operators. For example, if the | |
| 161554 | + ** index is on (x,y,z), then the following clauses are all | |
| 161555 | + ** optimized: | |
| 161556 | + ** | |
| 161557 | + ** x=5 | |
| 161558 | + ** x=5 AND y=10 | |
| 161559 | + ** x=5 AND y<10 | |
| 161560 | + ** x=5 AND y>5 AND y<10 | |
| 161561 | + ** x=5 AND y=5 AND z<=10 | |
| 161562 | + ** | |
| 161563 | + ** The z<10 term of the following cannot be used, only | |
| 161564 | + ** the x=5 term: | |
| 161565 | + ** | |
| 161566 | + ** x=5 AND z<10 | |
| 161567 | + ** | |
| 161568 | + ** N may be zero if there are inequality constraints. | |
| 161569 | + ** If there are no inequality constraints, then N is at | |
| 161570 | + ** least one. | |
| 161571 | + ** | |
| 161572 | + ** This case is also used when there are no WHERE clause | |
| 161573 | + ** constraints but an index is selected anyway, in order | |
| 161574 | + ** to force the output order to conform to an ORDER BY. | |
| 161445 | 161575 | */ |
| 161446 | 161576 | static const u8 aStartOp[] = { |
| 161447 | 161577 | 0, |
| 161448 | 161578 | 0, |
| 161449 | 161579 | OP_Rewind, /* 2: (!start_constraints && startEq && !bRev) */ |
| @@ -163459,34 +163589,46 @@ | ||
| 163459 | 163589 | ** column references. This routine checks to see if pExpr is an equivalence |
| 163460 | 163590 | ** relation: |
| 163461 | 163591 | ** 1. The SQLITE_Transitive optimization must be enabled |
| 163462 | 163592 | ** 2. Must be either an == or an IS operator |
| 163463 | 163593 | ** 3. Not originating in the ON clause of an OUTER JOIN |
| 163464 | -** 4. The affinities of A and B must be compatible | |
| 163465 | -** 5a. Both operands use the same collating sequence OR | |
| 163466 | -** 5b. The overall collating sequence is BINARY | |
| 163594 | +** 4. The operator is not IS or else the query does not contain RIGHT JOIN | |
| 163595 | +** 5. The affinities of A and B must be compatible | |
| 163596 | +** 6a. Both operands use the same collating sequence OR | |
| 163597 | +** 6b. The overall collating sequence is BINARY | |
| 163467 | 163598 | ** If this routine returns TRUE, that means that the RHS can be substituted |
| 163468 | 163599 | ** for the LHS anyplace else in the WHERE clause where the LHS column occurs. |
| 163469 | 163600 | ** This is an optimization. No harm comes from returning 0. But if 1 is |
| 163470 | 163601 | ** returned when it should not be, then incorrect answers might result. |
| 163471 | 163602 | */ |
| 163472 | -static int termIsEquivalence(Parse *pParse, Expr *pExpr){ | |
| 163603 | +static int termIsEquivalence(Parse *pParse, Expr *pExpr, SrcList *pSrc){ | |
| 163473 | 163604 | char aff1, aff2; |
| 163474 | 163605 | CollSeq *pColl; |
| 163475 | - if( !OptimizationEnabled(pParse->db, SQLITE_Transitive) ) return 0; | |
| 163476 | - if( pExpr->op!=TK_EQ && pExpr->op!=TK_IS ) return 0; | |
| 163477 | - if( ExprHasProperty(pExpr, EP_OuterON) ) return 0; | |
| 163606 | + if( !OptimizationEnabled(pParse->db, SQLITE_Transitive) ) return 0; /* (1) */ | |
| 163607 | + if( pExpr->op!=TK_EQ && pExpr->op!=TK_IS ) return 0; /* (2) */ | |
| 163608 | + if( ExprHasProperty(pExpr, EP_OuterON) ) return 0; /* (3) */ | |
| 163609 | + assert( pSrc!=0 ); | |
| 163610 | + if( pExpr->op==TK_IS | |
| 163611 | + && pSrc->nSrc | |
| 163612 | + && (pSrc->a[0].fg.jointype & JT_LTORJ)!=0 | |
| 163613 | + ){ | |
| 163614 | + return 0; /* (4) */ | |
| 163615 | + } | |
| 163478 | 163616 | aff1 = sqlite3ExprAffinity(pExpr->pLeft); |
| 163479 | 163617 | aff2 = sqlite3ExprAffinity(pExpr->pRight); |
| 163480 | 163618 | if( aff1!=aff2 |
| 163481 | 163619 | && (!sqlite3IsNumericAffinity(aff1) || !sqlite3IsNumericAffinity(aff2)) |
| 163482 | 163620 | ){ |
| 163483 | - return 0; | |
| 163621 | + return 0; /* (5) */ | |
| 163484 | 163622 | } |
| 163485 | 163623 | pColl = sqlite3ExprCompareCollSeq(pParse, pExpr); |
| 163486 | - if( sqlite3IsBinary(pColl) ) return 1; | |
| 163487 | - return sqlite3ExprCollSeqMatch(pParse, pExpr->pLeft, pExpr->pRight); | |
| 163624 | + if( !sqlite3IsBinary(pColl) | |
| 163625 | + && !sqlite3ExprCollSeqMatch(pParse, pExpr->pLeft, pExpr->pRight) | |
| 163626 | + ){ | |
| 163627 | + return 0; /* (6) */ | |
| 163628 | + } | |
| 163629 | + return 1; | |
| 163488 | 163630 | } |
| 163489 | 163631 | |
| 163490 | 163632 | /* |
| 163491 | 163633 | ** Recursively walk the expressions of a SELECT statement and generate |
| 163492 | 163634 | ** a bitmask indicating which tables are used in that expression |
| @@ -163640,10 +163782,13 @@ | ||
| 163640 | 163782 | if( db->mallocFailed ){ |
| 163641 | 163783 | return; |
| 163642 | 163784 | } |
| 163643 | 163785 | assert( pWC->nTerm > idxTerm ); |
| 163644 | 163786 | pTerm = &pWC->a[idxTerm]; |
| 163787 | +#ifdef SQLITE_DEBUG | |
| 163788 | + pTerm->iTerm = idxTerm; | |
| 163789 | +#endif | |
| 163645 | 163790 | pMaskSet = &pWInfo->sMaskSet; |
| 163646 | 163791 | pExpr = pTerm->pExpr; |
| 163647 | 163792 | assert( pExpr!=0 ); /* Because malloc() has not failed */ |
| 163648 | 163793 | assert( pExpr->op!=TK_AS && pExpr->op!=TK_COLLATE ); |
| 163649 | 163794 | pMaskSet->bVarSelect = 0; |
| @@ -163747,12 +163892,12 @@ | ||
| 163747 | 163892 | pNew = &pWC->a[idxNew]; |
| 163748 | 163893 | markTermAsChild(pWC, idxNew, idxTerm); |
| 163749 | 163894 | if( op==TK_IS ) pNew->wtFlags |= TERM_IS; |
| 163750 | 163895 | pTerm = &pWC->a[idxTerm]; |
| 163751 | 163896 | pTerm->wtFlags |= TERM_COPIED; |
| 163752 | - | |
| 163753 | - if( termIsEquivalence(pParse, pDup) ){ | |
| 163897 | + assert( pWInfo->pTabList!=0 ); | |
| 163898 | + if( termIsEquivalence(pParse, pDup, pWInfo->pTabList) ){ | |
| 163754 | 163899 | pTerm->eOperator |= WO_EQUIV; |
| 163755 | 163900 | eExtraOp = WO_EQUIV; |
| 163756 | 163901 | } |
| 163757 | 163902 | }else{ |
| 163758 | 163903 | pDup = pExpr; |
| @@ -164867,15 +165012,15 @@ | ||
| 164867 | 165012 | continue; |
| 164868 | 165013 | } |
| 164869 | 165014 | pScan->pWC = pWC; |
| 164870 | 165015 | pScan->k = k+1; |
| 164871 | 165016 | #ifdef WHERETRACE_ENABLED |
| 164872 | - if( sqlite3WhereTrace & 0x20000 ){ | |
| 165017 | + if( (sqlite3WhereTrace & 0x20000)!=0 && pScan->nEquiv>1 ){ | |
| 164873 | 165018 | int ii; |
| 164874 | - sqlite3DebugPrintf("SCAN-TERM %p: nEquiv=%d", | |
| 164875 | - pTerm, pScan->nEquiv); | |
| 164876 | - for(ii=0; ii<pScan->nEquiv; ii++){ | |
| 165019 | + sqlite3DebugPrintf("EQUIVALENT TO {%d:%d} (due to TERM-%d):", | |
| 165020 | + pScan->aiCur[0], pScan->aiColumn[0], pTerm->iTerm); | |
| 165021 | + for(ii=1; ii<pScan->nEquiv; ii++){ | |
| 164877 | 165022 | sqlite3DebugPrintf(" {%d:%d}", |
| 164878 | 165023 | pScan->aiCur[ii], pScan->aiColumn[ii]); |
| 164879 | 165024 | } |
| 164880 | 165025 | sqlite3DebugPrintf("\n"); |
| 164881 | 165026 | } |
| @@ -166826,10 +166971,11 @@ | ||
| 166826 | 166971 | sqlite3_snprintf(sizeof(zLeft),zLeft,"indexable=0x%llx", |
| 166827 | 166972 | pTerm->u.pOrInfo->indexable); |
| 166828 | 166973 | }else{ |
| 166829 | 166974 | sqlite3_snprintf(sizeof(zLeft),zLeft,"left=%d", pTerm->leftCursor); |
| 166830 | 166975 | } |
| 166976 | + iTerm = pTerm->iTerm = MAX(iTerm,pTerm->iTerm); | |
| 166831 | 166977 | sqlite3DebugPrintf( |
| 166832 | 166978 | "TERM-%-3d %p %s %-12s op=%03x wtFlags=%04x", |
| 166833 | 166979 | iTerm, pTerm, zType, zLeft, pTerm->eOperator, pTerm->wtFlags); |
| 166834 | 166980 | /* The 0x10000 .wheretrace flag causes extra information to be |
| 166835 | 166981 | ** shown about each Term */ |
| @@ -184450,10 +184596,11 @@ | ||
| 184450 | 184596 | #ifdef SQLITE_ENABLE_API_ARMOR |
| 184451 | 184597 | if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; |
| 184452 | 184598 | #endif |
| 184453 | 184599 | if( ms<-1 ) return SQLITE_RANGE; |
| 184454 | 184600 | #ifdef SQLITE_ENABLE_SETLK_TIMEOUT |
| 184601 | + sqlite3_mutex_enter(db->mutex); | |
| 184455 | 184602 | db->setlkTimeout = ms; |
| 184456 | 184603 | db->setlkFlags = flags; |
| 184457 | 184604 | sqlite3BtreeEnterAll(db); |
| 184458 | 184605 | for(iDb=0; iDb<db->nDb; iDb++){ |
| 184459 | 184606 | Btree *pBt = db->aDb[iDb].pBt; |
| @@ -184461,10 +184608,11 @@ | ||
| 184461 | 184608 | sqlite3_file *fd = sqlite3PagerFile(sqlite3BtreePager(pBt)); |
| 184462 | 184609 | sqlite3OsFileControlHint(fd, SQLITE_FCNTL_BLOCK_ON_CONNECT, (void*)&bBOC); |
| 184463 | 184610 | } |
| 184464 | 184611 | } |
| 184465 | 184612 | sqlite3BtreeLeaveAll(db); |
| 184613 | + sqlite3_mutex_leave(db->mutex); | |
| 184466 | 184614 | #endif |
| 184467 | 184615 | #if !defined(SQLITE_ENABLE_API_ARMOR) && !defined(SQLITE_ENABLE_SETLK_TIMEOUT) |
| 184468 | 184616 | UNUSED_PARAMETER(db); |
| 184469 | 184617 | UNUSED_PARAMETER(flags); |
| 184470 | 184618 | #endif |
| @@ -257257,11 +257405,11 @@ | ||
| 257257 | 257405 | int nArg, /* Number of args */ |
| 257258 | 257406 | sqlite3_value **apUnused /* Function arguments */ |
| 257259 | 257407 | ){ |
| 257260 | 257408 | assert( nArg==0 ); |
| 257261 | 257409 | UNUSED_PARAM2(nArg, apUnused); |
| 257262 | - sqlite3_result_text(pCtx, "fts5: 2025-06-03 10:49:51 ea1754f7d8a770477a1b19b606b27724fdc0b733e51fef32c1ef834f972c3cc5", -1, SQLITE_TRANSIENT); | |
| 257410 | + sqlite3_result_text(pCtx, "fts5: 2025-06-19 20:19:12 a88bb75288a06492a04ab1278e8a2101a74f4ba712d328b4c73e86ac01cb946d", -1, SQLITE_TRANSIENT); | |
| 257263 | 257411 | } |
| 257264 | 257412 | |
| 257265 | 257413 | /* |
| 257266 | 257414 | ** Implementation of fts5_locale(LOCALE, TEXT) function. |
| 257267 | 257415 | ** |
| @@ -258072,10 +258220,11 @@ | ||
| 258072 | 258220 | ctx.pStorage = p; |
| 258073 | 258221 | ctx.iCol = -1; |
| 258074 | 258222 | for(iCol=1; rc==SQLITE_OK && iCol<=pConfig->nCol; iCol++){ |
| 258075 | 258223 | if( pConfig->abUnindexed[iCol-1]==0 ){ |
| 258076 | 258224 | sqlite3_value *pVal = 0; |
| 258225 | + sqlite3_value *pFree = 0; | |
| 258077 | 258226 | const char *pText = 0; |
| 258078 | 258227 | int nText = 0; |
| 258079 | 258228 | const char *pLoc = 0; |
| 258080 | 258229 | int nLoc = 0; |
| 258081 | 258230 | |
| @@ -258088,15 +258237,26 @@ | ||
| 258088 | 258237 | } |
| 258089 | 258238 | |
| 258090 | 258239 | if( pConfig->bLocale && sqlite3Fts5IsLocaleValue(pConfig, pVal) ){ |
| 258091 | 258240 | rc = sqlite3Fts5DecodeLocaleValue(pVal, &pText, &nText, &pLoc, &nLoc); |
| 258092 | 258241 | }else{ |
| 258093 | - pText = (const char*)sqlite3_value_text(pVal); | |
| 258094 | - nText = sqlite3_value_bytes(pVal); | |
| 258095 | - if( pConfig->bLocale && pSeek ){ | |
| 258096 | - pLoc = (const char*)sqlite3_column_text(pSeek, iCol + pConfig->nCol); | |
| 258097 | - nLoc = sqlite3_column_bytes(pSeek, iCol + pConfig->nCol); | |
| 258242 | + if( sqlite3_value_type(pVal)!=SQLITE_TEXT ){ | |
| 258243 | + /* Make a copy of the value to work with. This is because the call | |
| 258244 | + ** to sqlite3_value_text() below forces the type of the value to | |
| 258245 | + ** SQLITE_TEXT, and we may need to use it again later. */ | |
| 258246 | + pFree = pVal = sqlite3_value_dup(pVal); | |
| 258247 | + if( pVal==0 ){ | |
| 258248 | + rc = SQLITE_NOMEM; | |
| 258249 | + } | |
| 258250 | + } | |
| 258251 | + if( rc==SQLITE_OK ){ | |
| 258252 | + pText = (const char*)sqlite3_value_text(pVal); | |
| 258253 | + nText = sqlite3_value_bytes(pVal); | |
| 258254 | + if( pConfig->bLocale && pSeek ){ | |
| 258255 | + pLoc = (const char*)sqlite3_column_text(pSeek, iCol+pConfig->nCol); | |
| 258256 | + nLoc = sqlite3_column_bytes(pSeek, iCol + pConfig->nCol); | |
| 258257 | + } | |
| 258098 | 258258 | } |
| 258099 | 258259 | } |
| 258100 | 258260 | |
| 258101 | 258261 | if( rc==SQLITE_OK ){ |
| 258102 | 258262 | sqlite3Fts5SetLocale(pConfig, pLoc, nLoc); |
| @@ -258108,10 +258268,11 @@ | ||
| 258108 | 258268 | if( rc==SQLITE_OK && p->aTotalSize[iCol-1]<0 ){ |
| 258109 | 258269 | rc = FTS5_CORRUPT; |
| 258110 | 258270 | } |
| 258111 | 258271 | sqlite3Fts5ClearLocale(pConfig); |
| 258112 | 258272 | } |
| 258273 | + sqlite3_value_free(pFree); | |
| 258113 | 258274 | } |
| 258114 | 258275 | } |
| 258115 | 258276 | if( rc==SQLITE_OK && p->nTotalRow<1 ){ |
| 258116 | 258277 | rc = FTS5_CORRUPT; |
| 258117 | 258278 | }else{ |
| 258118 | 258279 |
| --- extsrc/sqlite3.c | |
| +++ extsrc/sqlite3.c | |
| @@ -16,11 +16,11 @@ | |
| 16 | ** if you want a wrapper to interface SQLite with your choice of programming |
| 17 | ** language. The code for the "sqlite3" command-line shell is also in a |
| 18 | ** separate file. This file contains only code for the core SQLite library. |
| 19 | ** |
| 20 | ** The content in this amalgamation comes from Fossil check-in |
| 21 | ** ea1754f7d8a770477a1b19b606b27724fdc0 with changes in files: |
| 22 | ** |
| 23 | ** |
| 24 | */ |
| 25 | #ifndef SQLITE_AMALGAMATION |
| 26 | #define SQLITE_CORE 1 |
| @@ -465,11 +465,11 @@ | |
| 465 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 466 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 467 | */ |
| 468 | #define SQLITE_VERSION "3.51.0" |
| 469 | #define SQLITE_VERSION_NUMBER 3051000 |
| 470 | #define SQLITE_SOURCE_ID "2025-06-03 10:49:51 ea1754f7d8a770477a1b19b606b27724fdc0b733e51fef32c1ef834f972c3cc5" |
| 471 | |
| 472 | /* |
| 473 | ** CAPI3REF: Run-Time Library Version Numbers |
| 474 | ** KEYWORDS: sqlite3_version sqlite3_sourceid |
| 475 | ** |
| @@ -4396,11 +4396,11 @@ | |
| 4396 | ** These interfaces are provided for use by [VFS shim] implementations and |
| 4397 | ** are not useful outside of that context. |
| 4398 | ** |
| 4399 | ** The sqlite3_create_filename(D,J,W,N,P) allocates memory to hold a version of |
| 4400 | ** database filename D with corresponding journal file J and WAL file W and |
| 4401 | ** with N URI parameters key/values pairs in the array P. The result from |
| 4402 | ** sqlite3_create_filename(D,J,W,N,P) is a pointer to a database filename that |
| 4403 | ** is safe to pass to routines like: |
| 4404 | ** <ul> |
| 4405 | ** <li> [sqlite3_uri_parameter()], |
| 4406 | ** <li> [sqlite3_uri_boolean()], |
| @@ -5077,11 +5077,11 @@ | |
| 5077 | ** KEYWORDS: {host parameter} {host parameters} {host parameter name} |
| 5078 | ** KEYWORDS: {SQL parameter} {SQL parameters} {parameter binding} |
| 5079 | ** METHOD: sqlite3_stmt |
| 5080 | ** |
| 5081 | ** ^(In the SQL statement text input to [sqlite3_prepare_v2()] and its variants, |
| 5082 | ** literals may be replaced by a [parameter] that matches one of following |
| 5083 | ** templates: |
| 5084 | ** |
| 5085 | ** <ul> |
| 5086 | ** <li> ? |
| 5087 | ** <li> ?NNN |
| @@ -5122,11 +5122,11 @@ | |
| 5122 | ** either UTF8 if the sixth parameter is SQLITE_UTF8, or UTF16 |
| 5123 | ** otherwise. |
| 5124 | ** |
| 5125 | ** [[byte-order determination rules]] ^The byte-order of |
| 5126 | ** UTF16 input text is determined by the byte-order mark (BOM, U+FEFF) |
| 5127 | ** found in first character, which is removed, or in the absence of a BOM |
| 5128 | ** the byte order is the native byte order of the host |
| 5129 | ** machine for sqlite3_bind_text16() or the byte order specified in |
| 5130 | ** the 6th parameter for sqlite3_bind_text64().)^ |
| 5131 | ** ^If UTF16 input text contains invalid unicode |
| 5132 | ** characters, then SQLite might change those invalid characters |
| @@ -5142,11 +5142,11 @@ | |
| 5142 | ** the behavior is undefined. |
| 5143 | ** If a non-negative fourth parameter is provided to sqlite3_bind_text() |
| 5144 | ** or sqlite3_bind_text16() or sqlite3_bind_text64() then |
| 5145 | ** that parameter must be the byte offset |
| 5146 | ** where the NUL terminator would occur assuming the string were NUL |
| 5147 | ** terminated. If any NUL characters occurs at byte offsets less than |
| 5148 | ** the value of the fourth parameter then the resulting string value will |
| 5149 | ** contain embedded NULs. The result of expressions involving strings |
| 5150 | ** with embedded NULs is undefined. |
| 5151 | ** |
| 5152 | ** ^The fifth argument to the BLOB and string binding interfaces controls |
| @@ -5354,11 +5354,11 @@ | |
| 5354 | /* |
| 5355 | ** CAPI3REF: Source Of Data In A Query Result |
| 5356 | ** METHOD: sqlite3_stmt |
| 5357 | ** |
| 5358 | ** ^These routines provide a means to determine the database, table, and |
| 5359 | ** table column that is the origin of a particular result column in |
| 5360 | ** [SELECT] statement. |
| 5361 | ** ^The name of the database or table or column can be returned as |
| 5362 | ** either a UTF-8 or UTF-16 string. ^The _database_ routines return |
| 5363 | ** the database name, the _table_ routines return the table name, and |
| 5364 | ** the origin_ routines return the column name. |
| @@ -5923,12 +5923,12 @@ | |
| 5923 | ** within VIEWs, TRIGGERs, CHECK constraints, generated column expressions, |
| 5924 | ** index expressions, or the WHERE clause of partial indexes. |
| 5925 | ** |
| 5926 | ** For best security, the [SQLITE_DIRECTONLY] flag is recommended for |
| 5927 | ** all application-defined SQL functions that do not need to be |
| 5928 | ** used inside of triggers, view, CHECK constraints, or other elements of |
| 5929 | ** the database schema. This flags is especially recommended for SQL |
| 5930 | ** functions that have side effects or reveal internal application state. |
| 5931 | ** Without this flag, an attacker might be able to modify the schema of |
| 5932 | ** a database file to include invocations of the function with parameters |
| 5933 | ** chosen by the attacker, which the application will then execute when |
| 5934 | ** the database file is opened and read. |
| @@ -5955,11 +5955,11 @@ | |
| 5955 | ** or aggregate window function. More details regarding the implementation |
| 5956 | ** of aggregate window functions are |
| 5957 | ** [user-defined window functions|available here]. |
| 5958 | ** |
| 5959 | ** ^(If the final parameter to sqlite3_create_function_v2() or |
| 5960 | ** sqlite3_create_window_function() is not NULL, then it is destructor for |
| 5961 | ** the application data pointer. The destructor is invoked when the function |
| 5962 | ** is deleted, either by being overloaded or when the database connection |
| 5963 | ** closes.)^ ^The destructor is also invoked if the call to |
| 5964 | ** sqlite3_create_function_v2() fails. ^When the destructor callback is |
| 5965 | ** invoked, it is passed a single argument which is a copy of the application |
| @@ -7763,11 +7763,11 @@ | |
| 7763 | ** that is to be automatically loaded into all new database connections. |
| 7764 | ** |
| 7765 | ** ^(Even though the function prototype shows that xEntryPoint() takes |
| 7766 | ** no arguments and returns void, SQLite invokes xEntryPoint() with three |
| 7767 | ** arguments and expects an integer result as if the signature of the |
| 7768 | ** entry point where as follows: |
| 7769 | ** |
| 7770 | ** <blockquote><pre> |
| 7771 | ** int xEntryPoint( |
| 7772 | ** sqlite3 *db, |
| 7773 | ** const char **pzErrMsg, |
| @@ -8094,11 +8094,11 @@ | |
| 8094 | ** by the first parameter. ^The name of the module is given by the |
| 8095 | ** second parameter. ^The third parameter is a pointer to |
| 8096 | ** the implementation of the [virtual table module]. ^The fourth |
| 8097 | ** parameter is an arbitrary client data pointer that is passed through |
| 8098 | ** into the [xCreate] and [xConnect] methods of the virtual table module |
| 8099 | ** when a new virtual table is be being created or reinitialized. |
| 8100 | ** |
| 8101 | ** ^The sqlite3_create_module_v2() interface has a fifth parameter which |
| 8102 | ** is a pointer to a destructor for the pClientData. ^SQLite will |
| 8103 | ** invoke the destructor function (if it is not NULL) when SQLite |
| 8104 | ** no longer needs the pClientData pointer. ^The destructor will also |
| @@ -8259,11 +8259,11 @@ | |
| 8259 | ** |
| 8260 | ** ^(On success, [SQLITE_OK] is returned and the new [BLOB handle] is stored |
| 8261 | ** in *ppBlob. Otherwise an [error code] is returned and, unless the error |
| 8262 | ** code is SQLITE_MISUSE, *ppBlob is set to NULL.)^ ^This means that, provided |
| 8263 | ** the API is not misused, it is always safe to call [sqlite3_blob_close()] |
| 8264 | ** on *ppBlob after this function it returns. |
| 8265 | ** |
| 8266 | ** This function fails with SQLITE_ERROR if any of the following are true: |
| 8267 | ** <ul> |
| 8268 | ** <li> ^(Database zDb does not exist)^, |
| 8269 | ** <li> ^(Table zTable does not exist within database zDb)^, |
| @@ -8379,11 +8379,11 @@ | |
| 8379 | ** CAPI3REF: Return The Size Of An Open BLOB |
| 8380 | ** METHOD: sqlite3_blob |
| 8381 | ** |
| 8382 | ** ^Returns the size in bytes of the BLOB accessible via the |
| 8383 | ** successfully opened [BLOB handle] in its only argument. ^The |
| 8384 | ** incremental blob I/O routines can only read or overwriting existing |
| 8385 | ** blob content; they cannot change the size of a blob. |
| 8386 | ** |
| 8387 | ** This routine only works on a [BLOB handle] which has been created |
| 8388 | ** by a prior successful call to [sqlite3_blob_open()] and which has not |
| 8389 | ** been closed by [sqlite3_blob_close()]. Passing any other pointer in |
| @@ -9782,11 +9782,11 @@ | |
| 9782 | ** sqlite3_backup_step(), the source database may be modified mid-way |
| 9783 | ** through the backup process. ^If the source database is modified by an |
| 9784 | ** external process or via a database connection other than the one being |
| 9785 | ** used by the backup operation, then the backup will be automatically |
| 9786 | ** restarted by the next call to sqlite3_backup_step(). ^If the source |
| 9787 | ** database is modified by the using the same database connection as is used |
| 9788 | ** by the backup operation, then the backup database is automatically |
| 9789 | ** updated at the same time. |
| 9790 | ** |
| 9791 | ** [[sqlite3_backup_finish()]] <b>sqlite3_backup_finish()</b> |
| 9792 | ** |
| @@ -9799,11 +9799,11 @@ | |
| 9799 | ** active write-transaction on the destination database is rolled back. |
| 9800 | ** The [sqlite3_backup] object is invalid |
| 9801 | ** and may not be used following a call to sqlite3_backup_finish(). |
| 9802 | ** |
| 9803 | ** ^The value returned by sqlite3_backup_finish is [SQLITE_OK] if no |
| 9804 | ** sqlite3_backup_step() errors occurred, regardless or whether or not |
| 9805 | ** sqlite3_backup_step() completed. |
| 9806 | ** ^If an out-of-memory condition or IO error occurred during any prior |
| 9807 | ** sqlite3_backup_step() call on the same [sqlite3_backup] object, then |
| 9808 | ** sqlite3_backup_finish() returns the corresponding [error code]. |
| 9809 | ** |
| @@ -10869,11 +10869,11 @@ | |
| 10869 | /* |
| 10870 | ** CAPI3REF: Flush caches to disk mid-transaction |
| 10871 | ** METHOD: sqlite3 |
| 10872 | ** |
| 10873 | ** ^If a write-transaction is open on [database connection] D when the |
| 10874 | ** [sqlite3_db_cacheflush(D)] interface invoked, any dirty |
| 10875 | ** pages in the pager-cache that are not currently in use are written out |
| 10876 | ** to disk. A dirty page may be in use if a database cursor created by an |
| 10877 | ** active SQL statement is reading from it, or if it is page 1 of a database |
| 10878 | ** file (page 1 is always "in use"). ^The [sqlite3_db_cacheflush(D)] |
| 10879 | ** interface flushes caches for all schemas - "main", "temp", and |
| @@ -15562,10 +15562,11 @@ | |
| 15562 | ** 0x00008000 After all FROM-clause analysis |
| 15563 | ** 0x00010000 Beginning of DELETE/INSERT/UPDATE processing |
| 15564 | ** 0x00020000 Transform DISTINCT into GROUP BY |
| 15565 | ** 0x00040000 SELECT tree dump after all code has been generated |
| 15566 | ** 0x00080000 NOT NULL strength reduction |
| 15567 | */ |
| 15568 | |
| 15569 | /* |
| 15570 | ** Macros for "wheretrace" |
| 15571 | */ |
| @@ -15606,10 +15607,11 @@ | |
| 15606 | ** |
| 15607 | ** 0x00010000 Show more detail when printing WHERE terms |
| 15608 | ** 0x00020000 Show WHERE terms returned from whereScanNext() |
| 15609 | ** 0x00040000 Solver overview messages |
| 15610 | ** 0x00080000 Star-query heuristic |
| 15611 | */ |
| 15612 | |
| 15613 | |
| 15614 | /* |
| 15615 | ** An instance of the following structure is used to store the busy-handler |
| @@ -15678,11 +15680,11 @@ | |
| 15678 | ** one parameter that destructors normally want. So we have to introduce |
| 15679 | ** this magic value that the code knows to handle differently. Any |
| 15680 | ** pointer will work here as long as it is distinct from SQLITE_STATIC |
| 15681 | ** and SQLITE_TRANSIENT. |
| 15682 | */ |
| 15683 | #define SQLITE_DYNAMIC ((sqlite3_destructor_type)sqlite3OomClear) |
| 15684 | |
| 15685 | /* |
| 15686 | ** When SQLITE_OMIT_WSD is defined, it means that the target platform does |
| 15687 | ** not support Writable Static Data (WSD) such as global and static variables. |
| 15688 | ** All variables must either be on the stack or dynamically allocated from |
| @@ -21266,10 +21268,11 @@ | |
| 21266 | #endif |
| 21267 | #ifndef SQLITE_OMIT_WINDOWFUNC |
| 21268 | SQLITE_PRIVATE void sqlite3ShowWindow(const Window*); |
| 21269 | SQLITE_PRIVATE void sqlite3ShowWinFunc(const Window*); |
| 21270 | #endif |
| 21271 | #endif |
| 21272 | |
| 21273 | SQLITE_PRIVATE void sqlite3SetString(char **, sqlite3*, const char*); |
| 21274 | SQLITE_PRIVATE void sqlite3ProgressCheck(Parse*); |
| 21275 | SQLITE_PRIVATE void sqlite3ErrorMsg(Parse*, const char*, ...); |
| @@ -32077,10 +32080,18 @@ | |
| 32077 | }else{ |
| 32078 | longvalue = va_arg(ap,unsigned int); |
| 32079 | } |
| 32080 | prefix = 0; |
| 32081 | } |
| 32082 | if( longvalue==0 ) flag_alternateform = 0; |
| 32083 | if( flag_zeropad && precision<width-(prefix!=0) ){ |
| 32084 | precision = width-(prefix!=0); |
| 32085 | } |
| 32086 | if( precision<etBUFSIZE-10-etBUFSIZE/3 ){ |
| @@ -54872,10 +54883,11 @@ | |
| 54872 | BITVEC_TELEM aBitmap[BITVEC_NELEM]; /* Bitmap representation */ |
| 54873 | u32 aHash[BITVEC_NINT]; /* Hash table representation */ |
| 54874 | Bitvec *apSub[BITVEC_NPTR]; /* Recursive representation */ |
| 54875 | } u; |
| 54876 | }; |
| 54877 | |
| 54878 | /* |
| 54879 | ** Create a new bitmap object able to handle bits between 0 and iSize, |
| 54880 | ** inclusive. Return a pointer to the new object. Return NULL if |
| 54881 | ** malloc fails. |
| @@ -54982,11 +54994,13 @@ | |
| 54982 | if( aiValues==0 ){ |
| 54983 | return SQLITE_NOMEM_BKPT; |
| 54984 | }else{ |
| 54985 | memcpy(aiValues, p->u.aHash, sizeof(p->u.aHash)); |
| 54986 | memset(p->u.apSub, 0, sizeof(p->u.apSub)); |
| 54987 | p->iDivisor = (p->iSize + BITVEC_NPTR - 1)/BITVEC_NPTR; |
| 54988 | rc = sqlite3BitvecSet(p, i); |
| 54989 | for(j=0; j<BITVEC_NINT; j++){ |
| 54990 | if( aiValues[j] ) rc |= sqlite3BitvecSet(p, aiValues[j]); |
| 54991 | } |
| 54992 | sqlite3StackFree(0, aiValues); |
| @@ -55058,10 +55072,56 @@ | |
| 55058 | ** was created. |
| 55059 | */ |
| 55060 | SQLITE_PRIVATE u32 sqlite3BitvecSize(Bitvec *p){ |
| 55061 | return p->iSize; |
| 55062 | } |
| 55063 | |
| 55064 | #ifndef SQLITE_UNTESTABLE |
| 55065 | /* |
| 55066 | ** Let V[] be an array of unsigned characters sufficient to hold |
| 55067 | ** up to N bits. Let I be an integer between 0 and N. 0<=I<N. |
| @@ -55069,40 +55129,48 @@ | |
| 55069 | ** individual bits within V. |
| 55070 | */ |
| 55071 | #define SETBIT(V,I) V[I>>3] |= (1<<(I&7)) |
| 55072 | #define CLEARBIT(V,I) V[I>>3] &= ~(BITVEC_TELEM)(1<<(I&7)) |
| 55073 | #define TESTBIT(V,I) (V[I>>3]&(1<<(I&7)))!=0 |
| 55074 | |
| 55075 | /* |
| 55076 | ** This routine runs an extensive test of the Bitvec code. |
| 55077 | ** |
| 55078 | ** The input is an array of integers that acts as a program |
| 55079 | ** to test the Bitvec. The integers are opcodes followed |
| 55080 | ** by 0, 1, or 3 operands, depending on the opcode. Another |
| 55081 | ** opcode follows immediately after the last operand. |
| 55082 | ** |
| 55083 | ** There are 6 opcodes numbered from 0 through 5. 0 is the |
| 55084 | ** "halt" opcode and causes the test to end. |
| 55085 | ** |
| 55086 | ** 0 Halt and return the number of errors |
| 55087 | ** 1 N S X Set N bits beginning with S and incrementing by X |
| 55088 | ** 2 N S X Clear N bits beginning with S and incrementing by X |
| 55089 | ** 3 N Set N randomly chosen bits |
| 55090 | ** 4 N Clear N randomly chosen bits |
| 55091 | ** 5 N S X Set N bits from S increment X in array only, not in bitvec |
| 55092 | ** |
| 55093 | ** The opcodes 1 through 4 perform set and clear operations are performed |
| 55094 | ** on both a Bitvec object and on a linear array of bits obtained from malloc. |
| 55095 | ** Opcode 5 works on the linear array only, not on the Bitvec. |
| 55096 | ** Opcode 5 is used to deliberately induce a fault in order to |
| 55097 | ** confirm that error detection works. |
| 55098 | ** |
| 55099 | ** At the conclusion of the test the linear array is compared |
| 55100 | ** against the Bitvec object. If there are any differences, |
| 55101 | ** an error is returned. If they are the same, zero is returned. |
| 55102 | ** |
| 55103 | ** If a memory allocation error occurs, return -1. |
| 55104 | */ |
| 55105 | SQLITE_PRIVATE int sqlite3BitvecBuiltinTest(int sz, int *aOp){ |
| 55106 | Bitvec *pBitvec = 0; |
| 55107 | unsigned char *pV = 0; |
| 55108 | int rc = -1; |
| @@ -55109,22 +55177,45 @@ | |
| 55109 | int i, nx, pc, op; |
| 55110 | void *pTmpSpace; |
| 55111 | |
| 55112 | /* Allocate the Bitvec to be tested and a linear array of |
| 55113 | ** bits to act as the reference */ |
| 55114 | pBitvec = sqlite3BitvecCreate( sz ); |
| 55115 | pV = sqlite3MallocZero( (7+(i64)sz)/8 + 1 ); |
| 55116 | pTmpSpace = sqlite3_malloc64(BITVEC_SZ); |
| 55117 | if( pBitvec==0 || pV==0 || pTmpSpace==0 ) goto bitvec_end; |
| 55118 | |
| 55119 | /* NULL pBitvec tests */ |
| 55120 | sqlite3BitvecSet(0, 1); |
| 55121 | sqlite3BitvecClear(0, 1, pTmpSpace); |
| 55122 | |
| 55123 | /* Run the program */ |
| 55124 | pc = i = 0; |
| 55125 | while( (op = aOp[pc])!=0 ){ |
| 55126 | switch( op ){ |
| 55127 | case 1: |
| 55128 | case 2: |
| 55129 | case 5: { |
| 55130 | nx = 4; |
| @@ -55142,33 +55233,37 @@ | |
| 55142 | } |
| 55143 | if( (--aOp[pc+1]) > 0 ) nx = 0; |
| 55144 | pc += nx; |
| 55145 | i = (i & 0x7fffffff)%sz; |
| 55146 | if( (op & 1)!=0 ){ |
| 55147 | SETBIT(pV, (i+1)); |
| 55148 | if( op!=5 ){ |
| 55149 | if( sqlite3BitvecSet(pBitvec, i+1) ) goto bitvec_end; |
| 55150 | } |
| 55151 | }else{ |
| 55152 | CLEARBIT(pV, (i+1)); |
| 55153 | sqlite3BitvecClear(pBitvec, i+1, pTmpSpace); |
| 55154 | } |
| 55155 | } |
| 55156 | |
| 55157 | /* Test to make sure the linear array exactly matches the |
| 55158 | ** Bitvec object. Start with the assumption that they do |
| 55159 | ** match (rc==0). Change rc to non-zero if a discrepancy |
| 55160 | ** is found. |
| 55161 | */ |
| 55162 | rc = sqlite3BitvecTest(0,0) + sqlite3BitvecTest(pBitvec, sz+1) |
| 55163 | + sqlite3BitvecTest(pBitvec, 0) |
| 55164 | + (sqlite3BitvecSize(pBitvec) - sz); |
| 55165 | for(i=1; i<=sz; i++){ |
| 55166 | if( (TESTBIT(pV,i))!=sqlite3BitvecTest(pBitvec,i) ){ |
| 55167 | rc = i; |
| 55168 | break; |
| 55169 | } |
| 55170 | } |
| 55171 | |
| 55172 | /* Free allocated structure */ |
| 55173 | bitvec_end: |
| 55174 | sqlite3_free(pTmpSpace); |
| @@ -69670,10 +69765,11 @@ | |
| 69670 | rc = xUndo(pUndoCtx, walFramePgno(pWal, iFrame)); |
| 69671 | } |
| 69672 | if( iMax!=pWal->hdr.mxFrame ) walCleanupHash(pWal); |
| 69673 | } |
| 69674 | SEH_EXCEPT( rc = SQLITE_IOERR_IN_PAGE; ) |
| 69675 | } |
| 69676 | return rc; |
| 69677 | } |
| 69678 | |
| 69679 | /* |
| @@ -69717,10 +69813,13 @@ | |
| 69717 | pWal->hdr.aFrameCksum[1] = aWalData[2]; |
| 69718 | SEH_TRY { |
| 69719 | walCleanupHash(pWal); |
| 69720 | } |
| 69721 | SEH_EXCEPT( rc = SQLITE_IOERR_IN_PAGE; ) |
| 69722 | } |
| 69723 | |
| 69724 | return rc; |
| 69725 | } |
| 69726 | |
| @@ -77442,12 +77541,12 @@ | |
| 77442 | assert( (pCur->curFlags & BTCF_ValidOvfl)==0 ); |
| 77443 | return rc; |
| 77444 | } |
| 77445 | |
| 77446 | /* |
| 77447 | ** Compare the "idx"-th cell on the page the cursor pCur is currently |
| 77448 | ** pointing to to pIdxKey using xRecordCompare. Return negative or |
| 77449 | ** zero if the cell is less than or equal pIdxKey. Return positive |
| 77450 | ** if unknown. |
| 77451 | ** |
| 77452 | ** Return value negative: Cell at pCur[idx] less than pIdxKey |
| 77453 | ** |
| @@ -77458,16 +77557,15 @@ | |
| 77458 | ** |
| 77459 | ** This routine is part of an optimization. It is always safe to return |
| 77460 | ** a positive value as that will cause the optimization to be skipped. |
| 77461 | */ |
| 77462 | static int indexCellCompare( |
| 77463 | BtCursor *pCur, |
| 77464 | int idx, |
| 77465 | UnpackedRecord *pIdxKey, |
| 77466 | RecordCompare xRecordCompare |
| 77467 | ){ |
| 77468 | MemPage *pPage = pCur->pPage; |
| 77469 | int c; |
| 77470 | int nCell; /* Size of the pCell cell in bytes */ |
| 77471 | u8 *pCell = findCellPastPtr(pPage, idx); |
| 77472 | |
| 77473 | nCell = pCell[0]; |
| @@ -77572,18 +77670,18 @@ | |
| 77572 | && pCur->pPage->leaf |
| 77573 | && cursorOnLastPage(pCur) |
| 77574 | ){ |
| 77575 | int c; |
| 77576 | if( pCur->ix==pCur->pPage->nCell-1 |
| 77577 | && (c = indexCellCompare(pCur, pCur->ix, pIdxKey, xRecordCompare))<=0 |
| 77578 | && pIdxKey->errCode==SQLITE_OK |
| 77579 | ){ |
| 77580 | *pRes = c; |
| 77581 | return SQLITE_OK; /* Cursor already pointing at the correct spot */ |
| 77582 | } |
| 77583 | if( pCur->iPage>0 |
| 77584 | && indexCellCompare(pCur, 0, pIdxKey, xRecordCompare)<=0 |
| 77585 | && pIdxKey->errCode==SQLITE_OK |
| 77586 | ){ |
| 77587 | pCur->curFlags &= ~(BTCF_ValidOvfl|BTCF_AtLast); |
| 77588 | if( !pCur->pPage->isInit ){ |
| 77589 | return SQLITE_CORRUPT_BKPT; |
| @@ -77796,11 +77894,11 @@ | |
| 77796 | if( pCur->eState!=CURSOR_VALID ) return 0; |
| 77797 | if( NEVER(pCur->pPage->leaf==0) ) return -1; |
| 77798 | |
| 77799 | n = pCur->pPage->nCell; |
| 77800 | for(i=0; i<pCur->iPage; i++){ |
| 77801 | n *= pCur->apPage[i]->nCell; |
| 77802 | } |
| 77803 | return n; |
| 77804 | } |
| 77805 | |
| 77806 | /* |
| @@ -97581,10 +97679,19 @@ | |
| 97581 | ** Synopsis: typecheck(r[P1@P2]) |
| 97582 | ** |
| 97583 | ** Apply affinities to the range of P2 registers beginning with P1. |
| 97584 | ** Take the affinities from the Table object in P4. If any value |
| 97585 | ** cannot be coerced into the correct type, then raise an error. |
| 97586 | ** |
| 97587 | ** This opcode is similar to OP_Affinity except that this opcode |
| 97588 | ** forces the register type to the Table column type. This is used |
| 97589 | ** to implement "strict affinity". |
| 97590 | ** |
| @@ -97595,30 +97702,42 @@ | |
| 97595 | ** |
| 97596 | ** Preconditions: |
| 97597 | ** |
| 97598 | ** <ul> |
| 97599 | ** <li> P2 should be the number of non-virtual columns in the |
| 97600 | ** table of P4. |
| 97601 | ** <li> Table P4 should be a STRICT table. |
| 97602 | ** </ul> |
| 97603 | ** |
| 97604 | ** If any precondition is false, an assertion fault occurs. |
| 97605 | */ |
| 97606 | case OP_TypeCheck: { |
| 97607 | Table *pTab; |
| 97608 | Column *aCol; |
| 97609 | int i; |
| 97610 | |
| 97611 | assert( pOp->p4type==P4_TABLE ); |
| 97612 | pTab = pOp->p4.pTab; |
| 97613 | assert( pTab->tabFlags & TF_Strict ); |
| 97614 | assert( pTab->nNVCol==pOp->p2 ); |
| 97615 | aCol = pTab->aCol; |
| 97616 | pIn1 = &aMem[pOp->p1]; |
| 97617 | for(i=0; i<pTab->nCol; i++){ |
| 97618 | if( aCol[i].colFlags & COLFLAG_GENERATED ){ |
| 97619 | if( aCol[i].colFlags & COLFLAG_VIRTUAL ) continue; |
| 97620 | if( pOp->p3 ){ pIn1++; continue; } |
| 97621 | } |
| 97622 | assert( pIn1 < &aMem[pOp->p1+pOp->p2] ); |
| 97623 | applyAffinity(pIn1, aCol[i].affinity, encoding); |
| 97624 | if( (pIn1->flags & MEM_Null)==0 ){ |
| @@ -114626,11 +114745,16 @@ | |
| 114626 | iAddr = sqlite3VdbeAddOp3(v, OP_IfNullRow, pParse->iSelfTab-1, 0, regOut); |
| 114627 | }else{ |
| 114628 | iAddr = 0; |
| 114629 | } |
| 114630 | sqlite3ExprCodeCopy(pParse, sqlite3ColumnExpr(pTab,pCol), regOut); |
| 114631 | if( pCol->affinity>=SQLITE_AFF_TEXT ){ |
| 114632 | sqlite3VdbeAddOp4(v, OP_Affinity, regOut, 1, 0, &pCol->affinity, 1); |
| 114633 | } |
| 114634 | if( iAddr ) sqlite3VdbeJumpHere(v, iAddr); |
| 114635 | if( pParse->nErr>nErr ) pParse->db->errByteOffset = -1; |
| 114636 | } |
| @@ -132020,11 +132144,11 @@ | |
| 132020 | int argc, |
| 132021 | sqlite3_value **argv, |
| 132022 | int nSep, |
| 132023 | const char *zSep |
| 132024 | ){ |
| 132025 | i64 j, k, n = 0; |
| 132026 | int i; |
| 132027 | char *z; |
| 132028 | for(i=0; i<argc; i++){ |
| 132029 | n += sqlite3_value_bytes(argv[i]); |
| 132030 | } |
| @@ -132034,12 +132158,12 @@ | |
| 132034 | sqlite3_result_error_nomem(context); |
| 132035 | return; |
| 132036 | } |
| 132037 | j = 0; |
| 132038 | for(i=0; i<argc; i++){ |
| 132039 | k = sqlite3_value_bytes(argv[i]); |
| 132040 | if( k>0 ){ |
| 132041 | const char *v = (const char*)sqlite3_value_text(argv[i]); |
| 132042 | if( v!=0 ){ |
| 132043 | if( j>0 && nSep>0 ){ |
| 132044 | memcpy(&z[j], zSep, nSep); |
| 132045 | j += nSep; |
| @@ -134973,16 +135097,19 @@ | |
| 134973 | if( iReg==0 ){ |
| 134974 | /* Move the previous opcode (which should be OP_MakeRecord) forward |
| 134975 | ** by one slot and insert a new OP_TypeCheck where the current |
| 134976 | ** OP_MakeRecord is found */ |
| 134977 | VdbeOp *pPrev; |
| 134978 | sqlite3VdbeAppendP4(v, pTab, P4_TABLE); |
| 134979 | pPrev = sqlite3VdbeGetLastOp(v); |
| 134980 | assert( pPrev!=0 ); |
| 134981 | assert( pPrev->opcode==OP_MakeRecord || sqlite3VdbeDb(v)->mallocFailed ); |
| 134982 | pPrev->opcode = OP_TypeCheck; |
| 134983 | sqlite3VdbeAddOp3(v, OP_MakeRecord, pPrev->p1, pPrev->p2, pPrev->p3); |
| 134984 | }else{ |
| 134985 | /* Insert an isolated OP_Typecheck */ |
| 134986 | sqlite3VdbeAddOp2(v, OP_TypeCheck, iReg, pTab->nNVCol); |
| 134987 | sqlite3VdbeAppendP4(v, pTab, P4_TABLE); |
| 134988 | } |
| @@ -159213,10 +159340,13 @@ | |
| 159213 | u16 eOperator; /* A WO_xx value describing <op> */ |
| 159214 | u8 nChild; /* Number of children that must disable us */ |
| 159215 | u8 eMatchOp; /* Op for vtab MATCH/LIKE/GLOB/REGEXP terms */ |
| 159216 | int iParent; /* Disable pWC->a[iParent] when this term disabled */ |
| 159217 | int leftCursor; /* Cursor number of X in "X <op> <expr>" */ |
| 159218 | union { |
| 159219 | struct { |
| 159220 | int leftColumn; /* Column number of X in "X <op> <expr>" */ |
| 159221 | int iField; /* Field in (?,?,?) IN (SELECT...) vector */ |
| 159222 | } x; /* Opcode other than OP_OR or OP_AND */ |
| @@ -161410,40 +161540,40 @@ | |
| 161410 | VdbeCoverageIf(v, testOp==OP_Ge); |
| 161411 | VdbeCoverageIf(v, testOp==OP_Gt); |
| 161412 | sqlite3VdbeChangeP5(v, SQLITE_AFF_NUMERIC | SQLITE_JUMPIFNULL); |
| 161413 | } |
| 161414 | }else if( pLoop->wsFlags & WHERE_INDEXED ){ |
| 161415 | /* Case 4: A scan using an index. |
| 161416 | ** |
| 161417 | ** The WHERE clause may contain zero or more equality |
| 161418 | ** terms ("==" or "IN" operators) that refer to the N |
| 161419 | ** left-most columns of the index. It may also contain |
| 161420 | ** inequality constraints (>, <, >= or <=) on the indexed |
| 161421 | ** column that immediately follows the N equalities. Only |
| 161422 | ** the right-most column can be an inequality - the rest must |
| 161423 | ** use the "==" and "IN" operators. For example, if the |
| 161424 | ** index is on (x,y,z), then the following clauses are all |
| 161425 | ** optimized: |
| 161426 | ** |
| 161427 | ** x=5 |
| 161428 | ** x=5 AND y=10 |
| 161429 | ** x=5 AND y<10 |
| 161430 | ** x=5 AND y>5 AND y<10 |
| 161431 | ** x=5 AND y=5 AND z<=10 |
| 161432 | ** |
| 161433 | ** The z<10 term of the following cannot be used, only |
| 161434 | ** the x=5 term: |
| 161435 | ** |
| 161436 | ** x=5 AND z<10 |
| 161437 | ** |
| 161438 | ** N may be zero if there are inequality constraints. |
| 161439 | ** If there are no inequality constraints, then N is at |
| 161440 | ** least one. |
| 161441 | ** |
| 161442 | ** This case is also used when there are no WHERE clause |
| 161443 | ** constraints but an index is selected anyway, in order |
| 161444 | ** to force the output order to conform to an ORDER BY. |
| 161445 | */ |
| 161446 | static const u8 aStartOp[] = { |
| 161447 | 0, |
| 161448 | 0, |
| 161449 | OP_Rewind, /* 2: (!start_constraints && startEq && !bRev) */ |
| @@ -163459,34 +163589,46 @@ | |
| 163459 | ** column references. This routine checks to see if pExpr is an equivalence |
| 163460 | ** relation: |
| 163461 | ** 1. The SQLITE_Transitive optimization must be enabled |
| 163462 | ** 2. Must be either an == or an IS operator |
| 163463 | ** 3. Not originating in the ON clause of an OUTER JOIN |
| 163464 | ** 4. The affinities of A and B must be compatible |
| 163465 | ** 5a. Both operands use the same collating sequence OR |
| 163466 | ** 5b. The overall collating sequence is BINARY |
| 163467 | ** If this routine returns TRUE, that means that the RHS can be substituted |
| 163468 | ** for the LHS anyplace else in the WHERE clause where the LHS column occurs. |
| 163469 | ** This is an optimization. No harm comes from returning 0. But if 1 is |
| 163470 | ** returned when it should not be, then incorrect answers might result. |
| 163471 | */ |
| 163472 | static int termIsEquivalence(Parse *pParse, Expr *pExpr){ |
| 163473 | char aff1, aff2; |
| 163474 | CollSeq *pColl; |
| 163475 | if( !OptimizationEnabled(pParse->db, SQLITE_Transitive) ) return 0; |
| 163476 | if( pExpr->op!=TK_EQ && pExpr->op!=TK_IS ) return 0; |
| 163477 | if( ExprHasProperty(pExpr, EP_OuterON) ) return 0; |
| 163478 | aff1 = sqlite3ExprAffinity(pExpr->pLeft); |
| 163479 | aff2 = sqlite3ExprAffinity(pExpr->pRight); |
| 163480 | if( aff1!=aff2 |
| 163481 | && (!sqlite3IsNumericAffinity(aff1) || !sqlite3IsNumericAffinity(aff2)) |
| 163482 | ){ |
| 163483 | return 0; |
| 163484 | } |
| 163485 | pColl = sqlite3ExprCompareCollSeq(pParse, pExpr); |
| 163486 | if( sqlite3IsBinary(pColl) ) return 1; |
| 163487 | return sqlite3ExprCollSeqMatch(pParse, pExpr->pLeft, pExpr->pRight); |
| 163488 | } |
| 163489 | |
| 163490 | /* |
| 163491 | ** Recursively walk the expressions of a SELECT statement and generate |
| 163492 | ** a bitmask indicating which tables are used in that expression |
| @@ -163640,10 +163782,13 @@ | |
| 163640 | if( db->mallocFailed ){ |
| 163641 | return; |
| 163642 | } |
| 163643 | assert( pWC->nTerm > idxTerm ); |
| 163644 | pTerm = &pWC->a[idxTerm]; |
| 163645 | pMaskSet = &pWInfo->sMaskSet; |
| 163646 | pExpr = pTerm->pExpr; |
| 163647 | assert( pExpr!=0 ); /* Because malloc() has not failed */ |
| 163648 | assert( pExpr->op!=TK_AS && pExpr->op!=TK_COLLATE ); |
| 163649 | pMaskSet->bVarSelect = 0; |
| @@ -163747,12 +163892,12 @@ | |
| 163747 | pNew = &pWC->a[idxNew]; |
| 163748 | markTermAsChild(pWC, idxNew, idxTerm); |
| 163749 | if( op==TK_IS ) pNew->wtFlags |= TERM_IS; |
| 163750 | pTerm = &pWC->a[idxTerm]; |
| 163751 | pTerm->wtFlags |= TERM_COPIED; |
| 163752 | |
| 163753 | if( termIsEquivalence(pParse, pDup) ){ |
| 163754 | pTerm->eOperator |= WO_EQUIV; |
| 163755 | eExtraOp = WO_EQUIV; |
| 163756 | } |
| 163757 | }else{ |
| 163758 | pDup = pExpr; |
| @@ -164867,15 +165012,15 @@ | |
| 164867 | continue; |
| 164868 | } |
| 164869 | pScan->pWC = pWC; |
| 164870 | pScan->k = k+1; |
| 164871 | #ifdef WHERETRACE_ENABLED |
| 164872 | if( sqlite3WhereTrace & 0x20000 ){ |
| 164873 | int ii; |
| 164874 | sqlite3DebugPrintf("SCAN-TERM %p: nEquiv=%d", |
| 164875 | pTerm, pScan->nEquiv); |
| 164876 | for(ii=0; ii<pScan->nEquiv; ii++){ |
| 164877 | sqlite3DebugPrintf(" {%d:%d}", |
| 164878 | pScan->aiCur[ii], pScan->aiColumn[ii]); |
| 164879 | } |
| 164880 | sqlite3DebugPrintf("\n"); |
| 164881 | } |
| @@ -166826,10 +166971,11 @@ | |
| 166826 | sqlite3_snprintf(sizeof(zLeft),zLeft,"indexable=0x%llx", |
| 166827 | pTerm->u.pOrInfo->indexable); |
| 166828 | }else{ |
| 166829 | sqlite3_snprintf(sizeof(zLeft),zLeft,"left=%d", pTerm->leftCursor); |
| 166830 | } |
| 166831 | sqlite3DebugPrintf( |
| 166832 | "TERM-%-3d %p %s %-12s op=%03x wtFlags=%04x", |
| 166833 | iTerm, pTerm, zType, zLeft, pTerm->eOperator, pTerm->wtFlags); |
| 166834 | /* The 0x10000 .wheretrace flag causes extra information to be |
| 166835 | ** shown about each Term */ |
| @@ -184450,10 +184596,11 @@ | |
| 184450 | #ifdef SQLITE_ENABLE_API_ARMOR |
| 184451 | if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; |
| 184452 | #endif |
| 184453 | if( ms<-1 ) return SQLITE_RANGE; |
| 184454 | #ifdef SQLITE_ENABLE_SETLK_TIMEOUT |
| 184455 | db->setlkTimeout = ms; |
| 184456 | db->setlkFlags = flags; |
| 184457 | sqlite3BtreeEnterAll(db); |
| 184458 | for(iDb=0; iDb<db->nDb; iDb++){ |
| 184459 | Btree *pBt = db->aDb[iDb].pBt; |
| @@ -184461,10 +184608,11 @@ | |
| 184461 | sqlite3_file *fd = sqlite3PagerFile(sqlite3BtreePager(pBt)); |
| 184462 | sqlite3OsFileControlHint(fd, SQLITE_FCNTL_BLOCK_ON_CONNECT, (void*)&bBOC); |
| 184463 | } |
| 184464 | } |
| 184465 | sqlite3BtreeLeaveAll(db); |
| 184466 | #endif |
| 184467 | #if !defined(SQLITE_ENABLE_API_ARMOR) && !defined(SQLITE_ENABLE_SETLK_TIMEOUT) |
| 184468 | UNUSED_PARAMETER(db); |
| 184469 | UNUSED_PARAMETER(flags); |
| 184470 | #endif |
| @@ -257257,11 +257405,11 @@ | |
| 257257 | int nArg, /* Number of args */ |
| 257258 | sqlite3_value **apUnused /* Function arguments */ |
| 257259 | ){ |
| 257260 | assert( nArg==0 ); |
| 257261 | UNUSED_PARAM2(nArg, apUnused); |
| 257262 | sqlite3_result_text(pCtx, "fts5: 2025-06-03 10:49:51 ea1754f7d8a770477a1b19b606b27724fdc0b733e51fef32c1ef834f972c3cc5", -1, SQLITE_TRANSIENT); |
| 257263 | } |
| 257264 | |
| 257265 | /* |
| 257266 | ** Implementation of fts5_locale(LOCALE, TEXT) function. |
| 257267 | ** |
| @@ -258072,10 +258220,11 @@ | |
| 258072 | ctx.pStorage = p; |
| 258073 | ctx.iCol = -1; |
| 258074 | for(iCol=1; rc==SQLITE_OK && iCol<=pConfig->nCol; iCol++){ |
| 258075 | if( pConfig->abUnindexed[iCol-1]==0 ){ |
| 258076 | sqlite3_value *pVal = 0; |
| 258077 | const char *pText = 0; |
| 258078 | int nText = 0; |
| 258079 | const char *pLoc = 0; |
| 258080 | int nLoc = 0; |
| 258081 | |
| @@ -258088,15 +258237,26 @@ | |
| 258088 | } |
| 258089 | |
| 258090 | if( pConfig->bLocale && sqlite3Fts5IsLocaleValue(pConfig, pVal) ){ |
| 258091 | rc = sqlite3Fts5DecodeLocaleValue(pVal, &pText, &nText, &pLoc, &nLoc); |
| 258092 | }else{ |
| 258093 | pText = (const char*)sqlite3_value_text(pVal); |
| 258094 | nText = sqlite3_value_bytes(pVal); |
| 258095 | if( pConfig->bLocale && pSeek ){ |
| 258096 | pLoc = (const char*)sqlite3_column_text(pSeek, iCol + pConfig->nCol); |
| 258097 | nLoc = sqlite3_column_bytes(pSeek, iCol + pConfig->nCol); |
| 258098 | } |
| 258099 | } |
| 258100 | |
| 258101 | if( rc==SQLITE_OK ){ |
| 258102 | sqlite3Fts5SetLocale(pConfig, pLoc, nLoc); |
| @@ -258108,10 +258268,11 @@ | |
| 258108 | if( rc==SQLITE_OK && p->aTotalSize[iCol-1]<0 ){ |
| 258109 | rc = FTS5_CORRUPT; |
| 258110 | } |
| 258111 | sqlite3Fts5ClearLocale(pConfig); |
| 258112 | } |
| 258113 | } |
| 258114 | } |
| 258115 | if( rc==SQLITE_OK && p->nTotalRow<1 ){ |
| 258116 | rc = FTS5_CORRUPT; |
| 258117 | }else{ |
| 258118 |
| --- extsrc/sqlite3.c | |
| +++ extsrc/sqlite3.c | |
| @@ -16,11 +16,11 @@ | |
| 16 | ** if you want a wrapper to interface SQLite with your choice of programming |
| 17 | ** language. The code for the "sqlite3" command-line shell is also in a |
| 18 | ** separate file. This file contains only code for the core SQLite library. |
| 19 | ** |
| 20 | ** The content in this amalgamation comes from Fossil check-in |
| 21 | ** a88bb75288a06492a04ab1278e8a2101a74f with changes in files: |
| 22 | ** |
| 23 | ** |
| 24 | */ |
| 25 | #ifndef SQLITE_AMALGAMATION |
| 26 | #define SQLITE_CORE 1 |
| @@ -465,11 +465,11 @@ | |
| 465 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 466 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 467 | */ |
| 468 | #define SQLITE_VERSION "3.51.0" |
| 469 | #define SQLITE_VERSION_NUMBER 3051000 |
| 470 | #define SQLITE_SOURCE_ID "2025-06-19 20:19:12 a88bb75288a06492a04ab1278e8a2101a74f4ba712d328b4c73e86ac01cb946d" |
| 471 | |
| 472 | /* |
| 473 | ** CAPI3REF: Run-Time Library Version Numbers |
| 474 | ** KEYWORDS: sqlite3_version sqlite3_sourceid |
| 475 | ** |
| @@ -4396,11 +4396,11 @@ | |
| 4396 | ** These interfaces are provided for use by [VFS shim] implementations and |
| 4397 | ** are not useful outside of that context. |
| 4398 | ** |
| 4399 | ** The sqlite3_create_filename(D,J,W,N,P) allocates memory to hold a version of |
| 4400 | ** database filename D with corresponding journal file J and WAL file W and |
| 4401 | ** an array P of N URI Key/Value pairs. The result from |
| 4402 | ** sqlite3_create_filename(D,J,W,N,P) is a pointer to a database filename that |
| 4403 | ** is safe to pass to routines like: |
| 4404 | ** <ul> |
| 4405 | ** <li> [sqlite3_uri_parameter()], |
| 4406 | ** <li> [sqlite3_uri_boolean()], |
| @@ -5077,11 +5077,11 @@ | |
| 5077 | ** KEYWORDS: {host parameter} {host parameters} {host parameter name} |
| 5078 | ** KEYWORDS: {SQL parameter} {SQL parameters} {parameter binding} |
| 5079 | ** METHOD: sqlite3_stmt |
| 5080 | ** |
| 5081 | ** ^(In the SQL statement text input to [sqlite3_prepare_v2()] and its variants, |
| 5082 | ** literals may be replaced by a [parameter] that matches one of the following |
| 5083 | ** templates: |
| 5084 | ** |
| 5085 | ** <ul> |
| 5086 | ** <li> ? |
| 5087 | ** <li> ?NNN |
| @@ -5122,11 +5122,11 @@ | |
| 5122 | ** either UTF8 if the sixth parameter is SQLITE_UTF8, or UTF16 |
| 5123 | ** otherwise. |
| 5124 | ** |
| 5125 | ** [[byte-order determination rules]] ^The byte-order of |
| 5126 | ** UTF16 input text is determined by the byte-order mark (BOM, U+FEFF) |
| 5127 | ** found in the first character, which is removed, or in the absence of a BOM |
| 5128 | ** the byte order is the native byte order of the host |
| 5129 | ** machine for sqlite3_bind_text16() or the byte order specified in |
| 5130 | ** the 6th parameter for sqlite3_bind_text64().)^ |
| 5131 | ** ^If UTF16 input text contains invalid unicode |
| 5132 | ** characters, then SQLite might change those invalid characters |
| @@ -5142,11 +5142,11 @@ | |
| 5142 | ** the behavior is undefined. |
| 5143 | ** If a non-negative fourth parameter is provided to sqlite3_bind_text() |
| 5144 | ** or sqlite3_bind_text16() or sqlite3_bind_text64() then |
| 5145 | ** that parameter must be the byte offset |
| 5146 | ** where the NUL terminator would occur assuming the string were NUL |
| 5147 | ** terminated. If any NUL characters occur at byte offsets less than |
| 5148 | ** the value of the fourth parameter then the resulting string value will |
| 5149 | ** contain embedded NULs. The result of expressions involving strings |
| 5150 | ** with embedded NULs is undefined. |
| 5151 | ** |
| 5152 | ** ^The fifth argument to the BLOB and string binding interfaces controls |
| @@ -5354,11 +5354,11 @@ | |
| 5354 | /* |
| 5355 | ** CAPI3REF: Source Of Data In A Query Result |
| 5356 | ** METHOD: sqlite3_stmt |
| 5357 | ** |
| 5358 | ** ^These routines provide a means to determine the database, table, and |
| 5359 | ** table column that is the origin of a particular result column in a |
| 5360 | ** [SELECT] statement. |
| 5361 | ** ^The name of the database or table or column can be returned as |
| 5362 | ** either a UTF-8 or UTF-16 string. ^The _database_ routines return |
| 5363 | ** the database name, the _table_ routines return the table name, and |
| 5364 | ** the origin_ routines return the column name. |
| @@ -5923,12 +5923,12 @@ | |
| 5923 | ** within VIEWs, TRIGGERs, CHECK constraints, generated column expressions, |
| 5924 | ** index expressions, or the WHERE clause of partial indexes. |
| 5925 | ** |
| 5926 | ** For best security, the [SQLITE_DIRECTONLY] flag is recommended for |
| 5927 | ** all application-defined SQL functions that do not need to be |
| 5928 | ** used inside of triggers, views, CHECK constraints, or other elements of |
| 5929 | ** the database schema. This flag is especially recommended for SQL |
| 5930 | ** functions that have side effects or reveal internal application state. |
| 5931 | ** Without this flag, an attacker might be able to modify the schema of |
| 5932 | ** a database file to include invocations of the function with parameters |
| 5933 | ** chosen by the attacker, which the application will then execute when |
| 5934 | ** the database file is opened and read. |
| @@ -5955,11 +5955,11 @@ | |
| 5955 | ** or aggregate window function. More details regarding the implementation |
| 5956 | ** of aggregate window functions are |
| 5957 | ** [user-defined window functions|available here]. |
| 5958 | ** |
| 5959 | ** ^(If the final parameter to sqlite3_create_function_v2() or |
| 5960 | ** sqlite3_create_window_function() is not NULL, then it is the destructor for |
| 5961 | ** the application data pointer. The destructor is invoked when the function |
| 5962 | ** is deleted, either by being overloaded or when the database connection |
| 5963 | ** closes.)^ ^The destructor is also invoked if the call to |
| 5964 | ** sqlite3_create_function_v2() fails. ^When the destructor callback is |
| 5965 | ** invoked, it is passed a single argument which is a copy of the application |
| @@ -7763,11 +7763,11 @@ | |
| 7763 | ** that is to be automatically loaded into all new database connections. |
| 7764 | ** |
| 7765 | ** ^(Even though the function prototype shows that xEntryPoint() takes |
| 7766 | ** no arguments and returns void, SQLite invokes xEntryPoint() with three |
| 7767 | ** arguments and expects an integer result as if the signature of the |
| 7768 | ** entry point were as follows: |
| 7769 | ** |
| 7770 | ** <blockquote><pre> |
| 7771 | ** int xEntryPoint( |
| 7772 | ** sqlite3 *db, |
| 7773 | ** const char **pzErrMsg, |
| @@ -8094,11 +8094,11 @@ | |
| 8094 | ** by the first parameter. ^The name of the module is given by the |
| 8095 | ** second parameter. ^The third parameter is a pointer to |
| 8096 | ** the implementation of the [virtual table module]. ^The fourth |
| 8097 | ** parameter is an arbitrary client data pointer that is passed through |
| 8098 | ** into the [xCreate] and [xConnect] methods of the virtual table module |
| 8099 | ** when a new virtual table is being created or reinitialized. |
| 8100 | ** |
| 8101 | ** ^The sqlite3_create_module_v2() interface has a fifth parameter which |
| 8102 | ** is a pointer to a destructor for the pClientData. ^SQLite will |
| 8103 | ** invoke the destructor function (if it is not NULL) when SQLite |
| 8104 | ** no longer needs the pClientData pointer. ^The destructor will also |
| @@ -8259,11 +8259,11 @@ | |
| 8259 | ** |
| 8260 | ** ^(On success, [SQLITE_OK] is returned and the new [BLOB handle] is stored |
| 8261 | ** in *ppBlob. Otherwise an [error code] is returned and, unless the error |
| 8262 | ** code is SQLITE_MISUSE, *ppBlob is set to NULL.)^ ^This means that, provided |
| 8263 | ** the API is not misused, it is always safe to call [sqlite3_blob_close()] |
| 8264 | ** on *ppBlob after this function returns. |
| 8265 | ** |
| 8266 | ** This function fails with SQLITE_ERROR if any of the following are true: |
| 8267 | ** <ul> |
| 8268 | ** <li> ^(Database zDb does not exist)^, |
| 8269 | ** <li> ^(Table zTable does not exist within database zDb)^, |
| @@ -8379,11 +8379,11 @@ | |
| 8379 | ** CAPI3REF: Return The Size Of An Open BLOB |
| 8380 | ** METHOD: sqlite3_blob |
| 8381 | ** |
| 8382 | ** ^Returns the size in bytes of the BLOB accessible via the |
| 8383 | ** successfully opened [BLOB handle] in its only argument. ^The |
| 8384 | ** incremental blob I/O routines can only read or overwrite existing |
| 8385 | ** blob content; they cannot change the size of a blob. |
| 8386 | ** |
| 8387 | ** This routine only works on a [BLOB handle] which has been created |
| 8388 | ** by a prior successful call to [sqlite3_blob_open()] and which has not |
| 8389 | ** been closed by [sqlite3_blob_close()]. Passing any other pointer in |
| @@ -9782,11 +9782,11 @@ | |
| 9782 | ** sqlite3_backup_step(), the source database may be modified mid-way |
| 9783 | ** through the backup process. ^If the source database is modified by an |
| 9784 | ** external process or via a database connection other than the one being |
| 9785 | ** used by the backup operation, then the backup will be automatically |
| 9786 | ** restarted by the next call to sqlite3_backup_step(). ^If the source |
| 9787 | ** database is modified by using the same database connection as is used |
| 9788 | ** by the backup operation, then the backup database is automatically |
| 9789 | ** updated at the same time. |
| 9790 | ** |
| 9791 | ** [[sqlite3_backup_finish()]] <b>sqlite3_backup_finish()</b> |
| 9792 | ** |
| @@ -9799,11 +9799,11 @@ | |
| 9799 | ** active write-transaction on the destination database is rolled back. |
| 9800 | ** The [sqlite3_backup] object is invalid |
| 9801 | ** and may not be used following a call to sqlite3_backup_finish(). |
| 9802 | ** |
| 9803 | ** ^The value returned by sqlite3_backup_finish is [SQLITE_OK] if no |
| 9804 | ** sqlite3_backup_step() errors occurred, regardless of whether or not |
| 9805 | ** sqlite3_backup_step() completed. |
| 9806 | ** ^If an out-of-memory condition or IO error occurred during any prior |
| 9807 | ** sqlite3_backup_step() call on the same [sqlite3_backup] object, then |
| 9808 | ** sqlite3_backup_finish() returns the corresponding [error code]. |
| 9809 | ** |
| @@ -10869,11 +10869,11 @@ | |
| 10869 | /* |
| 10870 | ** CAPI3REF: Flush caches to disk mid-transaction |
| 10871 | ** METHOD: sqlite3 |
| 10872 | ** |
| 10873 | ** ^If a write-transaction is open on [database connection] D when the |
| 10874 | ** [sqlite3_db_cacheflush(D)] interface is invoked, any dirty |
| 10875 | ** pages in the pager-cache that are not currently in use are written out |
| 10876 | ** to disk. A dirty page may be in use if a database cursor created by an |
| 10877 | ** active SQL statement is reading from it, or if it is page 1 of a database |
| 10878 | ** file (page 1 is always "in use"). ^The [sqlite3_db_cacheflush(D)] |
| 10879 | ** interface flushes caches for all schemas - "main", "temp", and |
| @@ -15562,10 +15562,11 @@ | |
| 15562 | ** 0x00008000 After all FROM-clause analysis |
| 15563 | ** 0x00010000 Beginning of DELETE/INSERT/UPDATE processing |
| 15564 | ** 0x00020000 Transform DISTINCT into GROUP BY |
| 15565 | ** 0x00040000 SELECT tree dump after all code has been generated |
| 15566 | ** 0x00080000 NOT NULL strength reduction |
| 15567 | ** 0x00100000 Pointers are all shown as zero |
| 15568 | */ |
| 15569 | |
| 15570 | /* |
| 15571 | ** Macros for "wheretrace" |
| 15572 | */ |
| @@ -15606,10 +15607,11 @@ | |
| 15607 | ** |
| 15608 | ** 0x00010000 Show more detail when printing WHERE terms |
| 15609 | ** 0x00020000 Show WHERE terms returned from whereScanNext() |
| 15610 | ** 0x00040000 Solver overview messages |
| 15611 | ** 0x00080000 Star-query heuristic |
| 15612 | ** 0x00100000 Pointers are all shown as zero |
| 15613 | */ |
| 15614 | |
| 15615 | |
| 15616 | /* |
| 15617 | ** An instance of the following structure is used to store the busy-handler |
| @@ -15678,11 +15680,11 @@ | |
| 15680 | ** one parameter that destructors normally want. So we have to introduce |
| 15681 | ** this magic value that the code knows to handle differently. Any |
| 15682 | ** pointer will work here as long as it is distinct from SQLITE_STATIC |
| 15683 | ** and SQLITE_TRANSIENT. |
| 15684 | */ |
| 15685 | #define SQLITE_DYNAMIC ((sqlite3_destructor_type)sqlite3RowSetClear) |
| 15686 | |
| 15687 | /* |
| 15688 | ** When SQLITE_OMIT_WSD is defined, it means that the target platform does |
| 15689 | ** not support Writable Static Data (WSD) such as global and static variables. |
| 15690 | ** All variables must either be on the stack or dynamically allocated from |
| @@ -21266,10 +21268,11 @@ | |
| 21268 | #endif |
| 21269 | #ifndef SQLITE_OMIT_WINDOWFUNC |
| 21270 | SQLITE_PRIVATE void sqlite3ShowWindow(const Window*); |
| 21271 | SQLITE_PRIVATE void sqlite3ShowWinFunc(const Window*); |
| 21272 | #endif |
| 21273 | SQLITE_PRIVATE void sqlite3ShowBitvec(Bitvec*); |
| 21274 | #endif |
| 21275 | |
| 21276 | SQLITE_PRIVATE void sqlite3SetString(char **, sqlite3*, const char*); |
| 21277 | SQLITE_PRIVATE void sqlite3ProgressCheck(Parse*); |
| 21278 | SQLITE_PRIVATE void sqlite3ErrorMsg(Parse*, const char*, ...); |
| @@ -32077,10 +32080,18 @@ | |
| 32080 | }else{ |
| 32081 | longvalue = va_arg(ap,unsigned int); |
| 32082 | } |
| 32083 | prefix = 0; |
| 32084 | } |
| 32085 | |
| 32086 | #if WHERETRACE_ENABLED |
| 32087 | if( xtype==etPOINTER && sqlite3WhereTrace & 0x100000 ) longvalue = 0; |
| 32088 | #endif |
| 32089 | #if TREETRACE_ENABLED |
| 32090 | if( xtype==etPOINTER && sqlite3TreeTrace & 0x100000 ) longvalue = 0; |
| 32091 | #endif |
| 32092 | |
| 32093 | if( longvalue==0 ) flag_alternateform = 0; |
| 32094 | if( flag_zeropad && precision<width-(prefix!=0) ){ |
| 32095 | precision = width-(prefix!=0); |
| 32096 | } |
| 32097 | if( precision<etBUFSIZE-10-etBUFSIZE/3 ){ |
| @@ -54872,10 +54883,11 @@ | |
| 54883 | BITVEC_TELEM aBitmap[BITVEC_NELEM]; /* Bitmap representation */ |
| 54884 | u32 aHash[BITVEC_NINT]; /* Hash table representation */ |
| 54885 | Bitvec *apSub[BITVEC_NPTR]; /* Recursive representation */ |
| 54886 | } u; |
| 54887 | }; |
| 54888 | |
| 54889 | |
| 54890 | /* |
| 54891 | ** Create a new bitmap object able to handle bits between 0 and iSize, |
| 54892 | ** inclusive. Return a pointer to the new object. Return NULL if |
| 54893 | ** malloc fails. |
| @@ -54982,11 +54994,13 @@ | |
| 54994 | if( aiValues==0 ){ |
| 54995 | return SQLITE_NOMEM_BKPT; |
| 54996 | }else{ |
| 54997 | memcpy(aiValues, p->u.aHash, sizeof(p->u.aHash)); |
| 54998 | memset(p->u.apSub, 0, sizeof(p->u.apSub)); |
| 54999 | p->iDivisor = p->iSize/BITVEC_NPTR; |
| 55000 | if( (p->iSize%BITVEC_NPTR)!=0 ) p->iDivisor++; |
| 55001 | if( p->iDivisor<BITVEC_NBIT ) p->iDivisor = BITVEC_NBIT; |
| 55002 | rc = sqlite3BitvecSet(p, i); |
| 55003 | for(j=0; j<BITVEC_NINT; j++){ |
| 55004 | if( aiValues[j] ) rc |= sqlite3BitvecSet(p, aiValues[j]); |
| 55005 | } |
| 55006 | sqlite3StackFree(0, aiValues); |
| @@ -55058,10 +55072,56 @@ | |
| 55072 | ** was created. |
| 55073 | */ |
| 55074 | SQLITE_PRIVATE u32 sqlite3BitvecSize(Bitvec *p){ |
| 55075 | return p->iSize; |
| 55076 | } |
| 55077 | |
| 55078 | #ifdef SQLITE_DEBUG |
| 55079 | /* |
| 55080 | ** Show the content of a Bitvec option and its children. Indent |
| 55081 | ** everything by n spaces. Add x to each bitvec value. |
| 55082 | ** |
| 55083 | ** From a debugger such as gdb, one can type: |
| 55084 | ** |
| 55085 | ** call sqlite3ShowBitvec(p) |
| 55086 | ** |
| 55087 | ** For some Bitvec p and see a recursive view of the Bitvec's content. |
| 55088 | */ |
| 55089 | static void showBitvec(Bitvec *p, int n, unsigned x){ |
| 55090 | int i; |
| 55091 | if( p==0 ){ |
| 55092 | printf("NULL\n"); |
| 55093 | return; |
| 55094 | } |
| 55095 | printf("Bitvec 0x%p iSize=%u", p, p->iSize); |
| 55096 | if( p->iSize<=BITVEC_NBIT ){ |
| 55097 | printf(" bitmap\n"); |
| 55098 | printf("%*s bits:", n, ""); |
| 55099 | for(i=1; i<=BITVEC_NBIT; i++){ |
| 55100 | if( sqlite3BitvecTest(p,i) ) printf(" %u", x+(unsigned)i); |
| 55101 | } |
| 55102 | printf("\n"); |
| 55103 | }else if( p->iDivisor==0 ){ |
| 55104 | printf(" hash with %u entries\n", p->nSet); |
| 55105 | printf("%*s bits:", n, ""); |
| 55106 | for(i=0; i<BITVEC_NINT; i++){ |
| 55107 | if( p->u.aHash[i] ) printf(" %u", x+(unsigned)p->u.aHash[i]); |
| 55108 | } |
| 55109 | printf("\n"); |
| 55110 | }else{ |
| 55111 | printf(" sub-bitvec with iDivisor=%u\n", p->iDivisor); |
| 55112 | for(i=0; i<BITVEC_NPTR; i++){ |
| 55113 | if( p->u.apSub[i]==0 ) continue; |
| 55114 | printf("%*s apSub[%d]=", n, "", i); |
| 55115 | showBitvec(p->u.apSub[i], n+4, i*p->iDivisor); |
| 55116 | } |
| 55117 | } |
| 55118 | } |
| 55119 | SQLITE_PRIVATE void sqlite3ShowBitvec(Bitvec *p){ |
| 55120 | showBitvec(p, 0, 0); |
| 55121 | } |
| 55122 | #endif |
| 55123 | |
| 55124 | #ifndef SQLITE_UNTESTABLE |
| 55125 | /* |
| 55126 | ** Let V[] be an array of unsigned characters sufficient to hold |
| 55127 | ** up to N bits. Let I be an integer between 0 and N. 0<=I<N. |
| @@ -55069,40 +55129,48 @@ | |
| 55129 | ** individual bits within V. |
| 55130 | */ |
| 55131 | #define SETBIT(V,I) V[I>>3] |= (1<<(I&7)) |
| 55132 | #define CLEARBIT(V,I) V[I>>3] &= ~(BITVEC_TELEM)(1<<(I&7)) |
| 55133 | #define TESTBIT(V,I) (V[I>>3]&(1<<(I&7)))!=0 |
| 55134 | |
| 55135 | |
| 55136 | /* |
| 55137 | ** This routine runs an extensive test of the Bitvec code. |
| 55138 | ** |
| 55139 | ** The input is an array of integers that acts as a program |
| 55140 | ** to test the Bitvec. The integers are opcodes followed |
| 55141 | ** by 0, 1, or 3 operands, depending on the opcode. Another |
| 55142 | ** opcode follows immediately after the last operand. |
| 55143 | ** |
| 55144 | ** There are opcodes numbered starting with 0. 0 is the |
| 55145 | ** "halt" opcode and causes the test to end. |
| 55146 | ** |
| 55147 | ** 0 Halt and return the number of errors |
| 55148 | ** 1 N S X Set N bits beginning with S and incrementing by X |
| 55149 | ** 2 N S X Clear N bits beginning with S and incrementing by X |
| 55150 | ** 3 N Set N randomly chosen bits |
| 55151 | ** 4 N Clear N randomly chosen bits |
| 55152 | ** 5 N S X Set N bits from S increment X in array only, not in bitvec |
| 55153 | ** 6 Invoice sqlite3ShowBitvec() on the Bitvec object so far |
| 55154 | ** 7 X Show compile-time parameters and the hash of X |
| 55155 | ** |
| 55156 | ** The opcodes 1 through 4 perform set and clear operations are performed |
| 55157 | ** on both a Bitvec object and on a linear array of bits obtained from malloc. |
| 55158 | ** Opcode 5 works on the linear array only, not on the Bitvec. |
| 55159 | ** Opcode 5 is used to deliberately induce a fault in order to |
| 55160 | ** confirm that error detection works. Opcodes 6 and greater are |
| 55161 | ** state output opcodes. Opcodes 6 and greater are no-ops unless |
| 55162 | ** SQLite has been compiled with SQLITE_DEBUG. |
| 55163 | ** |
| 55164 | ** At the conclusion of the test the linear array is compared |
| 55165 | ** against the Bitvec object. If there are any differences, |
| 55166 | ** an error is returned. If they are the same, zero is returned. |
| 55167 | ** |
| 55168 | ** If a memory allocation error occurs, return -1. |
| 55169 | ** |
| 55170 | ** sz is the size of the Bitvec. Or if sz is negative, make the size |
| 55171 | ** 2*(unsigned)(-sz) and disabled the linear vector check. |
| 55172 | */ |
| 55173 | SQLITE_PRIVATE int sqlite3BitvecBuiltinTest(int sz, int *aOp){ |
| 55174 | Bitvec *pBitvec = 0; |
| 55175 | unsigned char *pV = 0; |
| 55176 | int rc = -1; |
| @@ -55109,22 +55177,45 @@ | |
| 55177 | int i, nx, pc, op; |
| 55178 | void *pTmpSpace; |
| 55179 | |
| 55180 | /* Allocate the Bitvec to be tested and a linear array of |
| 55181 | ** bits to act as the reference */ |
| 55182 | if( sz<=0 ){ |
| 55183 | pBitvec = sqlite3BitvecCreate( 2*(unsigned)(-sz) ); |
| 55184 | pV = 0; |
| 55185 | }else{ |
| 55186 | pBitvec = sqlite3BitvecCreate( sz ); |
| 55187 | pV = sqlite3MallocZero( (7+(i64)sz)/8 + 1 ); |
| 55188 | } |
| 55189 | pTmpSpace = sqlite3_malloc64(BITVEC_SZ); |
| 55190 | if( pBitvec==0 || pTmpSpace==0 || (pV==0 && sz>0) ) goto bitvec_end; |
| 55191 | |
| 55192 | /* NULL pBitvec tests */ |
| 55193 | sqlite3BitvecSet(0, 1); |
| 55194 | sqlite3BitvecClear(0, 1, pTmpSpace); |
| 55195 | |
| 55196 | /* Run the program */ |
| 55197 | pc = i = 0; |
| 55198 | while( (op = aOp[pc])!=0 ){ |
| 55199 | if( op>=6 ){ |
| 55200 | #ifdef SQLITE_DEBUG |
| 55201 | if( op==6 ){ |
| 55202 | sqlite3ShowBitvec(pBitvec); |
| 55203 | }else if( op==7 ){ |
| 55204 | printf("BITVEC_SZ = %d (%d by sizeof)\n", |
| 55205 | BITVEC_SZ, (int)sizeof(Bitvec)); |
| 55206 | printf("BITVEC_USIZE = %d\n", (int)BITVEC_USIZE); |
| 55207 | printf("BITVEC_NELEM = %d\n", (int)BITVEC_NELEM); |
| 55208 | printf("BITVEC_NBIT = %d\n", (int)BITVEC_NBIT); |
| 55209 | printf("BITVEC_NINT = %d\n", (int)BITVEC_NINT); |
| 55210 | printf("BITVEC_MXHASH = %d\n", (int)BITVEC_MXHASH); |
| 55211 | printf("BITVEC_NPTR = %d\n", (int)BITVEC_NPTR); |
| 55212 | } |
| 55213 | #endif |
| 55214 | pc++; |
| 55215 | continue; |
| 55216 | } |
| 55217 | switch( op ){ |
| 55218 | case 1: |
| 55219 | case 2: |
| 55220 | case 5: { |
| 55221 | nx = 4; |
| @@ -55142,33 +55233,37 @@ | |
| 55233 | } |
| 55234 | if( (--aOp[pc+1]) > 0 ) nx = 0; |
| 55235 | pc += nx; |
| 55236 | i = (i & 0x7fffffff)%sz; |
| 55237 | if( (op & 1)!=0 ){ |
| 55238 | if( pV ) SETBIT(pV, (i+1)); |
| 55239 | if( op!=5 ){ |
| 55240 | if( sqlite3BitvecSet(pBitvec, i+1) ) goto bitvec_end; |
| 55241 | } |
| 55242 | }else{ |
| 55243 | if( pV ) CLEARBIT(pV, (i+1)); |
| 55244 | sqlite3BitvecClear(pBitvec, i+1, pTmpSpace); |
| 55245 | } |
| 55246 | } |
| 55247 | |
| 55248 | /* Test to make sure the linear array exactly matches the |
| 55249 | ** Bitvec object. Start with the assumption that they do |
| 55250 | ** match (rc==0). Change rc to non-zero if a discrepancy |
| 55251 | ** is found. |
| 55252 | */ |
| 55253 | if( pV ){ |
| 55254 | rc = sqlite3BitvecTest(0,0) + sqlite3BitvecTest(pBitvec, sz+1) |
| 55255 | + sqlite3BitvecTest(pBitvec, 0) |
| 55256 | + (sqlite3BitvecSize(pBitvec) - sz); |
| 55257 | for(i=1; i<=sz; i++){ |
| 55258 | if( (TESTBIT(pV,i))!=sqlite3BitvecTest(pBitvec,i) ){ |
| 55259 | rc = i; |
| 55260 | break; |
| 55261 | } |
| 55262 | } |
| 55263 | }else{ |
| 55264 | rc = 0; |
| 55265 | } |
| 55266 | |
| 55267 | /* Free allocated structure */ |
| 55268 | bitvec_end: |
| 55269 | sqlite3_free(pTmpSpace); |
| @@ -69670,10 +69765,11 @@ | |
| 69765 | rc = xUndo(pUndoCtx, walFramePgno(pWal, iFrame)); |
| 69766 | } |
| 69767 | if( iMax!=pWal->hdr.mxFrame ) walCleanupHash(pWal); |
| 69768 | } |
| 69769 | SEH_EXCEPT( rc = SQLITE_IOERR_IN_PAGE; ) |
| 69770 | pWal->iReCksum = 0; |
| 69771 | } |
| 69772 | return rc; |
| 69773 | } |
| 69774 | |
| 69775 | /* |
| @@ -69717,10 +69813,13 @@ | |
| 69813 | pWal->hdr.aFrameCksum[1] = aWalData[2]; |
| 69814 | SEH_TRY { |
| 69815 | walCleanupHash(pWal); |
| 69816 | } |
| 69817 | SEH_EXCEPT( rc = SQLITE_IOERR_IN_PAGE; ) |
| 69818 | if( pWal->iReCksum>pWal->hdr.mxFrame ){ |
| 69819 | pWal->iReCksum = 0; |
| 69820 | } |
| 69821 | } |
| 69822 | |
| 69823 | return rc; |
| 69824 | } |
| 69825 | |
| @@ -77442,12 +77541,12 @@ | |
| 77541 | assert( (pCur->curFlags & BTCF_ValidOvfl)==0 ); |
| 77542 | return rc; |
| 77543 | } |
| 77544 | |
| 77545 | /* |
| 77546 | ** Compare the "idx"-th cell on the page pPage against the key |
| 77547 | ** pointing to by pIdxKey using xRecordCompare. Return negative or |
| 77548 | ** zero if the cell is less than or equal pIdxKey. Return positive |
| 77549 | ** if unknown. |
| 77550 | ** |
| 77551 | ** Return value negative: Cell at pCur[idx] less than pIdxKey |
| 77552 | ** |
| @@ -77458,16 +77557,15 @@ | |
| 77557 | ** |
| 77558 | ** This routine is part of an optimization. It is always safe to return |
| 77559 | ** a positive value as that will cause the optimization to be skipped. |
| 77560 | */ |
| 77561 | static int indexCellCompare( |
| 77562 | MemPage *pPage, |
| 77563 | int idx, |
| 77564 | UnpackedRecord *pIdxKey, |
| 77565 | RecordCompare xRecordCompare |
| 77566 | ){ |
| 77567 | int c; |
| 77568 | int nCell; /* Size of the pCell cell in bytes */ |
| 77569 | u8 *pCell = findCellPastPtr(pPage, idx); |
| 77570 | |
| 77571 | nCell = pCell[0]; |
| @@ -77572,18 +77670,18 @@ | |
| 77670 | && pCur->pPage->leaf |
| 77671 | && cursorOnLastPage(pCur) |
| 77672 | ){ |
| 77673 | int c; |
| 77674 | if( pCur->ix==pCur->pPage->nCell-1 |
| 77675 | && (c = indexCellCompare(pCur->pPage,pCur->ix,pIdxKey,xRecordCompare))<=0 |
| 77676 | && pIdxKey->errCode==SQLITE_OK |
| 77677 | ){ |
| 77678 | *pRes = c; |
| 77679 | return SQLITE_OK; /* Cursor already pointing at the correct spot */ |
| 77680 | } |
| 77681 | if( pCur->iPage>0 |
| 77682 | && indexCellCompare(pCur->pPage, 0, pIdxKey, xRecordCompare)<=0 |
| 77683 | && pIdxKey->errCode==SQLITE_OK |
| 77684 | ){ |
| 77685 | pCur->curFlags &= ~(BTCF_ValidOvfl|BTCF_AtLast); |
| 77686 | if( !pCur->pPage->isInit ){ |
| 77687 | return SQLITE_CORRUPT_BKPT; |
| @@ -77796,11 +77894,11 @@ | |
| 77894 | if( pCur->eState!=CURSOR_VALID ) return 0; |
| 77895 | if( NEVER(pCur->pPage->leaf==0) ) return -1; |
| 77896 | |
| 77897 | n = pCur->pPage->nCell; |
| 77898 | for(i=0; i<pCur->iPage; i++){ |
| 77899 | n *= pCur->apPage[i]->nCell+1; |
| 77900 | } |
| 77901 | return n; |
| 77902 | } |
| 77903 | |
| 77904 | /* |
| @@ -97581,10 +97679,19 @@ | |
| 97679 | ** Synopsis: typecheck(r[P1@P2]) |
| 97680 | ** |
| 97681 | ** Apply affinities to the range of P2 registers beginning with P1. |
| 97682 | ** Take the affinities from the Table object in P4. If any value |
| 97683 | ** cannot be coerced into the correct type, then raise an error. |
| 97684 | ** |
| 97685 | ** If P3==0, then omit checking of VIRTUAL columns. |
| 97686 | ** |
| 97687 | ** If P3==1, then omit checking of all generated column, both VIRTUAL |
| 97688 | ** and STORED. |
| 97689 | ** |
| 97690 | ** If P3>=2, then only check column number P3-2 in the table (which will |
| 97691 | ** be a VIRTUAL column) against the value in reg[P1]. In this case, |
| 97692 | ** P2 will be 1. |
| 97693 | ** |
| 97694 | ** This opcode is similar to OP_Affinity except that this opcode |
| 97695 | ** forces the register type to the Table column type. This is used |
| 97696 | ** to implement "strict affinity". |
| 97697 | ** |
| @@ -97595,30 +97702,42 @@ | |
| 97702 | ** |
| 97703 | ** Preconditions: |
| 97704 | ** |
| 97705 | ** <ul> |
| 97706 | ** <li> P2 should be the number of non-virtual columns in the |
| 97707 | ** table of P4 unless P3>1, in which case P2 will be 1. |
| 97708 | ** <li> Table P4 is a STRICT table. |
| 97709 | ** </ul> |
| 97710 | ** |
| 97711 | ** If any precondition is false, an assertion fault occurs. |
| 97712 | */ |
| 97713 | case OP_TypeCheck: { |
| 97714 | Table *pTab; |
| 97715 | Column *aCol; |
| 97716 | int i; |
| 97717 | int nCol; |
| 97718 | |
| 97719 | assert( pOp->p4type==P4_TABLE ); |
| 97720 | pTab = pOp->p4.pTab; |
| 97721 | assert( pTab->tabFlags & TF_Strict ); |
| 97722 | assert( pOp->p3>=0 && pOp->p3<pTab->nCol+2 ); |
| 97723 | aCol = pTab->aCol; |
| 97724 | pIn1 = &aMem[pOp->p1]; |
| 97725 | if( pOp->p3<2 ){ |
| 97726 | assert( pTab->nNVCol==pOp->p2 ); |
| 97727 | i = 0; |
| 97728 | nCol = pTab->nCol; |
| 97729 | }else{ |
| 97730 | i = pOp->p3-2; |
| 97731 | nCol = i+1; |
| 97732 | assert( i<pTab->nCol ); |
| 97733 | assert( aCol[i].colFlags & COLFLAG_VIRTUAL ); |
| 97734 | assert( pOp->p2==1 ); |
| 97735 | } |
| 97736 | for(; i<nCol; i++){ |
| 97737 | if( (aCol[i].colFlags & COLFLAG_GENERATED)!=0 && pOp->p3<2 ){ |
| 97738 | if( (aCol[i].colFlags & COLFLAG_VIRTUAL)!=0 ) continue; |
| 97739 | if( pOp->p3 ){ pIn1++; continue; } |
| 97740 | } |
| 97741 | assert( pIn1 < &aMem[pOp->p1+pOp->p2] ); |
| 97742 | applyAffinity(pIn1, aCol[i].affinity, encoding); |
| 97743 | if( (pIn1->flags & MEM_Null)==0 ){ |
| @@ -114626,11 +114745,16 @@ | |
| 114745 | iAddr = sqlite3VdbeAddOp3(v, OP_IfNullRow, pParse->iSelfTab-1, 0, regOut); |
| 114746 | }else{ |
| 114747 | iAddr = 0; |
| 114748 | } |
| 114749 | sqlite3ExprCodeCopy(pParse, sqlite3ColumnExpr(pTab,pCol), regOut); |
| 114750 | if( (pCol->colFlags & COLFLAG_VIRTUAL)!=0 |
| 114751 | && (pTab->tabFlags & TF_Strict)!=0 |
| 114752 | ){ |
| 114753 | int p3 = 2+(int)(pCol - pTab->aCol); |
| 114754 | sqlite3VdbeAddOp4(v, OP_TypeCheck, regOut, 1, p3, (char*)pTab, P4_TABLE); |
| 114755 | }else if( pCol->affinity>=SQLITE_AFF_TEXT ){ |
| 114756 | sqlite3VdbeAddOp4(v, OP_Affinity, regOut, 1, 0, &pCol->affinity, 1); |
| 114757 | } |
| 114758 | if( iAddr ) sqlite3VdbeJumpHere(v, iAddr); |
| 114759 | if( pParse->nErr>nErr ) pParse->db->errByteOffset = -1; |
| 114760 | } |
| @@ -132020,11 +132144,11 @@ | |
| 132144 | int argc, |
| 132145 | sqlite3_value **argv, |
| 132146 | int nSep, |
| 132147 | const char *zSep |
| 132148 | ){ |
| 132149 | i64 j, n = 0; |
| 132150 | int i; |
| 132151 | char *z; |
| 132152 | for(i=0; i<argc; i++){ |
| 132153 | n += sqlite3_value_bytes(argv[i]); |
| 132154 | } |
| @@ -132034,12 +132158,12 @@ | |
| 132158 | sqlite3_result_error_nomem(context); |
| 132159 | return; |
| 132160 | } |
| 132161 | j = 0; |
| 132162 | for(i=0; i<argc; i++){ |
| 132163 | if( sqlite3_value_type(argv[i])!=SQLITE_NULL ){ |
| 132164 | int k = sqlite3_value_bytes(argv[i]); |
| 132165 | const char *v = (const char*)sqlite3_value_text(argv[i]); |
| 132166 | if( v!=0 ){ |
| 132167 | if( j>0 && nSep>0 ){ |
| 132168 | memcpy(&z[j], zSep, nSep); |
| 132169 | j += nSep; |
| @@ -134973,16 +135097,19 @@ | |
| 135097 | if( iReg==0 ){ |
| 135098 | /* Move the previous opcode (which should be OP_MakeRecord) forward |
| 135099 | ** by one slot and insert a new OP_TypeCheck where the current |
| 135100 | ** OP_MakeRecord is found */ |
| 135101 | VdbeOp *pPrev; |
| 135102 | int p3; |
| 135103 | sqlite3VdbeAppendP4(v, pTab, P4_TABLE); |
| 135104 | pPrev = sqlite3VdbeGetLastOp(v); |
| 135105 | assert( pPrev!=0 ); |
| 135106 | assert( pPrev->opcode==OP_MakeRecord || sqlite3VdbeDb(v)->mallocFailed ); |
| 135107 | pPrev->opcode = OP_TypeCheck; |
| 135108 | p3 = pPrev->p3; |
| 135109 | pPrev->p3 = 0; |
| 135110 | sqlite3VdbeAddOp3(v, OP_MakeRecord, pPrev->p1, pPrev->p2, p3); |
| 135111 | }else{ |
| 135112 | /* Insert an isolated OP_Typecheck */ |
| 135113 | sqlite3VdbeAddOp2(v, OP_TypeCheck, iReg, pTab->nNVCol); |
| 135114 | sqlite3VdbeAppendP4(v, pTab, P4_TABLE); |
| 135115 | } |
| @@ -159213,10 +159340,13 @@ | |
| 159340 | u16 eOperator; /* A WO_xx value describing <op> */ |
| 159341 | u8 nChild; /* Number of children that must disable us */ |
| 159342 | u8 eMatchOp; /* Op for vtab MATCH/LIKE/GLOB/REGEXP terms */ |
| 159343 | int iParent; /* Disable pWC->a[iParent] when this term disabled */ |
| 159344 | int leftCursor; /* Cursor number of X in "X <op> <expr>" */ |
| 159345 | #ifdef SQLITE_DEBUG |
| 159346 | int iTerm; /* Which WhereTerm is this, for debug purposes */ |
| 159347 | #endif |
| 159348 | union { |
| 159349 | struct { |
| 159350 | int leftColumn; /* Column number of X in "X <op> <expr>" */ |
| 159351 | int iField; /* Field in (?,?,?) IN (SELECT...) vector */ |
| 159352 | } x; /* Opcode other than OP_OR or OP_AND */ |
| @@ -161410,40 +161540,40 @@ | |
| 161540 | VdbeCoverageIf(v, testOp==OP_Ge); |
| 161541 | VdbeCoverageIf(v, testOp==OP_Gt); |
| 161542 | sqlite3VdbeChangeP5(v, SQLITE_AFF_NUMERIC | SQLITE_JUMPIFNULL); |
| 161543 | } |
| 161544 | }else if( pLoop->wsFlags & WHERE_INDEXED ){ |
| 161545 | /* Case 4: Search using an index. |
| 161546 | ** |
| 161547 | ** The WHERE clause may contain zero or more equality |
| 161548 | ** terms ("==" or "IN" or "IS" operators) that refer to the N |
| 161549 | ** left-most columns of the index. It may also contain |
| 161550 | ** inequality constraints (>, <, >= or <=) on the indexed |
| 161551 | ** column that immediately follows the N equalities. Only |
| 161552 | ** the right-most column can be an inequality - the rest must |
| 161553 | ** use the "==", "IN", or "IS" operators. For example, if the |
| 161554 | ** index is on (x,y,z), then the following clauses are all |
| 161555 | ** optimized: |
| 161556 | ** |
| 161557 | ** x=5 |
| 161558 | ** x=5 AND y=10 |
| 161559 | ** x=5 AND y<10 |
| 161560 | ** x=5 AND y>5 AND y<10 |
| 161561 | ** x=5 AND y=5 AND z<=10 |
| 161562 | ** |
| 161563 | ** The z<10 term of the following cannot be used, only |
| 161564 | ** the x=5 term: |
| 161565 | ** |
| 161566 | ** x=5 AND z<10 |
| 161567 | ** |
| 161568 | ** N may be zero if there are inequality constraints. |
| 161569 | ** If there are no inequality constraints, then N is at |
| 161570 | ** least one. |
| 161571 | ** |
| 161572 | ** This case is also used when there are no WHERE clause |
| 161573 | ** constraints but an index is selected anyway, in order |
| 161574 | ** to force the output order to conform to an ORDER BY. |
| 161575 | */ |
| 161576 | static const u8 aStartOp[] = { |
| 161577 | 0, |
| 161578 | 0, |
| 161579 | OP_Rewind, /* 2: (!start_constraints && startEq && !bRev) */ |
| @@ -163459,34 +163589,46 @@ | |
| 163589 | ** column references. This routine checks to see if pExpr is an equivalence |
| 163590 | ** relation: |
| 163591 | ** 1. The SQLITE_Transitive optimization must be enabled |
| 163592 | ** 2. Must be either an == or an IS operator |
| 163593 | ** 3. Not originating in the ON clause of an OUTER JOIN |
| 163594 | ** 4. The operator is not IS or else the query does not contain RIGHT JOIN |
| 163595 | ** 5. The affinities of A and B must be compatible |
| 163596 | ** 6a. Both operands use the same collating sequence OR |
| 163597 | ** 6b. The overall collating sequence is BINARY |
| 163598 | ** If this routine returns TRUE, that means that the RHS can be substituted |
| 163599 | ** for the LHS anyplace else in the WHERE clause where the LHS column occurs. |
| 163600 | ** This is an optimization. No harm comes from returning 0. But if 1 is |
| 163601 | ** returned when it should not be, then incorrect answers might result. |
| 163602 | */ |
| 163603 | static int termIsEquivalence(Parse *pParse, Expr *pExpr, SrcList *pSrc){ |
| 163604 | char aff1, aff2; |
| 163605 | CollSeq *pColl; |
| 163606 | if( !OptimizationEnabled(pParse->db, SQLITE_Transitive) ) return 0; /* (1) */ |
| 163607 | if( pExpr->op!=TK_EQ && pExpr->op!=TK_IS ) return 0; /* (2) */ |
| 163608 | if( ExprHasProperty(pExpr, EP_OuterON) ) return 0; /* (3) */ |
| 163609 | assert( pSrc!=0 ); |
| 163610 | if( pExpr->op==TK_IS |
| 163611 | && pSrc->nSrc |
| 163612 | && (pSrc->a[0].fg.jointype & JT_LTORJ)!=0 |
| 163613 | ){ |
| 163614 | return 0; /* (4) */ |
| 163615 | } |
| 163616 | aff1 = sqlite3ExprAffinity(pExpr->pLeft); |
| 163617 | aff2 = sqlite3ExprAffinity(pExpr->pRight); |
| 163618 | if( aff1!=aff2 |
| 163619 | && (!sqlite3IsNumericAffinity(aff1) || !sqlite3IsNumericAffinity(aff2)) |
| 163620 | ){ |
| 163621 | return 0; /* (5) */ |
| 163622 | } |
| 163623 | pColl = sqlite3ExprCompareCollSeq(pParse, pExpr); |
| 163624 | if( !sqlite3IsBinary(pColl) |
| 163625 | && !sqlite3ExprCollSeqMatch(pParse, pExpr->pLeft, pExpr->pRight) |
| 163626 | ){ |
| 163627 | return 0; /* (6) */ |
| 163628 | } |
| 163629 | return 1; |
| 163630 | } |
| 163631 | |
| 163632 | /* |
| 163633 | ** Recursively walk the expressions of a SELECT statement and generate |
| 163634 | ** a bitmask indicating which tables are used in that expression |
| @@ -163640,10 +163782,13 @@ | |
| 163782 | if( db->mallocFailed ){ |
| 163783 | return; |
| 163784 | } |
| 163785 | assert( pWC->nTerm > idxTerm ); |
| 163786 | pTerm = &pWC->a[idxTerm]; |
| 163787 | #ifdef SQLITE_DEBUG |
| 163788 | pTerm->iTerm = idxTerm; |
| 163789 | #endif |
| 163790 | pMaskSet = &pWInfo->sMaskSet; |
| 163791 | pExpr = pTerm->pExpr; |
| 163792 | assert( pExpr!=0 ); /* Because malloc() has not failed */ |
| 163793 | assert( pExpr->op!=TK_AS && pExpr->op!=TK_COLLATE ); |
| 163794 | pMaskSet->bVarSelect = 0; |
| @@ -163747,12 +163892,12 @@ | |
| 163892 | pNew = &pWC->a[idxNew]; |
| 163893 | markTermAsChild(pWC, idxNew, idxTerm); |
| 163894 | if( op==TK_IS ) pNew->wtFlags |= TERM_IS; |
| 163895 | pTerm = &pWC->a[idxTerm]; |
| 163896 | pTerm->wtFlags |= TERM_COPIED; |
| 163897 | assert( pWInfo->pTabList!=0 ); |
| 163898 | if( termIsEquivalence(pParse, pDup, pWInfo->pTabList) ){ |
| 163899 | pTerm->eOperator |= WO_EQUIV; |
| 163900 | eExtraOp = WO_EQUIV; |
| 163901 | } |
| 163902 | }else{ |
| 163903 | pDup = pExpr; |
| @@ -164867,15 +165012,15 @@ | |
| 165012 | continue; |
| 165013 | } |
| 165014 | pScan->pWC = pWC; |
| 165015 | pScan->k = k+1; |
| 165016 | #ifdef WHERETRACE_ENABLED |
| 165017 | if( (sqlite3WhereTrace & 0x20000)!=0 && pScan->nEquiv>1 ){ |
| 165018 | int ii; |
| 165019 | sqlite3DebugPrintf("EQUIVALENT TO {%d:%d} (due to TERM-%d):", |
| 165020 | pScan->aiCur[0], pScan->aiColumn[0], pTerm->iTerm); |
| 165021 | for(ii=1; ii<pScan->nEquiv; ii++){ |
| 165022 | sqlite3DebugPrintf(" {%d:%d}", |
| 165023 | pScan->aiCur[ii], pScan->aiColumn[ii]); |
| 165024 | } |
| 165025 | sqlite3DebugPrintf("\n"); |
| 165026 | } |
| @@ -166826,10 +166971,11 @@ | |
| 166971 | sqlite3_snprintf(sizeof(zLeft),zLeft,"indexable=0x%llx", |
| 166972 | pTerm->u.pOrInfo->indexable); |
| 166973 | }else{ |
| 166974 | sqlite3_snprintf(sizeof(zLeft),zLeft,"left=%d", pTerm->leftCursor); |
| 166975 | } |
| 166976 | iTerm = pTerm->iTerm = MAX(iTerm,pTerm->iTerm); |
| 166977 | sqlite3DebugPrintf( |
| 166978 | "TERM-%-3d %p %s %-12s op=%03x wtFlags=%04x", |
| 166979 | iTerm, pTerm, zType, zLeft, pTerm->eOperator, pTerm->wtFlags); |
| 166980 | /* The 0x10000 .wheretrace flag causes extra information to be |
| 166981 | ** shown about each Term */ |
| @@ -184450,10 +184596,11 @@ | |
| 184596 | #ifdef SQLITE_ENABLE_API_ARMOR |
| 184597 | if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; |
| 184598 | #endif |
| 184599 | if( ms<-1 ) return SQLITE_RANGE; |
| 184600 | #ifdef SQLITE_ENABLE_SETLK_TIMEOUT |
| 184601 | sqlite3_mutex_enter(db->mutex); |
| 184602 | db->setlkTimeout = ms; |
| 184603 | db->setlkFlags = flags; |
| 184604 | sqlite3BtreeEnterAll(db); |
| 184605 | for(iDb=0; iDb<db->nDb; iDb++){ |
| 184606 | Btree *pBt = db->aDb[iDb].pBt; |
| @@ -184461,10 +184608,11 @@ | |
| 184608 | sqlite3_file *fd = sqlite3PagerFile(sqlite3BtreePager(pBt)); |
| 184609 | sqlite3OsFileControlHint(fd, SQLITE_FCNTL_BLOCK_ON_CONNECT, (void*)&bBOC); |
| 184610 | } |
| 184611 | } |
| 184612 | sqlite3BtreeLeaveAll(db); |
| 184613 | sqlite3_mutex_leave(db->mutex); |
| 184614 | #endif |
| 184615 | #if !defined(SQLITE_ENABLE_API_ARMOR) && !defined(SQLITE_ENABLE_SETLK_TIMEOUT) |
| 184616 | UNUSED_PARAMETER(db); |
| 184617 | UNUSED_PARAMETER(flags); |
| 184618 | #endif |
| @@ -257257,11 +257405,11 @@ | |
| 257405 | int nArg, /* Number of args */ |
| 257406 | sqlite3_value **apUnused /* Function arguments */ |
| 257407 | ){ |
| 257408 | assert( nArg==0 ); |
| 257409 | UNUSED_PARAM2(nArg, apUnused); |
| 257410 | sqlite3_result_text(pCtx, "fts5: 2025-06-19 20:19:12 a88bb75288a06492a04ab1278e8a2101a74f4ba712d328b4c73e86ac01cb946d", -1, SQLITE_TRANSIENT); |
| 257411 | } |
| 257412 | |
| 257413 | /* |
| 257414 | ** Implementation of fts5_locale(LOCALE, TEXT) function. |
| 257415 | ** |
| @@ -258072,10 +258220,11 @@ | |
| 258220 | ctx.pStorage = p; |
| 258221 | ctx.iCol = -1; |
| 258222 | for(iCol=1; rc==SQLITE_OK && iCol<=pConfig->nCol; iCol++){ |
| 258223 | if( pConfig->abUnindexed[iCol-1]==0 ){ |
| 258224 | sqlite3_value *pVal = 0; |
| 258225 | sqlite3_value *pFree = 0; |
| 258226 | const char *pText = 0; |
| 258227 | int nText = 0; |
| 258228 | const char *pLoc = 0; |
| 258229 | int nLoc = 0; |
| 258230 | |
| @@ -258088,15 +258237,26 @@ | |
| 258237 | } |
| 258238 | |
| 258239 | if( pConfig->bLocale && sqlite3Fts5IsLocaleValue(pConfig, pVal) ){ |
| 258240 | rc = sqlite3Fts5DecodeLocaleValue(pVal, &pText, &nText, &pLoc, &nLoc); |
| 258241 | }else{ |
| 258242 | if( sqlite3_value_type(pVal)!=SQLITE_TEXT ){ |
| 258243 | /* Make a copy of the value to work with. This is because the call |
| 258244 | ** to sqlite3_value_text() below forces the type of the value to |
| 258245 | ** SQLITE_TEXT, and we may need to use it again later. */ |
| 258246 | pFree = pVal = sqlite3_value_dup(pVal); |
| 258247 | if( pVal==0 ){ |
| 258248 | rc = SQLITE_NOMEM; |
| 258249 | } |
| 258250 | } |
| 258251 | if( rc==SQLITE_OK ){ |
| 258252 | pText = (const char*)sqlite3_value_text(pVal); |
| 258253 | nText = sqlite3_value_bytes(pVal); |
| 258254 | if( pConfig->bLocale && pSeek ){ |
| 258255 | pLoc = (const char*)sqlite3_column_text(pSeek, iCol+pConfig->nCol); |
| 258256 | nLoc = sqlite3_column_bytes(pSeek, iCol + pConfig->nCol); |
| 258257 | } |
| 258258 | } |
| 258259 | } |
| 258260 | |
| 258261 | if( rc==SQLITE_OK ){ |
| 258262 | sqlite3Fts5SetLocale(pConfig, pLoc, nLoc); |
| @@ -258108,10 +258268,11 @@ | |
| 258268 | if( rc==SQLITE_OK && p->aTotalSize[iCol-1]<0 ){ |
| 258269 | rc = FTS5_CORRUPT; |
| 258270 | } |
| 258271 | sqlite3Fts5ClearLocale(pConfig); |
| 258272 | } |
| 258273 | sqlite3_value_free(pFree); |
| 258274 | } |
| 258275 | } |
| 258276 | if( rc==SQLITE_OK && p->nTotalRow<1 ){ |
| 258277 | rc = FTS5_CORRUPT; |
| 258278 | }else{ |
| 258279 |
+265
-104
| --- extsrc/sqlite3.c | ||
| +++ extsrc/sqlite3.c | ||
| @@ -16,11 +16,11 @@ | ||
| 16 | 16 | ** if you want a wrapper to interface SQLite with your choice of programming |
| 17 | 17 | ** language. The code for the "sqlite3" command-line shell is also in a |
| 18 | 18 | ** separate file. This file contains only code for the core SQLite library. |
| 19 | 19 | ** |
| 20 | 20 | ** The content in this amalgamation comes from Fossil check-in |
| 21 | -** ea1754f7d8a770477a1b19b606b27724fdc0 with changes in files: | |
| 21 | +** a88bb75288a06492a04ab1278e8a2101a74f with changes in files: | |
| 22 | 22 | ** |
| 23 | 23 | ** |
| 24 | 24 | */ |
| 25 | 25 | #ifndef SQLITE_AMALGAMATION |
| 26 | 26 | #define SQLITE_CORE 1 |
| @@ -465,11 +465,11 @@ | ||
| 465 | 465 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 466 | 466 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 467 | 467 | */ |
| 468 | 468 | #define SQLITE_VERSION "3.51.0" |
| 469 | 469 | #define SQLITE_VERSION_NUMBER 3051000 |
| 470 | -#define SQLITE_SOURCE_ID "2025-06-03 10:49:51 ea1754f7d8a770477a1b19b606b27724fdc0b733e51fef32c1ef834f972c3cc5" | |
| 470 | +#define SQLITE_SOURCE_ID "2025-06-19 20:19:12 a88bb75288a06492a04ab1278e8a2101a74f4ba712d328b4c73e86ac01cb946d" | |
| 471 | 471 | |
| 472 | 472 | /* |
| 473 | 473 | ** CAPI3REF: Run-Time Library Version Numbers |
| 474 | 474 | ** KEYWORDS: sqlite3_version sqlite3_sourceid |
| 475 | 475 | ** |
| @@ -4396,11 +4396,11 @@ | ||
| 4396 | 4396 | ** These interfaces are provided for use by [VFS shim] implementations and |
| 4397 | 4397 | ** are not useful outside of that context. |
| 4398 | 4398 | ** |
| 4399 | 4399 | ** The sqlite3_create_filename(D,J,W,N,P) allocates memory to hold a version of |
| 4400 | 4400 | ** database filename D with corresponding journal file J and WAL file W and |
| 4401 | -** with N URI parameters key/values pairs in the array P. The result from | |
| 4401 | +** an array P of N URI Key/Value pairs. The result from | |
| 4402 | 4402 | ** sqlite3_create_filename(D,J,W,N,P) is a pointer to a database filename that |
| 4403 | 4403 | ** is safe to pass to routines like: |
| 4404 | 4404 | ** <ul> |
| 4405 | 4405 | ** <li> [sqlite3_uri_parameter()], |
| 4406 | 4406 | ** <li> [sqlite3_uri_boolean()], |
| @@ -5077,11 +5077,11 @@ | ||
| 5077 | 5077 | ** KEYWORDS: {host parameter} {host parameters} {host parameter name} |
| 5078 | 5078 | ** KEYWORDS: {SQL parameter} {SQL parameters} {parameter binding} |
| 5079 | 5079 | ** METHOD: sqlite3_stmt |
| 5080 | 5080 | ** |
| 5081 | 5081 | ** ^(In the SQL statement text input to [sqlite3_prepare_v2()] and its variants, |
| 5082 | -** literals may be replaced by a [parameter] that matches one of following | |
| 5082 | +** literals may be replaced by a [parameter] that matches one of the following | |
| 5083 | 5083 | ** templates: |
| 5084 | 5084 | ** |
| 5085 | 5085 | ** <ul> |
| 5086 | 5086 | ** <li> ? |
| 5087 | 5087 | ** <li> ?NNN |
| @@ -5122,11 +5122,11 @@ | ||
| 5122 | 5122 | ** either UTF8 if the sixth parameter is SQLITE_UTF8, or UTF16 |
| 5123 | 5123 | ** otherwise. |
| 5124 | 5124 | ** |
| 5125 | 5125 | ** [[byte-order determination rules]] ^The byte-order of |
| 5126 | 5126 | ** UTF16 input text is determined by the byte-order mark (BOM, U+FEFF) |
| 5127 | -** found in first character, which is removed, or in the absence of a BOM | |
| 5127 | +** found in the first character, which is removed, or in the absence of a BOM | |
| 5128 | 5128 | ** the byte order is the native byte order of the host |
| 5129 | 5129 | ** machine for sqlite3_bind_text16() or the byte order specified in |
| 5130 | 5130 | ** the 6th parameter for sqlite3_bind_text64().)^ |
| 5131 | 5131 | ** ^If UTF16 input text contains invalid unicode |
| 5132 | 5132 | ** characters, then SQLite might change those invalid characters |
| @@ -5142,11 +5142,11 @@ | ||
| 5142 | 5142 | ** the behavior is undefined. |
| 5143 | 5143 | ** If a non-negative fourth parameter is provided to sqlite3_bind_text() |
| 5144 | 5144 | ** or sqlite3_bind_text16() or sqlite3_bind_text64() then |
| 5145 | 5145 | ** that parameter must be the byte offset |
| 5146 | 5146 | ** where the NUL terminator would occur assuming the string were NUL |
| 5147 | -** terminated. If any NUL characters occurs at byte offsets less than | |
| 5147 | +** terminated. If any NUL characters occur at byte offsets less than | |
| 5148 | 5148 | ** the value of the fourth parameter then the resulting string value will |
| 5149 | 5149 | ** contain embedded NULs. The result of expressions involving strings |
| 5150 | 5150 | ** with embedded NULs is undefined. |
| 5151 | 5151 | ** |
| 5152 | 5152 | ** ^The fifth argument to the BLOB and string binding interfaces controls |
| @@ -5354,11 +5354,11 @@ | ||
| 5354 | 5354 | /* |
| 5355 | 5355 | ** CAPI3REF: Source Of Data In A Query Result |
| 5356 | 5356 | ** METHOD: sqlite3_stmt |
| 5357 | 5357 | ** |
| 5358 | 5358 | ** ^These routines provide a means to determine the database, table, and |
| 5359 | -** table column that is the origin of a particular result column in | |
| 5359 | +** table column that is the origin of a particular result column in a | |
| 5360 | 5360 | ** [SELECT] statement. |
| 5361 | 5361 | ** ^The name of the database or table or column can be returned as |
| 5362 | 5362 | ** either a UTF-8 or UTF-16 string. ^The _database_ routines return |
| 5363 | 5363 | ** the database name, the _table_ routines return the table name, and |
| 5364 | 5364 | ** the origin_ routines return the column name. |
| @@ -5923,12 +5923,12 @@ | ||
| 5923 | 5923 | ** within VIEWs, TRIGGERs, CHECK constraints, generated column expressions, |
| 5924 | 5924 | ** index expressions, or the WHERE clause of partial indexes. |
| 5925 | 5925 | ** |
| 5926 | 5926 | ** For best security, the [SQLITE_DIRECTONLY] flag is recommended for |
| 5927 | 5927 | ** all application-defined SQL functions that do not need to be |
| 5928 | -** used inside of triggers, view, CHECK constraints, or other elements of | |
| 5929 | -** the database schema. This flags is especially recommended for SQL | |
| 5928 | +** used inside of triggers, views, CHECK constraints, or other elements of | |
| 5929 | +** the database schema. This flag is especially recommended for SQL | |
| 5930 | 5930 | ** functions that have side effects or reveal internal application state. |
| 5931 | 5931 | ** Without this flag, an attacker might be able to modify the schema of |
| 5932 | 5932 | ** a database file to include invocations of the function with parameters |
| 5933 | 5933 | ** chosen by the attacker, which the application will then execute when |
| 5934 | 5934 | ** the database file is opened and read. |
| @@ -5955,11 +5955,11 @@ | ||
| 5955 | 5955 | ** or aggregate window function. More details regarding the implementation |
| 5956 | 5956 | ** of aggregate window functions are |
| 5957 | 5957 | ** [user-defined window functions|available here]. |
| 5958 | 5958 | ** |
| 5959 | 5959 | ** ^(If the final parameter to sqlite3_create_function_v2() or |
| 5960 | -** sqlite3_create_window_function() is not NULL, then it is destructor for | |
| 5960 | +** sqlite3_create_window_function() is not NULL, then it is the destructor for | |
| 5961 | 5961 | ** the application data pointer. The destructor is invoked when the function |
| 5962 | 5962 | ** is deleted, either by being overloaded or when the database connection |
| 5963 | 5963 | ** closes.)^ ^The destructor is also invoked if the call to |
| 5964 | 5964 | ** sqlite3_create_function_v2() fails. ^When the destructor callback is |
| 5965 | 5965 | ** invoked, it is passed a single argument which is a copy of the application |
| @@ -7763,11 +7763,11 @@ | ||
| 7763 | 7763 | ** that is to be automatically loaded into all new database connections. |
| 7764 | 7764 | ** |
| 7765 | 7765 | ** ^(Even though the function prototype shows that xEntryPoint() takes |
| 7766 | 7766 | ** no arguments and returns void, SQLite invokes xEntryPoint() with three |
| 7767 | 7767 | ** arguments and expects an integer result as if the signature of the |
| 7768 | -** entry point where as follows: | |
| 7768 | +** entry point were as follows: | |
| 7769 | 7769 | ** |
| 7770 | 7770 | ** <blockquote><pre> |
| 7771 | 7771 | ** int xEntryPoint( |
| 7772 | 7772 | ** sqlite3 *db, |
| 7773 | 7773 | ** const char **pzErrMsg, |
| @@ -8094,11 +8094,11 @@ | ||
| 8094 | 8094 | ** by the first parameter. ^The name of the module is given by the |
| 8095 | 8095 | ** second parameter. ^The third parameter is a pointer to |
| 8096 | 8096 | ** the implementation of the [virtual table module]. ^The fourth |
| 8097 | 8097 | ** parameter is an arbitrary client data pointer that is passed through |
| 8098 | 8098 | ** into the [xCreate] and [xConnect] methods of the virtual table module |
| 8099 | -** when a new virtual table is be being created or reinitialized. | |
| 8099 | +** when a new virtual table is being created or reinitialized. | |
| 8100 | 8100 | ** |
| 8101 | 8101 | ** ^The sqlite3_create_module_v2() interface has a fifth parameter which |
| 8102 | 8102 | ** is a pointer to a destructor for the pClientData. ^SQLite will |
| 8103 | 8103 | ** invoke the destructor function (if it is not NULL) when SQLite |
| 8104 | 8104 | ** no longer needs the pClientData pointer. ^The destructor will also |
| @@ -8259,11 +8259,11 @@ | ||
| 8259 | 8259 | ** |
| 8260 | 8260 | ** ^(On success, [SQLITE_OK] is returned and the new [BLOB handle] is stored |
| 8261 | 8261 | ** in *ppBlob. Otherwise an [error code] is returned and, unless the error |
| 8262 | 8262 | ** code is SQLITE_MISUSE, *ppBlob is set to NULL.)^ ^This means that, provided |
| 8263 | 8263 | ** the API is not misused, it is always safe to call [sqlite3_blob_close()] |
| 8264 | -** on *ppBlob after this function it returns. | |
| 8264 | +** on *ppBlob after this function returns. | |
| 8265 | 8265 | ** |
| 8266 | 8266 | ** This function fails with SQLITE_ERROR if any of the following are true: |
| 8267 | 8267 | ** <ul> |
| 8268 | 8268 | ** <li> ^(Database zDb does not exist)^, |
| 8269 | 8269 | ** <li> ^(Table zTable does not exist within database zDb)^, |
| @@ -8379,11 +8379,11 @@ | ||
| 8379 | 8379 | ** CAPI3REF: Return The Size Of An Open BLOB |
| 8380 | 8380 | ** METHOD: sqlite3_blob |
| 8381 | 8381 | ** |
| 8382 | 8382 | ** ^Returns the size in bytes of the BLOB accessible via the |
| 8383 | 8383 | ** successfully opened [BLOB handle] in its only argument. ^The |
| 8384 | -** incremental blob I/O routines can only read or overwriting existing | |
| 8384 | +** incremental blob I/O routines can only read or overwrite existing | |
| 8385 | 8385 | ** blob content; they cannot change the size of a blob. |
| 8386 | 8386 | ** |
| 8387 | 8387 | ** This routine only works on a [BLOB handle] which has been created |
| 8388 | 8388 | ** by a prior successful call to [sqlite3_blob_open()] and which has not |
| 8389 | 8389 | ** been closed by [sqlite3_blob_close()]. Passing any other pointer in |
| @@ -9782,11 +9782,11 @@ | ||
| 9782 | 9782 | ** sqlite3_backup_step(), the source database may be modified mid-way |
| 9783 | 9783 | ** through the backup process. ^If the source database is modified by an |
| 9784 | 9784 | ** external process or via a database connection other than the one being |
| 9785 | 9785 | ** used by the backup operation, then the backup will be automatically |
| 9786 | 9786 | ** restarted by the next call to sqlite3_backup_step(). ^If the source |
| 9787 | -** database is modified by the using the same database connection as is used | |
| 9787 | +** database is modified by using the same database connection as is used | |
| 9788 | 9788 | ** by the backup operation, then the backup database is automatically |
| 9789 | 9789 | ** updated at the same time. |
| 9790 | 9790 | ** |
| 9791 | 9791 | ** [[sqlite3_backup_finish()]] <b>sqlite3_backup_finish()</b> |
| 9792 | 9792 | ** |
| @@ -9799,11 +9799,11 @@ | ||
| 9799 | 9799 | ** active write-transaction on the destination database is rolled back. |
| 9800 | 9800 | ** The [sqlite3_backup] object is invalid |
| 9801 | 9801 | ** and may not be used following a call to sqlite3_backup_finish(). |
| 9802 | 9802 | ** |
| 9803 | 9803 | ** ^The value returned by sqlite3_backup_finish is [SQLITE_OK] if no |
| 9804 | -** sqlite3_backup_step() errors occurred, regardless or whether or not | |
| 9804 | +** sqlite3_backup_step() errors occurred, regardless of whether or not | |
| 9805 | 9805 | ** sqlite3_backup_step() completed. |
| 9806 | 9806 | ** ^If an out-of-memory condition or IO error occurred during any prior |
| 9807 | 9807 | ** sqlite3_backup_step() call on the same [sqlite3_backup] object, then |
| 9808 | 9808 | ** sqlite3_backup_finish() returns the corresponding [error code]. |
| 9809 | 9809 | ** |
| @@ -10869,11 +10869,11 @@ | ||
| 10869 | 10869 | /* |
| 10870 | 10870 | ** CAPI3REF: Flush caches to disk mid-transaction |
| 10871 | 10871 | ** METHOD: sqlite3 |
| 10872 | 10872 | ** |
| 10873 | 10873 | ** ^If a write-transaction is open on [database connection] D when the |
| 10874 | -** [sqlite3_db_cacheflush(D)] interface invoked, any dirty | |
| 10874 | +** [sqlite3_db_cacheflush(D)] interface is invoked, any dirty | |
| 10875 | 10875 | ** pages in the pager-cache that are not currently in use are written out |
| 10876 | 10876 | ** to disk. A dirty page may be in use if a database cursor created by an |
| 10877 | 10877 | ** active SQL statement is reading from it, or if it is page 1 of a database |
| 10878 | 10878 | ** file (page 1 is always "in use"). ^The [sqlite3_db_cacheflush(D)] |
| 10879 | 10879 | ** interface flushes caches for all schemas - "main", "temp", and |
| @@ -15562,10 +15562,11 @@ | ||
| 15562 | 15562 | ** 0x00008000 After all FROM-clause analysis |
| 15563 | 15563 | ** 0x00010000 Beginning of DELETE/INSERT/UPDATE processing |
| 15564 | 15564 | ** 0x00020000 Transform DISTINCT into GROUP BY |
| 15565 | 15565 | ** 0x00040000 SELECT tree dump after all code has been generated |
| 15566 | 15566 | ** 0x00080000 NOT NULL strength reduction |
| 15567 | +** 0x00100000 Pointers are all shown as zero | |
| 15567 | 15568 | */ |
| 15568 | 15569 | |
| 15569 | 15570 | /* |
| 15570 | 15571 | ** Macros for "wheretrace" |
| 15571 | 15572 | */ |
| @@ -15606,10 +15607,11 @@ | ||
| 15606 | 15607 | ** |
| 15607 | 15608 | ** 0x00010000 Show more detail when printing WHERE terms |
| 15608 | 15609 | ** 0x00020000 Show WHERE terms returned from whereScanNext() |
| 15609 | 15610 | ** 0x00040000 Solver overview messages |
| 15610 | 15611 | ** 0x00080000 Star-query heuristic |
| 15612 | +** 0x00100000 Pointers are all shown as zero | |
| 15611 | 15613 | */ |
| 15612 | 15614 | |
| 15613 | 15615 | |
| 15614 | 15616 | /* |
| 15615 | 15617 | ** An instance of the following structure is used to store the busy-handler |
| @@ -15678,11 +15680,11 @@ | ||
| 15678 | 15680 | ** one parameter that destructors normally want. So we have to introduce |
| 15679 | 15681 | ** this magic value that the code knows to handle differently. Any |
| 15680 | 15682 | ** pointer will work here as long as it is distinct from SQLITE_STATIC |
| 15681 | 15683 | ** and SQLITE_TRANSIENT. |
| 15682 | 15684 | */ |
| 15683 | -#define SQLITE_DYNAMIC ((sqlite3_destructor_type)sqlite3OomClear) | |
| 15685 | +#define SQLITE_DYNAMIC ((sqlite3_destructor_type)sqlite3RowSetClear) | |
| 15684 | 15686 | |
| 15685 | 15687 | /* |
| 15686 | 15688 | ** When SQLITE_OMIT_WSD is defined, it means that the target platform does |
| 15687 | 15689 | ** not support Writable Static Data (WSD) such as global and static variables. |
| 15688 | 15690 | ** All variables must either be on the stack or dynamically allocated from |
| @@ -21266,10 +21268,11 @@ | ||
| 21266 | 21268 | #endif |
| 21267 | 21269 | #ifndef SQLITE_OMIT_WINDOWFUNC |
| 21268 | 21270 | SQLITE_PRIVATE void sqlite3ShowWindow(const Window*); |
| 21269 | 21271 | SQLITE_PRIVATE void sqlite3ShowWinFunc(const Window*); |
| 21270 | 21272 | #endif |
| 21273 | +SQLITE_PRIVATE void sqlite3ShowBitvec(Bitvec*); | |
| 21271 | 21274 | #endif |
| 21272 | 21275 | |
| 21273 | 21276 | SQLITE_PRIVATE void sqlite3SetString(char **, sqlite3*, const char*); |
| 21274 | 21277 | SQLITE_PRIVATE void sqlite3ProgressCheck(Parse*); |
| 21275 | 21278 | SQLITE_PRIVATE void sqlite3ErrorMsg(Parse*, const char*, ...); |
| @@ -32077,10 +32080,18 @@ | ||
| 32077 | 32080 | }else{ |
| 32078 | 32081 | longvalue = va_arg(ap,unsigned int); |
| 32079 | 32082 | } |
| 32080 | 32083 | prefix = 0; |
| 32081 | 32084 | } |
| 32085 | + | |
| 32086 | +#if WHERETRACE_ENABLED | |
| 32087 | + if( xtype==etPOINTER && sqlite3WhereTrace & 0x100000 ) longvalue = 0; | |
| 32088 | +#endif | |
| 32089 | +#if TREETRACE_ENABLED | |
| 32090 | + if( xtype==etPOINTER && sqlite3TreeTrace & 0x100000 ) longvalue = 0; | |
| 32091 | +#endif | |
| 32092 | + | |
| 32082 | 32093 | if( longvalue==0 ) flag_alternateform = 0; |
| 32083 | 32094 | if( flag_zeropad && precision<width-(prefix!=0) ){ |
| 32084 | 32095 | precision = width-(prefix!=0); |
| 32085 | 32096 | } |
| 32086 | 32097 | if( precision<etBUFSIZE-10-etBUFSIZE/3 ){ |
| @@ -54872,10 +54883,11 @@ | ||
| 54872 | 54883 | BITVEC_TELEM aBitmap[BITVEC_NELEM]; /* Bitmap representation */ |
| 54873 | 54884 | u32 aHash[BITVEC_NINT]; /* Hash table representation */ |
| 54874 | 54885 | Bitvec *apSub[BITVEC_NPTR]; /* Recursive representation */ |
| 54875 | 54886 | } u; |
| 54876 | 54887 | }; |
| 54888 | + | |
| 54877 | 54889 | |
| 54878 | 54890 | /* |
| 54879 | 54891 | ** Create a new bitmap object able to handle bits between 0 and iSize, |
| 54880 | 54892 | ** inclusive. Return a pointer to the new object. Return NULL if |
| 54881 | 54893 | ** malloc fails. |
| @@ -54982,11 +54994,13 @@ | ||
| 54982 | 54994 | if( aiValues==0 ){ |
| 54983 | 54995 | return SQLITE_NOMEM_BKPT; |
| 54984 | 54996 | }else{ |
| 54985 | 54997 | memcpy(aiValues, p->u.aHash, sizeof(p->u.aHash)); |
| 54986 | 54998 | memset(p->u.apSub, 0, sizeof(p->u.apSub)); |
| 54987 | - p->iDivisor = (p->iSize + BITVEC_NPTR - 1)/BITVEC_NPTR; | |
| 54999 | + p->iDivisor = p->iSize/BITVEC_NPTR; | |
| 55000 | + if( (p->iSize%BITVEC_NPTR)!=0 ) p->iDivisor++; | |
| 55001 | + if( p->iDivisor<BITVEC_NBIT ) p->iDivisor = BITVEC_NBIT; | |
| 54988 | 55002 | rc = sqlite3BitvecSet(p, i); |
| 54989 | 55003 | for(j=0; j<BITVEC_NINT; j++){ |
| 54990 | 55004 | if( aiValues[j] ) rc |= sqlite3BitvecSet(p, aiValues[j]); |
| 54991 | 55005 | } |
| 54992 | 55006 | sqlite3StackFree(0, aiValues); |
| @@ -55058,10 +55072,56 @@ | ||
| 55058 | 55072 | ** was created. |
| 55059 | 55073 | */ |
| 55060 | 55074 | SQLITE_PRIVATE u32 sqlite3BitvecSize(Bitvec *p){ |
| 55061 | 55075 | return p->iSize; |
| 55062 | 55076 | } |
| 55077 | + | |
| 55078 | +#ifdef SQLITE_DEBUG | |
| 55079 | +/* | |
| 55080 | +** Show the content of a Bitvec option and its children. Indent | |
| 55081 | +** everything by n spaces. Add x to each bitvec value. | |
| 55082 | +** | |
| 55083 | +** From a debugger such as gdb, one can type: | |
| 55084 | +** | |
| 55085 | +** call sqlite3ShowBitvec(p) | |
| 55086 | +** | |
| 55087 | +** For some Bitvec p and see a recursive view of the Bitvec's content. | |
| 55088 | +*/ | |
| 55089 | +static void showBitvec(Bitvec *p, int n, unsigned x){ | |
| 55090 | + int i; | |
| 55091 | + if( p==0 ){ | |
| 55092 | + printf("NULL\n"); | |
| 55093 | + return; | |
| 55094 | + } | |
| 55095 | + printf("Bitvec 0x%p iSize=%u", p, p->iSize); | |
| 55096 | + if( p->iSize<=BITVEC_NBIT ){ | |
| 55097 | + printf(" bitmap\n"); | |
| 55098 | + printf("%*s bits:", n, ""); | |
| 55099 | + for(i=1; i<=BITVEC_NBIT; i++){ | |
| 55100 | + if( sqlite3BitvecTest(p,i) ) printf(" %u", x+(unsigned)i); | |
| 55101 | + } | |
| 55102 | + printf("\n"); | |
| 55103 | + }else if( p->iDivisor==0 ){ | |
| 55104 | + printf(" hash with %u entries\n", p->nSet); | |
| 55105 | + printf("%*s bits:", n, ""); | |
| 55106 | + for(i=0; i<BITVEC_NINT; i++){ | |
| 55107 | + if( p->u.aHash[i] ) printf(" %u", x+(unsigned)p->u.aHash[i]); | |
| 55108 | + } | |
| 55109 | + printf("\n"); | |
| 55110 | + }else{ | |
| 55111 | + printf(" sub-bitvec with iDivisor=%u\n", p->iDivisor); | |
| 55112 | + for(i=0; i<BITVEC_NPTR; i++){ | |
| 55113 | + if( p->u.apSub[i]==0 ) continue; | |
| 55114 | + printf("%*s apSub[%d]=", n, "", i); | |
| 55115 | + showBitvec(p->u.apSub[i], n+4, i*p->iDivisor); | |
| 55116 | + } | |
| 55117 | + } | |
| 55118 | +} | |
| 55119 | +SQLITE_PRIVATE void sqlite3ShowBitvec(Bitvec *p){ | |
| 55120 | + showBitvec(p, 0, 0); | |
| 55121 | +} | |
| 55122 | +#endif | |
| 55063 | 55123 | |
| 55064 | 55124 | #ifndef SQLITE_UNTESTABLE |
| 55065 | 55125 | /* |
| 55066 | 55126 | ** Let V[] be an array of unsigned characters sufficient to hold |
| 55067 | 55127 | ** up to N bits. Let I be an integer between 0 and N. 0<=I<N. |
| @@ -55069,40 +55129,48 @@ | ||
| 55069 | 55129 | ** individual bits within V. |
| 55070 | 55130 | */ |
| 55071 | 55131 | #define SETBIT(V,I) V[I>>3] |= (1<<(I&7)) |
| 55072 | 55132 | #define CLEARBIT(V,I) V[I>>3] &= ~(BITVEC_TELEM)(1<<(I&7)) |
| 55073 | 55133 | #define TESTBIT(V,I) (V[I>>3]&(1<<(I&7)))!=0 |
| 55134 | + | |
| 55074 | 55135 | |
| 55075 | 55136 | /* |
| 55076 | 55137 | ** This routine runs an extensive test of the Bitvec code. |
| 55077 | 55138 | ** |
| 55078 | 55139 | ** The input is an array of integers that acts as a program |
| 55079 | 55140 | ** to test the Bitvec. The integers are opcodes followed |
| 55080 | 55141 | ** by 0, 1, or 3 operands, depending on the opcode. Another |
| 55081 | 55142 | ** opcode follows immediately after the last operand. |
| 55082 | 55143 | ** |
| 55083 | -** There are 6 opcodes numbered from 0 through 5. 0 is the | |
| 55144 | +** There are opcodes numbered starting with 0. 0 is the | |
| 55084 | 55145 | ** "halt" opcode and causes the test to end. |
| 55085 | 55146 | ** |
| 55086 | 55147 | ** 0 Halt and return the number of errors |
| 55087 | 55148 | ** 1 N S X Set N bits beginning with S and incrementing by X |
| 55088 | 55149 | ** 2 N S X Clear N bits beginning with S and incrementing by X |
| 55089 | 55150 | ** 3 N Set N randomly chosen bits |
| 55090 | 55151 | ** 4 N Clear N randomly chosen bits |
| 55091 | 55152 | ** 5 N S X Set N bits from S increment X in array only, not in bitvec |
| 55153 | +** 6 Invoice sqlite3ShowBitvec() on the Bitvec object so far | |
| 55154 | +** 7 X Show compile-time parameters and the hash of X | |
| 55092 | 55155 | ** |
| 55093 | 55156 | ** The opcodes 1 through 4 perform set and clear operations are performed |
| 55094 | 55157 | ** on both a Bitvec object and on a linear array of bits obtained from malloc. |
| 55095 | 55158 | ** Opcode 5 works on the linear array only, not on the Bitvec. |
| 55096 | 55159 | ** Opcode 5 is used to deliberately induce a fault in order to |
| 55097 | -** confirm that error detection works. | |
| 55160 | +** confirm that error detection works. Opcodes 6 and greater are | |
| 55161 | +** state output opcodes. Opcodes 6 and greater are no-ops unless | |
| 55162 | +** SQLite has been compiled with SQLITE_DEBUG. | |
| 55098 | 55163 | ** |
| 55099 | 55164 | ** At the conclusion of the test the linear array is compared |
| 55100 | 55165 | ** against the Bitvec object. If there are any differences, |
| 55101 | 55166 | ** an error is returned. If they are the same, zero is returned. |
| 55102 | 55167 | ** |
| 55103 | 55168 | ** If a memory allocation error occurs, return -1. |
| 55169 | +** | |
| 55170 | +** sz is the size of the Bitvec. Or if sz is negative, make the size | |
| 55171 | +** 2*(unsigned)(-sz) and disabled the linear vector check. | |
| 55104 | 55172 | */ |
| 55105 | 55173 | SQLITE_PRIVATE int sqlite3BitvecBuiltinTest(int sz, int *aOp){ |
| 55106 | 55174 | Bitvec *pBitvec = 0; |
| 55107 | 55175 | unsigned char *pV = 0; |
| 55108 | 55176 | int rc = -1; |
| @@ -55109,22 +55177,45 @@ | ||
| 55109 | 55177 | int i, nx, pc, op; |
| 55110 | 55178 | void *pTmpSpace; |
| 55111 | 55179 | |
| 55112 | 55180 | /* Allocate the Bitvec to be tested and a linear array of |
| 55113 | 55181 | ** bits to act as the reference */ |
| 55114 | - pBitvec = sqlite3BitvecCreate( sz ); | |
| 55115 | - pV = sqlite3MallocZero( (7+(i64)sz)/8 + 1 ); | |
| 55182 | + if( sz<=0 ){ | |
| 55183 | + pBitvec = sqlite3BitvecCreate( 2*(unsigned)(-sz) ); | |
| 55184 | + pV = 0; | |
| 55185 | + }else{ | |
| 55186 | + pBitvec = sqlite3BitvecCreate( sz ); | |
| 55187 | + pV = sqlite3MallocZero( (7+(i64)sz)/8 + 1 ); | |
| 55188 | + } | |
| 55116 | 55189 | pTmpSpace = sqlite3_malloc64(BITVEC_SZ); |
| 55117 | - if( pBitvec==0 || pV==0 || pTmpSpace==0 ) goto bitvec_end; | |
| 55190 | + if( pBitvec==0 || pTmpSpace==0 || (pV==0 && sz>0) ) goto bitvec_end; | |
| 55118 | 55191 | |
| 55119 | 55192 | /* NULL pBitvec tests */ |
| 55120 | 55193 | sqlite3BitvecSet(0, 1); |
| 55121 | 55194 | sqlite3BitvecClear(0, 1, pTmpSpace); |
| 55122 | 55195 | |
| 55123 | 55196 | /* Run the program */ |
| 55124 | 55197 | pc = i = 0; |
| 55125 | 55198 | while( (op = aOp[pc])!=0 ){ |
| 55199 | + if( op>=6 ){ | |
| 55200 | +#ifdef SQLITE_DEBUG | |
| 55201 | + if( op==6 ){ | |
| 55202 | + sqlite3ShowBitvec(pBitvec); | |
| 55203 | + }else if( op==7 ){ | |
| 55204 | + printf("BITVEC_SZ = %d (%d by sizeof)\n", | |
| 55205 | + BITVEC_SZ, (int)sizeof(Bitvec)); | |
| 55206 | + printf("BITVEC_USIZE = %d\n", (int)BITVEC_USIZE); | |
| 55207 | + printf("BITVEC_NELEM = %d\n", (int)BITVEC_NELEM); | |
| 55208 | + printf("BITVEC_NBIT = %d\n", (int)BITVEC_NBIT); | |
| 55209 | + printf("BITVEC_NINT = %d\n", (int)BITVEC_NINT); | |
| 55210 | + printf("BITVEC_MXHASH = %d\n", (int)BITVEC_MXHASH); | |
| 55211 | + printf("BITVEC_NPTR = %d\n", (int)BITVEC_NPTR); | |
| 55212 | + } | |
| 55213 | +#endif | |
| 55214 | + pc++; | |
| 55215 | + continue; | |
| 55216 | + } | |
| 55126 | 55217 | switch( op ){ |
| 55127 | 55218 | case 1: |
| 55128 | 55219 | case 2: |
| 55129 | 55220 | case 5: { |
| 55130 | 55221 | nx = 4; |
| @@ -55142,33 +55233,37 @@ | ||
| 55142 | 55233 | } |
| 55143 | 55234 | if( (--aOp[pc+1]) > 0 ) nx = 0; |
| 55144 | 55235 | pc += nx; |
| 55145 | 55236 | i = (i & 0x7fffffff)%sz; |
| 55146 | 55237 | if( (op & 1)!=0 ){ |
| 55147 | - SETBIT(pV, (i+1)); | |
| 55238 | + if( pV ) SETBIT(pV, (i+1)); | |
| 55148 | 55239 | if( op!=5 ){ |
| 55149 | 55240 | if( sqlite3BitvecSet(pBitvec, i+1) ) goto bitvec_end; |
| 55150 | 55241 | } |
| 55151 | 55242 | }else{ |
| 55152 | - CLEARBIT(pV, (i+1)); | |
| 55243 | + if( pV ) CLEARBIT(pV, (i+1)); | |
| 55153 | 55244 | sqlite3BitvecClear(pBitvec, i+1, pTmpSpace); |
| 55154 | 55245 | } |
| 55155 | 55246 | } |
| 55156 | 55247 | |
| 55157 | 55248 | /* Test to make sure the linear array exactly matches the |
| 55158 | 55249 | ** Bitvec object. Start with the assumption that they do |
| 55159 | 55250 | ** match (rc==0). Change rc to non-zero if a discrepancy |
| 55160 | 55251 | ** is found. |
| 55161 | 55252 | */ |
| 55162 | - rc = sqlite3BitvecTest(0,0) + sqlite3BitvecTest(pBitvec, sz+1) | |
| 55163 | - + sqlite3BitvecTest(pBitvec, 0) | |
| 55164 | - + (sqlite3BitvecSize(pBitvec) - sz); | |
| 55165 | - for(i=1; i<=sz; i++){ | |
| 55166 | - if( (TESTBIT(pV,i))!=sqlite3BitvecTest(pBitvec,i) ){ | |
| 55167 | - rc = i; | |
| 55168 | - break; | |
| 55169 | - } | |
| 55253 | + if( pV ){ | |
| 55254 | + rc = sqlite3BitvecTest(0,0) + sqlite3BitvecTest(pBitvec, sz+1) | |
| 55255 | + + sqlite3BitvecTest(pBitvec, 0) | |
| 55256 | + + (sqlite3BitvecSize(pBitvec) - sz); | |
| 55257 | + for(i=1; i<=sz; i++){ | |
| 55258 | + if( (TESTBIT(pV,i))!=sqlite3BitvecTest(pBitvec,i) ){ | |
| 55259 | + rc = i; | |
| 55260 | + break; | |
| 55261 | + } | |
| 55262 | + } | |
| 55263 | + }else{ | |
| 55264 | + rc = 0; | |
| 55170 | 55265 | } |
| 55171 | 55266 | |
| 55172 | 55267 | /* Free allocated structure */ |
| 55173 | 55268 | bitvec_end: |
| 55174 | 55269 | sqlite3_free(pTmpSpace); |
| @@ -69670,10 +69765,11 @@ | ||
| 69670 | 69765 | rc = xUndo(pUndoCtx, walFramePgno(pWal, iFrame)); |
| 69671 | 69766 | } |
| 69672 | 69767 | if( iMax!=pWal->hdr.mxFrame ) walCleanupHash(pWal); |
| 69673 | 69768 | } |
| 69674 | 69769 | SEH_EXCEPT( rc = SQLITE_IOERR_IN_PAGE; ) |
| 69770 | + pWal->iReCksum = 0; | |
| 69675 | 69771 | } |
| 69676 | 69772 | return rc; |
| 69677 | 69773 | } |
| 69678 | 69774 | |
| 69679 | 69775 | /* |
| @@ -69717,10 +69813,13 @@ | ||
| 69717 | 69813 | pWal->hdr.aFrameCksum[1] = aWalData[2]; |
| 69718 | 69814 | SEH_TRY { |
| 69719 | 69815 | walCleanupHash(pWal); |
| 69720 | 69816 | } |
| 69721 | 69817 | SEH_EXCEPT( rc = SQLITE_IOERR_IN_PAGE; ) |
| 69818 | + if( pWal->iReCksum>pWal->hdr.mxFrame ){ | |
| 69819 | + pWal->iReCksum = 0; | |
| 69820 | + } | |
| 69722 | 69821 | } |
| 69723 | 69822 | |
| 69724 | 69823 | return rc; |
| 69725 | 69824 | } |
| 69726 | 69825 | |
| @@ -77442,12 +77541,12 @@ | ||
| 77442 | 77541 | assert( (pCur->curFlags & BTCF_ValidOvfl)==0 ); |
| 77443 | 77542 | return rc; |
| 77444 | 77543 | } |
| 77445 | 77544 | |
| 77446 | 77545 | /* |
| 77447 | -** Compare the "idx"-th cell on the page the cursor pCur is currently | |
| 77448 | -** pointing to to pIdxKey using xRecordCompare. Return negative or | |
| 77546 | +** Compare the "idx"-th cell on the page pPage against the key | |
| 77547 | +** pointing to by pIdxKey using xRecordCompare. Return negative or | |
| 77449 | 77548 | ** zero if the cell is less than or equal pIdxKey. Return positive |
| 77450 | 77549 | ** if unknown. |
| 77451 | 77550 | ** |
| 77452 | 77551 | ** Return value negative: Cell at pCur[idx] less than pIdxKey |
| 77453 | 77552 | ** |
| @@ -77458,16 +77557,15 @@ | ||
| 77458 | 77557 | ** |
| 77459 | 77558 | ** This routine is part of an optimization. It is always safe to return |
| 77460 | 77559 | ** a positive value as that will cause the optimization to be skipped. |
| 77461 | 77560 | */ |
| 77462 | 77561 | static int indexCellCompare( |
| 77463 | - BtCursor *pCur, | |
| 77562 | + MemPage *pPage, | |
| 77464 | 77563 | int idx, |
| 77465 | 77564 | UnpackedRecord *pIdxKey, |
| 77466 | 77565 | RecordCompare xRecordCompare |
| 77467 | 77566 | ){ |
| 77468 | - MemPage *pPage = pCur->pPage; | |
| 77469 | 77567 | int c; |
| 77470 | 77568 | int nCell; /* Size of the pCell cell in bytes */ |
| 77471 | 77569 | u8 *pCell = findCellPastPtr(pPage, idx); |
| 77472 | 77570 | |
| 77473 | 77571 | nCell = pCell[0]; |
| @@ -77572,18 +77670,18 @@ | ||
| 77572 | 77670 | && pCur->pPage->leaf |
| 77573 | 77671 | && cursorOnLastPage(pCur) |
| 77574 | 77672 | ){ |
| 77575 | 77673 | int c; |
| 77576 | 77674 | if( pCur->ix==pCur->pPage->nCell-1 |
| 77577 | - && (c = indexCellCompare(pCur, pCur->ix, pIdxKey, xRecordCompare))<=0 | |
| 77675 | + && (c = indexCellCompare(pCur->pPage,pCur->ix,pIdxKey,xRecordCompare))<=0 | |
| 77578 | 77676 | && pIdxKey->errCode==SQLITE_OK |
| 77579 | 77677 | ){ |
| 77580 | 77678 | *pRes = c; |
| 77581 | 77679 | return SQLITE_OK; /* Cursor already pointing at the correct spot */ |
| 77582 | 77680 | } |
| 77583 | 77681 | if( pCur->iPage>0 |
| 77584 | - && indexCellCompare(pCur, 0, pIdxKey, xRecordCompare)<=0 | |
| 77682 | + && indexCellCompare(pCur->pPage, 0, pIdxKey, xRecordCompare)<=0 | |
| 77585 | 77683 | && pIdxKey->errCode==SQLITE_OK |
| 77586 | 77684 | ){ |
| 77587 | 77685 | pCur->curFlags &= ~(BTCF_ValidOvfl|BTCF_AtLast); |
| 77588 | 77686 | if( !pCur->pPage->isInit ){ |
| 77589 | 77687 | return SQLITE_CORRUPT_BKPT; |
| @@ -77796,11 +77894,11 @@ | ||
| 77796 | 77894 | if( pCur->eState!=CURSOR_VALID ) return 0; |
| 77797 | 77895 | if( NEVER(pCur->pPage->leaf==0) ) return -1; |
| 77798 | 77896 | |
| 77799 | 77897 | n = pCur->pPage->nCell; |
| 77800 | 77898 | for(i=0; i<pCur->iPage; i++){ |
| 77801 | - n *= pCur->apPage[i]->nCell; | |
| 77899 | + n *= pCur->apPage[i]->nCell+1; | |
| 77802 | 77900 | } |
| 77803 | 77901 | return n; |
| 77804 | 77902 | } |
| 77805 | 77903 | |
| 77806 | 77904 | /* |
| @@ -97581,10 +97679,19 @@ | ||
| 97581 | 97679 | ** Synopsis: typecheck(r[P1@P2]) |
| 97582 | 97680 | ** |
| 97583 | 97681 | ** Apply affinities to the range of P2 registers beginning with P1. |
| 97584 | 97682 | ** Take the affinities from the Table object in P4. If any value |
| 97585 | 97683 | ** cannot be coerced into the correct type, then raise an error. |
| 97684 | +** | |
| 97685 | +** If P3==0, then omit checking of VIRTUAL columns. | |
| 97686 | +** | |
| 97687 | +** If P3==1, then omit checking of all generated column, both VIRTUAL | |
| 97688 | +** and STORED. | |
| 97689 | +** | |
| 97690 | +** If P3>=2, then only check column number P3-2 in the table (which will | |
| 97691 | +** be a VIRTUAL column) against the value in reg[P1]. In this case, | |
| 97692 | +** P2 will be 1. | |
| 97586 | 97693 | ** |
| 97587 | 97694 | ** This opcode is similar to OP_Affinity except that this opcode |
| 97588 | 97695 | ** forces the register type to the Table column type. This is used |
| 97589 | 97696 | ** to implement "strict affinity". |
| 97590 | 97697 | ** |
| @@ -97595,30 +97702,42 @@ | ||
| 97595 | 97702 | ** |
| 97596 | 97703 | ** Preconditions: |
| 97597 | 97704 | ** |
| 97598 | 97705 | ** <ul> |
| 97599 | 97706 | ** <li> P2 should be the number of non-virtual columns in the |
| 97600 | -** table of P4. | |
| 97601 | -** <li> Table P4 should be a STRICT table. | |
| 97707 | +** table of P4 unless P3>1, in which case P2 will be 1. | |
| 97708 | +** <li> Table P4 is a STRICT table. | |
| 97602 | 97709 | ** </ul> |
| 97603 | 97710 | ** |
| 97604 | 97711 | ** If any precondition is false, an assertion fault occurs. |
| 97605 | 97712 | */ |
| 97606 | 97713 | case OP_TypeCheck: { |
| 97607 | 97714 | Table *pTab; |
| 97608 | 97715 | Column *aCol; |
| 97609 | 97716 | int i; |
| 97717 | + int nCol; | |
| 97610 | 97718 | |
| 97611 | 97719 | assert( pOp->p4type==P4_TABLE ); |
| 97612 | 97720 | pTab = pOp->p4.pTab; |
| 97613 | 97721 | assert( pTab->tabFlags & TF_Strict ); |
| 97614 | - assert( pTab->nNVCol==pOp->p2 ); | |
| 97722 | + assert( pOp->p3>=0 && pOp->p3<pTab->nCol+2 ); | |
| 97615 | 97723 | aCol = pTab->aCol; |
| 97616 | 97724 | pIn1 = &aMem[pOp->p1]; |
| 97617 | - for(i=0; i<pTab->nCol; i++){ | |
| 97618 | - if( aCol[i].colFlags & COLFLAG_GENERATED ){ | |
| 97619 | - if( aCol[i].colFlags & COLFLAG_VIRTUAL ) continue; | |
| 97725 | + if( pOp->p3<2 ){ | |
| 97726 | + assert( pTab->nNVCol==pOp->p2 ); | |
| 97727 | + i = 0; | |
| 97728 | + nCol = pTab->nCol; | |
| 97729 | + }else{ | |
| 97730 | + i = pOp->p3-2; | |
| 97731 | + nCol = i+1; | |
| 97732 | + assert( i<pTab->nCol ); | |
| 97733 | + assert( aCol[i].colFlags & COLFLAG_VIRTUAL ); | |
| 97734 | + assert( pOp->p2==1 ); | |
| 97735 | + } | |
| 97736 | + for(; i<nCol; i++){ | |
| 97737 | + if( (aCol[i].colFlags & COLFLAG_GENERATED)!=0 && pOp->p3<2 ){ | |
| 97738 | + if( (aCol[i].colFlags & COLFLAG_VIRTUAL)!=0 ) continue; | |
| 97620 | 97739 | if( pOp->p3 ){ pIn1++; continue; } |
| 97621 | 97740 | } |
| 97622 | 97741 | assert( pIn1 < &aMem[pOp->p1+pOp->p2] ); |
| 97623 | 97742 | applyAffinity(pIn1, aCol[i].affinity, encoding); |
| 97624 | 97743 | if( (pIn1->flags & MEM_Null)==0 ){ |
| @@ -114626,11 +114745,16 @@ | ||
| 114626 | 114745 | iAddr = sqlite3VdbeAddOp3(v, OP_IfNullRow, pParse->iSelfTab-1, 0, regOut); |
| 114627 | 114746 | }else{ |
| 114628 | 114747 | iAddr = 0; |
| 114629 | 114748 | } |
| 114630 | 114749 | sqlite3ExprCodeCopy(pParse, sqlite3ColumnExpr(pTab,pCol), regOut); |
| 114631 | - if( pCol->affinity>=SQLITE_AFF_TEXT ){ | |
| 114750 | + if( (pCol->colFlags & COLFLAG_VIRTUAL)!=0 | |
| 114751 | + && (pTab->tabFlags & TF_Strict)!=0 | |
| 114752 | + ){ | |
| 114753 | + int p3 = 2+(int)(pCol - pTab->aCol); | |
| 114754 | + sqlite3VdbeAddOp4(v, OP_TypeCheck, regOut, 1, p3, (char*)pTab, P4_TABLE); | |
| 114755 | + }else if( pCol->affinity>=SQLITE_AFF_TEXT ){ | |
| 114632 | 114756 | sqlite3VdbeAddOp4(v, OP_Affinity, regOut, 1, 0, &pCol->affinity, 1); |
| 114633 | 114757 | } |
| 114634 | 114758 | if( iAddr ) sqlite3VdbeJumpHere(v, iAddr); |
| 114635 | 114759 | if( pParse->nErr>nErr ) pParse->db->errByteOffset = -1; |
| 114636 | 114760 | } |
| @@ -132020,11 +132144,11 @@ | ||
| 132020 | 132144 | int argc, |
| 132021 | 132145 | sqlite3_value **argv, |
| 132022 | 132146 | int nSep, |
| 132023 | 132147 | const char *zSep |
| 132024 | 132148 | ){ |
| 132025 | - i64 j, k, n = 0; | |
| 132149 | + i64 j, n = 0; | |
| 132026 | 132150 | int i; |
| 132027 | 132151 | char *z; |
| 132028 | 132152 | for(i=0; i<argc; i++){ |
| 132029 | 132153 | n += sqlite3_value_bytes(argv[i]); |
| 132030 | 132154 | } |
| @@ -132034,12 +132158,12 @@ | ||
| 132034 | 132158 | sqlite3_result_error_nomem(context); |
| 132035 | 132159 | return; |
| 132036 | 132160 | } |
| 132037 | 132161 | j = 0; |
| 132038 | 132162 | for(i=0; i<argc; i++){ |
| 132039 | - k = sqlite3_value_bytes(argv[i]); | |
| 132040 | - if( k>0 ){ | |
| 132163 | + if( sqlite3_value_type(argv[i])!=SQLITE_NULL ){ | |
| 132164 | + int k = sqlite3_value_bytes(argv[i]); | |
| 132041 | 132165 | const char *v = (const char*)sqlite3_value_text(argv[i]); |
| 132042 | 132166 | if( v!=0 ){ |
| 132043 | 132167 | if( j>0 && nSep>0 ){ |
| 132044 | 132168 | memcpy(&z[j], zSep, nSep); |
| 132045 | 132169 | j += nSep; |
| @@ -134973,16 +135097,19 @@ | ||
| 134973 | 135097 | if( iReg==0 ){ |
| 134974 | 135098 | /* Move the previous opcode (which should be OP_MakeRecord) forward |
| 134975 | 135099 | ** by one slot and insert a new OP_TypeCheck where the current |
| 134976 | 135100 | ** OP_MakeRecord is found */ |
| 134977 | 135101 | VdbeOp *pPrev; |
| 135102 | + int p3; | |
| 134978 | 135103 | sqlite3VdbeAppendP4(v, pTab, P4_TABLE); |
| 134979 | 135104 | pPrev = sqlite3VdbeGetLastOp(v); |
| 134980 | 135105 | assert( pPrev!=0 ); |
| 134981 | 135106 | assert( pPrev->opcode==OP_MakeRecord || sqlite3VdbeDb(v)->mallocFailed ); |
| 134982 | 135107 | pPrev->opcode = OP_TypeCheck; |
| 134983 | - sqlite3VdbeAddOp3(v, OP_MakeRecord, pPrev->p1, pPrev->p2, pPrev->p3); | |
| 135108 | + p3 = pPrev->p3; | |
| 135109 | + pPrev->p3 = 0; | |
| 135110 | + sqlite3VdbeAddOp3(v, OP_MakeRecord, pPrev->p1, pPrev->p2, p3); | |
| 134984 | 135111 | }else{ |
| 134985 | 135112 | /* Insert an isolated OP_Typecheck */ |
| 134986 | 135113 | sqlite3VdbeAddOp2(v, OP_TypeCheck, iReg, pTab->nNVCol); |
| 134987 | 135114 | sqlite3VdbeAppendP4(v, pTab, P4_TABLE); |
| 134988 | 135115 | } |
| @@ -159213,10 +159340,13 @@ | ||
| 159213 | 159340 | u16 eOperator; /* A WO_xx value describing <op> */ |
| 159214 | 159341 | u8 nChild; /* Number of children that must disable us */ |
| 159215 | 159342 | u8 eMatchOp; /* Op for vtab MATCH/LIKE/GLOB/REGEXP terms */ |
| 159216 | 159343 | int iParent; /* Disable pWC->a[iParent] when this term disabled */ |
| 159217 | 159344 | int leftCursor; /* Cursor number of X in "X <op> <expr>" */ |
| 159345 | +#ifdef SQLITE_DEBUG | |
| 159346 | + int iTerm; /* Which WhereTerm is this, for debug purposes */ | |
| 159347 | +#endif | |
| 159218 | 159348 | union { |
| 159219 | 159349 | struct { |
| 159220 | 159350 | int leftColumn; /* Column number of X in "X <op> <expr>" */ |
| 159221 | 159351 | int iField; /* Field in (?,?,?) IN (SELECT...) vector */ |
| 159222 | 159352 | } x; /* Opcode other than OP_OR or OP_AND */ |
| @@ -161410,40 +161540,40 @@ | ||
| 161410 | 161540 | VdbeCoverageIf(v, testOp==OP_Ge); |
| 161411 | 161541 | VdbeCoverageIf(v, testOp==OP_Gt); |
| 161412 | 161542 | sqlite3VdbeChangeP5(v, SQLITE_AFF_NUMERIC | SQLITE_JUMPIFNULL); |
| 161413 | 161543 | } |
| 161414 | 161544 | }else if( pLoop->wsFlags & WHERE_INDEXED ){ |
| 161415 | - /* Case 4: A scan using an index. | |
| 161416 | - ** | |
| 161417 | - ** The WHERE clause may contain zero or more equality | |
| 161418 | - ** terms ("==" or "IN" operators) that refer to the N | |
| 161419 | - ** left-most columns of the index. It may also contain | |
| 161420 | - ** inequality constraints (>, <, >= or <=) on the indexed | |
| 161421 | - ** column that immediately follows the N equalities. Only | |
| 161422 | - ** the right-most column can be an inequality - the rest must | |
| 161423 | - ** use the "==" and "IN" operators. For example, if the | |
| 161424 | - ** index is on (x,y,z), then the following clauses are all | |
| 161425 | - ** optimized: | |
| 161426 | - ** | |
| 161427 | - ** x=5 | |
| 161428 | - ** x=5 AND y=10 | |
| 161429 | - ** x=5 AND y<10 | |
| 161430 | - ** x=5 AND y>5 AND y<10 | |
| 161431 | - ** x=5 AND y=5 AND z<=10 | |
| 161432 | - ** | |
| 161433 | - ** The z<10 term of the following cannot be used, only | |
| 161434 | - ** the x=5 term: | |
| 161435 | - ** | |
| 161436 | - ** x=5 AND z<10 | |
| 161437 | - ** | |
| 161438 | - ** N may be zero if there are inequality constraints. | |
| 161439 | - ** If there are no inequality constraints, then N is at | |
| 161440 | - ** least one. | |
| 161441 | - ** | |
| 161442 | - ** This case is also used when there are no WHERE clause | |
| 161443 | - ** constraints but an index is selected anyway, in order | |
| 161444 | - ** to force the output order to conform to an ORDER BY. | |
| 161545 | + /* Case 4: Search using an index. | |
| 161546 | + ** | |
| 161547 | + ** The WHERE clause may contain zero or more equality | |
| 161548 | + ** terms ("==" or "IN" or "IS" operators) that refer to the N | |
| 161549 | + ** left-most columns of the index. It may also contain | |
| 161550 | + ** inequality constraints (>, <, >= or <=) on the indexed | |
| 161551 | + ** column that immediately follows the N equalities. Only | |
| 161552 | + ** the right-most column can be an inequality - the rest must | |
| 161553 | + ** use the "==", "IN", or "IS" operators. For example, if the | |
| 161554 | + ** index is on (x,y,z), then the following clauses are all | |
| 161555 | + ** optimized: | |
| 161556 | + ** | |
| 161557 | + ** x=5 | |
| 161558 | + ** x=5 AND y=10 | |
| 161559 | + ** x=5 AND y<10 | |
| 161560 | + ** x=5 AND y>5 AND y<10 | |
| 161561 | + ** x=5 AND y=5 AND z<=10 | |
| 161562 | + ** | |
| 161563 | + ** The z<10 term of the following cannot be used, only | |
| 161564 | + ** the x=5 term: | |
| 161565 | + ** | |
| 161566 | + ** x=5 AND z<10 | |
| 161567 | + ** | |
| 161568 | + ** N may be zero if there are inequality constraints. | |
| 161569 | + ** If there are no inequality constraints, then N is at | |
| 161570 | + ** least one. | |
| 161571 | + ** | |
| 161572 | + ** This case is also used when there are no WHERE clause | |
| 161573 | + ** constraints but an index is selected anyway, in order | |
| 161574 | + ** to force the output order to conform to an ORDER BY. | |
| 161445 | 161575 | */ |
| 161446 | 161576 | static const u8 aStartOp[] = { |
| 161447 | 161577 | 0, |
| 161448 | 161578 | 0, |
| 161449 | 161579 | OP_Rewind, /* 2: (!start_constraints && startEq && !bRev) */ |
| @@ -163459,34 +163589,46 @@ | ||
| 163459 | 163589 | ** column references. This routine checks to see if pExpr is an equivalence |
| 163460 | 163590 | ** relation: |
| 163461 | 163591 | ** 1. The SQLITE_Transitive optimization must be enabled |
| 163462 | 163592 | ** 2. Must be either an == or an IS operator |
| 163463 | 163593 | ** 3. Not originating in the ON clause of an OUTER JOIN |
| 163464 | -** 4. The affinities of A and B must be compatible | |
| 163465 | -** 5a. Both operands use the same collating sequence OR | |
| 163466 | -** 5b. The overall collating sequence is BINARY | |
| 163594 | +** 4. The operator is not IS or else the query does not contain RIGHT JOIN | |
| 163595 | +** 5. The affinities of A and B must be compatible | |
| 163596 | +** 6a. Both operands use the same collating sequence OR | |
| 163597 | +** 6b. The overall collating sequence is BINARY | |
| 163467 | 163598 | ** If this routine returns TRUE, that means that the RHS can be substituted |
| 163468 | 163599 | ** for the LHS anyplace else in the WHERE clause where the LHS column occurs. |
| 163469 | 163600 | ** This is an optimization. No harm comes from returning 0. But if 1 is |
| 163470 | 163601 | ** returned when it should not be, then incorrect answers might result. |
| 163471 | 163602 | */ |
| 163472 | -static int termIsEquivalence(Parse *pParse, Expr *pExpr){ | |
| 163603 | +static int termIsEquivalence(Parse *pParse, Expr *pExpr, SrcList *pSrc){ | |
| 163473 | 163604 | char aff1, aff2; |
| 163474 | 163605 | CollSeq *pColl; |
| 163475 | - if( !OptimizationEnabled(pParse->db, SQLITE_Transitive) ) return 0; | |
| 163476 | - if( pExpr->op!=TK_EQ && pExpr->op!=TK_IS ) return 0; | |
| 163477 | - if( ExprHasProperty(pExpr, EP_OuterON) ) return 0; | |
| 163606 | + if( !OptimizationEnabled(pParse->db, SQLITE_Transitive) ) return 0; /* (1) */ | |
| 163607 | + if( pExpr->op!=TK_EQ && pExpr->op!=TK_IS ) return 0; /* (2) */ | |
| 163608 | + if( ExprHasProperty(pExpr, EP_OuterON) ) return 0; /* (3) */ | |
| 163609 | + assert( pSrc!=0 ); | |
| 163610 | + if( pExpr->op==TK_IS | |
| 163611 | + && pSrc->nSrc | |
| 163612 | + && (pSrc->a[0].fg.jointype & JT_LTORJ)!=0 | |
| 163613 | + ){ | |
| 163614 | + return 0; /* (4) */ | |
| 163615 | + } | |
| 163478 | 163616 | aff1 = sqlite3ExprAffinity(pExpr->pLeft); |
| 163479 | 163617 | aff2 = sqlite3ExprAffinity(pExpr->pRight); |
| 163480 | 163618 | if( aff1!=aff2 |
| 163481 | 163619 | && (!sqlite3IsNumericAffinity(aff1) || !sqlite3IsNumericAffinity(aff2)) |
| 163482 | 163620 | ){ |
| 163483 | - return 0; | |
| 163621 | + return 0; /* (5) */ | |
| 163484 | 163622 | } |
| 163485 | 163623 | pColl = sqlite3ExprCompareCollSeq(pParse, pExpr); |
| 163486 | - if( sqlite3IsBinary(pColl) ) return 1; | |
| 163487 | - return sqlite3ExprCollSeqMatch(pParse, pExpr->pLeft, pExpr->pRight); | |
| 163624 | + if( !sqlite3IsBinary(pColl) | |
| 163625 | + && !sqlite3ExprCollSeqMatch(pParse, pExpr->pLeft, pExpr->pRight) | |
| 163626 | + ){ | |
| 163627 | + return 0; /* (6) */ | |
| 163628 | + } | |
| 163629 | + return 1; | |
| 163488 | 163630 | } |
| 163489 | 163631 | |
| 163490 | 163632 | /* |
| 163491 | 163633 | ** Recursively walk the expressions of a SELECT statement and generate |
| 163492 | 163634 | ** a bitmask indicating which tables are used in that expression |
| @@ -163640,10 +163782,13 @@ | ||
| 163640 | 163782 | if( db->mallocFailed ){ |
| 163641 | 163783 | return; |
| 163642 | 163784 | } |
| 163643 | 163785 | assert( pWC->nTerm > idxTerm ); |
| 163644 | 163786 | pTerm = &pWC->a[idxTerm]; |
| 163787 | +#ifdef SQLITE_DEBUG | |
| 163788 | + pTerm->iTerm = idxTerm; | |
| 163789 | +#endif | |
| 163645 | 163790 | pMaskSet = &pWInfo->sMaskSet; |
| 163646 | 163791 | pExpr = pTerm->pExpr; |
| 163647 | 163792 | assert( pExpr!=0 ); /* Because malloc() has not failed */ |
| 163648 | 163793 | assert( pExpr->op!=TK_AS && pExpr->op!=TK_COLLATE ); |
| 163649 | 163794 | pMaskSet->bVarSelect = 0; |
| @@ -163747,12 +163892,12 @@ | ||
| 163747 | 163892 | pNew = &pWC->a[idxNew]; |
| 163748 | 163893 | markTermAsChild(pWC, idxNew, idxTerm); |
| 163749 | 163894 | if( op==TK_IS ) pNew->wtFlags |= TERM_IS; |
| 163750 | 163895 | pTerm = &pWC->a[idxTerm]; |
| 163751 | 163896 | pTerm->wtFlags |= TERM_COPIED; |
| 163752 | - | |
| 163753 | - if( termIsEquivalence(pParse, pDup) ){ | |
| 163897 | + assert( pWInfo->pTabList!=0 ); | |
| 163898 | + if( termIsEquivalence(pParse, pDup, pWInfo->pTabList) ){ | |
| 163754 | 163899 | pTerm->eOperator |= WO_EQUIV; |
| 163755 | 163900 | eExtraOp = WO_EQUIV; |
| 163756 | 163901 | } |
| 163757 | 163902 | }else{ |
| 163758 | 163903 | pDup = pExpr; |
| @@ -164867,15 +165012,15 @@ | ||
| 164867 | 165012 | continue; |
| 164868 | 165013 | } |
| 164869 | 165014 | pScan->pWC = pWC; |
| 164870 | 165015 | pScan->k = k+1; |
| 164871 | 165016 | #ifdef WHERETRACE_ENABLED |
| 164872 | - if( sqlite3WhereTrace & 0x20000 ){ | |
| 165017 | + if( (sqlite3WhereTrace & 0x20000)!=0 && pScan->nEquiv>1 ){ | |
| 164873 | 165018 | int ii; |
| 164874 | - sqlite3DebugPrintf("SCAN-TERM %p: nEquiv=%d", | |
| 164875 | - pTerm, pScan->nEquiv); | |
| 164876 | - for(ii=0; ii<pScan->nEquiv; ii++){ | |
| 165019 | + sqlite3DebugPrintf("EQUIVALENT TO {%d:%d} (due to TERM-%d):", | |
| 165020 | + pScan->aiCur[0], pScan->aiColumn[0], pTerm->iTerm); | |
| 165021 | + for(ii=1; ii<pScan->nEquiv; ii++){ | |
| 164877 | 165022 | sqlite3DebugPrintf(" {%d:%d}", |
| 164878 | 165023 | pScan->aiCur[ii], pScan->aiColumn[ii]); |
| 164879 | 165024 | } |
| 164880 | 165025 | sqlite3DebugPrintf("\n"); |
| 164881 | 165026 | } |
| @@ -166826,10 +166971,11 @@ | ||
| 166826 | 166971 | sqlite3_snprintf(sizeof(zLeft),zLeft,"indexable=0x%llx", |
| 166827 | 166972 | pTerm->u.pOrInfo->indexable); |
| 166828 | 166973 | }else{ |
| 166829 | 166974 | sqlite3_snprintf(sizeof(zLeft),zLeft,"left=%d", pTerm->leftCursor); |
| 166830 | 166975 | } |
| 166976 | + iTerm = pTerm->iTerm = MAX(iTerm,pTerm->iTerm); | |
| 166831 | 166977 | sqlite3DebugPrintf( |
| 166832 | 166978 | "TERM-%-3d %p %s %-12s op=%03x wtFlags=%04x", |
| 166833 | 166979 | iTerm, pTerm, zType, zLeft, pTerm->eOperator, pTerm->wtFlags); |
| 166834 | 166980 | /* The 0x10000 .wheretrace flag causes extra information to be |
| 166835 | 166981 | ** shown about each Term */ |
| @@ -184450,10 +184596,11 @@ | ||
| 184450 | 184596 | #ifdef SQLITE_ENABLE_API_ARMOR |
| 184451 | 184597 | if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; |
| 184452 | 184598 | #endif |
| 184453 | 184599 | if( ms<-1 ) return SQLITE_RANGE; |
| 184454 | 184600 | #ifdef SQLITE_ENABLE_SETLK_TIMEOUT |
| 184601 | + sqlite3_mutex_enter(db->mutex); | |
| 184455 | 184602 | db->setlkTimeout = ms; |
| 184456 | 184603 | db->setlkFlags = flags; |
| 184457 | 184604 | sqlite3BtreeEnterAll(db); |
| 184458 | 184605 | for(iDb=0; iDb<db->nDb; iDb++){ |
| 184459 | 184606 | Btree *pBt = db->aDb[iDb].pBt; |
| @@ -184461,10 +184608,11 @@ | ||
| 184461 | 184608 | sqlite3_file *fd = sqlite3PagerFile(sqlite3BtreePager(pBt)); |
| 184462 | 184609 | sqlite3OsFileControlHint(fd, SQLITE_FCNTL_BLOCK_ON_CONNECT, (void*)&bBOC); |
| 184463 | 184610 | } |
| 184464 | 184611 | } |
| 184465 | 184612 | sqlite3BtreeLeaveAll(db); |
| 184613 | + sqlite3_mutex_leave(db->mutex); | |
| 184466 | 184614 | #endif |
| 184467 | 184615 | #if !defined(SQLITE_ENABLE_API_ARMOR) && !defined(SQLITE_ENABLE_SETLK_TIMEOUT) |
| 184468 | 184616 | UNUSED_PARAMETER(db); |
| 184469 | 184617 | UNUSED_PARAMETER(flags); |
| 184470 | 184618 | #endif |
| @@ -257257,11 +257405,11 @@ | ||
| 257257 | 257405 | int nArg, /* Number of args */ |
| 257258 | 257406 | sqlite3_value **apUnused /* Function arguments */ |
| 257259 | 257407 | ){ |
| 257260 | 257408 | assert( nArg==0 ); |
| 257261 | 257409 | UNUSED_PARAM2(nArg, apUnused); |
| 257262 | - sqlite3_result_text(pCtx, "fts5: 2025-06-03 10:49:51 ea1754f7d8a770477a1b19b606b27724fdc0b733e51fef32c1ef834f972c3cc5", -1, SQLITE_TRANSIENT); | |
| 257410 | + sqlite3_result_text(pCtx, "fts5: 2025-06-19 20:19:12 a88bb75288a06492a04ab1278e8a2101a74f4ba712d328b4c73e86ac01cb946d", -1, SQLITE_TRANSIENT); | |
| 257263 | 257411 | } |
| 257264 | 257412 | |
| 257265 | 257413 | /* |
| 257266 | 257414 | ** Implementation of fts5_locale(LOCALE, TEXT) function. |
| 257267 | 257415 | ** |
| @@ -258072,10 +258220,11 @@ | ||
| 258072 | 258220 | ctx.pStorage = p; |
| 258073 | 258221 | ctx.iCol = -1; |
| 258074 | 258222 | for(iCol=1; rc==SQLITE_OK && iCol<=pConfig->nCol; iCol++){ |
| 258075 | 258223 | if( pConfig->abUnindexed[iCol-1]==0 ){ |
| 258076 | 258224 | sqlite3_value *pVal = 0; |
| 258225 | + sqlite3_value *pFree = 0; | |
| 258077 | 258226 | const char *pText = 0; |
| 258078 | 258227 | int nText = 0; |
| 258079 | 258228 | const char *pLoc = 0; |
| 258080 | 258229 | int nLoc = 0; |
| 258081 | 258230 | |
| @@ -258088,15 +258237,26 @@ | ||
| 258088 | 258237 | } |
| 258089 | 258238 | |
| 258090 | 258239 | if( pConfig->bLocale && sqlite3Fts5IsLocaleValue(pConfig, pVal) ){ |
| 258091 | 258240 | rc = sqlite3Fts5DecodeLocaleValue(pVal, &pText, &nText, &pLoc, &nLoc); |
| 258092 | 258241 | }else{ |
| 258093 | - pText = (const char*)sqlite3_value_text(pVal); | |
| 258094 | - nText = sqlite3_value_bytes(pVal); | |
| 258095 | - if( pConfig->bLocale && pSeek ){ | |
| 258096 | - pLoc = (const char*)sqlite3_column_text(pSeek, iCol + pConfig->nCol); | |
| 258097 | - nLoc = sqlite3_column_bytes(pSeek, iCol + pConfig->nCol); | |
| 258242 | + if( sqlite3_value_type(pVal)!=SQLITE_TEXT ){ | |
| 258243 | + /* Make a copy of the value to work with. This is because the call | |
| 258244 | + ** to sqlite3_value_text() below forces the type of the value to | |
| 258245 | + ** SQLITE_TEXT, and we may need to use it again later. */ | |
| 258246 | + pFree = pVal = sqlite3_value_dup(pVal); | |
| 258247 | + if( pVal==0 ){ | |
| 258248 | + rc = SQLITE_NOMEM; | |
| 258249 | + } | |
| 258250 | + } | |
| 258251 | + if( rc==SQLITE_OK ){ | |
| 258252 | + pText = (const char*)sqlite3_value_text(pVal); | |
| 258253 | + nText = sqlite3_value_bytes(pVal); | |
| 258254 | + if( pConfig->bLocale && pSeek ){ | |
| 258255 | + pLoc = (const char*)sqlite3_column_text(pSeek, iCol+pConfig->nCol); | |
| 258256 | + nLoc = sqlite3_column_bytes(pSeek, iCol + pConfig->nCol); | |
| 258257 | + } | |
| 258098 | 258258 | } |
| 258099 | 258259 | } |
| 258100 | 258260 | |
| 258101 | 258261 | if( rc==SQLITE_OK ){ |
| 258102 | 258262 | sqlite3Fts5SetLocale(pConfig, pLoc, nLoc); |
| @@ -258108,10 +258268,11 @@ | ||
| 258108 | 258268 | if( rc==SQLITE_OK && p->aTotalSize[iCol-1]<0 ){ |
| 258109 | 258269 | rc = FTS5_CORRUPT; |
| 258110 | 258270 | } |
| 258111 | 258271 | sqlite3Fts5ClearLocale(pConfig); |
| 258112 | 258272 | } |
| 258273 | + sqlite3_value_free(pFree); | |
| 258113 | 258274 | } |
| 258114 | 258275 | } |
| 258115 | 258276 | if( rc==SQLITE_OK && p->nTotalRow<1 ){ |
| 258116 | 258277 | rc = FTS5_CORRUPT; |
| 258117 | 258278 | }else{ |
| 258118 | 258279 |
| --- extsrc/sqlite3.c | |
| +++ extsrc/sqlite3.c | |
| @@ -16,11 +16,11 @@ | |
| 16 | ** if you want a wrapper to interface SQLite with your choice of programming |
| 17 | ** language. The code for the "sqlite3" command-line shell is also in a |
| 18 | ** separate file. This file contains only code for the core SQLite library. |
| 19 | ** |
| 20 | ** The content in this amalgamation comes from Fossil check-in |
| 21 | ** ea1754f7d8a770477a1b19b606b27724fdc0 with changes in files: |
| 22 | ** |
| 23 | ** |
| 24 | */ |
| 25 | #ifndef SQLITE_AMALGAMATION |
| 26 | #define SQLITE_CORE 1 |
| @@ -465,11 +465,11 @@ | |
| 465 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 466 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 467 | */ |
| 468 | #define SQLITE_VERSION "3.51.0" |
| 469 | #define SQLITE_VERSION_NUMBER 3051000 |
| 470 | #define SQLITE_SOURCE_ID "2025-06-03 10:49:51 ea1754f7d8a770477a1b19b606b27724fdc0b733e51fef32c1ef834f972c3cc5" |
| 471 | |
| 472 | /* |
| 473 | ** CAPI3REF: Run-Time Library Version Numbers |
| 474 | ** KEYWORDS: sqlite3_version sqlite3_sourceid |
| 475 | ** |
| @@ -4396,11 +4396,11 @@ | |
| 4396 | ** These interfaces are provided for use by [VFS shim] implementations and |
| 4397 | ** are not useful outside of that context. |
| 4398 | ** |
| 4399 | ** The sqlite3_create_filename(D,J,W,N,P) allocates memory to hold a version of |
| 4400 | ** database filename D with corresponding journal file J and WAL file W and |
| 4401 | ** with N URI parameters key/values pairs in the array P. The result from |
| 4402 | ** sqlite3_create_filename(D,J,W,N,P) is a pointer to a database filename that |
| 4403 | ** is safe to pass to routines like: |
| 4404 | ** <ul> |
| 4405 | ** <li> [sqlite3_uri_parameter()], |
| 4406 | ** <li> [sqlite3_uri_boolean()], |
| @@ -5077,11 +5077,11 @@ | |
| 5077 | ** KEYWORDS: {host parameter} {host parameters} {host parameter name} |
| 5078 | ** KEYWORDS: {SQL parameter} {SQL parameters} {parameter binding} |
| 5079 | ** METHOD: sqlite3_stmt |
| 5080 | ** |
| 5081 | ** ^(In the SQL statement text input to [sqlite3_prepare_v2()] and its variants, |
| 5082 | ** literals may be replaced by a [parameter] that matches one of following |
| 5083 | ** templates: |
| 5084 | ** |
| 5085 | ** <ul> |
| 5086 | ** <li> ? |
| 5087 | ** <li> ?NNN |
| @@ -5122,11 +5122,11 @@ | |
| 5122 | ** either UTF8 if the sixth parameter is SQLITE_UTF8, or UTF16 |
| 5123 | ** otherwise. |
| 5124 | ** |
| 5125 | ** [[byte-order determination rules]] ^The byte-order of |
| 5126 | ** UTF16 input text is determined by the byte-order mark (BOM, U+FEFF) |
| 5127 | ** found in first character, which is removed, or in the absence of a BOM |
| 5128 | ** the byte order is the native byte order of the host |
| 5129 | ** machine for sqlite3_bind_text16() or the byte order specified in |
| 5130 | ** the 6th parameter for sqlite3_bind_text64().)^ |
| 5131 | ** ^If UTF16 input text contains invalid unicode |
| 5132 | ** characters, then SQLite might change those invalid characters |
| @@ -5142,11 +5142,11 @@ | |
| 5142 | ** the behavior is undefined. |
| 5143 | ** If a non-negative fourth parameter is provided to sqlite3_bind_text() |
| 5144 | ** or sqlite3_bind_text16() or sqlite3_bind_text64() then |
| 5145 | ** that parameter must be the byte offset |
| 5146 | ** where the NUL terminator would occur assuming the string were NUL |
| 5147 | ** terminated. If any NUL characters occurs at byte offsets less than |
| 5148 | ** the value of the fourth parameter then the resulting string value will |
| 5149 | ** contain embedded NULs. The result of expressions involving strings |
| 5150 | ** with embedded NULs is undefined. |
| 5151 | ** |
| 5152 | ** ^The fifth argument to the BLOB and string binding interfaces controls |
| @@ -5354,11 +5354,11 @@ | |
| 5354 | /* |
| 5355 | ** CAPI3REF: Source Of Data In A Query Result |
| 5356 | ** METHOD: sqlite3_stmt |
| 5357 | ** |
| 5358 | ** ^These routines provide a means to determine the database, table, and |
| 5359 | ** table column that is the origin of a particular result column in |
| 5360 | ** [SELECT] statement. |
| 5361 | ** ^The name of the database or table or column can be returned as |
| 5362 | ** either a UTF-8 or UTF-16 string. ^The _database_ routines return |
| 5363 | ** the database name, the _table_ routines return the table name, and |
| 5364 | ** the origin_ routines return the column name. |
| @@ -5923,12 +5923,12 @@ | |
| 5923 | ** within VIEWs, TRIGGERs, CHECK constraints, generated column expressions, |
| 5924 | ** index expressions, or the WHERE clause of partial indexes. |
| 5925 | ** |
| 5926 | ** For best security, the [SQLITE_DIRECTONLY] flag is recommended for |
| 5927 | ** all application-defined SQL functions that do not need to be |
| 5928 | ** used inside of triggers, view, CHECK constraints, or other elements of |
| 5929 | ** the database schema. This flags is especially recommended for SQL |
| 5930 | ** functions that have side effects or reveal internal application state. |
| 5931 | ** Without this flag, an attacker might be able to modify the schema of |
| 5932 | ** a database file to include invocations of the function with parameters |
| 5933 | ** chosen by the attacker, which the application will then execute when |
| 5934 | ** the database file is opened and read. |
| @@ -5955,11 +5955,11 @@ | |
| 5955 | ** or aggregate window function. More details regarding the implementation |
| 5956 | ** of aggregate window functions are |
| 5957 | ** [user-defined window functions|available here]. |
| 5958 | ** |
| 5959 | ** ^(If the final parameter to sqlite3_create_function_v2() or |
| 5960 | ** sqlite3_create_window_function() is not NULL, then it is destructor for |
| 5961 | ** the application data pointer. The destructor is invoked when the function |
| 5962 | ** is deleted, either by being overloaded or when the database connection |
| 5963 | ** closes.)^ ^The destructor is also invoked if the call to |
| 5964 | ** sqlite3_create_function_v2() fails. ^When the destructor callback is |
| 5965 | ** invoked, it is passed a single argument which is a copy of the application |
| @@ -7763,11 +7763,11 @@ | |
| 7763 | ** that is to be automatically loaded into all new database connections. |
| 7764 | ** |
| 7765 | ** ^(Even though the function prototype shows that xEntryPoint() takes |
| 7766 | ** no arguments and returns void, SQLite invokes xEntryPoint() with three |
| 7767 | ** arguments and expects an integer result as if the signature of the |
| 7768 | ** entry point where as follows: |
| 7769 | ** |
| 7770 | ** <blockquote><pre> |
| 7771 | ** int xEntryPoint( |
| 7772 | ** sqlite3 *db, |
| 7773 | ** const char **pzErrMsg, |
| @@ -8094,11 +8094,11 @@ | |
| 8094 | ** by the first parameter. ^The name of the module is given by the |
| 8095 | ** second parameter. ^The third parameter is a pointer to |
| 8096 | ** the implementation of the [virtual table module]. ^The fourth |
| 8097 | ** parameter is an arbitrary client data pointer that is passed through |
| 8098 | ** into the [xCreate] and [xConnect] methods of the virtual table module |
| 8099 | ** when a new virtual table is be being created or reinitialized. |
| 8100 | ** |
| 8101 | ** ^The sqlite3_create_module_v2() interface has a fifth parameter which |
| 8102 | ** is a pointer to a destructor for the pClientData. ^SQLite will |
| 8103 | ** invoke the destructor function (if it is not NULL) when SQLite |
| 8104 | ** no longer needs the pClientData pointer. ^The destructor will also |
| @@ -8259,11 +8259,11 @@ | |
| 8259 | ** |
| 8260 | ** ^(On success, [SQLITE_OK] is returned and the new [BLOB handle] is stored |
| 8261 | ** in *ppBlob. Otherwise an [error code] is returned and, unless the error |
| 8262 | ** code is SQLITE_MISUSE, *ppBlob is set to NULL.)^ ^This means that, provided |
| 8263 | ** the API is not misused, it is always safe to call [sqlite3_blob_close()] |
| 8264 | ** on *ppBlob after this function it returns. |
| 8265 | ** |
| 8266 | ** This function fails with SQLITE_ERROR if any of the following are true: |
| 8267 | ** <ul> |
| 8268 | ** <li> ^(Database zDb does not exist)^, |
| 8269 | ** <li> ^(Table zTable does not exist within database zDb)^, |
| @@ -8379,11 +8379,11 @@ | |
| 8379 | ** CAPI3REF: Return The Size Of An Open BLOB |
| 8380 | ** METHOD: sqlite3_blob |
| 8381 | ** |
| 8382 | ** ^Returns the size in bytes of the BLOB accessible via the |
| 8383 | ** successfully opened [BLOB handle] in its only argument. ^The |
| 8384 | ** incremental blob I/O routines can only read or overwriting existing |
| 8385 | ** blob content; they cannot change the size of a blob. |
| 8386 | ** |
| 8387 | ** This routine only works on a [BLOB handle] which has been created |
| 8388 | ** by a prior successful call to [sqlite3_blob_open()] and which has not |
| 8389 | ** been closed by [sqlite3_blob_close()]. Passing any other pointer in |
| @@ -9782,11 +9782,11 @@ | |
| 9782 | ** sqlite3_backup_step(), the source database may be modified mid-way |
| 9783 | ** through the backup process. ^If the source database is modified by an |
| 9784 | ** external process or via a database connection other than the one being |
| 9785 | ** used by the backup operation, then the backup will be automatically |
| 9786 | ** restarted by the next call to sqlite3_backup_step(). ^If the source |
| 9787 | ** database is modified by the using the same database connection as is used |
| 9788 | ** by the backup operation, then the backup database is automatically |
| 9789 | ** updated at the same time. |
| 9790 | ** |
| 9791 | ** [[sqlite3_backup_finish()]] <b>sqlite3_backup_finish()</b> |
| 9792 | ** |
| @@ -9799,11 +9799,11 @@ | |
| 9799 | ** active write-transaction on the destination database is rolled back. |
| 9800 | ** The [sqlite3_backup] object is invalid |
| 9801 | ** and may not be used following a call to sqlite3_backup_finish(). |
| 9802 | ** |
| 9803 | ** ^The value returned by sqlite3_backup_finish is [SQLITE_OK] if no |
| 9804 | ** sqlite3_backup_step() errors occurred, regardless or whether or not |
| 9805 | ** sqlite3_backup_step() completed. |
| 9806 | ** ^If an out-of-memory condition or IO error occurred during any prior |
| 9807 | ** sqlite3_backup_step() call on the same [sqlite3_backup] object, then |
| 9808 | ** sqlite3_backup_finish() returns the corresponding [error code]. |
| 9809 | ** |
| @@ -10869,11 +10869,11 @@ | |
| 10869 | /* |
| 10870 | ** CAPI3REF: Flush caches to disk mid-transaction |
| 10871 | ** METHOD: sqlite3 |
| 10872 | ** |
| 10873 | ** ^If a write-transaction is open on [database connection] D when the |
| 10874 | ** [sqlite3_db_cacheflush(D)] interface invoked, any dirty |
| 10875 | ** pages in the pager-cache that are not currently in use are written out |
| 10876 | ** to disk. A dirty page may be in use if a database cursor created by an |
| 10877 | ** active SQL statement is reading from it, or if it is page 1 of a database |
| 10878 | ** file (page 1 is always "in use"). ^The [sqlite3_db_cacheflush(D)] |
| 10879 | ** interface flushes caches for all schemas - "main", "temp", and |
| @@ -15562,10 +15562,11 @@ | |
| 15562 | ** 0x00008000 After all FROM-clause analysis |
| 15563 | ** 0x00010000 Beginning of DELETE/INSERT/UPDATE processing |
| 15564 | ** 0x00020000 Transform DISTINCT into GROUP BY |
| 15565 | ** 0x00040000 SELECT tree dump after all code has been generated |
| 15566 | ** 0x00080000 NOT NULL strength reduction |
| 15567 | */ |
| 15568 | |
| 15569 | /* |
| 15570 | ** Macros for "wheretrace" |
| 15571 | */ |
| @@ -15606,10 +15607,11 @@ | |
| 15606 | ** |
| 15607 | ** 0x00010000 Show more detail when printing WHERE terms |
| 15608 | ** 0x00020000 Show WHERE terms returned from whereScanNext() |
| 15609 | ** 0x00040000 Solver overview messages |
| 15610 | ** 0x00080000 Star-query heuristic |
| 15611 | */ |
| 15612 | |
| 15613 | |
| 15614 | /* |
| 15615 | ** An instance of the following structure is used to store the busy-handler |
| @@ -15678,11 +15680,11 @@ | |
| 15678 | ** one parameter that destructors normally want. So we have to introduce |
| 15679 | ** this magic value that the code knows to handle differently. Any |
| 15680 | ** pointer will work here as long as it is distinct from SQLITE_STATIC |
| 15681 | ** and SQLITE_TRANSIENT. |
| 15682 | */ |
| 15683 | #define SQLITE_DYNAMIC ((sqlite3_destructor_type)sqlite3OomClear) |
| 15684 | |
| 15685 | /* |
| 15686 | ** When SQLITE_OMIT_WSD is defined, it means that the target platform does |
| 15687 | ** not support Writable Static Data (WSD) such as global and static variables. |
| 15688 | ** All variables must either be on the stack or dynamically allocated from |
| @@ -21266,10 +21268,11 @@ | |
| 21266 | #endif |
| 21267 | #ifndef SQLITE_OMIT_WINDOWFUNC |
| 21268 | SQLITE_PRIVATE void sqlite3ShowWindow(const Window*); |
| 21269 | SQLITE_PRIVATE void sqlite3ShowWinFunc(const Window*); |
| 21270 | #endif |
| 21271 | #endif |
| 21272 | |
| 21273 | SQLITE_PRIVATE void sqlite3SetString(char **, sqlite3*, const char*); |
| 21274 | SQLITE_PRIVATE void sqlite3ProgressCheck(Parse*); |
| 21275 | SQLITE_PRIVATE void sqlite3ErrorMsg(Parse*, const char*, ...); |
| @@ -32077,10 +32080,18 @@ | |
| 32077 | }else{ |
| 32078 | longvalue = va_arg(ap,unsigned int); |
| 32079 | } |
| 32080 | prefix = 0; |
| 32081 | } |
| 32082 | if( longvalue==0 ) flag_alternateform = 0; |
| 32083 | if( flag_zeropad && precision<width-(prefix!=0) ){ |
| 32084 | precision = width-(prefix!=0); |
| 32085 | } |
| 32086 | if( precision<etBUFSIZE-10-etBUFSIZE/3 ){ |
| @@ -54872,10 +54883,11 @@ | |
| 54872 | BITVEC_TELEM aBitmap[BITVEC_NELEM]; /* Bitmap representation */ |
| 54873 | u32 aHash[BITVEC_NINT]; /* Hash table representation */ |
| 54874 | Bitvec *apSub[BITVEC_NPTR]; /* Recursive representation */ |
| 54875 | } u; |
| 54876 | }; |
| 54877 | |
| 54878 | /* |
| 54879 | ** Create a new bitmap object able to handle bits between 0 and iSize, |
| 54880 | ** inclusive. Return a pointer to the new object. Return NULL if |
| 54881 | ** malloc fails. |
| @@ -54982,11 +54994,13 @@ | |
| 54982 | if( aiValues==0 ){ |
| 54983 | return SQLITE_NOMEM_BKPT; |
| 54984 | }else{ |
| 54985 | memcpy(aiValues, p->u.aHash, sizeof(p->u.aHash)); |
| 54986 | memset(p->u.apSub, 0, sizeof(p->u.apSub)); |
| 54987 | p->iDivisor = (p->iSize + BITVEC_NPTR - 1)/BITVEC_NPTR; |
| 54988 | rc = sqlite3BitvecSet(p, i); |
| 54989 | for(j=0; j<BITVEC_NINT; j++){ |
| 54990 | if( aiValues[j] ) rc |= sqlite3BitvecSet(p, aiValues[j]); |
| 54991 | } |
| 54992 | sqlite3StackFree(0, aiValues); |
| @@ -55058,10 +55072,56 @@ | |
| 55058 | ** was created. |
| 55059 | */ |
| 55060 | SQLITE_PRIVATE u32 sqlite3BitvecSize(Bitvec *p){ |
| 55061 | return p->iSize; |
| 55062 | } |
| 55063 | |
| 55064 | #ifndef SQLITE_UNTESTABLE |
| 55065 | /* |
| 55066 | ** Let V[] be an array of unsigned characters sufficient to hold |
| 55067 | ** up to N bits. Let I be an integer between 0 and N. 0<=I<N. |
| @@ -55069,40 +55129,48 @@ | |
| 55069 | ** individual bits within V. |
| 55070 | */ |
| 55071 | #define SETBIT(V,I) V[I>>3] |= (1<<(I&7)) |
| 55072 | #define CLEARBIT(V,I) V[I>>3] &= ~(BITVEC_TELEM)(1<<(I&7)) |
| 55073 | #define TESTBIT(V,I) (V[I>>3]&(1<<(I&7)))!=0 |
| 55074 | |
| 55075 | /* |
| 55076 | ** This routine runs an extensive test of the Bitvec code. |
| 55077 | ** |
| 55078 | ** The input is an array of integers that acts as a program |
| 55079 | ** to test the Bitvec. The integers are opcodes followed |
| 55080 | ** by 0, 1, or 3 operands, depending on the opcode. Another |
| 55081 | ** opcode follows immediately after the last operand. |
| 55082 | ** |
| 55083 | ** There are 6 opcodes numbered from 0 through 5. 0 is the |
| 55084 | ** "halt" opcode and causes the test to end. |
| 55085 | ** |
| 55086 | ** 0 Halt and return the number of errors |
| 55087 | ** 1 N S X Set N bits beginning with S and incrementing by X |
| 55088 | ** 2 N S X Clear N bits beginning with S and incrementing by X |
| 55089 | ** 3 N Set N randomly chosen bits |
| 55090 | ** 4 N Clear N randomly chosen bits |
| 55091 | ** 5 N S X Set N bits from S increment X in array only, not in bitvec |
| 55092 | ** |
| 55093 | ** The opcodes 1 through 4 perform set and clear operations are performed |
| 55094 | ** on both a Bitvec object and on a linear array of bits obtained from malloc. |
| 55095 | ** Opcode 5 works on the linear array only, not on the Bitvec. |
| 55096 | ** Opcode 5 is used to deliberately induce a fault in order to |
| 55097 | ** confirm that error detection works. |
| 55098 | ** |
| 55099 | ** At the conclusion of the test the linear array is compared |
| 55100 | ** against the Bitvec object. If there are any differences, |
| 55101 | ** an error is returned. If they are the same, zero is returned. |
| 55102 | ** |
| 55103 | ** If a memory allocation error occurs, return -1. |
| 55104 | */ |
| 55105 | SQLITE_PRIVATE int sqlite3BitvecBuiltinTest(int sz, int *aOp){ |
| 55106 | Bitvec *pBitvec = 0; |
| 55107 | unsigned char *pV = 0; |
| 55108 | int rc = -1; |
| @@ -55109,22 +55177,45 @@ | |
| 55109 | int i, nx, pc, op; |
| 55110 | void *pTmpSpace; |
| 55111 | |
| 55112 | /* Allocate the Bitvec to be tested and a linear array of |
| 55113 | ** bits to act as the reference */ |
| 55114 | pBitvec = sqlite3BitvecCreate( sz ); |
| 55115 | pV = sqlite3MallocZero( (7+(i64)sz)/8 + 1 ); |
| 55116 | pTmpSpace = sqlite3_malloc64(BITVEC_SZ); |
| 55117 | if( pBitvec==0 || pV==0 || pTmpSpace==0 ) goto bitvec_end; |
| 55118 | |
| 55119 | /* NULL pBitvec tests */ |
| 55120 | sqlite3BitvecSet(0, 1); |
| 55121 | sqlite3BitvecClear(0, 1, pTmpSpace); |
| 55122 | |
| 55123 | /* Run the program */ |
| 55124 | pc = i = 0; |
| 55125 | while( (op = aOp[pc])!=0 ){ |
| 55126 | switch( op ){ |
| 55127 | case 1: |
| 55128 | case 2: |
| 55129 | case 5: { |
| 55130 | nx = 4; |
| @@ -55142,33 +55233,37 @@ | |
| 55142 | } |
| 55143 | if( (--aOp[pc+1]) > 0 ) nx = 0; |
| 55144 | pc += nx; |
| 55145 | i = (i & 0x7fffffff)%sz; |
| 55146 | if( (op & 1)!=0 ){ |
| 55147 | SETBIT(pV, (i+1)); |
| 55148 | if( op!=5 ){ |
| 55149 | if( sqlite3BitvecSet(pBitvec, i+1) ) goto bitvec_end; |
| 55150 | } |
| 55151 | }else{ |
| 55152 | CLEARBIT(pV, (i+1)); |
| 55153 | sqlite3BitvecClear(pBitvec, i+1, pTmpSpace); |
| 55154 | } |
| 55155 | } |
| 55156 | |
| 55157 | /* Test to make sure the linear array exactly matches the |
| 55158 | ** Bitvec object. Start with the assumption that they do |
| 55159 | ** match (rc==0). Change rc to non-zero if a discrepancy |
| 55160 | ** is found. |
| 55161 | */ |
| 55162 | rc = sqlite3BitvecTest(0,0) + sqlite3BitvecTest(pBitvec, sz+1) |
| 55163 | + sqlite3BitvecTest(pBitvec, 0) |
| 55164 | + (sqlite3BitvecSize(pBitvec) - sz); |
| 55165 | for(i=1; i<=sz; i++){ |
| 55166 | if( (TESTBIT(pV,i))!=sqlite3BitvecTest(pBitvec,i) ){ |
| 55167 | rc = i; |
| 55168 | break; |
| 55169 | } |
| 55170 | } |
| 55171 | |
| 55172 | /* Free allocated structure */ |
| 55173 | bitvec_end: |
| 55174 | sqlite3_free(pTmpSpace); |
| @@ -69670,10 +69765,11 @@ | |
| 69670 | rc = xUndo(pUndoCtx, walFramePgno(pWal, iFrame)); |
| 69671 | } |
| 69672 | if( iMax!=pWal->hdr.mxFrame ) walCleanupHash(pWal); |
| 69673 | } |
| 69674 | SEH_EXCEPT( rc = SQLITE_IOERR_IN_PAGE; ) |
| 69675 | } |
| 69676 | return rc; |
| 69677 | } |
| 69678 | |
| 69679 | /* |
| @@ -69717,10 +69813,13 @@ | |
| 69717 | pWal->hdr.aFrameCksum[1] = aWalData[2]; |
| 69718 | SEH_TRY { |
| 69719 | walCleanupHash(pWal); |
| 69720 | } |
| 69721 | SEH_EXCEPT( rc = SQLITE_IOERR_IN_PAGE; ) |
| 69722 | } |
| 69723 | |
| 69724 | return rc; |
| 69725 | } |
| 69726 | |
| @@ -77442,12 +77541,12 @@ | |
| 77442 | assert( (pCur->curFlags & BTCF_ValidOvfl)==0 ); |
| 77443 | return rc; |
| 77444 | } |
| 77445 | |
| 77446 | /* |
| 77447 | ** Compare the "idx"-th cell on the page the cursor pCur is currently |
| 77448 | ** pointing to to pIdxKey using xRecordCompare. Return negative or |
| 77449 | ** zero if the cell is less than or equal pIdxKey. Return positive |
| 77450 | ** if unknown. |
| 77451 | ** |
| 77452 | ** Return value negative: Cell at pCur[idx] less than pIdxKey |
| 77453 | ** |
| @@ -77458,16 +77557,15 @@ | |
| 77458 | ** |
| 77459 | ** This routine is part of an optimization. It is always safe to return |
| 77460 | ** a positive value as that will cause the optimization to be skipped. |
| 77461 | */ |
| 77462 | static int indexCellCompare( |
| 77463 | BtCursor *pCur, |
| 77464 | int idx, |
| 77465 | UnpackedRecord *pIdxKey, |
| 77466 | RecordCompare xRecordCompare |
| 77467 | ){ |
| 77468 | MemPage *pPage = pCur->pPage; |
| 77469 | int c; |
| 77470 | int nCell; /* Size of the pCell cell in bytes */ |
| 77471 | u8 *pCell = findCellPastPtr(pPage, idx); |
| 77472 | |
| 77473 | nCell = pCell[0]; |
| @@ -77572,18 +77670,18 @@ | |
| 77572 | && pCur->pPage->leaf |
| 77573 | && cursorOnLastPage(pCur) |
| 77574 | ){ |
| 77575 | int c; |
| 77576 | if( pCur->ix==pCur->pPage->nCell-1 |
| 77577 | && (c = indexCellCompare(pCur, pCur->ix, pIdxKey, xRecordCompare))<=0 |
| 77578 | && pIdxKey->errCode==SQLITE_OK |
| 77579 | ){ |
| 77580 | *pRes = c; |
| 77581 | return SQLITE_OK; /* Cursor already pointing at the correct spot */ |
| 77582 | } |
| 77583 | if( pCur->iPage>0 |
| 77584 | && indexCellCompare(pCur, 0, pIdxKey, xRecordCompare)<=0 |
| 77585 | && pIdxKey->errCode==SQLITE_OK |
| 77586 | ){ |
| 77587 | pCur->curFlags &= ~(BTCF_ValidOvfl|BTCF_AtLast); |
| 77588 | if( !pCur->pPage->isInit ){ |
| 77589 | return SQLITE_CORRUPT_BKPT; |
| @@ -77796,11 +77894,11 @@ | |
| 77796 | if( pCur->eState!=CURSOR_VALID ) return 0; |
| 77797 | if( NEVER(pCur->pPage->leaf==0) ) return -1; |
| 77798 | |
| 77799 | n = pCur->pPage->nCell; |
| 77800 | for(i=0; i<pCur->iPage; i++){ |
| 77801 | n *= pCur->apPage[i]->nCell; |
| 77802 | } |
| 77803 | return n; |
| 77804 | } |
| 77805 | |
| 77806 | /* |
| @@ -97581,10 +97679,19 @@ | |
| 97581 | ** Synopsis: typecheck(r[P1@P2]) |
| 97582 | ** |
| 97583 | ** Apply affinities to the range of P2 registers beginning with P1. |
| 97584 | ** Take the affinities from the Table object in P4. If any value |
| 97585 | ** cannot be coerced into the correct type, then raise an error. |
| 97586 | ** |
| 97587 | ** This opcode is similar to OP_Affinity except that this opcode |
| 97588 | ** forces the register type to the Table column type. This is used |
| 97589 | ** to implement "strict affinity". |
| 97590 | ** |
| @@ -97595,30 +97702,42 @@ | |
| 97595 | ** |
| 97596 | ** Preconditions: |
| 97597 | ** |
| 97598 | ** <ul> |
| 97599 | ** <li> P2 should be the number of non-virtual columns in the |
| 97600 | ** table of P4. |
| 97601 | ** <li> Table P4 should be a STRICT table. |
| 97602 | ** </ul> |
| 97603 | ** |
| 97604 | ** If any precondition is false, an assertion fault occurs. |
| 97605 | */ |
| 97606 | case OP_TypeCheck: { |
| 97607 | Table *pTab; |
| 97608 | Column *aCol; |
| 97609 | int i; |
| 97610 | |
| 97611 | assert( pOp->p4type==P4_TABLE ); |
| 97612 | pTab = pOp->p4.pTab; |
| 97613 | assert( pTab->tabFlags & TF_Strict ); |
| 97614 | assert( pTab->nNVCol==pOp->p2 ); |
| 97615 | aCol = pTab->aCol; |
| 97616 | pIn1 = &aMem[pOp->p1]; |
| 97617 | for(i=0; i<pTab->nCol; i++){ |
| 97618 | if( aCol[i].colFlags & COLFLAG_GENERATED ){ |
| 97619 | if( aCol[i].colFlags & COLFLAG_VIRTUAL ) continue; |
| 97620 | if( pOp->p3 ){ pIn1++; continue; } |
| 97621 | } |
| 97622 | assert( pIn1 < &aMem[pOp->p1+pOp->p2] ); |
| 97623 | applyAffinity(pIn1, aCol[i].affinity, encoding); |
| 97624 | if( (pIn1->flags & MEM_Null)==0 ){ |
| @@ -114626,11 +114745,16 @@ | |
| 114626 | iAddr = sqlite3VdbeAddOp3(v, OP_IfNullRow, pParse->iSelfTab-1, 0, regOut); |
| 114627 | }else{ |
| 114628 | iAddr = 0; |
| 114629 | } |
| 114630 | sqlite3ExprCodeCopy(pParse, sqlite3ColumnExpr(pTab,pCol), regOut); |
| 114631 | if( pCol->affinity>=SQLITE_AFF_TEXT ){ |
| 114632 | sqlite3VdbeAddOp4(v, OP_Affinity, regOut, 1, 0, &pCol->affinity, 1); |
| 114633 | } |
| 114634 | if( iAddr ) sqlite3VdbeJumpHere(v, iAddr); |
| 114635 | if( pParse->nErr>nErr ) pParse->db->errByteOffset = -1; |
| 114636 | } |
| @@ -132020,11 +132144,11 @@ | |
| 132020 | int argc, |
| 132021 | sqlite3_value **argv, |
| 132022 | int nSep, |
| 132023 | const char *zSep |
| 132024 | ){ |
| 132025 | i64 j, k, n = 0; |
| 132026 | int i; |
| 132027 | char *z; |
| 132028 | for(i=0; i<argc; i++){ |
| 132029 | n += sqlite3_value_bytes(argv[i]); |
| 132030 | } |
| @@ -132034,12 +132158,12 @@ | |
| 132034 | sqlite3_result_error_nomem(context); |
| 132035 | return; |
| 132036 | } |
| 132037 | j = 0; |
| 132038 | for(i=0; i<argc; i++){ |
| 132039 | k = sqlite3_value_bytes(argv[i]); |
| 132040 | if( k>0 ){ |
| 132041 | const char *v = (const char*)sqlite3_value_text(argv[i]); |
| 132042 | if( v!=0 ){ |
| 132043 | if( j>0 && nSep>0 ){ |
| 132044 | memcpy(&z[j], zSep, nSep); |
| 132045 | j += nSep; |
| @@ -134973,16 +135097,19 @@ | |
| 134973 | if( iReg==0 ){ |
| 134974 | /* Move the previous opcode (which should be OP_MakeRecord) forward |
| 134975 | ** by one slot and insert a new OP_TypeCheck where the current |
| 134976 | ** OP_MakeRecord is found */ |
| 134977 | VdbeOp *pPrev; |
| 134978 | sqlite3VdbeAppendP4(v, pTab, P4_TABLE); |
| 134979 | pPrev = sqlite3VdbeGetLastOp(v); |
| 134980 | assert( pPrev!=0 ); |
| 134981 | assert( pPrev->opcode==OP_MakeRecord || sqlite3VdbeDb(v)->mallocFailed ); |
| 134982 | pPrev->opcode = OP_TypeCheck; |
| 134983 | sqlite3VdbeAddOp3(v, OP_MakeRecord, pPrev->p1, pPrev->p2, pPrev->p3); |
| 134984 | }else{ |
| 134985 | /* Insert an isolated OP_Typecheck */ |
| 134986 | sqlite3VdbeAddOp2(v, OP_TypeCheck, iReg, pTab->nNVCol); |
| 134987 | sqlite3VdbeAppendP4(v, pTab, P4_TABLE); |
| 134988 | } |
| @@ -159213,10 +159340,13 @@ | |
| 159213 | u16 eOperator; /* A WO_xx value describing <op> */ |
| 159214 | u8 nChild; /* Number of children that must disable us */ |
| 159215 | u8 eMatchOp; /* Op for vtab MATCH/LIKE/GLOB/REGEXP terms */ |
| 159216 | int iParent; /* Disable pWC->a[iParent] when this term disabled */ |
| 159217 | int leftCursor; /* Cursor number of X in "X <op> <expr>" */ |
| 159218 | union { |
| 159219 | struct { |
| 159220 | int leftColumn; /* Column number of X in "X <op> <expr>" */ |
| 159221 | int iField; /* Field in (?,?,?) IN (SELECT...) vector */ |
| 159222 | } x; /* Opcode other than OP_OR or OP_AND */ |
| @@ -161410,40 +161540,40 @@ | |
| 161410 | VdbeCoverageIf(v, testOp==OP_Ge); |
| 161411 | VdbeCoverageIf(v, testOp==OP_Gt); |
| 161412 | sqlite3VdbeChangeP5(v, SQLITE_AFF_NUMERIC | SQLITE_JUMPIFNULL); |
| 161413 | } |
| 161414 | }else if( pLoop->wsFlags & WHERE_INDEXED ){ |
| 161415 | /* Case 4: A scan using an index. |
| 161416 | ** |
| 161417 | ** The WHERE clause may contain zero or more equality |
| 161418 | ** terms ("==" or "IN" operators) that refer to the N |
| 161419 | ** left-most columns of the index. It may also contain |
| 161420 | ** inequality constraints (>, <, >= or <=) on the indexed |
| 161421 | ** column that immediately follows the N equalities. Only |
| 161422 | ** the right-most column can be an inequality - the rest must |
| 161423 | ** use the "==" and "IN" operators. For example, if the |
| 161424 | ** index is on (x,y,z), then the following clauses are all |
| 161425 | ** optimized: |
| 161426 | ** |
| 161427 | ** x=5 |
| 161428 | ** x=5 AND y=10 |
| 161429 | ** x=5 AND y<10 |
| 161430 | ** x=5 AND y>5 AND y<10 |
| 161431 | ** x=5 AND y=5 AND z<=10 |
| 161432 | ** |
| 161433 | ** The z<10 term of the following cannot be used, only |
| 161434 | ** the x=5 term: |
| 161435 | ** |
| 161436 | ** x=5 AND z<10 |
| 161437 | ** |
| 161438 | ** N may be zero if there are inequality constraints. |
| 161439 | ** If there are no inequality constraints, then N is at |
| 161440 | ** least one. |
| 161441 | ** |
| 161442 | ** This case is also used when there are no WHERE clause |
| 161443 | ** constraints but an index is selected anyway, in order |
| 161444 | ** to force the output order to conform to an ORDER BY. |
| 161445 | */ |
| 161446 | static const u8 aStartOp[] = { |
| 161447 | 0, |
| 161448 | 0, |
| 161449 | OP_Rewind, /* 2: (!start_constraints && startEq && !bRev) */ |
| @@ -163459,34 +163589,46 @@ | |
| 163459 | ** column references. This routine checks to see if pExpr is an equivalence |
| 163460 | ** relation: |
| 163461 | ** 1. The SQLITE_Transitive optimization must be enabled |
| 163462 | ** 2. Must be either an == or an IS operator |
| 163463 | ** 3. Not originating in the ON clause of an OUTER JOIN |
| 163464 | ** 4. The affinities of A and B must be compatible |
| 163465 | ** 5a. Both operands use the same collating sequence OR |
| 163466 | ** 5b. The overall collating sequence is BINARY |
| 163467 | ** If this routine returns TRUE, that means that the RHS can be substituted |
| 163468 | ** for the LHS anyplace else in the WHERE clause where the LHS column occurs. |
| 163469 | ** This is an optimization. No harm comes from returning 0. But if 1 is |
| 163470 | ** returned when it should not be, then incorrect answers might result. |
| 163471 | */ |
| 163472 | static int termIsEquivalence(Parse *pParse, Expr *pExpr){ |
| 163473 | char aff1, aff2; |
| 163474 | CollSeq *pColl; |
| 163475 | if( !OptimizationEnabled(pParse->db, SQLITE_Transitive) ) return 0; |
| 163476 | if( pExpr->op!=TK_EQ && pExpr->op!=TK_IS ) return 0; |
| 163477 | if( ExprHasProperty(pExpr, EP_OuterON) ) return 0; |
| 163478 | aff1 = sqlite3ExprAffinity(pExpr->pLeft); |
| 163479 | aff2 = sqlite3ExprAffinity(pExpr->pRight); |
| 163480 | if( aff1!=aff2 |
| 163481 | && (!sqlite3IsNumericAffinity(aff1) || !sqlite3IsNumericAffinity(aff2)) |
| 163482 | ){ |
| 163483 | return 0; |
| 163484 | } |
| 163485 | pColl = sqlite3ExprCompareCollSeq(pParse, pExpr); |
| 163486 | if( sqlite3IsBinary(pColl) ) return 1; |
| 163487 | return sqlite3ExprCollSeqMatch(pParse, pExpr->pLeft, pExpr->pRight); |
| 163488 | } |
| 163489 | |
| 163490 | /* |
| 163491 | ** Recursively walk the expressions of a SELECT statement and generate |
| 163492 | ** a bitmask indicating which tables are used in that expression |
| @@ -163640,10 +163782,13 @@ | |
| 163640 | if( db->mallocFailed ){ |
| 163641 | return; |
| 163642 | } |
| 163643 | assert( pWC->nTerm > idxTerm ); |
| 163644 | pTerm = &pWC->a[idxTerm]; |
| 163645 | pMaskSet = &pWInfo->sMaskSet; |
| 163646 | pExpr = pTerm->pExpr; |
| 163647 | assert( pExpr!=0 ); /* Because malloc() has not failed */ |
| 163648 | assert( pExpr->op!=TK_AS && pExpr->op!=TK_COLLATE ); |
| 163649 | pMaskSet->bVarSelect = 0; |
| @@ -163747,12 +163892,12 @@ | |
| 163747 | pNew = &pWC->a[idxNew]; |
| 163748 | markTermAsChild(pWC, idxNew, idxTerm); |
| 163749 | if( op==TK_IS ) pNew->wtFlags |= TERM_IS; |
| 163750 | pTerm = &pWC->a[idxTerm]; |
| 163751 | pTerm->wtFlags |= TERM_COPIED; |
| 163752 | |
| 163753 | if( termIsEquivalence(pParse, pDup) ){ |
| 163754 | pTerm->eOperator |= WO_EQUIV; |
| 163755 | eExtraOp = WO_EQUIV; |
| 163756 | } |
| 163757 | }else{ |
| 163758 | pDup = pExpr; |
| @@ -164867,15 +165012,15 @@ | |
| 164867 | continue; |
| 164868 | } |
| 164869 | pScan->pWC = pWC; |
| 164870 | pScan->k = k+1; |
| 164871 | #ifdef WHERETRACE_ENABLED |
| 164872 | if( sqlite3WhereTrace & 0x20000 ){ |
| 164873 | int ii; |
| 164874 | sqlite3DebugPrintf("SCAN-TERM %p: nEquiv=%d", |
| 164875 | pTerm, pScan->nEquiv); |
| 164876 | for(ii=0; ii<pScan->nEquiv; ii++){ |
| 164877 | sqlite3DebugPrintf(" {%d:%d}", |
| 164878 | pScan->aiCur[ii], pScan->aiColumn[ii]); |
| 164879 | } |
| 164880 | sqlite3DebugPrintf("\n"); |
| 164881 | } |
| @@ -166826,10 +166971,11 @@ | |
| 166826 | sqlite3_snprintf(sizeof(zLeft),zLeft,"indexable=0x%llx", |
| 166827 | pTerm->u.pOrInfo->indexable); |
| 166828 | }else{ |
| 166829 | sqlite3_snprintf(sizeof(zLeft),zLeft,"left=%d", pTerm->leftCursor); |
| 166830 | } |
| 166831 | sqlite3DebugPrintf( |
| 166832 | "TERM-%-3d %p %s %-12s op=%03x wtFlags=%04x", |
| 166833 | iTerm, pTerm, zType, zLeft, pTerm->eOperator, pTerm->wtFlags); |
| 166834 | /* The 0x10000 .wheretrace flag causes extra information to be |
| 166835 | ** shown about each Term */ |
| @@ -184450,10 +184596,11 @@ | |
| 184450 | #ifdef SQLITE_ENABLE_API_ARMOR |
| 184451 | if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; |
| 184452 | #endif |
| 184453 | if( ms<-1 ) return SQLITE_RANGE; |
| 184454 | #ifdef SQLITE_ENABLE_SETLK_TIMEOUT |
| 184455 | db->setlkTimeout = ms; |
| 184456 | db->setlkFlags = flags; |
| 184457 | sqlite3BtreeEnterAll(db); |
| 184458 | for(iDb=0; iDb<db->nDb; iDb++){ |
| 184459 | Btree *pBt = db->aDb[iDb].pBt; |
| @@ -184461,10 +184608,11 @@ | |
| 184461 | sqlite3_file *fd = sqlite3PagerFile(sqlite3BtreePager(pBt)); |
| 184462 | sqlite3OsFileControlHint(fd, SQLITE_FCNTL_BLOCK_ON_CONNECT, (void*)&bBOC); |
| 184463 | } |
| 184464 | } |
| 184465 | sqlite3BtreeLeaveAll(db); |
| 184466 | #endif |
| 184467 | #if !defined(SQLITE_ENABLE_API_ARMOR) && !defined(SQLITE_ENABLE_SETLK_TIMEOUT) |
| 184468 | UNUSED_PARAMETER(db); |
| 184469 | UNUSED_PARAMETER(flags); |
| 184470 | #endif |
| @@ -257257,11 +257405,11 @@ | |
| 257257 | int nArg, /* Number of args */ |
| 257258 | sqlite3_value **apUnused /* Function arguments */ |
| 257259 | ){ |
| 257260 | assert( nArg==0 ); |
| 257261 | UNUSED_PARAM2(nArg, apUnused); |
| 257262 | sqlite3_result_text(pCtx, "fts5: 2025-06-03 10:49:51 ea1754f7d8a770477a1b19b606b27724fdc0b733e51fef32c1ef834f972c3cc5", -1, SQLITE_TRANSIENT); |
| 257263 | } |
| 257264 | |
| 257265 | /* |
| 257266 | ** Implementation of fts5_locale(LOCALE, TEXT) function. |
| 257267 | ** |
| @@ -258072,10 +258220,11 @@ | |
| 258072 | ctx.pStorage = p; |
| 258073 | ctx.iCol = -1; |
| 258074 | for(iCol=1; rc==SQLITE_OK && iCol<=pConfig->nCol; iCol++){ |
| 258075 | if( pConfig->abUnindexed[iCol-1]==0 ){ |
| 258076 | sqlite3_value *pVal = 0; |
| 258077 | const char *pText = 0; |
| 258078 | int nText = 0; |
| 258079 | const char *pLoc = 0; |
| 258080 | int nLoc = 0; |
| 258081 | |
| @@ -258088,15 +258237,26 @@ | |
| 258088 | } |
| 258089 | |
| 258090 | if( pConfig->bLocale && sqlite3Fts5IsLocaleValue(pConfig, pVal) ){ |
| 258091 | rc = sqlite3Fts5DecodeLocaleValue(pVal, &pText, &nText, &pLoc, &nLoc); |
| 258092 | }else{ |
| 258093 | pText = (const char*)sqlite3_value_text(pVal); |
| 258094 | nText = sqlite3_value_bytes(pVal); |
| 258095 | if( pConfig->bLocale && pSeek ){ |
| 258096 | pLoc = (const char*)sqlite3_column_text(pSeek, iCol + pConfig->nCol); |
| 258097 | nLoc = sqlite3_column_bytes(pSeek, iCol + pConfig->nCol); |
| 258098 | } |
| 258099 | } |
| 258100 | |
| 258101 | if( rc==SQLITE_OK ){ |
| 258102 | sqlite3Fts5SetLocale(pConfig, pLoc, nLoc); |
| @@ -258108,10 +258268,11 @@ | |
| 258108 | if( rc==SQLITE_OK && p->aTotalSize[iCol-1]<0 ){ |
| 258109 | rc = FTS5_CORRUPT; |
| 258110 | } |
| 258111 | sqlite3Fts5ClearLocale(pConfig); |
| 258112 | } |
| 258113 | } |
| 258114 | } |
| 258115 | if( rc==SQLITE_OK && p->nTotalRow<1 ){ |
| 258116 | rc = FTS5_CORRUPT; |
| 258117 | }else{ |
| 258118 |
| --- extsrc/sqlite3.c | |
| +++ extsrc/sqlite3.c | |
| @@ -16,11 +16,11 @@ | |
| 16 | ** if you want a wrapper to interface SQLite with your choice of programming |
| 17 | ** language. The code for the "sqlite3" command-line shell is also in a |
| 18 | ** separate file. This file contains only code for the core SQLite library. |
| 19 | ** |
| 20 | ** The content in this amalgamation comes from Fossil check-in |
| 21 | ** a88bb75288a06492a04ab1278e8a2101a74f with changes in files: |
| 22 | ** |
| 23 | ** |
| 24 | */ |
| 25 | #ifndef SQLITE_AMALGAMATION |
| 26 | #define SQLITE_CORE 1 |
| @@ -465,11 +465,11 @@ | |
| 465 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 466 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 467 | */ |
| 468 | #define SQLITE_VERSION "3.51.0" |
| 469 | #define SQLITE_VERSION_NUMBER 3051000 |
| 470 | #define SQLITE_SOURCE_ID "2025-06-19 20:19:12 a88bb75288a06492a04ab1278e8a2101a74f4ba712d328b4c73e86ac01cb946d" |
| 471 | |
| 472 | /* |
| 473 | ** CAPI3REF: Run-Time Library Version Numbers |
| 474 | ** KEYWORDS: sqlite3_version sqlite3_sourceid |
| 475 | ** |
| @@ -4396,11 +4396,11 @@ | |
| 4396 | ** These interfaces are provided for use by [VFS shim] implementations and |
| 4397 | ** are not useful outside of that context. |
| 4398 | ** |
| 4399 | ** The sqlite3_create_filename(D,J,W,N,P) allocates memory to hold a version of |
| 4400 | ** database filename D with corresponding journal file J and WAL file W and |
| 4401 | ** an array P of N URI Key/Value pairs. The result from |
| 4402 | ** sqlite3_create_filename(D,J,W,N,P) is a pointer to a database filename that |
| 4403 | ** is safe to pass to routines like: |
| 4404 | ** <ul> |
| 4405 | ** <li> [sqlite3_uri_parameter()], |
| 4406 | ** <li> [sqlite3_uri_boolean()], |
| @@ -5077,11 +5077,11 @@ | |
| 5077 | ** KEYWORDS: {host parameter} {host parameters} {host parameter name} |
| 5078 | ** KEYWORDS: {SQL parameter} {SQL parameters} {parameter binding} |
| 5079 | ** METHOD: sqlite3_stmt |
| 5080 | ** |
| 5081 | ** ^(In the SQL statement text input to [sqlite3_prepare_v2()] and its variants, |
| 5082 | ** literals may be replaced by a [parameter] that matches one of the following |
| 5083 | ** templates: |
| 5084 | ** |
| 5085 | ** <ul> |
| 5086 | ** <li> ? |
| 5087 | ** <li> ?NNN |
| @@ -5122,11 +5122,11 @@ | |
| 5122 | ** either UTF8 if the sixth parameter is SQLITE_UTF8, or UTF16 |
| 5123 | ** otherwise. |
| 5124 | ** |
| 5125 | ** [[byte-order determination rules]] ^The byte-order of |
| 5126 | ** UTF16 input text is determined by the byte-order mark (BOM, U+FEFF) |
| 5127 | ** found in the first character, which is removed, or in the absence of a BOM |
| 5128 | ** the byte order is the native byte order of the host |
| 5129 | ** machine for sqlite3_bind_text16() or the byte order specified in |
| 5130 | ** the 6th parameter for sqlite3_bind_text64().)^ |
| 5131 | ** ^If UTF16 input text contains invalid unicode |
| 5132 | ** characters, then SQLite might change those invalid characters |
| @@ -5142,11 +5142,11 @@ | |
| 5142 | ** the behavior is undefined. |
| 5143 | ** If a non-negative fourth parameter is provided to sqlite3_bind_text() |
| 5144 | ** or sqlite3_bind_text16() or sqlite3_bind_text64() then |
| 5145 | ** that parameter must be the byte offset |
| 5146 | ** where the NUL terminator would occur assuming the string were NUL |
| 5147 | ** terminated. If any NUL characters occur at byte offsets less than |
| 5148 | ** the value of the fourth parameter then the resulting string value will |
| 5149 | ** contain embedded NULs. The result of expressions involving strings |
| 5150 | ** with embedded NULs is undefined. |
| 5151 | ** |
| 5152 | ** ^The fifth argument to the BLOB and string binding interfaces controls |
| @@ -5354,11 +5354,11 @@ | |
| 5354 | /* |
| 5355 | ** CAPI3REF: Source Of Data In A Query Result |
| 5356 | ** METHOD: sqlite3_stmt |
| 5357 | ** |
| 5358 | ** ^These routines provide a means to determine the database, table, and |
| 5359 | ** table column that is the origin of a particular result column in a |
| 5360 | ** [SELECT] statement. |
| 5361 | ** ^The name of the database or table or column can be returned as |
| 5362 | ** either a UTF-8 or UTF-16 string. ^The _database_ routines return |
| 5363 | ** the database name, the _table_ routines return the table name, and |
| 5364 | ** the origin_ routines return the column name. |
| @@ -5923,12 +5923,12 @@ | |
| 5923 | ** within VIEWs, TRIGGERs, CHECK constraints, generated column expressions, |
| 5924 | ** index expressions, or the WHERE clause of partial indexes. |
| 5925 | ** |
| 5926 | ** For best security, the [SQLITE_DIRECTONLY] flag is recommended for |
| 5927 | ** all application-defined SQL functions that do not need to be |
| 5928 | ** used inside of triggers, views, CHECK constraints, or other elements of |
| 5929 | ** the database schema. This flag is especially recommended for SQL |
| 5930 | ** functions that have side effects or reveal internal application state. |
| 5931 | ** Without this flag, an attacker might be able to modify the schema of |
| 5932 | ** a database file to include invocations of the function with parameters |
| 5933 | ** chosen by the attacker, which the application will then execute when |
| 5934 | ** the database file is opened and read. |
| @@ -5955,11 +5955,11 @@ | |
| 5955 | ** or aggregate window function. More details regarding the implementation |
| 5956 | ** of aggregate window functions are |
| 5957 | ** [user-defined window functions|available here]. |
| 5958 | ** |
| 5959 | ** ^(If the final parameter to sqlite3_create_function_v2() or |
| 5960 | ** sqlite3_create_window_function() is not NULL, then it is the destructor for |
| 5961 | ** the application data pointer. The destructor is invoked when the function |
| 5962 | ** is deleted, either by being overloaded or when the database connection |
| 5963 | ** closes.)^ ^The destructor is also invoked if the call to |
| 5964 | ** sqlite3_create_function_v2() fails. ^When the destructor callback is |
| 5965 | ** invoked, it is passed a single argument which is a copy of the application |
| @@ -7763,11 +7763,11 @@ | |
| 7763 | ** that is to be automatically loaded into all new database connections. |
| 7764 | ** |
| 7765 | ** ^(Even though the function prototype shows that xEntryPoint() takes |
| 7766 | ** no arguments and returns void, SQLite invokes xEntryPoint() with three |
| 7767 | ** arguments and expects an integer result as if the signature of the |
| 7768 | ** entry point were as follows: |
| 7769 | ** |
| 7770 | ** <blockquote><pre> |
| 7771 | ** int xEntryPoint( |
| 7772 | ** sqlite3 *db, |
| 7773 | ** const char **pzErrMsg, |
| @@ -8094,11 +8094,11 @@ | |
| 8094 | ** by the first parameter. ^The name of the module is given by the |
| 8095 | ** second parameter. ^The third parameter is a pointer to |
| 8096 | ** the implementation of the [virtual table module]. ^The fourth |
| 8097 | ** parameter is an arbitrary client data pointer that is passed through |
| 8098 | ** into the [xCreate] and [xConnect] methods of the virtual table module |
| 8099 | ** when a new virtual table is being created or reinitialized. |
| 8100 | ** |
| 8101 | ** ^The sqlite3_create_module_v2() interface has a fifth parameter which |
| 8102 | ** is a pointer to a destructor for the pClientData. ^SQLite will |
| 8103 | ** invoke the destructor function (if it is not NULL) when SQLite |
| 8104 | ** no longer needs the pClientData pointer. ^The destructor will also |
| @@ -8259,11 +8259,11 @@ | |
| 8259 | ** |
| 8260 | ** ^(On success, [SQLITE_OK] is returned and the new [BLOB handle] is stored |
| 8261 | ** in *ppBlob. Otherwise an [error code] is returned and, unless the error |
| 8262 | ** code is SQLITE_MISUSE, *ppBlob is set to NULL.)^ ^This means that, provided |
| 8263 | ** the API is not misused, it is always safe to call [sqlite3_blob_close()] |
| 8264 | ** on *ppBlob after this function returns. |
| 8265 | ** |
| 8266 | ** This function fails with SQLITE_ERROR if any of the following are true: |
| 8267 | ** <ul> |
| 8268 | ** <li> ^(Database zDb does not exist)^, |
| 8269 | ** <li> ^(Table zTable does not exist within database zDb)^, |
| @@ -8379,11 +8379,11 @@ | |
| 8379 | ** CAPI3REF: Return The Size Of An Open BLOB |
| 8380 | ** METHOD: sqlite3_blob |
| 8381 | ** |
| 8382 | ** ^Returns the size in bytes of the BLOB accessible via the |
| 8383 | ** successfully opened [BLOB handle] in its only argument. ^The |
| 8384 | ** incremental blob I/O routines can only read or overwrite existing |
| 8385 | ** blob content; they cannot change the size of a blob. |
| 8386 | ** |
| 8387 | ** This routine only works on a [BLOB handle] which has been created |
| 8388 | ** by a prior successful call to [sqlite3_blob_open()] and which has not |
| 8389 | ** been closed by [sqlite3_blob_close()]. Passing any other pointer in |
| @@ -9782,11 +9782,11 @@ | |
| 9782 | ** sqlite3_backup_step(), the source database may be modified mid-way |
| 9783 | ** through the backup process. ^If the source database is modified by an |
| 9784 | ** external process or via a database connection other than the one being |
| 9785 | ** used by the backup operation, then the backup will be automatically |
| 9786 | ** restarted by the next call to sqlite3_backup_step(). ^If the source |
| 9787 | ** database is modified by using the same database connection as is used |
| 9788 | ** by the backup operation, then the backup database is automatically |
| 9789 | ** updated at the same time. |
| 9790 | ** |
| 9791 | ** [[sqlite3_backup_finish()]] <b>sqlite3_backup_finish()</b> |
| 9792 | ** |
| @@ -9799,11 +9799,11 @@ | |
| 9799 | ** active write-transaction on the destination database is rolled back. |
| 9800 | ** The [sqlite3_backup] object is invalid |
| 9801 | ** and may not be used following a call to sqlite3_backup_finish(). |
| 9802 | ** |
| 9803 | ** ^The value returned by sqlite3_backup_finish is [SQLITE_OK] if no |
| 9804 | ** sqlite3_backup_step() errors occurred, regardless of whether or not |
| 9805 | ** sqlite3_backup_step() completed. |
| 9806 | ** ^If an out-of-memory condition or IO error occurred during any prior |
| 9807 | ** sqlite3_backup_step() call on the same [sqlite3_backup] object, then |
| 9808 | ** sqlite3_backup_finish() returns the corresponding [error code]. |
| 9809 | ** |
| @@ -10869,11 +10869,11 @@ | |
| 10869 | /* |
| 10870 | ** CAPI3REF: Flush caches to disk mid-transaction |
| 10871 | ** METHOD: sqlite3 |
| 10872 | ** |
| 10873 | ** ^If a write-transaction is open on [database connection] D when the |
| 10874 | ** [sqlite3_db_cacheflush(D)] interface is invoked, any dirty |
| 10875 | ** pages in the pager-cache that are not currently in use are written out |
| 10876 | ** to disk. A dirty page may be in use if a database cursor created by an |
| 10877 | ** active SQL statement is reading from it, or if it is page 1 of a database |
| 10878 | ** file (page 1 is always "in use"). ^The [sqlite3_db_cacheflush(D)] |
| 10879 | ** interface flushes caches for all schemas - "main", "temp", and |
| @@ -15562,10 +15562,11 @@ | |
| 15562 | ** 0x00008000 After all FROM-clause analysis |
| 15563 | ** 0x00010000 Beginning of DELETE/INSERT/UPDATE processing |
| 15564 | ** 0x00020000 Transform DISTINCT into GROUP BY |
| 15565 | ** 0x00040000 SELECT tree dump after all code has been generated |
| 15566 | ** 0x00080000 NOT NULL strength reduction |
| 15567 | ** 0x00100000 Pointers are all shown as zero |
| 15568 | */ |
| 15569 | |
| 15570 | /* |
| 15571 | ** Macros for "wheretrace" |
| 15572 | */ |
| @@ -15606,10 +15607,11 @@ | |
| 15607 | ** |
| 15608 | ** 0x00010000 Show more detail when printing WHERE terms |
| 15609 | ** 0x00020000 Show WHERE terms returned from whereScanNext() |
| 15610 | ** 0x00040000 Solver overview messages |
| 15611 | ** 0x00080000 Star-query heuristic |
| 15612 | ** 0x00100000 Pointers are all shown as zero |
| 15613 | */ |
| 15614 | |
| 15615 | |
| 15616 | /* |
| 15617 | ** An instance of the following structure is used to store the busy-handler |
| @@ -15678,11 +15680,11 @@ | |
| 15680 | ** one parameter that destructors normally want. So we have to introduce |
| 15681 | ** this magic value that the code knows to handle differently. Any |
| 15682 | ** pointer will work here as long as it is distinct from SQLITE_STATIC |
| 15683 | ** and SQLITE_TRANSIENT. |
| 15684 | */ |
| 15685 | #define SQLITE_DYNAMIC ((sqlite3_destructor_type)sqlite3RowSetClear) |
| 15686 | |
| 15687 | /* |
| 15688 | ** When SQLITE_OMIT_WSD is defined, it means that the target platform does |
| 15689 | ** not support Writable Static Data (WSD) such as global and static variables. |
| 15690 | ** All variables must either be on the stack or dynamically allocated from |
| @@ -21266,10 +21268,11 @@ | |
| 21268 | #endif |
| 21269 | #ifndef SQLITE_OMIT_WINDOWFUNC |
| 21270 | SQLITE_PRIVATE void sqlite3ShowWindow(const Window*); |
| 21271 | SQLITE_PRIVATE void sqlite3ShowWinFunc(const Window*); |
| 21272 | #endif |
| 21273 | SQLITE_PRIVATE void sqlite3ShowBitvec(Bitvec*); |
| 21274 | #endif |
| 21275 | |
| 21276 | SQLITE_PRIVATE void sqlite3SetString(char **, sqlite3*, const char*); |
| 21277 | SQLITE_PRIVATE void sqlite3ProgressCheck(Parse*); |
| 21278 | SQLITE_PRIVATE void sqlite3ErrorMsg(Parse*, const char*, ...); |
| @@ -32077,10 +32080,18 @@ | |
| 32080 | }else{ |
| 32081 | longvalue = va_arg(ap,unsigned int); |
| 32082 | } |
| 32083 | prefix = 0; |
| 32084 | } |
| 32085 | |
| 32086 | #if WHERETRACE_ENABLED |
| 32087 | if( xtype==etPOINTER && sqlite3WhereTrace & 0x100000 ) longvalue = 0; |
| 32088 | #endif |
| 32089 | #if TREETRACE_ENABLED |
| 32090 | if( xtype==etPOINTER && sqlite3TreeTrace & 0x100000 ) longvalue = 0; |
| 32091 | #endif |
| 32092 | |
| 32093 | if( longvalue==0 ) flag_alternateform = 0; |
| 32094 | if( flag_zeropad && precision<width-(prefix!=0) ){ |
| 32095 | precision = width-(prefix!=0); |
| 32096 | } |
| 32097 | if( precision<etBUFSIZE-10-etBUFSIZE/3 ){ |
| @@ -54872,10 +54883,11 @@ | |
| 54883 | BITVEC_TELEM aBitmap[BITVEC_NELEM]; /* Bitmap representation */ |
| 54884 | u32 aHash[BITVEC_NINT]; /* Hash table representation */ |
| 54885 | Bitvec *apSub[BITVEC_NPTR]; /* Recursive representation */ |
| 54886 | } u; |
| 54887 | }; |
| 54888 | |
| 54889 | |
| 54890 | /* |
| 54891 | ** Create a new bitmap object able to handle bits between 0 and iSize, |
| 54892 | ** inclusive. Return a pointer to the new object. Return NULL if |
| 54893 | ** malloc fails. |
| @@ -54982,11 +54994,13 @@ | |
| 54994 | if( aiValues==0 ){ |
| 54995 | return SQLITE_NOMEM_BKPT; |
| 54996 | }else{ |
| 54997 | memcpy(aiValues, p->u.aHash, sizeof(p->u.aHash)); |
| 54998 | memset(p->u.apSub, 0, sizeof(p->u.apSub)); |
| 54999 | p->iDivisor = p->iSize/BITVEC_NPTR; |
| 55000 | if( (p->iSize%BITVEC_NPTR)!=0 ) p->iDivisor++; |
| 55001 | if( p->iDivisor<BITVEC_NBIT ) p->iDivisor = BITVEC_NBIT; |
| 55002 | rc = sqlite3BitvecSet(p, i); |
| 55003 | for(j=0; j<BITVEC_NINT; j++){ |
| 55004 | if( aiValues[j] ) rc |= sqlite3BitvecSet(p, aiValues[j]); |
| 55005 | } |
| 55006 | sqlite3StackFree(0, aiValues); |
| @@ -55058,10 +55072,56 @@ | |
| 55072 | ** was created. |
| 55073 | */ |
| 55074 | SQLITE_PRIVATE u32 sqlite3BitvecSize(Bitvec *p){ |
| 55075 | return p->iSize; |
| 55076 | } |
| 55077 | |
| 55078 | #ifdef SQLITE_DEBUG |
| 55079 | /* |
| 55080 | ** Show the content of a Bitvec option and its children. Indent |
| 55081 | ** everything by n spaces. Add x to each bitvec value. |
| 55082 | ** |
| 55083 | ** From a debugger such as gdb, one can type: |
| 55084 | ** |
| 55085 | ** call sqlite3ShowBitvec(p) |
| 55086 | ** |
| 55087 | ** For some Bitvec p and see a recursive view of the Bitvec's content. |
| 55088 | */ |
| 55089 | static void showBitvec(Bitvec *p, int n, unsigned x){ |
| 55090 | int i; |
| 55091 | if( p==0 ){ |
| 55092 | printf("NULL\n"); |
| 55093 | return; |
| 55094 | } |
| 55095 | printf("Bitvec 0x%p iSize=%u", p, p->iSize); |
| 55096 | if( p->iSize<=BITVEC_NBIT ){ |
| 55097 | printf(" bitmap\n"); |
| 55098 | printf("%*s bits:", n, ""); |
| 55099 | for(i=1; i<=BITVEC_NBIT; i++){ |
| 55100 | if( sqlite3BitvecTest(p,i) ) printf(" %u", x+(unsigned)i); |
| 55101 | } |
| 55102 | printf("\n"); |
| 55103 | }else if( p->iDivisor==0 ){ |
| 55104 | printf(" hash with %u entries\n", p->nSet); |
| 55105 | printf("%*s bits:", n, ""); |
| 55106 | for(i=0; i<BITVEC_NINT; i++){ |
| 55107 | if( p->u.aHash[i] ) printf(" %u", x+(unsigned)p->u.aHash[i]); |
| 55108 | } |
| 55109 | printf("\n"); |
| 55110 | }else{ |
| 55111 | printf(" sub-bitvec with iDivisor=%u\n", p->iDivisor); |
| 55112 | for(i=0; i<BITVEC_NPTR; i++){ |
| 55113 | if( p->u.apSub[i]==0 ) continue; |
| 55114 | printf("%*s apSub[%d]=", n, "", i); |
| 55115 | showBitvec(p->u.apSub[i], n+4, i*p->iDivisor); |
| 55116 | } |
| 55117 | } |
| 55118 | } |
| 55119 | SQLITE_PRIVATE void sqlite3ShowBitvec(Bitvec *p){ |
| 55120 | showBitvec(p, 0, 0); |
| 55121 | } |
| 55122 | #endif |
| 55123 | |
| 55124 | #ifndef SQLITE_UNTESTABLE |
| 55125 | /* |
| 55126 | ** Let V[] be an array of unsigned characters sufficient to hold |
| 55127 | ** up to N bits. Let I be an integer between 0 and N. 0<=I<N. |
| @@ -55069,40 +55129,48 @@ | |
| 55129 | ** individual bits within V. |
| 55130 | */ |
| 55131 | #define SETBIT(V,I) V[I>>3] |= (1<<(I&7)) |
| 55132 | #define CLEARBIT(V,I) V[I>>3] &= ~(BITVEC_TELEM)(1<<(I&7)) |
| 55133 | #define TESTBIT(V,I) (V[I>>3]&(1<<(I&7)))!=0 |
| 55134 | |
| 55135 | |
| 55136 | /* |
| 55137 | ** This routine runs an extensive test of the Bitvec code. |
| 55138 | ** |
| 55139 | ** The input is an array of integers that acts as a program |
| 55140 | ** to test the Bitvec. The integers are opcodes followed |
| 55141 | ** by 0, 1, or 3 operands, depending on the opcode. Another |
| 55142 | ** opcode follows immediately after the last operand. |
| 55143 | ** |
| 55144 | ** There are opcodes numbered starting with 0. 0 is the |
| 55145 | ** "halt" opcode and causes the test to end. |
| 55146 | ** |
| 55147 | ** 0 Halt and return the number of errors |
| 55148 | ** 1 N S X Set N bits beginning with S and incrementing by X |
| 55149 | ** 2 N S X Clear N bits beginning with S and incrementing by X |
| 55150 | ** 3 N Set N randomly chosen bits |
| 55151 | ** 4 N Clear N randomly chosen bits |
| 55152 | ** 5 N S X Set N bits from S increment X in array only, not in bitvec |
| 55153 | ** 6 Invoice sqlite3ShowBitvec() on the Bitvec object so far |
| 55154 | ** 7 X Show compile-time parameters and the hash of X |
| 55155 | ** |
| 55156 | ** The opcodes 1 through 4 perform set and clear operations are performed |
| 55157 | ** on both a Bitvec object and on a linear array of bits obtained from malloc. |
| 55158 | ** Opcode 5 works on the linear array only, not on the Bitvec. |
| 55159 | ** Opcode 5 is used to deliberately induce a fault in order to |
| 55160 | ** confirm that error detection works. Opcodes 6 and greater are |
| 55161 | ** state output opcodes. Opcodes 6 and greater are no-ops unless |
| 55162 | ** SQLite has been compiled with SQLITE_DEBUG. |
| 55163 | ** |
| 55164 | ** At the conclusion of the test the linear array is compared |
| 55165 | ** against the Bitvec object. If there are any differences, |
| 55166 | ** an error is returned. If they are the same, zero is returned. |
| 55167 | ** |
| 55168 | ** If a memory allocation error occurs, return -1. |
| 55169 | ** |
| 55170 | ** sz is the size of the Bitvec. Or if sz is negative, make the size |
| 55171 | ** 2*(unsigned)(-sz) and disabled the linear vector check. |
| 55172 | */ |
| 55173 | SQLITE_PRIVATE int sqlite3BitvecBuiltinTest(int sz, int *aOp){ |
| 55174 | Bitvec *pBitvec = 0; |
| 55175 | unsigned char *pV = 0; |
| 55176 | int rc = -1; |
| @@ -55109,22 +55177,45 @@ | |
| 55177 | int i, nx, pc, op; |
| 55178 | void *pTmpSpace; |
| 55179 | |
| 55180 | /* Allocate the Bitvec to be tested and a linear array of |
| 55181 | ** bits to act as the reference */ |
| 55182 | if( sz<=0 ){ |
| 55183 | pBitvec = sqlite3BitvecCreate( 2*(unsigned)(-sz) ); |
| 55184 | pV = 0; |
| 55185 | }else{ |
| 55186 | pBitvec = sqlite3BitvecCreate( sz ); |
| 55187 | pV = sqlite3MallocZero( (7+(i64)sz)/8 + 1 ); |
| 55188 | } |
| 55189 | pTmpSpace = sqlite3_malloc64(BITVEC_SZ); |
| 55190 | if( pBitvec==0 || pTmpSpace==0 || (pV==0 && sz>0) ) goto bitvec_end; |
| 55191 | |
| 55192 | /* NULL pBitvec tests */ |
| 55193 | sqlite3BitvecSet(0, 1); |
| 55194 | sqlite3BitvecClear(0, 1, pTmpSpace); |
| 55195 | |
| 55196 | /* Run the program */ |
| 55197 | pc = i = 0; |
| 55198 | while( (op = aOp[pc])!=0 ){ |
| 55199 | if( op>=6 ){ |
| 55200 | #ifdef SQLITE_DEBUG |
| 55201 | if( op==6 ){ |
| 55202 | sqlite3ShowBitvec(pBitvec); |
| 55203 | }else if( op==7 ){ |
| 55204 | printf("BITVEC_SZ = %d (%d by sizeof)\n", |
| 55205 | BITVEC_SZ, (int)sizeof(Bitvec)); |
| 55206 | printf("BITVEC_USIZE = %d\n", (int)BITVEC_USIZE); |
| 55207 | printf("BITVEC_NELEM = %d\n", (int)BITVEC_NELEM); |
| 55208 | printf("BITVEC_NBIT = %d\n", (int)BITVEC_NBIT); |
| 55209 | printf("BITVEC_NINT = %d\n", (int)BITVEC_NINT); |
| 55210 | printf("BITVEC_MXHASH = %d\n", (int)BITVEC_MXHASH); |
| 55211 | printf("BITVEC_NPTR = %d\n", (int)BITVEC_NPTR); |
| 55212 | } |
| 55213 | #endif |
| 55214 | pc++; |
| 55215 | continue; |
| 55216 | } |
| 55217 | switch( op ){ |
| 55218 | case 1: |
| 55219 | case 2: |
| 55220 | case 5: { |
| 55221 | nx = 4; |
| @@ -55142,33 +55233,37 @@ | |
| 55233 | } |
| 55234 | if( (--aOp[pc+1]) > 0 ) nx = 0; |
| 55235 | pc += nx; |
| 55236 | i = (i & 0x7fffffff)%sz; |
| 55237 | if( (op & 1)!=0 ){ |
| 55238 | if( pV ) SETBIT(pV, (i+1)); |
| 55239 | if( op!=5 ){ |
| 55240 | if( sqlite3BitvecSet(pBitvec, i+1) ) goto bitvec_end; |
| 55241 | } |
| 55242 | }else{ |
| 55243 | if( pV ) CLEARBIT(pV, (i+1)); |
| 55244 | sqlite3BitvecClear(pBitvec, i+1, pTmpSpace); |
| 55245 | } |
| 55246 | } |
| 55247 | |
| 55248 | /* Test to make sure the linear array exactly matches the |
| 55249 | ** Bitvec object. Start with the assumption that they do |
| 55250 | ** match (rc==0). Change rc to non-zero if a discrepancy |
| 55251 | ** is found. |
| 55252 | */ |
| 55253 | if( pV ){ |
| 55254 | rc = sqlite3BitvecTest(0,0) + sqlite3BitvecTest(pBitvec, sz+1) |
| 55255 | + sqlite3BitvecTest(pBitvec, 0) |
| 55256 | + (sqlite3BitvecSize(pBitvec) - sz); |
| 55257 | for(i=1; i<=sz; i++){ |
| 55258 | if( (TESTBIT(pV,i))!=sqlite3BitvecTest(pBitvec,i) ){ |
| 55259 | rc = i; |
| 55260 | break; |
| 55261 | } |
| 55262 | } |
| 55263 | }else{ |
| 55264 | rc = 0; |
| 55265 | } |
| 55266 | |
| 55267 | /* Free allocated structure */ |
| 55268 | bitvec_end: |
| 55269 | sqlite3_free(pTmpSpace); |
| @@ -69670,10 +69765,11 @@ | |
| 69765 | rc = xUndo(pUndoCtx, walFramePgno(pWal, iFrame)); |
| 69766 | } |
| 69767 | if( iMax!=pWal->hdr.mxFrame ) walCleanupHash(pWal); |
| 69768 | } |
| 69769 | SEH_EXCEPT( rc = SQLITE_IOERR_IN_PAGE; ) |
| 69770 | pWal->iReCksum = 0; |
| 69771 | } |
| 69772 | return rc; |
| 69773 | } |
| 69774 | |
| 69775 | /* |
| @@ -69717,10 +69813,13 @@ | |
| 69813 | pWal->hdr.aFrameCksum[1] = aWalData[2]; |
| 69814 | SEH_TRY { |
| 69815 | walCleanupHash(pWal); |
| 69816 | } |
| 69817 | SEH_EXCEPT( rc = SQLITE_IOERR_IN_PAGE; ) |
| 69818 | if( pWal->iReCksum>pWal->hdr.mxFrame ){ |
| 69819 | pWal->iReCksum = 0; |
| 69820 | } |
| 69821 | } |
| 69822 | |
| 69823 | return rc; |
| 69824 | } |
| 69825 | |
| @@ -77442,12 +77541,12 @@ | |
| 77541 | assert( (pCur->curFlags & BTCF_ValidOvfl)==0 ); |
| 77542 | return rc; |
| 77543 | } |
| 77544 | |
| 77545 | /* |
| 77546 | ** Compare the "idx"-th cell on the page pPage against the key |
| 77547 | ** pointing to by pIdxKey using xRecordCompare. Return negative or |
| 77548 | ** zero if the cell is less than or equal pIdxKey. Return positive |
| 77549 | ** if unknown. |
| 77550 | ** |
| 77551 | ** Return value negative: Cell at pCur[idx] less than pIdxKey |
| 77552 | ** |
| @@ -77458,16 +77557,15 @@ | |
| 77557 | ** |
| 77558 | ** This routine is part of an optimization. It is always safe to return |
| 77559 | ** a positive value as that will cause the optimization to be skipped. |
| 77560 | */ |
| 77561 | static int indexCellCompare( |
| 77562 | MemPage *pPage, |
| 77563 | int idx, |
| 77564 | UnpackedRecord *pIdxKey, |
| 77565 | RecordCompare xRecordCompare |
| 77566 | ){ |
| 77567 | int c; |
| 77568 | int nCell; /* Size of the pCell cell in bytes */ |
| 77569 | u8 *pCell = findCellPastPtr(pPage, idx); |
| 77570 | |
| 77571 | nCell = pCell[0]; |
| @@ -77572,18 +77670,18 @@ | |
| 77670 | && pCur->pPage->leaf |
| 77671 | && cursorOnLastPage(pCur) |
| 77672 | ){ |
| 77673 | int c; |
| 77674 | if( pCur->ix==pCur->pPage->nCell-1 |
| 77675 | && (c = indexCellCompare(pCur->pPage,pCur->ix,pIdxKey,xRecordCompare))<=0 |
| 77676 | && pIdxKey->errCode==SQLITE_OK |
| 77677 | ){ |
| 77678 | *pRes = c; |
| 77679 | return SQLITE_OK; /* Cursor already pointing at the correct spot */ |
| 77680 | } |
| 77681 | if( pCur->iPage>0 |
| 77682 | && indexCellCompare(pCur->pPage, 0, pIdxKey, xRecordCompare)<=0 |
| 77683 | && pIdxKey->errCode==SQLITE_OK |
| 77684 | ){ |
| 77685 | pCur->curFlags &= ~(BTCF_ValidOvfl|BTCF_AtLast); |
| 77686 | if( !pCur->pPage->isInit ){ |
| 77687 | return SQLITE_CORRUPT_BKPT; |
| @@ -77796,11 +77894,11 @@ | |
| 77894 | if( pCur->eState!=CURSOR_VALID ) return 0; |
| 77895 | if( NEVER(pCur->pPage->leaf==0) ) return -1; |
| 77896 | |
| 77897 | n = pCur->pPage->nCell; |
| 77898 | for(i=0; i<pCur->iPage; i++){ |
| 77899 | n *= pCur->apPage[i]->nCell+1; |
| 77900 | } |
| 77901 | return n; |
| 77902 | } |
| 77903 | |
| 77904 | /* |
| @@ -97581,10 +97679,19 @@ | |
| 97679 | ** Synopsis: typecheck(r[P1@P2]) |
| 97680 | ** |
| 97681 | ** Apply affinities to the range of P2 registers beginning with P1. |
| 97682 | ** Take the affinities from the Table object in P4. If any value |
| 97683 | ** cannot be coerced into the correct type, then raise an error. |
| 97684 | ** |
| 97685 | ** If P3==0, then omit checking of VIRTUAL columns. |
| 97686 | ** |
| 97687 | ** If P3==1, then omit checking of all generated column, both VIRTUAL |
| 97688 | ** and STORED. |
| 97689 | ** |
| 97690 | ** If P3>=2, then only check column number P3-2 in the table (which will |
| 97691 | ** be a VIRTUAL column) against the value in reg[P1]. In this case, |
| 97692 | ** P2 will be 1. |
| 97693 | ** |
| 97694 | ** This opcode is similar to OP_Affinity except that this opcode |
| 97695 | ** forces the register type to the Table column type. This is used |
| 97696 | ** to implement "strict affinity". |
| 97697 | ** |
| @@ -97595,30 +97702,42 @@ | |
| 97702 | ** |
| 97703 | ** Preconditions: |
| 97704 | ** |
| 97705 | ** <ul> |
| 97706 | ** <li> P2 should be the number of non-virtual columns in the |
| 97707 | ** table of P4 unless P3>1, in which case P2 will be 1. |
| 97708 | ** <li> Table P4 is a STRICT table. |
| 97709 | ** </ul> |
| 97710 | ** |
| 97711 | ** If any precondition is false, an assertion fault occurs. |
| 97712 | */ |
| 97713 | case OP_TypeCheck: { |
| 97714 | Table *pTab; |
| 97715 | Column *aCol; |
| 97716 | int i; |
| 97717 | int nCol; |
| 97718 | |
| 97719 | assert( pOp->p4type==P4_TABLE ); |
| 97720 | pTab = pOp->p4.pTab; |
| 97721 | assert( pTab->tabFlags & TF_Strict ); |
| 97722 | assert( pOp->p3>=0 && pOp->p3<pTab->nCol+2 ); |
| 97723 | aCol = pTab->aCol; |
| 97724 | pIn1 = &aMem[pOp->p1]; |
| 97725 | if( pOp->p3<2 ){ |
| 97726 | assert( pTab->nNVCol==pOp->p2 ); |
| 97727 | i = 0; |
| 97728 | nCol = pTab->nCol; |
| 97729 | }else{ |
| 97730 | i = pOp->p3-2; |
| 97731 | nCol = i+1; |
| 97732 | assert( i<pTab->nCol ); |
| 97733 | assert( aCol[i].colFlags & COLFLAG_VIRTUAL ); |
| 97734 | assert( pOp->p2==1 ); |
| 97735 | } |
| 97736 | for(; i<nCol; i++){ |
| 97737 | if( (aCol[i].colFlags & COLFLAG_GENERATED)!=0 && pOp->p3<2 ){ |
| 97738 | if( (aCol[i].colFlags & COLFLAG_VIRTUAL)!=0 ) continue; |
| 97739 | if( pOp->p3 ){ pIn1++; continue; } |
| 97740 | } |
| 97741 | assert( pIn1 < &aMem[pOp->p1+pOp->p2] ); |
| 97742 | applyAffinity(pIn1, aCol[i].affinity, encoding); |
| 97743 | if( (pIn1->flags & MEM_Null)==0 ){ |
| @@ -114626,11 +114745,16 @@ | |
| 114745 | iAddr = sqlite3VdbeAddOp3(v, OP_IfNullRow, pParse->iSelfTab-1, 0, regOut); |
| 114746 | }else{ |
| 114747 | iAddr = 0; |
| 114748 | } |
| 114749 | sqlite3ExprCodeCopy(pParse, sqlite3ColumnExpr(pTab,pCol), regOut); |
| 114750 | if( (pCol->colFlags & COLFLAG_VIRTUAL)!=0 |
| 114751 | && (pTab->tabFlags & TF_Strict)!=0 |
| 114752 | ){ |
| 114753 | int p3 = 2+(int)(pCol - pTab->aCol); |
| 114754 | sqlite3VdbeAddOp4(v, OP_TypeCheck, regOut, 1, p3, (char*)pTab, P4_TABLE); |
| 114755 | }else if( pCol->affinity>=SQLITE_AFF_TEXT ){ |
| 114756 | sqlite3VdbeAddOp4(v, OP_Affinity, regOut, 1, 0, &pCol->affinity, 1); |
| 114757 | } |
| 114758 | if( iAddr ) sqlite3VdbeJumpHere(v, iAddr); |
| 114759 | if( pParse->nErr>nErr ) pParse->db->errByteOffset = -1; |
| 114760 | } |
| @@ -132020,11 +132144,11 @@ | |
| 132144 | int argc, |
| 132145 | sqlite3_value **argv, |
| 132146 | int nSep, |
| 132147 | const char *zSep |
| 132148 | ){ |
| 132149 | i64 j, n = 0; |
| 132150 | int i; |
| 132151 | char *z; |
| 132152 | for(i=0; i<argc; i++){ |
| 132153 | n += sqlite3_value_bytes(argv[i]); |
| 132154 | } |
| @@ -132034,12 +132158,12 @@ | |
| 132158 | sqlite3_result_error_nomem(context); |
| 132159 | return; |
| 132160 | } |
| 132161 | j = 0; |
| 132162 | for(i=0; i<argc; i++){ |
| 132163 | if( sqlite3_value_type(argv[i])!=SQLITE_NULL ){ |
| 132164 | int k = sqlite3_value_bytes(argv[i]); |
| 132165 | const char *v = (const char*)sqlite3_value_text(argv[i]); |
| 132166 | if( v!=0 ){ |
| 132167 | if( j>0 && nSep>0 ){ |
| 132168 | memcpy(&z[j], zSep, nSep); |
| 132169 | j += nSep; |
| @@ -134973,16 +135097,19 @@ | |
| 135097 | if( iReg==0 ){ |
| 135098 | /* Move the previous opcode (which should be OP_MakeRecord) forward |
| 135099 | ** by one slot and insert a new OP_TypeCheck where the current |
| 135100 | ** OP_MakeRecord is found */ |
| 135101 | VdbeOp *pPrev; |
| 135102 | int p3; |
| 135103 | sqlite3VdbeAppendP4(v, pTab, P4_TABLE); |
| 135104 | pPrev = sqlite3VdbeGetLastOp(v); |
| 135105 | assert( pPrev!=0 ); |
| 135106 | assert( pPrev->opcode==OP_MakeRecord || sqlite3VdbeDb(v)->mallocFailed ); |
| 135107 | pPrev->opcode = OP_TypeCheck; |
| 135108 | p3 = pPrev->p3; |
| 135109 | pPrev->p3 = 0; |
| 135110 | sqlite3VdbeAddOp3(v, OP_MakeRecord, pPrev->p1, pPrev->p2, p3); |
| 135111 | }else{ |
| 135112 | /* Insert an isolated OP_Typecheck */ |
| 135113 | sqlite3VdbeAddOp2(v, OP_TypeCheck, iReg, pTab->nNVCol); |
| 135114 | sqlite3VdbeAppendP4(v, pTab, P4_TABLE); |
| 135115 | } |
| @@ -159213,10 +159340,13 @@ | |
| 159340 | u16 eOperator; /* A WO_xx value describing <op> */ |
| 159341 | u8 nChild; /* Number of children that must disable us */ |
| 159342 | u8 eMatchOp; /* Op for vtab MATCH/LIKE/GLOB/REGEXP terms */ |
| 159343 | int iParent; /* Disable pWC->a[iParent] when this term disabled */ |
| 159344 | int leftCursor; /* Cursor number of X in "X <op> <expr>" */ |
| 159345 | #ifdef SQLITE_DEBUG |
| 159346 | int iTerm; /* Which WhereTerm is this, for debug purposes */ |
| 159347 | #endif |
| 159348 | union { |
| 159349 | struct { |
| 159350 | int leftColumn; /* Column number of X in "X <op> <expr>" */ |
| 159351 | int iField; /* Field in (?,?,?) IN (SELECT...) vector */ |
| 159352 | } x; /* Opcode other than OP_OR or OP_AND */ |
| @@ -161410,40 +161540,40 @@ | |
| 161540 | VdbeCoverageIf(v, testOp==OP_Ge); |
| 161541 | VdbeCoverageIf(v, testOp==OP_Gt); |
| 161542 | sqlite3VdbeChangeP5(v, SQLITE_AFF_NUMERIC | SQLITE_JUMPIFNULL); |
| 161543 | } |
| 161544 | }else if( pLoop->wsFlags & WHERE_INDEXED ){ |
| 161545 | /* Case 4: Search using an index. |
| 161546 | ** |
| 161547 | ** The WHERE clause may contain zero or more equality |
| 161548 | ** terms ("==" or "IN" or "IS" operators) that refer to the N |
| 161549 | ** left-most columns of the index. It may also contain |
| 161550 | ** inequality constraints (>, <, >= or <=) on the indexed |
| 161551 | ** column that immediately follows the N equalities. Only |
| 161552 | ** the right-most column can be an inequality - the rest must |
| 161553 | ** use the "==", "IN", or "IS" operators. For example, if the |
| 161554 | ** index is on (x,y,z), then the following clauses are all |
| 161555 | ** optimized: |
| 161556 | ** |
| 161557 | ** x=5 |
| 161558 | ** x=5 AND y=10 |
| 161559 | ** x=5 AND y<10 |
| 161560 | ** x=5 AND y>5 AND y<10 |
| 161561 | ** x=5 AND y=5 AND z<=10 |
| 161562 | ** |
| 161563 | ** The z<10 term of the following cannot be used, only |
| 161564 | ** the x=5 term: |
| 161565 | ** |
| 161566 | ** x=5 AND z<10 |
| 161567 | ** |
| 161568 | ** N may be zero if there are inequality constraints. |
| 161569 | ** If there are no inequality constraints, then N is at |
| 161570 | ** least one. |
| 161571 | ** |
| 161572 | ** This case is also used when there are no WHERE clause |
| 161573 | ** constraints but an index is selected anyway, in order |
| 161574 | ** to force the output order to conform to an ORDER BY. |
| 161575 | */ |
| 161576 | static const u8 aStartOp[] = { |
| 161577 | 0, |
| 161578 | 0, |
| 161579 | OP_Rewind, /* 2: (!start_constraints && startEq && !bRev) */ |
| @@ -163459,34 +163589,46 @@ | |
| 163589 | ** column references. This routine checks to see if pExpr is an equivalence |
| 163590 | ** relation: |
| 163591 | ** 1. The SQLITE_Transitive optimization must be enabled |
| 163592 | ** 2. Must be either an == or an IS operator |
| 163593 | ** 3. Not originating in the ON clause of an OUTER JOIN |
| 163594 | ** 4. The operator is not IS or else the query does not contain RIGHT JOIN |
| 163595 | ** 5. The affinities of A and B must be compatible |
| 163596 | ** 6a. Both operands use the same collating sequence OR |
| 163597 | ** 6b. The overall collating sequence is BINARY |
| 163598 | ** If this routine returns TRUE, that means that the RHS can be substituted |
| 163599 | ** for the LHS anyplace else in the WHERE clause where the LHS column occurs. |
| 163600 | ** This is an optimization. No harm comes from returning 0. But if 1 is |
| 163601 | ** returned when it should not be, then incorrect answers might result. |
| 163602 | */ |
| 163603 | static int termIsEquivalence(Parse *pParse, Expr *pExpr, SrcList *pSrc){ |
| 163604 | char aff1, aff2; |
| 163605 | CollSeq *pColl; |
| 163606 | if( !OptimizationEnabled(pParse->db, SQLITE_Transitive) ) return 0; /* (1) */ |
| 163607 | if( pExpr->op!=TK_EQ && pExpr->op!=TK_IS ) return 0; /* (2) */ |
| 163608 | if( ExprHasProperty(pExpr, EP_OuterON) ) return 0; /* (3) */ |
| 163609 | assert( pSrc!=0 ); |
| 163610 | if( pExpr->op==TK_IS |
| 163611 | && pSrc->nSrc |
| 163612 | && (pSrc->a[0].fg.jointype & JT_LTORJ)!=0 |
| 163613 | ){ |
| 163614 | return 0; /* (4) */ |
| 163615 | } |
| 163616 | aff1 = sqlite3ExprAffinity(pExpr->pLeft); |
| 163617 | aff2 = sqlite3ExprAffinity(pExpr->pRight); |
| 163618 | if( aff1!=aff2 |
| 163619 | && (!sqlite3IsNumericAffinity(aff1) || !sqlite3IsNumericAffinity(aff2)) |
| 163620 | ){ |
| 163621 | return 0; /* (5) */ |
| 163622 | } |
| 163623 | pColl = sqlite3ExprCompareCollSeq(pParse, pExpr); |
| 163624 | if( !sqlite3IsBinary(pColl) |
| 163625 | && !sqlite3ExprCollSeqMatch(pParse, pExpr->pLeft, pExpr->pRight) |
| 163626 | ){ |
| 163627 | return 0; /* (6) */ |
| 163628 | } |
| 163629 | return 1; |
| 163630 | } |
| 163631 | |
| 163632 | /* |
| 163633 | ** Recursively walk the expressions of a SELECT statement and generate |
| 163634 | ** a bitmask indicating which tables are used in that expression |
| @@ -163640,10 +163782,13 @@ | |
| 163782 | if( db->mallocFailed ){ |
| 163783 | return; |
| 163784 | } |
| 163785 | assert( pWC->nTerm > idxTerm ); |
| 163786 | pTerm = &pWC->a[idxTerm]; |
| 163787 | #ifdef SQLITE_DEBUG |
| 163788 | pTerm->iTerm = idxTerm; |
| 163789 | #endif |
| 163790 | pMaskSet = &pWInfo->sMaskSet; |
| 163791 | pExpr = pTerm->pExpr; |
| 163792 | assert( pExpr!=0 ); /* Because malloc() has not failed */ |
| 163793 | assert( pExpr->op!=TK_AS && pExpr->op!=TK_COLLATE ); |
| 163794 | pMaskSet->bVarSelect = 0; |
| @@ -163747,12 +163892,12 @@ | |
| 163892 | pNew = &pWC->a[idxNew]; |
| 163893 | markTermAsChild(pWC, idxNew, idxTerm); |
| 163894 | if( op==TK_IS ) pNew->wtFlags |= TERM_IS; |
| 163895 | pTerm = &pWC->a[idxTerm]; |
| 163896 | pTerm->wtFlags |= TERM_COPIED; |
| 163897 | assert( pWInfo->pTabList!=0 ); |
| 163898 | if( termIsEquivalence(pParse, pDup, pWInfo->pTabList) ){ |
| 163899 | pTerm->eOperator |= WO_EQUIV; |
| 163900 | eExtraOp = WO_EQUIV; |
| 163901 | } |
| 163902 | }else{ |
| 163903 | pDup = pExpr; |
| @@ -164867,15 +165012,15 @@ | |
| 165012 | continue; |
| 165013 | } |
| 165014 | pScan->pWC = pWC; |
| 165015 | pScan->k = k+1; |
| 165016 | #ifdef WHERETRACE_ENABLED |
| 165017 | if( (sqlite3WhereTrace & 0x20000)!=0 && pScan->nEquiv>1 ){ |
| 165018 | int ii; |
| 165019 | sqlite3DebugPrintf("EQUIVALENT TO {%d:%d} (due to TERM-%d):", |
| 165020 | pScan->aiCur[0], pScan->aiColumn[0], pTerm->iTerm); |
| 165021 | for(ii=1; ii<pScan->nEquiv; ii++){ |
| 165022 | sqlite3DebugPrintf(" {%d:%d}", |
| 165023 | pScan->aiCur[ii], pScan->aiColumn[ii]); |
| 165024 | } |
| 165025 | sqlite3DebugPrintf("\n"); |
| 165026 | } |
| @@ -166826,10 +166971,11 @@ | |
| 166971 | sqlite3_snprintf(sizeof(zLeft),zLeft,"indexable=0x%llx", |
| 166972 | pTerm->u.pOrInfo->indexable); |
| 166973 | }else{ |
| 166974 | sqlite3_snprintf(sizeof(zLeft),zLeft,"left=%d", pTerm->leftCursor); |
| 166975 | } |
| 166976 | iTerm = pTerm->iTerm = MAX(iTerm,pTerm->iTerm); |
| 166977 | sqlite3DebugPrintf( |
| 166978 | "TERM-%-3d %p %s %-12s op=%03x wtFlags=%04x", |
| 166979 | iTerm, pTerm, zType, zLeft, pTerm->eOperator, pTerm->wtFlags); |
| 166980 | /* The 0x10000 .wheretrace flag causes extra information to be |
| 166981 | ** shown about each Term */ |
| @@ -184450,10 +184596,11 @@ | |
| 184596 | #ifdef SQLITE_ENABLE_API_ARMOR |
| 184597 | if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; |
| 184598 | #endif |
| 184599 | if( ms<-1 ) return SQLITE_RANGE; |
| 184600 | #ifdef SQLITE_ENABLE_SETLK_TIMEOUT |
| 184601 | sqlite3_mutex_enter(db->mutex); |
| 184602 | db->setlkTimeout = ms; |
| 184603 | db->setlkFlags = flags; |
| 184604 | sqlite3BtreeEnterAll(db); |
| 184605 | for(iDb=0; iDb<db->nDb; iDb++){ |
| 184606 | Btree *pBt = db->aDb[iDb].pBt; |
| @@ -184461,10 +184608,11 @@ | |
| 184608 | sqlite3_file *fd = sqlite3PagerFile(sqlite3BtreePager(pBt)); |
| 184609 | sqlite3OsFileControlHint(fd, SQLITE_FCNTL_BLOCK_ON_CONNECT, (void*)&bBOC); |
| 184610 | } |
| 184611 | } |
| 184612 | sqlite3BtreeLeaveAll(db); |
| 184613 | sqlite3_mutex_leave(db->mutex); |
| 184614 | #endif |
| 184615 | #if !defined(SQLITE_ENABLE_API_ARMOR) && !defined(SQLITE_ENABLE_SETLK_TIMEOUT) |
| 184616 | UNUSED_PARAMETER(db); |
| 184617 | UNUSED_PARAMETER(flags); |
| 184618 | #endif |
| @@ -257257,11 +257405,11 @@ | |
| 257405 | int nArg, /* Number of args */ |
| 257406 | sqlite3_value **apUnused /* Function arguments */ |
| 257407 | ){ |
| 257408 | assert( nArg==0 ); |
| 257409 | UNUSED_PARAM2(nArg, apUnused); |
| 257410 | sqlite3_result_text(pCtx, "fts5: 2025-06-19 20:19:12 a88bb75288a06492a04ab1278e8a2101a74f4ba712d328b4c73e86ac01cb946d", -1, SQLITE_TRANSIENT); |
| 257411 | } |
| 257412 | |
| 257413 | /* |
| 257414 | ** Implementation of fts5_locale(LOCALE, TEXT) function. |
| 257415 | ** |
| @@ -258072,10 +258220,11 @@ | |
| 258220 | ctx.pStorage = p; |
| 258221 | ctx.iCol = -1; |
| 258222 | for(iCol=1; rc==SQLITE_OK && iCol<=pConfig->nCol; iCol++){ |
| 258223 | if( pConfig->abUnindexed[iCol-1]==0 ){ |
| 258224 | sqlite3_value *pVal = 0; |
| 258225 | sqlite3_value *pFree = 0; |
| 258226 | const char *pText = 0; |
| 258227 | int nText = 0; |
| 258228 | const char *pLoc = 0; |
| 258229 | int nLoc = 0; |
| 258230 | |
| @@ -258088,15 +258237,26 @@ | |
| 258237 | } |
| 258238 | |
| 258239 | if( pConfig->bLocale && sqlite3Fts5IsLocaleValue(pConfig, pVal) ){ |
| 258240 | rc = sqlite3Fts5DecodeLocaleValue(pVal, &pText, &nText, &pLoc, &nLoc); |
| 258241 | }else{ |
| 258242 | if( sqlite3_value_type(pVal)!=SQLITE_TEXT ){ |
| 258243 | /* Make a copy of the value to work with. This is because the call |
| 258244 | ** to sqlite3_value_text() below forces the type of the value to |
| 258245 | ** SQLITE_TEXT, and we may need to use it again later. */ |
| 258246 | pFree = pVal = sqlite3_value_dup(pVal); |
| 258247 | if( pVal==0 ){ |
| 258248 | rc = SQLITE_NOMEM; |
| 258249 | } |
| 258250 | } |
| 258251 | if( rc==SQLITE_OK ){ |
| 258252 | pText = (const char*)sqlite3_value_text(pVal); |
| 258253 | nText = sqlite3_value_bytes(pVal); |
| 258254 | if( pConfig->bLocale && pSeek ){ |
| 258255 | pLoc = (const char*)sqlite3_column_text(pSeek, iCol+pConfig->nCol); |
| 258256 | nLoc = sqlite3_column_bytes(pSeek, iCol + pConfig->nCol); |
| 258257 | } |
| 258258 | } |
| 258259 | } |
| 258260 | |
| 258261 | if( rc==SQLITE_OK ){ |
| 258262 | sqlite3Fts5SetLocale(pConfig, pLoc, nLoc); |
| @@ -258108,10 +258268,11 @@ | |
| 258268 | if( rc==SQLITE_OK && p->aTotalSize[iCol-1]<0 ){ |
| 258269 | rc = FTS5_CORRUPT; |
| 258270 | } |
| 258271 | sqlite3Fts5ClearLocale(pConfig); |
| 258272 | } |
| 258273 | sqlite3_value_free(pFree); |
| 258274 | } |
| 258275 | } |
| 258276 | if( rc==SQLITE_OK && p->nTotalRow<1 ){ |
| 258277 | rc = FTS5_CORRUPT; |
| 258278 | }else{ |
| 258279 |
+16
-16
| --- extsrc/sqlite3.h | ||
| +++ extsrc/sqlite3.h | ||
| @@ -146,11 +146,11 @@ | ||
| 146 | 146 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 147 | 147 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 148 | 148 | */ |
| 149 | 149 | #define SQLITE_VERSION "3.51.0" |
| 150 | 150 | #define SQLITE_VERSION_NUMBER 3051000 |
| 151 | -#define SQLITE_SOURCE_ID "2025-06-03 10:49:51 ea1754f7d8a770477a1b19b606b27724fdc0b733e51fef32c1ef834f972c3cc5" | |
| 151 | +#define SQLITE_SOURCE_ID "2025-06-19 20:19:12 a88bb75288a06492a04ab1278e8a2101a74f4ba712d328b4c73e86ac01cb946d" | |
| 152 | 152 | |
| 153 | 153 | /* |
| 154 | 154 | ** CAPI3REF: Run-Time Library Version Numbers |
| 155 | 155 | ** KEYWORDS: sqlite3_version sqlite3_sourceid |
| 156 | 156 | ** |
| @@ -4077,11 +4077,11 @@ | ||
| 4077 | 4077 | ** These interfaces are provided for use by [VFS shim] implementations and |
| 4078 | 4078 | ** are not useful outside of that context. |
| 4079 | 4079 | ** |
| 4080 | 4080 | ** The sqlite3_create_filename(D,J,W,N,P) allocates memory to hold a version of |
| 4081 | 4081 | ** database filename D with corresponding journal file J and WAL file W and |
| 4082 | -** with N URI parameters key/values pairs in the array P. The result from | |
| 4082 | +** an array P of N URI Key/Value pairs. The result from | |
| 4083 | 4083 | ** sqlite3_create_filename(D,J,W,N,P) is a pointer to a database filename that |
| 4084 | 4084 | ** is safe to pass to routines like: |
| 4085 | 4085 | ** <ul> |
| 4086 | 4086 | ** <li> [sqlite3_uri_parameter()], |
| 4087 | 4087 | ** <li> [sqlite3_uri_boolean()], |
| @@ -4758,11 +4758,11 @@ | ||
| 4758 | 4758 | ** KEYWORDS: {host parameter} {host parameters} {host parameter name} |
| 4759 | 4759 | ** KEYWORDS: {SQL parameter} {SQL parameters} {parameter binding} |
| 4760 | 4760 | ** METHOD: sqlite3_stmt |
| 4761 | 4761 | ** |
| 4762 | 4762 | ** ^(In the SQL statement text input to [sqlite3_prepare_v2()] and its variants, |
| 4763 | -** literals may be replaced by a [parameter] that matches one of following | |
| 4763 | +** literals may be replaced by a [parameter] that matches one of the following | |
| 4764 | 4764 | ** templates: |
| 4765 | 4765 | ** |
| 4766 | 4766 | ** <ul> |
| 4767 | 4767 | ** <li> ? |
| 4768 | 4768 | ** <li> ?NNN |
| @@ -4803,11 +4803,11 @@ | ||
| 4803 | 4803 | ** either UTF8 if the sixth parameter is SQLITE_UTF8, or UTF16 |
| 4804 | 4804 | ** otherwise. |
| 4805 | 4805 | ** |
| 4806 | 4806 | ** [[byte-order determination rules]] ^The byte-order of |
| 4807 | 4807 | ** UTF16 input text is determined by the byte-order mark (BOM, U+FEFF) |
| 4808 | -** found in first character, which is removed, or in the absence of a BOM | |
| 4808 | +** found in the first character, which is removed, or in the absence of a BOM | |
| 4809 | 4809 | ** the byte order is the native byte order of the host |
| 4810 | 4810 | ** machine for sqlite3_bind_text16() or the byte order specified in |
| 4811 | 4811 | ** the 6th parameter for sqlite3_bind_text64().)^ |
| 4812 | 4812 | ** ^If UTF16 input text contains invalid unicode |
| 4813 | 4813 | ** characters, then SQLite might change those invalid characters |
| @@ -4823,11 +4823,11 @@ | ||
| 4823 | 4823 | ** the behavior is undefined. |
| 4824 | 4824 | ** If a non-negative fourth parameter is provided to sqlite3_bind_text() |
| 4825 | 4825 | ** or sqlite3_bind_text16() or sqlite3_bind_text64() then |
| 4826 | 4826 | ** that parameter must be the byte offset |
| 4827 | 4827 | ** where the NUL terminator would occur assuming the string were NUL |
| 4828 | -** terminated. If any NUL characters occurs at byte offsets less than | |
| 4828 | +** terminated. If any NUL characters occur at byte offsets less than | |
| 4829 | 4829 | ** the value of the fourth parameter then the resulting string value will |
| 4830 | 4830 | ** contain embedded NULs. The result of expressions involving strings |
| 4831 | 4831 | ** with embedded NULs is undefined. |
| 4832 | 4832 | ** |
| 4833 | 4833 | ** ^The fifth argument to the BLOB and string binding interfaces controls |
| @@ -5035,11 +5035,11 @@ | ||
| 5035 | 5035 | /* |
| 5036 | 5036 | ** CAPI3REF: Source Of Data In A Query Result |
| 5037 | 5037 | ** METHOD: sqlite3_stmt |
| 5038 | 5038 | ** |
| 5039 | 5039 | ** ^These routines provide a means to determine the database, table, and |
| 5040 | -** table column that is the origin of a particular result column in | |
| 5040 | +** table column that is the origin of a particular result column in a | |
| 5041 | 5041 | ** [SELECT] statement. |
| 5042 | 5042 | ** ^The name of the database or table or column can be returned as |
| 5043 | 5043 | ** either a UTF-8 or UTF-16 string. ^The _database_ routines return |
| 5044 | 5044 | ** the database name, the _table_ routines return the table name, and |
| 5045 | 5045 | ** the origin_ routines return the column name. |
| @@ -5604,12 +5604,12 @@ | ||
| 5604 | 5604 | ** within VIEWs, TRIGGERs, CHECK constraints, generated column expressions, |
| 5605 | 5605 | ** index expressions, or the WHERE clause of partial indexes. |
| 5606 | 5606 | ** |
| 5607 | 5607 | ** For best security, the [SQLITE_DIRECTONLY] flag is recommended for |
| 5608 | 5608 | ** all application-defined SQL functions that do not need to be |
| 5609 | -** used inside of triggers, view, CHECK constraints, or other elements of | |
| 5610 | -** the database schema. This flags is especially recommended for SQL | |
| 5609 | +** used inside of triggers, views, CHECK constraints, or other elements of | |
| 5610 | +** the database schema. This flag is especially recommended for SQL | |
| 5611 | 5611 | ** functions that have side effects or reveal internal application state. |
| 5612 | 5612 | ** Without this flag, an attacker might be able to modify the schema of |
| 5613 | 5613 | ** a database file to include invocations of the function with parameters |
| 5614 | 5614 | ** chosen by the attacker, which the application will then execute when |
| 5615 | 5615 | ** the database file is opened and read. |
| @@ -5636,11 +5636,11 @@ | ||
| 5636 | 5636 | ** or aggregate window function. More details regarding the implementation |
| 5637 | 5637 | ** of aggregate window functions are |
| 5638 | 5638 | ** [user-defined window functions|available here]. |
| 5639 | 5639 | ** |
| 5640 | 5640 | ** ^(If the final parameter to sqlite3_create_function_v2() or |
| 5641 | -** sqlite3_create_window_function() is not NULL, then it is destructor for | |
| 5641 | +** sqlite3_create_window_function() is not NULL, then it is the destructor for | |
| 5642 | 5642 | ** the application data pointer. The destructor is invoked when the function |
| 5643 | 5643 | ** is deleted, either by being overloaded or when the database connection |
| 5644 | 5644 | ** closes.)^ ^The destructor is also invoked if the call to |
| 5645 | 5645 | ** sqlite3_create_function_v2() fails. ^When the destructor callback is |
| 5646 | 5646 | ** invoked, it is passed a single argument which is a copy of the application |
| @@ -7444,11 +7444,11 @@ | ||
| 7444 | 7444 | ** that is to be automatically loaded into all new database connections. |
| 7445 | 7445 | ** |
| 7446 | 7446 | ** ^(Even though the function prototype shows that xEntryPoint() takes |
| 7447 | 7447 | ** no arguments and returns void, SQLite invokes xEntryPoint() with three |
| 7448 | 7448 | ** arguments and expects an integer result as if the signature of the |
| 7449 | -** entry point where as follows: | |
| 7449 | +** entry point were as follows: | |
| 7450 | 7450 | ** |
| 7451 | 7451 | ** <blockquote><pre> |
| 7452 | 7452 | ** int xEntryPoint( |
| 7453 | 7453 | ** sqlite3 *db, |
| 7454 | 7454 | ** const char **pzErrMsg, |
| @@ -7775,11 +7775,11 @@ | ||
| 7775 | 7775 | ** by the first parameter. ^The name of the module is given by the |
| 7776 | 7776 | ** second parameter. ^The third parameter is a pointer to |
| 7777 | 7777 | ** the implementation of the [virtual table module]. ^The fourth |
| 7778 | 7778 | ** parameter is an arbitrary client data pointer that is passed through |
| 7779 | 7779 | ** into the [xCreate] and [xConnect] methods of the virtual table module |
| 7780 | -** when a new virtual table is be being created or reinitialized. | |
| 7780 | +** when a new virtual table is being created or reinitialized. | |
| 7781 | 7781 | ** |
| 7782 | 7782 | ** ^The sqlite3_create_module_v2() interface has a fifth parameter which |
| 7783 | 7783 | ** is a pointer to a destructor for the pClientData. ^SQLite will |
| 7784 | 7784 | ** invoke the destructor function (if it is not NULL) when SQLite |
| 7785 | 7785 | ** no longer needs the pClientData pointer. ^The destructor will also |
| @@ -7940,11 +7940,11 @@ | ||
| 7940 | 7940 | ** |
| 7941 | 7941 | ** ^(On success, [SQLITE_OK] is returned and the new [BLOB handle] is stored |
| 7942 | 7942 | ** in *ppBlob. Otherwise an [error code] is returned and, unless the error |
| 7943 | 7943 | ** code is SQLITE_MISUSE, *ppBlob is set to NULL.)^ ^This means that, provided |
| 7944 | 7944 | ** the API is not misused, it is always safe to call [sqlite3_blob_close()] |
| 7945 | -** on *ppBlob after this function it returns. | |
| 7945 | +** on *ppBlob after this function returns. | |
| 7946 | 7946 | ** |
| 7947 | 7947 | ** This function fails with SQLITE_ERROR if any of the following are true: |
| 7948 | 7948 | ** <ul> |
| 7949 | 7949 | ** <li> ^(Database zDb does not exist)^, |
| 7950 | 7950 | ** <li> ^(Table zTable does not exist within database zDb)^, |
| @@ -8060,11 +8060,11 @@ | ||
| 8060 | 8060 | ** CAPI3REF: Return The Size Of An Open BLOB |
| 8061 | 8061 | ** METHOD: sqlite3_blob |
| 8062 | 8062 | ** |
| 8063 | 8063 | ** ^Returns the size in bytes of the BLOB accessible via the |
| 8064 | 8064 | ** successfully opened [BLOB handle] in its only argument. ^The |
| 8065 | -** incremental blob I/O routines can only read or overwriting existing | |
| 8065 | +** incremental blob I/O routines can only read or overwrite existing | |
| 8066 | 8066 | ** blob content; they cannot change the size of a blob. |
| 8067 | 8067 | ** |
| 8068 | 8068 | ** This routine only works on a [BLOB handle] which has been created |
| 8069 | 8069 | ** by a prior successful call to [sqlite3_blob_open()] and which has not |
| 8070 | 8070 | ** been closed by [sqlite3_blob_close()]. Passing any other pointer in |
| @@ -9463,11 +9463,11 @@ | ||
| 9463 | 9463 | ** sqlite3_backup_step(), the source database may be modified mid-way |
| 9464 | 9464 | ** through the backup process. ^If the source database is modified by an |
| 9465 | 9465 | ** external process or via a database connection other than the one being |
| 9466 | 9466 | ** used by the backup operation, then the backup will be automatically |
| 9467 | 9467 | ** restarted by the next call to sqlite3_backup_step(). ^If the source |
| 9468 | -** database is modified by the using the same database connection as is used | |
| 9468 | +** database is modified by using the same database connection as is used | |
| 9469 | 9469 | ** by the backup operation, then the backup database is automatically |
| 9470 | 9470 | ** updated at the same time. |
| 9471 | 9471 | ** |
| 9472 | 9472 | ** [[sqlite3_backup_finish()]] <b>sqlite3_backup_finish()</b> |
| 9473 | 9473 | ** |
| @@ -9480,11 +9480,11 @@ | ||
| 9480 | 9480 | ** active write-transaction on the destination database is rolled back. |
| 9481 | 9481 | ** The [sqlite3_backup] object is invalid |
| 9482 | 9482 | ** and may not be used following a call to sqlite3_backup_finish(). |
| 9483 | 9483 | ** |
| 9484 | 9484 | ** ^The value returned by sqlite3_backup_finish is [SQLITE_OK] if no |
| 9485 | -** sqlite3_backup_step() errors occurred, regardless or whether or not | |
| 9485 | +** sqlite3_backup_step() errors occurred, regardless of whether or not | |
| 9486 | 9486 | ** sqlite3_backup_step() completed. |
| 9487 | 9487 | ** ^If an out-of-memory condition or IO error occurred during any prior |
| 9488 | 9488 | ** sqlite3_backup_step() call on the same [sqlite3_backup] object, then |
| 9489 | 9489 | ** sqlite3_backup_finish() returns the corresponding [error code]. |
| 9490 | 9490 | ** |
| @@ -10550,11 +10550,11 @@ | ||
| 10550 | 10550 | /* |
| 10551 | 10551 | ** CAPI3REF: Flush caches to disk mid-transaction |
| 10552 | 10552 | ** METHOD: sqlite3 |
| 10553 | 10553 | ** |
| 10554 | 10554 | ** ^If a write-transaction is open on [database connection] D when the |
| 10555 | -** [sqlite3_db_cacheflush(D)] interface invoked, any dirty | |
| 10555 | +** [sqlite3_db_cacheflush(D)] interface is invoked, any dirty | |
| 10556 | 10556 | ** pages in the pager-cache that are not currently in use are written out |
| 10557 | 10557 | ** to disk. A dirty page may be in use if a database cursor created by an |
| 10558 | 10558 | ** active SQL statement is reading from it, or if it is page 1 of a database |
| 10559 | 10559 | ** file (page 1 is always "in use"). ^The [sqlite3_db_cacheflush(D)] |
| 10560 | 10560 | ** interface flushes caches for all schemas - "main", "temp", and |
| 10561 | 10561 |
| --- extsrc/sqlite3.h | |
| +++ extsrc/sqlite3.h | |
| @@ -146,11 +146,11 @@ | |
| 146 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 147 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 148 | */ |
| 149 | #define SQLITE_VERSION "3.51.0" |
| 150 | #define SQLITE_VERSION_NUMBER 3051000 |
| 151 | #define SQLITE_SOURCE_ID "2025-06-03 10:49:51 ea1754f7d8a770477a1b19b606b27724fdc0b733e51fef32c1ef834f972c3cc5" |
| 152 | |
| 153 | /* |
| 154 | ** CAPI3REF: Run-Time Library Version Numbers |
| 155 | ** KEYWORDS: sqlite3_version sqlite3_sourceid |
| 156 | ** |
| @@ -4077,11 +4077,11 @@ | |
| 4077 | ** These interfaces are provided for use by [VFS shim] implementations and |
| 4078 | ** are not useful outside of that context. |
| 4079 | ** |
| 4080 | ** The sqlite3_create_filename(D,J,W,N,P) allocates memory to hold a version of |
| 4081 | ** database filename D with corresponding journal file J and WAL file W and |
| 4082 | ** with N URI parameters key/values pairs in the array P. The result from |
| 4083 | ** sqlite3_create_filename(D,J,W,N,P) is a pointer to a database filename that |
| 4084 | ** is safe to pass to routines like: |
| 4085 | ** <ul> |
| 4086 | ** <li> [sqlite3_uri_parameter()], |
| 4087 | ** <li> [sqlite3_uri_boolean()], |
| @@ -4758,11 +4758,11 @@ | |
| 4758 | ** KEYWORDS: {host parameter} {host parameters} {host parameter name} |
| 4759 | ** KEYWORDS: {SQL parameter} {SQL parameters} {parameter binding} |
| 4760 | ** METHOD: sqlite3_stmt |
| 4761 | ** |
| 4762 | ** ^(In the SQL statement text input to [sqlite3_prepare_v2()] and its variants, |
| 4763 | ** literals may be replaced by a [parameter] that matches one of following |
| 4764 | ** templates: |
| 4765 | ** |
| 4766 | ** <ul> |
| 4767 | ** <li> ? |
| 4768 | ** <li> ?NNN |
| @@ -4803,11 +4803,11 @@ | |
| 4803 | ** either UTF8 if the sixth parameter is SQLITE_UTF8, or UTF16 |
| 4804 | ** otherwise. |
| 4805 | ** |
| 4806 | ** [[byte-order determination rules]] ^The byte-order of |
| 4807 | ** UTF16 input text is determined by the byte-order mark (BOM, U+FEFF) |
| 4808 | ** found in first character, which is removed, or in the absence of a BOM |
| 4809 | ** the byte order is the native byte order of the host |
| 4810 | ** machine for sqlite3_bind_text16() or the byte order specified in |
| 4811 | ** the 6th parameter for sqlite3_bind_text64().)^ |
| 4812 | ** ^If UTF16 input text contains invalid unicode |
| 4813 | ** characters, then SQLite might change those invalid characters |
| @@ -4823,11 +4823,11 @@ | |
| 4823 | ** the behavior is undefined. |
| 4824 | ** If a non-negative fourth parameter is provided to sqlite3_bind_text() |
| 4825 | ** or sqlite3_bind_text16() or sqlite3_bind_text64() then |
| 4826 | ** that parameter must be the byte offset |
| 4827 | ** where the NUL terminator would occur assuming the string were NUL |
| 4828 | ** terminated. If any NUL characters occurs at byte offsets less than |
| 4829 | ** the value of the fourth parameter then the resulting string value will |
| 4830 | ** contain embedded NULs. The result of expressions involving strings |
| 4831 | ** with embedded NULs is undefined. |
| 4832 | ** |
| 4833 | ** ^The fifth argument to the BLOB and string binding interfaces controls |
| @@ -5035,11 +5035,11 @@ | |
| 5035 | /* |
| 5036 | ** CAPI3REF: Source Of Data In A Query Result |
| 5037 | ** METHOD: sqlite3_stmt |
| 5038 | ** |
| 5039 | ** ^These routines provide a means to determine the database, table, and |
| 5040 | ** table column that is the origin of a particular result column in |
| 5041 | ** [SELECT] statement. |
| 5042 | ** ^The name of the database or table or column can be returned as |
| 5043 | ** either a UTF-8 or UTF-16 string. ^The _database_ routines return |
| 5044 | ** the database name, the _table_ routines return the table name, and |
| 5045 | ** the origin_ routines return the column name. |
| @@ -5604,12 +5604,12 @@ | |
| 5604 | ** within VIEWs, TRIGGERs, CHECK constraints, generated column expressions, |
| 5605 | ** index expressions, or the WHERE clause of partial indexes. |
| 5606 | ** |
| 5607 | ** For best security, the [SQLITE_DIRECTONLY] flag is recommended for |
| 5608 | ** all application-defined SQL functions that do not need to be |
| 5609 | ** used inside of triggers, view, CHECK constraints, or other elements of |
| 5610 | ** the database schema. This flags is especially recommended for SQL |
| 5611 | ** functions that have side effects or reveal internal application state. |
| 5612 | ** Without this flag, an attacker might be able to modify the schema of |
| 5613 | ** a database file to include invocations of the function with parameters |
| 5614 | ** chosen by the attacker, which the application will then execute when |
| 5615 | ** the database file is opened and read. |
| @@ -5636,11 +5636,11 @@ | |
| 5636 | ** or aggregate window function. More details regarding the implementation |
| 5637 | ** of aggregate window functions are |
| 5638 | ** [user-defined window functions|available here]. |
| 5639 | ** |
| 5640 | ** ^(If the final parameter to sqlite3_create_function_v2() or |
| 5641 | ** sqlite3_create_window_function() is not NULL, then it is destructor for |
| 5642 | ** the application data pointer. The destructor is invoked when the function |
| 5643 | ** is deleted, either by being overloaded or when the database connection |
| 5644 | ** closes.)^ ^The destructor is also invoked if the call to |
| 5645 | ** sqlite3_create_function_v2() fails. ^When the destructor callback is |
| 5646 | ** invoked, it is passed a single argument which is a copy of the application |
| @@ -7444,11 +7444,11 @@ | |
| 7444 | ** that is to be automatically loaded into all new database connections. |
| 7445 | ** |
| 7446 | ** ^(Even though the function prototype shows that xEntryPoint() takes |
| 7447 | ** no arguments and returns void, SQLite invokes xEntryPoint() with three |
| 7448 | ** arguments and expects an integer result as if the signature of the |
| 7449 | ** entry point where as follows: |
| 7450 | ** |
| 7451 | ** <blockquote><pre> |
| 7452 | ** int xEntryPoint( |
| 7453 | ** sqlite3 *db, |
| 7454 | ** const char **pzErrMsg, |
| @@ -7775,11 +7775,11 @@ | |
| 7775 | ** by the first parameter. ^The name of the module is given by the |
| 7776 | ** second parameter. ^The third parameter is a pointer to |
| 7777 | ** the implementation of the [virtual table module]. ^The fourth |
| 7778 | ** parameter is an arbitrary client data pointer that is passed through |
| 7779 | ** into the [xCreate] and [xConnect] methods of the virtual table module |
| 7780 | ** when a new virtual table is be being created or reinitialized. |
| 7781 | ** |
| 7782 | ** ^The sqlite3_create_module_v2() interface has a fifth parameter which |
| 7783 | ** is a pointer to a destructor for the pClientData. ^SQLite will |
| 7784 | ** invoke the destructor function (if it is not NULL) when SQLite |
| 7785 | ** no longer needs the pClientData pointer. ^The destructor will also |
| @@ -7940,11 +7940,11 @@ | |
| 7940 | ** |
| 7941 | ** ^(On success, [SQLITE_OK] is returned and the new [BLOB handle] is stored |
| 7942 | ** in *ppBlob. Otherwise an [error code] is returned and, unless the error |
| 7943 | ** code is SQLITE_MISUSE, *ppBlob is set to NULL.)^ ^This means that, provided |
| 7944 | ** the API is not misused, it is always safe to call [sqlite3_blob_close()] |
| 7945 | ** on *ppBlob after this function it returns. |
| 7946 | ** |
| 7947 | ** This function fails with SQLITE_ERROR if any of the following are true: |
| 7948 | ** <ul> |
| 7949 | ** <li> ^(Database zDb does not exist)^, |
| 7950 | ** <li> ^(Table zTable does not exist within database zDb)^, |
| @@ -8060,11 +8060,11 @@ | |
| 8060 | ** CAPI3REF: Return The Size Of An Open BLOB |
| 8061 | ** METHOD: sqlite3_blob |
| 8062 | ** |
| 8063 | ** ^Returns the size in bytes of the BLOB accessible via the |
| 8064 | ** successfully opened [BLOB handle] in its only argument. ^The |
| 8065 | ** incremental blob I/O routines can only read or overwriting existing |
| 8066 | ** blob content; they cannot change the size of a blob. |
| 8067 | ** |
| 8068 | ** This routine only works on a [BLOB handle] which has been created |
| 8069 | ** by a prior successful call to [sqlite3_blob_open()] and which has not |
| 8070 | ** been closed by [sqlite3_blob_close()]. Passing any other pointer in |
| @@ -9463,11 +9463,11 @@ | |
| 9463 | ** sqlite3_backup_step(), the source database may be modified mid-way |
| 9464 | ** through the backup process. ^If the source database is modified by an |
| 9465 | ** external process or via a database connection other than the one being |
| 9466 | ** used by the backup operation, then the backup will be automatically |
| 9467 | ** restarted by the next call to sqlite3_backup_step(). ^If the source |
| 9468 | ** database is modified by the using the same database connection as is used |
| 9469 | ** by the backup operation, then the backup database is automatically |
| 9470 | ** updated at the same time. |
| 9471 | ** |
| 9472 | ** [[sqlite3_backup_finish()]] <b>sqlite3_backup_finish()</b> |
| 9473 | ** |
| @@ -9480,11 +9480,11 @@ | |
| 9480 | ** active write-transaction on the destination database is rolled back. |
| 9481 | ** The [sqlite3_backup] object is invalid |
| 9482 | ** and may not be used following a call to sqlite3_backup_finish(). |
| 9483 | ** |
| 9484 | ** ^The value returned by sqlite3_backup_finish is [SQLITE_OK] if no |
| 9485 | ** sqlite3_backup_step() errors occurred, regardless or whether or not |
| 9486 | ** sqlite3_backup_step() completed. |
| 9487 | ** ^If an out-of-memory condition or IO error occurred during any prior |
| 9488 | ** sqlite3_backup_step() call on the same [sqlite3_backup] object, then |
| 9489 | ** sqlite3_backup_finish() returns the corresponding [error code]. |
| 9490 | ** |
| @@ -10550,11 +10550,11 @@ | |
| 10550 | /* |
| 10551 | ** CAPI3REF: Flush caches to disk mid-transaction |
| 10552 | ** METHOD: sqlite3 |
| 10553 | ** |
| 10554 | ** ^If a write-transaction is open on [database connection] D when the |
| 10555 | ** [sqlite3_db_cacheflush(D)] interface invoked, any dirty |
| 10556 | ** pages in the pager-cache that are not currently in use are written out |
| 10557 | ** to disk. A dirty page may be in use if a database cursor created by an |
| 10558 | ** active SQL statement is reading from it, or if it is page 1 of a database |
| 10559 | ** file (page 1 is always "in use"). ^The [sqlite3_db_cacheflush(D)] |
| 10560 | ** interface flushes caches for all schemas - "main", "temp", and |
| 10561 |
| --- extsrc/sqlite3.h | |
| +++ extsrc/sqlite3.h | |
| @@ -146,11 +146,11 @@ | |
| 146 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 147 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 148 | */ |
| 149 | #define SQLITE_VERSION "3.51.0" |
| 150 | #define SQLITE_VERSION_NUMBER 3051000 |
| 151 | #define SQLITE_SOURCE_ID "2025-06-19 20:19:12 a88bb75288a06492a04ab1278e8a2101a74f4ba712d328b4c73e86ac01cb946d" |
| 152 | |
| 153 | /* |
| 154 | ** CAPI3REF: Run-Time Library Version Numbers |
| 155 | ** KEYWORDS: sqlite3_version sqlite3_sourceid |
| 156 | ** |
| @@ -4077,11 +4077,11 @@ | |
| 4077 | ** These interfaces are provided for use by [VFS shim] implementations and |
| 4078 | ** are not useful outside of that context. |
| 4079 | ** |
| 4080 | ** The sqlite3_create_filename(D,J,W,N,P) allocates memory to hold a version of |
| 4081 | ** database filename D with corresponding journal file J and WAL file W and |
| 4082 | ** an array P of N URI Key/Value pairs. The result from |
| 4083 | ** sqlite3_create_filename(D,J,W,N,P) is a pointer to a database filename that |
| 4084 | ** is safe to pass to routines like: |
| 4085 | ** <ul> |
| 4086 | ** <li> [sqlite3_uri_parameter()], |
| 4087 | ** <li> [sqlite3_uri_boolean()], |
| @@ -4758,11 +4758,11 @@ | |
| 4758 | ** KEYWORDS: {host parameter} {host parameters} {host parameter name} |
| 4759 | ** KEYWORDS: {SQL parameter} {SQL parameters} {parameter binding} |
| 4760 | ** METHOD: sqlite3_stmt |
| 4761 | ** |
| 4762 | ** ^(In the SQL statement text input to [sqlite3_prepare_v2()] and its variants, |
| 4763 | ** literals may be replaced by a [parameter] that matches one of the following |
| 4764 | ** templates: |
| 4765 | ** |
| 4766 | ** <ul> |
| 4767 | ** <li> ? |
| 4768 | ** <li> ?NNN |
| @@ -4803,11 +4803,11 @@ | |
| 4803 | ** either UTF8 if the sixth parameter is SQLITE_UTF8, or UTF16 |
| 4804 | ** otherwise. |
| 4805 | ** |
| 4806 | ** [[byte-order determination rules]] ^The byte-order of |
| 4807 | ** UTF16 input text is determined by the byte-order mark (BOM, U+FEFF) |
| 4808 | ** found in the first character, which is removed, or in the absence of a BOM |
| 4809 | ** the byte order is the native byte order of the host |
| 4810 | ** machine for sqlite3_bind_text16() or the byte order specified in |
| 4811 | ** the 6th parameter for sqlite3_bind_text64().)^ |
| 4812 | ** ^If UTF16 input text contains invalid unicode |
| 4813 | ** characters, then SQLite might change those invalid characters |
| @@ -4823,11 +4823,11 @@ | |
| 4823 | ** the behavior is undefined. |
| 4824 | ** If a non-negative fourth parameter is provided to sqlite3_bind_text() |
| 4825 | ** or sqlite3_bind_text16() or sqlite3_bind_text64() then |
| 4826 | ** that parameter must be the byte offset |
| 4827 | ** where the NUL terminator would occur assuming the string were NUL |
| 4828 | ** terminated. If any NUL characters occur at byte offsets less than |
| 4829 | ** the value of the fourth parameter then the resulting string value will |
| 4830 | ** contain embedded NULs. The result of expressions involving strings |
| 4831 | ** with embedded NULs is undefined. |
| 4832 | ** |
| 4833 | ** ^The fifth argument to the BLOB and string binding interfaces controls |
| @@ -5035,11 +5035,11 @@ | |
| 5035 | /* |
| 5036 | ** CAPI3REF: Source Of Data In A Query Result |
| 5037 | ** METHOD: sqlite3_stmt |
| 5038 | ** |
| 5039 | ** ^These routines provide a means to determine the database, table, and |
| 5040 | ** table column that is the origin of a particular result column in a |
| 5041 | ** [SELECT] statement. |
| 5042 | ** ^The name of the database or table or column can be returned as |
| 5043 | ** either a UTF-8 or UTF-16 string. ^The _database_ routines return |
| 5044 | ** the database name, the _table_ routines return the table name, and |
| 5045 | ** the origin_ routines return the column name. |
| @@ -5604,12 +5604,12 @@ | |
| 5604 | ** within VIEWs, TRIGGERs, CHECK constraints, generated column expressions, |
| 5605 | ** index expressions, or the WHERE clause of partial indexes. |
| 5606 | ** |
| 5607 | ** For best security, the [SQLITE_DIRECTONLY] flag is recommended for |
| 5608 | ** all application-defined SQL functions that do not need to be |
| 5609 | ** used inside of triggers, views, CHECK constraints, or other elements of |
| 5610 | ** the database schema. This flag is especially recommended for SQL |
| 5611 | ** functions that have side effects or reveal internal application state. |
| 5612 | ** Without this flag, an attacker might be able to modify the schema of |
| 5613 | ** a database file to include invocations of the function with parameters |
| 5614 | ** chosen by the attacker, which the application will then execute when |
| 5615 | ** the database file is opened and read. |
| @@ -5636,11 +5636,11 @@ | |
| 5636 | ** or aggregate window function. More details regarding the implementation |
| 5637 | ** of aggregate window functions are |
| 5638 | ** [user-defined window functions|available here]. |
| 5639 | ** |
| 5640 | ** ^(If the final parameter to sqlite3_create_function_v2() or |
| 5641 | ** sqlite3_create_window_function() is not NULL, then it is the destructor for |
| 5642 | ** the application data pointer. The destructor is invoked when the function |
| 5643 | ** is deleted, either by being overloaded or when the database connection |
| 5644 | ** closes.)^ ^The destructor is also invoked if the call to |
| 5645 | ** sqlite3_create_function_v2() fails. ^When the destructor callback is |
| 5646 | ** invoked, it is passed a single argument which is a copy of the application |
| @@ -7444,11 +7444,11 @@ | |
| 7444 | ** that is to be automatically loaded into all new database connections. |
| 7445 | ** |
| 7446 | ** ^(Even though the function prototype shows that xEntryPoint() takes |
| 7447 | ** no arguments and returns void, SQLite invokes xEntryPoint() with three |
| 7448 | ** arguments and expects an integer result as if the signature of the |
| 7449 | ** entry point were as follows: |
| 7450 | ** |
| 7451 | ** <blockquote><pre> |
| 7452 | ** int xEntryPoint( |
| 7453 | ** sqlite3 *db, |
| 7454 | ** const char **pzErrMsg, |
| @@ -7775,11 +7775,11 @@ | |
| 7775 | ** by the first parameter. ^The name of the module is given by the |
| 7776 | ** second parameter. ^The third parameter is a pointer to |
| 7777 | ** the implementation of the [virtual table module]. ^The fourth |
| 7778 | ** parameter is an arbitrary client data pointer that is passed through |
| 7779 | ** into the [xCreate] and [xConnect] methods of the virtual table module |
| 7780 | ** when a new virtual table is being created or reinitialized. |
| 7781 | ** |
| 7782 | ** ^The sqlite3_create_module_v2() interface has a fifth parameter which |
| 7783 | ** is a pointer to a destructor for the pClientData. ^SQLite will |
| 7784 | ** invoke the destructor function (if it is not NULL) when SQLite |
| 7785 | ** no longer needs the pClientData pointer. ^The destructor will also |
| @@ -7940,11 +7940,11 @@ | |
| 7940 | ** |
| 7941 | ** ^(On success, [SQLITE_OK] is returned and the new [BLOB handle] is stored |
| 7942 | ** in *ppBlob. Otherwise an [error code] is returned and, unless the error |
| 7943 | ** code is SQLITE_MISUSE, *ppBlob is set to NULL.)^ ^This means that, provided |
| 7944 | ** the API is not misused, it is always safe to call [sqlite3_blob_close()] |
| 7945 | ** on *ppBlob after this function returns. |
| 7946 | ** |
| 7947 | ** This function fails with SQLITE_ERROR if any of the following are true: |
| 7948 | ** <ul> |
| 7949 | ** <li> ^(Database zDb does not exist)^, |
| 7950 | ** <li> ^(Table zTable does not exist within database zDb)^, |
| @@ -8060,11 +8060,11 @@ | |
| 8060 | ** CAPI3REF: Return The Size Of An Open BLOB |
| 8061 | ** METHOD: sqlite3_blob |
| 8062 | ** |
| 8063 | ** ^Returns the size in bytes of the BLOB accessible via the |
| 8064 | ** successfully opened [BLOB handle] in its only argument. ^The |
| 8065 | ** incremental blob I/O routines can only read or overwrite existing |
| 8066 | ** blob content; they cannot change the size of a blob. |
| 8067 | ** |
| 8068 | ** This routine only works on a [BLOB handle] which has been created |
| 8069 | ** by a prior successful call to [sqlite3_blob_open()] and which has not |
| 8070 | ** been closed by [sqlite3_blob_close()]. Passing any other pointer in |
| @@ -9463,11 +9463,11 @@ | |
| 9463 | ** sqlite3_backup_step(), the source database may be modified mid-way |
| 9464 | ** through the backup process. ^If the source database is modified by an |
| 9465 | ** external process or via a database connection other than the one being |
| 9466 | ** used by the backup operation, then the backup will be automatically |
| 9467 | ** restarted by the next call to sqlite3_backup_step(). ^If the source |
| 9468 | ** database is modified by using the same database connection as is used |
| 9469 | ** by the backup operation, then the backup database is automatically |
| 9470 | ** updated at the same time. |
| 9471 | ** |
| 9472 | ** [[sqlite3_backup_finish()]] <b>sqlite3_backup_finish()</b> |
| 9473 | ** |
| @@ -9480,11 +9480,11 @@ | |
| 9480 | ** active write-transaction on the destination database is rolled back. |
| 9481 | ** The [sqlite3_backup] object is invalid |
| 9482 | ** and may not be used following a call to sqlite3_backup_finish(). |
| 9483 | ** |
| 9484 | ** ^The value returned by sqlite3_backup_finish is [SQLITE_OK] if no |
| 9485 | ** sqlite3_backup_step() errors occurred, regardless of whether or not |
| 9486 | ** sqlite3_backup_step() completed. |
| 9487 | ** ^If an out-of-memory condition or IO error occurred during any prior |
| 9488 | ** sqlite3_backup_step() call on the same [sqlite3_backup] object, then |
| 9489 | ** sqlite3_backup_finish() returns the corresponding [error code]. |
| 9490 | ** |
| @@ -10550,11 +10550,11 @@ | |
| 10550 | /* |
| 10551 | ** CAPI3REF: Flush caches to disk mid-transaction |
| 10552 | ** METHOD: sqlite3 |
| 10553 | ** |
| 10554 | ** ^If a write-transaction is open on [database connection] D when the |
| 10555 | ** [sqlite3_db_cacheflush(D)] interface is invoked, any dirty |
| 10556 | ** pages in the pager-cache that are not currently in use are written out |
| 10557 | ** to disk. A dirty page may be in use if a database cursor created by an |
| 10558 | ** active SQL statement is reading from it, or if it is page 1 of a database |
| 10559 | ** file (page 1 is always "in use"). ^The [sqlite3_db_cacheflush(D)] |
| 10560 | ** interface flushes caches for all schemas - "main", "temp", and |
| 10561 |
+4
| --- src/configure.c | ||
| +++ src/configure.c | ||
| @@ -370,10 +370,14 @@ | ||
| 370 | 370 | ** /user $MTIME $LOGIN pw $VALUE cap $VALUE info $VALUE photo $VALUE |
| 371 | 371 | ** /shun $MTIME $UUID scom $VALUE |
| 372 | 372 | ** /reportfmt $MTIME $TITLE owner $VALUE cols $VALUE sqlcode $VALUE jx $JSON |
| 373 | 373 | ** /concealed $MTIME $HASH content $VALUE |
| 374 | 374 | ** /subscriber $SMTIME $SEMAIL suname $V ... |
| 375 | +** | |
| 376 | +** NAME-specific notes: | |
| 377 | +** | |
| 378 | +** - /reportftm's $MTIME is in Julian, not the Unix epoch. | |
| 375 | 379 | */ |
| 376 | 380 | void configure_receive(const char *zName, Blob *pContent, int groupMask){ |
| 377 | 381 | int checkMask; /* Masks for which we must first check existance of tables */ |
| 378 | 382 | |
| 379 | 383 | checkMask = CONFIGSET_SCRIBER; |
| 380 | 384 |
| --- src/configure.c | |
| +++ src/configure.c | |
| @@ -370,10 +370,14 @@ | |
| 370 | ** /user $MTIME $LOGIN pw $VALUE cap $VALUE info $VALUE photo $VALUE |
| 371 | ** /shun $MTIME $UUID scom $VALUE |
| 372 | ** /reportfmt $MTIME $TITLE owner $VALUE cols $VALUE sqlcode $VALUE jx $JSON |
| 373 | ** /concealed $MTIME $HASH content $VALUE |
| 374 | ** /subscriber $SMTIME $SEMAIL suname $V ... |
| 375 | */ |
| 376 | void configure_receive(const char *zName, Blob *pContent, int groupMask){ |
| 377 | int checkMask; /* Masks for which we must first check existance of tables */ |
| 378 | |
| 379 | checkMask = CONFIGSET_SCRIBER; |
| 380 |
| --- src/configure.c | |
| +++ src/configure.c | |
| @@ -370,10 +370,14 @@ | |
| 370 | ** /user $MTIME $LOGIN pw $VALUE cap $VALUE info $VALUE photo $VALUE |
| 371 | ** /shun $MTIME $UUID scom $VALUE |
| 372 | ** /reportfmt $MTIME $TITLE owner $VALUE cols $VALUE sqlcode $VALUE jx $JSON |
| 373 | ** /concealed $MTIME $HASH content $VALUE |
| 374 | ** /subscriber $SMTIME $SEMAIL suname $V ... |
| 375 | ** |
| 376 | ** NAME-specific notes: |
| 377 | ** |
| 378 | ** - /reportftm's $MTIME is in Julian, not the Unix epoch. |
| 379 | */ |
| 380 | void configure_receive(const char *zName, Blob *pContent, int groupMask){ |
| 381 | int checkMask; /* Masks for which we must first check existance of tables */ |
| 382 | |
| 383 | checkMask = CONFIGSET_SCRIBER; |
| 384 |
+4
-1
| --- src/repolist.c | ||
| +++ src/repolist.c | ||
| @@ -157,17 +157,20 @@ | ||
| 157 | 157 | allRepo = 1; |
| 158 | 158 | }else{ |
| 159 | 159 | /* The default case: All repositories under the g.zRepositoryName |
| 160 | 160 | ** directory. |
| 161 | 161 | */ |
| 162 | + Glob *pExclude; | |
| 162 | 163 | blob_init(&base, g.zRepositoryName, -1); |
| 163 | 164 | db_close(0); |
| 164 | 165 | assert( g.db==0 ); |
| 165 | 166 | sqlite3_open(":memory:", &g.db); |
| 166 | 167 | db_multi_exec("CREATE TABLE sfile(pathname TEXT);"); |
| 167 | 168 | db_multi_exec("CREATE TABLE vfile(pathname);"); |
| 168 | - vfile_scan(&base, blob_size(&base), 0, 0, 0, ExtFILE); | |
| 169 | + pExclude = glob_create("*/proc,proc"); | |
| 170 | + vfile_scan(&base, blob_size(&base), 0, pExclude, 0, ExtFILE); | |
| 171 | + glob_free(pExclude); | |
| 169 | 172 | db_multi_exec("DELETE FROM sfile WHERE pathname NOT GLOB '*[^/].fossil'" |
| 170 | 173 | #if USE_SEE |
| 171 | 174 | " AND pathname NOT GLOB '*[^/].efossil'" |
| 172 | 175 | #endif |
| 173 | 176 | ); |
| 174 | 177 |
| --- src/repolist.c | |
| +++ src/repolist.c | |
| @@ -157,17 +157,20 @@ | |
| 157 | allRepo = 1; |
| 158 | }else{ |
| 159 | /* The default case: All repositories under the g.zRepositoryName |
| 160 | ** directory. |
| 161 | */ |
| 162 | blob_init(&base, g.zRepositoryName, -1); |
| 163 | db_close(0); |
| 164 | assert( g.db==0 ); |
| 165 | sqlite3_open(":memory:", &g.db); |
| 166 | db_multi_exec("CREATE TABLE sfile(pathname TEXT);"); |
| 167 | db_multi_exec("CREATE TABLE vfile(pathname);"); |
| 168 | vfile_scan(&base, blob_size(&base), 0, 0, 0, ExtFILE); |
| 169 | db_multi_exec("DELETE FROM sfile WHERE pathname NOT GLOB '*[^/].fossil'" |
| 170 | #if USE_SEE |
| 171 | " AND pathname NOT GLOB '*[^/].efossil'" |
| 172 | #endif |
| 173 | ); |
| 174 |
| --- src/repolist.c | |
| +++ src/repolist.c | |
| @@ -157,17 +157,20 @@ | |
| 157 | allRepo = 1; |
| 158 | }else{ |
| 159 | /* The default case: All repositories under the g.zRepositoryName |
| 160 | ** directory. |
| 161 | */ |
| 162 | Glob *pExclude; |
| 163 | blob_init(&base, g.zRepositoryName, -1); |
| 164 | db_close(0); |
| 165 | assert( g.db==0 ); |
| 166 | sqlite3_open(":memory:", &g.db); |
| 167 | db_multi_exec("CREATE TABLE sfile(pathname TEXT);"); |
| 168 | db_multi_exec("CREATE TABLE vfile(pathname);"); |
| 169 | pExclude = glob_create("*/proc,proc"); |
| 170 | vfile_scan(&base, blob_size(&base), 0, pExclude, 0, ExtFILE); |
| 171 | glob_free(pExclude); |
| 172 | db_multi_exec("DELETE FROM sfile WHERE pathname NOT GLOB '*[^/].fossil'" |
| 173 | #if USE_SEE |
| 174 | " AND pathname NOT GLOB '*[^/].efossil'" |
| 175 | #endif |
| 176 | ); |
| 177 |
+4
-1
| --- src/wiki.c | ||
| +++ src/wiki.c | ||
| @@ -2583,11 +2583,14 @@ | ||
| 2583 | 2583 | static void wiki_submenu_to_read_wiki( |
| 2584 | 2584 | const char *zPrefix, /* "branch", "tag", or "checkin" */ |
| 2585 | 2585 | const char *zName, /* Name of the object */ |
| 2586 | 2586 | unsigned int mFlags /* Zero or more WIKIASSOC_* flags */ |
| 2587 | 2587 | ){ |
| 2588 | - if( g.perm.RdWiki && (mFlags & WIKIASSOC_MENU_READ)!=0 ){ | |
| 2588 | + if( g.perm.RdWiki && (mFlags & WIKIASSOC_MENU_READ)!=0 | |
| 2589 | + && 0!=fossil_strcmp("branch", zPrefix) | |
| 2590 | + /* ^^^ https://fossil-scm.org/forum/forumpost/ff453de2f30791dd */ | |
| 2591 | + ){ | |
| 2589 | 2592 | style_submenu_element("Wiki", "%R/wiki?name=%s/%t", zPrefix, zName); |
| 2590 | 2593 | } |
| 2591 | 2594 | } |
| 2592 | 2595 | |
| 2593 | 2596 | /* |
| 2594 | 2597 | |
| 2595 | 2598 | ADDED test/link-tester.html |
| 2596 | 2599 | ADDED test/link-tester.js |
| 2597 | 2600 | ADDED test/link-tester.json |
| --- src/wiki.c | |
| +++ src/wiki.c | |
| @@ -2583,11 +2583,14 @@ | |
| 2583 | static void wiki_submenu_to_read_wiki( |
| 2584 | const char *zPrefix, /* "branch", "tag", or "checkin" */ |
| 2585 | const char *zName, /* Name of the object */ |
| 2586 | unsigned int mFlags /* Zero or more WIKIASSOC_* flags */ |
| 2587 | ){ |
| 2588 | if( g.perm.RdWiki && (mFlags & WIKIASSOC_MENU_READ)!=0 ){ |
| 2589 | style_submenu_element("Wiki", "%R/wiki?name=%s/%t", zPrefix, zName); |
| 2590 | } |
| 2591 | } |
| 2592 | |
| 2593 | /* |
| 2594 | |
| 2595 | DDED test/link-tester.html |
| 2596 | DDED test/link-tester.js |
| 2597 | DDED test/link-tester.json |
| --- src/wiki.c | |
| +++ src/wiki.c | |
| @@ -2583,11 +2583,14 @@ | |
| 2583 | static void wiki_submenu_to_read_wiki( |
| 2584 | const char *zPrefix, /* "branch", "tag", or "checkin" */ |
| 2585 | const char *zName, /* Name of the object */ |
| 2586 | unsigned int mFlags /* Zero or more WIKIASSOC_* flags */ |
| 2587 | ){ |
| 2588 | if( g.perm.RdWiki && (mFlags & WIKIASSOC_MENU_READ)!=0 |
| 2589 | && 0!=fossil_strcmp("branch", zPrefix) |
| 2590 | /* ^^^ https://fossil-scm.org/forum/forumpost/ff453de2f30791dd */ |
| 2591 | ){ |
| 2592 | style_submenu_element("Wiki", "%R/wiki?name=%s/%t", zPrefix, zName); |
| 2593 | } |
| 2594 | } |
| 2595 | |
| 2596 | /* |
| 2597 | |
| 2598 | DDED test/link-tester.html |
| 2599 | DDED test/link-tester.js |
| 2600 | DDED test/link-tester.json |
+82
| --- a/test/link-tester.html | ||
| +++ b/test/link-tester.html | ||
| @@ -0,0 +1,82 @@ | ||
| 1 | +<!DOCTYPE html> | |
| 2 | +<head><!-- | |
| 3 | + This file is intended to be loaded from a fossil | |
| 4 | + repository, either using: | |
| 5 | + | |
| 6 | + fossil ui --extpage test/link-tester.html | |
| 7 | + | |
| 8 | + or by adding test/link-tester.* to uv and then: | |
| 9 | + | |
| 10 | + fossil ui -page uv/link-tester.html | |
| 11 | +--></head> | |
| 12 | +<style> | |
| 13 | + body { | |
| 14 | + width: 100%; | |
| 15 | + height: 100%; | |
| 16 | + margin: 0; | |
| 17 | + padding: 0; | |
| 18 | + display: flex; | |
| 19 | + flex-direction: column; | |
| 20 | + } | |
| 21 | + header { | |
| 22 | + margin: 0.5em 0 0 0; | |
| 23 | + padding: 0 1em 0 1em; | |
| 24 | + z-index: 1; | |
| 25 | + } | |
| 26 | + #controlWrapper { | |
| 27 | + display: flex; | |
| 28 | + flex-direction: row; | |
| 29 | + border-bottom: 2px dotted; | |
| 30 | + padding-bottom: 0.5em; | |
| 31 | + } | |
| 32 | + #controlWrapper > button { | |
| 33 | + flex-grow: 1; | |
| 34 | + margin: 0.5em; | |
| 35 | + } | |
| 36 | + #selectWrapper { | |
| 37 | + display: flex; | |
| 38 | + flex-direction: column; | |
| 39 | + flex-grow: 8; | |
| 40 | + } | |
| 41 | + #selectPage { | |
| 42 | + flex-grow: 1; | |
| 43 | + margin: 1em; | |
| 44 | + padding: 1em; | |
| 45 | + } | |
| 46 | + #currentUrl { | |
| 47 | + font-family: monospace; | |
| 48 | + text-align: center; | |
| 49 | + } | |
| 50 | + #iframe { | |
| 51 | + flex-grow: 1; border: none; margin: 0; padding: 0; | |
| 52 | + display: block; | |
| 53 | + /* Absolute positioning is apparently the only way to get | |
| 54 | + the iframe to stretch to fill the page, but we have to | |
| 55 | + set its Y coordinate to something a bit below #controls. */ | |
| 56 | + width: 100%; | |
| 57 | + height: calc(100% - 5em); | |
| 58 | + position: absolute; | |
| 59 | + top: 4em; | |
| 60 | + } | |
| 61 | +</style> | |
| 62 | +<body> | |
| 63 | + <header> | |
| 64 | + Fossil link test app. Select links from the list below to load | |
| 65 | + them. Use the arrow keys to cycle through the list. The links are | |
| 66 | + loaded within an iframe, so navigation within it will stay within | |
| 67 | + that frame. | |
| 68 | + </header> | |
| 69 | + <header id='controlWrapper'> | |
| 70 | + <button id='btn-prev'>←</button> | |
| 71 | + <div id='selectWrapper'> | |
| 72 | + <select id='selectPage'> | |
| 73 | + <option>/timeline</option> | |
| 74 | + <option>/dir</option> | |
| 75 | + </select> | |
| 76 | + <a target='_blank' id='currentUrl'></a> | |
| 77 | + </div> | |
| 78 | + <button id='btn-next'>→</button> | |
| 79 | + </header> | |
| 80 | + <iframe id='iframe'><!--populated via the UI--></iframe> | |
| 81 | + <script src='link-tester.js'></script> | |
| 82 | +<body> |
| --- a/test/link-tester.html | |
| +++ b/test/link-tester.html | |
| @@ -0,0 +1,82 @@ | |
| --- a/test/link-tester.html | |
| +++ b/test/link-tester.html | |
| @@ -0,0 +1,82 @@ | |
| 1 | <!DOCTYPE html> |
| 2 | <head><!-- |
| 3 | This file is intended to be loaded from a fossil |
| 4 | repository, either using: |
| 5 | |
| 6 | fossil ui --extpage test/link-tester.html |
| 7 | |
| 8 | or by adding test/link-tester.* to uv and then: |
| 9 | |
| 10 | fossil ui -page uv/link-tester.html |
| 11 | --></head> |
| 12 | <style> |
| 13 | body { |
| 14 | width: 100%; |
| 15 | height: 100%; |
| 16 | margin: 0; |
| 17 | padding: 0; |
| 18 | display: flex; |
| 19 | flex-direction: column; |
| 20 | } |
| 21 | header { |
| 22 | margin: 0.5em 0 0 0; |
| 23 | padding: 0 1em 0 1em; |
| 24 | z-index: 1; |
| 25 | } |
| 26 | #controlWrapper { |
| 27 | display: flex; |
| 28 | flex-direction: row; |
| 29 | border-bottom: 2px dotted; |
| 30 | padding-bottom: 0.5em; |
| 31 | } |
| 32 | #controlWrapper > button { |
| 33 | flex-grow: 1; |
| 34 | margin: 0.5em; |
| 35 | } |
| 36 | #selectWrapper { |
| 37 | display: flex; |
| 38 | flex-direction: column; |
| 39 | flex-grow: 8; |
| 40 | } |
| 41 | #selectPage { |
| 42 | flex-grow: 1; |
| 43 | margin: 1em; |
| 44 | padding: 1em; |
| 45 | } |
| 46 | #currentUrl { |
| 47 | font-family: monospace; |
| 48 | text-align: center; |
| 49 | } |
| 50 | #iframe { |
| 51 | flex-grow: 1; border: none; margin: 0; padding: 0; |
| 52 | display: block; |
| 53 | /* Absolute positioning is apparently the only way to get |
| 54 | the iframe to stretch to fill the page, but we have to |
| 55 | set its Y coordinate to something a bit below #controls. */ |
| 56 | width: 100%; |
| 57 | height: calc(100% - 5em); |
| 58 | position: absolute; |
| 59 | top: 4em; |
| 60 | } |
| 61 | </style> |
| 62 | <body> |
| 63 | <header> |
| 64 | Fossil link test app. Select links from the list below to load |
| 65 | them. Use the arrow keys to cycle through the list. The links are |
| 66 | loaded within an iframe, so navigation within it will stay within |
| 67 | that frame. |
| 68 | </header> |
| 69 | <header id='controlWrapper'> |
| 70 | <button id='btn-prev'>←</button> |
| 71 | <div id='selectWrapper'> |
| 72 | <select id='selectPage'> |
| 73 | <option>/timeline</option> |
| 74 | <option>/dir</option> |
| 75 | </select> |
| 76 | <a target='_blank' id='currentUrl'></a> |
| 77 | </div> |
| 78 | <button id='btn-next'>→</button> |
| 79 | </header> |
| 80 | <iframe id='iframe'><!--populated via the UI--></iframe> |
| 81 | <script src='link-tester.js'></script> |
| 82 | <body> |
+224
| --- a/test/link-tester.js | ||
| +++ b/test/link-tester.js | ||
| @@ -0,0 +1,224 @@ | ||
| 1 | +/** | |
| 2 | + JS code for link-tester.html. We cannot host this JS inline in that | |
| 3 | + file because fossil's default Content Security Policy won't let it | |
| 4 | + run that way. | |
| 5 | +*/ | |
| 6 | +window.addEventListener("DOMContentLoaded", function(){ | |
| 7 | + const E = function(s){ | |
| 8 | + const e = document.querySelector(s); | |
| 9 | + if( !e ) throw new Error("Missing element: "+s); | |
| 10 | + return e; | |
| 11 | + }; | |
| 12 | + const EAll = function(s){ | |
| 13 | + const e = document.querySelectorAll(s); | |
| 14 | + if( !e || !e.length ) throw new Error("Missing elements: "+s); | |
| 15 | + return e; | |
| 16 | + }; | |
| 17 | + const eIframe = E('#iframe'); | |
| 18 | + const eSelect = E('#selectPage'); | |
| 19 | + const eCurrentUrl = E('#currentUrl'); | |
| 20 | + | |
| 21 | + /* | |
| 22 | + Prepend the fossil instance's URL to each link. We have to guess | |
| 23 | + which part of the URL is the fossil CGI/server instance. The | |
| 24 | + following works when run (A) from under /uv or /ext and (B) from | |
| 25 | + /doc/branchname/test/link-tester.html. | |
| 26 | + */ | |
| 27 | + let urlTop; | |
| 28 | + let loc = (''+window.location); | |
| 29 | + let aLoc = loc.split('/') | |
| 30 | + aLoc.pop(); /* file name */ | |
| 31 | + const thisDir = aLoc.join('/'); | |
| 32 | + const rxDoc = /.*\/doc\/[^/]+\/.*/; | |
| 33 | + //console.log(rxDoc, loc, aLoc); | |
| 34 | + if( loc.match(rxDoc) ){ | |
| 35 | + /* We're hopefully now at the top-most fossil-served | |
| 36 | + URL. */ | |
| 37 | + aLoc.pop(); aLoc.pop(); /* /doc/foo */ | |
| 38 | + aLoc.pop(); /* current dir name */ | |
| 39 | + }else{ | |
| 40 | + aLoc.pop(); /* current dir name */ | |
| 41 | + } | |
| 42 | + urlTop = aLoc.join('/'); | |
| 43 | + //console.log(urlTop, aLoc); | |
| 44 | + for( const o of eSelect.options ){ | |
| 45 | + o.value = urlTop + (o.value || o.innerText); | |
| 46 | + } | |
| 47 | + | |
| 48 | + const updateUrl = function(opt){ | |
| 49 | + if( opt ){ | |
| 50 | + let url = (opt.value || opt.innerText); | |
| 51 | + eCurrentUrl.innerText = url.replace(urlTop,''); | |
| 52 | + eCurrentUrl.setAttribute('href', url); | |
| 53 | + }else{ | |
| 54 | + eCurrentUrl.innerText = ''; | |
| 55 | + } | |
| 56 | + }; | |
| 57 | + | |
| 58 | + eSelect.addEventListener('change',function(ev){ | |
| 59 | + const so = ev.target.options[ev.target.selectedIndex]; | |
| 60 | + if( so ){ | |
| 61 | + eIframe.setAttribute('src', so.value || so.innerText); | |
| 62 | + updateUrl(so); | |
| 63 | + } | |
| 64 | + }); | |
| 65 | + | |
| 66 | + /** Select the entry at the given ndx and fire a change event. */ | |
| 67 | + const selectEntry = function(ndx){ | |
| 68 | + if( ndx>=0 ){ | |
| 69 | + eSelect.selectedIndex = ndx; | |
| 70 | + eSelect.dispatchEvent(new Event('change',{target:eSelect})); | |
| 71 | + } | |
| 72 | + }; | |
| 73 | + | |
| 74 | + /* Cycle to the next link in the list, accounting for separators and | |
| 75 | + wrapping around at either end. */ | |
| 76 | + const cycleLink = function(dir/*<0 = prev, >0 = next*/){ | |
| 77 | + let n = eSelect.selectedIndex + dir; | |
| 78 | + if( n < 0 ) n = eSelect.options.length-1; | |
| 79 | + else if( n>=eSelect.options.length ){ | |
| 80 | + n = 0; | |
| 81 | + } | |
| 82 | + const opt = eSelect.options[n]; | |
| 83 | + if( opt && opt.disabled ){ | |
| 84 | + /* If that OPTION element is disabled, skip over it. */ | |
| 85 | + eSelect.selectedIndex = n; | |
| 86 | + cycleLink(dir); | |
| 87 | + }else{ | |
| 88 | + selectEntry(n); | |
| 89 | + } | |
| 90 | + }; | |
| 91 | + | |
| 92 | + E('#btn-prev').addEventListener('click', ()=>cycleLink(-1), false); | |
| 93 | + E('#btn-next').addEventListener('click', ()=>cycleLink(1), false); | |
| 94 | + | |
| 95 | + /** | |
| 96 | + We have to adjust the iframe's size dynamically to account for | |
| 97 | + other widgets around it. iframes don't simply like to fill up all | |
| 98 | + available space without some help. If #controlWrapper only | |
| 99 | + contained the one SELECT element, CSS would be sufficient, but | |
| 100 | + once we add text around it, #controlWrapper's size becomes | |
| 101 | + unpredictable and we need JS to calculate it. We do this every | |
| 102 | + time the window size changes. | |
| 103 | + */ | |
| 104 | + const effectiveHeight = function f(e){ | |
| 105 | + // Copied from fossil.dom.js | |
| 106 | + if(!e) return 0; | |
| 107 | + if(!f.measure){ | |
| 108 | + f.measure = function callee(e, depth){ | |
| 109 | + if(!e) return; | |
| 110 | + const m = e.getBoundingClientRect(); | |
| 111 | + if(0===depth){ | |
| 112 | + callee.top = m.top; | |
| 113 | + callee.bottom = m.bottom; | |
| 114 | + }else{ | |
| 115 | + callee.top = m.top ? Math.min(callee.top, m.top) : callee.top; | |
| 116 | + callee.bottom = Math.max(callee.bottom, m.bottom); | |
| 117 | + } | |
| 118 | + Array.prototype.forEach.call(e.children,(e)=>callee(e,depth+1)); | |
| 119 | + if(0===depth){ | |
| 120 | + //console.debug("measure() height:",e.className, callee.top, callee.bottom, (callee.bottom - callee.top)); | |
| 121 | + f.extra += callee.bottom - callee.top; | |
| 122 | + } | |
| 123 | + return f.extra; | |
| 124 | + }; | |
| 125 | + } | |
| 126 | + f.extra = 0; | |
| 127 | + f.measure(e,0); | |
| 128 | + return f.extra; | |
| 129 | + }; | |
| 130 | + | |
| 131 | + /* Helper for the window-resized event handler below, to avoid | |
| 132 | + handling the resize until after it's finished. */ | |
| 133 | + const debounce = function f(func, waitMs, immediate) { | |
| 134 | + // Copied from fossil.bootstrap.js | |
| 135 | + var timeoutId; | |
| 136 | + if(!waitMs) waitMs = f.$defaultDelay; | |
| 137 | + return function() { | |
| 138 | + const context = this, args = Array.prototype.slice.call(arguments); | |
| 139 | + const later = function() { | |
| 140 | + timeoutId = undefined; | |
| 141 | + if(!immediate) func.apply(context, args); | |
| 142 | + }; | |
| 143 | + const callNow = immediate && !timeoutId; | |
| 144 | + clearTimeout(timeoutId); | |
| 145 | + timeoutId = setTimeout(later, waitMs); | |
| 146 | + if(callNow) func.apply(context, args); | |
| 147 | + }; | |
| 148 | + }; | |
| 149 | + | |
| 150 | + /** | |
| 151 | + Resize eConstrained (the ifame element) so that it fits within | |
| 152 | + the page space not occupied by the list of elements eToAvoid. | |
| 153 | + */ | |
| 154 | + const ForceResizeKludge = (function(eToAvoid, eConstrained){ | |
| 155 | + const resized = function f(){ | |
| 156 | + if( f.$disabled ) return; | |
| 157 | + const wh = window.innerHeight; | |
| 158 | + let ht; | |
| 159 | + let extra = 0; | |
| 160 | + eToAvoid.forEach((e)=>e ? extra += effectiveHeight(e) : false); | |
| 161 | + ht = wh - extra; | |
| 162 | + if( ht < 100 ) ht = 100; | |
| 163 | + eConstrained.style.top = 'calc('+extra+'px + 2em)'; | |
| 164 | + eConstrained.style.height = | |
| 165 | + eConstrained.style.maxHeight = "calc("+ ht+ "px - 2em)"; | |
| 166 | + }; | |
| 167 | + resized.$disabled = true/* gets deleted later */; | |
| 168 | + window.addEventListener('resize', debounce(resized, 250), false); | |
| 169 | + return resized; | |
| 170 | + })( | |
| 171 | + EAll('body > *:not(iframe)'), | |
| 172 | + eIframe | |
| 173 | + ); | |
| 174 | + | |
| 175 | + delete ForceResizeKludge.$disabled; | |
| 176 | + ForceResizeKludge(); | |
| 177 | + | |
| 178 | + selectEntry(0); | |
| 179 | + | |
| 180 | + /** | |
| 181 | + Read link-tester.json, which should live in the same directory | |
| 182 | + as this file. It's expected to be an array with entries | |
| 183 | + in one of the following forms: | |
| 184 | + | |
| 185 | + - "string" = Separator label (disabled) | |
| 186 | + - ["/path"] = path with itself as a label | |
| 187 | + - ["label", "/path"] = path with the given label | |
| 188 | + | |
| 189 | + All paths are expected to have a "/" prefix and this script | |
| 190 | + accounts for mapping that to the fossil part of this script's | |
| 191 | + URL. | |
| 192 | + */ | |
| 193 | + window.fetch(thisDir+'/link-tester.json').then((r)=>r.json()).then(j=>{ | |
| 194 | + //console.log("fetched",j); | |
| 195 | + eSelect.innerHTML = ''; | |
| 196 | + const opt = function(arg){ | |
| 197 | + const o = document.createElement('option'); | |
| 198 | + //console.warn(arguments); | |
| 199 | + let rc = true; | |
| 200 | + if( 'string' === typeof arg ){ | |
| 201 | + /* Grouping separator */ | |
| 202 | + o.innerText = "--- " + arg + " ---"; | |
| 203 | + o.setAttribute('disabled',''); | |
| 204 | + rc = false; | |
| 205 | + }else if( 1===arg.length ){ | |
| 206 | + o.innerText = arg[0]; | |
| 207 | + o.value = urlTop + arg[0]; | |
| 208 | + }else if( 2==arg.length ){ | |
| 209 | + o.innerText = arg[0]; | |
| 210 | + o.value = urlTop + arg[1]; | |
| 211 | + } | |
| 212 | + eSelect.appendChild(o); | |
| 213 | + return rc; | |
| 214 | + }; | |
| 215 | + let ndx = -1/*index of first non-disabled entry*/, i = 0; | |
| 216 | + for(const e of j){ | |
| 217 | + if( opt(e) && ndx<0 ){ | |
| 218 | + ndx = i; | |
| 219 | + } | |
| 220 | + ++i; | |
| 221 | + } | |
| 222 | + selectEntry(ndx); | |
| 223 | + }); | |
| 224 | +}); |
| --- a/test/link-tester.js | |
| +++ b/test/link-tester.js | |
| @@ -0,0 +1,224 @@ | |
| --- a/test/link-tester.js | |
| +++ b/test/link-tester.js | |
| @@ -0,0 +1,224 @@ | |
| 1 | /** |
| 2 | JS code for link-tester.html. We cannot host this JS inline in that |
| 3 | file because fossil's default Content Security Policy won't let it |
| 4 | run that way. |
| 5 | */ |
| 6 | window.addEventListener("DOMContentLoaded", function(){ |
| 7 | const E = function(s){ |
| 8 | const e = document.querySelector(s); |
| 9 | if( !e ) throw new Error("Missing element: "+s); |
| 10 | return e; |
| 11 | }; |
| 12 | const EAll = function(s){ |
| 13 | const e = document.querySelectorAll(s); |
| 14 | if( !e || !e.length ) throw new Error("Missing elements: "+s); |
| 15 | return e; |
| 16 | }; |
| 17 | const eIframe = E('#iframe'); |
| 18 | const eSelect = E('#selectPage'); |
| 19 | const eCurrentUrl = E('#currentUrl'); |
| 20 | |
| 21 | /* |
| 22 | Prepend the fossil instance's URL to each link. We have to guess |
| 23 | which part of the URL is the fossil CGI/server instance. The |
| 24 | following works when run (A) from under /uv or /ext and (B) from |
| 25 | /doc/branchname/test/link-tester.html. |
| 26 | */ |
| 27 | let urlTop; |
| 28 | let loc = (''+window.location); |
| 29 | let aLoc = loc.split('/') |
| 30 | aLoc.pop(); /* file name */ |
| 31 | const thisDir = aLoc.join('/'); |
| 32 | const rxDoc = /.*\/doc\/[^/]+\/.*/; |
| 33 | //console.log(rxDoc, loc, aLoc); |
| 34 | if( loc.match(rxDoc) ){ |
| 35 | /* We're hopefully now at the top-most fossil-served |
| 36 | URL. */ |
| 37 | aLoc.pop(); aLoc.pop(); /* /doc/foo */ |
| 38 | aLoc.pop(); /* current dir name */ |
| 39 | }else{ |
| 40 | aLoc.pop(); /* current dir name */ |
| 41 | } |
| 42 | urlTop = aLoc.join('/'); |
| 43 | //console.log(urlTop, aLoc); |
| 44 | for( const o of eSelect.options ){ |
| 45 | o.value = urlTop + (o.value || o.innerText); |
| 46 | } |
| 47 | |
| 48 | const updateUrl = function(opt){ |
| 49 | if( opt ){ |
| 50 | let url = (opt.value || opt.innerText); |
| 51 | eCurrentUrl.innerText = url.replace(urlTop,''); |
| 52 | eCurrentUrl.setAttribute('href', url); |
| 53 | }else{ |
| 54 | eCurrentUrl.innerText = ''; |
| 55 | } |
| 56 | }; |
| 57 | |
| 58 | eSelect.addEventListener('change',function(ev){ |
| 59 | const so = ev.target.options[ev.target.selectedIndex]; |
| 60 | if( so ){ |
| 61 | eIframe.setAttribute('src', so.value || so.innerText); |
| 62 | updateUrl(so); |
| 63 | } |
| 64 | }); |
| 65 | |
| 66 | /** Select the entry at the given ndx and fire a change event. */ |
| 67 | const selectEntry = function(ndx){ |
| 68 | if( ndx>=0 ){ |
| 69 | eSelect.selectedIndex = ndx; |
| 70 | eSelect.dispatchEvent(new Event('change',{target:eSelect})); |
| 71 | } |
| 72 | }; |
| 73 | |
| 74 | /* Cycle to the next link in the list, accounting for separators and |
| 75 | wrapping around at either end. */ |
| 76 | const cycleLink = function(dir/*<0 = prev, >0 = next*/){ |
| 77 | let n = eSelect.selectedIndex + dir; |
| 78 | if( n < 0 ) n = eSelect.options.length-1; |
| 79 | else if( n>=eSelect.options.length ){ |
| 80 | n = 0; |
| 81 | } |
| 82 | const opt = eSelect.options[n]; |
| 83 | if( opt && opt.disabled ){ |
| 84 | /* If that OPTION element is disabled, skip over it. */ |
| 85 | eSelect.selectedIndex = n; |
| 86 | cycleLink(dir); |
| 87 | }else{ |
| 88 | selectEntry(n); |
| 89 | } |
| 90 | }; |
| 91 | |
| 92 | E('#btn-prev').addEventListener('click', ()=>cycleLink(-1), false); |
| 93 | E('#btn-next').addEventListener('click', ()=>cycleLink(1), false); |
| 94 | |
| 95 | /** |
| 96 | We have to adjust the iframe's size dynamically to account for |
| 97 | other widgets around it. iframes don't simply like to fill up all |
| 98 | available space without some help. If #controlWrapper only |
| 99 | contained the one SELECT element, CSS would be sufficient, but |
| 100 | once we add text around it, #controlWrapper's size becomes |
| 101 | unpredictable and we need JS to calculate it. We do this every |
| 102 | time the window size changes. |
| 103 | */ |
| 104 | const effectiveHeight = function f(e){ |
| 105 | // Copied from fossil.dom.js |
| 106 | if(!e) return 0; |
| 107 | if(!f.measure){ |
| 108 | f.measure = function callee(e, depth){ |
| 109 | if(!e) return; |
| 110 | const m = e.getBoundingClientRect(); |
| 111 | if(0===depth){ |
| 112 | callee.top = m.top; |
| 113 | callee.bottom = m.bottom; |
| 114 | }else{ |
| 115 | callee.top = m.top ? Math.min(callee.top, m.top) : callee.top; |
| 116 | callee.bottom = Math.max(callee.bottom, m.bottom); |
| 117 | } |
| 118 | Array.prototype.forEach.call(e.children,(e)=>callee(e,depth+1)); |
| 119 | if(0===depth){ |
| 120 | //console.debug("measure() height:",e.className, callee.top, callee.bottom, (callee.bottom - callee.top)); |
| 121 | f.extra += callee.bottom - callee.top; |
| 122 | } |
| 123 | return f.extra; |
| 124 | }; |
| 125 | } |
| 126 | f.extra = 0; |
| 127 | f.measure(e,0); |
| 128 | return f.extra; |
| 129 | }; |
| 130 | |
| 131 | /* Helper for the window-resized event handler below, to avoid |
| 132 | handling the resize until after it's finished. */ |
| 133 | const debounce = function f(func, waitMs, immediate) { |
| 134 | // Copied from fossil.bootstrap.js |
| 135 | var timeoutId; |
| 136 | if(!waitMs) waitMs = f.$defaultDelay; |
| 137 | return function() { |
| 138 | const context = this, args = Array.prototype.slice.call(arguments); |
| 139 | const later = function() { |
| 140 | timeoutId = undefined; |
| 141 | if(!immediate) func.apply(context, args); |
| 142 | }; |
| 143 | const callNow = immediate && !timeoutId; |
| 144 | clearTimeout(timeoutId); |
| 145 | timeoutId = setTimeout(later, waitMs); |
| 146 | if(callNow) func.apply(context, args); |
| 147 | }; |
| 148 | }; |
| 149 | |
| 150 | /** |
| 151 | Resize eConstrained (the ifame element) so that it fits within |
| 152 | the page space not occupied by the list of elements eToAvoid. |
| 153 | */ |
| 154 | const ForceResizeKludge = (function(eToAvoid, eConstrained){ |
| 155 | const resized = function f(){ |
| 156 | if( f.$disabled ) return; |
| 157 | const wh = window.innerHeight; |
| 158 | let ht; |
| 159 | let extra = 0; |
| 160 | eToAvoid.forEach((e)=>e ? extra += effectiveHeight(e) : false); |
| 161 | ht = wh - extra; |
| 162 | if( ht < 100 ) ht = 100; |
| 163 | eConstrained.style.top = 'calc('+extra+'px + 2em)'; |
| 164 | eConstrained.style.height = |
| 165 | eConstrained.style.maxHeight = "calc("+ ht+ "px - 2em)"; |
| 166 | }; |
| 167 | resized.$disabled = true/* gets deleted later */; |
| 168 | window.addEventListener('resize', debounce(resized, 250), false); |
| 169 | return resized; |
| 170 | })( |
| 171 | EAll('body > *:not(iframe)'), |
| 172 | eIframe |
| 173 | ); |
| 174 | |
| 175 | delete ForceResizeKludge.$disabled; |
| 176 | ForceResizeKludge(); |
| 177 | |
| 178 | selectEntry(0); |
| 179 | |
| 180 | /** |
| 181 | Read link-tester.json, which should live in the same directory |
| 182 | as this file. It's expected to be an array with entries |
| 183 | in one of the following forms: |
| 184 | |
| 185 | - "string" = Separator label (disabled) |
| 186 | - ["/path"] = path with itself as a label |
| 187 | - ["label", "/path"] = path with the given label |
| 188 | |
| 189 | All paths are expected to have a "/" prefix and this script |
| 190 | accounts for mapping that to the fossil part of this script's |
| 191 | URL. |
| 192 | */ |
| 193 | window.fetch(thisDir+'/link-tester.json').then((r)=>r.json()).then(j=>{ |
| 194 | //console.log("fetched",j); |
| 195 | eSelect.innerHTML = ''; |
| 196 | const opt = function(arg){ |
| 197 | const o = document.createElement('option'); |
| 198 | //console.warn(arguments); |
| 199 | let rc = true; |
| 200 | if( 'string' === typeof arg ){ |
| 201 | /* Grouping separator */ |
| 202 | o.innerText = "--- " + arg + " ---"; |
| 203 | o.setAttribute('disabled',''); |
| 204 | rc = false; |
| 205 | }else if( 1===arg.length ){ |
| 206 | o.innerText = arg[0]; |
| 207 | o.value = urlTop + arg[0]; |
| 208 | }else if( 2==arg.length ){ |
| 209 | o.innerText = arg[0]; |
| 210 | o.value = urlTop + arg[1]; |
| 211 | } |
| 212 | eSelect.appendChild(o); |
| 213 | return rc; |
| 214 | }; |
| 215 | let ndx = -1/*index of first non-disabled entry*/, i = 0; |
| 216 | for(const e of j){ |
| 217 | if( opt(e) && ndx<0 ){ |
| 218 | ndx = i; |
| 219 | } |
| 220 | ++i; |
| 221 | } |
| 222 | selectEntry(ndx); |
| 223 | }); |
| 224 | }); |
+68
| --- a/test/link-tester.json | ||
| +++ b/test/link-tester.json | ||
| @@ -0,0 +1,68 @@ | ||
| 1 | +[ | |
| 2 | + "Timelines", | |
| 3 | + ["Default", "/timeline"], | |
| 4 | + ["anonymous", "/timeline?u=anonymous&y=a"], | |
| 5 | + ["after date/time", "/timeline?n=12&y=ci&a=2024-12-31T20:29Z"], | |
| 6 | + ["after hash", "/timeline?n=12&y=ci&a=3cb092c0e2f0ff26"], | |
| 7 | + ["before date/time", "/timeline?n=12&y=ci&b=2024-12-31T20:30Z"], | |
| 8 | + ["before hash", "/timeline?n=12&y=ci&b=3cb092c0e2f0ff26"], | |
| 9 | + ["circa date/time", "/timeline?n=12&y=ci&c=2024-12-31T20:29Z"], | |
| 10 | + ["circa hash", "/timeline?n=12&y=ci&c=3cb092c0e2f0ff26"], | |
| 11 | + ["d=,p=", "/timeline?d=version-2.25&p=version-2.26"], | |
| 12 | + ["from=,ft=", "/timeline?from=2765f04694d36e68&ft=release"], | |
| 13 | + ["from=,ft=,min", "/timeline?from=2765f04694d36e68&ft=release&min"], | |
| 14 | + ["from=,to=", "/timeline?from=version-2.25&to=version-2.26"], | |
| 15 | + ["from=,to=,min", "/timeline?from=version-2.25&to=version-2.26&min"], | |
| 16 | + ["omit-cr branch", "/timeline?r=omit-cr&m&c=7e97f4999b16ab75"], | |
| 17 | + ["diff-eolws branch", "/timeline?r=diff-eolws&n=50"], | |
| 18 | + ["Shortest path (from=,to=)", | |
| 19 | + "/timeline?from=e663bac6f7&to=a298a0e2f9&shortest"], | |
| 20 | + ["Common Ancestor (me=,you=)", | |
| 21 | + "/timeline?me=e663bac6f7&you=a298a0e2f9"], | |
| 22 | + | |
| 23 | + "Diff", | |
| 24 | + ["Multiple edits on a single line", "/info/030035345c#chunk73"], | |
| 25 | + ["Tricky alignment, multiple edits per line", | |
| 26 | + "/fdiff?v1=6da016415dc52d61&v2=af6df3466e3c4a88"], | |
| 27 | + ["Column alignment with multibyte characters", | |
| 28 | + "/fdiff?v1=d1c60722e0b9d775&v2=58d1a8991bacb113"], | |
| 29 | + ["Large diff of sqlite3.c - was once very slow", | |
| 30 | + "/fdiff?v1=57b0d8183cab0e3d&v2=37b3ef49d73cdfe6"], | |
| 31 | + ["A difficult indentation change", "/info/bda00cbada#chunk49"], | |
| 32 | + ["Inverse of the previous", | |
| 33 | + "/fdiff?v1=bc8100c9ee01b8c2&v2=1d2acc1a2a65c2bf#chunk42"], | |
| 34 | + ["Another tricky indentation", | |
| 35 | + "/fdiff?v1=955cc67ace8fb622&v2=e2e1c87b86664b45#chunk13"], | |
| 36 | + ["Inverse of the previous", | |
| 37 | + "/fdiff?v2=955cc67ace8fb622&v1=e2e1c87b86664b45#chunk13"], | |
| 38 | + ["A tricky alignment", | |
| 39 | + "/fdiff?v1=955cc67ace8fb622&v2=e2e1c87b86664b45#chunk24"], | |
| 40 | + ["sqlite3.c changes that are difficult to align", | |
| 41 | + "/fdiff?v1=21f9a00fe2fa4a17&v2=d5c4ff0532bd89c3#chunk5"], | |
| 42 | + ["Lorem Ipsum in Greek", "/fdiff?v1=4f70c682e44f&v2=55659c6e062994f"], | |
| 43 | + ["Inverted Greek Lorem Ipsum", "/fdiff?v2=4f70c682e44f&v1=55659c6e062994f"], | |
| 44 | + | |
| 45 | + "Infos", | |
| 46 | + ["Merge riser coalescing #1", "/info/eed3946bd92a499?diff=0"], | |
| 47 | + ["Merge riser coalescing #2", "/info/ef6979eac9abded?diff=0"], | |
| 48 | + ["Merge riser coalescing #3", "/info/9e1fa626e47f147?diff=0"], | |
| 49 | + ["Merge riser coalescing #4", "/info/68bd2e7bedb8d05?diff=0"], | |
| 50 | + ["Merge riser coalescing #5", "/info/7766e689926c703?diff=0"], | |
| 51 | + ["Merge riser coalescing #6", "/info/3ea66260b5555d2?diff=0"], | |
| 52 | + ["Merge riser coalescing #7", "/info/66ae70a54b20656?diff=0"], | |
| 53 | + ["Context graph #1", "/info/b0f2a0ac53926c9?diff=0"], | |
| 54 | + ["Context graph #2", "/info/303e7af7c31866c?diff=0"], | |
| 55 | + ["Context graph #3", "/info/b31afcc2cab1dc4?diff=0"], | |
| 56 | + ["Context graph #4", "/info/1a164e5fb76a46b?diff=0"], | |
| 57 | + ["Context graph #5", "/info/2d75e87b760c0a9?diff=0"], | |
| 58 | + ["Context graph #6", "/info/76442af7e13267bd?diff=0"], | |
| 59 | + ["Info about the tip", "/info/tip"], | |
| 60 | + ["/info/tip"], | |
| 61 | + | |
| 62 | + "Admin", | |
| 63 | + ["Users", "/setup_ulist"], | |
| 64 | + | |
| 65 | + "Misc.", | |
| 66 | + ["/skins"], | |
| 67 | + ["/chat"] | |
| 68 | +] |
| --- a/test/link-tester.json | |
| +++ b/test/link-tester.json | |
| @@ -0,0 +1,68 @@ | |
| --- a/test/link-tester.json | |
| +++ b/test/link-tester.json | |
| @@ -0,0 +1,68 @@ | |
| 1 | [ |
| 2 | "Timelines", |
| 3 | ["Default", "/timeline"], |
| 4 | ["anonymous", "/timeline?u=anonymous&y=a"], |
| 5 | ["after date/time", "/timeline?n=12&y=ci&a=2024-12-31T20:29Z"], |
| 6 | ["after hash", "/timeline?n=12&y=ci&a=3cb092c0e2f0ff26"], |
| 7 | ["before date/time", "/timeline?n=12&y=ci&b=2024-12-31T20:30Z"], |
| 8 | ["before hash", "/timeline?n=12&y=ci&b=3cb092c0e2f0ff26"], |
| 9 | ["circa date/time", "/timeline?n=12&y=ci&c=2024-12-31T20:29Z"], |
| 10 | ["circa hash", "/timeline?n=12&y=ci&c=3cb092c0e2f0ff26"], |
| 11 | ["d=,p=", "/timeline?d=version-2.25&p=version-2.26"], |
| 12 | ["from=,ft=", "/timeline?from=2765f04694d36e68&ft=release"], |
| 13 | ["from=,ft=,min", "/timeline?from=2765f04694d36e68&ft=release&min"], |
| 14 | ["from=,to=", "/timeline?from=version-2.25&to=version-2.26"], |
| 15 | ["from=,to=,min", "/timeline?from=version-2.25&to=version-2.26&min"], |
| 16 | ["omit-cr branch", "/timeline?r=omit-cr&m&c=7e97f4999b16ab75"], |
| 17 | ["diff-eolws branch", "/timeline?r=diff-eolws&n=50"], |
| 18 | ["Shortest path (from=,to=)", |
| 19 | "/timeline?from=e663bac6f7&to=a298a0e2f9&shortest"], |
| 20 | ["Common Ancestor (me=,you=)", |
| 21 | "/timeline?me=e663bac6f7&you=a298a0e2f9"], |
| 22 | |
| 23 | "Diff", |
| 24 | ["Multiple edits on a single line", "/info/030035345c#chunk73"], |
| 25 | ["Tricky alignment, multiple edits per line", |
| 26 | "/fdiff?v1=6da016415dc52d61&v2=af6df3466e3c4a88"], |
| 27 | ["Column alignment with multibyte characters", |
| 28 | "/fdiff?v1=d1c60722e0b9d775&v2=58d1a8991bacb113"], |
| 29 | ["Large diff of sqlite3.c - was once very slow", |
| 30 | "/fdiff?v1=57b0d8183cab0e3d&v2=37b3ef49d73cdfe6"], |
| 31 | ["A difficult indentation change", "/info/bda00cbada#chunk49"], |
| 32 | ["Inverse of the previous", |
| 33 | "/fdiff?v1=bc8100c9ee01b8c2&v2=1d2acc1a2a65c2bf#chunk42"], |
| 34 | ["Another tricky indentation", |
| 35 | "/fdiff?v1=955cc67ace8fb622&v2=e2e1c87b86664b45#chunk13"], |
| 36 | ["Inverse of the previous", |
| 37 | "/fdiff?v2=955cc67ace8fb622&v1=e2e1c87b86664b45#chunk13"], |
| 38 | ["A tricky alignment", |
| 39 | "/fdiff?v1=955cc67ace8fb622&v2=e2e1c87b86664b45#chunk24"], |
| 40 | ["sqlite3.c changes that are difficult to align", |
| 41 | "/fdiff?v1=21f9a00fe2fa4a17&v2=d5c4ff0532bd89c3#chunk5"], |
| 42 | ["Lorem Ipsum in Greek", "/fdiff?v1=4f70c682e44f&v2=55659c6e062994f"], |
| 43 | ["Inverted Greek Lorem Ipsum", "/fdiff?v2=4f70c682e44f&v1=55659c6e062994f"], |
| 44 | |
| 45 | "Infos", |
| 46 | ["Merge riser coalescing #1", "/info/eed3946bd92a499?diff=0"], |
| 47 | ["Merge riser coalescing #2", "/info/ef6979eac9abded?diff=0"], |
| 48 | ["Merge riser coalescing #3", "/info/9e1fa626e47f147?diff=0"], |
| 49 | ["Merge riser coalescing #4", "/info/68bd2e7bedb8d05?diff=0"], |
| 50 | ["Merge riser coalescing #5", "/info/7766e689926c703?diff=0"], |
| 51 | ["Merge riser coalescing #6", "/info/3ea66260b5555d2?diff=0"], |
| 52 | ["Merge riser coalescing #7", "/info/66ae70a54b20656?diff=0"], |
| 53 | ["Context graph #1", "/info/b0f2a0ac53926c9?diff=0"], |
| 54 | ["Context graph #2", "/info/303e7af7c31866c?diff=0"], |
| 55 | ["Context graph #3", "/info/b31afcc2cab1dc4?diff=0"], |
| 56 | ["Context graph #4", "/info/1a164e5fb76a46b?diff=0"], |
| 57 | ["Context graph #5", "/info/2d75e87b760c0a9?diff=0"], |
| 58 | ["Context graph #6", "/info/76442af7e13267bd?diff=0"], |
| 59 | ["Info about the tip", "/info/tip"], |
| 60 | ["/info/tip"], |
| 61 | |
| 62 | "Admin", |
| 63 | ["Users", "/setup_ulist"], |
| 64 | |
| 65 | "Misc.", |
| 66 | ["/skins"], |
| 67 | ["/chat"] |
| 68 | ] |
+1
-1
| --- www/sync.wiki | ||
| +++ www/sync.wiki | ||
| @@ -1038,11 +1038,11 @@ | ||
| 1038 | 1038 | <ul> |
| 1039 | 1039 | <li> <b>login</b> <i>userid nonce signature</i> |
| 1040 | 1040 | <li> <b>push</b> <i>servercode projectcode</i> |
| 1041 | 1041 | <li> <b>pull</b> <i>servercode projectcode</i> |
| 1042 | 1042 | <li> <b>clone</b> |
| 1043 | - <li> <b>clone_seqno</b> <i>sequence-number</i> | |
| 1043 | + <li> <b>clone</b> <i>protocol-version sequence-number</i> | |
| 1044 | 1044 | <li> <b>file</b> <i>artifact-id size</i> <b>\n</b> <i>content</i> |
| 1045 | 1045 | <li> <b>file</b> <i>artifact-id delta-artifact-id size</i> <b>\n</b> <i>content</i> |
| 1046 | 1046 | <li> <b>cfile</b> <i>artifact-id size</i> <b>\n</b> <i>content</i> |
| 1047 | 1047 | <li> <b>cfile</b> <i>artifact-id delta-artifact-id size</i> <b>\n</b> <i>content</i> |
| 1048 | 1048 | <li> <b>uvfile</b> <i>name mtime hash size flags</i> <b>\n</b> <i>content</i> |
| 1049 | 1049 |
| --- www/sync.wiki | |
| +++ www/sync.wiki | |
| @@ -1038,11 +1038,11 @@ | |
| 1038 | <ul> |
| 1039 | <li> <b>login</b> <i>userid nonce signature</i> |
| 1040 | <li> <b>push</b> <i>servercode projectcode</i> |
| 1041 | <li> <b>pull</b> <i>servercode projectcode</i> |
| 1042 | <li> <b>clone</b> |
| 1043 | <li> <b>clone_seqno</b> <i>sequence-number</i> |
| 1044 | <li> <b>file</b> <i>artifact-id size</i> <b>\n</b> <i>content</i> |
| 1045 | <li> <b>file</b> <i>artifact-id delta-artifact-id size</i> <b>\n</b> <i>content</i> |
| 1046 | <li> <b>cfile</b> <i>artifact-id size</i> <b>\n</b> <i>content</i> |
| 1047 | <li> <b>cfile</b> <i>artifact-id delta-artifact-id size</i> <b>\n</b> <i>content</i> |
| 1048 | <li> <b>uvfile</b> <i>name mtime hash size flags</i> <b>\n</b> <i>content</i> |
| 1049 |
| --- www/sync.wiki | |
| +++ www/sync.wiki | |
| @@ -1038,11 +1038,11 @@ | |
| 1038 | <ul> |
| 1039 | <li> <b>login</b> <i>userid nonce signature</i> |
| 1040 | <li> <b>push</b> <i>servercode projectcode</i> |
| 1041 | <li> <b>pull</b> <i>servercode projectcode</i> |
| 1042 | <li> <b>clone</b> |
| 1043 | <li> <b>clone</b> <i>protocol-version sequence-number</i> |
| 1044 | <li> <b>file</b> <i>artifact-id size</i> <b>\n</b> <i>content</i> |
| 1045 | <li> <b>file</b> <i>artifact-id delta-artifact-id size</i> <b>\n</b> <i>content</i> |
| 1046 | <li> <b>cfile</b> <i>artifact-id size</i> <b>\n</b> <i>content</i> |
| 1047 | <li> <b>cfile</b> <i>artifact-id delta-artifact-id size</i> <b>\n</b> <i>content</i> |
| 1048 | <li> <b>uvfile</b> <i>name mtime hash size flags</i> <b>\n</b> <i>content</i> |
| 1049 |