]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Change the internal sqlite3WhereBegin() to report that the ORDER BY clause
authordrh <drh@noemail.net>
Mon, 24 Sep 2012 15:30:54 +0000 (15:30 +0000)
committerdrh <drh@noemail.net>
Mon, 24 Sep 2012 15:30:54 +0000 (15:30 +0000)
is satisfied by indices using the WhereInfo.nOBSat field of the returned
structure.

FossilOrigin-Name: 22989f3588531efd555cc29d6c576e7a34b7edc4

manifest
manifest.uuid
src/select.c
src/sqliteInt.h
src/where.c

index 8f9cec3047ed594bec8d3e10b176bf7abddbc3e8..534ea306e5e2e4292ec6a1f86faacdac6a3fae65 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Update\sdocumentation\sto\sdescribe\sthe\sthreadsafety\sof\s\nsqlite3_enable_shared_cache().
-D 2012-09-24T11:43:43.748
+C Change\sthe\sinternal\ssqlite3WhereBegin()\sto\sreport\sthat\sthe\sORDER\sBY\sclause\nis\ssatisfied\sby\sindices\susing\sthe\sWhereInfo.nOBSat\sfield\sof\sthe\sreturned\nstructure.
+D 2012-09-24T15:30:54.533
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in 5f4f26109f9d80829122e0e09f9cda008fa065fb
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -174,12 +174,12 @@ F src/printf.c 4a9f882f1c1787a8b494a2987765acf9d97ac21f
 F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50
 F src/resolve.c 9e28280ec98035f31900fdd1db01f86f68ca6c32
 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0
-F src/select.c c2a83ada835d3554a4d724c5358d4475aa7e1e77
+F src/select.c 1fad66b73a69c4004c9969a95b46d1f03390677d
 F src/shell.c 8ee5a3cb502e2d574f97b43972e6c1e275e7bec7
 F src/sqlite.h.in cbe846facaba903654b4136c97e7f57b3ac0bac7
 F src/sqlite3.rc fea433eb0a59f4c9393c8e6d76a6e2596b1fe0c0
 F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477
-F src/sqliteInt.h 6d02f0bbca677887bbbe1a69c69cdde6f54adb9c
+F src/sqliteInt.h 6b17114bb5c6ae30d360aeeef30ab40587afad4e
 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
 F src/status.c 35939e7e03abf1b7577ce311f48f682c40de3208
 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
@@ -249,7 +249,7 @@ F src/vtab.c d8020c0a0e8ccc490ca449d7e665311b6e9f3ba9
 F src/wal.c 5acb3e7bbd31f10ba39acad9ce6b399055337a9d
 F src/wal.h 29c197540b19044e6cd73487017e5e47a1d3dac6
 F src/walker.c 3d75ba73de15e0f8cd0737643badbeb0e002f07b
-F src/where.c 3b52eeffab96e6ee3e1593af0967206cde09c221
+F src/where.c af126a6cdb290c2d79ef18bb41bbca949c9cad61
 F test/8_3_names.test 631ea964a3edb091cf73c3b540f6bcfdb36ce823
 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
 F test/aggnested.test 0be144b453e0622a085fae8665c32f5676708e00
@@ -1016,7 +1016,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381
 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
 F tool/win/sqlite.vsix 67d8a99aceb56384a81b3f30d6c71743146d2cc9
-P 1be4b16b9e900181ae6848f2920ea646f407c9dc
-R 0efc5261436fa50b53879d926ef0509e
+P e081890cd77ad8de4bf55a8f8cf9d63bfaaf8218
+R 4ad3ce4fdebd545cd663ab5469164871
 U drh
