mirror of
https://github.com/sqlite/sqlite.git
synced 2025-11-14 00:22:38 +03:00
Update this branch with latest trunk changes.
FossilOrigin-Name: 11f4761c3a84e2cc9df62f117a003af8c57f3d226eec5a40d6241b121e78d002
This commit is contained in:
@@ -8124,9 +8124,6 @@ int sqlite3BtreeInsert(
|
||||
** btreeMoveto() call */
|
||||
if( (pCur->curFlags&BTCF_ValidNKey)!=0 && pX->nKey==pCur->info.nKey ){
|
||||
loc = 0;
|
||||
}else if( (pCur->curFlags&BTCF_ValidNKey)!=0 && pX->nKey>0
|
||||
&& pCur->info.nKey==pX->nKey-1 ){
|
||||
loc = -1;
|
||||
}else if( loc==0 ){
|
||||
rc = sqlite3BtreeMovetoUnpacked(pCur, 0, pX->nKey, flags!=0, &loc);
|
||||
if( rc ) return rc;
|
||||
|
||||
@@ -423,8 +423,10 @@ static void computeYMD(DateTime *p){
|
||||
p->Y = 2000;
|
||||
p->M = 1;
|
||||
p->D = 1;
|
||||
}else if( !validJulianDay(p->iJD) ){
|
||||
datetimeError(p);
|
||||
return;
|
||||
}else{
|
||||
assert( validJulianDay(p->iJD) );
|
||||
Z = (int)((p->iJD + 43200000)/86400000);
|
||||
A = (int)((Z - 1867216.25)/36524.25);
|
||||
A = Z + 1 + A - (A/4);
|
||||
|
||||
@@ -5035,6 +5035,10 @@ int sqlite3Select(
|
||||
** to be invoked again. */
|
||||
if( pItem->addrFillSub ){
|
||||
if( pItem->fg.viaCoroutine==0 ){
|
||||
/* The subroutine that manifests the view might be a one-time routine,
|
||||
** or it might need to be rerun on each iteration because it
|
||||
** encodes a correlated subquery. */
|
||||
testcase( sqlite3VdbeGetOp(v, pItem->addrFillSub)->opcode==OP_Once );
|
||||
sqlite3VdbeAddOp2(v, OP_Gosub, pItem->regReturn, pItem->addrFillSub);
|
||||
}
|
||||
continue;
|
||||
|
||||
42
src/vdbe.c
42
src/vdbe.c
@@ -764,7 +764,7 @@ jump_to_p2_and_check_for_interrupt:
|
||||
pOp = &aOp[pOp->p2 - 1];
|
||||
|
||||
/* Opcodes that are used as the bottom of a loop (OP_Next, OP_Prev,
|
||||
** OP_VNext, OP_RowSetNext, or OP_SorterNext) all jump here upon
|
||||
** OP_VNext, or OP_SorterNext) all jump here upon
|
||||
** completion. Check to see if sqlite3_interrupt() has been called
|
||||
** or if the progress callback needs to be invoked.
|
||||
**
|
||||
@@ -1567,7 +1567,7 @@ arithmetic_result_is_null:
|
||||
|
||||
/* Opcode: CollSeq P1 * * P4
|
||||
**
|
||||
** P4 is a pointer to a CollSeq struct. If the next call to a user function
|
||||
** P4 is a pointer to a CollSeq object. If the next call to a user function
|
||||
** or aggregate calls sqlite3GetFuncCollSeq(), this collation sequence will
|
||||
** be returned. This is used by the built-in min(), max() and nullif()
|
||||
** functions.
|
||||
@@ -1848,11 +1848,11 @@ case OP_RealAffinity: { /* in1 */
|
||||
** Force the value in register P1 to be the type defined by P2.
|
||||
**
|
||||
** <ul>
|
||||
** <li value="97"> TEXT
|
||||
** <li value="98"> BLOB
|
||||
** <li value="99"> NUMERIC
|
||||
** <li value="100"> INTEGER
|
||||
** <li value="101"> REAL
|
||||
** <li> P2=='A' → BLOB
|
||||
** <li> P2=='B' → TEXT
|
||||
** <li> P2=='C' → NUMERIC
|
||||
** <li> P2=='D' → INTEGER
|
||||
** <li> P2=='E' → REAL
|
||||
** </ul>
|
||||
**
|
||||
** A NULL value is not changed by this routine. It remains NULL.
|
||||
@@ -2723,8 +2723,8 @@ op_column_out:
|
||||
**
|
||||
** Apply affinities to a range of P2 registers starting with P1.
|
||||
**
|
||||
** P4 is a string that is P2 characters long. The nth character of the
|
||||
** string indicates the column affinity that should be used for the nth
|
||||
** P4 is a string that is P2 characters long. The N-th character of the
|
||||
** string indicates the column affinity that should be used for the N-th
|
||||
** memory cell in the range.
|
||||
*/
|
||||
case OP_Affinity: {
|
||||
@@ -2751,8 +2751,8 @@ case OP_Affinity: {
|
||||
** use as a data record in a database table or as a key
|
||||
** in an index. The OP_Column opcode can decode the record later.
|
||||
**
|
||||
** P4 may be a string that is P2 characters long. The nth character of the
|
||||
** string indicates the column affinity that should be used for the nth
|
||||
** P4 may be a string that is P2 characters long. The N-th character of the
|
||||
** string indicates the column affinity that should be used for the N-th
|
||||
** field of the index key.
|
||||
**
|
||||
** The mapping from character to affinity is given by the SQLITE_AFF_
|
||||
@@ -5748,7 +5748,7 @@ case OP_IntegrityCk: {
|
||||
/* Opcode: RowSetAdd P1 P2 * * *
|
||||
** Synopsis: rowset(P1)=r[P2]
|
||||
**
|
||||
** Insert the integer value held by register P2 into a boolean index
|
||||
** Insert the integer value held by register P2 into a RowSet object
|
||||
** held in register P1.
|
||||
**
|
||||
** An assertion fails if P2 is not an integer.
|
||||
@@ -5768,8 +5768,9 @@ case OP_RowSetAdd: { /* in1, in2 */
|
||||
/* Opcode: RowSetRead P1 P2 P3 * *
|
||||
** Synopsis: r[P3]=rowset(P1)
|
||||
**
|
||||
** Extract the smallest value from boolean index P1 and put that value into
|
||||
** register P3. Or, if boolean index P1 is initially empty, leave P3
|
||||
** Extract the smallest value from the RowSet object in P1
|
||||
** and put that value into register P3.
|
||||
** Or, if RowSet object P1 is initially empty, leave P3
|
||||
** unchanged and jump to instruction P2.
|
||||
*/
|
||||
case OP_RowSetRead: { /* jump, in1, out3 */
|
||||
@@ -5800,15 +5801,14 @@ case OP_RowSetRead: { /* jump, in1, out3 */
|
||||
** integer in P3 into the RowSet and continue on to the
|
||||
** next opcode.
|
||||
**
|
||||
** The RowSet object is optimized for the case where successive sets
|
||||
** of integers, where each set contains no duplicates. Each set
|
||||
** of values is identified by a unique P4 value. The first set
|
||||
** must have P4==0, the final set P4=-1. P4 must be either -1 or
|
||||
** non-negative. For non-negative values of P4 only the lower 4
|
||||
** bits are significant.
|
||||
** The RowSet object is optimized for the case where sets of integers
|
||||
** are inserted in distinct phases, which each set contains no duplicates.
|
||||
** Each set is identified by a unique P4 value. The first set
|
||||
** must have P4==0, the final set must have P4==-1, and for all other sets
|
||||
** must have P4>0.
|
||||
**
|
||||
** This allows optimizations: (a) when P4==0 there is no need to test
|
||||
** the rowset object for P3, as it is guaranteed not to contain it,
|
||||
** the RowSet object for P3, as it is guaranteed not to contain it,
|
||||
** (b) when P4==-1 there is no need to insert the value, as it will
|
||||
** never be tested for, and (c) when a value that is part of set X is
|
||||
** inserted, there is no need to search to see if the same value was
|
||||
|
||||
@@ -1053,7 +1053,7 @@ FuncDef *sqlite3VtabOverloadFunction(
|
||||
if( NEVER(pExpr==0) ) return pDef;
|
||||
if( pExpr->op!=TK_COLUMN ) return pDef;
|
||||
pTab = pExpr->pTab;
|
||||
if( NEVER(pTab==0) ) return pDef;
|
||||
if( pTab==0 ) return pDef;
|
||||
if( !IsVirtual(pTab) ) return pDef;
|
||||
pVtab = sqlite3GetVTable(db, pTab)->pVtab;
|
||||
assert( pVtab!=0 );
|
||||
|
||||
@@ -1129,6 +1129,8 @@ Bitmask sqlite3WhereCodeOneLoopStart(
|
||||
int addrCont; /* Jump here to continue with next cycle */
|
||||
int iRowidReg = 0; /* Rowid is stored in this register, if not zero */
|
||||
int iReleaseReg = 0; /* Temp register to free before returning */
|
||||
Index *pIdx = 0; /* Index used by loop (if any) */
|
||||
int loopAgain; /* True if constraint generator loop should repeat */
|
||||
|
||||
pParse = pWInfo->pParse;
|
||||
v = pParse->pVdbe;
|
||||
@@ -1454,7 +1456,6 @@ Bitmask sqlite3WhereCodeOneLoopStart(
|
||||
int endEq; /* True if range end uses ==, >= or <= */
|
||||
int start_constraints; /* Start of range is constrained */
|
||||
int nConstraint; /* Number of constraint terms */
|
||||
Index *pIdx; /* The index we will be using */
|
||||
int iIdxCur; /* The VDBE cursor for the index */
|
||||
int nExtraReg = 0; /* Number of extra registers needed */
|
||||
int op; /* Instruction opcode */
|
||||
@@ -1705,6 +1706,7 @@ Bitmask sqlite3WhereCodeOneLoopStart(
|
||||
}else{
|
||||
assert( pLevel->p5==0 );
|
||||
}
|
||||
if( omitTable ) pIdx = 0;
|
||||
}else
|
||||
|
||||
#ifndef SQLITE_OMIT_OR_OPTIMIZATION
|
||||
@@ -2022,43 +2024,56 @@ Bitmask sqlite3WhereCodeOneLoopStart(
|
||||
|
||||
/* Insert code to test every subexpression that can be completely
|
||||
** computed using the current set of tables.
|
||||
**
|
||||
** This loop may run either once (pIdx==0) or twice (pIdx!=0). If
|
||||
** it is run twice, then the first iteration codes those sub-expressions
|
||||
** that can be computed using columns from pIdx only (without seeking
|
||||
** the main table cursor).
|
||||
*/
|
||||
for(pTerm=pWC->a, j=pWC->nTerm; j>0; j--, pTerm++){
|
||||
Expr *pE;
|
||||
int skipLikeAddr = 0;
|
||||
testcase( pTerm->wtFlags & TERM_VIRTUAL );
|
||||
testcase( pTerm->wtFlags & TERM_CODED );
|
||||
if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
|
||||
if( (pTerm->prereqAll & pLevel->notReady)!=0 ){
|
||||
testcase( pWInfo->untestedTerms==0
|
||||
&& (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)!=0 );
|
||||
pWInfo->untestedTerms = 1;
|
||||
continue;
|
||||
}
|
||||
pE = pTerm->pExpr;
|
||||
assert( pE!=0 );
|
||||
if( pLevel->iLeftJoin && !ExprHasProperty(pE, EP_FromJoin) ){
|
||||
continue;
|
||||
}
|
||||
if( pTerm->wtFlags & TERM_LIKECOND ){
|
||||
/* If the TERM_LIKECOND flag is set, that means that the range search
|
||||
** is sufficient to guarantee that the LIKE operator is true, so we
|
||||
** can skip the call to the like(A,B) function. But this only works
|
||||
** for strings. So do not skip the call to the function on the pass
|
||||
** that compares BLOBs. */
|
||||
do{
|
||||
loopAgain = 0;
|
||||
for(pTerm=pWC->a, j=pWC->nTerm; j>0; j--, pTerm++){
|
||||
Expr *pE;
|
||||
int skipLikeAddr = 0;
|
||||
testcase( pTerm->wtFlags & TERM_VIRTUAL );
|
||||
testcase( pTerm->wtFlags & TERM_CODED );
|
||||
if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
|
||||
if( (pTerm->prereqAll & pLevel->notReady)!=0 ){
|
||||
testcase( pWInfo->untestedTerms==0
|
||||
&& (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)!=0 );
|
||||
pWInfo->untestedTerms = 1;
|
||||
continue;
|
||||
}
|
||||
pE = pTerm->pExpr;
|
||||
assert( pE!=0 );
|
||||
if( pLevel->iLeftJoin && !ExprHasProperty(pE, EP_FromJoin) ){
|
||||
continue;
|
||||
}
|
||||
if( pIdx && !sqlite3ExprCoveredByIndex(pE, pLevel->iTabCur, pIdx) ){
|
||||
loopAgain = 1;
|
||||
continue;
|
||||
}
|
||||
if( pTerm->wtFlags & TERM_LIKECOND ){
|
||||
/* If the TERM_LIKECOND flag is set, that means that the range search
|
||||
** is sufficient to guarantee that the LIKE operator is true, so we
|
||||
** can skip the call to the like(A,B) function. But this only works
|
||||
** for strings. So do not skip the call to the function on the pass
|
||||
** that compares BLOBs. */
|
||||
#ifdef SQLITE_LIKE_DOESNT_MATCH_BLOBS
|
||||
continue;
|
||||
continue;
|
||||
#else
|
||||
u32 x = pLevel->iLikeRepCntr;
|
||||
assert( x>0 );
|
||||
skipLikeAddr = sqlite3VdbeAddOp1(v, (x&1)? OP_IfNot : OP_If, (int)(x>>1));
|
||||
VdbeCoverage(v);
|
||||
u32 x = pLevel->iLikeRepCntr;
|
||||
assert( x>0 );
|
||||
skipLikeAddr = sqlite3VdbeAddOp1(v, (x&1)?OP_IfNot:OP_If, (int)(x>>1));
|
||||
VdbeCoverage(v);
|
||||
#endif
|
||||
}
|
||||
sqlite3ExprIfFalse(pParse, pE, addrCont, SQLITE_JUMPIFNULL);
|
||||
if( skipLikeAddr ) sqlite3VdbeJumpHere(v, skipLikeAddr);
|
||||
pTerm->wtFlags |= TERM_CODED;
|
||||
}
|
||||
sqlite3ExprIfFalse(pParse, pE, addrCont, SQLITE_JUMPIFNULL);
|
||||
if( skipLikeAddr ) sqlite3VdbeJumpHere(v, skipLikeAddr);
|
||||
pTerm->wtFlags |= TERM_CODED;
|
||||
}
|
||||
pIdx = 0;
|
||||
}while( loopAgain );
|
||||
|
||||
/* Insert code to test for implied constraints based on transitivity
|
||||
** of the "==" operator.
|
||||
|
||||
Reference in New Issue
Block a user