Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | Update the built-in SQLite to the second 3.35.0 beta, for testing. |
|---|---|
| Downloads: | Tarball | ZIP archive |
| Timelines: | family | ancestors | descendants | both | trunk |
| Files: | files | file ages | folders |
| SHA3-256: |
b46872985550604f02225faf66f6ec8f |
| User & Date: | drh 2021-03-09 21:24:06.149 |
Context
|
2021-03-10
| ||
| 12:34 | Ensure that there is always a newline before a conflict mark in merge output. See the [forum:/forumpost/2e97ca6caa|forum discussion]. check-in: b491c196c2 user: drh tags: trunk | |
|
2021-03-09
| ||
| 21:24 | Update the built-in SQLite to the second 3.35.0 beta, for testing. check-in: b468729855 user: drh tags: trunk | |
|
2021-03-07
| ||
| 21:21 | Avoid NULL pointer deference in the "hook test" command when an invalid hook number is supplied. check-in: 9527034f49 user: drh tags: trunk | |
Changes
Changes to src/shell.c.
| ︙ | ︙ | |||
3636 3637 3638 3639 3640 3641 3642 | ** ****************************************************************************** ** ** This file implements a VFS shim that allows an SQLite database to be ** appended onto the end of some other file, such as an executable. ** ** A special record must appear at the end of the file that identifies the | | > | | | | | < < < | < | | > > | | | | | | | | > | > > > > > > > > > > > > > > > | > > > > > > > > > > > > > > > > > > | > | > | | 3636 3637 3638 3639 3640 3641 3642 3643 3644 3645 3646 3647 3648 3649 3650 3651 3652 3653 3654 3655 3656 3657 3658 3659 3660 3661 3662 3663 3664 3665 3666 3667 3668 3669 3670 3671 3672 3673 3674 3675 3676 3677 3678 3679 3680 3681 3682 3683 3684 3685 3686 3687 3688 3689 3690 3691 3692 3693 3694 3695 3696 3697 3698 3699 3700 3701 3702 3703 3704 3705 3706 3707 3708 3709 3710 3711 3712 3713 3714 3715 3716 3717 3718 3719 3720 3721 3722 3723 3724 3725 3726 3727 3728 3729 3730 3731 3732 3733 3734 3735 3736 3737 3738 3739 3740 3741 3742 3743 3744 3745 3746 3747 3748 3749 3750 3751 3752 3753 3754 3755 3756 3757 |
**
******************************************************************************
**
** This file implements a VFS shim that allows an SQLite database to be
** appended onto the end of some other file, such as an executable.
**
** A special record must appear at the end of the file that identifies the
** file as an appended database and provides the offset to the first page
** of the exposed content. (Or, it is the length of the content prefix.)
** For best performance page 1 should be located at a disk page boundary,
** though that is not required.
**
** When opening a database using this VFS, the connection might treat
** the file as an ordinary SQLite database, or it might treat it as a
** database appended onto some other file. The decision is made by
** applying the following rules in order:
**
** (1) An empty file is an ordinary database.
**
** (2) If the file ends with the appendvfs trailer string
** "Start-Of-SQLite3-NNNNNNNN" that file is an appended database.
**
** (3) If the file begins with the standard SQLite prefix string
** "SQLite format 3", that file is an ordinary database.
**
** (4) If none of the above apply and the SQLITE_OPEN_CREATE flag is
** set, then a new database is appended to the already existing file.
**
** (5) Otherwise, SQLITE_CANTOPEN is returned.
**
** To avoid unnecessary complications with the PENDING_BYTE, the size of
** the file containing the database is limited to 1GB. (1000013824 bytes)
** This VFS will not read or write past the 1GB mark. This restriction
** might be lifted in future versions. For now, if you need a larger
** database, then keep it in a separate file.
**
** If the file being opened is a plain database (not an appended one), then
** this shim is a pass-through into the default underlying VFS. (rule 3)
**/
/* #include "sqlite3ext.h" */
SQLITE_EXTENSION_INIT1
#include <string.h>
#include <assert.h>
/* The append mark at the end of the database is:
**
** Start-Of-SQLite3-NNNNNNNN
** 123456789 123456789 12345
**
** The NNNNNNNN represents a 64-bit big-endian unsigned integer which is
** the offset to page 1, and also the length of the prefix content.
*/
#define APND_MARK_PREFIX "Start-Of-SQLite3-"
#define APND_MARK_PREFIX_SZ 17
#define APND_MARK_FOS_SZ 8
#define APND_MARK_SIZE (APND_MARK_PREFIX_SZ+APND_MARK_FOS_SZ)
/*
** Maximum size of the combined prefix + database + append-mark. This
** must be less than 0x40000000 to avoid locking issues on Windows.
*/
#define APND_MAX_SIZE (65536*15259)
/*
** Size of storage page upon which to align appendvfs portion.
*/
#ifndef APND_ROUNDUP_BITS
#define APND_ROUNDUP_BITS 12
#endif
/*
** Forward declaration of objects used by this utility
*/
typedef struct sqlite3_vfs ApndVfs;
typedef struct ApndFile ApndFile;
/* Access to a lower-level VFS that (might) implement dynamic loading,
** access to randomness, etc.
*/
#define ORIGVFS(p) ((sqlite3_vfs*)((p)->pAppData))
#define ORIGFILE(p) ((sqlite3_file*)(((ApndFile*)(p))+1))
/* Invariants for an open appendvfs file:
* Once an appendvfs file is opened, it will be in one of three states:
* State 0: Never written. Underlying file (if any) is unaltered.
* State 1: Append mark is persisted, content write is in progress.
* State 2: Append mark is persisted, content writes are complete.
*
* State 0 is persistent in the sense that nothing will have been done
* to the underlying file, including any attempt to convert it to an
* appendvfs file.
*
* State 1 is normally transitory. However, if a write operation ends
* abnormally (disk full, power loss, process kill, etc.), then State 1
* may be persistent on disk with an incomplete content write-out. This
* is logically equivalent to an interrupted write to an ordinary file,
* where some unknown portion of to-be-written data is persisted while
* the remainder is not. Database integrity in such cases is maintained
* (or not) by the same measures available for ordinary file access.
*
* State 2 is persistent under normal circumstances (when there is no
* abnormal termination of a write operation such that data provided
* to the underlying VFS write method has not yet reached storage.)
*
* In order to maintain the state invariant, the append mark is written
* in advance of content writes where any part of such content would
* overwrite an existing (or yet to be written) append mark.
*/
struct ApndFile {
/* Access to IO methods of the underlying file */
sqlite3_file base;
/* File offset to beginning of appended content (unchanging) */
sqlite3_int64 iPgOne;
/* File offset of written append-mark, or -1 if unwritten */
sqlite3_int64 iMark;
};
/*
** Methods for ApndFile
*/
static int apndClose(sqlite3_file*);
static int apndRead(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst);
|
| ︙ | ︙ | |||
3800 3801 3802 3803 3804 3805 3806 | apndShmLock, /* xShmLock */ apndShmBarrier, /* xShmBarrier */ apndShmUnmap, /* xShmUnmap */ apndFetch, /* xFetch */ apndUnfetch /* xUnfetch */ }; | < < | | | > > | > > | > > > > > < > | > > > | > > > < | > > < | | < | | < < < | | < < | < | < < < > | < | > > > | < < < < | < | | 3835 3836 3837 3838 3839 3840 3841 3842 3843 3844 3845 3846 3847 3848 3849 3850 3851 3852 3853 3854 3855 3856 3857 3858 3859 3860 3861 3862 3863 3864 3865 3866 3867 3868 3869 3870 3871 3872 3873 3874 3875 3876 3877 3878 3879 3880 3881 3882 3883 3884 3885 3886 3887 3888 3889 3890 3891 3892 3893 3894 3895 3896 3897 3898 3899 3900 3901 3902 3903 3904 3905 3906 3907 3908 3909 3910 3911 3912 3913 3914 3915 3916 3917 3918 3919 3920 3921 3922 3923 3924 3925 3926 3927 3928 3929 3930 3931 3932 3933 3934 3935 3936 3937 3938 3939 3940 3941 3942 3943 3944 3945 3946 3947 3948 3949 |
apndShmLock, /* xShmLock */
apndShmBarrier, /* xShmBarrier */
apndShmUnmap, /* xShmUnmap */
apndFetch, /* xFetch */
apndUnfetch /* xUnfetch */
};
/*
** Close an apnd-file.
*/
static int apndClose(sqlite3_file *pFile){
pFile = ORIGFILE(pFile);
return pFile->pMethods->xClose(pFile);
}
/*
** Read data from an apnd-file.
*/
static int apndRead(
sqlite3_file *pFile,
void *zBuf,
int iAmt,
sqlite_int64 iOfst
){
ApndFile *paf = (ApndFile *)pFile;
pFile = ORIGFILE(pFile);
return pFile->pMethods->xRead(pFile, zBuf, iAmt, paf->iPgOne+iOfst);
}
/*
** Add the append-mark onto what should become the end of the file.
* If and only if this succeeds, internal ApndFile.iMark is updated.
* Parameter iWriteEnd is the appendvfs-relative offset of the new mark.
*/
static int apndWriteMark(
ApndFile *paf,
sqlite3_file *pFile,
sqlite_int64 iWriteEnd
){
sqlite_int64 iPgOne = paf->iPgOne;
unsigned char a[APND_MARK_SIZE];
int i = APND_MARK_FOS_SZ;
int rc;
assert(pFile == ORIGFILE(paf));
memcpy(a, APND_MARK_PREFIX, APND_MARK_PREFIX_SZ);
while (--i >= 0) {
a[APND_MARK_PREFIX_SZ+i] = (unsigned char)(iPgOne & 0xff);
iPgOne >>= 8;
}
iWriteEnd += paf->iPgOne;
if( SQLITE_OK==(rc = pFile->pMethods->xWrite
(pFile, a, APND_MARK_SIZE, iWriteEnd)) ){
paf->iMark = iWriteEnd;
}
return rc;
}
/*
** Write data to an apnd-file.
*/
static int apndWrite(
sqlite3_file *pFile,
const void *zBuf,
int iAmt,
sqlite_int64 iOfst
){
ApndFile *paf = (ApndFile *)pFile;
sqlite_int64 iWriteEnd = iOfst + iAmt;
if( iWriteEnd>=APND_MAX_SIZE ) return SQLITE_FULL;
pFile = ORIGFILE(pFile);
/* If append-mark is absent or will be overwritten, write it. */
if( paf->iMark < 0 || paf->iPgOne + iWriteEnd > paf->iMark ){
int rc = apndWriteMark(paf, pFile, iWriteEnd);
if( SQLITE_OK!=rc )
return rc;
}
return pFile->pMethods->xWrite(pFile, zBuf, iAmt, paf->iPgOne+iOfst);
}
/*
** Truncate an apnd-file.
*/
static int apndTruncate(sqlite3_file *pFile, sqlite_int64 size){
ApndFile *paf = (ApndFile *)pFile;
pFile = ORIGFILE(pFile);
/* The append mark goes out first so truncate failure does not lose it. */
if( SQLITE_OK!=apndWriteMark(paf, pFile, size) )
return SQLITE_IOERR;
/* Truncate underlying file just past append mark */
return pFile->pMethods->xTruncate(pFile, paf->iMark+APND_MARK_SIZE);
}
/*
** Sync an apnd-file.
*/
static int apndSync(sqlite3_file *pFile, int flags){
pFile = ORIGFILE(pFile);
return pFile->pMethods->xSync(pFile, flags);
}
/*
** Return the current file-size of an apnd-file.
** If the append mark is not yet there, the file-size is 0.
*/
static int apndFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){
ApndFile *paf = (ApndFile *)pFile;
*pSize = ( paf->iMark >= 0 )? (paf->iMark - paf->iPgOne) : 0;
return SQLITE_OK;
}
/*
** Lock an apnd-file.
*/
static int apndLock(sqlite3_file *pFile, int eLock){
pFile = ORIGFILE(pFile);
|
| ︙ | ︙ | |||
3930 3931 3932 3933 3934 3935 3936 |
return pFile->pMethods->xCheckReservedLock(pFile, pResOut);
}
/*
** File control method. For custom operations on an apnd-file.
*/
static int apndFileControl(sqlite3_file *pFile, int op, void *pArg){
| | | | 3966 3967 3968 3969 3970 3971 3972 3973 3974 3975 3976 3977 3978 3979 3980 3981 3982 3983 3984 3985 |
return pFile->pMethods->xCheckReservedLock(pFile, pResOut);
}
/*
** File control method. For custom operations on an apnd-file.
*/
static int apndFileControl(sqlite3_file *pFile, int op, void *pArg){
ApndFile *paf = (ApndFile *)pFile;
int rc;
pFile = ORIGFILE(pFile);
rc = pFile->pMethods->xFileControl(pFile, op, pArg);
if( rc==SQLITE_OK && op==SQLITE_FCNTL_VFSNAME ){
*(char**)pArg = sqlite3_mprintf("apnd(%lld)/%z", paf->iPgOne,*(char**)pArg);
}
return rc;
}
/*
** Return the sector-size in bytes for an apnd-file.
*/
|
| ︙ | ︙ | |||
3994 3995 3996 3997 3998 3999 4000 4001 4002 4003 4004 4005 4006 4007 4008 4009 4010 4011 4012 |
static int apndFetch(
sqlite3_file *pFile,
sqlite3_int64 iOfst,
int iAmt,
void **pp
){
ApndFile *p = (ApndFile *)pFile;
pFile = ORIGFILE(pFile);
return pFile->pMethods->xFetch(pFile, iOfst+p->iPgOne, iAmt, pp);
}
/* Release a memory-mapped page */
static int apndUnfetch(sqlite3_file *pFile, sqlite3_int64 iOfst, void *pPage){
ApndFile *p = (ApndFile *)pFile;
pFile = ORIGFILE(pFile);
return pFile->pMethods->xUnfetch(pFile, iOfst+p->iPgOne, pPage);
}
/*
| > > < < < < < < < < < < < < < | | > > > > > | | | > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | > > > > > > > | | > > > > > > > | 4030 4031 4032 4033 4034 4035 4036 4037 4038 4039 4040 4041 4042 4043 4044 4045 4046 4047 4048 4049 4050 4051 4052 4053 4054 4055 4056 4057 4058 4059 4060 4061 4062 4063 4064 4065 4066 4067 4068 4069 4070 4071 4072 4073 4074 4075 4076 4077 4078 4079 4080 4081 4082 4083 4084 4085 4086 4087 4088 4089 4090 4091 4092 4093 4094 4095 4096 4097 4098 4099 4100 4101 4102 4103 4104 4105 4106 4107 4108 4109 4110 4111 4112 4113 4114 4115 4116 4117 4118 4119 4120 4121 4122 4123 4124 4125 4126 4127 4128 4129 4130 4131 4132 4133 4134 4135 4136 4137 4138 4139 4140 4141 4142 4143 4144 4145 4146 4147 4148 4149 4150 4151 4152 4153 4154 4155 4156 4157 4158 4159 4160 4161 4162 4163 4164 4165 4166 4167 4168 4169 4170 4171 4172 4173 4174 4175 4176 4177 4178 4179 4180 4181 4182 4183 4184 4185 4186 4187 4188 4189 4190 4191 4192 4193 4194 4195 4196 4197 4198 4199 4200 |
static int apndFetch(
sqlite3_file *pFile,
sqlite3_int64 iOfst,
int iAmt,
void **pp
){
ApndFile *p = (ApndFile *)pFile;
if( p->iMark < 0 || iOfst+iAmt > p->iMark)
return SQLITE_IOERR; /* Cannot read what is not yet there. */
pFile = ORIGFILE(pFile);
return pFile->pMethods->xFetch(pFile, iOfst+p->iPgOne, iAmt, pp);
}
/* Release a memory-mapped page */
static int apndUnfetch(sqlite3_file *pFile, sqlite3_int64 iOfst, void *pPage){
ApndFile *p = (ApndFile *)pFile;
pFile = ORIGFILE(pFile);
return pFile->pMethods->xUnfetch(pFile, iOfst+p->iPgOne, pPage);
}
/*
** Try to read the append-mark off the end of a file. Return the
** start of the appended database if the append-mark is present.
** If there is no valid append-mark, return -1;
**
** An append-mark is only valid if the NNNNNNNN start-of-database offset
** indicates that the appended database contains at least one page. The
** start-of-database value must be a multiple of 512.
*/
static sqlite3_int64 apndReadMark(sqlite3_int64 sz, sqlite3_file *pFile){
int rc, i;
sqlite3_int64 iMark;
int msbs = 8 * (APND_MARK_FOS_SZ-1);
unsigned char a[APND_MARK_SIZE];
if( APND_MARK_SIZE!=(sz & 0x1ff) ) return -1;
rc = pFile->pMethods->xRead(pFile, a, APND_MARK_SIZE, sz-APND_MARK_SIZE);
if( rc ) return -1;
if( memcmp(a, APND_MARK_PREFIX, APND_MARK_PREFIX_SZ)!=0 ) return -1;
iMark = ((sqlite3_int64)(a[APND_MARK_PREFIX_SZ] & 0x7f)) << msbs;
for(i=1; i<8; i++){
msbs -= 8;
iMark |= (sqlite3_int64)a[APND_MARK_PREFIX_SZ+i]<<msbs;
}
if( iMark > (sz - APND_MARK_SIZE - 512) ) return -1;
if( iMark & 0x1ff ) return -1;
return iMark;
}
static const char apvfsSqliteHdr[] = "SQLite format 3";
/*
** Check to see if the file is an appendvfs SQLite database file.
** Return true iff it is such. Parameter sz is the file's size.
*/
static int apndIsAppendvfsDatabase(sqlite3_int64 sz, sqlite3_file *pFile){
int rc;
char zHdr[16];
sqlite3_int64 iMark = apndReadMark(sz, pFile);
if( iMark>=0 ){
/* If file has right end-marker, the expected odd size, and the
* SQLite DB type marker where the end-marker puts it, then it
* is an appendvfs database (to be treated as such.)
*/
rc = pFile->pMethods->xRead(pFile, zHdr, sizeof(zHdr), iMark);
if( SQLITE_OK==rc && memcmp(zHdr, apvfsSqliteHdr, sizeof(zHdr))==0
&& (sz & 0x1ff)== APND_MARK_SIZE && sz>=512+APND_MARK_SIZE )
return 1; /* It's an appendvfs database */
}
return 0;
}
/*
** Check to see if the file is an ordinary SQLite database file.
** Return true iff so. Parameter sz is the file's size.
*/
static int apndIsOrdinaryDatabaseFile(sqlite3_int64 sz, sqlite3_file *pFile){
char zHdr[16];
if( apndIsAppendvfsDatabase(sz, pFile) /* rule 2 */
|| (sz & 0x1ff) != 0
|| SQLITE_OK!=pFile->pMethods->xRead(pFile, zHdr, sizeof(zHdr), 0)
|| memcmp(zHdr, apvfsSqliteHdr, sizeof(zHdr))!=0
){
return 0;
}else{
return 1;
}
}
/* Round-up used to get appendvfs portion to begin at a page boundary. */
#define APND_ALIGN_MASK(nbits) ((1<<nbits)-1)
#define APND_START_ROUNDUP(fsz, nbits) \
( ((fsz)+APND_ALIGN_MASK(nbits)) & ~(sqlite3_int64)APND_ALIGN_MASK(nbits) )
/*
** Open an apnd file handle.
*/
static int apndOpen(
sqlite3_vfs *pVfs,
const char *zName,
sqlite3_file *pFile,
int flags,
int *pOutFlags
){
ApndFile *p;
sqlite3_file *pSubFile;
sqlite3_vfs *pSubVfs;
int rc;
sqlite3_int64 sz;
pSubVfs = ORIGVFS(pVfs);
if( (flags & SQLITE_OPEN_MAIN_DB)==0 ){
/* The appendvfs is not to be used for transient or temporary databases. */
return pSubVfs->xOpen(pSubVfs, zName, pFile, flags, pOutFlags);
}
p = (ApndFile*)pFile;
memset(p, 0, sizeof(*p));
pSubFile = ORIGFILE(pFile);
pFile->pMethods = &apnd_io_methods;
rc = pSubVfs->xOpen(pSubVfs, zName, pSubFile, flags, pOutFlags);
if( rc ) goto apnd_open_done;
rc = pSubFile->pMethods->xFileSize(pSubFile, &sz);
if( rc ){
pSubFile->pMethods->xClose(pSubFile);
goto apnd_open_done;
}
if( apndIsOrdinaryDatabaseFile(sz, pSubFile) ){
memmove(pFile, pSubFile, pSubVfs->szOsFile);
return SQLITE_OK;
}
/* Record that append mark has not been written until seen otherwise. */
p->iMark = -1;
p->iPgOne = apndReadMark(sz, pFile);
if( p->iPgOne>=0 ){
/* Append mark was found, infer its offset */
p->iMark = sz - p->iPgOne - APND_MARK_SIZE;
return SQLITE_OK;
}
if( (flags & SQLITE_OPEN_CREATE)==0 ){
pSubFile->pMethods->xClose(pSubFile);
rc = SQLITE_CANTOPEN;
}
/* Round newly added appendvfs location to #define'd page boundary.
* Note that nothing has yet been written to the underlying file.
* The append mark will be written along with first content write.
* Until then, the p->iMark value indicates it is not yet written.
*/
p->iPgOne = APND_START_ROUNDUP(sz, APND_ROUNDUP_BITS);
apnd_open_done:
if( rc ) pFile->pMethods = 0;
return rc;
}
/*
** Delete an apnd file.
** For an appendvfs, this could mean delete the appendvfs portion,
** leaving the appendee as it was before it gained an appendvfs.
** For now, this code deletes the underlying file too.
*/
static int apndDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
return ORIGVFS(pVfs)->xDelete(ORIGVFS(pVfs), zPath, dirSync);
}
/*
** All other VFS methods are pass-thrus.
*/
static int apndAccess(
sqlite3_vfs *pVfs,
const char *zPath,
int flags,
int *pResOut
){
return ORIGVFS(pVfs)->xAccess(ORIGVFS(pVfs), zPath, flags, pResOut);
|
| ︙ | ︙ | |||
5200 5201 5202 5203 5204 5205 5206 5207 5208 5209 5210 5211 5212 5213 |
}
}else{
sqlite3_int64 m, e, a;
double r;
int isNeg = 0;
m = sqlite3_value_int64(argv[0]);
e = sqlite3_value_int64(argv[1]);
if( m<0 ){
isNeg = 1;
m = -m;
if( m<0 ) return;
}else if( m==0 && e>-1000 && e<1000 ){
sqlite3_result_double(context, 0.0);
return;
| > > > > > > > > | 5293 5294 5295 5296 5297 5298 5299 5300 5301 5302 5303 5304 5305 5306 5307 5308 5309 5310 5311 5312 5313 5314 |
}
}else{
sqlite3_int64 m, e, a;
double r;
int isNeg = 0;
m = sqlite3_value_int64(argv[0]);
e = sqlite3_value_int64(argv[1]);
/* Limit the range of e. Ticket 22dea1cfdb9151e4 2021-03-02 */
if( e>10000 ){
e = 10000;
}else if( e<-10000 ){
e = -10000;
}
if( m<0 ){
isNeg = 1;
m = -m;
if( m<0 ) return;
}else if( m==0 && e>-1000 && e<1000 ){
sqlite3_result_double(context, 0.0);
return;
|
| ︙ | ︙ | |||
20863 20864 20865 20866 20867 20868 20869 |
argv[0], argv[argc-1]);
exit(1);
}
return argv[i];
}
#ifndef SQLITE_SHELL_IS_UTF8
| | > | 20964 20965 20966 20967 20968 20969 20970 20971 20972 20973 20974 20975 20976 20977 20978 20979 |
argv[0], argv[argc-1]);
exit(1);
}
return argv[i];
}
#ifndef SQLITE_SHELL_IS_UTF8
# if (defined(_WIN32) || defined(WIN32)) \
&& (defined(_MSC_VER) || (defined(UNICODE) && defined(__GNUC__)))
# define SQLITE_SHELL_IS_UTF8 (0)
# else
# define SQLITE_SHELL_IS_UTF8 (1)
# endif
#endif
#if SQLITE_SHELL_IS_UTF8
|
| ︙ | ︙ |
Changes to src/sqlite3.c.
| ︙ | ︙ | |||
1184 1185 1186 1187 1188 1189 1190 | ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ #define SQLITE_VERSION "3.35.0" #define SQLITE_VERSION_NUMBER 3035000 | | | 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 | ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ #define SQLITE_VERSION "3.35.0" #define SQLITE_VERSION_NUMBER 3035000 #define SQLITE_SOURCE_ID "2021-03-09 21:20:12 9645fe1a050e8b61aea1fba2f142819c387ecb043741392c5719bf7ad303bf8b" /* ** CAPI3REF: Run-Time Library Version Numbers ** KEYWORDS: sqlite3_version sqlite3_sourceid ** ** These interfaces provide the same information as the [SQLITE_VERSION], ** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros |
| ︙ | ︙ | |||
3191 3192 3193 3194 3195 3196 3197 | ** <dd> ^This option is used to enable or disable [CREATE VIEW | views]. ** There should be two additional arguments. ** The first argument is an integer which is 0 to disable views, ** positive to enable views or negative to leave the setting unchanged. ** The second parameter is a pointer to an integer into which ** is written 0 or 1 to indicate whether views are disabled or enabled ** following this call. The second parameter may be a NULL pointer, in | | > > > > > > | 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 3204 3205 3206 3207 3208 3209 3210 3211 | ** <dd> ^This option is used to enable or disable [CREATE VIEW | views]. ** There should be two additional arguments. ** The first argument is an integer which is 0 to disable views, ** positive to enable views or negative to leave the setting unchanged. ** The second parameter is a pointer to an integer into which ** is written 0 or 1 to indicate whether views are disabled or enabled ** following this call. The second parameter may be a NULL pointer, in ** which case the view setting is not reported back. ** ** <p>Originally this option disabled all views. ^(However, since ** SQLite version 3.35.0, TEMP views are still allowed even if ** this option is off. So, in other words, this option now only disables ** views in the main database schema or in the schemas of ATTACH-ed ** databases.)^ </dd> ** ** [[SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER]] ** <dt>SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER</dt> ** <dd> ^This option is used to enable or disable the ** [fts3_tokenizer()] function which is part of the ** [FTS3] full-text search engine extension. ** There should be two additional arguments. |
| ︙ | ︙ | |||
15366 15367 15368 15369 15370 15371 15372 | SQLITE_PRIVATE int sqlite3BtreeCursorRestore(BtCursor*, int*); SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor*, u8 flags); /* Allowed flags for sqlite3BtreeDelete() and sqlite3BtreeInsert() */ #define BTREE_SAVEPOSITION 0x02 /* Leave cursor pointing at NEXT or PREV */ #define BTREE_AUXDELETE 0x04 /* not the primary delete operation */ #define BTREE_APPEND 0x08 /* Insert is likely an append */ | | | 15372 15373 15374 15375 15376 15377 15378 15379 15380 15381 15382 15383 15384 15385 15386 | SQLITE_PRIVATE int sqlite3BtreeCursorRestore(BtCursor*, int*); SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor*, u8 flags); /* Allowed flags for sqlite3BtreeDelete() and sqlite3BtreeInsert() */ #define BTREE_SAVEPOSITION 0x02 /* Leave cursor pointing at NEXT or PREV */ #define BTREE_AUXDELETE 0x04 /* not the primary delete operation */ #define BTREE_APPEND 0x08 /* Insert is likely an append */ #define BTREE_PREFORMAT 0x80 /* Inserted data is a preformated cell */ /* An instance of the BtreePayload object describes the content of a single ** entry in either an index or table btree. ** ** Index btrees (used for indexes and also WITHOUT ROWID tables) contain ** an arbitrary key and no data. These btrees have pKey,nKey set to the ** key and the pData,nData,nZero fields are uninitialized. The aMem,nMem |
| ︙ | ︙ | |||
20254 20255 20256 20257 20258 20259 20260 20261 20262 20263 20264 20265 20266 20267 | SQLITE_PRIVATE Schema *sqlite3SchemaGet(sqlite3 *, Btree *); SQLITE_PRIVATE int sqlite3SchemaToIndex(sqlite3 *db, Schema *); SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoAlloc(sqlite3*,int,int); SQLITE_PRIVATE void sqlite3KeyInfoUnref(KeyInfo*); SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoRef(KeyInfo*); SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoOfIndex(Parse*, Index*); SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoFromExprList(Parse*, ExprList*, int, int); SQLITE_PRIVATE int sqlite3HasExplicitNulls(Parse*, ExprList*); #ifdef SQLITE_DEBUG SQLITE_PRIVATE int sqlite3KeyInfoIsWriteable(KeyInfo*); #endif SQLITE_PRIVATE int sqlite3CreateFunc(sqlite3 *, const char *, int, int, void *, void (*)(sqlite3_context*,int,sqlite3_value **), | > | 20260 20261 20262 20263 20264 20265 20266 20267 20268 20269 20270 20271 20272 20273 20274 | SQLITE_PRIVATE Schema *sqlite3SchemaGet(sqlite3 *, Btree *); SQLITE_PRIVATE int sqlite3SchemaToIndex(sqlite3 *db, Schema *); SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoAlloc(sqlite3*,int,int); SQLITE_PRIVATE void sqlite3KeyInfoUnref(KeyInfo*); SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoRef(KeyInfo*); SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoOfIndex(Parse*, Index*); SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoFromExprList(Parse*, ExprList*, int, int); SQLITE_PRIVATE const char *sqlite3SelectOpName(int); SQLITE_PRIVATE int sqlite3HasExplicitNulls(Parse*, ExprList*); #ifdef SQLITE_DEBUG SQLITE_PRIVATE int sqlite3KeyInfoIsWriteable(KeyInfo*); #endif SQLITE_PRIVATE int sqlite3CreateFunc(sqlite3 *, const char *, int, int, void *, void (*)(sqlite3_context*,int,sqlite3_value **), |
| ︙ | ︙ | |||
29328 29329 29330 29331 29332 29333 29334 |
}
if( p->mxAlloc==0 ){
setStrAccumError(p, SQLITE_TOOBIG);
return p->nAlloc - p->nChar - 1;
}else{
char *zOld = isMalloced(p) ? p->zText : 0;
i64 szNew = p->nChar;
| | | 29335 29336 29337 29338 29339 29340 29341 29342 29343 29344 29345 29346 29347 29348 29349 |
}
if( p->mxAlloc==0 ){
setStrAccumError(p, SQLITE_TOOBIG);
return p->nAlloc - p->nChar - 1;
}else{
char *zOld = isMalloced(p) ? p->zText : 0;
i64 szNew = p->nChar;
szNew += (sqlite3_int64)N + 1;
if( szNew+p->nChar<=p->mxAlloc ){
/* Force exponential buffer size growth as long as it does not overflow,
** to avoid having to call this routine too often */
szNew += p->nChar;
}
if( szNew > p->mxAlloc ){
sqlite3_str_reset(p);
|
| ︙ | ︙ | |||
87393 87394 87395 87396 87397 87398 87399 |
** non-zero. The P2 opcode must be 1.
*/
case OP_ChngCntRow: {
assert( pOp->p2==1 );
if( (rc = sqlite3VdbeCheckFk(p,0))!=SQLITE_OK ){
goto abort_due_to_error;
}
| | | 87400 87401 87402 87403 87404 87405 87406 87407 87408 87409 87410 87411 87412 87413 87414 |
** non-zero. The P2 opcode must be 1.
*/
case OP_ChngCntRow: {
assert( pOp->p2==1 );
if( (rc = sqlite3VdbeCheckFk(p,0))!=SQLITE_OK ){
goto abort_due_to_error;
}
/* Fall through to the next case, OP_ResultRow */
/* no break */ deliberate_fall_through
}
/* Opcode: ResultRow P1 P2 * * *
** Synopsis: output=r[P1@P2]
**
** The registers P1 through P1+P2-1 contain a single row of
|
| ︙ | ︙ | |||
98167 98168 98169 98170 98171 98172 98173 |
memjrnlFreeChunks(p->pFirst);
p->pFirst = 0;
}else{
i64 iOff = p->nChunkSize;
for(pIter=p->pFirst; ALWAYS(pIter) && iOff<=size; pIter=pIter->pNext){
iOff += p->nChunkSize;
}
| | | 98174 98175 98176 98177 98178 98179 98180 98181 98182 98183 98184 98185 98186 98187 98188 |
memjrnlFreeChunks(p->pFirst);
p->pFirst = 0;
}else{
i64 iOff = p->nChunkSize;
for(pIter=p->pFirst; ALWAYS(pIter) && iOff<=size; pIter=pIter->pNext){
iOff += p->nChunkSize;
}
if( ALWAYS(pIter) ){
memjrnlFreeChunks(pIter->pNext);
pIter->pNext = 0;
}
}
p->endpoint.pChunk = pIter;
p->endpoint.iOffset = size;
|
| ︙ | ︙ | |||
99004 99005 99006 99007 99008 99009 99010 99011 99012 99013 99014 99015 99016 99017 99018 99019 99020 99021 99022 99023 99024 99025 99026 99027 99028 |
}
if( iCol>=pTab->nCol && sqlite3IsRowid(zCol) && VisibleRowid(pTab) ){
/* IMP: R-51414-32910 */
iCol = -1;
}
if( iCol<pTab->nCol ){
cnt++;
#ifndef SQLITE_OMIT_UPSERT
if( pExpr->iTable==EXCLUDED_TABLE_NUMBER ){
testcase( iCol==(-1) );
if( IN_RENAME_OBJECT ){
pExpr->iColumn = iCol;
pExpr->y.pTab = pTab;
eNewExprOp = TK_COLUMN;
}else{
pExpr->iTable = pNC->uNC.pUpsert->regData +
sqlite3TableColumnToStorage(pTab, iCol);
eNewExprOp = TK_REGISTER;
}
}else
#endif /* SQLITE_OMIT_UPSERT */
{
pExpr->y.pTab = pTab;
if( pParse->bReturning ){
eNewExprOp = TK_REGISTER;
| > | | | 99011 99012 99013 99014 99015 99016 99017 99018 99019 99020 99021 99022 99023 99024 99025 99026 99027 99028 99029 99030 99031 99032 99033 99034 99035 99036 99037 99038 99039 99040 99041 99042 99043 99044 99045 |
}
if( iCol>=pTab->nCol && sqlite3IsRowid(zCol) && VisibleRowid(pTab) ){
/* IMP: R-51414-32910 */
iCol = -1;
}
if( iCol<pTab->nCol ){
cnt++;
pMatch = 0;
#ifndef SQLITE_OMIT_UPSERT
if( pExpr->iTable==EXCLUDED_TABLE_NUMBER ){
testcase( iCol==(-1) );
if( IN_RENAME_OBJECT ){
pExpr->iColumn = iCol;
pExpr->y.pTab = pTab;
eNewExprOp = TK_COLUMN;
}else{
pExpr->iTable = pNC->uNC.pUpsert->regData +
sqlite3TableColumnToStorage(pTab, iCol);
eNewExprOp = TK_REGISTER;
}
}else
#endif /* SQLITE_OMIT_UPSERT */
{
pExpr->y.pTab = pTab;
if( pParse->bReturning ){
eNewExprOp = TK_REGISTER;
pExpr->iTable = pNC->uNC.iBaseReg + (pTab->nCol+1)*pExpr->iTable +
sqlite3TableColumnToStorage(pTab, iCol) + 1;
}else{
pExpr->iColumn = (i16)iCol;
eNewExprOp = TK_TRIGGER;
#ifndef SQLITE_OMIT_TRIGGER
if( iCol<0 ){
pExpr->affExpr = SQLITE_AFF_INTEGER;
}else if( pExpr->iTable==0 ){
|
| ︙ | ︙ | |||
99223 99224 99225 99226 99227 99228 99229 99230 99231 99232 99233 99234 99235 99236 99237 99238 99239 99240 99241 |
pExpr->pRight = 0;
}
pExpr->op = eNewExprOp;
ExprSetProperty(pExpr, EP_Leaf);
lookupname_end:
if( cnt==1 ){
assert( pNC!=0 );
if( pParse->db->xAuth
&& (pExpr->op==TK_COLUMN || pExpr->op==TK_TRIGGER)
){
sqlite3AuthRead(pParse, pExpr, pSchema, pNC->pSrcList);
}
/* Increment the nRef value on all name contexts from TopNC up to
** the point where the name matched. */
for(;;){
assert( pTopNC!=0 );
pTopNC->nRef++;
if( pTopNC==pNC ) break;
pTopNC = pTopNC->pNext;
| > > | 99231 99232 99233 99234 99235 99236 99237 99238 99239 99240 99241 99242 99243 99244 99245 99246 99247 99248 99249 99250 99251 |
pExpr->pRight = 0;
}
pExpr->op = eNewExprOp;
ExprSetProperty(pExpr, EP_Leaf);
lookupname_end:
if( cnt==1 ){
assert( pNC!=0 );
#ifndef SQLITE_OMIT_AUTHORIZATION
if( pParse->db->xAuth
&& (pExpr->op==TK_COLUMN || pExpr->op==TK_TRIGGER)
){
sqlite3AuthRead(pParse, pExpr, pSchema, pNC->pSrcList);
}
#endif
/* Increment the nRef value on all name contexts from TopNC up to
** the point where the name matched. */
for(;;){
assert( pTopNC!=0 );
pTopNC->nRef++;
if( pTopNC==pNC ) break;
pTopNC = pTopNC->pNext;
|
| ︙ | ︙ | |||
99372 99373 99374 99375 99376 99377 99378 |
pExpr->y.pTab = pItem->pTab;
pExpr->iTable = pItem->iCursor;
pExpr->iColumn--;
pExpr->affExpr = SQLITE_AFF_INTEGER;
break;
}
| | > | < | | > > | | | > | | | 99382 99383 99384 99385 99386 99387 99388 99389 99390 99391 99392 99393 99394 99395 99396 99397 99398 99399 99400 99401 99402 99403 99404 99405 99406 99407 99408 99409 99410 99411 99412 99413 99414 99415 99416 99417 99418 99419 |
pExpr->y.pTab = pItem->pTab;
pExpr->iTable = pItem->iCursor;
pExpr->iColumn--;
pExpr->affExpr = SQLITE_AFF_INTEGER;
break;
}
/* An optimization: Attempt to convert
**
** "expr IS NOT NULL" --> "TRUE"
** "expr IS NULL" --> "FALSE"
**
** if we can prove that "expr" is never NULL. Call this the
** "NOT NULL strength reduction optimization".
**
** If this optimization occurs, also restore the NameContext ref-counts
** to the state they where in before the "column" LHS expression was
** resolved. This prevents "column" from being counted as having been
** referenced, which might prevent a SELECT from being erroneously
** marked as correlated.
*/
case TK_NOTNULL:
case TK_ISNULL: {
int anRef[8];
NameContext *p;
int i;
for(i=0, p=pNC; p && i<ArraySize(anRef); p=p->pNext, i++){
anRef[i] = p->nRef;
}
sqlite3WalkExpr(pWalker, pExpr->pLeft);
if( 0==sqlite3ExprCanBeNull(pExpr->pLeft) && !IN_RENAME_OBJECT ){
if( pExpr->op==TK_NOTNULL ){
pExpr->u.zToken = "true";
ExprSetProperty(pExpr, EP_IsTrue);
}else{
pExpr->u.zToken = "false";
ExprSetProperty(pExpr, EP_IsFalse);
}
|
| ︙ | ︙ | |||
99637 99638 99639 99640 99641 99642 99643 99644 99645 99646 99647 99648 99649 99650 |
if( is_agg ){
#ifndef SQLITE_OMIT_WINDOWFUNC
if( pWin ){
Select *pSel = pNC->pWinSelect;
assert( pWin==pExpr->y.pWin );
if( IN_RENAME_OBJECT==0 ){
sqlite3WindowUpdate(pParse, pSel ? pSel->pWinDefn : 0, pWin, pDef);
}
sqlite3WalkExprList(pWalker, pWin->pPartition);
sqlite3WalkExprList(pWalker, pWin->pOrderBy);
sqlite3WalkExpr(pWalker, pWin->pFilter);
sqlite3WindowLink(pSel, pWin);
pNC->ncFlags |= NC_HasWin;
}else
| > | 99650 99651 99652 99653 99654 99655 99656 99657 99658 99659 99660 99661 99662 99663 99664 |
if( is_agg ){
#ifndef SQLITE_OMIT_WINDOWFUNC
if( pWin ){
Select *pSel = pNC->pWinSelect;
assert( pWin==pExpr->y.pWin );
if( IN_RENAME_OBJECT==0 ){
sqlite3WindowUpdate(pParse, pSel ? pSel->pWinDefn : 0, pWin, pDef);
if( pParse->db->mallocFailed ) break;
}
sqlite3WalkExprList(pWalker, pWin->pPartition);
sqlite3WalkExprList(pWalker, pWin->pOrderBy);
sqlite3WalkExpr(pWalker, pWin->pFilter);
sqlite3WindowLink(pSel, pWin);
pNC->ncFlags |= NC_HasWin;
}else
|
| ︙ | ︙ | |||
99711 99712 99713 99714 99715 99716 99717 |
}
case TK_IS:
case TK_ISNOT: {
Expr *pRight = sqlite3ExprSkipCollateAndLikely(pExpr->pRight);
assert( !ExprHasProperty(pExpr, EP_Reduced) );
/* Handle special cases of "x IS TRUE", "x IS FALSE", "x IS NOT TRUE",
** and "x IS NOT FALSE". */
| | | 99725 99726 99727 99728 99729 99730 99731 99732 99733 99734 99735 99736 99737 99738 99739 |
}
case TK_IS:
case TK_ISNOT: {
Expr *pRight = sqlite3ExprSkipCollateAndLikely(pExpr->pRight);
assert( !ExprHasProperty(pExpr, EP_Reduced) );
/* Handle special cases of "x IS TRUE", "x IS FALSE", "x IS NOT TRUE",
** and "x IS NOT FALSE". */
if( ALWAYS(pRight) && (pRight->op==TK_ID || pRight->op==TK_TRUEFALSE) ){
int rc = resolveExprStep(pWalker, pRight);
if( rc==WRC_Abort ) return WRC_Abort;
if( pRight->op==TK_TRUEFALSE ){
pExpr->op2 = pExpr->op;
pExpr->op = TK_TRUTH;
return WRC_Continue;
}
|
| ︙ | ︙ | |||
107940 107941 107942 107943 107944 107945 107946 |
if( rc==SQLITE_OK && pStep->pWhere ){
rc = sqlite3ResolveExprNames(&sNC, pStep->pWhere);
}
if( rc==SQLITE_OK ){
rc = sqlite3ResolveExprListNames(&sNC, pStep->pExprList);
}
assert( !pStep->pUpsert || (!pStep->pWhere && !pStep->pExprList) );
| | < | 107954 107955 107956 107957 107958 107959 107960 107961 107962 107963 107964 107965 107966 107967 107968 107969 |
if( rc==SQLITE_OK && pStep->pWhere ){
rc = sqlite3ResolveExprNames(&sNC, pStep->pWhere);
}
if( rc==SQLITE_OK ){
rc = sqlite3ResolveExprListNames(&sNC, pStep->pExprList);
}
assert( !pStep->pUpsert || (!pStep->pWhere && !pStep->pExprList) );
if( pStep->pUpsert && rc==SQLITE_OK ){
Upsert *pUpsert = pStep->pUpsert;
pUpsert->pUpsertSrc = pSrc;
sNC.uNC.pUpsert = pUpsert;
sNC.ncFlags = NC_UUpsert;
rc = sqlite3ResolveExprListNames(&sNC, pUpsert->pUpsertTarget);
if( rc==SQLITE_OK ){
ExprList *pUpsertSet = pUpsert->pUpsertSet;
rc = sqlite3ResolveExprListNames(&sNC, pUpsertSet);
|
| ︙ | ︙ | |||
108502 108503 108504 108505 108506 108507 108508 108509 108510 108511 | char *zNew = 0; #ifndef SQLITE_OMIT_AUTHORIZATION sqlite3_xauth xAuth = db->xAuth; db->xAuth = 0; #endif rc = renameParseSql(&sParse, zDb, db, zSql, iSchema==1); if( rc!=SQLITE_OK ) goto drop_column_done; pTab = sParse.pNewTable; | > | | 108515 108516 108517 108518 108519 108520 108521 108522 108523 108524 108525 108526 108527 108528 108529 108530 108531 108532 108533 |
char *zNew = 0;
#ifndef SQLITE_OMIT_AUTHORIZATION
sqlite3_xauth xAuth = db->xAuth;
db->xAuth = 0;
#endif
UNUSED_PARAMETER(NotUsed);
rc = renameParseSql(&sParse, zDb, db, zSql, iSchema==1);
if( rc!=SQLITE_OK ) goto drop_column_done;
pTab = sParse.pNewTable;
if( pTab==0 || pTab->nCol==1 || iCol>=pTab->nCol ){
/* This can happen if the sqlite_schema table is corrupt */
rc = SQLITE_CORRUPT_BKPT;
goto drop_column_done;
}
pCol = renameTokenFind(&sParse, 0, (void*)pTab->aCol[iCol].zName);
if( iCol<pTab->nCol-1 ){
|
| ︙ | ︙ | |||
112813 112814 112815 112816 112817 112818 112819 112820 112821 112822 112823 112824 112825 112826 |
return;
}
pParse->u1.pReturning = pRet;
pRet->pParse = pParse;
pRet->pReturnEL = pList;
sqlite3ParserAddCleanup(pParse,
(void(*)(sqlite3*,void*))sqlite3DeleteReturning, pRet);
if( db->mallocFailed ) return;
pRet->retTrig.zName = RETURNING_TRIGGER_NAME;
pRet->retTrig.op = TK_RETURNING;
pRet->retTrig.tr_tm = TRIGGER_AFTER;
pRet->retTrig.bReturning = 1;
pRet->retTrig.pSchema = db->aDb[1].pSchema;
pRet->retTrig.step_list = &pRet->retTStep;
| > | 112827 112828 112829 112830 112831 112832 112833 112834 112835 112836 112837 112838 112839 112840 112841 |
return;
}
pParse->u1.pReturning = pRet;
pRet->pParse = pParse;
pRet->pReturnEL = pList;
sqlite3ParserAddCleanup(pParse,
(void(*)(sqlite3*,void*))sqlite3DeleteReturning, pRet);
testcase( pParse->earlyCleanup );
if( db->mallocFailed ) return;
pRet->retTrig.zName = RETURNING_TRIGGER_NAME;
pRet->retTrig.op = TK_RETURNING;
pRet->retTrig.tr_tm = TRIGGER_AFTER;
pRet->retTrig.bReturning = 1;
pRet->retTrig.pSchema = db->aDb[1].pSchema;
pRet->retTrig.step_list = &pRet->retTStep;
|
| ︙ | ︙ | |||
130623 130624 130625 130626 130627 130628 130629 | ** Use this mechanism for uncommon cleanups. There is a higher setup ** cost for this mechansim (an extra malloc), so it should not be used ** for common cleanups that happen on most calls. But for less ** common cleanups, we save a single NULL-pointer comparison in ** sqlite3ParserReset(), which reduces the total CPU cycle count. ** ** If a memory allocation error occurs, then the cleanup happens immediately. | | > > > > > > > > | 130638 130639 130640 130641 130642 130643 130644 130645 130646 130647 130648 130649 130650 130651 130652 130653 130654 130655 130656 130657 130658 130659 130660 130661 130662 130663 130664 130665 130666 |
** Use this mechanism for uncommon cleanups. There is a higher setup
** cost for this mechansim (an extra malloc), so it should not be used
** for common cleanups that happen on most calls. But for less
** common cleanups, we save a single NULL-pointer comparison in
** sqlite3ParserReset(), which reduces the total CPU cycle count.
**
** If a memory allocation error occurs, then the cleanup happens immediately.
** When either SQLITE_DEBUG or SQLITE_COVERAGE_TEST are defined, the
** pParse->earlyCleanup flag is set in that case. Calling code show verify
** that test cases exist for which this happens, to guard against possible
** use-after-free errors following an OOM. The preferred way to do this is
** to immediately follow the call to this routine with:
**
** testcase( pParse->earlyCleanup );
**
** This routine returns a copy of its pPtr input (the third parameter)
** except if an early cleanup occurs, in which case it returns NULL. So
** another way to check for early cleanup is to check the return value.
** Or, stop using the pPtr parameter with this call and use only its
** return value thereafter. Something like this:
**
** pObj = sqlite3ParserAddCleanup(pParse, destructor, pObj);
*/
SQLITE_PRIVATE void *sqlite3ParserAddCleanup(
Parse *pParse, /* Destroy when this Parser finishes */
void (*xCleanup)(sqlite3*,void*), /* The cleanup routine */
void *pPtr /* Pointer to object to be cleaned up */
){
ParseCleanup *pCleanup = sqlite3DbMallocRaw(pParse->db, sizeof(*pCleanup));
|
| ︙ | ︙ | |||
131127 131128 131129 131130 131131 131132 131133 131134 131135 131136 131137 131138 |
sqlite3ExprListDelete(db, p->pEList);
sqlite3SrcListDelete(db, p->pSrc);
sqlite3ExprDelete(db, p->pWhere);
sqlite3ExprListDelete(db, p->pGroupBy);
sqlite3ExprDelete(db, p->pHaving);
sqlite3ExprListDelete(db, p->pOrderBy);
sqlite3ExprDelete(db, p->pLimit);
#ifndef SQLITE_OMIT_WINDOWFUNC
if( OK_IF_ALWAYS_TRUE(p->pWinDefn) ){
sqlite3WindowListDelete(db, p->pWinDefn);
}
#endif
| > > > > > < | 131150 131151 131152 131153 131154 131155 131156 131157 131158 131159 131160 131161 131162 131163 131164 131165 131166 131167 131168 131169 131170 131171 131172 131173 |
sqlite3ExprListDelete(db, p->pEList);
sqlite3SrcListDelete(db, p->pSrc);
sqlite3ExprDelete(db, p->pWhere);
sqlite3ExprListDelete(db, p->pGroupBy);
sqlite3ExprDelete(db, p->pHaving);
sqlite3ExprListDelete(db, p->pOrderBy);
sqlite3ExprDelete(db, p->pLimit);
if( OK_IF_ALWAYS_TRUE(p->pWith) ) sqlite3WithDelete(db, p->pWith);
#ifndef SQLITE_OMIT_WINDOWFUNC
if( OK_IF_ALWAYS_TRUE(p->pWinDefn) ){
sqlite3WindowListDelete(db, p->pWinDefn);
}
while( p->pWin ){
assert( p->pWin->ppThis==&p->pWin );
sqlite3WindowUnlinkFromSelect(p->pWin);
}
#endif
if( bFree ) sqlite3DbFreeNN(db, p);
p = pPrior;
bFree = 1;
}
}
/*
|
| ︙ | ︙ | |||
132428 132429 132430 132431 132432 132433 132434 | } return pInfo; } /* ** Name of the connection operator, used for error messages. */ | | | 132455 132456 132457 132458 132459 132460 132461 132462 132463 132464 132465 132466 132467 132468 132469 |
}
return pInfo;
}
/*
** Name of the connection operator, used for error messages.
*/
SQLITE_PRIVATE const char *sqlite3SelectOpName(int id){
char *z;
switch( id ){
case TK_ALL: z = "UNION ALL"; break;
case TK_INTERSECT: z = "INTERSECT"; break;
case TK_EXCEPT: z = "EXCEPT"; break;
default: z = "UNION"; break;
}
|
| ︙ | ︙ | |||
133647 133648 133649 133650 133651 133652 133653 | */ assert( p && p->pPrior ); /* Calling function guarantees this much */ assert( (p->selFlags & SF_Recursive)==0 || p->op==TK_ALL || p->op==TK_UNION ); assert( p->selFlags & SF_Compound ); db = pParse->db; pPrior = p->pPrior; dest = *pDest; | | < | < < < | 133674 133675 133676 133677 133678 133679 133680 133681 133682 133683 133684 133685 133686 133687 133688 133689 |
*/
assert( p && p->pPrior ); /* Calling function guarantees this much */
assert( (p->selFlags & SF_Recursive)==0 || p->op==TK_ALL || p->op==TK_UNION );
assert( p->selFlags & SF_Compound );
db = pParse->db;
pPrior = p->pPrior;
dest = *pDest;
assert( pPrior->pOrderBy==0 );
assert( pPrior->pLimit==0 );
v = sqlite3GetVdbe(pParse);
assert( v!=0 ); /* The VDBE already created by calling function */
/* Create the destination temporary table if necessary
*/
if( dest.eDest==SRT_EphemTab ){
|
| ︙ | ︙ | |||
133709 133710 133711 133712 133713 133714 133715 |
int addr = 0;
int nLimit;
assert( !pPrior->pLimit );
pPrior->iLimit = p->iLimit;
pPrior->iOffset = p->iOffset;
pPrior->pLimit = p->pLimit;
rc = sqlite3Select(pParse, pPrior, &dest);
| | | | | 133732 133733 133734 133735 133736 133737 133738 133739 133740 133741 133742 133743 133744 133745 133746 133747 133748 133749 133750 133751 133752 133753 133754 133755 133756 133757 133758 133759 133760 133761 133762 133763 133764 133765 133766 133767 133768 |
int addr = 0;
int nLimit;
assert( !pPrior->pLimit );
pPrior->iLimit = p->iLimit;
pPrior->iOffset = p->iOffset;
pPrior->pLimit = p->pLimit;
rc = sqlite3Select(pParse, pPrior, &dest);
pPrior->pLimit = 0;
if( rc ){
goto multi_select_end;
}
p->pPrior = 0;
p->iLimit = pPrior->iLimit;
p->iOffset = pPrior->iOffset;
if( p->iLimit ){
addr = sqlite3VdbeAddOp1(v, OP_IfNot, p->iLimit); VdbeCoverage(v);
VdbeComment((v, "Jump ahead if LIMIT reached"));
if( p->iOffset ){
sqlite3VdbeAddOp3(v, OP_OffsetLimit,
p->iLimit, p->iOffset+1, p->iOffset);
}
}
ExplainQueryPlan((pParse, 1, "UNION ALL"));
rc = sqlite3Select(pParse, p, &dest);
testcase( rc!=SQLITE_OK );
pDelete = p->pPrior;
p->pPrior = pPrior;
p->nSelectRow = sqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow);
if( p->pLimit
&& sqlite3ExprIsInteger(p->pLimit->pLeft, &nLimit)
&& nLimit>0 && p->nSelectRow > sqlite3LogEst((u64)nLimit)
){
p->nSelectRow = sqlite3LogEst((u64)nLimit);
}
if( addr ){
sqlite3VdbeJumpHere(v, addr);
}
|
| ︙ | ︙ | |||
133795 133796 133797 133798 133799 133800 133801 |
op = SRT_Union;
}
p->pPrior = 0;
pLimit = p->pLimit;
p->pLimit = 0;
uniondest.eDest = op;
ExplainQueryPlan((pParse, 1, "%s USING TEMP B-TREE",
| | | 133818 133819 133820 133821 133822 133823 133824 133825 133826 133827 133828 133829 133830 133831 133832 |
op = SRT_Union;
}
p->pPrior = 0;
pLimit = p->pLimit;
p->pLimit = 0;
uniondest.eDest = op;
ExplainQueryPlan((pParse, 1, "%s USING TEMP B-TREE",
sqlite3SelectOpName(p->op)));
rc = sqlite3Select(pParse, p, &uniondest);
testcase( rc!=SQLITE_OK );
assert( p->pOrderBy==0 );
pDelete = p->pPrior;
p->pPrior = pPrior;
p->pOrderBy = 0;
if( p->op==TK_UNION ){
|
| ︙ | ︙ | |||
133871 133872 133873 133874 133875 133876 133877 |
assert( p->addrOpenEphm[1] == -1 );
p->addrOpenEphm[1] = addr;
p->pPrior = 0;
pLimit = p->pLimit;
p->pLimit = 0;
intersectdest.iSDParm = tab2;
ExplainQueryPlan((pParse, 1, "%s USING TEMP B-TREE",
| | | 133894 133895 133896 133897 133898 133899 133900 133901 133902 133903 133904 133905 133906 133907 133908 |
assert( p->addrOpenEphm[1] == -1 );
p->addrOpenEphm[1] = addr;
p->pPrior = 0;
pLimit = p->pLimit;
p->pLimit = 0;
intersectdest.iSDParm = tab2;
ExplainQueryPlan((pParse, 1, "%s USING TEMP B-TREE",
sqlite3SelectOpName(p->op)));
rc = sqlite3Select(pParse, p, &intersectdest);
testcase( rc!=SQLITE_OK );
pDelete = p->pPrior;
p->pPrior = pPrior;
if( p->nSelectRow>pPrior->nSelectRow ){
p->nSelectRow = pPrior->nSelectRow;
}
|
| ︙ | ︙ | |||
133980 133981 133982 133983 133984 133985 133986 |
** size result sets.
*/
SQLITE_PRIVATE void sqlite3SelectWrongNumTermsError(Parse *pParse, Select *p){
if( p->selFlags & SF_Values ){
sqlite3ErrorMsg(pParse, "all VALUES must have the same number of terms");
}else{
sqlite3ErrorMsg(pParse, "SELECTs to the left and right of %s"
| | > | 134003 134004 134005 134006 134007 134008 134009 134010 134011 134012 134013 134014 134015 134016 134017 134018 |
** size result sets.
*/
SQLITE_PRIVATE void sqlite3SelectWrongNumTermsError(Parse *pParse, Select *p){
if( p->selFlags & SF_Values ){
sqlite3ErrorMsg(pParse, "all VALUES must have the same number of terms");
}else{
sqlite3ErrorMsg(pParse, "SELECTs to the left and right of %s"
" do not have the same number of result columns",
sqlite3SelectOpName(p->op));
}
}
/*
** Code an output subroutine for a coroutine implementation of a
** SELECT statment.
**
|
| ︙ | ︙ | |||
134077 134078 134079 134080 134081 134082 134083 |
/* If this is a scalar select that is part of an expression, then
** store the results in the appropriate memory cell and break out
** of the scan loop. Note that the select might return multiple columns
** if it is the RHS of a row-value IN operator.
*/
case SRT_Mem: {
| < | | < | 134101 134102 134103 134104 134105 134106 134107 134108 134109 134110 134111 134112 134113 134114 134115 134116 |
/* If this is a scalar select that is part of an expression, then
** store the results in the appropriate memory cell and break out
** of the scan loop. Note that the select might return multiple columns
** if it is the RHS of a row-value IN operator.
*/
case SRT_Mem: {
testcase( pIn->nSdst>1 );
sqlite3ExprCodeMove(pParse, pIn->iSdst, pDest->iSDParm, pIn->nSdst);
/* The LIMIT clause will jump out of the loop for us */
break;
}
#endif /* #ifndef SQLITE_OMIT_SUBQUERY */
/* The results are stored in a sequence of registers
** starting at pDest->iSdst. Then the co-routine yields.
|
| ︙ | ︙ | |||
134372 134373 134374 134375 134376 134377 134378 | regAddrA = ++pParse->nMem; regAddrB = ++pParse->nMem; regOutA = ++pParse->nMem; regOutB = ++pParse->nMem; sqlite3SelectDestInit(&destA, SRT_Coroutine, regAddrA); sqlite3SelectDestInit(&destB, SRT_Coroutine, regAddrB); | | | 134394 134395 134396 134397 134398 134399 134400 134401 134402 134403 134404 134405 134406 134407 134408 | regAddrA = ++pParse->nMem; regAddrB = ++pParse->nMem; regOutA = ++pParse->nMem; regOutB = ++pParse->nMem; sqlite3SelectDestInit(&destA, SRT_Coroutine, regAddrA); sqlite3SelectDestInit(&destB, SRT_Coroutine, regAddrB); ExplainQueryPlan((pParse, 1, "MERGE (%s)", sqlite3SelectOpName(p->op))); /* Generate a coroutine to evaluate the SELECT statement to the ** left of the compound operator - the "A" select. */ addrSelectA = sqlite3VdbeCurrentAddr(v) + 1; addr1 = sqlite3VdbeAddOp3(v, OP_InitCoroutine, regAddrA, 0, addrSelectA); VdbeComment((v, "left SELECT")); |
| ︙ | ︙ | |||
136297 136298 136299 136300 136301 136302 136303 |
}
#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE)
if( IsVirtual(pTab) || pTab->pSelect ){
i16 nCol;
u8 eCodeOrig = pWalker->eCode;
if( sqlite3ViewGetColumnNames(pParse, pTab) ) return WRC_Abort;
assert( pFrom->pSelect==0 );
| > | > > | 136319 136320 136321 136322 136323 136324 136325 136326 136327 136328 136329 136330 136331 136332 136333 136334 136335 136336 |
}
#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE)
if( IsVirtual(pTab) || pTab->pSelect ){
i16 nCol;
u8 eCodeOrig = pWalker->eCode;
if( sqlite3ViewGetColumnNames(pParse, pTab) ) return WRC_Abort;
assert( pFrom->pSelect==0 );
if( pTab->pSelect
&& (db->flags & SQLITE_EnableView)==0
&& pTab->pSchema!=db->aDb[1].pSchema
){
sqlite3ErrorMsg(pParse, "access to view \"%s\" prohibited",
pTab->zName);
}
#ifndef SQLITE_OMIT_VIRTUALTABLE
if( IsVirtual(pTab)
&& pFrom->fg.fromDDL
&& ALWAYS(pTab->pVTable!=0)
|
| ︙ | ︙ | |||
137076 137077 137078 137079 137080 137081 137082 |
assert( p->pOrderBy==0 || pDest->eDest!=SRT_DistQueue );
assert( p->pOrderBy==0 || pDest->eDest!=SRT_Queue );
if( IgnorableDistinct(pDest) ){
assert(pDest->eDest==SRT_Exists || pDest->eDest==SRT_Union ||
pDest->eDest==SRT_Except || pDest->eDest==SRT_Discard ||
pDest->eDest==SRT_DistQueue || pDest->eDest==SRT_DistFifo );
/* All of these destinations are also able to ignore the ORDER BY clause */
| > > > > > > > > > | > | > | 137101 137102 137103 137104 137105 137106 137107 137108 137109 137110 137111 137112 137113 137114 137115 137116 137117 137118 137119 137120 137121 137122 137123 137124 137125 137126 137127 |
assert( p->pOrderBy==0 || pDest->eDest!=SRT_DistQueue );
assert( p->pOrderBy==0 || pDest->eDest!=SRT_Queue );
if( IgnorableDistinct(pDest) ){
assert(pDest->eDest==SRT_Exists || pDest->eDest==SRT_Union ||
pDest->eDest==SRT_Except || pDest->eDest==SRT_Discard ||
pDest->eDest==SRT_DistQueue || pDest->eDest==SRT_DistFifo );
/* All of these destinations are also able to ignore the ORDER BY clause */
if( p->pOrderBy ){
#if SELECTTRACE_ENABLED
SELECTTRACE(1,pParse,p, ("dropping superfluous ORDER BY:\n"));
if( sqlite3SelectTrace & 0x100 ){
sqlite3TreeViewExprList(0, p->pOrderBy, 0, "ORDERBY");
}
#endif
sqlite3ParserAddCleanup(pParse,
(void(*)(sqlite3*,void*))sqlite3ExprListDelete,
p->pOrderBy);
testcase( pParse->earlyCleanup );
p->pOrderBy = 0;
}
p->selFlags &= ~SF_Distinct;
p->selFlags |= SF_NoopOrderBy;
}
sqlite3SelectPrep(pParse, p, 0);
if( pParse->nErr || db->mallocFailed ){
goto select_end;
}
|
| ︙ | ︙ | |||
137696 137697 137698 137699 137700 137701 137702 137703 137704 137705 137706 137707 137708 137709 |
** sAggInfo for all TK_AGG_FUNCTION nodes in expressions of the
** SELECT statement.
*/
pAggInfo = sqlite3DbMallocZero(db, sizeof(*pAggInfo) );
if( pAggInfo ){
sqlite3ParserAddCleanup(pParse,
(void(*)(sqlite3*,void*))agginfoFree, pAggInfo);
}
if( db->mallocFailed ){
goto select_end;
}
pAggInfo->selId = p->selId;
memset(&sNC, 0, sizeof(sNC));
sNC.pParse = pParse;
| > | 137732 137733 137734 137735 137736 137737 137738 137739 137740 137741 137742 137743 137744 137745 137746 |
** sAggInfo for all TK_AGG_FUNCTION nodes in expressions of the
** SELECT statement.
*/
pAggInfo = sqlite3DbMallocZero(db, sizeof(*pAggInfo) );
if( pAggInfo ){
sqlite3ParserAddCleanup(pParse,
(void(*)(sqlite3*,void*))agginfoFree, pAggInfo);
testcase( pParse->earlyCleanup );
}
if( db->mallocFailed ){
goto select_end;
}
pAggInfo->selId = p->selId;
memset(&sNC, 0, sizeof(sNC));
sNC.pParse = pParse;
|
| ︙ | ︙ | |||
147452 147453 147454 147455 147456 147457 147458 | Expr **ppAnd = 0; int idxNew; sqlite3 *db = pParse->db; assert( pExpr->op==TK_EXISTS ); assert( (pExpr->flags & EP_VarSelect) && (pExpr->flags & EP_xIsSelect) ); | | > > > | 147489 147490 147491 147492 147493 147494 147495 147496 147497 147498 147499 147500 147501 147502 147503 147504 147505 147506 |
Expr **ppAnd = 0;
int idxNew;
sqlite3 *db = pParse->db;
assert( pExpr->op==TK_EXISTS );
assert( (pExpr->flags & EP_VarSelect) && (pExpr->flags & EP_xIsSelect) );
if( pSel->selFlags & SF_Aggregate ) return;
#ifndef SQLITE_OMIT_WINDOWFUNC
if( pSel->pWin ) return;
#endif
if( pSel->pPrior ) return;
if( pSel->pWhere==0 ) return;
if( 0==exprAnalyzeExistsFindEq(pSel, 0, 0) ) return;
pDup = sqlite3ExprDup(db, pExpr, 0);
if( db->mallocFailed ){
sqlite3ExprDelete(db, pDup);
|
| ︙ | ︙ | |||
155835 155836 155837 155838 155839 155840 155841 155842 155843 155844 155845 155846 155847 155848 |
Vdbe *v = sqlite3GetVdbe(pParse);
ExprList *pOrderBy = p->pMWin->pOrderBy; /* ORDER BY clause for window */
int reg1 = sqlite3GetTempReg(pParse); /* Reg. for csr1.peerVal+regVal */
int reg2 = sqlite3GetTempReg(pParse); /* Reg. for csr2.peerVal */
int regString = ++pParse->nMem; /* Reg. for constant value '' */
int arith = OP_Add; /* OP_Add or OP_Subtract */
int addrGe; /* Jump destination */
assert( op==OP_Ge || op==OP_Gt || op==OP_Le );
assert( pOrderBy && pOrderBy->nExpr==1 );
if( pOrderBy->a[0].sortFlags & KEYINFO_ORDER_DESC ){
switch( op ){
case OP_Ge: op = OP_Le; break;
case OP_Gt: op = OP_Lt; break;
| > | 155875 155876 155877 155878 155879 155880 155881 155882 155883 155884 155885 155886 155887 155888 155889 |
Vdbe *v = sqlite3GetVdbe(pParse);
ExprList *pOrderBy = p->pMWin->pOrderBy; /* ORDER BY clause for window */
int reg1 = sqlite3GetTempReg(pParse); /* Reg. for csr1.peerVal+regVal */
int reg2 = sqlite3GetTempReg(pParse); /* Reg. for csr2.peerVal */
int regString = ++pParse->nMem; /* Reg. for constant value '' */
int arith = OP_Add; /* OP_Add or OP_Subtract */
int addrGe; /* Jump destination */
CollSeq *pColl;
assert( op==OP_Ge || op==OP_Gt || op==OP_Le );
assert( pOrderBy && pOrderBy->nExpr==1 );
if( pOrderBy->a[0].sortFlags & KEYINFO_ORDER_DESC ){
switch( op ){
case OP_Ge: op = OP_Le; break;
case OP_Gt: op = OP_Lt; break;
|
| ︙ | ︙ | |||
155925 155926 155927 155928 155929 155930 155931 155932 155933 155934 155935 155936 155937 155938 |
}
}
/* Compare registers reg2 and reg1, taking the jump if required. Note that
** control skips over this test if the BIGNULL flag is set and either
** reg1 or reg2 contain a NULL value. */
sqlite3VdbeAddOp3(v, op, reg2, lbl, reg1); VdbeCoverage(v);
sqlite3VdbeChangeP5(v, SQLITE_NULLEQ);
assert( op==OP_Ge || op==OP_Gt || op==OP_Lt || op==OP_Le );
testcase(op==OP_Ge); VdbeCoverageIf(v, op==OP_Ge);
testcase(op==OP_Lt); VdbeCoverageIf(v, op==OP_Lt);
testcase(op==OP_Le); VdbeCoverageIf(v, op==OP_Le);
testcase(op==OP_Gt); VdbeCoverageIf(v, op==OP_Gt);
| > > | 155966 155967 155968 155969 155970 155971 155972 155973 155974 155975 155976 155977 155978 155979 155980 155981 |
}
}
/* Compare registers reg2 and reg1, taking the jump if required. Note that
** control skips over this test if the BIGNULL flag is set and either
** reg1 or reg2 contain a NULL value. */
sqlite3VdbeAddOp3(v, op, reg2, lbl, reg1); VdbeCoverage(v);
pColl = sqlite3ExprNNCollSeq(pParse, pOrderBy->a[0].pExpr);
sqlite3VdbeAppendP4(v, (void*)pColl, P4_COLLSEQ);
sqlite3VdbeChangeP5(v, SQLITE_NULLEQ);
assert( op==OP_Ge || op==OP_Gt || op==OP_Lt || op==OP_Le );
testcase(op==OP_Ge); VdbeCoverageIf(v, op==OP_Ge);
testcase(op==OP_Lt); VdbeCoverageIf(v, op==OP_Lt);
testcase(op==OP_Le); VdbeCoverageIf(v, op==OP_Le);
testcase(op==OP_Gt); VdbeCoverageIf(v, op==OP_Gt);
|
| ︙ | ︙ | |||
156931 156932 156933 156934 156935 156936 156937 |
** For a compound SELECT statement, make sure p->pPrior->pNext==p for
** all elements in the list. And make sure list length does not exceed
** SQLITE_LIMIT_COMPOUND_SELECT.
*/
static void parserDoubleLinkSelect(Parse *pParse, Select *p){
assert( p!=0 );
if( p->pPrior ){
| | | | > > > > > > > > > > | 156974 156975 156976 156977 156978 156979 156980 156981 156982 156983 156984 156985 156986 156987 156988 156989 156990 156991 156992 156993 156994 156995 156996 156997 156998 156999 157000 157001 157002 |
** For a compound SELECT statement, make sure p->pPrior->pNext==p for
** all elements in the list. And make sure list length does not exceed
** SQLITE_LIMIT_COMPOUND_SELECT.
*/
static void parserDoubleLinkSelect(Parse *pParse, Select *p){
assert( p!=0 );
if( p->pPrior ){
Select *pNext = 0, *pLoop = p;
int mxSelect, cnt = 1;
while(1){
pLoop->pNext = pNext;
pLoop->selFlags |= SF_Compound;
pNext = pLoop;
pLoop = pLoop->pPrior;
if( pLoop==0 ) break;
cnt++;
if( pLoop->pOrderBy || pLoop->pLimit ){
sqlite3ErrorMsg(pParse,"%s clause should come after %s not before",
pLoop->pOrderBy!=0 ? "ORDER BY" : "LIMIT",
sqlite3SelectOpName(pNext->op));
break;
}
}
if( (p->selFlags & SF_MultiValue)==0 &&
(mxSelect = pParse->db->aLimit[SQLITE_LIMIT_COMPOUND_SELECT])>0 &&
cnt>mxSelect
){
sqlite3ErrorMsg(pParse, "too many terms in compound SELECT");
}
|
| ︙ | ︙ | |||
175031 175032 175033 175034 175035 175036 175037 |
p2 = pOut = pPhrase->doclist.pList;
res = fts3PoslistNearMerge(
&pOut, aTmp, nParam1, nParam2, paPoslist, &p2
);
if( res ){
nNew = (int)(pOut - pPhrase->doclist.pList) - 1;
| > | < | 175084 175085 175086 175087 175088 175089 175090 175091 175092 175093 175094 175095 175096 175097 175098 175099 175100 |
p2 = pOut = pPhrase->doclist.pList;
res = fts3PoslistNearMerge(
&pOut, aTmp, nParam1, nParam2, paPoslist, &p2
);
if( res ){
nNew = (int)(pOut - pPhrase->doclist.pList) - 1;
assert_fts3_nc( nNew<=pPhrase->doclist.nList && nNew>0 );
if( nNew>=0 && nNew<=pPhrase->doclist.nList ){
assert( pPhrase->doclist.pList[nNew]=='\0' );
memset(&pPhrase->doclist.pList[nNew], 0, pPhrase->doclist.nList - nNew);
pPhrase->doclist.nList = nNew;
}
*paPoslist = pPhrase->doclist.pList;
*pnToken = pPhrase->nToken;
}
|
| ︙ | ︙ | |||
176967 176968 176969 176970 176971 176972 176973 176974 176975 176976 176977 176978 176979 176980 |
return getNextString(pParse, &zInput[1], ii-1, ppExpr);
}
if( sqlite3_fts3_enable_parentheses ){
if( *zInput=='(' ){
int nConsumed = 0;
pParse->nNest++;
rc = fts3ExprParse(pParse, zInput+1, nInput-1, ppExpr, &nConsumed);
*pnConsumed = (int)(zInput - z) + 1 + nConsumed;
return rc;
}else if( *zInput==')' ){
pParse->nNest--;
*pnConsumed = (int)((zInput - z) + 1);
*ppExpr = 0;
| > > > > > | 177020 177021 177022 177023 177024 177025 177026 177027 177028 177029 177030 177031 177032 177033 177034 177035 177036 177037 177038 |
return getNextString(pParse, &zInput[1], ii-1, ppExpr);
}
if( sqlite3_fts3_enable_parentheses ){
if( *zInput=='(' ){
int nConsumed = 0;
pParse->nNest++;
#if !defined(SQLITE_MAX_EXPR_DEPTH)
if( pParse->nNest>1000 ) return SQLITE_ERROR;
#elif SQLITE_MAX_EXPR_DEPTH>0
if( pParse->nNest>SQLITE_MAX_EXPR_DEPTH ) return SQLITE_ERROR;
#endif
rc = fts3ExprParse(pParse, zInput+1, nInput-1, ppExpr, &nConsumed);
*pnConsumed = (int)(zInput - z) + 1 + nConsumed;
return rc;
}else if( *zInput==')' ){
pParse->nNest--;
*pnConsumed = (int)((zInput - z) + 1);
*ppExpr = 0;
|
| ︙ | ︙ | |||
184370 184371 184372 184373 184374 184375 184376 |
pNode = &pWriter->aNodeWriter[i];
if( pNode->block.a){
rc = nodeReaderInit(&reader, pNode->block.a, pNode->block.n);
while( reader.aNode && rc==SQLITE_OK ) rc = nodeReaderNext(&reader);
blobGrowBuffer(&pNode->key, reader.term.n, &rc);
if( rc==SQLITE_OK ){
| > | < < > | | | | | | | | | | | | | | | | < | 184428 184429 184430 184431 184432 184433 184434 184435 184436 184437 184438 184439 184440 184441 184442 184443 184444 184445 184446 184447 184448 184449 184450 184451 184452 184453 184454 184455 184456 184457 184458 184459 184460 184461 |
pNode = &pWriter->aNodeWriter[i];
if( pNode->block.a){
rc = nodeReaderInit(&reader, pNode->block.a, pNode->block.n);
while( reader.aNode && rc==SQLITE_OK ) rc = nodeReaderNext(&reader);
blobGrowBuffer(&pNode->key, reader.term.n, &rc);
if( rc==SQLITE_OK ){
assert_fts3_nc( reader.term.n>0 || reader.aNode==0 );
if( reader.term.n>0 ){
memcpy(pNode->key.a, reader.term.a, reader.term.n);
}
pNode->key.n = reader.term.n;
if( i>0 ){
char *aBlock = 0;
int nBlock = 0;
pNode = &pWriter->aNodeWriter[i-1];
pNode->iBlock = reader.iChild;
rc = sqlite3Fts3ReadBlock(p, reader.iChild, &aBlock, &nBlock,0);
blobGrowBuffer(&pNode->block,
MAX(nBlock, p->nNodeSize)+FTS3_NODE_PADDING, &rc
);
if( rc==SQLITE_OK ){
memcpy(pNode->block.a, aBlock, nBlock);
pNode->block.n = nBlock;
memset(&pNode->block.a[nBlock], 0, FTS3_NODE_PADDING);
}
sqlite3_free(aBlock);
}
}
}
nodeReaderRelease(&reader);
}
}
|
| ︙ | ︙ | |||
224440 224441 224442 224443 224444 224445 224446 224447 224448 224449 224450 224451 224452 224453 |
pIter->nPoslist = (nPos>>1);
}else{
pIter->nPoslist = ((int)(p[0])) >> 1;
pIter->nSize = 1;
}
pIter->aPoslist = p;
}
}
static void fts5DoclistIterInit(
Fts5Buffer *pBuf,
Fts5DoclistIter *pIter
){
| > > > | 224497 224498 224499 224500 224501 224502 224503 224504 224505 224506 224507 224508 224509 224510 224511 224512 224513 |
pIter->nPoslist = (nPos>>1);
}else{
pIter->nPoslist = ((int)(p[0])) >> 1;
pIter->nSize = 1;
}
pIter->aPoslist = p;
if( &pIter->aPoslist[pIter->nPoslist]>pIter->aEof ){
pIter->aPoslist = 0;
}
}
}
static void fts5DoclistIterInit(
Fts5Buffer *pBuf,
Fts5DoclistIter *pIter
){
|
| ︙ | ︙ | |||
229107 229108 229109 229110 229111 229112 229113 |
static void fts5SourceIdFunc(
sqlite3_context *pCtx, /* Function call context */
int nArg, /* Number of args */
sqlite3_value **apUnused /* Function arguments */
){
assert( nArg==0 );
UNUSED_PARAM2(nArg, apUnused);
| | | 229167 229168 229169 229170 229171 229172 229173 229174 229175 229176 229177 229178 229179 229180 229181 |
static void fts5SourceIdFunc(
sqlite3_context *pCtx, /* Function call context */
int nArg, /* Number of args */
sqlite3_value **apUnused /* Function arguments */
){
assert( nArg==0 );
UNUSED_PARAM2(nArg, apUnused);
sqlite3_result_text(pCtx, "fts5: 2021-03-09 21:20:12 9645fe1a050e8b61aea1fba2f142819c387ecb043741392c5719bf7ad303bf8b", -1, SQLITE_TRANSIENT);
}
/*
** Return true if zName is the extension on one of the shadow tables used
** by this module.
*/
static int fts5ShadowName(const char *zName){
|
| ︙ | ︙ | |||
234033 234034 234035 234036 234037 234038 234039 | #endif return rc; } #endif /* SQLITE_CORE */ #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_STMTVTAB) */ /************** End of stmt.c ************************************************/ | | | | 234093 234094 234095 234096 234097 234098 234099 234100 234101 234102 234103 234104 234105 234106 |
#endif
return rc;
}
#endif /* SQLITE_CORE */
#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_STMTVTAB) */
/************** End of stmt.c ************************************************/
#if __LINE__!=234100
#undef SQLITE_SOURCE_ID
#define SQLITE_SOURCE_ID "2021-03-09 21:20:12 9645fe1a050e8b61aea1fba2f142819c387ecb043741392c5719bf7ad303alt2"
#endif
/* Return the source-id for this library */
SQLITE_API const char *sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; }
/************************** End of sqlite3.c ******************************/
|
Changes to src/sqlite3.h.
| ︙ | ︙ | |||
121 122 123 124 125 126 127 | ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ #define SQLITE_VERSION "3.35.0" #define SQLITE_VERSION_NUMBER 3035000 | | | 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 | ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ #define SQLITE_VERSION "3.35.0" #define SQLITE_VERSION_NUMBER 3035000 #define SQLITE_SOURCE_ID "2021-03-09 21:20:12 9645fe1a050e8b61aea1fba2f142819c387ecb043741392c5719bf7ad303bf8b" /* ** CAPI3REF: Run-Time Library Version Numbers ** KEYWORDS: sqlite3_version sqlite3_sourceid ** ** These interfaces provide the same information as the [SQLITE_VERSION], ** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros |
| ︙ | ︙ | |||
2128 2129 2130 2131 2132 2133 2134 | ** <dd> ^This option is used to enable or disable [CREATE VIEW | views]. ** There should be two additional arguments. ** The first argument is an integer which is 0 to disable views, ** positive to enable views or negative to leave the setting unchanged. ** The second parameter is a pointer to an integer into which ** is written 0 or 1 to indicate whether views are disabled or enabled ** following this call. The second parameter may be a NULL pointer, in | | > > > > > > | 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 | ** <dd> ^This option is used to enable or disable [CREATE VIEW | views]. ** There should be two additional arguments. ** The first argument is an integer which is 0 to disable views, ** positive to enable views or negative to leave the setting unchanged. ** The second parameter is a pointer to an integer into which ** is written 0 or 1 to indicate whether views are disabled or enabled ** following this call. The second parameter may be a NULL pointer, in ** which case the view setting is not reported back. ** ** <p>Originally this option disabled all views. ^(However, since ** SQLite version 3.35.0, TEMP views are still allowed even if ** this option is off. So, in other words, this option now only disables ** views in the main database schema or in the schemas of ATTACH-ed ** databases.)^ </dd> ** ** [[SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER]] ** <dt>SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER</dt> ** <dd> ^This option is used to enable or disable the ** [fts3_tokenizer()] function which is part of the ** [FTS3] full-text search engine extension. ** There should be two additional arguments. |
| ︙ | ︙ |