]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Change FTS4 so that if both the content=xxx option and column names are specified...
authordan <dan@noemail.net>
Wed, 5 Oct 2011 15:11:30 +0000 (15:11 +0000)
committerdan <dan@noemail.net>
Wed, 5 Oct 2011 15:11:30 +0000 (15:11 +0000)
FossilOrigin-Name: 289ee43179369fce2fde50870d72c445e184e896

ext/fts3/fts3.c
ext/fts3/fts3_write.c
manifest
manifest.uuid
test/fts4content.test

index 624221f979af80641ec49a638d14b513d2dac0d6..6fa06907bf701c9376e2d6ed6ba7c35905d15b14 100644 (file)
@@ -1182,20 +1182,19 @@ static int fts3InitVtab(
   **
   **   1. Ignore any compress= and uncompress= options.
   **
-  **   2. Ignore any column names that were specified as part of the 
-  **      the CREATE VIRTUAL TABLE statement.
-  **
-  **   3. Determine the actual column names to use for the FTS table 
-  **      based on the columns of the content= table.
+  **   2. If no column names were specified as part of the CREATE VIRTUAL
+  **      TABLE statement, use all columns from the content table.
   */
   if( rc==SQLITE_OK && zContent ){
-    sqlite3_free(aCol); 
     sqlite3_free(zCompress); 
     sqlite3_free(zUncompress); 
     zCompress = 0;
     zUncompress = 0;
-    aCol = 0;
-    rc = fts3ContentColumns(db, argv[1], zContent, &aCol, &nCol, &nString);
+    if( nCol==0 ){
+      sqlite3_free(aCol); 
+      aCol = 0;
+      rc = fts3ContentColumns(db, argv[1], zContent, &aCol, &nCol, &nString);
+    }
     assert( rc!=SQLITE_OK || nCol>0 );
   }
   if( rc!=SQLITE_OK ) goto fts3_init_out;
@@ -1457,40 +1456,64 @@ static int fts3CloseMethod(sqlite3_vtab_cursor *pCursor){
   return SQLITE_OK;
 }
 
+/*
+** If pCsr->pStmt has not been prepared (i.e. if pCsr->pStmt==0), then
+** compose and prepare an SQL statement of the form:
+**
+**    "SELECT <columns> FROM %_content WHERE rowid = ?"
+**
+** (or the equivalent for a content=xxx table) and set pCsr->pStmt to
+** it. If an error occurs, return an SQLite error code.
+**
+** Otherwise, set *ppStmt to point to pCsr->pStmt and return SQLITE_OK.
+*/
+static int fts3CursorSeekStmt(Fts3Cursor *pCsr, sqlite3_stmt **ppStmt){
+  int rc = SQLITE_OK;
+  if( pCsr->pStmt==0 ){
+    Fts3Table *p = (Fts3Table *)pCsr->base.pVtab;
+    char *zSql;
+    zSql = sqlite3_mprintf("SELECT %s WHERE rowid = ?", p->zReadExprlist);
+    if( !zSql ) return SQLITE_NOMEM;
+    rc = sqlite3_prepare_v2(p->db, zSql, -1, &pCsr->pStmt, 0);
+    sqlite3_free(zSql);
+  }
+  *ppStmt = pCsr->pStmt;
+  return rc;
+}
+
 /*
 ** Position the pCsr->pStmt statement so that it is on the row
 ** of the %_content table that contains the last match.  Return
 ** SQLITE_OK on success.  
 */
 static int fts3CursorSeek(sqlite3_context *pContext, Fts3Cursor *pCsr){
+  int rc = SQLITE_OK;
   if( pCsr->isRequireSeek ){
-    sqlite3_bind_int64(pCsr->pStmt, 1, pCsr->iPrevId);
-    pCsr->isRequireSeek = 0;
-    if( SQLITE_ROW==sqlite3_step(pCsr->pStmt) ){
-      return SQLITE_OK;
-    }else{
-      int rc = sqlite3_reset(pCsr->pStmt);
-      if( rc==SQLITE_OK ){
-        Fts3Table *p = (Fts3Table *)pCsr->base.pVtab;
-        if( p->zContentTbl==0 ){
+    sqlite3_stmt *pStmt = 0;
+
+    rc = fts3CursorSeekStmt(pCsr, &pStmt);
+    if( rc==SQLITE_OK ){
+      sqlite3_bind_int64(pCsr->pStmt, 1, pCsr->iPrevId);
+      pCsr->isRequireSeek = 0;
+      if( SQLITE_ROW==sqlite3_step(pCsr->pStmt) ){
+        return SQLITE_OK;
+      }else{
+        rc = sqlite3_reset(pCsr->pStmt);
+        if( rc==SQLITE_OK && ((Fts3Table *)pCsr->base.pVtab)->zContentTbl==0 ){
           /* If no row was found and no error has occured, then the %_content
           ** table is missing a row that is present in the full-text index.
-          ** The data structures are corrupt.
-          */
+          ** The data structures are corrupt.  */
           rc = SQLITE_CORRUPT_VTAB;
-        }else{
-          return SQLITE_OK;
+          pCsr->isEof = 1;
         }
       }
-      pCsr->isEof = 1;
-      if( pContext ){
-        sqlite3_result_error_code(pContext, rc);
-      }
-      return rc;
     }
-  }else{
-    return SQLITE_OK;
   }
+
+  if( rc!=SQLITE_OK && pContext ){
+    sqlite3_result_error_code(pContext, rc);
+  }
+  return rc;
 }
 
 /*
@@ -2848,24 +2871,24 @@ static int fts3FilterMethod(
   ** row by docid.
   */
   if( idxNum==FTS3_FULLSCAN_SEARCH ){
-    const char *zTmpl = "SELECT %s ORDER BY rowid %s";
-    zSql = sqlite3_mprintf(zTmpl, 
+    zSql = sqlite3_mprintf(
+        "SELECT %s ORDER BY rowid %s",
         p->zReadExprlist, (pCsr->bDesc ? "DESC" : "ASC")
     );
-  }else{
-    const char *zTmpl = "SELECT %s WHERE rowid = ?";
-    zSql = sqlite3_mprintf(zTmpl, p->zReadExprlist);
+    if( zSql ){
+      rc = sqlite3_prepare_v2(p->db, zSql, -1, &pCsr->pStmt, 0);
+      sqlite3_free(zSql);
+    }else{
+      rc = SQLITE_NOMEM;
+    }
+  }else if( idxNum==FTS3_DOCID_SEARCH ){
+    rc = fts3CursorSeekStmt(pCsr, &pCsr->pStmt);
+    if( rc==SQLITE_OK ){
+      rc = sqlite3_bind_value(pCsr->pStmt, 1, apVal[0]);
+    }
   }
-  if( !zSql ) return SQLITE_NOMEM;
-  rc = sqlite3_prepare_v2(p->db, zSql, -1, &pCsr->pStmt, 0);
-  sqlite3_free(zSql);
   if( rc!=SQLITE_OK ) return rc;
 
-  if( idxNum==FTS3_DOCID_SEARCH ){
-    rc = sqlite3_bind_value(pCsr->pStmt, 1, apVal[0]);
-    if( rc!=SQLITE_OK ) return rc;
-  }
-
   return fts3NextMethod(pCursor);
 }
 
index 591f31f0816fcf133b3bf9a3cfecae0d9f1f35fc..47bed0dd5e0d8655466661ec9b43a5a05a22d231 100644 (file)
@@ -409,17 +409,24 @@ static void fts3SqlExec(
 ** not what users expect when they get SQLITE_LOCKED_SHAREDCACHE. It can
 ** still happen if the user reads data directly from the %_segments or
 ** %_segdir tables instead of going through FTS3 though.
+**
+** This reasoning does not apply to a content=xxx table.
 */
 int sqlite3Fts3ReadLock(Fts3Table *p){
   int rc;                         /* Return code */
   sqlite3_stmt *pStmt;            /* Statement used to obtain lock */
 
-  rc = fts3SqlStmt(p, SQL_SELECT_CONTENT_BY_ROWID, &pStmt, 0);
-  if( rc==SQLITE_OK ){
-    sqlite3_bind_null(pStmt, 1);
-    sqlite3_step(pStmt);
-    rc = sqlite3_reset(pStmt);
+  if( p->zContentTbl==0 ){
+    rc = fts3SqlStmt(p, SQL_SELECT_CONTENT_BY_ROWID, &pStmt, 0);
+    if( rc==SQLITE_OK ){
+      sqlite3_bind_null(pStmt, 1);
+      sqlite3_step(pStmt);
+      rc = sqlite3_reset(pStmt);
+    }
+  }else{
+    rc = SQLITE_OK;
   }
+
   return rc;
 }
 
index b582707f76bd8e91f840f015c4002f521ad151d1..0c36a83a5c20732331b32a2363331fc0fa8d2193 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Fix\sa\sproblem\swith\sIO\serror\shandling\sin\sthe\srebuild-index\scode.
-D 2011-10-05T06:07:00.875
+C Change\sFTS4\sso\sthat\sif\sboth\sthe\scontent=xxx\soption\sand\scolumn\snames\sare\sspecified,\sthe\svirtual\stable\sassumes\sthat\sthe\snamed\scolumns\scorrespond\sto\scolumns\sof\stable\sxxx.
+D 2011-10-05T15:11:30.760
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in a162fe39e249b8ed4a65ee947c30152786cfe897
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -62,7 +62,7 @@ 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 6d6f3d331ed785d2e68608443eff66448ea95354
+F ext/fts3/fts3.c f2ed0ae669534e0c9c8ba95b60b6c137544e7e49
 F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe
 F ext/fts3/fts3Int.h 06f442ce096e6254432a6b16a56b6fe7b24bd372
 F ext/fts3/fts3_aux.c 0ebfa7b86cf8ff6a0861605fcc63b83ec1b70691
@@ -77,7 +77,7 @@ F ext/fts3/fts3_test.c 24fa13f330db011500acb95590da9eee24951894
 F ext/fts3/fts3_tokenizer.c 9ff7ec66ae3c5c0340fa081958e64f395c71a106
 F ext/fts3/fts3_tokenizer.h 13ffd9fcb397fec32a05ef5cd9e0fa659bf3dbd3
 F ext/fts3/fts3_tokenizer1.c 0dde8f307b8045565cf63797ba9acfaff1c50c68
-F ext/fts3/fts3_write.c 16fba93fc840f15421ebf1a783a8c3395700bbf9
+F ext/fts3/fts3_write.c 06520aa8a0a32a7bed08b29a9004fde1cb7f0318
 F ext/fts3/fts3speed.tcl b54caf6a18d38174f1a6e84219950d85e98bb1e9
 F ext/fts3/mkfts3amal.tcl 252ecb7fe6467854f2aa237bf2c390b74e71f100
 F ext/icu/README.txt bf8461d8cdc6b8f514c080e4e10dc3b2bbdfefa9
@@ -486,7 +486,7 @@ F test/fts3shared.test 8bb266521d7c5495c0ae522bb4d376ad5387d4a2
 F test/fts3snippet.test 8e956051221a34c7daeb504f023cb54d5fa5a8b2
 F test/fts3sort.test 95be0b19d7e41c44b29014f13ea8bddd495fd659
 F test/fts4aa.test 6e7f90420b837b2c685f3bcbe84c868492d40a68
-F test/fts4content.test 5c226c7c666e250c175bcbdfbdd4be3f275c73ba
+F test/fts4content.test c5f531ecfc3d446b90032cae212549dbbb18dd78
 F test/func.test 6c5ce11e3a0021ca3c0649234e2d4454c89110ca
 F test/func2.test 772d66227e4e6684b86053302e2d74a2500e1e0f
 F test/func3.test 001021e5b88bd02a3b365a5c5fd8f6f49d39744a
@@ -966,7 +966,7 @@ F tool/symbols.sh caaf6ccc7300fd43353318b44524853e222557d5
 F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06
 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
 F tool/warnings.sh b7fdb2cc525f5ef4fa43c80e771636dd3690f9d2
-P 0f439944ab49a5691615bc170fdcf652055573df
-R 29197ea13db81f2ba07fe324b03117e5
+P c6ba81fcad32192674bd510e607f787adc1f7038
+R 0217fe49810be9d8f9417ba3c648ab3e
 U dan
-Z a28913360f741831433fc7b43c93a8a9
+Z 1eb4f36513f7844867f45162778888e7
index 5039f9295edbdae3a25953b4000114db47dfee90..b8efcec3d49d998be6332796984710bd4effda98 100644 (file)
@@ -1 +1 @@
-c6ba81fcad32192674bd510e607f787adc1f7038
\ No newline at end of file
+289ee43179369fce2fde50870d72c445e184e896
\ No newline at end of file
index 7925ed218d11b7f0c36de5c56635b56dc3bce19a..8295d91d61fe79e2ec2306f4144ec7e4397a40d5 100644 (file)
@@ -40,13 +40,13 @@ ifcapable !fts3 {
 #         creating a content=xxx FTS index.
 #
 
-do_execsql_test 1.1 {
+do_execsql_test 1.1.1 {
   CREATE TABLE t1(a, b, c);
   INSERT INTO t1 VALUES('w x', 'x y', 'y z');
   CREATE VIRTUAL TABLE ft1 USING fts4(content=t1);
 }
 
-do_execsql_test 1.2 {
+do_execsql_test 1.1.2 {
   PRAGMA table_info(ft1);
 } {
   0 a {} 0 {} 0 
@@ -54,12 +54,23 @@ do_execsql_test 1.2 {
   2 c {} 0 {} 0
 }
 
-do_execsql_test 1.3 { SELECT *, rowid FROM ft1 } {{w x} {x y} {y z} 1}
-do_execsql_test 1.4 { SELECT a, c FROM ft1 WHERE rowid=1 } {{w x} {y z}}
+do_execsql_test 1.1.3 { SELECT *, rowid FROM ft1 } {{w x} {x y} {y z} 1}
+do_execsql_test 1.1.4 { SELECT a, c FROM ft1 WHERE rowid=1 } {{w x} {y z}}
 
-do_execsql_test 1.5 { INSERT INTO ft1(ft1) VALUES('rebuild') } {}
-do_execsql_test 1.6 { SELECT rowid FROM ft1 WHERE ft1 MATCH 'x' } {1}
-do_execsql_test 1.7 { SELECT rowid FROM ft1 WHERE ft1 MATCH 'a' } {}
+do_execsql_test 1.1.5 { INSERT INTO ft1(ft1) VALUES('rebuild') } {}
+do_execsql_test 1.1.6 { SELECT rowid FROM ft1 WHERE ft1 MATCH 'x' } {1}
+do_execsql_test 1.1.7 { SELECT rowid FROM ft1 WHERE ft1 MATCH 'a' } {}
+
+do_execsql_test 1.2.1 {
+  DROP TABLE ft1;
+  CREATE VIRTUAL TABLE ft1 USING fts4(content=t1, b);
+  PRAGMA table_info(ft1);
+} {
+  0 b {} 0 {} 0 
+}
+do_execsql_test 1.2.2 { 
+  SELECT *, rowid FROM ft1 
+} {{x y} 1}
 
 #-------------------------------------------------------------------------
 # The following block of tests - 2.* - test that a content=xxx FTS table
@@ -433,10 +444,10 @@ do_execsql_test 6.2.7 {
   CREATE TABLE t7(x);
 }
 do_catchsql_test 6.2.8 {
-  SELECT rowid FROM ft7 WHERE ft7 MATCH '"A A"';
+  SELECT * FROM ft7 WHERE ft7 MATCH '"A A"';
 } {1 {SQL logic error or missing database}}
 do_catchsql_test 6.2.9 {
-  SELECT rowid FROM ft7 WHERE ft7 MATCH '"A A"';
+  SELECT * FROM ft7 WHERE ft7 MATCH '"A A"';
 } {1 {SQL logic error or missing database}}
 
 db close
@@ -448,4 +459,20 @@ do_catchsql_test 6.2.11 {
   SELECT rowid, * FROM ft7 WHERE ft7 MATCH '"A A"';
 } {0 {2 {}}}
 
+#-------------------------------------------------------------------------
+# Test cases 7.*
+# 
+do_execsql_test 7.1.1 {
+  CREATE VIRTUAL TABLE ft8 USING fts4(content=nosuchtable, x);
+  INSERT INTO ft8(docid, x) VALUES(13, 'U O N X G');
+  INSERT INTO ft8(docid, x) VALUES(14, 'C J J U B');
+  INSERT INTO ft8(docid, x) VALUES(15, 'N J Y G X');
+  INSERT INTO ft8(docid, x) VALUES(16, 'R Y D O R');
+  INSERT INTO ft8(docid, x) VALUES(17, 'I Y T Q O');
+}
+
+do_execsql_test 7.1.2 {
+  SELECT docid FROM ft8 WHERE ft8 MATCH 'N';
+} {13 15}
+
 finish_test