/ Check-in [43507bbe]
Login

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

Overview
Comment:Re-factored memory allocation failure handling in the sqlite3LimitWhere() function based on failures in the mallocJ.test script. (CVS 5791)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 43507bbefbf79e8db8fe31319ad621d48247983f
User & Date: shane 2008-10-10 13:35:58
Context
2008-10-10
14:27
Simplify the parser reduction code for the LIMIT clause on an UPDATE or DELETE. (CVS 5792) check-in: 3de17963 user: drh tags: trunk
13:35
Re-factored memory allocation failure handling in the sqlite3LimitWhere() function based on failures in the mallocJ.test script. (CVS 5791) check-in: 43507bbe user: shane tags: trunk
13:34
Added mallocJ.test to test allocation failure handling of the new LIMIT/OFFSET support for UPDATE/DELETE. (CVS 5790) check-in: 5375b348 user: shane tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/delete.c.

     8      8   **    May you find forgiveness for yourself and forgive others.
     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   ** This file contains C code routines that are called by the parser
    13     13   ** in order to generate code for DELETE FROM statements.
    14     14   **
    15         -** $Id: delete.c,v 1.179 2008/10/10 04:34:16 shane Exp $
           15  +** $Id: delete.c,v 1.180 2008/10/10 13:35:58 shane Exp $
    16     16   */
    17     17   #include "sqliteInt.h"
    18     18   
    19     19   /*
    20     20   ** Look up every table that is named in pSrc.  If any table is not found,
    21     21   ** add an error message to pParse->zErrMsg and return NULL.  If all tables
    22     22   ** are found, return a pointer to the last table.
................................................................................
   146    146     if (!pLimit && !pOffset) return pWhere;
   147    147   
   148    148     /* Generate a select expression tree to enforce the limit/offset 
   149    149     ** term for the DELETE or UPDATE statement.  For example:
   150    150     **   DELETE FROM table_a WHERE col1=1 ORDER BY col2 LIMIT 1 OFFSET 1
   151    151     ** becomes:
   152    152     **   DELETE FROM table_a WHERE rowid IN ( 
   153         -  **     DELETE rowid FROM table_a WHERE col1=1 ORDER BY col2 LIMIT 1 OFFSET 1
          153  +  **     SELECT rowid FROM table_a WHERE col1=1 ORDER BY col2 LIMIT 1 OFFSET 1
   154    154     **   );
   155    155     */
          156  +
   156    157     pSelectRowid = sqlite3Expr(pParse->db, TK_ROW, 0, 0, 0);
   157         -  if( pSelectRowid == 0 ) goto limit_where_cleanup;
          158  +  if( pSelectRowid == 0 ) return 0;
   158    159     pEList = sqlite3ExprListAppend(pParse, 0, pSelectRowid, 0);
   159         -  if( pEList == 0 ) goto limit_where_cleanup;
          160  +  if( pEList == 0 ) return 0;
          161  +
   160    162     /* duplicate the FROM clause as it is needed by both the DELETE/UPDATE tree
   161         -  ** and the DELETE tree. */
          163  +  ** and the SELECT subtree. */
   162    164     pSelectSrc = sqlite3SrcListDup(pParse->db, pSrc);
   163         -  if( pSelectSrc == 0 ) goto limit_where_cleanup;
   164         -  /* generate the DELETE expression tree. */
          165  +  if( pSelectSrc == 0 ) {
          166  +    sqlite3ExprListDelete(pParse->db, pEList);
          167  +    return 0;
          168  +  }
          169  +
          170  +  /* generate the SELECT expression tree. */
   165    171     pSelect = sqlite3SelectNew(pParse,pEList,pSelectSrc,pWhere,0,0,pOrderBy,0,pLimit,pOffset);
   166         -  if( pSelect == 0 ) goto limit_where_cleanup;
   167         -  /* generate the WHERE rowid IN ( select ) expression */
          172  +  if( pSelect == 0 ) return 0;
          173  +
   168    174     pWhereRowid = sqlite3Expr(pParse->db, TK_ROW, 0, 0, 0);
   169    175     if( pWhereRowid == 0 ) goto limit_where_cleanup;
   170    176     pInClause = sqlite3PExpr(pParse, TK_IN, pWhereRowid, 0, 0);
   171    177     if( pInClause == 0 ) goto limit_where_cleanup;
          178  +
   172    179     pInClause->pSelect = pSelect;
   173    180     sqlite3ExprSetHeight(pParse, pInClause);
   174    181     return pInClause;
   175    182   
   176         -limit_where_cleanup:
   177    183     /* something went wrong. clean up anything allocated. */
   178         -  sqlite3SrcListDelete(pParse->db, pSelectSrc);
   179         -  sqlite3ExprListDelete(pParse->db, pEList);
   180         -  sqlite3ExprDelete(pParse->db, pSelectRowid);
   181         -  sqlite3ExprDelete(pParse->db, pInClause);
   182         -  sqlite3ExprDelete(pParse->db, pWhereRowid);
          184  +limit_where_cleanup:
          185  +  sqlite3SelectDelete(pParse->db, pSelect);
   183    186     return 0;
   184    187   }
   185    188   #endif /* defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY) */
   186    189   
   187    190   /*
   188    191   ** Generate code for a DELETE FROM statement.
   189    192   **