1*4ead9634Sdrh /* 2*4ead9634Sdrh ** 2018-04-19 3*4ead9634Sdrh ** 4*4ead9634Sdrh ** The author disclaims copyright to this source code. In place of 5*4ead9634Sdrh ** a legal notice, here is a blessing: 6*4ead9634Sdrh ** 7*4ead9634Sdrh ** May you do good and not evil. 8*4ead9634Sdrh ** May you find forgiveness for yourself and forgive others. 9*4ead9634Sdrh ** May you share freely, never taking more than you give. 10*4ead9634Sdrh ** 11*4ead9634Sdrh ************************************************************************* 12*4ead9634Sdrh ** 13*4ead9634Sdrh ** This file implements a table-valued function: 14*4ead9634Sdrh ** 15*4ead9634Sdrh ** prefixes('abcdefg') 16*4ead9634Sdrh ** 17*4ead9634Sdrh ** The function has a single (non-HIDDEN) column named prefix that takes 18*4ead9634Sdrh ** on all prefixes of the string in its argument, including an empty string 19*4ead9634Sdrh ** and the input string itself. The order of prefixes is from longest 20*4ead9634Sdrh ** to shortest. 21*4ead9634Sdrh */ 22*4ead9634Sdrh #if !defined(SQLITEINT_H) 23*4ead9634Sdrh #include "sqlite3ext.h" 24*4ead9634Sdrh #endif 25*4ead9634Sdrh SQLITE_EXTENSION_INIT1 26*4ead9634Sdrh #include <string.h> 27*4ead9634Sdrh #include <assert.h> 28*4ead9634Sdrh 29*4ead9634Sdrh /* prefixes_vtab is a subclass of sqlite3_vtab which is 30*4ead9634Sdrh ** underlying representation of the virtual table 31*4ead9634Sdrh */ 32*4ead9634Sdrh typedef struct prefixes_vtab prefixes_vtab; 33*4ead9634Sdrh struct prefixes_vtab { 34*4ead9634Sdrh sqlite3_vtab base; /* Base class - must be first */ 35*4ead9634Sdrh /* No additional fields are necessary */ 36*4ead9634Sdrh }; 37*4ead9634Sdrh 38*4ead9634Sdrh /* prefixes_cursor is a subclass of sqlite3_vtab_cursor which will 39*4ead9634Sdrh ** serve as the underlying representation of a cursor that scans 40*4ead9634Sdrh ** over rows of the result 41*4ead9634Sdrh */ 42*4ead9634Sdrh typedef struct prefixes_cursor prefixes_cursor; 43*4ead9634Sdrh struct prefixes_cursor { 44*4ead9634Sdrh sqlite3_vtab_cursor base; /* Base class - must be first */ 45*4ead9634Sdrh sqlite3_int64 iRowid; /* The rowid */ 46*4ead9634Sdrh char *zStr; /* Original string to be prefixed */ 47*4ead9634Sdrh int nStr; /* Length of the string in bytes */ 48*4ead9634Sdrh }; 49*4ead9634Sdrh 50*4ead9634Sdrh /* 51*4ead9634Sdrh ** The prefixesConnect() method is invoked to create a new 52*4ead9634Sdrh ** template virtual table. 53*4ead9634Sdrh ** 54*4ead9634Sdrh ** Think of this routine as the constructor for prefixes_vtab objects. 55*4ead9634Sdrh ** 56*4ead9634Sdrh ** All this routine needs to do is: 57*4ead9634Sdrh ** 58*4ead9634Sdrh ** (1) Allocate the prefixes_vtab object and initialize all fields. 59*4ead9634Sdrh ** 60*4ead9634Sdrh ** (2) Tell SQLite (via the sqlite3_declare_vtab() interface) what the 61*4ead9634Sdrh ** result set of queries against the virtual table will look like. 62*4ead9634Sdrh */ 63*4ead9634Sdrh static int prefixesConnect( 64*4ead9634Sdrh sqlite3 *db, 65*4ead9634Sdrh void *pAux, 66*4ead9634Sdrh int argc, const char *const*argv, 67*4ead9634Sdrh sqlite3_vtab **ppVtab, 68*4ead9634Sdrh char **pzErr 69*4ead9634Sdrh ){ 70*4ead9634Sdrh prefixes_vtab *pNew; 71*4ead9634Sdrh int rc; 72*4ead9634Sdrh 73*4ead9634Sdrh rc = sqlite3_declare_vtab(db, 74*4ead9634Sdrh "CREATE TABLE prefixes(prefix TEXT, original_string TEXT HIDDEN)" 75*4ead9634Sdrh ); 76*4ead9634Sdrh if( rc==SQLITE_OK ){ 77*4ead9634Sdrh pNew = sqlite3_malloc( sizeof(*pNew) ); 78*4ead9634Sdrh *ppVtab = (sqlite3_vtab*)pNew; 79*4ead9634Sdrh if( pNew==0 ) return SQLITE_NOMEM; 80*4ead9634Sdrh memset(pNew, 0, sizeof(*pNew)); 81*4ead9634Sdrh } 82*4ead9634Sdrh return rc; 83*4ead9634Sdrh } 84*4ead9634Sdrh 85*4ead9634Sdrh /* 86*4ead9634Sdrh ** This method is the destructor for prefixes_vtab objects. 87*4ead9634Sdrh */ 88*4ead9634Sdrh static int prefixesDisconnect(sqlite3_vtab *pVtab){ 89*4ead9634Sdrh prefixes_vtab *p = (prefixes_vtab*)pVtab; 90*4ead9634Sdrh sqlite3_free(p); 91*4ead9634Sdrh return SQLITE_OK; 92*4ead9634Sdrh } 93*4ead9634Sdrh 94*4ead9634Sdrh /* 95*4ead9634Sdrh ** Constructor for a new prefixes_cursor object. 96*4ead9634Sdrh */ 97*4ead9634Sdrh static int prefixesOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){ 98*4ead9634Sdrh prefixes_cursor *pCur; 99*4ead9634Sdrh pCur = sqlite3_malloc( sizeof(*pCur) ); 100*4ead9634Sdrh if( pCur==0 ) return SQLITE_NOMEM; 101*4ead9634Sdrh memset(pCur, 0, sizeof(*pCur)); 102*4ead9634Sdrh *ppCursor = &pCur->base; 103*4ead9634Sdrh return SQLITE_OK; 104*4ead9634Sdrh } 105*4ead9634Sdrh 106*4ead9634Sdrh /* 107*4ead9634Sdrh ** Destructor for a prefixes_cursor. 108*4ead9634Sdrh */ 109*4ead9634Sdrh static int prefixesClose(sqlite3_vtab_cursor *cur){ 110*4ead9634Sdrh prefixes_cursor *pCur = (prefixes_cursor*)cur; 111*4ead9634Sdrh sqlite3_free(pCur->zStr); 112*4ead9634Sdrh sqlite3_free(pCur); 113*4ead9634Sdrh return SQLITE_OK; 114*4ead9634Sdrh } 115*4ead9634Sdrh 116*4ead9634Sdrh 117*4ead9634Sdrh /* 118*4ead9634Sdrh ** Advance a prefixes_cursor to its next row of output. 119*4ead9634Sdrh */ 120*4ead9634Sdrh static int prefixesNext(sqlite3_vtab_cursor *cur){ 121*4ead9634Sdrh prefixes_cursor *pCur = (prefixes_cursor*)cur; 122*4ead9634Sdrh pCur->iRowid++; 123*4ead9634Sdrh return SQLITE_OK; 124*4ead9634Sdrh } 125*4ead9634Sdrh 126*4ead9634Sdrh /* 127*4ead9634Sdrh ** Return values of columns for the row at which the prefixes_cursor 128*4ead9634Sdrh ** is currently pointing. 129*4ead9634Sdrh */ 130*4ead9634Sdrh static int prefixesColumn( 131*4ead9634Sdrh sqlite3_vtab_cursor *cur, /* The cursor */ 132*4ead9634Sdrh sqlite3_context *ctx, /* First argument to sqlite3_result_...() */ 133*4ead9634Sdrh int i /* Which column to return */ 134*4ead9634Sdrh ){ 135*4ead9634Sdrh prefixes_cursor *pCur = (prefixes_cursor*)cur; 136*4ead9634Sdrh switch( i ){ 137*4ead9634Sdrh case 0: 138*4ead9634Sdrh sqlite3_result_text(ctx, pCur->zStr, pCur->nStr - (int)pCur->iRowid, 139*4ead9634Sdrh 0); 140*4ead9634Sdrh break; 141*4ead9634Sdrh default: 142*4ead9634Sdrh sqlite3_result_text(ctx, pCur->zStr, pCur->nStr, 0); 143*4ead9634Sdrh break; 144*4ead9634Sdrh } 145*4ead9634Sdrh return SQLITE_OK; 146*4ead9634Sdrh } 147*4ead9634Sdrh 148*4ead9634Sdrh /* 149*4ead9634Sdrh ** Return the rowid for the current row. In this implementation, the 150*4ead9634Sdrh ** rowid is the same as the output value. 151*4ead9634Sdrh */ 152*4ead9634Sdrh static int prefixesRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){ 153*4ead9634Sdrh prefixes_cursor *pCur = (prefixes_cursor*)cur; 154*4ead9634Sdrh *pRowid = pCur->iRowid; 155*4ead9634Sdrh return SQLITE_OK; 156*4ead9634Sdrh } 157*4ead9634Sdrh 158*4ead9634Sdrh /* 159*4ead9634Sdrh ** Return TRUE if the cursor has been moved off of the last 160*4ead9634Sdrh ** row of output. 161*4ead9634Sdrh */ 162*4ead9634Sdrh static int prefixesEof(sqlite3_vtab_cursor *cur){ 163*4ead9634Sdrh prefixes_cursor *pCur = (prefixes_cursor*)cur; 164*4ead9634Sdrh return pCur->iRowid>pCur->nStr; 165*4ead9634Sdrh } 166*4ead9634Sdrh 167*4ead9634Sdrh /* 168*4ead9634Sdrh ** This method is called to "rewind" the prefixes_cursor object back 169*4ead9634Sdrh ** to the first row of output. This method is always called at least 170*4ead9634Sdrh ** once prior to any call to prefixesColumn() or prefixesRowid() or 171*4ead9634Sdrh ** prefixesEof(). 172*4ead9634Sdrh */ 173*4ead9634Sdrh static int prefixesFilter( 174*4ead9634Sdrh sqlite3_vtab_cursor *pVtabCursor, 175*4ead9634Sdrh int idxNum, const char *idxStr, 176*4ead9634Sdrh int argc, sqlite3_value **argv 177*4ead9634Sdrh ){ 178*4ead9634Sdrh prefixes_cursor *pCur = (prefixes_cursor *)pVtabCursor; 179*4ead9634Sdrh sqlite3_free(pCur->zStr); 180*4ead9634Sdrh if( argc>0 ){ 181*4ead9634Sdrh pCur->zStr = sqlite3_mprintf("%s", sqlite3_value_text(argv[0])); 182*4ead9634Sdrh pCur->nStr = pCur->zStr ? (int)strlen(pCur->zStr) : 0; 183*4ead9634Sdrh }else{ 184*4ead9634Sdrh pCur->zStr = 0; 185*4ead9634Sdrh pCur->nStr = 0; 186*4ead9634Sdrh } 187*4ead9634Sdrh pCur->iRowid = 0; 188*4ead9634Sdrh return SQLITE_OK; 189*4ead9634Sdrh } 190*4ead9634Sdrh 191*4ead9634Sdrh /* 192*4ead9634Sdrh ** SQLite will invoke this method one or more times while planning a query 193*4ead9634Sdrh ** that uses the virtual table. This routine needs to create 194*4ead9634Sdrh ** a query plan for each invocation and compute an estimated cost for that 195*4ead9634Sdrh ** plan. 196*4ead9634Sdrh */ 197*4ead9634Sdrh static int prefixesBestIndex( 198*4ead9634Sdrh sqlite3_vtab *tab, 199*4ead9634Sdrh sqlite3_index_info *pIdxInfo 200*4ead9634Sdrh ){ 201*4ead9634Sdrh /* Search for a usable equality constraint against column 1 202*4ead9634Sdrh ** (original_string) and use it if at all possible */ 203*4ead9634Sdrh int i; 204*4ead9634Sdrh const struct sqlite3_index_constraint *p; 205*4ead9634Sdrh 206*4ead9634Sdrh for(i=0, p=pIdxInfo->aConstraint; i<pIdxInfo->nConstraint; i++, p++){ 207*4ead9634Sdrh if( p->iColumn!=1 ) continue; 208*4ead9634Sdrh if( p->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue; 209*4ead9634Sdrh if( !p->usable ) continue; 210*4ead9634Sdrh pIdxInfo->aConstraintUsage[i].argvIndex = 1; 211*4ead9634Sdrh pIdxInfo->aConstraintUsage[i].omit = 1; 212*4ead9634Sdrh pIdxInfo->estimatedCost = (double)10; 213*4ead9634Sdrh pIdxInfo->estimatedRows = 10; 214*4ead9634Sdrh return SQLITE_OK; 215*4ead9634Sdrh } 216*4ead9634Sdrh pIdxInfo->estimatedCost = (double)1000000000; 217*4ead9634Sdrh pIdxInfo->estimatedRows = 1000000000; 218*4ead9634Sdrh return SQLITE_OK; 219*4ead9634Sdrh } 220*4ead9634Sdrh 221*4ead9634Sdrh /* 222*4ead9634Sdrh ** This following structure defines all the methods for the 223*4ead9634Sdrh ** virtual table. 224*4ead9634Sdrh */ 225*4ead9634Sdrh static sqlite3_module prefixesModule = { 226*4ead9634Sdrh /* iVersion */ 0, 227*4ead9634Sdrh /* xCreate */ 0, 228*4ead9634Sdrh /* xConnect */ prefixesConnect, 229*4ead9634Sdrh /* xBestIndex */ prefixesBestIndex, 230*4ead9634Sdrh /* xDisconnect */ prefixesDisconnect, 231*4ead9634Sdrh /* xDestroy */ 0, 232*4ead9634Sdrh /* xOpen */ prefixesOpen, 233*4ead9634Sdrh /* xClose */ prefixesClose, 234*4ead9634Sdrh /* xFilter */ prefixesFilter, 235*4ead9634Sdrh /* xNext */ prefixesNext, 236*4ead9634Sdrh /* xEof */ prefixesEof, 237*4ead9634Sdrh /* xColumn */ prefixesColumn, 238*4ead9634Sdrh /* xRowid */ prefixesRowid, 239*4ead9634Sdrh /* xUpdate */ 0, 240*4ead9634Sdrh /* xBegin */ 0, 241*4ead9634Sdrh /* xSync */ 0, 242*4ead9634Sdrh /* xCommit */ 0, 243*4ead9634Sdrh /* xRollback */ 0, 244*4ead9634Sdrh /* xFindMethod */ 0, 245*4ead9634Sdrh /* xRename */ 0, 246*4ead9634Sdrh /* xSavepoint */ 0, 247*4ead9634Sdrh /* xRelease */ 0, 248*4ead9634Sdrh /* xRollbackTo */ 0, 249*4ead9634Sdrh /* xShadowName */ 0 250*4ead9634Sdrh }; 251*4ead9634Sdrh 252*4ead9634Sdrh 253*4ead9634Sdrh #ifdef _WIN32 254*4ead9634Sdrh __declspec(dllexport) 255*4ead9634Sdrh #endif 256*4ead9634Sdrh int sqlite3_prefixes_init( 257*4ead9634Sdrh sqlite3 *db, 258*4ead9634Sdrh char **pzErrMsg, 259*4ead9634Sdrh const sqlite3_api_routines *pApi 260*4ead9634Sdrh ){ 261*4ead9634Sdrh int rc = SQLITE_OK; 262*4ead9634Sdrh SQLITE_EXTENSION_INIT2(pApi); 263*4ead9634Sdrh rc = sqlite3_create_module(db, "prefixes", &prefixesModule, 0); 264*4ead9634Sdrh return rc; 265*4ead9634Sdrh } 266