Documentation Source Text

Check-in [b22f668cca]
Login

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

Overview
Comment:Work-in-progress: refactoring the documentation on integer result codes.
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: b22f668cca900d76544c2c609c9837d85bedf6b2
User & Date: drh 2014-08-08 12:50:18
Context
2014-08-08
17:05
First complete draft of the "rescode.html" document. check-in: e5ea14f1ff user: drh tags: trunk
12:50
Work-in-progress: refactoring the documentation on integer result codes. check-in: b22f668cca user: drh tags: trunk
2014-08-07
13:22
General documentation updates. Attempts to provide better links and improve wording for better readability. check-in: 430bf0b418 user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to pages/docs.in.

83
84
85
86
87
88
89




90
91
92
93
94
95
96
doc {How To Compile SQLite} {howtocompile.html} {
  Instructions and hints for compiling SQLite C code and integrating
  that code with your own application.
}
doc {C/C++ API Reference} {c3ref/intro.html} {
  This document describes each API function separately.
}




doc {Tcl API} {tclsqlite.html} {
  A description of the TCL interface bindings for SQLite.
}
doc {SQL Syntax} {lang.html} {
  This document describes the SQL language that is understood by
  SQLite.  
}







>
>
>
>







83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
doc {How To Compile SQLite} {howtocompile.html} {
  Instructions and hints for compiling SQLite C code and integrating
  that code with your own application.
}
doc {C/C++ API Reference} {c3ref/intro.html} {
  This document describes each API function separately.
}
doc {Result Codes} {errors.html} {
  A description of the meanings of the numeric result codes
  returned by various C/C++ interfaces.
}
doc {Tcl API} {tclsqlite.html} {
  A description of the TCL interface bindings for SQLite.
}
doc {SQL Syntax} {lang.html} {
  This document describes the SQL language that is understood by
  SQLite.  
}

Added pages/rescode.in.



















































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
<title>SQLite Result Codes</title>
<tcl>hd_keywords {result code} {result codes} {error code} {error codes}</tcl>
<h1 align="center">SQLite Result Codes</h1>

<p>
Many of the routines in the SQLite [C-language Interface] return
numeric result codes indicating either success or failure, and 
in the event of a failure, providing some idea of the cause of
the failure.  This document strives to explain what each
of those numeric result codes means.

<h2>Result Codes versus Error Codes</h2>

<p>
"Error codes" are a subset of "result codes" that indicate that
something has gone wrong.  There are only a few non-error result
codes:  [SQLITE_OK], [SQLITE_ROW], and [SQLITE_DONE].  The term
"error code" means any result code other than these three.

<tcl>hd_fragment pve {primary versus extended result codes}</tcl>
<h2>Primary Result Codes versus Extended Result Codes</h2>

<p>
Result codes are signed 32-bit integers.
The least significant 8 bits of the result code define a broad category
and are called the "primary result code".  More significant bits provide
more detailed information about the error and are called the
"extended result code"

<p>
Note that the primary result code is always a part of the extended
result code.  Given a full 32-bit extended result code, the application
can always find the corresponding primary result code merely by extracting
the least significant 8 bits of the extended result code.

<p>
All extended result codes are also error codes.  Hence the terms
"extended result code" and "extended error code" are interchangeable.

<p>
For historic compatibility, the C-language interfaces return
primary result codes by default.  
The extended result code for the most recent error can be
retrieved using the [sqlite3_extended_errcode()] interface.
The [sqlite3_extended_result_codes()] interface can be used to put
a [database connection] into a mode where it returns the
extended result codes instead of the primary result codes.

<h2>Definitions</h2>

<p>
All result codes are integers.
Symbolic names for all result codes are created using
"#define" macros in the sqlite3.h header file.
There are separate sections in the sqlite3.h header file for
the [result code definitions] and the [extended result code definitions].

<p>
Primary result code symbolic names are of the form "SQLITE_XXXXXX" where
XXXXXX is a sequence of uppercase alphabetic characters.  Extended
result code names are of the form "SQLITE_XXXXXX_YYYYYYY" where
the XXXXXX part is the corresponding primary result code and the
YYYYYYY is an extension that further classifies the result code.

<p>
The names and numeric values for existing result codes are fixed
and unchanging.  However, new result codes, and especially new extended
result codes, might appear in future releases of SQLite.

