Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Modifications to the malloc failure tests to test transient and persistent failures. (CVS 4321) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
e38ef81b85feb5bff2ad8448f3438ff0 |
User & Date: | danielk1977 2007-08-29 12:31:26.000 |
Context
2007-08-29
| ||
13:45 | Be careful to verify the schema cookie when running the xfer optimization on INSERT statements. (CVS 4322) (check-in: d8ef702417 user: drh tags: trunk) | |
12:31 | Modifications to the malloc failure tests to test transient and persistent failures. (CVS 4321) (check-in: e38ef81b85 user: danielk1977 tags: trunk) | |
04:00 | Better asserts(). But now some of the tests are busted again. (CVS 4320) (check-in: e8060f85e7 user: drh tags: trunk) | |
Changes
Changes to src/btree.c.
1 2 3 4 5 6 7 8 9 10 11 | /* ** 2004 April 6 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | /* ** 2004 April 6 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** $Id: btree.c,v 1.417 2007/08/29 12:31:26 danielk1977 Exp $ ** ** This file implements a external (disk-based) database using BTrees. ** See the header comment on "btreeInt.h" for additional information. ** Including a description of file format and an overview of operation. */ #include "btreeInt.h" |
︙ | ︙ | |||
1208 1209 1210 1211 1212 1213 1214 | sqlite3PagerSetReiniter(pBt->pPager, pageReinit); pBt->pCursor = 0; pBt->pPage1 = 0; pBt->readOnly = sqlite3PagerIsreadonly(pBt->pPager); pBt->pageSize = get2byte(&zDbHeader[16]); if( pBt->pageSize<512 || pBt->pageSize>SQLITE_MAX_PAGE_SIZE || ((pBt->pageSize-1)&pBt->pageSize)!=0 ){ | > | | 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 | sqlite3PagerSetReiniter(pBt->pPager, pageReinit); pBt->pCursor = 0; pBt->pPage1 = 0; pBt->readOnly = sqlite3PagerIsreadonly(pBt->pPager); pBt->pageSize = get2byte(&zDbHeader[16]); if( pBt->pageSize<512 || pBt->pageSize>SQLITE_MAX_PAGE_SIZE || ((pBt->pageSize-1)&pBt->pageSize)!=0 ){ pBt->pageSize = 0; sqlite3PagerSetPagesize(pBt->pPager, &pBt->pageSize); pBt->maxEmbedFrac = 64; /* 25% */ pBt->minEmbedFrac = 32; /* 12.5% */ pBt->minLeafFrac = 32; /* 12.5% */ #ifndef SQLITE_OMIT_AUTOVACUUM /* If the magic name ":memory:" will create an in-memory database, then ** leave the autoVacuum mode at 0 (do not auto-vacuum), even if ** SQLITE_DEFAULT_AUTOVACUUM is true. On the other hand, if |
︙ | ︙ | |||
1238 1239 1240 1241 1242 1243 1244 | #ifndef SQLITE_OMIT_AUTOVACUUM pBt->autoVacuum = (get4byte(&zDbHeader[36 + 4*4])?1:0); pBt->incrVacuum = (get4byte(&zDbHeader[36 + 7*4])?1:0); #endif } pBt->usableSize = pBt->pageSize - nReserve; assert( (pBt->pageSize & 7)==0 ); /* 8-byte alignment of pageSize */ | | | 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 | #ifndef SQLITE_OMIT_AUTOVACUUM pBt->autoVacuum = (get4byte(&zDbHeader[36 + 4*4])?1:0); pBt->incrVacuum = (get4byte(&zDbHeader[36 + 7*4])?1:0); #endif } pBt->usableSize = pBt->pageSize - nReserve; assert( (pBt->pageSize & 7)==0 ); /* 8-byte alignment of pageSize */ sqlite3PagerSetPagesize(pBt->pPager, &pBt->pageSize); #if !defined(SQLITE_OMIT_SHARED_CACHE) && !defined(SQLITE_OMIT_DISKIO) /* Add the new BtShared object to the linked list sharable BtShareds. */ if( p->sharable ){ sqlite3_mutex *mutexShared; pBt->nRef = 1; |
︙ | ︙ | |||
1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 | ** the first byte past the 1GB boundary, 0x40000000) needs to occur ** at the beginning of a page. ** ** If parameter nReserve is less than zero, then the number of reserved ** bytes per page is left unchanged. */ int sqlite3BtreeSetPageSize(Btree *p, int pageSize, int nReserve){ BtShared *pBt = p->pBt; sqlite3BtreeEnter(p); if( pBt->pageSizeFixed ){ sqlite3BtreeLeave(p); return SQLITE_READONLY; } if( nReserve<0 ){ nReserve = pBt->pageSize - pBt->usableSize; } if( pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE && ((pageSize-1)&pageSize)==0 ){ assert( (pageSize & 7)==0 ); assert( !pBt->pPage1 && !pBt->pCursor ); | > > | | | 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 | ** the first byte past the 1GB boundary, 0x40000000) needs to occur ** at the beginning of a page. ** ** If parameter nReserve is less than zero, then the number of reserved ** bytes per page is left unchanged. */ int sqlite3BtreeSetPageSize(Btree *p, int pageSize, int nReserve){ int rc = SQLITE_OK; BtShared *pBt = p->pBt; sqlite3BtreeEnter(p); if( pBt->pageSizeFixed ){ sqlite3BtreeLeave(p); return SQLITE_READONLY; } if( nReserve<0 ){ nReserve = pBt->pageSize - pBt->usableSize; } if( pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE && ((pageSize-1)&pageSize)==0 ){ assert( (pageSize & 7)==0 ); assert( !pBt->pPage1 && !pBt->pCursor ); pBt->pageSize = pageSize; rc = sqlite3PagerSetPagesize(pBt->pPager, &pBt->pageSize); } pBt->usableSize = pBt->pageSize - nReserve; sqlite3BtreeLeave(p); return rc; } /* ** Return the currently defined page size */ int sqlite3BtreeGetPageSize(Btree *p){ return p->pBt->pageSize; |
︙ | ︙ |
Changes to src/build.c.
︙ | ︙ | |||
18 19 20 21 22 23 24 | ** CREATE INDEX ** DROP INDEX ** creating ID lists ** BEGIN TRANSACTION ** COMMIT ** ROLLBACK ** | | | 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | ** CREATE INDEX ** DROP INDEX ** creating ID lists ** BEGIN TRANSACTION ** COMMIT ** ROLLBACK ** ** $Id: build.c,v 1.441 2007/08/29 12:31:26 danielk1977 Exp $ */ #include "sqliteInt.h" #include <ctype.h> /* ** This routine is called when a new SQL statement is beginning to ** be parsed. Initialize the pParse structure as needed. |
︙ | ︙ | |||
237 238 239 240 241 242 243 244 245 246 247 248 249 250 | if( pParse->nErr ) return; assert( pParse->nested<10 ); /* Nesting should only be of limited depth */ va_start(ap, zFormat); zSql = sqlite3VMPrintf(pParse->db, zFormat, ap); va_end(ap); if( zSql==0 ){ return; /* A malloc must have failed */ } pParse->nested++; memcpy(saveBuf, &pParse->nVar, SAVE_SZ); memset(&pParse->nVar, 0, SAVE_SZ); sqlite3RunParser(pParse, zSql, 0); sqlite3_free(zSql); | > | 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 | if( pParse->nErr ) return; assert( pParse->nested<10 ); /* Nesting should only be of limited depth */ va_start(ap, zFormat); zSql = sqlite3VMPrintf(pParse->db, zFormat, ap); va_end(ap); if( zSql==0 ){ pParse->db->mallocFailed = 1; return; /* A malloc must have failed */ } pParse->nested++; memcpy(saveBuf, &pParse->nVar, SAVE_SZ); memset(&pParse->nVar, 0, SAVE_SZ); sqlite3RunParser(pParse, zSql, 0); sqlite3_free(zSql); |
︙ | ︙ | |||
1558 1559 1560 1561 1562 1563 1564 1565 1566 | if( pOld ){ assert( p==pOld ); /* Malloc must have failed inside HashInsert() */ db->mallocFailed = 1; return; } #ifndef SQLITE_OMIT_FOREIGN_KEY for(pFKey=p->pFKey; pFKey; pFKey=pFKey->pNextFrom){ int nTo = strlen(pFKey->zTo) + 1; pFKey->pNextTo = sqlite3HashFind(&pSchema->aFKey, pFKey->zTo, nTo); | > | > > > | 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 | if( pOld ){ assert( p==pOld ); /* Malloc must have failed inside HashInsert() */ db->mallocFailed = 1; return; } #ifndef SQLITE_OMIT_FOREIGN_KEY for(pFKey=p->pFKey; pFKey; pFKey=pFKey->pNextFrom){ void *data; int nTo = strlen(pFKey->zTo) + 1; pFKey->pNextTo = sqlite3HashFind(&pSchema->aFKey, pFKey->zTo, nTo); data = sqlite3HashInsert(&pSchema->aFKey, pFKey->zTo, nTo, pFKey); if( data==(void *)pFKey ){ db->mallocFailed = 1; } } #endif pParse->pNewTable = 0; db->nTable++; db->flags |= SQLITE_InternChanges; #ifndef SQLITE_OMIT_ALTERTABLE |
︙ | ︙ | |||
2379 2380 2381 2382 2383 2384 2385 | char zBuf[30]; int n; Index *pLoop; for(pLoop=pTab->pIndex, n=1; pLoop; pLoop=pLoop->pNext, n++){} sqlite3_snprintf(sizeof(zBuf),zBuf,"_%d",n); zName = 0; sqlite3SetString(&zName, "sqlite_autoindex_", pTab->zName, zBuf, (char*)0); | | > > > | 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 | char zBuf[30]; int n; Index *pLoop; for(pLoop=pTab->pIndex, n=1; pLoop; pLoop=pLoop->pNext, n++){} sqlite3_snprintf(sizeof(zBuf),zBuf,"_%d",n); zName = 0; sqlite3SetString(&zName, "sqlite_autoindex_", pTab->zName, zBuf, (char*)0); if( zName==0 ){ db->mallocFailed = 1; goto exit_create_index; } } /* Check for authorization to create an index. */ #ifndef SQLITE_OMIT_AUTHORIZATION { const char *zDb = pDb->zName; |
︙ | ︙ |
Changes to src/callback.c.
︙ | ︙ | |||
9 10 11 12 13 14 15 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** ** This file contains functions used to access the internal hash tables ** of user defined functions and collation sequences. ** | | | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** ** This file contains functions used to access the internal hash tables ** of user defined functions and collation sequences. ** ** $Id: callback.c,v 1.23 2007/08/29 12:31:26 danielk1977 Exp $ */ #include "sqliteInt.h" /* ** Invoke the 'collation needed' callback to request a collation sequence ** in the database text encoding of name zName, length nName. |
︙ | ︙ | |||
357 358 359 360 361 362 363 | /* ** Find and return the schema associated with a BTree. Create ** a new one if necessary. */ Schema *sqlite3SchemaGet(sqlite3 *db, Btree *pBt){ Schema * p; if( pBt ){ | | | > > | | 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 | /* ** Find and return the schema associated with a BTree. Create ** a new one if necessary. */ Schema *sqlite3SchemaGet(sqlite3 *db, Btree *pBt){ Schema * p; if( pBt ){ p = (Schema *)sqlite3BtreeSchema(pBt, sizeof(Schema), sqlite3SchemaFree); }else{ p = (Schema *)sqlite3MallocZero(sizeof(Schema)); } if( !p ){ db->mallocFailed = 1; }else if ( 0==p->file_format ){ sqlite3HashInit(&p->tblHash, SQLITE_HASH_STRING, 0); sqlite3HashInit(&p->idxHash, SQLITE_HASH_STRING, 0); sqlite3HashInit(&p->trigHash, SQLITE_HASH_STRING, 0); sqlite3HashInit(&p->aFKey, SQLITE_HASH_STRING, 1); p->enc = SQLITE_UTF8; } return p; } |
Changes to src/expr.c.
︙ | ︙ | |||
8 9 10 11 12 13 14 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains routines used for analyzing expressions and ** for generating VDBE code that evaluates expressions in SQLite. ** | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains routines used for analyzing expressions and ** for generating VDBE code that evaluates expressions in SQLite. ** ** $Id: expr.c,v 1.309 2007/08/29 12:31:26 danielk1977 Exp $ */ #include "sqliteInt.h" #include <ctype.h> /* ** Return the 'affinity' of the expression pExpr if any. ** |
︙ | ︙ | |||
217 218 219 220 221 222 223 224 225 226 227 228 229 | /* ** Construct a new expression node and return a pointer to it. Memory ** for this node is obtained from sqlite3_malloc(). The calling function ** is responsible for making sure the node eventually gets freed. */ Expr *sqlite3Expr( int op, /* Expression opcode */ Expr *pLeft, /* Left operand */ Expr *pRight, /* Right operand */ const Token *pToken /* Argument token */ ){ Expr *pNew; | > | | 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 | /* ** Construct a new expression node and return a pointer to it. Memory ** for this node is obtained from sqlite3_malloc(). The calling function ** is responsible for making sure the node eventually gets freed. */ Expr *sqlite3Expr( sqlite3 *db, /* Handle for sqlite3DbMallocZero() (may be null) */ int op, /* Expression opcode */ Expr *pLeft, /* Left operand */ Expr *pRight, /* Right operand */ const Token *pToken /* Argument token */ ){ Expr *pNew; pNew = sqlite3DbMallocZero(db, sizeof(Expr)); if( pNew==0 ){ /* When malloc fails, delete pLeft and pRight. Expressions passed to ** this function must always be allocated with sqlite3Expr() for this ** reason. */ sqlite3ExprDelete(pLeft); sqlite3ExprDelete(pRight); |
︙ | ︙ | |||
269 270 271 272 273 274 275 | Expr *sqlite3PExpr( Parse *pParse, /* Parsing context */ int op, /* Expression opcode */ Expr *pLeft, /* Left operand */ Expr *pRight, /* Right operand */ const Token *pToken /* Argument token */ ){ | | < < < < | | < | | 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 | Expr *sqlite3PExpr( Parse *pParse, /* Parsing context */ int op, /* Expression opcode */ Expr *pLeft, /* Left operand */ Expr *pRight, /* Right operand */ const Token *pToken /* Argument token */ ){ return sqlite3Expr(pParse->db, op, pLeft, pRight, pToken); } /* ** When doing a nested parse, you can include terms in an expression ** that look like this: #0 #1 #2 ... These terms refer to elements ** on the stack. "#0" means the top of the stack. ** "#1" means the next down on the stack. And so forth. ** ** This routine is called by the parser to deal with on of those terms. ** It immediately generates code to store the value in a memory location. ** The returns an expression that will code to extract the value from ** that memory location as needed. */ Expr *sqlite3RegisterExpr(Parse *pParse, Token *pToken){ Vdbe *v = pParse->pVdbe; Expr *p; int depth; if( pParse->nested==0 ){ sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", pToken); return sqlite3PExpr(pParse, TK_NULL, 0, 0, 0); } if( v==0 ) return 0; p = sqlite3PExpr(pParse, TK_REGISTER, 0, 0, pToken); if( p==0 ){ return 0; /* Malloc failed */ } depth = atoi((char*)&pToken->z[1]); p->iTable = pParse->nMem++; sqlite3VdbeAddOp(v, OP_Dup, depth, 0); sqlite3VdbeAddOp(v, OP_MemStore, p->iTable, 1); return p; } /* ** Join two expressions using an AND operator. If either expression is ** NULL, then just return the other expression. */ Expr *sqlite3ExprAnd(sqlite3 *db, Expr *pLeft, Expr *pRight){ if( pLeft==0 ){ return pRight; }else if( pRight==0 ){ return pLeft; }else{ Expr *p = sqlite3Expr(db, TK_AND, pLeft, pRight, 0); if( p==0 ){ db->mallocFailed = 1; } return p; } } |
︙ | ︙ | |||
1230 1231 1232 1233 1234 1235 1236 | if( zDb ){ sqlite3SetString(&z, zDb, ".", zTab, ".", zCol, (char*)0); }else if( zTab ){ sqlite3SetString(&z, zTab, ".", zCol, (char*)0); }else{ z = sqlite3StrDup(zCol); } | > | | | > > > | 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 | if( zDb ){ sqlite3SetString(&z, zDb, ".", zTab, ".", zCol, (char*)0); }else if( zTab ){ sqlite3SetString(&z, zTab, ".", zCol, (char*)0); }else{ z = sqlite3StrDup(zCol); } if( z ){ sqlite3ErrorMsg(pParse, zErr, z); sqlite3_free(z); pTopNC->nErr++; }else{ db->mallocFailed = 1; } } /* If a column from a table in pSrcList is referenced, then record ** this fact in the pSrcList.a[].colUsed bitmask. Column 0 causes ** bit 0 to be set. Column 1 sets bit 1. And so forth. If the ** column number is greater than the number of bits in the bitmask ** then set the high-order bit of the bitmask. |
︙ | ︙ | |||
1664 1665 1666 1667 1668 1669 1670 | VdbeComment((v, "# Init subquery result")); }else{ sop = SRT_Exists; sqlite3VdbeAddOp(v, OP_MemInt, 0, iMem); VdbeComment((v, "# Init EXISTS result")); } sqlite3ExprDelete(pSel->pLimit); | | | 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 | VdbeComment((v, "# Init subquery result")); }else{ sop = SRT_Exists; sqlite3VdbeAddOp(v, OP_MemInt, 0, iMem); VdbeComment((v, "# Init EXISTS result")); } sqlite3ExprDelete(pSel->pLimit); pSel->pLimit = sqlite3PExpr(pParse, TK_INTEGER, 0, 0, &one); if( sqlite3Select(pParse, pSel, sop, iMem, 0, 0, 0, 0) ){ return; } break; } } |
︙ | ︙ |
Changes to src/func.c.
︙ | ︙ | |||
12 13 14 15 16 17 18 | ** This file contains the C functions that implement various SQL ** functions of SQLite. ** ** There is only one exported symbol in this file - the function ** sqliteRegisterBuildinFunctions() found at the bottom of the file. ** All other code has file scope. ** | | | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | ** This file contains the C functions that implement various SQL ** functions of SQLite. ** ** There is only one exported symbol in this file - the function ** sqliteRegisterBuildinFunctions() found at the bottom of the file. ** All other code has file scope. ** ** $Id: func.c,v 1.170 2007/08/29 12:31:26 danielk1977 Exp $ */ #include "sqliteInt.h" #include <ctype.h> #include <stdlib.h> #include <assert.h> #include "vdbeInt.h" |
︙ | ︙ | |||
229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 | } if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return; r = sqlite3_value_double(argv[0]); sqlite3_snprintf(sizeof(zBuf),zBuf,"%.*f",n,r); sqlite3AtoF(zBuf, &r); sqlite3_result_double(context, r); } /* ** Implementation of the upper() and lower() SQL functions. */ static void upperFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ char *z1; const char *z2; int i, n; if( argc<1 || SQLITE_NULL==sqlite3_value_type(argv[0]) ) return; z2 = (char*)sqlite3_value_text(argv[0]); n = sqlite3_value_bytes(argv[0]); /* Verify that the call to _bytes() does not invalidate the _text() pointer */ assert( z2==(char*)sqlite3_value_text(argv[0]) ); if( z2 ){ | > > > > > > > > | | | 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 | } if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return; r = sqlite3_value_double(argv[0]); sqlite3_snprintf(sizeof(zBuf),zBuf,"%.*f",n,r); sqlite3AtoF(zBuf, &r); sqlite3_result_double(context, r); } static void *contextMalloc(sqlite3_context *context, int nByte){ char *z = sqlite3_malloc(nByte); if( !z && nByte>0 ){ sqlite3_result_error_nomem(context); } return z; } /* ** Implementation of the upper() and lower() SQL functions. */ static void upperFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ char *z1; const char *z2; int i, n; if( argc<1 || SQLITE_NULL==sqlite3_value_type(argv[0]) ) return; z2 = (char*)sqlite3_value_text(argv[0]); n = sqlite3_value_bytes(argv[0]); /* Verify that the call to _bytes() does not invalidate the _text() pointer */ assert( z2==(char*)sqlite3_value_text(argv[0]) ); if( z2 ){ z1 = contextMalloc(context, n+1); if( z1 ){ memcpy(z1, z2, n+1); for(i=0; z1[i]; i++){ z1[i] = toupper(z1[i]); } sqlite3_result_text(context, z1, -1, sqlite3_free); } } } static void lowerFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ char *z1; const char *z2; int i, n; if( argc<1 || SQLITE_NULL==sqlite3_value_type(argv[0]) ) return; z2 = (char*)sqlite3_value_text(argv[0]); n = sqlite3_value_bytes(argv[0]); /* Verify that the call to _bytes() does not invalidate the _text() pointer */ assert( z2==(char*)sqlite3_value_text(argv[0]) ); if( z2 ){ z1 = contextMalloc(context, n+1); if( z1 ){ memcpy(z1, z2, n+1); for(i=0; z1[i]; i++){ z1[i] = tolower(z1[i]); } sqlite3_result_text(context, z1, -1, sqlite3_free); } |
︙ | ︙ | |||
328 329 330 331 332 333 334 | if( n<1 ){ n = 1; } if( n>SQLITE_MAX_LENGTH ){ sqlite3_result_error_toobig(context); return; } | | | 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 | if( n<1 ){ n = 1; } if( n>SQLITE_MAX_LENGTH ){ sqlite3_result_error_toobig(context); return; } p = contextMalloc(context, n); if( p ){ sqlite3Randomness(n, p); sqlite3_result_blob(context, (char*)p, n, sqlite3_free); } } /* |
︙ | ︙ | |||
661 662 663 664 665 666 667 | int nBlob = sqlite3_value_bytes(argv[0]); assert( zBlob==sqlite3_value_blob(argv[0]) ); /* No encoding change */ if( 2*nBlob+4>SQLITE_MAX_LENGTH ){ sqlite3_result_error_toobig(context); return; } | | | < < | 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 | int nBlob = sqlite3_value_bytes(argv[0]); assert( zBlob==sqlite3_value_blob(argv[0]) ); /* No encoding change */ if( 2*nBlob+4>SQLITE_MAX_LENGTH ){ sqlite3_result_error_toobig(context); return; } zText = (char *)contextMalloc(context, (2*nBlob)+4); if( zText ){ int i; for(i=0; i<nBlob; i++){ zText[(i*2)+2] = hexdigits[(zBlob[i]>>4)&0x0F]; zText[(i*2)+3] = hexdigits[(zBlob[i])&0x0F]; } zText[(nBlob*2)+2] = '\''; zText[(nBlob*2)+3] = '\0'; |
︙ | ︙ | |||
691 692 693 694 695 696 697 | if( zArg==0 ) return; for(i=0, n=0; zArg[i]; i++){ if( zArg[i]=='\'' ) n++; } if( i+n+3>SQLITE_MAX_LENGTH ){ sqlite3_result_error_toobig(context); return; } | | | | | | | | | | | | | < > | 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 | if( zArg==0 ) return; for(i=0, n=0; zArg[i]; i++){ if( zArg[i]=='\'' ) n++; } if( i+n+3>SQLITE_MAX_LENGTH ){ sqlite3_result_error_toobig(context); return; } z = contextMalloc(context, i+n+3); if( z ){ z[0] = '\''; for(i=0, j=1; zArg[i]; i++){ z[j++] = zArg[i]; if( zArg[i]=='\'' ){ z[j++] = '\''; } } z[j++] = '\''; z[j] = 0; sqlite3_result_text(context, z, j, sqlite3_free); } } } } /* ** The hex() function. Interpret the argument as a blob. Return ** a hexadecimal rendering as text. |
︙ | ︙ | |||
728 729 730 731 732 733 734 | pBlob = sqlite3_value_blob(argv[0]); n = sqlite3_value_bytes(argv[0]); if( n*2+1>SQLITE_MAX_LENGTH ){ sqlite3_result_error_toobig(context); return; } assert( pBlob==sqlite3_value_blob(argv[0]) ); /* No encoding change */ | | | | | | | | | | > | 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 | pBlob = sqlite3_value_blob(argv[0]); n = sqlite3_value_bytes(argv[0]); if( n*2+1>SQLITE_MAX_LENGTH ){ sqlite3_result_error_toobig(context); return; } assert( pBlob==sqlite3_value_blob(argv[0]) ); /* No encoding change */ z = zHex = contextMalloc(context, n*2 + 1); if( zHex ){ for(i=0; i<n; i++, pBlob++){ unsigned char c = *pBlob; *(z++) = hexdigits[(c>>4)&0xf]; *(z++) = hexdigits[c&0xf]; } *z = 0; sqlite3_result_text(context, zHex, n*2, sqlite3_free); } } /* ** The zeroblob(N) function returns a zero-filled blob of size N bytes. */ static void zeroblobFunc( sqlite3_context *context, |
︙ | ︙ | |||
794 795 796 797 798 799 800 | assert( zPattern==sqlite3_value_text(argv[1]) ); /* No encoding change */ zRep = sqlite3_value_text(argv[2]); if( zRep==0 ) return; nRep = sqlite3_value_bytes(argv[2]); assert( zRep==sqlite3_value_text(argv[2]) ); nOut = nStr + 1; assert( nOut<SQLITE_MAX_LENGTH ); | | > | 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 | assert( zPattern==sqlite3_value_text(argv[1]) ); /* No encoding change */ zRep = sqlite3_value_text(argv[2]); if( zRep==0 ) return; nRep = sqlite3_value_bytes(argv[2]); assert( zRep==sqlite3_value_text(argv[2]) ); nOut = nStr + 1; assert( nOut<SQLITE_MAX_LENGTH ); zOut = contextMalloc(context, (int)nOut); if( zOut==0 ){ return; } loopLimit = nStr - nPattern; for(i=j=0; i<=loopLimit; i++){ if( zStr[i]!=zPattern[0] || memcmp(&zStr[i], zPattern, nPattern) ){ zOut[j++] = zStr[i]; }else{ u8 *zOld; nOut += nRep - nPattern; if( nOut>=SQLITE_MAX_LENGTH ){ sqlite3_result_error_toobig(context); sqlite3_free(zOut); return; } zOld = zOut; zOut = sqlite3_realloc(zOut, (int)nOut); if( zOut==0 ){ sqlite3_result_error_nomem(context); sqlite3_free(zOld); return; } memcpy(&zOut[j], zRep, nRep); j += nRep; i += nPattern-1; } |
︙ | ︙ | |||
869 870 871 872 873 874 875 | return; }else{ const unsigned char *z; for(z=zCharSet, nChar=0; *z; nChar++){ SQLITE_SKIP_UTF8(z); } if( nChar>0 ){ | | | 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 | return; }else{ const unsigned char *z; for(z=zCharSet, nChar=0; *z; nChar++){ SQLITE_SKIP_UTF8(z); } if( nChar>0 ){ azChar = contextMalloc(context, nChar*(sizeof(char*)+1)); if( azChar==0 ){ return; } aLen = (unsigned char*)&azChar[nChar]; for(z=zCharSet, nChar=0; *z; nChar++){ azChar[nChar] = z; SQLITE_SKIP_UTF8(z); |
︙ | ︙ | |||
1106 1107 1108 1109 1110 1111 1112 | static void free_test_auxdata(void *p) {sqlite3_free(p);} static void test_auxdata( sqlite3_context *pCtx, int nArg, sqlite3_value **argv ){ int i; | | > > | > | > | 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 | static void free_test_auxdata(void *p) {sqlite3_free(p);} static void test_auxdata( sqlite3_context *pCtx, int nArg, sqlite3_value **argv ){ int i; char *zRet = contextMalloc(pCtx, nArg*2); if( !zRet ) return; memset(zRet, 0, nArg*2); for(i=0; i<nArg; i++){ char const *z = (char*)sqlite3_value_text(argv[i]); if( z ){ char *zAux = sqlite3_get_auxdata(pCtx, i); if( zAux ){ zRet[i*2] = '1'; if( strcmp(zAux, z) ){ free_test_auxdata((void *)zRet); sqlite3_result_error(pCtx, "Auxilary data corruption", -1); return; } }else{ zRet[i*2] = '0'; zAux = contextMalloc(pCtx, strlen(z)+1); if( zAux ){ strcpy(zAux, z); sqlite3_set_auxdata(pCtx, i, zAux, free_test_auxdata); } } zRet[i*2+1] = ' '; } } sqlite3_result_text(pCtx, zRet, 2*nArg-1, free_test_auxdata); } #endif /* SQLITE_TEST */ |
︙ | ︙ |
Changes to src/hash.c.
︙ | ︙ | |||
8 9 10 11 12 13 14 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This is the implementation of generic hash-tables ** used in SQLite. ** | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This is the implementation of generic hash-tables ** used in SQLite. ** ** $Id: hash.c,v 1.22 2007/08/29 12:31:26 danielk1977 Exp $ */ #include "sqliteInt.h" #include <assert.h> /* Turn bulk memory into a hash table object by initializing the ** fields of the Hash structure. ** |
︙ | ︙ | |||
218 219 220 221 222 223 224 225 226 227 228 229 230 231 | */ static void rehash(Hash *pH, int new_size){ struct _ht *new_ht; /* The new hash table */ HashElem *elem, *next_elem; /* For looping over existing elements */ int (*xHash)(const void*,int); /* The hash function */ assert( (new_size & (new_size-1))==0 ); new_ht = (struct _ht *)sqlite3MallocZero( new_size*sizeof(struct _ht) ); if( new_ht==0 ) return; if( pH->ht ) sqlite3_free(pH->ht); pH->ht = new_ht; pH->htsize = new_size; xHash = hashFunction(pH->keyClass); for(elem=pH->first, pH->first=0; elem; elem = next_elem){ | > > > > > > > > | 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 | */ static void rehash(Hash *pH, int new_size){ struct _ht *new_ht; /* The new hash table */ HashElem *elem, *next_elem; /* For looping over existing elements */ int (*xHash)(const void*,int); /* The hash function */ assert( (new_size & (new_size-1))==0 ); /* There is a call to sqlite3_malloc() inside rehash(). If there is ** already an allocation at pH->ht, then if this malloc() fails it ** is benign (since failing to resize a hash table is a performance ** hit only, not a fatal error). */ sqlite3MallocBenignFailure(pH->htsize>0); new_ht = (struct _ht *)sqlite3MallocZero( new_size*sizeof(struct _ht) ); if( new_ht==0 ) return; if( pH->ht ) sqlite3_free(pH->ht); pH->ht = new_ht; pH->htsize = new_size; xHash = hashFunction(pH->keyClass); for(elem=pH->first, pH->first=0; elem; elem = next_elem){ |
︙ | ︙ |
Changes to src/legacy.c.
︙ | ︙ | |||
10 11 12 13 14 15 16 | ** ************************************************************************* ** Main file for the SQLite library. The routines in this file ** implement the programmer interface to the library. Routines in ** other files are for internal use by SQLite and should not be ** accessed by users of the library. ** | | | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | ** ************************************************************************* ** Main file for the SQLite library. The routines in this file ** implement the programmer interface to the library. Routines in ** other files are for internal use by SQLite and should not be ** accessed by users of the library. ** ** $Id: legacy.c,v 1.22 2007/08/29 12:31:26 danielk1977 Exp $ */ #include "sqliteInt.h" #include <ctype.h> /* ** Execute SQL code. Return one of the SQLITE_ success/failure |
︙ | ︙ | |||
42 43 44 45 46 47 48 49 50 51 52 53 54 55 | sqlite3_stmt *pStmt = 0; char **azCols = 0; int nRetry = 0; int nCallback; if( zSql==0 ) return SQLITE_OK; while( (rc==SQLITE_OK || (rc==SQLITE_SCHEMA && (++nRetry)<2)) && zSql[0] ){ int nCol; char **azVals = 0; pStmt = 0; rc = sqlite3_prepare(db, zSql, -1, &pStmt, &zLeftover); assert( rc==SQLITE_OK || pStmt==0 ); | > > | 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | sqlite3_stmt *pStmt = 0; char **azCols = 0; int nRetry = 0; int nCallback; if( zSql==0 ) return SQLITE_OK; sqlite3_mutex_enter(db->mutex); while( (rc==SQLITE_OK || (rc==SQLITE_SCHEMA && (++nRetry)<2)) && zSql[0] ){ int nCol; char **azVals = 0; pStmt = 0; rc = sqlite3_prepare(db, zSql, -1, &pStmt, &zLeftover); assert( rc==SQLITE_OK || pStmt==0 ); |
︙ | ︙ | |||
123 124 125 126 127 128 129 130 131 | memcpy(*pzErrMsg, sqlite3_errmsg(db), nErrMsg); } }else if( pzErrMsg ){ *pzErrMsg = 0; } assert( (rc&db->errMask)==rc ); return rc; } | > | 125 126 127 128 129 130 131 132 133 134 | memcpy(*pzErrMsg, sqlite3_errmsg(db), nErrMsg); } }else if( pzErrMsg ){ *pzErrMsg = 0; } assert( (rc&db->errMask)==rc ); sqlite3_mutex_leave(db->mutex); return rc; } |
Changes to src/malloc.c.
︙ | ︙ | |||
8 9 10 11 12 13 14 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** Memory allocation functions used throughout sqlite. ** ** | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** Memory allocation functions used throughout sqlite. ** ** ** $Id: malloc.c,v 1.12 2007/08/29 12:31:26 danielk1977 Exp $ */ #include "sqliteInt.h" #include <stdarg.h> #include <ctype.h> /* ** This routine runs when the memory allocator sees that the |
︙ | ︙ | |||
78 79 80 81 82 83 84 | } /* ** Allocate and zero memory. If the allocation fails, make ** the mallocFailed flag in the connection pointer. */ void *sqlite3DbMallocZero(sqlite3 *db, unsigned n){ | | < < > > | | | > > > > > > > > > > > > | < < | 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 | } /* ** Allocate and zero memory. If the allocation fails, make ** the mallocFailed flag in the connection pointer. */ void *sqlite3DbMallocZero(sqlite3 *db, unsigned n){ void *p = sqlite3DbMallocRaw(db, n); if( p ){ memset(p, 0, n); } return p; } /* ** Allocate and zero memory. If the allocation fails, make ** the mallocFailed flag in the connection pointer. */ void *sqlite3DbMallocRaw(sqlite3 *db, unsigned n){ void *p = 0; if( !db || db->mallocFailed==0 ){ p = sqlite3_malloc(n); if( !p && db ){ db->mallocFailed = 1; } } return p; } void *sqlite3DbRealloc(sqlite3 *db, void *p, int n){ void *pNew = 0; if( db->mallocFailed==0 ){ pNew = sqlite3_realloc(p, n); if( !pNew ){ db->mallocFailed = 1; } } return pNew; } /* ** Attempt to reallocate p. If the reallocation fails, then free p ** and set the mallocFailed flag in the database connection. */ void *sqlite3DbReallocOrFree(sqlite3 *db, void *p, int n){ void *pNew; pNew = sqlite3DbRealloc(db, p, n); if( !pNew ){ sqlite3_free(p); } return pNew; } /* ** Make a copy of a string in memory obtained from sqliteMalloc(). These ** functions call sqlite3MallocRaw() directly instead of sqliteMalloc(). This ** is because when memory debugging is turned on, these two functions are ** called via macros that record the current file and line number in the ** ThreadData structure. |
︙ | ︙ | |||
207 208 209 210 211 212 213 214 215 216 217 218 219 220 | ** invocation SQLITE_NOMEM is returned instead. ** ** If the first argument, db, is not NULL and a malloc() error has occured, ** then the connection error-code (the value returned by sqlite3_errcode()) ** is set to SQLITE_NOMEM. */ int sqlite3ApiExit(sqlite3* db, int rc){ if( db && db->mallocFailed ){ sqlite3Error(db, SQLITE_NOMEM, 0); db->mallocFailed = 0; rc = SQLITE_NOMEM; } return rc & (db ? db->errMask : 0xff); } | > > > > > > | 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 | ** invocation SQLITE_NOMEM is returned instead. ** ** If the first argument, db, is not NULL and a malloc() error has occured, ** then the connection error-code (the value returned by sqlite3_errcode()) ** is set to SQLITE_NOMEM. */ int sqlite3ApiExit(sqlite3* db, int rc){ /* If the db handle is not NULL, then we must hold the connection handle ** mutex here. Otherwise the read (and possible write) of db->mallocFailed ** is unsafe, as is the call to sqlite3Error(). */ assert( !db || sqlite3_mutex_held(db->mutex) ); if( db && db->mallocFailed ){ sqlite3Error(db, SQLITE_NOMEM, 0); db->mallocFailed = 0; rc = SQLITE_NOMEM; } return rc & (db ? db->errMask : 0xff); } |
Changes to src/mem2.c.
︙ | ︙ | |||
8 9 10 11 12 13 14 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains the C functions that implement a memory ** allocation subsystem for use by SQLite. ** | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains the C functions that implement a memory ** allocation subsystem for use by SQLite. ** ** $Id: mem2.c,v 1.11 2007/08/29 12:31:26 danielk1977 Exp $ */ /* ** This version of the memory allocator is used only if the ** SQLITE_MEMDEBUG macro is defined and SQLITE_OMIT_MEMORY_ALLOCATION ** is not defined. */ |
︙ | ︙ | |||
134 135 136 137 138 139 140 | /* ** These values are used to simulate malloc failures. When ** iFail is 1, simulate a malloc failures and reset the value ** to iReset. */ int iFail; /* Decrement and fail malloc when this is 1 */ int iReset; /* When malloc fails set iiFail to this value */ | | > > | 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 | /* ** These values are used to simulate malloc failures. When ** iFail is 1, simulate a malloc failures and reset the value ** to iReset. */ int iFail; /* Decrement and fail malloc when this is 1 */ int iReset; /* When malloc fails set iiFail to this value */ int iFailCnt; /* Number of failures */ int iBenignFailCnt; /* Number of benign failures */ int iNextIsBenign; /* True if the next call to malloc may fail benignly */ /* ** sqlite3MallocDisallow() increments the following counter. ** sqlite3MallocAllow() decrements it. */ int disallow; /* Do not allow memory allocation */ |
︙ | ︙ | |||
243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 | ** This routine is called once the first time a simulated memory ** failure occurs. The sole purpose of this routine is to provide ** a convenient place to set a debugger breakpoint when debugging ** errors related to malloc() failures. */ static void sqlite3MemsysFailed(void){ mem.iFailCnt = 0; } /* ** Allocate nByte bytes of memory. */ void *sqlite3_malloc(int nByte){ struct MemBlockHdr *pHdr; void **pBt; char *z; int *pInt; void *p; int totalSize; if( nByte<=0 ){ return 0; } if( mem.mutex==0 ){ mem.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM); } sqlite3_mutex_enter(mem.mutex); assert( mem.disallow==0 ); | > > | 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 | ** This routine is called once the first time a simulated memory ** failure occurs. The sole purpose of this routine is to provide ** a convenient place to set a debugger breakpoint when debugging ** errors related to malloc() failures. */ static void sqlite3MemsysFailed(void){ mem.iFailCnt = 0; mem.iBenignFailCnt = 0; } /* ** Allocate nByte bytes of memory. */ void *sqlite3_malloc(int nByte){ struct MemBlockHdr *pHdr; void **pBt; char *z; int *pInt; void *p; int totalSize; if( nByte<=0 ){ mem.iNextIsBenign = 0; return 0; } if( mem.mutex==0 ){ mem.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM); } sqlite3_mutex_enter(mem.mutex); assert( mem.disallow==0 ); |
︙ | ︙ | |||
278 279 280 281 282 283 284 285 286 287 288 289 290 291 | if( mem.iFail==1 ){ p = 0; mem.iFail = mem.iReset; if( mem.iFailCnt==0 ){ sqlite3MemsysFailed(); /* A place to set a breakpoint */ } mem.iFailCnt++; }else{ p = malloc(totalSize); mem.iFail--; } }else{ p = malloc(totalSize); if( p==0 ){ | > > > | 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 | if( mem.iFail==1 ){ p = 0; mem.iFail = mem.iReset; if( mem.iFailCnt==0 ){ sqlite3MemsysFailed(); /* A place to set a breakpoint */ } mem.iFailCnt++; if( mem.iNextIsBenign ){ mem.iBenignFailCnt++; } }else{ p = malloc(totalSize); mem.iFail--; } }else{ p = malloc(totalSize); if( p==0 ){ |
︙ | ︙ | |||
325 326 327 328 329 330 331 332 333 334 335 336 337 338 | mem.nowUsed += nByte; if( mem.nowUsed>mem.mxUsed ){ mem.mxUsed = mem.nowUsed; } p = (void*)pInt; } sqlite3_mutex_leave(mem.mutex); return p; } /* ** Free memory. */ void sqlite3_free(void *pPrior){ | > | 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 | mem.nowUsed += nByte; if( mem.nowUsed>mem.mxUsed ){ mem.mxUsed = mem.nowUsed; } p = (void*)pInt; } sqlite3_mutex_leave(mem.mutex); mem.iNextIsBenign = 0; return p; } /* ** Free memory. */ void sqlite3_free(void *pPrior){ |
︙ | ︙ | |||
471 472 473 474 475 476 477 | ** ** Each call to this routine overrides the previous. To disable ** the simulated allocation failure mechanism, set iFail to -1. ** ** This routine returns the number of simulated failures that have ** occurred since the previous call. */ | | > > > > > > > > > > | 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 | ** ** Each call to this routine overrides the previous. To disable ** the simulated allocation failure mechanism, set iFail to -1. ** ** This routine returns the number of simulated failures that have ** occurred since the previous call. */ int sqlite3_memdebug_fail(int iFail, int iRepeat, int *piBenign){ int n = mem.iFailCnt; if( piBenign ){ *piBenign = mem.iBenignFailCnt; } mem.iFail = iFail+1; if( iRepeat>=0 ){ mem.iReset = iRepeat; } mem.iFailCnt = 0; mem.iBenignFailCnt = 0; return n; } void sqlite3MallocBenignFailure(int isBenign){ if( isBenign ){ mem.iNextIsBenign = 1; } } /* ** The following two routines are used to assert that no memory ** allocations occur between one call and the next. The use of ** these routines does not change the computed results in any way. ** These routines are like asserts. */ |
︙ | ︙ |
Changes to src/pager.c.
︙ | ︙ | |||
14 15 16 17 18 19 20 | ** The pager is used to access a database disk file. It implements ** atomic commit and rollback through the use of a journal file that ** is separate from the database file. The pager also implements file ** locking to prevent two processes from writing the same database ** file simultaneously, or one process from reading the database while ** another is writing. ** | | | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | ** The pager is used to access a database disk file. It implements ** atomic commit and rollback through the use of a journal file that ** is separate from the database file. The pager also implements file ** locking to prevent two processes from writing the same database ** file simultaneously, or one process from reading the database while ** another is writing. ** ** @(#) $Id: pager.c,v 1.380 2007/08/29 12:31:27 danielk1977 Exp $ */ #ifndef SQLITE_OMIT_DISKIO #include "sqliteInt.h" #include <assert.h> #include <string.h> /* |
︙ | ︙ | |||
695 696 697 698 699 700 701 702 703 704 705 706 707 708 | ** Change the size of the pager hash table to N. N must be a power ** of two. */ static void pager_resize_hash_table(Pager *pPager, int N){ PgHdr **aHash, *pPg; assert( N>0 && (N&(N-1))==0 ); pagerLeave(pPager); aHash = sqlite3MallocZero( sizeof(aHash[0])*N ); pagerEnter(pPager); if( aHash==0 ){ /* Failure to rehash is not an error. It is only a performance hit. */ return; } sqlite3_free(pPager->aHash); | > | 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 | ** Change the size of the pager hash table to N. N must be a power ** of two. */ static void pager_resize_hash_table(Pager *pPager, int N){ PgHdr **aHash, *pPg; assert( N>0 && (N&(N-1))==0 ); pagerLeave(pPager); sqlite3MallocBenignFailure((int)pPager->aHash); aHash = sqlite3MallocZero( sizeof(aHash[0])*N ); pagerEnter(pPager); if( aHash==0 ){ /* Failure to rehash is not an error. It is only a performance hit. */ return; } sqlite3_free(pPager->aHash); |
︙ | ︙ | |||
2262 2263 2264 2265 2266 2267 2268 | ** page data. */ void sqlite3PagerSetReiniter(Pager *pPager, void (*xReinit)(DbPage*,int)){ pPager->xReiniter = xReinit; } /* | | | | | > > > | > > > > > | | | | < | | > | > | > | 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 | ** page data. */ void sqlite3PagerSetReiniter(Pager *pPager, void (*xReinit)(DbPage*,int)){ pPager->xReiniter = xReinit; } /* ** Set the page size to *pPageSize. If the suggest new page size is ** inappropriate, then an alternative page size is set to that ** value before returning. */ int sqlite3PagerSetPagesize(Pager *pPager, u16 *pPageSize){ int rc = SQLITE_OK; u16 pageSize = *pPageSize; assert( pageSize==0 || (pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE) ); if( pageSize && pageSize!=pPager->pageSize && !pPager->memDb && pPager->nRef==0 ){ char *pNew = (char *)sqlite3_malloc(pageSize); if( !pNew ){ rc = SQLITE_NOMEM; }else{ pagerEnter(pPager); pager_reset(pPager); pPager->pageSize = pageSize; setSectorSize(pPager); sqlite3_free(pPager->pTmpSpace); pPager->pTmpSpace = pNew; pagerLeave(pPager); } } *pPageSize = pPager->pageSize; return rc; } /* ** Attempt to set the maximum database page count if mxPage is positive. ** Make no changes if mxPage is zero or negative. And never reduce the ** maximum page count below the current size of the database. ** |
︙ | ︙ | |||
3263 3264 3265 3266 3267 3268 3269 | ** a read/write file handle. */ rc = SQLITE_BUSY; if( sqlite3OsAccess(pVfs, pPager->zJournal, SQLITE_ACCESS_EXISTS) ){ int fout = 0; int flags = SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_JOURNAL; assert( !pPager->tempFile ); | | | | 3274 3275 3276 3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293 3294 3295 3296 3297 | ** a read/write file handle. */ rc = SQLITE_BUSY; if( sqlite3OsAccess(pVfs, pPager->zJournal, SQLITE_ACCESS_EXISTS) ){ int fout = 0; int flags = SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_JOURNAL; assert( !pPager->tempFile ); rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, flags, &fout); assert( rc!=SQLITE_OK || pPager->jfd->pMethods ); if( fout&SQLITE_OPEN_READONLY ){ rc = SQLITE_BUSY; sqlite3OsClose(pPager->jfd); } } if( rc!=SQLITE_OK ){ pager_unlock(pPager); return (rc==SQLITE_NOMEM?rc:SQLITE_BUSY); } pPager->journalOpen = 1; pPager->journalStarted = 0; pPager->journalOff = 0; pPager->setMaster = 0; pPager->journalHdr = 0; |
︙ | ︙ |
Changes to src/pager.h.
︙ | ︙ | |||
9 10 11 12 13 14 15 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** This header file defines the interface that the sqlite page cache ** subsystem. The page cache subsystem reads and writes a file a page ** at a time and provides a journal for rollback. ** | | | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** This header file defines the interface that the sqlite page cache ** subsystem. The page cache subsystem reads and writes a file a page ** at a time and provides a journal for rollback. ** ** @(#) $Id: pager.h,v 1.64 2007/08/29 12:31:27 danielk1977 Exp $ */ #ifndef _PAGER_H_ #define _PAGER_H_ /* ** The type used to represent a page number. The first page in a file |
︙ | ︙ | |||
54 55 56 57 58 59 60 | ** See source code comments for a detailed description of the following ** routines: */ int sqlite3PagerOpen(sqlite3_vfs *, Pager **ppPager, const char *, int, int); void sqlite3PagerSetBusyhandler(Pager*, BusyHandler *pBusyHandler); void sqlite3PagerSetDestructor(Pager*, void(*)(DbPage*,int)); void sqlite3PagerSetReiniter(Pager*, void(*)(DbPage*,int)); | | | 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | ** See source code comments for a detailed description of the following ** routines: */ int sqlite3PagerOpen(sqlite3_vfs *, Pager **ppPager, const char *, int, int); void sqlite3PagerSetBusyhandler(Pager*, BusyHandler *pBusyHandler); void sqlite3PagerSetDestructor(Pager*, void(*)(DbPage*,int)); void sqlite3PagerSetReiniter(Pager*, void(*)(DbPage*,int)); int sqlite3PagerSetPagesize(Pager*, u16*); int sqlite3PagerMaxPageCount(Pager*, int); int sqlite3PagerReadFileheader(Pager*, int, unsigned char*); void sqlite3PagerSetCachesize(Pager*, int); int sqlite3PagerClose(Pager *pPager); int sqlite3PagerAcquire(Pager *pPager, Pgno pgno, DbPage **ppPage, int clrFlag); #define sqlite3PagerGet(A,B,C) sqlite3PagerAcquire(A,B,C,0) DbPage *sqlite3PagerLookup(Pager *pPager, Pgno pgno); |
︙ | ︙ |
Changes to src/prepare.c.
︙ | ︙ | |||
9 10 11 12 13 14 15 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains the implementation of the sqlite3_prepare() ** interface, and routines that contribute to loading the database schema ** from disk. ** | | | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains the implementation of the sqlite3_prepare() ** interface, and routines that contribute to loading the database schema ** from disk. ** ** $Id: prepare.c,v 1.60 2007/08/29 12:31:27 danielk1977 Exp $ */ #include "sqliteInt.h" #include <ctype.h> /* ** Fill the InitData structure with an error message that indicates ** that the database is corrupt. |
︙ | ︙ | |||
178 179 180 181 182 183 184 | azArg[3] = 0; initData.db = db; initData.iDb = iDb; initData.pzErrMsg = pzErrMsg; rc = sqlite3InitCallback(&initData, 3, (char **)azArg, 0); if( rc ){ sqlite3SafetyOn(db); | | > | 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 | azArg[3] = 0; initData.db = db; initData.iDb = iDb; initData.pzErrMsg = pzErrMsg; rc = sqlite3InitCallback(&initData, 3, (char **)azArg, 0); if( rc ){ sqlite3SafetyOn(db); rc = initData.rc; goto error_out; } pTab = sqlite3FindTable(db, zMasterName, db->aDb[iDb].zName); if( pTab ){ pTab->readOnly = 1; } sqlite3SafetyOn(db); |
︙ | ︙ | |||
200 201 202 203 204 205 206 | return SQLITE_OK; } sqlite3BtreeEnter(pDb->pBt); rc = sqlite3BtreeCursor(pDb->pBt, MASTER_ROOT, 0, 0, 0, &curMain); if( rc!=SQLITE_OK && rc!=SQLITE_EMPTY ){ sqlite3SetString(pzErrMsg, sqlite3ErrStr(rc), (char*)0); sqlite3BtreeLeave(pDb->pBt); | | | 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 | return SQLITE_OK; } sqlite3BtreeEnter(pDb->pBt); rc = sqlite3BtreeCursor(pDb->pBt, MASTER_ROOT, 0, 0, 0, &curMain); if( rc!=SQLITE_OK && rc!=SQLITE_EMPTY ){ sqlite3SetString(pzErrMsg, sqlite3ErrStr(rc), (char*)0); sqlite3BtreeLeave(pDb->pBt); goto error_out; } /* Get the database meta information. ** ** Meta values are as follows: ** meta[0] Schema cookie. Changes with each schema change. ** meta[1] File format of schema layer. |
︙ | ︙ | |||
229 230 231 232 233 234 235 | for(i=0; rc==SQLITE_OK && i<sizeof(meta)/sizeof(meta[0]); i++){ rc = sqlite3BtreeGetMeta(pDb->pBt, i+1, (u32 *)&meta[i]); } if( rc ){ sqlite3SetString(pzErrMsg, sqlite3ErrStr(rc), (char*)0); sqlite3BtreeCloseCursor(curMain); sqlite3BtreeLeave(pDb->pBt); | | | 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 | for(i=0; rc==SQLITE_OK && i<sizeof(meta)/sizeof(meta[0]); i++){ rc = sqlite3BtreeGetMeta(pDb->pBt, i+1, (u32 *)&meta[i]); } if( rc ){ sqlite3SetString(pzErrMsg, sqlite3ErrStr(rc), (char*)0); sqlite3BtreeCloseCursor(curMain); sqlite3BtreeLeave(pDb->pBt); goto error_out; } }else{ memset(meta, 0, sizeof(meta)); } pDb->pSchema->schema_cookie = meta[0]; /* If opening a non-empty database, check the text encoding. For the |
︙ | ︙ | |||
325 326 327 328 329 330 331 332 333 334 335 336 337 338 | ** purpose of this is to allow access to the sqlite_master table ** even when it's contents have been corrupted. */ DbSetProperty(db, iDb, DB_SchemaLoaded); rc = SQLITE_OK; } sqlite3BtreeLeave(pDb->pBt); return rc; } /* ** Initialize all database files - the main database file, the file ** used to store temporary tables, and any additional database files ** created using ATTACH statements. Return a success code. If an | > > > > > | 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 | ** purpose of this is to allow access to the sqlite_master table ** even when it's contents have been corrupted. */ DbSetProperty(db, iDb, DB_SchemaLoaded); rc = SQLITE_OK; } sqlite3BtreeLeave(pDb->pBt); error_out: if( rc==SQLITE_NOMEM ){ db->mallocFailed = 1; } return rc; } /* ** Initialize all database files - the main database file, the file ** used to store temporary tables, and any additional database files ** created using ATTACH statements. Return a success code. If an |
︙ | ︙ | |||
417 418 419 420 421 422 423 424 425 426 427 428 429 430 | rc = sqlite3BtreeCursor(pBt, MASTER_ROOT, 0, 0, 0, &curTemp); if( rc==SQLITE_OK ){ rc = sqlite3BtreeGetMeta(pBt, 1, (u32 *)&cookie); if( rc==SQLITE_OK && cookie!=db->aDb[iDb].pSchema->schema_cookie ){ allOk = 0; } sqlite3BtreeCloseCursor(curTemp); } } return allOk; } /* ** Convert a schema pointer into the iDb index that indicates | > > > | 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 | rc = sqlite3BtreeCursor(pBt, MASTER_ROOT, 0, 0, 0, &curTemp); if( rc==SQLITE_OK ){ rc = sqlite3BtreeGetMeta(pBt, 1, (u32 *)&cookie); if( rc==SQLITE_OK && cookie!=db->aDb[iDb].pSchema->schema_cookie ){ allOk = 0; } sqlite3BtreeCloseCursor(curTemp); } if( rc==SQLITE_NOMEM ){ db->mallocFailed = 1; } } return allOk; } /* ** Convert a schema pointer into the iDb index that indicates |
︙ | ︙ |
Changes to src/printf.c.
︙ | ︙ | |||
785 786 787 788 789 790 791 | if( xRealloc ){ if( sM.zText==sM.zBase ){ sM.zText = xRealloc(0, sM.nChar+1); if( sM.zText ){ memcpy(sM.zText, sM.zBase, sM.nChar+1); } }else if( sM.nAlloc>sM.nChar+10 ){ | > > | | 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 | if( xRealloc ){ if( sM.zText==sM.zBase ){ sM.zText = xRealloc(0, sM.nChar+1); if( sM.zText ){ memcpy(sM.zText, sM.zBase, sM.nChar+1); } }else if( sM.nAlloc>sM.nChar+10 ){ char *zNew; sqlite3MallocBenignFailure(1); zNew = xRealloc(sM.zText, sM.nChar+1); if( zNew ){ sM.zText = zNew; } } } return sM.zText; } |
︙ | ︙ |
Changes to src/select.c.
︙ | ︙ | |||
8 9 10 11 12 13 14 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains C code routines that are called by the parser ** to handle SELECT statements in SQLite. ** | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains C code routines that are called by the parser ** to handle SELECT statements in SQLite. ** ** $Id: select.c,v 1.357 2007/08/29 12:31:27 danielk1977 Exp $ */ #include "sqliteInt.h" /* ** Delete all the content of a Select structure but do not deallocate ** the select structure itself. |
︙ | ︙ | |||
56 57 58 59 60 61 62 | pNew = sqlite3DbMallocZero(db, sizeof(*pNew) ); assert( !pOffset || pLimit ); /* Can't have OFFSET without LIMIT. */ if( pNew==0 ){ pNew = &standin; memset(pNew, 0, sizeof(*pNew)); } if( pEList==0 ){ | | | 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | pNew = sqlite3DbMallocZero(db, sizeof(*pNew) ); assert( !pOffset || pLimit ); /* Can't have OFFSET without LIMIT. */ if( pNew==0 ){ pNew = &standin; memset(pNew, 0, sizeof(*pNew)); } if( pEList==0 ){ pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db,TK_ALL,0,0,0), 0); } pNew->pEList = pEList; pNew->pSrc = pSrc; pNew->pWhere = pWhere; pNew->pGroupBy = pGroupBy; pNew->pHaving = pHaving; pNew->pOrderBy = pOrderBy; |
︙ | ︙ | |||
1360 1361 1362 1363 1364 1365 1366 | } if( sqlite3IdListIndex(pLeft[1].pUsing, zName)>=0 ){ /* In a join with a USING clause, omit columns in the ** using clause from the table on the right. */ continue; } } | | | | | 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 | } if( sqlite3IdListIndex(pLeft[1].pUsing, zName)>=0 ){ /* In a join with a USING clause, omit columns in the ** using clause from the table on the right. */ continue; } } pRight = sqlite3PExpr(pParse, TK_ID, 0, 0, 0); if( pRight==0 ) break; setQuotedToken(pParse, &pRight->token, zName); if( zTabName && (longNames || pTabList->nSrc>1) ){ Expr *pLeft = sqlite3PExpr(pParse, TK_ID, 0, 0, 0); pExpr = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight, 0); if( pExpr==0 ) break; setQuotedToken(pParse, &pLeft->token, zTabName); setToken(&pExpr->span, sqlite3MPrintf(db, "%s.%s", zTabName, zName)); pExpr->span.dyn = 1; pExpr->token.z = 0; pExpr->token.n = 0; |
︙ | ︙ |
Changes to src/sqlite.h.in.
︙ | ︙ | |||
26 27 28 29 30 31 32 | ** on how SQLite interfaces are suppose to operate. ** ** The name of this file under configuration management is "sqlite.h.in". ** The makefile makes some minor changes to this file (such as inserting ** the version number) and changes its name to "sqlite3.h" as ** part of the build process. ** | | | 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | ** on how SQLite interfaces are suppose to operate. ** ** The name of this file under configuration management is "sqlite.h.in". ** The makefile makes some minor changes to this file (such as inserting ** the version number) and changes its name to "sqlite3.h" as ** part of the build process. ** ** @(#) $Id: sqlite.h.in,v 1.247 2007/08/29 12:31:28 danielk1977 Exp $ */ #ifndef _SQLITE3_H_ #define _SQLITE3_H_ #include <stdarg.h> /* Needed for the definition of va_list */ /* ** Make sure we can call this stuff from C++. |
︙ | ︙ | |||
2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 | ** the SQL function associated with the [sqlite3_context] pointer. */ void sqlite3_result_blob(sqlite3_context*, const void*, int, void(*)(void*)); void sqlite3_result_double(sqlite3_context*, double); void sqlite3_result_error(sqlite3_context*, const char*, int); void sqlite3_result_error16(sqlite3_context*, const void*, int); void sqlite3_result_error_toobig(sqlite3_context*); void sqlite3_result_int(sqlite3_context*, int); void sqlite3_result_int64(sqlite3_context*, sqlite3_int64); void sqlite3_result_null(sqlite3_context*); void sqlite3_result_text(sqlite3_context*, const char*, int, void(*)(void*)); void sqlite3_result_text16(sqlite3_context*, const void*, int, void(*)(void*)); void sqlite3_result_text16le(sqlite3_context*, const void*, int,void(*)(void*)); void sqlite3_result_text16be(sqlite3_context*, const void*, int,void(*)(void*)); | > | 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 | ** the SQL function associated with the [sqlite3_context] pointer. */ void sqlite3_result_blob(sqlite3_context*, const void*, int, void(*)(void*)); void sqlite3_result_double(sqlite3_context*, double); void sqlite3_result_error(sqlite3_context*, const char*, int); void sqlite3_result_error16(sqlite3_context*, const void*, int); void sqlite3_result_error_toobig(sqlite3_context*); void sqlite3_result_error_nomem(sqlite3_context*); void sqlite3_result_int(sqlite3_context*, int); void sqlite3_result_int64(sqlite3_context*, sqlite3_int64); void sqlite3_result_null(sqlite3_context*); void sqlite3_result_text(sqlite3_context*, const char*, int, void(*)(void*)); void sqlite3_result_text16(sqlite3_context*, const void*, int, void(*)(void*)); void sqlite3_result_text16le(sqlite3_context*, const void*, int,void(*)(void*)); void sqlite3_result_text16be(sqlite3_context*, const void*, int,void(*)(void*)); |
︙ | ︙ |
Changes to src/sqliteInt.h.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* ** 2001 September 15 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** Internal interface definitions for SQLite. ** | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* ** 2001 September 15 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** Internal interface definitions for SQLite. ** ** @(#) $Id: sqliteInt.h,v 1.605 2007/08/29 12:31:28 danielk1977 Exp $ */ #ifndef _SQLITEINT_H_ #define _SQLITEINT_H_ #include "sqliteLimit.h" #define _XOPEN_SOURCE 500 /* Needed to enable pthread recursive mutexes */ |
︙ | ︙ | |||
1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 | void *sqlite3DbMallocZero(sqlite3*, unsigned); void *sqlite3DbMallocRaw(sqlite3*, unsigned); char *sqlite3StrDup(const char*); char *sqlite3StrNDup(const char*, int); char *sqlite3DbStrDup(sqlite3*,const char*); char *sqlite3DbStrNDup(sqlite3*,const char*, int); void *sqlite3DbReallocOrFree(sqlite3 *, void *, int); char *sqlite3MPrintf(sqlite3*,const char*, ...); char *sqlite3VMPrintf(sqlite3*,const char*, va_list); #if defined(SQLITE_TEST) || defined(SQLITE_DEBUG) void sqlite3DebugPrintf(const char*, ...); void *sqlite3TextToPtr(const char*); #endif void sqlite3SetString(char **, ...); void sqlite3ErrorMsg(Parse*, const char*, ...); void sqlite3ErrorClear(Parse*); void sqlite3Dequote(char*); void sqlite3DequoteExpr(sqlite3*, Expr*); int sqlite3KeywordCode(const unsigned char*, int); int sqlite3RunParser(Parse*, const char*, char **); void sqlite3FinishCoding(Parse*); | > | | 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 | void *sqlite3DbMallocZero(sqlite3*, unsigned); void *sqlite3DbMallocRaw(sqlite3*, unsigned); char *sqlite3StrDup(const char*); char *sqlite3StrNDup(const char*, int); char *sqlite3DbStrDup(sqlite3*,const char*); char *sqlite3DbStrNDup(sqlite3*,const char*, int); void *sqlite3DbReallocOrFree(sqlite3 *, void *, int); void *sqlite3DbRealloc(sqlite3 *, void *, int); char *sqlite3MPrintf(sqlite3*,const char*, ...); char *sqlite3VMPrintf(sqlite3*,const char*, va_list); #if defined(SQLITE_TEST) || defined(SQLITE_DEBUG) void sqlite3DebugPrintf(const char*, ...); void *sqlite3TextToPtr(const char*); #endif void sqlite3SetString(char **, ...); void sqlite3ErrorMsg(Parse*, const char*, ...); void sqlite3ErrorClear(Parse*); void sqlite3Dequote(char*); void sqlite3DequoteExpr(sqlite3*, Expr*); int sqlite3KeywordCode(const unsigned char*, int); int sqlite3RunParser(Parse*, const char*, char **); void sqlite3FinishCoding(Parse*); Expr *sqlite3Expr(sqlite3*, int, Expr*, Expr*, const Token*); Expr *sqlite3PExpr(Parse*, int, Expr*, Expr*, const Token*); Expr *sqlite3RegisterExpr(Parse*,Token*); Expr *sqlite3ExprAnd(sqlite3*,Expr*, Expr*); void sqlite3ExprSpan(Expr*,Token*,Token*); Expr *sqlite3ExprFunction(Parse*,ExprList*, Token*); void sqlite3ExprAssignVarNumber(Parse*, Expr*); void sqlite3ExprDelete(Expr*); |
︙ | ︙ | |||
1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 | ** The MallocDisallow() and MallocAllow() routines are like asserts. ** Call them around a section of code that you do not expect to do ** any memory allocation. */ #ifdef SQLITE_MEMDEBUG void sqlite3MallocDisallow(void); void sqlite3MallocAllow(void); #else # define sqlite3MallocDisallow() # define sqlite3MallocAllow() #endif #ifdef SQLITE_OMIT_VIRTUALTABLE # define sqlite3VtabClear(X) # define sqlite3VtabSync(X,Y) (Y) # define sqlite3VtabRollback(X) | > > | 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 | ** The MallocDisallow() and MallocAllow() routines are like asserts. ** Call them around a section of code that you do not expect to do ** any memory allocation. */ #ifdef SQLITE_MEMDEBUG void sqlite3MallocDisallow(void); void sqlite3MallocAllow(void); void sqlite3MallocBenignFailure(int); #else # define sqlite3MallocDisallow() # define sqlite3MallocAllow() # define sqlite3MallocBenignFailure(x) #endif #ifdef SQLITE_OMIT_VIRTUALTABLE # define sqlite3VtabClear(X) # define sqlite3VtabSync(X,Y) (Y) # define sqlite3VtabRollback(X) |
︙ | ︙ |
Changes to src/test2.c.
︙ | ︙ | |||
9 10 11 12 13 14 15 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** Code for testing the pager.c module in SQLite. This code ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. ** | | | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** Code for testing the pager.c module in SQLite. This code ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. ** ** $Id: test2.c,v 1.51 2007/08/29 12:31:28 danielk1977 Exp $ */ #include "sqliteInt.h" #include "tcl.h" #include <stdlib.h> #include <string.h> /* |
︙ | ︙ | |||
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 | */ static int pager_open( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ const char **argv /* Text of each argument */ ){ Pager *pPager; int nPage; int rc; char zBuf[100]; if( argc!=3 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " FILENAME N-PAGE\"", 0); return TCL_ERROR; } if( Tcl_GetInt(interp, argv[2], &nPage) ) return TCL_ERROR; rc = sqlite3PagerOpen(sqlite3_vfs_find(0), &pPager, argv[1], 0, 0); if( rc!=SQLITE_OK ){ Tcl_AppendResult(interp, errorName(rc), 0); return TCL_ERROR; } sqlite3PagerSetCachesize(pPager, nPage); | > > | | 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 | */ static int pager_open( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ const char **argv /* Text of each argument */ ){ u16 pageSize; Pager *pPager; int nPage; int rc; char zBuf[100]; if( argc!=3 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " FILENAME N-PAGE\"", 0); return TCL_ERROR; } if( Tcl_GetInt(interp, argv[2], &nPage) ) return TCL_ERROR; rc = sqlite3PagerOpen(sqlite3_vfs_find(0), &pPager, argv[1], 0, 0); if( rc!=SQLITE_OK ){ Tcl_AppendResult(interp, errorName(rc), 0); return TCL_ERROR; } sqlite3PagerSetCachesize(pPager, nPage); pageSize = test_pagesize; sqlite3PagerSetPagesize(pPager, &pageSize); sqlite3_snprintf(sizeof(zBuf),zBuf,"%p",pPager); Tcl_AppendResult(interp, zBuf, 0); return TCL_OK; } /* ** Usage: pager_close ID |
︙ | ︙ |
Changes to src/test3.c.
︙ | ︙ | |||
9 10 11 12 13 14 15 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** Code for testing the btree.c module in SQLite. This code ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. ** | | > | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** Code for testing the btree.c module in SQLite. This code ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. ** ** $Id: test3.c,v 1.83 2007/08/29 12:31:28 danielk1977 Exp $ */ #include "sqliteInt.h" #include "btreeInt.h" #include "tcl.h" #include <stdlib.h> #include <string.h> /* ** Interpret an SQLite error number */ |
︙ | ︙ | |||
526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 | if( argc!=2 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " ID\"", 0); return TCL_ERROR; } pBt = sqlite3TextToPtr(argv[1]); sqlite3BtreeEnter(pBt); a = sqlite3PagerStats(sqlite3BtreePager(pBt)); for(i=0; i<11; i++){ static char *zName[] = { "ref", "page", "max", "size", "state", "err", "hit", "miss", "ovfl", "read", "write" }; char zBuf[100]; Tcl_AppendElement(interp, zName[i]); sqlite3_snprintf(sizeof(zBuf), zBuf,"%d",a[i]); Tcl_AppendElement(interp, zBuf); } sqlite3BtreeLeave(pBt); return TCL_OK; } /* ** Usage: btree_pager_ref_dump ID ** ** Print out all outstanding pages. | > > | 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 | if( argc!=2 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " ID\"", 0); return TCL_ERROR; } pBt = sqlite3TextToPtr(argv[1]); sqlite3_mutex_enter(pBt->pSqlite->mutex); sqlite3BtreeEnter(pBt); a = sqlite3PagerStats(sqlite3BtreePager(pBt)); for(i=0; i<11; i++){ static char *zName[] = { "ref", "page", "max", "size", "state", "err", "hit", "miss", "ovfl", "read", "write" }; char zBuf[100]; Tcl_AppendElement(interp, zName[i]); sqlite3_snprintf(sizeof(zBuf), zBuf,"%d",a[i]); Tcl_AppendElement(interp, zBuf); } sqlite3BtreeLeave(pBt); sqlite3_mutex_leave(pBt->pSqlite->mutex); return TCL_OK; } /* ** Usage: btree_pager_ref_dump ID ** ** Print out all outstanding pages. |
︙ | ︙ | |||
1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 | if( argc!=3 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " BT NCACHE\"", 0); return TCL_ERROR; } pBt = sqlite3TextToPtr(argv[1]); if( Tcl_GetInt(interp, argv[2], &nCache) ) return TCL_ERROR; sqlite3BtreeSetCacheSize(pBt, nCache); return TCL_OK; } /* ** Register commands with the TCL interpreter. */ | > > > > | 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 | if( argc!=3 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " BT NCACHE\"", 0); return TCL_ERROR; } pBt = sqlite3TextToPtr(argv[1]); if( Tcl_GetInt(interp, argv[2], &nCache) ) return TCL_ERROR; sqlite3_mutex_enter(pBt->pSqlite->mutex); sqlite3BtreeSetCacheSize(pBt, nCache); sqlite3_mutex_leave(pBt->pSqlite->mutex); return TCL_OK; } /* ** Register commands with the TCL interpreter. */ |
︙ | ︙ |
Changes to src/test8.c.
︙ | ︙ | |||
9 10 11 12 13 14 15 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** Code for testing the virtual table interfaces. This code ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. ** | | | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** Code for testing the virtual table interfaces. This code ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. ** ** $Id: test8.c,v 1.55 2007/08/29 12:31:28 danielk1977 Exp $ */ #include "sqliteInt.h" #include "tcl.h" #include <stdlib.h> #include <string.h> #ifndef SQLITE_OMIT_VIRTUALTABLE |
︙ | ︙ | |||
357 358 359 360 361 362 363 364 365 366 367 368 369 370 | static int echoConstructor( sqlite3 *db, void *pAux, int argc, const char *const*argv, sqlite3_vtab **ppVtab, char **pzErr ){ int i; echo_vtab *pVtab; /* Allocate the sqlite3_vtab/echo_vtab structure itself */ pVtab = sqlite3MallocZero( sizeof(*pVtab) ); if( !pVtab ){ return SQLITE_NOMEM; | > | 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 | static int echoConstructor( sqlite3 *db, void *pAux, int argc, const char *const*argv, sqlite3_vtab **ppVtab, char **pzErr ){ int rc; int i; echo_vtab *pVtab; /* Allocate the sqlite3_vtab/echo_vtab structure itself */ pVtab = sqlite3MallocZero( sizeof(*pVtab) ); if( !pVtab ){ return SQLITE_NOMEM; |
︙ | ︙ | |||
400 401 402 403 404 405 406 | appendToEchoModule(pVtab->interp, argv[i]); } /* Invoke sqlite3_declare_vtab and set up other members of the echo_vtab ** structure. If an error occurs, delete the sqlite3_vtab structure and ** return an error code. */ | | > | | 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 | appendToEchoModule(pVtab->interp, argv[i]); } /* Invoke sqlite3_declare_vtab and set up other members of the echo_vtab ** structure. If an error occurs, delete the sqlite3_vtab structure and ** return an error code. */ rc = echoDeclareVtab(pVtab, db); if( rc!=SQLITE_OK ){ echoDestructor((sqlite3_vtab *)pVtab); return rc; } /* Success. Set *ppVtab and return */ *ppVtab = &pVtab->base; return SQLITE_OK; } |
︙ | ︙ | |||
642 643 644 645 646 647 648 | ** string. The two strings are concatenated together and *pzStr ** set to point at the result. The initial buffer pointed to by *pzStr ** is deallocated via sqlite3_free(). ** ** If the third argument, doFree, is true, then sqlite3_free() is ** also called to free the buffer pointed to by zAppend. */ | | > > > > > > > | | | | | | > > > > | 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 | ** string. The two strings are concatenated together and *pzStr ** set to point at the result. The initial buffer pointed to by *pzStr ** is deallocated via sqlite3_free(). ** ** If the third argument, doFree, is true, then sqlite3_free() is ** also called to free the buffer pointed to by zAppend. */ static void string_concat(char **pzStr, char *zAppend, int doFree, int *pRc){ char *zIn = *pzStr; if( !zAppend && doFree && *pRc==SQLITE_OK ){ *pRc = SQLITE_NOMEM; } if( *pRc!=SQLITE_OK ){ sqlite3_free(zIn); zIn = 0; }else{ if( zIn ){ char *zTemp = zIn; zIn = sqlite3_mprintf("%s%s", zIn, zAppend); sqlite3_free(zTemp); }else{ zIn = sqlite3_mprintf("%s", zAppend); } if( !zIn ){ *pRc = SQLITE_NOMEM; } } *pzStr = zIn; if( doFree ){ sqlite3_free(zAppend); } } |
︙ | ︙ | |||
705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 | ** number of rows if the proposed scan uses an index. */ if( Tcl_GetVar(interp, "echo_module_cost", TCL_GLOBAL_ONLY) ){ cost = atof(Tcl_GetVar(interp, "echo_module_cost", TCL_GLOBAL_ONLY)); useCost = 1; } else { zQuery = sqlite3_mprintf("SELECT count(*) FROM %Q", pVtab->zTableName); rc = sqlite3_prepare(pVtab->db, zQuery, -1, &pStmt, 0); sqlite3_free(zQuery); if( rc!=SQLITE_OK ){ return rc; } sqlite3_step(pStmt); nRow = sqlite3_column_int(pStmt, 0); rc = sqlite3_finalize(pStmt); if( rc!=SQLITE_OK ){ return rc; } } zQuery = sqlite3_mprintf("SELECT rowid, * FROM %Q", pVtab->zTableName); for(ii=0; ii<pIdxInfo->nConstraint; ii++){ const struct sqlite3_index_constraint *pConstraint; struct sqlite3_index_constraint_usage *pUsage; int iCol; pConstraint = &pIdxInfo->aConstraint[ii]; pUsage = &pIdxInfo->aConstraintUsage[ii]; | > > > > > > | 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 | ** number of rows if the proposed scan uses an index. */ if( Tcl_GetVar(interp, "echo_module_cost", TCL_GLOBAL_ONLY) ){ cost = atof(Tcl_GetVar(interp, "echo_module_cost", TCL_GLOBAL_ONLY)); useCost = 1; } else { zQuery = sqlite3_mprintf("SELECT count(*) FROM %Q", pVtab->zTableName); if( !zQuery ){ return SQLITE_NOMEM; } rc = sqlite3_prepare(pVtab->db, zQuery, -1, &pStmt, 0); sqlite3_free(zQuery); if( rc!=SQLITE_OK ){ return rc; } sqlite3_step(pStmt); nRow = sqlite3_column_int(pStmt, 0); rc = sqlite3_finalize(pStmt); if( rc!=SQLITE_OK ){ return rc; } } zQuery = sqlite3_mprintf("SELECT rowid, * FROM %Q", pVtab->zTableName); if( !zQuery ){ return SQLITE_NOMEM; } for(ii=0; ii<pIdxInfo->nConstraint; ii++){ const struct sqlite3_index_constraint *pConstraint; struct sqlite3_index_constraint_usage *pUsage; int iCol; pConstraint = &pIdxInfo->aConstraint[ii]; pUsage = &pIdxInfo->aConstraintUsage[ii]; |
︙ | ︙ | |||
755 756 757 758 759 760 761 | } if( zOp[0]=='L' ){ zNew = sqlite3_mprintf(" %s %s LIKE (SELECT '%%'||?||'%%')", zSep, zCol); } else { zNew = sqlite3_mprintf(" %s %s %s ?", zSep, zCol, zOp); } | | | | | 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 | } if( zOp[0]=='L' ){ zNew = sqlite3_mprintf(" %s %s LIKE (SELECT '%%'||?||'%%')", zSep, zCol); } else { zNew = sqlite3_mprintf(" %s %s %s ?", zSep, zCol, zOp); } string_concat(&zQuery, zNew, 1, &rc); zSep = "AND"; pUsage->argvIndex = ++nArg; pUsage->omit = 1; } } /* If there is only one term in the ORDER BY clause, and it is ** on a column that this virtual table has an index for, then consume ** the ORDER BY clause. */ if( pIdxInfo->nOrderBy==1 && pVtab->aIndex[pIdxInfo->aOrderBy->iColumn] ){ int iCol = pIdxInfo->aOrderBy->iColumn; char *zCol = pVtab->aCol[iCol]; char *zDir = pIdxInfo->aOrderBy->desc?"DESC":"ASC"; if( iCol<0 ){ zCol = "rowid"; } zNew = sqlite3_mprintf(" ORDER BY %s %s", zCol, zDir); string_concat(&zQuery, zNew, 1, &rc); pIdxInfo->orderByConsumed = 1; } appendToEchoModule(pVtab->interp, "xBestIndex");; appendToEchoModule(pVtab->interp, zQuery); if( !zQuery ){ return rc; } pIdxInfo->idxNum = hashString(zQuery); pIdxInfo->idxStr = zQuery; pIdxInfo->needToFreeIdxStr = 1; if (useCost) { pIdxInfo->estimatedCost = cost; } else if( useIdx ){ |
︙ | ︙ | |||
839 840 841 842 843 844 845 846 847 848 849 850 | assert( nData==pVtab->nCol+2 || nData==1 ); /* If apData[0] is an integer and nData>1 then do an UPDATE */ if( nData>1 && sqlite3_value_type(apData[0])==SQLITE_INTEGER ){ char *zSep = " SET"; z = sqlite3_mprintf("UPDATE %Q", pVtab->zTableName); bindArgOne = (apData[1] && sqlite3_value_type(apData[1])==SQLITE_INTEGER); bindArgZero = 1; if( bindArgOne ){ | > > > | | | > > > > > > | | | | | | | > | > | 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 | assert( nData==pVtab->nCol+2 || nData==1 ); /* If apData[0] is an integer and nData>1 then do an UPDATE */ if( nData>1 && sqlite3_value_type(apData[0])==SQLITE_INTEGER ){ char *zSep = " SET"; z = sqlite3_mprintf("UPDATE %Q", pVtab->zTableName); if( !z ){ rc = SQLITE_NOMEM; } bindArgOne = (apData[1] && sqlite3_value_type(apData[1])==SQLITE_INTEGER); bindArgZero = 1; if( bindArgOne ){ string_concat(&z, " SET rowid=?1 ", 0, &rc); zSep = ","; } for(i=2; i<nData; i++){ if( apData[i]==0 ) continue; string_concat(&z, sqlite3_mprintf( "%s %Q=?%d", zSep, pVtab->aCol[i-2], i), 1, &rc); zSep = ","; } string_concat(&z, sqlite3_mprintf(" WHERE rowid=?%d", nData), 1, &rc); } /* If apData[0] is an integer and nData==1 then do a DELETE */ else if( nData==1 && sqlite3_value_type(apData[0])==SQLITE_INTEGER ){ z = sqlite3_mprintf("DELETE FROM %Q WHERE rowid = ?1", pVtab->zTableName); if( !z ){ rc = SQLITE_NOMEM; } bindArgZero = 1; } /* If the first argument is NULL and there are more than two args, INSERT */ else if( nData>2 && sqlite3_value_type(apData[0])==SQLITE_NULL ){ int ii; char *zInsert = 0; char *zValues = 0; zInsert = sqlite3_mprintf("INSERT INTO %Q (", pVtab->zTableName); if( !zInsert ){ rc = SQLITE_NOMEM; } if( sqlite3_value_type(apData[1])==SQLITE_INTEGER ){ bindArgOne = 1; zValues = sqlite3_mprintf("?"); string_concat(&zInsert, "rowid", 0, &rc); } assert((pVtab->nCol+2)==nData); for(ii=2; ii<nData; ii++){ string_concat(&zInsert, sqlite3_mprintf("%s%Q", zValues?", ":"", pVtab->aCol[ii-2]), 1, &rc); string_concat(&zValues, sqlite3_mprintf("%s?%d", zValues?", ":"", ii), 1, &rc); } string_concat(&z, zInsert, 1, &rc); string_concat(&z, ") VALUES(", 0, &rc); string_concat(&z, zValues, 1, &rc); string_concat(&z, ")", 0, &rc); } /* Anything else is an error */ else{ assert(0); return SQLITE_ERROR; } if( rc==SQLITE_OK ){ rc = sqlite3_prepare(db, z, -1, &pStmt, 0); } assert( rc!=SQLITE_OK || pStmt ); sqlite3_free(z); if( rc==SQLITE_OK ) { if( bindArgZero ){ sqlite3_bind_value(pStmt, nData, apData[0]); } if( bindArgOne ){ |
︙ | ︙ | |||
931 932 933 934 935 936 937 | static int echoTransactionCall(sqlite3_vtab *tab, const char *zCall){ char *z; echo_vtab *pVtab = (echo_vtab *)tab; z = sqlite3_mprintf("echo(%s)", pVtab->zTableName); appendToEchoModule(pVtab->interp, zCall); appendToEchoModule(pVtab->interp, z); sqlite3_free(z); | | > | > | | | | | | | | > | > | > | | | | | | | | > | > | 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 | static int echoTransactionCall(sqlite3_vtab *tab, const char *zCall){ char *z; echo_vtab *pVtab = (echo_vtab *)tab; z = sqlite3_mprintf("echo(%s)", pVtab->zTableName); appendToEchoModule(pVtab->interp, zCall); appendToEchoModule(pVtab->interp, z); sqlite3_free(z); return (z?SQLITE_OK:SQLITE_NOMEM); } static int echoBegin(sqlite3_vtab *tab){ int rc; echo_vtab *pVtab = (echo_vtab *)tab; Tcl_Interp *interp = pVtab->interp; const char *zVal; rc = echoTransactionCall(tab, "xBegin"); if( rc==SQLITE_OK ){ /* Check if the $::echo_module_begin_fail variable is defined. If it is, ** and it is set to the name of the real table underlying this virtual ** echo module table, then cause this xSync operation to fail. */ zVal = Tcl_GetVar(interp, "echo_module_begin_fail", TCL_GLOBAL_ONLY); if( zVal && 0==strcmp(zVal, pVtab->zTableName) ){ rc = SQLITE_ERROR; } } return rc; } static int echoSync(sqlite3_vtab *tab){ int rc; echo_vtab *pVtab = (echo_vtab *)tab; Tcl_Interp *interp = pVtab->interp; const char *zVal; rc = echoTransactionCall(tab, "xSync"); if( rc==SQLITE_OK ){ /* Check if the $::echo_module_sync_fail variable is defined. If it is, ** and it is set to the name of the real table underlying this virtual ** echo module table, then cause this xSync operation to fail. */ zVal = Tcl_GetVar(interp, "echo_module_sync_fail", TCL_GLOBAL_ONLY); if( zVal && 0==strcmp(zVal, pVtab->zTableName) ){ rc = -1; } } return rc; } static int echoCommit(sqlite3_vtab *tab){ sqlite3MallocBenignFailure(1); return echoTransactionCall(tab, "xCommit"); } static int echoRollback(sqlite3_vtab *tab){ return echoTransactionCall(tab, "xRollback"); } /* |
︙ | ︙ |
Changes to src/test_malloc.c.
︙ | ︙ | |||
9 10 11 12 13 14 15 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** ** This file contains code used to implement test interfaces to the ** memory allocation subsystem. ** | | | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** ** This file contains code used to implement test interfaces to the ** memory allocation subsystem. ** ** $Id: test_malloc.c,v 1.6 2007/08/29 12:31:28 danielk1977 Exp $ */ #include "sqliteInt.h" #include "tcl.h" #include <stdlib.h> #include <string.h> #include <assert.h> |
︙ | ︙ | |||
241 242 243 244 245 246 247 | } #endif return TCL_OK; } /* | | > > > > > > | > > > > | | | > > > > > > > > > | > > > > > > | > > > > > | > > > | > > | | > > > | 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 | } #endif return TCL_OK; } /* ** Usage: sqlite3_memdebug_fail COUNTER ?OPTIONS? ** ** where options are: ** ** -repeat <boolean> ** -benigncnt <varname> ** ** Arrange for a simulated malloc() failure after COUNTER successes. ** If REPEAT is 1 then all subsequent malloc()s fail. If REPEAT is ** 0 then only a single failure occurs. ** ** Each call to this routine overrides the prior counter value. ** This routine returns the number of simulated failures that have ** happened since the previous call to this routine. ** ** To disable simulated failures, use a COUNTER of -1. */ static int test_memdebug_fail( void * clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ int ii; int iFail; int iRepeat = -1; int iBenignCnt; Tcl_Obj *pBenignCnt = 0; int nFail = 0; if( objc<2 ){ Tcl_WrongNumArgs(interp, 1, objv, "COUNTER ?OPTIONS?"); return TCL_ERROR; } if( Tcl_GetIntFromObj(interp, objv[1], &iFail) ) return TCL_ERROR; for(ii=2; ii<objc; ii+=2){ int nOption; char *zOption = Tcl_GetStringFromObj(objv[ii], &nOption); char *zErr = 0; if( nOption>1 && strncmp(zOption, "-repeat", nOption)==0 ){ if( ii==(objc-1) ){ zErr = "option requires an argument: "; }else{ if( Tcl_GetIntFromObj(interp, objv[ii+1], &iRepeat) ){ return TCL_ERROR; } } }else if( nOption>1 && strncmp(zOption, "-benigncnt", nOption)==0 ){ if( ii==(objc-1) ){ zErr = "option requires an argument: "; }else{ pBenignCnt = objv[ii+1]; } }else{ zErr = "unknown option: "; } if( zErr ){ Tcl_AppendResult(interp, zErr, zOption, 0); return TCL_ERROR; } } #ifdef SQLITE_MEMDEBUG { extern int sqlite3_memdebug_fail(int,int,int*); nFail = sqlite3_memdebug_fail(iFail, iRepeat, &iBenignCnt); if( pBenignCnt ){ Tcl_ObjSetVar2(interp, pBenignCnt, 0, Tcl_NewIntObj(iBenignCnt), 0); } } #endif Tcl_SetObjResult(interp, Tcl_NewIntObj(nFail)); return TCL_OK; } |
︙ | ︙ |
Changes to src/vacuum.c.
︙ | ︙ | |||
10 11 12 13 14 15 16 | ** ************************************************************************* ** This file contains code used to implement the VACUUM command. ** ** Most of the code in this file may be omitted by defining the ** SQLITE_OMIT_VACUUM macro. ** | | > > > | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | ** ************************************************************************* ** This file contains code used to implement the VACUUM command. ** ** Most of the code in this file may be omitted by defining the ** SQLITE_OMIT_VACUUM macro. ** ** $Id: vacuum.c,v 1.73 2007/08/29 12:31:28 danielk1977 Exp $ */ #include "sqliteInt.h" #include "vdbeInt.h" #if !defined(SQLITE_OMIT_VACUUM) && !defined(SQLITE_OMIT_ATTACH) /* ** Execute zSql on database db. Return an error code. */ static int execSql(sqlite3 *db, const char *zSql){ sqlite3_stmt *pStmt; if( !zSql ){ return SQLITE_NOMEM; } if( SQLITE_OK!=sqlite3_prepare(db, zSql, -1, &pStmt, 0) ){ return sqlite3_errcode(db); } while( SQLITE_ROW==sqlite3_step(pStmt) ){} return sqlite3_finalize(pStmt); } |
︙ | ︙ |
Changes to src/vdbe.c.
︙ | ︙ | |||
39 40 41 42 43 44 45 | ** ** Various scripts scan this source file in order to generate HTML ** documentation, headers files, or other derived files. The formatting ** of the code in this file is, therefore, important. See other comments ** in this file for details. If in doubt, do not deviate from existing ** commenting and indentation practices when changing or adding code. ** | | | 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | ** ** Various scripts scan this source file in order to generate HTML ** documentation, headers files, or other derived files. The formatting ** of the code in this file is, therefore, important. See other comments ** in this file for details. If in doubt, do not deviate from existing ** commenting and indentation practices when changing or adding code. ** ** $Id: vdbe.c,v 1.647 2007/08/29 12:31:28 danielk1977 Exp $ */ #include "sqliteInt.h" #include <ctype.h> #include <math.h> #include "vdbeInt.h" /* |
︙ | ︙ | |||
2633 2634 2635 2636 2637 2638 2639 | if( pBt ){ rc = sqlite3BtreeGetMeta(pBt, 1, (u32 *)&iMeta); }else{ rc = SQLITE_OK; iMeta = 0; } if( rc==SQLITE_OK && iMeta!=pOp->p2 ){ | > | | 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 | if( pBt ){ rc = sqlite3BtreeGetMeta(pBt, 1, (u32 *)&iMeta); }else{ rc = SQLITE_OK; iMeta = 0; } if( rc==SQLITE_OK && iMeta!=pOp->p2 ){ sqlite3_free(p->zErrMsg); p->zErrMsg = sqlite3DbStrDup(db, "database schema has changed"); /* If the schema-cookie from the database file matches the cookie ** stored with the in-memory representation of the schema, do ** not reload the schema from the database file. ** ** If virtual-tables are in use, this is not just an optimisation. ** Often, v-tables store their data in other SQLite tables, which ** are queried from within xNext() and other v-table methods using |
︙ | ︙ |
Changes to src/vdbeapi.c.
︙ | ︙ | |||
230 231 232 233 234 235 236 237 238 239 240 241 242 243 | /* Force an SQLITE_TOOBIG error. */ void sqlite3_result_error_toobig(sqlite3_context *pCtx){ assert( sqlite3_mutex_held(pCtx->s.db->mutex) ); sqlite3VdbeMemSetZeroBlob(&pCtx->s, SQLITE_MAX_LENGTH+1); } /* ** Execute the statement pStmt, either until a row of data is ready, the ** statement is completely executed or an error occurs. ** ** This routine implements the bulk of the logic behind the sqlite_step() ** API. The only thing omitted is the automatic recompile if a | > > > > > > > | 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 | /* Force an SQLITE_TOOBIG error. */ void sqlite3_result_error_toobig(sqlite3_context *pCtx){ assert( sqlite3_mutex_held(pCtx->s.db->mutex) ); sqlite3VdbeMemSetZeroBlob(&pCtx->s, SQLITE_MAX_LENGTH+1); } /* An SQLITE_NOMEM error. */ void sqlite3_result_error_nomem(sqlite3_context *pCtx){ assert( sqlite3_mutex_held(pCtx->s.db->mutex) ); sqlite3VdbeMemSetNull(&pCtx->s); pCtx->isError = 1; pCtx->s.db->mallocFailed = 1; } /* ** Execute the statement pStmt, either until a row of data is ready, the ** statement is completely executed or an error occurs. ** ** This routine implements the bulk of the logic behind the sqlite_step() ** API. The only thing omitted is the automatic recompile if a |
︙ | ︙ |
Changes to src/vdbeaux.c.
︙ | ︙ | |||
111 112 113 114 115 116 117 | */ static void resizeOpArray(Vdbe *p, int N){ int runMode = p->magic==VDBE_MAGIC_RUN; if( runMode || p->nOpAlloc<N ){ VdbeOp *pNew; int nNew = N + 100*(!runMode); int oldSize = p->nOpAlloc; | | < < | 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 | */ static void resizeOpArray(Vdbe *p, int N){ int runMode = p->magic==VDBE_MAGIC_RUN; if( runMode || p->nOpAlloc<N ){ VdbeOp *pNew; int nNew = N + 100*(!runMode); int oldSize = p->nOpAlloc; pNew = sqlite3DbRealloc(p->db, p->aOp, nNew*sizeof(Op)); if( pNew ){ p->nOpAlloc = nNew; p->aOp = pNew; if( nNew>oldSize ){ memset(&p->aOp[oldSize], 0, (nNew-oldSize)*sizeof(Op)); } } } } /* ** Add a new instruction to the list of instructions current in the ** VDBE. Return the address of the new instruction. |
︙ | ︙ |
Changes to src/vdbemem.c.
︙ | ︙ | |||
256 257 258 259 260 261 262 | if( pMem->z && pMem->z!=pMem->zShort ){ sqlite3_free( pMem->z ); } *pMem = ctx.s; if( pMem->flags & MEM_Short ){ pMem->z = pMem->zShort; } | < | < | 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 | if( pMem->z && pMem->z!=pMem->zShort ){ sqlite3_free( pMem->z ); } *pMem = ctx.s; if( pMem->flags & MEM_Short ){ pMem->z = pMem->zShort; } rc = (ctx.isError?SQLITE_ERROR:SQLITE_OK); } return rc; } /* ** Release any memory held by the Mem. This may leave the Mem in an ** inconsistent state, for example with (Mem.z==0) and |
︙ | ︙ |
Changes to src/vtab.c.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* ** 2006 June 10 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains code used to help implement virtual tables. ** | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* ** 2006 June 10 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains code used to help implement virtual tables. ** ** $Id: vtab.c,v 1.55 2007/08/29 12:31:29 danielk1977 Exp $ */ #ifndef SQLITE_OMIT_VIRTUALTABLE #include "sqliteInt.h" static int createModule( sqlite3 *db, /* Database in which module is registered */ const char *zName, /* Name assigned to this module */ |
︙ | ︙ | |||
292 293 294 295 296 297 298 299 300 301 302 303 304 305 | else { Table *pOld; Schema *pSchema = pTab->pSchema; const char *zName = pTab->zName; int nName = strlen(zName) + 1; pOld = sqlite3HashInsert(&pSchema->tblHash, zName, nName, pTab); if( pOld ){ assert( pTab==pOld ); /* Malloc must have failed inside HashInsert() */ return; } pSchema->db = pParse->db; pParse->pNewTable = 0; } } | > | 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 | else { Table *pOld; Schema *pSchema = pTab->pSchema; const char *zName = pTab->zName; int nName = strlen(zName) + 1; pOld = sqlite3HashInsert(&pSchema->tblHash, zName, nName, pTab); if( pOld ){ db->mallocFailed = 1; assert( pTab==pOld ); /* Malloc must have failed inside HashInsert() */ return; } pSchema->db = pParse->db; pParse->pNewTable = 0; } } |
︙ | ︙ |
Changes to src/where.c.
︙ | ︙ | |||
12 13 14 15 16 17 18 | ** This module contains C code that generates VDBE code used to process ** the WHERE clause of SQL statements. This module is reponsible for ** generating the code that loops through a table looking for applicable ** rows. Indices are selected and used to speed the search when doing ** so is applicable. Because this module is responsible for selecting ** indices, you might also think of this module as the "query optimizer". ** | | | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | ** This module contains C code that generates VDBE code used to process ** the WHERE clause of SQL statements. This module is reponsible for ** generating the code that loops through a table looking for applicable ** rows. Indices are selected and used to speed the search when doing ** so is applicable. Because this module is responsible for selecting ** indices, you might also think of this module as the "query optimizer". ** ** $Id: where.c,v 1.258 2007/08/29 12:31:29 danielk1977 Exp $ */ #include "sqliteInt.h" /* ** The number of bits in a Bitmask. "BMS" means "BitMask Size". */ #define BMS (sizeof(Bitmask)*8) |
︙ | ︙ | |||
787 788 789 790 791 792 793 | int i; static const u8 ops[] = {TK_GE, TK_LE}; assert( pList!=0 ); assert( pList->nExpr==2 ); for(i=0; i<2; i++){ Expr *pNewExpr; int idxNew; | | | 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 | int i; static const u8 ops[] = {TK_GE, TK_LE}; assert( pList!=0 ); assert( pList->nExpr==2 ); for(i=0; i<2; i++){ Expr *pNewExpr; int idxNew; pNewExpr = sqlite3Expr(db, ops[i], sqlite3ExprDup(db, pExpr->pLeft), sqlite3ExprDup(db, pList->a[i].pExpr), 0); idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC); exprAnalyze(pSrc, pWC, idxNew); pTerm = &pWC->a[idxTerm]; pWC->a[idxNew].iParent = idxTerm; } pTerm->nChild = 2; |
︙ | ︙ | |||
854 855 856 857 858 859 860 | if( (pOrTerm->flags & TERM_OR_OK)==0 ) continue; pDup = sqlite3ExprDup(db, pOrTerm->pExpr->pRight); pList = sqlite3ExprListAppend(pWC->pParse, pList, pDup, 0); pLeft = pOrTerm->pExpr->pLeft; } assert( pLeft!=0 ); pDup = sqlite3ExprDup(db, pLeft); | | | 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 | if( (pOrTerm->flags & TERM_OR_OK)==0 ) continue; pDup = sqlite3ExprDup(db, pOrTerm->pExpr->pRight); pList = sqlite3ExprListAppend(pWC->pParse, pList, pDup, 0); pLeft = pOrTerm->pExpr->pLeft; } assert( pLeft!=0 ); pDup = sqlite3ExprDup(db, pLeft); pNew = sqlite3Expr(db, TK_IN, pDup, 0, 0); if( pNew ){ int idxNew; transferJoinMarkings(pNew, pExpr); pNew->pList = pList; idxNew = whereClauseInsert(pWC, pNew, TERM_VIRTUAL|TERM_DYNAMIC); exprAnalyze(pSrc, pWC, idxNew); pTerm = &pWC->a[idxTerm]; |
︙ | ︙ | |||
930 931 932 933 934 935 936 | pRight = pExpr->pList->a[0].pExpr; pLeft = pExpr->pList->a[1].pExpr; prereqExpr = exprTableUsage(pMaskSet, pRight); prereqColumn = exprTableUsage(pMaskSet, pLeft); if( (prereqExpr & prereqColumn)==0 ){ Expr *pNewExpr; | | | 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 | pRight = pExpr->pList->a[0].pExpr; pLeft = pExpr->pList->a[1].pExpr; prereqExpr = exprTableUsage(pMaskSet, pRight); prereqColumn = exprTableUsage(pMaskSet, pLeft); if( (prereqExpr & prereqColumn)==0 ){ Expr *pNewExpr; pNewExpr = sqlite3Expr(db, TK_MATCH, 0, sqlite3ExprDup(db, pRight), 0); idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC); pNewTerm = &pWC->a[idxNew]; pNewTerm->prereqRight = prereqExpr; pNewTerm->leftCursor = pLeft->iTable; pNewTerm->leftColumn = pLeft->iColumn; pNewTerm->eOperator = WO_MATCH; pNewTerm->iParent = idxTerm; |
︙ | ︙ |
Changes to test/capi3.test.
1 2 3 4 5 6 7 8 9 10 11 12 13 | # 2003 January 29 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. The # focus of this script testing the callback-free C/C++ API. # | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | # 2003 January 29 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. The # focus of this script testing the callback-free C/C++ API. # # $Id: capi3.test,v 1.54 2007/08/29 12:31:29 danielk1977 Exp $ # set testdir [file dirname $argv0] source $testdir/tester.tcl # Return the UTF-16 representation of the supplied UTF-8 string $str. # If $nt is true, append two 0x00 bytes as a nul terminator. |
︙ | ︙ | |||
750 751 752 753 754 755 756 | } # Test the error message when a "real" out of memory occurs. if {[info command sqlite3_memdebug_fail]!=""} { do_test capi3-10-1 { sqlite3 db test.db set DB [sqlite3_connection_pointer db] | | | | 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 | } # Test the error message when a "real" out of memory occurs. if {[info command sqlite3_memdebug_fail]!=""} { do_test capi3-10-1 { sqlite3 db test.db set DB [sqlite3_connection_pointer db] sqlite3_memdebug_fail 0 catchsql { select * from sqlite_master; } } {1 {out of memory}} do_test capi3-10-2 { sqlite3_errmsg $::DB } {out of memory} ifcapable {utf16} { do_test capi3-10-3 { utf8 [sqlite3_errmsg16 $::DB] } {out of memory} } db close sqlite3_memdebug_fail -1 } # The following tests - capi3-11.* - test that a COMMIT or ROLLBACK # statement issued while there are still outstanding VMs that are part of # the transaction fails. sqlite3 db test.db set DB [sqlite3_connection_pointer db] |
︙ | ︙ |
Changes to test/capi3c.test.
︙ | ︙ | |||
9 10 11 12 13 14 15 | # #*********************************************************************** # This file implements regression tests for SQLite library. # # This is a copy of the capi3.test file that has been adapted to # test the new sqlite3_prepare_v2 interface. # | | | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | # #*********************************************************************** # This file implements regression tests for SQLite library. # # This is a copy of the capi3.test file that has been adapted to # test the new sqlite3_prepare_v2 interface. # # $Id: capi3c.test,v 1.11 2007/08/29 12:31:29 danielk1977 Exp $ # set testdir [file dirname $argv0] source $testdir/tester.tcl # Return the UTF-16 representation of the supplied UTF-8 string $str. # If $nt is true, append two 0x00 bytes as a nul terminator. |
︙ | ︙ | |||
745 746 747 748 749 750 751 | } # Test the error message when a "real" out of memory occurs. if {[info command sqlite3_memdebug_fail]!=""} { do_test capi3c-10-1 { sqlite3 db test.db set DB [sqlite3_connection_pointer db] | | | | 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 | } # Test the error message when a "real" out of memory occurs. if {[info command sqlite3_memdebug_fail]!=""} { do_test capi3c-10-1 { sqlite3 db test.db set DB [sqlite3_connection_pointer db] sqlite3_memdebug_fail 0 catchsql { select * from sqlite_master; } } {1 {out of memory}} do_test capi3c-10-2 { sqlite3_errmsg $::DB } {out of memory} ifcapable {utf16} { do_test capi3c-10-3 { utf8 [sqlite3_errmsg16 $::DB] } {out of memory} } db close sqlite3_memdebug_fail -1 } # The following tests - capi3c-11.* - test that a COMMIT or ROLLBACK # statement issued while there are still outstanding VMs that are part of # the transaction fails. sqlite3 db test.db set DB [sqlite3_connection_pointer db] |
︙ | ︙ |
Changes to test/incrblob_err.test.
1 2 3 4 5 6 7 8 9 10 11 | # 2007 May 1 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | # 2007 May 1 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # # $Id: incrblob_err.test,v 1.6 2007/08/29 12:31:29 danielk1977 Exp $ # set testdir [file dirname $argv0] source $testdir/tester.tcl ifcapable {!incrblob || !memdebug} { finish_test |
︙ | ︙ | |||
75 76 77 78 79 80 81 | error "Bad data read..." } set rc [catch {close $::blob}] if {$rc} { error "out of memory" } } | | | 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 | error "Bad data read..." } set rc [catch {close $::blob}] if {$rc} { error "out of memory" } } sqlite3_memdebug_fail -1 do_ioerr_test incrblob_err-4 -cksum 1 -sqlprep { CREATE TABLE blobs(k, v BLOB); INSERT INTO blobs VALUES(1, $::data); } -tclbody { set ::blob [db incrblob blobs v 1] read $::blob |
︙ | ︙ |
Changes to test/malloc.test.
︙ | ︙ | |||
12 13 14 15 16 17 18 | # This file attempts to check the behavior of the SQLite library in # an out-of-memory situation. When compiled with -DSQLITE_DEBUG=1, # the SQLite library accepts a special command (sqlite3_memdebug_fail N C) # which causes the N-th malloc to fail. This special feature is used # to see what happens in the library if a malloc were to really fail # due to an out-of-memory situation. # | | | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | # This file attempts to check the behavior of the SQLite library in # an out-of-memory situation. When compiled with -DSQLITE_DEBUG=1, # the SQLite library accepts a special command (sqlite3_memdebug_fail N C) # which causes the N-th malloc to fail. This special feature is used # to see what happens in the library if a malloc were to really fail # due to an out-of-memory situation. # # $Id: malloc.test,v 1.45 2007/08/29 12:31:29 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl # Only run these tests if memory debugging is turned on. # ifcapable !memdebug { |
︙ | ︙ | |||
211 212 213 214 215 216 217 | } append ::bomstr [encoding convertto unicode "123456789_123456789_12345678"] } -tclbody { sqlite3_column_text16 $::STMT 0 sqlite3_column_int $::STMT 0 sqlite3_column_text16 $::STMT 1 sqlite3_column_double $::STMT 1 | | > | 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 | } append ::bomstr [encoding convertto unicode "123456789_123456789_12345678"] } -tclbody { sqlite3_column_text16 $::STMT 0 sqlite3_column_int $::STMT 0 sqlite3_column_text16 $::STMT 1 sqlite3_column_double $::STMT 1 set rc [sqlite3_reset $::STMT] if {$rc eq "SQLITE_NOMEM"} {error "out of memory"} sqlite3_bind_text16 $::STMT 1 $::bomstr 60 #catch {sqlite3_finalize $::STMT} #if {[lindex [sqlite_malloc_stat] 2]<=0} { # error "out of memory" #} } -cleanup { if {$::STMT!=""} { |
︙ | ︙ |
Changes to test/malloc2.test.
︙ | ︙ | |||
12 13 14 15 16 17 18 | # This file attempts to check that the library can recover from a malloc() # failure when sqlite3_global_recover() is invoked. # # (Later:) The sqlite3_global_recover() interface is now a no-op. # Recovery from malloc() failures is automatic. But we keep these # tests around because you can never have too many test cases. # | | | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | # This file attempts to check that the library can recover from a malloc() # failure when sqlite3_global_recover() is invoked. # # (Later:) The sqlite3_global_recover() interface is now a no-op. # Recovery from malloc() failures is automatic. But we keep these # tests around because you can never have too many test cases. # # $Id: malloc2.test,v 1.7 2007/08/29 12:31:29 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl # Only run these tests if memory debugging is turned on. # ifcapable !memdebug { |
︙ | ︙ | |||
61 62 63 64 65 66 67 | array set ::mallocopts $args set sum [cksum db] for {set ::n 1} {true} {incr ::n} { # Run the SQL. Malloc number $::n is set to fail. A malloc() failure # may or may not be reported. | | | | 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 | array set ::mallocopts $args set sum [cksum db] for {set ::n 1} {true} {incr ::n} { # Run the SQL. Malloc number $::n is set to fail. A malloc() failure # may or may not be reported. sqlite3_memdebug_fail $::n -repeat 1 do_test malloc2-$tn.$::n.2 { set res [catchsql [string trim $::mallocopts(-sql)]] set rc [expr { 0==[string compare $res {1 {out of memory}}] || 0==[lindex $res 0] }] if {$rc!=1} { puts "Error: $res" } set rc } {1} # If $::n is greater than the number of malloc() calls required to # execute the SQL, then this test is finished. Break out of the loop. set nFail [sqlite3_memdebug_fail -1] if {$nFail==0} break # Nothing should work now, because the allocator should refuse to # allocate any memory. # # Update: SQLite now automatically recovers from a malloc() failure. # So the statement in the test below would work. |
︙ | ︙ |
Changes to test/malloc3.test.
︙ | ︙ | |||
9 10 11 12 13 14 15 | # #*********************************************************************** # # This file contains tests to ensure that the library handles malloc() failures # correctly. The emphasis of these tests are the _prepare(), _step() and # _finalize() calls. # | | | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | # #*********************************************************************** # # This file contains tests to ensure that the library handles malloc() failures # correctly. The emphasis of these tests are the _prepare(), _step() and # _finalize() calls. # # $Id: malloc3.test,v 1.12 2007/08/29 12:31:29 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl # Only run these tests if memory debugging is turned on. # ifcapable !memdebug { |
︙ | ︙ | |||
556 557 558 559 560 561 562 | incr pc } -sql { set ::rollback_hook_count 0 set ac [sqlite3_get_autocommit $::DB] ;# Auto-Commit | | | | 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 | incr pc } -sql { set ::rollback_hook_count 0 set ac [sqlite3_get_autocommit $::DB] ;# Auto-Commit sqlite3_memdebug_fail $iFail -repeat 1 set rc [catch {db eval [lindex $v 1]} msg] ;# True error occurs set nac [sqlite3_get_autocommit $::DB] ;# New Auto-Commit if {$rc != 0 && $nac && !$ac} { # Before [db eval] the auto-commit flag was clear. Now it # is set. Since an error occured we assume this was not a # commit - therefore a rollback occured. Check that the # rollback-hook was invoked. do_test malloc3-rollback_hook.$iterid { set ::rollback_hook_count } {1} } set nFail [sqlite3_memdebug_fail -1] if {$rc == 0} { # Successful execution of sql. Our "mallocs-until-failure" # count should be greater than 0. Otherwise a malloc() failed # and the error was not reported. if {$nFail>0} { error "Unreported malloc() failure" } |
︙ | ︙ | |||
635 636 637 638 639 640 641 | } # Turn of the Tcl interface's prepared statement caching facility. db cache size 0 run_test $::run_test_script 9 1 # run_test [lrange $::run_test_script 0 3] 0 63 | | | 635 636 637 638 639 640 641 642 643 644 645 | } # Turn of the Tcl interface's prepared statement caching facility. db cache size 0 run_test $::run_test_script 9 1 # run_test [lrange $::run_test_script 0 3] 0 63 sqlite3_memdebug_fail -1 db close finish_test |
Changes to test/malloc4.test.
︙ | ︙ | |||
8 9 10 11 12 13 14 | # May you share freely, never taking more than you give. # #*********************************************************************** # # This file contains tests to ensure that the library handles malloc() failures # correctly. The emphasis in this file is on sqlite3_column_XXX() APIs. # | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | # May you share freely, never taking more than you give. # #*********************************************************************** # # This file contains tests to ensure that the library handles malloc() failures # correctly. The emphasis in this file is on sqlite3_column_XXX() APIs. # # $Id: malloc4.test,v 1.6 2007/08/29 12:31:29 danielk1977 Exp $ #--------------------------------------------------------------------------- # NOTES ON EXPECTED BEHAVIOUR # # [193] When a memory allocation failure occurs during sqlite3_column_name(), # sqlite3_column_name16(), sqlite3_column_decltype(), or # sqlite3_column_decltype16() the function shall return NULL. |
︙ | ︙ | |||
47 48 49 50 51 52 53 | # Prepare the statement do_test ${testid}.1 { set ::STMT [sqlite3_prepare $::DB $sql -1 TAIL] expr [string length $::STMT] > 0 } {1} # Set the Nth malloc() to fail. | | | 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | # Prepare the statement do_test ${testid}.1 { set ::STMT [sqlite3_prepare $::DB $sql -1 TAIL] expr [string length $::STMT] > 0 } {1} # Set the Nth malloc() to fail. sqlite3_memdebug_fail $n -repeat 1 # Test malloc failure in the _name(), _name16(), decltype() and # decltype16() APIs. Calls that occur after the malloc() failure should # return NULL. No error is raised though. # # ${testid}.2.1 - Call _name() # ${testid}.2.2 - Call _name16() |
︙ | ︙ |
Changes to test/mallocA.test.
1 2 3 4 5 6 7 8 9 10 11 12 | # 2007 April 30 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # This file contains additional out-of-memory checks (see malloc.tcl). # | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | # 2007 April 30 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # This file contains additional out-of-memory checks (see malloc.tcl). # # $Id: mallocA.test,v 1.4 2007/08/29 12:31:29 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl # Only run these tests if memory debugging is turned on. # ifcapable !memdebug { |
︙ | ︙ | |||
37 38 39 40 41 42 43 | CREATE INDEX t1i2 ON t1(b,c); CREATE TABLE t2(x,y,z); } db close file copy test.db test.db.bu | | | | | | | 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | CREATE INDEX t1i2 ON t1(b,c); CREATE TABLE t2(x,y,z); } db close file copy test.db test.db.bu do_malloc_test mallocA-1 -testdb test.db.bu -sqlbody { ANALYZE } do_malloc_test mallocA-2 -testdb test.db.bu -sqlbody { REINDEX; } do_malloc_test mallocA-3 -testdb test.db.bu -sqlbody { REINDEX t1; } do_malloc_test mallocA-4 -testdb test.db.bu -sqlbody { REINDEX main.t1; } do_malloc_test mallocA-5 -testdb test.db.bu -sqlbody { REINDEX nocase; } # Ensure that no file descriptors were leaked. do_test malloc-99.X { catch {db close} set sqlite_open_file_count } {0} file delete -force test.db.bu finish_test |
Changes to test/mallocC.test.
︙ | ︙ | |||
8 9 10 11 12 13 14 | # May you share freely, never taking more than you give. # #*********************************************************************** # # This file tests aspects of the malloc failure while parsing # CREATE TABLE statements in auto_vacuum mode. # | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | # May you share freely, never taking more than you give. # #*********************************************************************** # # This file tests aspects of the malloc failure while parsing # CREATE TABLE statements in auto_vacuum mode. # # $Id: mallocC.test,v 1.4 2007/08/29 12:31:29 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl # Only run these tests if memory debugging is turned on. # ifcapable !memdebug { |
︙ | ︙ | |||
57 58 59 60 61 62 63 | array set ::mallocopts $args set sum [cksum db] for {set ::n 1} {true} {incr ::n} { # Run the SQL. Malloc number $::n is set to fail. A malloc() failure # may or may not be reported. | | | | 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | array set ::mallocopts $args set sum [cksum db] for {set ::n 1} {true} {incr ::n} { # Run the SQL. Malloc number $::n is set to fail. A malloc() failure # may or may not be reported. sqlite3_memdebug_fail $::n -repeat 1 do_test mallocC-$tn.$::n.1 { set res [catchsql [string trim $::mallocopts(-sql)]] set rc [expr { 0==[string compare $res {1 {out of memory}}] || 0==[lindex $res 0] }] if {$rc!=1} { puts "Error: $res" } set rc } {1} # If $::n is greater than the number of malloc() calls required to # execute the SQL, then this test is finished. Break out of the loop. set nFail [sqlite3_memdebug_fail -1] if {$nFail==0} { break } # Recover from the malloc failure. # # Update: The new malloc() failure handling means that a transaction may |
︙ | ︙ |
Changes to test/malloc_common.tcl.
︙ | ︙ | |||
38 39 40 41 42 43 44 | } if {[info exists ::mallocopts(-start)]} { set start $::mallocopts(-start) } else { set start 1 } | > | | > > > > > > > > > | | | | > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | > > > > > > > | | > | > | > | | | | | | | | | | | | | | | | | | | | > | 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 | } if {[info exists ::mallocopts(-start)]} { set start $::mallocopts(-start) } else { set start 1 } foreach ::iRepeat {0 1} { set ::go 1 for {set ::n $start} {$::go && $::n < 50000} {incr ::n} { # If $::iRepeat is 0, then the malloc() failure is transient - it # fails and then subsequent calls succeed. If $::iRepeat is 1, # then the failure is persistent - once malloc() fails it keeps # failing. # set zRepeat "transient" if {$::iRepeat} {set zRepeat "persistent"} do_test ${tn}.${zRepeat}.${::n} { # Remove all traces of database files test.db and test2.db # from the file-system. Then open (empty database) "test.db" # with the handle [db]. # catch {db close} catch {file delete -force test.db} catch {file delete -force test.db-journal} catch {file delete -force test2.db} catch {file delete -force test2.db-journal} if {[info exists ::mallocopts(-testdb)]} { file copy $::mallocopts(-testdb) test.db } catch {sqlite3 db test.db} # Execute any -tclprep and -sqlprep scripts. # if {[info exists ::mallocopts(-tclprep)]} { eval $::mallocopts(-tclprep) } if {[info exists ::mallocopts(-sqlprep)]} { execsql $::mallocopts(-sqlprep) } # Now set the ${::n}th malloc() to fail and execute the -tclbody # and -sqlbody scripts. # sqlite3_memdebug_fail $::n -repeat $::iRepeat set ::mallocbody {} if {[info exists ::mallocopts(-tclbody)]} { append ::mallocbody "$::mallocopts(-tclbody)\n" } if {[info exists ::mallocopts(-sqlbody)]} { append ::mallocbody "db eval {$::mallocopts(-sqlbody)}" } # The following block sets local variables as follows: # # isFail - True if an error (any error) was reported by sqlite. # nFail - The total number of simulated malloc() failures. # nBenign - The number of benign simulated malloc() failures. # set isFail [catch $::mallocbody msg] set nFail [sqlite3_memdebug_fail -1 -benigncnt nBenign] #puts "isFail=$isFail nFail=$nFail nBenign=$nBenign msg=$msg" # If one or more mallocs failed, run this loop body again. # set go [expr {$nFail>0}] if {($nFail-$nBenign)==0} { if {$isFail} { set v2 $msg } else { set isFail 1 set v2 1 } } elseif {!$isFail} { set v2 $msg } elseif {[info command db]=="" || [db errorcode]==7 || $msg=="out of memory"} { set v2 1 } else { set v2 $msg } lappend isFail $v2 } {1 1} if {[info exists ::mallocopts(-cleanup)]} { catch [list uplevel #0 $::mallocopts(-cleanup)] msg } } } unset ::mallocopts } |
Changes to test/vtab_err.test.
1 2 3 4 5 6 7 8 9 10 11 | # 2006 June 10 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | # 2006 June 10 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # # $Id: vtab_err.test,v 1.7 2007/08/29 12:31:29 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl source $testdir/malloc_common.tcl ifcapable !vtab { |
︙ | ︙ | |||
36 37 38 39 40 41 42 | BEGIN; CREATE TABLE r2(a, b, c); INSERT INTO r2 SELECT * FROM e; INSERT INTO e SELECT a||'x', b, c FROM r2; COMMIT; } | | | | 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | BEGIN; CREATE TABLE r2(a, b, c); INSERT INTO r2 SELECT * FROM e; INSERT INTO e SELECT a||'x', b, c FROM r2; COMMIT; } do_malloc_test vtab_err-2 -tclprep { register_echo_module [sqlite3_connection_pointer db] } -sqlbody { BEGIN; CREATE TABLE r(a PRIMARY KEY, b, c); CREATE VIRTUAL TABLE e USING echo(r); INSERT INTO e VALUES(1, 2, 3); INSERT INTO e VALUES('a', 'b', 'c'); UPDATE e SET c = 10; DELETE FROM e WHERE a = 'a'; COMMIT; BEGIN; CREATE TABLE r2(a, b, c); INSERT INTO r2 SELECT * FROM e; INSERT INTO e SELECT a||'x', b, c FROM r2; COMMIT; } sqlite3_memdebug_fail -1 finish_test |