diff options
author | drh <drh@noemail.net> | 2004-02-25 13:47:31 +0000 |
---|---|---|
committer | drh <drh@noemail.net> | 2004-02-25 13:47:31 +0000 |
commit | 268380ca9ed4e5c1ac172f9650d6192bafd0346d (patch) | |
tree | da7230d896c790bebb5fee48a5bb088880691889 /src/expr.c | |
parent | d41d73d556d256f7732fb6a79063457b90f5dabc (diff) | |
download | sqlite-268380ca9ed4e5c1ac172f9650d6192bafd0346d.tar.gz sqlite-268380ca9ed4e5c1ac172f9650d6192bafd0346d.zip |
Min() and max() functions honor the distinction between TEXT and NUMERIC
data. Ticket #623. typeof() is now a user function. Some tests are
now failing due to ticket #521. (CVS 1272)
FossilOrigin-Name: adbe31adf1ad0ca723203ca3d7dc480324c60d43
Diffstat (limited to 'src/expr.c')
-rw-r--r-- | src/expr.c | 55 |
1 files changed, 34 insertions, 21 deletions
diff --git a/src/expr.c b/src/expr.c index 7b96ad3f9..dca48e35e 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.111 2004/02/22 20:05:01 drh Exp $ +** $Id: expr.c,v 1.112 2004/02/25 13:47:31 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> @@ -823,7 +823,6 @@ int sqliteExprCheck(Parse *pParse, Expr *pExpr, int allowAgg, int *pIsAgg){ case TK_FUNCTION: { int n = pExpr->pList ? pExpr->pList->nExpr : 0; /* Number of arguments */ int no_such_func = 0; /* True if no such function exists */ - int is_type_of = 0; /* True if is the special TypeOf() function */ int wrong_num_args = 0; /* True if wrong number of arguments */ int is_agg = 0; /* True if is an aggregate function */ int i; @@ -836,11 +835,7 @@ int sqliteExprCheck(Parse *pParse, Expr *pExpr, int allowAgg, int *pIsAgg){ if( pDef==0 ){ pDef = sqliteFindFunction(pParse->db, zId, nId, -1, 0); if( pDef==0 ){ - if( n==1 && nId==6 && sqliteStrNICmp(zId, "typeof", 6)==0 ){ - is_type_of = 1; - }else { - no_such_func = 1; - } + no_such_func = 1; }else{ wrong_num_args = 1; } @@ -868,16 +863,7 @@ int sqliteExprCheck(Parse *pParse, Expr *pExpr, int allowAgg, int *pIsAgg){ allowAgg && !is_agg, pIsAgg); } if( pDef==0 ){ - if( is_type_of ){ - pExpr->op = TK_STRING; - if( sqliteExprType(pExpr->pList->a[0].pExpr)==SQLITE_SO_NUM ){ - pExpr->token.z = "numeric"; - pExpr->token.n = 7; - }else{ - pExpr->token.z = "text"; - pExpr->token.n = 4; - } - } + /* Already reported an error */ }else if( pDef->dataType>=0 ){ if( pDef->dataType<n ){ pExpr->dataType = @@ -1155,7 +1141,6 @@ void sqliteExprCode(Parse *pParse, Expr *pExpr){ case TK_GLOB: case TK_LIKE: case TK_FUNCTION: { - int i; ExprList *pList = pExpr->pList; int nExpr = pList ? pList->nExpr : 0; FuncDef *pDef; @@ -1164,9 +1149,7 @@ void sqliteExprCode(Parse *pParse, Expr *pExpr){ getFunctionName(pExpr, &zId, &nId); pDef = sqliteFindFunction(pParse->db, zId, nId, nExpr, 0); assert( pDef!=0 ); - for(i=0; i<nExpr; i++){ - sqliteExprCode(pParse, pList->a[i].pExpr); - } + nExpr = sqliteExprCodeExprList(pParse, pList, pDef->includeTypes); sqliteVdbeOp3(v, OP_Function, nExpr, 0, (char*)pDef, P3_POINTER); break; } @@ -1271,6 +1254,36 @@ void sqliteExprCode(Parse *pParse, Expr *pExpr){ } /* +** Generate code that pushes the value of every element of the given +** expression list onto the stack. If the includeTypes flag is true, +** then also push a string that is the datatype of each element onto +** the stack after the value. +** +** Return the number of elements pushed onto the stack. +*/ +int sqliteExprCodeExprList( + Parse *pParse, /* Parsing context */ + ExprList *pList, /* The expression list to be coded */ + int includeTypes /* TRUE to put datatypes on the stack too */ +){ + struct ExprList_item *pItem; + int i, n; + Vdbe *v; + if( pList==0 ) return 0; + v = sqliteGetVdbe(pParse); + n = pList->nExpr; + for(pItem=pList->a, i=0; i<n; i++, pItem++){ + sqliteExprCode(pParse, pItem->pExpr); + if( includeTypes ){ + sqliteVdbeOp3(v, OP_String, 0, 0, + sqliteExprType(pItem->pExpr)==SQLITE_SO_NUM ? "numeric" : "text", + P3_STATIC); + } + } + return includeTypes ? n*2 : n; +} + +/* ** Generate code for a boolean expression such that a jump is made ** to the label "dest" if the expression is true but execution ** continues straight thru if the expression is false. |