SQLite

Check-in [678d672b73]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Use memmove() instead of memcpy() when moving between memory regions that might overlap. Ticket #2334. (CVS 3905)
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 678d672b73cc7b7f563c15daee3831cb5bbd890e
User & Date: drh 2007-05-03 13:02:27.000
Context
2007-05-03
13:11
Fix a bug where accessPayload() was calling PagerWrite() on the wrong page handle. Ticket #2332. (CVS 3906) (check-in: cf9eeba7be user: danielk1977 tags: trunk)
13:02
Use memmove() instead of memcpy() when moving between memory regions that might overlap. Ticket #2334. (CVS 3905) (check-in: 678d672b73 user: drh tags: trunk)
11:43
Minor bugfixes for incrblob mode. (CVS 3904) (check-in: b84d597c90 user: danielk1977 tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/select.c.
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.338 2007/04/16 17:07:55 drh Exp $
*/
#include "sqliteInt.h"


/*
** Delete all the content of a Select structure but do not deallocate
** the select structure itself.







|







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.339 2007/05/03 13:02:27 drh Exp $
*/
#include "sqliteInt.h"


/*
** Delete all the content of a Select structure but do not deallocate
** the select structure itself.
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
  ** no temp tables are required.
  */
  if( pOrderBy || p->usesEphm ){
    int i;                        /* Loop counter */
    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;

    assert( p->pRightmost==p );
    nKeyCol = nCol + (pOrderBy ? pOrderBy->nExpr : 0);
    pKeyInfo = sqliteMalloc(sizeof(*pKeyInfo)+nKeyCol*(sizeof(CollSeq*) + 1));
    if( !pKeyInfo ){
      rc = SQLITE_NOMEM;
      goto multi_select_end;







|
|







1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
  ** no temp tables are required.
  */
  if( pOrderBy || p->usesEphm ){
    int i;                        /* Loop counter */
    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;             /* For looping through pKeyInfo->aColl[] */
    CollSeq **aCopy;              /* A copy of pKeyInfo->aColl[] */

    assert( p->pRightmost==p );
    nKeyCol = nCol + (pOrderBy ? pOrderBy->nExpr : 0);
    pKeyInfo = sqliteMalloc(sizeof(*pKeyInfo)+nKeyCol*(sizeof(CollSeq*) + 1));
    if( !pKeyInfo ){
      rc = SQLITE_NOMEM;
      goto multi_select_end;
1947
1948
1949
1950
1951
1952
1953













1954
1955
1956

1957
1958
1959
1960
1961
1962
1963

    if( pOrderBy ){
      struct ExprList_item *pOTerm = pOrderBy->a;
      int nOrderByExpr = pOrderBy->nExpr;
      int addr;
      u8 *pSortOrder;














      aCopy = &pKeyInfo->aColl[nOrderByExpr];
      pSortOrder = pKeyInfo->aSortOrder = (u8*)&aCopy[nCol];
      memcpy(aCopy, pKeyInfo->aColl, nCol*sizeof(CollSeq*));

      apColl = pKeyInfo->aColl;
      for(i=0; i<nOrderByExpr; i++, pOTerm++, apColl++, pSortOrder++){
        Expr *pExpr = pOTerm->pExpr;
        if( (pExpr->flags & EP_ExpCollate) ){
          assert( pExpr->pColl!=0 );
          *apColl = pExpr->pColl;
        }else{







>
>
>
>
>
>
>
>
>
>
>
>
>


|
>







1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977

    if( pOrderBy ){
      struct ExprList_item *pOTerm = pOrderBy->a;
      int nOrderByExpr = pOrderBy->nExpr;
      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];
      memmove(aCopy, pKeyInfo->aColl, nCol*sizeof(CollSeq*));

      apColl = pKeyInfo->aColl;
      for(i=0; i<nOrderByExpr; i++, pOTerm++, apColl++, pSortOrder++){
        Expr *pExpr = pOTerm->pExpr;
        if( (pExpr->flags & EP_ExpCollate) ){
          assert( pExpr->pColl!=0 );
          *apColl = pExpr->pColl;
        }else{