Fixes default log output to console for macOS
[sqlcipher.git] / ext / misc / wholenumber.c
blob4c955925da4a23a8f0a1fb76c62a44ffe6eecf15
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 sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS);
54 memset(pNew, 0, sizeof(*pNew));
55 return SQLITE_OK;
57 /* Note that for this virtual table, the xCreate and xConnect
58 ** methods are identical. */
60 static int wholenumberDisconnect(sqlite3_vtab *pVtab){
61 sqlite3_free(pVtab);
62 return SQLITE_OK;
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;
76 return SQLITE_OK;
80 ** Close a wholenumber cursor.
82 static int wholenumberClose(sqlite3_vtab_cursor *cur){
83 sqlite3_free(cur);
84 return SQLITE_OK;
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;
93 pCur->iValue++;
94 return SQLITE_OK;
98 ** Return the value associated with a wholenumber.
100 static int wholenumberColumn(
101 sqlite3_vtab_cursor *cur,
102 sqlite3_context *ctx,
103 int i
105 wholenumber_cursor *pCur = (wholenumber_cursor*)cur;
106 sqlite3_result_int64(ctx, pCur->iValue);
107 return SQLITE_OK;
111 ** The rowid.
113 static int wholenumberRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
114 wholenumber_cursor *pCur = (wholenumber_cursor*)cur;
115 *pRowid = pCur->iValue;
116 return SQLITE_OK;
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 ** ------ ---------------------
135 ** 0 (none)
136 ** 1 value > $argv0
137 ** 2 value >= $argv0
138 ** 4 value < $argv0
139 ** 8 value <= $argv0
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;
152 sqlite3_int64 v;
153 int i = 0;
154 pCur->iValue = 1;
155 pCur->mxValue = 0xffffffff; /* 4294967295 */
156 if( idxNum & 3 ){
157 v = sqlite3_value_int64(argv[0]) + (idxNum&1);
158 if( v>pCur->iValue && v<=pCur->mxValue ) pCur->iValue = v;
159 i++;
161 if( idxNum & 12 ){
162 v = sqlite3_value_int64(argv[i]) - ((idxNum>>2)&1);
163 if( v>=pCur->iValue && v<pCur->mxValue ) pCur->mxValue = v;
165 return SQLITE_OK;
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(
179 sqlite3_vtab *tab,
180 sqlite3_index_info *pIdxInfo
182 int i;
183 int idxNum = 0;
184 int argvIdx = 1;
185 int ltIdx = -1;
186 int gtIdx = -1;
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 ){
192 idxNum |= 1;
193 ltIdx = i;
195 if( (idxNum & 3)==0 && pConstraint->op==SQLITE_INDEX_CONSTRAINT_GE ){
196 idxNum |= 2;
197 ltIdx = i;
199 if( (idxNum & 12)==0 && pConstraint->op==SQLITE_INDEX_CONSTRAINT_LT ){
200 idxNum |= 4;
201 gtIdx = i;
203 if( (idxNum & 12)==0 && pConstraint->op==SQLITE_INDEX_CONSTRAINT_LE ){
204 idxNum |= 8;
205 gtIdx = i;
208 pIdxInfo->idxNum = idxNum;
209 if( ltIdx>=0 ){
210 pIdxInfo->aConstraintUsage[ltIdx].argvIndex = argvIdx++;
211 pIdxInfo->aConstraintUsage[ltIdx].omit = 1;
213 if( gtIdx>=0 ){
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;
226 }else{
227 pIdxInfo->estimatedCost = (double)1;
229 return SQLITE_OK;
233 ** A virtual table module that provides read-only access to a
234 ** Tcl global variable namespace.
236 static sqlite3_module wholenumberModule = {
237 0, /* iVersion */
238 wholenumberConnect,
239 wholenumberConnect,
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 */
250 0, /* xUpdate */
251 0, /* xBegin */
252 0, /* xSync */
253 0, /* xCommit */
254 0, /* xRollback */
255 0, /* xFindMethod */
256 0, /* xRename */
257 0, /* xSavepoint */
258 0, /* xRelease */
259 0, /* xRollbackTo */
260 0, /* xShadowName */
261 0 /* xIntegrity */
264 #endif /* SQLITE_OMIT_VIRTUALTABLE */
266 #ifdef _WIN32
267 __declspec(dllexport)
268 #endif
269 int sqlite3_wholenumber_init(
270 sqlite3 *db,
271 char **pzErrMsg,
272 const sqlite3_api_routines *pApi
274 int rc = SQLITE_OK;
275 SQLITE_EXTENSION_INIT2(pApi);
276 #ifndef SQLITE_OMIT_VIRTUALTABLE
277 rc = sqlite3_create_module(db, "wholenumber", &wholenumberModule, 0);
278 #endif
279 return rc;