1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-11-14 00:22:38 +03:00

Factor all KeyInfo object allocations into a single function:

sqlite3KeyInfoAlloc().  Always allocate enough space so that 
sqlite3VdbeRecordCompare() can avoid checking boundaries and hence
run faster.

FossilOrigin-Name: 7301bedd94c8610568349953b18ff3575203e1b2
This commit is contained in:
drh
2013-08-05 19:11:29 +00:00
parent af5b2af77d
commit 323df7907e
8 changed files with 67 additions and 78 deletions

View File

@@ -802,6 +802,25 @@ static void selectInnerLoop(
}
}
/*
** Allocate a KeyInfo object sufficient for an index of N columns.
**
** Actually, always allocate one extra column for the rowid at the end
** of the index. So the KeyInfo returned will have space sufficient for
** N+1 columns.
*/
KeyInfo *sqlite3KeyInfoAlloc(sqlite3 *db, int N){
KeyInfo *p = sqlite3DbMallocZero(db,
sizeof(KeyInfo) + (N+1)*(sizeof(CollSeq*)+1));
if( p ){
p->aSortOrder = (u8*)&p->aColl[N+1];
p->nField = (u16)N;
p->enc = ENC(db);
p->db = db;
}
return p;
}
/*
** Given an expression list, generate a KeyInfo structure that records
** the collating sequence for each expression in that expression list.
@@ -818,25 +837,19 @@ static void selectInnerLoop(
** P4_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;
sqlite3 *db = pParse->db;
int i;
nExpr = pList->nExpr;
pInfo = sqlite3DbMallocZero(db, sizeof(*pInfo) + nExpr*(sizeof(CollSeq*)+1) );
pInfo = sqlite3KeyInfoAlloc(db, nExpr);
if( pInfo ){
pInfo->aSortOrder = (u8*)&pInfo->aColl[nExpr];
pInfo->nField = (u16)nExpr;
pInfo->enc = ENC(db);
pInfo->db = db;
for(i=0, pItem=pList->a; i<nExpr; i++, pItem++){
CollSeq *pColl;
pColl = sqlite3ExprCollSeq(pParse, pItem->pExpr);
if( !pColl ){
pColl = db->pDfltColl;
}
if( !pColl ) pColl = db->pDfltColl;
pInfo->aColl[i] = pColl;
pInfo->aSortOrder[i] = pItem->sortOrder;
}
@@ -1942,23 +1955,17 @@ static int multiSelect(
assert( p->pRightmost==p );
nCol = p->pEList->nExpr;
pKeyInfo = sqlite3DbMallocZero(db,
sizeof(*pKeyInfo)+nCol*(sizeof(CollSeq*) + 1));
pKeyInfo = sqlite3KeyInfoAlloc(db, nCol);
if( !pKeyInfo ){
rc = SQLITE_NOMEM;
goto multi_select_end;
}
pKeyInfo->enc = ENC(db);
pKeyInfo->nField = (u16)nCol;
for(i=0, apColl=pKeyInfo->aColl; i<nCol; i++, apColl++){
*apColl = multiSelectCollSeq(pParse, p, i);
if( 0==*apColl ){
*apColl = db->pDfltColl;
}
}
pKeyInfo->aSortOrder = (u8*)apColl;
for(pLoop=p; pLoop; pLoop=pLoop->pPrior){
for(i=0; i<2; i++){
@@ -2327,12 +2334,8 @@ static int multiSelectOrderBy(
assert( pItem->iOrderByCol>0 && pItem->iOrderByCol<=p->pEList->nExpr );
aPermute[i] = pItem->iOrderByCol - 1;
}
pKeyMerge =
sqlite3DbMallocRaw(db, sizeof(*pKeyMerge)+nOrderBy*(sizeof(CollSeq*)+1));
pKeyMerge = sqlite3KeyInfoAlloc(db, nOrderBy);
if( pKeyMerge ){
pKeyMerge->aSortOrder = (u8*)&pKeyMerge->aColl[nOrderBy];
pKeyMerge->nField = (u16)nOrderBy;
pKeyMerge->enc = ENC(db);
for(i=0; i<nOrderBy; i++){
CollSeq *pColl;
Expr *pTerm = pOrderBy->a[i].pExpr;
@@ -2369,12 +2372,8 @@ static int multiSelectOrderBy(
regPrev = pParse->nMem+1;
pParse->nMem += nExpr+1;
sqlite3VdbeAddOp2(v, OP_Integer, 0, regPrev);
pKeyDup = sqlite3DbMallocZero(db,
sizeof(*pKeyDup) + nExpr*(sizeof(CollSeq*)+1) );
pKeyDup = sqlite3KeyInfoAlloc(db, nExpr);
if( pKeyDup ){
pKeyDup->aSortOrder = (u8*)&pKeyDup->aColl[nExpr];
pKeyDup->nField = (u16)nExpr;
pKeyDup->enc = ENC(db);
for(i=0; i<nExpr; i++){
pKeyDup->aColl[i] = multiSelectCollSeq(pParse, p, i);
pKeyDup->aSortOrder[i] = 0;