/ Check-in [a5d09dfa]
Login

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

Overview
Comment:Add the sqlite3_vtab_nochange() interface. Test cases are in TH3.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: a5d09dfaa337fa51d6e702c6aefe58824ab1e7d221c6e79166e2c6f9c7ab1501
User & Date: drh 2018-01-11 18:15:40
Context
2018-01-12
12:02
Add a test to ensure that the sqlite3changeset_apply() function ignores tables that do not have the expected primary keys. check-in: bf2daf06 user: dan tags: trunk
00:30
Enable the one-pass optimization for DELETE and UPDATE on RTree. This is parked in a branch because is seems to make no measureable performance difference. Leaf check-in: 8b8314cb user: drh tags: rtree-one-pass
2018-01-11
18:15
Add the sqlite3_vtab_nochange() interface. Test cases are in TH3. check-in: a5d09dfa user: drh tags: trunk
17:33
Change zipfile to be a WITHOUT ROWID virtual table and table-valued function. check-in: 931201f6 user: dan tags: trunk
17:04
Add the sqlite3_vtab_nochange() method which virtual table implementations can use to optimize UPDATEs. Closed-Leaf check-in: d444b1ff user: drh tags: sqlite3_vtab_nochange
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/sqlite.h.in.

  8293   8293   ** value returned is one of [SQLITE_ROLLBACK], [SQLITE_IGNORE], [SQLITE_FAIL],
  8294   8294   ** [SQLITE_ABORT], or [SQLITE_REPLACE], according to the [ON CONFLICT] mode
  8295   8295   ** of the SQL statement that triggered the call to the [xUpdate] method of the
  8296   8296   ** [virtual table].
  8297   8297   */
  8298   8298   int sqlite3_vtab_on_conflict(sqlite3 *);
  8299   8299   
         8300  +/*
         8301  +** CAPI3REF: Determine If Virtual Table Column Access Is For UPDATE
         8302  +**
         8303  +** If the sqlite3_vtab_nochange(X) routine is called within the [xColumn]
         8304  +** method of a [virtual table], then it returns true if and only if the
         8305  +** column is being fetched as part of an UPDATE operation during which the
         8306  +** column value will not change.  Applications might use this to substitute
         8307  +** a lighter-weight value to return that the corresponding [xUpdate] method
         8308  +** understands as a "no-change" value.
         8309  +*/
         8310  +int sqlite3_vtab_nochange(sqlite3_context*);
         8311  +
  8300   8312   /*
  8301   8313   ** CAPI3REF: Determine The Collation For a Virtual Table Constraint
  8302   8314   **
  8303   8315   ** This function may only be called from within a call to the [xBestIndex]
  8304   8316   ** method of a [virtual table]. 
  8305   8317   **
  8306   8318   ** The first argument must be the sqlite3_index_info object that is the

Changes to src/update.c.

   823    823     if( pWInfo==0 ) return;
   824    824   
   825    825     /* Populate the argument registers. */
   826    826     for(i=0; i<pTab->nCol; i++){
   827    827       if( aXRef[i]>=0 ){
   828    828         sqlite3ExprCode(pParse, pChanges->a[aXRef[i]].pExpr, regArg+2+i);
   829    829       }else{
   830         -      sqlite3VdbeAddOp3(v, OP_VColumn, iCsr, i, regArg+2+i);
          830  +      sqlite3VdbeAddOp4Int(v, OP_VColumn, iCsr, i, regArg+2+i, 1);
   831    831       }
   832    832     }
   833    833     if( HasRowid(pTab) ){
   834    834       sqlite3VdbeAddOp2(v, OP_Rowid, iCsr, regArg);
   835    835       if( pRowid ){
   836    836         sqlite3ExprCode(pParse, pRowid, regArg+1);
   837    837       }else{

Changes to src/vdbe.c.

  6689   6689     VdbeBranchTaken(res!=0,2);
  6690   6690     if( res ) goto jump_to_p2;
  6691   6691     break;
  6692   6692   }
  6693   6693   #endif /* SQLITE_OMIT_VIRTUALTABLE */
  6694   6694   
  6695   6695   #ifndef SQLITE_OMIT_VIRTUALTABLE
  6696         -/* Opcode: VColumn P1 P2 P3 * *
         6696  +/* Opcode: VColumn P1 P2 P3 P4 *
  6697   6697   ** Synopsis: r[P3]=vcolumn(P2)
  6698   6698   **
  6699         -** Store the value of the P2-th column of
  6700         -** the row of the virtual-table that the 
  6701         -** P1 cursor is pointing to into register P3.
         6699  +** Store in register P3 the value of the P2-th column of
         6700  +** the current row of the virtual-table of cursor P1.
         6701  +**
         6702  +** If the VColumn opcode is being used to fetch the value of
         6703  +** an unchanging column during an UPDATE operation, then the P4
         6704  +** value is 1.  Otherwise, P4 is 0.  The P4 value is returned
         6705  +** by sqlite3_vtab_nochange() routine can can be used
         6706  +** by virtual table implementations to return special "no-change"
         6707  +** marks which can be more efficient, depending on the virtual table.
  6702   6708   */
  6703   6709   case OP_VColumn: {
  6704   6710     sqlite3_vtab *pVtab;
  6705   6711     const sqlite3_module *pModule;
  6706   6712     Mem *pDest;
  6707   6713     sqlite3_context sContext;
  6708   6714   
................................................................................
  6716   6722       break;
  6717   6723     }
  6718   6724     pVtab = pCur->uc.pVCur->pVtab;
  6719   6725     pModule = pVtab->pModule;
  6720   6726     assert( pModule->xColumn );
  6721   6727     memset(&sContext, 0, sizeof(sContext));
  6722   6728     sContext.pOut = pDest;
         6729  +  sContext.bVtabNoChng = pOp->p4.i!=0;
  6723   6730     MemSetTypeFlag(pDest, MEM_Null);
  6724   6731     rc = pModule->xColumn(pCur->uc.pVCur, &sContext, pOp->p2);
  6725   6732     sqlite3VtabImportErrmsg(p, pVtab);
  6726   6733     if( sContext.isError ){
  6727   6734       rc = sContext.isError;
  6728   6735     }
  6729   6736     sqlite3VdbeChangeEncoding(pDest, encoding);

Changes to src/vdbeInt.h.

   314    314     FuncDef *pFunc;         /* Pointer to function information */
   315    315     Mem *pMem;              /* Memory cell used to store aggregate context */
   316    316     Vdbe *pVdbe;            /* The VM that owns this context */
   317    317     int iOp;                /* Instruction number of OP_Function */
   318    318     int isError;            /* Error code returned by the function. */
   319    319     u8 skipFlag;            /* Skip accumulator loading if true */
   320    320     u8 fErrorOrAux;         /* isError!=0 or pVdbe->pAuxData modified */
          321  +  u8 bVtabNoChng;         /* Fetching an unchanging column in a vtab UPDATE */
   321    322     u8 argc;                /* Number of arguments */
   322    323     sqlite3_value *argv[1]; /* Argument set */
   323    324   };
   324    325   
   325    326   /* A bitfield type for use inside of structures.  Always follow with :N where
   326    327   ** N is the number of bits.
   327    328   */

