SQLite

Check-in [febf75f022]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Implement xRename() for fts1 so that it is possible to rename fts1 tables. See http://www.sqlite.org/cvstrac/chngview?cn=4143 (CVS 4184)
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: febf75f022b9414fc456ddf274d301f95d61e1b8
User & Date: shess 2007-07-25 00:56:10.000
Context
2007-07-26
06:50
Fix two obscure memory leaks that can follow a malloc() failure in sqlite3_set_auxdata(). Ticket #2534. (CVS 4185) (check-in: b88af1827b user: danielk1977 tags: trunk)
2007-07-25
00:56
Implement xRename() for fts1 so that it is possible to rename fts1 tables. See http://www.sqlite.org/cvstrac/chngview?cn=4143 (CVS 4184) (check-in: febf75f022 user: shess tags: trunk)
00:38
Replicates http://www.sqlite.org/cvstrac/chngview?cn=4151 which modified fts2:

Modify handling of SQLITE_SCHEMA in fts2 code. An SQLITE_SCHEMA error may cause SQLite to reload the internal schema, deleting and recreating v-table objects. So the sqlite3_vtab structure can be deleted out from under a v-table implementation. (CVS 4183) (check-in: f9020cffda user: shess tags: trunk)

Changes
Unified Diff Ignore Whitespace Patch
Changes to ext/fts1/fts1.c.
3257
3258
3259
3260
3261
3262
3263






















3264
3265
3266
3267
3268
3269
3270
    return 1;
  }else if( strcmp(zName,"offsets")==0 ){
    *pxFunc = snippetOffsetsFunc;
    return 1;
  }
  return 0;
}























static const sqlite3_module fulltextModule = {
  /* iVersion      */ 0,
  /* xCreate       */ fulltextCreate,
  /* xConnect      */ fulltextConnect,
  /* xBestIndex    */ fulltextBestIndex,
  /* xDisconnect   */ fulltextDisconnect,







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
    return 1;
  }else if( strcmp(zName,"offsets")==0 ){
    *pxFunc = snippetOffsetsFunc;
    return 1;
  }
  return 0;
}

/*
** Rename an fts1 table.
*/
static int fulltextRename(
  sqlite3_vtab *pVtab,
  const char *zName
){
  fulltext_vtab *p = (fulltext_vtab *)pVtab;
  int rc = SQLITE_NOMEM;
  char *zSql = sqlite3_mprintf(
    "ALTER TABLE %Q.'%q_content'  RENAME TO '%q_content';"
    "ALTER TABLE %Q.'%q_term' RENAME TO '%q_term';"
    , p->zDb, p->zName, zName
    , p->zDb, p->zName, zName
  );
  if( zSql ){
    rc = sqlite3_exec(p->db, zSql, 0, 0, 0);
    sqlite3_free(zSql);
  }
  return rc;
}

static const sqlite3_module fulltextModule = {
  /* iVersion      */ 0,
  /* xCreate       */ fulltextCreate,
  /* xConnect      */ fulltextConnect,
  /* xBestIndex    */ fulltextBestIndex,
  /* xDisconnect   */ fulltextDisconnect,
3278
3279
3280
3281
3282
3283
3284

3285
3286
3287
3288
3289
3290
3291
  /* xRowid        */ fulltextRowid,
  /* xUpdate       */ fulltextUpdate,
  /* xBegin        */ 0, 
  /* xSync         */ 0,
  /* xCommit       */ 0,
  /* xRollback     */ 0,
  /* xFindFunction */ fulltextFindFunction,

};

int sqlite3Fts1Init(sqlite3 *db){
  sqlite3_overload_function(db, "snippet", -1);
  sqlite3_overload_function(db, "offsets", -1);
  return sqlite3_create_module(db, "fts1", &fulltextModule, 0);
}







>







3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
  /* xRowid        */ fulltextRowid,
  /* xUpdate       */ fulltextUpdate,
  /* xBegin        */ 0, 
  /* xSync         */ 0,
  /* xCommit       */ 0,
  /* xRollback     */ 0,
  /* xFindFunction */ fulltextFindFunction,
  /* xRename       */ fulltextRename,
};

int sqlite3Fts1Init(sqlite3 *db){
  sqlite3_overload_function(db, "snippet", -1);
  sqlite3_overload_function(db, "offsets", -1);
  return sqlite3_create_module(db, "fts1", &fulltextModule, 0);
}
Added test/fts1o.test.












































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# 2007 July 24
#
# 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 FTS1 module rename functionality.  Mostly
# copied from fts2o.test.
#
# $Id: fts1o.test,v 1.1 2007/07/25 00:56:10 shess Exp $
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# If SQLITE_ENABLE_FTS1 is not defined, omit this file.
ifcapable !fts1 {
  finish_test
  return
}

