4 ** The author disclaims copyright to this source code. In place of
5 ** a legal notice, here is a blessing:
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.
18 ** CREATE VIRTUAL TABLE nums USING wholenumber;
19 ** SELECT value FROM nums WHERE value<10;
25 #include "sqlite3ext.h"
26 SQLITE_EXTENSION_INIT1
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(
45 int argc
, const char *const*argv
,
46 sqlite3_vtab
**ppVtab
,
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
));
56 /* Note that for this virtual table, the xCreate and xConnect
57 ** methods are identical. */
59 static int wholenumberDisconnect(sqlite3_vtab
*pVtab
){
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
;
79 ** Close a wholenumber cursor.
81 static int wholenumberClose(sqlite3_vtab_cursor
*cur
){
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
;
97 ** Return the value associated with a wholenumber.
99 static int wholenumberColumn(
100 sqlite3_vtab_cursor
*cur
,
101 sqlite3_context
*ctx
,
104 wholenumber_cursor
*pCur
= (wholenumber_cursor
*)cur
;
105 sqlite3_result_int64(ctx
, pCur
->iValue
);
112 static int wholenumberRowid(sqlite3_vtab_cursor
*cur
, sqlite_int64
*pRowid
){
113 wholenumber_cursor
*pCur
= (wholenumber_cursor
*)cur
;
114 *pRowid
= pCur
->iValue
;
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 ** ------ ---------------------
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
;
154 pCur
->mxValue
= 0xffffffff; /* 4294967295 */
156 v
= sqlite3_value_int64(argv
[0]) + (idxNum
&1);
157 if( v
>pCur
->iValue
&& v
<=pCur
->mxValue
) pCur
->iValue
= v
;
161 v
= sqlite3_value_int64(argv
[i
]) - ((idxNum
>>2)&1);
162 if( v
>=pCur
->iValue
&& v
<pCur
->mxValue
) pCur
->mxValue
= v
;
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(
179 sqlite3_index_info
*pIdxInfo
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
){
194 if( (idxNum
& 3)==0 && pConstraint
->op
==SQLITE_INDEX_CONSTRAINT_GE
){
198 if( (idxNum
& 12)==0 && pConstraint
->op
==SQLITE_INDEX_CONSTRAINT_LT
){
202 if( (idxNum
& 12)==0 && pConstraint
->op
==SQLITE_INDEX_CONSTRAINT_LE
){
207 pIdxInfo
->idxNum
= idxNum
;
209 pIdxInfo
->aConstraintUsage
[ltIdx
].argvIndex
= argvIdx
++;
210 pIdxInfo
->aConstraintUsage
[ltIdx
].omit
= 1;
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;
226 pIdxInfo
->estimatedCost
= (double)1;
232 ** A virtual table module that provides read-only access to a
233 ** Tcl global variable namespace.
235 static sqlite3_module wholenumberModule
= {
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 */
258 #endif /* SQLITE_OMIT_VIRTUALTABLE */
261 __declspec(dllexport
)
263 int sqlite3_wholenumber_init(
266 const sqlite3_api_routines
*pApi
269 SQLITE_EXTENSION_INIT2(pApi
);
270 #ifndef SQLITE_OMIT_VIRTUALTABLE
271 rc
= sqlite3_create_module(db
, "wholenumber", &wholenumberModule
, 0);