aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/alter.c2
-rw-r--r--src/attach.c6
-rw-r--r--src/build.c14
-rw-r--r--src/delete.c2
-rw-r--r--src/expr.c238
-rw-r--r--src/func.c5
-rw-r--r--src/parse.y2
-rw-r--r--src/pragma.c2
-rw-r--r--src/resolve.c34
-rw-r--r--src/select.c26
-rw-r--r--src/sqliteInt.h29
-rw-r--r--src/tokenize.c2
-rw-r--r--src/trigger.c36
-rw-r--r--src/update.c2
-rw-r--r--src/util.c2
-rw-r--r--src/vdbemem.c19
-rw-r--r--src/walker.c2
-rw-r--r--src/where.c12
18 files changed, 267 insertions, 168 deletions
diff --git a/src/alter.c b/src/alter.c
index 0c3e00e51..ac185f2da 100644
--- a/src/alter.c
+++ b/src/alter.c
@@ -12,7 +12,7 @@
** This file contains C code routines that used to generate VDBE code
** that implements the ALTER TABLE command.
**
-** $Id: alter.c,v 1.59 2009/05/27 10:31:29 drh Exp $
+** $Id: alter.c,v 1.60 2009/05/28 01:00:55 drh Exp $
*/
#include "sqliteInt.h"
diff --git a/src/attach.c b/src/attach.c
index 2b5ddb589..9af765973 100644
--- a/src/attach.c
+++ b/src/attach.c
@@ -11,7 +11,7 @@
*************************************************************************
** This file contains code used to implement the ATTACH and DETACH commands.
**
-** $Id: attach.c,v 1.91 2009/05/27 10:31:29 drh Exp $
+** $Id: attach.c,v 1.92 2009/05/28 01:00:55 drh Exp $
*/
#include "sqliteInt.h"
@@ -41,7 +41,7 @@ static int resolveAttachExpr(NameContext *pName, Expr *pExpr)
if( pExpr->op!=TK_ID ){
rc = sqlite3ResolveExprNames(pName, pExpr);
if( rc==SQLITE_OK && !sqlite3ExprIsConstant(pExpr) ){
- sqlite3ErrorMsg(pName->pParse, "invalid name: \"%s\"", pExpr->zToken);
+ sqlite3ErrorMsg(pName->pParse, "invalid name: \"%s\"", pExpr->u.zToken);
return SQLITE_ERROR;
}
}else{
@@ -312,7 +312,7 @@ static void codeAttach(
#ifndef SQLITE_OMIT_AUTHORIZATION
if( pAuthArg ){
- char *zAuthArg = pAuthArg->zToken;
+ char *zAuthArg = pAuthArg->u.zToken;
if( zAuthArg==0 ){
goto attach_end;
}
diff --git a/src/build.c b/src/build.c
index 66f932e6e..ce8385992 100644
--- a/src/build.c
+++ b/src/build.c
@@ -22,7 +22,7 @@
** COMMIT
** ROLLBACK
**
-** $Id: build.c,v 1.545 2009/05/27 10:31:29 drh Exp $
+** $Id: build.c,v 1.546 2009/05/28 01:00:55 drh Exp $
*/
#include "sqliteInt.h"
@@ -1181,14 +1181,12 @@ void sqlite3AddCheckConstraint(
#ifndef SQLITE_OMIT_CHECK
Table *pTab = pParse->pNewTable;
if( pTab && !IN_DECLARE_VTAB ){
- /* The CHECK expression must be duplicated so that tokens refer
- ** to malloced space and not the (ephemeral) text of the CREATE TABLE
- ** statement */
- pTab->pCheck = sqlite3ExprAnd(db, pTab->pCheck,
- sqlite3ExprDup(db, pCheckExpr, 0));
- }
+ pTab->pCheck = sqlite3ExprAnd(db, pTab->pCheck, pCheckExpr);
+ }else
#endif
- sqlite3ExprDelete(db, pCheckExpr);
+ {
+ sqlite3ExprDelete(db, pCheckExpr);
+ }
}
/*
diff --git a/src/delete.c b/src/delete.c
index e5177819c..95ef3cef7 100644
--- a/src/delete.c
+++ b/src/delete.c
@@ -12,7 +12,7 @@
** This file contains C code routines that are called by the parser
** in order to generate code for DELETE FROM statements.
**
-** $Id: delete.c,v 1.202 2009/05/27 10:31:29 drh Exp $
+** $Id: delete.c,v 1.203 2009/05/28 01:00:55 drh Exp $
*/
#include "sqliteInt.h"
diff --git a/src/expr.c b/src/expr.c
index 6fe400d1e..a94b825eb 100644
--- a/src/expr.c
+++ b/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.437 2009/05/27 10:31:29 drh Exp $
+** $Id: expr.c,v 1.438 2009/05/28 01:00:55 drh Exp $
*/
#include "sqliteInt.h"
@@ -40,7 +40,8 @@ char sqlite3ExprAffinity(Expr *pExpr){
}
#ifndef SQLITE_OMIT_CAST
if( op==TK_CAST ){
- return sqlite3AffinityType(pExpr->zToken);
+ assert( !ExprHasProperty(pExpr, EP_IntValue) );
+ return sqlite3AffinityType(pExpr->u.zToken);
}
#endif
if( (op==TK_AGG_COLUMN || op==TK_COLUMN || op==TK_REGISTER)
@@ -388,6 +389,12 @@ int sqlite3SelectExprHeight(Select *p){
** parameter is ignored if pToken is NULL or if the token does not
** appear to be quoted. If the quotes were of the form "..." (double-quotes)
** then the EP_DblQuoted flag is set on the expression node.
+**
+** Special case: If op==TK_INTEGER and pToken points to a string that
+** can be translated into a 32-bit integer, then the token is not
+** stored in u.zToken. Instead, the integer values is written
+** into u.iValue and the EP_IntValue flag is set. No extra storage
+** is allocated to hold the integer text and the dequote flag is ignored.
*/
Expr *sqlite3ExprAlloc(
sqlite3 *db, /* Handle for sqlite3DbMallocZero() (may be null) */
@@ -396,26 +403,33 @@ Expr *sqlite3ExprAlloc(
int dequote /* True to dequote */
){
Expr *pNew;
- int nExtra;
+ int nExtra = 0;
+ int iValue;
if( pToken ){
- nExtra = pToken->n+1;
- }else{
- nExtra = 0;
+ if( op!=TK_INTEGER || pToken->z==0
+ || sqlite3GetInt32(pToken->z, &iValue)==0 ){
+ nExtra = pToken->n+1;
+ }
}
pNew = sqlite3DbMallocZero(db, sizeof(Expr)+nExtra);
if( pNew ){
pNew->op = (u8)op;
pNew->iAgg = -1;
if( pToken ){
- int c;
- pNew->zToken = (char*)&pNew[1];
- memcpy(pNew->zToken, pToken->z, pToken->n);
- pNew->zToken[pToken->n] = 0;
- if( dequote && nExtra>=3
- && ((c = pToken->z[0])=='\'' || c=='"' || c=='[' || c=='`') ){
- sqlite3Dequote(pNew->zToken);
- if( c=='"' ) pNew->flags |= EP_DblQuoted;
+ if( nExtra==0 ){
+ pNew->flags |= EP_IntValue;
+ pNew->u.iValue = iValue;
+ }else{
+ int c;
+ pNew->u.zToken = (char*)&pNew[1];
+ memcpy(pNew->u.zToken, pToken->z, pToken->n);
+ pNew->u.zToken[pToken->n] = 0;
+ if( dequote && nExtra>=3
+ && ((c = pToken->z[0])=='\'' || c=='"' || c=='[' || c=='`') ){
+ sqlite3Dequote(pNew->u.zToken);
+ if( c=='"' ) pNew->flags |= EP_DblQuoted;
+ }
}
}
#if SQLITE_MAX_EXPR_DEPTH>0
@@ -550,7 +564,8 @@ void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr){
const char *z;
if( pExpr==0 ) return;
- z = pExpr->zToken;
+ assert( !ExprHasAnyProperty(pExpr, EP_IntValue|EP_Reduced|EP_TokenOnly) );
+ z = pExpr->u.zToken;
assert( z!=0 );
assert( z[0]!=0 );
if( z[1]==0 ){
@@ -584,7 +599,7 @@ void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr){
for(i=0; i<pParse->nVarExpr; i++){
Expr *pE = pParse->apVarExpr[i];
assert( pE!=0 );
- if( memcmp(pE->zToken, z, n)==0 && pE->zToken[n]==0 ){
+ if( memcmp(pE->u.zToken, z, n)==0 && pE->u.zToken[n]==0 ){
pExpr->iTable = pE->iTable;
break;
}
@@ -616,19 +631,13 @@ void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr){
** Substructure is deleted.
*/
void sqlite3ExprClear(sqlite3 *db, Expr *p){
+ assert( p!=0 );
if( !ExprHasAnyProperty(p, EP_TokenOnly) ){
- if( ExprHasProperty(p, EP_Reduced) ){
- /* Subtrees are part of the same memory allocation when EP_Reduced set */
- if( p->pLeft ) sqlite3ExprClear(db, p->pLeft);
- if( p->pRight ) sqlite3ExprClear(db, p->pRight);
- }else{
- /* Subtrees are separate allocations when EP_Reduced is clear */
- sqlite3ExprDelete(db, p->pLeft);
- sqlite3ExprDelete(db, p->pRight);
- /* Sometimes the zToken is allocated separately */
- if( p->flags2 & EP2_FreeToken ) sqlite3DbFree(db, p->zToken);
+ sqlite3ExprDelete(db, p->pLeft);
+ sqlite3ExprDelete(db, p->pRight);
+ if( !ExprHasProperty(p, EP_Reduced) && (p->flags2 & EP2_MallocedToken)!=0 ){
+ sqlite3DbFree(db, p->u.zToken);
}
- /* x.pSelect and x.pList are always separately allocated */
if( ExprHasProperty(p, EP_xIsSelect) ){
sqlite3SelectDelete(db, p->x.pSelect);
}else{
@@ -643,7 +652,9 @@ void sqlite3ExprClear(sqlite3 *db, Expr *p){
void sqlite3ExprDelete(sqlite3 *db, Expr *p){
if( p==0 ) return;
sqlite3ExprClear(db, p);
- sqlite3DbFree(db, p);
+ if( !ExprHasProperty(p, EP_Static) ){
+ sqlite3DbFree(db, p);
+ }
}
/*
@@ -658,34 +669,67 @@ static int exprStructSize(Expr *p){
}
/*
-** sqlite3ExprDup() has been called to create a copy of expression p with
-** the EXPRDUP_XXX flags passed as the second argument. This function
-** returns the space required for the copy of the Expr structure only.
-** This is always one of EXPR_FULLSIZE, EXPR_REDUCEDSIZE or EXPR_TOKENONLYSIZE.
+** The dupedExpr*Size() routines each return the number of bytes required
+** to store a copy of an expression or expression tree. They differ in
+** how much of the tree is measured.
+**
+** dupedExprStructSize() Size of only the Expr structure
+** dupedExprNodeSize() Size of Expr + space for token
+** dupedExprSize() Expr + token + subtree components
+**
+***************************************************************************
+**
+** The dupedExprStructSize() function returns two values OR-ed together:
+** (1) the space required for a copy of the Expr structure only and
+** (2) the EP_xxx flags that indicate what the structure size should be.
+** The return values is always one of:
+**
+** EXPR_FULLSIZE
+** EXPR_REDUCEDSIZE | EP_Reduced
+** EXPR_TOKENONLYSIZE | EP_TokenOnly
+**
+** The size of the structure can be found by masking the return value
+** of this routine with 0xfff. The flags can be found by masking the
+** return value with EP_Reduced|EP_TokenOnly.
+**
+** Note that with flags==EXPRDUP_REDUCE, this routines works on full-size
+** (unreduced) Expr objects as they or originally constructed by the parser.
+** During expression analysis, extra information is computed and moved into
+** later parts of teh Expr object and that extra information might get chopped
+** off if the expression is reduced. Note also that it does not work to
+** make a EXPRDUP_REDUCE copy of a reduced expression. It is only legal
+** to reduce a pristine expression tree from the parser. The implementation
+** of dupedExprStructSize() contain multiple assert() statements that attempt
+** to enforce this constraint.
*/
static int dupedExprStructSize(Expr *p, int flags){
int nSize;
+ assert( flags==EXPRDUP_REDUCE || flags==0 ); /* Only one flag value allowed */
if( 0==(flags&EXPRDUP_REDUCE) ){
nSize = EXPR_FULLSIZE;
- }else if( p->pLeft || p->pRight || p->pColl || p->x.pList ){
- nSize = EXPR_REDUCEDSIZE;
}else{
- nSize = EXPR_TOKENONLYSIZE;
+ assert( !ExprHasAnyProperty(p, EP_TokenOnly|EP_Reduced) );
+ assert( !ExprHasProperty(p, EP_FromJoin) );
+ assert( (p->flags2 & EP2_MallocedToken)==0 );
+ assert( (p->flags2 & EP2_Irreducible)==0 );
+ if( p->pLeft || p->pRight || p->pColl || p->x.pList ){
+ nSize = EXPR_REDUCEDSIZE | EP_Reduced;
+ }else{
+ nSize = EXPR_TOKENONLYSIZE | EP_TokenOnly;
+ }
}
return nSize;
}
/*
-** sqlite3ExprDup() has been called to create a copy of expression p with
-** the EXPRDUP_XXX passed as the second argument. This function returns
-** the space in bytes required to store the copy of the Expr structure
-** and the copies of the Expr.zToken (if applicable)
-** string buffers.
+** This function returns the space in bytes required to store the copy
+** of the Expr structure and a copy of the Expr.u.zToken string (if that
+** string is defined.)
*/
static int dupedExprNodeSize(Expr *p, int flags){
- int nByte = dupedExprStructSize(p, flags);
- if( p->zToken ){
- nByte += sqlite3Strlen30(p->zToken)+1;
+ int nByte = dupedExprStructSize(p, flags) & 0xfff;
+ if( !ExprHasProperty(p, EP_IntValue) && p->u.zToken ){
+ nByte += sqlite3Strlen30(p->u.zToken)+1;
}
return ROUND8(nByte);
}
@@ -696,7 +740,7 @@ static int dupedExprNodeSize(Expr *p, int flags){
** mask containing EXPRDUP_XXX flags.
**
** The value returned includes space to create a copy of the Expr struct
-** itself and the buffer referred to by Expr.zToken, if any.
+** itself and the buffer referred to by Expr.u.zToken, if any.
**
** If the EXPRDUP_REDUCE flag is set, then the return value includes
** space to duplicate all Expr nodes in the tree formed by Expr.pLeft
@@ -717,7 +761,7 @@ static int dupedExprSize(Expr *p, int flags){
/*
** This function is similar to sqlite3ExprDup(), except that if pzBuffer
** is not NULL then *pzBuffer is assumed to point to a buffer large enough
-** to store the copy of expression p, the copies of p->zToken
+** to store the copy of expression p, the copies of p->u.zToken
** (if applicable), and the copies of the p->pLeft and p->pRight expressions,
** if any. Before returning, *pzBuffer is set to the first byte passed the
** portion of the buffer copied into by this function.
@@ -727,12 +771,14 @@ static Expr *exprDup(sqlite3 *db, Expr *p, int flags, u8 **pzBuffer){
if( p ){
const int isReduced = (flags&EXPRDUP_REDUCE);
u8 *zAlloc;
+ u32 staticFlag = 0;
assert( pzBuffer==0 || isReduced );
/* Figure out where to write the new Expr structure. */
if( pzBuffer ){
zAlloc = *pzBuffer;
+ staticFlag = EP_Static;
}else{
zAlloc = sqlite3DbMallocRaw(db, dupedExprSize(p, flags));
}
@@ -742,10 +788,16 @@ static Expr *exprDup(sqlite3 *db, Expr *p, int flags, u8 **pzBuffer){
/* Set nNewSize to the size allocated for the structure pointed to
** by pNew. This is either EXPR_FULLSIZE, EXPR_REDUCEDSIZE or
** EXPR_TOKENONLYSIZE. nToken is set to the number of bytes consumed
- ** by the copy of the p->zToken string (if any).
+ ** by the copy of the p->u.zToken string (if any).
*/
- const int nNewSize = dupedExprStructSize(p, flags);
- const int nToken = (p->zToken ? sqlite3Strlen30(p->zToken) + 1 : 0);
+ const unsigned nStructSize = dupedExprStructSize(p, flags);
+ 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( isReduced ){
assert( ExprHasProperty(p, EP_Reduced)==0 );
memcpy(zAlloc, p, nNewSize);
@@ -755,17 +807,15 @@ static Expr *exprDup(sqlite3 *db, Expr *p, int flags, u8 **pzBuffer){
memset(&zAlloc[nSize], 0, EXPR_FULLSIZE-nSize);
}
- /* Set the EP_Reduced and EP_TokenOnly flags appropriately. */
- pNew->flags &= ~(EP_Reduced|EP_TokenOnly);
- switch( nNewSize ){
- case EXPR_REDUCEDSIZE: pNew->flags |= EP_Reduced; break;
- case EXPR_TOKENONLYSIZE: pNew->flags |= EP_TokenOnly; break;
- }
+ /* Set the EP_Reduced, EP_TokenOnly, and EP_Static flags appropriately. */
+ pNew->flags &= ~(EP_Reduced|EP_TokenOnly|EP_Static);
+ pNew->flags |= nStructSize & (EP_Reduced|EP_TokenOnly);
+ pNew->flags |= staticFlag;
- /* Copy the p->zToken string, if any. */
+ /* Copy the p->u.zToken string, if any. */
if( nToken ){
- char *zToken = pNew->zToken = (char*)&zAlloc[nNewSize];
- memcpy(zToken, p->zToken, nToken);
+ char *zToken = pNew->u.zToken = (char*)&zAlloc[nNewSize];
+ memcpy(zToken, p->u.zToken, nToken);
}
if( 0==((p->flags|pNew->flags) & EP_TokenOnly) ){
@@ -1180,12 +1230,13 @@ int sqlite3ExprIsConstantOrFunction(Expr *p){
int sqlite3ExprIsInteger(Expr *p, int *pValue){
int rc = 0;
if( p->flags & EP_IntValue ){
- *pValue = p->iTable;
+ *pValue = p->u.iValue;
return 1;
}
switch( p->op ){
case TK_INTEGER: {
- rc = sqlite3GetInt32(p->zToken, pValue);
+ rc = sqlite3GetInt32(p->u.zToken, pValue);
+ assert( rc==0 );
break;
}
case TK_UPLUS: {
@@ -1203,9 +1254,11 @@ int sqlite3ExprIsInteger(Expr *p, int *pValue){
default: break;
}
if( rc ){
+ assert( ExprHasAnyProperty(p, EP_Reduced|EP_TokenOnly)
+ || (p->flags2 & EP2_MallocedToken)==0 );
p->op = TK_INTEGER;
p->flags |= EP_IntValue;
- p->iTable = *pValue;
+ p->u.iValue = *pValue;
}
return rc;
}
@@ -1602,6 +1655,7 @@ void sqlite3CodeSubselect(
return;
}
pExpr->iColumn = dest.iParm;
+ ExprSetIrreducible(pExpr);
break;
}
}
@@ -1662,12 +1716,12 @@ static void codeReal(Vdbe *v, const char *z, int negateFlag, int iMem){
static void codeInteger(Vdbe *v, Expr *pExpr, int negFlag, int iMem){
const char *z;
if( pExpr->flags & EP_IntValue ){
- int i = pExpr->iTable;
+ int i = pExpr->u.iValue;
if( negFlag ) i = -i;
sqlite3VdbeAddOp2(v, OP_Integer, i, iMem);
- }else if( (z = pExpr->zToken)!=0 ){
+ }else if( (z = pExpr->u.zToken)!=0 ){
int i;
- int n = sqlite3Strlen30(pExpr->zToken);
+ int n = sqlite3Strlen30(pExpr->u.zToken);
assert( !sqlite3Isdigit(z[n]) );
if( sqlite3GetInt32(z, &i) ){
if( negFlag ) i = -i;
@@ -2078,11 +2132,13 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
break;
}
case TK_FLOAT: {
- codeReal(v, pExpr->zToken, 0, target);
+ assert( !ExprHasProperty(pExpr, EP_IntValue) );
+ codeReal(v, pExpr->u.zToken, 0, target);
break;
}
case TK_STRING: {
- sqlite3VdbeAddOp4(v, OP_String8, 0, target, 0, pExpr->zToken, 0);
+ assert( !ExprHasProperty(pExpr, EP_IntValue) );
+ sqlite3VdbeAddOp4(v, OP_String8, 0, target, 0, pExpr->u.zToken, 0);
break;
}
case TK_NULL: {
@@ -2094,9 +2150,10 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
int n;
const char *z;
char *zBlob;
- assert( pExpr->zToken[0]=='x' || pExpr->zToken[0]=='X' );
- assert( pExpr->zToken[1]=='\'' );
- z = &pExpr->zToken[2];
+ 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);
@@ -2107,9 +2164,10 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
case TK_VARIABLE: {
int iPrior;
VdbeOp *pOp;
- assert( pExpr->zToken!=0 );
- assert( pExpr->zToken[0]!=0 );
- if( pExpr->zToken[1]==0
+ assert( !ExprHasProperty(pExpr, EP_IntValue) );
+ assert( pExpr->u.zToken!=0 );
+ assert( pExpr->u.zToken[0]!=0 );
+ if( pExpr->u.zToken[1]==0
&& (iPrior = sqlite3VdbeCurrentAddr(v)-1)>=0
&& (pOp = sqlite3VdbeGetOp(v, iPrior))->opcode==OP_Variable
&& pOp->p1+pOp->p3==pExpr->iTable
@@ -2124,8 +2182,8 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
pOp->p3++;
}else{
sqlite3VdbeAddOp3(v, OP_Variable, pExpr->iTable, target, 1);
- if( pExpr->zToken[1]!=0 ){
- sqlite3VdbeChangeP4(v, -1, pExpr->zToken, 0);
+ if( pExpr->u.zToken[1]!=0 ){
+ sqlite3VdbeChangeP4(v, -1, pExpr->u.zToken, 0);
}
}
break;
@@ -2143,7 +2201,8 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
/* Expressions of the form: CAST(pLeft AS token) */
int aff, to_op;
inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target);
- aff = sqlite3AffinityType(pExpr->zToken);
+ assert( !ExprHasProperty(pExpr, EP_IntValue) );
+ aff = sqlite3AffinityType(pExpr->u.zToken);
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 );
@@ -2236,7 +2295,8 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
Expr *pLeft = pExpr->pLeft;
assert( pLeft );
if( pLeft->op==TK_FLOAT ){
- codeReal(v, pLeft->zToken, 1, target);
+ assert( !ExprHasProperty(pExpr, EP_IntValue) );
+ codeReal(v, pLeft->u.zToken, 1, target);
}else if( pLeft->op==TK_INTEGER ){
codeInteger(v, pLeft, 1, target);
}else{
@@ -2279,7 +2339,8 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
case TK_AGG_FUNCTION: {
AggInfo *pInfo = pExpr->pAggInfo;
if( pInfo==0 ){
- sqlite3ErrorMsg(pParse, "misuse of aggregate: %s()", pExpr->zToken);
+ assert( !ExprHasProperty(pExpr, EP_IntValue) );
+ sqlite3ErrorMsg(pParse, "misuse of aggregate: %s()", pExpr->u.zToken);
}else{
inReg = pInfo->aFunc[pExpr->iAgg].iMem;
}
@@ -2306,7 +2367,8 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
pFarg = pExpr->x.pList;
}
nFarg = pFarg ? pFarg->nExpr : 0;
- zId = pExpr->zToken;
+ assert( !ExprHasProperty(pExpr, EP_IntValue) );
+ zId = pExpr->u.zToken;
nId = sqlite3Strlen30(zId);
pDef = sqlite3FindFunction(db, zId, nId, nFarg, enc, 0);
assert( pDef!=0 );
@@ -2589,8 +2651,9 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
assert( pExpr->affinity==OE_Rollback ||
pExpr->affinity == OE_Abort ||
pExpr->affinity == OE_Fail );
+ assert( !ExprHasProperty(pExpr, EP_IntValue) );
sqlite3VdbeAddOp4(v, OP_Halt, SQLITE_CONSTRAINT, pExpr->affinity, 0,
- pExpr->zToken, 0);
+ pExpr->u.zToken, 0);
} else {
assert( pExpr->affinity == OE_Ignore );
sqlite3VdbeAddOp2(v, OP_ContextPop, 0, 0);
@@ -3115,6 +3178,8 @@ int sqlite3ExprCompare(Expr *pA, Expr *pB){
if( pA==0||pB==0 ){
return pB==pA;
}
+ assert( !ExprHasAnyProperty(pA, EP_TokenOnly|EP_Reduced) );
+ assert( !ExprHasAnyProperty(pB, EP_TokenOnly|EP_Reduced) );
if( ExprHasProperty(pA, EP_xIsSelect) || ExprHasProperty(pB, EP_xIsSelect) ){
return 0;
}
@@ -3135,9 +3200,13 @@ int sqlite3ExprCompare(Expr *pA, Expr *pB){
}
if( pA->iTable!=pB->iTable || pA->iColumn!=pB->iColumn ) return 0;
- if( pA->op!=TK_COLUMN && pA->zToken ){
- if( pB->zToken==0 ) return 0;
- if( sqlite3StrICmp(pA->zToken,pB->zToken)!=0 ){
+ if( ExprHasProperty(pA, EP_IntValue) ){
+ if( !ExprHasProperty(pB, EP_IntValue) || pA->u.iValue!=pB->u.iValue ){
+ return 0;
+ }
+ }else if( pA->op!=TK_COLUMN && pA->u.zToken ){
+ if( ExprHasProperty(pB, EP_IntValue) || pB->u.zToken==0 ) return 0;
+ if( sqlite3StrICmp(pA->u.zToken,pB->u.zToken)!=0 ){
return 0;
}
}
@@ -3204,6 +3273,7 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){
struct SrcList_item *pItem = pSrcList->a;
for(i=0; i<pSrcList->nSrc; i++, pItem++){
struct AggInfo_col *pCol;
+ assert( !ExprHasAnyProperty(pExpr, EP_TokenOnly|EP_Reduced) );
if( pExpr->iTable==pItem->iCursor ){
/* If we reach this point, it means that pExpr refers to a table
** that is in the FROM clause of the aggregate query.
@@ -3252,6 +3322,7 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){
** Convert the pExpr to be a TK_AGG_COLUMN referring to that
** pAggInfo->aCol[] entry.
*/
+ ExprSetIrreducible(pExpr);
pExpr->pAggInfo = pAggInfo;
pExpr->op = TK_AGG_COLUMN;
pExpr->iAgg = k;
@@ -3284,8 +3355,9 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){
pItem = &pAggInfo->aFunc[i];
pItem->pExpr = pExpr;
pItem->iMem = ++pParse->nMem;
+ assert( !ExprHasProperty(pExpr, EP_IntValue) );
pItem->pFunc = sqlite3FindFunction(pParse->db,
- pExpr->zToken, sqlite3Strlen30(pExpr->zToken),
+ pExpr->u.zToken, sqlite3Strlen30(pExpr->u.zToken),
pExpr->x.pList ? pExpr->x.pList->nExpr : 0, enc, 0);
if( pExpr->flags & EP_Distinct ){
pItem->iDistinct = pParse->nTab++;
@@ -3296,6 +3368,8 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){
}
/* Make pExpr point to the appropriate pAggInfo->aFunc[] entry
*/
+ assert( !ExprHasAnyProperty(pExpr, EP_TokenOnly|EP_Reduced) );
+ ExprSetIrreducible(pExpr);
pExpr->iAgg = i;
pExpr->pAggInfo = pAggInfo;
return WRC_Prune;
diff --git a/src/func.c b/src/func.c
index 3792d9efb..893406ceb 100644
--- a/src/func.c
+++ b/src/func.c
@@ -16,7 +16,7 @@
** sqliteRegisterBuildinFunctions() found at the bottom of the file.
** All other code has file scope.
**
-** $Id: func.c,v 1.235 2009/05/27 10:31:29 drh Exp $
+** $Id: func.c,v 1.236 2009/05/28 01:00:55 drh Exp $
*/
#include "sqliteInt.h"
#include <stdlib.h>
@@ -1368,7 +1368,8 @@ int sqlite3IsLikeFunction(sqlite3 *db, Expr *pExpr, int *pIsNocase, char *aWc){
return 0;
}
assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
- pDef = sqlite3FindFunction(db, pExpr->zToken, sqlite3Strlen30(pExpr->zToken),
+ pDef = sqlite3FindFunction(db, pExpr->u.zToken,
+ sqlite3Strlen30(pExpr->u.zToken),
2, SQLITE_UTF8, 0);
if( NEVER(pDef==0) || (pDef->flags & SQLITE_FUNC_LIKE)==0 ){
return 0;
diff --git a/src/parse.y b/src/parse.y
index 848ebaebc..d30f89f26 100644
--- a/src/parse.y
+++ b/src/parse.y
@@ -14,7 +14,7 @@
** the parser. Lemon will also generate a header file containing
** numeric codes for all of the tokens.
**
-** @(#) $Id: parse.y,v 1.277 2009/05/27 10:31:29 drh Exp $
+** @(#) $Id: parse.y,v 1.278 2009/05/28 01:00:55 drh Exp $
*/
// All token codes are small integers with #defines that begin with "TK_"
diff --git a/src/pragma.c b/src/pragma.c
index 6fca256d0..ae5ca7508 100644
--- a/src/pragma.c
+++ b/src/pragma.c
@@ -11,7 +11,7 @@
*************************************************************************
** This file contains code used to implement the PRAGMA command.
**
-** $Id: pragma.c,v 1.210 2009/05/27 10:31:29 drh Exp $
+** $Id: pragma.c,v 1.211 2009/05/28 01:00:55 drh Exp $
*/
#include "sqliteInt.h"
diff --git a/src/resolve.c b/src/resolve.c
index b9c7face3..015fe4bf7 100644
--- a/src/resolve.c
+++ b/src/resolve.c
@@ -14,7 +14,7 @@
** resolve all identifiers by associating them with a particular
** table and column.
**
-** $Id: resolve.c,v 1.23 2009/05/27 10:31:29 drh Exp $
+** $Id: resolve.c,v 1.24 2009/05/28 01:00:55 drh Exp $
*/
#include "sqliteInt.h"
#include <stdlib.h>
@@ -72,15 +72,15 @@ static void resolveAlias(
}
pDup->iTable = pEList->a[iCol].iAlias;
}else{
- char *zToken = pOrig->zToken;
- pOrig->zToken = 0;
+ char *zToken = pOrig->u.zToken;
+ pOrig->u.zToken = 0;
pDup = sqlite3ExprDup(db, pOrig, 0);
- pOrig->zToken = zToken;
+ pOrig->u.zToken = zToken;
if( pDup==0 ) return;
if( zToken ){
assert( (pDup->flags & (EP_Reduced|EP_TokenOnly))==0 );
- pDup->flags2 |= EP2_FreeToken;
- pDup->zToken = sqlite3DbStrDup(db, zToken);
+ pDup->flags2 |= EP2_MallocedToken;
+ pDup->u.zToken = sqlite3DbStrDup(db, zToken);
}
}
if( pExpr->flags & EP_ExpCollate ){
@@ -138,10 +138,12 @@ static int lookupName(
assert( pNC ); /* the name context cannot be NULL. */
assert( zCol ); /* The Z in X.Y.Z cannot be NULL */
+ assert( ~ExprHasAnyProperty(pExpr, EP_TokenOnly|EP_Reduced) );
/* Initialize the node to no-match */
pExpr->iTable = -1;
pExpr->pTab = 0;
+ ExprSetIrreducible(pExpr);
/* Start at the inner-most context and move outward until a match is found */
while( pNC && cnt==0 ){
@@ -439,7 +441,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
/* A lone identifier is the name of a column.
*/
case TK_ID: {
- lookupName(pParse, 0, 0, pExpr->zToken, pNC, pExpr);
+ lookupName(pParse, 0, 0, pExpr->u.zToken, pNC, pExpr);
return WRC_Prune;
}
@@ -456,13 +458,13 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
pRight = pExpr->pRight;
if( pRight->op==TK_ID ){
zDb = 0;
- zTable = pExpr->pLeft->zToken;
- zColumn = pRight->zToken;
+ zTable = pExpr->pLeft->u.zToken;
+ zColumn = pRight->u.zToken;
}else{
assert( pRight->op==TK_DOT );
- zDb = pExpr->pLeft->zToken;
- zTable = pRight->pLeft->zToken;
- zColumn = pRight->pRight->zToken;
+ zDb = pExpr->pLeft->u.zToken;
+ zTable = pRight->pLeft->u.zToken;
+ zColumn = pRight->pRight->u.zToken;
}
lookupName(pParse, zDb, zTable, zColumn, pNC, pExpr);
return WRC_Prune;
@@ -484,7 +486,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
u8 enc = ENC(pParse->db); /* The database encoding */
assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
- zId = pExpr->zToken;
+ zId = pExpr->u.zToken;
nId = sqlite3Strlen30(zId);
pDef = sqlite3FindFunction(pParse->db, zId, nId, n, enc, 0);
if( pDef==0 ){
@@ -586,8 +588,8 @@ static int resolveAsName(
){
int i; /* Loop counter */
- if( pE->op==TK_ID || (pE->op==TK_STRING && pE->zToken[0]!='\'') ){
- char *zCol = pE->zToken;
+ if( pE->op==TK_ID || (pE->op==TK_STRING && pE->u.zToken[0]!='\'') ){
+ char *zCol = pE->u.zToken;
for(i=0; i<pEList->nExpr; i++){
char *zAs = pEList->a[i].zName;
if( zAs!=0 && sqlite3StrICmp(zAs, zCol)==0 ){
@@ -748,7 +750,7 @@ static int resolveCompoundOrderBy(
if( pE==0 ) return 1;
pE->pColl = pColl;
pE->flags |= EP_IntValue | flags;
- pE->iTable = iCol;
+ pE->u.iValue = iCol;
pItem->iCol = (u16)iCol;
pItem->done = 1;
}else{
diff --git a/src/select.c b/src/select.c
index 2f91ba9c5..54a42ab29 100644
--- a/src/select.c
+++ b/src/select.c
@@ -12,7 +12,7 @@
** This file contains C code routines that are called by the parser
** to handle SELECT statements in SQLite.
**
-** $Id: select.c,v 1.519 2009/05/27 10:31:29 drh Exp $
+** $Id: select.c,v 1.520 2009/05/28 01:00:55 drh Exp $
*/
#include "sqliteInt.h"
@@ -232,6 +232,8 @@ static void addWhereTerm(
pE = sqlite3PExpr(pParse, TK_EQ, pE1c, pE2c, 0);
if( pE && isOuterJoin ){
ExprSetProperty(pE, EP_FromJoin);
+ assert( !ExprHasAnyProperty(pE, EP_TokenOnly|EP_Reduced) );
+ ExprSetIrreducible(pE);
pE->iRightJoinTable = iRightJoinTable;
}
*ppExpr = sqlite3ExprAnd(pParse->db,*ppExpr, pE);
@@ -266,6 +268,8 @@ static void addWhereTerm(
static void setJoinExpr(Expr *p, int iTable){
while( p ){
ExprSetProperty(p, EP_FromJoin);
+ assert( !ExprHasAnyProperty(p, EP_TokenOnly|EP_Reduced) );
+ ExprSetIrreducible(p);
p->iRightJoinTable = iTable;
setJoinExpr(p->pLeft, iTable);
p = p->pRight;
@@ -1127,7 +1131,8 @@ static int selectColumnsFromExprList(
/* Get an appropriate name for the column
*/
p = pEList->a[i].pExpr;
- assert( p->pRight==0 || p->pRight->zToken==0 || p->pRight->zToken[0]!=0 );
+ assert( p->pRight==0 || ExprHasProperty(p->pRight, EP_IntValue)
+ || p->pRight->u.zToken==0 || p->pRight->u.zToken[0]!=0 );
if( (zName = pEList->a[i].zName)!=0 ){
/* If the column contains an "AS <name>" phrase, use <name> as the name */
zName = sqlite3DbStrDup(db, zName);
@@ -1143,7 +1148,8 @@ static int selectColumnsFromExprList(
zName = sqlite3MPrintf(db, "%s",
iCol>=0 ? pTab->aCol[iCol].zName : "rowid");
}else if( pColExpr->op==TK_ID ){
- zName = sqlite3MPrintf(db, "%s", pColExpr->zToken);
+ assert( !ExprHasProperty(pColExpr, EP_IntValue) );
+ zName = sqlite3MPrintf(db, "%s", pColExpr->u.zToken);
}else{
/* Use the original text of the column expression as its name */
zName = sqlite3MPrintf(db, "%s", pEList->a[i].zSpan);
@@ -2048,7 +2054,7 @@ static int multiSelectOrderBy(
Expr *pNew = sqlite3Expr(db, TK_INTEGER, 0);
if( pNew==0 ) return SQLITE_NOMEM;
pNew->flags |= EP_IntValue;
- pNew->iTable = i;
+ pNew->u.iValue = i;
pOrderBy = sqlite3ExprListAppend(pParse, pOrderBy, pNew);
pOrderBy->a[nOrderBy++].iCol = (u16)i;
}
@@ -2896,9 +2902,10 @@ static u8 minMaxQuery(Select *p){
pEList = pExpr->x.pList;
if( pEList==0 || pEList->nExpr!=1 ) return 0;
if( pEList->a[0].pExpr->op!=TK_AGG_COLUMN ) return WHERE_ORDERBY_NORMAL;
- if( sqlite3StrICmp(pExpr->zToken,"min")==0 ){
+ assert( !ExprHasProperty(pExpr, EP_IntValue) );
+ if( sqlite3StrICmp(pExpr->u.zToken,"min")==0 ){
return WHERE_ORDERBY_MIN;
- }else if( sqlite3StrICmp(pExpr->zToken,"max")==0 ){
+ }else if( sqlite3StrICmp(pExpr->u.zToken,"max")==0 ){
return WHERE_ORDERBY_MAX;
}
return WHERE_ORDERBY_NORMAL;
@@ -3119,7 +3126,8 @@ static int selectExpander(Walker *pWalker, Select *p){
char *zTName; /* text of name of TABLE */
if( pE->op==TK_DOT ){
assert( pE->pLeft!=0 );
- zTName = pE->pLeft->zToken;
+ assert( !ExprHasProperty(pE->pLeft, EP_IntValue) );
+ zTName = pE->pLeft->u.zToken;
}else{
zTName = 0;
}
@@ -4143,8 +4151,8 @@ select_end:
** or from temporary "printf" statements inserted for debugging.
*/
void sqlite3PrintExpr(Expr *p){
- if( p->zToken ){
- sqlite3DebugPrintf("(%s", p->zToken);
+ if( !ExprHasProperty(p, EP_IntValue) && p->u.zToken ){
+ sqlite3DebugPrintf("(%s", p->u.zToken);
}else{
sqlite3DebugPrintf("(%d", p->op);
}
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index 3c0a525dd..97de27667 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -11,7 +11,7 @@
*************************************************************************
** Internal interface definitions for SQLite.
**
-** @(#) $Id: sqliteInt.h,v 1.876 2009/05/27 10:31:29 drh Exp $
+** @(#) $Id: sqliteInt.h,v 1.877 2009/05/28 01:00:55 drh Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_
@@ -1464,7 +1464,7 @@ struct AggInfo {
** help reduce memory requirements, sometimes an Expr object will be
** truncated. And to reduce the number of memory allocations, sometimes
** two or more Expr objects will be stored in a single memory allocation,
-** together with Expr.token strings.
+** together with Expr.zToken strings.
**
** If the EP_Reduced and EP_TokenOnly flags are set when
** an Expr object is truncated. When EP_Reduced is set, then all
@@ -1477,7 +1477,10 @@ struct Expr {
u8 op; /* Operation performed by this node */
char affinity; /* The affinity of the column or 0 if not a column */
u16 flags; /* Various flags. EP_* See below */
- char *zToken; /* Token value. Zero terminated and dequoted */
+ union {
+ char *zToken; /* Token value. Zero terminated and dequoted */
+ int iValue; /* Integer value if EP_IntValue */
+ } u;
/* If the EP_TokenOnly flag is set in the Expr.flags mask, then no
** space is allocated for the fields below this point. An attempt to
@@ -1498,8 +1501,7 @@ struct Expr {
*********************************************************************/
int iTable; /* TK_COLUMN: cursor number of table holding column
- ** TK_REGISTER: register number
- ** EP_IntValue: integer value */
+ ** TK_REGISTER: register number */
i16 iColumn; /* TK_COLUMN: column index. -1 for rowid */
i16 iAgg; /* Which entry in pAggInfo->aCol[] or ->aFunc[] */
i16 iRightJoinTable; /* If EP_FromJoin, the right table of the join */
@@ -1525,7 +1527,7 @@ struct Expr {
#define EP_ExpCollate 0x0100 /* Collating sequence specified explicitly */
#define EP_AnyAff 0x0200 /* Can take a cached column of any affinity */
#define EP_FixedDest 0x0400 /* Result needed in a specific register */
-#define EP_IntValue 0x0800 /* Integer value contained in iTable */
+#define EP_IntValue 0x0800 /* Integer value contained in u.iValue */
#define EP_xIsSelect 0x1000 /* x.pSelect is valid (otherwise x.pList is) */
#define EP_Reduced 0x2000 /* Expr struct is EXPR_REDUCEDSIZE bytes only */
@@ -1535,7 +1537,20 @@ struct Expr {
/*
** The following are the meanings of bits in the Expr.flags2 field.
*/
-#define EP2_FreeToken 0x0001 /* Need to call sqlite3DbFree() on Expr.zToken */
+#define EP2_MallocedToken 0x0001 /* Need to sqlite3DbFree() Expr.zToken */
+#define EP2_Irreducible 0x0002 /* Cannot EXPRDUP_REDUCE this Expr */
+
+/*
+** The pseudo-routine sqlite3ExprSetIrreducible sets the EP2_Irreducible
+** flag on an expression structure. This flag is used for VV&A only. The
+** routine is implemented as a macro that only works when in debugging mode,
+** so as not to burden production code.
+*/
+#ifdef SQLITE_DEBUG
+# define ExprSetIrreducible(X) (X)->flags2 |= EP2_Irreducible
+#else
+# define ExprSetIrreducible(X)
+#endif
/*
** These macros can be used to test, set, or clear bits in the
diff --git a/src/tokenize.c b/src/tokenize.c
index 3e6c98c97..8bfda9bfd 100644
--- a/src/tokenize.c
+++ b/src/tokenize.c
@@ -15,7 +15,7 @@
** individual tokens and sends those tokens one-by-one over to the
** parser for analysis.
**
-** $Id: tokenize.c,v 1.157 2009/05/27 10:31:29 drh Exp $
+** $Id: tokenize.c,v 1.158 2009/05/28 01:00:55 drh Exp $
*/
#include "sqliteInt.h"
#include <stdlib.h>
diff --git a/src/trigger.c b/src/trigger.c
index 718e46e11..ab94f246a 100644
--- a/src/trigger.c
+++ b/src/trigger.c
@@ -10,7 +10,7 @@
*************************************************************************
**
**
-** $Id: trigger.c,v 1.140 2009/05/27 10:31:29 drh Exp $
+** $Id: trigger.c,v 1.141 2009/05/28 01:00:55 drh Exp $
*/
#include "sqliteInt.h"
@@ -375,15 +375,15 @@ TriggerStep *sqlite3TriggerInsertStep(
pTriggerStep = triggerStepAllocate(db, TK_INSERT, pTableName);
if( pTriggerStep ){
- pTriggerStep->pSelect = pSelect;
+ pTriggerStep->pSelect = sqlite3SelectDup(db, pSelect, EXPRDUP_REDUCE);
pTriggerStep->pIdList = pColumn;
- pTriggerStep->pExprList = pEList;
+ pTriggerStep->pExprList = sqlite3ExprListDup(db, pEList, EXPRDUP_REDUCE);
pTriggerStep->orconf = orconf;
}else{
sqlite3IdListDelete(db, pColumn);
- sqlite3ExprListDelete(db, pEList);
- sqlite3SelectDelete(db, pSelect);
}
+ sqlite3ExprListDelete(db, pEList);
+ sqlite3SelectDelete(db, pSelect);
return pTriggerStep;
}
@@ -403,14 +403,13 @@ TriggerStep *sqlite3TriggerUpdateStep(
TriggerStep *pTriggerStep;
pTriggerStep = triggerStepAllocate(db, TK_UPDATE, pTableName);
- if( pTriggerStep==0 ){
- sqlite3ExprListDelete(db, pEList);
- sqlite3ExprDelete(db, pWhere);
- return 0;
- }
- pTriggerStep->pExprList = pEList;
- pTriggerStep->pWhere = pWhere;
- pTriggerStep->orconf = orconf;
+ if( pTriggerStep ){
+ pTriggerStep->pExprList = sqlite3ExprListDup(db, pEList, EXPRDUP_REDUCE);
+ pTriggerStep->pWhere = sqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE);
+ pTriggerStep->orconf = orconf;
+ }
+ sqlite3ExprListDelete(db, pEList);
+ sqlite3ExprDelete(db, pWhere);
return pTriggerStep;
}
@@ -427,13 +426,11 @@ TriggerStep *sqlite3TriggerDeleteStep(
TriggerStep *pTriggerStep;
pTriggerStep = triggerStepAllocate(db, TK_DELETE, pTableName);
- if( pTriggerStep==0 ){
- sqlite3ExprDelete(db, pWhere);
- return 0;
+ if( pTriggerStep ){
+ pTriggerStep->pWhere = sqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE);
+ pTriggerStep->orconf = OE_Default;
}
- pTriggerStep->pWhere = pWhere;
- pTriggerStep->orconf = OE_Default;
-
+ sqlite3ExprDelete(db, pWhere);
return pTriggerStep;
}
@@ -640,7 +637,6 @@ static SrcList *targetSrcList(
Parse *pParse, /* The parsing context */
TriggerStep *pStep /* The trigger containing the target token */
){
- Token sDb; /* Dummy database name token */
int iDb; /* Index of the database to use */
SrcList *pSrc; /* SrcList to be returned */
diff --git a/src/update.c b/src/update.c
index e72a6354a..6eb92fb61 100644
--- a/src/update.c
+++ b/src/update.c
@@ -12,7 +12,7 @@
** This file contains C code routines that are called by the parser
** to handle UPDATE statements.
**
-** $Id: update.c,v 1.201 2009/05/27 10:31:29 drh Exp $
+** $Id: update.c,v 1.202 2009/05/28 01:00:55 drh Exp $
*/
#include "sqliteInt.h"
diff --git a/src/util.c b/src/util.c
index 76a8848db..00d13dd0c 100644
--- a/src/util.c
+++ b/src/util.c
@@ -14,7 +14,7 @@
** This file contains functions for allocating memory, comparing
** strings, and stuff like that.
**
-** $Id: util.c,v 1.255 2009/05/27 10:31:29 drh Exp $
+** $Id: util.c,v 1.256 2009/05/28 01:00:55 drh Exp $
*/
#include "sqliteInt.h"
#include <stdarg.h>
diff --git a/src/vdbemem.c b/src/vdbemem.c
index 004ea367f..f5120c86b 100644
--- a/src/vdbemem.c
+++ b/src/vdbemem.c
@@ -15,7 +15,7 @@
** only within the VDBE. Interface routines refer to a Mem using the
** name sqlite_value
**
-** $Id: vdbemem.c,v 1.145 2009/05/27 10:31:29 drh Exp $
+** $Id: vdbemem.c,v 1.146 2009/05/28 01:00:55 drh Exp $
*/
#include "sqliteInt.h"
#include "vdbeInt.h"
@@ -974,10 +974,15 @@ int sqlite3ValueFromExpr(
op = pExpr->op;
if( op==TK_STRING || op==TK_FLOAT || op==TK_INTEGER ){
- zVal = sqlite3DbStrDup(db, pExpr->zToken);
pVal = sqlite3ValueNew(db);
- if( !zVal || !pVal ) goto no_mem;
- sqlite3ValueSetStr(pVal, -1, zVal, SQLITE_UTF8, SQLITE_DYNAMIC);
+ if( pVal==0 ) goto no_mem;
+ if( ExprHasProperty(pExpr, EP_IntValue) ){
+ sqlite3VdbeMemSetInt64(pVal, (i64)pExpr->u.iValue);
+ }else{
+ zVal = sqlite3DbStrDup(db, pExpr->u.zToken);
+ if( zVal==0 ) goto no_mem;
+ sqlite3ValueSetStr(pVal, -1, zVal, SQLITE_UTF8, SQLITE_DYNAMIC);
+ }
if( (op==TK_INTEGER || op==TK_FLOAT ) && affinity==SQLITE_AFF_NONE ){
sqlite3ValueApplyAffinity(pVal, SQLITE_AFF_NUMERIC, SQLITE_UTF8);
}else{
@@ -996,11 +1001,11 @@ int sqlite3ValueFromExpr(
#ifndef SQLITE_OMIT_BLOB_LITERAL
else if( op==TK_BLOB ){
int nVal;
- assert( pExpr->zToken[0]=='x' || pExpr->zToken[0]=='X' );
- assert( pExpr->zToken[1]=='\'' );
+ assert( pExpr->u.zToken[0]=='x' || pExpr->u.zToken[0]=='X' );
+ assert( pExpr->u.zToken[1]=='\'' );
pVal = sqlite3ValueNew(db);
if( !pVal ) goto no_mem;
- zVal = &pExpr->zToken[2];
+ zVal = &pExpr->u.zToken[2];
nVal = sqlite3Strlen30(zVal)-1;
assert( zVal[nVal]=='\'' );
sqlite3VdbeMemSetStr(pVal, sqlite3HexToBlob(db, zVal, nVal), nVal/2,
diff --git a/src/walker.c b/src/walker.c
index 7be9e252f..f565bc55f 100644
--- a/src/walker.c
+++ b/src/walker.c
@@ -12,7 +12,7 @@
** This file contains routines used for walking the parser tree for
** an SQL statement.
**
-** $Id: walker.c,v 1.5 2009/05/27 10:31:29 drh Exp $
+** $Id: walker.c,v 1.6 2009/05/28 01:00:55 drh Exp $
*/
#include "sqliteInt.h"
#include <stdlib.h>
diff --git a/src/where.c b/src/where.c
index 7396bf198..48651ceb9 100644
--- a/src/where.c
+++ b/src/where.c
@@ -16,7 +16,7 @@
** so is applicable. Because this module is responsible for selecting
** indices, you might also think of this module as the "query optimizer".
**
-** $Id: where.c,v 1.398 2009/05/27 10:31:29 drh Exp $
+** $Id: where.c,v 1.399 2009/05/28 01:00:55 drh Exp $
*/
#include "sqliteInt.h"
@@ -658,7 +658,7 @@ static int isLikeOrGlob(
(pColl->type!=SQLITE_COLL_NOCASE || !*pnoCase) ){
return 0;
}
- z = pRight->zToken;
+ z = pRight->u.zToken;
cnt = 0;
if( z ){
while( (c=z[cnt])!=0 && c!=wc[0] && c!=wc[1] && c!=wc[2] ){
@@ -691,7 +691,7 @@ static int isMatchOfColumn(
if( pExpr->op!=TK_FUNCTION ){
return 0;
}
- if( sqlite3StrICmp(pExpr->zToken,"match")!=0 ){
+ if( sqlite3StrICmp(pExpr->u.zToken,"match")!=0 ){
return 0;
}
pList = pExpr->x.pList;
@@ -1161,12 +1161,12 @@ static void exprAnalyze(
pLeft = pExpr->x.pList->a[1].pExpr;
pRight = pExpr->x.pList->a[0].pExpr;
- pStr1 = sqlite3Expr(db, TK_STRING, pRight->zToken);
- if( pStr1 ) pStr1->zToken[nPattern] = 0;
+ pStr1 = sqlite3Expr(db, TK_STRING, pRight->u.zToken);
+ if( pStr1 ) pStr1->u.zToken[nPattern] = 0;
pStr2 = sqlite3ExprDup(db, pStr1, 0);
if( !db->mallocFailed ){
u8 c, *pC;
- pC = (u8*)&pStr2->zToken[nPattern-1];
+ pC = (u8*)&pStr2->u.zToken[nPattern-1];
c = *pC;
if( noCase ){
if( c=='@' ) isComplete = 0;