};
/*
-** Variable pStmt is set to a compiled SQL statement of the form:
-**
+** pStmt:
** SELECT rowid, <fts> FROM <fts> ORDER BY +rank;
**
+** aIdx[]:
+** There is one entry in the aIdx[] array for each phrase in the query,
+** the value of which is the offset within aPoslist[] following the last
+** byte of the position list for the corresponding phrase.
*/
struct Fts5Sorter {
sqlite3_stmt *pStmt;
int aIdx[0]; /* Offsets into aPoslist for current row */
};
+
/*
** Virtual-table cursor object.
*/
const u8 *aBlob;
int nBlob;
int i;
+ int iOff = 0;
rc = SQLITE_OK;
pSorter->iRowid = sqlite3_column_int64(pSorter->pStmt, 0);
aBlob = a = sqlite3_column_blob(pSorter->pStmt, 1);
for(i=0; i<(pSorter->nIdx-1); i++){
- a += getVarint32(a, pSorter->aIdx[i]);
+ int iVal;
+ a += getVarint32(a, iVal);
+ iOff += iVal;
+ pSorter->aIdx[i] = iOff;
}
pSorter->aIdx[i] = &aBlob[nBlob] - a;
+
pSorter->aPoslist = a;
CsrFlagSet(pCsr, FTS5CSR_REQUIRE_CONTENT | FTS5CSR_REQUIRE_DOCSIZE );
}
pSorter = (Fts5Sorter*)sqlite3_malloc(nByte);
if( pSorter==0 ) return SQLITE_NOMEM;
memset(pSorter, 0, nByte);
+ pSorter->nIdx = nPhrase;
zSql = sqlite3_mprintf("SELECT rowid, %s FROM %Q.%Q ORDER BY +%s %s",
pConfig->zName, pConfig->zDb, pConfig->zName, FTS5_RANK_NAME,
}
static sqlite3_int64 fts5ApiRowid(Fts5Context *pCtx){
- Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
return fts5CursorRowid((Fts5Cursor*)pCtx);
}
const u8 *a; int n; /* Poslist for phrase iPhrase */
if( pCsr->pSorter ){
Fts5Sorter *pSorter = pCsr->pSorter;
- int i1 = (iPhrase ? 0 : pSorter->aIdx[iPhrase-1]);
+ int i1 = (iPhrase==0 ? 0 : pSorter->aIdx[iPhrase-1]);
n = pSorter->aIdx[iPhrase] - i1;
a = &pSorter->aPoslist[i1];
}else{
}
}
+/*
+** Return a "position-list blob" corresponding to the current position of
+** cursor pCsr via sqlite3_result_blob(). A position-list blob contains
+** the current position-list for each phrase in the query associated with
+** cursor pCsr.
+**
+** A position-list blob begins with (nPhrase-1) varints, where nPhrase is
+** the number of phrases in the query. Following the varints are the
+** concatenated position lists for each phrase, in order.
+**
+** The first varint (if it exists) contains the size of the position list
+** for phrase 0. The second (same disclaimer) contains the size of position
+** list 1. And so on. There is no size field for the final position list,
+** as it can be derived from the total size of the blob.
+*/
static int fts5PoslistBlob(sqlite3_context *pCtx, Fts5Cursor *pCsr){
int i;
int rc = SQLITE_OK;
int nPhrase = sqlite3Fts5ExprPhraseCount(pCsr->pExpr);
Fts5Buffer val;
- int iOff = 0;
memset(&val, 0, sizeof(Fts5Buffer));
- for(i=0; i<nPhrase; i++){
+
+ /* Append the varints */
+ for(i=0; i<(nPhrase-1); i++){
const u8 *dummy;
- if( i ) sqlite3Fts5BufferAppendVarint(&rc, &val, iOff);
- iOff += sqlite3Fts5ExprPoslist(pCsr->pExpr, i, &dummy);
+ int nByte = sqlite3Fts5ExprPoslist(pCsr->pExpr, i, &dummy);
+ sqlite3Fts5BufferAppendVarint(&rc, &val, nByte);
}
+ /* Append the position lists */
for(i=0; i<nPhrase; i++){
const u8 *pPoslist;
int nPoslist;
}
if( zReq==0 ){
- sqlite3Fts5BufferAppendPrintf(&rc, &s, "columncount ");
+ sqlite3Fts5BufferAppendPrintf(&rc, &s, " columncount ");
}
if( 0==zReq || 0==sqlite3_stricmp(zReq, "columncount") ){
sqlite3Fts5BufferAppendPrintf(&rc, &s, "%d", nCol);
}
if( zReq==0 ){
- sqlite3Fts5BufferAppendPrintf(&rc, &s, "columnsize ");
+ sqlite3Fts5BufferAppendPrintf(&rc, &s, " columnsize ");
}
if( 0==zReq || 0==sqlite3_stricmp(zReq, "columnsize") ){
if( zReq==0 && nCol>1 ) sqlite3Fts5BufferAppendPrintf(&rc, &s, "{");
}
if( zReq==0 ){
- sqlite3Fts5BufferAppendPrintf(&rc, &s, "columntext ");
+ sqlite3Fts5BufferAppendPrintf(&rc, &s, " columntext ");
}
if( 0==zReq || 0==sqlite3_stricmp(zReq, "columntext") ){
for(i=0; rc==SQLITE_OK && i<nCol; i++){
-C Fix\sthings\sso\sthat\sthe\sfts5\sextension\sAPI\sworks\swith\s"ORDER\sBY\srank"\squeries.
-D 2014-07-30T20:26:24.443
+C Add\sfurther\stests\sfor\sthe\sextension\sAPIs\swith\s"ORDER\sBY\srank"\squeries.
+D 2014-07-31T11:57:59.052
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in b03432313a3aad96c706f8164fb9f5307eaf19f5
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
F ext/fts3/unicode/CaseFolding.txt 8c678ca52ecc95e16bc7afc2dbf6fc9ffa05db8c
F ext/fts3/unicode/UnicodeData.txt cd07314edb62d49fde34debdaf92fa2aa69011e7
F ext/fts3/unicode/mkunicode.tcl dc6f268eb526710e2c6e496c372471d773d0c368
-F ext/fts5/fts5.c f322286c6a37dcea4b46b00677e9aad2e59abe9d
+F ext/fts5/fts5.c b54b776771d1e965bac02bffcf875a0bfc3660db
F ext/fts5/fts5.h 8ace10d5b249a3baa983c79e7a1306d2a79cfd6a
F ext/fts5/fts5Int.h 9a195c1706876c538902f007149b39e982e9da53
-F ext/fts5/fts5_aux.c 3cae4225d458af41b64bb40ed9dcc052eb41b9a0
+F ext/fts5/fts5_aux.c 366057c7186bc3615deb5ecc0ff61de50b6d2dbc
F ext/fts5/fts5_buffer.c 248c61ac9fec001602efc72a45704f3b8d367c00
F ext/fts5/fts5_config.c f4ebf143e141b8c77355e3b15aba81b7be51d710
F ext/fts5/fts5_expr.c e764d75c58a3accda795f1da1b45960ac87dc77a
F test/fts5ad.test 2ed38bbc865678cb2905247120d02ebba7f20e07
F test/fts5ae.test cb37b3135a00d3afd5492ec534ecf654be5ff69e
F test/fts5af.test 9ebe23aa3875896076952c7bc6e8308813a63c74
+F test/fts5ag.test 0747bf3bade16d5165810cf891f875933b28b420
F test/fts5ea.test ff43b40f8879ba50b82def70f2ab67c195d1a1d4
F test/full.test 6b3c8fb43c6beab6b95438c1675374b95fab245d
F test/func.test ae97561957aba6ca9e3a7b8a13aac41830d701ef
F test/pcache.test b09104b03160aca0d968d99e8cd2c5b1921a993d
F test/pcache2.test a83efe2dec0d392f814bfc998def1d1833942025
F test/percentile.test b98fc868d71eb5619d42a1702e9ab91718cbed54
-F test/permutations.test e6e951c816199693676d8c3d22d6bf54bcd719fc
+F test/permutations.test 5f1f942bae4139b33626b82627aa262c0f72d936
F test/pragma.test adb21a90875bc54a880fa939c4d7c46598905aa0
F test/pragma2.test aea7b3d82c76034a2df2b38a13745172ddc0bc13
F test/printf.test ec9870c4dce8686a37818e0bf1aba6e6a1863552
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
-P 4cc048c3651e830a6aeded924c7f3a60b634e133
-R e80b35a7b7fca0c8edda241edc415407
+P f1b4e1a98d49ecaba962beba16f8224175e4ba59
+R bf2807e3a776f0c27fe888a62861bcb4
U dan
-Z fdc04c3e2e7e600dae907e07830ae6e8
+Z 17018f27d9e25b34230168ffaec13df5
-f1b4e1a98d49ecaba962beba16f8224175e4ba59
\ No newline at end of file
+37a417d27e4ebafd4783f62728d7467316b75b17
\ No newline at end of file
--- /dev/null
+# 2014 June 17
+#
+# 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 SQLite library. The
+# focus of this script is testing the FTS5 module.
+#
+
+set testdir [file dirname $argv0]
+source $testdir/tester.tcl
+set testprefix fts5ag
+
+# If SQLITE_ENABLE_FTS3 is defined, omit this file.
+ifcapable !fts3 {
+ finish_test
+ return
+}
+
+#-------------------------------------------------------------------------
+# This file attempts to verify that the extension APIs work with
+# "ORDER BY rank" queries. This is done by comparing the results of
+# the fts5_test() function when run with queries of the form:
+#
+# ... WHERE fts MATCH ? ORDER BY bm25(fts) [ASC|DESC]
+#
+# and
+#
+# ... WHERE fts MATCH ? ORDER BY rank [ASC|DESC]
+#
+
+do_execsql_test 1.0 {
+ CREATE VIRTUAL TABLE t1 USING fts5(x, y, z);
+}
+
+do_test 1.1 {
+ foreach {x y z} {
+ {j s m y m r n l u k} {z k f u z g h s w g} {r n o s s b v n w w}
+ {m v g n d x q r r s} {q t d a q a v l h j} {s k l f s i n v q v}
+ {m f f d h h s o h a} {y e v r q i u m h d} {b c k q m z l z h n}
+ {j e m v k p e c j m} {m p v z d x l n i a} {v p u p m t p q i f}
+ {v r w l e e t d z p} {c s b w k m n k o u} {w g y f v w v w v p}
+ {k d g o u j p z n o} {t g e q l z i g b j} {f i q q j y h b g h}
+ {j s w x o t j b t m} {v a v v r t x c q a} {r t k x w u l h a g}
+ {j y b i u d e m d w} {y s o j h i n a u p} {n a g b u c w e b m}
+ {b c k s c w j p w b} {m o c o w o b d q q} {n t y o y z y r z e}
+ {p n q l e l h z q c} {n s e i h c v b b u} {m p d i t a o o f f}
+ {k c o n v e z l b m} {s m n i n s d e s u} {t a u e q d a o u c}
+ {h d t o i a g b b p} {k x c i g f g b b k} {x f i v n a n n j i}
+ {f z k r b u s k z e} {n z v z w l e r h t} {t i s v v a v p n s}
+ {k f e c t z r e f d} {f m g r c w q k b v} {v y s y f r b f e f}
+ {z r c t d q q h x b} {u c g z n z u v s s} {y t n f f x b f d x}
+ {u n p n u t i m e j} {p j j d m f k p m z} {d o l v c o e a h w}
+ {h o q w t f v i c y} {c q u n r z s l l q} {z x a q w s b w s y}
+ {y m s x k i m n x c} {b i a n v h z n k a} {w l q p b h h g d y}
+ {z v s j f p v l f w} {c s b i z e k i g c} {x b v d w j f e d z}
+ {r k k j e o m k g b} {h b d c h m y b t u} {u j s h k z c u d y}
+ {v h i v s y z i k l} {d t m w q w c a z p} {r s e s x v d w k b}
+ {u r e q j y h o o s} {x x z r x y t f j s} {k n h x i i u e c v}
+ {q l f d a p w l q o} {y z q w j o p b o v} {s u h z h f d f n l}
+ {q o e o x x l g q i} {j g m h q q w c d b} {o m d h w a g b f n}
+ {m x k t s s y l v a} {j x t c a u w b w g} {n f j b v x y p u t}
+ {u w k a q b u w k w} {a h j u o w f s k p} {j o f s h y t j h g}
+ {x v b l m t l m h l} {t p y i y i q b q a} {k o o z w a c h c f}
+ {j g c d k w b d t v} {a k v c m a v h v p} {i c a i j g h l j h}
+ {l m v l c z j b p b} {z p z f l n k i b a} {j v q k g i x g i b}
+ {m c i w u z m i s z} {i z r f n l q z k w} {x n b p b q r g i z}
+ {d g i o o x l f x d} {r t m f b n q y c b} {i u g k w x n m p o}
+ {t o s i q d z x d t} {v a k s q z j c o o} {z f n n r l y w v v}
+ {w k h d t l j g n n} {r z m v y b l n c u} {v b v s c l n k g v}
+ {m a g r a b u u n z} {u y l h v w v k b f} {x l p g i s j f x v}
+ {v s g x k z a k a r} {l t g v j q l k p l} {f h n a x t v s t y}
+ {z u v u x p s j y t} {g b q e e g l n w g} {e n p j i g j f u r}
+ {q z l t w o l m p e} {t s g h r p r o t z} {y b f a o n u m z g}
+ {d t w n y b o g f o} {d a j e r l g g s h} {d z e l w q l t h f}
+ {f l u w q v x j a h} {f n u l l d m h h w} {d x c c e r o d q j}
+ {b y f q s q f u l g} {u z w l f d b i a g} {m v q b g u o z e z}
+ {h z p t s e x i v m} {l h q m e o x x x j} {e e d n p r m g j f}
+ {k h s g o n s d a x} {u d t t s j o v h a} {z r b a e u v o e s}
+ {m b b g a f c p a t} {w c m j o d b l g e} {f p j p m o s y v j}
+ {c r n h d w c a b l} {s g e u s d n j b g} {b o n a x a b x y l}
+ {r h u x f c d z n o} {x y l g u m i i w d} {t f h b z v r s r g}
+ {t i o r b v g g p a} {d x l u q k m o s u} {j f h t u n z u k m}
+ {g j t y d c n j y g} {w e s k v c w i g t} {g a h r g v g h r o}
+ {e j l a q j g i n h} {d z k c u p n u p p} {t u e e v z v r r g}
+ {l j s g k j k h z l} {p v d a t x d e q u} {r l u z b m g k s j}
+ {i e y d u x d i n l} {p f z k m m w p u l} {z l p m r q w n d a}
+ } {
+ execsql { INSERT INTO t1 VALUES($x, $y, $z) }
+ }
+ set {} {}
+} {}
+
+proc do_fts5ag_test {tn E} {
+ set q1 {SELECT fts5_test(t1) FROM t1 WHERE t1 MATCH $E ORDER BY rank}
+ set q2 {SELECT fts5_test(t1) FROM t1 WHERE t1 MATCH $E ORDER BY bm25(t1)}
+
+ set res [execsql $q1]
+ set expected [execsql $q2]
+ uplevel [list do_test $tn.1 [list set {} $res] $expected]
+
+ append q1 " DESC"
+ append q2 " DESC"
+
+ set res [execsql $q1]
+ set expected [execsql $q2]
+ uplevel [list do_test $tn.2 [list set {} $res] $expected]
+}
+
+foreach {tn expr} {
+ 2.1 a
+ 2.2 b
+ 2.3 c
+ 2.4 d
+
+ 2.5 {"m m"}
+ 2.6 {e + s}
+
+ 3.0 {a AND b}
+ 3.1 {a OR b}
+ 3.2 {b OR c AND d}
+ 3.3 {NEAR(c d)}
+} {
+ do_fts5ag_test $tn $expr
+
+ if {[set_test_counter errors]} break
+}
+
+
+
+finish_test
+
All FTS5 tests.
} -files {
fts5aa.test fts5ab.test fts5ac.test fts5ad.test fts5ae.test fts5ea.test
- fts5af.test
+ fts5af.test fts5ag.test
}
test_suite "nofaultsim" -prefix "" -description {