/ Check-in [c0ce6319]
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

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

Overview
Comment:Handle transient malloc() failures in sqlite3CreateFunc(). (CVS 4371)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: c0ce63196458c81e0859fc8a38f2dd2145a580bc
User & Date: danielk1977 2007-09-03 11:04:22
Context
2007-09-03
11:51
Add a module-destructor to the echo module (test8.c) to improve code coverage. (CVS 4372) check-in: e3dd3651 user: danielk1977 tags: trunk
11:04
Handle transient malloc() failures in sqlite3CreateFunc(). (CVS 4371) check-in: c0ce6319 user: danielk1977 tags: trunk
07:31
Fixes to test code so that the test suite passes without SQLITE_MEMDEBUG defined. (CVS 4370) check-in: ed2a2e01 user: danielk1977 tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/func.c.

    12     12   ** This file contains the C functions that implement various SQL
    13     13   ** functions of SQLite.  
    14     14   **
    15     15   ** There is only one exported symbol in this file - the function
    16     16   ** sqliteRegisterBuildinFunctions() found at the bottom of the file.
    17     17   ** All other code has file scope.
    18     18   **
    19         -** $Id: func.c,v 1.173 2007/09/01 17:00:13 danielk1977 Exp $
           19  +** $Id: func.c,v 1.174 2007/09/03 11:04:22 danielk1977 Exp $
    20     20   */
    21     21   #include "sqliteInt.h"
    22     22   #include <ctype.h>
    23     23   #include <stdlib.h>
    24     24   #include <assert.h>
    25     25   #include "vdbeInt.h"
    26     26   
................................................................................
  1129   1129     for(i=0; i<nArg; i++){
  1130   1130       char const *z = (char*)sqlite3_value_text(argv[i]);
  1131   1131       if( z ){
  1132   1132         char *zAux = sqlite3_get_auxdata(pCtx, i);
  1133   1133         if( zAux ){
  1134   1134           zRet[i*2] = '1';
  1135   1135           if( strcmp(zAux, z) ){
  1136         -          free_test_auxdata((void *)zRet);
  1137   1136             sqlite3_result_error(pCtx, "Auxilary data corruption", -1);
  1138   1137             return;
  1139   1138           }
  1140         -      }else{
         1139  +      }else {
  1141   1140           zRet[i*2] = '0';
  1142         -        zAux = contextMalloc(pCtx, strlen(z)+1);
  1143         -        if( zAux ){
  1144         -          strcpy(zAux, z);
  1145         -          sqlite3_set_auxdata(pCtx, i, zAux, free_test_auxdata);
  1146         -        }
         1141  +      }
         1142  +
         1143  +      zAux = contextMalloc(pCtx, strlen(z)+1);
         1144  +      if( zAux ){
         1145  +        strcpy(zAux, z);
         1146  +        sqlite3_set_auxdata(pCtx, i, zAux, free_test_auxdata);
  1147   1147         }
  1148   1148         zRet[i*2+1] = ' ';
  1149   1149       }
  1150   1150     }
  1151   1151     sqlite3_result_text(pCtx, zRet, 2*nArg-1, free_test_auxdata);
  1152   1152   }
  1153   1153   #endif /* SQLITE_TEST */

Changes to src/main.c.

    10     10   **
    11     11   *************************************************************************
    12     12   ** Main file for the SQLite library.  The routines in this file
    13     13   ** implement the programmer interface to the library.  Routines in
    14     14   ** other files are for internal use by SQLite and should not be
    15     15   ** accessed by users of the library.
    16     16   **
    17         -** $Id: main.c,v 1.402 2007/09/01 06:51:28 danielk1977 Exp $
           17  +** $Id: main.c,v 1.403 2007/09/03 11:04:22 danielk1977 Exp $
    18     18   */
    19     19   #include "sqliteInt.h"
    20     20   #include <ctype.h>
    21     21   
    22     22   /*
    23     23   ** The version of the library
    24     24   */
