mirror of
https://github.com/sqlite/sqlite.git
synced 2025-11-08 03:22:21 +03:00
The compound-select merge optimization is mostly working with this check-in.
But there are still a few problems and so the optimization is disabled by and "#if 0". This check-in is to synchronize with the other changes happening in parallel. (CVS 5291) FossilOrigin-Name: e2ba324cbcac0ba35bbde50048677e085abb092b
This commit is contained in:
56
src/expr.c
56
src/expr.c
@@ -12,7 +12,7 @@
|
||||
** This file contains routines used for analyzing expressions and
|
||||
** for generating VDBE code that evaluates expressions in SQLite.
|
||||
**
|
||||
** $Id: expr.c,v 1.374 2008/06/22 12:37:58 drh Exp $
|
||||
** $Id: expr.c,v 1.375 2008/06/24 00:32:35 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include <ctype.h>
|
||||
@@ -756,8 +756,8 @@ Select *sqlite3SelectDup(sqlite3 *db, Select *p){
|
||||
pNew->pPrior = sqlite3SelectDup(db, p->pPrior);
|
||||
pNew->pLimit = sqlite3ExprDup(db, p->pLimit);
|
||||
pNew->pOffset = sqlite3ExprDup(db, p->pOffset);
|
||||
pNew->iLimit = -1;
|
||||
pNew->iOffset = -1;
|
||||
pNew->iLimit = 0;
|
||||
pNew->iOffset = 0;
|
||||
pNew->isResolved = p->isResolved;
|
||||
pNew->isAgg = p->isAgg;
|
||||
pNew->usesEphm = 0;
|
||||
@@ -1018,27 +1018,35 @@ int sqlite3ExprIsConstantOrFunction(Expr *p){
|
||||
** to fit in a signed 32-bit integer, return 0 and leave *pValue unchanged.
|
||||
*/
|
||||
int sqlite3ExprIsInteger(Expr *p, int *pValue){
|
||||
int rc = 0;
|
||||
if( p->flags & EP_IntValue ){
|
||||
*pValue = p->iTable;
|
||||
return 1;
|
||||
}
|
||||
switch( p->op ){
|
||||
case TK_INTEGER: {
|
||||
if( sqlite3GetInt32((char*)p->token.z, pValue) ){
|
||||
return 1;
|
||||
}
|
||||
rc = sqlite3GetInt32((char*)p->token.z, pValue);
|
||||
break;
|
||||
}
|
||||
case TK_UPLUS: {
|
||||
return sqlite3ExprIsInteger(p->pLeft, pValue);
|
||||
rc = sqlite3ExprIsInteger(p->pLeft, pValue);
|
||||
}
|
||||
case TK_UMINUS: {
|
||||
int v;
|
||||
if( sqlite3ExprIsInteger(p->pLeft, &v) ){
|
||||
*pValue = -v;
|
||||
return 1;
|
||||
rc = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
return 0;
|
||||
if( rc ){
|
||||
p->op = TK_INTEGER;
|
||||
p->flags |= EP_IntValue;
|
||||
p->iTable = *pValue;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1986,10 +1994,15 @@ static void codeReal(Vdbe *v, const char *z, int n, int negateFlag, int iMem){
|
||||
** z[n] character is guaranteed to be something that does not look
|
||||
** like the continuation of the number.
|
||||
*/
|
||||
static void codeInteger(Vdbe *v, const char *z, int n, int negFlag, int iMem){
|
||||
assert( z || v==0 || sqlite3VdbeDb(v)->mallocFailed );
|
||||
if( z ){
|
||||
static void codeInteger(Vdbe *v, Expr *pExpr, int negFlag, int iMem){
|
||||
const char *z;
|
||||
if( pExpr->flags & EP_IntValue ){
|
||||
int i = pExpr->iTable;
|
||||
if( negFlag ) i = -i;
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, i, iMem);
|
||||
}else if( (z = (char*)pExpr->token.z)!=0 ){
|
||||
int i;
|
||||
int n = pExpr->token.n;
|
||||
assert( !isdigit(z[n]) );
|
||||
if( sqlite3GetInt32(z, &i) ){
|
||||
if( negFlag ) i = -i;
|
||||
@@ -2127,6 +2140,18 @@ void sqlite3ExprCodeMove(Parse *pParse, int iFrom, int iTo, int nReg){
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Generate code to copy content from registers iFrom...iFrom+nReg-1
|
||||
** over to iTo..iTo+nReg-1.
|
||||
*/
|
||||
void sqlite3ExprCodeCopy(Parse *pParse, int iFrom, int iTo, int nReg){
|
||||
int i;
|
||||
if( iFrom==iTo ) return;
|
||||
for(i=0; i<nReg; i++){
|
||||
sqlite3VdbeAddOp2(pParse->pVdbe, OP_Copy, iFrom+i, iTo+i);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Return true if any register in the range iFrom..iTo (inclusive)
|
||||
** is used as part of the column cache.
|
||||
@@ -2246,7 +2271,7 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
|
||||
break;
|
||||
}
|
||||
case TK_INTEGER: {
|
||||
codeInteger(v, (char*)pExpr->token.z, pExpr->token.n, 0, target);
|
||||
codeInteger(v, pExpr, 0, target);
|
||||
break;
|
||||
}
|
||||
case TK_FLOAT: {
|
||||
@@ -2384,11 +2409,10 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
|
||||
Expr *pLeft = pExpr->pLeft;
|
||||
assert( pLeft );
|
||||
if( pLeft->op==TK_FLOAT || pLeft->op==TK_INTEGER ){
|
||||
Token *p = &pLeft->token;
|
||||
if( pLeft->op==TK_FLOAT ){
|
||||
codeReal(v, (char*)p->z, p->n, 1, target);
|
||||
codeReal(v, (char*)pLeft->token.z, pLeft->token.n, 1, target);
|
||||
}else{
|
||||
codeInteger(v, (char*)p->z, p->n, 1, target);
|
||||
codeInteger(v, pLeft, 1, target);
|
||||
}
|
||||
}else{
|
||||
regFree1 = r1 = sqlite3GetTempReg(pParse);
|
||||
|
||||
Reference in New Issue
Block a user