DBD-SQLite
view release on metacpan or search on metacpan
VdbeFrame *pDelFrame; /* List of frame objects to free on VM reset */
int nFrame; /* Number of frames in pFrame list */
u32 expmask; /* Binding to these vars invalidates VM */
SubProgram *pProgram; /* Linked list of all sub-programs used by VM */
AuxData *pAuxData; /* Linked list of auxdata allocations */
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
int nScan; /* Entries in aScan[] */
ScanStatus *aScan; /* Scan definitions for sqlite3_stmt_scanstatus() */
#endif
};
/*
** The following are allowed values for Vdbe.eVdbeState
*/
#define VDBE_INIT_STATE 0 /* Prepared statement under construction */
#define VDBE_READY_STATE 1 /* Ready to run but not yet started */
#define VDBE_RUN_STATE 2 /* Run in progress */
#define VDBE_HALT_STATE 3 /* Finished. Need reset() or finalize() */
/*
** Structure used to store the context required by the
** sqlite3_preupdate_*() API functions.
*/
struct PreUpdate {
Vdbe *v;
VdbeCursor *pCsr; /* Cursor to read old values from */
int op; /* One of SQLITE_INSERT, UPDATE, DELETE */
u8 *aRecord; /* old.* database record */
KeyInfo *pKeyinfo; /* Key information */
UnpackedRecord *pUnpacked; /* Unpacked version of aRecord[] */
UnpackedRecord *pNewUnpacked; /* Unpacked version of new.* record */
int iNewReg; /* Register for new.* values */
int iBlobWrite; /* Value returned by preupdate_blobwrite() */
i64 iKey1; /* First key value passed to hook */
i64 iKey2; /* Second key value passed to hook */
Mem oldipk; /* Memory cell holding "old" IPK value */
Mem *aNew; /* Array of new.* values */
Table *pTab; /* Schema object being updated */
Index *pPk; /* PK index if pTab is WITHOUT ROWID */
sqlite3_value **apDflt; /* Array of default values, if required */
struct {
u8 keyinfoSpace[SZ_KEYINFO_0]; /* Space to hold pKeyinfo[0] content */
} uKey;
};
/*
** An instance of this object is used to pass an vector of values into
** OP_VFilter, the xFilter method of a virtual table. The vector is the
** set of values on the right-hand side of an IN constraint.
**
** The value as passed into xFilter is an sqlite3_value with a "pointer"
** type, such as is generated by sqlite3_result_pointer() and read by
** sqlite3_value_pointer. Such values have MEM_Term|MEM_Subtype|MEM_Null
** and a subtype of 'p'. The sqlite3_vtab_in_first() and _next() interfaces
** know how to use this object to step through all the values in the
** right operand of the IN constraint.
*/
typedef struct ValueList ValueList;
struct ValueList {
BtCursor *pCsr; /* An ephemeral table holding all values */
sqlite3_value *pOut; /* Register to hold each decoded output value */
};
/* Size of content associated with serial types that fit into a
** single-byte varint.
*/
#ifndef SQLITE_AMALGAMATION
SQLITE_PRIVATE const u8 sqlite3SmallTypeSizes[];
#endif
/*
** Function prototypes
*/
SQLITE_PRIVATE void sqlite3VdbeError(Vdbe*, const char *, ...);
SQLITE_PRIVATE void sqlite3VdbeFreeCursor(Vdbe *, VdbeCursor*);
SQLITE_PRIVATE void sqlite3VdbeFreeCursorNN(Vdbe*,VdbeCursor*);
void sqliteVdbePopStack(Vdbe*,int);
SQLITE_PRIVATE int SQLITE_NOINLINE sqlite3VdbeHandleMovedCursor(VdbeCursor *p);
SQLITE_PRIVATE int SQLITE_NOINLINE sqlite3VdbeFinishMoveto(VdbeCursor*);
SQLITE_PRIVATE int sqlite3VdbeCursorRestore(VdbeCursor*);
SQLITE_PRIVATE u32 sqlite3VdbeSerialTypeLen(u32);
SQLITE_PRIVATE u8 sqlite3VdbeOneByteSerialTypeLen(u8);
#ifdef SQLITE_MIXED_ENDIAN_64BIT_FLOAT
SQLITE_PRIVATE u64 sqlite3FloatSwap(u64 in);
# define swapMixedEndianFloat(X) X = sqlite3FloatSwap(X)
#else
# define swapMixedEndianFloat(X)
#endif
SQLITE_PRIVATE void sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*);
SQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(sqlite3*, AuxData**, int, int);
int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *);
SQLITE_PRIVATE int sqlite3VdbeIdxKeyCompare(sqlite3*,VdbeCursor*,UnpackedRecord*,int*);
SQLITE_PRIVATE int sqlite3VdbeIdxRowid(sqlite3*, BtCursor*, i64*);
SQLITE_PRIVATE int sqlite3VdbeExec(Vdbe*);
#if !defined(SQLITE_OMIT_EXPLAIN) || defined(SQLITE_ENABLE_BYTECODE_VTAB)
SQLITE_PRIVATE int sqlite3VdbeNextOpcode(Vdbe*,Mem*,int,int*,int*,Op**);
SQLITE_PRIVATE char *sqlite3VdbeDisplayP4(sqlite3*,Op*);
#endif
#if defined(SQLITE_ENABLE_EXPLAIN_COMMENTS)
SQLITE_PRIVATE char *sqlite3VdbeDisplayComment(sqlite3*,const Op*,const char*);
#endif
#if !defined(SQLITE_OMIT_EXPLAIN)
SQLITE_PRIVATE int sqlite3VdbeList(Vdbe*);
#endif
SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe*);
SQLITE_PRIVATE int sqlite3VdbeChangeEncoding(Mem *, int);
SQLITE_PRIVATE int sqlite3VdbeMemTooBig(Mem*);
SQLITE_PRIVATE int sqlite3VdbeMemCopy(Mem*, const Mem*);
SQLITE_PRIVATE void sqlite3VdbeMemShallowCopy(Mem*, const Mem*, int);
SQLITE_PRIVATE void sqlite3VdbeMemMove(Mem*, Mem*);
SQLITE_PRIVATE int sqlite3VdbeMemNulTerminate(Mem*);
SQLITE_PRIVATE int sqlite3VdbeMemSetStr(Mem*, const char*, i64, u8, void(*)(void*));
SQLITE_PRIVATE void sqlite3VdbeMemSetInt64(Mem*, i64);
#ifdef SQLITE_OMIT_FLOATING_POINT
# define sqlite3VdbeMemSetDouble sqlite3VdbeMemSetInt64
#else
SQLITE_PRIVATE void sqlite3VdbeMemSetDouble(Mem*, double);
#endif
SQLITE_PRIVATE void sqlite3VdbeMemSetPointer(Mem*, void*, const char*, void(*)(void*));
SQLITE_PRIVATE void sqlite3VdbeMemInit(Mem*,sqlite3*,u16);
** dates afterwards, depending on locale. Beware of this difference.
**
** The conversion algorithms are implemented based on descriptions
** in the following text:
**
** Jean Meeus
** Astronomical Algorithms, 2nd Edition, 1998
** ISBN 0-943396-61-1
** Willmann-Bell, Inc
** Richmond, Virginia (USA)
*/
/* #include "sqliteInt.h" */
/* #include <stdlib.h> */
/* #include <assert.h> */
#include <time.h>
#ifndef SQLITE_OMIT_DATETIME_FUNCS
/*
** The MSVC CRT on Windows CE may not have a localtime() function.
** So declare a substitute. The substitute function itself is
** defined in "os_win.c".
*/
#if !defined(SQLITE_OMIT_LOCALTIME) && defined(_WIN32_WCE) && \
(!defined(SQLITE_MSVC_LOCALTIME_API) || !SQLITE_MSVC_LOCALTIME_API)
struct tm *__cdecl localtime(const time_t *);
#endif
/*
** A structure for holding a single date and time.
*/
typedef struct DateTime DateTime;
struct DateTime {
sqlite3_int64 iJD; /* The julian day number times 86400000 */
int Y, M, D; /* Year, month, and day */
int h, m; /* Hour and minutes */
int tz; /* Timezone offset in minutes */
double s; /* Seconds */
char validJD; /* True (1) if iJD is valid */
char validYMD; /* True (1) if Y,M,D are valid */
char validHMS; /* True (1) if h,m,s are valid */
char nFloor; /* Days to implement "floor" */
unsigned rawS : 1; /* Raw numeric value stored in s */
unsigned isError : 1; /* An overflow has occurred */
unsigned useSubsec : 1; /* Display subsecond precision */
unsigned isUtc : 1; /* Time is known to be UTC */
unsigned isLocal : 1; /* Time is known to be localtime */
};
/*
** Convert zDate into one or more integers according to the conversion
** specifier zFormat.
**
** zFormat[] contains 4 characters for each integer converted, except for
** the last integer which is specified by three characters. The meaning
** of a four-character format specifiers ABCD is:
**
** A: number of digits to convert. Always "2" or "4".
** B: minimum value. Always "0" or "1".
** C: maximum value, decoded as:
** a: 12
** b: 14
** c: 24
** d: 31
** e: 59
** f: 9999
** D: the separator character, or \000 to indicate this is the
** last number to convert.
**
** Example: To translate an ISO-8601 date YYYY-MM-DD, the format would
** be "40f-21a-20c". The "40f-" indicates the 4-digit year followed by "-".
** The "21a-" indicates the 2-digit month followed by "-". The "20c" indicates
** the 2-digit day which is the last integer in the set.
**
** The function returns the number of successful conversions.
*/
static int getDigits(const char *zDate, const char *zFormat, ...){
/* The aMx[] array translates the 3rd character of each format
** spec into a max size: a b c d e f */
static const u16 aMx[] = { 12, 14, 24, 31, 59, 14712 };
va_list ap;
int cnt = 0;
char nextC;
va_start(ap, zFormat);
do{
char N = zFormat[0] - '0';
char min = zFormat[1] - '0';
int val = 0;
u16 max;
assert( zFormat[2]>='a' && zFormat[2]<='f' );
max = aMx[zFormat[2] - 'a'];
nextC = zFormat[3];
val = 0;
while( N-- ){
if( !sqlite3Isdigit(*zDate) ){
goto end_getDigits;
}
val = val*10 + *zDate - '0';
zDate++;
}
if( val<(int)min || val>(int)max || (nextC!=0 && nextC!=*zDate) ){
goto end_getDigits;
}
*va_arg(ap,int*) = val;
zDate++;
cnt++;
zFormat += 4;
}while( nextC );
end_getDigits:
va_end(ap);
return cnt;
}
/*
** Parse a timezone extension on the end of a date-time.
** The extension is of the form:
**
** (+/-)HH:MM
**
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
};
/*
** Decode the text encoding back to binary. The binary content is
** written into pOut, which must be at least nOut bytes in length.
**
** The return value is the number of bytes actually written into aOut[].
*/
static int kvvfsDecode(const char *a, char *aOut, int nOut){
int i, j;
int c;
const unsigned char *aIn = (const unsigned char*)a;
i = 0;
j = 0;
while( 1 ){
c = kvvfsHexValue[aIn[i]];
if( c<0 ){
int n = 0;
int mult = 1;
c = aIn[i];
if( c==0 ) break;
while( c>='a' && c<='z' ){
n += (c - 'a')*mult;
mult *= 26;
c = aIn[++i];
}
if( j+n>nOut ) return -1;
memset(&aOut[j], 0, n);
j += n;
if( c==0 || mult==1 ) break; /* progress stalled if mult==1 */
}else{
aOut[j] = c<<4;
c = kvvfsHexValue[aIn[++i]];
if( c<0 ) break;
aOut[j++] += c;
i++;
}
}
return j;
}
/*
** Decode a complete journal file. Allocate space in pFile->aJrnl
** and store the decoding there. Or leave pFile->aJrnl set to NULL
** if an error is encountered.
**
** The first few characters of the text encoding will be a little-endian
** base-26 number (digits a..z) that is the total number of bytes
** in the decoded journal file image. This base-26 number is followed
** by a single space, then the encoding of the journal. The space
** separator is required to act as a terminator for the base-26 number.
*/
static void kvvfsDecodeJournal(
KVVfsFile *pFile, /* Store decoding in pFile->aJrnl */
const char *zTxt, /* Text encoding. Zero-terminated */
int nTxt /* Bytes in zTxt, excluding zero terminator */
){
unsigned int n = 0;
int c, i, mult;
i = 0;
mult = 1;
while( (c = zTxt[i++])>='a' && c<='z' ){
n += (zTxt[i] - 'a')*mult;
mult *= 26;
}
sqlite3_free(pFile->aJrnl);
pFile->aJrnl = sqlite3_malloc64( n );
if( pFile->aJrnl==0 ){
pFile->nJrnl = 0;
return;
}
pFile->nJrnl = n;
n = kvvfsDecode(zTxt+i, pFile->aJrnl, pFile->nJrnl);
if( n<pFile->nJrnl ){
sqlite3_free(pFile->aJrnl);
pFile->aJrnl = 0;
pFile->nJrnl = 0;
}
}
/*
** Read or write the "sz" element, containing the database file size.
*/
static sqlite3_int64 kvvfsReadFileSize(KVVfsFile *pFile){
char zData[50];
zData[0] = 0;
sqlite3KvvfsMethods.xRead(pFile->zClass, "sz", zData, sizeof(zData)-1);
return strtoll(zData, 0, 0);
}
static int kvvfsWriteFileSize(KVVfsFile *pFile, sqlite3_int64 sz){
char zData[50];
sqlite3_snprintf(sizeof(zData), zData, "%lld", sz);
return sqlite3KvvfsMethods.xWrite(pFile->zClass, "sz", zData);
}
/****** sqlite3_io_methods methods ******************************************/
/*
** Close an kvvfs-file.
*/
static int kvvfsClose(sqlite3_file *pProtoFile){
KVVfsFile *pFile = (KVVfsFile *)pProtoFile;
SQLITE_KV_LOG(("xClose %s %s\n", pFile->zClass,
pFile->isJournal ? "journal" : "db"));
sqlite3_free(pFile->aJrnl);
sqlite3_free(pFile->aData);
return SQLITE_OK;
}
}
case 3: { /* 3-byte signed integer */
/* EVIDENCE-OF: R-37839-54301 Value is a big-endian 24-bit
** twos-complement integer. */
pMem->u.i = THREE_BYTE_INT(buf);
pMem->flags = MEM_Int;
testcase( pMem->u.i<0 );
return;
}
case 4: { /* 4-byte signed integer */
/* EVIDENCE-OF: R-01849-26079 Value is a big-endian 32-bit
** twos-complement integer. */
pMem->u.i = FOUR_BYTE_INT(buf);
#ifdef __HP_cc
/* Work around a sign-extension bug in the HP compiler for HP/UX */
if( buf[0]&0x80 ) pMem->u.i |= 0xffffffff80000000LL;
#endif
pMem->flags = MEM_Int;
testcase( pMem->u.i<0 );
return;
}
case 5: { /* 6-byte signed integer */
/* EVIDENCE-OF: R-50385-09674 Value is a big-endian 48-bit
** twos-complement integer. */
pMem->u.i = FOUR_BYTE_UINT(buf+2) + (((i64)1)<<32)*TWO_BYTE_INT(buf);
pMem->flags = MEM_Int;
testcase( pMem->u.i<0 );
return;
}
case 6: /* 8-byte signed integer */
case 7: { /* IEEE floating point */
/* These use local variables, so do them in a separate routine
** to avoid having to move the frame pointer in the common case */
serialGet(buf,serial_type,pMem);
return;
}
case 8: /* Integer 0 */
case 9: { /* Integer 1 */
/* EVIDENCE-OF: R-12976-22893 Value is the integer 0. */
/* EVIDENCE-OF: R-18143-12121 Value is the integer 1. */
pMem->u.i = serial_type-8;
pMem->flags = MEM_Int;
return;
}
default: {
/* EVIDENCE-OF: R-14606-31564 Value is a BLOB that is (N-12)/2 bytes in
** length.
** EVIDENCE-OF: R-28401-00140 Value is a string in the text encoding and
** (N-13)/2 bytes in length. */
static const u16 aFlag[] = { MEM_Blob|MEM_Ephem, MEM_Str|MEM_Ephem };
pMem->z = (char *)buf;
pMem->n = (serial_type-12)/2;
pMem->flags = aFlag[serial_type&1];
return;
}
}
return;
}
/*
** Allocate sufficient space for an UnpackedRecord structure large enough
** to hold a decoded index record for pKeyInfo.
**
** The space is allocated using sqlite3DbMallocRaw(). If an OOM error
** occurs, NULL is returned.
*/
SQLITE_PRIVATE UnpackedRecord *sqlite3VdbeAllocUnpackedRecord(
KeyInfo *pKeyInfo /* Description of the record */
){
UnpackedRecord *p; /* Unpacked record to return */
u64 nByte; /* Number of bytes required for *p */
assert( sizeof(UnpackedRecord) + sizeof(Mem)*65536 < 0x7fffffff );
nByte = ROUND8P(sizeof(UnpackedRecord)) + sizeof(Mem)*(pKeyInfo->nKeyField+1);
p = (UnpackedRecord *)sqlite3DbMallocRaw(pKeyInfo->db, nByte);
if( !p ) return 0;
p->aMem = (Mem*)&((char*)p)[ROUND8P(sizeof(UnpackedRecord))];
p->pKeyInfo = pKeyInfo;
p->nField = pKeyInfo->nKeyField + 1;
return p;
}
/*
** Given the nKey-byte encoding of a record in pKey[], populate the
** UnpackedRecord structure indicated by the fourth argument with the
** contents of the decoded record.
*/
SQLITE_PRIVATE void sqlite3VdbeRecordUnpack(
int nKey, /* Size of the binary record */
const void *pKey, /* The binary record */
UnpackedRecord *p /* Populate this structure before returning. */
){
const unsigned char *aKey = (const unsigned char *)pKey;
u32 d;
u32 idx; /* Offset in aKey[] to read from */
u16 u; /* Unsigned loop counter */
u32 szHdr;
Mem *pMem = p->aMem;
KeyInfo *pKeyInfo = p->pKeyInfo;
p->default_rc = 0;
assert( EIGHT_BYTE_ALIGNMENT(pMem) );
idx = getVarint32(aKey, szHdr);
d = szHdr;
u = 0;
while( idx<szHdr && d<=(u32)nKey ){
u32 serial_type;
idx += getVarint32(&aKey[idx], serial_type);
pMem->enc = pKeyInfo->enc;
pMem->db = pKeyInfo->db;
/* pMem->flags = 0; // sqlite3VdbeSerialGet() will set this for us */
pMem->szMalloc = 0;
pMem->z = 0;
sqlite3VdbeSerialGet(&aKey[d], serial_type, pMem);
d += sqlite3VdbeSerialTypeLen(serial_type);
if( (++u)>=p->nField ) break;
pMem++;
}
if( d>(u32)nKey && u ){
assert( CORRUPT_DB );
/* In a corrupt record entry, the last pMem might have been set up using
** uninitialized memory. Overwrite its value with NULL, to prevent
** warnings from MSAN. */
sqlite3VdbeMemSetNull(pMem-(u<p->nField));
}
testcase( u == pKeyInfo->nKeyField + 1 );
testcase( u < pKeyInfo->nKeyField + 1 );
assert( u<=pKeyInfo->nKeyField + 1 );
p->nField = u;
}
#ifdef SQLITE_DEBUG
/*
** This function compares two index or table record keys in the same way
** as the sqlite3VdbeRecordCompare() routine. Unlike VdbeRecordCompare(),
** this function deserializes and compares values using the
** sqlite3VdbeSerialGet() and sqlite3MemCompare() functions. It is used
** in assert() statements to ensure that the optimized code in
** sqlite3VdbeRecordCompare() returns results with these two primitives.
**
** Return true if the result of comparison is equivalent to desiredResult.
** Return false if there is a disagreement.
*/
static int vdbeRecordCompareDebug(
int nKey1, const void *pKey1, /* Left key */
** P2 is the column number for the argument to the sqlite_offset() function.
** This opcode does not use P2 itself, but the P2 value is used by the
** code generator. The P1, P2, and P3 operands to this opcode are the
** same as for OP_Column.
**
** This opcode is only available if SQLite is compiled with the
** -DSQLITE_ENABLE_OFFSET_SQL_FUNC option.
*/
case OP_Offset: { /* out3 */
VdbeCursor *pC; /* The VDBE cursor */
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
pC = p->apCsr[pOp->p1];
pOut = &p->aMem[pOp->p3];
if( pC==0 || pC->eCurType!=CURTYPE_BTREE ){
sqlite3VdbeMemSetNull(pOut);
}else{
if( pC->deferredMoveto ){
rc = sqlite3VdbeFinishMoveto(pC);
if( rc ) goto abort_due_to_error;
}
if( sqlite3BtreeEof(pC->uc.pCursor) ){
sqlite3VdbeMemSetNull(pOut);
}else{
sqlite3VdbeMemSetInt64(pOut, sqlite3BtreeOffset(pC->uc.pCursor));
}
}
break;
}
#endif /* SQLITE_ENABLE_OFFSET_SQL_FUNC */
/* Opcode: Column P1 P2 P3 P4 P5
** Synopsis: r[P3]=PX cursor P1 column P2
**
** Interpret the data that cursor P1 points to as a structure built using
** the MakeRecord instruction. (See the MakeRecord opcode for additional
** information about the format of the data.) Extract the P2-th column
** from this record. If there are less than (P2+1)
** values in the record, extract a NULL.
**
** The value extracted is stored in register P3.
**
** If the record contains fewer than P2 fields, then extract a NULL. Or,
** if the P4 argument is a P4_MEM use the value of the P4 argument as
** the result.
**
** If the OPFLAG_LENGTHARG bit is set in P5 then the result is guaranteed
** to only be used by the length() function or the equivalent. The content
** of large blobs is not loaded, thus saving CPU cycles. If the
** OPFLAG_TYPEOFARG bit is set then the result will only be used by the
** typeof() function or the IS NULL or IS NOT NULL operators or the
** equivalent. In this case, all content loading can be omitted.
*/
case OP_Column: { /* ncycle */
u32 p2; /* column number to retrieve */
VdbeCursor *pC; /* The VDBE cursor */
BtCursor *pCrsr; /* The B-Tree cursor corresponding to pC */
u32 *aOffset; /* aOffset[i] is offset to start of data for i-th column */
int len; /* The length of the serialized data for the column */
int i; /* Loop counter */
Mem *pDest; /* Where to write the extracted value */
Mem sMem; /* For storing the record being decoded */
const u8 *zData; /* Part of the record being decoded */
const u8 *zHdr; /* Next unparsed byte of the header */
const u8 *zEndHdr; /* Pointer to first byte after the header */
u64 offset64; /* 64-bit offset */
u32 t; /* A type code from the record header */
Mem *pReg; /* PseudoTable input register */
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) );
pC = p->apCsr[pOp->p1];
p2 = (u32)pOp->p2;
op_column_restart:
assert( pC!=0 );
assert( p2<(u32)pC->nField
|| (pC->eCurType==CURTYPE_PSEUDO && pC->seekResult==0) );
aOffset = pC->aOffset;
assert( aOffset==pC->aType+pC->nField );
assert( pC->eCurType!=CURTYPE_VTAB );
assert( pC->eCurType!=CURTYPE_PSEUDO || pC->nullRow );
assert( pC->eCurType!=CURTYPE_SORTER );
if( pC->cacheStatus!=p->cacheCtr ){ /*OPTIMIZATION-IF-FALSE*/
if( pC->nullRow ){
if( pC->eCurType==CURTYPE_PSEUDO && pC->seekResult>0 ){
/* For the special case of as pseudo-cursor, the seekResult field
** identifies the register that holds the record */
pReg = &aMem[pC->seekResult];
assert( pReg->flags & MEM_Blob );
assert( memIsValid(pReg) );
pC->payloadSize = pC->szRow = pReg->n;
pC->aRow = (u8*)pReg->z;
}else{
pDest = &aMem[pOp->p3];
memAboutToChange(p, pDest);
sqlite3VdbeMemSetNull(pDest);
goto op_column_out;
}
}else{
pCrsr = pC->uc.pCursor;
if( pC->deferredMoveto ){
u32 iMap;
assert( !pC->isEphemeral );
if( pC->ub.aAltMap && (iMap = pC->ub.aAltMap[1+p2])>0 ){
pC = pC->pAltCursor;
p2 = iMap - 1;
goto op_column_restart;
}
rc = sqlite3VdbeFinishMoveto(pC);
if( rc ) goto abort_due_to_error;
}else if( sqlite3BtreeCursorHasMoved(pCrsr) ){
rc = sqlite3VdbeHandleMovedCursor(pC);
if( rc ) goto abort_due_to_error;
goto op_column_restart;
}
assert( pC->eCurType==CURTYPE_BTREE );
assert( pCrsr );
assert( sqlite3BtreeCursorIsValid(pCrsr) );
pC->payloadSize = sqlite3BtreePayloadSize(pCrsr);
pC->aRow = sqlite3BtreePayloadFetch(pCrsr, &pC->szRow);
assert( pC->szRow<=pC->payloadSize );
**
** Obtain a lock on a particular table. This instruction is only used when
** the shared-cache feature is enabled.
**
** P1 is the index of the database in sqlite3.aDb[] of the database
** on which the lock is acquired. A readlock is obtained if P3==0 or
** a write lock if P3==1.
**
** P2 contains the root-page of the table to lock.
**
** P4 contains a pointer to the name of the table being locked. This is only
** used to generate an error message if the lock cannot be obtained.
*/
case OP_TableLock: {
u8 isWriteLock = (u8)pOp->p3;
if( isWriteLock || 0==(db->flags&SQLITE_ReadUncommit) ){
int p1 = pOp->p1;
assert( p1>=0 && p1<db->nDb );
assert( DbMaskTest(p->btreeMask, p1) );
assert( isWriteLock==0 || isWriteLock==1 );
rc = sqlite3BtreeLockTable(db->aDb[p1].pBt, pOp->p2, isWriteLock);
if( rc ){
if( (rc&0xFF)==SQLITE_LOCKED ){
const char *z = pOp->p4.z;
sqlite3VdbeError(p, "database table is locked: %s", z);
}
goto abort_due_to_error;
}
}
break;
}
#endif /* SQLITE_OMIT_SHARED_CACHE */
#ifndef SQLITE_OMIT_VIRTUALTABLE
/* Opcode: VBegin * * * P4 *
**
** P4 may be a pointer to an sqlite3_vtab structure. If so, call the
** xBegin method for that table.
**
** Also, whether or not P4 is set, check that this is not being called from
** within a callback to a virtual table xSync() method. If it is, the error
** code will be set to SQLITE_LOCKED.
*/
case OP_VBegin: {
VTable *pVTab;
pVTab = pOp->p4.pVtab;
rc = sqlite3VtabBegin(db, pVTab);
if( pVTab ) sqlite3VtabImportErrmsg(p, pVTab->pVtab);
if( rc ) goto abort_due_to_error;
break;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */
#ifndef SQLITE_OMIT_VIRTUALTABLE
/* Opcode: VCreate P1 P2 * * *
**
** P2 is a register that holds the name of a virtual table in database
** P1. Call the xCreate method for that table.
*/
case OP_VCreate: {
Mem sMem; /* For storing the record being decoded */
const char *zTab; /* Name of the virtual table */
memset(&sMem, 0, sizeof(sMem));
sMem.db = db;
/* Because P2 is always a static string, it is impossible for the
** sqlite3VdbeMemCopy() to fail */
assert( (aMem[pOp->p2].flags & MEM_Str)!=0 );
assert( (aMem[pOp->p2].flags & MEM_Static)!=0 );
rc = sqlite3VdbeMemCopy(&sMem, &aMem[pOp->p2]);
assert( rc==SQLITE_OK );
zTab = (const char*)sqlite3_value_text(&sMem);
assert( zTab || db->mallocFailed );
if( zTab ){
rc = sqlite3VtabCallCreate(db, pOp->p1, zTab, &p->zErrMsg);
}
sqlite3VdbeMemRelease(&sMem);
if( rc ) goto abort_due_to_error;
break;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */
#ifndef SQLITE_OMIT_VIRTUALTABLE
/* Opcode: VDestroy P1 * * P4 *
**
** P4 is the name of a virtual table in database P1. Call the xDestroy method
** of that table.
*/
case OP_VDestroy: {
db->nVDestroy++;
rc = sqlite3VtabCallDestroy(db, pOp->p1, pOp->p4.z);
db->nVDestroy--;
assert( p->errorAction==OE_Abort && p->usesStmtJournal );
if( rc ) goto abort_due_to_error;
break;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */
#ifndef SQLITE_OMIT_VIRTUALTABLE
/* Opcode: VOpen P1 * * P4 *
**
** P4 is a pointer to a virtual table object, an sqlite3_vtab structure.
** P1 is a cursor number. This opcode opens a cursor to the virtual
** table and stores that cursor in P1.
*/
case OP_VOpen: { /* ncycle */
VdbeCursor *pCur;
sqlite3_vtab_cursor *pVCur;
sqlite3_vtab *pVtab;
const sqlite3_module *pModule;
assert( p->bIsReader );
pCur = p->apCsr[pOp->p1];
if( pCur!=0
&& ALWAYS( pCur->eCurType==CURTYPE_VTAB )
&& ALWAYS( pCur->uc.pVCur->pVtab==pOp->p4.pVtab->pVtab )
){
/* This opcode is a no-op if the cursor is already open */
break;
}
pVCur = 0;
*zOut++ = 0x80 + (u8)(c & 0x3F);
}else{
*zOut++ = 0xF0 + (u8)((c>>18) & 0x07);
*zOut++ = 0x80 + (u8)((c>>12) & 0x3F);
*zOut++ = 0x80 + (u8)((c>>6) & 0x3F);
*zOut++ = 0x80 + (u8)(c & 0x3F);
} \
}
*zOut = 0;
sqlite3_result_text64(context, (char*)z, zOut-z, sqlite3_free, SQLITE_UTF8);
}
/*
** The hex() function. Interpret the argument as a blob. Return
** a hexadecimal rendering as text.
*/
static void hexFunc(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
int i, n;
const unsigned char *pBlob;
char *zHex, *z;
assert( argc==1 );
UNUSED_PARAMETER(argc);
pBlob = sqlite3_value_blob(argv[0]);
n = sqlite3_value_bytes(argv[0]);
assert( pBlob==sqlite3_value_blob(argv[0]) ); /* No encoding change */
z = zHex = contextMalloc(context, ((i64)n)*2 + 1);
if( zHex ){
for(i=0; i<n; i++, pBlob++){
unsigned char c = *pBlob;
*(z++) = hexdigits[(c>>4)&0xf];
*(z++) = hexdigits[c&0xf];
}
*z = 0;
sqlite3_result_text64(context, zHex, (u64)(z-zHex),
sqlite3_free, SQLITE_UTF8);
}
}
/*
** Buffer zStr contains nStr bytes of utf-8 encoded text. Return 1 if zStr
** contains character ch, or 0 if it does not.
*/
static int strContainsChar(const u8 *zStr, int nStr, u32 ch){
const u8 *zEnd = &zStr[nStr];
const u8 *z = zStr;
while( z<zEnd ){
u32 tst = Utf8Read(z);
if( tst==ch ) return 1;
}
return 0;
}
/*
** The unhex() function. This function may be invoked with either one or
** two arguments. In both cases the first argument is interpreted as text
** a text value containing a set of pairs of hexadecimal digits which are
** decoded and returned as a blob.
**
** If there is only a single argument, then it must consist only of an
** even number of hexadecimal digits. Otherwise, return NULL.
**
** Or, if there is a second argument, then any character that appears in
** the second argument is also allowed to appear between pairs of hexadecimal
** digits in the first argument. If any other character appears in the
** first argument, or if one of the allowed characters appears between
** two hexadecimal digits that make up a single byte, NULL is returned.
**
** The following expressions are all true:
**
** unhex('ABCD') IS x'ABCD'
** unhex('AB CD') IS NULL
** unhex('AB CD', ' ') IS x'ABCD'
** unhex('A BCD', ' ') IS NULL
*/
static void unhexFunc(
sqlite3_context *pCtx,
int argc,
sqlite3_value **argv
){
const u8 *zPass = (const u8*)"";
int nPass = 0;
const u8 *zHex = sqlite3_value_text(argv[0]);
int nHex = sqlite3_value_bytes(argv[0]);
#ifdef SQLITE_DEBUG
const u8 *zEnd = zHex ? &zHex[nHex] : 0;
#endif
u8 *pBlob = 0;
u8 *p = 0;
assert( argc==1 || argc==2 );
if( argc==2 ){
zPass = sqlite3_value_text(argv[1]);
nPass = sqlite3_value_bytes(argv[1]);
}
if( !zHex || !zPass ) return;
p = pBlob = contextMalloc(pCtx, (nHex/2)+1);
if( pBlob ){
u8 c; /* Most significant digit of next byte */
u8 d; /* Least significant digit of next byte */
while( (c = *zHex)!=0x00 ){
while( !sqlite3Isxdigit(c) ){
u32 ch = Utf8Read(zHex);
assert( zHex<=zEnd );
if( !strContainsChar(zPass, nPass, ch) ) goto unhex_null;
c = *zHex;
if( c==0x00 ) goto unhex_done;
}
zHex++;
assert( *zEnd==0x00 );
assert( zHex<=zEnd );
d = *(zHex++);
if( !sqlite3Isxdigit(d) ) goto unhex_null;
*(p++) = (sqlite3HexToInt(c)<<4) | sqlite3HexToInt(d);
}
}
percentCompute(pCtx, 0);
}
/****** End of percentile family of functions ******/
#endif /* SQLITE_ENABLE_PERCENTILE */
#if defined(SQLITE_DEBUG) || defined(SQLITE_ENABLE_FILESTAT)
/*
** Implementation of sqlite_filestat(SCHEMA).
**
** Return JSON text that describes low-level debug/diagnostic information
** about the sqlite3_file object associated with SCHEMA.
*/
static void filestatFunc(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
sqlite3 *db = sqlite3_context_db_handle(context);
const char *zDbName;
sqlite3_str *pStr;
Btree *pBtree;
zDbName = (const char*)sqlite3_value_text(argv[0]);
pBtree = sqlite3DbNameToBtree(db, zDbName);
if( pBtree ){
Pager *pPager;
sqlite3_file *fd;
int rc;
sqlite3BtreeEnter(pBtree);
pPager = sqlite3BtreePager(pBtree);
assert( pPager!=0 );
fd = sqlite3PagerFile(pPager);
pStr = sqlite3_str_new(db);
if( pStr==0 ){
sqlite3_result_error_nomem(context);
}else{
sqlite3_str_append(pStr, "{\"db\":", 6);
rc = sqlite3OsFileControl(fd, SQLITE_FCNTL_FILESTAT, pStr);
if( rc ) sqlite3_str_append(pStr, "null", 4);
fd = sqlite3PagerJrnlFile(pPager);
if( fd && fd->pMethods!=0 ){
sqlite3_str_appendall(pStr, ",\"journal\":");
rc = sqlite3OsFileControl(fd, SQLITE_FCNTL_FILESTAT, pStr);
if( rc ) sqlite3_str_append(pStr, "null", 4);
}
sqlite3_str_append(pStr, "}", 1);
sqlite3_result_text(context, sqlite3_str_finish(pStr), -1,
sqlite3_free);
}
sqlite3BtreeLeave(pBtree);
}else{
sqlite3_result_text(context, "{}", 2, SQLITE_STATIC);
}
}
#endif /* SQLITE_DEBUG || SQLITE_ENABLE_FILESTAT */
#ifdef SQLITE_DEBUG
/*
** Implementation of fpdecode(x,y,z) function.
**
** x is a real number that is to be decoded. y is the precision.
** z is the maximum real precision. Return a string that shows the
** results of the sqlite3FpDecode() function.
**
** Used for testing and debugging only, specifically testing and debugging
** of the sqlite3FpDecode() function. This SQL function does not appear
** in production builds. This function is not an API and is subject to
** modification or removal in future versions of SQLite.
*/
static void fpdecodeFunc(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
FpDecode s;
double x;
int y, z;
char zBuf[100];
UNUSED_PARAMETER(argc);
assert( argc==3 );
x = sqlite3_value_double(argv[0]);
y = sqlite3_value_int(argv[1]);
z = sqlite3_value_int(argv[2]);
if( z<=0 ) z = 1;
sqlite3FpDecode(&s, x, y, z);
if( s.isSpecial==2 ){
sqlite3_snprintf(sizeof(zBuf), zBuf, "NaN");
}else{
sqlite3_snprintf(sizeof(zBuf), zBuf, "%c%.*s/%d", s.sign, s.n, s.z, s.iDP);
}
sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
}
#endif /* SQLITE_DEBUG */
#ifdef SQLITE_DEBUG
/*
** Implementation of parseuri(uri,flags) function.
**
** Required Arguments:
** "uri" The URI to parse.
** "flags" Bitmask of flags, as if to sqlite3_open_v2().
**
** Additional arguments beyond the first two make calls to
** sqlite3_uri_key() for integers and sqlite3_uri_parameter for
** anything else.
**
** The result is a string showing the results of calling sqlite3ParseUri().
**
** Used for testing and debugging only, specifically testing and debugging
** of the sqlite3ParseUri() function. This SQL function does not appear
** in production builds. This function is not an API and is subject to
** modification or removal in future versions of SQLite.
*/
static void parseuriFunc(
sqlite3_context *ctx,
int argc,
sqlite3_value **argv
){
sqlite3_str *pResult;
const char *zVfs;
const char *zUri;
** is happening when it is supposed to.
*/
SQLITE_API int sqlite3_xferopt_count;
#endif /* SQLITE_TEST */
#ifndef SQLITE_OMIT_XFER_OPT
/*
** Check to see if index pSrc is compatible as a source of data
** for index pDest in an insert transfer optimization. The rules
** for a compatible index:
**
** * The index is over the same set of columns
** * The same DESC and ASC markings occurs on all columns
** * The same onError processing (OE_Abort, OE_Ignore, etc)
** * The same collating sequence on each column
** * The index has the exact same WHERE clause
*/
static int xferCompatibleIndex(Index *pDest, Index *pSrc){
int i;
assert( pDest && pSrc );
assert( pDest->pTable!=pSrc->pTable );
if( pDest->nKeyCol!=pSrc->nKeyCol || pDest->nColumn!=pSrc->nColumn ){
return 0; /* Different number of columns */
}
if( pDest->onError!=pSrc->onError ){
return 0; /* Different conflict resolution strategies */
}
for(i=0; i<pSrc->nKeyCol; i++){
if( pSrc->aiColumn[i]!=pDest->aiColumn[i] ){
return 0; /* Different columns indexed */
}
if( pSrc->aiColumn[i]==XN_EXPR ){
assert( pSrc->aColExpr!=0 && pDest->aColExpr!=0 );
if( sqlite3ExprCompare(0, pSrc->aColExpr->a[i].pExpr,
pDest->aColExpr->a[i].pExpr, -1)!=0 ){
return 0; /* Different expressions in the index */
}
}
if( pSrc->aSortOrder[i]!=pDest->aSortOrder[i] ){
return 0; /* Different sort orders */
}
if( sqlite3_stricmp(pSrc->azColl[i],pDest->azColl[i])!=0 ){
return 0; /* Different collating sequences */
}
}
if( sqlite3ExprCompare(0, pSrc->pPartIdxWhere, pDest->pPartIdxWhere, -1) ){
return 0; /* Different WHERE clauses */
}
/* If no test above fails then the indices must be compatible */
return 1;
}
/*
** Attempt the transfer optimization on INSERTs of the form
**
** INSERT INTO tab1 SELECT * FROM tab2;
**
** The xfer optimization transfers raw records from tab2 over to tab1.
** Columns are not decoded and reassembled, which greatly improves
** performance. Raw index records are transferred in the same way.
**
** The xfer optimization is only attempted if tab1 and tab2 are compatible.
** There are lots of rules for determining compatibility - see comments
** embedded in the code for details.
**
** This routine returns TRUE if the optimization is guaranteed to be used.
** Sometimes the xfer optimization will only work if the destination table
** is empty - a factor that can only be determined at run-time. In that
** case, this routine generates code for the xfer optimization but also
** does a test to see if the destination table is empty and jumps over the
** xfer optimization code if the test fails. In that case, this routine
** returns FALSE so that the caller will know to go ahead and generate
** an unoptimized transfer. This routine also returns FALSE if there
** is no chance that the xfer optimization can be applied.
**
** This optimization is particularly useful at making VACUUM run faster.
*/
static int xferOptimization(
Parse *pParse, /* Parser context */
Table *pDest, /* The table we are inserting into */
Select *pSelect, /* A SELECT statement to use as the data source */
int onError, /* How to handle constraint errors */
int iDbDest /* The database of pDest */
){
sqlite3 *db = pParse->db;
ExprList *pEList; /* The result set of the SELECT */
Table *pSrc; /* The table in the FROM clause of SELECT */
Index *pSrcIdx, *pDestIdx; /* Source and destination indices */
SrcItem *pItem; /* An element of pSelect->pSrc */
int i; /* Loop counter */
int iDbSrc; /* The database of pSrc */
int iSrc, iDest; /* Cursors from source and destination */
int addr1, addr2; /* Loop addresses */
int emptyDestTest = 0; /* Address of test for empty pDest */
int emptySrcTest = 0; /* Address of test for empty pSrc */
Vdbe *v; /* The VDBE we are building */
int regAutoinc; /* Memory register used by AUTOINC */
int destHasUniqueIdx = 0; /* True if pDest has a UNIQUE index */
int regData, regRowid; /* Registers holding data and rowid */
assert( pSelect!=0 );
if( pParse->pWith || pSelect->pWith ){
/* Do not attempt to process this query if there are an WITH clauses
** attached to it. Proceeding may generate a false "no such table: xxx"
** error if pSelect reads from a CTE named "xxx". */
return 0;
}
#ifndef SQLITE_OMIT_VIRTUALTABLE
if( IsVirtual(pDest) ){
return 0; /* tab1 must not be a virtual table */
}
#endif
if( onError==OE_Default ){
if( pDest->iPKey>=0 ) onError = pDest->keyConf;
if( onError==OE_Default ) onError = OE_Abort;
}
assert(pSelect->pSrc); /* allocated even if there is no FROM clause */
if( pSelect->pSrc->nSrc!=1 ){
return 0; /* FROM clause must have exactly one term */
6, 9, 4, 2, 6, 5, 9, 9, 4, 7, 3, 2, 4,
4, 6, 11, 6, 2, 7, 5, 5, 9, 6, 10, 4, 6,
2, 3, 7, 5, 9, 6, 6, 4, 5, 5, 10, 6, 5,
7, 4, 5, 7, 6, 7, 7, 6, 5, 7, 3, 7, 4,
7, 6, 12, 9, 4, 6, 5, 4, 7, 6, 12, 8, 8,
2, 6, 6, 7, 6, 4, 5, 9, 5, 5, 6, 3, 4,
9, 13, 2, 2, 4, 6, 6, 8, 5, 17, 12, 7, 9,
4, 4, 6, 7, 5, 9, 4, 4, 5, 2, 5, 8, 6,
4, 9, 5, 8, 4, 3, 9, 5, 5, 6, 4, 6, 2,
2, 9, 3, 7,
};
/* aKWOffset[i] is the index into zKWText[] of the start of
** the text for the i-th keyword. */
static const unsigned short int aKWOffset[148] = {0,
0, 2, 2, 8, 9, 14, 16, 20, 23, 25, 25, 29, 33,
36, 41, 46, 48, 53, 54, 59, 62, 65, 67, 69, 78, 81,
86, 90, 90, 94, 99, 101, 105, 111, 119, 123, 123, 123, 126,
129, 132, 137, 142, 146, 147, 152, 156, 160, 168, 174, 181, 184,
184, 187, 189, 195, 198, 206, 211, 216, 219, 222, 226, 236, 239,
244, 244, 248, 252, 259, 265, 271, 277, 277, 283, 284, 288, 295,
299, 306, 312, 324, 333, 335, 341, 346, 348, 355, 359, 370, 377,
378, 385, 391, 397, 402, 408, 412, 415, 424, 429, 433, 439, 441,
444, 453, 455, 457, 466, 470, 476, 482, 490, 495, 495, 495, 511,
520, 523, 527, 532, 539, 544, 553, 557, 560, 565, 567, 571, 579,
585, 588, 597, 602, 610, 610, 614, 623, 628, 633, 639, 642, 645,
648, 650, 655, 659,
};
/* aKWCode[i] is the parser symbol code for the i-th keyword */
static const unsigned char aKWCode[148] = {0,
TK_REINDEX, TK_INDEXED, TK_INDEX, TK_DESC, TK_ESCAPE,
TK_EACH, TK_CHECK, TK_KEY, TK_BEFORE, TK_FOREIGN,
TK_FOR, TK_IGNORE, TK_LIKE_KW, TK_EXPLAIN, TK_INSTEAD,
TK_ADD, TK_DATABASE, TK_AS, TK_SELECT, TK_TABLE,
TK_JOIN_KW, TK_THEN, TK_END, TK_DEFERRABLE, TK_ELSE,
TK_EXCLUDE, TK_DELETE, TK_TEMP, TK_TEMP, TK_OR,
TK_ISNULL, TK_NULLS, TK_SAVEPOINT, TK_INTERSECT, TK_TIES,
TK_NOTNULL, TK_NOT, TK_NO, TK_NULL, TK_LIKE_KW,
TK_EXCEPT, TK_TRANSACTION,TK_ACTION, TK_ON, TK_JOIN_KW,
TK_ALTER, TK_RAISE, TK_EXCLUSIVE, TK_EXISTS, TK_CONSTRAINT,
TK_INTO, TK_OFFSET, TK_OF, TK_SET, TK_TRIGGER,
TK_RANGE, TK_GENERATED, TK_DETACH, TK_HAVING, TK_LIKE_KW,
TK_BEGIN, TK_JOIN_KW, TK_REFERENCES, TK_UNIQUE, TK_QUERY,
TK_WITHOUT, TK_WITH, TK_JOIN_KW, TK_RELEASE, TK_ATTACH,
TK_BETWEEN, TK_NOTHING, TK_GROUPS, TK_GROUP, TK_CASCADE,
TK_ASC, TK_DEFAULT, TK_CASE, TK_COLLATE, TK_CREATE,
TK_CTIME_KW, TK_IMMEDIATE, TK_JOIN, TK_INSERT, TK_MATCH,
TK_PLAN, TK_ANALYZE, TK_PRAGMA, TK_MATERIALIZED, TK_DEFERRED,
TK_DISTINCT, TK_IS, TK_UPDATE, TK_VALUES, TK_VIRTUAL,
TK_ALWAYS, TK_WHEN, TK_WHERE, TK_RECURSIVE, TK_ABORT,
TK_AFTER, TK_RENAME, TK_AND, TK_DROP, TK_PARTITION,
TK_AUTOINCR, TK_TO, TK_IN, TK_CAST, TK_COLUMNKW,
TK_COMMIT, TK_CONFLICT, TK_JOIN_KW, TK_CTIME_KW, TK_CTIME_KW,
TK_CURRENT, TK_PRECEDING, TK_FAIL, TK_LAST, TK_FILTER,
TK_REPLACE, TK_FIRST, TK_FOLLOWING, TK_FROM, TK_JOIN_KW,
TK_LIMIT, TK_IF, TK_ORDER, TK_RESTRICT, TK_OTHERS,
TK_OVER, TK_RETURNING, TK_JOIN_KW, TK_ROLLBACK, TK_ROWS,
TK_ROW, TK_UNBOUNDED, TK_UNION, TK_USING, TK_VACUUM,
TK_VIEW, TK_WINDOW, TK_DO, TK_BY, TK_INITIALLY,
TK_ALL, TK_PRIMARY,
};
/* Hash table decoded:
** 0: INSERT
** 1: IS
** 2: ROLLBACK TRIGGER
** 3: IMMEDIATE
** 4: PARTITION
** 5: TEMP
** 6:
** 7:
** 8: VALUES WITHOUT
** 9:
** 10: MATCH
** 11: NOTHING
** 12:
** 13: OF
** 14: TIES IGNORE
** 15: PLAN
** 16: INSTEAD INDEXED
** 17:
** 18: TRANSACTION RIGHT
** 19: WHEN
** 20: SET HAVING
** 21: MATERIALIZED IF
** 22: ROWS
** 23: SELECT
** 24:
** 25:
** 26: VACUUM SAVEPOINT
** 27:
** 28: LIKE UNION VIRTUAL REFERENCES
** 29: RESTRICT
** 30:
** 31: THEN REGEXP
** 32: TO
** 33:
** 34: BEFORE
** 35:
** 36:
** 37: FOLLOWING COLLATE CASCADE
** 38: CREATE
** 39:
** 40: CASE REINDEX
** 41: EACH
** 42:
** 43: QUERY
** 44: AND ADD
** 45: PRIMARY ANALYZE
** 46:
** 47: ROW ASC DETACH
** 48: CURRENT_TIME CURRENT_DATE
** 49:
** 50:
** 51: EXCLUSIVE TEMPORARY
** 52:
** 53: DEFERRED
** 54: DEFERRABLE
** 55:
** 56: DATABASE
** 57:
** 58: DELETE VIEW GENERATED
** 59: ATTACH
if( pCsr->aConstraint ){
int i; /* Used to iterate through constraint array */
for(i=0; i<pCsr->nConstraint; i++){
sqlite3_rtree_query_info *pInfo = pCsr->aConstraint[i].pInfo;
if( pInfo ){
if( pInfo->xDelUser ) pInfo->xDelUser(pInfo->pUser);
sqlite3_free(pInfo);
}
}
sqlite3_free(pCsr->aConstraint);
pCsr->aConstraint = 0;
}
for(ii=0; ii<RTREE_CACHE_SZ; ii++) nodeRelease(pRtree, pCsr->aNode[ii]);
sqlite3_free(pCsr->aPoint);
pStmt = pCsr->pReadAux;
memset(pCsr, 0, sizeof(RtreeCursor));
pCsr->base.pVtab = (sqlite3_vtab*)pRtree;
pCsr->pReadAux = pStmt;
/* The following will only fail if the previous sqlite3_step() call failed,
** in which case the error has already been caught. This statement never
** encounters an error within an sqlite3_column_xxx() function, as it
** calls sqlite3_column_value(), which does not use malloc(). So it is safe
** to ignore the error code here. */
sqlite3_reset(pStmt);
}
/*
** Rtree virtual table module xClose method.
*/
static int rtreeClose(sqlite3_vtab_cursor *cur){
Rtree *pRtree = (Rtree *)(cur->pVtab);
RtreeCursor *pCsr = (RtreeCursor *)cur;
assert( pRtree->nCursor>0 );
resetCursor(pCsr);
sqlite3_finalize(pCsr->pReadAux);
sqlite3_free(pCsr);
pRtree->nCursor--;
if( pRtree->nCursor==0 && pRtree->inWrTrans==0 ){
nodeBlobReset(pRtree);
}
return SQLITE_OK;
}
/*
** Rtree virtual table module xEof method.
**
** Return non-zero if the cursor does not currently point to a valid
** record (i.e if the scan has finished), or zero otherwise.
*/
static int rtreeEof(sqlite3_vtab_cursor *cur){
RtreeCursor *pCsr = (RtreeCursor *)cur;
return pCsr->atEOF;
}
/*
** Convert raw bits from the on-disk RTree record into a coordinate value.
** The on-disk format is big-endian and needs to be converted for little-
** endian platforms. The on-disk record stores integer coordinates if
** eInt is true and it stores 32-bit floating point records if eInt is
** false. a[] is the four bytes of the on-disk record to be decoded.
** Store the results in "r".
**
** There are five versions of this macro. The last one is generic. The
** other four are various architectures-specific optimizations.
*/
#if SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300
#define RTREE_DECODE_COORD(eInt, a, r) { \
RtreeCoord c; /* Coordinate decoded */ \
c.u = _byteswap_ulong(*(u32*)a); \
r = eInt ? (sqlite3_rtree_dbl)c.i : (sqlite3_rtree_dbl)c.f; \
}
#elif SQLITE_BYTEORDER==1234 && GCC_VERSION>=4003000
#define RTREE_DECODE_COORD(eInt, a, r) { \
RtreeCoord c; /* Coordinate decoded */ \
c.u = __builtin_bswap32(*(u32*)a); \
r = eInt ? (sqlite3_rtree_dbl)c.i : (sqlite3_rtree_dbl)c.f; \
}
#elif SQLITE_BYTEORDER==1234
#define RTREE_DECODE_COORD(eInt, a, r) { \
RtreeCoord c; /* Coordinate decoded */ \
memcpy(&c.u,a,4); \
c.u = ((c.u>>24)&0xff)|((c.u>>8)&0xff00)| \
((c.u&0xff)<<24)|((c.u&0xff00)<<8); \
r = eInt ? (sqlite3_rtree_dbl)c.i : (sqlite3_rtree_dbl)c.f; \
}
#elif SQLITE_BYTEORDER==4321
#define RTREE_DECODE_COORD(eInt, a, r) { \
RtreeCoord c; /* Coordinate decoded */ \
memcpy(&c.u,a,4); \
r = eInt ? (sqlite3_rtree_dbl)c.i : (sqlite3_rtree_dbl)c.f; \
}
#else
#define RTREE_DECODE_COORD(eInt, a, r) { \
RtreeCoord c; /* Coordinate decoded */ \
c.u = ((u32)a[0]<<24) + ((u32)a[1]<<16) \
+((u32)a[2]<<8) + a[3]; \
r = eInt ? (sqlite3_rtree_dbl)c.i : (sqlite3_rtree_dbl)c.f; \
}
#endif
/*
** Check the RTree node or entry given by pCellData and p against the MATCH
** constraint pConstraint.
*/
static int rtreeCallbackConstraint(
RtreeConstraint *pConstraint, /* The constraint to test */
int eInt, /* True if RTree holding integer coordinates */
u8 *pCellData, /* Raw cell content */
RtreeSearchPoint *pSearch, /* Container of this cell */
sqlite3_rtree_dbl *prScore, /* OUT: score for the cell */
int *peWithin /* OUT: visibility of the cell */
){
sqlite3_rtree_query_info *pInfo = pConstraint->pInfo; /* Callback info */
int nCoord = pInfo->nCoord; /* No. of coordinates */
int rc; /* Callback return code */
RtreeCoord c; /* Translator union */
sqlite3_rtree_dbl aCoord[RTREE_MAX_DIMENSIONS*2]; /* Decoded coordinates */
assert( pConstraint->op==RTREE_MATCH || pConstraint->op==RTREE_QUERY );
assert( nCoord==2 || nCoord==4 || nCoord==6 || nCoord==8 || nCoord==10 );
if( pConstraint->op==RTREE_QUERY && pSearch->iLevel==1 ){
pInfo->iRowid = readInt64(pCellData);
}
pCellData += 8;
#ifndef SQLITE_RTREE_INT_ONLY
if( eInt==0 ){
switch( nCoord ){
case 10: readCoord(pCellData+36, &c); aCoord[9] = c.f;
readCoord(pCellData+32, &c); aCoord[8] = c.f;
case 8: readCoord(pCellData+28, &c); aCoord[7] = c.f;
readCoord(pCellData+24, &c); aCoord[6] = c.f;
case 6: readCoord(pCellData+20, &c); aCoord[5] = c.f;
readCoord(pCellData+16, &c); aCoord[4] = c.f;
case 4: readCoord(pCellData+12, &c); aCoord[3] = c.f;
readCoord(pCellData+8, &c); aCoord[2] = c.f;
default: readCoord(pCellData+4, &c); aCoord[1] = c.f;
readCoord(pCellData, &c); aCoord[0] = c.f;
}
}else
#endif
{
switch( nCoord ){
case 10: readCoord(pCellData+36, &c); aCoord[9] = c.i;
readCoord(pCellData+32, &c); aCoord[8] = c.i;
case 8: readCoord(pCellData+28, &c); aCoord[7] = c.i;
readCoord(pCellData+24, &c); aCoord[6] = c.i;
case 6: readCoord(pCellData+20, &c); aCoord[5] = c.i;
readCoord(pCellData+16, &c); aCoord[4] = c.i;
case 4: readCoord(pCellData+12, &c); aCoord[3] = c.i;
readCoord(pCellData+8, &c); aCoord[2] = c.i;
default: readCoord(pCellData+4, &c); aCoord[1] = c.i;
readCoord(pCellData, &c); aCoord[0] = c.i;
}
** no-op. If an OOM or other error occurs within this function, *pRc is
** set to an SQLite error code before returning. The final state of buffer
** pBuf is undefined in this case.
*/
static void fts5DecodeRowidList(
int *pRc, /* IN/OUT: Error code */
Fts5Buffer *pBuf, /* Buffer to append text to */
const u8 *pData, int nData /* Data to decode list-of-rowids from */
){
int i = 0;
i64 iRowid = 0;
while( i<nData ){
const char *zApp = "";
u64 iVal;
i += sqlite3Fts5GetVarint(&pData[i], &iVal);
iRowid += iVal;
if( i<nData && pData[i]==0x00 ){
i++;
if( i<nData && pData[i]==0x00 ){
i++;
zApp = "+";
}else{
zApp = "*";
}
}
sqlite3Fts5BufferAppendPrintf(pRc, pBuf, " %lld%s", iRowid, zApp);
}
}
#endif /* SQLITE_TEST || SQLITE_FTS5_DEBUG */
#if defined(SQLITE_TEST) || defined(SQLITE_FTS5_DEBUG)
static void fts5BufferAppendTerm(int *pRc, Fts5Buffer *pBuf, Fts5Buffer *pTerm){
int ii;
fts5BufferGrow(pRc, pBuf, pTerm->n*2 + 1);
if( *pRc==SQLITE_OK ){
for(ii=0; ii<pTerm->n; ii++){
if( pTerm->p[ii]==0x00 ){
pBuf->p[pBuf->n++] = '\\';
pBuf->p[pBuf->n++] = '0';
}else{
pBuf->p[pBuf->n++] = pTerm->p[ii];
}
}
pBuf->p[pBuf->n] = 0x00;
}
}
#endif /* SQLITE_TEST || SQLITE_FTS5_DEBUG */
#if defined(SQLITE_TEST) || defined(SQLITE_FTS5_DEBUG)
/*
** The implementation of user-defined scalar function fts5_decode().
*/
static void fts5DecodeFunction(
sqlite3_context *pCtx, /* Function call context */
int nArg, /* Number of args (always 2) */
sqlite3_value **apVal /* Function arguments */
){
i64 iRowid; /* Rowid for record being decoded */
int iSegid,iHeight,iPgno,bDlidx;/* Rowid components */
int bTomb;
const u8 *aBlob; int n; /* Record to decode */
u8 *a = 0;
Fts5Buffer s; /* Build up text to return here */
int rc = SQLITE_OK; /* Return code */
sqlite3_int64 nSpace = 0;
int eDetailNone = (sqlite3_user_data(pCtx)!=0);
assert( nArg==2 );
UNUSED_PARAM(nArg);
memset(&s, 0, sizeof(Fts5Buffer));
iRowid = sqlite3_value_int64(apVal[0]);
/* Make a copy of the second argument (a blob) in aBlob[]. The aBlob[]
** copy is followed by FTS5_DATA_ZERO_PADDING 0x00 bytes, which prevents
** buffer overreads even if the record is corrupt. */
n = sqlite3_value_bytes(apVal[1]);
aBlob = sqlite3_value_blob(apVal[1]);
nSpace = ((i64)n) + FTS5_DATA_ZERO_PADDING;
a = (u8*)sqlite3Fts5MallocZero(&rc, nSpace);
if( a==0 ) goto decode_out;
if( n>0 ) memcpy(a, aBlob, n);
fts5DecodeRowid(iRowid, &bTomb, &iSegid, &bDlidx, &iHeight, &iPgno);
fts5DebugRowid(&rc, &s, iRowid);
if( bDlidx ){
Fts5Data dlidx;
Fts5DlidxLvl lvl;
dlidx.p = a;
dlidx.nn = n;
memset(&lvl, 0, sizeof(Fts5DlidxLvl));
lvl.pData = &dlidx;
lvl.iLeafPgno = iPgno;
for(fts5DlidxLvlNext(&lvl); lvl.bEof==0; fts5DlidxLvlNext(&lvl)){
sqlite3Fts5BufferAppendPrintf(&rc, &s,
" %d(%lld)", lvl.iLeafPgno, lvl.iRowid
);
}
}else if( bTomb ){
u32 nElem = fts5GetU32(&a[4]);
int szKey = (aBlob[0]==4 || aBlob[0]==8) ? aBlob[0] : 8;
int nSlot = (n - 8) / szKey;
int ii;
sqlite3Fts5BufferAppendPrintf(&rc, &s, " nElem=%d", (int)nElem);
if( aBlob[1] ){
sqlite3Fts5BufferAppendPrintf(&rc, &s, " 0");
}
for(ii=0; ii<nSlot; ii++){
u64 iVal = 0;
if( szKey==4 ){
u32 *aSlot = (u32*)&aBlob[8];
if( aSlot[ii] ) iVal = fts5GetU32((u8*)&aSlot[ii]);
}else{
u64 *aSlot = (u64*)&aBlob[8];
if( aSlot[ii] ) iVal = fts5GetU64((u8*)&aSlot[ii]);
( run in 0.482 second using v1.01-cache-2.11-cpan-13bb782fe5a )