Enhance the command-line completion extension to return the names of
[sqlite.git] / ext / misc / wholenumber.c
blob63369c6ac474e1cae1b4309f78536166ebc716a5
1 /*
2 ** 2011 April 02
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.
11 *************************************************************************
13 ** This file implements a virtual table that returns the whole numbers
14 ** between 1 and 4294967295, inclusive.
16 ** Example:
18 ** CREATE VIRTUAL TABLE nums USING wholenumber;
19 ** SELECT value FROM nums WHERE value<10;
21 ** Results in:
23 ** 1 2 3 4 5 6 7 8 9
25 #include "sqlite3ext.h"
26 SQLITE_EXTENSION_INIT1
27 #include <assert.h>
28 #include <string.h>
30 #ifndef SQLITE_OMIT_VIRTUALTABLE
33 /* A wholenumber cursor object */
34 typedef struct wholenumber_cursor wholenumber_cursor;
35 struct wholenumber_cursor {
36 sqlite3_vtab_cursor base; /* Base class - must be first */
37 sqlite3_int64 iValue; /* Current value */
38 sqlite3_int64 mxValue; /* Maximum value */
41 /* Methods for the wholenumber module */
42 static int wholenumberConnect(
43 sqlite3 *db,
44 void *pAux,
45 int argc, const char *const*argv,
46 sqlite3_vtab **ppVtab,
47 char **pzErr
49 sqlite3_vtab *pNew;
50 pNew = *ppVtab = sqlite3_malloc( sizeof(*pNew) );
51 if( pNew==0 ) return SQLITE_NOMEM;
52 sqlite3_declare_vtab(db, "CREATE TABLE x(value)");
53 memset(pNew, 0, sizeof(*pNew));
54 return SQLITE_OK;
56 /* Note that for this virtual table, the xCreate and xConnect
57 ** methods are identical. */
59 static int wholenumberDisconnect(sqlite3_vtab *pVtab){
60 sqlite3_free(pVtab);
61 return SQLITE_OK;
63 /* The xDisconnect and xDestroy methods are also the same */
67 ** Open a new wholenumber cursor.
69 static int wholenumberOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
70 wholenumber_cursor *pCur;
71 pCur = sqlite3_malloc( sizeof(*pCur) );
72 if( pCur==0 ) return SQLITE_NOMEM;
73 memset(pCur, 0, sizeof(*pCur));
74 *ppCursor = &pCur->base;
75 return SQLITE_OK;
79 ** Close a wholenumber cursor.
81 static int wholenumberClose(sqlite3_vtab_cursor *cur){
82 sqlite3_free(cur);
83 return SQLITE_OK;
88 ** Advance a cursor to its next row of output
90 static int wholenumberNext(sqlite3_vtab_cursor *cur){
91 wholenumber_cursor *pCur = (wholenumber_cursor*)cur;
92 pCur->iValue++;
93 return SQLITE_OK;
97 ** Return the value associated with a wholenumber.
99 static int wholenumberColumn(
100 sqlite3_vtab_cursor *cur,
101 sqlite3_context *ctx,
102 int i
104 wholenumber_cursor *pCur = (wholenumber_cursor*)cur;
105 sqlite3_result_int64(ctx, pCur->iValue);
106 return SQLITE_OK;
110 ** The rowid.
112 static int wholenumberRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
113 wholenumber_cursor *pCur = (wholenumber_cursor*)cur;
114 *pRowid = pCur->iValue;
115 return SQLITE_OK;
119 ** When the wholenumber_cursor.rLimit value is 0 or less, that is a signal
120 ** that the cursor has nothing more to output.
122 static int wholenumberEof(sqlite3_vtab_cursor *cur){
123 wholenumber_cursor *pCur = (wholenumber_cursor*)cur;
124 return pCur->iValue>pCur->mxValue || pCur->iValue==0;
128 ** Called to "rewind" a cursor back to the beginning so that
129 ** it starts its output over again. Always called at least once
130 ** prior to any wholenumberColumn, wholenumberRowid, or wholenumberEof call.
132 ** idxNum Constraints
133 ** ------ ---------------------
134 ** 0 (none)
135 ** 1 value > $argv0
136 ** 2 value >= $argv0
137 ** 4 value < $argv0
138 ** 8 value <= $argv0
140 ** 5 value > $argv0 AND value < $argv1
141 ** 6 value >= $argv0 AND value < $argv1
142 ** 9 value > $argv0 AND value <= $argv1
143 ** 10 value >= $argv0 AND value <= $argv1
145 static int wholenumberFilter(
146 sqlite3_vtab_cursor *pVtabCursor,
147 int idxNum, const char *idxStr,
148 int argc, sqlite3_value **argv
150 wholenumber_cursor *pCur = (wholenumber_cursor *)pVtabCursor;
151 sqlite3_int64 v;
152 int i = 0;
153 pCur->iValue = 1;
154 pCur->mxValue = 0xffffffff; /* 4294967295 */
155 if( idxNum & 3 ){
156 v = sqlite3_value_int64(argv[0]) + (idxNum&1);
157 if( v>pCur->iValue && v<=pCur->mxValue ) pCur->iValue = v;
158 i++;
160 if( idxNum & 12 ){
161 v = sqlite3_value_int64(argv[i]) - ((idxNum>>2)&1);
162 if( v>=pCur->iValue && v<pCur->mxValue ) pCur->mxValue = v;
164 return SQLITE_OK;
168 ** Search for terms of these forms:
170 ** (1) value > $value
171 ** (2) value >= $value
172 ** (4) value < $value
173 ** (8) value <= $value
175 ** idxNum is an ORed combination of 1 or 2 with 4 or 8.
177 static int wholenumberBestIndex(
178 sqlite3_vtab *tab,
179 sqlite3_index_info *pIdxInfo
181 int i;
182 int idxNum = 0;
183 int argvIdx = 1;
184 int ltIdx = -1;
185 int gtIdx = -1;
186 const struct sqlite3_index_constraint *pConstraint;
187 pConstraint = pIdxInfo->aConstraint;
188 for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
189 if( pConstraint->usable==0 ) continue;
190 if( (idxNum & 3)==0 && pConstraint->op==SQLITE_INDEX_CONSTRAINT_GT ){
191 idxNum |= 1;
192 ltIdx = i;
194 if( (idxNum & 3)==0 && pConstraint->op==SQLITE_INDEX_CONSTRAINT_GE ){
195 idxNum |= 2;
196 ltIdx = i;
198 if( (idxNum & 12)==0 && pConstraint->op==SQLITE_INDEX_CONSTRAINT_LT ){
199 idxNum |= 4;
200 gtIdx = i;
202 if( (idxNum & 12)==0 && pConstraint->op==SQLITE_INDEX_CONSTRAINT_LE ){
203 idxNum |= 8;
204 gtIdx = i;
207 pIdxInfo->idxNum = idxNum;
208 if( ltIdx>=0 ){
209 pIdxInfo->aConstraintUsage[ltIdx].argvIndex = argvIdx++;
210 pIdxInfo->aConstraintUsage[ltIdx].omit = 1;
212 if( gtIdx>=0 ){
213 pIdxInfo->aConstraintUsage[gtIdx].argvIndex = argvIdx;
214 pIdxInfo->aConstraintUsage[gtIdx].omit = 1;
216 if( pIdxInfo->nOrderBy==1
217 && pIdxInfo->aOrderBy[0].desc==0
219 pIdxInfo->orderByConsumed = 1;
221 if( (idxNum & 12)==0 ){
222 pIdxInfo->estimatedCost = (double)100000000;
223 }else if( (idxNum & 3)==0 ){
224 pIdxInfo->estimatedCost = (double)5;
225 }else{
226 pIdxInfo->estimatedCost = (double)1;
228 return SQLITE_OK;
232 ** A virtual table module that provides read-only access to a
233 ** Tcl global variable namespace.
235 static sqlite3_module wholenumberModule = {
236 0, /* iVersion */
237 wholenumberConnect,
238 wholenumberConnect,
239 wholenumberBestIndex,
240 wholenumberDisconnect,
241 wholenumberDisconnect,
242 wholenumberOpen, /* xOpen - open a cursor */
243 wholenumberClose, /* xClose - close a cursor */
244 wholenumberFilter, /* xFilter - configure scan constraints */
245 wholenumberNext, /* xNext - advance a cursor */
246 wholenumberEof, /* xEof - check for end of scan */
247 wholenumberColumn, /* xColumn - read data */
248 wholenumberRowid, /* xRowid - read data */
249 0, /* xUpdate */
250 0, /* xBegin */
251 0, /* xSync */
252 0, /* xCommit */
253 0, /* xRollback */
254 0, /* xFindMethod */
255 0, /* xRename */
258 #endif /* SQLITE_OMIT_VIRTUALTABLE */
260 #ifdef _WIN32
261 __declspec(dllexport)
262 #endif
263 int sqlite3_wholenumber_init(
264 sqlite3 *db,
265 char **pzErrMsg,
266 const sqlite3_api_routines *pApi
268 int rc = SQLITE_OK;
269 SQLITE_EXTENSION_INIT2(pApi);
270 #ifndef SQLITE_OMIT_VIRTUALTABLE
271 rc = sqlite3_create_module(db, "wholenumber", &wholenumberModule, 0);
272 #endif
273 return rc;