db eval {
  CREATE VIRTUAL TABLE t1 USING fts2(a, b, c);
  INSERT INTO t1(a, b, c) VALUES('one three four', 'one four', 'one four two');
}

#---------------------------------------------------------------------
# Test that it is possible to rename an fts1 table.
#
do_test fts1o-1.1 {
  execsql { SELECT tbl_name FROM sqlite_master WHERE type = 'table'}
} {t1 t1_content t1_segments t1_segdir}
do_test fts1o-1.2 {
  execsql { ALTER TABLE t1 RENAME to fts_t1; }
} {}
do_test fts1o-1.3 {
  execsql { SELECT rowid, snippet(fts_t1) FROM fts_t1 WHERE a MATCH 'four'; }
} {1 {one three <b>four</b>}}
do_test fts1o-1.4 {
  execsql { SELECT tbl_name FROM sqlite_master WHERE type = 'table'}
} {fts_t1 fts_t1_content fts_t1_segments fts_t1_segdir}

# See what happens when renaming the fts1 table fails.
#
do_test fts1o-2.1 {
  catchsql {
    CREATE TABLE t1_segdir(a, b, c);
    ALTER TABLE fts_t1 RENAME to t1;
  }
} {1 {SQL logic error or missing database}}
do_test fts1o-2.2 {
  execsql { SELECT rowid, snippet(fts_t1) FROM fts_t1 WHERE a MATCH 'four'; }
} {1 {one three <b>four</b>}}
do_test fts1o-2.3 {
  execsql { SELECT tbl_name FROM sqlite_master WHERE type = 'table'}
} {fts_t1 fts_t1_content fts_t1_segments fts_t1_segdir t1_segdir}

# See what happens when renaming the fts1 table fails inside a transaction.
#
do_test fts1o-3.1 {
  execsql {
    BEGIN;
    INSERT INTO fts_t1(a, b, c) VALUES('one two three', 'one four', 'one two');
  }
} {}
do_test fts1o-3.2 {
  catchsql {
    ALTER TABLE fts_t1 RENAME to t1;
  }
} {1 {SQL logic error or missing database}}
do_test fts1o-3.3 {
  execsql { SELECT rowid, snippet(fts_t1) FROM fts_t1 WHERE a MATCH 'four'; }
} {1 {one three <b>four</b>}}
do_test fts1o-3.4 {
  execsql { SELECT tbl_name FROM sqlite_master WHERE type = 'table'}
} {fts_t1 fts_t1_content fts_t1_segments fts_t1_segdir t1_segdir}
do_test fts1o-3.5 {
  execsql COMMIT
  execsql {SELECT a FROM fts_t1}
} {{one three four} {one two three}}
do_test fts1o-3.6 {
  execsql { SELECT a, b, c FROM fts_t1 WHERE c MATCH 'four'; }
} {{one three four} {one four} {one four two}}

#---------------------------------------------------------------------
# Test that it is possible to rename an fts1 table in an attached 
# database.
#
file delete -force test2.db test2.db-journal

do_test fts1o-4.1 {
  execsql {
    DROP TABLE t1_segdir;
    ALTER TABLE fts_t1 RENAME to t1;
    SELECT a, b, c FROM t1 WHERE c MATCH 'two';
  }
} {{one three four} {one four} {one four two} {one two three} {one four} {one two}}

do_test fts1o-4.2 {
  execsql {
    ATTACH 'test2.db' AS aux;
    CREATE VIRTUAL TABLE aux.t1 USING fts1(a, b, c);
    INSERT INTO aux.t1(a, b, c) VALUES(
      'neung song sahm', 'neung see', 'neung see song'
    );
  }
} {}

do_test fts1o-4.3 {
  execsql { SELECT a, b, c FROM aux.t1 WHERE a MATCH 'song'; }
} {{neung song sahm} {neung see} {neung see song}}

do_test fts1o-4.4 {
  execsql { SELECT a, b, c FROM t1 WHERE c MATCH 'two'; }
} {{one three four} {one four} {one four two} {one two three} {one four} {one two}}

do_test fts1o-4.5 {
  execsql { ALTER TABLE aux.t1 RENAME TO t2 }
} {}

do_test fts1o-4.6 {
  execsql { SELECT a, b, c FROM t2 WHERE a MATCH 'song'; }
} {{neung song sahm} {neung see} {neung see song}}

do_test fts1o-4.7 {
  execsql { SELECT a, b, c FROM t1 WHERE c MATCH 'two'; }
} {{one three four} {one four} {one four two} {one two three} {one four} {one two}}

finish_test