mirror of
https://github.com/php/php-src.git
synced 2025-08-20 01:14:28 +02:00
Upgraded bundled sqlite lib to 3.2.2
This commit is contained in:
parent
efc6ccaa01
commit
7d02c9dcb2
51 changed files with 5222 additions and 3790 deletions
|
|
@ -57,10 +57,16 @@ void sqlite3VdbeTrace(Vdbe *p, FILE *trace){
|
|||
|
||||
/*
|
||||
** Resize the Vdbe.aOp array so that it contains at least N
|
||||
** elements. If the Vdbe is in VDBE_MAGIC_RUN state, then
|
||||
** the Vdbe.aOp array will be sized to contain exactly N
|
||||
** elements.
|
||||
*/
|
||||
static void resizeOpArray(Vdbe *p, int N){
|
||||
if( p->nOpAlloc<N ){
|
||||
if( p->magic==VDBE_MAGIC_RUN ){
|
||||
assert( N==p->nOp );
|
||||
p->nOpAlloc = N;
|
||||
p->aOp = sqliteRealloc(p->aOp, N*sizeof(Op));
|
||||
}else if( p->nOpAlloc<N ){
|
||||
int oldSize = p->nOpAlloc;
|
||||
p->nOpAlloc = N+100;
|
||||
p->aOp = sqliteRealloc(p->aOp, p->nOpAlloc*sizeof(Op));
|
||||
|
|
@ -160,25 +166,123 @@ void sqlite3VdbeResolveLabel(Vdbe *p, int x){
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Return non-zero if opcode 'op' is guarenteed not to push more values
|
||||
** onto the VDBE stack than it pops off.
|
||||
*/
|
||||
static int opcodeNoPush(u8 op){
|
||||
/* The 10 NOPUSH_MASK_n constants are defined in the automatically
|
||||
** generated header file opcodes.h. Each is a 16-bit bitmask, one
|
||||
** bit corresponding to each opcode implemented by the virtual
|
||||
** machine in vdbe.c. The bit is true if the word "no-push" appears
|
||||
** in a comment on the same line as the "case OP_XXX:" in
|
||||
** sqlite3VdbeExec() in vdbe.c.
|
||||
**
|
||||
** If the bit is true, then the corresponding opcode is guarenteed not
|
||||
** to grow the stack when it is executed. Otherwise, it may grow the
|
||||
** stack by at most one entry.
|
||||
**
|
||||
** NOPUSH_MASK_0 corresponds to opcodes 0 to 15. NOPUSH_MASK_1 contains
|
||||
** one bit for opcodes 16 to 31, and so on.
|
||||
**
|
||||
** 16-bit bitmasks (rather than 32-bit) are specified in opcodes.h
|
||||
** because the file is generated by an awk program. Awk manipulates
|
||||
** all numbers as floating-point and we don't want to risk a rounding
|
||||
** error if someone builds with an awk that uses (for example) 32-bit
|
||||
** IEEE floats.
|
||||
*/
|
||||
static const u32 masks[5] = {
|
||||
NOPUSH_MASK_0 + (NOPUSH_MASK_1<<16),
|
||||
NOPUSH_MASK_2 + (NOPUSH_MASK_3<<16),
|
||||
NOPUSH_MASK_4 + (NOPUSH_MASK_5<<16),
|
||||
NOPUSH_MASK_6 + (NOPUSH_MASK_7<<16),
|
||||
NOPUSH_MASK_8 + (NOPUSH_MASK_9<<16)
|
||||
};
|
||||
return (masks[op>>5] & (1<<(op&0x1F)));
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
int sqlite3VdbeOpcodeNoPush(u8 op){
|
||||
return opcodeNoPush(op);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Loop through the program looking for P2 values that are negative.
|
||||
** Each such value is a label. Resolve the label by setting the P2
|
||||
** value to its correct non-zero value.
|
||||
**
|
||||
** This routine is called once after all opcodes have been inserted.
|
||||
**
|
||||
** Variable *pMaxFuncArgs is set to the maximum value of any P1 argument
|
||||
** to an OP_Function or P2 to an OP_AggFunc opcode. This is used by
|
||||
** sqlite3VdbeMakeReady() to size the Vdbe.apArg[] array.
|
||||
**
|
||||
** The integer *pMaxStack is set to the maximum number of vdbe stack
|
||||
** entries that static analysis reveals this program might need.
|
||||
**
|
||||
** This routine also does the following optimization: It scans for
|
||||
** Halt instructions where P1==SQLITE_CONSTRAINT or P2==OE_Abort or for
|
||||
** IdxInsert instructions where P2!=0. If no such instruction is
|
||||
** found, then every Statement instruction is changed to a Noop. In
|
||||
** this way, we avoid creating the statement journal file unnecessarily.
|
||||
*/
|
||||
static void resolveP2Values(Vdbe *p){
|
||||
static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs, int *pMaxStack){
|
||||
int i;
|
||||
int nMaxArgs = 0;
|
||||
int nMaxStack = p->nOp;
|
||||
Op *pOp;
|
||||
int *aLabel = p->aLabel;
|
||||
if( aLabel==0 ) return;
|
||||
int doesStatementRollback = 0;
|
||||
int hasStatementBegin = 0;
|
||||
for(pOp=p->aOp, i=p->nOp-1; i>=0; i--, pOp++){
|
||||
u8 opcode = pOp->opcode;
|
||||
|
||||
/* Todo: Maybe OP_AggFunc should change to use P1 in the same
|
||||
* way as OP_Function.
|
||||
*/
|
||||
if( opcode==OP_Function ){
|
||||
if( pOp->p1>nMaxArgs ) nMaxArgs = pOp->p1;
|
||||
}else if( opcode==OP_AggFunc ){
|
||||
if( pOp->p2>nMaxArgs ) nMaxArgs = pOp->p2;
|
||||
}else if( opcode==OP_Halt ){
|
||||
if( pOp->p1==SQLITE_CONSTRAINT && pOp->p2==OE_Abort ){
|
||||
doesStatementRollback = 1;
|
||||
}
|
||||
}else if( opcode==OP_IdxInsert ){
|
||||
if( pOp->p2 ){
|
||||
doesStatementRollback = 1;
|
||||
}
|
||||
}else if( opcode==OP_Statement ){
|
||||
hasStatementBegin = 1;
|
||||
}
|
||||
|
||||
if( opcodeNoPush(opcode) ){
|
||||
nMaxStack--;
|
||||
}
|
||||
|
||||
if( pOp->p2>=0 ) continue;
|
||||
assert( -1-pOp->p2<p->nLabel );
|
||||
pOp->p2 = aLabel[-1-pOp->p2];
|
||||
}
|
||||
sqliteFree(p->aLabel);
|
||||
p->aLabel = 0;
|
||||
|
||||
*pMaxFuncArgs = nMaxArgs;
|
||||
*pMaxStack = nMaxStack;
|
||||
|
||||
/* If we never rollback a statement transaction, then statement
|
||||
** transactions are not needed. So change every OP_Statement
|
||||
** opcode into an OP_Noop. This avoid a call to sqlite3OsOpenExclusive()
|
||||
** which can be expensive on some platforms.
|
||||
*/
|
||||
if( hasStatementBegin && !doesStatementRollback ){
|
||||
for(pOp=p->aOp, i=p->nOp-1; i>=0; i--, pOp++){
|
||||
if( pOp->opcode==OP_Statement ){
|
||||
pOp->opcode = OP_Noop;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -259,19 +363,32 @@ void sqlite3VdbeChangeP2(Vdbe *p, int addr, int val){
|
|||
** A value of n==0 means copy bytes of zP3 up to and including the
|
||||
** first null byte. If n>0 then copy n+1 bytes of zP3.
|
||||
**
|
||||
** If n==P3_STATIC it means that zP3 is a pointer to a constant static
|
||||
** string and we can just copy the pointer. n==P3_POINTER means zP3 is
|
||||
** a pointer to some object other than a string. n==P3_COLLSEQ and
|
||||
** n==P3_KEYINFO mean that zP3 is a pointer to a CollSeq or KeyInfo
|
||||
** structure. A copy is made of KeyInfo structures into memory obtained
|
||||
** from sqliteMalloc.
|
||||
** If n==P3_KEYINFO it means that zP3 is a pointer to a KeyInfo structure.
|
||||
** A copy is made of the KeyInfo structure into memory obtained from
|
||||
** sqliteMalloc, to be freed when the Vdbe is finalized.
|
||||
** n==P3_KEYINFO_HANDOFF indicates that zP3 points to a KeyInfo structure
|
||||
** stored in memory that the caller has obtained from sqliteMalloc. The
|
||||
** caller should not free the allocation, it will be freed when the Vdbe is
|
||||
** finalized.
|
||||
**
|
||||
** Other values of n (P3_STATIC, P3_COLLSEQ etc.) indicate that zP3 points
|
||||
** to a string or structure that is guaranteed to exist for the lifetime of
|
||||
** the Vdbe. In these cases we can just copy the pointer.
|
||||
**
|
||||
** If addr<0 then change P3 on the most recently inserted instruction.
|
||||
*/
|
||||
void sqlite3VdbeChangeP3(Vdbe *p, int addr, const char *zP3, int n){
|
||||
Op *pOp;
|
||||
assert( p->magic==VDBE_MAGIC_INIT );
|
||||
if( p==0 || p->aOp==0 ) return;
|
||||
if( p==0 || p->aOp==0 ){
|
||||
if( n==P3_DYNAMIC || n==P3_KEYINFO_HANDOFF ){
|
||||
sqliteFree((void*)zP3);
|
||||
}
|
||||
if( n==P3_MEM ){
|
||||
sqlite3ValueFree((sqlite3_value *)zP3);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if( addr<0 || addr>=p->nOp ){
|
||||
addr = p->nOp - 1;
|
||||
if( addr<0 ) return;
|
||||
|
|
@ -385,11 +502,6 @@ static char *displayP3(Op *pOp, char *zTemp, int nTemp){
|
|||
char *zP3;
|
||||
assert( nTemp>=20 );
|
||||
switch( pOp->p3type ){
|
||||
case P3_POINTER: {
|
||||
sprintf(zTemp, "ptr(%#x)", (int)pOp->p3);
|
||||
zP3 = zTemp;
|
||||
break;
|
||||
}
|
||||
case P3_KEYINFO: {
|
||||
int i, j;
|
||||
KeyInfo *pKeyInfo = (KeyInfo*)pOp->p3;
|
||||
|
|
@ -598,20 +710,33 @@ void sqlite3VdbeMakeReady(
|
|||
*/
|
||||
assert( p->nOp>0 );
|
||||
|
||||
/* Set the magic to VDBE_MAGIC_RUN sooner rather than later. This
|
||||
* is because the call to resizeOpArray() below may shrink the
|
||||
* p->aOp[] array to save memory if called when in VDBE_MAGIC_RUN
|
||||
* state.
|
||||
*/
|
||||
p->magic = VDBE_MAGIC_RUN;
|
||||
|
||||
/* No instruction ever pushes more than a single element onto the
|
||||
** stack. And the stack never grows on successive executions of the
|
||||
** same loop. So the total number of instructions is an upper bound
|
||||
** on the maximum stack depth required.
|
||||
** on the maximum stack depth required. (Added later:) The
|
||||
** resolveP2Values() call computes a tighter upper bound on the
|
||||
** stack size.
|
||||
**
|
||||
** Allocation all the stack space we will ever need.
|
||||
*/
|
||||
if( p->aStack==0 ){
|
||||
resolveP2Values(p);
|
||||
int nArg; /* Maximum number of args passed to a user function. */
|
||||
int nStack; /* Maximum number of stack entries required */
|
||||
resolveP2Values(p, &nArg, &nStack);
|
||||
resizeOpArray(p, p->nOp);
|
||||
assert( nVar>=0 );
|
||||
n = isExplain ? 10 : p->nOp;
|
||||
assert( nStack<p->nOp );
|
||||
nStack = isExplain ? 10 : nStack;
|
||||
p->aStack = sqliteMalloc(
|
||||
n*sizeof(p->aStack[0]) /* aStack */
|
||||
+ n*sizeof(Mem*) /* apArg */
|
||||
nStack*sizeof(p->aStack[0]) /* aStack */
|
||||
+ nArg*sizeof(Mem*) /* apArg */
|
||||
+ nVar*sizeof(Mem) /* aVar */
|
||||
+ nVar*sizeof(char*) /* azVar */
|
||||
+ nMem*sizeof(Mem) /* aMem */
|
||||
|
|
@ -619,13 +744,13 @@ void sqlite3VdbeMakeReady(
|
|||
+ nAgg*sizeof(Agg) /* Aggregate contexts */
|
||||
);
|
||||
if( !sqlite3_malloc_failed ){
|
||||
p->aMem = &p->aStack[n];
|
||||
p->aMem = &p->aStack[nStack];
|
||||
p->nMem = nMem;
|
||||
p->aVar = &p->aMem[nMem];
|
||||
p->nVar = nVar;
|
||||
p->okVar = 0;
|
||||
p->apArg = (Mem**)&p->aVar[nVar];
|
||||
p->azVar = (char**)&p->apArg[n];
|
||||
p->azVar = (char**)&p->apArg[nArg];
|
||||
p->apCsr = (Cursor**)&p->azVar[nVar];
|
||||
if( nAgg>0 ){
|
||||
p->nAgg = nAgg;
|
||||
|
|
@ -690,6 +815,7 @@ void sqlite3VdbeSorterReset(Vdbe *p){
|
|||
sqlite3VdbeMemRelease(&pSorter->data);
|
||||
sqliteFree(pSorter);
|
||||
}
|
||||
p->pSortTail = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -1017,6 +1143,7 @@ static int vdbeCommit(sqlite3 *db){
|
|||
** This requires a master journal file to ensure the transaction is
|
||||
** committed atomicly.
|
||||
*/
|
||||
#ifndef SQLITE_OMIT_DISKIO
|
||||
else{
|
||||
char *zMaster = 0; /* File-name for the master journal */
|
||||
char const *zMainFile = sqlite3BtreeGetFilename(db->aDb[0].pBt);
|
||||
|
|
@ -1133,6 +1260,7 @@ static int vdbeCommit(sqlite3 *db){
|
|||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
|
@ -1420,6 +1548,9 @@ void sqlite3VdbeDelete(Vdbe *p){
|
|||
sqlite3VdbeDeleteAuxData(pVdbeFunc, 0);
|
||||
sqliteFree(pVdbeFunc);
|
||||
}
|
||||
if( pOp->p3type==P3_MEM ){
|
||||
sqlite3ValueFree((sqlite3_value*)pOp->p3);
|
||||
}
|
||||
}
|
||||
sqliteFree(p->aOp);
|
||||
}
|
||||
|
|
@ -1441,8 +1572,8 @@ int sqlite3VdbeCursorMoveto(Cursor *p){
|
|||
if( p->deferredMoveto ){
|
||||
int res, rc;
|
||||
extern int sqlite3_search_count;
|
||||
assert( p->intKey );
|
||||
if( p->intKey ){
|
||||
assert( p->isTable );
|
||||
if( p->isTable ){
|
||||
rc = sqlite3BtreeMoveto(p->pCursor, 0, p->movetoTarget, &res);
|
||||
}else{
|
||||
rc = sqlite3BtreeMoveto(p->pCursor,(char*)&p->movetoTarget,
|
||||
|
|
@ -1450,8 +1581,8 @@ int sqlite3VdbeCursorMoveto(Cursor *p){
|
|||
}
|
||||
if( rc ) return rc;
|
||||
*p->pIncrKey = 0;
|
||||
p->lastRecno = keyToInt(p->movetoTarget);
|
||||
p->recnoIsValid = res==0;
|
||||
p->lastRowid = keyToInt(p->movetoTarget);
|
||||
p->rowidIsValid = res==0;
|
||||
if( res<0 ){
|
||||
rc = sqlite3BtreeNext(p->pCursor, &res);
|
||||
if( rc ) return rc;
|
||||
|
|
@ -1512,7 +1643,7 @@ u32 sqlite3VdbeSerialType(Mem *pMem){
|
|||
}
|
||||
if( flags&MEM_Int ){
|
||||
/* Figure out whether to use 1, 2, 4, 6 or 8 bytes. */
|
||||
# define MAX_6BYTE ((((i64)0x00010000)<<32)-1)
|
||||
# define MAX_6BYTE ((((i64)0x00001000)<<32)-1)
|
||||
i64 i = pMem->i;
|
||||
u64 u = i<0 ? -i : i;
|
||||
if( u<=127 ) return 1;
|
||||
|
|
@ -1595,61 +1726,71 @@ int sqlite3VdbeSerialGet(
|
|||
u32 serial_type, /* Serial type to deserialize */
|
||||
Mem *pMem /* Memory cell to write value into */
|
||||
){
|
||||
int len;
|
||||
|
||||
if( serial_type==0 ){
|
||||
/* NULL */
|
||||
pMem->flags = MEM_Null;
|
||||
return 0;
|
||||
}
|
||||
len = sqlite3VdbeSerialTypeLen(serial_type);
|
||||
if( serial_type<=7 ){
|
||||
/* Integer and Real */
|
||||
if( serial_type<=4 ){
|
||||
/* 32-bit integer type. This is handled by a special case for
|
||||
** performance reasons. */
|
||||
int v = buf[0];
|
||||
int n;
|
||||
if( v&0x80 ){
|
||||
v |= -256;
|
||||
}
|
||||
for(n=1; n<len; n++){
|
||||
v = (v<<8) | buf[n];
|
||||
}
|
||||
switch( serial_type ){
|
||||
case 8: /* Reserved for future use */
|
||||
case 9: /* Reserved for future use */
|
||||
case 10: /* Reserved for future use */
|
||||
case 11: /* Reserved for future use */
|
||||
case 0: { /* NULL */
|
||||
pMem->flags = MEM_Null;
|
||||
break;
|
||||
}
|
||||
case 1: { /* 1-byte signed integer */
|
||||
pMem->i = (signed char)buf[0];
|
||||
pMem->flags = MEM_Int;
|
||||
pMem->i = v;
|
||||
return n;
|
||||
}else{
|
||||
u64 v = 0;
|
||||
int n;
|
||||
|
||||
if( buf[0]&0x80 ){
|
||||
v = -1;
|
||||
}
|
||||
for(n=0; n<len; n++){
|
||||
v = (v<<8) | buf[n];
|
||||
}
|
||||
if( serial_type==7 ){
|
||||
pMem->flags = MEM_Real;
|
||||
pMem->r = *(double*)&v;
|
||||
}else{
|
||||
pMem->flags = MEM_Int;
|
||||
pMem->i = *(i64*)&v;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
}else{
|
||||
/* String or blob */
|
||||
assert( serial_type>=12 );
|
||||
pMem->z = (char *)buf;
|
||||
pMem->n = len;
|
||||
pMem->xDel = 0;
|
||||
if( serial_type&0x01 ){
|
||||
pMem->flags = MEM_Str | MEM_Ephem;
|
||||
}else{
|
||||
pMem->flags = MEM_Blob | MEM_Ephem;
|
||||
case 2: { /* 2-byte signed integer */
|
||||
pMem->i = (((signed char)buf[0])<<8) | buf[1];
|
||||
pMem->flags = MEM_Int;
|
||||
return 2;
|
||||
}
|
||||
case 3: { /* 3-byte signed integer */
|
||||
pMem->i = (((signed char)buf[0])<<16) | (buf[1]<<8) | buf[2];
|
||||
pMem->flags = MEM_Int;
|
||||
return 3;
|
||||
}
|
||||
case 4: { /* 4-byte signed integer */
|
||||
pMem->i = (buf[0]<<24) | (buf[1]<<16) | (buf[2]<<8) | buf[3];
|
||||
pMem->flags = MEM_Int;
|
||||
return 4;
|
||||
}
|
||||
case 5: { /* 6-byte signed integer */
|
||||
u64 x = (((signed char)buf[0])<<8) | buf[1];
|
||||
u32 y = (buf[2]<<24) | (buf[3]<<16) | (buf[4]<<8) | buf[5];
|
||||
x = (x<<32) | y;
|
||||
pMem->i = *(i64*)&x;
|
||||
pMem->flags = MEM_Int;
|
||||
return 6;
|
||||
}
|
||||
case 6: /* 6-byte signed integer */
|
||||
case 7: { /* IEEE floating point */
|
||||
u64 x = (buf[0]<<24) | (buf[1]<<16) | (buf[2]<<8) | buf[3];
|
||||
u32 y = (buf[4]<<24) | (buf[5]<<16) | (buf[6]<<8) | buf[7];
|
||||
x = (x<<32) | y;
|
||||
if( serial_type==6 ){
|
||||
pMem->i = *(i64*)&x;
|
||||
pMem->flags = MEM_Int;
|
||||
}else{
|
||||
pMem->r = *(double*)&x;
|
||||
pMem->flags = MEM_Real;
|
||||
}
|
||||
return 8;
|
||||
}
|
||||
default: {
|
||||
int len = (serial_type-12)/2;
|
||||
pMem->z = (char *)buf;
|
||||
pMem->n = len;
|
||||
pMem->xDel = 0;
|
||||
if( serial_type&0x01 ){
|
||||
pMem->flags = MEM_Str | MEM_Ephem;
|
||||
}else{
|
||||
pMem->flags = MEM_Blob | MEM_Ephem;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
}
|
||||
return len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -1703,8 +1844,8 @@ int sqlite3VdbeRecordCompare(
|
|||
d2 += sqlite3VdbeSerialGet(&aKey2[d2], serial_type2, &mem2);
|
||||
|
||||
rc = sqlite3MemCompare(&mem1, &mem2, i<nField ? pKeyInfo->aColl[i] : 0);
|
||||
sqlite3VdbeMemRelease(&mem1);
|
||||
sqlite3VdbeMemRelease(&mem2);
|
||||
if( mem1.flags & MEM_Dyn ) sqlite3VdbeMemRelease(&mem1);
|
||||
if( mem2.flags & MEM_Dyn ) sqlite3VdbeMemRelease(&mem2);
|
||||
if( rc!=0 ){
|
||||
break;
|
||||
}
|
||||
|
|
@ -1847,3 +1988,10 @@ void sqlite3ExpirePreparedStatements(sqlite3 *db){
|
|||
p->expired = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Return the database associated with the Vdbe.
|
||||
*/
|
||||
sqlite3 *sqlite3VdbeDb(Vdbe *v){
|
||||
return v->db;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue