SQLite

Check-in [8839850c44]
Login

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

Overview
Comment:Fix some memory leaks and crashes that could follow an OOM condition during WITH clause parsing.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | common-table-expr
Files: files | file ages | folders
SHA1: 8839850c44a8938883e493eacd752fa686e542df
User & Date: dan 2014-01-13 16:36:40.215
Context
2014-01-14
20:14
Add code to handle recursive CTEs. (check-in: a5c2a54a07 user: dan tags: common-table-expr)
2014-01-13
16:36
Fix some memory leaks and crashes that could follow an OOM condition during WITH clause parsing. (check-in: 8839850c44 user: dan tags: common-table-expr)
15:12
Add code to handle non-recursive CTEs in the same way as SQL views. (check-in: a26f399ba4 user: dan tags: common-table-expr)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/build.c.
4230
4231
4232
4233
4234
4235
4236

4237
4238
4239
4240
4241
4242

4243
4244
4245
4246
4247
4248
4249
  if( pWith ){
    int nByte = sizeof(*pWith) + (sizeof(pWith->a[1]) * pWith->nCte);
    pNew = sqlite3DbRealloc(db, pWith, nByte);
  }else{
    pNew = sqlite3DbMallocZero(db, sizeof(*pWith));
  }
  assert( zName!=0 || pNew==0 );


  if( pNew==0 ){
    sqlite3WithDelete(db, pWith);
    sqlite3ExprListDelete(db, pArglist);
    sqlite3SelectDelete(db, pQuery);
    sqlite3DbFree(db, zName);

  }else{
    pNew->a[pNew->nCte].pSelect = pQuery;
    pNew->a[pNew->nCte].pCols = pArglist;
    pNew->a[pNew->nCte].zName = zName;
    pNew->nCte++;
  }








>


<



>







4230
4231
4232
4233
4234
4235
4236
4237
4238
4239

4240
4241
4242
4243
4244
4245
4246
4247
4248
4249
4250
  if( pWith ){
    int nByte = sizeof(*pWith) + (sizeof(pWith->a[1]) * pWith->nCte);
    pNew = sqlite3DbRealloc(db, pWith, nByte);
  }else{
    pNew = sqlite3DbMallocZero(db, sizeof(*pWith));
  }
  assert( zName!=0 || pNew==0 );
  assert( db->mallocFailed==0 || pNew==0 );

  if( pNew==0 ){

    sqlite3ExprListDelete(db, pArglist);
    sqlite3SelectDelete(db, pQuery);
    sqlite3DbFree(db, zName);
    pNew = pWith;
  }else{
    pNew->a[pNew->nCte].pSelect = pQuery;
    pNew->a[pNew->nCte].pCols = pArglist;
    pNew->a[pNew->nCte].zName = zName;
    pNew->nCte++;
  }

Changes to src/parse.y.
408
409
410
411
412
413
414
415







416
417
418
419
420
421
422
%type select {Select*}
%destructor select {sqlite3SelectDelete(pParse->db, $$);}
%type selectnowith {Select*}
%destructor selectnowith {sqlite3SelectDelete(pParse->db, $$);}
%type oneselect {Select*}
%destructor oneselect {sqlite3SelectDelete(pParse->db, $$);}

select(A) ::= with(W) selectnowith(X). { if( X ) X->pWith = W; A = X; }








selectnowith(A) ::= oneselect(X).                      {A = X;}
%ifndef SQLITE_OMIT_COMPOUND_SELECT
selectnowith(A) ::= selectnowith(X) multiselect_op(Y) oneselect(Z).  {
  if( Z ){
    Z->op = (u8)Y;
    Z->pPrior = X;







|
>
>
>
>
>
>
>







408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
%type select {Select*}
%destructor select {sqlite3SelectDelete(pParse->db, $$);}
%type selectnowith {Select*}
%destructor selectnowith {sqlite3SelectDelete(pParse->db, $$);}
%type oneselect {Select*}
%destructor oneselect {sqlite3SelectDelete(pParse->db, $$);}

select(A) ::= with(W) selectnowith(X). { 
  if( X ){
    X->pWith = W; 
  }else{
    sqlite3WithDelete(pParse->db, W);
  }
  A = X; 
}

selectnowith(A) ::= oneselect(X).                      {A = X;}
%ifndef SQLITE_OMIT_COMPOUND_SELECT
selectnowith(A) ::= selectnowith(X) multiselect_op(Y) oneselect(Z).  {
  if( Z ){
    Z->op = (u8)Y;
    Z->pPrior = X;
Changes to test/withM.test.
18
19
20
21
22
23
24
25
26
27
28
29
30
31
















32
33
34
35
36
37
38
set ::testprefix withM

do_execsql_test 1.0 {
  CREATE TABLE t1(x INTEGER, y INTEGER);
  INSERT INTO t1 VALUES(123, 456);
}

do_faultsim_test withM-1 -prep {
  sqlite3 db test.db
} -body {
  execsql { 
    WITH tmp AS ( SELECT * FROM t1 )
    SELECT * FROM tmp;
  }
















} -test {
  faultsim_test_result {0 {123 456}}
  db close
}

finish_test








|






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







18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
set ::testprefix withM

do_execsql_test 1.0 {
  CREATE TABLE t1(x INTEGER, y INTEGER);
  INSERT INTO t1 VALUES(123, 456);
}

do_faultsim_test withM-1.1 -prep {
  sqlite3 db test.db
} -body {
  execsql { 
    WITH tmp AS ( SELECT * FROM t1 )
    SELECT * FROM tmp;
  }
} -test {
  faultsim_test_result {0 {123 456}}
  db close
}

do_faultsim_test withM-1.2 -prep {
  sqlite3 db test.db
} -body {
  execsql { 
    WITH w1 AS ( SELECT * FROM t1 ),
         w2 AS ( 
           WITH w3 AS ( SELECT * FROM w1 )
           SELECT * FROM w3
         )
    SELECT * FROM w2;
  }
} -test {
  faultsim_test_result {0 {123 456}}
  db close
}

finish_test