Changes to src/vdbeapi.c.

   740    740   ** sqlite3_create_function16() routines that originally registered the
   741    741   ** application defined function.
   742    742   */
   743    743   sqlite3 *sqlite3_context_db_handle(sqlite3_context *p){
   744    744     assert( p && p->pOut );
   745    745     return p->pOut->db;
   746    746   }
          747  +
          748  +/*
          749  +** If this routine is invoked from within an xColumn method of a virtual
          750  +** table, then it returns true if and only if the the call is during an
          751  +** UPDATE operation and the value of the column will not be modified
          752  +** by the UPDATE.
          753  +**
          754  +** If this routine is called from any context other than within the
          755  +** xColumn method of a virtual table, then the return value is meaningless
          756  +** and arbitrary.
          757  +**
          758  +** Virtual table implements might use this routine to optimize their
          759  +** performance by substituting a NULL result, or some other light-weight
          760  +** value, as a signal to the xUpdate routine that the column is unchanged.
          761  +*/
          762  +int sqlite3_vtab_nochange(sqlite3_context *p){
          763  +  assert( p );
          764  +  return p->bVtabNoChng;
          765  +}
   747    766   
   748    767   /*
   749    768   ** Return the current time for a statement.  If the current time
   750    769   ** is requested more than once within the same run of a single prepared
   751    770   ** statement, the exact same time is returned for each invocation regardless
   752    771   ** of the amount of time that elapses between invocations.  In other words,
   753    772   ** the time returned is always the time of the first call.