diff options
Diffstat (limited to 'ext/pdo_sqlite/sqlite/src/expr.c')
| -rw-r--r-- | ext/pdo_sqlite/sqlite/src/expr.c | 90 |
1 files changed, 61 insertions, 29 deletions
diff --git a/ext/pdo_sqlite/sqlite/src/expr.c b/ext/pdo_sqlite/sqlite/src/expr.c index 6d21918cd0..54a9f6abe1 100644 --- a/ext/pdo_sqlite/sqlite/src/expr.c +++ b/ext/pdo_sqlite/sqlite/src/expr.c @@ -131,7 +131,7 @@ static char comparisonAffinity(Expr *pExpr){ aff = sqlite3CompareAffinity(pExpr->pSelect->pEList->a[0].pExpr, aff); } else if( !aff ){ - aff = SQLITE_AFF_NUMERIC; + aff = SQLITE_AFF_NONE; } return aff; } @@ -404,7 +404,7 @@ void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr){ pExpr->iTable = ++pParse->nVar; if( pParse->nVarExpr>=pParse->nVarExprAlloc-1 ){ pParse->nVarExprAlloc += pParse->nVarExprAlloc + 10; - sqliteReallocOrFree((void**)&pParse->apVarExpr, + pParse->apVarExpr = sqliteReallocOrFree(pParse->apVarExpr, pParse->nVarExprAlloc*sizeof(pParse->apVarExpr[0]) ); } if( !sqlite3MallocFailed() ){ @@ -1518,6 +1518,31 @@ static void codeInteger(Vdbe *v, const char *z, int n){ } } + +/* +** Generate code that will extract the iColumn-th column from +** table pTab and push that column value on the stack. There +** is an open cursor to pTab in iTable. If iColumn<0 then +** code is generated that extracts the rowid. +*/ +void sqlite3ExprCodeGetColumn(Vdbe *v, Table *pTab, int iColumn, int iTable){ + if( iColumn<0 ){ + int op = (pTab && IsVirtual(pTab)) ? OP_VRowid : OP_Rowid; + sqlite3VdbeAddOp(v, op, iTable, 0); + }else if( pTab==0 ){ + sqlite3VdbeAddOp(v, OP_Column, iTable, iColumn); + }else{ + int op = IsVirtual(pTab) ? OP_VColumn : OP_Column; + sqlite3VdbeAddOp(v, op, iTable, iColumn); + sqlite3ColumnDefault(v, pTab, iColumn); +#ifndef SQLITE_OMIT_FLOATING_POINT + if( pTab->aCol[iColumn].affinity==SQLITE_AFF_REAL ){ + sqlite3VdbeAddOp(v, OP_RealAffinity, 0, 0); + } +#endif + } +} + /* ** Generate code into the current Vdbe to evaluate the given ** expression and leave the result on the top of stack. @@ -1558,21 +1583,8 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){ /* 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{ - Table *pTab = pExpr->pTab; - int op = (pTab && IsVirtual(pTab)) ? OP_VRowid : OP_Rowid; - sqlite3VdbeAddOp(v, op, pExpr->iTable, 0); + sqlite3ExprCodeGetColumn(v, pExpr->pTab, pExpr->iColumn, pExpr->iTable); } break; } @@ -2175,6 +2187,16 @@ void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ /* ** Do a deep comparison of two expression trees. Return TRUE (non-zero) ** if they are identical and return FALSE if they differ in any way. +** +** Sometimes this routine will return FALSE even if the two expressions +** really are equivalent. If we cannot prove that the expressions are +** identical, we return FALSE just to be safe. So if this routine +** returns false, then you do not really know for certain if the two +** expressions are the same. But if you get a TRUE return, then you +** can be sure the expressions are the same. In the places where +** this routine is used, it does not hurt to get an extra FALSE - that +** just might result in some slightly slower code. But returning +** an incorrect TRUE could lead to a malfunction. */ int sqlite3ExprCompare(Expr *pA, Expr *pB){ int i; @@ -2198,7 +2220,7 @@ int sqlite3ExprCompare(Expr *pA, Expr *pB){ } if( pA->pSelect || pB->pSelect ) return 0; if( pA->iTable!=pB->iTable || pA->iColumn!=pB->iColumn ) return 0; - if( pA->token.z ){ + if( pA->op!=TK_COLUMN && pA->token.z ){ if( pB->token.z==0 ) return 0; if( pB->token.n!=pA->token.n ) return 0; if( sqlite3StrNICmp((char*)pA->token.z,(char*)pB->token.z,pB->token.n)!=0 ){ @@ -2215,10 +2237,14 @@ int sqlite3ExprCompare(Expr *pA, Expr *pB){ */ static int addAggInfoColumn(AggInfo *pInfo){ int i; - i = sqlite3ArrayAllocate((void**)&pInfo->aCol, sizeof(pInfo->aCol[0]), 3); - if( i<0 ){ - return -1; - } + pInfo->aCol = sqlite3ArrayAllocate( + pInfo->aCol, + sizeof(pInfo->aCol[0]), + 3, + &pInfo->nColumn, + &pInfo->nColumnAlloc, + &i + ); return i; } @@ -2228,10 +2254,14 @@ static int addAggInfoColumn(AggInfo *pInfo){ */ static int addAggInfoFunc(AggInfo *pInfo){ int i; - i = sqlite3ArrayAllocate((void**)&pInfo->aFunc, sizeof(pInfo->aFunc[0]), 2); - if( i<0 ){ - return -1; - } + pInfo->aFunc = sqlite3ArrayAllocate( + pInfo->aFunc, + sizeof(pInfo->aFunc[0]), + 3, + &pInfo->nFunc, + &pInfo->nFuncAlloc, + &i + ); return i; } @@ -2266,15 +2296,17 @@ static int analyzeAggregate(void *pArg, Expr *pExpr){ ** Make an entry for the column in pAggInfo->aCol[] if there ** is not an entry there already. */ + int k; pCol = pAggInfo->aCol; - for(i=0; i<pAggInfo->nColumn; i++, pCol++){ + for(k=0; k<pAggInfo->nColumn; k++, pCol++){ if( pCol->iTable==pExpr->iTable && pCol->iColumn==pExpr->iColumn ){ break; } } - if( i>=pAggInfo->nColumn && (i = addAggInfoColumn(pAggInfo))>=0 ){ - pCol = &pAggInfo->aCol[i]; + if( k>=pAggInfo->nColumn && (k = addAggInfoColumn(pAggInfo))>=0 ){ + pCol = &pAggInfo->aCol[k]; + pCol->pTab = pExpr->pTab; pCol->iTable = pExpr->iTable; pCol->iColumn = pExpr->iColumn; pCol->iMem = pParse->nMem++; @@ -2305,7 +2337,7 @@ static int analyzeAggregate(void *pArg, Expr *pExpr){ */ pExpr->pAggInfo = pAggInfo; pExpr->op = TK_AGG_COLUMN; - pExpr->iAgg = i; + pExpr->iAgg = k; break; } /* endif pExpr->iTable==pItem->iCursor */ } /* end loop over pSrcList */ |
