/ Check-in [c6445b9f]
Login

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

Overview
Comment:Add the sqlite3_result_zeroblob64() API. Use it in the SQL zeroblob() function.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: c6445b9fb4d7d1a8479436d7d183bad754a01615
User & Date: dan 2015-07-24 16:24:37
Context
2015-07-24
17:14
Fix compiler warnings. Get the new sqlite3_result_zeroblob64() working on loadable extensions. check-in: f8991e6f user: drh tags: trunk
16:24
Add the sqlite3_result_zeroblob64() API. Use it in the SQL zeroblob() function. check-in: c6445b9f user: dan tags: trunk
15:49
More robust handling of zeroblob() with oversized arguments. Fix fuzzcheck so that it can be run with limited heap memory. check-in: 4e3e516a user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/func.c.

  1118   1118   */
  1119   1119   static void zeroblobFunc(
  1120   1120     sqlite3_context *context,
  1121   1121     int argc,
  1122   1122     sqlite3_value **argv
  1123   1123   ){
  1124   1124     i64 n;
         1125  +  int rc;
  1125   1126     sqlite3 *db = sqlite3_context_db_handle(context);
  1126   1127     assert( argc==1 );
  1127   1128     UNUSED_PARAMETER(argc);
  1128   1129     n = sqlite3_value_int64(argv[0]);
  1129   1130     testcase( n==db->aLimit[SQLITE_LIMIT_LENGTH] );
  1130   1131     testcase( n==db->aLimit[SQLITE_LIMIT_LENGTH]+1 );
  1131         -  if( n>db->aLimit[SQLITE_LIMIT_LENGTH] ){
  1132         -    sqlite3_result_error_toobig(context);
  1133         -  }else{
  1134         -    if( n<0 ) n = 0;
  1135         -    sqlite3_result_zeroblob(context, (int)n); /* IMP: R-00293-64994 */
         1132  +  if( n<0 ) n = 0;
         1133  +  rc = sqlite3_result_zeroblob64(context, n); /* IMP: R-00293-64994 */
         1134  +  if( rc ){
         1135  +    sqlite3_result_error_code(context, rc);
  1136   1136     }
  1137   1137   }
  1138   1138   
  1139   1139   /*
  1140   1140   ** The replace() function.  Three arguments are all strings: call
  1141   1141   ** them A, B, and C. The result is also a string which is derived
  1142   1142   ** from A by replacing every occurrence of B with C.  The match

Changes to src/sqlite.h.in.

  4530   4530   ** Refer to the [SQL parameter] documentation for additional information.
  4531   4531   **
  4532   4532   ** ^The sqlite3_result_blob() interface sets the result from
  4533   4533   ** an application-defined function to be the BLOB whose content is pointed
  4534   4534   ** to by the second parameter and which is N bytes long where N is the
  4535   4535   ** third parameter.
  4536   4536   **
  4537         -** ^The sqlite3_result_zeroblob() interfaces set the result of
  4538         -** the application-defined function to be a BLOB containing all zero
         4537  +** ^The sqlite3_result_zeroblob() and zeroblob64() interfaces set the result 
         4538  +** of the application-defined function to be a BLOB containing all zero
  4539   4539   ** bytes and N bytes in size, where N is the value of the 2nd parameter.
  4540   4540   **
  4541   4541   ** ^The sqlite3_result_double() interface sets the result from
  4542   4542   ** an application-defined function to be a floating point value specified
  4543   4543   ** by its 2nd argument.
  4544   4544   **
  4545   4545   ** ^The sqlite3_result_error() and sqlite3_result_error16() functions
................................................................................
  4647   4647   void sqlite3_result_text64(sqlite3_context*, const char*,sqlite3_uint64,
  4648   4648                              void(*)(void*), unsigned char encoding);
  4649   4649   void sqlite3_result_text16(sqlite3_context*, const void*, int, void(*)(void*));
  4650   4650   void sqlite3_result_text16le(sqlite3_context*, const void*, int,void(*)(void*));
  4651   4651   void sqlite3_result_text16be(sqlite3_context*, const void*, int,void(*)(void*));
  4652   4652   void sqlite3_result_value(sqlite3_context*, sqlite3_value*);
  4653   4653   void sqlite3_result_zeroblob(sqlite3_context*, int n);
         4654  +int sqlite3_result_zeroblob64(sqlite3_context*, sqlite3_uint64 n);
  4654   4655   
  4655   4656   /*
  4656   4657   ** CAPI3REF: Define New Collating Sequences
  4657   4658   ** METHOD: sqlite3
  4658   4659   **
  4659   4660   ** ^These functions add, remove, or modify a [collation] associated
  4660   4661   ** with the [database connection] specified as the first argument.

Changes to src/sqlite3ext.h.

   266    266                           void(*)(void*));
   267    267     void (*result_text64)(sqlite3_context*,const char*,sqlite3_uint64,
   268    268                            void(*)(void*), unsigned char);
   269    269     int (*strglob)(const char*,const char*);
   270    270     /* Version 3.8.11 and later */
   271    271     sqlite3_value *(*value_dup)(const sqlite3_value*);
   272    272     void (*value_free)(sqlite3_value*);
          273  +  int (*result_zeroblob64)(sqlite3_context*,sqlite3_uint64);
   273    274   };
   274    275   
   275    276   /*
   276    277   ** The following macros redefine the API routines so that they are
   277    278   ** redirected through the global sqlite3_api structure.
   278    279   **
   279    280   ** This header file is also used by the loadext.c source file
................................................................................
   499    500   #define sqlite3_reset_auto_extension   sqlite3_api->reset_auto_extension
   500    501   #define sqlite3_result_blob64          sqlite3_api->result_blob64
   501    502   #define sqlite3_result_text64          sqlite3_api->result_text64
   502    503   #define sqlite3_strglob                sqlite3_api->strglob
   503    504   /* Version 3.8.11 and later */
   504    505   #define sqlite3_value_dup              sqlite3_api->value_dup
   505    506   #define sqlite3_value_free             sqlite3_api->value_free
          507  +#define sqlite3_result_zeroblob64      sqlite3_api->result_zeroblob64
   506    508   #endif /* SQLITE_CORE */
   507    509   
   508    510   #ifndef SQLITE_CORE
   509    511     /* This case when the file really is being compiled as a loadable 
   510    512     ** extension */
   511    513   # define SQLITE_EXTENSION_INIT1     const sqlite3_api_routines *sqlite3_api=0;
   512    514   # define SQLITE_EXTENSION_INIT2(v)  sqlite3_api=v;

