#include "sqliteInt.h"
static void exprCodeBetween(Parse*,Expr*,int,void(*)(Parse*,Expr*,int,int),int);
static int exprCodeVector(Parse *pParse, Expr *p, int *piToFree);
char sqlite3TableColumnAffinity(const Table *pTab, int iCol){
if( iCol<0 || NEVER(iCol>=pTab->nCol) ) return SQLITE_AFF_INTEGER;
return pTab->aCol[iCol].affinity;
}
char sqlite3ExprAffinity(const Expr *pExpr){
int op;
op = pExpr->op;
while( 1 ){
if( op==TK_COLUMN || (op==TK_AGG_COLUMN && pExpr->y.pTab!=0) ){
assert( ExprUseYTab(pExpr) );
assert( pExpr->y.pTab!=0 );
return sqlite3TableColumnAffinity(pExpr->y.pTab, pExpr->iColumn);
}
if( op==TK_SELECT ){
assert( ExprUseXSelect(pExpr) );
assert( pExpr->x.pSelect!=0 );
assert( pExpr->x.pSelect->pEList!=0 );
assert( pExpr->x.pSelect->pEList->a[0].pExpr!=0 );
return sqlite3ExprAffinity(pExpr->x.pSelect->pEList->a[0].pExpr);
}
#ifndef SQLITE_OMIT_CAST
if( op==TK_CAST ){
assert( !ExprHasProperty(pExpr, EP_IntValue) );
return sqlite3AffinityType(pExpr->u.zToken, 0);
}
#endif
if( op==TK_SELECT_COLUMN ){
assert( pExpr->pLeft!=0 && ExprUseXSelect(pExpr->pLeft) );
assert( pExpr->iColumn < pExpr->iTable );
assert( pExpr->iColumn >= 0 );
assert( pExpr->iTable==pExpr->pLeft->x.pSelect->pEList->nExpr );
return sqlite3ExprAffinity(
pExpr->pLeft->x.pSelect->pEList->a[pExpr->iColumn].pExpr
);
}
if( op==TK_VECTOR ){
assert( ExprUseXList(pExpr) );
return sqlite3ExprAffinity(pExpr->x.pList->a[0].pExpr);
}
if( ExprHasProperty(pExpr, EP_Skip|EP_IfNullRow) ){
assert( pExpr->op==TK_COLLATE
|| pExpr->op==TK_IF_NULL_ROW
|| (pExpr->op==TK_REGISTER && pExpr->op2==TK_IF_NULL_ROW) );
pExpr = pExpr->pLeft;
op = pExpr->op;
continue;
}
if( op!=TK_REGISTER || (op = pExpr->op2)==TK_REGISTER ) break;
}
return pExpr->affExpr;
}
int sqlite3ExprDataType(const Expr *pExpr){
while( pExpr ){
switch( pExpr->op ){
case TK_COLLATE:
case TK_IF_NULL_ROW:
case TK_UPLUS: {
pExpr = pExpr->pLeft;
break;
}
case TK_NULL: {
pExpr = 0;
break;
}
case TK_STRING: {
return 0x02;
}
case TK_BLOB: {
return 0x04;
}
case TK_CONCAT: {
return 0x06;
}
case TK_VARIABLE:
case TK_AGG_FUNCTION:
case TK_FUNCTION: {
return 0x07;
}
case TK_COLUMN:
case TK_AGG_COLUMN:
case TK_SELECT:
case TK_CAST:
case TK_SELECT_COLUMN:
case TK_VECTOR: {
int aff = sqlite3ExprAffinity(pExpr);
if( aff>=SQLITE_AFF_NUMERIC ) return 0x05;
if( aff==SQLITE_AFF_TEXT ) return 0x06;
return 0x07;
}
case TK_CASE: {
int res = 0;
int ii;
ExprList *pList = pExpr->x.pList;
assert( ExprUseXList(pExpr) && pList!=0 );
assert( pList->nExpr > 0);
for(ii=1; ii<pList->nExpr; ii+=2){
res |= sqlite3ExprDataType(pList->a[ii].pExpr);
}
if( pList->nExpr % 2 ){
res |= sqlite3ExprDataType(pList->a[pList->nExpr-1].pExpr);
}
return res;
}
default: {
return 0x01;
}
}
}
return 0x00;
}
Expr *sqlite3ExprAddCollateToken(
const Parse *pParse,
Expr *pExpr,
const Token *pCollName,
int dequote
){
if( pCollName->n>0 ){
Expr *pNew = sqlite3ExprAlloc(pParse->db, TK_COLLATE, pCollName, dequote);
if( pNew ){
pNew->pLeft = pExpr;
pNew->flags |= EP_Collate|EP_Skip;
pExpr = pNew;
}
}
return pExpr;
}
Expr *sqlite3ExprAddCollateString(
const Parse *pParse,
Expr *pExpr,
const char *zC
){
Token s;
assert( zC!=0 );
sqlite3TokenInit(&s, (char*)zC);
return sqlite3ExprAddCollateToken(pParse, pExpr, &s, 0);
}
Expr *sqlite3ExprSkipCollate(Expr *pExpr){
while( pExpr && ExprHasProperty(pExpr, EP_Skip) ){
assert( pExpr->op==TK_COLLATE );
pExpr = pExpr->pLeft;
}
return pExpr;
}
Expr *sqlite3ExprSkipCollateAndLikely(Expr *pExpr){
while( pExpr && ExprHasProperty(pExpr, EP_Skip|EP_Unlikely) ){
if( ExprHasProperty(pExpr, EP_Unlikely) ){
assert( ExprUseXList(pExpr) );
assert( pExpr->x.pList->nExpr>0 );
assert( pExpr->op==TK_FUNCTION );
pExpr = pExpr->x.pList->a[0].pExpr;
}else{
assert( pExpr->op==TK_COLLATE );
pExpr = pExpr->pLeft;
}
}
return pExpr;
}
CollSeq *sqlite3ExprCollSeq(Parse *pParse, const Expr *pExpr){
sqlite3 *db = pParse->db;
CollSeq *pColl = 0;
const Expr *p = pExpr;
while( p ){
int op = p->op;
if( op==TK_REGISTER ) op = p->op2;
if( (op==TK_AGG_COLUMN && p->y.pTab!=0)
|| op==TK_COLUMN || op==TK_TRIGGER
){
int j;
assert( ExprUseYTab(p) );
assert( p->y.pTab!=0 );
if( (j = p->iColumn)>=0 ){
const char *zColl = sqlite3ColumnColl(&p->y.pTab->aCol[j]);
pColl = sqlite3FindCollSeq(db, ENC(db), zColl, 0);
}
break;
}
if( op==TK_CAST || op==TK_UPLUS ){
p = p->pLeft;
continue;
}
if( op==TK_VECTOR ){
assert( ExprUseXList(p) );
p = p->x.pList->a[0].pExpr;
continue;
}
if( op==TK_COLLATE ){
assert( !ExprHasProperty(p, EP_IntValue) );
pColl = sqlite3GetCollSeq(pParse, ENC(db), 0, p->u.zToken);
break;
}
if( p->flags & EP_Collate ){
if( p->pLeft && (p->pLeft->flags & EP_Collate)!=0 ){
p = p->pLeft;
}else{
Expr *pNext = p->pRight;
assert( !ExprUseXList(p) || p->x.pList==0 || p->pRight==0 );
if( ExprUseXList(p) && p->x.pList!=0 && !db->mallocFailed ){
int i;
for(i=0; i<p->x.pList->nExpr; i++){
if( ExprHasProperty(p->x.pList->a[i].pExpr, EP_Collate) ){
pNext = p->x.pList->a[i].pExpr;
break;
}
}
}
p = pNext;
}
}else{
break;
}
}
if( sqlite3CheckCollSeq(pParse, pColl) ){
pColl = 0;
}
return pColl;
}
CollSeq *sqlite3ExprNNCollSeq(Parse *pParse, const Expr *pExpr){
CollSeq *p = sqlite3ExprCollSeq(pParse, pExpr);
if( p==0 ) p = pParse->db->pDfltColl;
assert( p!=0 );
return p;
}
int sqlite3ExprCollSeqMatch(Parse *pParse, const Expr *pE1, const Expr *pE2){
CollSeq *pColl1 = sqlite3ExprNNCollSeq(pParse, pE1);
CollSeq *pColl2 = sqlite3ExprNNCollSeq(pParse, pE2);
return sqlite3StrICmp(pColl1->zName, pColl2->zName)==0;
}
char sqlite3CompareAffinity(const Expr *pExpr, char aff2){
char aff1 = sqlite3ExprAffinity(pExpr);
if( aff1>SQLITE_AFF_NONE && aff2>SQLITE_AFF_NONE ){
if( sqlite3IsNumericAffinity(aff1) || sqlite3IsNumericAffinity(aff2) ){
return SQLITE_AFF_NUMERIC;
}else{
return SQLITE_AFF_BLOB;
}
}else{
assert( aff1<=SQLITE_AFF_NONE || aff2<=SQLITE_AFF_NONE );
return (aff1<=SQLITE_AFF_NONE ? aff2 : aff1) | SQLITE_AFF_NONE;
}
}
static char comparisonAffinity(const Expr *pExpr){
char aff;
assert( pExpr->op==TK_EQ || pExpr->op==TK_IN || pExpr->op==TK_LT ||
pExpr->op==TK_GT || pExpr->op==TK_GE || pExpr->op==TK_LE ||
pExpr->op==TK_NE || pExpr->op==TK_IS || pExpr->op==TK_ISNOT );
assert( pExpr->pLeft );
aff = sqlite3ExprAffinity(pExpr->pLeft);
if( pExpr->pRight ){
aff = sqlite3CompareAffinity(pExpr->pRight, aff);
}else if( ExprUseXSelect(pExpr) ){
aff = sqlite3CompareAffinity(pExpr->x.pSelect->pEList->a[0].pExpr, aff);
}else if( aff==0 ){
aff = SQLITE_AFF_BLOB;
}
return aff;
}
int sqlite3IndexAffinityOk(const Expr *pExpr, char idx_affinity){
char aff = comparisonAffinity(pExpr);
if( aff<SQLITE_AFF_TEXT ){
return 1;
}
if( aff==SQLITE_AFF_TEXT ){
return idx_affinity==SQLITE_AFF_TEXT;
}
return sqlite3IsNumericAffinity(idx_affinity);
}
static u8 binaryCompareP5(
const Expr *pExpr1,
const Expr *pExpr2,
int jumpIfNull
){
u8 aff = (char)sqlite3ExprAffinity(pExpr2);
aff = (u8)sqlite3CompareAffinity(pExpr1, aff) | (u8)jumpIfNull;
return aff;
}
CollSeq *sqlite3BinaryCompareCollSeq(
Parse *pParse,
const Expr *pLeft,
const Expr *pRight
){
CollSeq *pColl;
assert( pLeft );
if( pLeft->flags & EP_Collate ){
pColl = sqlite3ExprCollSeq(pParse, pLeft);
}else if( pRight && (pRight->flags & EP_Collate)!=0 ){
pColl = sqlite3ExprCollSeq(pParse, pRight);
}else{
pColl = sqlite3ExprCollSeq(pParse, pLeft);
if( !pColl ){
pColl = sqlite3ExprCollSeq(pParse, pRight);
}
}
return pColl;
}
CollSeq *sqlite3ExprCompareCollSeq(Parse *pParse, const Expr *p){
if( ExprHasProperty(p, EP_Commuted) ){
return sqlite3BinaryCompareCollSeq(pParse, p->pRight, p->pLeft);
}else{
return sqlite3BinaryCompareCollSeq(pParse, p->pLeft, p->pRight);
}
}
static int codeCompare(
Parse *pParse,
Expr *pLeft,
Expr *pRight,
int opcode,
int in1, int in2,
int dest,
int jumpIfNull,
int isCommuted
){
int p5;
int addr;
CollSeq *p4;
if( pParse->nErr ) return 0;
if( isCommuted ){
p4 = sqlite3BinaryCompareCollSeq(pParse, pRight, pLeft);
}else{
p4 = sqlite3BinaryCompareCollSeq(pParse, pLeft, pRight);
}
p5 = binaryCompareP5(pLeft, pRight, jumpIfNull);
addr = sqlite3VdbeAddOp4(pParse->pVdbe, opcode, in2, dest, in1,
(void*)p4, P4_COLLSEQ);
sqlite3VdbeChangeP5(pParse->pVdbe, (u8)p5);
return addr;
}
int sqlite3ExprIsVector(const Expr *pExpr){
return sqlite3ExprVectorSize(pExpr)>1;
}
int sqlite3ExprVectorSize(const Expr *pExpr){
u8 op = pExpr->op;
if( op==TK_REGISTER ) op = pExpr->op2;
if( op==TK_VECTOR ){
assert( ExprUseXList(pExpr) );
return pExpr->x.pList->nExpr;
}else if( op==TK_SELECT ){
assert( ExprUseXSelect(pExpr) );
return pExpr->x.pSelect->pEList->nExpr;
}else{
return 1;
}
}
Expr *sqlite3VectorFieldSubexpr(Expr *pVector, int i){
assert( i<sqlite3ExprVectorSize(pVector) || pVector->op==TK_ERROR );
if( sqlite3ExprIsVector(pVector) ){
assert( pVector->op2==0 || pVector->op==TK_REGISTER );
if( pVector->op==TK_SELECT || pVector->op2==TK_SELECT ){
assert( ExprUseXSelect(pVector) );
return pVector->x.pSelect->pEList->a[i].pExpr;
}else{
assert( ExprUseXList(pVector) );
return pVector->x.pList->a[i].pExpr;
}
}
return pVector;
}
Expr *sqlite3ExprForVectorField(
Parse *pParse,
Expr *pVector,
int iField,
int nField
){
Expr *pRet;
if( pVector->op==TK_SELECT ){
assert( ExprUseXSelect(pVector) );
pRet = sqlite3PExpr(pParse, TK_SELECT_COLUMN, 0, 0);
if( pRet ){
pRet->iTable = nField;
pRet->iColumn = iField;
pRet->pLeft = pVector;
}
}else{
if( pVector->op==TK_VECTOR ){
Expr **ppVector;
assert( ExprUseXList(pVector) );
ppVector = &pVector->x.pList->a[iField].pExpr;
pVector = *ppVector;
if( IN_RENAME_OBJECT ){
*ppVector = 0;
return pVector;
}
}
pRet = sqlite3ExprDup(pParse->db, pVector, 0);
}
return pRet;
}
static int exprCodeSubselect(Parse *pParse, Expr *pExpr){
int reg = 0;
#ifndef SQLITE_OMIT_SUBQUERY
if( pExpr->op==TK_SELECT ){
reg = sqlite3CodeSubselect(pParse, pExpr);
}
#endif
return reg;
}
static int exprVectorRegister(
Parse *pParse,
Expr *pVector,
int iField,
int regSelect,
Expr **ppExpr,
int *pRegFree
){
u8 op = pVector->op;
assert( op==TK_VECTOR || op==TK_REGISTER || op==TK_SELECT || op==TK_ERROR );
if( op==TK_REGISTER ){
*ppExpr = sqlite3VectorFieldSubexpr(pVector, iField);
return pVector->iTable+iField;
}
if( op==TK_SELECT ){
assert( ExprUseXSelect(pVector) );
*ppExpr = pVector->x.pSelect->pEList->a[iField].pExpr;
return regSelect+iField;
}
if( op==TK_VECTOR ){
assert( ExprUseXList(pVector) );
*ppExpr = pVector->x.pList->a[iField].pExpr;
return sqlite3ExprCodeTemp(pParse, *ppExpr, pRegFree);
}
return 0;
}
static void codeVectorCompare(
Parse *pParse,
Expr *pExpr,
int dest,
u8 op,
u8 p5
){
Vdbe *v = pParse->pVdbe;
Expr *pLeft = pExpr->pLeft;
Expr *pRight = pExpr->pRight;
int nLeft = sqlite3ExprVectorSize(pLeft);
int i;
int regLeft = 0;
int regRight = 0;
u8 opx = op;
int addrCmp = 0;
int addrDone = sqlite3VdbeMakeLabel(pParse);
int isCommuted = ExprHasProperty(pExpr,EP_Commuted);
assert( !ExprHasVVAProperty(pExpr,EP_Immutable) );
if( pParse->nErr ) return;
if( nLeft!=sqlite3ExprVectorSize(pRight) ){
sqlite3ErrorMsg(pParse, "row value misused");
return;
}
assert( pExpr->op==TK_EQ || pExpr->op==TK_NE
|| pExpr->op==TK_IS || pExpr->op==TK_ISNOT
|| pExpr->op==TK_LT || pExpr->op==TK_GT
|| pExpr->op==TK_LE || pExpr->op==TK_GE
);
assert( pExpr->op==op || (pExpr->op==TK_IS && op==TK_EQ)
|| (pExpr->op==TK_ISNOT && op==TK_NE) );
assert( p5==0 || pExpr->op!=op );
assert( p5==SQLITE_NULLEQ || pExpr->op==op );
if( op==TK_LE ) opx = TK_LT;
if( op==TK_GE ) opx = TK_GT;
if( op==TK_NE ) opx = TK_EQ;
regLeft = exprCodeSubselect(pParse, pLeft);
regRight = exprCodeSubselect(pParse, pRight);
sqlite3VdbeAddOp2(v, OP_Integer, 1, dest);
for(i=0; 1 ; i++){
int regFree1 = 0, regFree2 = 0;
Expr *pL = 0, *pR = 0;
int r1, r2;
assert( i>=0 && i<nLeft );
if( addrCmp ) sqlite3VdbeJumpHere(v, addrCmp);
r1 = exprVectorRegister(pParse, pLeft, i, regLeft, &pL, ®Free1);
r2 = exprVectorRegister(pParse, pRight, i, regRight, &pR, ®Free2);
addrCmp = sqlite3VdbeCurrentAddr(v);
codeCompare(pParse, pL, pR, opx, r1, r2, addrDone, p5, isCommuted);
testcase(op==OP_Lt); VdbeCoverageIf(v,op==OP_Lt);
testcase(op==OP_Le); VdbeCoverageIf(v,op==OP_Le);
testcase(op==OP_Gt); VdbeCoverageIf(v,op==OP_Gt);
testcase(op==OP_Ge); VdbeCoverageIf(v,op==OP_Ge);
testcase(op==OP_Eq); VdbeCoverageIf(v,op==OP_Eq);
testcase(op==OP_Ne); VdbeCoverageIf(v,op==OP_Ne);
sqlite3ReleaseTempReg(pParse, regFree1);
sqlite3ReleaseTempReg(pParse, regFree2);
if( (opx==TK_LT || opx==TK_GT) && i<nLeft-1 ){
addrCmp = sqlite3VdbeAddOp0(v, OP_ElseEq);
testcase(opx==TK_LT); VdbeCoverageIf(v,opx==TK_LT);
testcase(opx==TK_GT); VdbeCoverageIf(v,opx==TK_GT);
}
if( p5==SQLITE_NULLEQ ){
sqlite3VdbeAddOp2(v, OP_Integer, 0, dest);
}else{
sqlite3VdbeAddOp3(v, OP_ZeroOrNull, r1, dest, r2);
}
if( i==nLeft-1 ){
break;
}
if( opx==TK_EQ ){
sqlite3VdbeAddOp2(v, OP_NotNull, dest, addrDone); VdbeCoverage(v);
}else{
assert( op==TK_LT || op==TK_GT || op==TK_LE || op==TK_GE );
sqlite3VdbeAddOp2(v, OP_Goto, 0, addrDone);
if( i==nLeft-2 ) opx = op;
}
}
sqlite3VdbeJumpHere(v, addrCmp);
sqlite3VdbeResolveLabel(v, addrDone);
if( op==TK_NE ){
sqlite3VdbeAddOp2(v, OP_Not, dest, dest);
}
}
#if SQLITE_MAX_EXPR_DEPTH>0
int sqlite3ExprCheckHeight(Parse *pParse, int nHeight){
int rc = SQLITE_OK;
int mxHeight = pParse->db->aLimit[SQLITE_LIMIT_EXPR_DEPTH];
if( nHeight>mxHeight ){
sqlite3ErrorMsg(pParse,
"Expression tree is too large (maximum depth %d)", mxHeight
);
rc = SQLITE_ERROR;
}
return rc;
}
static void heightOfExpr(const Expr *p, int *pnHeight){
if( p ){
if( p->nHeight>*pnHeight ){
*pnHeight = p->nHeight;
}
}
}
static void heightOfExprList(const ExprList *p, int *pnHeight){
if( p ){
int i;
for(i=0; i<p->nExpr; i++){
heightOfExpr(p->a[i].pExpr, pnHeight);
}
}
}
static void heightOfSelect(const Select *pSelect, int *pnHeight){
const Select *p;
for(p=pSelect; p; p=p->pPrior){
heightOfExpr(p->pWhere, pnHeight);
heightOfExpr(p->pHaving, pnHeight);
heightOfExpr(p->pLimit, pnHeight);
heightOfExprList(p->pEList, pnHeight);
heightOfExprList(p->pGroupBy, pnHeight);
heightOfExprList(p->pOrderBy, pnHeight);
}
}
static void exprSetHeight(Expr *p){
int nHeight = p->pLeft ? p->pLeft->nHeight : 0;
if( NEVER(p->pRight) && p->pRight->nHeight>nHeight ){
nHeight = p->pRight->nHeight;
}
if( ExprUseXSelect(p) ){
heightOfSelect(p->x.pSelect, &nHeight);
}else if( p->x.pList ){
heightOfExprList(p->x.pList, &nHeight);
p->flags |= EP_Propagate & sqlite3ExprListFlags(p->x.pList);
}
p->nHeight = nHeight + 1;
}
void sqlite3ExprSetHeightAndFlags(Parse *pParse, Expr *p){
if( pParse->nErr ) return;
exprSetHeight(p);
sqlite3ExprCheckHeight(pParse, p->nHeight);
}
int sqlite3SelectExprHeight(const Select *p){
int nHeight = 0;
heightOfSelect(p, &nHeight);
return nHeight;
}
#else
void sqlite3ExprSetHeightAndFlags(Parse *pParse, Expr *p){
if( pParse->nErr ) return;
if( p && ExprUseXList(p) && p->x.pList ){
p->flags |= EP_Propagate & sqlite3ExprListFlags(p->x.pList);
}
}
#define exprSetHeight(y)
#endif
void sqlite3ExprSetErrorOffset(Expr *pExpr, int iOfst){
if( pExpr==0 ) return;
if( NEVER(ExprUseWJoin(pExpr)) ) return;
pExpr->w.iOfst = iOfst;
}
Expr *sqlite3ExprAlloc(
sqlite3 *db,
int op,
const Token *pToken,
int dequote
){
Expr *pNew;
int nExtra = 0;
int iValue = 0;
assert( db!=0 );
if( pToken ){
if( op!=TK_INTEGER || pToken->z==0
|| sqlite3GetInt32(pToken->z, &iValue)==0 ){
nExtra = pToken->n+1;
assert( iValue>=0 );
}
}
pNew = sqlite3DbMallocRawNN(db, sizeof(Expr)+nExtra);
if( pNew ){
memset(pNew, 0, sizeof(Expr));
pNew->op = (u8)op;
pNew->iAgg = -1;
if( pToken ){
if( nExtra==0 ){
pNew->flags |= EP_IntValue|EP_Leaf|(iValue?EP_IsTrue:EP_IsFalse);
pNew->u.iValue = iValue;
}else{
pNew->u.zToken = (char*)&pNew[1];
assert( pToken->z!=0 || pToken->n==0 );
if( pToken->n ) memcpy(pNew->u.zToken, pToken->z, pToken->n);
pNew->u.zToken[pToken->n] = 0;
if( dequote && sqlite3Isquote(pNew->u.zToken[0]) ){
sqlite3DequoteExpr(pNew);
}
}
}
#if SQLITE_MAX_EXPR_DEPTH>0
pNew->nHeight = 1;
#endif
}
return pNew;
}
Expr *sqlite3Expr(
sqlite3 *db,
int op,
const char *zToken
){
Token x;
x.z = zToken;
x.n = sqlite3Strlen30(zToken);
return sqlite3ExprAlloc(db, op, &x, 0);
}
void sqlite3ExprAttachSubtrees(
sqlite3 *db,
Expr *pRoot,
Expr *pLeft,
Expr *pRight
){
if( pRoot==0 ){
assert( db->mallocFailed );
sqlite3ExprDelete(db, pLeft);
sqlite3ExprDelete(db, pRight);
}else{
assert( ExprUseXList(pRoot) );
assert( pRoot->x.pSelect==0 );
if( pRight ){
pRoot->pRight = pRight;
pRoot->flags |= EP_Propagate & pRight->flags;
#if SQLITE_MAX_EXPR_DEPTH>0
pRoot->nHeight = pRight->nHeight+1;
}else{
pRoot->nHeight = 1;
#endif
}
if( pLeft ){
pRoot->pLeft = pLeft;
pRoot->flags |= EP_Propagate & pLeft->flags;
#if SQLITE_MAX_EXPR_DEPTH>0
if( pLeft->nHeight>=pRoot->nHeight ){
pRoot->nHeight = pLeft->nHeight+1;
}
#endif
}
}
}
Expr *sqlite3PExpr(
Parse *pParse,
int op,
Expr *pLeft,
Expr *pRight
){
Expr *p;
p = sqlite3DbMallocRawNN(pParse->db, sizeof(Expr));
if( p ){
memset(p, 0, sizeof(Expr));
p->op = op & 0xff;
p->iAgg = -1;
sqlite3ExprAttachSubtrees(pParse->db, p, pLeft, pRight);
sqlite3ExprCheckHeight(pParse, p->nHeight);
}else{
sqlite3ExprDelete(pParse->db, pLeft);
sqlite3ExprDelete(pParse->db, pRight);
}
return p;
}
void sqlite3PExprAddSelect(Parse *pParse, Expr *pExpr, Select *pSelect){
if( pExpr ){
pExpr->x.pSelect = pSelect;
ExprSetProperty(pExpr, EP_xIsSelect|EP_Subquery);
sqlite3ExprSetHeightAndFlags(pParse, pExpr);
}else{
assert( pParse->db->mallocFailed );
sqlite3SelectDelete(pParse->db, pSelect);
}
}
Select *sqlite3ExprListToValues(Parse *pParse, int nElem, ExprList *pEList){
int ii;
Select *pRet = 0;
assert( nElem>1 );
for(ii=0; ii<pEList->nExpr; ii++){
Select *pSel;
Expr *pExpr = pEList->a[ii].pExpr;
int nExprElem;
if( pExpr->op==TK_VECTOR ){
assert( ExprUseXList(pExpr) );
nExprElem = pExpr->x.pList->nExpr;
}else{
nExprElem = 1;
}
if( nExprElem!=nElem ){
sqlite3ErrorMsg(pParse, "IN(...) element has %d term%s - expected %d",
nExprElem, nExprElem>1?"s":"", nElem
);
break;
}
assert( ExprUseXList(pExpr) );
pSel = sqlite3SelectNew(pParse, pExpr->x.pList, 0, 0, 0, 0, 0, SF_Values,0);
pExpr->x.pList = 0;
if( pSel ){
if( pRet ){
pSel->op = TK_ALL;
pSel->pPrior = pRet;
}
pRet = pSel;
}
}
if( pRet && pRet->pPrior ){
pRet->selFlags |= SF_MultiValue;
}
sqlite3ExprListDelete(pParse->db, pEList);
return pRet;
}
Expr *sqlite3ExprAnd(Parse *pParse, Expr *pLeft, Expr *pRight){
sqlite3 *db = pParse->db;
if( pLeft==0 ){
return pRight;
}else if( pRight==0 ){
return pLeft;
}else{
u32 f = pLeft->flags | pRight->flags;
if( (f&(EP_OuterON|EP_InnerON|EP_IsFalse))==EP_IsFalse
&& !IN_RENAME_OBJECT
){
sqlite3ExprDeferredDelete(pParse, pLeft);
sqlite3ExprDeferredDelete(pParse, pRight);
return sqlite3Expr(db, TK_INTEGER, "0");
}else{
return sqlite3PExpr(pParse, TK_AND, pLeft, pRight);
}
}
}
Expr *sqlite3ExprFunction(
Parse *pParse,
ExprList *pList,
const Token *pToken,
int eDistinct
){
Expr *pNew;
sqlite3 *db = pParse->db;
assert( pToken );
pNew = sqlite3ExprAlloc(db, TK_FUNCTION, pToken, 1);
if( pNew==0 ){
sqlite3ExprListDelete(db, pList);
return 0;
}
assert( !ExprHasProperty(pNew, EP_InnerON|EP_OuterON) );
pNew->w.iOfst = (int)(pToken->z - pParse->zTail);
if( pList
&& pList->nExpr > pParse->db->aLimit[SQLITE_LIMIT_FUNCTION_ARG]
&& !pParse->nested
){
sqlite3ErrorMsg(pParse, "too many arguments on function %T", pToken);
}
pNew->x.pList = pList;
ExprSetProperty(pNew, EP_HasFunc);
assert( ExprUseXList(pNew) );
sqlite3ExprSetHeightAndFlags(pParse, pNew);
if( eDistinct==SF_Distinct ) ExprSetProperty(pNew, EP_Distinct);
return pNew;
}
void sqlite3ExprFunctionUsable(
Parse *pParse,
const Expr *pExpr,
const FuncDef *pDef
){
assert( !IN_RENAME_OBJECT );
assert( (pDef->funcFlags & (SQLITE_FUNC_DIRECT|SQLITE_FUNC_UNSAFE))!=0 );
if( ExprHasProperty(pExpr, EP_FromDDL) ){
if( (pDef->funcFlags & SQLITE_FUNC_DIRECT)!=0
|| (pParse->db->flags & SQLITE_TrustedSchema)==0
){
sqlite3ErrorMsg(pParse, "unsafe use of %#T()", pExpr);
}
}
}
void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr, u32 n){
sqlite3 *db = pParse->db;
const char *z;
ynVar x;
if( pExpr==0 ) return;
assert( !ExprHasProperty(pExpr, EP_IntValue|EP_Reduced|EP_TokenOnly) );
z = pExpr->u.zToken;
assert( z!=0 );
assert( z[0]!=0 );
assert( n==(u32)sqlite3Strlen30(z) );
if( z[1]==0 ){
assert( z[0]=='?' );
x = (ynVar)(++pParse->nVar);
}else{
int doAdd = 0;
if( z[0]=='?' ){
i64 i;
int bOk;
if( n==2 ){
i = z[1]-'0';
bOk = 1;
}else{
bOk = 0==sqlite3Atoi64(&z[1], &i, n-1, SQLITE_UTF8);
}
testcase( i==0 );
testcase( i==1 );
testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]-1 );
testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] );
if( bOk==0 || i<1 || i>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){
sqlite3ErrorMsg(pParse, "variable number must be between ?1 and ?%d",
db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]);
sqlite3RecordErrorOffsetOfExpr(pParse->db, pExpr);
return;
}
x = (ynVar)i;
if( x>pParse->nVar ){
pParse->nVar = (int)x;
doAdd = 1;
}else if( sqlite3VListNumToName(pParse->pVList, x)==0 ){
doAdd = 1;
}
}else{
x = (ynVar)sqlite3VListNameToNum(pParse->pVList, z, n);
if( x==0 ){
x = (ynVar)(++pParse->nVar);
doAdd = 1;
}
}
if( doAdd ){
pParse->pVList = sqlite3VListAdd(db, pParse->pVList, z, n, x);
}
}
pExpr->iColumn = x;
if( x>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){
sqlite3ErrorMsg(pParse, "too many SQL variables");
sqlite3RecordErrorOffsetOfExpr(pParse->db, pExpr);
}
}
static SQLITE_NOINLINE void sqlite3ExprDeleteNN(sqlite3 *db, Expr *p){
assert( p!=0 );
assert( db!=0 );
assert( !ExprUseUValue(p) || p->u.iValue>=0 );
assert( !ExprUseYWin(p) || !ExprUseYSub(p) );
assert( !ExprUseYWin(p) || p->y.pWin!=0 || db->mallocFailed );
assert( p->op!=TK_FUNCTION || !ExprUseYSub(p) );
#ifdef SQLITE_DEBUG
if( ExprHasProperty(p, EP_Leaf) && !ExprHasProperty(p, EP_TokenOnly) ){
assert( p->pLeft==0 );
assert( p->pRight==0 );
assert( !ExprUseXSelect(p) || p->x.pSelect==0 );
assert( !ExprUseXList(p) || p->x.pList==0 );
}
#endif
if( !ExprHasProperty(p, (EP_TokenOnly|EP_Leaf)) ){
assert( (ExprUseXList(p) && p->x.pList==0) || p->pRight==0 );
if( p->pLeft && p->op!=TK_SELECT_COLUMN ) sqlite3ExprDeleteNN(db, p->pLeft);
if( p->pRight ){
assert( !ExprHasProperty(p, EP_WinFunc) );
sqlite3ExprDeleteNN(db, p->pRight);
}else if( ExprUseXSelect(p) ){
assert( !ExprHasProperty(p, EP_WinFunc) );
sqlite3SelectDelete(db, p->x.pSelect);
}else{
sqlite3ExprListDelete(db, p->x.pList);
#ifndef SQLITE_OMIT_WINDOWFUNC
if( ExprHasProperty(p, EP_WinFunc) ){
sqlite3WindowDelete(db, p->y.pWin);
}
#endif
}
}
if( !ExprHasProperty(p, EP_Static) ){
sqlite3DbNNFreeNN(db, p);
}
}
void sqlite3ExprDelete(sqlite3 *db, Expr *p){
if( p ) sqlite3ExprDeleteNN(db, p);
}
void sqlite3ClearOnOrUsing(sqlite3 *db, OnOrUsing *p){
if( p==0 ){
}else if( p->pOn ){
sqlite3ExprDeleteNN(db, p->pOn);
}else if( p->pUsing ){
sqlite3IdListDelete(db, p->pUsing);
}
}
void sqlite3ExprDeferredDelete(Parse *pParse, Expr *pExpr){
sqlite3ParserAddCleanup(pParse,
(void(*)(sqlite3*,void*))sqlite3ExprDelete,
pExpr);
}
void sqlite3ExprUnmapAndDelete(Parse *pParse, Expr *p){
if( p ){
if( IN_RENAME_OBJECT ){
sqlite3RenameExprUnmap(pParse, p);
}
sqlite3ExprDeleteNN(pParse->db, p);
}
}
static int exprStructSize(const Expr *p){
if( ExprHasProperty(p, EP_TokenOnly) ) return EXPR_TOKENONLYSIZE;
if( ExprHasProperty(p, EP_Reduced) ) return EXPR_REDUCEDSIZE;
return EXPR_FULLSIZE;
}
static int dupedExprStructSize(const Expr *p, int flags){
int nSize;
assert( flags==EXPRDUP_REDUCE || flags==0 );
assert( EXPR_FULLSIZE<=0xfff );
assert( (0xfff & (EP_Reduced|EP_TokenOnly))==0 );
if( 0==flags || p->op==TK_SELECT_COLUMN
#ifndef SQLITE_OMIT_WINDOWFUNC
|| ExprHasProperty(p, EP_WinFunc)
#endif
){
nSize = EXPR_FULLSIZE;
}else{
assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) );
assert( !ExprHasProperty(p, EP_OuterON) );
assert( !ExprHasVVAProperty(p, EP_NoReduce) );
if( p->pLeft || p->x.pList ){
nSize = EXPR_REDUCEDSIZE | EP_Reduced;
}else{
assert( p->pRight==0 );
nSize = EXPR_TOKENONLYSIZE | EP_TokenOnly;
}
}
return nSize;
}
static int dupedExprNodeSize(const Expr *p, int flags){
int nByte = dupedExprStructSize(p, flags) & 0xfff;
if( !ExprHasProperty(p, EP_IntValue) && p->u.zToken ){
nByte += sqlite3Strlen30NN(p->u.zToken)+1;
}
return ROUND8(nByte);
}
static int dupedExprSize(const Expr *p, int flags){
int nByte = 0;
if( p ){
nByte = dupedExprNodeSize(p, flags);
if( flags&EXPRDUP_REDUCE ){
nByte += dupedExprSize(p->pLeft, flags) + dupedExprSize(p->pRight, flags);
}
}
return nByte;
}
static Expr *exprDup(sqlite3 *db, const Expr *p, int dupFlags, u8 **pzBuffer){
Expr *pNew;
u8 *zAlloc;
u32 staticFlag;
assert( db!=0 );
assert( p );
assert( dupFlags==0 || dupFlags==EXPRDUP_REDUCE );
assert( pzBuffer==0 || dupFlags==EXPRDUP_REDUCE );
if( pzBuffer ){
zAlloc = *pzBuffer;
staticFlag = EP_Static;
assert( zAlloc!=0 );
}else{
zAlloc = sqlite3DbMallocRawNN(db, dupedExprSize(p, dupFlags));
staticFlag = 0;
}
pNew = (Expr *)zAlloc;
if( pNew ){
const unsigned nStructSize = dupedExprStructSize(p, dupFlags);
const int nNewSize = nStructSize & 0xfff;
int nToken;
if( !ExprHasProperty(p, EP_IntValue) && p->u.zToken ){
nToken = sqlite3Strlen30(p->u.zToken) + 1;
}else{
nToken = 0;
}
if( dupFlags ){
assert( ExprHasProperty(p, EP_Reduced)==0 );
memcpy(zAlloc, p, nNewSize);
}else{
u32 nSize = (u32)exprStructSize(p);
memcpy(zAlloc, p, nSize);
if( nSize<EXPR_FULLSIZE ){
memset(&zAlloc[nSize], 0, EXPR_FULLSIZE-nSize);
}
}
pNew->flags &= ~(EP_Reduced|EP_TokenOnly|EP_Static);
pNew->flags |= nStructSize & (EP_Reduced|EP_TokenOnly);
pNew->flags |= staticFlag;
ExprClearVVAProperties(pNew);
if( dupFlags ){
ExprSetVVAProperty(pNew, EP_Immutable);
}
if( nToken ){
char *zToken = pNew->u.zToken = (char*)&zAlloc[nNewSize];
memcpy(zToken, p->u.zToken, nToken);
}
if( 0==((p->flags|pNew->flags) & (EP_TokenOnly|EP_Leaf)) ){
if( ExprUseXSelect(p) ){
pNew->x.pSelect = sqlite3SelectDup(db, p->x.pSelect, dupFlags);
}else{
pNew->x.pList = sqlite3ExprListDup(db, p->x.pList, dupFlags);
}
}
if( ExprHasProperty(pNew, EP_Reduced|EP_TokenOnly|EP_WinFunc) ){
zAlloc += dupedExprNodeSize(p, dupFlags);
if( !ExprHasProperty(pNew, EP_TokenOnly|EP_Leaf) ){
pNew->pLeft = p->pLeft ?
exprDup(db, p->pLeft, EXPRDUP_REDUCE, &zAlloc) : 0;
pNew->pRight = p->pRight ?
exprDup(db, p->pRight, EXPRDUP_REDUCE, &zAlloc) : 0;
}
#ifndef SQLITE_OMIT_WINDOWFUNC
if( ExprHasProperty(p, EP_WinFunc) ){
pNew->y.pWin = sqlite3WindowDup(db, pNew, p->y.pWin);
assert( ExprHasProperty(pNew, EP_WinFunc) );
}
#endif
if( pzBuffer ){
*pzBuffer = zAlloc;
}
}else{
if( !ExprHasProperty(p, EP_TokenOnly|EP_Leaf) ){
if( pNew->op==TK_SELECT_COLUMN ){
pNew->pLeft = p->pLeft;
assert( p->pRight==0 || p->pRight==p->pLeft
|| ExprHasProperty(p->pLeft, EP_Subquery) );
}else{
pNew->pLeft = sqlite3ExprDup(db, p->pLeft, 0);
}
pNew->pRight = sqlite3ExprDup(db, p->pRight, 0);
}
}
}
return pNew;
}
#ifndef SQLITE_OMIT_CTE
With *sqlite3WithDup(sqlite3 *db, With *p){
With *pRet = 0;
if( p ){
sqlite3_int64 nByte = sizeof(*p) + sizeof(p->a[0]) * (p->nCte-1);
pRet = sqlite3DbMallocZero(db, nByte);
if( pRet ){
int i;
pRet->nCte = p->nCte;
for(i=0; i<p->nCte; i++){
pRet->a[i].pSelect = sqlite3SelectDup(db, p->a[i].pSelect, 0);
pRet->a[i].pCols = sqlite3ExprListDup(db, p->a[i].pCols, 0);
pRet->a[i].zName = sqlite3DbStrDup(db, p->a[i].zName);
pRet->a[i].eM10d = p->a[i].eM10d;
}
}
}
return pRet;
}
#else
# define sqlite3WithDup(x,y) 0
#endif
#ifndef SQLITE_OMIT_WINDOWFUNC
static int gatherSelectWindowsCallback(Walker *pWalker, Expr *pExpr){
if( pExpr->op==TK_FUNCTION && ExprHasProperty(pExpr, EP_WinFunc) ){
Select *pSelect = pWalker->u.pSelect;
Window *pWin = pExpr->y.pWin;
assert( pWin );
assert( IsWindowFunc(pExpr) );
assert( pWin->ppThis==0 );
sqlite3WindowLink(pSelect, pWin);
}
return WRC_Continue;
}
static int gatherSelectWindowsSelectCallback(Walker *pWalker, Select *p){
return p==pWalker->u.pSelect ? WRC_Continue : WRC_Prune;
}
static void gatherSelectWindows(Select *p){
Walker w;
w.xExprCallback = gatherSelectWindowsCallback;
w.xSelectCallback = gatherSelectWindowsSelectCallback;
w.xSelectCallback2 = 0;
w.pParse = 0;
w.u.pSelect = p;
sqlite3WalkSelect(&w, p);
}
#endif
Expr *sqlite3ExprDup(sqlite3 *db, const Expr *p, int flags){
assert( flags==0 || flags==EXPRDUP_REDUCE );
return p ? exprDup(db, p, flags, 0) : 0;
}
ExprList *sqlite3ExprListDup(sqlite3 *db, const ExprList *p, int flags){
ExprList *pNew;
struct ExprList_item *pItem;
const struct ExprList_item *pOldItem;
int i;
Expr *pPriorSelectColOld = 0;
Expr *pPriorSelectColNew = 0;
assert( db!=0 );
if( p==0 ) return 0;
pNew = sqlite3DbMallocRawNN(db, sqlite3DbMallocSize(db, p));
if( pNew==0 ) return 0;
pNew->nExpr = p->nExpr;
pNew->nAlloc = p->nAlloc;
pItem = pNew->a;
pOldItem = p->a;
for(i=0; i<p->nExpr; i++, pItem++, pOldItem++){
Expr *pOldExpr = pOldItem->pExpr;
Expr *pNewExpr;
pItem->pExpr = sqlite3ExprDup(db, pOldExpr, flags);
if( pOldExpr
&& pOldExpr->op==TK_SELECT_COLUMN
&& (pNewExpr = pItem->pExpr)!=0
){
if( pNewExpr->pRight ){
pPriorSelectColOld = pOldExpr->pRight;
pPriorSelectColNew = pNewExpr->pRight;
pNewExpr->pLeft = pNewExpr->pRight;
}else{
if( pOldExpr->pLeft!=pPriorSelectColOld ){
pPriorSelectColOld = pOldExpr->pLeft;
pPriorSelectColNew = sqlite3ExprDup(db, pPriorSelectColOld, flags);
pNewExpr->pRight = pPriorSelectColNew;
}
pNewExpr->pLeft = pPriorSelectColNew;
}
}
pItem->zEName = sqlite3DbStrDup(db, pOldItem->zEName);
pItem->fg = pOldItem->fg;
pItem->fg.done = 0;
pItem->u = pOldItem->u;
}
return pNew;
}
#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER) \
|| !defined(SQLITE_OMIT_SUBQUERY)
SrcList *sqlite3SrcListDup(sqlite3 *db, const SrcList *p, int flags){
SrcList *pNew;
int i;
int nByte;
assert( db!=0 );
if( p==0 ) return 0;
nByte = sizeof(*p) + (p->nSrc>0 ? sizeof(p->a[0]) * (p->nSrc-1) : 0);
pNew = sqlite3DbMallocRawNN(db, nByte );
if( pNew==0 ) return 0;
pNew->nSrc = pNew->nAlloc = p->nSrc;
for(i=0; i<p->nSrc; i++){
SrcItem *pNewItem = &pNew->a[i];
const SrcItem *pOldItem = &p->a[i];
Table *pTab;
pNewItem->pSchema = pOldItem->pSchema;
pNewItem->zDatabase = sqlite3DbStrDup(db, pOldItem->zDatabase);
pNewItem->zName = sqlite3DbStrDup(db, pOldItem->zName);
pNewItem->zAlias = sqlite3DbStrDup(db, pOldItem->zAlias);
pNewItem->fg = pOldItem->fg;
pNewItem->iCursor = pOldItem->iCursor;
pNewItem->addrFillSub = pOldItem->addrFillSub;
pNewItem->regReturn = pOldItem->regReturn;
if( pNewItem->fg.isIndexedBy ){
pNewItem->u1.zIndexedBy = sqlite3DbStrDup(db, pOldItem->u1.zIndexedBy);
}
pNewItem->u2 = pOldItem->u2;
if( pNewItem->fg.isCte ){
pNewItem->u2.pCteUse->nUse++;
}
if( pNewItem->fg.isTabFunc ){
pNewItem->u1.pFuncArg =
sqlite3ExprListDup(db, pOldItem->u1.pFuncArg, flags);
}
pTab = pNewItem->pTab = pOldItem->pTab;
if( pTab ){
pTab->nTabRef++;
}
pNewItem->pSelect = sqlite3SelectDup(db, pOldItem->pSelect, flags);
if( pOldItem->fg.isUsing ){
assert( pNewItem->fg.isUsing );
pNewItem->u3.pUsing = sqlite3IdListDup(db, pOldItem->u3.pUsing);
}else{
pNewItem->u3.pOn = sqlite3ExprDup(db, pOldItem->u3.pOn, flags);
}
pNewItem->colUsed = pOldItem->colUsed;
}
return pNew;
}
IdList *sqlite3IdListDup(sqlite3 *db, const IdList *p){
IdList *pNew;
int i;
assert( db!=0 );
if( p==0 ) return 0;
assert( p->eU4!=EU4_EXPR );
pNew = sqlite3DbMallocRawNN(db, sizeof(*pNew)+(p->nId-1)*sizeof(p->a[0]) );
if( pNew==0 ) return 0;
pNew->nId = p->nId;
pNew->eU4 = p->eU4;
for(i=0; i<p->nId; i++){
struct IdList_item *pNewItem = &pNew->a[i];
const struct IdList_item *pOldItem = &p->a[i];
pNewItem->zName = sqlite3DbStrDup(db, pOldItem->zName);
pNewItem->u4 = pOldItem->u4;
}
return pNew;
}
Select *sqlite3SelectDup(sqlite3 *db, const Select *pDup, int flags){
Select *pRet = 0;
Select *pNext = 0;
Select **pp = &pRet;
const Select *p;
assert( db!=0 );
for(p=pDup; p; p=p->pPrior){
Select *pNew = sqlite3DbMallocRawNN(db, sizeof(*p) );
if( pNew==0 ) break;
pNew->pEList = sqlite3ExprListDup(db, p->pEList, flags);
pNew->pSrc = sqlite3SrcListDup(db, p->pSrc, flags);
pNew->pWhere = sqlite3ExprDup(db, p->pWhere, flags);
pNew->pGroupBy = sqlite3ExprListDup(db, p->pGroupBy, flags);
pNew->pHaving = sqlite3ExprDup(db, p->pHaving, flags);
pNew->pOrderBy = sqlite3ExprListDup(db, p->pOrderBy, flags);
pNew->op = p->op;
pNew->pNext = pNext;
pNew->pPrior = 0;
pNew->pLimit = sqlite3ExprDup(db, p->pLimit, flags);
pNew->iLimit = 0;
pNew->iOffset = 0;
pNew->selFlags = p->selFlags & ~SF_UsesEphemeral;
pNew->addrOpenEphm[0] = -1;
pNew->addrOpenEphm[1] = -1;
pNew->nSelectRow = p->nSelectRow;
pNew->pWith = sqlite3WithDup(db, p->pWith);
#ifndef SQLITE_OMIT_WINDOWFUNC
pNew->pWin = 0;
pNew->pWinDefn = sqlite3WindowListDup(db, p->pWinDefn);
if( p->pWin && db->mallocFailed==0 ) gatherSelectWindows(pNew);
#endif
pNew->selId = p->selId;
if( db->mallocFailed ){
pNew->pNext = 0;
sqlite3SelectDelete(db, pNew);
break;
}
*pp = pNew;
pp = &pNew->pPrior;
pNext = pNew;
}
return pRet;
}
#else
Select *sqlite3SelectDup(sqlite3 *db, const Select *p, int flags){
assert( p==0 );
return 0;
}
#endif
static const struct ExprList_item zeroItem = {0};
SQLITE_NOINLINE ExprList *sqlite3ExprListAppendNew(
sqlite3 *db,
Expr *pExpr
){
struct ExprList_item *pItem;
ExprList *pList;
pList = sqlite3DbMallocRawNN(db, sizeof(ExprList)+sizeof(pList->a[0])*4 );
if( pList==0 ){
sqlite3ExprDelete(db, pExpr);
return 0;
}
pList->nAlloc = 4;
pList->nExpr = 1;
pItem = &pList->a[0];
*pItem = zeroItem;
pItem->pExpr = pExpr;
return pList;
}
SQLITE_NOINLINE ExprList *sqlite3ExprListAppendGrow(
sqlite3 *db,
ExprList *pList,
Expr *pExpr
){
struct ExprList_item *pItem;
ExprList *pNew;
pList->nAlloc *= 2;
pNew = sqlite3DbRealloc(db, pList,
sizeof(*pList)+(pList->nAlloc-1)*sizeof(pList->a[0]));
if( pNew==0 ){
sqlite3ExprListDelete(db, pList);
sqlite3ExprDelete(db, pExpr);
return 0;
}else{
pList = pNew;
}
pItem = &pList->a[pList->nExpr++];
*pItem = zeroItem;
pItem->pExpr = pExpr;
return pList;
}
ExprList *sqlite3ExprListAppend(
Parse *pParse,
ExprList *pList,
Expr *pExpr
){
struct ExprList_item *pItem;
if( pList==0 ){
return sqlite3ExprListAppendNew(pParse->db,pExpr);
}
if( pList->nAlloc<pList->nExpr+1 ){
return sqlite3ExprListAppendGrow(pParse->db,pList,pExpr);
}
pItem = &pList->a[pList->nExpr++];
*pItem = zeroItem;
pItem->pExpr = pExpr;
return pList;
}
ExprList *sqlite3ExprListAppendVector(
Parse *pParse,
ExprList *pList,
IdList *pColumns,
Expr *pExpr
){
sqlite3 *db = pParse->db;
int n;
int i;
int iFirst = pList ? pList->nExpr : 0;
if( NEVER(pColumns==0) ) goto vector_append_error;
if( pExpr==0 ) goto vector_append_error;
if( pExpr->op!=TK_SELECT && pColumns->nId!=(n=sqlite3ExprVectorSize(pExpr)) ){
sqlite3ErrorMsg(pParse, "%d columns assigned %d values",
pColumns->nId, n);
goto vector_append_error;
}
for(i=0; i<pColumns->nId; i++){
Expr *pSubExpr = sqlite3ExprForVectorField(pParse, pExpr, i, pColumns->nId);
assert( pSubExpr!=0 || db->mallocFailed );
if( pSubExpr==0 ) continue;
pList = sqlite3ExprListAppend(pParse, pList, pSubExpr);
if( pList ){
assert( pList->nExpr==iFirst+i+1 );
pList->a[pList->nExpr-1].zEName = pColumns->a[i].zName;
pColumns->a[i].zName = 0;
}
}
if( !db->mallocFailed && pExpr->op==TK_SELECT && ALWAYS(pList!=0) ){
Expr *pFirst = pList->a[iFirst].pExpr;
assert( pFirst!=0 );
assert( pFirst->op==TK_SELECT_COLUMN );
pFirst->pRight = pExpr;
pExpr = 0;
pFirst->iTable = pColumns->nId;
}
vector_append_error:
sqlite3ExprUnmapAndDelete(pParse, pExpr);
sqlite3IdListDelete(db, pColumns);
return pList;
}
void sqlite3ExprListSetSortOrder(ExprList *p, int iSortOrder, int eNulls){
struct ExprList_item *pItem;
if( p==0 ) return;
assert( p->nExpr>0 );
assert( SQLITE_SO_UNDEFINED<0 && SQLITE_SO_ASC==0 && SQLITE_SO_DESC>0 );
assert( iSortOrder==SQLITE_SO_UNDEFINED
|| iSortOrder==SQLITE_SO_ASC
|| iSortOrder==SQLITE_SO_DESC
);
assert( eNulls==SQLITE_SO_UNDEFINED
|| eNulls==SQLITE_SO_ASC
|| eNulls==SQLITE_SO_DESC
);
pItem = &p->a[p->nExpr-1];
assert( pItem->fg.bNulls==0 );
if( iSortOrder==SQLITE_SO_UNDEFINED ){
iSortOrder = SQLITE_SO_ASC;
}
pItem->fg.sortFlags = (u8)iSortOrder;
if( eNulls!=SQLITE_SO_UNDEFINED ){
pItem->fg.bNulls = 1;
if( iSortOrder!=eNulls ){
pItem->fg.sortFlags |= KEYINFO_ORDER_BIGNULL;
}
}
}
void sqlite3ExprListSetName(
Parse *pParse,
ExprList *pList,
const Token *pName,
int dequote
){
assert( pList!=0 || pParse->db->mallocFailed!=0 );
assert( pParse->eParseMode!=PARSE_MODE_UNMAP || dequote==0 );
if( pList ){
struct ExprList_item *pItem;
assert( pList->nExpr>0 );
pItem = &pList->a[pList->nExpr-1];
assert( pItem->zEName==0 );
assert( pItem->fg.eEName==ENAME_NAME );
pItem->zEName = sqlite3DbStrNDup(pParse->db, pName->z, pName->n);
if( dequote ){
sqlite3Dequote(pItem->zEName);
if( IN_RENAME_OBJECT ){
sqlite3RenameTokenMap(pParse, (const void*)pItem->zEName, pName);
}
}
}
}
void sqlite3ExprListSetSpan(
Parse *pParse,
ExprList *pList,
const char *zStart,
const char *zEnd
){
sqlite3 *db = pParse->db;
assert( pList!=0 || db->mallocFailed!=0 );
if( pList ){
struct ExprList_item *pItem = &pList->a[pList->nExpr-1];
assert( pList->nExpr>0 );
if( pItem->zEName==0 ){
pItem->zEName = sqlite3DbSpanDup(db, zStart, zEnd);
pItem->fg.eEName = ENAME_SPAN;
}
}
}
void sqlite3ExprListCheckLength(
Parse *pParse,
ExprList *pEList,
const char *zObject
){
int mx = pParse->db->aLimit[SQLITE_LIMIT_COLUMN];
testcase( pEList && pEList->nExpr==mx );
testcase( pEList && pEList->nExpr==mx+1 );
if( pEList && pEList->nExpr>mx ){
sqlite3ErrorMsg(pParse, "too many columns in %s", zObject);
}
}
static SQLITE_NOINLINE void exprListDeleteNN(sqlite3 *db, ExprList *pList){
int i = pList->nExpr;
struct ExprList_item *pItem = pList->a;
assert( pList->nExpr>0 );
assert( db!=0 );
do{
sqlite3ExprDelete(db, pItem->pExpr);
if( pItem->zEName ) sqlite3DbNNFreeNN(db, pItem->zEName);
pItem++;
}while( --i>0 );
sqlite3DbNNFreeNN(db, pList);
}
void sqlite3ExprListDelete(sqlite3 *db, ExprList *pList){
if( pList ) exprListDeleteNN(db, pList);
}
u32 sqlite3ExprListFlags(const ExprList *pList){
int i;
u32 m = 0;
assert( pList!=0 );
for(i=0; i<pList->nExpr; i++){
Expr *pExpr = pList->a[i].pExpr;
assert( pExpr!=0 );
m |= pExpr->flags;
}
return m;
}
int sqlite3SelectWalkFail(Walker *pWalker, Select *NotUsed){
UNUSED_PARAMETER(NotUsed);
pWalker->eCode = 0;
return WRC_Abort;
}
u32 sqlite3IsTrueOrFalse(const char *zIn){
if( sqlite3StrICmp(zIn, "true")==0 ) return EP_IsTrue;
if( sqlite3StrICmp(zIn, "false")==0 ) return EP_IsFalse;
return 0;
}
int sqlite3ExprIdToTrueFalse(Expr *pExpr){
u32 v;
assert( pExpr->op==TK_ID || pExpr->op==TK_STRING );
if( !ExprHasProperty(pExpr, EP_Quoted|EP_IntValue)
&& (v = sqlite3IsTrueOrFalse(pExpr->u.zToken))!=0
){
pExpr->op = TK_TRUEFALSE;
ExprSetProperty(pExpr, v);
return 1;
}
return 0;
}
int sqlite3ExprTruthValue(const Expr *pExpr){
pExpr = sqlite3ExprSkipCollateAndLikely((Expr*)pExpr);
assert( pExpr->op==TK_TRUEFALSE );
assert( !ExprHasProperty(pExpr, EP_IntValue) );
assert( sqlite3StrICmp(pExpr->u.zToken,"true")==0
|| sqlite3StrICmp(pExpr->u.zToken,"false")==0 );
return pExpr->u.zToken[4]==0;
}
Expr *sqlite3ExprSimplifiedAndOr(Expr *pExpr){
assert( pExpr!=0 );
if( pExpr->op==TK_AND || pExpr->op==TK_OR ){
Expr *pRight = sqlite3ExprSimplifiedAndOr(pExpr->pRight);
Expr *pLeft = sqlite3ExprSimplifiedAndOr(pExpr->pLeft);
if( ExprAlwaysTrue(pLeft) || ExprAlwaysFalse(pRight) ){
pExpr = pExpr->op==TK_AND ? pRight : pLeft;
}else if( ExprAlwaysTrue(pRight) || ExprAlwaysFalse(pLeft) ){
pExpr = pExpr->op==TK_AND ? pLeft : pRight;
}
}
return pExpr;
}
static int exprNodeIsConstant(Walker *pWalker, Expr *pExpr){
if( pWalker->eCode==2 && ExprHasProperty(pExpr, EP_OuterON) ){
pWalker->eCode = 0;
return WRC_Abort;
}
switch( pExpr->op ){
case TK_FUNCTION:
if( (pWalker->eCode>=4 || ExprHasProperty(pExpr,EP_ConstFunc))
&& !ExprHasProperty(pExpr, EP_WinFunc)
){
if( pWalker->eCode==5 ) ExprSetProperty(pExpr, EP_FromDDL);
return WRC_Continue;
}else{
pWalker->eCode = 0;
return WRC_Abort;
}
case TK_ID:
if( sqlite3ExprIdToTrueFalse(pExpr) ){
return WRC_Prune;
}
deliberate_fall_through
case TK_COLUMN:
case TK_AGG_FUNCTION:
case TK_AGG_COLUMN:
testcase( pExpr->op==TK_ID );
testcase( pExpr->op==TK_COLUMN );
testcase( pExpr->op==TK_AGG_FUNCTION );
testcase( pExpr->op==TK_AGG_COLUMN );
if( ExprHasProperty(pExpr, EP_FixedCol) && pWalker->eCode!=2 ){
return WRC_Continue;
}
if( pWalker->eCode==3 && pExpr->iTable==pWalker->u.iCur ){
return WRC_Continue;
}
deliberate_fall_through
case TK_IF_NULL_ROW:
case TK_REGISTER:
case TK_DOT:
testcase( pExpr->op==TK_REGISTER );
testcase( pExpr->op==TK_IF_NULL_ROW );
testcase( pExpr->op==TK_DOT );
pWalker->eCode = 0;
return WRC_Abort;
case TK_VARIABLE:
if( pWalker->eCode==5 ){
pExpr->op = TK_NULL;
}else if( pWalker->eCode==4 ){
pWalker->eCode = 0;
return WRC_Abort;
}
deliberate_fall_through
default:
testcase( pExpr->op==TK_SELECT );
testcase( pExpr->op==TK_EXISTS );
return WRC_Continue;
}
}
static int exprIsConst(Expr *p, int initFlag, int iCur){
Walker w;
w.eCode = initFlag;
w.xExprCallback = exprNodeIsConstant;
w.xSelectCallback = sqlite3SelectWalkFail;
#ifdef SQLITE_DEBUG
w.xSelectCallback2 = sqlite3SelectWalkAssert2;
#endif
w.u.iCur = iCur;
sqlite3WalkExpr(&w, p);
return w.eCode;
}
int sqlite3ExprIsConstant(Expr *p){
return exprIsConst(p, 1, 0);
}
int sqlite3ExprIsConstantNotJoin(Expr *p){
return exprIsConst(p, 2, 0);
}
int sqlite3ExprIsTableConstant(Expr *p, int iCur){
return exprIsConst(p, 3, iCur);
}
int sqlite3ExprIsSingleTableConstraint(
Expr *pExpr,
const SrcList *pSrcList,
int iSrc
){
const SrcItem *pSrc = &pSrcList->a[iSrc];
if( pSrc->fg.jointype & JT_LTORJ ){
return 0;
}
if( pSrc->fg.jointype & JT_LEFT ){
if( !ExprHasProperty(pExpr, EP_OuterON) ) return 0;
if( pExpr->w.iJoin!=pSrc->iCursor ) return 0;
}else{
if( ExprHasProperty(pExpr, EP_OuterON) ) return 0;
}
if( ExprHasProperty(pExpr, EP_OuterON|EP_InnerON)
&& (pSrcList->a[0].fg.jointype & JT_LTORJ)!=0
){
int jj;
for(jj=0; jj<iSrc; jj++){
if( pExpr->w.iJoin==pSrcList->a[jj].iCursor ){
if( (pSrcList->a[jj].fg.jointype & JT_LTORJ)!=0 ){
return 0;
}
break;
}
}
}
return sqlite3ExprIsTableConstant(pExpr, pSrc->iCursor);
}
static int exprNodeIsConstantOrGroupBy(Walker *pWalker, Expr *pExpr){
ExprList *pGroupBy = pWalker->u.pGroupBy;
int i;
for(i=0; i<pGroupBy->nExpr; i++){
Expr *p = pGroupBy->a[i].pExpr;
if( sqlite3ExprCompare(0, pExpr, p, -1)<2 ){
CollSeq *pColl = sqlite3ExprNNCollSeq(pWalker->pParse, p);
if( sqlite3IsBinary(pColl) ){
return WRC_Prune;
}
}
}
if( ExprUseXSelect(pExpr) ){
pWalker->eCode = 0;
return WRC_Abort;
}
return exprNodeIsConstant(pWalker, pExpr);
}
int sqlite3ExprIsConstantOrGroupBy(Parse *pParse, Expr *p, ExprList *pGroupBy){
Walker w;
w.eCode = 1;
w.xExprCallback = exprNodeIsConstantOrGroupBy;
w.xSelectCallback = 0;
w.u.pGroupBy = pGroupBy;
w.pParse = pParse;
sqlite3WalkExpr(&w, p);
return w.eCode;
}
int sqlite3ExprIsConstantOrFunction(Expr *p, u8 isInit){
assert( isInit==0 || isInit==1 );
return exprIsConst(p, 4+isInit, 0);
}
#ifdef SQLITE_ENABLE_CURSOR_HINTS
int sqlite3ExprContainsSubquery(Expr *p){
Walker w;
w.eCode = 1;
w.xExprCallback = sqlite3ExprWalkNoop;
w.xSelectCallback = sqlite3SelectWalkFail;
#ifdef SQLITE_DEBUG
w.xSelectCallback2 = sqlite3SelectWalkAssert2;
#endif
sqlite3WalkExpr(&w, p);
return w.eCode==0;
}
#endif
int sqlite3ExprIsInteger(const Expr *p, int *pValue){
int rc = 0;
if( NEVER(p==0) ) return 0;
assert( p->op!=TK_INTEGER || (p->flags & EP_IntValue)!=0
|| sqlite3GetInt32(p->u.zToken, &rc)==0 );
if( p->flags & EP_IntValue ){
*pValue = p->u.iValue;
return 1;
}
switch( p->op ){
case TK_UPLUS: {
rc = sqlite3ExprIsInteger(p->pLeft, pValue);
break;
}
case TK_UMINUS: {
int v = 0;
if( sqlite3ExprIsInteger(p->pLeft, &v) ){
assert( ((unsigned int)v)!=0x80000000 );
*pValue = -v;
rc = 1;
}
break;
}
default: break;
}
return rc;
}
int sqlite3ExprCanBeNull(const Expr *p){
u8 op;
assert( p!=0 );
while( p->op==TK_UPLUS || p->op==TK_UMINUS ){
p = p->pLeft;
assert( p!=0 );
}
op = p->op;
if( op==TK_REGISTER ) op = p->op2;
switch( op ){
case TK_INTEGER:
case TK_STRING:
case TK_FLOAT:
case TK_BLOB:
return 0;
case TK_COLUMN:
assert( ExprUseYTab(p) );
return ExprHasProperty(p, EP_CanBeNull) ||
p->y.pTab==0 ||
(p->iColumn>=0
&& p->y.pTab->aCol!=0
&& p->y.pTab->aCol[p->iColumn].notNull==0);
default:
return 1;
}
}
int sqlite3ExprNeedsNoAffinityChange(const Expr *p, char aff){
u8 op;
int unaryMinus = 0;
if( aff==SQLITE_AFF_BLOB ) return 1;
while( p->op==TK_UPLUS || p->op==TK_UMINUS ){
if( p->op==TK_UMINUS ) unaryMinus = 1;
p = p->pLeft;
}
op = p->op;
if( op==TK_REGISTER ) op = p->op2;
switch( op ){
case TK_INTEGER: {
return aff>=SQLITE_AFF_NUMERIC;
}
case TK_FLOAT: {
return aff>=SQLITE_AFF_NUMERIC;
}
case TK_STRING: {
return !unaryMinus && aff==SQLITE_AFF_TEXT;
}
case TK_BLOB: {
return !unaryMinus;
}
case TK_COLUMN: {
assert( p->iTable>=0 );
return aff>=SQLITE_AFF_NUMERIC && p->iColumn<0;
}
default: {
return 0;
}
}
}
int sqlite3IsRowid(const char *z){
if( sqlite3StrICmp(z, "_ROWID_")==0 ) return 1;
if( sqlite3StrICmp(z, "ROWID")==0 ) return 1;
if( sqlite3StrICmp(z, "OID")==0 ) return 1;
return 0;
}
#ifndef SQLITE_OMIT_SUBQUERY
static Select *isCandidateForInOpt(const Expr *pX){
Select *p;
SrcList *pSrc;
ExprList *pEList;
Table *pTab;
int i;
if( !ExprUseXSelect(pX) ) return 0;
if( ExprHasProperty(pX, EP_VarSelect) ) return 0;
p = pX->x.pSelect;
if( p->pPrior ) return 0;
if( p->selFlags & (SF_Distinct|SF_Aggregate) ){
testcase( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct );
testcase( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Aggregate );
return 0;
}
assert( p->pGroupBy==0 );
if( p->pLimit ) return 0;
if( p->pWhere ) return 0;
pSrc = p->pSrc;
assert( pSrc!=0 );
if( pSrc->nSrc!=1 ) return 0;
if( pSrc->a[0].pSelect ) return 0;
pTab = pSrc->a[0].pTab;
assert( pTab!=0 );
assert( !IsView(pTab) );
if( IsVirtual(pTab) ) return 0;
pEList = p->pEList;
assert( pEList!=0 );
for(i=0; i<pEList->nExpr; i++){
Expr *pRes = pEList->a[i].pExpr;
if( pRes->op!=TK_COLUMN ) return 0;
assert( pRes->iTable==pSrc->a[0].iCursor );
}
return p;
}
#endif
#ifndef SQLITE_OMIT_SUBQUERY
static void sqlite3SetHasNullFlag(Vdbe *v, int iCur, int regHasNull){
int addr1;
sqlite3VdbeAddOp2(v, OP_Integer, 0, regHasNull);
addr1 = sqlite3VdbeAddOp1(v, OP_Rewind, iCur); VdbeCoverage(v);
sqlite3VdbeAddOp3(v, OP_Column, iCur, 0, regHasNull);
sqlite3VdbeChangeP5(v, OPFLAG_TYPEOFARG);
VdbeComment((v, "first_entry_in(%d)", iCur));
sqlite3VdbeJumpHere(v, addr1);
}
#endif
#ifndef SQLITE_OMIT_SUBQUERY
static int sqlite3InRhsIsConstant(Expr *pIn){
Expr *pLHS;
int res;
assert( !ExprHasProperty(pIn, EP_xIsSelect) );
pLHS = pIn->pLeft;
pIn->pLeft = 0;
res = sqlite3ExprIsConstant(pIn);
pIn->pLeft = pLHS;
return res;
}
#endif
#ifndef SQLITE_OMIT_SUBQUERY
int sqlite3FindInIndex(
Parse *pParse,
Expr *pX,
u32 inFlags,
int *prRhsHasNull,
int *aiMap,
int *piTab
){
Select *p;
int eType = 0;
int iTab;
int mustBeUnique;
Vdbe *v = sqlite3GetVdbe(pParse);
assert( pX->op==TK_IN );
mustBeUnique = (inFlags & IN_INDEX_LOOP)!=0;
iTab = pParse->nTab++;
if( prRhsHasNull && ExprUseXSelect(pX) ){
int i;
ExprList *pEList = pX->x.pSelect->pEList;
for(i=0; i<pEList->nExpr; i++){
if( sqlite3ExprCanBeNull(pEList->a[i].pExpr) ) break;
}
if( i==pEList->nExpr ){
prRhsHasNull = 0;
}
}
if( pParse->nErr==0 && (p = isCandidateForInOpt(pX))!=0 ){
sqlite3 *db = pParse->db;
Table *pTab;
int iDb;
ExprList *pEList = p->pEList;
int nExpr = pEList->nExpr;
assert( p->pEList!=0 );
assert( p->pEList->a[0].pExpr!=0 );
assert( p->pSrc!=0 );
pTab = p->pSrc->a[0].pTab;
iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
assert( iDb>=0 && iDb<SQLITE_MAX_DB );
sqlite3CodeVerifySchema(pParse, iDb);
sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);
assert(v);
if( nExpr==1 && pEList->a[0].pExpr->iColumn<0 ){
int iAddr = sqlite3VdbeAddOp0(v, OP_Once);
VdbeCoverage(v);
sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead);
eType = IN_INDEX_ROWID;
ExplainQueryPlan((pParse, 0,
"USING ROWID SEARCH ON TABLE %s FOR IN-OPERATOR",pTab->zName));
sqlite3VdbeJumpHere(v, iAddr);
}else{
Index *pIdx;
int affinity_ok = 1;
int i;
for(i=0; i<nExpr && affinity_ok; i++){
Expr *pLhs = sqlite3VectorFieldSubexpr(pX->pLeft, i);
int iCol = pEList->a[i].pExpr->iColumn;
char idxaff = sqlite3TableColumnAffinity(pTab,iCol);
char cmpaff = sqlite3CompareAffinity(pLhs, idxaff);
testcase( cmpaff==SQLITE_AFF_BLOB );
testcase( cmpaff==SQLITE_AFF_TEXT );
switch( cmpaff ){
case SQLITE_AFF_BLOB:
break;
case SQLITE_AFF_TEXT:
assert( idxaff==SQLITE_AFF_TEXT );
break;
default:
affinity_ok = sqlite3IsNumericAffinity(idxaff);
}
}
if( affinity_ok ){
for(pIdx=pTab->pIndex; pIdx && eType==0; pIdx=pIdx->pNext){
Bitmask colUsed;
Bitmask mCol;
if( pIdx->nColumn<nExpr ) continue;
if( pIdx->pPartIdxWhere!=0 ) continue;
testcase( pIdx->nColumn==BMS-2 );
testcase( pIdx->nColumn==BMS-1 );
if( pIdx->nColumn>=BMS-1 ) continue;
if( mustBeUnique ){
if( pIdx->nKeyCol>nExpr
||(pIdx->nColumn>nExpr && !IsUniqueIndex(pIdx))
){
continue;
}
}
colUsed = 0;
for(i=0; i<nExpr; i++){
Expr *pLhs = sqlite3VectorFieldSubexpr(pX->pLeft, i);
Expr *pRhs = pEList->a[i].pExpr;
CollSeq *pReq = sqlite3BinaryCompareCollSeq(pParse, pLhs, pRhs);
int j;
for(j=0; j<nExpr; j++){
if( pIdx->aiColumn[j]!=pRhs->iColumn ) continue;
assert( pIdx->azColl[j] );
if( pReq!=0 && sqlite3StrICmp(pReq->zName, pIdx->azColl[j])!=0 ){
continue;
}
break;
}
if( j==nExpr ) break;
mCol = MASKBIT(j);
if( mCol & colUsed ) break;
colUsed |= mCol;
if( aiMap ) aiMap[i] = j;
}
assert( i==nExpr || colUsed!=(MASKBIT(nExpr)-1) );
if( colUsed==(MASKBIT(nExpr)-1) ){
int iAddr = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
ExplainQueryPlan((pParse, 0,
"USING INDEX %s FOR IN-OPERATOR",pIdx->zName));
sqlite3VdbeAddOp3(v, OP_OpenRead, iTab, pIdx->tnum, iDb);
sqlite3VdbeSetP4KeyInfo(pParse, pIdx);
VdbeComment((v, "%s", pIdx->zName));
assert( IN_INDEX_INDEX_DESC == IN_INDEX_INDEX_ASC+1 );
eType = IN_INDEX_INDEX_ASC + pIdx->aSortOrder[0];
if( prRhsHasNull ){
#ifdef SQLITE_ENABLE_COLUMN_USED_MASK
i64 mask = (1<<nExpr)-1;
sqlite3VdbeAddOp4Dup8(v, OP_ColumnsUsed,
iTab, 0, 0, (u8*)&mask, P4_INT64);
#endif
*prRhsHasNull = ++pParse->nMem;
if( nExpr==1 ){
sqlite3SetHasNullFlag(v, iTab, *prRhsHasNull);
}
}
sqlite3VdbeJumpHere(v, iAddr);
}
}
}
}
}
if( eType==0
&& (inFlags & IN_INDEX_NOOP_OK)
&& ExprUseXList(pX)
&& (!sqlite3InRhsIsConstant(pX) || pX->x.pList->nExpr<=2)
){
pParse->nTab--;
iTab = -1;
eType = IN_INDEX_NOOP;
}
if( eType==0 ){
u32 savedNQueryLoop = pParse->nQueryLoop;
int rMayHaveNull = 0;
eType = IN_INDEX_EPH;
if( inFlags & IN_INDEX_LOOP ){
pParse->nQueryLoop = 0;
}else if( prRhsHasNull ){
*prRhsHasNull = rMayHaveNull = ++pParse->nMem;
}
assert( pX->op==TK_IN );
sqlite3CodeRhsOfIN(pParse, pX, iTab);
if( rMayHaveNull ){
sqlite3SetHasNullFlag(v, iTab, rMayHaveNull);
}
pParse->nQueryLoop = savedNQueryLoop;
}
if( aiMap && eType!=IN_INDEX_INDEX_ASC && eType!=IN_INDEX_INDEX_DESC ){
int i, n;
n = sqlite3ExprVectorSize(pX->pLeft);
for(i=0; i<n; i++) aiMap[i] = i;
}
*piTab = iTab;
return eType;
}
#endif
#ifndef SQLITE_OMIT_SUBQUERY
static char *exprINAffinity(Parse *pParse, const Expr *pExpr){
Expr *pLeft = pExpr->pLeft;
int nVal = sqlite3ExprVectorSize(pLeft);
Select *pSelect = ExprUseXSelect(pExpr) ? pExpr->x.pSelect : 0;
char *zRet;
assert( pExpr->op==TK_IN );
zRet = sqlite3DbMallocRaw(pParse->db, nVal+1);
if( zRet ){
int i;
for(i=0; i<nVal; i++){
Expr *pA = sqlite3VectorFieldSubexpr(pLeft, i);
char a = sqlite3ExprAffinity(pA);
if( pSelect ){
zRet[i] = sqlite3CompareAffinity(pSelect->pEList->a[i].pExpr, a);
}else{
zRet[i] = a;
}
}
zRet[nVal] = '\0';
}
return zRet;
}
#endif
#ifndef SQLITE_OMIT_SUBQUERY
void sqlite3SubselectError(Parse *pParse, int nActual, int nExpect){
if( pParse->nErr==0 ){
const char *zFmt = "sub-select returns %d columns - expected %d";
sqlite3ErrorMsg(pParse, zFmt, nActual, nExpect);
}
}
#endif
void sqlite3VectorErrorMsg(Parse *pParse, Expr *pExpr){
#ifndef SQLITE_OMIT_SUBQUERY
if( ExprUseXSelect(pExpr) ){
sqlite3SubselectError(pParse, pExpr->x.pSelect->pEList->nExpr, 1);
}else
#endif
{
sqlite3ErrorMsg(pParse, "row value misused");
}
}
#ifndef SQLITE_OMIT_SUBQUERY
void sqlite3CodeRhsOfIN(
Parse *pParse,
Expr *pExpr,
int iTab
){
int addrOnce = 0;
int addr;
Expr *pLeft;
KeyInfo *pKeyInfo = 0;
int nVal;
Vdbe *v;
v = pParse->pVdbe;
assert( v!=0 );
if( !ExprHasProperty(pExpr, EP_VarSelect) && pParse->iSelfTab==0 ){
if( ExprHasProperty(pExpr, EP_Subrtn) ){
addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
if( ExprUseXSelect(pExpr) ){
ExplainQueryPlan((pParse, 0, "REUSE LIST SUBQUERY %d",
pExpr->x.pSelect->selId));
}
assert( ExprUseYSub(pExpr) );
sqlite3VdbeAddOp2(v, OP_Gosub, pExpr->y.sub.regReturn,
pExpr->y.sub.iAddr);
assert( iTab!=pExpr->iTable );
sqlite3VdbeAddOp2(v, OP_OpenDup, iTab, pExpr->iTable);
sqlite3VdbeJumpHere(v, addrOnce);
return;
}
assert( !ExprUseYWin(pExpr) );
ExprSetProperty(pExpr, EP_Subrtn);
assert( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) );
pExpr->y.sub.regReturn = ++pParse->nMem;
pExpr->y.sub.iAddr =
sqlite3VdbeAddOp2(v, OP_BeginSubrtn, 0, pExpr->y.sub.regReturn) + 1;
addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
}
pLeft = pExpr->pLeft;
nVal = sqlite3ExprVectorSize(pLeft);
pExpr->iTable = iTab;
addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pExpr->iTable, nVal);
#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
if( ExprUseXSelect(pExpr) ){
VdbeComment((v, "Result of SELECT %u", pExpr->x.pSelect->selId));
}else{
VdbeComment((v, "RHS of IN operator"));
}
#endif
pKeyInfo = sqlite3KeyInfoAlloc(pParse->db, nVal, 1);
if( ExprUseXSelect(pExpr) ){
Select *pSelect = pExpr->x.pSelect;
ExprList *pEList = pSelect->pEList;
ExplainQueryPlan((pParse, 1, "%sLIST SUBQUERY %d",
addrOnce?"":"CORRELATED ", pSelect->selId
));
if( ALWAYS(pEList->nExpr==nVal) ){
Select *pCopy;
SelectDest dest;
int i;
int rc;
sqlite3SelectDestInit(&dest, SRT_Set, iTab);
dest.zAffSdst = exprINAffinity(pParse, pExpr);
pSelect->iLimit = 0;
testcase( pSelect->selFlags & SF_Distinct );
testcase( pKeyInfo==0 );
pCopy = sqlite3SelectDup(pParse->db, pSelect, 0);
rc = pParse->db->mallocFailed ? 1 :sqlite3Select(pParse, pCopy, &dest);
sqlite3SelectDelete(pParse->db, pCopy);
sqlite3DbFree(pParse->db, dest.zAffSdst);
if( rc ){
sqlite3KeyInfoUnref(pKeyInfo);
return;
}
assert( pKeyInfo!=0 );
assert( pEList!=0 );
assert( pEList->nExpr>0 );
assert( sqlite3KeyInfoIsWriteable(pKeyInfo) );
for(i=0; i<nVal; i++){
Expr *p = sqlite3VectorFieldSubexpr(pLeft, i);
pKeyInfo->aColl[i] = sqlite3BinaryCompareCollSeq(
pParse, p, pEList->a[i].pExpr
);
}
}
}else if( ALWAYS(pExpr->x.pList!=0) ){
char affinity;
int i;
ExprList *pList = pExpr->x.pList;
struct ExprList_item *pItem;
int r1, r2;
affinity = sqlite3ExprAffinity(pLeft);
if( affinity<=SQLITE_AFF_NONE ){
affinity = SQLITE_AFF_BLOB;
}else if( affinity==SQLITE_AFF_REAL ){
affinity = SQLITE_AFF_NUMERIC;
}
if( pKeyInfo ){
assert( sqlite3KeyInfoIsWriteable(pKeyInfo) );
pKeyInfo->aColl[0] = sqlite3ExprCollSeq(pParse, pExpr->pLeft);
}
r1 = sqlite3GetTempReg(pParse);
r2 = sqlite3GetTempReg(pParse);
for(i=pList->nExpr, pItem=pList->a; i>0; i--, pItem++){
Expr *pE2 = pItem->pExpr;
if( addrOnce && !sqlite3ExprIsConstant(pE2) ){
sqlite3VdbeChangeToNoop(v, addrOnce-1);
sqlite3VdbeChangeToNoop(v, addrOnce);
ExprClearProperty(pExpr, EP_Subrtn);
addrOnce = 0;
}
sqlite3ExprCode(pParse, pE2, r1);
sqlite3VdbeAddOp4(v, OP_MakeRecord, r1, 1, r2, &affinity, 1);
sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iTab, r2, r1, 1);
}
sqlite3ReleaseTempReg(pParse, r1);
sqlite3ReleaseTempReg(pParse, r2);
}
if( pKeyInfo ){
sqlite3VdbeChangeP4(v, addr, (void *)pKeyInfo, P4_KEYINFO);
}
if( addrOnce ){
sqlite3VdbeAddOp1(v, OP_NullRow, iTab);
sqlite3VdbeJumpHere(v, addrOnce);
assert( ExprUseYSub(pExpr) );
assert( sqlite3VdbeGetOp(v,pExpr->y.sub.iAddr-1)->opcode==OP_BeginSubrtn
|| pParse->nErr );
sqlite3VdbeAddOp3(v, OP_Return, pExpr->y.sub.regReturn,
pExpr->y.sub.iAddr, 1);
VdbeCoverage(v);
sqlite3ClearTempRegCache(pParse);
}
}
#endif
#ifndef SQLITE_OMIT_SUBQUERY
int sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){
int addrOnce = 0;
int rReg = 0;
Select *pSel;
SelectDest dest;
int nReg;
Expr *pLimit;
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
int addrExplain;
#endif
Vdbe *v = pParse->pVdbe;
assert( v!=0 );
if( pParse->nErr ) return 0;
testcase( pExpr->op==TK_EXISTS );
testcase( pExpr->op==TK_SELECT );
assert( pExpr->op==TK_EXISTS || pExpr->op==TK_SELECT );
assert( ExprUseXSelect(pExpr) );
pSel = pExpr->x.pSelect;
if( ExprHasProperty(pExpr, EP_Subrtn) ){
ExplainQueryPlan((pParse, 0, "REUSE SUBQUERY %d", pSel->selId));
assert( ExprUseYSub(pExpr) );
sqlite3VdbeAddOp2(v, OP_Gosub, pExpr->y.sub.regReturn,
pExpr->y.sub.iAddr);
return pExpr->iTable;
}
assert( !ExprUseYWin(pExpr) );
assert( !ExprHasProperty(pExpr, EP_Reduced|EP_TokenOnly) );
ExprSetProperty(pExpr, EP_Subrtn);
pExpr->y.sub.regReturn = ++pParse->nMem;
pExpr->y.sub.iAddr =
sqlite3VdbeAddOp2(v, OP_BeginSubrtn, 0, pExpr->y.sub.regReturn) + 1;
if( !ExprHasProperty(pExpr, EP_VarSelect) ){
addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
}
ExplainQueryPlan2(addrExplain, (pParse, 1, "%sSCALAR SUBQUERY %d",
addrOnce?"":"CORRELATED ", pSel->selId));
sqlite3VdbeScanStatusCounters(v, addrExplain, addrExplain, -1);
nReg = pExpr->op==TK_SELECT ? pSel->pEList->nExpr : 1;
sqlite3SelectDestInit(&dest, 0, pParse->nMem+1);
pParse->nMem += nReg;
if( pExpr->op==TK_SELECT ){
dest.eDest = SRT_Mem;
dest.iSdst = dest.iSDParm;
dest.nSdst = nReg;
sqlite3VdbeAddOp3(v, OP_Null, 0, dest.iSDParm, dest.iSDParm+nReg-1);
VdbeComment((v, "Init subquery result"));
}else{
dest.eDest = SRT_Exists;
sqlite3VdbeAddOp2(v, OP_Integer, 0, dest.iSDParm);
VdbeComment((v, "Init EXISTS result"));
}
if( pSel->pLimit ){
sqlite3 *db = pParse->db;
pLimit = sqlite3Expr(db, TK_INTEGER, "0");
if( pLimit ){
pLimit->affExpr = SQLITE_AFF_NUMERIC;
pLimit = sqlite3PExpr(pParse, TK_NE,
sqlite3ExprDup(db, pSel->pLimit->pLeft, 0), pLimit);
}
sqlite3ExprDeferredDelete(pParse, pSel->pLimit->pLeft);
pSel->pLimit->pLeft = pLimit;
}else{
pLimit = sqlite3Expr(pParse->db, TK_INTEGER, "1");
pSel->pLimit = sqlite3PExpr(pParse, TK_LIMIT, pLimit, 0);
}
pSel->iLimit = 0;
if( sqlite3Select(pParse, pSel, &dest) ){
pExpr->op2 = pExpr->op;
pExpr->op = TK_ERROR;
return 0;
}
pExpr->iTable = rReg = dest.iSDParm;
ExprSetVVAProperty(pExpr, EP_NoReduce);
if( addrOnce ){
sqlite3VdbeJumpHere(v, addrOnce);
}
sqlite3VdbeScanStatusRange(v, addrExplain, addrExplain, -1);
assert( ExprUseYSub(pExpr) );
assert( sqlite3VdbeGetOp(v,pExpr->y.sub.iAddr-1)->opcode==OP_BeginSubrtn
|| pParse->nErr );
sqlite3VdbeAddOp3(v, OP_Return, pExpr->y.sub.regReturn,
pExpr->y.sub.iAddr, 1);
VdbeCoverage(v);
sqlite3ClearTempRegCache(pParse);
return rReg;
}
#endif
#ifndef SQLITE_OMIT_SUBQUERY
int sqlite3ExprCheckIN(Parse *pParse, Expr *pIn){
int nVector = sqlite3ExprVectorSize(pIn->pLeft);
if( ExprUseXSelect(pIn) && !pParse->db->mallocFailed ){
if( nVector!=pIn->x.pSelect->pEList->nExpr ){
sqlite3SubselectError(pParse, pIn->x.pSelect->pEList->nExpr, nVector);
return 1;
}
}else if( nVector!=1 ){
sqlite3VectorErrorMsg(pParse, pIn->pLeft);
return 1;
}
return 0;
}
#endif
#ifndef SQLITE_OMIT_SUBQUERY
static void sqlite3ExprCodeIN(
Parse *pParse,
Expr *pExpr,
int destIfFalse,
int destIfNull
){
int rRhsHasNull = 0;
int eType;
int rLhs;
int rLhsOrig;
Vdbe *v;
int *aiMap = 0;
char *zAff = 0;
int nVector;
int iDummy;
Expr *pLeft;
int i;
int destStep2;
int destStep6 = 0;
int addrTruthOp;
int destNotNull;
int addrTop;
int iTab = 0;
u8 okConstFactor = pParse->okConstFactor;
assert( !ExprHasVVAProperty(pExpr,EP_Immutable) );
pLeft = pExpr->pLeft;
if( sqlite3ExprCheckIN(pParse, pExpr) ) return;
zAff = exprINAffinity(pParse, pExpr);
nVector = sqlite3ExprVectorSize(pExpr->pLeft);
aiMap = (int*)sqlite3DbMallocZero(
pParse->db, nVector*(sizeof(int) + sizeof(char)) + 1
);
if( pParse->db->mallocFailed ) goto sqlite3ExprCodeIN_oom_error;
v = pParse->pVdbe;
assert( v!=0 );
VdbeNoopComment((v, "begin IN expr"));
eType = sqlite3FindInIndex(pParse, pExpr,
IN_INDEX_MEMBERSHIP | IN_INDEX_NOOP_OK,
destIfFalse==destIfNull ? 0 : &rRhsHasNull,
aiMap, &iTab);
assert( pParse->nErr || nVector==1 || eType==IN_INDEX_EPH
|| eType==IN_INDEX_INDEX_ASC || eType==IN_INDEX_INDEX_DESC
);
#ifdef SQLITE_DEBUG
for(i=0; i<nVector; i++){
int j, cnt;
for(cnt=j=0; j<nVector; j++) if( aiMap[j]==i ) cnt++;
assert( cnt==1 );
}
#endif
assert( pParse->okConstFactor==okConstFactor );
pParse->okConstFactor = 0;
rLhsOrig = exprCodeVector(pParse, pLeft, &iDummy);
pParse->okConstFactor = okConstFactor;
for(i=0; i<nVector && aiMap[i]==i; i++){}
if( i==nVector ){
rLhs = rLhsOrig;
}else{
rLhs = sqlite3GetTempRange(pParse, nVector);
for(i=0; i<nVector; i++){
sqlite3VdbeAddOp3(v, OP_Copy, rLhsOrig+i, rLhs+aiMap[i], 0);
}
}
if( eType==IN_INDEX_NOOP ){
ExprList *pList;
CollSeq *pColl;
int labelOk = sqlite3VdbeMakeLabel(pParse);
int r2, regToFree;
int regCkNull = 0;
int ii;
assert( ExprUseXList(pExpr) );
pList = pExpr->x.pList;
pColl = sqlite3ExprCollSeq(pParse, pExpr->pLeft);
if( destIfNull!=destIfFalse ){
regCkNull = sqlite3GetTempReg(pParse);
sqlite3VdbeAddOp3(v, OP_BitAnd, rLhs, rLhs, regCkNull);
}
for(ii=0; ii<pList->nExpr; ii++){
r2 = sqlite3ExprCodeTemp(pParse, pList->a[ii].pExpr, ®ToFree);
if( regCkNull && sqlite3ExprCanBeNull(pList->a[ii].pExpr) ){
sqlite3VdbeAddOp3(v, OP_BitAnd, regCkNull, r2, regCkNull);
}
sqlite3ReleaseTempReg(pParse, regToFree);
if( ii<pList->nExpr-1 || destIfNull!=destIfFalse ){
int op = rLhs!=r2 ? OP_Eq : OP_NotNull;
sqlite3VdbeAddOp4(v, op, rLhs, labelOk, r2,
(void*)pColl, P4_COLLSEQ);
VdbeCoverageIf(v, ii<pList->nExpr-1 && op==OP_Eq);
VdbeCoverageIf(v, ii==pList->nExpr-1 && op==OP_Eq);
VdbeCoverageIf(v, ii<pList->nExpr-1 && op==OP_NotNull);
VdbeCoverageIf(v, ii==pList->nExpr-1 && op==OP_NotNull);
sqlite3VdbeChangeP5(v, zAff[0]);
}else{
int op = rLhs!=r2 ? OP_Ne : OP_IsNull;
assert( destIfNull==destIfFalse );
sqlite3VdbeAddOp4(v, op, rLhs, destIfFalse, r2,
(void*)pColl, P4_COLLSEQ);
VdbeCoverageIf(v, op==OP_Ne);
VdbeCoverageIf(v, op==OP_IsNull);
sqlite3VdbeChangeP5(v, zAff[0] | SQLITE_JUMPIFNULL);
}
}
if( regCkNull ){
sqlite3VdbeAddOp2(v, OP_IsNull, regCkNull, destIfNull); VdbeCoverage(v);
sqlite3VdbeGoto(v, destIfFalse);
}
sqlite3VdbeResolveLabel(v, labelOk);
sqlite3ReleaseTempReg(pParse, regCkNull);
goto sqlite3ExprCodeIN_finished;
}
if( destIfNull==destIfFalse ){
destStep2 = destIfFalse;
}else{
destStep2 = destStep6 = sqlite3VdbeMakeLabel(pParse);
}
for(i=0; i<nVector; i++){
Expr *p = sqlite3VectorFieldSubexpr(pExpr->pLeft, i);
if( pParse->nErr ) goto sqlite3ExprCodeIN_oom_error;
if( sqlite3ExprCanBeNull(p) ){
sqlite3VdbeAddOp2(v, OP_IsNull, rLhs+i, destStep2);
VdbeCoverage(v);
}
}
if( eType==IN_INDEX_ROWID ){
sqlite3VdbeAddOp3(v, OP_SeekRowid, iTab, destIfFalse, rLhs);
VdbeCoverage(v);
addrTruthOp = sqlite3VdbeAddOp0(v, OP_Goto);
}else{
sqlite3VdbeAddOp4(v, OP_Affinity, rLhs, nVector, 0, zAff, nVector);
if( destIfFalse==destIfNull ){
sqlite3VdbeAddOp4Int(v, OP_NotFound, iTab, destIfFalse,
rLhs, nVector); VdbeCoverage(v);
goto sqlite3ExprCodeIN_finished;
}
addrTruthOp = sqlite3VdbeAddOp4Int(v, OP_Found, iTab, 0,
rLhs, nVector); VdbeCoverage(v);
}
if( rRhsHasNull && nVector==1 ){
sqlite3VdbeAddOp2(v, OP_NotNull, rRhsHasNull, destIfFalse);
VdbeCoverage(v);
}
if( destIfFalse==destIfNull ) sqlite3VdbeGoto(v, destIfFalse);
if( destStep6 ) sqlite3VdbeResolveLabel(v, destStep6);
addrTop = sqlite3VdbeAddOp2(v, OP_Rewind, iTab, destIfFalse);
VdbeCoverage(v);
if( nVector>1 ){
destNotNull = sqlite3VdbeMakeLabel(pParse);
}else{
destNotNull = destIfFalse;
}
for(i=0; i<nVector; i++){
Expr *p;
CollSeq *pColl;
int r3 = sqlite3GetTempReg(pParse);
p = sqlite3VectorFieldSubexpr(pLeft, i);
pColl = sqlite3ExprCollSeq(pParse, p);
sqlite3VdbeAddOp3(v, OP_Column, iTab, i, r3);
sqlite3VdbeAddOp4(v, OP_Ne, rLhs+i, destNotNull, r3,
(void*)pColl, P4_COLLSEQ);
VdbeCoverage(v);
sqlite3ReleaseTempReg(pParse, r3);
}
sqlite3VdbeAddOp2(v, OP_Goto, 0, destIfNull);
if( nVector>1 ){
sqlite3VdbeResolveLabel(v, destNotNull);
sqlite3VdbeAddOp2(v, OP_Next, iTab, addrTop+1);
VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_Goto, 0, destIfFalse);
}
sqlite3VdbeJumpHere(v, addrTruthOp);
sqlite3ExprCodeIN_finished:
if( rLhs!=rLhsOrig ) sqlite3ReleaseTempReg(pParse, rLhs);
VdbeComment((v, "end IN expr"));
sqlite3ExprCodeIN_oom_error:
sqlite3DbFree(pParse->db, aiMap);
sqlite3DbFree(pParse->db, zAff);
}
#endif
#ifndef SQLITE_OMIT_FLOATING_POINT
static void codeReal(Vdbe *v, const char *z, int negateFlag, int iMem){
if( ALWAYS(z!=0) ){
double value;
sqlite3AtoF(z, &value, sqlite3Strlen30(z), SQLITE_UTF8);
assert( !sqlite3IsNaN(value) );
if( negateFlag ) value = -value;
sqlite3VdbeAddOp4Dup8(v, OP_Real, 0, iMem, 0, (u8*)&value, P4_REAL);
}
}
#endif
static void codeInteger(Parse *pParse, Expr *pExpr, int negFlag, int iMem){
Vdbe *v = pParse->pVdbe;
if( pExpr->flags & EP_IntValue ){
int i = pExpr->u.iValue;
assert( i>=0 );
if( negFlag ) i = -i;
sqlite3VdbeAddOp2(v, OP_Integer, i, iMem);
}else{
int c;
i64 value;
const char *z = pExpr->u.zToken;
assert( z!=0 );
c = sqlite3DecOrHexToI64(z, &value);
if( (c==3 && !negFlag) || (c==2) || (negFlag && value==SMALLEST_INT64)){
#ifdef SQLITE_OMIT_FLOATING_POINT
sqlite3ErrorMsg(pParse, "oversized integer: %s%#T", negFlag?"-":"",pExpr);
#else
#ifndef SQLITE_OMIT_HEX_INTEGER
if( sqlite3_strnicmp(z,"0x",2)==0 ){
sqlite3ErrorMsg(pParse, "hex literal too big: %s%#T",
negFlag?"-":"",pExpr);
}else
#endif
{
codeReal(v, z, negFlag, iMem);
}
#endif
}else{
if( negFlag ){ value = c==3 ? SMALLEST_INT64 : -value; }
sqlite3VdbeAddOp4Dup8(v, OP_Int64, 0, iMem, 0, (u8*)&value, P4_INT64);
}
}
}
void sqlite3ExprCodeLoadIndexColumn(
Parse *pParse,
Index *pIdx,
int iTabCur,
int iIdxCol,
int regOut
){
i16 iTabCol = pIdx->aiColumn[iIdxCol];
if( iTabCol==XN_EXPR ){
assert( pIdx->aColExpr );
assert( pIdx->aColExpr->nExpr>iIdxCol );
pParse->iSelfTab = iTabCur + 1;
sqlite3ExprCodeCopy(pParse, pIdx->aColExpr->a[iIdxCol].pExpr, regOut);
pParse->iSelfTab = 0;
}else{
sqlite3ExprCodeGetColumnOfTable(pParse->pVdbe, pIdx->pTable, iTabCur,
iTabCol, regOut);
}
}
#ifndef SQLITE_OMIT_GENERATED_COLUMNS
void sqlite3ExprCodeGeneratedColumn(
Parse *pParse,
Table *pTab,
Column *pCol,
int regOut
){
int iAddr;
Vdbe *v = pParse->pVdbe;
int nErr = pParse->nErr;
assert( v!=0 );
assert( pParse->iSelfTab!=0 );
if( pParse->iSelfTab>0 ){
iAddr = sqlite3VdbeAddOp3(v, OP_IfNullRow, pParse->iSelfTab-1, 0, regOut);
}else{
iAddr = 0;
}
sqlite3ExprCodeCopy(pParse, sqlite3ColumnExpr(pTab,pCol), regOut);
if( pCol->affinity>=SQLITE_AFF_TEXT ){
sqlite3VdbeAddOp4(v, OP_Affinity, regOut, 1, 0, &pCol->affinity, 1);
}
if( iAddr ) sqlite3VdbeJumpHere(v, iAddr);
if( pParse->nErr>nErr ) pParse->db->errByteOffset = -1;
}
#endif
void sqlite3ExprCodeGetColumnOfTable(
Vdbe *v,
Table *pTab,
int iTabCur,
int iCol,
int regOut
){
Column *pCol;
assert( v!=0 );
assert( pTab!=0 );
assert( iCol!=XN_EXPR );
if( iCol<0 || iCol==pTab->iPKey ){
sqlite3VdbeAddOp2(v, OP_Rowid, iTabCur, regOut);
VdbeComment((v, "%s.rowid", pTab->zName));
}else{
int op;
int x;
if( IsVirtual(pTab) ){
op = OP_VColumn;
x = iCol;
#ifndef SQLITE_OMIT_GENERATED_COLUMNS
}else if( (pCol = &pTab->aCol[iCol])->colFlags & COLFLAG_VIRTUAL ){
Parse *pParse = sqlite3VdbeParser(v);
if( pCol->colFlags & COLFLAG_BUSY ){
sqlite3ErrorMsg(pParse, "generated column loop on \"%s\"",
pCol->zCnName);
}else{
int savedSelfTab = pParse->iSelfTab;
pCol->colFlags |= COLFLAG_BUSY;
pParse->iSelfTab = iTabCur+1;
sqlite3ExprCodeGeneratedColumn(pParse, pTab, pCol, regOut);
pParse->iSelfTab = savedSelfTab;
pCol->colFlags &= ~COLFLAG_BUSY;
}
return;
#endif
}else if( !HasRowid(pTab) ){
testcase( iCol!=sqlite3TableColumnToStorage(pTab, iCol) );
x = sqlite3TableColumnToIndex(sqlite3PrimaryKeyIndex(pTab), iCol);
op = OP_Column;
}else{
x = sqlite3TableColumnToStorage(pTab,iCol);
testcase( x!=iCol );
op = OP_Column;
}
sqlite3VdbeAddOp3(v, op, iTabCur, x, regOut);
sqlite3ColumnDefault(v, pTab, iCol, regOut);
}
}
int sqlite3ExprCodeGetColumn(
Parse *pParse,
Table *pTab,
int iColumn,
int iTable,
int iReg,
u8 p5
){
assert( pParse->pVdbe!=0 );
sqlite3ExprCodeGetColumnOfTable(pParse->pVdbe, pTab, iTable, iColumn, iReg);
if( p5 ){
VdbeOp *pOp = sqlite3VdbeGetLastOp(pParse->pVdbe);
if( pOp->opcode==OP_Column ) pOp->p5 = p5;
}
return iReg;
}
void sqlite3ExprCodeMove(Parse *pParse, int iFrom, int iTo, int nReg){
sqlite3VdbeAddOp3(pParse->pVdbe, OP_Move, iFrom, iTo, nReg);
}
static void exprToRegister(Expr *pExpr, int iReg){
Expr *p = sqlite3ExprSkipCollateAndLikely(pExpr);
if( NEVER(p==0) ) return;
p->op2 = p->op;
p->op = TK_REGISTER;
p->iTable = iReg;
ExprClearProperty(p, EP_Skip);
}
static int exprCodeVector(Parse *pParse, Expr *p, int *piFreeable){
int iResult;
int nResult = sqlite3ExprVectorSize(p);
if( nResult==1 ){
iResult = sqlite3ExprCodeTemp(pParse, p, piFreeable);
}else{
*piFreeable = 0;
if( p->op==TK_SELECT ){
#if SQLITE_OMIT_SUBQUERY
iResult = 0;
#else
iResult = sqlite3CodeSubselect(pParse, p);
#endif
}else{
int i;
iResult = pParse->nMem+1;
pParse->nMem += nResult;
assert( ExprUseXList(p) );
for(i=0; i<nResult; i++){
sqlite3ExprCodeFactorable(pParse, p->x.pList->a[i].pExpr, i+iResult);
}
}
}
return iResult;
}
static void setDoNotMergeFlagOnCopy(Vdbe *v){
if( sqlite3VdbeGetLastOp(v)->opcode==OP_Copy ){
sqlite3VdbeChangeP5(v, 1);
}
}
static int exprCodeInlineFunction(
Parse *pParse,
ExprList *pFarg,
int iFuncId,
int target
){
int nFarg;
Vdbe *v = pParse->pVdbe;
assert( v!=0 );
assert( pFarg!=0 );
nFarg = pFarg->nExpr;
assert( nFarg>0 );
switch( iFuncId ){
case INLINEFUNC_coalesce: {
int endCoalesce = sqlite3VdbeMakeLabel(pParse);
int i;
assert( nFarg>=2 );
sqlite3ExprCode(pParse, pFarg->a[0].pExpr, target);
for(i=1; i<nFarg; i++){
sqlite3VdbeAddOp2(v, OP_NotNull, target, endCoalesce);
VdbeCoverage(v);
sqlite3ExprCode(pParse, pFarg->a[i].pExpr, target);
}
setDoNotMergeFlagOnCopy(v);
sqlite3VdbeResolveLabel(v, endCoalesce);
break;
}
case INLINEFUNC_iif: {
Expr caseExpr;
memset(&caseExpr, 0, sizeof(caseExpr));
caseExpr.op = TK_CASE;
caseExpr.x.pList = pFarg;
return sqlite3ExprCodeTarget(pParse, &caseExpr, target);
}
#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
case INLINEFUNC_sqlite_offset: {
Expr *pArg = pFarg->a[0].pExpr;
if( pArg->op==TK_COLUMN && pArg->iTable>=0 ){
sqlite3VdbeAddOp3(v, OP_Offset, pArg->iTable, pArg->iColumn, target);
}else{
sqlite3VdbeAddOp2(v, OP_Null, 0, target);
}
break;
}
#endif
default: {
assert( nFarg==1 || nFarg==2 );
target = sqlite3ExprCodeTarget(pParse, pFarg->a[0].pExpr, target);
break;
}
#if !defined(SQLITE_UNTESTABLE)
case INLINEFUNC_expr_compare: {
assert( nFarg==2 );
sqlite3VdbeAddOp2(v, OP_Integer,
sqlite3ExprCompare(0,pFarg->a[0].pExpr, pFarg->a[1].pExpr,-1),
target);
break;
}
case INLINEFUNC_expr_implies_expr: {
assert( nFarg==2 );
sqlite3VdbeAddOp2(v, OP_Integer,
sqlite3ExprImpliesExpr(pParse,pFarg->a[0].pExpr, pFarg->a[1].pExpr,-1),
target);
break;
}
case INLINEFUNC_implies_nonnull_row: {
Expr *pA1;
assert( nFarg==2 );
pA1 = pFarg->a[1].pExpr;
if( pA1->op==TK_COLUMN ){
sqlite3VdbeAddOp2(v, OP_Integer,
sqlite3ExprImpliesNonNullRow(pFarg->a[0].pExpr,pA1->iTable,1),
target);
}else{
sqlite3VdbeAddOp2(v, OP_Null, 0, target);
}
break;
}
case INLINEFUNC_affinity: {
const char *azAff[] = { "blob", "text", "numeric", "integer",
"real", "flexnum" };
char aff;
assert( nFarg==1 );
aff = sqlite3ExprAffinity(pFarg->a[0].pExpr);
assert( aff<=SQLITE_AFF_NONE
|| (aff>=SQLITE_AFF_BLOB && aff<=SQLITE_AFF_FLEXNUM) );
sqlite3VdbeLoadString(v, target,
(aff<=SQLITE_AFF_NONE) ? "none" : azAff[aff-SQLITE_AFF_BLOB]);
break;
}
#endif
}
return target;
}
static SQLITE_NOINLINE int sqlite3IndexedExprLookup(
Parse *pParse,
Expr *pExpr,
int target
){
IndexedExpr *p;
Vdbe *v;
for(p=pParse->pIdxEpr; p; p=p->pIENext){
u8 exprAff;
int iDataCur = p->iDataCur;
if( iDataCur<0 ) continue;
if( pParse->iSelfTab ){
if( p->iDataCur!=pParse->iSelfTab-1 ) continue;
iDataCur = -1;
}
if( sqlite3ExprCompare(0, pExpr, p->pExpr, iDataCur)!=0 ) continue;
assert( p->aff>=SQLITE_AFF_BLOB && p->aff<=SQLITE_AFF_NUMERIC );
exprAff = sqlite3ExprAffinity(pExpr);
if( (exprAff<=SQLITE_AFF_BLOB && p->aff!=SQLITE_AFF_BLOB)
|| (exprAff==SQLITE_AFF_TEXT && p->aff!=SQLITE_AFF_TEXT)
|| (exprAff>=SQLITE_AFF_NUMERIC && p->aff!=SQLITE_AFF_NUMERIC)
){
continue;
}
v = pParse->pVdbe;
assert( v!=0 );
if( p->bMaybeNullRow ){
int addr = sqlite3VdbeCurrentAddr(v);
sqlite3VdbeAddOp3(v, OP_IfNullRow, p->iIdxCur, addr+3, target);
VdbeCoverage(v);
sqlite3VdbeAddOp3(v, OP_Column, p->iIdxCur, p->iIdxCol, target);
VdbeComment((v, "%s expr-column %d", p->zIdxName, p->iIdxCol));
sqlite3VdbeGoto(v, 0);
p = pParse->pIdxEpr;
pParse->pIdxEpr = 0;
sqlite3ExprCode(pParse, pExpr, target);
pParse->pIdxEpr = p;
sqlite3VdbeJumpHere(v, addr+2);
}else{
sqlite3VdbeAddOp3(v, OP_Column, p->iIdxCur, p->iIdxCol, target);
VdbeComment((v, "%s expr-column %d", p->zIdxName, p->iIdxCol));
}
return target;
}
return -1;
}
int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
Vdbe *v = pParse->pVdbe;
int op;
int inReg = target;
int regFree1 = 0;
int regFree2 = 0;
int r1, r2;
Expr tempX;
int p5 = 0;
assert( target>0 && target<=pParse->nMem );
assert( v!=0 );
expr_code_doover:
if( pExpr==0 ){
op = TK_NULL;
}else if( pParse->pIdxEpr!=0
&& !ExprHasProperty(pExpr, EP_Leaf)
&& (r1 = sqlite3IndexedExprLookup(pParse, pExpr, target))>=0
){
return r1;
}else{
assert( !ExprHasVVAProperty(pExpr,EP_Immutable) );
op = pExpr->op;
}
switch( op ){
case TK_AGG_COLUMN: {
AggInfo *pAggInfo = pExpr->pAggInfo;
struct AggInfo_col *pCol;
assert( pAggInfo!=0 );
assert( pExpr->iAgg>=0 );
if( pExpr->iAgg>=pAggInfo->nColumn ){
sqlite3VdbeAddOp2(v, OP_Null, 0, target);
#ifdef SQLITE_VDBE_COVERAGE
sqlite3VdbeAddOp2(v, OP_NotNull, target, 1);
VdbeCoverageNeverTaken(v);
#endif
break;
}
pCol = &pAggInfo->aCol[pExpr->iAgg];
if( !pAggInfo->directMode ){
return AggInfoColumnReg(pAggInfo, pExpr->iAgg);
}else if( pAggInfo->useSortingIdx ){
Table *pTab = pCol->pTab;
sqlite3VdbeAddOp3(v, OP_Column, pAggInfo->sortingIdxPTab,
pCol->iSorterColumn, target);
if( pTab==0 ){
}else if( pCol->iColumn<0 ){
VdbeComment((v,"%s.rowid",pTab->zName));
}else{
VdbeComment((v,"%s.%s",
pTab->zName, pTab->aCol[pCol->iColumn].zCnName));
if( pTab->aCol[pCol->iColumn].affinity==SQLITE_AFF_REAL ){
sqlite3VdbeAddOp1(v, OP_RealAffinity, target);
}
}
return target;
}else if( pExpr->y.pTab==0 ){
sqlite3VdbeAddOp3(v, OP_Column, pExpr->iTable, pExpr->iColumn, target);
return target;
}
deliberate_fall_through
}
case TK_COLUMN: {
int iTab = pExpr->iTable;
int iReg;
if( ExprHasProperty(pExpr, EP_FixedCol) ){
int aff;
iReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft,target);
assert( ExprUseYTab(pExpr) );
assert( pExpr->y.pTab!=0 );
aff = sqlite3TableColumnAffinity(pExpr->y.pTab, pExpr->iColumn);
if( aff>SQLITE_AFF_BLOB ){
static const char zAff[] = "B\000C\000D\000E\000F";
assert( SQLITE_AFF_BLOB=='A' );
assert( SQLITE_AFF_TEXT=='B' );
sqlite3VdbeAddOp4(v, OP_Affinity, iReg, 1, 0,
&zAff[(aff-'B')*2], P4_STATIC);
}
return iReg;
}
if( iTab<0 ){
if( pParse->iSelfTab<0 ){
Column *pCol;
Table *pTab;
int iSrc;
int iCol = pExpr->iColumn;
assert( ExprUseYTab(pExpr) );
pTab = pExpr->y.pTab;
assert( pTab!=0 );
assert( iCol>=XN_ROWID );
assert( iCol<pTab->nCol );
if( iCol<0 ){
return -1-pParse->iSelfTab;
}
pCol = pTab->aCol + iCol;
testcase( iCol!=sqlite3TableColumnToStorage(pTab,iCol) );
iSrc = sqlite3TableColumnToStorage(pTab, iCol) - pParse->iSelfTab;
#ifndef SQLITE_OMIT_GENERATED_COLUMNS
if( pCol->colFlags & COLFLAG_GENERATED ){
if( pCol->colFlags & COLFLAG_BUSY ){
sqlite3ErrorMsg(pParse, "generated column loop on \"%s\"",
pCol->zCnName);
return 0;
}
pCol->colFlags |= COLFLAG_BUSY;
if( pCol->colFlags & COLFLAG_NOTAVAIL ){
sqlite3ExprCodeGeneratedColumn(pParse, pTab, pCol, iSrc);
}
pCol->colFlags &= ~(COLFLAG_BUSY|COLFLAG_NOTAVAIL);
return iSrc;
}else
#endif
if( pCol->affinity==SQLITE_AFF_REAL ){
sqlite3VdbeAddOp2(v, OP_SCopy, iSrc, target);
sqlite3VdbeAddOp1(v, OP_RealAffinity, target);
return target;
}else{
return iSrc;
}
}else{
iTab = pParse->iSelfTab - 1;
}
}
assert( ExprUseYTab(pExpr) );
assert( pExpr->y.pTab!=0 );
iReg = sqlite3ExprCodeGetColumn(pParse, pExpr->y.pTab,
pExpr->iColumn, iTab, target,
pExpr->op2);
return iReg;
}
case TK_INTEGER: {
codeInteger(pParse, pExpr, 0, target);
return target;
}
case TK_TRUEFALSE: {
sqlite3VdbeAddOp2(v, OP_Integer, sqlite3ExprTruthValue(pExpr), target);
return target;
}
#ifndef SQLITE_OMIT_FLOATING_POINT
case TK_FLOAT: {
assert( !ExprHasProperty(pExpr, EP_IntValue) );
codeReal(v, pExpr->u.zToken, 0, target);
return target;
}
#endif
case TK_STRING: {
assert( !ExprHasProperty(pExpr, EP_IntValue) );
sqlite3VdbeLoadString(v, target, pExpr->u.zToken);
return target;
}
default: {
assert( op==TK_NULL || op==TK_ERROR || pParse->db->mallocFailed );
sqlite3VdbeAddOp2(v, OP_Null, 0, target);
return target;
}
#ifndef SQLITE_OMIT_BLOB_LITERAL
case TK_BLOB: {
int n;
const char *z;
char *zBlob;
assert( !ExprHasProperty(pExpr, EP_IntValue) );
assert( pExpr->u.zToken[0]=='x' || pExpr->u.zToken[0]=='X' );
assert( pExpr->u.zToken[1]=='\'' );
z = &pExpr->u.zToken[2];
n = sqlite3Strlen30(z) - 1;
assert( z[n]=='\'' );
zBlob = sqlite3HexToBlob(sqlite3VdbeDb(v), z, n);
sqlite3VdbeAddOp4(v, OP_Blob, n/2, target, 0, zBlob, P4_DYNAMIC);
return target;
}
#endif
case TK_VARIABLE: {
assert( !ExprHasProperty(pExpr, EP_IntValue) );
assert( pExpr->u.zToken!=0 );
assert( pExpr->u.zToken[0]!=0 );
sqlite3VdbeAddOp2(v, OP_Variable, pExpr->iColumn, target);
if( pExpr->u.zToken[1]!=0 ){
const char *z = sqlite3VListNumToName(pParse->pVList, pExpr->iColumn);
assert( pExpr->u.zToken[0]=='?' || (z && !strcmp(pExpr->u.zToken, z)) );
pParse->pVList[0] = 0;
sqlite3VdbeAppendP4(v, (char*)z, P4_STATIC);
}
return target;
}
case TK_REGISTER: {
return pExpr->iTable;
}
#ifndef SQLITE_OMIT_CAST
case TK_CAST: {
sqlite3ExprCode(pParse, pExpr->pLeft, target);
assert( inReg==target );
assert( !ExprHasProperty(pExpr, EP_IntValue) );
sqlite3VdbeAddOp2(v, OP_Cast, target,
sqlite3AffinityType(pExpr->u.zToken, 0));
return inReg;
}
#endif
case TK_IS:
case TK_ISNOT:
op = (op==TK_IS) ? TK_EQ : TK_NE;
p5 = SQLITE_NULLEQ;
case TK_LT:
case TK_LE:
case TK_GT:
case TK_GE:
case TK_NE:
case TK_EQ: {
Expr *pLeft = pExpr->pLeft;
if( sqlite3ExprIsVector(pLeft) ){
codeVectorCompare(pParse, pExpr, target, op, p5);
}else{
r1 = sqlite3ExprCodeTemp(pParse, pLeft, ®Free1);
r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2);
sqlite3VdbeAddOp2(v, OP_Integer, 1, inReg);
codeCompare(pParse, pLeft, pExpr->pRight, op, r1, r2,
sqlite3VdbeCurrentAddr(v)+2, p5,
ExprHasProperty(pExpr,EP_Commuted));
assert(TK_LT==OP_Lt); testcase(op==OP_Lt); VdbeCoverageIf(v,op==OP_Lt);
assert(TK_LE==OP_Le); testcase(op==OP_Le); VdbeCoverageIf(v,op==OP_Le);
assert(TK_GT==OP_Gt); testcase(op==OP_Gt); VdbeCoverageIf(v,op==OP_Gt);
assert(TK_GE==OP_Ge); testcase(op==OP_Ge); VdbeCoverageIf(v,op==OP_Ge);
assert(TK_EQ==OP_Eq); testcase(op==OP_Eq); VdbeCoverageIf(v,op==OP_Eq);
assert(TK_NE==OP_Ne); testcase(op==OP_Ne); VdbeCoverageIf(v,op==OP_Ne);
if( p5==SQLITE_NULLEQ ){
sqlite3VdbeAddOp2(v, OP_Integer, 0, inReg);
}else{
sqlite3VdbeAddOp3(v, OP_ZeroOrNull, r1, inReg, r2);
}
testcase( regFree1==0 );
testcase( regFree2==0 );
}
break;
}
case TK_AND:
case TK_OR:
case TK_PLUS:
case TK_STAR:
case TK_MINUS:
case TK_REM:
case TK_BITAND:
case TK_BITOR:
case TK_SLASH:
case TK_LSHIFT:
case TK_RSHIFT:
case TK_CONCAT: {
assert( TK_AND==OP_And ); testcase( op==TK_AND );
assert( TK_OR==OP_Or ); testcase( op==TK_OR );
assert( TK_PLUS==OP_Add ); testcase( op==TK_PLUS );
assert( TK_MINUS==OP_Subtract ); testcase( op==TK_MINUS );
assert( TK_REM==OP_Remainder ); testcase( op==TK_REM );
assert( TK_BITAND==OP_BitAnd ); testcase( op==TK_BITAND );
assert( TK_BITOR==OP_BitOr ); testcase( op==TK_BITOR );
assert( TK_SLASH==OP_Divide ); testcase( op==TK_SLASH );
assert( TK_LSHIFT==OP_ShiftLeft ); testcase( op==TK_LSHIFT );
assert( TK_RSHIFT==OP_ShiftRight ); testcase( op==TK_RSHIFT );
assert( TK_CONCAT==OP_Concat ); testcase( op==TK_CONCAT );
r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1);
r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2);
sqlite3VdbeAddOp3(v, op, r2, r1, target);
testcase( regFree1==0 );
testcase( regFree2==0 );
break;
}
case TK_UMINUS: {
Expr *pLeft = pExpr->pLeft;
assert( pLeft );
if( pLeft->op==TK_INTEGER ){
codeInteger(pParse, pLeft, 1, target);
return target;
#ifndef SQLITE_OMIT_FLOATING_POINT
}else if( pLeft->op==TK_FLOAT ){
assert( !ExprHasProperty(pExpr, EP_IntValue) );
codeReal(v, pLeft->u.zToken, 1, target);
return target;
#endif
}else{
tempX.op = TK_INTEGER;
tempX.flags = EP_IntValue|EP_TokenOnly;
tempX.u.iValue = 0;
ExprClearVVAProperties(&tempX);
r1 = sqlite3ExprCodeTemp(pParse, &tempX, ®Free1);
r2 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free2);
sqlite3VdbeAddOp3(v, OP_Subtract, r2, r1, target);
testcase( regFree2==0 );
}
break;
}
case TK_BITNOT:
case TK_NOT: {
assert( TK_BITNOT==OP_BitNot ); testcase( op==TK_BITNOT );
assert( TK_NOT==OP_Not ); testcase( op==TK_NOT );
r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1);
testcase( regFree1==0 );
sqlite3VdbeAddOp2(v, op, r1, inReg);
break;
}
case TK_TRUTH: {
int isTrue;
int bNormal;
r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1);
testcase( regFree1==0 );
isTrue = sqlite3ExprTruthValue(pExpr->pRight);
bNormal = pExpr->op2==TK_IS;
testcase( isTrue && bNormal);
testcase( !isTrue && bNormal);
sqlite3VdbeAddOp4Int(v, OP_IsTrue, r1, inReg, !isTrue, isTrue ^ bNormal);
break;
}
case TK_ISNULL:
case TK_NOTNULL: {
int addr;
assert( TK_ISNULL==OP_IsNull ); testcase( op==TK_ISNULL );
assert( TK_NOTNULL==OP_NotNull ); testcase( op==TK_NOTNULL );
sqlite3VdbeAddOp2(v, OP_Integer, 1, target);
r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1);
testcase( regFree1==0 );
addr = sqlite3VdbeAddOp1(v, op, r1);
VdbeCoverageIf(v, op==TK_ISNULL);
VdbeCoverageIf(v, op==TK_NOTNULL);
sqlite3VdbeAddOp2(v, OP_Integer, 0, target);
sqlite3VdbeJumpHere(v, addr);
break;
}
case TK_AGG_FUNCTION: {
AggInfo *pInfo = pExpr->pAggInfo;
if( pInfo==0
|| NEVER(pExpr->iAgg<0)
|| NEVER(pExpr->iAgg>=pInfo->nFunc)
){
assert( !ExprHasProperty(pExpr, EP_IntValue) );
sqlite3ErrorMsg(pParse, "misuse of aggregate: %#T()", pExpr);
}else{
return AggInfoFuncReg(pInfo, pExpr->iAgg);
}
break;
}
case TK_FUNCTION: {
ExprList *pFarg;
int nFarg;
FuncDef *pDef;
const char *zId;
u32 constMask = 0;
int i;
sqlite3 *db = pParse->db;
u8 enc = ENC(db);
CollSeq *pColl = 0;
#ifndef SQLITE_OMIT_WINDOWFUNC
if( ExprHasProperty(pExpr, EP_WinFunc) ){
return pExpr->y.pWin->regResult;
}
#endif
if( ConstFactorOk(pParse) && sqlite3ExprIsConstantNotJoin(pExpr) ){
return sqlite3ExprCodeRunJustOnce(pParse, pExpr, -1);
}
assert( !ExprHasProperty(pExpr, EP_TokenOnly) );
assert( ExprUseXList(pExpr) );
pFarg = pExpr->x.pList;
nFarg = pFarg ? pFarg->nExpr : 0;
assert( !ExprHasProperty(pExpr, EP_IntValue) );
zId = pExpr->u.zToken;
pDef = sqlite3FindFunction(db, zId, nFarg, enc, 0);
#ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
if( pDef==0 && pParse->explain ){
pDef = sqlite3FindFunction(db, "unknown", nFarg, enc, 0);
}
#endif
if( pDef==0 || pDef->xFinalize!=0 ){
sqlite3ErrorMsg(pParse, "unknown function: %#T()", pExpr);
break;
}
if( pDef->funcFlags & SQLITE_FUNC_INLINE ){
assert( (pDef->funcFlags & SQLITE_FUNC_UNSAFE)==0 );
assert( (pDef->funcFlags & SQLITE_FUNC_DIRECT)==0 );
return exprCodeInlineFunction(pParse, pFarg,
SQLITE_PTR_TO_INT(pDef->pUserData), target);
}else if( pDef->funcFlags & (SQLITE_FUNC_DIRECT|SQLITE_FUNC_UNSAFE) ){
sqlite3ExprFunctionUsable(pParse, pExpr, pDef);
}
for(i=0; i<nFarg; i++){
if( i<32 && sqlite3ExprIsConstant(pFarg->a[i].pExpr) ){
testcase( i==31 );
constMask |= MASKBIT32(i);
}
if( (pDef->funcFlags & SQLITE_FUNC_NEEDCOLL)!=0 && !pColl ){
pColl = sqlite3ExprCollSeq(pParse, pFarg->a[i].pExpr);
}
}
if( pFarg ){
if( constMask ){
r1 = pParse->nMem+1;
pParse->nMem += nFarg;
}else{
r1 = sqlite3GetTempRange(pParse, nFarg);
}
if( (pDef->funcFlags & (SQLITE_FUNC_LENGTH|SQLITE_FUNC_TYPEOF))!=0 ){
u8 exprOp;
assert( nFarg==1 );
assert( pFarg->a[0].pExpr!=0 );
exprOp = pFarg->a[0].pExpr->op;
if( exprOp==TK_COLUMN || exprOp==TK_AGG_COLUMN ){
assert( SQLITE_FUNC_LENGTH==OPFLAG_LENGTHARG );
assert( SQLITE_FUNC_TYPEOF==OPFLAG_TYPEOFARG );
testcase( pDef->funcFlags & OPFLAG_LENGTHARG );
pFarg->a[0].pExpr->op2 =
pDef->funcFlags & (OPFLAG_LENGTHARG|OPFLAG_TYPEOFARG);
}
}
sqlite3ExprCodeExprList(pParse, pFarg, r1, 0,
SQLITE_ECEL_DUP|SQLITE_ECEL_FACTOR);
}else{
r1 = 0;
}
#ifndef SQLITE_OMIT_VIRTUALTABLE
if( nFarg>=2 && ExprHasProperty(pExpr, EP_InfixFunc) ){
pDef = sqlite3VtabOverloadFunction(db, pDef, nFarg, pFarg->a[1].pExpr);
}else if( nFarg>0 ){
pDef = sqlite3VtabOverloadFunction(db, pDef, nFarg, pFarg->a[0].pExpr);
}
#endif
if( pDef->funcFlags & SQLITE_FUNC_NEEDCOLL ){
if( !pColl ) pColl = db->pDfltColl;
sqlite3VdbeAddOp4(v, OP_CollSeq, 0, 0, 0, (char *)pColl, P4_COLLSEQ);
}
sqlite3VdbeAddFunctionCall(pParse, constMask, r1, target, nFarg,
pDef, pExpr->op2);
if( nFarg ){
if( constMask==0 ){
sqlite3ReleaseTempRange(pParse, r1, nFarg);
}else{
sqlite3VdbeReleaseRegisters(pParse, r1, nFarg, constMask, 1);
}
}
return target;
}
#ifndef SQLITE_OMIT_SUBQUERY
case TK_EXISTS:
case TK_SELECT: {
int nCol;
testcase( op==TK_EXISTS );
testcase( op==TK_SELECT );
if( pParse->db->mallocFailed ){
return 0;
}else if( op==TK_SELECT
&& ALWAYS( ExprUseXSelect(pExpr) )
&& (nCol = pExpr->x.pSelect->pEList->nExpr)!=1
){
sqlite3SubselectError(pParse, nCol, 1);
}else{
return sqlite3CodeSubselect(pParse, pExpr);
}
break;
}
case TK_SELECT_COLUMN: {
int n;
Expr *pLeft = pExpr->pLeft;
if( pLeft->iTable==0 || pParse->withinRJSubrtn > pLeft->op2 ){
pLeft->iTable = sqlite3CodeSubselect(pParse, pLeft);
pLeft->op2 = pParse->withinRJSubrtn;
}
assert( pLeft->op==TK_SELECT || pLeft->op==TK_ERROR );
n = sqlite3ExprVectorSize(pLeft);
if( pExpr->iTable!=n ){
sqlite3ErrorMsg(pParse, "%d columns assigned %d values",
pExpr->iTable, n);
}
return pLeft->iTable + pExpr->iColumn;
}
case TK_IN: {
int destIfFalse = sqlite3VdbeMakeLabel(pParse);
int destIfNull = sqlite3VdbeMakeLabel(pParse);
sqlite3VdbeAddOp2(v, OP_Null, 0, target);
sqlite3ExprCodeIN(pParse, pExpr, destIfFalse, destIfNull);
sqlite3VdbeAddOp2(v, OP_Integer, 1, target);
sqlite3VdbeResolveLabel(v, destIfFalse);
sqlite3VdbeAddOp2(v, OP_AddImm, target, 0);
sqlite3VdbeResolveLabel(v, destIfNull);
return target;
}
#endif
case TK_BETWEEN: {
exprCodeBetween(pParse, pExpr, target, 0, 0);
return target;
}
case TK_COLLATE: {
if( !ExprHasProperty(pExpr, EP_Collate) ){
assert( pExpr->pLeft );
sqlite3ExprCode(pParse, pExpr->pLeft, target);
sqlite3VdbeAddOp1(v, OP_ClrSubtype, target);
return target;
}else{
pExpr = pExpr->pLeft;
goto expr_code_doover;
}
}
case TK_SPAN:
case TK_UPLUS: {
pExpr = pExpr->pLeft;
goto expr_code_doover;
}
case TK_TRIGGER: {
Table *pTab;
int iCol;
int p1;
assert( ExprUseYTab(pExpr) );
pTab = pExpr->y.pTab;
iCol = pExpr->iColumn;
p1 = pExpr->iTable * (pTab->nCol+1) + 1
+ sqlite3TableColumnToStorage(pTab, iCol);
assert( pExpr->iTable==0 || pExpr->iTable==1 );
assert( iCol>=-1 && iCol<pTab->nCol );
assert( pTab->iPKey<0 || iCol!=pTab->iPKey );
assert( p1>=0 && p1<(pTab->nCol*2+2) );
sqlite3VdbeAddOp2(v, OP_Param, p1, target);
VdbeComment((v, "r[%d]=%s.%s", target,
(pExpr->iTable ? "new" : "old"),
(pExpr->iColumn<0 ? "rowid" : pExpr->y.pTab->aCol[iCol].zCnName)
));
#ifndef SQLITE_OMIT_FLOATING_POINT
if( iCol>=0 && pTab->aCol[iCol].affinity==SQLITE_AFF_REAL ){
sqlite3VdbeAddOp1(v, OP_RealAffinity, target);
}
#endif
break;
}
case TK_VECTOR: {
sqlite3ErrorMsg(pParse, "row value misused");
break;
}
case TK_IF_NULL_ROW: {
int addrINR;
u8 okConstFactor = pParse->okConstFactor;
AggInfo *pAggInfo = pExpr->pAggInfo;
if( pAggInfo ){
assert( pExpr->iAgg>=0 && pExpr->iAgg<pAggInfo->nColumn );
if( !pAggInfo->directMode ){
inReg = AggInfoColumnReg(pAggInfo, pExpr->iAgg);
break;
}
if( pExpr->pAggInfo->useSortingIdx ){
sqlite3VdbeAddOp3(v, OP_Column, pAggInfo->sortingIdxPTab,
pAggInfo->aCol[pExpr->iAgg].iSorterColumn,
target);
inReg = target;
break;
}
}
addrINR = sqlite3VdbeAddOp3(v, OP_IfNullRow, pExpr->iTable, 0, target);
pParse->okConstFactor = 0;
sqlite3ExprCode(pParse, pExpr->pLeft, target);
assert( target==inReg );
pParse->okConstFactor = okConstFactor;
sqlite3VdbeJumpHere(v, addrINR);
break;
}
case TK_CASE: {
int endLabel;
int nextCase;
int nExpr;
int i;
ExprList *pEList;
struct ExprList_item *aListelem;
Expr opCompare;
Expr *pX;
Expr *pTest = 0;
Expr *pDel = 0;
sqlite3 *db = pParse->db;
assert( ExprUseXList(pExpr) && pExpr->x.pList!=0 );
assert(pExpr->x.pList->nExpr > 0);
pEList = pExpr->x.pList;
aListelem = pEList->a;
nExpr = pEList->nExpr;
endLabel = sqlite3VdbeMakeLabel(pParse);
if( (pX = pExpr->pLeft)!=0 ){
pDel = sqlite3ExprDup(db, pX, 0);
if( db->mallocFailed ){
sqlite3ExprDelete(db, pDel);
break;
}
testcase( pX->op==TK_COLUMN );
exprToRegister(pDel, exprCodeVector(pParse, pDel, ®Free1));
testcase( regFree1==0 );
memset(&opCompare, 0, sizeof(opCompare));
opCompare.op = TK_EQ;
opCompare.pLeft = pDel;
pTest = &opCompare;
regFree1 = 0;
}
for(i=0; i<nExpr-1; i=i+2){
if( pX ){
assert( pTest!=0 );
opCompare.pRight = aListelem[i].pExpr;
}else{
pTest = aListelem[i].pExpr;
}
nextCase = sqlite3VdbeMakeLabel(pParse);
testcase( pTest->op==TK_COLUMN );
sqlite3ExprIfFalse(pParse, pTest, nextCase, SQLITE_JUMPIFNULL);
testcase( aListelem[i+1].pExpr->op==TK_COLUMN );
sqlite3ExprCode(pParse, aListelem[i+1].pExpr, target);
sqlite3VdbeGoto(v, endLabel);
sqlite3VdbeResolveLabel(v, nextCase);
}
if( (nExpr&1)!=0 ){
sqlite3ExprCode(pParse, pEList->a[nExpr-1].pExpr, target);
}else{
sqlite3VdbeAddOp2(v, OP_Null, 0, target);
}
sqlite3ExprDelete(db, pDel);
setDoNotMergeFlagOnCopy(v);
sqlite3VdbeResolveLabel(v, endLabel);
break;
}
#ifndef SQLITE_OMIT_TRIGGER
case TK_RAISE: {
assert( pExpr->affExpr==OE_Rollback
|| pExpr->affExpr==OE_Abort
|| pExpr->affExpr==OE_Fail
|| pExpr->affExpr==OE_Ignore
);
if( !pParse->pTriggerTab && !pParse->nested ){
sqlite3ErrorMsg(pParse,
"RAISE() may only be used within a trigger-program");
return 0;
}
if( pExpr->affExpr==OE_Abort ){
sqlite3MayAbort(pParse);
}
assert( !ExprHasProperty(pExpr, EP_IntValue) );
if( pExpr->affExpr==OE_Ignore ){
sqlite3VdbeAddOp4(
v, OP_Halt, SQLITE_OK, OE_Ignore, 0, pExpr->u.zToken,0);
VdbeCoverage(v);
}else{
sqlite3HaltConstraint(pParse,
pParse->pTriggerTab ? SQLITE_CONSTRAINT_TRIGGER : SQLITE_ERROR,
pExpr->affExpr, pExpr->u.zToken, 0, 0);
}
break;
}
#endif
}
sqlite3ReleaseTempReg(pParse, regFree1);
sqlite3ReleaseTempReg(pParse, regFree2);
return inReg;
}
int sqlite3ExprCodeRunJustOnce(
Parse *pParse,
Expr *pExpr,
int regDest
){
ExprList *p;
assert( ConstFactorOk(pParse) );
p = pParse->pConstExpr;
if( regDest<0 && p ){
struct ExprList_item *pItem;
int i;
for(pItem=p->a, i=p->nExpr; i>0; pItem++, i--){
if( pItem->fg.reusable
&& sqlite3ExprCompare(0,pItem->pExpr,pExpr,-1)==0
){
return pItem->u.iConstExprReg;
}
}
}
pExpr = sqlite3ExprDup(pParse->db, pExpr, 0);
if( pExpr!=0 && ExprHasProperty(pExpr, EP_HasFunc) ){
Vdbe *v = pParse->pVdbe;
int addr;
assert( v );
addr = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
pParse->okConstFactor = 0;
if( !pParse->db->mallocFailed ){
if( regDest<0 ) regDest = ++pParse->nMem;
sqlite3ExprCode(pParse, pExpr, regDest);
}
pParse->okConstFactor = 1;
sqlite3ExprDelete(pParse->db, pExpr);
sqlite3VdbeJumpHere(v, addr);
}else{
p = sqlite3ExprListAppend(pParse, p, pExpr);
if( p ){
struct ExprList_item *pItem = &p->a[p->nExpr-1];
pItem->fg.reusable = regDest<0;
if( regDest<0 ) regDest = ++pParse->nMem;
pItem->u.iConstExprReg = regDest;
}
pParse->pConstExpr = p;
}
return regDest;
}
int sqlite3ExprCodeTemp(Parse *pParse, Expr *pExpr, int *pReg){
int r2;
pExpr = sqlite3ExprSkipCollateAndLikely(pExpr);
if( ConstFactorOk(pParse)
&& ALWAYS(pExpr!=0)
&& pExpr->op!=TK_REGISTER
&& sqlite3ExprIsConstantNotJoin(pExpr)
){
*pReg = 0;
r2 = sqlite3ExprCodeRunJustOnce(pParse, pExpr, -1);
}else{
int r1 = sqlite3GetTempReg(pParse);
r2 = sqlite3ExprCodeTarget(pParse, pExpr, r1);
if( r2==r1 ){
*pReg = r1;
}else{
sqlite3ReleaseTempReg(pParse, r1);
*pReg = 0;
}
}
return r2;
}
void sqlite3ExprCode(Parse *pParse, Expr *pExpr, int target){
int inReg;
assert( pExpr==0 || !ExprHasVVAProperty(pExpr,EP_Immutable) );
assert( target>0 && target<=pParse->nMem );
assert( pParse->pVdbe!=0 || pParse->db->mallocFailed );
if( pParse->pVdbe==0 ) return;
inReg = sqlite3ExprCodeTarget(pParse, pExpr, target);
if( inReg!=target ){
u8 op;
if( ALWAYS(pExpr)
&& (ExprHasProperty(pExpr,EP_Subquery) || pExpr->op==TK_REGISTER)
){
op = OP_Copy;
}else{
op = OP_SCopy;
}
sqlite3VdbeAddOp2(pParse->pVdbe, op, inReg, target);
}
}
void sqlite3ExprCodeCopy(Parse *pParse, Expr *pExpr, int target){
sqlite3 *db = pParse->db;
pExpr = sqlite3ExprDup(db, pExpr, 0);
if( !db->mallocFailed ) sqlite3ExprCode(pParse, pExpr, target);
sqlite3ExprDelete(db, pExpr);
}
void sqlite3ExprCodeFactorable(Parse *pParse, Expr *pExpr, int target){
if( pParse->okConstFactor && sqlite3ExprIsConstantNotJoin(pExpr) ){
sqlite3ExprCodeRunJustOnce(pParse, pExpr, target);
}else{
sqlite3ExprCodeCopy(pParse, pExpr, target);
}
}
int sqlite3ExprCodeExprList(
Parse *pParse,
ExprList *pList,
int target,
int srcReg,
u8 flags
){
struct ExprList_item *pItem;
int i, j, n;
u8 copyOp = (flags & SQLITE_ECEL_DUP) ? OP_Copy : OP_SCopy;
Vdbe *v = pParse->pVdbe;
assert( pList!=0 );
assert( target>0 );
assert( pParse->pVdbe!=0 );
n = pList->nExpr;
if( !ConstFactorOk(pParse) ) flags &= ~SQLITE_ECEL_FACTOR;
for(pItem=pList->a, i=0; i<n; i++, pItem++){
Expr *pExpr = pItem->pExpr;
#ifdef SQLITE_ENABLE_SORTER_REFERENCES
if( pItem->fg.bSorterRef ){
i--;
n--;
}else
#endif
if( (flags & SQLITE_ECEL_REF)!=0 && (j = pItem->u.x.iOrderByCol)>0 ){
if( flags & SQLITE_ECEL_OMITREF ){
i--;
n--;
}else{
sqlite3VdbeAddOp2(v, copyOp, j+srcReg-1, target+i);
}
}else if( (flags & SQLITE_ECEL_FACTOR)!=0
&& sqlite3ExprIsConstantNotJoin(pExpr)
){
sqlite3ExprCodeRunJustOnce(pParse, pExpr, target+i);
}else{
int inReg = sqlite3ExprCodeTarget(pParse, pExpr, target+i);
if( inReg!=target+i ){
VdbeOp *pOp;
if( copyOp==OP_Copy
&& (pOp=sqlite3VdbeGetLastOp(v))->opcode==OP_Copy
&& pOp->p1+pOp->p3+1==inReg
&& pOp->p2+pOp->p3+1==target+i
&& pOp->p5==0
){
pOp->p3++;
}else{
sqlite3VdbeAddOp2(v, copyOp, inReg, target+i);
}
}
}
}
return n;
}
static void exprCodeBetween(
Parse *pParse,
Expr *pExpr,
int dest,
void (*xJump)(Parse*,Expr*,int,int),
int jumpIfNull
){
Expr exprAnd;
Expr compLeft;
Expr compRight;
int regFree1 = 0;
Expr *pDel = 0;
sqlite3 *db = pParse->db;
memset(&compLeft, 0, sizeof(Expr));
memset(&compRight, 0, sizeof(Expr));
memset(&exprAnd, 0, sizeof(Expr));
assert( ExprUseXList(pExpr) );
pDel = sqlite3ExprDup(db, pExpr->pLeft, 0);
if( db->mallocFailed==0 ){
exprAnd.op = TK_AND;
exprAnd.pLeft = &compLeft;
exprAnd.pRight = &compRight;
compLeft.op = TK_GE;
compLeft.pLeft = pDel;
compLeft.pRight = pExpr->x.pList->a[0].pExpr;
compRight.op = TK_LE;
compRight.pLeft = pDel;
compRight.pRight = pExpr->x.pList->a[1].pExpr;
exprToRegister(pDel, exprCodeVector(pParse, pDel, ®Free1));
if( xJump ){
xJump(pParse, &exprAnd, dest, jumpIfNull);
}else{
pDel->flags |= EP_OuterON;
sqlite3ExprCodeTarget(pParse, &exprAnd, dest);
}
sqlite3ReleaseTempReg(pParse, regFree1);
}
sqlite3ExprDelete(db, pDel);
testcase( xJump==sqlite3ExprIfTrue && jumpIfNull==0 && regFree1==0 );
testcase( xJump==sqlite3ExprIfTrue && jumpIfNull==0 && regFree1!=0 );
testcase( xJump==sqlite3ExprIfTrue && jumpIfNull!=0 && regFree1==0 );
testcase( xJump==sqlite3ExprIfTrue && jumpIfNull!=0 && regFree1!=0 );
testcase( xJump==sqlite3ExprIfFalse && jumpIfNull==0 && regFree1==0 );
testcase( xJump==sqlite3ExprIfFalse && jumpIfNull==0 && regFree1!=0 );
testcase( xJump==sqlite3ExprIfFalse && jumpIfNull!=0 && regFree1==0 );
testcase( xJump==sqlite3ExprIfFalse && jumpIfNull!=0 && regFree1!=0 );
testcase( xJump==0 );
}
void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
Vdbe *v = pParse->pVdbe;
int op = 0;
int regFree1 = 0;
int regFree2 = 0;
int r1, r2;
assert( jumpIfNull==SQLITE_JUMPIFNULL || jumpIfNull==0 );
if( NEVER(v==0) ) return;
if( NEVER(pExpr==0) ) return;
assert( !ExprHasVVAProperty(pExpr, EP_Immutable) );
op = pExpr->op;
switch( op ){
case TK_AND:
case TK_OR: {
Expr *pAlt = sqlite3ExprSimplifiedAndOr(pExpr);
if( pAlt!=pExpr ){
sqlite3ExprIfTrue(pParse, pAlt, dest, jumpIfNull);
}else if( op==TK_AND ){
int d2 = sqlite3VdbeMakeLabel(pParse);
testcase( jumpIfNull==0 );
sqlite3ExprIfFalse(pParse, pExpr->pLeft, d2,
jumpIfNull^SQLITE_JUMPIFNULL);
sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull);
sqlite3VdbeResolveLabel(v, d2);
}else{
testcase( jumpIfNull==0 );
sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, jumpIfNull);
sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull);
}
break;
}
case TK_NOT: {
testcase( jumpIfNull==0 );
sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull);
break;
}
case TK_TRUTH: {
int isNot;
int isTrue;
testcase( jumpIfNull==0 );
isNot = pExpr->op2==TK_ISNOT;
isTrue = sqlite3ExprTruthValue(pExpr->pRight);
testcase( isTrue && isNot );
testcase( !isTrue && isNot );
if( isTrue ^ isNot ){
sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest,
isNot ? SQLITE_JUMPIFNULL : 0);
}else{
sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest,
isNot ? SQLITE_JUMPIFNULL : 0);
}
break;
}
case TK_IS:
case TK_ISNOT:
testcase( op==TK_IS );
testcase( op==TK_ISNOT );
op = (op==TK_IS) ? TK_EQ : TK_NE;
jumpIfNull = SQLITE_NULLEQ;
deliberate_fall_through
case TK_LT:
case TK_LE:
case TK_GT:
case TK_GE:
case TK_NE:
case TK_EQ: {
if( sqlite3ExprIsVector(pExpr->pLeft) ) goto default_expr;
testcase( jumpIfNull==0 );
r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1);
r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2);
codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op,
r1, r2, dest, jumpIfNull, ExprHasProperty(pExpr,EP_Commuted));
assert(TK_LT==OP_Lt); testcase(op==OP_Lt); VdbeCoverageIf(v,op==OP_Lt);
assert(TK_LE==OP_Le); testcase(op==OP_Le); VdbeCoverageIf(v,op==OP_Le);
assert(TK_GT==OP_Gt); testcase(op==OP_Gt); VdbeCoverageIf(v,op==OP_Gt);
assert(TK_GE==OP_Ge); testcase(op==OP_Ge); VdbeCoverageIf(v,op==OP_Ge);
assert(TK_EQ==OP_Eq); testcase(op==OP_Eq);
VdbeCoverageIf(v, op==OP_Eq && jumpIfNull==SQLITE_NULLEQ);
VdbeCoverageIf(v, op==OP_Eq && jumpIfNull!=SQLITE_NULLEQ);
assert(TK_NE==OP_Ne); testcase(op==OP_Ne);
VdbeCoverageIf(v, op==OP_Ne && jumpIfNull==SQLITE_NULLEQ);
VdbeCoverageIf(v, op==OP_Ne && jumpIfNull!=SQLITE_NULLEQ);
testcase( regFree1==0 );
testcase( regFree2==0 );
break;
}
case TK_ISNULL:
case TK_NOTNULL: {
assert( TK_ISNULL==OP_IsNull ); testcase( op==TK_ISNULL );
assert( TK_NOTNULL==OP_NotNull ); testcase( op==TK_NOTNULL );
r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1);
sqlite3VdbeTypeofColumn(v, r1);
sqlite3VdbeAddOp2(v, op, r1, dest);
VdbeCoverageIf(v, op==TK_ISNULL);
VdbeCoverageIf(v, op==TK_NOTNULL);
testcase( regFree1==0 );
break;
}
case TK_BETWEEN: {
testcase( jumpIfNull==0 );
exprCodeBetween(pParse, pExpr, dest, sqlite3ExprIfTrue, jumpIfNull);
break;
}
#ifndef SQLITE_OMIT_SUBQUERY
case TK_IN: {
int destIfFalse = sqlite3VdbeMakeLabel(pParse);
int destIfNull = jumpIfNull ? dest : destIfFalse;
sqlite3ExprCodeIN(pParse, pExpr, destIfFalse, destIfNull);
sqlite3VdbeGoto(v, dest);
sqlite3VdbeResolveLabel(v, destIfFalse);
break;
}
#endif
default: {
default_expr:
if( ExprAlwaysTrue(pExpr) ){
sqlite3VdbeGoto(v, dest);
}else if( ExprAlwaysFalse(pExpr) ){
}else{
r1 = sqlite3ExprCodeTemp(pParse, pExpr, ®Free1);
sqlite3VdbeAddOp3(v, OP_If, r1, dest, jumpIfNull!=0);
VdbeCoverage(v);
testcase( regFree1==0 );
testcase( jumpIfNull==0 );
}
break;
}
}
sqlite3ReleaseTempReg(pParse, regFree1);
sqlite3ReleaseTempReg(pParse, regFree2);
}
void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
Vdbe *v = pParse->pVdbe;
int op = 0;
int regFree1 = 0;
int regFree2 = 0;
int r1, r2;
assert( jumpIfNull==SQLITE_JUMPIFNULL || jumpIfNull==0 );
if( NEVER(v==0) ) return;
if( pExpr==0 ) return;
assert( !ExprHasVVAProperty(pExpr,EP_Immutable) );
op = ((pExpr->op+(TK_ISNULL&1))^1)-(TK_ISNULL&1);
assert( pExpr->op!=TK_ISNULL || op==OP_NotNull );
assert( pExpr->op!=TK_NOTNULL || op==OP_IsNull );
assert( pExpr->op!=TK_NE || op==OP_Eq );
assert( pExpr->op!=TK_EQ || op==OP_Ne );
assert( pExpr->op!=TK_LT || op==OP_Ge );
assert( pExpr->op!=TK_LE || op==OP_Gt );
assert( pExpr->op!=TK_GT || op==OP_Le );
assert( pExpr->op!=TK_GE || op==OP_Lt );
switch( pExpr->op ){
case TK_AND:
case TK_OR: {
Expr *pAlt = sqlite3ExprSimplifiedAndOr(pExpr);
if( pAlt!=pExpr ){
sqlite3ExprIfFalse(pParse, pAlt, dest, jumpIfNull);
}else if( pExpr->op==TK_AND ){
testcase( jumpIfNull==0 );
sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull);
sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull);
}else{
int d2 = sqlite3VdbeMakeLabel(pParse);
testcase( jumpIfNull==0 );
sqlite3ExprIfTrue(pParse, pExpr->pLeft, d2,
jumpIfNull^SQLITE_JUMPIFNULL);
sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull);
sqlite3VdbeResolveLabel(v, d2);
}
break;
}
case TK_NOT: {
testcase( jumpIfNull==0 );
sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, jumpIfNull);
break;
}
case TK_TRUTH: {
int isNot;
int isTrue;
testcase( jumpIfNull==0 );
isNot = pExpr->op2==TK_ISNOT;
isTrue = sqlite3ExprTruthValue(pExpr->pRight);
testcase( isTrue && isNot );
testcase( !isTrue && isNot );
if( isTrue ^ isNot ){
sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest,
isNot ? 0 : SQLITE_JUMPIFNULL);
}else{
sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest,
isNot ? 0 : SQLITE_JUMPIFNULL);
}
break;
}
case TK_IS:
case TK_ISNOT:
testcase( pExpr->op==TK_IS );
testcase( pExpr->op==TK_ISNOT );
op = (pExpr->op==TK_IS) ? TK_NE : TK_EQ;
jumpIfNull = SQLITE_NULLEQ;
deliberate_fall_through
case TK_LT:
case TK_LE:
case TK_GT:
case TK_GE:
case TK_NE:
case TK_EQ: {
if( sqlite3ExprIsVector(pExpr->pLeft) ) goto default_expr;
testcase( jumpIfNull==0 );
r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1);
r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2);
codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op,
r1, r2, dest, jumpIfNull,ExprHasProperty(pExpr,EP_Commuted));
assert(TK_LT==OP_Lt); testcase(op==OP_Lt); VdbeCoverageIf(v,op==OP_Lt);
assert(TK_LE==OP_Le); testcase(op==OP_Le); VdbeCoverageIf(v,op==OP_Le);
assert(TK_GT==OP_Gt); testcase(op==OP_Gt); VdbeCoverageIf(v,op==OP_Gt);
assert(TK_GE==OP_Ge); testcase(op==OP_Ge); VdbeCoverageIf(v,op==OP_Ge);
assert(TK_EQ==OP_Eq); testcase(op==OP_Eq);
VdbeCoverageIf(v, op==OP_Eq && jumpIfNull!=SQLITE_NULLEQ);
VdbeCoverageIf(v, op==OP_Eq && jumpIfNull==SQLITE_NULLEQ);
assert(TK_NE==OP_Ne); testcase(op==OP_Ne);
VdbeCoverageIf(v, op==OP_Ne && jumpIfNull!=SQLITE_NULLEQ);
VdbeCoverageIf(v, op==OP_Ne && jumpIfNull==SQLITE_NULLEQ);
testcase( regFree1==0 );
testcase( regFree2==0 );
break;
}
case TK_ISNULL:
case TK_NOTNULL: {
r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1);
sqlite3VdbeTypeofColumn(v, r1);
sqlite3VdbeAddOp2(v, op, r1, dest);
testcase( op==TK_ISNULL ); VdbeCoverageIf(v, op==TK_ISNULL);
testcase( op==TK_NOTNULL ); VdbeCoverageIf(v, op==TK_NOTNULL);
testcase( regFree1==0 );
break;
}
case TK_BETWEEN: {
testcase( jumpIfNull==0 );
exprCodeBetween(pParse, pExpr, dest, sqlite3ExprIfFalse, jumpIfNull);
break;
}
#ifndef SQLITE_OMIT_SUBQUERY
case TK_IN: {
if( jumpIfNull ){
sqlite3ExprCodeIN(pParse, pExpr, dest, dest);
}else{
int destIfNull = sqlite3VdbeMakeLabel(pParse);
sqlite3ExprCodeIN(pParse, pExpr, dest, destIfNull);
sqlite3VdbeResolveLabel(v, destIfNull);
}
break;
}
#endif
default: {
default_expr:
if( ExprAlwaysFalse(pExpr) ){
sqlite3VdbeGoto(v, dest);
}else if( ExprAlwaysTrue(pExpr) ){
}else{
r1 = sqlite3ExprCodeTemp(pParse, pExpr, ®Free1);
sqlite3VdbeAddOp3(v, OP_IfNot, r1, dest, jumpIfNull!=0);
VdbeCoverage(v);
testcase( regFree1==0 );
testcase( jumpIfNull==0 );
}
break;
}
}
sqlite3ReleaseTempReg(pParse, regFree1);
sqlite3ReleaseTempReg(pParse, regFree2);
}
void sqlite3ExprIfFalseDup(Parse *pParse, Expr *pExpr, int dest,int jumpIfNull){
sqlite3 *db = pParse->db;
Expr *pCopy = sqlite3ExprDup(db, pExpr, 0);
if( db->mallocFailed==0 ){
sqlite3ExprIfFalse(pParse, pCopy, dest, jumpIfNull);
}
sqlite3ExprDelete(db, pCopy);
}
static int exprCompareVariable(
const Parse *pParse,
const Expr *pVar,
const Expr *pExpr
){
int res = 0;
int iVar;
sqlite3_value *pL, *pR = 0;
sqlite3ValueFromExpr(pParse->db, pExpr, SQLITE_UTF8, SQLITE_AFF_BLOB, &pR);
if( pR ){
iVar = pVar->iColumn;
sqlite3VdbeSetVarmask(pParse->pVdbe, iVar);
pL = sqlite3VdbeGetBoundValue(pParse->pReprepare, iVar, SQLITE_AFF_BLOB);
if( pL ){
if( sqlite3_value_type(pL)==SQLITE_TEXT ){
sqlite3_value_text(pL);
}
res = 0==sqlite3MemCompare(pL, pR, 0);
}
sqlite3ValueFree(pR);
sqlite3ValueFree(pL);
}
return res;
}
int sqlite3ExprCompare(
const Parse *pParse,
const Expr *pA,
const Expr *pB,
int iTab
){
u32 combinedFlags;
if( pA==0 || pB==0 ){
return pB==pA ? 0 : 2;
}
if( pParse && pA->op==TK_VARIABLE && exprCompareVariable(pParse, pA, pB) ){
return 0;
}
combinedFlags = pA->flags | pB->flags;
if( combinedFlags & EP_IntValue ){
if( (pA->flags&pB->flags&EP_IntValue)!=0 && pA->u.iValue==pB->u.iValue ){
return 0;
}
return 2;
}
if( pA->op!=pB->op || pA->op==TK_RAISE ){
if( pA->op==TK_COLLATE && sqlite3ExprCompare(pParse, pA->pLeft,pB,iTab)<2 ){
return 1;
}
if( pB->op==TK_COLLATE && sqlite3ExprCompare(pParse, pA,pB->pLeft,iTab)<2 ){
return 1;
}
if( pA->op==TK_AGG_COLUMN && pB->op==TK_COLUMN
&& pB->iTable<0 && pA->iTable==iTab
){
}else{
return 2;
}
}
assert( !ExprHasProperty(pA, EP_IntValue) );
assert( !ExprHasProperty(pB, EP_IntValue) );
if( pA->u.zToken ){
if( pA->op==TK_FUNCTION || pA->op==TK_AGG_FUNCTION ){
if( sqlite3StrICmp(pA->u.zToken,pB->u.zToken)!=0 ) return 2;
#ifndef SQLITE_OMIT_WINDOWFUNC
assert( pA->op==pB->op );
if( ExprHasProperty(pA,EP_WinFunc)!=ExprHasProperty(pB,EP_WinFunc) ){
return 2;
}
if( ExprHasProperty(pA,EP_WinFunc) ){
if( sqlite3WindowCompare(pParse, pA->y.pWin, pB->y.pWin, 1)!=0 ){
return 2;
}
}
#endif
}else if( pA->op==TK_NULL ){
return 0;
}else if( pA->op==TK_COLLATE ){
if( sqlite3_stricmp(pA->u.zToken,pB->u.zToken)!=0 ) return 2;
}else
if( pB->u.zToken!=0
&& pA->op!=TK_COLUMN
&& pA->op!=TK_AGG_COLUMN
&& strcmp(pA->u.zToken,pB->u.zToken)!=0
){
return 2;
}
}
if( (pA->flags & (EP_Distinct|EP_Commuted))
!= (pB->flags & (EP_Distinct|EP_Commuted)) ) return 2;
if( ALWAYS((combinedFlags & EP_TokenOnly)==0) ){
if( combinedFlags & EP_xIsSelect ) return 2;
if( (combinedFlags & EP_FixedCol)==0
&& sqlite3ExprCompare(pParse, pA->pLeft, pB->pLeft, iTab) ) return 2;
if( sqlite3ExprCompare(pParse, pA->pRight, pB->pRight, iTab) ) return 2;
if( sqlite3ExprListCompare(pA->x.pList, pB->x.pList, iTab) ) return 2;
if( pA->op!=TK_STRING
&& pA->op!=TK_TRUEFALSE
&& ALWAYS((combinedFlags & EP_Reduced)==0)
){
if( pA->iColumn!=pB->iColumn ) return 2;
if( pA->op2!=pB->op2 && pA->op==TK_TRUTH ) return 2;
if( pA->op!=TK_IN && pA->iTable!=pB->iTable && pA->iTable!=iTab ){
return 2;
}
}
}
return 0;
}
int sqlite3ExprListCompare(const ExprList *pA, const ExprList *pB, int iTab){
int i;
if( pA==0 && pB==0 ) return 0;
if( pA==0 || pB==0 ) return 1;
if( pA->nExpr!=pB->nExpr ) return 1;
for(i=0; i<pA->nExpr; i++){
int res;
Expr *pExprA = pA->a[i].pExpr;
Expr *pExprB = pB->a[i].pExpr;
if( pA->a[i].fg.sortFlags!=pB->a[i].fg.sortFlags ) return 1;
if( (res = sqlite3ExprCompare(0, pExprA, pExprB, iTab)) ) return res;
}
return 0;
}
int sqlite3ExprCompareSkip(Expr *pA,Expr *pB, int iTab){
return sqlite3ExprCompare(0,
sqlite3ExprSkipCollateAndLikely(pA),
sqlite3ExprSkipCollateAndLikely(pB),
iTab);
}
static int exprImpliesNotNull(
const Parse *pParse,
const Expr *p,
const Expr *pNN,
int iTab,
int seenNot
){
assert( p );
assert( pNN );
if( sqlite3ExprCompare(pParse, p, pNN, iTab)==0 ){
return pNN->op!=TK_NULL;
}
switch( p->op ){
case TK_IN: {
if( seenNot && ExprHasProperty(p, EP_xIsSelect) ) return 0;
assert( ExprUseXSelect(p) || (p->x.pList!=0 && p->x.pList->nExpr>0) );
return exprImpliesNotNull(pParse, p->pLeft, pNN, iTab, 1);
}
case TK_BETWEEN: {
ExprList *pList;
assert( ExprUseXList(p) );
pList = p->x.pList;
assert( pList!=0 );
assert( pList->nExpr==2 );
if( seenNot ) return 0;
if( exprImpliesNotNull(pParse, pList->a[0].pExpr, pNN, iTab, 1)
|| exprImpliesNotNull(pParse, pList->a[1].pExpr, pNN, iTab, 1)
){
return 1;
}
return exprImpliesNotNull(pParse, p->pLeft, pNN, iTab, 1);
}
case TK_EQ:
case TK_NE:
case TK_LT:
case TK_LE:
case TK_GT:
case TK_GE:
case TK_PLUS:
case TK_MINUS:
case TK_BITOR:
case TK_LSHIFT:
case TK_RSHIFT:
case TK_CONCAT:
seenNot = 1;
deliberate_fall_through
case TK_STAR:
case TK_REM:
case TK_BITAND:
case TK_SLASH: {
if( exprImpliesNotNull(pParse, p->pRight, pNN, iTab, seenNot) ) return 1;
deliberate_fall_through
}
case TK_SPAN:
case TK_COLLATE:
case TK_UPLUS:
case TK_UMINUS: {
return exprImpliesNotNull(pParse, p->pLeft, pNN, iTab, seenNot);
}
case TK_TRUTH: {
if( seenNot ) return 0;
if( p->op2!=TK_IS ) return 0;
return exprImpliesNotNull(pParse, p->pLeft, pNN, iTab, 1);
}
case TK_BITNOT:
case TK_NOT: {
return exprImpliesNotNull(pParse, p->pLeft, pNN, iTab, 1);
}
}
return 0;
}
int sqlite3ExprImpliesExpr(
const Parse *pParse,
const Expr *pE1,
const Expr *pE2,
int iTab
){
if( sqlite3ExprCompare(pParse, pE1, pE2, iTab)==0 ){
return 1;
}
if( pE2->op==TK_OR
&& (sqlite3ExprImpliesExpr(pParse, pE1, pE2->pLeft, iTab)
|| sqlite3ExprImpliesExpr(pParse, pE1, pE2->pRight, iTab) )
){
return 1;
}
if( pE2->op==TK_NOTNULL
&& exprImpliesNotNull(pParse, pE1, pE2->pLeft, iTab, 0)
){
return 1;
}
return 0;
}
static void bothImplyNotNullRow(Walker *pWalker, Expr *pE1, Expr *pE2){
if( pWalker->eCode==0 ){
sqlite3WalkExpr(pWalker, pE1);
if( pWalker->eCode ){
pWalker->eCode = 0;
sqlite3WalkExpr(pWalker, pE2);
}
}
}
static int impliesNotNullRow(Walker *pWalker, Expr *pExpr){
testcase( pExpr->op==TK_AGG_COLUMN );
testcase( pExpr->op==TK_AGG_FUNCTION );
if( ExprHasProperty(pExpr, EP_OuterON) ) return WRC_Prune;
if( ExprHasProperty(pExpr, EP_InnerON) && pWalker->mWFlags ){
return WRC_Prune;
}
switch( pExpr->op ){
case TK_ISNOT:
case TK_ISNULL:
case TK_NOTNULL:
case TK_IS:
case TK_VECTOR:
case TK_FUNCTION:
case TK_TRUTH:
case TK_CASE:
testcase( pExpr->op==TK_ISNOT );
testcase( pExpr->op==TK_ISNULL );
testcase( pExpr->op==TK_NOTNULL );
testcase( pExpr->op==TK_IS );
testcase( pExpr->op==TK_VECTOR );
testcase( pExpr->op==TK_FUNCTION );
testcase( pExpr->op==TK_TRUTH );
testcase( pExpr->op==TK_CASE );
return WRC_Prune;
case TK_COLUMN:
if( pWalker->u.iCur==pExpr->iTable ){
pWalker->eCode = 1;
return WRC_Abort;
}
return WRC_Prune;
case TK_OR:
case TK_AND:
testcase( pExpr->op==TK_OR );
testcase( pExpr->op==TK_AND );
bothImplyNotNullRow(pWalker, pExpr->pLeft, pExpr->pRight);
return WRC_Prune;
case TK_IN:
if( ExprUseXList(pExpr) && ALWAYS(pExpr->x.pList->nExpr>0) ){
sqlite3WalkExpr(pWalker, pExpr->pLeft);
}
return WRC_Prune;
case TK_BETWEEN:
assert( ExprUseXList(pExpr) );
assert( pExpr->x.pList->nExpr==2 );
sqlite3WalkExpr(pWalker, pExpr->pLeft);
bothImplyNotNullRow(pWalker, pExpr->x.pList->a[0].pExpr,
pExpr->x.pList->a[1].pExpr);
return WRC_Prune;
case TK_EQ:
case TK_NE:
case TK_LT:
case TK_LE:
case TK_GT:
case TK_GE: {
Expr *pLeft = pExpr->pLeft;
Expr *pRight = pExpr->pRight;
testcase( pExpr->op==TK_EQ );
testcase( pExpr->op==TK_NE );
testcase( pExpr->op==TK_LT );
testcase( pExpr->op==TK_LE );
testcase( pExpr->op==TK_GT );
testcase( pExpr->op==TK_GE );
assert( pLeft->op!=TK_COLUMN || ExprUseYTab(pLeft) );
assert( pRight->op!=TK_COLUMN || ExprUseYTab(pRight) );
if( (pLeft->op==TK_COLUMN
&& ALWAYS(pLeft->y.pTab!=0)
&& IsVirtual(pLeft->y.pTab))
|| (pRight->op==TK_COLUMN
&& ALWAYS(pRight->y.pTab!=0)
&& IsVirtual(pRight->y.pTab))
){
return WRC_Prune;
}
deliberate_fall_through
}
default:
return WRC_Continue;
}
}
int sqlite3ExprImpliesNonNullRow(Expr *p, int iTab, int isRJ){
Walker w;
p = sqlite3ExprSkipCollateAndLikely(p);
if( p==0 ) return 0;
if( p->op==TK_NOTNULL ){
p = p->pLeft;
}else{
while( p->op==TK_AND ){
if( sqlite3ExprImpliesNonNullRow(p->pLeft, iTab, isRJ) ) return 1;
p = p->pRight;
}
}
w.xExprCallback = impliesNotNullRow;
w.xSelectCallback = 0;
w.xSelectCallback2 = 0;
w.eCode = 0;
w.mWFlags = isRJ!=0;
w.u.iCur = iTab;
sqlite3WalkExpr(&w, p);
return w.eCode;
}
struct IdxCover {
Index *pIdx;
int iCur;
};
static int exprIdxCover(Walker *pWalker, Expr *pExpr){
if( pExpr->op==TK_COLUMN
&& pExpr->iTable==pWalker->u.pIdxCover->iCur
&& sqlite3TableColumnToIndex(pWalker->u.pIdxCover->pIdx, pExpr->iColumn)<0
){
pWalker->eCode = 1;
return WRC_Abort;
}
return WRC_Continue;
}
int sqlite3ExprCoveredByIndex(
Expr *pExpr,
int iCur,
Index *pIdx
){
Walker w;
struct IdxCover xcov;
memset(&w, 0, sizeof(w));
xcov.iCur = iCur;
xcov.pIdx = pIdx;
w.xExprCallback = exprIdxCover;
w.u.pIdxCover = &xcov;
sqlite3WalkExpr(&w, pExpr);
return !w.eCode;
}
struct RefSrcList {
sqlite3 *db;
SrcList *pRef;
i64 nExclude;
int *aiExclude;
};
static int selectRefEnter(Walker *pWalker, Select *pSelect){
struct RefSrcList *p = pWalker->u.pRefSrcList;
SrcList *pSrc = pSelect->pSrc;
i64 i, j;
int *piNew;
if( pSrc->nSrc==0 ) return WRC_Continue;
j = p->nExclude;
p->nExclude += pSrc->nSrc;
piNew = sqlite3DbRealloc(p->db, p->aiExclude, p->nExclude*sizeof(int));
if( piNew==0 ){
p->nExclude = 0;
return WRC_Abort;
}else{
p->aiExclude = piNew;
}
for(i=0; i<pSrc->nSrc; i++, j++){
p->aiExclude[j] = pSrc->a[i].iCursor;
}
return WRC_Continue;
}
static void selectRefLeave(Walker *pWalker, Select *pSelect){
struct RefSrcList *p = pWalker->u.pRefSrcList;
SrcList *pSrc = pSelect->pSrc;
if( p->nExclude ){
assert( p->nExclude>=pSrc->nSrc );
p->nExclude -= pSrc->nSrc;
}
}
static int exprRefToSrcList(Walker *pWalker, Expr *pExpr){
if( pExpr->op==TK_COLUMN
|| pExpr->op==TK_AGG_COLUMN
){
int i;
struct RefSrcList *p = pWalker->u.pRefSrcList;
SrcList *pSrc = p->pRef;
int nSrc = pSrc ? pSrc->nSrc : 0;
for(i=0; i<nSrc; i++){
if( pExpr->iTable==pSrc->a[i].iCursor ){
pWalker->eCode |= 1;
return WRC_Continue;
}
}
for(i=0; i<p->nExclude && p->aiExclude[i]!=pExpr->iTable; i++){}
if( i>=p->nExclude ){
pWalker->eCode |= 2;
}
}
return WRC_Continue;
}
int sqlite3ReferencesSrcList(Parse *pParse, Expr *pExpr, SrcList *pSrcList){
Walker w;
struct RefSrcList x;
assert( pParse->db!=0 );
memset(&w, 0, sizeof(w));
memset(&x, 0, sizeof(x));
w.xExprCallback = exprRefToSrcList;
w.xSelectCallback = selectRefEnter;
w.xSelectCallback2 = selectRefLeave;
w.u.pRefSrcList = &x;
x.db = pParse->db;
x.pRef = pSrcList;
assert( pExpr->op==TK_AGG_FUNCTION );
assert( ExprUseXList(pExpr) );
sqlite3WalkExprList(&w, pExpr->x.pList);
#ifndef SQLITE_OMIT_WINDOWFUNC
if( ExprHasProperty(pExpr, EP_WinFunc) ){
sqlite3WalkExpr(&w, pExpr->y.pWin->pFilter);
}
#endif
if( x.aiExclude ) sqlite3DbNNFreeNN(pParse->db, x.aiExclude);
if( w.eCode & 0x01 ){
return 1;
}else if( w.eCode ){
return 0;
}else{
return -1;
}
}
static int agginfoPersistExprCb(Walker *pWalker, Expr *pExpr){
if( ALWAYS(!ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced))
&& pExpr->pAggInfo!=0
){
AggInfo *pAggInfo = pExpr->pAggInfo;
int iAgg = pExpr->iAgg;
Parse *pParse = pWalker->pParse;
sqlite3 *db = pParse->db;
assert( iAgg>=0 );
if( pExpr->op!=TK_AGG_FUNCTION ){
if( iAgg<pAggInfo->nColumn
&& pAggInfo->aCol[iAgg].pCExpr==pExpr
){
pExpr = sqlite3ExprDup(db, pExpr, 0);
if( pExpr ){
pAggInfo->aCol[iAgg].pCExpr = pExpr;
sqlite3ExprDeferredDelete(pParse, pExpr);
}
}
}else{
assert( pExpr->op==TK_AGG_FUNCTION );
if( ALWAYS(iAgg<pAggInfo->nFunc)
&& pAggInfo->aFunc[iAgg].pFExpr==pExpr
){
pExpr = sqlite3ExprDup(db, pExpr, 0);
if( pExpr ){
pAggInfo->aFunc[iAgg].pFExpr = pExpr;
sqlite3ExprDeferredDelete(pParse, pExpr);
}
}
}
}
return WRC_Continue;
}
void sqlite3AggInfoPersistWalkerInit(Walker *pWalker, Parse *pParse){
memset(pWalker, 0, sizeof(*pWalker));
pWalker->pParse = pParse;
pWalker->xExprCallback = agginfoPersistExprCb;
pWalker->xSelectCallback = sqlite3SelectWalkNoop;
}
static int addAggInfoColumn(sqlite3 *db, AggInfo *pInfo){
int i;
pInfo->aCol = sqlite3ArrayAllocate(
db,
pInfo->aCol,
sizeof(pInfo->aCol[0]),
&pInfo->nColumn,
&i
);
return i;
}
static int addAggInfoFunc(sqlite3 *db, AggInfo *pInfo){
int i;
pInfo->aFunc = sqlite3ArrayAllocate(
db,
pInfo->aFunc,
sizeof(pInfo->aFunc[0]),
&pInfo->nFunc,
&i
);
return i;
}
static void findOrCreateAggInfoColumn(
Parse *pParse,
AggInfo *pAggInfo,
Expr *pExpr
){
struct AggInfo_col *pCol;
int k;
assert( pAggInfo->iFirstReg==0 );
pCol = pAggInfo->aCol;
for(k=0; k<pAggInfo->nColumn; k++, pCol++){
if( pCol->pCExpr==pExpr ) return;
if( pCol->iTable==pExpr->iTable
&& pCol->iColumn==pExpr->iColumn
&& pExpr->op!=TK_IF_NULL_ROW
){
goto fix_up_expr;
}
}
k = addAggInfoColumn(pParse->db, pAggInfo);
if( k<0 ){
assert( pParse->db->mallocFailed );
return;
}
pCol = &pAggInfo->aCol[k];
assert( ExprUseYTab(pExpr) );
pCol->pTab = pExpr->y.pTab;
pCol->iTable = pExpr->iTable;
pCol->iColumn = pExpr->iColumn;
pCol->iSorterColumn = -1;
pCol->pCExpr = pExpr;
if( pAggInfo->pGroupBy && pExpr->op!=TK_IF_NULL_ROW ){
int j, n;
ExprList *pGB = pAggInfo->pGroupBy;
struct ExprList_item *pTerm = pGB->a;
n = pGB->nExpr;
for(j=0; j<n; j++, pTerm++){
Expr *pE = pTerm->pExpr;
if( pE->op==TK_COLUMN
&& pE->iTable==pExpr->iTable
&& pE->iColumn==pExpr->iColumn
){
pCol->iSorterColumn = j;
break;
}
}
}
if( pCol->iSorterColumn<0 ){
pCol->iSorterColumn = pAggInfo->nSortingColumn++;
}
fix_up_expr:
ExprSetVVAProperty(pExpr, EP_NoReduce);
assert( pExpr->pAggInfo==0 || pExpr->pAggInfo==pAggInfo );
pExpr->pAggInfo = pAggInfo;
if( pExpr->op==TK_COLUMN ){
pExpr->op = TK_AGG_COLUMN;
}
pExpr->iAgg = (i16)k;
}
static int analyzeAggregate(Walker *pWalker, Expr *pExpr){
int i;
NameContext *pNC = pWalker->u.pNC;
Parse *pParse = pNC->pParse;
SrcList *pSrcList = pNC->pSrcList;
AggInfo *pAggInfo = pNC->uNC.pAggInfo;
assert( pNC->ncFlags & NC_UAggInfo );
assert( pAggInfo->iFirstReg==0 );
switch( pExpr->op ){
default: {
IndexedExpr *pIEpr;
Expr tmp;
assert( pParse->iSelfTab==0 );
if( (pNC->ncFlags & NC_InAggFunc)==0 ) break;
if( pParse->pIdxEpr==0 ) break;
for(pIEpr=pParse->pIdxEpr; pIEpr; pIEpr=pIEpr->pIENext){
int iDataCur = pIEpr->iDataCur;
if( iDataCur<0 ) continue;
if( sqlite3ExprCompare(0, pExpr, pIEpr->pExpr, iDataCur)==0 ) break;
}
if( pIEpr==0 ) break;
if( NEVER(!ExprUseYTab(pExpr)) ) break;
for(i=0; i<pSrcList->nSrc; i++){
if( pSrcList->a[0].iCursor==pIEpr->iDataCur ) break;
}
if( i>=pSrcList->nSrc ) break;
if( NEVER(pExpr->pAggInfo!=0) ) break;
if( pParse->nErr ){ return WRC_Abort; }
memset(&tmp, 0, sizeof(tmp));
tmp.op = TK_AGG_COLUMN;
tmp.iTable = pIEpr->iIdxCur;
tmp.iColumn = pIEpr->iIdxCol;
findOrCreateAggInfoColumn(pParse, pAggInfo, &tmp);
if( pParse->nErr ){ return WRC_Abort; }
assert( pAggInfo->aCol!=0 );
assert( tmp.iAgg<pAggInfo->nColumn );
pAggInfo->aCol[tmp.iAgg].pCExpr = pExpr;
pExpr->pAggInfo = pAggInfo;
pExpr->iAgg = tmp.iAgg;
return WRC_Prune;
}
case TK_IF_NULL_ROW:
case TK_AGG_COLUMN:
case TK_COLUMN: {
testcase( pExpr->op==TK_AGG_COLUMN );
testcase( pExpr->op==TK_COLUMN );
testcase( pExpr->op==TK_IF_NULL_ROW );
if( ALWAYS(pSrcList!=0) ){
SrcItem *pItem = pSrcList->a;
for(i=0; i<pSrcList->nSrc; i++, pItem++){
assert( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) );
if( pExpr->iTable==pItem->iCursor ){
findOrCreateAggInfoColumn(pParse, pAggInfo, pExpr);
break;
}
}
}
return WRC_Continue;
}
case TK_AGG_FUNCTION: {
if( (pNC->ncFlags & NC_InAggFunc)==0
&& pWalker->walkerDepth==pExpr->op2
){
struct AggInfo_func *pItem = pAggInfo->aFunc;
for(i=0; i<pAggInfo->nFunc; i++, pItem++){
if( pItem->pFExpr==pExpr ) break;
if( sqlite3ExprCompare(0, pItem->pFExpr, pExpr, -1)==0 ){
break;
}
}
if( i>=pAggInfo->nFunc ){
u8 enc = ENC(pParse->db);
i = addAggInfoFunc(pParse->db, pAggInfo);
if( i>=0 ){
assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
pItem = &pAggInfo->aFunc[i];
pItem->pFExpr = pExpr;
assert( ExprUseUToken(pExpr) );
pItem->pFunc = sqlite3FindFunction(pParse->db,
pExpr->u.zToken,
pExpr->x.pList ? pExpr->x.pList->nExpr : 0, enc, 0);
if( pExpr->flags & EP_Distinct ){
pItem->iDistinct = pParse->nTab++;
}else{
pItem->iDistinct = -1;
}
}
}
assert( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) );
ExprSetVVAProperty(pExpr, EP_NoReduce);
pExpr->iAgg = (i16)i;
pExpr->pAggInfo = pAggInfo;
return WRC_Prune;
}else{
return WRC_Continue;
}
}
}
return WRC_Continue;
}
void sqlite3ExprAnalyzeAggregates(NameContext *pNC, Expr *pExpr){
Walker w;
w.xExprCallback = analyzeAggregate;
w.xSelectCallback = sqlite3WalkerDepthIncrease;
w.xSelectCallback2 = sqlite3WalkerDepthDecrease;
w.walkerDepth = 0;
w.u.pNC = pNC;
w.pParse = 0;
assert( pNC->pSrcList!=0 );
sqlite3WalkExpr(&w, pExpr);
}
void sqlite3ExprAnalyzeAggList(NameContext *pNC, ExprList *pList){
struct ExprList_item *pItem;
int i;
if( pList ){
for(pItem=pList->a, i=0; i<pList->nExpr; i++, pItem++){
sqlite3ExprAnalyzeAggregates(pNC, pItem->pExpr);
}
}
}
int sqlite3GetTempReg(Parse *pParse){
if( pParse->nTempReg==0 ){
return ++pParse->nMem;
}
return pParse->aTempReg[--pParse->nTempReg];
}
void sqlite3ReleaseTempReg(Parse *pParse, int iReg){
if( iReg ){
sqlite3VdbeReleaseRegisters(pParse, iReg, 1, 0, 0);
if( pParse->nTempReg<ArraySize(pParse->aTempReg) ){
pParse->aTempReg[pParse->nTempReg++] = iReg;
}
}
}
int sqlite3GetTempRange(Parse *pParse, int nReg){
int i, n;
if( nReg==1 ) return sqlite3GetTempReg(pParse);
i = pParse->iRangeReg;
n = pParse->nRangeReg;
if( nReg<=n ){
pParse->iRangeReg += nReg;
pParse->nRangeReg -= nReg;
}else{
i = pParse->nMem+1;
pParse->nMem += nReg;
}
return i;
}
void sqlite3ReleaseTempRange(Parse *pParse, int iReg, int nReg){
if( nReg==1 ){
sqlite3ReleaseTempReg(pParse, iReg);
return;
}
sqlite3VdbeReleaseRegisters(pParse, iReg, nReg, 0, 0);
if( nReg>pParse->nRangeReg ){
pParse->nRangeReg = nReg;
pParse->iRangeReg = iReg;
}
}
void sqlite3ClearTempRegCache(Parse *pParse){
pParse->nTempReg = 0;
pParse->nRangeReg = 0;
}
void sqlite3TouchRegister(Parse *pParse, int iReg){
if( pParse->nMem<iReg ) pParse->nMem = iReg;
}
#if defined(SQLITE_ENABLE_STAT4) || defined(SQLITE_DEBUG)
int sqlite3FirstAvailableRegister(Parse *pParse, int iMin){
const ExprList *pList = pParse->pConstExpr;
if( pList ){
int i;
for(i=0; i<pList->nExpr; i++){
if( pList->a[i].u.iConstExprReg>=iMin ){
iMin = pList->a[i].u.iConstExprReg + 1;
}
}
}
pParse->nTempReg = 0;
pParse->nRangeReg = 0;
return iMin;
}
#endif
#ifdef SQLITE_DEBUG
int sqlite3NoTempsInRange(Parse *pParse, int iFirst, int iLast){
int i;
if( pParse->nRangeReg>0
&& pParse->iRangeReg+pParse->nRangeReg > iFirst
&& pParse->iRangeReg <= iLast
){
return 0;
}
for(i=0; i<pParse->nTempReg; i++){
if( pParse->aTempReg[i]>=iFirst && pParse->aTempReg[i]<=iLast ){
return 0;
}
}
if( pParse->pConstExpr ){
ExprList *pList = pParse->pConstExpr;
for(i=0; i<pList->nExpr; i++){
int iReg = pList->a[i].u.iConstExprReg;
if( iReg==0 ) continue;
if( iReg>=iFirst && iReg<=iLast ) return 0;
}
}
return 1;
}
#endif