mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-05 15:55:57 +03:00
separate Select structure (CVS 51)
FossilOrigin-Name: ce45dea902f9010a1c2c9ba3550dd789e7c15fcd
This commit is contained in:
22
manifest
22
manifest
@@ -1,5 +1,5 @@
|
|||||||
C :-)\s(CVS\s50)
|
C separate\sSelect\sstructure\s(CVS\s51)
|
||||||
D 2000-06-05T02:07:04
|
D 2000-06-05T16:01:39
|
||||||
F COPYRIGHT 74a8a6531a42e124df07ab5599aad63870fa0bd4
|
F COPYRIGHT 74a8a6531a42e124df07ab5599aad63870fa0bd4
|
||||||
F Makefile.in 17ba1ccf8d2d40c627796bba8f72952365d6d644
|
F Makefile.in 17ba1ccf8d2d40c627796bba8f72952365d6d644
|
||||||
F README 51f6a4e7408b34afa5bc1c0485f61b6a4efb6958
|
F README 51f6a4e7408b34afa5bc1c0485f61b6a4efb6958
|
||||||
@@ -12,17 +12,17 @@ F src/dbbe.h a8a46f71238e0f09f3ec08fd9d1c8c7f4cdc49bf
|
|||||||
F src/delete.c e11433c14ed5cc8553cba14296b3baa3c23054bc
|
F src/delete.c e11433c14ed5cc8553cba14296b3baa3c23054bc
|
||||||
F src/expr.c 793c15de4ce2911fa1a74999750bd3c0c9ca513f
|
F src/expr.c 793c15de4ce2911fa1a74999750bd3c0c9ca513f
|
||||||
F src/insert.c ddae33b3dea1b4e743092d04240a20def9f88b72
|
F src/insert.c ddae33b3dea1b4e743092d04240a20def9f88b72
|
||||||
F src/main.c 06ee1dd1929b0a90e22a977c033e53c31cc012dd
|
F src/main.c 93a7ad14bb5a82ad13ad59da23ef674a94b0c3d6
|
||||||
F src/parse.y 9ec486608b7b4daaccf4ad9f05eef1a26a008fb8
|
F src/parse.y 020e5da71e14b63860c97589700eb11bf4699981
|
||||||
F src/select.c 2dff3d237db6588ad657bb13f19dedebc046a4eb
|
F src/select.c 98f417b72e2edd277602cc14eb5c23743e616e60
|
||||||
F src/shell.c 5fa24c0bb678782ffe9070128e3e160674f297eb
|
F src/shell.c 5fa24c0bb678782ffe9070128e3e160674f297eb
|
||||||
F src/sqlite.h 58da0a8590133777b741f9836beaef3d58f40268
|
F src/sqlite.h 58da0a8590133777b741f9836beaef3d58f40268
|
||||||
F src/sqliteInt.h 7c269d229848045995782b10688acd59cbf08079
|
F src/sqliteInt.h da8e0abf204438b812e315279acce05122166440
|
||||||
F src/tclsqlite.c 9f358618ae803bedf4fb96da5154fd45023bc1f7
|
F src/tclsqlite.c 9f358618ae803bedf4fb96da5154fd45023bc1f7
|
||||||
F src/tokenize.c 15c229fee77325334c6814652e429b0930eba6c1
|
F src/tokenize.c 15c229fee77325334c6814652e429b0930eba6c1
|
||||||
F src/update.c 3f05d5082fd2c34f15d1e4a4db17355ad8807a78
|
F src/update.c 3f05d5082fd2c34f15d1e4a4db17355ad8807a78
|
||||||
F src/util.c a06e8379665b18539cd9400641f3581d925f337e
|
F src/util.c 33f9baa01e45394ef0cf85361a0e872987884315
|
||||||
F src/vdbe.c c101c98de98cb4f946bb003ca2e6347cdd218ebc
|
F src/vdbe.c 108f0e58beee1361bcb8dc2a59c7d54e5f4360bc
|
||||||
F src/vdbe.h f20a3140905c385237e0891122beccde779c78c7
|
F src/vdbe.h f20a3140905c385237e0891122beccde779c78c7
|
||||||
F src/where.c bed9a8360cbfbf712bdc397c8e22216a5e5f9800
|
F src/where.c bed9a8360cbfbf712bdc397c8e22216a5e5f9800
|
||||||
F test/all.test 0950c135cab7e60c07bd745ccfad1476211e5bd7
|
F test/all.test 0950c135cab7e60c07bd745ccfad1476211e5bd7
|
||||||
@@ -47,7 +47,7 @@ F www/c_interface.tcl 8867d76ddd416d2fbd41e4cb3de8efa9cef105a5
|
|||||||
F www/changes.tcl 567cc6066d87460bdedff8e5bbc20f41ddaadf77
|
F www/changes.tcl 567cc6066d87460bdedff8e5bbc20f41ddaadf77
|
||||||
F www/index.tcl f8189a7898f6d06307c34047b9d7e00860026e44
|
F www/index.tcl f8189a7898f6d06307c34047b9d7e00860026e44
|
||||||
F www/sqlite.tcl 2f933ce18cffd34a0a020a82435ab937137970fd
|
F www/sqlite.tcl 2f933ce18cffd34a0a020a82435ab937137970fd
|
||||||
P 6ea5cebf05562de00d2cf0b9e2aac5f3857638ee
|
P 1cf2873d55b471bb3e397f90dc0868dd88c440a0
|
||||||
R 6949f362a1592f0e27ca1ae669f63813
|
R dfbce0b035783f6473b57dede04bcdd9
|
||||||
U drh
|
U drh
|
||||||
Z aae59671b659273e5022be83deddccc9
|
Z 4195201472d7632b2259e7fe18f40c66
|
||||||
|
@@ -1 +1 @@
|
|||||||
1cf2873d55b471bb3e397f90dc0868dd88c440a0
|
ce45dea902f9010a1c2c9ba3550dd789e7c15fcd
|
@@ -26,7 +26,7 @@
|
|||||||
** other files are for internal use by SQLite and should not be
|
** other files are for internal use by SQLite and should not be
|
||||||
** accessed by users of the library.
|
** accessed by users of the library.
|
||||||
**
|
**
|
||||||
** $Id: main.c,v 1.8 2000/06/05 02:07:04 drh Exp $
|
** $Id: main.c,v 1.9 2000/06/05 16:01:39 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
|
|
||||||
@@ -40,7 +40,6 @@ static int sqliteOpenCb(void *pDb, int argc, char **argv, char **azColName){
|
|||||||
sqlite *db = (sqlite*)pDb;
|
sqlite *db = (sqlite*)pDb;
|
||||||
Parse sParse;
|
Parse sParse;
|
||||||
int nErr;
|
int nErr;
|
||||||
char *zErrMsg = 0;
|
|
||||||
|
|
||||||
if( argc!=1 ) return 0;
|
if( argc!=1 ) return 0;
|
||||||
memset(&sParse, 0, sizeof(sParse));
|
memset(&sParse, 0, sizeof(sParse));
|
||||||
|
54
src/parse.y
54
src/parse.y
@@ -26,7 +26,7 @@
|
|||||||
** the parser. Lemon will also generate a header file containing
|
** the parser. Lemon will also generate a header file containing
|
||||||
** numeric codes for all of the tokens.
|
** numeric codes for all of the tokens.
|
||||||
**
|
**
|
||||||
** @(#) $Id: parse.y,v 1.8 2000/06/03 19:19:41 drh Exp $
|
** @(#) $Id: parse.y,v 1.9 2000/06/05 16:01:39 drh Exp $
|
||||||
*/
|
*/
|
||||||
%token_prefix TK_
|
%token_prefix TK_
|
||||||
%token_type {Token}
|
%token_type {Token}
|
||||||
@@ -132,28 +132,44 @@ cmd ::= DROP TABLE id(X). {sqliteDropTable(pParse,&X);}
|
|||||||
|
|
||||||
// The select statement
|
// The select statement
|
||||||
//
|
//
|
||||||
cmd ::= select.
|
cmd ::= select(X). {
|
||||||
select ::= SELECT distinct(D) selcollist(W) from(X) where_opt(Y) orderby_opt(Z).
|
sqliteSelect(pParse, X, 0, 0);
|
||||||
{sqliteSelect(pParse, W, X, Y, Z, D);}
|
sqliteSelectDelete(X);
|
||||||
select ::= SELECT distinct(D) STAR from(X) where_opt(Y) orderby_opt(Z).
|
}
|
||||||
{sqliteSelect(pParse, 0, X, Y, Z, D);}
|
|
||||||
|
|
||||||
|
%type select {Select*}
|
||||||
|
%destructor select {sqliteSelectDelete($$);}
|
||||||
|
|
||||||
|
select(A) ::= SELECT distinct(D) selcollist(W) from(X) where_opt(Y)
|
||||||
|
orderby_opt(Z). {
|
||||||
|
A = sqliteSelectNew(W,X,Y,0,0,Z,D);
|
||||||
|
}
|
||||||
|
|
||||||
|
// The "distinct" nonterminal is true (1) if the DISTINCT keyword is
|
||||||
|
// present and false (0) if it is not.
|
||||||
|
//
|
||||||
%type distinct {int}
|
%type distinct {int}
|
||||||
|
|
||||||
distinct(A) ::= DISTINCT. {A = 1;}
|
distinct(A) ::= DISTINCT. {A = 1;}
|
||||||
distinct(A) ::= . {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.
|
||||||
|
//
|
||||||
%type selcollist {ExprList*}
|
%type selcollist {ExprList*}
|
||||||
%destructor selcollist {sqliteExprListDelete($$);}
|
%destructor selcollist {sqliteExprListDelete($$);}
|
||||||
%type sclp {ExprList*}
|
%type sclp {ExprList*}
|
||||||
%destructor sclp {sqliteExprListDelete($$);}
|
%destructor sclp {sqliteExprListDelete($$);}
|
||||||
|
|
||||||
sclp(A) ::= selcollist(X) COMMA. {A = X;}
|
sclp(A) ::= selcollist(X) COMMA. {A = X;}
|
||||||
sclp(A) ::= . {A = 0;}
|
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). {A = sqliteExprListAppend(P,X,0);}
|
||||||
selcollist(A) ::= sclp(P) expr(X) AS ID(Y). {A = sqliteExprListAppend(P,X,&Y);}
|
selcollist(A) ::= sclp(P) expr(X) as ID(Y). {A = sqliteExprListAppend(P,X,&Y);}
|
||||||
selcollist(A) ::= sclp(P) expr(X) AS STRING(Y).
|
selcollist(A) ::= sclp(P) expr(X) as STRING(Y).
|
||||||
{A = sqliteExprListAppend(P,X,&Y);}
|
{A = sqliteExprListAppend(P,X,&Y);}
|
||||||
|
as ::= .
|
||||||
|
as ::= AS.
|
||||||
|
|
||||||
|
|
||||||
%type seltablist {IdList*}
|
%type seltablist {IdList*}
|
||||||
%destructor seltablist {sqliteIdListDelete($$);}
|
%destructor seltablist {sqliteIdListDelete($$);}
|
||||||
@@ -179,16 +195,14 @@ seltablist(A) ::= stl_prefix(X) id(Y) AS id(Z).
|
|||||||
|
|
||||||
orderby_opt(A) ::= . {A = 0;}
|
orderby_opt(A) ::= . {A = 0;}
|
||||||
orderby_opt(A) ::= ORDER BY sortlist(X). {A = X;}
|
orderby_opt(A) ::= ORDER BY sortlist(X). {A = X;}
|
||||||
sortlist(A) ::= sortlist(X) COMMA sortitem(Y) sortorder(Z).
|
sortlist(A) ::= sortlist(X) COMMA sortitem(Y) sortorder(Z). {
|
||||||
{
|
A = sqliteExprListAppend(X,Y,0);
|
||||||
A = sqliteExprListAppend(X,Y,0);
|
A->a[A->nExpr-1].idx = Z; /* 0 for ascending order, 1 for decending */
|
||||||
A->a[A->nExpr-1].idx = Z;
|
}
|
||||||
}
|
sortlist(A) ::= sortitem(Y) sortorder(Z). {
|
||||||
sortlist(A) ::= sortitem(Y) sortorder(Z).
|
A = sqliteExprListAppend(0,Y,0);
|
||||||
{
|
A->a[0].idx = Z;
|
||||||
A = sqliteExprListAppend(0,Y,0);
|
}
|
||||||
A->a[0].idx = Z;
|
|
||||||
}
|
|
||||||
sortitem(A) ::= expr(X). {A = X;}
|
sortitem(A) ::= expr(X). {A = X;}
|
||||||
|
|
||||||
%type sortorder {int}
|
%type sortorder {int}
|
||||||
|
122
src/select.c
122
src/select.c
@@ -24,28 +24,94 @@
|
|||||||
** This file contains C code routines that are called by the parser
|
** This file contains C code routines that are called by the parser
|
||||||
** to handle SELECT statements.
|
** to handle SELECT statements.
|
||||||
**
|
**
|
||||||
** $Id: select.c,v 1.6 2000/06/04 12:58:38 drh Exp $
|
** $Id: select.c,v 1.7 2000/06/05 16:01:39 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Process a SELECT statement.
|
** Allocate a new Select structure and return a pointer to that
|
||||||
|
** structure.
|
||||||
*/
|
*/
|
||||||
void sqliteSelect(
|
Select *sqliteSelectNew(
|
||||||
|
ExprList *pEList,
|
||||||
|
IdList *pSrc,
|
||||||
|
Expr *pWhere,
|
||||||
|
ExprList *pGroupBy,
|
||||||
|
Expr *pHaving,
|
||||||
|
ExprList *pOrderBy,
|
||||||
|
int isDistinct
|
||||||
|
){
|
||||||
|
Select *pNew;
|
||||||
|
pNew = sqliteMalloc( sizeof(*pNew) );
|
||||||
|
if( pNew==0 ) return 0;
|
||||||
|
pNew->pEList = pEList;
|
||||||
|
pNew->pSrc = pSrc;
|
||||||
|
pNew->pWhere = pWhere;
|
||||||
|
pNew->pGroupBy = pGroupBy;
|
||||||
|
pNew->pHaving = pHaving;
|
||||||
|
pNew->pOrderBy = pOrderBy;
|
||||||
|
pNew->isDistinct = isDistinct;
|
||||||
|
return pNew;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Delete the given Select structure and all of its substructures.
|
||||||
|
*/
|
||||||
|
void sqliteSelectDelete(Select *p){
|
||||||
|
sqliteExprListDelete(p->pEList);
|
||||||
|
sqliteIdListDelete(p->pSrc);
|
||||||
|
sqliteExprDelete(p->pWhere);
|
||||||
|
sqliteExprListDelete(p->pGroupBy);
|
||||||
|
sqliteExprDelete(p->pHaving);
|
||||||
|
sqliteExprListDelete(p->pOrderBy);
|
||||||
|
sqliteFree(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Generate code for the given SELECT statement.
|
||||||
|
**
|
||||||
|
** If pDest==0 and iMem<0, then the results of the query are sent to
|
||||||
|
** the callback function. If pDest!=0 then the results are written to
|
||||||
|
** the single table specified. If pDest==0 and iMem>=0 then the result
|
||||||
|
** should be a single value which is then stored in memory location iMem
|
||||||
|
** of the virtual machine.
|
||||||
|
**
|
||||||
|
** This routine returns the number of errors. If any errors are
|
||||||
|
** encountered, then an appropriate error message is left in
|
||||||
|
** pParse->zErrMsg.
|
||||||
|
**
|
||||||
|
** This routine does NOT free the Select structure passed in. The
|
||||||
|
** calling function needs to do that.
|
||||||
|
*/
|
||||||
|
int sqliteSelect(
|
||||||
Parse *pParse, /* The parser context */
|
Parse *pParse, /* The parser context */
|
||||||
ExprList *pEList, /* List of fields to extract. NULL means "*" */
|
Select *p, /* The SELECT statement being coded. */
|
||||||
IdList *pTabList, /* List of tables to select from */
|
Table *pDest, /* Write results here, if not NULL */
|
||||||
Expr *pWhere, /* The WHERE clause. May be NULL */
|
int iMem /* Save result in this memory location, if >=0 */
|
||||||
ExprList *pOrderBy, /* The ORDER BY clause. May be NULL */
|
|
||||||
int distinct /* If true, only output distinct results */
|
|
||||||
){
|
){
|
||||||
int i, j;
|
int i, j;
|
||||||
WhereInfo *pWInfo;
|
WhereInfo *pWInfo;
|
||||||
Vdbe *v;
|
Vdbe *v;
|
||||||
int isAgg = 0; /* True for select lists like "count(*)" */
|
int isAgg = 0; /* True for select lists like "count(*)" */
|
||||||
|
ExprList *pEList; /* List of fields to extract. NULL means "*" */
|
||||||
|
IdList *pTabList; /* List of tables to select from */
|
||||||
|
Expr *pWhere; /* The WHERE clause. May be NULL */
|
||||||
|
ExprList *pOrderBy; /* The ORDER BY clause. May be NULL */
|
||||||
|
int distinct; /* If true, only output distinct results */
|
||||||
|
|
||||||
if( pParse->nErr>0 ) goto select_cleanup;
|
|
||||||
|
pEList = p->pEList;
|
||||||
|
pTabList = p->pSrc;
|
||||||
|
pWhere = p->pWhere;
|
||||||
|
pOrderBy = p->pOrderBy;
|
||||||
|
distinct = p->isDistinct;
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Do not even attempt to generate any code if we have already seen
|
||||||
|
** errors before this routine starts.
|
||||||
|
*/
|
||||||
|
if( pParse->nErr>0 ) return 0;
|
||||||
|
|
||||||
/* Look up every table in the table list.
|
/* Look up every table in the table list.
|
||||||
*/
|
*/
|
||||||
@@ -55,7 +121,7 @@ void sqliteSelect(
|
|||||||
sqliteSetString(&pParse->zErrMsg, "no such table: ",
|
sqliteSetString(&pParse->zErrMsg, "no such table: ",
|
||||||
pTabList->a[i].zName, 0);
|
pTabList->a[i].zName, 0);
|
||||||
pParse->nErr++;
|
pParse->nErr++;
|
||||||
goto select_cleanup;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -78,10 +144,10 @@ void sqliteSelect(
|
|||||||
*/
|
*/
|
||||||
for(i=0; i<pEList->nExpr; i++){
|
for(i=0; i<pEList->nExpr; i++){
|
||||||
if( sqliteExprResolveIds(pParse, pTabList, pEList->a[i].pExpr) ){
|
if( sqliteExprResolveIds(pParse, pTabList, pEList->a[i].pExpr) ){
|
||||||
goto select_cleanup;
|
return 1;
|
||||||
}
|
}
|
||||||
if( sqliteExprCheck(pParse, pEList->a[i].pExpr, 1, &pEList->a[i].isAgg) ){
|
if( sqliteExprCheck(pParse, pEList->a[i].pExpr, 1, &pEList->a[i].isAgg) ){
|
||||||
goto select_cleanup;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( pEList->nExpr>0 ){
|
if( pEList->nExpr>0 ){
|
||||||
@@ -91,25 +157,25 @@ void sqliteSelect(
|
|||||||
sqliteSetString(&pParse->zErrMsg, "some selected items are aggregates "
|
sqliteSetString(&pParse->zErrMsg, "some selected items are aggregates "
|
||||||
"and others are not", 0);
|
"and others are not", 0);
|
||||||
pParse->nErr++;
|
pParse->nErr++;
|
||||||
goto select_cleanup;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( pWhere ){
|
if( pWhere ){
|
||||||
if( sqliteExprResolveIds(pParse, pTabList, pWhere) ){
|
if( sqliteExprResolveIds(pParse, pTabList, pWhere) ){
|
||||||
goto select_cleanup;
|
return 1;
|
||||||
}
|
}
|
||||||
if( sqliteExprCheck(pParse, pWhere, 0, 0) ){
|
if( sqliteExprCheck(pParse, pWhere, 0, 0) ){
|
||||||
goto select_cleanup;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( pOrderBy ){
|
if( pOrderBy ){
|
||||||
for(i=0; i<pOrderBy->nExpr; i++){
|
for(i=0; i<pOrderBy->nExpr; i++){
|
||||||
if( sqliteExprResolveIds(pParse, pTabList, pOrderBy->a[i].pExpr) ){
|
if( sqliteExprResolveIds(pParse, pTabList, pOrderBy->a[i].pExpr) ){
|
||||||
goto select_cleanup;
|
return 1;
|
||||||
}
|
}
|
||||||
if( sqliteExprCheck(pParse, pOrderBy->a[i].pExpr, 0, 0) ){
|
if( sqliteExprCheck(pParse, pOrderBy->a[i].pExpr, 0, 0) ){
|
||||||
goto select_cleanup;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -118,7 +184,6 @@ void sqliteSelect(
|
|||||||
** since only one row will be returned.
|
** since only one row will be returned.
|
||||||
*/
|
*/
|
||||||
if( isAgg && pOrderBy ){
|
if( isAgg && pOrderBy ){
|
||||||
sqliteExprListDelete(pOrderBy);
|
|
||||||
pOrderBy = 0;
|
pOrderBy = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -134,7 +199,11 @@ void sqliteSelect(
|
|||||||
if( v==0 ){
|
if( v==0 ){
|
||||||
v = pParse->pVdbe = sqliteVdbeCreate(pParse->db->pBe);
|
v = pParse->pVdbe = sqliteVdbeCreate(pParse->db->pBe);
|
||||||
}
|
}
|
||||||
if( v==0 ) goto select_cleanup;
|
if( v==0 ){
|
||||||
|
sqliteSetString(&pParse->zErrMsg, "out of memory", 0);
|
||||||
|
pParse->nErr++;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
if( pOrderBy ){
|
if( pOrderBy ){
|
||||||
sqliteVdbeAddOp(v, OP_SortOpen, 0, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_SortOpen, 0, 0, 0, 0);
|
||||||
}
|
}
|
||||||
@@ -201,7 +270,7 @@ void sqliteSelect(
|
|||||||
sqliteVdbeAddOp(v, OP_Open, distinct, 1, 0, 0);
|
sqliteVdbeAddOp(v, OP_Open, distinct, 1, 0, 0);
|
||||||
}
|
}
|
||||||
pWInfo = sqliteWhereBegin(pParse, pTabList, pWhere, 0);
|
pWInfo = sqliteWhereBegin(pParse, pTabList, pWhere, 0);
|
||||||
if( pWInfo==0 ) goto select_cleanup;
|
if( pWInfo==0 ) return 1;
|
||||||
|
|
||||||
/* Pull the requested fields.
|
/* Pull the requested fields.
|
||||||
*/
|
*/
|
||||||
@@ -232,7 +301,7 @@ void sqliteSelect(
|
|||||||
char *zSortOrder;
|
char *zSortOrder;
|
||||||
sqliteVdbeAddOp(v, OP_SortMakeRec, pEList->nExpr, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_SortMakeRec, pEList->nExpr, 0, 0, 0);
|
||||||
zSortOrder = sqliteMalloc( pOrderBy->nExpr + 1 );
|
zSortOrder = sqliteMalloc( pOrderBy->nExpr + 1 );
|
||||||
if( zSortOrder==0 ) goto select_cleanup;
|
if( zSortOrder==0 ) return 1;
|
||||||
for(i=0; i<pOrderBy->nExpr; i++){
|
for(i=0; i<pOrderBy->nExpr; i++){
|
||||||
zSortOrder[i] = pOrderBy->a[i].idx ? '-' : '+';
|
zSortOrder[i] = pOrderBy->a[i].idx ? '-' : '+';
|
||||||
sqliteExprCode(pParse, pOrderBy->a[i].pExpr);
|
sqliteExprCode(pParse, pOrderBy->a[i].pExpr);
|
||||||
@@ -288,14 +357,5 @@ void sqliteSelect(
|
|||||||
if( isAgg ){
|
if( isAgg ){
|
||||||
sqliteVdbeAddOp(v, OP_Callback, pEList->nExpr, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_Callback, pEList->nExpr, 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
/* Always execute the following code before exiting, in order to
|
|
||||||
** release resources.
|
|
||||||
*/
|
|
||||||
select_cleanup:
|
|
||||||
sqliteExprListDelete(pEList);
|
|
||||||
sqliteIdListDelete(pTabList);
|
|
||||||
sqliteExprDelete(pWhere);
|
|
||||||
sqliteExprListDelete(pOrderBy);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
@@ -23,7 +23,7 @@
|
|||||||
*************************************************************************
|
*************************************************************************
|
||||||
** Internal interface definitions for SQLite.
|
** Internal interface definitions for SQLite.
|
||||||
**
|
**
|
||||||
** @(#) $Id: sqliteInt.h,v 1.13 2000/06/05 02:07:04 drh Exp $
|
** @(#) $Id: sqliteInt.h,v 1.14 2000/06/05 16:01:39 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqlite.h"
|
#include "sqlite.h"
|
||||||
#include "dbbe.h"
|
#include "dbbe.h"
|
||||||
@@ -35,7 +35,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
/* #define MEMORY_DEBUG 1 */
|
#define MEMORY_DEBUG 1
|
||||||
#ifdef MEMORY_DEBUG
|
#ifdef MEMORY_DEBUG
|
||||||
# define sqliteMalloc(X) sqliteMalloc_(X,__FILE__,__LINE__)
|
# define sqliteMalloc(X) sqliteMalloc_(X,__FILE__,__LINE__)
|
||||||
# define sqliteFree(X) sqliteFree_(X,__FILE__,__LINE__)
|
# define sqliteFree(X) sqliteFree_(X,__FILE__,__LINE__)
|
||||||
@@ -87,6 +87,7 @@ typedef struct Parse Parse;
|
|||||||
typedef struct Token Token;
|
typedef struct Token Token;
|
||||||
typedef struct IdList IdList;
|
typedef struct IdList IdList;
|
||||||
typedef struct WhereInfo WhereInfo;
|
typedef struct WhereInfo WhereInfo;
|
||||||
|
typedef struct Select Select;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Each database is an instance of the following structure
|
** Each database is an instance of the following structure
|
||||||
@@ -208,6 +209,20 @@ struct WhereInfo {
|
|||||||
int iBreak;
|
int iBreak;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
** An instance of the following structure contains all information
|
||||||
|
** needed to generate code for a single SELECT statement.
|
||||||
|
*/
|
||||||
|
struct Select {
|
||||||
|
int isDistinct; /* True if the DISTINCT keyword is present */
|
||||||
|
ExprList *pEList; /* The fields of the result */
|
||||||
|
IdList *pSrc; /* The FROM clause */
|
||||||
|
Expr *pWhere; /* The WHERE clause */
|
||||||
|
ExprList *pGroupBy; /* The GROUP BY clause */
|
||||||
|
Expr *pHaving; /* The HAVING clause */
|
||||||
|
ExprList *pOrderBy; /* The ORDER BY clause */
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** An SQL parser context
|
** An SQL parser context
|
||||||
*/
|
*/
|
||||||
@@ -266,7 +281,9 @@ void sqliteIdListAddAlias(IdList*, Token*);
|
|||||||
void sqliteIdListDelete(IdList*);
|
void sqliteIdListDelete(IdList*);
|
||||||
void sqliteCreateIndex(Parse*, Token*, Token*, IdList*, Token*, Token*);
|
void sqliteCreateIndex(Parse*, Token*, Token*, IdList*, Token*, Token*);
|
||||||
void sqliteDropIndex(Parse*, Token*);
|
void sqliteDropIndex(Parse*, Token*);
|
||||||
void sqliteSelect(Parse*, ExprList*, IdList*, Expr*, ExprList*, int);
|
int sqliteSelect(Parse*, Select*, Table*, int);
|
||||||
|
Select *sqliteSelectNew(ExprList*,IdList*,Expr*,ExprList*,Expr*,ExprList*,int);
|
||||||
|
void sqliteSelectDelete(Select*);
|
||||||
void sqliteDeleteFrom(Parse*, Token*, Expr*);
|
void sqliteDeleteFrom(Parse*, Token*, Expr*);
|
||||||
void sqliteUpdate(Parse*, Token*, ExprList*, Expr*);
|
void sqliteUpdate(Parse*, Token*, ExprList*, Expr*);
|
||||||
WhereInfo *sqliteWhereBegin(Parse*, IdList*, Expr*, int);
|
WhereInfo *sqliteWhereBegin(Parse*, IdList*, Expr*, int);
|
||||||
|
@@ -26,7 +26,7 @@
|
|||||||
** This file contains functions for allocating memory, comparing
|
** This file contains functions for allocating memory, comparing
|
||||||
** strings, and stuff like that.
|
** strings, and stuff like that.
|
||||||
**
|
**
|
||||||
** $Id: util.c,v 1.10 2000/06/04 12:58:38 drh Exp $
|
** $Id: util.c,v 1.11 2000/06/05 16:01:39 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
@@ -102,13 +102,13 @@ void *sqliteRealloc_(void *oldP, int n, char *zFile, int line){
|
|||||||
oldPi -= 2;
|
oldPi -= 2;
|
||||||
if( oldPi[0]!=0xdead1122 ){
|
if( oldPi[0]!=0xdead1122 ){
|
||||||
fprintf(stderr,"Low-end memory corruption in realloc at 0x%x\n", (int)p);
|
fprintf(stderr,"Low-end memory corruption in realloc at 0x%x\n", (int)p);
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
oldN = oldPi[1];
|
oldN = oldPi[1];
|
||||||
oldK = (oldN+sizeof(int)-1)/sizeof(int);
|
oldK = (oldN+sizeof(int)-1)/sizeof(int);
|
||||||
if( oldPi[oldK+2]!=0xdead3344 ){
|
if( oldPi[oldK+2]!=0xdead3344 ){
|
||||||
fprintf(stderr,"High-end memory corruption in realloc at 0x%x\n", (int)p);
|
fprintf(stderr,"High-end memory corruption in realloc at 0x%x\n", (int)p);
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
k = (n + sizeof(int) - 1)/sizeof(int);
|
k = (n + sizeof(int) - 1)/sizeof(int);
|
||||||
pi = malloc( (k+3)*sizeof(int) );
|
pi = malloc( (k+3)*sizeof(int) );
|
||||||
|
@@ -41,9 +41,10 @@
|
|||||||
** But other routines are also provided to help in building up
|
** But other routines are also provided to help in building up
|
||||||
** a program instruction by instruction.
|
** a program instruction by instruction.
|
||||||
**
|
**
|
||||||
** $Id: vdbe.c,v 1.14 2000/06/05 02:07:04 drh Exp $
|
** $Id: vdbe.c,v 1.15 2000/06/05 16:01:39 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** SQL is translated into a sequence of instructions to be
|
** SQL is translated into a sequence of instructions to be
|
||||||
@@ -741,7 +742,6 @@ int sqliteVdbeExec(
|
|||||||
*/
|
*/
|
||||||
case OP_Null: {
|
case OP_Null: {
|
||||||
int i = ++p->tos;
|
int i = ++p->tos;
|
||||||
char *z;
|
|
||||||
if( NeedStack(p, p->tos) ) goto no_mem;
|
if( NeedStack(p, p->tos) ) goto no_mem;
|
||||||
p->zStack[i] = 0;
|
p->zStack[i] = 0;
|
||||||
p->aStack[i].flags = STK_Null;
|
p->aStack[i].flags = STK_Null;
|
||||||
|
Reference in New Issue
Block a user