]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Performance improvement to SQL function calls in the VDBE.
authordrh <drh@noemail.net>
Mon, 19 Aug 2013 23:18:12 +0000 (23:18 +0000)
committerdrh <drh@noemail.net>
Mon, 19 Aug 2013 23:18:12 +0000 (23:18 +0000)
FossilOrigin-Name: d2efea1682a7e708000c1f5d36370aaf1199b3be

manifest
manifest.uuid
src/vdbe.c
src/vdbeInt.h
src/vdbeapi.c

index 58a5caee727eee77e4dc314b6b085c44cfe67d3e..13d108d3d29a2ddf5f1e0190902201b73ff59896 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Additional\sperformance\simprovements\sin\ssqlite3BtreeNext()\sand\nsqlite3BtreePrevious().
-D 2013-08-19T22:22:41.690
+C Performance\simprovement\sto\sSQL\sfunction\scalls\sin\sthe\sVDBE.
+D 2013-08-19T23:18:12.597
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -277,10 +277,10 @@ F src/update.c 7f3fe64d8f3b44c44a1eac293f0f85f87c355b7a
 F src/utf.c 8d819e2e5104a430fc2005f018db14347c95a38f
 F src/util.c f566b5138099a2df8533b190d0dcc74b7dfbe0c9
 F src/vacuum.c d9c5759f4c5a438bb43c2086f72c5d2edabc36c8
-F src/vdbe.c 0fbe7a904a1187dc6c8a2dbe2f594f0ce8d01401
+F src/vdbe.c 54d28e7fbea2215998f8e12fcb0ddb15fadc5b14
 F src/vdbe.h 4f554b5627f26710c4c36d919110a3fc611ca5c4
-F src/vdbeInt.h e9b7c6b165a31a4715c5aa97223d20d265515231
-F src/vdbeapi.c 4d13580bd058b39623e8fcfc233b7df4b8191e8b
+F src/vdbeInt.h 6931139cefc2f01f8612b771a31d96d06b1a6860
+F src/vdbeapi.c a183f0daa22374427bd4cf3f18a6261aac141f5a
 F src/vdbeaux.c a6ea36a9dc714e1128a0173249a0532ddcab0489
 F src/vdbeblob.c 5dc79627775bd9a9b494dd956e26297946417d69
 F src/vdbemem.c 833005f1cbbf447289f1973dba2a0c2228c7b8ab
@@ -1106,7 +1106,7 @@ F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
 F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae
 F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac
-P af49707211ff7c7c4d30f4f457631ea8a9fa39eb
-R d86e9a19461f588d02ed145ef81cfebb
+P 6f99b54aedeb91e46d52f65504d02a9cc61c0062
+R a4ebd23f8bd1f91badaa0be999a387b9
 U drh
