]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Attempt to transform OP_Column to make use of eCurState instead of the other simplify-cursor-state
authordrh <>
Fri, 25 Feb 2022 18:15:09 +0000 (18:15 +0000)
committerdrh <>
Fri, 25 Feb 2022 18:15:09 +0000 (18:15 +0000)
miscellaneous flags.

FossilOrigin-Name: 09a47f32a44bfe8630157f09518e6467fac281bc70cf229c88efccac2028ea70

manifest
manifest.uuid
src/vdbe.c

index d50665573842cd52430ac4a5e22c936e26c45b37..87c0e550b04520655d51cdede29bb4ceeea40316 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Do\snot\sdo\sa\sdeferred\sseek\son\sa\scursor\sthat\sis\smarked\snullRow.
-D 2022-02-25T16:21:00.933
+C Attempt\sto\stransform\sOP_Column\sto\smake\suse\sof\seCurState\sinstead\sof\sthe\sother\nmiscellaneous\sflags.
+D 2022-02-25T18:15:09.709
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -624,7 +624,7 @@ F src/upsert.c 8789047a8f0a601ea42fa0256d1ba3190c13746b6ba940fe2d25643a7e991937
 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0
 F src/util.c 602fe229f32a96ceccae4f40824129669582096f7c355f53dbac156c9fecef23
 F src/vacuum.c 6c38ddc52f0619865c91dae9c441d4d48bf3040d7dc1bc5b22da1e45547ed0b3
-F src/vdbe.c 588de992e0efc2cc167748888b90fc0910e93b3030a16b5685f0acd7cb5f1cb3
+F src/vdbe.c 7778e0f54e7ffe99edf44133e346915cb1ababb696186e6f566ff0053d39f28d
 F src/vdbe.h a1d0e3b934e835e73edd146f2e7c4eadb711b5c9875c18159a57483fd78e550e
 F src/vdbeInt.h 68756566247e190f22ea8f175a81f9d1b91b6258bcdd69832ea2eb3c78ecfb11
 F src/vdbeapi.c 8863ffb5a7bac42fe9a68aaa3526ee29fc18fb02a9b27188b756de41e33856e9
@@ -1944,8 +1944,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P 7953716c12ca1deb50ee2c91d9b62a029e38f7cb61af418eeca438283c45f825
-R 85c483559243dc30f8f8dd48c45fb13f
+P 1c026bcb3c9e1ae0f38ad8a3e6e3bda1a0cdff9dcc77a08b1820f2fdde2ee200
+R 6589fae24aaa3fb0ff9b2ab0fa20c61e
 U drh
-Z 6cb6334f470796473908dc1f535cd43a
+Z bb01b1e110beac42908286888d97e4bc
 # Remove this line to create a well-formed Fossil manifest.
index d9f3573134a6866db8e42be868a3413eaffbc72f..95408aeeac12e6182088299f1551dcafc045cadb 100644 (file)
@@ -1 +1 @@
-1c026bcb3c9e1ae0f38ad8a3e6e3bda1a0cdff9dcc77a08b1820f2fdde2ee200
\ No newline at end of file
+09a47f32a44bfe8630157f09518e6467fac281bc70cf229c88efccac2028ea70
\ No newline at end of file
index 9d0a227e81a0ba9522bcb914290a94b877d8cc05..0deee95928247bdf36bda0849d860a88ec97a746 100644 (file)
@@ -2688,43 +2688,56 @@ case OP_Column: {
   pC = p->apCsr[pOp->p1];
   assert( pC!=0 );
   p2 = (u32)pOp->p2;
-
-  /* If the cursor cache is stale (meaning it is not currently point at
-  ** the correct row) then bring it up-to-date by doing the necessary 
-  ** B-Tree seek. */
-  rc = sqlite3VdbeCursorMoveto(&pC, &p2);
-  if( rc ) goto abort_due_to_error;
-
-  assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) );
   pDest = &aMem[pOp->p3];
   memAboutToChange(p, pDest);
+
+op_column_restart:
   assert( pC!=0 );
   assert( p2<(u32)pC->nField );
   aOffset = pC->aOffset;
   assert( aOffset==pC->aType+pC->nField );
