Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(512)

Side by Side Diff: third_party/sqlite/sqlite-src-3100200/ext/fts5/fts5.h

Issue 1610543003: [sql] Import reference version of SQLite 3.10.2. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 /*
2 ** 2014 May 31
3 **
4 ** The author disclaims copyright to this source code. In place of
5 ** a legal notice, here is a blessing:
6 **
7 ** May you do good and not evil.
8 ** May you find forgiveness for yourself and forgive others.
9 ** May you share freely, never taking more than you give.
10 **
11 ******************************************************************************
12 **
13 ** Interfaces to extend FTS5. Using the interfaces defined in this file,
14 ** FTS5 may be extended with:
15 **
16 ** * custom tokenizers, and
17 ** * custom auxiliary functions.
18 */
19
20
21 #ifndef _FTS5_H
22 #define _FTS5_H
23
24 #include "sqlite3.h"
25
26 #ifdef __cplusplus
27 extern "C" {
28 #endif
29
30 /*************************************************************************
31 ** CUSTOM AUXILIARY FUNCTIONS
32 **
33 ** Virtual table implementations may overload SQL functions by implementing
34 ** the sqlite3_module.xFindFunction() method.
35 */
36
37 typedef struct Fts5ExtensionApi Fts5ExtensionApi;
38 typedef struct Fts5Context Fts5Context;
39 typedef struct Fts5PhraseIter Fts5PhraseIter;
40
41 typedef void (*fts5_extension_function)(
42 const Fts5ExtensionApi *pApi, /* API offered by current FTS version */
43 Fts5Context *pFts, /* First arg to pass to pApi functions */
44 sqlite3_context *pCtx, /* Context for returning result/error */
45 int nVal, /* Number of values in apVal[] array */
46 sqlite3_value **apVal /* Array of trailing arguments */
47 );
48
49 struct Fts5PhraseIter {
50 const unsigned char *a;
51 const unsigned char *b;
52 };
53
54 /*
55 ** EXTENSION API FUNCTIONS
56 **
57 ** xUserData(pFts):
58 ** Return a copy of the context pointer the extension function was
59 ** registered with.
60 **
61 ** xColumnTotalSize(pFts, iCol, pnToken):
62 ** If parameter iCol is less than zero, set output variable *pnToken
63 ** to the total number of tokens in the FTS5 table. Or, if iCol is
64 ** non-negative but less than the number of columns in the table, return
65 ** the total number of tokens in column iCol, considering all rows in
66 ** the FTS5 table.
67 **
68 ** If parameter iCol is greater than or equal to the number of columns
69 ** in the table, SQLITE_RANGE is returned. Or, if an error occurs (e.g.
70 ** an OOM condition or IO error), an appropriate SQLite error code is
71 ** returned.
72 **
73 ** xColumnCount(pFts):
74 ** Return the number of columns in the table.
75 **
76 ** xColumnSize(pFts, iCol, pnToken):
77 ** If parameter iCol is less than zero, set output variable *pnToken
78 ** to the total number of tokens in the current row. Or, if iCol is
79 ** non-negative but less than the number of columns in the table, set
80 ** *pnToken to the number of tokens in column iCol of the current row.
81 **
82 ** If parameter iCol is greater than or equal to the number of columns
83 ** in the table, SQLITE_RANGE is returned. Or, if an error occurs (e.g.
84 ** an OOM condition or IO error), an appropriate SQLite error code is
85 ** returned.
86 **
87 ** xColumnText:
88 ** This function attempts to retrieve the text of column iCol of the
89 ** current document. If successful, (*pz) is set to point to a buffer
90 ** containing the text in utf-8 encoding, (*pn) is set to the size in bytes
91 ** (not characters) of the buffer and SQLITE_OK is returned. Otherwise,
92 ** if an error occurs, an SQLite error code is returned and the final values
93 ** of (*pz) and (*pn) are undefined.
94 **
95 ** xPhraseCount:
96 ** Returns the number of phrases in the current query expression.
97 **
98 ** xPhraseSize:
99 ** Returns the number of tokens in phrase iPhrase of the query. Phrases
100 ** are numbered starting from zero.
101 **
102 ** xInstCount:
103 ** Set *pnInst to the total number of occurrences of all phrases within
104 ** the query within the current row. Return SQLITE_OK if successful, or
105 ** an error code (i.e. SQLITE_NOMEM) if an error occurs.
106 **
107 ** xInst:
108 ** Query for the details of phrase match iIdx within the current row.
109 ** Phrase matches are numbered starting from zero, so the iIdx argument
110 ** should be greater than or equal to zero and smaller than the value
111 ** output by xInstCount().
112 **
113 ** Returns SQLITE_OK if successful, or an error code (i.e. SQLITE_NOMEM)
114 ** if an error occurs.
115 **
116 ** xRowid:
117 ** Returns the rowid of the current row.
118 **
119 ** xTokenize:
120 ** Tokenize text using the tokenizer belonging to the FTS5 table.
121 **
122 ** xQueryPhrase(pFts5, iPhrase, pUserData, xCallback):
123 ** This API function is used to query the FTS table for phrase iPhrase
124 ** of the current query. Specifically, a query equivalent to:
125 **
126 ** ... FROM ftstable WHERE ftstable MATCH $p ORDER BY rowid
127 **
128 ** with $p set to a phrase equivalent to the phrase iPhrase of the
129 ** current query is executed. For each row visited, the callback function
130 ** passed as the fourth argument is invoked. The context and API objects
131 ** passed to the callback function may be used to access the properties of
132 ** each matched row. Invoking Api.xUserData() returns a copy of the pointer
133 ** passed as the third argument to pUserData.
134 **
135 ** If the callback function returns any value other than SQLITE_OK, the
136 ** query is abandoned and the xQueryPhrase function returns immediately.
137 ** If the returned value is SQLITE_DONE, xQueryPhrase returns SQLITE_OK.
138 ** Otherwise, the error code is propagated upwards.
139 **
140 ** If the query runs to completion without incident, SQLITE_OK is returned.
141 ** Or, if some error occurs before the query completes or is aborted by
142 ** the callback, an SQLite error code is returned.
143 **
144 **
145 ** xSetAuxdata(pFts5, pAux, xDelete)
146 **
147 ** Save the pointer passed as the second argument as the extension functions
148 ** "auxiliary data". The pointer may then be retrieved by the current or any
149 ** future invocation of the same fts5 extension function made as part of
150 ** of the same MATCH query using the xGetAuxdata() API.
151 **
152 ** Each extension function is allocated a single auxiliary data slot for
153 ** each FTS query (MATCH expression). If the extension function is invoked
154 ** more than once for a single FTS query, then all invocations share a
155 ** single auxiliary data context.
156 **
157 ** If there is already an auxiliary data pointer when this function is
158 ** invoked, then it is replaced by the new pointer. If an xDelete callback
159 ** was specified along with the original pointer, it is invoked at this
160 ** point.
161 **
162 ** The xDelete callback, if one is specified, is also invoked on the
163 ** auxiliary data pointer after the FTS5 query has finished.
164 **
165 ** If an error (e.g. an OOM condition) occurs within this function, an
166 ** the auxiliary data is set to NULL and an error code returned. If the
167 ** xDelete parameter was not NULL, it is invoked on the auxiliary data
168 ** pointer before returning.
169 **
170 **
171 ** xGetAuxdata(pFts5, bClear)
172 **
173 ** Returns the current auxiliary data pointer for the fts5 extension
174 ** function. See the xSetAuxdata() method for details.
175 **
176 ** If the bClear argument is non-zero, then the auxiliary data is cleared
177 ** (set to NULL) before this function returns. In this case the xDelete,
178 ** if any, is not invoked.
179 **
180 **
181 ** xRowCount(pFts5, pnRow)
182 **
183 ** This function is used to retrieve the total number of rows in the table.
184 ** In other words, the same value that would be returned by:
185 **
186 ** SELECT count(*) FROM ftstable;
187 **
188 ** xPhraseFirst()
189 ** This function is used, along with type Fts5PhraseIter and the xPhraseNext
190 ** method, to iterate through all instances of a single query phrase within
191 ** the current row. This is the same information as is accessible via the
192 ** xInstCount/xInst APIs. While the xInstCount/xInst APIs are more convenient
193 ** to use, this API may be faster under some circumstances. To iterate
194 ** through instances of phrase iPhrase, use the following code:
195 **
196 ** Fts5PhraseIter iter;
197 ** int iCol, iOff;
198 ** for(pApi->xPhraseFirst(pFts, iPhrase, &iter, &iCol, &iOff);
199 ** iOff>=0;
200 ** pApi->xPhraseNext(pFts, &iter, &iCol, &iOff)
201 ** ){
202 ** // An instance of phrase iPhrase at offset iOff of column iCol
203 ** }
204 **
205 ** The Fts5PhraseIter structure is defined above. Applications should not
206 ** modify this structure directly - it should only be used as shown above
207 ** with the xPhraseFirst() and xPhraseNext() API methods.
208 **
209 ** xPhraseNext()
210 ** See xPhraseFirst above.
211 */
212 struct Fts5ExtensionApi {
213 int iVersion; /* Currently always set to 1 */
214
215 void *(*xUserData)(Fts5Context*);
216
217 int (*xColumnCount)(Fts5Context*);
218 int (*xRowCount)(Fts5Context*, sqlite3_int64 *pnRow);
219 int (*xColumnTotalSize)(Fts5Context*, int iCol, sqlite3_int64 *pnToken);
220
221 int (*xTokenize)(Fts5Context*,
222 const char *pText, int nText, /* Text to tokenize */
223 void *pCtx, /* Context passed to xToken() */
224 int (*xToken)(void*, int, const char*, int, int, int) /* Callback */
225 );
226
227 int (*xPhraseCount)(Fts5Context*);
228 int (*xPhraseSize)(Fts5Context*, int iPhrase);
229
230 int (*xInstCount)(Fts5Context*, int *pnInst);
231 int (*xInst)(Fts5Context*, int iIdx, int *piPhrase, int *piCol, int *piOff);
232
233 sqlite3_int64 (*xRowid)(Fts5Context*);
234 int (*xColumnText)(Fts5Context*, int iCol, const char **pz, int *pn);
235 int (*xColumnSize)(Fts5Context*, int iCol, int *pnToken);
236
237 int (*xQueryPhrase)(Fts5Context*, int iPhrase, void *pUserData,
238 int(*)(const Fts5ExtensionApi*,Fts5Context*,void*)
239 );
240 int (*xSetAuxdata)(Fts5Context*, void *pAux, void(*xDelete)(void*));
241 void *(*xGetAuxdata)(Fts5Context*, int bClear);
242
243 void (*xPhraseFirst)(Fts5Context*, int iPhrase, Fts5PhraseIter*, int*, int*);
244 void (*xPhraseNext)(Fts5Context*, Fts5PhraseIter*, int *piCol, int *piOff);
245 };
246
247 /*
248 ** CUSTOM AUXILIARY FUNCTIONS
249 *************************************************************************/
250
251 /*************************************************************************
252 ** CUSTOM TOKENIZERS
253 **
254 ** Applications may also register custom tokenizer types. A tokenizer
255 ** is registered by providing fts5 with a populated instance of the
256 ** following structure. All structure methods must be defined, setting
257 ** any member of the fts5_tokenizer struct to NULL leads to undefined
258 ** behaviour. The structure methods are expected to function as follows:
259 **
260 ** xCreate:
261 ** This function is used to allocate and inititalize a tokenizer instance.
262 ** A tokenizer instance is required to actually tokenize text.
263 **
264 ** The first argument passed to this function is a copy of the (void*)
265 ** pointer provided by the application when the fts5_tokenizer object
266 ** was registered with FTS5 (the third argument to xCreateTokenizer()).
267 ** The second and third arguments are an array of nul-terminated strings
268 ** containing the tokenizer arguments, if any, specified following the
269 ** tokenizer name as part of the CREATE VIRTUAL TABLE statement used
270 ** to create the FTS5 table.
271 **
272 ** The final argument is an output variable. If successful, (*ppOut)
273 ** should be set to point to the new tokenizer handle and SQLITE_OK
274 ** returned. If an error occurs, some value other than SQLITE_OK should
275 ** be returned. In this case, fts5 assumes that the final value of *ppOut
276 ** is undefined.
277 **
278 ** xDelete:
279 ** This function is invoked to delete a tokenizer handle previously
280 ** allocated using xCreate(). Fts5 guarantees that this function will
281 ** be invoked exactly once for each successful call to xCreate().
282 **
283 ** xTokenize:
284 ** This function is expected to tokenize the nText byte string indicated
285 ** by argument pText. pText may or may not be nul-terminated. The first
286 ** argument passed to this function is a pointer to an Fts5Tokenizer object
287 ** returned by an earlier call to xCreate().
288 **
289 ** The second argument indicates the reason that FTS5 is requesting
290 ** tokenization of the supplied text. This is always one of the following
291 ** four values:
292 **
293 ** <ul><li> <b>FTS5_TOKENIZE_DOCUMENT</b> - A document is being inserted into
294 ** or removed from the FTS table. The tokenizer is being invoked to
295 ** determine the set of tokens to add to (or delete from) the
296 ** FTS index.
297 **
298 ** <li> <b>FTS5_TOKENIZE_QUERY</b> - A MATCH query is being executed
299 ** against the FTS index. The tokenizer is being called to tokenize
300 ** a bareword or quoted string specified as part of the query.
301 **
302 ** <li> <b>(FTS5_TOKENIZE_QUERY | FTS5_TOKENIZE_PREFIX)</b> - Same as
303 ** FTS5_TOKENIZE_QUERY, except that the bareword or quoted string is
304 ** followed by a "*" character, indicating that the last token
305 ** returned by the tokenizer will be treated as a token prefix.
306 **
307 ** <li> <b>FTS5_TOKENIZE_AUX</b> - The tokenizer is being invoked to
308 ** satisfy an fts5_api.xTokenize() request made by an auxiliary
309 ** function. Or an fts5_api.xColumnSize() request made by the same
310 ** on a columnsize=0 database.
311 ** </ul>
312 **
313 ** For each token in the input string, the supplied callback xToken() must
314 ** be invoked. The first argument to it should be a copy of the pointer
315 ** passed as the second argument to xTokenize(). The third and fourth
316 ** arguments are a pointer to a buffer containing the token text, and the
317 ** size of the token in bytes. The 4th and 5th arguments are the byte offsets
318 ** of the first byte of and first byte immediately following the text from
319 ** which the token is derived within the input.
320 **
321 ** The second argument passed to the xToken() callback ("tflags") should
322 ** normally be set to 0. The exception is if the tokenizer supports
323 ** synonyms. In this case see the discussion below for details.
324 **
325 ** FTS5 assumes the xToken() callback is invoked for each token in the
326 ** order that they occur within the input text.
327 **
328 ** If an xToken() callback returns any value other than SQLITE_OK, then
329 ** the tokenization should be abandoned and the xTokenize() method should
330 ** immediately return a copy of the xToken() return value. Or, if the
331 ** input buffer is exhausted, xTokenize() should return SQLITE_OK. Finally,
332 ** if an error occurs with the xTokenize() implementation itself, it
333 ** may abandon the tokenization and return any error code other than
334 ** SQLITE_OK or SQLITE_DONE.
335 **
336 ** SYNONYM SUPPORT
337 **
338 ** Custom tokenizers may also support synonyms. Consider a case in which a
339 ** user wishes to query for a phrase such as "first place". Using the
340 ** built-in tokenizers, the FTS5 query 'first + place' will match instances
341 ** of "first place" within the document set, but not alternative forms
342 ** such as "1st place". In some applications, it would be better to match
343 ** all instances of "first place" or "1st place" regardless of which form
344 ** the user specified in the MATCH query text.
345 **
346 ** There are several ways to approach this in FTS5:
347 **
348 ** <ol><li> By mapping all synonyms to a single token. In this case, the
349 ** In the above example, this means that the tokenizer returns the
350 ** same token for inputs "first" and "1st". Say that token is in
351 ** fact "first", so that when the user inserts the document "I won
352 ** 1st place" entries are added to the index for tokens "i", "won",
353 ** "first" and "place". If the user then queries for '1st + place',
354 ** the tokenizer substitutes "first" for "1st" and the query works
355 ** as expected.
356 **
357 ** <li> By adding multiple synonyms for a single term to the FTS index.
358 ** In this case, when tokenizing query text, the tokenizer may
359 ** provide multiple synonyms for a single term within the document.
360 ** FTS5 then queries the index for each synonym individually. For
361 ** example, faced with the query:
362 **
363 ** <codeblock>
364 ** ... MATCH 'first place'</codeblock>
365 **
366 ** the tokenizer offers both "1st" and "first" as synonyms for the
367 ** first token in the MATCH query and FTS5 effectively runs a query
368 ** similar to:
369 **
370 ** <codeblock>
371 ** ... MATCH '(first OR 1st) place'</codeblock>
372 **
373 ** except that, for the purposes of auxiliary functions, the query
374 ** still appears to contain just two phrases - "(first OR 1st)"
375 ** being treated as a single phrase.
376 **
377 ** <li> By adding multiple synonyms for a single term to the FTS index.
378 ** Using this method, when tokenizing document text, the tokenizer
379 ** provides multiple synonyms for each token. So that when a
380 ** document such as "I won first place" is tokenized, entries are
381 ** added to the FTS index for "i", "won", "first", "1st" and
382 ** "place".
383 **
384 ** This way, even if the tokenizer does not provide synonyms
385 ** when tokenizing query text (it should not - to do would be
386 ** inefficient), it doesn't matter if the user queries for
387 ** 'first + place' or '1st + place', as there are entires in the
388 ** FTS index corresponding to both forms of the first token.
389 ** </ol>
390 **
391 ** Whether it is parsing document or query text, any call to xToken that
392 ** specifies a <i>tflags</i> argument with the FTS5_TOKEN_COLOCATED bit
393 ** is considered to supply a synonym for the previous token. For example,
394 ** when parsing the document "I won first place", a tokenizer that supports
395 ** synonyms would call xToken() 5 times, as follows:
396 **
397 ** <codeblock>
398 ** xToken(pCtx, 0, "i", 1, 0, 1);
399 ** xToken(pCtx, 0, "won", 3, 2, 5);
400 ** xToken(pCtx, 0, "first", 5, 6, 11);
401 ** xToken(pCtx, FTS5_TOKEN_COLOCATED, "1st", 3, 6, 11);
402 ** xToken(pCtx, 0, "place", 5, 12, 17);
403 **</codeblock>
404 **
405 ** It is an error to specify the FTS5_TOKEN_COLOCATED flag the first time
406 ** xToken() is called. Multiple synonyms may be specified for a single token
407 ** by making multiple calls to xToken(FTS5_TOKEN_COLOCATED) in sequence.
408 ** There is no limit to the number of synonyms that may be provided for a
409 ** single token.
410 **
411 ** In many cases, method (1) above is the best approach. It does not add
412 ** extra data to the FTS index or require FTS5 to query for multiple terms,
413 ** so it is efficient in terms of disk space and query speed. However, it
414 ** does not support prefix queries very well. If, as suggested above, the
415 ** token "first" is subsituted for "1st" by the tokenizer, then the query:
416 **
417 ** <codeblock>
418 ** ... MATCH '1s*'</codeblock>
419 **
420 ** will not match documents that contain the token "1st" (as the tokenizer
421 ** will probably not map "1s" to any prefix of "first").
422 **
423 ** For full prefix support, method (3) may be preferred. In this case,
424 ** because the index contains entries for both "first" and "1st", prefix
425 ** queries such as 'fi*' or '1s*' will match correctly. However, because
426 ** extra entries are added to the FTS index, this method uses more space
427 ** within the database.
428 **
429 ** Method (2) offers a midpoint between (1) and (3). Using this method,
430 ** a query such as '1s*' will match documents that contain the literal
431 ** token "1st", but not "first" (assuming the tokenizer is not able to
432 ** provide synonyms for prefixes). However, a non-prefix query like '1st'
433 ** will match against "1st" and "first". This method does not require
434 ** extra disk space, as no extra entries are added to the FTS index.
435 ** On the other hand, it may require more CPU cycles to run MATCH queries,
436 ** as separate queries of the FTS index are required for each synonym.
437 **
438 ** When using methods (2) or (3), it is important that the tokenizer only
439 ** provide synonyms when tokenizing document text (method (2)) or query
440 ** text (method (3)), not both. Doing so will not cause any errors, but is
441 ** inefficient.
442 */
443 typedef struct Fts5Tokenizer Fts5Tokenizer;
444 typedef struct fts5_tokenizer fts5_tokenizer;
445 struct fts5_tokenizer {
446 int (*xCreate)(void*, const char **azArg, int nArg, Fts5Tokenizer **ppOut);
447 void (*xDelete)(Fts5Tokenizer*);
448 int (*xTokenize)(Fts5Tokenizer*,
449 void *pCtx,
450 int flags, /* Mask of FTS5_TOKENIZE_* flags */
451 const char *pText, int nText,
452 int (*xToken)(
453 void *pCtx, /* Copy of 2nd argument to xTokenize() */
454 int tflags, /* Mask of FTS5_TOKEN_* flags */
455 const char *pToken, /* Pointer to buffer containing token */
456 int nToken, /* Size of token in bytes */
457 int iStart, /* Byte offset of token within input text */
458 int iEnd /* Byte offset of end of token within input text */
459 )
460 );
461 };
462
463 /* Flags that may be passed as the third argument to xTokenize() */
464 #define FTS5_TOKENIZE_QUERY 0x0001
465 #define FTS5_TOKENIZE_PREFIX 0x0002
466 #define FTS5_TOKENIZE_DOCUMENT 0x0004
467 #define FTS5_TOKENIZE_AUX 0x0008
468
469 /* Flags that may be passed by the tokenizer implementation back to FTS5
470 ** as the third argument to the supplied xToken callback. */
471 #define FTS5_TOKEN_COLOCATED 0x0001 /* Same position as prev. token */
472
473 /*
474 ** END OF CUSTOM TOKENIZERS
475 *************************************************************************/
476
477 /*************************************************************************
478 ** FTS5 EXTENSION REGISTRATION API
479 */
480 typedef struct fts5_api fts5_api;
481 struct fts5_api {
482 int iVersion; /* Currently always set to 2 */
483
484 /* Create a new tokenizer */
485 int (*xCreateTokenizer)(
486 fts5_api *pApi,
487 const char *zName,
488 void *pContext,
489 fts5_tokenizer *pTokenizer,
490 void (*xDestroy)(void*)
491 );
492
493 /* Find an existing tokenizer */
494 int (*xFindTokenizer)(
495 fts5_api *pApi,
496 const char *zName,
497 void **ppContext,
498 fts5_tokenizer *pTokenizer
499 );
500
501 /* Create a new auxiliary function */
502 int (*xCreateFunction)(
503 fts5_api *pApi,
504 const char *zName,
505 void *pContext,
506 fts5_extension_function xFunction,
507 void (*xDestroy)(void*)
508 );
509 };
510
511 /*
512 ** END OF REGISTRATION API
513 *************************************************************************/
514
515 #ifdef __cplusplus
516 } /* end of the 'extern "C"' block */
517 #endif
518
519 #endif /* _FTS5_H */
520
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698