Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Merge the 3.9.1 updates from trunk. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | begin-concurrent |
Files: | files | file ages | folders |
SHA1: |
bf866e6c0d95d48744c86ff0c0be9b26 |
User & Date: | drh 2015-10-16 20:55:12.158 |
Context
2015-10-30
| ||
17:17 | Merge the sqlite3_db_cacheflush() enhancements and other changes from trunk. (check-in: f2cde4cfc5 user: drh tags: begin-concurrent) | |
2015-10-16
| ||
20:55 | Merge the 3.9.1 updates from trunk. (check-in: bf866e6c0d user: drh tags: begin-concurrent) | |
20:13 | Enhancements to the MSVC makefile. (check-in: 39e8a5d93f user: mistachkin tags: trunk) | |
2015-10-15
| ||
07:44 | Merge in the 3.9.0 changes from trunk. (check-in: 5c3a2a6ed6 user: drh tags: begin-concurrent) | |
Changes
Changes to Makefile.msc.
︙ | ︙ | |||
288 289 290 291 292 293 294 | NSDKLIBPATH = $(NSDKLIBPATH:\\=\) # C compiler and options for use in building executables that # will run on the platform that is doing the build. # !IF $(USE_FULLWARN)!=0 | | | | 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 | NSDKLIBPATH = $(NSDKLIBPATH:\\=\) # C compiler and options for use in building executables that # will run on the platform that is doing the build. # !IF $(USE_FULLWARN)!=0 BCC = $(NCC) -nologo -W4 $(CCOPTS) $(BCCOPTS) !ELSE BCC = $(NCC) -nologo -W3 $(CCOPTS) $(BCCOPTS) !ENDIF # Check if assembly code listings should be generated for the source # code files to be compiled. # !IF $(USE_LISTINGS)!=0 BCC = $(BCC) -FAcs |
︙ | ︙ | |||
318 319 320 321 322 323 324 | !ENDIF # C compiler and options for use in building executables that # will run on the target platform. (BCC and TCC are usually the # same unless your are cross-compiling.) # !IF $(USE_FULLWARN)!=0 | | | | | 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 | !ENDIF # C compiler and options for use in building executables that # will run on the target platform. (BCC and TCC are usually the # same unless your are cross-compiling.) # !IF $(USE_FULLWARN)!=0 TCC = $(CC) -nologo -W4 -DINCLUDE_MSVC_H=1 $(CCOPTS) $(TCCOPTS) !ELSE TCC = $(CC) -nologo -W3 $(CCOPTS) $(TCCOPTS) !ENDIF TCC = $(TCC) -DSQLITE_OS_WIN=1 -I. -I$(TOP) -I$(TOP)\src -fp:precise RCC = $(RC) -DSQLITE_OS_WIN=1 -I$(TOP) -I$(TOP)\src $(RCOPTS) $(RCCOPTS) # Check if we want to use the "stdcall" calling convention when compiling. # This is not supported by the compilers for non-x86 platforms. It should # also be noted here that building any target with these "stdcall" options # will most likely fail if the Tcl library is also required. This is due # to how the Tcl library functions are declared and exported (i.e. without # an explicit calling convention, which results in "cdecl"). |
︙ | ︙ | |||
568 569 570 571 572 573 574 575 576 577 578 579 580 581 | !IFNDEF LIBTCL LIBTCL = tcl85.lib !ENDIF !IFNDEF LIBTCLSTUB LIBTCLSTUB = tclstub85.lib !ENDIF # The locations of the ICU header and library files. These variables # (ICUINCDIR, ICULIBDIR, and LIBICU) may be overridden via the environment # prior to running nmake in order to match the actual installed location on # this machine. # !IFNDEF ICUINCDIR | > > > > | 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 | !IFNDEF LIBTCL LIBTCL = tcl85.lib !ENDIF !IFNDEF LIBTCLSTUB LIBTCLSTUB = tclstub85.lib !ENDIF !IFNDEF LIBTCLPATH LIBTCLPATH = c:\tcl\bin !ENDIF # The locations of the ICU header and library files. These variables # (ICUINCDIR, ICULIBDIR, and LIBICU) may be overridden via the environment # prior to running nmake in order to match the actual installed location on # this machine. # !IFNDEF ICUINCDIR |
︙ | ︙ | |||
792 793 794 795 796 797 798 | LTLINKOPTS = $(LTLINKOPTS) "/LIBPATH:$(PSDKLIBPATH)" !ENDIF !ENDIF # If either debugging or symbols are enabled, enable PDBs. # !IF $(DEBUG)>1 || $(SYMBOLS)!=0 | | > > | 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 | LTLINKOPTS = $(LTLINKOPTS) "/LIBPATH:$(PSDKLIBPATH)" !ENDIF !ENDIF # If either debugging or symbols are enabled, enable PDBs. # !IF $(DEBUG)>1 || $(SYMBOLS)!=0 LDFLAGS = /DEBUG $(LDOPTS) !ELSE LDFLAGS = $(LDOPTS) !ENDIF # Start with the Tcl related linker options. # !IF $(NO_TCL)==0 LTLIBPATHS = /LIBPATH:$(TCLLIBDIR) LTLIBS = $(LIBTCL) |
︙ | ︙ | |||
1307 1308 1309 1310 1311 1312 1313 | # Rules to build the LEMON compiler generator # lempar.c: $(TOP)\src\lempar.c copy $(TOP)\src\lempar.c . lemon.exe: $(TOP)\tool\lemon.c lempar.c $(BCC) $(NO_WARN) -Daccess=_access \ | | | 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 | # Rules to build the LEMON compiler generator # lempar.c: $(TOP)\src\lempar.c copy $(TOP)\src\lempar.c . lemon.exe: $(TOP)\tool\lemon.c lempar.c $(BCC) $(NO_WARN) -Daccess=_access \ -Fe$@ $(TOP)\tool\lemon.c /link $(LDFLAGS) $(NLTLINKOPTS) $(NLTLIBPATHS) # Rules to build individual *.lo files from generated *.c files. This # applies to: # # parse.lo # opcodes.lo # |
︙ | ︙ | |||
1594 1595 1596 1597 1598 1599 1600 | $(TCLSH_CMD) $(TOP)\tool\mksqlite3h.tcl $(TOP:\=/) > sqlite3.h sqlite3ext.h: .target_source copy tsrc\sqlite3ext.h . mkkeywordhash.exe: $(TOP)\tool\mkkeywordhash.c $(BCC) $(NO_WARN) -Fe$@ $(REQ_FEATURE_FLAGS) $(OPT_FEATURE_FLAGS) $(OPTS) \ | | | 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 | $(TCLSH_CMD) $(TOP)\tool\mksqlite3h.tcl $(TOP:\=/) > sqlite3.h sqlite3ext.h: .target_source copy tsrc\sqlite3ext.h . mkkeywordhash.exe: $(TOP)\tool\mkkeywordhash.c $(BCC) $(NO_WARN) -Fe$@ $(REQ_FEATURE_FLAGS) $(OPT_FEATURE_FLAGS) $(OPTS) \ $(TOP)\tool\mkkeywordhash.c /link $(LDFLAGS) $(NLTLINKOPTS) $(NLTLIBPATHS) keywordhash.h: $(TOP)\tool\mkkeywordhash.c mkkeywordhash.exe .\mkkeywordhash.exe > keywordhash.h # Rules to build the extension objects. |
︙ | ︙ | |||
1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 | testfixture.exe: $(TESTFIXTURE_SRC) $(LIBRESOBJS) $(HDR) $(LTLINK) -DSQLITE_NO_SYNC=1 $(TESTFIXTURE_FLAGS) \ -DBUILD_sqlite -I$(TCLINCDIR) \ $(TESTFIXTURE_SRC) \ /link $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LTLIBS) $(TLIBS) extensiontest: testfixture.exe testloadext.dll .\testfixture.exe $(TOP)\test\loadext.test $(TESTOPTS) fulltest: $(TESTPROGS) fuzztest .\testfixture.exe $(TOP)\test\all.test $(TESTOPTS) soaktest: $(TESTPROGS) .\testfixture.exe $(TOP)\test\all.test -soak=1 $(TESTOPTS) fulltestonly: $(TESTPROGS) fuzztest .\testfixture.exe $(TOP)\test\full.test queryplantest: testfixture.exe sqlite3.exe .\testfixture.exe $(TOP)\test\permutations.test queryplanner $(TESTOPTS) fuzztest: fuzzcheck.exe .\fuzzcheck.exe $(FUZZDATA) fastfuzztest: fuzzcheck.exe .\fuzzcheck.exe --limit-mem 100M $(FUZZDATA) # Minimal testing that runs in less than 3 minutes (on a fast machine) # quicktest: testfixture.exe .\testfixture.exe $(TOP)\test\extraquick.test $(TESTOPTS) # This is the common case. Run many tests that do not take too long, # including fuzzcheck, sqlite3_analyzer, and sqldiff tests. # test: $(TESTPROGS) fastfuzztest .\testfixture.exe $(TOP)\test\veryquick.test $(TESTOPTS) smoketest: $(TESTPROGS) .\testfixture.exe $(TOP)\test\main.test $(TESTOPTS) sqlite3_analyzer.c: $(SQLITE3C) $(TOP)\src\tclsqlite.c $(TOP)\tool\spaceanal.tcl echo #define TCLSH 2 > $@ echo #define SQLITE_ENABLE_DBSTAT_VTAB 1 >> $@ copy $@ + $(SQLITE3C) + $(TOP)\src\tclsqlite.c $@ echo static const char *tclsh_main_loop(void){ >> $@ | > > > > > > > > | 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 | testfixture.exe: $(TESTFIXTURE_SRC) $(LIBRESOBJS) $(HDR) $(LTLINK) -DSQLITE_NO_SYNC=1 $(TESTFIXTURE_FLAGS) \ -DBUILD_sqlite -I$(TCLINCDIR) \ $(TESTFIXTURE_SRC) \ /link $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LTLIBS) $(TLIBS) extensiontest: testfixture.exe testloadext.dll @set PATH=$(LIBTCLPATH);$(PATH) .\testfixture.exe $(TOP)\test\loadext.test $(TESTOPTS) fulltest: $(TESTPROGS) fuzztest @set PATH=$(LIBTCLPATH);$(PATH) .\testfixture.exe $(TOP)\test\all.test $(TESTOPTS) soaktest: $(TESTPROGS) @set PATH=$(LIBTCLPATH);$(PATH) .\testfixture.exe $(TOP)\test\all.test -soak=1 $(TESTOPTS) fulltestonly: $(TESTPROGS) fuzztest @set PATH=$(LIBTCLPATH);$(PATH) .\testfixture.exe $(TOP)\test\full.test queryplantest: testfixture.exe sqlite3.exe @set PATH=$(LIBTCLPATH);$(PATH) .\testfixture.exe $(TOP)\test\permutations.test queryplanner $(TESTOPTS) fuzztest: fuzzcheck.exe .\fuzzcheck.exe $(FUZZDATA) fastfuzztest: fuzzcheck.exe .\fuzzcheck.exe --limit-mem 100M $(FUZZDATA) # Minimal testing that runs in less than 3 minutes (on a fast machine) # quicktest: testfixture.exe @set PATH=$(LIBTCLPATH);$(PATH) .\testfixture.exe $(TOP)\test\extraquick.test $(TESTOPTS) # This is the common case. Run many tests that do not take too long, # including fuzzcheck, sqlite3_analyzer, and sqldiff tests. # test: $(TESTPROGS) fastfuzztest @set PATH=$(LIBTCLPATH);$(PATH) .\testfixture.exe $(TOP)\test\veryquick.test $(TESTOPTS) smoketest: $(TESTPROGS) @set PATH=$(LIBTCLPATH);$(PATH) .\testfixture.exe $(TOP)\test\main.test $(TESTOPTS) sqlite3_analyzer.c: $(SQLITE3C) $(TOP)\src\tclsqlite.c $(TOP)\tool\spaceanal.tcl echo #define TCLSH 2 > $@ echo #define SQLITE_ENABLE_DBSTAT_VTAB 1 >> $@ copy $@ + $(SQLITE3C) + $(TOP)\src\tclsqlite.c $@ echo static const char *tclsh_main_loop(void){ >> $@ |
︙ | ︙ |
Changes to VERSION.
|
| | | 1 | 3.9.1 |
Changes to configure.
1 2 | #! /bin/sh # Guess values for system-dependent variables and create Makefiles. | | | 1 2 3 4 5 6 7 8 9 10 | #! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.69 for sqlite 3.9.1. # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. # # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. |
︙ | ︙ | |||
722 723 724 725 726 727 728 | subdirs= MFLAGS= MAKEFLAGS= # Identity of this package. PACKAGE_NAME='sqlite' PACKAGE_TARNAME='sqlite' | | | | 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 | subdirs= MFLAGS= MAKEFLAGS= # Identity of this package. PACKAGE_NAME='sqlite' PACKAGE_TARNAME='sqlite' PACKAGE_VERSION='3.9.1' PACKAGE_STRING='sqlite 3.9.1' PACKAGE_BUGREPORT='' PACKAGE_URL='' # Factoring default headers for most tests. ac_includes_default="\ #include <stdio.h> #ifdef HAVE_SYS_TYPES_H |
︙ | ︙ | |||
1454 1455 1456 1457 1458 1459 1460 | # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF | | | 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 | # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures sqlite 3.9.1 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. |
︙ | ︙ | |||
1519 1520 1521 1522 1523 1524 1525 | --build=BUILD configure for building on BUILD [guessed] --host=HOST cross-compile to build programs to run on HOST [BUILD] _ACEOF fi if test -n "$ac_init_help"; then case $ac_init_help in | | | 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 | --build=BUILD configure for building on BUILD [guessed] --host=HOST cross-compile to build programs to run on HOST [BUILD] _ACEOF fi if test -n "$ac_init_help"; then case $ac_init_help in short | recursive ) echo "Configuration of sqlite 3.9.1:";; esac cat <<\_ACEOF Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] |
︙ | ︙ | |||
1639 1640 1641 1642 1643 1644 1645 | cd "$ac_pwd" || { ac_status=$?; break; } done fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF | | | 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 | cd "$ac_pwd" || { ac_status=$?; break; } done fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF sqlite configure 3.9.1 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit |
︙ | ︙ | |||
2058 2059 2060 2061 2062 2063 2064 | eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_mongrel cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. | | | 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 | eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_mongrel cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by sqlite $as_me 3.9.1, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ _ACEOF exec 5>>config.log { |
︙ | ︙ | |||
11942 11943 11944 11945 11946 11947 11948 | test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Save the log message, to keep $0 and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" | | | 11942 11943 11944 11945 11946 11947 11948 11949 11950 11951 11952 11953 11954 11955 11956 | test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Save the log message, to keep $0 and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by sqlite $as_me 3.9.1, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ |
︙ | ︙ | |||
12008 12009 12010 12011 12012 12013 12014 | Report bugs to the package provider." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ | | | 12008 12009 12010 12011 12012 12013 12014 12015 12016 12017 12018 12019 12020 12021 12022 | Report bugs to the package provider." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ sqlite config.status 3.9.1 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" Copyright (C) 2012 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." |
︙ | ︙ |
Changes to ext/fts5/fts5_aux.c.
︙ | ︙ | |||
133 134 135 136 137 138 139 | */ static void fts5HighlightAppend( int *pRc, HighlightContext *p, const char *z, int n ){ if( *pRc==SQLITE_OK ){ | | | 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 | */ static void fts5HighlightAppend( int *pRc, HighlightContext *p, const char *z, int n ){ if( *pRc==SQLITE_OK ){ if( n<0 ) n = (int)strlen(z); p->zOut = sqlite3_mprintf("%z%.*s", p->zOut, n, z); if( p->zOut==0 ) *pRc = SQLITE_NOMEM; } } /* ** Tokenizer callback used by implementation of highlight() function. |
︙ | ︙ |
Changes to ext/fts5/fts5_buffer.c.
︙ | ︙ | |||
88 89 90 91 92 93 94 | ** though this byte is not included in the pBuf->n count. */ void sqlite3Fts5BufferAppendString( int *pRc, Fts5Buffer *pBuf, const char *zStr ){ | | | 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | ** though this byte is not included in the pBuf->n count. */ void sqlite3Fts5BufferAppendString( int *pRc, Fts5Buffer *pBuf, const char *zStr ){ int nStr = (int)strlen(zStr); sqlite3Fts5BufferAppendBlob(pRc, pBuf, nStr+1, (const u8*)zStr); pBuf->n--; } /* ** Argument zFmt is a printf() style format string. This function performs ** the printf() style processing, then appends the results to buffer pBuf. |
︙ | ︙ | |||
260 261 262 263 264 265 266 | ** It is the responsibility of the caller to eventually free the returned ** buffer using sqlite3_free(). If an OOM error occurs, NULL is returned. */ char *sqlite3Fts5Strndup(int *pRc, const char *pIn, int nIn){ char *zRet = 0; if( *pRc==SQLITE_OK ){ if( nIn<0 ){ | | | 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 | ** It is the responsibility of the caller to eventually free the returned ** buffer using sqlite3_free(). If an OOM error occurs, NULL is returned. */ char *sqlite3Fts5Strndup(int *pRc, const char *pIn, int nIn){ char *zRet = 0; if( *pRc==SQLITE_OK ){ if( nIn<0 ){ nIn = (int)strlen(pIn); } zRet = (char*)sqlite3_malloc(nIn+1); if( zRet ){ memcpy(zRet, pIn, nIn); zRet[nIn] = '\0'; }else{ *pRc = SQLITE_NOMEM; |
︙ | ︙ |
Changes to ext/fts5/fts5_config.c.
︙ | ︙ | |||
207 208 209 210 211 212 213 | Fts5Global *pGlobal, Fts5Config *pConfig, /* Configuration object to update */ const char *zCmd, /* Special command to parse */ const char *zArg, /* Argument to parse */ char **pzErr /* OUT: Error message */ ){ int rc = SQLITE_OK; | | | 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 | Fts5Global *pGlobal, Fts5Config *pConfig, /* Configuration object to update */ const char *zCmd, /* Special command to parse */ const char *zArg, /* Argument to parse */ char **pzErr /* OUT: Error message */ ){ int rc = SQLITE_OK; int nCmd = (int)strlen(zCmd); if( sqlite3_strnicmp("prefix", zCmd, nCmd)==0 ){ const int nByte = sizeof(int) * FTS5_MAX_PREFIX_INDEXES; const char *p; if( pConfig->aPrefix ){ *pzErr = sqlite3_mprintf("multiple prefix=... directives"); rc = SQLITE_ERROR; }else{ |
︙ | ︙ | |||
244 245 246 247 248 249 250 | pConfig->nPrefix++; } return rc; } if( sqlite3_strnicmp("tokenize", zCmd, nCmd)==0 ){ const char *p = (const char*)zArg; | | | 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 | pConfig->nPrefix++; } return rc; } if( sqlite3_strnicmp("tokenize", zCmd, nCmd)==0 ){ const char *p = (const char*)zArg; int nArg = (int)strlen(zArg) + 1; char **azArg = sqlite3Fts5MallocZero(&rc, sizeof(char*) * nArg); char *pDel = sqlite3Fts5MallocZero(&rc, nArg * 2); char *pSpace = pDel; if( azArg && pSpace ){ if( pConfig->pTok ){ *pzErr = sqlite3_mprintf("multiple tokenize=... directives"); |
︙ | ︙ | |||
360 361 362 363 364 365 366 | int *pRc, /* IN/OUT: Error code */ const char *zIn, /* Buffer to gobble string/bareword from */ char **pzOut, /* OUT: malloc'd buffer containing str/bw */ int *pbQuoted /* OUT: Set to true if dequoting required */ ){ const char *zRet = 0; | | | 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 | int *pRc, /* IN/OUT: Error code */ const char *zIn, /* Buffer to gobble string/bareword from */ char **pzOut, /* OUT: malloc'd buffer containing str/bw */ int *pbQuoted /* OUT: Set to true if dequoting required */ ){ const char *zRet = 0; int nIn = (int)strlen(zIn); char *zOut = sqlite3_malloc(nIn+1); assert( *pRc==SQLITE_OK ); *pbQuoted = 0; *pzOut = 0; if( zOut==0 ){ |
︙ | ︙ |
Changes to ext/fts5/fts5_expr.c.
︙ | ︙ | |||
903 904 905 906 907 908 909 | for(p=pTerm; p && rc==SQLITE_OK; p=p->pSynonym){ if( p->pIter ){ sqlite3Fts5IterClose(p->pIter); p->pIter = 0; } rc = sqlite3Fts5IndexQuery( | | | 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 | for(p=pTerm; p && rc==SQLITE_OK; p=p->pSynonym){ if( p->pIter ){ sqlite3Fts5IterClose(p->pIter); p->pIter = 0; } rc = sqlite3Fts5IndexQuery( pExpr->pIndex, p->zTerm, (int)strlen(p->zTerm), (pTerm->bPrefix ? FTS5INDEX_QUERY_PREFIX : 0) | (pExpr->bDesc ? FTS5INDEX_QUERY_DESC : 0), pNear->pColset, &p->pIter ); assert( rc==SQLITE_OK || p->pIter==0 ); if( p->pIter && 0==sqlite3Fts5IterEof(p->pIter) ){ |
︙ | ︙ | |||
1514 1515 1516 1517 1518 1519 1520 | sCtx.pPhrase = pAppend; rc = fts5ParseStringFromToken(pToken, &z); if( rc==SQLITE_OK ){ int flags = FTS5_TOKENIZE_QUERY | (bPrefix ? FTS5_TOKENIZE_QUERY : 0); int n; sqlite3Fts5Dequote(z); | | | 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 | sCtx.pPhrase = pAppend; rc = fts5ParseStringFromToken(pToken, &z); if( rc==SQLITE_OK ){ int flags = FTS5_TOKENIZE_QUERY | (bPrefix ? FTS5_TOKENIZE_QUERY : 0); int n; sqlite3Fts5Dequote(z); n = (int)strlen(z); rc = sqlite3Fts5Tokenize(pConfig, flags, z, n, &sCtx, fts5ParseTokenize); } sqlite3_free(z); if( rc || (rc = sCtx.rc) ){ pParse->rc = rc; fts5ExprPhraseFree(sCtx.pPhrase); sCtx.pPhrase = 0; |
︙ | ︙ | |||
1587 1588 1589 1590 1591 1592 1593 | } for(i=0; rc==SQLITE_OK && i<pOrig->nTerm; i++){ int tflags = 0; Fts5ExprTerm *p; for(p=&pOrig->aTerm[i]; p && rc==SQLITE_OK; p=p->pSynonym){ const char *zTerm = p->zTerm; | | > | 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 | } for(i=0; rc==SQLITE_OK && i<pOrig->nTerm; i++){ int tflags = 0; Fts5ExprTerm *p; for(p=&pOrig->aTerm[i]; p && rc==SQLITE_OK; p=p->pSynonym){ const char *zTerm = p->zTerm; rc = fts5ParseTokenize((void*)&sCtx, tflags, zTerm, (int)strlen(zTerm), 0, 0); tflags = FTS5_TOKEN_COLOCATED; } if( rc==SQLITE_OK ){ sCtx.pPhrase->aTerm[i].bPrefix = pOrig->aTerm[i].bPrefix; } } |
︙ | ︙ | |||
1829 1830 1831 1832 1833 1834 1835 | static char *fts5ExprTermPrint(Fts5ExprTerm *pTerm){ int nByte = 0; Fts5ExprTerm *p; char *zQuoted; /* Determine the maximum amount of space required. */ for(p=pTerm; p; p=p->pSynonym){ | | | 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 | static char *fts5ExprTermPrint(Fts5ExprTerm *pTerm){ int nByte = 0; Fts5ExprTerm *p; char *zQuoted; /* Determine the maximum amount of space required. */ for(p=pTerm; p; p=p->pSynonym){ nByte += (int)strlen(pTerm->zTerm) * 2 + 3 + 2; } zQuoted = sqlite3_malloc(nByte); if( zQuoted ){ int i = 0; for(p=pTerm; p; p=p->pSynonym){ char *zIn = p->zTerm; |
︙ | ︙ |
Changes to ext/fts5/fts5_hash.c.
︙ | ︙ | |||
166 167 168 169 170 171 172 | memset(apNew, 0, nNew*sizeof(Fts5HashEntry*)); for(i=0; i<pHash->nSlot; i++){ while( apOld[i] ){ int iHash; Fts5HashEntry *p = apOld[i]; apOld[i] = p->pHashNext; | | | 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 | memset(apNew, 0, nNew*sizeof(Fts5HashEntry*)); for(i=0; i<pHash->nSlot; i++){ while( apOld[i] ){ int iHash; Fts5HashEntry *p = apOld[i]; apOld[i] = p->pHashNext; iHash = fts5HashKey(nNew, (u8*)p->zKey, (int)strlen(p->zKey)); p->pHashNext = apNew[iHash]; apNew[iHash] = p; } } sqlite3_free(apOld); pHash->nSlot = nNew; |
︙ | ︙ | |||
454 455 456 457 458 459 460 | Fts5Hash *pHash, const char **pzTerm, /* OUT: term (nul-terminated) */ const u8 **ppDoclist, /* OUT: pointer to doclist */ int *pnDoclist /* OUT: size of doclist in bytes */ ){ Fts5HashEntry *p; if( (p = pHash->pScan) ){ | | | 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 | Fts5Hash *pHash, const char **pzTerm, /* OUT: term (nul-terminated) */ const u8 **ppDoclist, /* OUT: pointer to doclist */ int *pnDoclist /* OUT: size of doclist in bytes */ ){ Fts5HashEntry *p; if( (p = pHash->pScan) ){ int nTerm = (int)strlen(p->zKey); fts5HashAddPoslistSize(p); *pzTerm = p->zKey; *ppDoclist = (const u8*)&p->zKey[nTerm+1]; *pnDoclist = p->nData - (FTS5_HASHENTRYSIZE + nTerm + 1); }else{ *pzTerm = 0; *ppDoclist = 0; *pnDoclist = 0; } } |
Changes to ext/fts5/fts5_index.c.
︙ | ︙ | |||
1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 | } pIter->iLeafOffset = iOff; }else if( pIter->pSeg==0 ){ const u8 *pList = 0; const char *zTerm = 0; int nList = 0; if( 0==(pIter->flags & FTS5_SEGITER_ONETERM) ){ sqlite3Fts5HashScanNext(p->pHash); sqlite3Fts5HashScanEntry(p->pHash, &zTerm, &pList, &nList); } if( pList==0 ){ fts5DataRelease(pIter->pLeaf); pIter->pLeaf = 0; }else{ pIter->pLeaf->p = (u8*)pList; pIter->pLeaf->nn = nList; pIter->pLeaf->szLeaf = nList; pIter->iEndofDoclist = nList+1; | > | > | | 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 | } pIter->iLeafOffset = iOff; }else if( pIter->pSeg==0 ){ const u8 *pList = 0; const char *zTerm = 0; int nList = 0; assert( (pIter->flags & FTS5_SEGITER_ONETERM) || pbNewTerm ); if( 0==(pIter->flags & FTS5_SEGITER_ONETERM) ){ sqlite3Fts5HashScanNext(p->pHash); sqlite3Fts5HashScanEntry(p->pHash, &zTerm, &pList, &nList); } if( pList==0 ){ fts5DataRelease(pIter->pLeaf); pIter->pLeaf = 0; }else{ pIter->pLeaf->p = (u8*)pList; pIter->pLeaf->nn = nList; pIter->pLeaf->szLeaf = nList; pIter->iEndofDoclist = nList+1; sqlite3Fts5BufferSet(&p->rc, &pIter->term, (int)strlen(zTerm), (u8*)zTerm); pIter->iLeafOffset = fts5GetVarint(pList, (u64*)&pIter->iRowid); *pbNewTerm = 1; } }else{ iOff = 0; /* Next entry is not on the current page */ while( iOff==0 ){ fts5SegIterNextPage(p, pIter); pLeaf = pIter->pLeaf; |
︙ | ︙ | |||
2181 2182 2183 2184 2185 2186 2187 | assert( p->pHash ); assert( p->rc==SQLITE_OK ); if( pTerm==0 || (flags & FTS5INDEX_QUERY_SCAN) ){ p->rc = sqlite3Fts5HashScanInit(p->pHash, (const char*)pTerm, nTerm); sqlite3Fts5HashScanEntry(p->pHash, (const char**)&z, &pList, &nList); | | | 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 | assert( p->pHash ); assert( p->rc==SQLITE_OK ); if( pTerm==0 || (flags & FTS5INDEX_QUERY_SCAN) ){ p->rc = sqlite3Fts5HashScanInit(p->pHash, (const char*)pTerm, nTerm); sqlite3Fts5HashScanEntry(p->pHash, (const char**)&z, &pList, &nList); n = (z ? (int)strlen((const char*)z) : 0); }else{ pIter->flags |= FTS5_SEGITER_ONETERM; sqlite3Fts5HashQuery(p->pHash, (const char*)pTerm, nTerm, &pList, &nList); z = pTerm; n = nTerm; } |
︙ | ︙ | |||
3754 3755 3756 3757 3758 3759 3760 | while( p->rc==SQLITE_OK && 0==sqlite3Fts5HashScanEof(pHash) ){ const char *zTerm; /* Buffer containing term */ const u8 *pDoclist; /* Pointer to doclist for this term */ int nDoclist; /* Size of doclist in bytes */ /* Write the term for this entry to disk. */ sqlite3Fts5HashScanEntry(pHash, &zTerm, &pDoclist, &nDoclist); | | | 3756 3757 3758 3759 3760 3761 3762 3763 3764 3765 3766 3767 3768 3769 3770 | while( p->rc==SQLITE_OK && 0==sqlite3Fts5HashScanEof(pHash) ){ const char *zTerm; /* Buffer containing term */ const u8 *pDoclist; /* Pointer to doclist for this term */ int nDoclist; /* Size of doclist in bytes */ /* Write the term for this entry to disk. */ sqlite3Fts5HashScanEntry(pHash, &zTerm, &pDoclist, &nDoclist); fts5WriteAppendTerm(p, &writer, (int)strlen(zTerm), (const u8*)zTerm); assert( writer.bFirstRowidInPage==0 ); if( pgsz>=(pBuf->n + pPgidx->n + nDoclist + 1) ){ /* The entire doclist will fit on the current leaf. */ fts5BufferSafeAppendBlob(pBuf, pDoclist, nDoclist); }else{ i64 iRowid = 0; |
︙ | ︙ | |||
4030 4031 4032 4033 4034 4035 4036 | if( 0==fts5BufferGrow(&p->rc, pBuf, pSeg->nPos) ){ if( pColset==0 ){ fts5ChunkIterate(p, pSeg, (void*)pBuf, fts5PoslistCallback); }else{ PoslistCallbackCtx sCtx; sCtx.pBuf = pBuf; sCtx.pColset = pColset; | | | 4032 4033 4034 4035 4036 4037 4038 4039 4040 4041 4042 4043 4044 4045 4046 | if( 0==fts5BufferGrow(&p->rc, pBuf, pSeg->nPos) ){ if( pColset==0 ){ fts5ChunkIterate(p, pSeg, (void*)pBuf, fts5PoslistCallback); }else{ PoslistCallbackCtx sCtx; sCtx.pBuf = pBuf; sCtx.pColset = pColset; sCtx.eState = fts5IndexColsetTest(pColset, 0); assert( sCtx.eState==0 || sCtx.eState==1 ); fts5ChunkIterate(p, pSeg, (void*)&sCtx, fts5PoslistFilterCallback); } } } /* |
︙ | ︙ | |||
5191 5192 5193 5194 5195 5196 5197 | if( res<0 ) p->rc = FTS5_CORRUPT; } fts5IntegrityCheckPgidx(p, pLeaf); } fts5DataRelease(pLeaf); if( p->rc ) break; | < | 5193 5194 5195 5196 5197 5198 5199 5200 5201 5202 5203 5204 5205 5206 | if( res<0 ) p->rc = FTS5_CORRUPT; } fts5IntegrityCheckPgidx(p, pLeaf); } fts5DataRelease(pLeaf); if( p->rc ) break; /* Now check that the iter.nEmpty leaves following the current leaf ** (a) exist and (b) contain no terms. */ fts5IndexIntegrityCheckEmpty( p, pSeg, iIdxPrevLeaf+1, iDlidxPrevLeaf+1, iIdxLeaf-1 ); if( p->rc ) break; |
︙ | ︙ |
Changes to ext/fts5/fts5_main.c.
︙ | ︙ | |||
443 444 445 446 447 448 449 | /* ** Set the SQLITE_INDEX_SCAN_UNIQUE flag in pIdxInfo->flags. Unless this ** extension is currently being used by a version of SQLite too old to ** support index-info flags. In that case this function is a no-op. */ static void fts5SetUniqueFlag(sqlite3_index_info *pIdxInfo){ #if SQLITE_VERSION_NUMBER>=3008012 | > | > > | 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 | /* ** Set the SQLITE_INDEX_SCAN_UNIQUE flag in pIdxInfo->flags. Unless this ** extension is currently being used by a version of SQLite too old to ** support index-info flags. In that case this function is a no-op. */ static void fts5SetUniqueFlag(sqlite3_index_info *pIdxInfo){ #if SQLITE_VERSION_NUMBER>=3008012 #ifndef SQLITE_CORE if( sqlite3_libversion_number()>=3008012 ) #endif { pIdxInfo->idxFlags |= SQLITE_INDEX_SCAN_UNIQUE; } #endif } /* ** Implementation of the xBestIndex method for FTS5 tables. Within the |
︙ | ︙ |
Changes to ext/fts5/fts5_storage.c.
︙ | ︙ | |||
293 294 295 296 297 298 299 | char *zDefn = sqlite3_malloc(32 + pConfig->nCol * 10); if( zDefn==0 ){ rc = SQLITE_NOMEM; }else{ int i; int iOff; sqlite3_snprintf(nDefn, zDefn, "id INTEGER PRIMARY KEY"); | | | | 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 | char *zDefn = sqlite3_malloc(32 + pConfig->nCol * 10); if( zDefn==0 ){ rc = SQLITE_NOMEM; }else{ int i; int iOff; sqlite3_snprintf(nDefn, zDefn, "id INTEGER PRIMARY KEY"); iOff = (int)strlen(zDefn); for(i=0; i<pConfig->nCol; i++){ sqlite3_snprintf(nDefn-iOff, &zDefn[iOff], ", c%d", i); iOff += (int)strlen(&zDefn[iOff]); } rc = sqlite3Fts5CreateTable(pConfig, "content", zDefn, 0, pzErr); } sqlite3_free(zDefn); } if( rc==SQLITE_OK && pConfig->bColumnsize ){ |
︙ | ︙ | |||
721 722 723 724 725 726 727 | *piRowid = sqlite3_value_int64(apVal[1]); }else{ rc = fts5StorageNewRowid(p, piRowid); } }else{ sqlite3_stmt *pInsert = 0; /* Statement to write %_content table */ int i; /* Counter variable */ | < < < < < < < < < | < | 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 | *piRowid = sqlite3_value_int64(apVal[1]); }else{ rc = fts5StorageNewRowid(p, piRowid); } }else{ sqlite3_stmt *pInsert = 0; /* Statement to write %_content table */ int i; /* Counter variable */ rc = fts5StorageGetStmt(p, FTS5_STMT_INSERT_CONTENT, &pInsert, 0); for(i=1; rc==SQLITE_OK && i<=pConfig->nCol+1; i++){ rc = sqlite3_bind_value(pInsert, i, apVal[i]); } if( rc==SQLITE_OK ){ sqlite3_step(pInsert); rc = sqlite3_reset(pInsert); } |
︙ | ︙ |
Changes to ext/fts5/fts5_tokenize.c.
︙ | ︙ | |||
238 239 240 241 242 243 244 | static int fts5UnicodeAddExceptions( Unicode61Tokenizer *p, /* Tokenizer object */ const char *z, /* Characters to treat as exceptions */ int bTokenChars /* 1 for 'tokenchars', 0 for 'separators' */ ){ int rc = SQLITE_OK; | | | 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 | static int fts5UnicodeAddExceptions( Unicode61Tokenizer *p, /* Tokenizer object */ const char *z, /* Characters to treat as exceptions */ int bTokenChars /* 1 for 'tokenchars', 0 for 'separators' */ ){ int rc = SQLITE_OK; int n = (int)strlen(z); int *aNew; if( n>0 ){ aNew = (int*)sqlite3_realloc(p->aiException, (n+p->nException)*sizeof(int)); if( aNew ){ int nNew = p->nException; const unsigned char *zCsr = (const unsigned char*)z; |
︙ | ︙ |
Changes to ext/fts5/fts5_vocab.c.
︙ | ︙ | |||
164 165 166 167 168 169 170 | *pzErr = sqlite3_mprintf("wrong number of vtable arguments"); rc = SQLITE_ERROR; }else{ int nByte; /* Bytes of space to allocate */ const char *zDb = bDb ? argv[3] : argv[1]; const char *zTab = bDb ? argv[4] : argv[3]; const char *zType = bDb ? argv[5] : argv[4]; | | | | 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 | *pzErr = sqlite3_mprintf("wrong number of vtable arguments"); rc = SQLITE_ERROR; }else{ int nByte; /* Bytes of space to allocate */ const char *zDb = bDb ? argv[3] : argv[1]; const char *zTab = bDb ? argv[4] : argv[3]; const char *zType = bDb ? argv[5] : argv[4]; int nDb = (int)strlen(zDb)+1; int nTab = (int)strlen(zTab)+1; int eType; rc = fts5VocabTableType(zType, pzErr, &eType); if( rc==SQLITE_OK ){ assert( eType>=0 && eType<sizeof(azSchema)/sizeof(azSchema[0]) ); rc = sqlite3_declare_vtab(db, azSchema[eType]); } |
︙ | ︙ |
Changes to ext/fts5/test/fts5aa.test.
︙ | ︙ | |||
155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 | } do_execsql_test 6.3 { REPLACE INTO t1(rowid, x, y) VALUES('22', 'l l l', 'l l l'); } do_execsql_test 6.4 { INSERT INTO t1(t1) VALUES('integrity-check') } #------------------------------------------------------------------------- # reset_db expr srand(0) do_execsql_test 7.0 { CREATE VIRTUAL TABLE t1 USING fts5(x,y,z); | > > > > > > > > > > > | 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 | } do_execsql_test 6.3 { REPLACE INTO t1(rowid, x, y) VALUES('22', 'l l l', 'l l l'); } do_execsql_test 6.4 { REPLACE INTO t1(x, y) VALUES('x y z', 'x y z'); } do_execsql_test 6.5 { INSERT INTO t1(t1) VALUES('integrity-check') } do_execsql_test 6.6 { SELECT rowid, * FROM t1; } { 22 {l l l} {l l l} 23 {x y z} {x y z} } #------------------------------------------------------------------------- # reset_db expr srand(0) do_execsql_test 7.0 { CREATE VIRTUAL TABLE t1 USING fts5(x,y,z); |
︙ | ︙ |
Changes to ext/fts5/test/fts5corrupt3.test.
︙ | ︙ | |||
246 247 248 249 250 251 252 | } set {} {} } {} catch { db eval ROLLBACK } } } | < < | 246 247 248 249 250 251 252 253 254 255 256 257 258 259 | } set {} {} } {} catch { db eval ROLLBACK } } } #------------------------------------------------------------------------ # reset_db do_execsql_test 6.1.0 { CREATE VIRTUAL TABLE t1 USING fts5(a); INSERT INTO t1 VALUES('bbbbb ccccc'); SELECT quote(block) FROM t1_data WHERE rowid>100; |
︙ | ︙ | |||
331 332 333 334 335 336 337 338 339 340 | ----------^^----------------------------------------------------- WHERE id>100; } do_catchsql_test 6.3.5 { INSERT INTO t1(t1) VALUES('integrity-check'); } {1 {database disk image is malformed}} sqlite3_fts5_may_be_corrupt 0 finish_test | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 | ----------^^----------------------------------------------------- WHERE id>100; } do_catchsql_test 6.3.5 { INSERT INTO t1(t1) VALUES('integrity-check'); } {1 {database disk image is malformed}} } #------------------------------------------------------------------------ # reset_db reset_db proc rnddoc {n} { set map [list a b c d] set doc [list] for {set i 0} {$i < $n} {incr i} { lappend doc "x[lindex $map [expr int(rand()*4)]]" } set doc } db func rnddoc rnddoc do_test 7.0 { execsql { CREATE VIRTUAL TABLE t5 USING fts5(x); INSERT INTO t5 VALUES( rnddoc(10000) ); INSERT INTO t5 VALUES( rnddoc(10000) ); INSERT INTO t5 VALUES( rnddoc(10000) ); INSERT INTO t5 VALUES( rnddoc(10000) ); INSERT INTO t5(t5) VALUES('optimize'); } } {} do_test 7.1 { foreach i [db eval { SELECT rowid FROM t5_data WHERE rowid>100 }] { db eval BEGIN db eval {DELETE FROM t5_data WHERE rowid = $i} set r [catchsql { INSERT INTO t5(t5) VALUES('integrity-check')} ] if {$r != "1 {database disk image is malformed}"} { error $r } db eval ROLLBACK } } {} sqlite3_fts5_may_be_corrupt 0 finish_test |
Changes to ext/fts5/test/fts5fault7.test.
︙ | ︙ | |||
82 83 84 85 86 87 88 89 90 91 | INSERT INTO t2 VALUES('e a d a e d'); } } -body { db eval COMMIT } -test { faultsim_test_result {0 {}} } finish_test | > > > > > > > > > > > > > > > > > > > > > | 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 | INSERT INTO t2 VALUES('e a d a e d'); } } -body { db eval COMMIT } -test { faultsim_test_result {0 {}} } #------------------------------------------------------------------------- # Test fault-injection when a segment is promoted. # reset_db do_execsql_test 2.0 { CREATE VIRTUAL TABLE xy USING fts5(x); INSERT INTO xy(rowid, x) VALUES(1, '1 2 3'); INSERT INTO xy(rowid, x) VALUES(2, '2 3 4'); INSERT INTO xy(rowid, x) VALUES(3, '3 4 5'); } faultsim_save_and_close do_faultsim_test 2 -faults oom-* -prep { faultsim_restore_and_reopen } -body { db eval { UPDATE OR REPLACE xy SET rowid=3 WHERE rowid = 2 } } -test { faultsim_test_result {0 {}} } finish_test |
Changes to ext/fts5/test/fts5hash.test.
︙ | ︙ | |||
80 81 82 83 84 85 86 | set hash [sqlite3_fts5_token_hash 1024 xyz] set vocab [build_vocab1 -prefix xyz -hash $hash] lappend vocab xyz do_execsql_test 1.1 { CREATE VIRTUAL TABLE vocab USING fts5vocab(eee, 'row'); BEGIN; | < > > > | < | > | | 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 | set hash [sqlite3_fts5_token_hash 1024 xyz] set vocab [build_vocab1 -prefix xyz -hash $hash] lappend vocab xyz do_execsql_test 1.1 { CREATE VIRTUAL TABLE vocab USING fts5vocab(eee, 'row'); BEGIN; } do_test 1.2 { for {set i 1} {$i <= 100} {incr i} { execsql { INSERT INTO eee VALUES( r($vocab, 5), r($vocab, 7) ) } } } {} do_test 1.2 { db eval { SELECT term, doc FROM vocab } { set nRow [db one {SELECT count(*) FROM eee WHERE eee MATCH $term}] if {$nRow != $doc} { error "term=$term fts5vocab=$doc cnt=$nRow" } } |
︙ | ︙ |
Changes to ext/fts5/test/fts5prefix.test.
︙ | ︙ | |||
191 192 193 194 195 196 197 198 199 200 201 | } $res } } execsql { INSERT INTO t3(t3) VALUES('optimize') } execsql { INSERT INTO t3(t3) VALUES('integrity-check') } } finish_test | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 295 296 297 298 299 300 301 302 303 | } $res } } execsql { INSERT INTO t3(t3) VALUES('optimize') } execsql { INSERT INTO t3(t3) VALUES('integrity-check') } } #------------------------------------------------------------------------- # reset_db do_execsql_test 4.0 { CREATE VIRTUAL TABLE t2 USING fts5(c1, c2); INSERT INTO t2 VALUES('xa xb', 'xb xa'); INSERT INTO t2 SELECT c1||' '||c1, c2||' '||c2 FROM t2; -- 2 INSERT INTO t2 SELECT c1||' '||c1, c2||' '||c2 FROM t2; -- 4 INSERT INTO t2 SELECT c1||' '||c1, c2||' '||c2 FROM t2; -- 8 INSERT INTO t2 SELECT c1||' '||c1, c2||' '||c2 FROM t2; -- 16 INSERT INTO t2 SELECT c1||' '||c1, c2||' '||c2 FROM t2; -- 32 INSERT INTO t2 SELECT c1||' '||c1, c2||' '||c2 FROM t2; -- 64 INSERT INTO t2 SELECT c1||' '||c1, c2||' '||c2 FROM t2; -- 128 INSERT INTO t2 SELECT c1||' '||c1, c2||' '||c2 FROM t2; -- 256 INSERT INTO t2 SELECT c1||' '||c1, c2||' '||c2 FROM t2; -- 512 INSERT INTO t2 SELECT c1||' '||c1, c2||' '||c2 FROM t2; -- 1024 INSERT INTO t2 SELECT c1||' '||c1, c2||' '||c2 FROM t2; -- 2048 INSERT INTO t2 SELECT c1||' '||c1, c2||' '||c2 FROM t2; -- 4096 SELECT count(*) FROM t2('x*'); } {4096} do_execsql_test 4.1 { UPDATE t2 SET c2 = 'ya yb'; SELECT count(*) FROM t2('c1:x*'); SELECT count(*) FROM t2('c2:x*'); } {4096 0} do_execsql_test 4.2 { UPDATE t2 SET c2 = 'xa'; SELECT count(*) FROM t2('c1:x*'); SELECT count(*) FROM t2('c2:x*'); } {4096 4096} #------------------------------------------------------------------------- # reset_db proc rnddoc {n} { set map [list a b c d] set doc [list] for {set i 0} {$i < $n} {incr i} { lappend doc "x[lindex $map [expr int(rand()*4)]]" } set doc } set cols [list] for {set i 1} {$i<250} {incr i} { lappend cols "c$i" lappend vals "'[rnddoc 10]'" } do_test 5.0 { execsql "CREATE VIRTUAL TABLE t4 USING fts5([join $cols ,])" execsql {INSERT INTO t4(t4, rank) VALUES('pgsz', 32)} execsql "INSERT INTO t4 VALUES([join $vals ,])" execsql "INSERT INTO t4 VALUES([join $vals ,])" execsql "INSERT INTO t4 VALUES([join $vals ,])" execsql "INSERT INTO t4 VALUES([join $vals ,])" } {} proc gmatch {col pattern} { expr {[lsearch -glob $col $pattern]>=0} } db func gmatch gmatch foreach {tn col pattern} { 1 c100 {xa*} 2 c200 {xb*} } { set res [db eval "SELECT rowid FROM t4 WHERE gmatch($col, \$pattern)"] set query "$col : $pattern" do_execsql_test 5.$tn { SELECT rowid FROM t4($query) } $res } reset_db db func fts5_rnddoc fts5_rnddoc do_test 6.0 { execsql { CREATE VIRTUAL TABLE t5 USING fts5(x, y); INSERT INTO t5 VALUES( fts5_rnddoc(10000), fts5_rnddoc(10000) ); INSERT INTO t5 VALUES( fts5_rnddoc(10000), fts5_rnddoc(10000) ); INSERT INTO t5 VALUES( fts5_rnddoc(10000), fts5_rnddoc(10000) ); INSERT INTO t5 VALUES( fts5_rnddoc(10000), fts5_rnddoc(10000) ); } } {} proc gmatch {col pattern} { expr {[lsearch -glob $col $pattern]>=0} } db func gmatch gmatch foreach {tn col pattern} { 1 y {xa*} 2 y {xb*} 3 y {xc*} 4 x {xa*} 5 x {xb*} 6 x {xc*} } { set res [db eval "SELECT rowid FROM t5 WHERE gmatch($col, \$pattern)"] set query "$col : $pattern" do_execsql_test 6.$tn { SELECT rowid FROM t5($query) } $res } finish_test |
Changes to ext/fts5/test/fts5simple.test.
︙ | ︙ | |||
295 296 297 298 299 300 301 302 303 304 | } } {} do_execsql_test 12.2 { SELECT rowid FROM xx('x:a'); COMMIT; } {} finish_test | > > > > > > > > > > > > > > > > > > > > > > | 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 | } } {} do_execsql_test 12.2 { SELECT rowid FROM xx('x:a'); COMMIT; } {} #------------------------------------------------------------------------- # Try an UPDATE OR REPLACE query. # do_execsql_test 13.1 { CREATE VIRTUAL TABLE xy USING fts5(x); INSERT INTO xy(rowid, x) VALUES(1, '1 2 3'); INSERT INTO xy(rowid, x) VALUES(2, '2 3 4'); INSERT INTO xy(rowid, x) VALUES(3, '3 4 5'); } do_execsql_test 13.2 { UPDATE OR REPLACE xy SET rowid=3 WHERE rowid = 2; SELECT rowid, x FROM xy; } { 1 {1 2 3} 3 {2 3 4} } do_execsql_test 13.3 { INSERT INTO xy(xy) VALUES('integrity-check'); } finish_test |
Changes to ext/misc/json1.c.
︙ | ︙ | |||
24 25 26 27 28 29 30 | #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_JSON1) #if !defined(_SQLITEINT_H_) #include "sqlite3ext.h" #endif SQLITE_EXTENSION_INIT1 #include <assert.h> #include <string.h> | < > > > > > > > > | | > | | 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 | #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_JSON1) #if !defined(_SQLITEINT_H_) #include "sqlite3ext.h" #endif SQLITE_EXTENSION_INIT1 #include <assert.h> #include <string.h> #include <stdlib.h> #include <stdarg.h> #define UNUSED_PARAM(X) (void)(X) #ifndef LARGEST_INT64 # define LARGEST_INT64 (0xffffffff|(((sqlite3_int64)0x7fffffff)<<32)) # define SMALLEST_INT64 (((sqlite3_int64)-1) - LARGEST_INT64) #endif /* ** Versions of isspace(), isalnum() and isdigit() to which it is safe ** to pass signed char values. */ #ifdef sqlite3Isdigit /* Use the SQLite core versions if this routine is part of the ** SQLite amalgamation */ # define safe_isdigit(x) sqlite3Isdigit(x) # define safe_isalnum(x) sqlite3Isalnum(x) #else /* Use the standard library for separate compilation */ #include <ctype.h> /* amalgamator: keep */ # define safe_isdigit(x) isdigit((unsigned char)(x)) # define safe_isalnum(x) isalnum((unsigned char)(x)) #endif /* ** Growing our own isspace() routine this way is twice as fast as ** the library isspace() function, resulting in a 7% overall performance ** increase for the parser. (Ubuntu14.10 gcc 4.8.4 x64 with -Os). */ static const char jsonIsSpace[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
︙ | ︙ | |||
510 511 512 513 514 515 516 | if( pNode->u.zJContent[0]=='-' ){ i = -i; } sqlite3_result_int64(pCtx, i); int_done: break; int_as_real: /* fall through to real */; } case JSON_REAL: { | > > > > > | > | 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 | if( pNode->u.zJContent[0]=='-' ){ i = -i; } sqlite3_result_int64(pCtx, i); int_done: break; int_as_real: /* fall through to real */; } case JSON_REAL: { double r; #ifdef SQLITE_AMALGAMATION const char *z = pNode->u.zJContent; sqlite3AtoF(z, &r, sqlite3Strlen30(z), SQLITE_UTF8); #else r = strtod(pNode->u.zJContent, 0); #endif sqlite3_result_double(pCtx, r); break; } case JSON_STRING: { #if 0 /* Never happens because JNODE_RAW is only set by json_set(), ** json_insert() and json_replace() and those routines do not ** call jsonReturn() */ |
︙ | ︙ |
Changes to src/expr.c.
︙ | ︙ | |||
2477 2478 2479 2480 2481 2482 2483 | if( iCol>=0 ){ sqlite3ColumnDefault(v, pTab, iCol, regOut); } } /* ** Generate code that will extract the iColumn-th column from | | > | | > > | | 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 | if( iCol>=0 ){ sqlite3ColumnDefault(v, pTab, iCol, regOut); } } /* ** Generate code that will extract the iColumn-th column from ** table pTab and store the column value in a register. ** ** An effort is made to store the column value in register iReg. This ** is not garanteeed for GetColumn() - the result can be stored in ** any register. But the result is guaranteed to land in register iReg ** for GetColumnToReg(). ** ** There must be an open cursor to pTab in iTable when this routine ** is called. If iColumn<0 then code is generated that extracts the rowid. */ int sqlite3ExprCodeGetColumn( Parse *pParse, /* Parsing and code generating context */ Table *pTab, /* Description of the table we are reading from */ int iColumn, /* Index of the table column */ int iTable, /* The cursor pointing to the table */ int iReg, /* Store results here */ u8 p5 /* P5 value for OP_Column + FLAGS */ ){ Vdbe *v = pParse->pVdbe; int i; struct yColCache *p; for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){ if( p->iReg>0 && p->iTable==iTable && p->iColumn==iColumn ){ |
︙ | ︙ | |||
2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 | if( p5 ){ sqlite3VdbeChangeP5(v, p5); }else{ sqlite3ExprCacheStore(pParse, iTable, iColumn, iReg); } return iReg; } /* ** Clear all column cache entries. */ void sqlite3ExprCacheClear(Parse *pParse){ int i; struct yColCache *p; | > > > > > > > > > > > | 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 | if( p5 ){ sqlite3VdbeChangeP5(v, p5); }else{ sqlite3ExprCacheStore(pParse, iTable, iColumn, iReg); } return iReg; } void sqlite3ExprCodeGetColumnToReg( Parse *pParse, /* Parsing and code generating context */ Table *pTab, /* Description of the table we are reading from */ int iColumn, /* Index of the table column */ int iTable, /* The cursor pointing to the table */ int iReg /* Store results here */ ){ int r1 = sqlite3ExprCodeGetColumn(pParse, pTab, iColumn, iTable, iReg, 0); if( r1!=iReg ) sqlite3VdbeAddOp2(pParse->pVdbe, OP_SCopy, r1, iReg); } /* ** Clear all column cache entries. */ void sqlite3ExprCacheClear(Parse *pParse){ int i; struct yColCache *p; |
︙ | ︙ |
Changes to src/insert.c.
︙ | ︙ | |||
1418 1419 1420 1421 1422 1423 1424 | if( iField==XN_ROWID || iField==pTab->iPKey ){ if( regRowid==regIdx+i ) continue; /* ROWID already in regIdx+i */ x = regNewData; regRowid = pIdx->pPartIdxWhere ? -1 : regIdx+i; }else{ x = iField + regNewData + 1; } | | | 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 | if( iField==XN_ROWID || iField==pTab->iPKey ){ if( regRowid==regIdx+i ) continue; /* ROWID already in regIdx+i */ x = regNewData; regRowid = pIdx->pPartIdxWhere ? -1 : regIdx+i; }else{ x = iField + regNewData + 1; } sqlite3VdbeAddOp2(v, iField<0 ? OP_IntCopy : OP_SCopy, x, regIdx+i); VdbeComment((v, "%s", iField<0 ? "rowid" : pTab->aCol[iField].zName)); } } sqlite3VdbeAddOp3(v, OP_MakeRecord, regIdx, pIdx->nColumn, aRegIdx[ix]); VdbeComment((v, "for %s", pIdx->zName)); sqlite3ExprCacheAffinityChange(pParse, regIdx, pIdx->nColumn); |
︙ | ︙ |
Changes to src/loadext.c.
︙ | ︙ | |||
611 612 613 614 615 616 617 | /* ** The auto-extension code added regardless of whether or not extension ** loading is supported. We need a dummy sqlite3Apis pointer for that ** code if regular extension loading is not available. This is that ** dummy pointer. */ #ifdef SQLITE_OMIT_LOAD_EXTENSION | | | 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 | /* ** The auto-extension code added regardless of whether or not extension ** loading is supported. We need a dummy sqlite3Apis pointer for that ** code if regular extension loading is not available. This is that ** dummy pointer. */ #ifdef SQLITE_OMIT_LOAD_EXTENSION static const sqlite3_api_routines sqlite3Apis = { 0 }; #endif /* ** The following object holds the list of automatically loaded ** extensions. ** |
︙ | ︙ |
Changes to src/malloc.c.
︙ | ︙ | |||
127 128 129 130 131 132 133 | */ int sqlite3MallocInit(void){ int rc; if( sqlite3GlobalConfig.m.xMalloc==0 ){ sqlite3MemSetDefault(); } memset(&mem0, 0, sizeof(mem0)); | < | < | 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 | */ int sqlite3MallocInit(void){ int rc; if( sqlite3GlobalConfig.m.xMalloc==0 ){ sqlite3MemSetDefault(); } memset(&mem0, 0, sizeof(mem0)); mem0.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM); if( sqlite3GlobalConfig.pScratch && sqlite3GlobalConfig.szScratch>=100 && sqlite3GlobalConfig.nScratch>0 ){ int i, n, sz; ScratchFreeslot *pSlot; sz = ROUNDDOWN8(sqlite3GlobalConfig.szScratch); sqlite3GlobalConfig.szScratch = sz; pSlot = (ScratchFreeslot*)sqlite3GlobalConfig.pScratch; |
︙ | ︙ | |||
220 221 222 223 224 225 226 | ** lock is already held. */ static int mallocWithAlarm(int n, void **pp){ int nFull; void *p; assert( sqlite3_mutex_held(mem0.mutex) ); nFull = sqlite3GlobalConfig.m.xRoundup(n); | | | 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 | ** lock is already held. */ static int mallocWithAlarm(int n, void **pp){ int nFull; void *p; assert( sqlite3_mutex_held(mem0.mutex) ); nFull = sqlite3GlobalConfig.m.xRoundup(n); sqlite3StatusHighwater(SQLITE_STATUS_MALLOC_SIZE, n); if( mem0.alarmThreshold>0 ){ sqlite3_int64 nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED); if( nUsed >= mem0.alarmThreshold - nFull ){ mem0.nearlyFull = 1; sqlite3MallocAlarm(nFull); }else{ mem0.nearlyFull = 0; |
︙ | ︙ | |||
312 313 314 315 316 317 318 | ** embedded processor. */ void *sqlite3ScratchMalloc(int n){ void *p; assert( n>0 ); sqlite3_mutex_enter(mem0.mutex); | | | 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 | ** embedded processor. */ void *sqlite3ScratchMalloc(int n){ void *p; assert( n>0 ); sqlite3_mutex_enter(mem0.mutex); sqlite3StatusHighwater(SQLITE_STATUS_SCRATCH_SIZE, n); if( mem0.nScratchFree && sqlite3GlobalConfig.szScratch>=n ){ p = mem0.pScratchFree; mem0.pScratchFree = mem0.pScratchFree->pNext; mem0.nScratchFree--; sqlite3StatusUp(SQLITE_STATUS_SCRATCH_USED, 1); sqlite3_mutex_leave(mem0.mutex); }else{ |
︙ | ︙ | |||
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 | ** sqlite3Malloc() or sqlite3_malloc(). */ int sqlite3MallocSize(void *p){ assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) ); return sqlite3GlobalConfig.m.xSize(p); } int sqlite3DbMallocSize(sqlite3 *db, void *p){ if( db==0 || !isLookaside(db,p) ){ #if SQLITE_DEBUG if( db==0 ){ assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_HEAP) ); assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) ); }else{ assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); assert( sqlite3MemdebugNoType(p, (u8)~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); } #endif return sqlite3GlobalConfig.m.xSize(p); }else{ assert( sqlite3_mutex_held(db->mutex) ); return db->lookaside.sz; } } sqlite3_uint64 sqlite3_msize(void *p){ assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_HEAP) ); assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) ); | > | | 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 | ** sqlite3Malloc() or sqlite3_malloc(). */ int sqlite3MallocSize(void *p){ assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) ); return sqlite3GlobalConfig.m.xSize(p); } int sqlite3DbMallocSize(sqlite3 *db, void *p){ assert( p!=0 ); if( db==0 || !isLookaside(db,p) ){ #if SQLITE_DEBUG if( db==0 ){ assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_HEAP) ); assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) ); }else{ assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); assert( sqlite3MemdebugNoType(p, (u8)~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); } #endif return sqlite3GlobalConfig.m.xSize(p); }else{ assert( sqlite3_mutex_held(db->mutex) ); return db->lookaside.sz; } } sqlite3_uint64 sqlite3_msize(void *p){ assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_HEAP) ); assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) ); return p ? sqlite3GlobalConfig.m.xSize(p) : 0; } /* ** Free memory previously obtained from sqlite3Malloc(). */ void sqlite3_free(void *p){ if( p==0 ) return; /* IMP: R-49053-54554 */ |
︙ | ︙ | |||
452 453 454 455 456 457 458 | } /* ** Add the size of memory allocation "p" to the count in ** *db->pnBytesFreed. */ static SQLITE_NOINLINE void measureAllocationSize(sqlite3 *db, void *p){ | | | 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 | } /* ** Add the size of memory allocation "p" to the count in ** *db->pnBytesFreed. */ static SQLITE_NOINLINE void measureAllocationSize(sqlite3 *db, void *p){ if( p ) *db->pnBytesFreed += sqlite3DbMallocSize(db,p); } /* ** Free memory that might be associated with a particular database ** connection. */ void sqlite3DbFree(sqlite3 *db, void *p){ |
︙ | ︙ | |||
514 515 516 517 518 519 520 | ** argument to xRealloc is always a value returned by a prior call to ** xRoundup. */ nNew = sqlite3GlobalConfig.m.xRoundup((int)nBytes); if( nOld==nNew ){ pNew = pOld; }else if( sqlite3GlobalConfig.bMemstat ){ sqlite3_mutex_enter(mem0.mutex); | | | 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 | ** argument to xRealloc is always a value returned by a prior call to ** xRoundup. */ nNew = sqlite3GlobalConfig.m.xRoundup((int)nBytes); if( nOld==nNew ){ pNew = pOld; }else if( sqlite3GlobalConfig.bMemstat ){ sqlite3_mutex_enter(mem0.mutex); sqlite3StatusHighwater(SQLITE_STATUS_MALLOC_SIZE, (int)nBytes); nDiff = nNew - nOld; if( sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED) >= mem0.alarmThreshold-nDiff ){ sqlite3MallocAlarm(nDiff); } pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew); if( pNew==0 && mem0.alarmThreshold>0 ){ |
︙ | ︙ |
Changes to src/mem1.c.
︙ | ︙ | |||
167 168 169 170 171 172 173 174 | } /* ** Report the allocated size of a prior return from xMalloc() ** or xRealloc(). */ static int sqlite3MemSize(void *pPrior){ #ifdef SQLITE_MALLOCSIZE | > | < | 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 | } /* ** Report the allocated size of a prior return from xMalloc() ** or xRealloc(). */ static int sqlite3MemSize(void *pPrior){ assert( pPrior!=0 ); #ifdef SQLITE_MALLOCSIZE return (int)SQLITE_MALLOCSIZE(pPrior); #else sqlite3_int64 *p; p = (sqlite3_int64*)pPrior; p--; return (int)p[0]; #endif } /* |
︙ | ︙ |
Changes to src/mem3.c.
︙ | ︙ | |||
472 473 474 475 476 477 478 | /* ** Return the size of an outstanding allocation, in bytes. The ** size returned omits the 8-byte header overhead. This only ** works for chunks that are currently checked out. */ static int memsys3Size(void *p){ Mem3Block *pBlock; | | | 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 | /* ** Return the size of an outstanding allocation, in bytes. The ** size returned omits the 8-byte header overhead. This only ** works for chunks that are currently checked out. */ static int memsys3Size(void *p){ Mem3Block *pBlock; assert( p!=0 ); pBlock = (Mem3Block*)p; assert( (pBlock[-1].u.hdr.size4x&1)!=0 ); return (pBlock[-1].u.hdr.size4x&~3)*2 - 4; } /* ** Round up a request size to the next valid allocation size. |
︙ | ︙ |
Changes to src/mem5.c.
︙ | ︙ | |||
196 197 198 199 200 201 202 | /* ** Return the size of an outstanding allocation, in bytes. The ** size returned omits the 8-byte header overhead. This only ** works for chunks that are currently checked out. */ static int memsys5Size(void *p){ | | | | | | < | 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 | /* ** Return the size of an outstanding allocation, in bytes. The ** size returned omits the 8-byte header overhead. This only ** works for chunks that are currently checked out. */ static int memsys5Size(void *p){ int iSize, i; assert( p!=0 ); i = (int)(((u8 *)p-mem5.zPool)/mem5.szAtom); assert( i>=0 && i<mem5.nBlock ); iSize = mem5.szAtom * (1 << (mem5.aCtrl[i]&CTRL_LOGSIZE)); return iSize; } /* ** Return a block of memory of at least nBytes in size. ** Return NULL if unable. Return NULL if nBytes==0. ** |
︙ | ︙ |
Changes to src/pcache1.c.
︙ | ︙ | |||
316 317 318 319 320 321 322 | sqlite3_mutex_enter(pcache1.mutex); p = (PgHdr1 *)pcache1.pFree; if( p ){ pcache1.pFree = pcache1.pFree->pNext; pcache1.nFreeSlot--; pcache1.bUnderPressure = pcache1.nFreeSlot<pcache1.nReserve; assert( pcache1.nFreeSlot>=0 ); | | | | 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 | sqlite3_mutex_enter(pcache1.mutex); p = (PgHdr1 *)pcache1.pFree; if( p ){ pcache1.pFree = pcache1.pFree->pNext; pcache1.nFreeSlot--; pcache1.bUnderPressure = pcache1.nFreeSlot<pcache1.nReserve; assert( pcache1.nFreeSlot>=0 ); sqlite3StatusHighwater(SQLITE_STATUS_PAGECACHE_SIZE, nByte); sqlite3StatusUp(SQLITE_STATUS_PAGECACHE_USED, 1); } sqlite3_mutex_leave(pcache1.mutex); } if( p==0 ){ /* Memory is not available in the SQLITE_CONFIG_PAGECACHE pool. Get ** it from sqlite3Malloc instead. */ p = sqlite3Malloc(nByte); #ifndef SQLITE_DISABLE_PAGECACHE_OVERFLOW_STATS if( p ){ int sz = sqlite3MallocSize(p); sqlite3_mutex_enter(pcache1.mutex); sqlite3StatusHighwater(SQLITE_STATUS_PAGECACHE_SIZE, nByte); sqlite3StatusUp(SQLITE_STATUS_PAGECACHE_OVERFLOW, sz); sqlite3_mutex_leave(pcache1.mutex); } #endif sqlite3MemdebugSetType(p, MEMTYPE_PCACHE); } return p; |
︙ | ︙ |
Changes to src/select.c.
︙ | ︙ | |||
5291 5292 5293 5294 5295 5296 5297 | sqlite3ExprCacheClear(pParse); sqlite3ExprCodeExprList(pParse, pGroupBy, regBase, 0, 0); j = nGroupBy; for(i=0; i<sAggInfo.nColumn; i++){ struct AggInfo_col *pCol = &sAggInfo.aCol[i]; if( pCol->iSorterColumn>=j ){ int r1 = j + regBase; | < < | | < < < | 5291 5292 5293 5294 5295 5296 5297 5298 5299 5300 5301 5302 5303 5304 5305 5306 | sqlite3ExprCacheClear(pParse); sqlite3ExprCodeExprList(pParse, pGroupBy, regBase, 0, 0); j = nGroupBy; for(i=0; i<sAggInfo.nColumn; i++){ struct AggInfo_col *pCol = &sAggInfo.aCol[i]; if( pCol->iSorterColumn>=j ){ int r1 = j + regBase; sqlite3ExprCodeGetColumnToReg(pParse, pCol->pTab, pCol->iColumn, pCol->iTable, r1); j++; } } regRecord = sqlite3GetTempReg(pParse); sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nCol, regRecord); sqlite3VdbeAddOp2(v, OP_SorterInsert, sAggInfo.sortingIdx, regRecord); sqlite3ReleaseTempReg(pParse, regRecord); |
︙ | ︙ |
Changes to src/sqlite.h.in.
︙ | ︙ | |||
6568 6569 6570 6571 6572 6573 6574 | ** [[SQLITE_STATUS_SCRATCH_SIZE]] ^(<dt>SQLITE_STATUS_SCRATCH_SIZE</dt> ** <dd>This parameter records the largest memory allocation request ** handed to [scratch memory allocator]. Only the value returned in the ** *pHighwater parameter to [sqlite3_status()] is of interest. ** The value written into the *pCurrent parameter is undefined.</dd>)^ ** ** [[SQLITE_STATUS_PARSER_STACK]] ^(<dt>SQLITE_STATUS_PARSER_STACK</dt> | | > | 6568 6569 6570 6571 6572 6573 6574 6575 6576 6577 6578 6579 6580 6581 6582 6583 | ** [[SQLITE_STATUS_SCRATCH_SIZE]] ^(<dt>SQLITE_STATUS_SCRATCH_SIZE</dt> ** <dd>This parameter records the largest memory allocation request ** handed to [scratch memory allocator]. Only the value returned in the ** *pHighwater parameter to [sqlite3_status()] is of interest. ** The value written into the *pCurrent parameter is undefined.</dd>)^ ** ** [[SQLITE_STATUS_PARSER_STACK]] ^(<dt>SQLITE_STATUS_PARSER_STACK</dt> ** <dd>The *pHighwater parameter records the deepest parser stack. ** The *pCurrent value is undefined. The *pHighwater value is only ** meaningful if SQLite is compiled with [YYTRACKMAXSTACKDEPTH].</dd>)^ ** </dl> ** ** New status parameters may be added from time to time. */ #define SQLITE_STATUS_MEMORY_USED 0 #define SQLITE_STATUS_PAGECACHE_USED 1 |
︙ | ︙ |
Changes to src/sqliteInt.h.
︙ | ︙ | |||
3206 3207 3208 3209 3210 3211 3212 | #else # define sqlite3MemoryBarrier() #endif sqlite3_int64 sqlite3StatusValue(int); void sqlite3StatusUp(int, int); void sqlite3StatusDown(int, int); | | | 3206 3207 3208 3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 | #else # define sqlite3MemoryBarrier() #endif sqlite3_int64 sqlite3StatusValue(int); void sqlite3StatusUp(int, int); void sqlite3StatusDown(int, int); void sqlite3StatusHighwater(int, int); /* Access to mutexes used by sqlite3_status() */ sqlite3_mutex *sqlite3Pcache1Mutex(void); sqlite3_mutex *sqlite3MallocMutex(void); #ifndef SQLITE_OMIT_FLOATING_POINT int sqlite3IsNaN(double); |
︙ | ︙ | |||
3390 3391 3392 3393 3394 3395 3396 3397 3398 3399 3400 3401 3402 3403 | int sqlite3WhereBreakLabel(WhereInfo*); int sqlite3WhereOkOnePass(WhereInfo*, int*); #define ONEPASS_OFF 0 /* Use of ONEPASS not allowed */ #define ONEPASS_SINGLE 1 /* ONEPASS valid for a single row update */ #define ONEPASS_MULTI 2 /* ONEPASS is valid for multiple rows */ void sqlite3ExprCodeLoadIndexColumn(Parse*, Index*, int, int, int); int sqlite3ExprCodeGetColumn(Parse*, Table*, int, int, int, u8); void sqlite3ExprCodeGetColumnOfTable(Vdbe*, Table*, int, int, int); void sqlite3ExprCodeMove(Parse*, int, int, int); void sqlite3ExprCacheStore(Parse*, int, int, int); void sqlite3ExprCachePush(Parse*); void sqlite3ExprCachePop(Parse*); void sqlite3ExprCacheRemove(Parse*, int, int); void sqlite3ExprCacheClear(Parse*); | > | 3390 3391 3392 3393 3394 3395 3396 3397 3398 3399 3400 3401 3402 3403 3404 | int sqlite3WhereBreakLabel(WhereInfo*); int sqlite3WhereOkOnePass(WhereInfo*, int*); #define ONEPASS_OFF 0 /* Use of ONEPASS not allowed */ #define ONEPASS_SINGLE 1 /* ONEPASS valid for a single row update */ #define ONEPASS_MULTI 2 /* ONEPASS is valid for multiple rows */ void sqlite3ExprCodeLoadIndexColumn(Parse*, Index*, int, int, int); int sqlite3ExprCodeGetColumn(Parse*, Table*, int, int, int, u8); void sqlite3ExprCodeGetColumnToReg(Parse*, Table*, int, int, int); void sqlite3ExprCodeGetColumnOfTable(Vdbe*, Table*, int, int, int); void sqlite3ExprCodeMove(Parse*, int, int, int); void sqlite3ExprCacheStore(Parse*, int, int, int); void sqlite3ExprCachePush(Parse*); void sqlite3ExprCachePop(Parse*); void sqlite3ExprCacheRemove(Parse*, int, int); void sqlite3ExprCacheClear(Parse*); |
︙ | ︙ |
Changes to src/status.c.
︙ | ︙ | |||
104 105 106 107 108 109 110 | assert( sqlite3_mutex_held(statMutex[op] ? sqlite3Pcache1Mutex() : sqlite3MallocMutex()) ); assert( op>=0 && op<ArraySize(wsdStat.nowValue) ); wsdStat.nowValue[op] -= N; } /* | | | | | > > > | | | 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 | assert( sqlite3_mutex_held(statMutex[op] ? sqlite3Pcache1Mutex() : sqlite3MallocMutex()) ); assert( op>=0 && op<ArraySize(wsdStat.nowValue) ); wsdStat.nowValue[op] -= N; } /* ** Adjust the highwater mark if necessary. ** The caller must hold the appropriate mutex. */ void sqlite3StatusHighwater(int op, int X){ wsdStatInit; assert( op>=0 && op<ArraySize(wsdStat.nowValue) ); assert( op>=0 && op<ArraySize(statMutex) ); assert( sqlite3_mutex_held(statMutex[op] ? sqlite3Pcache1Mutex() : sqlite3MallocMutex()) ); assert( op==SQLITE_STATUS_MALLOC_SIZE || op==SQLITE_STATUS_PAGECACHE_SIZE || op==SQLITE_STATUS_SCRATCH_SIZE || op==SQLITE_STATUS_PARSER_STACK ); if( X>wsdStat.mxValue[op] ){ wsdStat.mxValue[op] = X; } } /* ** Query status information. */ int sqlite3_status64( |
︙ | ︙ | |||
248 249 250 251 252 253 254 | nByte += sqlite3GlobalConfig.m.xRoundup(sizeof(HashElem)) * ( pSchema->tblHash.count + pSchema->trigHash.count + pSchema->idxHash.count + pSchema->fkeyHash.count ); | | | | | | 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 | nByte += sqlite3GlobalConfig.m.xRoundup(sizeof(HashElem)) * ( pSchema->tblHash.count + pSchema->trigHash.count + pSchema->idxHash.count + pSchema->fkeyHash.count ); nByte += sqlite3_msize(pSchema->tblHash.ht); nByte += sqlite3_msize(pSchema->trigHash.ht); nByte += sqlite3_msize(pSchema->idxHash.ht); nByte += sqlite3_msize(pSchema->fkeyHash.ht); for(p=sqliteHashFirst(&pSchema->trigHash); p; p=sqliteHashNext(p)){ sqlite3DeleteTrigger(db, (Trigger*)sqliteHashData(p)); } for(p=sqliteHashFirst(&pSchema->tblHash); p; p=sqliteHashNext(p)){ sqlite3DeleteTable(db, (Table *)sqliteHashData(p)); } |
︙ | ︙ |
Changes to src/tokenize.c.
︙ | ︙ | |||
463 464 465 466 467 468 469 | } if( pParse->rc==SQLITE_OK && db->mallocFailed==0 ){ sqlite3Parser(pEngine, 0, pParse->sLastToken, pParse); } } #ifdef YYTRACKMAXSTACKDEPTH sqlite3_mutex_enter(sqlite3MallocMutex()); | | | 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 | } if( pParse->rc==SQLITE_OK && db->mallocFailed==0 ){ sqlite3Parser(pEngine, 0, pParse->sLastToken, pParse); } } #ifdef YYTRACKMAXSTACKDEPTH sqlite3_mutex_enter(sqlite3MallocMutex()); sqlite3StatusHighwater(SQLITE_STATUS_PARSER_STACK, sqlite3ParserStackPeak(pEngine) ); sqlite3_mutex_leave(sqlite3MallocMutex()); #endif /* YYDEBUG */ sqlite3ParserFree(pEngine, sqlite3_free); db->lookaside.bEnabled = enableLookaside; if( db->mallocFailed ){ |
︙ | ︙ |
Changes to src/update.c.
︙ | ︙ | |||
518 519 520 521 522 523 524 | /* This branch loads the value of a column that will not be changed ** into a register. This is done if there are no BEFORE triggers, or ** if there are one or more BEFORE triggers that use this value via ** a new.* reference in a trigger program. */ testcase( i==31 ); testcase( i==32 ); | | | 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 | /* This branch loads the value of a column that will not be changed ** into a register. This is done if there are no BEFORE triggers, or ** if there are one or more BEFORE triggers that use this value via ** a new.* reference in a trigger program. */ testcase( i==31 ); testcase( i==32 ); sqlite3ExprCodeGetColumnToReg(pParse, pTab, i, iDataCur, regNew+i); }else{ sqlite3VdbeAddOp2(v, OP_Null, 0, regNew+i); } } } /* Fire any BEFORE UPDATE triggers. This happens before constraints are |
︙ | ︙ |
Changes to src/vdbe.c.
︙ | ︙ | |||
514 515 516 517 518 519 520 | return 1; } #endif /* ** Return the register of pOp->p2 after first preparing it to be ** overwritten with an integer value. | | > > > > > | > > | | > | 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 | return 1; } #endif /* ** Return the register of pOp->p2 after first preparing it to be ** overwritten with an integer value. */ static SQLITE_NOINLINE Mem *out2PrereleaseWithClear(Mem *pOut){ sqlite3VdbeMemSetNull(pOut); pOut->flags = MEM_Int; return pOut; } static Mem *out2Prerelease(Vdbe *p, VdbeOp *pOp){ Mem *pOut; assert( pOp->p2>0 ); assert( pOp->p2<=(p->nMem-p->nCursor) ); pOut = &p->aMem[pOp->p2]; memAboutToChange(p, pOut); if( VdbeMemDynamic(pOut) ){ return out2PrereleaseWithClear(pOut); }else{ pOut->flags = MEM_Int; return pOut; } } /* ** Execute as much of a VDBE program as we can. ** This is the core of sqlite3_step(). */ |
︙ | ︙ | |||
1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 | assert( pOut!=pIn1 ); sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem); #ifdef SQLITE_DEBUG if( pOut->pScopyFrom==0 ) pOut->pScopyFrom = pIn1; #endif break; } /* Opcode: ResultRow P1 P2 * * * ** Synopsis: output=r[P1@P2] ** ** The registers P1 through P1+P2-1 contain a single row of ** results. This opcode causes the sqlite3_step() call to terminate ** with an SQLITE_ROW return code and it sets up the sqlite3_stmt | > > > > > > > > > > > > > > > > | 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 | assert( pOut!=pIn1 ); sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem); #ifdef SQLITE_DEBUG if( pOut->pScopyFrom==0 ) pOut->pScopyFrom = pIn1; #endif break; } /* Opcode: IntCopy P1 P2 * * * ** Synopsis: r[P2]=r[P1] ** ** Transfer the integer value held in register P1 into register P2. ** ** This is an optimized version of SCopy that works only for integer ** values. */ case OP_IntCopy: { /* out2 */ pIn1 = &aMem[pOp->p1]; assert( (pIn1->flags & MEM_Int)!=0 ); pOut = &aMem[pOp->p2]; sqlite3VdbeMemSetInt64(pOut, pIn1->u.i); break; } /* Opcode: ResultRow P1 P2 * * * ** Synopsis: output=r[P1@P2] ** ** The registers P1 through P1+P2-1 contain a single row of ** results. This opcode causes the sqlite3_step() call to terminate ** with an SQLITE_ROW return code and it sets up the sqlite3_stmt |
︙ | ︙ | |||
2340 2341 2342 2343 2344 2345 2346 | int i; /* Loop counter */ Mem *pDest; /* Where to write the extracted value */ Mem sMem; /* For storing the record being decoded */ const u8 *zData; /* Part of the record being decoded */ const u8 *zHdr; /* Next unparsed byte of the header */ const u8 *zEndHdr; /* Pointer to first byte after the header */ u32 offset; /* Offset into the data */ | | | 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 | int i; /* Loop counter */ Mem *pDest; /* Where to write the extracted value */ Mem sMem; /* For storing the record being decoded */ const u8 *zData; /* Part of the record being decoded */ const u8 *zHdr; /* Next unparsed byte of the header */ const u8 *zEndHdr; /* Pointer to first byte after the header */ u32 offset; /* Offset into the data */ u64 offset64; /* 64-bit offset */ u32 avail; /* Number of bytes of available data */ u32 t; /* A type code from the record header */ u16 fx; /* pDest->flags value */ Mem *pReg; /* PseudoTable input register */ p2 = pOp->p2; assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) ); |
︙ | ︙ | |||
2411 2412 2413 2414 2415 2416 2417 | } } pC->cacheStatus = p->cacheCtr; pC->iHdrOffset = getVarint32(pC->aRow, offset); pC->nHdrParsed = 0; aOffset[0] = offset; | < < < < < < < < < < < < < > > > > > > > > > > > > > > | 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 | } } pC->cacheStatus = p->cacheCtr; pC->iHdrOffset = getVarint32(pC->aRow, offset); pC->nHdrParsed = 0; aOffset[0] = offset; if( avail<offset ){ /* pC->aRow does not have to hold the entire row, but it does at least ** need to cover the header of the record. If pC->aRow does not contain ** the complete header, then set it to zero, forcing the header to be ** dynamically allocated. */ pC->aRow = 0; pC->szRow = 0; /* Make sure a corrupt database has not given us an oversize header. ** Do this now to avoid an oversize memory allocation. ** ** Type entries can be between 1 and 5 bytes each. But 4 and 5 byte ** types use so much data space that there can only be 4096 and 32 of ** them, respectively. So the maximum header length results from a ** 3-byte type for each of the maximum of 32768 columns plus three ** extra bytes for the header length itself. 32768*3 + 3 = 98307. */ if( offset > 98307 || offset > pC->payloadSize ){ rc = SQLITE_CORRUPT_BKPT; goto op_column_error; } } /* The following goto is an optimization. It can be omitted and ** everything will still work. But OP_Column is measurably faster ** by skipping the subsequent conditional, which is always true. */ assert( pC->nHdrParsed<=p2 ); /* Conditional skipped */ |
︙ | ︙ | |||
2454 2455 2456 2457 2458 2459 2460 | ** to extract additional fields up through the p2+1-th field */ op_column_read_header: if( pC->iHdrOffset<aOffset[0] ){ /* Make sure zData points to enough of the record to cover the header. */ if( pC->aRow==0 ){ memset(&sMem, 0, sizeof(sMem)); | | < | < < | < | > < < | < < < < | | | < < < < < < | | > > | | 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 | ** to extract additional fields up through the p2+1-th field */ op_column_read_header: if( pC->iHdrOffset<aOffset[0] ){ /* Make sure zData points to enough of the record to cover the header. */ if( pC->aRow==0 ){ memset(&sMem, 0, sizeof(sMem)); rc = sqlite3VdbeMemFromBtree(pCrsr, 0, aOffset[0], !pC->isTable, &sMem); if( rc!=SQLITE_OK ) goto op_column_error; zData = (u8*)sMem.z; }else{ zData = pC->aRow; } /* Fill in pC->aType[i] and aOffset[i] values through the p2-th field. */ i = pC->nHdrParsed; offset64 = aOffset[i]; zHdr = zData + pC->iHdrOffset; zEndHdr = zData + aOffset[0]; assert( i<=p2 && zHdr<zEndHdr ); do{ if( (t = zHdr[0])<0x80 ){ zHdr++; offset64 += sqlite3VdbeOneByteSerialTypeLen(t); }else{ zHdr += sqlite3GetVarint32(zHdr, &t); offset64 += sqlite3VdbeSerialTypeLen(t); } pC->aType[i++] = t; aOffset[i] = (u32)(offset64 & 0xffffffff); }while( i<=p2 && zHdr<zEndHdr ); pC->nHdrParsed = i; pC->iHdrOffset = (u32)(zHdr - zData); if( pC->aRow==0 ) sqlite3VdbeMemRelease(&sMem); /* The record is corrupt if any of the following are true: ** (1) the bytes of the header extend past the declared header size ** (2) the entire header was used but not all data was used ** (3) the end of the data extends beyond the end of the record. */ if( (zHdr>=zEndHdr && (zHdr>zEndHdr || offset64!=pC->payloadSize)) || (offset64 > pC->payloadSize) ){ rc = SQLITE_CORRUPT_BKPT; goto op_column_error; } } /* If after trying to extract new entries from the header, nHdrParsed is ** still not up to p2, that means that the record has fewer than p2 ** columns. So the result will be either the default value or a NULL. */ if( pC->nHdrParsed<=p2 ){ if( pOp->p4type==P4_MEM ){ sqlite3VdbeMemShallowCopy(pDest, pOp->p4.pMem, MEM_Static); }else{ sqlite3VdbeMemSetNull(pDest); } goto op_column_out; } }else{ t = pC->aType[p2]; } /* Extract the content for the p2+1-th column. Control can only ** reach this point if aOffset[p2], aOffset[p2+1], and pC->aType[p2] are ** all valid. */ assert( p2<pC->nHdrParsed ); assert( rc==SQLITE_OK ); assert( sqlite3VdbeCheckMemInvariants(pDest) ); if( VdbeMemDynamic(pDest) ) sqlite3VdbeMemSetNull(pDest); assert( t==pC->aType[p2] ); if( pC->szRow>=aOffset[p2+1] ){ /* This is the common case where the desired content fits on the original ** page - where the content is not on an overflow page */ sqlite3VdbeSerialGet(pC->aRow+aOffset[p2], t, pDest); }else{ /* This branch happens only when content is on overflow pages */ if( ((pOp->p5 & (OPFLAG_LENGTHARG|OPFLAG_TYPEOFARG))!=0 |
︙ | ︙ | |||
2644 2645 2646 2647 2648 2649 2650 | Mem *pData0; /* First field to be combined into the record */ Mem *pLast; /* Last field of the record */ int nField; /* Number of fields in the record */ char *zAffinity; /* The affinity string for the record */ int file_format; /* File format to use for encoding */ int i; /* Space used in zNewRecord[] header */ int j; /* Space used in zNewRecord[] content */ | | | 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 | Mem *pData0; /* First field to be combined into the record */ Mem *pLast; /* Last field of the record */ int nField; /* Number of fields in the record */ char *zAffinity; /* The affinity string for the record */ int file_format; /* File format to use for encoding */ int i; /* Space used in zNewRecord[] header */ int j; /* Space used in zNewRecord[] content */ u32 len; /* Length of a field */ /* Assuming the record contains N fields, the record format looks ** like this: ** ** ------------------------------------------------------------------------ ** | hdr-size | type 0 | type 1 | ... | type N-1 | data0 | ... | data N-1 | ** ------------------------------------------------------------------------ |
︙ | ︙ | |||
2694 2695 2696 2697 2698 2699 2700 | /* Loop through the elements that will make up the record to figure ** out how much space is required for the new record. */ pRec = pLast; do{ assert( memIsValid(pRec) ); | | < | 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 | /* Loop through the elements that will make up the record to figure ** out how much space is required for the new record. */ pRec = pLast; do{ assert( memIsValid(pRec) ); pRec->uTemp = serial_type = sqlite3VdbeSerialType(pRec, file_format, &len); if( pRec->flags & MEM_Zero ){ if( nData ){ if( sqlite3VdbeMemExpandBlob(pRec) ) goto no_mem; }else{ nZero += pRec->u.nZero; len -= pRec->u.nZero; } |
︙ | ︙ |
Changes to src/vdbeInt.h.
︙ | ︙ | |||
408 409 410 411 412 413 414 | void sqliteVdbePopStack(Vdbe*,int); int sqlite3VdbeCursorMoveto(VdbeCursor*); int sqlite3VdbeCursorRestore(VdbeCursor*); #if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE) void sqlite3VdbePrintOp(FILE*, int, Op*); #endif u32 sqlite3VdbeSerialTypeLen(u32); | > | | 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 | void sqliteVdbePopStack(Vdbe*,int); int sqlite3VdbeCursorMoveto(VdbeCursor*); int sqlite3VdbeCursorRestore(VdbeCursor*); #if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE) void sqlite3VdbePrintOp(FILE*, int, Op*); #endif u32 sqlite3VdbeSerialTypeLen(u32); u8 sqlite3VdbeOneByteSerialTypeLen(u8); u32 sqlite3VdbeSerialType(Mem*, int, u32*); u32 sqlite3VdbeSerialPut(unsigned char*, Mem*, u32); u32 sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*); void sqlite3VdbeDeleteAuxData(Vdbe*, int, int); int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *); int sqlite3VdbeIdxKeyCompare(sqlite3*,VdbeCursor*,UnpackedRecord*,int*); int sqlite3VdbeIdxRowid(sqlite3*, BtCursor*, i64*); |
︙ | ︙ |
Changes to src/vdbeaux.c.
︙ | ︙ | |||
2954 2955 2956 2957 2958 2959 2960 | ** The 8 and 9 types were added in 3.3.0, file format 4. Prior versions ** of SQLite will not understand those serial types. */ /* ** Return the serial-type for the value stored in pMem. */ | | > > | > > > > > | > | | | | > > > | > > > > | > > > > > > > > > | > > > > > > | 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 | ** The 8 and 9 types were added in 3.3.0, file format 4. Prior versions ** of SQLite will not understand those serial types. */ /* ** Return the serial-type for the value stored in pMem. */ u32 sqlite3VdbeSerialType(Mem *pMem, int file_format, u32 *pLen){ int flags = pMem->flags; u32 n; assert( pLen!=0 ); if( flags&MEM_Null ){ *pLen = 0; return 0; } if( flags&MEM_Int ){ /* Figure out whether to use 1, 2, 4, 6 or 8 bytes. */ # define MAX_6BYTE ((((i64)0x00008000)<<32)-1) i64 i = pMem->u.i; u64 u; if( i<0 ){ u = ~i; }else{ u = i; } if( u<=127 ){ if( (i&1)==i && file_format>=4 ){ *pLen = 0; return 8+(u32)u; }else{ *pLen = 1; return 1; } } if( u<=32767 ){ *pLen = 2; return 2; } if( u<=8388607 ){ *pLen = 3; return 3; } if( u<=2147483647 ){ *pLen = 4; return 4; } if( u<=MAX_6BYTE ){ *pLen = 6; return 5; } *pLen = 8; return 6; } if( flags&MEM_Real ){ *pLen = 8; return 7; } assert( pMem->db->mallocFailed || flags&(MEM_Str|MEM_Blob) ); assert( pMem->n>=0 ); n = (u32)pMem->n; if( flags & MEM_Zero ){ n += pMem->u.nZero; } *pLen = n; return ((n*2) + 12 + ((flags&MEM_Str)!=0)); } /* ** The sizes for serial types less than 128 */ static const u8 sqlite3SmallTypeSizes[] = { /* 0 1 2 3 4 5 6 7 8 9 */ /* 0 */ 0, 1, 2, 3, 4, 6, 8, 8, 0, 0, /* 10 */ 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, /* 20 */ 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, /* 30 */ 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, /* 40 */ 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, /* 50 */ 19, 19, 20, 20, 21, 21, 22, 22, 23, 23, /* 60 */ 24, 24, 25, 25, 26, 26, 27, 27, 28, 28, /* 70 */ 29, 29, 30, 30, 31, 31, 32, 32, 33, 33, /* 80 */ 34, 34, 35, 35, 36, 36, 37, 37, 38, 38, /* 90 */ 39, 39, 40, 40, 41, 41, 42, 42, 43, 43, /* 100 */ 44, 44, 45, 45, 46, 46, 47, 47, 48, 48, /* 110 */ 49, 49, 50, 50, 51, 51, 52, 52, 53, 53, /* 120 */ 54, 54, 55, 55, 56, 56, 57, 57 }; /* ** Return the length of the data corresponding to the supplied serial-type. */ u32 sqlite3VdbeSerialTypeLen(u32 serial_type){ if( serial_type>=128 ){ return (serial_type-12)/2; }else{ assert( serial_type<12 || sqlite3SmallTypeSizes[serial_type]==(serial_type - 12)/2 ); return sqlite3SmallTypeSizes[serial_type]; } } u8 sqlite3VdbeOneByteSerialTypeLen(u8 serial_type){ assert( serial_type<128 ); return sqlite3SmallTypeSizes[serial_type]; } /* ** If we are on an architecture with mixed-endian floating ** points (ex: ARM7) then swap the lower 4 bytes with the ** upper 4 bytes. Return the result. ** |
︙ | ︙ |
Changes to src/vdbemem.c.
︙ | ︙ | |||
1423 1424 1425 1426 1427 1428 1429 | */ static void recordFunc( sqlite3_context *context, int argc, sqlite3_value **argv ){ const int file_format = 1; | | | | < | 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 | */ static void recordFunc( sqlite3_context *context, int argc, sqlite3_value **argv ){ const int file_format = 1; u32 iSerial; /* Serial type */ int nSerial; /* Bytes of space for iSerial as varint */ u32 nVal; /* Bytes of space required for argv[0] */ int nRet; sqlite3 *db; u8 *aRet; UNUSED_PARAMETER( argc ); iSerial = sqlite3VdbeSerialType(argv[0], file_format, &nVal); nSerial = sqlite3VarintLen(iSerial); db = sqlite3_context_db_handle(context); nRet = 1 + nSerial + nVal; aRet = sqlite3DbMallocRaw(db, nRet); if( aRet==0 ){ sqlite3_result_error_nomem(context); }else{ |
︙ | ︙ |
Changes to src/vdbesort.c.
︙ | ︙ | |||
974 975 976 977 978 979 980 | pKeyInfo->db = 0; if( nField && nWorker==0 ){ pKeyInfo->nXField += (pKeyInfo->nField - nField); pKeyInfo->nField = nField; } pSorter->pgsz = pgsz = sqlite3BtreeGetPageSize(db->aDb[0].pBt); pSorter->nTask = nWorker + 1; | | | 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 | pKeyInfo->db = 0; if( nField && nWorker==0 ){ pKeyInfo->nXField += (pKeyInfo->nField - nField); pKeyInfo->nField = nField; } pSorter->pgsz = pgsz = sqlite3BtreeGetPageSize(db->aDb[0].pBt); pSorter->nTask = nWorker + 1; pSorter->iPrev = (u8)(nWorker - 1); pSorter->bUseThreads = (pSorter->nTask>1); pSorter->db = db; for(i=0; i<pSorter->nTask; i++){ SortSubtask *pTask = &pSorter->aTask[i]; pTask->pSorter = pSorter; } |
︙ | ︙ |
Changes to src/wherecode.c.
︙ | ︙ | |||
1301 1302 1303 1304 1305 1306 1307 | int nPk = pPk->nKeyCol; int iPk; /* Read the PK into an array of temp registers. */ r = sqlite3GetTempRange(pParse, nPk); for(iPk=0; iPk<nPk; iPk++){ int iCol = pPk->aiColumn[iPk]; | < | < < < | 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 | int nPk = pPk->nKeyCol; int iPk; /* Read the PK into an array of temp registers. */ r = sqlite3GetTempRange(pParse, nPk); for(iPk=0; iPk<nPk; iPk++){ int iCol = pPk->aiColumn[iPk]; sqlite3ExprCodeGetColumnToReg(pParse, pTab, iCol, iCur, r+iPk); } /* Check if the temp table already contains this key. If so, ** the row has already been included in the result set and ** can be ignored (by jumping past the Gosub below). Otherwise, ** insert the key into the temp table and proceed with processing ** the row. |
︙ | ︙ |
Changes to test/json101.test.
︙ | ︙ | |||
320 321 322 323 324 325 326 327 328 | do_execsql_test json-6.3 { SELECT json_valid('["a",55,"b",72,]'); } {0} do_execsql_test json-6.4 { SELECT json_valid('["a",55,"b",72]'); } {1} finish_test | > > > > > > > > > > > > > > > > > | 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 | do_execsql_test json-6.3 { SELECT json_valid('["a",55,"b",72,]'); } {0} do_execsql_test json-6.4 { SELECT json_valid('["a",55,"b",72]'); } {1} # White-space tests. Note that form-feed is not white-space in JSON. # ticket [57eec374ae1d0a1d4a23077a95f4e173fe269113] # foreach {tn isvalid ws} { 7.1 1 char(0x20) 7.2 1 char(0x09) 7.3 1 char(0x0A) 7.4 1 char(0x0D) 7.5 0 char(0x0C) 7.6 1 char(0x20,0x09,0x0a,0x0d,0x20) 7.7 0 char(0x20,0x09,0x0a,0x0c,0x0d,0x20) } { do_execsql_test json-$tn.1 \ "SELECT json_valid(printf('%s{%s\"x\"%s:%s9%s}%s', $::ws,$::ws,$::ws,$::ws,$::ws,$::ws));" \ $isvalid } finish_test |
Changes to tool/GetTclKit.bat.
︙ | ︙ | |||
169 170 171 172 173 174 175 176 177 178 179 180 181 182 | %__ECHO% ECHO SET TCLSH_CMD=%TEMP%\%TCLKIT_EXE%%OVERWRITE%"%ROOT%\SetTclKitEnv.bat" IF DEFINED TCLKIT_NOSDK GOTO skip_sdkVariables %__ECHO% ECHO SET TCLINCDIR=%TEMP%\%TCLKIT_SDK%\include%APPEND%"%ROOT%\SetTclKitEnv.bat" %__ECHO% ECHO SET TCLLIBDIR=%TEMP%\%TCLKIT_SDK%\lib%APPEND%"%ROOT%\SetTclKitEnv.bat" %__ECHO% ECHO SET LIBTCL=%TCLKIT_LIB%%APPEND%"%ROOT%\SetTclKitEnv.bat" %__ECHO% ECHO SET LIBTCLSTUB=%TCLKIT_LIB_STUB%%APPEND%"%ROOT%\SetTclKitEnv.bat" :skip_sdkVariables ECHO. ECHO Wrote "%ROOT%\SetTclKitEnv.bat". | > | 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 | %__ECHO% ECHO SET TCLSH_CMD=%TEMP%\%TCLKIT_EXE%%OVERWRITE%"%ROOT%\SetTclKitEnv.bat" IF DEFINED TCLKIT_NOSDK GOTO skip_sdkVariables %__ECHO% ECHO SET TCLINCDIR=%TEMP%\%TCLKIT_SDK%\include%APPEND%"%ROOT%\SetTclKitEnv.bat" %__ECHO% ECHO SET TCLLIBDIR=%TEMP%\%TCLKIT_SDK%\lib%APPEND%"%ROOT%\SetTclKitEnv.bat" %__ECHO% ECHO SET LIBTCLPATH=%TEMP%\%TCLKIT_SDK%\lib%APPEND%"%ROOT%\SetTclKitEnv.bat" %__ECHO% ECHO SET LIBTCL=%TCLKIT_LIB%%APPEND%"%ROOT%\SetTclKitEnv.bat" %__ECHO% ECHO SET LIBTCLSTUB=%TCLKIT_LIB_STUB%%APPEND%"%ROOT%\SetTclKitEnv.bat" :skip_sdkVariables ECHO. ECHO Wrote "%ROOT%\SetTclKitEnv.bat". |
︙ | ︙ |
Changes to tool/fuzzershell.c.
︙ | ︙ | |||
722 723 724 725 726 727 728 | if( pLook ){ rc = sqlite3_db_config(db, SQLITE_DBCONFIG_LOOKASIDE,pLook,szLook,nLook); if( rc!=SQLITE_OK ) abendError("lookaside configuration filed: %d", rc); } #ifndef SQLITE_OMIT_TRACE sqlite3_trace(db, verboseFlag ? traceCallback : traceNoop, 0); #endif | < < < < < < | 722 723 724 725 726 727 728 729 730 731 732 733 734 735 | if( pLook ){ rc = sqlite3_db_config(db, SQLITE_DBCONFIG_LOOKASIDE,pLook,szLook,nLook); if( rc!=SQLITE_OK ) abendError("lookaside configuration filed: %d", rc); } #ifndef SQLITE_OMIT_TRACE sqlite3_trace(db, verboseFlag ? traceCallback : traceNoop, 0); #endif sqlite3_create_function(db, "eval", 1, SQLITE_UTF8, 0, sqlEvalFunc, 0, 0); sqlite3_create_function(db, "eval", 2, SQLITE_UTF8, 0, sqlEvalFunc, 0, 0); sqlite3_limit(db, SQLITE_LIMIT_LENGTH, 1000000); if( zEncoding ) sqlexec(db, "PRAGMA encoding=%s", zEncoding); if( pageSize ) sqlexec(db, "PRAGMA pagesize=%d", pageSize); if( doAutovac ) sqlexec(db, "PRAGMA auto_vacuum=FULL"); iStart = timeOfDay(); |
︙ | ︙ |
Changes to tool/mksqlite3h.tcl.
︙ | ︙ | |||
94 95 96 97 98 99 100 | while {![eof $in]} { set line [gets $in] # File sqlite3rtree.h contains a line "#include <sqlite3.h>". Omit this # line when copying sqlite3rtree.h into sqlite3.h. # | | | 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 | while {![eof $in]} { set line [gets $in] # File sqlite3rtree.h contains a line "#include <sqlite3.h>". Omit this # line when copying sqlite3rtree.h into sqlite3.h. # if {[string match {*#include*[<"]sqlite3.h[>"]*} $line]} continue regsub -- --VERS-- $line $zVersion line regsub -- --VERSION-NUMBER-- $line $nVersion line regsub -- --SOURCE-ID-- $line "$zDate $zUuid" line if {[regexp $varpattern $line] && ![regexp {^ *typedef} $line]} { set line "SQLITE_API $line" |
︙ | ︙ |
Changes to tool/showjournal.c.
︙ | ︙ | |||
26 27 28 29 30 31 32 | ** from malloc(). */ static unsigned char *read_content(int N, int iOfst){ int got; unsigned char *pBuf = malloc(N); if( pBuf==0 ) out_of_memory(); fseek(db, iOfst, SEEK_SET); | | | 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | ** from malloc(). */ static unsigned char *read_content(int N, int iOfst){ int got; unsigned char *pBuf = malloc(N); if( pBuf==0 ) out_of_memory(); fseek(db, iOfst, SEEK_SET); got = (int)fread(pBuf, 1, N, db); if( got<0 ){ fprintf(stderr, "I/O error reading %d bytes from %d\n", N, iOfst); memset(pBuf, 0, N); }else if( got<N ){ fprintf(stderr, "Short read: got only %d of %d bytes from %d\n", got, N, iOfst); memset(&pBuf[got], 0, N-got); |
︙ | ︙ | |||
49 50 51 52 53 54 55 | int ofst, int nByte, /* Start and size of decode */ const char *zMsg /* Message to append */ ){ int i, j; unsigned val = aData[ofst]; char zBuf[100]; sprintf(zBuf, " %05x: %02x", ofst, aData[ofst]); | | | | 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | int ofst, int nByte, /* Start and size of decode */ const char *zMsg /* Message to append */ ){ int i, j; unsigned val = aData[ofst]; char zBuf[100]; sprintf(zBuf, " %05x: %02x", ofst, aData[ofst]); i = (int)strlen(zBuf); for(j=1; j<4; j++){ if( j>=nByte ){ sprintf(&zBuf[i], " "); }else{ sprintf(&zBuf[i], " %02x", aData[ofst+j]); val = val*256 + aData[ofst+j]; } i += (int)strlen(&zBuf[i]); } sprintf(&zBuf[i], " %10u", val); printf("%s %s\n", zBuf, zMsg); return val; } /* |
︙ | ︙ |
Changes to tool/vdbe_profile.tcl.
1 2 3 4 5 6 7 8 9 10 11 | #!/bin/tclsh # # Run this script in the same directory as the "vdbe_profile.out" file. # This script summarizes the results contained in that file. # if {![file readable vdbe_profile.out]} { error "run this script in the same directory as the vdbe_profile.out file" } set in [open vdbe_profile.out r] set stmt {} set allstmt {} | > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | #!/bin/tclsh # # SUMMARY: # Run this script in the same directory as the "vdbe_profile.out" file. # This script summarizes the results contained in that file. # # DETAILS: # Compile SQLite using the -DVDBE_PROFILE option on Linux. This causes # performance information about individual VDBE operations to be appended # to the "vdbe_profile.out" file. After content has been accumulated in # vdbe_profile.out, run this script to analyze the output and generate a # report. # if {![file readable vdbe_profile.out]} { error "run this script in the same directory as the vdbe_profile.out file" } set in [open vdbe_profile.out r] set stmt {} set allstmt {} |
︙ | ︙ |