}
}
/*
** Code an OP_Affinity opcode to apply the column affinity string zAff
** to the n registers starting at base.
**
** This routine assumes that zAff is dynamic and makes its own copy.
*/
static void codeApplyAffinity(Parse *pParse, int base, int n, char *zAff){
Vdbe *v = pParse->pVdbe;
assert( v!=0 );
sqlite3VdbeAddOp2(v, OP_Affinity, base, n);
sqlite3VdbeChangeP4(v, -1, zAff, 0);
sqlite3ExprCacheAffinityChange(pParse, base, n);
}
/*
** Generate code for a single equality term of the WHERE clause. An equality
** term can be either X=expr or X IN (...). pTerm is the term to be
** coded.
................................................................................
}
disableTerm(pLevel, pTerm);
return iReg;
}
/*
** Generate code that will evaluate all == and IN constraints for an
** index. The values for all constraints are left on the stack.
**
** For example, consider table t1(a,b,c,d,e,f) with index i1(a,b,c).
** Suppose the WHERE clause is this: a==5 AND b IN (1,2,3) AND c>5 AND c<10
** The index has as many as three equality constraints, but in this
** example, the third "c" value is an inequality. So only two
** constraints are coded. This routine will generate code to evaluate
** a==5 and b IN (1,2,3). The current values for a and b will be stored
** in consecutive registers and the index of the first register is returned.
**
** In the example above nEq==2. But this subroutine works for any value
** of nEq including 0. If nEq==0, this routine is nearly a no-op.
** The only thing it does is allocate the pLevel->iMem memory cell.
**
** This routine always allocates at least one memory cell and returns
** the index of that memory cell. The code that
** calls this routine will use that memory cell to store the termination
** key value of the loop. If one or more IN operators appear, then
** this routine allocates an additional nEq memory cells for internal
** use.
................................................................................
}else{
sqlite3VdbeAddOp2(v, OP_SCopy, r1, regBase+j);
}
}
testcase( pTerm->eOperator & WO_ISNULL );
testcase( pTerm->eOperator & WO_IN );
if( (pTerm->eOperator & (WO_ISNULL|WO_IN))==0 ){
sqlite3VdbeAddOp2(v, OP_IsNull, regBase+j, pLevel->addrBrk);
if( zAff
&& sqlite3CompareAffinity(pTerm->pExpr->pRight, zAff[j])==SQLITE_AFF_NONE
){
zAff[j] = SQLITE_AFF_NONE;
}
}
}
*pzAff = zAff;
return regBase;
}
................................................................................
/* Seek the index cursor to the start of the range. */
nConstraint = nEq;
if( pRangeStart ){
Expr *pRight = pRangeStart->pExpr->pRight;
sqlite3ExprCode(pParse, pRight, regBase+nEq);
sqlite3VdbeAddOp2(v, OP_IsNull, regBase+nEq, addrNxt);
if( zAff
&& sqlite3CompareAffinity(pRight, zAff[nConstraint])==SQLITE_AFF_NONE
){
/* Since the comparison is to be performed with no conversions applied** to the operands, set the affinity to apply to pRight to
** SQLITE_AFF_NONE. */
zAff[nConstraint] = SQLITE_AFF_NONE;
}
nConstraint++;
}else if( isMinQuery ){
sqlite3VdbeAddOp2(v, OP_Null, 0, regBase+nEq);
nConstraint++;
startEq = 0;
start_constraints = 1;
}
................................................................................
*/
nConstraint = nEq;
if( pRangeEnd ){
Expr *pRight = pRangeEnd->pExpr->pRight;
sqlite3ExprCacheRemove(pParse, regBase+nEq);
sqlite3ExprCode(pParse, pRight, regBase+nEq);
sqlite3VdbeAddOp2(v, OP_IsNull, regBase+nEq, addrNxt);
if( zAff
&& sqlite3CompareAffinity(pRight, zAff[nConstraint])==SQLITE_AFF_NONE
){
/* Since the comparison is to be performed with no conversions applied** to the operands, set the affinity to apply to pRight to
** SQLITE_AFF_NONE. */
zAff[nConstraint] = SQLITE_AFF_NONE;
}
codeApplyAffinity(pParse, regBase, nEq+1, zAff);
nConstraint++;
}
sqlite3DbFree(pParse->db, zAff);
/* Top of the loop body */
pLevel->p2 = sqlite3VdbeCurrentAddr(v);