<tcl>
unset -nocomplain resdesc
unset -nocomplain resvalue
proc RESCODE {name value desc} {
  set ::resdesc($name) $desc
  set ::resvalue($name) $value
}

RESCODE SQLITE_OK 0 {
  The SQLITE_OK result code means that the operation was successful and
  that there were no errors.  Most other result codes indicate an error.
}
RESCODE SQLITE_ERROR 1 {
  The SQLITE_ERROR result code is a generic error code that is used when
  no other more specific error code is available.
}
RESCODE SQLITE_INTERNAL     2  {
  The SQLITE_INTERNAL result code indicates an internal malfunction.
  In a working version of SQLite, an application should never see this
  result code.  If application does encounter this result code, it shows
  that there is a bug in the database engine.
  <p>
  Actually, SQLite does not currently generate this result code under
  any circumstances.  However, [application-defined SQL functions] or
  [virtual tables], or [VFSes], or other extensions might cause this 
  result code to be returned.
}
RESCODE SQLITE_PERM         3  {
  The SQLITE_PERM result code indicates a file-system permissions problem.
  Currently, on the unix VFS generates this result code.
}
RESCODE SQLITE_ABORT        4  {
  The SQLITE_ABORT result code indicates that an operation was aborted
  prior to completion, usually be application request.
  <p>
  If the callback function to [sqlite3_exec()] returns non-zero, then
  sqlite3_exec() will return SQLITE_ABORT.
  <p>
  In addition to being a result code,
  the SQLITE_ABORT value is also used as a [conflict resolution mode]
  returned from the [sqlite3_vtab_on_conflict()] interface.
}
RESCODE SQLITE_BUSY         5  {
}
RESCODE SQLITE_LOCKED       6  {}
RESCODE SQLITE_NOMEM        7   {
  The SQLITE_NOMEM result code indicates that SQLite was unable to allocate
  all the memory it needed to complete the operation.  In other words, an
  internal call to [sqlite3_malloc()] or [sqlite3_realloc()] has failed in
  a case where the memory being allocated was required in order to continue
  the operation.
}
RESCODE SQLITE_READONLY     8   {
  The SQLITE_READONLY result code is returned when an attempt is made to 
  alter some data for which the current database connection does not have
  write permission.
}
RESCODE SQLITE_INTERRUPT    9   {
  The SQLITE_INTERRUPT result code indicates that an operation was
  interrupted by the [sqlite3_interrupt()] interface.
}
RESCODE SQLITE_IOERR       10   {
  The SQLITE_IOERR result code says that the operation could not finish
  because the operating system reported an I/O error.  This could mean
  a hardware malfunction.  Or perhaps a removable storage device such as
  a USB thumb drive on which the database file is stored was removed in
  the middle of a write operation.
  <p>
  A full disk drive will normally give an SQLITE_FULL error rather than
  an SQLITE_IOERR error.
  <p>
  There are many different extended result codes for I/O errors that
  identify the specific I/O operation that failed.
}
RESCODE SQLITE_CORRUPT     11   {
  The SQLITE_CORRUPT result code indicates that the database file has
  been corrupted.  See the [How To Corrupt Your Database Files] for
  further discussion on how corruption can occur.
}
RESCODE SQLITE_NOTFOUND    12   {}
RESCODE SQLITE_FULL        13   {
  The SQLITE_FULL result code indicates that a write could not complete
  because the disk is full.  Note that this error can occur when trying
  to write information into the main database file, or into a temporary 
  file.  Sometimes users encounter this error when they are using large
  temporary files (for example to do large sorts) but have very little
  space available in the partition used by temporary files.
}
RESCODE SQLITE_CANTOPEN    14   {}
RESCODE SQLITE_PROTOCOL    15   {}
RESCODE SQLITE_EMPTY       16   {}
RESCODE SQLITE_SCHEMA      17   {
  The SQLITE_SCHEMA result code indicates that the database schema
  has changed.  This result code can be returned from [sqlite3_step()] for
  a [prepared statement] that was generated using [sqlite3_prepare()] or
  [sqlite3_prepare16()].  If the database schema was changed by some other
  process in between the time that the statement was prepared and the time
  the statement was run, this error can result.
  <p>
  If a [prepared statement] is generated from [sqlite3_prepare_v2()] then
  the statement is automatically re-prepared if the schema changes, up to
  [SQLITE_MAX_SCHEMA_RETRY] times (default: 50).  The [sqlite3_step()]
  interface will only return SQLITE_SCHEMA back to the application if 
  the failure persists after these many retries.
}
RESCODE SQLITE_TOOBIG      18   {}
RESCODE SQLITE_CONSTRAINT  19   {}
RESCODE SQLITE_MISMATCH    20   {}
RESCODE SQLITE_MISUSE      21   {
  The SQLITE_MISUSE return code might be returned if the application uses
  any SQLite interface in a way that is undefined or unsupported.  For
  example, using a [prepared statement] after that prepared statement has
  been [sqlite3_finalize|finalized] might result in an SQLITE_MISUSE error.
  <p>
  SQLite tries to detect misuse and report the misuse using this result code.
  However, there is no guarantee that the detection of misuse will be
  successful.  The misuse detection is probablistic.  Applications should
  never depend on an SQLITE_MISUSE return value.
  <p>
  If SQLite ever returns SQLITE_MISUSE from any interface, that means that
  the application is incorrectly coded and needs to be fixed.
}
RESCODE SQLITE_NOLFS       22   {
  The SQLITE_NOLFS error can be returned on systems that do not support
  large files when the database grows to be larger than what the filesystem
  can handle.  "NOLFS" stands for "NO Large File Support".
}
RESCODE SQLITE_AUTH        23   {}
RESCODE SQLITE_FORMAT      24   {}
RESCODE SQLITE_RANGE       25   {}
RESCODE SQLITE_NOTADB      26   {}
RESCODE SQLITE_NOTICE      27   {}
RESCODE SQLITE_WARNING     28   {}
RESCODE SQLITE_ROW         100  {}
RESCODE SQLITE_DONE        101  {}
RESCODE SQLITE_IOERR_READ              {SQLITE_IOERR | (1<<8)} {}
RESCODE SQLITE_IOERR_SHORT_READ        {SQLITE_IOERR | (2<<8)} {}
RESCODE SQLITE_IOERR_WRITE             {SQLITE_IOERR | (3<<8)} {}
RESCODE SQLITE_IOERR_FSYNC             {SQLITE_IOERR | (4<<8)} {}
RESCODE SQLITE_IOERR_DIR_FSYNC         {SQLITE_IOERR | (5<<8)} {}
RESCODE SQLITE_IOERR_TRUNCATE          {SQLITE_IOERR | (6<<8)} {}
RESCODE SQLITE_IOERR_FSTAT             {SQLITE_IOERR | (7<<8)} {}
RESCODE SQLITE_IOERR_UNLOCK            {SQLITE_IOERR | (8<<8)} {}
RESCODE SQLITE_IOERR_RDLOCK            {SQLITE_IOERR | (9<<8)} {}
RESCODE SQLITE_IOERR_DELETE            {SQLITE_IOERR | (10<<8)} {}
RESCODE SQLITE_IOERR_BLOCKED           {SQLITE_IOERR | (11<<8)} {}
RESCODE SQLITE_IOERR_NOMEM             {SQLITE_IOERR | (12<<8)} {}
RESCODE SQLITE_IOERR_ACCESS            {SQLITE_IOERR | (13<<8)} {}
RESCODE SQLITE_IOERR_CHECKRESERVEDLOCK {SQLITE_IOERR | (14<<8)} {}
RESCODE SQLITE_IOERR_LOCK              {SQLITE_IOERR | (15<<8)} {}
RESCODE SQLITE_IOERR_CLOSE             {SQLITE_IOERR | (16<<8)} {}
RESCODE SQLITE_IOERR_DIR_CLOSE         {SQLITE_IOERR | (17<<8)} {}
RESCODE SQLITE_IOERR_SHMOPEN           {SQLITE_IOERR | (18<<8)} {}
RESCODE SQLITE_IOERR_SHMSIZE           {SQLITE_IOERR | (19<<8)} {}
RESCODE SQLITE_IOERR_SHMLOCK           {SQLITE_IOERR | (20<<8)} {}
RESCODE SQLITE_IOERR_SHMMAP            {SQLITE_IOERR | (21<<8)} {}
RESCODE SQLITE_IOERR_SEEK              {SQLITE_IOERR | (22<<8)} {}
RESCODE SQLITE_IOERR_DELETE_NOENT      {SQLITE_IOERR | (23<<8)} {}
RESCODE SQLITE_IOERR_MMAP              {SQLITE_IOERR | (24<<8)} {}
RESCODE SQLITE_IOERR_GETTEMPPATH       {SQLITE_IOERR | (25<<8)} {}
RESCODE SQLITE_IOERR_CONVPATH          {SQLITE_IOERR | (26<<8)} {}
RESCODE SQLITE_LOCKED_SHAREDCACHE      {SQLITE_LOCKED |  (1<<8)} {}
RESCODE SQLITE_BUSY_RECOVERY           {SQLITE_BUSY   |  (1<<8)} {}
RESCODE SQLITE_BUSY_SNAPSHOT           {SQLITE_BUSY   |  (2<<8)} {}
RESCODE SQLITE_CANTOPEN_NOTEMPDIR      {SQLITE_CANTOPEN | (1<<8)} {}
RESCODE SQLITE_CANTOPEN_ISDIR          {SQLITE_CANTOPEN | (2<<8)} {}
RESCODE SQLITE_CANTOPEN_FULLPATH       {SQLITE_CANTOPEN | (3<<8)} {}
RESCODE SQLITE_CANTOPEN_CONVPATH       {SQLITE_CANTOPEN | (4<<8)} {}
RESCODE SQLITE_CORRUPT_VTAB            {SQLITE_CORRUPT | (1<<8)} {}
RESCODE SQLITE_READONLY_RECOVERY       {SQLITE_READONLY | (1<<8)} {}
RESCODE SQLITE_READONLY_CANTLOCK       {SQLITE_READONLY | (2<<8)} {}
RESCODE SQLITE_READONLY_ROLLBACK       {SQLITE_READONLY | (3<<8)} {}
RESCODE SQLITE_READONLY_DBMOVED        {SQLITE_READONLY | (4<<8)} {}
RESCODE SQLITE_ABORT_ROLLBACK          {SQLITE_ABORT | (2<<8)} {}
RESCODE SQLITE_CONSTRAINT_CHECK        {SQLITE_CONSTRAINT | (1<<8)} {}
RESCODE SQLITE_CONSTRAINT_COMMITHOOK   {SQLITE_CONSTRAINT | (2<<8)} {}
RESCODE SQLITE_CONSTRAINT_FOREIGNKEY   {SQLITE_CONSTRAINT | (3<<8)} {}
RESCODE SQLITE_CONSTRAINT_FUNCTION     {SQLITE_CONSTRAINT | (4<<8)} {}
RESCODE SQLITE_CONSTRAINT_NOTNULL      {SQLITE_CONSTRAINT | (5<<8)} {}
RESCODE SQLITE_CONSTRAINT_PRIMARYKEY   {SQLITE_CONSTRAINT | (6<<8)} {}
RESCODE SQLITE_CONSTRAINT_TRIGGER      {SQLITE_CONSTRAINT | (7<<8)} {}
RESCODE SQLITE_CONSTRAINT_UNIQUE       {SQLITE_CONSTRAINT | (8<<8)} {}
RESCODE SQLITE_CONSTRAINT_VTAB         {SQLITE_CONSTRAINT | (9<<8)} {}
RESCODE SQLITE_CONSTRAINT_ROWID        {SQLITE_CONSTRAINT |(10<<8)} {}
RESCODE SQLITE_NOTICE_RECOVER_WAL      {SQLITE_NOTICE | (1<<8)} {}
RESCODE SQLITE_NOTICE_RECOVER_ROLLBACK {SQLITE_NOTICE | (2<<8)} {}
RESCODE SQLITE_WARNING_AUTOINDEX       {SQLITE_WARNING | (1<<8)} {}

