]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
High-speed version of NGQP. Still has some minor problems.
authordrh <drh@noemail.net>
Sun, 9 Jun 2013 17:21:25 +0000 (17:21 +0000)
committerdrh <drh@noemail.net>
Sun, 9 Jun 2013 17:21:25 +0000 (17:21 +0000)
FossilOrigin-Name: db2415fa677b84cd0f6dd424283c94e98d246e3b

manifest
manifest.uuid
src/where.c

index d0734bd638cb5ae039f7c83a5ac7275a52cac061..39d6b5106409436676754d82407c4f6c2f83e9a2 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Must\sfaster\scomputation\sof\sestimated\slogarithm.
-D 2013-06-07T02:04:19.774
+C High-speed\sversion\sof\sNGQP.\s\sStill\shas\ssome\sminor\sproblems.
+D 2013-06-09T17:21:25.979
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -289,7 +289,7 @@ F src/vtab.c b05e5f1f4902461ba9f5fc49bb7eb7c3a0741a83
 F src/wal.c 436bfceb141b9423c45119e68e444358ee0ed35d
 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
 F src/walker.c 4fa43583d0a84b48f93b1e88f11adf2065be4e73
-F src/where.c 70e1ebd1c3f828f4062fc2b5ada2461419020dae
+F src/where.c 2dae18fe0b79aa90f213c5f2ff385a7ac56d36d5
 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
 F test/aggnested.test 45c0201e28045ad38a530b5a144b73cd4aa2cfd6
@@ -1094,7 +1094,10 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381
 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
 F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac
-P 02741d177bfc2fca23bc99974cd899eba13cb59a
-R 8ee17766ef9ac6851fd1329c34593963
+P dfbca3acaeb862f24f25e7810a16ff2066111ff4
+R e3ea6bb6c8cd62c47ea6f6e83f99515a
+T *branch * nextgen-query-plan-fast
+T *sym-nextgen-query-plan-fast *
+T -sym-nextgen-query-plan-exp *
 U drh
-Z adf16c6d5fc0c897d258a12782d83ad0
+Z 13597db4c2da76541af04a4f735ffed4
index 8ae2ff38a7d429dc55e88ea75629d9d5891c95b9..3a88e7286011a6060ee853d9b83e552b99f6a928 100644 (file)
@@ -1 +1 @@
-dfbca3acaeb862f24f25e7810a16ff2066111ff4
\ No newline at end of file
+db2415fa677b84cd0f6dd424283c94e98d246e3b
\ No newline at end of file
index c1fc4301d705dda4b5a73776a9a2f0ffe7f79083..135633e1cf4cc9f2c5d6ad1207f5c4a5bebd128c 100644 (file)
@@ -5168,6 +5168,75 @@ static int wherePathSolver(WhereInfo *pWInfo, WhereCost nRowEst){
   return SQLITE_OK;
 }
 
+/*
+** Most queries use only a single table (they are not joins) and have
+** simple == constraints against indexed fields.  This routine attempts
+** to plan those simple cases using much less ceremony than the
+** general-purpose query planner, and thereby yield faster sqlite3_prepare()
+** times for the common case.
+**
+** Return non-zero on success, if this query can be handled by this
+** no-frills query planner.  Return zero if this query needs the 
+** general-purpose query planner.
+*/
+static int whereSimpleFastCase(WhereLoopBuilder *pBuilder){
+  WhereInfo *pWInfo;
+  struct SrcList_item *pItem;
+  WhereClause *pWC;
+  WhereTerm *pTerm;
+  WhereLoop *pLoop;
+  int iCur;
+  int i, j;
+  int nOrderBy;
+  Table *pTab;
+  Index *pIdx;
+  
+  pWInfo = pBuilder->pWInfo;
+  assert( pWInfo->pTabList->nSrc>=1 );
+  pItem = pWInfo->pTabList->a;
+  pTab = pItem->pTab;
+  if( IsVirtual(pTab) ) return 0;
+  if( pItem->zIndex ) return 0;
+  iCur = pItem->iCursor;
+  pWC = &pWInfo->sWC;
+  pLoop = pBuilder->pNew;
+  pWInfo->a[0].pWLoop = pLoop;
+  pLoop->wsFlags = 0;
+  nOrderBy = pWInfo->pOrderBy ? pWInfo->pOrderBy->nExpr : 0;
+  pTerm = findTerm(pWC, iCur, -1, 1, WO_EQ, 0);
+  if( pTerm ){
+    pLoop->wsFlags = WHERE_COLUMN_EQ|WHERE_IPK|WHERE_ONEROW;
+    pLoop->aLTerm[0] = pTerm;
+    pLoop->nLTerm = 1;
+    pLoop->u.btree.nEq = 1;
+    pLoop->rRun = (WhereCost)10;
+    pLoop->nOut = (WhereCost)1;
+    pWInfo->nRowOut = 1;
+    pWInfo->nOBSat = nOrderBy;
+  }else{
+    for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
+      if( pIdx->onError==OE_None ) continue;
+      for(j=0; j<pIdx->nColumn; j++){
+        pTerm = findTerm(pWC, iCur, pIdx->aiColumn[j], 1, WO_EQ, pIdx);
+        if( pTerm==0 ) break;
+        whereLoopResize(pWInfo->pParse->db, pLoop, j);
+        pLoop->aLTerm[j] = pTerm;
+      }
+      if( j!=pIdx->nColumn ) continue;
+      pLoop->wsFlags = WHERE_COLUMN_EQ|WHERE_ONEROW;
+      pLoop->nLTerm = j;
+      pLoop->u.btree.nEq = j;
+      pLoop->u.btree.pIndex = pIdx;
+      pLoop->rRun = (WhereCost)15;
+      pLoop->nOut = (WhereCost)1;
+      pWInfo->nRowOut = 1;
+      pWInfo->nOBSat = nOrderBy;
+      break;
+    }
+  }
+  return pLoop->wsFlags!=0;
+}
+
 /*
 ** Generate the beginning of the loop used for WHERE clause processing.
 ** The return value is a pointer to an opaque structure that contains
@@ -5307,7 +5376,7 @@ WhereInfo *sqlite3WhereBegin(
   */
   db = pParse->db;
   nByteWInfo = ROUND8(sizeof(WhereInfo)+(nTabList-1)*sizeof(WhereLevel));
