/ Check-in [8baef581]
Login

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

Overview
Comment:Merge the latest trunk enhancements into the sessions branch.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | sessions
Files: files | file ages | folders
SHA1: 8baef58170ff851d0c4387a6888f59b487b4f33c
User & Date: drh 2011-10-21 17:08:23
Context
2011-10-31
14:34
Merge in all changes found in the version 3.7.9 release candidate. check-in: 23580718 user: drh tags: sessions
2011-10-21
17:08
Merge the latest trunk enhancements into the sessions branch. check-in: 8baef581 user: drh tags: sessions
16:47
Remove stale requirements marks from the query planner. check-in: 76de9914 user: drh tags: trunk
2011-10-11
12:58
Merge all the latest trunk changes into the sessions branch - especially the SQLITE_ENABLE_STAT3 enhancements. check-in: 403431ca user: drh tags: sessions
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to ext/fts3/fts3.c.

   434    434   */
   435    435   static void fts3GetReverseVarint(
   436    436     char **pp, 
   437    437     char *pStart, 
   438    438     sqlite3_int64 *pVal
   439    439   ){
   440    440     sqlite3_int64 iVal;
   441         -  char *p = *pp;
          441  +  char *p;
   442    442   
   443    443     /* Pointer p now points at the first byte past the varint we are 
   444    444     ** interested in. So, unless the doclist is corrupt, the 0x80 bit is
   445    445     ** clear on character p[-1]. */
   446    446     for(p = (*pp)-2; p>=pStart && *p&0x80; p--);
   447    447     p++;
   448    448     *pp = p;
................................................................................
   464    464     /* Free any prepared statements held */
   465    465     for(i=0; i<SizeofArray(p->aStmt); i++){
   466    466       sqlite3_finalize(p->aStmt[i]);
   467    467     }
   468    468     sqlite3_free(p->zSegmentsTbl);
   469    469     sqlite3_free(p->zReadExprlist);
   470    470     sqlite3_free(p->zWriteExprlist);
          471  +  sqlite3_free(p->zContentTbl);
   471    472   
   472    473     /* Invoke the tokenizer destructor to free the tokenizer. */
   473    474     p->pTokenizer->pModule->xDestroy(p->pTokenizer);
   474    475   
   475    476     sqlite3_free(p);
   476    477     return SQLITE_OK;
   477    478   }
................................................................................
   503    504     }
   504    505   }
   505    506   
   506    507   /*
   507    508   ** The xDestroy() virtual table method.
   508    509   */
   509    510   static int fts3DestroyMethod(sqlite3_vtab *pVtab){
   510         -  int rc = SQLITE_OK;              /* Return code */
   511    511     Fts3Table *p = (Fts3Table *)pVtab;
   512         -  sqlite3 *db = p->db;
          512  +  int rc = SQLITE_OK;              /* Return code */
          513  +  const char *zDb = p->zDb;        /* Name of database (e.g. "main", "temp") */
          514  +  sqlite3 *db = p->db;             /* Database handle */
   513    515   
   514    516     /* Drop the shadow tables */
   515         -  fts3DbExec(&rc, db, "DROP TABLE IF EXISTS %Q.'%q_content'", p->zDb, p->zName);
   516         -  fts3DbExec(&rc, db, "DROP TABLE IF EXISTS %Q.'%q_segments'", p->zDb,p->zName);
   517         -  fts3DbExec(&rc, db, "DROP TABLE IF EXISTS %Q.'%q_segdir'", p->zDb, p->zName);
   518         -  fts3DbExec(&rc, db, "DROP TABLE IF EXISTS %Q.'%q_docsize'", p->zDb, p->zName);
   519         -  fts3DbExec(&rc, db, "DROP TABLE IF EXISTS %Q.'%q_stat'", p->zDb, p->zName);
          517  +  if( p->zContentTbl==0 ){
          518  +    fts3DbExec(&rc, db, "DROP TABLE IF EXISTS %Q.'%q_content'", zDb, p->zName);
          519  +  }
          520  +  fts3DbExec(&rc, db, "DROP TABLE IF EXISTS %Q.'%q_segments'", zDb,p->zName);
          521  +  fts3DbExec(&rc, db, "DROP TABLE IF EXISTS %Q.'%q_segdir'", zDb, p->zName);
          522  +  fts3DbExec(&rc, db, "DROP TABLE IF EXISTS %Q.'%q_docsize'", zDb, p->zName);
          523  +  fts3DbExec(&rc, db, "DROP TABLE IF EXISTS %Q.'%q_stat'", zDb, p->zName);
   520    524   
   521    525     /* If everything has worked, invoke fts3DisconnectMethod() to free the
   522    526     ** memory associated with the Fts3Table structure and return SQLITE_OK.
   523    527     ** Otherwise, return an SQLite error code.
   524    528     */
   525    529     return (rc==SQLITE_OK ? fts3DisconnectMethod(pVtab) : rc);
   526    530   }
................................................................................
   574    578   ** If the p->bHasDocsize boolean is true (indicating that this is an
   575    579   ** FTS4 table, not an FTS3 table) then also create the %_docsize and
   576    580   ** %_stat tables required by FTS4.
   577    581   */
   578    582   static int fts3CreateTables(Fts3Table *p){
   579    583     int rc = SQLITE_OK;             /* Return code */
   580    584     int i;                          /* Iterator variable */
   581         -  char *zContentCols;             /* Columns of %_content table */
   582    585     sqlite3 *db = p->db;            /* The database connection */
   583    586   
   584         -  /* Create a list of user columns for the content table */
   585         -  zContentCols = sqlite3_mprintf("docid INTEGER PRIMARY KEY");
   586         -  for(i=0; zContentCols && i<p->nColumn; i++){
   587         -    char *z = p->azColumn[i];
   588         -    zContentCols = sqlite3_mprintf("%z, 'c%d%q'", zContentCols, i, z);
          587  +  if( p->zContentTbl==0 ){
          588  +    char *zContentCols;           /* Columns of %_content table */
          589  +
          590  +    /* Create a list of user columns for the content table */
          591  +    zContentCols = sqlite3_mprintf("docid INTEGER PRIMARY KEY");
          592  +    for(i=0; zContentCols && i<p->nColumn; i++){
          593  +      char *z = p->azColumn[i];
          594  +      zContentCols = sqlite3_mprintf("%z, 'c%d%q'", zContentCols, i, z);
          595  +    }
          596  +    if( zContentCols==0 ) rc = SQLITE_NOMEM;
          597  +  
          598  +    /* Create the content table */
          599  +    fts3DbExec(&rc, db, 
          600  +       "CREATE TABLE %Q.'%q_content'(%s)",
          601  +       p->zDb, p->zName, zContentCols
          602  +    );
          603  +    sqlite3_free(zContentCols);
   589    604     }
   590         -  if( zContentCols==0 ) rc = SQLITE_NOMEM;
   591    605   
   592         -  /* Create the content table */
   593         -  fts3DbExec(&rc, db, 
   594         -     "CREATE TABLE %Q.'%q_content'(%s)",
   595         -     p->zDb, p->zName, zContentCols
   596         -  );
   597         -  sqlite3_free(zContentCols);
   598    606     /* Create other tables */
   599    607     fts3DbExec(&rc, db, 
   600    608         "CREATE TABLE %Q.'%q_segments'(blockid INTEGER PRIMARY KEY, block BLOB);",
   601    609         p->zDb, p->zName
   602    610     );
   603    611     fts3DbExec(&rc, db, 
   604    612         "CREATE TABLE %Q.'%q_segdir'("
................................................................................
   741    749       *(z++) = '"';
   742    750       *(z++) = '\0';
   743    751     }
   744    752     return zRet;
   745    753   }
   746    754   
   747    755   /*
   748         -** Return a list of comma separated SQL expressions that could be used
   749         -** in a SELECT statement such as the following:
          756  +** Return a list of comma separated SQL expressions and a FROM clause that 
          757  +** could be used in a SELECT statement such as the following:
   750    758   **
   751    759   **     SELECT <list of expressions> FROM %_content AS x ...
   752    760   **
   753    761   ** to return the docid, followed by each column of text data in order
   754    762   ** from left to write. If parameter zFunc is not NULL, then instead of
   755    763   ** being returned directly each column of text data is passed to an SQL
   756    764   ** function named zFunc first. For example, if zFunc is "unzip" and the
   757    765   ** table has the three user-defined columns "a", "b", and "c", the following
   758    766   ** string is returned:
   759    767   **
   760         -**     "docid, unzip(x.'a'), unzip(x.'b'), unzip(x.'c')"
          768  +**     "docid, unzip(x.'a'), unzip(x.'b'), unzip(x.'c') FROM %_content AS x"
   761    769   **
   762    770   ** The pointer returned points to a buffer allocated by sqlite3_malloc(). It
   763    771   ** is the responsibility of the caller to eventually free it.
   764    772   **
   765    773   ** If *pRc is not SQLITE_OK when this function is called, it is a no-op (and
   766    774   ** a NULL pointer is returned). Otherwise, if an OOM error is encountered
   767    775   ** by this function, NULL is returned and *pRc is set to SQLITE_NOMEM. If
................................................................................
   769    777   */
   770    778   static char *fts3ReadExprList(Fts3Table *p, const char *zFunc, int *pRc){
   771    779     char *zRet = 0;
   772    780     char *zFree = 0;
   773    781     char *zFunction;
   774    782     int i;
   775    783   
   776         -  if( !zFunc ){
   777         -    zFunction = "";
          784  +  if( p->zContentTbl==0 ){
          785  +    if( !zFunc ){
          786  +      zFunction = "";
          787  +    }else{
          788  +      zFree = zFunction = fts3QuoteId(zFunc);
          789  +    }
          790  +    fts3Appendf(pRc, &zRet, "docid");
          791  +    for(i=0; i<p->nColumn; i++){
          792  +      fts3Appendf(pRc, &zRet, ",%s(x.'c%d%q')", zFunction, i, p->azColumn[i]);
          793  +    }
          794  +    sqlite3_free(zFree);
   778    795     }else{
   779         -    zFree = zFunction = fts3QuoteId(zFunc);
          796  +    fts3Appendf(pRc, &zRet, "rowid");
          797  +    for(i=0; i<p->nColumn; i++){
          798  +      fts3Appendf(pRc, &zRet, ", x.'%q'", p->azColumn[i]);
          799  +    }
   780    800     }
   781         -  fts3Appendf(pRc, &zRet, "docid");
   782         -  for(i=0; i<p->nColumn; i++){
   783         -    fts3Appendf(pRc, &zRet, ",%s(x.'c%d%q')", zFunction, i, p->azColumn[i]);
   784         -  }
   785         -  sqlite3_free(zFree);
          801  +  fts3Appendf(pRc, &zRet, "FROM '%q'.'%q%s' AS x", 
          802  +      p->zDb,
          803  +      (p->zContentTbl ? p->zContentTbl : p->zName),
          804  +      (p->zContentTbl ? "" : "_content")
          805  +  );
   786    806     return zRet;
   787    807   }
   788    808   
   789    809   /*
   790    810   ** Return a list of N comma separated question marks, where N is the number
   791    811   ** of columns in the %_content table (one for the docid plus one for each
   792    812   ** user-defined text column).
................................................................................
   835    855   **
   836    856   ** If *pp does not being with a decimal digit SQLITE_ERROR is returned and
   837    857   ** the output value undefined. Otherwise SQLITE_OK is returned.
   838    858   **
   839    859   ** This function is used when parsing the "prefix=" FTS4 parameter.
   840    860   */
   841    861   static int fts3GobbleInt(const char **pp, int *pnOut){
   842         -  const char *p = *pp;            /* Iterator pointer */
          862  +  const char *p;                  /* Iterator pointer */
   843    863     int nInt = 0;                   /* Output value */
   844    864   
   845    865     for(p=*pp; p[0]>='0' && p[0]<='9'; p++){
   846    866       nInt = nInt * 10 + (p[0] - '0');
   847    867     }
   848    868     if( p==*pp ) return SQLITE_ERROR;
   849    869     *pnOut = nInt;
................................................................................
   901    921         aIndex[i].nPrefix = nPrefix;
   902    922         p++;
   903    923       }
   904    924     }
   905    925   
   906    926     return SQLITE_OK;
   907    927   }
          928  +
          929  +/*
          930  +** This function is called when initializing an FTS4 table that uses the
          931  +** content=xxx option. It determines the number of and names of the columns
          932  +** of the new FTS4 table.
          933  +**
          934  +** The third argument passed to this function is the value passed to the
          935  +** config=xxx option (i.e. "xxx"). This function queries the database for
          936  +** a table of that name. If found, the output variables are populated
          937  +** as follows:
          938  +**
          939  +**   *pnCol:   Set to the number of columns table xxx has,
          940  +**
          941  +**   *pnStr:   Set to the total amount of space required to store a copy
          942  +**             of each columns name, including the nul-terminator.
          943  +**
          944  +**   *pazCol:  Set to point to an array of *pnCol strings. Each string is
          945  +**             the name of the corresponding column in table xxx. The array
          946  +**             and its contents are allocated using a single allocation. It
          947  +**             is the responsibility of the caller to free this allocation
          948  +**             by eventually passing the *pazCol value to sqlite3_free().
          949  +**
          950  +** If the table cannot be found, an error code is returned and the output
          951  +** variables are undefined. Or, if an OOM is encountered, SQLITE_NOMEM is
          952  +** returned (and the output variables are undefined).
          953  +*/
          954  +static int fts3ContentColumns(
          955  +  sqlite3 *db,                    /* Database handle */
          956  +  const char *zDb,                /* Name of db (i.e. "main", "temp" etc.) */
          957  +  const char *zTbl,               /* Name of content table */
          958  +  const char ***pazCol,           /* OUT: Malloc'd array of column names */
          959  +  int *pnCol,                     /* OUT: Size of array *pazCol */
          960  +  int *pnStr                      /* OUT: Bytes of string content */
          961  +){
          962  +  int rc = SQLITE_OK;             /* Return code */
          963  +  char *zSql;                     /* "SELECT *" statement on zTbl */  
          964  +  sqlite3_stmt *pStmt = 0;        /* Compiled version of zSql */
          965  +
          966  +  zSql = sqlite3_mprintf("SELECT * FROM %Q.%Q", zDb, zTbl);
          967  +  if( !zSql ){
          968  +    rc = SQLITE_NOMEM;
          969  +  }else{
          970  +    rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0);
          971  +  }
          972  +  sqlite3_free(zSql);
          973  +
          974  +  if( rc==SQLITE_OK ){
          975  +    const char **azCol;           /* Output array */
          976  +    int nStr = 0;                 /* Size of all column names (incl. 0x00) */
          977  +    int nCol;                     /* Number of table columns */
          978  +    int i;                        /* Used to iterate through columns */
          979  +
          980  +    /* Loop through the returned columns. Set nStr to the number of bytes of
          981  +    ** space required to store a copy of each column name, including the
          982  +    ** nul-terminator byte.  */
          983  +    nCol = sqlite3_column_count(pStmt);
          984  +    for(i=0; i<nCol; i++){
          985  +      const char *zCol = sqlite3_column_name(pStmt, i);
          986  +      nStr += strlen(zCol) + 1;
          987  +    }
          988  +
          989  +    /* Allocate and populate the array to return. */
          990  +    azCol = (const char **)sqlite3_malloc(sizeof(char *) * nCol + nStr);
          991  +    if( azCol==0 ){
          992  +      rc = SQLITE_NOMEM;
          993  +    }else{
          994  +      char *p = (char *)&azCol[nCol];
          995  +      for(i=0; i<nCol; i++){
          996  +        const char *zCol = sqlite3_column_name(pStmt, i);
          997  +        int n = strlen(zCol)+1;
          998  +        memcpy(p, zCol, n);
          999  +        azCol[i] = p;
         1000  +        p += n;
         1001  +      }
         1002  +    }
         1003  +    sqlite3_finalize(pStmt);
         1004  +
         1005  +    /* Set the output variables. */
         1006  +    *pnCol = nCol;
         1007  +    *pnStr = nStr;
         1008  +    *pazCol = azCol;
         1009  +  }
         1010  +
         1011  +  return rc;
         1012  +}
   908   1013   
   909   1014   /*
   910   1015   ** This function is the implementation of both the xConnect and xCreate
   911   1016   ** methods of the FTS3 virtual table.
   912   1017   **
   913   1018   ** The argv[] array contains the following:
   914   1019   **
................................................................................
   946   1051   
   947   1052     /* The results of parsing supported FTS4 key=value options: */
   948   1053     int bNoDocsize = 0;             /* True to omit %_docsize table */
   949   1054     int bDescIdx = 0;               /* True to store descending indexes */
   950   1055     char *zPrefix = 0;              /* Prefix parameter value (or NULL) */
   951   1056     char *zCompress = 0;            /* compress=? parameter (or NULL) */
   952   1057     char *zUncompress = 0;          /* uncompress=? parameter (or NULL) */
         1058  +  char *zContent = 0;             /* content=? parameter (or NULL) */
   953   1059   
   954   1060     assert( strlen(argv[0])==4 );
   955   1061     assert( (sqlite3_strnicmp(argv[0], "fts4", 4)==0 && isFts4)
   956   1062          || (sqlite3_strnicmp(argv[0], "fts3", 4)==0 && !isFts4)
   957   1063     );
   958   1064   
   959   1065     nDb = (int)strlen(argv[1]) + 1;
................................................................................
   989   1095       }
   990   1096   
   991   1097       /* Check if it is an FTS4 special argument. */
   992   1098       else if( isFts4 && fts3IsSpecialColumn(z, &nKey, &zVal) ){
   993   1099         struct Fts4Option {
   994   1100           const char *zOpt;
   995   1101           int nOpt;
   996         -        char **pzVar;
   997   1102         } aFts4Opt[] = {
   998         -        { "matchinfo",   9, 0 },            /* 0 -> MATCHINFO */
   999         -        { "prefix",      6, 0 },            /* 1 -> PREFIX */
  1000         -        { "compress",    8, 0 },            /* 2 -> COMPRESS */
  1001         -        { "uncompress", 10, 0 },            /* 3 -> UNCOMPRESS */
  1002         -        { "order",       5, 0 }             /* 4 -> ORDER */
         1103  +        { "matchinfo",   9 },     /* 0 -> MATCHINFO */
         1104  +        { "prefix",      6 },     /* 1 -> PREFIX */
         1105  +        { "compress",    8 },     /* 2 -> COMPRESS */
         1106  +        { "uncompress", 10 },     /* 3 -> UNCOMPRESS */
         1107  +        { "order",       5 },     /* 4 -> ORDER */
         1108  +        { "content",     7 }      /* 5 -> CONTENT */
  1003   1109         };
  1004   1110   
  1005   1111         int iOpt;
  1006   1112         if( !zVal ){
  1007   1113           rc = SQLITE_NOMEM;
  1008   1114         }else{
  1009   1115           for(iOpt=0; iOpt<SizeofArray(aFts4Opt); iOpt++){
................................................................................
  1041   1147                 sqlite3_free(zUncompress);
  1042   1148                 zUncompress = zVal;
  1043   1149                 zVal = 0;
  1044   1150                 break;
  1045   1151   
  1046   1152               case 4:               /* ORDER */
  1047   1153                 if( (strlen(zVal)!=3 || sqlite3_strnicmp(zVal, "asc", 3)) 
  1048         -               && (strlen(zVal)!=4 || sqlite3_strnicmp(zVal, "desc", 3)) 
         1154  +               && (strlen(zVal)!=4 || sqlite3_strnicmp(zVal, "desc", 4)) 
  1049   1155                 ){
  1050   1156                   *pzErr = sqlite3_mprintf("unrecognized order: %s", zVal);
  1051   1157                   rc = SQLITE_ERROR;
  1052   1158                 }
  1053   1159                 bDescIdx = (zVal[0]=='d' || zVal[0]=='D');
  1054   1160                 break;
         1161  +
         1162  +            default:              /* CONTENT */
         1163  +              assert( iOpt==5 );
         1164  +              sqlite3_free(zUncompress);
         1165  +              zContent = zVal;
         1166  +              zVal = 0;
         1167  +              break;
  1055   1168             }
  1056   1169           }
  1057   1170           sqlite3_free(zVal);
  1058   1171         }
  1059   1172       }
  1060   1173   
  1061   1174       /* Otherwise, the argument is a column name. */
  1062   1175       else {
  1063   1176         nString += (int)(strlen(z) + 1);
  1064   1177         aCol[nCol++] = z;
  1065   1178       }
  1066   1179     }
         1180  +
         1181  +  /* If a content=xxx option was specified, the following:
         1182  +  **
         1183  +  **   1. Ignore any compress= and uncompress= options.
         1184  +  **
         1185  +  **   2. If no column names were specified as part of the CREATE VIRTUAL
         1186  +  **      TABLE statement, use all columns from the content table.
         1187  +  */
         1188  +  if( rc==SQLITE_OK && zContent ){
         1189  +    sqlite3_free(zCompress); 
         1190  +    sqlite3_free(zUncompress); 
         1191  +    zCompress = 0;
         1192  +    zUncompress = 0;
         1193  +    if( nCol==0 ){
         1194  +      sqlite3_free((void*)aCol); 
         1195  +      aCol = 0;
         1196  +      rc = fts3ContentColumns(db, argv[1], zContent, &aCol, &nCol, &nString);
         1197  +    }
         1198  +    assert( rc!=SQLITE_OK || nCol>0 );
         1199  +  }
  1067   1200     if( rc!=SQLITE_OK ) goto fts3_init_out;
  1068   1201   
  1069   1202     if( nCol==0 ){
  1070   1203       assert( nString==0 );
  1071   1204       aCol[0] = "content";
  1072   1205       nString = 8;
  1073   1206       nCol = 1;
................................................................................
  1104   1237     p->nPendingData = 0;
  1105   1238     p->azColumn = (char **)&p[1];
  1106   1239     p->pTokenizer = pTokenizer;
  1107   1240     p->nMaxPendingData = FTS3_MAX_PENDING_DATA;
  1108   1241     p->bHasDocsize = (isFts4 && bNoDocsize==0);
  1109   1242     p->bHasStat = isFts4;
  1110   1243     p->bDescIdx = bDescIdx;
         1244  +  p->zContentTbl = zContent;
         1245  +  zContent = 0;
  1111   1246     TESTONLY( p->inTransaction = -1 );
  1112   1247     TESTONLY( p->mxSavepoint = -1 );
  1113   1248   
  1114   1249     p->aIndex = (struct Fts3Index *)&p->azColumn[nCol];
  1115   1250     memcpy(p->aIndex, aIndex, sizeof(struct Fts3Index) * nIndex);
  1116   1251     p->nIndex = nIndex;
  1117   1252     for(i=0; i<nIndex; i++){
................................................................................
  1165   1300     fts3DeclareVtab(&rc, p);
  1166   1301   
  1167   1302   fts3_init_out:
  1168   1303     sqlite3_free(zPrefix);
  1169   1304     sqlite3_free(aIndex);
  1170   1305     sqlite3_free(zCompress);
  1171   1306     sqlite3_free(zUncompress);
         1307  +  sqlite3_free(zContent);
  1172   1308     sqlite3_free((void *)aCol);
  1173   1309     if( rc!=SQLITE_OK ){
  1174   1310       if( p ){
  1175   1311         fts3DisconnectMethod((sqlite3_vtab *)p);
  1176   1312       }else if( pTokenizer ){
  1177   1313         pTokenizer->pModule->xDestroy(pTokenizer);
  1178   1314       }
................................................................................
  1315   1451     sqlite3Fts3FreeDeferredTokens(pCsr);
  1316   1452     sqlite3_free(pCsr->aDoclist);
  1317   1453     sqlite3_free(pCsr->aMatchinfo);
  1318   1454     assert( ((Fts3Table *)pCsr->base.pVtab)->pSegments==0 );
  1319   1455     sqlite3_free(pCsr);
  1320   1456     return SQLITE_OK;
  1321   1457   }
         1458  +
         1459  +/*
         1460  +** If pCsr->pStmt has not been prepared (i.e. if pCsr->pStmt==0), then
         1461  +** compose and prepare an SQL statement of the form:
         1462  +**
         1463  +**    "SELECT <columns> FROM %_content WHERE rowid = ?"
         1464  +**
         1465  +** (or the equivalent for a content=xxx table) and set pCsr->pStmt to
         1466  +** it. If an error occurs, return an SQLite error code.
         1467  +**
         1468  +** Otherwise, set *ppStmt to point to pCsr->pStmt and return SQLITE_OK.
         1469  +*/
         1470  +static int fts3CursorSeekStmt(Fts3Cursor *pCsr, sqlite3_stmt **ppStmt){
         1471  +  int rc = SQLITE_OK;
         1472  +  if( pCsr->pStmt==0 ){
         1473  +    Fts3Table *p = (Fts3Table *)pCsr->base.pVtab;
         1474  +    char *zSql;
         1475  +    zSql = sqlite3_mprintf("SELECT %s WHERE rowid = ?", p->zReadExprlist);
         1476  +    if( !zSql ) return SQLITE_NOMEM;
         1477  +    rc = sqlite3_prepare_v2(p->db, zSql, -1, &pCsr->pStmt, 0);
         1478  +    sqlite3_free(zSql);
         1479  +  }
         1480  +  *ppStmt = pCsr->pStmt;
         1481  +  return rc;
         1482  +}
  1322   1483   
  1323   1484   /*
  1324   1485   ** Position the pCsr->pStmt statement so that it is on the row
  1325   1486   ** of the %_content table that contains the last match.  Return
  1326   1487   ** SQLITE_OK on success.  
  1327   1488   */
  1328   1489   static int fts3CursorSeek(sqlite3_context *pContext, Fts3Cursor *pCsr){
         1490  +  int rc = SQLITE_OK;
  1329   1491     if( pCsr->isRequireSeek ){
  1330         -    sqlite3_bind_int64(pCsr->pStmt, 1, pCsr->iPrevId);
  1331         -    pCsr->isRequireSeek = 0;
  1332         -    if( SQLITE_ROW==sqlite3_step(pCsr->pStmt) ){
  1333         -      return SQLITE_OK;
  1334         -    }else{
  1335         -      int rc = sqlite3_reset(pCsr->pStmt);
  1336         -      if( rc==SQLITE_OK ){
  1337         -        /* If no row was found and no error has occured, then the %_content
  1338         -        ** table is missing a row that is present in the full-text index.
  1339         -        ** The data structures are corrupt.
  1340         -        */
  1341         -        rc = SQLITE_CORRUPT_VTAB;
  1342         -      }
  1343         -      pCsr->isEof = 1;
  1344         -      if( pContext ){
  1345         -        sqlite3_result_error_code(pContext, rc);
  1346         -      }
  1347         -      return rc;
  1348         -    }
  1349         -  }else{
  1350         -    return SQLITE_OK;
  1351         -  }
         1492  +    sqlite3_stmt *pStmt = 0;
         1493  +
         1494  +    rc = fts3CursorSeekStmt(pCsr, &pStmt);
         1495  +    if( rc==SQLITE_OK ){
         1496  +      sqlite3_bind_int64(pCsr->pStmt, 1, pCsr->iPrevId);
         1497  +      pCsr->isRequireSeek = 0;
         1498  +      if( SQLITE_ROW==sqlite3_step(pCsr->pStmt) ){
         1499  +        return SQLITE_OK;
         1500  +      }else{
         1501  +        rc = sqlite3_reset(pCsr->pStmt);
         1502  +        if( rc==SQLITE_OK && ((Fts3Table *)pCsr->base.pVtab)->zContentTbl==0 ){
         1503  +          /* If no row was found and no error has occured, then the %_content
         1504  +          ** table is missing a row that is present in the full-text index.
         1505  +          ** The data structures are corrupt.  */
         1506  +          rc = FTS_CORRUPT_VTAB;
         1507  +          pCsr->isEof = 1;
         1508  +        }
         1509  +      }
         1510  +    }
         1511  +  }
         1512  +
         1513  +  if( rc!=SQLITE_OK && pContext ){
         1514  +    sqlite3_result_error_code(pContext, rc);
         1515  +  }
         1516  +  return rc;
  1352   1517   }
  1353   1518   
  1354   1519   /*
  1355   1520   ** This function is used to process a single interior node when searching
  1356   1521   ** a b-tree for a term or term prefix. The node data is passed to this 
  1357   1522   ** function via the zNode/nNode parameters. The term to search for is
  1358   1523   ** passed in zTerm/nTerm.
................................................................................
  1394   1559     ** contents, or two zero bytes. Or, if the node is read from the %_segments
  1395   1560     ** table, then there are always 20 bytes of zeroed padding following the
  1396   1561     ** nNode bytes of content (see sqlite3Fts3ReadBlock() for details).
  1397   1562     */
  1398   1563     zCsr += sqlite3Fts3GetVarint(zCsr, &iChild);
  1399   1564     zCsr += sqlite3Fts3GetVarint(zCsr, &iChild);
  1400   1565     if( zCsr>zEnd ){
  1401         -    return SQLITE_CORRUPT_VTAB;
         1566  +    return FTS_CORRUPT_VTAB;
  1402   1567     }
  1403   1568     
  1404   1569     while( zCsr<zEnd && (piFirst || piLast) ){
  1405   1570       int cmp;                      /* memcmp() result */
  1406   1571       int nSuffix;                  /* Size of term suffix */
  1407   1572       int nPrefix = 0;              /* Size of term prefix */
  1408   1573       int nBuffer;                  /* Total term size */
................................................................................
  1412   1577       if( !isFirstTerm ){
  1413   1578         zCsr += sqlite3Fts3GetVarint32(zCsr, &nPrefix);
  1414   1579       }
  1415   1580       isFirstTerm = 0;
  1416   1581       zCsr += sqlite3Fts3GetVarint32(zCsr, &nSuffix);
  1417   1582       
  1418   1583       if( nPrefix<0 || nSuffix<0 || &zCsr[nSuffix]>zEnd ){
  1419         -      rc = SQLITE_CORRUPT_VTAB;
         1584  +      rc = FTS_CORRUPT_VTAB;
  1420   1585         goto finish_scan;
  1421   1586       }
  1422   1587       if( nPrefix+nSuffix>nAlloc ){
  1423   1588         char *zNew;
  1424   1589         nAlloc = (nPrefix+nSuffix) * 2;
  1425   1590         zNew = (char *)sqlite3_realloc(zBuffer, nAlloc);
  1426   1591         if( !zNew ){
  1427   1592           rc = SQLITE_NOMEM;
  1428   1593           goto finish_scan;
  1429   1594         }
  1430   1595         zBuffer = zNew;
  1431   1596       }
         1597  +    assert( zBuffer );
  1432   1598       memcpy(&zBuffer[nPrefix], zCsr, nSuffix);
  1433   1599       nBuffer = nPrefix + nSuffix;
  1434   1600       zCsr += nSuffix;
  1435   1601   
  1436   1602       /* Compare the term we are searching for with the term just loaded from
  1437   1603       ** the interior node. If the specified term is greater than or equal
  1438   1604       ** to the term from the interior node, then all terms on the sub-tree 
................................................................................
  1783   1949     char **pp,                      /* IN/OUT: Preallocated output buffer */
  1784   1950     int nToken,                     /* Maximum difference in token positions */
  1785   1951     int isSaveLeft,                 /* Save the left position */
  1786   1952     int isExact,                    /* If *pp1 is exactly nTokens before *pp2 */
  1787   1953     char **pp1,                     /* IN/OUT: Left input list */
  1788   1954     char **pp2                      /* IN/OUT: Right input list */
  1789   1955   ){
  1790         -  char *p = (pp ? *pp : 0);
         1956  +  char *p = *pp;
  1791   1957     char *p1 = *pp1;
  1792   1958     char *p2 = *pp2;
  1793   1959     int iCol1 = 0;
  1794   1960     int iCol2 = 0;
  1795   1961   
  1796   1962     /* Never set both isSaveLeft and isExact for the same invocation. */
  1797   1963     assert( isSaveLeft==0 || isExact==0 );
  1798   1964   
  1799         -  assert( *p1!=0 && *p2!=0 );
         1965  +  assert( p!=0 && *p1!=0 && *p2!=0 );
  1800   1966     if( *p1==POS_COLUMN ){ 
  1801   1967       p1++;
  1802   1968       p1 += sqlite3Fts3GetVarint32(p1, &iCol1);
  1803   1969     }
  1804   1970     if( *p2==POS_COLUMN ){ 
  1805   1971       p2++;
  1806   1972       p2 += sqlite3Fts3GetVarint32(p2, &iCol2);
................................................................................
  1809   1975     while( 1 ){
  1810   1976       if( iCol1==iCol2 ){
  1811   1977         char *pSave = p;
  1812   1978         sqlite3_int64 iPrev = 0;
  1813   1979         sqlite3_int64 iPos1 = 0;
  1814   1980         sqlite3_int64 iPos2 = 0;
  1815   1981   
  1816         -      if( pp && iCol1 ){
         1982  +      if( iCol1 ){
  1817   1983           *p++ = POS_COLUMN;
  1818   1984           p += sqlite3Fts3PutVarint(p, iCol1);
  1819   1985         }
  1820   1986   
  1821   1987         assert( *p1!=POS_END && *p1!=POS_COLUMN );
  1822   1988         assert( *p2!=POS_END && *p2!=POS_COLUMN );
  1823   1989         fts3GetDeltaVarint(&p1, &iPos1); iPos1 -= 2;
................................................................................
  1824   1990         fts3GetDeltaVarint(&p2, &iPos2); iPos2 -= 2;
  1825   1991   
  1826   1992         while( 1 ){
  1827   1993           if( iPos2==iPos1+nToken 
  1828   1994            || (isExact==0 && iPos2>iPos1 && iPos2<=iPos1+nToken) 
  1829   1995           ){
  1830   1996             sqlite3_int64 iSave;
  1831         -          if( !pp ){
  1832         -            fts3PoslistCopy(0, &p2);
  1833         -            fts3PoslistCopy(0, &p1);
  1834         -            *pp1 = p1;
  1835         -            *pp2 = p2;
  1836         -            return 1;
  1837         -          }
  1838   1997             iSave = isSaveLeft ? iPos1 : iPos2;
  1839   1998             fts3PutDeltaVarint(&p, &iPrev, iSave+2); iPrev -= 2;
  1840   1999             pSave = 0;
         2000  +          assert( p );
  1841   2001           }
  1842   2002           if( (!isSaveLeft && iPos2<=(iPos1+nToken)) || iPos2<=iPos1 ){
  1843   2003             if( (*p2&0xFE)==0 ) break;
  1844   2004             fts3GetDeltaVarint(&p2, &iPos2); iPos2 -= 2;
  1845   2005           }else{
  1846   2006             if( (*p1&0xFE)==0 ) break;
  1847   2007             fts3GetDeltaVarint(&p1, &iPos1); iPos1 -= 2;
................................................................................
  1882   2042       }
  1883   2043     }
  1884   2044   
  1885   2045     fts3PoslistCopy(0, &p2);
  1886   2046     fts3PoslistCopy(0, &p1);
  1887   2047     *pp1 = p1;
  1888   2048     *pp2 = p2;
  1889         -  if( !pp || *pp==p ){
         2049  +  if( *pp==p ){
  1890   2050       return 0;
  1891   2051     }
  1892   2052     *p++ = 0x00;
  1893   2053     *pp = p;
  1894   2054     return 1;
  1895   2055   }
  1896   2056   
................................................................................
  2184   2344         fts3PoslistCopy(0, &p2);
  2185   2345         fts3GetDeltaVarint3(&p2, pEnd2, bDescDoclist, &i2);
  2186   2346       }
  2187   2347     }
  2188   2348   
  2189   2349     *pnRight = p - aOut;
  2190   2350   }
         2351  +
         2352  +/*
         2353  +** Argument pList points to a position list nList bytes in size. This
         2354  +** function checks to see if the position list contains any entries for
         2355  +** a token in position 0 (of any column). If so, it writes argument iDelta
         2356  +** to the output buffer pOut, followed by a position list consisting only
         2357  +** of the entries from pList at position 0, and terminated by an 0x00 byte.
         2358  +** The value returned is the number of bytes written to pOut (if any).
         2359  +*/
         2360  +int sqlite3Fts3FirstFilter(
         2361  +  sqlite3_int64 iDelta,           /* Varint that may be written to pOut */
         2362  +  char *pList,                    /* Position list (no 0x00 term) */
         2363  +  int nList,                      /* Size of pList in bytes */
         2364  +  char *pOut                      /* Write output here */
         2365  +){
         2366  +  int nOut = 0;
         2367  +  int bWritten = 0;               /* True once iDelta has been written */
         2368  +  char *p = pList;
         2369  +  char *pEnd = &pList[nList];
         2370  +
         2371  +  if( *p!=0x01 ){
         2372  +    if( *p==0x02 ){
         2373  +      nOut += sqlite3Fts3PutVarint(&pOut[nOut], iDelta);
         2374  +      pOut[nOut++] = 0x02;
         2375  +      bWritten = 1;
         2376  +    }
         2377  +    fts3ColumnlistCopy(0, &p);
         2378  +  }
         2379  +
         2380  +  while( p<pEnd && *p==0x01 ){
         2381  +    sqlite3_int64 iCol;
         2382  +    p++;
         2383  +    p += sqlite3Fts3GetVarint(p, &iCol);
         2384  +    if( *p==0x02 ){
         2385  +      if( bWritten==0 ){
         2386  +        nOut += sqlite3Fts3PutVarint(&pOut[nOut], iDelta);
         2387  +        bWritten = 1;
         2388  +      }
         2389  +      pOut[nOut++] = 0x01;
         2390  +      nOut += sqlite3Fts3PutVarint(&pOut[nOut], iCol);
         2391  +      pOut[nOut++] = 0x02;
         2392  +    }
         2393  +    fts3ColumnlistCopy(0, &p);
         2394  +  }
         2395  +  if( bWritten ){
         2396  +    pOut[nOut++] = 0x00;
         2397  +  }
         2398  +
         2399  +  return nOut;
         2400  +}
  2191   2401   
  2192   2402   
  2193   2403   /*
  2194   2404   ** Merge all doclists in the TermSelect.aaOutput[] array into a single
  2195   2405   ** doclist stored in TermSelect.aaOutput[0]. If successful, delete all
  2196   2406   ** other doclists (except the aaOutput[0] one) and return SQLITE_OK.
  2197   2407   **
................................................................................
  2541   2751     Fts3SegFilter filter;           /* Segment term filter configuration */
  2542   2752   
  2543   2753     pSegcsr = pTok->pSegcsr;
  2544   2754     memset(&tsc, 0, sizeof(TermSelect));
  2545   2755   
  2546   2756     filter.flags = FTS3_SEGMENT_IGNORE_EMPTY | FTS3_SEGMENT_REQUIRE_POS
  2547   2757           | (pTok->isPrefix ? FTS3_SEGMENT_PREFIX : 0)
         2758  +        | (pTok->bFirst ? FTS3_SEGMENT_FIRST : 0)
  2548   2759           | (iColumn<p->nColumn ? FTS3_SEGMENT_COLUMN_FILTER : 0);
  2549   2760     filter.iCol = iColumn;
  2550   2761     filter.zTerm = pTok->z;
  2551   2762     filter.nTerm = pTok->n;
  2552   2763   
  2553   2764     rc = sqlite3Fts3SegReaderStart(p, pSegcsr, &filter);
  2554   2765     while( SQLITE_OK==rc
................................................................................
  2681   2892       int iCol = idxNum-FTS3_FULLTEXT_SEARCH;
  2682   2893       const char *zQuery = (const char *)sqlite3_value_text(apVal[0]);
  2683   2894   
  2684   2895       if( zQuery==0 && sqlite3_value_type(apVal[0])!=SQLITE_NULL ){
  2685   2896         return SQLITE_NOMEM;
  2686   2897       }
  2687   2898   
  2688         -    rc = sqlite3Fts3ExprParse(p->pTokenizer, p->azColumn, p->nColumn, 
  2689         -        iCol, zQuery, -1, &pCsr->pExpr
         2899  +    rc = sqlite3Fts3ExprParse(p->pTokenizer, p->azColumn, p->bHasStat, 
         2900  +        p->nColumn, iCol, zQuery, -1, &pCsr->pExpr
  2690   2901       );
  2691   2902       if( rc!=SQLITE_OK ){
  2692   2903         if( rc==SQLITE_ERROR ){
  2693   2904           static const char *zErr = "malformed MATCH expression: [%s]";
  2694   2905           p->base.zErrMsg = sqlite3_mprintf(zErr, zQuery);
  2695   2906         }
  2696   2907         return rc;
................................................................................
  2709   2920   
  2710   2921     /* Compile a SELECT statement for this cursor. For a full-table-scan, the
  2711   2922     ** statement loops through all rows of the %_content table. For a
  2712   2923     ** full-text query or docid lookup, the statement retrieves a single
  2713   2924     ** row by docid.
  2714   2925     */
  2715   2926     if( idxNum==FTS3_FULLSCAN_SEARCH ){
  2716         -    const char *zSort = (pCsr->bDesc ? "DESC" : "ASC");
  2717         -    const char *zTmpl = "SELECT %s FROM %Q.'%q_content' AS x ORDER BY docid %s";
  2718         -    zSql = sqlite3_mprintf(zTmpl, p->zReadExprlist, p->zDb, p->zName, zSort);
  2719         -  }else{
  2720         -    const char *zTmpl = "SELECT %s FROM %Q.'%q_content' AS x WHERE docid = ?";
  2721         -    zSql = sqlite3_mprintf(zTmpl, p->zReadExprlist, p->zDb, p->zName);
         2927  +    zSql = sqlite3_mprintf(
         2928  +        "SELECT %s ORDER BY rowid %s",
         2929  +        p->zReadExprlist, (pCsr->bDesc ? "DESC" : "ASC")
         2930  +    );
         2931  +    if( zSql ){
         2932  +      rc = sqlite3_prepare_v2(p->db, zSql, -1, &pCsr->pStmt, 0);
         2933  +      sqlite3_free(zSql);
         2934  +    }else{
         2935  +      rc = SQLITE_NOMEM;
         2936  +    }
         2937  +  }else if( idxNum==FTS3_DOCID_SEARCH ){
         2938  +    rc = fts3CursorSeekStmt(pCsr, &pCsr->pStmt);
         2939  +    if( rc==SQLITE_OK ){
         2940  +      rc = sqlite3_bind_value(pCsr->pStmt, 1, apVal[0]);
         2941  +    }
  2722   2942     }
  2723         -  if( !zSql ) return SQLITE_NOMEM;
  2724         -  rc = sqlite3_prepare_v2(p->db, zSql, -1, &pCsr->pStmt, 0);
  2725         -  sqlite3_free(zSql);
  2726   2943     if( rc!=SQLITE_OK ) return rc;
  2727   2944   
  2728         -  if( idxNum==FTS3_DOCID_SEARCH ){
  2729         -    rc = sqlite3_bind_value(pCsr->pStmt, 1, apVal[0]);
  2730         -    if( rc!=SQLITE_OK ) return rc;
  2731         -  }
  2732         -
  2733   2945     return fts3NextMethod(pCursor);
  2734   2946   }
  2735   2947   
  2736   2948   /* 
  2737   2949   ** This is the xEof method of the virtual table. SQLite calls this 
  2738   2950   ** routine to find out if it has reached the end of a result set.
  2739   2951   */
................................................................................
  2777   2989     }else if( iCol==p->nColumn ){
  2778   2990       /* The extra column whose name is the same as the table.
  2779   2991       ** Return a blob which is a pointer to the cursor.
  2780   2992       */
  2781   2993       sqlite3_result_blob(pContext, &pCsr, sizeof(pCsr), SQLITE_TRANSIENT);
  2782   2994     }else{
  2783   2995       rc = fts3CursorSeek(0, pCsr);
  2784         -    if( rc==SQLITE_OK ){
         2996  +    if( rc==SQLITE_OK && sqlite3_data_count(pCsr->pStmt)>(iCol+1) ){
  2785   2997         sqlite3_result_value(pContext, sqlite3_column_value(pCsr->pStmt, iCol+1));
  2786   2998       }
  2787   2999     }
  2788   3000   
  2789   3001     assert( ((Fts3Table *)pCsr->base.pVtab)->pSegments==0 );
  2790   3002     return rc;
  2791   3003   }
................................................................................
  2861   3073   ** When called, *ppPoslist must point to the byte immediately following the
  2862   3074   ** end of a position-list. i.e. ( (*ppPoslist)[-1]==POS_END ). This function
  2863   3075   ** moves *ppPoslist so that it instead points to the first byte of the
  2864   3076   ** same position list.
  2865   3077   */
  2866   3078   static void fts3ReversePoslist(char *pStart, char **ppPoslist){
  2867   3079     char *p = &(*ppPoslist)[-2];
  2868         -  char c;
         3080  +  char c = 0;
  2869   3081   
  2870   3082     while( p>pStart && (c=*p--)==0 );
  2871   3083     while( p>pStart && (*p & 0x80) | c ){ 
  2872   3084       c = *p--; 
  2873   3085     }
  2874   3086     if( p>pStart ){ p = &p[2]; }
  2875   3087     while( *p++&0x80 );
................................................................................
  3070   3282     sqlite3_vtab *pVtab,            /* Virtual table handle */
  3071   3283     const char *zName               /* New name of table */
  3072   3284   ){
  3073   3285     Fts3Table *p = (Fts3Table *)pVtab;
  3074   3286     sqlite3 *db = p->db;            /* Database connection */
  3075   3287     int rc;                         /* Return Code */
  3076   3288   
         3289  +  /* As it happens, the pending terms table is always empty here. This is
         3290  +  ** because an "ALTER TABLE RENAME TABLE" statement inside a transaction 
         3291  +  ** always opens a savepoint transaction. And the xSavepoint() method 
         3292  +  ** flushes the pending terms table. But leave the (no-op) call to
         3293  +  ** PendingTermsFlush() in in case that changes.
         3294  +  */
         3295  +  assert( p->nPendingData==0 );
  3077   3296     rc = sqlite3Fts3PendingTermsFlush(p);
  3078         -  if( rc!=SQLITE_OK ){
  3079         -    return rc;
         3297  +
         3298  +  if( p->zContentTbl==0 ){
         3299  +    fts3DbExec(&rc, db,
         3300  +      "ALTER TABLE %Q.'%q_content'  RENAME TO '%q_content';",
         3301  +      p->zDb, p->zName, zName
         3302  +    );
  3080   3303     }
  3081   3304   
  3082         -  fts3DbExec(&rc, db,
  3083         -    "ALTER TABLE %Q.'%q_content'  RENAME TO '%q_content';",
  3084         -    p->zDb, p->zName, zName
  3085         -  );
  3086   3305     if( p->bHasDocsize ){
  3087   3306       fts3DbExec(&rc, db,
  3088   3307         "ALTER TABLE %Q.'%q_docsize'  RENAME TO '%q_docsize';",
  3089   3308         p->zDb, p->zName, zName
  3090   3309       );
  3091   3310     }
  3092   3311     if( p->bHasStat ){
................................................................................
  3437   3656   ** means that the phrase does not appear in the current row, doclist.pList
  3438   3657   ** and doclist.nList are both zeroed.
  3439   3658   **
  3440   3659   ** SQLITE_OK is returned if no error occurs, otherwise an SQLite error code.
  3441   3660   */
  3442   3661   static int fts3EvalDeferredPhrase(Fts3Cursor *pCsr, Fts3Phrase *pPhrase){
  3443   3662     int iToken;                     /* Used to iterate through phrase tokens */
  3444         -  int rc = SQLITE_OK;             /* Return code */
  3445   3663     char *aPoslist = 0;             /* Position list for deferred tokens */
  3446   3664     int nPoslist = 0;               /* Number of bytes in aPoslist */
  3447   3665     int iPrev = -1;                 /* Token number of previous deferred token */
  3448   3666   
  3449   3667     assert( pPhrase->doclist.bFreeList==0 );
  3450   3668   
  3451         -  for(iToken=0; rc==SQLITE_OK && iToken<pPhrase->nToken; iToken++){
         3669  +  for(iToken=0; iToken<pPhrase->nToken; iToken++){
  3452   3670       Fts3PhraseToken *pToken = &pPhrase->aToken[iToken];
  3453   3671       Fts3DeferredToken *pDeferred = pToken->pDeferred;
  3454   3672   
  3455   3673       if( pDeferred ){
  3456   3674         char *pList;
  3457   3675         int nList;
  3458         -      rc = sqlite3Fts3DeferredTokenList(pDeferred, &pList, &nList);
         3676  +      int rc = sqlite3Fts3DeferredTokenList(pDeferred, &pList, &nList);
  3459   3677         if( rc!=SQLITE_OK ) return rc;
  3460   3678   
  3461   3679         if( pList==0 ){
  3462   3680           sqlite3_free(aPoslist);
  3463   3681           pPhrase->doclist.pList = 0;
  3464   3682           pPhrase->doclist.nList = 0;
  3465   3683           return SQLITE_OK;
................................................................................
  3552   3770     Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab;
  3553   3771   
  3554   3772     if( pCsr->bDesc==pTab->bDescIdx 
  3555   3773      && bOptOk==1 
  3556   3774      && p->nToken==1 
  3557   3775      && pFirst->pSegcsr 
  3558   3776      && pFirst->pSegcsr->bLookup 
         3777  +   && pFirst->bFirst==0
  3559   3778     ){
  3560   3779       /* Use the incremental approach. */
  3561   3780       int iCol = (p->iColumn >= pTab->nColumn ? -1 : p->iColumn);
  3562   3781       rc = sqlite3Fts3MsrIncrStart(
  3563   3782           pTab, pFirst->pSegcsr, iCol, pFirst->z, pFirst->n);
  3564   3783       p->bIncr = 1;
  3565   3784   
................................................................................
  3781   4000     Fts3Cursor *pCsr,               /* FTS Cursor handle */
  3782   4001     Fts3Expr *pRoot,                /* Root of current AND/NEAR cluster */
  3783   4002     Fts3Expr *pExpr,                /* Expression to consider */
  3784   4003     Fts3TokenAndCost **ppTC,        /* Write new entries to *(*ppTC)++ */
  3785   4004     Fts3Expr ***ppOr,               /* Write new OR root to *(*ppOr)++ */
  3786   4005     int *pRc                        /* IN/OUT: Error code */
  3787   4006   ){
  3788         -  if( *pRc==SQLITE_OK && pExpr ){
         4007  +  if( *pRc==SQLITE_OK ){
  3789   4008       if( pExpr->eType==FTSQUERY_PHRASE ){
  3790   4009         Fts3Phrase *pPhrase = pExpr->pPhrase;
  3791   4010         int i;
  3792   4011         for(i=0; *pRc==SQLITE_OK && i<pPhrase->nToken; i++){
  3793   4012           Fts3TokenAndCost *pTC = (*ppTC)++;
  3794   4013           pTC->pPhrase = pPhrase;
  3795   4014           pTC->iToken = i;
  3796   4015           pTC->pRoot = pRoot;
  3797   4016           pTC->pToken = &pPhrase->aToken[i];
  3798   4017           pTC->iCol = pPhrase->iColumn;
  3799   4018           *pRc = sqlite3Fts3MsrOvfl(pCsr, pTC->pToken->pSegcsr, &pTC->nOvfl);
  3800   4019         }
  3801   4020       }else if( pExpr->eType!=FTSQUERY_NOT ){
         4021  +      assert( pExpr->eType==FTSQUERY_OR
         4022  +           || pExpr->eType==FTSQUERY_AND
         4023  +           || pExpr->eType==FTSQUERY_NEAR
         4024  +      );
         4025  +      assert( pExpr->pLeft && pExpr->pRight );
  3802   4026         if( pExpr->eType==FTSQUERY_OR ){
  3803   4027           pRoot = pExpr->pLeft;
  3804   4028           **ppOr = pRoot;
  3805   4029           (*ppOr)++;
  3806   4030         }
  3807   4031         fts3EvalTokenCosts(pCsr, pRoot, pExpr->pLeft, ppTC, ppOr, pRc);
  3808   4032         if( pExpr->eType==FTSQUERY_OR ){
................................................................................
  3855   4079       pEnd = &a[sqlite3_column_bytes(pStmt, 0)];
  3856   4080       a += sqlite3Fts3GetVarint(a, &nDoc);
  3857   4081       while( a<pEnd ){
  3858   4082         a += sqlite3Fts3GetVarint(a, &nByte);
  3859   4083       }
  3860   4084       if( nDoc==0 || nByte==0 ){
  3861   4085         sqlite3_reset(pStmt);
  3862         -      return SQLITE_CORRUPT_VTAB;
         4086  +      return FTS_CORRUPT_VTAB;
  3863   4087       }
  3864   4088   
  3865   4089       pCsr->nDoc = nDoc;
  3866   4090       pCsr->nRowAvg = (int)(((nByte / nDoc) + p->nPgsz) / p->nPgsz);
  3867   4091       assert( pCsr->nRowAvg>0 ); 
  3868   4092       rc = sqlite3_reset(pStmt);
  3869   4093       if( rc!=SQLITE_OK ) return rc;
................................................................................
  3898   4122     int rc = SQLITE_OK;             /* Return code */
  3899   4123     int ii;                         /* Iterator variable for various purposes */
  3900   4124     int nOvfl = 0;                  /* Total overflow pages used by doclists */
  3901   4125     int nToken = 0;                 /* Total number of tokens in cluster */
  3902   4126   
  3903   4127     int nMinEst = 0;                /* The minimum count for any phrase so far. */
  3904   4128     int nLoad4 = 1;                 /* (Phrases that will be loaded)^4. */
         4129  +
         4130  +  /* Tokens are never deferred for FTS tables created using the content=xxx
         4131  +  ** option. The reason being that it is not guaranteed that the content
         4132  +  ** table actually contains the same data as the index. To prevent this from
         4133  +  ** causing any problems, the deferred token optimization is completely
         4134  +  ** disabled for content=xxx tables. */
         4135  +  if( pTab->zContentTbl ){
         4136  +    return SQLITE_OK;
         4137  +  }
  3905   4138   
  3906   4139     /* Count the tokens in this AND/NEAR cluster. If none of the doclists
  3907   4140     ** associated with the tokens spill onto overflow pages, or if there is
  3908   4141     ** only 1 token, exit early. No tokens to defer in this case. */
  3909   4142     for(ii=0; ii<nTC; ii++){
  3910   4143       if( aTC[ii].pRoot==pRoot ){
  3911   4144         nOvfl += aTC[ii].nOvfl;
................................................................................
  3961   4194         ** that will be loaded if all subsequent tokens are deferred.
  3962   4195         */
  3963   4196         Fts3PhraseToken *pToken = pTC->pToken;
  3964   4197         rc = sqlite3Fts3DeferToken(pCsr, pToken, pTC->iCol);
  3965   4198         fts3SegReaderCursorFree(pToken->pSegcsr);
  3966   4199         pToken->pSegcsr = 0;
  3967   4200       }else{
  3968         -      nLoad4 = nLoad4*4;
         4201  +      /* Set nLoad4 to the value of (4^nOther) for the next iteration of the
         4202  +      ** for-loop. Except, limit the value to 2^24 to prevent it from 
         4203  +      ** overflowing the 32-bit integer it is stored in. */
         4204  +      if( ii<12 ) nLoad4 = nLoad4*4;
         4205  +
  3969   4206         if( ii==0 || pTC->pPhrase->nToken>1 ){
  3970   4207           /* Either this is the cheapest token in the entire query, or it is
  3971   4208           ** part of a multi-token phrase. Either way, the entire doclist will
  3972   4209           ** (eventually) be loaded into memory. It may as well be now. */
  3973   4210           Fts3PhraseToken *pToken = pTC->pToken;
  3974   4211           int nList = 0;
  3975   4212           char *pList = 0;
................................................................................
  4331   4568           int nNear = p->nNear;
  4332   4569           res = fts3EvalNearTrim(nNear, aTmp, &aPoslist, &nToken, pPhrase);
  4333   4570         }
  4334   4571     
  4335   4572         aPoslist = pExpr->pRight->pPhrase->doclist.pList;
  4336   4573         nToken = pExpr->pRight->pPhrase->nToken;
  4337   4574         for(p=pExpr->pLeft; p && res; p=p->pLeft){
  4338         -        int nNear = p->pParent->nNear;
  4339         -        Fts3Phrase *pPhrase = (
         4575  +        int nNear;
         4576  +        Fts3Phrase *pPhrase;
         4577  +        assert( p->pParent && p->pParent->pLeft==p );
         4578  +        nNear = p->pParent->nNear;
         4579  +        pPhrase = (
  4340   4580               p->eType==FTSQUERY_NEAR ? p->pRight->pPhrase : p->pPhrase
  4341   4581           );
  4342   4582           res = fts3EvalNearTrim(nNear, aTmp, &aPoslist, &nToken, pPhrase);
  4343   4583         }
  4344   4584       }
  4345   4585   
  4346   4586       sqlite3_free(aTmp);
................................................................................
  4822   5062       for(i=0; i<pPhrase->nToken; i++){
  4823   5063         fts3SegReaderCursorFree(pPhrase->aToken[i].pSegcsr);
  4824   5064         pPhrase->aToken[i].pSegcsr = 0;
  4825   5065       }
  4826   5066     }
  4827   5067   }
  4828   5068   
         5069  +/*
         5070  +** Return SQLITE_CORRUPT_VTAB.
         5071  +*/
         5072  +#ifdef SQLITE_DEBUG
         5073  +int sqlite3Fts3Corrupt(){
         5074  +  return SQLITE_CORRUPT_VTAB;
         5075  +}
         5076  +#endif
         5077  +
  4829   5078   #if !SQLITE_CORE
  4830   5079   /*
  4831   5080   ** Initialize API pointer table, if required.
  4832   5081   */
  4833   5082   int sqlite3_extension_init(
  4834   5083     sqlite3 *db, 
  4835   5084     char **pzErrMsg,

Changes to ext/fts3/fts3Int.h.

   152    152   #if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST)
   153    153   # define TESTONLY(X)  X
   154    154   #else
   155    155   # define TESTONLY(X)
   156    156   #endif
   157    157   
   158    158   #endif /* SQLITE_AMALGAMATION */
          159  +
          160  +#ifdef SQLITE_DEBUG
          161  +int sqlite3Fts3Corrupt(void);
          162  +# define FTS_CORRUPT_VTAB sqlite3Fts3Corrupt()
          163  +#else
          164  +# define FTS_CORRUPT_VTAB SQLITE_CORRUPT_VTAB
          165  +#endif
   159    166   
   160    167   typedef struct Fts3Table Fts3Table;
   161    168   typedef struct Fts3Cursor Fts3Cursor;
   162    169   typedef struct Fts3Expr Fts3Expr;
   163    170   typedef struct Fts3Phrase Fts3Phrase;
   164    171   typedef struct Fts3PhraseToken Fts3PhraseToken;
   165    172   
................................................................................
   180    187     sqlite3_vtab base;              /* Base class used by SQLite core */
   181    188     sqlite3 *db;                    /* The database connection */
   182    189     const char *zDb;                /* logical database name */
   183    190     const char *zName;              /* virtual table name */
   184    191     int nColumn;                    /* number of named columns in virtual table */
   185    192     char **azColumn;                /* column names.  malloced */
   186    193     sqlite3_tokenizer *pTokenizer;  /* tokenizer for inserts and queries */
          194  +  char *zContentTbl;              /* content=xxx option, or NULL */
   187    195   
   188    196     /* Precompiled statements used by the implementation. Each of these 
   189    197     ** statements is run and reset within a single virtual table API call. 
   190    198     */
   191    199     sqlite3_stmt *aStmt[27];
   192    200   
   193    201     char *zReadExprlist;
................................................................................
   220    228       int nPrefix;                  /* Prefix length (0 for main terms index) */
   221    229       Fts3Hash hPending;            /* Pending terms table for this index */
   222    230     } *aIndex;
   223    231     int nMaxPendingData;            /* Max pending data before flush to disk */
   224    232     int nPendingData;               /* Current bytes of pending data */
   225    233     sqlite_int64 iPrevDocid;        /* Docid of most recently inserted document */
   226    234   
   227         -#if defined(SQLITE_DEBUG)
          235  +#if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST)
   228    236     /* State variables used for validating that the transaction control
   229    237     ** methods of the virtual table are called at appropriate times.  These
   230    238     ** values do not contribution to the FTS computation; they are used for
   231    239     ** verifying the SQLite core.
   232    240     */
   233    241     int inTransaction;     /* True after xBegin but before xCommit/xRollback */
   234    242     int mxSavepoint;       /* Largest valid xSavepoint integer */
................................................................................
   305    313   ** For a sequence of tokens contained in double-quotes (i.e. "one two three")
   306    314   ** nToken will be the number of tokens in the string.
   307    315   */
   308    316   struct Fts3PhraseToken {
   309    317     char *z;                        /* Text of the token */
   310    318     int n;                          /* Number of bytes in buffer z */
   311    319     int isPrefix;                   /* True if token ends with a "*" character */
          320  +  int bFirst;                     /* True if token must appear at position 0 */
   312    321   
   313    322     /* Variables above this point are populated when the expression is
   314    323     ** parsed (by code in fts3_expr.c). Below this point the variables are
   315    324     ** used when evaluating the expression. */
   316    325     Fts3DeferredToken *pDeferred;   /* Deferred token object for this token */
   317    326     Fts3MultiSegReader *pSegcsr;    /* Segment-reader for this token */
   318    327   };
................................................................................
   423    432   
   424    433   /* Flags allowed as part of the 4th argument to SegmentReaderIterate() */
   425    434   #define FTS3_SEGMENT_REQUIRE_POS   0x00000001
   426    435   #define FTS3_SEGMENT_IGNORE_EMPTY  0x00000002
   427    436   #define FTS3_SEGMENT_COLUMN_FILTER 0x00000004
   428    437   #define FTS3_SEGMENT_PREFIX        0x00000008
   429    438   #define FTS3_SEGMENT_SCAN          0x00000010
          439  +#define FTS3_SEGMENT_FIRST         0x00000020
   430    440   
   431    441   /* Type passed as 4th argument to SegmentReaderIterate() */
   432    442   struct Fts3SegFilter {
   433    443     const char *zTerm;
   434    444     int nTerm;
   435    445     int iCol;
   436    446     int flags;
................................................................................
   462    472   /* fts3.c */
   463    473   int sqlite3Fts3PutVarint(char *, sqlite3_int64);
   464    474   int sqlite3Fts3GetVarint(const char *, sqlite_int64 *);
   465    475   int sqlite3Fts3GetVarint32(const char *, int *);
   466    476   int sqlite3Fts3VarintLen(sqlite3_uint64);
   467    477   void sqlite3Fts3Dequote(char *);
   468    478   void sqlite3Fts3DoclistPrev(int,char*,int,char**,sqlite3_int64*,int*,u8*);
   469         -
   470    479   int sqlite3Fts3EvalPhraseStats(Fts3Cursor *, Fts3Expr *, u32 *);
          480  +int sqlite3Fts3FirstFilter(sqlite3_int64, char *, int, char *);
   471    481   
   472    482   /* fts3_tokenizer.c */
   473    483   const char *sqlite3Fts3NextToken(const char *, int *);
   474    484   int sqlite3Fts3InitHashTable(sqlite3 *, Fts3Hash *, const char *);
   475    485   int sqlite3Fts3InitTokenizer(Fts3Hash *pHash, const char *, 
   476    486       sqlite3_tokenizer **, char **
   477    487   );
................................................................................
   482    492   void sqlite3Fts3Snippet(sqlite3_context *, Fts3Cursor *, const char *,
   483    493     const char *, const char *, int, int
   484    494   );
   485    495   void sqlite3Fts3Matchinfo(sqlite3_context *, Fts3Cursor *, const char *);
   486    496   
   487    497   /* fts3_expr.c */
   488    498   int sqlite3Fts3ExprParse(sqlite3_tokenizer *, 
   489         -  char **, int, int, const char *, int, Fts3Expr **
          499  +  char **, int, int, int, const char *, int, Fts3Expr **
   490    500   );
   491    501   void sqlite3Fts3ExprFree(Fts3Expr *);
   492    502   #ifdef SQLITE_TEST
   493    503   int sqlite3Fts3ExprInitTestInterface(sqlite3 *db);
   494    504   int sqlite3Fts3InitTerm(sqlite3 *db);
   495    505   #endif
   496    506   

Changes to ext/fts3/fts3_expr.c.

    89     89   **   FTS3 query "sqlite -mysql". Otherwise, ParseContext.isNot is set to
    90     90   **   zero.
    91     91   */
    92     92   typedef struct ParseContext ParseContext;
    93     93   struct ParseContext {
    94     94     sqlite3_tokenizer *pTokenizer;      /* Tokenizer module */
    95     95     const char **azCol;                 /* Array of column names for fts3 table */
           96  +  int bFts4;                          /* True to allow FTS4-only syntax */
    96     97     int nCol;                           /* Number of entries in azCol[] */
    97     98     int iDefaultCol;                    /* Default column to query */
    98     99     int isNot;                          /* True if getNextNode() sees a unary - */
    99    100     sqlite3_context *pCtx;              /* Write error message here */
   100    101     int nNest;                          /* Number of nested brackets */
   101    102   };
   102    103   
................................................................................
   176    177           pRet->pPhrase->aToken[0].z = (char *)&pRet->pPhrase[1];
   177    178           memcpy(pRet->pPhrase->aToken[0].z, zToken, nToken);
   178    179   
   179    180           if( iEnd<n && z[iEnd]=='*' ){
   180    181             pRet->pPhrase->aToken[0].isPrefix = 1;
   181    182             iEnd++;
   182    183           }
   183         -        if( !sqlite3_fts3_enable_parentheses && iStart>0 && z[iStart-1]=='-' ){
   184         -          pParse->isNot = 1;
          184  +
          185  +        while( 1 ){
          186  +          if( !sqlite3_fts3_enable_parentheses 
          187  +           && iStart>0 && z[iStart-1]=='-' 
          188  +          ){
          189  +            pParse->isNot = 1;
          190  +            iStart--;
          191  +          }else if( pParse->bFts4 && iStart>0 && z[iStart-1]=='^' ){
          192  +            pRet->pPhrase->aToken[0].bFirst = 1;
          193  +            iStart--;
          194  +          }else{
          195  +            break;
          196  +          }
   185    197           }
          198  +
   186    199         }
   187    200         nConsumed = iEnd;
   188    201       }
   189    202   
   190    203       pModule->xClose(pCursor);
   191    204     }
   192    205     
................................................................................
   277    290           memset(pToken, 0, sizeof(Fts3PhraseToken));
   278    291   
   279    292           memcpy(&zTemp[nTemp], zByte, nByte);
   280    293           nTemp += nByte;
   281    294   
   282    295           pToken->n = nByte;
   283    296           pToken->isPrefix = (iEnd<nInput && zInput[iEnd]=='*');
          297  +        pToken->bFirst = (iBegin>0 && zInput[iBegin-1]=='^');
   284    298           nToken = ii+1;
   285    299         }
   286    300       }
   287    301   
   288    302       pModule->xClose(pCursor);
   289    303       pCursor = 0;
   290    304     }
................................................................................
   298    312       memset(p, 0, (char *)&(((Fts3Phrase *)&p[1])->aToken[0])-(char *)p);
   299    313       p->eType = FTSQUERY_PHRASE;
   300    314       p->pPhrase = (Fts3Phrase *)&p[1];
   301    315       p->pPhrase->iColumn = pParse->iDefaultCol;
   302    316       p->pPhrase->nToken = nToken;
   303    317   
   304    318       zBuf = (char *)&p->pPhrase->aToken[nToken];
   305         -    memcpy(zBuf, zTemp, nTemp);
   306         -    sqlite3_free(zTemp);
          319  +    if( zTemp ){
          320  +      memcpy(zBuf, zTemp, nTemp);
          321  +      sqlite3_free(zTemp);
          322  +    }else{
          323  +      assert( nTemp==0 );
          324  +    }
   307    325   
   308    326       for(jj=0; jj<p->pPhrase->nToken; jj++){
   309    327         p->pPhrase->aToken[jj].z = zBuf;
   310    328         zBuf += p->pPhrase->aToken[jj].n;
   311    329       }
   312    330       rc = SQLITE_OK;
   313    331     }
................................................................................
   724    742   ** column to match against for tokens for which a column name is not explicitly
   725    743   ** specified as part of the query string), or -1 if tokens may by default
   726    744   ** match any table column.
   727    745   */
   728    746   int sqlite3Fts3ExprParse(
   729    747     sqlite3_tokenizer *pTokenizer,      /* Tokenizer module */
   730    748     char **azCol,                       /* Array of column names for fts3 table */
          749  +  int bFts4,                          /* True to allow FTS4-only syntax */
   731    750     int nCol,                           /* Number of entries in azCol[] */
   732    751     int iDefaultCol,                    /* Default column to query */
   733    752     const char *z, int n,               /* Text of MATCH query */
   734    753     Fts3Expr **ppExpr                   /* OUT: Parsed query structure */
   735    754   ){
   736    755     int nParsed;
   737    756     int rc;
   738    757     ParseContext sParse;
   739    758     sParse.pTokenizer = pTokenizer;
   740    759     sParse.azCol = (const char **)azCol;
   741    760     sParse.nCol = nCol;
   742    761     sParse.iDefaultCol = iDefaultCol;
   743    762     sParse.nNest = 0;
          763  +  sParse.bFts4 = bFts4;
   744    764     if( z==0 ){
   745    765       *ppExpr = 0;
   746    766       return SQLITE_OK;
   747    767     }
   748    768     if( n<0 ){
   749    769       n = (int)strlen(z);
   750    770     }
................................................................................
   926    946       goto exprtest_out;
   927    947     }
   928    948     for(ii=0; ii<nCol; ii++){
   929    949       azCol[ii] = (char *)sqlite3_value_text(argv[ii+2]);
   930    950     }
   931    951   
   932    952     rc = sqlite3Fts3ExprParse(
   933         -      pTokenizer, azCol, nCol, nCol, zExpr, nExpr, &pExpr
          953  +      pTokenizer, azCol, 0, nCol, nCol, zExpr, nExpr, &pExpr
   934    954     );
   935    955     if( rc!=SQLITE_OK && rc!=SQLITE_NOMEM ){
   936    956       sqlite3_result_error(context, "Error parsing expression", -1);
   937    957     }else if( rc==SQLITE_NOMEM || !(zBuf = exprToString(pExpr, 0)) ){
   938    958       sqlite3_result_error_nomem(context);
   939    959     }else{
   940    960       sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);

Changes to ext/fts3/fts3_snippet.c.

   364    364     pPhrase->nToken = pExpr->pPhrase->nToken;
   365    365   
   366    366     pCsr = sqlite3Fts3EvalPhrasePoslist(p->pCsr, pExpr, p->iCol);
   367    367     if( pCsr ){
   368    368       int iFirst = 0;
   369    369       pPhrase->pList = pCsr;
   370    370       fts3GetDeltaPosition(&pCsr, &iFirst);
          371  +    assert( iFirst>=0 );
   371    372       pPhrase->pHead = pCsr;
   372    373       pPhrase->pTail = pCsr;
   373    374       pPhrase->iHead = iFirst;
   374    375       pPhrase->iTail = iFirst;
   375    376     }else{
   376    377       assert( pPhrase->pList==0 && pPhrase->pHead==0 && pPhrase->pTail==0 );
   377    378     }
................................................................................
   844    845       if( rc!=SQLITE_OK ) return rc;
   845    846     }
   846    847     pStmt = *ppStmt;
   847    848     assert( sqlite3_data_count(pStmt)==1 );
   848    849   
   849    850     a = sqlite3_column_blob(pStmt, 0);
   850    851     a += sqlite3Fts3GetVarint(a, &nDoc);
   851         -  if( nDoc==0 ) return SQLITE_CORRUPT_VTAB;
          852  +  if( nDoc==0 ) return FTS_CORRUPT_VTAB;
   852    853     *pnDoc = (u32)nDoc;
   853    854   
   854    855     if( paLen ) *paLen = a;
   855    856     return SQLITE_OK;
   856    857   }
   857    858   
   858    859   /*
................................................................................
  1405   1406             iMinPos = pT->iPos-pT->iOff;
  1406   1407             pTerm = pT;
  1407   1408           }
  1408   1409         }
  1409   1410   
  1410   1411         if( !pTerm ){
  1411   1412           /* All offsets for this column have been gathered. */
  1412         -        break;
         1413  +        rc = SQLITE_DONE;
  1413   1414         }else{
  1414   1415           assert( iCurrent<=iMinPos );
  1415   1416           if( 0==(0xFE&*pTerm->pList) ){
  1416   1417             pTerm->pList = 0;
  1417   1418           }else{
  1418   1419             fts3GetDeltaPosition(&pTerm->pList, &pTerm->iPos);
  1419   1420           }
................................................................................
  1422   1423           }
  1423   1424           if( rc==SQLITE_OK ){
  1424   1425             char aBuffer[64];
  1425   1426             sqlite3_snprintf(sizeof(aBuffer), aBuffer, 
  1426   1427                 "%d %d %d %d ", iCol, pTerm-sCtx.aTerm, iStart, iEnd-iStart
  1427   1428             );
  1428   1429             rc = fts3StringAppend(&res, aBuffer, -1);
  1429         -        }else if( rc==SQLITE_DONE ){
  1430         -          rc = SQLITE_CORRUPT_VTAB;
         1430  +        }else if( rc==SQLITE_DONE && pTab->zContentTbl==0 ){
         1431  +          rc = FTS_CORRUPT_VTAB;
  1431   1432           }
  1432   1433         }
  1433   1434       }
  1434   1435       if( rc==SQLITE_DONE ){
  1435   1436         rc = SQLITE_OK;
  1436   1437       }
  1437   1438   

Changes to ext/fts3/fts3_write.c.

   252    252   /* 0  */  "DELETE FROM %Q.'%q_content' WHERE rowid = ?",
   253    253   /* 1  */  "SELECT NOT EXISTS(SELECT docid FROM %Q.'%q_content' WHERE rowid!=?)",
   254    254   /* 2  */  "DELETE FROM %Q.'%q_content'",
   255    255   /* 3  */  "DELETE FROM %Q.'%q_segments'",
   256    256   /* 4  */  "DELETE FROM %Q.'%q_segdir'",
   257    257   /* 5  */  "DELETE FROM %Q.'%q_docsize'",
   258    258   /* 6  */  "DELETE FROM %Q.'%q_stat'",
   259         -/* 7  */  "SELECT %s FROM %Q.'%q_content' AS x WHERE rowid=?",
          259  +/* 7  */  "SELECT %s WHERE rowid=?",
   260    260   /* 8  */  "SELECT (SELECT max(idx) FROM %Q.'%q_segdir' WHERE level = ?) + 1",
   261    261   /* 9  */  "INSERT INTO %Q.'%q_segments'(blockid, block) VALUES(?, ?)",
   262    262   /* 10 */  "SELECT coalesce((SELECT max(blockid) FROM %Q.'%q_segments') + 1, 1)",
   263    263   /* 11 */  "INSERT INTO %Q.'%q_segdir' VALUES(?,?,?,?,?,?)",
   264    264   
   265    265             /* Return segments in order from oldest to newest.*/ 
   266    266   /* 12 */  "SELECT idx, start_block, leaves_end_block, end_block, root "
................................................................................
   294    294     
   295    295     pStmt = p->aStmt[eStmt];
   296    296     if( !pStmt ){
   297    297       char *zSql;
   298    298       if( eStmt==SQL_CONTENT_INSERT ){
   299    299         zSql = sqlite3_mprintf(azSql[eStmt], p->zDb, p->zName, p->zWriteExprlist);
   300    300       }else if( eStmt==SQL_SELECT_CONTENT_BY_ROWID ){
   301         -      zSql = sqlite3_mprintf(azSql[eStmt], p->zReadExprlist, p->zDb, p->zName);
          301  +      zSql = sqlite3_mprintf(azSql[eStmt], p->zReadExprlist);
   302    302       }else{
   303    303         zSql = sqlite3_mprintf(azSql[eStmt], p->zDb, p->zName);
   304    304       }
   305    305       if( !zSql ){
   306    306         rc = SQLITE_NOMEM;
   307    307       }else{
   308    308         rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, NULL);
................................................................................
   337    337     if( rc==SQLITE_OK ){
   338    338       if( eStmt==SQL_SELECT_DOCSIZE ){
   339    339         sqlite3_bind_int64(pStmt, 1, iDocid);
   340    340       }
   341    341       rc = sqlite3_step(pStmt);
   342    342       if( rc!=SQLITE_ROW || sqlite3_column_type(pStmt, 0)!=SQLITE_BLOB ){
   343    343         rc = sqlite3_reset(pStmt);
   344         -      if( rc==SQLITE_OK ) rc = SQLITE_CORRUPT_VTAB;
          344  +      if( rc==SQLITE_OK ) rc = FTS_CORRUPT_VTAB;
   345    345         pStmt = 0;
   346    346       }else{
   347    347         rc = SQLITE_OK;
   348    348       }
   349    349     }
   350    350   
   351    351     *ppStmt = pStmt;
................................................................................
   405    405   ** write-locks on the %_segments and %_segdir ** tables). 
   406    406   **
   407    407   ** We try to avoid this because if FTS3 returns any error when committing
   408    408   ** a transaction, the whole transaction will be rolled back. And this is
   409    409   ** not what users expect when they get SQLITE_LOCKED_SHAREDCACHE. It can
   410    410   ** still happen if the user reads data directly from the %_segments or
   411    411   ** %_segdir tables instead of going through FTS3 though.
          412  +**
          413  +** This reasoning does not apply to a content=xxx table.
   412    414   */
   413    415   int sqlite3Fts3ReadLock(Fts3Table *p){
   414    416     int rc;                         /* Return code */
   415    417     sqlite3_stmt *pStmt;            /* Statement used to obtain lock */
   416    418   
   417         -  rc = fts3SqlStmt(p, SQL_SELECT_CONTENT_BY_ROWID, &pStmt, 0);
   418         -  if( rc==SQLITE_OK ){
   419         -    sqlite3_bind_null(pStmt, 1);
   420         -    sqlite3_step(pStmt);
   421         -    rc = sqlite3_reset(pStmt);
          419  +  if( p->zContentTbl==0 ){
          420  +    rc = fts3SqlStmt(p, SQL_SELECT_CONTENT_BY_ROWID, &pStmt, 0);
          421  +    if( rc==SQLITE_OK ){
          422  +      sqlite3_bind_null(pStmt, 1);
          423  +      sqlite3_step(pStmt);
          424  +      rc = sqlite3_reset(pStmt);
          425  +    }
          426  +  }else{
          427  +    rc = SQLITE_OK;
   422    428     }
          429  +
   423    430     return rc;
   424    431   }
   425    432   
   426    433   /*
   427    434   ** Set *ppStmt to a statement handle that may be used to iterate through
   428    435   ** all rows in the %_segdir table, from oldest to newest. If successful,
   429    436   ** return SQLITE_OK. If an error occurs while preparing the statement, 
................................................................................
   775    782   static int fts3InsertData(
   776    783     Fts3Table *p,                   /* Full-text table */
   777    784     sqlite3_value **apVal,          /* Array of values to insert */
   778    785     sqlite3_int64 *piDocid          /* OUT: Docid for row just inserted */
   779    786   ){
   780    787     int rc;                         /* Return code */
   781    788     sqlite3_stmt *pContentInsert;   /* INSERT INTO %_content VALUES(...) */
          789  +
          790  +  if( p->zContentTbl ){
          791  +    sqlite3_value *pRowid = apVal[p->nColumn+3];
          792  +    if( sqlite3_value_type(pRowid)==SQLITE_NULL ){
          793  +      pRowid = apVal[1];
          794  +    }
          795  +    if( sqlite3_value_type(pRowid)!=SQLITE_INTEGER ){
          796  +      return SQLITE_CONSTRAINT;
          797  +    }
          798  +    *piDocid = sqlite3_value_int64(pRowid);
          799  +    return SQLITE_OK;
          800  +  }
   782    801   
   783    802     /* Locate the statement handle used to insert data into the %_content
   784    803     ** table. The SQL for this statement is:
   785    804     **
   786    805     **   INSERT INTO %_content VALUES(?, ?, ?, ...)
   787    806     **
   788    807     ** The statement features N '?' variables, where N is the number of user
................................................................................
   826    845   
   827    846   
   828    847   
   829    848   /*
   830    849   ** Remove all data from the FTS3 table. Clear the hash table containing
   831    850   ** pending terms.
   832    851   */
   833         -static int fts3DeleteAll(Fts3Table *p){
          852  +static int fts3DeleteAll(Fts3Table *p, int bContent){
   834    853     int rc = SQLITE_OK;             /* Return code */
   835    854   
   836    855     /* Discard the contents of the pending-terms hash table. */
   837    856     sqlite3Fts3PendingTermsClear(p);
   838    857   
   839         -  /* Delete everything from the %_content, %_segments and %_segdir tables. */
   840         -  fts3SqlExec(&rc, p, SQL_DELETE_ALL_CONTENT, 0);
          858  +  /* Delete everything from the shadow tables. Except, leave %_content as
          859  +  ** is if bContent is false.  */
          860  +  assert( p->zContentTbl==0 || bContent==0 );
          861  +  if( bContent ) fts3SqlExec(&rc, p, SQL_DELETE_ALL_CONTENT, 0);
   841    862     fts3SqlExec(&rc, p, SQL_DELETE_ALL_SEGMENTS, 0);
   842    863     fts3SqlExec(&rc, p, SQL_DELETE_ALL_SEGDIR, 0);
   843    864     if( p->bHasDocsize ){
   844    865       fts3SqlExec(&rc, p, SQL_DELETE_ALL_DOCSIZE, 0);
   845    866     }
   846    867     if( p->bHasStat ){
   847    868       fts3SqlExec(&rc, p, SQL_DELETE_ALL_STAT, 0);
................................................................................
  1141   1162     /* Because of the FTS3_NODE_PADDING bytes of padding, the following is 
  1142   1163     ** safe (no risk of overread) even if the node data is corrupted. */
  1143   1164     pNext += sqlite3Fts3GetVarint32(pNext, &nPrefix);
  1144   1165     pNext += sqlite3Fts3GetVarint32(pNext, &nSuffix);
  1145   1166     if( nPrefix<0 || nSuffix<=0 
  1146   1167      || &pNext[nSuffix]>&pReader->aNode[pReader->nNode] 
  1147   1168     ){
  1148         -    return SQLITE_CORRUPT_VTAB;
         1169  +    return FTS_CORRUPT_VTAB;
  1149   1170     }
  1150   1171   
  1151   1172     if( nPrefix+nSuffix>pReader->nTermAlloc ){
  1152   1173       int nNew = (nPrefix+nSuffix)*2;
  1153   1174       char *zNew = sqlite3_realloc(pReader->zTerm, nNew);
  1154   1175       if( !zNew ){
  1155   1176         return SQLITE_NOMEM;
................................................................................
  1171   1192     /* Check that the doclist does not appear to extend past the end of the
  1172   1193     ** b-tree node. And that the final byte of the doclist is 0x00. If either 
  1173   1194     ** of these statements is untrue, then the data structure is corrupt.
  1174   1195     */
  1175   1196     if( &pReader->aDoclist[pReader->nDoclist]>&pReader->aNode[pReader->nNode] 
  1176   1197      || (pReader->nPopulate==0 && pReader->aDoclist[pReader->nDoclist-1])
  1177   1198     ){
  1178         -    return SQLITE_CORRUPT_VTAB;
         1199  +    return FTS_CORRUPT_VTAB;
  1179   1200     }
  1180   1201     return SQLITE_OK;
  1181   1202   }
  1182   1203   
  1183   1204   /*
  1184   1205   ** Set the SegReader to point to the first docid in the doclist associated
  1185   1206   ** with the current term.
................................................................................
  2121   2142   ** If successful, *pisEmpty is set to true if the table is empty except for
  2122   2143   ** document pRowid, or false otherwise, and SQLITE_OK is returned. If an
  2123   2144   ** error occurs, an SQLite error code is returned.
  2124   2145   */
  2125   2146   static int fts3IsEmpty(Fts3Table *p, sqlite3_value *pRowid, int *pisEmpty){
  2126   2147     sqlite3_stmt *pStmt;
  2127   2148     int rc;
  2128         -  rc = fts3SqlStmt(p, SQL_IS_EMPTY, &pStmt, &pRowid);
  2129         -  if( rc==SQLITE_OK ){
  2130         -    if( SQLITE_ROW==sqlite3_step(pStmt) ){
  2131         -      *pisEmpty = sqlite3_column_int(pStmt, 0);
         2149  +  if( p->zContentTbl ){
         2150  +    /* If using the content=xxx option, assume the table is never empty */
         2151  +    *pisEmpty = 0;
         2152  +    rc = SQLITE_OK;
         2153  +  }else{
         2154  +    rc = fts3SqlStmt(p, SQL_IS_EMPTY, &pStmt, &pRowid);
         2155  +    if( rc==SQLITE_OK ){
         2156  +      if( SQLITE_ROW==sqlite3_step(pStmt) ){
         2157  +        *pisEmpty = sqlite3_column_int(pStmt, 0);
         2158  +      }
         2159  +      rc = sqlite3_reset(pStmt);
  2132   2160       }
  2133         -    rc = sqlite3_reset(pStmt);
  2134   2161     }
  2135   2162     return rc;
  2136   2163   }
  2137   2164   
  2138   2165   /*
  2139   2166   ** Set *pnMax to the largest segment level in the database for the index
  2140   2167   ** iIndex.
................................................................................
  2478   2505     int rc = SQLITE_OK;
  2479   2506   
  2480   2507     int isIgnoreEmpty =  (pCsr->pFilter->flags & FTS3_SEGMENT_IGNORE_EMPTY);
  2481   2508     int isRequirePos =   (pCsr->pFilter->flags & FTS3_SEGMENT_REQUIRE_POS);
  2482   2509     int isColFilter =    (pCsr->pFilter->flags & FTS3_SEGMENT_COLUMN_FILTER);
  2483   2510     int isPrefix =       (pCsr->pFilter->flags & FTS3_SEGMENT_PREFIX);
  2484   2511     int isScan =         (pCsr->pFilter->flags & FTS3_SEGMENT_SCAN);
         2512  +  int isFirst =        (pCsr->pFilter->flags & FTS3_SEGMENT_FIRST);
  2485   2513   
  2486   2514     Fts3SegReader **apSegment = pCsr->apSegment;
  2487   2515     int nSegment = pCsr->nSegment;
  2488   2516     Fts3SegFilter *pFilter = pCsr->pFilter;
  2489   2517     int (*xCmp)(Fts3SegReader *, Fts3SegReader *) = (
  2490   2518       p->bDescIdx ? fts3SegReaderDoclistCmpRev : fts3SegReaderDoclistCmp
  2491   2519     );
................................................................................
  2537   2565       ){
  2538   2566         nMerge++;
  2539   2567       }
  2540   2568   
  2541   2569       assert( isIgnoreEmpty || (isRequirePos && !isColFilter) );
  2542   2570       if( nMerge==1 
  2543   2571        && !isIgnoreEmpty 
         2572  +     && !isFirst 
  2544   2573        && (p->bDescIdx==0 || fts3SegReaderIsPending(apSegment[0])==0)
  2545   2574       ){
  2546   2575         pCsr->nDoclist = apSegment[0]->nDoclist;
  2547   2576         if( fts3SegReaderIsPending(apSegment[0]) ){
  2548   2577           rc = fts3MsrBufferData(pCsr, apSegment[0]->aDoclist, pCsr->nDoclist);
  2549   2578           pCsr->aDoclist = pCsr->aBuffer;
  2550   2579         }else{
................................................................................
  2602   2631               pCsr->nBuffer = (nDoclist+nByte)*2;
  2603   2632               aNew = sqlite3_realloc(pCsr->aBuffer, pCsr->nBuffer);
  2604   2633               if( !aNew ){
  2605   2634                 return SQLITE_NOMEM;
  2606   2635               }
  2607   2636               pCsr->aBuffer = aNew;
  2608   2637             }
  2609         -          nDoclist += sqlite3Fts3PutVarint(&pCsr->aBuffer[nDoclist], iDelta);
  2610         -          iPrev = iDocid;
  2611         -          if( isRequirePos ){
  2612         -            memcpy(&pCsr->aBuffer[nDoclist], pList, nList);
  2613         -            nDoclist += nList;
  2614         -            pCsr->aBuffer[nDoclist++] = '\0';
         2638  +
         2639  +          if( isFirst ){
         2640  +            char *a = &pCsr->aBuffer[nDoclist];
         2641  +            int nWrite;
         2642  +           
         2643  +            nWrite = sqlite3Fts3FirstFilter(iDelta, pList, nList, a);
         2644  +            if( nWrite ){
         2645  +              iPrev = iDocid;
         2646  +              nDoclist += nWrite;
         2647  +            }
         2648  +          }else{
         2649  +            nDoclist += sqlite3Fts3PutVarint(&pCsr->aBuffer[nDoclist], iDelta);
         2650  +            iPrev = iDocid;
         2651  +            if( isRequirePos ){
         2652  +              memcpy(&pCsr->aBuffer[nDoclist], pList, nList);
         2653  +              nDoclist += nList;
         2654  +              pCsr->aBuffer[nDoclist++] = '\0';
         2655  +            }
  2615   2656             }
  2616   2657           }
  2617   2658   
  2618   2659           fts3SegReaderSort(apSegment, nMerge, j, xCmp);
  2619   2660         }
  2620   2661         if( nDoclist>0 ){
  2621   2662           pCsr->aDoclist = pCsr->aBuffer;
................................................................................
  2783   2824   
  2784   2825   /*
  2785   2826   ** Insert the sizes (in tokens) for each column of the document
  2786   2827   ** with docid equal to p->iPrevDocid.  The sizes are encoded as
  2787   2828   ** a blob of varints.
  2788   2829   */
  2789   2830   static void fts3InsertDocsize(
  2790         -  int *pRC,         /* Result code */
  2791         -  Fts3Table *p,     /* Table into which to insert */
  2792         -  u32 *aSz          /* Sizes of each column */
         2831  +  int *pRC,                       /* Result code */
         2832  +  Fts3Table *p,                   /* Table into which to insert */
         2833  +  u32 *aSz                        /* Sizes of each column, in tokens */
  2793   2834   ){
  2794   2835     char *pBlob;             /* The BLOB encoding of the document size */
  2795   2836     int nBlob;               /* Number of bytes in the BLOB */
  2796   2837     sqlite3_stmt *pStmt;     /* Statement used to insert the encoding */
  2797   2838     int rc;                  /* Result code from subfunctions */
  2798   2839   
  2799   2840     if( *pRC ) return;
................................................................................
  2906   2947       }
  2907   2948     }
  2908   2949     sqlite3Fts3SegmentsClose(p);
  2909   2950     sqlite3Fts3PendingTermsClear(p);
  2910   2951   
  2911   2952     return (rc==SQLITE_OK && bReturnDone && bSeenDone) ? SQLITE_DONE : rc;
  2912   2953   }
         2954  +
         2955  +/*
         2956  +** This function is called when the user executes the following statement:
         2957  +**
         2958  +**     INSERT INTO <tbl>(<tbl>) VALUES('rebuild');
         2959  +**
         2960  +** The entire FTS index is discarded and rebuilt. If the table is one 
         2961  +** created using the content=xxx option, then the new index is based on
         2962  +** the current contents of the xxx table. Otherwise, it is rebuilt based
         2963  +** on the contents of the %_content table.
         2964  +*/
         2965  +static int fts3DoRebuild(Fts3Table *p){
         2966  +  int rc;                         /* Return Code */
         2967  +
         2968  +  rc = fts3DeleteAll(p, 0);
         2969  +  if( rc==SQLITE_OK ){
         2970  +    u32 *aSz = 0;
         2971  +    u32 *aSzIns = 0;
         2972  +    u32 *aSzDel = 0;
         2973  +    sqlite3_stmt *pStmt = 0;
         2974  +    int nEntry = 0;
         2975  +
         2976  +    /* Compose and prepare an SQL statement to loop through the content table */
         2977  +    char *zSql = sqlite3_mprintf("SELECT %s" , p->zReadExprlist);
         2978  +    if( !zSql ){
         2979  +      rc = SQLITE_NOMEM;
         2980  +    }else{
         2981  +      rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
         2982  +      sqlite3_free(zSql);
         2983  +    }
         2984  +
         2985  +    if( rc==SQLITE_OK ){
         2986  +      int nByte = sizeof(u32) * (p->nColumn+1)*3;
         2987  +      aSz = (u32 *)sqlite3_malloc(nByte);
         2988  +      if( aSz==0 ){
         2989  +        rc = SQLITE_NOMEM;
         2990  +      }else{
         2991  +        memset(aSz, 0, nByte);
         2992  +        aSzIns = &aSz[p->nColumn+1];
         2993  +        aSzDel = &aSzIns[p->nColumn+1];
         2994  +      }
         2995  +    }
         2996  +
         2997  +    while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
         2998  +      int iCol;
         2999  +      rc = fts3PendingTermsDocid(p, sqlite3_column_int64(pStmt, 0));
         3000  +      aSz[p->nColumn] = 0;
         3001  +      for(iCol=0; rc==SQLITE_OK && iCol<p->nColumn; iCol++){
         3002  +        const char *z = (const char *) sqlite3_column_text(pStmt, iCol+1);
         3003  +        rc = fts3PendingTermsAdd(p, z, iCol, &aSz[iCol]);
         3004  +        aSz[p->nColumn] += sqlite3_column_bytes(pStmt, iCol+1);
         3005  +      }
         3006  +      if( p->bHasDocsize ){
         3007  +        fts3InsertDocsize(&rc, p, aSz);
         3008  +      }
         3009  +      if( rc!=SQLITE_OK ){
         3010  +        sqlite3_finalize(pStmt);
         3011  +        pStmt = 0;
         3012  +      }else{
         3013  +        nEntry++;
         3014  +        for(iCol=0; iCol<=p->nColumn; iCol++){
         3015  +          aSzIns[iCol] += aSz[iCol];
         3016  +        }
         3017  +      }
         3018  +    }
         3019  +    if( p->bHasStat ){
         3020  +      fts3UpdateDocTotals(&rc, p, aSzIns, aSzDel, nEntry);
         3021  +    }
         3022  +    sqlite3_free(aSz);
         3023  +
         3024  +    if( pStmt ){
         3025  +      int rc2 = sqlite3_finalize(pStmt);
         3026  +      if( rc==SQLITE_OK ){
         3027  +        rc = rc2;
         3028  +      }
         3029  +    }
         3030  +  }
         3031  +
         3032  +  return rc;
         3033  +}
  2913   3034   
  2914   3035   /*
  2915   3036   ** Handle a 'special' INSERT of the form:
  2916   3037   **
  2917   3038   **   "INSERT INTO tbl(tbl) VALUES(<expr>)"
  2918   3039   **
  2919   3040   ** Argument pVal contains the result of <expr>. Currently the only 
................................................................................
  2924   3045     const char *zVal = (const char *)sqlite3_value_text(pVal);
  2925   3046     int nVal = sqlite3_value_bytes(pVal);
  2926   3047   
  2927   3048     if( !zVal ){
  2928   3049       return SQLITE_NOMEM;
  2929   3050     }else if( nVal==8 && 0==sqlite3_strnicmp(zVal, "optimize", 8) ){
  2930   3051       rc = fts3DoOptimize(p, 0);
         3052  +  }else if( nVal==7 && 0==sqlite3_strnicmp(zVal, "rebuild", 7) ){
         3053  +    rc = fts3DoRebuild(p);
  2931   3054   #ifdef SQLITE_TEST
  2932   3055     }else if( nVal>9 && 0==sqlite3_strnicmp(zVal, "nodesize=", 9) ){
  2933   3056       p->nNodeSize = atoi(&zVal[9]);
  2934   3057       rc = SQLITE_OK;
  2935   3058     }else if( nVal>11 && 0==sqlite3_strnicmp(zVal, "maxpending=", 9) ){
  2936   3059       p->nMaxPendingData = atoi(&zVal[11]);
  2937   3060       rc = SQLITE_OK;
................................................................................
  3004   3127           int iPos;                 /* Position of token in zText */
  3005   3128     
  3006   3129           pTC->pTokenizer = pT;
  3007   3130           rc = pModule->xNext(pTC, &zToken, &nToken, &iDum1, &iDum2, &iPos);
  3008   3131           for(pDef=pCsr->pDeferred; pDef && rc==SQLITE_OK; pDef=pDef->pNext){
  3009   3132             Fts3PhraseToken *pPT = pDef->pToken;
  3010   3133             if( (pDef->iCol>=p->nColumn || pDef->iCol==i)
         3134  +           && (pPT->bFirst==0 || iPos==0)
  3011   3135              && (pPT->n==nToken || (pPT->isPrefix && pPT->n<nToken))
  3012   3136              && (0==memcmp(zToken, pPT->z, pPT->n))
  3013   3137             ){
  3014   3138               fts3PendingListAppend(&pDef->pList, iDocid, i, iPos, &rc);
  3015   3139             }
  3016   3140           }
  3017   3141         }
................................................................................
  3095   3219     int isEmpty = 0;
  3096   3220     int rc = fts3IsEmpty(p, pRowid, &isEmpty);
  3097   3221     if( rc==SQLITE_OK ){
  3098   3222       if( isEmpty ){
  3099   3223         /* Deleting this row means the whole table is empty. In this case
  3100   3224         ** delete the contents of all three tables and throw away any
  3101   3225         ** data in the pendingTerms hash table.  */
  3102         -      rc = fts3DeleteAll(p);
         3226  +      rc = fts3DeleteAll(p, 1);
  3103   3227         *pnDoc = *pnDoc - 1;
  3104   3228       }else{
  3105   3229         sqlite3_int64 iRemove = sqlite3_value_int64(pRowid);
  3106   3230         rc = fts3PendingTermsDocid(p, iRemove);
  3107   3231         fts3DeleteTerms(&rc, p, pRowid, aSzDel);
  3108         -      fts3SqlExec(&rc, p, SQL_DELETE_CONTENT, &pRowid);
  3109         -      if( sqlite3_changes(p->db) ) *pnDoc = *pnDoc - 1;
         3232  +      if( p->zContentTbl==0 ){
         3233  +        fts3SqlExec(&rc, p, SQL_DELETE_CONTENT, &pRowid);
         3234  +        if( sqlite3_changes(p->db) ) *pnDoc = *pnDoc - 1;
         3235  +      }else{
         3236  +        *pnDoc = *pnDoc - 1;
         3237  +      }
  3110   3238         if( p->bHasDocsize ){
  3111   3239           fts3SqlExec(&rc, p, SQL_DELETE_DOCSIZE, &pRowid);
  3112   3240         }
  3113   3241       }
  3114   3242     }
  3115   3243   
  3116   3244     return rc;
................................................................................
  3125   3253     int nArg,                       /* Size of argument array */
  3126   3254     sqlite3_value **apVal,          /* Array of arguments */
  3127   3255     sqlite_int64 *pRowid            /* OUT: The affected (or effected) rowid */
  3128   3256   ){
  3129   3257     Fts3Table *p = (Fts3Table *)pVtab;
  3130   3258     int rc = SQLITE_OK;             /* Return Code */
  3131   3259     int isRemove = 0;               /* True for an UPDATE or DELETE */
  3132         -  sqlite3_int64 iRemove = 0;      /* Rowid removed by UPDATE or DELETE */
  3133   3260     u32 *aSzIns = 0;                /* Sizes of inserted documents */
  3134   3261     u32 *aSzDel;                    /* Sizes of deleted documents */
  3135   3262     int nChng = 0;                  /* Net change in number of documents */
  3136   3263     int bInsertDone = 0;
  3137   3264   
  3138   3265     assert( p->pSegments==0 );
  3139   3266   
................................................................................
  3163   3290     **
  3164   3291     ** If the on-conflict mode is REPLACE, this means that the existing row
  3165   3292     ** should be deleted from the database before inserting the new row. Or,
  3166   3293     ** if the on-conflict mode is other than REPLACE, then this method must
  3167   3294     ** detect the conflict and return SQLITE_CONSTRAINT before beginning to
  3168   3295     ** modify the database file.
  3169   3296     */
  3170         -  if( nArg>1 ){
         3297  +  if( nArg>1 && p->zContentTbl==0 ){
  3171   3298       /* Find the value object that holds the new rowid value. */
  3172   3299       sqlite3_value *pNewRowid = apVal[3+p->nColumn];
  3173   3300       if( sqlite3_value_type(pNewRowid)==SQLITE_NULL ){
  3174   3301         pNewRowid = apVal[1];
  3175   3302       }
  3176   3303   
  3177   3304       if( sqlite3_value_type(pNewRowid)!=SQLITE_NULL && ( 
................................................................................
  3208   3335     }
  3209   3336   
  3210   3337     /* If this is a DELETE or UPDATE operation, remove the old record. */
  3211   3338     if( sqlite3_value_type(apVal[0])!=SQLITE_NULL ){
  3212   3339       assert( sqlite3_value_type(apVal[0])==SQLITE_INTEGER );
  3213   3340       rc = fts3DeleteByRowid(p, apVal[0], &nChng, aSzDel);
  3214   3341       isRemove = 1;
  3215         -    iRemove = sqlite3_value_int64(apVal[0]);
  3216   3342     }
  3217   3343     
  3218   3344     /* If this is an INSERT or UPDATE operation, insert the new record. */
  3219   3345     if( nArg>1 && rc==SQLITE_OK ){
  3220   3346       if( bInsertDone==0 ){
  3221   3347         rc = fts3InsertData(p, apVal, pRowid);
  3222         -      if( rc==SQLITE_CONSTRAINT ) rc = SQLITE_CORRUPT_VTAB;
         3348  +      if( rc==SQLITE_CONSTRAINT && p->zContentTbl==0 ){
         3349  +        rc = FTS_CORRUPT_VTAB;
         3350  +      }
  3223   3351       }
  3224         -    if( rc==SQLITE_OK && (!isRemove || *pRowid!=iRemove) ){
         3352  +    if( rc==SQLITE_OK && (!isRemove || *pRowid!=p->iPrevDocid ) ){
  3225   3353         rc = fts3PendingTermsDocid(p, *pRowid);
  3226   3354       }
  3227   3355       if( rc==SQLITE_OK ){
         3356  +      assert( p->iPrevDocid==*pRowid );
  3228   3357         rc = fts3InsertTerms(p, apVal, aSzIns);
  3229   3358       }
  3230   3359       if( p->bHasDocsize ){
  3231   3360         fts3InsertDocsize(&rc, p, aSzIns);
  3232   3361       }
  3233   3362       nChng++;
  3234   3363     }

Changes to ext/rtree/rtree.c.

  1264   1264       if( argc>0 ){
  1265   1265         pCsr->aConstraint = sqlite3_malloc(sizeof(RtreeConstraint)*argc);
  1266   1266         pCsr->nConstraint = argc;
  1267   1267         if( !pCsr->aConstraint ){
  1268   1268           rc = SQLITE_NOMEM;
  1269   1269         }else{
  1270   1270           memset(pCsr->aConstraint, 0, sizeof(RtreeConstraint)*argc);
  1271         -        assert( (idxStr==0 && argc==0) || (int)strlen(idxStr)==argc*2 );
         1271  +        assert( (idxStr==0 && argc==0)
         1272  +                || (idxStr && (int)strlen(idxStr)==argc*2) );
  1272   1273           for(ii=0; ii<argc; ii++){
  1273   1274             RtreeConstraint *p = &pCsr->aConstraint[ii];
  1274   1275             p->op = idxStr[ii*2];
  1275   1276             p->iCoord = idxStr[ii*2+1]-'a';
  1276   1277             if( p->op==RTREE_MATCH ){
  1277   1278               /* A MATCH operator. The right-hand-side must be a blob that
  1278   1279               ** can be cast into an RtreeMatchArg object. One created using
................................................................................
  1565   1566   
  1566   1567     for(ii=0; rc==SQLITE_OK && ii<(pRtree->iDepth-iHeight); ii++){
  1567   1568       int iCell;
  1568   1569       sqlite3_int64 iBest = 0;
  1569   1570   
  1570   1571       float fMinGrowth = 0.0;
  1571   1572       float fMinArea = 0.0;
         1573  +#if VARIANT_RSTARTREE_CHOOSESUBTREE
  1572   1574       float fMinOverlap = 0.0;
         1575  +    float overlap;
         1576  +#endif
  1573   1577   
  1574   1578       int nCell = NCELL(pNode);
  1575   1579       RtreeCell cell;
  1576   1580       RtreeNode *pChild;
  1577   1581   
  1578   1582       RtreeCell *aCell = 0;
  1579   1583   
................................................................................
  1597   1601       ** is inserted into it. Resolve ties by choosing the entry with
  1598   1602       ** the smallest area.
  1599   1603       */
  1600   1604       for(iCell=0; iCell<nCell; iCell++){
  1601   1605         int bBest = 0;
  1602   1606         float growth;
  1603   1607         float area;
  1604         -      float overlap = 0.0;
  1605   1608         nodeGetCell(pRtree, pNode, iCell, &cell);
  1606   1609         growth = cellGrowth(pRtree, &cell, pCell);
  1607   1610         area = cellArea(pRtree, &cell);
  1608   1611   
  1609   1612   #if VARIANT_RSTARTREE_CHOOSESUBTREE
  1610   1613         if( ii==(pRtree->iDepth-1) ){
  1611   1614           overlap = cellOverlapEnlargement(pRtree,&cell,pCell,aCell,nCell,iCell);
         1615  +      }else{
         1616  +        overlap = 0.0;
  1612   1617         }
  1613   1618         if( (iCell==0) 
  1614   1619          || (overlap<fMinOverlap) 
  1615   1620          || (overlap==fMinOverlap && growth<fMinGrowth)
  1616   1621          || (overlap==fMinOverlap && growth==fMinGrowth && area<fMinArea)
  1617   1622         ){
  1618   1623           bBest = 1;
         1624  +        fMinOverlap = overlap;
  1619   1625         }
  1620   1626   #else
  1621   1627         if( iCell==0||growth<fMinGrowth||(growth==fMinGrowth && area<fMinArea) ){
  1622   1628           bBest = 1;
  1623   1629         }
  1624   1630   #endif
  1625   1631         if( bBest ){
  1626         -        fMinOverlap = overlap;
  1627   1632           fMinGrowth = growth;
  1628   1633           fMinArea = area;
  1629   1634           iBest = cell.iRowid;
  1630   1635         }
  1631   1636       }
  1632   1637   
  1633   1638       sqlite3_free(aCell);

Changes to main.mk.

   361    361   	$(RANLIB) libsqlite3.a
   362    362   
   363    363   sqlite3$(EXE):	$(TOP)/src/shell.c libsqlite3.a sqlite3.h
   364    364   	$(TCCX) $(READLINE_FLAGS) -o sqlite3$(EXE)                  \
   365    365   		$(TOP)/src/shell.c                                  \
   366    366   		libsqlite3.a $(LIBREADLINE) $(TLIBS) $(THREADLIB)
   367    367   
          368  +sqlite3.o:	sqlite3.c
          369  +	$(TCCX) -c sqlite3.c
          370  +
   368    371   # This target creates a directory named "tsrc" and fills it with
   369    372   # copies of all of the C source code and header files needed to
   370    373   # build on the target system.  Some of the C source code and header
   371    374   # files are automatically generated.  This target takes care of
   372    375   # all that automatic generation.
   373    376   #
   374    377   target_source:	$(SRC) $(TOP)/tool/vdbe-compress.tcl
................................................................................
   593    596   install:	sqlite3 libsqlite3.a sqlite3.h
   594    597   	mv sqlite3 /usr/bin
   595    598   	mv libsqlite3.a /usr/lib
   596    599   	mv sqlite3.h /usr/include
   597    600   
   598    601   clean:	
   599    602   	rm -f *.o sqlite3 sqlite3.exe libsqlite3.a sqlite3.h opcodes.*
   600         -	rm -f lemon lempar.c parse.* sqlite*.tar.gz mkkeywordhash keywordhash.h
          603  +	rm -f lemon lemon.exe lempar.c parse.* sqlite*.tar.gz
          604  +	rm -f mkkeywordhash mkkeywordhash.exe keywordhash.h
   601    605   	rm -f $(PUBLISH)
   602    606   	rm -f *.da *.bb *.bbg gmon.out
   603    607   	rm -rf tsrc target_source
   604    608   	rm -f testloadext.dll libtestloadext.so
   605    609   	rm -f amalgamation-testfixture amalgamation-testfixture.exe
   606    610   	rm -f fts3-testfixture fts3-testfixture.exe
   607    611   	rm -f testfixture testfixture.exe
   608    612   	rm -f threadtest3 threadtest3.exe
   609    613   	rm -f sqlite3.c fts?amal.c tclsqlite3.c
   610    614   	rm -f sqlite3_analyzer sqlite3_analyzer.exe sqlite3_analyzer.c

Changes to src/backup.c.

   539    539   }
   540    540   
   541    541   /*
   542    542   ** Release all resources associated with an sqlite3_backup* handle.
   543    543   */
   544    544   int sqlite3_backup_finish(sqlite3_backup *p){
   545    545     sqlite3_backup **pp;                 /* Ptr to head of pagers backup list */
   546         -  sqlite3_mutex *mutex;                /* Mutex to protect source database */
          546  +  MUTEX_LOGIC( sqlite3_mutex *mutex; ) /* Mutex to protect source database */
   547    547     int rc;                              /* Value to return */
   548    548   
   549    549     /* Enter the mutexes */
   550    550     if( p==0 ) return SQLITE_OK;
   551    551     sqlite3_mutex_enter(p->pSrcDb->mutex);
   552    552     sqlite3BtreeEnter(p->pSrc);
   553         -  mutex = p->pSrcDb->mutex;
          553  +  MUTEX_LOGIC( mutex = p->pSrcDb->mutex; )
   554    554     if( p->pDestDb ){
   555    555       sqlite3_mutex_enter(p->pDestDb->mutex);
   556    556     }
   557    557   
   558    558     /* Detach this backup from the source pager. */
   559    559     if( p->pDestDb ){
   560    560       p->pSrc->nBackup--;
................................................................................
   700    700     ** or an error code.
   701    701     */
   702    702     sqlite3_backup_step(&b, 0x7FFFFFFF);
   703    703     assert( b.rc!=SQLITE_OK );
   704    704     rc = sqlite3_backup_finish(&b);
   705    705     if( rc==SQLITE_OK ){
   706    706       pTo->pBt->pageSizeFixed = 0;
          707  +  }else{
          708  +    sqlite3PagerClearCache(sqlite3BtreePager(b.pDest));
   707    709     }
   708    710   
   709    711     assert( sqlite3BtreeIsInTrans(pTo)==0 );
   710    712     sqlite3BtreeLeave(pFrom);
   711    713     sqlite3BtreeLeave(pTo);
   712    714     return rc;
   713    715   }
   714    716   #endif /* SQLITE_OMIT_VACUUM */

Changes to src/btree.c.

  1762   1762     ** If this Btree is a candidate for shared cache, try to find an
  1763   1763     ** existing BtShared object that we can share with
  1764   1764     */
  1765   1765     if( isMemdb==0 && isTempDb==0 ){
  1766   1766       if( vfsFlags & SQLITE_OPEN_SHAREDCACHE ){
  1767   1767         int nFullPathname = pVfs->mxPathname+1;
  1768   1768         char *zFullPathname = sqlite3Malloc(nFullPathname);
  1769         -      sqlite3_mutex *mutexShared;
         1769  +      MUTEX_LOGIC( sqlite3_mutex *mutexShared; )
  1770   1770         p->sharable = 1;
  1771   1771         if( !zFullPathname ){
  1772   1772           sqlite3_free(p);
  1773   1773           return SQLITE_NOMEM;
  1774   1774         }
  1775   1775         sqlite3OsFullPathname(pVfs, zFilename, nFullPathname, zFullPathname);
         1776  +#if SQLITE_THREADSAFE
  1776   1777         mutexOpen = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_OPEN);
  1777   1778         sqlite3_mutex_enter(mutexOpen);
  1778   1779         mutexShared = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
  1779   1780         sqlite3_mutex_enter(mutexShared);
         1781  +#endif
  1780   1782         for(pBt=GLOBAL(BtShared*,sqlite3SharedCacheList); pBt; pBt=pBt->pNext){
  1781   1783           assert( pBt->nRef>0 );
  1782   1784           if( 0==strcmp(zFullPathname, sqlite3PagerFilename(pBt->pPager))
  1783   1785                    && sqlite3PagerVfs(pBt->pPager)==pVfs ){
  1784   1786             int iDb;
  1785   1787             for(iDb=db->nDb-1; iDb>=0; iDb--){
  1786   1788               Btree *pExisting = db->aDb[iDb].pBt;
................................................................................
  1878   1880       pBt->usableSize = pBt->pageSize - nReserve;
  1879   1881       assert( (pBt->pageSize & 7)==0 );  /* 8-byte alignment of pageSize */
  1880   1882      
  1881   1883   #if !defined(SQLITE_OMIT_SHARED_CACHE) && !defined(SQLITE_OMIT_DISKIO)
  1882   1884       /* Add the new BtShared object to the linked list sharable BtShareds.
  1883   1885       */
  1884   1886       if( p->sharable ){
  1885         -      sqlite3_mutex *mutexShared;
         1887  +      MUTEX_LOGIC( sqlite3_mutex *mutexShared; )
  1886   1888         pBt->nRef = 1;
  1887         -      mutexShared = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
         1889  +      MUTEX_LOGIC( mutexShared = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);)
  1888   1890         if( SQLITE_THREADSAFE && sqlite3GlobalConfig.bCoreMutex ){
  1889   1891           pBt->mutex = sqlite3MutexAlloc(SQLITE_MUTEX_FAST);
  1890   1892           if( pBt->mutex==0 ){
  1891   1893             rc = SQLITE_NOMEM;
  1892   1894             db->mallocFailed = 0;
  1893   1895             goto btree_open_out;
  1894   1896           }
................................................................................
  1962   1964   ** Decrement the BtShared.nRef counter.  When it reaches zero,
  1963   1965   ** remove the BtShared structure from the sharing list.  Return
  1964   1966   ** true if the BtShared.nRef counter reaches zero and return
  1965   1967   ** false if it is still positive.
  1966   1968   */
  1967   1969   static int removeFromSharingList(BtShared *pBt){
  1968   1970   #ifndef SQLITE_OMIT_SHARED_CACHE
  1969         -  sqlite3_mutex *pMaster;
         1971  +  MUTEX_LOGIC( sqlite3_mutex *pMaster; )
  1970   1972     BtShared *pList;
  1971   1973     int removed = 0;
  1972   1974   
  1973   1975     assert( sqlite3_mutex_notheld(pBt->mutex) );
  1974         -  pMaster = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
         1976  +  MUTEX_LOGIC( pMaster = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); )
  1975   1977     sqlite3_mutex_enter(pMaster);
  1976   1978     pBt->nRef--;
  1977   1979     if( pBt->nRef<=0 ){
  1978   1980       if( GLOBAL(BtShared*,sqlite3SharedCacheList)==pBt ){
  1979   1981         GLOBAL(BtShared*,sqlite3SharedCacheList) = pBt->pNext;
  1980   1982       }else{
  1981   1983         pList = GLOBAL(BtShared*,sqlite3SharedCacheList);
................................................................................
  4581   4583             c = sqlite3VdbeRecordCompare(nCell, pCellKey, pIdxKey);
  4582   4584             sqlite3_free(pCellKey);
  4583   4585           }
  4584   4586         }
  4585   4587         if( c==0 ){
  4586   4588           if( pPage->intKey && !pPage->leaf ){
  4587   4589             lwr = idx;
  4588         -          upr = lwr - 1;
  4589   4590             break;
  4590   4591           }else{
  4591   4592             *pRes = 0;
  4592   4593             rc = SQLITE_OK;
  4593   4594             goto moveto_finish;
  4594   4595           }
  4595   4596         }
................................................................................
  4599   4600           upr = idx-1;
  4600   4601         }
  4601   4602         if( lwr>upr ){
  4602   4603           break;
  4603   4604         }
  4604   4605         pCur->aiIdx[pCur->iPage] = (u16)(idx = (lwr+upr)/2);
  4605   4606       }
  4606         -    assert( lwr==upr+1 );
         4607  +    assert( lwr==upr+1 || (pPage->intKey && !pPage->leaf) );
  4607   4608       assert( pPage->isInit );
  4608   4609       if( pPage->leaf ){
  4609   4610         chldPg = 0;
  4610   4611       }else if( lwr>=pPage->nCell ){
  4611   4612         chldPg = get4byte(&pPage->aData[pPage->hdrOffset+8]);
  4612   4613       }else{
  4613   4614         chldPg = get4byte(findCell(pPage, lwr));
................................................................................
  4864   4865         }else{
  4865   4866           rc = btreeGetPage(pBt, iTrunk, &pTrunk, 0);
  4866   4867         }
  4867   4868         if( rc ){
  4868   4869           pTrunk = 0;
  4869   4870           goto end_allocate_page;
  4870   4871         }
         4872  +      assert( pTrunk!=0 );
         4873  +      assert( pTrunk->aData!=0 );
  4871   4874   
  4872   4875         k = get4byte(&pTrunk->aData[4]); /* # of leaves on this trunk page */
  4873   4876         if( k==0 && !searchList ){
  4874   4877           /* The trunk has no leaves and the list is not being searched. 
  4875   4878           ** So extract the trunk page itself and use it as the newly 
  4876   4879           ** allocated page */
  4877   4880           assert( pPrevTrunk==0 );
................................................................................
  5991   5994         /* Drop the cell from the parent page. apDiv[i] still points to
  5992   5995         ** the cell within the parent, even though it has been dropped.
  5993   5996         ** This is safe because dropping a cell only overwrites the first
  5994   5997         ** four bytes of it, and this function does not need the first
  5995   5998         ** four bytes of the divider cell. So the pointer is safe to use
  5996   5999         ** later on.  
  5997   6000         **
  5998         -      ** Unless SQLite is compiled in secure-delete mode. In this case,
         6001  +      ** But not if we are in secure-delete mode. In secure-delete mode,
  5999   6002         ** the dropCell() routine will overwrite the entire cell with zeroes.
  6000   6003         ** In this case, temporarily copy the cell into the aOvflSpace[]
  6001   6004         ** buffer. It will be copied out again as soon as the aSpace[] buffer
  6002   6005         ** is allocated.  */
  6003   6006         if( pBt->secureDelete ){
  6004         -        int iOff = SQLITE_PTR_TO_INT(apDiv[i]) - SQLITE_PTR_TO_INT(pParent->aData);
         6007  +        int iOff;
         6008  +
         6009  +        iOff = SQLITE_PTR_TO_INT(apDiv[i]) - SQLITE_PTR_TO_INT(pParent->aData);
  6005   6010           if( (iOff+szNew[i])>(int)pBt->usableSize ){
  6006   6011             rc = SQLITE_CORRUPT_BKPT;
  6007   6012             memset(apOld, 0, (i+1)*sizeof(MemPage*));
  6008   6013             goto balance_cleanup;
  6009   6014           }else{
  6010   6015             memcpy(&aOvflSpace[iOff], apDiv[i], szNew[i]);
  6011   6016             apDiv[i] = &aOvflSpace[apDiv[i]-pParent->aData];
................................................................................
  6417   6422       k = 0;                             /* Current 'new' sibling page */
  6418   6423       for(i=0; i<nCell; i++){
  6419   6424         int isDivider = 0;
  6420   6425         while( i==iNextOld ){
  6421   6426           /* Cell i is the cell immediately following the last cell on old
  6422   6427           ** sibling page j. If the siblings are not leaf pages of an
  6423   6428           ** intkey b-tree, then cell i was a divider cell. */
         6429  +        assert( j+1 < ArraySize(apCopy) );
  6424   6430           pOld = apCopy[++j];
  6425   6431           iNextOld = i + !leafData + pOld->nCell + pOld->nOverflow;
  6426   6432           if( pOld->nOverflow ){
  6427   6433             nOverflow = pOld->nOverflow;
  6428   6434             iOverflow = i + !leafData + pOld->aOvfl[0].idx;
  6429   6435           }
  6430   6436           isDivider = !leafData;  

Changes to src/build.c.

  2338   2338   ** the index already exists and must be cleared before being refilled and
  2339   2339   ** the root page number of the index is taken from pIndex->tnum.
  2340   2340   */
  2341   2341   static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
  2342   2342     Table *pTab = pIndex->pTable;  /* The table that is indexed */
  2343   2343     int iTab = pParse->nTab++;     /* Btree cursor used for pTab */
  2344   2344     int iIdx = pParse->nTab++;     /* Btree cursor used for pIndex */
  2345         -  int iSorter = iTab;            /* Cursor opened by OpenSorter (if in use) */
         2345  +  int iSorter;                   /* Cursor opened by OpenSorter (if in use) */
  2346   2346     int addr1;                     /* Address of top of loop */
  2347   2347     int addr2;                     /* Address to jump to for next iteration */
  2348   2348     int tnum;                      /* Root page of index */
  2349   2349     Vdbe *v;                       /* Generate code into this virtual machine */
  2350   2350     KeyInfo *pKey;                 /* KeyInfo for index */
         2351  +#ifdef SQLITE_OMIT_MERGE_SORT
  2351   2352     int regIdxKey;                 /* Registers containing the index key */
         2353  +#endif
  2352   2354     int regRecord;                 /* Register holding assemblied index record */
  2353   2355     sqlite3 *db = pParse->db;      /* The database connection */
  2354   2356     int iDb = sqlite3SchemaToIndex(db, pIndex->pSchema);
  2355   2357   
  2356   2358   #ifndef SQLITE_OMIT_AUTHORIZATION
  2357   2359     if( sqlite3AuthCheck(pParse, SQLITE_REINDEX, pIndex->zName, 0,
  2358   2360         db->aDb[iDb].zName ) ){
................................................................................
  2378   2380       sqlite3VdbeChangeP5(v, 1);
  2379   2381     }
  2380   2382   
  2381   2383   #ifndef SQLITE_OMIT_MERGE_SORT
  2382   2384     /* Open the sorter cursor if we are to use one. */
  2383   2385     iSorter = pParse->nTab++;
  2384   2386     sqlite3VdbeAddOp4(v, OP_SorterOpen, iSorter, 0, 0, (char*)pKey, P4_KEYINFO);
         2387  +#else
         2388  +  iSorter = iTab;
  2385   2389   #endif
  2386   2390   
  2387   2391     /* Open the table. Loop through all rows of the table, inserting index
  2388   2392     ** records into the sorter. */
  2389   2393     sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead);
  2390   2394     addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iTab, 0);
  2391         -  addr2 = addr1 + 1;
  2392   2395     regRecord = sqlite3GetTempReg(pParse);
  2393         -  regIdxKey = sqlite3GenerateIndexKey(pParse, pIndex, iTab, regRecord, 1);
  2394   2396   
  2395   2397   #ifndef SQLITE_OMIT_MERGE_SORT
         2398  +  sqlite3GenerateIndexKey(pParse, pIndex, iTab, regRecord, 1);
  2396   2399     sqlite3VdbeAddOp2(v, OP_SorterInsert, iSorter, regRecord);
  2397   2400     sqlite3VdbeAddOp2(v, OP_Next, iTab, addr1+1);
  2398   2401     sqlite3VdbeJumpHere(v, addr1);
  2399   2402     addr1 = sqlite3VdbeAddOp2(v, OP_SorterSort, iSorter, 0);
  2400   2403     if( pIndex->onError!=OE_None ){
  2401   2404       int j2 = sqlite3VdbeCurrentAddr(v) + 3;
  2402   2405       sqlite3VdbeAddOp2(v, OP_Goto, 0, j2);
................................................................................
  2408   2411     }else{
  2409   2412       addr2 = sqlite3VdbeCurrentAddr(v);
  2410   2413     }
  2411   2414     sqlite3VdbeAddOp2(v, OP_SorterData, iSorter, regRecord);
  2412   2415     sqlite3VdbeAddOp3(v, OP_IdxInsert, iIdx, regRecord, 1);
  2413   2416     sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
  2414   2417   #else
         2418  +  regIdxKey = sqlite3GenerateIndexKey(pParse, pIndex, iTab, regRecord, 1);
         2419  +  addr2 = addr1 + 1;
  2415   2420     if( pIndex->onError!=OE_None ){
  2416   2421       const int regRowid = regIdxKey + pIndex->nColumn;
  2417   2422       const int j2 = sqlite3VdbeCurrentAddr(v) + 2;
  2418   2423       void * const pRegKey = SQLITE_INT_TO_PTR(regIdxKey);
  2419   2424   
  2420   2425       /* The registers accessed by the OP_IsUnique opcode were allocated
  2421   2426       ** using sqlite3GetTempRange() inside of the sqlite3GenerateIndexKey()
................................................................................
  2505   2510       /* Use the two-part index name to determine the database 
  2506   2511       ** to search for the table. 'Fix' the table name to this db
  2507   2512       ** before looking up the table.
  2508   2513       */
  2509   2514       assert( pName1 && pName2 );
  2510   2515       iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pName);
  2511   2516       if( iDb<0 ) goto exit_create_index;
         2517  +    assert( pName && pName->z );
  2512   2518   
  2513   2519   #ifndef SQLITE_OMIT_TEMPDB
  2514   2520       /* If the index name was unqualified, check if the the table
  2515   2521       ** is a temp table. If so, set the database to 1. Do not do this
  2516   2522       ** if initialising a database schema.
  2517   2523       */
  2518   2524       if( !db->init.busy ){
................................................................................
  2532   2538       }
  2533   2539       pTab = sqlite3LocateTable(pParse, 0, pTblName->a[0].zName, 
  2534   2540           pTblName->a[0].zDatabase);
  2535   2541       if( !pTab || db->mallocFailed ) goto exit_create_index;
  2536   2542       assert( db->aDb[iDb].pSchema==pTab->pSchema );
  2537   2543     }else{
  2538   2544       assert( pName==0 );
         2545  +    assert( pStart==0 );
  2539   2546       pTab = pParse->pNewTable;
  2540   2547       if( !pTab ) goto exit_create_index;
  2541   2548       iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
  2542   2549     }
  2543   2550     pDb = &db->aDb[iDb];
  2544   2551   
  2545   2552     assert( pTab!=0 );
................................................................................
  2574   2581     ** If pName==0 it means that we are
  2575   2582     ** dealing with a primary key or UNIQUE constraint.  We have to invent our
  2576   2583     ** own name.
  2577   2584     */
  2578   2585     if( pName ){
  2579   2586       zName = sqlite3NameFromToken(db, pName);
  2580   2587       if( zName==0 ) goto exit_create_index;
         2588  +    assert( pName->z!=0 );
  2581   2589       if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){
  2582   2590         goto exit_create_index;
  2583   2591       }
  2584   2592       if( !db->init.busy ){
  2585   2593         if( sqlite3FindTable(db, zName, 0)!=0 ){
  2586   2594           sqlite3ErrorMsg(pParse, "there is already a table named %s", zName);
  2587   2595           goto exit_create_index;
................................................................................
  3429   3437     sqlite3VdbeAddOp2(v, OP_AutoCommit, 0, 0);
  3430   3438   }
  3431   3439   
  3432   3440   /*
  3433   3441   ** Commit a transaction
  3434   3442   */
  3435   3443   void sqlite3CommitTransaction(Parse *pParse){
  3436         -  sqlite3 *db;
  3437   3444     Vdbe *v;
  3438   3445   
  3439   3446     assert( pParse!=0 );
  3440         -  db = pParse->db;
  3441         -  assert( db!=0 );
  3442         -/*  if( db->aDb[0].pBt==0 ) return; */
         3447  +  assert( pParse->db!=0 );
  3443   3448     if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "COMMIT", 0, 0) ){
  3444   3449       return;
  3445   3450     }
  3446   3451     v = sqlite3GetVdbe(pParse);
  3447   3452     if( v ){
  3448   3453       sqlite3VdbeAddOp2(v, OP_AutoCommit, 1, 0);
  3449   3454     }
  3450   3455   }
  3451   3456   
  3452   3457   /*
  3453   3458   ** Rollback a transaction
  3454   3459   */
  3455   3460   void sqlite3RollbackTransaction(Parse *pParse){
  3456         -  sqlite3 *db;
  3457   3461     Vdbe *v;
  3458   3462   
  3459   3463     assert( pParse!=0 );
  3460         -  db = pParse->db;
  3461         -  assert( db!=0 );
  3462         -/*  if( db->aDb[0].pBt==0 ) return; */
         3464  +  assert( pParse->db!=0 );
  3463   3465     if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "ROLLBACK", 0, 0) ){
  3464   3466       return;
  3465   3467     }
  3466   3468     v = sqlite3GetVdbe(pParse);
  3467   3469     if( v ){
  3468   3470       sqlite3VdbeAddOp2(v, OP_AutoCommit, 1, 1);
  3469   3471     }

Changes to src/date.c.

   285    285     if( p->validTZ ){
   286    286       computeJD(p);
   287    287     }
   288    288     return 0;
   289    289   }
   290    290   
   291    291   /*
   292         -** Set the time to the current time reported by the VFS
          292  +** Set the time to the current time reported by the VFS.
          293  +**
          294  +** Return the number of errors.
   293    295   */
   294         -static void setDateTimeToCurrent(sqlite3_context *context, DateTime *p){
          296  +static int setDateTimeToCurrent(sqlite3_context *context, DateTime *p){
   295    297     sqlite3 *db = sqlite3_context_db_handle(context);
   296         -  sqlite3OsCurrentTimeInt64(db->pVfs, &p->iJD);
   297         -  p->validJD = 1;
          298  +  if( sqlite3OsCurrentTimeInt64(db->pVfs, &p->iJD)==SQLITE_OK ){
          299  +    p->validJD = 1;
          300  +    return 0;
          301  +  }else{
          302  +    return 1;
          303  +  }
   298    304   }
   299    305   
   300    306   /*
   301    307   ** Attempt to parse the given string into a Julian Day Number.  Return
   302    308   ** the number of errors.
   303    309   **
   304    310   ** The following are acceptable forms for the input string:
................................................................................
   320    326   ){
   321    327     double r;
   322    328     if( parseYyyyMmDd(zDate,p)==0 ){
   323    329       return 0;
   324    330     }else if( parseHhMmSs(zDate, p)==0 ){
   325    331       return 0;
   326    332     }else if( sqlite3StrICmp(zDate,"now")==0){
   327         -    setDateTimeToCurrent(context, p);
   328         -    return 0;
          333  +    return setDateTimeToCurrent(context, p);
   329    334     }else if( sqlite3AtoF(zDate, &r, sqlite3Strlen30(zDate), SQLITE_UTF8) ){
   330    335       p->iJD = (sqlite3_int64)(r*86400000.0 + 0.5);
   331    336       p->validJD = 1;
   332    337       return 0;
   333    338     }
   334    339     return 1;
   335    340   }
................................................................................
   748    753     DateTime *p
   749    754   ){
   750    755     int i;
   751    756     const unsigned char *z;
   752    757     int eType;
   753    758     memset(p, 0, sizeof(*p));
   754    759     if( argc==0 ){
   755         -    setDateTimeToCurrent(context, p);
   756         -  }else if( (eType = sqlite3_value_type(argv[0]))==SQLITE_FLOAT
          760  +    return setDateTimeToCurrent(context, p);
          761  +  }
          762  +  if( (eType = sqlite3_value_type(argv[0]))==SQLITE_FLOAT
   757    763                      || eType==SQLITE_INTEGER ){
   758    764       p->iJD = (sqlite3_int64)(sqlite3_value_double(argv[0])*86400000.0 + 0.5);
   759    765       p->validJD = 1;
   760    766     }else{
   761    767       z = sqlite3_value_text(argv[0]);
   762    768       if( !z || parseDateOrTime(context, (char*)z, p) ){
   763    769         return 1;
................................................................................
  1061   1067     int argc,
  1062   1068     sqlite3_value **argv
  1063   1069   ){
  1064   1070     time_t t;
  1065   1071     char *zFormat = (char *)sqlite3_user_data(context);
  1066   1072     sqlite3 *db;
  1067   1073     sqlite3_int64 iT;
         1074  +  struct tm *pTm;
         1075  +  struct tm sNow;
  1068   1076     char zBuf[20];
  1069   1077   
  1070   1078     UNUSED_PARAMETER(argc);
  1071   1079     UNUSED_PARAMETER(argv);
  1072   1080   
  1073   1081     db = sqlite3_context_db_handle(context);
  1074         -  sqlite3OsCurrentTimeInt64(db->pVfs, &iT);
         1082  +  if( sqlite3OsCurrentTimeInt64(db->pVfs, &iT) ) return;
  1075   1083     t = iT/1000 - 10000*(sqlite3_int64)21086676;
  1076   1084   #ifdef HAVE_GMTIME_R
  1077         -  {
  1078         -    struct tm sNow;
  1079         -    gmtime_r(&t, &sNow);
  1080         -    strftime(zBuf, 20, zFormat, &sNow);
  1081         -  }
         1085  +  pTm = gmtime_r(&t, &sNow);
  1082   1086   #else
  1083         -  {
  1084         -    struct tm *pTm;
  1085         -    sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
  1086         -    pTm = gmtime(&t);
  1087         -    strftime(zBuf, 20, zFormat, pTm);
  1088         -    sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
  1089         -  }
         1087  +  sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
         1088  +  pTm = gmtime(&t);
         1089  +  if( pTm ) memcpy(&sNow, pTm, sizeof(sNow));
         1090  +  sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
  1090   1091   #endif
  1091         -
  1092         -  sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
         1092  +  if( pTm ){
         1093  +    strftime(zBuf, 20, zFormat, &sNow);
         1094  +    sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
         1095  +  }
  1093   1096   }
  1094   1097   #endif
  1095   1098   
  1096   1099   /*
  1097   1100   ** This function registered all of the above C functions as SQL
  1098   1101   ** functions.  This should be the only routine in this file with
  1099   1102   ** external linkage.

Changes to src/expr.c.

   399    399       if( pToken ){
   400    400         if( nExtra==0 ){
   401    401           pNew->flags |= EP_IntValue;
   402    402           pNew->u.iValue = iValue;
   403    403         }else{
   404    404           int c;
   405    405           pNew->u.zToken = (char*)&pNew[1];
   406         -        memcpy(pNew->u.zToken, pToken->z, pToken->n);
          406  +        assert( pToken->z!=0 || pToken->n==0 );
          407  +        if( pToken->n ) memcpy(pNew->u.zToken, pToken->z, pToken->n);
   407    408           pNew->u.zToken[pToken->n] = 0;
   408    409           if( dequote && nExtra>=3 
   409    410                && ((c = pToken->z[0])=='\'' || c=='"' || c=='[' || c=='`') ){
   410    411             sqlite3Dequote(pNew->u.zToken);
   411    412             if( c=='"' ) pNew->flags |= EP_DblQuoted;
   412    413           }
   413    414         }
................................................................................
  1438   1439     /* Check to see if an existing table or index can be used to
  1439   1440     ** satisfy the query.  This is preferable to generating a new 
  1440   1441     ** ephemeral table.
  1441   1442     */
  1442   1443     p = (ExprHasProperty(pX, EP_xIsSelect) ? pX->x.pSelect : 0);
  1443   1444     if( ALWAYS(pParse->nErr==0) && isCandidateForInOpt(p) ){
  1444   1445       sqlite3 *db = pParse->db;              /* Database connection */
  1445         -    Expr *pExpr = p->pEList->a[0].pExpr;   /* Expression <column> */
  1446         -    int iCol = pExpr->iColumn;             /* Index of column <column> */
  1447   1446       Vdbe *v = sqlite3GetVdbe(pParse);      /* Virtual machine being coded */
  1448         -    Table *pTab = p->pSrc->a[0].pTab;      /* Table <table>. */
         1447  +    Table *pTab;                           /* Table <table>. */
         1448  +    Expr *pExpr;                           /* Expression <column> */
         1449  +    int iCol;                              /* Index of column <column> */
  1449   1450       int iDb;                               /* Database idx for pTab */
         1451  +
         1452  +    assert( p );                        /* Because of isCandidateForInOpt(p) */
         1453  +    assert( p->pEList!=0 );             /* Because of isCandidateForInOpt(p) */
         1454  +    assert( p->pEList->a[0].pExpr!=0 ); /* Because of isCandidateForInOpt(p) */
         1455  +    assert( p->pSrc!=0 );               /* Because of isCandidateForInOpt(p) */
         1456  +    pTab = p->pSrc->a[0].pTab;
         1457  +    pExpr = p->pEList->a[0].pExpr;
         1458  +    iCol = pExpr->iColumn;
  1450   1459      
  1451   1460       /* Code an OP_VerifyCookie and OP_TableLock for <table>. */
  1452   1461       iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
  1453   1462       sqlite3CodeVerifySchema(pParse, iDb);
  1454   1463       sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);
  1455   1464   
  1456   1465       /* This function is only called from two places. In both cases the vdbe
................................................................................
  3449   3458     if( pA->iTable!=pB->iTable || pA->iColumn!=pB->iColumn ) return 2;
  3450   3459     if( ExprHasProperty(pA, EP_IntValue) ){
  3451   3460       if( !ExprHasProperty(pB, EP_IntValue) || pA->u.iValue!=pB->u.iValue ){
  3452   3461         return 2;
  3453   3462       }
  3454   3463     }else if( pA->op!=TK_COLUMN && pA->u.zToken ){
  3455   3464       if( ExprHasProperty(pB, EP_IntValue) || NEVER(pB->u.zToken==0) ) return 2;
  3456         -    if( sqlite3StrICmp(pA->u.zToken,pB->u.zToken)!=0 ){
         3465  +    if( strcmp(pA->u.zToken,pB->u.zToken)!=0 ){
  3457   3466         return 2;
  3458   3467       }
  3459   3468     }
  3460   3469     if( (pA->flags & EP_ExpCollate)!=(pB->flags & EP_ExpCollate) ) return 1;
  3461   3470     if( (pA->flags & EP_ExpCollate)!=0 && pA->pColl!=pB->pColl ) return 2;
  3462   3471     return 0;
  3463   3472   }

Changes to src/fkey.c.

  1120   1120       sqlite3ExprDelete(db, pWhen);
  1121   1121       sqlite3ExprListDelete(db, pList);
  1122   1122       sqlite3SelectDelete(db, pSelect);
  1123   1123       if( db->mallocFailed==1 ){
  1124   1124         fkTriggerDelete(db, pTrigger);
  1125   1125         return 0;
  1126   1126       }
         1127  +    assert( pStep!=0 );
  1127   1128   
  1128   1129       switch( action ){
  1129   1130         case OE_Restrict:
  1130   1131           pStep->op = TK_SELECT; 
  1131   1132           break;
  1132   1133         case OE_Cascade: 
  1133   1134           if( !pChanges ){ 

Changes to src/func.c.

   328    328     z2 = (char*)sqlite3_value_text(argv[0]);
   329    329     n = sqlite3_value_bytes(argv[0]);
   330    330     /* Verify that the call to _bytes() does not invalidate the _text() pointer */
   331    331     assert( z2==(char*)sqlite3_value_text(argv[0]) );
   332    332     if( z2 ){
   333    333       z1 = contextMalloc(context, ((i64)n)+1);
   334    334       if( z1 ){
   335         -      memcpy(z1, z2, n+1);
   336         -      for(i=0; z1[i]; i++){
   337         -        z1[i] = (char)sqlite3Toupper(z1[i]);
          335  +      for(i=0; i<n; i++){
          336  +        z1[i] = (char)sqlite3Toupper(z2[i]);
   338    337         }
   339         -      sqlite3_result_text(context, z1, -1, sqlite3_free);
          338  +      sqlite3_result_text(context, z1, n, sqlite3_free);
   340    339       }
   341    340     }
   342    341   }
   343    342   static void lowerFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
   344         -  u8 *z1;
          343  +  char *z1;
   345    344     const char *z2;
   346    345     int i, n;
   347    346     UNUSED_PARAMETER(argc);
   348    347     z2 = (char*)sqlite3_value_text(argv[0]);
   349    348     n = sqlite3_value_bytes(argv[0]);
   350    349     /* Verify that the call to _bytes() does not invalidate the _text() pointer */
   351    350     assert( z2==(char*)sqlite3_value_text(argv[0]) );
   352    351     if( z2 ){
   353    352       z1 = contextMalloc(context, ((i64)n)+1);
   354    353       if( z1 ){
   355         -      memcpy(z1, z2, n+1);
   356         -      for(i=0; z1[i]; i++){
   357         -        z1[i] = sqlite3Tolower(z1[i]);
          354  +      for(i=0; i<n; i++){
          355  +        z1[i] = sqlite3Tolower(z2[i]);
   358    356         }
   359         -      sqlite3_result_text(context, (char *)z1, -1, sqlite3_free);
          357  +      sqlite3_result_text(context, z1, n, sqlite3_free);
   360    358       }
   361    359     }
   362    360   }
   363    361   
   364    362   
   365    363   #if 0  /* This function is never used. */
   366    364   /*

Changes to src/lempar.c.

   712    712     void *yyp,                   /* The parser */
   713    713     int yymajor,                 /* The major token code number */
   714    714     ParseTOKENTYPE yyminor       /* The value for the token */
   715    715     ParseARG_PDECL               /* Optional %extra_argument parameter */
   716    716   ){
   717    717     YYMINORTYPE yyminorunion;
   718    718     int yyact;            /* The parser action. */
          719  +#if !defined(YYERRORSYMBOL) && !defined(YYNOERRORRECOVERY)
   719    720     int yyendofinput;     /* True if we are at the end of input */
          721  +#endif
   720    722   #ifdef YYERRORSYMBOL
   721    723     int yyerrorhit = 0;   /* True if yymajor has invoked an error */
   722    724   #endif
   723    725     yyParser *yypParser;  /* The parser */
   724    726   
   725    727     /* (re)initialize the parser, if necessary */
   726    728     yypParser = (yyParser*)yyp;
................................................................................
   735    737   #endif
   736    738       yypParser->yyidx = 0;
   737    739       yypParser->yyerrcnt = -1;
   738    740       yypParser->yystack[0].stateno = 0;
   739    741       yypParser->yystack[0].major = 0;
   740    742     }
   741    743     yyminorunion.yy0 = yyminor;
          744  +#if !defined(YYERRORSYMBOL) && !defined(YYNOERRORRECOVERY)
   742    745     yyendofinput = (yymajor==0);
          746  +#endif
   743    747     ParseARG_STORE;
   744    748   
   745    749   #ifndef NDEBUG
   746    750     if( yyTraceFILE ){
   747    751       fprintf(yyTraceFILE,"%sInput %s\n",yyTracePrompt,yyTokenName[yymajor]);
   748    752     }
   749    753   #endif
   750    754   
   751    755     do{
   752    756       yyact = yy_find_shift_action(yypParser,(YYCODETYPE)yymajor);
   753    757       if( yyact<YYNSTATE ){
   754         -      assert( !yyendofinput );  /* Impossible to shift the $ token */
   755    758         yy_shift(yypParser,yyact,yymajor,&yyminorunion);
   756    759         yypParser->yyerrcnt--;
   757    760         yymajor = YYNOCODE;
   758    761       }else if( yyact < YYNSTATE + YYNRULE ){
   759    762         yy_reduce(yypParser,yyact-YYNSTATE);
   760    763       }else{
   761    764         assert( yyact == YY_ERROR_ACTION );

Changes to src/loadext.c.

   399    399     char **pzErrMsg       /* Put error message here if not 0 */
   400    400   ){
   401    401     sqlite3_vfs *pVfs = db->pVfs;
   402    402     void *handle;
   403    403     int (*xInit)(sqlite3*,char**,const sqlite3_api_routines*);
   404    404     char *zErrmsg = 0;
   405    405     void **aHandle;
   406         -  const int nMsg = 300;
          406  +  int nMsg = 300 + sqlite3Strlen30(zFile);
   407    407   
   408    408     if( pzErrMsg ) *pzErrMsg = 0;
   409    409   
   410    410     /* Ticket #1863.  To avoid a creating security problems for older
   411    411     ** applications that relink against newer versions of SQLite, the
   412    412     ** ability to run load_extension is turned off by default.  One
   413    413     ** must call sqlite3_enable_load_extension() to turn on extension
................................................................................
   436    436       }
   437    437       return SQLITE_ERROR;
   438    438     }
   439    439     xInit = (int(*)(sqlite3*,char**,const sqlite3_api_routines*))
   440    440                      sqlite3OsDlSym(pVfs, handle, zProc);
   441    441     if( xInit==0 ){
   442    442       if( pzErrMsg ){
          443  +      nMsg += sqlite3Strlen30(zProc);
   443    444         *pzErrMsg = zErrmsg = sqlite3_malloc(nMsg);
   444    445         if( zErrmsg ){
   445    446           sqlite3_snprintf(nMsg, zErrmsg,
   446    447               "no entry point [%s] in shared library [%s]", zProc,zFile);
   447    448           sqlite3OsDlError(pVfs, nMsg-1, zErrmsg);
   448    449         }
   449    450         sqlite3OsDlClose(pVfs, handle);

Changes to src/main.c.

   102    102   **    *  Calls to this routine from Y must block until the outer-most
   103    103   **       call by X completes.
   104    104   **
   105    105   **    *  Recursive calls to this routine from thread X return immediately
   106    106   **       without blocking.
   107    107   */
   108    108   int sqlite3_initialize(void){
   109         -  sqlite3_mutex *pMaster;                      /* The main static mutex */
          109  +  MUTEX_LOGIC( sqlite3_mutex *pMaster; )       /* The main static mutex */
   110    110     int rc;                                      /* Result code */
   111    111   
   112    112   #ifdef SQLITE_OMIT_WSD
   113    113     rc = sqlite3_wsd_init(4096, 24);
   114    114     if( rc!=SQLITE_OK ){
   115    115       return rc;
   116    116     }
................................................................................
   136    136   
   137    137     /* Initialize the malloc() system and the recursive pInitMutex mutex.
   138    138     ** This operation is protected by the STATIC_MASTER mutex.  Note that
   139    139     ** MutexAlloc() is called for a static mutex prior to initializing the
   140    140     ** malloc subsystem - this implies that the allocation of a static
   141    141     ** mutex must not require support from the malloc subsystem.
   142    142     */
   143         -  pMaster = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
          143  +  MUTEX_LOGIC( pMaster = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); )
   144    144     sqlite3_mutex_enter(pMaster);
   145    145     sqlite3GlobalConfig.isMutexInit = 1;
   146    146     if( !sqlite3GlobalConfig.isMallocInit ){
   147    147       rc = sqlite3MallocInit();
   148    148     }
   149    149     if( rc==SQLITE_OK ){
   150    150       sqlite3GlobalConfig.isMallocInit = 1;
................................................................................
  1210   1210   */
  1211   1211   int sqlite3_overload_function(
  1212   1212     sqlite3 *db,
  1213   1213     const char *zName,
  1214   1214     int nArg
  1215   1215   ){
  1216   1216     int nName = sqlite3Strlen30(zName);
  1217         -  int rc;
         1217  +  int rc = SQLITE_OK;
  1218   1218     sqlite3_mutex_enter(db->mutex);
  1219   1219     if( sqlite3FindFunction(db, zName, nName, nArg, SQLITE_UTF8, 0)==0 ){
  1220         -    sqlite3CreateFunc(db, zName, nArg, SQLITE_UTF8,
  1221         -                      0, sqlite3InvalidFunction, 0, 0, 0);
         1220  +    rc = sqlite3CreateFunc(db, zName, nArg, SQLITE_UTF8,
         1221  +                           0, sqlite3InvalidFunction, 0, 0, 0);
  1222   1222     }
  1223         -  rc = sqlite3ApiExit(db, SQLITE_OK);
         1223  +  rc = sqlite3ApiExit(db, rc);
  1224   1224     sqlite3_mutex_leave(db->mutex);
  1225   1225     return rc;
  1226   1226   }
  1227   1227   
  1228   1228   #ifndef SQLITE_OMIT_TRACE
  1229   1229   /*
  1230   1230   ** Register a trace function.  The pArg from the previously registered trace
................................................................................
  2299   2299   opendb_out:
  2300   2300     sqlite3_free(zOpen);
  2301   2301     if( db ){
  2302   2302       assert( db->mutex!=0 || isThreadsafe==0 || sqlite3GlobalConfig.bFullMutex==0 );
  2303   2303       sqlite3_mutex_leave(db->mutex);
  2304   2304     }
  2305   2305     rc = sqlite3_errcode(db);
         2306  +  assert( db!=0 || rc==SQLITE_NOMEM );
  2306   2307     if( rc==SQLITE_NOMEM ){
  2307   2308       sqlite3_close(db);
  2308   2309       db = 0;
  2309   2310     }else if( rc!=SQLITE_OK ){
  2310   2311       db->magic = SQLITE_MAGIC_SICK;
  2311   2312     }
  2312   2313     *ppDb = db;

Changes to src/mutex.h.

    56     56   
    57     57   #ifdef SQLITE_MUTEX_OMIT
    58     58   /*
    59     59   ** If this is a no-op implementation, implement everything as macros.
    60     60   */
    61     61   #define sqlite3_mutex_alloc(X)    ((sqlite3_mutex*)8)
    62     62   #define sqlite3_mutex_free(X)
    63         -#define sqlite3_mutex_enter(X)
           63  +#define sqlite3_mutex_enter(X)    
    64     64   #define sqlite3_mutex_try(X)      SQLITE_OK
    65         -#define sqlite3_mutex_leave(X)
           65  +#define sqlite3_mutex_leave(X)    
    66     66   #define sqlite3_mutex_held(X)     ((void)(X),1)
    67     67   #define sqlite3_mutex_notheld(X)  ((void)(X),1)
    68     68   #define sqlite3MutexAlloc(X)      ((sqlite3_mutex*)8)
    69     69   #define sqlite3MutexInit()        SQLITE_OK
    70     70   #define sqlite3MutexEnd()
           71  +#define MUTEX_LOGIC(X)
           72  +#else
           73  +#define MUTEX_LOGIC(X)            X
    71     74   #endif /* defined(SQLITE_MUTEX_OMIT) */

Changes to src/os.c.

   293    293   
   294    294   /*
   295    295   ** Register a VFS with the system.  It is harmless to register the same
   296    296   ** VFS multiple times.  The new VFS becomes the default if makeDflt is
   297    297   ** true.
   298    298   */
   299    299   int sqlite3_vfs_register(sqlite3_vfs *pVfs, int makeDflt){
   300         -  sqlite3_mutex *mutex = 0;
          300  +  MUTEX_LOGIC(sqlite3_mutex *mutex;)
   301    301   #ifndef SQLITE_OMIT_AUTOINIT
   302    302     int rc = sqlite3_initialize();
   303    303     if( rc ) return rc;
   304    304   #endif
   305         -  mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
          305  +  MUTEX_LOGIC( mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); )
   306    306     sqlite3_mutex_enter(mutex);
   307    307     vfsUnlink(pVfs);
   308    308     if( makeDflt || vfsList==0 ){
   309    309       pVfs->pNext = vfsList;
   310    310       vfsList = pVfs;
   311    311     }else{
   312    312       pVfs->pNext = vfsList->pNext;

Changes to src/os_unix.c.

   524    524   #ifdef SQLITE_DEBUG
   525    525   static int unixMutexHeld(void) {
   526    526     return sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
   527    527   }
   528    528   #endif
   529    529   
   530    530   
   531         -#ifdef SQLITE_DEBUG
          531  +#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG)
   532    532   /*
   533    533   ** Helper function for printing out trace information from debugging
   534    534   ** binaries. This returns the string represetation of the supplied
   535    535   ** integer lock-type.
   536    536   */
   537    537   static const char *azFileLock(int eFileLock){
   538    538     switch( eFileLock ){
................................................................................
  1359   1359     ** The reason a single byte cannot be used instead of the 'shared byte
  1360   1360     ** range' is that some versions of windows do not support read-locks. By
  1361   1361     ** locking a random byte from a range, concurrent SHARED locks may exist
  1362   1362     ** even if the locking primitive used is always a write-lock.
  1363   1363     */
  1364   1364     int rc = SQLITE_OK;
  1365   1365     unixFile *pFile = (unixFile*)id;
  1366         -  unixInodeInfo *pInode = pFile->pInode;
         1366  +  unixInodeInfo *pInode;
  1367   1367     struct flock lock;
  1368   1368     int tErrno = 0;
  1369   1369   
  1370   1370     assert( pFile );
  1371   1371     OSTRACE(("LOCK    %d %s was %s(%s,%d) pid=%d (unix)\n", pFile->h,
  1372   1372         azFileLock(eFileLock), azFileLock(pFile->eFileLock),
  1373         -      azFileLock(pInode->eFileLock), pInode->nShared , getpid()));
         1373  +      azFileLock(pFile->pInode->eFileLock), pFile->pInode->nShared , getpid()));
  1374   1374   
  1375   1375     /* If there is already a lock of this type or more restrictive on the
  1376   1376     ** unixFile, do nothing. Don't use the end_lock: exit path, as
  1377   1377     ** unixEnterMutex() hasn't been called yet.
  1378   1378     */
  1379   1379     if( pFile->eFileLock>=eFileLock ){
  1380   1380       OSTRACE(("LOCK    %d %s ok (already held) (unix)\n", pFile->h,
................................................................................
  1570   1570   ** remove the write lock on a region when a read lock is set.
  1571   1571   */
  1572   1572   static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){
  1573   1573     unixFile *pFile = (unixFile*)id;
  1574   1574     unixInodeInfo *pInode;
  1575   1575     struct flock lock;
  1576   1576     int rc = SQLITE_OK;
  1577         -  int h;
  1578   1577   
  1579   1578     assert( pFile );
  1580   1579     OSTRACE(("UNLOCK  %d %d was %d(%d,%d) pid=%d (unix)\n", pFile->h, eFileLock,
  1581   1580         pFile->eFileLock, pFile->pInode->eFileLock, pFile->pInode->nShared,
  1582   1581         getpid()));
  1583   1582   
  1584   1583     assert( eFileLock<=SHARED_LOCK );
  1585   1584     if( pFile->eFileLock<=eFileLock ){
  1586   1585       return SQLITE_OK;
  1587   1586     }
  1588   1587     unixEnterMutex();
  1589         -  h = pFile->h;
  1590   1588     pInode = pFile->pInode;
  1591   1589     assert( pInode->nShared!=0 );
  1592   1590     if( pFile->eFileLock>SHARED_LOCK ){
  1593   1591       assert( pInode->eFileLock==pFile->eFileLock );
  1594         -    SimulateIOErrorBenign(1);
  1595         -    SimulateIOError( h=(-1) )
  1596         -    SimulateIOErrorBenign(0);
  1597   1592   
  1598   1593   #ifndef NDEBUG
  1599   1594       /* When reducing a lock such that other processes can start
  1600   1595       ** reading the database file again, make sure that the
  1601   1596       ** transaction counter was updated if any part of the database
  1602   1597       ** file changed.  If the transaction counter is not updated,
  1603   1598       ** other connections to the same file might not realize that
  1604   1599       ** the file has changed and hence might not know to flush their
  1605   1600       ** cache.  The use of a stale cache can lead to database corruption.
  1606   1601       */
  1607         -#if 0
  1608         -    assert( pFile->inNormalWrite==0
  1609         -         || pFile->dbUpdate==0
  1610         -         || pFile->transCntrChng==1 );
  1611         -#endif
  1612   1602       pFile->inNormalWrite = 0;
  1613   1603   #endif
  1614   1604   
  1615   1605       /* downgrading to a shared lock on NFS involves clearing the write lock
  1616   1606       ** before establishing the readlock - to avoid a race condition we downgrade
  1617   1607       ** the lock in 2 blocks, so that part of the range will be covered by a 
  1618   1608       ** write lock until the rest is covered by a read lock:
................................................................................
  1706   1696       ** the lock.
  1707   1697       */
  1708   1698       pInode->nShared--;
  1709   1699       if( pInode->nShared==0 ){
  1710   1700         lock.l_type = F_UNLCK;
  1711   1701         lock.l_whence = SEEK_SET;
  1712   1702         lock.l_start = lock.l_len = 0L;
  1713         -      SimulateIOErrorBenign(1);
  1714         -      SimulateIOError( h=(-1) )
  1715         -      SimulateIOErrorBenign(0);
  1716   1703         if( unixFileLock(pFile, &lock)==0 ){
  1717   1704           pInode->eFileLock = NO_LOCK;
  1718   1705         }else{
  1719   1706           rc = SQLITE_IOERR_UNLOCK;
  1720   1707   	pFile->lastErrno = errno;
  1721   1708           pInode->eFileLock = NO_LOCK;
  1722   1709           pFile->eFileLock = NO_LOCK;
................................................................................
  3850   3837       pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
  3851   3838       if( pShmNode->mutex==0 ){
  3852   3839         rc = SQLITE_NOMEM;
  3853   3840         goto shm_open_err;
  3854   3841       }
  3855   3842   
  3856   3843       if( pInode->bProcessLock==0 ){
  3857         -      pShmNode->h = robust_open(zShmFilename, O_RDWR|O_CREAT,
  3858         -                               (sStat.st_mode & 0777));
         3844  +      const char *zRO;
         3845  +      int openFlags = O_RDWR | O_CREAT;
         3846  +      zRO = sqlite3_uri_parameter(pDbFd->zPath, "readonly_shm");
         3847  +      if( zRO && sqlite3GetBoolean(zRO) ){
         3848  +        openFlags = O_RDONLY;
         3849  +        pShmNode->isReadonly = 1;
         3850  +      }
         3851  +      pShmNode->h = robust_open(zShmFilename, openFlags, (sStat.st_mode&0777));
  3859   3852         if( pShmNode->h<0 ){
  3860         -        const char *zRO;
  3861         -        zRO = sqlite3_uri_parameter(pDbFd->zPath, "readonly_shm");
  3862         -        if( zRO && sqlite3GetBoolean(zRO) ){
  3863         -          pShmNode->h = robust_open(zShmFilename, O_RDONLY,
  3864         -                                    (sStat.st_mode & 0777));
  3865         -          pShmNode->isReadonly = 1;
  3866         -        }
  3867   3853           if( pShmNode->h<0 ){
  3868   3854             rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zShmFilename);
  3869   3855             goto shm_open_err;
  3870   3856           }
  3871   3857         }
  3872   3858     
  3873   3859         /* Check to see if another process is holding the dead-man switch.
................................................................................
  4544   4530     */
  4545   4531   #if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE
  4546   4532     assert( zFilename==0 || zFilename[0]=='/' 
  4547   4533       || pVfs->pAppData==(void*)&autolockIoFinder );
  4548   4534   #else
  4549   4535     assert( zFilename==0 || zFilename[0]=='/' );
  4550   4536   #endif
         4537  +
         4538  +  /* No locking occurs in temporary files */
         4539  +  assert( zFilename!=0 || noLock );
  4551   4540   
  4552   4541     OSTRACE(("OPEN    %-3d %s\n", h, zFilename));
  4553   4542     pNew->h = h;
  4554   4543     pNew->zPath = zFilename;
  4555   4544     if( memcmp(pVfs->zName,"unix-excl",10)==0 ){
  4556   4545       pNew->ctrlFlags = UNIXFILE_EXCL;
  4557   4546     }else{
................................................................................
  4646   4635   
  4647   4636     else if( pLockingStyle == &dotlockIoMethods ){
  4648   4637       /* Dotfile locking uses the file path so it needs to be included in
  4649   4638       ** the dotlockLockingContext 
  4650   4639       */
  4651   4640       char *zLockFile;
  4652   4641       int nFilename;
         4642  +    assert( zFilename!=0 );
  4653   4643       nFilename = (int)strlen(zFilename) + 6;
  4654   4644       zLockFile = (char *)sqlite3_malloc(nFilename);
  4655   4645       if( zLockFile==0 ){
  4656   4646         rc = SQLITE_NOMEM;
  4657   4647       }else{
  4658   4648         sqlite3_snprintf(nFilename, zLockFile, "%s" DOTLOCK_SUFFIX, zFilename);
  4659   4649       }
................................................................................
  4880   4870       ** the following naming conventions:
  4881   4871       **
  4882   4872       **   "<path to db>-journal"
  4883   4873       **   "<path to db>-wal"
  4884   4874       **   "<path to db>-journalNN"
  4885   4875       **   "<path to db>-walNN"
  4886   4876       **
  4887         -    ** where NN is a 4 digit decimal number. The NN naming schemes are 
         4877  +    ** where NN is a decimal number. The NN naming schemes are 
  4888   4878       ** used by the test_multiplex.c module.
  4889   4879       */
  4890   4880       nDb = sqlite3Strlen30(zPath) - 1; 
  4891   4881   #ifdef SQLITE_ENABLE_8_3_NAMES
  4892         -    while( nDb>0 && zPath[nDb]!='-' && zPath[nDb]!='/' ) nDb--;
  4893         -    if( nDb==0 || zPath[nDb]=='/' ) return SQLITE_OK;
         4882  +    while( nDb>0 && !sqlite3Isalnum(zPath[nDb]) ) nDb--;
         4883  +    if( nDb==0 || zPath[nDb]!='-' ) return SQLITE_OK;
  4894   4884   #else
  4895   4885       while( zPath[nDb]!='-' ){
  4896   4886         assert( nDb>0 );
  4897   4887         assert( zPath[nDb]!='\n' );
  4898   4888         nDb--;
  4899   4889       }
  4900   4890   #endif
................................................................................
  5425   5415   /*
  5426   5416   ** Find the current time (in Universal Coordinated Time).  Write into *piNow
  5427   5417   ** the current time and date as a Julian Day number times 86_400_000.  In
  5428   5418   ** other words, write into *piNow the number of milliseconds since the Julian
  5429   5419   ** epoch of noon in Greenwich on November 24, 4714 B.C according to the
  5430   5420   ** proleptic Gregorian calendar.
  5431   5421   **
  5432         -** On success, return 0.  Return 1 if the time and date cannot be found.
         5422  +** On success, return SQLITE_OK.  Return SQLITE_ERROR if the time and date 
         5423  +** cannot be found.
  5433   5424   */
  5434   5425   static int unixCurrentTimeInt64(sqlite3_vfs *NotUsed, sqlite3_int64 *piNow){
  5435   5426     static const sqlite3_int64 unixEpoch = 24405875*(sqlite3_int64)8640000;
         5427  +  int rc = SQLITE_OK;
  5436   5428   #if defined(NO_GETTOD)
  5437   5429     time_t t;
  5438   5430     time(&t);
  5439   5431     *piNow = ((sqlite3_int64)t)*1000 + unixEpoch;
  5440   5432   #elif OS_VXWORKS
  5441   5433     struct timespec sNow;
  5442   5434     clock_gettime(CLOCK_REALTIME, &sNow);
  5443   5435     *piNow = unixEpoch + 1000*(sqlite3_int64)sNow.tv_sec + sNow.tv_nsec/1000000;
  5444   5436   #else
  5445   5437     struct timeval sNow;
  5446         -  gettimeofday(&sNow, 0);
  5447         -  *piNow = unixEpoch + 1000*(sqlite3_int64)sNow.tv_sec + sNow.tv_usec/1000;
         5438  +  if( gettimeofday(&sNow, 0)==0 ){
         5439  +    *piNow = unixEpoch + 1000*(sqlite3_int64)sNow.tv_sec + sNow.tv_usec/1000;
         5440  +  }else{
         5441  +    rc = SQLITE_ERROR;
         5442  +  }
  5448   5443   #endif
  5449   5444   
  5450   5445   #ifdef SQLITE_TEST
  5451   5446     if( sqlite3_current_time ){
  5452   5447       *piNow = 1000*(sqlite3_int64)sqlite3_current_time + unixEpoch;
  5453   5448     }
  5454   5449   #endif
  5455   5450     UNUSED_PARAMETER(NotUsed);
  5456         -  return 0;
         5451  +  return rc;
  5457   5452   }
  5458   5453   
  5459   5454   /*
  5460   5455   ** Find the current time (in Universal Coordinated Time).  Write the
  5461   5456   ** current time and date as a Julian Day number into *prNow and
  5462   5457   ** return 0.  Return 1 if the time and date cannot be found.
  5463   5458   */
  5464   5459   static int unixCurrentTime(sqlite3_vfs *NotUsed, double *prNow){
  5465         -  sqlite3_int64 i;
         5460  +  sqlite3_int64 i = 0;
         5461  +  int rc;
  5466   5462     UNUSED_PARAMETER(NotUsed);
  5467         -  unixCurrentTimeInt64(0, &i);
         5463  +  rc = unixCurrentTimeInt64(0, &i);
  5468   5464     *prNow = i/86400000.0;
  5469         -  return 0;
         5465  +  return rc;
  5470   5466   }
  5471   5467   
  5472   5468   /*
  5473   5469   ** We added the xGetLastError() method with the intention of providing
  5474   5470   ** better low-level error messages when operating-system problems come up
  5475   5471   ** during SQLite operation.  But so far, none of that has been implemented
  5476   5472   ** in the core.  So this routine is never called.  For now, it is merely

Changes to src/os_win.c.

  2977   2977     free(zConverted);
  2978   2978     return (void*)h;
  2979   2979   }
  2980   2980   static void winDlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut){
  2981   2981     UNUSED_PARAMETER(pVfs);
  2982   2982     getLastErrorMsg(nBuf, zBufOut);
  2983   2983   }
  2984         -void (*winDlSym(sqlite3_vfs *pVfs, void *pHandle, const char *zSymbol))(void){
         2984  +static void (*winDlSym(sqlite3_vfs *pVfs, void *pHandle, const char *zSymbol))(void){
  2985   2985     UNUSED_PARAMETER(pVfs);
  2986   2986   #if SQLITE_OS_WINCE
  2987   2987     /* The GetProcAddressA() routine is only available on wince. */
  2988   2988     return (void(*)(void))GetProcAddressA((HANDLE)pHandle, zSymbol);
  2989   2989   #else
  2990   2990     /* All other windows platforms expect GetProcAddress() to take
  2991   2991     ** an Ansi string regardless of the _UNICODE setting */
  2992   2992     return (void(*)(void))GetProcAddress((HANDLE)pHandle, zSymbol);
  2993   2993   #endif
  2994   2994   }
  2995         -void winDlClose(sqlite3_vfs *pVfs, void *pHandle){
         2995  +static void winDlClose(sqlite3_vfs *pVfs, void *pHandle){
  2996   2996     UNUSED_PARAMETER(pVfs);
  2997   2997     FreeLibrary((HANDLE)pHandle);
  2998   2998   }
  2999   2999   #else /* if SQLITE_OMIT_LOAD_EXTENSION is defined: */
  3000   3000     #define winDlOpen  0
  3001   3001     #define winDlError 0
  3002   3002     #define winDlSym   0
................................................................................
  3062   3062   /*
  3063   3063   ** Find the current time (in Universal Coordinated Time).  Write into *piNow
  3064   3064   ** the current time and date as a Julian Day number times 86_400_000.  In
  3065   3065   ** other words, write into *piNow the number of milliseconds since the Julian
  3066   3066   ** epoch of noon in Greenwich on November 24, 4714 B.C according to the
  3067   3067   ** proleptic Gregorian calendar.
  3068   3068   **
  3069         -** On success, return 0.  Return 1 if the time and date cannot be found.
         3069  +** On success, return SQLITE_OK.  Return SQLITE_ERROR if the time and date 
         3070  +** cannot be found.
  3070   3071   */
  3071   3072   static int winCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *piNow){
  3072   3073     /* FILETIME structure is a 64-bit value representing the number of 
  3073   3074        100-nanosecond intervals since January 1, 1601 (= JD 2305813.5). 
  3074   3075     */
  3075   3076     FILETIME ft;
  3076   3077     static const sqlite3_int64 winFiletimeEpoch = 23058135*(sqlite3_int64)8640000;
................................................................................
  3082   3083         (sqlite3_int64)2000000000 + (sqlite3_int64)2000000000 + (sqlite3_int64)294967296;
  3083   3084   
  3084   3085   #if SQLITE_OS_WINCE
  3085   3086     SYSTEMTIME time;
  3086   3087     GetSystemTime(&time);
  3087   3088     /* if SystemTimeToFileTime() fails, it returns zero. */
  3088   3089     if (!SystemTimeToFileTime(&time,&ft)){
  3089         -    return 1;
         3090  +    return SQLITE_ERROR;
  3090   3091     }
  3091   3092   #else
  3092   3093     GetSystemTimeAsFileTime( &ft );
  3093   3094   #endif
  3094   3095   
  3095   3096     *piNow = winFiletimeEpoch +
  3096   3097               ((((sqlite3_int64)ft.dwHighDateTime)*max32BitValue) + 
................................................................................
  3098   3099   
  3099   3100   #ifdef SQLITE_TEST
  3100   3101     if( sqlite3_current_time ){
  3101   3102       *piNow = 1000*(sqlite3_int64)sqlite3_current_time + unixEpoch;
  3102   3103     }
  3103   3104   #endif
  3104   3105     UNUSED_PARAMETER(pVfs);
  3105         -  return 0;
         3106  +  return SQLITE_OK;
  3106   3107   }
  3107   3108   
  3108   3109   /*
  3109   3110   ** Find the current time (in Universal Coordinated Time).  Write the
  3110   3111   ** current time and date as a Julian Day number into *prNow and
  3111   3112   ** return 0.  Return 1 if the time and date cannot be found.
  3112   3113   */
  3113         -int winCurrentTime(sqlite3_vfs *pVfs, double *prNow){
         3114  +static int winCurrentTime(sqlite3_vfs *pVfs, double *prNow){
  3114   3115     int rc;
  3115   3116     sqlite3_int64 i;
  3116   3117     rc = winCurrentTimeInt64(pVfs, &i);
  3117   3118     if( !rc ){
  3118   3119       *prNow = i/86400000.0;
  3119   3120     }
  3120   3121     return rc;

Changes to src/pager.c.

  2699   2699         if( needPagerReset ){
  2700   2700           pager_reset(pPager);
  2701   2701           needPagerReset = 0;
  2702   2702         }
  2703   2703         rc = pager_playback_one_page(pPager,&pPager->journalOff,0,1,0);
  2704   2704         if( rc!=SQLITE_OK ){
  2705   2705           if( rc==SQLITE_DONE ){
  2706         -          rc = SQLITE_OK;
  2707   2706             pPager->journalOff = szJ;
  2708   2707             break;
  2709   2708           }else if( rc==SQLITE_IOERR_SHORT_READ ){
  2710   2709             /* If the journal has been truncated, simply stop reading and
  2711   2710             ** processing the journal. This might happen if the journal was
  2712   2711             ** not completely written and synced prior to a crash.  In that
  2713   2712             ** case, the database should have never been written in the
................................................................................
  2961   2960   ){
  2962   2961     int rc;                         /* Return code */
  2963   2962   #if defined(SQLITE_DEBUG) || defined(SQLITE_CHECK_PAGES)
  2964   2963     PgHdr *p;                       /* For looping over pages */
  2965   2964   #endif
  2966   2965   
  2967   2966     assert( pPager->pWal );
         2967  +  assert( pList );
  2968   2968   #ifdef SQLITE_DEBUG
  2969   2969     /* Verify that the page list is in accending order */
  2970   2970     for(p=pList; p && p->pDirty; p=p->pDirty){
  2971   2971       assert( p->pgno < p->pDirty->pgno );
  2972   2972     }
  2973   2973   #endif
  2974   2974   
................................................................................
  6831   6831         rc = sqlite3WalClose(pPager->pWal, pPager->ckptSyncFlags,
  6832   6832                              pPager->pageSize, (u8*)pPager->pTmpSpace);
  6833   6833         pPager->pWal = 0;
  6834   6834       }
  6835   6835     }
  6836   6836     return rc;
  6837   6837   }
         6838  +
         6839  +/*
         6840  +** Unless this is an in-memory or temporary database, clear the pager cache.
         6841  +*/
         6842  +void sqlite3PagerClearCache(Pager *pPager){
         6843  +  if( !MEMDB && pPager->tempFile==0 ) pager_reset(pPager);
         6844  +}
  6838   6845   
  6839   6846   #ifdef SQLITE_HAS_CODEC
  6840   6847   /*
  6841   6848   ** This function is called by the wal module when writing page content
  6842   6849   ** into the log file.
  6843   6850   **
  6844   6851   ** This function returns a pointer to a buffer containing the encrypted

Changes to src/pager.h.

   152    152   const sqlite3_vfs *sqlite3PagerVfs(Pager*);
   153    153   sqlite3_file *sqlite3PagerFile(Pager*);
   154    154   const char *sqlite3PagerJournalname(Pager*);
   155    155   int sqlite3PagerNosync(Pager*);
   156    156   void *sqlite3PagerTempSpace(Pager*);
   157    157   int sqlite3PagerIsMemdb(Pager*);
   158    158   void sqlite3PagerCacheStat(Pager *, int, int, int *);
          159  +void sqlite3PagerClearCache(Pager *);
   159    160   
   160    161   /* Functions used to truncate the database file. */
   161    162   void sqlite3PagerTruncateImage(Pager*,Pgno);
   162    163   
   163    164   #if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_WAL)
   164    165   void *sqlite3PagerCodec(DbPage *);
   165    166   #endif

Changes to src/pragma.c.

   463    463     if( sqlite3StrICmp(zLeft,"page_count")==0
   464    464      || sqlite3StrICmp(zLeft,"max_page_count")==0
   465    465     ){
   466    466       int iReg;
   467    467       if( sqlite3ReadSchema(pParse) ) goto pragma_out;
   468    468       sqlite3CodeVerifySchema(pParse, iDb);
   469    469       iReg = ++pParse->nMem;
   470         -    if( zLeft[0]=='p' ){
          470  +    if( sqlite3Tolower(zLeft[0])=='p' ){
   471    471         sqlite3VdbeAddOp2(v, OP_Pagecount, iDb, iReg);
   472    472       }else{
   473    473         sqlite3VdbeAddOp3(v, OP_MaxPgcnt, iDb, iReg, sqlite3Atoi(zRight));
   474    474       }
   475    475       sqlite3VdbeAddOp2(v, OP_ResultRow, iReg, 1);
   476    476       sqlite3VdbeSetNumCols(v, 1);
   477    477       sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zLeft, SQLITE_TRANSIENT);
................................................................................
  1076   1076       static const VdbeOpList endCode[] = {
  1077   1077         { OP_AddImm,      1, 0,        0},    /* 0 */
  1078   1078         { OP_IfNeg,       1, 0,        0},    /* 1 */
  1079   1079         { OP_String8,     0, 3,        0},    /* 2 */
  1080   1080         { OP_ResultRow,   3, 1,        0},
  1081   1081       };
  1082   1082   
  1083         -    int isQuick = (zLeft[0]=='q');
         1083  +    int isQuick = (sqlite3Tolower(zLeft[0])=='q');
  1084   1084   
  1085   1085       /* Initialize the VDBE program */
  1086   1086       if( sqlite3ReadSchema(pParse) ) goto pragma_out;
  1087   1087       pParse->nMem = 6;
  1088   1088       sqlite3VdbeSetNumCols(v, 1);
  1089   1089       sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "integrity_check", SQLITE_STATIC);
  1090   1090   

Changes to src/printf.c.

     3      3   ** the public domain.  The original comments are included here for
     4      4   ** completeness.  They are very out-of-date but might be useful as
     5      5   ** an historical reference.  Most of the "enhancements" have been backed
     6      6   ** out so that the functionality is now the same as standard printf().
     7      7   **
     8      8   **************************************************************************
     9      9   **
    10         -** The following modules is an enhanced replacement for the "printf" subroutines
    11         -** found in the standard C library.  The following enhancements are
    12         -** supported:
    13         -**
    14         -**      +  Additional functions.  The standard set of "printf" functions
    15         -**         includes printf, fprintf, sprintf, vprintf, vfprintf, and
    16         -**         vsprintf.  This module adds the following:
    17         -**
    18         -**           *  snprintf -- Works like sprintf, but has an extra argument
    19         -**                          which is the size of the buffer written to.
    20         -**
    21         -**           *  mprintf --  Similar to sprintf.  Writes output to memory
    22         -**                          obtained from malloc.
    23         -**
    24         -**           *  xprintf --  Calls a function to dispose of output.
    25         -**
    26         -**           *  nprintf --  No output, but returns the number of characters
    27         -**                          that would have been output by printf.
    28         -**
    29         -**           *  A v- version (ex: vsnprintf) of every function is also
    30         -**              supplied.
    31         -**
    32         -**      +  A few extensions to the formatting notation are supported:
    33         -**
    34         -**           *  The "=" flag (similar to "-") causes the output to be
    35         -**              be centered in the appropriately sized field.
    36         -**
    37         -**           *  The %b field outputs an integer in binary notation.
    38         -**
    39         -**           *  The %c field now accepts a precision.  The character output
    40         -**              is repeated by the number of times the precision specifies.
    41         -**
    42         -**           *  The %' field works like %c, but takes as its character the
    43         -**              next character of the format string, instead of the next
    44         -**              argument.  For example,  printf("%.78'-")  prints 78 minus
    45         -**              signs, the same as  printf("%.78c",'-').
    46         -**
    47         -**      +  When compiled using GCC on a SPARC, this version of printf is
    48         -**         faster than the library printf for SUN OS 4.1.
    49         -**
    50         -**      +  All functions are fully reentrant.
    51         -**
           10  +** This file contains code for a set of "printf"-like routines.  These
           11  +** routines format strings much like the printf() from the standard C
           12  +** library, though the implementation here has enhancements to support
           13  +** SQLlite.
    52     14   */
    53     15   #include "sqliteInt.h"
    54     16   
    55     17   /*
    56     18   ** Conversion types fall into various categories as defined by the
    57     19   ** following enumeration.
    58     20   */
................................................................................
   183    145     if( N>0 ){
   184    146       sqlite3StrAccumAppend(pAccum, zSpaces, N);
   185    147     }
   186    148   }
   187    149   
   188    150   /*
   189    151   ** On machines with a small stack size, you can redefine the
   190         -** SQLITE_PRINT_BUF_SIZE to be less than 350.
          152  +** SQLITE_PRINT_BUF_SIZE to be something smaller, if desired.
   191    153   */
   192    154   #ifndef SQLITE_PRINT_BUF_SIZE
   193         -# if defined(SQLITE_SMALL_STACK)
   194         -#   define SQLITE_PRINT_BUF_SIZE 50
   195         -# else
   196         -#   define SQLITE_PRINT_BUF_SIZE 350
   197         -# endif
          155  +# define SQLITE_PRINT_BUF_SIZE 70
   198    156   #endif
   199    157   #define etBUFSIZE SQLITE_PRINT_BUF_SIZE  /* Size of the output buffer */
   200    158   
   201    159   /*
   202         -** The root program.  All variations call this core.
   203         -**
   204         -** INPUTS:
   205         -**   func   This is a pointer to a function taking three arguments
   206         -**            1. A pointer to anything.  Same as the "arg" parameter.
   207         -**            2. A pointer to the list of characters to be output
   208         -**               (Note, this list is NOT null terminated.)
   209         -**            3. An integer number of characters to be output.
   210         -**               (Note: This number might be zero.)
   211         -**
   212         -**   arg    This is the pointer to anything which will be passed as the
   213         -**          first argument to "func".  Use it for whatever you like.
   214         -**
   215         -**   fmt    This is the format string, as in the usual print.
   216         -**
   217         -**   ap     This is a pointer to a list of arguments.  Same as in
   218         -**          vfprint.
   219         -**
   220         -** OUTPUTS:
   221         -**          The return value is the total number of characters sent to
   222         -**          the function "func".  Returns -1 on a error.
   223         -**
   224         -** Note that the order in which automatic variables are declared below
   225         -** seems to make a big difference in determining how fast this beast
   226         -** will run.
          160  +** Render a string given by "fmt" into the StrAccum object.
   227    161   */
   228    162   void sqlite3VXPrintf(
   229    163     StrAccum *pAccum,                  /* Accumulate results here */
   230    164     int useExtended,                   /* Allow extended %-conversions */
   231    165     const char *fmt,                   /* Format string */
   232    166     va_list ap                         /* arguments */
   233    167   ){
................................................................................
   242    176     etByte flag_blanksign;     /* True if " " flag is present */
   243    177     etByte flag_alternateform; /* True if "#" flag is present */
   244    178     etByte flag_altform2;      /* True if "!" flag is present */
   245    179     etByte flag_zeropad;       /* True if field width constant starts with zero */
   246    180     etByte flag_long;          /* True if "l" flag is present */
   247    181     etByte flag_longlong;      /* True if the "ll" flag is present */
   248    182     etByte done;               /* Loop termination flag */
          183  +  etByte xtype = 0;          /* Conversion paradigm */
          184  +  char prefix;               /* Prefix character.  "+" or "-" or " " or '\0'. */
   249    185     sqlite_uint64 longvalue;   /* Value for integer types */
   250    186     LONGDOUBLE_TYPE realvalue; /* Value for real types */
   251    187     const et_info *infop;      /* Pointer to the appropriate info structure */
   252         -  char buf[etBUFSIZE];       /* Conversion buffer */
   253         -  char prefix;               /* Prefix character.  "+" or "-" or " " or '\0'. */
   254         -  etByte xtype = 0;          /* Conversion paradigm */
   255         -  char *zExtra;              /* Extra memory used for etTCLESCAPE conversions */
          188  +  char *zOut;                /* Rendering buffer */
          189  +  int nOut;                  /* Size of the rendering buffer */
          190  +  char *zExtra;              /* Malloced memory used by some conversion */
   256    191   #ifndef SQLITE_OMIT_FLOATING_POINT
   257    192     int  exp, e2;              /* exponent of real numbers */
          193  +  int nsd;                   /* Number of significant digits returned */
   258    194     double rounder;            /* Used for rounding floating point values */
   259    195     etByte flag_dp;            /* True if decimal point should be shown */
   260    196     etByte flag_rtz;           /* True if trailing zeros should be removed */
   261         -  etByte flag_exp;           /* True to force display of the exponent */
   262         -  int nsd;                   /* Number of significant digits returned */
   263    197   #endif
          198  +  char buf[etBUFSIZE];       /* Conversion buffer */
   264    199   
   265         -  length = 0;
   266    200     bufpt = 0;
   267    201     for(; (c=(*fmt))!=0; ++fmt){
   268    202       if( c!='%' ){
   269    203         int amt;
   270    204         bufpt = (char *)fmt;
   271    205         amt = 1;
   272    206         while( (c=(*++fmt))!='%' && c!=0 ) amt++;
................................................................................
   303    237         c = *++fmt;
   304    238       }else{
   305    239         while( c>='0' && c<='9' ){
   306    240           width = width*10 + c - '0';
   307    241           c = *++fmt;
   308    242         }
   309    243       }
   310         -    if( width > etBUFSIZE-10 ){
   311         -      width = etBUFSIZE-10;
   312         -    }
   313    244       /* Get the precision */
   314    245       if( c=='.' ){
   315    246         precision = 0;
   316    247         c = *++fmt;
   317    248         if( c=='*' ){
   318    249           precision = va_arg(ap,int);
   319    250           if( precision<0 ) precision = -precision;
................................................................................
   352    283             return;
   353    284           }
   354    285           break;
   355    286         }
   356    287       }
   357    288       zExtra = 0;
   358    289   
   359         -
   360         -    /* Limit the precision to prevent overflowing buf[] during conversion */
   361         -    if( precision>etBUFSIZE-40 && (infop->flags & FLAG_STRING)==0 ){
   362         -      precision = etBUFSIZE-40;
   363         -    }
   364         -
   365    290       /*
   366    291       ** At this point, variables are initialized as follows:
   367    292       **
   368    293       **   flag_alternateform          TRUE if a '#' is present.
   369    294       **   flag_altform2               TRUE if a '!' is present.
   370    295       **   flag_plussign               TRUE if a '+' is present.
   371    296       **   flag_leftjustify            TRUE if a '-' is present or if the
................................................................................
   422    347             }
   423    348             prefix = 0;
   424    349           }
   425    350           if( longvalue==0 ) flag_alternateform = 0;
   426    351           if( flag_zeropad && precision<width-(prefix!=0) ){
   427    352             precision = width-(prefix!=0);
   428    353           }
   429         -        bufpt = &buf[etBUFSIZE-1];
          354  +        if( precision<etBUFSIZE-10 ){
          355  +          nOut = etBUFSIZE;
          356  +          zOut = buf;
          357  +        }else{
          358  +          nOut = precision + 10;
          359  +          zOut = zExtra = sqlite3Malloc( nOut );
          360  +          if( zOut==0 ){
          361  +            pAccum->mallocFailed = 1;
          362  +            return;
          363  +          }
          364  +        }
          365  +        bufpt = &zOut[nOut-1];
   430    366           if( xtype==etORDINAL ){
   431    367             static const char zOrd[] = "thstndrd";
   432    368             int x = (int)(longvalue % 10);
   433    369             if( x>=4 || (longvalue/10)%10==1 ){
   434    370               x = 0;
   435    371             }
   436         -          buf[etBUFSIZE-3] = zOrd[x*2];
   437         -          buf[etBUFSIZE-2] = zOrd[x*2+1];
   438         -          bufpt -= 2;
          372  +          *(--bufpt) = zOrd[x*2+1];
          373  +          *(--bufpt) = zOrd[x*2];
   439    374           }
   440    375           {
   441    376             register const char *cset;      /* Use registers for speed */
   442    377             register int base;
   443    378             cset = &aDigits[infop->charset];
   444    379             base = infop->base;
   445    380             do{                                           /* Convert to ascii */
   446    381               *(--bufpt) = cset[longvalue%base];
   447    382               longvalue = longvalue/base;
   448    383             }while( longvalue>0 );
   449    384           }
   450         -        length = (int)(&buf[etBUFSIZE-1]-bufpt);
          385  +        length = (int)(&zOut[nOut-1]-bufpt);
   451    386           for(idx=precision-length; idx>0; idx--){
   452    387             *(--bufpt) = '0';                             /* Zero pad */
   453    388           }
   454    389           if( prefix ) *(--bufpt) = prefix;               /* Add sign */
   455    390           if( flag_alternateform && infop->prefix ){      /* Add "0" or "0x" */
   456    391             const char *pre;
   457    392             char x;
   458    393             pre = &aPrefix[infop->prefix];
   459    394             for(; (x=(*pre))!=0; pre++) *(--bufpt) = x;
   460    395           }
   461         -        length = (int)(&buf[etBUFSIZE-1]-bufpt);
          396  +        length = (int)(&zOut[nOut-1]-bufpt);
   462    397           break;
   463    398         case etFLOAT:
   464    399         case etEXP:
   465    400         case etGENERIC:
   466    401           realvalue = va_arg(ap,double);
   467    402   #ifdef SQLITE_OMIT_FLOATING_POINT
   468    403           length = 0;
   469    404   #else
   470    405           if( precision<0 ) precision = 6;         /* Set default precision */
   471         -        if( precision>etBUFSIZE/2-10 ) precision = etBUFSIZE/2-10;
   472    406           if( realvalue<0.0 ){
   473    407             realvalue = -realvalue;
   474    408             prefix = '-';
   475    409           }else{
   476    410             if( flag_plussign )          prefix = '+';
   477    411             else if( flag_blanksign )    prefix = ' ';
   478    412             else                         prefix = 0;
................................................................................
   512    446             }
   513    447           }
   514    448           bufpt = buf;
   515    449           /*
   516    450           ** If the field type is etGENERIC, then convert to either etEXP
   517    451           ** or etFLOAT, as appropriate.
   518    452           */
   519         -        flag_exp = xtype==etEXP;
   520    453           if( xtype!=etFLOAT ){
   521    454             realvalue += rounder;
   522    455             if( realvalue>=10.0 ){ realvalue *= 0.1; exp++; }
   523    456           }
   524    457           if( xtype==etGENERIC ){
   525    458             flag_rtz = !flag_alternateform;
   526    459             if( exp<-4 || exp>precision ){
................................................................................
   533    466             flag_rtz = 0;
   534    467           }
   535    468           if( xtype==etEXP ){
   536    469             e2 = 0;
   537    470           }else{
   538    471             e2 = exp;
   539    472           }
          473  +        if( e2+precision+width > etBUFSIZE - 15 ){
          474  +          bufpt = zExtra = sqlite3Malloc( e2+precision+width+15 );
          475  +          if( bufpt==0 ){
          476  +            pAccum->mallocFailed = 1;
          477  +            return;
          478  +          }
          479  +        }
          480  +        zOut = bufpt;
   540    481           nsd = 0;
   541    482           flag_dp = (precision>0 ?1:0) | flag_alternateform | flag_altform2;
   542    483           /* The sign in front of the number */
   543    484           if( prefix ){
   544    485             *(bufpt++) = prefix;
   545    486           }
   546    487           /* Digits prior to the decimal point */
................................................................................
   564    505           /* Significant digits after the decimal point */
   565    506           while( (precision--)>0 ){
   566    507             *(bufpt++) = et_getdigit(&realvalue,&nsd);
   567    508           }
   568    509           /* Remove trailing zeros and the "." if no digits follow the "." */
   569    510           if( flag_rtz && flag_dp ){
   570    511             while( bufpt[-1]=='0' ) *(--bufpt) = 0;
   571         -          assert( bufpt>buf );
          512  +          assert( bufpt>zOut );
   572    513             if( bufpt[-1]=='.' ){
   573    514               if( flag_altform2 ){
   574    515                 *(bufpt++) = '0';
   575    516               }else{
   576    517                 *(--bufpt) = 0;
   577    518               }
   578    519             }
   579    520           }
   580    521           /* Add the "eNNN" suffix */
   581         -        if( flag_exp || xtype==etEXP ){
          522  +        if( xtype==etEXP ){
   582    523             *(bufpt++) = aDigits[infop->charset];
   583    524             if( exp<0 ){
   584    525               *(bufpt++) = '-'; exp = -exp;
   585    526             }else{
   586    527               *(bufpt++) = '+';
   587    528             }
   588    529             if( exp>=100 ){
................................................................................
   593    534             *(bufpt++) = (char)(exp%10+'0');             /* 1's digit */
   594    535           }
   595    536           *bufpt = 0;
   596    537   
   597    538           /* The converted number is in buf[] and zero terminated. Output it.
   598    539           ** Note that the number is in the usual order, not reversed as with
   599    540           ** integer conversions. */
   600         -        length = (int)(bufpt-buf);
   601         -        bufpt = buf;
          541  +        length = (int)(bufpt-zOut);
          542  +        bufpt = zOut;
   602    543   
   603    544           /* Special case:  Add leading zeros if the flag_zeropad flag is
   604    545           ** set and we are not left justified */
   605    546           if( flag_zeropad && !flag_leftjustify && length < width){
   606    547             int i;
   607    548             int nPad = width - length;
   608    549             for(i=width; i>=nPad; i--){
................................................................................
   732    673       if( flag_leftjustify ){
   733    674         register int nspace;
   734    675         nspace = width-length;
   735    676         if( nspace>0 ){
   736    677           appendSpace(pAccum, nspace);
   737    678         }
   738    679       }
   739         -    if( zExtra ){
   740         -      sqlite3_free(zExtra);
   741         -    }
          680  +    sqlite3_free(zExtra);
   742    681     }/* End for loop over the format string */
   743    682   } /* End of function */
   744    683   
   745    684   /*
   746    685   ** Append N bytes of text from z to the StrAccum object.
   747    686   */
   748    687   void sqlite3StrAccumAppend(StrAccum *p, const char *z, int N){
   749    688     assert( z!=0 || N==0 );
   750    689     if( p->tooBig | p->mallocFailed ){
   751    690       testcase(p->tooBig);
   752    691       testcase(p->mallocFailed);
   753    692       return;
   754    693     }
          694  +  assert( p->zText!=0 || p->nChar==0 );
   755    695     if( N<0 ){
   756    696       N = sqlite3Strlen30(z);
   757    697     }
   758    698     if( N==0 || NEVER(z==0) ){
   759    699       return;
   760    700     }
   761    701     if( p->nChar+N >= p->nAlloc ){
................................................................................
   779    719         }
   780    720         if( p->useMalloc==1 ){
   781    721           zNew = sqlite3DbRealloc(p->db, zOld, p->nAlloc);
   782    722         }else{
   783    723           zNew = sqlite3_realloc(zOld, p->nAlloc);
   784    724         }
   785    725         if( zNew ){
   786         -        if( zOld==0 ) memcpy(zNew, p->zText, p->nChar);
          726  +        if( zOld==0 && p->nChar>0 ) memcpy(zNew, p->zText, p->nChar);
   787    727           p->zText = zNew;
   788    728         }else{
   789    729           p->mallocFailed = 1;
   790    730           sqlite3StrAccumReset(p);
   791    731           return;
   792    732         }
   793    733       }
   794    734     }
          735  +  assert( p->zText );
   795    736     memcpy(&p->zText[p->nChar], z, N);
   796    737     p->nChar += N;
   797    738   }
   798    739   
   799    740   /*
   800    741   ** Finish off a string by making sure it is zero-terminated.
   801    742   ** Return a pointer to the resulting string.  Return a NULL

Changes to src/resolve.c.

    93     93     ** allowing it to be repopulated by the memcpy() on the following line.
    94     94     */
    95     95     ExprSetProperty(pExpr, EP_Static);
    96     96     sqlite3ExprDelete(db, pExpr);
    97     97     memcpy(pExpr, pDup, sizeof(*pExpr));
    98     98     sqlite3DbFree(db, pDup);
    99     99   }
          100  +
          101  +
          102  +/*
          103  +** Return TRUE if the name zCol occurs anywhere in the USING clause.
          104  +**
          105  +** Return FALSE if the USING clause is NULL or if it does not contain
          106  +** zCol.
          107  +*/
          108  +static int nameInUsingClause(IdList *pUsing, const char *zCol){
          109  +  if( pUsing ){
          110  +    int k;
          111  +    for(k=0; k<pUsing->nId; k++){
          112  +      if( sqlite3StrICmp(pUsing->a[k].zName, zCol)==0 ) return 1;
          113  +    }
          114  +  }
          115  +  return 0;
          116  +}
          117  +
   100    118   
   101    119   /*
   102    120   ** Given the name of a column of the form X.Y.Z or Y.Z or just Z, look up
   103    121   ** that name in the set of source tables in pSrcList and make the pExpr 
   104    122   ** expression node refer back to that source column.  The following changes
   105    123   ** are made to pExpr:
   106    124   **
................................................................................
   185    203             pExpr->iTable = pItem->iCursor;
   186    204             pExpr->pTab = pTab;
   187    205             pSchema = pTab->pSchema;
   188    206             pMatch = pItem;
   189    207           }
   190    208           for(j=0, pCol=pTab->aCol; j<pTab->nCol; j++, pCol++){
   191    209             if( sqlite3StrICmp(pCol->zName, zCol)==0 ){
   192         -            IdList *pUsing;
          210  +            /* If there has been exactly one prior match and this match
          211  +            ** is for the right-hand table of a NATURAL JOIN or is in a 
          212  +            ** USING clause, then skip this match.
          213  +            */
          214  +            if( cnt==1 ){
          215  +              if( pItem->jointype & JT_NATURAL ) continue;
          216  +              if( nameInUsingClause(pItem->pUsing, zCol) ) continue;
          217  +            }
   193    218               cnt++;
   194    219               pExpr->iTable = pItem->iCursor;
   195    220               pExpr->pTab = pTab;
   196    221               pMatch = pItem;
   197    222               pSchema = pTab->pSchema;
   198    223               /* Substitute the rowid (column -1) for the INTEGER PRIMARY KEY */
   199    224               pExpr->iColumn = j==pTab->iPKey ? -1 : (i16)j;
   200         -            if( i<pSrcList->nSrc-1 ){
   201         -              if( pItem[1].jointype & JT_NATURAL ){
   202         -                /* If this match occurred in the left table of a natural join,
   203         -                ** then skip the right table to avoid a duplicate match */
   204         -                pItem++;
   205         -                i++;
   206         -              }else if( (pUsing = pItem[1].pUsing)!=0 ){
   207         -                /* If this match occurs on a column that is in the USING clause
   208         -                ** of a join, skip the search of the right table of the join
   209         -                ** to avoid a duplicate match there. */
   210         -                int k;
   211         -                for(k=0; k<pUsing->nId; k++){
   212         -                  if( sqlite3StrICmp(pUsing->a[k].zName, zCol)==0 ){
   213         -                    pItem++;
   214         -                    i++;
   215         -                    break;
   216         -                  }
   217         -                }
   218         -              }
   219         -            }
   220    225               break;
   221    226             }
   222    227           }
   223    228         }
   224    229       }
   225    230   
   226    231   #ifndef SQLITE_OMIT_TRIGGER

Changes to src/select.c.

    61     61   ){
    62     62     Select *pNew;
    63     63     Select standin;
    64     64     sqlite3 *db = pParse->db;
    65     65     pNew = sqlite3DbMallocZero(db, sizeof(*pNew) );
    66     66     assert( db->mallocFailed || !pOffset || pLimit ); /* OFFSET implies LIMIT */
    67     67     if( pNew==0 ){
           68  +    assert( db->mallocFailed );
    68     69       pNew = &standin;
    69     70       memset(pNew, 0, sizeof(*pNew));
    70     71     }
    71     72     if( pEList==0 ){
    72     73       pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db,TK_ALL,0));
    73     74     }
    74     75     pNew->pEList = pEList;
................................................................................
    88     89     if( db->mallocFailed ) {
    89     90       clearSelect(db, pNew);
    90     91       if( pNew!=&standin ) sqlite3DbFree(db, pNew);
    91     92       pNew = 0;
    92     93     }else{
    93     94       assert( pNew->pSrc!=0 || pParse->nErr>0 );
    94     95     }
           96  +  assert( pNew!=&standin );
    95     97     return pNew;
    96     98   }
    97     99   
    98    100   /*
    99    101   ** Delete the given Select structure and all of its substructures.
   100    102   */
   101    103   void sqlite3SelectDelete(sqlite3 *db, Select *p){
................................................................................
  1266   1268                  || p->pRight->u.zToken==0 || p->pRight->u.zToken[0]!=0 );
  1267   1269       if( (zName = pEList->a[i].zName)!=0 ){
  1268   1270         /* If the column contains an "AS <name>" phrase, use <name> as the name */
  1269   1271         zName = sqlite3DbStrDup(db, zName);
  1270   1272       }else{
  1271   1273         Expr *pColExpr = p;  /* The expression that is the result column name */
  1272   1274         Table *pTab;         /* Table associated with this expression */
  1273         -      while( pColExpr->op==TK_DOT ) pColExpr = pColExpr->pRight;
         1275  +      while( pColExpr->op==TK_DOT ){
         1276  +        pColExpr = pColExpr->pRight;
         1277  +        assert( pColExpr!=0 );
         1278  +      }
  1274   1279         if( pColExpr->op==TK_COLUMN && ALWAYS(pColExpr->pTab!=0) ){
  1275   1280           /* For columns use the column name name */
  1276   1281           int iCol = pColExpr->iColumn;
  1277   1282           pTab = pColExpr->pTab;
  1278   1283           if( iCol<0 ) iCol = pTab->iPKey;
  1279   1284           zName = sqlite3MPrintf(db, "%s",
  1280   1285                    iCol>=0 ? pTab->aCol[iCol].zName : "rowid");

Changes to src/shell.c.

    13     13   ** utility for accessing SQLite databases.
    14     14   */
    15     15   #if (defined(_WIN32) || defined(WIN32)) && !defined(_CRT_SECURE_NO_WARNINGS)
    16     16   /* This needs to come before any includes for MSVC compiler */
    17     17   #define _CRT_SECURE_NO_WARNINGS
    18     18   #endif
    19     19   
           20  +/*
           21  +** Enable large-file support for fopen() and friends on unix.
           22  +*/
           23  +#ifndef SQLITE_DISABLE_LFS
           24  +# define _LARGE_FILE       1
           25  +# ifndef _FILE_OFFSET_BITS
           26  +#   define _FILE_OFFSET_BITS 64
           27  +# endif
           28  +# define _LARGEFILE_SOURCE 1
           29  +#endif
           30  +
    20     31   #include <stdlib.h>
    21     32   #include <string.h>
    22     33   #include <stdio.h>
    23     34   #include <assert.h>
    24     35   #include "sqlite3.h"
    25     36   #include <ctype.h>
    26     37   #include <stdarg.h>
................................................................................
    56     67   #if defined(_WIN32) || defined(WIN32)
    57     68   # include <io.h>
    58     69   #define isatty(h) _isatty(h)
    59     70   #define access(f,m) _access((f),(m))
    60     71   #else
    61     72   /* Make sure isatty() has a prototype.
    62     73   */
    63         -extern int isatty();
           74  +extern int isatty(int);
    64     75   #endif
    65     76   
    66     77   #if defined(_WIN32_WCE)
    67     78   /* Windows CE (arm-wince-mingw32ce-gcc) does not provide isatty()
    68     79    * thus we always assume that we have a console. That can be
    69     80    * overridden with the -batch command line option.
    70     81    */
    71     82   #define isatty(x) 1
    72     83   #endif
    73     84   
    74     85   /* True if the timer is enabled */
    75     86   static int enableTimer = 0;
           87  +
           88  +/* ctype macros that work with signed characters */
           89  +#define IsSpace(X)  isspace((unsigned char)X)
           90  +#define IsDigit(X)  isdigit((unsigned char)X)
           91  +#define ToLower(X)  (char)tolower((unsigned char)X)
    76     92   
    77     93   #if !defined(_WIN32) && !defined(WIN32) && !defined(__OS2__) && !defined(__RTP__) && !defined(_WRS_KERNEL)
    78     94   #include <sys/time.h>
    79     95   #include <sys/resource.h>
    80     96   
    81     97   /* Saved resource information for the beginning of an operation */
    82     98   static struct rusage sBegin;
................................................................................
   261    277   
   262    278   
   263    279   /*
   264    280   ** Determines if a string is a number of not.
   265    281   */
   266    282   static int isNumber(const char *z, int *realnum){
   267    283     if( *z=='-' || *z=='+' ) z++;
   268         -  if( !isdigit(*z) ){
          284  +  if( !IsDigit(*z) ){
   269    285       return 0;
   270    286     }
   271    287     z++;
   272    288     if( realnum ) *realnum = 0;
   273         -  while( isdigit(*z) ){ z++; }
          289  +  while( IsDigit(*z) ){ z++; }
   274    290     if( *z=='.' ){
   275    291       z++;
   276         -    if( !isdigit(*z) ) return 0;
   277         -    while( isdigit(*z) ){ z++; }
          292  +    if( !IsDigit(*z) ) return 0;
          293  +    while( IsDigit(*z) ){ z++; }
   278    294       if( realnum ) *realnum = 1;
   279    295     }
   280    296     if( *z=='e' || *z=='E' ){
   281    297       z++;
   282    298       if( *z=='+' || *z=='-' ) z++;
   283         -    if( !isdigit(*z) ) return 0;
   284         -    while( isdigit(*z) ){ z++; }
          299  +    if( !IsDigit(*z) ) return 0;
          300  +    while( IsDigit(*z) ){ z++; }
   285    301       if( realnum ) *realnum = 1;
   286    302     }
   287    303     return *z==0;
   288    304   }
   289    305   
   290    306   /*
   291    307   ** A global char* and an SQL function to access its current value 
................................................................................
   318    334   ** The interface is like "readline" but no command-line editing
   319    335   ** is done.
   320    336   */
   321    337   static char *local_getline(char *zPrompt, FILE *in){
   322    338     char *zLine;
   323    339     int nLine;
   324    340     int n;
   325         -  int eol;
   326    341   
   327    342     if( zPrompt && *zPrompt ){
   328    343       printf("%s",zPrompt);
   329    344       fflush(stdout);
   330    345     }
   331    346     nLine = 100;
   332    347     zLine = malloc( nLine );
   333    348     if( zLine==0 ) return 0;
   334    349     n = 0;
   335         -  eol = 0;
   336         -  while( !eol ){
          350  +  while( 1 ){
   337    351       if( n+100>nLine ){
   338    352         nLine = nLine*2 + 100;
   339    353         zLine = realloc(zLine, nLine);
   340    354         if( zLine==0 ) return 0;
   341    355       }
   342    356       if( fgets(&zLine[n], nLine - n, in)==0 ){
   343    357         if( n==0 ){
   344    358           free(zLine);
   345    359           return 0;
   346    360         }
   347    361         zLine[n] = 0;
   348         -      eol = 1;
   349    362         break;
   350    363       }
   351    364       while( zLine[n] ){ n++; }
   352    365       if( n>0 && zLine[n-1]=='\n' ){
   353    366         n--;
   354    367         if( n>0 && zLine[n-1]=='\r' ) n--;
   355    368         zLine[n] = 0;
   356         -      eol = 1;
          369  +      break;
   357    370       }
   358    371     }
   359    372     zLine = realloc( zLine, n+1 );
   360    373     return zLine;
   361    374   }
   362    375   
   363    376   /*
................................................................................
   398    411   */
   399    412   struct callback_data {
   400    413     sqlite3 *db;           /* The database */
   401    414     int echoOn;            /* True to echo input commands */
   402    415     int statsOn;           /* True to display memory stats before each finalize */
   403    416     int cnt;               /* Number of records displayed so far */
   404    417     FILE *out;             /* Write results here */
          418  +  int nErr;              /* Number of errors seen */
   405    419     int mode;              /* An output mode setting */
   406    420     int writableSchema;    /* True if PRAGMA writable_schema=ON */
   407    421     int showHeader;        /* True to show column names in List or Column mode */
   408    422     char *zDestTable;      /* Name of destination table when MODE_Insert */
   409    423     char separator[20];    /* Separator character for MODE_List */
   410    424     int colWidth[100];     /* Requested width of each column when in column mode*/
   411    425     int actualWidth[100];  /* Actual width of each column */
................................................................................
   923    937   ** Execute a query statement that has a single result column.  Print
   924    938   ** that result column on a line by itself with a semicolon terminator.
   925    939   **
   926    940   ** This is used, for example, to show the schema of the database by
   927    941   ** querying the SQLITE_MASTER table.
   928    942   */
   929    943   static int run_table_dump_query(
   930         -  FILE *out,              /* Send output here */
   931         -  sqlite3 *db,            /* Database to query */
   932         -  const char *zSelect,    /* SELECT statement to extract content */
   933         -  const char *zFirstRow   /* Print before first row, if not NULL */
          944  +  struct callback_data *p, /* Query context */
          945  +  const char *zSelect,     /* SELECT statement to extract content */
          946  +  const char *zFirstRow    /* Print before first row, if not NULL */
   934    947   ){
   935    948     sqlite3_stmt *pSelect;
   936    949     int rc;
   937         -  rc = sqlite3_prepare(db, zSelect, -1, &pSelect, 0);
          950  +  rc = sqlite3_prepare(p->db, zSelect, -1, &pSelect, 0);
   938    951     if( rc!=SQLITE_OK || !pSelect ){
          952  +    fprintf(p->out, "/**** ERROR: (%d) %s *****/\n", rc, sqlite3_errmsg(p->db));
          953  +    p->nErr++;
   939    954       return rc;
   940    955     }
   941    956     rc = sqlite3_step(pSelect);
   942    957     while( rc==SQLITE_ROW ){
   943    958       if( zFirstRow ){
   944         -      fprintf(out, "%s", zFirstRow);
          959  +      fprintf(p->out, "%s", zFirstRow);
   945    960         zFirstRow = 0;
   946    961       }
   947         -    fprintf(out, "%s;\n", sqlite3_column_text(pSelect, 0));
          962  +    fprintf(p->out, "%s;\n", sqlite3_column_text(pSelect, 0));
   948    963       rc = sqlite3_step(pSelect);
   949    964     }
   950         -  return sqlite3_finalize(pSelect);
          965  +  rc = sqlite3_finalize(pSelect);
          966  +  if( rc!=SQLITE_OK ){
          967  +    fprintf(p->out, "/**** ERROR: (%d) %s *****/\n", rc, sqlite3_errmsg(p->db));
          968  +    p->nErr++;
          969  +  }
          970  +  return rc;
   951    971   }
   952    972   
   953    973   /*
   954    974   ** Allocate space and save off current error string.
   955    975   */
   956    976   static char *save_err_msg(
   957    977     sqlite3 *db            /* Database to query */
................................................................................
  1070   1090     int (*xCallback)(void*,int,char**,char**,int*),   /* Callback function */
  1071   1091                                                 /* (not the same as sqlite3_exec) */
  1072   1092     struct callback_data *pArg,                 /* Pointer to struct callback_data */
  1073   1093     char **pzErrMsg                             /* Error msg written here */
  1074   1094   ){
  1075   1095     sqlite3_stmt *pStmt = NULL;     /* Statement to execute. */
  1076   1096     int rc = SQLITE_OK;             /* Return Code */
         1097  +  int rc2;
  1077   1098     const char *zLeftover;          /* Tail of unprocessed SQL */
  1078   1099   
  1079   1100     if( pzErrMsg ){
  1080   1101       *pzErrMsg = NULL;
  1081   1102     }
  1082   1103   
  1083   1104     while( zSql[0] && (SQLITE_OK == rc) ){
................................................................................
  1086   1107         if( pzErrMsg ){
  1087   1108           *pzErrMsg = save_err_msg(db);
  1088   1109         }
  1089   1110       }else{
  1090   1111         if( !pStmt ){
  1091   1112           /* this happens for a comment or white-space */
  1092   1113           zSql = zLeftover;
  1093         -        while( isspace(zSql[0]) ) zSql++;
         1114  +        while( IsSpace(zSql[0]) ) zSql++;
  1094   1115           continue;
  1095   1116         }
  1096   1117   
  1097   1118         /* save off the prepared statment handle and reset row count */
  1098   1119         if( pArg ){
  1099   1120           pArg->pStmt = pStmt;
  1100   1121           pArg->cnt = 0;
................................................................................
  1163   1184         if( pArg && pArg->statsOn ){
  1164   1185           display_stats(db, pArg, 0);
  1165   1186         }
  1166   1187   
  1167   1188         /* Finalize the statement just executed. If this fails, save a 
  1168   1189         ** copy of the error message. Otherwise, set zSql to point to the
  1169   1190         ** next statement to execute. */
  1170         -      rc = sqlite3_finalize(pStmt);
         1191  +      rc2 = sqlite3_finalize(pStmt);
         1192  +      if( rc!=SQLITE_NOMEM ) rc = rc2;
  1171   1193         if( rc==SQLITE_OK ){
  1172   1194           zSql = zLeftover;
  1173         -        while( isspace(zSql[0]) ) zSql++;
         1195  +        while( IsSpace(zSql[0]) ) zSql++;
  1174   1196         }else if( pzErrMsg ){
  1175   1197           *pzErrMsg = save_err_msg(db);
  1176   1198         }
  1177   1199   
  1178   1200         /* clear saved stmt handle */
  1179   1201         if( pArg ){
  1180   1202           pArg->pStmt = NULL;
................................................................................
  1269   1291       if( rc!=SQLITE_OK || nRow==0 ){
  1270   1292         free(zSelect);
  1271   1293         return 1;
  1272   1294       }
  1273   1295       zSelect = appendText(zSelect, "|| ')' FROM  ", 0);
  1274   1296       zSelect = appendText(zSelect, zTable, '"');
  1275   1297   
  1276         -    rc = run_table_dump_query(p->out, p->db, zSelect, zPrepStmt);
         1298  +    rc = run_table_dump_query(p, zSelect, zPrepStmt);
  1277   1299       if( rc==SQLITE_CORRUPT ){
  1278   1300         zSelect = appendText(zSelect, " ORDER BY rowid DESC", 0);
  1279         -      rc = run_table_dump_query(p->out, p->db, zSelect, 0);
         1301  +      run_table_dump_query(p, zSelect, 0);
  1280   1302       }
  1281   1303       if( zSelect ) free(zSelect);
  1282   1304     }
  1283   1305     return 0;
  1284   1306   }
  1285   1307   
  1286   1308   /*
................................................................................
  1288   1310   ** the contents of the query are output as SQL statements.
  1289   1311   **
  1290   1312   ** If we get a SQLITE_CORRUPT error, rerun the query after appending
  1291   1313   ** "ORDER BY rowid DESC" to the end.
  1292   1314   */
  1293   1315   static int run_schema_dump_query(
  1294   1316     struct callback_data *p, 
  1295         -  const char *zQuery,
  1296         -  char **pzErrMsg
         1317  +  const char *zQuery
  1297   1318   ){
  1298   1319     int rc;
  1299         -  rc = sqlite3_exec(p->db, zQuery, dump_callback, p, pzErrMsg);
         1320  +  char *zErr = 0;
         1321  +  rc = sqlite3_exec(p->db, zQuery, dump_callback, p, &zErr);
  1300   1322     if( rc==SQLITE_CORRUPT ){
  1301   1323       char *zQ2;
  1302   1324       int len = strlen30(zQuery);
  1303         -    if( pzErrMsg ) sqlite3_free(*pzErrMsg);
         1325  +    fprintf(p->out, "/****** CORRUPTION ERROR *******/\n");
         1326  +    if( zErr ){
         1327  +      fprintf(p->out, "/****** %s ******/\n", zErr);
         1328  +      sqlite3_free(zErr);
         1329  +      zErr = 0;
         1330  +    }
  1304   1331       zQ2 = malloc( len+100 );
  1305   1332       if( zQ2==0 ) return rc;
  1306   1333       sqlite3_snprintf(sizeof(zQ2), zQ2, "%s ORDER BY rowid DESC", zQuery);
  1307         -    rc = sqlite3_exec(p->db, zQ2, dump_callback, p, pzErrMsg);
         1334  +    rc = sqlite3_exec(p->db, zQ2, dump_callback, p, &zErr);
         1335  +    if( rc ){
         1336  +      fprintf(p->out, "/****** ERROR: %s ******/\n", zErr);
         1337  +    }else{
         1338  +      rc = SQLITE_CORRUPT;
         1339  +    }
         1340  +    sqlite3_free(zErr);
  1308   1341       free(zQ2);
  1309   1342     }
  1310   1343     return rc;
  1311   1344   }
  1312   1345   
  1313   1346   /*
  1314   1347   ** Text of a help message
................................................................................
  1437   1470   /*
  1438   1471   ** Interpret zArg as a boolean value.  Return either 0 or 1.
  1439   1472   */
  1440   1473   static int booleanValue(char *zArg){
  1441   1474     int val = atoi(zArg);
  1442   1475     int j;
  1443   1476     for(j=0; zArg[j]; j++){
  1444         -    zArg[j] = (char)tolower(zArg[j]);
         1477  +    zArg[j] = ToLower(zArg[j]);
  1445   1478     }
  1446   1479     if( strcmp(zArg,"on")==0 ){
  1447   1480       val = 1;
  1448   1481     }else if( strcmp(zArg,"yes")==0 ){
  1449   1482       val = 1;
  1450   1483     }
  1451   1484     return val;
................................................................................
  1463   1496     int n, c;
  1464   1497     int rc = 0;
  1465   1498     char *azArg[50];
  1466   1499   
  1467   1500     /* Parse the input line into tokens.
  1468   1501     */
  1469   1502     while( zLine[i] && nArg<ArraySize(azArg) ){
  1470         -    while( isspace((unsigned char)zLine[i]) ){ i++; }
         1503  +    while( IsSpace(zLine[i]) ){ i++; }
  1471   1504       if( zLine[i]==0 ) break;
  1472   1505       if( zLine[i]=='\'' || zLine[i]=='"' ){
  1473   1506         int delim = zLine[i++];
  1474   1507         azArg[nArg++] = &zLine[i];
  1475   1508         while( zLine[i] && zLine[i]!=delim ){ i++; }
  1476   1509         if( zLine[i]==delim ){
  1477   1510           zLine[i++] = 0;
  1478   1511         }
  1479   1512         if( delim=='"' ) resolve_backslashes(azArg[nArg-1]);
  1480   1513       }else{
  1481   1514         azArg[nArg++] = &zLine[i];
  1482         -      while( zLine[i] && !isspace((unsigned char)zLine[i]) ){ i++; }
         1515  +      while( zLine[i] && !IsSpace(zLine[i]) ){ i++; }
  1483   1516         if( zLine[i] ) zLine[i++] = 0;
  1484   1517         resolve_backslashes(azArg[nArg-1]);
  1485   1518       }
  1486   1519     }
  1487   1520   
  1488   1521     /* Process the input line.
  1489   1522     */
................................................................................
  1546   1579         fprintf(stderr,"Error: %s\n", zErrMsg);
  1547   1580         sqlite3_free(zErrMsg);
  1548   1581         rc = 1;
  1549   1582       }
  1550   1583     }else
  1551   1584   
  1552   1585     if( c=='d' && strncmp(azArg[0], "dump", n)==0 && nArg<3 ){
  1553         -    char *zErrMsg = 0;
  1554   1586       open_db(p);
  1555   1587       /* When playing back a "dump", the content might appear in an order
  1556   1588       ** which causes immediate foreign key constraints to be violated.
  1557   1589       ** So disable foreign-key constraint enforcement to prevent problems. */
  1558   1590       fprintf(p->out, "PRAGMA foreign_keys=OFF;\n");
  1559   1591       fprintf(p->out, "BEGIN TRANSACTION;\n");
  1560   1592       p->writableSchema = 0;
  1561         -    sqlite3_exec(p->db, "PRAGMA writable_schema=ON", 0, 0, 0);
         1593  +    sqlite3_exec(p->db, "SAVEPOINT dump; PRAGMA writable_schema=ON", 0, 0, 0);
         1594  +    p->nErr = 0;
  1562   1595       if( nArg==1 ){
  1563   1596         run_schema_dump_query(p, 
  1564   1597           "SELECT name, type, sql FROM sqlite_master "
  1565         -        "WHERE sql NOT NULL AND type=='table' AND name!='sqlite_sequence'", 0
         1598  +        "WHERE sql NOT NULL AND type=='table' AND name!='sqlite_sequence'"
  1566   1599         );
  1567   1600         run_schema_dump_query(p, 
  1568   1601           "SELECT name, type, sql FROM sqlite_master "
  1569         -        "WHERE name=='sqlite_sequence'", 0
         1602  +        "WHERE name=='sqlite_sequence'"
  1570   1603         );
  1571         -      run_table_dump_query(p->out, p->db,
         1604  +      run_table_dump_query(p,
  1572   1605           "SELECT sql FROM sqlite_master "
  1573   1606           "WHERE sql NOT NULL AND type IN ('index','trigger','view')", 0
  1574   1607         );
  1575   1608       }else{
  1576   1609         int i;
  1577   1610         for(i=1; i<nArg; i++){
  1578   1611           zShellStatic = azArg[i];
  1579   1612           run_schema_dump_query(p,
  1580   1613             "SELECT name, type, sql FROM sqlite_master "
  1581   1614             "WHERE tbl_name LIKE shellstatic() AND type=='table'"
  1582         -          "  AND sql NOT NULL", 0);
  1583         -        run_table_dump_query(p->out, p->db,
         1615  +          "  AND sql NOT NULL");
         1616  +        run_table_dump_query(p,
  1584   1617             "SELECT sql FROM sqlite_master "
  1585   1618             "WHERE sql NOT NULL"
  1586   1619             "  AND type IN ('index','trigger','view')"
  1587   1620             "  AND tbl_name LIKE shellstatic()", 0
  1588   1621           );
  1589   1622           zShellStatic = 0;
  1590   1623         }
  1591   1624       }
  1592   1625       if( p->writableSchema ){
  1593   1626         fprintf(p->out, "PRAGMA writable_schema=OFF;\n");
  1594   1627         p->writableSchema = 0;
  1595   1628       }
  1596         -    sqlite3_exec(p->db, "PRAGMA writable_schema=OFF", 0, 0, 0);
  1597         -    if( zErrMsg ){
  1598         -      fprintf(stderr,"Error: %s\n", zErrMsg);
  1599         -      sqlite3_free(zErrMsg);
  1600         -    }else{
  1601         -      fprintf(p->out, "COMMIT;\n");
  1602         -    }
         1629  +    sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
         1630  +    sqlite3_exec(p->db, "RELEASE dump;", 0, 0, 0);
         1631  +    fprintf(p->out, p->nErr ? "ROLLBACK; -- due to errors\n" : "COMMIT;\n");
  1603   1632     }else
  1604   1633   
  1605   1634     if( c=='e' && strncmp(azArg[0], "echo", n)==0 && nArg>1 && nArg<3 ){
  1606   1635       p->echoOn = booleanValue(azArg[1]);
  1607   1636     }else
  1608   1637   
  1609   1638     if( c=='e' && strncmp(azArg[0], "exit", n)==0  && nArg==1 ){
................................................................................
  1728   1757         sqlite3_finalize(pStmt);
  1729   1758         return 1;
  1730   1759       }
  1731   1760       sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
  1732   1761       zCommit = "COMMIT";
  1733   1762       while( (zLine = local_getline(0, in))!=0 ){
  1734   1763         char *z;
  1735         -      i = 0;
  1736   1764         lineno++;
  1737   1765         azCol[0] = zLine;
  1738   1766         for(i=0, z=zLine; *z && *z!='\n' && *z!='\r'; z++){
  1739   1767           if( *z==p->separator[0] && strncmp(z, p->separator, nSep)==0 ){
  1740   1768             *z = 0;
  1741   1769             i++;
  1742   1770             if( i<nCol ){
................................................................................
  2017   2045       char *zErrMsg = 0;
  2018   2046       open_db(p);
  2019   2047       memcpy(&data, p, sizeof(data));
  2020   2048       data.showHeader = 0;
  2021   2049       data.mode = MODE_Semi;
  2022   2050       if( nArg>1 ){
  2023   2051         int i;
  2024         -      for(i=0; azArg[1][i]; i++) azArg[1][i] = (char)tolower(azArg[1][i]);
         2052  +      for(i=0; azArg[1][i]; i++) azArg[1][i] = ToLower(azArg[1][i]);
  2025   2053         if( strcmp(azArg[1],"sqlite_master")==0 ){
  2026   2054           char *new_argv[2], *new_colv[2];
  2027   2055           new_argv[0] = "CREATE TABLE sqlite_master (\n"
  2028   2056                         "  type text,\n"
  2029   2057                         "  name text,\n"
  2030   2058                         "  tbl_name text,\n"
  2031   2059                         "  rootpage integer,\n"
................................................................................
  2203   2231       ** of the option name, or a numerical value. */
  2204   2232       n = strlen30(azArg[1]);
  2205   2233       for(i=0; i<(int)(sizeof(aCtrl)/sizeof(aCtrl[0])); i++){
  2206   2234         if( strncmp(azArg[1], aCtrl[i].zCtrlName, n)==0 ){
  2207   2235           if( testctrl<0 ){
  2208   2236             testctrl = aCtrl[i].ctrlCode;
  2209   2237           }else{
  2210         -          fprintf(stderr, "ambiguous option name: \"%s\"\n", azArg[i]);
         2238  +          fprintf(stderr, "ambiguous option name: \"%s\"\n", azArg[1]);
  2211   2239             testctrl = -1;
  2212   2240             break;
  2213   2241           }
  2214   2242         }
  2215   2243       }
  2216   2244       if( testctrl<0 ) testctrl = atoi(azArg[1]);
  2217   2245       if( (testctrl<SQLITE_TESTCTRL_FIRST) || (testctrl>SQLITE_TESTCTRL_LAST) ){
................................................................................
  2340   2368   }
  2341   2369   
  2342   2370   /*
  2343   2371   ** Test to see if a line consists entirely of whitespace.
  2344   2372   */
  2345   2373   static int _all_whitespace(const char *z){
  2346   2374     for(; *z; z++){
  2347         -    if( isspace(*(unsigned char*)z) ) continue;
         2375  +    if( IsSpace(z[0]) ) continue;
  2348   2376       if( *z=='/' && z[1]=='*' ){
  2349   2377         z += 2;
  2350   2378         while( *z && (*z!='*' || z[1]!='/') ){ z++; }
  2351   2379         if( *z==0 ) return 0;
  2352   2380         z++;
  2353   2381         continue;
  2354   2382       }
................................................................................
  2365   2393   
  2366   2394   /*
  2367   2395   ** Return TRUE if the line typed in is an SQL command terminator other
  2368   2396   ** than a semi-colon.  The SQL Server style "go" command is understood
  2369   2397   ** as is the Oracle "/".
  2370   2398   */
  2371   2399   static int _is_command_terminator(const char *zLine){
  2372         -  while( isspace(*(unsigned char*)zLine) ){ zLine++; };
         2400  +  while( IsSpace(zLine[0]) ){ zLine++; };
  2373   2401     if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ){
  2374   2402       return 1;  /* Oracle */
  2375   2403     }
  2376         -  if( tolower(zLine[0])=='g' && tolower(zLine[1])=='o'
         2404  +  if( ToLower(zLine[0])=='g' && ToLower(zLine[1])=='o'
  2377   2405            && _all_whitespace(&zLine[2]) ){
  2378   2406       return 1;  /* SQL Server */
  2379   2407     }
  2380   2408     return 0;
  2381   2409   }
  2382   2410   
  2383   2411   /*
................................................................................
  2439   2467       }
  2440   2468       if( _is_command_terminator(zLine) && _is_complete(zSql, nSql) ){
  2441   2469         memcpy(zLine,";",2);
  2442   2470       }
  2443   2471       nSqlPrior = nSql;
  2444   2472       if( zSql==0 ){
  2445   2473         int i;
  2446         -      for(i=0; zLine[i] && isspace((unsigned char)zLine[i]); i++){}
         2474  +      for(i=0; zLine[i] && IsSpace(zLine[i]); i++){}
  2447   2475         if( zLine[i]!=0 ){
  2448   2476           nSql = strlen30(zLine);
  2449   2477           zSql = malloc( nSql+3 );
  2450   2478           if( zSql==0 ){
  2451   2479             fprintf(stderr, "Error: out of memory\n");
  2452   2480             exit(1);
  2453   2481           }
................................................................................
  2711   2739       /* Need to check for batch mode here to so we can avoid printing
  2712   2740       ** informational messages (like from process_sqliterc) before 
  2713   2741       ** we do the actual processing of arguments later in a second pass.
  2714   2742       */
  2715   2743       }else if( strcmp(argv[i],"-batch")==0 ){
  2716   2744         stdin_is_interactive = 0;
  2717   2745       }else if( strcmp(argv[i],"-heap")==0 ){
         2746  +#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
  2718   2747         int j, c;
  2719   2748         const char *zSize;
  2720   2749         sqlite3_int64 szHeap;
  2721   2750   
  2722   2751         zSize = argv[++i];
  2723   2752         szHeap = atoi(zSize);
  2724   2753         for(j=0; (c = zSize[j])!=0; j++){
  2725   2754           if( c=='M' ){ szHeap *= 1000000; break; }
  2726   2755           if( c=='K' ){ szHeap *= 1000; break; }
  2727   2756           if( c=='G' ){ szHeap *= 1000000000; break; }
  2728   2757         }
  2729   2758         if( szHeap>0x7fff0000 ) szHeap = 0x7fff0000;
  2730         -#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
  2731   2759         sqlite3_config(SQLITE_CONFIG_HEAP, malloc((int)szHeap), (int)szHeap, 64);
  2732   2760   #endif
  2733   2761   #ifdef SQLITE_ENABLE_VFSTRACE
  2734   2762       }else if( strcmp(argv[i],"-vfstrace")==0 ){
  2735   2763         extern int vfstrace_register(
  2736   2764            const char *zTraceName,
  2737   2765            const char *zOldVfsName,

Changes to src/sqlite.h.in.

  1395   1395   ** to using its default memory allocator (the system malloc() implementation),
  1396   1396   ** undoing any prior invocation of [SQLITE_CONFIG_MALLOC].  ^If the
  1397   1397   ** memory pointer is not NULL and either [SQLITE_ENABLE_MEMSYS3] or
  1398   1398   ** [SQLITE_ENABLE_MEMSYS5] are defined, then the alternative memory
  1399   1399   ** allocator is engaged to handle all of SQLites memory allocation needs.
  1400   1400   ** The first pointer (the memory pointer) must be aligned to an 8-byte
  1401   1401   ** boundary or subsequent behavior of SQLite will be undefined.
  1402         -** The minimum allocation size is capped at 2^12. Reasonable values
  1403         -** for the minimum allocation size are 2^5 through 2^8.</dd>
         1402  +** The minimum allocation size is capped at 2**12. Reasonable values
         1403  +** for the minimum allocation size are 2**5 through 2**8.</dd>
  1404   1404   **
  1405   1405   ** [[SQLITE_CONFIG_MUTEX]] <dt>SQLITE_CONFIG_MUTEX</dt>
  1406   1406   ** <dd> ^(This option takes a single argument which is a pointer to an
  1407   1407   ** instance of the [sqlite3_mutex_methods] structure.  The argument specifies
  1408   1408   ** alternative low-level mutex routines to be used in place
  1409   1409   ** the mutex routines built into SQLite.)^  ^SQLite makes a copy of the
  1410   1410   ** content of the [sqlite3_mutex_methods] structure before the call to
................................................................................
  2795   2795   ** first zero terminator. ^If nByte is non-negative, then it is the maximum
  2796   2796   ** number of  bytes read from zSql.  ^When nByte is non-negative, the
  2797   2797   ** zSql string ends at either the first '\000' or '\u0000' character or
  2798   2798   ** the nByte-th byte, whichever comes first. If the caller knows
  2799   2799   ** that the supplied string is nul-terminated, then there is a small
  2800   2800   ** performance advantage to be gained by passing an nByte parameter that
  2801   2801   ** is equal to the number of bytes in the input string <i>including</i>
  2802         -** the nul-terminator bytes.
         2802  +** the nul-terminator bytes as this saves SQLite from having to
         2803  +** make a copy of the input string.
  2803   2804   **
  2804   2805   ** ^If pzTail is not NULL then *pzTail is made to point to the first byte
  2805   2806   ** past the end of the first SQL statement in zSql.  These routines only
  2806   2807   ** compile the first statement in zSql, so *pzTail is left pointing to
  2807   2808   ** what remains uncompiled.
  2808   2809   **
  2809   2810   ** ^*ppStmt is left pointing to a compiled [prepared statement] that can be
................................................................................
  3016   3017   ** ^The third argument is the value to bind to the parameter.
  3017   3018   **
  3018   3019   ** ^(In those routines that have a fourth argument, its value is the
  3019   3020   ** number of bytes in the parameter.  To be clear: the value is the
  3020   3021   ** number of <u>bytes</u> in the value, not the number of characters.)^
  3021   3022   ** ^If the fourth parameter is negative, the length of the string is
  3022   3023   ** the number of bytes up to the first zero terminator.
         3024  +** If a non-negative fourth parameter is provided to sqlite3_bind_text()
         3025  +** or sqlite3_bind_text16() then that parameter must be the byte offset
         3026  +** where the NUL terminator would occur assuming the string were NUL
         3027  +** terminated.  If any NUL characters occur at byte offsets less than 
         3028  +** the value of the fourth parameter then the resulting string value will
         3029  +** contain embedded NULs.  The result of expressions involving strings
         3030  +** with embedded NULs is undefined.
  3023   3031   **
  3024   3032   ** ^The fifth argument to sqlite3_bind_blob(), sqlite3_bind_text(), and
  3025   3033   ** sqlite3_bind_text16() is a destructor used to dispose of the BLOB or
  3026   3034   ** string after SQLite has finished with it.  ^The destructor is called
  3027   3035   ** to dispose of the BLOB or string even if the call to sqlite3_bind_blob(),
  3028   3036   ** sqlite3_bind_text(), or sqlite3_bind_text16() fails.  
  3029   3037   ** ^If the fifth argument is
................................................................................
  4034   4042   ** the 2nd parameter of the sqlite3_result_text* interfaces.
  4035   4043   ** ^If the 3rd parameter to the sqlite3_result_text* interfaces
  4036   4044   ** is negative, then SQLite takes result text from the 2nd parameter
  4037   4045   ** through the first zero character.
  4038   4046   ** ^If the 3rd parameter to the sqlite3_result_text* interfaces
  4039   4047   ** is non-negative, then as many bytes (not characters) of the text
  4040   4048   ** pointed to by the 2nd parameter are taken as the application-defined
  4041         -** function result.
         4049  +** function result.  If the 3rd parameter is non-negative, then it
         4050  +** must be the byte offset into the string where the NUL terminator would
         4051  +** appear if the string where NUL terminated.  If any NUL characters occur
         4052  +** in the string at a byte offset that is less than the value of the 3rd
         4053  +** parameter, then the resulting string will contain embedded NULs and the
         4054  +** result of expressions operating on strings with embedded NULs is undefined.
  4042   4055   ** ^If the 4th parameter to the sqlite3_result_text* interfaces
  4043   4056   ** or sqlite3_result_blob is a non-NULL pointer, then SQLite calls that
  4044   4057   ** function as the destructor on the text or BLOB result when it has
  4045   4058   ** finished using that result.
  4046   4059   ** ^If the 4th parameter to the sqlite3_result_text* interfaces or to
  4047   4060   ** sqlite3_result_blob is the special constant SQLITE_STATIC, then SQLite
  4048   4061   ** assumes that the text or BLOB result is in constant space and does not

Changes to src/sqliteInt.h.

  3100   3100   #  define sqlite3VtabRollback(X)
  3101   3101   #  define sqlite3VtabCommit(X)
  3102   3102   #  define sqlite3VtabInSync(db) 0
  3103   3103   #  define sqlite3VtabLock(X) 
  3104   3104   #  define sqlite3VtabUnlock(X)
  3105   3105   #  define sqlite3VtabUnlockList(X)
  3106   3106   #  define sqlite3VtabSavepoint(X, Y, Z) SQLITE_OK
         3107  +#  define sqlite3GetVTable(X,Y)  ((VTable*)0)
  3107   3108   #else
  3108   3109      void sqlite3VtabClear(sqlite3 *db, Table*);
  3109   3110      int sqlite3VtabSync(sqlite3 *db, char **);
  3110   3111      int sqlite3VtabRollback(sqlite3 *db);
  3111   3112      int sqlite3VtabCommit(sqlite3 *db);
  3112   3113      void sqlite3VtabLock(VTable *);
  3113   3114      void sqlite3VtabUnlock(VTable *);
  3114   3115      void sqlite3VtabUnlockList(sqlite3*);
  3115   3116      int sqlite3VtabSavepoint(sqlite3 *, int, int);
         3117  +   VTable *sqlite3GetVTable(sqlite3*, Table*);
  3116   3118   #  define sqlite3VtabInSync(db) ((db)->nVTrans>0 && (db)->aVTrans==0)
  3117   3119   #endif
  3118   3120   void sqlite3VtabMakeWritable(Parse*,Table*);
  3119   3121   void sqlite3VtabBeginParse(Parse*, Token*, Token*, Token*);
  3120   3122   void sqlite3VtabFinishParse(Parse*, Token*);
  3121   3123   void sqlite3VtabArgInit(Parse*);
  3122   3124   void sqlite3VtabArgExtend(Parse*, Token*);
................................................................................
  3128   3130   void sqlite3InvalidFunction(sqlite3_context*,int,sqlite3_value**);
  3129   3131   int sqlite3VdbeParameterIndex(Vdbe*, const char*, int);
  3130   3132   int sqlite3TransferBindings(sqlite3_stmt *, sqlite3_stmt *);
  3131   3133   int sqlite3Reprepare(Vdbe*);
  3132   3134   void sqlite3ExprListCheckLength(Parse*, ExprList*, const char*);
  3133   3135   CollSeq *sqlite3BinaryCompareCollSeq(Parse *, Expr *, Expr *);
  3134   3136   int sqlite3TempInMemory(const sqlite3*);
  3135         -VTable *sqlite3GetVTable(sqlite3*, Table*);
  3136   3137   const char *sqlite3JournalModename(int);
  3137   3138   int sqlite3Checkpoint(sqlite3*, int, int, int*, int*);
  3138   3139   int sqlite3WalDefaultHook(void*,sqlite3*,const char*,int);
  3139   3140   
  3140   3141   /* Declarations for functions in fkey.c. All of these are replaced by
  3141   3142   ** no-op macros if OMIT_FOREIGN_KEY is defined. In this case no foreign
  3142   3143   ** key functionality is available. If OMIT_TRIGGER is defined but

Changes to src/tclsqlite.c.

   959    959     Tcl_DStringAppendElement(&str, zCode);
   960    960     Tcl_DStringAppendElement(&str, zArg1 ? zArg1 : "");
   961    961     Tcl_DStringAppendElement(&str, zArg2 ? zArg2 : "");
   962    962     Tcl_DStringAppendElement(&str, zArg3 ? zArg3 : "");
   963    963     Tcl_DStringAppendElement(&str, zArg4 ? zArg4 : "");
   964    964     rc = Tcl_GlobalEval(pDb->interp, Tcl_DStringValue(&str));
   965    965     Tcl_DStringFree(&str);
   966         -  zReply = Tcl_GetStringResult(pDb->interp);
          966  +  zReply = rc==TCL_OK ? Tcl_GetStringResult(pDb->interp) : "SQLITE_DENY";
   967    967     if( strcmp(zReply,"SQLITE_OK")==0 ){
   968    968       rc = SQLITE_OK;
   969    969     }else if( strcmp(zReply,"SQLITE_DENY")==0 ){
   970    970       rc = SQLITE_DENY;
   971    971     }else if( strcmp(zReply,"SQLITE_IGNORE")==0 ){
   972    972       rc = SQLITE_IGNORE;
   973    973     }else{
................................................................................
  1008   1008   **
  1009   1009   ** copied from shell.c from '.import' command
  1010   1010   */
  1011   1011   static char *local_getline(char *zPrompt, FILE *in){
  1012   1012     char *zLine;
  1013   1013     int nLine;
  1014   1014     int n;
  1015         -  int eol;
  1016   1015   
  1017   1016     nLine = 100;
  1018   1017     zLine = malloc( nLine );
  1019   1018     if( zLine==0 ) return 0;
  1020   1019     n = 0;
  1021         -  eol = 0;
  1022         -  while( !eol ){
         1020  +  while( 1 ){
  1023   1021       if( n+100>nLine ){
  1024   1022         nLine = nLine*2 + 100;
  1025   1023         zLine = realloc(zLine, nLine);
  1026   1024         if( zLine==0 ) return 0;
  1027   1025       }
  1028   1026       if( fgets(&zLine[n], nLine - n, in)==0 ){
  1029   1027         if( n==0 ){
  1030   1028           free(zLine);
  1031   1029           return 0;
  1032   1030         }
  1033   1031         zLine[n] = 0;
  1034         -      eol = 1;
  1035   1032         break;
  1036   1033       }
  1037   1034       while( zLine[n] ){ n++; }
  1038   1035       if( n>0 && zLine[n-1]=='\n' ){
  1039   1036         n--;
  1040   1037         zLine[n] = 0;
  1041         -      eol = 1;
         1038  +      break;
  1042   1039       }
  1043   1040     }
  1044   1041     zLine = realloc( zLine, n+1 );
  1045   1042     return zLine;
  1046   1043   }
  1047   1044   
  1048   1045   
................................................................................
  2202   2199         fclose(in);
  2203   2200         return TCL_ERROR;
  2204   2201       }
  2205   2202       (void)sqlite3_exec(pDb->db, "BEGIN", 0, 0, 0);
  2206   2203       zCommit = "COMMIT";
  2207   2204       while( (zLine = local_getline(0, in))!=0 ){
  2208   2205         char *z;
  2209         -      i = 0;
  2210   2206         lineno++;
  2211   2207         azCol[0] = zLine;
  2212   2208         for(i=0, z=zLine; *z; z++){
  2213   2209           if( *z==zSep[0] && strncmp(z, zSep, nSep)==0 ){
  2214   2210             *z = 0;
  2215   2211             i++;
  2216   2212             if( i<nCol ){
................................................................................
  2631   2627   
  2632   2628     /*
  2633   2629     **     $db rekey KEY
  2634   2630     **
  2635   2631     ** Change the encryption key on the currently open database.
  2636   2632     */
  2637   2633     case DB_REKEY: {
         2634  +#ifdef SQLITE_HAS_CODEC
  2638   2635       int nKey;
  2639   2636       void *pKey;
         2637  +#endif
  2640   2638       if( objc!=3 ){
  2641   2639         Tcl_WrongNumArgs(interp, 2, objv, "KEY");
  2642   2640         return TCL_ERROR;
  2643   2641       }
  2644         -    pKey = Tcl_GetByteArrayFromObj(objv[2], &nKey);
  2645   2642   #ifdef SQLITE_HAS_CODEC
         2643  +    pKey = Tcl_GetByteArrayFromObj(objv[2], &nKey);
  2646   2644       rc = sqlite3_rekey(pDb->db, pKey, nKey);
  2647   2645       if( rc ){
  2648   2646         Tcl_AppendResult(interp, sqlite3ErrStr(rc), 0);
  2649   2647         rc = TCL_ERROR;
  2650   2648       }
  2651   2649   #endif
  2652   2650       break;
................................................................................
  3062   3060   ** connection is deleted when the DBNAME command is deleted.
  3063   3061   **
  3064   3062   ** The second argument is the name of the database file.
  3065   3063   **
  3066   3064   */
  3067   3065   static int DbMain(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
  3068   3066     SqliteDb *p;
  3069         -  void *pKey = 0;
  3070         -  int nKey = 0;
  3071   3067     const char *zArg;
  3072   3068     char *zErrMsg;
  3073   3069     int i;
  3074   3070     const char *zFile;
  3075   3071     const char *zVfs = 0;
  3076   3072     int flags;
  3077   3073     Tcl_DString translatedFilename;
         3074  +#ifdef SQLITE_HAS_CODEC
         3075  +  void *pKey = 0;
         3076  +  int nKey = 0;
         3077  +#endif
  3078   3078   
  3079   3079     /* In normal use, each TCL interpreter runs in a single thread.  So
  3080   3080     ** by default, we can turn of mutexing on SQLite database connections.
  3081   3081     ** However, for testing purposes it is useful to have mutexes turned
  3082   3082     ** on.  So, by default, mutexes default off.  But if compiled with
  3083   3083     ** SQLITE_TCL_DEFAULT_FULLMUTEX then mutexes default on.
  3084   3084     */
................................................................................
  3102   3102   #endif
  3103   3103         return TCL_OK;
  3104   3104       }
  3105   3105     }
  3106   3106     for(i=3; i+1<objc; i+=2){
  3107   3107       zArg = Tcl_GetString(objv[i]);
  3108   3108       if( strcmp(zArg,"-key")==0 ){
         3109  +#ifdef SQLITE_HAS_CODEC
  3109   3110         pKey = Tcl_GetByteArrayFromObj(objv[i+1], &nKey);
         3111  +#endif
  3110   3112       }else if( strcmp(zArg, "-vfs")==0 ){
  3111   3113         zVfs = Tcl_GetString(objv[i+1]);
  3112   3114       }else if( strcmp(zArg, "-readonly")==0 ){
  3113   3115         int b;
  3114   3116         if( Tcl_GetBooleanFromObj(interp, objv[i+1], &b) ) return TCL_ERROR;
  3115   3117         if( b ){
  3116   3118           flags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE);

Changes to src/update.c.

   352    352           if( pIdx->onError==OE_Replace ){
   353    353             openAll = 1;
   354    354             break;
   355    355           }
   356    356         }
   357    357       }
   358    358       for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
          359  +      assert( aRegIdx );
   359    360         if( openAll || aRegIdx[i]>0 ){
   360    361           KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIdx);
   361    362           sqlite3VdbeAddOp4(v, OP_OpenWrite, iCur+i+1, pIdx->tnum, iDb,
   362    363                          (char*)pKey, P4_KEYINFO_HANDOFF);
   363    364           assert( pParse->nTab>iCur+i+1 );
   364    365         }
   365    366       }
................................................................................
   538    539     ** all record selected by the WHERE clause have been updated.
   539    540     */
   540    541     sqlite3VdbeAddOp2(v, OP_Goto, 0, addr);
   541    542     sqlite3VdbeJumpHere(v, addr);
   542    543   
   543    544     /* Close all tables */
   544    545     for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
          546  +    assert( aRegIdx );
   545    547       if( openAll || aRegIdx[i]>0 ){
   546    548         sqlite3VdbeAddOp2(v, OP_Close, iCur+i+1, 0);
   547    549       }
   548    550     }
   549    551     sqlite3VdbeAddOp2(v, OP_Close, iCur, 0);
   550    552   
   551    553     /* Update the sqlite_sequence table by storing the content of the

Changes to src/util.c.

   327    327         esign = -1;
   328    328         z+=incr;
   329    329       }else if( *z=='+' ){
   330    330         z+=incr;
   331    331       }
   332    332       /* copy digits to exponent */
   333    333       while( z<zEnd && sqlite3Isdigit(*z) ){
   334         -      e = e*10 + (*z - '0');
          334  +      e = e<10000 ? (e*10 + (*z - '0')) : 10000;
   335    335         z+=incr;
   336    336         eValid = 1;
   337    337       }
   338    338     }
   339    339   
   340    340     /* skip trailing spaces */
   341    341     if( nDigits && eValid ){
................................................................................
   378    378           if( esign<0 ){
   379    379             result = s / scale;
   380    380             result /= 1.0e+308;
   381    381           }else{
   382    382             result = s * scale;
   383    383             result *= 1.0e+308;
   384    384           }
          385  +      }else if( e>=342 ){
          386  +        if( esign<0 ){
          387  +          result = 0.0*s;
          388  +        }else{
          389  +          result = 1e308*1e308*s;  /* Infinity */
          390  +        }
   385    391         }else{
   386    392           /* 1.0e+22 is the largest power of 10 than can be 
   387    393           ** represented exactly. */
   388    394           while( e%22 ) { scale *= 1.0e+1; e -= 1; }
   389    395           while( e>0 ) { scale *= 1.0e+22; e -= 22; }
   390    396           if( esign<0 ){
   391    397             result = s / scale;

Changes to src/vdbe.c.

  2184   2184       if( pC->nullRow ){
  2185   2185         payloadSize = 0;
  2186   2186       }else if( pC->cacheStatus==p->cacheCtr ){
  2187   2187         payloadSize = pC->payloadSize;
  2188   2188         zRec = (char*)pC->aRow;
  2189   2189       }else if( pC->isIndex ){
  2190   2190         assert( sqlite3BtreeCursorIsValid(pCrsr) );
  2191         -      rc = sqlite3BtreeKeySize(pCrsr, &payloadSize64);
         2191  +      VVA_ONLY(rc =) sqlite3BtreeKeySize(pCrsr, &payloadSize64);
  2192   2192         assert( rc==SQLITE_OK );   /* True because of CursorMoveto() call above */
  2193   2193         /* sqlite3BtreeParseCellPtr() uses getVarint32() to extract the
  2194   2194         ** payload size, so it is impossible for payloadSize64 to be
  2195   2195         ** larger than 32 bits. */
  2196   2196         assert( (payloadSize64 & SQLITE_MAX_U32)==(u64)payloadSize64 );
  2197   2197         payloadSize = (u32)payloadSize64;
  2198   2198       }else{
  2199   2199         assert( sqlite3BtreeCursorIsValid(pCrsr) );
  2200         -      rc = sqlite3BtreeDataSize(pCrsr, &payloadSize);
         2200  +      VVA_ONLY(rc =) sqlite3BtreeDataSize(pCrsr, &payloadSize);
  2201   2201         assert( rc==SQLITE_OK );   /* DataSize() cannot fail */
  2202   2202       }
  2203   2203     }else if( ALWAYS(pC->pseudoTableReg>0) ){
  2204   2204       pReg = &aMem[pC->pseudoTableReg];
  2205   2205       assert( pReg->flags & MEM_Blob );
  2206   2206       assert( memIsValid(pReg) );
  2207   2207       payloadSize = pReg->n;
................................................................................
  4239   4239     */
  4240   4240     assert( pC->deferredMoveto==0 );
  4241   4241     rc = sqlite3VdbeCursorMoveto(pC);
  4242   4242     if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error;
  4243   4243   
  4244   4244     if( pC->isIndex ){
  4245   4245       assert( !pC->isTable );
  4246         -    rc = sqlite3BtreeKeySize(pCrsr, &n64);
         4246  +    VVA_ONLY(rc =) sqlite3BtreeKeySize(pCrsr, &n64);
  4247   4247       assert( rc==SQLITE_OK );    /* True because of CursorMoveto() call above */
  4248   4248       if( n64>db->aLimit[SQLITE_LIMIT_LENGTH] ){
  4249   4249         goto too_big;
  4250   4250       }
  4251   4251       n = (u32)n64;
  4252   4252     }else{
  4253         -    rc = sqlite3BtreeDataSize(pCrsr, &n);
         4253  +    VVA_ONLY(rc =) sqlite3BtreeDataSize(pCrsr, &n);
  4254   4254       assert( rc==SQLITE_OK );    /* DataSize() cannot fail */
  4255   4255       if( n>(u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){
  4256   4256         goto too_big;
  4257   4257       }
  4258   4258     }
  4259   4259     if( sqlite3VdbeMemGrow(pOut, n, 0) ){
  4260   4260       goto no_mem;
................................................................................
  5515   5515   #ifndef SQLITE_OMIT_WAL
  5516   5516     zFilename = sqlite3PagerFilename(pPager);
  5517   5517   
  5518   5518     /* Do not allow a transition to journal_mode=WAL for a database
  5519   5519     ** in temporary storage or if the VFS does not support shared memory 
  5520   5520     */
  5521   5521     if( eNew==PAGER_JOURNALMODE_WAL
  5522         -   && (zFilename[0]==0                         /* Temp file */
         5522  +   && (sqlite3Strlen30(zFilename)==0           /* Temp file */
  5523   5523          || !sqlite3PagerWalSupported(pPager))   /* No shared-memory support */
  5524   5524     ){
  5525   5525       eNew = eOld;
  5526   5526     }
  5527   5527   
  5528   5528     if( (eNew!=eOld)
  5529   5529      && (eOld==PAGER_JOURNALMODE_WAL || eNew==PAGER_JOURNALMODE_WAL)
................................................................................
  5936   5936   
  5937   5937     pVtab = pOp->p4.pVtab->pVtab;
  5938   5938     pName = &aMem[pOp->p1];
  5939   5939     assert( pVtab->pModule->xRename );
  5940   5940     assert( memIsValid(pName) );
  5941   5941     REGISTER_TRACE(pOp->p1, pName);
  5942   5942     assert( pName->flags & MEM_Str );
  5943         -  rc = pVtab->pModule->xRename(pVtab, pName->z);
  5944         -  importVtabErrMsg(p, pVtab);
  5945         -  p->expired = 0;
  5946         -
         5943  +  testcase( pName->enc==SQLITE_UTF8 );
         5944  +  testcase( pName->enc==SQLITE_UTF16BE );
         5945  +  testcase( pName->enc==SQLITE_UTF16LE );
         5946  +  rc = sqlite3VdbeChangeEncoding(pName, SQLITE_UTF8);
         5947  +  if( rc==SQLITE_OK ){
         5948  +    rc = pVtab->pModule->xRename(pVtab, pName->z);
         5949  +    importVtabErrMsg(p, pVtab);
         5950  +    p->expired = 0;
         5951  +  }
  5947   5952     break;
  5948   5953   }
  5949   5954   #endif
  5950   5955   
  5951   5956   #ifndef SQLITE_OMIT_VIRTUALTABLE
  5952   5957   /* Opcode: VUpdate P1 P2 P3 P4 *
  5953   5958   **

Changes to src/vdbeaux.c.

   778    778   #ifndef NDEBUG
   779    779   /*
   780    780   ** Change the comment on the the most recently coded instruction.  Or
   781    781   ** insert a No-op and add the comment to that new instruction.  This
   782    782   ** makes the code easier to read during debugging.  None of this happens
   783    783   ** in a production build.
   784    784   */
   785         -void sqlite3VdbeComment(Vdbe *p, const char *zFormat, ...){
   786         -  va_list ap;
   787         -  if( !p ) return;
          785  +static void vdbeVComment(Vdbe *p, const char *zFormat, va_list ap){
   788    786     assert( p->nOp>0 || p->aOp==0 );
   789    787     assert( p->aOp==0 || p->aOp[p->nOp-1].zComment==0 || p->db->mallocFailed );
   790    788     if( p->nOp ){
   791         -    char **pz = &p->aOp[p->nOp-1].zComment;
          789  +    assert( p->aOp );
          790  +    sqlite3DbFree(p->db, p->aOp[p->nOp-1].zComment);
          791  +    p->aOp[p->nOp-1].zComment = sqlite3VMPrintf(p->db, zFormat, ap);
          792  +  }
          793  +}
          794  +void sqlite3VdbeComment(Vdbe *p, const char *zFormat, ...){
          795  +  va_list ap;
          796  +  if( p ){
   792    797       va_start(ap, zFormat);
   793         -    sqlite3DbFree(p->db, *pz);
   794         -    *pz = sqlite3VMPrintf(p->db, zFormat, ap);
          798  +    vdbeVComment(p, zFormat, ap);
   795    799       va_end(ap);
   796    800     }
   797    801   }
   798    802   void sqlite3VdbeNoopComment(Vdbe *p, const char *zFormat, ...){
   799    803     va_list ap;
   800         -  if( !p ) return;
   801         -  sqlite3VdbeAddOp0(p, OP_Noop);
   802         -  assert( p->nOp>0 || p->aOp==0 );
   803         -  assert( p->aOp==0 || p->aOp[p->nOp-1].zComment==0 || p->db->mallocFailed );
   804         -  if( p->nOp ){
   805         -    char **pz = &p->aOp[p->nOp-1].zComment;
          804  +  if( p ){
          805  +    sqlite3VdbeAddOp0(p, OP_Noop);
   806    806       va_start(ap, zFormat);
   807         -    sqlite3DbFree(p->db, *pz);
   808         -    *pz = sqlite3VMPrintf(p->db, zFormat, ap);
          807  +    vdbeVComment(p, zFormat, ap);
   809    808       va_end(ap);
   810    809     }
   811    810   }
   812    811   #endif  /* NDEBUG */
   813    812   
   814    813   /*
   815    814   ** Return the opcode for a given address.  If the address is -1, then
................................................................................
  3062   3061   
  3063   3062     /* Get the size of the index entry.  Only indices entries of less
  3064   3063     ** than 2GiB are support - anything large must be database corruption.
  3065   3064     ** Any corruption is detected in sqlite3BtreeParseCellPtr(), though, so
  3066   3065     ** this code can safely assume that nCellKey is 32-bits  
  3067   3066     */
  3068   3067     assert( sqlite3BtreeCursorIsValid(pCur) );
  3069         -  rc = sqlite3BtreeKeySize(pCur, &nCellKey);
         3068  +  VVA_ONLY(rc =) sqlite3BtreeKeySize(pCur, &nCellKey);
  3070   3069     assert( rc==SQLITE_OK );     /* pCur is always valid so KeySize cannot fail */
  3071   3070     assert( (nCellKey & SQLITE_MAX_U32)==(u64)nCellKey );
  3072   3071   
  3073   3072     /* Read in the complete content of the index entry */
  3074   3073     memset(&m, 0, sizeof(m));
  3075   3074     rc = sqlite3VdbeMemFromBtree(pCur, 0, (int)nCellKey, 1, &m);
  3076   3075     if( rc ){
................................................................................
  3137   3136   ){
  3138   3137     i64 nCellKey = 0;
  3139   3138     int rc;
  3140   3139     BtCursor *pCur = pC->pCursor;
  3141   3140     Mem m;
  3142   3141   
  3143   3142     assert( sqlite3BtreeCursorIsValid(pCur) );
  3144         -  rc = sqlite3BtreeKeySize(pCur, &nCellKey);
         3143  +  VVA_ONLY(rc =) sqlite3BtreeKeySize(pCur, &nCellKey);
  3145   3144     assert( rc==SQLITE_OK );    /* pCur is always valid so KeySize cannot fail */
  3146   3145     /* nCellKey will always be between 0 and 0xffffffff because of the say
  3147   3146     ** that btreeParseCellPtr() and sqlite3GetVarint32() are implemented */
  3148   3147     if( nCellKey<=0 || nCellKey>0x7fffffff ){
  3149   3148       *res = 0;
  3150   3149       return SQLITE_CORRUPT_BKPT;
  3151   3150     }

Changes to src/wal.c.

  2339   2339     /* If iRead is non-zero, then it is the log frame number that contains the
  2340   2340     ** required page. Read and return data from the log file.
  2341   2341     */
  2342   2342     if( iRead ){
  2343   2343       int sz;
  2344   2344       i64 iOffset;
  2345   2345       sz = pWal->hdr.szPage;
  2346         -    sz = (pWal->hdr.szPage&0xfe00) + ((pWal->hdr.szPage&0x0001)<<16);
         2346  +    sz = (sz&0xfe00) + ((sz&0x0001)<<16);
  2347   2347       testcase( sz<=32768 );
  2348   2348       testcase( sz>=65536 );
  2349   2349       iOffset = walFrameOffset(iRead, sz) + WAL_FRAME_HDRSIZE;
  2350   2350       *pInWal = 1;
  2351   2351       /* testcase( IS_BIG_INT(iOffset) ); // requires a 4GiB WAL */
  2352   2352       return sqlite3OsRead(pWal->pWalFd, pOut, nOut, iOffset);
  2353   2353     }

Changes to src/where.c.

   701    701     if( op==TK_VARIABLE ){
   702    702       Vdbe *pReprepare = pParse->pReprepare;
   703    703       int iCol = pRight->iColumn;
   704    704       pVal = sqlite3VdbeGetValue(pReprepare, iCol, SQLITE_AFF_NONE);
   705    705       if( pVal && sqlite3_value_type(pVal)==SQLITE_TEXT ){
   706    706         z = (char *)sqlite3_value_text(pVal);
   707    707       }
   708         -    sqlite3VdbeSetVarmask(pParse->pVdbe, iCol); /* IMP: R-31526-56213 */
          708  +    sqlite3VdbeSetVarmask(pParse->pVdbe, iCol);
   709    709       assert( pRight->op==TK_VARIABLE || pRight->op==TK_REGISTER );
   710    710     }else if( op==TK_STRING ){
   711    711       z = pRight->u.zToken;
   712    712     }
   713    713     if( z ){
   714    714       cnt = 0;
   715    715       while( (c=z[cnt])!=0 && c!=wc[0] && c!=wc[1] && c!=wc[2] ){
................................................................................
   719    719         Expr *pPrefix;
   720    720         *pisComplete = c==wc[0] && z[cnt+1]==0;
   721    721         pPrefix = sqlite3Expr(db, TK_STRING, z);
   722    722         if( pPrefix ) pPrefix->u.zToken[cnt] = 0;
   723    723         *ppPrefix = pPrefix;
   724    724         if( op==TK_VARIABLE ){
   725    725           Vdbe *v = pParse->pVdbe;
   726         -        sqlite3VdbeSetVarmask(v, pRight->iColumn); /* IMP: R-31526-56213 */
          726  +        sqlite3VdbeSetVarmask(v, pRight->iColumn);
   727    727           if( *pisComplete && pRight->u.zToken[1] ){
   728    728             /* If the rhs of the LIKE expression is a variable, and the current
   729    729             ** value of the variable means there is no need to invoke the LIKE
   730    730             ** function, then no OP_Variable will be added to the program.
   731    731             ** This causes problems for the sqlite3_bind_parameter_name()
   732    732             ** API. To workaround them, add a dummy OP_Variable here.
   733    733             */ 
................................................................................
  1851   1851           }else if( pOrTerm->leftCursor==iCur ){
  1852   1852             WhereClause tempWC;
  1853   1853             tempWC.pParse = pWC->pParse;
  1854   1854             tempWC.pMaskSet = pWC->pMaskSet;
  1855   1855             tempWC.pOuter = pWC;
  1856   1856             tempWC.op = TK_AND;
  1857   1857             tempWC.a = pOrTerm;
         1858  +          tempWC.wctrlFlags = 0;
  1858   1859             tempWC.nTerm = 1;
  1859   1860             bestIndex(pParse, &tempWC, pSrc, notReady, notValid, 0, &sTermCost);
  1860   1861           }else{
  1861   1862             continue;
  1862   1863           }
  1863   1864           rTotal += sTermCost.rCost;
  1864   1865           nRow += sTermCost.plan.nRow;
................................................................................
  2472   2473     double r, rS;
  2473   2474   
  2474   2475     assert( roundUp==0 || roundUp==1 );
  2475   2476     assert( pIdx->nSample>0 );
  2476   2477     if( pVal==0 ) return SQLITE_ERROR;
  2477   2478     n = pIdx->aiRowEst[0];
  2478   2479     aSample = pIdx->aSample;
  2479         -  i = 0;
  2480   2480     eType = sqlite3_value_type(pVal);
  2481   2481   
  2482   2482     if( eType==SQLITE_INTEGER ){
  2483   2483       v = sqlite3_value_int64(pVal);
  2484   2484       r = (i64)v;
  2485   2485       for(i=0; i<pIdx->nSample; i++){
  2486   2486         if( aSample[i].eType==SQLITE_NULL ) continue;
................................................................................
  2633   2633     u8 aff, 
  2634   2634     sqlite3_value **pp
  2635   2635   ){
  2636   2636     if( pExpr->op==TK_VARIABLE
  2637   2637      || (pExpr->op==TK_REGISTER && pExpr->op2==TK_VARIABLE)
  2638   2638     ){
  2639   2639       int iVar = pExpr->iColumn;
  2640         -    sqlite3VdbeSetVarmask(pParse->pVdbe, iVar); /* IMP: R-31526-56213 */
         2640  +    sqlite3VdbeSetVarmask(pParse->pVdbe, iVar);
  2641   2641       *pp = sqlite3VdbeGetValue(pParse->pReprepare, iVar, aff);
  2642   2642       return SQLITE_OK;
  2643   2643     }
  2644   2644     return sqlite3ValueFromExpr(pParse->db, pExpr, SQLITE_UTF8, aff, pp);
  2645   2645   }
  2646   2646   #endif
  2647   2647   
................................................................................
  4892   4892         }
  4893   4893       }
  4894   4894       assert( bestJ>=0 );
  4895   4895       assert( notReady & getMask(pMaskSet, pTabList->a[bestJ].iCursor) );
  4896   4896       WHERETRACE(("*** Optimizer selects table %d for loop %d"
  4897   4897                   " with cost=%g and nRow=%g\n",
  4898   4898                   bestJ, pLevel-pWInfo->a, bestPlan.rCost, bestPlan.plan.nRow));
  4899         -    if( (bestPlan.plan.wsFlags & WHERE_ORDERBY)!=0 ){
         4899  +    /* The ALWAYS() that follows was added to hush up clang scan-build */
         4900  +    if( (bestPlan.plan.wsFlags & WHERE_ORDERBY)!=0 && ALWAYS(ppOrderBy) ){
  4900   4901         *ppOrderBy = 0;
  4901   4902       }
  4902   4903       if( (bestPlan.plan.wsFlags & WHERE_DISTINCT)!=0 ){
  4903   4904         assert( pWInfo->eDistinct==0 );
  4904   4905         pWInfo->eDistinct = WHERE_DISTINCT_ORDERED;
  4905   4906       }
  4906   4907       andFlags &= bestPlan.plan.wsFlags;

Added test/fts-9fd058691.test.

            1  +# 2011 October 13
            2  +#
            3  +#    May you do good and not evil.
            4  +#    May you find forgiveness for yourself and forgive others.
            5  +#    May you share freely, never taking more than you give.
            6  +#
            7  +#***********************************************************************
            8  +#
            9  +# This file implements regression tests for the FTS SQLite module.
           10  +#
           11  +# This file implements tests to verify that ticket [9fd058691] has been
           12  +# fixed.  
           13  +#
           14  +
           15  +set testdir [file dirname $argv0]
           16  +source $testdir/tester.tcl
           17  +
           18  +# If SQLITE_ENABLE_FTS3 is defined, omit this file.
           19  +ifcapable !fts3 {
           20  +  finish_test
           21  +  return
           22  +}
           23  +
           24  +set ::testprefix fts3-9fd058691
           25  +
           26  +do_execsql_test 1.0 {
           27  +  CREATE VIRTUAL TABLE fts USING fts3( tags TEXT);
           28  +  INSERT INTO fts (tags) VALUES ('tag1');
           29  +  SELECT * FROM fts WHERE tags MATCH 'tag1';
           30  +} {tag1}
           31  +
           32  +do_test 1.1 {
           33  +  db close
           34  +  sqlite3 db test.db
           35  +  execsql {
           36  +    UPDATE fts SET tags = 'tag1' WHERE rowid = 1;
           37  +    SELECT * FROM fts WHERE tags MATCH 'tag1';
           38  +  }
           39  +} {tag1}
           40  +
           41  +db close
           42  +forcedelete test.db
           43  +sqlite3 db test.db
           44  +
           45  +do_execsql_test 2.0 {
           46  +  CREATE VIRTUAL TABLE fts USING fts3(tags TEXT);
           47  +  INSERT INTO fts (docid, tags) VALUES (1, 'tag1');
           48  +  INSERT INTO fts (docid, tags) VALUES (2, NULL);
           49  +  INSERT INTO fts (docid, tags) VALUES (3, 'three');
           50  +} {}
           51  +
           52  +do_test 2.1 {
           53  +  execsql {
           54  +    UPDATE fts SET tags = 'two' WHERE rowid = 2;
           55  +    SELECT * FROM fts WHERE tags MATCH 'two';
           56  +  }
           57  +} {two}
           58  +
           59  +finish_test

Changes to test/fts3ao.test.

   196    196         INSERT INTO t5 VALUES('Down came a jumbuck to drink at that billabong');
   197    197         ALTER TABLE t5 RENAME TO t6;
   198    198         INSERT INTO t6 VALUES('Down came the troopers, one, two, three');
   199    199       ROLLBACK;
   200    200       SELECT * FROM t5;
   201    201     }
   202    202   } {{the quick brown fox} {jumped over the} {lazy dog}}
          203  +do_execsql_test fts3ao-4.8 {
          204  +  SELECT snippet(t5, '[', ']') FROM t5 WHERE t5 MATCH 'the'
          205  +} {{[the] quick brown fox} {jumped over [the]}}
   203    206   
   204    207   # Test that it is possible to rename an FTS4 table. Renaming an FTS4 table
   205    208   # involves renaming the extra %_docsize and %_stat tables.
   206    209   #
   207    210   do_execsql_test 5.1 {
   208    211     CREATE VIRTUAL TABLE t7 USING FTS4;
   209    212     INSERT INTO t7 VALUES('coined by a German clinician');

Changes to test/fts3d.test.

   300    300     execsql {
   301    301       UPDATE t1_segdir SET level = 2 WHERE level = 1 AND idx = 0;
   302    302       SELECT OPTIMIZE(t1) FROM t1 LIMIT 1;
   303    303       SELECT level, idx FROM t1_segdir ORDER BY level, idx;
   304    304     }
   305    305   } {{Index already optimal} 2 0}
   306    306   
          307  +
          308  +# ALTER TABLE RENAME should work regardless of the database encoding.
          309  +#
          310  +do_test fts3d-6.0 {
          311  +  db close
          312  +  forcedelete test.db
          313  +  sqlite3 db test.db
          314  +  db eval {
          315  +    PRAGMA encoding=UTF8;
          316  +    CREATE VIRTUAL TABLE fts USING fts3(a,b,c);
          317  +    SELECT name FROM sqlite_master WHERE name GLOB '???_*' ORDER BY 1;
          318  +  }
          319  +} {fts_content fts_segdir fts_segments}
          320  +do_test fts3d-6.1 {
          321  +  db eval {
          322  +    ALTER TABLE fts RENAME TO xyz;
          323  +    SELECT name FROM sqlite_master WHERE name GLOB '???_*' ORDER BY 1;
          324  +  }
          325  +} {xyz_content xyz_segdir xyz_segments}
          326  +do_test fts3d-6.2 {
          327  +  db close
          328  +  forcedelete test.db
          329  +  sqlite3 db test.db
          330  +  db eval {
          331  +    PRAGMA encoding=UTF16le;
          332  +    CREATE VIRTUAL TABLE fts USING fts3(a,b,c);
          333  +    SELECT name FROM sqlite_master WHERE name GLOB '???_*' ORDER BY 1;
          334  +  }
          335  +} {fts_content fts_segdir fts_segments}
          336  +do_test fts3d-6.3 {
          337  +  db eval {
          338  +    ALTER TABLE fts RENAME TO xyz;
          339  +    SELECT name FROM sqlite_master WHERE name GLOB '???_*' ORDER BY 1;
          340  +  }
          341  +} {xyz_content xyz_segdir xyz_segments}
          342  +do_test fts3d-6.4 {
          343  +  db close
          344  +  forcedelete test.db
          345  +  sqlite3 db test.db
          346  +  db eval {
          347  +    PRAGMA encoding=UTF16be;
          348  +    CREATE VIRTUAL TABLE fts USING fts3(a,b,c);
          349  +    SELECT name FROM sqlite_master WHERE name GLOB '???_*' ORDER BY 1;
          350  +  }
          351  +} {fts_content fts_segdir fts_segments}
          352  +do_test fts3d-6.5 {
          353  +  db eval {
          354  +    ALTER TABLE fts RENAME TO xyz;
          355  +    SELECT name FROM sqlite_master WHERE name GLOB '???_*' ORDER BY 1;
          356  +  }
          357  +} {xyz_content xyz_segdir xyz_segments}
          358  + 
          359  +
   307    360   finish_test

Changes to test/fts3defer.test.

   422    422       SELECT rowid FROM t1 WHERE t1 MATCH '"zm azavwm"'
   423    423     } {15 26 92 96}
   424    424     if {$fts3_simple_deferred_tokens_only==0} {
   425    425       do_select_test 6.2.3 {
   426    426         SELECT rowid FROM t1 WHERE t1 MATCH '"jk xduvfhk" OR "zm azavwm"'
   427    427       } {8 15 26 92 96}
   428    428     }
          429  +
          430  +  if {$tn>1} {
          431  +    # These tests will not work with $tn==1, as in this case table t1 is
          432  +    # created using FTS3. The ^ syntax is only available with FTS4 tables.
          433  +    #
          434  +    do_select_test 7.1 {
          435  +      SELECT rowid FROM t1 WHERE t1 MATCH '^zm mjpavjuhw'
          436  +    } {56 62}
          437  +    do_select_test 7.2 {
          438  +      SELECT rowid FROM t1 WHERE t1 MATCH '^azavwm zm'
          439  +    } {43}
          440  +  }
   429    441   }
   430    442   
   431    443   set testprefix fts3defer
   432    444   
   433    445   do_execsql_test 3.1 {
   434    446     CREATE VIRTUAL TABLE x1 USING fts4(a, b);
   435    447     INSERT INTO x1 VALUES('a b c', 'd e f');
................................................................................
   444    456     );
   445    457     INSERT INTO x1(x1) VALUES('optimize');
   446    458   "
   447    459   
   448    460   do_execsql_test 3.3 {
   449    461     SELECT count(*) FROM x1 WHERE x1 MATCH '"d e f"'
   450    462   } {16}
          463  +
          464  +# At one point the following was causing a floating-point exception.
          465  +#
          466  +do_execsql_test 4.1 {
          467  +  CREATE VIRTUAL TABLE x2 USING FTS4(x);
          468  +  BEGIN;
          469  +  INSERT INTO x2 VALUES('m m m m m m m m m m m m m m m m m m m m m m m m m m');
          470  +  INSERT INTO x2 SELECT * FROM x2;
          471  +  INSERT INTO x2 SELECT * FROM x2;
          472  +  INSERT INTO x2 SELECT * FROM x2;
          473  +  INSERT INTO x2 SELECT * FROM x2;
          474  +  INSERT INTO x2 SELECT * FROM x2;
          475  +  INSERT INTO x2 SELECT * FROM x2;
          476  +  INSERT INTO x2 SELECT * FROM x2;
          477  +  INSERT INTO x2 SELECT * FROM x2;
          478  +  INSERT INTO x2 SELECT * FROM x2;
          479  +  INSERT INTO x2 SELECT * FROM x2;
          480  +  INSERT INTO x2 SELECT * FROM x2;
          481  +  INSERT INTO x2 SELECT * FROM x2;
          482  +  INSERT INTO x2 SELECT * FROM x2;
          483  +  INSERT INTO x2 SELECT * FROM x2;
          484  +  INSERT INTO x2 SELECT * FROM x2;
          485  +  INSERT INTO x2 VALUES('a b c d e f g h i j k l m n o p q r s t u v w x y m');
          486  +  COMMIT;
          487  +}
          488  +do_execsql_test 4.2 {
          489  +  SELECT * FROM x2 WHERE x2 MATCH 'a b c d e f g h i j k l m n o p q r s';
          490  +} {{a b c d e f g h i j k l m n o p q r s t u v w x y m}}
   451    491   
   452    492   
   453    493   finish_test

Changes to test/fts3fault2.test.

    77     77     faultsim_restore_and_reopen
    78     78     db eval {SELECT * FROM sqlite_master}
    79     79   } -body {
    80     80     execsql "SELECT * FROM terms2"
    81     81   } -test {
    82     82     faultsim_test_result {0 {a * 1 1 a 0 1 1 b * 1 1 b 0 1 1 c * 1 1 c 0 1 1 x * 1 1 x 1 1 1 y * 1 1 y 1 1 1 z * 1 1 z 1 1 1}}
    83     83   }
           84  +
           85  +do_faultsim_test 3.0 -faults oom* -prep {
           86  +  faultsim_delete_and_reopen
           87  +  db eval { CREATE TABLE 'xx yy'(a, b); }
           88  +} -body {
           89  +  execsql {
           90  +    CREATE VIRTUAL TABLE tt USING fts4(content="xx yy");
           91  +  }
           92  +} -test {
           93  +  faultsim_test_result {0 {}}
           94  +}
           95  +
           96  +do_faultsim_test 3.1 -faults oom* -prep {
           97  +  faultsim_delete_and_reopen
           98  +  db func zip zip
           99  +  db func unzip unzip
          100  +} -body {
          101  +  execsql {
          102  +    CREATE VIRTUAL TABLE tt USING fts4(compress=zip, uncompress=unzip);
          103  +  }
          104  +} -test {
          105  +  faultsim_test_result {0 {}}
          106  +}
          107  +
          108  +do_test 4.0 {
          109  +  faultsim_delete_and_reopen
          110  +  execsql {
          111  +    CREATE VIRTUAL TABLE ft USING fts4(a, b);
          112  +    INSERT INTO ft VALUES('U U T C O', 'F N D E S');
          113  +    INSERT INTO ft VALUES('P H X G B', 'I D M R U');
          114  +    INSERT INTO ft VALUES('P P X D M', 'Y V N T C');
          115  +    INSERT INTO ft VALUES('Z L Q O W', 'D F U N Q');
          116  +    INSERT INTO ft VALUES('A J D U P', 'C H M Q E');
          117  +    INSERT INTO ft VALUES('P S A O H', 'S Z C W D');
          118  +    INSERT INTO ft VALUES('T B N L W', 'C A K T I');
          119  +    INSERT INTO ft VALUES('K E Z L O', 'L L Y C E');
          120  +    INSERT INTO ft VALUES('C R E S V', 'Q V F W P');
          121  +    INSERT INTO ft VALUES('S K H G W', 'R W Q F G');
          122  +  }
          123  +  faultsim_save_and_close
          124  +} {}
          125  +do_faultsim_test 4.1 -prep {
          126  +  faultsim_restore_and_reopen
          127  +  db eval {SELECT * FROM sqlite_master}
          128  +} -body {
          129  +  execsql { INSERT INTO ft(ft) VALUES('rebuild') }
          130  +} -test {
          131  +  faultsim_test_result {0 {}}
          132  +}
    84    133   
    85    134   finish_test

Added test/fts3first.test.

            1  +# 2011 October 18
            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  +set testdir [file dirname $argv0]
           13  +source $testdir/tester.tcl
           14  +source $testdir/malloc_common.tcl
           15  +
           16  +ifcapable !fts3 {
           17  +  finish_test
           18  +  return
           19  +}
           20  +
           21  +set testprefix fts3first
           22  +
           23  +proc lreverse {L} {
           24  +  set res [list]
           25  +  for {set ii [expr [llength $L]-1]} {$ii>=0} {incr ii -1} {
           26  +    lappend res [lindex $L $ii]
           27  +  }
           28  +  set res
           29  +}
           30  +
           31  +proc mit {blob} {
           32  +  set scan(littleEndian) i*
           33  +  set scan(bigEndian) I*
           34  +  binary scan $blob $scan($::tcl_platform(byteOrder)) r
           35  +  return $r
           36  +}
           37  +db func mit mit
           38  +
           39  +do_execsql_test 1.0 {
           40  +  CREATE VIRTUAL TABLE x1 USING FTS4(a, b, c);
           41  +  INSERT INTO x1(docid,a,b,c) VALUES(0, 'K H D S T', 'V M N Y K', 'S Z N Q S');
           42  +  INSERT INTO x1(docid,a,b,c) VALUES(1, 'K N J L W', 'S Z W J Q', 'D U W S E');
           43  +  INSERT INTO x1(docid,a,b,c) VALUES(2, 'B P M O I', 'R P H W S', 'R J L L E');
           44  +  INSERT INTO x1(docid,a,b,c) VALUES(3, 'U R Q M L', 'M J K A V', 'Q W J T J');
           45  +  INSERT INTO x1(docid,a,b,c) VALUES(4, 'N J C Y N', 'R U D X V', 'B O U A Q');
           46  +  INSERT INTO x1(docid,a,b,c) VALUES(5, 'Q L X L U', 'I F N X S', 'U Q A N Y');
           47  +  INSERT INTO x1(docid,a,b,c) VALUES(6, 'M R G U T', 'U V I Q P', 'X Y D L S');
           48  +  INSERT INTO x1(docid,a,b,c) VALUES(7, 'D Y P O I', 'X J P K R', 'V O T H V');
           49  +  INSERT INTO x1(docid,a,b,c) VALUES(8, 'R Y D L R', 'U U E S J', 'N W L M R');
           50  +  INSERT INTO x1(docid,a,b,c) VALUES(9, 'Z P F N P', 'W A X D U', 'V A E Q A');
           51  +  INSERT INTO x1(docid,a,b,c) VALUES(10, 'Q I A Q M', 'N D K H C', 'A H T Q Z');
           52  +  INSERT INTO x1(docid,a,b,c) VALUES(11, 'T E R Q B', 'C I B C B', 'F Z U W R');
           53  +  INSERT INTO x1(docid,a,b,c) VALUES(12, 'E S V U W', 'T P F W H', 'A M D J Q');
           54  +  INSERT INTO x1(docid,a,b,c) VALUES(13, 'X S B X Y', 'U D N D P', 'X Z Y G F');
           55  +  INSERT INTO x1(docid,a,b,c) VALUES(14, 'K H A B L', 'S R C C Z', 'D W E H J');
           56  +  INSERT INTO x1(docid,a,b,c) VALUES(15, 'C E U C C', 'W F M N M', 'T Z U X T');
           57  +  INSERT INTO x1(docid,a,b,c) VALUES(16, 'Q G C G H', 'H N N B H', 'B Q I H Y');
           58  +  INSERT INTO x1(docid,a,b,c) VALUES(17, 'Q T S K B', 'W B D Y N', 'V J P E C');
           59  +  INSERT INTO x1(docid,a,b,c) VALUES(18, 'A J M O Q', 'L G Y Y A', 'G N M R N');
           60  +  INSERT INTO x1(docid,a,b,c) VALUES(19, 'T R Y P Y', 'N V Y B X', 'L Z T N T');
           61  +
           62  +  CREATE VIRTUAL TABLE x2 USING FTS4(a, b, c, order=DESC);
           63  +  INSERT INTO x2(docid, a, b, c) SELECT docid, a, b, c FROM x1;
           64  +}
           65  +
           66  +
           67  +# Test queries.
           68  +#
           69  +foreach x {1 2} {
           70  +  foreach {tn match res} {
           71  +    1  "^K"              {0 1 14}
           72  +    2  "^S"              {0 1 14}
           73  +    3  "^W"              {9 15 17}
           74  +    4  "^J"              {}
           75  +    5  "^E"              {12}
           76  +    6  "V ^-E"           {0 3 4 6 7 9 17 19}
           77  +    7  "V -^E"           {0 3 4 6 7 9 17 19}
           78  +    8  "^-E V"           {0 3 4 6 7 9 17 19}
           79  +    9  "-^E V"           {0 3 4 6 7 9 17 19}
           80  +    10 "V"               {0 3 4 6 7 9 12 17 19}
           81  +
           82  +    11 {"^K H"}          {0 14}
           83  +    12 {"K H"}           {0 10 14}
           84  +    13 {"K ^H"}          {}
           85  +  } {
           86  +    set rev [lreverse $res]
           87  +    do_execsql_test 1.$x.$tn.1 {SELECT docid FROM x1 WHERE x1 MATCH $match} $res
           88  +    do_execsql_test 1.$x.$tn.2 {SELECT docid FROM x2 WHERE x2 MATCH $match} $rev
           89  +  }
           90  +
           91  +  do_execsql_test 1.$x.[expr $tn+1] { 
           92  +    INSERT INTO x1(x1) VALUES('optimize');
           93  +    INSERT INTO x2(x2) VALUES('optimize');
           94  +  } {}
           95  +}
           96  +
           97  +# Test the snippet() function.
           98  +#
           99  +foreach {tn match res} {
          100  +  1  {^K}    {{[K] H D S T} {[K] N J L W} {[K] H A B L}}
          101  +  2  {^X}    {{[X] Y D L S} {[X] J P K R} {[X] S B X Y}}
          102  +  3  {^X Y}  {{[X] [Y] D L S} {D [Y] P O I...[X] J P K R} {[X] S B X [Y]}}
          103  +} {
          104  +  set rev [lreverse $res]
          105  +
          106  +  do_execsql_test 1.3.$tn.1 {
          107  +    SELECT snippet(x1, '[', ']', '...') FROM x1 WHERE x1 MATCH $match
          108  +  } $res
          109  +
          110  +  do_execsql_test 1.3.$tn.2 {
          111  +    SELECT snippet(x2, '[', ']', '...') FROM x2 WHERE x2 MATCH $match
          112  +  } $rev
          113  +}
          114  +
          115  +# Test matchinfo().
          116  +#
          117  +foreach {tn match res} {
          118  +  1  {^K}    {
          119  +                {1 3 3 0 0 0 0 0 0}
          120  +                {1 3 3 0 0 0 0 0 0}
          121  +                {1 3 3 0 0 0 0 0 0}
          122  +             }
          123  +  2  {^X}    {
          124  +                {0 1 1 0 1 1 1 2 2}
          125  +                {0 1 1 1 1 1 0 2 2}
          126  +                {1 1 1 0 1 1 1 2 2}
          127  +             }
          128  +  3  {^X Y}  {
          129  +                {0 1 1 0 1 1 1 2 2 0 6 5 0 5 4 1 4 4} 
          130  +                {0 1 1 1 1 1 0 2 2 1 6 5 0 5 4 0 4 4} 
          131  +                {1 1 1 0 1 1 1 2 2 1 6 5 0 5 4 1 4 4}
          132  +             }
          133  +} {
          134  +  set rev [lreverse $res]
          135  +
          136  +  do_execsql_test 1.3.$tn.1 {
          137  +    SELECT mit(matchinfo(x1, 'x')) FROM x1 WHERE x1 MATCH $match
          138  +  } $res
          139  +  do_execsql_test 1.3.$tn.2 {
          140  +    SELECT mit(matchinfo(x2, 'x')) FROM x2 WHERE x2 MATCH $match
          141  +  } $rev
          142  +}
          143  +
          144  +# Test that ^ is ignored for FTS3 tables.
          145  +#
          146  +do_execsql_test 2.1 {
          147  +  CREATE VIRTUAL TABLE x3 USING fts3;
          148  +  INSERT INTO x3 VALUES('A B C');
          149  +  INSERT INTO x3 VALUES('B A C');
          150  +
          151  +  CREATE VIRTUAL TABLE x4 USING fts4;
          152  +  INSERT INTO x4 VALUES('A B C');
          153  +  INSERT INTO x4 VALUES('B A C');
          154  +}
          155  +
          156  +do_execsql_test 2.2.1 {
          157  +  SELECT * FROM x3 WHERE x3 MATCH '^A';
          158  +} {{A B C} {B A C}}
          159  +do_execsql_test 2.2.2 {
          160  +  SELECT * FROM x4 WHERE x4 MATCH '^A';
          161  +} {{A B C}}
          162  +
          163  +finish_test

Changes to test/fts3malloc.test.

   290    290   
   291    291   do_write_test fts3_malloc-5.1 ft_content {
   292    292     INSERT INTO ft VALUES('short alongertoken reallyquitealotlongerimeanit andthistokenisjustsolongthatonemightbeforgivenforimaginingthatitwasmerelyacontrivedexampleandnotarealtoken', 'cynics!')
   293    293   }
   294    294   do_test fts3_malloc-5.2 {
   295    295     execsql { CREATE VIRTUAL TABLE ft8 USING fts3(x, tokenize porter) }
   296    296   } {}
          297  +
   297    298   do_write_test fts3_malloc-5.3 ft_content {
   298    299     INSERT INTO ft8 VALUES('short alongertoken reallyquitealotlongerimeanit andthistokenisjustsolongthatonemightbeforgivenforimaginingthatitwasmerelyacontrivedexampleandnotarealtoken')
   299    300   }
   300    301   
   301    302   
   302    303   finish_test
   303    304   

Changes to test/fts3matchinfo.test.

    15     15   set testdir [file dirname $argv0]
    16     16   source $testdir/tester.tcl
    17     17   
    18     18   # If SQLITE_ENABLE_FTS3 is not defined, omit this file.
    19     19   ifcapable !fts3 { finish_test ; return }
    20     20   
    21     21   set testprefix fts3matchinfo
           22  +set sqlite_fts3_enable_parentheses 0
    22     23   
    23     24   proc mit {blob} {
    24     25     set scan(littleEndian) i*
    25     26     set scan(bigEndian) I*
    26     27     binary scan $blob $scan($::tcl_platform(byteOrder)) r
    27     28     return $r
    28     29   }
................................................................................
    53     54   #
    54     55   do_catchsql_test 2.0 {
    55     56     CREATE VIRTUAL TABLE x1 USING fts4(matchinfo=fs3);
    56     57   } {1 {unrecognized matchinfo: fs3}}
    57     58   do_catchsql_test 2.1 {
    58     59     CREATE VIRTUAL TABLE x2 USING fts4(mtchinfo=fts3);
    59     60   } {1 {unrecognized parameter: mtchinfo=fts3}}
           61  +do_catchsql_test 2.2 {
           62  +  CREATE VIRTUAL TABLE x2 USING fts4(matchinfo=fts5);
           63  +} {1 {unrecognized matchinfo: fts5}}
    60     64   
    61     65   # Check that with fts3, the "=" character is permitted in column definitions.
    62     66   #
    63     67   do_execsql_test 3.1 {
    64     68     CREATE VIRTUAL TABLE t3 USING fts3(mtchinfo=fts3);
    65     69     INSERT INTO t3(mtchinfo) VALUES('Beside the lake, beneath the trees');
    66     70     SELECT mtchinfo FROM t3;
................................................................................
   220    224     sxsxs -
   221    225   }
   222    226   
   223    227   do_matchinfo_test 4.1.3 t4 {t4 MATCH 'a b'}     { s {{2 0} {0 2}} }
   224    228   do_matchinfo_test 4.1.4 t4 {t4 MATCH '"a b" c'} { s {{2 0} {0 2}} }
   225    229   do_matchinfo_test 4.1.5 t4 {t4 MATCH 'a "b c"'} { s {{2 0} {0 2}} }
   226    230   do_matchinfo_test 4.1.6 t4 {t4 MATCH 'd d'}     { s {{1 0} {0 1}} }
          231  +do_matchinfo_test 4.1.7 t4 {t4 MATCH 'f OR abcd'} {
          232  +  x { 
          233  +    {0 1 1  1 1 1  0 0 0  0 0 0} 
          234  +    {1 1 1  0 1 1  0 0 0  0 0 0}
          235  +  }
          236  +}
          237  +do_matchinfo_test 4.1.8 t4 {t4 MATCH 'f -abcd'} {
          238  +  x { 
          239  +    {0 1 1  1 1 1}
          240  +    {1 1 1  0 1 1}
          241  +  }
          242  +}
   227    243   
   228    244   do_execsql_test 4.2.0 {
   229    245     CREATE VIRTUAL TABLE t5 USING fts4;
   230    246     INSERT INTO t5 VALUES('a a a a a');
   231    247     INSERT INTO t5 VALUES('a b a b a');
   232    248     INSERT INTO t5 VALUES('c b c b c');
   233    249     INSERT INTO t5 VALUES('x x x x x');

Changes to test/fts3prefix.test.

   195    195   } {{four five six} {seven eight nine}}
   196    196   do_execsql_test 4.5 {
   197    197     SELECT * FROM t3 WHERE t3 MATCH 'sev*'
   198    198   } {{seven eight nine}}
   199    199   do_execsql_test 4.6 {
   200    200     SELECT * FROM t3 WHERE t3 MATCH 'one*'
   201    201   } {{one two three}}
          202  +
          203  +#-------------------------------------------------------------------------
          204  +# Syntax tests.
          205  +#
          206  +do_catchsql_test 5.1 {
          207  +  CREATE VIRTUAL TABLE t4 USING fts4(prefix="abc");
          208  +} {1 {error parsing prefix parameter: abc}}
          209  +do_catchsql_test 5.2 {
          210  +  CREATE VIRTUAL TABLE t4 USING fts4(prefix="");
          211  +} {0 {}}
   202    212   
   203    213   finish_test

Changes to test/fts3sort.test.

   134    134   #
   135    135   foreach {tn param res} {
   136    136     1 "order=asc"             {0 {}}
   137    137     2 "order=desc"            {0 {}}
   138    138     3 "order=dec"             {1 {unrecognized order: dec}}
   139    139     4 "order=xxx, order=asc"  {1 {unrecognized order: xxx}}
   140    140     5 "order=desc, order=asc" {0 {}}
          141  +  6 "order=xxxx, order=asc" {1 {unrecognized order: xxxx}}
          142  +  7 "order=desk"            {1 {unrecognized order: desk}}
   141    143   } {
   142    144     execsql { DROP TABLE IF EXISTS t1 }
   143    145     do_catchsql_test 2.1.$tn "
   144    146       CREATE VIRTUAL TABLE t1 USING fts4(a, b, $param)
   145    147     " $res
   146    148   }
   147    149   
................................................................................
   153    155       INSERT INTO t2 VALUES('cc aa');
   154    156       SELECT docid FROM t2 WHERE t2 MATCH 'aa';
   155    157     END;
   156    158   } {3 1}
   157    159   do_execsql_test 2.3 {
   158    160     SELECT docid FROM t2 WHERE t2 MATCH 'aa';
   159    161   } {3 1}
          162  +do_execsql_test 2.4 {
          163  +  SELECT docid FROM t2 WHERE t2 MATCH 'aa' ORDER BY content;
          164  +} {1 3}
   160    165   
   161    166   #-------------------------------------------------------------------------
   162    167   # Test that ticket [56be976859] has been fixed.
   163    168   #
   164    169   do_execsql_test 3.1 {
   165    170     CREATE VIRTUAL TABLE t3 USING fts4(x, order=DESC);
   166    171     INSERT INTO t3(docid, x) VALUES(113382409004785664, 'aa');

Added test/fts4content.test.

            1  +# 2011 October 03
            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  +# This file implements regression tests for SQLite library.  The
           12  +# focus of this script is testing the content=xxx FTS4 option.
           13  +#
           14  +
           15  +set testdir [file dirname $argv0]
           16  +source $testdir/tester.tcl
           17  +set ::testprefix fts4content
           18  +
           19  +# If SQLITE_ENABLE_FTS3 is defined, omit this file.
           20  +ifcapable !fts3 {
           21  +  finish_test
           22  +  return
           23  +}
           24  +
           25  +#-------------------------------------------------------------------------
           26  +# Test organization:
           27  +#   
           28  +#   1.* - Warm-body tests.
           29  +#
           30  +#   2.* - Querying a content=xxx FTS table.
           31  +#
           32  +#   3.* - Writing to a content=xxx FTS table.
           33  +#
           34  +#   4.* - The "INSERT INTO fts(fts) VALUES('rebuild')" command.
           35  +#
           36  +#   5.* - Check that CREATE TABLE, DROP TABLE and ALTER TABLE correctly
           37  +#         ignore any %_content table when used with the content=xxx option.
           38  +#
           39  +#   6.* - Test the effects of messing with the schema of table xxx after
           40  +#         creating a content=xxx FTS index.
           41  +#
           42  +
           43  +do_execsql_test 1.1.1 {
           44  +  CREATE TABLE t1(a, b, c);
           45  +  INSERT INTO t1 VALUES('w x', 'x y', 'y z');
           46  +  CREATE VIRTUAL TABLE ft1 USING fts4(content=t1);
           47  +}
           48  +
           49  +do_execsql_test 1.1.2 {
           50  +  PRAGMA table_info(ft1);
           51  +} {
           52  +  0 a {} 0 {} 0 
           53  +  1 b {} 0 {} 0 
           54  +  2 c {} 0 {} 0
           55  +}
           56  +
           57  +do_execsql_test 1.1.3 { SELECT *, rowid FROM ft1 } {{w x} {x y} {y z} 1}
           58  +do_execsql_test 1.1.4 { SELECT a, c FROM ft1 WHERE rowid=1 } {{w x} {y z}}
           59  +
           60  +do_execsql_test 1.1.5 { INSERT INTO ft1(ft1) VALUES('rebuild') } {}
           61  +do_execsql_test 1.1.6 { SELECT rowid FROM ft1 WHERE ft1 MATCH 'x' } {1}
           62  +do_execsql_test 1.1.7 { SELECT rowid FROM ft1 WHERE ft1 MATCH 'a' } {}
           63  +
           64  +do_execsql_test 1.2.1 {
           65  +  DROP TABLE ft1;
           66  +  CREATE VIRTUAL TABLE ft1 USING fts4(content=t1, b);
           67  +  PRAGMA table_info(ft1);
           68  +} {
           69  +  0 b {} 0 {} 0 
           70  +}
           71  +do_execsql_test 1.2.2 { 
           72  +  SELECT *, rowid FROM ft1 
           73  +} {{x y} 1}
           74  +
           75  +#-------------------------------------------------------------------------
           76  +# The following block of tests - 2.* - test that a content=xxx FTS table
           77  +# can be queried. Also tested are cases where rows identified in the FTS
           78  +# are missing from the content table, and cases where the index is 
           79  +# inconsistent with the content table.
           80  +# 
           81  +do_execsql_test 2.0 {
           82  +  CREATE TABLE t2(x);
           83  +  INSERT INTO t2 VALUES('O S W W F U C R Q I C N P Z Y Y E Y Y E');  -- 1
           84  +  INSERT INTO t2 VALUES('Y X U V L B E H Y J C Y A I A P V F V K');  -- 2
           85  +  INSERT INTO t2 VALUES('P W I N J H I I N I F B K D U Q B Z S F');  -- 3
           86  +  INSERT INTO t2 VALUES('N R O R H J R H G M D I U U B O M P A U');  -- 4
           87  +  INSERT INTO t2 VALUES('Y O V O G T P N G T N F I V B U M J M G');  -- 5
           88  +  INSERT INTO t2 VALUES('J O B N K N E C H Z R K J O U G M K L S');  -- 6
           89  +  INSERT INTO t2 VALUES('S Z S R I Q U A P W R X H K C Z U L S P');  -- 7
           90  +  INSERT INTO t2 VALUES('J C H N R C K R V N M O F Z M Z A I H W');  -- 8
           91  +  INSERT INTO t2 VALUES('O Y G I S J U U W O D Z F J K N R P R L');  -- 9
           92  +  INSERT INTO t2 VALUES('B G L K U R U P V X Z I H V R W C Q A S');  -- 10
           93  +  INSERT INTO t2 VALUES('T F T J F F Y V F W N X K Q A Y L X W G');  -- 11
           94  +  INSERT INTO t2 VALUES('C J U H B Q X L C M M Y E G V F W V Z C');  -- 12
           95  +  INSERT INTO t2 VALUES('B W L T F S G X D P H N G M R I O A X I');  -- 13
           96  +  INSERT INTO t2 VALUES('N G Y O K Q K Z N M H U J E D H U W R K');  -- 14
           97  +  INSERT INTO t2 VALUES('U D T R U Y F J D S J X E H Q G V A S Z');  -- 15
           98  +  INSERT INTO t2 VALUES('M I W P J S H R J D Q I C G P C T P H R');  -- 16
           99  +  INSERT INTO t2 VALUES('J M N I S L X Q C A B F C B Y D H V R J');  -- 17
          100  +  INSERT INTO t2 VALUES('F V Z W J Q L P X Y E W B U Q N H X K T');  -- 18
          101  +  INSERT INTO t2 VALUES('R F S R Y O F Q E I E G H C B H R X Y N');  -- 19
          102  +  INSERT INTO t2 VALUES('U Q Q Q T E P D M F X P J G H X C Q D L');  -- 20
          103  +}
          104  +
          105  +do_execsql_test 2.1 {
          106  +  CREATE VIRTUAL TABLE ft2 USING fts4(content=t2);
          107  +  INSERT INTO ft2(ft2) VALUES('rebuild');
          108  +
          109  +  -- Modify the backing table a bit: Row 17 is missing and the contents 
          110  +  -- of row 20 do not match the FTS index contents. 
          111  +  DELETE FROM t2 WHERE rowid = 17;
          112  +  UPDATE t2 SET x = 'a b c d e f g h i j' WHERE rowid = 20;
          113  +}
          114  +
          115  +foreach {tn match rowidlist} {
          116  +  1   {S}        {1 3 6 7 9 10 13 15 16 17 19}
          117  +  2   {"S R"}    {7 19}
          118  +  3   {"N K N"}  {6}
          119  +  4   {"Q Q"}    {20}
          120  +  5   {"B Y D"}  {17}
          121  +} {
          122  +  do_execsql_test 2.2.1.$tn {
          123  +    SELECT rowid FROM ft2 WHERE ft2 MATCH $match
          124  +  } $rowidlist
          125  +
          126  +  do_execsql_test 2.2.2.$tn {
          127  +    SELECT docid FROM ft2 WHERE ft2 MATCH $match
          128  +  } $rowidlist
          129  +}
          130  +
          131  +foreach {tn match result} {
          132  +  1   {"N K N"}  {{J O B N K N E C H Z R K J O U G M K L S}}
          133  +  2   {"Q Q"}    {{a b c d e f g h i j}}
          134  +  3   {"B Y D"}  {{}}
          135  +} {
          136  +  do_execsql_test 2.3.$tn {
          137  +    SELECT * FROM ft2 WHERE ft2 MATCH $match
          138  +  } $result
          139  +}
          140  +
          141  +foreach {tn match result} {
          142  +  1   {"N K N"}  {{..O B [N] [K] [N] E..}}
          143  +  2   {"B Y D"}  {{}}
          144  +  3   {"Q Q"}    {{a [b] [c] [d] e f..}}
          145  +} {
          146  +  do_execsql_test 2.4.$tn {
          147  +    SELECT snippet(ft2, '[', ']', '..', -1, 6) FROM ft2 WHERE ft2 MATCH $match
          148  +  } $result
          149  +}
          150  +
          151  +foreach {tn match result} {
          152  +  1   {"N K N"}  {{0 0 6 1 0 1 8 1 0 2 10 1}}
          153  +  2   {"B Y D"}  {{}}
          154  +  3   {"Q Q"}    {{0 0 2 1 0 0 4 1 0 1 4 1 0 1 6 1}}
          155  +  4   {"Q D L"}  {{}}
          156  +} {
          157  +  do_execsql_test 2.5.$tn {
          158  +    SELECT offsets(ft2) FROM ft2 WHERE ft2 MATCH $match
          159  +  } $result
          160  +}
          161  +
          162  +#-------------------------------------------------------------------------
          163  +# The following block of tests - 3.* - test that the FTS index can be
          164  +# modified by writing to the table. But that this has no effect on the 
          165  +# content table.
          166  +# 
          167  +
          168  +do_execsql_test 3.1 {
          169  +  CREATE TABLE t3(x, y);
          170  +  CREATE VIRTUAL TABLE ft3 USING fts4(content=t3);
          171  +}
          172  +
          173  +do_catchsql_test 3.1.1 {
          174  +  INSERT INTO ft3 VALUES('a b c', 'd e f');
          175  +} {1 {constraint failed}}
          176  +do_execsql_test 3.1.2 {
          177  +  INSERT INTO ft3(docid, x, y) VALUES(21, 'a b c', 'd e f');
          178  +  SELECT rowid FROM ft3 WHERE ft3 MATCH '"a b c"';
          179  +} {21}
          180  +do_execsql_test 3.1.3 { SELECT * FROM t3 } {}
          181  +
          182  +# This DELETE does not work, since there is no row in [t3] to base the
          183  +# DELETE on. So the SELECT on [ft3] still returns rowid 21.
          184  +do_execsql_test 3.1.4 { 
          185  +  DELETE FROM ft3;
          186  +  SELECT rowid FROM ft3 WHERE ft3 MATCH '"a b c"';
          187  +} {21}
          188  +
          189  +# If the row is added to [t3] before the DELETE on [ft3], it works.
          190  +do_execsql_test 3.1.5 {
          191  +  INSERT INTO t3(rowid, x, y) VALUES(21, 'a b c', 'd e f');
          192  +  DELETE FROM ft3;
          193  +  SELECT rowid FROM ft3 WHERE ft3 MATCH '"a b c"';
          194  +} {}
          195  +do_execsql_test 3.1.6 { SELECT rowid FROM t3 } {21}
          196  +
          197  +do_execsql_test 3.2.1 {
          198  +  INSERT INTO ft3(rowid, x, y) VALUES(0, 'R T M S M', 'A F O K H');
          199  +  INSERT INTO ft3(rowid, x, y) VALUES(1, 'C Z J O X', 'U S Q D K');
          200  +  INSERT INTO ft3(rowid, x, y) VALUES(2, 'N G H P O', 'N O P O C');
          201  +  INSERT INTO ft3(rowid, x, y) VALUES(3, 'V H S D R', 'K N G E C');
          202  +  INSERT INTO ft3(rowid, x, y) VALUES(4, 'J T R V U', 'U X S L C');
          203  +  INSERT INTO ft3(rowid, x, y) VALUES(5, 'N A Y N G', 'X D G P Y');
          204  +  INSERT INTO ft3(rowid, x, y) VALUES(6, 'I Q I S P', 'D R O Q B');
          205  +  INSERT INTO ft3(rowid, x, y) VALUES(7, 'T K T Z J', 'B W D G O');
          206  +  INSERT INTO ft3(rowid, x, y) VALUES(8, 'Y K F X T', 'D F G V G');
          207  +  INSERT INTO ft3(rowid, x, y) VALUES(9, 'E L E T L', 'P W N F Z');
          208  +  INSERT INTO ft3(rowid, x, y) VALUES(10, 'O G J G X', 'G J F E P');
          209  +  INSERT INTO ft3(rowid, x, y) VALUES(11, 'O L N N Z', 'K E Z F D');
          210  +  INSERT INTO ft3(rowid, x, y) VALUES(12, 'R Z M R J', 'X G I M Z');
          211  +  INSERT INTO ft3(rowid, x, y) VALUES(13, 'L X N N X', 'R R N S T');
          212  +  INSERT INTO ft3(rowid, x, y) VALUES(14, 'F L B J H', 'K W F L C');
          213  +  INSERT INTO ft3(rowid, x, y) VALUES(15, 'P E B M V', 'E A A B U');
          214  +  INSERT INTO ft3(rowid, x, y) VALUES(16, 'V E C F P', 'L U T V K');
          215  +  INSERT INTO ft3(rowid, x, y) VALUES(17, 'T N O Z N', 'T P Q X N');
          216  +  INSERT INTO ft3(rowid, x, y) VALUES(18, 'V W U W R', 'H O A A V');
          217  +  INSERT INTO ft3(rowid, x, y) VALUES(19, 'A H N L F', 'I G H B O');
          218  +}
          219  +
          220  +foreach {tn match rowidlist} {
          221  +  1   "N A"    {5 19}
          222  +  2   "x:O"    {1 2 10 11 17}
          223  +  3   "y:O"    {0 2 6 7 18 19}
          224  +} {
          225  +  set res [list]
          226  +  foreach rowid $rowidlist { lappend res $rowid {} {} }
          227  +
          228  +  do_execsql_test 3.2.2.$tn {
          229  +    SELECT rowid, * FROM ft3 WHERE ft3 MATCH $match
          230  +  } $res
          231  +  do_execsql_test 3.2.3.$tn {
          232  +    SELECT docid, * FROM ft3 WHERE ft3 MATCH $match
          233  +  } $res
          234  +}
          235  +
          236  +do_execsql_test 3.3.1 {
          237  +  INSERT INTO t3(rowid, x, y) VALUES(0, 'R T M S M', 'A F O K H');
          238  +  INSERT INTO t3(rowid, x, y) VALUES(1, 'C Z J O X', 'U S Q D K');
          239  +  INSERT INTO t3(rowid, x, y) VALUES(2, 'N G H P O', 'N O P O C');
          240  +  INSERT INTO t3(rowid, x, y) VALUES(3, 'V H S D R', 'K N G E C');
          241  +  INSERT INTO t3(rowid, x, y) VALUES(4, 'J T R V U', 'U X S L C');
          242  +  INSERT INTO t3(rowid, x, y) VALUES(5, 'N A Y N G', 'X D G P Y');
          243  +  UPDATE ft3 SET x = y, y = x;
          244  +  DELETE FROM t3;
          245  +}
          246  +
          247  +foreach {tn match rowidlist} {
          248  +  1   "N A"    {5 19}
          249  +  2   "x:O"    {0 2 10 11 17}
          250  +  3   "y:O"    {1 2 6 7 18 19}
          251  +} {
          252  +  set res [list]
          253  +  foreach rowid $rowidlist { lappend res $rowid {} {} }
          254  +
          255  +  do_execsql_test 3.3.2.$tn {
          256  +    SELECT rowid, * FROM ft3 WHERE ft3 MATCH $match
          257  +  } $res
          258  +  do_execsql_test 3.3.3.$tn {
          259  +    SELECT docid, * FROM ft3 WHERE ft3 MATCH $match
          260  +  } $res
          261  +}
          262  +
          263  +do_execsql_test 3.3.1 {
          264  +  INSERT INTO t3(rowid, x, y) VALUES(15, 'P E B M V', 'E A A B U');
          265  +  INSERT INTO t3(rowid, x, y) VALUES(16, 'V E C F P', 'L U T V K');
          266  +  INSERT INTO t3(rowid, x, y) VALUES(17, 'T N O Z N', 'T P Q X N');
          267  +  INSERT INTO t3(rowid, x, y) VALUES(18, 'V W U W R', 'H O A A V');
          268  +  INSERT INTO t3(rowid, x, y) VALUES(19, 'A H N L F', 'I G H B O');
          269  +  DELETE FROM ft3;
          270  +}
          271  +
          272  +foreach {tn match rowidlist} {
          273  +  1   "N A"    {5}
          274  +  2   "x:O"    {0 2 10 11}
          275  +  3   "y:O"    {1 2 6 7}
          276  +} {
          277  +  set res [list]
          278  +  foreach rowid $rowidlist { lappend res $rowid {} {} }
          279  +
          280  +  do_execsql_test 3.3.2.$tn {
          281  +    SELECT rowid, * FROM ft3 WHERE ft3 MATCH $match
          282  +  } $res
          283  +  do_execsql_test 3.3.3.$tn {
          284  +    SELECT docid, * FROM ft3 WHERE ft3 MATCH $match
          285  +  } $res
          286  +}
          287  +
          288  +
          289  +#-------------------------------------------------------------------------
          290  +# Test cases 4.* test the 'rebuild' command. On content=xxx and regular
          291  +# FTS tables.
          292  +# 
          293  +do_execsql_test 4.0 {
          294  +  CREATE TABLE t4(x);
          295  +  CREATE VIRTUAL TABLE ft4 USING fts4(content=t4);
          296  +  CREATE VIRTUAL TABLE ft4x USING fts4(x);
          297  +}
          298  +
          299  +do_execsql_test 4.1.1 {
          300  +  INSERT INTO ft4x(ft4x) VALUES('rebuild');
          301  +  INSERT INTO ft4(ft4) VALUES('rebuild');
          302  +} {}
          303  +do_execsql_test 4.1.2 {
          304  +  SELECT id, quote(value) FROM ft4_stat
          305  +} {0 X'000000'}
          306  +do_execsql_test 4.1.3 {
          307  +  SELECT id, quote(value) FROM ft4x_stat
          308  +} {0 X'000000'}
          309  +
          310  +do_execsql_test 4.2.1 {
          311  +  INSERT INTO ft4x VALUES('M G M F T');
          312  +  INSERT INTO ft4x VALUES('Z Q C A U');
          313  +  INSERT INTO ft4x VALUES('N L L V');
          314  +  INSERT INTO ft4x VALUES('T F D X D');
          315  +  INSERT INTO ft4x VALUES('Z H I S D');
          316  +
          317  +  SELECT id, quote(value) FROM ft4x_stat
          318  +} {0 X'05182B'}
          319  +
          320  +do_execsql_test 4.2.2 {
          321  +  INSERT INTO ft4(rowid, x) SELECT rowid, * FROM ft4x;
          322  +  SELECT id, quote(value) FROM ft4_stat
          323  +} {0 X'05182B'}
          324  +
          325  +do_execsql_test 4.2.3 {
          326  +  SELECT docid, quote(size) FROM ft4_docsize
          327  +} {1 X'05' 2 X'05' 3 X'04' 4 X'05' 5 X'05'}
          328  +
          329  +do_execsql_test 4.2.4 {
          330  +  INSERT INTO ft4x(ft4x) VALUES('rebuild');
          331  +  SELECT id, quote(value) FROM ft4x_stat;
          332  +  SELECT docid, quote(size) FROM ft4x_docsize
          333  +} {0 X'05182B' 1 X'05' 2 X'05' 3 X'04' 4 X'05' 5 X'05'}
          334  +
          335  +do_execsql_test 4.2.5 {
          336  +  INSERT INTO ft4(ft4) VALUES('rebuild');
          337  +  SELECT id, quote(value) FROM ft4_stat;
          338  +  SELECT docid, quote(size) FROM ft4_docsize
          339  +} {0 X'000000'}
          340  +
          341  +do_execsql_test 4.2.6 {
          342  +  INSERT INTO t4(rowid, x) SELECT rowid, x FROM ft4x;
          343  +  INSERT INTO ft4(ft4) VALUES('rebuild');
          344  +  SELECT id, quote(value) FROM ft4_stat;
          345  +  SELECT docid, quote(size) FROM ft4_docsize
          346  +} {0 X'05182B' 1 X'05' 2 X'05' 3 X'04' 4 X'05' 5 X'05'}
          347  +
          348  +
          349  +#-------------------------------------------------------------------------
          350  +# Test cases 5.* test that the following commands do not create/move or
          351  +# delete a %_content table when used with a content=xxx FTS table.
          352  +# 
          353  +do_execsql_test 5.1.1 {
          354  +  CREATE TABLE t5(a, b, c, d);
          355  +  CREATE VIRTUAL TABLE ft5 USING fts4(content=t5);
          356  +  SELECT name FROM sqlite_master WHERE name LIKE '%t5%';
          357  +} {
          358  +  t5 ft5 ft5_segments ft5_segdir 
          359  +  sqlite_autoindex_ft5_segdir_1 ft5_docsize ft5_stat
          360  +}
          361  +do_execsql_test 5.1.2 {
          362  +  ALTER TABLE ft5 RENAME TO ft6;
          363  +  SELECT name FROM sqlite_master WHERE name LIKE '%t5%';
          364  +} {
          365  +  t5
          366  +}
          367  +do_execsql_test 5.1.3 {
          368  +  SELECT name FROM sqlite_master WHERE name LIKE '%t6%';
          369  +} {
          370  +  ft6 ft6_segments ft6_segdir 
          371  +  sqlite_autoindex_ft6_segdir_1 ft6_docsize ft6_stat
          372  +}
          373  +do_execsql_test 5.1.4 {
          374  +  INSERT INTO t5 VALUES('a', 'b', 'c', 'd');
          375  +  INSERT INTO ft6(ft6) VALUES('rebuild');
          376  +  SELECT rowid FROM ft6 WHERE ft6 MATCH 'b';
          377  +} {1}
          378  +do_execsql_test 5.1.5 {
          379  +  DROP TABLE ft6;
          380  +  SELECT * FROM t5;
          381  +} {a b c d}
          382  +do_execsql_test 5.1.6 {
          383  +  SELECT name FROM sqlite_master WHERE name LIKE '%t6%';
          384  +} {
          385  +}
          386  +do_execsql_test 5.1.7 {
          387  +  CREATE VIRTUAL TABLE ft5 USING fts4(content=t5);
          388  +  CREATE TABLE t5_content(a, b);
          389  +  DROP TABLE ft5;
          390  +  SELECT name FROM sqlite_master WHERE name LIKE '%t5%';
          391  +} {
          392  +  t5 t5_content
          393  +}
          394  +
          395  +#-------------------------------------------------------------------------
          396  +# Test cases 6.* test 
          397  +# 
          398  +do_catchsql_test 6.1.1 {
          399  +  CREATE VIRTUAL TABLE ft7 USING fts4(content=t7);
          400  +} {1 {vtable constructor failed: ft7}}
          401  +
          402  +do_execsql_test 6.2.1 {
          403  +  CREATE TABLE t7(one, two);
          404  +  CREATE VIRTUAL TABLE ft7 USING fts4(content=t7);
          405  +  INSERT INTO t7 VALUES('A B', 'B A');
          406  +  INSERT INTO t7 VALUES('C D', 'A A');
          407  +  SELECT * FROM ft7;
          408  +} {
          409  +  {A B} {B A} {C D} {A A}
          410  +}
          411  +
          412  +do_catchsql_test 6.2.2 {
          413  +  DROP TABLE t7;
          414  +  SELECT * FROM ft7;
          415  +} {1 {SQL logic error or missing database}}
          416  +
          417  +db close
          418  +sqlite3 db test.db
          419  +do_execsql_test 6.2.3 {
          420  +  SELECT name FROM sqlite_master WHERE name LIKE '%t7%'
          421  +} {
          422  +  ft7 ft7_segments ft7_segdir sqlite_autoindex_ft7_segdir_1 
          423  +  ft7_docsize ft7_stat
          424  +}
          425  +do_catchsql_test 6.2.4 {
          426  +  SELECT * FROM ft7;
          427  +} {1 {vtable constructor failed: ft7}}
          428  +do_execsql_test 6.2.5 {
          429  +  CREATE TABLE t7(x, y);
          430  +  INSERT INTO t7 VALUES('A B', 'B A');
          431  +  INSERT INTO t7 VALUES('C D', 'A A');
          432  +  SELECT * FROM ft7;
          433  +} {
          434  +  {A B} {B A} {C D} {A A}
          435  +}
          436  +
          437  +do_execsql_test 6.2.6 {
          438  +  INSERT INTO ft7(ft7) VALUES('rebuild');
          439  +  SELECT rowid FROM ft7 WHERE ft7 MATCH '"A A"';
          440  +} {2}
          441  +
          442  +do_execsql_test 6.2.7 {
          443  +  DROP TABLE t7;
          444  +  CREATE TABLE t7(x);
          445  +}
          446  +do_catchsql_test 6.2.8 {
          447  +  SELECT * FROM ft7 WHERE ft7 MATCH '"A A"';
          448  +} {1 {SQL logic error or missing database}}
          449  +do_catchsql_test 6.2.9 {
          450  +  SELECT * FROM ft7 WHERE ft7 MATCH '"A A"';
          451  +} {1 {SQL logic error or missing database}}
          452  +
          453  +db close
          454  +sqlite3 db test.db
          455  +do_catchsql_test 6.2.10 {
          456  +  SELECT rowid FROM ft7 WHERE ft7 MATCH '"A A"';
          457  +} {0 2}
          458  +do_catchsql_test 6.2.11 {
          459  +  SELECT rowid, * FROM ft7 WHERE ft7 MATCH '"A A"';
          460  +} {0 {2 {}}}
          461  +
          462  +#-------------------------------------------------------------------------
          463  +# Test cases 7.*
          464  +# 
          465  +do_execsql_test 7.1.1 {
          466  +  CREATE VIRTUAL TABLE ft8 USING fts4(content=nosuchtable, x);
          467  +  INSERT INTO ft8(docid, x) VALUES(13, 'U O N X G');
          468  +  INSERT INTO ft8(docid, x) VALUES(14, 'C J J U B');
          469  +  INSERT INTO ft8(docid, x) VALUES(15, 'N J Y G X');
          470  +  INSERT INTO ft8(docid, x) VALUES(16, 'R Y D O R');
          471  +  INSERT INTO ft8(docid, x) VALUES(17, 'I Y T Q O');
          472  +}
          473  +
          474  +do_execsql_test 7.1.2 {
          475  +  SELECT docid FROM ft8 WHERE ft8 MATCH 'N';
          476  +} {13 15}
          477  +
          478  +finish_test

Changes to test/nan.test.

   315    315   
   316    316   do_realnum_test nan-4.20 {
   317    317     db eval {DELETE FROM t1}
   318    318     set big [string repeat 9 10000].0e-9000
   319    319     db eval "INSERT INTO t1 VALUES($big)"
   320    320     db eval {SELECT x, typeof(x) FROM t1}
   321    321   } {inf real}
          322  +
          323  +do_realnum_test nan-4.30 {
          324  +  db eval {
          325  +    DELETE FROM t1;
          326  +    INSERT INTO t1 VALUES('2.5e+9999');
          327  +    SELECT x, typeof(x) FROM t1;
          328  +  }
          329  +} {inf real}
          330  +do_realnum_test nan-4.31 {
          331  +  db eval {
          332  +    DELETE FROM t1;
          333  +    INSERT INTO t1 VALUES('2.5e+10000');
          334  +    SELECT x, typeof(x) FROM t1;
          335  +  }
          336  +} {inf real}
          337  +
          338  +do_realnum_test nan-4.32 {
          339  +  db eval {
          340  +    DELETE FROM t1;
          341  +    INSERT INTO t1 VALUES('2.5e-9999');
          342  +    SELECT x, typeof(x) FROM t1;
          343  +  }
          344  +} {0.0 real}
          345  +do_realnum_test nan-4.33 {
          346  +  db eval {
          347  +    DELETE FROM t1;
          348  +    INSERT INTO t1 VALUES('2.5e-10000');
          349  +    SELECT x, typeof(x) FROM t1;
          350  +  }
          351  +} {0.0 real}
          352  +do_realnum_test nan-4.34 {
          353  +  db eval {
          354  +    DELETE FROM t1;
          355  +    INSERT INTO t1 VALUES('2.5e2147483650');
          356  +    SELECT x, typeof(x) FROM t1;
          357  +  }
          358  +} {inf real}
          359  +do_realnum_test nan-4.35 {
          360  +  db eval {
          361  +    DELETE FROM t1;
          362  +    INSERT INTO t1 VALUES('2.5e-2147483650');
          363  +    SELECT x, typeof(x) FROM t1;
          364  +  }
          365  +} {0.0 real}
          366  +
          367  +  
   322    368   
   323    369   
   324    370   
   325    371   finish_test

Changes to test/permutations.test.

   179    179     fts3aa.test fts3ab.test fts3ac.test fts3ad.test fts3ae.test
   180    180     fts3af.test fts3ag.test fts3ah.test fts3ai.test fts3aj.test
   181    181     fts3ak.test fts3al.test fts3am.test fts3an.test fts3ao.test
   182    182     fts3atoken.test fts3b.test fts3c.test fts3cov.test fts3d.test
   183    183     fts3defer.test fts3defer2.test fts3e.test fts3expr.test fts3expr2.test 
   184    184     fts3near.test fts3query.test fts3shared.test fts3snippet.test 
   185    185     fts3sort.test
   186         -
   187    186     fts3fault.test fts3malloc.test fts3matchinfo.test
   188         -
   189    187     fts3aux1.test fts3comp1.test fts3auto.test
          188  +  fts4aa.test fts4content.test
          189  +  fts3conf.test fts3prefix.test fts3fault2.test fts3corrupt.test
          190  +  fts3corrupt2.test
          191  +  fts3first.test
   190    192   }
   191    193   
   192    194   
   193    195   lappend ::testsuitelist xxx
   194    196   #-------------------------------------------------------------------------
   195    197   # Define the coverage related test suites:
   196    198   #

Changes to test/pragma.test.

   325    325         hexio_write testerr.db 28 00000000
   326    326         execsql {REINDEX t2}
   327    327         execsql {PRAGMA integrity_check}
   328    328       } {ok}
   329    329       do_test pragma-3.8.1 {
   330    330         execsql {PRAGMA quick_check}
   331    331       } {ok}
          332  +    do_test pragma-3.8.2 {
          333  +      execsql {PRAGMA QUICK_CHECK}
          334  +    } {ok}
   332    335       do_test pragma-3.9 {
   333    336         execsql {
   334    337           ATTACH 'testerr.db' AS t2;
   335    338           PRAGMA integrity_check
   336    339         }
   337    340       } {{*** in database t2 ***
   338    341   Page 4 is never used
................................................................................
  1215   1218   
  1216   1219     do_test pragma-14.2 {
  1217   1220       execsql { 
  1218   1221         CREATE TABLE abc(a, b, c);
  1219   1222         PRAGMA page_count;
  1220   1223       }
  1221   1224     } {2}
         1225  +  do_test pragma-14.2uc {
         1226  +    execsql {pragma PAGE_COUNT}
         1227  +  } {2}
  1222   1228   
  1223   1229     do_test pragma-14.3 {
  1224   1230       execsql { 
  1225   1231         BEGIN;
  1226   1232         CREATE TABLE def(a, b, c);
  1227   1233         PRAGMA page_count;
  1228   1234       }
  1229   1235     } {3}
         1236  +  do_test pragma-14.3uc {
         1237  +    execsql {pragma PAGE_COUNT}
         1238  +  } {3}
  1230   1239   
  1231   1240     do_test pragma-14.4 {
  1232   1241       set page_size [db one {pragma page_size}]
  1233   1242       expr [file size test.db] / $page_size
  1234   1243     } {2}
  1235   1244   
  1236   1245     do_test pragma-14.5 {
................................................................................
  1252   1261       } db2
  1253   1262       db2 close
  1254   1263       execsql {
  1255   1264         ATTACH 'test2.db' AS aux;
  1256   1265         PRAGMA aux.page_count;
  1257   1266       } 
  1258   1267     } {5}
         1268  +  do_test pragma-14.6uc {
         1269  +    execsql {pragma AUX.PAGE_COUNT}
         1270  +  } {5}
  1259   1271   }
  1260   1272   
  1261   1273   # Test that the value set using the cache_size pragma is not reset when the
  1262   1274   # schema is reloaded.
  1263   1275   #
  1264   1276   ifcapable pager_pragmas {
  1265   1277     db close

Changes to test/printf.test.

  3543   3543     sqlite3_mprintf_str {%d A quoted string: '%.*q'} 1 6 {Hi Y'all}
  3544   3544   } {1 A quoted string: 'Hi Y''a'}
  3545   3545   
  3546   3546   
  3547   3547   do_test printf-5.1 {
  3548   3548     set x [sqlite3_mprintf_str {%d %d %100000s} 0 0 {Hello}]
  3549   3549     string length $x
  3550         -} {344}
         3550  +} {100004}
  3551   3551   do_test printf-5.2 {
  3552   3552     sqlite3_mprintf_str {%d %d (%-10.10s) %} -9 -10 {HelloHelloHello}
  3553   3553   } {-9 -10 (HelloHello) %}
  3554   3554   
  3555   3555   do_test printf-6.1 {
  3556   3556     sqlite3_mprintf_z_test , one two three four five six
  3557   3557   } {,one,two,three,four,five,six}

Added test/tkt-fa7bf5ec.test.

            1  +# 2011 October 13
            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  +# This file implements regression tests for SQLite library. Specifically,
           12  +# it tests that ticket [fa7bf5ec94801e7e2030e41eefe5d9dd96eaacfd] has
           13  +# been resolved.
           14  +#
           15  +# The problem described by this ticket was that the sqlite3ExprCompare()
           16  +# function was saying that expressions (x='a') and (x='A') were identical
           17  +# because it was using sqlite3StrICmp() instead of strcmp() to compare string
           18  +# literals.  That was causing the query optimizer for aggregate queries to 
           19  +# believe that both count() operations were identical, and thus only 
           20  +# computing the first count() and making a copy of the result for the 
           21  +# second count().
           22  +#
           23  +
           24  +set testdir [file dirname $argv0]
           25  +source $testdir/tester.tcl
           26  +
           27  +do_test tkt-fa7bf5ec-1 {
           28  +  execsql {
           29  +    CREATE TABLE t1(x);
           30  +    INSERT INTO t1 VALUES ('a');
           31  +    INSERT INTO t1 VALUES ('A');
           32  +    INSERT INTO t1 VALUES ('A');
           33  +    SELECT count(CASE WHEN x='a' THEN 1 END),
           34  +           count(CASE WHEN x='A' THEN 1 END)
           35  +      FROM t1;
           36  +  }
           37  +} {1 2}
           38  +
           39  +finish_test

Changes to test/tkt3793.test.

    96     96   # connection that called sqlite3_step()). When bug #3793 existed, sometimes
    97     97   # the [db2] busy-handler was invoked from within the call to sqlite3_step()
    98     98   # associated with [db1]. 
    99     99   #
   100    100   # Note: Before the bug was fixed, if [db2] was opened with the "-fullmutex 1"
   101    101   # option, then this test case would cause an assert() to fail.
   102    102   #
   103         -set ::busyconnection db1
   104         -db1 eval {SELECT * FROM t2 ORDER BY a LIMIT 20} {
   105         -  do_test tkt3793-2.[incr x] { set ::busyconnection } db1
   106         -  set ::busyconnection db2
   107         -
   108         -  db2 eval { SELECT count(*) FROM t2 }
   109         -  do_test tkt3793-2.[incr x] { set ::busyconnection } db2
          103  +ifcapable threadsafe {
   110    104     set ::busyconnection db1
          105  +  db1 eval {SELECT * FROM t2 ORDER BY a LIMIT 20} {
          106  +    do_test tkt3793-2.[incr x] { set ::busyconnection } db1
          107  +    set ::busyconnection db2
          108  +  
          109  +    db2 eval { SELECT count(*) FROM t2 }
          110  +    do_test tkt3793-2.[incr x] { set ::busyconnection } db2
          111  +    set ::busyconnection db1
          112  +  }
   111    113   }
   112         -
          114  +  
   113    115   do_test tkt3793-3 {
   114    116     db1 close
   115    117     db2 close
   116    118   } {}
   117    119   
   118    120   sqlite3_enable_shared_cache $::enable_shared_cache
   119    121   finish_test

Changes to test/walro.test.

   139    139     do_test 1.3.1 {
   140    140       code1 { db close }
   141    141       code1 { sqlite3 db test.db }
   142    142       csql1 { SELECT * FROM t1 }
   143    143     } {1 {unable to open database file}}
   144    144   
   145    145     # Also test that if the -shm file can be opened for read/write access,
   146         -  # it is, even if readonly_shm=1 is present in the URI.
          146  +  # it is not if readonly_shm=1 is present in the URI.
   147    147     do_test 1.3.2.1 {
   148    148       code1 { db close }
   149    149       code2 { db2 close }
   150    150       file exists test.db-shm
   151    151     } {0}
   152    152     do_test 1.3.2.2 {
   153    153       code1 { sqlite3 db file:test.db?readonly_shm=1 }
   154         -    sql1 { SELECT * FROM t1 }
   155         -  } {a b c d e f g h i j k l}
          154  +    csql1 { SELECT * FROM sqlite_master }
          155  +  } {1 {unable to open database file}}
   156    156     do_test 1.3.2.3 {
   157    157       code1 { db close }
   158    158       close [open test.db-shm w]
   159    159       file attributes test.db-shm -permissions r--r--r--
   160    160       code1 { sqlite3 db file:test.db?readonly_shm=1 }
   161    161       csql1 { SELECT * FROM t1 }
   162    162     } {1 {attempt to write a readonly database}}
   163    163     do_test 1.3.2.4 {
   164    164       code1 { sqlite3_extended_errcode db } 
   165    165     } {SQLITE_READONLY_RECOVERY}
   166    166   }
   167    167   
   168    168   finish_test

Changes to test/where3.test.

   337    337         AND bbb.parent = 4
   338    338       ORDER BY bbb.title COLLATE NOCASE ASC;
   339    339   } {
   340    340     0 0 1 {SEARCH TABLE aaa USING INDEX aaa_333 (fk=?) (~10 rows)} 
   341    341     0 1 0 {SEARCH TABLE aaa AS bbb USING INTEGER PRIMARY KEY (rowid=?) (~1 rows)} 
   342    342     0 0 0 {USE TEMP B-TREE FOR ORDER BY}
   343    343   }
          344  +
          345  +# Name resolution with NATURAL JOIN and USING
          346  +#
          347  +do_test where3-6.setup {
          348  +  db eval {
          349  +    CREATE TABLE t6w(a, w);
          350  +    INSERT INTO t6w VALUES(1, 'w-one');
          351  +    INSERT INTO t6w VALUES(2, 'w-two');
          352  +    INSERT INTO t6w VALUES(9, 'w-nine');
          353  +    CREATE TABLE t6x(a, x);
          354  +    INSERT INTO t6x VALUES(1, 'x-one');
          355  +    INSERT INTO t6x VALUES(3, 'x-three');
          356  +    INSERT INTO t6x VALUES(9, 'x-nine');
          357  +    CREATE TABLE t6y(a, y);
          358  +    INSERT INTO t6y VALUES(1, 'y-one');
          359  +    INSERT INTO t6y VALUES(4, 'y-four');
          360  +    INSERT INTO t6y VALUES(9, 'y-nine');
          361  +    CREATE TABLE t6z(a, z);
          362  +    INSERT INTO t6z VALUES(1, 'z-one');
          363  +    INSERT INTO t6z VALUES(5, 'z-five');
          364  +    INSERT INTO t6z VALUES(9, 'z-nine');
          365  +  }
          366  +} {}
          367  +set cnt 0
          368  +foreach predicate {
          369  +   {}
          370  +   {ORDER BY a}
          371  +   {ORDER BY t6w.a}
          372  +   {WHERE a>0}
          373  +   {WHERE t6y.a>0}
          374  +   {WHERE a>0 ORDER BY a}
          375  +} {
          376  +  incr cnt
          377  +  do_test where3-6.$cnt.1 {
          378  +    set sql "SELECT * FROM t6w NATURAL JOIN t6x NATURAL JOIN t6y"
          379  +    append sql " NATURAL JOIN t6z "
          380  +    append sql $::predicate
          381  +    db eval $sql
          382  +  } {1 w-one x-one y-one z-one 9 w-nine x-nine y-nine z-nine}
          383  +  do_test where3-6.$cnt.2 {
          384  +    set sql "SELECT * FROM t6w JOIN t6x USING(a) JOIN t6y USING(a)"
          385  +    append sql " JOIN t6z USING(a) "
          386  +    append sql $::predicate
          387  +    db eval $sql
          388  +  } {1 w-one x-one y-one z-one 9 w-nine x-nine y-nine z-nine}
          389  +  do_test where3-6.$cnt.3 {
          390  +    set sql "SELECT * FROM t6w NATURAL JOIN t6x JOIN t6y USING(a)"
          391  +    append sql " JOIN t6z USING(a) "
          392  +    append sql $::predicate
          393  +    db eval $sql
          394  +  } {1 w-one x-one y-one z-one 9 w-nine x-nine y-nine z-nine}
          395  +  do_test where3-6.$cnt.4 {
          396  +    set sql "SELECT * FROM t6w JOIN t6x USING(a) NATURAL JOIN t6y"
          397  +    append sql " JOIN t6z USING(a) "
          398  +    append sql $::predicate
          399  +    db eval $sql
          400  +  } {1 w-one x-one y-one z-one 9 w-nine x-nine y-nine z-nine}
          401  +  do_test where3-6.$cnt.5 {
          402  +    set sql "SELECT * FROM t6w JOIN t6x USING(a) JOIN t6y USING(a)"
          403  +    append sql " NATURAL JOIN t6z "
          404  +    append sql $::predicate
          405  +    db eval $sql
          406  +  } {1 w-one x-one y-one z-one 9 w-nine x-nine y-nine z-nine}
          407  +  do_test where3-6.$cnt.6 {
          408  +    set sql "SELECT * FROM t6w JOIN t6x USING(a) NATURAL JOIN t6y"
          409  +    append sql " NATURAL JOIN t6z "
          410  +    append sql $::predicate
          411  +    db eval $sql
          412  +  } {1 w-one x-one y-one z-one 9 w-nine x-nine y-nine z-nine}
          413  +  do_test where3-6.$cnt.7 {
          414  +    set sql "SELECT * FROM t6w NATURAL JOIN t6x JOIN t6y USING(a)"
          415  +    append sql " NATURAL JOIN t6z "
          416  +    append sql $::predicate
          417  +    db eval $sql
          418  +  } {1 w-one x-one y-one z-one 9 w-nine x-nine y-nine z-nine}
          419  +  do_test where3-6.$cnt.8 {
          420  +    set sql "SELECT * FROM t6w NATURAL JOIN t6x NATURAL JOIN t6y"
          421  +    append sql " JOIN t6z USING(a) "
          422  +    append sql $::predicate
          423  +    db eval $sql
          424  +  } {1 w-one x-one y-one z-one 9 w-nine x-nine y-nine z-nine}
          425  +}
          426  +
   344    427   
   345    428   finish_test

Changes to tool/omittest.tcl.

    44     44   # test in. The second parameter is a list of OMIT symbols to define
    45     45   # when doing so. For example:
    46     46   #
    47     47   #     run_quick_test /tmp/testdir {SQLITE_OMIT_TRIGGER SQLITE_OMIT_VIEW}
    48     48   #
    49     49   #
    50     50   proc run_quick_test {dir omit_symbol_list} {
    51         -  set target "testfixture"
    52     51     # Compile the value of the OPTS Makefile variable.
    53         -  set opts "-DSQLITE_MEMDEBUG -DSQLITE_DEBUG -DSQLITE_NO_SYNC" 
           52  +  set opts ""
    54     53     if {$::tcl_platform(platform)=="windows"} {
    55         -    append opts " -DSQLITE_OS_WIN=1"
           54  +    append opts "OPTS += -DSQLITE_OS_WIN=1\n"
    56     55       set target "testfixture.exe"
    57     56     } elseif {$::tcl_platform(platform)=="os2"} {
    58         -    append opts " -DSQLITE_OS_OS2=1"
           57  +    append opts "OPTS += -DSQLITE_OS_OS2=1\n"
    59     58     } else {
    60         -    append opts " -DSQLITE_OS_UNIX=1"
           59  +    append opts "OPTS += -DSQLITE_OS_UNIX=1\n"
    61     60     }
    62     61     foreach sym $omit_symbol_list {
    63         -    append opts " -D${sym}=1"
           62  +    append opts "OPTS += -D${sym}=1\n"
    64     63     }
    65     64   
    66     65     # Create the directory and do the build. If an error occurs return
    67     66     # early without attempting to run the test suite.
    68     67     file mkdir $dir
    69     68     puts -nonewline "Building $dir..."
    70     69     flush stdout
    71         -catch {
    72         -  file copy -force ./config.h $dir
    73         -  file copy -force ./libtool $dir
    74         -}
           70  +  catch {
           71  +    file copy -force ./config.h $dir
           72  +    file copy -force ./libtool $dir
           73  +  }
           74  +  set fd [open $::MAKEFILE]
           75  +  set mkfile [read $fd]
           76  +  close $fd
           77  +  regsub {\ninclude} $mkfile "\n$opts\ninclude" mkfile
           78  +  set fd [open $dir/makefile w]
           79  +  puts $fd $mkfile
           80  +  close $fd
           81  +  
    75     82     set rc [catch {
    76         -    exec $::MAKEBIN -C $dir -f $::MAKEFILE clean $target OPTS=$opts >& $dir/build.log
           83  +    exec $::MAKEBIN -C $dir -f makefile clean $::TARGET >& $dir/build.log
    77     84     }]
    78     85     if {$rc} {
    79     86       puts "No good. See $dir/build.log."
    80     87       return
    81     88     } else {
    82     89       puts "Ok"
    83     90     }
................................................................................
    98    105     if {$::SKIP_RUN} {
    99    106         puts "Skip testing $dir."
   100    107     } else {
   101    108       # Run the test suite.
   102    109       puts -nonewline "Testing $dir..."
   103    110       flush stdout
   104    111       set rc [catch {
   105         -      exec $::MAKEBIN -C $dir -f $::MAKEFILE test OPTS=$opts >& $dir/test.log
          112  +      exec $::MAKEBIN -C $dir -f makefile test >& $dir/test.log
   106    113       }]
   107    114       if {$rc} {
   108    115         puts "No good. See $dir/test.log."
   109    116       } else {
   110    117         puts "Ok"
   111    118       }
   112    119     }
................................................................................
   122    129     set ::MAKEBIN make                        ;# Default value
   123    130     if {$::tcl_platform(platform)=="windows" || $::tcl_platform(platform)=="os2"} {
   124    131       set ::MAKEFILE ./Makefile               ;# Default value on Windows and OS2
   125    132     } else {
   126    133       set ::MAKEFILE ./Makefile.linux-gcc     ;# Default value
   127    134     }
   128    135     set ::SKIP_RUN 0                          ;# Default to attempt test
          136  +  set ::TARGET testfixture                  ;# Default thing to build
   129    137   
   130    138     for {set i 0} {$i < [llength $argv]} {incr i} {
   131    139       switch -- [lindex $argv $i] {
   132    140         -makefile {
   133    141           incr i
   134    142           set ::MAKEFILE [lindex $argv $i]
   135    143         }
   136    144     
   137    145         -nmake {
   138    146           set ::MAKEBIN nmake
   139    147           set ::MAKEFILE ./Makefile.msc
   140    148         }
          149  +
          150  +      -target {
          151  +        incr i
          152  +        set ::TARGET [lindex $argv $i]
          153  +      }
   141    154   
   142    155         -skip_run {
   143    156           set ::SKIP_RUN 1
   144    157         }
   145    158   
   146    159         default {
   147    160           if {[info exists ::SYMBOL]} {
................................................................................
   178    191       SQLITE_OMIT_CHECK \
   179    192       SQLITE_OMIT_COMPILEOPTION_DIAGS \
   180    193       SQLITE_OMIT_COMPLETE \
   181    194       SQLITE_OMIT_COMPOUND_SELECT \
   182    195       SQLITE_OMIT_DATETIME_FUNCS \
   183    196       SQLITE_OMIT_DECLTYPE \
   184    197       SQLITE_OMIT_DEPRECATED \
   185         -    xxxSQLITE_OMIT_DISKIO \
   186    198       SQLITE_OMIT_EXPLAIN \
   187    199       SQLITE_OMIT_FLAG_PRAGMAS \
   188    200       SQLITE_OMIT_FLOATING_POINT \
   189    201       SQLITE_OMIT_FOREIGN_KEY \
   190    202       SQLITE_OMIT_GET_TABLE \
   191    203       SQLITE_OMIT_INCRBLOB \
   192    204       SQLITE_OMIT_INTEGRITY_CHECK \
................................................................................
   220    232       SQLITE_OMIT_XFER_OPT \
   221    233     ]
   222    234   
   223    235     set ::ENABLE_SYMBOLS [list \
   224    236       SQLITE_DISABLE_DIRSYNC \
   225    237       SQLITE_DISABLE_LFS \
   226    238       SQLITE_ENABLE_ATOMIC_WRITE \
   227         -    xxxSQLITE_ENABLE_CEROD \
   228    239       SQLITE_ENABLE_COLUMN_METADATA \
   229    240       SQLITE_ENABLE_EXPENSIVE_ASSERT \
   230         -    xxxSQLITE_ENABLE_FTS1 \
   231         -    xxxSQLITE_ENABLE_FTS2 \
   232    241       SQLITE_ENABLE_FTS3 \
   233    242       SQLITE_ENABLE_FTS3_PARENTHESIS \
   234    243       SQLITE_ENABLE_FTS4 \
   235         -    xxxSQLITE_ENABLE_ICU \
   236    244       SQLITE_ENABLE_IOTRACE \
   237    245       SQLITE_ENABLE_LOAD_EXTENSION \
   238    246       SQLITE_ENABLE_LOCKING_STYLE \
   239    247       SQLITE_ENABLE_MEMORY_MANAGEMENT \
   240    248       SQLITE_ENABLE_MEMSYS3 \
   241    249       SQLITE_ENABLE_MEMSYS5 \
   242    250       SQLITE_ENABLE_OVERSIZE_CELL_CHECK \
   243    251       SQLITE_ENABLE_RTREE \
   244         -    SQLITE_ENABLE_STAT2 \
          252  +    SQLITE_ENABLE_STAT3 \
   245    253       SQLITE_ENABLE_UNLOCK_NOTIFY \
   246    254       SQLITE_ENABLE_UPDATE_DELETE_LIMIT \
   247    255     ]
   248    256   
   249    257     # Process any command line options.
   250    258     process_options $argv
   251    259   

Added tool/symbols-mingw.sh.

            1  +#!/bin/sh
            2  +#
            3  +# Run this script in a directory that contains a valid SQLite makefile in
            4  +# order to verify that unintentionally exported symbols.
            5  +#
            6  +make sqlite3.c
            7  +
            8  +echo '****** Exported symbols from a build including RTREE && FTS4 ******'
            9  +gcc -c -DSQLITE_ENABLE_FTS3 -DSQLITE_ENABLE_RTREE \
           10  +  -DSQLITE_ENABLE_MEMORY_MANAGEMENT -DSQLITE_ENABLE_STAT3 \
           11  +  -DSQLITE_ENABLE_MEMSYS5 -DSQLITE_ENABLE_UNLOCK_NOTIFY \
           12  +  -DSQLITE_ENABLE_COLUMN_METADATA -DSQLITE_ENABLE_ATOMIC_WRITE \
           13  +  sqlite3.c
           14  +nm sqlite3.o | grep " [TD] "
           15  +
           16  +echo '****** Surplus symbols from a build including RTREE & FTS4 ******'
           17  +nm sqlite3.o | grep " [TD] " | grep -v " .*sqlite3_"
           18  +
           19  +echo '****** Dependencies of the core. No extensions. No OS interface *******'
           20  +gcc -c -DSQLITE_ENABLE_MEMORY_MANAGEMENT -DSQLITE_ENABLE_STAT3 \
           21  +  -DSQLITE_ENABLE_MEMSYS5 -DSQLITE_ENABLE_UNLOCK_NOTIFY \
           22  +  -DSQLITE_ENABLE_COLUMN_METADATA -DSQLITE_ENABLE_ATOMIC_WRITE \
           23  +  -DSQLITE_OS_OTHER -DSQLITE_THREADSAFE=0 \
           24  +  sqlite3.c
           25  +nm sqlite3.o | grep " U "
           26  +
           27  +echo '****** Dependencies including RTREE & FTS4 *******'
           28  +gcc -c -DSQLITE_ENABLE_FTS3 -DSQLITE_ENABLE_RTREE \
           29  +  -DSQLITE_ENABLE_MEMORY_MANAGEMENT -DSQLITE_ENABLE_STAT3 \
           30  +  -DSQLITE_ENABLE_MEMSYS5 -DSQLITE_ENABLE_UNLOCK_NOTIFY \
           31  +  -DSQLITE_ENABLE_COLUMN_METADATA -DSQLITE_ENABLE_ATOMIC_WRITE \
           32  +  sqlite3.c
           33  +nm sqlite3.o | grep " U "

Changes to tool/symbols.sh.

     3      3   # Run this script in a directory that contains a valid SQLite makefile in
     4      4   # order to verify that unintentionally exported symbols.
     5      5   #
     6      6   make sqlite3.c
     7      7   
     8      8   echo '****** Exported symbols from a build including RTREE, FTS4 & ICU ******'
     9      9   gcc -c -DSQLITE_ENABLE_FTS3 -DSQLITE_ENABLE_RTREE \
    10         -  -DSQLITE_ENABLE_MEMORY_MANAGEMENT -DSQLITE_ENABLE_STAT2 \
           10  +  -DSQLITE_ENABLE_MEMORY_MANAGEMENT -DSQLITE_ENABLE_STAT3 \
    11     11     -DSQLITE_ENABLE_MEMSYS5 -DSQLITE_ENABLE_UNLOCK_NOTIFY \
    12     12     -DSQLITE_ENABLE_COLUMN_METADATA -DSQLITE_ENABLE_ATOMIC_WRITE \
    13     13     -DSQLITE_ENABLE_ICU \
    14     14     sqlite3.c
    15     15   nm sqlite3.o | grep ' [TD] ' | sort -k 3
    16     16   
    17     17   echo '****** Surplus symbols from a build including RTREE, FTS4 & ICU ******'
    18     18   nm sqlite3.o | grep ' [TD] ' | grep -v ' .*sqlite3_'
    19     19   
    20     20   echo '****** Dependencies of the core. No extensions. No OS interface *******'
    21         -gcc -c -DSQLITE_ENABLE_MEMORY_MANAGEMENT -DSQLITE_ENABLE_STAT2 \
           21  +gcc -c -DSQLITE_ENABLE_MEMORY_MANAGEMENT -DSQLITE_ENABLE_STAT3 \
    22     22     -DSQLITE_ENABLE_MEMSYS5 -DSQLITE_ENABLE_UNLOCK_NOTIFY \
    23     23     -DSQLITE_ENABLE_COLUMN_METADATA -DSQLITE_ENABLE_ATOMIC_WRITE \
    24     24     -DSQLITE_OS_OTHER -DSQLITE_THREADSAFE=0 \
    25     25     sqlite3.c
    26     26   nm sqlite3.o | grep ' U ' | sort -k 3
    27     27   
    28     28   echo '****** Dependencies including RTREE & FTS4 *******'
    29     29   gcc -c -DSQLITE_ENABLE_FTS3 -DSQLITE_ENABLE_RTREE \
    30         -  -DSQLITE_ENABLE_MEMORY_MANAGEMENT -DSQLITE_ENABLE_STAT2 \
           30  +  -DSQLITE_ENABLE_MEMORY_MANAGEMENT -DSQLITE_ENABLE_STAT3 \
    31     31     -DSQLITE_ENABLE_MEMSYS5 -DSQLITE_ENABLE_UNLOCK_NOTIFY \
    32     32     -DSQLITE_ENABLE_COLUMN_METADATA -DSQLITE_ENABLE_ATOMIC_WRITE \
    33     33     sqlite3.c
    34     34   nm sqlite3.o | grep ' U ' | sort -k 3

Added tool/warnings-clang.sh.

            1  +#/bin/sh
            2  +#
            3  +# Run this script in a directory with a working makefile to check for 
            4  +# compiler warnings in SQLite.
            5  +#
            6  +rm -f sqlite3.c
            7  +make sqlite3.c
            8  +echo '************* FTS4 and RTREE ****************'
            9  +scan-build gcc -c -DHAVE_STDINT_H -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_RTREE \
           10  +      -DSQLITE_DEBUG sqlite3.c 2>&1 | grep -v 'ANALYZE:'
           11  +echo '********** ENABLE_STAT3. THREADSAFE=0 *******'
           12  +scan-build gcc -c -DSQLITE_ENABLE_STAT3 -DSQLITE_THREADSAFE=0 \
           13  +      -DSQLITE_DEBUG sqlite3.c 2>&1 | grep -v 'ANALYZE:'