xref: /sqlite-3.40.0/ext/misc/prefixes.c (revision 871b1349)
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 */
22*871b1349Sdan #if !defined(SQLITE_CORE) || !defined(SQLITE_OMIT_VIRTUALTABLE)
234ead9634Sdrh #if !defined(SQLITEINT_H)
244ead9634Sdrh #include "sqlite3ext.h"
254ead9634Sdrh #endif
264ead9634Sdrh SQLITE_EXTENSION_INIT1
274ead9634Sdrh #include <string.h>
284ead9634Sdrh #include <assert.h>
294ead9634Sdrh 
304ead9634Sdrh /* prefixes_vtab is a subclass of sqlite3_vtab which is
314ead9634Sdrh ** underlying representation of the virtual table
324ead9634Sdrh */
334ead9634Sdrh typedef struct prefixes_vtab prefixes_vtab;
344ead9634Sdrh struct prefixes_vtab {
354ead9634Sdrh   sqlite3_vtab base;  /* Base class - must be first */
364ead9634Sdrh   /* No additional fields are necessary */
374ead9634Sdrh };
384ead9634Sdrh 
394ead9634Sdrh /* prefixes_cursor is a subclass of sqlite3_vtab_cursor which will
404ead9634Sdrh ** serve as the underlying representation of a cursor that scans
414ead9634Sdrh ** over rows of the result
424ead9634Sdrh */
434ead9634Sdrh typedef struct prefixes_cursor prefixes_cursor;
444ead9634Sdrh struct prefixes_cursor {
454ead9634Sdrh   sqlite3_vtab_cursor base;  /* Base class - must be first */
464ead9634Sdrh   sqlite3_int64 iRowid;      /* The rowid */
474ead9634Sdrh   char *zStr;                /* Original string to be prefixed */
484ead9634Sdrh   int nStr;                  /* Length of the string in bytes */
494ead9634Sdrh };
504ead9634Sdrh 
514ead9634Sdrh /*
524ead9634Sdrh ** The prefixesConnect() method is invoked to create a new
534ead9634Sdrh ** template virtual table.
544ead9634Sdrh **
554ead9634Sdrh ** Think of this routine as the constructor for prefixes_vtab objects.
564ead9634Sdrh **
574ead9634Sdrh ** All this routine needs to do is:
584ead9634Sdrh **
594ead9634Sdrh **    (1) Allocate the prefixes_vtab object and initialize all fields.
604ead9634Sdrh **
614ead9634Sdrh **    (2) Tell SQLite (via the sqlite3_declare_vtab() interface) what the
624ead9634Sdrh **        result set of queries against the virtual table will look like.
634ead9634Sdrh */
644ead9634Sdrh static int prefixesConnect(
654ead9634Sdrh   sqlite3 *db,
664ead9634Sdrh   void *pAux,
674ead9634Sdrh   int argc, const char *const*argv,
684ead9634Sdrh   sqlite3_vtab **ppVtab,
694ead9634Sdrh   char **pzErr
704ead9634Sdrh ){
714ead9634Sdrh   prefixes_vtab *pNew;
724ead9634Sdrh   int rc;
734ead9634Sdrh 
744ead9634Sdrh   rc = sqlite3_declare_vtab(db,
754ead9634Sdrh            "CREATE TABLE prefixes(prefix TEXT, original_string TEXT HIDDEN)"
764ead9634Sdrh        );
774ead9634Sdrh   if( rc==SQLITE_OK ){
784ead9634Sdrh     pNew = sqlite3_malloc( sizeof(*pNew) );
794ead9634Sdrh     *ppVtab = (sqlite3_vtab*)pNew;
804ead9634Sdrh     if( pNew==0 ) return SQLITE_NOMEM;
814ead9634Sdrh     memset(pNew, 0, sizeof(*pNew));
824ead9634Sdrh   }
834ead9634Sdrh   return rc;
844ead9634Sdrh }
854ead9634Sdrh 
864ead9634Sdrh /*
874ead9634Sdrh ** This method is the destructor for prefixes_vtab objects.
884ead9634Sdrh */
894ead9634Sdrh static int prefixesDisconnect(sqlite3_vtab *pVtab){
904ead9634Sdrh   prefixes_vtab *p = (prefixes_vtab*)pVtab;
914ead9634Sdrh   sqlite3_free(p);
924ead9634Sdrh   return SQLITE_OK;
934ead9634Sdrh }
944ead9634Sdrh 
954ead9634Sdrh /*
964ead9634Sdrh ** Constructor for a new prefixes_cursor object.
974ead9634Sdrh */
984ead9634Sdrh static int prefixesOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
994ead9634Sdrh   prefixes_cursor *pCur;
1004ead9634Sdrh   pCur = sqlite3_malloc( sizeof(*pCur) );
1014ead9634Sdrh   if( pCur==0 ) return SQLITE_NOMEM;
1024ead9634Sdrh   memset(pCur, 0, sizeof(*pCur));
1034ead9634Sdrh   *ppCursor = &pCur->base;
1044ead9634Sdrh   return SQLITE_OK;
1054ead9634Sdrh }
1064ead9634Sdrh 
1074ead9634Sdrh /*
1084ead9634Sdrh ** Destructor for a prefixes_cursor.
1094ead9634Sdrh */
1104ead9634Sdrh static int prefixesClose(sqlite3_vtab_cursor *cur){
1114ead9634Sdrh   prefixes_cursor *pCur = (prefixes_cursor*)cur;
1124ead9634Sdrh   sqlite3_free(pCur->zStr);
1134ead9634Sdrh   sqlite3_free(pCur);
1144ead9634Sdrh   return SQLITE_OK;
1154ead9634Sdrh }
1164ead9634Sdrh 
1174ead9634Sdrh 
1184ead9634Sdrh /*
1194ead9634Sdrh ** Advance a prefixes_cursor to its next row of output.
1204ead9634Sdrh */
1214ead9634Sdrh static int prefixesNext(sqlite3_vtab_cursor *cur){
1224ead9634Sdrh   prefixes_cursor *pCur = (prefixes_cursor*)cur;
1234ead9634Sdrh   pCur->iRowid++;
1244ead9634Sdrh   return SQLITE_OK;
1254ead9634Sdrh }
1264ead9634Sdrh 
1274ead9634Sdrh /*
1284ead9634Sdrh ** Return values of columns for the row at which the prefixes_cursor
1294ead9634Sdrh ** is currently pointing.
1304ead9634Sdrh */
1314ead9634Sdrh static int prefixesColumn(
1324ead9634Sdrh   sqlite3_vtab_cursor *cur,   /* The cursor */
1334ead9634Sdrh   sqlite3_context *ctx,       /* First argument to sqlite3_result_...() */
1344ead9634Sdrh   int i                       /* Which column to return */
1354ead9634Sdrh ){
1364ead9634Sdrh   prefixes_cursor *pCur = (prefixes_cursor*)cur;
1374ead9634Sdrh   switch( i ){
1384ead9634Sdrh     case 0:
1394ead9634Sdrh       sqlite3_result_text(ctx, pCur->zStr, pCur->nStr - (int)pCur->iRowid,
1404ead9634Sdrh                           0);
1414ead9634Sdrh       break;
1424ead9634Sdrh     default:
1434ead9634Sdrh       sqlite3_result_text(ctx, pCur->zStr, pCur->nStr, 0);
1444ead9634Sdrh       break;
1454ead9634Sdrh   }
1464ead9634Sdrh   return SQLITE_OK;
1474ead9634Sdrh }
1484ead9634Sdrh 
1494ead9634Sdrh /*
1504ead9634Sdrh ** Return the rowid for the current row.  In this implementation, the
1514ead9634Sdrh ** rowid is the same as the output value.
1524ead9634Sdrh */
1534ead9634Sdrh static int prefixesRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
1544ead9634Sdrh   prefixes_cursor *pCur = (prefixes_cursor*)cur;
1554ead9634Sdrh   *pRowid = pCur->iRowid;
1564ead9634Sdrh   return SQLITE_OK;
1574ead9634Sdrh }
1584ead9634Sdrh 
1594ead9634Sdrh /*
1604ead9634Sdrh ** Return TRUE if the cursor has been moved off of the last
1614ead9634Sdrh ** row of output.
1624ead9634Sdrh */
1634ead9634Sdrh static int prefixesEof(sqlite3_vtab_cursor *cur){
1644ead9634Sdrh   prefixes_cursor *pCur = (prefixes_cursor*)cur;
1654ead9634Sdrh   return pCur->iRowid>pCur->nStr;
1664ead9634Sdrh }
1674ead9634Sdrh 
1684ead9634Sdrh /*
1694ead9634Sdrh ** This method is called to "rewind" the prefixes_cursor object back
1704ead9634Sdrh ** to the first row of output.  This method is always called at least
1714ead9634Sdrh ** once prior to any call to prefixesColumn() or prefixesRowid() or
1724ead9634Sdrh ** prefixesEof().
1734ead9634Sdrh */
1744ead9634Sdrh static int prefixesFilter(
1754ead9634Sdrh   sqlite3_vtab_cursor *pVtabCursor,
1764ead9634Sdrh   int idxNum, const char *idxStr,
1774ead9634Sdrh   int argc, sqlite3_value **argv
1784ead9634Sdrh ){
1794ead9634Sdrh   prefixes_cursor *pCur = (prefixes_cursor *)pVtabCursor;
1804ead9634Sdrh   sqlite3_free(pCur->zStr);
1814ead9634Sdrh   if( argc>0 ){
1824ead9634Sdrh     pCur->zStr = sqlite3_mprintf("%s", sqlite3_value_text(argv[0]));
1834ead9634Sdrh     pCur->nStr = pCur->zStr ? (int)strlen(pCur->zStr) : 0;
1844ead9634Sdrh   }else{
1854ead9634Sdrh     pCur->zStr = 0;
1864ead9634Sdrh     pCur->nStr = 0;
1874ead9634Sdrh   }
1884ead9634Sdrh   pCur->iRowid = 0;
1894ead9634Sdrh   return SQLITE_OK;
1904ead9634Sdrh }
1914ead9634Sdrh 
1924ead9634Sdrh /*
1934ead9634Sdrh ** SQLite will invoke this method one or more times while planning a query
1944ead9634Sdrh ** that uses the virtual table.  This routine needs to create
1954ead9634Sdrh ** a query plan for each invocation and compute an estimated cost for that
1964ead9634Sdrh ** plan.
1974ead9634Sdrh */
1984ead9634Sdrh static int prefixesBestIndex(
1994ead9634Sdrh   sqlite3_vtab *tab,
2004ead9634Sdrh   sqlite3_index_info *pIdxInfo
2014ead9634Sdrh ){
2024ead9634Sdrh   /* Search for a usable equality constraint against column 1
2034ead9634Sdrh   ** (original_string) and use it if at all possible */
2044ead9634Sdrh   int i;
2054ead9634Sdrh   const struct sqlite3_index_constraint *p;
2064ead9634Sdrh 
2074ead9634Sdrh   for(i=0, p=pIdxInfo->aConstraint; i<pIdxInfo->nConstraint; i++, p++){
2084ead9634Sdrh     if( p->iColumn!=1 ) continue;
2094ead9634Sdrh     if( p->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
2104ead9634Sdrh     if( !p->usable ) continue;
2114ead9634Sdrh     pIdxInfo->aConstraintUsage[i].argvIndex = 1;
2124ead9634Sdrh     pIdxInfo->aConstraintUsage[i].omit = 1;
2134ead9634Sdrh     pIdxInfo->estimatedCost = (double)10;
2144ead9634Sdrh     pIdxInfo->estimatedRows = 10;
2154ead9634Sdrh     return SQLITE_OK;
2164ead9634Sdrh   }
2174ead9634Sdrh   pIdxInfo->estimatedCost = (double)1000000000;
2184ead9634Sdrh   pIdxInfo->estimatedRows = 1000000000;
2194ead9634Sdrh   return SQLITE_OK;
2204ead9634Sdrh }
2214ead9634Sdrh 
2224ead9634Sdrh /*
2234ead9634Sdrh ** This following structure defines all the methods for the
2244ead9634Sdrh ** virtual table.
2254ead9634Sdrh */
2264ead9634Sdrh static sqlite3_module prefixesModule = {
2274ead9634Sdrh   /* iVersion    */ 0,
2284ead9634Sdrh   /* xCreate     */ 0,
2294ead9634Sdrh   /* xConnect    */ prefixesConnect,
2304ead9634Sdrh   /* xBestIndex  */ prefixesBestIndex,
2314ead9634Sdrh   /* xDisconnect */ prefixesDisconnect,
2324ead9634Sdrh   /* xDestroy    */ 0,
2334ead9634Sdrh   /* xOpen       */ prefixesOpen,
2344ead9634Sdrh   /* xClose      */ prefixesClose,
2354ead9634Sdrh   /* xFilter     */ prefixesFilter,
2364ead9634Sdrh   /* xNext       */ prefixesNext,
2374ead9634Sdrh   /* xEof        */ prefixesEof,
2384ead9634Sdrh   /* xColumn     */ prefixesColumn,
2394ead9634Sdrh   /* xRowid      */ prefixesRowid,
2404ead9634Sdrh   /* xUpdate     */ 0,
2414ead9634Sdrh   /* xBegin      */ 0,
2424ead9634Sdrh   /* xSync       */ 0,
2434ead9634Sdrh   /* xCommit     */ 0,
2444ead9634Sdrh   /* xRollback   */ 0,
2454ead9634Sdrh   /* xFindMethod */ 0,
2464ead9634Sdrh   /* xRename     */ 0,
2474ead9634Sdrh   /* xSavepoint  */ 0,
2484ead9634Sdrh   /* xRelease    */ 0,
2494ead9634Sdrh   /* xRollbackTo */ 0,
2504ead9634Sdrh   /* xShadowName */ 0
2514ead9634Sdrh };
2524ead9634Sdrh 
2539c039d9fSdan /*
2549c039d9fSdan ** This is a copy of the SQLITE_SKIP_UTF8(zIn) macro in sqliteInt.h.
2559c039d9fSdan **
2569c039d9fSdan ** Assuming zIn points to the first byte of a UTF-8 character,
2579c039d9fSdan ** advance zIn to point to the first byte of the next UTF-8 character.
2589c039d9fSdan */
2599c039d9fSdan #define PREFIX_SKIP_UTF8(zIn) {                        \
2609c039d9fSdan   if( (*(zIn++))>=0xc0 ){                              \
2619c039d9fSdan     while( (*zIn & 0xc0)==0x80 ){ zIn++; }             \
2629c039d9fSdan   }                                                    \
2639c039d9fSdan }
2649c039d9fSdan 
2659c039d9fSdan /*
2669c039d9fSdan ** Implementation of function prefix_length(). This function accepts two
2679c039d9fSdan ** strings as arguments and returns the length in characters (not bytes),
2689c039d9fSdan ** of the longest prefix shared by the two strings. For example:
2699c039d9fSdan **
2709c039d9fSdan **   prefix_length('abcdxxx', 'abcyy') == 3
2719c039d9fSdan **   prefix_length('abcdxxx', 'bcyyy') == 0
2729c039d9fSdan **   prefix_length('abcdxxx', 'ab')    == 2
2739c039d9fSdan **   prefix_length('ab',      'abcd')  == 2
2749c039d9fSdan **
2759c039d9fSdan ** This function assumes the input is well-formed utf-8. If it is not,
2769c039d9fSdan ** it is possible for this function to return -1.
2779c039d9fSdan */
2789c039d9fSdan static void prefixLengthFunc(
2799c039d9fSdan   sqlite3_context *ctx,
2809c039d9fSdan   int nVal,
2819c039d9fSdan   sqlite3_value **apVal
2829c039d9fSdan ){
2839c039d9fSdan   int nByte;                      /* Number of bytes to compare */
2849c039d9fSdan   int nRet = 0;                   /* Return value */
2859c039d9fSdan   const unsigned char *zL = sqlite3_value_text(apVal[0]);
2869c039d9fSdan   const unsigned char *zR = sqlite3_value_text(apVal[1]);
2879c039d9fSdan   int nL = sqlite3_value_bytes(apVal[0]);
2889c039d9fSdan   int nR = sqlite3_value_bytes(apVal[1]);
2899c039d9fSdan   int i;
2909c039d9fSdan 
2919c039d9fSdan   nByte = (nL > nR ? nL : nR);
2929c039d9fSdan   for(i=0; i<nByte; i++){
2939c039d9fSdan     if( zL[i]!=zR[i] ) break;
2949c039d9fSdan     if( (zL[i] & 0xC0)!=0x80 ) nRet++;
2959c039d9fSdan   }
2969c039d9fSdan 
2979c039d9fSdan   if( (zL[i] & 0xC0)==0x80 ) nRet--;
2989c039d9fSdan   sqlite3_result_int(ctx, nRet);
2999c039d9fSdan }
3004ead9634Sdrh 
3014ead9634Sdrh #ifdef _WIN32
3024ead9634Sdrh __declspec(dllexport)
3034ead9634Sdrh #endif
3044ead9634Sdrh int sqlite3_prefixes_init(
3054ead9634Sdrh   sqlite3 *db,
3064ead9634Sdrh   char **pzErrMsg,
3074ead9634Sdrh   const sqlite3_api_routines *pApi
3084ead9634Sdrh ){
3094ead9634Sdrh   int rc = SQLITE_OK;
3104ead9634Sdrh   SQLITE_EXTENSION_INIT2(pApi);
3114ead9634Sdrh   rc = sqlite3_create_module(db, "prefixes", &prefixesModule, 0);
3129c039d9fSdan   if( rc==SQLITE_OK ){
3139c039d9fSdan     rc = sqlite3_create_function(
3149c039d9fSdan         db, "prefix_length", 2, SQLITE_UTF8, 0, prefixLengthFunc, 0, 0
3159c039d9fSdan     );
3169c039d9fSdan   }
3174ead9634Sdrh   return rc;
3184ead9634Sdrh }
319*871b1349Sdan #endif /* !defined(SQLITE_CORE) || !defined(SQLITE_OMIT_VIRTUALTABLE) */
320