/ Check-in [8f30b095]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Merge in latest trunk changes.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | experimental
Files: files | file ages | folders
SHA1: 8f30b09518d23c3f6cecd244a66ef918fdb55323
User & Date: dan 2014-02-27 20:52:26
Context
2014-02-28
09:48
Minor tweak to vdbeRecordCompareInt(). check-in: 284bde0e user: dan tags: experimental
2014-02-27
20:52
Merge in latest trunk changes. check-in: 8f30b095 user: dan tags: experimental
20:44
Further changes to sqlite3VdbeRecordCompare(). check-in: 57089374 user: dan tags: experimental
15:11
A better way of handling the USE_SYSTEM_SQLITE #define in shell.c. check-in: 51ce713c user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/select.c.

   814    814         ExprList *pSO;
   815    815         pSO = pDest->pOrderBy;
   816    816         assert( pSO );
   817    817         nKey = pSO->nExpr;
   818    818         r1 = sqlite3GetTempReg(pParse);
   819    819         r2 = sqlite3GetTempRange(pParse, nKey+2);
   820    820         r3 = r2+nKey+1;
   821         -      sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nResultCol, r3);
   822    821         if( eDest==SRT_DistQueue ){
   823    822           /* If the destination is DistQueue, then cursor (iParm+1) is open
   824    823           ** on a second ephemeral index that holds all values every previously
   825         -        ** added to the queue.  Only add this new value if it has never before
   826         -        ** been added */
   827         -        addrTest = sqlite3VdbeAddOp4Int(v, OP_Found, iParm+1, 0, r3, 0);
          824  +        ** added to the queue. */
          825  +        addrTest = sqlite3VdbeAddOp4Int(v, OP_Found, iParm+1, 0, 
          826  +                                        regResult, nResultCol);
   828    827           VdbeCoverage(v);
          828  +      }
          829  +      sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nResultCol, r3);
          830  +      if( eDest==SRT_DistQueue ){
   829    831           sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm+1, r3);
   830    832           sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
   831    833         }
   832    834         for(i=0; i<nKey; i++){
   833    835           sqlite3VdbeAddOp2(v, OP_SCopy,
   834    836                             regResult + pSO->a[i].u.x.iOrderByCol - 1,
   835    837                             r2+i);

Changes to src/shell.c.

  1004   1004     const char *zFirstRow    /* Print before first row, if not NULL */
  1005   1005   ){
  1006   1006     sqlite3_stmt *pSelect;
  1007   1007     int rc;
  1008   1008     int nResult;
  1009   1009     int i;
  1010   1010     const char *z;
  1011         -  rc = sqlite3_prepare(p->db, zSelect, -1, &pSelect, 0);
         1011  +  rc = sqlite3_prepare_v2(p->db, zSelect, -1, &pSelect, 0);
  1012   1012     if( rc!=SQLITE_OK || !pSelect ){
  1013   1013       fprintf(p->out, "/**** ERROR: (%d) %s *****/\n", rc, sqlite3_errmsg(p->db));
  1014   1014       if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++;
  1015   1015       return rc;
  1016   1016     }
  1017   1017     rc = sqlite3_step(pSelect);
  1018   1018     nResult = sqlite3_column_count(pSelect);
................................................................................
  1452   1452       char *zTmp = 0;
  1453   1453       int nRow = 0;
  1454   1454      
  1455   1455       zTableInfo = appendText(zTableInfo, "PRAGMA table_info(", 0);
  1456   1456       zTableInfo = appendText(zTableInfo, zTable, '"');
  1457   1457       zTableInfo = appendText(zTableInfo, ");", 0);
  1458   1458   
  1459         -    rc = sqlite3_prepare(p->db, zTableInfo, -1, &pTableInfo, 0);
         1459  +    rc = sqlite3_prepare_v2(p->db, zTableInfo, -1, &pTableInfo, 0);
  1460   1460       free(zTableInfo);
  1461   1461       if( rc!=SQLITE_OK || !pTableInfo ){
  1462   1462         return 1;
  1463   1463       }
  1464   1464   
  1465   1465       zSelect = appendText(zSelect, "SELECT 'INSERT INTO ' || ", 0);
  1466   1466       /* Always quote the table name, even if it appears to be pure ascii,
................................................................................
  1889   1889     }else{
  1890   1890       while( c!=EOF && c!=cSep && c!='\n' ){
  1891   1891         csv_append_char(p, c);
  1892   1892         c = fgetc(p->in);
  1893   1893       }
  1894   1894       if( c=='\n' ){
  1895   1895         p->nLine++;
  1896         -      if( p->n>1 && p->z[p->n-1]=='\r' ) p->n--;
         1896  +      if( p->n>0 && p->z[p->n-1]=='\r' ) p->n--;
  1897   1897       }
  1898   1898       p->cTerm = c;
  1899   1899     }
  1900   1900     if( p->z ) p->z[p->n] = 0;
  1901   1901     return p->z;
  1902   1902   }
  1903   1903   
................................................................................
  2395   2395       zSql = sqlite3_mprintf("SELECT * FROM %s", zTable);
  2396   2396       if( zSql==0 ){
  2397   2397         fprintf(stderr, "Error: out of memory\n");
  2398   2398         xCloser(sCsv.in);
  2399   2399         return 1;
  2400   2400       }
  2401   2401       nByte = strlen30(zSql);
  2402         -    rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
         2402  +    rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
  2403   2403       if( rc && sqlite3_strglob("no such table: *", sqlite3_errmsg(db))==0 ){
  2404   2404         char *zCreate = sqlite3_mprintf("CREATE TABLE %s", zTable);
  2405   2405         char cSep = '(';
  2406   2406         while( csv_read_one_field(&sCsv) ){
  2407   2407           zCreate = sqlite3_mprintf("%z%c\n  \"%s\" TEXT", zCreate, cSep, sCsv.z);
  2408   2408           cSep = ',';
  2409   2409           if( sCsv.cTerm!=sCsv.cSeparator ) break;
................................................................................
  2421   2421         if( rc ){
  2422   2422           fprintf(stderr, "CREATE TABLE %s(...) failed: %s\n", zTable,
  2423   2423                   sqlite3_errmsg(db));
  2424   2424           sqlite3_free(sCsv.z);
  2425   2425           xCloser(sCsv.in);
  2426   2426           return 1;
  2427   2427         }
  2428         -      rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
         2428  +      rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
  2429   2429       }
  2430   2430       sqlite3_free(zSql);
  2431   2431       if( rc ){
  2432   2432         if (pStmt) sqlite3_finalize(pStmt);
  2433   2433         fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
  2434   2434         xCloser(sCsv.in);
  2435   2435         return 1;
................................................................................
  2448   2448       j = strlen30(zSql);
  2449   2449       for(i=1; i<nCol; i++){
  2450   2450         zSql[j++] = ',';
  2451   2451         zSql[j++] = '?';
  2452   2452       }
  2453   2453       zSql[j++] = ')';
  2454   2454       zSql[j] = 0;
  2455         -    rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
         2455  +    rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
  2456   2456       sqlite3_free(zSql);
  2457   2457       if( rc ){
  2458   2458         fprintf(stderr, "Error: %s\n", sqlite3_errmsg(db));
  2459   2459         if (pStmt) sqlite3_finalize(pStmt);
  2460   2460         xCloser(sCsv.in);
  2461   2461         return 1;
  2462   2462       }
................................................................................
  3544   3544     struct callback_data data;
  3545   3545     const char *zInitFile = 0;
  3546   3546     char *zFirstCmd = 0;
  3547   3547     int i;
  3548   3548     int rc = 0;
  3549   3549     int warnInmemoryDb = 0;
  3550   3550   
         3551  +#if USE_SYSTEM_SQLITE+0!=1
  3551   3552     if( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)!=0 ){
  3552   3553       fprintf(stderr, "SQLite header and source version mismatch\n%s\n%s\n",
  3553   3554               sqlite3_sourceid(), SQLITE_SOURCE_ID);
  3554   3555       exit(1);
  3555   3556     }
         3557  +#endif
  3556   3558     Argv0 = argv[0];
  3557   3559     main_init(&data);
  3558   3560     stdin_is_interactive = isatty(0);
  3559   3561   
  3560   3562     /* Make sure we have a valid signal handler early, before anything
  3561   3563     ** else is done.
  3562   3564     */
................................................................................
  3641   3643     if( data.zDbFilename==0 ){
  3642   3644   #ifndef SQLITE_OMIT_MEMORYDB
  3643   3645       data.zDbFilename = ":memory:";
  3644   3646       warnInmemoryDb = argc==1;
  3645   3647   #else
  3646   3648       fprintf(stderr,"%s: Error: no database filename specified\n", Argv0);
  3647   3649       return 1;
         3650  +#endif
         3651  +#ifdef SQLITE_SHELL_DBNAME_PROC
         3652  +    { extern void SQLITE_SHELL_DBNAME_PROC(const char**);
         3653  +      SQLITE_SHELL_DBNAME_PROC(&data.zDbFilename);
         3654  +      warnInmemoryDb = 0; }
  3648   3655   #endif
  3649   3656     }
  3650   3657     data.out = stdout;
  3651   3658   
  3652   3659     /* Go ahead and open the database file if it already exists.  If the
  3653   3660     ** file does not exist, delay opening it.  This prevents empty database
  3654   3661     ** files from being created if a user mistypes the database name argument

Changes to src/sqliteInt.h.

  2351   2351     char *zErrMsg;       /* An error message */
  2352   2352     Vdbe *pVdbe;         /* An engine for executing database bytecode */
  2353   2353     int rc;              /* Return code from execution */
  2354   2354     u8 colNamesSet;      /* TRUE after OP_ColumnName has been issued to pVdbe */
  2355   2355     u8 checkSchema;      /* Causes schema cookie check after an error */
  2356   2356     u8 nested;           /* Number of nested calls to the parser/code generator */
  2357   2357     u8 nTempReg;         /* Number of temporary registers in aTempReg[] */
  2358         -  u8 nTempInUse;       /* Number of aTempReg[] currently checked out */
  2359   2358     u8 nColCache;        /* Number of entries in aColCache[] */
  2360   2359     u8 iColCache;        /* Next entry in aColCache[] to replace */
  2361   2360     u8 isMultiWrite;     /* True if statement may modify/insert multiple rows */
  2362   2361     u8 mayAbort;         /* True if statement may throw an ABORT exception */
  2363   2362     u8 hasCompound;      /* Need to invoke convertCompoundSelectToSubquery() */
  2364   2363     u8 okConstFactor;    /* OK to factor out constants */
  2365   2364     int aTempReg[8];     /* Holding area for temporary registers */

Changes to src/where.c.

  2849   2849     ){
  2850   2850       /* Case 2:  We can directly reference a single row using an
  2851   2851       **          equality comparison against the ROWID field.  Or
  2852   2852       **          we reference multiple rows using a "rowid IN (...)"
  2853   2853       **          construct.
  2854   2854       */
  2855   2855       assert( pLoop->u.btree.nEq==1 );
  2856         -    iReleaseReg = sqlite3GetTempReg(pParse);
  2857   2856       pTerm = pLoop->aLTerm[0];
  2858   2857       assert( pTerm!=0 );
  2859   2858       assert( pTerm->pExpr!=0 );
  2860   2859       assert( omitTable==0 );
  2861   2860       testcase( pTerm->wtFlags & TERM_VIRTUAL );
         2861  +    iReleaseReg = ++pParse->nMem;
  2862   2862       iRowidReg = codeEqualityTerm(pParse, pTerm, pLevel, 0, bRev, iReleaseReg);
         2863  +    if( iRowidReg!=iReleaseReg ) sqlite3ReleaseTempReg(pParse, iReleaseReg);
  2863   2864       addrNxt = pLevel->addrNxt;
  2864   2865       sqlite3VdbeAddOp2(v, OP_MustBeInt, iRowidReg, addrNxt); VdbeCoverage(v);
  2865   2866       sqlite3VdbeAddOp3(v, OP_NotExists, iCur, addrNxt, iRowidReg);
  2866   2867       VdbeCoverage(v);
  2867   2868       sqlite3ExprCacheAffinityChange(pParse, iRowidReg, 1);
  2868   2869       sqlite3ExprCacheStore(pParse, iCur, -1, iRowidReg);
  2869   2870       VdbeComment((v, "pk"));
................................................................................
  2944   2945       }
  2945   2946       start = sqlite3VdbeCurrentAddr(v);
  2946   2947       pLevel->op = bRev ? OP_Prev : OP_Next;
  2947   2948       pLevel->p1 = iCur;
  2948   2949       pLevel->p2 = start;
  2949   2950       assert( pLevel->p5==0 );
  2950   2951       if( testOp!=OP_Noop ){
  2951         -      iRowidReg = iReleaseReg = sqlite3GetTempReg(pParse);
         2952  +      iRowidReg = ++pParse->nMem;
  2952   2953         sqlite3VdbeAddOp2(v, OP_Rowid, iCur, iRowidReg);
  2953   2954         sqlite3ExprCacheStore(pParse, iCur, -1, iRowidReg);
  2954   2955         sqlite3VdbeAddOp3(v, testOp, memEndValue, addrBrk, iRowidReg);
  2955   2956         VdbeCoverageIf(v, testOp==OP_Le);
  2956   2957         VdbeCoverageIf(v, testOp==OP_Lt);
  2957   2958         VdbeCoverageIf(v, testOp==OP_Ge);
  2958   2959         VdbeCoverageIf(v, testOp==OP_Gt);
................................................................................
  3177   3178   
  3178   3179       /* Seek the table cursor, if required */
  3179   3180       disableTerm(pLevel, pRangeStart);
  3180   3181       disableTerm(pLevel, pRangeEnd);
  3181   3182       if( omitTable ){
  3182   3183         /* pIdx is a covering index.  No need to access the main table. */
  3183   3184       }else if( HasRowid(pIdx->pTable) ){
  3184         -      iRowidReg = iReleaseReg = sqlite3GetTempReg(pParse);
         3185  +      iRowidReg = ++pParse->nMem;
  3185   3186         sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur, iRowidReg);
  3186   3187         sqlite3ExprCacheStore(pParse, iCur, -1, iRowidReg);
  3187   3188         sqlite3VdbeAddOp2(v, OP_Seek, iCur, iRowidReg);  /* Deferred seek */
  3188   3189       }else{
  3189   3190         Index *pPk = sqlite3PrimaryKeyIndex(pIdx->pTable);
  3190   3191         iRowidReg = sqlite3GetTempRange(pParse, pPk->nKeyCol);
  3191   3192         for(j=0; j<pPk->nKeyCol; j++){
................................................................................
  3525   3526           continue;
  3526   3527         }
  3527   3528         assert( pTerm->pExpr );
  3528   3529         sqlite3ExprIfFalse(pParse, pTerm->pExpr, addrCont, SQLITE_JUMPIFNULL);
  3529   3530         pTerm->wtFlags |= TERM_CODED;
  3530   3531       }
  3531   3532     }
  3532         -  sqlite3ReleaseTempReg(pParse, iReleaseReg);
  3533   3533   
  3534   3534     return pLevel->notReady;
  3535   3535   }
  3536   3536   
  3537   3537   #if defined(WHERETRACE_ENABLED) && defined(SQLITE_ENABLE_TREE_EXPLAIN)
  3538   3538   /*
  3539   3539   ** Generate "Explanation" text for a WhereTerm.
................................................................................
  4897   4897       } /* end-if not one-row */
  4898   4898   
  4899   4899       /* Mark off any other ORDER BY terms that reference pLoop */
  4900   4900       if( isOrderDistinct ){
  4901   4901         orderDistinctMask |= pLoop->maskSelf;
  4902   4902         for(i=0; i<nOrderBy; i++){
  4903   4903           Expr *p;
         4904  +        Bitmask mTerm;
  4904   4905           if( MASKBIT(i) & obSat ) continue;
  4905   4906           p = pOrderBy->a[i].pExpr;
  4906         -        if( (exprTableUsage(&pWInfo->sMaskSet, p)&~orderDistinctMask)==0 ){
         4907  +        mTerm = exprTableUsage(&pWInfo->sMaskSet,p);
         4908  +        if( mTerm==0 && !sqlite3ExprIsConstant(p) ) continue;
         4909  +        if( (mTerm&~orderDistinctMask)==0 ){
  4907   4910             obSat |= MASKBIT(i);
  4908   4911           }
  4909   4912         }
  4910   4913       }
  4911   4914     } /* End the loop over all WhereLoops from outer-most down to inner-most */
  4912   4915     if( obSat==obDone ) return 1;
  4913   4916     if( !isOrderDistinct ) return 0;
