From dece1a84642a8b52a3b1844c9ba0ae03599f1faa Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 31 Aug 2005 18:20:00 +0000 Subject: [PATCH] {quote: KeyInfo} generation moved to a common subroutine. (CVS 2652) FossilOrigin-Name: a25801df06e218e70570a6b9eae71603d590fe3a --- manifest | 12 +++---- manifest.uuid | 2 +- src/select.c | 87 +++++++++++++++++++++++++-------------------------- 3 files changed, 49 insertions(+), 52 deletions(-) diff --git a/manifest b/manifest index 639cb2dec0..79225b7f13 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Updates\sto\sthe\squery\soptimizer\soverview\sdocument.\s(CVS\s2651) -D 2005-08-31T13:48:35 +C {quote:\sKeyInfo}\sgeneration\smoved\sto\sa\scommon\ssubroutine.\s(CVS\s2652) +D 2005-08-31T18:20:00 F Makefile.in 12784cdce5ffc8dfb707300c34e4f1eb3b8a14f1 F Makefile.linux-gcc 06be33b2a9ad4f005a5f42b22c4a19dab3cbb5c7 F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028 @@ -63,7 +63,7 @@ F src/pragma.c 69413fbdc0c6aaa493a776ea52c1b3e6cf35dfb2 F src/prepare.c 86f0d8e744b8d956eff6bc40e29049efee017610 F src/printf.c d2678b06cfa07be9b14c330a42310f62340e34ce F src/random.c 90adff4e73a3b249eb4f1fc2a6ff9cf78c7233a4 -F src/select.c a185b91fd0060a16ada1a32de844d8e570273070 +F src/select.c cf566f995358f728288f0be481f12d20305117c0 F src/shell.c b21daba017b8feef2fdc65ecde57f70209494217 F src/sqlite.h.in d6561d51025d08de4f455607f3f9f9aa76e855d5 F src/sqliteInt.h 207b63f9782d7faf1f19e694e8052e60841fb377 @@ -306,7 +306,7 @@ F www/tclsqlite.tcl 3df553505b6efcad08f91e9b975deb2e6c9bb955 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0 F www/version3.tcl a99cf5f6d8bd4d5537584a2b342f0fb9fa601d8b F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513 -P 90712ea7273597214d6c77a01e41f84146d201c8 -R caf39f797300b82be8fdb35ca85651cd +P b1dceef0508ffe20ab2ff8fa5e5b5a44f4f224aa +R 22b6fa7b5f0b031707b250894ea2c1df U drh -Z be0a7dd07de7a11911fd94c99400be61 +Z 24532867563e79fa05da569ea322e240 diff --git a/manifest.uuid b/manifest.uuid index e78f70a22e..acc282824b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b1dceef0508ffe20ab2ff8fa5e5b5a44f4f224aa \ No newline at end of file +a25801df06e218e70570a6b9eae71603d590fe3a \ No newline at end of file diff --git a/src/select.c b/src/select.c index bb8c06e863..631f82d3ea 100644 --- a/src/select.c +++ b/src/select.c @@ -12,7 +12,7 @@ ** This file contains C code routines that are called by the parser ** to handle SELECT statements in SQLite. ** -** $Id: select.c,v 1.256 2005/08/30 00:54:03 drh Exp $ +** $Id: select.c,v 1.257 2005/08/31 18:20:00 drh Exp $ */ #include "sqliteInt.h" @@ -551,6 +551,42 @@ static int selectInnerLoop( 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; ipExpr); + 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 @@ -569,28 +605,10 @@ static void generateSortTail( int end2 = sqlite3VdbeMakeLabel(v); int addr; KeyInfo *pInfo; - ExprList *pOrderBy; - int nCol, i; - sqlite3 *db = pParse->db; if( eDest==SRT_Sorter ) return; - pOrderBy = p->pOrderBy; - nCol = pOrderBy->nExpr; - pInfo = sqliteMalloc( sizeof(*pInfo) + nCol*(sizeof(CollSeq*)+1) ); + pInfo = keyInfoFromExprList(pParse, p->pOrderBy); if( pInfo==0 ) return; - pInfo->aSortOrder = (char*)&pInfo->aColl[nCol]; - pInfo->nField = nCol; - for(i=0; ia[i].zName. Otherwise, use the default - ** collation type for the expression. - */ - pInfo->aColl[i] = sqlite3ExprCollSeq(pParse, pOrderBy->a[i].pExpr); - if( !pInfo->aColl[i] ){ - pInfo->aColl[i] = db->pDfltColl; - } - pInfo->aSortOrder[i] = pOrderBy->a[i].sortOrder; - } sqlite3VdbeOp3(v, OP_Sort, 0, 0, (char*)pInfo, P3_KEYINFO_HANDOFF); addr = sqlite3VdbeAddOp(v, OP_SortNext, 0, end1); codeLimiter(v, p, addr, end2, 1); @@ -1323,28 +1341,16 @@ static void computeLimitRegisters(Parse *pParse, Select *p){ */ static int openVirtualIndex(Parse *pParse, Select *p, int iTab){ KeyInfo *pKeyInfo; - int nColumn; - sqlite3 *db = pParse->db; - int i; Vdbe *v = pParse->pVdbe; int addr; if( prepSelectStmt(pParse, p) ){ return 0; } - nColumn = p->pEList->nExpr; - pKeyInfo = sqliteMalloc( sizeof(*pKeyInfo)+nColumn*sizeof(CollSeq*) ); + pKeyInfo = keyInfoFromExprList(pParse, p->pEList); if( pKeyInfo==0 ) return 0; - pKeyInfo->enc = db->enc; - pKeyInfo->nField = nColumn; - for(i=0; iaColl[i] = sqlite3ExprCollSeq(pParse, p->pEList->a[i].pExpr); - if( !pKeyInfo->aColl[i] ){ - pKeyInfo->aColl[i] = db->pDfltColl; - } - } addr = sqlite3VdbeOp3(v, OP_OpenVirtual, iTab, 0, - (char*)pKeyInfo, P3_KEYINFO_HANDOFF); + (char*)pKeyInfo, P3_KEYINFO_HANDOFF); return addr; } @@ -2696,19 +2702,10 @@ int sqlite3Select( } } if( pGroupBy ){ - int sz = sizeof(KeyInfo) + pGroupBy->nExpr*sizeof(CollSeq*); - KeyInfo *pKey = (KeyInfo *)sqliteMalloc(sz); + KeyInfo *pKey = keyInfoFromExprList(pParse, pGroupBy); if( 0==pKey ){ goto select_end; } - pKey->enc = pParse->db->enc; - pKey->nField = pGroupBy->nExpr; - for(i=0; inExpr; i++){ - pKey->aColl[i] = sqlite3ExprCollSeq(pParse, pGroupBy->a[i].pExpr); - if( !pKey->aColl[i] ){ - pKey->aColl[i] = pParse->db->pDfltColl; - } - } sqlite3VdbeChangeP3(v, addr, (char *)pKey, P3_KEYINFO_HANDOFF); } } @@ -2720,7 +2717,7 @@ int sqlite3Select( sqlite3VdbeAddOp(v, OP_MemStore, iParm, 1); } - /* Open a temporary table to use for the distinct set. + /* Open a virtual index to use for the distinct set. */ if( isDistinct ){ distinct = pParse->nTab++; -- 2.47.2