mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-08 14:02:16 +03:00
Merge the latest trunk changes (especially "PRAGMA busy_timeout" and the
ORDER BY query planner optimizations) into the sessions branch. FossilOrigin-Name: 6ca8eae1f89d19ee23cbc3a869d85b57d29b4a7d
This commit is contained in:
67
src/vdbe.c
67
src/vdbe.c
@@ -966,23 +966,28 @@ case OP_String: { /* out2-prerelease */
|
||||
break;
|
||||
}
|
||||
|
||||
/* Opcode: Null * P2 P3 * *
|
||||
/* Opcode: Null P1 P2 P3 * *
|
||||
**
|
||||
** Write a NULL into registers P2. If P3 greater than P2, then also write
|
||||
** NULL into register P3 and ever register in between P2 and P3. If P3
|
||||
** NULL into register P3 and every register in between P2 and P3. If P3
|
||||
** is less than P2 (typically P3 is zero) then only register P2 is
|
||||
** set to NULL
|
||||
** set to NULL.
|
||||
**
|
||||
** If the P1 value is non-zero, then also set the MEM_Cleared flag so that
|
||||
** NULL values will not compare equal even if SQLITE_NULLEQ is set on
|
||||
** OP_Ne or OP_Eq.
|
||||
*/
|
||||
case OP_Null: { /* out2-prerelease */
|
||||
int cnt;
|
||||
u16 nullFlag;
|
||||
cnt = pOp->p3-pOp->p2;
|
||||
assert( pOp->p3<=p->nMem );
|
||||
pOut->flags = MEM_Null;
|
||||
pOut->flags = nullFlag = pOp->p1 ? (MEM_Null|MEM_Cleared) : MEM_Null;
|
||||
while( cnt>0 ){
|
||||
pOut++;
|
||||
memAboutToChange(p, pOut);
|
||||
VdbeMemRelease(pOut);
|
||||
pOut->flags = MEM_Null;
|
||||
pOut->flags = nullFlag;
|
||||
cnt--;
|
||||
}
|
||||
break;
|
||||
@@ -1025,10 +1030,10 @@ case OP_Variable: { /* out2-prerelease */
|
||||
|
||||
/* Opcode: Move P1 P2 P3 * *
|
||||
**
|
||||
** Move the values in register P1..P1+P3-1 over into
|
||||
** registers P2..P2+P3-1. Registers P1..P1+P1-1 are
|
||||
** Move the values in register P1..P1+P3 over into
|
||||
** registers P2..P2+P3. Registers P1..P1+P3 are
|
||||
** left holding a NULL. It is an error for register ranges
|
||||
** P1..P1+P3-1 and P2..P2+P3-1 to overlap.
|
||||
** P1..P1+P3 and P2..P2+P3 to overlap.
|
||||
*/
|
||||
case OP_Move: {
|
||||
char *zMalloc; /* Holding variable for allocated memory */
|
||||
@@ -1036,7 +1041,7 @@ case OP_Move: {
|
||||
int p1; /* Register to copy from */
|
||||
int p2; /* Register to copy to */
|
||||
|
||||
n = pOp->p3;
|
||||
n = pOp->p3 + 1;
|
||||
p1 = pOp->p1;
|
||||
p2 = pOp->p2;
|
||||
assert( n>0 && p1>0 && p2>0 );
|
||||
@@ -1065,20 +1070,28 @@ case OP_Move: {
|
||||
break;
|
||||
}
|
||||
|
||||
/* Opcode: Copy P1 P2 * * *
|
||||
/* Opcode: Copy P1 P2 P3 * *
|
||||
**
|
||||
** Make a copy of register P1 into register P2.
|
||||
** Make a copy of registers P1..P1+P3 into registers P2..P2+P3.
|
||||
**
|
||||
** This instruction makes a deep copy of the value. A duplicate
|
||||
** is made of any string or blob constant. See also OP_SCopy.
|
||||
*/
|
||||
case OP_Copy: { /* in1, out2 */
|
||||
case OP_Copy: {
|
||||
int n;
|
||||
|
||||
n = pOp->p3;
|
||||
pIn1 = &aMem[pOp->p1];
|
||||
pOut = &aMem[pOp->p2];
|
||||
assert( pOut!=pIn1 );
|
||||
sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem);
|
||||
Deephemeralize(pOut);
|
||||
REGISTER_TRACE(pOp->p2, pOut);
|
||||
while( 1 ){
|
||||
sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem);
|
||||
Deephemeralize(pOut);
|
||||
REGISTER_TRACE(pOp->p2+pOp->p3-n, pOut);
|
||||
if( (n--)==0 ) break;
|
||||
pOut++;
|
||||
pIn1++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1747,6 +1760,10 @@ case OP_ToReal: { /* same as TK_TO_REAL, in1 */
|
||||
**
|
||||
** If the SQLITE_STOREP2 bit of P5 is set, then do not jump. Instead,
|
||||
** store a boolean result (either 0, or 1, or NULL) in register P2.
|
||||
**
|
||||
** If the SQLITE_NULLEQ bit is set in P5, then NULL values are considered
|
||||
** equal to one another, provided that they do not have their MEM_Cleared
|
||||
** bit set.
|
||||
*/
|
||||
/* Opcode: Ne P1 P2 P3 P4 P5
|
||||
**
|
||||
@@ -1813,7 +1830,15 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
|
||||
** or not both operands are null.
|
||||
*/
|
||||
assert( pOp->opcode==OP_Eq || pOp->opcode==OP_Ne );
|
||||
res = (flags1 & flags3 & MEM_Null)==0;
|
||||
assert( (flags1 & MEM_Cleared)==0 );
|
||||
if( (flags1&MEM_Null)!=0
|
||||
&& (flags3&MEM_Null)!=0
|
||||
&& (flags3&MEM_Cleared)==0
|
||||
){
|
||||
res = 0; /* Results are equal */
|
||||
}else{
|
||||
res = 1; /* Results are not equal */
|
||||
}
|
||||
}else{
|
||||
/* SQLITE_NULLEQ is clear and at least one operand is NULL,
|
||||
** then the result is always NULL.
|
||||
@@ -3288,6 +3313,7 @@ case OP_OpenEphemeral: {
|
||||
*/
|
||||
case OP_SorterOpen: {
|
||||
VdbeCursor *pCx;
|
||||
|
||||
#ifndef SQLITE_OMIT_MERGE_SORT
|
||||
pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, 1);
|
||||
if( pCx==0 ) goto no_mem;
|
||||
@@ -4220,6 +4246,7 @@ case OP_SorterCompare: {
|
||||
*/
|
||||
case OP_SorterData: {
|
||||
VdbeCursor *pC;
|
||||
|
||||
#ifndef SQLITE_OMIT_MERGE_SORT
|
||||
pOut = &aMem[pOp->p2];
|
||||
pC = p->apCsr[pOp->p1];
|
||||
@@ -4758,6 +4785,7 @@ case OP_Destroy: { /* out2-prerelease */
|
||||
int iCnt;
|
||||
Vdbe *pVdbe;
|
||||
int iDb;
|
||||
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
iCnt = 0;
|
||||
for(pVdbe=db->pVdbe; pVdbe; pVdbe = pVdbe->pNext){
|
||||
@@ -5547,7 +5575,9 @@ case OP_JournalMode: { /* out2-prerelease */
|
||||
Pager *pPager; /* Pager associated with pBt */
|
||||
int eNew; /* New journal mode */
|
||||
int eOld; /* The old journal mode */
|
||||
#ifndef SQLITE_OMIT_WAL
|
||||
const char *zFilename; /* Name of database file for pPager */
|
||||
#endif
|
||||
|
||||
eNew = pOp->p3;
|
||||
assert( eNew==PAGER_JOURNALMODE_DELETE
|
||||
@@ -6127,7 +6157,10 @@ case OP_Trace: {
|
||||
char *zTrace;
|
||||
char *z;
|
||||
|
||||
if( db->xTrace && (zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0 ){
|
||||
if( db->xTrace
|
||||
&& !p->doingRerun
|
||||
&& (zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0
|
||||
){
|
||||
z = sqlite3VdbeExpandSql(p, zTrace);
|
||||
db->xTrace(db->pTraceArg, z);
|
||||
sqlite3DbFree(db, z);
|
||||
|
Reference in New Issue
Block a user