................................................................................
  5522   5525     ** and work forward so that the added virtual terms are never processed.
  5523   5526     */
  5524   5527     exprAnalyzeAll(pTabList, &pWInfo->sWC);
  5525   5528     if( db->mallocFailed ){
  5526   5529       goto whereBeginError;
  5527   5530     }
  5528   5531   
  5529         -  /* If the ORDER BY (or GROUP BY) clause contains references to general
  5530         -  ** expressions, then we won't be able to satisfy it using indices, so
  5531         -  ** go ahead and disable it now.
  5532         -  */
  5533         -  if( pOrderBy && (wctrlFlags & WHERE_WANT_DISTINCT)!=0 ){
  5534         -    for(ii=0; ii<pOrderBy->nExpr; ii++){
  5535         -      Expr *pExpr = sqlite3ExprSkipCollate(pOrderBy->a[ii].pExpr);
  5536         -      if( pExpr->op!=TK_COLUMN ){
  5537         -        pWInfo->pOrderBy = pOrderBy = 0;
  5538         -        break;
  5539         -      }else if( pExpr->iColumn<0 ){
  5540         -        break;
  5541         -      }
  5542         -    }
  5543         -  }
  5544         -
  5545   5532     if( wctrlFlags & WHERE_WANT_DISTINCT ){
  5546   5533       if( isDistinctRedundant(pParse, pTabList, &pWInfo->sWC, pResultSet) ){
  5547   5534         /* The DISTINCT marking is pointless.  Ignore it. */
  5548   5535         pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE;
  5549   5536       }else if( pOrderBy==0 ){
  5550   5537         /* Try to ORDER BY the result set to make distinct processing easier */
  5551   5538         pWInfo->wctrlFlags |= WHERE_DISTINCTBY;

Changes to test/shell5.test.

   280    280     catchcmd test.db {.mode csv
   281    281       CREATE TABLE t1(a,b,c,d);
   282    282   .import shell5.csv t1
   283    283     }
   284    284     sqlite3 db test.db
   285    285     db eval {SELECT hex(c) FROM t1 ORDER BY rowid}
   286    286   } {636F6C756D6E33 783320220D0A64617461222033 783320220A64617461222033}
          287  +
          288  +# Blank last column with \r\n line endings.
          289  +do_test shell5-1.11 {
          290  +  set out [open shell5.csv w]
          291  +  fconfigure $out -translation binary
          292  +  puts $out "column1,column2,column3\r"
          293  +  puts $out "a,b, \r"
          294  +  puts $out "x,y,\r"
          295  +  puts $out "p,q,r\r"
          296  +  close $out
          297  +  catch {db close}
          298  +  forcedelete test.db
          299  +  catchcmd test.db {.mode csv
          300  +.import shell5.csv t1
          301  +  }
          302  +  sqlite3 db test.db
          303  +  db eval {SELECT *, '|' FROM t1}
          304  +} {a b { } | x y {} | p q r |}
          305  +
   287    306   
   288    307   db close
   289    308   
   290    309   finish_test

Added test/tkt-8c63ff0ec.test.

            1  +# 2014-02-25
            2  +#
            3  +# The author disclaims copyright to this source code.  In place of
            4  +# a legal notice, here is a blessing:
            5  +#
            6  +#    May you do good and not evil.
            7  +#    May you find forgiveness for yourself and forgive others.
            8  +#    May you share freely, never taking more than you give.
            9  +#
           10  +#***********************************************************************
           11  +# 
           12  +# Test cases to show that ticket [8c63ff0eca81a9132d8d67b31cd6ae9712a2cc6f]
           13  +# "Incorrect query result on a UNION ALL" which was caused by using the same
           14  +# temporary register in concurrent co-routines, as been fixed.
           15  +# 
           16  +
           17  +
           18  +set testdir [file dirname $argv0]
           19  +source $testdir/tester.tcl
           20  +set ::testprefix tkt-8c63ff0ec
           21  +
           22  +do_execsql_test 1.1 {
           23  +  CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c, d, e);
           24  +  INSERT INTO t1 VALUES(1,20,30,40,50),(3,60,70,80,90);
           25  +  CREATE TABLE t2(x INTEGER PRIMARY KEY);
           26  +  INSERT INTO t2 VALUES(2);
           27  +  CREATE TABLE t3(z);
           28  +  INSERT INTO t3 VALUES(2),(2),(2),(2);
           29  +  
           30  +  SELECT a, b+c FROM t1
           31  +  UNION ALL
           32  +  SELECT x, 5 FROM t2 JOIN t3 ON z=x WHERE x=2
           33  +  ORDER BY a;
           34  +} {1 50 2 5 2 5 2 5 2 5 3 130}
           35  +do_execsql_test 1.2 {
           36  +  SELECT a, b+c+d FROM t1
           37  +  UNION ALL
           38  +  SELECT x, 5 FROM t2 JOIN t3 ON z=x WHERE x=2
           39  +  ORDER BY a;
           40  +} {1 90 2 5 2 5 2 5 2 5 3 210}
           41  +do_execsql_test 1.3 {
           42  +  SELECT a, b+c+d+e FROM t1
           43  +  UNION ALL
           44  +  SELECT x, 5 FROM t2 JOIN t3 ON z=x WHERE x=2
           45  +  ORDER BY a;
           46  +} {1 140 2 5 2 5 2 5 2 5 3 300}
           47  +
           48  +finish_test