#############################################################################
# Code to process the RESCODE values
#
# Convert formula RESCODE values into numerics
set nResCode 0
set nPrimCode 0
set nExtCode 0
set nNonError 3
unset -nocomplain prim_rc
unset -nocomplain ext_rc
foreach name [array names resvalue] {
  set val $resvalue($name)
  if {[regexp {^(SQLITE_[^ ]+) *\| *\((\d+)<<8\)$} $val all basename hival]} {
    set val [expr {$resvalue($basename)+($hival<<8)}]
    set resvalue($name) $val
  }
  set valtoname($val) $name
  incr nResCode
  if {$val<256} {
    incr nPrimCode
    set prim_rc($name) $val
  } else {
    incr nExtCode
    set ext_rc($name) $val
  }
}

hd_puts "<h2>Primary Result Code List</h2>\n"
hd_puts "<p>The $nPrimCode result codes"
</tcl>
  are [result code definitions|defined in sqlite3.h] and are
  listed in alphabetical order below:
  <table border=0 width="100%" cellpadding=10>
  <tr><td valign="top" align="left"><ul>
<tcl>
set nrow [expr {($nPrimCode+2)/3}]
set i 0
foreach name [lsort [array names prim_rc]] {
  if {$i==$nrow} {
    hd_puts "</ul></td><td valign=\"top\" align=\"left\"><ul>\n"
    set i 0
  }
  incr i
  hd_resolve "<li> \[$name\] ($prim_rc($name))\n"
}
hd_puts "</td></td></table>\n\n"

