/ Check-in [c47d552e]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment::-) (CVS 75)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: c47d552e7e275dcc03a687e2a874e8e6e1eeb109
User & Date: drh 2000-06-08 00:19:03
Context
2000-06-08
00:28
:-) (CVS 76) check-in: 19029233 user: drh tags: trunk
00:19
:-) (CVS 75) check-in: c47d552e user: drh tags: trunk
2000-06-07
23:51
:-) (CVS 74) check-in: 2ffeb850 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/select.c.

    20     20   **   drh@hwaci.com
    21     21   **   http://www.hwaci.com/drh/
    22     22   **
    23     23   *************************************************************************
    24     24   ** This file contains C code routines that are called by the parser
    25     25   ** to handle SELECT statements.
    26     26   **
    27         -** $Id: select.c,v 1.16 2000/06/07 23:51:50 drh Exp $
           27  +** $Id: select.c,v 1.17 2000/06/08 00:19:03 drh Exp $
    28     28   */
    29     29   #include "sqliteInt.h"
    30     30   
    31     31   /*
    32     32   ** Allocate a new Select structure and return a pointer to that
    33     33   ** structure.
    34     34   */
................................................................................
   425    425       
   426    426   
   427    427   /*
   428    428   ** This routine is called to process a query that is really the union
   429    429   ** or intersection of two or more separate queries.
   430    430   */
   431    431   static int multiSelect(Parse *pParse, Select *p, int eDest, int iParm){
   432         -  int rc;
   433         -  Select *pPrior;
   434         -  Vdbe *v;
          432  +  int rc;             /* Success code from a subroutine */
          433  +  Select *pPrior;     /* Another SELECT immediately to our left */
          434  +  Vdbe *v;            /* Generate code to this VDBE */
          435  +  int base;           /* Baseline value for pParse->nTab */
   435    436   
   436    437     /* Make sure there is no ORDER BY clause on prior SELECTs.  Only the 
   437    438     ** last SELECT in the series may have an ORDER BY.
   438    439     */
   439    440     assert( p->pPrior!=0 );
   440    441     pPrior = p->pPrior;
   441    442     if( pPrior->pOrderBy ){
................................................................................
   448    449     /* Make sure we have a valid query engine.  If not, create a new one.
   449    450     */
   450    451     v = sqliteGetVdbe(pParse);
   451    452     if( v==0 ) return 1;
   452    453   
   453    454     /* Process the UNION or INTERSECTION
   454    455     */
          456  +  base = pParse->nTab;
   455    457     switch( p->op ){
   456    458       case TK_ALL:
   457    459       case TK_EXCEPT:
   458    460       case TK_UNION: {
   459    461         int unionTab;    /* Cursor number of the temporary table holding result */
   460    462         int op;          /* One of the SRT_ operations to apply to self */
   461    463         int priorOp;     /* The SRT_ operation to apply to prior selects */
................................................................................
   576    578     assert( p->pEList && pPrior->pEList );
   577    579     if( p->pEList->nExpr!=pPrior->pEList->nExpr ){
   578    580       sqliteSetString(&pParse->zErrMsg, "SELECTs to the left and right of ",
   579    581         selectOpName(p->op), " do not have the same number of result columns", 0);
   580    582       pParse->nErr++;
   581    583       return 1;
   582    584     }
          585  +  pParse->nTab = base;
   583    586     return 0;
   584    587   }
   585    588   
   586    589   /*
   587    590   ** Generate code for the given SELECT statement.
   588    591   **
   589    592   ** The results are distributed in various ways depending on the
................................................................................
   622    625     IdList *pTabList;      /* List of tables to select from */
   623    626     Expr *pWhere;          /* The WHERE clause.  May be NULL */
   624    627     ExprList *pOrderBy;    /* The ORDER BY clause.  May be NULL */
   625    628     ExprList *pGroupBy;    /* The GROUP BY clause.  May be NULL */
   626    629     Expr *pHaving;         /* The HAVING clause.  May be NULL */
   627    630     int isDistinct;        /* True if the DISTINCT keyword is present */
   628    631     int distinct;          /* Table to use for the distinct set */
          632  +  int base;              /* First cursor available for use */
   629    633   
   630    634     /* If there is are a sequence of queries, do the earlier ones first.
   631    635     */
   632    636     if( p->pPrior ){
   633    637       return multiSelect(pParse, p, eDest, iParm);
   634    638     }
   635    639   
................................................................................
   638    642     pTabList = p->pSrc;
   639    643     pWhere = p->pWhere;
   640    644     pOrderBy = p->pOrderBy;
   641    645     pGroupBy = p->pGroupBy;
   642    646     pHaving = p->pHaving;
   643    647     isDistinct = p->isDistinct;
   644    648   
          649  +  /* Save the current value of pParse->nTab.  Restore this value before
          650  +  ** we exit.
          651  +  */
          652  +  base = pParse->nTab;
          653  +
   645    654     /* 
   646    655     ** Do not even attempt to generate any code if we have already seen
   647    656     ** errors before this routine starts.
   648    657     */
   649         -  if( pParse->nErr>0 ) return 0;
          658  +  if( pParse->nErr>0 ) return 1;
   650    659     sqliteParseInfoReset(pParse);
   651    660   
   652    661     /* Look up every table in the table list and create an appropriate
   653    662     ** columnlist in pEList if there isn't one already.  (The parser leaves
   654    663     ** a NULL in the pEList field if the SQL said "SELECT * FROM ...")
   655    664     */
   656    665     if( fillInColumnList(pParse, p) ){
................................................................................
   698    707     if( pGroupBy ){
   699    708       for(i=0; i<pGroupBy->nExpr; i++){
   700    709         sqliteExprResolveInSelect(pParse, pGroupBy->a[i].pExpr);
   701    710       }
   702    711     }
   703    712     if( pHaving ) sqliteExprResolveInSelect(pParse, pHaving);
   704    713   
   705         -  /* Resolve the field names and do a semantics check on all the expressions.
          714  +  /* At this point, we should have allocated all the cursors that we
          715  +  ** need to handle subquerys and temporary tables.  From here on we
          716  +  ** are committed to keeping the same value for pParse->nTab.
          717  +  **
          718  +  ** Resolve the field names and do a semantics check on all the expressions.
   706    719     */
   707    720     for(i=0; i<pEList->nExpr; i++){
   708    721       if( sqliteExprResolveIds(pParse, pTabList, pEList->a[i].pExpr) ){
   709    722         return 1;
   710    723       }
   711    724       if( sqliteExprCheck(pParse, pEList->a[i].pExpr, 1, &isAgg) ){
   712    725         return 1;
................................................................................
   914    927   
   915    928     /* If there is an ORDER BY clause, then we need to sort the results
   916    929     ** and send them to the callback one by one.
   917    930     */
   918    931     if( pOrderBy ){
   919    932       generateSortTail(v, pEList->nExpr);
   920    933     }
          934  +  pParse->nTab = base;
   921    935     return 0;
   922    936   }