Changes to test/where2.test.

   116    116     }
   117    117   } {85 6 7396 7402 sort t1 i1xy}
   118    118   do_test where2-2.3 {
   119    119     queryplan {
   120    120       SELECT * FROM t1 WHERE rowid=85 AND x=6 AND y=7396 ORDER BY random();
   121    121     }
   122    122   } {85 6 7396 7402 nosort t1 *}
          123  +
          124  +# Ticket [65bdeb9739605cc22966f49208452996ff29a640] 2014-02-26
          125  +# Make sure "ORDER BY random" does not gets optimized out.
          126  +#
          127  +do_test where2-2.4 {
          128  +  db eval {
          129  +    CREATE TABLE x1(a INTEGER PRIMARY KEY, b DEFAULT 1);
          130  +    WITH RECURSIVE
          131  +       cnt(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM cnt WHERE x<50)
          132  +    INSERT INTO x1 SELECT x, 1 FROM cnt;
          133  +    CREATE TABLE x2(x INTEGER PRIMARY KEY);
          134  +    INSERT INTO x2 VALUES(1);
          135  +  }
          136  +  set sql {SELECT * FROM x1, x2 WHERE x=1 ORDER BY random()}
          137  +  set out1 [db eval $sql]
          138  +  set out2 [db eval $sql]
          139  +  set out3 [db eval $sql]
          140  +  expr {$out1!=$out2 && $out2!=$out3}
          141  +} {1}
          142  +do_execsql_test where2-2.5 {
          143  +  -- random() is not optimized out
          144  +  EXPLAIN SELECT * FROM x1, x2 WHERE x=1 ORDER BY random();
          145  +} {/ random/}
          146  +do_execsql_test where2-2.5b {
          147  +  -- random() is not optimized out
          148  +  EXPLAIN SELECT * FROM x1, x2 WHERE x=1 ORDER BY random();
          149  +} {/ SorterOpen /}
          150  +do_execsql_test where2-2.6 {
          151  +  -- other constant functions are optimized out
          152  +  EXPLAIN SELECT * FROM x1, x2 WHERE x=1 ORDER BY abs(5);
          153  +} {~/ abs/}
          154  +do_execsql_test where2-2.6b {
          155  +  -- other constant functions are optimized out
          156  +  EXPLAIN SELECT * FROM x1, x2 WHERE x=1 ORDER BY abs(5);
          157  +} {~/ SorterOpen /}
          158  +
   123    159   
   124    160   
   125    161   # Efficient handling of forward and reverse table scans.
   126    162   #
   127    163   do_test where2-3.1 {
   128    164     queryplan {
   129    165       SELECT * FROM t1 ORDER BY rowid LIMIT 2