+  assert( aOffset==pC->aType+pC->nField );
   assert( pC->eCurType!=CURTYPE_VTAB );
   assert( pC->eCurType!=CURTYPE_PSEUDO || pC->nullRow );
   assert( pC->eCurType!=CURTYPE_SORTER );
 
-  if( pC->cacheStatus!=p->cacheCtr ){                /*OPTIMIZATION-IF-FALSE*/
-    if( pC->nullRow ){
-      if( pC->eCurType==CURTYPE_PSEUDO ){
-        /* For the special case of as pseudo-cursor, the seekResult field
-        ** identifies the register that holds the record */
-        assert( pC->seekResult>0 );
-        assert( pC->eCurState==CURSTATE_PSEUDO_UNINIT
-             || pC->eCurState==CURSTATE_NULLROW );
-        pReg = &aMem[pC->seekResult];
-        assert( pReg->flags & MEM_Blob );
-        assert( memIsValid(pReg) );
-        pC->payloadSize = pC->szRow = pReg->n;
-        pC->aRow = (u8*)pReg->z;
-      }else{
-        assert( pC->eCurState==CURSTATE_NULLROW );
-        sqlite3VdbeMemSetNull(pDest);
-        goto op_column_out;
+  switch( pC->eCurState ){
+    case CURSTATE_READY: {
+      rc = sqlite3VdbeCursorRestore(pC);
+      if( rc ) goto abort_due_to_error;
+      break;
+    }
+    case CURSTATE_PSEUDO: {
+      break;
+    }
+    case CURSTATE_DEFERRED: {
+      u32 iMap;
+      assert( !pC->isEphemeral );
+      if( pC->ub.aAltMap && (iMap = pC->ub.aAltMap[1+p2])>0 ){
+        pC = pC->pAltCursor;
+        p2 = iMap - 1;
+        goto op_column_restart;
       }
-    }else{
+      rc = sqlite3VdbeFinishMoveto(pC);
+      if( rc ) goto abort_due_to_error;
+      goto op_column_btree_init;
+    }
+    case CURSTATE_PSEUDO_UNINIT: {
+      assert( pC->eCurType==CURTYPE_PSEUDO );
+      /* For the special case of as pseudo-cursor, the seekResult field
+      ** identifies the register that holds the record */
+      assert( pC->seekResult>0 );
+      pReg = &aMem[pC->seekResult];
+      assert( pReg->flags & MEM_Blob );
+      assert( memIsValid(pReg) );
+      pC->payloadSize = pC->szRow = pReg->n;
+      pC->aRow = (u8*)pReg->z;
+      goto op_column_init_cache;
+    }
+    case CURSTATE_UNINIT: {
+      rc = sqlite3VdbeCursorRestore(pC);
+      if( rc ) goto abort_due_to_error;
+    op_column_btree_init:
       pCrsr = pC->uc.pCursor;
       assert( pC->eCurType==CURTYPE_BTREE );
       assert( pC->eCurState==CURSTATE_UNINIT );
@@ -2737,51 +2750,57 @@ case OP_Column: {
       if( pC->payloadSize > (u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){
         goto too_big;
       }
-    }
-    pC->eCurState = pC->eCurType;
-    pC->cacheStatus = p->cacheCtr;
-    pC->iHdrOffset = getVarint32(pC->aRow, aOffset[0]);
-    pC->nHdrParsed = 0;
-
-
-    if( pC->szRow<aOffset[0] ){      /*OPTIMIZATION-IF-FALSE*/
-      /* pC->aRow does not have to hold the entire row, but it does at least
-      ** need to cover the header of the record.  If pC->aRow does not contain
-      ** the complete header, then set it to zero, forcing the header to be
-      ** dynamically allocated. */
-      pC->aRow = 0;
-      pC->szRow = 0;
-
-      /* Make sure a corrupt database has not given us an oversize header.
-      ** Do this now to avoid an oversize memory allocation.
-      **
-      ** Type entries can be between 1 and 5 bytes each.  But 4 and 5 byte
-      ** types use so much data space that there can only be 4096 and 32 of
-      ** them, respectively.  So the maximum header length results from a
-      ** 3-byte type for each of the maximum of 32768 columns plus three
-      ** extra bytes for the header length itself.  32768*3 + 3 = 98307.
-      */
-      if( aOffset[0] > 98307 || aOffset[0] > pC->payloadSize ){
-        goto op_column_corrupt;
+    op_column_init_cache:
+      pC->eCurState = pC->eCurType;
+      pC->cacheStatus = p->cacheCtr;
+      pC->iHdrOffset = getVarint32(pC->aRow, aOffset[0]);
+      pC->nHdrParsed = 0;
+
+      if( pC->szRow<aOffset[0] ){      /*OPTIMIZATION-IF-FALSE*/
+        /* pC->aRow does not have to hold the entire row, but it does at least
+        ** need to cover the header of the record.  If pC->aRow does not contain
+        ** the complete header, then set it to zero, forcing the header to be
+        ** dynamically allocated. */
+        pC->aRow = 0;
+        pC->szRow = 0;
+
+        /* Make sure a corrupt database has not given us an oversize header.
+        ** Do this now to avoid an oversize memory allocation.
+        **
+        ** Type entries can be between 1 and 5 bytes each.  But 4 and 5 byte
+        ** types use so much data space that there can only be 4096 and 32 of
+        ** them, respectively.  So the maximum header length results from a
+        ** 3-byte type for each of the maximum of 32768 columns plus three
+        ** extra bytes for the header length itself.  32768*3 + 3 = 98307.
+        */
+        if( aOffset[0] > 98307 || aOffset[0] > pC->payloadSize ){
+          goto op_column_corrupt;
+        }
+      }else{
+        /* This is an optimization.  By skipping over the first few tests
+        ** (ex: pC->nHdrParsed<=p2) in the next section, we achieve a
+        ** measurable performance gain.
+        **
+        ** This branch is taken even if aOffset[0]==0.  Such a record is never
+        ** generated by SQLite, and could be considered corruption, but we
+        ** accept it for historical reasons.  When aOffset[0]==0, the code this
+        ** branch jumps to reads past the end of the record, but never more
+        ** than a few bytes.  Even if the record occurs at the end of the page
+        ** content area, the "page header" comes after the page content and so
+        ** this overread is harmless.  Similar overreads can occur for a corrupt
+        ** database file.
+        */
+        zData = pC->aRow;
+        assert( pC->nHdrParsed<=p2 );         /* Conditional skipped */
+        testcase( aOffset[0]==0 );
+        goto op_column_read_header;
       }
-    }else{
-      /* This is an optimization.  By skipping over the first few tests
-      ** (ex: pC->nHdrParsed<=p2) in the next section, we achieve a
-      ** measurable performance gain.
-      **
-      ** This branch is taken even if aOffset[0]==0.  Such a record is never
-      ** generated by SQLite, and could be considered corruption, but we
-      ** accept it for historical reasons.  When aOffset[0]==0, the code this
-      ** branch jumps to reads past the end of the record, but never more
-      ** than a few bytes.  Even if the record occurs at the end of the page
-      ** content area, the "page header" comes after the page content and so
-      ** this overread is harmless.  Similar overreads can occur for a corrupt
-      ** database file.
-      */
-      zData = pC->aRow;
-      assert( pC->nHdrParsed<=p2 );         /* Conditional skipped */
-      testcase( aOffset[0]==0 );
-      goto op_column_read_header;
+      break;
+    }
+    default: {
+      assert( pC->eCurState==CURSTATE_NULLROW );
+      sqlite3VdbeMemSetNull(pDest);
+      goto op_column_out;
     }
   }
 
@@ -5752,10 +5771,14 @@ case OP_NullRow: {
   assert( pC!=0 );
   pC->nullRow = 1;
   pC->cacheStatus = CACHE_STALE;
-  pC->eCurState = CURSTATE_NULLROW;
   if( pC->eCurType==CURTYPE_BTREE ){
     assert( pC->uc.pCursor!=0 );
     sqlite3BtreeClearCursor(pC->uc.pCursor);
+    pC->eCurState = CURSTATE_NULLROW;
+  }else if( pC->eCurType==CURTYPE_PSEUDO ){
+    pC->eCurState = CURSTATE_PSEUDO_UNINIT;
+  }else{
+    pC->eCurState = CURSTATE_NULLROW;
   }
 #ifdef SQLITE_DEBUG
   if( pC->seekOp==0 ) pC->seekOp = OP_NullRow;