** drh@hwaci.com
** http://www.hwaci.com/drh/
**
*************************************************************************
** This file contains C code routines that are called by the parser
** to handle SELECT statements.
**
** $Id: select.c,v 1.16 2000/06/07 23:51:50 drh Exp $
*/
#include "sqliteInt.h"
/*
** Allocate a new Select structure and return a pointer to that
** structure.
*/
................................................................................
/*
** This routine is called to process a query that is really the union
** or intersection of two or more separate queries.
*/
static int multiSelect(Parse *pParse, Select *p, int eDest, int iParm){
int rc;
Select *pPrior;
Vdbe *v;
/* Make sure there is no ORDER BY clause on prior SELECTs. Only the
** last SELECT in the series may have an ORDER BY.
*/
assert( p->pPrior!=0 );
pPrior = p->pPrior;
if( pPrior->pOrderBy ){
................................................................................
/* Make sure we have a valid query engine. If not, create a new one.
*/
v = sqliteGetVdbe(pParse);
if( v==0 ) return 1;
/* Process the UNION or INTERSECTION
*/
switch( p->op ){
case TK_ALL:
case TK_EXCEPT:
case TK_UNION: {
int unionTab; /* Cursor number of the temporary table holding result */
int op; /* One of the SRT_ operations to apply to self */
int priorOp; /* The SRT_ operation to apply to prior selects */
................................................................................
assert( p->pEList && pPrior->pEList );
if( p->pEList->nExpr!=pPrior->pEList->nExpr ){
sqliteSetString(&pParse->zErrMsg, "SELECTs to the left and right of ",
selectOpName(p->op), " do not have the same number of result columns", 0);
pParse->nErr++;
return 1;
}
return 0;
}
/*
** Generate code for the given SELECT statement.
**
** The results are distributed in various ways depending on the
................................................................................
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 */
ExprList *pGroupBy; /* The GROUP BY clause. May be NULL */
Expr *pHaving; /* The HAVING clause. May be NULL */
int isDistinct; /* True if the DISTINCT keyword is present */
int distinct; /* Table to use for the distinct set */
/* If there is are a sequence of queries, do the earlier ones first.
*/
if( p->pPrior ){
return multiSelect(pParse, p, eDest, iParm);
}
................................................................................
pTabList = p->pSrc;
pWhere = p->pWhere;
pOrderBy = p->pOrderBy;
pGroupBy = p->pGroupBy;
pHaving = p->pHaving;
isDistinct = 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;
sqliteParseInfoReset(pParse);
/* Look up every table in the table list and create an appropriate
** columnlist in pEList if there isn't one already. (The parser leaves
** a NULL in the pEList field if the SQL said "SELECT * FROM ...")
*/
if( fillInColumnList(pParse, p) ){
................................................................................
if( pGroupBy ){
for(i=0; i<pGroupBy->nExpr; i++){
sqliteExprResolveInSelect(pParse, pGroupBy->a[i].pExpr);
}
}
if( pHaving ) sqliteExprResolveInSelect(pParse, pHaving);
/* Resolve the field names and do a semantics check on all the expressions.
*/
for(i=0; i<pEList->nExpr; i++){
if( sqliteExprResolveIds(pParse, pTabList, pEList->a[i].pExpr) ){
return 1;
}
if( sqliteExprCheck(pParse, pEList->a[i].pExpr, 1, &isAgg) ){
return 1;
................................................................................
/* If there is an ORDER BY clause, then we need to sort the results
** and send them to the callback one by one.
*/
if( pOrderBy ){
generateSortTail(v, pEList->nExpr);
}
return 0;
}

** drh@hwaci.com
** http://www.hwaci.com/drh/
**
*************************************************************************
** This file contains C code routines that are called by the parser
** to handle SELECT statements.
**
** $Id: select.c,v 1.17 2000/06/08 00:19:03 drh Exp $
*/
#include "sqliteInt.h"
/*
** Allocate a new Select structure and return a pointer to that
** structure.
*/
................................................................................
/*
** This routine is called to process a query that is really the union
** or intersection of two or more separate queries.
*/
static int multiSelect(Parse *pParse, Select *p, int eDest, int iParm){
int rc; /* Success code from a subroutine */
Select *pPrior; /* Another SELECT immediately to our left */
Vdbe *v; /* Generate code to this VDBE */ int base; /* Baseline value for pParse->nTab */
/* Make sure there is no ORDER BY clause on prior SELECTs. Only the
** last SELECT in the series may have an ORDER BY.
*/
assert( p->pPrior!=0 );
pPrior = p->pPrior;
if( pPrior->pOrderBy ){
................................................................................
/* Make sure we have a valid query engine. If not, create a new one.
*/
v = sqliteGetVdbe(pParse);
if( v==0 ) return 1;
/* Process the UNION or INTERSECTION
*/
base = pParse->nTab;
switch( p->op ){
case TK_ALL:
case TK_EXCEPT:
case TK_UNION: {
int unionTab; /* Cursor number of the temporary table holding result */
int op; /* One of the SRT_ operations to apply to self */
int priorOp; /* The SRT_ operation to apply to prior selects */
................................................................................
assert( p->pEList && pPrior->pEList );
if( p->pEList->nExpr!=pPrior->pEList->nExpr ){
sqliteSetString(&pParse->zErrMsg, "SELECTs to the left and right of ",
selectOpName(p->op), " do not have the same number of result columns", 0);
pParse->nErr++;
return 1;
}
pParse->nTab = base;
return 0;
}
/*
** Generate code for the given SELECT statement.
**
** The results are distributed in various ways depending on the
................................................................................
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 */
ExprList *pGroupBy; /* The GROUP BY clause. May be NULL */
Expr *pHaving; /* The HAVING clause. May be NULL */
int isDistinct; /* True if the DISTINCT keyword is present */
int distinct; /* Table to use for the distinct set */
int base; /* First cursor available for use */
/* If there is are a sequence of queries, do the earlier ones first.
*/
if( p->pPrior ){
return multiSelect(pParse, p, eDest, iParm);
}
................................................................................
pTabList = p->pSrc;
pWhere = p->pWhere;
pOrderBy = p->pOrderBy;
pGroupBy = p->pGroupBy;
pHaving = p->pHaving;
isDistinct = p->isDistinct;
/* Save the current value of pParse->nTab. Restore this value before ** we exit. */ base = pParse->nTab;
/*
** Do not even attempt to generate any code if we have already seen
** errors before this routine starts.
*/
if( pParse->nErr>0 ) return 1;
sqliteParseInfoReset(pParse);
/* Look up every table in the table list and create an appropriate
** columnlist in pEList if there isn't one already. (The parser leaves
** a NULL in the pEList field if the SQL said "SELECT * FROM ...")
*/
if( fillInColumnList(pParse, p) ){
................................................................................
if( pGroupBy ){
for(i=0; i<pGroupBy->nExpr; i++){
sqliteExprResolveInSelect(pParse, pGroupBy->a[i].pExpr);
}
}
if( pHaving ) sqliteExprResolveInSelect(pParse, pHaving);
/* At this point, we should have allocated all the cursors that we ** need to handle subquerys and temporary tables. From here on we ** are committed to keeping the same value for pParse->nTab. **** Resolve the field names and do a semantics check on all the expressions.
*/
for(i=0; i<pEList->nExpr; i++){
if( sqliteExprResolveIds(pParse, pTabList, pEList->a[i].pExpr) ){
return 1;
}
if( sqliteExprCheck(pParse, pEList->a[i].pExpr, 1, &isAgg) ){
return 1;
................................................................................
/* If there is an ORDER BY clause, then we need to sort the results
** and send them to the callback one by one.
*/
if( pOrderBy ){
generateSortTail(v, pEList->nExpr);
}
pParse->nTab = base;
return 0;
}

This page was generated in about
0.034s by
Fossil 2.9 [356c0d017e] 2019-05-23 17:18:56