Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Fix a bug in the threadtest4.c program. Remove the keyinfo cache as it provides minimal performance improvements, and then only at SQL preparation time, not at runtime, and it has problems with data races in shared-cache mode. We might later add the keyinfo cache back but only enable it when shared-cache mode is off. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | threadtest4 |
Files: | files | file ages | folders |
SHA1: |
b7489f9451628c68f1dfc1d457fc161a |
User & Date: | drh 2014-12-12 00:20:37.023 |
Context
2014-12-12
| ||
00:26 | Merge the cell overflow page number cache thread race fix from trunk. (check-in: cefad47ec2 user: drh tags: threadtest4) | |
00:20 | Fix a bug in the threadtest4.c program. Remove the keyinfo cache as it provides minimal performance improvements, and then only at SQL preparation time, not at runtime, and it has problems with data races in shared-cache mode. We might later add the keyinfo cache back but only enable it when shared-cache mode is off. (check-in: b7489f9451 user: drh tags: threadtest4) | |
2014-12-11
| ||
19:29 | Add the threadtest4.c test program. Not yet working. (check-in: ec3a74469c user: drh tags: threadtest4) | |
Changes
Changes to src/build.c.
︙ | ︙ | |||
431 432 433 434 435 436 437 | /* ** Reclaim the memory used by an index */ static void freeIndex(sqlite3 *db, Index *p){ #ifndef SQLITE_OMIT_ANALYZE sqlite3DeleteIndexSamples(db, p); #endif | < | 431 432 433 434 435 436 437 438 439 440 441 442 443 444 | /* ** Reclaim the memory used by an index */ static void freeIndex(sqlite3 *db, Index *p){ #ifndef SQLITE_OMIT_ANALYZE sqlite3DeleteIndexSamples(db, p); #endif sqlite3ExprDelete(db, p->pPartIdxWhere); sqlite3DbFree(db, p->zColAff); if( p->isResized ) sqlite3DbFree(db, p->azColl); #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 sqlite3_free(p->aiRowEst); #endif sqlite3DbFree(db, p); |
︙ | ︙ | |||
4186 4187 4188 4189 4190 4191 4192 | ** So there might be multiple references to the returned pointer. The ** caller should not try to modify the KeyInfo object. ** ** The caller should invoke sqlite3KeyInfoUnref() on the returned object ** when it has finished using it. */ KeyInfo *sqlite3KeyInfoOfIndex(Parse *pParse, Index *pIdx){ | < < < < < < < < | | | | > | | | | | | | | | | | | | | | | < | | | < | | 4185 4186 4187 4188 4189 4190 4191 4192 4193 4194 4195 4196 4197 4198 4199 4200 4201 4202 4203 4204 4205 4206 4207 4208 4209 4210 4211 4212 4213 4214 4215 4216 4217 4218 4219 4220 4221 4222 4223 | ** So there might be multiple references to the returned pointer. The ** caller should not try to modify the KeyInfo object. ** ** The caller should invoke sqlite3KeyInfoUnref() on the returned object ** when it has finished using it. */ KeyInfo *sqlite3KeyInfoOfIndex(Parse *pParse, Index *pIdx){ int i; int nCol = pIdx->nColumn; int nKey = pIdx->nKeyCol; KeyInfo *pKey; if( pParse->nErr ) return 0; if( pIdx->uniqNotNull ){ pKey = sqlite3KeyInfoAlloc(pParse->db, nKey, nCol-nKey); }else{ pKey = sqlite3KeyInfoAlloc(pParse->db, nCol, 0); } if( pKey ){ assert( sqlite3KeyInfoIsWriteable(pKey) ); for(i=0; i<nCol; i++){ char *zColl = pIdx->azColl[i]; assert( zColl!=0 ); pKey->aColl[i] = strcmp(zColl,"BINARY")==0 ? 0 : sqlite3LocateCollSeq(pParse, zColl); pKey->aSortOrder[i] = pIdx->aSortOrder[i]; } if( pParse->nErr ){ sqlite3KeyInfoUnref(pKey); pKey = 0; } } return pKey; } #ifndef SQLITE_OMIT_CTE /* ** This routine is invoked once per CTE by the parser while parsing a ** WITH clause. */ |
︙ | ︙ |
Changes to src/main.c.
︙ | ︙ | |||
1028 1029 1030 1031 1032 1033 1034 | /* Free any outstanding Savepoint structures. */ sqlite3CloseSavepoints(db); /* Close all database connections */ for(j=0; j<db->nDb; j++){ struct Db *pDb = &db->aDb[j]; if( pDb->pBt ){ | < < < < < < < < < < | 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 | /* Free any outstanding Savepoint structures. */ sqlite3CloseSavepoints(db); /* Close all database connections */ for(j=0; j<db->nDb; j++){ struct Db *pDb = &db->aDb[j]; if( pDb->pBt ){ sqlite3BtreeClose(pDb->pBt); pDb->pBt = 0; if( j!=1 ){ pDb->pSchema = 0; } } } |
︙ | ︙ | |||
2165 2166 2167 2168 2169 2170 2171 | ** argument. For now, this simply calls the internal sqlite3ErrStr() ** function. */ const char *sqlite3_errstr(int rc){ return sqlite3ErrStr(rc); } | < < < < < < < < < < < < < < < < < < < < < < < < < < | 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 | ** argument. For now, this simply calls the internal sqlite3ErrStr() ** function. */ const char *sqlite3_errstr(int rc){ return sqlite3ErrStr(rc); } /* ** Create a new collating function for database "db". The name is zName ** and the encoding is enc. */ static int createCollation( sqlite3* db, const char *zName, |
︙ | ︙ | |||
2234 2235 2236 2237 2238 2239 2240 | if( pColl && pColl->xCmp ){ if( db->nVdbeActive ){ sqlite3ErrorWithMsg(db, SQLITE_BUSY, "unable to delete/modify collation sequence due to active statements"); return SQLITE_BUSY; } sqlite3ExpirePreparedStatements(db); | < | 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 | if( pColl && pColl->xCmp ){ if( db->nVdbeActive ){ sqlite3ErrorWithMsg(db, SQLITE_BUSY, "unable to delete/modify collation sequence due to active statements"); return SQLITE_BUSY; } sqlite3ExpirePreparedStatements(db); /* If collation sequence pColl was created directly by a call to ** sqlite3_create_collation, and not generated by synthCollSeq(), ** then any copies made by synthCollSeq() need to be invalidated. ** Also, collation destructor - CollSeq.xDel() - function may need ** to be called. */ |
︙ | ︙ |
Changes to src/sqliteInt.h.
︙ | ︙ | |||
1780 1781 1782 1783 1784 1785 1786 | Table *pTable; /* The SQL table being indexed */ char *zColAff; /* String defining the affinity of each column */ Index *pNext; /* The next index associated with the same table */ Schema *pSchema; /* Schema containing this index */ u8 *aSortOrder; /* for each column: True==DESC, False==ASC */ char **azColl; /* Array of collation sequence names for index */ Expr *pPartIdxWhere; /* WHERE clause for partial indices */ | < | 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 | Table *pTable; /* The SQL table being indexed */ char *zColAff; /* String defining the affinity of each column */ Index *pNext; /* The next index associated with the same table */ Schema *pSchema; /* Schema containing this index */ u8 *aSortOrder; /* for each column: True==DESC, False==ASC */ char **azColl; /* Array of collation sequence names for index */ Expr *pPartIdxWhere; /* WHERE clause for partial indices */ int tnum; /* DB Page containing root of this index */ LogEst szIdxRow; /* Estimated average row size in bytes */ u16 nKeyCol; /* Number of columns forming the key */ u16 nColumn; /* Number of columns stored in the index */ u8 onError; /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */ unsigned idxType:2; /* 1==UNIQUE, 2==PRIMARY KEY, 0==CREATE INDEX */ unsigned bUnordered:1; /* Use this index for == or IN queries only */ |
︙ | ︙ |
Changes to src/where.c.
︙ | ︙ | |||
3937 3938 3939 3940 3941 3942 3943 | if( p->wsFlags & (WHERE_VIRTUALTABLE|WHERE_AUTO_INDEX) ){ if( (p->wsFlags & WHERE_VIRTUALTABLE)!=0 && p->u.vtab.needFree ){ sqlite3_free(p->u.vtab.idxStr); p->u.vtab.needFree = 0; p->u.vtab.idxStr = 0; }else if( (p->wsFlags & WHERE_AUTO_INDEX)!=0 && p->u.btree.pIndex!=0 ){ sqlite3DbFree(db, p->u.btree.pIndex->zColAff); | < | 3937 3938 3939 3940 3941 3942 3943 3944 3945 3946 3947 3948 3949 3950 | if( p->wsFlags & (WHERE_VIRTUALTABLE|WHERE_AUTO_INDEX) ){ if( (p->wsFlags & WHERE_VIRTUALTABLE)!=0 && p->u.vtab.needFree ){ sqlite3_free(p->u.vtab.idxStr); p->u.vtab.needFree = 0; p->u.vtab.idxStr = 0; }else if( (p->wsFlags & WHERE_AUTO_INDEX)!=0 && p->u.btree.pIndex!=0 ){ sqlite3DbFree(db, p->u.btree.pIndex->zColAff); sqlite3DbFree(db, p->u.btree.pIndex); p->u.btree.pIndex = 0; } } } /* |
︙ | ︙ |
Changes to test/threadtest4.c.
︙ | ︙ | |||
297 298 299 300 301 302 303 304 305 306 307 308 309 310 | rc = sqlite3_step(pStmt); if( rc!=SQLITE_ROW ){ worker_error(p, "Failed to step: %s", sqlite3_sql(pStmt)); }else if( sqlite3_column_int(pStmt, 0)!=400 ){ worker_error(p, "Wrong result: %d", sqlite3_column_int(pStmt,0)); } if( p->nErr ) break; worker_delete_all_content(p, (p->tid+iOuter)%2); worker_close_connection(p); p->db = 0; } worker_close_connection(p); printf("worker %d finished\n", p->tid); fflush(stdout); | > | 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 | rc = sqlite3_step(pStmt); if( rc!=SQLITE_ROW ){ worker_error(p, "Failed to step: %s", sqlite3_sql(pStmt)); }else if( sqlite3_column_int(pStmt, 0)!=400 ){ worker_error(p, "Wrong result: %d", sqlite3_column_int(pStmt,0)); } if( p->nErr ) break; sqlite3_finalize(pStmt); worker_delete_all_content(p, (p->tid+iOuter)%2); worker_close_connection(p); p->db = 0; } worker_close_connection(p); printf("worker %d finished\n", p->tid); fflush(stdout); |
︙ | ︙ |