Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Merge all recent trunk enhancements and fixes into the apple-osx branch. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | apple-osx |
Files: | files | file ages | folders |
SHA1: |
74b7bf17446bc21a73fa5b75c2942b56 |
User & Date: | drh 2015-04-20 01:25:56.443 |
Context
2015-08-11
| ||
18:18 | Fix the retry mechanism on file locks. (check-in: 600df309fc user: drh tags: apple-osx) | |
2015-04-20
| ||
01:25 | Merge all recent trunk enhancements and fixes into the apple-osx branch. (check-in: 74b7bf1744 user: drh tags: apple-osx) | |
01:13 | Add an ALWAYS() around a new branch that was made unreachable by an even newer change. (check-in: 592c010478 user: drh tags: trunk) | |
2015-04-15
| ||
13:51 | Merge recent trunk fixes and enhancements into the apple-osx branch. (check-in: bfc7142ad2 user: drh tags: apple-osx) | |
Changes
Changes to Makefile.in.
︙ | ︙ | |||
547 548 549 550 551 552 553 554 555 556 557 558 559 560 | sqlite3$(TEXE): $(TOP)/src/shell.c libsqlite3.la sqlite3.h $(LTLINK) $(READLINE_FLAGS) \ -o $@ $(TOP)/src/shell.c libsqlite3.la \ $(LIBREADLINE) $(TLIBS) -rpath "$(libdir)" sqldiff$(EXE): $(TOP)/tool/sqldiff.c sqlite3.c sqlite3.h $(LTLINK) -o $@ $(TOP)/tool/sqldiff.c sqlite3.c $(TLIBS) mptester$(EXE): sqlite3.c $(TOP)/mptest/mptest.c $(LTLINK) -o $@ -I. $(TOP)/mptest/mptest.c sqlite3.c \ $(TLIBS) -rpath "$(libdir)" MPTEST1=./mptester$(EXE) mptest.db $(TOP)/mptest/crash01.test --repeat 20 MPTEST2=./mptester$(EXE) mptest.db $(TOP)/mptest/multiwrite01.test --repeat 20 | > > > | 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 | sqlite3$(TEXE): $(TOP)/src/shell.c libsqlite3.la sqlite3.h $(LTLINK) $(READLINE_FLAGS) \ -o $@ $(TOP)/src/shell.c libsqlite3.la \ $(LIBREADLINE) $(TLIBS) -rpath "$(libdir)" sqldiff$(EXE): $(TOP)/tool/sqldiff.c sqlite3.c sqlite3.h $(LTLINK) -o $@ $(TOP)/tool/sqldiff.c sqlite3.c $(TLIBS) fuzzershell$(EXE): $(TOP)/tool/fuzzershell.c sqlite3.c sqlite3.h $(LTLINK) -o $@ $(TOP)/tool/fuzzershell.c sqlite3.c $(TLIBS) mptester$(EXE): sqlite3.c $(TOP)/mptest/mptest.c $(LTLINK) -o $@ -I. $(TOP)/mptest/mptest.c sqlite3.c \ $(TLIBS) -rpath "$(libdir)" MPTEST1=./mptester$(EXE) mptest.db $(TOP)/mptest/crash01.test --repeat 20 MPTEST2=./mptester$(EXE) mptest.db $(TOP)/mptest/multiwrite01.test --repeat 20 |
︙ | ︙ |
Changes to Makefile.msc.
︙ | ︙ | |||
1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 | sqlite3.exe: $(TOP)\src\shell.c $(SHELL_CORE_DEP) $(LIBRESOBJS) sqlite3.h $(LTLINK) $(SHELL_COMPILE_OPTS) $(READLINE_FLAGS) $(TOP)\src\shell.c \ /link /pdb:sqlite3sh.pdb $(LTLINKOPTS) $(SHELL_LINK_OPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LIBREADLINE) $(LTLIBS) $(TLIBS) sqldiff.exe: $(TOP)\tool\sqldiff.c sqlite3.c sqlite3.h $(LTLINK) $(TOP)\tool\sqldiff.c sqlite3.c mptester.exe: $(TOP)\mptest\mptest.c $(SHELL_CORE_DEP) $(LIBRESOBJS) sqlite3.h $(LTLINK) $(SHELL_COMPILE_OPTS) $(TOP)\mptest\mptest.c \ /link $(LTLINKOPTS) $(LTLIBPATHS) $(SHELL_LINK_OPTS) $(LIBRESOBJS) $(LIBREADLINE) $(LTLIBS) $(TLIBS) | > > > | | | 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 | sqlite3.exe: $(TOP)\src\shell.c $(SHELL_CORE_DEP) $(LIBRESOBJS) sqlite3.h $(LTLINK) $(SHELL_COMPILE_OPTS) $(READLINE_FLAGS) $(TOP)\src\shell.c \ /link /pdb:sqlite3sh.pdb $(LTLINKOPTS) $(SHELL_LINK_OPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LIBREADLINE) $(LTLIBS) $(TLIBS) sqldiff.exe: $(TOP)\tool\sqldiff.c sqlite3.c sqlite3.h $(LTLINK) $(TOP)\tool\sqldiff.c sqlite3.c fuzzershell.exe: $(TOP)\tool\fuzzershell.c sqlite3.c sqlite3.h $(LTLINK) $(TOP)\tool\fuzzershell.c sqlite3.c mptester.exe: $(TOP)\mptest\mptest.c $(SHELL_CORE_DEP) $(LIBRESOBJS) sqlite3.h $(LTLINK) $(SHELL_COMPILE_OPTS) $(TOP)\mptest\mptest.c \ /link $(LTLINKOPTS) $(LTLIBPATHS) $(SHELL_LINK_OPTS) $(LIBRESOBJS) $(LIBREADLINE) $(LTLIBS) $(TLIBS) MPTEST1 = mptester mptest.db $(TOP)\mptest\crash01.test --repeat 20 MPTEST2 = mptester mptest.db $(TOP)\mptest\multiwrite01.test --repeat 20 mptest: mptester.exe del /Q mptest.db 2>NUL $(MPTEST1) --journalmode DELETE $(MPTEST2) --journalmode WAL $(MPTEST1) --journalmode WAL $(MPTEST2) --journalmode PERSIST |
︙ | ︙ | |||
1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 | queryplantest: testfixture.exe sqlite3.exe .\testfixture.exe $(TOP)\test\permutations.test queryplanner test: testfixture.exe sqlite3.exe .\testfixture.exe $(TOP)\test\veryquick.test sqlite3_analyzer.c: $(SQLITE3C) $(TOP)\src\test_stat.c $(TOP)\src\tclsqlite.c $(TOP)\tool\spaceanal.tcl copy $(SQLITE3C) + $(TOP)\src\test_stat.c + $(TOP)\src\tclsqlite.c $@ echo static const char *tclsh_main_loop(void){ >> $@ echo static const char *zMainloop = >> $@ $(NAWK) -f $(TOP)\tool\tostr.awk $(TOP)\tool\spaceanal.tcl >> $@ echo ; return zMainloop; } >> $@ | > > > | 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 | queryplantest: testfixture.exe sqlite3.exe .\testfixture.exe $(TOP)\test\permutations.test queryplanner test: testfixture.exe sqlite3.exe .\testfixture.exe $(TOP)\test\veryquick.test smoketest: testfixture.exe .\testfixture.exe $(TOP)\test\main.test sqlite3_analyzer.c: $(SQLITE3C) $(TOP)\src\test_stat.c $(TOP)\src\tclsqlite.c $(TOP)\tool\spaceanal.tcl copy $(SQLITE3C) + $(TOP)\src\test_stat.c + $(TOP)\src\tclsqlite.c $@ echo static const char *tclsh_main_loop(void){ >> $@ echo static const char *zMainloop = >> $@ $(NAWK) -f $(TOP)\tool\tostr.awk $(TOP)\tool\spaceanal.tcl >> $@ echo ; return zMainloop; } >> $@ |
︙ | ︙ |
Changes to ext/fts3/fts3.c.
︙ | ︙ | |||
3455 3456 3457 3458 3459 3460 3461 3462 3463 3464 3465 | ** moves *ppPoslist so that it instead points to the first byte of the ** same position list. */ static void fts3ReversePoslist(char *pStart, char **ppPoslist){ char *p = &(*ppPoslist)[-2]; char c = 0; while( p>pStart && (c=*p--)==0 ); while( p>pStart && (*p & 0x80) | c ){ c = *p--; } | > > > > > > | > > > > > > > > > > > > > > | 3455 3456 3457 3458 3459 3460 3461 3462 3463 3464 3465 3466 3467 3468 3469 3470 3471 3472 3473 3474 3475 3476 3477 3478 3479 3480 3481 3482 3483 3484 3485 3486 3487 3488 3489 3490 3491 3492 3493 | ** moves *ppPoslist so that it instead points to the first byte of the ** same position list. */ static void fts3ReversePoslist(char *pStart, char **ppPoslist){ char *p = &(*ppPoslist)[-2]; char c = 0; /* Skip backwards passed any trailing 0x00 bytes added by NearTrim() */ while( p>pStart && (c=*p--)==0 ); /* Search backwards for a varint with value zero (the end of the previous ** poslist). This is an 0x00 byte preceded by some byte that does not ** have the 0x80 bit set. */ while( p>pStart && (*p & 0x80) | c ){ c = *p--; } assert( p==pStart || c==0 ); /* At this point p points to that preceding byte without the 0x80 bit ** set. So to find the start of the poslist, skip forward 2 bytes then ** over a varint. ** ** Normally. The other case is that p==pStart and the poslist to return ** is the first in the doclist. In this case do not skip forward 2 bytes. ** The second part of the if condition (c==0 && *ppPoslist>&p[2]) ** is required for cases where the first byte of a doclist and the ** doclist is empty. For example, if the first docid is 10, a doclist ** that begins with: ** ** 0x0A 0x00 <next docid delta varint> */ if( p>pStart || (c==0 && *ppPoslist>&p[2]) ){ p = &p[2]; } while( *p++&0x80 ); *ppPoslist = p; } /* ** Helper function used by the implementation of the overloaded snippet(), ** offsets() and optimize() SQL functions. |
︙ | ︙ | |||
5761 5762 5763 5764 5765 5766 5767 | } } if( rc!=SQLITE_OK ) return rc; pIter = pPhrase->pOrPoslist; iDocid = pPhrase->iOrDocid; if( pCsr->bDesc==bDescDoclist ){ | > | | 5781 5782 5783 5784 5785 5786 5787 5788 5789 5790 5791 5792 5793 5794 5795 5796 | } } if( rc!=SQLITE_OK ) return rc; pIter = pPhrase->pOrPoslist; iDocid = pPhrase->iOrDocid; if( pCsr->bDesc==bDescDoclist ){ bEof = !pPhrase->doclist.nAll || (pIter >= (pPhrase->doclist.aAll + pPhrase->doclist.nAll)); while( (pIter==0 || DOCID_CMP(iDocid, pCsr->iPrevId)<0 ) && bEof==0 ){ sqlite3Fts3DoclistNext( bDescDoclist, pPhrase->doclist.aAll, pPhrase->doclist.nAll, &pIter, &iDocid, &bEof ); } }else{ |
︙ | ︙ |
Changes to main.mk.
︙ | ︙ | |||
390 391 392 393 394 395 396 397 398 399 400 401 402 403 | $(TCCX) $(READLINE_FLAGS) -o sqlite3$(EXE) \ $(TOP)/src/shell.c \ libsqlite3.a $(LIBREADLINE) $(TLIBS) $(THREADLIB) sqldiff$(EXE): $(TOP)/tool/sqldiff.c sqlite3.c sqlite3.h $(TCCX) -o sqldiff$(EXE) -DSQLITE_THREADSAFE=0 \ $(TOP)/tool/sqldiff.c sqlite3.c $(TLIBS) $(THREADLIB) mptester$(EXE): sqlite3.c $(TOP)/mptest/mptest.c $(TCCX) -o $@ -I. $(TOP)/mptest/mptest.c sqlite3.c \ $(TLIBS) $(THREADLIB) MPTEST1=./mptester$(EXE) mptest.db $(TOP)/mptest/crash01.test --repeat 20 MPTEST2=./mptester$(EXE) mptest.db $(TOP)/mptest/multiwrite01.test --repeat 20 | > > > > | 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 | $(TCCX) $(READLINE_FLAGS) -o sqlite3$(EXE) \ $(TOP)/src/shell.c \ libsqlite3.a $(LIBREADLINE) $(TLIBS) $(THREADLIB) sqldiff$(EXE): $(TOP)/tool/sqldiff.c sqlite3.c sqlite3.h $(TCCX) -o sqldiff$(EXE) -DSQLITE_THREADSAFE=0 \ $(TOP)/tool/sqldiff.c sqlite3.c $(TLIBS) $(THREADLIB) fuzzershell$(EXE): $(TOP)/tool/fuzzershell.c sqlite3.c sqlite3.h $(TCCX) -o fuzzershell$(EXE) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION\ $(TOP)/tool/fuzzershell.c sqlite3.c $(TLIBS) $(THREADLIB) mptester$(EXE): sqlite3.c $(TOP)/mptest/mptest.c $(TCCX) -o $@ -I. $(TOP)/mptest/mptest.c sqlite3.c \ $(TLIBS) $(THREADLIB) MPTEST1=./mptester$(EXE) mptest.db $(TOP)/mptest/crash01.test --repeat 20 MPTEST2=./mptester$(EXE) mptest.db $(TOP)/mptest/multiwrite01.test --repeat 20 |
︙ | ︙ |
Changes to mptest/mptest.c.
︙ | ︙ | |||
48 49 50 51 52 53 54 55 56 57 58 59 60 61 | /* The suffix to append to the child command lines, if any */ #if defined(_WIN32) # define GETPID (int)GetCurrentProcessId #else # define GETPID getpid #endif /* Mark a parameter as unused to suppress compiler warnings */ #define UNUSED_PARAMETER(x) (void)x /* Global data */ static struct Global { | > > > > > > > | 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | /* The suffix to append to the child command lines, if any */ #if defined(_WIN32) # define GETPID (int)GetCurrentProcessId #else # define GETPID getpid #endif /* The directory separator character(s) */ #if defined(_WIN32) # define isDirSep(c) (((c) == '/') || ((c) == '\\')) #else # define isDirSep(c) ((c) == '/') #endif /* Mark a parameter as unused to suppress compiler warnings */ #define UNUSED_PARAMETER(x) (void)x /* Global data */ static struct Global { |
︙ | ︙ | |||
820 821 822 823 824 825 826 | } } /* Return a pointer to the tail of a filename */ static char *filenameTail(char *z){ int i, j; | | | 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 | } } /* Return a pointer to the tail of a filename */ static char *filenameTail(char *z){ int i, j; for(i=j=0; z[i]; i++) if( isDirSep(z[i]) ) j = i+1; return z+j; } /* ** Interpret zArg as a boolean value. Return either 0 or 1. */ static int booleanValue(char *zArg){ |
︙ | ︙ | |||
1017 1018 1019 1020 1021 1022 1023 | ** ** Run a subscript from a separate file. */ if( strcmp(zCmd, "source")==0 ){ char *zNewFile, *zNewScript; char *zToDel = 0; zNewFile = azArg[0]; | | | | 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 | ** ** Run a subscript from a separate file. */ if( strcmp(zCmd, "source")==0 ){ char *zNewFile, *zNewScript; char *zToDel = 0; zNewFile = azArg[0]; if( !isDirSep(zNewFile[0]) ){ int k; for(k=(int)strlen(zFilename)-1; k>=0 && !isDirSep(zFilename[k]); k--){} if( k>0 ){ zNewFile = zToDel = sqlite3_mprintf("%.*s/%s", k,zFilename,zNewFile); } } zNewScript = readFile(zNewFile); if( g.iTrace ) logMessage("begin script [%s]\n", zNewFile); runScript(0, 0, zNewScript, zNewFile); |
︙ | ︙ | |||
1227 1228 1229 1230 1231 1232 1233 | } /* Print a usage message for the program and exit */ static void usage(const char *argv0){ int i; const char *zTail = argv0; for(i=0; argv0[i]; i++){ | | | 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 | } /* Print a usage message for the program and exit */ static void usage(const char *argv0){ int i; const char *zTail = argv0; for(i=0; argv0[i]; i++){ if( isDirSep(argv0[i]) ) zTail = argv0+i+1; } fprintf(stderr,"Usage: %s DATABASE ?OPTIONS? ?SCRIPT?\n", zTail); exit(1); } /* Report on unrecognized arguments */ static void unrecognizedArguments( |
︙ | ︙ | |||
1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 | ){ printf("Changing journal mode to DELETE from %s", zJMode); zJMode = "DELETE"; } #endif runSql("PRAGMA journal_mode=%Q;", zJMode); } sqlite3_enable_load_extension(g.db, 1); sqlite3_busy_handler(g.db, busyHandler, 0); sqlite3_create_function(g.db, "vfsname", 0, SQLITE_UTF8, 0, vfsNameFunc, 0, 0); sqlite3_create_function(g.db, "eval", 1, SQLITE_UTF8, 0, evalFunc, 0, 0); g.iTimeout = DEFAULT_TIMEOUT; if( g.bSqlTrace ) sqlite3_trace(g.db, sqlTraceCallback, 0); | > < | 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 | ){ printf("Changing journal mode to DELETE from %s", zJMode); zJMode = "DELETE"; } #endif runSql("PRAGMA journal_mode=%Q;", zJMode); } if( !g.bSync ) trySql("PRAGMA synchronous=OFF"); sqlite3_enable_load_extension(g.db, 1); sqlite3_busy_handler(g.db, busyHandler, 0); sqlite3_create_function(g.db, "vfsname", 0, SQLITE_UTF8, 0, vfsNameFunc, 0, 0); sqlite3_create_function(g.db, "eval", 1, SQLITE_UTF8, 0, evalFunc, 0, 0); g.iTimeout = DEFAULT_TIMEOUT; if( g.bSqlTrace ) sqlite3_trace(g.db, sqlTraceCallback, 0); if( iClient>0 ){ if( n>0 ) unrecognizedArguments(argv[0], n, argv+2); if( g.iTrace ) logMessage("start-client"); while(1){ char *zTaskName = 0; rc = startScript(iClient, &zScript, &taskId, &zTaskName); if( rc==SQLITE_DONE ) break; |
︙ | ︙ |
Changes to src/attach.c.
︙ | ︙ | |||
328 329 330 331 332 333 334 | sName.pParse = pParse; if( SQLITE_OK!=(rc = resolveAttachExpr(&sName, pFilename)) || SQLITE_OK!=(rc = resolveAttachExpr(&sName, pDbname)) || SQLITE_OK!=(rc = resolveAttachExpr(&sName, pKey)) ){ | < | 328 329 330 331 332 333 334 335 336 337 338 339 340 341 | sName.pParse = pParse; if( SQLITE_OK!=(rc = resolveAttachExpr(&sName, pFilename)) || SQLITE_OK!=(rc = resolveAttachExpr(&sName, pDbname)) || SQLITE_OK!=(rc = resolveAttachExpr(&sName, pKey)) ){ goto attach_end; } #ifndef SQLITE_OMIT_AUTHORIZATION if( pAuthArg ){ char *zAuthArg; if( pAuthArg->op==TK_STRING ){ |
︙ | ︙ |
Changes to src/btree.c.
︙ | ︙ | |||
4474 4475 4476 4477 4478 4479 4480 4481 4482 4483 4484 4485 4486 | ** page of the database. The data might change or move the next time ** any btree routine is called. */ static const void *fetchPayload( BtCursor *pCur, /* Cursor pointing to entry to read from */ u32 *pAmt /* Write the number of available bytes here */ ){ assert( pCur!=0 && pCur->iPage>=0 && pCur->apPage[pCur->iPage]); assert( pCur->eState==CURSOR_VALID ); assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) ); assert( cursorHoldsMutex(pCur) ); assert( pCur->aiIdx[pCur->iPage]<pCur->apPage[pCur->iPage]->nCell ); assert( pCur->info.nSize>0 ); | > > > > > | | 4474 4475 4476 4477 4478 4479 4480 4481 4482 4483 4484 4485 4486 4487 4488 4489 4490 4491 4492 4493 4494 4495 4496 4497 4498 4499 | ** page of the database. The data might change or move the next time ** any btree routine is called. */ static const void *fetchPayload( BtCursor *pCur, /* Cursor pointing to entry to read from */ u32 *pAmt /* Write the number of available bytes here */ ){ u32 amt; assert( pCur!=0 && pCur->iPage>=0 && pCur->apPage[pCur->iPage]); assert( pCur->eState==CURSOR_VALID ); assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) ); assert( cursorHoldsMutex(pCur) ); assert( pCur->aiIdx[pCur->iPage]<pCur->apPage[pCur->iPage]->nCell ); assert( pCur->info.nSize>0 ); assert( pCur->info.pPayload>pCur->apPage[pCur->iPage]->aData || CORRUPT_DB ); assert( pCur->info.pPayload<pCur->apPage[pCur->iPage]->aDataEnd ||CORRUPT_DB); amt = (int)(pCur->apPage[pCur->iPage]->aDataEnd - pCur->info.pPayload); if( pCur->info.nLocal<amt ) amt = pCur->info.nLocal; *pAmt = amt; return (void*)pCur->info.pPayload; } /* ** For the entry that cursor pCur is point to, return as ** many bytes of the key or data as are available on the local |
︙ | ︙ | |||
8545 8546 8547 8548 8549 8550 8551 8552 8553 8554 8555 8556 8557 8558 | } #endif iPage = get4byte(pOvflData); sqlite3PagerUnref(pOvflPage); } } #endif /* SQLITE_OMIT_INTEGRITY_CHECK */ #ifndef SQLITE_OMIT_INTEGRITY_CHECK /* ** Do various sanity checks on a single page of a tree. Return ** the tree depth. Root pages return 0. Parents of root pages ** return 1, and so forth. ** | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 8550 8551 8552 8553 8554 8555 8556 8557 8558 8559 8560 8561 8562 8563 8564 8565 8566 8567 8568 8569 8570 8571 8572 8573 8574 8575 8576 8577 8578 8579 8580 8581 8582 8583 8584 8585 8586 8587 8588 8589 8590 8591 8592 8593 8594 8595 8596 8597 8598 8599 8600 8601 8602 8603 8604 8605 8606 8607 8608 8609 8610 8611 8612 8613 8614 | } #endif iPage = get4byte(pOvflData); sqlite3PagerUnref(pOvflPage); } } #endif /* SQLITE_OMIT_INTEGRITY_CHECK */ /* ** An implementation of a min-heap. ** ** aHeap[0] is the number of elements on the heap. aHeap[1] is the ** root element. The daughter nodes of aHeap[N] are aHeap[N*2] ** and aHeap[N*2+1]. ** ** The heap property is this: Every node is less than or equal to both ** of its daughter nodes. A consequence of the heap property is that the ** root node aHeap[1] is always the minimum value current in the heap. ** ** The btreeHeapInsert() routine inserts an unsigned 32-bit number onto ** the heap, preserving the heap property. The btreeHeapPull() routine ** removes the root element from the heap (the minimum value in the heap) ** and then move other nodes around as necessary to preserve the heap ** property. ** ** This heap is used for cell overlap and coverage testing. Each u32 ** entry represents the span of a cell or freeblock on a btree page. ** The upper 16 bits are the index of the first byte of a range and the ** lower 16 bits are the index of the last byte of that range. */ static void btreeHeapInsert(u32 *aHeap, u32 x){ u32 j, i = ++aHeap[0]; aHeap[i] = x; while( (j = i/2)>0 && aHeap[j]>aHeap[i] ){ x = aHeap[j]; aHeap[j] = aHeap[i]; aHeap[i] = x; i = j; } } static int btreeHeapPull(u32 *aHeap, u32 *pOut){ u32 j, i, x; if( (x = aHeap[0])==0 ) return 0; *pOut = aHeap[1]; aHeap[1] = aHeap[x]; aHeap[x] = 0xffffffff; aHeap[0]--; i = 1; while( (j = i*2)<=aHeap[0] ){ if( aHeap[j]>aHeap[j+1] ) j++; if( aHeap[i]<aHeap[j] ) break; x = aHeap[i]; aHeap[i] = aHeap[j]; aHeap[j] = x; i = j; } return 1; } #ifndef SQLITE_OMIT_INTEGRITY_CHECK /* ** Do various sanity checks on a single page of a tree. Return ** the tree depth. Root pages return 0. Parents of root pages ** return 1, and so forth. ** |
︙ | ︙ | |||
8578 8579 8580 8581 8582 8583 8584 | MemPage *pPage; int i, rc, depth, d2, pgno, cnt; int hdr, cellStart; int nCell; u8 *data; BtShared *pBt; int usableSize; | > | | 8634 8635 8636 8637 8638 8639 8640 8641 8642 8643 8644 8645 8646 8647 8648 8649 | MemPage *pPage; int i, rc, depth, d2, pgno, cnt; int hdr, cellStart; int nCell; u8 *data; BtShared *pBt; int usableSize; u32 *heap = 0; u32 x, prev = 0; i64 nMinKey = 0; i64 nMaxKey = 0; const char *saved_zPfx = pCheck->zPfx; int saved_v1 = pCheck->v1; int saved_v2 = pCheck->v2; /* Check that the page exists |
︙ | ︙ | |||
8723 8724 8725 8726 8727 8728 8729 | } } /* Check for complete coverage of the page */ data = pPage->aData; hdr = pPage->hdrOffset; | | | | | < | | < < | > > > > | | > > > > | | | 8780 8781 8782 8783 8784 8785 8786 8787 8788 8789 8790 8791 8792 8793 8794 8795 8796 8797 8798 8799 8800 8801 8802 8803 8804 8805 8806 8807 8808 8809 8810 8811 8812 8813 8814 8815 8816 8817 8818 8819 8820 8821 8822 8823 8824 8825 8826 8827 8828 8829 8830 8831 8832 8833 8834 8835 8836 8837 8838 8839 8840 8841 8842 8843 8844 8845 8846 8847 8848 8849 8850 8851 8852 8853 8854 8855 8856 8857 8858 8859 8860 8861 8862 8863 8864 8865 8866 8867 8868 8869 8870 8871 8872 | } } /* Check for complete coverage of the page */ data = pPage->aData; hdr = pPage->hdrOffset; heap = (u32*)sqlite3PageMalloc( pBt->pageSize ); pCheck->zPfx = 0; if( heap==0 ){ pCheck->mallocFailed = 1; }else{ int contentOffset = get2byteNotZero(&data[hdr+5]); assert( contentOffset<=usableSize ); /* Enforced by btreeInitPage() */ heap[0] = 0; btreeHeapInsert(heap, contentOffset-1); /* EVIDENCE-OF: R-37002-32774 The two-byte integer at offset 3 gives the ** number of cells on the page. */ nCell = get2byte(&data[hdr+3]); /* EVIDENCE-OF: R-23882-45353 The cell pointer array of a b-tree page ** immediately follows the b-tree page header. */ cellStart = hdr + 12 - 4*pPage->leaf; /* EVIDENCE-OF: R-02776-14802 The cell pointer array consists of K 2-byte ** integer offsets to the cell contents. */ for(i=0; i<nCell; i++){ int pc = get2byte(&data[cellStart+i*2]); u32 size = 65536; if( pc<=usableSize-4 ){ size = cellSizePtr(pPage, &data[pc]); } if( (int)(pc+size-1)>=usableSize ){ pCheck->zPfx = 0; checkAppendMsg(pCheck, "Corruption detected in cell %d on page %d",i,iPage); }else{ btreeHeapInsert(heap, (pc<<16)|(pc+size-1)); } } /* EVIDENCE-OF: R-20690-50594 The second field of the b-tree page header ** is the offset of the first freeblock, or zero if there are no ** freeblocks on the page. */ i = get2byte(&data[hdr+1]); while( i>0 ){ int size, j; assert( i<=usableSize-4 ); /* Enforced by btreeInitPage() */ size = get2byte(&data[i+2]); assert( i+size<=usableSize ); /* Enforced by btreeInitPage() */ btreeHeapInsert(heap, (i<<16)|(i+size-1)); /* EVIDENCE-OF: R-58208-19414 The first 2 bytes of a freeblock are a ** big-endian integer which is the offset in the b-tree page of the next ** freeblock in the chain, or zero if the freeblock is the last on the ** chain. */ j = get2byte(&data[i]); /* EVIDENCE-OF: R-06866-39125 Freeblocks are always connected in order of ** increasing offset. */ assert( j==0 || j>i+size ); /* Enforced by btreeInitPage() */ assert( j<=usableSize-4 ); /* Enforced by btreeInitPage() */ i = j; } cnt = 0; assert( heap[0]>0 ); assert( (heap[1]>>16)==0 ); btreeHeapPull(heap,&prev); while( btreeHeapPull(heap,&x) ){ if( (prev&0xffff)+1>(x>>16) ){ checkAppendMsg(pCheck, "Multiple uses for byte %u of page %d", x>>16, iPage); break; }else{ cnt += (x>>16) - (prev&0xffff) - 1; prev = x; } } cnt += usableSize - (prev&0xffff) - 1; /* EVIDENCE-OF: R-43263-13491 The total number of bytes in all fragments ** is stored in the fifth field of the b-tree page header. ** EVIDENCE-OF: R-07161-27322 The one-byte integer at offset 7 gives the ** number of fragmented free bytes within the cell content area. */ if( heap[0]==0 && cnt!=data[hdr+7] ){ checkAppendMsg(pCheck, "Fragmentation of %d bytes reported as %d on page %d", cnt, data[hdr+7], iPage); } } sqlite3PageFree(heap); releasePage(pPage); end_of_check: pCheck->zPfx = saved_zPfx; pCheck->v1 = saved_v1; pCheck->v2 = saved_v2; return depth+1; |
︙ | ︙ |
Changes to src/build.c.
︙ | ︙ | |||
138 139 140 141 142 143 144 | */ void sqlite3FinishCoding(Parse *pParse){ sqlite3 *db; Vdbe *v; assert( pParse->pToplevel==0 ); db = pParse->db; | > | | | > | 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 | */ void sqlite3FinishCoding(Parse *pParse){ sqlite3 *db; Vdbe *v; assert( pParse->pToplevel==0 ); db = pParse->db; if( pParse->nested ) return; if( db->mallocFailed || pParse->nErr ){ if( pParse->rc==SQLITE_OK ) pParse->rc = SQLITE_ERROR; return; } /* Begin by generating some termination code at the end of the ** vdbe program */ v = sqlite3GetVdbe(pParse); assert( !pParse->isMultiWrite || sqlite3VdbeAssertMayAbort(v, pParse->mayAbort)); |
︙ | ︙ | |||
757 758 759 760 761 762 763 | ){ int iDb; /* Database holding the object */ sqlite3 *db = pParse->db; if( ALWAYS(pName2!=0) && pName2->n>0 ){ if( db->init.busy ) { sqlite3ErrorMsg(pParse, "corrupt database"); | < < | 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 | ){ int iDb; /* Database holding the object */ sqlite3 *db = pParse->db; if( ALWAYS(pName2!=0) && pName2->n>0 ){ if( db->init.busy ) { sqlite3ErrorMsg(pParse, "corrupt database"); return -1; } *pUnqual = pName2; iDb = sqlite3FindDb(db, pName1); if( iDb<0 ){ sqlite3ErrorMsg(pParse, "unknown database %T", pName1); return -1; } }else{ assert( db->init.iDb==0 || db->init.busy ); iDb = db->init.iDb; *pUnqual = pName1; } |
︙ | ︙ | |||
923 924 925 926 927 928 929 | goto begin_table_error; } pTable = sqlite3FindTable(db, zName, zDb); if( pTable ){ if( !noErr ){ sqlite3ErrorMsg(pParse, "table %T already exists", pName); }else{ | | | 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 | 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 || CORRUPT_DB ); 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; |
︙ | ︙ | |||
1212 1213 1214 1215 1216 1217 1218 | void sqlite3AddColumnType(Parse *pParse, Token *pType){ Table *p; Column *pCol; p = pParse->pNewTable; if( p==0 || NEVER(p->nCol<1) ) return; pCol = &p->aCol[p->nCol-1]; | | > | 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 | void sqlite3AddColumnType(Parse *pParse, Token *pType){ Table *p; Column *pCol; p = pParse->pNewTable; if( p==0 || NEVER(p->nCol<1) ) return; pCol = &p->aCol[p->nCol-1]; assert( pCol->zType==0 || CORRUPT_DB ); sqlite3DbFree(pParse->db, pCol->zType); pCol->zType = sqlite3NameFromToken(pParse->db, pType); pCol->affinity = sqlite3AffinityType(pCol->zType, &pCol->szEst); } /* ** The expression is the default value for the most recently added column ** of the table currently under construction. |
︙ | ︙ | |||
2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 | int iDb; if( db->mallocFailed ){ goto exit_drop_table; } assert( pParse->nErr==0 ); assert( pName->nSrc==1 ); if( noErr ) db->suppressErr++; pTab = sqlite3LocateTableItem(pParse, isView, &pName->a[0]); if( noErr ) db->suppressErr--; if( pTab==0 ){ if( noErr ) sqlite3CodeVerifyNamedSchema(pParse, pName->a[0].zDatabase); goto exit_drop_table; | > | 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 | int iDb; if( db->mallocFailed ){ goto exit_drop_table; } assert( pParse->nErr==0 ); assert( pName->nSrc==1 ); if( sqlite3ReadSchema(pParse) ) goto exit_drop_table; if( noErr ) db->suppressErr++; pTab = sqlite3LocateTableItem(pParse, isView, &pName->a[0]); if( noErr ) db->suppressErr--; if( pTab==0 ){ if( noErr ) sqlite3CodeVerifyNamedSchema(pParse, pName->a[0].zDatabase); goto exit_drop_table; |
︙ | ︙ | |||
2853 2854 2855 2856 2857 2858 2859 | struct ExprList_item *pListItem; /* For looping over pList */ const Column *pTabCol; /* A column in the table */ int nExtra = 0; /* Space allocated for zExtra[] */ int nExtraCol; /* Number of extra columns needed */ char *zExtra = 0; /* Extra space after the Index object */ Index *pPk = 0; /* PRIMARY KEY index for WITHOUT ROWID tables */ | < | | 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 | struct ExprList_item *pListItem; /* For looping over pList */ const Column *pTabCol; /* A column in the table */ int nExtra = 0; /* Space allocated for zExtra[] */ int nExtraCol; /* Number of extra columns needed */ char *zExtra = 0; /* Extra space after the Index object */ Index *pPk = 0; /* PRIMARY KEY index for WITHOUT ROWID tables */ if( db->mallocFailed || IN_DECLARE_VTAB || pParse->nErr>0 ){ goto exit_create_index; } if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){ goto exit_create_index; } /* |
︙ | ︙ |
Changes to src/expr.c.
︙ | ︙ | |||
1247 1248 1249 1250 1251 1252 1253 | ** ExprList. */ u32 sqlite3ExprListFlags(const ExprList *pList){ int i; u32 m = 0; if( pList ){ for(i=0; i<pList->nExpr; i++){ | > | | 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 | ** ExprList. */ u32 sqlite3ExprListFlags(const ExprList *pList){ int i; u32 m = 0; if( pList ){ for(i=0; i<pList->nExpr; i++){ Expr *pExpr = pList->a[i].pExpr; if( ALWAYS(pExpr) ) m |= pList->a[i].pExpr->flags; } } return m; } /* ** These routines are Walker callbacks used to check expressions to |
︙ | ︙ | |||
2012 2013 2014 2015 2016 2017 2018 | sqlite3VdbeAddOp2(v, OP_Integer, 0, dest.iSDParm); VdbeComment((v, "Init EXISTS result")); } sqlite3ExprDelete(pParse->db, pSel->pLimit); pSel->pLimit = sqlite3PExpr(pParse, TK_INTEGER, 0, 0, &sqlite3IntTokens[1]); pSel->iLimit = 0; | | | 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 | sqlite3VdbeAddOp2(v, OP_Integer, 0, dest.iSDParm); VdbeComment((v, "Init EXISTS result")); } sqlite3ExprDelete(pParse->db, pSel->pLimit); pSel->pLimit = sqlite3PExpr(pParse, TK_INTEGER, 0, 0, &sqlite3IntTokens[1]); pSel->iLimit = 0; pSel->selFlags &= ~SF_MultiValue; if( sqlite3Select(pParse, pSel, &dest) ){ return 0; } rReg = dest.iSDParm; ExprSetVVAProperty(pExpr, EP_NoReduce); break; } |
︙ | ︙ | |||
4013 4014 4015 4016 4017 4018 4019 | } if( (pA->flags & EP_Distinct)!=(pB->flags & EP_Distinct) ) return 2; if( ALWAYS((combinedFlags & EP_TokenOnly)==0) ){ if( combinedFlags & EP_xIsSelect ) return 2; if( sqlite3ExprCompare(pA->pLeft, pB->pLeft, iTab) ) return 2; if( sqlite3ExprCompare(pA->pRight, pB->pRight, iTab) ) return 2; if( sqlite3ExprListCompare(pA->x.pList, pB->x.pList, iTab) ) return 2; | | | 4014 4015 4016 4017 4018 4019 4020 4021 4022 4023 4024 4025 4026 4027 4028 | } if( (pA->flags & EP_Distinct)!=(pB->flags & EP_Distinct) ) return 2; if( ALWAYS((combinedFlags & EP_TokenOnly)==0) ){ if( combinedFlags & EP_xIsSelect ) return 2; if( sqlite3ExprCompare(pA->pLeft, pB->pLeft, iTab) ) return 2; if( sqlite3ExprCompare(pA->pRight, pB->pRight, iTab) ) return 2; if( sqlite3ExprListCompare(pA->x.pList, pB->x.pList, iTab) ) return 2; if( ALWAYS((combinedFlags & EP_Reduced)==0) && pA->op!=TK_STRING ){ if( pA->iColumn!=pB->iColumn ) return 2; if( pA->iTable!=pB->iTable && (pA->iTable!=iTab || NEVER(pB->iTable>=0)) ) return 2; } } return 0; } |
︙ | ︙ |
Changes to src/insert.c.
︙ | ︙ | |||
338 339 340 341 342 343 344 | int onError, /* How to handle constraint errors */ int iDbDest /* The database of pDest */ ); /* ** This routine is called to handle SQL of the following forms: ** | | > | | > | > | | | | | 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 | int onError, /* How to handle constraint errors */ int iDbDest /* The database of pDest */ ); /* ** This routine is called to handle SQL of the following forms: ** ** insert into TABLE (IDLIST) values(EXPRLIST),(EXPRLIST),... ** insert into TABLE (IDLIST) select ** insert into TABLE (IDLIST) default values ** ** The IDLIST following the table name is always optional. If omitted, ** then a list of all (non-hidden) columns for the table is substituted. ** The IDLIST appears in the pColumn parameter. pColumn is NULL if IDLIST ** is omitted. ** ** For the pSelect parameter holds the values to be inserted for the ** first two forms shown above. A VALUES clause is really just short-hand ** for a SELECT statement that omits the FROM clause and everything else ** that follows. If the pSelect parameter is NULL, that means that the ** DEFAULT VALUES form of the INSERT statement is intended. ** ** The code generated follows one of four templates. For a simple ** insert with data coming from a single-row VALUES clause, the code executes ** once straight down through. Pseudo-code follows (we call this ** the "1st template"): ** ** open write cursor to <table> and its indices ** put VALUES clause expressions into registers ** write the resulting record into <table> ** cleanup |
︙ | ︙ | |||
458 459 460 461 462 463 464 | int addrCont = 0; /* Top of insert loop. Label "C" in templates 3 and 4 */ SelectDest dest; /* Destination for SELECT on rhs of INSERT */ int iDb; /* Index of database holding TABLE */ Db *pDb; /* The database containing table being inserted into */ u8 useTempTable = 0; /* Store SELECT results in intermediate table */ u8 appendFlag = 0; /* True if the insert is likely to be an append */ u8 withoutRowid; /* 0 for normal table. 1 for WITHOUT ROWID table */ | | | 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 | int addrCont = 0; /* Top of insert loop. Label "C" in templates 3 and 4 */ SelectDest dest; /* Destination for SELECT on rhs of INSERT */ int iDb; /* Index of database holding TABLE */ Db *pDb; /* The database containing table being inserted into */ u8 useTempTable = 0; /* Store SELECT results in intermediate table */ u8 appendFlag = 0; /* True if the insert is likely to be an append */ u8 withoutRowid; /* 0 for normal table. 1 for WITHOUT ROWID table */ u8 bIdListInOrder; /* True if IDLIST is in table order */ ExprList *pList = 0; /* List of VALUES() to be inserted */ /* Register allocations */ int regFromSelect = 0;/* Base register for data coming from SELECT */ int regAutoinc = 0; /* Register holding the AUTOINCREMENT counter */ int regRowCount = 0; /* Memory cell used for the row counter */ int regIns; /* Block of regs holding rowid+data being inserted */ |
︙ | ︙ | |||
483 484 485 486 487 488 489 | db = pParse->db; memset(&dest, 0, sizeof(dest)); if( pParse->nErr || db->mallocFailed ){ goto insert_cleanup; } /* If the Select object is really just a simple VALUES() list with a | | | | 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 | db = pParse->db; memset(&dest, 0, sizeof(dest)); if( pParse->nErr || db->mallocFailed ){ goto insert_cleanup; } /* If the Select object is really just a simple VALUES() list with a ** single row (the common case) then keep that one row of values ** and discard the other (unused) parts of the pSelect object */ if( pSelect && (pSelect->selFlags & SF_Values)!=0 && pSelect->pPrior==0 ){ pList = pSelect->pEList; pSelect->pEList = 0; sqlite3SelectDelete(db, pSelect); pSelect = 0; } |
︙ | ︙ | |||
592 593 594 595 596 597 598 599 600 601 602 603 604 605 | ** If the table has an INTEGER PRIMARY KEY column and that column ** is named in the IDLIST, then record in the ipkColumn variable ** the index into IDLIST of the primary key column. ipkColumn is ** the index of the primary key as it appears in IDLIST, not as ** is appears in the original table. (The index of the INTEGER ** PRIMARY KEY in the original table is pTab->iPKey.) */ if( pColumn ){ for(i=0; i<pColumn->nId; i++){ pColumn->a[i].idx = -1; } for(i=0; i<pColumn->nId; i++){ for(j=0; j<pTab->nCol; j++){ if( sqlite3StrICmp(pColumn->a[i].zName, pTab->aCol[j].zName)==0 ){ | > | 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 | ** If the table has an INTEGER PRIMARY KEY column and that column ** is named in the IDLIST, then record in the ipkColumn variable ** the index into IDLIST of the primary key column. ipkColumn is ** the index of the primary key as it appears in IDLIST, not as ** is appears in the original table. (The index of the INTEGER ** PRIMARY KEY in the original table is pTab->iPKey.) */ bIdListInOrder = (pTab->tabFlags & TF_OOOHidden)==0; if( pColumn ){ for(i=0; i<pColumn->nId; i++){ pColumn->a[i].idx = -1; } for(i=0; i<pColumn->nId; i++){ for(j=0; j<pTab->nCol; j++){ if( sqlite3StrICmp(pColumn->a[i].zName, pTab->aCol[j].zName)==0 ){ |
︙ | ︙ | |||
627 628 629 630 631 632 633 | /* Figure out how many columns of data are supplied. If the data ** is coming from a SELECT statement, then generate a co-routine that ** produces a single row of the SELECT on each invocation. The ** co-routine is the common header to the 3rd and 4th templates. */ if( pSelect ){ | > | < | | 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 | /* Figure out how many columns of data are supplied. If the data ** is coming from a SELECT statement, then generate a co-routine that ** produces a single row of the SELECT on each invocation. The ** co-routine is the common header to the 3rd and 4th templates. */ if( pSelect ){ /* Data is coming from a SELECT or from a multi-row VALUES clause. ** Generate a co-routine to run the SELECT. */ int regYield; /* Register holding co-routine entry-point */ int addrTop; /* Top of the co-routine */ int rc; /* Result code */ regYield = ++pParse->nMem; addrTop = sqlite3VdbeCurrentAddr(v) + 1; sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, addrTop); sqlite3SelectDestInit(&dest, SRT_Coroutine, regYield); dest.iSdst = bIdListInOrder ? regData : 0; dest.nSdst = pTab->nCol; rc = sqlite3Select(pParse, pSelect, &dest); regFromSelect = dest.iSdst; if( rc || db->mallocFailed || pParse->nErr ) goto insert_cleanup; sqlite3VdbeAddOp1(v, OP_EndCoroutine, regYield); sqlite3VdbeJumpHere(v, addrTop - 1); /* label B: */ assert( pSelect->pEList ); nColumn = pSelect->pEList->nExpr; /* Set useTempTable to TRUE if the result of the SELECT statement ** should be written into a temporary table (template 4). Set to |
︙ | ︙ | |||
689 690 691 692 693 694 695 | sqlite3VdbeAddOp3(v, OP_Insert, srcTab, regRec, regTempRowid); sqlite3VdbeAddOp2(v, OP_Goto, 0, addrL); sqlite3VdbeJumpHere(v, addrL); sqlite3ReleaseTempReg(pParse, regRec); sqlite3ReleaseTempReg(pParse, regTempRowid); } }else{ | | | | 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 | sqlite3VdbeAddOp3(v, OP_Insert, srcTab, regRec, regTempRowid); sqlite3VdbeAddOp2(v, OP_Goto, 0, addrL); sqlite3VdbeJumpHere(v, addrL); sqlite3ReleaseTempReg(pParse, regRec); sqlite3ReleaseTempReg(pParse, regTempRowid); } }else{ /* This is the case if the data for the INSERT is coming from a ** single-row VALUES clause */ NameContext sNC; memset(&sNC, 0, sizeof(sNC)); sNC.pParse = pParse; srcTab = -1; assert( useTempTable==0 ); nColumn = pList ? pList->nExpr : 0; |
︙ | ︙ |
Changes to src/parse.y.
︙ | ︙ | |||
405 406 407 408 409 410 411 | %type select {Select*} %destructor select {sqlite3SelectDelete(pParse->db, $$);} %type selectnowith {Select*} %destructor selectnowith {sqlite3SelectDelete(pParse->db, $$);} %type oneselect {Select*} %destructor oneselect {sqlite3SelectDelete(pParse->db, $$);} | < < | > > > > > | < < | > < < | < | | > > > > > > > > > > | 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 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 | %type select {Select*} %destructor select {sqlite3SelectDelete(pParse->db, $$);} %type selectnowith {Select*} %destructor selectnowith {sqlite3SelectDelete(pParse->db, $$);} %type oneselect {Select*} %destructor oneselect {sqlite3SelectDelete(pParse->db, $$);} %include { /* ** For a compound SELECT statement, make sure p->pPrior->pNext==p for ** all elements in the list. And make sure list length does not exceed ** SQLITE_LIMIT_COMPOUND_SELECT. */ static void parserDoubleLinkSelect(Parse *pParse, Select *p){ if( p->pPrior ){ Select *pNext = 0, *pLoop; int mxSelect, cnt = 0; for(pLoop=p; pLoop; pNext=pLoop, pLoop=pLoop->pPrior, cnt++){ pLoop->pNext = pNext; pLoop->selFlags |= SF_Compound; } if( (p->selFlags & SF_MultiValue)==0 && (mxSelect = pParse->db->aLimit[SQLITE_LIMIT_COMPOUND_SELECT])>0 && cnt>mxSelect ){ sqlite3ErrorMsg(pParse, "too many terms in compound SELECT"); } } } } select(A) ::= with(W) selectnowith(X). { Select *p = X; if( p ){ p->pWith = W; parserDoubleLinkSelect(pParse, p); }else{ sqlite3WithDelete(pParse->db, W); } A = p; } selectnowith(A) ::= oneselect(X). {A = X;} %ifndef SQLITE_OMIT_COMPOUND_SELECT selectnowith(A) ::= selectnowith(X) multiselect_op(Y) oneselect(Z). { Select *pRhs = Z; if( pRhs && pRhs->pPrior ){ SrcList *pFrom; Token x; x.n = 0; parserDoubleLinkSelect(pParse, pRhs); pFrom = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&x,pRhs,0,0); pRhs = sqlite3SelectNew(pParse,0,pFrom,0,0,0,0,0,0,0); } if( pRhs ){ pRhs->op = (u8)Y; pRhs->pPrior = X; pRhs->selFlags &= ~SF_MultiValue; if( Y!=TK_ALL ) pParse->hasCompound = 1; }else{ sqlite3SelectDelete(pParse->db, X); } A = pRhs; } %type multiselect_op {int} |
︙ | ︙ | |||
494 495 496 497 498 499 500 | %type values {Select*} %destructor values {sqlite3SelectDelete(pParse->db, $$);} values(A) ::= VALUES LP nexprlist(X) RP. { A = sqlite3SelectNew(pParse,X,0,0,0,0,0,SF_Values,0,0); } values(A) ::= values(X) COMMA LP exprlist(Y) RP. { | > | > > | | | 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 | %type values {Select*} %destructor values {sqlite3SelectDelete(pParse->db, $$);} values(A) ::= VALUES LP nexprlist(X) RP. { A = sqlite3SelectNew(pParse,X,0,0,0,0,0,SF_Values,0,0); } values(A) ::= values(X) COMMA LP exprlist(Y) RP. { Select *pRight, *pLeft = X; pRight = sqlite3SelectNew(pParse,Y,0,0,0,0,0,SF_Values|SF_MultiValue,0,0); if( ALWAYS(pLeft) ) pLeft->selFlags &= ~SF_MultiValue; if( pRight ){ pRight->op = TK_ALL; pLeft = X; pRight->pPrior = pLeft; A = pRight; }else{ A = pLeft; } } // The "distinct" nonterminal is true (1) if the DISTINCT keyword is // present and false (0) if it is not. // %type distinct {u16} |
︙ | ︙ |
Changes to src/pragma.c.
︙ | ︙ | |||
957 958 959 960 961 962 963 | returnSingleInt(pParse, "synchronous", SQLITE_DbSafetyLevelValue(pDb->safety_level)-1); }else{ if( !db->autoCommit ){ sqlite3ErrorMsg(pParse, "Safety level may not be changed inside a transaction"); }else{ | | > > > | 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 | returnSingleInt(pParse, "synchronous", SQLITE_DbSafetyLevelValue(pDb->safety_level)-1); }else{ if( !db->autoCommit ){ sqlite3ErrorMsg(pParse, "Safety level may not be changed inside a transaction"); }else{ int iLevel = (getSafetyLevel(zRight,0,1)+1) | SQLITE_SAFETYLEVEL_FIXED; iLevel &= PAGER_SYNCHRONOUS_MASK; if( iLevel==0 ) iLevel = 1; pDb->safety_level = iLevel; setAllPagerFlags(db); } } break; } #endif /* SQLITE_OMIT_PAGER_PRAGMAS */ |
︙ | ︙ |
Changes to src/prepare.c.
︙ | ︙ | |||
66 67 68 69 70 71 72 | return 1; } assert( iDb>=0 && iDb<db->nDb ); if( argv==0 ) return 0; /* Might happen if EMPTY_RESULT_CALLBACKS are on */ if( argv[1]==0 ){ corruptSchema(pData, argv[0], 0); | | | 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | return 1; } assert( iDb>=0 && iDb<db->nDb ); if( argv==0 ) return 0; /* Might happen if EMPTY_RESULT_CALLBACKS are on */ if( argv[1]==0 ){ corruptSchema(pData, argv[0], 0); }else if( sqlite3_strnicmp(argv[2],"create ",7)==0 ){ /* Call the parser to process a CREATE TABLE, INDEX or VIEW. ** But because db->init.busy is set to 1, no VDBE code is generated ** or executed. All the parser does is build the internal data ** structures that describe the table, index, or view. */ int rc; sqlite3_stmt *pStmt; |
︙ | ︙ | |||
97 98 99 100 101 102 103 | db->mallocFailed = 1; }else if( rc!=SQLITE_INTERRUPT && (rc&0xFF)!=SQLITE_LOCKED ){ corruptSchema(pData, argv[0], sqlite3_errmsg(db)); } } } sqlite3_finalize(pStmt); | | | | 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 | db->mallocFailed = 1; }else if( rc!=SQLITE_INTERRUPT && (rc&0xFF)!=SQLITE_LOCKED ){ corruptSchema(pData, argv[0], sqlite3_errmsg(db)); } } } sqlite3_finalize(pStmt); }else if( argv[0]==0 || (argv[2]!=0 && argv[2][0]!=0) ){ corruptSchema(pData, argv[0], 0); }else{ /* If the SQL column is blank it means this is an index that ** was created to be the PRIMARY KEY or to fulfill a UNIQUE ** constraint for a CREATE TABLE. The index should have already ** been created when we processed the CREATE TABLE. All we have ** to do here is record the root page number for that index. */ |
︙ | ︙ |
Changes to src/resolve.c.
︙ | ︙ | |||
456 457 458 459 460 461 462 | ** ** Because no reference was made to outer contexts, the pNC->nRef ** fields are not changed in any context. */ if( cnt==0 && zTab==0 && ExprHasProperty(pExpr,EP_DblQuoted) ){ pExpr->op = TK_STRING; pExpr->pTab = 0; | < | 456 457 458 459 460 461 462 463 464 465 466 467 468 469 | ** ** Because no reference was made to outer contexts, the pNC->nRef ** fields are not changed in any context. */ if( cnt==0 && zTab==0 && ExprHasProperty(pExpr,EP_DblQuoted) ){ pExpr->op = TK_STRING; pExpr->pTab = 0; return WRC_Prune; } /* ** cnt==0 means there was not match. cnt>1 means there were two or ** more matches. Either way, we have an error. */ |
︙ | ︙ | |||
1296 1297 1298 1299 1300 1301 1302 1303 | pSub->pOrderBy = 0; } /* Process the ORDER BY clause for singleton SELECT statements. ** The ORDER BY clause for compounds SELECT statements is handled ** below, after all of the result-sets for all of the elements of ** the compound have been resolved. */ | > > > > > > | > | 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 | pSub->pOrderBy = 0; } /* Process the ORDER BY clause for singleton SELECT statements. ** The ORDER BY clause for compounds SELECT statements is handled ** below, after all of the result-sets for all of the elements of ** the compound have been resolved. ** ** If there is an ORDER BY clause on a term of a compound-select other ** than the right-most term, then that is a syntax error. But the error ** is not detected until much later, and so we need to go ahead and ** resolve those symbols on the incorrect ORDER BY for consistency. */ if( isCompound<=nCompound /* Defer right-most ORDER BY of a compound */ && resolveOrderGroupBy(&sNC, p, p->pOrderBy, "ORDER") ){ return WRC_Abort; } if( db->mallocFailed ){ return WRC_Abort; } /* Resolve the GROUP BY clause. At the same time, make sure |
︙ | ︙ |
Changes to src/select.c.
︙ | ︙ | |||
107 108 109 110 111 112 113 | Expr *pLimit, /* LIMIT value. NULL means not used */ Expr *pOffset /* OFFSET value. NULL means no offset */ ){ Select *pNew; Select standin; sqlite3 *db = pParse->db; pNew = sqlite3DbMallocZero(db, sizeof(*pNew) ); | < | | 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 | Expr *pLimit, /* LIMIT value. NULL means not used */ Expr *pOffset /* OFFSET value. NULL means no offset */ ){ Select *pNew; Select standin; sqlite3 *db = pParse->db; pNew = sqlite3DbMallocZero(db, sizeof(*pNew) ); if( pNew==0 ){ assert( db->mallocFailed ); pNew = &standin; memset(pNew, 0, sizeof(*pNew)); } if( pEList==0 ){ pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db,TK_ALL,0)); } pNew->pEList = pEList; if( pSrc==0 ) pSrc = sqlite3DbMallocZero(db, sizeof(*pSrc)); pNew->pSrc = pSrc; pNew->pWhere = pWhere; pNew->pGroupBy = pGroupBy; pNew->pHaving = pHaving; pNew->pOrderBy = pOrderBy; pNew->selFlags = selFlags; pNew->op = TK_SELECT; pNew->pLimit = pLimit; pNew->pOffset = pOffset; assert( pOffset==0 || pLimit!=0 || pParse->nErr>0 || db->mallocFailed!=0 ); pNew->addrOpenEphm[0] = -1; pNew->addrOpenEphm[1] = -1; if( db->mallocFailed ) { clearSelect(db, pNew, pNew!=&standin); pNew = 0; }else{ assert( pNew->pSrc!=0 || pParse->nErr>0 ); |
︙ | ︙ | |||
1377 1378 1379 1380 1381 1382 1383 | assert( pTab && pExpr->pTab==pTab ); if( pS ){ /* The "table" is actually a sub-select or a view in the FROM clause ** of the SELECT statement. Return the declaration type and origin ** data for the result-set column of the sub-select. */ | | | 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 | assert( pTab && pExpr->pTab==pTab ); if( pS ){ /* The "table" is actually a sub-select or a view in the FROM clause ** of the SELECT statement. Return the declaration type and origin ** data for the result-set column of the sub-select. */ if( iCol>=0 && iCol<pS->pEList->nExpr ){ /* If iCol is less than zero, then the expression requests the ** rowid of the sub-select or view. This expression is legal (see ** test case misc2.2.2) - it always evaluates to NULL. */ NameContext sNC; Expr *p = pS->pEList->a[iCol].pExpr; sNC.pSrcList = pS->pSrc; |
︙ | ︙ | |||
2104 2105 2106 2107 2108 2109 2110 | Select *p, /* The right-most of SELECTs to be coded */ SelectDest *pDest /* What to do with query results */ ){ Select *pPrior; int nExpr = p->pEList->nExpr; int nRow = 1; int rc = 0; | < | | 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 | Select *p, /* The right-most of SELECTs to be coded */ SelectDest *pDest /* What to do with query results */ ){ Select *pPrior; int nExpr = p->pEList->nExpr; int nRow = 1; int rc = 0; assert( p->selFlags & SF_MultiValue ); do{ assert( p->selFlags & SF_Values ); assert( p->op==TK_ALL || (p->op==TK_SELECT && p->pPrior==0) ); assert( p->pLimit==0 ); assert( p->pOffset==0 ); if( p->pEList->nExpr!=nExpr ){ selectWrongNumTermsError(pParse, p); |
︙ | ︙ | |||
2214 2215 2216 2217 2218 2219 2220 | sqlite3VdbeAddOp2(v, OP_OpenEphemeral, dest.iSDParm, p->pEList->nExpr); sqlite3VdbeChangeP5(v, BTREE_UNORDERED); dest.eDest = SRT_Table; } /* Special handling for a compound-select that originates as a VALUES clause. */ | | | 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 | sqlite3VdbeAddOp2(v, OP_OpenEphemeral, dest.iSDParm, p->pEList->nExpr); sqlite3VdbeChangeP5(v, BTREE_UNORDERED); dest.eDest = SRT_Table; } /* Special handling for a compound-select that originates as a VALUES clause. */ if( p->selFlags & SF_MultiValue ){ rc = multiSelectValues(pParse, p, &dest); goto multi_select_end; } /* Make sure all SELECTs in the statement have the same number of elements ** in their result sets. */ |
︙ | ︙ | |||
2625 2626 2627 2628 2629 2630 2631 | #endif /* If this is a scalar select that is part of an expression, then ** store the results in the appropriate memory cell and break out ** of the scan loop. */ case SRT_Mem: { | | | 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 | #endif /* If this is a scalar select that is part of an expression, then ** store the results in the appropriate memory cell and break out ** of the scan loop. */ case SRT_Mem: { assert( pIn->nSdst==1 || pParse->nErr>0 ); testcase( pIn->nSdst!=1 ); sqlite3ExprCodeMove(pParse, pIn->iSdst, pDest->iSDParm, 1); /* The LIMIT clause will jump out of the loop for us */ break; } #endif /* #ifndef SQLITE_OMIT_SUBQUERY */ /* The results are stored in a sequence of registers |
︙ | ︙ | |||
2856 2857 2858 2859 2860 2861 2862 | ** to the right and the left are evaluated, they use the correct ** collation. */ aPermute = sqlite3DbMallocRaw(db, sizeof(int)*nOrderBy); if( aPermute ){ struct ExprList_item *pItem; for(i=0, pItem=pOrderBy->a; i<nOrderBy; i++, pItem++){ | | | > > | 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 | ** to the right and the left are evaluated, they use the correct ** collation. */ aPermute = sqlite3DbMallocRaw(db, sizeof(int)*nOrderBy); if( aPermute ){ struct ExprList_item *pItem; for(i=0, pItem=pOrderBy->a; i<nOrderBy; i++, pItem++){ assert( pItem->u.x.iOrderByCol>0 ); /* assert( pItem->u.x.iOrderByCol<=p->pEList->nExpr ) is also true ** but only for well-formed SELECT statements. */ testcase( pItem->u.x.iOrderByCol > p->pEList->nExpr ); aPermute[i] = pItem->u.x.iOrderByCol - 1; } pKeyMerge = multiSelectOrderByKeyInfo(pParse, p, 1); }else{ pKeyMerge = 0; } |
︙ | ︙ | |||
4418 4419 4420 4421 4422 4423 4424 | w.xExprCallback = exprWalkNoop; w.pParse = pParse; if( pParse->hasCompound ){ w.xSelectCallback = convertCompoundSelectToSubquery; sqlite3WalkSelect(&w, pSelect); } w.xSelectCallback = selectExpander; | | | 4418 4419 4420 4421 4422 4423 4424 4425 4426 4427 4428 4429 4430 4431 4432 | w.xExprCallback = exprWalkNoop; w.pParse = pParse; if( pParse->hasCompound ){ w.xSelectCallback = convertCompoundSelectToSubquery; sqlite3WalkSelect(&w, pSelect); } w.xSelectCallback = selectExpander; if( (pSelect->selFlags & SF_MultiValue)==0 ){ w.xSelectCallback2 = selectPopWith; } sqlite3WalkSelect(&w, pSelect); } #ifndef SQLITE_OMIT_SUBQUERY |
︙ | ︙ | |||
5479 5480 5481 5482 5483 5484 5485 | generateSortTail(pParse, p, &sSort, pEList->nExpr, pDest); } /* Jump here to skip this query */ sqlite3VdbeResolveLabel(v, iEnd); | > | < < | | 5479 5480 5481 5482 5483 5484 5485 5486 5487 5488 5489 5490 5491 5492 5493 5494 5495 | generateSortTail(pParse, p, &sSort, pEList->nExpr, pDest); } /* Jump here to skip this query */ sqlite3VdbeResolveLabel(v, iEnd); /* The SELECT has been coded. If there is an error in the Parse structure, ** set the return code to 1. Otherwise 0. */ rc = (pParse->nErr>0); /* Control jumps to here if an error is encountered above, or upon ** successful coding of the SELECT. */ select_end: explainSetInteger(pParse->iSelectId, iRestoreSelectId); |
︙ | ︙ |
Changes to src/shell.c.
︙ | ︙ | |||
523 524 525 526 527 528 529 530 531 532 533 534 535 536 | typedef struct ShellState ShellState; struct ShellState { sqlite3 *db; /* The database */ int echoOn; /* True to echo input commands */ int autoEQP; /* Run EXPLAIN QUERY PLAN prior to seach SQL stmt */ int statsOn; /* True to display memory stats before each finalize */ int scanstatsOn; /* True to display scan stats before each finalize */ int outCount; /* Revert to stdout when reaching zero */ int cnt; /* Number of records displayed so far */ FILE *out; /* Write results here */ FILE *traceOut; /* Output for sqlite3_trace() */ int nErr; /* Number of errors seen */ int mode; /* An output mode setting */ int writableSchema; /* True if PRAGMA writable_schema=ON */ | > | 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 | typedef struct ShellState ShellState; struct ShellState { sqlite3 *db; /* The database */ int echoOn; /* True to echo input commands */ int autoEQP; /* Run EXPLAIN QUERY PLAN prior to seach SQL stmt */ int statsOn; /* True to display memory stats before each finalize */ int scanstatsOn; /* True to display scan stats before each finalize */ int backslashOn; /* Resolve C-style \x escapes in SQL input text */ int outCount; /* Revert to stdout when reaching zero */ int cnt; /* Number of records displayed so far */ FILE *out; /* Write results here */ FILE *traceOut; /* Output for sqlite3_trace() */ int nErr; /* Number of errors seen */ int mode; /* An output mode setting */ int writableSchema; /* True if PRAGMA writable_schema=ON */ |
︙ | ︙ | |||
1940 1941 1942 1943 1944 1945 1946 | ** \\ -> backslash */ static void resolve_backslashes(char *z){ int i, j; char c; while( *z && *z!='\\' ) z++; for(i=j=0; (c = z[i])!=0; i++, j++){ | | | 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 | ** \\ -> backslash */ static void resolve_backslashes(char *z){ int i, j; char c; while( *z && *z!='\\' ) z++; for(i=j=0; (c = z[i])!=0; i++, j++){ if( c=='\\' && z[i+1]!=0 ){ c = z[++i]; if( c=='n' ){ c = '\n'; }else if( c=='t' ){ c = '\t'; }else if( c=='r' ){ c = '\r'; |
︙ | ︙ | |||
4107 4108 4109 4110 4111 4112 4113 4114 4115 4116 4117 4118 4119 4120 | memcpy(zSql+nSql, zLine, nLine+1); nSql += nLine; } if( nSql && line_contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior) && sqlite3_complete(zSql) ){ p->cnt = 0; open_db(p, 0); BEGIN_TIMER; rc = shell_exec(p->db, zSql, shell_callback, p, &zErrMsg); END_TIMER; if( rc || zErrMsg ){ char zPrefix[100]; if( in!=0 || !stdin_is_interactive ){ sqlite3_snprintf(sizeof(zPrefix), zPrefix, | > | 4108 4109 4110 4111 4112 4113 4114 4115 4116 4117 4118 4119 4120 4121 4122 | memcpy(zSql+nSql, zLine, nLine+1); nSql += nLine; } if( nSql && line_contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior) && sqlite3_complete(zSql) ){ p->cnt = 0; open_db(p, 0); if( p->backslashOn ) resolve_backslashes(zSql); BEGIN_TIMER; rc = shell_exec(p->db, zSql, shell_callback, p, &zErrMsg); END_TIMER; if( rc || zErrMsg ){ char zPrefix[100]; if( in!=0 || !stdin_is_interactive ){ sqlite3_snprintf(sizeof(zPrefix), zPrefix, |
︙ | ︙ | |||
4573 4574 4575 4576 4577 4578 4579 4580 4581 4582 4583 4584 4585 4586 | data.echoOn = 1; }else if( strcmp(z,"-eqp")==0 ){ data.autoEQP = 1; }else if( strcmp(z,"-stats")==0 ){ data.statsOn = 1; }else if( strcmp(z,"-scanstats")==0 ){ data.scanstatsOn = 1; }else if( strcmp(z,"-bail")==0 ){ bail_on_error = 1; }else if( strcmp(z,"-version")==0 ){ printf("%s %s\n", sqlite3_libversion(), sqlite3_sourceid()); return 0; }else if( strcmp(z,"-interactive")==0 ){ stdin_is_interactive = 1; | > > > > > > > | 4575 4576 4577 4578 4579 4580 4581 4582 4583 4584 4585 4586 4587 4588 4589 4590 4591 4592 4593 4594 4595 | data.echoOn = 1; }else if( strcmp(z,"-eqp")==0 ){ data.autoEQP = 1; }else if( strcmp(z,"-stats")==0 ){ data.statsOn = 1; }else if( strcmp(z,"-scanstats")==0 ){ data.scanstatsOn = 1; }else if( strcmp(z,"-backslash")==0 ){ /* Undocumented command-line option: -backslash ** Causes C-style backslash escapes to be evaluated in SQL statements ** prior to sending the SQL into SQLite. Useful for injecting ** crazy bytes in the middle of SQL statements for testing and debugging. */ data.backslashOn = 1; }else if( strcmp(z,"-bail")==0 ){ bail_on_error = 1; }else if( strcmp(z,"-version")==0 ){ printf("%s %s\n", sqlite3_libversion(), sqlite3_sourceid()); return 0; }else if( strcmp(z,"-interactive")==0 ){ stdin_is_interactive = 1; |
︙ | ︙ |
Changes to src/sqliteInt.h.
︙ | ︙ | |||
1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 | Trigger *pTrigger; /* List of triggers stored in pSchema */ Schema *pSchema; /* Schema that contains this table */ Table *pNextZombie; /* Next on the Parse.pZombieTab list */ }; /* ** Allowed values for Table.tabFlags. */ #define TF_Readonly 0x01 /* Read-only system table */ #define TF_Ephemeral 0x02 /* An ephemeral table */ #define TF_HasPrimaryKey 0x04 /* Table has a primary key */ #define TF_Autoincrement 0x08 /* Integer primary key is autoincrement */ #define TF_Virtual 0x10 /* Is a virtual table */ #define TF_WithoutRowid 0x20 /* No rowid used. PRIMARY KEY is the key */ /* ** Test to see whether or not a table is a virtual table. This is ** done as a macro so that it will be optimized out when virtual ** table support is omitted from the build. */ | > > > > > > > | 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 | Trigger *pTrigger; /* List of triggers stored in pSchema */ Schema *pSchema; /* Schema that contains this table */ Table *pNextZombie; /* Next on the Parse.pZombieTab list */ }; /* ** Allowed values for Table.tabFlags. ** ** TF_OOOHidden applies to virtual tables that have hidden columns that are ** followed by non-hidden columns. Example: "CREATE VIRTUAL TABLE x USING ** vtab1(a HIDDEN, b);". Since "b" is a non-hidden column but "a" is hidden, ** the TF_OOOHidden attribute would apply in this case. Such tables require ** special handling during INSERT processing. */ #define TF_Readonly 0x01 /* Read-only system table */ #define TF_Ephemeral 0x02 /* An ephemeral table */ #define TF_HasPrimaryKey 0x04 /* Table has a primary key */ #define TF_Autoincrement 0x08 /* Integer primary key is autoincrement */ #define TF_Virtual 0x10 /* Is a virtual table */ #define TF_WithoutRowid 0x20 /* No rowid used. PRIMARY KEY is the key */ #define TF_OOOHidden 0x40 /* Out-of-Order hidden columns */ /* ** Test to see whether or not a table is a virtual table. This is ** done as a macro so that it will be optimized out when virtual ** table support is omitted from the build. */ |
︙ | ︙ | |||
2391 2392 2393 2394 2395 2396 2397 | #define SF_Resolved 0x0002 /* Identifiers have been resolved */ #define SF_Aggregate 0x0004 /* Contains aggregate functions */ #define SF_UsesEphemeral 0x0008 /* Uses the OpenEphemeral opcode */ #define SF_Expanded 0x0010 /* sqlite3SelectExpand() called on this */ #define SF_HasTypeInfo 0x0020 /* FROM subqueries have Table metadata */ #define SF_Compound 0x0040 /* Part of a compound query */ #define SF_Values 0x0080 /* Synthesized from VALUES clause */ | | | 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 | #define SF_Resolved 0x0002 /* Identifiers have been resolved */ #define SF_Aggregate 0x0004 /* Contains aggregate functions */ #define SF_UsesEphemeral 0x0008 /* Uses the OpenEphemeral opcode */ #define SF_Expanded 0x0010 /* sqlite3SelectExpand() called on this */ #define SF_HasTypeInfo 0x0020 /* FROM subqueries have Table metadata */ #define SF_Compound 0x0040 /* Part of a compound query */ #define SF_Values 0x0080 /* Synthesized from VALUES clause */ #define SF_MultiValue 0x0100 /* Single VALUES term with multiple rows */ #define SF_NestedFrom 0x0200 /* Part of a parenthesized FROM clause */ #define SF_MaybeConvert 0x0400 /* Need convertCompoundSelectToSubquery() */ #define SF_Recursive 0x0800 /* The recursive part of a recursive CTE */ #define SF_MinMaxAgg 0x1000 /* Aggregate containing min() or max() */ #define SF_Converted 0x2000 /* By convertCompoundSelectToSubquery() */ |
︙ | ︙ |
Changes to src/tokenize.c.
︙ | ︙ | |||
512 513 514 515 516 517 518 | sqlite3DbFree(db, p); } while( pParse->pZombieTab ){ Table *p = pParse->pZombieTab; pParse->pZombieTab = p->pNextZombie; sqlite3DeleteTable(db, p); } | < | < | 512 513 514 515 516 517 518 519 520 521 | sqlite3DbFree(db, p); } while( pParse->pZombieTab ){ Table *p = pParse->pZombieTab; pParse->pZombieTab = p->pNextZombie; sqlite3DeleteTable(db, p); } assert( nErr==0 || pParse->rc!=SQLITE_OK ); return nErr; } |
Changes to src/trigger.c.
︙ | ︙ | |||
189 190 191 192 193 194 195 | } 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"); | < | 189 190 191 192 193 194 195 196 197 198 199 200 201 202 | } 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"); goto trigger_cleanup; } /* INSTEAD of triggers are only for views and views only support INSTEAD ** of triggers. */ if( pTab->pSelect && tr_tm!=TK_INSTEAD ){ |
︙ | ︙ | |||
791 792 793 794 795 796 797 798 799 800 801 802 803 804 | */ static void transferParseError(Parse *pTo, Parse *pFrom){ assert( pFrom->zErrMsg==0 || pFrom->nErr ); assert( pTo->zErrMsg==0 || pTo->nErr ); if( pTo->nErr==0 ){ pTo->zErrMsg = pFrom->zErrMsg; pTo->nErr = pFrom->nErr; }else{ sqlite3DbFree(pFrom->db, pFrom->zErrMsg); } } /* ** Create and populate a new TriggerPrg object with a sub-program | > | 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 | */ static void transferParseError(Parse *pTo, Parse *pFrom){ assert( pFrom->zErrMsg==0 || pFrom->nErr ); assert( pTo->zErrMsg==0 || pTo->nErr ); if( pTo->nErr==0 ){ pTo->zErrMsg = pFrom->zErrMsg; pTo->nErr = pFrom->nErr; pTo->rc = pFrom->rc; }else{ sqlite3DbFree(pFrom->db, pFrom->zErrMsg); } } /* ** Create and populate a new TriggerPrg object with a sub-program |
︙ | ︙ |
Changes to src/util.c.
︙ | ︙ | |||
651 652 653 654 655 656 657 658 659 660 661 662 663 664 | memcpy(pValue, &u, 4); return 1; }else{ return 0; } } #endif for(i=0; i<11 && (c = zNum[i] - '0')>=0 && c<=9; i++){ v = v*10 + c; } /* The longest decimal representation of a 32 bit integer is 10 digits: ** ** 1234567890 | > | 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 | memcpy(pValue, &u, 4); return 1; }else{ return 0; } } #endif while( zNum[0]=='0' ) zNum++; for(i=0; i<11 && (c = zNum[i] - '0')>=0 && c<=9; i++){ v = v*10 + c; } /* The longest decimal representation of a 32 bit integer is 10 digits: ** ** 1234567890 |
︙ | ︙ |
Changes to src/vdbe.c.
︙ | ︙ | |||
535 536 537 538 539 540 541 542 543 544 545 546 547 548 | ** This is the core of sqlite3_step(). */ int sqlite3VdbeExec( Vdbe *p /* The VDBE */ ){ Op *aOp = p->aOp; /* Copy of p->aOp */ Op *pOp = aOp; /* Current operation */ int rc = SQLITE_OK; /* Value to return */ sqlite3 *db = p->db; /* The database */ u8 resetSchemaOnFault = 0; /* Reset schema after an error if positive */ u8 encoding = ENC(db); /* The database encoding */ int iCompare = 0; /* Result of last OP_Compare operation */ unsigned nVmStep = 0; /* Number of virtual machine steps */ #ifndef SQLITE_OMIT_PROGRESS_CALLBACK | > > > | 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 | ** This is the core of sqlite3_step(). */ int sqlite3VdbeExec( Vdbe *p /* The VDBE */ ){ Op *aOp = p->aOp; /* Copy of p->aOp */ Op *pOp = aOp; /* Current operation */ #if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE) Op *pOrigOp; /* Value of pOp at the top of the loop */ #endif int rc = SQLITE_OK; /* Value to return */ sqlite3 *db = p->db; /* The database */ u8 resetSchemaOnFault = 0; /* Reset schema after an error if positive */ u8 encoding = ENC(db); /* The database encoding */ int iCompare = 0; /* Result of last OP_Compare operation */ unsigned nVmStep = 0; /* Number of virtual machine steps */ #ifndef SQLITE_OMIT_PROGRESS_CALLBACK |
︙ | ︙ | |||
676 677 678 679 680 681 682 683 684 685 686 687 688 689 | memAboutToChange(p, &aMem[pOp->p2]); } if( (pOp->opflags & OPFLG_OUT3)!=0 ){ assert( pOp->p3>0 ); assert( pOp->p3<=(p->nMem-p->nCursor) ); memAboutToChange(p, &aMem[pOp->p3]); } #endif switch( pOp->opcode ){ /***************************************************************************** ** What follows is a massive switch statement where each case implements a ** separate instruction in the virtual machine. If we follow the usual | > > > | 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 | memAboutToChange(p, &aMem[pOp->p2]); } if( (pOp->opflags & OPFLG_OUT3)!=0 ){ assert( pOp->p3>0 ); assert( pOp->p3<=(p->nMem-p->nCursor) ); memAboutToChange(p, &aMem[pOp->p3]); } #endif #if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE) pOrigOp = pOp; #endif switch( pOp->opcode ){ /***************************************************************************** ** What follows is a massive switch statement where each case implements a ** separate instruction in the virtual machine. If we follow the usual |
︙ | ︙ | |||
2915 2916 2917 2918 2919 2920 2921 | db->nSavepoint--; } }else{ db->nDeferredCons = pSavepoint->nDeferredCons; db->nDeferredImmCons = pSavepoint->nDeferredImmCons; } | | | 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 | db->nSavepoint--; } }else{ db->nDeferredCons = pSavepoint->nDeferredCons; db->nDeferredImmCons = pSavepoint->nDeferredImmCons; } if( !isTransaction || p1==SAVEPOINT_ROLLBACK ){ rc = sqlite3VtabSavepoint(db, p1, iSavepoint); if( rc!=SQLITE_OK ) goto abort_due_to_error; } } } break; |
︙ | ︙ | |||
6485 6486 6487 6488 6489 6490 6491 | ** restored. *****************************************************************************/ } #ifdef VDBE_PROFILE { u64 endTime = sqlite3Hwtime(); | | | | | | | | | 6491 6492 6493 6494 6495 6496 6497 6498 6499 6500 6501 6502 6503 6504 6505 6506 6507 6508 6509 6510 6511 6512 6513 6514 6515 6516 6517 6518 6519 6520 6521 6522 6523 6524 6525 | ** restored. *****************************************************************************/ } #ifdef VDBE_PROFILE { u64 endTime = sqlite3Hwtime(); if( endTime>start ) pOrigOp->cycles += endTime - start; pOrigOp->cnt++; } #endif /* The following code adds nothing to the actual functionality ** of the program. It is only here for testing and debugging. ** On the other hand, it does burn CPU cycles every time through ** the evaluator loop. So we can leave it out when NDEBUG is defined. */ #ifndef NDEBUG assert( pOp>=&aOp[-1] && pOp<&aOp[p->nOp-1] ); #ifdef SQLITE_DEBUG if( db->flags & SQLITE_VdbeTrace ){ if( rc!=0 ) printf("rc=%d\n",rc); if( pOrigOp->opflags & (OPFLG_OUT2) ){ registerTrace(pOrigOp->p2, &aMem[pOrigOp->p2]); } if( pOrigOp->opflags & OPFLG_OUT3 ){ registerTrace(pOrigOp->p3, &aMem[pOrigOp->p3]); } } #endif /* SQLITE_DEBUG */ #endif /* NDEBUG */ } /* The end of the for(;;) loop the loops through opcodes */ /* If we reach this point, it means that execution is finished with |
︙ | ︙ |
Changes to src/vdbeaux.c.
︙ | ︙ | |||
1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 | const sqlite3_module *pModule = pVtabCursor->pVtab->pModule; assert( pVtabCursor->pVtab->nRef>0 ); pVtabCursor->pVtab->nRef--; pModule->xClose(pVtabCursor); } #endif } /* ** Copy the values stored in the VdbeFrame structure to its Vdbe. This ** is used, for example, when a trigger sub-program is halted to restore ** control to the main program. */ int sqlite3VdbeFrameRestore(VdbeFrame *pFrame){ Vdbe *v = pFrame->v; #ifdef SQLITE_ENABLE_STMT_SCANSTATUS v->anExec = pFrame->anExec; #endif v->aOnceFlag = pFrame->aOnceFlag; v->nOnceFlag = pFrame->nOnceFlag; v->aOp = pFrame->aOp; v->nOp = pFrame->nOp; | > > > > > > > > > > > > > > > > > | 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 | const sqlite3_module *pModule = pVtabCursor->pVtab->pModule; assert( pVtabCursor->pVtab->nRef>0 ); pVtabCursor->pVtab->nRef--; pModule->xClose(pVtabCursor); } #endif } /* ** Close all cursors in the current frame. */ static void closeCursorsInFrame(Vdbe *p){ if( p->apCsr ){ int i; for(i=0; i<p->nCursor; i++){ VdbeCursor *pC = p->apCsr[i]; if( pC ){ sqlite3VdbeFreeCursor(p, pC); p->apCsr[i] = 0; } } } } /* ** Copy the values stored in the VdbeFrame structure to its Vdbe. This ** is used, for example, when a trigger sub-program is halted to restore ** control to the main program. */ int sqlite3VdbeFrameRestore(VdbeFrame *pFrame){ Vdbe *v = pFrame->v; closeCursorsInFrame(v); #ifdef SQLITE_ENABLE_STMT_SCANSTATUS v->anExec = pFrame->anExec; #endif v->aOnceFlag = pFrame->aOnceFlag; v->nOnceFlag = pFrame->nOnceFlag; v->aOp = pFrame->aOp; v->nOp = pFrame->nOp; |
︙ | ︙ | |||
1828 1829 1830 1831 1832 1833 1834 | VdbeFrame *pFrame; for(pFrame=p->pFrame; pFrame->pParent; pFrame=pFrame->pParent); sqlite3VdbeFrameRestore(pFrame); p->pFrame = 0; p->nFrame = 0; } assert( p->nFrame==0 ); | | < < < < < < < < < < | 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 | VdbeFrame *pFrame; for(pFrame=p->pFrame; pFrame->pParent; pFrame=pFrame->pParent); sqlite3VdbeFrameRestore(pFrame); p->pFrame = 0; p->nFrame = 0; } assert( p->nFrame==0 ); closeCursorsInFrame(p); if( p->aMem ){ releaseMemArray(&p->aMem[1], p->nMem); } while( p->pDelFrame ){ VdbeFrame *pDel = p->pDelFrame; p->pDelFrame = pDel->pParent; sqlite3VdbeFrameDelete(pDel); |
︙ | ︙ |
Changes to src/vdbetrace.c.
︙ | ︙ | |||
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 | while( *zRawSql ){ const char *zStart = zRawSql; while( *(zRawSql++)!='\n' && *zRawSql ); sqlite3StrAccumAppend(&out, "-- ", 3); assert( (zRawSql - zStart) > 0 ); sqlite3StrAccumAppend(&out, zStart, (int)(zRawSql-zStart)); } }else{ while( zRawSql[0] ){ n = findNextHostParameter(zRawSql, &nToken); assert( n>0 ); sqlite3StrAccumAppend(&out, zRawSql, n); zRawSql += n; assert( zRawSql[0] || nToken==0 ); if( nToken==0 ) break; if( zRawSql[0]=='?' ){ if( nToken>1 ){ assert( sqlite3Isdigit(zRawSql[1]) ); sqlite3GetInt32(&zRawSql[1], &idx); }else{ idx = nextIndex; } }else{ | > > | > > | 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 | while( *zRawSql ){ const char *zStart = zRawSql; while( *(zRawSql++)!='\n' && *zRawSql ); sqlite3StrAccumAppend(&out, "-- ", 3); assert( (zRawSql - zStart) > 0 ); sqlite3StrAccumAppend(&out, zStart, (int)(zRawSql-zStart)); } }else if( p->nVar==0 ){ sqlite3StrAccumAppend(&out, zRawSql, sqlite3Strlen30(zRawSql)); }else{ while( zRawSql[0] ){ n = findNextHostParameter(zRawSql, &nToken); assert( n>0 ); sqlite3StrAccumAppend(&out, zRawSql, n); zRawSql += n; assert( zRawSql[0] || nToken==0 ); if( nToken==0 ) break; if( zRawSql[0]=='?' ){ if( nToken>1 ){ assert( sqlite3Isdigit(zRawSql[1]) ); sqlite3GetInt32(&zRawSql[1], &idx); }else{ idx = nextIndex; } }else{ assert( zRawSql[0]==':' || zRawSql[0]=='$' || zRawSql[0]=='@' || zRawSql[0]=='#' ); testcase( zRawSql[0]==':' ); testcase( zRawSql[0]=='$' ); testcase( zRawSql[0]=='@' ); testcase( zRawSql[0]=='#' ); idx = sqlite3VdbeParameterIndex(p, zRawSql, nToken); assert( idx>0 ); } zRawSql += nToken; nextIndex = idx + 1; assert( idx>0 && idx<=p->nVar ); pVar = &p->aVar[idx-1]; |
︙ | ︙ |
Changes to src/vtab.c.
︙ | ︙ | |||
468 469 470 471 472 473 474 | */ void sqlite3VtabArgExtend(Parse *pParse, Token *p){ Token *pArg = &pParse->sArg; if( pArg->z==0 ){ pArg->z = p->z; pArg->n = p->n; }else{ | | | 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 | */ void sqlite3VtabArgExtend(Parse *pParse, Token *p){ Token *pArg = &pParse->sArg; if( pArg->z==0 ){ pArg->z = p->z; pArg->n = p->n; }else{ assert(pArg->z <= p->z); pArg->n = (int)(&p->z[p->n] - pArg->z); } } /* ** Invoke a virtual table constructor (either xCreate or xConnect). The ** pointer to the function to invoke is passed as the fourth parameter |
︙ | ︙ | |||
555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 | if( sCtx.bDeclared==0 ){ const char *zFormat = "vtable constructor did not declare schema: %s"; *pzErr = sqlite3MPrintf(db, zFormat, pTab->zName); sqlite3VtabUnlock(pVTable); rc = SQLITE_ERROR; }else{ int iCol; /* If everything went according to plan, link the new VTable structure ** into the linked list headed by pTab->pVTable. Then loop through the ** columns of the table to see if any of them contain the token "hidden". ** If so, set the Column COLFLAG_HIDDEN flag and remove the token from ** the type string. */ pVTable->pNext = pTab->pVTable; pTab->pVTable = pVTable; for(iCol=0; iCol<pTab->nCol; iCol++){ char *zType = pTab->aCol[iCol].zType; int nType; int i = 0; | > | > > > | 555 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 | if( sCtx.bDeclared==0 ){ const char *zFormat = "vtable constructor did not declare schema: %s"; *pzErr = sqlite3MPrintf(db, zFormat, pTab->zName); sqlite3VtabUnlock(pVTable); rc = SQLITE_ERROR; }else{ int iCol; u8 oooHidden = 0; /* If everything went according to plan, link the new VTable structure ** into the linked list headed by pTab->pVTable. Then loop through the ** columns of the table to see if any of them contain the token "hidden". ** If so, set the Column COLFLAG_HIDDEN flag and remove the token from ** the type string. */ pVTable->pNext = pTab->pVTable; pTab->pVTable = pVTable; for(iCol=0; iCol<pTab->nCol; iCol++){ char *zType = pTab->aCol[iCol].zType; int nType; int i = 0; if( !zType ){ pTab->tabFlags |= oooHidden; continue; } nType = sqlite3Strlen30(zType); if( sqlite3StrNICmp("hidden", zType, 6)||(zType[6] && zType[6]!=' ') ){ for(i=0; i<nType; i++){ if( (0==sqlite3StrNICmp(" hidden", &zType[i], 7)) && (zType[i+7]=='\0' || zType[i+7]==' ') ){ i++; |
︙ | ︙ | |||
590 591 592 593 594 595 596 597 598 599 600 601 602 603 | zType[j] = zType[j+nDel]; } if( zType[i]=='\0' && i>0 ){ assert(zType[i-1]==' '); zType[i-1] = '\0'; } pTab->aCol[iCol].colFlags |= COLFLAG_HIDDEN; } } } } sqlite3DbFree(db, zModuleName); return rc; | > > > | 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 | zType[j] = zType[j+nDel]; } if( zType[i]=='\0' && i>0 ){ assert(zType[i-1]==' '); zType[i-1] = '\0'; } pTab->aCol[iCol].colFlags |= COLFLAG_HIDDEN; oooHidden = TF_OOOHidden; }else{ pTab->tabFlags |= oooHidden; } } } } sqlite3DbFree(db, zModuleName); return rc; |
︙ | ︙ | |||
953 954 955 956 957 958 959 | ** function immediately. If all calls to virtual table methods are successful, ** SQLITE_OK is returned. */ int sqlite3VtabSavepoint(sqlite3 *db, int op, int iSavepoint){ int rc = SQLITE_OK; assert( op==SAVEPOINT_RELEASE||op==SAVEPOINT_ROLLBACK||op==SAVEPOINT_BEGIN ); | | | 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 | ** function immediately. If all calls to virtual table methods are successful, ** SQLITE_OK is returned. */ int sqlite3VtabSavepoint(sqlite3 *db, int op, int iSavepoint){ int rc = SQLITE_OK; assert( op==SAVEPOINT_RELEASE||op==SAVEPOINT_ROLLBACK||op==SAVEPOINT_BEGIN ); assert( iSavepoint>=-1 ); if( db->aVTrans ){ int i; for(i=0; rc==SQLITE_OK && i<db->nVTrans; i++){ VTable *pVTab = db->aVTrans[i]; const sqlite3_module *pMod = pVTab->pMod->pModule; if( pVTab->pVtab && pMod->iVersion>=2 ){ int (*xMethod)(sqlite3_vtab *, int); |
︙ | ︙ |
Changes to test/analyze.test.
︙ | ︙ | |||
355 356 357 358 359 360 361 | UPDATE sqlite_master SET sql='nonsense' WHERE name='sqlite_stat1'; } db close catch { sqlite3 db test.db } catchsql { ANALYZE } | | | 355 356 357 358 359 360 361 362 363 364 | UPDATE sqlite_master SET sql='nonsense' WHERE name='sqlite_stat1'; } db close catch { sqlite3 db test.db } catchsql { ANALYZE } } {1 {malformed database schema (sqlite_stat1)}} finish_test |
Changes to test/corruptC.test.
︙ | ︙ | |||
288 289 290 291 292 293 294 | # do_test corruptC-2.15 { db close forcecopy test.bu test.db hexio_write test.db 986 b9 sqlite3 db test.db catchsql {SELECT count(*) FROM sqlite_master;} | | | 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 | # do_test corruptC-2.15 { db close forcecopy test.bu test.db hexio_write test.db 986 b9 sqlite3 db test.db catchsql {SELECT count(*) FROM sqlite_master;} } {1 {database disk image is malformed}} # # Now test for a series of quasi-random seeds. # We loop over the entire file size and touch # each byte at least once. for {set tn 0} {$tn<$fsize} {incr tn 1} { |
︙ | ︙ |
Changes to test/e_reindex.test.
︙ | ︙ | |||
44 45 46 47 48 49 50 51 | # Test this by corrupting some database indexes, running REINDEX, and # observing that the corruption is gone. # do_execsql_test e_reindex-1.1 { INSERT INTO t1 VALUES(1, 2); INSERT INTO t1 VALUES(3, 4); INSERT INTO t1 VALUES(5, 6); PRAGMA writable_schema = 1; | > > > | | > | 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 | # Test this by corrupting some database indexes, running REINDEX, and # observing that the corruption is gone. # do_execsql_test e_reindex-1.1 { INSERT INTO t1 VALUES(1, 2); INSERT INTO t1 VALUES(3, 4); INSERT INTO t1 VALUES(5, 6); CREATE TABLE saved(a,b,c,d,e); INSERT INTO saved SELECT * FROM sqlite_master WHERE type = 'index'; PRAGMA writable_schema = 1; DELETE FROM sqlite_master WHERE type = 'index'; } {} db close sqlite3 db test.db do_execsql_test e_reindex-1.2 { DELETE FROM t1 WHERE a = 3; INSERT INTO t1 VALUES(7, 8); INSERT INTO t1 VALUES(9, 10); PRAGMA writable_schema = 1; INSERT INTO sqlite_master SELECT * FROM saved; DROP TABLE saved; } {} db close sqlite3 db test.db do_execsql_test e_reindex-1.3 { PRAGMA integrity_check; } [list \ |
︙ | ︙ |
Changes to test/expr.test.
︙ | ︙ | |||
938 939 940 941 942 943 944 945 946 947 | } } {9.22337203685478e+18} do_realnum_test expr-13.7 { execsql { SELECT '9223372036854775807.0'+0 } } {9.22337203685478e+18} finish_test | > > > > > > > > | 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 | } } {9.22337203685478e+18} do_realnum_test expr-13.7 { execsql { SELECT '9223372036854775807.0'+0 } } {9.22337203685478e+18} do_execsql_test expr-13.8 { SELECT "" <= ''; } {1} do_execsql_test expr-13.9 { SELECT '' <= ""; } {1} finish_test |
Changes to test/fkey2.test.
︙ | ︙ | |||
672 673 674 675 676 677 678 679 680 681 682 683 684 685 | } {6 A 5 6 B 5 3 A 2 3 B 2} do_test fkey2-9.2.3 { execsql { DELETE FROM pp WHERE a = 4; SELECT * FROM cc; } } {{} A {} {} B {} 3 A 2 3 B 2} #------------------------------------------------------------------------- # The following tests, fkey2-10.*, test "foreign key mismatch" and # other errors. # set tn 0 foreach zSql [list { | > > > > > | 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 | } {6 A 5 6 B 5 3 A 2 3 B 2} do_test fkey2-9.2.3 { execsql { DELETE FROM pp WHERE a = 4; SELECT * FROM cc; } } {{} A {} {} B {} 3 A 2 3 B 2} do_execsql_test fkey2-9.3.0 { CREATE TABLE t3(x PRIMARY KEY REFERENCES t3 ON DELETE SET NULL); INSERT INTO t3(x) VALUES(12345); DROP TABLE t3; } {} #------------------------------------------------------------------------- # The following tests, fkey2-10.*, test "foreign key mismatch" and # other errors. # set tn 0 foreach zSql [list { |
︙ | ︙ | |||
2009 2010 2011 2012 2013 2014 2015 2016 2017 | } } {1 {FOREIGN KEY constraint failed}} do_test fkey2-ce7c13.1.6 { catchsql { UPDATE tce73 set a = 101 where a = 100; } } {1 {FOREIGN KEY constraint failed}} finish_test | > > > > > > > > > > > > > > | 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 | } } {1 {FOREIGN KEY constraint failed}} do_test fkey2-ce7c13.1.6 { catchsql { UPDATE tce73 set a = 101 where a = 100; } } {1 {FOREIGN KEY constraint failed}} # 2015-04-16: Foreign key errors propagate back up to the parser. # do_test fkey2-20150416-100 { db close sqlite3 db :memory: catchsql { PRAGMA foreign_keys=1; CREATE TABLE t1(x PRIMARY KEY); CREATE TABLE t(y REFERENCES t0(x)ON DELETE SET DEFAULT); CREATE TABLE t0(y REFERENCES t1 ON DELETE SET NULL); REPLACE INTO t1 SELECT(0);CREATE TABLE t2(x);CREATE TABLE t3; } } {1 {foreign key mismatch - "t" referencing "t0"}} finish_test |
Changes to test/fts3aa.test.
︙ | ︙ | |||
12 13 14 15 16 17 18 19 20 21 22 23 24 25 | # focus of this script is testing the FTS3 module. # # $Id: fts3aa.test,v 1.1 2007/08/20 17:38:42 shess Exp $ # set testdir [file dirname $argv0] source $testdir/tester.tcl # If SQLITE_ENABLE_FTS3 is defined, omit this file. ifcapable !fts3 { finish_test return } | > | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | # focus of this script is testing the FTS3 module. # # $Id: fts3aa.test,v 1.1 2007/08/20 17:38:42 shess Exp $ # set testdir [file dirname $argv0] source $testdir/tester.tcl set testprefix fts3aa # If SQLITE_ENABLE_FTS3 is defined, omit this file. ifcapable !fts3 { finish_test return } |
︙ | ︙ | |||
216 217 218 219 220 221 222 223 224 225 | do_execsql_test fts3aa-7.4 { CREATE VIRTUAL TABLE t3 USING fts3(tokenize=simple, tokenize=simple); SELECT tokenize FROM t3; } {} do_catchsql_test fts3aa-7.5 { CREATE VIRTUAL TABLE t4 USING fts4(tokenize=simple, tokenize=simple); } {1 {unrecognized parameter: tokenize=simple}} finish_test | > > > > > > > > > > > > > > > > > > > > > | 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 | do_execsql_test fts3aa-7.4 { CREATE VIRTUAL TABLE t3 USING fts3(tokenize=simple, tokenize=simple); SELECT tokenize FROM t3; } {} do_catchsql_test fts3aa-7.5 { CREATE VIRTUAL TABLE t4 USING fts4(tokenize=simple, tokenize=simple); } {1 {unrecognized parameter: tokenize=simple}} do_execsql_test 8.0 { CREATE VIRTUAL TABLE t0 USING fts4(order=desc); BEGIN; INSERT INTO t0(rowid, content) VALUES(1, 'abc'); UPDATE t0 SET docid=5 WHERE docid=1; INSERT INTO t0(rowid, content) VALUES(6, 'abc'); } do_execsql_test 8.1 { SELECT docid FROM t0 WHERE t0 MATCH 'abc'; } {6 5} do_execsql_test 8.2 { SELECT docid FROM t0 WHERE t0 MATCH '"abc abc"'; } {} do_execsql_test 8.3 { COMMIT } do_execsql_test 8.4 { SELECT docid FROM t0 WHERE t0 MATCH 'abc'; } {6 5} do_execsql_test 8.5 { SELECT docid FROM t0 WHERE t0 MATCH '"abc abc"'; } {} finish_test |
Changes to test/index3.test.
︙ | ︙ | |||
47 48 49 50 51 52 53 | execsql { PRAGMA writable_schema=on; UPDATE sqlite_master SET sql='nonsense'; } db close catch { sqlite3 db test.db } catchsql { DROP INDEX i1 } | | | 47 48 49 50 51 52 53 54 55 56 | execsql { PRAGMA writable_schema=on; UPDATE sqlite_master SET sql='nonsense'; } db close catch { sqlite3 db test.db } catchsql { DROP INDEX i1 } } {1 {malformed database schema (t1)}} finish_test |
Changes to test/index7.test.
︙ | ︙ | |||
307 308 309 310 311 312 313 314 315 | def xyz } do_eqp_test index7-6.4 { SELECT * FROM v4 WHERE d='xyz' AND c='def' } { 0 0 0 {SEARCH TABLE t4 USING INDEX i4 (c=?)} } finish_test | > > > > | 307 308 309 310 311 312 313 314 315 316 317 318 319 | def xyz } do_eqp_test index7-6.4 { SELECT * FROM v4 WHERE d='xyz' AND c='def' } { 0 0 0 {SEARCH TABLE t4 USING INDEX i4 (c=?)} } do_catchsql_test index7-6.5 { CREATE INDEX t5a ON t5(a) WHERE a=#1; } {1 {near "#1": syntax error}} finish_test |
Changes to test/insert4.test.
︙ | ︙ | |||
556 557 558 559 560 561 562 563 564 | CREATE TABLE t2(x INTEGER PRIMARY KEY ON CONFLICT ROLLBACK, y); INSERT INTO t2 VALUES(1,3); INSERT INTO t1 SELECT * FROM t2; SELECT * FROM t1; } } {1 3} finish_test | > > > > > | 556 557 558 559 560 561 562 563 564 565 566 567 568 569 | CREATE TABLE t2(x INTEGER PRIMARY KEY ON CONFLICT ROLLBACK, y); INSERT INTO t2 VALUES(1,3); INSERT INTO t1 SELECT * FROM t2; SELECT * FROM t1; } } {1 3} do_catchsql_test insert4-9.1 { DROP TABLE IF EXISTS t1; CREATE TABLE t1(x); INSERT INTO t1(x) VALUES(5 COLLATE xyzzy) UNION SELECT 0; } {1 {no such collation sequence: xyzzy}} finish_test |
Changes to test/misc1.test.
︙ | ︙ | |||
639 640 641 642 643 644 645 646 647 | VALUES(0,0x0MATCH#0; } {1 {near ";": syntax error}} # 2015-04-15 do_execsql_test misc1-22.1 { SELECT ""+3 FROM (SELECT ""+5); } {3} finish_test | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 639 640 641 642 643 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 677 678 679 680 681 682 683 684 685 686 687 | VALUES(0,0x0MATCH#0; } {1 {near ";": syntax error}} # 2015-04-15 do_execsql_test misc1-22.1 { SELECT ""+3 FROM (SELECT ""+5); } {3} # 2015-04-19: NULL pointer dereference on a corrupt schema # db close sqlite3 db :memory: do_execsql_test misc1-23.1 { CREATE TABLE t1(x); PRAGMA writable_schema=ON; UPDATE sqlite_master SET sql='CREATE table t(d CHECK(T(#0)'; BEGIN; CREATE TABLE t2(y); ROLLBACK; DROP TABLE IF EXISTS t3; } {} # 2015-04-19: Faulty assert() statement # db close database_may_be_corrupt sqlite3 db :memory: do_catchsql_test misc1-23.2 { CREATE TABLE t1(x UNIQUE); PRAGMA writable_schema=ON; UPDATE sqlite_master SET sql='CREATE TABLE IF not EXISTS t(c)'; BEGIN; CREATE TABLE t2(x); ROLLBACK; DROP TABLE F; } {1 {no such table: F}} db close sqlite3 db :memory: do_catchsql_test misc1-23.3 { CREATE TABLE t1(x UNIQUE); PRAGMA writable_schema=ON; UPDATE sqlite_master SET sql='CREATE table y(a TEXT, a TEXT)'; BEGIN; CREATE TABLE t2(y); ROLLBACK; DROP TABLE IF EXISTS t; } {0 {}} finish_test |
Changes to test/misc5.test.
︙ | ︙ | |||
578 579 580 581 582 583 584 585 586 587 588 589 590 591 | for {set i 0} {$i<200} {incr i} { append sql "(1+" append tail ")" } append sql 2$tail catchsql $sql } {1 {parser stack overflow}} # Ticket #1911 # ifcapable compound { do_test misc5-9.1 { execsql { SELECT name, type FROM sqlite_master WHERE name IS NULL | > > > > > > > > > > > > > > > > > > | 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 | for {set i 0} {$i<200} {incr i} { append sql "(1+" append tail ")" } append sql 2$tail catchsql $sql } {1 {parser stack overflow}} # Parser stack overflow is silently ignored when it occurs while parsing the # schema and PRAGMA writable_schema is turned on. # do_test misc5-7.2 { sqlite3 db2 :memory: catchsql { CREATE TABLE t1(x UNIQUE); PRAGMA writable_schema=ON; UPDATE sqlite_master SET sql='CREATE table t(o CHECK(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((;VALUES(o)'; BEGIN; CREATE TABLE t2(y); ROLLBACK; DROP TABLE IF EXISTS D; } db2 } {0 {}} db2 close # Ticket #1911 # ifcapable compound { do_test misc5-9.1 { execsql { SELECT name, type FROM sqlite_master WHERE name IS NULL |
︙ | ︙ |
Changes to test/pragma.test.
︙ | ︙ | |||
214 215 216 217 218 219 220 221 222 223 224 225 226 227 | } } {0} do_test pragma-1.14 { execsql { PRAGMA synchronous=2; PRAGMA synchronous; } } {2} } ;# ifcapable pager_pragmas # Test turning "flag" pragmas on and off. # ifcapable debug { # Pragma "vdbe_listing" is only available if compiled with SQLITE_DEBUG | > > > > > > > > > > > > > > > > > > | 214 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 | } } {0} do_test pragma-1.14 { execsql { PRAGMA synchronous=2; PRAGMA synchronous; } } {2} do_test pragma-1.14.1 { execsql { PRAGMA synchronous=4; PRAGMA synchronous; } } {0} do_test pragma-1.14.2 { execsql { PRAGMA synchronous=3; PRAGMA synchronous; } } {0} do_test pragma-1.14.3 { execsql { PRAGMA synchronous=10; PRAGMA synchronous; } } {2} } ;# ifcapable pager_pragmas # Test turning "flag" pragmas on and off. # ifcapable debug { # Pragma "vdbe_listing" is only available if compiled with SQLITE_DEBUG |
︙ | ︙ |
Changes to test/releasetest.tcl.
︙ | ︙ | |||
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | optional) are: --srcdir TOP-OF-SQLITE-TREE (see below) --platform PLATFORM (see below) --config CONFIGNAME (Run only CONFIGNAME) --quick (Run "veryquick.test" only) --veryquick (Run "make smoketest" only) --buildonly (Just build testfixture - do not run) --dryrun (Print what would have happened) --info (Show diagnostic info) The default value for --srcdir is the parent of the directory holding this script. The script determines the default value for --platform using the | > | | > | 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 | optional) are: --srcdir TOP-OF-SQLITE-TREE (see below) --platform PLATFORM (see below) --config CONFIGNAME (Run only CONFIGNAME) --quick (Run "veryquick.test" only) --veryquick (Run "make smoketest" only) --msvc (Use MSVC as the compiler) --buildonly (Just build testfixture - do not run) --dryrun (Print what would have happened) --info (Show diagnostic info) The default value for --srcdir is the parent of the directory holding this script. The script determines the default value for --platform using the $tcl_platform(os) and $tcl_platform(machine) variables. Supported platforms are "Linux-x86", "Linux-x86_64", "Darwin-i386", "Darwin-x86_64", "Windows NT-intel", and "Windows NT-amd64". Every test begins with a fresh run of the configure script at the top of the SQLite source tree. } # Omit comments (text between # and \n) in a long multi-line string. # |
︙ | ︙ | |||
234 235 236 237 238 239 240 241 242 243 244 245 246 247 | "Have-Not" test "OS-X" "threadtest fulltest" } "Windows NT-intel" { "Default" "mptest fulltestonly" "Have-Not" test } # The Failure-Detection platform runs various tests that deliberately # fail. This is used as a test of this script to verify that this script # correctly identifies failures. # Failure-Detection { Fail0 "TEST_FAILURE=0 test" | > > > > | 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 | "Have-Not" test "OS-X" "threadtest fulltest" } "Windows NT-intel" { "Default" "mptest fulltestonly" "Have-Not" test } "Windows NT-amd64" { "Default" "mptest fulltestonly" "Have-Not" test } # The Failure-Detection platform runs various tests that deliberately # fail. This is used as a test of this script to verify that this script # correctly identifies failures. # Failure-Detection { Fail0 "TEST_FAILURE=0 test" |
︙ | ︙ | |||
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 | } if {[regexp {runtime error: +(.*)} $line all msg]} { incr ::NERRCASE if {$rc==0} { set rc 1 set errmsg $msg } } if {[regexp {ERROR SUMMARY: (\d+) errors.*} $line all cnt] && $cnt>0} { incr ::NERRCASE if {$rc==0} { set rc 1 set errmsg $all } } if {[regexp {^VERSION: 3\.\d+.\d+} $line]} { set v [string range $line 9 end] if {$::SQLITE_VERSION eq ""} { set ::SQLITE_VERSION $v } elseif {$::SQLITE_VERSION ne $v} { set rc 1 set errmsg "version conflict: {$::SQLITE_VERSION} vs. {$v}" } } } close $fd | > > > > > > > > > > > > > | | | > > > > > > > | 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 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 | } if {[regexp {runtime error: +(.*)} $line all msg]} { incr ::NERRCASE if {$rc==0} { set rc 1 set errmsg $msg } } if {[regexp {fatal error +(.*)} $line all msg]} { incr ::NERRCASE if {$rc==0} { set rc 1 set errmsg $msg } } if {[regexp {ERROR SUMMARY: (\d+) errors.*} $line all cnt] && $cnt>0} { incr ::NERRCASE if {$rc==0} { set rc 1 set errmsg $all } } if {[regexp {^VERSION: 3\.\d+.\d+} $line]} { set v [string range $line 9 end] if {$::SQLITE_VERSION eq ""} { set ::SQLITE_VERSION $v } elseif {$::SQLITE_VERSION ne $v} { set rc 1 set errmsg "version conflict: {$::SQLITE_VERSION} vs. {$v}" } } } close $fd if {$::BUILDONLY} { if {$rc==0} { set errmsg "Build complete" } else { set errmsg "Build failed" } } elseif {!$seen} { set rc 1 set errmsg "Test did not complete" if {[file readable core]} { append errmsg " - core file exists" } } } proc run_test_suite {name testtarget config} { # Tcl variable $opts is used to build up the value used to set the # OPTS Makefile variable. Variable $cflags holds the value for # CFLAGS. The makefile will pass OPTS to both gcc and lemon, but # CFLAGS is only passed to gcc. # set cflags [expr {$::MSVC ? "-Zi" : "-g"}] set opts "" set title ${name}($testtarget) set configOpts "" regsub -all {#[^\n]*\n} $config \n config foreach arg $config { if {[regexp {^-[UD]} $arg]} { lappend opts $arg } elseif {[regexp {^[A-Z]+=} $arg]} { lappend testtarget $arg } elseif {[regexp {^--(enable|disable)-} $arg]} { lappend configOpts $arg } else { lappend cflags $arg } } set cflags [join $cflags " "] set opts [join $opts " "] append opts " -DSQLITE_NO_SYNC=1" # Some configurations already set HAVE_USLEEP; in that case, skip it. # if {![regexp { -DHAVE_USLEEP$} $opts] && ![regexp { -DHAVE_USLEEP[ =]+} $opts]} { append opts " -DHAVE_USLEEP=1" } # Set the sub-directory to use. # set dir [string tolower [string map {- _ " " _} $name]] if {$::tcl_platform(platform)=="windows"} { append opts " -DSQLITE_OS_WIN=1" |
︙ | ︙ | |||
386 387 388 389 390 391 392 | set hours [expr {($tm2-$tm1)/3600}] set minutes [expr {(($tm2-$tm1)/60)%60}] set seconds [expr {($tm2-$tm1)%60}] set tm [format (%02d:%02d:%02d) $hours $minutes $seconds] if {$rc} { puts " FAIL $tm" incr ::NERR | < > > | > > > > > > > | 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 446 447 448 449 450 451 452 453 454 455 456 457 458 | set hours [expr {($tm2-$tm1)/3600}] set minutes [expr {(($tm2-$tm1)/60)%60}] set seconds [expr {($tm2-$tm1)%60}] set tm [format (%02d:%02d:%02d) $hours $minutes $seconds] if {$rc} { puts " FAIL $tm" incr ::NERR } else { puts " Ok $tm" } if {$errmsg!=""} {puts " $errmsg"} } } # The following procedure returns the "configure" command to be exectued for # the current platform, which may be Windows (via MinGW, etc). # proc configureCommand {opts} { if {$::MSVC} return [list]; # This is not needed for MSVC. set result [list trace_cmd exec] if {$::tcl_platform(platform)=="windows"} { lappend result sh } lappend result $::SRCDIR/configure --enable-load-extension foreach x $opts {lappend result $x} lappend result >& test.log } # The following procedure returns the "make" command to be executed for the # specified targets, compiler flags, and options. # proc makeCommand { targets cflags opts } { set result [list trace_cmd exec] if {$::MSVC} { set nmakeDir [file nativename $::SRCDIR] set nmakeFile [file join $nmakeDir Makefile.msc] lappend result nmake /f $nmakeFile TOP=$nmakeDir clean } else { lappend result make clean } foreach target $targets { lappend result $target } lappend result CFLAGS=$cflags OPTS=$opts >>& test.log } # The following procedure prints its arguments if ::TRACE is true. |
︙ | ︙ | |||
439 440 441 442 443 444 445 446 447 448 449 450 451 452 | # Currently the only option supported is "-makefile", default # "releasetest.mk". Set the ::MAKEFILE variable to the value of this # option. # proc process_options {argv} { set ::SRCDIR [file normalize [file dirname [file dirname $::argv0]]] set ::QUICK 0 set ::BUILDONLY 0 set ::DRYRUN 0 set ::EXEC exec set ::TRACE 0 set config {} set platform $::tcl_platform(os)-$::tcl_platform(machine) | > | 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 | # Currently the only option supported is "-makefile", default # "releasetest.mk". Set the ::MAKEFILE variable to the value of this # option. # proc process_options {argv} { set ::SRCDIR [file normalize [file dirname [file dirname $::argv0]]] set ::QUICK 0 set ::MSVC 0 set ::BUILDONLY 0 set ::DRYRUN 0 set ::EXEC exec set ::TRACE 0 set config {} set platform $::tcl_platform(os)-$::tcl_platform(machine) |
︙ | ︙ | |||
471 472 473 474 475 476 477 478 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 | set ::QUICK 2 } -config { incr i set config [lindex $argv $i] } -buildonly { set ::BUILDONLY 1 } -dryrun { set ::DRYRUN 1 } -trace { set ::TRACE 1 } -info { puts "Command-line Options:" puts " --srcdir $::SRCDIR" puts " --platform [list $platform]" puts " --config [list $config]" if {$::QUICK} {puts " --quick"} if {$::BUILDONLY} {puts " --buildonly"} if {$::DRYRUN} {puts " --dryrun"} if {$::TRACE} {puts " --trace"} puts "\nAvailable --platform options:" foreach y [lsort [array names ::Platforms]] { puts " [list $y]" } puts "\nAvailable --config options:" foreach y [lsort [array names ::Configs]] { puts " [list $y]" } exit } | > > > > > > | > > > > > > > | 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 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 553 554 555 556 557 558 559 560 561 562 563 564 565 | set ::QUICK 2 } -config { incr i set config [lindex $argv $i] } -msvc { set ::MSVC 1 } -buildonly { set ::BUILDONLY 1 } -dryrun { set ::DRYRUN 1 } -trace { set ::TRACE 1 } -info { puts "Command-line Options:" puts " --srcdir $::SRCDIR" puts " --platform [list $platform]" puts " --config [list $config]" if {$::QUICK} {puts " --quick"} if {$::MSVC} {puts " --msvc"} if {$::BUILDONLY} {puts " --buildonly"} if {$::DRYRUN} {puts " --dryrun"} if {$::TRACE} {puts " --trace"} puts "\nAvailable --platform options:" foreach y [lsort [array names ::Platforms]] { puts " [list $y]" } puts "\nAvailable --config options:" foreach y [lsort [array names ::Configs]] { puts " [list $y]" } exit } -g { if {$::MSVC} { lappend ::EXTRACONFIG -Zi } else { lappend ::EXTRACONFIG [lindex $argv $i] } } -D* - -O* - -enable-* - -disable-* - *=* { lappend ::EXTRACONFIG [lindex $argv $i] } |
︙ | ︙ | |||
543 544 545 546 547 548 549 550 551 552 553 554 555 556 | set ::CONFIGLIST $::Platforms($platform) } puts "Running the following test configurations for $platform:" puts " [string trim $::CONFIGLIST]" puts -nonewline "Flags:" if {$::DRYRUN} {puts -nonewline " --dryrun"} if {$::BUILDONLY} {puts -nonewline " --buildonly"} switch -- $::QUICK { 1 {puts -nonewline " --quick"} 2 {puts -nonewline " --veryquick"} } puts "" } | > | 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 | set ::CONFIGLIST $::Platforms($platform) } puts "Running the following test configurations for $platform:" puts " [string trim $::CONFIGLIST]" puts -nonewline "Flags:" if {$::DRYRUN} {puts -nonewline " --dryrun"} if {$::BUILDONLY} {puts -nonewline " --buildonly"} if {$::MSVC} {puts -nonewline " --msvc"} switch -- $::QUICK { 1 {puts -nonewline " --quick"} 2 {puts -nonewline " --veryquick"} } puts "" } |
︙ | ︙ | |||
566 567 568 569 570 571 572 573 574 575 576 577 | set ::NERR 0 set ::NTEST 0 set ::NTESTCASE 0 set ::NERRCASE 0 set ::SQLITE_VERSION {} set STARTTIME [clock seconds] foreach {zConfig target} $::CONFIGLIST { if {$target ne "checksymbols"} { switch -- $::QUICK { 1 {set target test} 2 {set target smoketest} } | > > > > > | > > > | 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 | set ::NERR 0 set ::NTEST 0 set ::NTESTCASE 0 set ::NERRCASE 0 set ::SQLITE_VERSION {} set STARTTIME [clock seconds] foreach {zConfig target} $::CONFIGLIST { if {$::MSVC && ($zConfig eq "Sanitize" || "checksymbols" in $target || "valgrindtest" in $target)} { puts "Skipping $zConfig / $target for MSVC..." continue } if {$target ne "checksymbols"} { switch -- $::QUICK { 1 {set target test} 2 {set target smoketest} } if {$::BUILDONLY} { set target testfixture if {$::MSVC} {append target .exe} } } set config_options [concat $::Configs($zConfig) $::EXTRACONFIG] incr NTEST run_test_suite $zConfig $target $config_options # If the configuration included the SQLITE_DEBUG option, then remove |
︙ | ︙ |
Changes to test/select1.test.
︙ | ︙ | |||
303 304 305 306 307 308 309 310 311 312 313 314 315 316 | set v [catch {execsql {SELECT f1 FROM test1 ORDER BY min(f1,f2)}} msg] lappend v $msg } {0 {11 33}} do_test select1-4.4 { set v [catch {execsql {SELECT f1 FROM test1 ORDER BY min(f1)}} msg] lappend v $msg } {1 {misuse of aggregate: min()}} # The restriction not allowing constants in the ORDER BY clause # has been removed. See ticket #1768 #do_test select1-4.5 { # catchsql { # SELECT f1 FROM test1 ORDER BY 8.4; # } | > > > | 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 | set v [catch {execsql {SELECT f1 FROM test1 ORDER BY min(f1,f2)}} msg] lappend v $msg } {0 {11 33}} do_test select1-4.4 { set v [catch {execsql {SELECT f1 FROM test1 ORDER BY min(f1)}} msg] lappend v $msg } {1 {misuse of aggregate: min()}} do_catchsql_test select1-4.5 { INSERT INTO test1(f1) SELECT f1 FROM test1 ORDER BY min(f1); } {1 {misuse of aggregate: min()}} # The restriction not allowing constants in the ORDER BY clause # has been removed. See ticket #1768 #do_test select1-4.5 { # catchsql { # SELECT f1 FROM test1 ORDER BY 8.4; # } |
︙ | ︙ | |||
1068 1069 1070 1071 1072 1073 1074 | } # Crash bug reported on the mailing list on 2012-02-23 # do_test select1-16.1 { catchsql {SELECT 1 FROM (SELECT *)} } {1 {no tables specified}} | | > > > > > | 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 | } # Crash bug reported on the mailing list on 2012-02-23 # do_test select1-16.1 { catchsql {SELECT 1 FROM (SELECT *)} } {1 {no tables specified}} # 2015-04-17: assertion fix. do_catchsql_test select1-16.2 { SELECT 1 FROM sqlite_master LIMIT 1,#1; } {1 {near "#1": syntax error}} finish_test |
Changes to test/select4.test.
︙ | ︙ | |||
114 115 116 117 118 119 120 121 122 123 124 125 126 127 | SELECT DISTINCT log FROM t1 ORDER BY log UNION ALL SELECT n FROM t1 WHERE log=3 ORDER BY log; }} msg] lappend v $msg } {1 {ORDER BY clause should come after UNION ALL not before}} # Union operator # do_test select4-2.1 { execsql { SELECT DISTINCT log FROM t1 UNION | > > > > | 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 | SELECT DISTINCT log FROM t1 ORDER BY log UNION ALL SELECT n FROM t1 WHERE log=3 ORDER BY log; }} msg] lappend v $msg } {1 {ORDER BY clause should come after UNION ALL not before}} do_catchsql_test select4-1.4 { SELECT (VALUES(0) INTERSECT SELECT(0) UNION SELECT(0) ORDER BY 1 UNION SELECT 0 UNION SELECT 0 ORDER BY 1); } {1 {ORDER BY clause should come after UNION not before}} # Union operator # do_test select4-2.1 { execsql { SELECT DISTINCT log FROM t1 UNION |
︙ | ︙ | |||
142 143 144 145 146 147 148 149 150 151 152 153 154 155 | do_test select4-2.3 { set v [catch {execsql { SELECT DISTINCT log FROM t1 ORDER BY log UNION SELECT n FROM t1 WHERE log=3 ORDER BY log; }} msg] lappend v $msg } {1 {ORDER BY clause should come after UNION not before}} # Except operator # do_test select4-3.1.1 { execsql { | > > > > > > | 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 | do_test select4-2.3 { set v [catch {execsql { SELECT DISTINCT log FROM t1 ORDER BY log UNION SELECT n FROM t1 WHERE log=3 ORDER BY log; }} msg] lappend v $msg } {1 {ORDER BY clause should come after UNION not before}} do_test select4-2.4 { set v [catch {execsql { SELECT 0 ORDER BY (SELECT 0) UNION SELECT 0; }} msg] lappend v $msg } {1 {ORDER BY clause should come after UNION not before}} # Except operator # do_test select4-3.1.1 { execsql { |
︙ | ︙ | |||
870 871 872 873 874 875 876 | } {1 2 3 4 5 6 3 2 1 2 3 1 1 2 3 2 1 3} do_execsql_test select4-14.10 { SELECT (VALUES(1),(2),(3),(4)) } {1} do_execsql_test select4-14.11 { SELECT (SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4) } {1} | | > > > > > > > > | 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 | } {1 2 3 4 5 6 3 2 1 2 3 1 1 2 3 2 1 3} do_execsql_test select4-14.10 { SELECT (VALUES(1),(2),(3),(4)) } {1} do_execsql_test select4-14.11 { SELECT (SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4) } {1} do_execsql_test select4-14.12 { VALUES(1) UNION VALUES(2); } {1 2} do_execsql_test select4-14.13 { VALUES(1),(2),(3) EXCEPT VALUES(2); } {1 3} do_execsql_test select4-14.14 { VALUES(1),(2),(3) EXCEPT VALUES(1),(3); } {2} finish_test |
Changes to test/table.test.
︙ | ︙ | |||
267 268 269 270 271 272 273 274 275 276 277 278 279 280 | DROP TABLE IF EXISTS sqlite_stat1; DROP TABLE IF EXISTS sqlite_stat2; DROP TABLE IF EXISTS sqlite_stat3; DROP TABLE IF EXISTS sqlite_stat4; SELECT name FROM sqlite_master WHERE name GLOB 'sqlite_stat*'; } } {} # Make sure an EXPLAIN does not really create a new table # do_test table-5.3 { ifcapable {explain} { execsql {EXPLAIN CREATE TABLE test1(f1 int)} } | > > > > > > > > > > > > > > > > > > > | 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 | DROP TABLE IF EXISTS sqlite_stat1; DROP TABLE IF EXISTS sqlite_stat2; DROP TABLE IF EXISTS sqlite_stat3; DROP TABLE IF EXISTS sqlite_stat4; SELECT name FROM sqlite_master WHERE name GLOB 'sqlite_stat*'; } } {} do_test table-5.2.2 { db close forcedelete test.db sqlite3 db test.db db eval { CREATE TABLE t0(a,b); CREATE INDEX t ON t0(a); PRAGMA writable_schema=ON; UPDATE sqlite_master SET sql='CREATE TABLE a.b(a UNIQUE'; BEGIN; CREATE TABLE t1(x); ROLLBACK; DROP TABLE IF EXISTS t99; } } {} db close forcedelete test.db sqlite3 db test.db # Make sure an EXPLAIN does not really create a new table # do_test table-5.3 { ifcapable {explain} { execsql {EXPLAIN CREATE TABLE test1(f1 int)} } |
︙ | ︙ |
Changes to test/trigger7.test.
︙ | ︙ | |||
110 111 112 113 114 115 116 | execsql { PRAGMA writable_schema=on; UPDATE sqlite_master SET sql='nonsense'; } db close catch { sqlite3 db test.db } catchsql { DROP TRIGGER t2r5 } | | | 110 111 112 113 114 115 116 117 118 119 | execsql { PRAGMA writable_schema=on; UPDATE sqlite_master SET sql='nonsense'; } db close catch { sqlite3 db test.db } catchsql { DROP TRIGGER t2r5 } } {1 {malformed database schema (t2r12)}} finish_test |
Changes to test/vtab1.test.
︙ | ︙ | |||
1486 1487 1488 1489 1490 1491 1492 1493 1494 | do_test 23.3.1 { execsql { CREATE VIRTUAL TABLE t1e USING echo(t2) } execsql { INSERT INTO t1e SELECT 4 } catchsql { INSERT INTO t1e SELECT eval('DROP TABLE t1e') } } {1 {database table is locked}} do_execsql_test 23.3.2 { SELECT * FROM t1e } {1 2 3 4} finish_test | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 | do_test 23.3.1 { execsql { CREATE VIRTUAL TABLE t1e USING echo(t2) } execsql { INSERT INTO t1e SELECT 4 } catchsql { INSERT INTO t1e SELECT eval('DROP TABLE t1e') } } {1 {database table is locked}} do_execsql_test 23.3.2 { SELECT * FROM t1e } {1 2 3 4} #------------------------------------------------------------------------- # At one point SQL like this: # # SAVEPOINT xyz; -- Opens SQL transaction # INSERT INTO vtab -- Write to virtual table # ROLLBACK TO xyz; # RELEASE xyz; # # was not invoking the xRollbackTo() callback for the ROLLBACK TO # operation. Which meant that virtual tables like FTS3 would incorrectly # commit the results of the INSERT as part of the "RELEASE xyz" command. # # The following tests check that this has been fixed. # ifcapable fts3 { do_execsql_test 24.0 { CREATE VIRTUAL TABLE t4 USING fts3(); SAVEPOINT a; INSERT INTO t4 VALUES('a b c'); ROLLBACK TO a; RELEASE a; SELECT * FROM t4; } {} do_execsql_test 24.1 { SELECT * FROM t4 WHERE t4 MATCH 'b' } {} do_execsql_test 24.2 { INSERT INTO t4(t4) VALUES('integrity-check') } {} do_execsql_test 24.3 { SAVEPOINT a; CREATE VIRTUAL TABLE t5 USING fts3(); SAVEPOINT b; ROLLBACK TO a; SAVEPOINT c; RELEASE a; } } finish_test |
Changes to test/vtabA.test.
︙ | ︙ | |||
70 71 72 73 74 75 76 77 78 79 80 | } {{value a} {} {value c}} do_test vtabA-1.6 { execsql { SELECT * FROM t1e; } } {{value a} {value c}} # Test that the expansion of a '*' expression in the result set of # a SELECT does not include the hidden column. # | > > > > > > > > > > > | | | | | | | 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 | } {{value a} {} {value c}} do_test vtabA-1.6 { execsql { SELECT * FROM t1e; } } {{value a} {value c}} do_execsql_test vtabA-1.7 { DELETE FROM t1e; INSERT INTO t1e SELECT 'abc','def'; } {} do_execsql_test vtabA-1.8 { INSERT INTO t1e VALUES('ghi','jkl'),('mno','pqr'),('stu','vwx'); } {} do_execsql_test vtabA-1.9 { SELECT a,b,c, '|' FROM t1e ORDER BY 1; } {abc {} def | ghi {} jkl | mno {} pqr | stu {} vwx |} # Test that the expansion of a '*' expression in the result set of # a SELECT does not include the hidden column. # do_test vtabA-1.20 { execsql { INSERT INTO t1e SELECT * FROM t1e; } } {} do_test vtabA-1.21 { execsql { SELECT * FROM t1e ORDER BY 1; } } {abc def abc def ghi jkl ghi jkl mno pqr mno pqr stu vwx stu vwx} # Test that the declaration type of the hidden column does not include # the token "HIDDEN". # do_test vtabA-1.22 { get_decltype t1e b } {VARCHAR} do_test vtabA-1.23 { get_collist t1e } {a c} #---------------------------------------------------------------------- # These tests vtabA-2.* concentrate on testing that the HIDDEN token # is detected and handled correctly in various declarations. # |
︙ | ︙ |
Added tool/fuzzershell.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 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 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 | /* ** 2015-04-17 ** ** 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 is a utility program designed to aid running the SQLite library ** against an external fuzzer, such as American Fuzzy Lop (AFL) ** (http://lcamtuf.coredump.cx/afl/). Basically, this program reads ** SQL text from standard input and passes it through to SQLite for evaluation, ** just like the "sqlite3" command-line shell. Differences from the ** command-line shell: ** ** (1) The complex "dot-command" extensions are omitted. This ** prevents the fuzzer from discovering that it can run things ** like ".shell rm -rf ~" ** ** (2) The database is opened with the SQLITE_OPEN_MEMORY flag so that ** no disk I/O from the database is permitted. The ATTACH command ** with a filename still uses an in-memory database. ** ** (3) The main in-memory database can be initialized from a template ** disk database so that the fuzzer starts with a database containing ** content. ** ** (4) The eval() SQL function is added, allowing the fuzzer to do ** interesting recursive operations. */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdarg.h> #include "sqlite3.h" /* ** All global variables are gathered into the "g" singleton. */ struct GlobalVars { const char *zArgv0; /* Name of program */ } g; /* ** Print an error message and abort in such a way to indicate to the ** fuzzer that this counts as a crash. */ static void abendError(const char *zFormat, ...){ va_list ap; fprintf(stderr, "%s: ", g.zArgv0); va_start(ap, zFormat); vfprintf(stderr, zFormat, ap); va_end(ap); fprintf(stderr, "\n"); abort(); } /* ** Print an error message and quit, but not in a way that would look ** like a crash. */ static void fatalError(const char *zFormat, ...){ va_list ap; fprintf(stderr, "%s: ", g.zArgv0); va_start(ap, zFormat); vfprintf(stderr, zFormat, ap); va_end(ap); fprintf(stderr, "\n"); exit(1); } /* ** This callback is invoked by sqlite3_log(). */ static void shellLog(void *pNotUsed, int iErrCode, const char *zMsg){ printf("LOG: (%d) %s\n", iErrCode, zMsg); } /* ** This callback is invoked by sqlite3_exec() to return query results. */ static int execCallback(void *NotUsed, int argc, char **argv, char **colv){ int i; static unsigned cnt = 0; printf("ROW #%u:\n", ++cnt); for(i=0; i<argc; i++){ printf(" %s=", colv[i]); if( argv[i] ){ printf("[%s]\n", argv[i]); }else{ printf("NULL\n"); } } return 0; } /* ** This callback is invoked by sqlite3_trace() as each SQL statement ** starts. */ static void traceCallback(void *NotUsed, const char *zMsg){ printf("TRACE: %s\n", zMsg); } /*************************************************************************** ** eval() implementation copied from ../ext/misc/eval.c */ /* ** Structure used to accumulate the output */ struct EvalResult { char *z; /* Accumulated output */ const char *zSep; /* Separator */ int szSep; /* Size of the separator string */ sqlite3_int64 nAlloc; /* Number of bytes allocated for z[] */ sqlite3_int64 nUsed; /* Number of bytes of z[] actually used */ }; /* ** Callback from sqlite_exec() for the eval() function. */ static int callback(void *pCtx, int argc, char **argv, char **colnames){ struct EvalResult *p = (struct EvalResult*)pCtx; int i; for(i=0; i<argc; i++){ const char *z = argv[i] ? argv[i] : ""; size_t sz = strlen(z); if( (sqlite3_int64)sz+p->nUsed+p->szSep+1 > p->nAlloc ){ char *zNew; p->nAlloc = p->nAlloc*2 + sz + p->szSep + 1; /* Using sqlite3_realloc64() would be better, but it is a recent ** addition and will cause a segfault if loaded by an older version ** of SQLite. */ zNew = p->nAlloc<=0x7fffffff ? sqlite3_realloc(p->z, (int)p->nAlloc) : 0; if( zNew==0 ){ sqlite3_free(p->z); memset(p, 0, sizeof(*p)); return 1; } p->z = zNew; } if( p->nUsed>0 ){ memcpy(&p->z[p->nUsed], p->zSep, p->szSep); p->nUsed += p->szSep; } memcpy(&p->z[p->nUsed], z, sz); p->nUsed += sz; } return 0; } /* ** Implementation of the eval(X) and eval(X,Y) SQL functions. ** ** Evaluate the SQL text in X. Return the results, using string ** Y as the separator. If Y is omitted, use a single space character. */ static void sqlEvalFunc( sqlite3_context *context, int argc, sqlite3_value **argv ){ const char *zSql; sqlite3 *db; char *zErr = 0; int rc; struct EvalResult x; memset(&x, 0, sizeof(x)); x.zSep = " "; zSql = (const char*)sqlite3_value_text(argv[0]); if( zSql==0 ) return; if( argc>1 ){ x.zSep = (const char*)sqlite3_value_text(argv[1]); if( x.zSep==0 ) return; } x.szSep = (int)strlen(x.zSep); db = sqlite3_context_db_handle(context); rc = sqlite3_exec(db, zSql, callback, &x, &zErr); if( rc!=SQLITE_OK ){ sqlite3_result_error(context, zErr, -1); sqlite3_free(zErr); }else if( x.zSep==0 ){ sqlite3_result_error_nomem(context); sqlite3_free(x.z); }else{ sqlite3_result_text(context, x.z, (int)x.nUsed, sqlite3_free); } } /* End of the eval() implementation ******************************************************************************/ /* ** Print sketchy documentation for this utility program */ static void showHelp(void){ printf("Usage: %s [options]\n", g.zArgv0); printf( "Read SQL text from standard input and evaluate it.\n" "Options:\n" " -f FILE Read SQL text from FILE instead of standard input\n" " --help Show this help text\n" " --initdb DBFILE Initialize the in-memory database using template DBFILE\n" ); } int main(int argc, char **argv){ char *zIn = 0; /* Input text */ int nAlloc = 0; /* Number of bytes allocated for zIn[] */ int nIn = 0; /* Number of bytes of zIn[] used */ size_t got; /* Bytes read from input */ FILE *in = stdin; /* Where to read SQL text from */ int rc = SQLITE_OK; /* Result codes from API functions */ int i; /* Loop counter */ sqlite3 *db; /* Open database */ sqlite3 *dbInit; /* On-disk database used to initialize the in-memory db */ const char *zInitDb = 0;/* Name of the initialization database file */ char *zErrMsg = 0; /* Error message returned from sqlite3_exec() */ g.zArgv0 = argv[0]; for(i=1; i<argc; i++){ const char *z = argv[i]; if( z[0]=='-' ){ z++; if( z[0]=='-' ) z++; if( strcmp(z,"help")==0 ){ showHelp(); return 0; }else if( strcmp(z, "f")==0 && i+1<argc ){ if( in!=stdin ) abendError("only one -f allowed"); in = fopen(argv[++i],"rb"); if( in==0 ) abendError("cannot open input file \"%s\"", argv[i]); }else if( strcmp(z, "initdb")==0 && i+1<argc ){ if( zInitDb!=0 ) abendError("only one --initdb allowed"); zInitDb = argv[++i]; }else { abendError("unknown option: %s", argv[i]); } }else{ abendError("unknown argument: %s", argv[i]); } } sqlite3_config(SQLITE_CONFIG_LOG, shellLog, 0); rc = sqlite3_open_v2( "main.db", &db, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_MEMORY, 0); if( rc!=SQLITE_OK ){ abendError("Unable to open the in-memory database"); } if( zInitDb ){ sqlite3_backup *pBackup; rc = sqlite3_open_v2(zInitDb, &dbInit, SQLITE_OPEN_READONLY, 0); if( rc!=SQLITE_OK ){ abendError("unable to open initialization database \"%s\"", zInitDb); } pBackup = sqlite3_backup_init(db, "main", dbInit, "main"); rc = sqlite3_backup_step(pBackup, -1); if( rc!=SQLITE_DONE ){ abendError("attempt to initialize the in-memory database failed (rc=%d)",rc); } sqlite3_backup_finish(pBackup); sqlite3_close(dbInit); } sqlite3_trace(db, traceCallback, 0); sqlite3_create_function(db, "eval", 1, SQLITE_UTF8, 0, sqlEvalFunc, 0, 0); sqlite3_create_function(db, "eval", 2, SQLITE_UTF8, 0, sqlEvalFunc, 0, 0); while( !feof(in) ){ nAlloc += 1000; zIn = sqlite3_realloc(zIn, nAlloc); if( zIn==0 ) fatalError("out of memory"); got = fread(zIn+nIn, 1, nAlloc-nIn-1, in); nIn += (int)got; zIn[nIn] = 0; if( got==0 ) break; } printf("INPUT (%d bytes): [%s]\n", nIn, zIn); rc = sqlite3_exec(db, zIn, execCallback, 0, &zErrMsg); printf("RESULT-CODE: %d\n", rc); if( zErrMsg ){ printf("ERROR-MSG: [%s]\n", zErrMsg); sqlite3_free(zErrMsg); } return rc!=SQLITE_OK; } |
Changes to tool/showdb.c.
︙ | ︙ | |||
60 61 62 63 64 65 66 67 68 69 70 | ** Read content from the file. ** ** Space to hold the content is obtained from malloc() and needs to be ** freed by the caller. */ static unsigned char *getContent(int ofst, int nByte){ unsigned char *aData; aData = malloc(nByte+32); if( aData==0 ) out_of_memory(); memset(aData, 0, nByte+32); lseek(db, ofst, SEEK_SET); | > | > | 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | ** Read content from the file. ** ** Space to hold the content is obtained from malloc() and needs to be ** freed by the caller. */ static unsigned char *getContent(int ofst, int nByte){ unsigned char *aData; int got; aData = malloc(nByte+32); if( aData==0 ) out_of_memory(); memset(aData, 0, nByte+32); lseek(db, ofst, SEEK_SET); got = read(db, aData, nByte); if( got>0 && got<nByte ) memset(aData+got, 0, nByte-got); return aData; } /* ** Print a range of bytes as hex and as ascii. */ static unsigned char *print_byte_range( |
︙ | ︙ | |||
977 978 979 980 981 982 983 | zPgSz[1] = 0; lseek(db, 16, SEEK_SET); if( read(db, zPgSz, 2)<2 ) memset(zPgSz, 0, 2); pagesize = zPgSz[0]*256 + zPgSz[1]*65536; if( pagesize==0 ) pagesize = 1024; printf("Pagesize: %d\n", pagesize); fstat(db, &sbuf); | | | 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 | zPgSz[1] = 0; lseek(db, 16, SEEK_SET); if( read(db, zPgSz, 2)<2 ) memset(zPgSz, 0, 2); pagesize = zPgSz[0]*256 + zPgSz[1]*65536; if( pagesize==0 ) pagesize = 1024; printf("Pagesize: %d\n", pagesize); fstat(db, &sbuf); mxPage = (sbuf.st_size+pagesize-1)/pagesize; printf("Available pages: 1..%d\n", mxPage); if( argc==2 ){ int i; for(i=1; i<=mxPage; i++) print_page(i); }else{ int i; for(i=2; i<argc; i++){ |
︙ | ︙ |
Changes to tool/sqldiff.c.
1 2 3 4 5 6 7 8 9 10 11 12 | /* ** 2015-04-06 ** ** 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 20 21 22 23 24 25 26 | /* ** 2015-04-06 ** ** 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 is a utility program that computes the differences in content ** between two SQLite databases. ** ** To compile, simply link against SQLite. ** ** See the showHelp() routine below for a brief description of how to ** run the utility. */ #include <stdio.h> #include <stdlib.h> #include <stdarg.h> #include <ctype.h> #include <string.h> #include "sqlite3.h" |
︙ | ︙ |