summaryrefslogtreecommitdiff
path: root/ext/pdo_sqlite/sqlite/src/analyze.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/pdo_sqlite/sqlite/src/analyze.c')
-rw-r--r--ext/pdo_sqlite/sqlite/src/analyze.c37
1 files changed, 27 insertions, 10 deletions
diff --git a/ext/pdo_sqlite/sqlite/src/analyze.c b/ext/pdo_sqlite/sqlite/src/analyze.c
index a6c92e9f6f..dc1f33286d 100644
--- a/ext/pdo_sqlite/sqlite/src/analyze.c
+++ b/ext/pdo_sqlite/sqlite/src/analyze.c
@@ -61,8 +61,14 @@ static void openStatTable(
sqlite3VdbeAddOp(v, OP_Clear, pStat->tnum, iDb);
}
- /* Open the sqlite_stat1 table for writing.
+ /* Open the sqlite_stat1 table for writing. Unless it was created
+ ** by this vdbe program, lock it for writing at the shared-cache level.
+ ** If this vdbe did create the sqlite_stat1 table, then it must have
+ ** already obtained a schema-lock, making the write-lock redundant.
*/
+ if( iRootPage>0 ){
+ sqlite3TableLock(pParse, iDb, iRootPage, 1, "sqlite_stat1");
+ }
sqlite3VdbeAddOp(v, OP_Integer, iDb, 0);
sqlite3VdbeAddOp(v, OP_OpenWrite, iStatCur, iRootPage);
sqlite3VdbeAddOp(v, OP_SetNumColumns, iStatCur, 3);
@@ -86,6 +92,7 @@ static void analyzeOneTable(
int topOfLoop; /* The top of the loop */
int endOfLoop; /* The end of the loop */
int addr; /* The address of an instruction */
+ int iDb; /* Index of database containing pTab */
v = sqlite3GetVdbe(pParse);
if( pTab==0 || pTab->pIndex==0 ){
@@ -93,21 +100,29 @@ static void analyzeOneTable(
return;
}
+ iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
+ assert( iDb>=0 );
#ifndef SQLITE_OMIT_AUTHORIZATION
if( sqlite3AuthCheck(pParse, SQLITE_ANALYZE, pTab->zName, 0,
- pParse->db->aDb[pTab->iDb].zName ) ){
+ pParse->db->aDb[iDb].zName ) ){
return;
}
#endif
+ /* Establish a read-lock on the table at the shared-cache level. */
+ sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);
+
iIdxCur = pParse->nTab;
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
+ KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIdx);
+
/* Open a cursor to the index to be analyzed
*/
- sqlite3VdbeAddOp(v, OP_Integer, pIdx->iDb, 0);
+ assert( iDb==sqlite3SchemaToIndex(pParse->db, pIdx->pSchema) );
+ sqlite3VdbeAddOp(v, OP_Integer, iDb, 0);
VdbeComment((v, "# %s", pIdx->zName));
sqlite3VdbeOp3(v, OP_OpenRead, iIdxCur, pIdx->tnum,
- (char*)&pIdx->keyInfo, P3_KEYINFO);
+ (char *)pKey, P3_KEYINFO_HANDOFF);
nCol = pIdx->nColumn;
if( iMem+nCol*2>=pParse->nMem ){
pParse->nMem = iMem+nCol*2+1;
@@ -139,7 +154,7 @@ static void analyzeOneTable(
endOfLoop = sqlite3VdbeMakeLabel(v);
sqlite3VdbeAddOp(v, OP_Rewind, iIdxCur, endOfLoop);
topOfLoop = sqlite3VdbeCurrentAddr(v);
- sqlite3VdbeAddOp(v, OP_MemIncr, iMem, 0);
+ sqlite3VdbeAddOp(v, OP_MemIncr, 1, iMem);
for(i=0; i<nCol; i++){
sqlite3VdbeAddOp(v, OP_Column, iIdxCur, i);
sqlite3VdbeAddOp(v, OP_MemLoad, iMem+nCol+i+1, 0);
@@ -147,7 +162,7 @@ static void analyzeOneTable(
}
sqlite3VdbeAddOp(v, OP_Goto, 0, endOfLoop);
for(i=0; i<nCol; i++){
- addr = sqlite3VdbeAddOp(v, OP_MemIncr, iMem+i+1, 0);
+ addr = sqlite3VdbeAddOp(v, OP_MemIncr, 1, iMem+i+1);
sqlite3VdbeChangeP2(v, topOfLoop + 3*i + 3, addr);
sqlite3VdbeAddOp(v, OP_Column, iIdxCur, i);
sqlite3VdbeAddOp(v, OP_MemStore, iMem+nCol+i+1, 1);
@@ -188,13 +203,14 @@ static void analyzeOneTable(
sqlite3VdbeAddOp(v, OP_AddImm, -1, 0);
sqlite3VdbeAddOp(v, OP_MemLoad, iMem+i+1, 0);
sqlite3VdbeAddOp(v, OP_Divide, 0, 0);
+ sqlite3VdbeAddOp(v, OP_ToInt, 0, 0);
if( i==nCol-1 ){
sqlite3VdbeAddOp(v, OP_Concat, nCol*2-1, 0);
}else{
sqlite3VdbeAddOp(v, OP_Dup, 1, 0);
}
}
- sqlite3VdbeOp3(v, OP_MakeRecord, 3, 0, "ttt", 0);
+ sqlite3VdbeOp3(v, OP_MakeRecord, 3, 0, "aaa", 0);
sqlite3VdbeAddOp(v, OP_Insert, iStatCur, 0);
sqlite3VdbeJumpHere(v, addr);
}
@@ -214,6 +230,7 @@ static void loadAnalysis(Parse *pParse, int iDb){
*/
static void analyzeDatabase(Parse *pParse, int iDb){
sqlite3 *db = pParse->db;
+ Schema *pSchema = db->aDb[iDb].pSchema; /* Schema of database iDb */
HashElem *k;
int iStatCur;
int iMem;
@@ -222,7 +239,7 @@ static void analyzeDatabase(Parse *pParse, int iDb){
iStatCur = pParse->nTab++;
openStatTable(pParse, iDb, iStatCur, 0);
iMem = pParse->nMem;
- for(k=sqliteHashFirst(&db->aDb[iDb].tblHash); k; k=sqliteHashNext(k)){
+ for(k=sqliteHashFirst(&pSchema->tblHash); k; k=sqliteHashNext(k)){
Table *pTab = (Table*)sqliteHashData(k);
analyzeOneTable(pParse, pTab, iStatCur, iMem);
}
@@ -238,7 +255,7 @@ static void analyzeTable(Parse *pParse, Table *pTab){
int iStatCur;
assert( pTab!=0 );
- iDb = pTab->iDb;
+ iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
sqlite3BeginWriteOperation(pParse, 0, iDb);
iStatCur = pParse->nTab++;
openStatTable(pParse, iDb, iStatCur, pTab->zName);
@@ -360,7 +377,7 @@ void sqlite3AnalysisLoad(sqlite3 *db, int iDb){
char *zSql;
/* Clear any prior statistics */
- for(i=sqliteHashFirst(&db->aDb[iDb].idxHash); i; i=sqliteHashNext(i)){
+ for(i=sqliteHashFirst(&db->aDb[iDb].pSchema->idxHash);i;i=sqliteHashNext(i)){
Index *pIdx = sqliteHashData(i);
sqlite3DefaultRowEst(pIdx);
}