Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | :-) (CVS 75) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
c47d552e7e275dcc03a687e2a874e8e6 |
User & Date: | drh 2000-06-08 00:19:03.000 |
Context
2000-06-08
| ||
00:28 | :-) (CVS 76) (check-in: 1902923308 user: drh tags: trunk) | |
00:19 | :-) (CVS 75) (check-in: c47d552e7e user: drh tags: trunk) | |
2000-06-07
| ||
23:51 | :-) (CVS 74) (check-in: 2ffeb8509c user: drh tags: trunk) | |
Changes
Changes to src/select.c.
︙ | ︙ | |||
20 21 22 23 24 25 26 | ** drh@hwaci.com ** http://www.hwaci.com/drh/ ** ************************************************************************* ** This file contains C code routines that are called by the parser ** to handle SELECT statements. ** | | | 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | ** 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. */ |
︙ | ︙ | |||
425 426 427 428 429 430 431 | /* ** 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){ | | | | > > | 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 | /* ** 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 ){ sqliteSetString(&pParse->zErrMsg,"ORDER BY clause should come after ", selectOpName(p->op), " not before", 0); pParse->nErr++; return 1; } /* 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 */ |
︙ | ︙ | |||
576 577 578 579 580 581 582 583 584 585 586 587 588 589 | 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 | > | 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 | 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 |
︙ | ︙ | |||
622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 | 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); } /* Make local copies of the parameters for this query. */ 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. */ | > > > > > > | | 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 | 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); } /* Make local copies of the parameters for this query. */ 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) ){ |
︙ | ︙ | |||
698 699 700 701 702 703 704 | if( pGroupBy ){ for(i=0; i<pGroupBy->nExpr; i++){ sqliteExprResolveInSelect(pParse, pGroupBy->a[i].pExpr); } } if( pHaving ) sqliteExprResolveInSelect(pParse, pHaving); | > > > > | | 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 | 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; |
︙ | ︙ | |||
914 915 916 917 918 919 920 921 922 | /* 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; } | > | 927 928 929 930 931 932 933 934 935 936 | /* 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; } |