modernc.org/cc@v1.0.1/v2/testdata/_sqlite/test/fts4opt.test (about)

     1  # 2016 March 8
     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  
    13  set testdir [file dirname $argv0]
    14  source $testdir/tester.tcl
    15  source $testdir/fts3_common.tcl
    16  set ::testprefix fts4opt
    17  
    18  # If SQLITE_ENABLE_FTS3 is defined, omit this file.
    19  ifcapable !fts3 {
    20    finish_test
    21    return
    22  }
    23  
    24  # Create the fts_kjv_genesis procedure which fills and FTS3/4 table 
    25  # with the complete text of the Book of Genesis.
    26  #
    27  source $testdir/genesis.tcl
    28  
    29  do_execsql_test 1.0 { CREATE TABLE t1(docid, words) }
    30  fts_kjv_genesis
    31  
    32  #-------------------------------------------------------------------------
    33  # Argument $db is an open database handle. $tbl is the name of an FTS3/4
    34  # table with the database. This command rearranges the contents of the
    35  # %_segdir table so that all segments within each index are on the same
    36  # level. This means that the 'merge' command can then be used for an
    37  # incremental optimize routine.
    38  #
    39  proc prepare_for_optimize {db tbl} {
    40    $db eval [string map [list % $tbl] {
    41      BEGIN;
    42        CREATE TEMP TABLE tmp_segdir(
    43          level, idx, start_block, leaves_end_block, end_block, root
    44        );
    45  
    46        INSERT INTO temp.tmp_segdir 
    47          SELECT 
    48          1024*(o.level / 1024) + 32,                                -- level
    49          sum(o.level<i.level OR (o.level=i.level AND o.idx>i.idx)), -- idx
    50          o.start_block, o.leaves_end_block, o.end_block, o.root     -- other
    51          FROM %_segdir o, %_segdir i 
    52          WHERE (o.level / 1024) = (i.level / 1024)
    53          GROUP BY o.level, o.idx;
    54    
    55        DELETE FROM %_segdir;
    56        INSERT INTO %_segdir SELECT * FROM temp.tmp_segdir;
    57        DROP TABLE temp.tmp_segdir;
    58    
    59      COMMIT;
    60    }]
    61  }
    62  
    63  do_test 1.1 {
    64    execsql { CREATE VIRTUAL TABLE t2 USING fts4(words, prefix="1,2,3") }
    65    foreach {docid words} [db eval { SELECT * FROM t1 }] {
    66      execsql { INSERT INTO t2(docid, words) VALUES($docid, $words) }
    67    }
    68  } {}
    69  
    70  do_execsql_test 1.2 {
    71    SELECT level, count(*) FROM t2_segdir GROUP BY level
    72  } {
    73    0    13    1 15    2 5 
    74    1024 13 1025 15 1026 5 
    75    2048 13 2049 15 2050 5 
    76    3072 13 3073 15 3074 5
    77  }
    78  
    79  do_execsql_test 1.3 { INSERT INTO t2(t2) VALUES('integrity-check') }
    80  prepare_for_optimize db t2
    81  do_execsql_test 1.4 { INSERT INTO t2(t2) VALUES('integrity-check') }
    82  
    83  do_execsql_test 1.5 {
    84    SELECT level, count(*) FROM t2_segdir GROUP BY level
    85  } {
    86    32   33 
    87    1056 33 
    88    2080 33 
    89    3104 33
    90  }
    91  
    92  do_test 1.6 {
    93    while 1 {
    94      set tc1 [db total_changes]
    95      execsql { INSERT INTO t2(t2) VALUES('merge=5,2') }
    96      set tc2 [db total_changes]
    97      if {($tc2 - $tc1) < 2} break
    98    }
    99    execsql { SELECT level, count(*) FROM t2_segdir GROUP BY level }
   100  } {33 1 1057 1 2081 1 3105 1}
   101  do_execsql_test 1.7 { INSERT INTO t2(t2) VALUES('integrity-check') }
   102  
   103  do_execsql_test 1.8 {
   104    INSERT INTO t2(words) SELECT words FROM t1;
   105    SELECT level, count(*) FROM t2_segdir GROUP BY level;
   106  } {0 2 1024 2 2048 2 3072 2}
   107  
   108  #-------------------------------------------------------------------------
   109  
   110  do_execsql_test 2.0 {
   111    DELETE FROM t2;
   112  }
   113  do_test 2.1 {
   114    foreach {docid words} [db eval { SELECT * FROM t1 }] {
   115      execsql { INSERT INTO t2(docid, words) VALUES($docid, $words) }
   116    }
   117  
   118    set i 0
   119    foreach {docid words} [db eval { SELECT * FROM t1 }] {
   120      if {[incr i] % 2} { execsql { DELETE FROM t2 WHERE docid = $docid } }
   121    }
   122  
   123    set i 0
   124    foreach {docid words} [db eval { SELECT * FROM t1 }] {
   125      if {[incr i] % 3} {
   126        execsql { INSERT OR REPLACE INTO t2(docid, words) VALUES($docid, $words) }
   127      }
   128    }
   129  } {}
   130  
   131  do_execsql_test 2.2 {
   132    SELECT level, count(*) FROM t2_segdir GROUP BY level
   133  } {
   134    0    10    1 15    2 12 
   135    1024 10 1025 15 1026 12 
   136    2048 10 2049 15 2050 12 
   137    3072 10 3073 15 3074 12
   138  }
   139  
   140  do_execsql_test 2.3 { INSERT INTO t2(t2) VALUES('integrity-check') }
   141  prepare_for_optimize db t2
   142  do_execsql_test 2.4 { INSERT INTO t2(t2) VALUES('integrity-check') }
   143  
   144  do_execsql_test 2.5 {
   145    SELECT level, count(*) FROM t2_segdir GROUP BY level
   146  } {
   147      32 37 
   148    1056 37 
   149    2080 37 
   150    3104 37
   151  }
   152  
   153  do_test 2.6 {
   154    while 1 {
   155      set tc1 [db total_changes]
   156      execsql { INSERT INTO t2(t2) VALUES('merge=5,2') }
   157      set tc2 [db total_changes]
   158      if {($tc2 - $tc1) < 2} break
   159    }
   160    execsql { SELECT level, count(*) FROM t2_segdir GROUP BY level }
   161  } {33 1 1057 1 2081 1 3105 1}
   162  do_execsql_test 2.7 { INSERT INTO t2(t2) VALUES('integrity-check') }
   163  
   164  do_execsql_test 2.8 {
   165    INSERT INTO t2(words) SELECT words FROM t1;
   166    SELECT level, count(*) FROM t2_segdir GROUP BY level;
   167  } {0 2 1024 2 2048 2 3072 2}
   168  
   169  #-------------------------------------------------------------------------
   170  # Check that 'optimize' works when there is data in the in-memory hash
   171  # table, but no segments at all on disk.
   172  #
   173  do_execsql_test 3.1 {
   174    CREATE VIRTUAL TABLE fts USING fts4 (t);
   175    INSERT INTO fts (fts) VALUES ('optimize');
   176  }
   177  do_execsql_test 3.2 {
   178    INSERT INTO fts(fts) VALUES('integrity-check');
   179    SELECT count(*) FROM fts_segdir;
   180  } {0}
   181  do_execsql_test 3.3 {
   182    BEGIN;
   183    INSERT INTO fts (rowid, t) VALUES (2, 'test');
   184    INSERT INTO fts (fts) VALUES ('optimize');
   185    COMMIT;
   186    SELECT level, idx FROM fts_segdir;
   187  } {0 0}
   188  do_execsql_test 3.4 {
   189    INSERT INTO fts(fts) VALUES('integrity-check');
   190    SELECT rowid FROM fts WHERE fts MATCH 'test';
   191  } {2}
   192  do_execsql_test 3.5 {
   193    INSERT INTO fts (fts) VALUES ('optimize');
   194    INSERT INTO fts(fts) VALUES('integrity-check');
   195  }
   196  do_test 3.6 {
   197    set c1 [db total_changes]
   198    execsql { INSERT INTO fts (fts) VALUES ('optimize') }
   199    expr {[db total_changes] - $c1}
   200  } {1}
   201  do_test 3.7 {
   202    execsql { INSERT INTO fts (rowid, t) VALUES (3, 'xyz') }
   203    set c1 [db total_changes]
   204    execsql { INSERT INTO fts (fts) VALUES ('optimize') }
   205    expr {([db total_changes] - $c1) > 1}
   206  } {1}
   207  do_test 3.8 {
   208    set c1 [db total_changes]
   209    execsql { INSERT INTO fts (fts) VALUES ('optimize') }
   210    expr {[db total_changes] - $c1}
   211  } {1}
   212  
   213  finish_test