Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Parse common table expressions. But do not do anything with them (yet). |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | common-table-expr |
Files: | files | file ages | folders |
SHA1: |
da98b7205eb3d7ec2ddbf8a8e24eee0b |
User & Date: | drh 2014-01-11 13:22:17.016 |
Context
2014-01-11
| ||
19:19 | Update the parser so that sub-queries and CTEs may have WITH clauses. (check-in: 704d3931b8 user: dan tags: common-table-expr) | |
13:22 | Parse common table expressions. But do not do anything with them (yet). (check-in: da98b7205e user: drh tags: common-table-expr) | |
12:52 | In LEMON, limit the size of the grammar file to 100MB. This ensures that the program will never experience integer overflow. To be doubly sure, use calloc() instead of malloc() when allocating arrays. (check-in: 29ba458d84 user: drh tags: trunk) | |
Changes
Changes to src/build.c.
︙ | ︙ | |||
4194 4195 4196 4197 4198 4199 4200 | }else{ pIdx->pKeyInfo = pKey; } } } return sqlite3KeyInfoRef(pIdx->pKeyInfo); } | > > > > > > > > > > > > > > > > > > > > > | 4194 4195 4196 4197 4198 4199 4200 4201 4202 4203 4204 4205 4206 4207 4208 4209 4210 4211 4212 4213 4214 4215 4216 4217 4218 4219 4220 4221 | }else{ pIdx->pKeyInfo = pKey; } } } return sqlite3KeyInfoRef(pIdx->pKeyInfo); } #ifndef SQLITE_OMIT_CTE /* This routine is invoked when a single with_query of a ** common-table-expression has been parsed. Record the query. */ void sqlite3CteAdd( Parse *pParse, /* Parsing context */ Token *pName, /* Name of the common-table */ ExprList *pArgList, /* Optional column name list for the table */ Select *pQuery /* Query used to initialize the table */ ){ sqlite3ExprListDelete(pParse->db, pArgList); sqlite3SelectDelete(pParse->db, pQuery); } /* This routine is invoked at the end of the entire WITH clause. */ void sqlite3CteFinish(Parse *pParse, int isRecursive){ /* TBD */ } #endif /* !defined(SQLITE_OMIT_CTE) */ |
Changes to src/parse.y.
︙ | ︙ | |||
200 201 202 203 204 205 206 | // fallback to ID if they will not parse as their original value. // This obviates the need for the "id" nonterminal. // %fallback ID ABORT ACTION AFTER ANALYZE ASC ATTACH BEFORE BEGIN BY CASCADE CAST COLUMNKW CONFLICT DATABASE DEFERRED DESC DETACH EACH END EXCLUSIVE EXPLAIN FAIL FOR IGNORE IMMEDIATE INITIALLY INSTEAD LIKE_KW MATCH NO PLAN | | | | 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 | // fallback to ID if they will not parse as their original value. // This obviates the need for the "id" nonterminal. // %fallback ID ABORT ACTION AFTER ANALYZE ASC ATTACH BEFORE BEGIN BY CASCADE CAST COLUMNKW CONFLICT DATABASE DEFERRED DESC DETACH EACH END EXCLUSIVE EXPLAIN FAIL FOR IGNORE IMMEDIATE INITIALLY INSTEAD LIKE_KW MATCH NO PLAN QUERY KEY OF OFFSET PRAGMA RAISE RECURSIVE RELEASE REPLACE RESTRICT ROW ROLLBACK SAVEPOINT TEMP TRIGGER VACUUM VIEW VIRTUAL WITH WITHOUT %ifdef SQLITE_OMIT_COMPOUND_SELECT EXCEPT INTERSECT UNION %endif SQLITE_OMIT_COMPOUND_SELECT REINDEX RENAME CTIME_KW IF . %wildcard ANY. |
︙ | ︙ | |||
392 393 394 395 396 397 398 | cmd ::= DROP VIEW ifexists(E) fullname(X). { sqlite3DropTable(pParse, X, 1, E); } %endif SQLITE_OMIT_VIEW //////////////////////// The SELECT statement ///////////////////////////////// // | | | 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 | cmd ::= DROP VIEW ifexists(E) fullname(X). { sqlite3DropTable(pParse, X, 1, E); } %endif SQLITE_OMIT_VIEW //////////////////////// The SELECT statement ///////////////////////////////// // cmd ::= with select(X). { SelectDest dest = {SRT_Output, 0, 0, 0, 0}; sqlite3Select(pParse, X, &dest); sqlite3ExplainBegin(pParse->pVdbe); sqlite3ExplainSelect(pParse->pVdbe, X); sqlite3ExplainFinish(pParse->pVdbe); sqlite3SelectDelete(pParse->db, X); } |
︙ | ︙ | |||
644 645 646 647 648 649 650 | {A.pLimit = X.pExpr; A.pOffset = Y.pExpr;} limit_opt(A) ::= LIMIT expr(X) COMMA expr(Y). {A.pOffset = X.pExpr; A.pLimit = Y.pExpr;} /////////////////////////// The DELETE statement ///////////////////////////// // %ifdef SQLITE_ENABLE_UPDATE_DELETE_LIMIT | | | | | | | 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 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 | {A.pLimit = X.pExpr; A.pOffset = Y.pExpr;} limit_opt(A) ::= LIMIT expr(X) COMMA expr(Y). {A.pOffset = X.pExpr; A.pLimit = Y.pExpr;} /////////////////////////// The DELETE statement ///////////////////////////// // %ifdef SQLITE_ENABLE_UPDATE_DELETE_LIMIT cmd ::= with DELETE FROM fullname(X) indexed_opt(I) where_opt(W) orderby_opt(O) limit_opt(L). { sqlite3SrcListIndexedBy(pParse, X, &I); W = sqlite3LimitWhere(pParse, X, W, O, L.pLimit, L.pOffset, "DELETE"); sqlite3DeleteFrom(pParse,X,W); } %endif %ifndef SQLITE_ENABLE_UPDATE_DELETE_LIMIT cmd ::= with DELETE FROM fullname(X) indexed_opt(I) where_opt(W). { sqlite3SrcListIndexedBy(pParse, X, &I); sqlite3DeleteFrom(pParse,X,W); } %endif %type where_opt {Expr*} %destructor where_opt {sqlite3ExprDelete(pParse->db, $$);} where_opt(A) ::= . {A = 0;} where_opt(A) ::= WHERE expr(X). {A = X.pExpr;} ////////////////////////// The UPDATE command //////////////////////////////// // %ifdef SQLITE_ENABLE_UPDATE_DELETE_LIMIT cmd ::= with UPDATE orconf(R) fullname(X) indexed_opt(I) SET setlist(Y) where_opt(W) orderby_opt(O) limit_opt(L). { sqlite3SrcListIndexedBy(pParse, X, &I); sqlite3ExprListCheckLength(pParse,Y,"set list"); W = sqlite3LimitWhere(pParse, X, W, O, L.pLimit, L.pOffset, "UPDATE"); sqlite3Update(pParse,X,Y,W,R); } %endif %ifndef SQLITE_ENABLE_UPDATE_DELETE_LIMIT cmd ::= with UPDATE orconf(R) fullname(X) indexed_opt(I) SET setlist(Y) where_opt(W). { sqlite3SrcListIndexedBy(pParse, X, &I); sqlite3ExprListCheckLength(pParse,Y,"set list"); sqlite3Update(pParse,X,Y,W,R); } %endif |
︙ | ︙ | |||
698 699 700 701 702 703 704 | setlist(A) ::= nm(X) EQ expr(Y). { A = sqlite3ExprListAppend(pParse, 0, Y.pExpr); sqlite3ExprListSetName(pParse, A, &X, 1); } ////////////////////////// The INSERT command ///////////////////////////////// // | | | | 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 | setlist(A) ::= nm(X) EQ expr(Y). { A = sqlite3ExprListAppend(pParse, 0, Y.pExpr); sqlite3ExprListSetName(pParse, A, &X, 1); } ////////////////////////// The INSERT command ///////////////////////////////// // cmd ::= with insert_cmd(R) INTO fullname(X) inscollist_opt(F) select(S). {sqlite3Insert(pParse, X, S, F, R);} cmd ::= with insert_cmd(R) INTO fullname(X) inscollist_opt(F) DEFAULT VALUES. {sqlite3Insert(pParse, X, 0, F, R);} %type insert_cmd {u8} insert_cmd(A) ::= INSERT orconf(R). {A = R;} insert_cmd(A) ::= REPLACE. {A = OE_Replace;} %type inscollist_opt {IdList*} |
︙ | ︙ | |||
847 848 849 850 851 852 853 | {spanBinaryExpr(&A,pParse,@OP,&X,&Y);} expr(A) ::= expr(X) PLUS|MINUS(OP) expr(Y). {spanBinaryExpr(&A,pParse,@OP,&X,&Y);} expr(A) ::= expr(X) STAR|SLASH|REM(OP) expr(Y). {spanBinaryExpr(&A,pParse,@OP,&X,&Y);} expr(A) ::= expr(X) CONCAT(OP) expr(Y). {spanBinaryExpr(&A,pParse,@OP,&X,&Y);} %type likeop {struct LikeOp} | | | < < | 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 | {spanBinaryExpr(&A,pParse,@OP,&X,&Y);} expr(A) ::= expr(X) PLUS|MINUS(OP) expr(Y). {spanBinaryExpr(&A,pParse,@OP,&X,&Y);} expr(A) ::= expr(X) STAR|SLASH|REM(OP) expr(Y). {spanBinaryExpr(&A,pParse,@OP,&X,&Y);} expr(A) ::= expr(X) CONCAT(OP) expr(Y). {spanBinaryExpr(&A,pParse,@OP,&X,&Y);} %type likeop {struct LikeOp} likeop(A) ::= LIKE_KW|MATCH(X). {A.eOperator = X; A.bNot = 0;} likeop(A) ::= NOT LIKE_KW|MATCH(X). {A.eOperator = X; A.bNot = 1;} expr(A) ::= expr(X) likeop(OP) expr(Y). [LIKE_KW] { ExprList *pList; pList = sqlite3ExprListAppend(pParse,0, Y.pExpr); pList = sqlite3ExprListAppend(pParse,pList, X.pExpr); A.pExpr = sqlite3ExprFunction(pParse, pList, &OP.eOperator); if( OP.bNot ) A.pExpr = sqlite3PExpr(pParse, TK_NOT, A.pExpr, 0, 0); A.zStart = X.zStart; |
︙ | ︙ | |||
1360 1361 1362 1363 1364 1365 1366 | vtabargtoken ::= ANY(X). {sqlite3VtabArgExtend(pParse,&X);} vtabargtoken ::= lp anylist RP(X). {sqlite3VtabArgExtend(pParse,&X);} lp ::= LP(X). {sqlite3VtabArgExtend(pParse,&X);} anylist ::= . anylist ::= anylist LP anylist RP. anylist ::= anylist ANY. %endif SQLITE_OMIT_VIRTUALTABLE | > > > > > > > > > > > > > | 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 | vtabargtoken ::= ANY(X). {sqlite3VtabArgExtend(pParse,&X);} vtabargtoken ::= lp anylist RP(X). {sqlite3VtabArgExtend(pParse,&X);} lp ::= LP(X). {sqlite3VtabArgExtend(pParse,&X);} anylist ::= . anylist ::= anylist LP anylist RP. anylist ::= anylist ANY. %endif SQLITE_OMIT_VIRTUALTABLE //////////////////////// COMMON TABLE EXPRESSIONS //////////////////////////// with ::= . %ifndef SQLITE_OMIT_CTE with ::= WITH wqlist. {sqlite3CteFinish(pParse, 0);} with ::= WITH RECURSIVE wqlist. {sqlite3CteFinish(pParse, 1);} wqlist ::= with_query. wqlist ::= wqlist COMMA with_query. with_query ::= nm(X) idxlist_opt(Y) AS LP select(Z) RP. { sqlite3CteAdd(pParse, &X, Y, Z); } %endif SQLITE_OMIT_CTE |
Changes to src/sqliteInt.h.
︙ | ︙ | |||
3325 3326 3327 3328 3329 3330 3331 3332 3333 3334 3335 3336 3337 3338 | CollSeq *sqlite3BinaryCompareCollSeq(Parse *, Expr *, Expr *); int sqlite3TempInMemory(const sqlite3*); const char *sqlite3JournalModename(int); #ifndef SQLITE_OMIT_WAL int sqlite3Checkpoint(sqlite3*, int, int, int*, int*); int sqlite3WalDefaultHook(void*,sqlite3*,const char*,int); #endif /* Declarations for functions in fkey.c. All of these are replaced by ** no-op macros if OMIT_FOREIGN_KEY is defined. In this case no foreign ** key functionality is available. If OMIT_TRIGGER is defined but ** OMIT_FOREIGN_KEY is not, only some of the functions are no-oped. In ** this case foreign keys are parsed, but no other functionality is ** provided (enforcement of FK constraints requires the triggers sub-system). | > > > > | 3325 3326 3327 3328 3329 3330 3331 3332 3333 3334 3335 3336 3337 3338 3339 3340 3341 3342 | CollSeq *sqlite3BinaryCompareCollSeq(Parse *, Expr *, Expr *); int sqlite3TempInMemory(const sqlite3*); const char *sqlite3JournalModename(int); #ifndef SQLITE_OMIT_WAL int sqlite3Checkpoint(sqlite3*, int, int, int*, int*); int sqlite3WalDefaultHook(void*,sqlite3*,const char*,int); #endif #ifndef SQLITE_OMIT_CTE void sqlite3CteAdd(Parse*,Token*,ExprList*,Select*); void sqlite3CteFinish(Parse*,int); #endif /* Declarations for functions in fkey.c. All of these are replaced by ** no-op macros if OMIT_FOREIGN_KEY is defined. In this case no foreign ** key functionality is available. If OMIT_TRIGGER is defined but ** OMIT_FOREIGN_KEY is not, only some of the functions are no-oped. In ** this case foreign keys are parsed, but no other functionality is ** provided (enforcement of FK constraints requires the triggers sub-system). |
︙ | ︙ |
Changes to tool/mkkeywordhash.c.
︙ | ︙ | |||
134 135 136 137 138 139 140 141 142 143 144 145 146 147 | # define VTAB 0x00010000 #endif #ifdef SQLITE_OMIT_AUTOVACUUM # define AUTOVACUUM 0 #else # define AUTOVACUUM 0x00020000 #endif /* ** These are the keywords */ static Keyword aKeywordTable[] = { { "ABORT", "TK_ABORT", CONFLICT|TRIGGER }, { "ACTION", "TK_ACTION", FKEY }, | > > > > > | 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 | # define VTAB 0x00010000 #endif #ifdef SQLITE_OMIT_AUTOVACUUM # define AUTOVACUUM 0 #else # define AUTOVACUUM 0x00020000 #endif #ifdef SQLITE_OMIT_CTE # define CTE 0 #else # define CTE 0x00040000 #endif /* ** These are the keywords */ static Keyword aKeywordTable[] = { { "ABORT", "TK_ABORT", CONFLICT|TRIGGER }, { "ACTION", "TK_ACTION", FKEY }, |
︙ | ︙ | |||
230 231 232 233 234 235 236 237 238 239 240 241 242 243 | { "ORDER", "TK_ORDER", ALWAYS }, { "OUTER", "TK_JOIN_KW", ALWAYS }, { "PLAN", "TK_PLAN", EXPLAIN }, { "PRAGMA", "TK_PRAGMA", PRAGMA }, { "PRIMARY", "TK_PRIMARY", ALWAYS }, { "QUERY", "TK_QUERY", EXPLAIN }, { "RAISE", "TK_RAISE", TRIGGER }, { "REFERENCES", "TK_REFERENCES", FKEY }, { "REGEXP", "TK_LIKE_KW", ALWAYS }, { "REINDEX", "TK_REINDEX", REINDEX }, { "RELEASE", "TK_RELEASE", ALWAYS }, { "RENAME", "TK_RENAME", ALTER }, { "REPLACE", "TK_REPLACE", CONFLICT }, { "RESTRICT", "TK_RESTRICT", FKEY }, | > | 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 | { "ORDER", "TK_ORDER", ALWAYS }, { "OUTER", "TK_JOIN_KW", ALWAYS }, { "PLAN", "TK_PLAN", EXPLAIN }, { "PRAGMA", "TK_PRAGMA", PRAGMA }, { "PRIMARY", "TK_PRIMARY", ALWAYS }, { "QUERY", "TK_QUERY", EXPLAIN }, { "RAISE", "TK_RAISE", TRIGGER }, { "RECURSIVE", "TK_RECURSIVE", CTE }, { "REFERENCES", "TK_REFERENCES", FKEY }, { "REGEXP", "TK_LIKE_KW", ALWAYS }, { "REINDEX", "TK_REINDEX", REINDEX }, { "RELEASE", "TK_RELEASE", ALWAYS }, { "RENAME", "TK_RENAME", ALTER }, { "REPLACE", "TK_REPLACE", CONFLICT }, { "RESTRICT", "TK_RESTRICT", FKEY }, |
︙ | ︙ | |||
258 259 260 261 262 263 264 265 266 267 268 269 270 271 | { "UNIQUE", "TK_UNIQUE", ALWAYS }, { "UPDATE", "TK_UPDATE", ALWAYS }, { "USING", "TK_USING", ALWAYS }, { "VACUUM", "TK_VACUUM", VACUUM }, { "VALUES", "TK_VALUES", ALWAYS }, { "VIEW", "TK_VIEW", VIEW }, { "VIRTUAL", "TK_VIRTUAL", VTAB }, { "WITHOUT", "TK_WITHOUT", ALWAYS }, { "WHEN", "TK_WHEN", ALWAYS }, { "WHERE", "TK_WHERE", ALWAYS }, }; /* Number of keywords */ static int nKeyword = (sizeof(aKeywordTable)/sizeof(aKeywordTable[0])); | > | 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 | { "UNIQUE", "TK_UNIQUE", ALWAYS }, { "UPDATE", "TK_UPDATE", ALWAYS }, { "USING", "TK_USING", ALWAYS }, { "VACUUM", "TK_VACUUM", VACUUM }, { "VALUES", "TK_VALUES", ALWAYS }, { "VIEW", "TK_VIEW", VIEW }, { "VIRTUAL", "TK_VIRTUAL", VTAB }, { "WITH", "TK_WITH", CTE }, { "WITHOUT", "TK_WITHOUT", ALWAYS }, { "WHEN", "TK_WHEN", ALWAYS }, { "WHERE", "TK_WHERE", ALWAYS }, }; /* Number of keywords */ static int nKeyword = (sizeof(aKeywordTable)/sizeof(aKeywordTable[0])); |
︙ | ︙ |