hd_fragment extrc {extended result code} {extended result codes} \
                  {extended error code} {extended error codes}
hd_puts "<h2>Extended Result Code List</h2>\n"
hd_puts "<p>The $nExtCode extended result codes"
</tcl>
  are [extended result code definitions|defined in sqlite3.h] and are
  listed in alphabetical order below:
  <table border=0 width="100%" cellpadding=10>
  <tr><td valign="top" align="left"><ul>
<tcl>
set nrow [expr {($nExtCode+1)/2}]
set i 0
foreach name [lsort [array names ext_rc]] {
  if {$i==$nrow} {
    hd_puts "</ul></td><td valign=\"top\" align=\"left\"><ul>\n"
    set i 0
  }
  incr i
  hd_resolve "<li> \[$name\] ($ext_rc($name))\n"
}
hd_puts "</td></td></table>\n\n"

hd_puts "
<h2>Result Code Meanings</h2>
<p>
The meanings for all $nResCode result code values are shown below,
in numeric order.
"

# Generate the table of result codes
#
foreach val [lsort -int [array names valtoname]] {
  set name $valtoname($val)
  regsub {sqlite_} [string tolower $name] {} tag
  hd_puts "<!--------------------------------------------------------------->\n"
  hd_fragment $tag --override $name
  hd_puts "<h3>($val) $valtoname($val)</h3>\n"
  hd_resolve $resdesc($name)\n\n
}

