]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Highly experimental (and non-working) changes aimed at increasing the number coroutines-exp1
authordrh <>
Tue, 6 Dec 2022 00:54:55 +0000 (00:54 +0000)
committerdrh <>
Tue, 6 Dec 2022 00:54:55 +0000 (00:54 +0000)
of occasions where a subquery can be implemented using a co-routine rather
than being materialized.  This is just saving work in progress.

FossilOrigin-Name: e7d323c16ee774816c825b8a8e078dda8f38bbbd8d87a101a42739559196f503

manifest
manifest.uuid
src/prepare.c
src/select.c
src/sqlite.h.in
src/update.c
src/vdbe.h

index 9b85c87887f096ae369f9bbc1a5588d5f55aa749..f2d7a7cc36bddf9e4bebb5a5ad35b5e64728378e 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Enhance\sthe\ssqlite3_stmt_scanstatus()\sAPI\sand\sadd\ssqlite3_stmt_scanstatus_v2().\sFor\screation\sof\senhanced\squery\sperformance\sreports.
-D 2022-12-05T19:16:23.509
+C Highly\sexperimental\s(and\snon-working)\schanges\saimed\sat\sincreasing\sthe\snumber\nof\soccasions\swhere\sa\ssubquery\scan\sbe\simplemented\susing\sa\sco-routine\srather\nthan\sbeing\smaterialized.\s\sThis\sis\sjust\ssaving\swork\sin\sprogress.
+D 2022-12-06T00:54:55.085
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -640,14 +640,14 @@ F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586
 F src/pcache1.c dee95e3cd2b61e6512dc814c5ab76d5eb36f0bfc9441dbb4260fccc0d12bbddc
 F src/pragma.c 894c2621d35edd4beea9b331cfdb1b42032394420074d2294c8febe548eea8a1
 F src/pragma.h e690a356c18e98414d2e870ea791c1be1545a714ba623719deb63f7f226d8bb7
-F src/prepare.c 9ebd3a1b12bbd1951f0d6db850f32cf5d4547a6ab8bb9e958d75dfbe4e60d0a3
+F src/prepare.c eb701220a724831190d7935c8bee7f230af0c7a8f6ac13d629088f9d37a566cd
 F src/printf.c e99ee9741e79ae3873458146f59644276657340385ade4e76a5f5d1c25793764
 F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c
 F src/resolve.c efea4e5fbecfd6d0a9071b0be0d952620991673391b6ffaaf4c277b0bb674633
 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92
-F src/select.c 321f29e431fbb71e594cc7026391a827a0270237597d2e2401244e7602dea8bd
+F src/select.c f243554e94c55dab12f812cc9043459e4299b24d326101240897bbf0090aa39a
 F src/shell.c.in e7fc8db64df14d1893a86dce488770efdbb1007e44ec8cd5549769533bb419f2
-F src/sqlite.h.in 1fe1836879ecbb2e28f00f44eb6092db09a2a06bf072af351c6c2466bd515496
+F src/sqlite.h.in 5e3f90b38e1865d39e55db747efe51848d9b05ba64ea21372a1abbd8367bfd8e
 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
 F src/sqlite3ext.h c4b9fa7a7e2bcdf850cfeb4b8a91d5ec47b7a00033bc996fd2ee96cbf2741f5f
 F src/sqliteInt.h 0c9934acd88e0fa14f0d4743233b4cd7bd7bbc84099ba3cad50d8e69676ce2b9
@@ -712,13 +712,13 @@ F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c
 F src/tokenize.c 1305797eab3542a0896b552c6e7669c972c1468e11e92b370533c1f37a37082b
 F src/treeview.c 29b1dc7e0f84ba090734febe27393d4719682af0cae1b902d5ebf0236ecebea4
 F src/trigger.c 5e68b790f022b8dafbfb0eb244786512a95c9575fc198719d2557d73e5795858
-F src/update.c 5b0302c47cf31b533d5dff04c497ca1d8b9d89c39727e633fbe7b882fd5ac5aa
+F src/update.c 3cf1cb45674177e09338bdbe5454fb62207c7f2eb8cea288e74286467e901959
 F src/upsert.c 5303dc6c518fa7d4b280ec65170f465c7a70b7ac2b22491598f6d0b4875b3145
 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0
 F src/util.c 313f3154e2b85a447326f5dd15de8d31a4df6ab0c3579bd58f426ff634ec9050
 F src/vacuum.c 84ce7f01f8a7a08748e107a441db83bcec13970190ddcb0c9ff522adbc1c23fd
 F src/vdbe.c e744259050ec9bbcd47acf9a03a66fe3305d7429c823995de11ed524ca06d16f
