Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Added the ability to say things like "SELECT rowid, * FROM table1;" (CVS 332) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
ffbdd43f5de62e7bf81631c83473aca2 |
User & Date: | drh 2001-12-16 20:05:05.000 |
Context
2001-12-21
| ||
14:30 | Added support for the INTEGER PRIMARY KEY column type. (CVS 333) (check-in: 236a54d289 user: drh tags: trunk) | |
2001-12-16
| ||
20:05 | Added the ability to say things like "SELECT rowid, * FROM table1;" (CVS 332) (check-in: ffbdd43f5d user: drh tags: trunk) | |
2001-12-15
| ||
14:22 | Comment and documentation changes. (CVS 331) (check-in: e8595579a5 user: drh tags: trunk) | |
Changes
Changes to VERSION.
|
| | | 1 | 2.1.8 |
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.39 2001/12/16 20:05:06 drh Exp $ */ %token_prefix TK_ %token_type {Token} %default_type {Token} %extra_argument {Parse *pParse} %syntax_error { sqliteSetString(&pParse->zErrMsg,"syntax error",0); |
︙ | ︙ | |||
194 195 196 197 198 199 200 | // %type distinct {int} distinct(A) ::= DISTINCT. {A = 1;} distinct(A) ::= ALL. {A = 0;} distinct(A) ::= . {A = 0;} // selcollist is a list of expressions that are to become the return | | > | < > > > | 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 | // %type distinct {int} distinct(A) ::= DISTINCT. {A = 1;} distinct(A) ::= ALL. {A = 0;} distinct(A) ::= . {A = 0;} // selcollist is a list of expressions that are to become the return // values of the SELECT statement. The "*" in statements like // "SELECT * FROM ..." is encoded as a special expression with an // opcode of TK_ALL. // %type selcollist {ExprList*} %destructor selcollist {sqliteExprListDelete($$);} %type sclp {ExprList*} %destructor sclp {sqliteExprListDelete($$);} sclp(A) ::= selcollist(X) COMMA. {A = X;} sclp(A) ::= . {A = 0;} selcollist(A) ::= sclp(P) expr(X). {A = sqliteExprListAppend(P,X,0);} selcollist(A) ::= sclp(P) expr(X) as ids(Y). {A = sqliteExprListAppend(P,X,&Y);} selcollist(A) ::= sclp(P) STAR. { A = sqliteExprListAppend(P, sqliteExpr(TK_ALL, 0, 0, 0), 0); } as ::= . as ::= AS. %type seltablist {IdList*} %destructor seltablist {sqliteIdListDelete($$);} %type stl_prefix {IdList*} |
︙ | ︙ |
Changes to src/select.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 C code routines that are called by the parser ** to handle SELECT statements 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 C code routines that are called by the parser ** to handle SELECT statements in SQLite. ** ** $Id: select.c,v 1.50 2001/12/16 20:05:06 drh Exp $ */ #include "sqliteInt.h" /* ** Allocate a new Select structure and return a pointer to that ** structure. */ |
︙ | ︙ | |||
314 315 316 317 318 319 320 | ** create a fake pEList containing the names of all columns ** of all tables. ** ** Return 0 on success. If there are problems, leave an error message ** in pParse and return non-zero. */ static int fillInColumnList(Parse *pParse, Select *p){ | | | 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 | ** create a fake pEList containing the names of all columns ** of all tables. ** ** Return 0 on success. If there are problems, leave an error message ** in pParse and return non-zero. */ static int fillInColumnList(Parse *pParse, Select *p){ int i, j, k; IdList *pTabList; ExprList *pEList; if( p==0 || p->pSrc==0 ) return 1; pTabList = p->pSrc; pEList = p->pEList; |
︙ | ︙ | |||
349 350 351 352 353 354 355 | sqliteSetString(&pParse->zErrMsg, "no such table: ", pTabList->a[i].zName, 0); pParse->nErr++; return 1; } } | > | > > | > | > > > > > > > > > > > | | | | | | | | | | | | | | | | | | | | | | | > > > | | 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 | sqliteSetString(&pParse->zErrMsg, "no such table: ", pTabList->a[i].zName, 0); pParse->nErr++; return 1; } } /* For every "*" that occurs in the column list, insert the names of ** all columns in all tables. The parser inserted a special expression ** with the TK_ALL operator for each "*" that it found in the column list. ** The following code just has to locate the TK_ALL expressions and expand ** each one to the list of all columns in all tables. */ for(k=0; k<pEList->nExpr; k++){ if( pEList->a[k].pExpr->op==TK_ALL ) break; } if( k<pEList->nExpr ){ struct ExprList_item *a = pEList->a; ExprList *pNew = 0; for(k=0; k<pEList->nExpr; k++){ if( a[k].pExpr->op!=TK_ALL ){ pNew = sqliteExprListAppend(pNew, a[k].pExpr, 0); pNew->a[pNew->nExpr-1].zName = a[k].zName; a[k].pExpr = 0; a[k].zName = 0; }else{ for(i=0; i<pTabList->nId; i++){ Table *pTab = pTabList->a[i].pTab; for(j=0; j<pTab->nCol; j++){ Expr *pExpr = sqliteExpr(TK_DOT, 0, 0, 0); if( pExpr==0 ) break; pExpr->pLeft = sqliteExpr(TK_ID, 0, 0, 0); if( pExpr->pLeft==0 ){ sqliteExprDelete(pExpr); break; } if( pTabList->a[i].zAlias && pTabList->a[i].zAlias[0] ){ pExpr->pLeft->token.z = pTabList->a[i].zAlias; pExpr->pLeft->token.n = strlen(pTabList->a[i].zAlias); }else{ pExpr->pLeft->token.z = pTab->zName; pExpr->pLeft->token.n = strlen(pTab->zName); } pExpr->pRight = sqliteExpr(TK_ID, 0, 0, 0); if( pExpr->pRight==0 ){ sqliteExprDelete(pExpr); break; } pExpr->pRight->token.z = pTab->aCol[j].zName; pExpr->pRight->token.n = strlen(pTab->aCol[j].zName); pExpr->span.z = ""; pExpr->span.n = 0; pNew = sqliteExprListAppend(pNew, pExpr, 0); } } } } sqliteExprListDelete(pEList); p->pEList = pNew; } return 0; } /* ** This routine associates entries in an ORDER BY expression list with ** columns in a result. For each ORDER BY expression, the opcode of |
︙ | ︙ |
Changes to test/select1.test.
1 2 3 4 5 6 7 8 9 10 11 12 13 | # 2001 September 15 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. The # focus of this file is testing the SELECT statement. # | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | # 2001 September 15 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. The # focus of this file is testing the SELECT statement. # # $Id: select1.test,v 1.16 2001/12/16 20:05:06 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl # Try to select on a non-existant table. # do_test select1-1.1 { |
︙ | ︙ | |||
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | } {22 11} do_test select1-1.7 { execsql {SELECT f1, f2 FROM test1} } {11 22} do_test select1-1.8 { execsql {SELECT * FROM test1} } {11 22} execsql {CREATE TABLE test2(r1 real, r2 real)} execsql {INSERT INTO test2(r1,r2) VALUES(1.1,2.2)} do_test select1-1.9 { execsql {SELECT * FROM test1, test2} } {11 22 1.1 2.2} do_test select1-1.10 { execsql {SELECT test1.f1, test2.r1 FROM test1, test2} } {11 1.1} do_test select1-1.11 { execsql {SELECT test1.f1, test2.r1 FROM test2, test1} } {11 1.1} do_test select1-1.11.1 { | > > > > > > > > > > > > > > > | 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 | } {22 11} do_test select1-1.7 { execsql {SELECT f1, f2 FROM test1} } {11 22} do_test select1-1.8 { execsql {SELECT * FROM test1} } {11 22} do_test select1-1.8.1 { execsql {SELECT *, * FROM test1} } {11 22 11 22} do_test select1-1.8.2 { execsql {SELECT *, min(f1,f2), max(f1,f2) FROM test1} } {11 22 11 22} do_test select1-1.8.3 { execsql {SELECT 'one', *, 'two', * FROM test1} } {one 11 22 two 11 22} execsql {CREATE TABLE test2(r1 real, r2 real)} execsql {INSERT INTO test2(r1,r2) VALUES(1.1,2.2)} do_test select1-1.9 { execsql {SELECT * FROM test1, test2} } {11 22 1.1 2.2} do_test select1-1.9.1 { execsql {SELECT *, 'hi' FROM test1, test2} } {11 22 1.1 2.2 hi} do_test select1-1.9.2 { execsql {SELECT 'one', *, 'two', * FROM test1, test2} } {one 11 22 1.1 2.2 two 11 22 1.1 2.2} do_test select1-1.10 { execsql {SELECT test1.f1, test2.r1 FROM test1, test2} } {11 1.1} do_test select1-1.11 { execsql {SELECT test1.f1, test2.r1 FROM test2, test1} } {11 1.1} do_test select1-1.11.1 { |
︙ | ︙ |
Changes to www/changes.tcl.
︙ | ︙ | |||
12 13 14 15 16 17 18 19 20 21 22 23 24 25 | } proc chng {date desc} { puts "<DT><B>$date</B></DT>" puts "<DD><P><UL>$desc</UL></P></DD>" } chng {2001 Dec 14 (2.1.7)} { <li>Fix a bug in <b>CREATE TEMPORARY TABLE</b> which was causing the table to be initially allocated in the main database file instead of in the separate temporary file. This bug could cause the library to suffer an assertion failure and it could cause "page leaks" in the main database file. | > > > > > > > | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | } proc chng {date desc} { puts "<DT><B>$date</B></DT>" puts "<DD><P><UL>$desc</UL></P></DD>" } chng {2001 Dec 16 (2.1.8)} { <li>Added the ability to specify "*" as part of a larger column list in the result section of a SELECT statement. For example: <nobr>"<b>SELECT rowid, * FROM table1;</b>"</nobr>.</li> <li>Updates to comments and documentation.</li> } chng {2001 Dec 14 (2.1.7)} { <li>Fix a bug in <b>CREATE TEMPORARY TABLE</b> which was causing the table to be initially allocated in the main database file instead of in the separate temporary file. This bug could cause the library to suffer an assertion failure and it could cause "page leaks" in the main database file. |
︙ | ︙ |