mirror of
https://github.com/sqlite/sqlite.git
synced 2025-11-16 23:02:26 +03:00
Fix a couple of bugs in the schemalint code.
FossilOrigin-Name: 02fbf699c07286f842d9617755f071b0fffc5d40
This commit is contained in:
12
manifest
12
manifest
@@ -1,5 +1,5 @@
|
|||||||
C Have\sthe\sschemalint\soutput\sdistinguish\sbetween\sexisting\sand\srecommended\sindexes.
|
C Fix\sa\scouple\sof\sbugs\sin\sthe\sschemalint\scode.
|
||||||
D 2016-02-18T19:10:02.440
|
D 2016-02-19T07:53:43.883
|
||||||
F Makefile.in dac2776c84e0d533b158a9af6e57e05c4a6b19f3
|
F Makefile.in dac2776c84e0d533b158a9af6e57e05c4a6b19f3
|
||||||
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
|
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
|
||||||
F Makefile.msc b0493f10caddb8adf992a4e6f1943141fc7c6816
|
F Makefile.msc b0493f10caddb8adf992a4e6f1943141fc7c6816
|
||||||
@@ -350,7 +350,7 @@ F src/resolve.c 9f7ce3a3c087afb7597b7c916c99126ff3f12f0c
|
|||||||
F src/rowset.c 9fe4b3ad7cc00944386bb600233d8f523de07a6e
|
F src/rowset.c 9fe4b3ad7cc00944386bb600233d8f523de07a6e
|
||||||
F src/select.c ff80004a9a6ece891a8d9327a88e7b6e2588ee6d
|
F src/select.c ff80004a9a6ece891a8d9327a88e7b6e2588ee6d
|
||||||
F src/shell.c 2cde87e03712204231167c4a6c61b0eb5129e105
|
F src/shell.c 2cde87e03712204231167c4a6c61b0eb5129e105
|
||||||
F src/shell_indexes.c 277eb75b8cfb3c2bcf76e062baaa419779f824e7
|
F src/shell_indexes.c c0099c01c7af01038ab4315621814df535b700a3
|
||||||
F src/sqlite.h.in c7db059d3b810b70b83d9ed1436fa813eba22462
|
F src/sqlite.h.in c7db059d3b810b70b83d9ed1436fa813eba22462
|
||||||
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
||||||
F src/sqlite3ext.h dfbe62ffd95b99afe2140d8c35b180d11924072d
|
F src/sqlite3ext.h dfbe62ffd95b99afe2140d8c35b180d11924072d
|
||||||
@@ -1430,7 +1430,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f
|
|||||||
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
||||||
F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b
|
F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b
|
||||||
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
||||||
P cf0f7eeb4f6490b1e3f05b45e83b87cd64640846
|
P 4ab3df25f1fee7c8fea19d0c64b3e0e4d3b9c3cf
|
||||||
R f54b8a1f9b5e206798931d383b1eb3a6
|
R 0c9cae22954d1f32b48770c565f201e2
|
||||||
U dan
|
U dan
|
||||||
Z 5c18fceb59d8462f5aec79ee219a18a2
|
Z cecc60af647c055f880ee4bdf2018855
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
4ab3df25f1fee7c8fea19d0c64b3e0e4d3b9c3cf
|
02fbf699c07286f842d9617755f071b0fffc5d40
|
||||||
@@ -95,7 +95,7 @@ struct IdxScan {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Context object passed to idxWhereInfo()
|
** Context object passed to idxWhereInfo() and other functions.
|
||||||
*/
|
*/
|
||||||
struct IdxContext {
|
struct IdxContext {
|
||||||
char **pzErrmsg;
|
char **pzErrmsg;
|
||||||
@@ -454,7 +454,7 @@ static char *idxAppendText(int *pRc, char *zIn, const char *zFmt, ...){
|
|||||||
zAppend = sqlite3_vmprintf(zFmt, ap);
|
zAppend = sqlite3_vmprintf(zFmt, ap);
|
||||||
if( zAppend ){
|
if( zAppend ){
|
||||||
nAppend = strlen(zAppend);
|
nAppend = strlen(zAppend);
|
||||||
zRet = (char*)sqlite3_malloc(nIn + nAppend);
|
zRet = (char*)sqlite3_malloc(nIn + nAppend + 1);
|
||||||
}
|
}
|
||||||
if( zAppend && zRet ){
|
if( zAppend && zRet ){
|
||||||
memcpy(zRet, zIn, nIn);
|
memcpy(zRet, zIn, nIn);
|
||||||
@@ -532,8 +532,9 @@ static int idxFindCompatible(
|
|||||||
int nEq = 0; /* Number of elements in pEq */
|
int nEq = 0; /* Number of elements in pEq */
|
||||||
int rc, rc2;
|
int rc, rc2;
|
||||||
|
|
||||||
|
|
||||||
/* Count the elements in list pEq */
|
/* Count the elements in list pEq */
|
||||||
for(pIter=pEq; pIter; pIter=pIter->pNext) nEq++;
|
for(pIter=pEq; pIter; pIter=pIter->pLink) nEq++;
|
||||||
|
|
||||||
rc = idxPrintfPrepareStmt(dbm, &pIdxList, 0, "PRAGMA index_list=%Q", zTbl);
|
rc = idxPrintfPrepareStmt(dbm, &pIdxList, 0, "PRAGMA index_list=%Q", zTbl);
|
||||||
while( rc==SQLITE_OK && sqlite3_step(pIdxList)==SQLITE_ROW ){
|
while( rc==SQLITE_OK && sqlite3_step(pIdxList)==SQLITE_ROW ){
|
||||||
@@ -543,7 +544,7 @@ static int idxFindCompatible(
|
|||||||
const char *zIdx = (const char*)sqlite3_column_text(pIdxList, 1);
|
const char *zIdx = (const char*)sqlite3_column_text(pIdxList, 1);
|
||||||
|
|
||||||
/* Zero the IdxConstraint.bFlag values in the pEq list */
|
/* Zero the IdxConstraint.bFlag values in the pEq list */
|
||||||
for(pIter=pEq; pIter; pIter=pIter->pNext) pIter->bFlag = 0;
|
for(pIter=pEq; pIter; pIter=pIter->pLink) pIter->bFlag = 0;
|
||||||
|
|
||||||
rc = idxPrintfPrepareStmt(dbm, &pInfo, 0, "PRAGMA index_xInfo=%Q", zIdx);
|
rc = idxPrintfPrepareStmt(dbm, &pInfo, 0, "PRAGMA index_xInfo=%Q", zIdx);
|
||||||
while( rc==SQLITE_OK && sqlite3_step(pInfo)==SQLITE_ROW ){
|
while( rc==SQLITE_OK && sqlite3_step(pInfo)==SQLITE_ROW ){
|
||||||
@@ -552,7 +553,7 @@ static int idxFindCompatible(
|
|||||||
const char *zColl = (const char*)sqlite3_column_text(pInfo, 4);
|
const char *zColl = (const char*)sqlite3_column_text(pInfo, 4);
|
||||||
|
|
||||||
if( iIdx<nEq ){
|
if( iIdx<nEq ){
|
||||||
for(pIter=pEq; pIter; pIter=pIter->pNext){
|
for(pIter=pEq; pIter; pIter=pIter->pLink){
|
||||||
if( pIter->bFlag ) continue;
|
if( pIter->bFlag ) continue;
|
||||||
if( pIter->iCol!=iCol ) continue;
|
if( pIter->iCol!=iCol ) continue;
|
||||||
if( sqlite3_stricmp(pIter->zColl, zColl) ) continue;
|
if( sqlite3_stricmp(pIter->zColl, zColl) ) continue;
|
||||||
@@ -627,10 +628,8 @@ static int idxCreateFromCons(
|
|||||||
if( !zIdx ){
|
if( !zIdx ){
|
||||||
rc = SQLITE_NOMEM;
|
rc = SQLITE_NOMEM;
|
||||||
}else{
|
}else{
|
||||||
rc = sqlite3_exec(dbm, zIdx, 0, 0, 0);
|
rc = sqlite3_exec(dbm, zIdx, 0, 0, pCtx->pzErrmsg);
|
||||||
#if 0
|
/* printf("%s\n", zIdx); */
|
||||||
printf("/* %s */\n", zIdx);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( rc==SQLITE_OK && pCtx->iIdxRowid==0 ){
|
if( rc==SQLITE_OK && pCtx->iIdxRowid==0 ){
|
||||||
@@ -676,6 +675,18 @@ static int idxCreateForeachOr(
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Return true if list pList (linked by IdxConstraint.pLink) contains
|
||||||
|
** a constraint compatible with *p. Otherwise return false.
|
||||||
|
*/
|
||||||
|
static int idxFindConstraint(IdxConstraint *pList, IdxConstraint *p){
|
||||||
|
IdxConstraint *pCmp;
|
||||||
|
for(pCmp=pList; pCmp; pCmp=pCmp->pLink){
|
||||||
|
if( p->iCol==pCmp->iCol ) return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int idxCreateFromWhere(
|
static int idxCreateFromWhere(
|
||||||
IdxContext *pCtx,
|
IdxContext *pCtx,
|
||||||
i64 mask, /* Consider only these constraints */
|
i64 mask, /* Consider only these constraints */
|
||||||
@@ -691,7 +702,10 @@ static int idxCreateFromWhere(
|
|||||||
|
|
||||||
/* Gather up all the == constraints that match the mask. */
|
/* Gather up all the == constraints that match the mask. */
|
||||||
for(pCon=pWhere->pEq; pCon; pCon=pCon->pNext){
|
for(pCon=pWhere->pEq; pCon; pCon=pCon->pNext){
|
||||||
if( (mask & pCon->depmask)==pCon->depmask ){
|
if( (mask & pCon->depmask)==pCon->depmask
|
||||||
|
&& idxFindConstraint(p1, pCon)==0
|
||||||
|
&& idxFindConstraint(pTail, pCon)==0
|
||||||
|
){
|
||||||
pCon->pLink = p1;
|
pCon->pLink = p1;
|
||||||
p1 = pCon;
|
p1 = pCon;
|
||||||
}
|
}
|
||||||
@@ -709,7 +723,10 @@ static int idxCreateFromWhere(
|
|||||||
if( pTail==0 ){
|
if( pTail==0 ){
|
||||||
for(pCon=pWhere->pRange; rc==SQLITE_OK && pCon; pCon=pCon->pNext){
|
for(pCon=pWhere->pRange; rc==SQLITE_OK && pCon; pCon=pCon->pNext){
|
||||||
assert( pCon->pLink==0 );
|
assert( pCon->pLink==0 );
|
||||||
if( (mask & pCon->depmask)==pCon->depmask ){
|
if( (mask & pCon->depmask)==pCon->depmask
|
||||||
|
&& idxFindConstraint(pEq, pCon)==0
|
||||||
|
&& idxFindConstraint(pTail, pCon)==0
|
||||||
|
){
|
||||||
rc = idxCreateFromCons(pCtx, pScan, p1, pCon);
|
rc = idxCreateFromCons(pCtx, pScan, p1, pCon);
|
||||||
if( rc==SQLITE_OK ){
|
if( rc==SQLITE_OK ){
|
||||||
rc = idxCreateForeachOr(pCtx, mask, pScan, pWhere, p1, pCon);
|
rc = idxCreateForeachOr(pCtx, mask, pScan, pWhere, p1, pCon);
|
||||||
@@ -787,9 +804,14 @@ int idxFindIndexes(
|
|||||||
int nDetail = strlen(zDetail);
|
int nDetail = strlen(zDetail);
|
||||||
|
|
||||||
for(i=0; i<nDetail; i++){
|
for(i=0; i<nDetail; i++){
|
||||||
|
const char *zIdx = 0;
|
||||||
if( memcmp(&zDetail[i], " USING INDEX ", 13)==0 ){
|
if( memcmp(&zDetail[i], " USING INDEX ", 13)==0 ){
|
||||||
|
zIdx = &zDetail[i+13];
|
||||||
|
}else if( memcmp(&zDetail[i], " USING COVERING INDEX ", 22)==0 ){
|
||||||
|
zIdx = &zDetail[i+22];
|
||||||
|
}
|
||||||
|
if( zIdx ){
|
||||||
int nIdx = 0;
|
int nIdx = 0;
|
||||||
const char *zIdx = &zDetail[i+13];
|
|
||||||
while( zIdx[nIdx]!='\0' && zIdx[nIdx]!=' ' ) nIdx++;
|
while( zIdx[nIdx]!='\0' && zIdx[nIdx]!=' ' ) nIdx++;
|
||||||
sqlite3_bind_text(pSelect, 1, zIdx, nIdx, SQLITE_STATIC);
|
sqlite3_bind_text(pSelect, 1, zIdx, nIdx, SQLITE_STATIC);
|
||||||
if( SQLITE_ROW==sqlite3_step(pSelect) ){
|
if( SQLITE_ROW==sqlite3_step(pSelect) ){
|
||||||
@@ -856,6 +878,7 @@ int shellIndexesCommand(
|
|||||||
sqlite3_stmt *pStmt = 0; /* Statement compiled from zSql */
|
sqlite3_stmt *pStmt = 0; /* Statement compiled from zSql */
|
||||||
|
|
||||||
memset(&ctx, 0, sizeof(IdxContext));
|
memset(&ctx, 0, sizeof(IdxContext));
|
||||||
|
ctx.pzErrmsg = pzErrmsg;
|
||||||
|
|
||||||
/* Open an in-memory database to work with. The main in-memory
|
/* Open an in-memory database to work with. The main in-memory
|
||||||
** database schema contains tables similar to those in the users
|
** database schema contains tables similar to those in the users
|
||||||
|
|||||||
Reference in New Issue
Block a user