Changes to src/vdbeapi.c.

   158    158   /**************************** sqlite3_value_  *******************************
   159    159   ** The following routines extract information from a Mem or sqlite3_value
   160    160   ** structure.
   161    161   */
   162    162   const void *sqlite3_value_blob(sqlite3_value *pVal){
   163    163     Mem *p = (Mem*)pVal;
   164    164     if( p->flags & (MEM_Blob|MEM_Str) ){
   165         -    if( sqlite3VdbeMemExpandBlob(p)!=SQLITE_OK ) return 0;
          165  +    if( sqlite3VdbeMemExpandBlob(p)!=SQLITE_OK ){
          166  +      assert( p->flags==MEM_Null && p->z==0 );
          167  +      return 0;
          168  +    }
   166    169       p->flags |= MEM_Blob;
   167    170       return p->n ? p->z : 0;
   168    171     }else{
   169    172       return sqlite3_value_text(pVal);
   170    173     }
   171    174   }
   172    175   int sqlite3_value_bytes(sqlite3_value *pVal){
................................................................................
   419    422   void sqlite3_result_value(sqlite3_context *pCtx, sqlite3_value *pValue){
   420    423     assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
   421    424     sqlite3VdbeMemCopy(pCtx->pOut, pValue);
   422    425   }
   423    426   void sqlite3_result_zeroblob(sqlite3_context *pCtx, int n){
   424    427     assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
   425    428     sqlite3VdbeMemSetZeroBlob(pCtx->pOut, n);
          429  +}
          430  +int sqlite3_result_zeroblob64(sqlite3_context *pCtx, u64 n){
          431  +  Mem *pOut = pCtx->pOut;
          432  +  assert( sqlite3_mutex_held(pOut->db->mutex) );
          433  +  if( n>pOut->db->aLimit[SQLITE_LIMIT_LENGTH] ){
          434  +    return SQLITE_TOOBIG;
          435  +  }
          436  +  sqlite3VdbeMemSetZeroBlob(pCtx->pOut, (int)n);
          437  +  return SQLITE_OK;
   426    438   }
   427    439   void sqlite3_result_error_code(sqlite3_context *pCtx, int errCode){
   428    440     pCtx->isError = errCode;
   429    441     pCtx->fErrorOrAux = 1;
   430    442   #ifdef SQLITE_DEBUG
   431    443     if( pCtx->pVdbe ) pCtx->pVdbe->rcApp = errCode;
   432    444   #endif

Changes to test/zeroblob.test.

    13     13   # including the sqlite3_bind_zeroblob(), sqlite3_result_zeroblob(),
    14     14   # and the built-in zeroblob() SQL function.
    15     15   #
    16     16   # $Id: zeroblob.test,v 1.14 2009/07/14 02:33:02 drh Exp $
    17     17   
    18     18   set testdir [file dirname $argv0]
    19     19   source $testdir/tester.tcl
           20  +set testprefix zeroblob
    20     21   
    21     22   ifcapable !incrblob {
    22     23     finish_test
    23     24     return
    24     25   }
    25     26   
    26     27   test_set_config_pagecache 0 0
................................................................................
   263    264   do_test zeroblob-10.1 {
   264    265     db eval {
   265    266       CREATE TABLE t10(a,b,c);
   266    267     }
   267    268     catchsql {INSERT INTO t10 VALUES(zeroblob(1e9),zeroblob(1e9),zeroblob(1e9))}
   268    269   } {1 {string or blob too big}}
   269    270   
          271  +#-------------------------------------------------------------------------
          272  +## Test the zeroblob() function on its own with negative or oversized 
          273  +## arguments.
          274  +##
          275  +do_execsql_test 11.0 { 
          276  +  SELECT length(zeroblob(-1444444444444444));
          277  +} {0}
          278  +do_catchsql_test 11.1 { 
          279  +  SELECT zeroblob(1025 * 1024 * 1024);
          280  +} {1 {string or blob too big}}
          281  +do_catchsql_test 11.2 { 
          282  +  SELECT quote(zeroblob(1025 * 1024 * 1024));
          283  +} {1 {string or blob too big}}
          284  +do_catchsql_test 11.3 { 
          285  +  SELECT quote(zeroblob(-1444444444444444));
          286  +} {0 X''}
          287  +do_catchsql_test 11.4 {
          288  +  SELECT quote(test_zeroblob(-1));
          289  +} {0 X''}
   270    290   
   271    291   test_restore_config_pagecache
   272    292   finish_test