Enhance the command-line completion extension to return the names of
[sqlite.git] / ext / misc / unionvtab.c
blob94a5c8f013e006c5656c7303b471897a3e913325
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 int bHaveSrcDb = (pSrc->db!=0);
488 sqlite3_close(pSrc->db);
489 if( bHaveSrcDb ){
490 unionInvokeOpenClose(pTab, pSrc, 1, 0);
492 sqlite3_free(pSrc->zDb);
493 sqlite3_free(pSrc->zTab);
494 sqlite3_free(pSrc->zFile);
495 sqlite3_free(pSrc->zContext);
497 sqlite3_finalize(pTab->pNotFound);
498 sqlite3_finalize(pTab->pOpenClose);
499 sqlite3_free(pTab->zSourceStr);
500 sqlite3_free(pTab->aSrc);
501 sqlite3_free(pTab);
503 return SQLITE_OK;
507 ** Check that the table identified by pSrc is a rowid table. If not,
508 ** return SQLITE_ERROR and set (*pzErr) to point to an English language
509 ** error message. If the table is a rowid table and no error occurs,
510 ** return SQLITE_OK and leave (*pzErr) unmodified.
512 static int unionIsIntkeyTable(
513 sqlite3 *db, /* Database handle */
514 UnionSrc *pSrc, /* Source table to test */
515 char **pzErr /* OUT: Error message */
517 int bPk = 0;
518 const char *zType = 0;
519 int rc;
521 sqlite3_table_column_metadata(
522 db, pSrc->zDb, pSrc->zTab, "_rowid_", &zType, 0, 0, &bPk, 0
524 rc = sqlite3_errcode(db);
525 if( rc==SQLITE_ERROR
526 || (rc==SQLITE_OK && (!bPk || sqlite3_stricmp("integer", zType)))
528 rc = SQLITE_ERROR;
529 *pzErr = sqlite3_mprintf("no such rowid table: %s%s%s",
530 (pSrc->zDb ? pSrc->zDb : ""),
531 (pSrc->zDb ? "." : ""),
532 pSrc->zTab
535 return rc;
539 ** This function is a no-op if *pRc is other than SQLITE_OK when it is
540 ** called. In this case it returns NULL.
542 ** Otherwise, this function checks that the source table passed as the
543 ** second argument (a) exists, (b) is not a view and (c) has a column
544 ** named "_rowid_" of type "integer" that is the primary key.
545 ** If this is not the case, *pRc is set to SQLITE_ERROR and NULL is
546 ** returned.
548 ** Finally, if the source table passes the checks above, a nul-terminated
549 ** string describing the column names and types belonging to the source
550 ** table is returned. Tables with the same set of column names and types
551 ** cause this function to return identical strings. Is is the responsibility
552 ** of the caller to free the returned string using sqlite3_free() when
553 ** it is no longer required.
555 static char *unionSourceToStr(
556 int *pRc, /* IN/OUT: Error code */
557 UnionTab *pTab, /* Virtual table object */
558 UnionSrc *pSrc, /* Source table to test */
559 char **pzErr /* OUT: Error message */
561 char *zRet = 0;
562 if( *pRc==SQLITE_OK ){
563 sqlite3 *db = unionGetDb(pTab, pSrc);
564 int rc = unionIsIntkeyTable(db, pSrc, pzErr);
565 sqlite3_stmt *pStmt = unionPrepare(&rc, db,
566 "SELECT group_concat(quote(name) || '.' || quote(type)) "
567 "FROM pragma_table_info(?, ?)", pzErr
569 if( rc==SQLITE_OK ){
570 sqlite3_bind_text(pStmt, 1, pSrc->zTab, -1, SQLITE_STATIC);
571 sqlite3_bind_text(pStmt, 2, pSrc->zDb, -1, SQLITE_STATIC);
572 if( SQLITE_ROW==sqlite3_step(pStmt) ){
573 const char *z = (const char*)sqlite3_column_text(pStmt, 0);
574 zRet = unionStrdup(&rc, z);
576 unionFinalize(&rc, pStmt, pzErr);
578 *pRc = rc;
581 return zRet;
585 ** Check that all configured source tables exist and have the same column
586 ** names and datatypes. If this is not the case, or if some other error
587 ** occurs, return an SQLite error code. In this case *pzErr may be set
588 ** to point to an error message buffer allocated by sqlite3_mprintf().
589 ** Or, if no problems regarding the source tables are detected and no
590 ** other error occurs, SQLITE_OK is returned.
592 static int unionSourceCheck(UnionTab *pTab, char **pzErr){
593 int rc = SQLITE_OK;
594 char *z0 = 0;
595 int i;
597 assert( *pzErr==0 );
598 z0 = unionSourceToStr(&rc, pTab, &pTab->aSrc[0], pzErr);
599 for(i=1; i<pTab->nSrc; i++){
600 char *z = unionSourceToStr(&rc, pTab, &pTab->aSrc[i], pzErr);
601 if( rc==SQLITE_OK && sqlite3_stricmp(z, z0) ){
602 *pzErr = sqlite3_mprintf("source table schema mismatch");
603 rc = SQLITE_ERROR;
605 sqlite3_free(z);
607 sqlite3_free(z0);
609 return rc;
613 ** Try to open the swarmvtab database. If initially unable, invoke the
614 ** not-found callback UDF and then try again.
616 static int unionOpenDatabaseInner(UnionTab *pTab, UnionSrc *pSrc, char **pzErr){
617 static const int openFlags = SQLITE_OPEN_READONLY | SQLITE_OPEN_URI;
618 int rc;
620 rc = unionInvokeOpenClose(pTab, pSrc, 0, pzErr);
621 if( rc!=SQLITE_OK ) return rc;
623 rc = sqlite3_open_v2(pSrc->zFile, &pSrc->db, openFlags, 0);
624 if( rc==SQLITE_OK ) return rc;
625 if( pTab->pNotFound ){
626 sqlite3_close(pSrc->db);
627 pSrc->db = 0;
628 sqlite3_bind_text(pTab->pNotFound, 1, pSrc->zFile, -1, SQLITE_STATIC);
629 if( pTab->bHasContext ){
630 sqlite3_bind_text(pTab->pNotFound, 2, pSrc->zContext, -1, SQLITE_STATIC);
632 sqlite3_step(pTab->pNotFound);
633 if( SQLITE_OK!=(rc = sqlite3_reset(pTab->pNotFound)) ){
634 *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(pTab->db));
635 return rc;
637 rc = sqlite3_open_v2(pSrc->zFile, &pSrc->db, openFlags, 0);
639 if( rc!=SQLITE_OK ){
640 *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(pSrc->db));
642 return rc;
646 ** This function may only be called for swarmvtab tables. The results of
647 ** calling it on a unionvtab table are undefined.
649 ** For a swarmvtab table, this function ensures that source database iSrc
650 ** is open. If the database is opened successfully and the schema is as
651 ** expected, or if it is already open when this function is called, SQLITE_OK
652 ** is returned.
654 ** Alternatively If an error occurs while opening the databases, or if the
655 ** database schema is unsuitable, an SQLite error code is returned and (*pzErr)
656 ** may be set to point to an English language error message. In this case it is
657 ** the responsibility of the caller to eventually free the error message buffer
658 ** using sqlite3_free().
660 static int unionOpenDatabase(UnionTab *pTab, int iSrc, char **pzErr){
661 int rc = SQLITE_OK;
662 UnionSrc *pSrc = &pTab->aSrc[iSrc];
664 assert( pTab->bSwarm && iSrc<pTab->nSrc );
665 if( pSrc->db==0 ){
666 unionCloseSources(pTab, pTab->nMaxOpen-1);
667 rc = unionOpenDatabaseInner(pTab, pSrc, pzErr);
668 if( rc==SQLITE_OK ){
669 char *z = unionSourceToStr(&rc, pTab, pSrc, pzErr);
670 if( rc==SQLITE_OK ){
671 if( pTab->zSourceStr==0 ){
672 pTab->zSourceStr = z;
673 }else{
674 if( sqlite3_stricmp(z, pTab->zSourceStr) ){
675 *pzErr = sqlite3_mprintf("source table schema mismatch");
676 rc = SQLITE_ERROR;
678 sqlite3_free(z);
683 if( rc==SQLITE_OK ){
684 pSrc->pNextClosable = pTab->pClosable;
685 pTab->pClosable = pSrc;
686 pTab->nOpen++;
687 }else{
688 sqlite3_close(pSrc->db);
689 pSrc->db = 0;
690 unionInvokeOpenClose(pTab, pSrc, 1, 0);
694 return rc;
699 ** This function is a no-op for unionvtab tables. For swarmvtab, increment
700 ** the reference count for source table iTab. If the reference count was
701 ** zero before it was incremented, also remove the source from the closable
702 ** list.
704 static void unionIncrRefcount(UnionTab *pTab, int iTab){
705 if( pTab->bSwarm ){
706 UnionSrc *pSrc = &pTab->aSrc[iTab];
707 assert( pSrc->nUser>=0 && pSrc->db );
708 if( pSrc->nUser==0 ){
709 UnionSrc **pp;
710 for(pp=&pTab->pClosable; *pp!=pSrc; pp=&(*pp)->pNextClosable);
711 *pp = pSrc->pNextClosable;
712 pSrc->pNextClosable = 0;
714 pSrc->nUser++;
719 ** Finalize the SQL statement pCsr->pStmt and return the result.
721 ** If this is a swarmvtab table (not unionvtab) and pCsr->pStmt was not
722 ** NULL when this function was called, also decrement the reference
723 ** count on the associated source table. If this means the source tables
724 ** refcount is now zero, add it to the closable list.
726 static int unionFinalizeCsrStmt(UnionCsr *pCsr){
727 int rc = SQLITE_OK;
728 if( pCsr->pStmt ){
729 UnionTab *pTab = (UnionTab*)pCsr->base.pVtab;
730 UnionSrc *pSrc = &pTab->aSrc[pCsr->iTab];
731 rc = sqlite3_finalize(pCsr->pStmt);
732 pCsr->pStmt = 0;
733 if( pTab->bSwarm ){
734 pSrc->nUser--;
735 assert( pSrc->nUser>=0 );
736 if( pSrc->nUser==0 ){
737 pSrc->pNextClosable = pTab->pClosable;
738 pTab->pClosable = pSrc;
740 unionCloseSources(pTab, pTab->nMaxOpen);
743 return rc;
747 ** Return true if the argument is a space, tab, CR or LF character.
749 static int union_isspace(char c){
750 return (c==' ' || c=='\n' || c=='\r' || c=='\t');
754 ** Return true if the argument is an alphanumeric character in the
755 ** ASCII range.
757 static int union_isidchar(char c){
758 return ((c>='a' && c<='z') || (c>='A' && c<'Z') || (c>='0' && c<='9'));
762 ** This function is called to handle all arguments following the first
763 ** (the SQL statement) passed to a swarmvtab (not unionvtab) CREATE
764 ** VIRTUAL TABLE statement. It may bind parameters to the SQL statement
765 ** or configure members of the UnionTab object passed as the second
766 ** argument.
768 ** Refer to header comments at the top of this file for a description
769 ** of the arguments parsed.
771 ** This function is a no-op if *pRc is other than SQLITE_OK when it is
772 ** called. Otherwise, if an error occurs, *pRc is set to an SQLite error
773 ** code. In this case *pzErr may be set to point to a buffer containing
774 ** an English language error message. It is the responsibility of the
775 ** caller to eventually free the buffer using sqlite3_free().
777 static void unionConfigureVtab(
778 int *pRc, /* IN/OUT: Error code */
779 UnionTab *pTab, /* Table to configure */
780 sqlite3_stmt *pStmt, /* SQL statement to find sources */
781 int nArg, /* Number of entries in azArg[] array */
782 const char * const *azArg, /* Array of arguments to consider */
783 char **pzErr /* OUT: Error message */
785 int rc = *pRc;
786 int i;
787 if( rc==SQLITE_OK ){
788 pTab->bHasContext = (sqlite3_column_count(pStmt)>4);
790 for(i=0; rc==SQLITE_OK && i<nArg; i++){
791 char *zArg = unionStrdup(&rc, azArg[i]);
792 if( zArg ){
793 int nOpt = 0; /* Size of option name in bytes */
794 char *zOpt; /* Pointer to option name */
795 char *zVal; /* Pointer to value */
797 unionDequote(zArg);
798 zOpt = zArg;
799 while( union_isspace(*zOpt) ) zOpt++;
800 zVal = zOpt;
801 if( *zVal==':' ) zVal++;
802 while( union_isidchar(*zVal) ) zVal++;
803 nOpt = (int)(zVal-zOpt);
805 while( union_isspace(*zVal) ) zVal++;
806 if( *zVal=='=' ){
807 zOpt[nOpt] = '\0';
808 zVal++;
809 while( union_isspace(*zVal) ) zVal++;
810 zVal = unionStrdup(&rc, zVal);
811 if( zVal ){
812 unionDequote(zVal);
813 if( zOpt[0]==':' ){
814 /* A value to bind to the SQL statement */
815 int iParam = sqlite3_bind_parameter_index(pStmt, zOpt);
816 if( iParam==0 ){
817 *pzErr = sqlite3_mprintf(
818 "swarmvtab: no such SQL parameter: %s", zOpt
820 rc = SQLITE_ERROR;
821 }else{
822 rc = sqlite3_bind_text(pStmt, iParam, zVal, -1, SQLITE_TRANSIENT);
824 }else if( nOpt==7 && 0==sqlite3_strnicmp(zOpt, "maxopen", 7) ){
825 pTab->nMaxOpen = atoi(zVal);
826 if( pTab->nMaxOpen<=0 ){
827 *pzErr = sqlite3_mprintf("swarmvtab: illegal maxopen value");
828 rc = SQLITE_ERROR;
830 }else if( nOpt==7 && 0==sqlite3_strnicmp(zOpt, "missing", 7) ){
831 if( pTab->pNotFound ){
832 *pzErr = sqlite3_mprintf(
833 "swarmvtab: duplicate \"missing\" option");
834 rc = SQLITE_ERROR;
835 }else{
836 pTab->pNotFound = unionPreparePrintf(&rc, pzErr, pTab->db,
837 "SELECT \"%w\"(?%s)", zVal, pTab->bHasContext ? ",?" : ""
840 }else if( nOpt==9 && 0==sqlite3_strnicmp(zOpt, "openclose", 9) ){
841 if( pTab->pOpenClose ){
842 *pzErr = sqlite3_mprintf(
843 "swarmvtab: duplicate \"openclose\" option");
844 rc = SQLITE_ERROR;
845 }else{
846 pTab->pOpenClose = unionPreparePrintf(&rc, pzErr, pTab->db,
847 "SELECT \"%w\"(?,?%s)", zVal, pTab->bHasContext ? ",?" : ""
850 }else{
851 *pzErr = sqlite3_mprintf("swarmvtab: unrecognized option: %s",zOpt);
852 rc = SQLITE_ERROR;
854 sqlite3_free(zVal);
856 }else{
857 if( i==0 && nArg==1 ){
858 pTab->pNotFound = unionPreparePrintf(&rc, pzErr, pTab->db,
859 "SELECT \"%w\"(?)", zArg
861 }else{
862 *pzErr = sqlite3_mprintf( "swarmvtab: parse error: %s", azArg[i]);
863 rc = SQLITE_ERROR;
866 sqlite3_free(zArg);
869 *pRc = rc;
873 ** xConnect/xCreate method.
875 ** The argv[] array contains the following:
877 ** argv[0] -> module name ("unionvtab" or "swarmvtab")
878 ** argv[1] -> database name
879 ** argv[2] -> table name
880 ** argv[3] -> SQL statement
881 ** argv[4] -> not-found callback UDF name
883 static int unionConnect(
884 sqlite3 *db,
885 void *pAux,
886 int argc, const char *const*argv,
887 sqlite3_vtab **ppVtab,
888 char **pzErr
890 UnionTab *pTab = 0;
891 int rc = SQLITE_OK;
892 int bSwarm = (pAux==0 ? 0 : 1);
893 const char *zVtab = (bSwarm ? "swarmvtab" : "unionvtab");
895 if( sqlite3_stricmp("temp", argv[1]) ){
896 /* unionvtab tables may only be created in the temp schema */
897 *pzErr = sqlite3_mprintf("%s tables must be created in TEMP schema", zVtab);
898 rc = SQLITE_ERROR;
899 }else if( argc<4 || (argc>4 && bSwarm==0) ){
900 *pzErr = sqlite3_mprintf("wrong number of arguments for %s", zVtab);
901 rc = SQLITE_ERROR;
902 }else{
903 int nAlloc = 0; /* Allocated size of pTab->aSrc[] */
904 sqlite3_stmt *pStmt = 0; /* Argument statement */
905 char *zArg = unionStrdup(&rc, argv[3]); /* Copy of argument to CVT */
907 /* Prepare the SQL statement. Instead of executing it directly, sort
908 ** the results by the "minimum rowid" field. This makes it easier to
909 ** check that there are no rowid range overlaps between source tables
910 ** and that the UnionTab.aSrc[] array is always sorted by rowid. */
911 unionDequote(zArg);
912 pStmt = unionPreparePrintf(&rc, pzErr, db,
913 "SELECT * FROM (%z) ORDER BY 3", zArg
916 /* Allocate the UnionTab structure */
917 pTab = unionMalloc(&rc, sizeof(UnionTab));
918 if( pTab ){
919 assert( rc==SQLITE_OK );
920 pTab->db = db;
921 pTab->bSwarm = bSwarm;
922 pTab->nMaxOpen = SWARMVTAB_MAX_OPEN;
925 /* Parse other CVT arguments, if any */
926 if( bSwarm ){
927 unionConfigureVtab(&rc, pTab, pStmt, argc-4, &argv[4], pzErr);
930 /* Iterate through the rows returned by the SQL statement specified
931 ** as an argument to the CREATE VIRTUAL TABLE statement. */
932 while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
933 const char *zDb = (const char*)sqlite3_column_text(pStmt, 0);
934 const char *zTab = (const char*)sqlite3_column_text(pStmt, 1);
935 sqlite3_int64 iMin = sqlite3_column_int64(pStmt, 2);
936 sqlite3_int64 iMax = sqlite3_column_int64(pStmt, 3);
937 UnionSrc *pSrc;
939 /* Grow the pTab->aSrc[] array if required. */
940 if( nAlloc<=pTab->nSrc ){
941 int nNew = nAlloc ? nAlloc*2 : 8;
942 UnionSrc *aNew = (UnionSrc*)sqlite3_realloc(
943 pTab->aSrc, nNew*sizeof(UnionSrc)
945 if( aNew==0 ){
946 rc = SQLITE_NOMEM;
947 break;
948 }else{
949 memset(&aNew[pTab->nSrc], 0, (nNew-pTab->nSrc)*sizeof(UnionSrc));
950 pTab->aSrc = aNew;
951 nAlloc = nNew;
955 /* Check for problems with the specified range of rowids */
956 if( iMax<iMin || (pTab->nSrc>0 && iMin<=pTab->aSrc[pTab->nSrc-1].iMax) ){
957 *pzErr = sqlite3_mprintf("rowid range mismatch error");
958 rc = SQLITE_ERROR;
961 if( rc==SQLITE_OK ){
962 pSrc = &pTab->aSrc[pTab->nSrc++];
963 pSrc->zTab = unionStrdup(&rc, zTab);
964 pSrc->iMin = iMin;
965 pSrc->iMax = iMax;
966 if( bSwarm ){
967 pSrc->zFile = unionStrdup(&rc, zDb);
968 }else{
969 pSrc->zDb = unionStrdup(&rc, zDb);
971 if( pTab->bHasContext ){
972 const char *zContext = (const char*)sqlite3_column_text(pStmt, 4);
973 pSrc->zContext = unionStrdup(&rc, zContext);
977 unionFinalize(&rc, pStmt, pzErr);
978 pStmt = 0;
980 /* It is an error if the SELECT statement returned zero rows. If only
981 ** because there is no way to determine the schema of the virtual
982 ** table in this case. */
983 if( rc==SQLITE_OK && pTab->nSrc==0 ){
984 *pzErr = sqlite3_mprintf("no source tables configured");
985 rc = SQLITE_ERROR;
988 /* For unionvtab, verify that all source tables exist and have
989 ** compatible schemas. For swarmvtab, attach the first database and
990 ** check that the first table is a rowid table only. */
991 if( rc==SQLITE_OK ){
992 if( bSwarm ){
993 rc = unionOpenDatabase(pTab, 0, pzErr);
994 }else{
995 rc = unionSourceCheck(pTab, pzErr);
999 /* Compose a CREATE TABLE statement and pass it to declare_vtab() */
1000 if( rc==SQLITE_OK ){
1001 UnionSrc *pSrc = &pTab->aSrc[0];
1002 sqlite3 *tdb = unionGetDb(pTab, pSrc);
1003 pStmt = unionPreparePrintf(&rc, pzErr, tdb, "SELECT "
1004 "'CREATE TABLE xyz('"
1005 " || group_concat(quote(name) || ' ' || type, ', ')"
1006 " || ')',"
1007 "max((cid+1) * (type='INTEGER' COLLATE nocase AND pk=1))-1 "
1008 "FROM pragma_table_info(%Q, ?)",
1009 pSrc->zTab, pSrc->zDb
1012 if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
1013 const char *zDecl = (const char*)sqlite3_column_text(pStmt, 0);
1014 rc = sqlite3_declare_vtab(db, zDecl);
1015 pTab->iPK = sqlite3_column_int(pStmt, 1);
1018 unionFinalize(&rc, pStmt, pzErr);
1021 if( rc!=SQLITE_OK ){
1022 unionDisconnect((sqlite3_vtab*)pTab);
1023 pTab = 0;
1026 *ppVtab = (sqlite3_vtab*)pTab;
1027 return rc;
1031 ** xOpen
1033 static int unionOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
1034 UnionCsr *pCsr;
1035 int rc = SQLITE_OK;
1036 (void)p; /* Suppress harmless warning */
1037 pCsr = (UnionCsr*)unionMalloc(&rc, sizeof(UnionCsr));
1038 *ppCursor = &pCsr->base;
1039 return rc;
1043 ** xClose
1045 static int unionClose(sqlite3_vtab_cursor *cur){
1046 UnionCsr *pCsr = (UnionCsr*)cur;
1047 unionFinalizeCsrStmt(pCsr);
1048 sqlite3_free(pCsr);
1049 return SQLITE_OK;
1053 ** This function does the work of the xNext() method. Except that, if it
1054 ** returns SQLITE_ROW, it should be called again within the same xNext()
1055 ** method call. See unionNext() for details.
1057 static int doUnionNext(UnionCsr *pCsr){
1058 int rc = SQLITE_OK;
1059 assert( pCsr->pStmt );
1060 if( sqlite3_step(pCsr->pStmt)!=SQLITE_ROW ){
1061 UnionTab *pTab = (UnionTab*)pCsr->base.pVtab;
1062 rc = unionFinalizeCsrStmt(pCsr);
1063 if( rc==SQLITE_OK && pTab->bSwarm ){
1064 pCsr->iTab++;
1065 if( pCsr->iTab<pTab->nSrc ){
1066 UnionSrc *pSrc = &pTab->aSrc[pCsr->iTab];
1067 if( pCsr->iMaxRowid>=pSrc->iMin ){
1068 /* It is necessary to scan the next table. */
1069 rc = unionOpenDatabase(pTab, pCsr->iTab, &pTab->base.zErrMsg);
1070 pCsr->pStmt = unionPreparePrintf(&rc, &pTab->base.zErrMsg, pSrc->db,
1071 "SELECT rowid, * FROM %Q %s %lld",
1072 pSrc->zTab,
1073 (pSrc->iMax>pCsr->iMaxRowid ? "WHERE _rowid_ <=" : "-- "),
1074 pCsr->iMaxRowid
1076 if( rc==SQLITE_OK ){
1077 assert( pCsr->pStmt );
1078 unionIncrRefcount(pTab, pCsr->iTab);
1079 rc = SQLITE_ROW;
1086 return rc;
1090 ** xNext
1092 static int unionNext(sqlite3_vtab_cursor *cur){
1093 int rc;
1094 do {
1095 rc = doUnionNext((UnionCsr*)cur);
1096 }while( rc==SQLITE_ROW );
1097 return rc;
1101 ** xColumn
1103 static int unionColumn(
1104 sqlite3_vtab_cursor *cur,
1105 sqlite3_context *ctx,
1106 int i
1108 UnionCsr *pCsr = (UnionCsr*)cur;
1109 sqlite3_result_value(ctx, sqlite3_column_value(pCsr->pStmt, i+1));
1110 return SQLITE_OK;
1114 ** xRowid
1116 static int unionRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
1117 UnionCsr *pCsr = (UnionCsr*)cur;
1118 *pRowid = sqlite3_column_int64(pCsr->pStmt, 0);
1119 return SQLITE_OK;
1123 ** xEof
1125 static int unionEof(sqlite3_vtab_cursor *cur){
1126 UnionCsr *pCsr = (UnionCsr*)cur;
1127 return pCsr->pStmt==0;
1131 ** xFilter
1133 static int unionFilter(
1134 sqlite3_vtab_cursor *pVtabCursor,
1135 int idxNum, const char *idxStr,
1136 int argc, sqlite3_value **argv
1138 UnionTab *pTab = (UnionTab*)(pVtabCursor->pVtab);
1139 UnionCsr *pCsr = (UnionCsr*)pVtabCursor;
1140 int rc = SQLITE_OK;
1141 int i;
1142 char *zSql = 0;
1143 int bZero = 0;
1145 sqlite3_int64 iMin = SMALLEST_INT64;
1146 sqlite3_int64 iMax = LARGEST_INT64;
1148 assert( idxNum==0
1149 || idxNum==SQLITE_INDEX_CONSTRAINT_EQ
1150 || idxNum==SQLITE_INDEX_CONSTRAINT_LE
1151 || idxNum==SQLITE_INDEX_CONSTRAINT_GE
1152 || idxNum==SQLITE_INDEX_CONSTRAINT_LT
1153 || idxNum==SQLITE_INDEX_CONSTRAINT_GT
1154 || idxNum==(SQLITE_INDEX_CONSTRAINT_GE|SQLITE_INDEX_CONSTRAINT_LE)
1157 (void)idxStr; /* Suppress harmless warning */
1159 if( idxNum==SQLITE_INDEX_CONSTRAINT_EQ ){
1160 assert( argc==1 );
1161 iMin = iMax = sqlite3_value_int64(argv[0]);
1162 }else{
1164 if( idxNum & (SQLITE_INDEX_CONSTRAINT_LE|SQLITE_INDEX_CONSTRAINT_LT) ){
1165 assert( argc>=1 );
1166 iMax = sqlite3_value_int64(argv[0]);
1167 if( idxNum & SQLITE_INDEX_CONSTRAINT_LT ){
1168 if( iMax==SMALLEST_INT64 ){
1169 bZero = 1;
1170 }else{
1171 iMax--;
1176 if( idxNum & (SQLITE_INDEX_CONSTRAINT_GE|SQLITE_INDEX_CONSTRAINT_GT) ){
1177 assert( argc>=1 );
1178 iMin = sqlite3_value_int64(argv[argc-1]);
1179 if( idxNum & SQLITE_INDEX_CONSTRAINT_GT ){
1180 if( iMin==LARGEST_INT64 ){
1181 bZero = 1;
1182 }else{
1183 iMin++;
1189 unionFinalizeCsrStmt(pCsr);
1190 if( bZero ){
1191 return SQLITE_OK;
1194 for(i=0; i<pTab->nSrc; i++){
1195 UnionSrc *pSrc = &pTab->aSrc[i];
1196 if( iMin>pSrc->iMax || iMax<pSrc->iMin ){
1197 continue;
1200 zSql = sqlite3_mprintf("%z%sSELECT rowid, * FROM %s%q%s%Q"
1201 , zSql
1202 , (zSql ? " UNION ALL " : "")
1203 , (pSrc->zDb ? "'" : "")
1204 , (pSrc->zDb ? pSrc->zDb : "")
1205 , (pSrc->zDb ? "'." : "")
1206 , pSrc->zTab
1208 if( zSql==0 ){
1209 rc = SQLITE_NOMEM;
1210 break;
1213 if( iMin==iMax ){
1214 zSql = sqlite3_mprintf("%z WHERE rowid=%lld", zSql, iMin);
1215 }else{
1216 const char *zWhere = "WHERE";
1217 if( iMin!=SMALLEST_INT64 && iMin>pSrc->iMin ){
1218 zSql = sqlite3_mprintf("%z WHERE rowid>=%lld", zSql, iMin);
1219 zWhere = "AND";
1221 if( iMax!=LARGEST_INT64 && iMax<pSrc->iMax ){
1222 zSql = sqlite3_mprintf("%z %s rowid<=%lld", zSql, zWhere, iMax);
1226 if( pTab->bSwarm ){
1227 pCsr->iTab = i;
1228 pCsr->iMaxRowid = iMax;
1229 rc = unionOpenDatabase(pTab, i, &pTab->base.zErrMsg);
1230 break;
1234 if( zSql==0 ){
1235 return rc;
1236 }else{
1237 sqlite3 *db = unionGetDb(pTab, &pTab->aSrc[pCsr->iTab]);
1238 pCsr->pStmt = unionPrepare(&rc, db, zSql, &pTab->base.zErrMsg);
1239 if( pCsr->pStmt ){
1240 unionIncrRefcount(pTab, pCsr->iTab);
1242 sqlite3_free(zSql);
1244 if( rc!=SQLITE_OK ) return rc;
1245 return unionNext(pVtabCursor);
1249 ** xBestIndex.
1251 ** This implementation searches for constraints on the rowid field. EQ,
1252 ** LE, LT, GE and GT are handled.
1254 ** If there is an EQ comparison, then idxNum is set to INDEX_CONSTRAINT_EQ.
1255 ** In this case the only argument passed to xFilter is the rhs of the ==
1256 ** operator.
1258 ** Otherwise, if an LE or LT constraint is found, then the INDEX_CONSTRAINT_LE
1259 ** or INDEX_CONSTRAINT_LT (but not both) bit is set in idxNum. The first
1260 ** argument to xFilter is the rhs of the <= or < operator. Similarly, if
1261 ** an GE or GT constraint is found, then the INDEX_CONSTRAINT_GE or
1262 ** INDEX_CONSTRAINT_GT bit is set in idxNum. The rhs of the >= or > operator
1263 ** is passed as either the first or second argument to xFilter, depending
1264 ** on whether or not there is also a LT|LE constraint.
1266 static int unionBestIndex(
1267 sqlite3_vtab *tab,
1268 sqlite3_index_info *pIdxInfo
1270 UnionTab *pTab = (UnionTab*)tab;
1271 int iEq = -1;
1272 int iLt = -1;
1273 int iGt = -1;
1274 int i;
1276 for(i=0; i<pIdxInfo->nConstraint; i++){
1277 struct sqlite3_index_constraint *p = &pIdxInfo->aConstraint[i];
1278 if( p->usable && (p->iColumn<0 || p->iColumn==pTab->iPK) ){
1279 switch( p->op ){
1280 case SQLITE_INDEX_CONSTRAINT_EQ:
1281 iEq = i;
1282 break;
1283 case SQLITE_INDEX_CONSTRAINT_LE:
1284 case SQLITE_INDEX_CONSTRAINT_LT:
1285 iLt = i;
1286 break;
1287 case SQLITE_INDEX_CONSTRAINT_GE:
1288 case SQLITE_INDEX_CONSTRAINT_GT:
1289 iGt = i;
1290 break;
1295 if( iEq>=0 ){
1296 pIdxInfo->estimatedRows = 1;
1297 pIdxInfo->idxFlags = SQLITE_INDEX_SCAN_UNIQUE;
1298 pIdxInfo->estimatedCost = 3.0;
1299 pIdxInfo->idxNum = SQLITE_INDEX_CONSTRAINT_EQ;
1300 pIdxInfo->aConstraintUsage[iEq].argvIndex = 1;
1301 pIdxInfo->aConstraintUsage[iEq].omit = 1;
1302 }else{
1303 int iCons = 1;
1304 int idxNum = 0;
1305 sqlite3_int64 nRow = 1000000;
1306 if( iLt>=0 ){
1307 nRow = nRow / 2;
1308 pIdxInfo->aConstraintUsage[iLt].argvIndex = iCons++;
1309 pIdxInfo->aConstraintUsage[iLt].omit = 1;
1310 idxNum |= pIdxInfo->aConstraint[iLt].op;
1312 if( iGt>=0 ){
1313 nRow = nRow / 2;
1314 pIdxInfo->aConstraintUsage[iGt].argvIndex = iCons++;
1315 pIdxInfo->aConstraintUsage[iGt].omit = 1;
1316 idxNum |= pIdxInfo->aConstraint[iGt].op;
1318 pIdxInfo->estimatedRows = nRow;
1319 pIdxInfo->estimatedCost = 3.0 * (double)nRow;
1320 pIdxInfo->idxNum = idxNum;
1323 return SQLITE_OK;
1327 ** Register the unionvtab virtual table module with database handle db.
1329 static int createUnionVtab(sqlite3 *db){
1330 static sqlite3_module unionModule = {
1331 0, /* iVersion */
1332 unionConnect,
1333 unionConnect,
1334 unionBestIndex, /* xBestIndex - query planner */
1335 unionDisconnect,
1336 unionDisconnect,
1337 unionOpen, /* xOpen - open a cursor */
1338 unionClose, /* xClose - close a cursor */
1339 unionFilter, /* xFilter - configure scan constraints */
1340 unionNext, /* xNext - advance a cursor */
1341 unionEof, /* xEof - check for end of scan */
1342 unionColumn, /* xColumn - read data */
1343 unionRowid, /* xRowid - read data */
1344 0, /* xUpdate */
1345 0, /* xBegin */
1346 0, /* xSync */
1347 0, /* xCommit */
1348 0, /* xRollback */
1349 0, /* xFindMethod */
1350 0, /* xRename */
1351 0, /* xSavepoint */
1352 0, /* xRelease */
1353 0 /* xRollbackTo */
1355 int rc;
1357 rc = sqlite3_create_module(db, "unionvtab", &unionModule, 0);
1358 if( rc==SQLITE_OK ){
1359 rc = sqlite3_create_module(db, "swarmvtab", &unionModule, (void*)db);
1361 return rc;
1364 #endif /* SQLITE_OMIT_VIRTUALTABLE */
1366 #ifdef _WIN32
1367 __declspec(dllexport)
1368 #endif
1369 int sqlite3_unionvtab_init(
1370 sqlite3 *db,
1371 char **pzErrMsg,
1372 const sqlite3_api_routines *pApi
1374 int rc = SQLITE_OK;
1375 SQLITE_EXTENSION_INIT2(pApi);
1376 (void)pzErrMsg; /* Suppress harmless warning */
1377 #ifndef SQLITE_OMIT_VIRTUALTABLE
1378 rc = createUnionVtab(db);
1379 #endif
1380 return rc;