-Z f86abf9bd38d08dcead454a5f06f2799
+Z 1dbcfbc31e18555fa81506ef779ada01
index 11bb5536dab55eadeb6ff0990dc6a2304a00cfad..79fb09f4719fe8a0d98bd57ba74b2efe4bd0d05a 100644 (file)
@@ -1 +1 @@
-e081890cd77ad8de4bf55a8f8cf9d63bfaaf8218
\ No newline at end of file
+22989f3588531efd555cc29d6c576e7a34b7edc4
\ No newline at end of file
index 39787de80aa7c3912489c2515bb64f05b86b396b..01fe27694fc389ad744154d5f9385930f0f0e324 100644 (file)
@@ -4098,10 +4098,11 @@ int sqlite3Select(
     ExprList *pDist = (sDistinct.isTnct ? p->pEList : 0);
 
     /* Begin the database scan. */
-    pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, &pOrderBy, pDist, 0,0);
+    pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pOrderBy, pDist, 0,0);
     if( pWInfo==0 ) goto select_end;
     if( pWInfo->nRowOut < p->nSelectRow ) p->nSelectRow = pWInfo->nRowOut;
     if( pWInfo->eDistinct ) sDistinct.eTnctType = pWInfo->eDistinct;
+    if( pOrderBy && pWInfo->nOBSat==pOrderBy->nExpr ) pOrderBy = 0;
 
     /* If sorting index that was created by a prior OP_OpenEphemeral 
     ** instruction ended up not being needed, then change the OP_OpenEphemeral
@@ -4229,14 +4230,13 @@ int sqlite3Select(
       ** in the right order to begin with.
       */
       sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset);
-      pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, &pGroupBy, 0, 0, 0);
+      pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pGroupBy, 0, 0, 0);
       if( pWInfo==0 ) goto select_end;
-      if( pGroupBy==0 ){
+      if( pWInfo->nOBSat==pGroupBy->nExpr ){
         /* The optimizer is able to deliver rows in group by order so
         ** we do not have to sort.  The OP_OpenEphemeral table will be
         ** cancelled later because we still need to use the pKeyInfo
         */
-        pGroupBy = p->pGroupBy;
         groupBySort = 0;
       }else{
         /* Rows are coming out in undetermined order.  We have to push
@@ -4486,6 +4486,7 @@ int sqlite3Select(
         u8 flag = minMaxQuery(p);
         if( flag ){
           assert( !ExprHasProperty(p->pEList->a[0].pExpr, EP_xIsSelect) );
+          assert( p->pEList->a[0].pExpr->x.pList->nExpr==1 );
           pMinMax = sqlite3ExprListDup(db, p->pEList->a[0].pExpr->x.pList,0);
           pDel = pMinMax;
           if( pMinMax && !db->mallocFailed ){
@@ -4499,13 +4500,13 @@ int sqlite3Select(
         ** of output.
         */
         resetAccumulator(pParse, &sAggInfo);
-        pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, &pMinMax,0,flag,0);
+        pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pMinMax,0,flag,0);
         if( pWInfo==0 ){
           sqlite3ExprListDelete(db, pDel);
           goto select_end;
         }
         updateAccumulator(pParse, &sAggInfo);