-  pWInfo = sqlite3DbMallocZero(db, nByteWInfo);
+  pWInfo = sqlite3DbMallocZero(db, nByteWInfo + sizeof(WhereLoop));
   if( db->mallocFailed ){
     sqlite3DbFree(db, pWInfo);
     pWInfo = 0;
@@ -5324,6 +5393,8 @@ WhereInfo *sqlite3WhereBegin(
   pMaskSet = &pWInfo->sMaskSet;
   sWLB.pWInfo = pWInfo;
   sWLB.pWC = &pWInfo->sWC;
+  sWLB.pNew = (WhereLoop*)&pWInfo->a[nTabList];
+  whereLoopInit(sWLB.pNew);
 
   /* Disable the DISTINCT optimization if SQLITE_DistinctOpt is set via
   ** sqlite3_test_ctrl(SQLITE_TESTCTRL_OPTIMIZATIONS,...) */
@@ -5396,30 +5467,32 @@ WhereInfo *sqlite3WhereBegin(
 
   /* Construct the WhereLoop objects */
   WHERETRACE(("*** Optimizer Start ***\n"));
-  /* TBD: if( nTablist==1 ) whereCommonCase(&sWLB); */
-  rc = whereLoopAddAll(&sWLB);
-  if( rc ) goto whereBeginError;
-
-  /* Display all of the WhereLoop objects if wheretrace is enabled */
+  if( nTabList!=1 || whereSimpleFastCase(&sWLB)==0 ){
+    rc = whereLoopAddAll(&sWLB);
+    if( rc ) goto whereBeginError;
+  
+    /* Display all of the WhereLoop objects if wheretrace is enabled */
 #ifdef WHERETRACE_ENABLED
-  if( sqlite3WhereTrace ){
-    WhereLoop *p;
-    int i = 0;
-    static char zLabel[] = "0123456789abcdefghijklmnopqrstuvwyxz"
-                                     "ABCDEFGHIJKLMNOPQRSTUVWYXZ";
-    for(p=pWInfo->pLoops; p; p=p->pNextLoop){
-      p->cId = zLabel[(i++)%sizeof(zLabel)];
-      whereLoopPrint(p, pTabList);
+    if( sqlite3WhereTrace ){
+      WhereLoop *p;
+      int i = 0;
+      static char zLabel[] = "0123456789abcdefghijklmnopqrstuvwyxz"
+                                       "ABCDEFGHIJKLMNOPQRSTUVWYXZ";
+      for(p=pWInfo->pLoops; p; p=p->pNextLoop){
+        p->cId = zLabel[(i++)%sizeof(zLabel)];
+        whereLoopPrint(p, pTabList);
+      }
     }
-  }
 #endif
-
-  wherePathSolver(pWInfo, -1);
-  if( db->mallocFailed ) goto whereBeginError;
-  if( pWInfo->pOrderBy ){
-     wherePathSolver(pWInfo, pWInfo->nRowOut);
-     if( db->mallocFailed ) goto whereBeginError;
-  }else if( db->flags & SQLITE_ReverseOrder ){
+  
+    wherePathSolver(pWInfo, -1);
+    if( db->mallocFailed ) goto whereBeginError;
+    if( pWInfo->pOrderBy ){
+       wherePathSolver(pWInfo, pWInfo->nRowOut);
+       if( db->mallocFailed ) goto whereBeginError;
+    }
+  }
+  if( pWInfo->pOrderBy==0 && (db->flags & SQLITE_ReverseOrder)!=0 ){
      pWInfo->revMask = (Bitmask)(-1);
   }
   if( pParse->nErr || db->mallocFailed ){