mirror of
https://github.com/sqlite/sqlite.git
synced 2025-11-12 13:01:09 +03:00
Evaluate typeof(X) and length(Y) where X is any column and Y is a blob column
without actually loading X and Y from disk. FossilOrigin-Name: b899dbeb60752843287e2c6ad3577e1d00f0d587
This commit is contained in:
38
src/expr.c
38
src/expr.c
@@ -2032,15 +2032,6 @@ void sqlite3ExprCacheStore(Parse *pParse, int iTab, int iCol, int iReg){
|
||||
*/
|
||||
#ifndef NDEBUG
|
||||
for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
|
||||
#if 0 /* This code wold remove the entry from the cache if it existed */
|
||||
if( p->iReg && p->iTable==iTab && p->iColumn==iCol ){
|
||||
cacheEntryClear(pParse, p);
|
||||
p->iLevel = pParse->iCacheLevel;
|
||||
p->iReg = iReg;
|
||||
p->lru = pParse->iCacheCnt++;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
assert( p->iReg==0 || p->iTable!=iTab || p->iColumn!=iCol );
|
||||
}
|
||||
#endif
|
||||
@@ -2175,7 +2166,8 @@ int sqlite3ExprCodeGetColumn(
|
||||
Table *pTab, /* Description of the table we are reading from */
|
||||
int iColumn, /* Index of the table column */
|
||||
int iTable, /* The cursor pointing to the table */
|
||||
int iReg /* Store results here */
|
||||
int iReg, /* Store results here */
|
||||
u8 p5 /* P5 value for OP_Column */
|
||||
){
|
||||
Vdbe *v = pParse->pVdbe;
|
||||
int i;
|
||||
@@ -2190,7 +2182,11 @@ int sqlite3ExprCodeGetColumn(
|
||||
}
|
||||
assert( v!=0 );
|
||||
sqlite3ExprCodeGetColumnOfTable(v, pTab, iTable, iColumn, iReg);
|
||||
sqlite3ExprCacheStore(pParse, iTable, iColumn, iReg);
|
||||
if( p5 ){
|
||||
sqlite3VdbeChangeP5(v, p5);
|
||||
}else{
|
||||
sqlite3ExprCacheStore(pParse, iTable, iColumn, iReg);
|
||||
}
|
||||
return iReg;
|
||||
}
|
||||
|
||||
@@ -2318,7 +2314,8 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
|
||||
inReg = pExpr->iColumn + pParse->ckBase;
|
||||
}else{
|
||||
inReg = sqlite3ExprCodeGetColumn(pParse, pExpr->pTab,
|
||||
pExpr->iColumn, pExpr->iTable, target);
|
||||
pExpr->iColumn, pExpr->iTable, target,
|
||||
pExpr->op2);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -2595,6 +2592,23 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
|
||||
|
||||
if( pFarg ){
|
||||
r1 = sqlite3GetTempRange(pParse, nFarg);
|
||||
|
||||
/* For length() and typeof() functions with a column argument,
|
||||
** set the P5 parameter to the OP_Column opcode to OPFLAG_LENGTHARG
|
||||
** or OPFLAG_TYPEOFARG respectively, to avoid unnecessary data
|
||||
** loading.
|
||||
*/
|
||||
if( (pDef->flags & (SQLITE_FUNC_LENGTH|SQLITE_FUNC_TYPEOF))!=0 ){
|
||||
assert( nFarg==1 );
|
||||
assert( pFarg->a[0].pExpr!=0 );
|
||||
if( pFarg->a[0].pExpr->op==TK_COLUMN ){
|
||||
assert( SQLITE_FUNC_LENGTH==OPFLAG_LENGTHARG );
|
||||
assert( SQLITE_FUNC_TYPEOF==OPFLAG_TYPEOFARG );
|
||||
testcase( pDef->flags==SQLITE_FUNC_LENGTH );
|
||||
pFarg->a[0].pExpr->op2 = pDef->flags;
|
||||
}
|
||||
}
|
||||
|
||||
sqlite3ExprCachePush(pParse); /* Ticket 2ea2425d34be */
|
||||
sqlite3ExprCodeExprList(pParse, pFarg, r1, 1);
|
||||
sqlite3ExprCachePop(pParse, 1); /* Ticket 2ea2425d34be */
|
||||
|
||||
Reference in New Issue
Block a user