]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Changes to allow FTS4 tables to be created without the underlying %_docsize table...
authordan <dan@noemail.net>
Tue, 2 Nov 2010 17:41:52 +0000 (17:41 +0000)
committerdan <dan@noemail.net>
Tue, 2 Nov 2010 17:41:52 +0000 (17:41 +0000)
FossilOrigin-Name: 31989b18f53d97eddfb39660ef04fbf9463583e0

ext/fts3/fts3.c
ext/fts3/fts3Int.h
ext/fts3/fts3_tokenizer.c
ext/fts3/fts3_write.c
manifest
manifest.uuid
test/fts3defer.test
test/fts3fault.test
test/fts3matchinfo.test [new file with mode: 0644]
test/permutations.test

index 5fcb77fb559fa6be567f1b4d0ef6f48efbae3116..023787c3bf110c91cd9c7735fe49910f2af0ba1f 100644 (file)
@@ -595,6 +595,8 @@ static int fts3CreateTables(Fts3Table *p){
         "CREATE TABLE %Q.'%q_docsize'(docid INTEGER PRIMARY KEY, size BLOB);",
         p->zDb, p->zName
     );
+  }
+  if( p->bHasStat ){
     fts3DbExec(&rc, db, 
         "CREATE TABLE %Q.'%q_stat'(id INTEGER PRIMARY KEY, value BLOB);",
         p->zDb, p->zName
@@ -669,6 +671,36 @@ static void fts3DatabasePageSize(int *pRc, Fts3Table *p){
   }
 }
 
+/*
+** "Special" FTS4 arguments are column specifications of the following form:
+**
+**   <key> = <value>
+**
+** There may not be whitespace surrounding the "=" character. The <value> 
+** term may be quoted, but the <key> may not.
+*/
+static int fts3IsSpecialColumn(
+  const char *z, 
+  int *pnKey,
+  char **pzValue
+){
+  char *zValue;
+  const char *zCsr = z;
+
+  while( *zCsr!='=' ){
+    if( *zCsr=='\0' ) return 0;
+    zCsr++;
+  }
+
+  *pnKey = zCsr-z;
+  zValue = sqlite3_mprintf("%s", &zCsr[1]);
+  if( zValue ){
+    sqlite3Fts3Dequote(zValue);
+  }
+  *pzValue = zValue;
+  return 1;
+}
+
 /*
 ** This function is the implementation of both the xConnect and xCreate
 ** methods of the FTS3 virtual table.
@@ -690,8 +722,8 @@ static int fts3InitVtab(
   char **pzErr                    /* Write any error message here */
 ){
   Fts3Hash *pHash = (Fts3Hash *)pAux;
-  Fts3Table *p;                   /* Pointer to allocated vtab */
-  int rc;                         /* Return code */
+  Fts3Table *p = 0;               /* Pointer to allocated vtab */
+  int rc = SQLITE_OK;             /* Return code */
   int i;                          /* Iterator variable */
   int nByte;                      /* Size of allocation used for *p */
   int iCol;                       /* Column index */
@@ -700,35 +732,90 @@ static int fts3InitVtab(
   char *zCsr;                     /* Space for holding column names */
   int nDb;                        /* Bytes required to hold database name */
   int nName;                      /* Bytes required to hold table name */
-
-  const char *zTokenizer = 0;               /* Name of tokenizer to use */
+  int isFts4 = (argv[0][3]=='4'); /* True for FTS4, false for FTS3 */
+  int bNoDocsize = 0;             /* True to omit %_docsize table */
+  const char **aCol;              /* Array of column names */
   sqlite3_tokenizer *pTokenizer = 0;        /* Tokenizer for this table */
 
+  assert( strlen(argv[0])==4 );
+  assert( (sqlite3_strnicmp(argv[0], "fts4", 4)==0 && isFts4)
+       || (sqlite3_strnicmp(argv[0], "fts3", 4)==0 && !isFts4)
+  );
+
   nDb = (int)strlen(argv[1]) + 1;
   nName = (int)strlen(argv[2]) + 1;
-  for(i=3; i<argc; i++){
+
+  aCol = (const char **)sqlite3_malloc(sizeof(const char *) * (argc-2) );
+  if( !aCol ) return SQLITE_NOMEM;
+  memset(aCol, 0, sizeof(const char *) * (argc-2));
+
+  /* Loop through all of the arguments passed by the user to the FTS3/4
+  ** module (i.e. all the column names and special arguments). This loop
+  ** does the following:
+  **
+  **   + Figures out the number of columns the FTSX table will have, and
+  **     the number of bytes of space that must be allocated to store copies
+  **     of the column names.
+  **
+  **   + If there is a tokenizer specification included in the arguments,
+  **     initializes the tokenizer pTokenizer.
+  */
+  for(i=3; rc==SQLITE_OK && i<argc; i++){
     char const *z = argv[i];
-    rc = sqlite3Fts3InitTokenizer(pHash, z, &pTokenizer, &zTokenizer, pzErr);
-    if( rc!=SQLITE_OK ){
-      return rc;
+    int nKey;
+    char *zVal;
+
+    /* Check if this is a tokenizer specification */
+    if( !pTokenizer 
+     && strlen(z)>8
+     && 0==sqlite3_strnicmp(z, "tokenize", 8) 
+     && 0==sqlite3Fts3IsIdChar(z[8])
+    ){
+      rc = sqlite3Fts3InitTokenizer(pHash, &z[9], &pTokenizer, pzErr);
     }
-    if( z!=zTokenizer ){
-      nString += (int)(strlen(z) + 1);
+
+    /* Check if it is an FTS4 special argument. */
+    else if( isFts4 && fts3IsSpecialColumn(z, &nKey, &zVal) ){
+      if( !zVal ){
+        rc = SQLITE_NOMEM;
+        goto fts3_init_out;
+      }
+      if( nKey==9 && 0==sqlite3_strnicmp(z, "matchinfo", 9) ){
+        if( strlen(zVal)==4 && 0==sqlite3_strnicmp(zVal, "fts3", 4) ){
+          bNoDocsize = 1;
+        }else{
+          *pzErr = sqlite3_mprintf("unrecognized matchinfo: %s", zVal);
+          rc = SQLITE_ERROR;
+        }
+      }else{
+        *pzErr = sqlite3_mprintf("unrecognized parameter: %s", z);
+        rc = SQLITE_ERROR;
+      }
+      sqlite3_free(zVal);
     }
-  }
-  nCol = argc - 3 - (zTokenizer!=0);
-  if( zTokenizer==0 ){
-    rc = sqlite3Fts3InitTokenizer(pHash, 0, &pTokenizer, 0, pzErr);
-    if( rc!=SQLITE_OK ){
-      return rc;
+
+    /* Otherwise, the argument is a column name. */
+    else {
+      nString += (int)(strlen(z) + 1);
+      aCol[nCol++] = z;
     }
-    assert( pTokenizer );
   }
+  if( rc!=SQLITE_OK ) goto fts3_init_out;
 
   if( nCol==0 ){
+    assert( nString==0 );
+    aCol[0] = "content";
+    nString = 8;
     nCol = 1;
   }
 
+  if( pTokenizer==0 ){
+    rc = sqlite3Fts3InitTokenizer(pHash, "simple", &pTokenizer, pzErr);
+    if( rc!=SQLITE_OK ) goto fts3_init_out;
+  }
+  assert( pTokenizer );
+
+
   /* Allocate and populate the Fts3Table structure. */
   nByte = sizeof(Fts3Table) +              /* Fts3Table */
           nCol * sizeof(char *) +              /* azColumn */
@@ -741,7 +828,6 @@ static int fts3InitVtab(
     goto fts3_init_out;
   }
   memset(p, 0, nByte);
-
   p->db = db;
   p->nColumn = nCol;
   p->nPendingData = 0;
@@ -749,11 +835,12 @@ static int fts3InitVtab(
   p->pTokenizer = pTokenizer;
   p->nNodeSize = 1000;
   p->nMaxPendingData = FTS3_MAX_PENDING_DATA;
-  zCsr = (char *)&p->azColumn[nCol];
-
+  p->bHasDocsize = (isFts4 && bNoDocsize==0);
+  p->bHasStat = isFts4;
   fts3HashInit(&p->pendingTerms, FTS3_HASH_STRING, 1);
 
   /* Fill in the zName and zDb fields of the vtab structure. */
+  zCsr = (char *)&p->azColumn[nCol];
   p->zName = zCsr;
   memcpy(zCsr, argv[2], nName);
   zCsr += nName;
@@ -762,36 +849,23 @@ static int fts3InitVtab(
   zCsr += nDb;
 
   /* Fill in the azColumn array */
-  iCol = 0;
-  for(i=3; i<argc; i++){
-    if( argv[i]!=zTokenizer ){
-      char *z; 
-      int n;
-      z = (char *)sqlite3Fts3NextToken(argv[i], &n);
-      memcpy(zCsr, z, n);
-      zCsr[n] = '\0';
-      sqlite3Fts3Dequote(zCsr);
-      p->azColumn[iCol++] = zCsr;
-      zCsr += n+1;
-      assert( zCsr <= &((char *)p)[nByte] );
-    }
-  }
-  if( iCol==0 ){
-    assert( nCol==1 );
-    p->azColumn[0] = "content";
+  for(iCol=0; iCol<nCol; iCol++){
+    char *z; 
+    int n;
+    z = (char *)sqlite3Fts3NextToken(aCol[iCol], &n);
+    memcpy(zCsr, z, n);
+    zCsr[n] = '\0';
+    sqlite3Fts3Dequote(zCsr);
+    p->azColumn[iCol] = zCsr;
+    zCsr += n+1;
+    assert( zCsr <= &((char *)p)[nByte] );
   }
 
   /* If this is an xCreate call, create the underlying tables in the 
   ** database. TODO: For xConnect(), it could verify that said tables exist.
   */
   if( isCreate ){
-    p->bHasContent = 1;
-    p->bHasDocsize = argv[0][3]=='4';
     rc = fts3CreateTables(p);
-  }else{
-    rc = SQLITE_OK;
-    fts3TableExists(&rc, db, argv[1], argv[2], "_content", &p->bHasContent);
-    fts3TableExists(&rc, db, argv[1], argv[2], "_docsize", &p->bHasDocsize);
   }
 
   /* Figure out the page-size for the database. This is required in order to
@@ -804,11 +878,12 @@ static int fts3InitVtab(
   fts3DeclareVtab(&rc, p);
 
 fts3_init_out:
-  assert( p || (pTokenizer && rc!=SQLITE_OK) );
+
+  sqlite3_free(aCol);
   if( rc!=SQLITE_OK ){
     if( p ){
       fts3DisconnectMethod((sqlite3_vtab *)p);
-    }else{
+    }else if( pTokenizer ){
       pTokenizer->pModule->xDestroy(pTokenizer);
     }
   }else{
@@ -3302,6 +3377,8 @@ static int fts3RenameMethod(
       "ALTER TABLE %Q.'%q_docsize'  RENAME TO '%q_docsize';",
       p->zDb, p->zName, zName
     );
+  }
+  if( p->bHasStat ){
     fts3DbExec(&rc, db,
       "ALTER TABLE %Q.'%q_stat'  RENAME TO '%q_stat';",
       p->zDb, p->zName, zName
index 9ddf5e51d07b7e018ec71e7540715536fda6487b..8ad560e316591f22d2af3f47628080fe2f1ae1d5 100644 (file)
@@ -131,7 +131,7 @@ struct Fts3Table {
   sqlite3_stmt *aStmt[24];
 
   int nNodeSize;                  /* Soft limit for node size */
-  u8 bHasContent;                 /* True if %_content table exists */
+  u8 bHasStat;                    /* True if %_stat table exists */
   u8 bHasDocsize;                 /* True if %_docsize table exists */
   int nPgsz;                      /* Page size for host database */
   char *zSegmentsTbl;             /* Name of %_segments table */
@@ -329,9 +329,10 @@ int sqlite3Fts3ExprNearTrim(Fts3Expr *, Fts3Expr *, int);
 /* fts3_tokenizer.c */
 const char *sqlite3Fts3NextToken(const char *, int *);
 int sqlite3Fts3InitHashTable(sqlite3 *, Fts3Hash *, const char *);
-int sqlite3Fts3InitTokenizer(Fts3Hash *pHash, 
-  const char *, sqlite3_tokenizer **, const char **, char **
+int sqlite3Fts3InitTokenizer(Fts3Hash *pHash, const char *, 
+    sqlite3_tokenizer **, char **
 );
+int sqlite3Fts3IsIdChar(char);
 
 /* fts3_snippet.c */
 void sqlite3Fts3Offsets(sqlite3_context*, Fts3Cursor*);
index 54a91bfe4548ec9f4eec88868fba316e7335466d..cf392d38f77aa19abb3ba608541c0049b0b729be 100644 (file)
@@ -97,7 +97,7 @@ static void scalarFunc(
   sqlite3_result_blob(context, (void *)&pPtr, sizeof(pPtr), SQLITE_TRANSIENT);
 }
 
-static int fts3IsIdChar(char c){
+int sqlite3Fts3IsIdChar(char c){
   static const char isFtsIdChar[] = {
       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  /* 0x */
       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  /* 1x */
@@ -135,9 +135,9 @@ const char *sqlite3Fts3NextToken(const char *zStr, int *pn){
         break;
 
       default:
-        if( fts3IsIdChar(*z1) ){
+        if( sqlite3Fts3IsIdChar(*z1) ){
           z2 = &z1[1];
-          while( fts3IsIdChar(*z2) ) z2++;
+          while( sqlite3Fts3IsIdChar(*z2) ) z2++;
         }else{
           z1++;
         }
@@ -150,9 +150,8 @@ const char *sqlite3Fts3NextToken(const char *zStr, int *pn){
 
 int sqlite3Fts3InitTokenizer(
   Fts3Hash *pHash,                /* Tokenizer hash table */
-  const char *zArg,               /* Possible tokenizer specification */
+  const char *zArg,               /* Tokenizer name */
   sqlite3_tokenizer **ppTok,      /* OUT: Tokenizer (if applicable) */
-  const char **pzTokenizer,       /* OUT: Set to zArg if is tokenizer */
   char **pzErr                    /* OUT: Set to malloced error message */
 ){
   int rc;
@@ -162,26 +161,15 @@ int sqlite3Fts3InitTokenizer(
   char *zEnd;                     /* Pointer to nul-term of zCopy */
   sqlite3_tokenizer_module *m;
 
-  if( !z ){
-    zCopy = sqlite3_mprintf("simple");
-  }else{
-    if( sqlite3_strnicmp(z, "tokenize", 8) || fts3IsIdChar(z[8])){
-      return SQLITE_OK;
-    }
-    zCopy = sqlite3_mprintf("%s", &z[8]);
-    *pzTokenizer = zArg;
-  }
-  if( !zCopy ){
-    return SQLITE_NOMEM;
-  }
-
+  zCopy = sqlite3_mprintf("%s", zArg);
+  if( !zCopy ) return SQLITE_NOMEM;
   zEnd = &zCopy[strlen(zCopy)];
 
   z = (char *)sqlite3Fts3NextToken(zCopy, &n);
   z[n] = '\0';
   sqlite3Fts3Dequote(z);
 
-  m = (sqlite3_tokenizer_module *)sqlite3Fts3HashFind(pHash, z, (int)strlen(z)+1);
+  m = (sqlite3_tokenizer_module *)sqlite3Fts3HashFind(pHash,z,(int)strlen(z)+1);
   if( !m ){
     *pzErr = sqlite3_mprintf("unknown tokenizer: %s", z);
     rc = SQLITE_ERROR;
index 2f4db406edd03bff893d8803e8b4d4e1b4c6f2af..91699bedb7ad1828b2b0ea389ee5b4836d5e8de3 100644 (file)
@@ -683,6 +683,8 @@ static int fts3DeleteAll(Fts3Table *p){
   fts3SqlExec(&rc, p, SQL_DELETE_ALL_SEGDIR, 0);
   if( p->bHasDocsize ){
     fts3SqlExec(&rc, p, SQL_DELETE_ALL_DOCSIZE, 0);
+  }
+  if( p->bHasStat ){
     fts3SqlExec(&rc, p, SQL_DELETE_ALL_STAT, 0);
   }
   return rc;
@@ -1035,7 +1037,7 @@ int sqlite3Fts3SegReaderCost(
   ** for the segment is stored on the root page of the b-tree, then the cost
   ** is zero. In this case all required data is already in main memory.
   */
-  if( p->bHasDocsize 
+  if( p->bHasStat 
    && !fts3SegReaderIsPending(pReader) 
    && !fts3SegReaderIsRootOnly(pReader) 
   ){
@@ -2855,8 +2857,8 @@ int sqlite3Fts3UpdateMethod(
         fts3SqlExec(&rc, p, SQL_DELETE_CONTENT, apVal);
         if( p->bHasDocsize ){
           fts3SqlExec(&rc, p, SQL_DELETE_DOCSIZE, apVal);
-          nChng--;
         }
+        nChng--;
       }
     }
   }else if( sqlite3_value_type(apVal[p->nColumn+2])!=SQLITE_NULL ){
@@ -2874,12 +2876,12 @@ int sqlite3Fts3UpdateMethod(
       rc = fts3InsertTerms(p, apVal, aSzIns);
     }
     if( p->bHasDocsize ){
-      nChng++;
       fts3InsertDocsize(&rc, p, aSzIns);
     }
+    nChng++;
   }
 
-  if( p->bHasDocsize ){
+  if( p->bHasStat ){
     fts3UpdateDocTotals(&rc, p, aSzIns, aSzDel, nChng);
   }
 
index e625fa9968744a0e07d8efd8899da6e9708ccbe2..414c336c3673d6255fb092b5812b38b727849e95 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,8 +1,5 @@
------BEGIN PGP SIGNED MESSAGE-----
-Hash: SHA1
-
-C Add\sevidence\smarks\sfor\sthe\ssqlite3_blob_reopen()\sinterface.\s\sFix\scompiler\nwarnings\sin\stest1.c.\s\sFix\sincorrect\sevidence\smarks\son\se_select.tcl.
-D 2010-11-02T15:26:24
+C Changes\sto\sallow\sFTS4\stables\sto\sbe\screated\swithout\sthe\sunderlying\s%_docsize\stable\s(in\sorder\sto\ssave\sspace).
+D 2010-11-02T17:41:53
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in 2c8cefd962eca0147132c7cf9eaa4bb24c656f3f
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -64,19 +61,19 @@ F ext/fts2/mkfts2amal.tcl 974d5d438cb3f7c4a652639262f82418c1e4cff0
 F ext/fts3/README.syntax a19711dc5458c20734b8e485e75fb1981ec2427a
 F ext/fts3/README.tokenizers 998756696647400de63d5ba60e9655036cb966e9
 F ext/fts3/README.txt 8c18f41574404623b76917b9da66fcb0ab38328d
-F ext/fts3/fts3.c 48c37f640fb5837dcdbd04ef2d51ec40c8637503
+F ext/fts3/fts3.c 9da9f1d5bc4b087540255ffdb7a4428fe708edf0
 F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe
-F ext/fts3/fts3Int.h 819bc2661c8f3b46221d146f1810dc6741819f55
+F ext/fts3/fts3Int.h bbcd6d671228c9ae2ed5514723fcc6217821d0a6
 F ext/fts3/fts3_expr.c ee48b9278b8b2432a05a03320fbcacba151dbaa5
 F ext/fts3/fts3_hash.c 3c8f6387a4a7f5305588b203fa7c887d753e1f1c
 F ext/fts3/fts3_hash.h 8331fb2206c609f9fc4c4735b9ab5ad6137c88ec
 F ext/fts3/fts3_icu.c ac494aed69835008185299315403044664bda295
 F ext/fts3/fts3_porter.c 8df6f6efcc4e9e31f8bf73a4007c2e9abca1dfba
 F ext/fts3/fts3_snippet.c 300c12b7f0a2a6ae0491bb2d00e2d5ff9c28f685
-F ext/fts3/fts3_tokenizer.c b4f2d01c24573852755bc92864816785dae39318
+F ext/fts3/fts3_tokenizer.c 1301b0ee3ef414caae3257a702215925cc48cd9c
 F ext/fts3/fts3_tokenizer.h 13ffd9fcb397fec32a05ef5cd9e0fa659bf3dbd3
 F ext/fts3/fts3_tokenizer1.c 6e5cbaa588924ac578263a598e4fb9f5c9bb179d
-F ext/fts3/fts3_write.c 01478ee63bb321f240bb5565d9e36e8641b33928
+F ext/fts3/fts3_write.c 3d12dad6cbe788ff7214ef227520fb6600ff5112
 F ext/fts3/fts3speed.tcl b54caf6a18d38174f1a6e84219950d85e98bb1e9
 F ext/fts3/mkfts3amal.tcl 252ecb7fe6467854f2aa237bf2c390b74e71f100
 F ext/icu/README.txt bf8461d8cdc6b8f514c080e4e10dc3b2bbdfefa9
@@ -438,13 +435,14 @@ F test/fts3corrupt.test d874ba27975aa8e5514bf58bf97b473404de0dbb
 F test/fts3corrupt2.test 6d96efae2f8a6af3eeaf283aba437e6d0e5447ba
 F test/fts3cov.test e0fb00d8b715ddae4a94c305992dfc3ef70353d7
 F test/fts3d.test 95fb3c862cbc4297c93fceb9a635543744e9ef52
-F test/fts3defer.test eab4f24c8402fb4e1e6aad44bcdfbe5bf42160b2
+F test/fts3defer.test d6cb0db9b5997ecf863d96ff419f83f8f2c87f4f
 F test/fts3defer2.test d3c7db6584aab06a2781b8de58747c33b23cb19c
 F test/fts3e.test 1f6c6ac9cc8b772ca256e6b22aaeed50c9350851
 F test/fts3expr.test 5e745b2b6348499d9ef8d59015de3182072c564c
 F test/fts3expr2.test 18da930352e5693eaa163a3eacf96233b7290d1a
-F test/fts3fault.test c45707ac123b511e4d8291ca3d84e25fd5029b43
+F test/fts3fault.test 2c8c26f9002be900056b63996a2891a043775f7b
 F test/fts3malloc.test 9c8cc3f885bb4dfc66d0460c52f68f45e4710d1b
+F test/fts3matchinfo.test 5ded93253526033c662ec49c696e936da4e8885d
 F test/fts3near.test 2e318ee434d32babd27c167142e2b94ddbab4844
 F test/fts3query.test 724a662dbbec4e9dbef66a1389588aa29aeb9b27
 F test/fts3rnd.test 707533ce943f490443ce5e696236bb1675a37635
@@ -578,7 +576,7 @@ F test/pageropt.test 8146bf448cf09e87bb1867c2217b921fb5857806
 F test/pagesize.test 76aa9f23ecb0741a4ed9d2e16c5fa82671f28efb
 F test/pcache.test 4118a183908ecaed343a06fcef3ba82e87e0129d
 F test/pcache2.test 0d85f2ab6963aee28c671d4c71bec038c00a1d16
-F test/permutations.test e54d5fc34708ecb4a67f2a18f7b8719b175a1652
+F test/permutations.test 193238b7828759805091ecddd9a0912767f236a4
 F test/pragma.test fdfc09067ea104a0c247a1a79d8093b56656f850
 F test/pragma2.test 5364893491b9231dd170e3459bfc2e2342658b47
 F test/printf.test 05970cde31b1a9f54bd75af60597be75a5c54fea
@@ -885,14 +883,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
 F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
-P 6cae552927392d8b735aa118c318d7468097ebeb
-R 99d449c40cc2af47a17f6b479744ba94
-U drh
-Z e0eff9674ebb6295f2b6870d990e3417
------BEGIN PGP SIGNATURE-----
-Version: GnuPG v1.4.6 (GNU/Linux)
-
-iD8DBQFM0C2qoxKgR168RlERAtsWAJ0c+Qg4qImQebinYShOYuBIEoXfRwCfQdMI
-MPI2wIAAWE4t5rkTCaRo+NI=
-=5kvu
------END PGP SIGNATURE-----
+P 3771faa88eda3eb91264ce0982e22f53596abd4b
+R 1930e53dc41c38f7661c545902820ee1
+U dan
+Z d5d5199f8f8688f85abc4cc6dcb16369
index 58981e0986818bfc9de197fa3833d48f8f3ac9bf..b78828ea1c1e6ad5038f0fd790265062361803b4 100644 (file)
@@ -1 +1 @@
-3771faa88eda3eb91264ce0982e22f53596abd4b
\ No newline at end of file
+31989b18f53d97eddfb39660ef04fbf9463583e0
\ No newline at end of file
index f6231435681b0335b483dbfcde710d6b849e3c4e..1c9056fd9d25de68f36c174d2b3ba5121cc0e8dd 100644 (file)
@@ -233,6 +233,13 @@ foreach {tn setup} {
     execsql "INSERT INTO t1(t1) VALUES('optimize')"
     execsql $zero_long_doclists
   }
+  5 {
+    set dmt_modes 0
+    execsql { CREATE VIRTUAL TABLE t1 USING FTS4(matchinfo=fts3) }
+    foreach doc $data { execsql { INSERT INTO t1 VALUES($doc) } }
+    add_empty_records 1000
+    execsql $zero_long_doclists
+  }
 } {
 
   execsql { DROP TABLE IF EXISTS t1 }
index 67f47ddf8ebae67a142e5124c9909afb54f2a91e..fe1f77f9a634497fdc66228e923b318ab08138ea 100644 (file)
@@ -126,4 +126,30 @@ do_faultsim_test 6 -prep {
   faultsim_test_result {0 {}}
 }
 
+# Test various malloc failures while processing FTS4 parameters.
+#
+do_faultsim_test 7.1 -prep { 
+  faultsim_delete_and_reopen
+} -body {
+  execsql { CREATE VIRTUAL TABLE t1 USING fts4(a, b, matchinfo=fts3) }
+} -test {
+  faultsim_test_result {0 {}}
+}
+do_faultsim_test 7.2 -prep { 
+  faultsim_delete_and_reopen
+} -body {
+  execsql { CREATE VIRTUAL TABLE t1 USING fts4(a, b, matchinfo=fs3) }
+} -test {
+  faultsim_test_result {1 {unrecognized matchinfo: fs3}} \
+                       {1 {vtable constructor failed: t1}}
+}
+do_faultsim_test 7.3 -prep { 
+  faultsim_delete_and_reopen
+} -body {
+  execsql { CREATE VIRTUAL TABLE t1 USING fts4(a, b, matchnfo=fts3) }
+} -test {
+  faultsim_test_result {1 {unrecognized parameter: matchnfo=fts3}} \
+                       {1 {vtable constructor failed: t1}}
+}
+
 finish_test
diff --git a/test/fts3matchinfo.test b/test/fts3matchinfo.test
new file mode 100644 (file)
index 0000000..44f111f
--- /dev/null
@@ -0,0 +1,68 @@
+# 2010 November 02
+#
+# The author disclaims copyright to this source code.  In place of
+# a legal notice, here is a blessing:
+#
+#    May you do good and not evil.
+#    May you find forgiveness for yourself and forgive others.
+#    May you share freely, never taking more than you give.
+#
+#***********************************************************************
+# This file implements regression tests for the FTS3 module. The focus
+# of this file is tables created with the "matchinfo=fts3" option.
+#
+
+set testdir [file dirname $argv0]
+source $testdir/tester.tcl
+
+set testprefix fts3matchinfo
+
+proc mit {blob} {
+  set scan(littleEndian) i*
+  set scan(bigEndian) I*
+  binary scan $blob $scan($::tcl_platform(byteOrder)) r
+  return $r
+}
+db func mit mit
+
+do_execsql_test 1.0 {
+  CREATE VIRTUAL TABLE t1 USING fts4(matchinfo=fts3);
+  SELECT name FROM sqlite_master WHERE type = 'table';
+} {t1 t1_content t1_segments t1_segdir t1_stat}
+
+do_execsql_test 1.1 {
+  INSERT INTO t1(content) VALUES('I wandered lonely as a cloud');
+  INSERT INTO t1(content) VALUES('That floats on high o''er vales and hills,');
+  INSERT INTO t1(content) VALUES('When all at once I saw a crowd,');
+  INSERT INTO t1(content) VALUES('A host, of golden daffodils,');
+  SELECT mit(matchinfo(t1)) FROM t1 WHERE t1 MATCH 'I';
+} {{1 1 1 2 2} {1 1 1 2 2}}
+
+# Now create an FTS4 table that does not specify matchinfo=fts3. The 
+# %_docsize table is created in this case and the array of integers returned
+# by matchinfo() includes the extra data.
+#
+do_execsql_test 1.2 {
+  CREATE VIRTUAL TABLE t2 USING fts4;
+  INSERT INTO t2 SELECT * FROM t1;
+  SELECT mit(matchinfo(t2)) FROM t2 WHERE t2 MATCH 'I';
+} {{1 1 1 2 2 4 7 6} {1 1 1 2 2 4 7 8}}
+
+# Test some syntax-error handling.
+#
+do_catchsql_test 2.0 {
+  CREATE VIRTUAL TABLE x1 USING fts4(matchinfo=fs3);
+} {1 {unrecognized matchinfo: fs3}}
+do_catchsql_test 2.1 {
+  CREATE VIRTUAL TABLE x2 USING fts4(mtchinfo=fts3);
+} {1 {unrecognized parameter: mtchinfo=fts3}}
+
+# Check that with fts3, the "=" character is permitted in column definitions.
+#
+do_execsql_test 3.1 {
+  CREATE VIRTUAL TABLE t3 USING fts3(mtchinfo=fts3);
+  INSERT INTO t3(mtchinfo) VALUES('Beside the lake, beneath the trees');
+  SELECT mtchinfo FROM t3;
+} {{Beside the lake, beneath the trees}}
+
+finish_test
index 14cf3abfe620bbccce38c8d928d5e89fb6ca4646..5576f5bf392a4a32b47d8c109e497b63260686a1 100644 (file)
@@ -168,7 +168,7 @@ test_suite "fts3" -prefix "" -description {
   fts3defer.test fts3defer2.test fts3e.test fts3expr.test fts3expr2.test 
   fts3near.test fts3query.test fts3shared.test fts3snippet.test 
 
-  fts3fault.test fts3malloc.test
+  fts3fault.test fts3malloc.test fts3matchinfo.test
 }