/ 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 Unified Diffs Show Whitespace Changes Patch

Changes to src/delete.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
146
147
148
149
150
151
152
153
154
155

156
157
158
159

160
161
162
163




164
165
166
167

168
169
170
171

172
173
174
175
176
177
178
179

180
181
182
183
184
185
186
187
188
189
**    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
** in order to generate code for DELETE FROM statements.
**
** $Id: delete.c,v 1.179 2008/10/10 04:34:16 shane Exp $
*/
#include "sqliteInt.h"

/*
** Look up every table that is named in pSrc.  If any table is not found,
** add an error message to pParse->zErrMsg and return NULL.  If all tables
** are found, return a pointer to the last table.
................................................................................
  if (!pLimit && !pOffset) return pWhere;

  /* Generate a select expression tree to enforce the limit/offset 
  ** term for the DELETE or UPDATE statement.  For example:
  **   DELETE FROM table_a WHERE col1=1 ORDER BY col2 LIMIT 1 OFFSET 1
  ** becomes:
  **   DELETE FROM table_a WHERE rowid IN ( 
  **     DELETE rowid FROM table_a WHERE col1=1 ORDER BY col2 LIMIT 1 OFFSET 1
  **   );
  */

  pSelectRowid = sqlite3Expr(pParse->db, TK_ROW, 0, 0, 0);
  if( pSelectRowid == 0 ) goto limit_where_cleanup;
  pEList = sqlite3ExprListAppend(pParse, 0, pSelectRowid, 0);
  if( pEList == 0 ) goto limit_where_cleanup;

  /* duplicate the FROM clause as it is needed by both the DELETE/UPDATE tree
  ** and the DELETE tree. */
  pSelectSrc = sqlite3SrcListDup(pParse->db, pSrc);
  if( pSelectSrc == 0 ) goto limit_where_cleanup;




  /* generate the DELETE expression tree. */
  pSelect = sqlite3SelectNew(pParse,pEList,pSelectSrc,pWhere,0,0,pOrderBy,0,pLimit,pOffset);
  if( pSelect == 0 ) goto limit_where_cleanup;
  /* generate the WHERE rowid IN ( select ) expression */

  pWhereRowid = sqlite3Expr(pParse->db, TK_ROW, 0, 0, 0);
  if( pWhereRowid == 0 ) goto limit_where_cleanup;
  pInClause = sqlite3PExpr(pParse, TK_IN, pWhereRowid, 0, 0);
  if( pInClause == 0 ) goto limit_where_cleanup;

  pInClause->pSelect = pSelect;
  sqlite3ExprSetHeight(pParse, pInClause);
  return pInClause;

limit_where_cleanup:
  /* something went wrong. clean up anything allocated. */
  sqlite3SrcListDelete(pParse->db, pSelectSrc);
  sqlite3ExprListDelete(pParse->db, pEList);

  sqlite3ExprDelete(pParse->db, pSelectRowid);
  sqlite3ExprDelete(pParse->db, pInClause);
  sqlite3ExprDelete(pParse->db, pWhereRowid);
  return 0;
}
#endif /* defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY) */

/*
** Generate code for a DELETE FROM statement.
**







|







 







|


>

|

|
>

|

|
>
>
>
>
|

|
<
>




>




<

<
<
>
|
<
<







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172

173
174
175
176
177
178
179
180
181
182

183


184
185


186
187
188
189
190
191
192
**    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
** in order to generate code for DELETE FROM statements.
**
** $Id: delete.c,v 1.180 2008/10/10 13:35:58 shane Exp $
*/
#include "sqliteInt.h"

/*
** Look up every table that is named in pSrc.  If any table is not found,
** add an error message to pParse->zErrMsg and return NULL.  If all tables
** are found, return a pointer to the last table.
................................................................................
  if (!pLimit && !pOffset) return pWhere;

  /* Generate a select expression tree to enforce the limit/offset 
  ** term for the DELETE or UPDATE statement.  For example:
  **   DELETE FROM table_a WHERE col1=1 ORDER BY col2 LIMIT 1 OFFSET 1
  ** becomes:
  **   DELETE FROM table_a WHERE rowid IN ( 
  **     SELECT rowid FROM table_a WHERE col1=1 ORDER BY col2 LIMIT 1 OFFSET 1
  **   );
  */

  pSelectRowid = sqlite3Expr(pParse->db, TK_ROW, 0, 0, 0);
  if( pSelectRowid == 0 ) return 0;
  pEList = sqlite3ExprListAppend(pParse, 0, pSelectRowid, 0);
  if( pEList == 0 ) return 0;

  /* duplicate the FROM clause as it is needed by both the DELETE/UPDATE tree
  ** and the SELECT subtree. */
  pSelectSrc = sqlite3SrcListDup(pParse->db, pSrc);
  if( pSelectSrc == 0 ) {
    sqlite3ExprListDelete(pParse->db, pEList);
    return 0;
  }

  /* generate the SELECT expression tree. */
  pSelect = sqlite3SelectNew(pParse,pEList,pSelectSrc,pWhere,0,0,pOrderBy,0,pLimit,pOffset);
  if( pSelect == 0 ) return 0;


  pWhereRowid = sqlite3Expr(pParse->db, TK_ROW, 0, 0, 0);
  if( pWhereRowid == 0 ) goto limit_where_cleanup;
  pInClause = sqlite3PExpr(pParse, TK_IN, pWhereRowid, 0, 0);
  if( pInClause == 0 ) goto limit_where_cleanup;

  pInClause->pSelect = pSelect;
  sqlite3ExprSetHeight(pParse, pInClause);
  return pInClause;


  /* something went wrong. clean up anything allocated. */


limit_where_cleanup:
  sqlite3SelectDelete(pParse->db, pSelect);


  return 0;
}
#endif /* defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY) */

/*
** Generate code for a DELETE FROM statement.
**