-F src/vdbe.h 6d921884cf8ec6a53efba99f8b68e32e955367631743e29039840e781aaf547c
+F src/vdbe.h c93d4bc242fc9109558aa6b3ce8acef7effe100a42c148dc63239c488ad6c060
 F src/vdbeInt.h e83be1eea422758d42302941e96e59d93193c373da655a87befdc03a851e0f95
 F src/vdbeapi.c 959cef4c1e5cb6589e67b3295fe9d3e45cbd109ae6618d57b74c900dbd6be0cd
 F src/vdbeaux.c 0b81f317c86ed9f4ba822af66a52777fed6e8180edc79d4fc62ffe75c8e52d80
@@ -2067,8 +2067,11 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P dc7dd2d3e50e7cc474b22f1b5b219da32bcd7aa1ba56864d1dbcf0d3a6fa06f2 009462f2344b1f468cf9440343a47fec68d783a2bfb4fa6168bb227ec910b918
-R 6f58eb8b4613cbdc0da9cabf0de9170c
-U dan
-Z dd8e28132ec997579f72120c72f627ae
+P 4893b4e3eafc7c9c22b24717f90a585862203f987cf108b079ce6e946093e675
+R 2462bad04e68d73a11cdd7ebb93dbee4
+T *branch * coroutines-exp1
+T *sym-coroutines-exp1 *
+T -sym-trunk *
+U drh
+Z 3ebf6ead00c81074e10b3b13d6b1d9c7
 # Remove this line to create a well-formed Fossil manifest.
