Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | The REGEXP operator is recognized. It tries to invoke a function named regexp() which does not exist in the native build. But users who want to can add an appropriate regexp() function using sqlite3_create_function(). (CVS 2478) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
42a626ace126f730f33ecb6c41ac5679 |
User & Date: | drh 2005-05-23 17:26:51.000 |
Context
2005-05-24
| ||
12:01 | Move a few things around to make building without the parser easier. (CVS 2479) (check-in: 5fadb464eb user: danielk1977 tags: trunk) | |
2005-05-23
| ||
17:26 | The REGEXP operator is recognized. It tries to invoke a function named regexp() which does not exist in the native build. But users who want to can add an appropriate regexp() function using sqlite3_create_function(). (CVS 2478) (check-in: 42a626ace1 user: drh tags: trunk) | |
15:06 | Make sure that the use of a double-quoted string literal does not trick the optimizer into using a correlated subquery when a static subquery would suffice. (CVS 2477) (check-in: ef4059e3af user: drh tags: trunk) | |
Changes
Changes to src/expr.c.
︙ | ︙ | |||
8 9 10 11 12 13 14 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains routines used for analyzing expressions and ** for generating VDBE code that evaluates expressions in SQLite. ** | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains routines used for analyzing expressions and ** for generating VDBE code that evaluates expressions in SQLite. ** ** $Id: expr.c,v 1.200 2005/05/23 17:26:51 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> /* ** Return the 'affinity' of the expression pExpr if any. ** |
︙ | ︙ | |||
990 991 992 993 994 995 996 | } return 0; } else { return 1; } } | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 | } return 0; } else { return 1; } } /* ** This routine is designed as an xFunc for walkExprTree(). ** ** Resolve symbolic names into TK_COLUMN operators for the current ** node in the expression tree. Return 0 to continue the search down ** the tree or 2 to abort the tree walk. ** |
︙ | ︙ | |||
1107 1108 1109 1110 1111 1112 1113 | } lookupName(pParse, pDb, pTable, pColumn, pNC, pExpr); return 1; } /* Resolve function names */ | | < < < < | > | 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 | } lookupName(pParse, pDb, pTable, pColumn, pNC, pExpr); return 1; } /* Resolve function names */ case TK_CONST_FUNC: case TK_FUNCTION: { ExprList *pList = pExpr->pList; /* The argument list */ int n = pList ? pList->nExpr : 0; /* Number of arguments */ int no_such_func = 0; /* True if no such function exists */ int wrong_num_args = 0; /* True if wrong number of arguments */ int is_agg = 0; /* True if is an aggregate function */ int i; int nId; /* Number of characters in function name */ const char *zId; /* The function name. */ FuncDef *pDef; /* Information about the function */ int enc = pParse->db->enc; /* The database encoding */ 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); if( pDef==0 ){ no_such_func = 1; }else{ wrong_num_args = 1; |
︙ | ︙ | |||
1540 1541 1542 1543 1544 1545 1546 | sqlite3VdbeAddOp(v, OP_AddImm, -1, 0); break; } case TK_AGG_FUNCTION: { sqlite3VdbeAddOp(v, OP_AggGet, 0, pExpr->iAgg); break; } | | < < < < | > | 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 | sqlite3VdbeAddOp(v, OP_AddImm, -1, 0); break; } case TK_AGG_FUNCTION: { sqlite3VdbeAddOp(v, OP_AggGet, 0, pExpr->iAgg); break; } case TK_CONST_FUNC: case TK_FUNCTION: { ExprList *pList = pExpr->pList; int nExpr = pList ? pList->nExpr : 0; FuncDef *pDef; int nId; const char *zId; int p2 = 0; int i; u8 enc = pParse->db->enc; CollSeq *pColl = 0; zId = pExpr->token.z; nId = pExpr->token.n; pDef = sqlite3FindFunction(pParse->db, zId, nId, nExpr, enc, 0); assert( pDef!=0 ); nExpr = sqlite3ExprCodeExprList(pParse, pList); for(i=0; i<nExpr && i<32; i++){ if( sqlite3ExprIsConstant(pList->a[i].pExpr) ){ p2 |= (1<<i); } |
︙ | ︙ |
Changes to src/parse.y.
︙ | ︙ | |||
10 11 12 13 14 15 16 | ** ************************************************************************* ** This file contains SQLite's grammar for SQL. Process this file ** using the lemon parser generator to generate C code that runs ** the parser. Lemon will also generate a header file containing ** numeric codes for all of the tokens. ** | | | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | ** ************************************************************************* ** This file contains SQLite's grammar for SQL. Process this file ** using the lemon parser generator to generate C code that runs ** the parser. Lemon will also generate a header file containing ** numeric codes for all of the tokens. ** ** @(#) $Id: parse.y,v 1.172 2005/05/23 17:26:51 drh Exp $ */ %token_prefix TK_ %token_type {Token} %default_type {Token} %extra_argument {Parse *pParse} %syntax_error { if( pParse->zErrMsg==0 ){ |
︙ | ︙ | |||
44 45 46 47 48 49 50 | }; /* ** An instance of this structure is used to store the LIKE, ** GLOB, NOT LIKE, and NOT GLOB operators. */ struct LikeOp { | | | | 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | }; /* ** An instance of this structure is used to store the LIKE, ** GLOB, NOT LIKE, and NOT GLOB operators. */ struct LikeOp { Token operator; /* "like" or "glob" or "regexp" */ int not; /* True if the NOT keyword is present */ }; /* ** An instance of the following structure describes the event of a ** TRIGGER. "a" is the event type, one of TK_UPDATE, TK_INSERT, ** TK_DELETE, or TK_INSTEAD. If the event is of the form ** |
︙ | ︙ | |||
71 72 73 74 75 76 77 | } // end %include // These are extra tokens used by the lexer but never seen by the // parser. We put them in a rule so that the parser generator will // add them to the parse.h output file. // %nonassoc END_OF_FILE ILLEGAL SPACE UNCLOSED_STRING COMMENT FUNCTION | | | 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 | } // end %include // These are extra tokens used by the lexer but never seen by the // parser. We put them in a rule so that the parser generator will // add them to the parse.h output file. // %nonassoc END_OF_FILE ILLEGAL SPACE UNCLOSED_STRING COMMENT FUNCTION COLUMN AGG_FUNCTION CONST_FUNC. // Input is a single SQL command input ::= cmdlist. cmdlist ::= cmdlist ecmd. cmdlist ::= ecmd. cmdx ::= cmd. { sqlite3FinishCoding(pParse); } ecmd ::= SEMI. |
︙ | ︙ | |||
149 150 151 152 153 154 155 | // The following directive causes tokens ABORT, AFTER, ASC, etc. to // fallback to ID if they will not parse as their original value. // This obviates the need for the "id" nonterminal. // %fallback ID ABORT AFTER ASC ATTACH BEFORE BEGIN CASCADE CONFLICT DATABASE DEFERRED DESC DETACH EACH END EXCLUSIVE EXPLAIN FAIL FOR | | | | | 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 | // The following directive causes tokens ABORT, AFTER, ASC, etc. to // fallback to ID if they will not parse as their original value. // This obviates the need for the "id" nonterminal. // %fallback ID ABORT AFTER ASC ATTACH BEFORE BEGIN CASCADE CONFLICT DATABASE DEFERRED DESC DETACH EACH END EXCLUSIVE EXPLAIN FAIL FOR 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 CTIME_KW ALTER . // Define operator precedence early so that this is the first occurance // of the operator tokens in the grammer. Keeping the operators together // causes them to be assigned integer values that are close together, // which keeps parser tables smaller. // // The token values assigned to these symbols is determined by the order // in which lemon first sees them. It must be the case that ISNULL/NOTNULL, // NE/EQ, GT/LE, and GE/LT are separated by only a single value. See // the sqlite3ExprIfFalse() routine for additional information on this // constraint. // %left OR. %left AND. %right NOT. %left IS LIKE_KW BETWEEN IN ISNULL NOTNULL NE EQ. %left GT LE LT GE. %right ESCAPE. %left BITAND BITOR LSHIFT RSHIFT. %left PLUS MINUS. %left STAR SLASH REM. %left CONCAT. %right UMINUS UPLUS BITNOT. |
︙ | ︙ | |||
623 624 625 626 627 628 629 | A = sqlite3ExprFunction(Y, &X); sqlite3ExprSpan(A,&X,&E); } expr(A) ::= ID(X) LP STAR RP(E). { A = sqlite3ExprFunction(0, &X); sqlite3ExprSpan(A,&X,&E); } | | | > | > > | < | < | | < | 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 | A = sqlite3ExprFunction(Y, &X); sqlite3ExprSpan(A,&X,&E); } expr(A) ::= ID(X) LP STAR RP(E). { A = sqlite3ExprFunction(0, &X); sqlite3ExprSpan(A,&X,&E); } 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) GT(OP) expr(Y). {A = sqlite3Expr(@OP, X, Y, 0);} expr(A) ::= expr(X) LE(OP) expr(Y). {A = sqlite3Expr(@OP, X, Y, 0);} expr(A) ::= expr(X) GE(OP) expr(Y). {A = sqlite3Expr(@OP, X, Y, 0);} expr(A) ::= expr(X) NE(OP) expr(Y). {A = sqlite3Expr(@OP, X, Y, 0);} expr(A) ::= expr(X) EQ(OP) expr(Y). {A = sqlite3Expr(@OP, X, Y, 0);} expr(A) ::= expr(X) BITAND(OP) expr(Y). {A = sqlite3Expr(@OP, X, Y, 0);} expr(A) ::= expr(X) BITOR(OP) expr(Y). {A = sqlite3Expr(@OP, X, Y, 0);} expr(A) ::= expr(X) LSHIFT(OP) expr(Y). {A = sqlite3Expr(@OP, X, Y, 0);} expr(A) ::= expr(X) RSHIFT(OP) expr(Y). {A = sqlite3Expr(@OP, X, Y, 0);} expr(A) ::= expr(X) PLUS(OP) expr(Y). {A = sqlite3Expr(@OP, X, Y, 0);} expr(A) ::= expr(X) MINUS(OP) expr(Y). {A = sqlite3Expr(@OP, X, Y, 0);} expr(A) ::= expr(X) STAR(OP) expr(Y). {A = sqlite3Expr(@OP, X, Y, 0);} expr(A) ::= expr(X) SLASH(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_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_KW] { ExprList *pList = sqlite3ExprListAppend(0, Y, 0); pList = sqlite3ExprListAppend(pList, X, 0); if( E ){ pList = sqlite3ExprListAppend(pList, E, 0); } A = sqlite3ExprFunction(pList, &OP.operator); if( OP.not ) A = sqlite3Expr(TK_NOT, A, 0, 0); sqlite3ExprSpan(A, &X->span, &Y->span); } expr(A) ::= expr(X) ISNULL(E). { A = sqlite3Expr(TK_ISNULL, X, 0, 0); sqlite3ExprSpan(A,&X->span,&E); |
︙ | ︙ |
Changes to tool/mkkeywordhash.c.
︙ | ︙ | |||
121 122 123 124 125 126 127 | { "COLLATE", "TK_COLLATE", ALWAYS }, { "COLUMN", "TK_COLUMNKW", ALTER }, { "COMMIT", "TK_COMMIT", ALWAYS }, { "CONFLICT", "TK_CONFLICT", CONFLICT }, { "CONSTRAINT", "TK_CONSTRAINT", ALWAYS }, { "CREATE", "TK_CREATE", ALWAYS }, { "CROSS", "TK_JOIN_KW", ALWAYS }, | | | | | 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 | { "COLLATE", "TK_COLLATE", ALWAYS }, { "COLUMN", "TK_COLUMNKW", ALTER }, { "COMMIT", "TK_COMMIT", ALWAYS }, { "CONFLICT", "TK_CONFLICT", CONFLICT }, { "CONSTRAINT", "TK_CONSTRAINT", ALWAYS }, { "CREATE", "TK_CREATE", ALWAYS }, { "CROSS", "TK_JOIN_KW", 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 }, { "DEFERRABLE", "TK_DEFERRABLE", FKEY }, { "DELETE", "TK_DELETE", ALWAYS }, { "DESC", "TK_DESC", ALWAYS }, { "DETACH", "TK_DETACH", ATTACH }, |
︙ | ︙ | |||
146 147 148 149 150 151 152 | { "EXISTS", "TK_EXISTS", SUBQUERY }, { "EXPLAIN", "TK_EXPLAIN", EXPLAIN }, { "FAIL", "TK_FAIL", CONFLICT|TRIGGER }, { "FOR", "TK_FOR", TRIGGER }, { "FOREIGN", "TK_FOREIGN", FKEY }, { "FROM", "TK_FROM", ALWAYS }, { "FULL", "TK_JOIN_KW", ALWAYS }, | | | > | 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 | { "EXISTS", "TK_EXISTS", SUBQUERY }, { "EXPLAIN", "TK_EXPLAIN", EXPLAIN }, { "FAIL", "TK_FAIL", CONFLICT|TRIGGER }, { "FOR", "TK_FOR", TRIGGER }, { "FOREIGN", "TK_FOREIGN", FKEY }, { "FROM", "TK_FROM", ALWAYS }, { "FULL", "TK_JOIN_KW", ALWAYS }, { "GLOB", "TK_LIKE_KW", ALWAYS }, { "GROUP", "TK_GROUP", ALWAYS }, { "HAVING", "TK_HAVING", ALWAYS }, { "IGNORE", "TK_IGNORE", CONFLICT|TRIGGER }, { "IMMEDIATE", "TK_IMMEDIATE", ALWAYS }, { "IN", "TK_IN", ALWAYS }, { "INDEX", "TK_INDEX", ALWAYS }, { "INITIALLY", "TK_INITIALLY", FKEY }, { "INNER", "TK_JOIN_KW", ALWAYS }, { "INSERT", "TK_INSERT", ALWAYS }, { "INSTEAD", "TK_INSTEAD", TRIGGER }, { "INTERSECT", "TK_INTERSECT", COMPOUND }, { "INTO", "TK_INTO", ALWAYS }, { "IS", "TK_IS", ALWAYS }, { "ISNULL", "TK_ISNULL", ALWAYS }, { "JOIN", "TK_JOIN", ALWAYS }, { "KEY", "TK_KEY", ALWAYS }, { "LEFT", "TK_JOIN_KW", ALWAYS }, { "LIKE", "TK_LIKE_KW", ALWAYS }, { "LIMIT", "TK_LIMIT", ALWAYS }, { "MATCH", "TK_MATCH", ALWAYS }, { "NATURAL", "TK_JOIN_KW", ALWAYS }, { "NOT", "TK_NOT", ALWAYS }, { "NOTNULL", "TK_NOTNULL", ALWAYS }, { "NULL", "TK_NULL", ALWAYS }, { "OF", "TK_OF", ALWAYS }, { "OFFSET", "TK_OFFSET", ALWAYS }, { "ON", "TK_ON", ALWAYS }, { "OR", "TK_OR", ALWAYS }, { "ORDER", "TK_ORDER", ALWAYS }, { "OUTER", "TK_JOIN_KW", ALWAYS }, { "PRAGMA", "TK_PRAGMA", PRAGMA }, { "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 }, { "RESTRICT", "TK_RESTRICT", FKEY }, { "RIGHT", "TK_JOIN_KW", ALWAYS }, { "ROLLBACK", "TK_ROLLBACK", ALWAYS }, { "ROW", "TK_ROW", TRIGGER }, |
︙ | ︙ |