Fix compiler warnings.
[sqlite.git] / ext / misc / unionvtab.c
blob92d0b833c490242132bf9928c31d69d8a1ea7603
1 /*
2 ** 2017 July 15
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 contains the implementation of the "unionvtab" and "swarmvtab"
14 ** virtual tables. These modules provide read-only access to multiple tables,
15 ** possibly in multiple database files, via a single database object.
16 ** The source tables must have the following characteristics:
18 ** * They must all be rowid tables (not VIRTUAL or WITHOUT ROWID
19 ** tables or views).
21 ** * Each table must have the same set of columns, declared in
22 ** the same order and with the same declared types.
24 ** * The tables must not feature a user-defined column named "_rowid_".
26 ** * Each table must contain a distinct range of rowid values.
28 ** The difference between the two virtual table modules is that for
29 ** "unionvtab", all source tables must be located in the main database or
30 ** in databases ATTACHed to the main database by the user. For "swarmvtab",
31 ** the tables may be located in any database file on disk. The "swarmvtab"
32 ** implementation takes care of opening and closing database files
33 ** automatically.
35 ** UNIONVTAB
37 ** A "unionvtab" virtual table is created as follows:
39 ** CREATE VIRTUAL TABLE <name> USING unionvtab(<sql-statement>);
41 ** The implementation evalutes <sql statement> whenever a unionvtab virtual
42 ** table is created or opened. It should return one row for each source
43 ** database table. The four columns required of each row are:
45 ** 1. The name of the database containing the table ("main" or "temp" or
46 ** the name of an attached database). Or NULL to indicate that all
47 ** databases should be searched for the table in the usual fashion.
49 ** 2. The name of the database table.
51 ** 3. The smallest rowid in the range of rowids that may be stored in the
52 ** database table (an integer).
54 ** 4. The largest rowid in the range of rowids that may be stored in the
55 ** database table (an integer).
57 ** SWARMVTAB
59 ** LEGACY SYNTAX:
61 ** A "swarmvtab" virtual table is created similarly to a unionvtab table:
63 ** CREATE VIRTUAL TABLE <name>
64 ** USING swarmvtab(<sql-statement>, <callback>);
66 ** The difference is that for a swarmvtab table, the first column returned
67 ** by the <sql statement> must return a path or URI that can be used to open
68 ** the database file containing the source table. The <callback> option
69 ** is optional. If included, it is the name of an application-defined
70 ** SQL function that is invoked with the URI of the file, if the file
71 ** does not already exist on disk when required by swarmvtab.
73 ** NEW SYNTAX:
75 ** Using the new syntax, a swarmvtab table is created with:
77 ** CREATE VIRTUAL TABLE <name> USING swarmvtab(
78 ** <sql-statement> [, <options>]
79 ** );
81 ** where valid <options> are:
83 ** missing=<udf-function-name>
84 ** openclose=<udf-function-name>
85 ** maxopen=<integer>
86 ** <sql-parameter>=<text-value>
88 ** The <sql-statement> must return the same 4 columns as for a swarmvtab
89 ** table in legacy mode. However, it may also return a 5th column - the
90 ** "context" column. The text value returned in this column is not used
91 ** at all by the swarmvtab implementation, except that it is passed as
92 ** an additional argument to the two UDF functions that may be invoked
93 ** (see below).
95 ** The "missing" option, if present, specifies the name of an SQL UDF
96 ** function to be invoked if a database file is not already present on
97 ** disk when required by swarmvtab. If the <sql-statement> did not provide
98 ** a context column, it is invoked as:
100 ** SELECT <missing-udf>(<database filename/uri>);
102 ** Or, if there was a context column:
104 ** SELECT <missing-udf>(<database filename/uri>, <context>);
106 ** The "openclose" option may also specify a UDF function. This function
107 ** is invoked right before swarmvtab opens a database, and right after
108 ** it closes one. The first argument - or first two arguments, if
109 ** <sql-statement> supplied the context column - is the same as for
110 ** the "missing" UDF. Following this, the UDF is passed integer value
111 ** 0 before a db is opened, and 1 right after it is closed. If both
112 ** a missing and openclose UDF is supplied, the application should expect
113 ** the following sequence of calls (for a single database):
115 ** SELECT <openclose-udf>(<db filename>, <context>, 0);
116 ** if( db not already on disk ){
117 ** SELECT <missing-udf>(<db filename>, <context>);
118 ** }
119 ** ... swarmvtab uses database ...
120 ** SELECT <openclose-udf>(<db filename>, <context>, 1);
122 ** The "maxopen" option is used to configure the maximum number of
123 ** database files swarmvtab will hold open simultaneously (default 9).
125 ** If an option name begins with a ":" character, then it is assumed
126 ** to be an SQL parameter. In this case, the specified text value is
127 ** bound to the same variable of the <sql-statement> before it is
128 ** executed. It is an error of the named SQL parameter does not exist.
129 ** For example:
131 ** CREATE VIRTUAL TABLE swarm USING swarmvtab(
132 ** 'SELECT :path || localfile, tbl, min, max FROM swarmdir',
133 ** :path='/home/user/databases/'
134 ** missing='missing_func'
135 ** );
138 #include "sqlite3ext.h"
139 SQLITE_EXTENSION_INIT1
140 #include <assert.h>
141 #include <string.h>
142 #include <stdlib.h>
144 #ifndef SQLITE_OMIT_VIRTUALTABLE
147 ** Largest and smallest possible 64-bit signed integers. These macros
148 ** copied from sqliteInt.h.
150 #ifndef LARGEST_INT64
151 # define LARGEST_INT64 (0xffffffff|(((sqlite3_int64)0x7fffffff)<<32))
152 #endif
153 #ifndef SMALLEST_INT64
154 # define SMALLEST_INT64 (((sqlite3_int64)-1) - LARGEST_INT64)
155 #endif
158 ** The following is also copied from sqliteInt.h. To facilitate coverage
159 ** testing.
161 #ifndef ALWAYS
162 # if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_MUTATION_TEST)
163 # define ALWAYS(X) (1)
164 # define NEVER(X) (0)
165 # elif !defined(NDEBUG)
166 # define ALWAYS(X) ((X)?1:(assert(0),0))
167 # define NEVER(X) ((X)?(assert(0),1):0)
168 # else
169 # define ALWAYS(X) (X)
170 # define NEVER(X) (X)
171 # endif
172 #endif
175 ** The swarmvtab module attempts to keep the number of open database files
176 ** at or below this limit. This may not be possible if there are too many
177 ** simultaneous queries.
179 #define SWARMVTAB_MAX_OPEN 9
181 typedef struct UnionCsr UnionCsr;
182 typedef struct UnionTab UnionTab;
183 typedef struct UnionSrc UnionSrc;
186 ** Each source table (row returned by the initialization query) is
187 ** represented by an instance of the following structure stored in the
188 ** UnionTab.aSrc[] array.
190 struct UnionSrc {
191 char *zDb; /* Database containing source table */
192 char *zTab; /* Source table name */
193 sqlite3_int64 iMin; /* Minimum rowid */
194 sqlite3_int64 iMax; /* Maximum rowid */
196 /* Fields used by swarmvtab only */
197 char *zFile; /* Database file containing table zTab */
198 char *zContext; /* Context string, if any */
199 int nUser; /* Current number of users */
200 sqlite3 *db; /* Database handle */
201 UnionSrc *pNextClosable; /* Next in list of closable sources */
205 ** Virtual table type for union vtab.
207 struct UnionTab {
208 sqlite3_vtab base; /* Base class - must be first */
209 sqlite3 *db; /* Database handle */
210 int bSwarm; /* 1 for "swarmvtab", 0 for "unionvtab" */
211 int iPK; /* INTEGER PRIMARY KEY column, or -1 */
212 int nSrc; /* Number of elements in the aSrc[] array */
213 UnionSrc *aSrc; /* Array of source tables, sorted by rowid */
215 /* Used by swarmvtab only */
216 int bHasContext; /* Has context strings */
217 char *zSourceStr; /* Expected unionSourceToStr() value */
218 sqlite3_stmt *pNotFound; /* UDF to invoke if file not found on open */
219 sqlite3_stmt *pOpenClose; /* UDF to invoke on open and close */
221 UnionSrc *pClosable; /* First in list of closable sources */
222 int nOpen; /* Current number of open sources */
223 int nMaxOpen; /* Maximum number of open sources */
227 ** Virtual table cursor type for union vtab.
229 struct UnionCsr {
230 sqlite3_vtab_cursor base; /* Base class - must be first */
231 sqlite3_stmt *pStmt; /* SQL statement to run */
233 /* Used by swarmvtab only */
234 sqlite3_int64 iMaxRowid; /* Last rowid to visit */
235 int iTab; /* Index of table read by pStmt */
239 ** Given UnionTab table pTab and UnionSrc object pSrc, return the database
240 ** handle that should be used to access the table identified by pSrc. This
241 ** is the main db handle for "unionvtab" tables, or the source-specific
242 ** handle for "swarmvtab".
244 #define unionGetDb(pTab, pSrc) ((pTab)->bSwarm ? (pSrc)->db : (pTab)->db)
247 ** If *pRc is other than SQLITE_OK when this function is called, it
248 ** always returns NULL. Otherwise, it attempts to allocate and return
249 ** a pointer to nByte bytes of zeroed memory. If the memory allocation
250 ** is attempted but fails, NULL is returned and *pRc is set to
251 ** SQLITE_NOMEM.
253 static void *unionMalloc(int *pRc, int nByte){
254 void *pRet;
255 assert( nByte>0 );
256 if( *pRc==SQLITE_OK ){
257 pRet = sqlite3_malloc(nByte);
258 if( pRet ){
259 memset(pRet, 0, nByte);
260 }else{
261 *pRc = SQLITE_NOMEM;
263 }else{
264 pRet = 0;
266 return pRet;
270 ** If *pRc is other than SQLITE_OK when this function is called, it
271 ** always returns NULL. Otherwise, it attempts to allocate and return
272 ** a copy of the nul-terminated string passed as the second argument.
273 ** If the allocation is attempted but fails, NULL is returned and *pRc is
274 ** set to SQLITE_NOMEM.
276 static char *unionStrdup(int *pRc, const char *zIn){
277 char *zRet = 0;
278 if( zIn ){
279 int nByte = (int)strlen(zIn) + 1;
280 zRet = unionMalloc(pRc, nByte);
281 if( zRet ){
282 memcpy(zRet, zIn, nByte);
285 return zRet;
289 ** If the first character of the string passed as the only argument to this
290 ** function is one of the 4 that may be used as an open quote character
291 ** in SQL, this function assumes that the input is a well-formed quoted SQL
292 ** string. In this case the string is dequoted in place.
294 ** If the first character of the input is not an open quote, then this
295 ** function is a no-op.
297 static void unionDequote(char *z){
298 if( z ){
299 char q = z[0];
301 /* Set stack variable q to the close-quote character */
302 if( q=='[' || q=='\'' || q=='"' || q=='`' ){
303 int iIn = 1;
304 int iOut = 0;
305 if( q=='[' ) q = ']';
306 while( ALWAYS(z[iIn]) ){
307 if( z[iIn]==q ){
308 if( z[iIn+1]!=q ){
309 /* Character iIn was the close quote. */
310 iIn++;
311 break;
312 }else{
313 /* Character iIn and iIn+1 form an escaped quote character. Skip
314 ** the input cursor past both and copy a single quote character
315 ** to the output buffer. */
316 iIn += 2;
317 z[iOut++] = q;
319 }else{
320 z[iOut++] = z[iIn++];
323 z[iOut] = '\0';
329 ** This function is a no-op if *pRc is set to other than SQLITE_OK when it
330 ** is called. NULL is returned in this case.
332 ** Otherwise, the SQL statement passed as the third argument is prepared
333 ** against the database handle passed as the second. If the statement is
334 ** successfully prepared, a pointer to the new statement handle is
335 ** returned. It is the responsibility of the caller to eventually free the
336 ** statement by calling sqlite3_finalize(). Alternatively, if statement
337 ** compilation fails, NULL is returned, *pRc is set to an SQLite error
338 ** code and *pzErr may be set to an error message buffer allocated by
339 ** sqlite3_malloc().
341 static sqlite3_stmt *unionPrepare(
342 int *pRc, /* IN/OUT: Error code */
343 sqlite3 *db, /* Database handle */
344 const char *zSql, /* SQL statement to prepare */
345 char **pzErr /* OUT: Error message */
347 sqlite3_stmt *pRet = 0;
348 assert( pzErr );
349 if( *pRc==SQLITE_OK ){
350 int rc = sqlite3_prepare_v2(db, zSql, -1, &pRet, 0);
351 if( rc!=SQLITE_OK ){
352 *pzErr = sqlite3_mprintf("sql error: %s", sqlite3_errmsg(db));
353 *pRc = rc;
356 return pRet;
360 ** Like unionPrepare(), except prepare the results of vprintf(zFmt, ...)
361 ** instead of a constant SQL string.
363 static sqlite3_stmt *unionPreparePrintf(
364 int *pRc, /* IN/OUT: Error code */
365 char **pzErr, /* OUT: Error message */
366 sqlite3 *db, /* Database handle */
367 const char *zFmt, /* printf() format string */
368 ... /* Trailing printf args */
370 sqlite3_stmt *pRet = 0;
371 char *zSql;
372 va_list ap;
373 va_start(ap, zFmt);
375 zSql = sqlite3_vmprintf(zFmt, ap);
376 if( *pRc==SQLITE_OK ){
377 if( zSql==0 ){
378 *pRc = SQLITE_NOMEM;
379 }else{
380 pRet = unionPrepare(pRc, db, zSql, pzErr);
383 sqlite3_free(zSql);
385 va_end(ap);
386 return pRet;
391 ** Call sqlite3_reset() on SQL statement pStmt. If *pRc is set to
392 ** SQLITE_OK when this function is called, then it is set to the
393 ** value returned by sqlite3_reset() before this function exits.
394 ** In this case, *pzErr may be set to point to an error message
395 ** buffer allocated by sqlite3_malloc().
397 #if 0
398 static void unionReset(int *pRc, sqlite3_stmt *pStmt, char **pzErr){
399 int rc = sqlite3_reset(pStmt);
400 if( *pRc==SQLITE_OK ){
401 *pRc = rc;
402 if( rc ){
403 *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(sqlite3_db_handle(pStmt)));
407 #endif
410 ** Call sqlite3_finalize() on SQL statement pStmt. If *pRc is set to
411 ** SQLITE_OK when this function is called, then it is set to the
412 ** value returned by sqlite3_finalize() before this function exits.
414 static void unionFinalize(int *pRc, sqlite3_stmt *pStmt, char **pzErr){
415 sqlite3 *db = sqlite3_db_handle(pStmt);
416 int rc = sqlite3_finalize(pStmt);
417 if( *pRc==SQLITE_OK ){
418 *pRc = rc;
419 if( rc ){
420 *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db));
426 ** If an "openclose" UDF was supplied when this virtual table was created,
427 ** invoke it now. The first argument passed is the name of the database
428 ** file for source pSrc. The second is integer value bClose.
430 ** If successful, return SQLITE_OK. Otherwise an SQLite error code. In this
431 ** case if argument pzErr is not NULL, also set (*pzErr) to an English
432 ** language error message. The caller is responsible for eventually freeing
433 ** any error message using sqlite3_free().
435 static int unionInvokeOpenClose(
436 UnionTab *pTab,
437 UnionSrc *pSrc,
438 int bClose,
439 char **pzErr
441 int rc = SQLITE_OK;
442 if( pTab->pOpenClose ){
443 sqlite3_bind_text(pTab->pOpenClose, 1, pSrc->zFile, -1, SQLITE_STATIC);
444 if( pTab->bHasContext ){
445 sqlite3_bind_text(pTab->pOpenClose, 2, pSrc->zContext, -1, SQLITE_STATIC);
447 sqlite3_bind_int(pTab->pOpenClose, 2+pTab->bHasContext, bClose);
448 sqlite3_step(pTab->pOpenClose);
449 if( SQLITE_OK!=(rc = sqlite3_reset(pTab->pOpenClose)) ){
450 if( pzErr ){
451 *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(pTab->db));
455 return rc;
459 ** This function is a no-op for unionvtab. For swarmvtab, it attempts to
460 ** close open database files until at most nMax are open. An SQLite error
461 ** code is returned if an error occurs, or SQLITE_OK otherwise.
463 static void unionCloseSources(UnionTab *pTab, int nMax){
464 while( pTab->pClosable && pTab->nOpen>nMax ){
465 UnionSrc *p;
466 UnionSrc **pp;
467 for(pp=&pTab->pClosable; (*pp)->pNextClosable; pp=&(*pp)->pNextClosable);
468 p = *pp;
469 assert( p->db );
470 sqlite3_close(p->db);
471 p->db = 0;
472 *pp = 0;
473 pTab->nOpen--;
474 unionInvokeOpenClose(pTab, p, 1, 0);
479 ** xDisconnect method.
481 static int unionDisconnect(sqlite3_vtab *pVtab){
482 if( pVtab ){
483 UnionTab *pTab = (UnionTab*)pVtab;
484 int i;
485 for(i=0; i<pTab->nSrc; i++){
486 UnionSrc *pSrc = &pTab->aSrc[i];
487 if( pSrc->db ){
488 unionInvokeOpenClose(pTab, pSrc, 1, 0);
490 sqlite3_free(pSrc->zDb);
491 sqlite3_free(pSrc->zTab);
492 sqlite3_free(pSrc->zFile);
493 sqlite3_free(pSrc->zContext);
494 sqlite3_close(pSrc->db);
496 sqlite3_finalize(pTab->pNotFound);
497 sqlite3_finalize(pTab->pOpenClose);
498 sqlite3_free(pTab->zSourceStr);
499 sqlite3_free(pTab->aSrc);
500 sqlite3_free(pTab);
502 return SQLITE_OK;
506 ** Check that the table identified by pSrc is a rowid table. If not,
507 ** return SQLITE_ERROR and set (*pzErr) to point to an English language
508 ** error message. If the table is a rowid table and no error occurs,
509 ** return SQLITE_OK and leave (*pzErr) unmodified.
511 static int unionIsIntkeyTable(
512 sqlite3 *db, /* Database handle */
513 UnionSrc *pSrc, /* Source table to test */
514 char **pzErr /* OUT: Error message */
516 int bPk = 0;
517 const char *zType = 0;
518 int rc;
520 sqlite3_table_column_metadata(
521 db, pSrc->zDb, pSrc->zTab, "_rowid_", &zType, 0, 0, &bPk, 0
523 rc = sqlite3_errcode(db);
524 if( rc==SQLITE_ERROR
525 || (rc==SQLITE_OK && (!bPk || sqlite3_stricmp("integer", zType)))
527 rc = SQLITE_ERROR;
528 *pzErr = sqlite3_mprintf("no such rowid table: %s%s%s",
529 (pSrc->zDb ? pSrc->zDb : ""),
530 (pSrc->zDb ? "." : ""),
531 pSrc->zTab
534 return rc;
538 ** This function is a no-op if *pRc is other than SQLITE_OK when it is
539 ** called. In this case it returns NULL.
541 ** Otherwise, this function checks that the source table passed as the
542 ** second argument (a) exists, (b) is not a view and (c) has a column
543 ** named "_rowid_" of type "integer" that is the primary key.
544 ** If this is not the case, *pRc is set to SQLITE_ERROR and NULL is
545 ** returned.
547 ** Finally, if the source table passes the checks above, a nul-terminated
548 ** string describing the column names and types belonging to the source
549 ** table is returned. Tables with the same set of column names and types
550 ** cause this function to return identical strings. Is is the responsibility
551 ** of the caller to free the returned string using sqlite3_free() when
552 ** it is no longer required.
554 static char *unionSourceToStr(
555 int *pRc, /* IN/OUT: Error code */
556 UnionTab *pTab, /* Virtual table object */
557 UnionSrc *pSrc, /* Source table to test */
558 char **pzErr /* OUT: Error message */
560 char *zRet = 0;
561 if( *pRc==SQLITE_OK ){
562 sqlite3 *db = unionGetDb(pTab, pSrc);
563 int rc = unionIsIntkeyTable(db, pSrc, pzErr);
564 sqlite3_stmt *pStmt = unionPrepare(&rc, db,
565 "SELECT group_concat(quote(name) || '.' || quote(type)) "
566 "FROM pragma_table_info(?, ?)", pzErr
568 if( rc==SQLITE_OK ){
569 sqlite3_bind_text(pStmt, 1, pSrc->zTab, -1, SQLITE_STATIC);
570 sqlite3_bind_text(pStmt, 2, pSrc->zDb, -1, SQLITE_STATIC);
571 if( SQLITE_ROW==sqlite3_step(pStmt) ){
572 const char *z = (const char*)sqlite3_column_text(pStmt, 0);
573 zRet = unionStrdup(&rc, z);
575 unionFinalize(&rc, pStmt, pzErr);
577 *pRc = rc;
580 return zRet;
584 ** Check that all configured source tables exist and have the same column
585 ** names and datatypes. If this is not the case, or if some other error
586 ** occurs, return an SQLite error code. In this case *pzErr may be set
587 ** to point to an error message buffer allocated by sqlite3_mprintf().
588 ** Or, if no problems regarding the source tables are detected and no
589 ** other error occurs, SQLITE_OK is returned.
591 static int unionSourceCheck(UnionTab *pTab, char **pzErr){
592 int rc = SQLITE_OK;
593 char *z0 = 0;
594 int i;
596 assert( *pzErr==0 );
597 z0 = unionSourceToStr(&rc, pTab, &pTab->aSrc[0], pzErr);
598 for(i=1; i<pTab->nSrc; i++){
599 char *z = unionSourceToStr(&rc, pTab, &pTab->aSrc[i], pzErr);
600 if( rc==SQLITE_OK && sqlite3_stricmp(z, z0) ){
601 *pzErr = sqlite3_mprintf("source table schema mismatch");
602 rc = SQLITE_ERROR;
604 sqlite3_free(z);
606 sqlite3_free(z0);
608 return rc;
612 ** Try to open the swarmvtab database. If initially unable, invoke the
613 ** not-found callback UDF and then try again.
615 static int unionOpenDatabaseInner(UnionTab *pTab, UnionSrc *pSrc, char **pzErr){
616 static const int openFlags = SQLITE_OPEN_READONLY | SQLITE_OPEN_URI;
617 int rc;
619 rc = unionInvokeOpenClose(pTab, pSrc, 0, pzErr);
620 if( rc!=SQLITE_OK ) return rc;
622 rc = sqlite3_open_v2(pSrc->zFile, &pSrc->db, openFlags, 0);
623 if( rc==SQLITE_OK ) return rc;
624 if( pTab->pNotFound ){
625 sqlite3_close(pSrc->db);
626 pSrc->db = 0;
627 sqlite3_bind_text(pTab->pNotFound, 1, pSrc->zFile, -1, SQLITE_STATIC);
628 if( pTab->bHasContext ){
629 sqlite3_bind_text(pTab->pNotFound, 2, pSrc->zContext, -1, SQLITE_STATIC);
631 sqlite3_step(pTab->pNotFound);
632 if( SQLITE_OK!=(rc = sqlite3_reset(pTab->pNotFound)) ){
633 *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(pTab->db));
634 return rc;
636 rc = sqlite3_open_v2(pSrc->zFile, &pSrc->db, openFlags, 0);
638 if( rc!=SQLITE_OK ){
639 *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(pSrc->db));
641 return rc;
645 ** This function may only be called for swarmvtab tables. The results of
646 ** calling it on a unionvtab table are undefined.
648 ** For a swarmvtab table, this function ensures that source database iSrc
649 ** is open. If the database is opened successfully and the schema is as
650 ** expected, or if it is already open when this function is called, SQLITE_OK
651 ** is returned.
653 ** Alternatively If an error occurs while opening the databases, or if the
654 ** database schema is unsuitable, an SQLite error code is returned and (*pzErr)
655 ** may be set to point to an English language error message. In this case it is
656 ** the responsibility of the caller to eventually free the error message buffer
657 ** using sqlite3_free().
659 static int unionOpenDatabase(UnionTab *pTab, int iSrc, char **pzErr){
660 int rc = SQLITE_OK;
661 UnionSrc *pSrc = &pTab->aSrc[iSrc];
663 assert( pTab->bSwarm && iSrc<pTab->nSrc );
664 if( pSrc->db==0 ){
665 unionCloseSources(pTab, pTab->nMaxOpen-1);
666 rc = unionOpenDatabaseInner(pTab, pSrc, pzErr);
667 if( rc==SQLITE_OK ){
668 char *z = unionSourceToStr(&rc, pTab, pSrc, pzErr);
669 if( rc==SQLITE_OK ){
670 if( pTab->zSourceStr==0 ){
671 pTab->zSourceStr = z;
672 }else{
673 if( sqlite3_stricmp(z, pTab->zSourceStr) ){
674 *pzErr = sqlite3_mprintf("source table schema mismatch");
675 rc = SQLITE_ERROR;
677 sqlite3_free(z);
682 if( rc==SQLITE_OK ){
683 pSrc->pNextClosable = pTab->pClosable;
684 pTab->pClosable = pSrc;
685 pTab->nOpen++;
686 }else{
687 sqlite3_close(pSrc->db);
688 pSrc->db = 0;
689 unionInvokeOpenClose(pTab, pSrc, 1, 0);
693 return rc;
698 ** This function is a no-op for unionvtab tables. For swarmvtab, increment
699 ** the reference count for source table iTab. If the reference count was
700 ** zero before it was incremented, also remove the source from the closable
701 ** list.
703 static void unionIncrRefcount(UnionTab *pTab, int iTab){
704 if( pTab->bSwarm ){
705 UnionSrc *pSrc = &pTab->aSrc[iTab];
706 assert( pSrc->nUser>=0 && pSrc->db );
707 if( pSrc->nUser==0 ){
708 UnionSrc **pp;
709 for(pp=&pTab->pClosable; *pp!=pSrc; pp=&(*pp)->pNextClosable);
710 *pp = pSrc->pNextClosable;
711 pSrc->pNextClosable = 0;
713 pSrc->nUser++;
718 ** Finalize the SQL statement pCsr->pStmt and return the result.
720 ** If this is a swarmvtab table (not unionvtab) and pCsr->pStmt was not
721 ** NULL when this function was called, also decrement the reference
722 ** count on the associated source table. If this means the source tables
723 ** refcount is now zero, add it to the closable list.
725 static int unionFinalizeCsrStmt(UnionCsr *pCsr){
726 int rc = SQLITE_OK;
727 if( pCsr->pStmt ){
728 UnionTab *pTab = (UnionTab*)pCsr->base.pVtab;
729 UnionSrc *pSrc = &pTab->aSrc[pCsr->iTab];
730 rc = sqlite3_finalize(pCsr->pStmt);
731 pCsr->pStmt = 0;
732 if( pTab->bSwarm ){
733 pSrc->nUser--;
734 assert( pSrc->nUser>=0 );
735 if( pSrc->nUser==0 ){
736 pSrc->pNextClosable = pTab->pClosable;
737 pTab->pClosable = pSrc;
739 unionCloseSources(pTab, pTab->nMaxOpen);
742 return rc;
746 ** Return true if the argument is a space, tab, CR or LF character.
748 static int union_isspace(char c){
749 return (c==' ' || c=='\n' || c=='\r' || c=='\t');
753 ** Return true if the argument is an alphanumeric character in the
754 ** ASCII range.
756 static int union_isidchar(char c){
757 return ((c>='a' && c<='z') || (c>='A' && c<'Z') || (c>='0' && c<='9'));
761 ** This function is called to handle all arguments following the first
762 ** (the SQL statement) passed to a swarmvtab (not unionvtab) CREATE
763 ** VIRTUAL TABLE statement. It may bind parameters to the SQL statement
764 ** or configure members of the UnionTab object passed as the second
765 ** argument.
767 ** Refer to header comments at the top of this file for a description
768 ** of the arguments parsed.
770 ** This function is a no-op if *pRc is other than SQLITE_OK when it is
771 ** called. Otherwise, if an error occurs, *pRc is set to an SQLite error
772 ** code. In this case *pzErr may be set to point to a buffer containing
773 ** an English language error message. It is the responsibility of the
774 ** caller to eventually free the buffer using sqlite3_free().
776 static void unionConfigureVtab(
777 int *pRc, /* IN/OUT: Error code */
778 UnionTab *pTab, /* Table to configure */
779 sqlite3_stmt *pStmt, /* SQL statement to find sources */
780 int nArg, /* Number of entries in azArg[] array */
781 const char * const *azArg, /* Array of arguments to consider */
782 char **pzErr /* OUT: Error message */
784 int rc = *pRc;
785 int i;
786 if( rc==SQLITE_OK ){
787 pTab->bHasContext = (sqlite3_column_count(pStmt)>4);
789 for(i=0; rc==SQLITE_OK && i<nArg; i++){
790 char *zArg = unionStrdup(&rc, azArg[i]);
791 if( zArg ){
792 int nOpt = 0; /* Size of option name in bytes */
793 char *zOpt; /* Pointer to option name */
794 char *zVal; /* Pointer to value */
796 unionDequote(zArg);
797 zOpt = zArg;
798 while( union_isspace(*zOpt) ) zOpt++;
799 zVal = zOpt;
800 if( *zVal==':' ) zVal++;
801 while( union_isidchar(*zVal) ) zVal++;
802 nOpt = (int)(zVal-zOpt);
804 while( union_isspace(*zVal) ) zVal++;
805 if( *zVal=='=' ){
806 zOpt[nOpt] = '\0';
807 zVal++;
808 while( union_isspace(*zVal) ) zVal++;
809 zVal = unionStrdup(&rc, zVal);
810 if( zVal ){
811 unionDequote(zVal);
812 if( zOpt[0]==':' ){
813 /* A value to bind to the SQL statement */
814 int iParam = sqlite3_bind_parameter_index(pStmt, zOpt);
815 if( iParam==0 ){
816 *pzErr = sqlite3_mprintf(
817 "swarmvtab: no such SQL parameter: %s", zOpt
819 rc = SQLITE_ERROR;
820 }else{
821 rc = sqlite3_bind_text(pStmt, iParam, zVal, -1, SQLITE_TRANSIENT);
823 }else if( nOpt==7 && 0==sqlite3_strnicmp(zOpt, "maxopen", 7) ){
824 pTab->nMaxOpen = atoi(zVal);
825 if( pTab->nMaxOpen<=0 ){
826 *pzErr = sqlite3_mprintf("swarmvtab: illegal maxopen value");
827 rc = SQLITE_ERROR;
829 }else if( nOpt==7 && 0==sqlite3_strnicmp(zOpt, "missing", 7) ){
830 if( pTab->pNotFound ){
831 *pzErr = sqlite3_mprintf(
832 "swarmvtab: duplicate \"missing\" option");
833 rc = SQLITE_ERROR;
834 }else{
835 pTab->pNotFound = unionPreparePrintf(&rc, pzErr, pTab->db,
836 "SELECT \"%w\"(?%s)", zVal, pTab->bHasContext ? ",?" : ""
839 }else if( nOpt==9 && 0==sqlite3_strnicmp(zOpt, "openclose", 9) ){
840 if( pTab->pOpenClose ){
841 *pzErr = sqlite3_mprintf(
842 "swarmvtab: duplicate \"openclose\" option");
843 rc = SQLITE_ERROR;
844 }else{
845 pTab->pOpenClose = unionPreparePrintf(&rc, pzErr, pTab->db,
846 "SELECT \"%w\"(?,?%s)", zVal, pTab->bHasContext ? ",?" : ""
849 }else{
850 *pzErr = sqlite3_mprintf("swarmvtab: unrecognized option: %s",zOpt);
851 rc = SQLITE_ERROR;
853 sqlite3_free(zVal);
855 }else{
856 if( i==0 && nArg==1 ){
857 pTab->pNotFound = unionPreparePrintf(&rc, pzErr, pTab->db,
858 "SELECT \"%w\"(?)", zArg
860 }else{
861 *pzErr = sqlite3_mprintf( "swarmvtab: parse error: %s", azArg[i]);
862 rc = SQLITE_ERROR;
865 sqlite3_free(zArg);
868 *pRc = rc;
872 ** xConnect/xCreate method.
874 ** The argv[] array contains the following:
876 ** argv[0] -> module name ("unionvtab" or "swarmvtab")
877 ** argv[1] -> database name
878 ** argv[2] -> table name
879 ** argv[3] -> SQL statement
880 ** argv[4] -> not-found callback UDF name
882 static int unionConnect(
883 sqlite3 *db,
884 void *pAux,
885 int argc, const char *const*argv,
886 sqlite3_vtab **ppVtab,
887 char **pzErr
889 UnionTab *pTab = 0;
890 int rc = SQLITE_OK;
891 int bSwarm = (pAux==0 ? 0 : 1);
892 const char *zVtab = (bSwarm ? "swarmvtab" : "unionvtab");
894 if( sqlite3_stricmp("temp", argv[1]) ){
895 /* unionvtab tables may only be created in the temp schema */
896 *pzErr = sqlite3_mprintf("%s tables must be created in TEMP schema", zVtab);
897 rc = SQLITE_ERROR;
898 }else if( argc<4 || (argc>4 && bSwarm==0) ){
899 *pzErr = sqlite3_mprintf("wrong number of arguments for %s", zVtab);
900 rc = SQLITE_ERROR;
901 }else{
902 int nAlloc = 0; /* Allocated size of pTab->aSrc[] */
903 sqlite3_stmt *pStmt = 0; /* Argument statement */
904 char *zArg = unionStrdup(&rc, argv[3]); /* Copy of argument to CVT */
906 /* Prepare the SQL statement. Instead of executing it directly, sort
907 ** the results by the "minimum rowid" field. This makes it easier to
908 ** check that there are no rowid range overlaps between source tables
909 ** and that the UnionTab.aSrc[] array is always sorted by rowid. */
910 unionDequote(zArg);
911 pStmt = unionPreparePrintf(&rc, pzErr, db,
912 "SELECT * FROM (%z) ORDER BY 3", zArg
915 /* Allocate the UnionTab structure */
916 pTab = unionMalloc(&rc, sizeof(UnionTab));
917 if( pTab ){
918 assert( rc==SQLITE_OK );
919 pTab->db = db;
920 pTab->bSwarm = bSwarm;
921 pTab->nMaxOpen = SWARMVTAB_MAX_OPEN;
924 /* Parse other CVT arguments, if any */
925 if( bSwarm ){
926 unionConfigureVtab(&rc, pTab, pStmt, argc-4, &argv[4], pzErr);
929 /* Iterate through the rows returned by the SQL statement specified
930 ** as an argument to the CREATE VIRTUAL TABLE statement. */
931 while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
932 const char *zDb = (const char*)sqlite3_column_text(pStmt, 0);
933 const char *zTab = (const char*)sqlite3_column_text(pStmt, 1);
934 sqlite3_int64 iMin = sqlite3_column_int64(pStmt, 2);
935 sqlite3_int64 iMax = sqlite3_column_int64(pStmt, 3);
936 UnionSrc *pSrc;
938 /* Grow the pTab->aSrc[] array if required. */
939 if( nAlloc<=pTab->nSrc ){
940 int nNew = nAlloc ? nAlloc*2 : 8;
941 UnionSrc *aNew = (UnionSrc*)sqlite3_realloc(
942 pTab->aSrc, nNew*sizeof(UnionSrc)
944 if( aNew==0 ){
945 rc = SQLITE_NOMEM;
946 break;
947 }else{
948 memset(&aNew[pTab->nSrc], 0, (nNew-pTab->nSrc)*sizeof(UnionSrc));
949 pTab->aSrc = aNew;
950 nAlloc = nNew;
954 /* Check for problems with the specified range of rowids */
955 if( iMax<iMin || (pTab->nSrc>0 && iMin<=pTab->aSrc[pTab->nSrc-1].iMax) ){
956 *pzErr = sqlite3_mprintf("rowid range mismatch error");
957 rc = SQLITE_ERROR;
960 if( rc==SQLITE_OK ){
961 pSrc = &pTab->aSrc[pTab->nSrc++];
962 pSrc->zTab = unionStrdup(&rc, zTab);
963 pSrc->iMin = iMin;
964 pSrc->iMax = iMax;
965 if( bSwarm ){
966 pSrc->zFile = unionStrdup(&rc, zDb);
967 }else{
968 pSrc->zDb = unionStrdup(&rc, zDb);
970 if( pTab->bHasContext ){
971 const char *zContext = (const char*)sqlite3_column_text(pStmt, 4);
972 pSrc->zContext = unionStrdup(&rc, zContext);
976 unionFinalize(&rc, pStmt, pzErr);
977 pStmt = 0;
979 /* It is an error if the SELECT statement returned zero rows. If only
980 ** because there is no way to determine the schema of the virtual
981 ** table in this case. */
982 if( rc==SQLITE_OK && pTab->nSrc==0 ){
983 *pzErr = sqlite3_mprintf("no source tables configured");
984 rc = SQLITE_ERROR;
987 /* For unionvtab, verify that all source tables exist and have
988 ** compatible schemas. For swarmvtab, attach the first database and
989 ** check that the first table is a rowid table only. */
990 if( rc==SQLITE_OK ){
991 if( bSwarm ){
992 rc = unionOpenDatabase(pTab, 0, pzErr);
993 }else{
994 rc = unionSourceCheck(pTab, pzErr);
998 /* Compose a CREATE TABLE statement and pass it to declare_vtab() */
999 if( rc==SQLITE_OK ){
1000 UnionSrc *pSrc = &pTab->aSrc[0];
1001 sqlite3 *tdb = unionGetDb(pTab, pSrc);
1002 pStmt = unionPreparePrintf(&rc, pzErr, tdb, "SELECT "
1003 "'CREATE TABLE xyz('"
1004 " || group_concat(quote(name) || ' ' || type, ', ')"
1005 " || ')',"
1006 "max((cid+1) * (type='INTEGER' COLLATE nocase AND pk=1))-1 "
1007 "FROM pragma_table_info(%Q, ?)",
1008 pSrc->zTab, pSrc->zDb
1011 if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
1012 const char *zDecl = (const char*)sqlite3_column_text(pStmt, 0);
1013 rc = sqlite3_declare_vtab(db, zDecl);
1014 pTab->iPK = sqlite3_column_int(pStmt, 1);
1017 unionFinalize(&rc, pStmt, pzErr);
1020 if( rc!=SQLITE_OK ){
1021 unionDisconnect((sqlite3_vtab*)pTab);
1022 pTab = 0;
1025 *ppVtab = (sqlite3_vtab*)pTab;
1026 return rc;
1030 ** xOpen
1032 static int unionOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
1033 UnionCsr *pCsr;
1034 int rc = SQLITE_OK;
1035 (void)p; /* Suppress harmless warning */
1036 pCsr = (UnionCsr*)unionMalloc(&rc, sizeof(UnionCsr));
1037 *ppCursor = &pCsr->base;
1038 return rc;
1042 ** xClose
1044 static int unionClose(sqlite3_vtab_cursor *cur){
1045 UnionCsr *pCsr = (UnionCsr*)cur;
1046 unionFinalizeCsrStmt(pCsr);
1047 sqlite3_free(pCsr);
1048 return SQLITE_OK;
1052 ** This function does the work of the xNext() method. Except that, if it
1053 ** returns SQLITE_ROW, it should be called again within the same xNext()
1054 ** method call. See unionNext() for details.
1056 static int doUnionNext(UnionCsr *pCsr){
1057 int rc = SQLITE_OK;
1058 assert( pCsr->pStmt );
1059 if( sqlite3_step(pCsr->pStmt)!=SQLITE_ROW ){
1060 UnionTab *pTab = (UnionTab*)pCsr->base.pVtab;
1061 rc = unionFinalizeCsrStmt(pCsr);
1062 if( rc==SQLITE_OK && pTab->bSwarm ){
1063 pCsr->iTab++;
1064 if( pCsr->iTab<pTab->nSrc ){
1065 UnionSrc *pSrc = &pTab->aSrc[pCsr->iTab];
1066 if( pCsr->iMaxRowid>=pSrc->iMin ){
1067 /* It is necessary to scan the next table. */
1068 rc = unionOpenDatabase(pTab, pCsr->iTab, &pTab->base.zErrMsg);
1069 pCsr->pStmt = unionPreparePrintf(&rc, &pTab->base.zErrMsg, pSrc->db,
1070 "SELECT rowid, * FROM %Q %s %lld",
1071 pSrc->zTab,
1072 (pSrc->iMax>pCsr->iMaxRowid ? "WHERE _rowid_ <=" : "-- "),
1073 pCsr->iMaxRowid
1075 if( rc==SQLITE_OK ){
1076 assert( pCsr->pStmt );
1077 unionIncrRefcount(pTab, pCsr->iTab);
1078 rc = SQLITE_ROW;
1085 return rc;
1089 ** xNext
1091 static int unionNext(sqlite3_vtab_cursor *cur){
1092 int rc;
1093 do {
1094 rc = doUnionNext((UnionCsr*)cur);
1095 }while( rc==SQLITE_ROW );
1096 return rc;
1100 ** xColumn
1102 static int unionColumn(
1103 sqlite3_vtab_cursor *cur,
1104 sqlite3_context *ctx,
1105 int i
1107 UnionCsr *pCsr = (UnionCsr*)cur;
1108 sqlite3_result_value(ctx, sqlite3_column_value(pCsr->pStmt, i+1));
1109 return SQLITE_OK;
1113 ** xRowid
1115 static int unionRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
1116 UnionCsr *pCsr = (UnionCsr*)cur;
1117 *pRowid = sqlite3_column_int64(pCsr->pStmt, 0);
1118 return SQLITE_OK;
1122 ** xEof
1124 static int unionEof(sqlite3_vtab_cursor *cur){
1125 UnionCsr *pCsr = (UnionCsr*)cur;
1126 return pCsr->pStmt==0;
1130 ** xFilter
1132 static int unionFilter(
1133 sqlite3_vtab_cursor *pVtabCursor,
1134 int idxNum, const char *idxStr,
1135 int argc, sqlite3_value **argv
1137 UnionTab *pTab = (UnionTab*)(pVtabCursor->pVtab);
1138 UnionCsr *pCsr = (UnionCsr*)pVtabCursor;
1139 int rc = SQLITE_OK;
1140 int i;
1141 char *zSql = 0;
1142 int bZero = 0;
1144 sqlite3_int64 iMin = SMALLEST_INT64;
1145 sqlite3_int64 iMax = LARGEST_INT64;
1147 assert( idxNum==0
1148 || idxNum==SQLITE_INDEX_CONSTRAINT_EQ
1149 || idxNum==SQLITE_INDEX_CONSTRAINT_LE
1150 || idxNum==SQLITE_INDEX_CONSTRAINT_GE
1151 || idxNum==SQLITE_INDEX_CONSTRAINT_LT
1152 || idxNum==SQLITE_INDEX_CONSTRAINT_GT
1153 || idxNum==(SQLITE_INDEX_CONSTRAINT_GE|SQLITE_INDEX_CONSTRAINT_LE)
1156 (void)idxStr; /* Suppress harmless warning */
1158 if( idxNum==SQLITE_INDEX_CONSTRAINT_EQ ){
1159 assert( argc==1 );
1160 iMin = iMax = sqlite3_value_int64(argv[0]);
1161 }else{
1163 if( idxNum & (SQLITE_INDEX_CONSTRAINT_LE|SQLITE_INDEX_CONSTRAINT_LT) ){
1164 assert( argc>=1 );
1165 iMax = sqlite3_value_int64(argv[0]);
1166 if( idxNum & SQLITE_INDEX_CONSTRAINT_LT ){
1167 if( iMax==SMALLEST_INT64 ){
1168 bZero = 1;
1169 }else{
1170 iMax--;
1175 if( idxNum & (SQLITE_INDEX_CONSTRAINT_GE|SQLITE_INDEX_CONSTRAINT_GT) ){
1176 assert( argc>=1 );
1177 iMin = sqlite3_value_int64(argv[argc-1]);
1178 if( idxNum & SQLITE_INDEX_CONSTRAINT_GT ){
1179 if( iMin==LARGEST_INT64 ){
1180 bZero = 1;
1181 }else{
1182 iMin++;
1188 unionFinalizeCsrStmt(pCsr);
1189 if( bZero ){
1190 return SQLITE_OK;
1193 for(i=0; i<pTab->nSrc; i++){
1194 UnionSrc *pSrc = &pTab->aSrc[i];
1195 if( iMin>pSrc->iMax || iMax<pSrc->iMin ){
1196 continue;
1199 zSql = sqlite3_mprintf("%z%sSELECT rowid, * FROM %s%q%s%Q"
1200 , zSql
1201 , (zSql ? " UNION ALL " : "")
1202 , (pSrc->zDb ? "'" : "")
1203 , (pSrc->zDb ? pSrc->zDb : "")
1204 , (pSrc->zDb ? "'." : "")
1205 , pSrc->zTab
1207 if( zSql==0 ){
1208 rc = SQLITE_NOMEM;
1209 break;
1212 if( iMin==iMax ){
1213 zSql = sqlite3_mprintf("%z WHERE rowid=%lld", zSql, iMin);
1214 }else{
1215 const char *zWhere = "WHERE";
1216 if( iMin!=SMALLEST_INT64 && iMin>pSrc->iMin ){
1217 zSql = sqlite3_mprintf("%z WHERE rowid>=%lld", zSql, iMin);
1218 zWhere = "AND";
1220 if( iMax!=LARGEST_INT64 && iMax<pSrc->iMax ){
1221 zSql = sqlite3_mprintf("%z %s rowid<=%lld", zSql, zWhere, iMax);
1225 if( pTab->bSwarm ){
1226 pCsr->iTab = i;
1227 pCsr->iMaxRowid = iMax;
1228 rc = unionOpenDatabase(pTab, i, &pTab->base.zErrMsg);
1229 break;
1233 if( zSql==0 ){
1234 return rc;
1235 }else{
1236 sqlite3 *db = unionGetDb(pTab, &pTab->aSrc[pCsr->iTab]);
1237 pCsr->pStmt = unionPrepare(&rc, db, zSql, &pTab->base.zErrMsg);
1238 if( pCsr->pStmt ){
1239 unionIncrRefcount(pTab, pCsr->iTab);
1241 sqlite3_free(zSql);
1243 if( rc!=SQLITE_OK ) return rc;
1244 return unionNext(pVtabCursor);
1248 ** xBestIndex.
1250 ** This implementation searches for constraints on the rowid field. EQ,
1251 ** LE, LT, GE and GT are handled.
1253 ** If there is an EQ comparison, then idxNum is set to INDEX_CONSTRAINT_EQ.
1254 ** In this case the only argument passed to xFilter is the rhs of the ==
1255 ** operator.
1257 ** Otherwise, if an LE or LT constraint is found, then the INDEX_CONSTRAINT_LE
1258 ** or INDEX_CONSTRAINT_LT (but not both) bit is set in idxNum. The first
1259 ** argument to xFilter is the rhs of the <= or < operator. Similarly, if
1260 ** an GE or GT constraint is found, then the INDEX_CONSTRAINT_GE or
1261 ** INDEX_CONSTRAINT_GT bit is set in idxNum. The rhs of the >= or > operator
1262 ** is passed as either the first or second argument to xFilter, depending
1263 ** on whether or not there is also a LT|LE constraint.
1265 static int unionBestIndex(
1266 sqlite3_vtab *tab,
1267 sqlite3_index_info *pIdxInfo
1269 UnionTab *pTab = (UnionTab*)tab;
1270 int iEq = -1;
1271 int iLt = -1;
1272 int iGt = -1;
1273 int i;
1275 for(i=0; i<pIdxInfo->nConstraint; i++){
1276 struct sqlite3_index_constraint *p = &pIdxInfo->aConstraint[i];
1277 if( p->usable && (p->iColumn<0 || p->iColumn==pTab->iPK) ){
1278 switch( p->op ){
1279 case SQLITE_INDEX_CONSTRAINT_EQ:
1280 iEq = i;
1281 break;
1282 case SQLITE_INDEX_CONSTRAINT_LE:
1283 case SQLITE_INDEX_CONSTRAINT_LT:
1284 iLt = i;
1285 break;
1286 case SQLITE_INDEX_CONSTRAINT_GE:
1287 case SQLITE_INDEX_CONSTRAINT_GT:
1288 iGt = i;
1289 break;
1294 if( iEq>=0 ){
1295 pIdxInfo->estimatedRows = 1;
1296 pIdxInfo->idxFlags = SQLITE_INDEX_SCAN_UNIQUE;
1297 pIdxInfo->estimatedCost = 3.0;
1298 pIdxInfo->idxNum = SQLITE_INDEX_CONSTRAINT_EQ;
1299 pIdxInfo->aConstraintUsage[iEq].argvIndex = 1;
1300 pIdxInfo->aConstraintUsage[iEq].omit = 1;
1301 }else{
1302 int iCons = 1;
1303 int idxNum = 0;
1304 sqlite3_int64 nRow = 1000000;
1305 if( iLt>=0 ){
1306 nRow = nRow / 2;
1307 pIdxInfo->aConstraintUsage[iLt].argvIndex = iCons++;
1308 pIdxInfo->aConstraintUsage[iLt].omit = 1;
1309 idxNum |= pIdxInfo->aConstraint[iLt].op;
1311 if( iGt>=0 ){
1312 nRow = nRow / 2;
1313 pIdxInfo->aConstraintUsage[iGt].argvIndex = iCons++;
1314 pIdxInfo->aConstraintUsage[iGt].omit = 1;
1315 idxNum |= pIdxInfo->aConstraint[iGt].op;
1317 pIdxInfo->estimatedRows = nRow;
1318 pIdxInfo->estimatedCost = 3.0 * (double)nRow;
1319 pIdxInfo->idxNum = idxNum;
1322 return SQLITE_OK;
1326 ** Register the unionvtab virtual table module with database handle db.
1328 static int createUnionVtab(sqlite3 *db){
1329 static sqlite3_module unionModule = {
1330 0, /* iVersion */
1331 unionConnect,
1332 unionConnect,
1333 unionBestIndex, /* xBestIndex - query planner */
1334 unionDisconnect,
1335 unionDisconnect,
1336 unionOpen, /* xOpen - open a cursor */
1337 unionClose, /* xClose - close a cursor */
1338 unionFilter, /* xFilter - configure scan constraints */
1339 unionNext, /* xNext - advance a cursor */
1340 unionEof, /* xEof - check for end of scan */
1341 unionColumn, /* xColumn - read data */
1342 unionRowid, /* xRowid - read data */
1343 0, /* xUpdate */
1344 0, /* xBegin */
1345 0, /* xSync */
1346 0, /* xCommit */
1347 0, /* xRollback */
1348 0, /* xFindMethod */
1349 0, /* xRename */
1350 0, /* xSavepoint */
1351 0, /* xRelease */
1352 0 /* xRollbackTo */
1354 int rc;
1356 rc = sqlite3_create_module(db, "unionvtab", &unionModule, 0);
1357 if( rc==SQLITE_OK ){
1358 rc = sqlite3_create_module(db, "swarmvtab", &unionModule, (void*)db);
1360 return rc;
1363 #endif /* SQLITE_OMIT_VIRTUALTABLE */
1365 #ifdef _WIN32
1366 __declspec(dllexport)
1367 #endif
1368 int sqlite3_unionvtab_init(
1369 sqlite3 *db,
1370 char **pzErrMsg,
1371 const sqlite3_api_routines *pApi
1373 int rc = SQLITE_OK;
1374 SQLITE_EXTENSION_INIT2(pApi);
1375 (void)pzErrMsg; /* Suppress harmless warning */
1376 #ifndef SQLITE_OMIT_VIRTUALTABLE
1377 rc = createUnionVtab(db);
1378 #endif
1379 return rc;