index e55b14b4b22f536d3cfef2f2e6df7ef99c6a6487..85de0c3c0b380a428228a267cf953755fda50208 100644 (file)
@@ -1 +1 @@
-4893b4e3eafc7c9c22b24717f90a585862203f987cf108b079ce6e946093e675
\ No newline at end of file
+e7d323c16ee774816c825b8a8e078dda8f38bbbd8d87a101a42739559196f503
\ No newline at end of file
index 76073874081a7da9b6d14d42a7a81e787d8edabd..369793f3377462b636a5076e84adcef1363ebe37 100644 (file)
@@ -838,17 +838,32 @@ static int sqlite3LockAndPrepare(
   if( !sqlite3SafetyCheckOk(db)||zSql==0 ){
     return SQLITE_MISUSE_BKPT;
   }
+//prepFlags |= SQLITE_PREPARE_SAFEOPT;
   sqlite3_mutex_enter(db->mutex);
   sqlite3BtreeEnterAll(db);
-  do{
+  while( 1 /* exit-by-break */ ){
     /* Make multiple attempts to compile the SQL, until it either succeeds
     ** or encounters a permanent error.  A schema problem after one schema
     ** reset is considered a permanent error. */
     rc = sqlite3Prepare(db, zSql, nBytes, prepFlags, pOld, ppStmt, pzTail);
     assert( rc==SQLITE_OK || *ppStmt==0 );
     if( rc==SQLITE_OK || db->mallocFailed ) break;
-  }while( (rc==SQLITE_ERROR_RETRY && (cnt++)<SQLITE_MAX_PREPARE_RETRY)
-       || (rc==SQLITE_SCHEMA && (sqlite3ResetOneSchema(db,-1), cnt++)==0) );
+    if( rc==SQLITE_ERROR_RETRY ){
+      if( (cnt++) < SQLITE_MAX_PREPARE_RETRY ) continue;
+      break;
+    }
+    if( rc==SQLITE_SCHEMA ){
+      if( cnt++>0 ) break;
+      sqlite3ResetOneSchema(db,-1);
+      continue;
+    }
+//    if( rc==SQLITE_ERROR_UNSAFEOPT ){
+//      assert( (prepFlags & SQLITE_PREPARE_SAFEOPT)==0 );
+//      prepFlags |= SQLITE_PREPARE_SAFEOPT;
+//      continue;
+//    }
+    break;
+  }
   sqlite3BtreeLeaveAll(db);
   rc = sqlite3ApiExit(db, rc);
   assert( (rc&db->errMask)==rc );
index 34ba3f7a4ce921e983ed7791149f18b04453c56a..0576d3489ba20c8d241622ddf747d26a7c554e51 100644 (file)
@@ -6854,6 +6854,44 @@ static int sameSrcAlias(SrcItem *p0, SrcList *pSrc){
   return 0;
 }
 
+/*
+** Return TRUE (non-zero) if the i-th entry in the pTabList SrcList can
+** be implemented as a co-routine.  The i-th entry is guaranteed to be
+** a subquery.
+**
+** The subquery is implemented as a co-routine if all of the following are
+** true:
+**
+**    (1)  the subquery is the left-most subquery and there is nothing
+**         that would prevent it from being the outer-most loop.
+**    (2)  the subquery is not a CTE that should be materialized
+**    (3)  the subquery is not part of a left operand for a RIGHT JOIN
+*/
+static int fromClauseTermCanBeCoroutine(
+  Parse *pParse,            /* Parsing context */
+  SrcList *pTabList,        /* FROM clause */
+  int i                     /* Which term of the FROM clause */
+){
+  SrcItem *pItem = &pTabList->a[i];
+  if( pItem->fg.isCte && pItem->u2.pCteUse->eM10d==M10d_Yes ) return 0;
+  if( pTabList->a[0].fg.jointype & JT_LTORJ ) return 0;
+  if( i==0 ){
+    if( pTabList->nSrc==1 ) return 1;
+    if( pTabList->a[1].fg.jointype & JT_CROSS ) return 1;
+    if( pParse->prepFlags & SQLITE_PREPARE_SAFEOPT ) return 0;
+    return 1;
+  }
+  if( pParse->prepFlags & SQLITE_PREPARE_SAFEOPT ) return 0;
+  while( 1 /*exit-by-break*/ ){
+    if( pItem->fg.jointype & (JT_OUTER|JT_CROSS)  ) return 0;
+    if( i==0 ) break;
+    i--;
+    pItem--;
+    if( pItem->pSelect!=0 ) return 0;
+  }
+  return 1;
+}
+
 /*
 ** Generate code for the SELECT statement given in the p argument.  
 **
@@ -7241,21 +7279,8 @@ int sqlite3Select(
     pParse->zAuthContext = pItem->zName;
 
     /* Generate code to implement the subquery
-    **
-    ** The subquery is implemented as a co-routine if all of the following are
-    ** true:
-    **
-    **    (1)  the subquery is guaranteed to be the outer loop (so that
-    **         it does not need to be computed more than once), and
-    **    (2)  the subquery is not a CTE that should be materialized
-    **    (3)  the subquery is not part of a left operand for a RIGHT JOIN
     */
-    if( i==0
-     && (pTabList->nSrc==1
-            || (pTabList->a[1].fg.jointype&(JT_OUTER|JT_CROSS))!=0)  /* (1) */
-     && (pItem->fg.isCte==0 || pItem->u2.pCteUse->eM10d!=M10d_Yes)   /* (2) */
-     && (pTabList->a[0].fg.jointype & JT_LTORJ)==0                   /* (3) */
-    ){
+    if( fromClauseTermCanBeCoroutine(pParse, pTabList, i) ){
       /* Implement a co-routine that will return a single row of the result
       ** set on each invocation.
       */
index 91e1e07f87d73647676e13494f73a1320b382233..598a244937c5fcfc3e66fb665e6cc401c5431a6b 100644 (file)
@@ -495,6 +495,7 @@ int sqlite3_exec(
 #define SQLITE_ERROR_MISSING_COLLSEQ   (SQLITE_ERROR | (1<<8))
 #define SQLITE_ERROR_RETRY             (SQLITE_ERROR | (2<<8))
 #define SQLITE_ERROR_SNAPSHOT          (SQLITE_ERROR | (3<<8))
+#define SQLITE_ERROR_UNSAFEOPT         (SQLITE_ERROR | (4<<8))
 #define SQLITE_IOERR_READ              (SQLITE_IOERR | (1<<8))
 #define SQLITE_IOERR_SHORT_READ        (SQLITE_IOERR | (2<<8))
 #define SQLITE_IOERR_WRITE             (SQLITE_IOERR | (3<<8))
index 809b3065399b493444e62e2d69ff5f26cd785665..0612b2708d03d3cbfbc58130eef3b1e3a4aaed96 100644 (file)
@@ -268,6 +268,7 @@ static void updateFromSelect(
   if( pSelect ) pSelect->selFlags |= SF_OrderByReqd;
   sqlite3SelectDestInit(&dest, eDest, iEph);
   dest.iSDParm2 = (pPk ? pPk->nKeyCol : -1);
+  pParse->prepFlags |= SQLITE_PREPARE_SAFEOPT;
   sqlite3Select(pParse, pSelect, &dest);
   sqlite3SelectDelete(db, pSelect);
 }
index a199247434e95df90353a7261fdee7ba6725e076..467c9993433e45b8627866eb68d1b704402d9d75 100644 (file)
@@ -165,6 +165,7 @@ typedef struct VdbeOpList VdbeOpList;
 ** Additional non-public SQLITE_PREPARE_* flags
 */
 #define SQLITE_PREPARE_SAVESQL  0x80  /* Preserve SQL text */
+#define SQLITE_PREPARE_SAFEOPT  0x40  /* Use only safe optimizations */
 #define SQLITE_PREPARE_MASK     0x0f  /* Mask of public flags */
 
 /*