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 sqlite3_vtab_config(db
, SQLITE_VTAB_INNOCUOUS
);
54 memset(pNew
, 0, sizeof(*pNew
));
57 /* Note that for this virtual table, the xCreate and xConnect
58 ** methods are identical. */
60 static int wholenumberDisconnect(sqlite3_vtab
*pVtab
){
64 /* The xDisconnect and xDestroy methods are also the same */
68 ** Open a new wholenumber cursor.
70 static int wholenumberOpen(sqlite3_vtab
*p
, sqlite3_vtab_cursor
**ppCursor
){
71 wholenumber_cursor
*pCur
;
72 pCur
= sqlite3_malloc( sizeof(*pCur
) );
73 if( pCur
==0 ) return SQLITE_NOMEM
;
74 memset(pCur
, 0, sizeof(*pCur
));
75 *ppCursor
= &pCur
->base
;
80 ** Close a wholenumber cursor.
82 static int wholenumberClose(sqlite3_vtab_cursor
*cur
){
89 ** Advance a cursor to its next row of output
91 static int wholenumberNext(sqlite3_vtab_cursor
*cur
){
92 wholenumber_cursor
*pCur
= (wholenumber_cursor
*)cur
;
98 ** Return the value associated with a wholenumber.
100 static int wholenumberColumn(
101 sqlite3_vtab_cursor
*cur
,
102 sqlite3_context
*ctx
,
105 wholenumber_cursor
*pCur
= (wholenumber_cursor
*)cur
;
106 sqlite3_result_int64(ctx
, pCur
->iValue
);
113 static int wholenumberRowid(sqlite3_vtab_cursor
*cur
, sqlite_int64
*pRowid
){
114 wholenumber_cursor
*pCur
= (wholenumber_cursor
*)cur
;
115 *pRowid
= pCur
->iValue
;
120 ** When the wholenumber_cursor.rLimit value is 0 or less, that is a signal
121 ** that the cursor has nothing more to output.
123 static int wholenumberEof(sqlite3_vtab_cursor
*cur
){
124 wholenumber_cursor
*pCur
= (wholenumber_cursor
*)cur
;
125 return pCur
->iValue
>pCur
->mxValue
|| pCur
->iValue
==0;
129 ** Called to "rewind" a cursor back to the beginning so that
130 ** it starts its output over again. Always called at least once
131 ** prior to any wholenumberColumn, wholenumberRowid, or wholenumberEof call.
133 ** idxNum Constraints
134 ** ------ ---------------------
141 ** 5 value > $argv0 AND value < $argv1
142 ** 6 value >= $argv0 AND value < $argv1
143 ** 9 value > $argv0 AND value <= $argv1
144 ** 10 value >= $argv0 AND value <= $argv1
146 static int wholenumberFilter(
147 sqlite3_vtab_cursor
*pVtabCursor
,
148 int idxNum
, const char *idxStr
,
149 int argc
, sqlite3_value
**argv
151 wholenumber_cursor
*pCur
= (wholenumber_cursor
*)pVtabCursor
;
155 pCur
->mxValue
= 0xffffffff; /* 4294967295 */
157 v
= sqlite3_value_int64(argv
[0]) + (idxNum
&1);
158 if( v
>pCur
->iValue
&& v
<=pCur
->mxValue
) pCur
->iValue
= v
;
162 v
= sqlite3_value_int64(argv
[i
]) - ((idxNum
>>2)&1);
163 if( v
>=pCur
->iValue
&& v
<pCur
->mxValue
) pCur
->mxValue
= v
;
169 ** Search for terms of these forms:
171 ** (1) value > $value
172 ** (2) value >= $value
173 ** (4) value < $value
174 ** (8) value <= $value
176 ** idxNum is an ORed combination of 1 or 2 with 4 or 8.
178 static int wholenumberBestIndex(
180 sqlite3_index_info
*pIdxInfo
187 const struct sqlite3_index_constraint
*pConstraint
;
188 pConstraint
= pIdxInfo
->aConstraint
;
189 for(i
=0; i
<pIdxInfo
->nConstraint
; i
++, pConstraint
++){
190 if( pConstraint
->usable
==0 ) continue;
191 if( (idxNum
& 3)==0 && pConstraint
->op
==SQLITE_INDEX_CONSTRAINT_GT
){
195 if( (idxNum
& 3)==0 && pConstraint
->op
==SQLITE_INDEX_CONSTRAINT_GE
){
199 if( (idxNum
& 12)==0 && pConstraint
->op
==SQLITE_INDEX_CONSTRAINT_LT
){
203 if( (idxNum
& 12)==0 && pConstraint
->op
==SQLITE_INDEX_CONSTRAINT_LE
){
208 pIdxInfo
->idxNum
= idxNum
;
210 pIdxInfo
->aConstraintUsage
[ltIdx
].argvIndex
= argvIdx
++;
211 pIdxInfo
->aConstraintUsage
[ltIdx
].omit
= 1;
214 pIdxInfo
->aConstraintUsage
[gtIdx
].argvIndex
= argvIdx
;
215 pIdxInfo
->aConstraintUsage
[gtIdx
].omit
= 1;
217 if( pIdxInfo
->nOrderBy
==1
218 && pIdxInfo
->aOrderBy
[0].desc
==0
220 pIdxInfo
->orderByConsumed
= 1;
222 if( (idxNum
& 12)==0 ){
223 pIdxInfo
->estimatedCost
= 1e99
;
224 }else if( (idxNum
& 3)==0 ){
225 pIdxInfo
->estimatedCost
= (double)5;
227 pIdxInfo
->estimatedCost
= (double)1;
233 ** A virtual table module that provides read-only access to a
234 ** Tcl global variable namespace.
236 static sqlite3_module wholenumberModule
= {
240 wholenumberBestIndex
,
241 wholenumberDisconnect
,
242 wholenumberDisconnect
,
243 wholenumberOpen
, /* xOpen - open a cursor */
244 wholenumberClose
, /* xClose - close a cursor */
245 wholenumberFilter
, /* xFilter - configure scan constraints */
246 wholenumberNext
, /* xNext - advance a cursor */
247 wholenumberEof
, /* xEof - check for end of scan */
248 wholenumberColumn
, /* xColumn - read data */
249 wholenumberRowid
, /* xRowid - read data */
264 #endif /* SQLITE_OMIT_VIRTUALTABLE */
267 __declspec(dllexport
)
269 int sqlite3_wholenumber_init(
272 const sqlite3_api_routines
*pApi
275 SQLITE_EXTENSION_INIT2(pApi
);
276 #ifndef SQLITE_OMIT_VIRTUALTABLE
277 rc
= sqlite3_create_module(db
, "wholenumber", &wholenumberModule
, 0);