diff options
author | drh <drh@noemail.net> | 2007-05-03 13:02:26 +0000 |
---|---|---|
committer | drh <drh@noemail.net> | 2007-05-03 13:02:26 +0000 |
commit | f68d7d17a18496d8cf33a4997b4a5cc4d05681c7 (patch) | |
tree | 6cfb46cafdf104622759ba42f0f917a3086e21d8 /src | |
parent | cdf1c4d21fb03290e204720c91b303d333cb0286 (diff) | |
download | sqlite-f68d7d17a18496d8cf33a4997b4a5cc4d05681c7.tar.gz sqlite-f68d7d17a18496d8cf33a4997b4a5cc4d05681c7.zip |
Use memmove() instead of memcpy() when moving between memory regions that
might overlap. Ticket #2334. (CVS 3905)
FossilOrigin-Name: 678d672b73cc7b7f563c15daee3831cb5bbd890e
Diffstat (limited to 'src')
-rw-r--r-- | src/select.c | 22 |
1 files changed, 18 insertions, 4 deletions
diff --git a/src/select.c b/src/select.c index 62ba72565..ed524c2e7 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.338 2007/04/16 17:07:55 drh Exp $ +** $Id: select.c,v 1.339 2007/05/03 13:02:27 drh Exp $ */ #include "sqliteInt.h" @@ -1909,8 +1909,8 @@ static int multiSelect( KeyInfo *pKeyInfo; /* Collating sequence for the result set */ Select *pLoop; /* For looping through SELECT statements */ int nKeyCol; /* Number of entries in pKeyInfo->aCol[] */ - CollSeq **apColl; - CollSeq **aCopy; + CollSeq **apColl; /* For looping through pKeyInfo->aColl[] */ + CollSeq **aCopy; /* A copy of pKeyInfo->aColl[] */ assert( p->pRightmost==p ); nKeyCol = nCol + (pOrderBy ? pOrderBy->nExpr : 0); @@ -1951,9 +1951,23 @@ static int multiSelect( int addr; u8 *pSortOrder; + /* Reuse the same pKeyInfo for the ORDER BY as was used above for + ** the compound select statements. Except we have to change out the + ** pKeyInfo->aColl[] values. Some of the aColl[] values will be + ** reused when constructing the pKeyInfo for the ORDER BY, so make + ** a copy. Sufficient space to hold both the nCol entries for + ** the compound select and the nOrderbyExpr entries for the ORDER BY + ** was allocated above. But we need to move the compound select + ** entries out of the way before constructing the ORDER BY entries. + ** Move the compound select entries into aCopy[] where they can be + ** accessed and reused when constructing the ORDER BY entries. + ** Because nCol might be greater than or less than nOrderByExpr + ** we have to use memmove() when doing the copy. + */ aCopy = &pKeyInfo->aColl[nOrderByExpr]; pSortOrder = pKeyInfo->aSortOrder = (u8*)&aCopy[nCol]; - memcpy(aCopy, pKeyInfo->aColl, nCol*sizeof(CollSeq*)); + memmove(aCopy, pKeyInfo->aColl, nCol*sizeof(CollSeq*)); + apColl = pKeyInfo->aColl; for(i=0; i<nOrderByExpr; i++, pOTerm++, apColl++, pSortOrder++){ Expr *pExpr = pOTerm->pExpr; |