-C Make\ssure\sthat\sthe\suse\sof\sa\sdouble-quoted\sstring\sliteral\sdoes\snot\strick\nthe\soptimizer\sinto\susing\sa\scorrelated\ssubquery\swhen\sa\sstatic\nsubquery\swould\ssuffice.\s(CVS\s2477)
-D 2005-05-23T15:06:39
+C The\sREGEXP\soperator\sis\srecognized.\s\sIt\stries\sto\sinvoke\sa\sfunction\snamed\r\nregexp()\swhich\sdoes\snot\sexist\sin\sthe\snative\sbuild.\s\sBut\susers\swho\swant\sto\r\ncan\sadd\san\sappropriate\sregexp()\sfunction\susing\ssqlite3_create_function().\s(CVS\s2478)
+D 2005-05-23T17:26:51
F Makefile.in 5c00d0037104de2a50ac7647a5f12769795957a3
F Makefile.linux-gcc 06be33b2a9ad4f005a5f42b22c4a19dab3cbb5c7
F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
F src/date.c 2134ef4388256e8247405178df8a61bd60dc180a
F src/delete.c 75b53db21aa1879d3655bbbc208007db31d58a63
F src/experimental.c 50c1e3b34f752f4ac10c36f287db095c2b61766d
-F src/expr.c f2ff12d9970d844564ec8b3ce4ea702bf6730b6a
+F src/expr.c d0fbb951fd260feb2e2028c5ec078e98daca5bb6
F src/func.c d09df82e35ef988cd28a3ffd63cd772271b7def9
F src/hash.c 2b1b13f7400e179631c83a1be0c664608c8f021f
F src/hash.h 1b0c445e1c89ff2aaad9b4605ba61375af001e84
F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b
F src/pager.c f86d79d37eb4e30d8e2201dbe12497370719320c
F src/pager.h 0d9153d6269d60d04af3dd84a0cc0a96253cf4a4
-F src/parse.y 3e314b3a96b199b0501ed426f2cee3392ffce806
+F src/parse.y 72cd7553f05fbc7b63ea9476108d0da6237f2818
F src/pragma.c 0ed94a1aa982802a9cf2a932c48d99b60683fa53
F src/printf.c 3d20b21cfecadacecac3fb7274e746cb81d3d357
F src/random.c eff68e3f257e05e81eae6c4d50a51eb88beb4ff3
F tool/memleak.awk 4e7690a51bf3ed757e611273d43fe3f65b510133
F tool/memleak2.awk 9cc20c8e8f3c675efac71ea0721ee6874a1566e8
F tool/memleak3.tcl 009da0ea82dc5893edca76cf1a21fb7260e9412e
-F tool/mkkeywordhash.c 02ac5c523fd6d55364cd70aded5c36ba6651a6bf
+F tool/mkkeywordhash.c 596389943f516bf6eaddd46659e7b87b16ea7c33
F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e x
F tool/opcodeDoc.awk b3a2a3d5d3075b8bd90b7afe24283efdd586659c
F tool/report1.txt 9eae07f26a8fc53889b45fc833a66a33daa22816
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
F www/version3.tcl a99cf5f6d8bd4d5537584a2b342f0fb9fa601d8b
F www/whentouse.tcl 528299b8316726dbcc5548e9aa0648c8b1bd055b
-P f7b76d02e003faf0310b87949d3cb0f38062853f
-R 7f9d3157fe368f24bc8a9f1b20f7fe23
+P ef4059e3afa1a61a9e59df00cdfedc57d8df9fec
+R 8996a199d8872550587b98a7437c931f
U drh
-Z b4157a0f7dc132bb0373ae1877998e51
+Z 797c50f3e25833784eb0ca0d6800d861
-ef4059e3afa1a61a9e59df00cdfedc57d8df9fec
\ No newline at end of file
+42a626ace126f730f33ecb6c41ac5679d6766a31
\ No newline at end of file
** This file contains routines used for analyzing expressions and
** for generating VDBE code that evaluates expressions in SQLite.
**
-** $Id: expr.c,v 1.199 2005/05/23 15:06:39 drh Exp $
+** $Id: expr.c,v 1.200 2005/05/23 17:26:51 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
}
}
-/*
-** pExpr is a node that defines a function of some kind. It might
-** be a syntactic function like "count(x)" or it might be a function
-** that implements an operator, like "a LIKE b".
-**
-** This routine makes *pzName point to the name of the function and
-** *pnName hold the number of characters in the function name.
-*/
-static void getFunctionName(Expr *pExpr, const char **pzName, int *pnName){
- switch( pExpr->op ){
- case TK_FUNCTION: {
- *pzName = pExpr->token.z;
- *pnName = pExpr->token.n;
- break;
- }
- case TK_LIKE: {
- *pzName = "like";
- *pnName = 4;
- break;
- }
- case TK_GLOB: {
- *pzName = "glob";
- *pnName = 4;
- break;
- }
- case TK_CTIME: {
- *pzName = "current_time";
- *pnName = 12;
- break;
- }
- case TK_CDATE: {
- *pzName = "current_date";
- *pnName = 12;
- break;
- }
- case TK_CTIMESTAMP: {
- *pzName = "current_timestamp";
- *pnName = 17;
- break;
- }
- }
-}
-
/*
** This routine is designed as an xFunc for walkExprTree().
**
/* Resolve function names
*/
- case TK_CTIME:
- case TK_CTIMESTAMP:
- case TK_CDATE:
- case TK_GLOB:
- case TK_LIKE:
+ case TK_CONST_FUNC:
case TK_FUNCTION: {
ExprList *pList = pExpr->pList; /* The argument list */
int n = pList ? pList->nExpr : 0; /* Number of arguments */
FuncDef *pDef; /* Information about the function */
int enc = pParse->db->enc; /* The database encoding */
- getFunctionName(pExpr, &zId, &nId);
+ zId = pExpr->token.z;
+ nId = pExpr->token.n;
pDef = sqlite3FindFunction(pParse->db, zId, nId, n, enc, 0);
if( pDef==0 ){
pDef = sqlite3FindFunction(pParse->db, zId, nId, -1, enc, 0);
sqlite3VdbeAddOp(v, OP_AggGet, 0, pExpr->iAgg);
break;
}
- case TK_CDATE:
- case TK_CTIME:
- case TK_CTIMESTAMP:
- case TK_GLOB:
- case TK_LIKE:
+ case TK_CONST_FUNC:
case TK_FUNCTION: {
ExprList *pList = pExpr->pList;
int nExpr = pList ? pList->nExpr : 0;
int i;
u8 enc = pParse->db->enc;
CollSeq *pColl = 0;
- getFunctionName(pExpr, &zId, &nId);
+ zId = pExpr->token.z;
+ nId = pExpr->token.n;
pDef = sqlite3FindFunction(pParse->db, zId, nId, nExpr, enc, 0);
assert( pDef!=0 );
nExpr = sqlite3ExprCodeExprList(pParse, pList);
** the parser. Lemon will also generate a header file containing
** numeric codes for all of the tokens.
**
-** @(#) $Id: parse.y,v 1.171 2005/04/22 02:38:38 drh Exp $
+** @(#) $Id: parse.y,v 1.172 2005/05/23 17:26:51 drh Exp $
*/
%token_prefix TK_
%token_type {Token}
** GLOB, NOT LIKE, and NOT GLOB operators.
*/
struct LikeOp {
- int opcode; /* Either TK_GLOB or TK_LIKE */
- int not; /* True if the NOT keyword is present */
+ Token operator; /* "like" or "glob" or "regexp" */
+ int not; /* True if the NOT keyword is present */
};
/*
// add them to the parse.h output file.
//
%nonassoc END_OF_FILE ILLEGAL SPACE UNCLOSED_STRING COMMENT FUNCTION
- COLUMN AGG_FUNCTION.
+ COLUMN AGG_FUNCTION CONST_FUNC.
// Input is a single SQL command
input ::= cmdlist.
%fallback ID
ABORT AFTER ASC ATTACH BEFORE BEGIN CASCADE CONFLICT
DATABASE DEFERRED DESC DETACH EACH END EXCLUSIVE EXPLAIN FAIL FOR
- GLOB IGNORE IMMEDIATE INITIALLY INSTEAD LIKE MATCH KEY
+ IGNORE IMMEDIATE INITIALLY INSTEAD LIKE_KW MATCH KEY
OF OFFSET PRAGMA RAISE REPLACE RESTRICT ROW STATEMENT
TEMP TRIGGER VACUUM VIEW
%ifdef SQLITE_OMIT_COMPOUND_SELECT
EXCEPT INTERSECT UNION
%endif
- REINDEX RENAME CDATE CTIME CTIMESTAMP ALTER
+ REINDEX RENAME CTIME_KW ALTER
.
// Define operator precedence early so that this is the first occurance
%left OR.
%left AND.
%right NOT.
-%left IS LIKE GLOB BETWEEN IN ISNULL NOTNULL NE EQ.
+%left IS LIKE_KW BETWEEN IN ISNULL NOTNULL NE EQ.
%left GT LE LT GE.
%right ESCAPE.
%left BITAND BITOR LSHIFT RSHIFT.
A = sqlite3ExprFunction(0, &X);
sqlite3ExprSpan(A,&X,&E);
}
-term(A) ::= CTIME(OP). {A = sqlite3Expr(@OP,0,0,0);}
-term(A) ::= CDATE(OP). {A = sqlite3Expr(@OP,0,0,0);}
-term(A) ::= CTIMESTAMP(OP). {A = sqlite3Expr(@OP,0,0,0);}
+term(A) ::= CTIME_KW(OP). {
+ /* The CURRENT_TIME, CURRENT_DATE, and CURRENT_TIMESTAMP values are
+ ** treated as functions that return constants */
+ A = sqlite3ExprFunction(0,&OP);
+ if( A ) A->op = TK_CONST_FUNC;
+}
expr(A) ::= expr(X) AND(OP) expr(Y). {A = sqlite3Expr(@OP, X, Y, 0);}
expr(A) ::= expr(X) OR(OP) expr(Y). {A = sqlite3Expr(@OP, X, Y, 0);}
expr(A) ::= expr(X) LT(OP) expr(Y). {A = sqlite3Expr(@OP, X, Y, 0);}
expr(A) ::= expr(X) REM(OP) expr(Y). {A = sqlite3Expr(@OP, X, Y, 0);}
expr(A) ::= expr(X) CONCAT(OP) expr(Y). {A = sqlite3Expr(@OP, X, Y, 0);}
%type likeop {struct LikeOp}
-likeop(A) ::= LIKE. {A.opcode = TK_LIKE; A.not = 0;}
-likeop(A) ::= GLOB. {A.opcode = TK_GLOB; A.not = 0;}
-likeop(A) ::= NOT LIKE. {A.opcode = TK_LIKE; A.not = 1;}
-likeop(A) ::= NOT GLOB. {A.opcode = TK_GLOB; A.not = 1;}
+likeop(A) ::= LIKE_KW(X). {A.operator = X; A.not = 0;}
+likeop(A) ::= NOT LIKE_KW(X). {A.operator = X; A.not = 1;}
%type escape {Expr*}
escape(X) ::= ESCAPE expr(A). [ESCAPE] {X = A;}
escape(X) ::= . [ESCAPE] {X = 0;}
-expr(A) ::= expr(X) likeop(OP) expr(Y) escape(E). [LIKE] {
+expr(A) ::= expr(X) likeop(OP) expr(Y) escape(E). [LIKE_KW] {
ExprList *pList = sqlite3ExprListAppend(0, Y, 0);
pList = sqlite3ExprListAppend(pList, X, 0);
if( E ){
pList = sqlite3ExprListAppend(pList, E, 0);
}
- A = sqlite3ExprFunction(pList, 0);
- if( A ) A->op = OP.opcode;
+ A = sqlite3ExprFunction(pList, &OP.operator);
if( OP.not ) A = sqlite3Expr(TK_NOT, A, 0, 0);
sqlite3ExprSpan(A, &X->span, &Y->span);
}
{ "CONSTRAINT", "TK_CONSTRAINT", ALWAYS },
{ "CREATE", "TK_CREATE", ALWAYS },
{ "CROSS", "TK_JOIN_KW", ALWAYS },
- { "CURRENT_DATE", "TK_CDATE", ALWAYS },
- { "CURRENT_TIME", "TK_CTIME", ALWAYS },
- { "CURRENT_TIMESTAMP","TK_CTIMESTAMP", ALWAYS },
+ { "CURRENT_DATE", "TK_CTIME_KW", ALWAYS },
+ { "CURRENT_TIME", "TK_CTIME_KW", ALWAYS },
+ { "CURRENT_TIMESTAMP","TK_CTIME_KW", ALWAYS },
{ "DATABASE", "TK_DATABASE", ATTACH },
{ "DEFAULT", "TK_DEFAULT", ALWAYS },
{ "DEFERRED", "TK_DEFERRED", ALWAYS },
{ "FOREIGN", "TK_FOREIGN", FKEY },
{ "FROM", "TK_FROM", ALWAYS },
{ "FULL", "TK_JOIN_KW", ALWAYS },
- { "GLOB", "TK_GLOB", ALWAYS },
+ { "GLOB", "TK_LIKE_KW", ALWAYS },
{ "GROUP", "TK_GROUP", ALWAYS },
{ "HAVING", "TK_HAVING", ALWAYS },
{ "IGNORE", "TK_IGNORE", CONFLICT|TRIGGER },
{ "JOIN", "TK_JOIN", ALWAYS },
{ "KEY", "TK_KEY", ALWAYS },
{ "LEFT", "TK_JOIN_KW", ALWAYS },
- { "LIKE", "TK_LIKE", ALWAYS },
+ { "LIKE", "TK_LIKE_KW", ALWAYS },
{ "LIMIT", "TK_LIMIT", ALWAYS },
{ "MATCH", "TK_MATCH", ALWAYS },
{ "NATURAL", "TK_JOIN_KW", ALWAYS },
{ "PRIMARY", "TK_PRIMARY", ALWAYS },
{ "RAISE", "TK_RAISE", TRIGGER },
{ "REFERENCES", "TK_REFERENCES", FKEY },
+ { "REGEXP", "TK_LIKE_KW", ALWAYS },
{ "REINDEX", "TK_REINDEX", REINDEX },
{ "RENAME", "TK_RENAME", ALTER },
{ "REPLACE", "TK_REPLACE", CONFLICT },