xref: /sqlite-3.40.0/ext/misc/prefixes.c (revision 9c039d9f)
14ead9634Sdrh /*
24ead9634Sdrh ** 2018-04-19
34ead9634Sdrh **
44ead9634Sdrh ** The author disclaims copyright to this source code.  In place of
54ead9634Sdrh ** a legal notice, here is a blessing:
64ead9634Sdrh **
74ead9634Sdrh **    May you do good and not evil.
84ead9634Sdrh **    May you find forgiveness for yourself and forgive others.
94ead9634Sdrh **    May you share freely, never taking more than you give.
104ead9634Sdrh **
114ead9634Sdrh *************************************************************************
124ead9634Sdrh **
134ead9634Sdrh ** This file implements a table-valued function:
144ead9634Sdrh **
154ead9634Sdrh **      prefixes('abcdefg')
164ead9634Sdrh **
174ead9634Sdrh ** The function has a single (non-HIDDEN) column named prefix that takes
184ead9634Sdrh ** on all prefixes of the string in its argument, including an empty string
194ead9634Sdrh ** and the input string itself.  The order of prefixes is from longest
204ead9634Sdrh ** to shortest.
214ead9634Sdrh */
224ead9634Sdrh #if !defined(SQLITEINT_H)
234ead9634Sdrh #include "sqlite3ext.h"
244ead9634Sdrh #endif
254ead9634Sdrh SQLITE_EXTENSION_INIT1
264ead9634Sdrh #include <string.h>
274ead9634Sdrh #include <assert.h>
284ead9634Sdrh 
294ead9634Sdrh /* prefixes_vtab is a subclass of sqlite3_vtab which is
304ead9634Sdrh ** underlying representation of the virtual table
314ead9634Sdrh */
324ead9634Sdrh typedef struct prefixes_vtab prefixes_vtab;
334ead9634Sdrh struct prefixes_vtab {
344ead9634Sdrh   sqlite3_vtab base;  /* Base class - must be first */
354ead9634Sdrh   /* No additional fields are necessary */
364ead9634Sdrh };
374ead9634Sdrh 
384ead9634Sdrh /* prefixes_cursor is a subclass of sqlite3_vtab_cursor which will
394ead9634Sdrh ** serve as the underlying representation of a cursor that scans
404ead9634Sdrh ** over rows of the result
414ead9634Sdrh */
424ead9634Sdrh typedef struct prefixes_cursor prefixes_cursor;
434ead9634Sdrh struct prefixes_cursor {
444ead9634Sdrh   sqlite3_vtab_cursor base;  /* Base class - must be first */
454ead9634Sdrh   sqlite3_int64 iRowid;      /* The rowid */
464ead9634Sdrh   char *zStr;                /* Original string to be prefixed */
474ead9634Sdrh   int nStr;                  /* Length of the string in bytes */
484ead9634Sdrh };
494ead9634Sdrh 
504ead9634Sdrh /*
514ead9634Sdrh ** The prefixesConnect() method is invoked to create a new
524ead9634Sdrh ** template virtual table.
534ead9634Sdrh **
544ead9634Sdrh ** Think of this routine as the constructor for prefixes_vtab objects.
554ead9634Sdrh **
564ead9634Sdrh ** All this routine needs to do is:
574ead9634Sdrh **
584ead9634Sdrh **    (1) Allocate the prefixes_vtab object and initialize all fields.
594ead9634Sdrh **
604ead9634Sdrh **    (2) Tell SQLite (via the sqlite3_declare_vtab() interface) what the
614ead9634Sdrh **        result set of queries against the virtual table will look like.
624ead9634Sdrh */
634ead9634Sdrh static int prefixesConnect(
644ead9634Sdrh   sqlite3 *db,
654ead9634Sdrh   void *pAux,
664ead9634Sdrh   int argc, const char *const*argv,
674ead9634Sdrh   sqlite3_vtab **ppVtab,
684ead9634Sdrh   char **pzErr
694ead9634Sdrh ){
704ead9634Sdrh   prefixes_vtab *pNew;
714ead9634Sdrh   int rc;
724ead9634Sdrh 
734ead9634Sdrh   rc = sqlite3_declare_vtab(db,
744ead9634Sdrh            "CREATE TABLE prefixes(prefix TEXT, original_string TEXT HIDDEN)"
754ead9634Sdrh        );
764ead9634Sdrh   if( rc==SQLITE_OK ){
774ead9634Sdrh     pNew = sqlite3_malloc( sizeof(*pNew) );
784ead9634Sdrh     *ppVtab = (sqlite3_vtab*)pNew;
794ead9634Sdrh     if( pNew==0 ) return SQLITE_NOMEM;
804ead9634Sdrh     memset(pNew, 0, sizeof(*pNew));
814ead9634Sdrh   }
824ead9634Sdrh   return rc;
834ead9634Sdrh }
844ead9634Sdrh 
854ead9634Sdrh /*
864ead9634Sdrh ** This method is the destructor for prefixes_vtab objects.
874ead9634Sdrh */
884ead9634Sdrh static int prefixesDisconnect(sqlite3_vtab *pVtab){
894ead9634Sdrh   prefixes_vtab *p = (prefixes_vtab*)pVtab;
904ead9634Sdrh   sqlite3_free(p);
914ead9634Sdrh   return SQLITE_OK;
924ead9634Sdrh }
934ead9634Sdrh 
944ead9634Sdrh /*
954ead9634Sdrh ** Constructor for a new prefixes_cursor object.
964ead9634Sdrh */
974ead9634Sdrh static int prefixesOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
984ead9634Sdrh   prefixes_cursor *pCur;
994ead9634Sdrh   pCur = sqlite3_malloc( sizeof(*pCur) );
1004ead9634Sdrh   if( pCur==0 ) return SQLITE_NOMEM;
1014ead9634Sdrh   memset(pCur, 0, sizeof(*pCur));
1024ead9634Sdrh   *ppCursor = &pCur->base;
1034ead9634Sdrh   return SQLITE_OK;
1044ead9634Sdrh }
1054ead9634Sdrh 
1064ead9634Sdrh /*
1074ead9634Sdrh ** Destructor for a prefixes_cursor.
1084ead9634Sdrh */
1094ead9634Sdrh static int prefixesClose(sqlite3_vtab_cursor *cur){
1104ead9634Sdrh   prefixes_cursor *pCur = (prefixes_cursor*)cur;
1114ead9634Sdrh   sqlite3_free(pCur->zStr);
1124ead9634Sdrh   sqlite3_free(pCur);
1134ead9634Sdrh   return SQLITE_OK;
1144ead9634Sdrh }
1154ead9634Sdrh 
1164ead9634Sdrh 
1174ead9634Sdrh /*
1184ead9634Sdrh ** Advance a prefixes_cursor to its next row of output.
1194ead9634Sdrh */
1204ead9634Sdrh static int prefixesNext(sqlite3_vtab_cursor *cur){
1214ead9634Sdrh   prefixes_cursor *pCur = (prefixes_cursor*)cur;
1224ead9634Sdrh   pCur->iRowid++;
1234ead9634Sdrh   return SQLITE_OK;
1244ead9634Sdrh }
1254ead9634Sdrh 
1264ead9634Sdrh /*
1274ead9634Sdrh ** Return values of columns for the row at which the prefixes_cursor
1284ead9634Sdrh ** is currently pointing.
1294ead9634Sdrh */
1304ead9634Sdrh static int prefixesColumn(
1314ead9634Sdrh   sqlite3_vtab_cursor *cur,   /* The cursor */
1324ead9634Sdrh   sqlite3_context *ctx,       /* First argument to sqlite3_result_...() */
1334ead9634Sdrh   int i                       /* Which column to return */
1344ead9634Sdrh ){
1354ead9634Sdrh   prefixes_cursor *pCur = (prefixes_cursor*)cur;
1364ead9634Sdrh   switch( i ){
1374ead9634Sdrh     case 0:
1384ead9634Sdrh       sqlite3_result_text(ctx, pCur->zStr, pCur->nStr - (int)pCur->iRowid,
1394ead9634Sdrh                           0);
1404ead9634Sdrh       break;
1414ead9634Sdrh     default:
1424ead9634Sdrh       sqlite3_result_text(ctx, pCur->zStr, pCur->nStr, 0);
1434ead9634Sdrh       break;
1444ead9634Sdrh   }
1454ead9634Sdrh   return SQLITE_OK;
1464ead9634Sdrh }
1474ead9634Sdrh 
1484ead9634Sdrh /*
1494ead9634Sdrh ** Return the rowid for the current row.  In this implementation, the
1504ead9634Sdrh ** rowid is the same as the output value.
1514ead9634Sdrh */
1524ead9634Sdrh static int prefixesRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
1534ead9634Sdrh   prefixes_cursor *pCur = (prefixes_cursor*)cur;
1544ead9634Sdrh   *pRowid = pCur->iRowid;
1554ead9634Sdrh   return SQLITE_OK;
1564ead9634Sdrh }
1574ead9634Sdrh 
1584ead9634Sdrh /*
1594ead9634Sdrh ** Return TRUE if the cursor has been moved off of the last
1604ead9634Sdrh ** row of output.
1614ead9634Sdrh */
1624ead9634Sdrh static int prefixesEof(sqlite3_vtab_cursor *cur){
1634ead9634Sdrh   prefixes_cursor *pCur = (prefixes_cursor*)cur;
1644ead9634Sdrh   return pCur->iRowid>pCur->nStr;
1654ead9634Sdrh }
1664ead9634Sdrh 
1674ead9634Sdrh /*
1684ead9634Sdrh ** This method is called to "rewind" the prefixes_cursor object back
1694ead9634Sdrh ** to the first row of output.  This method is always called at least
1704ead9634Sdrh ** once prior to any call to prefixesColumn() or prefixesRowid() or
1714ead9634Sdrh ** prefixesEof().
1724ead9634Sdrh */
1734ead9634Sdrh static int prefixesFilter(
1744ead9634Sdrh   sqlite3_vtab_cursor *pVtabCursor,
1754ead9634Sdrh   int idxNum, const char *idxStr,
1764ead9634Sdrh   int argc, sqlite3_value **argv
1774ead9634Sdrh ){
1784ead9634Sdrh   prefixes_cursor *pCur = (prefixes_cursor *)pVtabCursor;
1794ead9634Sdrh   sqlite3_free(pCur->zStr);
1804ead9634Sdrh   if( argc>0 ){
1814ead9634Sdrh     pCur->zStr = sqlite3_mprintf("%s", sqlite3_value_text(argv[0]));
1824ead9634Sdrh     pCur->nStr = pCur->zStr ? (int)strlen(pCur->zStr) : 0;
1834ead9634Sdrh   }else{
1844ead9634Sdrh     pCur->zStr = 0;
1854ead9634Sdrh     pCur->nStr = 0;
1864ead9634Sdrh   }
1874ead9634Sdrh   pCur->iRowid = 0;
1884ead9634Sdrh   return SQLITE_OK;
1894ead9634Sdrh }
1904ead9634Sdrh 
1914ead9634Sdrh /*
1924ead9634Sdrh ** SQLite will invoke this method one or more times while planning a query
1934ead9634Sdrh ** that uses the virtual table.  This routine needs to create
1944ead9634Sdrh ** a query plan for each invocation and compute an estimated cost for that
1954ead9634Sdrh ** plan.
1964ead9634Sdrh */
1974ead9634Sdrh static int prefixesBestIndex(
1984ead9634Sdrh   sqlite3_vtab *tab,
1994ead9634Sdrh   sqlite3_index_info *pIdxInfo
2004ead9634Sdrh ){
2014ead9634Sdrh   /* Search for a usable equality constraint against column 1
2024ead9634Sdrh   ** (original_string) and use it if at all possible */
2034ead9634Sdrh   int i;
2044ead9634Sdrh   const struct sqlite3_index_constraint *p;
2054ead9634Sdrh 
2064ead9634Sdrh   for(i=0, p=pIdxInfo->aConstraint; i<pIdxInfo->nConstraint; i++, p++){
2074ead9634Sdrh     if( p->iColumn!=1 ) continue;
2084ead9634Sdrh     if( p->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
2094ead9634Sdrh     if( !p->usable ) continue;
2104ead9634Sdrh     pIdxInfo->aConstraintUsage[i].argvIndex = 1;
2114ead9634Sdrh     pIdxInfo->aConstraintUsage[i].omit = 1;
2124ead9634Sdrh     pIdxInfo->estimatedCost = (double)10;
2134ead9634Sdrh     pIdxInfo->estimatedRows = 10;
2144ead9634Sdrh     return SQLITE_OK;
2154ead9634Sdrh   }
2164ead9634Sdrh   pIdxInfo->estimatedCost = (double)1000000000;
2174ead9634Sdrh   pIdxInfo->estimatedRows = 1000000000;
2184ead9634Sdrh   return SQLITE_OK;
2194ead9634Sdrh }
2204ead9634Sdrh 
2214ead9634Sdrh /*
2224ead9634Sdrh ** This following structure defines all the methods for the
2234ead9634Sdrh ** virtual table.
2244ead9634Sdrh */
2254ead9634Sdrh static sqlite3_module prefixesModule = {
2264ead9634Sdrh   /* iVersion    */ 0,
2274ead9634Sdrh   /* xCreate     */ 0,
2284ead9634Sdrh   /* xConnect    */ prefixesConnect,
2294ead9634Sdrh   /* xBestIndex  */ prefixesBestIndex,
2304ead9634Sdrh   /* xDisconnect */ prefixesDisconnect,
2314ead9634Sdrh   /* xDestroy    */ 0,
2324ead9634Sdrh   /* xOpen       */ prefixesOpen,
2334ead9634Sdrh   /* xClose      */ prefixesClose,
2344ead9634Sdrh   /* xFilter     */ prefixesFilter,
2354ead9634Sdrh   /* xNext       */ prefixesNext,
2364ead9634Sdrh   /* xEof        */ prefixesEof,
2374ead9634Sdrh   /* xColumn     */ prefixesColumn,
2384ead9634Sdrh   /* xRowid      */ prefixesRowid,
2394ead9634Sdrh   /* xUpdate     */ 0,
2404ead9634Sdrh   /* xBegin      */ 0,
2414ead9634Sdrh   /* xSync       */ 0,
2424ead9634Sdrh   /* xCommit     */ 0,
2434ead9634Sdrh   /* xRollback   */ 0,
2444ead9634Sdrh   /* xFindMethod */ 0,
2454ead9634Sdrh   /* xRename     */ 0,
2464ead9634Sdrh   /* xSavepoint  */ 0,
2474ead9634Sdrh   /* xRelease    */ 0,
2484ead9634Sdrh   /* xRollbackTo */ 0,
2494ead9634Sdrh   /* xShadowName */ 0
2504ead9634Sdrh };
2514ead9634Sdrh 
252*9c039d9fSdan /*
253*9c039d9fSdan ** This is a copy of the SQLITE_SKIP_UTF8(zIn) macro in sqliteInt.h.
254*9c039d9fSdan **
255*9c039d9fSdan ** Assuming zIn points to the first byte of a UTF-8 character,
256*9c039d9fSdan ** advance zIn to point to the first byte of the next UTF-8 character.
257*9c039d9fSdan */
258*9c039d9fSdan #define PREFIX_SKIP_UTF8(zIn) {                        \
259*9c039d9fSdan   if( (*(zIn++))>=0xc0 ){                              \
260*9c039d9fSdan     while( (*zIn & 0xc0)==0x80 ){ zIn++; }             \
261*9c039d9fSdan   }                                                    \
262*9c039d9fSdan }
263*9c039d9fSdan 
264*9c039d9fSdan /*
265*9c039d9fSdan ** Implementation of function prefix_length(). This function accepts two
266*9c039d9fSdan ** strings as arguments and returns the length in characters (not bytes),
267*9c039d9fSdan ** of the longest prefix shared by the two strings. For example:
268*9c039d9fSdan **
269*9c039d9fSdan **   prefix_length('abcdxxx', 'abcyy') == 3
270*9c039d9fSdan **   prefix_length('abcdxxx', 'bcyyy') == 0
271*9c039d9fSdan **   prefix_length('abcdxxx', 'ab')    == 2
272*9c039d9fSdan **   prefix_length('ab',      'abcd')  == 2
273*9c039d9fSdan **
274*9c039d9fSdan ** This function assumes the input is well-formed utf-8. If it is not,
275*9c039d9fSdan ** it is possible for this function to return -1.
276*9c039d9fSdan */
277*9c039d9fSdan static void prefixLengthFunc(
278*9c039d9fSdan   sqlite3_context *ctx,
279*9c039d9fSdan   int nVal,
280*9c039d9fSdan   sqlite3_value **apVal
281*9c039d9fSdan ){
282*9c039d9fSdan   int nByte;                      /* Number of bytes to compare */
283*9c039d9fSdan   int nRet = 0;                   /* Return value */
284*9c039d9fSdan   const unsigned char *zL = sqlite3_value_text(apVal[0]);
285*9c039d9fSdan   const unsigned char *zR = sqlite3_value_text(apVal[1]);
286*9c039d9fSdan   int nL = sqlite3_value_bytes(apVal[0]);
287*9c039d9fSdan   int nR = sqlite3_value_bytes(apVal[1]);
288*9c039d9fSdan   int i;
289*9c039d9fSdan 
290*9c039d9fSdan   nByte = (nL > nR ? nL : nR);
291*9c039d9fSdan   for(i=0; i<nByte; i++){
292*9c039d9fSdan     if( zL[i]!=zR[i] ) break;
293*9c039d9fSdan     if( (zL[i] & 0xC0)!=0x80 ) nRet++;
294*9c039d9fSdan   }
295*9c039d9fSdan 
296*9c039d9fSdan   if( (zL[i] & 0xC0)==0x80 ) nRet--;
297*9c039d9fSdan   sqlite3_result_int(ctx, nRet);
298*9c039d9fSdan }
2994ead9634Sdrh 
3004ead9634Sdrh #ifdef _WIN32
3014ead9634Sdrh __declspec(dllexport)
3024ead9634Sdrh #endif
3034ead9634Sdrh int sqlite3_prefixes_init(
3044ead9634Sdrh   sqlite3 *db,
3054ead9634Sdrh   char **pzErrMsg,
3064ead9634Sdrh   const sqlite3_api_routines *pApi
3074ead9634Sdrh ){
3084ead9634Sdrh   int rc = SQLITE_OK;
3094ead9634Sdrh   SQLITE_EXTENSION_INIT2(pApi);
3104ead9634Sdrh   rc = sqlite3_create_module(db, "prefixes", &prefixesModule, 0);
311*9c039d9fSdan   if( rc==SQLITE_OK ){
312*9c039d9fSdan     rc = sqlite3_create_function(
313*9c039d9fSdan         db, "prefix_length", 2, SQLITE_UTF8, 0, prefixLengthFunc, 0, 0
314*9c039d9fSdan     );
315*9c039d9fSdan   }
3164ead9634Sdrh   return rc;
3174ead9634Sdrh }
318