1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-07-29 08:01:23 +03:00

Added the ability to say things like "SELECT rowid, * FROM table1;" (CVS 332)

FossilOrigin-Name: ffbdd43f5de62e7bf81631c83473aca29c3a6c98
This commit is contained in:
drh
2001-12-16 20:05:05 +00:00
parent 6446c4dc67
commit 7c917d196f
7 changed files with 86 additions and 43 deletions

View File

@ -14,7 +14,7 @@
** the parser. Lemon will also generate a header file containing
** numeric codes for all of the tokens.
**
** @(#) $Id: parse.y,v 1.38 2001/11/06 04:00:18 drh Exp $
** @(#) $Id: parse.y,v 1.39 2001/12/16 20:05:06 drh Exp $
*/
%token_prefix TK_
%token_type {Token}
@ -198,8 +198,9 @@ 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. In the case of "SELECT * FROM ..."
// the selcollist value is NULL.
// 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($$);}
@ -207,9 +208,11 @@ distinct(A) ::= . {A = 0;}
%destructor sclp {sqliteExprListDelete($$);}
sclp(A) ::= selcollist(X) COMMA. {A = X;}
sclp(A) ::= . {A = 0;}
selcollist(A) ::= STAR. {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.

View File

@ -12,7 +12,7 @@
** This file contains C code routines that are called by the parser
** to handle SELECT statements in SQLite.
**
** $Id: select.c,v 1.49 2001/11/07 16:48:27 drh Exp $
** $Id: select.c,v 1.50 2001/12/16 20:05:06 drh Exp $
*/
#include "sqliteInt.h"
@ -318,7 +318,7 @@ static const char *selectOpName(int id){
** in pParse and return non-zero.
*/
static int fillInColumnList(Parse *pParse, Select *p){
int i, j;
int i, j, k;
IdList *pTabList;
ExprList *pEList;
@ -353,34 +353,52 @@ static int fillInColumnList(Parse *pParse, Select *p){
}
}
/* If the list of columns to retrieve is "*" then replace it with
** a list of all columns from all tables.
/* 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.
*/
if( pEList==0 ){
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);
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);
}
}
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;
pEList = sqliteExprListAppend(pEList, pExpr, 0);
}
}
p->pEList = pEList;
sqliteExprListDelete(pEList);
p->pEList = pNew;
}
return 0;
}