................................................................................
   507    507         return SQLITE_BUSY;
   508    508       }else{
   509    509         sqlite3ExpirePreparedStatements(db);
   510    510       }
   511    511     }
   512    512   
   513    513     p = sqlite3FindFunction(db, zFunctionName, nName, nArg, enc, 1);
   514         -  if( p ){
   515         -    p->flags = 0;
   516         -    p->xFunc = xFunc;
   517         -    p->xStep = xStep;
   518         -    p->xFinalize = xFinal;
   519         -    p->pUserData = pUserData;
   520         -    p->nArg = nArg;
          514  +  assert(p || db->mallocFailed);
          515  +  if( !p ){
          516  +    return SQLITE_NOMEM;
   521    517     }
          518  +  p->flags = 0;
          519  +  p->xFunc = xFunc;
          520  +  p->xStep = xStep;
          521  +  p->xFinalize = xFinal;
          522  +  p->pUserData = pUserData;
          523  +  p->nArg = nArg;
   522    524     return SQLITE_OK;
   523    525   }
   524    526   
   525    527   /*
   526    528   ** Create new user functions.
   527    529   */
   528    530   int sqlite3_create_function(

Changes to src/test1.c.

     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   ** Code for testing all sorts of SQLite interfaces.  This code
    13     13   ** is not included in the SQLite library.  It is used for automated
    14     14   ** testing of the SQLite library.
    15     15   **
    16         -** $Id: test1.c,v 1.274 2007/09/01 11:04:26 danielk1977 Exp $
           16  +** $Id: test1.c,v 1.275 2007/09/03 11:04:22 danielk1977 Exp $
    17     17   */
    18     18   #include "sqliteInt.h"
    19     19   #include "tcl.h"
    20     20   #include <stdlib.h>
    21     21   #include <string.h>
    22     22   
    23     23   /*
................................................................................
  1007   1007       if( p->n==42 ){
  1008   1008         sqlite3_result_error(context, "x_count totals to 42", -1);
  1009   1009       }else{
  1010   1010         sqlite3_result_int(context, p ? p->n : 0);
  1011   1011       }
  1012   1012     }
  1013   1013   }
         1014  +
         1015  +static void legacyCountStep(
         1016  +  sqlite3_context *context,
         1017  +  int argc,
         1018  +  sqlite3_value **argv
         1019  +){
         1020  +  /* no-op */
         1021  +}
         1022  +static void legacyCountFinalize(sqlite3_context *context){
         1023  +  sqlite3_result_int(context, sqlite3_aggregate_count(context));
         1024  +}
  1014   1025   
  1015   1026   /*
  1016         -** Usage:  sqlite_test_create_aggregate DB
         1027  +** Usage:  sqlite3_create_aggregate DB
  1017   1028   **
  1018   1029   ** Call the sqlite3_create_function API on the given database in order
  1019         -** to create a function named "x_count".  This function does the same thing
  1020         -** as the "md5sum" function.
         1030  +** to create a function named "x_count".  This function is similar
         1031  +** to the built-in count() function, with a few special quirks
         1032  +** for testing the sqlite3_result_error() APIs.
  1021   1033   **
  1022   1034   ** The original motivation for this routine was to be able to call the
  1023   1035   ** sqlite3_create_aggregate function while a query is in progress in order
  1024   1036   ** to test the SQLITE_MISUSE detection logic.  See misuse.test.
  1025   1037   **
  1026   1038   ** This routine was later extended to test the use of sqlite3_result_error()
  1027   1039   ** within aggregate functions.
         1040  +**
         1041  +** Later: It is now also extended to register the aggregate function
         1042  +** "legacy_count()" with the supplied database handle. This is used
         1043  +** to test the deprecated sqlite3_aggregate_count() API.
  1028   1044   */
  1029   1045   static int test_create_aggregate(
  1030   1046     void *NotUsed,
  1031   1047     Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  1032   1048     int argc,              /* Number of arguments */
  1033   1049     char **argv            /* Text of each argument */
  1034   1050   ){
................................................................................
  1039   1055          " FILENAME\"", 0);
  1040   1056       return TCL_ERROR;
  1041   1057     }
  1042   1058     if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
  1043   1059     rc = sqlite3_create_function(db, "x_count", 0, SQLITE_UTF8, 0, 0,
  1044   1060         t1CountStep,t1CountFinalize);
  1045   1061     if( rc==SQLITE_OK ){
  1046         -    sqlite3_create_function(db, "x_count", 1, SQLITE_UTF8, 0, 0,
         1062  +    rc = sqlite3_create_function(db, "x_count", 1, SQLITE_UTF8, 0, 0,
  1047   1063           t1CountStep,t1CountFinalize);
         1064  +  }
         1065  +  if( rc==SQLITE_OK ){
         1066  +    rc = sqlite3_create_function(db, "legacy_count", 0, SQLITE_ANY, 0, 0,
         1067  +        legacyCountStep, legacyCountFinalize
         1068  +    );
  1048   1069     }
  1049   1070     if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
         1071  +  Tcl_SetResult(interp, (char *)t1ErrorName(rc), 0);
  1050   1072     return TCL_OK;
  1051   1073   }
  1052   1074   
  1053   1075   
  1054   1076   /*
  1055   1077   ** Usage:  printf TEXT
  1056   1078   **

Changes to test/func.test.

     7      7   #    May you find forgiveness for yourself and forgive others.
     8      8   #    May you share freely, never taking more than you give.
     9      9   #
    10     10   #***********************************************************************
    11     11   # This file implements regression tests for SQLite library.  The
    12     12   # focus of this file is testing built-in functions.
    13     13   #
    14         -# $Id: func.test,v 1.67 2007/05/15 18:35:21 drh Exp $
           14  +# $Id: func.test,v 1.68 2007/09/03 11:04:22 danielk1977 Exp $
    15     15   
    16     16   set testdir [file dirname $argv0]
    17     17   source $testdir/tester.tcl
    18     18   
    19     19   # Create a table to work with.
    20     20   #
    21     21   do_test func-0.0 {
................................................................................
   865    865   } {null}
   866    866   do_test func-22.21 {
   867    867     execsql {SELECT typeof(trim(NULL,'xyz'));}
   868    868   } {null}
   869    869   do_test func-22.22 {
   870    870     execsql {SELECT typeof(trim('hello',NULL));}
   871    871   } {null}
          872  +
          873  +# This is to test the deprecated sqlite3_aggregate_count() API.
          874  +#
          875  +do_test func-23.1 {
          876  +  sqlite3_create_aggregate db
          877  +  execsql {
          878  +    SELECT legacy_count() FROM t6;
          879  +  }
          880  +} {3}
   872    881   
   873    882   finish_test

Changes to test/malloc.test.

    12     12   # This file attempts to check the behavior of the SQLite library in 
    13     13   # an out-of-memory situation. When compiled with -DSQLITE_DEBUG=1, 
    14     14   # the SQLite library accepts a special command (sqlite3_memdebug_fail N C)
    15     15   # which causes the N-th malloc to fail.  This special feature is used
    16     16   # to see what happens in the library if a malloc were to really fail
    17     17   # due to an out-of-memory situation.
    18     18   #
    19         -# $Id: malloc.test,v 1.45 2007/08/29 12:31:29 danielk1977 Exp $
           19  +# $Id: malloc.test,v 1.46 2007/09/03 11:04:22 danielk1977 Exp $
    20     20   
    21     21   set testdir [file dirname $argv0]
    22     22   source $testdir/tester.tcl
    23     23   
    24     24   # Only run these tests if memory debugging is turned on.
    25     25   #
    26     26   ifcapable !memdebug {
................................................................................
   255    255     db2 close
   256    256   } 
   257    257   
   258    258   # This block tests malloc() failures that occur within calls to
   259    259   # sqlite3_create_function().
   260    260   do_malloc_test 11 -tclbody {
   261    261     set rc [sqlite3_create_function db]
          262  +  if {[string match $rc SQLITE_OK]} {
          263  +    set rc [sqlite3_create_aggregate db]
          264  +  }
   262    265     if {[string match $rc SQLITE_NOMEM]} {
   263    266       error "out of memory"
   264    267     }
   265    268   }
   266    269   
   267    270   do_malloc_test 12 -tclbody {
   268    271     set sql16 [encoding convertto unicode "SELECT * FROM sqlite_master"]

Changes to test/malloc5.test.

     8      8   #    May you share freely, never taking more than you give.
     9      9   #
    10     10   #***********************************************************************
    11     11   #
    12     12   # This file contains test cases focused on the two memory-management APIs, 
    13     13   # sqlite3_soft_heap_limit() and sqlite3_release_memory().
    14     14   #
    15         -# $Id: malloc5.test,v 1.14 2007/08/28 08:00:18 danielk1977 Exp $
           15  +# $Id: malloc5.test,v 1.15 2007/09/03 11:04:22 danielk1977 Exp $
    16     16   
    17     17   #---------------------------------------------------------------------------
    18     18   # NOTES ON EXPECTED BEHAVIOUR
    19     19   #
    20     20   #---------------------------------------------------------------------------
    21     21   
    22     22   
................................................................................
   294    294           SELECT randstr(50,50), randstr(75,75), randstr(100,100) FROM abc;
   295    295       INSERT INTO abc 
   296    296           SELECT randstr(50,50), randstr(75,75), randstr(100,100) FROM abc;
   297    297       COMMIT;
   298    298     } 
   299    299     copy_file test.db test2.db
   300    300     sqlite3 db2 test2.db
   301         -  list [expr [file size test.db]/1024] [expr [file size test2.db]/1024]
   302         -} {23 23}
          301  +  list \
          302  +    [expr ([file size test.db]/1024)>20] [expr ([file size test2.db]/1024)>20]
          303  +} {1 1}
   303    304   do_test malloc5-6.1.2 {
   304    305     list [execsql {PRAGMA cache_size}] [execsql {PRAGMA cache_size} db2]
   305    306   } {10 10}
   306    307   
   307    308   do_test malloc5-6.2.1 {
   308    309     execsql { SELECT * FROM abc } db2
   309    310     execsql {SELECT * FROM abc} db