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. 10 ** 11 ************************************************************************* 12 ** 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: 17 ** 18 ** * They must all be rowid tables (not VIRTUAL or WITHOUT ROWID 19 ** tables or views). 20 ** 21 ** * Each table must have the same set of columns, declared in 22 ** the same order and with the same declared types. 23 ** 24 ** * The tables must not feature a user-defined column named "_rowid_". 25 ** 26 ** * Each table must contain a distinct range of rowid values. 27 ** 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. 34 ** 35 ** UNIONVTAB 36 ** 37 ** A "unionvtab" virtual table is created as follows: 38 ** 39 ** CREATE VIRTUAL TABLE <name> USING unionvtab(<sql-statement>); 40 ** 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: 44 ** 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. 48 ** 49 ** 2. The name of the database table. 50 ** 51 ** 3. The smallest rowid in the range of rowids that may be stored in the 52 ** database table (an integer). 53 ** 54 ** 4. The largest rowid in the range of rowids that may be stored in the 55 ** database table (an integer). 56 ** 57 ** SWARMVTAB 58 ** 59 ** LEGACY SYNTAX: 60 ** 61 ** A "swarmvtab" virtual table is created similarly to a unionvtab table: 62 ** 63 ** CREATE VIRTUAL TABLE <name> 64 ** USING swarmvtab(<sql-statement>, <callback>); 65 ** 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. 72 ** 73 ** NEW SYNTAX: 74 ** 75 ** Using the new syntax, a swarmvtab table is created with: 76 ** 77 ** CREATE VIRTUAL TABLE <name> USING swarmvtab( 78 ** <sql-statement> [, <options>] 79 ** ); 80 ** 81 ** where valid <options> are: 82 ** 83 ** missing=<udf-function-name> 84 ** openclose=<udf-function-name> 85 ** maxopen=<integer> 86 ** <sql-parameter>=<text-value> 87 ** 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). 94 ** 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: 99 ** 100 ** SELECT <missing-udf>(<database filename/uri>); 101 ** 102 ** Or, if there was a context column: 103 ** 104 ** SELECT <missing-udf>(<database filename/uri>, <context>); 105 ** 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): 114 ** 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); 121 ** 122 ** The "maxopen" option is used to configure the maximum number of 123 ** database files swarmvtab will hold open simultaneously (default 9). 124 ** 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: 130 ** 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 ** ); 136 */ 137 138 #include "sqlite3ext.h" 139 SQLITE_EXTENSION_INIT1 140 #include <assert.h> 141 #include <string.h> 142 #include <stdlib.h> 143 144 #ifndef SQLITE_OMIT_VIRTUALTABLE 145 146 /* 147 ** Largest and smallest possible 64-bit signed integers. These macros 148 ** copied from sqliteInt.h. 149 */ 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 156 157 /* 158 ** The following is also copied from sqliteInt.h. To facilitate coverage 159 ** testing. 160 */ 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 173 174 /* 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. 178 */ 179 #define SWARMVTAB_MAX_OPEN 9 180 181 typedef struct UnionCsr UnionCsr; 182 typedef struct UnionTab UnionTab; 183 typedef struct UnionSrc UnionSrc; 184 185 /* 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. 189 */ 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 */ 195 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 */ 202 }; 203 204 /* 205 ** Virtual table type for union vtab. 206 */ 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 */ 214 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 */ 220 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 */ 224 }; 225 226 /* 227 ** Virtual table cursor type for union vtab. 228 */ 229 struct UnionCsr { 230 sqlite3_vtab_cursor base; /* Base class - must be first */ 231 sqlite3_stmt *pStmt; /* SQL statement to run */ 232 233 /* Used by swarmvtab only */ 234 sqlite3_int64 iMaxRowid; /* Last rowid to visit */ 235 int iTab; /* Index of table read by pStmt */ 236 }; 237 238 /* 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". 243 */ 244 #define unionGetDb(pTab, pSrc) ((pTab)->bSwarm ? (pSrc)->db : (pTab)->db) 245 246 /* 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. 252 */ 253 static void *unionMalloc(int *pRc, sqlite3_int64 nByte){ 254 void *pRet; 255 assert( nByte>0 ); 256 if( *pRc==SQLITE_OK ){ 257 pRet = sqlite3_malloc64(nByte); 258 if( pRet ){ 259 memset(pRet, 0, (size_t)nByte); 260 }else{ 261 *pRc = SQLITE_NOMEM; 262 } 263 }else{ 264 pRet = 0; 265 } 266 return pRet; 267 } 268 269 /* 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. 275 */ 276 static char *unionStrdup(int *pRc, const char *zIn){ 277 char *zRet = 0; 278 if( zIn ){ 279 sqlite3_int64 nByte = strlen(zIn) + 1; 280 zRet = unionMalloc(pRc, nByte); 281 if( zRet ){ 282 memcpy(zRet, zIn, (size_t)nByte); 283 } 284 } 285 return zRet; 286 } 287 288 /* 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. 293 ** 294 ** If the first character of the input is not an open quote, then this 295 ** function is a no-op. 296 */ 297 static void unionDequote(char *z){ 298 if( z ){ 299 char q = z[0]; 300 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; 318 } 319 }else{ 320 z[iOut++] = z[iIn++]; 321 } 322 } 323 z[iOut] = '\0'; 324 } 325 } 326 } 327 328 /* 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. 331 ** 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(). 340 */ 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 */ 346 ){ 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; 354 } 355 } 356 return pRet; 357 } 358 359 /* 360 ** Like unionPrepare(), except prepare the results of vprintf(zFmt, ...) 361 ** instead of a constant SQL string. 362 */ 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 */ 369 ){ 370 sqlite3_stmt *pRet = 0; 371 char *zSql; 372 va_list ap; 373 va_start(ap, zFmt); 374 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); 381 } 382 } 383 sqlite3_free(zSql); 384 385 va_end(ap); 386 return pRet; 387 } 388 389 390 /* 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(). 396 */ 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))); 404 } 405 } 406 } 407 #endif 408 409 /* 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. 413 */ 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)); 421 } 422 } 423 } 424 425 /* 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. 429 ** 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(). 434 */ 435 static int unionInvokeOpenClose( 436 UnionTab *pTab, 437 UnionSrc *pSrc, 438 int bClose, 439 char **pzErr 440 ){ 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); 446 } 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)); 452 } 453 } 454 } 455 return rc; 456 } 457 458 /* 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. 462 */ 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); 475 } 476 } 477 478 /* 479 ** xDisconnect method. 480 */ 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); 491 } 492 sqlite3_free(pSrc->zDb); 493 sqlite3_free(pSrc->zTab); 494 sqlite3_free(pSrc->zFile); 495 sqlite3_free(pSrc->zContext); 496 } 497 sqlite3_finalize(pTab->pNotFound); 498 sqlite3_finalize(pTab->pOpenClose); 499 sqlite3_free(pTab->zSourceStr); 500 sqlite3_free(pTab->aSrc); 501 sqlite3_free(pTab); 502 } 503 return SQLITE_OK; 504 } 505 506 /* 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. 511 */ 512 static int unionIsIntkeyTable( 513 sqlite3 *db, /* Database handle */ 514 UnionSrc *pSrc, /* Source table to test */ 515 char **pzErr /* OUT: Error message */ 516 ){ 517 int bPk = 0; 518 const char *zType = 0; 519 int rc; 520 521 sqlite3_table_column_metadata( 522 db, pSrc->zDb, pSrc->zTab, "_rowid_", &zType, 0, 0, &bPk, 0 523 ); 524 rc = sqlite3_errcode(db); 525 if( rc==SQLITE_ERROR 526 || (rc==SQLITE_OK && (!bPk || sqlite3_stricmp("integer", zType))) 527 ){ 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 533 ); 534 } 535 return rc; 536 } 537 538 /* 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. 541 ** 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. 547 ** 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. 554 */ 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 */ 560 ){ 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 568 ); 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); 575 } 576 unionFinalize(&rc, pStmt, pzErr); 577 } 578 *pRc = rc; 579 } 580 581 return zRet; 582 } 583 584 /* 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. 591 */ 592 static int unionSourceCheck(UnionTab *pTab, char **pzErr){ 593 int rc = SQLITE_OK; 594 char *z0 = 0; 595 int i; 596 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; 604 } 605 sqlite3_free(z); 606 } 607 sqlite3_free(z0); 608 609 return rc; 610 } 611 612 /* 613 ** Try to open the swarmvtab database. If initially unable, invoke the 614 ** not-found callback UDF and then try again. 615 */ 616 static int unionOpenDatabaseInner(UnionTab *pTab, UnionSrc *pSrc, char **pzErr){ 617 static const int openFlags = SQLITE_OPEN_READONLY | SQLITE_OPEN_URI; 618 int rc; 619 620 rc = unionInvokeOpenClose(pTab, pSrc, 0, pzErr); 621 if( rc!=SQLITE_OK ) return rc; 622 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); 631 } 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; 636 } 637 rc = sqlite3_open_v2(pSrc->zFile, &pSrc->db, openFlags, 0); 638 } 639 if( rc!=SQLITE_OK ){ 640 *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(pSrc->db)); 641 } 642 return rc; 643 } 644 645 /* 646 ** This function may only be called for swarmvtab tables. The results of 647 ** calling it on a unionvtab table are undefined. 648 ** 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. 653 ** 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(). 659 */ 660 static int unionOpenDatabase(UnionTab *pTab, int iSrc, char **pzErr){ 661 int rc = SQLITE_OK; 662 UnionSrc *pSrc = &pTab->aSrc[iSrc]; 663 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; 677 } 678 sqlite3_free(z); 679 } 680 } 681 } 682 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); 691 } 692 } 693 694 return rc; 695 } 696 697 698 /* 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. 703 */ 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; 713 } 714 pSrc->nUser++; 715 } 716 } 717 718 /* 719 ** Finalize the SQL statement pCsr->pStmt and return the result. 720 ** 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. 725 */ 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; 739 } 740 unionCloseSources(pTab, pTab->nMaxOpen); 741 } 742 } 743 return rc; 744 } 745 746 /* 747 ** Return true if the argument is a space, tab, CR or LF character. 748 */ 749 static int union_isspace(char c){ 750 return (c==' ' || c=='\n' || c=='\r' || c=='\t'); 751 } 752 753 /* 754 ** Return true if the argument is an alphanumeric character in the 755 ** ASCII range. 756 */ 757 static int union_isidchar(char c){ 758 return ((c>='a' && c<='z') || (c>='A' && c<'Z') || (c>='0' && c<='9')); 759 } 760 761 /* 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. 767 ** 768 ** Refer to header comments at the top of this file for a description 769 ** of the arguments parsed. 770 ** 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(). 776 */ 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 */ 784 ){ 785 int rc = *pRc; 786 int i; 787 if( rc==SQLITE_OK ){ 788 pTab->bHasContext = (sqlite3_column_count(pStmt)>4); 789 } 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 */ 796 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); 804 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 819 ); 820 rc = SQLITE_ERROR; 821 }else{ 822 rc = sqlite3_bind_text(pStmt, iParam, zVal, -1, SQLITE_TRANSIENT); 823 } 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; 829 } 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 ? ",?" : "" 838 ); 839 } 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 ? ",?" : "" 848 ); 849 } 850 }else{ 851 *pzErr = sqlite3_mprintf("swarmvtab: unrecognized option: %s",zOpt); 852 rc = SQLITE_ERROR; 853 } 854 sqlite3_free(zVal); 855 } 856 }else{ 857 if( i==0 && nArg==1 ){ 858 pTab->pNotFound = unionPreparePrintf(&rc, pzErr, pTab->db, 859 "SELECT \"%w\"(?)", zArg 860 ); 861 }else{ 862 *pzErr = sqlite3_mprintf( "swarmvtab: parse error: %s", azArg[i]); 863 rc = SQLITE_ERROR; 864 } 865 } 866 sqlite3_free(zArg); 867 } 868 } 869 *pRc = rc; 870 } 871 872 /* 873 ** xConnect/xCreate method. 874 ** 875 ** The argv[] array contains the following: 876 ** 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 882 */ 883 static int unionConnect( 884 sqlite3 *db, 885 void *pAux, 886 int argc, const char *const*argv, 887 sqlite3_vtab **ppVtab, 888 char **pzErr 889 ){ 890 UnionTab *pTab = 0; 891 int rc = SQLITE_OK; 892 int bSwarm = (pAux==0 ? 0 : 1); 893 const char *zVtab = (bSwarm ? "swarmvtab" : "unionvtab"); 894 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 */ 906 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 914 ); 915 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; 923 } 924 925 /* Parse other CVT arguments, if any */ 926 if( bSwarm ){ 927 unionConfigureVtab(&rc, pTab, pStmt, argc-4, &argv[4], pzErr); 928 } 929 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; 938 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_realloc64( 943 pTab->aSrc, nNew*sizeof(UnionSrc) 944 ); 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; 952 } 953 } 954 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; 959 } 960 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); 970 } 971 if( pTab->bHasContext ){ 972 const char *zContext = (const char*)sqlite3_column_text(pStmt, 4); 973 pSrc->zContext = unionStrdup(&rc, zContext); 974 } 975 } 976 } 977 unionFinalize(&rc, pStmt, pzErr); 978 pStmt = 0; 979 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; 986 } 987 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); 996 } 997 } 998 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 1010 ); 1011 } 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); 1016 } 1017 1018 unionFinalize(&rc, pStmt, pzErr); 1019 } 1020 1021 if( rc!=SQLITE_OK ){ 1022 unionDisconnect((sqlite3_vtab*)pTab); 1023 pTab = 0; 1024 } 1025 1026 *ppVtab = (sqlite3_vtab*)pTab; 1027 return rc; 1028 } 1029 1030 /* 1031 ** xOpen 1032 */ 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; 1040 } 1041 1042 /* 1043 ** xClose 1044 */ 1045 static int unionClose(sqlite3_vtab_cursor *cur){ 1046 UnionCsr *pCsr = (UnionCsr*)cur; 1047 unionFinalizeCsrStmt(pCsr); 1048 sqlite3_free(pCsr); 1049 return SQLITE_OK; 1050 } 1051 1052 /* 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. 1056 */ 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 1075 ); 1076 if( rc==SQLITE_OK ){ 1077 assert( pCsr->pStmt ); 1078 unionIncrRefcount(pTab, pCsr->iTab); 1079 rc = SQLITE_ROW; 1080 } 1081 } 1082 } 1083 } 1084 } 1085 1086 return rc; 1087 } 1088 1089 /* 1090 ** xNext 1091 */ 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; 1098 } 1099 1100 /* 1101 ** xColumn 1102 */ 1103 static int unionColumn( 1104 sqlite3_vtab_cursor *cur, 1105 sqlite3_context *ctx, 1106 int i 1107 ){ 1108 UnionCsr *pCsr = (UnionCsr*)cur; 1109 sqlite3_result_value(ctx, sqlite3_column_value(pCsr->pStmt, i+1)); 1110 return SQLITE_OK; 1111 } 1112 1113 /* 1114 ** xRowid 1115 */ 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; 1120 } 1121 1122 /* 1123 ** xEof 1124 */ 1125 static int unionEof(sqlite3_vtab_cursor *cur){ 1126 UnionCsr *pCsr = (UnionCsr*)cur; 1127 return pCsr->pStmt==0; 1128 } 1129 1130 /* 1131 ** xFilter 1132 */ 1133 static int unionFilter( 1134 sqlite3_vtab_cursor *pVtabCursor, 1135 int idxNum, const char *idxStr, 1136 int argc, sqlite3_value **argv 1137 ){ 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; 1144 1145 sqlite3_int64 iMin = SMALLEST_INT64; 1146 sqlite3_int64 iMax = LARGEST_INT64; 1147 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) 1155 ); 1156 1157 (void)idxStr; /* Suppress harmless warning */ 1158 1159 if( idxNum==SQLITE_INDEX_CONSTRAINT_EQ ){ 1160 assert( argc==1 ); 1161 iMin = iMax = sqlite3_value_int64(argv[0]); 1162 }else{ 1163 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--; 1172 } 1173 } 1174 } 1175 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++; 1184 } 1185 } 1186 } 1187 } 1188 1189 unionFinalizeCsrStmt(pCsr); 1190 if( bZero ){ 1191 return SQLITE_OK; 1192 } 1193 1194 for(i=0; i<pTab->nSrc; i++){ 1195 UnionSrc *pSrc = &pTab->aSrc[i]; 1196 if( iMin>pSrc->iMax || iMax<pSrc->iMin ){ 1197 continue; 1198 } 1199 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 1207 ); 1208 if( zSql==0 ){ 1209 rc = SQLITE_NOMEM; 1210 break; 1211 } 1212 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"; 1220 } 1221 if( iMax!=LARGEST_INT64 && iMax<pSrc->iMax ){ 1222 zSql = sqlite3_mprintf("%z %s rowid<=%lld", zSql, zWhere, iMax); 1223 } 1224 } 1225 1226 if( pTab->bSwarm ){ 1227 pCsr->iTab = i; 1228 pCsr->iMaxRowid = iMax; 1229 rc = unionOpenDatabase(pTab, i, &pTab->base.zErrMsg); 1230 break; 1231 } 1232 } 1233 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); 1241 } 1242 sqlite3_free(zSql); 1243 } 1244 if( rc!=SQLITE_OK ) return rc; 1245 return unionNext(pVtabCursor); 1246 } 1247 1248 /* 1249 ** xBestIndex. 1250 ** 1251 ** This implementation searches for constraints on the rowid field. EQ, 1252 ** LE, LT, GE and GT are handled. 1253 ** 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. 1257 ** 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. 1265 */ 1266 static int unionBestIndex( 1267 sqlite3_vtab *tab, 1268 sqlite3_index_info *pIdxInfo 1269 ){ 1270 UnionTab *pTab = (UnionTab*)tab; 1271 int iEq = -1; 1272 int iLt = -1; 1273 int iGt = -1; 1274 int i; 1275 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; 1291 } 1292 } 1293 } 1294 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; 1311 } 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; 1317 } 1318 pIdxInfo->estimatedRows = nRow; 1319 pIdxInfo->estimatedCost = 3.0 * (double)nRow; 1320 pIdxInfo->idxNum = idxNum; 1321 } 1322 1323 return SQLITE_OK; 1324 } 1325 1326 /* 1327 ** Register the unionvtab virtual table module with database handle db. 1328 */ 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 */ 1354 0 /* xShadowName */ 1355 }; 1356 int rc; 1357 1358 rc = sqlite3_create_module(db, "unionvtab", &unionModule, 0); 1359 if( rc==SQLITE_OK ){ 1360 rc = sqlite3_create_module(db, "swarmvtab", &unionModule, (void*)db); 1361 } 1362 return rc; 1363 } 1364 1365 #endif /* SQLITE_OMIT_VIRTUALTABLE */ 1366 1367 #ifdef _WIN32 1368 __declspec(dllexport) 1369 #endif 1370 int sqlite3_unionvtab_init( 1371 sqlite3 *db, 1372 char **pzErrMsg, 1373 const sqlite3_api_routines *pApi 1374 ){ 1375 int rc = SQLITE_OK; 1376 SQLITE_EXTENSION_INIT2(pApi); 1377 (void)pzErrMsg; /* Suppress harmless warning */ 1378 #ifndef SQLITE_OMIT_VIRTUALTABLE 1379 rc = createUnionVtab(db); 1380 #endif 1381 return rc; 1382 } 1383