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 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
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
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).
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.
75 ** Using the new syntax, a swarmvtab table is created with:
77 ** CREATE VIRTUAL TABLE <name> USING swarmvtab(
78 ** <sql-statement> [, <options>]
81 ** where valid <options> are:
83 ** missing=<udf-function-name>
84 ** openclose=<udf-function-name>
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
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>);
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.
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'
138 #include "sqlite3ext.h"
139 SQLITE_EXTENSION_INIT1
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))
153 #ifndef SMALLEST_INT64
154 # define SMALLEST_INT64 (((sqlite3_int64)-1) - LARGEST_INT64)
158 ** The following is also copied from sqliteInt.h. To facilitate coverage
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)
169 # define ALWAYS(X) (X)
170 # define NEVER(X) (X)
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.
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.
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.
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
253 static void *unionMalloc(int *pRc
, int nByte
){
256 if( *pRc
==SQLITE_OK
){
257 pRet
= sqlite3_malloc(nByte
);
259 memset(pRet
, 0, nByte
);
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
){
279 int nByte
= (int)strlen(zIn
) + 1;
280 zRet
= unionMalloc(pRc
, nByte
);
282 memcpy(zRet
, zIn
, nByte
);
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
){
301 /* Set stack variable q to the close-quote character */
302 if( q
=='[' || q
=='\'' || q
=='"' || q
=='`' ){
305 if( q
=='[' ) q
= ']';
306 while( ALWAYS(z
[iIn
]) ){
309 /* Character iIn was the close quote. */
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. */
320 z
[iOut
++] = z
[iIn
++];
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
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;
349 if( *pRc
==SQLITE_OK
){
350 int rc
= sqlite3_prepare_v2(db
, zSql
, -1, &pRet
, 0);
352 *pzErr
= sqlite3_mprintf("sql error: %s", sqlite3_errmsg(db
));
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;
375 zSql
= sqlite3_vmprintf(zFmt
, ap
);
376 if( *pRc
==SQLITE_OK
){
380 pRet
= unionPrepare(pRc
, db
, zSql
, pzErr
);
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().
398 static void unionReset(int *pRc
, sqlite3_stmt
*pStmt
, char **pzErr
){
399 int rc
= sqlite3_reset(pStmt
);
400 if( *pRc
==SQLITE_OK
){
403 *pzErr
= sqlite3_mprintf("%s", sqlite3_errmsg(sqlite3_db_handle(pStmt
)));
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
){
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(
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
)) ){
451 *pzErr
= sqlite3_mprintf("%s", sqlite3_errmsg(pTab
->db
));
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
){
467 for(pp
=&pTab
->pClosable
; (*pp
)->pNextClosable
; pp
=&(*pp
)->pNextClosable
);
470 sqlite3_close(p
->db
);
474 unionInvokeOpenClose(pTab
, p
, 1, 0);
479 ** xDisconnect method.
481 static int unionDisconnect(sqlite3_vtab
*pVtab
){
483 UnionTab
*pTab
= (UnionTab
*)pVtab
;
485 for(i
=0; i
<pTab
->nSrc
; i
++){
486 UnionSrc
*pSrc
= &pTab
->aSrc
[i
];
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
);
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 */
517 const char *zType
= 0;
520 sqlite3_table_column_metadata(
521 db
, pSrc
->zDb
, pSrc
->zTab
, "_rowid_", &zType
, 0, 0, &bPk
, 0
523 rc
= sqlite3_errcode(db
);
525 || (rc
==SQLITE_OK
&& (!bPk
|| sqlite3_stricmp("integer", zType
)))
528 *pzErr
= sqlite3_mprintf("no such rowid table: %s%s%s",
529 (pSrc
->zDb
? pSrc
->zDb
: ""),
530 (pSrc
->zDb
? "." : ""),
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
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 */
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
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
);
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
){
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");
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
;
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
);
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
));
636 rc
= sqlite3_open_v2(pSrc
->zFile
, &pSrc
->db
, openFlags
, 0);
639 *pzErr
= sqlite3_mprintf("%s", sqlite3_errmsg(pSrc
->db
));
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
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
){
661 UnionSrc
*pSrc
= &pTab
->aSrc
[iSrc
];
663 assert( pTab
->bSwarm
&& iSrc
<pTab
->nSrc
);
665 unionCloseSources(pTab
, pTab
->nMaxOpen
-1);
666 rc
= unionOpenDatabaseInner(pTab
, pSrc
, pzErr
);
668 char *z
= unionSourceToStr(&rc
, pTab
, pSrc
, pzErr
);
670 if( pTab
->zSourceStr
==0 ){
671 pTab
->zSourceStr
= z
;
673 if( sqlite3_stricmp(z
, pTab
->zSourceStr
) ){
674 *pzErr
= sqlite3_mprintf("source table schema mismatch");
683 pSrc
->pNextClosable
= pTab
->pClosable
;
684 pTab
->pClosable
= pSrc
;
687 sqlite3_close(pSrc
->db
);
689 unionInvokeOpenClose(pTab
, pSrc
, 1, 0);
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
703 static void unionIncrRefcount(UnionTab
*pTab
, int iTab
){
705 UnionSrc
*pSrc
= &pTab
->aSrc
[iTab
];
706 assert( pSrc
->nUser
>=0 && pSrc
->db
);
707 if( pSrc
->nUser
==0 ){
709 for(pp
=&pTab
->pClosable
; *pp
!=pSrc
; pp
=&(*pp
)->pNextClosable
);
710 *pp
= pSrc
->pNextClosable
;
711 pSrc
->pNextClosable
= 0;
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
){
728 UnionTab
*pTab
= (UnionTab
*)pCsr
->base
.pVtab
;
729 UnionSrc
*pSrc
= &pTab
->aSrc
[pCsr
->iTab
];
730 rc
= sqlite3_finalize(pCsr
->pStmt
);
734 assert( pSrc
->nUser
>=0 );
735 if( pSrc
->nUser
==0 ){
736 pSrc
->pNextClosable
= pTab
->pClosable
;
737 pTab
->pClosable
= pSrc
;
739 unionCloseSources(pTab
, pTab
->nMaxOpen
);
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
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
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 */
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
]);
792 int nOpt
= 0; /* Size of option name in bytes */
793 char *zOpt
; /* Pointer to option name */
794 char *zVal
; /* Pointer to value */
798 while( union_isspace(*zOpt
) ) zOpt
++;
800 if( *zVal
==':' ) zVal
++;
801 while( union_isidchar(*zVal
) ) zVal
++;
802 nOpt
= (int)(zVal
-zOpt
);
804 while( union_isspace(*zVal
) ) zVal
++;
808 while( union_isspace(*zVal
) ) zVal
++;
809 zVal
= unionStrdup(&rc
, zVal
);
813 /* A value to bind to the SQL statement */
814 int iParam
= sqlite3_bind_parameter_index(pStmt
, zOpt
);
816 *pzErr
= sqlite3_mprintf(
817 "swarmvtab: no such SQL parameter: %s", zOpt
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");
829 }else if( nOpt
==7 && 0==sqlite3_strnicmp(zOpt
, "missing", 7) ){
830 if( pTab
->pNotFound
){
831 *pzErr
= sqlite3_mprintf(
832 "swarmvtab: duplicate \"missing\" option");
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");
845 pTab
->pOpenClose
= unionPreparePrintf(&rc
, pzErr
, pTab
->db
,
846 "SELECT \"%w\"(?,?%s)", zVal
, pTab
->bHasContext
? ",?" : ""
850 *pzErr
= sqlite3_mprintf("swarmvtab: unrecognized option: %s",zOpt
);
856 if( i
==0 && nArg
==1 ){
857 pTab
->pNotFound
= unionPreparePrintf(&rc
, pzErr
, pTab
->db
,
858 "SELECT \"%w\"(?)", zArg
861 *pzErr
= sqlite3_mprintf( "swarmvtab: parse error: %s", azArg
[i
]);
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(
885 int argc
, const char *const*argv
,
886 sqlite3_vtab
**ppVtab
,
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
);
898 }else if( argc
<4 || (argc
>4 && bSwarm
==0) ){
899 *pzErr
= sqlite3_mprintf("wrong number of arguments for %s", zVtab
);
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. */
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
));
918 assert( rc
==SQLITE_OK
);
920 pTab
->bSwarm
= bSwarm
;
921 pTab
->nMaxOpen
= SWARMVTAB_MAX_OPEN
;
924 /* Parse other CVT arguments, if any */
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);
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
)
948 memset(&aNew
[pTab
->nSrc
], 0, (nNew
-pTab
->nSrc
)*sizeof(UnionSrc
));
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");
961 pSrc
= &pTab
->aSrc
[pTab
->nSrc
++];
962 pSrc
->zTab
= unionStrdup(&rc
, zTab
);
966 pSrc
->zFile
= unionStrdup(&rc
, zDb
);
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
);
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");
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. */
992 rc
= unionOpenDatabase(pTab
, 0, pzErr
);
994 rc
= unionSourceCheck(pTab
, pzErr
);
998 /* Compose a CREATE TABLE statement and pass it to declare_vtab() */
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, ', ')"
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
);
1025 *ppVtab
= (sqlite3_vtab
*)pTab
;
1032 static int unionOpen(sqlite3_vtab
*p
, sqlite3_vtab_cursor
**ppCursor
){
1035 (void)p
; /* Suppress harmless warning */
1036 pCsr
= (UnionCsr
*)unionMalloc(&rc
, sizeof(UnionCsr
));
1037 *ppCursor
= &pCsr
->base
;
1044 static int unionClose(sqlite3_vtab_cursor
*cur
){
1045 UnionCsr
*pCsr
= (UnionCsr
*)cur
;
1046 unionFinalizeCsrStmt(pCsr
);
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
){
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
){
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",
1072 (pSrc
->iMax
>pCsr
->iMaxRowid
? "WHERE _rowid_ <=" : "-- "),
1075 if( rc
==SQLITE_OK
){
1076 assert( pCsr
->pStmt
);
1077 unionIncrRefcount(pTab
, pCsr
->iTab
);
1091 static int unionNext(sqlite3_vtab_cursor
*cur
){
1094 rc
= doUnionNext((UnionCsr
*)cur
);
1095 }while( rc
==SQLITE_ROW
);
1102 static int unionColumn(
1103 sqlite3_vtab_cursor
*cur
,
1104 sqlite3_context
*ctx
,
1107 UnionCsr
*pCsr
= (UnionCsr
*)cur
;
1108 sqlite3_result_value(ctx
, sqlite3_column_value(pCsr
->pStmt
, i
+1));
1115 static int unionRowid(sqlite3_vtab_cursor
*cur
, sqlite_int64
*pRowid
){
1116 UnionCsr
*pCsr
= (UnionCsr
*)cur
;
1117 *pRowid
= sqlite3_column_int64(pCsr
->pStmt
, 0);
1124 static int unionEof(sqlite3_vtab_cursor
*cur
){
1125 UnionCsr
*pCsr
= (UnionCsr
*)cur
;
1126 return pCsr
->pStmt
==0;
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
;
1144 sqlite3_int64 iMin
= SMALLEST_INT64
;
1145 sqlite3_int64 iMax
= LARGEST_INT64
;
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
){
1160 iMin
= iMax
= sqlite3_value_int64(argv
[0]);
1163 if( idxNum
& (SQLITE_INDEX_CONSTRAINT_LE
|SQLITE_INDEX_CONSTRAINT_LT
) ){
1165 iMax
= sqlite3_value_int64(argv
[0]);
1166 if( idxNum
& SQLITE_INDEX_CONSTRAINT_LT
){
1167 if( iMax
==SMALLEST_INT64
){
1175 if( idxNum
& (SQLITE_INDEX_CONSTRAINT_GE
|SQLITE_INDEX_CONSTRAINT_GT
) ){
1177 iMin
= sqlite3_value_int64(argv
[argc
-1]);
1178 if( idxNum
& SQLITE_INDEX_CONSTRAINT_GT
){
1179 if( iMin
==LARGEST_INT64
){
1188 unionFinalizeCsrStmt(pCsr
);
1193 for(i
=0; i
<pTab
->nSrc
; i
++){
1194 UnionSrc
*pSrc
= &pTab
->aSrc
[i
];
1195 if( iMin
>pSrc
->iMax
|| iMax
<pSrc
->iMin
){
1199 zSql
= sqlite3_mprintf("%z%sSELECT rowid, * FROM %s%q%s%Q"
1201 , (zSql
? " UNION ALL " : "")
1202 , (pSrc
->zDb
? "'" : "")
1203 , (pSrc
->zDb
? pSrc
->zDb
: "")
1204 , (pSrc
->zDb
? "'." : "")
1213 zSql
= sqlite3_mprintf("%z WHERE rowid=%lld", zSql
, iMin
);
1215 const char *zWhere
= "WHERE";
1216 if( iMin
!=SMALLEST_INT64
&& iMin
>pSrc
->iMin
){
1217 zSql
= sqlite3_mprintf("%z WHERE rowid>=%lld", zSql
, iMin
);
1220 if( iMax
!=LARGEST_INT64
&& iMax
<pSrc
->iMax
){
1221 zSql
= sqlite3_mprintf("%z %s rowid<=%lld", zSql
, zWhere
, iMax
);
1227 pCsr
->iMaxRowid
= iMax
;
1228 rc
= unionOpenDatabase(pTab
, i
, &pTab
->base
.zErrMsg
);
1236 sqlite3
*db
= unionGetDb(pTab
, &pTab
->aSrc
[pCsr
->iTab
]);
1237 pCsr
->pStmt
= unionPrepare(&rc
, db
, zSql
, &pTab
->base
.zErrMsg
);
1239 unionIncrRefcount(pTab
, pCsr
->iTab
);
1243 if( rc
!=SQLITE_OK
) return rc
;
1244 return unionNext(pVtabCursor
);
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 ==
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(
1267 sqlite3_index_info
*pIdxInfo
1269 UnionTab
*pTab
= (UnionTab
*)tab
;
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
) ){
1279 case SQLITE_INDEX_CONSTRAINT_EQ
:
1282 case SQLITE_INDEX_CONSTRAINT_LE
:
1283 case SQLITE_INDEX_CONSTRAINT_LT
:
1286 case SQLITE_INDEX_CONSTRAINT_GE
:
1287 case SQLITE_INDEX_CONSTRAINT_GT
:
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;
1304 sqlite3_int64 nRow
= 1000000;
1307 pIdxInfo
->aConstraintUsage
[iLt
].argvIndex
= iCons
++;
1308 pIdxInfo
->aConstraintUsage
[iLt
].omit
= 1;
1309 idxNum
|= pIdxInfo
->aConstraint
[iLt
].op
;
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
;
1326 ** Register the unionvtab virtual table module with database handle db.
1328 static int createUnionVtab(sqlite3
*db
){
1329 static sqlite3_module unionModule
= {
1333 unionBestIndex
, /* xBestIndex - query planner */
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 */
1348 0, /* xFindMethod */
1356 rc
= sqlite3_create_module(db
, "unionvtab", &unionModule
, 0);
1357 if( rc
==SQLITE_OK
){
1358 rc
= sqlite3_create_module(db
, "swarmvtab", &unionModule
, (void*)db
);
1363 #endif /* SQLITE_OMIT_VIRTUALTABLE */
1366 __declspec(dllexport
)
1368 int sqlite3_unionvtab_init(
1371 const sqlite3_api_routines
*pApi
1374 SQLITE_EXTENSION_INIT2(pApi
);
1375 (void)pzErrMsg
; /* Suppress harmless warning */
1376 #ifndef SQLITE_OMIT_VIRTUALTABLE
1377 rc
= createUnionVtab(db
);