1 /* 2 ** 2017 April 09 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 #include "sqlite3expert.h" 14 #include <assert.h> 15 #include <string.h> 16 #include <stdio.h> 17 18 typedef sqlite3_int64 i64; 19 typedef sqlite3_uint64 u64; 20 21 typedef struct IdxColumn IdxColumn; 22 typedef struct IdxConstraint IdxConstraint; 23 typedef struct IdxScan IdxScan; 24 typedef struct IdxStatement IdxStatement; 25 typedef struct IdxTable IdxTable; 26 typedef struct IdxWrite IdxWrite; 27 28 #define STRLEN (int)strlen 29 30 /* 31 ** A temp table name that we assume no user database will actually use. 32 ** If this assumption proves incorrect triggers on the table with the 33 ** conflicting name will be ignored. 34 */ 35 #define UNIQUE_TABLE_NAME "t592690916721053953805701627921227776" 36 37 /* 38 ** A single constraint. Equivalent to either "col = ?" or "col < ?" (or 39 ** any other type of single-ended range constraint on a column). 40 ** 41 ** pLink: 42 ** Used to temporarily link IdxConstraint objects into lists while 43 ** creating candidate indexes. 44 */ 45 struct IdxConstraint { 46 char *zColl; /* Collation sequence */ 47 int bRange; /* True for range, false for eq */ 48 int iCol; /* Constrained table column */ 49 int bFlag; /* Used by idxFindCompatible() */ 50 int bDesc; /* True if ORDER BY <expr> DESC */ 51 IdxConstraint *pNext; /* Next constraint in pEq or pRange list */ 52 IdxConstraint *pLink; /* See above */ 53 }; 54 55 /* 56 ** A single scan of a single table. 57 */ 58 struct IdxScan { 59 IdxTable *pTab; /* Associated table object */ 60 int iDb; /* Database containing table zTable */ 61 i64 covering; /* Mask of columns required for cov. index */ 62 IdxConstraint *pOrder; /* ORDER BY columns */ 63 IdxConstraint *pEq; /* List of == constraints */ 64 IdxConstraint *pRange; /* List of < constraints */ 65 IdxScan *pNextScan; /* Next IdxScan object for same analysis */ 66 }; 67 68 /* 69 ** Information regarding a single database table. Extracted from 70 ** "PRAGMA table_info" by function idxGetTableInfo(). 71 */ 72 struct IdxColumn { 73 char *zName; 74 char *zColl; 75 int iPk; 76 }; 77 struct IdxTable { 78 int nCol; 79 char *zName; /* Table name */ 80 IdxColumn *aCol; 81 IdxTable *pNext; /* Next table in linked list of all tables */ 82 }; 83 84 /* 85 ** An object of the following type is created for each unique table/write-op 86 ** seen. The objects are stored in a singly-linked list beginning at 87 ** sqlite3expert.pWrite. 88 */ 89 struct IdxWrite { 90 IdxTable *pTab; 91 int eOp; /* SQLITE_UPDATE, DELETE or INSERT */ 92 IdxWrite *pNext; 93 }; 94 95 /* 96 ** Each statement being analyzed is represented by an instance of this 97 ** structure. 98 */ 99 struct IdxStatement { 100 int iId; /* Statement number */ 101 char *zSql; /* SQL statement */ 102 char *zIdx; /* Indexes */ 103 char *zEQP; /* Plan */ 104 IdxStatement *pNext; 105 }; 106 107 108 /* 109 ** A hash table for storing strings. With space for a payload string 110 ** with each entry. Methods are: 111 ** 112 ** idxHashInit() 113 ** idxHashClear() 114 ** idxHashAdd() 115 ** idxHashSearch() 116 */ 117 #define IDX_HASH_SIZE 1023 118 typedef struct IdxHashEntry IdxHashEntry; 119 typedef struct IdxHash IdxHash; 120 struct IdxHashEntry { 121 char *zKey; /* nul-terminated key */ 122 char *zVal; /* nul-terminated value string */ 123 char *zVal2; /* nul-terminated value string 2 */ 124 IdxHashEntry *pHashNext; /* Next entry in same hash bucket */ 125 IdxHashEntry *pNext; /* Next entry in hash */ 126 }; 127 struct IdxHash { 128 IdxHashEntry *pFirst; 129 IdxHashEntry *aHash[IDX_HASH_SIZE]; 130 }; 131 132 /* 133 ** sqlite3expert object. 134 */ 135 struct sqlite3expert { 136 int iSample; /* Percentage of tables to sample for stat1 */ 137 sqlite3 *db; /* User database */ 138 sqlite3 *dbm; /* In-memory db for this analysis */ 139 sqlite3 *dbv; /* Vtab schema for this analysis */ 140 IdxTable *pTable; /* List of all IdxTable objects */ 141 IdxScan *pScan; /* List of scan objects */ 142 IdxWrite *pWrite; /* List of write objects */ 143 IdxStatement *pStatement; /* List of IdxStatement objects */ 144 int bRun; /* True once analysis has run */ 145 char **pzErrmsg; 146 int rc; /* Error code from whereinfo hook */ 147 IdxHash hIdx; /* Hash containing all candidate indexes */ 148 char *zCandidates; /* For EXPERT_REPORT_CANDIDATES */ 149 }; 150 151 152 /* 153 ** Allocate and return nByte bytes of zeroed memory using sqlite3_malloc(). 154 ** If the allocation fails, set *pRc to SQLITE_NOMEM and return NULL. 155 */ 156 static void *idxMalloc(int *pRc, int nByte){ 157 void *pRet; 158 assert( *pRc==SQLITE_OK ); 159 assert( nByte>0 ); 160 pRet = sqlite3_malloc(nByte); 161 if( pRet ){ 162 memset(pRet, 0, nByte); 163 }else{ 164 *pRc = SQLITE_NOMEM; 165 } 166 return pRet; 167 } 168 169 /* 170 ** Initialize an IdxHash hash table. 171 */ 172 static void idxHashInit(IdxHash *pHash){ 173 memset(pHash, 0, sizeof(IdxHash)); 174 } 175 176 /* 177 ** Reset an IdxHash hash table. 178 */ 179 static void idxHashClear(IdxHash *pHash){ 180 int i; 181 for(i=0; i<IDX_HASH_SIZE; i++){ 182 IdxHashEntry *pEntry; 183 IdxHashEntry *pNext; 184 for(pEntry=pHash->aHash[i]; pEntry; pEntry=pNext){ 185 pNext = pEntry->pHashNext; 186 sqlite3_free(pEntry->zVal2); 187 sqlite3_free(pEntry); 188 } 189 } 190 memset(pHash, 0, sizeof(IdxHash)); 191 } 192 193 /* 194 ** Return the index of the hash bucket that the string specified by the 195 ** arguments to this function belongs. 196 */ 197 static int idxHashString(const char *z, int n){ 198 unsigned int ret = 0; 199 int i; 200 for(i=0; i<n; i++){ 201 ret += (ret<<3) + (unsigned char)(z[i]); 202 } 203 return (int)(ret % IDX_HASH_SIZE); 204 } 205 206 /* 207 ** If zKey is already present in the hash table, return non-zero and do 208 ** nothing. Otherwise, add an entry with key zKey and payload string zVal to 209 ** the hash table passed as the second argument. 210 */ 211 static int idxHashAdd( 212 int *pRc, 213 IdxHash *pHash, 214 const char *zKey, 215 const char *zVal 216 ){ 217 int nKey = STRLEN(zKey); 218 int iHash = idxHashString(zKey, nKey); 219 int nVal = (zVal ? STRLEN(zVal) : 0); 220 IdxHashEntry *pEntry; 221 assert( iHash>=0 ); 222 for(pEntry=pHash->aHash[iHash]; pEntry; pEntry=pEntry->pHashNext){ 223 if( STRLEN(pEntry->zKey)==nKey && 0==memcmp(pEntry->zKey, zKey, nKey) ){ 224 return 1; 225 } 226 } 227 pEntry = idxMalloc(pRc, sizeof(IdxHashEntry) + nKey+1 + nVal+1); 228 if( pEntry ){ 229 pEntry->zKey = (char*)&pEntry[1]; 230 memcpy(pEntry->zKey, zKey, nKey); 231 if( zVal ){ 232 pEntry->zVal = &pEntry->zKey[nKey+1]; 233 memcpy(pEntry->zVal, zVal, nVal); 234 } 235 pEntry->pHashNext = pHash->aHash[iHash]; 236 pHash->aHash[iHash] = pEntry; 237 238 pEntry->pNext = pHash->pFirst; 239 pHash->pFirst = pEntry; 240 } 241 return 0; 242 } 243 244 /* 245 ** If zKey/nKey is present in the hash table, return a pointer to the 246 ** hash-entry object. 247 */ 248 static IdxHashEntry *idxHashFind(IdxHash *pHash, const char *zKey, int nKey){ 249 int iHash; 250 IdxHashEntry *pEntry; 251 if( nKey<0 ) nKey = STRLEN(zKey); 252 iHash = idxHashString(zKey, nKey); 253 assert( iHash>=0 ); 254 for(pEntry=pHash->aHash[iHash]; pEntry; pEntry=pEntry->pHashNext){ 255 if( STRLEN(pEntry->zKey)==nKey && 0==memcmp(pEntry->zKey, zKey, nKey) ){ 256 return pEntry; 257 } 258 } 259 return 0; 260 } 261 262 /* 263 ** If the hash table contains an entry with a key equal to the string 264 ** passed as the final two arguments to this function, return a pointer 265 ** to the payload string. Otherwise, if zKey/nKey is not present in the 266 ** hash table, return NULL. 267 */ 268 static const char *idxHashSearch(IdxHash *pHash, const char *zKey, int nKey){ 269 IdxHashEntry *pEntry = idxHashFind(pHash, zKey, nKey); 270 if( pEntry ) return pEntry->zVal; 271 return 0; 272 } 273 274 /* 275 ** Allocate and return a new IdxConstraint object. Set the IdxConstraint.zColl 276 ** variable to point to a copy of nul-terminated string zColl. 277 */ 278 static IdxConstraint *idxNewConstraint(int *pRc, const char *zColl){ 279 IdxConstraint *pNew; 280 int nColl = STRLEN(zColl); 281 282 assert( *pRc==SQLITE_OK ); 283 pNew = (IdxConstraint*)idxMalloc(pRc, sizeof(IdxConstraint) * nColl + 1); 284 if( pNew ){ 285 pNew->zColl = (char*)&pNew[1]; 286 memcpy(pNew->zColl, zColl, nColl+1); 287 } 288 return pNew; 289 } 290 291 /* 292 ** An error associated with database handle db has just occurred. Pass 293 ** the error message to callback function xOut. 294 */ 295 static void idxDatabaseError( 296 sqlite3 *db, /* Database handle */ 297 char **pzErrmsg /* Write error here */ 298 ){ 299 *pzErrmsg = sqlite3_mprintf("%s", sqlite3_errmsg(db)); 300 } 301 302 /* 303 ** Prepare an SQL statement. 304 */ 305 static int idxPrepareStmt( 306 sqlite3 *db, /* Database handle to compile against */ 307 sqlite3_stmt **ppStmt, /* OUT: Compiled SQL statement */ 308 char **pzErrmsg, /* OUT: sqlite3_malloc()ed error message */ 309 const char *zSql /* SQL statement to compile */ 310 ){ 311 int rc = sqlite3_prepare_v2(db, zSql, -1, ppStmt, 0); 312 if( rc!=SQLITE_OK ){ 313 *ppStmt = 0; 314 idxDatabaseError(db, pzErrmsg); 315 } 316 return rc; 317 } 318 319 /* 320 ** Prepare an SQL statement using the results of a printf() formatting. 321 */ 322 static int idxPrintfPrepareStmt( 323 sqlite3 *db, /* Database handle to compile against */ 324 sqlite3_stmt **ppStmt, /* OUT: Compiled SQL statement */ 325 char **pzErrmsg, /* OUT: sqlite3_malloc()ed error message */ 326 const char *zFmt, /* printf() format of SQL statement */ 327 ... /* Trailing printf() arguments */ 328 ){ 329 va_list ap; 330 int rc; 331 char *zSql; 332 va_start(ap, zFmt); 333 zSql = sqlite3_vmprintf(zFmt, ap); 334 if( zSql==0 ){ 335 rc = SQLITE_NOMEM; 336 }else{ 337 rc = idxPrepareStmt(db, ppStmt, pzErrmsg, zSql); 338 sqlite3_free(zSql); 339 } 340 va_end(ap); 341 return rc; 342 } 343 344 345 /************************************************************************* 346 ** Beginning of virtual table implementation. 347 */ 348 typedef struct ExpertVtab ExpertVtab; 349 struct ExpertVtab { 350 sqlite3_vtab base; 351 IdxTable *pTab; 352 sqlite3expert *pExpert; 353 }; 354 355 typedef struct ExpertCsr ExpertCsr; 356 struct ExpertCsr { 357 sqlite3_vtab_cursor base; 358 sqlite3_stmt *pData; 359 }; 360 361 static char *expertDequote(const char *zIn){ 362 int n = STRLEN(zIn); 363 char *zRet = sqlite3_malloc(n); 364 365 assert( zIn[0]=='\'' ); 366 assert( zIn[n-1]=='\'' ); 367 368 if( zRet ){ 369 int iOut = 0; 370 int iIn = 0; 371 for(iIn=1; iIn<(n-1); iIn++){ 372 if( zIn[iIn]=='\'' ){ 373 assert( zIn[iIn+1]=='\'' ); 374 iIn++; 375 } 376 zRet[iOut++] = zIn[iIn]; 377 } 378 zRet[iOut] = '\0'; 379 } 380 381 return zRet; 382 } 383 384 /* 385 ** This function is the implementation of both the xConnect and xCreate 386 ** methods of the r-tree virtual table. 387 ** 388 ** argv[0] -> module name 389 ** argv[1] -> database name 390 ** argv[2] -> table name 391 ** argv[...] -> column names... 392 */ 393 static int expertConnect( 394 sqlite3 *db, 395 void *pAux, 396 int argc, const char *const*argv, 397 sqlite3_vtab **ppVtab, 398 char **pzErr 399 ){ 400 sqlite3expert *pExpert = (sqlite3expert*)pAux; 401 ExpertVtab *p = 0; 402 int rc; 403 404 if( argc!=4 ){ 405 *pzErr = sqlite3_mprintf("internal error!"); 406 rc = SQLITE_ERROR; 407 }else{ 408 char *zCreateTable = expertDequote(argv[3]); 409 if( zCreateTable ){ 410 rc = sqlite3_declare_vtab(db, zCreateTable); 411 if( rc==SQLITE_OK ){ 412 p = idxMalloc(&rc, sizeof(ExpertVtab)); 413 } 414 if( rc==SQLITE_OK ){ 415 p->pExpert = pExpert; 416 p->pTab = pExpert->pTable; 417 assert( sqlite3_stricmp(p->pTab->zName, argv[2])==0 ); 418 } 419 sqlite3_free(zCreateTable); 420 }else{ 421 rc = SQLITE_NOMEM; 422 } 423 } 424 425 *ppVtab = (sqlite3_vtab*)p; 426 return rc; 427 } 428 429 static int expertDisconnect(sqlite3_vtab *pVtab){ 430 ExpertVtab *p = (ExpertVtab*)pVtab; 431 sqlite3_free(p); 432 return SQLITE_OK; 433 } 434 435 static int expertBestIndex(sqlite3_vtab *pVtab, sqlite3_index_info *pIdxInfo){ 436 ExpertVtab *p = (ExpertVtab*)pVtab; 437 sqlite3 *dbv = p->pExpert->dbv; 438 int rc = SQLITE_OK; 439 int n = 0; 440 IdxScan *pScan; 441 const int opmask = 442 SQLITE_INDEX_CONSTRAINT_EQ | SQLITE_INDEX_CONSTRAINT_GT | 443 SQLITE_INDEX_CONSTRAINT_LT | SQLITE_INDEX_CONSTRAINT_GE | 444 SQLITE_INDEX_CONSTRAINT_LE; 445 446 pScan = idxMalloc(&rc, sizeof(IdxScan)); 447 if( pScan ){ 448 int i; 449 450 /* Link the new scan object into the list */ 451 pScan->pTab = p->pTab; 452 pScan->pNextScan = p->pExpert->pScan; 453 p->pExpert->pScan = pScan; 454 455 /* Add the constraints to the IdxScan object */ 456 for(i=0; i<pIdxInfo->nConstraint; i++){ 457 struct sqlite3_index_constraint *pCons = &pIdxInfo->aConstraint[i]; 458 if( pCons->usable 459 && pCons->iColumn>=0 460 && p->pTab->aCol[pCons->iColumn].iPk==0 461 && (pCons->op & opmask) 462 ){ 463 IdxConstraint *pNew; 464 const char *zColl = sqlite3_vtab_collation(dbv, i); 465 pNew = idxNewConstraint(&rc, zColl); 466 if( pNew ){ 467 pNew->iCol = pCons->iColumn; 468 if( pCons->op==SQLITE_INDEX_CONSTRAINT_EQ ){ 469 pNew->pNext = pScan->pEq; 470 pScan->pEq = pNew; 471 }else{ 472 pNew->bRange = 1; 473 pNew->pNext = pScan->pRange; 474 pScan->pRange = pNew; 475 } 476 } 477 n++; 478 pIdxInfo->aConstraintUsage[i].argvIndex = n; 479 } 480 } 481 482 /* Add the ORDER BY to the IdxScan object */ 483 for(i=pIdxInfo->nOrderBy-1; i>=0; i--){ 484 int iCol = pIdxInfo->aOrderBy[i].iColumn; 485 if( iCol>=0 ){ 486 IdxConstraint *pNew = idxNewConstraint(&rc, p->pTab->aCol[iCol].zColl); 487 if( pNew ){ 488 pNew->iCol = iCol; 489 pNew->bDesc = pIdxInfo->aOrderBy[i].desc; 490 pNew->pNext = pScan->pOrder; 491 pNew->pLink = pScan->pOrder; 492 pScan->pOrder = pNew; 493 n++; 494 } 495 } 496 } 497 } 498 499 pIdxInfo->estimatedCost = 1000000.0 / n; 500 return rc; 501 } 502 503 static int expertUpdate( 504 sqlite3_vtab *pVtab, 505 int nData, 506 sqlite3_value **azData, 507 sqlite_int64 *pRowid 508 ){ 509 return SQLITE_OK; 510 } 511 512 /* 513 ** Virtual table module xOpen method. 514 */ 515 static int expertOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){ 516 int rc = SQLITE_OK; 517 ExpertCsr *pCsr; 518 pCsr = idxMalloc(&rc, sizeof(ExpertCsr)); 519 *ppCursor = (sqlite3_vtab_cursor*)pCsr; 520 return rc; 521 } 522 523 /* 524 ** Virtual table module xClose method. 525 */ 526 static int expertClose(sqlite3_vtab_cursor *cur){ 527 ExpertCsr *pCsr = (ExpertCsr*)cur; 528 sqlite3_finalize(pCsr->pData); 529 sqlite3_free(pCsr); 530 return SQLITE_OK; 531 } 532 533 /* 534 ** Virtual table module xEof method. 535 ** 536 ** Return non-zero if the cursor does not currently point to a valid 537 ** record (i.e if the scan has finished), or zero otherwise. 538 */ 539 static int expertEof(sqlite3_vtab_cursor *cur){ 540 ExpertCsr *pCsr = (ExpertCsr*)cur; 541 return pCsr->pData==0; 542 } 543 544 /* 545 ** Virtual table module xNext method. 546 */ 547 static int expertNext(sqlite3_vtab_cursor *cur){ 548 ExpertCsr *pCsr = (ExpertCsr*)cur; 549 int rc = SQLITE_OK; 550 551 assert( pCsr->pData ); 552 rc = sqlite3_step(pCsr->pData); 553 if( rc!=SQLITE_ROW ){ 554 rc = sqlite3_finalize(pCsr->pData); 555 pCsr->pData = 0; 556 }else{ 557 rc = SQLITE_OK; 558 } 559 560 return rc; 561 } 562 563 /* 564 ** Virtual table module xRowid method. 565 */ 566 static int expertRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){ 567 *pRowid = 0; 568 return SQLITE_OK; 569 } 570 571 /* 572 ** Virtual table module xColumn method. 573 */ 574 static int expertColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){ 575 ExpertCsr *pCsr = (ExpertCsr*)cur; 576 sqlite3_value *pVal; 577 pVal = sqlite3_column_value(pCsr->pData, i); 578 if( pVal ){ 579 sqlite3_result_value(ctx, pVal); 580 } 581 return SQLITE_OK; 582 } 583 584 /* 585 ** Virtual table module xFilter method. 586 */ 587 static int expertFilter( 588 sqlite3_vtab_cursor *cur, 589 int idxNum, const char *idxStr, 590 int argc, sqlite3_value **argv 591 ){ 592 ExpertCsr *pCsr = (ExpertCsr*)cur; 593 ExpertVtab *pVtab = (ExpertVtab*)(cur->pVtab); 594 sqlite3expert *pExpert = pVtab->pExpert; 595 int rc; 596 597 rc = sqlite3_finalize(pCsr->pData); 598 pCsr->pData = 0; 599 if( rc==SQLITE_OK ){ 600 rc = idxPrintfPrepareStmt(pExpert->db, &pCsr->pData, &pVtab->base.zErrMsg, 601 "SELECT * FROM main.%Q WHERE sample()", pVtab->pTab->zName 602 ); 603 } 604 605 if( rc==SQLITE_OK ){ 606 rc = expertNext(cur); 607 } 608 return rc; 609 } 610 611 static int idxRegisterVtab(sqlite3expert *p){ 612 static sqlite3_module expertModule = { 613 2, /* iVersion */ 614 expertConnect, /* xCreate - create a table */ 615 expertConnect, /* xConnect - connect to an existing table */ 616 expertBestIndex, /* xBestIndex - Determine search strategy */ 617 expertDisconnect, /* xDisconnect - Disconnect from a table */ 618 expertDisconnect, /* xDestroy - Drop a table */ 619 expertOpen, /* xOpen - open a cursor */ 620 expertClose, /* xClose - close a cursor */ 621 expertFilter, /* xFilter - configure scan constraints */ 622 expertNext, /* xNext - advance a cursor */ 623 expertEof, /* xEof */ 624 expertColumn, /* xColumn - read data */ 625 expertRowid, /* xRowid - read data */ 626 expertUpdate, /* xUpdate - write data */ 627 0, /* xBegin - begin transaction */ 628 0, /* xSync - sync transaction */ 629 0, /* xCommit - commit transaction */ 630 0, /* xRollback - rollback transaction */ 631 0, /* xFindFunction - function overloading */ 632 0, /* xRename - rename the table */ 633 0, /* xSavepoint */ 634 0, /* xRelease */ 635 0, /* xRollbackTo */ 636 }; 637 638 return sqlite3_create_module(p->dbv, "expert", &expertModule, (void*)p); 639 } 640 /* 641 ** End of virtual table implementation. 642 *************************************************************************/ 643 /* 644 ** Finalize SQL statement pStmt. If (*pRc) is SQLITE_OK when this function 645 ** is called, set it to the return value of sqlite3_finalize() before 646 ** returning. Otherwise, discard the sqlite3_finalize() return value. 647 */ 648 static void idxFinalize(int *pRc, sqlite3_stmt *pStmt){ 649 int rc = sqlite3_finalize(pStmt); 650 if( *pRc==SQLITE_OK ) *pRc = rc; 651 } 652 653 /* 654 ** Attempt to allocate an IdxTable structure corresponding to table zTab 655 ** in the main database of connection db. If successful, set (*ppOut) to 656 ** point to the new object and return SQLITE_OK. Otherwise, return an 657 ** SQLite error code and set (*ppOut) to NULL. In this case *pzErrmsg may be 658 ** set to point to an error string. 659 ** 660 ** It is the responsibility of the caller to eventually free either the 661 ** IdxTable object or error message using sqlite3_free(). 662 */ 663 static int idxGetTableInfo( 664 sqlite3 *db, /* Database connection to read details from */ 665 const char *zTab, /* Table name */ 666 IdxTable **ppOut, /* OUT: New object (if successful) */ 667 char **pzErrmsg /* OUT: Error message (if not) */ 668 ){ 669 sqlite3_stmt *p1 = 0; 670 int nCol = 0; 671 int nTab = STRLEN(zTab); 672 int nByte = sizeof(IdxTable) + nTab + 1; 673 IdxTable *pNew = 0; 674 int rc, rc2; 675 char *pCsr = 0; 676 677 rc = idxPrintfPrepareStmt(db, &p1, pzErrmsg, "PRAGMA table_info=%Q", zTab); 678 while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(p1) ){ 679 const char *zCol = (const char*)sqlite3_column_text(p1, 1); 680 nByte += 1 + STRLEN(zCol); 681 rc = sqlite3_table_column_metadata( 682 db, "main", zTab, zCol, 0, &zCol, 0, 0, 0 683 ); 684 nByte += 1 + STRLEN(zCol); 685 nCol++; 686 } 687 rc2 = sqlite3_reset(p1); 688 if( rc==SQLITE_OK ) rc = rc2; 689 690 nByte += sizeof(IdxColumn) * nCol; 691 if( rc==SQLITE_OK ){ 692 pNew = idxMalloc(&rc, nByte); 693 } 694 if( rc==SQLITE_OK ){ 695 pNew->aCol = (IdxColumn*)&pNew[1]; 696 pNew->nCol = nCol; 697 pCsr = (char*)&pNew->aCol[nCol]; 698 } 699 700 nCol = 0; 701 while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(p1) ){ 702 const char *zCol = (const char*)sqlite3_column_text(p1, 1); 703 int nCopy = STRLEN(zCol) + 1; 704 pNew->aCol[nCol].zName = pCsr; 705 pNew->aCol[nCol].iPk = sqlite3_column_int(p1, 5); 706 memcpy(pCsr, zCol, nCopy); 707 pCsr += nCopy; 708 709 rc = sqlite3_table_column_metadata( 710 db, "main", zTab, zCol, 0, &zCol, 0, 0, 0 711 ); 712 if( rc==SQLITE_OK ){ 713 nCopy = STRLEN(zCol) + 1; 714 pNew->aCol[nCol].zColl = pCsr; 715 memcpy(pCsr, zCol, nCopy); 716 pCsr += nCopy; 717 } 718 719 nCol++; 720 } 721 idxFinalize(&rc, p1); 722 723 if( rc!=SQLITE_OK ){ 724 sqlite3_free(pNew); 725 pNew = 0; 726 }else{ 727 pNew->zName = pCsr; 728 memcpy(pNew->zName, zTab, nTab+1); 729 } 730 731 *ppOut = pNew; 732 return rc; 733 } 734 735 /* 736 ** This function is a no-op if *pRc is set to anything other than 737 ** SQLITE_OK when it is called. 738 ** 739 ** If *pRc is initially set to SQLITE_OK, then the text specified by 740 ** the printf() style arguments is appended to zIn and the result returned 741 ** in a buffer allocated by sqlite3_malloc(). sqlite3_free() is called on 742 ** zIn before returning. 743 */ 744 static char *idxAppendText(int *pRc, char *zIn, const char *zFmt, ...){ 745 va_list ap; 746 char *zAppend = 0; 747 char *zRet = 0; 748 int nIn = zIn ? STRLEN(zIn) : 0; 749 int nAppend = 0; 750 va_start(ap, zFmt); 751 if( *pRc==SQLITE_OK ){ 752 zAppend = sqlite3_vmprintf(zFmt, ap); 753 if( zAppend ){ 754 nAppend = STRLEN(zAppend); 755 zRet = (char*)sqlite3_malloc(nIn + nAppend + 1); 756 } 757 if( zAppend && zRet ){ 758 memcpy(zRet, zIn, nIn); 759 memcpy(&zRet[nIn], zAppend, nAppend+1); 760 }else{ 761 sqlite3_free(zRet); 762 zRet = 0; 763 *pRc = SQLITE_NOMEM; 764 } 765 sqlite3_free(zAppend); 766 sqlite3_free(zIn); 767 } 768 va_end(ap); 769 return zRet; 770 } 771 772 /* 773 ** Return true if zId must be quoted in order to use it as an SQL 774 ** identifier, or false otherwise. 775 */ 776 static int idxIdentifierRequiresQuotes(const char *zId){ 777 int i; 778 for(i=0; zId[i]; i++){ 779 if( !(zId[i]=='_') 780 && !(zId[i]>='0' && zId[i]<='9') 781 && !(zId[i]>='a' && zId[i]<='z') 782 && !(zId[i]>='A' && zId[i]<='Z') 783 ){ 784 return 1; 785 } 786 } 787 return 0; 788 } 789 790 /* 791 ** This function appends an index column definition suitable for constraint 792 ** pCons to the string passed as zIn and returns the result. 793 */ 794 static char *idxAppendColDefn( 795 int *pRc, /* IN/OUT: Error code */ 796 char *zIn, /* Column defn accumulated so far */ 797 IdxTable *pTab, /* Table index will be created on */ 798 IdxConstraint *pCons 799 ){ 800 char *zRet = zIn; 801 IdxColumn *p = &pTab->aCol[pCons->iCol]; 802 if( zRet ) zRet = idxAppendText(pRc, zRet, ", "); 803 804 if( idxIdentifierRequiresQuotes(p->zName) ){ 805 zRet = idxAppendText(pRc, zRet, "%Q", p->zName); 806 }else{ 807 zRet = idxAppendText(pRc, zRet, "%s", p->zName); 808 } 809 810 if( sqlite3_stricmp(p->zColl, pCons->zColl) ){ 811 if( idxIdentifierRequiresQuotes(pCons->zColl) ){ 812 zRet = idxAppendText(pRc, zRet, " COLLATE %Q", pCons->zColl); 813 }else{ 814 zRet = idxAppendText(pRc, zRet, " COLLATE %s", pCons->zColl); 815 } 816 } 817 818 if( pCons->bDesc ){ 819 zRet = idxAppendText(pRc, zRet, " DESC"); 820 } 821 return zRet; 822 } 823 824 /* 825 ** Search database dbm for an index compatible with the one idxCreateFromCons() 826 ** would create from arguments pScan, pEq and pTail. If no error occurs and 827 ** such an index is found, return non-zero. Or, if no such index is found, 828 ** return zero. 829 ** 830 ** If an error occurs, set *pRc to an SQLite error code and return zero. 831 */ 832 static int idxFindCompatible( 833 int *pRc, /* OUT: Error code */ 834 sqlite3* dbm, /* Database to search */ 835 IdxScan *pScan, /* Scan for table to search for index on */ 836 IdxConstraint *pEq, /* List of == constraints */ 837 IdxConstraint *pTail /* List of range constraints */ 838 ){ 839 const char *zTbl = pScan->pTab->zName; 840 sqlite3_stmt *pIdxList = 0; 841 IdxConstraint *pIter; 842 int nEq = 0; /* Number of elements in pEq */ 843 int rc; 844 845 /* Count the elements in list pEq */ 846 for(pIter=pEq; pIter; pIter=pIter->pLink) nEq++; 847 848 rc = idxPrintfPrepareStmt(dbm, &pIdxList, 0, "PRAGMA index_list=%Q", zTbl); 849 while( rc==SQLITE_OK && sqlite3_step(pIdxList)==SQLITE_ROW ){ 850 int bMatch = 1; 851 IdxConstraint *pT = pTail; 852 sqlite3_stmt *pInfo = 0; 853 const char *zIdx = (const char*)sqlite3_column_text(pIdxList, 1); 854 855 /* Zero the IdxConstraint.bFlag values in the pEq list */ 856 for(pIter=pEq; pIter; pIter=pIter->pLink) pIter->bFlag = 0; 857 858 rc = idxPrintfPrepareStmt(dbm, &pInfo, 0, "PRAGMA index_xInfo=%Q", zIdx); 859 while( rc==SQLITE_OK && sqlite3_step(pInfo)==SQLITE_ROW ){ 860 int iIdx = sqlite3_column_int(pInfo, 0); 861 int iCol = sqlite3_column_int(pInfo, 1); 862 const char *zColl = (const char*)sqlite3_column_text(pInfo, 4); 863 864 if( iIdx<nEq ){ 865 for(pIter=pEq; pIter; pIter=pIter->pLink){ 866 if( pIter->bFlag ) continue; 867 if( pIter->iCol!=iCol ) continue; 868 if( sqlite3_stricmp(pIter->zColl, zColl) ) continue; 869 pIter->bFlag = 1; 870 break; 871 } 872 if( pIter==0 ){ 873 bMatch = 0; 874 break; 875 } 876 }else{ 877 if( pT ){ 878 if( pT->iCol!=iCol || sqlite3_stricmp(pT->zColl, zColl) ){ 879 bMatch = 0; 880 break; 881 } 882 pT = pT->pLink; 883 } 884 } 885 } 886 idxFinalize(&rc, pInfo); 887 888 if( rc==SQLITE_OK && bMatch ){ 889 sqlite3_finalize(pIdxList); 890 return 1; 891 } 892 } 893 idxFinalize(&rc, pIdxList); 894 895 *pRc = rc; 896 return 0; 897 } 898 899 static int idxCreateFromCons( 900 sqlite3expert *p, 901 IdxScan *pScan, 902 IdxConstraint *pEq, 903 IdxConstraint *pTail 904 ){ 905 sqlite3 *dbm = p->dbm; 906 int rc = SQLITE_OK; 907 if( (pEq || pTail) && 0==idxFindCompatible(&rc, dbm, pScan, pEq, pTail) ){ 908 IdxTable *pTab = pScan->pTab; 909 char *zCols = 0; 910 char *zIdx = 0; 911 IdxConstraint *pCons; 912 int h = 0; 913 const char *zFmt; 914 915 for(pCons=pEq; pCons; pCons=pCons->pLink){ 916 zCols = idxAppendColDefn(&rc, zCols, pTab, pCons); 917 } 918 for(pCons=pTail; pCons; pCons=pCons->pLink){ 919 zCols = idxAppendColDefn(&rc, zCols, pTab, pCons); 920 } 921 922 if( rc==SQLITE_OK ){ 923 /* Hash the list of columns to come up with a name for the index */ 924 const char *zTable = pScan->pTab->zName; 925 char *zName; /* Index name */ 926 int i; 927 for(i=0; zCols[i]; i++){ 928 h += ((h<<3) + zCols[i]); 929 } 930 zName = sqlite3_mprintf("%s_idx_%08x", zTable, h); 931 if( zName==0 ){ 932 rc = SQLITE_NOMEM; 933 }else{ 934 if( idxIdentifierRequiresQuotes(zTable) ){ 935 zFmt = "CREATE INDEX '%q' ON %Q(%s)"; 936 }else{ 937 zFmt = "CREATE INDEX %s ON %s(%s)"; 938 } 939 zIdx = sqlite3_mprintf(zFmt, zName, zTable, zCols); 940 if( !zIdx ){ 941 rc = SQLITE_NOMEM; 942 }else{ 943 rc = sqlite3_exec(dbm, zIdx, 0, 0, p->pzErrmsg); 944 idxHashAdd(&rc, &p->hIdx, zName, zIdx); 945 } 946 sqlite3_free(zName); 947 sqlite3_free(zIdx); 948 } 949 } 950 951 sqlite3_free(zCols); 952 } 953 return rc; 954 } 955 956 /* 957 ** Return true if list pList (linked by IdxConstraint.pLink) contains 958 ** a constraint compatible with *p. Otherwise return false. 959 */ 960 static int idxFindConstraint(IdxConstraint *pList, IdxConstraint *p){ 961 IdxConstraint *pCmp; 962 for(pCmp=pList; pCmp; pCmp=pCmp->pLink){ 963 if( p->iCol==pCmp->iCol ) return 1; 964 } 965 return 0; 966 } 967 968 static int idxCreateFromWhere( 969 sqlite3expert *p, 970 IdxScan *pScan, /* Create indexes for this scan */ 971 IdxConstraint *pTail /* range/ORDER BY constraints for inclusion */ 972 ){ 973 IdxConstraint *p1 = 0; 974 IdxConstraint *pCon; 975 int rc; 976 977 /* Gather up all the == constraints. */ 978 for(pCon=pScan->pEq; pCon; pCon=pCon->pNext){ 979 if( !idxFindConstraint(p1, pCon) && !idxFindConstraint(pTail, pCon) ){ 980 pCon->pLink = p1; 981 p1 = pCon; 982 } 983 } 984 985 /* Create an index using the == constraints collected above. And the 986 ** range constraint/ORDER BY terms passed in by the caller, if any. */ 987 rc = idxCreateFromCons(p, pScan, p1, pTail); 988 989 /* If no range/ORDER BY passed by the caller, create a version of the 990 ** index for each range constraint. */ 991 if( pTail==0 ){ 992 for(pCon=pScan->pRange; rc==SQLITE_OK && pCon; pCon=pCon->pNext){ 993 assert( pCon->pLink==0 ); 994 if( !idxFindConstraint(p1, pCon) && !idxFindConstraint(pTail, pCon) ){ 995 rc = idxCreateFromCons(p, pScan, p1, pCon); 996 } 997 } 998 } 999 1000 return rc; 1001 } 1002 1003 /* 1004 ** Create candidate indexes in database [dbm] based on the data in 1005 ** linked-list pScan. 1006 */ 1007 static int idxCreateCandidates(sqlite3expert *p, char **pzErr){ 1008 int rc = SQLITE_OK; 1009 IdxScan *pIter; 1010 1011 for(pIter=p->pScan; pIter && rc==SQLITE_OK; pIter=pIter->pNextScan){ 1012 rc = idxCreateFromWhere(p, pIter, 0); 1013 if( rc==SQLITE_OK && pIter->pOrder ){ 1014 rc = idxCreateFromWhere(p, pIter, pIter->pOrder); 1015 } 1016 } 1017 1018 return rc; 1019 } 1020 1021 /* 1022 ** Free all elements of the linked list starting at pConstraint. 1023 */ 1024 static void idxConstraintFree(IdxConstraint *pConstraint){ 1025 IdxConstraint *pNext; 1026 IdxConstraint *p; 1027 1028 for(p=pConstraint; p; p=pNext){ 1029 pNext = p->pNext; 1030 sqlite3_free(p); 1031 } 1032 } 1033 1034 /* 1035 ** Free all elements of the linked list starting from pScan up until pLast 1036 ** (pLast is not freed). 1037 */ 1038 static void idxScanFree(IdxScan *pScan, IdxScan *pLast){ 1039 IdxScan *p; 1040 IdxScan *pNext; 1041 for(p=pScan; p!=pLast; p=pNext){ 1042 pNext = p->pNextScan; 1043 idxConstraintFree(p->pOrder); 1044 idxConstraintFree(p->pEq); 1045 idxConstraintFree(p->pRange); 1046 sqlite3_free(p); 1047 } 1048 } 1049 1050 /* 1051 ** Free all elements of the linked list starting from pStatement up 1052 ** until pLast (pLast is not freed). 1053 */ 1054 static void idxStatementFree(IdxStatement *pStatement, IdxStatement *pLast){ 1055 IdxStatement *p; 1056 IdxStatement *pNext; 1057 for(p=pStatement; p!=pLast; p=pNext){ 1058 pNext = p->pNext; 1059 sqlite3_free(p->zEQP); 1060 sqlite3_free(p->zIdx); 1061 sqlite3_free(p); 1062 } 1063 } 1064 1065 /* 1066 ** Free the linked list of IdxTable objects starting at pTab. 1067 */ 1068 static void idxTableFree(IdxTable *pTab){ 1069 IdxTable *pIter; 1070 IdxTable *pNext; 1071 for(pIter=pTab; pIter; pIter=pNext){ 1072 pNext = pIter->pNext; 1073 sqlite3_free(pIter); 1074 } 1075 } 1076 1077 /* 1078 ** Free the linked list of IdxWrite objects starting at pTab. 1079 */ 1080 static void idxWriteFree(IdxWrite *pTab){ 1081 IdxWrite *pIter; 1082 IdxWrite *pNext; 1083 for(pIter=pTab; pIter; pIter=pNext){ 1084 pNext = pIter->pNext; 1085 sqlite3_free(pIter); 1086 } 1087 } 1088 1089 1090 1091 /* 1092 ** This function is called after candidate indexes have been created. It 1093 ** runs all the queries to see which indexes they prefer, and populates 1094 ** IdxStatement.zIdx and IdxStatement.zEQP with the results. 1095 */ 1096 int idxFindIndexes( 1097 sqlite3expert *p, 1098 char **pzErr /* OUT: Error message (sqlite3_malloc) */ 1099 ){ 1100 IdxStatement *pStmt; 1101 sqlite3 *dbm = p->dbm; 1102 int rc = SQLITE_OK; 1103 1104 IdxHash hIdx; 1105 idxHashInit(&hIdx); 1106 1107 for(pStmt=p->pStatement; rc==SQLITE_OK && pStmt; pStmt=pStmt->pNext){ 1108 IdxHashEntry *pEntry; 1109 sqlite3_stmt *pExplain = 0; 1110 idxHashClear(&hIdx); 1111 rc = idxPrintfPrepareStmt(dbm, &pExplain, pzErr, 1112 "EXPLAIN QUERY PLAN %s", pStmt->zSql 1113 ); 1114 while( rc==SQLITE_OK && sqlite3_step(pExplain)==SQLITE_ROW ){ 1115 int iSelectid = sqlite3_column_int(pExplain, 0); 1116 int iOrder = sqlite3_column_int(pExplain, 1); 1117 int iFrom = sqlite3_column_int(pExplain, 2); 1118 const char *zDetail = (const char*)sqlite3_column_text(pExplain, 3); 1119 int nDetail = STRLEN(zDetail); 1120 int i; 1121 1122 for(i=0; i<nDetail; i++){ 1123 const char *zIdx = 0; 1124 if( memcmp(&zDetail[i], " USING INDEX ", 13)==0 ){ 1125 zIdx = &zDetail[i+13]; 1126 }else if( memcmp(&zDetail[i], " USING COVERING INDEX ", 22)==0 ){ 1127 zIdx = &zDetail[i+22]; 1128 } 1129 if( zIdx ){ 1130 const char *zSql; 1131 int nIdx = 0; 1132 while( zIdx[nIdx]!='\0' && (zIdx[nIdx]!=' ' || zIdx[nIdx+1]!='(') ){ 1133 nIdx++; 1134 } 1135 zSql = idxHashSearch(&p->hIdx, zIdx, nIdx); 1136 if( zSql ){ 1137 idxHashAdd(&rc, &hIdx, zSql, 0); 1138 if( rc ) goto find_indexes_out; 1139 } 1140 break; 1141 } 1142 } 1143 1144 pStmt->zEQP = idxAppendText(&rc, pStmt->zEQP, "%d|%d|%d|%s\n", 1145 iSelectid, iOrder, iFrom, zDetail 1146 ); 1147 } 1148 1149 for(pEntry=hIdx.pFirst; pEntry; pEntry=pEntry->pNext){ 1150 pStmt->zIdx = idxAppendText(&rc, pStmt->zIdx, "%s;\n", pEntry->zKey); 1151 } 1152 1153 idxFinalize(&rc, pExplain); 1154 } 1155 1156 find_indexes_out: 1157 idxHashClear(&hIdx); 1158 return rc; 1159 } 1160 1161 static int idxAuthCallback( 1162 void *pCtx, 1163 int eOp, 1164 const char *z3, 1165 const char *z4, 1166 const char *zDb, 1167 const char *zTrigger 1168 ){ 1169 int rc = SQLITE_OK; 1170 if( eOp==SQLITE_INSERT || eOp==SQLITE_UPDATE || eOp==SQLITE_DELETE ){ 1171 if( sqlite3_stricmp(zDb, "main")==0 ){ 1172 sqlite3expert *p = (sqlite3expert*)pCtx; 1173 IdxTable *pTab; 1174 for(pTab=p->pTable; pTab; pTab=pTab->pNext){ 1175 if( 0==sqlite3_stricmp(z3, pTab->zName) ) break; 1176 } 1177 if( pTab ){ 1178 IdxWrite *pWrite; 1179 for(pWrite=p->pWrite; pWrite; pWrite=pWrite->pNext){ 1180 if( pWrite->pTab==pTab && pWrite->eOp==eOp ) break; 1181 } 1182 if( pWrite==0 ){ 1183 pWrite = idxMalloc(&rc, sizeof(IdxWrite)); 1184 if( rc==SQLITE_OK ){ 1185 pWrite->pTab = pTab; 1186 pWrite->eOp = eOp; 1187 pWrite->pNext = p->pWrite; 1188 p->pWrite = pWrite; 1189 } 1190 } 1191 } 1192 } 1193 } 1194 return rc; 1195 } 1196 1197 static int idxProcessOneTrigger( 1198 sqlite3expert *p, 1199 IdxWrite *pWrite, 1200 char **pzErr 1201 ){ 1202 static const char *zInt = UNIQUE_TABLE_NAME; 1203 static const char *zDrop = "DROP TABLE " UNIQUE_TABLE_NAME; 1204 IdxTable *pTab = pWrite->pTab; 1205 const char *zTab = pTab->zName; 1206 const char *zSql = 1207 "SELECT 'CREATE TEMP' || substr(sql, 7) FROM sqlite_master " 1208 "WHERE tbl_name = %Q AND type IN ('table', 'trigger') " 1209 "ORDER BY type;"; 1210 sqlite3_stmt *pSelect = 0; 1211 int rc = SQLITE_OK; 1212 char *zWrite = 0; 1213 1214 /* Create the table and its triggers in the temp schema */ 1215 rc = idxPrintfPrepareStmt(p->db, &pSelect, pzErr, zSql, zTab, zTab); 1216 while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSelect) ){ 1217 const char *zCreate = (const char*)sqlite3_column_text(pSelect, 0); 1218 rc = sqlite3_exec(p->dbv, zCreate, 0, 0, pzErr); 1219 } 1220 idxFinalize(&rc, pSelect); 1221 1222 /* Rename the table in the temp schema to zInt */ 1223 if( rc==SQLITE_OK ){ 1224 char *z = sqlite3_mprintf("ALTER TABLE temp.%Q RENAME TO %Q", zTab, zInt); 1225 if( z==0 ){ 1226 rc = SQLITE_NOMEM; 1227 }else{ 1228 rc = sqlite3_exec(p->dbv, z, 0, 0, pzErr); 1229 sqlite3_free(z); 1230 } 1231 } 1232 1233 switch( pWrite->eOp ){ 1234 case SQLITE_INSERT: { 1235 int i; 1236 zWrite = idxAppendText(&rc, zWrite, "INSERT INTO %Q VALUES(", zInt); 1237 for(i=0; i<pTab->nCol; i++){ 1238 zWrite = idxAppendText(&rc, zWrite, "%s?", i==0 ? "" : ", "); 1239 } 1240 zWrite = idxAppendText(&rc, zWrite, ")"); 1241 break; 1242 } 1243 case SQLITE_UPDATE: { 1244 int i; 1245 zWrite = idxAppendText(&rc, zWrite, "UPDATE %Q SET ", zInt); 1246 for(i=0; i<pTab->nCol; i++){ 1247 zWrite = idxAppendText(&rc, zWrite, "%s%Q=?", i==0 ? "" : ", ", 1248 pTab->aCol[i].zName 1249 ); 1250 } 1251 break; 1252 } 1253 default: { 1254 assert( pWrite->eOp==SQLITE_DELETE ); 1255 if( rc==SQLITE_OK ){ 1256 zWrite = sqlite3_mprintf("DELETE FROM %Q", zInt); 1257 if( zWrite==0 ) rc = SQLITE_NOMEM; 1258 } 1259 } 1260 } 1261 1262 if( rc==SQLITE_OK ){ 1263 sqlite3_stmt *pX = 0; 1264 rc = sqlite3_prepare_v2(p->dbv, zWrite, -1, &pX, 0); 1265 idxFinalize(&rc, pX); 1266 if( rc!=SQLITE_OK ){ 1267 idxDatabaseError(p->dbv, pzErr); 1268 } 1269 } 1270 sqlite3_free(zWrite); 1271 1272 if( rc==SQLITE_OK ){ 1273 rc = sqlite3_exec(p->dbv, zDrop, 0, 0, pzErr); 1274 } 1275 1276 return rc; 1277 } 1278 1279 static int idxProcessTriggers(sqlite3expert *p, char **pzErr){ 1280 int rc = SQLITE_OK; 1281 IdxWrite *pEnd = 0; 1282 IdxWrite *pFirst = p->pWrite; 1283 1284 while( rc==SQLITE_OK && pFirst!=pEnd ){ 1285 IdxWrite *pIter; 1286 for(pIter=pFirst; rc==SQLITE_OK && pIter!=pEnd; pIter=pIter->pNext){ 1287 rc = idxProcessOneTrigger(p, pIter, pzErr); 1288 } 1289 pEnd = pFirst; 1290 pFirst = p->pWrite; 1291 } 1292 1293 return rc; 1294 } 1295 1296 1297 static int idxCreateVtabSchema(sqlite3expert *p, char **pzErrmsg){ 1298 int rc = idxRegisterVtab(p); 1299 sqlite3_stmt *pSchema = 0; 1300 1301 /* For each table in the main db schema: 1302 ** 1303 ** 1) Add an entry to the p->pTable list, and 1304 ** 2) Create the equivalent virtual table in dbv. 1305 */ 1306 rc = idxPrepareStmt(p->db, &pSchema, pzErrmsg, 1307 "SELECT type, name, sql, 1 FROM sqlite_master " 1308 "WHERE type IN ('table','view') AND name NOT LIKE 'sqlite_%%' " 1309 " UNION ALL " 1310 "SELECT type, name, sql, 2 FROM sqlite_master " 1311 "WHERE type = 'trigger'" 1312 " AND tbl_name IN(SELECT name FROM sqlite_master WHERE type = 'view') " 1313 "ORDER BY 4, 1" 1314 ); 1315 while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSchema) ){ 1316 const char *zType = (const char*)sqlite3_column_text(pSchema, 0); 1317 const char *zName = (const char*)sqlite3_column_text(pSchema, 1); 1318 const char *zSql = (const char*)sqlite3_column_text(pSchema, 2); 1319 1320 if( zType[0]=='v' || zType[1]=='r' ){ 1321 rc = sqlite3_exec(p->dbv, zSql, 0, 0, pzErrmsg); 1322 }else{ 1323 IdxTable *pTab; 1324 rc = idxGetTableInfo(p->db, zName, &pTab, pzErrmsg); 1325 if( rc==SQLITE_OK ){ 1326 int i; 1327 char *zInner = 0; 1328 char *zOuter = 0; 1329 pTab->pNext = p->pTable; 1330 p->pTable = pTab; 1331 1332 /* The statement the vtab will pass to sqlite3_declare_vtab() */ 1333 zInner = idxAppendText(&rc, 0, "CREATE TABLE x("); 1334 for(i=0; i<pTab->nCol; i++){ 1335 zInner = idxAppendText(&rc, zInner, "%s%Q COLLATE %s", 1336 (i==0 ? "" : ", "), pTab->aCol[i].zName, pTab->aCol[i].zColl 1337 ); 1338 } 1339 zInner = idxAppendText(&rc, zInner, ")"); 1340 1341 /* The CVT statement to create the vtab */ 1342 zOuter = idxAppendText(&rc, 0, 1343 "CREATE VIRTUAL TABLE %Q USING expert(%Q)", zName, zInner 1344 ); 1345 if( rc==SQLITE_OK ){ 1346 rc = sqlite3_exec(p->dbv, zOuter, 0, 0, pzErrmsg); 1347 } 1348 sqlite3_free(zInner); 1349 sqlite3_free(zOuter); 1350 } 1351 } 1352 } 1353 idxFinalize(&rc, pSchema); 1354 return rc; 1355 } 1356 1357 struct IdxSampleCtx { 1358 int iTarget; 1359 double target; /* Target nRet/nRow value */ 1360 double nRow; /* Number of rows seen */ 1361 double nRet; /* Number of rows returned */ 1362 }; 1363 1364 static void idxSampleFunc( 1365 sqlite3_context *pCtx, 1366 int argc, 1367 sqlite3_value **argv 1368 ){ 1369 struct IdxSampleCtx *p = (struct IdxSampleCtx*)sqlite3_user_data(pCtx); 1370 int bRet; 1371 1372 assert( argc==0 ); 1373 if( p->nRow==0.0 ){ 1374 bRet = 1; 1375 }else{ 1376 bRet = (p->nRet / p->nRow) <= p->target; 1377 if( bRet==0 ){ 1378 unsigned short rnd; 1379 sqlite3_randomness(2, (void*)&rnd); 1380 bRet = ((int)rnd % 100) <= p->iTarget; 1381 } 1382 } 1383 1384 sqlite3_result_int(pCtx, bRet); 1385 p->nRow += 1.0; 1386 p->nRet += (double)bRet; 1387 } 1388 1389 struct IdxRemCtx { 1390 int nSlot; 1391 struct IdxRemSlot { 1392 int eType; /* SQLITE_NULL, INTEGER, REAL, TEXT, BLOB */ 1393 i64 iVal; /* SQLITE_INTEGER value */ 1394 double rVal; /* SQLITE_FLOAT value */ 1395 int nByte; /* Bytes of space allocated at z */ 1396 int n; /* Size of buffer z */ 1397 char *z; /* SQLITE_TEXT/BLOB value */ 1398 } aSlot[1]; 1399 }; 1400 1401 /* 1402 ** Implementation of scalar function rem(). 1403 */ 1404 static void idxRemFunc( 1405 sqlite3_context *pCtx, 1406 int argc, 1407 sqlite3_value **argv 1408 ){ 1409 struct IdxRemCtx *p = (struct IdxRemCtx*)sqlite3_user_data(pCtx); 1410 struct IdxRemSlot *pSlot; 1411 int iSlot; 1412 assert( argc==2 ); 1413 1414 iSlot = sqlite3_value_int(argv[0]); 1415 assert( iSlot<=p->nSlot ); 1416 pSlot = &p->aSlot[iSlot]; 1417 1418 switch( pSlot->eType ){ 1419 case SQLITE_NULL: 1420 /* no-op */ 1421 break; 1422 1423 case SQLITE_INTEGER: 1424 sqlite3_result_int64(pCtx, pSlot->iVal); 1425 break; 1426 1427 case SQLITE_FLOAT: 1428 sqlite3_result_double(pCtx, pSlot->rVal); 1429 break; 1430 1431 case SQLITE_BLOB: 1432 sqlite3_result_blob(pCtx, pSlot->z, pSlot->n, SQLITE_TRANSIENT); 1433 break; 1434 1435 case SQLITE_TEXT: 1436 sqlite3_result_text(pCtx, pSlot->z, pSlot->n, SQLITE_TRANSIENT); 1437 break; 1438 } 1439 1440 pSlot->eType = sqlite3_value_type(argv[1]); 1441 switch( pSlot->eType ){ 1442 case SQLITE_NULL: 1443 /* no-op */ 1444 break; 1445 1446 case SQLITE_INTEGER: 1447 pSlot->iVal = sqlite3_value_int64(argv[1]); 1448 break; 1449 1450 case SQLITE_FLOAT: 1451 pSlot->rVal = sqlite3_value_double(argv[1]); 1452 break; 1453 1454 case SQLITE_BLOB: 1455 case SQLITE_TEXT: { 1456 int nByte = sqlite3_value_bytes(argv[1]); 1457 if( nByte>pSlot->nByte ){ 1458 char *zNew = (char*)sqlite3_realloc(pSlot->z, nByte*2); 1459 if( zNew==0 ){ 1460 sqlite3_result_error_nomem(pCtx); 1461 return; 1462 } 1463 pSlot->nByte = nByte*2; 1464 pSlot->z = zNew; 1465 } 1466 pSlot->n = nByte; 1467 if( pSlot->eType==SQLITE_BLOB ){ 1468 memcpy(pSlot->z, sqlite3_value_blob(argv[1]), nByte); 1469 }else{ 1470 memcpy(pSlot->z, sqlite3_value_text(argv[1]), nByte); 1471 } 1472 break; 1473 } 1474 } 1475 } 1476 1477 static int idxLargestIndex(sqlite3 *db, int *pnMax, char **pzErr){ 1478 int rc = SQLITE_OK; 1479 const char *zMax = 1480 "SELECT max(i.seqno) FROM " 1481 " sqlite_master AS s, " 1482 " pragma_index_list(s.name) AS l, " 1483 " pragma_index_info(l.name) AS i " 1484 "WHERE s.type = 'table'"; 1485 sqlite3_stmt *pMax = 0; 1486 1487 *pnMax = 0; 1488 rc = idxPrepareStmt(db, &pMax, pzErr, zMax); 1489 if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pMax) ){ 1490 *pnMax = sqlite3_column_int(pMax, 0) + 1; 1491 } 1492 idxFinalize(&rc, pMax); 1493 1494 return rc; 1495 } 1496 1497 static int idxPopulateOneStat1( 1498 sqlite3expert *p, 1499 sqlite3_stmt *pIndexXInfo, 1500 sqlite3_stmt *pWriteStat, 1501 const char *zTab, 1502 const char *zIdx, 1503 char **pzErr 1504 ){ 1505 char *zCols = 0; 1506 char *zOrder = 0; 1507 char *zQuery = 0; 1508 int nCol = 0; 1509 int i; 1510 sqlite3_stmt *pQuery = 0; 1511 int *aStat = 0; 1512 int rc = SQLITE_OK; 1513 1514 assert( p->iSample>0 ); 1515 1516 /* Formulate the query text */ 1517 sqlite3_bind_text(pIndexXInfo, 1, zIdx, -1, SQLITE_STATIC); 1518 while( SQLITE_OK==rc && SQLITE_ROW==sqlite3_step(pIndexXInfo) ){ 1519 const char *zComma = zCols==0 ? "" : ", "; 1520 const char *zName = (const char*)sqlite3_column_text(pIndexXInfo, 0); 1521 const char *zColl = (const char*)sqlite3_column_text(pIndexXInfo, 1); 1522 zCols = idxAppendText(&rc, zCols, 1523 "%sx.%Q IS rem(%d, x.%Q) COLLATE %s", zComma, zName, nCol, zName, zColl 1524 ); 1525 zOrder = idxAppendText(&rc, zOrder, "%s%d", zComma, ++nCol); 1526 } 1527 if( rc==SQLITE_OK ){ 1528 if( p->iSample==100 ){ 1529 zQuery = sqlite3_mprintf( 1530 "SELECT %s FROM %Q x ORDER BY %s", zCols, zTab, zOrder 1531 ); 1532 }else{ 1533 zQuery = sqlite3_mprintf( 1534 "SELECT %s FROM temp."UNIQUE_TABLE_NAME" x ORDER BY %s", zCols, zOrder 1535 ); 1536 } 1537 } 1538 sqlite3_free(zCols); 1539 sqlite3_free(zOrder); 1540 1541 /* Formulate the query text */ 1542 if( rc==SQLITE_OK ){ 1543 sqlite3 *dbrem = (p->iSample==100 ? p->db : p->dbv); 1544 rc = idxPrepareStmt(dbrem, &pQuery, pzErr, zQuery); 1545 } 1546 sqlite3_free(zQuery); 1547 1548 if( rc==SQLITE_OK ){ 1549 aStat = (int*)idxMalloc(&rc, sizeof(int)*(nCol+1)); 1550 } 1551 if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pQuery) ){ 1552 IdxHashEntry *pEntry; 1553 char *zStat = 0; 1554 for(i=0; i<=nCol; i++) aStat[i] = 1; 1555 while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pQuery) ){ 1556 aStat[0]++; 1557 for(i=0; i<nCol; i++){ 1558 if( sqlite3_column_int(pQuery, i)==0 ) break; 1559 } 1560 for(/*no-op*/; i<nCol; i++){ 1561 aStat[i+1]++; 1562 } 1563 } 1564 1565 if( rc==SQLITE_OK ){ 1566 int s0 = aStat[0]; 1567 zStat = sqlite3_mprintf("%d", s0); 1568 if( zStat==0 ) rc = SQLITE_NOMEM; 1569 for(i=1; rc==SQLITE_OK && i<=nCol; i++){ 1570 zStat = idxAppendText(&rc, zStat, " %d", (s0+aStat[i]/2) / aStat[i]); 1571 } 1572 } 1573 1574 if( rc==SQLITE_OK ){ 1575 sqlite3_bind_text(pWriteStat, 1, zTab, -1, SQLITE_STATIC); 1576 sqlite3_bind_text(pWriteStat, 2, zIdx, -1, SQLITE_STATIC); 1577 sqlite3_bind_text(pWriteStat, 3, zStat, -1, SQLITE_STATIC); 1578 sqlite3_step(pWriteStat); 1579 rc = sqlite3_reset(pWriteStat); 1580 } 1581 1582 pEntry = idxHashFind(&p->hIdx, zIdx, STRLEN(zIdx)); 1583 if( pEntry ){ 1584 assert( pEntry->zVal2==0 ); 1585 pEntry->zVal2 = zStat; 1586 }else{ 1587 sqlite3_free(zStat); 1588 } 1589 } 1590 sqlite3_free(aStat); 1591 idxFinalize(&rc, pQuery); 1592 1593 return rc; 1594 } 1595 1596 static int idxBuildSampleTable(sqlite3expert *p, const char *zTab){ 1597 int rc; 1598 char *zSql; 1599 1600 rc = sqlite3_exec(p->dbv,"DROP TABLE IF EXISTS temp."UNIQUE_TABLE_NAME,0,0,0); 1601 if( rc!=SQLITE_OK ) return rc; 1602 1603 zSql = sqlite3_mprintf( 1604 "CREATE TABLE temp." UNIQUE_TABLE_NAME " AS SELECT * FROM %Q", zTab 1605 ); 1606 if( zSql==0 ) return SQLITE_NOMEM; 1607 rc = sqlite3_exec(p->dbv, zSql, 0, 0, 0); 1608 sqlite3_free(zSql); 1609 1610 return rc; 1611 } 1612 1613 /* 1614 ** This function is called as part of sqlite3_expert_analyze(). Candidate 1615 ** indexes have already been created in database sqlite3expert.dbm, this 1616 ** function populates sqlite_stat1 table in the same database. 1617 ** 1618 ** The stat1 data is generated by querying the 1619 */ 1620 static int idxPopulateStat1(sqlite3expert *p, char **pzErr){ 1621 int rc = SQLITE_OK; 1622 int nMax =0; 1623 struct IdxRemCtx *pCtx = 0; 1624 struct IdxSampleCtx samplectx; 1625 int i; 1626 i64 iPrev = -100000; 1627 sqlite3_stmt *pAllIndex = 0; 1628 sqlite3_stmt *pIndexXInfo = 0; 1629 sqlite3_stmt *pWrite = 0; 1630 1631 const char *zAllIndex = 1632 "SELECT s.rowid, s.name, l.name FROM " 1633 " sqlite_master AS s, " 1634 " pragma_index_list(s.name) AS l " 1635 "WHERE s.type = 'table'"; 1636 const char *zIndexXInfo = 1637 "SELECT name, coll FROM pragma_index_xinfo(?) WHERE key"; 1638 const char *zWrite = "INSERT INTO sqlite_stat1 VALUES(?, ?, ?)"; 1639 1640 /* If iSample==0, no sqlite_stat1 data is required. */ 1641 if( p->iSample==0 ) return SQLITE_OK; 1642 1643 rc = idxLargestIndex(p->dbm, &nMax, pzErr); 1644 if( nMax<=0 || rc!=SQLITE_OK ) return rc; 1645 1646 rc = sqlite3_exec(p->dbm, "ANALYZE; PRAGMA writable_schema=1", 0, 0, 0); 1647 1648 if( rc==SQLITE_OK ){ 1649 int nByte = sizeof(struct IdxRemCtx) + (sizeof(struct IdxRemSlot) * nMax); 1650 pCtx = (struct IdxRemCtx*)idxMalloc(&rc, nByte); 1651 } 1652 1653 if( rc==SQLITE_OK ){ 1654 sqlite3 *dbrem = (p->iSample==100 ? p->db : p->dbv); 1655 rc = sqlite3_create_function( 1656 dbrem, "rem", 2, SQLITE_UTF8, (void*)pCtx, idxRemFunc, 0, 0 1657 ); 1658 } 1659 if( rc==SQLITE_OK ){ 1660 rc = sqlite3_create_function( 1661 p->db, "sample", 0, SQLITE_UTF8, (void*)&samplectx, idxSampleFunc, 0, 0 1662 ); 1663 } 1664 1665 if( rc==SQLITE_OK ){ 1666 pCtx->nSlot = nMax+1; 1667 rc = idxPrepareStmt(p->dbm, &pAllIndex, pzErr, zAllIndex); 1668 } 1669 if( rc==SQLITE_OK ){ 1670 rc = idxPrepareStmt(p->dbm, &pIndexXInfo, pzErr, zIndexXInfo); 1671 } 1672 if( rc==SQLITE_OK ){ 1673 rc = idxPrepareStmt(p->dbm, &pWrite, pzErr, zWrite); 1674 } 1675 1676 while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pAllIndex) ){ 1677 i64 iRowid = sqlite3_column_int64(pAllIndex, 0); 1678 const char *zTab = (const char*)sqlite3_column_text(pAllIndex, 1); 1679 const char *zIdx = (const char*)sqlite3_column_text(pAllIndex, 2); 1680 if( p->iSample<100 && iPrev!=iRowid ){ 1681 samplectx.target = (double)p->iSample / 100.0; 1682 samplectx.iTarget = p->iSample; 1683 samplectx.nRow = 0.0; 1684 samplectx.nRet = 0.0; 1685 rc = idxBuildSampleTable(p, zTab); 1686 if( rc!=SQLITE_OK ) break; 1687 } 1688 rc = idxPopulateOneStat1(p, pIndexXInfo, pWrite, zTab, zIdx, pzErr); 1689 iPrev = iRowid; 1690 } 1691 if( rc==SQLITE_OK && p->iSample<100 ){ 1692 rc = sqlite3_exec(p->dbv, 1693 "DROP TABLE IF EXISTS temp." UNIQUE_TABLE_NAME, 0,0,0 1694 ); 1695 } 1696 1697 idxFinalize(&rc, pAllIndex); 1698 idxFinalize(&rc, pIndexXInfo); 1699 idxFinalize(&rc, pWrite); 1700 1701 for(i=0; i<pCtx->nSlot; i++){ 1702 sqlite3_free(pCtx->aSlot[i].z); 1703 } 1704 sqlite3_free(pCtx); 1705 1706 if( rc==SQLITE_OK ){ 1707 rc = sqlite3_exec(p->dbm, "ANALYZE sqlite_master", 0, 0, 0); 1708 } 1709 1710 sqlite3_exec(p->db, "DROP TABLE IF EXISTS temp."UNIQUE_TABLE_NAME,0,0,0); 1711 return rc; 1712 } 1713 1714 /* 1715 ** Allocate a new sqlite3expert object. 1716 */ 1717 sqlite3expert *sqlite3_expert_new(sqlite3 *db, char **pzErrmsg){ 1718 int rc = SQLITE_OK; 1719 sqlite3expert *pNew; 1720 1721 pNew = (sqlite3expert*)idxMalloc(&rc, sizeof(sqlite3expert)); 1722 1723 /* Open two in-memory databases to work with. The "vtab database" (dbv) 1724 ** will contain a virtual table corresponding to each real table in 1725 ** the user database schema, and a copy of each view. It is used to 1726 ** collect information regarding the WHERE, ORDER BY and other clauses 1727 ** of the user's query. 1728 */ 1729 if( rc==SQLITE_OK ){ 1730 pNew->db = db; 1731 pNew->iSample = 100; 1732 rc = sqlite3_open(":memory:", &pNew->dbv); 1733 } 1734 if( rc==SQLITE_OK ){ 1735 rc = sqlite3_open(":memory:", &pNew->dbm); 1736 if( rc==SQLITE_OK ){ 1737 sqlite3_db_config(pNew->dbm, SQLITE_DBCONFIG_FULL_EQP, 1, (int*)0); 1738 } 1739 } 1740 1741 1742 /* Copy the entire schema of database [db] into [dbm]. */ 1743 if( rc==SQLITE_OK ){ 1744 sqlite3_stmt *pSql; 1745 rc = idxPrintfPrepareStmt(pNew->db, &pSql, pzErrmsg, 1746 "SELECT sql FROM sqlite_master WHERE name NOT LIKE 'sqlite_%%'" 1747 " AND sql NOT LIKE 'CREATE VIRTUAL %%'" 1748 ); 1749 while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSql) ){ 1750 const char *zSql = (const char*)sqlite3_column_text(pSql, 0); 1751 rc = sqlite3_exec(pNew->dbm, zSql, 0, 0, pzErrmsg); 1752 } 1753 idxFinalize(&rc, pSql); 1754 } 1755 1756 /* Create the vtab schema */ 1757 if( rc==SQLITE_OK ){ 1758 rc = idxCreateVtabSchema(pNew, pzErrmsg); 1759 } 1760 1761 /* Register the auth callback with dbv */ 1762 if( rc==SQLITE_OK ){ 1763 sqlite3_set_authorizer(pNew->dbv, idxAuthCallback, (void*)pNew); 1764 } 1765 1766 /* If an error has occurred, free the new object and reutrn NULL. Otherwise, 1767 ** return the new sqlite3expert handle. */ 1768 if( rc!=SQLITE_OK ){ 1769 sqlite3_expert_destroy(pNew); 1770 pNew = 0; 1771 } 1772 return pNew; 1773 } 1774 1775 /* 1776 ** Configure an sqlite3expert object. 1777 */ 1778 int sqlite3_expert_config(sqlite3expert *p, int op, ...){ 1779 int rc = SQLITE_OK; 1780 va_list ap; 1781 va_start(ap, op); 1782 switch( op ){ 1783 case EXPERT_CONFIG_SAMPLE: { 1784 int iVal = va_arg(ap, int); 1785 if( iVal<0 ) iVal = 0; 1786 if( iVal>100 ) iVal = 100; 1787 p->iSample = iVal; 1788 break; 1789 } 1790 default: 1791 rc = SQLITE_NOTFOUND; 1792 break; 1793 } 1794 1795 va_end(ap); 1796 return rc; 1797 } 1798 1799 /* 1800 ** Add an SQL statement to the analysis. 1801 */ 1802 int sqlite3_expert_sql( 1803 sqlite3expert *p, /* From sqlite3_expert_new() */ 1804 const char *zSql, /* SQL statement to add */ 1805 char **pzErr /* OUT: Error message (if any) */ 1806 ){ 1807 IdxScan *pScanOrig = p->pScan; 1808 IdxStatement *pStmtOrig = p->pStatement; 1809 int rc = SQLITE_OK; 1810 const char *zStmt = zSql; 1811 1812 if( p->bRun ) return SQLITE_MISUSE; 1813 1814 while( rc==SQLITE_OK && zStmt && zStmt[0] ){ 1815 sqlite3_stmt *pStmt = 0; 1816 rc = sqlite3_prepare_v2(p->dbv, zStmt, -1, &pStmt, &zStmt); 1817 if( rc==SQLITE_OK ){ 1818 if( pStmt ){ 1819 IdxStatement *pNew; 1820 const char *z = sqlite3_sql(pStmt); 1821 int n = STRLEN(z); 1822 pNew = (IdxStatement*)idxMalloc(&rc, sizeof(IdxStatement) + n+1); 1823 if( rc==SQLITE_OK ){ 1824 pNew->zSql = (char*)&pNew[1]; 1825 memcpy(pNew->zSql, z, n+1); 1826 pNew->pNext = p->pStatement; 1827 if( p->pStatement ) pNew->iId = p->pStatement->iId+1; 1828 p->pStatement = pNew; 1829 } 1830 sqlite3_finalize(pStmt); 1831 } 1832 }else{ 1833 idxDatabaseError(p->dbv, pzErr); 1834 } 1835 } 1836 1837 if( rc!=SQLITE_OK ){ 1838 idxScanFree(p->pScan, pScanOrig); 1839 idxStatementFree(p->pStatement, pStmtOrig); 1840 p->pScan = pScanOrig; 1841 p->pStatement = pStmtOrig; 1842 } 1843 1844 return rc; 1845 } 1846 1847 int sqlite3_expert_analyze(sqlite3expert *p, char **pzErr){ 1848 int rc; 1849 IdxHashEntry *pEntry; 1850 1851 /* Do trigger processing to collect any extra IdxScan structures */ 1852 rc = idxProcessTriggers(p, pzErr); 1853 1854 /* Create candidate indexes within the in-memory database file */ 1855 if( rc==SQLITE_OK ){ 1856 rc = idxCreateCandidates(p, pzErr); 1857 } 1858 1859 /* Generate the stat1 data */ 1860 if( rc==SQLITE_OK ){ 1861 rc = idxPopulateStat1(p, pzErr); 1862 } 1863 1864 /* Formulate the EXPERT_REPORT_CANDIDATES text */ 1865 for(pEntry=p->hIdx.pFirst; pEntry; pEntry=pEntry->pNext){ 1866 p->zCandidates = idxAppendText(&rc, p->zCandidates, 1867 "%s;%s%s\n", pEntry->zVal, 1868 pEntry->zVal2 ? " -- stat1: " : "", pEntry->zVal2 1869 ); 1870 } 1871 1872 /* Figure out which of the candidate indexes are preferred by the query 1873 ** planner and report the results to the user. */ 1874 if( rc==SQLITE_OK ){ 1875 rc = idxFindIndexes(p, pzErr); 1876 } 1877 1878 if( rc==SQLITE_OK ){ 1879 p->bRun = 1; 1880 } 1881 return rc; 1882 } 1883 1884 /* 1885 ** Return the total number of statements that have been added to this 1886 ** sqlite3expert using sqlite3_expert_sql(). 1887 */ 1888 int sqlite3_expert_count(sqlite3expert *p){ 1889 int nRet = 0; 1890 if( p->pStatement ) nRet = p->pStatement->iId+1; 1891 return nRet; 1892 } 1893 1894 /* 1895 ** Return a component of the report. 1896 */ 1897 const char *sqlite3_expert_report(sqlite3expert *p, int iStmt, int eReport){ 1898 const char *zRet = 0; 1899 IdxStatement *pStmt; 1900 1901 if( p->bRun==0 ) return 0; 1902 for(pStmt=p->pStatement; pStmt && pStmt->iId!=iStmt; pStmt=pStmt->pNext); 1903 switch( eReport ){ 1904 case EXPERT_REPORT_SQL: 1905 if( pStmt ) zRet = pStmt->zSql; 1906 break; 1907 case EXPERT_REPORT_INDEXES: 1908 if( pStmt ) zRet = pStmt->zIdx; 1909 break; 1910 case EXPERT_REPORT_PLAN: 1911 if( pStmt ) zRet = pStmt->zEQP; 1912 break; 1913 case EXPERT_REPORT_CANDIDATES: 1914 zRet = p->zCandidates; 1915 break; 1916 } 1917 return zRet; 1918 } 1919 1920 /* 1921 ** Free an sqlite3expert object. 1922 */ 1923 void sqlite3_expert_destroy(sqlite3expert *p){ 1924 if( p ){ 1925 sqlite3_close(p->dbm); 1926 sqlite3_close(p->dbv); 1927 idxScanFree(p->pScan, 0); 1928 idxStatementFree(p->pStatement, 0); 1929 idxTableFree(p->pTable); 1930 idxWriteFree(p->pWrite); 1931 idxHashClear(&p->hIdx); 1932 sqlite3_free(p->zCandidates); 1933 sqlite3_free(p); 1934 } 1935 } 1936