Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Changes In Branch connect-by Excluding Merge-Ins
This is equivalent to a diff from f461e2b397 to 4365ddd62d
2014-01-09
| ||
13:39 | Fix harmless compiler warning in unixUnfetch(). (check-in: 618f248f4e user: drh tags: trunk) | |
2014-01-06
| ||
18:32 | Start a new experimental branch for support of Oracle-style CONNECT BY syntax. (Closed-Leaf check-in: 4365ddd62d user: drh tags: connect-by) | |
2014-01-04
| ||
20:00 | Fix an typo that breaks the build when SQLITE_ENABLE_TREE_EXPLAIN is defined. (check-in: f461e2b397 user: drh tags: trunk) | |
19:58 | Add the usual "fts3" prefix to new static method setEstimatedRows() in fts3.c. This fixes a problem when compiling the amalgamation, as the r-tree module also contains a static method named setEstimatedRows. (check-in: d6fcfc8890 user: dan tags: trunk) | |
Changes to src/parse.y.
︙ | ︙ | |||
97 98 99 100 101 102 103 104 105 106 107 108 109 110 | /* ** One or more VALUES claues */ struct ValueList { ExprList *pList; Select *pSelect; }; } // end %include // Input is a single SQL command input ::= cmdlist. cmdlist ::= cmdlist ecmd. cmdlist ::= ecmd. | > > > > > > > > > | 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 | /* ** One or more VALUES claues */ struct ValueList { ExprList *pList; Select *pSelect; }; /* ** An instance of this structure stores the optional Oracle Hierarchical ** Query clauses - the START WITH and CONNECT BY clauses. */ struct HierarchicalQuery { Expr *pStartWith; /* The START WITH condition */ Expr *pConnectBy; /* The CONNECT BY condition */ }; } // end %include // Input is a single SQL command input ::= cmdlist. cmdlist ::= cmdlist ecmd. cmdlist ::= ecmd. |
︙ | ︙ | |||
434 435 436 437 438 439 440 | A = Z; } %type multiselect_op {int} multiselect_op(A) ::= UNION(OP). {A = @OP;} multiselect_op(A) ::= UNION ALL. {A = TK_ALL;} multiselect_op(A) ::= EXCEPT|INTERSECT(OP). {A = @OP;} %endif SQLITE_OMIT_COMPOUND_SELECT | | | 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 | A = Z; } %type multiselect_op {int} multiselect_op(A) ::= UNION(OP). {A = @OP;} multiselect_op(A) ::= UNION ALL. {A = TK_ALL;} multiselect_op(A) ::= EXCEPT|INTERSECT(OP). {A = @OP;} %endif SQLITE_OMIT_COMPOUND_SELECT oneselect(A) ::= SELECT distinct(D) selcollist(W) from(X) where_opt(Y) hq_opt groupby_opt(P) having_opt(Q) orderby_opt(Z) limit_opt(L). { A = sqlite3SelectNew(pParse,W,X,Y,P,Q,Z,D,L.pLimit,L.pOffset); } // The "distinct" nonterminal is true (1) if the DISTINCT keyword is // present and false (0) if it is not. // |
︙ | ︙ | |||
634 635 636 637 638 639 640 641 642 643 644 645 646 647 | //} limit_opt(A) ::= . {A.pLimit = 0; A.pOffset = 0;} limit_opt(A) ::= LIMIT expr(X). {A.pLimit = X.pExpr; A.pOffset = 0;} limit_opt(A) ::= LIMIT expr(X) OFFSET expr(Y). {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 ::= DELETE FROM fullname(X) indexed_opt(I) where_opt(W) orderby_opt(O) limit_opt(L). { sqlite3SrcListIndexedBy(pParse, X, &I); | > > > > > > > > > > > > > | 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 | //} limit_opt(A) ::= . {A.pLimit = 0; A.pOffset = 0;} limit_opt(A) ::= LIMIT expr(X). {A.pLimit = X.pExpr; A.pOffset = 0;} limit_opt(A) ::= LIMIT expr(X) OFFSET expr(Y). {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;} ///////// Oracle-style CONNECT BY clauses for hierarchical queries //////////// %type hq_opt {struct HierarchicalQuery} %destructor hq_opt { sqlite3ExprDelete(pParse->db, $$.pStartWith); sqlite3ExprDelete(pParse->db, $$.pConnectBy); } hq_opt(A) ::= START WITH expr(X) CONNECT BY expr(Y). { A.pStartWith=X.pExpr; A.pConnectBy=Y.pExpr; } hq_opt(A) ::= CONNECT BY expr(Y). { A.pStartWith=0; A.pConnectBy=Y.pExpr; } hq_opt(A) ::= . { A.pStartWith=0; A.pConnectBy=0; } /////////////////////////// The DELETE statement ///////////////////////////// // %ifdef SQLITE_ENABLE_UPDATE_DELETE_LIMIT cmd ::= DELETE FROM fullname(X) indexed_opt(I) where_opt(W) orderby_opt(O) limit_opt(L). { sqlite3SrcListIndexedBy(pParse, X, &I); |
︙ | ︙ | |||
981 982 983 984 985 986 987 988 989 990 991 992 993 994 | expr(A) ::= NOT(B) expr(X). {spanUnaryPrefix(&A,pParse,@B,&X,&B);} expr(A) ::= BITNOT(B) expr(X). {spanUnaryPrefix(&A,pParse,@B,&X,&B);} expr(A) ::= MINUS(B) expr(X). [BITNOT] {spanUnaryPrefix(&A,pParse,TK_UMINUS,&X,&B);} expr(A) ::= PLUS(B) expr(X). [BITNOT] {spanUnaryPrefix(&A,pParse,TK_UPLUS,&X,&B);} %type between_op {int} between_op(A) ::= BETWEEN. {A = 0;} between_op(A) ::= NOT BETWEEN. {A = 1;} expr(A) ::= expr(W) between_op(N) expr(X) AND expr(Y). [BETWEEN] { ExprList *pList = sqlite3ExprListAppend(pParse,0, X.pExpr); pList = sqlite3ExprListAppend(pParse,pList, Y.pExpr); | > > | 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 | expr(A) ::= NOT(B) expr(X). {spanUnaryPrefix(&A,pParse,@B,&X,&B);} expr(A) ::= BITNOT(B) expr(X). {spanUnaryPrefix(&A,pParse,@B,&X,&B);} expr(A) ::= MINUS(B) expr(X). [BITNOT] {spanUnaryPrefix(&A,pParse,TK_UMINUS,&X,&B);} expr(A) ::= PLUS(B) expr(X). [BITNOT] {spanUnaryPrefix(&A,pParse,TK_UPLUS,&X,&B);} expr(A) ::= PRIOR(B) expr(X). [BITNOT] {spanUnaryPrefix(&A,pParse,TK_PRIOR,&X,&B);} %type between_op {int} between_op(A) ::= BETWEEN. {A = 0;} between_op(A) ::= NOT BETWEEN. {A = 1;} expr(A) ::= expr(W) between_op(N) expr(X) AND expr(Y). [BETWEEN] { ExprList *pList = sqlite3ExprListAppend(pParse,0, X.pExpr); pList = sqlite3ExprListAppend(pParse,pList, Y.pExpr); |
︙ | ︙ |
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_CONNECTBY # define CONNECTBY 0 #else # define CONNECTBY 0x00040000 #endif /* ** These are the keywords */ static Keyword aKeywordTable[] = { { "ABORT", "TK_ABORT", CONFLICT|TRIGGER }, { "ACTION", "TK_ACTION", FKEY }, |
︙ | ︙ | |||
163 164 165 166 167 168 169 170 171 172 173 174 175 176 | { "CASE", "TK_CASE", ALWAYS }, { "CAST", "TK_CAST", CAST }, { "CHECK", "TK_CHECK", ALWAYS }, { "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 }, | > | 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 | { "CASE", "TK_CASE", ALWAYS }, { "CAST", "TK_CAST", CAST }, { "CHECK", "TK_CHECK", ALWAYS }, { "COLLATE", "TK_COLLATE", ALWAYS }, { "COLUMN", "TK_COLUMNKW", ALTER }, { "COMMIT", "TK_COMMIT", ALWAYS }, { "CONFLICT", "TK_CONFLICT", CONFLICT }, { "CONNECT", "TK_CONNECT", CONNECTBY }, { "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 }, |
︙ | ︙ | |||
228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 | { "ON", "TK_ON", ALWAYS }, { "OR", "TK_OR", ALWAYS }, { "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 }, { "RIGHT", "TK_JOIN_KW", ALWAYS }, { "ROLLBACK", "TK_ROLLBACK", ALWAYS }, { "ROW", "TK_ROW", TRIGGER }, { "SAVEPOINT", "TK_SAVEPOINT", ALWAYS }, { "SELECT", "TK_SELECT", ALWAYS }, { "SET", "TK_SET", ALWAYS }, { "TABLE", "TK_TABLE", ALWAYS }, { "TEMP", "TK_TEMP", ALWAYS }, { "TEMPORARY", "TK_TEMP", ALWAYS }, { "THEN", "TK_THEN", ALWAYS }, { "TO", "TK_TO", ALWAYS }, { "TRANSACTION", "TK_TRANSACTION", ALWAYS }, { "TRIGGER", "TK_TRIGGER", TRIGGER }, { "UNION", "TK_UNION", COMPOUND }, { "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])); | > > > | 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 | { "ON", "TK_ON", ALWAYS }, { "OR", "TK_OR", ALWAYS }, { "ORDER", "TK_ORDER", ALWAYS }, { "OUTER", "TK_JOIN_KW", ALWAYS }, { "PLAN", "TK_PLAN", EXPLAIN }, { "PRAGMA", "TK_PRAGMA", PRAGMA }, { "PRIMARY", "TK_PRIMARY", ALWAYS }, { "PRIOR", "TK_PRIOR", CONNECTBY }, { "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 }, { "RIGHT", "TK_JOIN_KW", ALWAYS }, { "ROLLBACK", "TK_ROLLBACK", ALWAYS }, { "ROW", "TK_ROW", TRIGGER }, { "SAVEPOINT", "TK_SAVEPOINT", ALWAYS }, { "SELECT", "TK_SELECT", ALWAYS }, { "SET", "TK_SET", ALWAYS }, { "START", "TK_START", CONNECTBY }, { "TABLE", "TK_TABLE", ALWAYS }, { "TEMP", "TK_TEMP", ALWAYS }, { "TEMPORARY", "TK_TEMP", ALWAYS }, { "THEN", "TK_THEN", ALWAYS }, { "TO", "TK_TO", ALWAYS }, { "TRANSACTION", "TK_TRANSACTION", ALWAYS }, { "TRIGGER", "TK_TRIGGER", TRIGGER }, { "UNION", "TK_UNION", COMPOUND }, { "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", CONNECTBY }, { "WITHOUT", "TK_WITHOUT", ALWAYS }, { "WHEN", "TK_WHEN", ALWAYS }, { "WHERE", "TK_WHERE", ALWAYS }, }; /* Number of keywords */ static int nKeyword = (sizeof(aKeywordTable)/sizeof(aKeywordTable[0])); |
︙ | ︙ |