diff options
Diffstat (limited to 'ext/pdo_sqlite/sqlite/src/expr.c')
-rw-r--r-- | ext/pdo_sqlite/sqlite/src/expr.c | 310 |
1 files changed, 199 insertions, 111 deletions
diff --git a/ext/pdo_sqlite/sqlite/src/expr.c b/ext/pdo_sqlite/sqlite/src/expr.c index 1276fe9f6..e26aba5b3 100644 --- a/ext/pdo_sqlite/sqlite/src/expr.c +++ b/ext/pdo_sqlite/sqlite/src/expr.c @@ -75,12 +75,10 @@ CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){ char sqlite3CompareAffinity(Expr *pExpr, char aff2){ char aff1 = sqlite3ExprAffinity(pExpr); if( aff1 && aff2 ){ - /* Both sides of the comparison are columns. If one has numeric or - ** integer affinity, use that. Otherwise use no affinity. + /* Both sides of the comparison are columns. If one has numeric + ** affinity, use that. Otherwise use no affinity. */ - if( aff1==SQLITE_AFF_INTEGER || aff2==SQLITE_AFF_INTEGER ){ - return SQLITE_AFF_INTEGER; - }else if( aff1==SQLITE_AFF_NUMERIC || aff2==SQLITE_AFF_NUMERIC ){ + if( sqlite3IsNumericAffinity(aff1) || sqlite3IsNumericAffinity(aff2) ){ return SQLITE_AFF_NUMERIC; }else{ return SQLITE_AFF_NONE; @@ -89,7 +87,6 @@ char sqlite3CompareAffinity(Expr *pExpr, char aff2){ /* Neither side of the comparison is a column. Compare the ** results directly. */ - /* return SQLITE_AFF_NUMERIC; // Ticket #805 */ return SQLITE_AFF_NONE; }else{ /* One side is a column, the other is not. Use the columns affinity. */ @@ -129,11 +126,14 @@ static char comparisonAffinity(Expr *pExpr){ */ int sqlite3IndexAffinityOk(Expr *pExpr, char idx_affinity){ char aff = comparisonAffinity(pExpr); - return - (aff==SQLITE_AFF_NONE) || - (aff==SQLITE_AFF_NUMERIC && idx_affinity==SQLITE_AFF_INTEGER) || - (aff==SQLITE_AFF_INTEGER && idx_affinity==SQLITE_AFF_NUMERIC) || - (aff==idx_affinity); + switch( aff ){ + case SQLITE_AFF_NONE: + return 1; + case SQLITE_AFF_TEXT: + return idx_affinity==SQLITE_AFF_TEXT; + default: + return sqlite3IsNumericAffinity(idx_affinity); + } } /* @@ -212,6 +212,19 @@ Expr *sqlite3Expr(int op, Expr *pLeft, Expr *pRight, const Token *pToken){ } /* +** Works like sqlite3Expr() but frees its pLeft and pRight arguments +** if it fails due to a malloc problem. +*/ +Expr *sqlite3ExprOrFree(int op, Expr *pLeft, Expr *pRight, const Token *pToken){ + Expr *pNew = sqlite3Expr(op, pLeft, pRight, pToken); + if( pNew==0 ){ + sqlite3ExprDelete(pLeft); + sqlite3ExprDelete(pRight); + } + return pNew; +} + +/* ** When doing a nested parse, you can include terms in an expression ** that look like this: #0 #1 #2 ... These terms refer to elements ** on the stack. "#0" means the top of the stack. @@ -235,7 +248,7 @@ Expr *sqlite3RegisterExpr(Parse *pParse, Token *pToken){ if( p==0 ){ return 0; /* Malloc failed */ } - depth = atoi(&pToken->z[1]); + depth = atoi((char*)&pToken->z[1]); p->iTable = pParse->nMem++; sqlite3VdbeAddOp(v, OP_Dup, depth, 0); sqlite3VdbeAddOp(v, OP_MemStore, p->iTable, 1); @@ -263,7 +276,7 @@ Expr *sqlite3ExprAnd(Expr *pLeft, Expr *pRight){ void sqlite3ExprSpan(Expr *pExpr, Token *pLeft, Token *pRight){ assert( pRight!=0 ); assert( pLeft!=0 ); - if( !sqlite3_malloc_failed && pRight->z && pLeft->z ){ + if( !sqlite3MallocFailed() && pRight->z && pLeft->z ){ assert( pLeft->dyn==0 || pLeft->z[pLeft->n]==0 ); if( pLeft->dyn==0 && pRight->dyn==0 ){ pExpr->span.z = pLeft->z; @@ -280,6 +293,7 @@ void sqlite3ExprSpan(Expr *pExpr, Token *pLeft, Token *pRight){ */ Expr *sqlite3ExprFunction(ExprList *pList, Token *pToken){ Expr *pNew; + assert( pToken ); pNew = sqliteMalloc( sizeof(Expr) ); if( pNew==0 ){ sqlite3ExprListDelete(pList); /* Avoid leaking memory when malloc fails */ @@ -287,12 +301,8 @@ Expr *sqlite3ExprFunction(ExprList *pList, Token *pToken){ } pNew->op = TK_FUNCTION; pNew->pList = pList; - if( pToken ){ - assert( pToken->dyn==0 ); - pNew->token = *pToken; - }else{ - pNew->token.z = 0; - } + assert( pToken->dyn==0 ); + pNew->token = *pToken; pNew->span = pNew->token; return pNew; } @@ -327,7 +337,7 @@ void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr){ /* Wildcard of the form "?nnn". Convert "nnn" to an integer and ** use it as the variable number */ int i; - pExpr->iTable = i = atoi(&pToken->z[1]); + pExpr->iTable = i = atoi((char*)&pToken->z[1]); if( i<1 || i>SQLITE_MAX_VARIABLE_NUMBER ){ sqlite3ErrorMsg(pParse, "variable number must be between ?1 and ?%d", SQLITE_MAX_VARIABLE_NUMBER); @@ -355,10 +365,10 @@ void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr){ pExpr->iTable = ++pParse->nVar; if( pParse->nVarExpr>=pParse->nVarExprAlloc-1 ){ pParse->nVarExprAlloc += pParse->nVarExprAlloc + 10; - sqlite3ReallocOrFree((void**)&pParse->apVarExpr, + sqliteReallocOrFree((void**)&pParse->apVarExpr, pParse->nVarExprAlloc*sizeof(pParse->apVarExpr[0]) ); } - if( !sqlite3_malloc_failed ){ + if( !sqlite3MallocFailed() ){ assert( pParse->apVarExpr!=0 ); pParse->apVarExpr[pParse->nVarExpr++] = pExpr; } @@ -415,7 +425,7 @@ Expr *sqlite3ExprDup(Expr *p){ if( pNew==0 ) return 0; memcpy(pNew, p, sizeof(*pNew)); if( p->token.z!=0 ){ - pNew->token.z = sqliteStrNDup(p->token.z, p->token.n); + pNew->token.z = (u8*)sqliteStrNDup((char*)p->token.z, p->token.n); pNew->token.dyn = 1; }else{ assert( pNew->token.z==0 ); @@ -432,7 +442,7 @@ void sqlite3TokenCopy(Token *pTo, Token *pFrom){ if( pTo->dyn ) sqliteFree((char*)pTo->z); if( pFrom->z ){ pTo->n = pFrom->n; - pTo->z = sqliteStrNDup(pFrom->z, pFrom->n); + pTo->z = (u8*)sqliteStrNDup((char*)pFrom->z, pFrom->n); pTo->dyn = 1; }else{ pTo->z = 0; @@ -462,7 +472,8 @@ ExprList *sqlite3ExprListDup(ExprList *p){ sqlite3TokenCopy(&pNewExpr->span, &pOldExpr->span); } assert( pNewExpr==0 || pNewExpr->span.z!=0 - || pOldExpr->span.z==0 || sqlite3_malloc_failed ); + || pOldExpr->span.z==0 + || sqlite3MallocFailed() ); pItem->zName = sqliteStrDup(pOldItem->zName); pItem->sortOrder = pOldItem->sortOrder; pItem->isAgg = pOldItem->isAgg; @@ -497,6 +508,7 @@ SrcList *sqlite3SrcListDup(SrcList *p){ pNewItem->zAlias = sqliteStrDup(pOldItem->zAlias); pNewItem->jointype = pOldItem->jointype; pNewItem->iCursor = pOldItem->iCursor; + pNewItem->isPopulated = pOldItem->isPopulated; pTab = pNewItem->pTab = pOldItem->pTab; if( pTab ){ pTab->nRef++; @@ -548,12 +560,12 @@ Select *sqlite3SelectDup(Select *p){ pNew->iOffset = -1; pNew->isResolved = p->isResolved; pNew->isAgg = p->isAgg; - pNew->usesVirt = 0; + pNew->usesEphm = 0; pNew->disallowOrderBy = 0; pNew->pRightmost = 0; - pNew->addrOpenVirt[0] = -1; - pNew->addrOpenVirt[1] = -1; - pNew->addrOpenVirt[2] = -1; + pNew->addrOpenEphm[0] = -1; + pNew->addrOpenEphm[1] = -1; + pNew->addrOpenEphm[2] = -1; return pNew; } #else @@ -752,7 +764,7 @@ int sqlite3ExprIsConstantOrFunction(Expr *p){ int sqlite3ExprIsInteger(Expr *p, int *pValue){ switch( p->op ){ case TK_INTEGER: { - if( sqlite3GetInt32(p->token.z, pValue) ){ + if( sqlite3GetInt32((char*)p->token.z, pValue) ){ return 1; } break; @@ -809,7 +821,7 @@ int sqlite3IsRowid(const char *z){ ** in pParse and return non-zero. Return zero on success. */ static int lookupName( - Parse *pParse, /* The parsing context */ + Parse *pParse, /* The parsing context */ Token *pDbToken, /* Name of the database containing table, or NULL */ Token *pTableToken, /* Name of table containing column, or NULL */ Token *pColumnToken, /* Name of the column. */ @@ -831,22 +843,24 @@ static int lookupName( zDb = sqlite3NameFromToken(pDbToken); zTab = sqlite3NameFromToken(pTableToken); zCol = sqlite3NameFromToken(pColumnToken); - if( sqlite3_malloc_failed ){ + if( sqlite3MallocFailed() ){ goto lookupname_end; } pExpr->iTable = -1; while( pNC && cnt==0 ){ + ExprList *pEList; SrcList *pSrcList = pNC->pSrcList; - ExprList *pEList = pNC->pEList; - /* assert( zTab==0 || pEList==0 ); */ if( pSrcList ){ for(i=0, pItem=pSrcList->a; i<pSrcList->nSrc; i++, pItem++){ - Table *pTab = pItem->pTab; + Table *pTab; + int iDb; Column *pCol; - if( pTab==0 ) continue; + pTab = pItem->pTab; + assert( pTab!=0 ); + iDb = sqlite3SchemaToIndex(db, pTab->pSchema); assert( pTab->nCol>0 ); if( zTab ){ if( pItem->zAlias ){ @@ -855,27 +869,28 @@ static int lookupName( }else{ char *zTabName = pTab->zName; if( zTabName==0 || sqlite3StrICmp(zTabName, zTab)!=0 ) continue; - if( zDb!=0 && sqlite3StrICmp(db->aDb[pTab->iDb].zName, zDb)!=0 ){ + if( zDb!=0 && sqlite3StrICmp(db->aDb[iDb].zName, zDb)!=0 ){ continue; } } } if( 0==(cntTab++) ){ pExpr->iTable = pItem->iCursor; - pExpr->iDb = pTab->iDb; + pExpr->pSchema = pTab->pSchema; pMatch = pItem; } for(j=0, pCol=pTab->aCol; j<pTab->nCol; j++, pCol++){ if( sqlite3StrICmp(pCol->zName, zCol)==0 ){ + const char *zColl = pTab->aCol[j].zColl; IdList *pUsing; cnt++; pExpr->iTable = pItem->iCursor; pMatch = pItem; - pExpr->iDb = pTab->iDb; + pExpr->pSchema = pTab->pSchema; /* Substitute the rowid (column -1) for the INTEGER PRIMARY KEY */ pExpr->iColumn = j==pTab->iPKey ? -1 : j; pExpr->affinity = pTab->aCol[j].affinity; - pExpr->pColl = pTab->aCol[j].pColl; + pExpr->pColl = sqlite3FindCollSeq(db, ENC(db), zColl,-1, 0); if( pItem->jointype & JT_NATURAL ){ /* If this match occurred in the left table of a natural join, ** then skip the right table to avoid a duplicate match */ @@ -919,17 +934,18 @@ static int lookupName( } if( pTab ){ - int j; + int iCol; Column *pCol = pTab->aCol; - pExpr->iDb = pTab->iDb; + pExpr->pSchema = pTab->pSchema; cntTab++; - for(j=0; j < pTab->nCol; j++, pCol++) { + for(iCol=0; iCol < pTab->nCol; iCol++, pCol++) { if( sqlite3StrICmp(pCol->zName, zCol)==0 ){ + const char *zColl = pTab->aCol[iCol].zColl; cnt++; - pExpr->iColumn = j==pTab->iPKey ? -1 : j; - pExpr->affinity = pTab->aCol[j].affinity; - pExpr->pColl = pTab->aCol[j].pColl; + pExpr->iColumn = iCol==pTab->iPKey ? -1 : iCol; + pExpr->affinity = pTab->aCol[iCol].affinity; + pExpr->pColl = sqlite3FindCollSeq(db, ENC(db), zColl,-1, 0); pExpr->pTab = pTab; break; } @@ -959,7 +975,7 @@ static int lookupName( ** Note that the expression in the result set should have already been ** resolved by the time the WHERE clause is resolved. */ - if( cnt==0 && pEList!=0 && zTab==0 ){ + if( cnt==0 && (pEList = pNC->pEList)!=0 && zTab==0 ){ for(j=0; j<pEList->nExpr; j++){ char *zAs = pEList->a[j].zName; if( zAs!=0 && sqlite3StrICmp(zAs, zCol)==0 ){ @@ -1006,9 +1022,9 @@ static int lookupName( char *zErr; zErr = cnt==0 ? "no such column: %s" : "ambiguous column name: %s"; if( zDb ){ - sqlite3SetString(&z, zDb, ".", zTab, ".", zCol, 0); + sqlite3SetString(&z, zDb, ".", zTab, ".", zCol, (char*)0); }else if( zTab ){ - sqlite3SetString(&z, zTab, ".", zCol, 0); + sqlite3SetString(&z, zTab, ".", zCol, (char*)0); }else{ z = sqliteStrDup(zCol); } @@ -1077,20 +1093,19 @@ lookupname_end_2: */ static int nameResolverStep(void *pArg, Expr *pExpr){ NameContext *pNC = (NameContext*)pArg; - SrcList *pSrcList; Parse *pParse; if( pExpr==0 ) return 1; assert( pNC!=0 ); - pSrcList = pNC->pSrcList; pParse = pNC->pParse; if( ExprHasAnyProperty(pExpr, EP_Resolved) ) return 1; ExprSetProperty(pExpr, EP_Resolved); #ifndef NDEBUG - if( pSrcList ){ + if( pNC->pSrcList && pNC->pSrcList->nAlloc>0 ){ + SrcList *pSrcList = pNC->pSrcList; int i; - for(i=0; i<pSrcList->nSrc; i++){ + for(i=0; i<pNC->pSrcList->nSrc; i++){ assert( pSrcList->a[i].iCursor>=0 && pSrcList->a[i].iCursor<pParse->nTab); } } @@ -1149,9 +1164,9 @@ static int nameResolverStep(void *pArg, Expr *pExpr){ int nId; /* Number of characters in function name */ const char *zId; /* The function name. */ FuncDef *pDef; /* Information about the function */ - int enc = pParse->db->enc; /* The database encoding */ + int enc = ENC(pParse->db); /* The database encoding */ - zId = pExpr->token.z; + zId = (char*)pExpr->token.z; nId = pExpr->token.n; pDef = sqlite3FindFunction(pParse->db, zId, nId, n, enc, 0); if( pDef==0 ){ @@ -1197,13 +1212,27 @@ static int nameResolverStep(void *pArg, Expr *pExpr){ case TK_IN: { if( pExpr->pSelect ){ int nRef = pNC->nRef; +#ifndef SQLITE_OMIT_CHECK + if( pNC->isCheck ){ + sqlite3ErrorMsg(pParse,"subqueries prohibited in CHECK constraints"); + } +#endif sqlite3SelectResolve(pParse, pExpr->pSelect, pNC); assert( pNC->nRef>=nRef ); if( nRef!=pNC->nRef ){ ExprSetProperty(pExpr, EP_VarSelect); } } + break; + } +#ifndef SQLITE_OMIT_CHECK + case TK_VARIABLE: { + if( pNC->isCheck ){ + sqlite3ErrorMsg(pParse,"parameters prohibited in CHECK constraints"); + } + break; } +#endif } return 0; } @@ -1261,17 +1290,16 @@ struct QueryCoder { /* -** Generate code for subqueries and IN operators. +** Generate code for scalar subqueries used as an expression +** and IN operators. Examples: ** -** IN operators comes in two forms: +** (SELECT a FROM b) -- subquery +** EXISTS (SELECT a FROM b) -- EXISTS subquery +** x IN (4,5,11) -- IN operator with list on right-hand side +** x IN (SELECT a FROM b) -- IN operator with subquery on the right ** -** expr IN (exprlist) -** and -** expr IN (SELECT ...) -** -** The first form is handled by creating a set holding the list -** of allowed values. The second form causes the SELECT to generate -** a temporary table. +** The pExpr parameter describes the expression that contains the IN +** operator or subquery. */ #ifndef SQLITE_OMIT_SUBQUERY void sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){ @@ -1293,7 +1321,7 @@ void sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){ int mem = pParse->nMem++; sqlite3VdbeAddOp(v, OP_MemLoad, mem, 0); testAddr = sqlite3VdbeAddOp(v, OP_If, 0, 0); - assert( testAddr>0 || sqlite3_malloc_failed ); + assert( testAddr>0 || sqlite3MallocFailed() ); sqlite3VdbeAddOp(v, OP_MemInt, 1, mem); } @@ -1301,7 +1329,7 @@ void sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){ case TK_IN: { char affinity; KeyInfo keyInfo; - int addr; /* Address of OP_OpenVirtual instruction */ + int addr; /* Address of OP_OpenEphemeral instruction */ affinity = sqlite3ExprAffinity(pExpr->pLeft); @@ -1319,7 +1347,7 @@ void sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){ ** is used. */ pExpr->iTable = pParse->nTab++; - addr = sqlite3VdbeAddOp(v, OP_OpenVirtual, pExpr->iTable, 0); + addr = sqlite3VdbeAddOp(v, OP_OpenEphemeral, pExpr->iTable, 0); memset(&keyInfo, 0, sizeof(keyInfo)); keyInfo.nField = 1; sqlite3VdbeAddOp(v, OP_SetNumColumns, pExpr->iTable, 1); @@ -1352,7 +1380,7 @@ void sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){ struct ExprList_item *pItem; if( !affinity ){ - affinity = SQLITE_AFF_NUMERIC; + affinity = SQLITE_AFF_NONE; } keyInfo.aColl[0] = pExpr->pLeft->pColl; @@ -1366,11 +1394,7 @@ void sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){ ** expression we need to rerun this code each time. */ if( testAddr>0 && !sqlite3ExprIsConstant(pE2) ){ - VdbeOp *aOp = sqlite3VdbeGetOp(v, testAddr-1); - int i; - for(i=0; i<3; i++){ - aOp[i].opcode = OP_Noop; - } + sqlite3VdbeChangeToNoop(v, testAddr-1, 3); testAddr = 0; } @@ -1390,21 +1414,25 @@ void sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){ ** value of this select in a memory cell and record the number ** of the memory cell in iColumn. */ - int sop; + static const Token one = { (u8*)"1", 0, 1 }; Select *pSel; + int iMem; + int sop; - pExpr->iColumn = pParse->nMem++; + pExpr->iColumn = iMem = pParse->nMem++; pSel = pExpr->pSelect; if( pExpr->op==TK_SELECT ){ sop = SRT_Mem; + sqlite3VdbeAddOp(v, OP_MemNull, iMem, 0); + VdbeComment((v, "# Init subquery result")); }else{ - static const Token one = { "1", 0, 1 }; sop = SRT_Exists; - sqlite3ExprListDelete(pSel->pEList); - pSel->pEList = sqlite3ExprListAppend(0, - sqlite3Expr(TK_INTEGER, 0, 0, &one), 0); + sqlite3VdbeAddOp(v, OP_MemInt, 0, iMem); + VdbeComment((v, "# Init EXISTS result")); } - sqlite3Select(pParse, pSel, sop, pExpr->iColumn, 0, 0, 0, 0); + sqlite3ExprDelete(pSel->pLimit); + pSel->pLimit = sqlite3Expr(TK_INTEGER, 0, 0, &one); + sqlite3Select(pParse, pSel, sop, iMem, 0, 0, 0, 0); break; } } @@ -1444,6 +1472,8 @@ static void codeInteger(Vdbe *v, const char *z, int n){ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){ Vdbe *v = pParse->pVdbe; int op; + int stackChng = 1; /* Amount of change to stack depth */ + if( v==0 ) return; if( pExpr==0 ){ sqlite3VdbeAddOp(v, OP_Null, 0, 0); @@ -1465,16 +1495,30 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){ /* Otherwise, fall thru into the TK_COLUMN case */ } case TK_COLUMN: { - if( pExpr->iColumn>=0 ){ - sqlite3VdbeAddOp(v, OP_Column, pExpr->iTable, pExpr->iColumn); - sqlite3ColumnDefault(v, pExpr->pTab, pExpr->iColumn); + if( pExpr->iTable<0 ){ + /* This only happens when coding check constraints */ + assert( pParse->ckOffset>0 ); + sqlite3VdbeAddOp(v, OP_Dup, pParse->ckOffset-pExpr->iColumn-1, 1); + }else if( pExpr->iColumn>=0 ){ + Table *pTab = pExpr->pTab; + int iCol = pExpr->iColumn; + int op = (pTab && IsVirtual(pTab)) ? OP_VColumn : OP_Column; + sqlite3VdbeAddOp(v, op, pExpr->iTable, iCol); + sqlite3ColumnDefault(v, pTab, iCol); +#ifndef SQLITE_OMIT_FLOATING_POINT + if( pTab && pTab->aCol[iCol].affinity==SQLITE_AFF_REAL ){ + sqlite3VdbeAddOp(v, OP_RealAffinity, 0, 0); + } +#endif }else{ - sqlite3VdbeAddOp(v, OP_Rowid, pExpr->iTable, 0); + Table *pTab = pExpr->pTab; + int op = (pTab && IsVirtual(pTab)) ? OP_VRowid : OP_Rowid; + sqlite3VdbeAddOp(v, op, pExpr->iTable, 0); } break; } case TK_INTEGER: { - codeInteger(v, pExpr->token.z, pExpr->token.n); + codeInteger(v, (char*)pExpr->token.z, pExpr->token.n); break; } case TK_FLOAT: @@ -1482,7 +1526,7 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){ assert( TK_FLOAT==OP_Real ); assert( TK_STRING==OP_String8 ); sqlite3DequoteExpr(pExpr); - sqlite3VdbeOp3(v, op, 0, 0, pExpr->token.z, pExpr->token.n); + sqlite3VdbeOp3(v, op, 0, 0, (char*)pExpr->token.z, pExpr->token.n); break; } case TK_NULL: { @@ -1495,7 +1539,7 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){ const char *z; assert( TK_BLOB==OP_HexBlob ); n = pExpr->token.n - 3; - z = pExpr->token.z + 2; + z = (char*)pExpr->token.z + 2; assert( n>=0 ); if( n==0 ){ z = ""; @@ -1507,7 +1551,7 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){ case TK_VARIABLE: { sqlite3VdbeAddOp(v, OP_Variable, pExpr->iTable, 0); if( pExpr->token.n>1 ){ - sqlite3VdbeChangeP3(v, -1, pExpr->token.z, pExpr->token.n); + sqlite3VdbeChangeP3(v, -1, (char*)pExpr->token.z, pExpr->token.n); } break; } @@ -1518,16 +1562,17 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){ #ifndef SQLITE_OMIT_CAST case TK_CAST: { /* Expressions of the form: CAST(pLeft AS token) */ - int aff, op; + int aff, to_op; sqlite3ExprCode(pParse, pExpr->pLeft); aff = sqlite3AffinityType(&pExpr->token); - switch( aff ){ - case SQLITE_AFF_INTEGER: op = OP_ToInt; break; - case SQLITE_AFF_NUMERIC: op = OP_ToNumeric; break; - case SQLITE_AFF_TEXT: op = OP_ToText; break; - case SQLITE_AFF_NONE: op = OP_ToBlob; break; - } - sqlite3VdbeAddOp(v, op, 0, 0); + to_op = aff - SQLITE_AFF_TEXT + OP_ToText; + assert( to_op==OP_ToText || aff!=SQLITE_AFF_TEXT ); + assert( to_op==OP_ToBlob || aff!=SQLITE_AFF_NONE ); + assert( to_op==OP_ToNumeric || aff!=SQLITE_AFF_NUMERIC ); + assert( to_op==OP_ToInt || aff!=SQLITE_AFF_INTEGER ); + assert( to_op==OP_ToReal || aff!=SQLITE_AFF_REAL ); + sqlite3VdbeAddOp(v, to_op, 0, 0); + stackChng = 0; break; } #endif /* SQLITE_OMIT_CAST */ @@ -1546,6 +1591,7 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){ sqlite3ExprCode(pParse, pExpr->pLeft); sqlite3ExprCode(pParse, pExpr->pRight); codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op, 0, 0); + stackChng = -1; break; } case TK_AND: @@ -1574,6 +1620,7 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){ sqlite3ExprCode(pParse, pExpr->pLeft); sqlite3ExprCode(pParse, pExpr->pRight); sqlite3VdbeAddOp(v, op, 0, 0); + stackChng = -1; break; } case TK_UMINUS: { @@ -1581,8 +1628,7 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){ assert( pLeft ); if( pLeft->op==TK_FLOAT || pLeft->op==TK_INTEGER ){ Token *p = &pLeft->token; - char *z = sqliteMalloc( p->n + 2 ); - sprintf(z, "-%.*s", p->n, p->z); + char *z = sqlite3MPrintf("-%.*s", p->n, p->z); if( pLeft->op==TK_FLOAT ){ sqlite3VdbeOp3(v, OP_Real, 0, 0, z, p->n+1); }else{ @@ -1599,6 +1645,7 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){ assert( TK_NOT==OP_Not ); sqlite3ExprCode(pParse, pExpr->pLeft); sqlite3VdbeAddOp(v, op, 0, 0); + stackChng = 0; break; } case TK_ISNULL: @@ -1611,11 +1658,17 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){ dest = sqlite3VdbeCurrentAddr(v) + 2; sqlite3VdbeAddOp(v, op, 1, dest); sqlite3VdbeAddOp(v, OP_AddImm, -1, 0); + stackChng = 0; break; } case TK_AGG_FUNCTION: { AggInfo *pInfo = pExpr->pAggInfo; - sqlite3VdbeAddOp(v, OP_MemLoad, pInfo->aFunc[pExpr->iAgg].iMem, 0); + if( pInfo==0 ){ + sqlite3ErrorMsg(pParse, "misuse of aggregate: %T", + &pExpr->span); + }else{ + sqlite3VdbeAddOp(v, OP_MemLoad, pInfo->aFunc[pExpr->iAgg].iMem, 0); + } break; } case TK_CONST_FUNC: @@ -1627,13 +1680,32 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){ const char *zId; int constMask = 0; int i; - u8 enc = pParse->db->enc; + u8 enc = ENC(pParse->db); CollSeq *pColl = 0; - zId = pExpr->token.z; + zId = (char*)pExpr->token.z; nId = pExpr->token.n; pDef = sqlite3FindFunction(pParse->db, zId, nId, nExpr, enc, 0); assert( pDef!=0 ); nExpr = sqlite3ExprCodeExprList(pParse, pList); +#ifndef SQLITE_OMIT_VIRTUALTABLE + /* Possibly overload the function if the first argument is + ** a virtual table column. + ** + ** For infix functions (LIKE, GLOB, REGEXP, and MATCH) use the + ** second argument, not the first, as the argument to test to + ** see if it is a column in a virtual table. This is done because + ** the left operand of infix functions (the operand we want to + ** control overloading) ends up as the second argument to the + ** function. The expression "A glob B" is equivalent to + ** "glob(B,A). We want to use the A in "A glob B" to test + ** for function overloading. But we use the B term in "glob(B,A)". + */ + if( nExpr>=2 && (pExpr->flags & EP_InfixFunc) ){ + pDef = sqlite3VtabOverloadFunction(pDef, nExpr, pList->a[1].pExpr); + }else if( nExpr>0 ){ + pDef = sqlite3VtabOverloadFunction(pDef, nExpr, pList->a[0].pExpr); + } +#endif for(i=0; i<nExpr && i<32; i++){ if( sqlite3ExprIsConstant(pList->a[i].pExpr) ){ constMask |= (1<<i); @@ -1647,12 +1719,15 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){ sqlite3VdbeOp3(v, OP_CollSeq, 0, 0, (char *)pColl, P3_COLLSEQ); } sqlite3VdbeOp3(v, OP_Function, constMask, nExpr, (char*)pDef, P3_FUNCDEF); + stackChng = 1-nExpr; break; } #ifndef SQLITE_OMIT_SUBQUERY case TK_EXISTS: case TK_SELECT: { - sqlite3CodeSubselect(pParse, pExpr); + if( pExpr->iColumn==0 ){ + sqlite3CodeSubselect(pParse, pExpr); + } sqlite3VdbeAddOp(v, OP_MemLoad, pExpr->iColumn, 0); VdbeComment((v, "# load subquery result")); break; @@ -1660,6 +1735,7 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){ case TK_IN: { int addr; char affinity; + int ckOffset = pParse->ckOffset; sqlite3CodeSubselect(pParse, pExpr); /* Figure out the affinity to use to create a key from the results @@ -1669,6 +1745,7 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){ affinity = comparisonAffinity(pExpr); sqlite3VdbeAddOp(v, OP_Integer, 1, 0); + pParse->ckOffset = ckOffset+1; /* Code the <expr> from "<expr> IN (...)". The temporary table ** pExpr->iTable contains the values that make up the (...) set. @@ -1705,6 +1782,7 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){ case TK_UPLUS: case TK_AS: { sqlite3ExprCode(pParse, pExpr->pLeft); + stackChng = 0; break; } case TK_CASE: { @@ -1763,16 +1841,22 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){ pExpr->iColumn == OE_Fail ); sqlite3DequoteExpr(pExpr); sqlite3VdbeOp3(v, OP_Halt, SQLITE_CONSTRAINT, pExpr->iColumn, - pExpr->token.z, pExpr->token.n); + (char*)pExpr->token.z, pExpr->token.n); } else { assert( pExpr->iColumn == OE_Ignore ); sqlite3VdbeAddOp(v, OP_ContextPop, 0, 0); sqlite3VdbeAddOp(v, OP_Goto, 0, pParse->trigStack->ignoreJump); VdbeComment((v, "# raise(IGNORE)")); } + stackChng = 0; + break; } #endif - break; + } + + if( pParse->ckOffset ){ + pParse->ckOffset += stackChng; + assert( pParse->ckOffset ); } } @@ -1840,6 +1924,7 @@ int sqlite3ExprCodeExprList( void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ Vdbe *v = pParse->pVdbe; int op = 0; + int ckOffset = pParse->ckOffset; if( v==0 || pExpr==0 ) return; op = pExpr->op; switch( op ){ @@ -1914,6 +1999,7 @@ void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ break; } } + pParse->ckOffset = ckOffset; } /* @@ -1927,6 +2013,7 @@ void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ Vdbe *v = pParse->pVdbe; int op = 0; + int ckOffset = pParse->ckOffset; if( v==0 || pExpr==0 ) return; /* The value of pExpr->op and op are related as follows: @@ -2023,6 +2110,7 @@ void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ break; } } + pParse->ckOffset = ckOffset; } /* @@ -2031,10 +2119,8 @@ void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ */ int sqlite3ExprCompare(Expr *pA, Expr *pB){ int i; - if( pA==0 ){ - return pB==0; - }else if( pB==0 ){ - return 0; + if( pA==0||pB==0 ){ + return pB==pA; } if( pA->op!=pB->op ) return 0; if( (pA->flags & EP_Distinct)!=(pB->flags & EP_Distinct) ) return 0; @@ -2056,7 +2142,9 @@ int sqlite3ExprCompare(Expr *pA, Expr *pB){ if( pA->token.z ){ if( pB->token.z==0 ) return 0; if( pB->token.n!=pA->token.n ) return 0; - if( sqlite3StrNICmp(pA->token.z, pB->token.z, pB->token.n)!=0 ) return 0; + if( sqlite3StrNICmp((char*)pA->token.z,(char*)pB->token.z,pB->token.n)!=0 ){ + return 0; + } } return 1; } @@ -2180,14 +2268,14 @@ static int analyzeAggregate(void *pArg, Expr *pExpr){ if( i>=pAggInfo->nFunc ){ /* pExpr is original. Make a new entry in pAggInfo->aFunc[] */ - u8 enc = pParse->db->enc; + u8 enc = ENC(pParse->db); i = addAggInfoFunc(pAggInfo); if( i>=0 ){ pItem = &pAggInfo->aFunc[i]; pItem->pExpr = pExpr; pItem->iMem = pParse->nMem++; pItem->pFunc = sqlite3FindFunction(pParse->db, - pExpr->token.z, pExpr->token.n, + (char*)pExpr->token.z, pExpr->token.n, pExpr->pList ? pExpr->pList->nExpr : 0, enc, 0); if( pExpr->flags & EP_Distinct ){ pItem->iDistinct = pParse->nTab++; |