Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | {quote: KeyInfo} generation moved to a common subroutine. (CVS 2652) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
a25801df06e218e70570a6b9eae71603 |
User & Date: | drh 2005-08-31 18:20:00.000 |
Context
2005-09-01
| ||
03:07 | Sorting is now done using a sorting index rather than loading the entire result set into memory and doing a merge sort. The old merge sort technique was a carry-over from SQLite version 1. The new method uses a bounded amount of memory and scales to much larger result sets. There are still errors: some 39 regression tests fail. (CVS 2653) (check-in: 09db0a2424 user: drh tags: trunk) | |
2005-08-31
| ||
18:20 | {quote: KeyInfo} generation moved to a common subroutine. (CVS 2652) (check-in: a25801df06 user: drh tags: trunk) | |
13:48 | Updates to the query optimizer overview document. (CVS 2651) (check-in: b1dceef050 user: drh tags: trunk) | |
Changes
Changes to src/select.c.
︙ | ︙ | |||
8 9 10 11 12 13 14 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains C code routines that are called by the parser ** to handle SELECT statements in SQLite. ** | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains C code routines that are called by the parser ** to handle SELECT statements in SQLite. ** ** $Id: select.c,v 1.257 2005/08/31 18:20:00 drh Exp $ */ #include "sqliteInt.h" /* ** Allocate a new Select structure and return a pointer to that ** structure. |
︙ | ︙ | |||
546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 | sqlite3VdbeAddOp(v, OP_Pop, nColumn, 0); break; } #endif } return 0; } /* ** If the inner loop was generated using a non-null pOrderBy argument, ** then the results were placed in a sorter. After the loop is terminated ** we need to run the sorter and output the results. The following ** routine generates the code needed to do that. */ static void generateSortTail( Parse *pParse, /* The parsing context */ Select *p, /* The SELECT statement */ Vdbe *v, /* Generate code into this VDBE */ int nColumn, /* Number of columns of data */ int eDest, /* Write the sorted results here */ int iParm /* Optional parameter associated with eDest */ ){ int end1 = sqlite3VdbeMakeLabel(v); int end2 = sqlite3VdbeMakeLabel(v); int addr; KeyInfo *pInfo; | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > < < < | < < < < < < < < < < < < < < < | 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 | sqlite3VdbeAddOp(v, OP_Pop, nColumn, 0); break; } #endif } return 0; } /* ** Given an expression list, generate a KeyInfo structure that records ** the collating sequence for each expression in that expression list. ** ** Space to hold the KeyInfo structure is obtain from malloc. The calling ** function is responsible for seeing that this structure is eventually ** freed. Add the KeyInfo structure to the P3 field of an opcode using ** P3_KEYINFO_HANDOFF is the usual way of dealing with this. */ static KeyInfo *keyInfoFromExprList(Parse *pParse, ExprList *pList){ sqlite3 *db = pParse->db; int nExpr; KeyInfo *pInfo; struct ExprList_item *pItem; int i; nExpr = pList->nExpr; pInfo = sqliteMalloc( sizeof(*pInfo) + nExpr*(sizeof(CollSeq*)+1) ); if( pInfo ){ pInfo->aSortOrder = (char*)&pInfo->aColl[nExpr]; pInfo->nField = nExpr; pInfo->enc = db->enc; for(i=0, pItem=pList->a; i<nExpr; i++, pItem++){ CollSeq *pColl; pColl = sqlite3ExprCollSeq(pParse, pItem->pExpr); if( !pColl ){ pColl = db->pDfltColl; } pInfo->aColl[i] = pColl; pInfo->aSortOrder[i] = pItem->sortOrder; } } return pInfo; } /* ** If the inner loop was generated using a non-null pOrderBy argument, ** then the results were placed in a sorter. After the loop is terminated ** we need to run the sorter and output the results. The following ** routine generates the code needed to do that. */ static void generateSortTail( Parse *pParse, /* The parsing context */ Select *p, /* The SELECT statement */ Vdbe *v, /* Generate code into this VDBE */ int nColumn, /* Number of columns of data */ int eDest, /* Write the sorted results here */ int iParm /* Optional parameter associated with eDest */ ){ int end1 = sqlite3VdbeMakeLabel(v); int end2 = sqlite3VdbeMakeLabel(v); int addr; KeyInfo *pInfo; if( eDest==SRT_Sorter ) return; pInfo = keyInfoFromExprList(pParse, p->pOrderBy); if( pInfo==0 ) return; sqlite3VdbeOp3(v, OP_Sort, 0, 0, (char*)pInfo, P3_KEYINFO_HANDOFF); addr = sqlite3VdbeAddOp(v, OP_SortNext, 0, end1); codeLimiter(v, p, addr, end2, 1); switch( eDest ){ case SRT_Table: case SRT_TempTable: { sqlite3VdbeAddOp(v, OP_NewRowid, iParm, 0); |
︙ | ︙ | |||
1319 1320 1321 1322 1323 1324 1325 | ** DISTINCT, UNION, INTERSECT and EXCEPT select statements (but not ** UNION ALL). ** ** The value returned is the address of the OP_OpenVirtual instruction. */ static int openVirtualIndex(Parse *pParse, Select *p, int iTab){ KeyInfo *pKeyInfo; | < < < | < < < < < < < < < | | 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 | ** DISTINCT, UNION, INTERSECT and EXCEPT select statements (but not ** UNION ALL). ** ** The value returned is the address of the OP_OpenVirtual instruction. */ static int openVirtualIndex(Parse *pParse, Select *p, int iTab){ KeyInfo *pKeyInfo; Vdbe *v = pParse->pVdbe; int addr; if( prepSelectStmt(pParse, p) ){ return 0; } pKeyInfo = keyInfoFromExprList(pParse, p->pEList); if( pKeyInfo==0 ) return 0; addr = sqlite3VdbeOp3(v, OP_OpenVirtual, iTab, 0, (char*)pKeyInfo, P3_KEYINFO_HANDOFF); return addr; } #ifndef SQLITE_OMIT_COMPOUND_SELECT /* ** Add the address "addr" to the set of all OpenVirtual opcode addresses ** that are being accumulated in p->ppOpenVirtual. |
︙ | ︙ | |||
2692 2693 2694 2695 2696 2697 2698 | nExpr = pAggExpr->pList->nExpr; } #endif sqlite3VdbeOp3(v, OP_AggInit, nExpr, i, (char*)pFunc, P3_FUNCDEF); } } if( pGroupBy ){ | < | < < < < < < < < | | 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 | nExpr = pAggExpr->pList->nExpr; } #endif sqlite3VdbeOp3(v, OP_AggInit, nExpr, i, (char*)pFunc, P3_FUNCDEF); } } if( pGroupBy ){ KeyInfo *pKey = keyInfoFromExprList(pParse, pGroupBy); if( 0==pKey ){ goto select_end; } sqlite3VdbeChangeP3(v, addr, (char *)pKey, P3_KEYINFO_HANDOFF); } } /* Initialize the memory cell to NULL for SRT_Mem or 0 for SRT_Exists */ if( eDest==SRT_Mem || eDest==SRT_Exists ){ sqlite3VdbeAddOp(v, eDest==SRT_Mem ? OP_Null : OP_Integer, 0, 0); sqlite3VdbeAddOp(v, OP_MemStore, iParm, 1); } /* Open a virtual index to use for the distinct set. */ if( isDistinct ){ distinct = pParse->nTab++; openVirtualIndex(pParse, p, distinct); }else{ distinct = -1; } |
︙ | ︙ |