diff options
Diffstat (limited to 'src/pragma.c')
-rw-r--r-- | src/pragma.c | 108 |
1 files changed, 70 insertions, 38 deletions
diff --git a/src/pragma.c b/src/pragma.c index 969af6af3..a1f32c36d 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -56,18 +56,19 @@ #define PragTyp_SECURE_DELETE 25 #define PragTyp_SHRINK_MEMORY 26 #define PragTyp_SOFT_HEAP_LIMIT 27 -#define PragTyp_SYNCHRONOUS 28 -#define PragTyp_TABLE_INFO 29 -#define PragTyp_TEMP_STORE 30 -#define PragTyp_TEMP_STORE_DIRECTORY 31 -#define PragTyp_WAL_AUTOCHECKPOINT 32 -#define PragTyp_WAL_CHECKPOINT 33 -#define PragTyp_ACTIVATE_EXTENSIONS 34 -#define PragTyp_HEXKEY 35 -#define PragTyp_KEY 36 -#define PragTyp_REKEY 37 -#define PragTyp_LOCK_STATUS 38 -#define PragTyp_PARSER_TRACE 39 +#define PragTyp_STATS 28 +#define PragTyp_SYNCHRONOUS 29 +#define PragTyp_TABLE_INFO 30 +#define PragTyp_TEMP_STORE 31 +#define PragTyp_TEMP_STORE_DIRECTORY 32 +#define PragTyp_WAL_AUTOCHECKPOINT 33 +#define PragTyp_WAL_CHECKPOINT 34 +#define PragTyp_ACTIVATE_EXTENSIONS 35 +#define PragTyp_HEXKEY 36 +#define PragTyp_KEY 37 +#define PragTyp_REKEY 38 +#define PragTyp_LOCK_STATUS 39 +#define PragTyp_PARSER_TRACE 40 #define PragFlag_NeedSchema 0x01 static const struct sPragmaNames { const char *const zName; /* Name of pragma */ @@ -359,6 +360,12 @@ static const struct sPragmaNames { /* ePragFlag: */ 0, /* iArg: */ SQLITE_SqlTrace }, #endif +#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) + { /* zName: */ "stats", + /* ePragTyp: */ PragTyp_STATS, + /* ePragFlag: */ PragFlag_NeedSchema, + /* iArg: */ 0 }, +#endif #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) { /* zName: */ "synchronous", /* ePragTyp: */ PragTyp_SYNCHRONOUS, @@ -420,7 +427,7 @@ static const struct sPragmaNames { /* ePragFlag: */ 0, /* iArg: */ SQLITE_WriteSchema|SQLITE_RecoveryMode }, }; -/* Number of pragmas: 55 on by default, 67 total. */ +/* Number of pragmas: 56 on by default, 68 total. */ /* End of the automatically generated pragma table. ***************************************************************************/ @@ -1425,6 +1432,36 @@ void sqlite3Pragma( } break; + case PragTyp_STATS: { + Index *pIdx; + HashElem *i; + v = sqlite3GetVdbe(pParse); + sqlite3VdbeSetNumCols(v, 4); + pParse->nMem = 4; + sqlite3CodeVerifySchema(pParse, iDb); + sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "table", SQLITE_STATIC); + sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "index", SQLITE_STATIC); + sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "width", SQLITE_STATIC); + sqlite3VdbeSetColName(v, 3, COLNAME_NAME, "height", SQLITE_STATIC); + for(i=sqliteHashFirst(&pDb->pSchema->tblHash); i; i=sqliteHashNext(i)){ + Table *pTab = sqliteHashData(i); + sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, pTab->zName, 0); + sqlite3VdbeAddOp2(v, OP_Null, 0, 2); + sqlite3VdbeAddOp2(v, OP_Integer, + (int)sqlite3LogEstToInt(pTab->szTabRow), 3); + sqlite3VdbeAddOp2(v, OP_Integer, (int)pTab->nRowEst, 4); + sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 4); + for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ + sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0, pIdx->zName, 0); + sqlite3VdbeAddOp2(v, OP_Integer, + (int)sqlite3LogEstToInt(pIdx->szIdxRow), 3); + sqlite3VdbeAddOp2(v, OP_Integer, (int)pIdx->aiRowEst[0], 4); + sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 4); + } + } + } + break; + case PragTyp_INDEX_INFO: if( zRight ){ Index *pIdx; Table *pTab; @@ -1457,26 +1494,17 @@ void sqlite3Pragma( pTab = sqlite3FindTable(db, zRight, zDb); if( pTab ){ v = sqlite3GetVdbe(pParse); - sqlite3VdbeSetNumCols(v, 4); - pParse->nMem = 4; + sqlite3VdbeSetNumCols(v, 3); + pParse->nMem = 3; sqlite3CodeVerifySchema(pParse, iDb); sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seq", SQLITE_STATIC); sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", SQLITE_STATIC); sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "unique", SQLITE_STATIC); - sqlite3VdbeSetColName(v, 3, COLNAME_NAME, "avgrowsize", SQLITE_STATIC); - sqlite3VdbeAddOp2(v, OP_Integer, 0, 1); - sqlite3VdbeAddOp2(v, OP_Null, 0, 2); - sqlite3VdbeAddOp2(v, OP_Integer, 1, 3); - sqlite3VdbeAddOp2(v, OP_Integer, - (int)sqlite3LogEstToInt(pTab->szTabRow), 4); - sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 4); - for(pIdx=pTab->pIndex, i=1; pIdx; pIdx=pIdx->pNext, i++){ + for(pIdx=pTab->pIndex, i=0; pIdx; pIdx=pIdx->pNext, i++){ sqlite3VdbeAddOp2(v, OP_Integer, i, 1); sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0, pIdx->zName, 0); sqlite3VdbeAddOp2(v, OP_Integer, pIdx->onError!=OE_None, 3); - sqlite3VdbeAddOp2(v, OP_Integer, - (int)sqlite3LogEstToInt(pIdx->szIdxRow), 4); - sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 4); + sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 3); } } } @@ -1610,8 +1638,8 @@ void sqlite3Pragma( sqlite3VdbeAddOp4(v, OP_String8, 0, regResult, 0, pTab->zName, P4_TRANSIENT); for(i=1, pFK=pTab->pFKey; pFK; i++, pFK=pFK->pNextFrom){ - pParent = sqlite3LocateTable(pParse, 0, pFK->zTo, zDb); - if( pParent==0 ) break; + pParent = sqlite3FindTable(db, pFK->zTo, zDb); + if( pParent==0 ) continue; pIdx = 0; sqlite3TableLock(pParse, iDb, pParent->tnum, 0, pParent->zName); x = sqlite3FkLocateIndex(pParse, pParent, pFK, &pIdx, 0); @@ -1628,18 +1656,20 @@ void sqlite3Pragma( break; } } + assert( pParse->nErr>0 || pFK==0 ); if( pFK ) break; if( pParse->nTab<i ) pParse->nTab = i; addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, 0); for(i=1, pFK=pTab->pFKey; pFK; i++, pFK=pFK->pNextFrom){ - pParent = sqlite3LocateTable(pParse, 0, pFK->zTo, zDb); - assert( pParent!=0 ); + pParent = sqlite3FindTable(db, pFK->zTo, zDb); pIdx = 0; aiCols = 0; - x = sqlite3FkLocateIndex(pParse, pParent, pFK, &pIdx, &aiCols); - assert( x==0 ); + if( pParent ){ + x = sqlite3FkLocateIndex(pParse, pParent, pFK, &pIdx, &aiCols); + assert( x==0 ); + } addrOk = sqlite3VdbeMakeLabel(v); - if( pIdx==0 ){ + if( pParent && pIdx==0 ){ int iKey = pFK->aCol[0].iFrom; assert( iKey>=0 && iKey<pTab->nCol ); if( iKey!=pTab->iPKey ){ @@ -1657,13 +1687,15 @@ void sqlite3Pragma( }else{ for(j=0; j<pFK->nCol; j++){ sqlite3ExprCodeGetColumnOfTable(v, pTab, 0, - aiCols ? aiCols[j] : pFK->aCol[0].iFrom, regRow+j); + aiCols ? aiCols[j] : pFK->aCol[j].iFrom, regRow+j); sqlite3VdbeAddOp2(v, OP_IsNull, regRow+j, addrOk); } - sqlite3VdbeAddOp3(v, OP_MakeRecord, regRow, pFK->nCol, regKey); - sqlite3VdbeChangeP4(v, -1, - sqlite3IndexAffinityStr(v,pIdx), P4_TRANSIENT); - sqlite3VdbeAddOp4Int(v, OP_Found, i, addrOk, regKey, 0); + if( pParent ){ + sqlite3VdbeAddOp3(v, OP_MakeRecord, regRow, pFK->nCol, regKey); + sqlite3VdbeChangeP4(v, -1, + sqlite3IndexAffinityStr(v,pIdx), P4_TRANSIENT); + sqlite3VdbeAddOp4Int(v, OP_Found, i, addrOk, regKey, 0); + } } sqlite3VdbeAddOp2(v, OP_Rowid, 0, regResult+1); sqlite3VdbeAddOp4(v, OP_String8, 0, regResult+2, 0, |