Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Changes In Branch reuse-schema-vdbe-opt Excluding Merge-Ins
This is equivalent to a diff from 7c2ec2d4 to e002666a
2019-02-13
| ||
14:06 | Rearrange the code in the VDBE to help out the C-compiler optimizer. And fix a harmless compiler warning. (check-in: 219b39e1 user: drh tags: reuse-schema) | |
13:48 | Performance optimization in the VDBE, and a fix for a harmless compiler warning. (Closed-Leaf check-in: e002666a user: drh tags: reuse-schema-vdbe-opt) | |
08:40 | Fix a problem with OPEN_REUSE_SCHEMA connections reloading the temp schema. (check-in: 7c2ec2d4 user: dan tags: reuse-schema) | |
2019-02-12
| ||
20:58 | Add tests for creating temp schema objects with SQLITE_OPEN_REUSE_SCHEMA connections. (check-in: 8c07b609 user: dan tags: reuse-schema) | |
Changes to src/status.c.
︙ | ︙ | |||
278 279 280 281 282 283 284 | sqlite3BtreeEnterAll(db); db->pnBytesFreed = &nByte; for(i=0; i<db->nDb; i++){ Schema *pSchema = db->aDb[i].pSchema; if( ALWAYS(pSchema!=0) ){ HashElem *p; | < | 278 279 280 281 282 283 284 285 286 287 288 289 290 291 | sqlite3BtreeEnterAll(db); db->pnBytesFreed = &nByte; for(i=0; i<db->nDb; i++){ Schema *pSchema = db->aDb[i].pSchema; if( ALWAYS(pSchema!=0) ){ HashElem *p; nByte += sqlite3GlobalConfig.m.xRoundup(sizeof(HashElem)) * ( pSchema->tblHash.count + pSchema->trigHash.count + pSchema->idxHash.count + pSchema->fkeyHash.count ); |
︙ | ︙ |
Changes to src/vdbe.c.
︙ | ︙ | |||
407 408 409 410 411 412 413 414 415 416 417 418 419 420 | return pMem->flags & (MEM_Int|MEM_Real); } if( pMem->flags & (MEM_Str|MEM_Blob) ){ return computeNumericType(pMem); } return 0; } #ifdef SQLITE_DEBUG /* ** Write a nice string representation of the contents of cell pMem ** into buffer zBuf, length nBuf. */ void sqlite3VdbeMemPrettyPrint(Mem *pMem, char *zBuf){ | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 | return pMem->flags & (MEM_Int|MEM_Real); } if( pMem->flags & (MEM_Str|MEM_Blob) ){ return computeNumericType(pMem); } return 0; } /* ** This is the implementation of the OP_ParseSchema opcode. It is factored ** out of the main sqlite3VdbeExec() routine because it is not a performance- ** critical opcode and by factoring it out, it frees up registers in order ** to help the compiler optimizer do a better job with the other opcodes ** that are performance critical. */ static SQLITE_NOINLINE int parseSchemaOp(Vdbe *p, VdbeOp *pOp, sqlite3 *db){ int iDb; const char *zMaster; char *zSql; InitData initData; int bRelease; int rc = SQLITE_OK; /* Any prepared statement that invokes this opcode will hold mutexes ** on every btree. This is a prerequisite for invoking ** sqlite3InitCallback(). */ #ifdef SQLITE_DEBUG for(iDb=0; iDb<db->nDb; iDb++){ assert( iDb==1 || sqlite3BtreeHoldsMutex(db->aDb[iDb].pBt) ); } #endif iDb = pOp->p1; assert( iDb>=0 && iDb<db->nDb ); assert( DbHasProperty(db, iDb, DB_SchemaLoaded) ); #ifndef SQLITE_OMIT_ALTERTABLE if( pOp->p4.z==0 ){ assert( !IsReuseSchema(db) || iDb==1 ); sqlite3SchemaClear(db->aDb[iDb].pSchema); db->mDbFlags &= ~DBFLAG_SchemaKnownOk; rc = sqlite3InitOne(db, iDb, &p->zErrMsg, INITFLAG_AlterTable); db->mDbFlags |= DBFLAG_SchemaChange; p->expired = 0; }else #endif { zMaster = MASTER_NAME; initData.db = db; initData.iDb = iDb; initData.pzErrMsg = &p->zErrMsg; initData.mInitFlags = 0; zSql = sqlite3MPrintf(db, "SELECT name, rootpage, sql FROM '%q'.%s WHERE %s ORDER BY rowid", db->aDb[iDb].zDbSName, zMaster, pOp->p4.z); if( zSql==0 ){ rc = SQLITE_NOMEM_BKPT; }else{ bRelease = sqlite3LockReusableSchema(db); if( IsReuseSchema(db) ){ rc = sqlite3Init(db, &p->zErrMsg); if( rc ){ sqlite3UnlockReusableSchema(db, bRelease); return rc; } } assert( db->init.busy==0 ); db->init.busy = 1; initData.rc = SQLITE_OK; initData.nInitRow = 0; assert( !db->mallocFailed ); rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0); sqlite3UnlockReusableSchema(db, bRelease); if( rc==SQLITE_OK ) rc = initData.rc; if( rc==SQLITE_OK && initData.nInitRow==0 ){ /* The OP_ParseSchema opcode with a non-NULL P4 argument should parse ** at least one SQL statement. Any less than that indicates that ** the sqlite_master table is corrupt. */ rc = SQLITE_CORRUPT_BKPT; } sqlite3DbFreeNN(db, zSql); db->init.busy = 0; } } return rc; } #ifdef SQLITE_DEBUG /* ** Write a nice string representation of the contents of cell pMem ** into buffer zBuf, length nBuf. */ void sqlite3VdbeMemPrettyPrint(Mem *pMem, char *zBuf){ |
︙ | ︙ | |||
5753 5754 5755 5756 5757 5758 5759 | ** that match the WHERE clause P4. If P4 is a NULL pointer, then the ** entire schema for P1 is reparsed. ** ** This opcode invokes the parser to create a new virtual machine, ** then runs the new virtual machine. It is thus a re-entrant opcode. */ case OP_ParseSchema: { | < < < < < | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 5833 5834 5835 5836 5837 5838 5839 5840 5841 5842 5843 5844 5845 5846 5847 | ** that match the WHERE clause P4. If P4 is a NULL pointer, then the ** entire schema for P1 is reparsed. ** ** This opcode invokes the parser to create a new virtual machine, ** then runs the new virtual machine. It is thus a re-entrant opcode. */ case OP_ParseSchema: { rc = parseSchemaOp(p, pOp, db); if( rc ){ sqlite3ResetAllSchemasOfConnection(db); if( rc==SQLITE_NOMEM ){ goto no_mem; } goto abort_due_to_error; } |
︙ | ︙ |