</tcl>

Changes to wrap.tcl.

180
181
182
183
184
185
186

187











188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
    }
  } else {
    set gurl {}
    if {$hd(fragment)!=""} {
      set lurl $hd(fn-main)#$hd(fragment)
    }
  }

  foreach a $args {











    if {[regexp {^\*} $a]} {
      set visible 0
      set a [string range $a 1 end]
    } else {
      set visible 1
    }
    regsub -all {[^a-zA-Z0-9_.#/ -]} $a {} kw
    if {[info exists glink($kw)]} {
      if {[info exists hd(aux)] && $glink($kw)==$hd(fn-aux)} {
        db eval {DELETE FROM keyword WHERE kw=$kw}
      } else {
        puts stderr "WARNING: duplicate keyword \"$kw\" - $glink($kw) and $lurl"
      }
    }
    if {$gurl==""} {
      set glink($kw) $lurl
      db eval {INSERT OR IGNORE INTO keyword(kw,fragment,indexKw) 
                VALUES($a,$lurl,$visible)}







>

>
>
>
>
>
>
>
>
>
>
>










|







180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
    }
  } else {
    set gurl {}
    if {$hd(fragment)!=""} {
      set lurl $hd(fn-main)#$hd(fragment)
    }
  }
  set override_flag 0
  foreach a $args {
    if {[regexp {^-+(.*)} $a all param]} {
      switch $param {
        "override" {
           set override_flag 1
        }
        default {
           puts stderr "ERROR: unknown parameter: $a"
        }
      }
      continue
    }
    if {[regexp {^\*} $a]} {
      set visible 0
      set a [string range $a 1 end]
    } else {
      set visible 1
    }
    regsub -all {[^a-zA-Z0-9_.#/ -]} $a {} kw
    if {[info exists glink($kw)]} {
      if {[info exists hd(aux)] && $glink($kw)==$hd(fn-aux)} {
        db eval {DELETE FROM keyword WHERE kw=$kw}
      } elseif {$override_flag==0} {
        puts stderr "WARNING: duplicate keyword \"$kw\" - $glink($kw) and $lurl"
      }
    }
    if {$gurl==""} {
      set glink($kw) $lurl
      db eval {INSERT OR IGNORE INTO keyword(kw,fragment,indexKw) 
                VALUES($a,$lurl,$visible)}