-        if( !pMinMax && flag ){
+        if( pWInfo->nOBSat>0 ){
           sqlite3VdbeAddOp2(v, OP_Goto, 0, pWInfo->iBreak);
           VdbeComment((v, "%s() by index",
                 (flag==WHERE_ORDERBY_MIN?"min":"max")));
index 7701b6d7cbcac22d54c5109697b46935abfa3f40..7b9894254a521ae5451364293595ed96be7b5dd9 100644 (file)
@@ -1982,20 +1982,21 @@ struct WhereLevel {
 ** into the second half to give some continuity.
 */
 struct WhereInfo {
-  Parse *pParse;       /* Parsing and code generating context */
-  u16 wctrlFlags;      /* Flags originally passed to sqlite3WhereBegin() */
-  u8 okOnePass;        /* Ok to use one-pass algorithm for UPDATE or DELETE */
-  u8 untestedTerms;    /* Not all WHERE terms resolved by outer loop */
-  u8 eDistinct;                  /* One of the WHERE_DISTINCT_* values below */
-  SrcList *pTabList;             /* List of tables in the join */
-  int iTop;                      /* The very beginning of the WHERE loop */
-  int iContinue;                 /* Jump here to continue with next record */
-  int iBreak;                    /* Jump here to break out of the loop */
-  int nLevel;                    /* Number of nested loop */
-  struct WhereClause *pWC;       /* Decomposition of the WHERE clause */
-  double savedNQueryLoop;        /* pParse->nQueryLoop outside the WHERE loop */
-  double nRowOut;                /* Estimated number of output rows */
-  WhereLevel a[1];               /* Information about each nest loop in WHERE */
+  Parse *pParse;            /* Parsing and code generating context */
+  SrcList *pTabList;        /* List of tables in the join */
+  u16 nOBSat;               /* Number of ORDER BY terms satisfied by indices */
+  u16 wctrlFlags;           /* Flags originally passed to sqlite3WhereBegin() */
+  u8 okOnePass;             /* Ok to use one-pass algorithm for UPDATE/DELETE */
+  u8 untestedTerms;         /* Not all WHERE terms resolved by outer loop */
+  u8 eDistinct;             /* One of the WHERE_DISTINCT_* values below */
+  int iTop;                 /* The very beginning of the WHERE loop */
+  int iContinue;            /* Jump here to continue with next record */
+  int iBreak;               /* Jump here to break out of the loop */
+  int nLevel;               /* Number of nested loop */
+  struct WhereClause *pWC;  /* Decomposition of the WHERE clause */
+  double savedNQueryLoop;   /* pParse->nQueryLoop outside the WHERE loop */
+  double nRowOut;           /* Estimated number of output rows */
+  WhereLevel a[1];          /* Information about each nest loop in WHERE */
 };
 
 /* Allowed values for WhereInfo.eDistinct and DistinctCtx.eTnctType */
@@ -2811,8 +2812,7 @@ Expr *sqlite3LimitWhere(Parse *, SrcList *, Expr *, ExprList *, Expr *, Expr *,
 #endif
 void sqlite3DeleteFrom(Parse*, SrcList*, Expr*);
 void sqlite3Update(Parse*, SrcList*, ExprList*, Expr*, int);
-WhereInfo *sqlite3WhereBegin(
-    Parse*,SrcList*,Expr*,ExprList**,ExprList*,u16,int);
+WhereInfo *sqlite3WhereBegin(Parse*,SrcList*,Expr*,ExprList*,ExprList*,u16,int);
 void sqlite3WhereEnd(WhereInfo*);
 int sqlite3ExprCodeGetColumn(Parse*, Table*, int, int, int, u8);
 void sqlite3ExprCodeGetColumnOfTable(Vdbe*, Table*, int, int, int);
index d5a1f41f80241eefc35a3d5cbbddfd492209de57..ba885f130415593e63e843e08e30b7fa267af913 100644 (file)
@@ -4667,24 +4667,24 @@ static void whereInfoFree(sqlite3 *db, WhereInfo *pWInfo){
 **
 ** ORDER BY CLAUSE PROCESSING
 **
-** *ppOrderBy is a pointer to the ORDER BY clause of a SELECT statement,
+** pOrderBy is a pointer to the ORDER BY clause of a SELECT statement,
 ** if there is one.  If there is no ORDER BY clause or if this routine
-** is called from an UPDATE or DELETE statement, then ppOrderBy is NULL.
+** is called from an UPDATE or DELETE statement, then pOrderBy is NULL.
 **
 ** If an index can be used so that the natural output order of the table
 ** scan is correct for the ORDER BY clause, then that index is used and
-** *ppOrderBy is set to NULL.  This is an optimization that prevents an
-** unnecessary sort of the result set if an index appropriate for the
-** ORDER BY clause already exists.
+** the returned WhereInfo.nOBSat field is set to pOrderBy->nExpr.  This
+** is an optimization that prevents an unnecessary sort of the result set
+** if an index appropriate for the ORDER BY clause already exists.
 **
 ** If the where clause loops cannot be arranged to provide the correct
-** output order, then the *ppOrderBy is unchanged.
+** output order, then WhereInfo.nOBSat is 0.
 */
 WhereInfo *sqlite3WhereBegin(
   Parse *pParse,        /* The parser context */
   SrcList *pTabList,    /* A list of all tables to be scanned */
   Expr *pWhere,         /* The WHERE clause */
-  ExprList **ppOrderBy, /* An ORDER BY clause, or NULL */
+  ExprList *pOrderBy,   /* An ORDER BY clause, or NULL */
   ExprList *pDistinct,  /* The select-list for DISTINCT queries - or NULL */
   u16 wctrlFlags,       /* One of the WHERE_* flags defined in sqliteInt.h */
   int iIdxCur           /* If WHERE_ONETABLE_ONLY is set, index cursor number */
@@ -4909,7 +4909,7 @@ WhereInfo *sqlite3WhereBegin(
       for(j=iFrom, pTabItem=&pTabList->a[j]; j<nTabList; j++, pTabItem++){
         int doNotReorder;    /* True if this table should not be reordered */
         WhereCost sCost;     /* Cost information from best[Virtual]Index() */
-        ExprList *pOrderBy;  /* ORDER BY clause for index to optimize */
+        ExprList *pOB;       /* ORDER BY clause for index to optimize */
         ExprList *pDist;     /* DISTINCT clause for index to optimize */
   
         doNotReorder =  (pTabItem->jointype & (JT_LEFT|JT_CROSS))!=0;
@@ -4920,7 +4920,7 @@ WhereInfo *sqlite3WhereBegin(
           continue;
         }
         mask = (isOptimal ? m : notReady);
-        pOrderBy = ((i==0 && ppOrderBy )?*ppOrderBy:0);
+        pOB = (i==0) ? pOrderBy : 0;
         pDist = (i==0 ? pDistinct : 0);
         if( pTabItem->pIndex==0 ) nUnconstrained++;
   
@@ -4930,12 +4930,12 @@ WhereInfo *sqlite3WhereBegin(
 #ifndef SQLITE_OMIT_VIRTUALTABLE
         if( IsVirtual(pTabItem->pTab) ){
           sqlite3_index_info **pp = &pWInfo->a[j].pIdxInfo;
-          bestVirtualIndex(pParse, pWC, pTabItem, mask, notReady, pOrderBy,
+          bestVirtualIndex(pParse, pWC, pTabItem, mask, notReady, pOB,
                            &sCost, pp);
         }else 
 #endif
         {
-          bestBtreeIndex(pParse, pWC, pTabItem, mask, notReady, pOrderBy,
+          bestBtreeIndex(pParse, pWC, pTabItem, mask, notReady, pOB,
               pDist, &sCost);
         }
         assert( isOptimal || (sCost.used&notReady)==0 );
@@ -4995,8 +4995,8 @@ WhereInfo *sqlite3WhereBegin(
                 " with cost=%g and nRow=%g\n",
                 bestJ, pLevel-pWInfo->a, bestPlan.rCost, bestPlan.plan.nRow));
     /* The ALWAYS() that follows was added to hush up clang scan-build */
-    if( (bestPlan.plan.wsFlags & WHERE_ORDERBY)!=0 && ALWAYS(ppOrderBy) ){
-      *ppOrderBy = 0;
+    if( (bestPlan.plan.wsFlags & WHERE_ORDERBY)!=0 ){
+      pWInfo->nOBSat = pOrderBy->nExpr;
     }
     if( (bestPlan.plan.wsFlags & WHERE_DISTINCT)!=0 ){
       assert( pWInfo->eDistinct==0 );
@@ -5049,8 +5049,8 @@ WhereInfo *sqlite3WhereBegin(
   /* If the total query only selects a single row, then the ORDER BY
   ** clause is irrelevant.
   */
-  if( (andFlags & WHERE_UNIQUE)!=0 && ppOrderBy ){
-    *ppOrderBy = 0;
+  if( (andFlags & WHERE_UNIQUE)!=0 && pOrderBy ){
+    pWInfo->nOBSat = pOrderBy->nExpr;
   }
 
   /* If the caller is an UPDATE or DELETE statement that is requesting