/ Check-in [ff530675]
Login

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

Overview
Comment:Negative N values in sqlite3_get_auxdata() and sqlite3_set_auxdata() can be used to access an auxiliary data cache over all functions in a single prepared statement.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | auxdata-cache
Files: files | file ages | folders
SHA3-256: ff5306752e83e760255a10f20168c0f090929a4fee2a5f720dfab36f0ee72fae
User & Date: drh 2017-05-11 15:20:18
Context
2017-05-11
16:49
Cache the JSON parse used by json_extract(). Closed-Leaf check-in: 44ca6c2c user: drh tags: auxdata-cache
15:20
Negative N values in sqlite3_get_auxdata() and sqlite3_set_auxdata() can be used to access an auxiliary data cache over all functions in a single prepared statement. check-in: ff530675 user: drh tags: auxdata-cache
13:43
New requirements marks and documentation for the authorizer. check-in: 3980ea09 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/sqlite.h.in.

  4759   4759   ** of where this might be useful is in a regular-expression matching
  4760   4760   ** function. The compiled version of the regular expression can be stored as
  4761   4761   ** metadata associated with the pattern string.  
  4762   4762   ** Then as long as the pattern string remains the same,
  4763   4763   ** the compiled regular expression can be reused on multiple
  4764   4764   ** invocations of the same function.
  4765   4765   **
  4766         -** ^The sqlite3_get_auxdata() interface returns a pointer to the metadata
  4767         -** associated by the sqlite3_set_auxdata() function with the Nth argument
  4768         -** value to the application-defined function. ^If there is no metadata
  4769         -** associated with the function argument, this sqlite3_get_auxdata() interface
         4766  +** ^The sqlite3_get_auxdata(C,N) interface returns a pointer to the metadata
         4767  +** associated by the sqlite3_set_auxdata(C,N,P,X) function with the Nth argument
         4768  +** value to the application-defined function.  ^N is zero for the left-most
         4769  +** function argument.  ^If there is no metadata
         4770  +** associated with the function argument, the sqlite3_get_auxdata(C,N) interface
  4770   4771   ** returns a NULL pointer.
  4771   4772   **
  4772   4773   ** ^The sqlite3_set_auxdata(C,N,P,X) interface saves P as metadata for the N-th
  4773   4774   ** argument of the application-defined function.  ^Subsequent
  4774   4775   ** calls to sqlite3_get_auxdata(C,N) return P from the most recent
  4775   4776   ** sqlite3_set_auxdata(C,N,P,X) call if the metadata is still valid or
  4776   4777   ** NULL if the metadata has been discarded.
................................................................................
  4792   4793   ** should be called near the end of the function implementation and the
  4793   4794   ** function implementation should not make any use of P after
  4794   4795   ** sqlite3_set_auxdata() has been called.
  4795   4796   **
  4796   4797   ** ^(In practice, metadata is preserved between function calls for
  4797   4798   ** function parameters that are compile-time constants, including literal
  4798   4799   ** values and [parameters] and expressions composed from the same.)^
         4800  +**
         4801  +** The value of the N parameter to these interfaces should be non-negative.
         4802  +** Future enhancements may make use of negative N values to define new
         4803  +** kinds of function caching behavior.
  4799   4804   **
  4800   4805   ** These routines must be called from the same thread in which
  4801   4806   ** the SQL function is running.
  4802   4807   */
  4803   4808   void *sqlite3_get_auxdata(sqlite3_context*, int N);
  4804   4809   void sqlite3_set_auxdata(sqlite3_context*, int N, void*, void (*)(void*));
  4805   4810   