-Z 1181ebcd03ded8a6c716b64a93881e5c
+Z 07c571cc9e32147d1ee20914dbc33fe8
index 10a6d51396da32a09611ccfce11469234b9c4b39..cd5dd5dbfe4787df8e5d8ef72dfcc2264aea34b5 100644 (file)
@@ -1 +1 @@
-6f99b54aedeb91e46d52f65504d02a9cc61c0062
\ No newline at end of file
+d2efea1682a7e708000c1f5d36370aaf1199b3be
\ No newline at end of file
index 4bd26b377cc9c91ce8c4bf3c49a4fd3bfff2d6b7..716c7127fd36e8d74618422bd144fe9eb96b5072 100644 (file)
@@ -1449,7 +1449,7 @@ case OP_Function: {
   sqlite3VdbeMemMove(&ctx.s, pOut);
   MemSetTypeFlag(&ctx.s, MEM_Null);
 
-  ctx.isError = 0;
+  ctx.fErrorOrAux = 0;
   if( ctx.pFunc->flags & SQLITE_FUNC_NEEDCOLL ){
     assert( pOp>aOp );
     assert( pOp[-1].p4type==P4_COLLSEQ );
@@ -1460,11 +1460,6 @@ case OP_Function: {
   (*ctx.pFunc->xFunc)(&ctx, n, apVal); /* IMP: R-24505-23230 */
   lastRowid = db->lastRowid;
 
-  /* If any auxiliary data functions have been called by this user function,
-  ** immediately call the destructor for any non-static values.
-  */
-  sqlite3VdbeDeleteAuxData(p, pc, pOp->p1);
-
   if( db->mallocFailed ){
     /* Even though a malloc() has failed, the implementation of the
     ** user function may have called an sqlite3_result_XXX() function
@@ -1476,9 +1471,12 @@ case OP_Function: {
   }
 
   /* If the function returned an error, throw an exception */
-  if( ctx.isError ){
-    sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(&ctx.s));
-    rc = ctx.isError;
+  if( ctx.fErrorOrAux ){
+    if( ctx.isError ){
+      sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(&ctx.s));
+      rc = ctx.isError;
+    }
+    sqlite3VdbeDeleteAuxData(p, pc, pOp->p1);
   }
 
   /* Copy the result of the function into register P3 */
index 9ee82b4ea031a204b1c10774835b6f83b57012eb..1003d8465cecef501415d2b983870734c02269c0 100644 (file)
@@ -266,10 +266,11 @@ struct sqlite3_context {
   Mem s;                /* The return value is stored here */
   Mem *pMem;            /* Memory cell used to store aggregate context */
   CollSeq *pColl;       /* Collating sequence */
-  int isError;          /* Error code returned by the function. */
-  int skipFlag;         /* Skip skip accumulator loading if true */
-  int iOp;              /* Instruction number of OP_Function */
   Vdbe *pVdbe;          /* The VM that owns this context */
+  int iOp;              /* Instruction number of OP_Function */
+  int isError;          /* Error code returned by the function. */
+  u8 skipFlag;          /* Skip skip accumulator loading if true */
+  u8 fErrorOrAux;       /* isError!=0 or pVdbe->pAuxData modified */
 };
 
 /*
index 7c9db9beec44eff2ef731c6499558b239da44f0e..178129d34ebd8114160bc0b73456195e450c134a 100644 (file)
@@ -211,12 +211,14 @@ void sqlite3_result_double(sqlite3_context *pCtx, double rVal){
 void sqlite3_result_error(sqlite3_context *pCtx, const char *z, int n){
   assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
   pCtx->isError = SQLITE_ERROR;
+  pCtx->fErrorOrAux = 1;
   sqlite3VdbeMemSetStr(&pCtx->s, z, n, SQLITE_UTF8, SQLITE_TRANSIENT);
 }
 #ifndef SQLITE_OMIT_UTF16
 void sqlite3_result_error16(sqlite3_context *pCtx, const void *z, int n){
   assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
   pCtx->isError = SQLITE_ERROR;
+  pCtx->fErrorOrAux = 1;
   sqlite3VdbeMemSetStr(&pCtx->s, z, n, SQLITE_UTF16NATIVE, SQLITE_TRANSIENT);
 }
 #endif
@@ -280,6 +282,7 @@ void sqlite3_result_zeroblob(sqlite3_context *pCtx, int n){
 }
 void sqlite3_result_error_code(sqlite3_context *pCtx, int errCode){
   pCtx->isError = errCode;
+  pCtx->fErrorOrAux = 1;
   if( pCtx->s.flags & MEM_Null ){
     sqlite3VdbeMemSetStr(&pCtx->s, sqlite3ErrStr(errCode), -1, 
                          SQLITE_UTF8, SQLITE_STATIC);
@@ -290,6 +293,7 @@ void sqlite3_result_error_code(sqlite3_context *pCtx, int errCode){
 void sqlite3_result_error_toobig(sqlite3_context *pCtx){
   assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
   pCtx->isError = SQLITE_TOOBIG;
+  pCtx->fErrorOrAux = 1;
   sqlite3VdbeMemSetStr(&pCtx->s, "string or blob too big", -1, 
                        SQLITE_UTF8, SQLITE_STATIC);
 }
@@ -299,6 +303,7 @@ void sqlite3_result_error_nomem(sqlite3_context *pCtx){
   assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
   sqlite3VdbeMemSetNull(&pCtx->s);
   pCtx->isError = SQLITE_NOMEM;
+  pCtx->fErrorOrAux = 1;
   pCtx->s.db->mallocFailed = 1;
 }
 
@@ -621,6 +626,10 @@ void sqlite3_set_auxdata(
     pAuxData->iArg = iArg;
     pAuxData->pNext = pVdbe->pAuxData;
     pVdbe->pAuxData = pAuxData;
+    if( pCtx->fErrorOrAux==0 ){
+      pCtx->isError = 0;
+      pCtx->fErrorOrAux = 1;
+    }
   }else if( pAuxData->xDelete ){
     pAuxData->xDelete(pAuxData->pAux);
   }