Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Merge the latest trunk changes into the sessions branch. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | sessions |
Files: | files | file ages | folders |
SHA1: |
83705e90a54bad462a5b7fbca70cc129 |
User & Date: | drh 2011-04-09 18:07:51.034 |
Context
2011-04-14
| ||
11:16 | Start adding the sqlite3changeset_concat() function to the session module. (check-in: 8927b2260b user: dan tags: sessions) | |
2011-04-09
| ||
18:07 | Merge the latest trunk changes into the sessions branch. (check-in: 83705e90a5 user: drh tags: sessions) | |
17:53 | Remove an always-true conditional. Replace it with an assert(). (check-in: 1c2f0f8477 user: drh tags: trunk) | |
2011-04-06
| ||
23:40 | Add a missing "extern C" terminator to the end of sqlite3session.h. (check-in: 29090b695a user: drh tags: sessions) | |
Changes
Changes to src/analyze.c.
︙ | ︙ | |||
544 545 546 547 548 549 550 551 552 553 554 555 556 557 | v = v*10 + c - '0'; z++; } if( i==0 ) pTable->nRowEst = v; if( pIndex==0 ) break; pIndex->aiRowEst[i] = v; if( *z==' ' ) z++; } return 0; } /* ** If the Index.aSample variable is not NULL, delete the aSample[] array ** and its contents. | > > > > | 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 | v = v*10 + c - '0'; z++; } if( i==0 ) pTable->nRowEst = v; if( pIndex==0 ) break; pIndex->aiRowEst[i] = v; if( *z==' ' ) z++; if( memcmp(z, "unordered", 10)==0 ){ pIndex->bUnordered = 1; break; } } return 0; } /* ** If the Index.aSample variable is not NULL, delete the aSample[] array ** and its contents. |
︙ | ︙ |
Changes to src/attach.c.
︙ | ︙ | |||
172 173 174 175 176 177 178 | zKey = (char *)sqlite3_value_blob(argv[2]); rc = sqlite3CodecAttach(db, db->nDb-1, zKey, nKey); break; case SQLITE_NULL: /* No key specified. Use the key from the main database */ sqlite3CodecGetKey(db, 0, (void**)&zKey, &nKey); | > | > | 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 | zKey = (char *)sqlite3_value_blob(argv[2]); rc = sqlite3CodecAttach(db, db->nDb-1, zKey, nKey); break; case SQLITE_NULL: /* No key specified. Use the key from the main database */ sqlite3CodecGetKey(db, 0, (void**)&zKey, &nKey); if( nKey>0 || sqlite3BtreeGetReserve(db->aDb[0].pBt)>0 ){ rc = sqlite3CodecAttach(db, db->nDb-1, zKey, nKey); } break; } } #endif /* If the file was opened successfully, read the schema for the new database. ** If this fails, or if opening the file failed, then close the file and |
︙ | ︙ |
Changes to src/backup.c.
︙ | ︙ | |||
215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 | */ static int backupOnePage(sqlite3_backup *p, Pgno iSrcPg, const u8 *zSrcData){ Pager * const pDestPager = sqlite3BtreePager(p->pDest); const int nSrcPgsz = sqlite3BtreeGetPageSize(p->pSrc); int nDestPgsz = sqlite3BtreeGetPageSize(p->pDest); const int nCopy = MIN(nSrcPgsz, nDestPgsz); const i64 iEnd = (i64)iSrcPg*(i64)nSrcPgsz; int rc = SQLITE_OK; i64 iOff; assert( p->bDestLocked ); assert( !isFatalError(p->rc) ); assert( iSrcPg!=PENDING_BYTE_PAGE(p->pSrc->pBt) ); assert( zSrcData ); /* Catch the case where the destination is an in-memory database and the ** page sizes of the source and destination differ. */ if( nSrcPgsz!=nDestPgsz && sqlite3PagerIsMemdb(pDestPager) ){ rc = SQLITE_READONLY; } #ifdef SQLITE_HAS_CODEC /* Backup is not possible if the page size of the destination is changing | > > > > | > > > > > > > > > > > | 215 216 217 218 219 220 221 222 223 224 225 226 227 228 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 | */ static int backupOnePage(sqlite3_backup *p, Pgno iSrcPg, const u8 *zSrcData){ Pager * const pDestPager = sqlite3BtreePager(p->pDest); const int nSrcPgsz = sqlite3BtreeGetPageSize(p->pSrc); int nDestPgsz = sqlite3BtreeGetPageSize(p->pDest); const int nCopy = MIN(nSrcPgsz, nDestPgsz); const i64 iEnd = (i64)iSrcPg*(i64)nSrcPgsz; #ifdef SQLITE_HAS_CODEC int nSrcReserve = sqlite3BtreeGetReserve(p->pSrc); int nDestReserve = sqlite3BtreeGetReserve(p->pDest); #endif int rc = SQLITE_OK; i64 iOff; assert( p->bDestLocked ); assert( !isFatalError(p->rc) ); assert( iSrcPg!=PENDING_BYTE_PAGE(p->pSrc->pBt) ); assert( zSrcData ); /* Catch the case where the destination is an in-memory database and the ** page sizes of the source and destination differ. */ if( nSrcPgsz!=nDestPgsz && sqlite3PagerIsMemdb(pDestPager) ){ rc = SQLITE_READONLY; } #ifdef SQLITE_HAS_CODEC /* Backup is not possible if the page size of the destination is changing ** and a codec is in use. */ if( nSrcPgsz!=nDestPgsz && sqlite3PagerGetCodec(pDestPager)!=0 ){ rc = SQLITE_READONLY; } /* Backup is not possible if the number of bytes of reserve space differ ** between source and destination. If there is a difference, try to ** fix the destination to agree with the source. If that is not possible, ** then the backup cannot proceed. */ if( nSrcReserve!=nDestReserve ){ u32 newPgsz = nSrcPgsz; rc = sqlite3PagerSetPagesize(pDestPager, &newPgsz, nSrcReserve); if( rc==SQLITE_OK && newPgsz!=nSrcPgsz ) rc = SQLITE_READONLY; } #endif /* This loop runs once for each destination page spanned by the source ** page. For each iteration, variable iOff is set to the byte offset ** of the destination page. */ for(iOff=iEnd-(i64)nSrcPgsz; rc==SQLITE_OK && iOff<iEnd; iOff+=nDestPgsz){ |
︙ | ︙ | |||
603 604 605 606 607 608 609 | for(p=pBackup; p; p=p->pNext){ assert( sqlite3_mutex_held(p->pSrc->pBt->mutex) ); if( !isFatalError(p->rc) && iPage<p->iNext ){ /* The backup process p has already copied page iPage. But now it ** has been modified by a transaction on the source pager. Copy ** the new data into the backup. */ | > > > | > | 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 | for(p=pBackup; p; p=p->pNext){ assert( sqlite3_mutex_held(p->pSrc->pBt->mutex) ); if( !isFatalError(p->rc) && iPage<p->iNext ){ /* The backup process p has already copied page iPage. But now it ** has been modified by a transaction on the source pager. Copy ** the new data into the backup. */ int rc; assert( p->pDestDb ); sqlite3_mutex_enter(p->pDestDb->mutex); rc = backupOnePage(p, iPage, aData); sqlite3_mutex_leave(p->pDestDb->mutex); assert( rc!=SQLITE_BUSY && rc!=SQLITE_LOCKED ); if( rc!=SQLITE_OK ){ p->rc = rc; } } } } |
︙ | ︙ |
Changes to src/btree.c.
︙ | ︙ | |||
4815 4816 4817 4818 4819 4820 4821 | rc = btreeGetPage(pBt, iTrunk, &pTrunk, 0); } if( rc ){ pTrunk = 0; goto end_allocate_page; } | | | 4815 4816 4817 4818 4819 4820 4821 4822 4823 4824 4825 4826 4827 4828 4829 | rc = btreeGetPage(pBt, iTrunk, &pTrunk, 0); } if( rc ){ pTrunk = 0; goto end_allocate_page; } k = get4byte(&pTrunk->aData[4]); /* # of leaves on this trunk page */ if( k==0 && !searchList ){ /* The trunk has no leaves and the list is not being searched. ** So extract the trunk page itself and use it as the newly ** allocated page */ assert( pPrevTrunk==0 ); rc = sqlite3PagerWrite(pTrunk->pDbPage); if( rc ){ |
︙ | ︙ | |||
4900 4901 4902 4903 4904 4905 4906 | TRACE(("ALLOCATE: %d trunk - %d free pages left\n", *pPgno, n-1)); #endif }else if( k>0 ){ /* Extract a leaf from the trunk */ u32 closest; Pgno iPage; unsigned char *aData = pTrunk->aData; | < < < < | 4900 4901 4902 4903 4904 4905 4906 4907 4908 4909 4910 4911 4912 4913 | TRACE(("ALLOCATE: %d trunk - %d free pages left\n", *pPgno, n-1)); #endif }else if( k>0 ){ /* Extract a leaf from the trunk */ u32 closest; Pgno iPage; unsigned char *aData = pTrunk->aData; if( nearby>0 ){ u32 i; int dist; closest = 0; dist = sqlite3AbsInt32(get4byte(&aData[8]) - nearby); for(i=1; i<k; i++){ int d2 = sqlite3AbsInt32(get4byte(&aData[8+i*4]) - nearby); |
︙ | ︙ | |||
4933 4934 4935 4936 4937 4938 4939 4940 4941 4942 4943 | testcase( iPage==mxPage ); if( !searchList || iPage==nearby ){ int noContent; *pPgno = iPage; TRACE(("ALLOCATE: %d was leaf %d of %d on trunk %d" ": %d more free pages\n", *pPgno, closest+1, k, pTrunk->pgno, n-1)); if( closest<k-1 ){ memcpy(&aData[8+closest*4], &aData[4+k*4], 4); } put4byte(&aData[4], k-1); | > > < | 4929 4930 4931 4932 4933 4934 4935 4936 4937 4938 4939 4940 4941 4942 4943 4944 4945 4946 4947 4948 | testcase( iPage==mxPage ); if( !searchList || iPage==nearby ){ int noContent; *pPgno = iPage; TRACE(("ALLOCATE: %d was leaf %d of %d on trunk %d" ": %d more free pages\n", *pPgno, closest+1, k, pTrunk->pgno, n-1)); rc = sqlite3PagerWrite(pTrunk->pDbPage); if( rc ) goto end_allocate_page; if( closest<k-1 ){ memcpy(&aData[8+closest*4], &aData[4+k*4], 4); } put4byte(&aData[4], k-1); noContent = !btreeGetHasContent(pBt, *pPgno); rc = btreeGetPage(pBt, *pPgno, ppPage, noContent); if( rc==SQLITE_OK ){ rc = sqlite3PagerWrite((*ppPage)->pDbPage); if( rc!=SQLITE_OK ){ releasePage(*ppPage); } |
︙ | ︙ | |||
5006 5007 5008 5009 5010 5011 5012 5013 5014 5015 5016 5017 5018 5019 | releasePage(*ppPage); return SQLITE_CORRUPT_BKPT; } (*ppPage)->isInit = 0; }else{ *ppPage = 0; } return rc; } /* ** This function is used to add page iPage to the database file free-list. ** It is assumed that the page is not already a part of the free-list. ** | > | 5003 5004 5005 5006 5007 5008 5009 5010 5011 5012 5013 5014 5015 5016 5017 | releasePage(*ppPage); return SQLITE_CORRUPT_BKPT; } (*ppPage)->isInit = 0; }else{ *ppPage = 0; } assert( rc!=SQLITE_OK || sqlite3PagerIswriteable((*ppPage)->pDbPage) ); return rc; } /* ** This function is used to add page iPage to the database file free-list. ** It is assumed that the page is not already a part of the free-list. ** |
︙ | ︙ |
Changes to src/build.c.
︙ | ︙ | |||
809 810 811 812 813 814 815 816 817 818 819 820 821 822 | if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){ goto begin_table_error; } pTable = sqlite3FindTable(db, zName, zDb); if( pTable ){ if( !noErr ){ sqlite3ErrorMsg(pParse, "table %T already exists", pName); } goto begin_table_error; } if( sqlite3FindIndex(db, zName, zDb)!=0 ){ sqlite3ErrorMsg(pParse, "there is already an index named %s", zName); goto begin_table_error; } | > > > | 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 | if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){ goto begin_table_error; } pTable = sqlite3FindTable(db, zName, zDb); if( pTable ){ if( !noErr ){ sqlite3ErrorMsg(pParse, "table %T already exists", pName); }else{ assert( !db->init.busy ); sqlite3CodeVerifySchema(pParse, iDb); } goto begin_table_error; } if( sqlite3FindIndex(db, zName, zDb)!=0 ){ sqlite3ErrorMsg(pParse, "there is already an index named %s", zName); goto begin_table_error; } |
︙ | ︙ | |||
1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 | assert( pName->nSrc==1 ); if( noErr ) db->suppressErr++; pTab = sqlite3LocateTable(pParse, isView, pName->a[0].zName, pName->a[0].zDatabase); if( noErr ) db->suppressErr--; if( pTab==0 ){ goto exit_drop_table; } iDb = sqlite3SchemaToIndex(db, pTab->pSchema); assert( iDb>=0 && iDb<db->nDb ); /* If pTab is a virtual table, call ViewGetColumnNames() to ensure ** it is initialized. | > | 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 | assert( pName->nSrc==1 ); if( noErr ) db->suppressErr++; pTab = sqlite3LocateTable(pParse, isView, pName->a[0].zName, pName->a[0].zDatabase); if( noErr ) db->suppressErr--; if( pTab==0 ){ if( noErr ) sqlite3CodeVerifyNamedSchema(pParse, pName->a[0].zDatabase); goto exit_drop_table; } iDb = sqlite3SchemaToIndex(db, pTab->pSchema); assert( iDb>=0 && iDb<db->nDb ); /* If pTab is a virtual table, call ViewGetColumnNames() to ensure ** it is initialized. |
︙ | ︙ | |||
2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 | sqlite3ErrorMsg(pParse, "there is already a table named %s", zName); goto exit_create_index; } } if( sqlite3FindIndex(db, zName, pDb->zName)!=0 ){ if( !ifNotExist ){ sqlite3ErrorMsg(pParse, "index %s already exists", zName); } goto exit_create_index; } }else{ int n; Index *pLoop; for(pLoop=pTab->pIndex, n=1; pLoop; pLoop=pLoop->pNext, n++){} | > > > | 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 | sqlite3ErrorMsg(pParse, "there is already a table named %s", zName); goto exit_create_index; } } if( sqlite3FindIndex(db, zName, pDb->zName)!=0 ){ if( !ifNotExist ){ sqlite3ErrorMsg(pParse, "index %s already exists", zName); }else{ assert( !db->init.busy ); sqlite3CodeVerifySchema(pParse, iDb); } goto exit_create_index; } }else{ int n; Index *pLoop; for(pLoop=pTab->pIndex, n=1; pLoop; pLoop=pLoop->pNext, n++){} |
︙ | ︙ | |||
2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 | if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){ goto exit_drop_index; } pIndex = sqlite3FindIndex(db, pName->a[0].zName, pName->a[0].zDatabase); if( pIndex==0 ){ if( !ifExists ){ sqlite3ErrorMsg(pParse, "no such index: %S", pName, 0); } pParse->checkSchema = 1; goto exit_drop_index; } if( pIndex->autoIndex ){ sqlite3ErrorMsg(pParse, "index associated with UNIQUE " "or PRIMARY KEY constraint cannot be dropped", 0); | > > | 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 | if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){ goto exit_drop_index; } pIndex = sqlite3FindIndex(db, pName->a[0].zName, pName->a[0].zDatabase); if( pIndex==0 ){ if( !ifExists ){ sqlite3ErrorMsg(pParse, "no such index: %S", pName, 0); }else{ sqlite3CodeVerifyNamedSchema(pParse, pName->a[0].zDatabase); } pParse->checkSchema = 1; goto exit_drop_index; } if( pIndex->autoIndex ){ sqlite3ErrorMsg(pParse, "index associated with UNIQUE " "or PRIMARY KEY constraint cannot be dropped", 0); |
︙ | ︙ | |||
3495 3496 3497 3498 3499 3500 3501 3502 3503 3504 3505 3506 3507 3508 | pToplevel->cookieValue[iDb] = db->aDb[iDb].pSchema->schema_cookie; if( !OMIT_TEMPDB && iDb==1 ){ sqlite3OpenTempDatabase(pToplevel); } } } } /* ** Generate VDBE code that prepares for doing an operation that ** might change the database. ** ** This routine starts a new transaction if we are not already within ** a transaction. If we are already within a transaction, then a checkpoint | > > > > > > > > > > > > > > > | 3504 3505 3506 3507 3508 3509 3510 3511 3512 3513 3514 3515 3516 3517 3518 3519 3520 3521 3522 3523 3524 3525 3526 3527 3528 3529 3530 3531 3532 | pToplevel->cookieValue[iDb] = db->aDb[iDb].pSchema->schema_cookie; if( !OMIT_TEMPDB && iDb==1 ){ sqlite3OpenTempDatabase(pToplevel); } } } } /* ** If argument zDb is NULL, then call sqlite3CodeVerifySchema() for each ** attached database. Otherwise, invoke it for the database named zDb only. */ void sqlite3CodeVerifyNamedSchema(Parse *pParse, const char *zDb){ sqlite3 *db = pParse->db; int i; for(i=0; i<db->nDb; i++){ Db *pDb = &db->aDb[i]; if( pDb->pBt && (!zDb || 0==sqlite3StrICmp(zDb, pDb->zName)) ){ sqlite3CodeVerifySchema(pParse, i); } } } /* ** Generate VDBE code that prepares for doing an operation that ** might change the database. ** ** This routine starts a new transaction if we are not already within ** a transaction. If we are already within a transaction, then a checkpoint |
︙ | ︙ |
Changes to src/ctime.c.
︙ | ︙ | |||
298 299 300 301 302 303 304 | #endif #ifdef SQLITE_OMIT_TRIGGER "OMIT_TRIGGER", #endif #ifdef SQLITE_OMIT_TRUNCATE_OPTIMIZATION "OMIT_TRUNCATE_OPTIMIZATION", #endif | < < < | 298 299 300 301 302 303 304 305 306 307 308 309 310 311 | #endif #ifdef SQLITE_OMIT_TRIGGER "OMIT_TRIGGER", #endif #ifdef SQLITE_OMIT_TRUNCATE_OPTIMIZATION "OMIT_TRUNCATE_OPTIMIZATION", #endif #ifdef SQLITE_OMIT_UTF16 "OMIT_UTF16", #endif #ifdef SQLITE_OMIT_VACUUM "OMIT_VACUUM", #endif #ifdef SQLITE_OMIT_VIEW |
︙ | ︙ |
Changes to src/insert.c.
︙ | ︙ | |||
1318 1319 1320 1321 1322 1323 1324 | /* Test all UNIQUE constraints by creating entries for each UNIQUE ** index and making sure that duplicate entries do not already exist. ** Add the new records to the indices as we go. */ for(iCur=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, iCur++){ int regIdx; | < | < < < < < | 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 | /* Test all UNIQUE constraints by creating entries for each UNIQUE ** index and making sure that duplicate entries do not already exist. ** Add the new records to the indices as we go. */ for(iCur=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, iCur++){ int regIdx; int regR; if( aRegIdx[iCur]==0 ) continue; /* Skip unused indices */ /* Create a key for accessing the index entry */ regIdx = sqlite3GetTempRange(pParse, pIdx->nColumn+1); for(i=0; i<pIdx->nColumn; i++){ int idx = pIdx->aiColumn[i]; if( idx==pTab->iPKey ){ sqlite3VdbeAddOp2(v, OP_SCopy, regRowid, regIdx+i); }else{ sqlite3VdbeAddOp2(v, OP_SCopy, regData+idx, regIdx+i); } } sqlite3VdbeAddOp2(v, OP_SCopy, regRowid, regIdx+i); sqlite3VdbeAddOp3(v, OP_MakeRecord, regIdx, pIdx->nColumn+1, aRegIdx[iCur]); sqlite3VdbeChangeP4(v, -1, sqlite3IndexAffinityStr(v, pIdx), P4_TRANSIENT); sqlite3ExprCacheAffinityChange(pParse, regIdx, pIdx->nColumn+1); /* Find out what action to take in case there is an indexing conflict */ onError = pIdx->onError; if( onError==OE_None ){ sqlite3ReleaseTempRange(pParse, regIdx, pIdx->nColumn+1); continue; /* pIdx is not a UNIQUE index */ } if( overrideError!=OE_Default ){ |
︙ | ︙ | |||
1416 1417 1418 1419 1420 1421 1422 | ); seenReplace = 1; break; } } sqlite3VdbeJumpHere(v, j3); sqlite3ReleaseTempReg(pParse, regR); | < | 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 | ); seenReplace = 1; break; } } sqlite3VdbeJumpHere(v, j3); sqlite3ReleaseTempReg(pParse, regR); } if( pbMayReplace ){ *pbMayReplace = seenReplace; } } |
︙ | ︙ |
Changes to src/main.c.
︙ | ︙ | |||
511 512 513 514 515 516 517 | */ int sqlite3_db_config(sqlite3 *db, int op, ...){ va_list ap; int rc; va_start(ap, op); switch( op ){ case SQLITE_DBCONFIG_LOOKASIDE: { | | | 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 | */ int sqlite3_db_config(sqlite3 *db, int op, ...){ va_list ap; int rc; va_start(ap, op); switch( op ){ case SQLITE_DBCONFIG_LOOKASIDE: { void *pBuf = va_arg(ap, void*); /* IMP: R-26835-10964 */ int sz = va_arg(ap, int); /* IMP: R-47871-25994 */ int cnt = va_arg(ap, int); /* IMP: R-04460-53386 */ rc = setupLookaside(db, pBuf, sz, cnt); break; } default: { static const struct { |
︙ | ︙ |
Changes to src/prepare.c.
︙ | ︙ | |||
30 31 32 33 34 35 36 | sqlite3SetString(pData->pzErrMsg, db, "malformed database schema (%s)", zObj); if( zExtra ){ *pData->pzErrMsg = sqlite3MAppendf(db, *pData->pzErrMsg, "%s - %s", *pData->pzErrMsg, zExtra); } } | | | 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | sqlite3SetString(pData->pzErrMsg, db, "malformed database schema (%s)", zObj); if( zExtra ){ *pData->pzErrMsg = sqlite3MAppendf(db, *pData->pzErrMsg, "%s - %s", *pData->pzErrMsg, zExtra); } } pData->rc = db->mallocFailed ? SQLITE_NOMEM : SQLITE_CORRUPT_BKPT; } /* ** This is the callback routine for the code that initializes the ** database. See sqlite3Init() below for additional information. ** This routine is also called from the OP_ParseSchema opcode of the VDBE. ** |
︙ | ︙ |
Changes to src/shell.c.
︙ | ︙ | |||
2195 2196 2197 2198 2199 2200 2201 | int testctrl = -1; int rc = 0; int i, n; open_db(p); /* convert testctrl text option to value. allow any unique prefix ** of the option name, or a numerical value. */ | | | 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 | int testctrl = -1; int rc = 0; int i, n; open_db(p); /* convert testctrl text option to value. allow any unique prefix ** of the option name, or a numerical value. */ n = strlen30(azArg[1]); for(i=0; i<(int)(sizeof(aCtrl)/sizeof(aCtrl[0])); i++){ if( strncmp(azArg[1], aCtrl[i].zCtrlName, n)==0 ){ if( testctrl<0 ){ testctrl = aCtrl[i].ctrlCode; }else{ fprintf(stderr, "ambiguous option name: \"%s\"\n", azArg[i]); testctrl = -1; |
︙ | ︙ |
Changes to src/sqlite.h.in.
︙ | ︙ | |||
723 724 725 726 727 728 729 | ** ^(The [SQLITE_FCNTL_SYNC_OMITTED] opcode is generated internally by ** SQLite and sent to all VFSes in place of a call to the xSync method ** when the database connection has [PRAGMA synchronous] set to OFF.)^ ** Some specialized VFSes need this signal in order to operate correctly ** when [PRAGMA synchronous | PRAGMA synchronous=OFF] is set, but most ** VFSes do not need this signal and should silently ignore this opcode. ** Applications should not call [sqlite3_file_control()] with this | | | 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 | ** ^(The [SQLITE_FCNTL_SYNC_OMITTED] opcode is generated internally by ** SQLite and sent to all VFSes in place of a call to the xSync method ** when the database connection has [PRAGMA synchronous] set to OFF.)^ ** Some specialized VFSes need this signal in order to operate correctly ** when [PRAGMA synchronous | PRAGMA synchronous=OFF] is set, but most ** VFSes do not need this signal and should silently ignore this opcode. ** Applications should not call [sqlite3_file_control()] with this ** opcode as doing so may disrupt the operation of the specialized VFSes ** that do require it. */ #define SQLITE_FCNTL_LOCKSTATE 1 #define SQLITE_GET_LOCKPROXYFILE 2 #define SQLITE_SET_LOCKPROXYFILE 3 #define SQLITE_LAST_ERRNO 4 #define SQLITE_FCNTL_SIZE_HINT 5 |
︙ | ︙ | |||
1305 1306 1307 1308 1309 1310 1311 | ** compiled with [SQLITE_DEFAULT_MEMSTATUS]=0 in which case memory ** allocation statistics are disabled by default. ** </dd> ** ** <dt>SQLITE_CONFIG_SCRATCH</dt> ** <dd> ^This option specifies a static memory buffer that SQLite can use for ** scratch memory. There are three arguments: A pointer an 8-byte | | | 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 | ** compiled with [SQLITE_DEFAULT_MEMSTATUS]=0 in which case memory ** allocation statistics are disabled by default. ** </dd> ** ** <dt>SQLITE_CONFIG_SCRATCH</dt> ** <dd> ^This option specifies a static memory buffer that SQLite can use for ** scratch memory. There are three arguments: A pointer an 8-byte ** aligned memory buffer from which the scratch allocations will be ** drawn, the size of each scratch allocation (sz), ** and the maximum number of scratch allocations (N). The sz ** argument must be a multiple of 16. ** The first argument must be a pointer to an 8-byte aligned buffer ** of at least sz*N bytes of memory. ** ^SQLite will use no more than two scratch buffers per thread. So ** N should be set to twice the expected maximum number of threads. |
︙ | ︙ | |||
1457 1458 1459 1460 1461 1462 1463 | ** is invoked. ** ** <dl> ** <dt>SQLITE_DBCONFIG_LOOKASIDE</dt> ** <dd> ^This option takes three additional arguments that determine the ** [lookaside memory allocator] configuration for the [database connection]. ** ^The first argument (the third parameter to [sqlite3_db_config()] is a | | | 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 | ** is invoked. ** ** <dl> ** <dt>SQLITE_DBCONFIG_LOOKASIDE</dt> ** <dd> ^This option takes three additional arguments that determine the ** [lookaside memory allocator] configuration for the [database connection]. ** ^The first argument (the third parameter to [sqlite3_db_config()] is a ** pointer to a memory buffer to use for lookaside memory. ** ^The first argument after the SQLITE_DBCONFIG_LOOKASIDE verb ** may be NULL in which case SQLite will allocate the ** lookaside buffer itself using [sqlite3_malloc()]. ^The second argument is the ** size of each lookaside buffer slot. ^The third argument is the number of ** slots. The size of the buffer in the first argument must be greater than ** or equal to the product of the second and third arguments. The buffer ** must be aligned to an 8-byte boundary. ^If the second argument to |
︙ | ︙ | |||
1489 1490 1491 1492 1493 1494 1495 | ** following this call. The second parameter may be a NULL pointer, in ** which case the FK enforcement setting is not reported back. </dd> ** ** <dt>SQLITE_DBCONFIG_ENABLE_TRIGGER</dt> ** <dd> ^This option is used to enable or disable [CREATE TRIGGER | triggers]. ** There should be two additional arguments. ** The first argument is an integer which is 0 to disable triggers, | | | 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 | ** following this call. The second parameter may be a NULL pointer, in ** which case the FK enforcement setting is not reported back. </dd> ** ** <dt>SQLITE_DBCONFIG_ENABLE_TRIGGER</dt> ** <dd> ^This option is used to enable or disable [CREATE TRIGGER | triggers]. ** There should be two additional arguments. ** The first argument is an integer which is 0 to disable triggers, ** positive to enable triggers or negative to leave the setting unchanged. ** The second parameter is a pointer to an integer into which ** is written 0 or 1 to indicate whether triggers are disabled or enabled ** following this call. The second parameter may be a NULL pointer, in ** which case the trigger setting is not reported back. </dd> ** ** </dl> */ |
︙ | ︙ | |||
2101 2102 2103 2104 2105 2106 2107 | ** method. */ void sqlite3_randomness(int N, void *P); /* ** CAPI3REF: Compile-Time Authorization Callbacks ** | | | 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 | ** method. */ void sqlite3_randomness(int N, void *P); /* ** CAPI3REF: Compile-Time Authorization Callbacks ** ** ^This routine registers an authorizer callback with a particular ** [database connection], supplied in the first argument. ** ^The authorizer callback is invoked as SQL statements are being compiled ** by [sqlite3_prepare()] or its variants [sqlite3_prepare_v2()], ** [sqlite3_prepare16()] and [sqlite3_prepare16_v2()]. ^At various ** points during the compilation process, as logic is being created ** to perform various actions, the authorizer callback is invoked to ** see if those actions are allowed. ^The authorizer callback should |
︙ | ︙ | |||
2747 2748 2749 2750 2751 2752 2753 | ** An sqlite3_value object may be either "protected" or "unprotected". ** Some interfaces require a protected sqlite3_value. Other interfaces ** will accept either a protected or an unprotected sqlite3_value. ** Every interface that accepts sqlite3_value arguments specifies ** whether or not it requires a protected sqlite3_value. ** ** The terms "protected" and "unprotected" refer to whether or not | | | 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 | ** An sqlite3_value object may be either "protected" or "unprotected". ** Some interfaces require a protected sqlite3_value. Other interfaces ** will accept either a protected or an unprotected sqlite3_value. ** Every interface that accepts sqlite3_value arguments specifies ** whether or not it requires a protected sqlite3_value. ** ** The terms "protected" and "unprotected" refer to whether or not ** a mutex is held. An internal mutex is held for a protected ** sqlite3_value object but no mutex is held for an unprotected ** sqlite3_value object. If SQLite is compiled to be single-threaded ** (with [SQLITE_THREADSAFE=0] and with [sqlite3_threadsafe()] returning 0) ** or if SQLite is run in one of reduced mutex modes ** [SQLITE_CONFIG_SINGLETHREAD] or [SQLITE_CONFIG_MULTITHREAD] ** then there is no distinction between protected and unprotected ** sqlite3_value objects and they can be used interchangeably. However, |
︙ | ︙ | |||
3433 3434 3435 3436 3437 3438 3439 | ** KEYWORDS: {application-defined SQL function} ** KEYWORDS: {application-defined SQL functions} ** ** ^These functions (collectively known as "function creation routines") ** are used to add SQL functions or aggregates or to redefine the behavior ** of existing SQL functions or aggregates. The only differences between ** these routines are the text encoding expected for | | | 3433 3434 3435 3436 3437 3438 3439 3440 3441 3442 3443 3444 3445 3446 3447 | ** KEYWORDS: {application-defined SQL function} ** KEYWORDS: {application-defined SQL functions} ** ** ^These functions (collectively known as "function creation routines") ** are used to add SQL functions or aggregates or to redefine the behavior ** of existing SQL functions or aggregates. The only differences between ** these routines are the text encoding expected for ** the second parameter (the name of the function being created) ** and the presence or absence of a destructor callback for ** the application data pointer. ** ** ^The first parameter is the [database connection] to which the SQL ** function is to be added. ^If an application uses more than one database ** connection then application-defined SQL functions must be added ** to each database connection separately. |
︙ | ︙ | |||
3478 3479 3480 3481 3482 3483 3484 | ** ** ^The sixth, seventh and eighth parameters, xFunc, xStep and xFinal, are ** pointers to C-language functions that implement the SQL function or ** aggregate. ^A scalar SQL function requires an implementation of the xFunc ** callback only; NULL pointers must be passed as the xStep and xFinal ** parameters. ^An aggregate SQL function requires an implementation of xStep ** and xFinal and NULL pointer must be passed for xFunc. ^To delete an existing | | | 3478 3479 3480 3481 3482 3483 3484 3485 3486 3487 3488 3489 3490 3491 3492 | ** ** ^The sixth, seventh and eighth parameters, xFunc, xStep and xFinal, are ** pointers to C-language functions that implement the SQL function or ** aggregate. ^A scalar SQL function requires an implementation of the xFunc ** callback only; NULL pointers must be passed as the xStep and xFinal ** parameters. ^An aggregate SQL function requires an implementation of xStep ** and xFinal and NULL pointer must be passed for xFunc. ^To delete an existing ** SQL function or aggregate, pass NULL pointers for all three function ** callbacks. ** ** ^(If the ninth parameter to sqlite3_create_function_v2() is not NULL, ** then it is destructor for the application data pointer. ** The destructor is invoked when the function is deleted, either by being ** overloaded or when the database connection closes.)^ ** ^The destructor is also invoked if the call to |
︙ | ︙ | |||
3912 3913 3914 3915 3916 3917 3918 | ** ^The eTextRep argument determines the encoding of strings passed ** to the collating function callback, xCallback. ** ^The [SQLITE_UTF16] and [SQLITE_UTF16_ALIGNED] values for eTextRep ** force strings to be UTF16 with native byte order. ** ^The [SQLITE_UTF16_ALIGNED] value for eTextRep forces strings to begin ** on an even byte address. ** | | | | 3912 3913 3914 3915 3916 3917 3918 3919 3920 3921 3922 3923 3924 3925 3926 3927 3928 3929 3930 3931 3932 3933 3934 3935 3936 3937 3938 3939 3940 3941 3942 | ** ^The eTextRep argument determines the encoding of strings passed ** to the collating function callback, xCallback. ** ^The [SQLITE_UTF16] and [SQLITE_UTF16_ALIGNED] values for eTextRep ** force strings to be UTF16 with native byte order. ** ^The [SQLITE_UTF16_ALIGNED] value for eTextRep forces strings to begin ** on an even byte address. ** ** ^The fourth argument, pArg, is an application data pointer that is passed ** through as the first argument to the collating function callback. ** ** ^The fifth argument, xCallback, is a pointer to the collating function. ** ^Multiple collating functions can be registered using the same name but ** with different eTextRep parameters and SQLite will use whichever ** function requires the least amount of data transformation. ** ^If the xCallback argument is NULL then the collating function is ** deleted. ^When all collating functions having the same name are deleted, ** that collation is no longer usable. ** ** ^The collating function callback is invoked with a copy of the pArg ** application data pointer and with two strings in the encoding specified ** by the eTextRep argument. The collating function must return an ** integer that is negative, zero, or positive ** if the first string is less than, equal to, or greater than the second, ** respectively. A collating function must always return the same answer ** given the same inputs. If two or more collating functions are registered ** to the same collation name (using different eTextRep values) then all ** must give an equivalent answer when invoked with equivalent strings. ** The collating function must obey the following properties for all ** strings A, B, and C: ** ** <ol> |
︙ | ︙ | |||
4340 4341 4342 4343 4344 4345 4346 | ** if one or more of following conditions are true: ** ** <ul> ** <li> The soft heap limit is set to zero. ** <li> Memory accounting is disabled using a combination of the ** [sqlite3_config]([SQLITE_CONFIG_MEMSTATUS],...) start-time option and ** the [SQLITE_DEFAULT_MEMSTATUS] compile-time option. | | | 4340 4341 4342 4343 4344 4345 4346 4347 4348 4349 4350 4351 4352 4353 4354 | ** if one or more of following conditions are true: ** ** <ul> ** <li> The soft heap limit is set to zero. ** <li> Memory accounting is disabled using a combination of the ** [sqlite3_config]([SQLITE_CONFIG_MEMSTATUS],...) start-time option and ** the [SQLITE_DEFAULT_MEMSTATUS] compile-time option. ** <li> An alternative page cache implementation is specified using ** [sqlite3_config]([SQLITE_CONFIG_PCACHE],...). ** <li> The page cache allocates from its own memory pool supplied ** by [sqlite3_config]([SQLITE_CONFIG_PAGECACHE],...) rather than ** from the heap. ** </ul>)^ ** ** Beginning with SQLite version 3.7.3, the soft heap limit is enforced |
︙ | ︙ | |||
4561 4562 4563 4564 4565 4566 4567 | typedef struct sqlite3_vtab_cursor sqlite3_vtab_cursor; typedef struct sqlite3_module sqlite3_module; /* ** CAPI3REF: Virtual Table Object ** KEYWORDS: sqlite3_module {virtual table module} ** | | | 4561 4562 4563 4564 4565 4566 4567 4568 4569 4570 4571 4572 4573 4574 4575 | typedef struct sqlite3_vtab_cursor sqlite3_vtab_cursor; typedef struct sqlite3_module sqlite3_module; /* ** CAPI3REF: Virtual Table Object ** KEYWORDS: sqlite3_module {virtual table module} ** ** This structure, sometimes called a "virtual table module", ** defines the implementation of a [virtual tables]. ** This structure consists mostly of methods for the module. ** ** ^A virtual table module is created by filling in a persistent ** instance of this structure and passing a pointer to that instance ** to [sqlite3_create_module()] or [sqlite3_create_module_v2()]. ** ^The registration remains valid until it is replaced by a different |
︙ | ︙ | |||
4873 4874 4875 4876 4877 4878 4879 | ** ** ^(If the row that a BLOB handle points to is modified by an ** [UPDATE], [DELETE], or by [ON CONFLICT] side-effects ** then the BLOB handle is marked as "expired". ** This is true if any column of the row is changed, even a column ** other than the one the BLOB handle is open on.)^ ** ^Calls to [sqlite3_blob_read()] and [sqlite3_blob_write()] for | | | 4873 4874 4875 4876 4877 4878 4879 4880 4881 4882 4883 4884 4885 4886 4887 | ** ** ^(If the row that a BLOB handle points to is modified by an ** [UPDATE], [DELETE], or by [ON CONFLICT] side-effects ** then the BLOB handle is marked as "expired". ** This is true if any column of the row is changed, even a column ** other than the one the BLOB handle is open on.)^ ** ^Calls to [sqlite3_blob_read()] and [sqlite3_blob_write()] for ** an expired BLOB handle fail with a return code of [SQLITE_ABORT]. ** ^(Changes written into a BLOB prior to the BLOB expiring are not ** rolled back by the expiration of the BLOB. Such changes will eventually ** commit if the transaction continues to completion.)^ ** ** ^Use the [sqlite3_blob_bytes()] interface to determine the size of ** the opened blob. ^The size of a blob may not be changed by this ** interface. Use the [UPDATE] SQL command to change the size of a |
︙ | ︙ |
Changes to src/sqliteInt.h.
︙ | ︙ | |||
1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 | int nColumn; /* Number of columns in the table used by this index */ int *aiColumn; /* Which columns are used by this index. 1st is 0 */ unsigned *aiRowEst; /* Result of ANALYZE: Est. rows selected by each column */ Table *pTable; /* The SQL table being indexed */ int tnum; /* Page containing root of this index in database file */ u8 onError; /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */ u8 autoIndex; /* True if is automatically created (ex: by UNIQUE) */ char *zColAff; /* String defining the affinity of each column */ Index *pNext; /* The next index associated with the same table */ Schema *pSchema; /* Schema containing this index */ u8 *aSortOrder; /* Array of size Index.nColumn. True==DESC, False==ASC */ char **azColl; /* Array of collation sequence names for index */ IndexSample *aSample; /* Array of SQLITE_INDEX_SAMPLES samples */ }; | > | 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 | int nColumn; /* Number of columns in the table used by this index */ int *aiColumn; /* Which columns are used by this index. 1st is 0 */ unsigned *aiRowEst; /* Result of ANALYZE: Est. rows selected by each column */ Table *pTable; /* The SQL table being indexed */ int tnum; /* Page containing root of this index in database file */ u8 onError; /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */ u8 autoIndex; /* True if is automatically created (ex: by UNIQUE) */ u8 bUnordered; /* Use this index for == or IN queries only */ char *zColAff; /* String defining the affinity of each column */ Index *pNext; /* The next index associated with the same table */ Schema *pSchema; /* Schema containing this index */ u8 *aSortOrder; /* Array of size Index.nColumn. True==DESC, False==ASC */ char **azColl; /* Array of collation sequence names for index */ IndexSample *aSample; /* Array of SQLITE_INDEX_SAMPLES samples */ }; |
︙ | ︙ | |||
2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 | void sqlite3ExprAnalyzeAggList(NameContext*,ExprList*); Vdbe *sqlite3GetVdbe(Parse*); void sqlite3PrngSaveState(void); void sqlite3PrngRestoreState(void); void sqlite3PrngResetState(void); void sqlite3RollbackAll(sqlite3*); void sqlite3CodeVerifySchema(Parse*, int); void sqlite3BeginTransaction(Parse*, int); void sqlite3CommitTransaction(Parse*); void sqlite3RollbackTransaction(Parse*); void sqlite3Savepoint(Parse*, int, Token*); void sqlite3CloseSavepoints(sqlite3 *); int sqlite3ExprIsConstant(Expr*); int sqlite3ExprIsConstantNotJoin(Expr*); | > | 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 | void sqlite3ExprAnalyzeAggList(NameContext*,ExprList*); Vdbe *sqlite3GetVdbe(Parse*); void sqlite3PrngSaveState(void); void sqlite3PrngRestoreState(void); void sqlite3PrngResetState(void); void sqlite3RollbackAll(sqlite3*); void sqlite3CodeVerifySchema(Parse*, int); void sqlite3CodeVerifyNamedSchema(Parse*, const char *zDb); void sqlite3BeginTransaction(Parse*, int); void sqlite3CommitTransaction(Parse*); void sqlite3RollbackTransaction(Parse*); void sqlite3Savepoint(Parse*, int, Token*); void sqlite3CloseSavepoints(sqlite3 *); int sqlite3ExprIsConstant(Expr*); int sqlite3ExprIsConstantNotJoin(Expr*); |
︙ | ︙ |
Changes to src/test_config.c.
︙ | ︙ | |||
92 93 94 95 96 97 98 99 100 101 102 103 104 105 | #endif #ifdef SQLITE_MUTEX_OMIT Tcl_SetVar2(interp, "sqlite_options", "mutex", "0", TCL_GLOBAL_ONLY); #else Tcl_SetVar2(interp, "sqlite_options", "mutex", "1", TCL_GLOBAL_ONLY); #endif #ifdef SQLITE_OMIT_ALTERTABLE Tcl_SetVar2(interp, "sqlite_options", "altertable", "0", TCL_GLOBAL_ONLY); #else Tcl_SetVar2(interp, "sqlite_options", "altertable", "1", TCL_GLOBAL_ONLY); #endif | > > > > > > | 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 | #endif #ifdef SQLITE_MUTEX_OMIT Tcl_SetVar2(interp, "sqlite_options", "mutex", "0", TCL_GLOBAL_ONLY); #else Tcl_SetVar2(interp, "sqlite_options", "mutex", "1", TCL_GLOBAL_ONLY); #endif #ifdef SQLITE_MUTEX_NOOP Tcl_SetVar2(interp, "sqlite_options", "mutex_noop", "1", TCL_GLOBAL_ONLY); #else Tcl_SetVar2(interp, "sqlite_options", "mutex_noop", "0", TCL_GLOBAL_ONLY); #endif #ifdef SQLITE_OMIT_ALTERTABLE Tcl_SetVar2(interp, "sqlite_options", "altertable", "0", TCL_GLOBAL_ONLY); #else Tcl_SetVar2(interp, "sqlite_options", "altertable", "1", TCL_GLOBAL_ONLY); #endif |
︙ | ︙ | |||
483 484 485 486 487 488 489 | #ifdef SQLITE_OMIT_TRUNCATE_OPTIMIZATION Tcl_SetVar2(interp, "sqlite_options", "truncate_opt", "0", TCL_GLOBAL_ONLY); #else Tcl_SetVar2(interp, "sqlite_options", "truncate_opt", "1", TCL_GLOBAL_ONLY); #endif | < < < < < < | 489 490 491 492 493 494 495 496 497 498 499 500 501 502 | #ifdef SQLITE_OMIT_TRUNCATE_OPTIMIZATION Tcl_SetVar2(interp, "sqlite_options", "truncate_opt", "0", TCL_GLOBAL_ONLY); #else Tcl_SetVar2(interp, "sqlite_options", "truncate_opt", "1", TCL_GLOBAL_ONLY); #endif #ifdef SQLITE_OMIT_UTF16 Tcl_SetVar2(interp, "sqlite_options", "utf16", "0", TCL_GLOBAL_ONLY); #else Tcl_SetVar2(interp, "sqlite_options", "utf16", "1", TCL_GLOBAL_ONLY); #endif #if defined(SQLITE_OMIT_VACUUM) || defined(SQLITE_OMIT_ATTACH) |
︙ | ︙ |
Changes to src/trigger.c.
︙ | ︙ | |||
167 168 169 170 171 172 173 174 175 176 177 178 179 180 | goto trigger_cleanup; } assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); if( sqlite3HashFind(&(db->aDb[iDb].pSchema->trigHash), zName, sqlite3Strlen30(zName)) ){ if( !noErr ){ sqlite3ErrorMsg(pParse, "trigger %T already exists", pName); } goto trigger_cleanup; } /* Do not create a trigger on a system table */ if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0 ){ sqlite3ErrorMsg(pParse, "cannot create trigger on system table"); | > > > | 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 | goto trigger_cleanup; } assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); if( sqlite3HashFind(&(db->aDb[iDb].pSchema->trigHash), zName, sqlite3Strlen30(zName)) ){ if( !noErr ){ sqlite3ErrorMsg(pParse, "trigger %T already exists", pName); }else{ assert( !db->init.busy ); sqlite3CodeVerifySchema(pParse, iDb); } goto trigger_cleanup; } /* Do not create a trigger on a system table */ if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0 ){ sqlite3ErrorMsg(pParse, "cannot create trigger on system table"); |
︙ | ︙ | |||
495 496 497 498 499 500 501 502 503 504 505 506 507 508 | assert( sqlite3SchemaMutexHeld(db, j, 0) ); pTrigger = sqlite3HashFind(&(db->aDb[j].pSchema->trigHash), zName, nName); if( pTrigger ) break; } if( !pTrigger ){ if( !noErr ){ sqlite3ErrorMsg(pParse, "no such trigger: %S", pName, 0); } pParse->checkSchema = 1; goto drop_trigger_cleanup; } sqlite3DropTriggerPtr(pParse, pTrigger); drop_trigger_cleanup: | > > | 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 | assert( sqlite3SchemaMutexHeld(db, j, 0) ); pTrigger = sqlite3HashFind(&(db->aDb[j].pSchema->trigHash), zName, nName); if( pTrigger ) break; } if( !pTrigger ){ if( !noErr ){ sqlite3ErrorMsg(pParse, "no such trigger: %S", pName, 0); }else{ sqlite3CodeVerifyNamedSchema(pParse, zDb); } pParse->checkSchema = 1; goto drop_trigger_cleanup; } sqlite3DropTriggerPtr(pParse, pTrigger); drop_trigger_cleanup: |
︙ | ︙ |
Changes to src/where.c.
︙ | ︙ | |||
1338 1339 1340 1341 1342 1343 1344 | ** virtual term of that form. ** ** Note that the virtual term must be tagged with TERM_VNULL. This ** TERM_VNULL tag will suppress the not-null check at the beginning ** of the loop. Without the TERM_VNULL flag, the not-null check at ** the start of the loop will prevent any results from being returned. */ | | > > > | 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 | ** virtual term of that form. ** ** Note that the virtual term must be tagged with TERM_VNULL. This ** TERM_VNULL tag will suppress the not-null check at the beginning ** of the loop. Without the TERM_VNULL flag, the not-null check at ** the start of the loop will prevent any results from being returned. */ if( pExpr->op==TK_NOTNULL && pExpr->pLeft->op==TK_COLUMN && pExpr->pLeft->iColumn>=0 ){ Expr *pNewExpr; Expr *pLeft = pExpr->pLeft; int idxNew; WhereTerm *pNewTerm; pNewExpr = sqlite3PExpr(pParse, TK_GT, sqlite3ExprDup(db, pLeft, 0), |
︙ | ︙ | |||
2528 2529 2530 2531 2532 2533 2534 | ** non-zero. ** ** This routine can fail if it is unable to load a collating sequence ** required for string comparison, or if unable to allocate memory ** for a UTF conversion required for comparison. The error is stored ** in the pParse structure. */ | | | 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 | ** non-zero. ** ** This routine can fail if it is unable to load a collating sequence ** required for string comparison, or if unable to allocate memory ** for a UTF conversion required for comparison. The error is stored ** in the pParse structure. */ static int whereEqualScanEst( Parse *pParse, /* Parsing & code generating context */ Index *p, /* The index whose left-most column is pTerm */ Expr *pExpr, /* Expression for VALUE in the x=VALUE constraint */ double *pnRow /* Write the revised row estimate here */ ){ sqlite3_value *pRhs = 0; /* VALUE on right-hand side of pTerm */ int iLower, iUpper; /* Range of histogram regions containing pRhs */ |
︙ | ︙ | |||
2585 2586 2587 2588 2589 2590 2591 | ** non-zero. ** ** This routine can fail if it is unable to load a collating sequence ** required for string comparison, or if unable to allocate memory ** for a UTF conversion required for comparison. The error is stored ** in the pParse structure. */ | | | 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 | ** non-zero. ** ** This routine can fail if it is unable to load a collating sequence ** required for string comparison, or if unable to allocate memory ** for a UTF conversion required for comparison. The error is stored ** in the pParse structure. */ static int whereInScanEst( Parse *pParse, /* Parsing & code generating context */ Index *p, /* The index whose left-most column is pTerm */ ExprList *pList, /* The value list on the RHS of "x IN (v1,v2,v3,...)" */ double *pnRow /* Write the revised row estimate here */ ){ sqlite3_value *pVal = 0; /* One value from list */ int iLower, iUpper; /* Range of histogram regions containing pRhs */ |
︙ | ︙ | |||
2856 2857 2858 2859 2860 2861 2862 | #ifdef SQLITE_ENABLE_STAT2 if( nEq==0 && pProbe->aSample ) pFirstTerm = pTerm; #endif used |= pTerm->prereqRight; } /* Determine the value of estBound. */ | | | 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 | #ifdef SQLITE_ENABLE_STAT2 if( nEq==0 && pProbe->aSample ) pFirstTerm = pTerm; #endif used |= pTerm->prereqRight; } /* Determine the value of estBound. */ if( nEq<pProbe->nColumn && pProbe->bUnordered==0 ){ int j = pProbe->aiColumn[nEq]; if( findTerm(pWC, iCur, j, notReady, WO_LT|WO_LE|WO_GT|WO_GE, pIdx) ){ WhereTerm *pTop = findTerm(pWC, iCur, j, notReady, WO_LT|WO_LE, pIdx); WhereTerm *pBtm = findTerm(pWC, iCur, j, notReady, WO_GT|WO_GE, pIdx); whereRangeScanEst(pParse, pProbe, nEq, pBtm, pTop, &estBound); if( pTop ){ nBound = 1; |
︙ | ︙ | |||
2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 | /* If there is an ORDER BY clause and the index being considered will ** naturally scan rows in the required order, set the appropriate flags ** in wsFlags. Otherwise, if there is an ORDER BY clause but the index ** will scan rows in a different order, set the bSort variable. */ if( pOrderBy ){ if( (wsFlags & WHERE_COLUMN_IN)==0 && isSortingIndex(pParse, pWC->pMaskSet, pProbe, iCur, pOrderBy, nEq, wsFlags, &rev) ){ wsFlags |= WHERE_ROWID_RANGE|WHERE_COLUMN_RANGE|WHERE_ORDERBY; wsFlags |= (rev ? WHERE_REVERSE : 0); }else{ bSort = 1; | > | 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 | /* If there is an ORDER BY clause and the index being considered will ** naturally scan rows in the required order, set the appropriate flags ** in wsFlags. Otherwise, if there is an ORDER BY clause but the index ** will scan rows in a different order, set the bSort variable. */ if( pOrderBy ){ if( (wsFlags & WHERE_COLUMN_IN)==0 && pProbe->bUnordered==0 && isSortingIndex(pParse, pWC->pMaskSet, pProbe, iCur, pOrderBy, nEq, wsFlags, &rev) ){ wsFlags |= WHERE_ROWID_RANGE|WHERE_COLUMN_RANGE|WHERE_ORDERBY; wsFlags |= (rev ? WHERE_REVERSE : 0); }else{ bSort = 1; |
︙ | ︙ |
Changes to test/analyze5.test.
︙ | ︙ | |||
205 206 207 208 209 210 211 212 213 214 215 216 217 218 | # foreach {testid where index rows} { 500 {x IS NULL AND u='charlie'} t1u 20 501 {x=1 AND u='charlie'} t1x 5 502 {x IS NULL} {} 100 503 {x=1} t1x 50 504 {x IS NOT NULL} t1x 25 } { # Verify that the expected index is used with the expected row count do_test analyze5-1.${testid}a { set x [lindex [eqp "SELECT * FROM t1 WHERE $where"] 3] set idx {} regexp {INDEX (t1.) } $x all idx | > > | 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 | # foreach {testid where index rows} { 500 {x IS NULL AND u='charlie'} t1u 20 501 {x=1 AND u='charlie'} t1x 5 502 {x IS NULL} {} 100 503 {x=1} t1x 50 504 {x IS NOT NULL} t1x 25 505 {+x IS NOT NULL} {} 500 506 {upper(x) IS NOT NULL} {} 500 } { # Verify that the expected index is used with the expected row count do_test analyze5-1.${testid}a { set x [lindex [eqp "SELECT * FROM t1 WHERE $where"] 3] set idx {} regexp {INDEX (t1.) } $x all idx |
︙ | ︙ |
Changes to test/analyze7.test.
︙ | ︙ | |||
83 84 85 86 87 88 89 | execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE c=?;} } {0 0 0 {SEARCH TABLE t1 USING INDEX t1cd (c=?) (~86 rows)}} ifcapable stat2 { # If ENABLE_STAT2 is defined, SQLite comes up with a different estimated # row count for (c=2) than it does for (c=?). do_test analyze7-3.2.2 { execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE c=2;} | | | 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 | execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE c=?;} } {0 0 0 {SEARCH TABLE t1 USING INDEX t1cd (c=?) (~86 rows)}} ifcapable stat2 { # If ENABLE_STAT2 is defined, SQLite comes up with a different estimated # row count for (c=2) than it does for (c=?). do_test analyze7-3.2.2 { execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE c=2;} } {0 0 0 {SEARCH TABLE t1 USING INDEX t1cd (c=?) (~51 rows)}} } else { # If ENABLE_STAT2 is not defined, the expected row count for (c=2) is the # same as that for (c=?). do_test analyze7-3.2.3 { execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE c=2;} } {0 0 0 {SEARCH TABLE t1 USING INDEX t1cd (c=?) (~86 rows)}} } |
︙ | ︙ |
Changes to test/attach4.test.
︙ | ︙ | |||
70 71 72 73 74 75 76 | } set L } $files set L [list] set S "" foreach {name f} $files { | > > > | > | 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 | } set L } $files set L [list] set S "" foreach {name f} $files { if {[permutation] == "journaltest"} { lappend L delete } else { lappend L wal } append S " PRAGMA $name.journal_mode = WAL; UPDATE $name.tbl SET x = '$name'; " } do_execsql_test 1.5 $S $L |
︙ | ︙ |
Changes to test/backcompat.test.
︙ | ︙ | |||
362 363 364 365 366 367 368 369 370 371 372 | 6 "SELECT offsets(t1) FROM t1 WHERE t1 MATCH 'aa'" 7 "SELECT offsets(t1) FROM t1 WHERE t1 MATCH '44'" 8 "SELECT offsets(t1) FROM t1 WHERE t1 MATCH 'a*'" } { do_test backcompat-3.7 [list sql1 $q] [sql2 $q] } } } finish_test | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 | 6 "SELECT offsets(t1) FROM t1 WHERE t1 MATCH 'aa'" 7 "SELECT offsets(t1) FROM t1 WHERE t1 MATCH '44'" 8 "SELECT offsets(t1) FROM t1 WHERE t1 MATCH 'a*'" } { do_test backcompat-3.7 [list sql1 $q] [sql2 $q] } } } #------------------------------------------------------------------------- # Test that Rtree tables may be read/written by different versions of # SQLite. # set contents { CREATE VIRTUAL TABLE t1 USING rtree(id, x1, x2, y1, y2); } foreach {id x1 x2 y1 y2} { 1 -47.64 43.87 33.86 34.42 2 -21.51 17.32 2.05 31.04 3 -43.67 -38.33 -19.79 3.43 4 32.41 35.16 9.12 19.82 5 33.28 34.87 14.78 28.26 6 49.31 116.59 -9.87 75.09 7 -14.93 34.51 -17.64 64.09 8 -43.05 23.43 -1.19 69.44 9 44.79 133.56 28.09 80.30 10 -2.66 81.47 -41.38 -10.46 11 -42.89 -3.54 15.76 71.63 12 -3.50 84.96 -11.64 64.95 13 -45.69 26.25 11.14 55.06 14 -44.09 11.23 17.52 44.45 15 36.23 133.49 -19.38 53.67 16 -17.89 81.54 14.64 50.61 17 -41.97 -24.04 -39.43 28.95 18 -5.85 7.76 -6.38 47.02 19 18.82 27.10 42.82 100.09 20 39.17 113.45 26.14 73.47 21 22.31 103.17 49.92 106.05 22 -43.06 40.38 -1.75 76.08 23 2.43 57.27 -14.19 -3.83 24 -47.57 -4.35 8.93 100.06 25 -37.47 49.14 -29.11 8.81 26 -7.86 75.72 49.34 107.42 27 1.53 45.49 20.36 49.74 28 -48.48 32.54 28.81 54.45 29 2.67 39.77 -4.05 13.67 30 4.11 62.88 -47.44 -5.72 31 -21.47 51.75 37.25 116.09 32 45.59 111.37 -6.43 43.64 33 35.23 48.29 23.54 113.33 34 16.61 68.35 -14.69 65.97 35 13.98 16.60 48.66 102.87 36 19.74 23.84 31.15 77.27 37 -27.61 24.43 7.96 94.91 38 -34.77 12.05 -22.60 -6.29 39 -25.83 8.71 -13.48 -12.53 40 -17.11 -1.01 18.06 67.89 41 14.13 71.72 -3.78 39.25 42 23.75 76.00 -16.30 8.23 43 -39.15 28.63 38.12 125.88 44 48.62 86.09 36.49 102.95 45 -31.39 -21.98 2.52 89.78 46 5.65 56.04 15.94 89.10 47 18.28 95.81 46.46 143.08 48 30.93 102.82 -20.08 37.36 49 -20.78 -3.48 -5.58 35.46 50 49.85 90.58 -24.48 46.29 } { if {$x1 >= $x2 || $y1 >= $y2} { error "$x1 $x2 $y1 $y2" } append contents "INSERT INTO t1 VALUES($id, $x1, $x2, $y1, $y2);" } set queries { 1 "SELECT id FROM t1 WHERE x1>10 AND x2<44" 2 "SELECT id FROM t1 WHERE y1<100" 3 "SELECT id FROM t1 WHERE y1<100 AND x1>0" 4 "SELECT id FROM t1 WHERE y1>10 AND x1>0 AND x2<50 AND y2<550" } do_allbackcompat_test { if {[code1 {set ::sqlite_options(fts3)}] && [code2 {set ::sqlite_options(fts3)}] } { do_test backcompat-4.1 { sql1 $contents } {} foreach {n q} $::queries { do_test backcompat-4.2.$n [list sql1 $q] [sql2 $q] } do_test backcompat-4.3 { sql1 { INSERT INTO t1 SELECT id+100, x1+10.0, x2+10.0, y1-10.0, y2-10.0 FROM t1; } } {} foreach {n q} $::queries { do_test backcompat-4.4.$n [list sql1 $q] [sql2 $q] } do_test backcompat-4.5 { sql2 { INSERT INTO t1 SELECT id+200, x1+20.0, x2+20.0, y1-20.0, y2-20.0 FROM t1; } } {} foreach {n q} $::queries { do_test backcompat-4.6.$n [list sql1 $q] [sql2 $q] } } } finish_test |
Added test/exists.test.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 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 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 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 | # 2011 April 9 # # 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 file is testing the various schema modification statements # that feature "IF EXISTS" or "IF NOT EXISTS" clauses. # set testdir [file dirname $argv0] source $testdir/tester.tcl source $testdir/lock_common.tcl set testprefix exists # This block of tests is targeted at CREATE XXX IF NOT EXISTS statements. # do_multiclient_test tn { # TABLE objects. # do_test 1.$tn.1.1 { sql2 { CREATE TABLE t1(x) } sql1 { CREATE TABLE IF NOT EXISTS t1(a, b) } sql2 { DROP TABLE t1 } sql1 { CREATE TABLE IF NOT EXISTS t1(a, b) } sql2 { SELECT name FROM sqlite_master WHERE type = 'table' } } {t1} do_test 1.$tn.1.2 { sql2 { CREATE TABLE t2(x) } sql1 { CREATE TABLE IF NOT EXISTS t2 AS SELECT * FROM t1 } sql2 { DROP TABLE t2 } sql1 { CREATE TABLE IF NOT EXISTS t2 AS SELECT * FROM t1 } sql2 { SELECT name FROM sqlite_master WHERE type = 'table' } } {t1 t2} # INDEX objects. # do_test 1.$tn.2 { sql2 { CREATE INDEX i1 ON t1(a) } sql1 { CREATE INDEX IF NOT EXISTS i1 ON t1(a, b) } sql2 { DROP INDEX i1 } sql1 { CREATE INDEX IF NOT EXISTS i1 ON t1(a, b) } sql2 { SELECT name FROM sqlite_master WHERE type = 'index' } } {i1} # VIEW objects. # do_test 1.$tn.3 { sql2 { CREATE VIEW v1 AS SELECT * FROM t1 } sql1 { CREATE VIEW IF NOT EXISTS v1 AS SELECT * FROM t1 } sql2 { DROP VIEW v1 } sql1 { CREATE VIEW IF NOT EXISTS v1 AS SELECT * FROM t1 } sql2 { SELECT name FROM sqlite_master WHERE type = 'view' } } {v1} # TRIGGER objects. # do_test $tn.4 { sql2 { CREATE TRIGGER tr1 AFTER INSERT ON t1 BEGIN SELECT 1; END } sql1 { CREATE TRIGGER IF NOT EXISTS tr1 AFTER INSERT ON t1 BEGIN SELECT 1; END } sql2 { DROP TRIGGER tr1 } sql1 { CREATE TRIGGER IF NOT EXISTS tr1 AFTER INSERT ON t1 BEGIN SELECT 1; END } sql2 { SELECT name FROM sqlite_master WHERE type = 'trigger' } } {tr1} } # This block of tests is targeted at DROP XXX IF EXISTS statements. # do_multiclient_test tn { # TABLE objects. # do_test 2.$tn.1 { sql1 { DROP TABLE IF EXISTS t1 } sql2 { CREATE TABLE t1(x) } sql1 { DROP TABLE IF EXISTS t1 } sql2 { SELECT name FROM sqlite_master WHERE type = 'table' } } {} # INDEX objects. # do_test 2.$tn.2 { sql1 { CREATE TABLE t2(x) } sql1 { DROP INDEX IF EXISTS i2 } sql2 { CREATE INDEX i2 ON t2(x) } sql1 { DROP INDEX IF EXISTS i2 } sql2 { SELECT name FROM sqlite_master WHERE type = 'index' } } {} # VIEW objects. # do_test 2.$tn.3 { sql1 { DROP VIEW IF EXISTS v1 } sql2 { CREATE VIEW v1 AS SELECT * FROM t2 } sql1 { DROP VIEW IF EXISTS v1 } sql2 { SELECT name FROM sqlite_master WHERE type = 'view' } } {} # TRIGGER objects. # do_test 2.$tn.4 { sql1 { DROP TRIGGER IF EXISTS tr1 } sql2 { CREATE TRIGGER tr1 AFTER INSERT ON t2 BEGIN SELECT 1; END } sql1 { DROP TRIGGER IF EXISTS tr1 } sql2 { SELECT name FROM sqlite_master WHERE type = 'trigger' } } {} } # This block of tests is targeted at DROP XXX IF EXISTS statements with # attached databases. # do_multiclient_test tn { forcedelete test.db2 do_test 3.$tn.0 { sql1 { ATTACH 'test.db2' AS aux } sql2 { ATTACH 'test.db2' AS aux } } {} # TABLE objects. # do_test 3.$tn.1.1 { sql1 { DROP TABLE IF EXISTS aux.t1 } sql2 { CREATE TABLE aux.t1(x) } sql1 { DROP TABLE IF EXISTS aux.t1 } sql2 { SELECT name FROM aux.sqlite_master WHERE type = 'table' } } {} do_test 3.$tn.1.2 { sql1 { DROP TABLE IF EXISTS t1 } sql2 { CREATE TABLE aux.t1(x) } sql1 { DROP TABLE IF EXISTS t1 } sql2 { SELECT name FROM aux.sqlite_master WHERE type = 'table' } } {} # INDEX objects. # do_test 3.$tn.2.1 { sql1 { CREATE TABLE aux.t2(x) } sql1 { DROP INDEX IF EXISTS aux.i2 } sql2 { CREATE INDEX aux.i2 ON t2(x) } sql1 { DROP INDEX IF EXISTS aux.i2 } sql2 { SELECT name FROM aux.sqlite_master WHERE type = 'index' } } {} do_test 3.$tn.2.2 { sql1 { DROP INDEX IF EXISTS i2 } sql2 { CREATE INDEX aux.i2 ON t2(x) } sql1 { DROP INDEX IF EXISTS i2 } sql2 { SELECT name FROM aux.sqlite_master WHERE type = 'index' } } {} # VIEW objects. # do_test 3.$tn.3.1 { sql1 { DROP VIEW IF EXISTS aux.v1 } sql2 { CREATE VIEW aux.v1 AS SELECT * FROM t2 } sql1 { DROP VIEW IF EXISTS aux.v1 } sql2 { SELECT name FROM aux.sqlite_master WHERE type = 'view' } } {} do_test 3.$tn.3.2 { sql1 { DROP VIEW IF EXISTS v1 } sql2 { CREATE VIEW aux.v1 AS SELECT * FROM t2 } sql1 { DROP VIEW IF EXISTS v1 } sql2 { SELECT name FROM aux.sqlite_master WHERE type = 'view' } } {} # TRIGGER objects. # do_test 3.$tn.4.1 { sql1 { DROP TRIGGER IF EXISTS aux.tr1 } sql2 { CREATE TRIGGER aux.tr1 AFTER INSERT ON t2 BEGIN SELECT 1; END } sql1 { DROP TRIGGER IF EXISTS aux.tr1 } sql2 { SELECT name FROM aux.sqlite_master WHERE type = 'trigger' } } {} do_test 3.$tn.4.2 { sql1 { DROP TRIGGER IF EXISTS tr1 } sql2 { CREATE TRIGGER aux.tr1 AFTER INSERT ON t2 BEGIN SELECT 1; END } sql1 { DROP TRIGGER IF EXISTS tr1 } sql2 { SELECT name FROM aux.sqlite_master WHERE type = 'trigger' } } {} } finish_test |
Changes to test/incrvacuum2.test.
︙ | ︙ | |||
19 20 21 22 23 24 25 26 27 28 29 30 31 32 | # If this build of the library does not support auto-vacuum, omit this # whole file. ifcapable {!autovacuum || !pragma} { finish_test return } # Create a database in incremental vacuum mode that has many # pages on the freelist. # do_test incrvacuum2-1.1 { execsql { PRAGMA page_size=1024; | > | 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | # If this build of the library does not support auto-vacuum, omit this # whole file. ifcapable {!autovacuum || !pragma} { finish_test return } set testprefix incrvacuum2 # Create a database in incremental vacuum mode that has many # pages on the freelist. # do_test incrvacuum2-1.1 { execsql { PRAGMA page_size=1024; |
︙ | ︙ | |||
127 128 129 130 131 132 133 | BEGIN; DELETE FROM abc; PRAGMA incremental_vacuum; COMMIT; } } {} | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 | BEGIN; DELETE FROM abc; PRAGMA incremental_vacuum; COMMIT; } } {} integrity_check incrvacuum2-3.3 ifcapable wal { # At one point, when a specific page was being extracted from the b-tree # free-list (e.g. during an incremental-vacuum), all trunk pages that # occurred before the specific page in the free-list trunk were being # written to the journal or wal file. This is not necessary. Only the # extracted page and the page that contains the pointer to it need to # be journalled. # # This problem was fixed by [d03d63d77e] (just before 3.7.6 release). # # This test case builds a database containing many free pages. Then runs # "PRAGMA incremental_vacuum(1)" until the db contains zero free pages. # Each "PRAGMA incremental_vacuum(1)" should modify at most 4 pages. The # worst case is when a trunk page is removed from the end of the db file. # In this case pages written are: # # 1. The previous trunk page (that contains a pointer to the recycled # trunk page), and # 2. The leaf page transformed into a trunk page to replace the recycled # page, and # 3. The trunk page that contained a pointer to the leaf page used # in (2), and # 4. Page 1. Page 1 is always updated, even in WAL mode, since it contains # the "number of free-list pages" field. # db close forcedelete test.db sqlite3 db test.db do_execsql_test 4.1 { PRAGMA page_size = 512; PRAGMA auto_vacuum = 2; CREATE TABLE t1(x); INSERT INTO t1 VALUES(randomblob(400)); INSERT INTO t1 SELECT * FROM t1; -- 2 INSERT INTO t1 SELECT * FROM t1; -- 4 INSERT INTO t1 SELECT * FROM t1; -- 8 INSERT INTO t1 SELECT * FROM t1; -- 16 INSERT INTO t1 SELECT * FROM t1; -- 32 INSERT INTO t1 SELECT * FROM t1; -- 128 INSERT INTO t1 SELECT * FROM t1; -- 256 INSERT INTO t1 SELECT * FROM t1; -- 512 INSERT INTO t1 SELECT * FROM t1; -- 1024 INSERT INTO t1 SELECT * FROM t1; -- 2048 INSERT INTO t1 SELECT * FROM t1; -- 4096 INSERT INTO t1 SELECT * FROM t1; -- 8192 DELETE FROM t1 WHERE oid>512; DELETE FROM t1; } do_test 4.2 { execsql { PRAGMA journal_mode = WAL; PRAGMA incremental_vacuum(1); PRAGMA wal_checkpoint; } file size test.db-wal } {1640} do_test 4.3 { db close sqlite3 db test.db set maxsz 0 while {[file size test.db] > [expr 512*3]} { execsql { PRAGMA journal_mode = WAL } execsql { PRAGMA wal_checkpoint } execsql { PRAGMA incremental_vacuum(1) } set newsz [file size test.db-wal] if {$newsz>$maxsz} {set maxsz $newsz} } set maxsz } {2176} } finish_test |
Deleted test/omitunique.test.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Changes to test/thread1.test.
︙ | ︙ | |||
15 16 17 18 19 20 21 | set testdir [file dirname $argv0] source $testdir/tester.tcl # Skip this whole file if the thread testing code is not enabled # | < | < < | 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | set testdir [file dirname $argv0] source $testdir/tester.tcl # Skip this whole file if the thread testing code is not enabled # if {[run_thread_tests]==0} { finish_test ; return } if {[llength [info command thread_step]]==0 || [sqlite3 -has-codec]} { finish_test return } # Create some data to work with # |
︙ | ︙ |
Changes to test/thread2.test.
︙ | ︙ | |||
13 14 15 16 17 18 19 | # # $Id: thread2.test,v 1.3 2008/10/07 15:25:49 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl | < | < < < | 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | # # $Id: thread2.test,v 1.3 2008/10/07 15:25:49 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl if {[run_thread_tests]==0} { finish_test ; return } # Skip this whole file if the thread testing code is not enabled # if {[llength [info command thread_step]]==0 || [sqlite3 -has-codec]} { finish_test return } |
︙ | ︙ |
Changes to test/thread_common.tcl.
︙ | ︙ | |||
85 86 87 88 89 90 91 92 93 94 95 96 97 98 | # Return true if this build can run the multi-threaded tests. # proc run_thread_tests {{print_warning 0}} { ifcapable !mutex { set zProblem "SQLite build is not threadsafe" } if {[info commands sqlthread] eq ""} { set zProblem "SQLite build is not threadsafe" } if {![info exists ::tcl_platform(threaded)]} { set zProblem "Linked against a non-threadsafe Tcl build" } if {[info exists zProblem]} { | > > > | 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 | # Return true if this build can run the multi-threaded tests. # proc run_thread_tests {{print_warning 0}} { ifcapable !mutex { set zProblem "SQLite build is not threadsafe" } ifcapable mutex_noop { set zProblem "SQLite build uses SQLITE_MUTEX_NOOP" } if {[info commands sqlthread] eq ""} { set zProblem "SQLite build is not threadsafe" } if {![info exists ::tcl_platform(threaded)]} { set zProblem "Linked against a non-threadsafe Tcl build" } if {[info exists zProblem]} { |
︙ | ︙ |
Changes to test/wal.test.
︙ | ︙ | |||
1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 | file exists test.db-wal } 0 do_test 24.3 { file size test.db } [expr 84 * 1024] do_test 24.4 { execsql { PRAGMA incremental_vacuum; PRAGMA wal_checkpoint; } file size test.db } [expr 3 * 1024] do_test 24.5 { file size test.db-wal | > | 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 | file exists test.db-wal } 0 do_test 24.3 { file size test.db } [expr 84 * 1024] do_test 24.4 { execsql { PRAGMA cache_size = 200; PRAGMA incremental_vacuum; PRAGMA wal_checkpoint; } file size test.db } [expr 3 * 1024] do_test 24.5 { file size test.db-wal |
︙ | ︙ |