Changes to src/vdbeapi.c.

   800    800       return (void*)p->pMem->z;
   801    801     }
   802    802   }
   803    803   
   804    804   /*
   805    805   ** Return the auxiliary data pointer, if any, for the iArg'th argument to
   806    806   ** the user-function defined by pCtx.
          807  +**
          808  +** The left-most argument is 0.
          809  +**
          810  +** Undocumented behavior:  If iArg is negative then access a cache of
          811  +** auxiliary data pointers that is available to all functions within a
          812  +** single prepared statement.  The iArg values must match.
   807    813   */
   808    814   void *sqlite3_get_auxdata(sqlite3_context *pCtx, int iArg){
   809    815     AuxData *pAuxData;
   810    816   
   811    817     assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
   812    818   #if SQLITE_ENABLE_STAT3_OR_STAT4
   813    819     if( pCtx->pVdbe==0 ) return 0;
   814    820   #else
   815    821     assert( pCtx->pVdbe!=0 );
   816    822   #endif
   817    823     for(pAuxData=pCtx->pVdbe->pAuxData; pAuxData; pAuxData=pAuxData->pNextAux){
   818         -    if( pAuxData->iAuxOp==pCtx->iOp && pAuxData->iAuxArg==iArg ){
          824  +    if(  pAuxData->iAuxArg==iArg && (pAuxData->iAuxOp==pCtx->iOp || iArg<0) ){
   819    825         return pAuxData->pAux;
   820    826       }
   821    827     }
   822    828     return 0;
   823    829   }
   824    830   
   825    831   /*
   826    832   ** Set the auxiliary data pointer and delete function, for the iArg'th
   827    833   ** argument to the user-function defined by pCtx. Any previous value is
   828    834   ** deleted by calling the delete function specified when it was set.
          835  +**
          836  +** The left-most argument is 0.
          837  +**
          838  +** Undocumented behavior:  If iArg is negative then make the data available
          839  +** to all functions within the current prepared statement using iArg as an
          840  +** access code.
   829    841   */
   830    842   void sqlite3_set_auxdata(
   831    843     sqlite3_context *pCtx, 
   832    844     int iArg, 
   833    845     void *pAux, 
   834    846     void (*xDelete)(void*)
   835    847   ){
   836    848     AuxData *pAuxData;
   837    849     Vdbe *pVdbe = pCtx->pVdbe;
   838    850   
   839    851     assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
   840         -  if( iArg<0 ) goto failed;
   841    852   #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
   842    853     if( pVdbe==0 ) goto failed;
   843    854   #else
   844    855     assert( pVdbe!=0 );
   845    856   #endif
   846    857   
   847    858     for(pAuxData=pVdbe->pAuxData; pAuxData; pAuxData=pAuxData->pNextAux){
   848         -    if( pAuxData->iAuxOp==pCtx->iOp && pAuxData->iAuxArg==iArg ) break;
          859  +    if( pAuxData->iAuxArg==iArg && (pAuxData->iAuxOp==pCtx->iOp || iArg<0) ){
          860  +      break;
          861  +    }
   849    862     }
   850    863     if( pAuxData==0 ){
   851    864       pAuxData = sqlite3DbMallocZero(pVdbe->db, sizeof(AuxData));
   852    865       if( !pAuxData ) goto failed;
   853    866       pAuxData->iAuxOp = pCtx->iOp;
   854    867       pAuxData->iAuxArg = iArg;
   855    868       pAuxData->pNextAux = pVdbe->pAuxData;

Changes to src/vdbeaux.c.

  2964   2964   **    * the corresponding bit in argument mask is clear (where the first
  2965   2965   **      function parameter corresponds to bit 0 etc.).
  2966   2966   */
  2967   2967   void sqlite3VdbeDeleteAuxData(sqlite3 *db, AuxData **pp, int iOp, int mask){
  2968   2968     while( *pp ){
  2969   2969       AuxData *pAux = *pp;
  2970   2970       if( (iOp<0)
  2971         -     || (pAux->iAuxOp==iOp 
         2971  +     || (pAux->iAuxOp==iOp
         2972  +          && pAux->iAuxArg>=0
  2972   2973             && (pAux->iAuxArg>31 || !(mask & MASKBIT32(pAux->iAuxArg))))
  2973   2974       ){
  2974   2975         testcase( pAux->iAuxArg==31 );
  2975   2976         if( pAux->xDeleteAux ){
  2976   2977           pAux->xDeleteAux(pAux->pAux);
  2977   2978         }
  2978   2979         *pp = pAux->pNextAux;