modernc.org/cc@v1.0.1/v2/testdata/_sqlite/ext/fts5/test/fts5aux.test (about)

     1  # 2014 Dec 20
     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  # Tests focusing on the auxiliary function APIs.
    13  #
    14  
    15  source [file join [file dirname [info script]] fts5_common.tcl]
    16  set testprefix fts5aux
    17  
    18  # If SQLITE_ENABLE_FTS5 is defined, omit this file.
    19  ifcapable !fts5 {
    20    finish_test
    21    return
    22  }
    23  
    24  proc inst {cmd i} { 
    25    $cmd xInst $i
    26  }
    27  sqlite3_fts5_create_function db inst inst
    28  
    29  proc colsize {cmd i} { 
    30    $cmd xColumnSize $i
    31  }
    32  sqlite3_fts5_create_function db colsize colsize
    33  
    34  proc totalsize {cmd i} { 
    35    $cmd xColumnTotalSize $i
    36  }
    37  sqlite3_fts5_create_function db totalsize totalsize
    38  
    39  do_execsql_test 1.0 {
    40    CREATE VIRTUAL TABLE f1 USING fts5(a, b);
    41    INSERT INTO f1 VALUES('one two', 'two one zero');
    42    INSERT INTO f1 VALUES('one one', 'one one one');
    43  }
    44  
    45  do_catchsql_test 1.1 {
    46    SELECT inst(f1, -1) FROM f1 WHERE f1 MATCH 'two';
    47  } {1 SQLITE_RANGE}
    48  do_catchsql_test 1.2 {
    49    SELECT inst(f1, 0) FROM f1 WHERE f1 MATCH 'two';
    50  } {0 {{0 0 1}}}
    51  do_catchsql_test 1.3 {
    52    SELECT inst(f1, 1) FROM f1 WHERE f1 MATCH 'two';
    53  } {0 {{0 1 0}}}
    54  do_catchsql_test 1.4 {
    55    SELECT inst(f1, 2) FROM f1 WHERE f1 MATCH 'two';
    56  } {1 SQLITE_RANGE}
    57  
    58  do_catchsql_test 2.1 {
    59    SELECT colsize(f1, 2) FROM f1 WHERE f1 MATCH 'two';
    60  } {1 SQLITE_RANGE}
    61  do_execsql_test 2.2 {
    62    SELECT colsize(f1, 0), colsize(f1, 1) FROM f1 WHERE f1 MATCH 'zero';
    63  } {2 3}
    64  do_execsql_test 2.3 {
    65    SELECT colsize(f1, -1) FROM f1 WHERE f1 MATCH 'zero';
    66  } {5}
    67  
    68  do_execsql_test 2.4.1 {
    69    SELECT totalsize(f1, -1) FROM f1 WHERE f1 MATCH 'zero';
    70  } {10}
    71  do_execsql_test 2.4.2 {
    72    SELECT totalsize(f1, 0) FROM f1 WHERE f1 MATCH 'zero';
    73  } {4}
    74  do_execsql_test 2.4.3 {
    75    SELECT totalsize(f1, 1) FROM f1 WHERE f1 MATCH 'zero';
    76  } {6}
    77  do_catchsql_test 2.4.4 {
    78    SELECT totalsize(f1, 2) FROM f1 WHERE f1 MATCH 'zero';
    79  } {1 SQLITE_RANGE}
    80  
    81  #-------------------------------------------------------------------------
    82  # Test the xSet and xGetAuxdata APIs with a NULL destructor.
    83  #
    84  proc prevrowid {add cmd} {
    85    set res [$cmd xGetAuxdataInt 0]
    86    set r [$cmd xRowid]
    87    $cmd xSetAuxdataInt $r
    88    return [expr $res + $add]
    89  }
    90  sqlite3_fts5_create_function db prevrowid  [list prevrowid 0]
    91  sqlite3_fts5_create_function db prevrowid1 [list prevrowid 1]
    92  
    93  do_execsql_test 3.0 {
    94    CREATE VIRTUAL TABLE e5 USING fts5(x);
    95    INSERT INTO e5 VALUES('a b c');
    96    INSERT INTO e5 VALUES('d e f');
    97    INSERT INTO e5 VALUES('a b c');
    98    INSERT INTO e5 VALUES('d e f');
    99    INSERT INTO e5 VALUES('a b c');
   100  }
   101  
   102  do_execsql_test 3.1 {
   103    SELECT prevrowid(e5) || '+' || rowid FROM e5 WHERE e5 MATCH 'c'
   104  } {0+1   1+3   3+5}
   105  
   106  do_execsql_test 3.2 {
   107    SELECT prevrowid(e5) || '+' || prevrowid1(e5) || '+' || rowid 
   108    FROM e5 WHERE e5 MATCH 'e'
   109  } {0+1+2    2+3+4}
   110  
   111  #-------------------------------------------------------------------------
   112  # Test that if the xQueryPhrase callback returns other than SQLITE_OK,
   113  # the query is abandoned. And that if it returns an error code other than 
   114  # SQLITE_DONE, the error is propagated back to the caller.
   115  #
   116  do_execsql_test 4.0 {
   117    CREATE VIRTUAL TABLE e7 USING fts5(x);
   118    INSERT INTO e7 VALUES('a x a');
   119    INSERT INTO e7 VALUES('b x b');
   120    INSERT INTO e7 VALUES('c x c');
   121    INSERT INTO e7 VALUES('d x d');
   122    INSERT INTO e7 VALUES('e x e');
   123  }
   124  
   125  proc xCallback {rowid code cmd} {
   126    set r [$cmd xRowid]
   127    lappend ::cb $r
   128    if {$r==$rowid} { return $code }
   129    return ""
   130  }
   131  
   132  proc phrasequery {cmd code} {
   133    set ::cb [list]
   134    $cmd xQueryPhrase 1 [list xCallback [$cmd xRowid] $code]
   135    set ::cb
   136  }
   137  
   138  sqlite3_fts5_create_function db phrasequery phrasequery
   139  
   140  do_execsql_test 4.1 {
   141    SELECT phrasequery(e7, 'SQLITE_OK') FROM e7 WHERE e7 MATCH 'c x'
   142  } {{1 2 3 4 5}}
   143  
   144  do_execsql_test 4.2 {
   145    SELECT phrasequery(e7, 'SQLITE_DONE') FROM e7 WHERE e7 MATCH 'c x'
   146  } {{1 2 3}}
   147  
   148  do_catchsql_test 4.3 {
   149    SELECT phrasequery(e7, 'SQLITE_ERROR') FROM e7 WHERE e7 MATCH 'c x'
   150  } {1 SQLITE_ERROR}
   151  
   152  #-------------------------------------------------------------------------
   153  # Auxiliary function calls with many cursors in the global cursor list.
   154  #
   155  do_execsql_test 5.0 {
   156    CREATE VIRTUAL TABLE e9 USING fts5(y);
   157    INSERT INTO e9(rowid, y) VALUES(1, 'i iii');
   158    INSERT INTO e9(rowid, y) VALUES(2, 'ii iv');
   159    INSERT INTO e9(rowid, y) VALUES(3, 'ii');
   160    INSERT INTO e9(rowid, y) VALUES(4, 'i iv');
   161    INSERT INTO e9(rowid, y) VALUES(5, 'iii');
   162  }
   163  
   164  proc my_rowid {cmd} { $cmd xRowid }
   165  sqlite3_fts5_create_function db my_rowid my_rowid
   166  
   167  foreach {var q} {
   168    s1 i
   169    s2 ii
   170    s3 iii
   171    s4 iv
   172  } {
   173    set sql "SELECT my_rowid(e9) FROM e9 WHERE e9 MATCH '$q'"
   174    set $var [sqlite3_prepare db $sql -1 dummy]
   175  }
   176  
   177  do_test 5.1.1 { sqlite3_step $s1 ; sqlite3_column_int $s1 0 } 1
   178  do_test 5.1.2 { sqlite3_step $s2 ; sqlite3_column_int $s2 0 } 2
   179  do_test 5.1.3 { sqlite3_step $s3 ; sqlite3_column_int $s3 0 } 1
   180  do_test 5.1.4 { sqlite3_step $s4 ; sqlite3_column_int $s4 0 } 2
   181  
   182  do_test 5.2.1 { sqlite3_step $s1 ; sqlite3_column_int $s1 0 } 4
   183  do_test 5.2.2 { sqlite3_step $s2 ; sqlite3_column_int $s2 0 } 3
   184  do_test 5.2.3 { sqlite3_step $s3 ; sqlite3_column_int $s3 0 } 5
   185  do_test 5.2.4 { sqlite3_step $s4 ; sqlite3_column_int $s4 0 } 4
   186  
   187  sqlite3_finalize $s1
   188  sqlite3_finalize $s2
   189  sqlite3_finalize $s3
   190  sqlite3_finalize $s4
   191  
   192  #-------------------------------------------------------------------------
   193  # Passing an invalid first argument to an auxiliary function is detected.
   194  #
   195  do_execsql_test 6.0 {
   196    CREATE VIRTUAL TABLE e11 USING fts5(y, z);
   197    INSERT INTO e11(rowid, y, z) VALUES(1, 'a b', 45);
   198    INSERT INTO e11(rowid, y, z) VALUES(2, 'b c', 46);
   199  }
   200  
   201  do_catchsql_test 6.1 {
   202    SELECT my_rowid(z) FROM e11 WHERE e11 MATCH 'b'
   203  } {1 {no such cursor: 45}}
   204  
   205  do_catchsql_test 6.2 {
   206    SELECT my_rowid(y) FROM e11 WHERE e11 MATCH 'b'
   207  } {1 {no such cursor: 0}}
   208  
   209  #-------------------------------------------------------------------------
   210  # Test passing an out-of-range phrase number to xPhraseSize (should 
   211  # return 0).
   212  #
   213  proc my_phrasesize {cmd iPhrase} { $cmd xPhraseSize $iPhrase }
   214  sqlite3_fts5_create_function db my_phrasesize my_phrasesize
   215  
   216  do_execsql_test 7.1 {
   217    CREATE VIRTUAL TABLE t1 USING fts5(a);
   218    INSERT INTO t1 VALUES('a b c');
   219  }
   220  do_execsql_test 7.2 {
   221    SELECT 
   222      my_phrasesize(t1, -1),
   223      my_phrasesize(t1, 0),
   224      my_phrasesize(t1, 1),
   225      my_phrasesize(t1, 2)
   226    FROM t1 WHERE t1 MATCH 'a OR b+c'
   227  } {0 1 2 0}
   228  
   229  #-------------------------------------------------------------------------
   230  #
   231  do_execsql_test 8.0 {
   232    CREATE VIRTUAL TABLE x1 USING fts5(a);
   233  }
   234  
   235  foreach {tn lRow res} {
   236    4  {"a a a" "b" "a d"} {"[a] [a] [a]" "[a] d"}
   237    1  {"b d" "a b"}       {"[b] [d]" "[a] b"}
   238    2  {"d b" "a d"}       {"[d] [b]" "[a] d"}
   239    3  {"a a d"}           {"[a] [a] d"}
   240  } {
   241    execsql { DELETE FROM x1 }
   242    foreach row $lRow { execsql { INSERT INTO x1 VALUES($row) } }
   243    do_execsql_test 8.$tn {
   244      SELECT highlight(x1, 0, '[', ']') FROM x1 WHERE x1 MATCH 'a OR (b AND d)';
   245    } $res
   246  }
   247  
   248  #-------------------------------------------------------------------------
   249  # Test the built-in bm25() demo.
   250  #
   251  reset_db
   252  do_execsql_test 9.1 {
   253    CREATE VIRTUAL TABLE t1 USING fts5(a, b);
   254    INSERT INTO t1 VALUES('a',   NULL);           -- 1
   255    INSERT INTO t1 VALUES('a',   NULL);           -- 2
   256    INSERT INTO t1 VALUES('a',   NULL);           -- 3
   257    INSERT INTO t1 VALUES('a',   NULL);           -- 4
   258    INSERT INTO t1 VALUES('a',   NULL);           -- 5
   259    INSERT INTO t1 VALUES('a',   NULL);           -- 6
   260    INSERT INTO t1 VALUES('a',   NULL);           -- 7
   261    INSERT INTO t1 VALUES('a',   NULL);           -- 8
   262    INSERT INTO t1 VALUES(NULL,  'a a b');        -- 9
   263    INSERT INTO t1 VALUES(NULL,  'b b a');        -- 10
   264  }
   265  
   266  do_execsql_test 9.2 {
   267    SELECT rowid FROM t1('a AND b') ORDER BY rank;
   268  } {
   269    10 9
   270  }
   271  
   272  do_execsql_test 9.3 {
   273    SELECT rowid FROM t1('b:a AND b:b') ORDER BY rank;
   274  } {
   275    9 10
   276  }
   277  
   278  
   279  
   280  finish_test